fltk 1.3.0rc3
About: FLTK (Fast Light Tool Kit) is a cross-platform C++ GUI toolkit for UNIX/Linux (X11), Microsoft Windows, and MacOS X. Release candidate.
  SfR Fresh Dox: fltk-1.3.0rc3-source.tar.gz ("inofficial" and yet experimental doxygen-generated source code documentation)  

Fl_Button.cxx

Go to the documentation of this file.
00001 //
00002 // "$Id: Fl_Button.cxx 7903 2010-11-28 21:06:39Z matt $"
00003 //
00004 // Button widget for the Fast Light Tool Kit (FLTK).
00005 //
00006 // Copyright 1998-2010 by Bill Spitzak and others.
00007 //
00008 // This library is free software; you can redistribute it and/or
00009 // modify it under the terms of the GNU Library General Public
00010 // License as published by the Free Software Foundation; either
00011 // version 2 of the License, or (at your option) any later version.
00012 //
00013 // This library is distributed in the hope that it will be useful,
00014 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016 // Library General Public License for more details.
00017 //
00018 // You should have received a copy of the GNU Library General Public
00019 // License along with this library; if not, write to the Free Software
00020 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00021 // USA.
00022 //
00023 // Please report all bugs and problems on the following page:
00024 //
00025 //     http://www.fltk.org/str.php
00026 //
00027 
00028 #include <FL/Fl.H>
00029 #include <FL/Fl_Button.H>
00030 #include <FL/Fl_Group.H>
00031 #include <FL/Fl_Window.H>
00032 
00033 
00034 Fl_Widget_Tracker *Fl_Button::key_release_tracker = 0;
00035 
00036 
00037 // There are a lot of subclasses, named Fl_*_Button.  Some of
00038 // them are implemented by setting the type() value and testing it
00039 // here.  This includes Fl_Radio_Button and Fl_Toggle_Button
00040 
00047 int Fl_Button::value(int v) {
00048   v = v ? 1 : 0;
00049   oldval = v;
00050   clear_changed();
00051   if (value_ != v) {
00052     value_ = v;
00053     if (box()) redraw();
00054     else redraw_label();
00055     return 1;
00056   } else {
00057     return 0;
00058   }
00059 }
00060 
00065 void Fl_Button::setonly() { // set this radio button on, turn others off
00066   value(1);
00067   Fl_Group* g = parent();
00068   Fl_Widget*const* a = g->array();
00069   for (int i = g->children(); i--;) {
00070     Fl_Widget* o = *a++;
00071     if (o != this && o->type()==FL_RADIO_BUTTON) ((Fl_Button*)o)->value(0);
00072   }
00073 }
00074 
00075 void Fl_Button::draw() {
00076   if (type() == FL_HIDDEN_BUTTON) return;
00077   Fl_Color col = value() ? selection_color() : color();
00078   draw_box(value() ? (down_box()?down_box():fl_down(box())) : box(), col);
00079   draw_backdrop();
00080   if (labeltype() == FL_NORMAL_LABEL && value()) {
00081     Fl_Color c = labelcolor();
00082     labelcolor(fl_contrast(c, col));
00083     draw_label();
00084     labelcolor(c);
00085   } else draw_label();
00086   if (Fl::focus() == this) draw_focus();
00087 }
00088 
00089 int Fl_Button::handle(int event) {
00090   int newval;
00091   switch (event) {
00092   case FL_ENTER: /* FALLTHROUGH */
00093   case FL_LEAVE:
00094 //  if ((value_?selection_color():color())==FL_GRAY) redraw();
00095     return 1;
00096   case FL_PUSH:
00097     if (Fl::visible_focus() && handle(FL_FOCUS)) Fl::focus(this);
00098   case FL_DRAG:
00099     if (Fl::event_inside(this)) {
00100       if (type() == FL_RADIO_BUTTON) newval = 1;
00101       else newval = !oldval;
00102     } else
00103     {
00104       clear_changed();
00105       newval = oldval;
00106     }
00107     if (newval != value_) {
00108       value_ = newval;
00109       set_changed();
00110       redraw();
00111       if (when() & FL_WHEN_CHANGED) do_callback();
00112     }
00113     return 1;
00114   case FL_RELEASE:
00115     if (value_ == oldval) {
00116       if (when() & FL_WHEN_NOT_CHANGED) do_callback();
00117       return 1;
00118     }
00119     set_changed();
00120     if (type() == FL_RADIO_BUTTON) setonly();
00121     else if (type() == FL_TOGGLE_BUTTON) oldval = value_;
00122     else {
00123       value(oldval);
00124       set_changed();
00125       if (when() & FL_WHEN_CHANGED) {
00126         Fl_Widget_Tracker wp(this);
00127         do_callback();
00128         if (wp.deleted()) return 1;
00129       }
00130     }
00131     if (when() & FL_WHEN_RELEASE) do_callback();
00132     return 1;
00133   case FL_SHORTCUT:
00134     if (!(shortcut() ?
00135           Fl::test_shortcut(shortcut()) : test_shortcut())) return 0;    
00136     if (Fl::visible_focus() && handle(FL_FOCUS)) Fl::focus(this);
00137     goto triggered_by_keyboard;
00138   case FL_FOCUS : /* FALLTHROUGH */
00139   case FL_UNFOCUS :
00140     if (Fl::visible_focus()) {
00141       if (box() == FL_NO_BOX) {
00142         // Widgets with the FL_NO_BOX boxtype need a parent to
00143         // redraw, since it is responsible for redrawing the
00144         // background...
00145         int X = x() > 0 ? x() - 1 : 0;
00146         int Y = y() > 0 ? y() - 1 : 0;
00147         if (window()) window()->damage(FL_DAMAGE_ALL, X, Y, w() + 2, h() + 2);
00148       } else redraw();
00149       return 1;
00150     } else return 0;
00151   case FL_KEYBOARD :
00152     if (Fl::focus() == this && Fl::event_key() == ' ' &&
00153         !(Fl::event_state() & (FL_SHIFT | FL_CTRL | FL_ALT | FL_META))) {
00154       set_changed();
00155     triggered_by_keyboard:
00156       Fl_Widget_Tracker wp(this);
00157       if (type() == FL_RADIO_BUTTON && !value_) {
00158         setonly();
00159         if (when() & FL_WHEN_CHANGED) do_callback();
00160       } else if (type() == FL_TOGGLE_BUTTON) {
00161         value(!value());
00162         if (when() & FL_WHEN_CHANGED) do_callback();
00163       } else {
00164         simulate_key_action();
00165       }
00166       if (wp.deleted()) return 1;
00167       if (when() & FL_WHEN_RELEASE) do_callback();
00168       return 1;
00169     }
00170   default:
00171     return 0;
00172   }
00173 }
00174 
00175 void Fl_Button::simulate_key_action()
00176 {
00177   if (key_release_tracker) {
00178     Fl::remove_timeout(key_release_timeout, key_release_tracker);
00179     key_release_timeout(key_release_tracker);
00180   }
00181   value(1); 
00182   redraw();
00183   key_release_tracker = new Fl_Widget_Tracker(this);
00184   Fl::add_timeout(0.15, key_release_timeout, key_release_tracker);
00185 }
00186 
00187 void Fl_Button::key_release_timeout(void *d)
00188 {
00189   Fl_Widget_Tracker *wt = (Fl_Widget_Tracker*)d;
00190   if (!wt)
00191     return;
00192   if (wt==key_release_tracker) 
00193     key_release_tracker = 0L;
00194   Fl_Button *btn = (Fl_Button*)wt->widget();
00195   if (btn) {
00196     btn->value(0);
00197     btn->redraw();
00198   }
00199   delete wt;
00200 }
00201 
00207 Fl_Button::Fl_Button(int X, int Y, int W, int H, const char *L)
00208 : Fl_Widget(X,Y,W,H,L) {
00209   box(FL_UP_BOX);
00210   down_box(FL_NO_BOX);
00211   value_ = oldval = 0;
00212   shortcut_ = 0;
00213   set_flag(SHORTCUT_LABEL);
00214 }
00215 
00216 //
00217 // End of "$Id: Fl_Button.cxx 7903 2010-11-28 21:06:39Z matt $".
00218 //