X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Feditor_drag.h;h=6267956ed7774a193c4ed3cd3ba5aa2c9a2afdb2;hb=8b5f990267622100b3a1a7ff6fa346282aca4dda;hp=7f17a228381437b60231454733fcee61192e650a;hpb=613fe6353ade9c0c6d8205b4b09dd48a0d9d617f;p=ardour.git diff --git a/gtk2_ardour/editor_drag.h b/gtk2_ardour/editor_drag.h index 7f17a22838..6267956ed7 100644 --- a/gtk2_ardour/editor_drag.h +++ b/gtk2_ardour/editor_drag.h @@ -24,7 +24,6 @@ #include #include -#include #include "ardour/types.h" @@ -42,6 +41,7 @@ namespace PBD { namespace Gnome { namespace Canvas { class CanvasNoteEvent; + class CanvasPatchChange; } } @@ -88,7 +88,7 @@ public: } /** @return current pointer frame */ - nframes64_t current_pointer_frame () const { + ARDOUR::framepos_t current_pointer_frame () const { return _current_pointer_frame; } @@ -98,7 +98,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 */ @@ -121,9 +122,9 @@ 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. * @param c Cursor to use, or 0. @@ -146,8 +147,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. @@ -157,7 +159,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); } @@ -175,6 +177,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 { @@ -205,11 +212,17 @@ protected: return _last_pointer_frame; } + boost::shared_ptr add_midi_region (MidiTimeAxisView*); + + void show_verbose_cursor_time (framepos_t); + void show_verbose_cursor_duration (framepos_t, framepos_t, double xoffset = 0); + void show_verbose_cursor_text (std::string const &); + Editor* _editor; ///< our editor 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 @@ -222,23 +235,31 @@ private: 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 ARDOUR::framepos_t _raw_grab_frame; ///< unsnapped frame that the mouse was at when start_grab was called, or 0 - 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 _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 +class DraggingView { +public: DraggingView (RegionView *, RegionDrag *); RegionView* view; ///< the view - /** index into RegionDrag::_time_axis_views of the view that this region is currently beind displayed on */ + /** index into RegionDrag::_time_axis_views of the view that this region is currently being displayed on, + * or -1 if it is not visible. + */ int time_axis_view; - /** layer that this region is currently being displayed on */ - ARDOUR::layer_t layer; + /** layer that this region is currently being displayed on. This is a double + rather than a layer_t as we use fractional layers during drags to allow the user + to indicate a new layer to put a region on. + */ + double 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; }; @@ -262,9 +283,9 @@ protected: int _visible_y_high; friend class DraggingView; - + private: - + void region_going_away (RegionView *); PBD::ScopedConnection death_connection; }; @@ -280,8 +301,8 @@ public: virtual void start_grab (GdkEvent *, Gdk::Cursor *); virtual void motion (GdkEvent *, bool); - virtual void finished (GdkEvent *, bool) = 0; - virtual void aborted (); + virtual void finished (GdkEvent *, bool); + 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). @@ -290,14 +311,14 @@ public: protected: - double compute_x_delta (GdkEvent const *, nframes64_t *); - bool y_movement_allowed (int, ARDOUR::layer_t) const; + double compute_x_delta (GdkEvent const *, ARDOUR::framepos_t *); + bool y_movement_allowed (int, double) const; 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; + double _last_pointer_layer; }; @@ -310,19 +331,20 @@ 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; @@ -355,7 +377,7 @@ private: void add_stateful_diff_commands_for_playlists (PlaylistSet const &); void collect_new_region_view (RegionView *); - + bool _copy; RegionView* _new_region_view; }; @@ -364,10 +386,10 @@ private: 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; @@ -382,7 +404,7 @@ public: void motion (GdkEvent *, bool); void finished (GdkEvent *, bool); - void aborted (); + void aborted (bool); }; /** Drags to create regions */ @@ -393,7 +415,7 @@ public: void motion (GdkEvent *, bool); void finished (GdkEvent *, bool); - void aborted (); + void aborted (bool); private: MidiTimeAxisView* _view; @@ -409,7 +431,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; @@ -426,13 +448,13 @@ 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: ARDOUR::frameoffset_t total_dx () const; int8_t total_dy () const; - + MidiRegionView* _region; Gnome::Canvas::CanvasNoteEvent* _primary; double _cumulative_dx; @@ -441,19 +463,84 @@ class NoteDrag : public Drag double _note_height; }; -/** Drag of region gain */ -class RegionGainDrag : public Drag +class NoteCreateDrag : public Drag +{ +public: + NoteCreateDrag (Editor *, ArdourCanvas::Item *, MidiRegionView *); + ~NoteCreateDrag (); + + void start_grab (GdkEvent *, Gdk::Cursor* c = 0); + void motion (GdkEvent *, bool); + void finished (GdkEvent *, bool); + void aborted (bool); + +private: + double y_to_region (double) const; + framecnt_t grid_frames (framepos_t) const; + + MidiRegionView* _region_view; + ArdourCanvas::SimpleRect* _drag_rect; + framepos_t _note[2]; +}; + +/** 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; +}; + +/** Container for details about audio regions being dragged along with video */ +class AVDraggingView { public: - RegionGainDrag (Editor *e, ArdourCanvas::Item *i) : Drag (e, i) {} + AVDraggingView (RegionView *); + + RegionView* view; ///< the view + framepos_t initial_position; ///< initial position of the region +}; + +/** Drag of video offset */ +class VideoTimeLineDrag : public Drag +{ +public: + VideoTimeLineDrag (Editor *e, ArdourCanvas::Item *i); void motion (GdkEvent *, bool); void finished (GdkEvent *, bool); - bool active (Editing::MouseMode m) { - return (m == Editing::MouseGain); + void start_grab (GdkEvent *, Gdk::Cursor* c = 0); + + bool y_movement_matters () const { + return false; } - void aborted (); + bool allow_vertical_autoscroll () const { + return false; + } + + void aborted (bool); + +protected: + std::list _views; ///< information about all audio that are being dragged along + +private: + ARDOUR::frameoffset_t _startdrag_video_offset; + ARDOUR::frameoffset_t _max_backwards_drag; }; /** Drag to trim region(s) */ @@ -466,21 +553,24 @@ public: ContentsTrim, }; - TrimDrag (Editor *, ArdourCanvas::Item *, RegionView*, std::list const &); + TrimDrag (Editor *, ArdourCanvas::Item *, RegionView*, std::list const &, bool preserve_fade_anchor = false); 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. + + bool _preserve_fade_anchor; }; /** Meter marker drag */ @@ -492,7 +582,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; @@ -501,10 +591,13 @@ public: bool y_movement_matters () const { return false; } - + + void setup_pointer_frame_offset (); + private: MeterMarker* _marker; bool _copy; + XMLNode* before_state; }; /** Tempo marker drag */ @@ -516,7 +609,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; @@ -526,13 +619,16 @@ public: return false; } + void setup_pointer_frame_offset (); + private: TempoMarker* _marker; bool _copy; + XMLNode* before_state; }; -/** Drag of a cursor */ +/** Drag of the playhead cursor */ class CursorDrag : public Drag { public: @@ -541,7 +637,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; @@ -552,13 +648,14 @@ public: } bool y_movement_matters () const { - return false; + return true; } private: - EditorCursor* _cursor; ///< cursor being dragged - bool _stop; ///< true to stop the transport on starting the drag, otherwise false + void fake_locate (framepos_t); + bool _stop; ///< true to stop the transport on starting the drag, otherwise false + double _grab_zoom; ///< editor frames per unit when our grab started }; /** Region fade-in drag */ @@ -570,11 +667,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 */ @@ -586,11 +685,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 */ @@ -603,7 +704,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; @@ -612,13 +713,23 @@ 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; + + struct CopiedLocationMarkerInfo { + ARDOUR::Location* location; + std::vector markers; + bool move_both; + CopiedLocationMarkerInfo (ARDOUR::Location* l, Marker* m); + }; + + typedef std::list CopiedLocationInfo; + CopiedLocationInfo _copied_locations; ArdourCanvas::Points _points; }; @@ -631,7 +742,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 m); @@ -642,7 +753,9 @@ private: double _fixed_grab_y; double _cumulative_x_drag; double _cumulative_y_drag; - static double const _zero_gain_fraction; + bool _pushing; + uint32_t _final_index; + static double _zero_gain_fraction; }; /** Gain or automation line drag */ @@ -654,7 +767,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; @@ -679,7 +792,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; @@ -687,13 +800,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; }; @@ -701,40 +814,93 @@ 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); } + + void do_select_things (GdkEvent *, bool); + + /** Select some things within a rectangle. + * @param button_state The button state from the GdkEvent. + * @param x1 The left-hand side of the rectangle in session frames. + * @param x2 The right-hand side of the rectangle in session frames. + * @param y1 The top of the rectangle in trackview coordinates. + * @param y2 The bottom of the rectangle in trackview coordinates. + * @param drag_in_progress true if the drag is currently happening. + */ + virtual void select_things (int button_state, framepos_t x1, framepos_t x2, double y1, double y2, bool drag_in_progress) = 0; + + virtual void deselect_things () = 0; + + protected: + bool _vertical_only; +}; + +/** A general editor RubberbandSelectDrag (for regions, automation points etc.) */ +class EditorRubberbandSelectDrag : public RubberbandSelectDrag +{ +public: + EditorRubberbandSelectDrag (Editor *, ArdourCanvas::Item *); + + void select_things (int, framepos_t, framepos_t, double, double, bool); + void deselect_things (); +}; + +/** A RubberbandSelectDrag for selecting MIDI notes */ +class MidiRubberbandSelectDrag : public RubberbandSelectDrag +{ +public: + MidiRubberbandSelectDrag (Editor *, MidiRegionView *); + + void select_things (int, framepos_t, framepos_t, double, double, bool); + void deselect_things (); + +private: + MidiRegionView* _region_view; +}; + +/** A RubberbandSelectDrag for selecting MIDI notes but with no horizonal component */ +class MidiVerticalSelectDrag : public RubberbandSelectDrag +{ +public: + MidiVerticalSelectDrag (Editor *, MidiRegionView *); + + void select_things (int, framepos_t, framepos_t, double, double, bool); + void deselect_things (); + +private: + MidiRegionView* _region_view; }; /** Region drag in time-FX mode */ 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 */ @@ -745,7 +911,8 @@ public: CreateSelection, SelectionStartTrim, SelectionEndTrim, - SelectionMove + SelectionMove, + SelectionExtend }; SelectionDrag (Editor *, ArdourCanvas::Item *, Operation); @@ -753,14 +920,20 @@ 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; - bool _copy; + bool _add; + bool _extend; int _original_pointer_time_axis; int _last_pointer_time_axis; std::list _added_time_axes; + bool _time_selection_at_start; + framepos_t start_at_start; + framepos_t end_at_start; }; /** Range marker drag */ @@ -778,7 +951,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; @@ -800,35 +973,87 @@ 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 */ +/** Drag of a range of automation data (either on an automation track or region gain), + * changing value but not position. + */ class AutomationRangeDrag : public Drag { public: - AutomationRangeDrag (Editor *, ArdourCanvas::Item *, std::list const &); + AutomationRangeDrag (Editor *, AutomationTimeAxisView *, std::list const &); + AutomationRangeDrag (Editor *, AudioRegionView *, std::list const &); 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; } + bool active (Editing::MouseMode) { + return true; + } + private: + void setup (std::list > const &); + double y_fraction (boost::shared_ptr, double global_y_position) const; + 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 + double original_fraction; ///< initial y-fraction before the drag + }; + + std::list _lines; + double y_origin; bool _nothing_to_drag; }; +/** Drag of one edge of an xfade + */ +class CrossfadeEdgeDrag : public Drag +{ + public: + CrossfadeEdgeDrag (Editor*, AudioRegionView*, ArdourCanvas::Item*, bool start); + + void start_grab (GdkEvent*, Gdk::Cursor* c = 0); + void motion (GdkEvent*, bool); + void finished (GdkEvent*, bool); + void aborted (bool); + + bool y_movement_matters () const { + return false; + } + + virtual std::pair move_threshold () const { + return std::make_pair (4, 4); + } + + private: + AudioRegionView* arv; + bool start; +}; + #endif /* __gtk2_ardour_editor_drag_h_ */