Back to index

texmacs  1.0.7.15
tabs_widget.cpp
Go to the documentation of this file.
00001 
00002 /******************************************************************************
00003 * MODULE     : tabs_widget.cpp
00004 * DESCRIPTION: display one among several tabs
00005 * COPYRIGHT  : (C) 2012  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/composite_widget.hpp"
00014 #include "Widkit/layout.hpp"
00015 
00016 #define THIS (wk_widget (this))
00017 
00018 void abs_round (SI& l);
00019 void refresh_size (widget wid, bool exact);
00020 
00021 /******************************************************************************
00022 * Horizontal lists
00023 ******************************************************************************/
00024 
00025 class tabs_widget_rep: public composite_widget_rep {
00026 public:
00027   array<SI> xs;
00028   SI h1, h2;
00029   tabs_widget_rep (array<wk_widget> a, array<wk_widget> b);
00030   operator tree ();
00031 
00032   void handle_get_size (get_size_event ev);
00033   void handle_position (position_event ev);
00034   void handle_repaint (repaint_event ev);
00035   void handle_find_child (find_child_event ev);
00036   void handle_mouse (mouse_event ev);
00037 };
00038 
00039 array<wk_widget>
00040 tabs_make (array<wk_widget> a, array<wk_widget> b) {
00041   array<wk_widget> copy_a= copy (a);
00042   array<string> names;
00043   for (int i=0; i<N(a); i++) names << as_string (i);
00044   copy_a << switch_widget (b, names, 0);
00045   return copy_a;
00046 }
00047 
00048 tabs_widget_rep::tabs_widget_rep (array<wk_widget> a, array<wk_widget> b):
00049   composite_widget_rep (tabs_make (a, b), south_west),
00050   xs (), h1 (0), h2 (0) {}
00051 
00052 tabs_widget_rep::operator tree () {
00053   int i;
00054   tree t (TUPLE, N(a)+1);
00055   t[0]= "tabs";
00056   for (i=0; i<N(a); i++) t[i+1]= (tree) a[i];
00057   return t;
00058 }
00059 
00060 void
00061 tabs_widget_rep::handle_get_size (get_size_event ev) {
00062   SI& w= ev->w;
00063   SI& h= ev->h;
00064 
00065   int i, l=N(a)-1, ww=0, hh=0;
00066   for (i=0; i<l; i++) {
00067     int www= w, hhh= h;
00068     a[i] << get_size (www, hhh, -1);
00069     ww= ww+ www + 2*PIXEL;
00070     hh= max (hh, hhh);
00071   }
00072   int www= w, hhh= h - hh;
00073   a[l] << get_size (www, hhh, ev->mode);
00074   w= max (ww, www); h= hh + hhh + 3*PIXEL;
00075 }
00076 
00077 void
00078 tabs_widget_rep::handle_position (position_event ev) {
00079   (void) ev;
00080 
00081   int i, l= N(a)-1, tot_w= 0, max_h= 0;
00082   for (i=0; i<l; i++) {
00083     SI the_w= w, the_h= h;
00084     a[i] << get_size (the_w, the_h, -1);
00085     abs_round (the_w);
00086     abs_round (the_h);
00087     tot_w += the_w + 2*PIXEL;
00088     max_h= max (max_h, the_h);
00089   }
00090   SI last_w= w, last_h= h;
00091   a[l] << get_size (last_w, last_h, 0);
00092   abs_round (last_w);
00093   abs_round (last_h);
00094   SI main_w= max (tot_w, last_w);
00095   SI main_h= max_h + last_h;
00096   abs_round (main_w);
00097   abs_round (main_h);
00098   xs= array<SI> (); xs << 0;
00099   int cur_w= 0;
00100   for (i=0; i<l; i++) {
00101     SI the_w= w, the_h= h;
00102     a[i] << get_size (the_w, the_h, -1);
00103     abs_round (the_w);
00104     abs_round (the_h);
00105     a[i] << emit_position (cur_w + PIXEL, last_h + 2*PIXEL,
00106                            the_w, max_h, south_west);
00107     cur_w += the_w + 2*PIXEL;
00108     xs << cur_w;
00109   }
00110   a[l] << emit_position (0, 0, w, last_h, south_west);
00111   h1= last_h; h2= max_h;
00112 }
00113 
00114 void
00115 tabs_widget_rep::handle_repaint (repaint_event ev) { (void) ev;
00116   renderer ren= win->get_renderer ();
00117   layout_default (ren, 0, 0, w, h);
00118   if (h1 == 0 || h2 == 0 || N(xs) == 0) return;
00119 
00120   int l= N(a)-1, focus= 0;
00121   a[l] << get_integer ("switch", focus);
00122   color pastel= layout_pastel (ren);
00123   color dark= layout_dark (ren);
00124   SI fx1= xs[focus] - PIXEL;
00125   SI fx2= xs[focus+1] - PIXEL;
00126   SI top= h1 + h2 + 2*PIXEL;
00127   SI lim= xs[N(xs)-1];
00128 
00129   ren->set_line_style (PIXEL);
00130   ren->set_color (pastel);
00131   if (focus > 0)
00132     ren->line (0, h1, fx1, h1);
00133   ren->line (fx2, h1, w, h1);
00134   ren->set_color (dark);
00135   if (focus > 0)
00136     ren->line (0, h1 + PIXEL, fx1, h1 + PIXEL);
00137   ren->line (fx2, h1 + PIXEL, w, h1 + PIXEL);
00138   ren->set_color (dark);
00139   ren->line (0, top, lim - PIXEL, top);
00140   for (int i=0; i<l; i++) {
00141     ren->set_color (pastel);
00142     ren->line (xs[i], h1+2*PIXEL, xs[i], top - PIXEL);
00143     ren->set_color (dark);
00144     ren->line (xs[i+1]-PIXEL, h1+2*PIXEL, xs[i+1]-PIXEL, top - PIXEL);
00145   }
00146 }
00147 
00148 void
00149 tabs_widget_rep::handle_find_child (find_child_event ev) {
00150   int& i= ev->which;
00151   int l= N(a) - 1;
00152   if (ev->y < a[l]->y2() - oy) {
00153     i=l; return; }
00154   for (i=0; i<l; i++)
00155     if ((ev->x >= a[i]->x1()-ox) && (ev->x < a[i]->x2()-ox)) return;
00156   i= -1;
00157 }
00158 
00159 void
00160 tabs_widget_rep::handle_mouse (mouse_event ev) {
00161   int    l= N(a) - 1;
00162   string type= ev->type;
00163   SI     x= ev->x, y= ev->y;
00164   int    focus;
00165   THIS << emit_find_child (x, y, focus);
00166   if (focus >= 0 && focus < l &&
00167       (type == "release-left" || type == "release-right")) {
00168     a[l] << set_integer ("switch", focus);
00169     THIS << emit_update ();
00170     THIS << emit_reposition ();
00171     refresh_size (win->get_widget (), true);
00172   }
00173   else composite_widget_rep::handle_mouse (ev);
00174 }
00175 
00176 /******************************************************************************
00177 * Interface
00178 ******************************************************************************/
00179 
00180 wk_widget
00181 tabs_widget (array<wk_widget> a, array<wk_widget> b) {
00182   return tm_new<tabs_widget_rep> (a, b);
00183 }