source: golgotha/src/i4/gui/create_dialog.cc @ 608

Last change on this file since 608 was 80, checked in by Sam Hocevar, 15 years ago
  • Adding the Golgotha source code. Not sure what's going to be interesting in there, but since it's all public domain, there's certainly stuff to pick up.
File size: 11.8 KB
Line 
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
19char *tokens[]={"=", "(", ")",
20                "[", "]", "right", "down", "up_deco", "down_deco", "'", "text_input", "text",
21                "button", "butbox", "obj_ev", "user_ev", "x+", "y+", 0};
22
23enum {
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
32void 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
50int 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
60int 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
78int 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
148int 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
161i4_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
185i4_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
239i4_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
457void 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
Note: See TracBrowser for help on using the repository browser.