void Fl_Scrollbar::increment_cb() { double i; switch (which_pushed) { case UP_ARROW: i = -linesize(); break; default:i = linesize(); break; case ABOVE_SLIDER: i = -pagesize(); break; case BELOW_SLIDER: i = pagesize(); break; } handle_drag(value()+i); }
Fl_Scrollbar::Fl_Scrollbar(int X, int Y, int W, int H, const char* L) : Fl_Slider(X, Y, W, H, L) { style(default_style); step(1); pagesize_ = 1; linesize(2); }
// New stile ctor Fl_Scrollbar::Fl_Scrollbar(const char* l,int layout_size,Fl_Align layout_al,int label_w) : Fl_Slider(l,layout_size,layout_al,label_w) { style(default_style); step(0); pagesize_ = 1; linesize(2); }
int Flu_Wrap_Group :: Scrollbar :: handle( int event ) { if( event == FL_MOUSEWHEEL ) { handle_drag( clamp( value() + linesize() * Fl::e_dy ) ); return 1; } else return Fl_Scrollbar::handle( event ); }
int Fl_Scrollbar::value(int p, int w, int t, int l) { // p = position, first line displayed // w = window, number of lines displayed // t = top, number of first line // l = length, total number of lines if (p+w > t+l) l = p+w-t; if (l <= 0) l = 1; int b = l-w+t; int X=0; int Y=0; int W=this->w(); int H=h(); box()->inset(X,Y,W,H); if (vertical()) {int T = W; W = H; H = T; T = b; b = t; t = T;} if (W >= 3*H) W -= 2*H; int S = W*w/l; if (S < H) S = H; if (S > W) S = W; if (S != slider_size() || t != minimum() || b != maximum()) { slider_size(S); minimum(t); maximum(b); redraw(); } int ls = int(linesize()); pagesize(w>2*ls ? w-ls : ls); return Fl_Slider::value(p); }
int Fl_Scrollbar::handle(int event) { // area of scrollbar: int X=0; int Y=0; int W=w(); int H=h(); box()->inset(X,Y,W,H); // adjust slider area to be inside the arrow buttons: if (vertical()) { if (H >= 3*W) {Y += W; H -= 2*W;} } else { if (W >= 3*H) {X += H; W -= 2*H;} } // which widget part is highlighted? int mx = Fl::event_x(); int my = Fl::event_y(); int which_part; if (!Fl::event_inside(0, 0, w(), h())) which_part = NOTHING; else if (vertical()) { if (my < Y) which_part = UP_ARROW; else if (my >= Y+H) which_part = DOWN_ARROW; else { int slidery = slider_position(value(), H); if (my < Y+slidery) which_part = ABOVE_SLIDER; else if (my >= Y+slidery+slider_size()) which_part = BELOW_SLIDER; else which_part = SLIDER; } } // horizontal else { if (mx < X) which_part = UP_ARROW; else if (mx >= X+W) which_part = DOWN_ARROW; else { int sliderx = slider_position(value(), W); if (mx < X+sliderx) which_part = ABOVE_SLIDER; else if (mx >= X+sliderx+slider_size()) which_part = BELOW_SLIDER; else which_part = SLIDER; } } switch (event) { case FL_FOCUS: return 0; case FL_ENTER: case FL_MOVE: if (!highlight_color()) return 1; if (which_part != which_highlight) { which_highlight = which_part; redraw(FL_DAMAGE_HIGHLIGHT); } return 1; case FL_LEAVE: if (which_highlight) { which_highlight = 0; redraw(FL_DAMAGE_HIGHLIGHT); } return 1; case FL_PUSH: // Clicking on the slider or middle or right click on the trough // gives us normal slider behavior: if (which_part == SLIDER || Fl::event_button() > 1 && which_part > DOWN_ARROW) { which_pushed = SLIDER; return Fl_Slider::handle(event, X,Y,W,H); } handle_push(); goto J1; case FL_DRAG: if (which_pushed==SLIDER) return Fl_Slider::handle(event, X,Y,W,H); if (which_part == SLIDER) which_part = NOTHING; // it is okay to switch between arrows and nothing, but no other // changes are allowed: if (!which_pushed && which_part <= DOWN_ARROW) ; else if (!which_part && which_pushed <= DOWN_ARROW) ; else which_part = which_pushed; J1: if (which_part != which_pushed) { Fl::remove_timeout(timeout_cb, this); which_highlight = which_pushed = which_part; redraw(FL_DAMAGE_HIGHLIGHT); if (which_part) { Fl::add_timeout(INITIALREPEAT, timeout_cb, this); increment_cb(); } } return 1; case FL_RELEASE: if (which_pushed == SLIDER) { Fl_Slider::handle(event, X,Y,W,H); } else if (which_pushed) { Fl::remove_timeout(timeout_cb, this); handle_release(); redraw(FL_DAMAGE_HIGHLIGHT); } which_pushed = NOTHING; return 1; case FL_MOUSEWHEEL: { float n = (vertical() ? Fl::event_dy() : Fl::event_dx()) * Fl_Style::wheel_scroll_lines * linesize(); if (fabsf(n) > pagesize()) n = (n<0)?-pagesize():pagesize(); handle_drag(value()+n); return 1; } case FL_KEY: if (vertical()) switch(Fl::event_key()) { case FL_Home: handle_drag(maximum()); return 1; case FL_End: handle_drag(minimum()); return 1; case FL_Page_Up: handle_drag(value()-pagesize()); return 1; case FL_Page_Down: handle_drag(value()+pagesize()); return 1; } // else fall through... default: return Fl_Slider::handle(event); } }