|
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) ![]() |
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 //