summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2011-07-03 15:01:21 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2011-07-03 15:01:21 +0000
commita3583c89b20160de154d05ff4c3e2f2bd0ff44df (patch)
tree7e0e4661f3a6cbd17292687f1bee3d9c5317f7e1
parent8f3f86b8a815da24179b893cfc6825e034c1b81b (diff)
ctrl-alt-click now toggles input active status of other MIDI tracks using (any of) the same input(s) as the clicked track
git-svn-id: svn://localhost/ardour2/branches/3.0@9789 d708f5d6-7413-0410-9779-e7cbd77b26cf
-rw-r--r--gtk2_ardour/mixer_strip.cc35
-rw-r--r--gtk2_ardour/mixer_strip.h3
-rw-r--r--libs/ardour/ardour/io.h1
-rw-r--r--libs/ardour/ardour/session.h2
-rw-r--r--libs/ardour/io.cc12
-rw-r--r--libs/ardour/session.cc56
6 files changed, 103 insertions, 6 deletions
diff --git a/gtk2_ardour/mixer_strip.cc b/gtk2_ardour/mixer_strip.cc
index 2b260bcb5a..78d69ba6bf 100644
--- a/gtk2_ardour/mixer_strip.cc
+++ b/gtk2_ardour/mixer_strip.cc
@@ -407,7 +407,8 @@ MixerStrip::set_route (boost::shared_ptr<Route> rt)
midi_input_enable_button = manage (new StatefulToggleButton);
midi_input_enable_button->set_name ("MixerMidiInputEnableButton");
midi_input_enable_button->set_image (*img);
- midi_input_enable_button->signal_toggled().connect (sigc::mem_fun (*this, &MixerStrip::midi_input_toggled));
+ midi_input_enable_button->signal_button_press_event().connect (sigc::mem_fun (*this, &MixerStrip::input_active_button_press), false);
+ midi_input_enable_button->signal_button_release_event().connect (sigc::mem_fun (*this, &MixerStrip::input_active_button_release), false);
ARDOUR_UI::instance()->set_tip (midi_input_enable_button, _("Enable/Disable MIDI input"));
} else {
input_button_box.remove (*midi_input_enable_button);
@@ -1915,16 +1916,40 @@ MixerStrip::hide_things ()
processor_box.hide_things ();
}
-void
-MixerStrip::midi_input_toggled ()
+bool
+MixerStrip::input_active_button_press (GdkEventButton* ev)
+{
+ /* nothing happens on press */
+ return true;
+}
+
+bool
+MixerStrip::input_active_button_release (GdkEventButton* ev)
{
boost::shared_ptr<MidiTrack> mt = midi_track ();
if (!mt) {
- return;
+ return true;
}
- mt->set_input_active (midi_input_enable_button->get_active());
+ if (mt->input_active()) {
+ if (Keyboard::modifier_state_contains (ev->state, Keyboard::ModifierMask (Keyboard::PrimaryModifier|Keyboard::SecondaryModifier))) {
+ /* turn all other tracks using this input off */
+ _session->set_exclusive_input_active (mt, false);
+ } else {
+ mt->set_input_active (false);
+ }
+
+ } else {
+ if (Keyboard::modifier_state_contains (ev->state, Keyboard::ModifierMask (Keyboard::PrimaryModifier|Keyboard::SecondaryModifier))) {
+ /* turn all other tracks using this input on */
+ _session->set_exclusive_input_active (mt, true);
+ } else {
+ mt->set_input_active (true);
+ }
+ }
+
+ return true;
}
void
diff --git a/gtk2_ardour/mixer_strip.h b/gtk2_ardour/mixer_strip.h
index de907a3607..863aab2ee6 100644
--- a/gtk2_ardour/mixer_strip.h
+++ b/gtk2_ardour/mixer_strip.h
@@ -188,7 +188,8 @@ class MixerStrip : public RouteUI, public Gtk::EventBox
std::string longest_label;
void midi_input_status_changed ();
- void midi_input_toggled ();
+ bool input_active_button_press (GdkEventButton*);
+ bool input_active_button_release (GdkEventButton*);
gint mark_update_safe ();
guint32 mode_switch_in_progress;
diff --git a/libs/ardour/ardour/io.h b/libs/ardour/ardour/io.h
index 865971b377..062abac4f4 100644
--- a/libs/ardour/ardour/io.h
+++ b/libs/ardour/ardour/io.h
@@ -107,6 +107,7 @@ class IO : public SessionObject, public Latent
int disconnect (Port *our_port, std::string other_port, void *src);
int disconnect (void *src);
bool connected_to (boost::shared_ptr<const IO>) const;
+ bool connected_to (const std::string&) const;
bool connected () const;
bool physically_connected () const;
diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h
index 004ff41f83..6b9010642c 100644
--- a/libs/ardour/ardour/session.h
+++ b/libs/ardour/ardour/session.h
@@ -238,6 +238,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
boost::shared_ptr<Route> route_by_name (std::string);
boost::shared_ptr<Route> route_by_id (PBD::ID);
boost::shared_ptr<Route> route_by_remote_id (uint32_t id);
+ void routes_using_input_from (const std::string& str, RouteList& rl);
bool route_name_unique (std::string) const;
bool route_name_internal (std::string) const;
@@ -608,6 +609,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
void set_listen (boost::shared_ptr<RouteList>, bool, SessionEvent::RTeventCallback after = rt_cleanup, bool group_override = false);
void set_record_enabled (boost::shared_ptr<RouteList>, bool, SessionEvent::RTeventCallback after = rt_cleanup, bool group_override = false);
void set_solo_isolated (boost::shared_ptr<RouteList>, bool, SessionEvent::RTeventCallback after = rt_cleanup, bool group_override = false);
+ void set_exclusive_input_active (boost::shared_ptr<Route> rt, bool others_on);
PBD::Signal1<void,bool> SoloActive;
PBD::Signal0<void> SoloChanged;
diff --git a/libs/ardour/io.cc b/libs/ardour/io.cc
index 5c2cdcf53e..13d22e6592 100644
--- a/libs/ardour/io.cc
+++ b/libs/ardour/io.cc
@@ -1519,6 +1519,18 @@ IO::connected_to (boost::shared_ptr<const IO> other) const
return false;
}
+bool
+IO::connected_to (const string& str) const
+{
+ for (PortSet::const_iterator i = _ports.begin(); i != _ports.end(); ++i) {
+ if (i->connected_to (str)) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
void
IO::process_input (boost::shared_ptr<Processor> proc, framepos_t start_frame, framepos_t end_frame, pframes_t nframes)
{
diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc
index ecdd9bca8d..d4af9b6766 100644
--- a/libs/ardour/session.cc
+++ b/libs/ardour/session.cc
@@ -2466,6 +2466,62 @@ Session::io_name_is_legal (const std::string& name)
return true;
}
+void
+Session::set_exclusive_input_active (boost::shared_ptr<Route> rt, bool others_on)
+{
+ RouteList rl;
+ vector<string> connections;
+
+ PortSet& ps (rt->input()->ports());
+
+ for (PortSet::iterator p = ps.begin(); p != ps.end(); ++p) {
+ p->get_connections (connections);
+ }
+
+ for (vector<string>::iterator s = connections.begin(); s != connections.end(); ++s) {
+ routes_using_input_from (*s, rl);
+ }
+
+ /* scan all relevant routes to see if others are on or off */
+
+ bool others_are_already_on = false;
+
+ for (RouteList::iterator r = rl.begin(); r != rl.end(); ++r) {
+ if ((*r) != rt) {
+ boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (*r);
+ if (mt) {
+ if (mt->input_active()) {
+ others_are_already_on = true;
+ break;
+ }
+ }
+ }
+ }
+
+ /* globally reverse other routes */
+
+ for (RouteList::iterator r = rl.begin(); r != rl.end(); ++r) {
+ if ((*r) != rt) {
+ boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (*r);
+ if (mt) {
+ mt->set_input_active (!others_are_already_on);
+ }
+ }
+ }
+}
+
+void
+Session::routes_using_input_from (const string& str, RouteList& rl)
+{
+ boost::shared_ptr<RouteList> r = routes.reader ();
+
+ for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
+ if ((*i)->input()->connected_to (str)) {
+ rl.push_back (*i);
+ }
+ }
+}
+
boost::shared_ptr<Route>
Session::route_by_name (string name)
{