From: Daniel Karbach Date: Wed, 8 Aug 2012 20:47:20 +0000 (+0200) Subject: added rough implementation of a Menu X-Git-Url: https://git.localhorst.tv/?a=commitdiff_plain;h=8c055cbdddac2114c130e6a6524ff887d89ccf53;p=l2e.git added rough implementation of a Menu --- diff --git a/src/battle/BattleState.cpp b/src/battle/BattleState.cpp index ae882a6..15d9d18 100644 --- a/src/battle/BattleState.cpp +++ b/src/battle/BattleState.cpp @@ -20,6 +20,7 @@ using app::Application; using app::Input; using geometry::Point; using geometry::Vector; +using graphics::Menu; using std::vector; @@ -50,6 +51,14 @@ void BattleState::EnterState(Application &ctrl, SDL_Surface *screen) { heroesLayout->CalculatePositions(background->w, background->h, heroesPositions); attackChoices.resize(heroes.size()); for (vector::size_type i(0), end(heroes.size()); i < end; ++i) { + // TODO: extract menu dimensions to resources + Menu spellMenu(res->normalFont, 12, 6, 8, 2, 32); + spellMenu.Add("Strong : 3", 0); + spellMenu.Add("Stronger : 8", 0); + spellMenu.Add("Champion :16", 0); + spellMenu.Add("Rally :10", 0); + spellMenu.Add("Valor :30", 0); + spellMenus.push_back(spellMenu); heroTags.push_back(HeroTag(&heroes[i], &attackChoices[i], res, HeroTag::Alignment((i + 1) % 2))); } } diff --git a/src/battle/BattleState.h b/src/battle/BattleState.h index 484e452..365f198 100644 --- a/src/battle/BattleState.h +++ b/src/battle/BattleState.h @@ -18,6 +18,7 @@ #include "../app/State.h" #include "../geometry/Point.h" #include "../geometry/Vector.h" +#include "../graphics/Menu.h" #include #include @@ -77,6 +78,7 @@ public: bool HasChosenAttackType() const { return attackChoices[activeHero].GetType() != AttackChoice::UNDECIDED; } void SetAttackType(AttackChoice::Type t) { attackChoices[activeHero].SetType(t); } bool AttackSelectionDone() const { return activeHero >= (int) heroes.size(); } + const graphics::Menu GetSpellMenu() const { return spellMenus[activeHero]; } public: geometry::Vector CalculateScreenOffset(SDL_Surface *screen) const { @@ -103,6 +105,7 @@ private: std::vector > heroesPositions; std::vector monsters; std::vector heroes; + std::vector > spellMenus; std::vector heroTags; std::vector attackChoices; int activeHero; diff --git a/src/battle/states/SelectSpell.cpp b/src/battle/states/SelectSpell.cpp index 1b01250..5f358fb 100644 --- a/src/battle/states/SelectSpell.cpp +++ b/src/battle/states/SelectSpell.cpp @@ -63,13 +63,23 @@ void SelectSpell::UpdateWorld(float deltaT) { void SelectSpell::Render(SDL_Surface *screen) { parent->Render(screen); + Vector offset(battle->CalculateScreenOffset(screen)); + RenderFrame(screen, offset); + RenderMenu(screen, offset); +} + +void SelectSpell::RenderFrame(SDL_Surface *screen, const Vector &offset) { const Frame *frame(battle->Res().selectFrame); Point position(frame->BorderWidth(), frame->BorderHeight()); - Vector offset(battle->CalculateScreenOffset(screen)); int width(battle->BackgroundWidth() - 2 * frame->BorderWidth()); // TODO: replace with font height int height(frame->BorderHeight() * 13); frame->Draw(screen, position + offset, width, height); } +void SelectSpell::RenderMenu(SDL_Surface *screen, const Vector &offset) { + Point position(2 * battle->Res().selectFrame->BorderWidth(), 2 * battle->Res().selectFrame->BorderHeight()); + battle->GetSpellMenu().Draw(screen, position + offset); +} + } diff --git a/src/battle/states/SelectSpell.h b/src/battle/states/SelectSpell.h index e0bb118..f3841a1 100644 --- a/src/battle/states/SelectSpell.h +++ b/src/battle/states/SelectSpell.h @@ -10,6 +10,8 @@ #include "../../app/State.h" +#include "../../geometry/Vector.h" + namespace battle { class BattleState; @@ -34,6 +36,10 @@ public: virtual void UpdateWorld(float deltaT); virtual void Render(SDL_Surface *); +private: + void RenderFrame(SDL_Surface *, const geometry::Vector &offset); + void RenderMenu(SDL_Surface *, const geometry::Vector &offset); + private: app::Application *ctrl; BattleState *battle; diff --git a/src/graphics/Menu.h b/src/graphics/Menu.h new file mode 100644 index 0000000..0a4a698 --- /dev/null +++ b/src/graphics/Menu.h @@ -0,0 +1,146 @@ +/* + * Menu.h + * + * Created on: Aug 8, 2012 + * Author: holy + */ + +#ifndef GRAPHICS_MENU_H_ +#define GRAPHICS_MENU_H_ + +#include "Font.h" +#include "../geometry/operators.h" +#include "../geometry/Point.h" +#include "../geometry/Vector.h" + +#include +#include + +namespace graphics { + +class Sprite; + +template +class Menu { + +public: + Menu(const Font *font, int charsPerEntry, int rows, int rowGap = 0, int cols = 1, int colGap = 0); + +public: + int Width() const; + int Height() const; + int ColWidth() const { return font->CharWidth() * charsPerEntry; } + int RowHeight() const { return font->CharHeight() + rowGap; } + + T &Selected() { return entries[selected].value; } + const T &Selected() const { return entries[selected].value; } + const char *SelectedTitle() const { return entries[selected].title; } + + void NextItem(); + void PreviousItem(); + void NextRow(); + void PreviousRow(); + void SelectIndex(int index); + + void Add(const char *title, const T &value, const Sprite *icon = 0) { entries.push_back(Entry(title, value, icon)); } + void Reserve(int n) { entries.reserve(n); } + + void Draw(SDL_Surface *dest, geometry::Point position) const; + +private: + int GetRow(int index) const { return index / cols; } + int GetCol(int index) const { return index % cols; } + +private: + struct Entry { + Entry(const char *title, const T &value, const Sprite *icon = 0) + : title(title), icon(icon), value(value) { } + const char *title; + const Sprite *icon; + T value; + }; + const Font *font; + std::vector entries; + int charsPerEntry; + int rows; + int rowGap; + int cols; + int colGap; + int selected; + int topRow; + +}; + + +template +Menu::Menu(const Font *font, int charsPerEntry, int rows, int rowGap, int cols, int colGap) +: font(font) +, charsPerEntry(charsPerEntry) +, rows(rows) +, rowGap(rowGap) +, cols(cols) +, colGap(colGap) +, selected(0) +, topRow(0) { + +} + + +template +int Menu::Width() const { + return cols * ColWidth() + (cols - 1) * colGap; +} + +template +int Menu::Height() const { + return rows * font->CharHeight() + (rows - 1) * rowGap; +} + + +template +void Menu::NextItem() { + SelectIndex(selected + 1); +} + +template +void Menu::PreviousItem() { + SelectIndex(selected - 1); +} + +template +void Menu::NextRow() { + SelectIndex(selected + cols); +} + +template +void Menu::PreviousRow() { + SelectIndex(selected - cols); +} + +template +void Menu::SelectIndex(int index) { + if (index < 0 || entries.size() < index) return; + selected = index; + if (GetRow(selected) - rows > topRow) { + topRow = GetRow(selected) - rows; + } else if (GetRow(selected) < topRow) { + topRow = GetRow(selected); + } +} + + +template +void Menu::Draw(SDL_Surface *dest, geometry::Point position) const { + int start(topRow * cols); + int slots((topRow + rows) * cols); + int items(entries.size() - start); + int end(items < slots ? items : slots); + for (int i(0), count(end - start); i < count; ++i) { + geometry::Vector offset((i % cols) * (ColWidth() + colGap), (i / cols) * RowHeight()); + font->DrawString(entries[start + i].title, dest, position + offset, charsPerEntry); + } +} + +} + +#endif /* GRAPHICS_MENU_H_ */ diff --git a/src/main.cpp b/src/main.cpp index d9a2f57..676f2d7 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -161,6 +161,9 @@ int main(int argc, char **argv) { normalFont.MapRange('N', 'Z', 0, 2); normalFont.MapRange('a', 'm', 0, 3); normalFont.MapRange('n', 'z', 0, 4); + normalFont.MapChar(':', 10, 0); + normalFont.MapChar('!', 10, 0); + normalFont.MapChar('?', 10, 0); battleRes.normalFont = &normalFont; BattleState *battleState(new BattleState(bg, monstersLayout, heroesLayout, &battleRes)); diff --git a/test-data/normal-font.png b/test-data/normal-font.png index b2b1a40..0bd50d0 100644 Binary files a/test-data/normal-font.png and b/test-data/normal-font.png differ