1 | /********************************************************************** <BR>
|
---|
2 | This file is part of Crack dot Com's free source code release of
|
---|
3 | Golgotha. <a href="http://www.crack.com/golgotha_release"> <BR> for
|
---|
4 | information about compiling & licensing issues visit this URL</a>
|
---|
5 | <PRE> If that doesn't help, contact Jonathan Clark at
|
---|
6 | golgotha_source@usa.net (Subject should have "GOLG" in it)
|
---|
7 | ***********************************************************************/
|
---|
8 |
|
---|
9 | #include "window/window.hh"
|
---|
10 | #include "device/event.hh"
|
---|
11 | #include "gui/text.hh"
|
---|
12 | #include "gui/text_input.hh"
|
---|
13 | #include "window/colorwin.hh"
|
---|
14 | #include "error/alert.hh"
|
---|
15 | #include "gui/button.hh"
|
---|
16 | #include "gui/butbox.hh"
|
---|
17 | #include "gui/deco_win.hh"
|
---|
18 |
|
---|
19 | char *tokens[]={"=", "(", ")",
|
---|
20 | "[", "]", "right", "down", "up_deco", "down_deco", "'", "text_input", "text",
|
---|
21 | "button", "butbox", "obj_ev", "user_ev", "x+", "y+", 0};
|
---|
22 |
|
---|
23 | enum {
|
---|
24 | TK_EQUAL, TK_LPAREN, TK_RPAREN,
|
---|
25 | TK_LBRACE, TK_RBRACE, TK_RIGHT, TK_DOWN, TK_UP_DECO, TK_DOWN_DECO, TK_TICK,
|
---|
26 | TK_TEXT_INPUT, TK_TEXT,
|
---|
27 | TK_BUTTON, TK_BUTBOX, TK_OBJ_EV, TK_USER_EV,
|
---|
28 | TK_XPLUS, TK_YPLUS, TK_NUMBER, TK_POINTER, TK_NONE };
|
---|
29 |
|
---|
30 |
|
---|
31 |
|
---|
32 | void i4_expected(char *why, i4_const_str::iterator i, const i4_const_str &s)
|
---|
33 | {
|
---|
34 | i4_str *er=new i4_str(i4gets("expected"),2000);
|
---|
35 | i4_str::iterator x=er->end();
|
---|
36 |
|
---|
37 | while (i!=s.end())
|
---|
38 | {
|
---|
39 | x.set(i.get());
|
---|
40 | ++i;
|
---|
41 | ++x;
|
---|
42 | er->set_length(er->length()+1);
|
---|
43 | }
|
---|
44 |
|
---|
45 | i4_warning(why);
|
---|
46 | i4_alert(*er, 2000);
|
---|
47 | i4_error("expected error : see error output");
|
---|
48 | }
|
---|
49 |
|
---|
50 | int i4_is_space(i4_const_str::iterator i)
|
---|
51 | {
|
---|
52 | if (i.get().value()==' ' ||
|
---|
53 | i.get().value()=='\t' ||
|
---|
54 | i.get().value()=='\n' ||
|
---|
55 | i.get().value()=='\r')
|
---|
56 | return 1;
|
---|
57 | else return 0;
|
---|
58 | }
|
---|
59 |
|
---|
60 | int i4_cmp_char_str(i4_const_str::iterator i, const i4_const_str &s, char *c)
|
---|
61 | {
|
---|
62 | while (*c && i!=s.end())
|
---|
63 | {
|
---|
64 | if (i.get().value()!=*c)
|
---|
65 | return 0;
|
---|
66 |
|
---|
67 | c++;
|
---|
68 | ++i;
|
---|
69 | }
|
---|
70 |
|
---|
71 | if (*c)
|
---|
72 | return 0;
|
---|
73 | else return 1;
|
---|
74 |
|
---|
75 | }
|
---|
76 |
|
---|
77 |
|
---|
78 | int i4_read_dlg_token(i4_const_str::iterator &i,
|
---|
79 | const i4_const_str &fmt,
|
---|
80 | sw32 &num,
|
---|
81 | void *&ptr,
|
---|
82 | va_list &ap)
|
---|
83 | {
|
---|
84 | while (i!=fmt.end() && i4_is_space(i))
|
---|
85 | ++i;
|
---|
86 |
|
---|
87 | if (i==fmt.end()) return TK_NONE;
|
---|
88 |
|
---|
89 | if (i.get().value()=='%')
|
---|
90 | {
|
---|
91 | ++i;
|
---|
92 | if (i.get().value()=='d')
|
---|
93 | {
|
---|
94 | ++i;
|
---|
95 | num=va_arg(ap,int);
|
---|
96 | return TK_NUMBER;
|
---|
97 | }
|
---|
98 | else if (i.get().value()=='p')
|
---|
99 | {
|
---|
100 | ++i;
|
---|
101 | ptr=va_arg(ap,void *);
|
---|
102 | return TK_POINTER;
|
---|
103 | }
|
---|
104 | else i4_error("expecting p or d after %");
|
---|
105 | }
|
---|
106 | else
|
---|
107 | {
|
---|
108 | if ((i.get().value()>='0' && i.get().value()<='9') || i.get().value()=='-')
|
---|
109 | {
|
---|
110 | int neg=0;
|
---|
111 | if (i.get().value()=='-')
|
---|
112 | {
|
---|
113 | neg=1;
|
---|
114 | ++i;
|
---|
115 | }
|
---|
116 |
|
---|
117 | num=0;
|
---|
118 | while (i!=fmt.end() && !i4_is_space(i) && i.get().value()>='0' && i.get().value()<='9')
|
---|
119 | {
|
---|
120 | num=num*10+i.get().value()-'0';
|
---|
121 | ++i;
|
---|
122 | }
|
---|
123 |
|
---|
124 | if (neg) num=-num;
|
---|
125 | return TK_NUMBER;
|
---|
126 | }
|
---|
127 |
|
---|
128 | for (int j=0; tokens[j]; j++)
|
---|
129 | if (i4_cmp_char_str(i, fmt, tokens[j]))
|
---|
130 | {
|
---|
131 | int l=strlen(tokens[j]);
|
---|
132 | while (l)
|
---|
133 | {
|
---|
134 | ++i;
|
---|
135 | l--;
|
---|
136 | }
|
---|
137 |
|
---|
138 | return j;
|
---|
139 | }
|
---|
140 |
|
---|
141 | i4_expected("unknown token", i, fmt);
|
---|
142 |
|
---|
143 | }
|
---|
144 | return TK_NONE;
|
---|
145 | }
|
---|
146 |
|
---|
147 |
|
---|
148 | int i4_next_token_is_rbrace(i4_const_str::iterator i,
|
---|
149 | const i4_const_str &fmt)
|
---|
150 | {
|
---|
151 | while (i!=fmt.end() && i4_is_space(i))
|
---|
152 | ++i;
|
---|
153 |
|
---|
154 | if (i==fmt.end()) return 1;
|
---|
155 |
|
---|
156 | if (i.get().value()==']') return 1;
|
---|
157 | else return 0;
|
---|
158 | }
|
---|
159 |
|
---|
160 |
|
---|
161 | i4_str *i4_read_str(i4_const_str::iterator &i, const i4_const_str &fmt, va_list &ap)
|
---|
162 | {
|
---|
163 | sw32 n; void *p;
|
---|
164 |
|
---|
165 | if (i4_read_dlg_token(i, fmt, n, p, ap)!=TK_TICK)
|
---|
166 | i4_expected("'",i,fmt);
|
---|
167 |
|
---|
168 | i4_str *s=new i4_str(i4_string_man.get(0), 200);
|
---|
169 | i4_str::iterator x=s->begin();
|
---|
170 | while (i!=fmt.end() && i.get().value()!='\'')
|
---|
171 | {
|
---|
172 | x.set(i.get().value());
|
---|
173 | ++i;
|
---|
174 | ++x;
|
---|
175 | s->set_length(s->length()+1);
|
---|
176 | }
|
---|
177 | ++i;
|
---|
178 |
|
---|
179 | i4_str *ret=s->vsprintf(200, ap);
|
---|
180 |
|
---|
181 | delete s;
|
---|
182 | return ret;
|
---|
183 | }
|
---|
184 |
|
---|
185 | i4_event_reaction_class *i4_read_reaction(i4_const_str::iterator &i,
|
---|
186 | const i4_const_str &fmt,
|
---|
187 | va_list &ap)
|
---|
188 | {
|
---|
189 | sw32 x,id; void *p, *from, *to;
|
---|
190 | int t=i4_read_dlg_token(i, fmt, x, p, ap);
|
---|
191 |
|
---|
192 | if (t==TK_OBJ_EV)
|
---|
193 | {
|
---|
194 | if (i4_read_dlg_token(i, fmt, x, p, ap)!=TK_LPAREN)
|
---|
195 | i4_expected("(",i,fmt);
|
---|
196 |
|
---|
197 | if (i4_read_dlg_token(i, fmt, x, from, ap)!=TK_POINTER)
|
---|
198 | i4_expected("pointer",i,fmt);
|
---|
199 |
|
---|
200 | if (i4_read_dlg_token(i, fmt, x, to, ap)!=TK_POINTER)
|
---|
201 | i4_expected("pointer",i,fmt);
|
---|
202 |
|
---|
203 | if (i4_read_dlg_token(i, fmt, id, p, ap)!=TK_NUMBER)
|
---|
204 | i4_expected("number",i,fmt);
|
---|
205 |
|
---|
206 | if (i4_read_dlg_token(i, fmt, x, p, ap)!=TK_RPAREN)
|
---|
207 | i4_expected(")",i,fmt);
|
---|
208 |
|
---|
209 | i4_object_message_event_class *om;
|
---|
210 | om=new i4_object_message_event_class((i4_event_handler_class *)from, id);
|
---|
211 | return new i4_event_reaction_class((i4_event_handler_class *)to, om);
|
---|
212 | }
|
---|
213 | else if (t==TK_USER_EV)
|
---|
214 | {
|
---|
215 | if (i4_read_dlg_token(i, fmt, x, p, ap)!=TK_LPAREN)
|
---|
216 | i4_expected("(",i,fmt);
|
---|
217 |
|
---|
218 | if (i4_read_dlg_token(i, fmt, x, to, ap)!=TK_POINTER)
|
---|
219 | i4_expected("pointer",i,fmt);
|
---|
220 |
|
---|
221 | if (i4_read_dlg_token(i, fmt, id, p, ap)!=TK_NUMBER)
|
---|
222 | i4_expected("number",i,fmt);
|
---|
223 |
|
---|
224 | if (i4_read_dlg_token(i, fmt, x, p, ap)!=TK_RPAREN)
|
---|
225 | i4_expected(")",i,fmt);
|
---|
226 |
|
---|
227 | i4_user_message_event_class *uev;
|
---|
228 | uev=new i4_user_message_event_class(id);
|
---|
229 |
|
---|
230 | return new i4_event_reaction_class((i4_event_handler_class *)to, uev);
|
---|
231 | }
|
---|
232 | else
|
---|
233 | {
|
---|
234 | i4_expected("obj_ev or user_ev",i,fmt);
|
---|
235 | return 0;
|
---|
236 | }
|
---|
237 | }
|
---|
238 |
|
---|
239 | i4_window_class *i4_read_object(i4_parent_window_class *parent,
|
---|
240 | i4_graphical_style_class *style,
|
---|
241 | sw32 &cx, sw32 &cy,
|
---|
242 | i4_const_str::iterator &i, const i4_const_str &fmt,
|
---|
243 | va_list &ap,
|
---|
244 | int in_buttonbox)
|
---|
245 | {
|
---|
246 | sw32 x;
|
---|
247 | void *p;
|
---|
248 | i4_const_str::iterator start_i=i;
|
---|
249 | i4_window_class *ret=0;
|
---|
250 |
|
---|
251 |
|
---|
252 | int token=i4_read_dlg_token(i, fmt, x, p, ap);
|
---|
253 | switch (token)
|
---|
254 | {
|
---|
255 | case TK_POINTER :
|
---|
256 | {
|
---|
257 | token=i4_read_dlg_token(i, fmt, x, p, ap);
|
---|
258 | if (token!=TK_EQUAL)
|
---|
259 | i4_expected("expected = after %p", start_i, fmt);
|
---|
260 |
|
---|
261 | i4_window_class *r=i4_read_object(parent, style, cx, cy, i, fmt, ap, in_buttonbox);
|
---|
262 | *((i4_window_class **)p)=r;
|
---|
263 | ret=r;
|
---|
264 | } break;
|
---|
265 |
|
---|
266 | case TK_LBRACE :
|
---|
267 | {
|
---|
268 | int dir=i4_read_dlg_token(i, fmt, x, p, ap);
|
---|
269 | if (dir!=TK_RIGHT && dir!=TK_DOWN)
|
---|
270 | i4_expected("right or down after [", start_i, fmt);
|
---|
271 |
|
---|
272 | sw32 ncx=cx, ncy=cy;
|
---|
273 | int max_w=0, max_h=0;
|
---|
274 | i4_window_class *r;
|
---|
275 | while (!i4_next_token_is_rbrace(i, fmt))
|
---|
276 | {
|
---|
277 | r=i4_read_object(parent, style, ncx, ncy, i, fmt, ap, in_buttonbox);
|
---|
278 | if (r)
|
---|
279 | {
|
---|
280 | if (!ret) ret=r;
|
---|
281 | if (dir==TK_RIGHT)
|
---|
282 | ncx+=r->width();
|
---|
283 | else ncy+=r->height();
|
---|
284 | }
|
---|
285 | }
|
---|
286 | i4_read_dlg_token(i, fmt, x, p, ap);
|
---|
287 |
|
---|
288 | } break;
|
---|
289 |
|
---|
290 | case TK_RIGHT :
|
---|
291 | case TK_DOWN :
|
---|
292 | case TK_NUMBER :
|
---|
293 | case TK_RBRACE :
|
---|
294 | i4_expected("out of place token",start_i,fmt);
|
---|
295 | break;
|
---|
296 |
|
---|
297 | case TK_XPLUS :
|
---|
298 | {
|
---|
299 | if (i4_read_dlg_token( i, fmt, x, p, ap)!=TK_LPAREN)
|
---|
300 | i4_expected("(",start_i,fmt);
|
---|
301 |
|
---|
302 | if (i4_read_dlg_token( i, fmt, x, p, ap)!=TK_NUMBER)
|
---|
303 | i4_expected("number",start_i,fmt);
|
---|
304 |
|
---|
305 | if (i4_read_dlg_token( i, fmt, x, p, ap)!=TK_RPAREN)
|
---|
306 | i4_expected(")",start_i,fmt);
|
---|
307 |
|
---|
308 | cx+=x;
|
---|
309 | } break;
|
---|
310 |
|
---|
311 | case TK_YPLUS :
|
---|
312 | {
|
---|
313 | if (i4_read_dlg_token( i, fmt, x, p, ap)!=TK_LPAREN)
|
---|
314 | i4_expected("(",start_i,fmt);
|
---|
315 |
|
---|
316 | if (i4_read_dlg_token( i, fmt, x, p, ap)!=TK_NUMBER)
|
---|
317 | i4_expected("number",start_i,fmt);
|
---|
318 | cy+=x;
|
---|
319 |
|
---|
320 | if (i4_read_dlg_token( i, fmt, x, p, ap)!=TK_RPAREN)
|
---|
321 | i4_expected(")",start_i,fmt);
|
---|
322 |
|
---|
323 | } break;
|
---|
324 |
|
---|
325 | case TK_UP_DECO :
|
---|
326 | {
|
---|
327 | sw32 w,h;
|
---|
328 | if (i4_read_dlg_token( i, fmt, x, p, ap)!=TK_LPAREN)
|
---|
329 | i4_expected("(",start_i,fmt);
|
---|
330 |
|
---|
331 | if (i4_read_dlg_token( i, fmt, w, p, ap)!=TK_NUMBER)
|
---|
332 | i4_expected("number",start_i,fmt);
|
---|
333 |
|
---|
334 | if (i4_read_dlg_token( i, fmt, h, p, ap)!=TK_NUMBER)
|
---|
335 | i4_expected("number",start_i,fmt);
|
---|
336 |
|
---|
337 | i4_deco_window_class *cw=new i4_deco_window_class(w,h, i4_T, style);
|
---|
338 |
|
---|
339 | sw32 ncx=0, ncy=0;
|
---|
340 | i4_window_class *r=i4_read_object(cw, style, ncx, ncy, i, fmt, ap, 0);
|
---|
341 |
|
---|
342 | parent->add_child(cx,cy, cw);
|
---|
343 |
|
---|
344 | if (i4_read_dlg_token( i, fmt, x, p, ap)!=TK_RPAREN)
|
---|
345 | i4_expected(")",start_i,fmt);
|
---|
346 |
|
---|
347 | ret=cw;
|
---|
348 | } break;
|
---|
349 |
|
---|
350 | case TK_TEXT :
|
---|
351 | {
|
---|
352 | if (i4_read_dlg_token( i, fmt, x, p, ap)!=TK_LPAREN)
|
---|
353 | i4_expected("(",start_i,fmt);
|
---|
354 |
|
---|
355 | i4_str *s=i4_read_str(i, fmt, ap);
|
---|
356 | if (s)
|
---|
357 | {
|
---|
358 | i4_text_window_class *tw=new i4_text_window_class(*s, style);
|
---|
359 | delete s;
|
---|
360 | parent->add_child(cx, cy, tw);
|
---|
361 | ret=tw;
|
---|
362 | }
|
---|
363 |
|
---|
364 | if (i4_read_dlg_token( i, fmt, x, p, ap)!=TK_RPAREN)
|
---|
365 | i4_expected(")",start_i,fmt);
|
---|
366 |
|
---|
367 | } break;
|
---|
368 |
|
---|
369 | case TK_TEXT_INPUT :
|
---|
370 | {
|
---|
371 | sw32 w;
|
---|
372 | if (i4_read_dlg_token( i, fmt, x, p, ap)!=TK_LPAREN)
|
---|
373 | i4_expected("(",start_i,fmt);
|
---|
374 |
|
---|
375 | if (i4_read_dlg_token( i, fmt, w, p, ap)!=TK_NUMBER)
|
---|
376 | i4_expected("number",start_i,fmt);
|
---|
377 |
|
---|
378 | i4_str *s=i4_read_str(i, fmt, ap);
|
---|
379 | if (s)
|
---|
380 | {
|
---|
381 | i4_text_input_class *ti=new i4_text_input_class(style, *s, w, 256);
|
---|
382 | delete s;
|
---|
383 | parent->add_child(cx, cy, ti);
|
---|
384 | ret=ti;
|
---|
385 | }
|
---|
386 |
|
---|
387 | if (i4_read_dlg_token( i, fmt, x, p, ap)!=TK_RPAREN)
|
---|
388 | i4_expected(")",start_i,fmt);
|
---|
389 | } break;
|
---|
390 |
|
---|
391 |
|
---|
392 | case TK_BUTTON :
|
---|
393 | {
|
---|
394 | if (i4_read_dlg_token( i, fmt, x, p, ap)!=TK_LPAREN)
|
---|
395 | i4_expected("(",start_i,fmt);
|
---|
396 |
|
---|
397 | i4_color_window_class tmp_win(0,0,0,style);
|
---|
398 | i4_window_class *r=i4_read_object(&tmp_win, style, cx, cy, i, fmt, ap, in_buttonbox);
|
---|
399 | i4_event_reaction_class *re=i4_read_reaction(i, fmt, ap);
|
---|
400 |
|
---|
401 | if (r)
|
---|
402 | {
|
---|
403 | tmp_win.remove_child(r);
|
---|
404 |
|
---|
405 | i4_button_class *b=new i4_button_class(0, r, style, re);
|
---|
406 |
|
---|
407 | if (in_buttonbox)
|
---|
408 | ((i4_button_box_class *)parent)->add_button(cx, cy, b);
|
---|
409 | else
|
---|
410 | {
|
---|
411 | b->set_popup(i4_T);
|
---|
412 | parent->add_child(cx,cy, b);
|
---|
413 | }
|
---|
414 | ret=b;
|
---|
415 | }
|
---|
416 |
|
---|
417 | if (i4_read_dlg_token( i, fmt, x, p, ap)!=TK_RPAREN)
|
---|
418 | i4_expected(")",start_i,fmt);
|
---|
419 |
|
---|
420 |
|
---|
421 | } break;
|
---|
422 |
|
---|
423 |
|
---|
424 | case TK_BUTBOX :
|
---|
425 | {
|
---|
426 | sw32 def_down;
|
---|
427 |
|
---|
428 | if (i4_read_dlg_token( i, fmt, x, p, ap)!=TK_LPAREN)
|
---|
429 | i4_expected("(",start_i,fmt);
|
---|
430 |
|
---|
431 | if (i4_read_dlg_token( i, fmt, def_down, p, ap)!=TK_NUMBER)
|
---|
432 | i4_expected("number",start_i,fmt);
|
---|
433 |
|
---|
434 |
|
---|
435 | i4_button_box_class *bbox=new i4_button_box_class(0);
|
---|
436 |
|
---|
437 | sw32 ncx=0,ncy=0;
|
---|
438 | i4_window_class *r=i4_read_object(bbox, style, ncx, ncy, i, fmt, ap, 1);
|
---|
439 | bbox->resize_to_fit_children();
|
---|
440 |
|
---|
441 | i4_button_class *b=(i4_button_class *)bbox->get_nth_window(def_down);
|
---|
442 | if (b)
|
---|
443 | bbox->push_button(b,0);
|
---|
444 |
|
---|
445 | parent->add_child(cx, cy, bbox);
|
---|
446 |
|
---|
447 | if (i4_read_dlg_token( i, fmt, x, p, ap)!=TK_RPAREN)
|
---|
448 | i4_expected(")",start_i,fmt);
|
---|
449 |
|
---|
450 | return bbox;
|
---|
451 | } break;
|
---|
452 |
|
---|
453 | }
|
---|
454 | return ret;
|
---|
455 | }
|
---|
456 |
|
---|
457 | void i4_create_dialog(const i4_const_str &fmt,
|
---|
458 | i4_parent_window_class *parent,
|
---|
459 | i4_graphical_style_class *style,
|
---|
460 | ...)
|
---|
461 | {
|
---|
462 | va_list ap;
|
---|
463 | va_start(ap, style);
|
---|
464 |
|
---|
465 |
|
---|
466 | i4_const_str::iterator i=fmt.begin();
|
---|
467 |
|
---|
468 | sw32 cx=0, cy=0;
|
---|
469 |
|
---|
470 | i4_read_object(parent, style, cx, cy, i, fmt, ap, 0);
|
---|
471 |
|
---|
472 | va_end(ap);
|
---|
473 |
|
---|
474 | }
|
---|
475 |
|
---|
476 |
|
---|
477 |
|
---|