1 /***************************************************************************
2 guiobject.cpp
3 -------------------
4 created : Fri Aug 13 22:25:06 CEST 1999
5 copyright : (C) 1999 by Eric Espie
6 email : torcs@free.fr
7 version : $Id: guiobject.cpp,v 1.3.2.3 2013/08/27 14:26:58 berniw Exp $
8 ***************************************************************************/
9
10 /***************************************************************************
11 * *
12 * This program is free software; you can redistribute it and/or modify *
13 * it under the terms of the GNU General Public License as published by *
14 * the Free Software Foundation; either version 2 of the License, or *
15 * (at your option) any later version. *
16 * *
17 ***************************************************************************/
18
19
20 #ifdef WIN32
21 #include <windows.h>
22 #endif
23 #include <tgfclient.h>
24 #include "gui.h"
25
26 void
gfuiObjectInit(void)27 gfuiObjectInit(void)
28 {
29 }
30
31 void
gfuiPrintString(int x,int y,GfuiFontClass * font,const char * string)32 gfuiPrintString(int x, int y, GfuiFontClass *font, const char *string)
33 {
34 glEnable(GL_TEXTURE_2D);
35 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
36 glEnable(GL_ALPHA_TEST);
37 glAlphaFunc(GL_GREATER, 0.1) ;
38 font->output(x, y, string);
39 glDisable(GL_ALPHA_TEST);
40 glDisable(GL_TEXTURE_2D);
41 }
42
GfuiPrintString(const char * text,float * fgColor,int font,int x,int y,int align)43 void GfuiPrintString(const char *text, float *fgColor, int font, int x, int y, int align)
44 {
45 glEnable(GL_TEXTURE_2D);
46 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
47 glEnable(GL_ALPHA_TEST);
48 glAlphaFunc(GL_GREATER, 0.1) ;
49 glColor4fv(fgColor);
50 switch(align&0xF0) {
51 case 0x00 /* LEFT */:
52 gfuiFont[font]->output(x, y, text);
53 break;
54 case 0x10 /* CENTER */:
55 gfuiFont[font]->output(x - gfuiFont[font]->getWidth(text) / 2, y, text);
56 break;
57 case 0x20 /* RIGHT */:
58 gfuiFont[font]->output(x - gfuiFont[font]->getWidth(text), y, text);
59 break;
60 }
61 glDisable(GL_ALPHA_TEST);
62 glDisable(GL_TEXTURE_2D);
63 }
64
GfuiFontHeight(int font)65 int GfuiFontHeight(int font)
66 {
67 return gfuiFont[font]->getHeight();
68 }
69
GfuiFontWidth(int font,const char * text)70 int GfuiFontWidth(int font, const char *text)
71 {
72 return gfuiFont[font]->getWidth(text);
73 }
74
75 void
GfuiDrawCursor()76 GfuiDrawCursor()
77 {
78 float xf = (float)(GfuiMouse.X);
79 float yf = (float)(GfuiMouse.Y);
80
81 #define SCALE 1.3
82
83 glColor4fv(GfuiScreen->mouseColor[0]) ;
84 glBegin(GL_TRIANGLES);
85 glVertex2f(xf, yf);
86 glVertex2f(xf + 4.8 * SCALE, yf - 10.4 * SCALE);
87 glVertex2f(xf + 6.4 * SCALE, yf - 6.4 * SCALE);
88 glEnd();
89
90 glBegin(GL_QUADS);
91 glVertex2f(xf + 5.6 * SCALE, yf - 6.4 * SCALE);
92 glVertex2f(xf + 6 * SCALE, yf - 6 * SCALE);
93 glVertex2f(xf + 12.4 * SCALE, yf - 12.4 * SCALE);
94 glVertex2f(xf + 12 * SCALE, yf - 12.8 * SCALE);
95 glEnd();
96
97 glColor4fv(GfuiScreen->mouseColor[1]) ;
98 glBegin(GL_TRIANGLES);
99 glVertex2f(xf, yf) ;
100 glVertex2f(xf + 10.4 * SCALE, yf - 4.8 * SCALE);
101 glVertex2f(xf + 6.4 * SCALE, yf - 6.4 * SCALE);
102 glEnd();
103
104 glBegin(GL_QUADS);
105 glVertex2f(xf + 6 * SCALE, yf - 6 * SCALE);
106 glVertex2f(xf + 6.4 * SCALE, yf - 4.8 * SCALE);
107 glVertex2f(xf + 12.8 * SCALE, yf - 12 * SCALE);
108 glVertex2f(xf + 12.4 * SCALE, yf - 12.4 * SCALE);
109 glEnd();
110
111 }
112
113 void
GfuiDraw(tGfuiObject * obj)114 GfuiDraw(tGfuiObject *obj)
115 {
116 if (obj->visible) {
117 switch (obj->widget){
118 case GFUI_LABEL:
119 gfuiDrawLabel(obj);
120 break;
121
122 case GFUI_BUTTON:
123 gfuiDrawButton(obj);
124 break;
125
126 case GFUI_GRBUTTON:
127 gfuiDrawGrButton(obj);
128 break;
129
130 case GFUI_SCROLLIST:
131 gfuiDrawScrollist(obj);
132 break;
133
134 case GFUI_EDITBOX:
135 gfuiDrawEditbox(obj);
136 break;
137
138 case GFUI_IMAGE:
139 gfuiDrawImage(obj);
140 break;
141 }
142 }
143 }
144
145
146 static int
gfuiMouseIn(tGfuiObject * obj)147 gfuiMouseIn(tGfuiObject *obj)
148 {
149 if ((GfuiMouse.X >= obj->xmin) &&
150 (GfuiMouse.X <= obj->xmax) &&
151 (GfuiMouse.Y >= obj->ymin) &&
152 (GfuiMouse.Y <= obj->ymax)) {
153 return 1;
154 }
155 return 0;
156 }
157
158 /** Remove the focus on the current element.
159 @ingroup gui
160 */
161 void
GfuiUnSelectCurrent(void)162 GfuiUnSelectCurrent(void)
163 {
164 tGfuiButton *button;
165 tGfuiEditbox *editbox;
166 tGfuiGrButton *grbutton;
167 tGfuiObject *obj;
168
169 obj = GfuiScreen->hasFocus;
170 if (obj == NULL) {
171 return;
172 }
173 GfuiScreen->hasFocus = (tGfuiObject*)NULL;
174 obj->focus = 0;
175 switch (obj->widget) {
176 case GFUI_BUTTON:
177 button = &(obj->u.button);
178 button->state = GFUI_BTN_RELEASED;
179 if (button->onFocusLost != NULL) {
180 button->onFocusLost(button->userDataOnFocus);
181 }
182 break;
183 case GFUI_GRBUTTON:
184 grbutton = &(obj->u.grbutton);
185 grbutton->state = GFUI_BTN_RELEASED;
186 if (grbutton->onFocusLost != NULL) {
187 grbutton->onFocusLost(grbutton->userDataOnFocus);
188 }
189 break;
190 case GFUI_EDITBOX:
191 editbox = &(obj->u.editbox);
192 editbox->state = GFUI_BTN_RELEASED;
193 if (editbox->onFocusLost != NULL) {
194 editbox->onFocusLost(editbox->userDataOnFocus);
195 }
196 break;
197 }
198 }
199
200 static void
gfuiLoseFocus(tGfuiObject * obj)201 gfuiLoseFocus(tGfuiObject *obj)
202 {
203 if (obj->state == GFUI_DISABLE) {
204 return;
205 }
206
207 tGfuiButton *button;
208 tGfuiEditbox *editbox;
209 tGfuiGrButton *grbutton;
210
211 GfuiScreen->hasFocus = (tGfuiObject*)NULL;
212 obj->focus = 0;
213 switch (obj->widget) {
214 case GFUI_BUTTON:
215 button = &(obj->u.button);
216 button->state = GFUI_BTN_RELEASED;
217 if (button->onFocusLost != NULL) {
218 button->onFocusLost(button->userDataOnFocus);
219 }
220 break;
221 case GFUI_GRBUTTON:
222 grbutton = &(obj->u.grbutton);
223 grbutton->state = GFUI_BTN_RELEASED;
224 if (grbutton->onFocusLost != NULL) {
225 grbutton->onFocusLost(grbutton->userDataOnFocus);
226 }
227 break;
228 case GFUI_EDITBOX:
229 editbox = &(obj->u.editbox);
230 editbox->state = GFUI_BTN_RELEASED;
231 if (editbox->onFocusLost != NULL) {
232 editbox->onFocusLost(editbox->userDataOnFocus);
233 }
234 break;
235 }
236 }
237
238 static void
gfuiSetFocus(tGfuiObject * obj)239 gfuiSetFocus(tGfuiObject *obj)
240 {
241 if (obj->state == GFUI_DISABLE) {
242 return;
243 }
244
245 tGfuiButton *button;
246 tGfuiEditbox *editbox;
247 tGfuiGrButton *grbutton;
248
249 if (GfuiScreen->hasFocus != NULL) {
250 gfuiLoseFocus(GfuiScreen->hasFocus);
251 }
252 GfuiScreen->hasFocus = obj;
253 obj->focus = 1;
254 switch (obj->widget) {
255 case GFUI_BUTTON:
256 button = &(obj->u.button);
257 if (button->onFocus != NULL) {
258 button->onFocus(button->userDataOnFocus);
259 }
260 break;
261 case GFUI_GRBUTTON:
262 grbutton = &(obj->u.grbutton);
263 if (grbutton->onFocus != NULL) {
264 grbutton->onFocus(grbutton->userDataOnFocus);
265 }
266 break;
267 case GFUI_EDITBOX:
268 editbox = &(obj->u.editbox);
269 if (editbox->onFocus != NULL) {
270 editbox->onFocus(editbox->userDataOnFocus);
271 }
272 break;
273 }
274 }
275
276 void
gfuiUpdateFocus(void)277 gfuiUpdateFocus(void)
278 {
279 tGfuiObject *curObject;
280
281 curObject = GfuiScreen->hasFocus;
282 if (curObject != NULL) {
283 if (gfuiMouseIn(curObject)) {
284 return; /* focus has not changed */
285 }
286 if (curObject->focusMode != GFUI_FOCUS_MOUSE_CLICK) {
287 gfuiLoseFocus(GfuiScreen->hasFocus);
288 GfuiScreen->hasFocus = (tGfuiObject*)NULL;
289 }
290 }
291
292 /* Search for a new focused object */
293 curObject = GfuiScreen->objects;
294 if (curObject != NULL) {
295 do {
296 curObject = curObject->next;
297 if ((curObject->visible == 0) ||
298 (curObject->focusMode == GFUI_FOCUS_NONE) ||
299 ((curObject->focusMode == GFUI_FOCUS_MOUSE_CLICK) && (GfuiScreen->mouse == 0))) {
300 continue;
301 }
302 if (gfuiMouseIn(curObject)) {
303 gfuiSetFocus(curObject);
304 break;
305 }
306 } while (curObject != GfuiScreen->objects);
307 }
308 }
309
310 void
gfuiSelectNext(void *)311 gfuiSelectNext(void * /* dummy */)
312 {
313 tGfuiObject *startObject;
314 tGfuiObject *curObject;
315
316 startObject = GfuiScreen->hasFocus;
317 if (startObject == NULL) {
318 startObject = GfuiScreen->objects;
319 }
320 if (startObject == NULL) {
321 return;
322 }
323 curObject = startObject;
324 do {
325 switch (curObject->widget) {
326 case GFUI_SCROLLIST:
327 gfuiScrollListNextElt(curObject);
328 break;
329
330 default:
331 curObject = curObject->next;
332 if ((curObject->focusMode != GFUI_FOCUS_NONE) &&
333 (curObject->state != GFUI_DISABLE) &&
334 (curObject->visible)) {
335 gfuiSetFocus(curObject);
336 return;
337 }
338 break;
339 }
340 } while (curObject != startObject);
341 }
342
343 void
gfuiSelectPrev(void *)344 gfuiSelectPrev(void * /* dummy */)
345 {
346 tGfuiObject *startObject;
347 tGfuiObject *curObject;
348
349 startObject = GfuiScreen->hasFocus;
350 if (startObject == NULL) {
351 startObject = GfuiScreen->objects;
352 if (startObject == NULL) {
353 return;
354 }
355 startObject = startObject->next;
356 }
357 curObject = startObject;
358 do {
359 switch (curObject->widget) {
360 case GFUI_SCROLLIST:
361 gfuiScrollListPrevElt(curObject);
362 break;
363
364 default:
365 curObject = curObject->prev;
366 if ((curObject->focusMode != GFUI_FOCUS_NONE) &&
367 (curObject->state != GFUI_DISABLE) &&
368 (curObject->visible)) {
369 gfuiSetFocus(curObject);
370 return;
371 }
372 break;
373 }
374 } while (curObject != startObject);
375 }
376
377 void
gfuiSelectId(void * scr,int id)378 gfuiSelectId(void *scr, int id)
379 {
380 tGfuiObject *curObject;
381 tGfuiScreen *screen = (tGfuiScreen*)scr;
382
383 curObject = screen->objects;
384 if (curObject != NULL) {
385 do {
386 curObject = curObject->next;
387 if (curObject->id == id) {
388 gfuiSetFocus(curObject);
389 break;
390 }
391 } while (curObject != screen->objects);
392 }
393 }
394
395 /** Set/unset the visibility attribute of an object.
396 @param scr Screen
397 @param id Object id
398 @param visible GFUI_VISIBLE or GFUI_INVISIBLE
399 @return <tt>0 ... </tt>Ok
400 <br><tt>-1 .. </tt>Error
401 @ingroup gui
402 */
403 int
GfuiVisibilitySet(void * scr,int id,int visible)404 GfuiVisibilitySet(void *scr, int id, int visible)
405 {
406 tGfuiObject *curObject;
407
408 curObject = gfuiGetObject(scr, id);
409 if (curObject == NULL) {
410 return -1;
411 }
412 switch(visible) {
413 case GFUI_VISIBLE:
414 curObject->visible = GFUI_VISIBLE;
415 break;
416 case GFUI_INVISIBLE:
417 curObject->visible = GFUI_INVISIBLE;
418 break;
419 default:
420 return -1;
421 }
422 return 0;
423 }
424
425 /** Enable / Disable an object
426 @param scr Screen
427 @param id Object id
428 @param flag GFUI_ENABLE or GFUI_DISABLE
429 @return <tt>0 ... </tt>Ok
430 <br><tt>-1 .. </tt>Error
431 @ingroup gui
432 */
433 int
GfuiEnable(void * scr,int id,int flag)434 GfuiEnable(void *scr, int id, int flag)
435 {
436 tGfuiObject *curObject;
437
438 curObject = gfuiGetObject(scr, id);
439 if (curObject == NULL) {
440 return -1;
441 }
442 switch(flag) {
443 case GFUI_ENABLE:
444 curObject->state = GFUI_ENABLE;
445 break;
446 case GFUI_DISABLE:
447 curObject->state = GFUI_DISABLE;
448 break;
449 default:
450 return -1;
451 }
452 return 0;
453 }
454
455 void
gfuiMouseAction(void * vaction)456 gfuiMouseAction(void *vaction)
457 {
458 tGfuiObject *curObject;
459 long action = (long)vaction;
460
461 curObject = GfuiScreen->hasFocus;
462 if (curObject != NULL) {
463 if (curObject->state == GFUI_DISABLE) {
464 return;
465 }
466
467 switch (curObject->widget) {
468 case GFUI_BUTTON:
469 gfuiButtonAction((int)action);
470 break;
471 case GFUI_GRBUTTON:
472 gfuiGrButtonAction((int)action);
473 break;
474 case GFUI_SCROLLIST:
475 gfuiScrollListAction((int)action);
476 break;
477 case GFUI_EDITBOX:
478 gfuiEditboxAction((int)action);
479 break;
480 }
481 }
482 }
483
484 void
gfuiAddObject(tGfuiScreen * screen,tGfuiObject * object)485 gfuiAddObject(tGfuiScreen *screen, tGfuiObject *object)
486 {
487 if (screen->objects == NULL) {
488 screen->objects = object;
489 object->next = object;
490 object->prev = object;
491 } else {
492 object->next = screen->objects->next;
493 object->prev = screen->objects;
494 screen->objects->next = object;
495 object->next->prev = object;
496 screen->objects = object;
497 }
498 }
499
500 tGfuiObject *
gfuiGetObject(void * scr,int id)501 gfuiGetObject(void *scr, int id)
502 {
503 tGfuiObject *curObject;
504 tGfuiScreen *screen = (tGfuiScreen*)scr;
505
506 curObject = screen->objects;
507 if (curObject != NULL) {
508 do {
509 curObject = curObject->next;
510 if (curObject->id == id) {
511 return curObject;
512 }
513 } while (curObject != screen->objects);
514 }
515 return (tGfuiObject *)NULL;
516 }
517
518
519 void
gfuiReleaseObject(tGfuiObject * curObject)520 gfuiReleaseObject(tGfuiObject *curObject)
521 {
522 switch (curObject->widget){
523 case GFUI_LABEL:
524 gfuiReleaseLabel(curObject);
525 break;
526
527 case GFUI_BUTTON:
528 gfuiReleaseButton(curObject);
529 break;
530
531 case GFUI_GRBUTTON:
532 gfuiReleaseGrButton(curObject);
533 break;
534
535 case GFUI_SCROLLIST:
536 gfuiReleaseScrollist(curObject);
537 break;
538
539 case GFUI_SCROLLBAR:
540 gfuiReleaseScrollbar(curObject);
541 break;
542
543 case GFUI_EDITBOX:
544 gfuiReleaseEditbox(curObject);
545 break;
546 case GFUI_IMAGE:
547 gfuiReleaseImage(curObject);
548 break;
549 }
550 }
551