Annotation of hatari/src/gui-sdl/sdlgui.c, revision 1.1.1.2

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: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.