patches from lincoln to speed up the regionlist and provide region removal (causes...
[ardour2.git] / gtk2_ardour / editor_drag.h
blobce8a1370f4e63ca1ac6ce266f0e75ea1dee97443
1 /*
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_
23 #include <list>
25 #include <gdk/gdk.h>
26 #include <stdint.h>
27 #include <bitset>
29 #include "ardour/types.h"
31 #include "canvas.h"
32 #include "editor_items.h"
34 namespace ARDOUR {
35 class Location;
38 namespace PBD {
39 class StatefulDiffCommand;
42 namespace Gnome {
43 namespace Canvas {
44 class CanvasNoteEvent;
45 class CanvasPatchChange;
49 class Editor;
50 class EditorCursor;
51 class TimeAxisView;
52 class MidiTimeAxisView;
53 class Drag;
55 /** Class to manage current drags */
56 class DragManager
58 public:
60 DragManager (Editor* e);
61 ~DragManager ();
63 bool motion_handler (GdkEvent *, bool);
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;
72 /** @return true if an end drag or abort is in progress */
73 bool ending () const {
74 return _ending;
77 bool active () const {
78 return !_drags.empty ();
81 /** @return current pointer x position in trackview coordinates */
82 double current_pointer_x () const {
83 return _current_pointer_x;
86 /** @return current pointer y position in trackview coordinates */
87 double current_pointer_y () const {
88 return _current_pointer_y;
91 /** @return current pointer frame */
92 ARDOUR::framepos_t current_pointer_frame () const {
93 return _current_pointer_frame;
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
106 /** Abstract base class for dragging of things within the editor */
107 class Drag
109 public:
110 Drag (Editor *, ArdourCanvas::Item *);
111 virtual ~Drag () {}
113 void set_manager (DragManager* m) {
114 _drags = m;
117 /** @return the canvas item being dragged */
118 ArdourCanvas::Item* item () const {
119 return _item;
122 void swap_grab (ArdourCanvas::Item *, Gdk::Cursor *, uint32_t);
123 bool motion_handler (GdkEvent*, bool);
124 void abort ();
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;
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.
133 virtual void start_grab (GdkEvent* e, Gdk::Cursor* c = 0);
135 virtual bool end_grab (GdkEvent *);
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.
141 virtual void motion (GdkEvent* e, bool f) = 0;
143 /** Called when a drag has finished.
144 * @param e Event describing the finish.
145 * @param m true if some movement occurred, otherwise false.
147 virtual void finished (GdkEvent* e, bool m) = 0;
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.
153 virtual void aborted (bool m) = 0;
155 /** @param m Mouse mode.
156 * @return true if this drag should happen in this mouse mode.
158 virtual bool active (Editing::MouseMode m) {
159 return (m != Editing::MouseGain);
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);
167 virtual bool allow_vertical_autoscroll () const {
168 return true;
171 /** @return true if x movement matters to this drag */
172 virtual bool x_movement_matters () const {
173 return true;
176 /** @return true if y movement matters to this drag */
177 virtual bool y_movement_matters () const {
178 return true;
181 /** Set up the _pointer_frame_offset */
182 virtual void setup_pointer_frame_offset () {
183 _pointer_frame_offset = 0;
186 protected:
188 double grab_x () const {
189 return _grab_x;
192 double grab_y () const {
193 return _grab_y;
196 ARDOUR::framepos_t raw_grab_frame () const {
197 return _raw_grab_frame;
200 ARDOUR::framepos_t grab_frame () const {
201 return _grab_frame;
204 double last_pointer_x () const {
205 return _last_pointer_x;
208 double last_pointer_y () const {
209 return _last_pointer_y;
212 double last_pointer_frame () const {
213 return _last_pointer_frame;
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
225 private:
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
237 class RegionDrag;
239 /** Container for details about a region being dragged */
240 struct DraggingView
242 DraggingView (RegionView *, RegionDrag *);
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;
255 /** Abstract base class for drags that involve region(s) */
256 class RegionDrag : public Drag, public sigc::trackable
258 public:
259 RegionDrag (Editor *, ArdourCanvas::Item *, RegionView *, std::list<RegionView*> const &);
260 virtual ~RegionDrag () {}
262 protected:
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
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;
271 int _visible_y_low;
272 int _visible_y_high;
274 friend class DraggingView;
276 private:
278 void region_going_away (RegionView *);
279 PBD::ScopedConnection death_connection;
283 /** Drags involving region motion from somewhere */
284 class RegionMotionDrag : public RegionDrag
286 public:
288 RegionMotionDrag (Editor *, ArdourCanvas::Item *, RegionView *, std::list<RegionView*> const &, bool);
289 virtual ~RegionMotionDrag () {}
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);
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).
299 virtual bool regions_came_from_canvas () const = 0;
301 protected:
303 double compute_x_delta (GdkEvent const *, ARDOUR::framecnt_t *);
304 bool y_movement_allowed (int, ARDOUR::layer_t) const;
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;
314 /** Drags to move (or copy) regions that are already shown in the GUI to
315 * somewhere different.
317 class RegionMoveDrag : public RegionMotionDrag
319 public:
320 RegionMoveDrag (Editor *, ArdourCanvas::Item *, RegionView *, std::list<RegionView*> const &, bool, bool);
321 virtual ~RegionMoveDrag () {}
323 void motion (GdkEvent *, bool);
324 void finished (GdkEvent *, bool);
325 void aborted (bool);
327 bool regions_came_from_canvas () const {
328 return true;
331 std::pair<ARDOUR::framecnt_t, int> move_threshold () const {
332 return std::make_pair (4, 4);
335 void setup_pointer_frame_offset ();
337 private:
338 typedef std::set<boost::shared_ptr<ARDOUR::Playlist> > PlaylistSet;
340 void finished_no_copy (
341 bool const,
342 bool const,
343 ARDOUR::framecnt_t const
346 void finished_copy (
347 bool const,
348 bool const,
349 ARDOUR::framecnt_t const
352 RegionView* insert_region_into_playlist (
353 boost::shared_ptr<ARDOUR::Region>,
354 RouteTimeAxisView*,
355 ARDOUR::layer_t,
356 ARDOUR::framecnt_t,
357 PlaylistSet&
360 void remove_region_from_playlist (
361 boost::shared_ptr<ARDOUR::Region>,
362 boost::shared_ptr<ARDOUR::Playlist>,
363 PlaylistSet& modified_playlists
366 void add_stateful_diff_commands_for_playlists (PlaylistSet const &);
368 void collect_new_region_view (RegionView *);
370 bool _copy;
371 RegionView* _new_region_view;
374 /** Drag to insert a region from somewhere */
375 class RegionInsertDrag : public RegionMotionDrag
377 public:
378 RegionInsertDrag (Editor *, boost::shared_ptr<ARDOUR::Region>, RouteTimeAxisView*, ARDOUR::framepos_t);
380 void finished (GdkEvent *, bool);
381 void aborted (bool);
383 bool regions_came_from_canvas () const {
384 return false;
388 /** Region drag in splice mode */
389 class RegionSpliceDrag : public RegionMoveDrag
391 public:
392 RegionSpliceDrag (Editor *, ArdourCanvas::Item *, RegionView *, std::list<RegionView*> const &);
394 void motion (GdkEvent *, bool);
395 void finished (GdkEvent *, bool);
396 void aborted (bool);
399 /** Drags to create regions */
400 class RegionCreateDrag : public Drag
402 public:
403 RegionCreateDrag (Editor *, ArdourCanvas::Item *, TimeAxisView *);
405 void motion (GdkEvent *, bool);
406 void finished (GdkEvent *, bool);
407 void aborted (bool);
409 private:
410 MidiTimeAxisView* _view;
411 boost::shared_ptr<ARDOUR::Region> _region;
412 void add_region ();
415 /** Drags to resize MIDI notes */
416 class NoteResizeDrag : public Drag
418 public:
419 NoteResizeDrag (Editor *, ArdourCanvas::Item *);
421 void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
422 void motion (GdkEvent *, bool);
423 void finished (GdkEvent *, bool);
424 void aborted (bool);
426 private:
427 MidiRegionView* region;
428 bool relative;
429 bool at_front;
432 /** Drags to move MIDI notes */
433 class NoteDrag : public Drag
435 public:
436 NoteDrag (Editor*, ArdourCanvas::Item*);
438 void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
439 void motion (GdkEvent *, bool);
440 void finished (GdkEvent *, bool);
441 void aborted (bool);
443 private:
445 ARDOUR::frameoffset_t total_dx () const;
446 int8_t total_dy () const;
448 MidiRegionView* _region;
449 Gnome::Canvas::CanvasNoteEvent* _primary;
450 double _cumulative_dx;
451 double _cumulative_dy;
452 bool _was_selected;
453 double _note_height;
456 /** Drag to move MIDI patch changes */
457 class PatchChangeDrag : public Drag
459 public:
460 PatchChangeDrag (Editor *, ArdourCanvas::CanvasPatchChange *, MidiRegionView *);
462 void motion (GdkEvent *, bool);
463 void finished (GdkEvent *, bool);
464 void aborted (bool);
466 bool y_movement_matters () const {
467 return false;
470 void setup_pointer_frame_offset ();
472 private:
473 MidiRegionView* _region_view;
474 ArdourCanvas::CanvasPatchChange* _patch_change;
475 double _cumulative_dx;
478 /** Drag of region gain */
479 class RegionGainDrag : public Drag
481 public:
482 RegionGainDrag (Editor *, ArdourCanvas::Item *);
484 void motion (GdkEvent *, bool);
485 void finished (GdkEvent *, bool);
486 bool active (Editing::MouseMode m) {
487 return (m == Editing::MouseGain);
490 void aborted (bool);
493 /** Drag to trim region(s) */
494 class TrimDrag : public RegionDrag
496 public:
497 enum Operation {
498 StartTrim,
499 EndTrim,
500 ContentsTrim,
503 TrimDrag (Editor *, ArdourCanvas::Item *, RegionView*, std::list<RegionView*> const &);
505 void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
506 void motion (GdkEvent *, bool);
507 void finished (GdkEvent *, bool);
508 void aborted (bool);
510 bool y_movement_matters () const {
511 return false;
514 void setup_pointer_frame_offset ();
516 private:
518 Operation _operation;
521 /** Meter marker drag */
522 class MeterMarkerDrag : public Drag
524 public:
525 MeterMarkerDrag (Editor *, ArdourCanvas::Item *, bool);
527 void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
528 void motion (GdkEvent *, bool);
529 void finished (GdkEvent *, bool);
530 void aborted (bool);
532 bool allow_vertical_autoscroll () const {
533 return false;
536 bool y_movement_matters () const {
537 return false;
540 void setup_pointer_frame_offset ();
542 private:
543 MeterMarker* _marker;
544 bool _copy;
547 /** Tempo marker drag */
548 class TempoMarkerDrag : public Drag
550 public:
551 TempoMarkerDrag (Editor *, ArdourCanvas::Item *, bool);
553 void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
554 void motion (GdkEvent *, bool);
555 void finished (GdkEvent *, bool);
556 void aborted (bool);
558 bool allow_vertical_autoscroll () const {
559 return false;
562 bool y_movement_matters () const {
563 return false;
566 void setup_pointer_frame_offset ();
568 private:
569 TempoMarker* _marker;
570 bool _copy;
574 /** Drag of the playhead cursor */
575 class CursorDrag : public Drag
577 public:
578 CursorDrag (Editor *, ArdourCanvas::Item *, bool);
580 void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
581 void motion (GdkEvent *, bool);
582 void finished (GdkEvent *, bool);
583 void aborted (bool);
585 bool active (Editing::MouseMode) {
586 return true;
589 bool allow_vertical_autoscroll () const {
590 return false;
593 bool y_movement_matters () const {
594 return false;
597 private:
598 void fake_locate (framepos_t);
600 bool _stop; ///< true to stop the transport on starting the drag, otherwise false
603 /** Region fade-in drag */
604 class FadeInDrag : public RegionDrag
606 public:
607 FadeInDrag (Editor *, ArdourCanvas::Item *, RegionView *, std::list<RegionView*> const &);
609 void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
610 void motion (GdkEvent *, bool);
611 void finished (GdkEvent *, bool);
612 void aborted (bool);
614 bool y_movement_matters () const {
615 return false;
618 void setup_pointer_frame_offset ();
621 /** Region fade-out drag */
622 class FadeOutDrag : public RegionDrag
624 public:
625 FadeOutDrag (Editor *, ArdourCanvas::Item *, RegionView *, std::list<RegionView*> const &);
627 void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
628 void motion (GdkEvent *, bool);
629 void finished (GdkEvent *, bool);
630 void aborted (bool);
632 bool y_movement_matters () const {
633 return false;
636 void setup_pointer_frame_offset ();
639 /** Marker drag */
640 class MarkerDrag : public Drag
642 public:
643 MarkerDrag (Editor *, ArdourCanvas::Item *);
644 ~MarkerDrag ();
646 void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
647 void motion (GdkEvent *, bool);
648 void finished (GdkEvent *, bool);
649 void aborted (bool);
651 bool allow_vertical_autoscroll () const {
652 return false;
655 bool y_movement_matters () const {
656 return false;
659 void setup_pointer_frame_offset ();
661 private:
662 void update_item (ARDOUR::Location *);
664 Marker* _marker; ///< marker being dragged
665 std::list<ARDOUR::Location*> _copied_locations;
666 ArdourCanvas::Points _points;
669 /** Control point drag */
670 class ControlPointDrag : public Drag
672 public:
673 ControlPointDrag (Editor *, ArdourCanvas::Item *);
675 void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
676 void motion (GdkEvent *, bool);
677 void finished (GdkEvent *, bool);
678 void aborted (bool);
680 bool active (Editing::MouseMode m);
682 private:
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;
692 /** Gain or automation line drag */
693 class LineDrag : public Drag
695 public:
696 LineDrag (Editor *e, ArdourCanvas::Item *i);
698 void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
699 void motion (GdkEvent *, bool);
700 void finished (GdkEvent *, bool);
701 void aborted (bool);
703 bool active (Editing::MouseMode) {
704 return true;
707 private:
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;
717 /** Transient feature line drags*/
718 class FeatureLineDrag : public Drag
720 public:
721 FeatureLineDrag (Editor *e, ArdourCanvas::Item *i);
723 void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
724 void motion (GdkEvent *, bool);
725 void finished (GdkEvent *, bool);
726 void aborted (bool);
728 bool active (Editing::MouseMode) {
729 return true;
732 private:
734 ArdourCanvas::Line* _line;
735 AudioRegionView* _arv;
737 double _region_view_grab_x;
738 double _cumulative_x_drag;
740 float _before;
741 uint32_t _max_x;
744 /** Dragging of a rubberband rectangle for selecting things */
745 class RubberbandSelectDrag : public Drag
747 public:
748 RubberbandSelectDrag (Editor *, ArdourCanvas::Item *);
750 void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
751 void motion (GdkEvent *, bool);
752 void finished (GdkEvent *, bool);
753 void aborted (bool);
755 std::pair<ARDOUR::framecnt_t, int> move_threshold () const {
756 return std::make_pair (8, 1);
760 /** Region drag in time-FX mode */
761 class TimeFXDrag : public RegionDrag
763 public:
764 TimeFXDrag (Editor *, ArdourCanvas::Item *, RegionView *, std::list<RegionView*> const &);
766 void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
767 void motion (GdkEvent *, bool);
768 void finished (GdkEvent *, bool);
769 void aborted (bool);
772 /** Scrub drag in audition mode */
773 class ScrubDrag : public Drag
775 public:
776 ScrubDrag (Editor *, ArdourCanvas::Item *);
778 void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
779 void motion (GdkEvent *, bool);
780 void finished (GdkEvent *, bool);
781 void aborted (bool);
784 /** Drag in range select mode */
785 class SelectionDrag : public Drag
787 public:
788 enum Operation {
789 CreateSelection,
790 SelectionStartTrim,
791 SelectionEndTrim,
792 SelectionMove
795 SelectionDrag (Editor *, ArdourCanvas::Item *, Operation);
797 void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
798 void motion (GdkEvent *, bool);
799 void finished (GdkEvent *, bool);
800 void aborted (bool);
802 void setup_pointer_frame_offset ();
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;
812 /** Range marker drag */
813 class RangeMarkerBarDrag : public Drag
815 public:
816 enum Operation {
817 CreateRangeMarker,
818 CreateTransportMarker,
819 CreateCDMarker
822 RangeMarkerBarDrag (Editor *, ArdourCanvas::Item *, Operation);
824 void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
825 void motion (GdkEvent *, bool);
826 void finished (GdkEvent *, bool);
827 void aborted (bool);
829 bool allow_vertical_autoscroll () const {
830 return false;
833 bool y_movement_matters () const {
834 return false;
837 private:
838 void update_item (ARDOUR::Location *);
840 Operation _operation;
841 ArdourCanvas::SimpleRect* _drag_rect;
842 bool _copy;
845 /** Drag of rectangle to set zoom */
846 class MouseZoomDrag : public Drag
848 public:
849 MouseZoomDrag (Editor *, ArdourCanvas::Item *);
851 void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
852 void motion (GdkEvent *, bool);
853 void finished (GdkEvent *, bool);
854 void aborted (bool);
856 std::pair<ARDOUR::framecnt_t, int> move_threshold () const {
857 return std::make_pair (4, 4);
860 private:
861 bool _zoom_out;
864 /** Drag of a range of automation data, changing value but not position */
865 class AutomationRangeDrag : public Drag
867 public:
868 AutomationRangeDrag (Editor *, ArdourCanvas::Item *, std::list<ARDOUR::AudioRange> const &);
870 void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
871 void motion (GdkEvent *, bool);
872 void finished (GdkEvent *, bool);
873 void aborted (bool);
875 bool x_movement_matters () const {
876 return false;
879 private:
880 std::list<ARDOUR::AudioRange> _ranges;
881 AutomationTimeAxisView* _atav;
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
891 std::list<Line> _lines;
893 bool _nothing_to_drag;
896 #endif /* __gtk2_ardour_editor_drag_h_ */