Back to index

texmacs  1.0.7.15
texmacs_widget.cpp
Go to the documentation of this file.
00001 
00002 /******************************************************************************
00003 * MODULE     : texmacs_widget.cpp
00004 * DESCRIPTION: Widget for the main TeXmacs window
00005 * COPYRIGHT  : (C) 1999  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 "window.hpp"
00013 #include "Widkit/basic_widget.hpp"
00014 #include "Widkit/Event/attribute_event.hpp"
00015 #include "message.hpp"
00016 #include "dictionary.hpp"
00017 
00018 #define THIS (wk_widget (this))
00019 
00020 /******************************************************************************
00021 * The TeXmacs widget
00022 ******************************************************************************/
00023 
00024 class texmacs_widget_rep: public basic_widget_rep {
00025 protected:
00026   bool    footer_flag;  // footer visible ?
00027   command quit;         // called on destruction
00028 
00029 protected:
00030   void set_left_footer (string s);
00031   void set_right_footer (string s);
00032   int  get_footer_mode ();
00033   void set_footer_mode (int which);
00034   bool get_footer_flag ();
00035   void set_footer_flag (bool on);
00036 
00037   void set_subwidget (wk_widget w, string which, wk_widget sw);
00038   bool get_subwidget_flag (wk_widget w);
00039   void set_subwidget_flag (wk_widget w, bool on);
00040 
00041 public:
00042   texmacs_widget_rep (int mask, command quit);
00043   ~texmacs_widget_rep ();
00044   operator tree ();
00045 
00046   void handle_get_size (get_size_event ev);
00047   void handle_set_widget (set_widget_event ev);
00048   void handle_get_widget (get_widget_event ev);
00049   void handle_set_integer (set_integer_event ev);
00050   void handle_set_string (set_string_event ev);
00051   void handle_get_string (get_string_event ev);
00052   void handle_set_coord2 (set_coord2_event ev);
00053   void handle_get_coord2 (get_coord2_event ev);
00054   void handle_set_coord4 (set_coord4_event ev);
00055   void handle_get_coord4 (get_coord4_event ev);
00056   void handle_keypress (keypress_event ev);
00057   void handle_mouse (mouse_event ev);
00058   void handle_keyboard_focus (keyboard_focus_event ev);
00059   void handle_resize (resize_event ev);
00060   void handle_destroy (destroy_event ev);
00061 
00062   bool handle (event ev);
00063 
00064   friend class tm_editor_rep;
00065   friend class texmacs_widget;
00066 };
00067 
00068 /******************************************************************************
00069 * Subwidgets of main TeXmacs widgets
00070 ******************************************************************************/
00071 
00072 static wk_widget
00073 make_menu_bar () {
00074   array<wk_widget> M (2);
00075   array<string> M_name (2);
00076   M[0]= horizontal_array (array<wk_widget> (0));
00077   M[1]= glue_wk_widget (true, false);
00078   M_name[0]= "menu";
00079 
00080   array<wk_widget> V (2);
00081   array<string> V_name (2);
00082   V[0]= glue_wk_widget (true, false, 0, 2*PIXEL);
00083   V[1]= horizontal_array (M, M_name);
00084   V_name[1]= "bar";
00085   return optional_widget (vertical_list (V, V_name));
00086 }
00087 
00088 static wk_widget
00089 make_icon_bar (bool on) {
00090   array<wk_widget> I (4);
00091   array<string> I_name (4);
00092   I[0]= glue_wk_widget (false, false, 3*PIXEL);
00093   I[1]= horizontal_array (array<wk_widget> (0));
00094   I[2]= glue_wk_widget (true, false);
00095   I[3]= glue_wk_widget (false, false, 3*PIXEL);
00096   I_name[1]= "icons";
00097 
00098   array<wk_widget> V (2);
00099   array<string> V_name (2);
00100   V[0]= separator_wk_widget (PIXEL, 2*PIXEL);
00101   V[1]= horizontal_array (I, I_name);
00102   V_name[1]= "bar";
00103   return optional_widget (vertical_list (V, V_name), on);
00104 }
00105 
00106 static wk_widget
00107 make_header (int mask) {
00108   array<wk_widget> H (6);
00109   array<string> H_name (6);
00110   H[0]= make_menu_bar ();
00111   H[1]= make_icon_bar ((mask & 2) == 2);
00112   H[2]= make_icon_bar ((mask & 4) == 4);
00113   H[3]= make_icon_bar ((mask & 8) == 8);
00114   H[4]= make_icon_bar ((mask & 16) == 16);
00115   H[5]= glue_wk_widget (true, false, 0, 2*PIXEL);
00116   H_name[0]= "menu";
00117   H_name[1]= "main";
00118   H_name[2]= "mode";
00119   H_name[3]= "focus";
00120   H_name[4]= "user";
00121   return optional_widget (vertical_list (H, H_name), (mask & 1) == 1);
00122 }
00123 
00124 static wk_widget
00125 make_footer (int mask) {
00126   array<wk_widget> F (3);
00127   array<string> F_name (3);
00128   F[0]= text_wk_widget (translate ("Welcome to TeXmacs!"));
00129   F[1]= glue_wk_widget (true, false);
00130   F[2]= text_wk_widget ("TeXmacs " TEXMACS_VERSION);
00131   F_name[0]= "left";
00132   F_name[1]= "middle";
00133   F_name[2]= "right";
00134   wk_widget ftr= horizontal_array (F, F_name, 1);
00135 #ifdef OS_MACOS
00136   F << glue_wk_widget (false, false, 14*PIXEL, 0);
00137   F_name << string ("margin");
00138 #endif
00139 
00140   array<wk_widget> I (3);
00141   array<string> I_name (3);
00142   I[0]= text_wk_widget (translate ("Input:"));
00143   I[1]= glue_wk_widget (true, false);
00144 #ifdef OS_MACOS
00145   I[2]= glue_wk_widget (false, false, 18*PIXEL);
00146 #else
00147   I[2]= glue_wk_widget (false, false, 2*PIXEL);
00148 #endif
00149   I_name[0]= "left";
00150   I_name[1]= "middle";
00151   I_name[2]= "right";
00152   wk_widget iac= horizontal_list (I, I_name);
00153   //wk_widget iac= horizontal_array (I, I_name, 1);
00154 
00155   array<wk_widget> S (3);
00156   array<string> S_name (3);
00157   S[0]= ftr;
00158   S[1]= iac;
00159   S[2]= glue_wk_widget (false, false);
00160   S_name[0]= "default";
00161   S_name[1]= "interactive";
00162   return switch_widget (S, S_name, (mask & 32) == 32? 0: 2);
00163 }
00164 
00165 static wk_widget
00166 middle_widget () {
00167   wk_widget w1= canvas_widget (glue_wk_widget (), north_west, true);
00168   wk_widget w2= glue_wk_widget (true, true, 200*PIXEL, 0);
00169   wk_widget w3= resize_widget (w2, 0, "200px", "", "200px", "", "200px", "");
00170   if (!use_side_tools) return w1;
00171   else return hsplit_widget (w1, w3);
00172 }
00173 
00174 static wk_widget
00175 make_texmacs_widget (int mask) {
00176   array<wk_widget> V (5);
00177   array<string> V_name (5);
00178   V[0]= make_header (mask);
00179   //V[1]= canvas_widget (glue_wk_widget (), north_west, true);
00180   V[1]= middle_widget ();
00181   V[2]= glue_wk_widget (false, false, 0, PIXEL);
00182   V[3]= make_footer (mask);
00183   V[4]= glue_wk_widget (false, false, 0, PIXEL);
00184   V_name[0]= "header";
00185   //V_name[1]= "canvas";
00186   V_name[1]= "middle";
00187   V_name[3]= "footer";
00188   return vertical_list (V, V_name);
00189 }
00190 
00191 /******************************************************************************
00192 * Constructor and destructor
00193 ******************************************************************************/
00194 
00195 texmacs_widget_rep::texmacs_widget_rep (int mask, command quit2):
00196   basic_widget_rep (1), footer_flag (true), quit (quit2)
00197 {
00198   a[0]= make_texmacs_widget (mask);
00199 }
00200 
00201 texmacs_widget_rep::~texmacs_widget_rep () {}
00202 
00203 texmacs_widget_rep::operator tree () {
00204   return tree (TUPLE, "TeXmacs window", (tree) a[0]);
00205 }
00206 
00207 /******************************************************************************
00208 * Accessors
00209 ******************************************************************************/
00210 
00211 void
00212 texmacs_widget_rep::set_subwidget (wk_widget w, string which, wk_widget sw) {
00213   SI ww1= 600*PIXEL, hh1=18*PIXEL, ww2=600*PIXEL, hh2=18*PIXEL;
00214   if (which == "icons") hh1= hh2= 18*PIXEL;
00215   w << get_size (ww1, hh1);
00216   w << set_widget (which, sw);
00217   w << get_size (ww2, hh2);
00218   if (attached ()) {
00219     if (hh1 == hh2) w << emit_update ();
00220     else THIS << emit_update ();
00221   }
00222 }
00223 
00224 bool
00225 texmacs_widget_rep::get_subwidget_flag (wk_widget w) {
00226   int which;
00227   w << get_integer ("switch", which);
00228   return which == 0;
00229 }
00230 
00231 void
00232 texmacs_widget_rep::set_subwidget_flag (wk_widget w, bool on) {
00233   if (get_subwidget_flag (w) != on) {
00234     w << set_integer ("switch", on? 0: 1);
00235     if (attached ()) THIS << emit_update ();
00236   }
00237 }
00238 
00239 /******************************************************************************
00240 * Changing the footer
00241 ******************************************************************************/
00242 
00243 void
00244 texmacs_widget_rep::set_left_footer (string s) {
00245   wk_widget tw= text_wk_widget (s);
00246   set_subwidget (THIS ["footer"], "left", tw);
00247 }
00248 
00249 void
00250 texmacs_widget_rep::set_right_footer (string s) {
00251   wk_widget tw= text_wk_widget (s);
00252   set_subwidget (THIS ["footer"], "right", tw);
00253 }
00254 
00255 int
00256 texmacs_widget_rep::get_footer_mode () {
00257   int which;
00258   THIS ["footer"] << get_integer ("switch", which);
00259   return which;
00260 }
00261 
00262 void
00263 texmacs_widget_rep::set_footer_mode (int new_mode) {
00264   int old_mode= get_footer_mode ();
00265   if (old_mode != new_mode) {
00266     wk_widget iac= THIS ["footer"] ["interactive"];
00267     if (old_mode == 1)
00268       send_keyboard_focus (abstract (THIS ["canvas"]));
00269 
00270     SI ww1= 600*PIXEL, hh1=18*PIXEL, ww2=600*PIXEL, hh2=18*PIXEL;
00271     THIS ["footer"] << get_size (ww1, hh1);
00272     THIS ["footer"] << set_integer ("switch", new_mode);
00273     THIS ["footer"] << get_size (ww2, hh2);
00274     if (attached ()) {
00275       if (hh1 == hh2) THIS ["footer"] << emit_update ();
00276       else THIS << emit_update ();
00277     }
00278 
00279     if (new_mode == 1) {
00280       iac << emit_update ();
00281       send_keyboard_focus (abstract (iac ["middle"]));
00282     }
00283   }
00284 }
00285 
00286 bool
00287 texmacs_widget_rep::get_footer_flag () {
00288   return footer_flag;
00289 }
00290 
00291 void
00292 texmacs_widget_rep::set_footer_flag (bool on) {
00293   footer_flag= on;
00294   if (get_footer_mode () != 1)
00295     set_footer_mode (on? 0: 2);
00296 }
00297 
00298 /******************************************************************************
00299 * Handling standard events
00300 ******************************************************************************/
00301 
00302 void
00303 texmacs_widget_rep::handle_get_size (get_size_event ev) {
00304   if (ev->mode == 0) {
00305     ev->w= (800-24) * PIXEL; // (800-32) * PIXEL;
00306     ev->h= (600-28) * PIXEL;
00307   }
00308   else if (ev->mode == 1) gui_maximal_extents (ev->w, ev->h);
00309   else basic_widget_rep::handle_get_size (ev);
00310 }
00311 
00312 void
00313 texmacs_widget_rep::handle_get_widget (get_widget_event ev) {
00314   if (ev->which == "canvas") {
00315     if (use_side_tools) a[0] ["middle"] << get_widget ("left", ev->w);
00316     else a[0] << get_widget ("middle", ev->w);
00317   }
00318   else a[0] << ev;
00319 }
00320 
00321 void
00322 texmacs_widget_rep::handle_set_widget (set_widget_event ev) {
00323   if (ev->which == "menu bar")
00324     set_subwidget (THIS ["header"] ["menu"] ["bar"], "menu", ev->w);
00325   else if (ev->which == "main icons bar")
00326     set_subwidget (THIS ["header"] ["main"] ["bar"], "icons", ev->w);
00327   else if (ev->which == "mode icons bar")
00328     set_subwidget (THIS ["header"] ["mode"] ["bar"], "icons", ev->w);
00329   else if (ev->which == "focus icons bar")
00330     set_subwidget (THIS ["header"] ["focus"] ["bar"], "icons", ev->w);
00331   else if (ev->which == "user icons bar")
00332     set_subwidget (THIS ["header"] ["user"] ["bar"], "icons", ev->w);
00333   else if (use_side_tools && ev->which == "side tools") {
00334     wk_widget side=
00335       resize_widget (ev->w, 0, "200px", "", "200px", "", "200px", "");
00336     THIS ["middle"] << set_widget ("right", side);
00337     if (attached ()) {
00338       side << emit_attach_window (win);
00339       THIS ["middle"] << emit_reposition ();
00340       THIS ["middle"] ["right"] << emit_invalidate_all ();
00341     }
00342   }
00343   else if (ev->which == "interactive prompt")
00344     set_subwidget (THIS ["footer"] ["interactive"], "left", ev->w);
00345   else if (ev->which == "interactive input")
00346     set_subwidget (THIS ["footer"] ["interactive"], "middle", ev->w);
00347   else if (ev->which == "scrollable") {
00348     THIS ["canvas"] << set_widget ("scrollable", ev->w);
00349     if (attached ()) {
00350       // FIXME: we manually take care of the keyboard focus
00351       // this should be done more systematically when changing subwidgets
00352       wk_widget old= THIS ["canvas"] ["scrollable"];
00353       bool focus= query_keyboard_focus (abstract (old));
00354       THIS ["canvas"] << emit_attach_window (win);
00355       old << emit_attach_window (NULL);
00356       if (focus) send_keyboard_focus (abstract (THIS ["canvas"]));
00357       THIS ["canvas"] << emit_update ();
00358     }
00359   }
00360   else a[0] << ev;
00361 }
00362 
00363 void
00364 texmacs_widget_rep::handle_set_integer (set_integer_event ev) {
00365   if (ev->which == "shrinking factor")
00366     THIS ["canvas"] << set_integer ("shrinking factor", ev->i);
00367   else if (ev->which == "scrollbars")
00368     THIS ["canvas"] << set_integer ("scrollbars", ev->i);
00369   else WK_FAILED ("could not set integer attribute " * ev->which);
00370 }
00371 
00372 void
00373 texmacs_widget_rep::handle_set_string (set_string_event ev) {
00374   if (ev->which == "window name") win->set_name (ev->s);
00375   else if (ev->which == "file");
00376   else if (ev->which == "header")
00377     set_subwidget_flag (THIS ["header"], ev->s == "on");
00378   else if (ev->which == "main icons")
00379     set_subwidget_flag (THIS ["header"] ["main"], ev->s == "on");
00380   else if (ev->which == "mode icons")
00381     set_subwidget_flag (THIS ["header"] ["mode"], ev->s == "on");
00382   else if (ev->which == "focus icons")
00383     set_subwidget_flag (THIS ["header"] ["focus"], ev->s == "on");
00384   else if (ev->which == "user icons")
00385     set_subwidget_flag (THIS ["header"] ["user"], ev->s == "on");
00386   else if (use_side_tools && ev->which == "side tools")
00387     /*set_side_tools_flag (ev->s == "on")*/;
00388   else if (ev->which == "interactive mode")
00389     set_footer_mode (ev->s == "on"? 1: (footer_flag? 0: 2));
00390   else if (ev->which == "footer flag") set_footer_flag (ev->s == "on");
00391   else if (ev->which == "left footer") set_left_footer (ev->s);
00392   else if (ev->which == "right footer") set_right_footer (ev->s);
00393   else WK_FAILED ("could not set string attribute " * ev->which);
00394 }
00395 
00396 void
00397 texmacs_widget_rep::handle_get_string (get_string_event ev) {
00398   if (ev->which == "header")
00399     ev->s= get_subwidget_flag (THIS ["header"])?
00400              string ("on"): string ("off");
00401   else if (ev->which == "main icons")
00402     ev->s= get_subwidget_flag (THIS ["header"] ["main"])?
00403              string ("on"): string ("off");
00404   else if (ev->which == "mode icons")
00405     ev->s= get_subwidget_flag (THIS ["header"] ["mode"])?
00406              string ("on"): string ("off");
00407   else if (ev->which == "focus icons")
00408     ev->s= get_subwidget_flag (THIS ["header"] ["focus"])?
00409              string ("on"): string ("off");
00410   else if (ev->which == "user icons")
00411     ev->s= get_subwidget_flag (THIS ["header"] ["user"])?
00412              string ("on"): string ("off");
00413   else if (use_side_tools && ev->which == "side tools")
00414     //ev->s= get_side_tools_flag ()? string ("on"): string ("off");
00415     ev->s= string ("on");
00416   else if (ev->which == "interactive mode")
00417     ev->s= get_footer_mode () == 1? string ("on"): string ("off");
00418   else if (ev->which == "footer flag")
00419     ev->s= get_footer_flag ()? string ("on"): string ("off");
00420   else if (ev->which == "interactive input")
00421     THIS ["footer"] ["interactive"] ["middle"] << get_input_string (ev->s);
00422   else WK_FAILED ("could not set string attribute " * ev->which);
00423 }
00424 
00425 void
00426 texmacs_widget_rep::handle_set_coord2 (set_coord2_event ev) {
00427   if (ev->which == "extra width" && ev->c1 == 0 && ev->c2 == 0) return;
00428   else if (ev->which == "scroll position") THIS ["canvas"] << ev;
00429   else WK_FAILED ("could not set coord2 attribute " * ev->which);
00430 }
00431 
00432 void
00433 texmacs_widget_rep::handle_get_coord2 (get_coord2_event ev) {
00434   if (ev->which == "extra width") { ev->c1= ev->c2= 0; return; }
00435   else if (ev->which == "scroll position") THIS ["canvas"] << ev;
00436   else WK_FAILED ("could not get coord2 attribute " * ev->which);
00437 }
00438 
00439 void
00440 texmacs_widget_rep::handle_set_coord4 (set_coord4_event ev) {
00441   if (ev->which == "extents") THIS ["canvas"] << ev;
00442   else WK_FAILED ("could not set coord4 attribute " * ev->which);
00443 }
00444 
00445 void
00446 texmacs_widget_rep::handle_get_coord4 (get_coord4_event ev) {
00447   if (ev->which == "extents") THIS ["canvas"] << ev;
00448   else if (ev->which == "visible") THIS ["canvas"] << ev;
00449   else WK_FAILED ("could not get coord4 attribute " * ev->which);
00450 }
00451 
00452 void
00453 texmacs_widget_rep::handle_keypress (keypress_event ev) {
00454   if (get_footer_mode () == 1)
00455     THIS ["footer"] ["interactive"] ["middle"] << ev;
00456   else THIS ["canvas"] << ev;
00457 }
00458 
00459 void
00460 texmacs_widget_rep::handle_mouse (mouse_event ev) {
00461   basic_widget_rep::handle_mouse (ev);
00462 }
00463 
00464 void
00465 texmacs_widget_rep::handle_keyboard_focus (keyboard_focus_event ev) {
00466   if (get_footer_mode () == 1)
00467     THIS ["footer"] ["interactive"] ["middle"] << ev;
00468   else THIS ["canvas"] << ev;
00469 }
00470 
00471 void
00472 texmacs_widget_rep::handle_resize (resize_event ev) {
00473   switch (get_footer_mode ()) {
00474   case 0: THIS ["footer"] ["middle"] << ev; break;
00475   case 1: THIS ["footer"] ["interactive"] ["middle"] << ev; break;
00476   }
00477   THIS ["canvas"] << ev;
00478 }
00479 
00480 void
00481 texmacs_widget_rep::handle_destroy (destroy_event ev) {
00482   if (!is_nil (quit)) quit ();
00483 }
00484 
00485 /******************************************************************************
00486 * Handling standard events
00487 ******************************************************************************/
00488 
00489 bool
00490 texmacs_widget_rep::handle (event ev) {
00491   //cout << "handle " << ((event) ev) << LF;
00492   //  if (ev->type == POSITION_EVENT) {
00493   //  cout << "position: " << ((event) ev) << LF;
00494   //}
00495   switch (ev->type) {
00496   case SET_INTEGER_EVENT:
00497     handle_set_integer (ev);
00498     return true;
00499   case GET_STRING_EVENT:
00500     handle_get_string (ev);
00501     return true;
00502   case SET_STRING_EVENT:
00503     handle_set_string (ev);
00504     return true;
00505   case GET_COORD2_EVENT:
00506     handle_get_coord2 (ev);
00507     return true;
00508   case SET_COORD2_EVENT:
00509     handle_set_coord2 (ev);
00510     return true;
00511   case GET_COORD4_EVENT:
00512     handle_get_coord4 (ev);
00513     return true;
00514   case SET_COORD4_EVENT:
00515     handle_set_coord4 (ev);
00516     return true;
00517   default:
00518     {
00519       //cout << "size< " << (w>>8) << ", " << (h>>8) << LF;
00520       bool flag= basic_widget_rep::handle (ev);
00521       //cout << "size> " << (w>>8) << ", " << (h>>8) << LF;
00522       return flag;
00523     }
00524   }
00525 }
00526 
00527 /******************************************************************************
00528 * exported routines
00529 ******************************************************************************/
00530 
00531 wk_widget
00532 texmacs_wk_widget (int mask, command quit) {
00533   return tm_new<texmacs_widget_rep> (mask, quit);
00534 }