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