ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/Frodo4/Src/sdlgui.cpp
Revision: 1.3
Committed: 2007-03-28T06:55:52Z (17 years, 1 month ago) by berlac
Branch: MAIN
CVS Tags: HEAD
Changes since 1.2: +10 -10 lines
Log Message:
Minor code clean up.

File Contents

# User Rev Content
1 berlac 1.1 /*
2     * sdlgui.cpp
3     *
4     * This file is taken from the ARAnyM project which builds a new and powerful
5     * TOS/FreeMiNT compatible virtual machine running on almost any hardware.
6     *
7     * Copyright (c) 2001 Thomas Huth - taken from his hatari project
8     * Copyright (c) 2002-2005 Petr Stehlik of ARAnyM dev team (see AUTHORS)
9     *
10     * It is free software; you can redistribute it and/or modify
11     * it under the terms of the GNU General Public License as published by
12     * the Free Software Foundation; either version 2 of the License, or
13     * (at your option) any later version.
14     *
15     * You should have received a copy of the GNU General Public License
16     * along with Frodo; if not, write to the Free Software
17     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18     */
19    
20     #include "sysdeps.h"
21     #include "sdlgui.h"
22    
23     #include <cstdlib>
24    
25     #include "font8.h"
26    
27     static SDL_Surface *mainsurface = NULL;
28     #define sdlscrn mainsurface
29    
30     static SDL_Surface *fontgfx=NULL;
31     static int fontwidth, fontheight; /* Height and width of the actual font */
32    
33     // Stores current dialog coordinates
34     static SDL_Rect DialogRect = {0, 0, 0, 0};
35    
36     // Used by SDLGui_Get[First|Next]BackgroundRect()
37     static SDL_Rect BackgroundRect = {0, 0, 0, 0};
38     static int BackgroundRectCounter;
39     enum
40     {
41     SG_BCKGND_RECT_BEGIN,
42     SG_BCKGND_RECT_TOP,
43     SG_BCKGND_RECT_LEFT,
44     SG_BCKGND_RECT_RIGHT,
45     SG_BCKGND_RECT_BOTTOM,
46     SG_BCKGND_RECT_END
47     };
48    
49     SDL_Color blackc[] = {{0, 0, 0, 0}};
50     SDL_Color darkgreyc[] = {{128, 128, 128, 0}};
51     SDL_Color greyc[] = {{192, 192, 192, 0}};
52     SDL_Color whitec[] = {{255, 255, 255, 0}};
53    
54     enum
55     {
56     SG_FIRST_EDITFIELD,
57     SG_PREVIOUS_EDITFIELD,
58     SG_NEXT_EDITFIELD,
59     SG_LAST_EDITFIELD
60     };
61    
62     /*-----------------------------------------------------------------------*/
63     /*
64     Load an 1 plane XBM into a 8 planes SDL_Surface.
65     */
66     static SDL_Surface *SDLGui_LoadXBM(int w, int h, Uint8 *srcbits)
67     {
68     SDL_Surface *bitmap;
69     Uint8 *dstbits;
70     int x, y, srcpitch;
71    
72     /* Allocate the bitmap */
73     bitmap = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 8, 0, 0, 0, 0);
74     if ( bitmap == NULL )
75     {
76     // TODO panicbug("Couldn't allocate bitmap: %s", SDL_GetError());
77     return(NULL);
78     }
79    
80     srcpitch = ((w + 7) / 8);
81     dstbits = (Uint8 *)bitmap->pixels;
82     int mask = 1;
83    
84     /* Copy the pixels */
85     for (y = 0 ; y < h ; y++)
86     {
87     for (x = 0 ; x < w ; x++)
88     {
89     dstbits[x] = (srcbits[x / 8] & mask) ? 1 : 0;
90     mask <<= 1;
91     mask |= (mask >> 8);
92     mask &= 0xFF;
93     }
94     dstbits += bitmap->pitch;
95     srcbits += srcpitch;
96     }
97    
98     return(bitmap);
99     }
100    
101     /*-----------------------------------------------------------------------*/
102     /*
103     Initialize the GUI.
104     */
105     bool SDLGui_Init(SDL_Surface *GUISurface)
106     {
107     mainsurface = GUISurface;
108     /* Load the font graphics: */
109     fontgfx = SDLGui_LoadXBM(font8_width, font8_height, font8_bits);
110     if (fontgfx == NULL)
111     {
112     // TODO panicbug("Could not create font data");
113     // TODO panicbug("ARAnyM GUI will not be available");
114     return false;
115     }
116    
117     /* Set font color 0 as transparent */
118     SDL_SetColorKey(fontgfx, SDL_SRCCOLORKEY, 0);
119    
120     /* Get the font width and height: */
121     fontwidth = fontgfx->w/16;
122     fontheight = fontgfx->h/16;
123    
124     return true;
125     }
126    
127    
128     /*-----------------------------------------------------------------------*/
129     /*
130     Uninitialize the GUI.
131     */
132     int SDLGui_UnInit()
133     {
134     if (fontgfx)
135     {
136     SDL_FreeSurface(fontgfx);
137     fontgfx = NULL;
138     }
139    
140     return 0;
141     }
142    
143    
144     /*-----------------------------------------------------------------------*/
145     /*
146     Compute real coordinates for a given object.
147     Note: centers dialog on screen.
148     */
149     static void SDLGui_ObjCoord(SGOBJ *dlg, int objnum, SDL_Rect *rect)
150     {
151     rect->x = dlg[objnum].x * fontwidth;
152     rect->y = dlg[objnum].y * fontheight;
153     rect->w = dlg[objnum].w * fontwidth;
154     rect->h = dlg[objnum].h * fontheight;
155    
156     rect->x += (sdlscrn->w - (dlg[0].w * fontwidth)) / 2;
157     rect->y += (sdlscrn->h - (dlg[0].h * fontheight)) / 2;
158     }
159    
160    
161     /*-----------------------------------------------------------------------*/
162     /*
163     Compute real coordinates for a given object.
164     This one takes borders into account and give coordinates as seen by user
165     */
166     void SDLGui_ObjFullCoord(SGOBJ *dlg, int objnum, SDL_Rect *coord)
167     {
168     SDLGui_ObjCoord(dlg, objnum, coord);
169    
170     switch (dlg[objnum].type)
171     {
172     case SGBOX:
173     case SGBUTTON:
174     {
175     // Take border into account
176     int border_size;
177    
178     if (dlg[objnum].flags & SG_SELECTABLE)
179     {
180     if (dlg[objnum].flags & SG_DEFAULT)
181     border_size = 4;
182     else
183     border_size = 3;
184     }
185     else
186     {
187     if (dlg[objnum].flags & SG_BACKGROUND)
188     border_size = 6;
189     else
190     border_size = 5;
191     }
192    
193     coord->x -= border_size;
194     coord->y -= border_size;
195     coord->w += (border_size * 2);
196     coord->h += (border_size * 2);
197     }
198     break;
199     case SGEDITFIELD:
200     // Allow one more pixel to the right for cursor
201     coord->w += 1;
202     // There is a line below
203     coord->h += 1;
204     break;
205     }
206     }
207    
208    
209     /*-----------------------------------------------------------------------*/
210     /*
211     Refresh display at given coordinates.
212     Unlike SDL_UpdateRect() this function can eat coords that goes beyond screen
213     boundaries.
214     "rect" will be modified to represent the area actually refreshed.
215     */
216     void SDLGui_UpdateRect(SDL_Rect *rect)
217     {
218     if (rect->x < 0)
219     {
220     rect->w += rect->x;
221     rect->x = 0;
222     }
223     if ((rect->x + rect->w) > sdlscrn->w)
224     rect->w = (sdlscrn->w - rect->x);
225    
226     if (rect->y < 0)
227     {
228     rect->h += rect->y;
229     rect->y = 0;
230     }
231     if ((rect->y + rect->h) > sdlscrn->h)
232     rect->h = (sdlscrn->h - rect->y);
233    
234     if ((rect->w > 0) && (rect->h > 0))
235     SDL_UpdateRects(sdlscrn, 1, rect);
236     else
237     {
238     rect->x = 0;
239     rect->y = 0;
240     rect->w = 0;
241     rect->h = 0;
242     }
243     }
244    
245    
246     /*-----------------------------------------------------------------------*/
247     /*
248     Maps an SDL_Color to the screen format.
249     */
250     Uint32 SDLGui_MapColor(SDL_Color *color)
251     {
252     return SDL_MapRGB(sdlscrn->format, color->r, color->g, color->b);
253     }
254    
255    
256     /*-----------------------------------------------------------------------*/
257     /*
258     Refresh display to reflect an object change.
259     */
260     void SDLGui_RefreshObj(SGOBJ *dlg, int objnum)
261     {
262     SDL_Rect coord;
263    
264     SDLGui_ObjFullCoord(dlg, objnum, &coord);
265    
266 berlac 1.3 screenlock();
267 berlac 1.1 SDLGui_UpdateRect(&coord);
268 berlac 1.3 screenunlock();
269 berlac 1.1 }
270    
271    
272     /*-----------------------------------------------------------------------*/
273     /*
274     Draw a text string.
275     */
276     void SDLGui_Text(int x, int y, const char *txt, SDL_Color *col)
277     {
278     int i;
279     char c;
280     SDL_Rect sr, dr;
281    
282     SDL_SetColors(fontgfx, col, 1, 1);
283    
284 berlac 1.3 screenlock();
285 berlac 1.1 for (i = 0 ; txt[i] != 0 ; i++)
286     {
287     c = txt[i];
288     sr.x = fontwidth * (c % 16);
289     sr.y = fontheight * (c / 16);
290     sr.w = fontwidth;
291     sr.h = fontheight;
292    
293     dr.x = x + (fontwidth * i);
294     dr.y = y;
295     dr.w = fontwidth;
296     dr.h = fontheight;
297    
298     SDL_BlitSurface(fontgfx, &sr, sdlscrn, &dr);
299     }
300 berlac 1.3 screenunlock();
301 berlac 1.1 }
302    
303    
304     /*-----------------------------------------------------------------------*/
305     /*
306     Draw a dialog text object.
307     */
308     void SDLGui_DrawText(SGOBJ *tdlg, int objnum)
309     {
310     SDL_Rect coord;
311     SDL_Color *textc, *backgroundc;
312    
313     if (tdlg[objnum].state & SG_SELECTED)
314     {
315     textc = whitec;
316     backgroundc = darkgreyc;
317     }
318     else if (tdlg[objnum].state & SG_DISABLED)
319     {
320     textc = darkgreyc;
321     backgroundc = greyc;
322     }
323     else
324     {
325     textc = blackc;
326     backgroundc = greyc;
327     }
328    
329     SDLGui_ObjCoord(tdlg, objnum, &coord);
330     SDL_FillRect(sdlscrn, &coord, SDLGui_MapColor(backgroundc));
331     SDLGui_Text(coord.x, coord.y, tdlg[objnum].txt, textc);
332     }
333    
334    
335     /*-----------------------------------------------------------------------*/
336     /*
337     Draw an edit field object.
338     */
339     void SDLGui_DrawEditField(SGOBJ *edlg, int objnum)
340     {
341     SDL_Rect coord;
342     SDL_Color *textc;
343    
344     if (edlg[objnum].state & SG_DISABLED)
345     textc = darkgreyc;
346     else
347     textc = blackc;
348    
349     SDLGui_ObjCoord(edlg, objnum, &coord);
350     coord.w += 1;
351     SDL_FillRect(sdlscrn, &coord, SDLGui_MapColor(greyc));
352     SDLGui_Text(coord.x, coord.y, edlg[objnum].txt, textc);
353    
354     // Draw a line below.
355     coord.y = coord.y + coord.h;
356     coord.h = 1;
357     SDL_FillRect(sdlscrn, &coord, SDLGui_MapColor(darkgreyc));
358     }
359    
360    
361     /*-----------------------------------------------------------------------*/
362     /*
363     Draw or erase cursor.
364     */
365     void SDLGui_DrawCursor(SGOBJ *dlg, cursor_state *cursor)
366     {
367     if (cursor->object != -1)
368     {
369     SDL_Rect coord;
370     SDL_Color *cursorc;
371    
372     SDLGui_DrawEditField(dlg, cursor->object);
373    
374     if (cursor->blink_state)
375     cursorc = blackc;
376     else
377     cursorc = greyc;
378    
379     SDLGui_ObjCoord(dlg, cursor->object, &coord);
380     coord.x += (cursor->position * fontwidth);
381     coord.w = 1;
382     SDL_FillRect(sdlscrn, &coord, SDLGui_MapColor(cursorc));
383    
384     SDLGui_RefreshObj(dlg, cursor->object);
385     }
386     }
387    
388    
389     /*-----------------------------------------------------------------------*/
390     /*
391     Draw a 3D effect around a given rectangle.
392     Rectangle is updated to the full size of the new object.
393     */
394     void SDLGui_Draw3DAround(SDL_Rect *coord, SDL_Color *upleftc, SDL_Color *downrightc, SDL_Color *cornerc, int width)
395     {
396     SDL_Rect rect;
397     int i;
398     Uint32 upleftcol = SDLGui_MapColor(upleftc);
399     Uint32 downrightcol = SDLGui_MapColor(downrightc);
400     Uint32 cornercol = SDLGui_MapColor(cornerc);
401    
402 berlac 1.3 screenlock();
403 berlac 1.1
404     for ( i = 1 ; i <= width ; i++)
405     {
406     rect.x = coord->x - i;
407     rect.y = coord->y - i;
408     rect.w = coord->w + (i * 2) - 1;
409     rect.h = 1;
410     SDL_FillRect(sdlscrn, &rect, upleftcol);
411    
412     rect.x = coord->x - i;
413     rect.y = coord->y - i;
414     rect.w = 1;
415     rect.h = coord->h + (i * 2) - 1;
416     SDL_FillRect(sdlscrn, &rect, upleftcol);
417    
418     rect.x = coord->x - i + 1;
419     rect.y = coord->y + coord->h - 1 + i;
420     rect.w = coord->w + (i * 2) - 1;
421     rect.h = 1;
422     SDL_FillRect(sdlscrn, &rect, downrightcol);
423    
424     rect.x = coord->x + coord->w - 1 + i;
425     rect.y = coord->y - i + 1;
426     rect.w = 1;
427     rect.h = coord->h + (i * 2) - 1;
428     SDL_FillRect(sdlscrn, &rect, downrightcol);
429    
430     rect.x = coord->x + coord->w + i - 1;
431     rect.y = coord->y - i;
432     rect.w = 1;
433     rect.h = 1;
434     SDL_FillRect(sdlscrn, &rect, cornercol);
435    
436     rect.x = coord->x - i;
437     rect.y = coord->y + coord->h + i - 1;
438     rect.w = 1;
439     rect.h = 1;
440     SDL_FillRect(sdlscrn, &rect, cornercol);
441     }
442    
443 berlac 1.3 screenunlock();
444 berlac 1.1
445     coord->x -= width;
446     coord->y -= width;
447     coord->w += (width * 2);
448     coord->h += (width * 2);
449     }
450    
451    
452     /*-----------------------------------------------------------------------*/
453     /*
454     Draw a colored box around a given rectangle.
455     Rectangle is updated to the full size of the new object.
456     */
457     void SDLGui_DrawBoxAround(SDL_Rect *coord, SDL_Color *color, int width)
458     {
459     SDL_Rect rect;
460     Uint32 col = SDLGui_MapColor(color);
461    
462 berlac 1.3 screenlock();
463 berlac 1.1
464     rect.x = coord->x - width;
465     rect.y = coord->y - width;
466     rect.w = coord->w + (width * 2);
467     rect.h = width;
468     SDL_FillRect(sdlscrn, &rect, col);
469    
470     rect.x = coord->x - width;
471     rect.y = coord->y - width;
472     rect.w = width;
473     rect.h = coord->h + (width * 2);
474     SDL_FillRect(sdlscrn, &rect, col);
475    
476     rect.x = coord->x + coord->w;
477     rect.y = coord->y - width;
478     rect.w = width;
479     rect.h = coord->h + (width * 2);
480     SDL_FillRect(sdlscrn, &rect, col);
481    
482     rect.x = coord->x - width;
483     rect.y = coord->y + coord->h;
484     rect.w = coord->w + (width * 2);
485     rect.h = width;
486     SDL_FillRect(sdlscrn, &rect, col);
487    
488 berlac 1.3 screenunlock();
489 berlac 1.1
490     coord->x -= width;
491     coord->y -= width;
492     coord->w += (width * 2);
493     coord->h += (width * 2);
494     }
495    
496    
497     /*-----------------------------------------------------------------------*/
498     /*
499     Draw a 3D box with given attributes.
500     */
501     void SDLGui_Draw3DBox(SDL_Rect *coord,
502     SDL_Color *backgroundc,
503     SDL_Color *inboxc,
504     SDL_Color *upleftc,
505     SDL_Color *downrightc,
506     SDL_Color *outboxc,
507     int widthbackground,
508     int widthinbox,
509     int width3D1,
510     int width3D2,
511     int widthoutbox)
512     {
513     SDL_Rect rect;
514    
515 berlac 1.3 screenlock();
516 berlac 1.1
517     // Draw background
518     rect.x = coord->x - widthbackground;
519     rect.y = coord->y - widthbackground;
520     rect.w = coord->w + (widthbackground * 2);
521     rect.h = coord->h + (widthbackground * 2);
522     SDL_FillRect(sdlscrn, &rect, SDLGui_MapColor(backgroundc));
523    
524 berlac 1.3 screenunlock();
525 berlac 1.1
526     // Update coords
527     coord->x -= widthbackground;
528     coord->y -= widthbackground;
529     coord->w += (widthbackground * 2);
530     coord->h += (widthbackground * 2);
531    
532     if (widthinbox > 0)
533     SDLGui_DrawBoxAround(coord, inboxc, widthinbox);
534    
535     if (width3D1 > 0)
536     SDLGui_Draw3DAround(coord, upleftc, downrightc, backgroundc, width3D1);
537    
538     if (width3D2 > 0)
539     SDLGui_Draw3DAround(coord, downrightc, upleftc, backgroundc, width3D2);
540    
541     if (widthoutbox > 0)
542     SDLGui_DrawBoxAround(coord, outboxc, widthoutbox);
543     }
544    
545    
546     /*-----------------------------------------------------------------------*/
547     /*
548     Draw a dialog box object.
549     */
550     void SDLGui_DrawBox(SGOBJ *bdlg, int objnum)
551     {
552     SDL_Rect coord;
553     SDL_Color *my_blackc;
554     SDL_Color *upleftc, *downrightc;
555    
556     SDLGui_ObjCoord(bdlg, objnum, &coord);
557    
558     // Modify box drawing according to object state
559     if (bdlg[objnum].state & SG_DISABLED)
560     my_blackc = darkgreyc;
561     else
562     my_blackc = blackc;
563    
564     if (bdlg[objnum].state & SG_SELECTED)
565     {
566     upleftc = darkgreyc;
567     downrightc = whitec;
568     }
569     else
570     {
571     upleftc = whitec;
572     downrightc = darkgreyc;
573     }
574    
575     // Draw box according to object flags
576     switch (bdlg[objnum].flags & (SG_SELECTABLE | SG_DEFAULT | SG_BACKGROUND))
577     {
578     case (SG_SELECTABLE | SG_DEFAULT | SG_BACKGROUND):
579     case (SG_SELECTABLE | SG_DEFAULT):
580     SDLGui_Draw3DBox(&coord,
581     greyc, NULL, upleftc, downrightc, my_blackc,
582     1, 0, 1, 0, 2);
583     break;
584     case (SG_SELECTABLE | SG_BACKGROUND):
585     case SG_SELECTABLE:
586     SDLGui_Draw3DBox(&coord,
587     greyc, NULL, upleftc, downrightc, my_blackc,
588     1, 0, 1, 0, 1);
589     break;
590     case (SG_DEFAULT | SG_BACKGROUND):
591     case SG_BACKGROUND:
592     SDLGui_Draw3DBox(&coord,
593     greyc, my_blackc, upleftc, downrightc, darkgreyc,
594     0, 2, 3, 0, 1);
595     break;
596     case SG_DEFAULT:
597     case 0:
598     SDLGui_Draw3DBox(&coord,
599     greyc, NULL, upleftc, downrightc, NULL,
600     3, 0, 1, 1, 0);
601     break;
602     }
603     }
604    
605    
606     /*-----------------------------------------------------------------------*/
607     /*
608     Draw a normal button.
609     */
610     void SDLGui_DrawButton(SGOBJ *bdlg, int objnum)
611     {
612     SDL_Rect coord;
613     int x, y;
614     SDL_Color *textc;
615    
616     SDLGui_ObjCoord(bdlg, objnum, &coord);
617    
618     x = coord.x + ((coord.w - (strlen(bdlg[objnum].txt) * fontwidth)) / 2);
619     y = coord.y + ((coord.h - fontheight) / 2);
620    
621     if (bdlg[objnum].state & SG_SELECTED)
622     {
623     x += 1;
624     y += 1;
625     }
626    
627     if (bdlg[objnum].state & SG_DISABLED)
628     textc = darkgreyc;
629     else
630     textc = blackc;
631    
632     SDLGui_DrawBox(bdlg, objnum);
633     SDLGui_Text(x, y, bdlg[objnum].txt, textc);
634     }
635    
636    
637     /*-----------------------------------------------------------------------*/
638     /*
639     Draw a dialog check box object state.
640     */
641     void SDLGui_DrawCheckBoxState(SGOBJ *cdlg, int objnum)
642     {
643     Uint32 grey = SDLGui_MapColor(greyc);
644     SDL_Rect coord;
645     char str[2];
646     SDL_Color *textc;
647    
648     SDLGui_ObjCoord(cdlg, objnum, &coord);
649    
650     if (cdlg[objnum].flags & SG_RADIO)
651     {
652     if (cdlg[objnum].state & SG_SELECTED)
653     str[0]=SGCHECKBOX_RADIO_SELECTED;
654     else
655     str[0]=SGCHECKBOX_RADIO_NORMAL;
656     }
657     else
658     {
659     if (cdlg[objnum].state & SG_SELECTED)
660     str[0]=SGCHECKBOX_SELECTED;
661     else
662     str[0]=SGCHECKBOX_NORMAL;
663     }
664    
665     if (cdlg[objnum].state & SG_DISABLED)
666     textc = darkgreyc;
667     else
668     textc = blackc;
669    
670     str[1]='\0';
671    
672     coord.w = fontwidth;
673     coord.h = fontheight;
674    
675     if (cdlg[objnum].flags & SG_BUTTON_RIGHT)
676     coord.x += ((strlen(cdlg[objnum].txt) + 1) * fontwidth);
677    
678     SDL_FillRect(sdlscrn, &coord, grey);
679     SDLGui_Text(coord.x, coord.y, str, textc);
680     }
681    
682    
683     /*-----------------------------------------------------------------------*/
684     /*
685     Draw a dialog check box object.
686     */
687     void SDLGui_DrawCheckBox(SGOBJ *cdlg, int objnum)
688     {
689     SDL_Rect coord;
690     SDL_Color *textc;
691    
692     SDLGui_ObjCoord(cdlg, objnum, &coord);
693    
694     if (!(cdlg[objnum].flags&SG_BUTTON_RIGHT))
695     coord.x += (fontwidth * 2);
696    
697     if (cdlg[objnum].state & SG_DISABLED)
698     textc = darkgreyc;
699     else
700     textc = blackc;
701    
702     SDLGui_Text(coord.x, coord.y, cdlg[objnum].txt, textc);
703     SDLGui_DrawCheckBoxState(cdlg, objnum);
704     }
705    
706    
707     /*-----------------------------------------------------------------------*/
708     /*
709     Draw a dialog popup button object.
710     */
711     void SDLGui_DrawPopupButton(SGOBJ *pdlg, int objnum)
712     {
713     SDL_Rect coord;
714     const char *downstr = "\x02";
715     SDL_Color *textc;
716    
717     if (pdlg[objnum].state & SG_DISABLED)
718     textc = darkgreyc;
719     else
720     textc = blackc;
721    
722     SDLGui_DrawBox(pdlg, objnum);
723    
724     SDLGui_ObjCoord(pdlg, objnum, &coord);
725    
726     SDLGui_Text(coord.x, coord.y, pdlg[objnum].txt, textc);
727     SDLGui_Text(coord.x+coord.w-fontwidth, coord.y, downstr, textc);
728     }
729    
730    
731     /*-----------------------------------------------------------------------*/
732     /*
733     Draw an object.
734     */
735     void SDLGui_DrawObject(SGOBJ *dlg, int objnum)
736     {
737     switch (dlg[objnum].type)
738     {
739     case SGBOX:
740     SDLGui_DrawBox(dlg, objnum);
741     break;
742     case SGTEXT:
743     SDLGui_DrawText(dlg, objnum);
744     break;
745     case SGEDITFIELD:
746     SDLGui_DrawEditField(dlg, objnum);
747     break;
748     case SGBUTTON:
749     SDLGui_DrawButton(dlg, objnum);
750     break;
751     case SGCHECKBOX:
752     SDLGui_DrawCheckBox(dlg, objnum);
753     break;
754     case SGPOPUP:
755     SDLGui_DrawPopupButton(dlg, objnum);
756     break;
757     }
758     }
759    
760    
761     /*-----------------------------------------------------------------------*/
762     /*
763     Draw a whole dialog.
764     */
765     void SDLGui_DrawDialog(SGOBJ *dlg)
766     {
767     int i;
768    
769     // Store dialog coordinates
770     SDLGui_ObjFullCoord(dlg, 0, &DialogRect);
771    
772     for (i = 0 ; dlg[i].type != -1 ; i++)
773     {
774     if (dlg[i].state & SG_HIDDEN) continue;
775     SDLGui_DrawObject(dlg, i);
776     }
777     SDLGui_RefreshObj(dlg, 0);
778     }
779    
780    
781     /*-----------------------------------------------------------------------*/
782     /*
783     Search default object in a dialog.
784     */
785     int SDLGui_FindDefaultObj(SGOBJ *dlg)
786     {
787     int i = 0;
788    
789     while (dlg[i].type != -1)
790     {
791     if (dlg[i].flags & SG_DEFAULT)
792     return i;
793     i++;
794     }
795    
796     return -1;
797     }
798    
799    
800     /*-----------------------------------------------------------------------*/
801     /*
802     Search an object at given coordinates.
803     */
804     int SDLGui_FindObj(SGOBJ *dlg, int fx, int fy)
805     {
806     SDL_Rect coord;
807     int end, i;
808     int ob = -1;
809    
810     // Search end object in dialog
811     i = 0;
812     while (dlg[i++].type != -1);
813     end = i;
814    
815     // Now check each object
816     for (i = end-1 ; i >= 0 ; i--)
817     {
818     SDLGui_ObjFullCoord(dlg, i, &coord);
819    
820     if(fx >= coord.x &&
821     fy >= coord.y &&
822     fx < (coord.x + coord.w) &&
823     fy < (coord.y + coord.h))
824     {
825     if (dlg[i].state & (SG_HIDDEN | SG_DISABLED)) continue;
826     ob = i;
827     break;
828     }
829     }
830    
831     return ob;
832     }
833    
834    
835     /*-----------------------------------------------------------------------*/
836     /*
837     A radio object has been selected. Let's deselect any other in his group.
838     */
839     void SDLGui_SelectRadioObject(SGOBJ *dlg, int clicked_obj)
840     {
841     int obj;
842    
843     // Find first radio object in this group
844     obj = clicked_obj;
845     while (dlg[--obj].flags & SG_RADIO);
846    
847     // Update state
848     while (dlg[++obj].flags & SG_RADIO)
849     {
850     // This code scan every object in the group. This allows to solve cases
851     // where multiple objects where selected in the group by clicking one.
852     if ((obj != clicked_obj) && (dlg[obj].state & SG_SELECTED))
853     {
854     // Deselect this radio button
855     dlg[obj].state &= ~SG_SELECTED;
856     SDLGui_DrawObject(dlg, obj);
857     SDLGui_RefreshObj(dlg, obj);
858     }
859     }
860     }
861    
862    
863     /*-----------------------------------------------------------------------*/
864     /*
865     Update clicked object state depending on given mouse coordinates.
866     Returns true if the mouse is over the object, false otherwise.
867     */
868     bool SDLGui_UpdateObjState(SGOBJ *dlg, int clicked_obj, int original_state,
869     int x, int y)
870     {
871     int obj;
872    
873     obj = SDLGui_FindObj(dlg, x, y);
874    
875     // Special case : user clicked on an already selected radio object
876     // do not modify its state.
877     // We handle it here because it allows to exit if the object is SG_EXIT or
878     // SG_TOUCHEXIT without any additional test.
879     if ((dlg[clicked_obj].flags & SG_RADIO) && (original_state & SG_SELECTED))
880     return (obj == clicked_obj);
881    
882     if (((obj != clicked_obj) &&
883     (dlg[clicked_obj].state != original_state)) ||
884     ((obj == clicked_obj) &&
885     (dlg[clicked_obj].state == original_state)))
886     {
887     if (dlg[clicked_obj].flags & SG_SELECTABLE)
888     {
889     dlg[clicked_obj].state ^= SG_SELECTED;
890     SDLGui_DrawObject(dlg, clicked_obj);
891     SDLGui_RefreshObj(dlg, clicked_obj);
892     }
893     }
894    
895     return (obj == clicked_obj);
896     }
897    
898    
899     /*-----------------------------------------------------------------------*/
900     /*
901     Search edit field in a dialog.
902     */
903     int SDLGui_FindEditField(SGOBJ *dlg, int objnum, int mode)
904     {
905     int i, j;
906    
907     switch (mode)
908     {
909     case SG_FIRST_EDITFIELD:
910     i = 0;
911     while (dlg[i].type != -1)
912     {
913     if ((dlg[i].type == SGEDITFIELD) &&
914     ((dlg[i].state & (SG_HIDDEN | SG_DISABLED)) == 0))
915     return i;
916     i++;
917     }
918     break;
919    
920     case SG_PREVIOUS_EDITFIELD:
921     i = objnum - 1;
922     while (i >= 0)
923     {
924     if ((dlg[i].type == SGEDITFIELD) &&
925     ((dlg[i].state & (SG_HIDDEN | SG_DISABLED)) == 0))
926     return i;
927     i--;
928     }
929     break;
930    
931     case SG_NEXT_EDITFIELD:
932     i = objnum + 1;
933     while (dlg[i].type != -1)
934     {
935     if ((dlg[i].type == SGEDITFIELD) &&
936     ((dlg[i].state & (SG_HIDDEN | SG_DISABLED)) == 0))
937     return i;
938     i++;
939     }
940     break;
941    
942     case SG_LAST_EDITFIELD:
943     i = objnum + 1;
944     j = -1;
945     while (dlg[i].type != -1)
946     {
947     if ((dlg[i].type == SGEDITFIELD) &&
948     ((dlg[i].state & (SG_HIDDEN | SG_DISABLED)) == 0))
949     j = i;
950     i++;
951     }
952     if (j != -1)
953     return j;
954     break;
955     }
956    
957     return objnum;
958     }
959    
960    
961     /*-----------------------------------------------------------------------*/
962     /*
963     Move cursor to another edit field.
964     */
965     void SDLGui_MoveCursor(SGOBJ *dlg, cursor_state *cursor, int mode)
966     {
967     int new_object;
968    
969     new_object = SDLGui_FindEditField(dlg, cursor->object, mode);
970    
971     if (new_object != cursor->object)
972     {
973     /* Erase old cursor */
974     cursor->blink_state = false;
975     SDLGui_DrawCursor(dlg, cursor);
976    
977     cursor->object = new_object;
978     cursor->position = strlen(dlg[new_object].txt);
979     }
980     else
981     {
982     /* We stay in the same field */
983     /* Move cursor to begin or end of text depending on mode */
984     switch (mode)
985     {
986     case SG_FIRST_EDITFIELD:
987     case SG_PREVIOUS_EDITFIELD:
988     cursor->position = 0;
989     break;
990    
991     case SG_NEXT_EDITFIELD:
992     case SG_LAST_EDITFIELD:
993     cursor->position = strlen(dlg[new_object].txt);
994     break;
995     }
996     }
997     }
998    
999    
1000     /*-----------------------------------------------------------------------*/
1001     /*
1002     Handle mouse clicks on edit fields.
1003     */
1004     void SDLGui_ClickEditField(SGOBJ *dlg, cursor_state *cursor, int clicked_obj, int x)
1005     {
1006     SDL_Rect coord;
1007     int i, j;
1008    
1009     /* Erase old cursor */
1010     cursor->blink_state = false;
1011     SDLGui_DrawCursor(dlg, cursor);
1012    
1013     SDLGui_ObjFullCoord(dlg, clicked_obj, &coord);
1014     i = (x - coord.x + (fontwidth / 2)) / fontwidth;
1015     j = strlen(dlg[clicked_obj].txt);
1016    
1017     cursor->object = clicked_obj;
1018     cursor->position = MIN(i, j);
1019     cursor->blink_state = true;
1020     cursor->blink_counter = 0;
1021     SDLGui_DrawCursor(dlg, cursor);
1022     }
1023    
1024    
1025     /*-----------------------------------------------------------------------*/
1026     /*
1027     Handle mouse clicks.
1028     */
1029     int SDLGui_MouseClick(SGOBJ *dlg, int fx, int fy, cursor_state *cursor)
1030     {
1031     int clicked_obj;
1032     int return_obj = -1;
1033     int original_state = 0;
1034     int x, y;
1035    
1036     clicked_obj = SDLGui_FindObj(dlg, fx, fy);
1037    
1038     if (clicked_obj >= 0)
1039     {
1040     original_state = dlg[clicked_obj].state;
1041     SDLGui_UpdateObjState(dlg, clicked_obj, original_state, fx, fy);
1042    
1043     if (dlg[clicked_obj].flags & SG_TOUCHEXIT)
1044     {
1045     return_obj = clicked_obj;
1046     clicked_obj = -1;
1047     }
1048     }
1049    
1050     while (clicked_obj >= 0)
1051     {
1052     SDL_Event evnt;
1053     // SDL_PumpEvents() - not necessary, the main check_event thread calls it
1054     if (SDL_PeepEvents(&evnt, 1, SDL_GETEVENT, SDL_EVENTMASK(SDL_USEREVENT)))
1055     {
1056     switch (evnt.user.code)
1057     {
1058     case SDL_USEREVENT:
1059     // a signal that resolution has changed
1060     // Restore clicked object original state
1061     dlg[clicked_obj].state = original_state;
1062    
1063     // re-draw dialog
1064     SDLGui_DrawDialog(dlg);
1065    
1066     // Exit from mouse click handling.
1067     clicked_obj = -1;
1068     break;
1069    
1070     case SDL_MOUSEBUTTONUP:
1071     x = reinterpret_cast<intptr>(evnt.user.data1);
1072     y = reinterpret_cast<intptr>(evnt.user.data2);
1073     if (SDLGui_UpdateObjState(dlg, clicked_obj, original_state, x, y))
1074     {
1075     // true if mouse button is released over clicked object.
1076     // If applicable, the object has been selected by
1077     // SDLGui_UpdateObjState(). Let's do additional handling here.
1078    
1079     // Exit if object is an SG_EXIT one.
1080     if (dlg[clicked_obj].flags & SG_EXIT)
1081     return_obj = clicked_obj;
1082    
1083     // If it's a SG_RADIO object, deselect other objects in his group.
1084     if (dlg[clicked_obj].flags & SG_RADIO)
1085     SDLGui_SelectRadioObject(dlg, clicked_obj);
1086    
1087     if (dlg[clicked_obj].type == SGEDITFIELD)
1088     SDLGui_ClickEditField(dlg, cursor, clicked_obj, x);
1089     }
1090    
1091     // Exit from mouse click handling.
1092     clicked_obj = -1;
1093    
1094     break;
1095     }
1096     }
1097     else
1098     {
1099     // No special event occured.
1100     // Update object state according to mouse coordinates.
1101     SDL_GetMouseState(&x, &y);
1102     SDLGui_UpdateObjState(dlg, clicked_obj, original_state, x, y);
1103    
1104     // Wait a little to avoid eating CPU.
1105     SDL_Delay(100);
1106     }
1107     }
1108    
1109     return return_obj;
1110     }
1111    
1112    
1113     /*-----------------------------------------------------------------------*/
1114     /*
1115     Handle key press.
1116     */
1117     int SDLGui_KeyPress(SGOBJ *dlg, int keysym, int mod, cursor_state *cursor)
1118     {
1119     int return_obj = -1;
1120     int obj;
1121    
1122     if (cursor->object != -1)
1123     {
1124     switch(keysym)
1125     {
1126     case SDLK_RETURN:
1127     case SDLK_KP_ENTER:
1128     break;
1129    
1130     case SDLK_BACKSPACE:
1131     if (cursor->position > 0)
1132     {
1133     memmove(&dlg[cursor->object].txt[cursor->position-1],
1134     &dlg[cursor->object].txt[cursor->position],
1135     strlen(&dlg[cursor->object].txt[cursor->position])+1);
1136     cursor->position--;
1137     }
1138     break;
1139    
1140     case SDLK_DELETE:
1141     if(cursor->position < (int)strlen(dlg[cursor->object].txt))
1142     {
1143     memmove(&dlg[cursor->object].txt[cursor->position],
1144     &dlg[cursor->object].txt[cursor->position+1],
1145     strlen(&dlg[cursor->object].txt[cursor->position+1])+1);
1146     }
1147     break;
1148    
1149     case SDLK_LEFT:
1150     if (cursor->position > 0)
1151     cursor->position--;
1152     break;
1153    
1154     case SDLK_RIGHT:
1155     if (cursor->position < (int)strlen(dlg[cursor->object].txt))
1156     cursor->position++;
1157     break;
1158    
1159     case SDLK_DOWN:
1160     SDLGui_MoveCursor(dlg, cursor, SG_NEXT_EDITFIELD);
1161     break;
1162    
1163     case SDLK_UP:
1164     SDLGui_MoveCursor(dlg, cursor, SG_PREVIOUS_EDITFIELD);
1165     break;
1166    
1167     case SDLK_TAB:
1168     if (mod & KMOD_SHIFT)
1169     SDLGui_MoveCursor(dlg, cursor, SG_PREVIOUS_EDITFIELD);
1170     else
1171     SDLGui_MoveCursor(dlg, cursor, SG_NEXT_EDITFIELD);
1172     break;
1173    
1174     case SDLK_HOME:
1175     if (mod & KMOD_CTRL)
1176     SDLGui_MoveCursor(dlg, cursor, SG_FIRST_EDITFIELD);
1177     else
1178     cursor->position = 0;
1179     break;
1180    
1181     case SDLK_END:
1182     if (mod & KMOD_CTRL)
1183     SDLGui_MoveCursor(dlg, cursor, SG_LAST_EDITFIELD);
1184     else
1185     cursor->position = strlen(dlg[cursor->object].txt);
1186     break;
1187    
1188     default:
1189     if ((keysym >= SDLK_KP0) && (keysym <= SDLK_KP9))
1190     {
1191     // map numpad numbers to normal numbers
1192     keysym -= (SDLK_KP0 - SDLK_0);
1193     }
1194     /* If it is a "good" key then insert it into the text field */
1195     if ((keysym >= SDLK_SPACE) && (keysym < SDLK_KP0))
1196     {
1197     if (strlen(dlg[cursor->object].txt) < dlg[cursor->object].w)
1198     {
1199     memmove(&dlg[cursor->object].txt[cursor->position+1],
1200     &dlg[cursor->object].txt[cursor->position],
1201     strlen(&dlg[cursor->object].txt[cursor->position])+1);
1202     if (mod & KMOD_SHIFT)
1203     dlg[cursor->object].txt[cursor->position] = toupper(keysym);
1204     else
1205     dlg[cursor->object].txt[cursor->position] = keysym;
1206     cursor->position += 1;
1207     }
1208     }
1209     break;
1210     }
1211     }
1212    
1213     switch(keysym)
1214     {
1215     case SDLK_RETURN:
1216     case SDLK_KP_ENTER:
1217     obj = SDLGui_FindDefaultObj(dlg);
1218     if (obj >= 0)
1219     {
1220     dlg[obj].state ^= SG_SELECTED;
1221     SDLGui_DrawObject(dlg, obj);
1222     SDLGui_RefreshObj(dlg, obj);
1223     if (dlg[obj].flags & (SG_EXIT | SG_TOUCHEXIT))
1224     {
1225     return_obj = obj;
1226     SDL_Delay(300);
1227     }
1228     }
1229     break;
1230     }
1231    
1232     // Force cursor display. Should ease text input.
1233     cursor->blink_state = true;
1234     cursor->blink_counter = 0;
1235     // Redraw current edit field...
1236     SDLGui_DrawCursor(dlg, cursor);
1237    
1238     return return_obj;
1239     }
1240    
1241    
1242     /*-----------------------------------------------------------------------*/
1243     /*
1244     Used to update screen while GUI is opened. Return a list of rectangles that
1245     covers the screen without overlaping the current dialog.
1246     */
1247     SDL_Rect *SDLGui_GetFirstBackgroundRect(void)
1248     {
1249     // Reset counter...
1250     BackgroundRectCounter = SG_BCKGND_RECT_BEGIN;
1251     // And returns first rectangle
1252     return SDLGui_GetNextBackgroundRect();
1253     }
1254    
1255    
1256     /*-----------------------------------------------------------------------*/
1257     /*
1258     Returns next rectangle to be redrawn to update screen or NULL if we reached
1259     the end of the list.
1260     This code is "flying dialog" ready :)
1261     It will need some updating if we implement popup buttons handled by sdlgui,
1262     as the popup could be higher than the root box...
1263     I used some recursivity here to simplify the code.
1264     */
1265     SDL_Rect *SDLGui_GetNextBackgroundRect(void)
1266     {
1267     SDL_Rect *return_rect = NULL;
1268    
1269     switch (BackgroundRectCounter)
1270     {
1271     case SG_BCKGND_RECT_END:
1272     // Nothing to do : return_rect is already initialized to NULL.
1273     break;
1274    
1275     case SG_BCKGND_RECT_BEGIN:
1276     if (DialogRect.w == 0)
1277     {
1278     // The dialog is not drawn yet...
1279     // Let's redraw the full screen.
1280     BackgroundRect.x = 0;
1281     BackgroundRect.y = 0;
1282     BackgroundRect.w = sdlscrn->w;
1283     BackgroundRect.h = sdlscrn->h;
1284     return_rect = &BackgroundRect;
1285     // We reached the end of the list.
1286     BackgroundRectCounter = SG_BCKGND_RECT_END;
1287     }
1288     else
1289     {
1290     BackgroundRectCounter = SG_BCKGND_RECT_TOP;
1291     return_rect = SDLGui_GetNextBackgroundRect();
1292     }
1293     break;
1294    
1295     case SG_BCKGND_RECT_TOP:
1296     BackgroundRectCounter = SG_BCKGND_RECT_LEFT;
1297     if (DialogRect.y > 0)
1298     {
1299     BackgroundRect.x = 0;
1300     BackgroundRect.y = 0;
1301     BackgroundRect.w = sdlscrn->w;
1302     BackgroundRect.h = DialogRect.y;
1303     return_rect = &BackgroundRect;
1304     }
1305     else
1306     return_rect = SDLGui_GetNextBackgroundRect();
1307     break;
1308    
1309     case SG_BCKGND_RECT_LEFT:
1310     BackgroundRectCounter = SG_BCKGND_RECT_RIGHT;
1311     if (DialogRect.x > 0)
1312     {
1313     BackgroundRect.x = 0;
1314     BackgroundRect.y = (DialogRect.y > 0) ? DialogRect.y : 0;
1315     BackgroundRect.w = DialogRect.x;
1316     BackgroundRect.h =
1317     ((DialogRect.y + DialogRect.h) < (int)sdlscrn->h) ?
1318     (DialogRect.h + DialogRect.y - BackgroundRect.y) :
1319     (sdlscrn->h - DialogRect.y);
1320     return_rect = &BackgroundRect;
1321     }
1322     else
1323     return_rect = SDLGui_GetNextBackgroundRect();
1324     break;
1325    
1326     case SG_BCKGND_RECT_RIGHT:
1327     BackgroundRectCounter = SG_BCKGND_RECT_BOTTOM;
1328     if ((DialogRect.x + DialogRect.w) < (int)sdlscrn->w)
1329     {
1330     BackgroundRect.x = DialogRect.x + DialogRect.w;
1331     BackgroundRect.y = (DialogRect.y > 0) ? DialogRect.y : 0;
1332     BackgroundRect.w = sdlscrn->w - (DialogRect.x + DialogRect.w);
1333     BackgroundRect.h =
1334     ((DialogRect.y + DialogRect.h) < (int)sdlscrn->w) ?
1335     (DialogRect.h + DialogRect.y - BackgroundRect.y) :
1336     (sdlscrn->h - DialogRect.y);
1337     return_rect = &BackgroundRect;
1338     }
1339     else
1340     return_rect = SDLGui_GetNextBackgroundRect();
1341     break;
1342    
1343     case SG_BCKGND_RECT_BOTTOM:
1344     BackgroundRectCounter = SG_BCKGND_RECT_END;
1345     if ((DialogRect.y + DialogRect.h) < (int)sdlscrn->h)
1346     {
1347     // Bottom
1348     BackgroundRect.x = 0;
1349     BackgroundRect.y = DialogRect.y + DialogRect.h;
1350     BackgroundRect.w = sdlscrn->w;
1351     BackgroundRect.h = sdlscrn->h - (DialogRect.y + DialogRect.h);
1352     return_rect = &BackgroundRect;
1353     }
1354     else
1355     return_rect = SDLGui_GetNextBackgroundRect();
1356     break;
1357     }
1358    
1359     return return_rect;
1360     }
1361    
1362     SDL_Event getEvent(SGOBJ *dlg, cursor_state *cursor)
1363     {
1364     int i = 0;
1365     while(1) {
1366     SDL_Event evnt;
1367     // fprintf(stderr, "Debug Before Peep events\n");
1368     if (SDL_PeepEvents(&evnt, 1, SDL_GETEVENT, SDL_EVENTMASK(SDL_USEREVENT)))
1369     {
1370     fprintf(stderr, "Debug Peep events %d\n",i++);
1371     SDL_Event e;
1372     switch(evnt.user.code)
1373     {
1374     case SDL_KEYDOWN:
1375     case SDL_KEYUP:
1376     e.type = evnt.user.code;
1377     e.key.keysym.sym = (SDLKey)reinterpret_cast<uintptr>(evnt.user.data1);
1378     e.key.keysym.mod = (SDLMod)reinterpret_cast<uintptr>(evnt.user.data2);
1379     return e;
1380    
1381     case SDL_MOUSEBUTTONDOWN:
1382     case SDL_MOUSEBUTTONUP:
1383     e.type = evnt.user.code;
1384     if (evnt.user.code == SDL_MOUSEBUTTONDOWN)
1385     fprintf(stderr, "Debug mouse down\n");
1386     else
1387     fprintf(stderr, "Debug mouse down\n");
1388     e.button.x = reinterpret_cast<intptr>(evnt.user.data1);
1389     e.button.y = reinterpret_cast<intptr>(evnt.user.data2);
1390     return e;
1391    
1392     case SDL_USEREVENT:
1393     // a signal that resolution has changed
1394     if (dlg != NULL)
1395     SDLGui_DrawDialog(dlg); // re-draw dialog
1396     break;
1397     }
1398     }
1399     else
1400     {
1401     // No special event occured.
1402     // Wait a little to avoid eating CPU.
1403     SDL_Delay(50);
1404     if (cursor != NULL) {
1405     cursor->blink_counter++;
1406     if (cursor->blink_counter >= 10) {
1407     cursor->blink_counter = 0;
1408     cursor->blink_state = !cursor->blink_state;
1409     if (dlg != NULL)
1410     SDLGui_DrawCursor(dlg, cursor);
1411     }
1412     }
1413     }
1414     }
1415     }
1416    
1417     /*-----------------------------------------------------------------------*/
1418     /*
1419     Show and process a dialog. Returns the button number that has been
1420     pressed. Does NOT handle SDL_QUIT - you must handle it before you
1421     pass the input event to the SDL GUI.
1422     */
1423     int SDLGui_DoDialog(SGOBJ *dlg)
1424     {
1425     int return_obj = -1;
1426     int obj;
1427     int x, y;
1428     // int keysym, mod;
1429     cursor_state cursor;
1430    
1431     // Is the left mouse button still pressed? Yes -> Handle TOUCHEXIT objects here
1432     bool stillPressed = (SDL_GetMouseState(&x, &y) & SDL_BUTTON(1));
1433     obj = SDLGui_FindObj(dlg, x, y);
1434     if (stillPressed && (obj >= 0) && (dlg[obj].flags & SG_TOUCHEXIT))
1435     {
1436     // Mouse button is pressed over a TOUCHEXIT Button
1437     // Toogle its state before drawing anything (it has been deselected before).
1438     dlg[obj].state ^= SG_SELECTED;
1439    
1440     return_obj = obj;
1441     }
1442    
1443     cursor.object = SDLGui_FindEditField(dlg, -1, SG_FIRST_EDITFIELD);
1444     cursor.position = (cursor.object != -1) ? strlen(dlg[cursor.object].txt) : 0;
1445     cursor.blink_counter = 0;
1446     cursor.blink_state = true;
1447    
1448     SDLGui_DrawDialog(dlg);
1449    
1450     /* The main loop */
1451     while (return_obj < 0)
1452     {
1453     fprintf(stderr, "Debug SDL main loop\n");
1454     SDL_Event evnt = getEvent(dlg, &cursor);
1455     fprintf(stderr, "Debug SDL main loop got event\n");
1456     switch(evnt.type)
1457     {
1458     case SDL_KEYDOWN:
1459     return_obj = SDLGui_KeyPress(dlg, evnt.key.keysym.sym, evnt.key.keysym.mod, &cursor);
1460     break;
1461    
1462     case SDL_MOUSEBUTTONDOWN:
1463     return_obj = SDLGui_MouseClick(dlg, evnt.button.x, evnt.button.y, &cursor);
1464     break;
1465     }
1466     }
1467     fprintf(stderr, "Debug SDL main loop finished\n");
1468     if (dlg[return_obj].type == SGBUTTON)
1469     {
1470     // Deselect button...
1471     // BUG: This should be caller responsibility
1472     dlg[return_obj].state ^= SG_SELECTED;
1473     }
1474    
1475     return return_obj;
1476     }