OSC: Make pan controls work properly with MB too.
[ardour.git] / libs / evoral / src / ControlList.cpp
index d8665d339631a65bf2f6af7bbe04cf669ce17df5..2a013f26695e45394ab5026c362837e8908966f6 100644 (file)
@@ -36,6 +36,7 @@
 #include "evoral/Curve.hpp"
 #include "evoral/ParameterDescriptor.hpp"
 #include "evoral/TypeMap.hpp"
+#include "evoral/types.hpp"
 
 #include "pbd/compose.h"
 #include "pbd/debug.h"
@@ -451,12 +452,19 @@ ControlList::in_write_pass () const
        return _in_write_pass;
 }
 
-void
+bool
 ControlList::editor_add (double when, double value, bool with_guard)
 {
        /* this is for making changes from a graphical line editor
        */
 
+       ControlEvent cp (when, 0.0f);
+       iterator i = lower_bound (_events.begin(), _events.end(), &cp, time_comparator);
+
+       if (i != _events.end () && (*i)->when == when) {
+               return false;
+       }
+
        if (_events.empty()) {
 
                /* as long as the point we're adding is not at zero,
@@ -477,15 +485,18 @@ ControlList::editor_add (double when, double value, bool with_guard)
                maybe_add_insert_guard (when);
        }
 
-       ControlEvent cp (when, 0.0f);
-       iterator i = lower_bound (_events.begin(), _events.end(), &cp, time_comparator);
+       iterator result;
        DEBUG_TRACE (DEBUG::ControlList, string_compose ("editor_add: actually add when= %1 value= %2\n", when, value));
-       _events.insert (i, new ControlEvent (when, value));
+       result = _events.insert (i, new ControlEvent (when, value));
 
-       mark_dirty ();
+       if (i == result) {
+               return false;
+       }
 
+       mark_dirty ();
        maybe_signal_changed ();
 
+       return true;
 }
 
 void
@@ -574,8 +585,15 @@ ControlList::add (double when, double value, bool with_guards, bool with_initial
                        /* empty: add an "anchor" point if the point we're adding past time 0 */
 
                        if (when >= 1) {
-                               _events.insert (_events.end(), new ControlEvent (0, value));
-                               DEBUG_TRACE (DEBUG::ControlList, string_compose ("@%1 added default value %2 at zero\n", this, _default_value));
+                               if (_desc.toggled) {
+                                       const double opp_val = ((value < 0.5) ? 1.0 : 0.0);
+                                       _events.insert (_events.end(), new ControlEvent (0, opp_val));
+                                       DEBUG_TRACE (DEBUG::ControlList, string_compose ("@%1 added toggled value %2 at zero\n", this, opp_val));
+
+                               } else {
+                                       _events.insert (_events.end(), new ControlEvent (0, value));
+                                       DEBUG_TRACE (DEBUG::ControlList, string_compose ("@%1 added default value %2 at zero\n", this, _default_value));
+                               }
                        }
                }
 
@@ -1642,10 +1660,19 @@ ControlList::paste (const ControlList& alist, double pos, float /*times*/)
                        if (alist.parameter() != parameter()) {
                                const ParameterDescriptor& src_desc = alist.descriptor();
 
+                               // This does not work for logscale and will probably also not do
+                               // the right thing for integer_step and sr_dependent parameters.
+                               //
+                               // TODO various flags from from ARDOUR::ParameterDescriptor
+                               // to Evoral::ParameterDescriptor
+
                                value -= src_desc.lower;  // translate to 0-relative
                                value /= (src_desc.upper - src_desc.lower);  // normalize range
                                value *= (_desc.upper - _desc.lower);  // scale to our range
                                value += _desc.lower;  // translate to our offset
+                               if (_desc.toggled) {
+                                       value = (value < 0.5) ? 0.0 : 1.0;
+                               }
                        }
                        _events.insert (where, new ControlEvent((*i)->when + pos, value));
                        end = (*i)->when + pos;