Back to index

texmacs  1.0.7.15
widkit_wrapper.cpp
Go to the documentation of this file.
00001 
00002 /******************************************************************************
00003 * MODULE     : widkit_wrapper.hpp
00004 * DESCRIPTION: Conversions between widget and wk_widget
00005 * COPYRIGHT  : (C) 2007  Joris van der Hoeven
00006 *******************************************************************************
00007 * This software falls under the GNU general public license version 3 or later.
00008 * It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE
00009 * in the root directory or <http://www.gnu.org/licenses/gpl-3.0.html>.
00010 ******************************************************************************/
00011 
00012 #include "promise.hpp"
00013 #include "url.hpp"
00014 #include "Widkit/wk_widget.hpp"
00015 #include "message.hpp"
00016 #include "window.hpp"
00017 #include "dictionary.hpp"
00018 
00019 #define THIS wk_widget (this)
00020 
00021 static void noop () {}
00022 widget box_widget (scheme_tree p, string s, color col, bool trans, bool ink);
00023 
00024 /******************************************************************************
00025 * Type conversions
00026 ******************************************************************************/
00027 
00028 array<widget>
00029 abstract (array<wk_widget> a) {
00030   int i, n= N(a);
00031   array<widget> b (n);
00032   for (i=0; i<n; i++) b[i]= abstract (a[i]);
00033   return b;
00034 }
00035 
00036 array<wk_widget>
00037 concrete (array<widget> a) {
00038   int i, n= N(a);
00039   array<wk_widget> b (n);
00040   for (i=0; i<n; i++) b[i]= concrete (a[i]);
00041   return b;
00042 }
00043 
00044 class abstract_promise_rep: public promise_rep<widget> {
00045   promise<wk_widget> p;
00046 public:
00047   abstract_promise_rep (promise<wk_widget> p2): p (p2) {}
00048   tm_ostream& print (tm_ostream& out) { return out << p; }
00049   widget eval () { return abstract (p ()); }
00050 };
00051 
00052 promise<widget>
00053 abstract (promise<wk_widget> pw) {
00054   return tm_new<abstract_promise_rep> (pw);
00055 }
00056 
00057 class concrete_promise_rep: public promise_rep<wk_widget> {
00058   promise<widget> p;
00059 public:
00060   concrete_promise_rep (promise<widget> p2): p (p2) {}
00061   tm_ostream& print (tm_ostream& out) { return out << p; }
00062   wk_widget eval () { return concrete (p ()); }
00063 };
00064 
00065 promise<wk_widget>
00066 concrete (promise<widget> pw) {
00067   return tm_new<concrete_promise_rep> (pw);
00068 }
00069 
00070 /******************************************************************************
00071 * Exported special widgets
00072 ******************************************************************************/
00073 
00074 widget
00075 extend (widget w, array<widget> a) {
00076   return abstract (extend (concrete (w), concrete (a)));
00077 }
00078 
00079 widget
00080 horizontal_list (array<widget> a) {
00081   return abstract (horizontal_list (concrete (a)));
00082 }
00083 
00084 widget
00085 vertical_list (array<widget> a) {
00086   return abstract (vertical_list (concrete (a)));
00087 }
00088 
00089 widget
00090 aligned_widget (array<widget> lhs, array<widget> rhs,
00091                 SI hsep, SI vsep, SI lpad, SI rpad) {
00092   return abstract (aligned_widget (concrete (lhs), concrete (rhs),
00093                                    hsep, vsep, lpad, rpad));
00094 }
00095 
00096 widget
00097 tabs_widget (array<widget> tabs, array<widget> bodies) {
00098   return abstract (tabs_widget (concrete (tabs), concrete (bodies)));
00099 }
00100 
00101 widget
00102 horizontal_menu (array<widget> a) {
00103   return abstract (horizontal_list (concrete (a)));
00104   //return abstract (horizontal_array (concrete (a), -1));
00105 }
00106 
00107 widget
00108 vertical_menu (array<widget> a) {
00109   return abstract (vertical_menu (concrete (a)));
00110 }
00111 
00112 widget
00113 tile_menu (array<widget> a, int cols) {
00114   return abstract (tile (concrete (a), cols));
00115 }
00116 
00117 widget
00118 minibar_widget (widget w) {
00119   return abstract (minibar_widget (concrete (w)));
00120 }
00121 
00122 widget
00123 minibar_menu (array<widget> a) {
00124   return minibar_widget (horizontal_menu (a));
00125 }
00126 
00127 widget
00128 switch_widget (array<widget> a, array<string> name, int init) {
00129   return abstract (switch_widget (concrete (a), name, init));
00130 }
00131 
00132 widget
00133 optional_widget (widget w, bool on) {
00134   return abstract (optional_widget (concrete (w), on));
00135 }
00136 
00137 widget
00138 wrapped_widget (widget w, command cmd) {
00139   return abstract (wrapped_widget (concrete (w), cmd));
00140 }
00141 
00142 widget
00143 empty_widget () {
00144   return abstract (glue_wk_widget (false, false, 0, 0));
00145 }
00146 
00147 widget
00148 glue_widget (bool hx, bool vx, SI w, SI h) {
00149   return abstract (glue_wk_widget (hx, vx, w, h));
00150 }
00151 
00152 widget
00153 glue_widget (tree col, bool hx, bool vx, SI w, SI h) {
00154   return abstract (glue_wk_widget (col, hx, vx, w, h));
00155 }
00156 
00157 widget
00158 menu_separator (bool vert) {
00159   return abstract (separator_wk_widget (2*PIXEL, 2*PIXEL, vert));
00160 }
00161 
00162 widget
00163 menu_text_widget (string s, int style, color col, bool tsp, bool tt) {
00164   return abstract (menu_text_wk_widget (s, style, col, tsp, tt));
00165 }
00166 
00167 widget
00168 text_widget (string s, int style, color col, bool tsp) {
00169   return menu_text_widget (s, style, col, tsp, false);
00170 }
00171 
00172 widget
00173 xpm_widget (url file_name) {
00174   return abstract (xpm_wk_widget (file_name, true));
00175 }
00176 
00177 widget
00178 command_button (widget w, command cmd, int style) {
00179   return abstract (command_button (concrete (w), cmd, style));
00180 }
00181 
00182 widget
00183 command_button (widget lw, widget cw, widget rw, command cmd, int style) {
00184   return abstract (command_button (concrete (lw), concrete (cw),
00185                                concrete (rw), cmd, style));
00186 }
00187 
00188 widget
00189 menu_group (string name, int style) {
00190   widget lw= empty_widget ();
00191   widget cw= text_widget (name, style, dark_grey, false);
00192   widget rw= empty_widget ();
00193   return command_button (lw, cw, rw, noop,
00194                       WIDGET_STYLE_INERT | WIDGET_STYLE_CENTERED);
00195 }
00196 
00197 widget
00198 menu_button (widget w, command cmd, string pre, string ks, int style) {
00199   bool ok= (style & WIDGET_STYLE_INERT) == 0;
00200   if (pre == "" && ks == "")
00201     return command_button (w, cmd, style);
00202   else {
00203     color  c = ok? black: dark_grey;
00204     widget lw= empty_widget ();
00205     widget rw= menu_text_widget (ks, 0, c, true, true);
00206     if (pre != "") {
00207       string s= "";
00208       if (pre == "v") s= "<checked>";
00209       if (pre == "o") s= "<circ>";
00210       if (pre == "*") s= "<bullet>";
00211       if (s != "") lw= box_widget (tree (TUPLE), s, c, true, false);
00212     }
00213     return command_button (lw, w, rw, cmd, style);
00214   }
00215 }
00216 
00217 widget
00218 pulldown_button (widget w, promise<widget> pw) {
00219   return abstract (pulldown_button (concrete (w), concrete (pw)));
00220 }
00221 
00222 widget
00223 pullright_button (widget w, promise<widget> pw) {
00224   return abstract (pullright_button (concrete (w), concrete (pw)));
00225 }
00226 
00227 widget
00228 toggle_widget (command cmd, bool on, int style) {
00229   return abstract (toggle_wk_widget (cmd, on, style));
00230 }
00231 
00232 widget
00233 popup_widget (widget w) {
00234   return abstract (popup_widget (concrete (w), center));
00235 }
00236 
00237 widget
00238 canvas_widget (widget w) {
00239   return abstract (canvas_widget (concrete (w), north_west, true));
00240 }
00241 
00242 widget
00243 user_canvas_widget (widget wid, int style) {
00244   return abstract (user_canvas_widget (concrete (wid), style));
00245 }
00246 
00247 widget
00248 resize_widget (widget w, int style, string w1, string h1,
00249                string w2, string h2, string w3, string h3) {
00250   return abstract (resize_widget (concrete (w), style, w1, h1, w2, h2, w3, h3));
00251 }
00252 
00253 widget
00254 hsplit_widget (widget l, widget r) {
00255   return abstract (hsplit_widget (concrete (l), concrete (r)));
00256 }
00257 
00258 widget
00259 vsplit_widget (widget t, widget b) {
00260   return abstract (vsplit_widget (concrete (t), concrete (b)));
00261 }
00262 
00263 widget
00264 input_text_widget (command call_back, string type, array<string> def,
00265                  int style, string width) {
00266   return abstract (input_text_wk_widget (call_back, type, def, style, width));
00267 }
00268 
00269 widget
00270 inputs_list_widget (command call_back, array<string> prompts) {
00271   return abstract (inputs_list_wk_widget (call_back, prompts));
00272 }
00273 
00274 widget
00275 enum_widget (command cb, array<string> vals, string v, int style, string w) {
00276   return abstract (enum_wk_widget (cb, vals, v, style, w));
00277 }
00278 
00279 widget
00280 choice_widget (command cb, array<string> vals, string v) {
00281   return abstract (choice_wk_widget (cb, vals, v));
00282 }
00283 
00284 widget
00285 choice_widget (command cb, array<string> vals, array<string> mc) {
00286   return abstract (choice_wk_widget (cb, vals, mc));
00287 }
00288 
00289 widget
00290 file_chooser_widget (command cmd, string type, bool save) {
00291   return abstract (file_chooser_wk_widget (cmd, type));
00292 }
00293 
00294 widget
00295 printer_widget (command cmd, url u) {
00296   return menu_button (text_widget ("Cancel", 0, black), cmd, "", "", 0);
00297 }
00298 
00299 widget
00300 color_picker_widget (command cmd, bool bg, array<tree> proposals) {
00301   return abstract (color_picker_wk_widget (cmd, bg, proposals));
00302 }
00303 
00304 widget
00305 balloon_widget (widget w, widget help) {
00306   return abstract (balloon_widget (concrete (w), concrete (help)));
00307 }
00308 
00309 widget
00310 wait_widget (SI w, SI h, string message) {
00311   return abstract (wait_wk_widget (w, h, message));
00312 }
00313 
00314 widget
00315 ink_widget (command cb) {
00316   return abstract (ink_wk_widget (cb));
00317 }
00318 
00319 widget
00320 refresh_widget (string tmwid) {
00321   return abstract (refresh_wk_widget (tmwid));
00322 }
00323 
00324 widget
00325 texmacs_widget (int mask, command quit) {
00326   return abstract (texmacs_wk_widget (mask, quit));
00327 }
00328 
00329 widget
00330 plain_window_widget (widget wid, string s, command quit) {
00331   return abstract (plain_window_widget (concrete (wid), s, quit));
00332 }
00333 
00334 widget
00335 popup_window_widget (widget wid, string s) {
00336   return abstract (popup_window_widget (concrete (wid), s));
00337 }
00338 
00339 void
00340 destroy_window_widget (widget w) {
00341   destroy_window_widget (concrete (w));
00342 }
00343 
00344 /******************************************************************************
00345 * Type checking
00346 ******************************************************************************/
00347 
00348 void
00349 check_type_void (blackbox bb, string s) {
00350   if (!is_nil (bb)) {
00351     cerr << "\nslot type= " << s << "\n";
00352     FAILED ("type mismatch");
00353   }
00354 }
00355 
00356 template<class T> void
00357 check_type (blackbox bb, string s) {
00358   if (type_box (bb) != type_helper<T>::id) {
00359     cerr << "\nslot type= " << s << "\n";
00360     FAILED ("type mismatch");
00361   }
00362 }
00363 
00364 template<class T1, class T2> inline void
00365 check_type (blackbox bb, string s) {
00366   check_type<pair<T1,T2> > (bb, s);
00367 }
00368 
00369 /******************************************************************************
00370 * Widget geometry
00371 ******************************************************************************/
00372 
00373 SI get_dx (gravity grav, SI w);
00374 SI get_dy (gravity grav, SI h);
00375 
00376 bool
00377 bad_parent (wk_widget wid) {
00378   return wid->win != NULL && wid != concrete (wid->win->get_widget ()) [0];
00379 }
00380 
00381 void
00382 principal_widget_check (wk_widget wid) {
00383   // FIXME: Positions should really be computed relative to parent widgets.
00384   // Currently, we only allow geometry access of the unique child of
00385   // a window widget.
00386   if (bad_parent (wid)) {
00387     cerr << "Widget= " << wid << "\n";
00388     FAILED ("invalid geometry access");
00389   }
00390 }
00391 
00392 void
00393 set_geometry (wk_widget wid, SI x, SI y, SI w, SI h) {
00394   if (wid->is_window_widget ()) {
00395     wid->win->set_position (x, y);
00396     wid->win->set_size (w, h);
00397   }
00398   else {
00399     //principal_widget_check (wid);// FIXME: we should use parent's coordinates
00400     if (bad_parent (wid)) {
00401       SI dx, dy;
00402       wid->win->get_position (dx, dy);
00403       x -= dx; y -= dy;
00404     }
00405     wid << emit_position (x, y, w, h, north_west);
00406   }
00407 }
00408 
00409 void
00410 get_geometry (wk_widget wid, SI& x, SI& y, SI& w, SI& h) {
00411   if (wid->is_window_widget ()) {
00412     wid->win->get_position (x, y);
00413     wid->win->get_size (w, h);
00414     //cout << "Size == " << (w>>8) << ", " << (h>>8) << "\n";
00415   }
00416   else {
00417     //principal_widget_check (wid);// FIXME: we should use parent's coordinates
00418     x= wid->ox - get_dx (wid->grav, wid->w);
00419     y= wid->oy - get_dy (wid->grav, wid->h);
00420     w= wid->w;
00421     h= wid->h;
00422 
00423     if (bad_parent (wid)) {
00424       SI dx, dy;
00425       wid->win->get_position (dx, dy);
00426       x += dx; y += dy;
00427     }
00428     //cout << "Size " << ((tree) wid) << " := " << (w>>8) << ", " << (h>>8) << "\n";
00429   }
00430 }
00431 
00432 /******************************************************************************
00433 * Sending messages
00434 ******************************************************************************/
00435 
00436 void
00437 send_bool (wk_widget w, string key, blackbox val) {
00438   ASSERT (type_box (val) == type_helper<bool>::id, "type mismatch");
00439   w << set_string (key, open_box<bool> (val)? string ("on"): string ("off"));
00440 }
00441 
00442 void
00443 send_int (wk_widget w, string key, blackbox val) {
00444   ASSERT (type_box (val) == type_helper<int>::id, "type mismatch");
00445   w << set_integer (key, open_box<int> (val));
00446 }
00447 
00448 void
00449 send_string (wk_widget w, string key, blackbox val) {
00450   ASSERT (type_box (val) == type_helper<string>::id, "type mismatch");
00451   w << set_string (key, open_box<string> (val));
00452 }
00453 
00454 void
00455 send_coord2 (wk_widget w, string key, blackbox val) {
00456   typedef pair<SI,SI> coord2;
00457   ASSERT (type_box (val) == type_helper<coord2>::id, "type mismatch");
00458   coord2 p= open_box<coord2> (val);
00459   w << set_coord2 (key, p.x1, p.x2);
00460 }
00461 
00462 void
00463 send_coord4 (wk_widget w, string key, blackbox val) {
00464   typedef quartet<SI,SI,SI,SI> coord4;
00465   ASSERT (type_box (val) == type_helper<coord4>::id, "type mismatch");
00466   coord4 p= open_box<coord4> (val);
00467   w << set_coord4 (key, p.x1, p.x2, p.x3, p.x4);
00468 }
00469 
00470 void
00471 send_position (wk_widget w, blackbox val) {
00472   typedef pair<SI,SI> coord2;
00473   ASSERT (type_box (val) == type_helper<coord2>::id, "type mismatch");
00474   coord2 p= open_box<coord2> (val);
00475   if (w->is_window_widget ()) w->win->set_position (p.x1, p.x2);
00476   else {
00477     SI x, y, W, H;
00478     get_geometry (w, x, y, W, H);
00479     set_geometry (w, p.x1, p.x2, W, H);
00480   }
00481 }
00482 
00483 void
00484 send_size (wk_widget w, blackbox val) {
00485   typedef pair<SI,SI> coord2;
00486   ASSERT (type_box (val) == type_helper<coord2>::id, "type mismatch");
00487   coord2 p= open_box<coord2> (val);
00488   if (w->is_window_widget ()) w->win->set_size (p.x1, p.x2);
00489   else {
00490     SI x, y, W, H;
00491     get_geometry (w, x, y, W, H);
00492     set_geometry (w, x, y, p.x1, p.x2);
00493   }
00494 }
00495 
00496 void
00497 send_update (wk_widget w, blackbox val) {
00498   ASSERT (is_nil (val), "type mismatch");
00499   w << emit_update ();
00500 }
00501 
00502 void
00503 send_refresh (wk_widget w, blackbox val) {
00504   ASSERT (is_nil (val), "type mismatch");
00505   w << emit_refresh ();
00506 }
00507 
00508 void
00509 send_keyboard (wk_widget w, blackbox val) {
00510   typedef pair<string,time_t> keypress;
00511   ASSERT (type_box (val) == type_helper<keypress>::id, "type mismatch");
00512   keypress k= open_box<keypress> (val);
00513   w << emit_keypress (k.x1, k.x2);
00514 }
00515 
00516 void
00517 send_keyboard_focus (wk_widget w, blackbox val) {
00518   ASSERT (type_box (val) == type_helper<bool>::id, "type mismatch");
00519   w->win->set_keyboard_focus (abstract (w), open_box<bool> (val));
00520 }
00521 
00522 void
00523 send_mouse (wk_widget w, blackbox val) {
00524   typedef quintuple<string,SI,SI,int,time_t> mouse;
00525   ASSERT (type_box (val) == type_helper<mouse>::id, "type mismatch");
00526   mouse m= open_box<mouse> (val);
00527   // FIXME: we should assume the position in the local coordinates
00528   w << emit_mouse (m.x1, m.x2, m.x3, m.x4, m.x5);
00529 }
00530 
00531 void
00532 send_mouse_grab (wk_widget w, blackbox val) {
00533   ASSERT (type_box (val) == type_helper<bool>::id, "type mismatch");
00534   w->win->set_mouse_grab (abstract (w), open_box<bool> (val));
00535 }
00536 
00537 void
00538 send_mouse_pointer (wk_widget w, blackbox val) {
00539   typedef pair<string,string> change_pointer;
00540   ASSERT (type_box (val) == type_helper<change_pointer>::id, "type mismatch");
00541   change_pointer cp= open_box<change_pointer> (val);
00542   w->win->set_mouse_pointer (abstract (w), cp.x1, cp.x2);
00543 }
00544 
00545 void
00546 send_invalidate (wk_widget w, blackbox val) {
00547   typedef quartet<SI,SI,SI,SI> coord4;
00548   ASSERT (type_box (val) == type_helper<coord4>::id, "type mismatch");
00549   coord4 p= open_box<coord4> (val);
00550   w << emit_invalidate (w->ox + p.x1, w->oy + p.x2,
00551                      w->ox + p.x3, w->oy + p.x4);
00552 }
00553 
00554 void
00555 send_invalidate_all (wk_widget w, blackbox val) {
00556   ASSERT (is_nil (val), "type mismatch");
00557   w << emit_invalidate_all ();
00558 }
00559 
00560 void
00561 send_repaint (wk_widget w, blackbox val) {
00562   typedef quartet<SI,SI,SI,SI> repaint;
00563   ASSERT (type_box (val) == type_helper<repaint>::id, "type mismatch");
00564   repaint r= open_box<repaint> (val);
00565   bool stop_flag= false;
00566   // FIXME: we should assume local coordinates for repainting
00567   w << emit_repaint (r.x1, r.x2, r.x3, r.x4, stop_flag);
00568 }
00569 
00570 void
00571 send_delayed_message (wk_widget w, blackbox val) {
00572   typedef pair<string,time_t> delayed;
00573   ASSERT (type_box (val) == type_helper<delayed>::id, "type mismatch");
00574   delayed dm= open_box<delayed> (val);
00575   w << emit_alarm (dm.x1, dm.x2);
00576 }
00577 
00578 void
00579 send_destroy (wk_widget w, blackbox val) {
00580   ASSERT (is_nil (val), "type mismatch");
00581   w << emit_destroy ();
00582 }
00583 
00584 void
00585 wk_widget_rep::send (slot s, blackbox val) {
00586   switch (s) {
00587   case SLOT_IDENTIFIER:
00588     check_type<int> (val, "SLOT_IDENTIFIER");
00589     THIS << emit_attach_window (get_window (open_box<int> (val)));
00590     break;
00591   case SLOT_VISIBILITY:
00592     check_type<bool> (val, "SLOT_VISIBILITY");
00593     win->set_visibility (open_box<bool> (val));
00594     break;
00595   case SLOT_FULL_SCREEN:
00596     check_type<bool> (val, "SLOT_FULL_SCREEN");
00597     win->set_full_screen (open_box<bool> (val));
00598     break;
00599   case SLOT_NAME:
00600     send_string (THIS, "window name", val);
00601     break;
00602   case SLOT_SIZE:
00603     send_size (THIS, val);
00604     break;
00605   case SLOT_POSITION:
00606     send_position (THIS, val);
00607     break;
00608   case SLOT_UPDATE:
00609     send_update (THIS, val);
00610     break;
00611   case SLOT_REFRESH:
00612     send_refresh (THIS, val);
00613     break;
00614   case SLOT_KEYBOARD:
00615     send_keyboard (THIS, val);
00616     break;
00617   case SLOT_KEYBOARD_FOCUS:
00618     send_keyboard_focus (THIS, val);
00619     break;
00620   case SLOT_MOUSE:
00621     send_mouse (THIS, val);
00622     break;
00623   case SLOT_MOUSE_GRAB:
00624     send_mouse_grab (THIS, val);
00625     break;
00626   case SLOT_MOUSE_POINTER:
00627     send_mouse_pointer (THIS, val);
00628     break;
00629   case SLOT_INVALIDATE:
00630     send_invalidate (THIS, val);
00631     break;
00632   case SLOT_INVALIDATE_ALL:
00633     send_invalidate_all (THIS, val);
00634     break;
00635   case SLOT_REPAINT:
00636     send_repaint (THIS, val);
00637     break;
00638   case SLOT_DELAYED_MESSAGE:
00639     send_delayed_message (THIS, val);
00640     break;
00641   case SLOT_DESTROY:
00642     send_destroy (THIS, val);
00643     break;
00644   case SLOT_CURSOR:
00645    // send_coord2 (THIS, "cursor", val); 
00646     // this message is currently ignored. Used only in TeXmacs/Qt
00647     break;
00648       
00649   case SLOT_SHRINKING_FACTOR:
00650     send_int (THIS, "shrinking factor", val);
00651     break;
00652   case SLOT_EXTENTS:
00653     send_coord4 (THIS, "extents", val);
00654     break;
00655   case SLOT_SCROLLBARS_VISIBILITY:
00656     send_int (THIS, "scrollbars", val);
00657     break;
00658   case SLOT_SCROLL_POSITION:
00659     send_coord2 (THIS, "scroll position", val);
00660     break;
00661 
00662   case SLOT_HEADER_VISIBILITY:
00663     send_bool (THIS, "header", val);
00664     break;
00665   case SLOT_MAIN_ICONS_VISIBILITY:
00666     send_bool (THIS, "main icons", val);
00667     break;
00668   case SLOT_MODE_ICONS_VISIBILITY:
00669     send_bool (THIS, "mode icons", val);
00670     break;
00671   case SLOT_FOCUS_ICONS_VISIBILITY:
00672     send_bool (THIS, "focus icons", val);
00673     break;
00674   case SLOT_USER_ICONS_VISIBILITY:
00675     send_bool (THIS, "user icons", val);
00676     break;
00677   case SLOT_SIDE_TOOLS_VISIBILITY:
00678     send_bool (THIS, "side tools", val);
00679     break;
00680   case SLOT_FOOTER_VISIBILITY:
00681     send_bool (THIS, "footer flag", val);
00682     break;
00683   case SLOT_LEFT_FOOTER:
00684     send_string (THIS, "left footer", val);
00685     break;
00686   case SLOT_RIGHT_FOOTER:
00687     send_string (THIS, "right footer", val);
00688     break;
00689   case SLOT_INTERACTIVE_MODE:
00690     send_bool (THIS, "interactive mode", val);
00691     break;
00692 
00693   case SLOT_STRING_INPUT:
00694     send_string (THIS, "input", val);
00695     break;
00696   case SLOT_INPUT_TYPE:
00697     send_string (THIS, "type", val);
00698     break;
00699   case SLOT_INPUT_PROPOSAL:
00700     send_string (THIS, "default", val);
00701     break;
00702   case SLOT_FILE:
00703     send_string (THIS, "file", val);
00704     break;
00705   case SLOT_DIRECTORY:
00706     send_string (THIS, "directory", val);
00707     break;
00708   default:
00709     FAILED ("cannot handle slot type");
00710   }
00711 }
00712 
00713 /******************************************************************************
00714 * Querying
00715 ******************************************************************************/
00716 
00717 blackbox
00718 query_bool (wk_widget w, string key, int type_id) {
00719   ASSERT (type_id == type_helper<bool>::id, "type mismatch");
00720   string s;
00721   w << get_string (key, s);
00722   return close_box<bool> (s == "on");
00723 }
00724 
00725 blackbox
00726 query_int (wk_widget w, string key, int type_id) {
00727   ASSERT (type_id == type_helper<int>::id, "type mismatch");
00728   int i;
00729   w << get_integer (key, i);
00730   return close_box<int> (i);
00731 }
00732 
00733 blackbox
00734 query_string (wk_widget w, string key, int type_id) {
00735   ASSERT (type_id == type_helper<string>::id, "type mismatch");
00736   string s;
00737   w << get_string (key, s);
00738   return close_box<string> (s);
00739 }
00740 
00741 blackbox
00742 query_coord2 (wk_widget w, string key, int type_id) {
00743   typedef pair<SI,SI> coord2;
00744   ASSERT (type_id == type_helper<coord2>::id, "type mismatch");
00745   SI c1, c2;
00746   w << get_coord2 (key, c1, c2);
00747   return close_box<coord2> (coord2 (c1, c2));
00748 }
00749 
00750 blackbox
00751 query_coord4 (wk_widget w, string key, int type_id) {
00752   typedef quartet<SI,SI,SI,SI> coord4;
00753   ASSERT (type_id == type_helper<coord4>::id, "type mismatch");
00754   SI c1, c2, c3, c4;
00755   w << get_coord4 (key, c1, c2, c3, c4);
00756   return close_box<coord4> (coord4 (c1, c2, c3, c4));
00757 }
00758 
00759 blackbox
00760 query_size (wk_widget w, int type_id) {
00761   typedef pair<SI,SI> coord2;
00762   ASSERT (type_id == type_helper<coord2>::id, "type mismatch");
00763   SI x, y, W, H;
00764   get_geometry (w, x, y, W, H);
00765   return close_box<coord2> (coord2 (W, H));
00766 }
00767 
00768 blackbox
00769 query_position (wk_widget w, int type_id) {
00770   typedef pair<SI,SI> coord2;
00771   ASSERT (type_id == type_helper<coord2>::id, "type mismatch");
00772   SI x, y, W, H;
00773   get_geometry (w, x, y, W, H);
00774   return close_box<coord2> (coord2 (x, y));
00775 }
00776 
00777 blackbox
00778 query_keyboard_focus (wk_widget w, int type_id) {
00779   ASSERT (type_id == type_helper<bool>::id, "type mismatch");
00780   if (w->win == NULL) return close_box<bool> (false);
00781   return close_box<bool> (w->win->get_keyboard_focus (abstract (w)));
00782 }
00783 
00784 blackbox
00785 query_mouse_grab (wk_widget w, int type_id) {
00786   ASSERT (type_id == type_helper<bool>::id, "type mismatch");
00787   if (w->win == NULL) return close_box<bool> (false);
00788   return close_box<bool> (w->win->get_mouse_grab (abstract (w)));
00789 }
00790 
00791 blackbox
00792 wk_widget_rep::query (slot s, int type_id) {
00793   switch (s) {
00794   case SLOT_IDENTIFIER:
00795     ASSERT (type_id == type_helper<int>::id,
00796            "int expected (SLOT_IDENTIFIER)");
00797     return close_box<int> (get_identifier (win));
00798   case SLOT_RENDERER:
00799     ASSERT (type_id == type_helper<renderer>::id,
00800            "renderer expected (SLOT_RENDERER)");
00801     return close_box<renderer> (win->get_renderer ());
00802   case SLOT_SIZE:
00803     return query_size (THIS, type_id);
00804   case SLOT_POSITION:
00805     return query_position (THIS, type_id);
00806   case SLOT_KEYBOARD_FOCUS:
00807     return query_keyboard_focus (THIS, type_id);
00808   case SLOT_MOUSE_GRAB:
00809     return query_mouse_grab (THIS, type_id);
00810 
00811   case SLOT_EXTENTS:
00812     return query_coord4 (THIS, "extents", type_id);
00813   case SLOT_VISIBLE_PART:
00814     return query_coord4 (THIS, "visible", type_id);
00815   case SLOT_SCROLLBARS_VISIBILITY:
00816     return query_int (THIS, "scrollbars", type_id);
00817   case SLOT_SCROLL_POSITION:
00818     return query_coord2 (THIS, "scroll position", type_id);
00819 
00820   case SLOT_HEADER_VISIBILITY:
00821     return query_bool (THIS, "header", type_id);
00822   case SLOT_MAIN_ICONS_VISIBILITY:
00823     return query_bool (THIS, "main icons", type_id);
00824   case SLOT_MODE_ICONS_VISIBILITY:
00825     return query_bool (THIS, "mode icons", type_id);
00826   case SLOT_FOCUS_ICONS_VISIBILITY:
00827     return query_bool (THIS, "focus icons", type_id);
00828   case SLOT_USER_ICONS_VISIBILITY:
00829     return query_bool (THIS, "user icons", type_id);
00830   case SLOT_SIDE_TOOLS_VISIBILITY:
00831     return query_bool (THIS, "side tools", type_id);
00832   case SLOT_FOOTER_VISIBILITY:
00833     return query_bool (THIS, "footer flag", type_id);
00834   case SLOT_INTERACTIVE_MODE:
00835     return query_bool (THIS, "interactive mode", type_id);
00836   case SLOT_INTERACTIVE_INPUT:
00837     return query_string (THIS, "interactive input", type_id);
00838 
00839   case SLOT_STRING_INPUT:
00840     return query_string (THIS, "input", type_id);
00841   default:
00842     FAILED ("cannot handle slot type");
00843     return blackbox ();
00844   }
00845 }
00846 
00847 /******************************************************************************
00848 * Notification of state changes
00849 ******************************************************************************/
00850 
00851 void
00852 notify_keyboard_focus (wk_widget w, blackbox val) {
00853   ASSERT (type_box (val) == type_helper<bool>::id, "type mismatch");
00854   w << emit_keyboard_focus (open_box<bool> (val));
00855 }
00856 
00857 void
00858 notify_mouse_grab (wk_widget w, blackbox val) {
00859   ASSERT (type_box (val) == type_helper<bool>::id, "type mismatch");
00860   w << emit_mouse_grab (open_box<bool> (val));
00861 }
00862 
00863 void
00864 wk_widget_rep::notify (slot s, blackbox new_val) {
00865   switch (s) {
00866   case SLOT_SIZE:
00867     check_type<SI,SI> (new_val, "SLOT_SIZE");
00868     THIS << emit_resize ();
00869     if (is_window_widget ())
00870       send_size (THIS [0], new_val);
00871     break;
00872   case SLOT_POSITION:
00873     check_type<SI,SI> (new_val, "SLOT_POSITION");
00874     THIS << emit_move ();
00875     break;
00876   case SLOT_KEYBOARD_FOCUS:
00877     notify_keyboard_focus (THIS, new_val);
00878     break;
00879   case SLOT_MOUSE_GRAB:
00880     notify_mouse_grab (THIS, new_val);
00881     break;
00882   default:
00883     break;
00884   }
00885   widget_rep::notify (s, new_val);
00886 }
00887 
00888 /******************************************************************************
00889 * Read and write access of subwidgets
00890 ******************************************************************************/
00891 
00892 widget
00893 wk_widget_rep::read (slot s, blackbox index) {
00894   switch (s) {
00895   case SLOT_WINDOW:
00896     check_type_void (index, "SLOT_WINDOW");
00897     return win -> get_widget ();
00898   case SLOT_CANVAS:
00899     check_type_void (index, "SLOT_CANVAS");
00900     return abstract (THIS ["canvas"]);
00901   case SLOT_FORM_FIELD:
00902     check_type<int> (index, "SLOT_FORM_FIELD");
00903     return abstract (THIS [0] ["inputs"] [2*open_box<int> (index)] ["input"]);
00904   case SLOT_FILE:
00905     check_type_void (index, "SLOT_FILE");
00906     return abstract (THIS [0] ["file"] ["input"]);
00907   case SLOT_DIRECTORY:
00908     check_type_void (index, "SLOT_DIRECTORY");
00909     return abstract (THIS [0] ["directory"] ["input"]);
00910   default:
00911     FAILED ("cannot handle slot type");
00912     return widget ();
00913   }
00914 }
00915 
00916 void
00917 wk_widget_rep::write (slot s, blackbox index, widget w) {
00918   switch (s) {
00919   case SLOT_MAIN_MENU:
00920     check_type_void (index, "SLOT_MAIN_MENU");
00921     THIS << set_widget ("menu bar", concrete (w));
00922     break;
00923   case SLOT_MAIN_ICONS:
00924     check_type_void (index, "SLOT_MAIN_ICONS");
00925     THIS << set_widget ("main icons bar", concrete (w));
00926     break;
00927   case SLOT_MODE_ICONS:
00928     check_type_void (index, "SLOT_MODE_ICONS");
00929     THIS << set_widget ("mode icons bar", concrete (w));
00930     break;
00931   case SLOT_FOCUS_ICONS:
00932     check_type_void (index, "SLOT_FOCUS_ICONS");
00933     THIS << set_widget ("focus icons bar", concrete (w));
00934     break;
00935   case SLOT_USER_ICONS:
00936     check_type_void (index, "SLOT_USER_ICONS");
00937     THIS << set_widget ("user icons bar", concrete (w));
00938     break;
00939   case SLOT_SIDE_TOOLS:
00940     check_type_void (index, "SLOT_SIDE_TOOLS");
00941     THIS << set_widget ("side tools", concrete (w));
00942     break;
00943   case SLOT_SCROLLABLE:
00944     check_type_void (index, "SLOT_SCROLLABLE");
00945     THIS << set_widget ("scrollable", concrete (w));
00946     break;
00947   case SLOT_INTERACTIVE_PROMPT:
00948     check_type_void (index, "SLOT_INTERACTIVE_PROMPT");
00949     THIS << set_widget ("interactive prompt", concrete (w));
00950     break;
00951   case SLOT_INTERACTIVE_INPUT:
00952     check_type_void (index, "SLOT_INTERACTIVE_INPUT");
00953     THIS << set_widget ("interactive input", concrete (w));
00954     break;
00955   default:
00956     FAILED ("cannot handle slot type");
00957   }
00958 }