1 //
2 // "$Id: Fl_Roller.cxx 7903 2010-11-28 21:06:39Z matt $"
3 //
4 // Roller widget for the Fast Light Tool Kit (FLTK).
5 //
6 // Copyright 1998-2010 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307
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 // Rapid-App style knob
29
30 #include <FL/Fl.H>
31 #include <FL/Fl_Roller.H>
32 #include <FL/fl_draw.H>
33 #include <math.h>
34
handle(int event)35 int Fl_Roller::handle(int event) {
36 static int ipos;
37 int newpos = horizontal() ? Fl::event_x() : Fl::event_y();
38 switch (event) {
39 case FL_PUSH:
40 if (Fl::visible_focus()) {
41 Fl::focus(this);
42 redraw();
43 }
44 handle_push();
45 ipos = newpos;
46 return 1;
47 case FL_DRAG:
48 handle_drag(clamp(round(increment(previous_value(),newpos-ipos))));
49 return 1;
50 case FL_RELEASE:
51 handle_release();
52 return 1;
53 case FL_KEYBOARD :
54 switch (Fl::event_key()) {
55 case FL_Up:
56 if (horizontal()) return 0;
57 handle_drag(clamp(increment(value(),-1)));
58 return 1;
59 case FL_Down:
60 if (horizontal()) return 0;
61 handle_drag(clamp(increment(value(),1)));
62 return 1;
63 case FL_Left:
64 if (!horizontal()) return 0;
65 handle_drag(clamp(increment(value(),-1)));
66 return 1;
67 case FL_Right:
68 if (!horizontal()) return 0;
69 handle_drag(clamp(increment(value(),1)));
70 return 1;
71 default:
72 return 0;
73 }
74 // break not required because of switch...
75 case FL_FOCUS :
76 case FL_UNFOCUS :
77 if (Fl::visible_focus()) {
78 redraw();
79 return 1;
80 } else return 0;
81 case FL_ENTER :
82 case FL_LEAVE :
83 return 1;
84 default:
85 return 0;
86 }
87 }
88
draw()89 void Fl_Roller::draw() {
90 if (damage()&FL_DAMAGE_ALL) draw_box();
91 int X = x()+Fl::box_dx(box());
92 int Y = y()+Fl::box_dy(box());
93 int W = w()-Fl::box_dw(box())-1;
94 int H = h()-Fl::box_dh(box())-1;
95 if (W<=0 || H <=0) return;
96 int offset = step() ? int(value()/step()) : 0;
97 const double ARC = 1.5; // 1/2 the number of radians visible
98 const double delta = .2; // radians per knurl
99 if (horizontal()) { // horizontal one
100 // draw shaded ends of wheel:
101 int h1 = W/4+1; // distance from end that shading starts
102 fl_color(color()); fl_rectf(X+h1,Y,W-2*h1,H);
103 for (int i=0; h1; i++) {
104 fl_color((Fl_Color)(FL_GRAY-i-1));
105 int h2 = FL_GRAY-i-1 > FL_DARK3 ? 2*h1/3+1 : 0;
106 fl_rectf(X+h2,Y,h1-h2,H);
107 fl_rectf(X+W-h1,Y,h1-h2,H);
108 h1 = h2;
109 }
110 if (active_r()) {
111 // draw ridges:
112 double junk;
113 for (double yy = -ARC+modf(offset*sin(ARC)/(W/2)/delta,&junk)*delta;;
114 yy += delta) {
115 int yy1 = int((sin(yy)/sin(ARC)+1)*W/2);
116 if (yy1 <= 0) continue; else if (yy1 >= W-1) break;
117 fl_color(FL_DARK3); fl_yxline(X+yy1,Y+1,Y+H-1);
118 if (yy < 0) yy1--; else yy1++;
119 fl_color(FL_LIGHT1);fl_yxline(X+yy1,Y+1,Y+H-1);
120 }
121 // draw edges:
122 h1 = W/8+1; // distance from end the color inverts
123 fl_color(FL_DARK2);
124 fl_xyline(X+h1,Y+H-1,X+W-h1);
125 fl_color(FL_DARK3);
126 fl_yxline(X,Y+H,Y,X+h1);
127 fl_xyline(X+W-h1,Y,X+W);
128 fl_color(FL_LIGHT2);
129 fl_xyline(X+h1,Y-1,X+W-h1);
130 fl_yxline(X+W,Y,Y+H,X+W-h1);
131 fl_xyline(X+h1,Y+H,X);
132 }
133 } else { // vertical one
134 // draw shaded ends of wheel:
135 int h1 = H/4+1; // distance from end that shading starts
136 fl_color(color()); fl_rectf(X,Y+h1,W,H-2*h1);
137 for (int i=0; h1; i++) {
138 fl_color((Fl_Color)(FL_GRAY-i-1));
139 int h2 = FL_GRAY-i-1 > FL_DARK3 ? 2*h1/3+1 : 0;
140 fl_rectf(X,Y+h2,W,h1-h2);
141 fl_rectf(X,Y+H-h1,W,h1-h2);
142 h1 = h2;
143 }
144 if (active_r()) {
145 // draw ridges:
146 double junk;
147 for (double yy = -ARC+modf(offset*sin(ARC)/(H/2)/delta,&junk)*delta;
148 ; yy += delta) {
149 int yy1 = int((sin(yy)/sin(ARC)+1)*H/2);
150 if (yy1 <= 0) continue; else if (yy1 >= H-1) break;
151 fl_color(FL_DARK3); fl_xyline(X+1,Y+yy1,X+W-1);
152 if (yy < 0) yy1--; else yy1++;
153 fl_color(FL_LIGHT1);fl_xyline(X+1,Y+yy1,X+W-1);
154 }
155 // draw edges:
156 h1 = H/8+1; // distance from end the color inverts
157 fl_color(FL_DARK2);
158 fl_yxline(X+W-1,Y+h1,Y+H-h1);
159 fl_color(FL_DARK3);
160 fl_xyline(X+W,Y,X,Y+h1);
161 fl_yxline(X,Y+H-h1,Y+H);
162 fl_color(FL_LIGHT2);
163 fl_yxline(X,Y+h1,Y+H-h1);
164 fl_xyline(X,Y+H,X+W,Y+H-h1);
165 fl_yxline(X+W,Y+h1,Y);
166 }
167 }
168
169 if (Fl::focus() == this) draw_focus(FL_THIN_UP_FRAME, x(), y(), w(), h());
170 }
171
172 /**
173 Creates a new Fl_Roller widget using the given position,
174 size, and label string. The default boxtype is FL_NO_BOX.
175 <P>Inherited destructor destroys the valuator.
176 */
Fl_Roller(int X,int Y,int W,int H,const char * L)177 Fl_Roller::Fl_Roller(int X,int Y,int W,int H,const char* L)
178 : Fl_Valuator(X,Y,W,H,L) {
179 box(FL_UP_BOX);
180 step(1,1000);
181 }
182
183 //
184 // End of "$Id: Fl_Roller.cxx 7903 2010-11-28 21:06:39Z matt $".
185 //
186