diff --git a/FL/Fl_Value_SliderX.C b/FL/Fl_Value_SliderX.C index 59499d5..98ca6bc 100644 --- a/FL/Fl_Value_SliderX.C +++ b/FL/Fl_Value_SliderX.C @@ -24,54 +24,208 @@ #include #include +void Fl_Value_SliderX::input_cb(Fl_Widget*, void* v) { + Fl_Value_SliderX& t = *(Fl_Value_SliderX*)v; + double nv; + if ((t.step() - floor(t.step()))>0.0 || t.step() == 0.0) + nv = strtod(t.input.value(), 0); + else + nv = strtol(t.input.value(), 0, 0); + + if (nv != t.value() || t.when() & FL_WHEN_NOT_CHANGED) { + + if ( ! t.soft()) + nv = t.clamp(nv); + t.set_value(nv); + t.set_changed(); + if (t.when()) + { + t.value_damage(); + t.do_callback(); + } + } +} + +void Fl_Value_SliderX::value_damage() { + char buf[128]; + format(buf); + input.value(buf); + input.mark(input.position()); // turn off selection highlight + redraw(); +} + + +Fl_Value_SliderX::~Fl_Value_SliderX ( void ) +{ + if (input.parent() == (Fl_Group *)this) + input.parent(0); // *revert* ctor kludge! +} + /** - Creates a new Fl_Value_SliderX widget using the given - position, size, and label string. The default boxtype is FL_DOWN_BOX. + Creates a new Fl_Value_SliderX widget using the given + position, size, and label string. The default boxtype is FL_DOWN_BOX. */ Fl_Value_SliderX::Fl_Value_SliderX(int X, int Y, int W, int H, const char*l) -: Fl_SliderX(X,Y,W,H,l) { - step(1,100); - textfont_ = FL_HELVETICA; - textsize_ = 10; - textcolor_ = FL_FOREGROUND_COLOR; + : Fl_SliderX(X,Y,W,H,l),input(X, Y, W, H, 0) { + step(1,100); + + soft_ = 0; + if (input.parent()) // defeat automatic-add + input.parent()->remove(input); + input.parent((Fl_Group *)this); // kludge! + input.callback(input_cb, this); + input.when(FL_WHEN_ENTER_KEY); + box(input.box()); + color(input.color()); + selection_color(input.selection_color()); + align(FL_ALIGN_LEFT); + value_damage(); + textsize(9); + set_flag(SHORTCUT_LABEL); + } void Fl_Value_SliderX::draw() { - int sxx = x(), syy = y(), sww = w(), shh = h(); - int bxx = x(), byy = y(), bww = w(), bhh = h(); - if (horizontal()) { - bww = 35; sxx += 35; sww -= 35; - } else { - syy += 25; bhh = 25; shh -= 25; - } - if (damage()&FL_DAMAGE_ALL) draw_box(box(),sxx,syy,sww,shh,color()); - Fl_SliderX::draw(sxx+Fl::box_dx(box()), - syy+Fl::box_dy(box()), - sww-Fl::box_dw(box()), - shh-Fl::box_dh(box())); - draw_box(box(),bxx,byy,bww,bhh,color()); - char buf[128]; - format(buf); - fl_font(textfont(), textsize()); - fl_color(active_r() ? textcolor() : fl_inactive(textcolor())); - fl_draw(buf, bxx, byy, bww, bhh, FL_ALIGN_CLIP); + + int sxx = x(), syy = y(), sww = w(), shh = h(); + int bxx = x(), byy = y(), bww = w(), bhh = h(); + if (horizontal()) { + input.resize(x(), y(), 35, h()); + bww = 35; sxx += 35; sww -= 35; + } else { + input.resize(x(), y(), w(), 25 ); + syy += 25; bhh = 25; shh -= 25; + } + if (damage()&FL_DAMAGE_ALL) draw_box(box(),sxx,syy,sww,shh,color()); + Fl_SliderX::draw(sxx+Fl::box_dx(box()), + syy+Fl::box_dy(box()), + sww-Fl::box_dw(box()), + shh-Fl::box_dh(box())); + draw_box(box(),bxx,byy,bww,bhh,color()); + + if (damage()&~FL_DAMAGE_CHILD) input.clear_damage(FL_DAMAGE_ALL); + input.box(box()); + input.color(color(), selection_color()); + Fl_Widget *i = &input; i->draw(); // calls protected input.draw() + input.clear_damage(); } int Fl_Value_SliderX::handle(int event) { - if (event == FL_PUSH && Fl::visible_focus()) { - Fl::focus(this); - redraw(); - } - int sxx = x(), syy = y(), sww = w(), shh = h(); - if (horizontal()) { - sxx += 35; sww -= 35; - } else { - syy += 25; shh -= 25; - } - return Fl_SliderX::handle(event, - sxx+Fl::box_dx(box()), - syy+Fl::box_dy(box()), - sww-Fl::box_dw(box()), - shh-Fl::box_dh(box())); + if (event == FL_PUSH && Fl::visible_focus()) { + Fl::focus(this); + redraw(); + } + + int sxx = x(), syy = y(), sww = w(), shh = h(); + if (horizontal()) { + sxx += 35; sww -= 35; + } else { + syy += 25; shh -= 25; + } + + double v; + int delta; + int mx = Fl::event_x_root(); + static int ix, drag; +// input.when(when()); + switch (event) { + case FL_ENTER: + return 1; + case FL_LEAVE: + if ( ! drag ) + fl_cursor( FL_CURSOR_DEFAULT ); + return 1; + case FL_MOVE: + if ( drag || Fl::event_inside( &input ) ) + fl_cursor( FL_CURSOR_WE ); + else + fl_cursor( FL_CURSOR_DEFAULT ); + return 1; + case FL_PUSH: +// if (!step()) goto DEFAULT; + if ( Fl::event_inside(&input) ) + { + input.handle(event); + ix = mx; + drag = Fl::event_button(); + handle_push(); + return 1; + } + goto DEFAULT; + break; + case FL_DRAG: + if ( ! drag ) + goto DEFAULT; + + fl_cursor( FL_CURSOR_WE ); + +// if (!step()) goto DEFAULT; + delta = mx-ix; + if (delta > 5) delta -= 5; + else if (delta < -5) delta += 5; + else delta = 0; + + switch (drag) { + case 3: v = increment(previous_value(), delta*100); break; + case 2: v = increment(previous_value(), delta*10); break; + default:v = increment(previous_value(), delta); break; + } + +// v = previous_value() + delta * ( fabs( maximum() - minimum() ) * 0.001 ); + + v = round(v); + v = soft()?softclamp(v):clamp(v); + handle_drag(v); + value_damage(); + return 1; + case FL_RELEASE: + + if ( ! drag ) + goto DEFAULT; + + // if (!step()) goto DEFAULT; + if (value() != previous_value() || !Fl::event_is_click()) + handle_release(); + + drag = 0; + + fl_cursor( FL_CURSOR_DEFAULT ); + + /* else { */ + /* Fl_Widget_Tracker wp(&input); */ + /* input.handle(FL_PUSH); */ + /* if (wp.exists()) */ + /* input.handle(FL_RELEASE); */ + /* } */ + return 1; + case FL_FOCUS: + return input.take_focus(); + case FL_UNFOCUS: + { + input_cb(&input,this); + return 1; + } + case FL_SHORTCUT: + return input.handle(event); + + } + +DEFAULT: + + int r = Fl_SliderX::handle(event, + sxx+Fl::box_dx(box()), + syy+Fl::box_dy(box()), + sww-Fl::box_dw(box()), + shh-Fl::box_dh(box())); + + if ( r ) + { + return r; + } + else + { + input.type(((step() - floor(step()))>0.0 || step() == 0.0) ? FL_FLOAT_INPUT : FL_INT_INPUT); + return input.handle(event); + } } diff --git a/FL/Fl_Value_SliderX.H b/FL/Fl_Value_SliderX.H index 5d081c4..39492b0 100644 --- a/FL/Fl_Value_SliderX.H +++ b/FL/Fl_Value_SliderX.H @@ -21,6 +21,7 @@ #define Fl_Value_SliderX_H #include "Fl_SliderX.H" +#include /** The Fl_Value_SliderX widget is a Fl_SliderX widget @@ -29,26 +30,70 @@ \image latex value_slider.png "Fl_Value_SliderX" width=4cm */ class FL_EXPORT Fl_Value_SliderX : public Fl_SliderX { - Fl_Font textfont_; - Fl_Fontsize textsize_; - Fl_Color textcolor_; + /* This is the encapsulated Fl_input attribute to which + this class delegates the value font, color and shortcut */ + Fl_Input input; + +private: + char soft_; + static void input_cb(Fl_Widget*,void*); + virtual void value_damage(); // cause damage() due to value() changing + protected: void draw(); public: int handle(int); Fl_Value_SliderX(int x,int y,int w,int h, const char *l = 0); - /** Gets the typeface of the text in the value box. */ - Fl_Font textfont() const {return textfont_;} - /** Sets the typeface of the text in the value box. */ - void textfont(Fl_Font s) {textfont_ = s;} - /** Gets the size of the text in the value box. */ - Fl_Fontsize textsize() const {return textsize_;} - /** Sets the size of the text in the value box. */ - void textsize(Fl_Fontsize s) {textsize_ = s;} - /** Gets the color of the text in the value box. */ - Fl_Color textcolor() const {return textcolor_;} - /** Sets the color of the text in the value box. */ - void textcolor(Fl_Color s) {textcolor_ = s;} + virtual ~Fl_Value_SliderX ( ); + +/** See void Fl_Value_Input::soft(char s) */ + void soft(char s) {soft_ = s;} + /** + If "soft" is turned on, the user is allowed to drag + the value outside the range. If they drag the value to one of + the ends, let go, then grab again and continue to drag, they can + get to any value. The default is true. + */ + char soft() const {return soft_;} + /** + Returns the current shortcut key for the Input. + \see Fl_Value_Input::shortcut(int) + */ + int shortcut() const {return input.shortcut();} + /** + Sets the shortcut key to \p s. Setting this + overrides the use of '&' in the label(). The value is a bitwise + OR of a key and a set of shift flags, for example FL_ALT | 'a' + , FL_ALT | (FL_F + 10), or just 'a'. A value + of 0 disables the shortcut. + + The key can be any value returned by + Fl::event_key(), but will usually be an ASCII letter. Use + a lower-case letter unless you require the shift key to be held down. + + The shift flags can be any set of values accepted by + Fl::event_state(). If the bit is on that shift key must + be pushed. Meta, Alt, Ctrl, and Shift must be off if they are not in + the shift flags (zero for the other bits indicates a "don't care" + setting). + */ + void shortcut(int s) {input.shortcut(s);} + /** Gets the typeface of the text in the value box. */ + Fl_Font textfont() const {return input.textfont();} + /** Sets the typeface of the text in the value box. */ + void textfont(Fl_Font s) {input.textfont(s);} + /** Gets the size of the text in the value box. */ + Fl_Fontsize textsize() const {return input.textsize();} + /** Sets the size of the text in the value box. */ + void textsize(Fl_Fontsize s) {input.textsize(s);} + /** Gets the color of the text in the value box. */ + Fl_Color textcolor() const {return input.textcolor();} + /** Sets the color of the text in the value box.*/ + void textcolor(Fl_Color n) {input.textcolor(n);} + /** Gets the color of the text cursor. The text cursor is black by default. */ + Fl_Color cursor_color() const {return input.cursor_color();} + /** Sets the color of the text cursor. The text cursor is black by default. */ + void cursor_color(Fl_Color n) {input.cursor_color(n);} }; #endif diff --git a/mixer/src/Controller_Module.C b/mixer/src/Controller_Module.C index 184f570..6d98c47 100644 --- a/mixer/src/Controller_Module.C +++ b/mixer/src/Controller_Module.C @@ -467,6 +467,8 @@ Controller_Module::connect_to ( Port *p ) } } + o->precision(2); + o->value( p->control_value() ); _type = SLIDER; @@ -813,9 +815,8 @@ Controller_Module::menu ( void ) void Controller_Module::draw ( void ) { - draw_box(x(),y(),w(),h()); Fl_Group::draw(); - + draw_box(x(),y(),w(),h()); if ( learn_mode() ) { diff --git a/mixer/src/Module_Parameter_Editor.C b/mixer/src/Module_Parameter_Editor.C index 46ad00d..8029d46 100644 --- a/mixer/src/Module_Parameter_Editor.C +++ b/mixer/src/Module_Parameter_Editor.C @@ -249,12 +249,22 @@ Module_Parameter_Editor::make_controls ( void ) o->align(FL_ALIGN_TOP); o->box( FL_DOWN_BOX ); - o->precision( 2 ); /* a couple of plugins have ridiculously small units */ - if ( p->hints.maximum < 0.5f ) - o->precision( 5 ); + float r = fabs( p->hints.maximum - p->hints.minimum ); + + if ( r <= 0.01f ) + o->precision( 4 ); + else if ( r <= 0.1f ) + o->precision( 3 ); + else if ( r <= 100.0f ) + o->precision( 2 ); + else if ( r <= 5000.0f ) + o->precision( 1 ); + /* else if ( r <= 10000.0f ) */ + /* o->precision( 1 ); */ + else + o->precision( 0 ); -// o->step( fabs( ( o->maximum() - o->minimum() ) ) / 32.0f ); } else { @@ -285,10 +295,21 @@ Module_Parameter_Editor::make_controls ( void ) o->minimum( p->hints.maximum ); } - o->precision( 2 ); /* a couple of plugins have ridiculously small units */ - if ( p->hints.maximum < 0.5f ) - o->precision( 5 ); + float r = fabs( p->hints.maximum - p->hints.minimum ); + + if ( r <= 0.01f ) + o->precision( 4 ); + else if ( r <= 0.1f ) + o->precision( 3 ); + else if ( r <= 100.0f ) + o->precision( 2 ); + else if ( r <= 5000.0f ) + o->precision( 1 ); + /* else if ( r <= 10000.0f ) */ + /* o->precision( 1 ); */ + else + o->precision( 0 ); o->textsize( 8 ); // o->box( FL_NO_BOX );