]> git.localhorst.tv Git - l2e.git/blobdiff - src/graphics/Menu.h
made third column hack of menus configurable
[l2e.git] / src / graphics / Menu.h
index e42f24e0cfcf7334777f99616aaa6fa34c44b990..d83b2a5e9b540801b88128b77f4d41002bc36521 100644 (file)
@@ -1,10 +1,3 @@
-/*
- * Menu.h
- *
- *  Created on: Aug 8, 2012
- *      Author: holy
- */
-
 #ifndef GRAPHICS_MENU_H_
 #define GRAPHICS_MENU_H_
 
@@ -13,6 +6,7 @@
 #include "Sprite.h"
 #include "../geometry/Vector.h"
 
+#include <algorithm>
 #include <vector>
 #include <SDL.h>
 
@@ -24,6 +18,7 @@ struct MenuProperties {
        const Font *font;
        const Font *disabledFont;
        const Sprite *cursor;
+       const Sprite *selectedCursor;
        int charsPerEntry;
        int rows;
        int rowGap;
@@ -33,16 +28,17 @@ struct MenuProperties {
        int charsPerNumber;
        int charsPerAdditionalText;
        int additionalTextGap;
+       int thirdColumnHack;
        char delimiter;
        bool wrapX;
        bool wrapY;
 
        MenuProperties()
-       : font(0), disabledFont(0), cursor(0)
+       : font(0), disabledFont(0), cursor(0), selectedCursor(0)
        , charsPerEntry(0), rows(1), rowGap(0)
        , iconSpace(0), cols(1), colGap(0)
        , charsPerNumber(0), charsPerAdditionalText(0)
-       , additionalTextGap(0), delimiter(':')
+       , additionalTextGap(0), thirdColumnHack(0), delimiter(':')
        , wrapX(false), wrapY(false) { }
 
        static void CreateTypeDescription();
@@ -59,6 +55,14 @@ public:
        Menu(const MenuProperties &);
 
 public:
+       void SetInactive() { state = STATE_INACTIVE; }
+       void SetActive() { state = STATE_ACTIVE; }
+       void SetSelected() { state = STATE_SELECTED; }
+       void SetDualSelection() { state = STATE_DUAL; secondarySelection = selected; }
+       bool IsActive() const { return state == STATE_ACTIVE; }
+       bool HasSelected() const { return state == STATE_SELECTED; }
+       bool InDualMode() const { return state == STATE_DUAL; }
+
        int Width() const;
        int Height() const;
        int ColWidth() const;
@@ -71,12 +75,22 @@ public:
        int SelectedNumber() const { return entries[selected].number; }
        bool SelectedIsEnabled() const { return entries[selected].enabled; }
 
+       T &SecondarySelection() { return entries[secondarySelection].value; }
+       const T &SecondarySelection() const { return entries[secondarySelection].value; }
+       const char *SecondaryTitle() const { return entries[secondarySelection].title; }
+       int SecondaryNumber() const { return entries[secondarySelection].number; }
+       bool SecondaryIsEnabled() const { return entries[secondarySelection].enabled; }
+
+       void SwapSelected() { SwapEntriesAt(selected, secondarySelection); }
+       void SwapEntriesAt(int lhs, int rhs) { std::swap(entries[lhs], entries[rhs]); }
+
        void NextItem();
        void PreviousItem();
        void NextRow();
        void PreviousRow();
        void SelectIndex(int index);
        int SelectedIndex() const { return selected; }
+       int SecondaryIndex() const { return secondarySelection; }
        bool IsSelected(int index) const { return index == selected; }
 
        int EntryCount() const { return entries.size(); }
@@ -89,6 +103,7 @@ public:
        void Enable(int index) { entries[index].enabled = true; }
        void Reserve(int n) { entries.reserve(n); }
        void Clear() { entries.clear(); }
+       void ClearEntry(int at) { entries[at] = Entry(0, T(), false); }
 
        void Draw(SDL_Surface *dest, const geometry::Vector<int> &position) const;
 
@@ -109,7 +124,15 @@ private:
        };
        std::vector<Entry> entries;
        int selected;
+       int secondarySelection;
        int topRow;
+       enum State {
+               STATE_INACTIVE,
+               STATE_ACTIVE,
+               STATE_SELECTED,
+               STATE_DUAL,
+       };
+       State state;
 
 };
 
@@ -118,7 +141,9 @@ template<class T>
 Menu<T>::Menu()
 : MenuProperties()
 , selected(0)
-, topRow(0) {
+, secondarySelection(0)
+, topRow(0)
+, state(STATE_ACTIVE) {
 
 }
 
@@ -126,7 +151,9 @@ template<class T>
 Menu<T>::Menu(const MenuProperties &p)
 : MenuProperties(p)
 , selected(0)
-, topRow(0) {
+, secondarySelection(0)
+, topRow(0)
+, state(STATE_ACTIVE) {
 
 }
 
@@ -215,10 +242,9 @@ void Menu<T>::Draw(SDL_Surface *dest, const geometry::Vector<int> &position) con
                                (i % cols) * (ColWidth() + colGap),
                                (i / cols) * RowHeight());
 
-               // Third column hack!
-               // This fixes the position of the "DROP" item in the inventory menu.
-               if (i % cols == 2) {
-                       iconOffset += geometry::Vector<int>(font->CharWidth(), 0);
+               // This fixes the position of the third column of the inventory and capsule menus.
+               if (thirdColumnHack && i % cols == 2) {
+                       iconOffset += geometry::Vector<int>(font->CharWidth() * thirdColumnHack, 0);
                }
 
                if (entries[start + i].icon) {
@@ -247,7 +273,30 @@ void Menu<T>::Draw(SDL_Surface *dest, const geometry::Vector<int> &position) con
        geometry::Vector<int> cursorOffset(
                        (selected % cols) * (ColWidth() + colGap) - cursor->Width(),
                        ((selected - start) / cols) * RowHeight());
-       cursor->Draw(dest, position + cursorOffset);
+       // This fixes the position of the third column of the inventory and capsule menus.
+       if (thirdColumnHack && selected % cols == 2) {
+               cursorOffset += geometry::Vector<int>(font->CharWidth() * thirdColumnHack, 0);
+       }
+       switch (state) {
+               case STATE_INACTIVE:
+                       break;
+               case STATE_ACTIVE:
+                       cursor->Draw(dest, position + cursorOffset);
+                       break;
+               case STATE_SELECTED:
+                       selectedCursor->Draw(dest, position + cursorOffset);
+                       break;
+               case STATE_DUAL:
+                       cursor->Draw(dest, position + cursorOffset
+                                       - geometry::Vector<int>(selectedCursor->Width(), 0));
+                       if (secondarySelection >= start && secondarySelection <= end) {
+                               geometry::Vector<int> secondaryOffset(
+                                               (secondarySelection % cols) * (ColWidth() + colGap) - cursor->Width(),
+                                               ((secondarySelection - start) / cols) * RowHeight());
+                               selectedCursor->Draw(dest, position + secondaryOffset);
+                       }
+                       break;
+       }
 }
 
 }