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