@@ -24,54 +24,208 @@ | |||||
#include <FL/fl_draw.H> | #include <FL/fl_draw.H> | ||||
#include <math.h> | #include <math.h> | ||||
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_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() { | 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) { | 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); | |||||
} | |||||
} | } | ||||
@@ -21,6 +21,7 @@ | |||||
#define Fl_Value_SliderX_H | #define Fl_Value_SliderX_H | ||||
#include "Fl_SliderX.H" | #include "Fl_SliderX.H" | ||||
#include <FL/Fl_Input.H> | |||||
/** | /** | ||||
The Fl_Value_SliderX widget is a Fl_SliderX widget | The Fl_Value_SliderX widget is a Fl_SliderX widget | ||||
@@ -29,26 +30,70 @@ | |||||
\image latex value_slider.png "Fl_Value_SliderX" width=4cm | \image latex value_slider.png "Fl_Value_SliderX" width=4cm | ||||
*/ | */ | ||||
class FL_EXPORT Fl_Value_SliderX : public Fl_SliderX { | 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: | protected: | ||||
void draw(); | void draw(); | ||||
public: | public: | ||||
int handle(int); | int handle(int); | ||||
Fl_Value_SliderX(int x,int y,int w,int h, const char *l = 0); | 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 | #endif | ||||
@@ -467,6 +467,8 @@ Controller_Module::connect_to ( Port *p ) | |||||
} | } | ||||
} | } | ||||
o->precision(2); | |||||
o->value( p->control_value() ); | o->value( p->control_value() ); | ||||
_type = SLIDER; | _type = SLIDER; | ||||
@@ -813,9 +815,8 @@ Controller_Module::menu ( void ) | |||||
void | void | ||||
Controller_Module::draw ( void ) | Controller_Module::draw ( void ) | ||||
{ | { | ||||
draw_box(x(),y(),w(),h()); | |||||
Fl_Group::draw(); | Fl_Group::draw(); | ||||
draw_box(x(),y(),w(),h()); | |||||
if ( learn_mode() ) | if ( learn_mode() ) | ||||
{ | { | ||||
@@ -249,12 +249,22 @@ Module_Parameter_Editor::make_controls ( void ) | |||||
o->align(FL_ALIGN_TOP); | o->align(FL_ALIGN_TOP); | ||||
o->box( FL_DOWN_BOX ); | o->box( FL_DOWN_BOX ); | ||||
o->precision( 2 ); | |||||
/* a couple of plugins have ridiculously small units */ | /* 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 | else | ||||
{ | { | ||||
@@ -285,10 +295,21 @@ Module_Parameter_Editor::make_controls ( void ) | |||||
o->minimum( p->hints.maximum ); | o->minimum( p->hints.maximum ); | ||||
} | } | ||||
o->precision( 2 ); | |||||
/* a couple of plugins have ridiculously small units */ | /* 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->textsize( 8 ); | ||||
// o->box( FL_NO_BOX ); | // o->box( FL_NO_BOX ); | ||||