X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;ds=sidebyside;f=libs%2Fsurfaces%2Fmackie%2Fmackie_control_protocol.cc;h=2ea61cc9f0baf0b64ab0a71964f834e10b55c2a8;hb=cf52d6e4b40111eb04b244ec054055a4ec15dbe0;hp=fbd6f286bcec9433cc332f4d13c571ff3f1f9db1;hpb=4b7bbacaaa97e3cf4a07fe4b98fe03491b5c0b53;p=ardour.git diff --git a/libs/surfaces/mackie/mackie_control_protocol.cc b/libs/surfaces/mackie/mackie_control_protocol.cc index fbd6f286bc..2ea61cc9f0 100644 --- a/libs/surfaces/mackie/mackie_control_protocol.cc +++ b/libs/surfaces/mackie/mackie_control_protocol.cc @@ -52,6 +52,7 @@ #include "ardour/panner.h" #include "ardour/panner_shell.h" #include "ardour/profile.h" +#include "ardour/record_enable_control.h" #include "ardour/route.h" #include "ardour/route_group.h" #include "ardour/session.h" @@ -82,7 +83,7 @@ using namespace Glib; using namespace ArdourSurface; using namespace Mackie; -#include "i18n.h" +#include "pbd/i18n.h" #include "pbd/abstract_ui.cc" // instantiate template @@ -137,7 +138,7 @@ MackieControlProtocol::MackieControlProtocol (Session& session) _last_bank[i] = 0; } - StripableSelectionChanged.connect (gui_connections, MISSING_INVALIDATOR, boost::bind (&MackieControlProtocol::gui_track_selection_changed, this, _1, true), this); + PresentationInfo::Change.connect (gui_connections, MISSING_INVALIDATOR, boost::bind (&MackieControlProtocol::notify_presentation_info_changed, this), this); _instance = this; @@ -245,17 +246,17 @@ struct StripableByPresentationOrder { bool operator () (const boost::shared_ptr & a, const boost::shared_ptr & b) const { - return a->presentation_info() < b->presentation_info(); + return a->presentation_info().order() < b->presentation_info().order(); } bool operator () (const Stripable & a, const Stripable & b) const { - return a.presentation_info() < b.presentation_info(); + return a.presentation_info().order() < b.presentation_info().order(); } bool operator () (const Stripable * a, const Stripable * b) const { - return a->presentation_info() < b->presentation_info(); + return a->presentation_info().order() < b->presentation_info().order(); } }; @@ -288,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; @@ -305,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; @@ -319,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; @@ -428,17 +429,13 @@ MackieControlProtocol::switch_banks (uint32_t initial, bool force) DEBUG_TRACE (DEBUG::MackieControl, string_compose ("clear all strips, bank target %1 is outside route range %2\n", _current_initial_bank, sorted.size())); for (Surfaces::iterator si = surfaces.begin(); si != surfaces.end(); ++si) { - vector > routes; - /* pass in an empty route list, so that all strips will be reset */ - (*si)->map_routes (routes); + vector > stripables; + /* pass in an empty stripables list, so that all strips will be reset */ + (*si)->map_stripables (stripables); } return -1; } - /* make sure selection is correct */ - - _gui_track_selection_changed (&_last_selected_stripables, false, false); - /* current bank has not been saved */ session->set_dirty(); @@ -716,10 +713,6 @@ MackieControlProtocol::connect_session_signals() // make sure remote id changed signals reach here // see also notify_stripable_added Sorted sorted = get_sorted_stripables(); - - for (Sorted::iterator it = sorted.begin(); it != sorted.end(); ++it) { - (*it)->PresentationInfoChanged.connect (stripable_connections, MISSING_INVALIDATOR, boost::bind (&MackieControlProtocol::notify_presentation_info_changed, this), this); - } } void @@ -1277,13 +1270,6 @@ MackieControlProtocol::notify_routes_added (ARDOUR::RouteList & rl) refresh_current_bank(); // otherwise route added, but current bank needs no updating - - // make sure presentation info changes in the new stripables are handled - typedef ARDOUR::RouteList ARS; - - for (ARS::iterator it = rl.begin(); it != rl.end(); ++it) { - (*it)->PresentationInfoChanged.connect (stripable_connections, MISSING_INVALIDATOR, boost::bind (&MackieControlProtocol::notify_presentation_info_changed, this), this); - } } void @@ -1311,7 +1297,7 @@ MackieControlProtocol::notify_solo_active_changed (bool active) } void -MackieControlProtocol::notify_presentation_info_changed() +MackieControlProtocol::notify_presentation_info_changed () { { Glib::Threads::Mutex::Lock lm (surfaces_lock); @@ -1644,7 +1630,7 @@ MackieControlProtocol::midi_input_handler (IOCondition ioc, MIDI::Port* port) if (ioc & IO_IN) { - DEBUG_TRACE (DEBUG::MackieControl, string_compose ("something happend on %1\n", port->name())); + // DEBUG_TRACE (DEBUG::MackieControl, string_compose ("something happend on %1\n", port->name())); /* Devices using regular JACK MIDI ports will need to have the x-thread FIFO drained to avoid burning endless CPU. @@ -1661,7 +1647,7 @@ MackieControlProtocol::midi_input_handler (IOCondition ioc, MIDI::Port* port) } } - DEBUG_TRACE (DEBUG::MackieControl, string_compose ("data available on %1\n", port->name())); + // DEBUG_TRACE (DEBUG::MackieControl, string_compose ("data available on %1\n", port->name())); framepos_t now = session->engine().sample_time(); port->parse (now); } @@ -1742,12 +1728,16 @@ MackieControlProtocol::redisplay_subview_mode () int MackieControlProtocol::set_subview_mode (SubViewMode sm, boost::shared_ptr r) { + DEBUG_TRACE (DEBUG::MackieControl, string_compose ("set subview mode %1 with stripable %2, current flip mode %3\n", sm, (r ? r->name() : string ("null")), _flip_mode)); + if (_flip_mode != Normal) { set_flip_mode (Normal); } if (!subview_mode_would_be_ok (sm, r)) { + DEBUG_TRACE (DEBUG::MackieControl, "subview mode not OK\n"); + if (r) { Glib::Threads::Mutex::Lock lm (surfaces_lock); @@ -1793,8 +1783,8 @@ MackieControlProtocol::set_subview_mode (SubViewMode sm, boost::shared_ptr unless we want to - handle the complexities of route deletion. So instead, the GUI sends - us a notification using weak_ptr, which we keep a copy - of. For efficiency's sake, however, we convert the weak_ptr's into - shared_ptr before passing them to however many surfaces (and - thus strips) that we have. - */ - - StrongStripableNotificationList srl; - - for (ARDOUR::StripableNotificationList::const_iterator i = rl->begin(); i != rl->end(); ++i) { - boost::shared_ptr r = (*i).lock(); - if (r) { - srl.push_back (r); - } - } - - { - Glib::Threads::Mutex::Lock lm (surfaces_lock); - - for (Surfaces::iterator s = surfaces.begin(); s != surfaces.end(); ++s) { - (*s)->gui_selection_changed (srl); - } - } - - if (save_list) { - _last_selected_stripables = *rl; - } - - if (gui_selection_did_change) { - - check_fader_automation_state (); - - /* note: this method is also called when we switch banks. - * But ... we don't allow bank switching when in subview mode. - * - * so .. we only have to care about subview mode if the - * GUI selection has changed. - * - * It is possible that first_selected_stripable() may return null if we - * are no longer displaying/mapping that route. In that case, - * we will exit subview mode. If first_selected_stripable() is - * null, and subview mode is not None, then the first call to - * set_subview_mode() will fail, and we will reset to None. - */ - - if (set_subview_mode (_subview_mode, first_selected_stripable())) { - set_subview_mode (None, boost::shared_ptr()); - } - } -} - void MackieControlProtocol::check_fader_automation_state () { @@ -2099,30 +2027,32 @@ MackieControlProtocol::remove_down_select_button (int surface, int strip) } void -MackieControlProtocol::select_range () +MackieControlProtocol::select_range (uint32_t pressed) { StripableList stripables; - pull_stripable_range (_down_select_buttons, stripables); + pull_stripable_range (_down_select_buttons, stripables, pressed); - DEBUG_TRACE (DEBUG::MackieControl, string_compose ("select range: found %1 stripables\n", stripables.size())); + DEBUG_TRACE (DEBUG::MackieControl, string_compose ("select range: found %1 stripables, first = %2\n", stripables.size(), stripables.front()->name())); if (stripables.empty()) { return; } - for (StripableList::iterator s = stripables.begin(); s != stripables.end(); ++s) { + if (stripables.size() == 1 && ControlProtocol::last_selected().size() == 1 && stripables.front()->presentation_info().selected()) { + /* cancel selection for one and only selected stripable */ + ToggleStripableSelection (stripables.front()); + } else { + for (StripableList::iterator s = stripables.begin(); s != stripables.end(); ++s) { - if (main_modifier_state() == MODIFIER_SHIFT) { - /* XXX can only use numeric part of ID at present */ - ToggleStripableSelection ((*s)->presentation_info ().global_order()); - } else { - if (s == stripables.begin()) { - /* XXX can only use numeric part of ID at present */ - SetStripableSelection ((*s)->presentation_info().global_order()); + if (main_modifier_state() == MODIFIER_SHIFT) { + ToggleStripableSelection (*s); } else { - /* XXX can only use numeric part of ID at present */ - AddStripableToSelection ((*s)->presentation_info().global_order()); + if (s == stripables.begin()) { + SetStripableSelection (*s); + } else { + AddStripableToSelection (*s); + } } } } @@ -2163,7 +2093,7 @@ MackieControlProtocol::remove_down_button (AutomationType a, int surface, int st } MackieControlProtocol::ControlList -MackieControlProtocol::down_controls (AutomationType p) +MackieControlProtocol::down_controls (AutomationType p, uint32_t pressed) { ControlList controls; StripableList stripables; @@ -2177,7 +2107,7 @@ MackieControlProtocol::down_controls (AutomationType p) DEBUG_TRACE (DEBUG::MackieControl, string_compose ("looking for down buttons for %1, got %2\n", p, m->second.size())); - pull_stripable_range (m->second, stripables); + pull_stripable_range (m->second, stripables, pressed); switch (p) { case GainAutomation: @@ -2197,7 +2127,7 @@ MackieControlProtocol::down_controls (AutomationType p) break; case RecEnableAutomation: for (StripableList::iterator s = stripables.begin(); s != stripables.end(); ++s) { - boost::shared_ptr ac = (*s)->recenable_control(); + boost::shared_ptr ac = (*s)->rec_enable_control(); if (ac) { controls.push_back (ac); } @@ -2220,7 +2150,7 @@ struct ButtonRangeSorter { }; void -MackieControlProtocol::pull_stripable_range (DownButtonList& down, StripableList& selected) +MackieControlProtocol::pull_stripable_range (DownButtonList& down, StripableList& selected, uint32_t pressed) { ButtonRangeSorter cmp; @@ -2270,13 +2200,19 @@ MackieControlProtocol::pull_stripable_range (DownButtonList& down, StripableList (*s)->number(), fs, ls)); for (uint32_t n = fs; n < ls; ++n) { - boost::shared_ptr r = (*s)->nth_strip (n)->stripable(); + Strip* strip = (*s)->nth_strip (n); + boost::shared_ptr r = strip->stripable(); if (r) { - selected.push_back (r); + if (global_index_locked (*strip) == pressed) { + selected.push_front (r); + } else { + selected.push_back (r); + } } } } } + } void @@ -2418,56 +2354,50 @@ MackieControlProtocol::is_midi_track (boost::shared_ptr r) const } bool -MackieControlProtocol::selected (boost::shared_ptr r) const +MackieControlProtocol::is_mapped (boost::shared_ptr r) const { - const StripableNotificationList* rl = &_last_selected_stripables; + Glib::Threads::Mutex::Lock lm (surfaces_lock); - for (ARDOUR::StripableNotificationList::const_iterator i = rl->begin(); i != rl->end(); ++i) { - boost::shared_ptr rt = (*i).lock(); - if (rt == r) { + for (Surfaces::const_iterator s = surfaces.begin(); s != surfaces.end(); ++s) { + if ((*s)->stripable_is_mapped (r)) { return true; } } + return false; } -bool -MackieControlProtocol::is_hidden (boost::shared_ptr r) const +void +MackieControlProtocol::update_selected (boost::shared_ptr s, bool became_selected) { - if (!r) { - return false; - } - return (r->presentation_info().flags() & PresentationInfo::Hidden); -} + if (became_selected) { -bool -MackieControlProtocol::is_mapped (boost::shared_ptr r) const -{ - Glib::Threads::Mutex::Lock lm (surfaces_lock); + check_fader_automation_state (); - for (Surfaces::const_iterator s = surfaces.begin(); s != surfaces.end(); ++s) { - if ((*s)->stripable_is_mapped (r)) { - return true; + /* It is possible that first_selected_route() may return null if we + * are no longer displaying/mapping that route. In that case, + * we will exit subview mode. If first_selected_route() is + * null, and subview mode is not None, then the first call to + * set_subview_mode() will fail, and we will reset to None. + */ + + if (set_subview_mode (_subview_mode, first_selected_stripable())) { + set_subview_mode (None, boost::shared_ptr()); } - } - return false; + } } boost::shared_ptr MackieControlProtocol::first_selected_stripable () const { - if (_last_selected_stripables.empty()) { - return boost::shared_ptr(); - } + boost::shared_ptr s = ControlProtocol::first_selected_stripable(); - boost::shared_ptr r = _last_selected_stripables.front().lock(); - - 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 @@ -2475,10 +2405,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 @@ -2491,6 +2421,12 @@ uint32_t MackieControlProtocol::global_index (Strip& strip) { Glib::Threads::Mutex::Lock lm (surfaces_lock); + return global_index_locked (strip); +} + +uint32_t +MackieControlProtocol::global_index_locked (Strip& strip) +{ uint32_t global = 0; for (Surfaces::const_iterator s = surfaces.begin(); s != surfaces.end(); ++s) {