- //step the value of the controllable
- boost::shared_ptr<PBD::Controllable> c = binding_proxy.get_controllable();
- if (c) {
- float val = c->get_interface();
- val += y_delta * scale;
- c->set_interface(val);
+ _grabbed_x = ev->x;
+ _grabbed_y = ev->y;
+ float val = c->get_interface();
+
+ 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(), Controllable::NoGroup);
+ _dead_zone_delta = remain / px_deadzone;
+ return true;
+ }
+ }
+
+ if (fabsf (rintf((val - _normal) / scale) + _dead_zone_delta) < 1) {
+ c->set_value (c->normal(), Controllable::NoGroup);
+ _dead_zone_delta += delta / px_deadzone;
+ return true;
+ }
+
+ _dead_zone_delta = 0;