Annotation of previous/src/gui-sdl/sdlgui.c, revision 1.1.1.4

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: const char SDLGui_fileid[] = "Previous sdlgui.c : " __DATE__ " " __TIME__;
                     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: 
                     22: static SDL_Surface *pSdlGuiScrn;            /* Pointer to the actual main SDL screen surface */
                     23: static SDL_Surface *pSmallFontGfx = NULL;   /* The small font graphics */
                     24: static SDL_Surface *pBigFontGfx = NULL;     /* The big font graphics */
                     25: static SDL_Surface *pFontGfx = NULL;        /* The actual font graphics */
1.1.1.2   root       26: static int current_object = 0;                         /* Current selected object */
1.1       root       27: 
                     28: 
                     29: /*-----------------------------------------------------------------------*/
                     30: /**
                     31:  * Load an 1 plane XBM into a 8 planes SDL_Surface.
                     32:  */
                     33: static SDL_Surface *SDLGui_LoadXBM(int w, int h, const Uint8 *pXbmBits)
                     34: {
                     35:        SDL_Surface *bitmap;
                     36:        Uint8 *dstbits;
                     37:        const Uint8 *srcbits;
                     38:        int x, y, srcpitch;
                     39:        int mask;
                     40: 
                     41:        srcbits = pXbmBits;
                     42: 
                     43:        /* Allocate the bitmap */
                     44:        bitmap = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 8, 0, 0, 0, 0);
                     45:        if (bitmap == NULL)
                     46:        {
                     47:                fprintf(stderr, "Failed to allocate bitmap: %s", SDL_GetError());
                     48:                return NULL;
                     49:        }
                     50: 
                     51:        srcpitch = ((w + 7) / 8);
                     52:        dstbits = (Uint8 *)bitmap->pixels;
                     53:        mask = 1;
                     54: 
                     55:        /* Copy the pixels */
                     56:        for (y = 0 ; y < h ; y++)
                     57:        {
                     58:                for (x = 0 ; x < w ; x++)
                     59:                {
                     60:                        dstbits[x] = (srcbits[x / 8] & mask) ? 1 : 0;
                     61:                        mask <<= 1;
                     62:                        mask |= (mask >> 8);
                     63:                        mask &= 0xFF;
                     64:                }
                     65:                dstbits += bitmap->pitch;
                     66:                srcbits += srcpitch;
                     67:        }
                     68: 
                     69:        return bitmap;
                     70: }
                     71: 
                     72: 
                     73: /*-----------------------------------------------------------------------*/
                     74: /**
                     75:  * Initialize the GUI.
                     76:  */
                     77: int SDLGui_Init(void)
                     78: {
1.1.1.4 ! root       79:        SDL_Color blackWhiteColors[2] = {{255, 255, 255, 255}, {0, 0, 0, 255}};
1.1       root       80: 
                     81:        if (pSmallFontGfx && pBigFontGfx)
                     82:        {
                     83:                /* already initialized */
                     84:                return 0;
                     85:        }
                     86: 
                     87:        /* Initialize the font graphics: */
                     88:        pSmallFontGfx = SDLGui_LoadXBM(font5x8_width, font5x8_height, font5x8_bits);
                     89:        pBigFontGfx = SDLGui_LoadXBM(font10x16_width, font10x16_height, font10x16_bits);
                     90:        if (pSmallFontGfx == NULL || pBigFontGfx == NULL)
                     91:        {
                     92:                fprintf(stderr, "Error: Can not init font graphics!\n");
                     93:                return -1;
                     94:        }
                     95: 
                     96:        /* Set color palette of the font graphics: */
1.1.1.4 ! root       97:        SDL_SetPaletteColors(pSmallFontGfx->format->palette, blackWhiteColors, 0, 2);
        !            98:        SDL_SetPaletteColors(pBigFontGfx->format->palette, blackWhiteColors, 0, 2);
1.1       root       99: 
                    100:        /* Set font color 0 as transparent: */
1.1.1.4 ! root      101:        SDL_SetColorKey(pSmallFontGfx, (SDL_TRUE|SDL_RLEACCEL), 0);
        !           102:        SDL_SetColorKey(pBigFontGfx, (SDL_TRUE|SDL_RLEACCEL), 0);
1.1       root      103: 
                    104:        return 0;
                    105: }
                    106: 
                    107: 
                    108: /*-----------------------------------------------------------------------*/
                    109: /**
                    110:  * Uninitialize the GUI.
                    111:  */
                    112: int SDLGui_UnInit(void)
                    113: {
                    114:        if (pSmallFontGfx)
                    115:        {
                    116:                SDL_FreeSurface(pSmallFontGfx);
                    117:                pSmallFontGfx = NULL;
                    118:        }
                    119: 
                    120:        if (pBigFontGfx)
                    121:        {
                    122:                SDL_FreeSurface(pBigFontGfx);
                    123:                pBigFontGfx = NULL;
                    124:        }
                    125: 
                    126:        return 0;
                    127: }
                    128: 
                    129: 
                    130: /*-----------------------------------------------------------------------*/
                    131: /**
                    132:  * Inform the SDL-GUI about the actual SDL_Surface screen pointer and
                    133:  * prepare the font to suit the actual resolution.
                    134:  */
                    135: int SDLGui_SetScreen(SDL_Surface *pScrn)
                    136: {
                    137:        pSdlGuiScrn = pScrn;
1.1.1.4 ! root      138:     
1.1       root      139:        /* Decide which font to use - small or big one: */
                    140:        if (pSdlGuiScrn->w >= 640 && pSdlGuiScrn->h >= 400 && pBigFontGfx != NULL)
                    141:        {
                    142:                pFontGfx = pBigFontGfx;
                    143:        }
                    144:        else
                    145:        {
                    146:                pFontGfx = pSmallFontGfx;
                    147:        }
                    148: 
                    149:        if (pFontGfx == NULL)
                    150:        {
                    151:                fprintf(stderr, "Error: A problem with the font occured!\n");
                    152:                return -1;
                    153:        }
1.1.1.4 ! root      154:     
1.1       root      155:        /* Get the font width and height: */
1.1.1.2   root      156:        sdlgui_fontwidth = pFontGfx->w/16;
                    157:     sdlgui_fontheight = pFontGfx->h/16;
1.1       root      158: 
                    159:        return 0;
                    160: }
                    161: 
                    162: /*-----------------------------------------------------------------------*/
                    163: /**
                    164:  * Return character size for current font in given arguments.
                    165:  */
                    166: void SDLGui_GetFontSize(int *width, int *height)
                    167: {
1.1.1.2   root      168:        *width = sdlgui_fontwidth;
                    169:     *height = sdlgui_fontheight;
1.1       root      170: }
                    171: 
                    172: /*-----------------------------------------------------------------------*/
                    173: /**
                    174:  * Center a dialog so that it appears in the middle of the screen.
                    175:  * Note: We only store the coordinates in the root box of the dialog,
                    176:  * all other objects in the dialog are positioned relatively to this one.
                    177:  */
                    178: void SDLGui_CenterDlg(SGOBJ *dlg)
                    179: {
1.1.1.2   root      180:        dlg[0].x = (pSdlGuiScrn->w/sdlgui_fontwidth-dlg[0].w)/2;
                    181:     dlg[0].y = (pSdlGuiScrn->h/sdlgui_fontheight-dlg[0].h)/2;
1.1       root      182: }
                    183: 
                    184: 
                    185: /*-----------------------------------------------------------------------*/
                    186: /**
                    187:  * Draw a text string.
                    188:  */
                    189: void SDLGui_Text(int x, int y, const char *txt)
                    190: {
                    191:        int i;
                    192:        char c;
                    193:        SDL_Rect sr, dr;
                    194: 
                    195:        for (i=0; txt[i]!=0; i++)
                    196:        {
                    197:                c = txt[i];
1.1.1.2   root      198:                sr.x=sdlgui_fontwidth*(c%16);
                    199:         sr.y=sdlgui_fontheight*(c/16);
                    200:         sr.w=sdlgui_fontwidth;
                    201:         sr.h=sdlgui_fontheight;
                    202:         dr.x=x+i*sdlgui_fontwidth;
                    203:                dr.y=y;
                    204:         dr.w=sdlgui_fontwidth;
                    205:         dr.h=sdlgui_fontheight;
1.1       root      206:                SDL_BlitSurface(pFontGfx, &sr, pSdlGuiScrn, &dr);
                    207:        }
                    208: }
                    209: 
                    210: 
                    211: /*-----------------------------------------------------------------------*/
                    212: /**
                    213:  * Draw a dialog text object.
                    214:  */
                    215: static void SDLGui_DrawText(const SGOBJ *tdlg, int objnum)
                    216: {
                    217:        int x, y;
1.1.1.2   root      218:        x = (tdlg[0].x+tdlg[objnum].x)*sdlgui_fontwidth;
                    219:     y = (tdlg[0].y+tdlg[objnum].y)*sdlgui_fontheight;
1.1       root      220:        SDLGui_Text(x, y, tdlg[objnum].txt);
                    221: }
                    222: 
                    223: 
                    224: /*-----------------------------------------------------------------------*/
                    225: /**
                    226:  * Draw a edit field object.
                    227:  */
                    228: static void SDLGui_DrawEditField(const SGOBJ *edlg, int objnum)
                    229: {
                    230:        int x, y;
                    231:        SDL_Rect rect;
                    232: 
1.1.1.2   root      233:        x = (edlg[0].x+edlg[objnum].x)*sdlgui_fontwidth;
                    234:     y = (edlg[0].y+edlg[objnum].y)*sdlgui_fontheight;
1.1       root      235:        SDLGui_Text(x, y, edlg[objnum].txt);
                    236: 
                    237:        rect.x = x;
1.1.1.2   root      238:        rect.y = y + edlg[objnum].h * sdlgui_fontheight;
                    239:     rect.w = edlg[objnum].w * sdlgui_fontwidth;
1.1       root      240:        rect.h = 1;
                    241:        SDL_FillRect(pSdlGuiScrn, &rect, SDL_MapRGB(pSdlGuiScrn->format,160,160,160));
                    242: }
                    243: 
                    244: 
                    245: /*-----------------------------------------------------------------------*/
                    246: /**
                    247:  * Draw a dialog box object.
                    248:  */
                    249: static void SDLGui_DrawBox(const SGOBJ *bdlg, int objnum)
                    250: {
                    251:        SDL_Rect rect;
                    252:        int x, y, w, h, offset;
1.1.1.4 ! root      253:        Uint32 grey = SDL_MapRGB(pSdlGuiScrn->format,181,183,170);
1.1       root      254:        Uint32 upleftc, downrightc;
                    255: 
1.1.1.2   root      256:        x = bdlg[objnum].x*sdlgui_fontwidth;
                    257:     y = bdlg[objnum].y*sdlgui_fontheight;
                    258:        if (objnum > 0)                 /* Since the root object is a box, too, */
                    259:        {
                    260:                /* we have to look for it now here and only */
                    261:                x += bdlg[0].x*sdlgui_fontwidth;   /* add its absolute coordinates if we need to */
                    262:                y += bdlg[0].y*sdlgui_fontheight;
                    263:        }
                    264:        w = bdlg[objnum].w*sdlgui_fontwidth;
                    265:        h = bdlg[objnum].h*sdlgui_fontheight;
1.1       root      266: 
                    267:        if (bdlg[objnum].state & SG_SELECTED)
                    268:        {
1.1.1.4 ! root      269:                upleftc = SDL_MapRGB(pSdlGuiScrn->format,147,145,170);
1.1       root      270:                downrightc = SDL_MapRGB(pSdlGuiScrn->format,255,255,255);
                    271:        }
                    272:        else
                    273:        {
                    274:                upleftc = SDL_MapRGB(pSdlGuiScrn->format,255,255,255);
1.1.1.4 ! root      275:                downrightc = SDL_MapRGB(pSdlGuiScrn->format,147,145,170);
1.1       root      276:        }
                    277: 
                    278:        /* The root box should be bigger than the screen, so we disable the offset there: */
                    279:        if (objnum != 0)
                    280:                offset = 1;
                    281:        else
                    282:                offset = 0;
                    283: 
                    284:        /* Draw background: */
                    285:        rect.x = x;
                    286:        rect.y = y;
                    287:        rect.w = w;
                    288:        rect.h = h;
                    289:        SDL_FillRect(pSdlGuiScrn, &rect, grey);
                    290: 
                    291:        /* Draw upper border: */
                    292:        rect.x = x;
                    293:        rect.y = y - offset;
                    294:        rect.w = w;
                    295:        rect.h = 1;
                    296:        SDL_FillRect(pSdlGuiScrn, &rect, upleftc);
                    297: 
                    298:        /* Draw left border: */
                    299:        rect.x = x - offset;
                    300:        rect.y = y;
                    301:        rect.w = 1;
                    302:        rect.h = h;
                    303:        SDL_FillRect(pSdlGuiScrn, &rect, upleftc);
                    304: 
                    305:        /* Draw bottom border: */
                    306:        rect.x = x;
                    307:        rect.y = y + h - 1 + offset;
                    308:        rect.w = w;
                    309:        rect.h = 1;
                    310:        SDL_FillRect(pSdlGuiScrn, &rect, downrightc);
                    311: 
                    312:        /* Draw right border: */
                    313:        rect.x = x + w - 1 + offset;
                    314:        rect.y = y;
                    315:        rect.w = 1;
                    316:        rect.h = h;
                    317:        SDL_FillRect(pSdlGuiScrn, &rect, downrightc);
                    318: }
                    319: 
                    320: 
                    321: /*-----------------------------------------------------------------------*/
                    322: /**
                    323:  * Draw a normal button.
                    324:  */
                    325: static void SDLGui_DrawButton(const SGOBJ *bdlg, int objnum)
                    326: {
                    327:        int x,y;
                    328: 
                    329:        SDLGui_DrawBox(bdlg, objnum);
                    330: 
1.1.1.2   root      331:        x = (bdlg[0].x + bdlg[objnum].x + (bdlg[objnum].w-strlen(bdlg[objnum].txt))/2) * sdlgui_fontwidth;
                    332:        y = (bdlg[0].y + bdlg[objnum].y + (bdlg[objnum].h-1)/2) * sdlgui_fontheight;
1.1       root      333: 
                    334:        if (bdlg[objnum].state & SG_SELECTED)
                    335:        {
                    336:                x+=1;
                    337:                y+=1;
                    338:        }
                    339:        SDLGui_Text(x, y, bdlg[objnum].txt);
                    340: }
                    341: 
                    342: 
                    343: /*-----------------------------------------------------------------------*/
                    344: /**
                    345:  * Draw a dialog radio button object.
                    346:  */
                    347: static void SDLGui_DrawRadioButton(const SGOBJ *rdlg, int objnum)
                    348: {
                    349:        char str[80];
                    350:        int x, y;
                    351: 
1.1.1.2   root      352:        x = (rdlg[0].x + rdlg[objnum].x) * sdlgui_fontwidth;
                    353:        y = (rdlg[0].y + rdlg[objnum].y) * sdlgui_fontheight;
1.1       root      354: 
                    355:        if (rdlg[objnum].state & SG_SELECTED)
                    356:                str[0]=SGRADIOBUTTON_SELECTED;
                    357:        else
                    358:                str[0]=SGRADIOBUTTON_NORMAL;
                    359:        str[1]=' ';
                    360:        strcpy(&str[2], rdlg[objnum].txt);
                    361: 
                    362:        SDLGui_Text(x, y, str);
                    363: }
                    364: 
                    365: 
                    366: /*-----------------------------------------------------------------------*/
                    367: /**
                    368:  * Draw a dialog check box object.
                    369:  */
                    370: static void SDLGui_DrawCheckBox(const SGOBJ *cdlg, int objnum)
                    371: {
                    372:        char str[80];
                    373:        int x, y;
                    374: 
1.1.1.2   root      375:        x = (cdlg[0].x + cdlg[objnum].x) * sdlgui_fontwidth;
                    376:        y = (cdlg[0].y + cdlg[objnum].y) * sdlgui_fontheight;
1.1       root      377: 
                    378:        if ( cdlg[objnum].state&SG_SELECTED )
                    379:                str[0]=SGCHECKBOX_SELECTED;
                    380:        else
                    381:                str[0]=SGCHECKBOX_NORMAL;
                    382:        str[1]=' ';
                    383:        strcpy(&str[2], cdlg[objnum].txt);
                    384: 
                    385:        SDLGui_Text(x, y, str);
                    386: }
                    387: 
                    388: 
                    389: /*-----------------------------------------------------------------------*/
                    390: /**
1.1.1.2   root      391:   * Draw a scrollbar button.
                    392:   */
                    393: static void SDLGui_DrawScrollbar(const SGOBJ *bdlg, int objnum)
                    394: {
                    395:        SDL_Rect rect;
                    396:        int x, y, w, h;
1.1.1.4 ! root      397:        Uint32 grey0 = SDL_MapRGB(pSdlGuiScrn->format,147,145,170);
        !           398:        Uint32 grey1 = SDL_MapRGB(pSdlGuiScrn->format,181,183,170);
        !           399:        Uint32 grey2 = SDL_MapRGB(pSdlGuiScrn->format, 73, 72, 85);
1.1.1.2   root      400:  
                    401:        x = bdlg[objnum].x * sdlgui_fontwidth;
                    402:        y = bdlg[objnum].y * sdlgui_fontheight + bdlg[objnum].h;
                    403:  
                    404:        x += bdlg[0].x*sdlgui_fontwidth;   /* add mainbox absolute coordinates */
                    405:        y += bdlg[0].y*sdlgui_fontheight;  /* add mainbox absolute coordinates */
                    406:        
                    407:        w = 1 * sdlgui_fontwidth;
                    408:        h = bdlg[objnum].w;
                    409:  
                    410:        /* Draw background: */
                    411:        rect.x = x;
                    412:        rect.y = y;
                    413:        rect.w = w;
                    414:        rect.h = h;
                    415:        SDL_FillRect(pSdlGuiScrn, &rect, grey0);
                    416:  
                    417:        /* Draw upper border: */
                    418:        rect.x = x;
                    419:        rect.y = y;
                    420:        rect.w = w;
                    421:        rect.h = 1;
                    422:        SDL_FillRect(pSdlGuiScrn, &rect, grey1);
                    423:  
                    424:        /* Draw bottom border: */
                    425:        rect.x = x;
                    426:        rect.y = y + h - 1;
                    427:        rect.w = w;
                    428:        rect.h = 1;
                    429:        SDL_FillRect(pSdlGuiScrn, &rect, grey2);
                    430:        
                    431: }
                    432:  
                    433: /*-----------------------------------------------------------------------*/
                    434: /**
1.1       root      435:  *  Draw a dialog popup button object.
                    436:  */
                    437: static void SDLGui_DrawPopupButton(const SGOBJ *pdlg, int objnum)
                    438: {
1.1.1.2   root      439:        int x, y, w;
1.1       root      440:        const char *downstr = "\x02";
                    441: 
                    442:        SDLGui_DrawBox(pdlg, objnum);
                    443: 
1.1.1.2   root      444:        x = (pdlg[0].x + pdlg[objnum].x) * sdlgui_fontwidth;
                    445:        y = (pdlg[0].y + pdlg[objnum].y) * sdlgui_fontheight;
                    446:        w = pdlg[objnum].w * sdlgui_fontwidth;
                    447:     
                    448:        SDLGui_Text(x, y, pdlg[objnum].txt);
                    449:        SDLGui_Text(x+w-sdlgui_fontwidth, y, downstr);
1.1       root      450: }
                    451: 
                    452: 
                    453: /*-----------------------------------------------------------------------*/
                    454: /**
                    455:  * Let the user insert text into an edit field object.
                    456:  * NOTE: The dlg[objnum].txt must point to an an array that is big enough
                    457:  * for dlg[objnum].w characters!
                    458:  */
                    459: static void SDLGui_EditField(SGOBJ *dlg, int objnum)
                    460: {
                    461:        size_t cursorPos;                   /* Position of the cursor in the edit field */
                    462:        int blinkState = 0;                 /* Used for cursor blinking */
                    463:        int bStopEditing = false;           /* true if user wants to exit the edit field */
                    464:        char *txt;                          /* Shortcut for dlg[objnum].txt */
                    465:        SDL_Rect rect;
                    466:        Uint32 grey, cursorCol;
                    467:        SDL_Event event;
                    468: 
1.1.1.4 ! root      469:        /* Enable text input to get unicode characters with SDL_TEXTINPUT event */
        !           470:     SDL_SetTextInputRect(&rect);
        !           471:     SDL_StartTextInput();
1.1       root      472: 
1.1.1.4 ! root      473:        grey = SDL_MapRGB(pSdlGuiScrn->format, 181, 183, 170);
        !           474:        cursorCol = SDL_MapRGB(pSdlGuiScrn->format, 147, 145, 170);
1.1       root      475: 
1.1.1.2   root      476:        rect.x = (dlg[0].x + dlg[objnum].x) * sdlgui_fontwidth;
                    477:        rect.y = (dlg[0].y + dlg[objnum].y) * sdlgui_fontheight;
                    478:        rect.w = (dlg[objnum].w + 1) * sdlgui_fontwidth - 1;
                    479:        rect.h = dlg[objnum].h * sdlgui_fontheight;
1.1       root      480: 
                    481:        txt = dlg[objnum].txt;
                    482:        cursorPos = strlen(txt);
                    483: 
                    484:        do
                    485:        {
                    486:                /* Look for events */
                    487:                if (SDL_PollEvent(&event) == 0)
                    488:                {
                    489:                        /* No event: Wait some time for cursor blinking */
                    490:                        SDL_Delay(250);
                    491:                        blinkState ^= 1;
                    492:                }
                    493:                else
                    494:                {
                    495:                        /* Handle events */
                    496:                        do
                    497:                        {
                    498:                                switch (event.type)
                    499:                                {
1.1.1.4 ! root      500:                 case SDL_WINDOWEVENT:
        !           501:                         if(event.window.event == SDL_WINDOWEVENT_CLOSE) {
        !           502:                             bQuitProgram = true;
        !           503:                             bStopEditing = true;
        !           504:                         }
        !           505:                     break;
1.1       root      506:                                 case SDL_QUIT:                     /* User wants to quit */
                    507:                                        bQuitProgram = true;
                    508:                                        bStopEditing = true;
                    509:                                        break;
                    510:                                 case SDL_MOUSEBUTTONDOWN:          /* Mouse pressed -> stop editing */
                    511:                                        bStopEditing = true;
                    512:                                        break;
                    513:                                 case SDL_KEYDOWN:                  /* Key pressed */
                    514:                                        switch (event.key.keysym.sym)
                    515:                                        {
                    516:                                         case SDLK_RETURN:
                    517:                                         case SDLK_KP_ENTER:
                    518:                                                bStopEditing = true;
                    519:                                                break;
                    520:                                         case SDLK_LEFT:
                    521:                                                if (cursorPos > 0)
                    522:                                                        cursorPos -= 1;
                    523:                                                break;
                    524:                                         case SDLK_RIGHT:
                    525:                                                if (cursorPos < strlen(txt))
                    526:                                                        cursorPos += 1;
                    527:                                                break;
                    528:                                         case SDLK_BACKSPACE:
                    529:                                                if (cursorPos > 0)
                    530:                                                {
                    531:                                                        memmove(&txt[cursorPos-1], &txt[cursorPos], strlen(&txt[cursorPos])+1);
                    532:                                                        cursorPos -= 1;
                    533:                                                }
                    534:                                                break;
                    535:                                         case SDLK_DELETE:
                    536:                                                if (cursorPos < strlen(txt))
                    537:                                                        memmove(&txt[cursorPos], &txt[cursorPos+1], strlen(&txt[cursorPos+1])+1);
                    538:                                                break;
                    539:                                         default:
1.1.1.4 ! root      540:                                                /* Get other keys from SDL_TEXTINPUT event */
        !           541:                             break;
        !           542:                     }
        !           543:                     break;
        !           544:                 case SDL_TEXTINPUT:
        !           545:                         if (strlen(txt) < (size_t)dlg[objnum].w)
        !           546:                         {
        !           547:                             memmove(&txt[cursorPos+1], &txt[cursorPos], strlen(&txt[cursorPos])+1);
        !           548:                                                        txt[cursorPos] = event.text.text[0];
        !           549:                             cursorPos += 1;
        !           550:                         }
1.1       root      551:                                                break;
                    552:                                        }
                    553:                                        break;
                    554:                                }
                    555:                        while (SDL_PollEvent(&event));
                    556: 
                    557:                        blinkState = 1;
                    558:                }
                    559: 
                    560:                /* Redraw the text field: */
                    561:                SDL_FillRect(pSdlGuiScrn, &rect, grey);  /* Draw background */
                    562:                /* Draw the cursor: */
                    563:                if (blinkState && !bStopEditing)
                    564:                {
                    565:                        SDL_Rect cursorrect;
1.1.1.2   root      566:                        cursorrect.x = rect.x + cursorPos * sdlgui_fontwidth;
1.1       root      567:                        cursorrect.y = rect.y;
1.1.1.2   root      568:                        cursorrect.w = sdlgui_fontwidth;
1.1       root      569:                        cursorrect.h = rect.h;
                    570:                        SDL_FillRect(pSdlGuiScrn, &cursorrect, cursorCol);
                    571:                }
                    572:                SDLGui_Text(rect.x, rect.y, dlg[objnum].txt);  /* Draw text */
                    573:                SDL_UpdateRects(pSdlGuiScrn, 1, &rect);
                    574:        }
                    575:        while (!bStopEditing);
                    576: 
1.1.1.4 ! root      577:     SDL_StopTextInput();
1.1       root      578: }
                    579: 
                    580: 
                    581: /*-----------------------------------------------------------------------*/
                    582: /**
                    583:  * Draw a whole dialog.
                    584:  */
                    585: void SDLGui_DrawDialog(const SGOBJ *dlg)
                    586: {
                    587:        int i;
                    588:        for (i = 0; dlg[i].type != -1; i++)
                    589:        {
                    590:                switch (dlg[i].type)
                    591:                {
                    592:                 case SGBOX:
                    593:                        SDLGui_DrawBox(dlg, i);
                    594:                        break;
                    595:                 case SGTEXT:
                    596:                        SDLGui_DrawText(dlg, i);
                    597:                        break;
                    598:                 case SGEDITFIELD:
                    599:                        SDLGui_DrawEditField(dlg, i);
                    600:                        break;
                    601:                 case SGBUTTON:
                    602:                        SDLGui_DrawButton(dlg, i);
                    603:                        break;
                    604:                 case SGRADIOBUT:
                    605:                        SDLGui_DrawRadioButton(dlg, i);
                    606:                        break;
                    607:                 case SGCHECKBOX:
                    608:                        SDLGui_DrawCheckBox(dlg, i);
                    609:                        break;
                    610:                 case SGPOPUP:
                    611:                        SDLGui_DrawPopupButton(dlg, i);
                    612:                        break;
1.1.1.2   root      613:         case SGSCROLLBAR:
                    614:                        SDLGui_DrawScrollbar(dlg, i);
                    615:                        break;
1.1       root      616:                }
                    617:        }
                    618:        SDL_UpdateRect(pSdlGuiScrn, 0,0,0,0);
                    619: }
                    620: 
                    621: 
                    622: /*-----------------------------------------------------------------------*/
                    623: /**
                    624:  * Search an object at a certain position.
                    625:  */
                    626: static int SDLGui_FindObj(const SGOBJ *dlg, int fx, int fy)
                    627: {
                    628:        int len, i;
                    629:        int ob = -1;
                    630:        int xpos, ypos;
                    631: 
                    632:        len = 0;
                    633:        while (dlg[len].type != -1)   len++;
                    634: 
1.1.1.2   root      635:        xpos = fx / sdlgui_fontwidth;
                    636:        ypos = fy / sdlgui_fontheight;
1.1       root      637:        /* Now search for the object: */
                    638:        for (i = len; i >= 0; i--)
                    639:        {
1.1.1.2   root      640:                /* clicked on a scrollbar ? */
                    641:                if (dlg[i].type == SGSCROLLBAR) {
                    642:                        if (xpos >= dlg[0].x+dlg[i].x && xpos < dlg[0].x+dlg[i].x+1) {
                    643:                                ypos = dlg[i].y * sdlgui_fontheight + dlg[i].h + dlg[0].y * sdlgui_fontheight;
                    644:                                if (fy >= ypos && fy < ypos + dlg[i].w) {
                    645:                                        ob = i;
                    646:                                        break;
                    647:                                }
                    648:                        }
                    649:                }
                    650:                /* clicked on another object ? */
                    651:                else if (xpos >= dlg[0].x+dlg[i].x && ypos >= dlg[0].y+dlg[i].y
                    652:                          && xpos < dlg[0].x+dlg[i].x+dlg[i].w && ypos < dlg[0].y+dlg[i].y+dlg[i].h)
1.1       root      653:                {
                    654:                        ob = i;
                    655:                        break;
                    656:                }
                    657:        }
                    658: 
                    659:        return ob;
                    660: }
                    661: 
                    662: 
                    663: /*-----------------------------------------------------------------------*/
                    664: /**
                    665:  * Search a button with a special flag (e.g. SG_DEFAULT or SG_CANCEL).
                    666:  */
                    667: static int SDLGui_SearchFlaggedButton(const SGOBJ *dlg, int flag)
                    668: {
                    669:        int i = 0;
                    670: 
                    671:        while (dlg[i].type != -1)
                    672:        {
                    673:                if (dlg[i].flags & flag)
                    674:                        return i;
                    675:                i++;
                    676:        }
                    677: 
                    678:        return 0;
                    679: }
                    680: 
                    681: 
                    682: /*-----------------------------------------------------------------------*/
                    683: /**
                    684:  * Show and process a dialog. Returns the button number that has been
                    685:  * pressed or SDLGUI_UNKNOWNEVENT if an unsupported event occured (will be
                    686:  * stored in parameter pEventOut).
                    687:  */
                    688: int SDLGui_DoDialog(SGOBJ *dlg, SDL_Event *pEventOut)
                    689: {
                    690:        int obj=0;
                    691:        int oldbutton=0;
                    692:        int retbutton=0;
                    693:        int i, j, b;
                    694:        SDL_Event sdlEvent;
                    695:        SDL_Rect rct;
                    696:        Uint32 grey;
                    697:        SDL_Surface *pBgSurface;
                    698:        SDL_Rect dlgrect, bgrect;
                    699: 
1.1.1.2   root      700:        if (pSdlGuiScrn->h / sdlgui_fontheight < dlg[0].h)
1.1       root      701:        {
                    702:                fprintf(stderr, "Screen size too small for dialog!\n");
                    703:                return SDLGUI_ERROR;
                    704:        }
                    705: 
1.1.1.4 ! root      706:        grey = SDL_MapRGB(pSdlGuiScrn->format,181,183,170);
1.1       root      707: 
1.1.1.2   root      708:        dlgrect.x = dlg[0].x * sdlgui_fontwidth;
                    709:        dlgrect.y = dlg[0].y * sdlgui_fontheight;
                    710:        dlgrect.w = dlg[0].w * sdlgui_fontwidth;
                    711:        dlgrect.h = dlg[0].h * sdlgui_fontheight;
1.1       root      712: 
                    713:        bgrect.x = bgrect.y = 0;
                    714:        bgrect.w = dlgrect.w;
                    715:        bgrect.h = dlgrect.h;
                    716: 
                    717:        /* Save background */
                    718:        pBgSurface = SDL_CreateRGBSurface(SDL_SWSURFACE, dlgrect.w, dlgrect.h, pSdlGuiScrn->format->BitsPerPixel,
                    719:                                          pSdlGuiScrn->format->Rmask, pSdlGuiScrn->format->Gmask, pSdlGuiScrn->format->Bmask, pSdlGuiScrn->format->Amask);
                    720:        if (pSdlGuiScrn->format->palette != NULL)
                    721:        {
1.1.1.4 ! root      722:                SDL_SetPaletteColors(pBgSurface->format->palette, pSdlGuiScrn->format->palette->colors, 0, pSdlGuiScrn->format->palette->ncolors-1);
1.1       root      723:        }
                    724: 
                    725:        if (pBgSurface != NULL)
                    726:        {
                    727:                SDL_BlitSurface(pSdlGuiScrn,  &dlgrect, pBgSurface, &bgrect);
                    728:        }
                    729:        else
                    730:        {
                    731:                fprintf(stderr, "SDLGUI_DoDialog: CreateRGBSurface failed: %s\n", SDL_GetError());
                    732:        }
                    733: 
                    734:        /* (Re-)draw the dialog */
                    735:        SDLGui_DrawDialog(dlg);
                    736: 
                    737:        /* Is the left mouse button still pressed? Yes -> Handle TOUCHEXIT objects here */
                    738:        SDL_PumpEvents();
                    739:        b = SDL_GetMouseState(&i, &j);
1.1.1.2   root      740: 
                    741:        /* If current object is the scrollbar, and mouse is still down, we can scroll it */
                    742:        /* also if the mouse pointer has left the scrollbar */
                    743:        if (dlg[current_object].type == SGSCROLLBAR) {
                    744:                if (b & SDL_BUTTON(1)) {
                    745:                        obj = current_object;
                    746:                        dlg[obj].state |= SG_MOUSEDOWN;
                    747:                        oldbutton = obj;
                    748:                        retbutton = obj;
                    749:                }
                    750:                else {
                    751:                        obj = current_object;
                    752:                        current_object = 0;
                    753:                        dlg[obj].state &= SG_MOUSEUP;
1.1       root      754:                        retbutton = obj;
1.1.1.2   root      755:             oldbutton = obj;
1.1       root      756:                }
                    757:        }
1.1.1.2   root      758:     else {
                    759:                obj = SDLGui_FindObj(dlg, i, j);
                    760:                current_object = obj;
                    761:                if (obj > 0 && (dlg[obj].flags&SG_TOUCHEXIT) )
                    762:                {
                    763:                        oldbutton = obj;
                    764:                        if (b & SDL_BUTTON(1))
                    765:                        {
                    766:                                dlg[obj].state |= SG_SELECTED;
                    767:                                retbutton = obj;
                    768:                        }
                    769:                }
                    770:        }
1.1       root      771: 
1.1.1.2   root      772:     
1.1       root      773:        /* The main loop */
                    774:        while (retbutton == 0 && !bQuitProgram)
                    775:        {
                    776:                if (SDL_WaitEvent(&sdlEvent) == 1)  /* Wait for events */
1.1.1.2   root      777:             
1.1       root      778:                        switch (sdlEvent.type)
                    779:                        {
                    780:                         case SDL_QUIT:
                    781:                                retbutton = SDLGUI_QUIT;
                    782:                                break;
                    783: 
                    784:                         case SDL_MOUSEBUTTONDOWN:
                    785:                                if (sdlEvent.button.button != SDL_BUTTON_LEFT)
                    786:                                {
                    787:                                        /* Not left mouse button -> unsupported event */
                    788:                                        if (pEventOut)
                    789:                                                retbutton = SDLGUI_UNKNOWNEVENT;
                    790:                                        break;
                    791:                                }
                    792:                                /* It was the left button: Find the object under the mouse cursor */
                    793:                                obj = SDLGui_FindObj(dlg, sdlEvent.button.x, sdlEvent.button.y);
                    794:                                if (obj>0)
                    795:                                {
                    796:                                        if (dlg[obj].type==SGBUTTON)
                    797:                                        {
                    798:                                                dlg[obj].state |= SG_SELECTED;
                    799:                                                SDLGui_DrawButton(dlg, obj);
1.1.1.2   root      800:                                                SDL_UpdateRect(pSdlGuiScrn, (dlg[0].x+dlg[obj].x)*sdlgui_fontwidth-2, (dlg[0].y+dlg[obj].y)*sdlgui_fontheight-2,
                    801:                                                               dlg[obj].w*sdlgui_fontwidth+4, dlg[obj].h*sdlgui_fontheight+4);
                    802:                                                oldbutton=obj;
                    803:                                        }
                    804:                                        if (dlg[obj].type==SGSCROLLBAR)
                    805:                                        {
                    806:                                                dlg[obj].state |= SG_MOUSEDOWN;
1.1       root      807:                                                oldbutton=obj;
                    808:                                        }
                    809:                                        if ( dlg[obj].flags&SG_TOUCHEXIT )
                    810:                                        {
                    811:                                                dlg[obj].state |= SG_SELECTED;
                    812:                                                retbutton = obj;
                    813:                                        }
                    814:                                }
                    815:                                break;
                    816: 
                    817:                         case SDL_MOUSEBUTTONUP:
                    818:                                if (sdlEvent.button.button != SDL_BUTTON_LEFT)
                    819:                                {
                    820:                                        /* Not left mouse button -> unsupported event */
                    821:                                        if (pEventOut)
                    822:                                                retbutton = SDLGUI_UNKNOWNEVENT;
                    823:                                        break;
                    824:                                }
                    825:                                /* It was the left button: Find the object under the mouse cursor */
                    826:                                obj = SDLGui_FindObj(dlg, sdlEvent.button.x, sdlEvent.button.y);
                    827:                                if (obj>0)
                    828:                                {
                    829:                                        switch (dlg[obj].type)
                    830:                                        {
                    831:                                         case SGBUTTON:
                    832:                                                if (oldbutton==obj)
                    833:                                                        retbutton=obj;
                    834:                                                break;
1.1.1.2   root      835:                         case SGSCROLLBAR:
                    836:                                                dlg[obj].state &= SG_MOUSEUP;
                    837:  
                    838:                                                if (oldbutton==obj)
                    839:                                                        retbutton=obj;
                    840:                                                break;
                    841:                                        case SGEDITFIELD:
1.1       root      842:                                                SDLGui_EditField(dlg, obj);
                    843:                                                break;
                    844:                                         case SGRADIOBUT:
                    845:                                                for (i = obj-1; i > 0 && dlg[i].type == SGRADIOBUT; i--)
                    846:                                                {
                    847:                                                        dlg[i].state &= ~SG_SELECTED;  /* Deselect all radio buttons in this group */
1.1.1.2   root      848:                                                        rct.x = (dlg[0].x+dlg[i].x)*sdlgui_fontwidth;
                    849:                                                        rct.y = (dlg[0].y+dlg[i].y)*sdlgui_fontheight;
                    850:                                                        rct.w = sdlgui_fontwidth;
                    851:                                                        rct.h = sdlgui_fontheight;
1.1       root      852:                                                        SDL_FillRect(pSdlGuiScrn, &rct, grey); /* Clear old */
                    853:                                                        SDLGui_DrawRadioButton(dlg, i);
                    854:                                                        SDL_UpdateRects(pSdlGuiScrn, 1, &rct);
                    855:                                                }
                    856:                                                for (i = obj+1; dlg[i].type == SGRADIOBUT; i++)
                    857:                                                {
                    858:                                                        dlg[i].state &= ~SG_SELECTED;  /* Deselect all radio buttons in this group */
1.1.1.2   root      859:                                                        rct.x = (dlg[0].x+dlg[i].x)*sdlgui_fontwidth;
                    860:                                                        rct.y = (dlg[0].y+dlg[i].y)*sdlgui_fontheight;
                    861:                                                        rct.w = sdlgui_fontwidth;
                    862:                                                        rct.h = sdlgui_fontheight;
1.1       root      863:                                                        SDL_FillRect(pSdlGuiScrn, &rct, grey); /* Clear old */
                    864:                                                        SDLGui_DrawRadioButton(dlg, i);
                    865:                                                        SDL_UpdateRects(pSdlGuiScrn, 1, &rct);
                    866:                                                }
                    867:                                                dlg[obj].state |= SG_SELECTED;  /* Select this radio button */
1.1.1.2   root      868:                             rct.x = (dlg[0].x+dlg[obj].x)*sdlgui_fontwidth;
                    869:                                                rct.y = (dlg[0].y+dlg[obj].y)*sdlgui_fontheight;
                    870:                                                rct.w = sdlgui_fontwidth;
                    871:                                                rct.h = sdlgui_fontheight;
1.1       root      872:                                                SDL_FillRect(pSdlGuiScrn, &rct, grey); /* Clear old */
                    873:                                                SDLGui_DrawRadioButton(dlg, obj);
                    874:                                                SDL_UpdateRects(pSdlGuiScrn, 1, &rct);
1.1.1.3   root      875:                             retbutton = obj; // added by andreas_g
1.1       root      876:                                                break;
                    877:                                         case SGCHECKBOX:
                    878:                                                dlg[obj].state ^= SG_SELECTED;
1.1.1.2   root      879:                         rct.x = (dlg[0].x+dlg[obj].x)*sdlgui_fontwidth;
                    880:                                                rct.y = (dlg[0].y+dlg[obj].y)*sdlgui_fontheight;
                    881:                                                rct.w = sdlgui_fontwidth;
                    882:                                                rct.h = sdlgui_fontheight;
1.1       root      883:                                                SDL_FillRect(pSdlGuiScrn, &rct, grey); /* Clear old */
                    884:                                                SDLGui_DrawCheckBox(dlg, obj);
                    885:                                                SDL_UpdateRects(pSdlGuiScrn, 1, &rct);
1.1.1.3   root      886:                             retbutton = obj; // added by andreas_g
1.1       root      887:                                                break;
                    888:                                         case SGPOPUP:
                    889:                                                dlg[obj].state |= SG_SELECTED;
                    890:                                                SDLGui_DrawPopupButton(dlg, obj);
1.1.1.2   root      891:                             SDL_UpdateRect(pSdlGuiScrn, (dlg[0].x+dlg[obj].x)*sdlgui_fontwidth-2, (dlg[0].y+dlg[obj].y)*sdlgui_fontheight-2,
                    892:                                                               dlg[obj].w*sdlgui_fontwidth+4, dlg[obj].h*sdlgui_fontheight+4);
1.1       root      893:                                                retbutton=obj;
                    894:                                                break;
                    895:                                        }
                    896:                                }
1.1.1.2   root      897:                                if (oldbutton > 0 && dlg[oldbutton].type == SGBUTTON)
1.1       root      898:                                {
                    899:                                        dlg[oldbutton].state &= ~SG_SELECTED;
                    900:                                        SDLGui_DrawButton(dlg, oldbutton);
1.1.1.2   root      901:                                        SDL_UpdateRect(pSdlGuiScrn, (dlg[0].x+dlg[oldbutton].x)*sdlgui_fontwidth-2, (dlg[0].y+dlg[oldbutton].y)*sdlgui_fontheight-2,
                    902:                                                       dlg[oldbutton].w*sdlgui_fontwidth+4, dlg[oldbutton].h*sdlgui_fontheight+4);
1.1       root      903:                                        oldbutton = 0;
                    904:                                }
                    905:                                if (obj >= 0 && (dlg[obj].flags&SG_EXIT))
                    906:                                {
                    907:                                        retbutton = obj;
                    908:                                }
                    909:                                break;
                    910: 
                    911:                         case SDL_JOYAXISMOTION:
                    912:                         case SDL_JOYBALLMOTION:
                    913:                         case SDL_JOYHATMOTION:
                    914:                         case SDL_MOUSEMOTION:
                    915:                                break;
                    916: 
                    917:                         case SDL_KEYDOWN:                     /* Key pressed */
                    918:                                if (sdlEvent.key.keysym.sym == SDLK_RETURN
                    919:                                    || sdlEvent.key.keysym.sym == SDLK_KP_ENTER)
                    920:                                {
                    921:                                        retbutton = SDLGui_SearchFlaggedButton(dlg, SG_DEFAULT);
                    922:                                }
                    923:                                else if (sdlEvent.key.keysym.sym == SDLK_ESCAPE)
                    924:                                {
                    925:                                        retbutton = SDLGui_SearchFlaggedButton(dlg, SG_CANCEL);
                    926:                                }
                    927:                                else if (pEventOut)
                    928:                                {
                    929:                                        retbutton = SDLGUI_UNKNOWNEVENT;
                    930:                                }
                    931:                                break;
                    932: 
                    933:                         default:
                    934:                                if (pEventOut)
                    935:                                        retbutton = SDLGUI_UNKNOWNEVENT;
                    936:                                break;
                    937:                        }
                    938:        }
                    939: 
                    940:        /* Restore background */
                    941:        if (pBgSurface)
                    942:        {
                    943:                SDL_BlitSurface(pBgSurface, &bgrect, pSdlGuiScrn,  &dlgrect);
                    944:                SDL_FreeSurface(pBgSurface);
                    945:        }
                    946: 
                    947:        /* Copy event data of unsupported events if caller wants to have it */
                    948:        if (retbutton == SDLGUI_UNKNOWNEVENT && pEventOut)
                    949:                memcpy(pEventOut, &sdlEvent, sizeof(SDL_Event));
                    950: 
                    951:        if (retbutton == SDLGUI_QUIT)
                    952:                bQuitProgram = true;
                    953: 
                    954:        return retbutton;
                    955: }
                    956: 

unix.superglobalmegacorp.com

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