OSC: make temp modes work with linked surfaces too
[ardour.git] / libs / surfaces / osc / osc.cc
index e0547012322e4699b7ac91b8a77330e45c3c1b3e..9c0e8e7d32b6a4df82b9c5945cbd901fb1743461 100644 (file)
@@ -586,8 +586,6 @@ OSC::register_callbacks()
                REGISTER_CALLBACK (serv, X_("/select/db_delta"), "f", sel_dB_delta);
                REGISTER_CALLBACK (serv, X_("/select/trimdB"), "f", sel_trim);
                REGISTER_CALLBACK (serv, X_("/select/hide"), "i", sel_hide);
-               REGISTER_CALLBACK (serv, X_("/select/bus/only"), "f", sel_bus_only);
-               REGISTER_CALLBACK (serv, X_("/select/bus/only"), "", sel_bus_only);
                REGISTER_CALLBACK (serv, X_("/select/previous"), "f", sel_previous);
                REGISTER_CALLBACK (serv, X_("/select/previous"), "", sel_previous);
                REGISTER_CALLBACK (serv, X_("/select/next"), "f", sel_next);
@@ -826,6 +824,7 @@ OSC::catchall (const char *path, const char* types, lo_arg **argv, int argc, lo_
                sur->custom_strips = set->custom_strips;
                sur->temp_mode = set->temp_mode;
                sur->temp_strips = set->temp_strips;
+               sur->temp_master = set->temp_master;
        }
 
        if (strstr (path, X_("/automation"))) {
@@ -835,6 +834,10 @@ OSC::catchall (const char *path, const char* types, lo_arg **argv, int argc, lo_
        if (strstr (path, X_("/touch"))) {
                ret = touch_detect (path, types, argv, argc, msg);
 
+       } else
+       if (strstr (path, X_("/collect"))) {
+               ret = collect (path, types, argv, argc, msg);
+
        } else
        if (len >= 17 && !strcmp (&path[len-15], X_("/#current_value"))) {
                current_value_query (path, len, argv, argc, msg);
@@ -1651,6 +1654,7 @@ OSC::link_strip_types (uint32_t linkset, uint32_t striptypes)
        }
        ls = &link_sets[linkset];
        ls->strip_types = striptypes;
+       ls->temp_mode = TempOff;
        for (uint32_t dv = 1; dv < ls->urls.size(); dv++) {
                OSCSurface *su;
 
@@ -2247,6 +2251,7 @@ OSC::strip_feedback (OSCSurface* sur, bool new_bank_size)
                sur->custom_strips = set->custom_strips;
                sur->temp_mode = set->temp_mode;
                sur->temp_strips = set->temp_strips;
+               sur->temp_master = set->temp_master;
        }
        if (!sur->temp_mode) {
                sur->strips = get_sorted_stripables(sur->strip_types, sur->cue, sur->custom_mode, sur->custom_strips);
@@ -2609,21 +2614,7 @@ OSC::parse_sel_group (const char *path, const char* types, lo_arg **argv, int ar
                                value = (uint32_t) argv[0]->i;
                        }
                }
-               if (!strncmp (path, X_("/select/group/only"), 18)) {
-                       if (!rg) {
-                               return ret;
-                       }
-                       if ((argc == 1 && value) || !argc) {
-                               // fill sur->strips with routes from this group and hit bank1
-                               sur->temp_mode = GroupOnly;
-                               ret = set_temp_mode (get_address (msg));
-                               set_bank (1, msg);
-                       } else {
-                               // key off is ignored
-                               ret = 0;
-                       }
-               }
-               else if (!strncmp (path, X_("/select/group/enable"), 20)) {
+               if (!strncmp (path, X_("/select/group/enable"), 20)) {
                        if (rg) {
                                if (argc == 1) {
                                        rg->set_active (value, this);
@@ -2784,28 +2775,6 @@ OSC::parse_sel_vca (const char *path, const char* types, lo_arg **argv, int argc
                        }
 
                }
-               else if (!strncmp (path, X_("/select/vca/only"), 16)) {
-                       if (argc == 1) {
-                               if (types[0] == 'f') {
-                                       ivalue = (uint32_t) argv[0]->f;
-                               } else if (types[0] == 'i') {
-                                       ivalue = (uint32_t) argv[0]->i;
-                               }
-                       }
-                       boost::shared_ptr<VCA> vca = boost::dynamic_pointer_cast<VCA> (s);
-                       if (vca) {
-                               if ((argc == 1 && ivalue) || !argc) {
-                                       sur->temp_mode = VCAOnly;
-                                       ret = set_temp_mode (get_address (msg));
-                                       set_bank (1, msg);
-                               } else {
-                                       // key off is ignored
-                                       ret = 0;
-                               }
-                       } else {
-                               PBD::warning << "OSC: Select is not a VCA right now" << endmsg;
-                       }
-               }
        }
        return ret;
 }
@@ -2827,32 +2796,12 @@ OSC::get_vca_by_name (std::string vname)
        return boost::shared_ptr<VCA>();
 }
 
-int
-OSC::sel_bus_only (lo_message msg)
-{
-       OSCSurface *sur = get_surface(get_address (msg));
-       boost::shared_ptr<Stripable> s = sur->select;
-       if (s) {
-               boost::shared_ptr<Route> rt = boost::dynamic_pointer_cast<Route> (s);
-               if (rt) {
-                       if (!rt->is_track () && rt->can_solo ()) {
-                               // this is a bus, but not master, monitor or audition
-                               sur->temp_mode = BusOnly;
-                               set_temp_mode (get_address (msg));
-                               set_bank (1, msg);
-                               return 0;
-                       }
-               }
-       }
-       return 1;
-}
-
 int
 OSC::set_temp_mode (lo_address addr)
 {
        bool ret = 1;
        OSCSurface *sur = get_surface(addr);
-       boost::shared_ptr<Stripable> s = sur->select;
+       boost::shared_ptr<Stripable> s = sur->temp_master;
        if (s) {
                if (sur->temp_mode == GroupOnly) {
                        boost::shared_ptr<Route> rt = boost::dynamic_pointer_cast<Route> (s);
@@ -2866,17 +2815,24 @@ OSC::set_temp_mode (lo_address addr)
                                                boost::shared_ptr<Stripable> st = boost::dynamic_pointer_cast<Stripable> (r);
                                                sur->temp_strips.push_back(st);
                                        }
+                                       // check if this group feeds a bus or is slaved
+                                       boost::shared_ptr<Stripable> mstr = boost::shared_ptr<Stripable> ();
+                                       if (rg->has_control_master()) {
+                                               boost::shared_ptr<VCA> vca = session->vca_manager().vca_by_number (rg->group_master_number());
+                                               if (vca) {
+                                                       mstr = boost::dynamic_pointer_cast<Stripable> (vca);
+                                               }
+                                       } else if (rg->has_subgroup()) {
+                                               boost::shared_ptr<Route> sgr = rg->subgroup_bus().lock();
+                                               if (sgr) {
+                                                       mstr = boost::dynamic_pointer_cast<Stripable> (sgr);
+                                               }
+                                       }
+                                       if (mstr) {
+                                               sur->temp_strips.push_back(mstr);
+                                       }
                                        sur->strips = get_sorted_stripables(sur->strip_types, sur->cue, 1, sur->temp_strips);
                                        sur->nstrips = sur->temp_strips.size();
-                                       LinkSet *set;
-                                       uint32_t ls = sur->linkset;
-                                       if (ls) {
-                                               set = &(link_sets[ls]);
-                                               set->temp_mode = GroupOnly;
-                                               set->temp_strips.clear ();
-                                               set->temp_strips = sur->temp_strips;
-                                               set->strips = sur->strips;
-                                       }
                                        ret = 0;
                                }
                        }
@@ -2895,15 +2851,6 @@ OSC::set_temp_mode (lo_address addr)
                                sur->temp_strips.push_back(s);
                                sur->strips = get_sorted_stripables(sur->strip_types, sur->cue, 1, sur->temp_strips);
                                sur->nstrips = sur->temp_strips.size();
-                               LinkSet *set;
-                               uint32_t ls = sur->linkset;
-                               if (ls) {
-                                       set = &(link_sets[ls]);
-                                       set->temp_mode = VCAOnly;
-                                       set->temp_strips.clear ();
-                                       set->temp_strips = sur->temp_strips;
-                                       set->strips = sur->strips;
-                               }
                                ret = 0;
                        }
                } else if (sur->temp_mode == BusOnly) {
@@ -2925,15 +2872,6 @@ OSC::set_temp_mode (lo_address addr)
                                        sur->temp_strips.push_back(s);
                                        sur->strips = get_sorted_stripables(sur->strip_types, sur->cue, 1, sur->temp_strips);
                                        sur->nstrips = sur->temp_strips.size();
-                                       LinkSet *set;
-                                       uint32_t ls = sur->linkset;
-                                       if (ls) {
-                                               set = &(link_sets[ls]);
-                                               set->temp_mode = BusOnly;
-                                               set->temp_strips.clear ();
-                                               set->temp_strips = sur->temp_strips;
-                                               set->strips = sur->strips;
-                                       }
                                        ret = 0;
                                }
                        }
@@ -2942,6 +2880,16 @@ OSC::set_temp_mode (lo_address addr)
                        ret = 0;
                }
        }
+       LinkSet *set;
+       uint32_t ls = sur->linkset;
+       if (ls) {
+               set = &(link_sets[ls]);
+               set->temp_mode = sur->temp_mode;
+               set->temp_strips.clear ();
+               set->temp_strips = sur->temp_strips;
+               set->temp_master = sur->temp_master;
+               set->strips = sur->strips;
+       }
        if (ret) {
                sur->temp_mode = TempOff;
        }
@@ -2952,7 +2900,7 @@ boost::shared_ptr<Send>
 OSC::get_send (boost::shared_ptr<Stripable> st, lo_address addr)
 {
        OSCSurface *sur = get_surface(addr);
-       boost::shared_ptr<Stripable> s = sur->select;
+       boost::shared_ptr<Stripable> s = sur->temp_master;
        if (st && s && (st != s)) {
                boost::shared_ptr<Route> rt = boost::dynamic_pointer_cast<Route> (s);
                boost::shared_ptr<Route> rst = boost::dynamic_pointer_cast<Route> (st);
@@ -3993,6 +3941,104 @@ OSC::fake_touch (boost::shared_ptr<ARDOUR::AutomationControl> ctrl)
        return 0;
 }
 
+int
+OSC::collect (const char *path, const char* types, lo_arg **argv, int argc, lo_message msg)
+{
+       /*
+        * collect should have the form of:
+        * /select/collect (may have i or f keypress/release)
+        * /strip/collect i (may have keypress and i may be inline)
+        */
+       if (!session || argc > 1) return -1;
+
+       int ret = 1;
+       OSCSurface *sur = get_surface(get_address (msg));
+       boost::shared_ptr<Stripable> strp = boost::shared_ptr<Stripable>();
+       uint32_t value = 0;
+       OSCTempMode new_mode = TempOff;
+
+       if (argc) {
+               if (types[0] == 'f') {
+                       value = (int)argv[0]->f;
+               } else {
+                       value = argv[0]->i;
+               }
+               if (!value) {
+                       // key release ignore
+                       return 0;
+               }
+       }
+
+       //parse path first to find stripable
+       if (!strncmp (path, X_("/strip/"), 7)) {
+               /*
+                * we don't know if value is press or ssid
+                * so we have to check if the last / has an int after it first
+                * if not then we use value
+                */
+               uint32_t ssid = 0;
+               ssid = atoi (&(strrchr (path, '/' ))[1]);
+               if (!ssid) {
+                       ssid = value;
+               }
+               strp = get_strip (ssid, get_address (msg));
+       } else if (!strncmp (path, X_("/select/"), 8)) {
+               strp = sur->select;
+       } else {
+               return ret;
+       }
+       if (strp) {
+               boost::shared_ptr<Route> rt = boost::dynamic_pointer_cast<Route> (strp);
+               boost::shared_ptr<VCA> v = boost::dynamic_pointer_cast<VCA> (strp);
+               if (strstr (path, X_("/vca")) || v) {
+                       //strp must be a VCA
+                       if (v) {
+                               new_mode = VCAOnly;
+                       } else {
+                               return ret;
+                       }
+               } else
+               if (strstr (path, X_("/group"))) {
+                       //strp must be in a group
+                       if (rt) {
+                               RouteGroup *rg = rt->route_group();
+                               if (rg) {
+                                       new_mode = GroupOnly;
+                               } else {
+                                       return ret;
+                               }
+                       }
+               } else
+               if (strstr (path, X_("/bus"))) {
+                       //strp must be a bus with either sends or no inputs
+                       if (rt) {
+                               if (!rt->is_track () && rt->can_solo ()) {
+                                       new_mode = BusOnly;
+                               }
+                       }
+               } else {
+                       // decide by auto
+                       // vca should never get here
+                       if (rt->is_track ()) {
+                               if (rt->route_group()) {
+                                       new_mode = GroupOnly;
+                               }
+                       } else if (!rt->is_track () && rt->can_solo ()) {
+                                               new_mode = BusOnly;
+                       }
+               }
+               if (new_mode) {
+                       sur->temp_mode = new_mode;
+                       sur->temp_master = strp;
+                       set_temp_mode (get_address (msg));
+                       set_bank (1, msg);
+                       return 0;
+               }
+
+       }
+       return ret;
+}
+
 int
 OSC::route_mute (int ssid, int yn, lo_message msg)
 {
@@ -4001,7 +4047,7 @@ OSC::route_mute (int ssid, int yn, lo_message msg)
        OSCSurface *sur = get_surface(get_address (msg));
 
        if (s) {
-               if ((sur->temp_mode == BusOnly) && (s != sur->select)) {
+               if ((sur->temp_mode == BusOnly) && (s != sur->temp_master)) {
                        return float_message_with_id (X_("/strip/mute"), ssid, 0, sur->feedback[2], get_address (msg));
                }
                if (s->mute_control()) {
@@ -4036,7 +4082,7 @@ OSC::route_solo (int ssid, int yn, lo_message msg)
        OSCSurface *sur = get_surface(get_address (msg));
 
        if (s) {
-               if ((sur->temp_mode == BusOnly) && (s != sur->select)) {
+               if ((sur->temp_mode == BusOnly) && (s != sur->temp_master)) {
                        return float_message_with_id (X_("/strip/solo"), ssid, 0, sur->feedback[2], get_address (msg));
                }
                if (s->solo_control()) {
@@ -4055,7 +4101,7 @@ OSC::route_solo_iso (int ssid, int yn, lo_message msg)
        OSCSurface *sur = get_surface(get_address (msg));
 
        if (s) {
-               if ((sur->temp_mode == BusOnly) && (s != sur->select)) {
+               if ((sur->temp_mode == BusOnly) && (s != sur->temp_master)) {
                        return float_message_with_id (X_("/strip/solo_iso"), ssid, 0, sur->feedback[2], get_address (msg));
                }
                if (s->solo_isolate_control()) {
@@ -4075,7 +4121,7 @@ OSC::route_solo_safe (int ssid, int yn, lo_message msg)
        OSCSurface *sur = get_surface(get_address (msg));
 
        if (s) {
-               if ((sur->temp_mode == BusOnly) && (s != sur->select)) {
+               if ((sur->temp_mode == BusOnly) && (s != sur->temp_master)) {
                        return float_message_with_id (X_("/strip/solo_safe"), ssid, 0, sur->feedback[2], get_address (msg));
                }
                if (s->solo_safe_control()) {
@@ -4156,7 +4202,7 @@ OSC::route_recenable (int ssid, int yn, lo_message msg)
        OSCSurface *sur = get_surface(get_address (msg));
 
        if (s) {
-               if ((sur->temp_mode == BusOnly) && (s != sur->select)) {
+               if ((sur->temp_mode == BusOnly) && (s != sur->temp_master)) {
                        return float_message_with_id (X_("/strip/recenable"), ssid, 0, sur->feedback[2], get_address (msg));
                }
                if (s->rec_enable_control()) {
@@ -4178,7 +4224,7 @@ OSC::route_rename (int ssid, char *newname, lo_message msg) {
        boost::shared_ptr<Stripable> s = get_strip(ssid, get_address(msg));
 
        if (s) {
-               if ((sur->temp_mode == BusOnly) && (s != sur->select)) {
+               if ((sur->temp_mode == BusOnly) && (s != sur->temp_master)) {
                        text_message_with_id (X_("/strip/name"), ssid, string_compose ("%1-Send", s->name()), sur->feedback[2], get_address(msg));
                        return 1;
                }
@@ -4324,7 +4370,7 @@ OSC::route_recsafe (int ssid, int yn, lo_message msg)
        boost::shared_ptr<Stripable> s = get_strip (ssid, get_address (msg));
        OSCSurface *sur = get_surface(get_address (msg));
        if (s) {
-               if ((sur->temp_mode == BusOnly) && (s != sur->select)) {
+               if ((sur->temp_mode == BusOnly) && (s != sur->temp_master)) {
                        return float_message_with_id (X_("/strip/record_safe"), ssid, 0, sur->feedback[2], get_address (msg));
                }
                if (s->rec_safe_control()) {
@@ -4345,7 +4391,7 @@ OSC::route_monitor_input (int ssid, int yn, lo_message msg)
        OSCSurface *sur = get_surface(get_address (msg));
 
        if (s) {
-               if ((sur->temp_mode == BusOnly) && (s != sur->select)) {
+               if ((sur->temp_mode == BusOnly) && (s != sur->temp_master)) {
                        return float_message_with_id (X_("/strip/monitor_input"), ssid, 0, sur->feedback[2], get_address (msg));
                }
                boost::shared_ptr<Track> track = boost::dynamic_pointer_cast<Track> (s);
@@ -4390,7 +4436,7 @@ OSC::route_monitor_disk (int ssid, int yn, lo_message msg)
        OSCSurface *sur = get_surface(get_address (msg));
 
        if (s) {
-               if ((sur->temp_mode == BusOnly) && (s != sur->select)) {
+               if ((sur->temp_mode == BusOnly) && (s != sur->temp_master)) {
                        return float_message_with_id (X_("/strip/monitor_disk"), ssid, 0, sur->feedback[2], get_address (msg));
                }
                boost::shared_ptr<Track> track = boost::dynamic_pointer_cast<Track> (s);
@@ -4436,7 +4482,7 @@ OSC::strip_phase (int ssid, int yn, lo_message msg)
        OSCSurface *sur = get_surface(get_address (msg));
 
        if (s) {
-               if ((sur->temp_mode == BusOnly) && (s != sur->select)) {
+               if ((sur->temp_mode == BusOnly) && (s != sur->temp_master)) {
                        return float_message_with_id (X_("/strip/polarity"), ssid, 0, sur->feedback[2], get_address (msg));
                }
                if (s->phase_control()) {
@@ -4469,15 +4515,7 @@ OSC::strip_expand (int ssid, int yn, lo_message msg)
        OSCSurface *sur = get_surface(get_address (msg));
        boost::shared_ptr<Stripable> s = get_strip (ssid, get_address (msg));
        if (s) {
-               if ((sur->temp_mode == BusOnly)/* && (s != sur->select)*/) {
-                       uint32_t val = 0;
-                       if (ssid == (int) sur->expand) {
-                               val = 1;
-                       }
-                       return float_message_with_id (X_("/strip/expand"), ssid, val, sur->feedback[2], get_address (msg));
-               } else {
-                       sur->expand_strip = s;
-               }
+               sur->expand_strip = s;
        }
        sur->expand_enable = (bool) yn;
        sur->expand = ssid;
@@ -4498,7 +4536,7 @@ OSC::strip_hide (int ssid, int state, lo_message msg)
        OSCSurface *sur = get_surface(get_address (msg));
 
        if (s) {
-               if ((sur->temp_mode == BusOnly) && (s != sur->select)) {
+               if ((sur->temp_mode == BusOnly) && (s != sur->temp_master)) {
                        return float_message_with_id (X_("/strip/hide"), ssid, 0, sur->feedback[2], get_address (msg));
                }
                if (state != s->is_hidden ()) {
@@ -4584,15 +4622,6 @@ OSC::_strip_select (boost::shared_ptr<Stripable> s, lo_address addr)
                        sur->observers[i]->set_expand (obs_expand);
                }
        }
-       if (s != old_sel) {
-               if (sur->temp_mode) {
-                       set_temp_mode (addr);
-                       if (sur->temp_mode > GroupOnly) {
-                               sur->bank = 1;
-                               strip_feedback (sur, false);
-                       }
-               }
-       }
        // need to set monitor for processor changed signal (for paging)
        string address = lo_address_get_url (addr);
        boost::shared_ptr<Route> r = boost::dynamic_pointer_cast<Route>(s);
@@ -4628,9 +4657,6 @@ OSC::strip_gui_select (int ssid, int yn, lo_message msg)
        OSCSurface *sur = get_surface(get_address (msg));
        boost::shared_ptr<Stripable> s = get_strip (ssid, get_address (msg));
        if (s) {
-               if ((sur->temp_mode == BusOnly) && (s != sur->select)) {
-                       return -1;
-               }
                sur->expand_enable = false;
                SetStripableSelection (s);
        } else {
@@ -4682,15 +4708,7 @@ OSC::sel_delta (int delta, lo_message msg)
        }
        OSCSurface *sur = get_surface(get_address (msg));
        Sorted sel_strips;
-       if (sur->temp_mode < VCAOnly) {
-               sel_strips = sur->strips;
-       } else if (sur->temp_mode == VCAOnly) {
-               sel_strips = get_sorted_stripables(16, false, 0, sur->strips);
-       } else if (sur->temp_mode == BusOnly) {
-               sel_strips = get_sorted_stripables(132, false, 0, sur->strips);
-       } else {
-               return -1;
-       }
+       sel_strips = sur->strips;
        // the current selected strip _should_ be in sel_strips
        uint32_t nstps = sel_strips.size ();
        if (!nstps) {
@@ -4727,6 +4745,7 @@ OSC::sel_delta (int delta, lo_message msg)
                if (!sur->expand_enable) {
                        SetStripableSelection (new_sel);
                } else {
+                       sur->expand_strip = new_sel;
                        _strip_select (new_sel, get_address (msg));
                }
                return 0;
@@ -4903,7 +4922,7 @@ OSC::route_set_trim_abs (int ssid, float level, lo_message msg)
        OSCSurface *sur = get_surface(get_address (msg));
 
        if (s) {
-               if ((sur->temp_mode == BusOnly) && (s != sur->select)) {
+               if ((sur->temp_mode == BusOnly) && (s != sur->temp_master)) {
                        return float_message_with_id (X_("/strip/trimdB"), ssid, 0, sur->feedback[2], get_address (msg));
                }
                if (s->trim_control()) {
@@ -5022,7 +5041,7 @@ OSC::route_set_pan_stereo_width (int ssid, float pos, lo_message msg)
        OSCSurface *sur = get_surface(get_address (msg));
 
        if (s) {
-               if ((sur->temp_mode == BusOnly) && (s != sur->select)) {
+               if ((sur->temp_mode == BusOnly) && (s != sur->temp_master)) {
                        return float_message_with_id (X_("/strip/pan_stereo_width"), ssid, 1, sur->feedback[2], get_address (msg));
                }
                if (s->pan_width_control()) {