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