2 // "$Id: Fl_Scrollbar.cxx 7903 2010-11-28 21:06:39Z matt $"
4 // Scroll bar 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
30 #include <FL/Fl_Scrollbar.H>
31 #include <FL/fl_draw.H>
35 #define INITIALREPEAT .5
38 void Fl_Scrollbar::increment_cb() {
39 char inv
= maximum()<minimum();
40 int ls
= inv
? -linesize_
: linesize_
;
43 case 1: // clicked on arrow left
46 default: // clicked on arrow right
49 case 5: // clicked into the box next to the slider on the left
50 i
= -(int((maximum()-minimum())*slider_size()/(1.0-slider_size())));
54 if (i
>-ls
) i
= -ls
; // err
57 case 6: // clicked into the box next to the slider on the right
58 i
= (int((maximum()-minimum())*slider_size()/(1.0-slider_size())));
62 if (i
<ls
) i
= ls
; // err
66 handle_drag(clamp(value() + i
));
69 void Fl_Scrollbar::timeout_cb(void* v
) {
70 Fl_Scrollbar
* s
= (Fl_Scrollbar
*)v
;
72 Fl::add_timeout(REPEAT
, timeout_cb
, s
);
75 int Fl_Scrollbar::handle(int event
) {
78 int X
=x(); int Y
=y(); int W
=w(); int H
=h();
80 // adjust slider area to be inside the arrow buttons:
82 if (W
>= 3*H
) {X
+= H
; W
-= 2*H
;}
84 if (H
>= 3*W
) {Y
+= W
; H
-= 2*W
;}
87 // which widget part is highlighted?
91 relx
= Fl::event_x()-X
;
94 relx
= Fl::event_y()-Y
;
97 if (relx
< 0) area
= 1;
98 else if (relx
>= ww
) area
= 2;
100 int S
= int(slider_size()*ww
+.5);
101 int T
= (horizontal() ? H
: W
)/2+1;
102 if (type()==FL_VERT_NICE_SLIDER
|| type()==FL_HOR_NICE_SLIDER
) T
+= 4;
105 (maximum()-minimum()) ? (value()-minimum())/(maximum()-minimum()) : 0.5;
107 if (val
>= 1.0) sliderx
= ww
-S
;
108 else if (val
<= 0.0) sliderx
= 0;
109 else sliderx
= int(val
*(ww
-S
)+.5);
110 if (Fl::event_button() == FL_MIDDLE_MOUSE
) area
= 8;
111 else if (relx
< sliderx
) area
= 5;
112 else if (relx
>= sliderx
+S
) area
= 6;
123 Fl::remove_timeout(timeout_cb
, this);
129 if (pushed_
) return 1;
130 if (area
!= 8) pushed_
= area
;
133 Fl::add_timeout(INITIALREPEAT
, timeout_cb
, this);
138 return Fl_Slider::handle(event
, X
,Y
,W
,H
);
140 if (pushed_
) return 1;
141 return Fl_Slider::handle(event
, X
,Y
,W
,H
);
144 if (Fl::e_dx
==0) return 0;
145 int ls
= maximum()>=minimum() ? linesize_
: -linesize_
;
146 handle_drag(clamp(value() + ls
* Fl::e_dx
));
149 if (Fl::e_dy
==0) return 0;
150 int ls
= maximum()>=minimum() ? linesize_
: -linesize_
;
151 handle_drag(clamp(value() + ls
* Fl::e_dy
));
157 int ls
= maximum()>=minimum() ? linesize_
: -linesize_
;
159 switch (Fl::event_key()) {
170 switch (Fl::event_key()) {
178 if (slider_size() >= 1.0) return 0;
179 v
-= int((maximum()-minimum())*slider_size()/(1.0-slider_size()));
183 if (slider_size() >= 1.0) return 0;
184 v
+= int((maximum()-minimum())*slider_size()/(1.0-slider_size()));
209 void Fl_Scrollbar::draw() {
210 if (damage()&FL_DAMAGE_ALL
) draw_box();
211 int X
= x()+Fl::box_dx(box());
212 int Y
= y()+Fl::box_dy(box());
213 int W
= w()-Fl::box_dw(box());
214 int H
= h()-Fl::box_dh(box());
216 if (W
< 3*H
) {Fl_Slider::draw(X
,Y
,W
,H
); return;}
217 Fl_Slider::draw(X
+H
,Y
,W
-2*H
,H
);
218 if (damage()&FL_DAMAGE_ALL
) {
219 draw_box((pushed_
==1) ? fl_down(slider()) : slider(),
220 X
, Y
, H
, H
, selection_color());
221 draw_box((pushed_
==2) ? fl_down(slider()) : slider(),
222 X
+W
-H
, Y
, H
, H
, selection_color());
224 fl_color(labelcolor());
226 fl_color(fl_inactive(labelcolor()));
227 int w1
= (H
-4)/3; if (w1
< 1) w1
= 1;
228 int x1
= X
+(H
-w1
-1)/2;
229 int yy1
= Y
+(H
-2*w1
-1)/2;
230 if (Fl::scheme_
&& !strcmp(Fl::scheme_
, "gtk+")) {
231 fl_polygon(x1
, yy1
+w1
, x1
+w1
, yy1
+2*w1
, x1
+w1
-1, yy1
+w1
, x1
+w1
, yy1
);
233 fl_polygon(x1
, yy1
, x1
+1, yy1
+w1
, x1
, yy1
+2*w1
, x1
+w1
, yy1
+w1
);
235 fl_polygon(x1
, yy1
+w1
, x1
+w1
, yy1
+2*w1
, x1
+w1
, yy1
);
237 fl_polygon(x1
, yy1
, x1
, yy1
+2*w1
, x1
+w1
, yy1
+w1
);
241 if (H
< 3*W
) {Fl_Slider::draw(X
,Y
,W
,H
); return;}
242 Fl_Slider::draw(X
,Y
+W
,W
,H
-2*W
);
243 if (damage()&FL_DAMAGE_ALL
) {
244 draw_box((pushed_
==1) ? fl_down(slider()) : slider(),
245 X
, Y
, W
, W
, selection_color());
246 draw_box((pushed_
==2) ? fl_down(slider()) : slider(),
247 X
, Y
+H
-W
, W
, W
, selection_color());
249 fl_color(labelcolor());
251 fl_color(fl_inactive(labelcolor()));
252 int w1
= (W
-4)/3; if (w1
< 1) w1
= 1;
253 int x1
= X
+(W
-2*w1
-1)/2;
254 int yy1
= Y
+(W
-w1
-1)/2;
255 if (Fl::scheme_
&& !strcmp(Fl::scheme_
, "gtk+")) {
256 fl_polygon(x1
, yy1
+w1
, x1
+w1
, yy1
+w1
-1, x1
+2*w1
, yy1
+w1
, x1
+w1
, yy1
);
258 fl_polygon(x1
, yy1
, x1
+w1
, yy1
+1, x1
+w1
, yy1
+w1
);
259 fl_polygon(x1
+w1
, yy1
+1, x1
+2*w1
, yy1
, x1
+w1
, yy1
+w1
);
261 fl_polygon(x1
, yy1
+w1
, x1
+2*w1
, yy1
+w1
, x1
+w1
, yy1
);
263 fl_polygon(x1
, yy1
, x1
+w1
, yy1
+w1
, x1
+2*w1
, yy1
);
270 Creates a new Fl_Scrollbar widget with given position, size, and label.
271 You need to do type(FL_HORIZONTAL) if you want a horizontal scrollbar.
273 Fl_Scrollbar::Fl_Scrollbar(int X
, int Y
, int W
, int H
, const char* L
)
274 : Fl_Slider(X
, Y
, W
, H
, L
) {
283 /** Destroys the Scrollbar. */
284 Fl_Scrollbar::~Fl_Scrollbar() {
286 Fl::remove_timeout(timeout_cb
, this);
291 // End of "$Id: Fl_Scrollbar.cxx 7903 2010-11-28 21:06:39Z matt $".