<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'/>
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);
}
Drag* _drag;
void break_drag ();
+ void escape ();
Gtk::Menu fade_context_menu;
void popup_fade_context_menu (int, int, ArdourCanvas::Item*, ItemType);
/* 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);
, _item (i)
, _pointer_frame_offset (0)
, _have_transaction (false)
+ , _ending (false)
, _move_threshold_passed (false)
, _grab_frame (0)
, _last_pointer_frame (0)
_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);
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>
void
RegionDrag::region_going_away (RegionView* v)
{
- _views.remove (v);
+ if (!ending ()) {
+ _views.remove (v);
+ }
}
pair<nframes64_t, nframes64_t>
: RegionDrag (e, i, p, v),
_dest_trackview (0),
_dest_layer (0),
- _brushing (b)
+ _brushing (b),
+ _total_x_delta (0)
{
}
} /* foreach region */
+ _total_x_delta += x_delta;
+
if (first_move) {
_editor->cursor_group->raise_to_top();
}
}
}
+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
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();
}
_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)
{
}
+void
+RegionSpliceDrag::aborted ()
+{
+ /* XXX: TODO */
+}
RegionCreateDrag::RegionCreateDrag (Editor* e, ArdourCanvas::Item* i, TimeAxisView* v)
: Drag (e, i),
}
}
+void
+RegionCreateDrag::aborted ()
+{
+ /* XXX: TODO */
+}
+
NoteResizeDrag::NoteResizeDrag (Editor* e, ArdourCanvas::Item* i)
: Drag (e, i)
, region (0)
}
}
+void
+NoteResizeDrag::aborted ()
+{
+ /* XXX: TODO */
+}
+
void
RegionGainDrag::motion (GdkEvent* /*event*/, bool)
{
}
+void
+RegionGainDrag::aborted ()
+{
+ /* XXX: TODO */
+}
+
TrimDrag::TrimDrag (Editor* e, ArdourCanvas::Item* i, RegionView* p, list<RegionView*> const & v)
: RegionDrag (e, i, p, v)
{
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
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;
}
{
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;
}
}
}
+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)
}
}
+void
+MeterMarkerDrag::aborted ()
+{
+ _marker->set_position (_marker->meter().frame ());
+}
+
TempoMarkerDrag::TempoMarkerDrag (Editor* e, ArdourCanvas::Item* i, bool c)
: Drag (e, i),
_copy (c)
}
}
+void
+TempoMarkerDrag::aborted ()
+{
+ _marker->set_position (_marker->tempo().frame());
+}
CursorDrag::CursorDrag (Editor* e, ArdourCanvas::Item* i, bool s)
: Drag (e, i),
}
}
+ _pointer_frame_offset = grab_frame() - _cursor->current_frame;
+
_editor->show_verbose_time_cursor (_cursor->current_frame, 10);
}
}
}
+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)
{
_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)
{
_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)
{
_line->hide();
}
+void
+MarkerDrag::aborted ()
+{
+ /* XXX: TODO */
+}
+
void
MarkerDrag::update_item (Location* location)
{
_point->line().end_drag ();
}
+void
+ControlPointDrag::aborted ()
+{
+ /* XXX: TODO */
+}
+
bool
ControlPointDrag::active (Editing::MouseMode m)
{
_line->end_drag ();
}
+void
+LineDrag::aborted ()
+{
+ /* XXX: TODO */
+}
+
void
RubberbandSelectDrag::start_grab (GdkEvent* event, Gdk::Cursor *)
{
_editor->rubberband_rect->hide();
}
+void
+RubberbandSelectDrag::aborted ()
+{
+ /* XXX: TODO */
+}
+
void
TimeFXDrag::start_grab (GdkEvent* event, Gdk::Cursor *)
{
}
}
+void
+TimeFXDrag::aborted ()
+{
+ /* XXX: TODO */
+}
+
+
void
ScrubDrag::start_grab (GdkEvent* event, Gdk::Cursor *)
{
}
}
+void
+ScrubDrag::aborted ()
+{
+ /* XXX: TODO */
+}
+
SelectionDrag::SelectionDrag (Editor* e, ArdourCanvas::Item* i, Operation o)
: Drag (e, i)
, _operation (o)
_editor->stop_canvas_autoscroll ();
}
+void
+SelectionDrag::aborted ()
+{
+ /* XXX: TODO */
+}
+
RangeMarkerBarDrag::RangeMarkerBarDrag (Editor* e, ArdourCanvas::Item* i, Operation o)
: Drag (e, i),
_operation (o),
_editor->stop_canvas_autoscroll ();
}
-
+void
+RangeMarkerBarDrag::aborted ()
+{
+ /* XXX: TODO */
+}
void
RangeMarkerBarDrag::update_item (Location* location)
_editor->zoom_rect->hide();
}
+void
+MouseZoomDrag::aborted ()
+{
+ /* XXX: TODO */
+}
+
NoteDrag::NoteDrag (Editor* e, ArdourCanvas::Item* i)
: Drag (e, i)
{
}
}
+void
+NoteDrag::aborted ()
+{
+ /* XXX: TODO */
+}
+
AutomationRangeDrag::AutomationRangeDrag (Editor* e, ArdourCanvas::Item* i, list<AudioRange> const & r)
: Drag (e, i)
, _ranges (r)
_line->end_drag ();
_line->clear_always_in_view ();
}
+
+void
+AutomationRangeDrag::aborted ()
+{
+ /* XXX: TODO */
+}
}
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 {
*/
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.
*/
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
virtual void start_grab (GdkEvent *, Gdk::Cursor *);
virtual void motion (GdkEvent *, bool);
virtual void finished (GdkEvent *, bool) = 0;
+ virtual void aborted ();
protected:
struct TimeAxisViewSummary {
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;
};
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);
RegionInsertDrag (Editor *, boost::shared_ptr<ARDOUR::Region>, RouteTimeAxisView*, nframes64_t);
void finished (GdkEvent *, bool);
+ void aborted ();
};
/** Region drag in splice mode */
void motion (GdkEvent *, bool);
void finished (GdkEvent *, bool);
+ void aborted ();
};
/** Drags to create regions */
void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
void motion (GdkEvent *, bool);
void finished (GdkEvent *, bool);
+ void aborted ();
private:
TimeAxisView* _view;
void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
void motion (GdkEvent *, bool);
void finished (GdkEvent *, bool);
+ void aborted ();
private:
MidiRegionView* region;
void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
void motion (GdkEvent *, bool);
void finished (GdkEvent *, bool);
+ void aborted ();
private:
MidiRegionView* region;
bool active (Editing::MouseMode m) {
return (m == Editing::MouseGain);
}
+
+ void aborted ();
};
/** Drag to trim region(s) */
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;
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;
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;
void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
void motion (GdkEvent *, bool);
void finished (GdkEvent *, bool);
+ void aborted ();
bool active (Editing::MouseMode) {
return true;
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;
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;
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;
void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
void motion (GdkEvent *, bool);
void finished (GdkEvent *, bool);
+ void aborted ();
bool active (Editing::MouseMode m);
void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
void motion (GdkEvent *, bool);
void finished (GdkEvent *, bool);
+ void aborted ();
bool active (Editing::MouseMode) {
return true;
void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
void motion (GdkEvent *, bool);
void finished (GdkEvent *, bool);
+ void aborted ();
};
/** Region drag in time-FX mode */
void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
void motion (GdkEvent *, bool);
void finished (GdkEvent *, bool);
+ void aborted ();
};
/** Scrub drag in audition mode */
void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
void motion (GdkEvent *, bool);
void finished (GdkEvent *, bool);
+ void aborted ();
};
/** Drag in range select mode */
void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
void motion (GdkEvent *, bool);
void finished (GdkEvent *, bool);
+ void aborted ();
private:
Operation _operation;
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;
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 */
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;
_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;
}
}
@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
: sigc::trackable(other)
, PBD::ScopedConnectionList()
, trackview (other.trackview)
+ , _recregion (other._recregion)
{
Gdk::Color c;