nframes64_t -> frame{pos,cnt}_t
[ardour.git] / gtk2_ardour / editor_drag.h
1 /*
2     Copyright (C) 2009 Paul Davis
3
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.
8
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.
13
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.
17
18 */
19
20 #ifndef __gtk2_ardour_editor_drag_h_
21 #define __gtk2_ardour_editor_drag_h_
22
23 #include <list>
24
25 #include <gdk/gdk.h>
26 #include <stdint.h>
27 #include <bitset>
28
29 #include "ardour/types.h"
30
31 #include "canvas.h"
32 #include "editor_items.h"
33
34 namespace ARDOUR {
35         class Location;
36 }
37
38 namespace PBD {
39         class StatefulDiffCommand;
40 }
41
42 namespace Gnome {
43         namespace Canvas {
44                 class CanvasNoteEvent;
45         }
46 }
47
48 class Editor;
49 class EditorCursor;
50 class TimeAxisView;
51 class MidiTimeAxisView;
52 class Drag;
53
54 /** Class to manage current drags */
55 class DragManager
56 {
57 public:
58
59         DragManager (Editor* e);
60         ~DragManager ();
61
62         bool motion_handler (GdkEvent *, bool);
63
64         void abort ();
65         void add (Drag *);
66         void set (Drag *, GdkEvent *, Gdk::Cursor* c = 0);
67         void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
68         bool end_grab (GdkEvent *);
69         bool have_item (ArdourCanvas::Item *) const;
70
71         /** @return true if an end drag or abort is in progress */
72         bool ending () const {
73                 return _ending;
74         }
75
76         bool active () const {
77                 return !_drags.empty ();
78         }
79
80         /** @return current pointer x position in trackview coordinates */
81         double current_pointer_x () const {
82                 return _current_pointer_x;
83         }
84
85         /** @return current pointer y position in trackview coordinates */
86         double current_pointer_y () const {
87                 return _current_pointer_y;
88         }
89
90         /** @return current pointer frame */
91         ARDOUR::framepos_t current_pointer_frame () const {
92                 return _current_pointer_frame;
93         }
94
95 private:
96         Editor* _editor;
97         std::list<Drag*> _drags;
98         bool _ending; ///< true if end_grab or abort is in progress, otherwise false
99         double _current_pointer_x; ///< trackview x of the current pointer
100         double _current_pointer_y; ///< trackview y of the current pointer
101         ARDOUR::framepos_t _current_pointer_frame; ///< frame that the pointer is now at
102 };
103
104 /** Abstract base class for dragging of things within the editor */
105 class Drag
106 {
107 public:
108         Drag (Editor *, ArdourCanvas::Item *);
109         virtual ~Drag () {}
110
111         void set_manager (DragManager* m) {
112                 _drags = m;
113         }
114
115         /** @return the canvas item being dragged */
116         ArdourCanvas::Item* item () const {
117                 return _item;
118         }
119
120         void swap_grab (ArdourCanvas::Item *, Gdk::Cursor *, uint32_t);
121         bool motion_handler (GdkEvent*, bool);
122         void abort ();
123
124         ARDOUR::framepos_t adjusted_frame (ARDOUR::framepos_t, GdkEvent const *, bool snap = true) const;
125         ARDOUR::framepos_t adjusted_current_frame (GdkEvent const *, bool snap = true) const;
126         
127         /** Called to start a grab of an item.
128          *  @param e Event that caused the grab to start.
129          *  @param c Cursor to use, or 0.
130          */
131         virtual void start_grab (GdkEvent* e, Gdk::Cursor* c = 0);
132
133         virtual bool end_grab (GdkEvent *);
134
135         /** Called when a drag motion has occurred.
136          *  @param e Event describing the motion.
137          *  @param f true if this is the first movement, otherwise false.
138          */
139         virtual void motion (GdkEvent* e, bool f) = 0;
140
141         /** Called when a drag has finished.
142          *  @param e Event describing the finish.
143          *  @param m true if some movement occurred, otherwise false.
144          */
145         virtual void finished (GdkEvent* e, bool m) = 0;
146
147         /** Called to abort a drag and return things to how
148          *  they were before it started.
149          */
150         virtual void aborted () = 0;
151
152         /** @param m Mouse mode.
153          *  @return true if this drag should happen in this mouse mode.
154          */
155         virtual bool active (Editing::MouseMode m) {
156                 return (m != Editing::MouseGain);
157         }
158
159         /** @return minimum number of frames (in x) and pixels (in y) that should be considered a movement */
160         virtual std::pair<ARDOUR::framecnt_t, int> move_threshold () const {
161                 return std::make_pair (1, 1);
162         }
163
164         virtual bool allow_vertical_autoscroll () const {
165                 return true;
166         }
167
168         /** @return true if x movement matters to this drag */
169         virtual bool x_movement_matters () const {
170                 return true;
171         }
172
173         /** @return true if y movement matters to this drag */
174         virtual bool y_movement_matters () const {
175                 return true;
176         }
177
178 protected:
179
180         double grab_x () const {
181                 return _grab_x;
182         }
183
184         double grab_y () const {
185                 return _grab_y;
186         }
187
188         ARDOUR::framepos_t raw_grab_frame () const {
189                 return _raw_grab_frame;
190         }
191
192         ARDOUR::framepos_t grab_frame () const {
193                 return _grab_frame;
194         }
195
196         double last_pointer_x () const {
197                 return _last_pointer_x;
198         }
199
200         double last_pointer_y () const {
201                 return _last_pointer_y;
202         }
203
204         double last_pointer_frame () const {
205                 return _last_pointer_frame;
206         }
207
208         Editor* _editor; ///< our editor
209         DragManager* _drags;
210         ArdourCanvas::Item* _item; ///< our item
211         /** Offset from the mouse's position for the drag to the start of the thing that is being dragged */
212         ARDOUR::framecnt_t _pointer_frame_offset;
213         bool _x_constrained; ///< true if x motion is constrained, otherwise false
214         bool _y_constrained; ///< true if y motion is constrained, otherwise false
215         bool _was_rolling; ///< true if the session was rolling before the drag started, otherwise false
216
217 private:
218
219         bool _move_threshold_passed; ///< true if the move threshold has been passed, otherwise false
220         double _grab_x; ///< trackview x of the grab start position
221         double _grab_y; ///< trackview y of the grab start position
222         double _last_pointer_x; ///< trackview x of the pointer last time a motion occurred
223         double _last_pointer_y; ///< trackview y of the pointer last time a motion occurred
224         ARDOUR::framepos_t _raw_grab_frame; ///< unsnapped frame that the mouse was at when start_grab was called, or 0
225         ARDOUR::framepos_t _grab_frame; ///< adjusted_frame that the mouse was at when start_grab was called, or 0
226         ARDOUR::framepos_t _last_pointer_frame; ///< adjusted_frame the last time a motion occurred
227 };
228
229 class RegionDrag;
230
231 /** Container for details about a region being dragged */
232 struct DraggingView
233 {
234         DraggingView (RegionView *, RegionDrag *);
235
236         RegionView* view; ///< the view
237         /** index into RegionDrag::_time_axis_views of the view that this region is currently beind displayed on */
238         int time_axis_view;
239         /** layer that this region is currently being displayed on */
240         ARDOUR::layer_t layer;
241         double initial_y; ///< the initial y position of the view before any reparenting
242         boost::shared_ptr<ARDOUR::Playlist> initial_playlist;
243 };
244
245 /** Abstract base class for drags that involve region(s) */
246 class RegionDrag : public Drag, public sigc::trackable
247 {
248 public:
249         RegionDrag (Editor *, ArdourCanvas::Item *, RegionView *, std::list<RegionView*> const &);
250         virtual ~RegionDrag () {}
251
252 protected:
253
254         RegionView* _primary; ///< the view that was clicked on (or whatever) to start the drag
255         std::list<DraggingView> _views; ///< information about all views that are being dragged
256
257         /** a list of the non-hidden TimeAxisViews sorted by editor order key */
258         std::vector<TimeAxisView*> _time_axis_views;
259         int find_time_axis_view (TimeAxisView *) const;
260
261         int _visible_y_low;
262         int _visible_y_high;
263
264         friend class DraggingView;
265         
266 private:
267         
268         void region_going_away (RegionView *);
269         PBD::ScopedConnection death_connection;
270 };
271
272
273 /** Drags involving region motion from somewhere */
274 class RegionMotionDrag : public RegionDrag
275 {
276 public:
277
278         RegionMotionDrag (Editor *, ArdourCanvas::Item *, RegionView *, std::list<RegionView*> const &, bool);
279         virtual ~RegionMotionDrag () {}
280
281         virtual void start_grab (GdkEvent *, Gdk::Cursor *);
282         virtual void motion (GdkEvent *, bool);
283         virtual void finished (GdkEvent *, bool) = 0;
284         virtual void aborted ();
285
286         /** @return true if the regions being `moved' came from somewhere on the canvas;
287          *  false if they came from outside (e.g. from the region list).
288          */
289         virtual bool regions_came_from_canvas () const = 0;
290
291 protected:
292
293         double compute_x_delta (GdkEvent const *, ARDOUR::framecnt_t *);
294         bool y_movement_allowed (int, ARDOUR::layer_t) const;
295
296         bool _brushing;
297         ARDOUR::framepos_t _last_frame_position; ///< last position of the thing being dragged
298         double _total_x_delta;
299         int _last_pointer_time_axis_view;
300         ARDOUR::layer_t _last_pointer_layer;
301 };
302
303
304 /** Drags to move (or copy) regions that are already shown in the GUI to
305  *  somewhere different.
306  */
307 class RegionMoveDrag : public RegionMotionDrag
308 {
309 public:
310         RegionMoveDrag (Editor *, ArdourCanvas::Item *, RegionView *, std::list<RegionView*> const &, bool, bool);
311         virtual ~RegionMoveDrag () {}
312
313         virtual void start_grab (GdkEvent *, Gdk::Cursor *);
314         void motion (GdkEvent *, bool);
315         void finished (GdkEvent *, bool);
316         void aborted ();
317
318         bool regions_came_from_canvas () const {
319                 return true;
320         }
321
322         std::pair<ARDOUR::framecnt_t, int> move_threshold () const {
323                 return std::make_pair (4, 4);
324         }
325
326 private:
327         typedef std::set<boost::shared_ptr<ARDOUR::Playlist> > PlaylistSet;
328
329         void finished_no_copy (
330                 bool const,
331                 bool const,
332                 ARDOUR::framecnt_t const
333                 );
334
335         void finished_copy (
336                 bool const,
337                 bool const,
338                 ARDOUR::framecnt_t const
339                 );
340
341         RegionView* insert_region_into_playlist (
342                 boost::shared_ptr<ARDOUR::Region>,
343                 RouteTimeAxisView*,
344                 ARDOUR::layer_t,
345                 ARDOUR::framecnt_t,
346                 PlaylistSet&
347                 );
348
349         void remove_region_from_playlist (
350                 boost::shared_ptr<ARDOUR::Region>,
351                 boost::shared_ptr<ARDOUR::Playlist>,
352                 PlaylistSet& modified_playlists
353                 );
354
355         void add_stateful_diff_commands_for_playlists (PlaylistSet const &);
356
357         void collect_new_region_view (RegionView *);
358         
359         bool _copy;
360         RegionView* _new_region_view;
361 };
362
363 /** Drag to insert a region from somewhere */
364 class RegionInsertDrag : public RegionMotionDrag
365 {
366 public:
367         RegionInsertDrag (Editor *, boost::shared_ptr<ARDOUR::Region>, RouteTimeAxisView*, ARDOUR::framepos_t);
368
369         void finished (GdkEvent *, bool);
370         void aborted ();
371
372         bool regions_came_from_canvas () const {
373                 return false;
374         }
375 };
376
377 /** Region drag in splice mode */
378 class RegionSpliceDrag : public RegionMoveDrag
379 {
380 public:
381         RegionSpliceDrag (Editor *, ArdourCanvas::Item *, RegionView *, std::list<RegionView*> const &);
382
383         void motion (GdkEvent *, bool);
384         void finished (GdkEvent *, bool);
385         void aborted ();
386 };
387
388 /** Drags to create regions */
389 class RegionCreateDrag : public Drag
390 {
391 public:
392         RegionCreateDrag (Editor *, ArdourCanvas::Item *, TimeAxisView *);
393
394         void motion (GdkEvent *, bool);
395         void finished (GdkEvent *, bool);
396         void aborted ();
397
398 private:
399         MidiTimeAxisView* _view;
400         boost::shared_ptr<ARDOUR::Region> _region;
401 };
402
403 /** Drags to resize MIDI notes */
404 class NoteResizeDrag : public Drag
405 {
406 public:
407         NoteResizeDrag (Editor *, ArdourCanvas::Item *);
408
409         void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
410         void motion (GdkEvent *, bool);
411         void finished (GdkEvent *, bool);
412         void aborted ();
413
414 private:
415         MidiRegionView*     region;
416         bool                relative;
417         bool                at_front;
418 };
419
420 /** Drags to move MIDI notes */
421 class NoteDrag : public Drag
422 {
423   public:
424         NoteDrag (Editor*, ArdourCanvas::Item*);
425
426         void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
427         void motion (GdkEvent *, bool);
428         void finished (GdkEvent *, bool);
429         void aborted ();
430
431   private:
432
433         ARDOUR::frameoffset_t total_dx () const;
434         int8_t total_dy () const;
435         
436         MidiRegionView* _region;
437         Gnome::Canvas::CanvasNoteEvent* _primary;
438         double _cumulative_dx;
439         double _cumulative_dy;
440         bool _was_selected;
441         double _note_height;
442 };
443
444 /** Drag of region gain */
445 class RegionGainDrag : public Drag
446 {
447 public:
448         RegionGainDrag (Editor *e, ArdourCanvas::Item *i) : Drag (e, i) {}
449
450         void motion (GdkEvent *, bool);
451         void finished (GdkEvent *, bool);
452         bool active (Editing::MouseMode m) {
453                 return (m == Editing::MouseGain);
454         }
455
456         void aborted ();
457 };
458
459 /** Drag to trim region(s) */
460 class TrimDrag : public RegionDrag
461 {
462 public:
463         enum Operation {
464                 StartTrim,
465                 EndTrim,
466                 ContentsTrim,
467         };
468
469         TrimDrag (Editor *, ArdourCanvas::Item *, RegionView*, std::list<RegionView*> const &);
470
471         void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
472         void motion (GdkEvent *, bool);
473         void finished (GdkEvent *, bool);
474         void aborted ();
475
476         bool y_movement_matters () const {
477                 return false;
478         }
479
480 private:
481
482         Operation _operation;
483         bool _have_transaction; ///< true if a transaction has been started, false otherwise. Must be set true by derived class.
484 };
485
486 /** Meter marker drag */
487 class MeterMarkerDrag : public Drag
488 {
489 public:
490         MeterMarkerDrag (Editor *, ArdourCanvas::Item *, bool);
491
492         void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
493         void motion (GdkEvent *, bool);
494         void finished (GdkEvent *, bool);
495         void aborted ();
496
497         bool allow_vertical_autoscroll () const {
498                 return false;
499         }
500
501         bool y_movement_matters () const {
502                 return false;
503         }
504         
505 private:
506         MeterMarker* _marker;
507         bool _copy;
508 };
509
510 /** Tempo marker drag */
511 class TempoMarkerDrag : public Drag
512 {
513 public:
514         TempoMarkerDrag (Editor *, ArdourCanvas::Item *, bool);
515
516         void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
517         void motion (GdkEvent *, bool);
518         void finished (GdkEvent *, bool);
519         void aborted ();
520
521         bool allow_vertical_autoscroll () const {
522                 return false;
523         }
524
525         bool y_movement_matters () const {
526                 return false;
527         }
528
529 private:
530         TempoMarker* _marker;
531         bool _copy;
532 };
533
534
535 /** Drag of a cursor */
536 class CursorDrag : public Drag
537 {
538 public:
539         CursorDrag (Editor *, ArdourCanvas::Item *, bool);
540
541         void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
542         void motion (GdkEvent *, bool);
543         void finished (GdkEvent *, bool);
544         void aborted ();
545
546         bool active (Editing::MouseMode) {
547                 return true;
548         }
549
550         bool allow_vertical_autoscroll () const {
551                 return false;
552         }
553
554         bool y_movement_matters () const {
555                 return false;
556         }
557
558 private:
559         EditorCursor* _cursor; ///< cursor being dragged
560         bool _stop; ///< true to stop the transport on starting the drag, otherwise false
561
562 };
563
564 /** Region fade-in drag */
565 class FadeInDrag : public RegionDrag
566 {
567 public:
568         FadeInDrag (Editor *, ArdourCanvas::Item *, RegionView *, std::list<RegionView*> const &);
569
570         void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
571         void motion (GdkEvent *, bool);
572         void finished (GdkEvent *, bool);
573         void aborted ();
574
575         bool y_movement_matters () const {
576                 return false;
577         }
578 };
579
580 /** Region fade-out drag */
581 class FadeOutDrag : public RegionDrag
582 {
583 public:
584         FadeOutDrag (Editor *, ArdourCanvas::Item *, RegionView *, std::list<RegionView*> const &);
585
586         void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
587         void motion (GdkEvent *, bool);
588         void finished (GdkEvent *, bool);
589         void aborted ();
590
591         bool y_movement_matters () const {
592                 return false;
593         }
594 };
595
596 /** Marker drag */
597 class MarkerDrag : public Drag
598 {
599 public:
600         MarkerDrag (Editor *, ArdourCanvas::Item *);
601         ~MarkerDrag ();
602
603         void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
604         void motion (GdkEvent *, bool);
605         void finished (GdkEvent *, bool);
606         void aborted ();
607
608         bool allow_vertical_autoscroll () const {
609                 return false;
610         }
611
612         bool y_movement_matters () const {
613                 return false;
614         }
615         
616 private:
617         void update_item (ARDOUR::Location *);
618
619         Marker* _marker; ///< marker being dragged
620         std::list<ARDOUR::Location*> _copied_locations;
621         ArdourCanvas::Line* _line;
622         ArdourCanvas::Points _points;
623 };
624
625 /** Control point drag */
626 class ControlPointDrag : public Drag
627 {
628 public:
629         ControlPointDrag (Editor *, ArdourCanvas::Item *);
630
631         void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
632         void motion (GdkEvent *, bool);
633         void finished (GdkEvent *, bool);
634         void aborted ();
635
636         bool active (Editing::MouseMode m);
637
638 private:
639
640         ControlPoint* _point;
641         double _fixed_grab_x;
642         double _fixed_grab_y;
643         double _cumulative_x_drag;
644         double _cumulative_y_drag;
645         static double const _zero_gain_fraction;
646 };
647
648 /** Gain or automation line drag */
649 class LineDrag : public Drag
650 {
651 public:
652         LineDrag (Editor *e, ArdourCanvas::Item *i);
653
654         void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
655         void motion (GdkEvent *, bool);
656         void finished (GdkEvent *, bool);
657         void aborted ();
658
659         bool active (Editing::MouseMode) {
660                 return true;
661         }
662
663 private:
664
665         AutomationLine* _line;
666         double _fixed_grab_x;
667         double _fixed_grab_y;
668         uint32_t _before;
669         uint32_t _after;
670         double _cumulative_y_drag;
671 };
672
673 /** Transient feature line drags*/
674 class FeatureLineDrag : public Drag
675 {
676 public:
677         FeatureLineDrag (Editor *e, ArdourCanvas::Item *i);
678
679         void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
680         void motion (GdkEvent *, bool);
681         void finished (GdkEvent *, bool);
682         void aborted ();
683
684         bool active (Editing::MouseMode) {
685                 return true;
686         }
687
688 private:
689
690         ArdourCanvas::SimpleLine* _line;
691         AudioRegionView* _arv;
692         
693         double _region_view_grab_x;
694         double _cumulative_x_drag;
695         
696         uint32_t _before;
697         uint32_t _max_x;
698 };
699
700 /** Dragging of a rubberband rectangle for selecting things */
701 class RubberbandSelectDrag : public Drag
702 {
703 public:
704         RubberbandSelectDrag (Editor *e, ArdourCanvas::Item *i) : Drag (e, i) {}
705
706         void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
707         void motion (GdkEvent *, bool);
708         void finished (GdkEvent *, bool);
709         void aborted ();
710
711         std::pair<ARDOUR::framecnt_t, int> move_threshold () const {
712                 return std::make_pair (8, 1);
713         }
714 };
715
716 /** Region drag in time-FX mode */
717 class TimeFXDrag : public RegionDrag
718 {
719 public:
720         TimeFXDrag (Editor *e, ArdourCanvas::Item *i, RegionView* p, std::list<RegionView*> const & v) : RegionDrag (e, i, p, v) {}
721
722         void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
723         void motion (GdkEvent *, bool);
724         void finished (GdkEvent *, bool);
725         void aborted ();
726 };
727
728 /** Scrub drag in audition mode */
729 class ScrubDrag : public Drag
730 {
731 public:
732         ScrubDrag (Editor *e, ArdourCanvas::Item *i) : Drag (e, i) {}
733
734         void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
735         void motion (GdkEvent *, bool);
736         void finished (GdkEvent *, bool);
737         void aborted ();
738 };
739
740 /** Drag in range select mode */
741 class SelectionDrag : public Drag
742 {
743 public:
744         enum Operation {
745                 CreateSelection,
746                 SelectionStartTrim,
747                 SelectionEndTrim,
748                 SelectionMove
749         };
750
751         SelectionDrag (Editor *, ArdourCanvas::Item *, Operation);
752
753         void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
754         void motion (GdkEvent *, bool);
755         void finished (GdkEvent *, bool);
756         void aborted ();
757
758 private:
759         Operation _operation;
760         bool _copy;
761         int _original_pointer_time_axis;
762         int _last_pointer_time_axis;
763         std::list<TimeAxisView*> _added_time_axes;
764 };
765
766 /** Range marker drag */
767 class RangeMarkerBarDrag : public Drag
768 {
769 public:
770         enum Operation {
771                 CreateRangeMarker,
772                 CreateTransportMarker,
773                 CreateCDMarker
774         };
775
776         RangeMarkerBarDrag (Editor *, ArdourCanvas::Item *, Operation);
777
778         void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
779         void motion (GdkEvent *, bool);
780         void finished (GdkEvent *, bool);
781         void aborted ();
782
783         bool allow_vertical_autoscroll () const {
784                 return false;
785         }
786
787         bool y_movement_matters () const {
788                 return false;
789         }
790
791 private:
792         void update_item (ARDOUR::Location *);
793
794         Operation _operation;
795         ArdourCanvas::SimpleRect* _drag_rect;
796         bool _copy;
797 };
798
799 /** Drag of rectangle to set zoom */
800 class MouseZoomDrag : public Drag
801 {
802 public:
803         MouseZoomDrag (Editor* e, ArdourCanvas::Item *i) : Drag (e, i) {}
804
805         void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
806         void motion (GdkEvent *, bool);
807         void finished (GdkEvent *, bool);
808         void aborted ();
809 };
810
811 /** Drag of a range of automation data, changing value but not position */
812 class AutomationRangeDrag : public Drag
813 {
814 public:
815         AutomationRangeDrag (Editor *, ArdourCanvas::Item *, std::list<ARDOUR::AudioRange> const &);
816
817         void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
818         void motion (GdkEvent *, bool);
819         void finished (GdkEvent *, bool);
820         void aborted ();
821
822         bool x_movement_matters () const {
823                 return false;
824         }
825
826 private:
827         std::list<ARDOUR::AudioRange> _ranges;
828         AutomationTimeAxisView* _atav;
829         boost::shared_ptr<AutomationLine> _line;
830         bool _nothing_to_drag;
831 };
832
833 #endif /* __gtk2_ardour_editor_drag_h_ */
834