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