|
fltk 1.3.0rc3
About: FLTK (Fast Light Tool Kit) is a cross-platform C++ GUI toolkit for UNIX/Linux (X11), Microsoft Windows, and MacOS X. Release candidate.
SfR Fresh Dox: fltk-1.3.0rc3-source.tar.gz ("inofficial" and yet experimental doxygen-generated source code documentation) ![]() |
00001 // 00002 // "$Id: Fl_Scrollbar.cxx 7903 2010-11-28 21:06:39Z matt $" 00003 // 00004 // Scroll bar widget for the Fast Light Tool Kit (FLTK). 00005 // 00006 // Copyright 1998-2010 by Bill Spitzak and others. 00007 // 00008 // This library is free software; you can redistribute it and/or 00009 // modify it under the terms of the GNU Library General Public 00010 // License as published by the Free Software Foundation; either 00011 // version 2 of the License, or (at your option) any later version. 00012 // 00013 // This library is distributed in the hope that it will be useful, 00014 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00016 // Library General Public License for more details. 00017 // 00018 // You should have received a copy of the GNU Library General Public 00019 // License along with this library; if not, write to the Free Software 00020 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 00021 // USA. 00022 // 00023 // Please report all bugs and problems on the following page: 00024 // 00025 // http://www.fltk.org/str.php 00026 // 00027 00028 00029 #include <FL/Fl.H> 00030 #include <FL/Fl_Scrollbar.H> 00031 #include <FL/fl_draw.H> 00032 #include <math.h> 00033 #include "flstring.h" 00034 00035 #define INITIALREPEAT .5 00036 #define REPEAT .05 00037 00038 void Fl_Scrollbar::increment_cb() { 00039 char inv = maximum()<minimum(); 00040 int ls = inv ? -linesize_ : linesize_; 00041 int i; 00042 switch (pushed_) { 00043 case 1: // clicked on arrow left 00044 i = -ls; 00045 break; 00046 default: // clicked on arrow right 00047 i = ls; 00048 break; 00049 case 5: // clicked into the box next to the slider on the left 00050 i = -(int((maximum()-minimum())*slider_size()/(1.0-slider_size()))); 00051 if (inv) { 00052 if (i<-ls) i = -ls; 00053 } else { 00054 if (i>-ls) i = -ls; // err 00055 } 00056 break; 00057 case 6: // clicked into the box next to the slider on the right 00058 i = (int((maximum()-minimum())*slider_size()/(1.0-slider_size()))); 00059 if (inv) { 00060 if (i>ls) i = ls; 00061 } else { 00062 if (i<ls) i = ls; // err 00063 } 00064 break; 00065 } 00066 handle_drag(clamp(value() + i)); 00067 } 00068 00069 void Fl_Scrollbar::timeout_cb(void* v) { 00070 Fl_Scrollbar* s = (Fl_Scrollbar*)v; 00071 s->increment_cb(); 00072 Fl::add_timeout(REPEAT, timeout_cb, s); 00073 } 00074 00075 int Fl_Scrollbar::handle(int event) { 00076 // area of scrollbar: 00077 int area; 00078 int X=x(); int Y=y(); int W=w(); int H=h(); 00079 00080 // adjust slider area to be inside the arrow buttons: 00081 if (horizontal()) { 00082 if (W >= 3*H) {X += H; W -= 2*H;} 00083 } else { 00084 if (H >= 3*W) {Y += W; H -= 2*W;} 00085 } 00086 00087 // which widget part is highlighted? 00088 int relx; 00089 int ww; 00090 if (horizontal()) { 00091 relx = Fl::event_x()-X; 00092 ww = W; 00093 } else { 00094 relx = Fl::event_y()-Y; 00095 ww = H; 00096 } 00097 if (relx < 0) area = 1; 00098 else if (relx >= ww) area = 2; 00099 else { 00100 int S = int(slider_size()*ww+.5); 00101 int T = (horizontal() ? H : W)/2+1; 00102 if (type()==FL_VERT_NICE_SLIDER || type()==FL_HOR_NICE_SLIDER) T += 4; 00103 if (S < T) S = T; 00104 double val = 00105 (maximum()-minimum()) ? (value()-minimum())/(maximum()-minimum()) : 0.5; 00106 int sliderx; 00107 if (val >= 1.0) sliderx = ww-S; 00108 else if (val <= 0.0) sliderx = 0; 00109 else sliderx = int(val*(ww-S)+.5); 00110 if (Fl::event_button() == FL_MIDDLE_MOUSE) area = 8; 00111 else if (relx < sliderx) area = 5; 00112 else if (relx >= sliderx+S) area = 6; 00113 else area = 8; 00114 } 00115 00116 switch (event) { 00117 case FL_ENTER: 00118 case FL_LEAVE: 00119 return 1; 00120 case FL_RELEASE: 00121 damage(FL_DAMAGE_ALL); 00122 if (pushed_) { 00123 Fl::remove_timeout(timeout_cb, this); 00124 pushed_ = 0; 00125 } 00126 handle_release(); 00127 return 1; 00128 case FL_PUSH: 00129 if (pushed_) return 1; 00130 if (area != 8) pushed_ = area; 00131 if (pushed_) { 00132 handle_push(); 00133 Fl::add_timeout(INITIALREPEAT, timeout_cb, this); 00134 increment_cb(); 00135 damage(FL_DAMAGE_ALL); 00136 return 1; 00137 } 00138 return Fl_Slider::handle(event, X,Y,W,H); 00139 case FL_DRAG: 00140 if (pushed_) return 1; 00141 return Fl_Slider::handle(event, X,Y,W,H); 00142 case FL_MOUSEWHEEL : 00143 if (horizontal()) { 00144 if (Fl::e_dx==0) return 0; 00145 int ls = maximum()>=minimum() ? linesize_ : -linesize_; 00146 handle_drag(clamp(value() + ls * Fl::e_dx)); 00147 return 1; 00148 } else { 00149 if (Fl::e_dy==0) return 0; 00150 int ls = maximum()>=minimum() ? linesize_ : -linesize_; 00151 handle_drag(clamp(value() + ls * Fl::e_dy)); 00152 return 1; 00153 } 00154 case FL_SHORTCUT: 00155 case FL_KEYBOARD: { 00156 int v = value(); 00157 int ls = maximum()>=minimum() ? linesize_ : -linesize_; 00158 if (horizontal()) { 00159 switch (Fl::event_key()) { 00160 case FL_Left: 00161 v -= ls; 00162 break; 00163 case FL_Right: 00164 v += ls; 00165 break; 00166 default: 00167 return 0; 00168 } 00169 } else { // vertical 00170 switch (Fl::event_key()) { 00171 case FL_Up: 00172 v -= ls; 00173 break; 00174 case FL_Down: 00175 v += ls; 00176 break; 00177 case FL_Page_Up: 00178 if (slider_size() >= 1.0) return 0; 00179 v -= int((maximum()-minimum())*slider_size()/(1.0-slider_size())); 00180 v += ls; 00181 break; 00182 case FL_Page_Down: 00183 if (slider_size() >= 1.0) return 0; 00184 v += int((maximum()-minimum())*slider_size()/(1.0-slider_size())); 00185 v -= ls; 00186 break; 00187 case FL_Home: 00188 v = int(minimum()); 00189 break; 00190 case FL_End: 00191 v = int(maximum()); 00192 break; 00193 default: 00194 return 0; 00195 } 00196 } 00197 v = int(clamp(v)); 00198 if (v != value()) { 00199 Fl_Slider::value(v); 00200 value_damage(); 00201 set_changed(); 00202 do_callback(); 00203 } 00204 return 1;} 00205 } 00206 return 0; 00207 } 00208 00209 void Fl_Scrollbar::draw() { 00210 if (damage()&FL_DAMAGE_ALL) draw_box(); 00211 int X = x()+Fl::box_dx(box()); 00212 int Y = y()+Fl::box_dy(box()); 00213 int W = w()-Fl::box_dw(box()); 00214 int H = h()-Fl::box_dh(box()); 00215 if (horizontal()) { 00216 if (W < 3*H) {Fl_Slider::draw(X,Y,W,H); return;} 00217 Fl_Slider::draw(X+H,Y,W-2*H,H); 00218 if (damage()&FL_DAMAGE_ALL) { 00219 draw_box((pushed_==1) ? fl_down(slider()) : slider(), 00220 X, Y, H, H, selection_color()); 00221 draw_box((pushed_==2) ? fl_down(slider()) : slider(), 00222 X+W-H, Y, H, H, selection_color()); 00223 if (active_r()) 00224 fl_color(labelcolor()); 00225 else 00226 fl_color(fl_inactive(labelcolor())); 00227 int w1 = (H-4)/3; if (w1 < 1) w1 = 1; 00228 int x1 = X+(H-w1-1)/2; 00229 int yy1 = Y+(H-2*w1-1)/2; 00230 if (Fl::scheme_ && !strcmp(Fl::scheme_, "gtk+")) { 00231 fl_polygon(x1, yy1+w1, x1+w1, yy1+2*w1, x1+w1-1, yy1+w1, x1+w1, yy1); 00232 x1 += (W-H); 00233 fl_polygon(x1, yy1, x1+1, yy1+w1, x1, yy1+2*w1, x1+w1, yy1+w1); 00234 } else { 00235 fl_polygon(x1, yy1+w1, x1+w1, yy1+2*w1, x1+w1, yy1); 00236 x1 += (W-H); 00237 fl_polygon(x1, yy1, x1, yy1+2*w1, x1+w1, yy1+w1); 00238 } 00239 } 00240 } else { // vertical 00241 if (H < 3*W) {Fl_Slider::draw(X,Y,W,H); return;} 00242 Fl_Slider::draw(X,Y+W,W,H-2*W); 00243 if (damage()&FL_DAMAGE_ALL) { 00244 draw_box((pushed_==1) ? fl_down(slider()) : slider(), 00245 X, Y, W, W, selection_color()); 00246 draw_box((pushed_==2) ? fl_down(slider()) : slider(), 00247 X, Y+H-W, W, W, selection_color()); 00248 if (active_r()) 00249 fl_color(labelcolor()); 00250 else 00251 fl_color(fl_inactive(labelcolor())); 00252 int w1 = (W-4)/3; if (w1 < 1) w1 = 1; 00253 int x1 = X+(W-2*w1-1)/2; 00254 int yy1 = Y+(W-w1-1)/2; 00255 if (Fl::scheme_ && !strcmp(Fl::scheme_, "gtk+")) { 00256 fl_polygon(x1, yy1+w1, x1+w1, yy1+w1-1, x1+2*w1, yy1+w1, x1+w1, yy1); 00257 yy1 += H-W; 00258 fl_polygon(x1, yy1, x1+w1, yy1+1, x1+w1, yy1+w1); 00259 fl_polygon(x1+w1, yy1+1, x1+2*w1, yy1, x1+w1, yy1+w1); 00260 } else { 00261 fl_polygon(x1, yy1+w1, x1+2*w1, yy1+w1, x1+w1, yy1); 00262 yy1 += H-W; 00263 fl_polygon(x1, yy1, x1+w1, yy1+w1, x1+2*w1, yy1); 00264 } 00265 } 00266 } 00267 } 00268 00273 Fl_Scrollbar::Fl_Scrollbar(int X, int Y, int W, int H, const char* L) 00274 : Fl_Slider(X, Y, W, H, L) { 00275 box(FL_FLAT_BOX); 00276 color(FL_DARK2); 00277 slider(FL_UP_BOX); 00278 linesize_ = 16; 00279 pushed_ = 0; 00280 step(1); 00281 } 00282 00284 Fl_Scrollbar::~Fl_Scrollbar() { 00285 if (pushed_) 00286 Fl::remove_timeout(timeout_cb, this); 00287 } 00288 00289 00290 // 00291 // End of "$Id: Fl_Scrollbar.cxx 7903 2010-11-28 21:06:39Z matt $". 00292 //