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