diff options
-rw-r--r-- | gtk2_ardour/editor_ops.cc | 20 | ||||
-rw-r--r-- | libs/ardour/ardour/location.h | 4 | ||||
-rw-r--r-- | libs/ardour/location.cc | 79 | ||||
-rw-r--r-- | libs/surfaces/control_protocol/basic_ui.cc | 14 | ||||
-rw-r--r-- | libs/surfaces/mackie/mcp_buttons.cc | 27 |
5 files changed, 79 insertions, 65 deletions
diff --git a/gtk2_ardour/editor_ops.cc b/gtk2_ardour/editor_ops.cc index 6ceb3fd111..aeb307dc77 100644 --- a/gtk2_ardour/editor_ops.cc +++ b/gtk2_ardour/editor_ops.cc @@ -1846,13 +1846,13 @@ Editor::jump_forward_to_mark () return; } - Location *location = _session->locations()->first_location_after (playhead_cursor->current_frame); + framepos_t pos = _session->locations()->first_mark_after (playhead_cursor->current_frame); - if (location) { - _session->request_locate (location->start(), _session->transport_rolling()); - } else { - _session->request_locate (_session->current_end_frame()); + if (pos < 0) { + return; } + + _session->request_locate (pos, _session->transport_rolling()); } void @@ -1862,13 +1862,13 @@ Editor::jump_backward_to_mark () return; } - Location *location = _session->locations()->first_location_before (playhead_cursor->current_frame); + framepos_t pos = _session->locations()->first_mark_before (playhead_cursor->current_frame); - if (location) { - _session->request_locate (location->start(), _session->transport_rolling()); - } else { - _session->goto_start (); + if (pos < 0) { + return; } + + _session->request_locate (pos, _session->transport_rolling()); } void diff --git a/libs/ardour/ardour/location.h b/libs/ardour/ardour/location.h index 2b9c53e063..bb42df1b58 100644 --- a/libs/ardour/ardour/location.h +++ b/libs/ardour/ardour/location.h @@ -161,8 +161,8 @@ class Locations : public SessionHandleRef, public PBD::StatefulDestructible int set_current (Location *, bool want_lock = true); Location *current () const { return current_location; } - Location* first_location_before (framepos_t, bool include_special_ranges = false); - Location* first_location_after (framepos_t, bool include_special_ranges = false); + framepos_t first_mark_before (framepos_t, bool include_special_ranges = false); + framepos_t first_mark_after (framepos_t, bool include_special_ranges = false); void marks_either_side (framepos_t const, framepos_t &, framepos_t &) const; diff --git a/libs/ardour/location.cc b/libs/ardour/location.cc index 4586fbee26..2a27fc318a 100644 --- a/libs/ardour/location.cc +++ b/libs/ardour/location.cc @@ -922,72 +922,87 @@ Locations::set_state (const XMLNode& node, int version) return 0; } + +typedef std::pair<framepos_t,Location*> LocationPair; + struct LocationStartEarlierComparison { - bool operator() (Location *a, Location *b) { - return a->start() < b->start(); + bool operator() (LocationPair a, LocationPair b) { + return a.first < b.first; } }; struct LocationStartLaterComparison { - bool operator() (Location *a, Location *b) { - return a->start() > b->start(); + bool operator() (LocationPair a, LocationPair b) { + return a.first > b.first; } }; -Location * -Locations::first_location_before (framepos_t frame, bool include_special_ranges) +framepos_t +Locations::first_mark_before (framepos_t frame, bool include_special_ranges) { - LocationList locs; - - { - Glib::Threads::Mutex::Lock lm (lock); - locs = locations; + Glib::Threads::Mutex::Lock lm (lock); + vector<LocationPair> locs; + + for (LocationList::iterator i = locations.begin(); i != locations.end(); ++i) { + locs.push_back (make_pair ((*i)->start(), (*i))); + if (!(*i)->is_mark()) { + locs.push_back (make_pair ((*i)->end(), (*i))); + } } LocationStartLaterComparison cmp; - locs.sort (cmp); + sort (locs.begin(), locs.end(), cmp); - /* locs is now sorted latest..earliest */ + /* locs is sorted in ascending order */ - for (LocationList::iterator i = locs.begin(); i != locs.end(); ++i) { - if (!include_special_ranges && ((*i)->is_auto_loop() || (*i)->is_auto_punch())) { + for (vector<LocationPair>::iterator i = locs.begin(); i != locs.end(); ++i) { + if ((*i).second->is_hidden()) { + continue; + } + if (!include_special_ranges && ((*i).second->is_auto_loop() || (*i).second->is_auto_punch())) { continue; } - if (!(*i)->is_hidden() && (*i)->start() < frame) { - return (*i); + if ((*i).first < frame) { + return (*i).first; } } - return 0; + return -1; } -Location * -Locations::first_location_after (framepos_t frame, bool include_special_ranges) +framepos_t +Locations::first_mark_after (framepos_t frame, bool include_special_ranges) { - LocationList locs; + Glib::Threads::Mutex::Lock lm (lock); + vector<LocationPair> locs; - { - Glib::Threads::Mutex::Lock lm (lock); - locs = locations; + for (LocationList::iterator i = locations.begin(); i != locations.end(); ++i) { + locs.push_back (make_pair ((*i)->start(), (*i))); + if (!(*i)->is_mark()) { + locs.push_back (make_pair ((*i)->end(), (*i))); + } } LocationStartEarlierComparison cmp; - locs.sort (cmp); - - /* locs is now sorted earliest..latest */ + sort (locs.begin(), locs.end(), cmp); + + /* locs is sorted in reverse order */ - for (LocationList::iterator i = locs.begin(); i != locs.end(); ++i) { - if (!include_special_ranges && ((*i)->is_auto_loop() || (*i)->is_auto_punch())) { + for (vector<LocationPair>::iterator i = locs.begin(); i != locs.end(); ++i) { + if ((*i).second->is_hidden()) { continue; } - if (!(*i)->is_hidden() && (*i)->start() > frame) { - return (*i); + if (!include_special_ranges && ((*i).second->is_auto_loop() || (*i).second->is_auto_punch())) { + continue; + } + if ((*i).first > frame) { + return (*i).first; } } - return 0; + return -1; } /** Look for the `marks' (either locations which are marks, or start/end points of range markers) either diff --git a/libs/surfaces/control_protocol/basic_ui.cc b/libs/surfaces/control_protocol/basic_ui.cc index 2ed82cd8c3..98e7adf949 100644 --- a/libs/surfaces/control_protocol/basic_ui.cc +++ b/libs/surfaces/control_protocol/basic_ui.cc @@ -171,10 +171,10 @@ BasicUI::save_state () void BasicUI::prev_marker () { - Location *location = session->locations()->first_location_before (session->transport_frame()); + framepos_t pos = session->locations()->first_mark_before (session->transport_frame()); - if (location) { - session->request_locate (location->start(), session->transport_rolling()); + if (pos >= 0) { + session->request_locate (pos, session->transport_rolling()); } else { session->goto_start (); } @@ -183,12 +183,12 @@ BasicUI::prev_marker () void BasicUI::next_marker () { - Location *location = session->locations()->first_location_after (session->transport_frame()); + framepos_t pos = session->locations()->first_mark_after (session->transport_frame()); - if (location) { - session->request_locate (location->start(), session->transport_rolling()); + if (pos >= 0) { + session->request_locate (pos, session->transport_rolling()); } else { - session->request_locate (session->current_end_frame()); + session->goto_end(); } } diff --git a/libs/surfaces/mackie/mcp_buttons.cc b/libs/surfaces/mackie/mcp_buttons.cc index 874f752b4e..286e87a0fb 100644 --- a/libs/surfaces/mackie/mcp_buttons.cc +++ b/libs/surfaces/mackie/mcp_buttons.cc @@ -429,22 +429,21 @@ MackieControlProtocol::frm_left_press (Button &) // can use first_mark_before/after as well unsigned long elapsed = _frm_left_last.restart(); - Location * loc = session->locations()->first_location_before (session->transport_frame()); - + framepos_t pos = session->locations()->first_mark_before (session->transport_frame()); + // allow a quick double to go past a previous mark - if (session->transport_rolling() && elapsed < 500 && loc != 0) { - Location * loc_two_back = session->locations()->first_location_before (loc->start()); - if (loc_two_back != 0) - { - loc = loc_two_back; + if (session->transport_rolling() && elapsed < 500 && pos >= 0) { + framepos_t pos_two_back = session->locations()->first_mark_before (pos); + if (pos_two_back >= 0) { + pos = pos_two_back; } } // move to the location, if it's valid - if (loc != 0) { - session->request_locate (loc->start(), session->transport_rolling()); + if (pos >= 0) { + session->request_locate (pos, session->transport_rolling()); } else { - session->request_locate (session->locations()->session_range_location()->start(), session->transport_rolling()); + session->request_locate (session->current_start_frame(), session->transport_rolling()); } return on; @@ -460,12 +459,12 @@ LedState MackieControlProtocol::frm_right_press (Button &) { // can use first_mark_before/after as well - Location * loc = session->locations()->first_location_after (session->transport_frame()); + framepos_t pos = session->locations()->first_mark_after (session->transport_frame()); - if (loc != 0) { - session->request_locate (loc->start(), session->transport_rolling()); + if (pos >= 0) { + session->request_locate (pos, session->transport_rolling()); } else { - session->request_locate (session->locations()->session_range_location()->end(), session->transport_rolling()); + session->request_locate (session->current_end_frame(), session->transport_rolling()); } return on; |