1 //
2 // "$Id: Fl_Button.cxx 6589 2008-12-17 10:47:09Z fabien $"
3 //
4 // Button widget for the Fast Light Tool Kit (FLTK).
5 //
6 // Copyright 1998-2006 by Bill Spitzak and others.
7 //
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.
12 //
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.
17 //
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
21 // USA.
22 //
23 // Please report all bugs and problems on the following page:
24 //
25 // http://www.fltk.org/str.php
26 //
27
28 #include <FL/Fl.H>
29 #include <FL/Fl_Button.H>
30 #include <FL/Fl_Group.H>
31 #include <FL/Fl_Window.H>
32
33 // There are a lot of subclasses, named Fl_*_Button. Some of
34 // them are implemented by setting the type() value and testing it
35 // here. This includes Fl_Radio_Button and Fl_Toggle_Button
36
value(int v)37 int Fl_Button::value(int v) {
38 v = v ? 1 : 0;
39 oldval = v;
40 clear_changed();
41 if (value_ != v) {
42 value_ = v;
43 if (box()) redraw();
44 else redraw_label();
45 return 1;
46 } else {
47 return 0;
48 }
49 }
50
setonly()51 void Fl_Button::setonly() { // set this radio button on, turn others off
52 value(1);
53 Fl_Group* g = (Fl_Group*)parent();
54 Fl_Widget*const* a = g->array();
55 for (int i = g->children(); i--;) {
56 Fl_Widget* o = *a++;
57 if (o != this && o->type()==FL_RADIO_BUTTON) ((Fl_Button*)o)->value(0);
58 }
59 }
60
draw()61 void Fl_Button::draw() {
62 if (type() == FL_HIDDEN_BUTTON) return;
63 Fl_Color col = value() ? selection_color() : color();
64 draw_box(value() ? (down_box()?down_box():fl_down(box())) : box(), col);
65 if (labeltype() == FL_NORMAL_LABEL && value()) {
66 Fl_Color c = labelcolor();
67 labelcolor(fl_contrast(c, col));
68 draw_label();
69 labelcolor(c);
70 } else draw_label();
71 if (Fl::focus() == this) draw_focus();
72 }
73
handle(int event)74 int Fl_Button::handle(int event) {
75 int newval;
76 switch (event) {
77 case FL_ENTER:
78 case FL_LEAVE:
79 // if ((value_?selection_color():color())==FL_GRAY) redraw();
80 return 1;
81 case FL_PUSH:
82 if (Fl::visible_focus() && handle(FL_FOCUS)) Fl::focus(this);
83 case FL_DRAG:
84 if (Fl::event_inside(this)) {
85 if (type() == FL_RADIO_BUTTON) newval = 1;
86 else newval = !oldval;
87 } else
88 {
89 clear_changed();
90 newval = oldval;
91 }
92 if (newval != value_) {
93 value_ = newval;
94 set_changed();
95 redraw();
96 if (when() & FL_WHEN_CHANGED) do_callback();
97 }
98 return 1;
99 case FL_RELEASE:
100 if (value_ == oldval) {
101 if (when() & FL_WHEN_NOT_CHANGED) do_callback();
102 return 1;
103 }
104 set_changed();
105 if (type() == FL_RADIO_BUTTON) setonly();
106 else if (type() == FL_TOGGLE_BUTTON) oldval = value_;
107 else {
108 value(oldval);
109 set_changed();
110 if (when() & FL_WHEN_CHANGED) do_callback();
111 }
112 if (when() & FL_WHEN_RELEASE) do_callback();
113 return 1;
114 case FL_SHORTCUT:
115 if (!(shortcut() ?
116 Fl::test_shortcut(shortcut()) : test_shortcut())) return 0;
117
118 if (Fl::visible_focus() && handle(FL_FOCUS)) Fl::focus(this);
119
120 if (type() == FL_RADIO_BUTTON && !value_) {
121 setonly();
122 set_changed();
123 if (when() & (FL_WHEN_CHANGED|FL_WHEN_RELEASE))
124 do_callback();
125 } else if (type() == FL_TOGGLE_BUTTON) {
126 value(!value());
127 set_changed();
128 if (when() & (FL_WHEN_CHANGED|FL_WHEN_RELEASE))
129 do_callback();
130 } else if (when() & FL_WHEN_RELEASE) do_callback();
131 return 1;
132 case FL_FOCUS :
133 case FL_UNFOCUS :
134 if (Fl::visible_focus()) {
135 if (box() == FL_NO_BOX) {
136 // Widgets with the FL_NO_BOX boxtype need a parent to
137 // redraw, since it is responsible for redrawing the
138 // background...
139 int X = x() > 0 ? x() - 1 : 0;
140 int Y = y() > 0 ? y() - 1 : 0;
141 if (window()) window()->damage(FL_DAMAGE_ALL, X, Y, w() + 2, h() + 2);
142 } else redraw();
143 return 1;
144 } else return 0;
145 case FL_KEYBOARD :
146 if (Fl::focus() == this && Fl::event_key() == ' ' &&
147 !(Fl::event_state() & (FL_SHIFT | FL_CTRL | FL_ALT | FL_META))) {
148 set_changed();
149 if (type() == FL_RADIO_BUTTON && !value_) {
150 setonly();
151 if (when() & FL_WHEN_CHANGED) do_callback();
152 } else if (type() == FL_TOGGLE_BUTTON) {
153 value(!value());
154 if (when() & FL_WHEN_CHANGED) do_callback();
155 }
156 if (when() & FL_WHEN_RELEASE) do_callback();
157 return 1;
158 }
159 default:
160 return 0;
161 }
162 }
163
Fl_Button(int X,int Y,int W,int H,const char * l)164 Fl_Button::Fl_Button(int X, int Y, int W, int H, const char *l)
165 : Fl_Widget(X,Y,W,H,l) {
166 box(FL_UP_BOX);
167 down_box(FL_NO_BOX);
168 value_ = oldval = 0;
169 shortcut_ = 0;
170 set_flag(SHORTCUT_LABEL);
171 }
172
173 //
174 // End of "$Id: Fl_Button.cxx 6589 2008-12-17 10:47:09Z fabien $".
175 //
176