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"
31 #include "editor_items.h"
41 /** Abstract base class for dragging of things within the editor */
46 Drag (Editor *, ArdourCanvas::Item *);
49 /** @return the canvas item being dragged */
50 ArdourCanvas::Item* item () const {
54 void swap_grab (ArdourCanvas::Item *, Gdk::Cursor *, uint32_t);
57 bool motion_handler (GdkEvent*, bool);
59 /** @return true if an end drag is in progress */
60 bool ending () const {
64 /** @return true if the first move (past any move threshold) has occurred */
65 bool first_move () const {
69 /** @return current pointer x position in item coordinates */
70 double current_pointer_x () const {
71 return _current_pointer_x;
74 /** @return current pointer y position in item coordinates */
75 double current_pointer_y () const {
76 return _current_pointer_y;
79 /** @return current pointer frame */
80 nframes64_t current_pointer_frame () const {
81 return _current_pointer_frame;
84 /** Called to start a grab of an item.
85 * @param e Event that caused the grab to start.
86 * @param c Cursor to use, or 0.
88 virtual void start_grab (GdkEvent* e, Gdk::Cursor* c = 0);
90 virtual bool end_grab (GdkEvent *);
92 /** Called when a drag motion has occurred.
93 * @param e Event describing the motion.
95 virtual void motion (GdkEvent* e) = 0;
97 /** Called when a drag has finished.
98 * @param e Event describing the finish.
100 virtual void finished (GdkEvent *) = 0;
102 /** @param m Mouse mode.
103 * @return true if this drag should happen in this mouse mode.
105 virtual bool active (Editing::MouseMode m) {
106 return (m != Editing::MouseGain);
109 /** Called when a subclass should update the editor's selection following a drag */
110 virtual void update_selection () {}
113 nframes64_t adjusted_current_frame () const;
115 Editor* _editor; ///< our editor
116 ArdourCanvas::Item* _item; ///< our item
117 nframes64_t _pointer_frame_offset; ///< offset from the mouse's position for the drag
118 ///< to the start of the thing that is being dragged
119 nframes64_t _last_frame_position; ///< last position of the thing being dragged
120 nframes64_t _grab_frame; ///< frame that the mouse was at when start_grab was called, or 0
121 nframes64_t _last_pointer_frame; ///< frame that the pointer was at last time a motion occurred
122 nframes64_t _current_pointer_frame; ///< frame that the pointer is now at
123 double _original_x; ///< original world x of the thing being dragged
124 double _original_y; ///< original world y of the thing being dragged
125 double _grab_x; ///< item x of the grab start position
126 double _grab_y; ///< item y of the grab start position
127 double _current_pointer_x; ///< item x of the current pointer
128 double _current_pointer_y; ///< item y of the current pointer
129 double _last_pointer_x; ///< item x of the pointer last time a motion occurred
130 double _last_pointer_y; ///< item y of the pointer last time a motion occurred
131 bool _x_constrained; ///< true if x motion is constrained, otherwise false
132 bool _y_constrained; ///< true if y motion is constrained, otherwise false
133 bool _copy; ///< true if we're copying the things that we're dragging
134 bool _was_rolling; ///< true if the session was rolling before the drag started, otherwise false
135 bool _first_move; ///< true if some movement has occurred, otherwise false
136 bool _move_threshold_passed; ///< true if the move threshold has been passed, otherwise false
137 bool _want_move_threshold; ///< true if a move threshold should be applied, otherwise false
141 bool _ending; ///< true if end_grab is in progress, otherwise false
145 /** Abstract base class for drags that involve region(s) */
146 class RegionDrag : public Drag, public sigc::trackable
149 RegionDrag (Editor *, ArdourCanvas::Item *, RegionView *, std::list<RegionView*> const &);
150 virtual ~RegionDrag () {}
152 void update_selection ();
156 RegionView* _primary; ///< the view that was clicked on (or whatever) to start the drag
157 std::list<RegionView*> _views; ///< all views that are being dragged
160 void region_going_away (RegionView *);
164 /** Drags to move regions */
165 class RegionMoveDrag : public RegionDrag
168 RegionMoveDrag (Editor *, ArdourCanvas::Item *, RegionView *, std::list<RegionView*> const &, bool, bool);
169 virtual ~RegionMoveDrag () {}
171 virtual void start_grab (GdkEvent *, Gdk::Cursor *);
172 virtual void motion (GdkEvent *);
173 virtual void finished (GdkEvent *);
177 bool check_possible (RouteTimeAxisView **, ARDOUR::layer_t *);
179 TimeAxisView* _dest_trackview;
180 ARDOUR::layer_t _dest_layer;
184 void copy_regions (GdkEvent *);
185 bool y_movement_disallowed (int, int, int, int, int, std::bitset<512> const &, std::vector<int32_t> const &) const;
190 /** Region drag in splice mode */
191 class RegionSpliceDrag : public RegionMoveDrag
194 RegionSpliceDrag (Editor *, ArdourCanvas::Item *, RegionView *, std::list<RegionView*> const &);
196 void motion (GdkEvent *);
197 void finished (GdkEvent *);
200 /** Drags to create regions */
201 class RegionCreateDrag : public Drag
204 RegionCreateDrag (Editor *, ArdourCanvas::Item *, TimeAxisView *);
206 void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
207 void motion (GdkEvent *);
208 void finished (GdkEvent *);
212 TimeAxisView* _dest_trackview;
215 /** Drag of region gain */
216 class RegionGainDrag : public Drag
219 RegionGainDrag (Editor *e, ArdourCanvas::Item *i) : Drag (e, i) {}
221 void motion (GdkEvent *);
222 void finished (GdkEvent *);
223 bool active (Editing::MouseMode m) {
224 return (m == Editing::MouseGain);
228 /** Drag to trim region(s) */
229 class TrimDrag : public RegionDrag
238 TrimDrag (Editor *, ArdourCanvas::Item *, RegionView*, std::list<RegionView*> const &);
240 void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
241 void motion (GdkEvent *);
242 void finished (GdkEvent *);
246 Operation _operation;
249 /** Meter marker drag */
250 class MeterMarkerDrag : public Drag
253 MeterMarkerDrag (Editor *, ArdourCanvas::Item *, bool);
255 void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
256 void motion (GdkEvent *);
257 void finished (GdkEvent *);
260 MeterMarker* _marker;
263 /** Tempo marker drag */
264 class TempoMarkerDrag : public Drag
267 TempoMarkerDrag (Editor *, ArdourCanvas::Item *, bool);
269 void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
270 void motion (GdkEvent *);
271 void finished (GdkEvent *);
274 TempoMarker* _marker;
278 /** Drag of a cursor */
279 class CursorDrag : public Drag
282 CursorDrag (Editor *, ArdourCanvas::Item *, bool);
284 void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
285 void motion (GdkEvent *);
286 void finished (GdkEvent *);
289 EditorCursor* _cursor; ///< cursor being dragged
290 bool _stop; ///< true to stop the transport on starting the drag, otherwise false
294 /** Region fade-in drag */
295 class FadeInDrag : public RegionDrag
298 FadeInDrag (Editor *, ArdourCanvas::Item *, RegionView *, std::list<RegionView*> const &);
300 void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
301 void motion (GdkEvent *);
302 void finished (GdkEvent *);
305 /** Region fade-out drag */
306 class FadeOutDrag : public RegionDrag
309 FadeOutDrag (Editor *, ArdourCanvas::Item *, RegionView *, std::list<RegionView*> const &);
311 void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
312 void motion (GdkEvent *);
313 void finished (GdkEvent *);
317 class MarkerDrag : public Drag
320 MarkerDrag (Editor *, ArdourCanvas::Item *);
323 void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
324 void motion (GdkEvent *);
325 void finished (GdkEvent *);
328 void update_item (ARDOUR::Location *);
330 Marker* _marker; ///< marker being dragged
331 std::list<ARDOUR::Location*> _copied_locations;
332 ArdourCanvas::Line* _line;
333 ArdourCanvas::Points _points;
336 /** Control point drag */
337 class ControlPointDrag : public Drag
340 ControlPointDrag (Editor *, ArdourCanvas::Item *);
342 void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
343 void motion (GdkEvent *);
344 void finished (GdkEvent *);
348 ControlPoint* _point;
349 double _cumulative_x_drag;
350 double _cumulative_y_drag;
351 static double const _zero_gain_fraction;
354 /** Gain or automation line drag */
355 class LineDrag : public Drag
358 LineDrag (Editor *e, ArdourCanvas::Item *i);
360 void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
361 void motion (GdkEvent *);
362 void finished (GdkEvent *);
366 AutomationLine* _line;
369 double _cumulative_y_drag;
372 /** Dragging of a rubberband rectangle for selecting things */
373 class RubberbandSelectDrag : public Drag
376 RubberbandSelectDrag (Editor *e, ArdourCanvas::Item *i) : Drag (e, i) {}
378 void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
379 void motion (GdkEvent *);
380 void finished (GdkEvent *);
383 /** Region drag in time-FX mode */
384 class TimeFXDrag : public RegionDrag
387 TimeFXDrag (Editor *e, ArdourCanvas::Item *i, RegionView* p, std::list<RegionView*> const & v) : RegionDrag (e, i, p, v) {}
389 void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
390 void motion (GdkEvent *);
391 void finished (GdkEvent *);
394 /** Drag in range selection mode */
395 class SelectionDrag : public Drag
405 SelectionDrag (Editor *, ArdourCanvas::Item *, Operation);
407 void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
408 void motion (GdkEvent *);
409 void finished (GdkEvent *);
412 Operation _operation;
415 /** Range marker drag */
416 class RangeMarkerBarDrag : public Drag
421 CreateTransportMarker,
425 RangeMarkerBarDrag (Editor *, ArdourCanvas::Item *, Operation);
427 void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
428 void motion (GdkEvent *);
429 void finished (GdkEvent *);
432 void update_item (ARDOUR::Location *);
434 Operation _operation;
435 ArdourCanvas::SimpleRect* _drag_rect;
438 /* Drag of rectangle to set zoom */
439 class MouseZoomDrag : public Drag
442 MouseZoomDrag (Editor *e, ArdourCanvas::Item *i) : Drag (e, i) {}
444 void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
445 void motion (GdkEvent *);
446 void finished (GdkEvent *);
449 #endif /* __gtk2_ardour_editor_drag_h_ */