From 14e32ba0758c776b2660f8b86a9192cddaa3de99 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 5 Jan 2010 01:10:53 +0000 Subject: [PATCH] Fix various confusions about move threshold when snapping. Fixes non-appearing range rectangles when defining ranges with snap enabled. git-svn-id: svn://localhost/ardour2/branches/3.0@6449 d708f5d6-7413-0410-9779-e7cbd77b26cf --- gtk2_ardour/editor_drag.cc | 42 ++++++++++++------------- gtk2_ardour/editor_drag.h | 64 ++++++++++++++++++++++++++++++++------ 2 files changed, 75 insertions(+), 31 deletions(-) diff --git a/gtk2_ardour/editor_drag.cc b/gtk2_ardour/editor_drag.cc index ca2468cd2c..d3ada92ff7 100644 --- a/gtk2_ardour/editor_drag.cc +++ b/gtk2_ardour/editor_drag.cc @@ -58,7 +58,6 @@ Drag::Drag (Editor* e, ArdourCanvas::Item* i) , _item (i) , _pointer_frame_offset (0) , _have_transaction (false) - , _had_movement (false) , _move_threshold_passed (false) , _grab_frame (0) , _last_pointer_frame (0) @@ -103,6 +102,7 @@ Drag::start_grab (GdkEvent* event, Gdk::Cursor *cursor) } _grab_frame = _editor->event_frame (event, &_grab_x, &_grab_y); + _grab_frame = adjusted_frame (_grab_frame, event); _last_pointer_frame = _grab_frame; _current_pointer_frame = _grab_frame; _current_pointer_x = _grab_x; @@ -150,22 +150,22 @@ Drag::end_grab (GdkEvent* event) _last_pointer_x = _current_pointer_x; _last_pointer_y = _current_pointer_y; - finished (event, _had_movement); + finished (event, _move_threshold_passed); _editor->hide_verbose_canvas_cursor(); _ending = false; - return _had_movement; + return _move_threshold_passed; } nframes64_t -Drag::adjusted_current_frame (GdkEvent const * event, bool snap) const +Drag::adjusted_frame (nframes64_t f, GdkEvent const * event, bool snap) const { nframes64_t pos = 0; - if (_current_pointer_frame > _pointer_frame_offset) { - pos = _current_pointer_frame - _pointer_frame_offset; + if (f > _pointer_frame_offset) { + pos = f - _pointer_frame_offset; } if (snap) { @@ -175,6 +175,12 @@ Drag::adjusted_current_frame (GdkEvent const * event, bool snap) const return pos; } +nframes64_t +Drag::adjusted_current_frame (GdkEvent const * event, bool snap) const +{ + return adjusted_frame (_current_pointer_frame, event, snap); +} + bool Drag::motion_handler (GdkEvent* event, bool from_autoscroll) { @@ -183,32 +189,26 @@ Drag::motion_handler (GdkEvent* event, bool from_autoscroll) _last_pointer_frame = adjusted_current_frame (event); _current_pointer_frame = _editor->event_frame (event, &_current_pointer_x, &_current_pointer_y); + pair const threshold = move_threshold (); + + bool const old_move_threshold_passed = _move_threshold_passed; + if (!from_autoscroll && !_move_threshold_passed) { - bool const xp = (::llabs ((nframes64_t) (_current_pointer_x - _grab_x)) > 4LL); - bool const yp = (::llabs ((nframes64_t) (_current_pointer_y - _grab_y)) > 4LL); + bool const xp = (::llabs (adjusted_current_frame (event) - _grab_frame) >= threshold.first); + bool const yp = (::fabs ((_current_pointer_y - _grab_y)) >= threshold.second); - _move_threshold_passed = (xp || yp); + _move_threshold_passed = ((xp && x_movement_matters()) || (yp && y_movement_matters())); } - bool old_had_movement = _had_movement; - - /* a motion event has happened, so we've had movement... */ - _had_movement = true; - - /* ... unless we're using a move threshold and we've not yet passed it */ - if (apply_move_threshold() && !_move_threshold_passed) { - _had_movement = false; - } - - if (active (_editor->mouse_mode) && _had_movement) { + if (active (_editor->mouse_mode) && _move_threshold_passed) { if (event->motion.state & Gdk::BUTTON1_MASK || event->motion.state & Gdk::BUTTON2_MASK) { if (!from_autoscroll) { _editor->maybe_autoscroll (&event->motion, allow_vertical_autoscroll ()); } - motion (event, _had_movement != old_had_movement); + motion (event, _move_threshold_passed != old_move_threshold_passed); return true; } } diff --git a/gtk2_ardour/editor_drag.h b/gtk2_ardour/editor_drag.h index 9d7215d93f..5d8cf39090 100644 --- a/gtk2_ardour/editor_drag.h +++ b/gtk2_ardour/editor_drag.h @@ -71,6 +71,7 @@ public: return _current_pointer_y; } + nframes64_t adjusted_frame (nframes64_t, GdkEvent const *, bool snap = true) const; nframes64_t adjusted_current_frame (GdkEvent const *, bool snap = true) const; /** Called to start a grab of an item. @@ -100,17 +101,25 @@ public: return (m != Editing::MouseGain); } - /** @return true if a small threshold should be applied before a mouse movement - * is considered a drag, otherwise false. - */ - virtual bool apply_move_threshold () const { - return false; + /** @return minimum number of frames (in x) and pixels (in y) that should be considered a movement */ + virtual std::pair move_threshold () const { + return std::make_pair (1, 1); } virtual bool allow_vertical_autoscroll () const { return true; } + /** @return true if x movement matters to this drag */ + virtual bool x_movement_matters () const { + return true; + } + + /** @return true if y movement matters to this drag */ + virtual bool y_movement_matters () const { + return true; + } + protected: double grab_x () const { @@ -149,7 +158,6 @@ protected: private: bool _ending; ///< true if end_grab is in progress, otherwise false - bool _had_movement; ///< true if movement has occurred, 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 @@ -159,8 +167,8 @@ private: double _current_pointer_y; ///< trackview y of the current pointer double _last_pointer_x; ///< trackview x of the pointer last time a motion occurred double _last_pointer_y; ///< trackview y of the pointer last time a motion occurred - nframes64_t _grab_frame; ///< frame that the mouse was at when start_grab was called, or 0 - nframes64_t _last_pointer_frame; ///< adjusted_current_frame the last time a motion occurred + nframes64_t _grab_frame; ///< adjusted_frame that the mouse was at when start_grab was called, or 0 + nframes64_t _last_pointer_frame; ///< adjusted_frame the last time a motion occurred nframes64_t _current_pointer_frame; ///< frame that the pointer is now at }; @@ -238,8 +246,8 @@ public: void motion (GdkEvent *, bool); void finished (GdkEvent *, bool); - bool apply_move_threshold () const { - return true; + std::pair move_threshold () const { + return std::make_pair (4, 4); } private: @@ -343,6 +351,10 @@ public: void motion (GdkEvent *, bool); void finished (GdkEvent *, bool); + bool y_movement_matters () const { + return false; + } + private: Operation _operation; @@ -361,6 +373,10 @@ public: bool allow_vertical_autoscroll () const { return false; } + + bool y_movement_matters () const { + return false; + } private: MeterMarker* _marker; @@ -381,6 +397,10 @@ public: return false; } + bool y_movement_matters () const { + return false; + } + private: TempoMarker* _marker; bool _copy; @@ -405,6 +425,10 @@ public: return false; } + bool y_movement_matters () const { + return false; + } + private: EditorCursor* _cursor; ///< cursor being dragged bool _stop; ///< true to stop the transport on starting the drag, otherwise false @@ -420,6 +444,10 @@ public: void start_grab (GdkEvent *, Gdk::Cursor* c = 0); void motion (GdkEvent *, bool); void finished (GdkEvent *, bool); + + bool y_movement_matters () const { + return false; + } }; /** Region fade-out drag */ @@ -431,6 +459,10 @@ public: void start_grab (GdkEvent *, Gdk::Cursor* c = 0); void motion (GdkEvent *, bool); void finished (GdkEvent *, bool); + + bool y_movement_matters () const { + return false; + } }; /** Marker drag */ @@ -447,6 +479,10 @@ public: bool allow_vertical_autoscroll () const { return false; } + + bool y_movement_matters () const { + return false; + } private: void update_item (ARDOUR::Location *); @@ -577,6 +613,10 @@ public: void motion (GdkEvent *, bool); void finished (GdkEvent *, bool); + bool y_movement_matters () const { + return false; + } + private: void update_item (ARDOUR::Location *); @@ -606,6 +646,10 @@ public: void motion (GdkEvent *, bool); void finished (GdkEvent *, bool); + bool x_movement_matters () const { + return false; + } + private: std::list _ranges; AutomationTimeAxisView* _atav;