Back to index

texmacs  1.0.7.15
list_widget.cpp
Go to the documentation of this file.
00001 
00002 /******************************************************************************
00003 * MODULE     : composite_widget.cpp
00004 * DESCRIPTION: composite list widgets
00005 *              If there is space left in a list widget,
00006 *              then all items are stretched proportionally
00007 *              according to their sizes.
00008 * COPYRIGHT  : (C) 1999  Joris van der Hoeven
00009 *******************************************************************************
00010 * This software falls under the GNU general public license version 3 or later.
00011 * It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE
00012 * in the root directory or <http://www.gnu.org/licenses/gpl-3.0.html>.
00013 ******************************************************************************/
00014 
00015 #include "window.hpp"
00016 #include "Widkit/composite_widget.hpp"
00017 #include "Widkit/layout.hpp"
00018 
00019 void abs_round (SI& l);
00020 
00021 /******************************************************************************
00022 * Horizontal lists
00023 ******************************************************************************/
00024 
00025 class horizontal_list_rep: public composite_widget_rep {
00026 public:
00027   horizontal_list_rep (array<wk_widget> a);
00028   horizontal_list_rep (array<wk_widget> a, array<string> name);
00029   operator tree ();
00030 
00031   void handle_get_size (get_size_event ev);
00032   void handle_position (position_event ev);
00033   void handle_find_child (find_child_event ev);
00034 };
00035 
00036 horizontal_list_rep::horizontal_list_rep (array<wk_widget> a):
00037   composite_widget_rep (a) {}
00038 
00039 horizontal_list_rep::horizontal_list_rep (array<wk_widget> a,
00040   array<string> n):
00041   composite_widget_rep (a, n) {}
00042 
00043 horizontal_list_rep::operator tree () {
00044   int i;
00045   tree t (TUPLE, N(a)+1);
00046   t[0]= "horizontal list";
00047   for (i=0; i<N(a); i++) t[i+1]= (tree) a[i];
00048   return t;
00049 }
00050 
00051 void
00052 horizontal_list_rep::handle_get_size (get_size_event ev) {
00053   SI& w= ev->w;
00054   SI& h= ev->h;
00055 
00056   if (ev->mode==0) {
00057     SI ww= w, hh= h;
00058     this << get_size (ww, hh, 1);
00059     w= min (w, ww);
00060     h= min (h, hh);
00061     ww= w; hh= h;
00062     this << get_size (ww, hh, -1);
00063     w= ww; //max (w, ww);
00064     h= hh;
00065   }
00066   else {
00067     int i, ww=0, hh=0;
00068     for (i=0; i<N(a); i++) {
00069       int www= w/N(a), hhh= h;
00070       a[i] << get_size (www, hhh, ev->mode);
00071       ww= ww+ www;
00072       hh= max (hh, hhh);
00073     }
00074     w= ww; h= hh;
00075   }
00076 }
00077 
00078 void
00079 horizontal_list_rep::handle_position (position_event ev) {
00080   (void) ev;
00081   if (N(a)==0) return;
00082 
00083   SI min_w=w, min_h= h;
00084   this << get_size (min_w, min_h, -1);
00085   SI max_w=w, max_h= h;
00086   this << get_size (max_w, max_h,  1);
00087   double stretch;
00088   if ((max_w==min_w) || (w<min_w)) stretch= 0.0;
00089   else if (w>max_w) stretch=1.0;
00090   else stretch= ((double) (w-min_w))/((double) (max_w-min_w));
00091 
00092   int i;
00093   SI  cur_w=0;
00094   for (i=0; i<N(a); i++) {
00095     SI the_w, the_h= h;
00096     if (i<N(a)-1) {
00097       min_w= w/N(a), min_h= h;
00098       a[i] << get_size (min_w, min_h, -1);
00099       max_w= w/N(a), max_h= h;
00100       a[i] << get_size (max_w, max_h,  1);
00101       the_w= (SI) (min_w+ stretch* (max_w- min_w));
00102     }
00103     else the_w= w- cur_w;
00104     abs_round (the_w);
00105     a[i] << emit_position (cur_w, 0, the_w, the_h);
00106     cur_w+=the_w;
00107   }
00108 }
00109 
00110 void
00111 horizontal_list_rep::handle_find_child (find_child_event ev) {
00112   int& i= ev->which;
00113   for (i=0; i<N(a); i++)
00114     if ((ev->x >= a[i]->x1()-ox) && (ev->x < a[i]->x2()-ox)) return;
00115   i= -1;
00116 }
00117 
00118 /******************************************************************************
00119 * Vertical lists
00120 ******************************************************************************/
00121 
00122 class vertical_list_rep: public composite_widget_rep {
00123   bool menu_flag;
00124 public:
00125   vertical_list_rep (array<wk_widget> a, bool mf= false);
00126   vertical_list_rep (array<wk_widget> a, array<string> name);
00127   operator tree ();
00128 
00129   void handle_get_size (get_size_event ev);
00130   void handle_position (position_event ev);
00131   void handle_find_child (find_child_event ev);
00132   void handle_repaint (repaint_event ev);
00133 };
00134 
00135 vertical_list_rep::vertical_list_rep (array<wk_widget> a, bool mf):
00136   composite_widget_rep (a), menu_flag (mf) {}
00137 
00138 vertical_list_rep::vertical_list_rep (array<wk_widget> a,
00139   array<string> name):
00140     composite_widget_rep (a, name), menu_flag (false) {}
00141 
00142 vertical_list_rep::operator tree () {
00143   int i;
00144   tree t (TUPLE, N(a)+1);
00145   t[0]= "vertical list";
00146   for (i=0; i<N(a); i++) t[i+1]= (tree) a[i];
00147   return t;
00148 }
00149 
00150 void
00151 vertical_list_rep::handle_get_size (get_size_event ev) {
00152   SI& w= ev->w;
00153   SI& h= ev->h;
00154 
00155   if (menu_flag) {
00156     int i;
00157     SI m1=0, m2=0, c1=0, c2=0;
00158     for (i=0; i<N(a); i++) {
00159       a[i] << get_coord2 ("extra width", c1, c2);
00160       m1= max (m1, c1); m2= max (m2, c2);
00161     }
00162     for (i=0; i<N(a); i++)
00163       a[i] << set_coord2 ("extra width", m1, m2);
00164   }
00165 
00166   if (ev->mode==0) {
00167     SI ww= w, hh= h;
00168     this << get_size (ww, hh, 1);
00169     w= min (w, ww);
00170     h= min (h, hh);
00171     ww= w; hh= h;
00172     this << get_size (ww, hh, -1);
00173     w= ww;
00174     h= hh; //max (h, hh);
00175   }
00176   else {
00177     int i, ww=0, hh=0;
00178     for (i=0; i<N(a); i++) {
00179       int www= w, hhh= h/N(a);
00180       a[i] << get_size (www, hhh, ev->mode);
00181       ww= max (ww, www);
00182       hh= hh+ hhh;
00183     }
00184     w= ww; h= hh;
00185   }
00186 }
00187 
00188 void
00189 vertical_list_rep::handle_position (position_event ev) {
00190   (void) ev;
00191   if (N(a)==0) return;
00192 
00193   SI min_w=w, min_h= h;
00194   this << get_size (min_w, min_h, -1);
00195   SI max_w=w, max_h= h;
00196   this << get_size (max_w, max_h,  1);
00197   double stretch;
00198   if ((max_h==min_h) || (h<min_h)) stretch= 0.0;
00199   else if (h>max_h) stretch=1.0;
00200   else stretch= ((double) (h-min_h))/((double) (max_h-min_h));
00201 
00202   int i;
00203   SI  cur_h=0;
00204   for (i=0; i<N(a); i++) {
00205     SI the_w= w, the_h;
00206     //if (i<N(a)-1) {
00207     min_w= w, min_h= h/N(a);
00208     a[i] << get_size (min_w, min_h, -1);
00209     max_w= w, max_h= h/N(a);
00210     a[i] << get_size (max_w, max_h,  1);
00211     the_h= (SI) (min_h+ stretch* (max_h- min_h));
00212     //}
00213     //else the_h= h+ cur_h;
00214     abs_round (the_h);
00215     a[i] << emit_position (0, cur_h, the_w, the_h);
00216     cur_h-=the_h;
00217   }
00218 }
00219 
00220 void
00221 vertical_list_rep::handle_find_child (find_child_event ev) {
00222   int& i= ev->which;
00223   for (i=0; i<N(a); i++)
00224     if ((ev->y >= a[i]->y1()-oy) && (ev->y < a[i]->y2()-oy)) return;
00225   i= -1;
00226 }
00227 
00228 void
00229 vertical_list_rep::handle_repaint (repaint_event ev) {
00230   renderer ren= win->get_renderer ();
00231   int i= N(a)-1;
00232   SI bot= a[i]->y1()-oy;
00233   if (bot > -h) layout_default (ren, 0, -h, w, bot);
00234   basic_widget_rep::handle_repaint (ev);
00235 }
00236 
00237 /******************************************************************************
00238 * Interface
00239 ******************************************************************************/
00240 
00241 wk_widget
00242 horizontal_list (array<wk_widget> a) {
00243   return tm_new<horizontal_list_rep> (a);
00244 }
00245 
00246 wk_widget
00247 horizontal_list (array<wk_widget> a, array<string> name) {
00248   return tm_new<horizontal_list_rep> (a, name);
00249 }
00250 
00251 wk_widget
00252 vertical_list (array<wk_widget> a) {
00253   return tm_new<vertical_list_rep> (a);
00254 }
00255 
00256 wk_widget
00257 vertical_list (array<wk_widget> a, array<string> name) {
00258   return tm_new<vertical_list_rep> (a, name);
00259 }
00260 
00261 wk_widget
00262 vertical_menu (array<wk_widget> a) {
00263   return tm_new<vertical_list_rep> (a, true);
00264 }