1 /*
2 * dlgAlert.cpp - AES-like AlertBox
3 *
4 * Copyright (c) 2004-2007 Petr Stehlik of ARAnyM dev team (see AUTHORS)
5 *
6 * This file is part of the ARAnyM project which builds a new and powerful
7 * TOS/FreeMiNT compatible virtual machine running on almost any hardware.
8 *
9 * ARAnyM 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 * ARAnyM 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 for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with ARAnyM; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23
24 #include "sysdeps.h"
25 #include <string.h>
26 #include <stdlib.h>
27
28 #include "sdlgui.h"
29 #include "dlgAlert.h"
30
31 #define DLG_WIDTH 76
32 #define MAX_LINES 20
33
34 /* The "Alert"-dialog: */
35 SGOBJ alertdlg[1/*BACKGROUND*/ + MAX_LINES/*text*/ + 1/*OK*/ + 1/*Cancel*/ + 1/*NULL*/] =
36 {
37 { SGBOX, SG_BACKGROUND, 0, 0,0, DLG_WIDTH,25, NULL, 0 },
38 { -1, 0, 0, 0,0, 0,0, NULL, 0 }
39 };
40
41 SGOBJ obj_text = { SGTEXT, 0, 0, 1,1, DLG_WIDTH-2,1, NULL, 0 };
42 SGOBJ obj_but_ok = { SGBUTTON, SG_SELECTABLE|SG_EXIT|SG_DEFAULT, 0, (DLG_WIDTH-8-8)/3,5, 8,1, "OK", 0 };
43 SGOBJ obj_but_cancel = { SGBUTTON, SG_SELECTABLE|SG_EXIT, 0, (DLG_WIDTH-8-8)*2/3+8,5, 8,1, "Cancel", 0 };
44 SGOBJ obj_null = { -1, 0, 0, 0,0, 0,0, NULL, 0 };
45
46 /*
47 Breaks long string to several strings of max_width, divided by '\0'
48 and returns the number of lines you need to display the strings.
49 */
FormatTextToBox(char * text,int max_width)50 int FormatTextToBox(char *text, int max_width)
51 {
52 int lines=1;
53 int delka = strlen(text);
54 char *p; /* pointer to begin of actual line */
55 char *q; /* pointer to start of next search */
56 char *rozdel = text-1; /* pointer to last place suitable for breaking the line */
57 char *konec; /* pointer to end of the text */
58 q = p = text;
59 konec = text + delka;
60
61 while(q < konec) { /* q was last place suitable for breaking */
62 char *r = strpbrk(q, " \t/\\\n"); /* find next suitable place for the break */
63 if (r == NULL)
64 r = konec; /* if there's no place then point to the end */
65
66 if ((r-p) < max_width && *r != '\n') { /* '\n' is always used for breaking */
67 rozdel = r; /* remember new place suitable for breaking */
68 q++;
69 continue; /* search again */
70 }
71
72 if ((r-p) > max_width) { /* too long line already? */
73 if (p > rozdel) /* bad luck - no place for the delimiter. Let's do it the strong way */
74 rozdel = p + max_width; /* we loose one character */
75 }
76 else
77 rozdel = r; /* break in this place */
78
79 *rozdel = '\0'; /* BREAK */
80 p = q = rozdel+1; /* next line begins here */
81 lines++; /* increment line counter */
82 }
83 return lines; /* return line counter */
84 }
85
86
87
88 /*-----------------------------------------------------------------------*/
89 /*
90 Show the "alert" dialog:
91 */
92
DlgAlert(SGOBJ * dlg,const char * _text,alert_type _type)93 DlgAlert::DlgAlert(SGOBJ *dlg, const char *_text, alert_type _type)
94 : Dialog(dlg), text(_text), type(_type), orig_t(NULL), ok_but_idx(-1)
95 {
96 char *t = (char *)malloc(strlen(text)+1);
97 orig_t = t;
98 strcpy(t, text);
99 int max_linelen = 0;
100 // break long text into '\0' terminated array of strings
101 int lines = FormatTextToBox(t, obj_text.w);
102 if (lines > MAX_LINES)
103 lines = MAX_LINES;
104 // build the dialog, find the longest line
105 int idx = 1;
106 for(int i=0; i<lines; i++) {
107 obj_text.y = i+1;
108 obj_text.txt = t;
109 alertdlg[idx++] = obj_text;
110 int str_len = strlen(t);
111 if (str_len > max_linelen)
112 max_linelen = str_len;
113 t += str_len + 1;
114 }
115
116 // compute smallest possible dialog width
117 int dlg_width = obj_but_ok.w + 2;
118 if (type == ALERT_OKCANCEL) {
119 dlg_width += obj_but_cancel.w + 2;
120 }
121 if (max_linelen+2 > dlg_width)
122 dlg_width = max_linelen+2;
123
124 // update dialog width
125 alertdlg[0].w = dlg_width;
126 for(int i=0; i<lines; i++) {
127 alertdlg[1+i].w = max_linelen;
128 }
129
130 // update OK/Cancel buttons placement
131 obj_but_ok.y = lines+2;
132 obj_but_cancel.y = lines+2;
133 if (type == ALERT_OKCANCEL) {
134 int butwidth = obj_but_ok.w + obj_but_cancel.w;
135 int space = alertdlg[0].w - butwidth;
136 obj_but_ok.x = space / 3;
137 obj_but_cancel.x = space * 2/3 + obj_but_ok.w;
138 }
139 else {
140 obj_but_ok.x = (alertdlg[0].w - obj_but_ok.w) / 2;
141 }
142
143 // add OK/Cancel buttons to dialog
144 ok_but_idx = idx;
145 alertdlg[idx++] = obj_but_ok;
146 if (type == ALERT_OKCANCEL) {
147 alertdlg[idx++] = obj_but_cancel;
148 }
149 alertdlg[idx] = obj_null;
150 alertdlg[0].h = lines+4;
151 }
152
~DlgAlert()153 DlgAlert::~DlgAlert()
154 {
155 if (orig_t) {
156 free(orig_t);
157 orig_t = NULL;
158 }
159 }
160
pressedOk(void)161 bool DlgAlert::pressedOk(void)
162 {
163 return (return_obj == ok_but_idx);
164 }
165
processResult(void)166 void DlgAlert::processResult(void)
167 {
168 }
169
DlgAlertOpen(const char * text,alert_type type)170 Dialog *DlgAlertOpen(const char *text, alert_type type)
171 {
172 return new DlgAlert(alertdlg, text, type);
173 }
174