--- /dev/null
+/*
+ * SpellMenu.cpp
+ *
+ * Created on: Nov 18, 2012
+ * Author: holy
+ */
+
+#include "SpellMenu.h"
+
+#include "HeroStatus.h"
+#include "PartyMenu.h"
+#include "Resources.h"
+#include "../app/Input.h"
+#include "../common/GameConfig.h"
+#include "../common/GameState.h"
+#include "../common/Hero.h"
+#include "../common/Spell.h"
+#include "../graphics/Font.h"
+#include "../graphics/Frame.h"
+
+#include <SDL.h>
+#include <vector>
+
+using app::Input;
+using common::Hero;
+using common::Spell;
+using geometry::Vector;
+using graphics::Font;
+using graphics::Frame;
+using std::vector;
+
+namespace menu {
+
+SpellMenu::SpellMenu(PartyMenu *parent, int cursor)
+: parent(parent)
+, highlight(0)
+, cursor(cursor)
+, actionMenu(*parent->Res().itemMenuProperties)
+, spellMenu(*parent->Res().spellMenuProperties) {
+ actionMenu.Add(parent->Res().itemMenuUseText, CHOICE_USE);
+ actionMenu.Add(parent->Res().itemMenuSortText, CHOICE_SORT);
+}
+
+
+void SpellMenu::OnEnterState(SDL_Surface *) {
+ const HeroStatus &status(parent->GetHeroStatus(0));
+ highlight = SDL_CreateRGBSurface(0, status.Width(), status.Height(), 32, 0xFF000000, 0xFF0000, 0xFF00, 0);
+ SDL_FillRect(highlight, 0, SDL_MapRGB(highlight->format, 0xFF, 0xFF, 0xFF));
+ SDL_SetAlpha(highlight, SDL_SRCALPHA|SDL_RLEACCEL, 0x20);
+
+ actionMenu.SetSelected();
+ LoadSpells();
+}
+
+void SpellMenu::LoadSpells() {
+ spellMenu.Clear();
+ // TODO: set to max spells once implementation is changed
+ spellMenu.Reserve(GetHero().Spells().size());
+ for (vector<const Spell *>::const_iterator
+ i = GetHero().Spells().begin(), end = GetHero().Spells().end();
+ i != end; ++i) {
+ const Spell *spell = *i;
+ spellMenu.Add(spell->Name(), spell, spell->CanUseOnStatusScreen(), 0, spell->Cost());
+ }
+}
+
+const Hero &SpellMenu::GetHero() const {
+ return *parent->Game().state->party[cursor];
+}
+
+void SpellMenu::OnExitState(SDL_Surface *) {
+ SDL_FreeSurface(highlight);
+}
+
+void SpellMenu::OnResumeState(SDL_Surface *) {
+
+}
+
+void SpellMenu::OnPauseState(SDL_Surface *) {
+
+}
+
+
+void SpellMenu::OnResize(int width, int height) {
+
+}
+
+
+void SpellMenu::HandleEvents(const Input &input) {
+ if (actionMenu.IsActive()) {
+ if (input.JustPressed(Input::PAD_LEFT)) {
+ actionMenu.PreviousItem();
+ }
+ if (input.JustPressed(Input::PAD_RIGHT)) {
+ actionMenu.NextItem();
+ }
+ } else {
+ if (input.JustPressed(Input::PAD_UP)) {
+ spellMenu.PreviousRow();
+ }
+ if (input.JustPressed(Input::PAD_RIGHT)) {
+ spellMenu.NextItem();
+ }
+ if (input.JustPressed(Input::PAD_DOWN)) {
+ spellMenu.NextRow();
+ }
+ if (input.JustPressed(Input::PAD_LEFT)) {
+ spellMenu.PreviousItem();
+ }
+ }
+
+ if (input.JustPressed(Input::ACTION_A)) {
+ if (actionMenu.IsActive()) {
+ if (actionMenu.Selected() == CHOICE_SORT) {
+ // TODO: sort spells
+ LoadSpells();
+ } else {
+ actionMenu.SetSelected();
+ spellMenu.SetActive();
+ }
+ } else if (spellMenu.IsActive()) {
+ spellMenu.SetDualSelection();
+ } else if (spellMenu.SelectedIndex() == spellMenu.SecondaryIndex()) {
+ if (spellMenu.Selected()->CanUseOnStatusScreen()) {
+ // TODO: use spell
+ }
+ } else {
+ // TODO: swap spells
+ spellMenu.SwapSelected();
+ spellMenu.SetActive();
+ }
+ }
+
+ if (input.JustPressed(Input::ACTION_B)) {
+ if (actionMenu.IsActive()) {
+ Ctrl().PopState();
+ } else if (spellMenu.IsActive()) {
+ actionMenu.SetActive();
+ spellMenu.SetInactive();
+ } else {
+ spellMenu.SetActive();
+ }
+ }
+}
+
+void SpellMenu::UpdateWorld(float deltaT) {
+
+}
+
+void SpellMenu::Render(SDL_Surface *screen) {
+ const Font &font(*parent->Res().normalFont);
+ Vector<int> offset((screen->w - Width()) / 2, (screen->h - Height()) / 2);
+ Vector<int> menuOffset(font.CharWidth(), 13 * font.CharHeight() + font.CharHeight() / 8);
+ Vector<int> spellsOffset(font.CharWidth(), 16 * font.CharHeight() + font.CharHeight() / 8);
+
+ parent->RenderBackground(screen);
+ RenderHighlight(screen, offset);
+ parent->RenderHeros(screen, offset);
+ RenderMenu(screen, menuOffset + offset);
+ RenderSpells(screen, spellsOffset + offset);
+}
+
+int SpellMenu::Width() const {
+ return parent->Width();
+}
+
+int SpellMenu::Height() const {
+ return parent->Height();
+}
+
+void SpellMenu::RenderHighlight(SDL_Surface *screen, const Vector<int> &offset) const {
+ if (cursor < 0) return;
+ Vector<int> statusOffset(parent->StatusOffset(cursor));
+ statusOffset -= Vector<int>(0, parent->Res().normalFont->CharHeight() / 8);
+ SDL_Rect rect;
+ rect.x = statusOffset.X();
+ rect.y = statusOffset.Y();
+ SDL_BlitSurface(highlight, 0, screen, &rect);
+}
+
+void SpellMenu::RenderMenu(SDL_Surface *screen, const Vector<int> &offset) const {
+ const Font &font(*parent->Res().normalFont);
+ const Frame &frame(*parent->Res().statusFrame);
+
+ const Vector<int> labelOffset(2 * font.CharWidth(), font.CharHeight());
+ const Vector<int> menuFrameOffset(offset.X() + 9 * font.CharWidth(), offset.Y());
+ const Vector<int> menuOffset(menuFrameOffset.X() + 3 * font.CharWidth(), menuFrameOffset.Y() + font.CharHeight());
+
+ frame.Draw(screen, offset, 9 * font.CharWidth(), 3 * font.CharHeight());
+ font.DrawString(parent->Res().mainMenuSpellText, screen, labelOffset + offset);
+ frame.Draw(screen, menuFrameOffset, 21 * font.CharWidth(), 3 * font.CharHeight());
+ actionMenu.Draw(screen, menuOffset);
+}
+
+void SpellMenu::RenderSpells(SDL_Surface *screen, const Vector<int> &offset) const {
+ const Font &font(*parent->Res().normalFont);
+ const Frame &frame(*parent->Res().statusFrame);
+ const Vector<int> menuOffset(3 * font.CharWidth(), font.CharHeight() + font.CharHeight() / 4);
+
+ frame.Draw(screen, offset, 30 * font.CharWidth(), 11 * font.CharHeight());
+ spellMenu.Draw(screen, offset + menuOffset);
+}
+
+}
--- /dev/null
+/*
+ * SpellMenu.h
+ *
+ * Created on: Nov 18, 2012
+ * Author: holy
+ */
+
+#ifndef MENU_SPELLMENU_H_
+#define MENU_SPELLMENU_H_
+
+#include "fwd.h"
+#include "../app/State.h"
+#include "../common/fwd.h"
+#include "../geometry/Vector.h"
+#include "../graphics/Menu.h"
+
+namespace menu {
+
+class SpellMenu
+: public app::State {
+
+public:
+ SpellMenu(PartyMenu *parent, int heroIndex);
+
+public:
+ virtual void HandleEvents(const app::Input &);
+ virtual void UpdateWorld(float deltaT);
+ virtual void Render(SDL_Surface *);
+
+public:
+ int Width() const;
+ int Height() const;
+
+private:
+ virtual void OnEnterState(SDL_Surface *screen);
+ virtual void OnExitState(SDL_Surface *screen);
+ virtual void OnResumeState(SDL_Surface *screen);
+ virtual void OnPauseState(SDL_Surface *screen);
+
+ virtual void OnResize(int width, int height);
+
+ const common::Hero &GetHero() const;
+
+ void LoadSpells();
+
+ void RenderHighlight(SDL_Surface *screen, const geometry::Vector<int> &offset) const;
+ void RenderMenu(SDL_Surface *screen, const geometry::Vector<int> &offset) const;
+ void RenderSpells(SDL_Surface *screen, const geometry::Vector<int> &offset) const;
+
+private:
+ PartyMenu *parent;
+ SDL_Surface *highlight;
+ int cursor;
+ enum Choice {
+ CHOICE_USE,
+ CHOICE_SORT,
+ };
+ graphics::Menu<Choice> actionMenu;
+ graphics::Menu<const common::Spell *> spellMenu;
+
+};
+
+}
+
+#endif /* MENU_SPELLMENU_H_ */