1 /***************************************************************************
2 gui.cpp - The graphical user interface: menu's etc.
3 -------------------
4 begin : vr jan 31 2003
5 copyright : (C) 2003 by CJP
6 email : cornware-cjp@users.sourceforge.net
7 ***************************************************************************/
8
9 /***************************************************************************
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 ***************************************************************************/
17
18 #include <cstdio>
19 #include <GL/gl.h>
20
21 #include "SDL.h"
22
23 #include <libintl.h>
24 #define _(String) gettext (String)
25
26 #include "gui.h"
27 #include "inputbox.h"
28 #include "keyinputbox.h"
29 #include "listbox.h"
30 #include "messagebox.h"
31 #include "colorselect.h"
32 #include "fileselect.h"
33
34
CGUI(CWinSystem * winsys)35 CGUI::CGUI(CWinSystem *winsys)
36 {
37 //TODO: get conffile options
38 m_WinSys = winsys;
39 m_ChildWidget = NULL;
40 m_in2DMode = false;
41 }
42
~CGUI()43 CGUI::~CGUI(){
44 }
45
46 bool znabled, fnabled;
47
enter2DMode()48 void CGUI::enter2DMode()
49 {
50 if(m_in2DMode) return;
51 m_in2DMode = true;
52
53 znabled = glIsEnabled(GL_DEPTH_TEST);
54 if(znabled) glDisable(GL_DEPTH_TEST);
55 fnabled = glIsEnabled(GL_FOG);
56 if(fnabled) glDisable(GL_FOG);
57 glDisable(GL_LIGHTING);
58 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
59
60 glEnable(GL_SCISSOR_TEST);
61
62 int w = m_WinSys->getWidth();
63 int h = m_WinSys->getHeight();
64 onResize(0, 0, w, h);
65 }
66
leave2DMode()67 void CGUI::leave2DMode()
68 {
69 if(!m_in2DMode) return;
70 m_in2DMode = false;
71
72 glEnable(GL_LIGHTING);
73 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
74 if(znabled) glEnable(GL_DEPTH_TEST);
75 if(fnabled) glEnable(GL_FOG);
76
77 glDisable(GL_SCISSOR_TEST);
78 }
79
start()80 void CGUI::start()
81 {
82 enter2DMode();
83
84 if(m_ChildWidget != NULL)
85 m_WinSys->runLoop(this);
86
87 leave2DMode();
88 }
89
onMouseMove(int x,int y,unsigned int buttons)90 int CGUI::onMouseMove(int x, int y, unsigned int buttons)
91 {
92 return m_ChildWidget->onMouseMove(x, y, buttons);
93 }
94
onMouseClick(int x,int y,unsigned int buttons)95 int CGUI::onMouseClick(int x, int y, unsigned int buttons)
96 {
97 return m_ChildWidget->onMouseClick(x, y, buttons);
98 }
99
onKeyPress(int key)100 int CGUI::onKeyPress(int key)
101 {
102 return m_ChildWidget->onKeyPress(key);
103 }
104
onResize(int x,int y,int w,int h)105 int CGUI::onResize(int x, int y, int w, int h)
106 {
107 CWidget::onResize(x, y, w, h);
108
109 //no perspective
110 glMatrixMode( GL_PROJECTION );
111 glLoadIdentity();
112 glOrtho(0, w, 0, h, -1, 1);
113 glMatrixMode( GL_MODELVIEW );
114 glLoadIdentity();
115 glViewport(0, 0, w, h);
116 glScissor(0, 0, w, h);
117
118 if(m_ChildWidget == NULL) return 0;
119
120 return m_ChildWidget->onResize(1, 1, w-2, h-2);
121 }
122
onRedraw()123 int CGUI::onRedraw()
124 {
125 //Firt clear the screen
126 glDisable(GL_SCISSOR_TEST);
127 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
128 glEnable(GL_SCISSOR_TEST);
129
130 return m_ChildWidget->onRedraw();
131 }
132
onIdle()133 int CGUI::onIdle()
134 {
135 return m_ChildWidget->onIdle();
136 }
137
showSettingBox(const CString & field,const CString & deflt,const CString & metaData,bool * cancelled)138 CString CGUI::showSettingBox(const CString &field, const CString &deflt, const CString &metaData, bool *cancelled)
139 {
140 CString title;
141 CString options;
142
143 int pos = metaData.inStr('|');
144 if(pos < 0)
145 {
146 title = metaData;
147 }
148 else
149 {
150 title = metaData.mid(0, pos);
151 options = metaData.mid(pos+1);
152 }
153
154 CString options_case = options;
155 options.toUpper();
156
157 //Default title = field name
158 if(title == "") title = field;
159
160 if(options.inStr("YESNO") >= 0)
161 {
162 bool ret = showYNMessageBox(title, cancelled);
163 if(ret) return "true";
164 return "false";
165 }
166
167 if(options.inStr("LANGUAGE") >= 0)
168 {
169 vector<CString> namelist, codelist;
170 codelist.push_back("system"); namelist.push_back(_("System's default language"));
171 codelist.push_back("de_DE"); namelist.push_back("Deutsch");
172 codelist.push_back("en"); namelist.push_back("English");
173 codelist.push_back("fr_FR"); namelist.push_back("Fran�ais");
174 codelist.push_back("hu_HU"); namelist.push_back("Magyar");
175 codelist.push_back("nl_NL"); namelist.push_back("Nederlands");
176 codelist.push_back("pt_BR"); namelist.push_back("Portugu�s Brasileiro");
177
178 CString defltname = deflt;
179 for(unsigned int i=0; i < codelist.size(); i++)
180 if(codelist[i] == deflt)
181 {
182 defltname = namelist[i];
183 break;
184 }
185
186 CString ret = showChoiceBox(_("Language:"), namelist, defltname, cancelled);
187
188 for(unsigned int i=0; i < codelist.size(); i++)
189 if(namelist[i] == ret)
190 return codelist[i];
191
192 return ret;
193 }
194
195 if(options.inStr("DISPLAY") >= 0)
196 {
197 bool fullscreen = showYNMessageBox(_("Full screen mode?"), cancelled);
198 if(cancelled != NULL && *cancelled) return deflt;
199
200 SDL_Rect **modes = SDL_ListModes(NULL, SDL_OPENGL | SDL_FULLSCREEN | SDL_ANYFORMAT);
201
202 if(!fullscreen)
203 {
204 CString w = showInputBox(_("Enter window width:"), theWinSystem->getWidth(), cancelled);
205 if(cancelled != NULL && *cancelled) return deflt;
206 CString h = showInputBox(_("Enter window height:"), theWinSystem->getHeight(), cancelled);
207 if(cancelled != NULL && *cancelled) return deflt;
208 return CString("window:") + w + "x" + h;
209 }
210
211 if(modes == NULL || modes == (SDL_Rect **)-1)
212 {
213 CString w = showInputBox(_("Enter screen resolution width:"), theWinSystem->getWidth(), cancelled);
214 if(cancelled != NULL && *cancelled) return deflt;
215 CString h = showInputBox(_("Enter screen resolution height:"), theWinSystem->getHeight(), cancelled);
216 if(cancelled != NULL && *cancelled) return deflt;
217 return CString("fullscreen:") + w + "x" + h;
218 }
219
220 //List fullscreen modes:
221 vector<CString> list;
222
223 for(unsigned int i=0; modes[i] != NULL; i++)
224 {
225 CString modename;
226 modename.format("%dx%d", 80, modes[i]->w, modes[i]->h);
227 list.push_back(modename);
228 }
229 list.push_back(_("Default resolution"));
230
231 CString defltmode; defltmode.format("%dx%d", 80, theWinSystem->getWidth(), theWinSystem->getHeight());
232 CString ret = showChoiceBox(_("Select a screen resolution:"), list, defltmode, cancelled);
233
234 if(ret == list.back()) return "fullscreen";
235
236 return CString("fullscreen:") + ret;
237 }
238
239 if(options.inStr("SWITCH") >= 0)
240 {
241 //Read possible options from options string
242 vector<CString> list;
243
244 int pos = options.inStr("SWITCH");
245 CString liststring = options_case.mid(pos+6);
246 pos = liststring.inStr(':');
247 if(pos >= 0)
248 {
249 liststring = liststring.mid(pos+1);
250
251 while(true)
252 {
253 pos = liststring.inStr(';');
254 if(pos >= 0)
255 {
256 list.push_back(liststring.mid(0, pos));
257 liststring = liststring.mid(pos+1);
258 }
259 else
260 {
261 list.push_back(liststring);
262 break;
263 }
264 }
265 }
266
267 return showChoiceBox(title, list, deflt, cancelled);
268 }
269
270 if(options.inStr("KEY") >= 0)
271 {
272 CString ret = showKeyInputBox(title, deflt, cancelled);
273 if(cancelled != NULL && *cancelled) return deflt;
274 return ret;
275 }
276
277 //Fall-back: a simple input box
278 return showInputBox(title, deflt, cancelled);
279 }
280
showChoiceBox(const CString & title,const vector<CString> & options,const CString & deflt,bool * cancelled)281 CString CGUI::showChoiceBox(const CString &title, const vector<CString> &options, const CString &deflt, bool *cancelled)
282 {
283 CListBox *listbox = new CListBox;
284 listbox->setTitle(title);
285 listbox->setOptions(options);
286
287 //Set default
288 for(unsigned int i=0; i < options.size(); i++)
289 if(options[i] == deflt)
290 {
291 listbox->setSelected(i);
292 break;
293 }
294
295 listbox->m_Wrel = 0.5;
296 listbox->m_Hrel = 0.5;
297 listbox->m_Xrel = 0.25;
298 listbox->m_Yrel = 0.25;
299 m_ChildWidget->m_Widgets.push_back(listbox);
300 m_WinSys->runLoop(this);
301 CString ret = options[listbox->getSelected()];
302 if(cancelled != NULL)
303 *cancelled = listbox->m_Cancelled;
304
305 m_ChildWidget->m_Widgets.resize(m_ChildWidget->m_Widgets.size()-1); //removes messagebox
306 delete listbox;
307
308 return ret;
309 }
310
showInputBox(const CString & title,const CString & deflt,bool * cancelled)311 CString CGUI::showInputBox(const CString &title, const CString &deflt, bool *cancelled)
312 {
313 CInputBox *inputbox = new CInputBox;
314 inputbox->setTitle(title);
315 inputbox->m_Text = deflt;
316
317 inputbox->m_Wrel = 0.5;
318 inputbox->m_Hrel = 0.4;
319 inputbox->m_Xrel = 0.25;
320 inputbox->m_Yrel = 0.3;
321 m_ChildWidget->m_Widgets.push_back(inputbox);
322 m_WinSys->runLoop(this);
323
324 CString ret = inputbox->m_Text;
325 if(cancelled != NULL)
326 *cancelled = inputbox->m_Cancelled;
327
328 if(inputbox->m_Cancelled)
329 ret = deflt;
330
331 m_ChildWidget->m_Widgets.resize(m_ChildWidget->m_Widgets.size()-1); //removes inputbox
332 delete inputbox;
333
334 return ret;
335 }
336
showKeyInputBox(const CString & title,const CString & deflt,bool * cancelled)337 CString CGUI::showKeyInputBox(const CString &title, const CString &deflt, bool *cancelled)
338 {
339 CKeyInputBox *inputbox = new CKeyInputBox;
340 inputbox->setTitle(title);
341 inputbox->m_Key = name2key(deflt);
342
343 inputbox->m_Wrel = 0.5;
344 inputbox->m_Hrel = 0.4;
345 inputbox->m_Xrel = 0.25;
346 inputbox->m_Yrel = 0.3;
347 m_ChildWidget->m_Widgets.push_back(inputbox);
348 m_WinSys->runLoop(this);
349
350 CString ret = key2name(inputbox->m_Key);
351 if(cancelled != NULL)
352 *cancelled = inputbox->m_Cancelled;
353
354 if(inputbox->m_Cancelled)
355 ret = deflt;
356
357 m_ChildWidget->m_Widgets.resize(m_ChildWidget->m_Widgets.size()-1); //removes inputbox
358 delete inputbox;
359
360 return ret;
361 }
362
showYNMessageBox(const CString & title,bool * cancelled)363 bool CGUI::showYNMessageBox(const CString &title, bool *cancelled)
364 {
365 CMessageBox *messagebox = new CMessageBox;
366 messagebox->setTitle(title);
367 messagebox->m_Type = CMessageBox::eYesNo;
368
369 messagebox->m_Wrel = 0.5;
370 messagebox->m_Hrel = 0.4;
371 messagebox->m_Xrel = 0.25;
372 messagebox->m_Yrel = 0.3;
373 m_ChildWidget->m_Widgets.push_back(messagebox);
374 m_WinSys->runLoop(this);
375 bool ret = (messagebox->m_Selected == 0);
376 if(cancelled != NULL)
377 *cancelled = messagebox->m_Cancelled;
378
379 m_ChildWidget->m_Widgets.resize(m_ChildWidget->m_Widgets.size()-1); //removes messagebox
380 delete messagebox;
381
382 return ret;
383 }
384
showMessageBox(const CString & title)385 void CGUI::showMessageBox(const CString &title)
386 {
387 CMessageBox *messagebox = new CMessageBox;
388 messagebox->setTitle(title);
389 messagebox->m_Type = CMessageBox::eOK;
390
391 messagebox->m_Wrel = 0.5;
392 messagebox->m_Hrel = 0.4;
393 messagebox->m_Xrel = 0.25;
394 messagebox->m_Yrel = 0.3;
395 m_ChildWidget->m_Widgets.push_back(messagebox);
396 m_WinSys->runLoop(this);
397 m_ChildWidget->m_Widgets.resize(m_ChildWidget->m_Widgets.size()-1); //removes messagebox
398 delete messagebox;
399 }
400
showColorSelect(const CString & title,CVector deflt,bool * cancelled)401 CVector CGUI::showColorSelect(const CString &title, CVector deflt, bool *cancelled)
402 {
403 CColorSelect *selector = new CColorSelect;
404 selector->setTitle(title);
405 selector->m_Color = deflt;
406
407 selector->m_Wrel = 0.5;
408 selector->m_Hrel = 0.4;
409 selector->m_Xrel = 0.25;
410 selector->m_Yrel = 0.3;
411 m_ChildWidget->m_Widgets.push_back(selector);
412 m_WinSys->runLoop(this);
413
414 CVector ret = selector->m_Color;
415 if(cancelled != NULL)
416 *cancelled = selector->m_Cancelled;
417
418 if(selector->m_Cancelled)
419 ret = deflt;
420
421 m_ChildWidget->m_Widgets.resize(m_ChildWidget->m_Widgets.size()-1); //removes selector
422 delete selector;
423
424 return ret;
425 }
426
showFileSelect(const CString & title,CString extension,bool * cancelled)427 CString CGUI::showFileSelect(const CString &title, CString extension, bool *cancelled)
428 {
429 CFileSelect *selector = new CFileSelect;
430 selector->setTitle(title);
431
432 selector->setExtension(extension);
433
434 selector->m_Wrel = 0.5;
435 selector->m_Hrel = 0.6;
436 selector->m_Xrel = 0.25;
437 selector->m_Yrel = 0.2;
438 m_ChildWidget->m_Widgets.push_back(selector);
439 m_WinSys->runLoop(this);
440
441 CString ret = selector->getFullName();
442 if(cancelled != NULL)
443 *cancelled = selector->m_Cancelled;
444
445 if(selector->m_Cancelled)
446 ret = "";
447
448 m_ChildWidget->m_Widgets.resize(m_ChildWidget->m_Widgets.size()-1); //removes selector
449 delete selector;
450
451 return ret;
452 }
453
key2name(int key) const454 CString CGUI::key2name(int key) const
455 {
456 return "";
457 }
458
name2key(const CString & name) const459 int CGUI::name2key(const CString &name) const
460 {
461 return -1;
462 }
463