2 // "$Id: Fl_Button.cxx 7903 2010-11-28 21:06:39Z matt $"
4 // Button widget for the Fast Light Tool Kit (FLTK).
6 // Copyright 1998-2010 by Bill Spitzak and others.
8 // This library is free software; you can redistribute it and/or
9 // modify it under the terms of the GNU Library General Public
10 // License as published by the Free Software Foundation; either
11 // version 2 of the License, or (at your option) any later version.
13 // This library is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 // Library General Public License for more details.
18 // You should have received a copy of the GNU Library General Public
19 // License along with this library; if not, write to the Free Software
20 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
23 // Please report all bugs and problems on the following page:
25 // http://www.fltk.org/str.php
29 #include <FL/Fl_Button.H>
30 #include <FL/Fl_Group.H>
31 #include <FL/Fl_Window.H>
34 Fl_Widget_Tracker
*Fl_Button::key_release_tracker
= 0;
37 // There are a lot of subclasses, named Fl_*_Button. Some of
38 // them are implemented by setting the type() value and testing it
39 // here. This includes Fl_Radio_Button and Fl_Toggle_Button
42 Sets the current value of the button.
43 A non-zero value sets the button to 1 (ON), and zero sets it to 0 (OFF).
44 \param[in] v button value.
47 int Fl_Button::value(int v
) {
62 Turns on this button and turns off all other radio buttons in the group
63 (calling \c value(1) or \c set() does not do this).
65 void Fl_Button::setonly() { // set this radio button on, turn others off
67 Fl_Group
* g
= parent();
68 Fl_Widget
*const* a
= g
->array();
69 for (int i
= g
->children(); i
--;) {
71 if (o
!= this && o
->type()==FL_RADIO_BUTTON
) ((Fl_Button
*)o
)->value(0);
75 void Fl_Button::draw() {
76 if (type() == FL_HIDDEN_BUTTON
) return;
77 Fl_Color col
= value() ? selection_color() : color();
78 draw_box(value() ? (down_box()?down_box():fl_down(box())) : box(), col
);
80 if (labeltype() == FL_NORMAL_LABEL
&& value()) {
81 Fl_Color c
= labelcolor();
82 labelcolor(fl_contrast(c
, col
));
86 if (Fl::focus() == this) draw_focus();
89 int Fl_Button::handle(int event
) {
92 case FL_ENTER
: /* FALLTHROUGH */
94 // if ((value_?selection_color():color())==FL_GRAY) redraw();
97 if (Fl::visible_focus() && handle(FL_FOCUS
)) Fl::focus(this);
99 if (Fl::event_inside(this)) {
100 if (type() == FL_RADIO_BUTTON
) newval
= 1;
101 else newval
= !oldval
;
107 if (newval
!= value_
) {
111 if (when() & FL_WHEN_CHANGED
) do_callback();
115 if (value_
== oldval
) {
116 if (when() & FL_WHEN_NOT_CHANGED
) do_callback();
120 if (type() == FL_RADIO_BUTTON
) setonly();
121 else if (type() == FL_TOGGLE_BUTTON
) oldval
= value_
;
125 if (when() & FL_WHEN_CHANGED
) {
126 Fl_Widget_Tracker
wp(this);
128 if (wp
.deleted()) return 1;
131 if (when() & FL_WHEN_RELEASE
) do_callback();
135 Fl::test_shortcut(shortcut()) : test_shortcut())) return 0;
136 if (Fl::visible_focus() && handle(FL_FOCUS
)) Fl::focus(this);
137 goto triggered_by_keyboard
;
138 case FL_FOCUS
: /* FALLTHROUGH */
140 if (Fl::visible_focus()) {
141 if (box() == FL_NO_BOX
) {
142 // Widgets with the FL_NO_BOX boxtype need a parent to
143 // redraw, since it is responsible for redrawing the
145 int X
= x() > 0 ? x() - 1 : 0;
146 int Y
= y() > 0 ? y() - 1 : 0;
147 if (window()) window()->damage(FL_DAMAGE_ALL
, X
, Y
, w() + 2, h() + 2);
152 if (Fl::focus() == this && Fl::event_key() == ' ' &&
153 !(Fl::event_state() & (FL_SHIFT
| FL_CTRL
| FL_ALT
| FL_META
))) {
155 triggered_by_keyboard
:
156 Fl_Widget_Tracker
wp(this);
157 if (type() == FL_RADIO_BUTTON
&& !value_
) {
159 if (when() & FL_WHEN_CHANGED
) do_callback();
160 } else if (type() == FL_TOGGLE_BUTTON
) {
162 if (when() & FL_WHEN_CHANGED
) do_callback();
164 simulate_key_action();
166 if (wp
.deleted()) return 1;
167 if (when() & FL_WHEN_RELEASE
) do_callback();
175 void Fl_Button::simulate_key_action()
177 if (key_release_tracker
) {
178 Fl::remove_timeout(key_release_timeout
, key_release_tracker
);
179 key_release_timeout(key_release_tracker
);
183 key_release_tracker
= new Fl_Widget_Tracker(this);
184 Fl::add_timeout(0.15, key_release_timeout
, key_release_tracker
);
187 void Fl_Button::key_release_timeout(void *d
)
189 Fl_Widget_Tracker
*wt
= (Fl_Widget_Tracker
*)d
;
192 if (wt
==key_release_tracker
)
193 key_release_tracker
= 0L;
194 Fl_Button
*btn
= (Fl_Button
*)wt
->widget();
203 The constructor creates the button using the given position, size and label.
204 \param[in] X, Y, W, H position and size of the widget
205 \param[in] L widget label, default is no label
207 Fl_Button::Fl_Button(int X
, int Y
, int W
, int H
, const char *L
)
208 : Fl_Widget(X
,Y
,W
,H
,L
) {
213 set_flag(SHORTCUT_LABEL
);
217 // End of "$Id: Fl_Button.cxx 7903 2010-11-28 21:06:39Z matt $".