|
|
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
1.1.1.2 root 17: * GNU General Public License (gpl.txt) for more details.
1.1 root 18: */
1.1.1.7 root 19: const char DlgAlert_fileid[] = "Hatari dlgAlert.c : " __DATE__ " " __TIME__;
1.1 root 20:
21: #include <string.h>
22:
23: #include "main.h"
24: #include "dialog.h"
1.1.1.2 root 25: #include "screen.h"
1.1 root 26: #include "sdlgui.h"
27:
28:
29: #define MAX_LINES 4
30:
31: static char dlglines[MAX_LINES][50+1];
32:
1.1.1.3 root 33: #ifdef ALERT_HOOKS
34: // The alert hook functions
1.1.1.7 root 35: extern int HookedAlertNotice(const char* szMessage); // Must return true if OK clicked, false otherwise
36: extern int HookedAlertQuery(const char* szMessage); // Must return true if OK clicked, false otherwise
1.1.1.3 root 37: #endif
1.1 root 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] },
1.1.1.4 root 50: { SGBUTTON, SG_DEFAULT, 0, 5,5, 8,1, "OK" },
51: { SGBUTTON, SG_CANCEL, 0, 24,5, 8,1, "Cancel" },
1.1 root 52: { -1, 0, 0, 0,0, 0,0, NULL }
53: };
54:
55:
56: /*-----------------------------------------------------------------------*/
1.1.1.8 root 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: */
1.1.1.4 root 62: static int DlgAlert_FormatTextToBox(char *text, int max_width, int *text_width)
1.1 root 63: {
1.1.1.4 root 64: int columns = 0;
1.1 root 65: int lines = 1;
66: int txtlen;
1.1.1.4 root 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 */
1.1 root 71:
72: txtlen = strlen(text);
73:
74: q = p = text;
1.1.1.4 root 75: llb = text-1; /* pointer to last line break */
1.1 root 76: txtend = text + txtlen;
77:
1.1.1.4 root 78: if (txtlen <= max_width)
1.1 root 79: {
1.1.1.4 root 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? */
1.1 root 100: {
1.1.1.4 root 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 */
1.1 root 103: }
1.1.1.4 root 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 */
1.1 root 112: }
113:
1.1.1.4 root 114: *text_width = columns;
115:
116: return lines; /* return line counter */
1.1 root 117: }
118:
119:
120:
121: /*-----------------------------------------------------------------------*/
1.1.1.8 root 122: /**
123: * Show the "alert" dialog. Return true if user pressed "OK".
124: */
1.1 root 125: static int DlgAlert_ShowDlg(const char *text)
126: {
1.1.1.4 root 127: static int maxlen = sizeof(dlglines[0])-1;
1.1 root 128: char *t = (char *)malloc(strlen(text)+1);
129: char *orig_t = t;
1.1.1.4 root 130: int lines, i, len, offset;
1.1.1.5 root 131: bool bOldMouseVisibility;
1.1.1.4 root 132: int nOldMouseX, nOldMouseY;
1.1 root 133:
1.1.1.11! root 134: #if WITH_SDL2
! 135: bool bOldMouseMode = SDL_GetRelativeMouseMode();
! 136: SDL_SetRelativeMouseMode(SDL_FALSE);
! 137: #endif
1.1 root 138: strcpy(t, text);
1.1.1.4 root 139: lines = DlgAlert_FormatTextToBox(t, maxlen, &len);
140: offset = (maxlen-len)/2;
1.1 root 141:
142: for(i=0; i<MAX_LINES; i++)
143: {
144: if (i < lines)
145: {
1.1.1.4 root 146: /* center text to current dlgline */
147: memset(dlglines[i], ' ', offset);
148: strcpy(dlglines[i] + offset, t);
1.1 root 149: t += strlen(t)+1;
150: }
151: else
152: {
153: dlglines[i][0] = '\0';
154: }
155: }
156:
157: free(orig_t);
158:
1.1.1.2 root 159: if (SDLGui_SetScreen(sdlscrn))
1.1.1.7 root 160: return false;
1.1 root 161: SDLGui_CenterDlg(alertdlg);
162:
1.1.1.4 root 163: SDL_GetMouseState(&nOldMouseX, &nOldMouseY);
1.1 root 164: bOldMouseVisibility = SDL_ShowCursor(SDL_QUERY);
165: SDL_ShowCursor(SDL_ENABLE);
166:
1.1.1.11! root 167: i = SDLGui_DoDialog(alertdlg, NULL, false);
1.1 root 168:
1.1.1.4 root 169: SDL_UpdateRect(sdlscrn, 0,0, 0,0);
1.1 root 170: SDL_ShowCursor(bOldMouseVisibility);
1.1.1.11! root 171: Main_WarpMouse(nOldMouseX, nOldMouseY, true);
! 172:
! 173: #if WITH_SDL2
! 174: SDL_SetRelativeMouseMode(bOldMouseMode);
! 175: #endif
1.1 root 176:
177: return (i == DLGALERT_OK);
178: }
179:
180:
181: /*-----------------------------------------------------------------------*/
1.1.1.8 root 182: /**
183: * Show a "notice" dialog: (only one button)
184: */
1.1 root 185: int DlgAlert_Notice(const char *text)
186: {
1.1.1.10 root 187: #ifdef ALERT_HOOKS
188: if (!Main_UnPauseEmulation())
189: Main_PauseEmulation(true);
190: if(!bInFullScreen)
191: return HookedAlertNotice(text);
1.1.1.3 root 192: #endif
193:
1.1 root 194: /* Hide "cancel" button: */
195: alertdlg[DLGALERT_CANCEL].type = SGTEXT;
196: alertdlg[DLGALERT_CANCEL].txt = "";
1.1.1.9 root 197: alertdlg[DLGALERT_CANCEL].w = 0;
198: alertdlg[DLGALERT_CANCEL].h = 0;
1.1 root 199:
200: /* Adjust button position: */
201: alertdlg[DLGALERT_OK].x = (alertdlg[0].w - alertdlg[DLGALERT_OK].w) / 2;
202:
203: return DlgAlert_ShowDlg(text);
204: }
205:
206:
207: /*-----------------------------------------------------------------------*/
1.1.1.8 root 208: /**
209: * Show a "query" dialog: (two buttons), return true for OK
210: */
1.1 root 211: int DlgAlert_Query(const char *text)
212: {
1.1.1.3 root 213: #ifdef ALERT_HOOKS
1.1.1.10 root 214: if(!bInFullScreen)
215: return HookedAlertQuery(text);
1.1.1.3 root 216: #endif
217:
1.1 root 218: /* Show "cancel" button: */
219: alertdlg[DLGALERT_CANCEL].type = SGBUTTON;
220: alertdlg[DLGALERT_CANCEL].txt = "Cancel";
221: alertdlg[DLGALERT_CANCEL].w = 8;
222: alertdlg[DLGALERT_CANCEL].h = 1;
223:
224: /* Adjust buttons positions: */
225: alertdlg[DLGALERT_OK].x = (alertdlg[0].w - alertdlg[DLGALERT_OK].w - alertdlg[DLGALERT_CANCEL].w) / 3;
226: alertdlg[DLGALERT_CANCEL].x = alertdlg[DLGALERT_OK].x * 2 + alertdlg[DLGALERT_OK].w;
227:
228: return DlgAlert_ShowDlg(text);
229: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.