X-Git-Url: http://git.localhorst.tv/?a=blobdiff_plain;f=src%2Fgraphics%2FMenu.h;h=172c3184d4e57d7912083a4f3b4f78eb3a9caacc;hb=859750479ac0c8febfaf4eb603fc599aef4571ca;hp=0a4a69885d7ff6dd81b2b1ceb63bbe8c1b8ff777;hpb=8c055cbdddac2114c130e6a6524ff887d89ccf53;p=l2e.git diff --git a/src/graphics/Menu.h b/src/graphics/Menu.h index 0a4a698..172c318 100644 --- a/src/graphics/Menu.h +++ b/src/graphics/Menu.h @@ -9,6 +9,7 @@ #define GRAPHICS_MENU_H_ #include "Font.h" +#include "Sprite.h" #include "../geometry/operators.h" #include "../geometry/Point.h" #include "../geometry/Vector.h" @@ -20,29 +21,40 @@ namespace graphics { class Sprite; +// TODO: animation when top row changes template class Menu { public: - Menu(const Font *font, int charsPerEntry, int rows, int rowGap = 0, int cols = 1, int colGap = 0); + Menu(); + Menu(const Font *font, const Font *disabledFont, const Sprite *cursor, int charsPerEntry, int rows, int rowGap = 0, int iconSpace = 0, int cols = 1, int colGap = 0); public: int Width() const; int Height() const; - int ColWidth() const { return font->CharWidth() * charsPerEntry; } + int ColWidth() const { return iconSpace + 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; } + bool SelectedIsEnabled() const { return entries[selected].enabled; } void NextItem(); void PreviousItem(); void NextRow(); void PreviousRow(); void SelectIndex(int index); + int SelectedIndex() const { return selected; } + bool IsSelected(int index) const { return index == selected; } - void Add(const char *title, const T &value, const Sprite *icon = 0) { entries.push_back(Entry(title, value, icon)); } + int EntryCount() const { return entries.size(); } + T &ValueAt(int index) { return entries[index].value; } + const T &ValueAt(int index) const { return entries[index].value; } + + void Add(const char *title, const T &value, bool enabled = true, const Sprite *icon = 0) { entries.push_back(Entry(title, value, enabled, icon)); } + void Disable(int index) { entries[index].enabled = false; } + void Enable(int index) { entries[index].enabled = true; } void Reserve(int n) { entries.reserve(n); } void Draw(SDL_Surface *dest, geometry::Point position) const; @@ -53,17 +65,21 @@ private: private: struct Entry { - Entry(const char *title, const T &value, const Sprite *icon = 0) - : title(title), icon(icon), value(value) { } + Entry(const char *title, const T &value, bool enabled = true, const Sprite *icon = 0) + : title(title), icon(icon), value(value), enabled(enabled) { } const char *title; const Sprite *icon; T value; + bool enabled; }; const Font *font; + const Font *disabledFont; + const Sprite *cursor; std::vector entries; int charsPerEntry; int rows; int rowGap; + int iconSpace; int cols; int colGap; int selected; @@ -73,11 +89,30 @@ private: template -Menu::Menu(const Font *font, int charsPerEntry, int rows, int rowGap, int cols, int colGap) +Menu::Menu() +: font(0) +, disabledFont(0) +, cursor(0) +, charsPerEntry(0) +, rows(0) +, rowGap(0) +, iconSpace(0) +, cols(0) +, colGap(0) +, selected(0) +, topRow(0) { + +} + +template +Menu::Menu(const Font *font, const Font *disabledFont, const Sprite *cursor, int charsPerEntry, int rows, int rowGap, int iconSpace, int cols, int colGap) : font(font) +, disabledFont(disabledFont ? disabledFont : font) +, cursor(cursor) , charsPerEntry(charsPerEntry) , rows(rows) , rowGap(rowGap) +, iconSpace(iconSpace) , cols(cols) , colGap(colGap) , selected(0) @@ -119,10 +154,10 @@ void Menu::PreviousRow() { template void Menu::SelectIndex(int index) { - if (index < 0 || entries.size() < index) return; + if (index < 0 || int(entries.size()) <= index) return; selected = index; - if (GetRow(selected) - rows > topRow) { - topRow = GetRow(selected) - rows; + if (topRow <= GetRow(selected) - rows) { + topRow = GetRow(selected) - rows + 1; } else if (GetRow(selected) < topRow) { topRow = GetRow(selected); } @@ -132,13 +167,27 @@ void Menu::SelectIndex(int index) { template void Menu::Draw(SDL_Surface *dest, geometry::Point position) const { int start(topRow * cols); - int slots((topRow + rows) * cols); + int slots(rows * cols); int items(entries.size() - start); - int end(items < slots ? items : slots); + int end(start + (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); + geometry::Vector iconOffset( + (i % cols) * (ColWidth() + colGap), + (i / cols) * RowHeight()); + if (entries[start + i].icon) { + entries[start + i].icon->Draw(dest, position + iconOffset); + } + geometry::Vector labelOffset(iconOffset.X() + + iconSpace, iconOffset.Y()); + if (entries[start + i].enabled) { + font->DrawString(entries[start + i].title, dest, position + labelOffset, charsPerEntry); + } else { + disabledFont->DrawString(entries[start + i].title, dest, position + labelOffset, charsPerEntry); + } } + geometry::Vector cursorOffset( + (selected % cols) * (ColWidth() + colGap) - cursor->Width(), + ((selected - start) / cols) * RowHeight()); + cursor->Draw(dest, position + cursorOffset); } }