Back to index

texmacs  1.0.7.15
button_widget.cpp
Go to the documentation of this file.
00001 
00002 /******************************************************************************
00003 * MODULE     : button_widget.cpp
00004 * DESCRIPTION: Buttons
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 "renderer.hpp"
00013 #include "Widkit/layout.hpp"
00014 #include "Widkit/Button/button_widget.hpp"
00015 #include "Widkit/Event/composite_event.hpp"
00016 
00017 /******************************************************************************
00018 * Routines for abstract button_widgets
00019 ******************************************************************************/
00020 
00021 button_widget_rep::button_widget_rep
00022   (wk_widget w2, bool rf2, int style2):
00023     attribute_widget_rep (1, south_west),
00024     extra_left (0), extra_right (0), rflag (rf2), style (style2),
00025     button_flag ((style2 & WIDGET_STYLE_BUTTON) != 0),
00026     enabled ((style2 & WIDGET_STYLE_INERT) == 0),
00027     centered ((style2 & WIDGET_STYLE_CENTERED) != 0),
00028     has_pull_down (false), status (false), inside (false)
00029 { a[0]= w2; }
00030     
00031 button_widget_rep::button_widget_rep
00032   (wk_widget lw, wk_widget rw, int style2):
00033     attribute_widget_rep (2, south_west),
00034     extra_left (0), extra_right (0), rflag (false), style (style2),
00035     button_flag ((style2 & WIDGET_STYLE_BUTTON) != 0),
00036     enabled ((style2 & WIDGET_STYLE_INERT) == 0),
00037     centered ((style2 & WIDGET_STYLE_CENTERED) != 0),
00038     has_pull_down (false), status (false), inside (false)
00039 { a[0]= lw; a[1]= rw; }
00040     
00041 button_widget_rep::button_widget_rep
00042   (wk_widget lw, wk_widget cw, wk_widget rw, int style2):
00043     attribute_widget_rep (3, south_west),
00044     extra_left (0), extra_right (0), rflag (false), style (style2),
00045     button_flag ((style2 & WIDGET_STYLE_BUTTON) != 0),
00046     enabled ((style2 & WIDGET_STYLE_INERT) == 0),
00047     centered ((style2 & WIDGET_STYLE_CENTERED) != 0),
00048     has_pull_down (false), status (false), inside (false)
00049 { a[0]= lw; a[1]= cw; a[2]= rw; }
00050 
00051 button_widget_rep::operator tree () {
00052   if (N(a)==1) return tree (TUPLE, "button", tree (a[0]));
00053   else if (N(a)==2) return tree (TUPLE, "button", tree (a[0]), tree (a[1]));
00054   else return tree (TUPLE, "button", tree (a[0]), tree (a[1]), tree (a[2]));
00055 }
00056 
00057 void
00058 button_widget_rep::handle_get_size (get_size_event ev) {
00059   if (N(a)==1) {
00060     attribute_widget_rep::handle_get_size (ev);
00061     if (rflag) ev->w += extra_left + max (extra_right, 16*PIXEL);
00062     else ev->w += extra_left + extra_right;
00063   }
00064   else if (N(a)==2) {
00065     SI pw1= 0, ph1= 0, pw2= 0, ph2= 0;
00066     a[0] << get_size (pw1, ph1, -1);
00067     a[1] << get_size (pw2, ph2, -1);
00068     ev->w = pw1+ extra_left+ max (extra_right, pw2);
00069     if (extra_right>0 || pw2>0) ev->w += 8*PIXEL;
00070     ev->h = max (ph1, ph2);
00071   }
00072   else {    
00073     SI pw1= 0, ph1= 0, pw2= 0, ph2= 0, pw3= 0, ph3= 0;
00074     a[0] << get_size (pw1, ph1, -1);
00075     a[1] << get_size (pw2, ph2, -1);
00076     a[2] << get_size (pw3, ph3, -1);
00077     ev->w = pw2+ max(extra_left, pw1)+ max (extra_right, pw3);
00078     if (extra_right>0 || pw3>0) ev->w += 8*PIXEL;
00079     ev->h = max (ph1, max (ph2, ph3));
00080   }
00081   abs_round (ev->w, ev->h);
00082   ev->w += 2*PIXEL;
00083   ev->h += 2*PIXEL;
00084 }
00085 
00086 void
00087 button_widget_rep::handle_position (position_event ev) {
00088   (event) ev;
00089   if (N(a)==1) {
00090     SI ww= w-2*PIXEL-extra_left;
00091     SI hh= h-2*PIXEL;
00092     if (rflag) ww -= 16*PIXEL;
00093     a[0] << emit_position (extra_left+PIXEL, PIXEL, ww, hh, south_west);
00094   }
00095   else if (N(a)==2) {
00096     SI pw1= 0, ph1= 0, pw2= 0, ph2= 0;
00097     a[0] << get_size (pw1, ph1, -1);
00098     a[1] << get_size (pw2, ph2, -1);
00099     a[0] << emit_position (extra_left+PIXEL, PIXEL, pw1, ph1, south_west);
00100     a[1] << emit_position (w-PIXEL-extra_right, PIXEL, pw2, ph2, south_west);
00101   }
00102   else {
00103     SI pw1= 0, ph1= 0, pw2= 0, ph2= 0, pw3= 0, ph3= 0;
00104     a[0] << get_size (pw1, ph1, -1);
00105     a[1] << get_size (pw2, ph2, -1);
00106     a[2] << get_size (pw3, ph3, -1);
00107     SI rounded_x, rounded_y= (h-ph1)/2; abs_round (rounded_y);
00108     a[0] << emit_position (PIXEL, rounded_y, pw1, ph1, south_west);
00109     if (centered) rounded_x= (w-pw2)/2;
00110     else rounded_x= extra_left+PIXEL;
00111     abs_round (rounded_x);
00112     a[1] << emit_position (rounded_x, PIXEL, pw2, ph2, south_west); 
00113     a[2] << emit_position (w-PIXEL-extra_right, PIXEL, pw3, ph3, south_west);
00114   }
00115 }
00116 
00117 void
00118 button_widget_rep::handle_repaint (repaint_event ev) { (void) ev;
00119   renderer ren= win->get_renderer ();
00120   layout_default (ren, 0, 0, w, h);
00121   if ((style & WIDGET_STYLE_PRESSED) != 0) {
00122     if (status) layout_higher (ren, 0, 0, w, h);
00123     else {
00124       layout_dark (ren, 0, 0, w, h);
00125       layout_lower (ren, 0, 0, w, h);
00126     }
00127   }
00128   else if (inside && !status && enabled)
00129     layout_higher (ren, 0, 0, w, h);
00130   else if (status) {
00131     layout_dark (ren, 0, 0, w, h);
00132     layout_lower (ren, 0, 0, w, h);
00133   }
00134   else if (button_flag)
00135     layout_higher (ren, 0, 0, w, h);
00136   if (rflag)
00137     layout_submenu_triangle (ren, w-10*PIXEL, h>>1);
00138   if (has_pull_down && inside && !status)
00139     //layout_pulldown_triangle (ren, 6*PIXEL, 4*PIXEL);
00140     layout_pulldown_dash (ren, 0, 0, w-2*PIXEL);
00141   //if (has_pull_down && !inside && !status)
00142   //  layout_pulldown_dash (ren, 2*PIXEL, 0, w-4*PIXEL);
00143 }
00144 
00145 void
00146 button_widget_rep::handle_get_coord2 (get_coord2_event ev) {
00147   if (ev->which != "extra width") attribute_widget_rep::handle_get_coord2 (ev);
00148   else {
00149     SI dummy;
00150     ev->c1= 0; ev->c2= 0;
00151     if (N(a) == 2) a[1] << get_size (ev->c2, dummy, -1);
00152     if (N(a) == 3) {
00153       a[0] << get_size (ev->c1, dummy, -1);
00154       a[2] << get_size (ev->c2, dummy, -1);
00155     }
00156   }
00157 }
00158 
00159 void
00160 button_widget_rep::handle_set_coord2 (set_coord2_event ev) {
00161   if (ev->which != "extra width") attribute_widget_rep::handle_set_coord2 (ev);
00162   else {
00163     extra_left = ev->c1;
00164     extra_right= ev->c2;
00165   }
00166 }
00167 
00168 /******************************************************************************
00169 * Command buttons
00170 ******************************************************************************/
00171 
00172 class command_button_rep: public button_widget_rep {
00173   command cmd;
00174 public:
00175   command_button_rep (wk_widget w, command cmd, int style);
00176   command_button_rep (wk_widget lw, wk_widget rw, command cmd, int style);
00177   command_button_rep (wk_widget lw, wk_widget cw, wk_widget rw,
00178                     command cmd, int style);
00179   void handle_mouse (mouse_event ev);
00180 };
00181 
00182 command_button_rep::command_button_rep (
00183  wk_widget w, command cmd2, int style):
00184     button_widget_rep (w, false, style), cmd (cmd2) {}
00185 
00186 command_button_rep::command_button_rep (
00187   wk_widget lw, wk_widget rw, command cmd2, int style):
00188     button_widget_rep (lw, rw, style), cmd (cmd2) {}
00189 
00190 command_button_rep::command_button_rep (
00191   wk_widget lw, wk_widget cw, wk_widget rw, command cmd2, int style):
00192     button_widget_rep (lw, cw, rw, style), cmd (cmd2) {}
00193 
00194 void
00195 command_button_rep::handle_mouse (mouse_event ev) {
00196   string type= ev->type;
00197   SI     x= ev->x, y= ev->y;
00198   // cout << "Command button[" << status << "] "
00199   //      << s << ": " << ((event) ev) << "\n";
00200 
00201   bool old_inside= inside;
00202   bool old_status= status;
00203   inside= (y>=0) && (y<h) && (x>=0) && (x<w);
00204   status= inside && enabled && (ev->pressed ("left") || ev->pressed ("right"));
00205 
00206   if (inside != old_inside || status != old_status)
00207     if (attached ())
00208       this << emit_invalidate_all ();
00209   if (status != old_status)
00210     if ((type == "release-left") || (type == "release-right"))
00211       if (!is_nil (cmd)) cmd ();
00212 }
00213 
00214 /******************************************************************************
00215 * Interface
00216 ******************************************************************************/
00217 
00218 wk_widget
00219 command_button (wk_widget w, command cmd, int style) {
00220   return tm_new<command_button_rep> (w, cmd, style);
00221 }
00222 
00223 wk_widget
00224 command_button (wk_widget lw, wk_widget rw, command cmd, int style) {
00225   return tm_new<command_button_rep> (lw, rw, cmd, style);
00226 }
00227 
00228 wk_widget
00229 command_button (wk_widget lw, wk_widget cw, wk_widget rw,
00230               command cmd, int style)
00231 {
00232   return tm_new<command_button_rep> (lw, cw, rw, cmd, style);
00233 }