|
|
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.4 ! root 19: const char DlgAlert_rcsid[] = "Hatari $Id: dlgAlert.c,v 1.12 2008/02/29 20:24:21 thothy Exp $";
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
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
37:
38: // Runtime switch to activate/deactivate alert hooks
39: BOOL useAlertHooks = FALSE;
40: #endif
1.1 root 41:
42: #define DLGALERT_OK 5
43: #define DLGALERT_CANCEL 6
44:
45: /* The "Alert"-dialog: */
46: static SGOBJ alertdlg[] =
47: {
48: { SGBOX, 0, 0, 0,0, 52,7, NULL },
49: { SGTEXT, 0, 0, 1,1, 50,1, dlglines[0] },
50: { SGTEXT, 0, 0, 1,2, 50,1, dlglines[1] },
51: { SGTEXT, 0, 0, 1,3, 50,1, dlglines[2] },
52: { SGTEXT, 0, 0, 1,4, 50,1, dlglines[3] },
1.1.1.4 ! root 53: { SGBUTTON, SG_DEFAULT, 0, 5,5, 8,1, "OK" },
! 54: { SGBUTTON, SG_CANCEL, 0, 24,5, 8,1, "Cancel" },
1.1 root 55: { -1, 0, 0, 0,0, 0,0, NULL }
56: };
57:
58:
59: /*-----------------------------------------------------------------------*/
60: /*
1.1.1.4 ! root 61: Breaks long string to several strings of max_width, divided by '\0',
! 62: sets text_width to the longest line width and returns the number of lines
! 63: you need to display the strings.
1.1 root 64: */
1.1.1.4 ! root 65: static int DlgAlert_FormatTextToBox(char *text, int max_width, int *text_width)
1.1 root 66: {
1.1.1.4 ! root 67: int columns = 0;
1.1 root 68: int lines = 1;
69: int txtlen;
1.1.1.4 ! root 70: char *p; /* pointer to begin of actual line */
! 71: char *q; /* pointer to start of next search */
! 72: char *llb; /* pointer to last place suitable for breaking the line */
! 73: char *txtend; /* pointer to end of the text */
1.1 root 74:
75: txtlen = strlen(text);
76:
77: q = p = text;
1.1.1.4 ! root 78: llb = text-1; /* pointer to last line break */
1.1 root 79: txtend = text + txtlen;
80:
1.1.1.4 ! root 81: if (txtlen <= max_width)
1.1 root 82: {
1.1.1.4 ! root 83: *text_width = txtlen;
! 84: return lines;
! 85: }
! 86:
! 87: while(q < txtend) /* q was last place suitable for breaking */
! 88: {
! 89: char *r = strpbrk(q, " \t/\\\n"); /* find next suitable place for the break */
! 90: if (r == NULL)
! 91: r = txtend; /* if there's no place then point to the end */
! 92:
! 93: if ((r-p) <= max_width && *r != '\n') /* '\n' is always used for breaking */
! 94: {
! 95: llb = r; /* remember new place suitable for breaking */
! 96: q++;
! 97: if ((r-p) > columns)
! 98: columns = r - p;
! 99: continue; /* search again */
! 100: }
! 101:
! 102: if ((r-p) > max_width) /* too long line already? */
1.1 root 103: {
1.1.1.4 ! root 104: if (p > llb) /* bad luck - no place for the delimiter. Let's do it the strong way */
! 105: llb = p + max_width; /* we loose one character */
1.1 root 106: }
1.1.1.4 ! root 107: else
! 108: llb = r; /* break from previous delimiter */
! 109:
! 110: *llb = '\0'; /* BREAK */
! 111: if ((llb-p) > columns)
! 112: columns = llb - p; /* longest line so far */
! 113: p = q = llb + 1; /* next line begins here */
! 114: lines++; /* increment line counter */
1.1 root 115: }
116:
1.1.1.4 ! root 117: *text_width = columns;
! 118:
! 119: return lines; /* return line counter */
1.1 root 120: }
121:
122:
123:
124: /*-----------------------------------------------------------------------*/
125: /*
126: Show the "alert" dialog. Return TRUE if user pressed "OK".
127: */
128: static int DlgAlert_ShowDlg(const char *text)
129: {
1.1.1.4 ! root 130: static int maxlen = sizeof(dlglines[0])-1;
1.1 root 131: char *t = (char *)malloc(strlen(text)+1);
132: char *orig_t = t;
1.1.1.4 ! root 133: int lines, i, len, offset;
1.1 root 134: BOOL bOldMouseVisibility;
1.1.1.4 ! root 135: int nOldMouseX, nOldMouseY;
1.1 root 136:
137: strcpy(t, text);
1.1.1.4 ! root 138: lines = DlgAlert_FormatTextToBox(t, maxlen, &len);
! 139: offset = (maxlen-len)/2;
1.1 root 140:
141: for(i=0; i<MAX_LINES; i++)
142: {
143: if (i < lines)
144: {
1.1.1.4 ! root 145: /* center text to current dlgline */
! 146: memset(dlglines[i], ' ', offset);
! 147: strcpy(dlglines[i] + offset, t);
1.1 root 148: t += strlen(t)+1;
149: }
150: else
151: {
152: dlglines[i][0] = '\0';
153: }
154: }
155:
156: free(orig_t);
157:
1.1.1.2 root 158: if (SDLGui_SetScreen(sdlscrn))
159: return FALSE;
1.1 root 160: SDLGui_CenterDlg(alertdlg);
161:
1.1.1.4 ! root 162: SDL_GetMouseState(&nOldMouseX, &nOldMouseY);
1.1 root 163: bOldMouseVisibility = SDL_ShowCursor(SDL_QUERY);
164: SDL_ShowCursor(SDL_ENABLE);
165:
1.1.1.2 root 166: i = SDLGui_DoDialog(alertdlg, NULL);
1.1 root 167:
1.1.1.4 ! root 168: SDL_UpdateRect(sdlscrn, 0,0, 0,0);
1.1 root 169: SDL_ShowCursor(bOldMouseVisibility);
1.1.1.4 ! root 170: Main_WarpMouse(nOldMouseX, nOldMouseY);
1.1 root 171:
172: return (i == DLGALERT_OK);
173: }
174:
175:
176: /*-----------------------------------------------------------------------*/
177: /*
178: Show a "notice" dialog: (only one button)
179: */
180: int DlgAlert_Notice(const char *text)
181: {
1.1.1.3 root 182: #ifdef ALERT_HOOKS
183: // If activated, used the hooked function instead
184: if (useAlertHooks)
185: {
186: return HookedAlertNotice(text);
187: }
188: #endif
189:
1.1 root 190: /* Hide "cancel" button: */
191: alertdlg[DLGALERT_CANCEL].type = SGTEXT;
192: alertdlg[DLGALERT_CANCEL].txt = "";
193: alertdlg[DLGALERT_CANCEL].w = alertdlg[DLGALERT_CANCEL].w = 0;
194:
195: /* Adjust button position: */
196: alertdlg[DLGALERT_OK].x = (alertdlg[0].w - alertdlg[DLGALERT_OK].w) / 2;
197:
198: return DlgAlert_ShowDlg(text);
199: }
200:
201:
202: /*-----------------------------------------------------------------------*/
203: /*
1.1.1.4 ! root 204: Show a "query" dialog: (two buttons), return true for OK
1.1 root 205: */
206: int DlgAlert_Query(const char *text)
207: {
1.1.1.3 root 208: #ifdef ALERT_HOOKS
209: // If activated, used the hooked function instead
210: if (useAlertHooks)
211: {
212: return HookedAlertQuery(text);
213: }
214: #endif
215:
1.1 root 216: /* Show "cancel" button: */
217: alertdlg[DLGALERT_CANCEL].type = SGBUTTON;
218: alertdlg[DLGALERT_CANCEL].txt = "Cancel";
219: alertdlg[DLGALERT_CANCEL].w = 8;
220: alertdlg[DLGALERT_CANCEL].h = 1;
221:
222: /* Adjust buttons positions: */
223: alertdlg[DLGALERT_OK].x = (alertdlg[0].w - alertdlg[DLGALERT_OK].w - alertdlg[DLGALERT_CANCEL].w) / 3;
224: alertdlg[DLGALERT_CANCEL].x = alertdlg[DLGALERT_OK].x * 2 + alertdlg[DLGALERT_OK].w;
225:
226: return DlgAlert_ShowDlg(text);
227: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.