Back to index

texmacs  1.0.7.15
tm_window.cpp
Go to the documentation of this file.
00001 
00002 /******************************************************************************
00003 * MODULE     : tm_window.cpp
00004 * DESCRIPTION: Main TeXmacs windows
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 "tm_window.hpp"
00013 #include "message.hpp"
00014 #include "dictionary.hpp"
00015 #include "merge_sort.hpp"
00016 #include "iterator.hpp"
00017 
00018 int geometry_w= 800, geometry_h= 600;
00019 int geometry_x= 0  , geometry_y= 0;
00020 
00021 widget texmacs_window_widget (widget wid, tree geom);
00022 widget make_menu_widget (object menu);
00023 void refresh_size (widget wid, bool exact);
00024 
00025 /******************************************************************************
00026 * Meta editor constructor and destructor
00027 ******************************************************************************/
00028 
00029 static int tm_window_serial= 0;
00030 
00031 tm_window_rep::tm_window_rep (widget wid2, tree geom):
00032   win (texmacs_window_widget (wid2, geom)),
00033   wid (wid2), id (create_window_id ()),
00034   serial (tm_window_serial++),
00035   menu_current (object ()), menu_cache (widget ()),
00036   text_ptr (NULL)
00037 {
00038   sfactor= get_server () -> get_default_shrinking_factor ();
00039 }
00040 
00041 tm_window_rep::tm_window_rep (tree doc, command quit):
00042   win (texmacs_widget (0, quit)),
00043   wid (win), id (-1),
00044   serial (tm_window_serial++),
00045   menu_current (object ()), menu_cache (widget ()),
00046   text_ptr (NULL)
00047 {
00048   sfactor= get_server () -> get_default_shrinking_factor ();
00049 }
00050 
00051 tm_window_rep::~tm_window_rep () {
00052   if (id != -1) destroy_window_id (id);
00053 }
00054 
00055 /******************************************************************************
00056 * Creation of TeXmacs window
00057 ******************************************************************************/
00058 
00059 widget
00060 texmacs_window_widget (widget wid, tree geom) {
00061   int W, H;
00062   int w= geometry_w, h= geometry_h;
00063   int x= geometry_x, y= geometry_y;
00064   if (use_side_tools) { w += 200; h += 100; }
00065   if (is_tuple (geom) && N (geom) >= 2) {
00066     w= as_int (geom[0]);
00067     h= as_int (geom[1]);
00068   }
00069   gui_root_extents (W, H); W /= PIXEL; H /= PIXEL;
00070   if (x < 0) x= W + x + 1 - w;
00071   if (y < 0) y= H + y + 1 - h;
00072   widget win= plain_window_widget (wid, "TeXmacs");
00073   set_size (win, w*PIXEL, h*PIXEL);
00074   set_position (win, x*PIXEL, (-y)*PIXEL);
00075   return win;
00076 }
00077 
00078 /******************************************************************************
00079 * Closing embedded TeXmacs widgets
00080 ******************************************************************************/
00081 
00082 class close_embedded_command_rep: public command_rep {
00083   tm_view vw;
00084 public:
00085   close_embedded_command_rep (tm_view vw2): vw (vw2) {}
00086   void apply ();
00087   tm_ostream& print (tm_ostream& out) {
00088     return out << "Close_Embedded widget command"; }
00089 };
00090 
00091 void
00092 close_embedded_command_rep::apply () {
00093   //cout << "Destroy " << vw->buf->buf->name << "\n";
00094   window_focus (vw->ed->mvw->win->id);
00095   //cout << "Changed focus\n";
00096   tm_window win= vw->win;
00097   ASSERT (N(vw->buf->vws) == 1, "invalid cloned embedded TeXmacs widget");
00098   delete_buffer (vw->buf);
00099   //cout << "Deleted buffer\n";
00100   tm_delete (win);
00101   //cout << "Deleted window\n";
00102 }
00103 
00104 command
00105 close_embedded_command (tm_view vw) {
00106   return tm_new<close_embedded_command_rep> (vw);
00107 }
00108 
00109 /******************************************************************************
00110 * Embedded TeXmacs widgets
00111 ******************************************************************************/
00112 
00113 string
00114 embedded_name () {
00115   static int nr= 0;
00116   nr++;
00117   return "* Embedded " * as_string (nr) * " *";
00118 }
00119 
00120 tree
00121 enrich_embedded_document (tree body) {
00122   tree orig= body;
00123   if (is_func (body, WITH)) body= body[N(body)-1];
00124   if (!is_func (body, DOCUMENT)) body= tree (DOCUMENT, body);
00125   tree style= "generic";
00126   hashmap<string,tree> initial (UNINIT);
00127   initial (PAGE_MEDIUM)= "automatic";
00128   initial (PAGE_SCREEN_LEFT)= "4px";
00129   initial (PAGE_SCREEN_RIGHT)= "4px";
00130   initial (PAGE_SCREEN_TOP)= "2px";
00131   initial (PAGE_SCREEN_BOT)= "2px";
00132   if (is_func (orig, WITH))
00133     for (int i=0; i+2<N(orig); i++)
00134       if (is_atomic (orig[i]))
00135         initial (orig[i]->label)= orig[i+1];
00136   tree doc (DOCUMENT);
00137   doc << compound ("TeXmacs", TEXMACS_VERSION);
00138   doc << compound ("style", tree (TUPLE, "generic"));
00139   doc << compound ("body", body);
00140   doc << compound ("initial", make_collection (initial));
00141   return doc;
00142 }
00143 
00144 widget
00145 texmacs_input_widget (tree doc, command cmd, bool continuous) {
00146   (void) cmd; (void) continuous;
00147   doc= enrich_embedded_document (doc);
00148   tm_view   curvw=  get_server () -> get_view ();
00149   string    name = embedded_name ();
00150   tm_buffer buf  = create_buffer (url (name), doc);
00151   tm_view   vw   = get_passive_view (buf);
00152   tm_window win  = tm_new<tm_window_rep> (doc, command ());
00153   set_aux (name, name);
00154   vw->win= win;
00155   vw->buf->buf->in_menu= false;
00156   set_scrollable (win->wid, vw->ed);
00157   vw->ed->cvw= win->wid.rep;
00158   vw->ed->mvw= curvw;
00159   return wrapped_widget (win->wid, close_embedded_command (vw));
00160 }
00161 
00162 /******************************************************************************
00163 * Meta mathods
00164 ******************************************************************************/
00165 
00166 void
00167 tm_window_rep::set_window_name (string s) {
00168   set_name (wid, s);
00169 }
00170 
00171 void
00172 tm_window_rep::set_window_url (url u) {
00173   if (!is_none (u)) set_file (wid, as_string (u));
00174 }
00175 
00176 void
00177 tm_window_rep::map () {
00178   set_visibility (win, true);
00179 }
00180 
00181 void
00182 tm_window_rep::unmap () {
00183   set_visibility (win, false);
00184 }
00185 
00186 void
00187 tm_window_rep::refresh () {
00188   menu_cache= hashmap<object,widget> (widget ());
00189 }
00190 
00191 /******************************************************************************
00192 * Menus
00193 ******************************************************************************/
00194 
00195 bool
00196 tm_window_rep::get_menu_widget (int which, string menu, widget& w) {
00197   object xmenu= call ("menu-expand", eval ("'" * menu));
00198   //cout << "xmenu= " << xmenu << "\n";
00199   if (menu_cache->contains (xmenu)) {
00200     //if (menu_current[which] == xmenu) cout << "Same " << menu << "\n";
00201     if (menu_current[which] == xmenu) return false;
00202     menu_current (which)= xmenu;
00203     //cout << "Cached " << menu << "\n";
00204     w= menu_cache [xmenu];
00205     return true;
00206   }
00207   menu_current (which)= xmenu;
00208   //cout << "Compute " << menu << "\n";
00209   object umenu= eval ("'" * menu);
00210   w= make_menu_widget (umenu);
00211   menu_cache (xmenu)= w;
00212   return true;
00213 }
00214 
00215 void
00216 tm_window_rep::menu_main (string menu) {
00217   eval ("(lazy-initialize-force)");
00218   widget w;
00219   if (get_menu_widget (-1, menu, w))
00220     ::set_main_menu (wid, w);
00221 }
00222 
00223 void
00224 tm_window_rep::menu_icons (int which, string menu) {
00225   eval ("(lazy-initialize-force)");
00226   widget w;
00227   if (get_menu_widget (which, menu, w)) {
00228     if      (which == 0) set_main_icons (wid, w);
00229     else if (which == 1) set_mode_icons (wid, w);
00230     else if (which == 2) set_focus_icons (wid, w);
00231     else if (which == 3) set_user_icons (wid, w);
00232   }
00233 }
00234 
00235 void
00236 tm_window_rep::side_tools (int which, string tools) {
00237   eval ("(lazy-initialize-force)");
00238   widget w;
00239   if (get_menu_widget (10 + which, tools, w)) {
00240     if (which == 0) set_side_tools (wid, w);
00241   }
00242 }
00243 
00244 void
00245 tm_window_rep::set_header_flag (bool flag) {
00246   set_header_visibility (wid, flag);
00247 }
00248 
00249 void
00250 tm_window_rep::set_icon_bar_flag (int which, bool flag) {
00251   if      (which == 0) set_main_icons_visibility (wid, flag);
00252   else if (which == 1) set_mode_icons_visibility (wid, flag);
00253   else if (which == 2) set_focus_icons_visibility (wid, flag);
00254   else if (which == 3) set_user_icons_visibility (wid, flag);
00255 }
00256 
00257 void
00258 tm_window_rep::set_side_tools_flag (int which, bool flag) {
00259   if (which == 0) set_side_tools_visibility (wid, flag);
00260 }
00261 
00262 bool
00263 tm_window_rep::get_header_flag () {
00264   return get_header_visibility (wid);
00265 }
00266 
00267 bool
00268 tm_window_rep::get_icon_bar_flag (int which) {
00269   if      (which == 0) return get_main_icons_visibility (wid);
00270   else if (which == 1) return get_mode_icons_visibility (wid);
00271   else if (which == 2) return get_focus_icons_visibility (wid);
00272   else if (which == 3) return get_user_icons_visibility (wid);
00273   else return false;
00274 }
00275 
00276 bool
00277 tm_window_rep::get_side_tools_flag (int which) {
00278   if (which == 0) return get_side_tools_visibility (wid);
00279   else return false;
00280 }
00281 
00282 /******************************************************************************
00283 * The canvas
00284 ******************************************************************************/
00285 
00286 void
00287 tm_window_rep::set_shrinking_factor (int sf) {
00288   sfactor= sf;
00289   ::set_shrinking_factor (wid, sf);
00290 }
00291 
00292 int
00293 tm_window_rep::get_shrinking_factor () {
00294   return sfactor;
00295 }
00296 
00297 void
00298 tm_window_rep::get_visible (SI& x1, SI& y1, SI& x2, SI& y2) {
00299   get_visible_part (wid, x1, y1, x2, y2);
00300 }
00301 
00302 void
00303 tm_window_rep::get_extents (SI& x1, SI& y1, SI& x2, SI& y2) {
00304   ::get_extents (wid, x1, y1, x2, y2);
00305 }
00306 
00307 void
00308 tm_window_rep::set_extents (SI x1, SI y1, SI x2, SI y2) {
00309   ::set_extents (wid, x1, y1, x2, y2);
00310 }
00311 
00312 void
00313 tm_window_rep::set_scrollbars (int i) {
00314   ::set_scrollbars_visibility (wid, i);
00315 }
00316 
00317 void
00318 tm_window_rep::get_scroll_pos (SI& x, SI& y) {
00319   get_scroll_position (wid, x, y);
00320 }
00321 
00322 void
00323 tm_window_rep::set_scroll_pos (SI x, SI y) {
00324   set_scroll_position (wid, x, y);
00325 }
00326 
00327 /******************************************************************************
00328 * The footer as a status bar
00329 ******************************************************************************/
00330 
00331 bool
00332 tm_window_rep::get_footer_flag () {
00333   return get_footer_visibility (wid);
00334 }
00335 
00336 void
00337 tm_window_rep::set_footer_flag (bool flag) {
00338   set_footer_visibility (wid, flag);
00339 }
00340 
00341 void
00342 tm_window_rep::set_left_footer (string s) {
00343   ::set_left_footer (wid, s);
00344 }
00345 
00346 void
00347 tm_window_rep::set_right_footer (string s) {
00348   ::set_right_footer (wid, s);
00349 }
00350 
00351 /******************************************************************************
00352 * Interactive commands on the footer
00353 ******************************************************************************/
00354 
00355 class ia_command_rep: public command_rep {
00356   tm_window_rep* win;
00357 public:
00358   ia_command_rep (tm_window_rep* win2): win (win2) {}
00359   void apply () { win->interactive_return (); }
00360   tm_ostream& print (tm_ostream& out) { return out << "tm_window command"; }
00361 };
00362 
00363 bool
00364 tm_window_rep::get_interactive_mode () {
00365   return ::get_interactive_mode (wid);
00366 }
00367 
00368 void
00369 tm_window_rep::set_interactive_mode (bool flag) {
00370   ::set_interactive_mode (wid, flag);
00371 }
00372 
00373 void
00374 tm_window_rep::interactive (string name, string type, array<string> def,
00375                          string& s, command cmd)
00376 {
00377   if (get_interactive_mode ()) { s= "cancel"; return; }
00378   text_ptr = &s;
00379   call_back= cmd;
00380   widget tw = text_widget (translate (name), 0, black, false);
00381   widget inp= input_text_widget (tm_new<ia_command_rep> (this), type, def);
00382   set_interactive_prompt (wid, tw);
00383   set_interactive_input (wid, inp);
00384   set_interactive_mode (true);
00385 }
00386 
00387 void
00388 tm_window_rep::interactive_return () {
00389   *text_ptr= get_interactive_input (wid);
00390   text_ptr= NULL;
00391   set_interactive_mode (false);
00392   call_back ();
00393 }
00394 
00395 /******************************************************************************
00396 * Other top level windows
00397 ******************************************************************************/
00398 
00399 static hashmap<int,widget> window_table (NULL);
00400 static time_t refresh_time= 0;
00401 
00402 int
00403 window_handle () {
00404   static int window_next= 1;
00405   return window_next++;
00406 }
00407 
00408 void
00409 window_create (int win, widget wid, string name, bool plain) {
00410   widget pww;
00411   if (plain)
00412     pww= plain_window_widget (wid, name);
00413   else
00414     pww= popup_window_widget (wid, name);
00415   window_table (win)= pww;
00416 }
00417 
00418 void
00419 window_create (int win, widget wid, string name, command quit) {
00420   widget pww;
00421   pww= plain_window_widget (wid, name, quit);
00422   window_table (win)= pww;
00423 }
00424 
00425 void
00426 window_delete (int win) {
00427   ASSERT (window_table->contains (win), "window does not exist");
00428   widget pww= window_table [win];
00429   window_table->reset (win);
00430   destroy_window_widget (pww);
00431 }
00432 
00433 void
00434 window_show (int win) {
00435   ASSERT (window_table->contains (win), "window does not exist");
00436   widget pww= window_table [win];
00437   set_visibility (pww, true);
00438 }
00439 
00440 void
00441 window_hide (int win) {
00442   ASSERT (window_table->contains (win), "window does not exist");
00443   widget pww= window_table [win];
00444   set_visibility (pww, false);
00445 }
00446 
00447 void
00448 windows_delayed_refresh (int ms) {
00449   refresh_time= texmacs_time () + ms;
00450 }
00451 
00452 void
00453 windows_refresh () {
00454   if (texmacs_time () < refresh_time) return;
00455   iterator<int> it= iterate (window_table);
00456   while (it->busy ()) {
00457     int id= it->next ();
00458     send_refresh (window_table[id]);
00459 #ifndef QTTEXMACS
00460     refresh_size (window_table[id], false);
00461 #endif
00462   }
00463   windows_delayed_refresh (1000000000);
00464 }