summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gtk2_ardour/ardour.menus.in2
-rw-r--r--gtk2_ardour/editor.cc2
-rw-r--r--gtk2_ardour/editor.h1
-rw-r--r--gtk2_ardour/editor_actions.cc2
-rw-r--r--gtk2_ardour/editor_drag.cc234
-rw-r--r--gtk2_ardour/editor_drag.h38
-rw-r--r--gtk2_ardour/editor_mouse.cc12
-rw-r--r--gtk2_ardour/mnemonic-us.bindings.in2
-rw-r--r--gtk2_ardour/time_axis_view_item.cc1
9 files changed, 263 insertions, 31 deletions
diff --git a/gtk2_ardour/ardour.menus.in b/gtk2_ardour/ardour.menus.in
index f4995411e7..d5bb7b797c 100644
--- a/gtk2_ardour/ardour.menus.in
+++ b/gtk2_ardour/ardour.menus.in
@@ -228,7 +228,7 @@
<menuitem action='boost-region-gain'/>
<menuitem action='cut-region-gain'/>
<separator/>
- <menuitem action='break-drag'/>
+ <menuitem action='escape'/>
</menu>
<menu action="TempoMenu">
<menuitem action='set-tempo-from-region'/>
diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc
index 5c5d3abad9..16153908e2 100644
--- a/gtk2_ardour/editor.cc
+++ b/gtk2_ardour/editor.cc
@@ -2290,10 +2290,8 @@ Editor::set_state (const XMLNode& node, int /*version*/)
if ((prop = node.property ("mouse-mode"))) {
MouseMode m = str2mousemode(prop->value());
- mouse_mode = MouseMode ((int) m + 1); /* lie, force mode switch */
set_mouse_mode (m, true);
} else {
- mouse_mode = MouseGain; /* lie, to force the mode switch */
set_mouse_mode (MouseObject, true);
}
diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h
index 6227afa805..74f3ab0448 100644
--- a/gtk2_ardour/editor.h
+++ b/gtk2_ardour/editor.h
@@ -1282,6 +1282,7 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
Drag* _drag;
void break_drag ();
+ void escape ();
Gtk::Menu fade_context_menu;
void popup_fade_context_menu (int, int, ArdourCanvas::Item*, ItemType);
diff --git a/gtk2_ardour/editor_actions.cc b/gtk2_ardour/editor_actions.cc
index 99177601f6..4193e74d74 100644
--- a/gtk2_ardour/editor_actions.cc
+++ b/gtk2_ardour/editor_actions.cc
@@ -106,7 +106,7 @@ Editor::register_actions ()
/* add named actions for the editor */
- ActionManager::register_action (editor_actions, "break-drag", _("Break drag"), sigc::mem_fun (*this, &Editor::break_drag));
+ ActionManager::register_action (editor_actions, "escape", _("Break drag or deselect all"), sigc::mem_fun (*this, &Editor::escape));
act = ActionManager::register_toggle_action (editor_actions, "show-editor-mixer", _("Show Editor Mixer"), sigc::mem_fun (*this, &Editor::editor_mixer_button_toggled));
ActionManager::session_sensitive_actions.push_back (act);
diff --git a/gtk2_ardour/editor_drag.cc b/gtk2_ardour/editor_drag.cc
index 86fbe134bb..858c6d6b99 100644
--- a/gtk2_ardour/editor_drag.cc
+++ b/gtk2_ardour/editor_drag.cc
@@ -58,6 +58,7 @@ Drag::Drag (Editor* e, ArdourCanvas::Item* i)
, _item (i)
, _pointer_frame_offset (0)
, _have_transaction (false)
+ , _ending (false)
, _move_threshold_passed (false)
, _grab_frame (0)
, _last_pointer_frame (0)
@@ -110,10 +111,6 @@ Drag::start_grab (GdkEvent* event, Gdk::Cursor *cursor)
_last_pointer_x = _current_pointer_x;
_last_pointer_y = _current_pointer_y;
- _original_x = 0;
- _original_y = 0;
- _item->i2w (_original_x, _original_y);
-
_item->grab (Gdk::POINTER_MOTION_MASK|Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK,
*cursor,
event->button.time);
@@ -222,24 +219,21 @@ Drag::motion_handler (GdkEvent* event, bool from_autoscroll)
return false;
}
-
void
Drag::break_drag ()
{
- _editor->stop_canvas_autoscroll ();
- _editor->hide_verbose_canvas_cursor ();
-
+ _ending = true;
+
if (_item) {
_item->ungrab (0);
+ }
- /* put it back where it came from */
+ aborted ();
- double cxw, cyw;
- cxw = 0;
- cyw = 0;
- _item->i2w (cxw, cyw);
- _item->move (_original_x - cxw, _original_y - cyw);
- }
+ _editor->stop_canvas_autoscroll ();
+ _editor->hide_verbose_canvas_cursor ();
+
+ _ending = false;
}
pair<nframes64_t, nframes64_t>
@@ -260,7 +254,9 @@ RegionDrag::RegionDrag (Editor* e, ArdourCanvas::Item* i, RegionView* p, list<Re
void
RegionDrag::region_going_away (RegionView* v)
{
- _views.remove (v);
+ if (!ending ()) {
+ _views.remove (v);
+ }
}
pair<nframes64_t, nframes64_t>
@@ -275,7 +271,8 @@ RegionMotionDrag::RegionMotionDrag (Editor* e, ArdourCanvas::Item* i, RegionView
: RegionDrag (e, i, p, v),
_dest_trackview (0),
_dest_layer (0),
- _brushing (b)
+ _brushing (b),
+ _total_x_delta (0)
{
}
@@ -709,6 +706,8 @@ RegionMotionDrag::motion (GdkEvent* event, bool first_move)
} /* foreach region */
+ _total_x_delta += x_delta;
+
if (first_move) {
_editor->cursor_group->raise_to_top();
}
@@ -990,6 +989,40 @@ RegionMoveDrag::finished (GdkEvent* /*event*/, bool movement_occurred)
}
}
+void
+RegionMoveDrag::aborted ()
+{
+ if (_copy) {
+
+ for (list<RegionView*>::const_iterator i = _views.begin(); i != _views.end(); ++i) {
+ delete *i;
+ }
+
+ _views.clear ();
+
+ } else {
+ RegionMotionDrag::aborted ();
+ }
+}
+
+void
+RegionMotionDrag::aborted ()
+{
+ for (list<RegionView*>::const_iterator i = _views.begin(); i != _views.end(); ++i) {
+ TimeAxisView* tv = &(*i)->get_time_axis_view ();
+ RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*> (tv);
+ assert (rtv);
+ (*i)->get_canvas_group()->reparent (*rtv->view()->canvas_item());
+ (*i)->get_canvas_group()->property_y() = 0;
+ (*i)->get_time_axis_view().reveal_dependent_views (**i);
+ (*i)->fake_set_opaque (false);
+ (*i)->move (-_total_x_delta, 0);
+ (*i)->set_height (rtv->view()->child_height ());
+ }
+
+ _editor->update_canvas_now ();
+}
+
bool
RegionMotionDrag::x_move_allowed () const
@@ -1060,7 +1093,7 @@ RegionMotionDrag::copy_regions (GdkEvent* event)
without it, the canvas seems to
"forget" to update properly after the upcoming reparent()
..only if the mouse is in rapid motion at the time of the grab.
- something to do with regionview creation raking so long?
+ something to do with regionview creation taking so long?
*/
_editor->update_canvas_now();
}
@@ -1273,6 +1306,12 @@ RegionInsertDrag::finished (GdkEvent* /*event*/, bool /*movement_occurred*/)
_views.clear ();
}
+void
+RegionInsertDrag::aborted ()
+{
+ /* XXX: TODO */
+}
+
RegionSpliceDrag::RegionSpliceDrag (Editor* e, ArdourCanvas::Item* i, RegionView* p, list<RegionView*> const & v)
: RegionMoveDrag (e, i, p, v, false, false)
{
@@ -1349,6 +1388,11 @@ RegionSpliceDrag::finished (GdkEvent* /*event*/, bool)
}
+void
+RegionSpliceDrag::aborted ()
+{
+ /* XXX: TODO */
+}
RegionCreateDrag::RegionCreateDrag (Editor* e, ArdourCanvas::Item* i, TimeAxisView* v)
: Drag (e, i),
@@ -1393,6 +1437,12 @@ RegionCreateDrag::finished (GdkEvent* event, bool movement_occurred)
}
}
+void
+RegionCreateDrag::aborted ()
+{
+ /* XXX: TODO */
+}
+
NoteResizeDrag::NoteResizeDrag (Editor* e, ArdourCanvas::Item* i)
: Drag (e, i)
, region (0)
@@ -1466,6 +1516,12 @@ NoteResizeDrag::finished (GdkEvent*, bool /*movement_occurred*/)
}
void
+NoteResizeDrag::aborted ()
+{
+ /* XXX: TODO */
+}
+
+void
RegionGainDrag::motion (GdkEvent* /*event*/, bool)
{
@@ -1477,6 +1533,12 @@ RegionGainDrag::finished (GdkEvent *, bool)
}
+void
+RegionGainDrag::aborted ()
+{
+ /* XXX: TODO */
+}
+
TrimDrag::TrimDrag (Editor* e, ArdourCanvas::Item* i, RegionView* p, list<RegionView*> const & v)
: RegionDrag (e, i, p, v)
{
@@ -1535,7 +1597,7 @@ TrimDrag::motion (GdkEvent* event, bool first_move)
nframes64_t frame_delta = 0;
bool left_direction;
- bool obey_snap = !Keyboard::modifier_state_contains (event->button.state, Keyboard::snap_modifier());
+ bool obey_snap = event ? !Keyboard::modifier_state_contains (event->button.state, Keyboard::snap_modifier()) : false;
/* snap modifier works differently here..
its current state has to be passed to the
@@ -1613,7 +1675,7 @@ TrimDrag::motion (GdkEvent* event, bool first_move)
bool non_overlap_trim = false;
- if (Keyboard::modifier_state_equals (event->button.state, Keyboard::TertiaryModifier)) {
+ if (event && Keyboard::modifier_state_equals (event->button.state, Keyboard::TertiaryModifier)) {
non_overlap_trim = true;
}
@@ -1644,7 +1706,7 @@ TrimDrag::motion (GdkEvent* event, bool first_move)
{
bool swap_direction = false;
- if (Keyboard::modifier_state_equals (event->button.state, Keyboard::PrimaryModifier)) {
+ if (event && Keyboard::modifier_state_equals (event->button.state, Keyboard::PrimaryModifier)) {
swap_direction = true;
}
@@ -1703,6 +1765,21 @@ TrimDrag::finished (GdkEvent* event, bool movement_occurred)
}
}
+void
+TrimDrag::aborted ()
+{
+ /* Our motion method is changing model state, so use the Undo system
+ to cancel. Perhaps not ideal, as this will leave an Undo point
+ behind which may be slightly odd from the user's point of view.
+ */
+
+ finished (0, true);
+
+ if (_have_transaction) {
+ _editor->undo ();
+ }
+}
+
MeterMarkerDrag::MeterMarkerDrag (Editor* e, ArdourCanvas::Item* i, bool c)
: Drag (e, i),
_copy (c)
@@ -1791,6 +1868,12 @@ MeterMarkerDrag::finished (GdkEvent* event, bool movement_occurred)
}
}
+void
+MeterMarkerDrag::aborted ()
+{
+ _marker->set_position (_marker->meter().frame ());
+}
+
TempoMarkerDrag::TempoMarkerDrag (Editor* e, ArdourCanvas::Item* i, bool c)
: Drag (e, i),
_copy (c)
@@ -1881,6 +1964,11 @@ TempoMarkerDrag::finished (GdkEvent* event, bool movement_occurred)
}
}
+void
+TempoMarkerDrag::aborted ()
+{
+ _marker->set_position (_marker->tempo().frame());
+}
CursorDrag::CursorDrag (Editor* e, ArdourCanvas::Item* i, bool s)
: Drag (e, i),
@@ -1916,6 +2004,8 @@ CursorDrag::start_grab (GdkEvent* event, Gdk::Cursor* c)
}
}
+ _pointer_frame_offset = grab_frame() - _cursor->current_frame;
+
_editor->show_verbose_time_cursor (_cursor->current_frame, 10);
}
@@ -1957,6 +2047,13 @@ CursorDrag::finished (GdkEvent* event, bool movement_occurred)
}
}
+void
+CursorDrag::aborted ()
+{
+ _editor->_dragging_playhead = false;
+ _cursor->set_position (adjusted_frame (grab_frame (), 0, false));
+}
+
FadeInDrag::FadeInDrag (Editor* e, ArdourCanvas::Item* i, RegionView* p, list<RegionView*> const & v)
: RegionDrag (e, i, p, v)
{
@@ -2050,6 +2147,20 @@ FadeInDrag::finished (GdkEvent* event, bool movement_occurred)
_editor->commit_reversible_command ();
}
+void
+FadeInDrag::aborted ()
+{
+ for (RegionSelection::iterator i = _views.begin(); i != _views.end(); ++i) {
+ AudioRegionView* tmp = dynamic_cast<AudioRegionView*> (*i);
+
+ if (!tmp) {
+ continue;
+ }
+
+ tmp->reset_fade_in_shape_width (tmp->audio_region()->fade_in()->back()->when);
+ }
+}
+
FadeOutDrag::FadeOutDrag (Editor* e, ArdourCanvas::Item* i, RegionView* p, list<RegionView*> const & v)
: RegionDrag (e, i, p, v)
{
@@ -2147,6 +2258,20 @@ FadeOutDrag::finished (GdkEvent* event, bool movement_occurred)
_editor->commit_reversible_command ();
}
+void
+FadeOutDrag::aborted ()
+{
+ for (RegionSelection::iterator i = _views.begin(); i != _views.end(); ++i) {
+ AudioRegionView* tmp = dynamic_cast<AudioRegionView*> (*i);
+
+ if (!tmp) {
+ continue;
+ }
+
+ tmp->reset_fade_out_shape_width (tmp->audio_region()->fade_out()->back()->when);
+ }
+}
+
MarkerDrag::MarkerDrag (Editor* e, ArdourCanvas::Item* i)
: Drag (e, i)
{
@@ -2460,6 +2585,12 @@ MarkerDrag::finished (GdkEvent* event, bool movement_occurred)
}
void
+MarkerDrag::aborted ()
+{
+ /* XXX: TODO */
+}
+
+void
MarkerDrag::update_item (Location* location)
{
double const x1 = _editor->frame_to_pixel (location->start());
@@ -2570,6 +2701,12 @@ ControlPointDrag::finished (GdkEvent* event, bool movement_occurred)
_point->line().end_drag ();
}
+void
+ControlPointDrag::aborted ()
+{
+ /* XXX: TODO */
+}
+
bool
ControlPointDrag::active (Editing::MouseMode m)
{
@@ -2673,6 +2810,12 @@ LineDrag::finished (GdkEvent* event, bool)
}
void
+LineDrag::aborted ()
+{
+ /* XXX: TODO */
+}
+
+void
RubberbandSelectDrag::start_grab (GdkEvent* event, Gdk::Cursor *)
{
Drag::start_grab (event);
@@ -2781,6 +2924,12 @@ RubberbandSelectDrag::finished (GdkEvent* event, bool movement_occurred)
}
void
+RubberbandSelectDrag::aborted ()
+{
+ /* XXX: TODO */
+}
+
+void
TimeFXDrag::start_grab (GdkEvent* event, Gdk::Cursor *)
{
Drag::start_grab (event);
@@ -2844,6 +2993,13 @@ TimeFXDrag::finished (GdkEvent* /*event*/, bool movement_occurred)
}
void
+TimeFXDrag::aborted ()
+{
+ /* XXX: TODO */
+}
+
+
+void
ScrubDrag::start_grab (GdkEvent* event, Gdk::Cursor *)
{
Drag::start_grab (event);
@@ -2864,6 +3020,12 @@ ScrubDrag::finished (GdkEvent* /*event*/, bool movement_occurred)
}
}
+void
+ScrubDrag::aborted ()
+{
+ /* XXX: TODO */
+}
+
SelectionDrag::SelectionDrag (Editor* e, ArdourCanvas::Item* i, Operation o)
: Drag (e, i)
, _operation (o)
@@ -3135,6 +3297,12 @@ SelectionDrag::finished (GdkEvent* event, bool movement_occurred)
_editor->stop_canvas_autoscroll ();
}
+void
+SelectionDrag::aborted ()
+{
+ /* XXX: TODO */
+}
+
RangeMarkerBarDrag::RangeMarkerBarDrag (Editor* e, ArdourCanvas::Item* i, Operation o)
: Drag (e, i),
_operation (o),
@@ -3337,7 +3505,11 @@ RangeMarkerBarDrag::finished (GdkEvent* event, bool movement_occurred)
_editor->stop_canvas_autoscroll ();
}
-
+void
+RangeMarkerBarDrag::aborted ()
+{
+ /* XXX: TODO */
+}
void
RangeMarkerBarDrag::update_item (Location* location)
@@ -3415,6 +3587,12 @@ MouseZoomDrag::finished (GdkEvent* event, bool movement_occurred)
_editor->zoom_rect->hide();
}
+void
+MouseZoomDrag::aborted ()
+{
+ /* XXX: TODO */
+}
+
NoteDrag::NoteDrag (Editor* e, ArdourCanvas::Item* i)
: Drag (e, i)
{
@@ -3542,6 +3720,12 @@ NoteDrag::finished (GdkEvent* ev, bool moved)
}
}
+void
+NoteDrag::aborted ()
+{
+ /* XXX: TODO */
+}
+
AutomationRangeDrag::AutomationRangeDrag (Editor* e, ArdourCanvas::Item* i, list<AudioRange> const & r)
: Drag (e, i)
, _ranges (r)
@@ -3645,3 +3829,9 @@ AutomationRangeDrag::finished (GdkEvent* event, bool)
_line->end_drag ();
_line->clear_always_in_view ();
}
+
+void
+AutomationRangeDrag::aborted ()
+{
+ /* XXX: TODO */
+}
diff --git a/gtk2_ardour/editor_drag.h b/gtk2_ardour/editor_drag.h
index 941833d0c0..16ef6c4678 100644
--- a/gtk2_ardour/editor_drag.h
+++ b/gtk2_ardour/editor_drag.h
@@ -52,9 +52,8 @@ public:
}
void swap_grab (ArdourCanvas::Item *, Gdk::Cursor *, uint32_t);
- void break_drag ();
-
bool motion_handler (GdkEvent*, bool);
+ void break_drag ();
/** @return true if an end drag is in progress */
bool ending () const {
@@ -94,6 +93,11 @@ public:
*/
virtual void finished (GdkEvent* e, bool m) = 0;
+ /** Called to abort a drag and return things to how
+ * they were before it started.
+ */
+ virtual void aborted () = 0;
+
/** @param m Mouse mode.
* @return true if this drag should happen in this mouse mode.
*/
@@ -162,10 +166,8 @@ protected:
private:
- bool _ending; ///< true if end_grab is in progress, otherwise false
+ bool _ending; ///< true if end_grab or break_drag is in progress, otherwise false
bool _move_threshold_passed; ///< true if the move threshold has been passed, otherwise false
- double _original_x; ///< original world x of the thing being dragged
- double _original_y; ///< original world y of the thing being dragged
double _grab_x; ///< trackview x of the grab start position
double _grab_y; ///< trackview y of the grab start position
double _current_pointer_x; ///< trackview x of the current pointer
@@ -209,6 +211,7 @@ public:
virtual void start_grab (GdkEvent *, Gdk::Cursor *);
virtual void motion (GdkEvent *, bool);
virtual void finished (GdkEvent *, bool) = 0;
+ virtual void aborted ();
protected:
struct TimeAxisViewSummary {
@@ -237,6 +240,7 @@ protected:
bool check_possible (RouteTimeAxisView **, ARDOUR::layer_t *);
bool _brushing;
nframes64_t _last_frame_position; ///< last position of the thing being dragged
+ double _total_x_delta;
};
@@ -252,6 +256,7 @@ public:
virtual void start_grab (GdkEvent *, Gdk::Cursor *);
void motion (GdkEvent *, bool);
void finished (GdkEvent *, bool);
+ void aborted ();
std::pair<nframes64_t, int> move_threshold () const {
return std::make_pair (4, 4);
@@ -268,6 +273,7 @@ public:
RegionInsertDrag (Editor *, boost::shared_ptr<ARDOUR::Region>, RouteTimeAxisView*, nframes64_t);
void finished (GdkEvent *, bool);
+ void aborted ();
};
/** Region drag in splice mode */
@@ -278,6 +284,7 @@ public:
void motion (GdkEvent *, bool);
void finished (GdkEvent *, bool);
+ void aborted ();
};
/** Drags to create regions */
@@ -289,6 +296,7 @@ public:
void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
void motion (GdkEvent *, bool);
void finished (GdkEvent *, bool);
+ void aborted ();
private:
TimeAxisView* _view;
@@ -304,6 +312,7 @@ public:
void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
void motion (GdkEvent *, bool);
void finished (GdkEvent *, bool);
+ void aborted ();
private:
MidiRegionView* region;
@@ -319,6 +328,7 @@ class NoteDrag : public Drag
void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
void motion (GdkEvent *, bool);
void finished (GdkEvent *, bool);
+ void aborted ();
private:
MidiRegionView* region;
@@ -340,6 +350,8 @@ public:
bool active (Editing::MouseMode m) {
return (m == Editing::MouseGain);
}
+
+ void aborted ();
};
/** Drag to trim region(s) */
@@ -357,6 +369,7 @@ public:
void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
void motion (GdkEvent *, bool);
void finished (GdkEvent *, bool);
+ void aborted ();
bool y_movement_matters () const {
return false;
@@ -376,6 +389,7 @@ public:
void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
void motion (GdkEvent *, bool);
void finished (GdkEvent *, bool);
+ void aborted ();
bool allow_vertical_autoscroll () const {
return false;
@@ -399,6 +413,7 @@ public:
void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
void motion (GdkEvent *, bool);
void finished (GdkEvent *, bool);
+ void aborted ();
bool allow_vertical_autoscroll () const {
return false;
@@ -423,6 +438,7 @@ public:
void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
void motion (GdkEvent *, bool);
void finished (GdkEvent *, bool);
+ void aborted ();
bool active (Editing::MouseMode) {
return true;
@@ -451,6 +467,7 @@ public:
void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
void motion (GdkEvent *, bool);
void finished (GdkEvent *, bool);
+ void aborted ();
bool y_movement_matters () const {
return false;
@@ -466,6 +483,7 @@ public:
void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
void motion (GdkEvent *, bool);
void finished (GdkEvent *, bool);
+ void aborted ();
bool y_movement_matters () const {
return false;
@@ -482,6 +500,7 @@ public:
void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
void motion (GdkEvent *, bool);
void finished (GdkEvent *, bool);
+ void aborted ();
bool allow_vertical_autoscroll () const {
return false;
@@ -509,6 +528,7 @@ public:
void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
void motion (GdkEvent *, bool);
void finished (GdkEvent *, bool);
+ void aborted ();
bool active (Editing::MouseMode m);
@@ -531,6 +551,7 @@ public:
void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
void motion (GdkEvent *, bool);
void finished (GdkEvent *, bool);
+ void aborted ();
bool active (Editing::MouseMode) {
return true;
@@ -555,6 +576,7 @@ public:
void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
void motion (GdkEvent *, bool);
void finished (GdkEvent *, bool);
+ void aborted ();
};
/** Region drag in time-FX mode */
@@ -566,6 +588,7 @@ public:
void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
void motion (GdkEvent *, bool);
void finished (GdkEvent *, bool);
+ void aborted ();
};
/** Scrub drag in audition mode */
@@ -577,6 +600,7 @@ public:
void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
void motion (GdkEvent *, bool);
void finished (GdkEvent *, bool);
+ void aborted ();
};
/** Drag in range select mode */
@@ -595,6 +619,7 @@ public:
void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
void motion (GdkEvent *, bool);
void finished (GdkEvent *, bool);
+ void aborted ();
private:
Operation _operation;
@@ -619,6 +644,7 @@ public:
void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
void motion (GdkEvent *, bool);
void finished (GdkEvent *, bool);
+ void aborted ();
bool allow_vertical_autoscroll () const {
return false;
@@ -645,6 +671,7 @@ public:
void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
void motion (GdkEvent *, bool);
void finished (GdkEvent *, bool);
+ void aborted ();
};
/** Drag of a range of automation data, changing value but not position */
@@ -656,6 +683,7 @@ public:
void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
void motion (GdkEvent *, bool);
void finished (GdkEvent *, bool);
+ void aborted ();
bool x_movement_matters () const {
return false;
diff --git a/gtk2_ardour/editor_mouse.cc b/gtk2_ardour/editor_mouse.cc
index cb9926d3a4..c0beab03aa 100644
--- a/gtk2_ardour/editor_mouse.cc
+++ b/gtk2_ardour/editor_mouse.cc
@@ -2639,10 +2639,22 @@ Editor::start_selection_grab (ArdourCanvas::Item* /*item*/, GdkEvent* event)
}
void
+Editor::escape ()
+{
+ if (_drag) {
+ break_drag ();
+ } else {
+ selection->clear ();
+ }
+}
+
+void
Editor::break_drag ()
{
if (_drag) {
_drag->break_drag ();
+ delete _drag;
+ _drag = 0;
}
}
diff --git a/gtk2_ardour/mnemonic-us.bindings.in b/gtk2_ardour/mnemonic-us.bindings.in
index 11af889c3b..8f6b1e46d2 100644
--- a/gtk2_ardour/mnemonic-us.bindings.in
+++ b/gtk2_ardour/mnemonic-us.bindings.in
@@ -247,6 +247,8 @@ This mode provides many different operations on both regions and control points,
@eep|Editor/edit-to-playhead|<@SECONDARY@>Return|move EP to playhead
@trans|Editor/remove-last-capture|<@PRIMARY@>Delete|destroy last recording
+@-group|Editor/escape|Escape|break drag or deselect all
+
;; keypad
@rop|Editor/nudge-backward|KP_Subtract|nudge backward
diff --git a/gtk2_ardour/time_axis_view_item.cc b/gtk2_ardour/time_axis_view_item.cc
index 19b599215b..3ecb152fea 100644
--- a/gtk2_ardour/time_axis_view_item.cc
+++ b/gtk2_ardour/time_axis_view_item.cc
@@ -115,6 +115,7 @@ TimeAxisViewItem::TimeAxisViewItem (const TimeAxisViewItem& other)
: sigc::trackable(other)
, PBD::ScopedConnectionList()
, trackview (other.trackview)
+ , _recregion (other._recregion)
{
Gdk::Color c;