|
|
1.1 root 1: /*
2: Hatari - sdlgui.c
3:
4: This file is distributed under the GNU Public License, version 2 or at
5: your option any later version. Read the file gpl.txt for details.
6:
7: A tiny graphical user interface for Hatari.
8: */
1.1.1.3 ! root 9: char SDLGui_rcsid[] = "Hatari $Id: sdlgui.c,v 1.11 2005/09/29 08:36:59 thothy Exp $";
1.1 root 10:
11: #include <SDL.h>
12: #include <ctype.h>
13: #include <string.h>
14:
15: #include "main.h"
16: #include "sdlgui.h"
17:
18: #include "font5x8.h"
19: #include "font10x16.h"
20:
21:
1.1.1.2 root 22: static SDL_Surface *pSdlGuiScrn; /* Pointer to the actual main SDL screen surface */
1.1 root 23: static SDL_Surface *pSmallFontGfx = NULL; /* The small font graphics */
24: static SDL_Surface *pBigFontGfx = NULL; /* The big font graphics */
1.1.1.2 root 25: static SDL_Surface *pFontGfx = NULL; /* The actual font graphics */
1.1 root 26: static int fontwidth, fontheight; /* Width & height of the actual font */
27:
28:
29:
30: /*-----------------------------------------------------------------------*/
31: /*
32: Load an 1 plane XBM into a 8 planes SDL_Surface.
33: */
1.1.1.3 ! root 34: static SDL_Surface *SDLGui_LoadXBM(int w, int h, void *pXbmBits)
1.1 root 35: {
36: SDL_Surface *bitmap;
1.1.1.3 ! root 37: Uint8 *dstbits, *srcbits;
1.1 root 38: int x, y, srcpitch;
39: int mask;
40:
1.1.1.3 ! root 41: srcbits = pXbmBits;
! 42:
1.1 root 43: /* Allocate the bitmap */
44: bitmap = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 8, 0, 0, 0, 0);
45: if (bitmap == NULL)
46: {
47: fprintf(stderr, "Couldn't allocate bitmap: %s", SDL_GetError());
48: return(NULL);
49: }
50:
51: srcpitch = ((w + 7) / 8);
52: dstbits = (Uint8 *)bitmap->pixels;
53: mask = 1;
54:
55: /* Copy the pixels */
56: for (y = 0 ; y < h ; y++)
57: {
58: for (x = 0 ; x < w ; x++)
59: {
60: dstbits[x] = (srcbits[x / 8] & mask) ? 1 : 0;
61: mask <<= 1;
62: mask |= (mask >> 8);
63: mask &= 0xFF;
64: }
65: dstbits += bitmap->pitch;
66: srcbits += srcpitch;
67: }
68:
69: return(bitmap);
70: }
71:
72:
73: /*-----------------------------------------------------------------------*/
74: /*
75: Initialize the GUI.
76: */
77: int SDLGui_Init(void)
78: {
79: SDL_Color blackWhiteColors[2] = {{255, 255, 255, 0}, {0, 0, 0, 0}};
80:
81: /* Initialize the font graphics: */
82: pSmallFontGfx = SDLGui_LoadXBM(font5x8_width, font5x8_height, font5x8_bits);
83: pBigFontGfx = SDLGui_LoadXBM(font10x16_width, font10x16_height, font10x16_bits);
84: if (pSmallFontGfx == NULL || pBigFontGfx == NULL)
85: {
86: fprintf(stderr, "Error: Can not init font graphics!\n");
87: return -1;
88: }
89:
90: /* Set color palette of the font graphics: */
91: SDL_SetColors(pSmallFontGfx, blackWhiteColors, 0, 2);
92: SDL_SetColors(pBigFontGfx, blackWhiteColors, 0, 2);
93:
94: /* Set font color 0 as transparent: */
95: SDL_SetColorKey(pSmallFontGfx, (SDL_SRCCOLORKEY|SDL_RLEACCEL), 0);
96: SDL_SetColorKey(pBigFontGfx, (SDL_SRCCOLORKEY|SDL_RLEACCEL), 0);
97:
98: return 0;
99: }
100:
101:
102: /*-----------------------------------------------------------------------*/
103: /*
104: Uninitialize the GUI.
105: */
106: int SDLGui_UnInit(void)
107: {
108: if (pSmallFontGfx)
109: {
110: SDL_FreeSurface(pSmallFontGfx);
111: pSmallFontGfx = NULL;
112: }
113:
114: if (pBigFontGfx)
115: {
116: SDL_FreeSurface(pBigFontGfx);
117: pBigFontGfx = NULL;
118: }
119:
120: return 0;
121: }
122:
123:
124: /*-----------------------------------------------------------------------*/
125: /*
1.1.1.2 root 126: Inform the SDL-GUI about the actual SDL_Surface screen pointer and
127: prepare the font to suit the actual resolution.
1.1 root 128: */
1.1.1.2 root 129: int SDLGui_SetScreen(SDL_Surface *pScrn)
1.1 root 130: {
1.1.1.2 root 131: pSdlGuiScrn = pScrn;
132:
1.1 root 133: /* Decide which font to use - small or big one: */
1.1.1.2 root 134: if (pSdlGuiScrn->w >= 640 && pSdlGuiScrn->h >= 400 && pBigFontGfx != NULL)
1.1 root 135: {
1.1.1.2 root 136: pFontGfx = pBigFontGfx;
1.1 root 137: }
138: else
139: {
1.1.1.2 root 140: pFontGfx = pSmallFontGfx;
1.1 root 141: }
142:
1.1.1.2 root 143: if (pFontGfx == NULL)
1.1 root 144: {
145: fprintf(stderr, "Error: A problem with the font occured!\n");
146: return -1;
147: }
148:
149: /* Get the font width and height: */
1.1.1.2 root 150: fontwidth = pFontGfx->w/16;
151: fontheight = pFontGfx->h/16;
1.1 root 152:
153: return 0;
154: }
155:
156:
157: /*-----------------------------------------------------------------------*/
158: /*
159: Center a dialog so that it appears in the middle of the screen.
160: Note: We only store the coordinates in the root box of the dialog,
161: all other objects in the dialog are positioned relatively to this one.
162: */
163: void SDLGui_CenterDlg(SGOBJ *dlg)
164: {
1.1.1.2 root 165: dlg[0].x = (pSdlGuiScrn->w/fontwidth-dlg[0].w)/2;
166: dlg[0].y = (pSdlGuiScrn->h/fontheight-dlg[0].h)/2;
1.1 root 167: }
168:
169:
170: /*-----------------------------------------------------------------------*/
171: /*
172: Draw a text string.
173: */
174: static void SDLGui_Text(int x, int y, const char *txt)
175: {
176: int i;
177: char c;
178: SDL_Rect sr, dr;
179:
180: for(i=0; txt[i]!=0; i++)
181: {
182: c = txt[i];
183: sr.x=fontwidth*(c%16); sr.y=fontheight*(c/16);
184: sr.w=fontwidth; sr.h=fontheight;
185: dr.x=x+i*fontwidth; dr.y=y;
186: dr.w=fontwidth; dr.h=fontheight;
1.1.1.2 root 187: SDL_BlitSurface(pFontGfx, &sr, pSdlGuiScrn, &dr);
1.1 root 188: }
189: }
190:
191:
192: /*-----------------------------------------------------------------------*/
193: /*
194: Draw a dialog text object.
195: */
1.1.1.2 root 196: static void SDLGui_DrawText(const SGOBJ *tdlg, int objnum)
1.1 root 197: {
198: int x, y;
199: x = (tdlg[0].x+tdlg[objnum].x)*fontwidth;
200: y = (tdlg[0].y+tdlg[objnum].y)*fontheight;
201: SDLGui_Text(x, y, tdlg[objnum].txt);
202: }
203:
204:
205: /*-----------------------------------------------------------------------*/
206: /*
207: Draw a edit field object.
208: */
1.1.1.2 root 209: static void SDLGui_DrawEditField(const SGOBJ *edlg, int objnum)
1.1 root 210: {
211: int x, y;
212: SDL_Rect rect;
213:
214: x = (edlg[0].x+edlg[objnum].x)*fontwidth;
215: y = (edlg[0].y+edlg[objnum].y)*fontheight;
216: SDLGui_Text(x, y, edlg[objnum].txt);
217:
218: rect.x = x; rect.y = y + edlg[objnum].h * fontheight;
219: rect.w = edlg[objnum].w * fontwidth; rect.h = 1;
1.1.1.2 root 220: SDL_FillRect(pSdlGuiScrn, &rect, SDL_MapRGB(pSdlGuiScrn->format,160,160,160));
1.1 root 221: }
222:
223:
224: /*-----------------------------------------------------------------------*/
225: /*
226: Draw a dialog box object.
227: */
1.1.1.2 root 228: static void SDLGui_DrawBox(const SGOBJ *bdlg, int objnum)
1.1 root 229: {
230: SDL_Rect rect;
231: int x, y, w, h, offset;
1.1.1.2 root 232: Uint32 grey = SDL_MapRGB(pSdlGuiScrn->format,192,192,192);
1.1 root 233: Uint32 upleftc, downrightc;
234:
235: x = bdlg[objnum].x*fontwidth;
236: y = bdlg[objnum].y*fontheight;
237: if(objnum>0) /* Since the root object is a box, too, */
238: { /* we have to look for it now here and only */
239: x += bdlg[0].x*fontwidth; /* add its absolute coordinates if we need to */
240: y += bdlg[0].y*fontheight;
241: }
242: w = bdlg[objnum].w*fontwidth;
243: h = bdlg[objnum].h*fontheight;
244:
245: if( bdlg[objnum].state&SG_SELECTED )
246: {
1.1.1.2 root 247: upleftc = SDL_MapRGB(pSdlGuiScrn->format,128,128,128);
248: downrightc = SDL_MapRGB(pSdlGuiScrn->format,255,255,255);
1.1 root 249: }
250: else
251: {
1.1.1.2 root 252: upleftc = SDL_MapRGB(pSdlGuiScrn->format,255,255,255);
253: downrightc = SDL_MapRGB(pSdlGuiScrn->format,128,128,128);
1.1 root 254: }
255:
256: /* The root box should be bigger than the screen, so we disable the offset there: */
257: if (objnum != 0)
258: offset = 1;
259: else
260: offset = 0;
261:
262: /* Draw background: */
263: rect.x = x; rect.y = y;
264: rect.w = w; rect.h = h;
1.1.1.2 root 265: SDL_FillRect(pSdlGuiScrn, &rect, grey);
1.1 root 266:
267: /* Draw upper border: */
268: rect.x = x; rect.y = y - offset;
269: rect.w = w; rect.h = 1;
1.1.1.2 root 270: SDL_FillRect(pSdlGuiScrn, &rect, upleftc);
1.1 root 271:
272: /* Draw left border: */
273: rect.x = x - offset; rect.y = y;
274: rect.w = 1; rect.h = h;
1.1.1.2 root 275: SDL_FillRect(pSdlGuiScrn, &rect, upleftc);
1.1 root 276:
277: /* Draw bottom border: */
278: rect.x = x; rect.y = y + h - 1 + offset;
279: rect.w = w; rect.h = 1;
1.1.1.2 root 280: SDL_FillRect(pSdlGuiScrn, &rect, downrightc);
1.1 root 281:
282: /* Draw right border: */
283: rect.x = x + w - 1 + offset; rect.y = y;
284: rect.w = 1; rect.h = h;
1.1.1.2 root 285: SDL_FillRect(pSdlGuiScrn, &rect, downrightc);
1.1 root 286: }
287:
288:
289: /*-----------------------------------------------------------------------*/
290: /*
291: Draw a normal button.
292: */
1.1.1.2 root 293: static void SDLGui_DrawButton(const SGOBJ *bdlg, int objnum)
1.1 root 294: {
295: int x,y;
296:
297: SDLGui_DrawBox(bdlg, objnum);
298:
299: x = (bdlg[0].x+bdlg[objnum].x+(bdlg[objnum].w-strlen(bdlg[objnum].txt))/2)*fontwidth;
300: y = (bdlg[0].y+bdlg[objnum].y+(bdlg[objnum].h-1)/2)*fontheight;
301:
302: if( bdlg[objnum].state&SG_SELECTED )
303: {
304: x+=1;
305: y+=1;
306: }
307: SDLGui_Text(x, y, bdlg[objnum].txt);
308: }
309:
310:
311: /*-----------------------------------------------------------------------*/
312: /*
313: Draw a dialog radio button object.
314: */
1.1.1.2 root 315: static void SDLGui_DrawRadioButton(const SGOBJ *rdlg, int objnum)
1.1 root 316: {
317: char str[80];
318: int x, y;
319:
320: x = (rdlg[0].x+rdlg[objnum].x)*fontwidth;
321: y = (rdlg[0].y+rdlg[objnum].y)*fontheight;
322:
323: if( rdlg[objnum].state&SG_SELECTED )
324: str[0]=SGRADIOBUTTON_SELECTED;
325: else
326: str[0]=SGRADIOBUTTON_NORMAL;
327: str[1]=' ';
328: strcpy(&str[2], rdlg[objnum].txt);
329:
330: SDLGui_Text(x, y, str);
331: }
332:
333:
334: /*-----------------------------------------------------------------------*/
335: /*
336: Draw a dialog check box object.
337: */
1.1.1.2 root 338: static void SDLGui_DrawCheckBox(const SGOBJ *cdlg, int objnum)
1.1 root 339: {
340: char str[80];
341: int x, y;
342:
343: x = (cdlg[0].x+cdlg[objnum].x)*fontwidth;
344: y = (cdlg[0].y+cdlg[objnum].y)*fontheight;
345:
346: if( cdlg[objnum].state&SG_SELECTED )
347: str[0]=SGCHECKBOX_SELECTED;
348: else
349: str[0]=SGCHECKBOX_NORMAL;
350: str[1]=' ';
351: strcpy(&str[2], cdlg[objnum].txt);
352:
353: SDLGui_Text(x, y, str);
354: }
355:
356:
357: /*-----------------------------------------------------------------------*/
358: /*
359: Draw a dialog popup button object.
360: */
1.1.1.2 root 361: static void SDLGui_DrawPopupButton(const SGOBJ *pdlg, int objnum)
1.1 root 362: {
363: int x, y, w, h;
364: const char *downstr = "\x02";
365:
366: SDLGui_DrawBox(pdlg, objnum);
367:
368: x = (pdlg[0].x+pdlg[objnum].x)*fontwidth;
369: y = (pdlg[0].y+pdlg[objnum].y)*fontheight;
370: w = pdlg[objnum].w*fontwidth;
371: h = pdlg[objnum].h*fontheight;
372:
373: SDLGui_Text(x, y, pdlg[objnum].txt);
374: SDLGui_Text(x+w-fontwidth, y, downstr);
375: }
376:
377:
378: /*-----------------------------------------------------------------------*/
379: /*
380: Let the user insert text into an edit field object.
381: NOTE: The dlg[objnum].txt must point to an an array that is big enough
382: for dlg[objnum].w characters!
383: */
384: static void SDLGui_EditField(SGOBJ *dlg, int objnum)
385: {
1.1.1.2 root 386: size_t cursorPos; /* Position of the cursor in the edit field */
1.1 root 387: int blinkState = 0; /* Used for cursor blinking */
1.1.1.2 root 388: int bStopEditing = FALSE; /* TRUE if user wants to exit the edit field */
1.1 root 389: char *txt; /* Shortcut for dlg[objnum].txt */
390: SDL_Rect rect;
391: Uint32 grey, cursorCol;
392: SDL_Event event;
393:
1.1.1.2 root 394: grey = SDL_MapRGB(pSdlGuiScrn->format,192,192,192);
395: cursorCol = SDL_MapRGB(pSdlGuiScrn->format,128,128,128);
1.1 root 396:
397: rect.x = (dlg[0].x + dlg[objnum].x) * fontwidth;
398: rect.y = (dlg[0].y + dlg[objnum].y) * fontheight;
399: rect.w = (dlg[objnum].w + 1) * fontwidth - 1;
400: rect.h = dlg[objnum].h * fontheight;
401:
402: txt = dlg[objnum].txt;
403: cursorPos = strlen(txt);
404:
405: do
406: {
407: /* Look for events */
408: if(SDL_PollEvent(&event) == 0)
409: {
410: /* No event: Wait some time for cursor blinking */
411: SDL_Delay(250);
412: blinkState ^= 1;
413: }
414: else
415: {
416: int keysym;
417:
418: /* Handle events */
419: do
420: {
421: switch(event.type)
422: {
423: case SDL_QUIT: /* User wants to quit */
424: bQuitProgram = TRUE;
425: bStopEditing = TRUE;
426: break;
427: case SDL_MOUSEBUTTONDOWN: /* Mouse pressed -> stop editing */
428: bStopEditing = TRUE;
429: break;
430: case SDL_KEYDOWN: /* Key pressed */
431: keysym = event.key.keysym.sym;
432: switch(keysym)
433: {
434: case SDLK_RETURN:
435: case SDLK_KP_ENTER:
436: bStopEditing = TRUE;
437: break;
438: case SDLK_LEFT:
439: if(cursorPos > 0)
440: cursorPos -= 1;
441: break;
442: case SDLK_RIGHT:
443: if(cursorPos < strlen(txt))
444: cursorPos += 1;
445: break;
446: case SDLK_BACKSPACE:
447: if(cursorPos > 0)
448: {
449: memmove(&txt[cursorPos-1], &txt[cursorPos], strlen(&txt[cursorPos])+1);
450: cursorPos -= 1;
451: }
452: break;
453: case SDLK_DELETE:
454: if(cursorPos < strlen(txt))
455: memmove(&txt[cursorPos], &txt[cursorPos+1], strlen(&txt[cursorPos+1])+1);
456: break;
457: default:
458: /* If it is a "good" key then insert it into the text field */
459: if(keysym >= 32 && keysym < 256)
460: {
1.1.1.2 root 461: if(strlen(txt) < (size_t)dlg[objnum].w)
1.1 root 462: {
463: memmove(&txt[cursorPos+1], &txt[cursorPos], strlen(&txt[cursorPos])+1);
464: if(event.key.keysym.mod & (KMOD_LSHIFT|KMOD_RSHIFT))
465: txt[cursorPos] = toupper(keysym);
466: else
467: txt[cursorPos] = keysym;
468: cursorPos += 1;
469: }
470: }
471: break;
472: }
473: break;
474: }
475: }
476: while(SDL_PollEvent(&event));
477:
478: blinkState = 1;
479: }
480:
481: /* Redraw the text field: */
1.1.1.2 root 482: SDL_FillRect(pSdlGuiScrn, &rect, grey); /* Draw background */
1.1 root 483: /* Draw the cursor: */
484: if(blinkState && !bStopEditing)
485: {
486: SDL_Rect cursorrect;
487: cursorrect.x = rect.x + cursorPos * fontwidth; cursorrect.y = rect.y;
488: cursorrect.w = fontwidth; cursorrect.h = rect.h;
1.1.1.2 root 489: SDL_FillRect(pSdlGuiScrn, &cursorrect, cursorCol);
1.1 root 490: }
491: SDLGui_Text(rect.x, rect.y, dlg[objnum].txt); /* Draw text */
1.1.1.2 root 492: SDL_UpdateRects(pSdlGuiScrn, 1, &rect);
1.1 root 493: }
494: while(!bStopEditing);
495: }
496:
497:
498: /*-----------------------------------------------------------------------*/
499: /*
500: Draw a whole dialog.
501: */
1.1.1.3 ! root 502: void SDLGui_DrawDialog(const SGOBJ *dlg)
1.1 root 503: {
504: int i;
505: for(i=0; dlg[i].type!=-1; i++ )
506: {
507: switch( dlg[i].type )
508: {
509: case SGBOX:
510: SDLGui_DrawBox(dlg, i);
511: break;
512: case SGTEXT:
513: SDLGui_DrawText(dlg, i);
514: break;
515: case SGEDITFIELD:
516: SDLGui_DrawEditField(dlg, i);
517: break;
518: case SGBUTTON:
519: SDLGui_DrawButton(dlg, i);
520: break;
521: case SGRADIOBUT:
522: SDLGui_DrawRadioButton(dlg, i);
523: break;
524: case SGCHECKBOX:
525: SDLGui_DrawCheckBox(dlg, i);
526: break;
527: case SGPOPUP:
528: SDLGui_DrawPopupButton(dlg, i);
529: break;
530: }
531: }
1.1.1.2 root 532: SDL_UpdateRect(pSdlGuiScrn, 0,0,0,0);
1.1 root 533: }
534:
535:
536: /*-----------------------------------------------------------------------*/
537: /*
538: Search an object at a certain position.
539: */
1.1.1.2 root 540: static int SDLGui_FindObj(const SGOBJ *dlg, int fx, int fy)
1.1 root 541: {
542: int len, i;
543: int ob = -1;
544: int xpos, ypos;
545:
546: len = 0;
547: while( dlg[len].type!=-1) len++;
548:
549: xpos = fx/fontwidth;
550: ypos = fy/fontheight;
551: /* Now search for the object: */
1.1.1.2 root 552: for (i = len; i >= 0; i--)
1.1 root 553: {
554: if(xpos>=dlg[0].x+dlg[i].x && ypos>=dlg[0].y+dlg[i].y
555: && xpos<dlg[0].x+dlg[i].x+dlg[i].w && ypos<dlg[0].y+dlg[i].y+dlg[i].h)
556: {
557: ob = i;
558: break;
559: }
560: }
561:
562: return ob;
563: }
564:
565:
566: /*-----------------------------------------------------------------------*/
567: /*
568: Show and process a dialog. Returns the button number that has been
1.1.1.2 root 569: pressed or SDLGUI_UNKNOWNEVENT if an unsupported event occured (will be
570: stored in parameter pEventOut).
1.1 root 571: */
1.1.1.2 root 572: int SDLGui_DoDialog(SGOBJ *dlg, SDL_Event *pEventOut)
1.1 root 573: {
574: int obj=0;
575: int oldbutton=0;
576: int retbutton=0;
577: int i, j, b;
1.1.1.2 root 578: SDL_Event sdlEvent;
1.1 root 579: SDL_Rect rct;
580: Uint32 grey;
581: SDL_Surface *pBgSurface;
582: SDL_Rect dlgrect, bgrect;
583:
1.1.1.2 root 584: grey = SDL_MapRGB(pSdlGuiScrn->format,192,192,192);
1.1 root 585:
586: dlgrect.x = dlg[0].x * fontwidth;
587: dlgrect.y = dlg[0].y * fontheight;
588: dlgrect.w = dlg[0].w * fontwidth;
589: dlgrect.h = dlg[0].h * fontheight;
590:
591: bgrect.x = bgrect.y = 0;
592: bgrect.w = dlgrect.w;
593: bgrect.h = dlgrect.h;
594:
595: /* Save background */
1.1.1.2 root 596: pBgSurface = SDL_CreateRGBSurface(SDL_SWSURFACE, dlgrect.w, dlgrect.h, pSdlGuiScrn->format->BitsPerPixel,
597: pSdlGuiScrn->format->Rmask, pSdlGuiScrn->format->Gmask, pSdlGuiScrn->format->Bmask, pSdlGuiScrn->format->Amask);
598: if (pSdlGuiScrn->format->palette != NULL)
1.1 root 599: {
1.1.1.2 root 600: SDL_SetColors(pBgSurface, pSdlGuiScrn->format->palette->colors, 0, pSdlGuiScrn->format->palette->ncolors-1);
1.1 root 601: }
602:
603: if (pBgSurface != NULL)
604: {
1.1.1.2 root 605: SDL_BlitSurface(pSdlGuiScrn, &dlgrect, pBgSurface, &bgrect);
1.1 root 606: }
607: else
608: {
609: fprintf(stderr, "SDLGUI_DoDialog: CreateRGBSurface failed: %s\n", SDL_GetError());
610: }
611:
612: /* (Re-)draw the dialog */
613: SDLGui_DrawDialog(dlg);
614:
615: /* Is the left mouse button still pressed? Yes -> Handle TOUCHEXIT objects here */
616: SDL_PumpEvents();
617: b = SDL_GetMouseState(&i, &j);
618: obj = SDLGui_FindObj(dlg, i, j);
619: if(obj>0 && (dlg[obj].flags&SG_TOUCHEXIT) )
620: {
621: oldbutton = obj;
622: if( b&SDL_BUTTON(1) )
623: {
624: dlg[obj].state |= SG_SELECTED;
625: retbutton = obj;
626: }
627: }
628:
629: /* The main loop */
1.1.1.2 root 630: while (retbutton == 0 && !bQuitProgram)
1.1 root 631: {
1.1.1.2 root 632: if (SDL_WaitEvent(&sdlEvent) == 1) /* Wait for events */
633: switch (sdlEvent.type)
1.1 root 634: {
635: case SDL_QUIT:
1.1.1.2 root 636: retbutton = SDLGUI_QUIT;
1.1 root 637: break;
1.1.1.2 root 638:
1.1 root 639: case SDL_MOUSEBUTTONDOWN:
1.1.1.2 root 640: if (sdlEvent.button.button != SDL_BUTTON_LEFT)
641: {
642: /* Not left mouse button -> unsupported event */
643: if (pEventOut)
644: retbutton = SDLGUI_UNKNOWNEVENT;
645: break;
646: }
647: /* It was the left button: Find the object under the mouse cursor */
648: obj = SDLGui_FindObj(dlg, sdlEvent.button.x, sdlEvent.button.y);
1.1 root 649: if(obj>0)
650: {
651: if(dlg[obj].type==SGBUTTON)
652: {
653: dlg[obj].state |= SG_SELECTED;
654: SDLGui_DrawButton(dlg, obj);
1.1.1.2 root 655: SDL_UpdateRect(pSdlGuiScrn, (dlg[0].x+dlg[obj].x)*fontwidth-2, (dlg[0].y+dlg[obj].y)*fontheight-2,
1.1 root 656: dlg[obj].w*fontwidth+4, dlg[obj].h*fontheight+4);
657: oldbutton=obj;
658: }
659: if( dlg[obj].flags&SG_TOUCHEXIT )
660: {
661: dlg[obj].state |= SG_SELECTED;
662: retbutton = obj;
663: }
664: }
665: break;
1.1.1.2 root 666:
1.1 root 667: case SDL_MOUSEBUTTONUP:
1.1.1.2 root 668: if (sdlEvent.button.button != SDL_BUTTON_LEFT)
669: {
670: /* Not left mouse button -> unsupported event */
671: if (pEventOut)
672: retbutton = SDLGUI_UNKNOWNEVENT;
673: break;
674: }
675: /* It was the left button: Find the object under the mouse cursor */
676: obj = SDLGui_FindObj(dlg, sdlEvent.button.x, sdlEvent.button.y);
1.1 root 677: if(obj>0)
678: {
679: switch(dlg[obj].type)
680: {
681: case SGBUTTON:
682: if(oldbutton==obj)
683: retbutton=obj;
684: break;
685: case SGEDITFIELD:
686: SDLGui_EditField(dlg, obj);
687: break;
688: case SGRADIOBUT:
689: for(i=obj-1; i>0 && dlg[i].type==SGRADIOBUT; i--)
690: {
691: dlg[i].state &= ~SG_SELECTED; /* Deselect all radio buttons in this group */
692: rct.x = (dlg[0].x+dlg[i].x)*fontwidth;
693: rct.y = (dlg[0].y+dlg[i].y)*fontheight;
694: rct.w = fontwidth; rct.h = fontheight;
1.1.1.2 root 695: SDL_FillRect(pSdlGuiScrn, &rct, grey); /* Clear old */
1.1 root 696: SDLGui_DrawRadioButton(dlg, i);
1.1.1.2 root 697: SDL_UpdateRects(pSdlGuiScrn, 1, &rct);
1.1 root 698: }
699: for(i=obj+1; dlg[i].type==SGRADIOBUT; i++)
700: {
701: dlg[i].state &= ~SG_SELECTED; /* Deselect all radio buttons in this group */
702: rct.x = (dlg[0].x+dlg[i].x)*fontwidth;
703: rct.y = (dlg[0].y+dlg[i].y)*fontheight;
704: rct.w = fontwidth; rct.h = fontheight;
1.1.1.2 root 705: SDL_FillRect(pSdlGuiScrn, &rct, grey); /* Clear old */
1.1 root 706: SDLGui_DrawRadioButton(dlg, i);
1.1.1.2 root 707: SDL_UpdateRects(pSdlGuiScrn, 1, &rct);
1.1 root 708: }
709: dlg[obj].state |= SG_SELECTED; /* Select this radio button */
710: rct.x = (dlg[0].x+dlg[obj].x)*fontwidth;
711: rct.y = (dlg[0].y+dlg[obj].y)*fontheight;
712: rct.w = fontwidth; rct.h = fontheight;
1.1.1.2 root 713: SDL_FillRect(pSdlGuiScrn, &rct, grey); /* Clear old */
1.1 root 714: SDLGui_DrawRadioButton(dlg, obj);
1.1.1.2 root 715: SDL_UpdateRects(pSdlGuiScrn, 1, &rct);
1.1 root 716: break;
717: case SGCHECKBOX:
718: dlg[obj].state ^= SG_SELECTED;
719: rct.x = (dlg[0].x+dlg[obj].x)*fontwidth;
720: rct.y = (dlg[0].y+dlg[obj].y)*fontheight;
721: rct.w = fontwidth; rct.h = fontheight;
1.1.1.2 root 722: SDL_FillRect(pSdlGuiScrn, &rct, grey); /* Clear old */
1.1 root 723: SDLGui_DrawCheckBox(dlg, obj);
1.1.1.2 root 724: SDL_UpdateRects(pSdlGuiScrn, 1, &rct);
1.1 root 725: break;
726: case SGPOPUP:
727: dlg[obj].state |= SG_SELECTED;
728: SDLGui_DrawPopupButton(dlg, obj);
1.1.1.2 root 729: SDL_UpdateRect(pSdlGuiScrn, (dlg[0].x+dlg[obj].x)*fontwidth-2, (dlg[0].y+dlg[obj].y)*fontheight-2,
1.1 root 730: dlg[obj].w*fontwidth+4, dlg[obj].h*fontheight+4);
731: retbutton=obj;
732: break;
733: }
734: }
735: if(oldbutton>0)
736: {
737: dlg[oldbutton].state &= ~SG_SELECTED;
738: SDLGui_DrawButton(dlg, oldbutton);
1.1.1.2 root 739: SDL_UpdateRect(pSdlGuiScrn, (dlg[0].x+dlg[oldbutton].x)*fontwidth-2, (dlg[0].y+dlg[oldbutton].y)*fontheight-2,
1.1 root 740: dlg[oldbutton].w*fontwidth+4, dlg[oldbutton].h*fontheight+4);
741: oldbutton = 0;
742: }
1.1.1.2 root 743: if (obj >= 0 && (dlg[obj].flags&SG_EXIT))
1.1 root 744: {
745: retbutton = obj;
746: }
747: break;
1.1.1.2 root 748:
749: case SDL_MOUSEMOTION:
750: break;
751:
752: default:
753: if (pEventOut)
754: retbutton = SDLGUI_UNKNOWNEVENT;
755: break;
1.1 root 756: }
757: }
758:
759: /* Restore background */
760: if (pBgSurface)
761: {
1.1.1.2 root 762: SDL_BlitSurface(pBgSurface, &bgrect, pSdlGuiScrn, &dlgrect);
1.1 root 763: SDL_FreeSurface(pBgSurface);
764: }
765:
1.1.1.2 root 766: /* Copy event data of unsupported events if caller wants to have it */
767: if (retbutton == SDLGUI_UNKNOWNEVENT && pEventOut)
768: memcpy(pEventOut, &sdlEvent, sizeof(SDL_Event));
769:
770: if (retbutton == SDLGUI_QUIT)
771: bQuitProgram = TRUE;
1.1 root 772:
773: return retbutton;
774: }
775:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.