Back to index

texmacs  1.0.7.15
bridge_gui.cpp
Go to the documentation of this file.
00001 
00002 /******************************************************************************
00003 * MODULE     : bridge_with.cpp
00004 * DESCRIPTION: Bridge for GUI markup
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 "bridge.hpp"
00013 #include "analyze.hpp"
00014 #include "Concat/canvas_properties.hpp"
00015 #include "Line/lazy_paragraph.hpp"
00016 
00017 /******************************************************************************
00018 * Abstract bridge for ornaments
00019 ******************************************************************************/
00020 
00021 class bridge_ornamented_rep: public bridge_rep {
00022 protected:
00023   int    last;
00024   bridge body;
00025   tree   with;
00026 
00027 public:
00028   bridge_ornamented_rep (typesetter ttt, tree st, path ip);
00029   void initialize ();
00030 
00031   void notify_assign (path p, tree u);
00032   void notify_insert (path p, tree u);
00033   void notify_remove (path p, int nr);
00034   bool notify_macro  (int type, string var, int level, path p, tree u);
00035   void notify_change ();
00036 
00037   void my_exec_until (path p);
00038   bool my_typeset_will_be_complete ();
00039   box  typeset_ornament (int desired_status);
00040   void insert_ornament (box b);
00041 };
00042 
00043 bridge_ornamented_rep::bridge_ornamented_rep (
00044   typesetter ttt, tree st, path ip):
00045     bridge_rep (ttt, st, ip), with (tree (TUPLE))
00046 {
00047   initialize ();
00048 }
00049 
00050 void
00051 bridge_ornamented_rep::initialize () {
00052   last= N(st)-1;
00053   if (is_nil(body)) body= make_bridge (ttt, st[last], descend (ip, last));
00054   else replace_bridge (body, st[last], descend (ip, last));
00055 }
00056 
00057 /******************************************************************************
00058 * Event notification
00059 ******************************************************************************/
00060 
00061 void
00062 bridge_ornamented_rep::notify_assign (path p, tree u) {
00063   // cout << "Assign " << p << ", " << u << " in " << st << "\n";
00064   if (is_nil (p)) {
00065     st= u;
00066     initialize ();
00067   }
00068   else {
00069     bool mp_flag= is_multi_paragraph (st);
00070     if (p->item == last) {
00071       if (is_atom (p)) body= make_bridge (ttt, u, descend (ip, last));
00072       else body->notify_assign (p->next, u);
00073       st= substitute (st, p->item, body->st);
00074     }
00075     else {
00076       st= substitute (st, p, u);
00077       body->notify_change ();
00078     }
00079     if (mp_flag != is_multi_paragraph (st)) initialize ();
00080   }
00081   status= CORRUPTED;
00082 }
00083 
00084 void
00085 bridge_ornamented_rep::notify_insert (path p, tree u) {
00086   // cout << "Insert " << p << ", " << u << " in " << st << "\n";
00087   ASSERT (!is_nil (p), "nil path");
00088   if (is_atom (p) || (p->item != last)) bridge_rep::notify_insert (p, u);
00089   else {
00090     bool mp_flag= is_multi_paragraph (st);
00091     body->notify_insert (p->next, u);
00092     st= substitute (st, last, body->st);
00093     if (mp_flag != is_multi_paragraph (st)) initialize ();
00094   }
00095   status= CORRUPTED;
00096 }
00097 
00098 void
00099 bridge_ornamented_rep::notify_remove (path p, int nr) {
00100   // cout << "Remove " << p << ", " << nr << " in " << st << "\n";
00101   ASSERT (!is_nil (p), "nil path");
00102   if (is_atom (p) || (p->item != last)) bridge_rep::notify_remove (p, nr);
00103   else {
00104     bool mp_flag= is_multi_paragraph (st);
00105     body->notify_remove (p->next, nr);
00106     st= substitute (st, last, body->st);
00107     if (mp_flag != is_multi_paragraph (st)) initialize ();
00108   }
00109   status= CORRUPTED;
00110 }
00111 
00112 bool
00113 bridge_ornamented_rep::notify_macro (
00114   int type, string var, int l, path p, tree u)
00115 {
00116   //cout << "Notify macro " << type << ", " << var << ", " << l
00117   //     << ", " << p << ", " << u << " in " << st << "\n";
00118   bool flag= body->notify_macro (type, var, l, p, u);
00119   flag= flag || env->depends (st (0, last), var, l);
00120   if (flag) status= CORRUPTED;
00121   return flag;
00122 }
00123 
00124 void
00125 bridge_ornamented_rep::notify_change () {
00126   status= CORRUPTED;
00127   body->notify_change ();
00128 }
00129 
00130 /******************************************************************************
00131 * Typesetting
00132 ******************************************************************************/
00133 
00134 void
00135 bridge_ornamented_rep::my_exec_until (path p) {
00136   for (int i=0; i<N(with)-1; i+=2)
00137     env->monitored_write_update (with[i]->label, with[i+1]);
00138   body->exec_until (p->next);
00139 }
00140 
00141 bool
00142 bridge_ornamented_rep::my_typeset_will_be_complete () {
00143   if (status != CORRUPTED) return false;
00144   return body->my_typeset_will_be_complete ();
00145 }
00146 
00147 static box
00148 make_ornament_body (path ip, array<page_item> l) {
00149   int i, n= N(l);
00150   array<box> lines_bx (n);
00151   array<SI>  lines_ht (n);
00152   for (i=0; i<n; i++) {
00153     page_item item= copy (l[i]);
00154     lines_bx[i]= item->b;
00155     lines_ht[i]= item->spc->def;
00156   }
00157   box b= stack_box (ip, lines_bx, lines_ht);
00158   SI dy= n==0? 0: b[0]->y2;
00159   return move_box (decorate (ip), stack_box (ip, lines_bx, lines_ht), 0, dy);
00160 }
00161 
00162 box
00163 bridge_ornamented_rep::typeset_ornament (int desired_status) {
00164   int i;
00165   tree old (TUPLE, N(with));
00166   for (i=0; i<N(with)-1; i+=2) {
00167     old[i+1]= env->read (with[i]->label);
00168     env->write_update (with[i]->label, with[i+1]);
00169   }
00170   array<page_item> l2;
00171   stack_border sb2;
00172   array<line_item> a2, b2;
00173   ttt->local_start (l2, sb2);
00174   a2= ttt->a; b2= ttt->b;
00175   ttt->a= array<line_item> (); ttt->b= array<line_item> ();
00176   body->typeset (desired_status);
00177   ttt->a= a2; ttt->b= b2;
00178   ttt->local_end (l2, sb2);
00179   for (i-=2; i>=0; i-=2)
00180     env->write_update (with[i]->label, old[i+1]);
00181   return make_ornament_body (ip, l2);
00182 }
00183 
00184 void
00185 bridge_ornamented_rep::insert_ornament (box b) {
00186   /*
00187   ttt->insert_marker (st, ip);
00188   array<page_item> l2= array<page_item> (1);
00189   l2[0]= page_item (b);
00190   ttt->insert_stack (l2, stack_border ());
00191   */
00192   lazy_paragraph par (env, ip);
00193   par->a= copy (ttt->a);
00194   par->a << line_item (STD_ITEM, env->mode_op, b, HYPH_INVALID);
00195   par->a << ttt->b;
00196   par->format_paragraph ();
00197   ttt->insert_stack (par->sss->l, par->sss->sb);
00198 }
00199 
00200 /******************************************************************************
00201 * Canvases
00202 ******************************************************************************/
00203 
00204 class bridge_canvas_rep: public bridge_ornamented_rep {
00205 public:
00206   bridge_canvas_rep (typesetter ttt, tree st, path ip):
00207     bridge_ornamented_rep (ttt, st, ip) {}
00208   void my_typeset (int desired_status);
00209 };
00210 
00211 bridge
00212 bridge_canvas (typesetter ttt, tree st, path ip) {
00213   return tm_new<bridge_canvas_rep> (ttt, st, ip);
00214 }
00215 
00216 void
00217 bridge_canvas_rep::my_typeset (int desired_status) {
00218   canvas_properties props= get_canvas_properties (env, st);
00219 
00220   SI delta= 0;
00221   string type= props->type;
00222   if (type != "plain") {
00223     SI hpad= props->hpadding;
00224     SI w   = props->bar_width;
00225     SI pad = props->bar_padding;
00226     SI bor = props->border;
00227     if (ends (type, "w") || ends (type, "e"))
00228       delta= max (0, w + pad);
00229     delta += 2 * bor + 2 * hpad;
00230   }
00231   SI l= env->get_length (PAR_LEFT);
00232   SI r= env->get_length (PAR_RIGHT) + delta;
00233   with= tuple (PAR_LEFT, tree (TMLEN, as_string (0))) *
00234         tuple (PAR_RIGHT, tree (TMLEN, as_string (l + r)));
00235 
00236   box b = typeset_ornament (desired_status);
00237 
00238   SI x1, y1, x2, y2, scx, scy;
00239   get_canvas_horizontal (props, b->x1, b->x2, x1, x2, scx);
00240   get_canvas_vertical (props, b->y1, b->y2, y1, y2, scy);
00241   path dip= (type == "plain"? ip: decorate (ip));
00242   box cb= clip_box (dip, b, x1, y1, x2, y2, props->xt, props->yt, scx, scy);
00243   if (type != "plain") cb= put_scroll_bars (props, cb, ip, b, scx, scy);
00244   insert_ornament (cb);
00245   //insert_ornament (remember_box (decorate (ip), cb));
00246 }
00247 
00248 /******************************************************************************
00249 * Hightlighting
00250 ******************************************************************************/
00251 
00252 class bridge_ornament_rep: public bridge_ornamented_rep {
00253 public:
00254   bridge_ornament_rep (typesetter ttt, tree st, path ip):
00255     bridge_ornamented_rep (ttt, st, ip) {}
00256   void my_typeset (int desired_status);
00257 };
00258 
00259 bridge
00260 bridge_ornament (typesetter ttt, tree st, path ip) {
00261   return tm_new<bridge_ornament_rep> (ttt, st, ip);
00262 }
00263 
00264 void
00265 bridge_ornament_rep::my_typeset (int desired_status) {
00266   SI    w     = env->get_length (ORNAMENT_BORDER);
00267   SI    xpad  = env->get_length (ORNAMENT_HPADDING);
00268   SI    ypad  = env->get_length (ORNAMENT_VPADDING);
00269   tree  bg    = env->read       (ORNAMENT_COLOR);
00270   int   a     = env->alpha;
00271   color sunny = env->get_color  (ORNAMENT_SUNNY_COLOR);
00272   color shadow= env->get_color  (ORNAMENT_SHADOW_COLOR);
00273   SI    l     = env->get_length (PAR_LEFT ) + w + xpad;
00274   SI    r     = env->get_length (PAR_RIGHT) + w + xpad;
00275   with        = tuple (PAR_LEFT , tree (TMLEN, as_string (l))) *
00276                 tuple (PAR_RIGHT, tree (TMLEN, as_string (r)));
00277   box   b     = typeset_ornament (desired_status);
00278   box   hb    = highlight_box (ip, b, w, xpad, ypad, bg, a, sunny, shadow);
00279   box   mb    = move_box (decorate (ip), hb, -l, 0);
00280   insert_ornament (remember_box (decorate (ip), mb));
00281 }