1 #ifndef INC_MENU_H
2 #define INC_MENU_H
3 
4 #include <string>
5 #include <iostream>
6 #include <sstream>
7 
8 #include "keybindings.h"
9 
10 enum MenuNodeType
11 {
12     MNT_NONE,
13     MNT_MENU,
14     MNT_LEAF
15 };
16 enum LeafReturn
17 {
18     LR_NONE,
19     LR_QUIT,
20     LR_SURRENDER,
21     LR_NEWSPEED,
22     LR_SETRES,
23     LR_NEWBACKGROUND,
24     LR_EXITMENU,
25     LR_SAVESETTINGS
26 };
27 
28 class Menu;
29 class MenuLeaf;
30 
31 class Menu
32 {
33     public:
34 	std::string title;
35 
36 	/* menus and leaves give the menu or leaf to be found in each
37 	 * direction; 0->west, 1->north, 2->east, 3->south. For each i, at
38 	 * most one of menus[i] and leaves[i] should be non-NULL.
39 	 */
40 	Menu* menus[4];
41 	MenuLeaf* leaves[4];
42 
43 	std::string textOfDir(int dir) const;
44 
45 	Menu();
46 
47 	Menu(std::string title,
48 		Menu* m1=NULL, MenuLeaf* ml1=NULL,
49 		Menu* m2=NULL, MenuLeaf* ml2=NULL,
50 		Menu* m3=NULL, MenuLeaf* ml3=NULL,
51 		Menu* m4=NULL, MenuLeaf* ml4=NULL
52 		);
53 };
54 
55 class MenuLeaf
56 {
57     public:
58 	virtual std::string name() =0;
59 	virtual LeafReturn act() =0;
60 
~MenuLeaf()61 	virtual ~MenuLeaf() {};
62 };
63 
64 class MenuLeafToggleBool : public MenuLeaf
65 {
66     private:
67 	std::string varName;
68 	bool* var;
69     public:
70 	std::string name();
71 	LeafReturn act();
72 
MenuLeafToggleBool(std::string varName,bool * var)73 	MenuLeafToggleBool(std::string varName, bool* var) :
74 	    varName(varName), var(var) {}
75 };
76 
77 class MenuLeafCycleAA : public MenuLeaf
78 {
79     public:
80 	std::string name();
81 	LeafReturn act();
82 
MenuLeafCycleAA()83 	MenuLeafCycleAA() {}
84 };
85 
86 class MenuLeafCycleFreq : public MenuLeaf
87 {
88     public:
89 	std::string name();
90 	LeafReturn act();
91 
MenuLeafCycleFreq()92 	MenuLeafCycleFreq() {}
93 };
94 
95 template<typename T>
96 class MenuLeafIncVar : public MenuLeaf
97 {
98     private:
99 	T* var;
100 	std::string varName;
101 	T amount;
102 	T min;
103 	T max;
104     public:
name()105 	std::string name() {
106 	    return ( (amount >= 0) ? "Inc " : "Dec " ) + varName;
107 	}
act()108 	LeafReturn act() {
109 	    *var += amount;
110 	    if (*var < min)
111 		*var = min;
112 	    if (max > min && *var > max)
113 		*var = max;
114 	    return LR_NONE;
115 	}
116 
117 	MenuLeafIncVar(T* var, std::string(varName), T amount, T min = 0, T max = 0) :
var(var)118 	    var(var), varName(varName), amount(amount), min(min), max(max) {}
119 };
120 
121 template<typename T>
122 class MenuLeafShowVar : public MenuLeaf
123 {
124     private:
125 	T* var;
126 	std::string varName;
127 	LeafReturn ret;
128     public:
name()129 	std::string name() {
130 	    std::stringstream ss;
131 	    ss << varName << ": " << *var;
132 	    return ss.str();
133 	}
act()134 	LeafReturn act() { return ret; }
135 
136 	MenuLeafShowVar(T* var, std::string(varName), LeafReturn ret=LR_NONE) :
var(var)137 	    var(var), varName(varName), ret(ret) {}
138 };
139 
140 class MenuLeafReturn : public MenuLeaf
141 {
142     private:
143 	std::string text;
144 	LeafReturn ret;
145     public:
name()146 	std::string name() { return text; }
act()147 	LeafReturn act() { return ret; }
148 
MenuLeafReturn(std::string text,LeafReturn ret)149 	MenuLeafReturn(std::string text, LeafReturn ret) :
150 	    text(text), ret(ret) {}
151 };
152 
153 class MenuLeafSetRes : public MenuLeaf
154 {
155     public:
156 	std::string name();
act()157 	LeafReturn act() { return LR_SETRES; }
158 };
159 
160 class MenuLeafCycleBpp : public MenuLeaf
161 {
162     public:
name()163 	std::string name() { return "Depth"; }
164 	LeafReturn act();
165 };
166 
167 class MenuLeafCycleBGType : public MenuLeaf
168 {
169     public:
170 	std::string name();
171 	LeafReturn act();
172 };
173 
174 class MenuLeafToggleFullscreen : public MenuLeaf
175 {
176     public:
name()177 	std::string name() { return "Fullscreen"; }
178 	LeafReturn act();
179 };
180 
181 class MenuLeafCycleRes : public MenuLeaf
182 {
183     public:
name()184 	std::string name() { return "Resolution"; }
185 	LeafReturn act();
186 };
187 
188 class MenuLeafSpeed : public MenuLeaf
189 {
190     public:
191 	std::string name();
192 	LeafReturn act();
193 
MenuLeafSpeed()194 	MenuLeafSpeed() {}
195 };
196 
197 class MenuLeafSetKey : public MenuLeaf
198 {
199     public:
200 	command selectedKey;
201 
202 	std::string name();
203 	LeafReturn act();
204 
MenuLeafSetKey()205 	MenuLeafSetKey() : selectedKey(C_FIRST) {}
206 };
207 
208 class MenuLeafPrevKey : public MenuLeaf
209 {
210     private:
211 	command* commandp;
212     public:
name()213 	std::string name() { return "Previous key"; }
214 	LeafReturn act();
MenuLeafPrevKey(command * commandp)215 	MenuLeafPrevKey(command* commandp) : commandp(commandp) {}
216 };
217 class MenuLeafNextKey : public MenuLeaf
218 {
219     private:
220 	command* commandp;
221     public:
name()222 	std::string name() { return "Next key"; }
223 	LeafReturn act();
MenuLeafNextKey(command * commandp)224 	MenuLeafNextKey(command* commandp) : commandp(commandp) {}
225 };
226 
227 class MenuLeafKeyConflicts : public MenuLeaf
228 {
229     private:
230 	command* commandp;
231 	command getConflictingCommand();
232     public:
233 	std::string name();
234 	LeafReturn act();
MenuLeafKeyConflicts(command * commandp)235 	MenuLeafKeyConflicts(command* commandp) : commandp(commandp) {}
236 };
237 
238 extern Menu topMenu;
239 
240 
241 struct SDL_Surface;
242 void drawMenu(SDL_Surface* surface, const Menu& menu);
243 
244 #endif /* INC_MENU_H */
245