Fix various confusions about move threshold when snapping. Fixes non-appearing range...
authorCarl Hetherington <carl@carlh.net>
Tue, 5 Jan 2010 01:10:53 +0000 (01:10 +0000)
committerCarl Hetherington <carl@carlh.net>
Tue, 5 Jan 2010 01:10:53 +0000 (01:10 +0000)
git-svn-id: svn://localhost/ardour2/branches/3.0@6449 d708f5d6-7413-0410-9779-e7cbd77b26cf

gtk2_ardour/editor_drag.cc
gtk2_ardour/editor_drag.h

index ca2468cd2c94d7ea2e8b114e7bb105c2e4c21022..d3ada92ff71b08d95f2b357eed77928a80fa1f12 100644 (file)
@@ -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);
 
-       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);
-
-               _move_threshold_passed = (xp || yp);
-       }
+       pair<nframes64_t, int> const threshold = move_threshold ();
 
-       bool old_had_movement = _had_movement;
+       bool const old_move_threshold_passed = _move_threshold_passed;
+       
+       if (!from_autoscroll && !_move_threshold_passed) {
 
-       /* a motion event has happened, so we've had movement... */
-       _had_movement = true;
+               bool const xp = (::llabs (adjusted_current_frame (event) - _grab_frame) >= threshold.first);
+               bool const yp = (::fabs ((_current_pointer_y - _grab_y)) >= threshold.second);
 
-       /* ... unless we're using a move threshold and we've not yet passed it */
-       if (apply_move_threshold() && !_move_threshold_passed) {
-               _had_movement = false;
+               _move_threshold_passed = ((xp && x_movement_matters()) || (yp && y_movement_matters()));
        }
 
-       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;
                }
        }
index 9d7215d93f689a7b5d12834c155db06c9c918209..5d8cf390903c85eef6bdcb5f2564ce49ca358de7 100644 (file)
@@ -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<nframes64_t, int> 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<nframes64_t, int> 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<ARDOUR::AudioRange> _ranges;
        AutomationTimeAxisView* _atav;