OSC: add group sharing bit feedback
[ardour.git] / libs / surfaces / osc / osc.cc
index 14cdf04bd8416392a64129e0c1f714a699bb01d0..1a9d7371598918f088d59587b27115e426297210 100644 (file)
@@ -504,6 +504,7 @@ OSC::register_callbacks()
                REGISTER_CALLBACK (serv, X_("/quick_snapshot_switch"), "f", quick_snapshot_switch);
                REGISTER_CALLBACK (serv, X_("/quick_snapshot_stay"), "", quick_snapshot_stay);
                REGISTER_CALLBACK (serv, X_("/quick_snapshot_stay"), "f", quick_snapshot_stay);
+               REGISTER_CALLBACK (serv, X_("/session_name"), "s", name_session);
                REGISTER_CALLBACK (serv, X_("/fit_1_track"), "", fit_1_track);
                REGISTER_CALLBACK (serv, X_("/fit_1_track"), "f", fit_1_track);
                REGISTER_CALLBACK (serv, X_("/fit_2_tracks"), "", fit_2_tracks);
@@ -570,7 +571,6 @@ OSC::register_callbacks()
                REGISTER_CALLBACK (serv, X_("/select/record_safe"), "i", sel_recsafe);
                REGISTER_CALLBACK (serv, X_("/select/name"), "s", sel_rename);
                REGISTER_CALLBACK (serv, X_("/select/comment"), "s", sel_comment);
-               REGISTER_CALLBACK (serv, X_("/select/group"), "s", sel_group);
                REGISTER_CALLBACK (serv, X_("/select/mute"), "i", sel_mute);
                REGISTER_CALLBACK (serv, X_("/select/solo"), "i", sel_solo);
                REGISTER_CALLBACK (serv, X_("/select/solo_iso"), "i", sel_solo_iso);
@@ -814,6 +814,7 @@ OSC::catchall (const char *path, const char* types, lo_arg **argv, int argc, lo_
                set = &(link_sets[ls]);
                sur->custom_mode = set->custom_mode;
                sur->custom_strips = set->custom_strips;
+               sur->temp_strips = set->temp_strips;
        }
 
        if (strstr (path, X_("/automation"))) {
@@ -978,8 +979,11 @@ OSC::catchall (const char *path, const char* types, lo_arg **argv, int argc, lo_
        else if (!strncmp (path, X_("/strip/select/"), 14) && strlen (path) > 14) {
                int ssid = atoi (&path[14]);
                ret = strip_gui_select (ssid, argv[0]->i, msg);
-       } else
-       if (strstr (path, X_("/select")) && (argc != 1)) {
+       }
+       else if (strstr (path, X_("/select/group"))) {
+               ret = parse_sel_group (path, types, argv, argc, msg);
+       }
+       else if (strstr (path, X_("/select")) && (argc != 1)) {
                // All of the select commands below require 1 parameter
                PBD::warning << "OSC: Wrong number of parameters." << endmsg;
        }
@@ -2208,11 +2212,13 @@ OSC::strip_feedback (OSCSurface* sur, bool new_bank_size)
                }
                sur->custom_mode = set->custom_mode;
                sur->custom_strips = set->custom_strips;
+               sur->temp_strips = set->temp_strips;
        }
-       if (sur->custom_strips.size () == 0) {
-               sur->custom_mode = 0;
+       if (sur->custom_mode < 7) {
+               sur->strips = get_sorted_stripables(sur->strip_types, sur->cue, sur->custom_mode, sur->custom_strips);
+       } else {
+               sur->strips = get_sorted_stripables(sur->strip_types, sur->cue, 1, sur->temp_strips);
        }
-       sur->strips = get_sorted_stripables(sur->strip_types, sur->cue, sur->custom_mode, sur->custom_strips);
        sur->nstrips = sur->strips.size();
        if (ls) {
                set->strips = sur->strips;
@@ -2348,17 +2354,25 @@ OSC::_set_bank (uint32_t bank_start, lo_address addr)
                set->bank = bank_start;
                uint32_t not_ready = 0;
                for (uint32_t dv = 1; dv < d_count; dv++) {
-                       OSCSurface *sur;
                        if (set->urls[dv] != "") {
                                string url = set->urls[dv];
-                               sur = get_surface (lo_address_new_from_url (url.c_str()));
+                               OSCSurface *sur = get_surface (lo_address_new_from_url (url.c_str()));
+                               if (sur->linkset != ls) {
+                                       set->urls[dv] = "";
+                                       not_ready = dv;
+                               } else {
+                                       lo_address sur_addr = lo_address_new_from_url (sur->remote_url.c_str());
+
+                                       sur->bank = bank_start;
+                                       bank_start = bank_start + sur->bank_size;
+                                       strip_feedback (sur, false);
+                                       _strip_select (boost::shared_ptr<ARDOUR::Stripable>(), sur_addr);
+                                       bank_leds (sur);
+                                       lo_address_free (sur_addr);
+                               }
                        } else {
                                not_ready = dv;
                        }
-                       if (sur->linkset != ls) {
-                               set->urls[dv] = "";
-                               not_ready = dv;
-                       }
                        if (not_ready) {
                                if (!set->not_ready) {
                                        set->not_ready = not_ready;
@@ -2366,14 +2380,6 @@ OSC::_set_bank (uint32_t bank_start, lo_address addr)
                                set->bank = 1;
                                break;
                        }
-                       lo_address sur_addr = lo_address_new_from_url (sur->remote_url.c_str());
-
-                       sur->bank = bank_start;
-                       bank_start = bank_start + sur->bank_size;
-                       strip_feedback (sur, false);
-                       _strip_select (boost::shared_ptr<ARDOUR::Stripable>(), sur_addr);
-                       bank_leds (sur);
-                       lo_address_free (sur_addr);
                }
                if (not_ready) {
                        surface_link_state (set);
@@ -2523,6 +2529,134 @@ OSC::use_group (float value, lo_message msg)
        return 0;
 }
 
+// this gets called for anything that starts with /select/group
+int
+OSC::parse_sel_group (const char *path, const char* types, lo_arg **argv, int argc, lo_message msg)
+{
+       OSCSurface *sur = get_surface(get_address (msg));
+       boost::shared_ptr<Stripable> s;
+       if (sur->expand_enable) {
+               s = get_strip (sur->expand, get_address (msg));
+       } else {
+               s = _select;
+       }
+       int ret = 1; /* unhandled */
+       if (s) {
+               if (!strncmp (path, X_("/select/group"), 13)) {
+                       if (argc == 1) {
+                               if (types[0] == 's') {
+                                       return strip_select_group (s, &argv[0]->s);
+                               }
+                       }
+               }
+               boost::shared_ptr<Route> rt = boost::dynamic_pointer_cast<Route> (s);
+               if (!rt) {
+                       PBD::warning << "OSC: VCAs can not be part of a group." << endmsg;
+                       return ret;
+               }
+               RouteGroup *rg = rt->route_group();
+               if (!rg) {
+                       PBD::warning << "OSC: This strip is not part of a group." << endmsg;
+                       return ret;
+               }
+               float value = 0;
+               if (argc == 1) {
+                       if (types[0] == 'f') {
+                               value = (uint32_t) argv[0]->f;
+                       } else if (types[0] == 'i') {
+                               value = (uint32_t) argv[0]->i;
+                       }
+               }
+               if (!strncmp (path, X_("/select/group/enable"), 20)) {
+                       if (argc == 1) {
+                               rg->set_active (value, this);
+                               ret = 0;
+                       }
+               }
+               else if (!strncmp (path, X_("/select/group/only"), 18)) {
+                       if ((argc == 1 && value) || !argc) {
+                               // fill sur->strips with routes from this group and hit bank1
+                               sur->temp_strips.clear();
+                               boost::shared_ptr<RouteList> rl = rg->route_list();
+                               for (RouteList::iterator it = rl->begin(); it != rl->end(); ++it) {
+                                       boost::shared_ptr<Route> r = *it;
+                                       boost::shared_ptr<Stripable> s = boost::dynamic_pointer_cast<Stripable> (r);
+                                       sur->temp_strips.push_back(s);
+                               }
+                               sur->custom_mode = 7;
+                               set_bank (1, msg);
+                               ret = 0;
+                       } else {
+                               // key off is ignored
+                               ret = 0;
+                       }
+               }
+               else if (!strncmp (path, X_("/select/group/sharing"), 21)) {
+                       if (argc == 9) {
+                               if (rg->is_gain() != (bool) argv[0]->i) {
+                                       rg->set_gain ((bool) argv[0]->i);
+                               }
+                               if (rg->is_relative() != (bool) argv[1]->i) {
+                                       rg->set_relative ((bool) argv[1]->i, this);
+                               }
+                               if (rg->is_mute() != (bool) argv[2]->i) {
+                                       rg->set_mute ((bool) argv[2]->i);
+                               }
+                               if (rg->is_solo() != (bool) argv[3]->i) {
+                                       rg->set_solo ((bool) argv[3]->i);
+                               }
+                               if (rg->is_recenable() != (bool) argv[4]->i) {
+                                       rg->set_recenable ((bool) argv[4]->i);
+                               }
+                               if (rg->is_select() != (bool) argv[5]->i) {
+                                       rg->set_select ((bool) argv[5]->i);
+                               }
+                               if (rg->is_route_active() != (bool) argv[6]->i) {
+                                       rg->set_route_active ((bool) argv[6]->i);
+                               }
+                               if (rg->is_color() != (bool) argv[7]->i) {
+                                       rg->set_color ((bool) argv[7]->i);
+                               }
+                               if (rg->is_monitoring() != (bool) argv[8]->i) {
+                                       rg->set_monitoring ((bool) argv[8]->i);
+                               }
+                               ret = 0;
+                       } else {
+                               PBD::warning << "OSC: Sharing can only be set if all 9 parameters are sent." << endmsg;
+                       }
+               }
+       }
+       return ret;
+ }
+
+int
+OSC::name_session (char *n, lo_message msg)
+{
+       if (!session) {
+               return -1;
+       }
+       string new_name = n;
+       char illegal = Session::session_name_is_legal (new_name);
+
+       if (illegal) {
+               PBD::warning  << (string_compose (_("To ensure compatibility with various systems\n"
+                                   "session names may not contain a '%1' character"), illegal)) << endmsg;
+               return -1;
+       }
+       switch (session->rename (new_name)) {
+               case -1:
+                       PBD::warning  << (_("That name is already in use by another directory/folder. Please try again.")) << endmsg;
+                       break;
+               case 0:
+                       return 0;
+                       break;
+               default:
+                       PBD::warning  << (_("Renaming this session failed.\nThings could be seriously messed up at this point")) << endmsg;
+                       break;
+       }
+       return -1;
+}
+
 uint32_t
 OSC::get_sid (boost::shared_ptr<ARDOUR::Stripable> strip, lo_address addr)
 {
@@ -4073,7 +4207,7 @@ OSC::_strip_select (boost::shared_ptr<Stripable> s, lo_address addr)
                if (so != 0) {
                        so->refresh_strip (s, nsends, sur->gainmode, true);
                } else {
-                       OSCSelectObserver* sel_fb = new OSCSelectObserver (*this, sur);
+                       OSCSelectObserver* sel_fb = new OSCSelectObserver (*this, *session, sur);
                        sur->sel_obs = sel_fb;
                }
                sur->sel_obs->set_expand (sur->expand_enable);