Allow strips to add or remove personal sends
authorLen Ovens <len@ovenwerks.net>
Fri, 2 Nov 2018 00:42:42 +0000 (17:42 -0700)
committerLen Ovens <len@ovenwerks.net>
Fri, 2 Nov 2018 00:43:35 +0000 (17:43 -0700)
in processor box context menu

gtk2_ardour/ardour.menus.in
gtk2_ardour/processor_box.cc
gtk2_ardour/processor_box.h
gtk2_ardour/trx.menus.in

index 87fd8c973d11b564f16b369990607767f0adfb8c..68eb7871fcfdd33822985066fb2b1fa3e3689f0c 100644 (file)
     <menuitem action='newinsert'/>
     <menuitem action='newsend'/>
     <menuitem action='newaux'/>
+    <menuitem action='newlisten'/>
+    <menuitem action='removelisten'/>
     <separator/>
     <menuitem action='controls'/>
     <menuitem action='send_options'/>
index 9e77f97c61865107d9bdb25a46b76dfe2ac1cfe7..3b23f294a3649bede5c28db7289e85f5322d8543 100644 (file)
@@ -2047,6 +2047,9 @@ ProcessorBox::build_possible_aux_menu ()
                        /* don't allow sending to master or monitor or to self */
                        continue;
                }
+               if ((*r)->is_listenbus ()) {
+                       continue;
+               }
                if (_route->internal_send_for (*r)) {
                        /* aux-send to target already exists */
                        continue;
@@ -2057,6 +2060,78 @@ ProcessorBox::build_possible_aux_menu ()
        return menu;
 }
 
+Gtk::Menu*
+ProcessorBox::build_possible_listener_menu ()
+{
+       boost::shared_ptr<RouteList> rl = _session->get_routes_with_internal_returns();
+
+       if (rl->empty()) {
+               /* No aux sends if there are no busses */
+               return 0;
+       }
+
+       if (_route->is_monitor () || _route->is_listenbus ()) {
+               return 0;
+       }
+
+       using namespace Menu_Helpers;
+       Menu* menu = manage (new Menu);
+       MenuList& items = menu->items();
+
+       for (RouteList::iterator r = rl->begin(); r != rl->end(); ++r) {
+               if ((*r)->is_master() || (*r)->is_monitor () || *r == _route) {
+                       /* don't allow sending to master or monitor or to self */
+                       continue;
+               }
+               if (!(*r)->is_listenbus ()) {
+                       continue;
+               }
+               if (_route->internal_send_for (*r)) {
+                       /* aux-send to target already exists */
+                       continue;
+               }
+               items.push_back (MenuElemNoMnemonic ((*r)->name(), sigc::bind (sigc::ptr_fun (ProcessorBox::rb_choose_aux), boost::weak_ptr<Route>(*r))));
+       }
+
+       return menu;
+}
+
+Gtk::Menu*
+ProcessorBox::build_possible_remove_listener_menu ()
+{
+       boost::shared_ptr<RouteList> rl = _session->get_routes_with_internal_returns();
+
+       if (rl->empty()) {
+               /* No aux sends if there are no busses */
+               return 0;
+       }
+
+       if (_route->is_monitor () || _route->is_listenbus ()) {
+               return 0;
+       }
+
+       using namespace Menu_Helpers;
+       Menu* menu = manage (new Menu);
+       MenuList& items = menu->items();
+
+       for (RouteList::iterator r = rl->begin(); r != rl->end(); ++r) {
+               if ((*r)->is_master() || (*r)->is_monitor () || *r == _route) {
+                       /* don't allow sending to master or monitor or to self */
+                       continue;
+               }
+               if (!(*r)->is_listenbus ()) {
+                       continue;
+               }
+               if (!_route->internal_send_for (*r)) {
+                       /* aux-send to target already exists */
+                       continue;
+               }
+               items.push_back (MenuElemNoMnemonic ((*r)->name(), sigc::bind (sigc::ptr_fun (ProcessorBox::rb_remove_aux), boost::weak_ptr<Route>(*r))));
+       }
+
+       return menu;
+}
+
 void
 ProcessorBox::show_processor_menu (int arg)
 {
@@ -2089,8 +2164,36 @@ ProcessorBox::show_processor_menu (int arg)
                }
        }
 
-       ActionManager::get_action (X_("ProcessorMenu"), "newinsert")->set_sensitive (!_route->is_monitor ());
-       ActionManager::get_action (X_("ProcessorMenu"), "newsend")->set_sensitive (!_route->is_monitor ());
+       Gtk::MenuItem* listen_menu_item = dynamic_cast<Gtk::MenuItem*>(ActionManager::get_widget("/ProcessorMenu/newlisten"));
+
+       if (listen_menu_item) {
+               Menu* m = build_possible_listener_menu();
+               if (m && !m->items().empty()) {
+                       listen_menu_item->set_submenu (*m);
+                       listen_menu_item->set_sensitive (true);
+               } else {
+                       /* stupid gtkmm: we need to pass a null reference here */
+                       gtk_menu_item_set_submenu (listen_menu_item->gobj(), 0);
+                       listen_menu_item->set_sensitive (false);
+               }
+       }
+
+       Gtk::MenuItem* remove_listen_menu_item = dynamic_cast<Gtk::MenuItem*>(ActionManager::get_widget("/ProcessorMenu/removelisten"));
+
+       if (remove_listen_menu_item) {
+               Menu* m = build_possible_remove_listener_menu();
+               if (m && !m->items().empty()) {
+                       remove_listen_menu_item->set_submenu (*m);
+                       remove_listen_menu_item->set_sensitive (true);
+               } else {
+                       /* stupid gtkmm: we need to pass a null reference here */
+                       gtk_menu_item_set_submenu (remove_listen_menu_item->gobj(), 0);
+                       remove_listen_menu_item->set_sensitive (false);
+               }
+       }
+
+       ActionManager::get_action (X_("ProcessorMenu"), "newinsert")->set_sensitive (!_route->is_monitor () && !_route->is_listenbus ());
+       ActionManager::get_action (X_("ProcessorMenu"), "newsend")->set_sensitive (!_route->is_monitor () && !_route->is_listenbus ());
 
        ProcessorEntry* single_selection = 0;
        if (processor_display.selection().size() == 1) {
@@ -2615,7 +2718,29 @@ ProcessorBox::choose_aux (boost::weak_ptr<Route> wr)
                return;
        }
 
-       _session->add_internal_send (target, _placement, _route);
+       if (target->is_listenbus ()) {
+               _route->add_personal_send (target);
+       } else {
+               _session->add_internal_send (target, _placement, _route);
+       }
+}
+
+void
+ProcessorBox::remove_aux (boost::weak_ptr<Route> wr)
+{
+       if (!_route) {
+               return;
+       }
+
+       boost::shared_ptr<Route> target = wr.lock();
+
+       if (!target) {
+               return;
+       }
+       boost::shared_ptr<Send>  send = _route->internal_send_for (target);
+       boost::shared_ptr<Processor> proc = boost::dynamic_pointer_cast<Processor> (send);
+       _route->remove_processor (proc);
+
 }
 
 void
@@ -3654,6 +3779,8 @@ ProcessorBox::register_actions ()
        ActionManager::engine_sensitive_actions.push_back (act);
 
        myactions.register_action (processor_box_actions, X_("newaux"), _("New Aux Send ..."));
+       myactions.register_action (processor_box_actions, X_("newlisten"), _("New Monitor Send ..."));
+       myactions.register_action (processor_box_actions, X_("removelisten"), _("Remove Monitor Send ..."));
 
        myactions.register_action (processor_box_actions, X_("controls"), _("Controls"));
        myactions.register_action (processor_box_actions, X_("send_options"), _("Send Options"));
@@ -3797,6 +3924,16 @@ ProcessorBox::rb_choose_aux (boost::weak_ptr<Route> wr)
        _current_processor_box->choose_aux (wr);
 }
 
+void
+ProcessorBox::rb_remove_aux (boost::weak_ptr<Route> wr)
+{
+       if (_current_processor_box == 0) {
+               return;
+       }
+
+       _current_processor_box->remove_aux (wr);
+}
+
 void
 ProcessorBox::rb_clear ()
 {
index 81c5c8e20fb3a57dee720c9a106a42fe52294063..037e601f3369ef744d18d37613bee12d61a38be0 100644 (file)
@@ -511,8 +511,11 @@ private:
        Gtk::Menu * build_processor_menu ();
        void show_processor_menu (int);
        Gtk::Menu* build_possible_aux_menu();
+       Gtk::Menu* build_possible_listener_menu();
+       Gtk::Menu* build_possible_remove_listener_menu();
 
        void choose_aux (boost::weak_ptr<ARDOUR::Route>);
+       void remove_aux (boost::weak_ptr<ARDOUR::Route>);
        void choose_send ();
        void send_io_finished (IOSelector::Result, boost::weak_ptr<ARDOUR::Processor>, IOSelectorWindow*);
        void return_io_finished (IOSelector::Result, boost::weak_ptr<ARDOUR::Processor>, IOSelectorWindow*);
@@ -581,6 +584,7 @@ private:
        static ProcessorBox* _current_processor_box;
 
        static void rb_choose_aux (boost::weak_ptr<ARDOUR::Route>);
+       static void rb_remove_aux (boost::weak_ptr<ARDOUR::Route>);
        static void rb_choose_plugin ();
        static void rb_choose_insert ();
        static void rb_choose_send ();
index d4a7e3187ac15e9e4cb7c331f8d4c959f5c796da..5dd401c310ee7f34b7e4387c6de68dc5b95a5dde 100644 (file)
@@ -24,7 +24,7 @@
         <menuitem action='goto-mark-8'/>
         <menuitem action='goto-mark-9'/>
 -->
-  
+
   <menubar name='Main' action='MainMenu'>
     <menu name='Session' action='Session'>
       <menuitem action='New'/>
@@ -44,7 +44,7 @@
         <menuitem action='CleanupUnused'/>
         <menuitem action='FlushWastebasket'/>
       </menu>
-#ifdef GTKOSX      
+#ifdef GTKOSX
       <menuitem action='toggle-about'/>
       <menuitem action='toggle-rc-options-editor'/>
 #endif
       <menuitem action='editor-cut'/>
       <menuitem action='editor-copy'/>
       <menuitem action='editor-paste'/>
-      <separator/>       
-      <menu action="SelectMenu">          
+      <separator/>
+      <menu action="SelectMenu">
         <menuitem action='select-all'/>
         <menuitem action='deselect-all'/>
         <menuitem action='invert-selection'/>
-      </menu>     
+      </menu>
       <separator/>
       <menuitem action='editor-delete'/>
       <menuitem action='editor-crop'/>
       <separator/>
       <menuitem action='toggle-rc-options-editor'/>
 #endif
-    </menu>         
+    </menu>
 
     <menu action='TrackMenu'>
-      <menuitem action='AddTrackBus'/> 
+      <menuitem action='AddTrackBus'/>
       <menuitem action="move-selected-tracks-up"/>
       <menuitem action="move-selected-tracks-down"/>
     </menu>
     <menuitem action='newinsert'/>
     <menuitem action='newsend'/>
     <menuitem action='newaux'/>
+    <menuitem action='newlisten'/>
+    <menuitem action='removelisten'/>
     <separator/>
     <menuitem action='controls'/>
     <menuitem action='send_options'/>
     <separator/>
     <menuitem action='addExternalAudioToRegionList'/>
     <separator/>
-    <menuitem action='removeUnusedRegions'/>    
+    <menuitem action='removeUnusedRegions'/>
   </popup>
 
   <popup name='PopupRegionMenu' action='PopupRegionMenu'>
       <menuitem action='toggle-opaque-region'/>
       <menuitem action='toggle-region-mute'/>
       <menuitem action='pitch-shift-region'/>
-      <menuitem action='reverse-region'/>    
+      <menuitem action='reverse-region'/>
       <menuitem action='close-region-gaps'/>
       <menuitem action='place-transient' />
       <menuitem action='show-rhythm-ferret'/>
     <menu action='RegionMenuGain'>
       <menuitem action='normalize-region'/>
       <menuitem action='boost-region-gain'/>
-      <menuitem action='cut-region-gain'/>                        
+      <menuitem action='cut-region-gain'/>
       <menuitem action='reset-region-gain-envelopes'/>
       <menuitem action='toggle-region-gain-envelope-active'/>
     </menu>
     <menuitem action='analyze-region'/>
     <separator/>
     <menuitem action='remove-region'/>
-    
+
   </popup>
 
 </ui>