summaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2016-07-06 13:36:55 -0400
committerPaul Davis <paul@linuxaudiosystems.com>2016-07-06 13:39:10 -0400
commit2047ee527c688ed2c2bedea79a7e01088da58d72 (patch)
treea9326585d3bfeb12c87e2879b7280e5368b18013 /libs
parenteed3ea5047ae50484542cacece0df1fd9db2e4d0 (diff)
restore/extend/simplify ControlProtocol API to allow tracking of selection
Diffstat (limited to 'libs')
-rw-r--r--libs/surfaces/control_protocol/control_protocol.cc50
-rw-r--r--libs/surfaces/control_protocol/control_protocol/control_protocol.h19
-rw-r--r--libs/surfaces/generic_midi/midifunction.cc3
-rw-r--r--libs/surfaces/mackie/mackie_control_protocol.cc89
-rw-r--r--libs/surfaces/mackie/mackie_control_protocol.h4
-rw-r--r--libs/surfaces/osc/osc.cc3
6 files changed, 93 insertions, 75 deletions
diff --git a/libs/surfaces/control_protocol/control_protocol.cc b/libs/surfaces/control_protocol/control_protocol.cc
index f1b2f9f112..4d578409c3 100644
--- a/libs/surfaces/control_protocol/control_protocol.cc
+++ b/libs/surfaces/control_protocol/control_protocol.cc
@@ -49,8 +49,20 @@ PBD::Signal0<void> ControlProtocol::VerticalZoomOutSelected;
PBD::Signal0<void> ControlProtocol::StepTracksDown;
PBD::Signal0<void> ControlProtocol::StepTracksUp;
+PBD::Signal1<void,boost::shared_ptr<ARDOUR::Stripable> > ControlProtocol::AddStripableToSelection;
+PBD::Signal1<void,boost::shared_ptr<ARDOUR::Stripable> > ControlProtocol::SetStripableSelection;
+PBD::Signal1<void,boost::shared_ptr<ARDOUR::Stripable> > ControlProtocol::ToggleStripableSelection;
+PBD::Signal1<void,boost::shared_ptr<ARDOUR::Stripable> > ControlProtocol::RemoveStripableFromSelection;
+PBD::Signal0<void> ControlProtocol::ClearStripableSelection;
+
PBD::Signal1<void,StripableNotificationListPtr> ControlProtocol::StripableSelectionChanged;
+Glib::Threads::Mutex ControlProtocol::first_selected_mutex;
+boost::weak_ptr<Stripable> ControlProtocol::_first_selected_stripable;
+StripableNotificationList ControlProtocol::_last_selected;
+bool ControlProtocol::selection_connected = false;
+PBD::ScopedConnection ControlProtocol::selection_connection;
+
const std::string ControlProtocol::state_node_name ("Protocol");
ControlProtocol::ControlProtocol (Session& s, string str)
@@ -58,6 +70,12 @@ ControlProtocol::ControlProtocol (Session& s, string str)
, _name (str)
, _active (false)
{
+ if (!selection_connected) {
+ /* this is all static, connect it only once (and early), for all ControlProtocols */
+
+ StripableSelectionChanged.connect_same_thread (selection_connection, boost::bind (&ControlProtocol::stripable_selection_changed, _1));
+ selection_connected = true;
+ }
}
ControlProtocol::~ControlProtocol ()
@@ -324,3 +342,35 @@ ControlProtocol::set_state (XMLNode const & node, int /* version */)
return 0;
}
+
+boost::shared_ptr<Stripable>
+ControlProtocol::first_selected_stripable ()
+{
+ Glib::Threads::Mutex::Lock lm (first_selected_mutex);
+ return _first_selected_stripable.lock();
+}
+
+void
+ControlProtocol::set_first_selected_stripable (boost::shared_ptr<Stripable> s)
+{
+ Glib::Threads::Mutex::Lock lm (first_selected_mutex);
+ _first_selected_stripable = s;
+}
+
+void
+ControlProtocol::stripable_selection_changed (StripableNotificationListPtr sp)
+{
+ _last_selected = *sp;
+
+ {
+ Glib::Threads::Mutex::Lock lm (first_selected_mutex);
+
+ if (!_last_selected.empty()) {
+ _first_selected_stripable = _last_selected.front().lock();
+ } else {
+ _first_selected_stripable = boost::weak_ptr<Stripable>();
+ }
+ }
+
+ cerr << "CP: selection now " << _last_selected.size() << endl;
+}
diff --git a/libs/surfaces/control_protocol/control_protocol/control_protocol.h b/libs/surfaces/control_protocol/control_protocol/control_protocol.h
index 496ba99083..2485ca84ac 100644
--- a/libs/surfaces/control_protocol/control_protocol/control_protocol.h
+++ b/libs/surfaces/control_protocol/control_protocol/control_protocol.h
@@ -39,6 +39,7 @@ namespace ARDOUR {
class Route;
class Session;
class Bundle;
+class Stripable;
class LIBCONTROLCP_API ControlProtocol : public PBD::Stateful, public PBD::ScopedConnectionList, public BasicUI
{
@@ -78,6 +79,12 @@ class LIBCONTROLCP_API ControlProtocol : public PBD::Stateful, public PBD::Scope
static PBD::Signal0<void> StepTracksDown;
static PBD::Signal0<void> StepTracksUp;
+ static PBD::Signal1<void,boost::shared_ptr<ARDOUR::Stripable> > AddStripableToSelection;
+ static PBD::Signal1<void,boost::shared_ptr<ARDOUR::Stripable> > SetStripableSelection;
+ static PBD::Signal1<void,boost::shared_ptr<ARDOUR::Stripable> > ToggleStripableSelection;
+ static PBD::Signal1<void,boost::shared_ptr<ARDOUR::Stripable> > RemoveStripableFromSelection;
+ static PBD::Signal0<void> ClearStripableSelection;
+
/* signals that one UI (e.g. the GUI) can emit to get all other UI's to
respond. Typically this will always be GUI->"others" - the GUI pays
no attention to these signals.
@@ -85,6 +92,9 @@ class LIBCONTROLCP_API ControlProtocol : public PBD::Stateful, public PBD::Scope
static PBD::Signal1<void,StripableNotificationListPtr> StripableSelectionChanged;
+ static boost::shared_ptr<ARDOUR::Stripable> first_selected_stripable ();
+ static void set_first_selected_stripable (boost::shared_ptr<ARDOUR::Stripable>);
+
/* the model here is as follows:
we imagine most control surfaces being able to control
@@ -132,6 +142,7 @@ class LIBCONTROLCP_API ControlProtocol : public PBD::Stateful, public PBD::Scope
int set_state (XMLNode const &, int version);
static const std::string state_node_name;
+ static StripableNotificationList const & last_selected() { return _last_selected; }
protected:
std::vector<boost::shared_ptr<ARDOUR::Route> > route_table;
@@ -143,6 +154,14 @@ class LIBCONTROLCP_API ControlProtocol : public PBD::Stateful, public PBD::Scope
private:
LIBCONTROLCP_LOCAL ControlProtocol (const ControlProtocol&); /* noncopyable */
bool _active;
+
+
+ static Glib::Threads::Mutex first_selected_mutex;
+ static boost::weak_ptr<ARDOUR::Stripable> _first_selected_stripable;
+ static StripableNotificationList _last_selected;
+ static void stripable_selection_changed (StripableNotificationListPtr);
+ static bool selection_connected;
+ static PBD::ScopedConnection selection_connection;
};
extern "C" {
diff --git a/libs/surfaces/generic_midi/midifunction.cc b/libs/surfaces/generic_midi/midifunction.cc
index 4d2b19fdfd..3a60f53961 100644
--- a/libs/surfaces/generic_midi/midifunction.cc
+++ b/libs/surfaces/generic_midi/midifunction.cc
@@ -167,7 +167,8 @@ MIDIFunction::execute ()
if (!_argument.empty()) {
uint32_t rid;
sscanf (_argument.c_str(), "%d", &rid);
- _ui->toggle_selection (rid, ARDOUR::PresentationInfo::Flag (ARDOUR::PresentationInfo::Route|ARDOUR::PresentationInfo::VCA));
+ // XX fix me ... need to get stripable, not RID
+ //_ui->toggle_selection (rid, ARDOUR::PresentationInfo::Flag (ARDOUR::PresentationInfo::Route|ARDOUR::PresentationInfo::VCA));
DEBUG_TRACE (DEBUG::GenericMidi, string_compose ("Function: SetRouteSelection = %1\n", rid));
}
break;
diff --git a/libs/surfaces/mackie/mackie_control_protocol.cc b/libs/surfaces/mackie/mackie_control_protocol.cc
index 222b1177a8..c1786756a4 100644
--- a/libs/surfaces/mackie/mackie_control_protocol.cc
+++ b/libs/surfaces/mackie/mackie_control_protocol.cc
@@ -289,12 +289,12 @@ MackieControlProtocol::get_sorted_stripables()
switch (_view_mode) {
case Mixer:
- if (!is_hidden (s)) {
+ if (!s->presentation_info().hidden()) {
sorted.push_back (s);
}
break;
case AudioTracks:
- if (is_audio_track(s) && !is_hidden(s)) {
+ if (is_audio_track(s) && !s->presentation_info().hidden()) {
sorted.push_back (s);
}
break;
@@ -306,13 +306,13 @@ MackieControlProtocol::get_sorted_stripables()
}
#endif
} else {
- if (!is_track(s) && !is_hidden(s)) {
+ if (!is_track(s) && !s->presentation_info().hidden()) {
sorted.push_back (s);
}
}
break;
case MidiTracks:
- if (is_midi_track(s) && !is_hidden(s)) {
+ if (is_midi_track(s) && !s->presentation_info().hidden()) {
sorted.push_back (s);
}
break;
@@ -320,22 +320,22 @@ MackieControlProtocol::get_sorted_stripables()
break;
case Auxes: // in ardour, for now aux and buss are same. for mixbus, "Busses" are mixbuses, "Auxes" are ardour buses
#ifdef MIXBUS
- if (!s->mixbus() && !is_track() && !is_hidden(s))
+ if (!s->mixbus() && !is_track() && !s->presentation_info().hidden())
#else
- if (!is_track(s) && !is_hidden(s))
+ if (!is_track(s) && !s->presentation_info().hidden())
#endif
{
sorted.push_back (s);
}
break;
case Hidden: // Show all the tracks we have hidden
- if (is_hidden(s)) {
+ if (s->presentation_info().hidden()) {
// maybe separate groups
sorted.push_back (s);
}
break;
case Selected: // For example: a group (this is USER)
- if (selected(s) && !is_hidden(s)) {
+ if (s->presentation_info().selected() && !s->presentation_info().hidden()) {
sorted.push_back (s);
}
break;
@@ -2039,23 +2039,19 @@ MackieControlProtocol::select_range ()
return;
}
- if (stripables.size() == 1 && _last_selected_stripables.size() == 1 && stripables.front()->presentation_info().selected()) {
+ if (stripables.size() == 1 && ControlProtocol::last_selected().size() == 1 && stripables.front()->presentation_info().selected()) {
/* cancel selection for one and only selected stripable */
- session->toggle_stripable_selection (stripables.front());
+ ToggleStripableSelection (stripables.front());
} else {
-
for (StripableList::iterator s = stripables.begin(); s != stripables.end(); ++s) {
- if (main_modifier_state() == MODIFIER_CONTROL) {
- DEBUG_TRACE (DEBUG::MackieControl, string_compose ("toggle selection of %1 (%2)\n", (*s)->name(), (*s)->presentation_info().order()));
- session->toggle_stripable_selection (*s);
+ if (main_modifier_state() == MODIFIER_SHIFT) {
+ ToggleStripableSelection (*s);
} else {
if (s == stripables.begin()) {
- DEBUG_TRACE (DEBUG::MackieControl, string_compose ("set selection of %1 (%2)\n", (*s)->name(), (*s)->presentation_info().order()));
- session->set_stripable_selection (*s);
- } else {
- DEBUG_TRACE (DEBUG::MackieControl, string_compose ("add to selection %1 (%2)\n", (*s)->name(), (*s)->presentation_info().order()));
- session->add_stripable_selection (*s);
+ SetStripableSelection (*s);
+ } else {
+ AddStripableToSelection (*s);
}
}
}
@@ -2352,27 +2348,6 @@ MackieControlProtocol::is_midi_track (boost::shared_ptr<Stripable> r) const
}
bool
-MackieControlProtocol::selected (boost::shared_ptr<Stripable> r) const
-{
- for (Selection::const_iterator i = _last_selected_stripables.begin(); i != _last_selected_stripables.end(); ++i) {
- boost::shared_ptr<ARDOUR::Stripable> rt = (*i).lock();
- if (rt == r) {
- return true;
- }
- }
- return false;
-}
-
-bool
-MackieControlProtocol::is_hidden (boost::shared_ptr<Stripable> r) const
-{
- if (!r) {
- return false;
- }
- return (r->presentation_info().flags() & PresentationInfo::Hidden);
-}
-
-bool
MackieControlProtocol::is_mapped (boost::shared_ptr<Stripable> r) const
{
Glib::Threads::Mutex::Lock lm (surfaces_lock);
@@ -2391,14 +2366,6 @@ MackieControlProtocol::update_selected (boost::shared_ptr<Stripable> s, bool bec
{
if (became_selected) {
- if (selected (s)) {
- /* already selected .. mmmm */
- cerr << "stripable " << s->name() << " already marked as selected\n";
- return;
- }
-
- _last_selected_stripables.push_back (boost::weak_ptr<Stripable> (s));
-
check_fader_automation_state ();
/* It is possible that first_selected_route() may return null if we
@@ -2412,33 +2379,19 @@ MackieControlProtocol::update_selected (boost::shared_ptr<Stripable> s, bool bec
set_subview_mode (None, boost::shared_ptr<Stripable>());
}
- } else {
-
- for (Selection::iterator i = _last_selected_stripables.begin(); i != _last_selected_stripables.end(); ++i) {
- boost::shared_ptr<ARDOUR::Stripable> ss = (*i).lock();
-
- if (ss == s) {
- _last_selected_stripables.erase (i);
- break;
- }
- }
}
}
boost::shared_ptr<Stripable>
MackieControlProtocol::first_selected_stripable () const
{
- if (_last_selected_stripables.empty()) {
- return boost::shared_ptr<Stripable>();
- }
-
- boost::shared_ptr<Stripable> r = (*(_last_selected_stripables.begin())).lock();
+ boost::shared_ptr<Stripable> s = ControlProtocol::first_selected_stripable();
- if (r) {
+ if (s) {
/* check it is on one of our surfaces */
- if (is_mapped (r)) {
- return r;
+ if (is_mapped (s)) {
+ return s;
}
/* stripable is not mapped. thus, the currently selected stripable is
@@ -2446,10 +2399,10 @@ MackieControlProtocol::first_selected_stripable () const
* no currently selected stripable.
*/
- r.reset ();
+ s.reset ();
}
- return r; /* may be null */
+ return s; /* may be null */
}
boost::shared_ptr<Stripable>
diff --git a/libs/surfaces/mackie/mackie_control_protocol.h b/libs/surfaces/mackie/mackie_control_protocol.h
index 76da4fe5e8..56ead71b50 100644
--- a/libs/surfaces/mackie/mackie_control_protocol.h
+++ b/libs/surfaces/mackie/mackie_control_protocol.h
@@ -138,8 +138,6 @@ class MackieControlProtocol
bool is_track (boost::shared_ptr<ARDOUR::Stripable>) const;
bool is_audio_track (boost::shared_ptr<ARDOUR::Stripable>) const;
bool is_midi_track (boost::shared_ptr<ARDOUR::Stripable>) const;
- bool selected (boost::shared_ptr<ARDOUR::Stripable>) const;
- bool is_hidden (boost::shared_ptr<ARDOUR::Stripable>) const;
bool is_mapped (boost::shared_ptr<ARDOUR::Stripable>) const;
boost::shared_ptr<ARDOUR::Stripable> first_selected_stripable () const;
void update_selected (boost::shared_ptr<ARDOUR::Stripable>, bool selected);
@@ -335,8 +333,6 @@ class MackieControlProtocol
bool needs_ipmidi_restart;
bool _metering_active;
bool _initialized;
- typedef std::vector<boost::weak_ptr<ARDOUR::Stripable> > Selection;
- Selection _last_selected_stripables;
XMLNode* configuration_state;
int state_version;
int _last_bank[9];
diff --git a/libs/surfaces/osc/osc.cc b/libs/surfaces/osc/osc.cc
index f2fd8af867..b199b64f84 100644
--- a/libs/surfaces/osc/osc.cc
+++ b/libs/surfaces/osc/osc.cc
@@ -2600,9 +2600,8 @@ OSC::route_plugin_parameter_print (int ssid, int piid, int par, lo_message msg)
void
OSC::gui_selection_changed ()
{
- boost::shared_ptr<Stripable> strip;
+ boost::shared_ptr<Stripable> strip = ControlProtocol::first_selected_stripable();
- strip = boost::dynamic_pointer_cast<Stripable>(session->get_editor_mixer().lock());
if (strip) {
_select = strip;
for (uint32_t it = 0; it < _surface.size(); ++it) {