Commit 91cf7978 authored by Ivica Bukvic's avatar Ivica Bukvic
Browse files

Proper fix to support all legacy knob features

*Yay! Got the log working cleanly and made code a lot more readable.

*Added support for log and reverse log.

*Improved coloring/drawing.

*Support for dragging that is in line with the object height (legacy behavior). This actually makes sense since it poses as a circular slider whose length (or height in this case) corresponds with the movable range. It also prevents the need to use a large amount of the screen estate to change its value with a mouse. Besides, there is always a shift+click.
parent 57433e71
Pipeline #2923 failed with stage
in 225 minutes and 46 seconds
...@@ -45,8 +45,6 @@ ...@@ -45,8 +45,6 @@
#define IEM_KNOB_DEFAULTSIZE 32 #define IEM_KNOB_DEFAULTSIZE 32
static log_warning = 0;
/* ------------ knob gui-vertical slider ----------------------- */ /* ------------ knob gui-vertical slider ----------------------- */
t_widgetbehavior knob_widgetbehavior; t_widgetbehavior knob_widgetbehavior;
...@@ -70,7 +68,7 @@ static void knob_draw_update(t_knob *x, t_glist *glist) ...@@ -70,7 +68,7 @@ static void knob_draw_update(t_knob *x, t_glist *glist)
{ {
t_float normalized_value = (t_float)((x->x_pos-x->x_min)/(x->x_max - x->x_min)); t_float normalized_value = (t_float)((x->x_pos-x->x_min)/(x->x_max - x->x_min));
/* compute dial:*/ /* compute dial:*/
t_float radius = 0.5*(t_float)x->x_gui.x_h; t_float radius = 0.51*(t_float)x->x_gui.x_h;
t_float angle = 2.0/9.0 + ((t_float)normalized_value * (2.0 * M_PI - (4.0/9.0))); t_float angle = 2.0/9.0 + ((t_float)normalized_value * (2.0 * M_PI - (4.0/9.0)));
/* center point: */ /* center point: */
int x1 = radius; int x1 = radius;
...@@ -244,8 +242,7 @@ static void knob_properties(t_gobj *z, t_glist *owner) ...@@ -244,8 +242,7 @@ static void knob_properties(t_gobj *z, t_glist *owner)
gui_s("size"); gui_i(x->x_gui.x_h); gui_s("size"); gui_i(x->x_gui.x_h);
gui_s("minimum_range"); gui_f(x->x_min); gui_s("minimum_range"); gui_f(x->x_min);
gui_s("maximum_range"); gui_f(x->x_max); gui_s("maximum_range"); gui_f(x->x_max);
/* spent 2 days trying to fix--life is too short */ gui_s("log_scaling"); gui_i(x->x_lin0_log1);
// gui_s("log_scaling"); gui_i(x->x_lin0_log1);
gui_s("init"); gui_i(x->x_gui.x_loadinit); gui_s("init"); gui_i(x->x_gui.x_loadinit);
gui_s("steady_on_click"); gui_i(x->x_steady); gui_s("steady_on_click"); gui_i(x->x_steady);
gui_s("send_symbol"); gui_s(srl[0]->s_name); gui_s("send_symbol"); gui_s(srl[0]->s_name);
...@@ -284,12 +281,12 @@ static void knob_dialog(t_knob *x, t_symbol *s, int argc, t_atom *argv) ...@@ -284,12 +281,12 @@ static void knob_dialog(t_knob *x, t_symbol *s, int argc, t_atom *argv)
int h = (int)atom_getintarg(1, argc, argv); int h = (int)atom_getintarg(1, argc, argv);
double min = (double)atom_getfloatarg(2, argc, argv); double min = (double)atom_getfloatarg(2, argc, argv);
double max = (double)atom_getfloatarg(3, argc, argv); double max = (double)atom_getfloatarg(3, argc, argv);
//int lilo = (int)atom_getintarg(4, argc, argv); int lilo = (int)atom_getintarg(4, argc, argv);
int steady = (int)atom_getintarg(17, argc, argv); int steady = (int)atom_getintarg(17, argc, argv);
int sr_flags; int sr_flags;
//if(lilo != 0) lilo = 1; if(lilo != 0) lilo = 1;
//x->x_lin0_log1 = lilo; x->x_lin0_log1 = lilo;
if(steady) if(steady)
x->x_steady = 1; x->x_steady = 1;
else else
...@@ -311,9 +308,9 @@ static void knob_motion(t_knob *x, t_floatarg dx, t_floatarg dy) ...@@ -311,9 +308,9 @@ static void knob_motion(t_knob *x, t_floatarg dx, t_floatarg dy)
if (x->x_gui.x_reverse) if (x->x_gui.x_reverse)
dy = -dy; dy = -dy;
if(x->x_gui.x_finemoved) if(x->x_gui.x_finemoved)
x->x_pos -= dy * 0.01; x->x_pos -= dy * 0.01 * ((abs(x->x_max - x->x_min))/ x->x_gui.x_h);
else else
x->x_pos -= dy; x->x_pos -= dy * ((abs(x->x_max - x->x_min))/ x->x_gui.x_h);
if (!x->x_gui.x_reverse) if (!x->x_gui.x_reverse)
{ {
...@@ -330,35 +327,37 @@ static void knob_motion(t_knob *x, t_floatarg dx, t_floatarg dy) ...@@ -330,35 +327,37 @@ static void knob_motion(t_knob *x, t_floatarg dx, t_floatarg dy)
x->x_pos = x->x_min; x->x_pos = x->x_min;
} }
t_float norm_val = (x->x_pos - x->x_min) / (x->x_max - x->x_min); /* ico@vt.edu 2020-09-25
/*if (x->x_lin0_log1) DO NOT ERASE -- this took 2 days to flesh out from the old code and can be now reused for other purposes
{ t_float norm_val = (x->x_pos - x->x_min) / (x->x_max - x->x_min);
t_float max; t_float log_norm_val = log(1 + (norm_val * 99))/(log(100));
t_float exp_norm_val = (exp(norm_val * log(100))/exp(log(100)) - 0.01) / 0.99;
post("norm_val=%f log=%f log*norm=%f exp=%f exp*norm=%f",
norm_val,
log(1 + (norm_val * 99))/(log(100)),
norm_val * log(1 + (norm_val * 99))/(log(100)),
(exp(norm_val * log(100))/exp(log(100)) - 0.01) / 0.99,
norm_val * exp(norm_val * log(100))/exp(log(100))
);
t_float norm2log = log_norm_val * (abs(x->x_max-x->x_min)) + x->x_min;
t_float log2norm = (exp(log_norm_val * log(100))/exp(log(100)) - 0.01) / 0.99 * (abs(x->x_max-x->x_min)) + x->x_min;
post("norm2log=%f log2norm=%f", norm2log, (exp(log_norm_val * log(100))/exp(log(100)) - 0.01) / 0.99 * (abs(x->x_max-x->x_min)) + x->x_min);
*/
if (!x->x_gui.x_reverse) if (x->x_lin0_log1)
{
t_float norm_val = (x->x_pos - x->x_min) / (x->x_max - x->x_min);
if (x->x_gui.x_reverse)
{ {
// ico@vt.edu 2020-09-24: giving up on this mess... x->x_val = x->x_max - (exp((1 - norm_val) * log(100))/exp(log(100)) - 0.01) / 0.99 * (x->x_max-x->x_min);
// if someone else wants to figure out how to get inverse value in a universal
// way please lemme know
max = exp((x->x_max * log(x->x_max - x->x_min))/(x->x_max - x->x_min)
- x->x_min) + x->x_min - 1;
x->x_val = exp((x->x_pos * log(x->x_max - x->x_min))/(x->x_max - x->x_min) - x->x_min)
+ x->x_min - 1; //1.569453
post("x->x_pos=%f max=%f val=%f", x->x_pos, max, x->x_val);
x->x_val = x->x_val / max * (x->x_max - x->x_min) + x->x_min;
} }
else else
{ {
max = exp((x->x_max * log(abs(x->x_max - x->x_min)))/(x->x_max - x->x_min) x->x_val = (exp(norm_val * log(100))/exp(log(100)) - 0.01) / 0.99 * (abs(x->x_max-x->x_min)) + x->x_min;
- x->x_min) + x->x_max - 1.569453 + 0.034129 + 0.00214;
x->x_val = exp((x->x_pos * log(abs(x->x_max - x->x_min)))/(x->x_max - x->x_min) - x->x_max)
+ x->x_max - 1.569453 + 0.034129;
post("x->x_pos=%f max=%f val=%f", x->x_pos, max, x->x_val);
x->x_val = (x->x_val / max) * (abs(x->x_max - x->x_min)) + x->x_max;
} }
} }
else*/ else
x->x_val = x->x_pos; x->x_val = x->x_pos;
if (!x->x_gui.x_reverse) if (!x->x_gui.x_reverse)
{ {
...@@ -396,22 +395,24 @@ static void knob_click(t_knob *x, t_floatarg xpos, t_floatarg ypos, ...@@ -396,22 +395,24 @@ static void knob_click(t_knob *x, t_floatarg xpos, t_floatarg ypos,
if (angle < 14) angle = 14; if (angle < 14) angle = 14;
if (angle > 346) angle = 346; if (angle > 346) angle = 346;
t_float norm_val = (angle - 14)/332; t_float norm_val = (angle - 14)/332;
/*if (x->x_lin0_log1)
if (x->x_lin0_log1)
{ {
if (x->x_gui.x_reverse)
{
x->x_val = x->x_max - (exp((1 - norm_val) * log(100))/exp(log(100)) - 0.01) / 0.99 * (x->x_max-x->x_min);
}
else
{
x->x_val = (exp(norm_val * log(100))/exp(log(100)) - 0.01) / 0.99 * (abs(x->x_max-x->x_min)) + x->x_min;
}
x->x_pos = ((x->x_max - x->x_min) * norm_val) + x->x_min; x->x_pos = ((x->x_max - x->x_min) * norm_val) + x->x_min;
t_float min = exp((x->x_min * log(x->x_max - x->x_min))/(x->x_max - x->x_min) - x->x_min)
+ x->x_min - 1;
t_float max = exp((x->x_max * log(x->x_max - x->x_min))/(x->x_max - x->x_min) - x->x_min)
+ x->x_min - 1 - min;
x->x_val = exp((x->x_pos * log(x->x_max - x->x_min))/(x->x_max - x->x_min) - x->x_min)
+ x->x_min - 1 - min;
x->x_val = x->x_val / max * (x->x_max - x->x_min) + x->x_min;
} }
else else
{*/ {
x->x_val = ((x->x_max - x->x_min) * norm_val) + x->x_min; x->x_val = ((x->x_max - x->x_min) * norm_val) + x->x_min;
x->x_pos = x->x_val; x->x_pos = x->x_val;
//} }
} }
if (x->x_gui.x_reverse) if (x->x_gui.x_reverse)
{ {
...@@ -452,8 +453,6 @@ static int knob_newclick(t_gobj *z, struct _glist *glist, ...@@ -452,8 +453,6 @@ static int knob_newclick(t_gobj *z, struct _glist *glist,
static void knob_set(t_knob *x, t_floatarg f) static void knob_set(t_knob *x, t_floatarg f)
{ {
//double g;
if (x->x_gui.x_reverse) /* bugfix */ if (x->x_gui.x_reverse) /* bugfix */
{ {
if (f > x->x_min) if (f > x->x_min)
...@@ -469,19 +468,31 @@ static void knob_set(t_knob *x, t_floatarg f) ...@@ -469,19 +468,31 @@ static void knob_set(t_knob *x, t_floatarg f)
f = x->x_min; f = x->x_min;
} }
x->x_val = f; x->x_val = f;
/*if (x->x_lin0_log1) if (x->x_lin0_log1)
{ {
if (!x->x_gui.x_reverse && x->x_val == x->x_min) if (!x->x_gui.x_reverse && x->x_val == x->x_min)
x->x_pos = x->x_min; x->x_pos = x->x_min;
else if (x->x_gui.x_reverse && x->x_val == x->x_max) else if (x->x_gui.x_reverse && x->x_val == x->x_max)
x->x_pos = x->x_max; x->x_pos = x->x_max;
else else
x->x_pos = (log(x->x_val - x->x_min + 1)/log(x->x_max - x->x_min)) * (x->x_max - x->x_min) + x->x_min; {
t_float norm_val = (x->x_val - x->x_min) / (x->x_max - x->x_min);
if (x->x_gui.x_reverse)
{
t_float log_norm_val = log(100 - (norm_val * 99))/(log(100));
x->x_pos = log_norm_val * (abs(x->x_max-x->x_min)) + x->x_max;
}
else
{
t_float log_norm_val = log(1 + (norm_val * 99))/(log(100));
x->x_pos = log_norm_val * (abs(x->x_max-x->x_min)) + x->x_min;
}
}
} }
else else
{*/ {
x->x_pos = x->x_val; x->x_pos = x->x_val;
//} }
if (glist_isvisible(x->x_gui.x_glist)) if (glist_isvisible(x->x_gui.x_glist))
(*x->x_gui.x_draw)(x, x->x_gui.x_glist, IEM_GUI_DRAW_MODE_UPDATE); (*x->x_gui.x_draw)(x, x->x_gui.x_glist, IEM_GUI_DRAW_MODE_UPDATE);
} }
...@@ -549,15 +560,15 @@ static void knob_label_font(t_knob *x, t_symbol *s, int ac, t_atom *av) ...@@ -549,15 +560,15 @@ static void knob_label_font(t_knob *x, t_symbol *s, int ac, t_atom *av)
static void knob_log(t_knob *x) static void knob_log(t_knob *x)
{ {
//x->x_lin0_log1 = 1; x->x_lin0_log1 = 1;
error("knob: lin and log commands are not anymore supported. Ignoring..."); //error("knob: lin and log commands are not anymore supported. Ignoring...");
knob_check_minmax(x, x->x_min, x->x_max); knob_check_minmax(x, x->x_min, x->x_max);
} }
static void knob_lin(t_knob *x) static void knob_lin(t_knob *x)
{ {
error("knob: lin and log commands are not anymore supported. Ignoring..."); //error("knob: lin and log commands are not anymore supported. Ignoring...");
//x->x_lin0_log1 = 0; x->x_lin0_log1 = 0;
} }
static void knob_init(t_knob *x, t_floatarg f) static void knob_init(t_knob *x, t_floatarg f)
...@@ -693,7 +704,7 @@ static void *knob_new(t_symbol *s, int argc, t_atom *argv) ...@@ -693,7 +704,7 @@ static void *knob_new(t_symbol *s, int argc, t_atom *argv)
h = (int)atom_getintarg(1, argc, argv); h = (int)atom_getintarg(1, argc, argv);
min = (double)atom_getfloatarg(2, argc, argv); min = (double)atom_getfloatarg(2, argc, argv);
max = (double)atom_getfloatarg(3, argc, argv); max = (double)atom_getfloatarg(3, argc, argv);
//lilo = (int)atom_getintarg(4, argc, argv); lilo = (int)atom_getintarg(4, argc, argv);
iem_inttosymargs(&x->x_gui, atom_getintarg(5, argc, argv)); iem_inttosymargs(&x->x_gui, atom_getintarg(5, argc, argv));
iemgui_new_getnames(&x->x_gui, 6, argv); iemgui_new_getnames(&x->x_gui, 6, argv);
ldx = (int)atom_getintarg(9, argc, argv); ldx = (int)atom_getintarg(9, argc, argv);
...@@ -711,14 +722,6 @@ static void *knob_new(t_symbol *s, int argc, t_atom *argv) ...@@ -711,14 +722,6 @@ static void *knob_new(t_symbol *s, int argc, t_atom *argv)
x->x_gui.x_fsf.x_snd_able = 1; x->x_gui.x_fsf.x_snd_able = 1;
x->x_gui.x_fsf.x_rcv_able = 1; x->x_gui.x_fsf.x_rcv_able = 1;
*/ */
if (!log_warning)
{
post("Please note this is a Purr-Data reimplementation of the flatgui/knob \
(a.k.a. footils knob) which does not support logarithmic scaling. All \
other features remain supported.");
log_warning = 1;
}
x->x_gui.x_glist = (t_glist *)canvas_getcurrent(); x->x_gui.x_glist = (t_glist *)canvas_getcurrent();
if (x->x_gui.x_loadinit) if (x->x_gui.x_loadinit)
x->x_val = v; x->x_val = v;
......
...@@ -4951,8 +4951,8 @@ function gui_configure_mknob(cid, tag, size, bg_color, fg_color, ...@@ -4951,8 +4951,8 @@ function gui_configure_mknob(cid, tag, size, bg_color, fg_color,
"knob_w": size, "knob_w": size,
fill: "none", fill: "none",
stroke: bg_color, stroke: bg_color,
"stroke-width": 3, "stroke-width": 4,
"d": describeArc(size/2, size/2, size/2 - 1, 193, 528), "d": describeArc(size/2, size/2, size/2 - 1, 192.9, 528.1),
}); });
} }
} }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment