1
// menus.cpp: ingame menu system (also used for scores and serverlist)
7
static int menustart = 0;
8
static int menutab = 1;
9
static g3d_gui *cgui = NULL;
11
static hashtable<char *, char *> guis;
12
static vector<char *> guistack;
13
static vector<char *> executelater;
14
static bool clearlater = false;
16
VARP(menudistance, 16, 40, 256);
18
vec menuinfrontofplayer()
21
vecfromyawpitch(camera1->yaw, 0, 1, 0, dir, false);
22
dir.mul(menudistance).add(camera1->o);
23
dir.z -= player->eyeheight-1;
27
int cleargui(int n = 0)
29
int clear = guistack.length();
30
if(n>0) clear = min(clear, n);
31
loopi(clear) delete[] guistack.pop();
32
if(!guistack.empty()) showgui(guistack.last());
36
void cleargui_(int *n)
41
#define GUI_TITLE_COLOR 0xFFDD88
42
#define GUI_BUTTON_COLOR 0xFFFFFF
43
#define GUI_TEXT_COLOR 0xDDFFDD
45
//@DOC name and icon are optional
46
void guibutton(char *name, char *action, char *icon)
49
int ret = cgui->button(name, GUI_BUTTON_COLOR, *icon ? icon : (strstr(action, "showgui") ? "menu" : "action"));
52
executelater.add(newstring(*action ? action : name));
55
else if(ret&G3D_ROLLOVER)
57
alias("guirollovername", name);
58
alias("guirolloveraction", action);
62
void guiimage(char *path, char *action, float *scale, int *overlaid)
64
if(cgui && cgui->image(path, *scale, *overlaid!=0)&G3D_UP && *action)
66
executelater.add(newstring(action));
71
void guitext(char *name)
73
if(cgui) cgui->text(name, GUI_TEXT_COLOR, "info");
76
void guititle(char *name)
78
if(cgui) cgui->title(name, GUI_TITLE_COLOR);
81
void guitab(char *name)
83
if(cgui) cgui->tab(name, GUI_TITLE_COLOR);
88
if(cgui) cgui->separator();
91
static void updateval(char *var, int val, char *onchange)
93
ident *id = getident(var);
96
else if(id->_type==ID_VAR) s_sprintf(assign)("%s %d", var, val);
97
else if(id->_type==ID_ALIAS) s_sprintf(assign)("%s = %d", var, val);
99
executelater.add(newstring(assign));
100
if(onchange[0]) executelater.add(newstring(onchange));
103
static int getval(char *var)
105
ident *id = getident(var);
107
else if(id->_type==ID_VAR) return *id->_storage;
108
else if(id->_type==ID_ALIAS) return atoi(id->_action);
112
void guislider(char *var, int *min, int *max, char *onchange)
115
int oldval = getval(var), val = oldval, vmin = *max ? *min : getvarmin(var), vmax = *max ? *max : getvarmax(var);
116
cgui->slider(val, vmin, vmax, GUI_TITLE_COLOR);
117
if(val != oldval) updateval(var, val, onchange);
120
void guicheckbox(char *name, char *var, int *on, int *off, char *onchange)
122
bool enabled = getval(var)!=*off;
123
if(cgui && cgui->button(name, GUI_BUTTON_COLOR, enabled ? "checkbox_on" : "checkbox_off")&G3D_UP)
125
updateval(var, enabled ? *off : (*on || *off ? *on : 1), onchange);
129
void guiradio(char *name, char *var, int *n, char *onchange)
131
bool enabled = getval(var)==*n;
132
if(cgui && cgui->button(name, GUI_BUTTON_COLOR, enabled ? "radio_on" : "radio_off")&G3D_UP)
134
if(!enabled) updateval(var, *n, onchange);
138
void guilist(char *contents)
146
void newgui(char *name, char *contents)
148
if(guis.access(name))
151
guis[name] = newstring(contents);
153
else guis[newstring(name)] = newstring(contents);
156
void showgui(char *name)
158
int pos = guistack.find(name);
161
if(!guis.access(name)) return;
162
if(guistack.empty()) menupos = menuinfrontofplayer();
163
guistack.add(newstring(name));
167
pos = guistack.length()-pos-1;
168
loopi(pos) delete[] guistack.pop();
171
menustart = lastmillis;
176
extern const char *showservers(g3d_gui *cgui);
179
const char *name = showservers(cgui);
182
s_sprintfd(connect)("connect %s", name);
183
executelater.add(newstring(connect));
189
COMMAND(newgui, "ss");
190
COMMAND(guibutton, "sss");
191
COMMAND(guitext, "s");
192
COMMAND(guiservers, "s");
193
COMMANDN(cleargui, cleargui_, "i");
194
COMMAND(showgui, "s");
196
COMMAND(guilist, "s");
197
COMMAND(guititle, "s");
199
COMMAND(guiimage,"ssfi");
200
COMMAND(guislider,"siis");
201
COMMAND(guiradio,"ssis");
202
COMMAND(guicheckbox, "ssiis");
203
COMMAND(guitab, "s");
205
static struct mainmenucallback : g3d_callback
207
void gui(g3d_gui &g, bool firstpass)
209
if(guistack.empty()) return;
210
char *name = guistack.last();
211
char **contents = guis.access(name);
212
if(!contents) return;
214
cgui->start(menustart, 0.03f, &menutab);
224
int level = guistack.length();
225
loopv(executelater) execute(executelater[i]);
226
executelater.deletecontentsa();
229
if(level==guistack.length()) guistack.deletecontentsa();
236
if(!guistack.empty())
238
if(camera1->o.dist(menupos) > menudistance*3) cleargui();
239
else g3d_addgui(&mmcb, menupos);