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 <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
|
Creates a new Fl_Value_SliderX widget using the given
|
||||||
position, size, and label string. The default boxtype is FL_DOWN_BOX.
|
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) {
|
: Fl_SliderX(X,Y,W,H,l),input(X, Y, W, H, 0) {
|
||||||
step(1,100);
|
step(1,100);
|
||||||
textfont_ = FL_HELVETICA;
|
|
||||||
textsize_ = 10;
|
soft_ = 0;
|
||||||
textcolor_ = FL_FOREGROUND_COLOR;
|
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 sxx = x(), syy = y(), sww = w(), shh = h();
|
||||||
int bxx = x(), byy = y(), bww = w(), bhh = h();
|
int bxx = x(), byy = y(), bww = w(), bhh = h();
|
||||||
if (horizontal()) {
|
if (horizontal()) {
|
||||||
|
input.resize(x(), y(), 35, h());
|
||||||
bww = 35; sxx += 35; sww -= 35;
|
bww = 35; sxx += 35; sww -= 35;
|
||||||
} else {
|
} else {
|
||||||
|
input.resize(x(), y(), w(), 25 );
|
||||||
syy += 25; bhh = 25; shh -= 25;
|
syy += 25; bhh = 25; shh -= 25;
|
||||||
}
|
}
|
||||||
if (damage()&FL_DAMAGE_ALL) draw_box(box(),sxx,syy,sww,shh,color());
|
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()),
|
sww-Fl::box_dw(box()),
|
||||||
shh-Fl::box_dh(box()));
|
shh-Fl::box_dh(box()));
|
||||||
draw_box(box(),bxx,byy,bww,bhh,color());
|
draw_box(box(),bxx,byy,bww,bhh,color());
|
||||||
char buf[128];
|
|
||||||
format(buf);
|
if (damage()&~FL_DAMAGE_CHILD) input.clear_damage(FL_DAMAGE_ALL);
|
||||||
fl_font(textfont(), textsize());
|
input.box(box());
|
||||||
fl_color(active_r() ? textcolor() : fl_inactive(textcolor()));
|
input.color(color(), selection_color());
|
||||||
fl_draw(buf, bxx, byy, bww, bhh, FL_ALIGN_CLIP);
|
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) {
|
||||||
|
@ -62,16 +115,117 @@ int Fl_Value_SliderX::handle(int event) {
|
||||||
Fl::focus(this);
|
Fl::focus(this);
|
||||||
redraw();
|
redraw();
|
||||||
}
|
}
|
||||||
|
|
||||||
int sxx = x(), syy = y(), sww = w(), shh = h();
|
int sxx = x(), syy = y(), sww = w(), shh = h();
|
||||||
if (horizontal()) {
|
if (horizontal()) {
|
||||||
sxx += 35; sww -= 35;
|
sxx += 35; sww -= 35;
|
||||||
} else {
|
} else {
|
||||||
syy += 25; shh -= 25;
|
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()),
|
sxx+Fl::box_dx(box()),
|
||||||
syy+Fl::box_dy(box()),
|
syy+Fl::box_dy(box()),
|
||||||
sww-Fl::box_dw(box()),
|
sww-Fl::box_dw(box()),
|
||||||
shh-Fl::box_dh(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_;
|
/* This is the encapsulated Fl_input attribute to which
|
||||||
Fl_Fontsize textsize_;
|
this class delegates the value font, color and shortcut */
|
||||||
Fl_Color textcolor_;
|
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);
|
||||||
|
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. */
|
/** 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. */
|
/** 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. */
|
/** 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. */
|
/** 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. */
|
/** Gets the color of the text in the value box. */
|
||||||
Fl_Color textcolor() const {return textcolor_;}
|
Fl_Color textcolor() const {return input.textcolor();}
|
||||||
/** Sets the color of the text in the value box.*/
|
/** Sets the color of the text in the value box.*/
|
||||||
void textcolor(Fl_Color s) {textcolor_ = s;}
|
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 )
|
float r = fabs( p->hints.maximum - p->hints.minimum );
|
||||||
o->precision( 5 );
|
|
||||||
|
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 )
|
float r = fabs( p->hints.maximum - p->hints.minimum );
|
||||||
o->precision( 5 );
|
|
||||||
|
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 );
|
||||||
|
|
Loading…
Reference in New Issue