mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-10 16:46:35 +01:00
various fixes for "advanced" operations on range selections. ctrl-drags now add a new range selection, allowing discontiguous selections as in ardour2, shift-click extends an existing range selection to the clicked position, alt-drag on a range selection moves it, and to do a so-called "separation drag" now use ctrl-alt-drag (or ctrl-alt-click)
git-svn-id: svn://localhost/ardour2/branches/3.0@13660 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
2292e33ee4
commit
40e9dae606
5 changed files with 106 additions and 34 deletions
|
|
@ -3421,12 +3421,18 @@ ScrubDrag::aborted (bool)
|
||||||
SelectionDrag::SelectionDrag (Editor* e, ArdourCanvas::Item* i, Operation o)
|
SelectionDrag::SelectionDrag (Editor* e, ArdourCanvas::Item* i, Operation o)
|
||||||
: Drag (e, i)
|
: Drag (e, i)
|
||||||
, _operation (o)
|
, _operation (o)
|
||||||
, _copy (false)
|
, _add (false)
|
||||||
|
, _extend (false)
|
||||||
, _original_pointer_time_axis (-1)
|
, _original_pointer_time_axis (-1)
|
||||||
, _last_pointer_time_axis (-1)
|
, _last_pointer_time_axis (-1)
|
||||||
, _time_selection_at_start (!_editor->get_selection().time.empty())
|
, _time_selection_at_start (!_editor->get_selection().time.empty())
|
||||||
{
|
{
|
||||||
DEBUG_TRACE (DEBUG::Drags, "New SelectionDrag\n");
|
DEBUG_TRACE (DEBUG::Drags, "New SelectionDrag\n");
|
||||||
|
|
||||||
|
if (_time_selection_at_start) {
|
||||||
|
start_at_start = _editor->get_selection().time.start();
|
||||||
|
end_at_start = _editor->get_selection().time.end_frame();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -3440,10 +3446,10 @@ SelectionDrag::start_grab (GdkEvent* event, Gdk::Cursor*)
|
||||||
|
|
||||||
switch (_operation) {
|
switch (_operation) {
|
||||||
case CreateSelection:
|
case CreateSelection:
|
||||||
if (Keyboard::modifier_state_equals (event->button.state, Keyboard::TertiaryModifier)) {
|
if (Keyboard::modifier_state_equals (event->button.state, Keyboard::CopyModifier)) {
|
||||||
_copy = true;
|
_add = true;
|
||||||
} else {
|
} else {
|
||||||
_copy = false;
|
_add = false;
|
||||||
}
|
}
|
||||||
cursor = _editor->cursors()->selector;
|
cursor = _editor->cursors()->selector;
|
||||||
Drag::start_grab (event, cursor);
|
Drag::start_grab (event, cursor);
|
||||||
|
|
@ -3466,6 +3472,10 @@ SelectionDrag::start_grab (GdkEvent* event, Gdk::Cursor*)
|
||||||
case SelectionMove:
|
case SelectionMove:
|
||||||
Drag::start_grab (event, cursor);
|
Drag::start_grab (event, cursor);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SelectionExtend:
|
||||||
|
Drag::start_grab (event, cursor);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_operation == SelectionMove) {
|
if (_operation == SelectionMove) {
|
||||||
|
|
@ -3493,6 +3503,9 @@ SelectionDrag::setup_pointer_frame_offset ()
|
||||||
case SelectionEndTrim:
|
case SelectionEndTrim:
|
||||||
_pointer_frame_offset = raw_grab_frame() - _editor->selection->time[_editor->clicked_selection].end;
|
_pointer_frame_offset = raw_grab_frame() - _editor->selection->time[_editor->clicked_selection].end;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SelectionExtend:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3501,7 +3514,8 @@ SelectionDrag::motion (GdkEvent* event, bool first_move)
|
||||||
{
|
{
|
||||||
framepos_t start = 0;
|
framepos_t start = 0;
|
||||||
framepos_t end = 0;
|
framepos_t end = 0;
|
||||||
framecnt_t length;
|
framecnt_t length = 0;
|
||||||
|
framecnt_t distance = 0;
|
||||||
|
|
||||||
pair<TimeAxisView*, int> const pending_time_axis = _editor->trackview_by_y_position (_drags->current_pointer_y ());
|
pair<TimeAxisView*, int> const pending_time_axis = _editor->trackview_by_y_position (_drags->current_pointer_y ());
|
||||||
if (pending_time_axis.first == 0) {
|
if (pending_time_axis.first == 0) {
|
||||||
|
|
@ -3544,12 +3558,12 @@ SelectionDrag::motion (GdkEvent* event, bool first_move)
|
||||||
|
|
||||||
if (first_move) {
|
if (first_move) {
|
||||||
|
|
||||||
if (_copy) {
|
if (_add) {
|
||||||
/* adding to the selection */
|
/* adding to the selection */
|
||||||
_editor->set_selected_track_as_side_effect (Selection::Add);
|
_editor->set_selected_track_as_side_effect (Selection::Add);
|
||||||
//_editor->selection->add (_editor->clicked_axisview);
|
//_editor->selection->add (_editor->clicked_axisview);
|
||||||
_editor->clicked_selection = _editor->selection->add (start, end);
|
_editor->clicked_selection = _editor->selection->add (start, end);
|
||||||
_copy = false;
|
_add = false;
|
||||||
} else {
|
} else {
|
||||||
/* new selection */
|
/* new selection */
|
||||||
|
|
||||||
|
|
@ -3617,20 +3631,23 @@ SelectionDrag::motion (GdkEvent* event, bool first_move)
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SelectionMove:
|
case SelectionMove:
|
||||||
|
|
||||||
start = _editor->selection->time[_editor->clicked_selection].start;
|
start = _editor->selection->time[_editor->clicked_selection].start;
|
||||||
end = _editor->selection->time[_editor->clicked_selection].end;
|
end = _editor->selection->time[_editor->clicked_selection].end;
|
||||||
|
|
||||||
length = end - start;
|
length = end - start;
|
||||||
|
distance = pending_position - start;
|
||||||
start = pending_position;
|
start = pending_position;
|
||||||
_editor->snap_to (start);
|
_editor->snap_to (start);
|
||||||
|
|
||||||
end = start + length;
|
end = start + length;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SelectionExtend:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event->button.x >= _editor->horizontal_position() + _editor->_canvas_width) {
|
if (event->button.x >= _editor->horizontal_position() + _editor->_canvas_width) {
|
||||||
|
|
@ -3638,7 +3655,15 @@ SelectionDrag::motion (GdkEvent* event, bool first_move)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (start != end) {
|
if (start != end) {
|
||||||
_editor->selection->replace (_editor->clicked_selection, start, end);
|
switch (_operation) {
|
||||||
|
case SelectionMove:
|
||||||
|
if (_time_selection_at_start) {
|
||||||
|
_editor->selection->move_time (distance);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
_editor->selection->replace (_editor->clicked_selection, start, end);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_operation == SelectionMove) {
|
if (_operation == SelectionMove) {
|
||||||
|
|
@ -3674,12 +3699,30 @@ SelectionDrag::finished (GdkEvent* event, bool movement_occurred)
|
||||||
} else {
|
} else {
|
||||||
/* just a click, no pointer movement.
|
/* just a click, no pointer movement.
|
||||||
*/
|
*/
|
||||||
_editor->selection->clear_time();
|
|
||||||
|
if (_operation == SelectionExtend) {
|
||||||
|
if (_time_selection_at_start) {
|
||||||
|
framepos_t pos = adjusted_current_frame (event, false);
|
||||||
|
framepos_t start = min (pos, start_at_start);
|
||||||
|
framepos_t end = max (pos, end_at_start);
|
||||||
|
_editor->selection->set (start, end);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (Keyboard::modifier_state_equals (event->button.state, Keyboard::CopyModifier)) {
|
||||||
|
if (_editor->clicked_selection) {
|
||||||
|
_editor->selection->remove (_editor->clicked_selection);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!_editor->clicked_selection) {
|
||||||
|
_editor->selection->clear_time();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (_editor->clicked_axisview && !_editor->selection->selected (_editor->clicked_axisview)) {
|
if (_editor->clicked_axisview && !_editor->selection->selected (_editor->clicked_axisview)) {
|
||||||
_editor->selection->set (_editor->clicked_axisview);
|
_editor->selection->set (_editor->clicked_axisview);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s && s->get_play_range () && s->transport_rolling()) {
|
if (s && s->get_play_range () && s->transport_rolling()) {
|
||||||
s->request_stop (false, false);
|
s->request_stop (false, false);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -862,7 +862,8 @@ public:
|
||||||
CreateSelection,
|
CreateSelection,
|
||||||
SelectionStartTrim,
|
SelectionStartTrim,
|
||||||
SelectionEndTrim,
|
SelectionEndTrim,
|
||||||
SelectionMove
|
SelectionMove,
|
||||||
|
SelectionExtend
|
||||||
};
|
};
|
||||||
|
|
||||||
SelectionDrag (Editor *, ArdourCanvas::Item *, Operation);
|
SelectionDrag (Editor *, ArdourCanvas::Item *, Operation);
|
||||||
|
|
@ -876,11 +877,14 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Operation _operation;
|
Operation _operation;
|
||||||
bool _copy;
|
bool _add;
|
||||||
|
bool _extend;
|
||||||
int _original_pointer_time_axis;
|
int _original_pointer_time_axis;
|
||||||
int _last_pointer_time_axis;
|
int _last_pointer_time_axis;
|
||||||
std::list<TimeAxisView*> _added_time_axes;
|
std::list<TimeAxisView*> _added_time_axes;
|
||||||
bool _time_selection_at_start;
|
bool _time_selection_at_start;
|
||||||
|
framepos_t start_at_start;
|
||||||
|
framepos_t end_at_start;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Range marker drag */
|
/** Range marker drag */
|
||||||
|
|
|
||||||
|
|
@ -598,22 +598,24 @@ Editor::button_selection (ArdourCanvas::Item* /*item*/, GdkEvent* event, ItemTyp
|
||||||
|
|
||||||
switch (item_type) {
|
switch (item_type) {
|
||||||
case RegionItem:
|
case RegionItem:
|
||||||
if (press) {
|
if (!get_smart_mode() || (_join_object_range_state == JOIN_OBJECT_RANGE_OBJECT)) {
|
||||||
if (mouse_mode != MouseRange) {
|
if (press) {
|
||||||
set_selected_regionview_from_click (press, op);
|
if (mouse_mode != MouseRange) {
|
||||||
} else {
|
set_selected_regionview_from_click (press, op);
|
||||||
/* don't change the selection unless the
|
} else {
|
||||||
clicked track is not currently selected. if
|
/* don't change the selection unless the
|
||||||
so, "collapse" the selection to just this
|
clicked track is not currently selected. if
|
||||||
track
|
so, "collapse" the selection to just this
|
||||||
*/
|
track
|
||||||
if (!selection->selected (clicked_axisview)) {
|
*/
|
||||||
set_selected_track_as_side_effect (Selection::Set);
|
if (!selection->selected (clicked_axisview)) {
|
||||||
|
set_selected_track_as_side_effect (Selection::Set);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (mouse_mode != MouseRange) {
|
||||||
|
set_selected_regionview_from_click (press, op);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (mouse_mode != MouseRange) {
|
|
||||||
set_selected_regionview_from_click (press, op);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -800,9 +802,7 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SelectionItem:
|
case SelectionItem:
|
||||||
if (Keyboard::modifier_state_contains
|
if (Keyboard::modifier_state_contains (event->button.state, Keyboard::ModifierMask(Keyboard::PrimaryModifier|Keyboard::SecondaryModifier))) {
|
||||||
(event->button.state, Keyboard::ModifierMask(Keyboard::PrimaryModifier))) {
|
|
||||||
// contains and not equals because I can't use alt as a modifier alone.
|
|
||||||
start_selection_grab (item, event);
|
start_selection_grab (item, event);
|
||||||
} else if (Keyboard::modifier_state_equals (event->button.state, Keyboard::SecondaryModifier)) {
|
} else if (Keyboard::modifier_state_equals (event->button.state, Keyboard::SecondaryModifier)) {
|
||||||
/* grab selection for moving */
|
/* grab selection for moving */
|
||||||
|
|
@ -831,7 +831,11 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_drags->set (new SelectionDrag (this, item, SelectionDrag::CreateSelection), event);
|
if (Keyboard::modifier_state_equals (event->button.state, Keyboard::RangeSelectModifier)) {
|
||||||
|
_drags->set (new SelectionDrag (this, item, SelectionDrag::SelectionExtend), event);
|
||||||
|
} else {
|
||||||
|
_drags->set (new SelectionDrag (this, item, SelectionDrag::CreateSelection), event);
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -855,7 +859,11 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (!internal_editing()) {
|
if (!internal_editing()) {
|
||||||
_drags->set (new SelectionDrag (this, item, SelectionDrag::CreateSelection), event);
|
if (Keyboard::modifier_state_equals (event->button.state, Keyboard::RangeSelectModifier)) {
|
||||||
|
_drags->set (new SelectionDrag (this, item, SelectionDrag::SelectionExtend), event);
|
||||||
|
} else {
|
||||||
|
_drags->set (new SelectionDrag (this, item, SelectionDrag::CreateSelection), event);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
|
|
@ -531,6 +531,21 @@ Selection::add (framepos_t start, framepos_t end)
|
||||||
return next_time_id - 1;
|
return next_time_id - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Selection::move_time (framecnt_t distance)
|
||||||
|
{
|
||||||
|
if (distance == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (list<AudioRange>::iterator i = time.begin(); i != time.end(); ++i) {
|
||||||
|
(*i).start += distance;
|
||||||
|
(*i).end += distance;
|
||||||
|
}
|
||||||
|
|
||||||
|
TimeChanged ();
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Selection::replace (uint32_t sid, framepos_t start, framepos_t end)
|
Selection::replace (uint32_t sid, framepos_t start, framepos_t end)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -184,6 +184,8 @@ class Selection : public sigc::trackable, public PBD::ScopedConnectionList
|
||||||
|
|
||||||
void remove_regions (TimeAxisView *);
|
void remove_regions (TimeAxisView *);
|
||||||
|
|
||||||
|
void move_time (framecnt_t);
|
||||||
|
|
||||||
void replace (uint32_t time_index, framepos_t start, framepos_t end);
|
void replace (uint32_t time_index, framepos_t start, framepos_t end);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue