Mixer: Enable keyboard value input and mouse value dragging on slider controls.
This commit is contained in:
parent
47f15d9937
commit
b7b3d499e5
|
@ -24,24 +24,76 @@
|
|||
#include <FL/fl_draw.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.
|
||||
*/
|
||||
Fl_Value_SliderX::Fl_Value_SliderX(int X, int Y, int W, int H, const char*l)
|
||||
: Fl_SliderX(X,Y,W,H,l) {
|
||||
: Fl_SliderX(X,Y,W,H,l),input(X, Y, W, H, 0) {
|
||||
step(1,100);
|
||||
textfont_ = FL_HELVETICA;
|
||||
textsize_ = 10;
|
||||
textcolor_ = FL_FOREGROUND_COLOR;
|
||||
|
||||
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()) {
|
||||
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());
|
||||
|
@ -50,11 +102,12 @@ void Fl_Value_SliderX::draw() {
|
|||
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);
|
||||
|
||||
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) {
|
||||
|
@ -62,16 +115,117 @@ int Fl_Value_SliderX::handle(int event) {
|
|||
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,
|
||||
|
||||
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
|
||||
|
||||
#include "Fl_SliderX.H"
|
||||
#include <FL/Fl_Input.H>
|
||||
|
||||
/**
|
||||
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);
|
||||
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 textfont_;}
|
||||
Fl_Font textfont() const {return input.textfont();}
|
||||
/** Sets the typeface of the text in the value box. */
|
||||
void textfont(Fl_Font s) {textfont_ = s;}
|
||||
void textfont(Fl_Font s) {input.textfont(s);}
|
||||
/** Gets the size of the text in the value box. */
|
||||
Fl_Fontsize textsize() const {return textsize_;}
|
||||
Fl_Fontsize textsize() const {return input.textsize();}
|
||||
/** Sets the size of the text in the value box. */
|
||||
void textsize(Fl_Fontsize s) {textsize_ = s;}
|
||||
void textsize(Fl_Fontsize s) {input.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;}
|
||||
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
|
||||
|
|
|
@ -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() )
|
||||
{
|
||||
|
|
|
@ -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 );
|
||||
|
|
Loading…
Reference in New Issue