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