From 597c737ab57fda950768de19fffd6dd70fb2df49 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Thu, 7 Jul 2016 09:42:26 -0400 Subject: [PATCH] push2: get automatic pad connection to selected MIDI track working again --- libs/surfaces/push2/push2.cc | 86 ++++++++++++++++++++++++------------ libs/surfaces/push2/push2.h | 9 +++- 2 files changed, 66 insertions(+), 29 deletions(-) diff --git a/libs/surfaces/push2/push2.cc b/libs/surfaces/push2/push2.cc index 273c14a3b3..40a454211f 100644 --- a/libs/surfaces/push2/push2.cc +++ b/libs/surfaces/push2/push2.cc @@ -105,6 +105,8 @@ Push2::Push2 (ARDOUR::Session& s) throw failed_constructor (); } + StripableSelectionChanged.connect (selection_connection, MISSING_INVALIDATOR, boost::bind (&Push2::stripable_selection_change, this, _1), this); + ARDOUR::AudioEngine::instance()->PortRegisteredOrUnregistered.connect (port_reg_connection, MISSING_INVALIDATOR, boost::bind (&Push2::port_registration_handler, this), this); /* Catch port connections and disconnections */ @@ -1143,37 +1145,65 @@ Push2::stripable_property_change (PropertyChange const& what_changed, int which) */ mid_layout[which]->set_text (string()); - - if (stripable[which]->presentation_info().selected()) { - - boost::shared_ptr pad_port = boost::dynamic_pointer_cast(_async_in)->shadow_port(); - boost::shared_ptr current_first_selection = first_selected_stripable.lock(); - boost::shared_ptr mtrack; - - mtrack = boost::dynamic_pointer_cast (current_first_selection); - - /* disconnect from pad port, if appropriate */ - if (mtrack && pad_port) { - cerr << "Disconnect pads from " << mtrack->name() << endl; - mtrack->input()->disconnect (mtrack->input()->nth(0), pad_port->name(), this); - } - - first_selected_stripable = boost::weak_ptr (stripable[which]); - - /* now connect the pad port to this (newly) selected midi - * track, if indeed it is - */ - - mtrack = boost::dynamic_pointer_cast (stripable[which]); - - if (mtrack && pad_port) { - cerr << "Reconnect pads to " << mtrack->name() << endl; - mtrack->input()->connect (mtrack->input()->nth (0), pad_port->name(), this); - } - } } } +void +Push2::stripable_selection_change (StripableNotificationListPtr selected) +{ + + boost::shared_ptr pad_port = boost::dynamic_pointer_cast(_async_in)->shadow_port(); + boost::shared_ptr current_midi_track = current_pad_target.lock(); + boost::shared_ptr new_pad_target; + + /* See if there's a MIDI track selected */ + + for (StripableNotificationList::iterator si = selected->begin(); si != selected->end(); ++si) { + + new_pad_target = boost::dynamic_pointer_cast ((*si).lock()); + + if (new_pad_target) { + break; + } + } + + if (new_pad_target) { + cerr << "new midi pad target " << new_pad_target->name() << endl; + } else { + cerr << "no midi pad target\n"; + } + + if (current_midi_track == new_pad_target) { + /* nothing to do */ + return; + } + + if (!new_pad_target) { + /* leave existing connection alone */ + return; + } + + /* disconnect from pad port, if appropriate */ + + if (current_midi_track && pad_port) { + cerr << "Disconnect pads from " << current_midi_track->name() << endl; + current_midi_track->input()->disconnect (current_midi_track->input()->nth(0), pad_port->name(), this); + } + + /* now connect the pad port to this (newly) selected midi + * track, if indeed there is one. + */ + + if (new_pad_target && pad_port) { + cerr << "Reconnect pads to " << new_pad_target->name() << endl; + new_pad_target->input()->connect (new_pad_target->input()->nth (0), pad_port->name(), this); + current_pad_target = new_pad_target; + } else { + current_pad_target.reset (); + } +} + + void Push2::solo_change (int n) { diff --git a/libs/surfaces/push2/push2.h b/libs/surfaces/push2/push2.h index f987cd63f2..e065dc590a 100644 --- a/libs/surfaces/push2/push2.h +++ b/libs/surfaces/push2/push2.h @@ -30,9 +30,13 @@ #define ABSTRACT_UI_EXPORTS #include "pbd/abstract_ui.h" + #include "midi++/types.h" + #include "ardour/types.h" + #include "control_protocol/control_protocol.h" +#include "control_protocol/types.h" #include "midi_byte_array.h" @@ -54,6 +58,7 @@ namespace ARDOUR { class AsyncMIDIPort; class Port; class MidiBuffer; + class MidiTrack; } namespace ArdourSurface { @@ -467,7 +472,9 @@ class Push2 : public ARDOUR::ControlProtocol bool pad_filter (ARDOUR::MidiBuffer& in, ARDOUR::MidiBuffer& out) const; - boost::weak_ptr first_selected_stripable; + boost::weak_ptr current_pad_target; + PBD::ScopedConnection selection_connection; + void stripable_selection_change (ARDOUR::StripableNotificationListPtr); PBD::ScopedConnection port_reg_connection; void port_registration_handler ();