|
|
1.1 ! root 1: /* ! 2: * Hatari - dlgAlert.c - AES-like AlertBox ! 3: * ! 4: * Based on dlgAlert.cpp from the emulator ARAnyM, ! 5: * Copyright (c) 2004 Petr Stehlik of ARAnyM dev team ! 6: * ! 7: * Adaptation to Hatari by Thomas Huth. ! 8: * ! 9: * This file is free software; you can redistribute it and/or modify ! 10: * it under the terms of the GNU General Public License as published by ! 11: * the Free Software Foundation; either version 2 of the License, or ! 12: * (at your option) any later version. ! 13: * ! 14: * This file is distributed in the hope that it will be useful, ! 15: * but WITHOUT ANY WARRANTY; without even the implied warranty of ! 16: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ! 17: * GNU General Public License (gpl.txt) for more details. ! 18: */ ! 19: const char DlgAlert_fileid[] = "Hatari dlgAlert.c : " __DATE__ " " __TIME__; ! 20: ! 21: #include <string.h> ! 22: ! 23: #include "main.h" ! 24: #include "dialog.h" ! 25: #include "screen.h" ! 26: #include "sdlgui.h" ! 27: ! 28: ! 29: #define MAX_LINES 4 ! 30: ! 31: static char dlglines[MAX_LINES][50+1]; ! 32: ! 33: #ifdef ALERT_HOOKS ! 34: // The alert hook functions ! 35: int HookedAlertNotice(const char* szMessage); // Must return true if OK clicked, false otherwise ! 36: int HookedAlertQuery(const char* szMessage); // Must return true if OK clicked, false otherwise ! 37: #endif ! 38: ! 39: #define DLGALERT_OK 5 ! 40: #define DLGALERT_CANCEL 6 ! 41: ! 42: /* The "Alert"-dialog: */ ! 43: static SGOBJ alertdlg[] = ! 44: { ! 45: { SGBOX, 0, 0, 0,0, 52,7, NULL }, ! 46: { SGTEXT, 0, 0, 1,1, 50,1, dlglines[0] }, ! 47: { SGTEXT, 0, 0, 1,2, 50,1, dlglines[1] }, ! 48: { SGTEXT, 0, 0, 1,3, 50,1, dlglines[2] }, ! 49: { SGTEXT, 0, 0, 1,4, 50,1, dlglines[3] }, ! 50: { SGBUTTON, SG_DEFAULT, 0, 5,5, 8,1, "OK" }, ! 51: { SGBUTTON, SG_CANCEL, 0, 24,5, 8,1, "Cancel" }, ! 52: { -1, 0, 0, 0,0, 0,0, NULL } ! 53: }; ! 54: ! 55: ! 56: /*-----------------------------------------------------------------------*/ ! 57: /** ! 58: * Breaks long string to several strings of max_width, divided by '\0', ! 59: * sets text_width to the longest line width and returns the number of lines ! 60: * you need to display the strings. ! 61: */ ! 62: static int DlgAlert_FormatTextToBox(char *text, int max_width, int *text_width) ! 63: { ! 64: int columns = 0; ! 65: int lines = 1; ! 66: int txtlen; ! 67: char *p; /* pointer to begin of actual line */ ! 68: char *q; /* pointer to start of next search */ ! 69: char *llb; /* pointer to last place suitable for breaking the line */ ! 70: char *txtend; /* pointer to end of the text */ ! 71: ! 72: txtlen = strlen(text); ! 73: ! 74: q = p = text; ! 75: llb = text-1; /* pointer to last line break */ ! 76: txtend = text + txtlen; ! 77: ! 78: if (txtlen <= max_width) ! 79: { ! 80: *text_width = txtlen; ! 81: return lines; ! 82: } ! 83: ! 84: while(q < txtend) /* q was last place suitable for breaking */ ! 85: { ! 86: char *r = strpbrk(q, " \t/\\\n"); /* find next suitable place for the break */ ! 87: if (r == NULL) ! 88: r = txtend; /* if there's no place then point to the end */ ! 89: ! 90: if ((r-p) <= max_width && *r != '\n') /* '\n' is always used for breaking */ ! 91: { ! 92: llb = r; /* remember new place suitable for breaking */ ! 93: q++; ! 94: if ((r-p) > columns) ! 95: columns = r - p; ! 96: continue; /* search again */ ! 97: } ! 98: ! 99: if ((r-p) > max_width) /* too long line already? */ ! 100: { ! 101: if (p > llb) /* bad luck - no place for the delimiter. Let's do it the strong way */ ! 102: llb = p + max_width; /* we loose one character */ ! 103: } ! 104: else ! 105: llb = r; /* break from previous delimiter */ ! 106: ! 107: *llb = '\0'; /* BREAK */ ! 108: if ((llb-p) > columns) ! 109: columns = llb - p; /* longest line so far */ ! 110: p = q = llb + 1; /* next line begins here */ ! 111: lines++; /* increment line counter */ ! 112: } ! 113: ! 114: *text_width = columns; ! 115: ! 116: return lines; /* return line counter */ ! 117: } ! 118: ! 119: ! 120: ! 121: /*-----------------------------------------------------------------------*/ ! 122: /** ! 123: * Show the "alert" dialog. Return true if user pressed "OK". ! 124: */ ! 125: static int DlgAlert_ShowDlg(const char *text) ! 126: { ! 127: static int maxlen = sizeof(dlglines[0])-1; ! 128: char *t = (char *)malloc(strlen(text)+1); ! 129: char *orig_t = t; ! 130: int lines, i, len, offset; ! 131: bool bOldMouseVisibility; ! 132: int nOldMouseX, nOldMouseY; ! 133: ! 134: strcpy(t, text); ! 135: lines = DlgAlert_FormatTextToBox(t, maxlen, &len); ! 136: offset = (maxlen-len)/2; ! 137: ! 138: for(i=0; i<MAX_LINES; i++) ! 139: { ! 140: if (i < lines) ! 141: { ! 142: /* center text to current dlgline */ ! 143: memset(dlglines[i], ' ', offset); ! 144: strcpy(dlglines[i] + offset, t); ! 145: t += strlen(t)+1; ! 146: } ! 147: else ! 148: { ! 149: dlglines[i][0] = '\0'; ! 150: } ! 151: } ! 152: ! 153: free(orig_t); ! 154: ! 155: if (SDLGui_SetScreen(sdlscrn)) ! 156: return false; ! 157: SDLGui_CenterDlg(alertdlg); ! 158: ! 159: SDL_GetMouseState(&nOldMouseX, &nOldMouseY); ! 160: bOldMouseVisibility = SDL_ShowCursor(SDL_QUERY); ! 161: SDL_ShowCursor(SDL_ENABLE); ! 162: ! 163: i = SDLGui_DoDialog(alertdlg, NULL); ! 164: ! 165: SDL_UpdateRect(sdlscrn, 0,0, 0,0); ! 166: SDL_ShowCursor(bOldMouseVisibility); ! 167: Main_WarpMouse(nOldMouseX, nOldMouseY); ! 168: ! 169: return (i == DLGALERT_OK); ! 170: } ! 171: ! 172: ! 173: /*-----------------------------------------------------------------------*/ ! 174: /** ! 175: * Show a "notice" dialog: (only one button) ! 176: */ ! 177: int DlgAlert_Notice(const char *text) ! 178: { ! 179: #ifdef ALERT_HOOKS ! 180: return HookedAlertNotice(text); ! 181: #endif ! 182: ! 183: /* Hide "cancel" button: */ ! 184: alertdlg[DLGALERT_CANCEL].type = SGTEXT; ! 185: alertdlg[DLGALERT_CANCEL].txt = ""; ! 186: alertdlg[DLGALERT_CANCEL].w = 0; ! 187: alertdlg[DLGALERT_CANCEL].h = 0; ! 188: ! 189: /* Adjust button position: */ ! 190: alertdlg[DLGALERT_OK].x = (alertdlg[0].w - alertdlg[DLGALERT_OK].w) / 2; ! 191: ! 192: return DlgAlert_ShowDlg(text); ! 193: } ! 194: ! 195: ! 196: /*-----------------------------------------------------------------------*/ ! 197: /** ! 198: * Show a "query" dialog: (two buttons), return true for OK ! 199: */ ! 200: int DlgAlert_Query(const char *text) ! 201: { ! 202: #ifdef ALERT_HOOKS ! 203: return HookedAlertQuery(text); ! 204: #endif ! 205: ! 206: /* Show "cancel" button: */ ! 207: alertdlg[DLGALERT_CANCEL].type = SGBUTTON; ! 208: alertdlg[DLGALERT_CANCEL].txt = "Cancel"; ! 209: alertdlg[DLGALERT_CANCEL].w = 8; ! 210: alertdlg[DLGALERT_CANCEL].h = 1; ! 211: ! 212: /* Adjust buttons positions: */ ! 213: alertdlg[DLGALERT_OK].x = (alertdlg[0].w - alertdlg[DLGALERT_OK].w - alertdlg[DLGALERT_CANCEL].w) / 3; ! 214: alertdlg[DLGALERT_CANCEL].x = alertdlg[DLGALERT_OK].x * 2 + alertdlg[DLGALERT_OK].w; ! 215: ! 216: return DlgAlert_ShowDlg(text); ! 217: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.