diff options
Diffstat (limited to 'gtk2_ardour')
-rw-r--r-- | gtk2_ardour/ardour-sae-ansi.bindings.in | 1 | ||||
-rw-r--r-- | gtk2_ardour/ardour-sae.menus | 1 | ||||
-rw-r--r-- | gtk2_ardour/ardour.menus | 1 | ||||
-rw-r--r-- | gtk2_ardour/editor.h | 1 | ||||
-rw-r--r-- | gtk2_ardour/editor_actions.cc | 1 | ||||
-rw-r--r-- | gtk2_ardour/editor_ops.cc | 10 | ||||
-rw-r--r-- | gtk2_ardour/editor_selection.cc | 200 |
7 files changed, 176 insertions, 39 deletions
diff --git a/gtk2_ardour/ardour-sae-ansi.bindings.in b/gtk2_ardour/ardour-sae-ansi.bindings.in index 9b27b7f5f0..523878bd3f 100644 --- a/gtk2_ardour/ardour-sae-ansi.bindings.in +++ b/gtk2_ardour/ardour-sae-ansi.bindings.in @@ -67,6 +67,7 @@ ; (gtk_accel_path "<Actions>/Main/AudioFileFormatData" "") ; (gtk_accel_path "<Actions>/options/MeterFalloffFastest" "") (gtk_accel_path "<Actions>/Editor/play-selected-regions" "w") +(gtk_accel_path "<Actions>/Editor/play-edit-range" "<%SECONDARY%>w") (gtk_accel_path "<Actions>/Transport/Forward" "<%PRIMARY%>rightarrow") ; (gtk_accel_path "<Actions>/Snap/snap-to-smpte-seconds" "") ; (gtk_accel_path "<Actions>/Snap/snap-to-smpte-frame" "") diff --git a/gtk2_ardour/ardour-sae.menus b/gtk2_ardour/ardour-sae.menus index 66d00c51e7..a1818a9965 100644 --- a/gtk2_ardour/ardour-sae.menus +++ b/gtk2_ardour/ardour-sae.menus @@ -31,6 +31,7 @@ <menu name='Transport' action='Transport'> <menuitem action='ToggleRoll'/> <menuitem action='play-from-edit-point-and-return'/> + <menuitem action='play-edit-range'/> <menuitem action='record-roll'/> <menuitem action='ToggleRollForgetCapture'/> <menuitem action='Loop'/> diff --git a/gtk2_ardour/ardour.menus b/gtk2_ardour/ardour.menus index 4681a4451c..a60e52561e 100644 --- a/gtk2_ardour/ardour.menus +++ b/gtk2_ardour/ardour.menus @@ -33,6 +33,7 @@ <menuitem action='ToggleRollForgetCapture'/> <menuitem action='Loop'/> <menuitem action='PlaySelection'/> + <menuitem action='play-edit-range'/> <menuitem action='Forward'/> <menuitem action='Rewind'/> <menuitem action='GotoZero'/> diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h index b54555b68d..8287bde9f1 100644 --- a/gtk2_ardour/editor.h +++ b/gtk2_ardour/editor.h @@ -1001,6 +1001,7 @@ class Editor : public PublicEditor void play_from_edit_point (); void play_from_edit_point_and_return (); void play_selected_region (); + void play_edit_range (); void loop_selected_region (); void play_location (ARDOUR::Location&); void loop_location (ARDOUR::Location&); diff --git a/gtk2_ardour/editor_actions.cc b/gtk2_ardour/editor_actions.cc index 320c1cc781..7e5b4adca3 100644 --- a/gtk2_ardour/editor_actions.cc +++ b/gtk2_ardour/editor_actions.cc @@ -300,6 +300,7 @@ Editor::register_actions () act = ActionManager::register_action (editor_actions, "play-from-edit-point-and-return", _("Play from Edit Point & Return"), mem_fun(*this, &Editor::play_from_edit_point_and_return)); ActionManager::session_sensitive_actions.push_back (act); + act = ActionManager::register_action (editor_actions, "play-edit-range", _("Play Edit Range"), mem_fun(*this, &Editor::play_edit_range)); act = ActionManager::register_action (editor_actions, "play-selected-regions", _("Play Selected Region(s)"), mem_fun(*this, &Editor::play_selected_region)); ActionManager::session_sensitive_actions.push_back (act); act = ActionManager::register_action (editor_actions, "brush-at-mouse", _("Brush at Mouse"), mem_fun(*this, &Editor::kbd_brush)); diff --git a/gtk2_ardour/editor_ops.cc b/gtk2_ardour/editor_ops.cc index d5e47c42e3..b30c44eae0 100644 --- a/gtk2_ardour/editor_ops.cc +++ b/gtk2_ardour/editor_ops.cc @@ -2365,6 +2365,16 @@ Editor::audition_playlist_region_via_route (boost::shared_ptr<Region> region, Ro } void +Editor::play_edit_range () +{ + nframes64_t start, end; + + if (get_edit_op_range (start, end)) { + session->request_bounded_roll (start, end); + } +} + +void Editor::play_selected_region () { nframes64_t start = max_frames; diff --git a/gtk2_ardour/editor_selection.cc b/gtk2_ardour/editor_selection.cc index 29d7a8a6bb..1ae304316b 100644 --- a/gtk2_ardour/editor_selection.cc +++ b/gtk2_ardour/editor_selection.cc @@ -17,6 +17,9 @@ */ +#include <algorithm> +#include <stdlib.h> + #include <pbd/stacktrace.h> #include <ardour/diskstream.h> @@ -464,6 +467,7 @@ Editor::set_selected_regionview_from_click (bool press, Selection::Operation op, list<Selectable*> results; nframes_t last_frame; nframes_t first_frame; + bool same_track = false; /* 1. find the last selected regionview in the track that was clicked in */ @@ -480,63 +484,181 @@ Editor::set_selected_regionview_from_click (bool press, Selection::Operation op, if ((*x)->region()->first_frame() < first_frame) { first_frame = (*x)->region()->first_frame(); } + + same_track = true; } } - /* 2. figure out the boundaries for our search for new objects */ + if (same_track) { - switch (clicked_regionview->region()->coverage (first_frame, last_frame)) { - case OverlapNone: - if (last_frame < clicked_regionview->region()->first_frame()) { - first_frame = last_frame; - last_frame = clicked_regionview->region()->last_frame(); - } else { - last_frame = first_frame; - first_frame = clicked_regionview->region()->first_frame(); - } - break; - - case OverlapExternal: - if (last_frame < clicked_regionview->region()->first_frame()) { - first_frame = last_frame; - last_frame = clicked_regionview->region()->last_frame(); - } else { - last_frame = first_frame; - first_frame = clicked_regionview->region()->first_frame(); + /* 2. figure out the boundaries for our search for new objects */ + + switch (clicked_regionview->region()->coverage (first_frame, last_frame)) { + case OverlapNone: + if (last_frame < clicked_regionview->region()->first_frame()) { + first_frame = last_frame; + last_frame = clicked_regionview->region()->last_frame(); + } else { + last_frame = first_frame; + first_frame = clicked_regionview->region()->first_frame(); + } + break; + + case OverlapExternal: + if (last_frame < clicked_regionview->region()->first_frame()) { + first_frame = last_frame; + last_frame = clicked_regionview->region()->last_frame(); + } else { + last_frame = first_frame; + first_frame = clicked_regionview->region()->first_frame(); + } + break; + + case OverlapInternal: + if (last_frame < clicked_regionview->region()->first_frame()) { + first_frame = last_frame; + last_frame = clicked_regionview->region()->last_frame(); + } else { + last_frame = first_frame; + first_frame = clicked_regionview->region()->first_frame(); + } + break; + + case OverlapStart: + case OverlapEnd: + /* nothing to do except add clicked region to selection, since it + overlaps with the existing selection in this track. + */ + break; } - break; - case OverlapInternal: - if (last_frame < clicked_regionview->region()->first_frame()) { - first_frame = last_frame; - last_frame = clicked_regionview->region()->last_frame(); - } else { - last_frame = first_frame; - first_frame = clicked_regionview->region()->first_frame(); - } - break; + } else { - case OverlapStart: - case OverlapEnd: - /* nothing to do except add clicked region to selection, since it - overlaps with the existing selection in this track. + /* click in a track that has no regions selected, so extend vertically + to pick out all regions that are defined by the existing selection + plus this one. */ - break; + + + first_frame = entered_regionview->region()->position(); + last_frame = entered_regionview->region()->last_frame(); + + for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) { + if ((*i)->region()->position() < first_frame) { + first_frame = (*i)->region()->position(); + } + if ((*i)->region()->last_frame() + 1 > last_frame) { + last_frame = (*i)->region()->last_frame(); + } + } } - /* 2. find all selectable objects (regionviews in this case) between that one and the end of the - one that was clicked. - */ + /* 2. find all the tracks we should select in */ set<AudioTimeAxisView*> relevant_tracks; - + set<AudioTimeAxisView*> already_in_selection; + get_relevant_audio_tracks (relevant_tracks); + if (relevant_tracks.empty()) { + + /* no relevant tracks -> no tracks selected .. thus .. if + the regionview we're in isn't selected (i.e. we're + about to extend to it), then find all tracks between + the this one and any selected ones. + */ + + if (!selection->selected (entered_regionview)) { + + AudioTimeAxisView* atv = dynamic_cast<AudioTimeAxisView*> (&entered_regionview->get_time_axis_view()); + + if (atv) { + + /* add this track to the ones we will search */ + + relevant_tracks.insert (atv); + + /* find the track closest to this one that + already a selected region. + */ + + AudioTimeAxisView* closest = 0; + int distance = INT_MAX; + int key = atv->route()->order_key ("editor"); + + for (RegionSelection::iterator x = selection->regions.begin(); x != selection->regions.end(); ++x) { + + AudioTimeAxisView* aatv = dynamic_cast<AudioTimeAxisView*>(&(*x)->get_time_axis_view()); + + if (aatv && aatv != atv) { + + pair<set<AudioTimeAxisView*>::iterator,bool> result; + + result = already_in_selection.insert (aatv); + + if (result.second) { + /* newly added to already_in_selection */ + + + int d = aatv->route()->order_key ("editor"); + + d -= key; + + if (abs (d) < distance) { + distance = abs (d); + closest = aatv; + } + } + } + } + + if (closest) { + + /* now add all tracks between that one and this one */ + + int okey = closest->route()->order_key ("editor"); + + if (okey > key) { + swap (okey, key); + } + + for (TrackViewList::iterator x = track_views.begin(); x != track_views.end(); ++x) { + AudioTimeAxisView* aatv = dynamic_cast<AudioTimeAxisView*>(*x); + if (aatv && aatv != atv) { + + int k = aatv->route()->order_key ("editor"); + + if (k >= okey && k <= key) { + + /* in range but don't add it if + it already has tracks selected. + this avoids odd selection + behaviour that feels wrong. + */ + + if (find (already_in_selection.begin(), + already_in_selection.end(), + aatv) == already_in_selection.end()) { + + relevant_tracks.insert (aatv); + } + } + } + } + } + } + } + } + + /* 3. find all selectable objects (regionviews in this case) between that one and the end of the + one that was clicked. + */ + for (set<AudioTimeAxisView*>::iterator t = relevant_tracks.begin(); t != relevant_tracks.end(); ++t) { (*t)->get_selectables (first_frame, last_frame, -1.0, -1.0, results); } - /* 3. convert to a vector of audio regions */ + /* 4. convert to a vector of audio regions */ vector<RegionView*> regions; |