create_dialog.cc 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478
  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. #include "window/window.hh"
  9. #include "device/event.hh"
  10. #include "gui/text.hh"
  11. #include "gui/text_input.hh"
  12. #include "window/colorwin.hh"
  13. #include "error/alert.hh"
  14. #include "gui/button.hh"
  15. #include "gui/butbox.hh"
  16. #include "gui/deco_win.hh"
  17. char *tokens[]={"=", "(", ")",
  18. "[", "]", "right", "down", "up_deco", "down_deco", "'", "text_input", "text",
  19. "button", "butbox", "obj_ev", "user_ev", "x+", "y+", 0};
  20. enum {
  21. TK_EQUAL, TK_LPAREN, TK_RPAREN,
  22. TK_LBRACE, TK_RBRACE, TK_RIGHT, TK_DOWN, TK_UP_DECO, TK_DOWN_DECO, TK_TICK,
  23. TK_TEXT_INPUT, TK_TEXT,
  24. TK_BUTTON, TK_BUTBOX, TK_OBJ_EV, TK_USER_EV,
  25. TK_XPLUS, TK_YPLUS, TK_NUMBER, TK_POINTER, TK_NONE };
  26. void i4_expected(char *why, i4_const_str::iterator i, const i4_const_str &s)
  27. {
  28. i4_str *er=new i4_str(i4gets("expected"),2000);
  29. i4_str::iterator x=er->end();
  30. while (i!=s.end())
  31. {
  32. x.set(i.get());
  33. ++i;
  34. ++x;
  35. er->set_length(er->length()+1);
  36. }
  37. i4_warning(why);
  38. i4_alert(*er, 2000);
  39. i4_error("expected error : see error output");
  40. }
  41. int i4_is_space(i4_const_str::iterator i)
  42. {
  43. if (i.get().value()==' ' ||
  44. i.get().value()=='\t' ||
  45. i.get().value()=='\n' ||
  46. i.get().value()=='\r')
  47. return 1;
  48. else return 0;
  49. }
  50. int i4_cmp_char_str(i4_const_str::iterator i, const i4_const_str &s, char *c)
  51. {
  52. while (*c && i!=s.end())
  53. {
  54. if (i.get().value()!=*c)
  55. return 0;
  56. c++;
  57. ++i;
  58. }
  59. if (*c)
  60. return 0;
  61. else return 1;
  62. }
  63. int i4_read_dlg_token(i4_const_str::iterator &i,
  64. const i4_const_str &fmt,
  65. sw32 &num,
  66. void *&ptr,
  67. va_list &ap)
  68. {
  69. while (i!=fmt.end() && i4_is_space(i))
  70. ++i;
  71. if (i==fmt.end()) return TK_NONE;
  72. if (i.get().value()=='%')
  73. {
  74. ++i;
  75. if (i.get().value()=='d')
  76. {
  77. ++i;
  78. num=va_arg(ap,int);
  79. return TK_NUMBER;
  80. }
  81. else if (i.get().value()=='p')
  82. {
  83. ++i;
  84. ptr=va_arg(ap,void *);
  85. return TK_POINTER;
  86. }
  87. else i4_error("expecting p or d after %");
  88. }
  89. else
  90. {
  91. if ((i.get().value()>='0' && i.get().value()<='9') || i.get().value()=='-')
  92. {
  93. int neg=0;
  94. if (i.get().value()=='-')
  95. {
  96. neg=1;
  97. ++i;
  98. }
  99. num=0;
  100. while (i!=fmt.end() && !i4_is_space(i) && i.get().value()>='0' && i.get().value()<='9')
  101. {
  102. num=num*10+i.get().value()-'0';
  103. ++i;
  104. }
  105. if (neg) num=-num;
  106. return TK_NUMBER;
  107. }
  108. for (int j=0; tokens[j]; j++)
  109. if (i4_cmp_char_str(i, fmt, tokens[j]))
  110. {
  111. int l=strlen(tokens[j]);
  112. while (l)
  113. {
  114. ++i;
  115. l--;
  116. }
  117. return j;
  118. }
  119. i4_expected("unknown token", i, fmt);
  120. }
  121. return TK_NONE;
  122. }
  123. int i4_next_token_is_rbrace(i4_const_str::iterator i,
  124. const i4_const_str &fmt)
  125. {
  126. while (i!=fmt.end() && i4_is_space(i))
  127. ++i;
  128. if (i==fmt.end()) return 1;
  129. if (i.get().value()==']') return 1;
  130. else return 0;
  131. }
  132. i4_str *i4_read_str(i4_const_str::iterator &i, const i4_const_str &fmt, va_list &ap)
  133. {
  134. sw32 n; void *p;
  135. if (i4_read_dlg_token(i, fmt, n, p, ap)!=TK_TICK)
  136. i4_expected("'",i,fmt);
  137. i4_str *s=new i4_str(i4_string_man.get(0), 200);
  138. i4_str::iterator x=s->begin();
  139. while (i!=fmt.end() && i.get().value()!='\'')
  140. {
  141. x.set(i.get().value());
  142. ++i;
  143. ++x;
  144. s->set_length(s->length()+1);
  145. }
  146. ++i;
  147. i4_str *ret=s->vsprintf(200, ap);
  148. delete s;
  149. return ret;
  150. }
  151. i4_event_reaction_class *i4_read_reaction(i4_const_str::iterator &i,
  152. const i4_const_str &fmt,
  153. va_list &ap)
  154. {
  155. sw32 x,id; void *p, *from, *to;
  156. int t=i4_read_dlg_token(i, fmt, x, p, ap);
  157. if (t==TK_OBJ_EV)
  158. {
  159. if (i4_read_dlg_token(i, fmt, x, p, ap)!=TK_LPAREN)
  160. i4_expected("(",i,fmt);
  161. if (i4_read_dlg_token(i, fmt, x, from, ap)!=TK_POINTER)
  162. i4_expected("pointer",i,fmt);
  163. if (i4_read_dlg_token(i, fmt, x, to, ap)!=TK_POINTER)
  164. i4_expected("pointer",i,fmt);
  165. if (i4_read_dlg_token(i, fmt, id, p, ap)!=TK_NUMBER)
  166. i4_expected("number",i,fmt);
  167. if (i4_read_dlg_token(i, fmt, x, p, ap)!=TK_RPAREN)
  168. i4_expected(")",i,fmt);
  169. i4_object_message_event_class *om;
  170. om=new i4_object_message_event_class((i4_event_handler_class *)from, id);
  171. return new i4_event_reaction_class((i4_event_handler_class *)to, om);
  172. }
  173. else if (t==TK_USER_EV)
  174. {
  175. if (i4_read_dlg_token(i, fmt, x, p, ap)!=TK_LPAREN)
  176. i4_expected("(",i,fmt);
  177. if (i4_read_dlg_token(i, fmt, x, to, ap)!=TK_POINTER)
  178. i4_expected("pointer",i,fmt);
  179. if (i4_read_dlg_token(i, fmt, id, p, ap)!=TK_NUMBER)
  180. i4_expected("number",i,fmt);
  181. if (i4_read_dlg_token(i, fmt, x, p, ap)!=TK_RPAREN)
  182. i4_expected(")",i,fmt);
  183. i4_user_message_event_class *uev;
  184. uev=new i4_user_message_event_class(id);
  185. return new i4_event_reaction_class((i4_event_handler_class *)to, uev);
  186. }
  187. else
  188. {
  189. i4_expected("obj_ev or user_ev",i,fmt);
  190. return 0;
  191. }
  192. }
  193. i4_window_class *i4_read_object(i4_parent_window_class *parent,
  194. i4_graphical_style_class *style,
  195. sw32 &cx, sw32 &cy,
  196. i4_const_str::iterator &i, const i4_const_str &fmt,
  197. va_list &ap,
  198. int in_buttonbox)
  199. {
  200. sw32 x;
  201. void *p;
  202. i4_const_str::iterator start_i=i;
  203. i4_window_class *ret=0;
  204. int token=i4_read_dlg_token(i, fmt, x, p, ap);
  205. switch (token)
  206. {
  207. case TK_POINTER :
  208. {
  209. token=i4_read_dlg_token(i, fmt, x, p, ap);
  210. if (token!=TK_EQUAL)
  211. i4_expected("expected = after %p", start_i, fmt);
  212. i4_window_class *r=i4_read_object(parent, style, cx, cy, i, fmt, ap, in_buttonbox);
  213. *((i4_window_class **)p)=r;
  214. ret=r;
  215. } break;
  216. case TK_LBRACE :
  217. {
  218. int dir=i4_read_dlg_token(i, fmt, x, p, ap);
  219. if (dir!=TK_RIGHT && dir!=TK_DOWN)
  220. i4_expected("right or down after [", start_i, fmt);
  221. sw32 ncx=cx, ncy=cy;
  222. int max_w=0, max_h=0;
  223. i4_window_class *r;
  224. while (!i4_next_token_is_rbrace(i, fmt))
  225. {
  226. r=i4_read_object(parent, style, ncx, ncy, i, fmt, ap, in_buttonbox);
  227. if (r)
  228. {
  229. if (!ret) ret=r;
  230. if (dir==TK_RIGHT)
  231. ncx+=r->width();
  232. else ncy+=r->height();
  233. }
  234. }
  235. i4_read_dlg_token(i, fmt, x, p, ap);
  236. } break;
  237. case TK_RIGHT :
  238. case TK_DOWN :
  239. case TK_NUMBER :
  240. case TK_RBRACE :
  241. i4_expected("out of place token",start_i,fmt);
  242. break;
  243. case TK_XPLUS :
  244. {
  245. if (i4_read_dlg_token( i, fmt, x, p, ap)!=TK_LPAREN)
  246. i4_expected("(",start_i,fmt);
  247. if (i4_read_dlg_token( i, fmt, x, p, ap)!=TK_NUMBER)
  248. i4_expected("number",start_i,fmt);
  249. if (i4_read_dlg_token( i, fmt, x, p, ap)!=TK_RPAREN)
  250. i4_expected(")",start_i,fmt);
  251. cx+=x;
  252. } break;
  253. case TK_YPLUS :
  254. {
  255. if (i4_read_dlg_token( i, fmt, x, p, ap)!=TK_LPAREN)
  256. i4_expected("(",start_i,fmt);
  257. if (i4_read_dlg_token( i, fmt, x, p, ap)!=TK_NUMBER)
  258. i4_expected("number",start_i,fmt);
  259. cy+=x;
  260. if (i4_read_dlg_token( i, fmt, x, p, ap)!=TK_RPAREN)
  261. i4_expected(")",start_i,fmt);
  262. } break;
  263. case TK_UP_DECO :
  264. {
  265. sw32 w,h;
  266. if (i4_read_dlg_token( i, fmt, x, p, ap)!=TK_LPAREN)
  267. i4_expected("(",start_i,fmt);
  268. if (i4_read_dlg_token( i, fmt, w, p, ap)!=TK_NUMBER)
  269. i4_expected("number",start_i,fmt);
  270. if (i4_read_dlg_token( i, fmt, h, p, ap)!=TK_NUMBER)
  271. i4_expected("number",start_i,fmt);
  272. i4_deco_window_class *cw=new i4_deco_window_class(w,h, i4_T, style);
  273. sw32 ncx=0, ncy=0;
  274. i4_window_class *r=i4_read_object(cw, style, ncx, ncy, i, fmt, ap, 0);
  275. parent->add_child(cx,cy, cw);
  276. if (i4_read_dlg_token( i, fmt, x, p, ap)!=TK_RPAREN)
  277. i4_expected(")",start_i,fmt);
  278. ret=cw;
  279. } break;
  280. case TK_TEXT :
  281. {
  282. if (i4_read_dlg_token( i, fmt, x, p, ap)!=TK_LPAREN)
  283. i4_expected("(",start_i,fmt);
  284. i4_str *s=i4_read_str(i, fmt, ap);
  285. if (s)
  286. {
  287. i4_text_window_class *tw=new i4_text_window_class(*s, style);
  288. delete s;
  289. parent->add_child(cx, cy, tw);
  290. ret=tw;
  291. }
  292. if (i4_read_dlg_token( i, fmt, x, p, ap)!=TK_RPAREN)
  293. i4_expected(")",start_i,fmt);
  294. } break;
  295. case TK_TEXT_INPUT :
  296. {
  297. sw32 w;
  298. if (i4_read_dlg_token( i, fmt, x, p, ap)!=TK_LPAREN)
  299. i4_expected("(",start_i,fmt);
  300. if (i4_read_dlg_token( i, fmt, w, p, ap)!=TK_NUMBER)
  301. i4_expected("number",start_i,fmt);
  302. i4_str *s=i4_read_str(i, fmt, ap);
  303. if (s)
  304. {
  305. i4_text_input_class *ti=new i4_text_input_class(style, *s, w, 256);
  306. delete s;
  307. parent->add_child(cx, cy, ti);
  308. ret=ti;
  309. }
  310. if (i4_read_dlg_token( i, fmt, x, p, ap)!=TK_RPAREN)
  311. i4_expected(")",start_i,fmt);
  312. } break;
  313. case TK_BUTTON :
  314. {
  315. if (i4_read_dlg_token( i, fmt, x, p, ap)!=TK_LPAREN)
  316. i4_expected("(",start_i,fmt);
  317. i4_color_window_class tmp_win(0,0,0,style);
  318. i4_window_class *r=i4_read_object(&tmp_win, style, cx, cy, i, fmt, ap, in_buttonbox);
  319. i4_event_reaction_class *re=i4_read_reaction(i, fmt, ap);
  320. if (r)
  321. {
  322. tmp_win.remove_child(r);
  323. i4_button_class *b=new i4_button_class(0, r, style, re);
  324. if (in_buttonbox)
  325. ((i4_button_box_class *)parent)->add_button(cx, cy, b);
  326. else
  327. {
  328. b->set_popup(i4_T);
  329. parent->add_child(cx,cy, b);
  330. }
  331. ret=b;
  332. }
  333. if (i4_read_dlg_token( i, fmt, x, p, ap)!=TK_RPAREN)
  334. i4_expected(")",start_i,fmt);
  335. } break;
  336. case TK_BUTBOX :
  337. {
  338. sw32 def_down;
  339. if (i4_read_dlg_token( i, fmt, x, p, ap)!=TK_LPAREN)
  340. i4_expected("(",start_i,fmt);
  341. if (i4_read_dlg_token( i, fmt, def_down, p, ap)!=TK_NUMBER)
  342. i4_expected("number",start_i,fmt);
  343. i4_button_box_class *bbox=new i4_button_box_class(0);
  344. sw32 ncx=0,ncy=0;
  345. i4_window_class *r=i4_read_object(bbox, style, ncx, ncy, i, fmt, ap, 1);
  346. bbox->resize_to_fit_children();
  347. i4_button_class *b=(i4_button_class *)bbox->get_nth_window(def_down);
  348. if (b)
  349. bbox->push_button(b,0);
  350. parent->add_child(cx, cy, bbox);
  351. if (i4_read_dlg_token( i, fmt, x, p, ap)!=TK_RPAREN)
  352. i4_expected(")",start_i,fmt);
  353. return bbox;
  354. } break;
  355. }
  356. return ret;
  357. }
  358. void i4_create_dialog(const i4_const_str &fmt,
  359. i4_parent_window_class *parent,
  360. i4_graphical_style_class *style,
  361. ...)
  362. {
  363. va_list ap;
  364. va_start(ap, style);
  365. i4_const_str::iterator i=fmt.begin();
  366. sw32 cx=0, cy=0;
  367. i4_read_object(parent, style, cx, cy, i, fmt, ap, 0);
  368. va_end(ap);
  369. }