PageRenderTime 133ms CodeModel.GetById 30ms app.highlight 95ms RepoModel.GetById 1ms app.codeStats 0ms

/TeXmacs-1.0.7.11-src/src/Plugins/Widkit/Basic/widkit_wrapper.cpp

#
C++ | 849 lines | 707 code | 101 blank | 41 comment | 68 complexity | 864a168e69467fc065225846ac6aead1 MD5 | raw file
Possible License(s): GPL-3.0, GPL-2.0, MPL-2.0-no-copyleft-exception
  1
  2/******************************************************************************
  3* MODULE     : widkit_wrapper.hpp
  4* DESCRIPTION: Conversions between widget and wk_widget
  5* COPYRIGHT  : (C) 2007  Joris van der Hoeven
  6*******************************************************************************
  7* This software falls under the GNU general public license version 3 or later.
  8* It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE
  9* in the root directory or <http://www.gnu.org/licenses/gpl-3.0.html>.
 10******************************************************************************/
 11
 12#include "promise.hpp"
 13#include "url.hpp"
 14#include "Widkit/wk_widget.hpp"
 15#include "message.hpp"
 16#include "window.hpp"
 17#include "dictionary.hpp"
 18
 19#define THIS wk_widget (this)
 20
 21static void noop () {}
 22widget box_widget (scheme_tree p, string s, color col, bool trans, bool ink);
 23
 24/******************************************************************************
 25* Type conversions
 26******************************************************************************/
 27
 28array<widget>
 29abstract (array<wk_widget> a) {
 30  int i, n= N(a);
 31  array<widget> b (n);
 32  for (i=0; i<n; i++) b[i]= abstract (a[i]);
 33  return b;
 34}
 35
 36array<wk_widget>
 37concrete (array<widget> a) {
 38  int i, n= N(a);
 39  array<wk_widget> b (n);
 40  for (i=0; i<n; i++) b[i]= concrete (a[i]);
 41  return b;
 42}
 43
 44class abstract_promise_rep: public promise_rep<widget> {
 45  promise<wk_widget> p;
 46public:
 47  abstract_promise_rep (promise<wk_widget> p2): p (p2) {}
 48  tm_ostream& print (tm_ostream& out) { return out << p; }
 49  widget eval () { return abstract (p ()); }
 50};
 51
 52promise<widget>
 53abstract (promise<wk_widget> pw) {
 54  return tm_new<abstract_promise_rep> (pw);
 55}
 56
 57class concrete_promise_rep: public promise_rep<wk_widget> {
 58  promise<widget> p;
 59public:
 60  concrete_promise_rep (promise<widget> p2): p (p2) {}
 61  tm_ostream& print (tm_ostream& out) { return out << p; }
 62  wk_widget eval () { return concrete (p ()); }
 63};
 64
 65promise<wk_widget>
 66concrete (promise<widget> pw) {
 67  return tm_new<concrete_promise_rep> (pw);
 68}
 69
 70/******************************************************************************
 71* Exported special widgets
 72******************************************************************************/
 73
 74widget
 75extend (widget w, array<widget> a) {
 76  return abstract (extend (concrete (w), concrete (a)));
 77}
 78
 79widget
 80horizontal_list (array<widget> a) {
 81  return abstract (horizontal_list (concrete (a)));
 82}
 83
 84widget
 85vertical_list (array<widget> a) {
 86  return abstract (vertical_list (concrete (a)));
 87}
 88
 89widget
 90horizontal_menu (array<widget> a) {
 91  return abstract (horizontal_list (concrete (a)));
 92  //return abstract (horizontal_array (concrete (a), -1));
 93}
 94
 95widget
 96vertical_menu (array<widget> a) {
 97  return abstract (vertical_menu (concrete (a)));
 98}
 99
100widget
101tile_menu (array<widget> a, int cols) {
102  return abstract (tile (concrete (a), cols));
103}
104
105widget
106minibar_widget (widget w) {
107  return abstract (minibar_widget (concrete (w)));
108}
109
110widget
111minibar_menu (array<widget> a) {
112  return minibar_widget (horizontal_menu (a));
113}
114
115widget
116switch_widget (array<widget> a, array<string> name, int init) {
117  return abstract (switch_widget (concrete (a), name, init));
118}
119
120widget
121optional_widget (widget w, bool on) {
122  return abstract (optional_widget (concrete (w), on));
123}
124
125widget
126empty_widget () {
127  return abstract (glue_wk_widget (false, false, 0, 0));
128}
129
130widget
131glue_widget (bool hx, bool vx, SI w, SI h) {
132  return abstract (glue_wk_widget (hx, vx, w, h));
133}
134
135widget
136glue_widget (tree col, bool hx, bool vx, SI w, SI h) {
137  return abstract (glue_wk_widget (col, hx, vx, w, h));
138}
139
140widget
141menu_separator (bool vert) {
142  return abstract (separator_wk_widget (2*PIXEL, 2*PIXEL, vert));
143}
144
145widget
146menu_text_widget (string s, int style, color col, bool tsp, bool tt) {
147  return abstract (menu_text_wk_widget (s, style, col, tsp, tt));
148}
149
150widget
151text_widget (string s, int style, color col, bool tsp) {
152  return menu_text_widget (s, style, col, tsp, false);
153}
154
155widget
156xpm_widget (url file_name) {
157  return abstract (xpm_wk_widget (file_name, true));
158}
159
160widget
161command_button (widget w, command cmd, int style) {
162  return abstract (command_button (concrete (w), cmd, style));
163}
164
165widget
166command_button (widget lw, widget cw, widget rw, command cmd, int style) {
167  return abstract (command_button (concrete (lw), concrete (cw),
168				   concrete (rw), cmd, style));
169}
170
171widget
172menu_group (string name, int style) {
173  widget lw= empty_widget ();
174  widget cw= text_widget (name, style, dark_grey, false);
175  widget rw= empty_widget ();
176  return command_button (lw, cw, rw, noop,
177			 WIDGET_STYLE_INERT | WIDGET_STYLE_CENTERED);
178}
179
180widget
181menu_button (widget w, command cmd, string pre, string ks, int style) {
182  bool ok= (style & WIDGET_STYLE_INERT) == 0;
183  if (pre == "" && ks == "")
184    return command_button (w, cmd, style);
185  else {
186    color  c = ok? black: dark_grey;
187    widget lw= empty_widget ();
188    widget rw= menu_text_widget (ks, 0, c, true, true);
189    if (pre != "") {
190      string s= "";
191      if (pre == "v") s= "<checked>";
192      if (pre == "o") s= "<circ>";
193      if (pre == "*") s= "<bullet>";
194      if (s != "") lw= box_widget (tree (TUPLE), s, c, true, false);
195    }
196    return command_button (lw, w, rw, cmd, style);
197  }
198}
199
200widget
201pulldown_button (widget w, promise<widget> pw) {
202  return abstract (pulldown_button (concrete (w), concrete (pw)));
203}
204
205widget
206pullright_button (widget w, promise<widget> pw) {
207  return abstract (pullright_button (concrete (w), concrete (pw)));
208}
209
210widget
211popup_widget (widget w) {
212  return abstract (popup_widget (concrete (w), center));
213}
214
215widget
216canvas_widget (widget w) {
217  return abstract (canvas_widget (concrete (w), north_west, true));
218}
219
220widget
221input_text_widget (command call_back, string type, array<string> def,
222		   int style, string width) {
223  return abstract (input_text_wk_widget (call_back, type, def, style, width));
224}
225
226widget
227inputs_list_widget (command call_back, array<string> prompts) {
228  return abstract (inputs_list_wk_widget (call_back, prompts));
229}
230
231widget
232file_chooser_widget (command cmd, string type, bool save) {
233  return abstract (file_chooser_wk_widget (cmd, type));
234}
235
236widget
237printer_widget (command cmd, url u) {
238  return menu_button (text_widget ("Cancel", 0, black), cmd, "", "", 0);
239}
240
241widget
242color_picker_widget (command cmd, bool bg, array<tree> proposals) {
243  return abstract (color_picker_wk_widget (cmd, bg, proposals));
244}
245
246widget
247balloon_widget (widget w, widget help) {
248  return abstract (balloon_widget (concrete (w), concrete (help)));
249}
250
251widget
252wait_widget (SI w, SI h, string message) {
253  return abstract (wait_wk_widget (w, h, message));
254}
255
256widget
257texmacs_widget (int mask, command quit) {
258  return abstract (texmacs_wk_widget (mask, quit));
259}
260
261widget
262plain_window_widget (widget wid, string s) {
263  return abstract (plain_window_widget (concrete (wid), s));
264}
265
266widget
267popup_window_widget (widget wid, string s) {
268  return abstract (popup_window_widget (concrete (wid), s));
269}
270
271void
272destroy_window_widget (widget w) {
273  destroy_window_widget (concrete (w));
274}
275
276/******************************************************************************
277* Type checking
278******************************************************************************/
279
280void
281check_type_void (blackbox bb, string s) {
282  if (!is_nil (bb)) {
283    cerr << "\nslot type= " << s << "\n";
284    FAILED ("type mismatch");
285  }
286}
287
288template<class T> void
289check_type (blackbox bb, string s) {
290  if (type_box (bb) != type_helper<T>::id) {
291    cerr << "\nslot type= " << s << "\n";
292    FAILED ("type mismatch");
293  }
294}
295
296template<class T1, class T2> inline void
297check_type (blackbox bb, string s) {
298  check_type<pair<T1,T2> > (bb, s);
299}
300
301/******************************************************************************
302* Widget geometry
303******************************************************************************/
304
305SI get_dx (gravity grav, SI w);
306SI get_dy (gravity grav, SI h);
307
308void
309principal_widget_check (wk_widget wid) {
310  // FIXME: Positions should really be computed relative to parent widgets.
311  // Currently, we only allow geometry access of the unique child of
312  // a window widget.
313  if (wid->win != NULL && wid != concrete (wid->win->get_widget ()) [0]) {
314    cerr << "Widget= " << wid << "\n";
315    FAILED ("invalid geometry access");
316  }
317}
318
319void
320set_geometry (wk_widget wid, SI x, SI y, SI w, SI h) {
321  if (wid->is_window_widget ()) {
322    wid->win->set_position (x, y);
323    wid->win->set_size (w, h);
324  }
325  else {
326    principal_widget_check (wid); // FIXME: we should use parent's coordinates
327    wid << emit_position (x, y, w, h, north_west);
328  }
329}
330
331void
332get_geometry (wk_widget wid, SI& x, SI& y, SI& w, SI& h) {
333  if (wid->is_window_widget ()) {
334    wid->win->get_position (x, y);
335    wid->win->get_size (w, h);
336  }
337  else {
338    principal_widget_check (wid); // FIXME: we should use parent's coordinates
339    x= wid->ox - get_dx (wid->grav, wid->w);
340    y= wid->oy - get_dy (wid->grav, wid->h);
341    w= wid->w;
342    h= wid->h;
343  }
344}
345
346/******************************************************************************
347* Sending messages
348******************************************************************************/
349
350void
351send_bool (wk_widget w, string key, blackbox val) {
352  ASSERT (type_box (val) == type_helper<bool>::id, "type mismatch");
353  w << set_string (key, open_box<bool> (val)? string ("on"): string ("off"));
354}
355
356void
357send_int (wk_widget w, string key, blackbox val) {
358  ASSERT (type_box (val) == type_helper<int>::id, "type mismatch");
359  w << set_integer (key, open_box<int> (val));
360}
361
362void
363send_string (wk_widget w, string key, blackbox val) {
364  ASSERT (type_box (val) == type_helper<string>::id, "type mismatch");
365  w << set_string (key, open_box<string> (val));
366}
367
368void
369send_coord2 (wk_widget w, string key, blackbox val) {
370  typedef pair<SI,SI> coord2;
371  ASSERT (type_box (val) == type_helper<coord2>::id, "type mismatch");
372  coord2 p= open_box<coord2> (val);
373  w << set_coord2 (key, p.x1, p.x2);
374}
375
376void
377send_coord4 (wk_widget w, string key, blackbox val) {
378  typedef quartet<SI,SI,SI,SI> coord4;
379  ASSERT (type_box (val) == type_helper<coord4>::id, "type mismatch");
380  coord4 p= open_box<coord4> (val);
381  w << set_coord4 (key, p.x1, p.x2, p.x3, p.x4);
382}
383
384void
385send_position (wk_widget w, blackbox val) {
386  typedef pair<SI,SI> coord2;
387  ASSERT (type_box (val) == type_helper<coord2>::id, "type mismatch");
388  coord2 p= open_box<coord2> (val);
389  if (w->is_window_widget ()) w->win->set_position (p.x1, p.x2);
390  else {
391    SI x, y, W, H;
392    get_geometry (w, x, y, W, H);
393    set_geometry (w, p.x1, p.x2, W, H);
394  }
395}
396
397void
398send_size (wk_widget w, blackbox val) {
399  typedef pair<SI,SI> coord2;
400  ASSERT (type_box (val) == type_helper<coord2>::id, "type mismatch");
401  coord2 p= open_box<coord2> (val);
402  if (w->is_window_widget ()) w->win->set_size (p.x1, p.x2);
403  else {
404    SI x, y, W, H;
405    get_geometry (w, x, y, W, H);
406    set_geometry (w, x, y, p.x1, p.x2);
407  }
408}
409
410void
411send_update (wk_widget w, blackbox val) {
412  ASSERT (is_nil (val), "type mismatch");
413  w << emit_update ();
414}
415
416void
417send_keyboard (wk_widget w, blackbox val) {
418  typedef pair<string,time_t> keypress;
419  ASSERT (type_box (val) == type_helper<keypress>::id, "type mismatch");
420  keypress k= open_box<keypress> (val);
421  w << emit_keypress (k.x1, k.x2);
422}
423
424void
425send_keyboard_focus (wk_widget w, blackbox val) {
426  ASSERT (type_box (val) == type_helper<bool>::id, "type mismatch");
427  w->win->set_keyboard_focus (abstract (w), open_box<bool> (val));
428}
429
430void
431send_mouse (wk_widget w, blackbox val) {
432  typedef quintuple<string,SI,SI,int,time_t> mouse;
433  ASSERT (type_box (val) == type_helper<mouse>::id, "type mismatch");
434  mouse m= open_box<mouse> (val);
435  // FIXME: we should assume the position in the local coordinates
436  w << emit_mouse (m.x1, m.x2, m.x3, m.x4, m.x5);
437}
438
439void
440send_mouse_grab (wk_widget w, blackbox val) {
441  ASSERT (type_box (val) == type_helper<bool>::id, "type mismatch");
442  w->win->set_mouse_grab (abstract (w), open_box<bool> (val));
443}
444
445void
446send_mouse_pointer (wk_widget w, blackbox val) {
447  typedef pair<string,string> change_pointer;
448  ASSERT (type_box (val) == type_helper<change_pointer>::id, "type mismatch");
449  change_pointer cp= open_box<change_pointer> (val);
450  w->win->set_mouse_pointer (abstract (w), cp.x1, cp.x2);
451}
452
453void
454send_invalidate (wk_widget w, blackbox val) {
455  typedef quartet<SI,SI,SI,SI> coord4;
456  ASSERT (type_box (val) == type_helper<coord4>::id, "type mismatch");
457  coord4 p= open_box<coord4> (val);
458  w << emit_invalidate (w->ox + p.x1, w->oy + p.x2,
459			w->ox + p.x3, w->oy + p.x4);
460}
461
462void
463send_invalidate_all (wk_widget w, blackbox val) {
464  ASSERT (is_nil (val), "type mismatch");
465  w << emit_invalidate_all ();
466}
467
468void
469send_repaint (wk_widget w, blackbox val) {
470  typedef quartet<SI,SI,SI,SI> repaint;
471  ASSERT (type_box (val) == type_helper<repaint>::id, "type mismatch");
472  repaint r= open_box<repaint> (val);
473  bool stop_flag= false;
474  // FIXME: we should assume local coordinates for repainting
475  w << emit_repaint (r.x1, r.x2, r.x3, r.x4, stop_flag);
476}
477
478void
479send_delayed_message (wk_widget w, blackbox val) {
480  typedef pair<string,time_t> delayed;
481  ASSERT (type_box (val) == type_helper<delayed>::id, "type mismatch");
482  delayed dm= open_box<delayed> (val);
483  w << emit_alarm (dm.x1, dm.x2);
484}
485
486void
487send_destroy (wk_widget w, blackbox val) {
488  ASSERT (is_nil (val), "type mismatch");
489  w << emit_destroy ();
490}
491
492void
493wk_widget_rep::send (slot s, blackbox val) {
494  switch (s) {
495  case SLOT_IDENTIFIER:
496    check_type<int> (val, "SLOT_IDENTIFIER");
497    THIS << emit_attach_window (get_window (open_box<int> (val)));
498    break;
499  case SLOT_VISIBILITY:
500    check_type<bool> (val, "SLOT_VISIBILITY");
501    win->set_visibility (open_box<bool> (val));
502    break;
503  case SLOT_FULL_SCREEN:
504    check_type<bool> (val, "SLOT_FULL_SCREEN");
505    win->set_full_screen (open_box<bool> (val));
506    break;
507  case SLOT_NAME:
508    send_string (THIS, "window name", val);
509    break;
510  case SLOT_SIZE:
511    send_size (THIS, val);
512    break;
513  case SLOT_POSITION:
514    send_position (THIS, val);
515    break;
516  case SLOT_UPDATE:
517    send_update (THIS, val);
518    break;
519  case SLOT_KEYBOARD:
520    send_keyboard (THIS, val);
521    break;
522  case SLOT_KEYBOARD_FOCUS:
523    send_keyboard_focus (THIS, val);
524    break;
525  case SLOT_MOUSE:
526    send_mouse (THIS, val);
527    break;
528  case SLOT_MOUSE_GRAB:
529    send_mouse_grab (THIS, val);
530    break;
531  case SLOT_MOUSE_POINTER:
532    send_mouse_pointer (THIS, val);
533    break;
534  case SLOT_INVALIDATE:
535    send_invalidate (THIS, val);
536    break;
537  case SLOT_INVALIDATE_ALL:
538    send_invalidate_all (THIS, val);
539    break;
540  case SLOT_REPAINT:
541    send_repaint (THIS, val);
542    break;
543  case SLOT_DELAYED_MESSAGE:
544    send_delayed_message (THIS, val);
545    break;
546  case SLOT_DESTROY:
547    send_destroy (THIS, val);
548    break;
549  case SLOT_CURSOR:
550   // send_coord2 (THIS, "cursor", val); 
551    // this message is currently ignored. Used only in TeXmacs/Qt
552    break;
553      
554  case SLOT_SHRINKING_FACTOR:
555    send_int (THIS, "shrinking factor", val);
556    break;
557  case SLOT_EXTENTS:
558    send_coord4 (THIS, "extents", val);
559    break;
560  case SLOT_SCROLLBARS_VISIBILITY:
561    send_int (THIS, "scrollbars", val);
562    break;
563  case SLOT_SCROLL_POSITION:
564    send_coord2 (THIS, "scroll position", val);
565    break;
566
567  case SLOT_HEADER_VISIBILITY:
568    send_bool (THIS, "header", val);
569    break;
570  case SLOT_MAIN_ICONS_VISIBILITY:
571    send_bool (THIS, "main icons", val);
572    break;
573  case SLOT_MODE_ICONS_VISIBILITY:
574    send_bool (THIS, "mode icons", val);
575    break;
576  case SLOT_FOCUS_ICONS_VISIBILITY:
577    send_bool (THIS, "focus icons", val);
578    break;
579  case SLOT_USER_ICONS_VISIBILITY:
580    send_bool (THIS, "user icons", val);
581    break;
582  case SLOT_FOOTER_VISIBILITY:
583    send_bool (THIS, "footer flag", val);
584    break;
585  case SLOT_LEFT_FOOTER:
586    send_string (THIS, "left footer", val);
587    break;
588  case SLOT_RIGHT_FOOTER:
589    send_string (THIS, "right footer", val);
590    break;
591  case SLOT_INTERACTIVE_MODE:
592    send_bool (THIS, "interactive mode", val);
593    break;
594
595  case SLOT_STRING_INPUT:
596    send_string (THIS, "input", val);
597    break;
598  case SLOT_INPUT_TYPE:
599    send_string (THIS, "type", val);
600    break;
601  case SLOT_INPUT_PROPOSAL:
602    send_string (THIS, "default", val);
603    break;
604  case SLOT_FILE:
605    send_string (THIS, "file", val);
606    break;
607  case SLOT_DIRECTORY:
608    send_string (THIS, "directory", val);
609    break;
610  default:
611    FAILED ("cannot handle slot type");
612  }
613}
614
615/******************************************************************************
616* Querying
617******************************************************************************/
618
619blackbox
620query_bool (wk_widget w, string key, int type_id) {
621  ASSERT (type_id == type_helper<bool>::id, "type mismatch");
622  string s;
623  w << get_string (key, s);
624  return close_box<bool> (s == "on");
625}
626
627blackbox
628query_int (wk_widget w, string key, int type_id) {
629  ASSERT (type_id == type_helper<int>::id, "type mismatch");
630  int i;
631  w << get_integer (key, i);
632  return close_box<int> (i);
633}
634
635blackbox
636query_string (wk_widget w, string key, int type_id) {
637  ASSERT (type_id == type_helper<string>::id, "type mismatch");
638  string s;
639  w << get_string (key, s);
640  return close_box<string> (s);
641}
642
643blackbox
644query_coord2 (wk_widget w, string key, int type_id) {
645  typedef pair<SI,SI> coord2;
646  ASSERT (type_id == type_helper<coord2>::id, "type mismatch");
647  SI c1, c2;
648  w << get_coord2 (key, c1, c2);
649  return close_box<coord2> (coord2 (c1, c2));
650}
651
652blackbox
653query_coord4 (wk_widget w, string key, int type_id) {
654  typedef quartet<SI,SI,SI,SI> coord4;
655  ASSERT (type_id == type_helper<coord4>::id, "type mismatch");
656  SI c1, c2, c3, c4;
657  w << get_coord4 (key, c1, c2, c3, c4);
658  return close_box<coord4> (coord4 (c1, c2, c3, c4));
659}
660
661blackbox
662query_size (wk_widget w, int type_id) {
663  typedef pair<SI,SI> coord2;
664  ASSERT (type_id == type_helper<coord2>::id, "type mismatch");
665  SI x, y, W, H;
666  get_geometry (w, x, y, W, H);
667  return close_box<coord2> (coord2 (W, H));
668}
669
670blackbox
671query_position (wk_widget w, int type_id) {
672  typedef pair<SI,SI> coord2;
673  ASSERT (type_id == type_helper<coord2>::id, "type mismatch");
674  SI x, y, W, H;
675  get_geometry (w, x, y, W, H);
676  return close_box<coord2> (coord2 (x, y));
677}
678
679blackbox
680query_keyboard_focus (wk_widget w, int type_id) {
681  ASSERT (type_id == type_helper<bool>::id, "type mismatch");
682  return close_box<bool> (w->win->get_keyboard_focus (abstract (w)));
683}
684
685blackbox
686query_mouse_grab (wk_widget w, int type_id) {
687  ASSERT (type_id == type_helper<bool>::id, "type mismatch");
688  return close_box<bool> (w->win->get_mouse_grab (abstract (w)));
689}
690
691blackbox
692wk_widget_rep::query (slot s, int type_id) {
693  switch (s) {
694  case SLOT_IDENTIFIER:
695    ASSERT (type_id == type_helper<int>::id,
696	    "int expected (SLOT_IDENTIFIER)");
697    return close_box<int> (get_identifier (win));
698  case SLOT_RENDERER:
699    ASSERT (type_id == type_helper<renderer>::id,
700	    "renderer expected (SLOT_RENDERER)");
701    return close_box<renderer> (win->get_renderer ());
702  case SLOT_SIZE:
703    return query_size (THIS, type_id);
704  case SLOT_POSITION:
705    return query_position (THIS, type_id);
706  case SLOT_KEYBOARD_FOCUS:
707    return query_keyboard_focus (THIS, type_id);
708  case SLOT_MOUSE_GRAB:
709    return query_mouse_grab (THIS, type_id);
710
711  case SLOT_EXTENTS:
712    return query_coord4 (THIS, "extents", type_id);
713  case SLOT_VISIBLE_PART:
714    return query_coord4 (THIS, "visible", type_id);
715  case SLOT_SCROLLBARS_VISIBILITY:
716    return query_int (THIS, "scrollbars", type_id);
717  case SLOT_SCROLL_POSITION:
718    return query_coord2 (THIS, "scroll position", type_id);
719
720  case SLOT_HEADER_VISIBILITY:
721    return query_bool (THIS, "header", type_id);
722  case SLOT_MAIN_ICONS_VISIBILITY:
723    return query_bool (THIS, "main icons", type_id);
724  case SLOT_MODE_ICONS_VISIBILITY:
725    return query_bool (THIS, "mode icons", type_id);
726  case SLOT_FOCUS_ICONS_VISIBILITY:
727    return query_bool (THIS, "focus icons", type_id);
728  case SLOT_USER_ICONS_VISIBILITY:
729    return query_bool (THIS, "user icons", type_id);
730  case SLOT_FOOTER_VISIBILITY:
731    return query_bool (THIS, "footer flag", type_id);
732  case SLOT_INTERACTIVE_MODE:
733    return query_bool (THIS, "interactive mode", type_id);
734  case SLOT_INTERACTIVE_INPUT:
735    return query_string (THIS, "interactive input", type_id);
736
737  case SLOT_STRING_INPUT:
738    return query_string (THIS, "input", type_id);
739  default:
740    FAILED ("cannot handle slot type");
741    return blackbox ();
742  }
743}
744
745/******************************************************************************
746* Notification of state changes
747******************************************************************************/
748
749void
750notify_keyboard_focus (wk_widget w, blackbox val) {
751  ASSERT (type_box (val) == type_helper<bool>::id, "type mismatch");
752  w << emit_keyboard_focus (open_box<bool> (val));
753}
754
755void
756notify_mouse_grab (wk_widget w, blackbox val) {
757  ASSERT (type_box (val) == type_helper<bool>::id, "type mismatch");
758  w << emit_mouse_grab (open_box<bool> (val));
759}
760
761void
762wk_widget_rep::notify (slot s, blackbox new_val) {
763  switch (s) {
764  case SLOT_SIZE:
765    check_type<SI,SI> (new_val, "SLOT_SIZE");
766    THIS << emit_resize ();
767    if (is_window_widget ())
768      send_size (THIS [0], new_val);
769    break;
770  case SLOT_POSITION:
771    check_type<SI,SI> (new_val, "SLOT_POSITION");
772    THIS << emit_move ();
773    break;
774  case SLOT_KEYBOARD_FOCUS:
775    notify_keyboard_focus (THIS, new_val);
776    break;
777  case SLOT_MOUSE_GRAB:
778    notify_mouse_grab (THIS, new_val);
779    break;
780  default:
781    break;
782  }
783  widget_rep::notify (s, new_val);
784}
785
786/******************************************************************************
787* Read and write access of subwidgets
788******************************************************************************/
789
790widget
791wk_widget_rep::read (slot s, blackbox index) {
792  switch (s) {
793  case SLOT_WINDOW:
794    check_type_void (index, "SLOT_WINDOW");
795    return win -> get_widget ();
796  case SLOT_FORM_FIELD:
797    check_type<int> (index, "SLOT_FORM_FIELD");
798    return abstract (THIS [0] ["inputs"] [2*open_box<int> (index)] ["input"]);
799  case SLOT_FILE:
800    check_type_void (index, "SLOT_FILE");
801    return abstract (THIS [0] ["file"] ["input"]);
802  case SLOT_DIRECTORY:
803    check_type_void (index, "SLOT_DIRECTORY");
804    return abstract (THIS [0] ["directory"] ["input"]);
805  default:
806    FAILED ("cannot handle slot type");
807    return widget ();
808  }
809}
810
811void
812wk_widget_rep::write (slot s, blackbox index, widget w) {
813  switch (s) {
814  case SLOT_MAIN_MENU:
815    check_type_void (index, "SLOT_MAIN_MENU");
816    THIS << set_widget ("menu bar", concrete (w));
817    break;
818  case SLOT_MAIN_ICONS:
819    check_type_void (index, "SLOT_MAIN_ICONS");
820    THIS << set_widget ("main icons bar", concrete (w));
821    break;
822  case SLOT_MODE_ICONS:
823    check_type_void (index, "SLOT_MODE_ICONS");
824    THIS << set_widget ("mode icons bar", concrete (w));
825    break;
826  case SLOT_FOCUS_ICONS:
827    check_type_void (index, "SLOT_FOCUS_ICONS");
828    THIS << set_widget ("focus icons bar", concrete (w));
829    break;
830  case SLOT_USER_ICONS:
831    check_type_void (index, "SLOT_USER_ICONS");
832    THIS << set_widget ("user icons bar", concrete (w));
833    break;
834  case SLOT_CANVAS:
835    check_type_void (index, "SLOT_CANVAS");
836    THIS << set_widget ("scrollable", concrete (w));
837    break;
838  case SLOT_INTERACTIVE_PROMPT:
839    check_type_void (index, "SLOT_INTERACTIVE_PROMPT");
840    THIS << set_widget ("interactive prompt", concrete (w));
841    break;
842  case SLOT_INTERACTIVE_INPUT:
843    check_type_void (index, "SLOT_INTERACTIVE_INPUT");
844    THIS << set_widget ("interactive input", concrete (w));
845    break;
846  default:
847    FAILED ("cannot handle slot type");
848  }
849}