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