diff options
| author | Michael R Sweet <michael.r.sweet@gmail.com> | 1999-12-04 12:22:37 +0000 |
|---|---|---|
| committer | Michael R Sweet <michael.r.sweet@gmail.com> | 1999-12-04 12:22:37 +0000 |
| commit | 08ed55a14b0c26dabf3c6bc36b19d1888b1ec96d (patch) | |
| tree | 1f4cccfce3b345cf0d9d8dcf136140d7f4ebd883 | |
| parent | 6291a3352629198d5f0bebd0a6ee502199b21169 (diff) | |
Scrollbars now "page" when you click outside the scroller.
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.0@934 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
| -rw-r--r-- | src/Fl_Scrollbar.cxx | 93 | ||||
| -rw-r--r-- | src/Fl_Slider.cxx | 74 |
2 files changed, 114 insertions, 53 deletions
diff --git a/src/Fl_Scrollbar.cxx b/src/Fl_Scrollbar.cxx index c0e3276ca..77fc82f88 100644 --- a/src/Fl_Scrollbar.cxx +++ b/src/Fl_Scrollbar.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_Scrollbar.cxx,v 1.7.2.1 1999/05/14 09:07:07 bill Exp $" +// "$Id: Fl_Scrollbar.cxx,v 1.7.2.2 1999/12/04 12:22:37 mike Exp $" // // Scroll bar widget for the Fast Light Tool Kit (FLTK). // @@ -32,8 +32,18 @@ #define REPEAT .05 void Fl_Scrollbar::increment_cb() { - handle_drag(clamp(value() + ( - ((pushed_>1) == (maximum()>=minimum())) ? linesize_ : -linesize_))); + int i; + int W = horizontal() ? w() : h(); + int S = int(slider_size()*W+.5); + + switch (pushed_) { + case 1: i = -linesize_; break; + default:i = linesize_; break; + case 3: i = -S * (maximum() - minimum()) / W; break; + case 4: i = S * (maximum() - minimum()) / W; break; + } + if (maximum() < minimum() && pushed_ < 3) i = -i; + handle_drag(clamp(value() + i)); } void Fl_Scrollbar::timeout_cb(void* v) { @@ -43,41 +53,80 @@ void Fl_Scrollbar::timeout_cb(void* v) { } int Fl_Scrollbar::handle(int event) { - if (!pushed_) { - if (horizontal()) { - if (w() < 3*h()) return Fl_Slider::handle(event); - if (Fl_Slider::handle(event, x()+h(), y(), w()-2*h(), h())) return 1; - } else { - if (h() < 3*w()) return Fl_Slider::handle(event); - if (Fl_Slider::handle(event, x(), y()+w(), w(), h()-2*w())) return 1; + // area of scrollbar: + int area; + int X=x(); int Y=y(); int W=w(); int H=h(); + int SX = X; int SY = Y; int SW = W; int SH = H; + + // adjust slider area to be inside the arrow buttons: + if (horizontal()) { + if (W >= 3*H) {X += H; W -= 2*H;} + } else { + if (H >= 3*W) {Y += W; H -= 2*W;} + } + + // which widget part is highlighted? + int mx = Fl::event_x(); + int my = Fl::event_y(); + if (!Fl::event_inside(SX, SY, SW, SH)) area = 0; + else if (horizontal()) { + if (mx < X) area = 1; + else if (mx >= X+W) area = 2; + else { + int sliderx; + int S = int(slider_size()*W+.5); + double val = (value()-minimum())/(maximum()-minimum()); + if (val >= 1.0) sliderx = W-S; + else if (val <= 0.0) sliderx = 0; + else sliderx = int(val*(W-S)+.5); + + if (mx < X+sliderx) area = 3; + else if (mx >= X+sliderx+S) area = 4; + else area = 5; + } + } else { + if (mx < X || mx >= X+W) area = 0; + else if (my < Y) area = 1; + else if (my >= Y+H) area = 2; + else { + int slidery; + int S = int(slider_size()*H+.5); + double val = (value()-minimum())/(maximum()-minimum()); + if (val >= 1.0) slidery = H-S; + else if (val <= 0.0) slidery = 0; + else slidery = int(val*(H-S)+.5); + + if (my < Y+slidery) area = 3; + else if (my >= Y+slidery+S) area = 4; + else area = 5; } } switch (event) { + case FL_ENTER: + case FL_LEAVE: + return 1; case FL_RELEASE: + damage(FL_DAMAGE_EXPOSE); if (pushed_) { Fl::remove_timeout(timeout_cb, this); pushed_ = 0; - redraw(); } handle_release(); return 1; case FL_PUSH: - if (horizontal()) { - if (Fl::event_inside(x(), y(), h(), h())) pushed_ = 1; - if (Fl::event_inside(x()+w()-h(), y(), h(), h())) pushed_ = 2; - } else { - if (Fl::event_inside(x(), y(), w(), w())) pushed_ = 1; - if (Fl::event_inside(x(), y()+h()-w(), w(), w())) pushed_ = 2; - } + if (pushed_) return 1; + if (area != 5) pushed_ = area; if (pushed_) { handle_push(); Fl::add_timeout(INITIALREPEAT, timeout_cb, this); increment_cb(); - redraw(); + damage(FL_DAMAGE_EXPOSE); + return 1; } - return 1; + return Fl_Slider::handle(event, X,Y,W,H); case FL_DRAG: - return pushed_; + if (pushed_) return 1; + return Fl_Slider::handle(event, X,Y,W,H); case FL_SHORTCUT: { int v = value(); int ls = maximum()>=minimum() ? linesize_ : -linesize_; @@ -192,5 +241,5 @@ Fl_Scrollbar::Fl_Scrollbar(int X, int Y, int W, int H, const char* L) } // -// End of "$Id: Fl_Scrollbar.cxx,v 1.7.2.1 1999/05/14 09:07:07 bill Exp $". +// End of "$Id: Fl_Scrollbar.cxx,v 1.7.2.2 1999/12/04 12:22:37 mike Exp $". // diff --git a/src/Fl_Slider.cxx b/src/Fl_Slider.cxx index e72fc7b3a..376692be3 100644 --- a/src/Fl_Slider.cxx +++ b/src/Fl_Slider.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_Slider.cxx,v 1.8.2.2 1999/10/15 08:14:37 bill Exp $" +// "$Id: Fl_Slider.cxx,v 1.8.2.3 1999/12/04 12:22:37 mike Exp $" // // Slider widget for the Fast Light Tool Kit (FLTK). // @@ -179,42 +179,54 @@ int Fl_Slider::handle(int event, int x, int y, int w, int h) { if (!Fl::event_inside(x, y, w, h)) return 0; handle_push(); case FL_DRAG: { - if (slider_size() >= 1 || minimum()==maximum()) return 1; int W = (horizontal() ? w : h); - int X = (horizontal() ? Fl::event_x()-x : Fl::event_y()-y); + int H = (horizontal() ? h : w); + int mx = (horizontal() ? Fl::event_x()-x : Fl::event_y()-y); int S = int(slider_size_*W+.5); - int T = (horizontal() ? h : w)/2+1; - if (type()==FL_VERT_NICE_SLIDER || type()==FL_HOR_NICE_SLIDER) T += 4; - if (type()!=FL_HOR_FILL_SLIDER && type()!=FL_VERT_FILL_SLIDER) { - if (S < T) S = T; - } - double v = double(X)/(W-S); - double sliderwidth = double(S)/(W-S); - double val = (value()-minimum())/(maximum()-minimum()); - static double offcenter; - if (event == FL_PUSH) { - offcenter = v-val; - if (offcenter < 0) offcenter = 0; - else if (offcenter > sliderwidth) offcenter = sliderwidth; - else return 1; + int X; + static int offcenter; + if (type() == FL_HOR_FILL_SLIDER || type() == FL_VERT_FILL_SLIDER) { + double val = (value()-minimum())/(maximum()-minimum()); + + if (val >= 1.0) X = W; + else if (val <= 0.0) X = 0; + else X = int(val*W+.5); + + if (event == FL_PUSH) { + offcenter = mx-X; + if (offcenter < -S/2) offcenter = 0; + else if (offcenter > S/2) offcenter = 0; + else return 1; + } + S = 0; + } else { + double val = (value()-minimum())/(maximum()-minimum()); + + if (val >= 1.0) X = W-S; + else if (val <= 0.0) X = 0; + else X = int(val*(W-S)+.5); + + if (event == FL_PUSH) { + offcenter = mx-X; + if (offcenter < 0) offcenter = 0; + else if (offcenter > S) offcenter = S; + else return 1; + } } + X = mx-offcenter; + double v; TRY_AGAIN: - v -= offcenter; - if (v < 0) { - offcenter = v+offcenter; - if (offcenter<0) offcenter=0; - v = 0; - } else if (v > 1) { - offcenter = v+offcenter-1; - if (offcenter > sliderwidth) offcenter = sliderwidth; - v = 1; + if (X < 0) { + X = 0; + offcenter = mx; if (offcenter < 0) offcenter = 0; + } else if (X > (W-S)) { + X = W-S; + offcenter = mx-X; if (offcenter > S) offcenter = S; } - // if (Fl::event_state(FL_SHIFT)) v = val+(v-val)*.05; - v = round(v*(maximum()-minimum())+minimum()); + v = round(X*(maximum()-minimum())/(W-S) + minimum()); // make sure a click outside the sliderbar moves it: if (event == FL_PUSH && v == value()) { - offcenter = sliderwidth/2; - v = double(X)/(W-S); + offcenter = S/2; event = FL_DRAG; goto TRY_AGAIN; } @@ -237,5 +249,5 @@ int Fl_Slider::handle(int event) { } // -// End of "$Id: Fl_Slider.cxx,v 1.8.2.2 1999/10/15 08:14:37 bill Exp $". +// End of "$Id: Fl_Slider.cxx,v 1.8.2.3 1999/12/04 12:22:37 mike Exp $". // |
