mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-20 21:56:30 +01:00
first pass at making shift-click to select region extend the selection vertically across tracks
git-svn-id: svn://localhost/ardour2/branches/2.0-ongoing@2809 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
ed1283568b
commit
bae8d50093
7 changed files with 176 additions and 39 deletions
|
|
@ -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" "")
|
||||
|
|
|
|||
|
|
@ -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'/>
|
||||
|
|
|
|||
|
|
@ -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'/>
|
||||
|
|
|
|||
|
|
@ -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&);
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -2364,6 +2364,16 @@ Editor::audition_playlist_region_via_route (boost::shared_ptr<Region> region, Ro
|
|||
/* XXX how to unset the solo state ? */
|
||||
}
|
||||
|
||||
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 ()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
/* 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 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;
|
||||
} else {
|
||||
|
||||
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.
|
||||
/* 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;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue