Handle generic-midi bindings per session.
authorRobin Gareus <robin@gareus.org>
Thu, 4 Oct 2018 00:30:21 +0000 (02:30 +0200)
committerRobin Gareus <robin@gareus.org>
Thu, 4 Oct 2018 00:30:21 +0000 (02:30 +0200)
This allows to special-cases session-specific control-surface state.
e.g. midi-learn.

Only restore midi-learned, session-specific, bindings when loading a
session with generic-midi enabled.

Also dis/re-enable generic-midi resets midi-learned, but no other
session-independent settings.

This also handles the edge case:
 1) load global config, generic-midi = ON, w/ bindings.
    state is remembered as cpi->state
 2) load session-condig, generic-midi = OFF, cpi->state is retained
 3) user enables the surface, cpi->state from (1) is applied.
 -> invalid bindings applied -> fail

libs/ardour/control_protocol_manager.cc
libs/ardour/globals.cc
libs/ardour/session_state.cc
libs/surfaces/generic_midi/generic_midi_control_protocol.cc

index c1c595ebb29ee6363e4b0dc9ce0e47a13a197db1..048ff3f7d5dac16bc7fca17fbe7ea96dad430610 100644 (file)
@@ -452,7 +452,7 @@ ControlProtocolManager::cpi_by_name (string name)
 }
 
 int
-ControlProtocolManager::set_state (const XMLNode& node, int /*version*/)
+ControlProtocolManager::set_state (const XMLNode& node, int session_specific_state /* here: not version */)
 {
        XMLNodeList clist;
        XMLNodeConstIterator citer;
@@ -483,6 +483,7 @@ ControlProtocolManager::set_state (const XMLNode& node, int /*version*/)
                                if (active) {
                                        delete cpi->state;
                                        cpi->state = new XMLNode (**citer);
+                                       cpi->state->set_property (X_("session-state"), session_specific_state ? true : false);
                                        if (_session) {
                                                instantiate (*cpi);
                                        } else {
@@ -492,6 +493,7 @@ ControlProtocolManager::set_state (const XMLNode& node, int /*version*/)
                                        if (!cpi->state) {
                                                cpi->state = new XMLNode (**citer);
                                                cpi->state->set_property (X_("active"), false);
+                                               cpi->state->set_property (X_("session-state"), session_specific_state ? true : false);
                                        }
                                        cpi->requested = false;
                                        if (_session) {
index fc17b3a5e9f527ce29a6adfdc32ff0ebb0a535f5..eab0b93a41345d57024997126cbd748c7111beb1 100644 (file)
@@ -599,7 +599,7 @@ ARDOUR::init_post_engine ()
        XMLNode* node;
 
        if ((node = Config->control_protocol_state()) != 0) {
-               ControlProtocolManager::instance().set_state (*node, Stateful::loading_state_version);
+               ControlProtocolManager::instance().set_state (*node, 0 /* here: global-config state */);
        }
 
        if ((node = Config->transport_master_state()) != 0) {
index 1335c554cb286890d3ee14d9effdc4b2354dcdb6..0c974fcc84f0649c6a555ef374e9bafd8f82fb7c 100644 (file)
@@ -1729,7 +1729,7 @@ Session::set_state (const XMLNode& node, int version)
        }
 
        if ((child = find_named_node (node, ControlProtocolManager::state_node_name)) != 0) {
-               ControlProtocolManager::instance().set_state (*child, version);
+               ControlProtocolManager::instance().set_state (*child, 1 /* here: session-specific state */);
        }
 
        if ((child = find_named_node (node, "Script"))) {
index 4d931b8fe01fcb96198c40ebcc77df0f941fc950..214c9fede7cdb0ba6cba77ac50c301d2ef6da10f 100644 (file)
@@ -669,7 +669,10 @@ GenericMidiControlProtocol::set_state (const XMLNode& node, int version)
         * <Controls><MidiControllable>...</MidiControllable><Controls> section
         */
 
-       {
+       bool load_dynamic_bindings = false;
+       node.get_property ("session-state", load_dynamic_bindings);
+
+       if (load_dynamic_bindings) {
                Glib::Threads::Mutex::Lock lm2 (controllables_lock);
                nlist = node.children(); // "Controls"