Revert "C++11 Building - Use new style struct field inititializing" (this code
[ardour.git] / libs / surfaces / generic_midi / midicontrollable.cc
index f721e7fbbcf6c51eae33a77d2dbafb90486372f3..d36ccefd44eb44b2a206a7723771c24fb3324152 100644 (file)
@@ -61,11 +61,12 @@ MIDIControllable::MIDIControllable (GenericMidiControlProtocol* s, Port& p, bool
 
 MIDIControllable::MIDIControllable (GenericMidiControlProtocol* s, Port& p, Controllable& c, bool m)
        : _surface (s)
-       , controllable (&c)
        , _descriptor (0)
        , _port (p)
        , _momentary (m)
 {
+       set_controllable (&c);
+       
        _learned = true; /* from controllable */
        setting = false;
        last_value = 0; // got a better idea ?
@@ -113,7 +114,25 @@ MIDIControllable::drop_external_control ()
 void
 MIDIControllable::set_controllable (Controllable* c)
 {
+       if (c == controllable) {
+               return;
+       }
+       
+       controllable_death_connection.disconnect ();
+
        controllable = c;
+
+       if (controllable) {
+               last_controllable_value = controllable->get_value();
+       } else {
+               last_controllable_value = 0.0f; // is there a better value?
+       }
+
+       if (controllable) {
+               controllable->Destroyed.connect (controllable_death_connection, MISSING_INVALIDATOR,
+                                                boost::bind (&MIDIControllable::drop_controllable, this), 
+                                                MidiControlUI::instance());
+       }
 }
 
 void
@@ -150,6 +169,14 @@ MIDIControllable::control_to_midi (float val)
        float control_max = controllable->upper ();
        const float control_range = control_max - control_min;
 
+       if (controllable->is_toggle()) {
+               if (val >= (control_min + (control_range/2.0f))) {
+                       return max_value_for_type();
+               } else {
+                       return 0;
+               }
+       }
+
        return (val - control_min) / control_range * max_value_for_type ();
 }
 
@@ -199,10 +226,7 @@ MIDIControllable::lookup_controllable()
                return -1;
        }
 
-       controllable = c.get();
-       controllable->Destroyed.connect (controllable_death_connection, MISSING_INVALIDATOR,
-                                        boost::bind (&MIDIControllable::drop_controllable, this), 
-                                        MidiControlUI::instance());
+       set_controllable (c.get ());
 
        return 0;
 }
@@ -210,9 +234,7 @@ MIDIControllable::lookup_controllable()
 void
 MIDIControllable::drop_controllable ()
 {
-       cerr << "removed controllable\n";
-       controllable_death_connection.disconnect ();
-       controllable = 0;
+       set_controllable (0);
 }
 
 void
@@ -225,7 +247,9 @@ MIDIControllable::midi_sense_note (Parser &, EventTwoBytes *msg, bool /*is_on*/)
        }
 
        if (!controllable->is_toggle()) {
-               controllable->set_value (midi_to_control (msg->note_number));
+               if (control_additional == msg->note_number) {
+                       controllable->set_value (midi_to_control (msg->velocity));
+               }
        } else {
                if (control_additional == msg->note_number) {
                        controllable->set_value (controllable->get_value() > 0.5f ? 0.0f : 1.0f);
@@ -253,6 +277,7 @@ MIDIControllable::midi_sense_controller (Parser &, EventTwoBytes *msg)
        if (control_additional == msg->controller_number) {
 
                if (!controllable->is_toggle()) {
+
                        float new_value = msg->value;
                        float max_value = max(last_controllable_value, new_value);
                        float min_value = min(last_controllable_value, new_value);