2 Copyright (C) 2009 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 #ifndef __gtk2_ardour_editor_drag_h_
21 #define __gtk2_ardour_editor_drag_h_
28 #include "ardour/types.h"
30 #include "editor_items.h"
37 class StatefulDiffCommand;
44 class MidiTimeAxisView;
48 /** Class to manage current drags */
53 DragManager (Editor* e);
56 bool motion_handler (GdkEvent *, bool);
57 bool window_motion_handler (GdkEvent *, bool);
61 void set (Drag *, GdkEvent *, Gdk::Cursor* c = 0);
62 void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
63 bool end_grab (GdkEvent *);
64 bool have_item (ArdourCanvas::Item *) const;
66 /** @return true if an end drag or abort is in progress */
67 bool ending () const {
71 bool active () const {
72 return !_drags.empty ();
75 /** @return current pointer x position in trackview coordinates */
76 double current_pointer_x () const {
77 return _current_pointer_x;
80 /** @return current pointer y position in trackview coordinates */
81 double current_pointer_y () const {
82 return _current_pointer_y;
85 /** @return current pointer frame */
86 ARDOUR::framepos_t current_pointer_frame () const {
87 return _current_pointer_frame;
92 std::list<Drag*> _drags;
93 bool _ending; ///< true if end_grab or abort is in progress, otherwise false
94 double _current_pointer_x; ///< trackview x of the current pointer
95 double _current_pointer_y; ///< trackview y of the current pointer
96 ARDOUR::framepos_t _current_pointer_frame; ///< frame that the pointer is now at
97 bool _old_follow_playhead; ///< state of Editor::follow_playhead() before the drags started
100 /** Abstract base class for dragging of things within the editor */
104 Drag (Editor *, ArdourCanvas::Item *);
107 void set_manager (DragManager* m) {
111 /** @return the canvas item being dragged */
112 ArdourCanvas::Item* item () const {
116 void swap_grab (ArdourCanvas::Item *, Gdk::Cursor *, uint32_t);
117 bool motion_handler (GdkEvent*, bool);
120 ARDOUR::framepos_t adjusted_frame (ARDOUR::framepos_t, GdkEvent const *, bool snap = true) const;
121 ARDOUR::framepos_t adjusted_current_frame (GdkEvent const *, bool snap = true) const;
123 /** Called to start a grab of an item.
124 * @param e Event that caused the grab to start.
125 * @param c Cursor to use, or 0.
127 virtual void start_grab (GdkEvent* e, Gdk::Cursor* c = 0);
129 virtual bool end_grab (GdkEvent *);
131 /** Called when a drag motion has occurred.
132 * @param e Event describing the motion.
133 * @param f true if this is the first movement, otherwise false.
135 virtual void motion (GdkEvent* e, bool f) = 0;
137 /** Called when a drag has finished.
138 * @param e Event describing the finish.
139 * @param m true if some movement occurred, otherwise false.
141 virtual void finished (GdkEvent* e, bool m) = 0;
143 /** Called to abort a drag and return things to how
144 * they were before it started.
145 * @param m true if some movement occurred, otherwise false.
147 virtual void aborted (bool m) = 0;
149 /** @param m Mouse mode.
150 * @return true if this drag should happen in this mouse mode.
152 virtual bool active (Editing::MouseMode m) {
153 return (m != Editing::MouseGain);
156 /** @return minimum number of frames (in x) and pixels (in y) that should be considered a movement */
157 virtual std::pair<ARDOUR::framecnt_t, int> move_threshold () const {
158 return std::make_pair (1, 1);
161 virtual bool allow_vertical_autoscroll () const {
165 /** @return true if x movement matters to this drag */
166 virtual bool x_movement_matters () const {
170 /** @return true if y movement matters to this drag */
171 virtual bool y_movement_matters () const {
175 /** Set up the _pointer_frame_offset */
176 virtual void setup_pointer_frame_offset () {
177 _pointer_frame_offset = 0;
182 double grab_x () const {
186 double grab_y () const {
190 ARDOUR::framepos_t raw_grab_frame () const {
191 return _raw_grab_frame;
194 ARDOUR::framepos_t grab_frame () const {
198 double last_pointer_x () const {
199 return _last_pointer_x;
202 double last_pointer_y () const {
203 return _last_pointer_y;
206 double last_pointer_frame () const {
207 return _last_pointer_frame;
210 boost::shared_ptr<ARDOUR::Region> add_midi_region (MidiTimeAxisView*);
212 void show_verbose_cursor_time (framepos_t);
213 void show_verbose_cursor_duration (framepos_t, framepos_t, double xoffset = 0);
214 void show_verbose_cursor_text (std::string const &);
216 Editor* _editor; ///< our editor
218 ArdourCanvas::Item* _item; ///< our item
219 /** Offset from the mouse's position for the drag to the start of the thing that is being dragged */
220 ARDOUR::framecnt_t _pointer_frame_offset;
221 bool _x_constrained; ///< true if x motion is constrained, otherwise false
222 bool _y_constrained; ///< true if y motion is constrained, otherwise false
223 bool _was_rolling; ///< true if the session was rolling before the drag started, otherwise false
227 bool _move_threshold_passed; ///< true if the move threshold has been passed, otherwise false
228 double _grab_x; ///< trackview x of the grab start position
229 double _grab_y; ///< trackview y of the grab start position
230 double _last_pointer_x; ///< trackview x of the pointer last time a motion occurred
231 double _last_pointer_y; ///< trackview y of the pointer last time a motion occurred
232 ARDOUR::framepos_t _raw_grab_frame; ///< unsnapped frame that the mouse was at when start_grab was called, or 0
233 ARDOUR::framepos_t _grab_frame; ///< adjusted_frame that the mouse was at when start_grab was called, or 0
234 ARDOUR::framepos_t _last_pointer_frame; ///< adjusted_frame the last time a motion occurred
239 /** Container for details about a region being dragged */
243 DraggingView (RegionView *, RegionDrag *);
245 RegionView* view; ///< the view
246 /** index into RegionDrag::_time_axis_views of the view that this region is currently being displayed on,
247 * or -1 if it is not visible.
250 /** layer that this region is currently being displayed on. This is a double
251 rather than a layer_t as we use fractional layers during drags to allow the user
252 to indicate a new layer to put a region on.
255 double initial_y; ///< the initial y position of the view before any reparenting
256 framepos_t initial_position; ///< initial position of the region
257 framepos_t initial_end; ///< initial end position of the region
258 boost::shared_ptr<ARDOUR::Playlist> initial_playlist;
261 /** Abstract base class for drags that involve region(s) */
262 class RegionDrag : public Drag, public sigc::trackable
265 RegionDrag (Editor *, ArdourCanvas::Item *, RegionView *, std::list<RegionView*> const &);
266 virtual ~RegionDrag () {}
270 RegionView* _primary; ///< the view that was clicked on (or whatever) to start the drag
271 std::list<DraggingView> _views; ///< information about all views that are being dragged
273 /** a list of the non-hidden TimeAxisViews sorted by editor order key */
274 std::vector<TimeAxisView*> _time_axis_views;
275 int find_time_axis_view (TimeAxisView *) const;
280 friend class DraggingView;
284 void region_going_away (RegionView *);
285 PBD::ScopedConnection death_connection;
289 /** Drags involving region motion from somewhere */
290 class RegionMotionDrag : public RegionDrag
294 RegionMotionDrag (Editor *, ArdourCanvas::Item *, RegionView *, std::list<RegionView*> const &, bool);
295 virtual ~RegionMotionDrag () {}
297 virtual void start_grab (GdkEvent *, Gdk::Cursor *);
298 virtual void motion (GdkEvent *, bool);
299 virtual void finished (GdkEvent *, bool);
300 virtual void aborted (bool);
302 /** @return true if the regions being `moved' came from somewhere on the canvas;
303 * false if they came from outside (e.g. from the region list).
305 virtual bool regions_came_from_canvas () const = 0;
309 double compute_x_delta (GdkEvent const *, ARDOUR::framepos_t *);
310 bool y_movement_allowed (int, double) const;
313 ARDOUR::framepos_t _last_frame_position; ///< last position of the thing being dragged
314 double _total_x_delta;
315 int _last_pointer_time_axis_view;
316 double _last_pointer_layer;
320 /** Drags to move (or copy) regions that are already shown in the GUI to
321 * somewhere different.
323 class RegionMoveDrag : public RegionMotionDrag
326 RegionMoveDrag (Editor *, ArdourCanvas::Item *, RegionView *, std::list<RegionView*> const &, bool, bool);
327 virtual ~RegionMoveDrag () {}
329 void motion (GdkEvent *, bool);
330 void finished (GdkEvent *, bool);
333 bool regions_came_from_canvas () const {
337 std::pair<ARDOUR::framecnt_t, int> move_threshold () const {
338 return std::make_pair (4, 4);
341 void setup_pointer_frame_offset ();
344 typedef std::set<boost::shared_ptr<ARDOUR::Playlist> > PlaylistSet;
346 void finished_no_copy (
349 ARDOUR::framecnt_t const
355 ARDOUR::framecnt_t const
358 RegionView* insert_region_into_playlist (
359 boost::shared_ptr<ARDOUR::Region>,
366 void remove_region_from_playlist (
367 boost::shared_ptr<ARDOUR::Region>,
368 boost::shared_ptr<ARDOUR::Playlist>,
369 PlaylistSet& modified_playlists
372 void add_stateful_diff_commands_for_playlists (PlaylistSet const &);
374 void collect_new_region_view (RegionView *);
377 RegionView* _new_region_view;
380 /** Drag to insert a region from somewhere */
381 class RegionInsertDrag : public RegionMotionDrag
384 RegionInsertDrag (Editor *, boost::shared_ptr<ARDOUR::Region>, RouteTimeAxisView*, ARDOUR::framepos_t);
386 void finished (GdkEvent *, bool);
389 bool regions_came_from_canvas () const {
394 /** Region drag in splice mode */
395 class RegionSpliceDrag : public RegionMoveDrag
398 RegionSpliceDrag (Editor *, ArdourCanvas::Item *, RegionView *, std::list<RegionView*> const &);
400 void motion (GdkEvent *, bool);
401 void finished (GdkEvent *, bool);
405 /** Drags to create regions */
406 class RegionCreateDrag : public Drag
409 RegionCreateDrag (Editor *, ArdourCanvas::Item *, TimeAxisView *);
411 void motion (GdkEvent *, bool);
412 void finished (GdkEvent *, bool);
416 MidiTimeAxisView* _view;
417 boost::shared_ptr<ARDOUR::Region> _region;
420 /** Drags to resize MIDI notes */
421 class NoteResizeDrag : public Drag
424 NoteResizeDrag (Editor *, ArdourCanvas::Item *);
426 void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
427 void motion (GdkEvent *, bool);
428 void finished (GdkEvent *, bool);
432 MidiRegionView* region;
437 /** Drags to move MIDI notes */
438 class NoteDrag : public Drag
441 NoteDrag (Editor*, ArdourCanvas::Item*);
443 void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
444 void motion (GdkEvent *, bool);
445 void finished (GdkEvent *, bool);
450 ARDOUR::frameoffset_t total_dx () const;
451 int8_t total_dy () const;
453 MidiRegionView* _region;
455 double _cumulative_dx;
456 double _cumulative_dy;
461 class NoteCreateDrag : public Drag
464 NoteCreateDrag (Editor *, ArdourCanvas::Item *, MidiRegionView *);
467 void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
468 void motion (GdkEvent *, bool);
469 void finished (GdkEvent *, bool);
473 double y_to_region (double) const;
474 framecnt_t grid_frames (framepos_t) const;
476 MidiRegionView* _region_view;
477 ArdourCanvas::Rectangle* _drag_rect;
481 /** Drag to move MIDI patch changes */
482 class PatchChangeDrag : public Drag
485 PatchChangeDrag (Editor *, PatchChange *, MidiRegionView *);
487 void motion (GdkEvent *, bool);
488 void finished (GdkEvent *, bool);
491 bool y_movement_matters () const {
495 void setup_pointer_frame_offset ();
498 MidiRegionView* _region_view;
499 PatchChange* _patch_change;
500 double _cumulative_dx;
503 /** Container for details about audio regions being dragged along with video */
507 AVDraggingView (RegionView *);
509 RegionView* view; ///< the view
510 framepos_t initial_position; ///< initial position of the region
513 /** Drag of video offset */
514 class VideoTimeLineDrag : public Drag
517 VideoTimeLineDrag (Editor *e, ArdourCanvas::Item *i);
519 void motion (GdkEvent *, bool);
520 void finished (GdkEvent *, bool);
521 void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
523 bool y_movement_matters () const {
527 bool allow_vertical_autoscroll () const {
534 std::list<AVDraggingView> _views; ///< information about all audio that are being dragged along
537 ARDOUR::frameoffset_t _startdrag_video_offset;
538 ARDOUR::frameoffset_t _max_backwards_drag;
541 /** Drag to trim region(s) */
542 class TrimDrag : public RegionDrag
551 TrimDrag (Editor *, ArdourCanvas::Item *, RegionView*, std::list<RegionView*> const &, bool preserve_fade_anchor = false);
553 void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
554 void motion (GdkEvent *, bool);
555 void finished (GdkEvent *, bool);
558 bool y_movement_matters () const {
562 void setup_pointer_frame_offset ();
566 Operation _operation;
568 bool _preserve_fade_anchor;
571 /** Meter marker drag */
572 class MeterMarkerDrag : public Drag
575 MeterMarkerDrag (Editor *, ArdourCanvas::Item *, bool);
577 void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
578 void motion (GdkEvent *, bool);
579 void finished (GdkEvent *, bool);
582 bool allow_vertical_autoscroll () const {
586 bool y_movement_matters () const {
590 void setup_pointer_frame_offset ();
593 MeterMarker* _marker;
595 XMLNode* before_state;
598 /** Tempo marker drag */
599 class TempoMarkerDrag : public Drag
602 TempoMarkerDrag (Editor *, ArdourCanvas::Item *, bool);
604 void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
605 void motion (GdkEvent *, bool);
606 void finished (GdkEvent *, bool);
609 bool allow_vertical_autoscroll () const {
613 bool y_movement_matters () const {
617 void setup_pointer_frame_offset ();
620 TempoMarker* _marker;
622 XMLNode* before_state;
626 /** Drag of the playhead cursor */
627 class CursorDrag : public Drag
630 CursorDrag (Editor *, EditorCursor&, bool);
632 void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
633 void motion (GdkEvent *, bool);
634 void finished (GdkEvent *, bool);
637 bool active (Editing::MouseMode) {
641 bool allow_vertical_autoscroll () const {
645 bool y_movement_matters () const {
650 void fake_locate (framepos_t);
652 EditorCursor& _cursor;
653 bool _stop; ///< true to stop the transport on starting the drag, otherwise false
654 double _grab_zoom; ///< editor frames per unit when our grab started
657 /** Region fade-in drag */
658 class FadeInDrag : public RegionDrag
661 FadeInDrag (Editor *, ArdourCanvas::Item *, RegionView *, std::list<RegionView*> const &);
663 void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
664 void motion (GdkEvent *, bool);
665 void finished (GdkEvent *, bool);
668 bool y_movement_matters () const {
672 void setup_pointer_frame_offset ();
675 /** Region fade-out drag */
676 class FadeOutDrag : public RegionDrag
679 FadeOutDrag (Editor *, ArdourCanvas::Item *, RegionView *, std::list<RegionView*> const &);
681 void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
682 void motion (GdkEvent *, bool);
683 void finished (GdkEvent *, bool);
686 bool y_movement_matters () const {
690 void setup_pointer_frame_offset ();
694 class MarkerDrag : public Drag
697 MarkerDrag (Editor *, ArdourCanvas::Item *);
700 void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
701 void motion (GdkEvent *, bool);
702 void finished (GdkEvent *, bool);
705 bool allow_vertical_autoscroll () const {
709 bool y_movement_matters () const {
713 void setup_pointer_frame_offset ();
716 void update_item (ARDOUR::Location *);
718 Marker* _marker; ///< marker being dragged
720 struct CopiedLocationMarkerInfo {
721 ARDOUR::Location* location;
722 std::vector<Marker*> markers;
724 CopiedLocationMarkerInfo (ARDOUR::Location* l, Marker* m);
727 typedef std::list<CopiedLocationMarkerInfo> CopiedLocationInfo;
728 CopiedLocationInfo _copied_locations;
729 ArdourCanvas::Points _points;
732 /** Control point drag */
733 class ControlPointDrag : public Drag
736 ControlPointDrag (Editor *, ArdourCanvas::Item *);
738 void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
739 void motion (GdkEvent *, bool);
740 void finished (GdkEvent *, bool);
743 bool active (Editing::MouseMode m);
747 ControlPoint* _point;
748 double _fixed_grab_x;
749 double _fixed_grab_y;
750 double _cumulative_x_drag;
751 double _cumulative_y_drag;
753 uint32_t _final_index;
754 static double _zero_gain_fraction;
757 /** Gain or automation line drag */
758 class LineDrag : public Drag
761 LineDrag (Editor *e, ArdourCanvas::Item *i);
763 void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
764 void motion (GdkEvent *, bool);
765 void finished (GdkEvent *, bool);
768 bool active (Editing::MouseMode) {
774 AutomationLine* _line;
775 double _fixed_grab_x;
776 double _fixed_grab_y;
779 double _cumulative_y_drag;
782 /** Transient feature line drags*/
783 class FeatureLineDrag : public Drag
786 FeatureLineDrag (Editor *e, ArdourCanvas::Item *i);
788 void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
789 void motion (GdkEvent *, bool);
790 void finished (GdkEvent *, bool);
793 bool active (Editing::MouseMode) {
799 ArdourCanvas::Line* _line;
800 AudioRegionView* _arv;
802 double _region_view_grab_x;
803 double _cumulative_x_drag;
809 /** Dragging of a rubberband rectangle for selecting things */
810 class RubberbandSelectDrag : public Drag
813 RubberbandSelectDrag (Editor *, ArdourCanvas::Item *);
815 void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
816 void motion (GdkEvent *, bool);
817 void finished (GdkEvent *, bool);
820 std::pair<ARDOUR::framecnt_t, int> move_threshold () const {
821 return std::make_pair (8, 1);
824 void do_select_things (GdkEvent *, bool);
826 /** Select some things within a rectangle.
827 * @param button_state The button state from the GdkEvent.
828 * @param x1 The left-hand side of the rectangle in session frames.
829 * @param x2 The right-hand side of the rectangle in session frames.
830 * @param y1 The top of the rectangle in trackview coordinates.
831 * @param y2 The bottom of the rectangle in trackview coordinates.
832 * @param drag_in_progress true if the drag is currently happening.
834 virtual void select_things (int button_state, framepos_t x1, framepos_t x2, double y1, double y2, bool drag_in_progress) = 0;
836 virtual void deselect_things () = 0;
842 /** A general editor RubberbandSelectDrag (for regions, automation points etc.) */
843 class EditorRubberbandSelectDrag : public RubberbandSelectDrag
846 EditorRubberbandSelectDrag (Editor *, ArdourCanvas::Item *);
848 void select_things (int, framepos_t, framepos_t, double, double, bool);
849 void deselect_things ();
852 /** A RubberbandSelectDrag for selecting MIDI notes */
853 class MidiRubberbandSelectDrag : public RubberbandSelectDrag
856 MidiRubberbandSelectDrag (Editor *, MidiRegionView *);
858 void select_things (int, framepos_t, framepos_t, double, double, bool);
859 void deselect_things ();
862 MidiRegionView* _region_view;
865 /** A RubberbandSelectDrag for selecting MIDI notes but with no horizonal component */
866 class MidiVerticalSelectDrag : public RubberbandSelectDrag
869 MidiVerticalSelectDrag (Editor *, MidiRegionView *);
871 void select_things (int, framepos_t, framepos_t, double, double, bool);
872 void deselect_things ();
875 MidiRegionView* _region_view;
878 /** Region drag in time-FX mode */
879 class TimeFXDrag : public RegionDrag
882 TimeFXDrag (Editor *, ArdourCanvas::Item *, RegionView *, std::list<RegionView*> const &);
884 void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
885 void motion (GdkEvent *, bool);
886 void finished (GdkEvent *, bool);
890 /** Scrub drag in audition mode */
891 class ScrubDrag : public Drag
894 ScrubDrag (Editor *, ArdourCanvas::Item *);
896 void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
897 void motion (GdkEvent *, bool);
898 void finished (GdkEvent *, bool);
902 /** Drag in range select mode */
903 class SelectionDrag : public Drag
914 SelectionDrag (Editor *, ArdourCanvas::Item *, Operation);
916 void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
917 void motion (GdkEvent *, bool);
918 void finished (GdkEvent *, bool);
921 void setup_pointer_frame_offset ();
924 Operation _operation;
927 int _original_pointer_time_axis;
928 int _last_pointer_time_axis;
929 std::list<TimeAxisView*> _added_time_axes;
930 bool _time_selection_at_start;
931 framepos_t start_at_start;
932 framepos_t end_at_start;
935 /** Range marker drag */
936 class RangeMarkerBarDrag : public Drag
941 CreateTransportMarker,
945 RangeMarkerBarDrag (Editor *, ArdourCanvas::Item *, Operation);
947 void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
948 void motion (GdkEvent *, bool);
949 void finished (GdkEvent *, bool);
952 bool allow_vertical_autoscroll () const {
956 bool y_movement_matters () const {
961 void update_item (ARDOUR::Location *);
963 Operation _operation;
964 ArdourCanvas::Rectangle* _drag_rect;
968 /** Drag of rectangle to set zoom */
969 class MouseZoomDrag : public Drag
972 MouseZoomDrag (Editor *, ArdourCanvas::Item *);
974 void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
975 void motion (GdkEvent *, bool);
976 void finished (GdkEvent *, bool);
979 std::pair<ARDOUR::framecnt_t, int> move_threshold () const {
980 return std::make_pair (4, 4);
987 /** Drag of a range of automation data (either on an automation track or region gain),
988 * changing value but not position.
990 class AutomationRangeDrag : public Drag
993 AutomationRangeDrag (Editor *, AutomationTimeAxisView *, std::list<ARDOUR::AudioRange> const &);
994 AutomationRangeDrag (Editor *, AudioRegionView *, std::list<ARDOUR::AudioRange> const &);
996 void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
997 void motion (GdkEvent *, bool);
998 void finished (GdkEvent *, bool);
1001 bool x_movement_matters () const {
1005 bool active (Editing::MouseMode) {
1010 void setup (std::list<boost::shared_ptr<AutomationLine> > const &);
1011 double y_fraction (boost::shared_ptr<AutomationLine>, double global_y_position) const;
1013 std::list<ARDOUR::AudioRange> _ranges;
1015 /** A line that is part of the drag */
1017 boost::shared_ptr<AutomationLine> line; ///< the line
1018 std::list<ControlPoint*> points; ///< points to drag on the line
1019 std::pair<ARDOUR::framepos_t, ARDOUR::framepos_t> range; ///< the range of all points on the line, in session frames
1020 XMLNode* state; ///< the XML state node before the drag
1021 double original_fraction; ///< initial y-fraction before the drag
1024 std::list<Line> _lines;
1026 bool _nothing_to_drag;
1029 /** Drag of one edge of an xfade
1031 class CrossfadeEdgeDrag : public Drag
1034 CrossfadeEdgeDrag (Editor*, AudioRegionView*, ArdourCanvas::Item*, bool start);
1036 void start_grab (GdkEvent*, Gdk::Cursor* c = 0);
1037 void motion (GdkEvent*, bool);
1038 void finished (GdkEvent*, bool);
1039 void aborted (bool);
1041 bool y_movement_matters () const {
1045 virtual std::pair<ARDOUR::framecnt_t, int> move_threshold () const {
1046 return std::make_pair (4, 4);
1050 AudioRegionView* arv;
1054 #endif /* __gtk2_ardour_editor_drag_h_ */