mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-21 14:16:31 +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>/Main/AudioFileFormatData" "")
|
||||||
; (gtk_accel_path "<Actions>/options/MeterFalloffFastest" "")
|
; (gtk_accel_path "<Actions>/options/MeterFalloffFastest" "")
|
||||||
(gtk_accel_path "<Actions>/Editor/play-selected-regions" "w")
|
(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>/Transport/Forward" "<%PRIMARY%>rightarrow")
|
||||||
; (gtk_accel_path "<Actions>/Snap/snap-to-smpte-seconds" "")
|
; (gtk_accel_path "<Actions>/Snap/snap-to-smpte-seconds" "")
|
||||||
; (gtk_accel_path "<Actions>/Snap/snap-to-smpte-frame" "")
|
; (gtk_accel_path "<Actions>/Snap/snap-to-smpte-frame" "")
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@
|
||||||
<menu name='Transport' action='Transport'>
|
<menu name='Transport' action='Transport'>
|
||||||
<menuitem action='ToggleRoll'/>
|
<menuitem action='ToggleRoll'/>
|
||||||
<menuitem action='play-from-edit-point-and-return'/>
|
<menuitem action='play-from-edit-point-and-return'/>
|
||||||
|
<menuitem action='play-edit-range'/>
|
||||||
<menuitem action='record-roll'/>
|
<menuitem action='record-roll'/>
|
||||||
<menuitem action='ToggleRollForgetCapture'/>
|
<menuitem action='ToggleRollForgetCapture'/>
|
||||||
<menuitem action='Loop'/>
|
<menuitem action='Loop'/>
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,7 @@
|
||||||
<menuitem action='ToggleRollForgetCapture'/>
|
<menuitem action='ToggleRollForgetCapture'/>
|
||||||
<menuitem action='Loop'/>
|
<menuitem action='Loop'/>
|
||||||
<menuitem action='PlaySelection'/>
|
<menuitem action='PlaySelection'/>
|
||||||
|
<menuitem action='play-edit-range'/>
|
||||||
<menuitem action='Forward'/>
|
<menuitem action='Forward'/>
|
||||||
<menuitem action='Rewind'/>
|
<menuitem action='Rewind'/>
|
||||||
<menuitem action='GotoZero'/>
|
<menuitem action='GotoZero'/>
|
||||||
|
|
|
||||||
|
|
@ -1001,6 +1001,7 @@ class Editor : public PublicEditor
|
||||||
void play_from_edit_point ();
|
void play_from_edit_point ();
|
||||||
void play_from_edit_point_and_return ();
|
void play_from_edit_point_and_return ();
|
||||||
void play_selected_region ();
|
void play_selected_region ();
|
||||||
|
void play_edit_range ();
|
||||||
void loop_selected_region ();
|
void loop_selected_region ();
|
||||||
void play_location (ARDOUR::Location&);
|
void play_location (ARDOUR::Location&);
|
||||||
void loop_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));
|
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);
|
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));
|
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);
|
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));
|
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 ? */
|
/* 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
|
void
|
||||||
Editor::play_selected_region ()
|
Editor::play_selected_region ()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,9 @@
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include <pbd/stacktrace.h>
|
#include <pbd/stacktrace.h>
|
||||||
|
|
||||||
#include <ardour/diskstream.h>
|
#include <ardour/diskstream.h>
|
||||||
|
|
@ -464,6 +467,7 @@ Editor::set_selected_regionview_from_click (bool press, Selection::Operation op,
|
||||||
list<Selectable*> results;
|
list<Selectable*> results;
|
||||||
nframes_t last_frame;
|
nframes_t last_frame;
|
||||||
nframes_t first_frame;
|
nframes_t first_frame;
|
||||||
|
bool same_track = false;
|
||||||
|
|
||||||
/* 1. find the last selected regionview in the track that was clicked in */
|
/* 1. find the last selected regionview in the track that was clicked in */
|
||||||
|
|
||||||
|
|
@ -480,9 +484,13 @@ Editor::set_selected_regionview_from_click (bool press, Selection::Operation op,
|
||||||
if ((*x)->region()->first_frame() < first_frame) {
|
if ((*x)->region()->first_frame() < first_frame) {
|
||||||
first_frame = (*x)->region()->first_frame();
|
first_frame = (*x)->region()->first_frame();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
same_track = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (same_track) {
|
||||||
|
|
||||||
/* 2. figure out the boundaries for our search for new objects */
|
/* 2. figure out the boundaries for our search for new objects */
|
||||||
|
|
||||||
switch (clicked_regionview->region()->coverage (first_frame, last_frame)) {
|
switch (clicked_regionview->region()->coverage (first_frame, last_frame)) {
|
||||||
|
|
@ -524,19 +532,133 @@ Editor::set_selected_regionview_from_click (bool press, Selection::Operation op,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 2. find all selectable objects (regionviews in this case) between that one and the end of the
|
} else {
|
||||||
one that was clicked.
|
|
||||||
|
/* 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.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
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 the tracks we should select in */
|
||||||
|
|
||||||
set<AudioTimeAxisView*> relevant_tracks;
|
set<AudioTimeAxisView*> relevant_tracks;
|
||||||
|
set<AudioTimeAxisView*> already_in_selection;
|
||||||
|
|
||||||
get_relevant_audio_tracks (relevant_tracks);
|
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) {
|
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);
|
(*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;
|
vector<RegionView*> regions;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue