int Flu_Spinner::handle(int event) { int W = w()*15/100; if( W < h()/2 ) W = h()/2; int X = x()+w()-W, Y = y(); if( (align() & FL_ALIGN_INSIDE) || !_editable ) { _input.readonly( true ); _input.cursor_color( FL_WHITE ); } else { _input.readonly( false ); _input.cursor_color( FL_BLACK ); } switch( event ) { case FL_PUSH: _dragging = true; if (Fl::visible_focus() && handle(FL_FOCUS)) Fl::focus(this); _lastValue = value(); _lastY = Fl::event_y(); Fl::remove_timeout( repeat_callback, this ); if( Fl::event_inside( X, Y, W, h()/2 ) ) // up button { _pushed = true; _valbox[0] = FL_DOWN_BOX; _up = true; } if( Fl::event_inside( X, Y+h()/2, W, h()/2 ) ) // down button { _pushed = true; _valbox[1] = FL_DOWN_BOX; _up = false; } if( _pushed ) { increment_cb(); _totalTime = _initialDelay; if( _doRepeat ) Fl::add_timeout( _initialDelay, repeat_callback, this); handle_push(); take_focus(); redraw(); return 1; } break; case FL_DRAG: { // only do the dragging if the last Y differs from the current Y by more than 3 pixels if( ABS(_lastY-Fl::event_y()) < 3 ) break; _dragging = true; _pushed = false; Fl::remove_timeout( repeat_callback, this ); int oldWhen = when(); _setvalue(increment(_lastValue,(_lastY-Fl::event_y())*(Fl::event_state(FL_SHIFT|FL_CTRL|FL_ALT)?10:1))); _valbox[0] = _valbox[1] = FL_DOWN_BOX; when( oldWhen ); fl_cursor((Fl_Cursor)22); _input.redraw(); redraw(); } break; case FL_RELEASE: { bool doCB = ( ( when() & FL_WHEN_RELEASE ) || ( when() & FL_WHEN_RELEASE_ALWAYS ) ) && ( _pushed || ( _valbox[0] == FL_DOWN_BOX ^ _valbox[1] == FL_DOWN_BOX ) ); _pushed = false; _dragging = false; Fl::remove_timeout( repeat_callback, this ); _valbox[0] = _valbox[1] = FL_UP_BOX; fl_cursor(FL_CURSOR_DEFAULT); redraw(); handle_release(); if( doCB ) do_callback(); _input.take_focus(); } break; case FL_FOCUS: case FL_UNFOCUS: redraw(); _input.take_focus(); return 0; case FL_ENTER: if( Fl::event_inside( &_input ) ) return _input.handle(event); else if( active_r() ) { fl_cursor(FL_CURSOR_DEFAULT); return 1; } break; case FL_LEAVE: if( Fl::event_inside( &_input ) ) return _input.handle(event); else if( active_r() ) { fl_cursor(FL_CURSOR_DEFAULT); return 1; } break; case FL_KEYBOARD: switch( Fl::event_key() ) { case FL_Down: { int oldWhen = when(); when( FL_WHEN_CHANGED ); _setvalue(increment(value(),-1*(Fl::event_state(FL_SHIFT|FL_CTRL|FL_ALT)?10:1))); when( oldWhen ); redraw(); return 1; } case FL_Up: { int oldWhen = when(); when( FL_WHEN_CHANGED ); _setvalue(increment(value(),1*(Fl::event_state(FL_SHIFT|FL_CTRL|FL_ALT)?10:1))); when( oldWhen ); redraw(); return 1; } } break; } return _input.handle(event); }
int Fl_Value_Input_Spin::handle(int event) { double v; int olddelta; int mx = Fl::event_x(); int my = Fl::event_y(); int sxx = x(), syy = y(), sww = w(), shh = h(); sxx += sww - buttonssize(); sww = buttonssize(); if(!indrag && ( !sldrag || !((mx>=sxx && mx<=(sxx+sww)) && (my>=syy && my<=(syy+shh)))) ) { indrag=0; switch(event) { case FL_PUSH: case FL_DRAG: sldrag=1; break; case FL_FOCUS: input.take_focus(); break; case FL_UNFOCUS: redraw(); break; default: sldrag=0; } input.type(step()>=1.0 ? FL_INT_INPUT : FL_FLOAT_INPUT); return input.handle(event); } switch (event) { case FL_PUSH: // if (!step()) goto DEFAULT; iy = my; ix = mx; drag = Fl::event_button(); handle_push(); indrag=1; mouseobj=1; Fl::add_timeout(.5, repeat_callback, this); delta=0; if(Fl::event_inside(sxx,syy,sww,shh/2)) { deltadir=1; } else if (Fl::event_inside(sxx,syy+shh/2,sww,shh/2)) { deltadir=-1; } else { deltadir=0; } increment_cb(); redraw(); return 1; case FL_DRAG: if(mouseobj) { mouseobj=0; Fl::remove_timeout(repeat_callback, this); } // if (!step()) goto DEFAULT; olddelta=delta; delta = - (Fl::event_y()-iy); if ((delta>5) || (delta<-5) ) { deltadir=((olddelta-delta)>0)?-1:(((olddelta-delta)<0)?1:0); } else { deltadir=0; delta = olddelta;} switch (drag) { case 3: v = increment(value(), deltadir*100); break; case 2: v = increment(value(), deltadir*10); break; default:v = increment(value(), deltadir); break; } v = round(v); handle_drag(soft()?softclamp(v):clamp(v)); indrag=1; return 1; case FL_RELEASE: if(mouseobj) { Fl::remove_timeout(repeat_callback, this); } // if (!step()) goto DEFAULT; indrag=0; delta=0; deltadir=0; mouseobj=0; handle_release(); redraw(); return 1; case FL_FOCUS: indrag=0; return input.take_focus(); default: indrag=0; input.type(step()>=1.0 ? FL_INT_INPUT : FL_FLOAT_INPUT); return 1; } }
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); } }
int Fl_Spin::handle(int event) { double v; int olddelta; int mx = Fl::event_x(); int my = Fl::event_y(); int sxx = x(), syy = y(), sww = w(), shh = h(); switch (event) { case FL_PUSH: // if (!step()) goto DEFAULT; iy = my; ix = mx; drag = Fl::event_button(); handle_push(); indrag=1; mouseobj=1; Fl::add_timeout(.5, repeat_callback, this); delta=0; if(Fl::event_inside(sxx,syy,sww,shh/2)) { deltadir=1; } else if (Fl::event_inside(sxx,syy+shh/2,sww,shh/2)) { deltadir=-1; } else { deltadir=0; } increment_cb(); redraw(); return 1; case FL_DRAG: if(mouseobj) { mouseobj=0; Fl::remove_timeout(repeat_callback, this); } // if (!step()) goto DEFAULT; olddelta=delta; delta = - (Fl::event_y()-iy); if ((delta>5) || (delta<-5) ) { deltadir=((olddelta-delta)>0)?-1:(((olddelta-delta)<0)?1:0); } else { deltadir=0; delta = olddelta;} switch (drag) { case 3: v = increment(value(), deltadir*100); break; case 2: v = increment(value(), deltadir*10); break; default:v = increment(value(), deltadir); break; } v = round(v); handle_drag(soft()?softclamp(v):clamp(v)); indrag=1; return 1; case FL_RELEASE: if(mouseobj) { Fl::remove_timeout(repeat_callback, this); } // if (!step()) goto DEFAULT; indrag=0; delta=0; deltadir=0; mouseobj=0; handle_release(); redraw(); return 1; default: indrag=0; return Fl_Valuator::handle(event); } }