1 //
2 // "$Id: Fl_Counter.cxx 5190 2006-06-09 16:16:34Z mike $"
3 //
4 // Counter widget for the Fast Light Tool Kit (FLTK).
5 //
6 // Copyright 1998-2005 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_Counter.H>
30 #include <FL/fl_draw.H>
31 
draw()32 void Fl_Counter::draw() {
33   int i; Fl_Boxtype boxtype[5];
34   Fl_Color selcolor;
35 
36   boxtype[0] = box();
37   if (boxtype[0] == FL_UP_BOX) boxtype[0] = FL_DOWN_BOX;
38   if (boxtype[0] == FL_THIN_UP_BOX) boxtype[0] = FL_THIN_DOWN_BOX;
39   for (i=1; i<5; i++)
40     if (mouseobj == i)
41       boxtype[i] = fl_down(box());
42     else
43       boxtype[i] = box();
44 
45   int xx[5], ww[5];
46   if (type() == FL_NORMAL_COUNTER) {
47     int W = w()*15/100;
48     xx[1] = x();	 ww[1] = W;
49     xx[2] = x()+1*W;     ww[2] = W;
50     xx[0] = x()+2*W;     ww[0] = w()-4*W;
51     xx[3] = x()+w()-2*W; ww[3] = W;
52     xx[4] = x()+w()-1*W; ww[4] = W;
53   } else {
54     int W = w()*20/100;
55     xx[1] = 0;	         ww[1] = 0;
56     xx[2] = x();	 ww[2] = W;
57     xx[0] = x()+W;	 ww[0] = w()-2*W;
58     xx[3] = x()+w()-1*W; ww[3] = W;
59     xx[4] = 0;	         ww[4] = 0;
60   }
61 
62   draw_box(boxtype[0], xx[0], y(), ww[0], h(), FL_BACKGROUND2_COLOR);
63   fl_font(textfont(), textsize());
64   fl_color(active_r() ? textcolor() : fl_inactive(textcolor()));
65   char str[128]; format(str);
66   fl_draw(str, xx[0], y(), ww[0], h(), FL_ALIGN_CENTER);
67   if (Fl::focus() == this) draw_focus(boxtype[0], xx[0], y(), ww[0], h());
68   if (!(damage()&FL_DAMAGE_ALL)) return; // only need to redraw text
69 
70   if (active_r())
71     selcolor = labelcolor();
72   else
73     selcolor = fl_inactive(labelcolor());
74 
75   if (type() == FL_NORMAL_COUNTER) {
76     draw_box(boxtype[1], xx[1], y(), ww[1], h(), color());
77     fl_draw_symbol("@-4<<", xx[1], y(), ww[1], h(), selcolor);
78   }
79   draw_box(boxtype[2], xx[2], y(), ww[2], h(), color());
80   fl_draw_symbol("@-4<",  xx[2], y(), ww[2], h(), selcolor);
81   draw_box(boxtype[3], xx[3], y(), ww[3], h(), color());
82   fl_draw_symbol("@-4>",  xx[3], y(), ww[3], h(), selcolor);
83   if (type() == FL_NORMAL_COUNTER) {
84     draw_box(boxtype[4], xx[4], y(), ww[4], h(), color());
85     fl_draw_symbol("@-4>>", xx[4], y(), ww[4], h(), selcolor);
86   }
87 }
88 
increment_cb()89 void Fl_Counter::increment_cb() {
90   if (!mouseobj) return;
91   double v = value();
92   switch (mouseobj) {
93   case 1: v -= lstep_; break;
94   case 2: v = increment(v, -1); break;
95   case 3: v = increment(v, 1); break;
96   case 4: v += lstep_; break;
97   }
98   handle_drag(clamp(round(v)));
99 }
100 
101 #define INITIALREPEAT .5
102 #define REPEAT .1
103 
repeat_callback(void * v)104 void Fl_Counter::repeat_callback(void* v) {
105   Fl_Counter* b = (Fl_Counter*)v;
106   if (b->mouseobj) {
107     Fl::add_timeout(REPEAT, repeat_callback, b);
108     b->increment_cb();
109   }
110 }
111 
calc_mouseobj()112 int Fl_Counter::calc_mouseobj() {
113   if (type() == FL_NORMAL_COUNTER) {
114     int W = w()*15/100;
115     if (Fl::event_inside(x(), y(), W, h())) return 1;
116     if (Fl::event_inside(x()+W, y(), W, h())) return 2;
117     if (Fl::event_inside(x()+w()-2*W, y(), W, h())) return 3;
118     if (Fl::event_inside(x()+w()-W, y(), W, h())) return 4;
119   } else {
120     int W = w()*20/100;
121     if (Fl::event_inside(x(), y(), W, h())) return 2;
122     if (Fl::event_inside(x()+w()-W, y(), W, h())) return 3;
123   }
124   return -1;
125 }
126 
handle(int event)127 int Fl_Counter::handle(int event) {
128   int i;
129   switch (event) {
130   case FL_RELEASE:
131     if (mouseobj) {
132       Fl::remove_timeout(repeat_callback, this);
133       mouseobj = 0;
134       redraw();
135     }
136     handle_release();
137     return 1;
138   case FL_PUSH:
139     if (Fl::visible_focus()) Fl::focus(this);
140     handle_push();
141   case FL_DRAG:
142     i = calc_mouseobj();
143     if (i != mouseobj) {
144       Fl::remove_timeout(repeat_callback, this);
145       mouseobj = (uchar)i;
146       if (i) Fl::add_timeout(INITIALREPEAT, repeat_callback, this);
147       increment_cb();
148       redraw();
149     }
150     return 1;
151   case FL_KEYBOARD :
152     switch (Fl::event_key()) {
153       case FL_Left:
154 	handle_drag(clamp(increment(value(),-1)));
155 	return 1;
156       case FL_Right:
157 	handle_drag(clamp(increment(value(),1)));
158 	return 1;
159       default:
160         return 0;
161     }
162     // break not required because of switch...
163   case FL_FOCUS :
164   case FL_UNFOCUS :
165     if (Fl::visible_focus()) {
166       redraw();
167       return 1;
168     } else return 0;
169   case FL_ENTER :
170   case FL_LEAVE :
171     return 1;
172   default:
173     return 0;
174   }
175 }
176 
~Fl_Counter()177 Fl_Counter::~Fl_Counter() {
178   Fl::remove_timeout(repeat_callback, this);
179 }
180 
Fl_Counter(int X,int Y,int W,int H,const char * l)181 Fl_Counter::Fl_Counter(int X, int Y, int W, int H, const char* l)
182   : Fl_Valuator(X, Y, W, H, l) {
183   box(FL_UP_BOX);
184   selection_color(FL_INACTIVE_COLOR); // was FL_BLUE
185   align(FL_ALIGN_BOTTOM);
186   bounds(-1000000.0, 1000000.0);
187   Fl_Valuator::step(1, 10);
188   lstep_ = 1.0;
189   mouseobj = 0;
190   textfont_ = FL_HELVETICA;
191   textsize_ = (uchar)FL_NORMAL_SIZE;
192   textcolor_ = FL_FOREGROUND_COLOR;
193 }
194 
195 //
196 // End of "$Id: Fl_Counter.cxx 5190 2006-06-09 16:16:34Z mike $".
197 //
198