X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Fardour_knob.cc;h=17fbff2f7ee11de3205e291078646b5c627ea7fa;hb=5e7d9d30e28e8022661497244ccd43a1f5a836c6;hp=21017a0e1a850b827477db7ace185c04758edc64;hpb=a7523c4e6d38b23c61072c5402f81cad14d5e772;p=ardour.git diff --git a/gtk2_ardour/ardour_knob.cc b/gtk2_ardour/ardour_knob.cc index 21017a0e1a..17fbff2f7e 100644 --- a/gtk2_ardour/ardour_knob.cc +++ b/gtk2_ardour/ardour_knob.cc @@ -37,6 +37,7 @@ #include "ardour_knob.h" #include "ardour_ui.h" #include "global_signals.h" +#include "timers.h" #include "canvas/colors.h" #include "canvas/utils.h" @@ -54,18 +55,21 @@ using namespace std; ArdourKnob::Element ArdourKnob::default_elements = ArdourKnob::Element (ArdourKnob::Arc); -ArdourKnob::ArdourKnob (Element e, bool arc_to_zero) +ArdourKnob::ArdourKnob (Element e, Flags flags) : _elements (e) , _hovering (false) , _grabbed_x (0) , _grabbed_y (0) , _val (0) - , _zero (0) + , _normal (0) , _dead_zone_delta (0) - , _arc_to_zero (arc_to_zero) + , _flags (flags) , _tooltip (this) { ARDOUR_UI_UTILS::ColorsChanged.connect (sigc::mem_fun (*this, &ArdourKnob::color_handler)); + + // watch automation :( + Timers::rapid_connect (sigc::mem_fun (*this, &ArdourKnob::controllable_changed)); } ArdourKnob::~ArdourKnob() @@ -86,8 +90,13 @@ ArdourKnob::render (cairo_t* cr, cairo_rectangle_t *) const float start_angle = ((180 - 65) * G_PI) / 180; const float end_angle = ((360 + 65) * G_PI) / 180; + float zero = 0; + if (_flags & ArcToZero) { + zero = _normal; + } + const float value_angle = start_angle + (_val * (end_angle - start_angle)); - const float zero_angle = start_angle + (_zero * (end_angle - start_angle)); + const float zero_angle = start_angle + (zero * (end_angle - start_angle)); float value_x = cos (value_angle); float value_y = sin (value_angle); @@ -130,7 +139,7 @@ ArdourKnob::render (cairo_t* cr, cairo_rectangle_t *) ArdourCanvas::color_to_rgba( arc_end_color, red_end, green_end, blue_end, unused ); //vary the arc color over the travel of the knob - float intensity = fabsf (_val - _zero) / std::max(_zero, (1.f - _zero)); + float intensity = fabsf (_val - zero) / std::max(zero, (1.f - zero)); const float intensity_inv = 1.0 - intensity; float r = intensity_inv * red_end + intensity * red_start; float g = intensity_inv * green_end + intensity * green_start; @@ -323,7 +332,7 @@ ArdourKnob::on_motion_notify_event (GdkEventMotion *ev) //scale the adjustment based on keyboard modifiers & GUI size const float ui_scale = max (1.f, ARDOUR_UI::ui_scale); - float scale = 0.0025 * ui_scale; + float scale = 0.0025 / ui_scale; if (ev->state & Keyboard::GainFineScaleModifier) { if (ev->state & Keyboard::GainExtraFineScaleModifier) { @@ -343,32 +352,34 @@ ArdourKnob::on_motion_notify_event (GdkEventMotion *ev) _grabbed_y = ev->y; float val = c->get_interface(); - const float px_deadzone = 42.f * ui_scale; - - if ((val - _zero) * (val - _zero + delta * scale) < 0) { - /* zero transition */ - const int tozero = (_zero - val) * scale; - int remain = delta - tozero; - if (abs (remain) > px_deadzone) { - /* slow down zero transitions */ - remain += (remain > 0) ? px_deadzone * -.5 : px_deadzone * .5; - delta = tozero + remain; - _dead_zone_delta = 0; - } else { - c->set_interface(_zero); - val = _zero; - _dead_zone_delta = remain / px_deadzone; + if (_flags & Detent) { + const float px_deadzone = 42.f * ui_scale; + + if ((val - _normal) * (val - _normal + delta * scale) < 0) { + /* detent */ + const int tozero = (_normal - val) * scale; + int remain = delta - tozero; + if (abs (remain) > px_deadzone) { + /* slow down passing the default value */ + remain += (remain > 0) ? px_deadzone * -.5 : px_deadzone * .5; + delta = tozero + remain; + _dead_zone_delta = 0; + } else { + c->set_value (c->normal()); + _dead_zone_delta = remain / px_deadzone; + return true; + } + } + + if (fabsf (rintf((val - _normal) / scale) + _dead_zone_delta) < 1) { + c->set_value (c->normal()); + _dead_zone_delta += delta / px_deadzone; return true; } - } - if (fabsf (rintf((val - _zero) / scale) + _dead_zone_delta) < 1) { - c->set_interface(_zero); - _dead_zone_delta += delta / px_deadzone; - return true; + _dead_zone_delta = 0; } - _dead_zone_delta = 0; val += delta * scale; c->set_interface(val); @@ -443,7 +454,7 @@ ArdourKnob::on_size_allocate (Allocation& alloc) void ArdourKnob::set_controllable (boost::shared_ptr c) { - watch_connection.disconnect (); //stop watching the old controllable + watch_connection.disconnect (); //stop watching the old controllable if (!c) return; @@ -451,11 +462,7 @@ ArdourKnob::set_controllable (boost::shared_ptr c) c->Changed.connect (watch_connection, invalidator(*this), boost::bind (&ArdourKnob::controllable_changed, this), gui_context()); - if (_arc_to_zero) { - _zero = c->internal_to_interface(c->normal()); - } else { - _zero = 0; - } + _normal = c->internal_to_interface(c->normal()); controllable_changed(); } @@ -464,10 +471,16 @@ void ArdourKnob::controllable_changed () { boost::shared_ptr c = binding_proxy.get_controllable(); + if (!c) return; - _val = c->get_interface(); //% of knob travel - _val = min( max(0.0f, _val), 1.0f); //range check + float val = c->get_interface(); + val = min( max(0.0f, val), 1.0f); // clamp + + if (val == _val) { + return; + } + _val = val; if (!_tooltip_prefix.empty()) { _tooltip.set_tip (_tooltip_prefix + c->get_user_string()); } @@ -550,7 +563,7 @@ ArdourKnob::add_elements (Element e) KnobPersistentTooltip::KnobPersistentTooltip (Gtk::Widget* w) - : PersistentTooltip (w, 3) + : PersistentTooltip (w, true, 3) , _dragging (false) { }