, _item (i)
, _pointer_frame_offset (0)
, _have_transaction (false)
- , _had_movement (false)
, _move_threshold_passed (false)
, _grab_frame (0)
, _last_pointer_frame (0)
}
_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;
_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) {
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)
{
_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;
}
}
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.
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 {
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
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
};
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:
void motion (GdkEvent *, bool);
void finished (GdkEvent *, bool);
+ bool y_movement_matters () const {
+ return false;
+ }
+
private:
Operation _operation;
bool allow_vertical_autoscroll () const {
return false;
}
+
+ bool y_movement_matters () const {
+ return false;
+ }
private:
MeterMarker* _marker;
return false;
}
+ bool y_movement_matters () const {
+ return false;
+ }
+
private:
TempoMarker* _marker;
bool _copy;
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
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 */
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 */
bool allow_vertical_autoscroll () const {
return false;
}
+
+ bool y_movement_matters () const {
+ return false;
+ }
private:
void update_item (ARDOUR::Location *);
void motion (GdkEvent *, bool);
void finished (GdkEvent *, bool);
+ bool y_movement_matters () const {
+ return false;
+ }
+
private:
void update_item (ARDOUR::Location *);
void motion (GdkEvent *, bool);
void finished (GdkEvent *, bool);
+ bool x_movement_matters () const {
+ return false;
+ }
+
private:
std::list<ARDOUR::AudioRange> _ranges;
AutomationTimeAxisView* _atav;