X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Feditor_drag.h;h=ce8a1370f4e63ca1ac6ce266f0e75ea1dee97443;hb=89d6f40e33933b12a40079e391a96856bfa79e2a;hp=d710e3a639261e0dd80dbca52d7e1691194c6ff9;hpb=812e95da016e334b8856b24aba14db809da3f774;p=ardour.git diff --git a/gtk2_ardour/editor_drag.h b/gtk2_ardour/editor_drag.h index d710e3a639..ce8a1370f4 100644 --- a/gtk2_ardour/editor_drag.h +++ b/gtk2_ardour/editor_drag.h @@ -35,9 +35,14 @@ namespace ARDOUR { class Location; } +namespace PBD { + class StatefulDiffCommand; +} + namespace Gnome { namespace Canvas { class CanvasNoteEvent; + class CanvasPatchChange; } } @@ -84,7 +89,7 @@ public: } /** @return current pointer frame */ - nframes64_t current_pointer_frame () const { + ARDOUR::framepos_t current_pointer_frame () const { return _current_pointer_frame; } @@ -94,7 +99,8 @@ private: bool _ending; ///< true if end_grab or abort is in progress, otherwise false double _current_pointer_x; ///< trackview x of the current pointer double _current_pointer_y; ///< trackview y of the current pointer - nframes64_t _current_pointer_frame; ///< frame that the pointer is now at + ARDOUR::framepos_t _current_pointer_frame; ///< frame that the pointer is now at + bool _old_follow_playhead; ///< state of Editor::follow_playhead() before the drags started }; /** Abstract base class for dragging of things within the editor */ @@ -117,8 +123,8 @@ public: bool motion_handler (GdkEvent*, bool); void abort (); - nframes64_t adjusted_frame (nframes64_t, GdkEvent const *, bool snap = true) const; - nframes64_t adjusted_current_frame (GdkEvent const *, bool snap = true) const; + ARDOUR::framepos_t adjusted_frame (ARDOUR::framepos_t, GdkEvent const *, bool snap = true) const; + ARDOUR::framepos_t adjusted_current_frame (GdkEvent const *, bool snap = true) const; /** Called to start a grab of an item. * @param e Event that caused the grab to start. @@ -142,8 +148,9 @@ public: /** Called to abort a drag and return things to how * they were before it started. + * @param m true if some movement occurred, otherwise false. */ - virtual void aborted () = 0; + virtual void aborted (bool m) = 0; /** @param m Mouse mode. * @return true if this drag should happen in this mouse mode. @@ -153,7 +160,7 @@ public: } /** @return minimum number of frames (in x) and pixels (in y) that should be considered a movement */ - virtual std::pair move_threshold () const { + virtual std::pair move_threshold () const { return std::make_pair (1, 1); } @@ -171,6 +178,11 @@ public: return true; } + /** Set up the _pointer_frame_offset */ + virtual void setup_pointer_frame_offset () { + _pointer_frame_offset = 0; + } + protected: double grab_x () const { @@ -181,6 +193,10 @@ protected: return _grab_y; } + ARDOUR::framepos_t raw_grab_frame () const { + return _raw_grab_frame; + } + ARDOUR::framepos_t grab_frame () const { return _grab_frame; } @@ -201,7 +217,7 @@ protected: DragManager* _drags; ArdourCanvas::Item* _item; ///< our item /** Offset from the mouse's position for the drag to the start of the thing that is being dragged */ - nframes64_t _pointer_frame_offset; + ARDOUR::framecnt_t _pointer_frame_offset; bool _x_constrained; ///< true if x motion is constrained, otherwise false bool _y_constrained; ///< true if y motion is constrained, otherwise false bool _was_rolling; ///< true if the session was rolling before the drag started, otherwise false @@ -213,16 +229,27 @@ private: double _grab_y; ///< trackview y of the grab start position double _last_pointer_x; ///< trackview x of the pointer last time a motion occurred double _last_pointer_y; ///< trackview y of the pointer last time a motion occurred - nframes64_t _grab_frame; ///< adjusted_frame that the mouse was at when start_grab was called, or 0 - nframes64_t _last_pointer_frame; ///< adjusted_frame the last time a motion occurred + ARDOUR::framepos_t _raw_grab_frame; ///< unsnapped frame that the mouse was at when start_grab was called, or 0 + ARDOUR::framepos_t _grab_frame; ///< adjusted_frame that the mouse was at when start_grab was called, or 0 + ARDOUR::framepos_t _last_pointer_frame; ///< adjusted_frame the last time a motion occurred }; +class RegionDrag; + +/** Container for details about a region being dragged */ struct DraggingView { - DraggingView (RegionView* v); + DraggingView (RegionView *, RegionDrag *); RegionView* view; ///< the view + /** index into RegionDrag::_time_axis_views of the view that this region is currently beind displayed on */ + int time_axis_view; + /** layer that this region is currently being displayed on */ + ARDOUR::layer_t layer; double initial_y; ///< the initial y position of the view before any reparenting + framepos_t initial_position; ///< initial position of the region + framepos_t initial_end; ///< initial end position of the region + boost::shared_ptr initial_playlist; }; /** Abstract base class for drags that involve region(s) */ @@ -237,7 +264,17 @@ protected: RegionView* _primary; ///< the view that was clicked on (or whatever) to start the drag std::list _views; ///< information about all views that are being dragged + /** a list of the non-hidden TimeAxisViews sorted by editor order key */ + std::vector _time_axis_views; + int find_time_axis_view (TimeAxisView *) const; + + int _visible_y_low; + int _visible_y_high; + + friend class DraggingView; + private: + void region_going_away (RegionView *); PBD::ScopedConnection death_connection; }; @@ -254,7 +291,7 @@ public: virtual void start_grab (GdkEvent *, Gdk::Cursor *); virtual void motion (GdkEvent *, bool); virtual void finished (GdkEvent *, bool) = 0; - virtual void aborted (); + virtual void aborted (bool); /** @return true if the regions being `moved' came from somewhere on the canvas; * false if they came from outside (e.g. from the region list). @@ -262,33 +299,15 @@ public: virtual bool regions_came_from_canvas () const = 0; protected: - struct TimeAxisViewSummary { - TimeAxisViewSummary () : height_list(512) {} - - std::bitset<512> tracks; - std::vector height_list; - int visible_y_low; - int visible_y_high; - }; - - void copy_regions (GdkEvent *); - bool y_movement_disallowed (int, int, int, TimeAxisViewSummary const &) const; - std::map > find_time_axis_views_and_layers (); - double compute_x_delta (GdkEvent const *, nframes64_t *); - bool compute_y_delta ( - TimeAxisView const *, TimeAxisView*, int32_t, int32_t, TimeAxisViewSummary const &, - int32_t *, int32_t *, int32_t * - ); - TimeAxisViewSummary get_time_axis_view_summary (); - bool x_move_allowed () const; + double compute_x_delta (GdkEvent const *, ARDOUR::framecnt_t *); + bool y_movement_allowed (int, ARDOUR::layer_t) const; - TimeAxisView* _dest_trackview; - ARDOUR::layer_t _dest_layer; - bool check_possible (RouteTimeAxisView **, ARDOUR::layer_t *); bool _brushing; - nframes64_t _last_frame_position; ///< last position of the thing being dragged + ARDOUR::framepos_t _last_frame_position; ///< last position of the thing being dragged double _total_x_delta; + int _last_pointer_time_axis_view; + ARDOUR::layer_t _last_pointer_layer; }; @@ -301,31 +320,65 @@ public: RegionMoveDrag (Editor *, ArdourCanvas::Item *, RegionView *, std::list const &, bool, bool); virtual ~RegionMoveDrag () {} - virtual void start_grab (GdkEvent *, Gdk::Cursor *); void motion (GdkEvent *, bool); void finished (GdkEvent *, bool); - void aborted (); + void aborted (bool); bool regions_came_from_canvas () const { return true; } - std::pair move_threshold () const { + std::pair move_threshold () const { return std::make_pair (4, 4); } + void setup_pointer_frame_offset (); + private: + typedef std::set > PlaylistSet; + + void finished_no_copy ( + bool const, + bool const, + ARDOUR::framecnt_t const + ); + + void finished_copy ( + bool const, + bool const, + ARDOUR::framecnt_t const + ); + + RegionView* insert_region_into_playlist ( + boost::shared_ptr, + RouteTimeAxisView*, + ARDOUR::layer_t, + ARDOUR::framecnt_t, + PlaylistSet& + ); + + void remove_region_from_playlist ( + boost::shared_ptr, + boost::shared_ptr, + PlaylistSet& modified_playlists + ); + + void add_stateful_diff_commands_for_playlists (PlaylistSet const &); + + void collect_new_region_view (RegionView *); + bool _copy; + RegionView* _new_region_view; }; /** Drag to insert a region from somewhere */ class RegionInsertDrag : public RegionMotionDrag { public: - RegionInsertDrag (Editor *, boost::shared_ptr, RouteTimeAxisView*, nframes64_t); + RegionInsertDrag (Editor *, boost::shared_ptr, RouteTimeAxisView*, ARDOUR::framepos_t); void finished (GdkEvent *, bool); - void aborted (); + void aborted (bool); bool regions_came_from_canvas () const { return false; @@ -340,7 +393,7 @@ public: void motion (GdkEvent *, bool); void finished (GdkEvent *, bool); - void aborted (); + void aborted (bool); }; /** Drags to create regions */ @@ -351,11 +404,12 @@ public: void motion (GdkEvent *, bool); void finished (GdkEvent *, bool); - void aborted (); + void aborted (bool); private: MidiTimeAxisView* _view; boost::shared_ptr _region; + void add_region (); }; /** Drags to resize MIDI notes */ @@ -367,7 +421,7 @@ public: void start_grab (GdkEvent *, Gdk::Cursor* c = 0); void motion (GdkEvent *, bool); void finished (GdkEvent *, bool); - void aborted (); + void aborted (bool); private: MidiRegionView* region; @@ -384,7 +438,7 @@ class NoteDrag : public Drag void start_grab (GdkEvent *, Gdk::Cursor* c = 0); void motion (GdkEvent *, bool); void finished (GdkEvent *, bool); - void aborted (); + void aborted (bool); private: @@ -399,11 +453,33 @@ class NoteDrag : public Drag double _note_height; }; +/** Drag to move MIDI patch changes */ +class PatchChangeDrag : public Drag +{ +public: + PatchChangeDrag (Editor *, ArdourCanvas::CanvasPatchChange *, MidiRegionView *); + + void motion (GdkEvent *, bool); + void finished (GdkEvent *, bool); + void aborted (bool); + + bool y_movement_matters () const { + return false; + } + + void setup_pointer_frame_offset (); + +private: + MidiRegionView* _region_view; + ArdourCanvas::CanvasPatchChange* _patch_change; + double _cumulative_dx; +}; + /** Drag of region gain */ class RegionGainDrag : public Drag { public: - RegionGainDrag (Editor *e, ArdourCanvas::Item *i) : Drag (e, i) {} + RegionGainDrag (Editor *, ArdourCanvas::Item *); void motion (GdkEvent *, bool); void finished (GdkEvent *, bool); @@ -411,7 +487,7 @@ public: return (m == Editing::MouseGain); } - void aborted (); + void aborted (bool); }; /** Drag to trim region(s) */ @@ -429,16 +505,17 @@ public: void start_grab (GdkEvent *, Gdk::Cursor* c = 0); void motion (GdkEvent *, bool); void finished (GdkEvent *, bool); - void aborted (); + void aborted (bool); bool y_movement_matters () const { return false; } + void setup_pointer_frame_offset (); + private: Operation _operation; - bool _have_transaction; ///< true if a transaction has been started, false otherwise. Must be set true by derived class. }; /** Meter marker drag */ @@ -450,7 +527,7 @@ public: void start_grab (GdkEvent *, Gdk::Cursor* c = 0); void motion (GdkEvent *, bool); void finished (GdkEvent *, bool); - void aborted (); + void aborted (bool); bool allow_vertical_autoscroll () const { return false; @@ -459,6 +536,8 @@ public: bool y_movement_matters () const { return false; } + + void setup_pointer_frame_offset (); private: MeterMarker* _marker; @@ -474,7 +553,7 @@ public: void start_grab (GdkEvent *, Gdk::Cursor* c = 0); void motion (GdkEvent *, bool); void finished (GdkEvent *, bool); - void aborted (); + void aborted (bool); bool allow_vertical_autoscroll () const { return false; @@ -484,13 +563,15 @@ public: return false; } + void setup_pointer_frame_offset (); + private: TempoMarker* _marker; bool _copy; }; -/** Drag of a cursor */ +/** Drag of the playhead cursor */ class CursorDrag : public Drag { public: @@ -499,7 +580,7 @@ public: void start_grab (GdkEvent *, Gdk::Cursor* c = 0); void motion (GdkEvent *, bool); void finished (GdkEvent *, bool); - void aborted (); + void aborted (bool); bool active (Editing::MouseMode) { return true; @@ -512,11 +593,11 @@ public: bool y_movement_matters () const { return false; } - + private: - EditorCursor* _cursor; ///< cursor being dragged + void fake_locate (framepos_t); + bool _stop; ///< true to stop the transport on starting the drag, otherwise false - }; /** Region fade-in drag */ @@ -528,11 +609,13 @@ public: void start_grab (GdkEvent *, Gdk::Cursor* c = 0); void motion (GdkEvent *, bool); void finished (GdkEvent *, bool); - void aborted (); + void aborted (bool); bool y_movement_matters () const { return false; } + + void setup_pointer_frame_offset (); }; /** Region fade-out drag */ @@ -544,11 +627,13 @@ public: void start_grab (GdkEvent *, Gdk::Cursor* c = 0); void motion (GdkEvent *, bool); void finished (GdkEvent *, bool); - void aborted (); + void aborted (bool); bool y_movement_matters () const { return false; } + + void setup_pointer_frame_offset (); }; /** Marker drag */ @@ -561,7 +646,7 @@ public: void start_grab (GdkEvent *, Gdk::Cursor* c = 0); void motion (GdkEvent *, bool); void finished (GdkEvent *, bool); - void aborted (); + void aborted (bool); bool allow_vertical_autoscroll () const { return false; @@ -570,13 +655,14 @@ public: bool y_movement_matters () const { return false; } + + void setup_pointer_frame_offset (); private: void update_item (ARDOUR::Location *); Marker* _marker; ///< marker being dragged std::list _copied_locations; - ArdourCanvas::Line* _line; ArdourCanvas::Points _points; }; @@ -589,15 +675,15 @@ public: void start_grab (GdkEvent *, Gdk::Cursor* c = 0); void motion (GdkEvent *, bool); void finished (GdkEvent *, bool); - void aborted (); + void aborted (bool); bool active (Editing::MouseMode m); private: ControlPoint* _point; - double _time_axis_view_grab_x; - double _time_axis_view_grab_y; + double _fixed_grab_x; + double _fixed_grab_y; double _cumulative_x_drag; double _cumulative_y_drag; static double const _zero_gain_fraction; @@ -612,7 +698,7 @@ public: void start_grab (GdkEvent *, Gdk::Cursor* c = 0); void motion (GdkEvent *, bool); void finished (GdkEvent *, bool); - void aborted (); + void aborted (bool); bool active (Editing::MouseMode) { return true; @@ -621,8 +707,8 @@ public: private: AutomationLine* _line; - double _time_axis_view_grab_x; - double _time_axis_view_grab_y; + double _fixed_grab_x; + double _fixed_grab_y; uint32_t _before; uint32_t _after; double _cumulative_y_drag; @@ -637,7 +723,7 @@ public: void start_grab (GdkEvent *, Gdk::Cursor* c = 0); void motion (GdkEvent *, bool); void finished (GdkEvent *, bool); - void aborted (); + void aborted (bool); bool active (Editing::MouseMode) { return true; @@ -645,13 +731,13 @@ public: private: - ArdourCanvas::SimpleLine* _line; + ArdourCanvas::Line* _line; AudioRegionView* _arv; double _region_view_grab_x; double _cumulative_x_drag; - uint32_t _before; + float _before; uint32_t _max_x; }; @@ -659,14 +745,14 @@ private: class RubberbandSelectDrag : public Drag { public: - RubberbandSelectDrag (Editor *e, ArdourCanvas::Item *i) : Drag (e, i) {} + RubberbandSelectDrag (Editor *, ArdourCanvas::Item *); void start_grab (GdkEvent *, Gdk::Cursor* c = 0); void motion (GdkEvent *, bool); void finished (GdkEvent *, bool); - void aborted (); + void aborted (bool); - std::pair move_threshold () const { + std::pair move_threshold () const { return std::make_pair (8, 1); } }; @@ -675,24 +761,24 @@ public: class TimeFXDrag : public RegionDrag { public: - TimeFXDrag (Editor *e, ArdourCanvas::Item *i, RegionView* p, std::list const & v) : RegionDrag (e, i, p, v) {} + TimeFXDrag (Editor *, ArdourCanvas::Item *, RegionView *, std::list const &); void start_grab (GdkEvent *, Gdk::Cursor* c = 0); void motion (GdkEvent *, bool); void finished (GdkEvent *, bool); - void aborted (); + void aborted (bool); }; /** Scrub drag in audition mode */ class ScrubDrag : public Drag { public: - ScrubDrag (Editor *e, ArdourCanvas::Item *i) : Drag (e, i) {} + ScrubDrag (Editor *, ArdourCanvas::Item *); void start_grab (GdkEvent *, Gdk::Cursor* c = 0); void motion (GdkEvent *, bool); void finished (GdkEvent *, bool); - void aborted (); + void aborted (bool); }; /** Drag in range select mode */ @@ -711,7 +797,9 @@ public: void start_grab (GdkEvent *, Gdk::Cursor* c = 0); void motion (GdkEvent *, bool); void finished (GdkEvent *, bool); - void aborted (); + void aborted (bool); + + void setup_pointer_frame_offset (); private: Operation _operation; @@ -736,7 +824,7 @@ public: void start_grab (GdkEvent *, Gdk::Cursor* c = 0); void motion (GdkEvent *, bool); void finished (GdkEvent *, bool); - void aborted (); + void aborted (bool); bool allow_vertical_autoscroll () const { return false; @@ -758,12 +846,19 @@ private: class MouseZoomDrag : public Drag { public: - MouseZoomDrag (Editor* e, ArdourCanvas::Item *i) : Drag (e, i) {} + MouseZoomDrag (Editor *, ArdourCanvas::Item *); void start_grab (GdkEvent *, Gdk::Cursor* c = 0); void motion (GdkEvent *, bool); void finished (GdkEvent *, bool); - void aborted (); + void aborted (bool); + + std::pair move_threshold () const { + return std::make_pair (4, 4); + } + +private: + bool _zoom_out; }; /** Drag of a range of automation data, changing value but not position */ @@ -775,7 +870,7 @@ public: void start_grab (GdkEvent *, Gdk::Cursor* c = 0); void motion (GdkEvent *, bool); void finished (GdkEvent *, bool); - void aborted (); + void aborted (bool); bool x_movement_matters () const { return false; @@ -784,7 +879,17 @@ public: private: std::list _ranges; AutomationTimeAxisView* _atav; - boost::shared_ptr _line; + + /** A line that is part of the drag */ + struct Line { + boost::shared_ptr line; ///< the line + std::list points; ///< points to drag on the line + std::pair range; ///< the range of all points on the line, in session frames + XMLNode* state; ///< the XML state node before the drag + }; + + std::list _lines; + bool _nothing_to_drag; };