]> git.localhorst.tv Git - l2e.git/blobdiff - src/graphics/Menu.h
added some information about menus
[l2e.git] / src / graphics / Menu.h
index 90af3e479c55a484da9aca53f3f9581b6315e4c7..1cdddcdb01467cb752ebc979913a55a7fd03a34e 100644 (file)
@@ -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,20 +21,20 @@ namespace graphics {
 
 class Sprite;
 
-// TODO: alternate font for disabled entries
-// TODO: sprite for the cursor
 // TODO: animation when top row changes
 template<class T>
 class Menu {
 
 public:
-       explicit Menu(const Font *font = NULL, const Font *disabledFont = NULL, int charsPerEntry = 16, int rows = 1, 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; }
+       int CharsPerEntry() const { return charsPerEntry; }
 
        T &Selected() { return entries[selected].value; }
        const T &Selected() const { return entries[selected].value; }
@@ -45,6 +46,8 @@ public:
        void NextRow();
        void PreviousRow();
        void SelectIndex(int index);
+       int SelectedIndex() const { return selected; }
+       bool IsSelected(int index) const { return index == selected; }
 
        int EntryCount() const { return entries.size(); }
        T &ValueAt(int index) { return entries[index].value; }
@@ -54,6 +57,7 @@ public:
        void Disable(int index) { entries[index].enabled = false; }
        void Enable(int index) { entries[index].enabled = true; }
        void Reserve(int n) { entries.reserve(n); }
+       void Clear() { entries.clear(); }
 
        void Draw(SDL_Surface *dest, geometry::Point<int> position) const;
 
@@ -72,10 +76,12 @@ private:
        };
        const Font *font;
        const Font *disabledFont;
+       const Sprite *cursor;
        std::vector<Entry> entries;
        int charsPerEntry;
        int rows;
        int rowGap;
+       int iconSpace;
        int cols;
        int colGap;
        int selected;
@@ -85,12 +91,30 @@ private:
 
 
 template<class T>
-Menu<T>::Menu(const Font *font, const Font *disabledFont, int charsPerEntry, int rows, int rowGap, int cols, int colGap)
+Menu<T>::Menu()
+: font(0)
+, disabledFont(0)
+, cursor(0)
+, charsPerEntry(0)
+, rows(0)
+, rowGap(0)
+, iconSpace(0)
+, cols(0)
+, colGap(0)
+, selected(0)
+, topRow(0) {
+
+}
+
+template<class T>
+Menu<T>::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)
@@ -132,10 +156,10 @@ void Menu<T>::PreviousRow() {
 
 template<class T>
 void Menu<T>::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);
        }
@@ -145,17 +169,27 @@ void Menu<T>::SelectIndex(int index) {
 template<class T>
 void Menu<T>::Draw(SDL_Surface *dest, geometry::Point<int> 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<int> offset((i % cols) * (ColWidth() + colGap), (i / cols) * RowHeight());
+               geometry::Vector<int> iconOffset(
+                               (i % cols) * (ColWidth() + colGap),
+                               (i / cols) * RowHeight());
+               if (entries[start + i].icon) {
+                       entries[start + i].icon->Draw(dest, position + iconOffset);
+               }
+               geometry::Vector<int> labelOffset(iconOffset.X() +  + iconSpace, iconOffset.Y());
                if (entries[start + i].enabled) {
-                       font->DrawString(entries[start + i].title, dest, position + offset, charsPerEntry);
+                       font->DrawString(entries[start + i].title, dest, position + labelOffset, charsPerEntry);
                } else {
-                       disabledFont->DrawString(entries[start + i].title, dest, position + offset, charsPerEntry);
+                       disabledFont->DrawString(entries[start + i].title, dest, position + labelOffset, charsPerEntry);
                }
        }
+       geometry::Vector<int> cursorOffset(
+                       (selected % cols) * (ColWidth() + colGap) - cursor->Width(),
+                       ((selected - start) / cols) * RowHeight());
+       cursor->Draw(dest, position + cursorOffset);
 }
 
 }