Make a new action "escape", bound to the Escape key, and make it
authorCarl Hetherington <carl@carlh.net>
Fri, 8 Jan 2010 01:28:15 +0000 (01:28 +0000)
committerCarl Hetherington <carl@carlh.net>
Fri, 8 Jan 2010 01:28:15 +0000 (01:28 +0000)
abort a drag (if one is in progress) or clear the selection.
Fix breaking of drags in a few cases; some still to do.

git-svn-id: svn://localhost/ardour2/branches/3.0@6467 d708f5d6-7413-0410-9779-e7cbd77b26cf

gtk2_ardour/ardour.menus.in
gtk2_ardour/editor.cc
gtk2_ardour/editor.h
gtk2_ardour/editor_actions.cc
gtk2_ardour/editor_drag.cc
gtk2_ardour/editor_drag.h
gtk2_ardour/editor_mouse.cc
gtk2_ardour/mnemonic-us.bindings.in
gtk2_ardour/time_axis_view_item.cc

index f4995411e761617f1c6d13602b94cfe5736ddf91..d5bb7b797cf4b7a59d1ab59eb2f7dd845b5aa908 100644 (file)
                   <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'/>
index 5c5d3abad971c2ce54a6ce8d03ab16e6f04da2fc..16153908e21c479c08b178ca07d2d7746207ee4b 100644 (file)
@@ -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);
        }
 
index 6227afa8052166255a982b57eece611df752d4d1..74f3ab04489b73c1bae4c308d8b4fa15319dfea6 100644 (file)
@@ -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);
index 99177601f6a4929ab9df497d5708ae15517bd497..4193e74d7476116de8ecaf1a8e7124508dfd27f5 100644 (file)
@@ -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);
index 86fbe134bb141571c934f57c668318f56eb88174..858c6d6b99581deacb52048236a72b89eac1e952 100644 (file)
@@ -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)
@@ -1465,6 +1515,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)
 {
@@ -2459,6 +2584,12 @@ MarkerDrag::finished (GdkEvent* event, bool movement_occurred)
        _line->hide();
 }
 
+void
+MarkerDrag::aborted ()
+{
+       /* XXX: TODO */
+}
+
 void
 MarkerDrag::update_item (Location* location)
 {
@@ -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)
 {
@@ -2672,6 +2809,12 @@ LineDrag::finished (GdkEvent* event, bool)
        _line->end_drag ();
 }
 
+void
+LineDrag::aborted ()
+{
+       /* XXX: TODO */
+}
+
 void
 RubberbandSelectDrag::start_grab (GdkEvent* event, Gdk::Cursor *)
 {
@@ -2780,6 +2923,12 @@ RubberbandSelectDrag::finished (GdkEvent* event, bool movement_occurred)
        _editor->rubberband_rect->hide();
 }
 
+void
+RubberbandSelectDrag::aborted ()
+{
+       /* XXX: TODO */
+}
+
 void
 TimeFXDrag::start_grab (GdkEvent* event, Gdk::Cursor *)
 {
@@ -2843,6 +2992,13 @@ TimeFXDrag::finished (GdkEvent* /*event*/, bool movement_occurred)
        }
 }
 
+void
+TimeFXDrag::aborted ()
+{
+       /* XXX: TODO */
+}
+
+
 void
 ScrubDrag::start_grab (GdkEvent* event, Gdk::Cursor *)
 {
@@ -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 */
+}
index 941833d0c06a582bb02bb7ded5a0916186d8867a..16ef6c4678781498e058358cf262f897fae20231 100644 (file)
@@ -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;
index cb9926d3a49cf7adff72e64b94532920d0e54cb4..c0beab03aa3d68fbd85baacfa0e4e995bf91f88d 100644 (file)
@@ -2638,11 +2638,23 @@ Editor::start_selection_grab (ArdourCanvas::Item* /*item*/, GdkEvent* event)
        _drag->start_grab (event);
 }
 
+void
+Editor::escape ()
+{
+       if (_drag) {
+               break_drag ();
+       } else {
+               selection->clear ();
+       }
+}
+
 void
 Editor::break_drag ()
 {
        if (_drag) {
                _drag->break_drag ();
+               delete _drag;
+               _drag = 0;
        }
 }
 
index 11af889c3b52e1db7f03f1ac1e62b11e7dc7af59..8f6b1e46d2e0984f6a88f3c54884087d5ac28b0d 100644 (file)
@@ -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
index 19b599215bb37bbd53a0d2350b7dc8bf5340f1db..3ecb152fea47604bb7e8a946bdab456ba67805e0 100644 (file)
@@ -115,6 +115,7 @@ TimeAxisViewItem::TimeAxisViewItem (const TimeAxisViewItem& other)
        : sigc::trackable(other)
        , PBD::ScopedConnectionList()
        , trackview (other.trackview)
+       , _recregion (other._recregion)
 {
 
        Gdk::Color c;