X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;ds=sidebyside;f=libs%2Fsurfaces%2Fmackie%2Fmackie_control_protocol.cc;h=2a5d710eafe52d968abe591b808b64f8342d14a4;hb=bb74bba1c7eb6679b910840cd73746feefbbdad1;hp=89719d03e9c9722fee1b761e4a14bbeeaa193712;hpb=91ad3ef81d94d4108c971b8c9f7a226293d57cfc;p=ardour.git diff --git a/libs/surfaces/mackie/mackie_control_protocol.cc b/libs/surfaces/mackie/mackie_control_protocol.cc index 89719d03e9..2a5d710eaf 100644 --- a/libs/surfaces/mackie/mackie_control_protocol.cc +++ b/libs/surfaces/mackie/mackie_control_protocol.cc @@ -83,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 @@ -138,8 +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); + PresentationInfo::Change.connect (gui_connections, MISSING_INVALIDATOR, boost::bind (&MackieControlProtocol::notify_presentation_info_changed, this, _1), this); _instance = this; @@ -247,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(); } }; @@ -290,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; @@ -307,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; @@ -321,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) && !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; @@ -369,6 +368,7 @@ int MackieControlProtocol::switch_banks (uint32_t initial, bool force) { DEBUG_TRACE (DEBUG::MackieControl, string_compose ("switch banking to start at %1 force ? %2 current = %3\n", initial, force, _current_initial_bank)); + PBD::stacktrace (cerr, 20); if (initial == _current_initial_bank && !force) { /* everything is as it should be */ @@ -437,10 +437,6 @@ MackieControlProtocol::switch_banks (uint32_t initial, bool force) 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(); @@ -1302,8 +1298,17 @@ MackieControlProtocol::notify_solo_active_changed (bool active) } void -MackieControlProtocol::notify_presentation_info_changed () +MackieControlProtocol::notify_presentation_info_changed (PBD::PropertyChange const & what_changed) { + PBD::PropertyChange order_or_hidden; + + order_or_hidden.add (Properties::hidden); + order_or_hidden.add (Properties::order); + + if (!what_changed.contains (order_or_hidden)) { + return; + } + { Glib::Threads::Mutex::Lock lm (surfaces_lock); @@ -1312,23 +1317,7 @@ MackieControlProtocol::notify_presentation_info_changed () } } - Sorted sorted = get_sorted_stripables(); - uint32_t sz = n_strips(); - - // if a remote id has been moved off the end, we need to shift - // the current bank backwards. - - if (sorted.size() - _current_initial_bank < sz) { - // but don't shift backwards past the zeroth channel - if (sorted.size() < sz) { // avoid unsigned math mistake below - (void) switch_banks(0, true); - } else { - (void) switch_banks (max((Sorted::size_type) 0, sorted.size() - sz), true); - } - } else { - // Otherwise just refresh the current bank - refresh_current_bank(); - } + refresh_current_bank(); } /////////////////////////////////////////// @@ -1544,14 +1533,6 @@ MackieControlProtocol::handle_button_event (Surface& surface, Button& button, Bu return; } - if ((button_id != Button::Marker) && (modifier_state() & MODIFIER_MARKER)) { - marker_modifier_consumed_by_button = true; - } - - if ((button_id != Button::Nudge) && (modifier_state() & MODIFIER_NUDGE)) { - nudge_modifier_consumed_by_button = true; - } - DEBUG_TRACE (DEBUG::MackieControl, string_compose ("Handling %1 for button %2 (%3)\n", (bs == press ? "press" : "release"), button.id(), Button::id_to_name (button.bid()))); @@ -1559,6 +1540,8 @@ MackieControlProtocol::handle_button_event (Surface& surface, Button& button, Bu string action = _device_profile.get_button_action (button.bid(), _modifier_state); + DEBUG_TRACE (DEBUG::MackieControl, string_compose ("device profile returned [%1] for that button\n", action)); + if (!action.empty()) { if (action.find ('/') != string::npos) { /* good chance that this is really an action */ @@ -1599,14 +1582,30 @@ MackieControlProtocol::handle_button_event (Surface& surface, Button& button, Bu } } + /* Now that we have the correct (maybe remapped) button ID, do these + * checks on it. + */ + + if ((button_id != Button::Marker) && (modifier_state() & MODIFIER_MARKER)) { + marker_modifier_consumed_by_button = true; + } + + if ((button_id != Button::Nudge) && (modifier_state() & MODIFIER_NUDGE)) { + nudge_modifier_consumed_by_button = true; + } + /* lookup using the device-INDEPENDENT button ID */ + DEBUG_TRACE (DEBUG::MackieControl, string_compose ("now looking up button ID %1\n", button_id)); + ButtonMap::iterator b = button_map.find (button_id); if (b != button_map.end()) { ButtonHandlers& bh (b->second); + DEBUG_TRACE (DEBUG::MackieControl, string_compose ("button found in map, now invoking %1\n", (bs == press ? "press" : "release"))); + switch (bs) { case press: surface.write (button.set_state ((this->*(bh.press)) (button))); @@ -1635,7 +1634,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. @@ -1652,7 +1651,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); } @@ -1733,12 +1732,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); @@ -1926,68 +1929,6 @@ MackieControlProtocol::force_special_stripable_to_strip (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 () { @@ -2090,30 +2031,33 @@ 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.empty() ? "null" : 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 order part of PresentationInfo at present */ - ToggleStripableSelection ((*s)->presentation_info ().order()); - } else { - if (s == stripables.begin()) { - /* XXX can only use order part of PresentationInfo at present */ - SetStripableSelection ((*s)->presentation_info().order()); + if (main_modifier_state() == MODIFIER_SHIFT) { + ToggleStripableSelection (*s); } else { - /* XXX can only use order part of PresentationInfo at present */ - AddStripableToSelection ((*s)->presentation_info().order()); + if (s == stripables.begin()) { + SetStripableSelection (*s); + } else { + AddStripableToSelection (*s); + } } } } @@ -2154,7 +2098,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; @@ -2168,7 +2112,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: @@ -2211,7 +2155,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; @@ -2261,13 +2205,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 @@ -2409,56 +2359,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 @@ -2466,10 +2410,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 @@ -2482,6 +2426,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) {