X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Feditor_drag.h;h=cd1b0c2474446934222a3f5cf9b3b41623fb6276;hb=23b1944beac919e80225c50400d9b2ed973ed13c;hp=724c2eb355cbc352bfec05ee2dc838bbfed8b19d;hpb=da7215e1ad6ebcf99cf5874cf676c460dcbb7ee7;p=ardour.git diff --git a/gtk2_ardour/editor_drag.h b/gtk2_ardour/editor_drag.h index 724c2eb355..cd1b0c2474 100644 --- a/gtk2_ardour/editor_drag.h +++ b/gtk2_ardour/editor_drag.h @@ -27,29 +27,46 @@ #include "ardour/types.h" -#include "canvas.h" +#include "canvas/types.h" + +#include "cursor_context.h" #include "editor_items.h" +#include "mouse_cursors.h" +#include "editing.h" namespace ARDOUR { class Location; } -namespace PBD { - class StatefulDiffCommand; +namespace ArdourCanvas { + class Item; + class Line; + class Rectangle; } -namespace Gnome { - namespace Canvas { - class CanvasNoteEvent; - class CanvasPatchChange; - } +namespace PBD { + class StatefulDiffCommand; } +class PatchChange; class Editor; class EditorCursor; class TimeAxisView; class MidiTimeAxisView; class Drag; +class NoteBase; +class RegionView; +class TimeAxisView; +class RouteTimeAxisView; +class RegionSelection; +class MidiRegionView; +class MeterMarker; +class ArdourMarker; +class TempoMarker; +class ControlPoint; +class AudioRegionView; +class AutomationLine; +class AutomationTimeAxisView; /** Class to manage current drags */ class DragManager @@ -63,11 +80,13 @@ public: void abort (); void add (Drag *); - void set (Drag *, GdkEvent *, Gdk::Cursor* c = 0); - void start_grab (GdkEvent *, Gdk::Cursor* c = 0); + void set (Drag *, GdkEvent *, Gdk::Cursor* c = MouseCursors::invalid_cursor()); + void start_grab (GdkEvent *, Gdk::Cursor* c = MouseCursors::invalid_cursor()); bool end_grab (GdkEvent *); bool have_item (ArdourCanvas::Item *) const; + void mark_double_click (); + /** @return true if an end drag or abort is in progress */ bool ending () const { return _ending; @@ -77,12 +96,12 @@ public: return !_drags.empty (); } - /** @return current pointer x position in trackview coordinates */ + /** @return current pointer x position in canvas coordinates */ double current_pointer_x () const { return _current_pointer_x; } - /** @return current pointer y position in trackview coordinates */ + /** @return current pointer y position in canvas coordinates */ double current_pointer_y () const { return _current_pointer_y; } @@ -96,8 +115,8 @@ private: Editor* _editor; std::list _drags; 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 + double _current_pointer_x; ///< canvas-coordinate space x of the current pointer + double _current_pointer_y; ///< canvas-coordinate space y of the current pointer 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 }; @@ -106,7 +125,7 @@ private: class Drag { public: - Drag (Editor *, ArdourCanvas::Item *); + Drag (Editor *, ArdourCanvas::Item *, bool trackview_only = true); virtual ~Drag () {} void set_manager (DragManager* m) { @@ -125,6 +144,9 @@ public: 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; + bool was_double_click() const { return _was_double_click; } + void set_double_click (bool yn) { _was_double_click = yn; } + /** Called to start a grab of an item. * @param e Event that caused the grab to start. * @param c Cursor to use, or 0. @@ -155,7 +177,7 @@ public: * @return true if this drag should happen in this mouse mode. */ virtual bool active (Editing::MouseMode m) { - return (m != Editing::MouseGain); + return true; } /** @return minimum number of frames (in x) and pixels (in y) that should be considered a movement */ @@ -177,6 +199,10 @@ public: return true; } + bool initially_vertical() const { + return _initially_vertical; + } + /** Set up the _pointer_frame_offset */ virtual void setup_pointer_frame_offset () { _pointer_frame_offset = 0; @@ -208,11 +234,19 @@ protected: return _last_pointer_y; } - double last_pointer_frame () const { + ARDOUR::framepos_t last_pointer_frame () const { return _last_pointer_frame; } - boost::shared_ptr add_midi_region (MidiTimeAxisView*); + ARDOUR::frameoffset_t snap_delta (guint const) const; + + double current_pointer_x () const; + double current_pointer_y () const; + + /* sets snap delta from unsnapped pos */ + void setup_snap_delta (framepos_t pos); + + boost::shared_ptr add_midi_region (MidiTimeAxisView*, bool commit); void show_verbose_cursor_time (framepos_t); void show_verbose_cursor_duration (framepos_t, framepos_t, double xoffset = 0); @@ -228,23 +262,33 @@ protected: bool _was_rolling; ///< true if the session was rolling before the drag started, otherwise false private: - + bool _trackview_only; ///< true if pointer y value should always be relative to the top of the trackview group bool _move_threshold_passed; ///< true if the move threshold has been passed, otherwise false + bool _starting_point_passed; ///< true if we called move () with first_move flag, otherwise false + bool _initially_vertical; ///< true if after move threshold is passed we appear to be moving vertically; undefined before that + bool _was_double_click; ///< true if drag initiated by a double click event double _grab_x; ///< trackview x of the grab start position - double _grab_y; ///< trackview y of the grab start position + double _grab_y; ///< y of the grab start position, possibly adjusted if _trackview_only is true 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 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 + + /* difference between some key position's snapped and unsnapped + * framepos. used for relative snap. + */ + ARDOUR::frameoffset_t _snap_delta; + CursorContext::Handle _cursor_ctx; ///< cursor change context }; class RegionDrag; /** Container for details about a region being dragged */ -struct DraggingView +class DraggingView { - DraggingView (RegionView *, RegionDrag *); +public: + DraggingView (RegionView *, RegionDrag *, TimeAxisView* original_tav); RegionView* view; ///< the view /** index into RegionDrag::_time_axis_views of the view that this region is currently being displayed on, @@ -259,7 +303,9 @@ struct DraggingView 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 + framepos_t anchored_fade_length; ///< fade_length when anchored during drag boost::shared_ptr initial_playlist; + TimeAxisView* initial_time_axis_view; }; /** Abstract base class for drags that involve region(s) */ @@ -277,9 +323,11 @@ protected: /** 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 apply_track_delta (const int start, const int delta, const int skip, const bool distance_only = false) const; int _visible_y_low; int _visible_y_high; + uint32_t _ntracks; friend class DraggingView; @@ -311,13 +359,18 @@ public: protected: double compute_x_delta (GdkEvent const *, ARDOUR::framepos_t *); - bool y_movement_allowed (int, double) const; + virtual bool y_movement_allowed (int, double, int skip_invisible = 0) const; bool _brushing; + bool _ignore_video_lock; ARDOUR::framepos_t _last_frame_position; ///< last position of the thing being dragged double _total_x_delta; int _last_pointer_time_axis_view; double _last_pointer_layer; +private: + uint32_t _ndropzone; + uint32_t _pdropzone; + uint32_t _ddropzone; }; @@ -344,9 +397,11 @@ public: void setup_pointer_frame_offset (); -private: +protected: typedef std::set > PlaylistSet; + void add_stateful_diff_commands_for_playlists (PlaylistSet const &); +private: void finished_no_copy ( bool const, bool const, @@ -373,9 +428,9 @@ private: PlaylistSet& modified_playlists ); - void add_stateful_diff_commands_for_playlists (PlaylistSet const &); void collect_new_region_view (RegionView *); + RouteTimeAxisView* create_destination_time_axis (boost::shared_ptr, TimeAxisView* original); bool _copy; RegionView* _new_region_view; @@ -406,6 +461,48 @@ public: void aborted (bool); }; +/** Region drag in ripple mode */ + +class RegionRippleDrag : public RegionMoveDrag +{ +public: + RegionRippleDrag (Editor *, ArdourCanvas::Item *, RegionView *, std::list const &); + ~RegionRippleDrag () { delete exclude; } + + void motion (GdkEvent *, bool); + void finished (GdkEvent *, bool); + void aborted (bool); +protected: + bool y_movement_allowed (int delta_track, double delta_layer, int skip_invisible = 0) const; + +private: + TimeAxisView *prev_tav; // where regions were most recently dragged from + TimeAxisView *orig_tav; // where drag started + ARDOUR::framecnt_t prev_amount; + ARDOUR::framepos_t prev_position; + ARDOUR::framecnt_t selection_length; + bool allow_moves_across_tracks; // only if all selected regions are on one track + ARDOUR::RegionList *exclude; + void add_all_after_to_views (TimeAxisView *tav, ARDOUR::framepos_t where, const RegionSelection &exclude, bool drag_in_progress); + void remove_unselected_from_views (ARDOUR::framecnt_t amount, bool move_regions); + +}; + +/** "Drag" to cut a region (action only on button release) */ +class RegionCutDrag : public Drag +{ + public: + RegionCutDrag (Editor*, ArdourCanvas::Item*, framepos_t); + ~RegionCutDrag (); + + void motion (GdkEvent*, bool); + void finished (GdkEvent*, bool); + void aborted (bool); + + private: + EditorCursor* line; +}; + /** Drags to create regions */ class RegionCreateDrag : public Drag { @@ -436,6 +533,8 @@ private: MidiRegionView* region; bool relative; bool at_front; + bool _was_selected; + double _snap_delta; }; /** Drags to move MIDI notes */ @@ -451,14 +550,14 @@ class NoteDrag : public Drag private: - ARDOUR::frameoffset_t total_dx () const; + ARDOUR::frameoffset_t total_dx (const guint) const; int8_t total_dy () const; MidiRegionView* _region; - Gnome::Canvas::CanvasNoteEvent* _primary; + NoteBase* _primary; double _cumulative_dx; double _cumulative_dy; - bool _was_selected; + bool _was_selected; double _note_height; }; @@ -473,12 +572,20 @@ public: void finished (GdkEvent *, bool); void aborted (bool); + bool active (Editing::MouseMode mode) { + return mode == Editing::MouseDraw || mode == Editing::MouseContent; + } + + bool y_movement_matters () const { + return false; + } + private: double y_to_region (double) const; - framecnt_t grid_frames (framepos_t) const; - + ARDOUR::framecnt_t grid_frames (framepos_t) const; + MidiRegionView* _region_view; - ArdourCanvas::SimpleRect* _drag_rect; + ArdourCanvas::Rectangle* _drag_rect; framepos_t _note[2]; }; @@ -486,7 +593,7 @@ private: class PatchChangeDrag : public Drag { public: - PatchChangeDrag (Editor *, ArdourCanvas::CanvasPatchChange *, MidiRegionView *); + PatchChangeDrag (Editor *, PatchChange *, MidiRegionView *); void motion (GdkEvent *, bool); void finished (GdkEvent *, bool); @@ -500,10 +607,49 @@ public: private: MidiRegionView* _region_view; - ArdourCanvas::CanvasPatchChange* _patch_change; + PatchChange* _patch_change; double _cumulative_dx; }; +/** Container for details about audio regions being dragged along with video */ +class AVDraggingView +{ +public: + 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); + void start_grab (GdkEvent *, Gdk::Cursor* c = 0); + + bool y_movement_matters () const { + return false; + } + + 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; + bool _stuck; +}; + /** Drag to trim region(s) */ class TrimDrag : public RegionDrag { @@ -514,7 +660,7 @@ 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); @@ -530,6 +676,9 @@ public: private: Operation _operation; + + bool _preserve_fade_anchor; + bool _jump_position_when_done; }; /** Meter marker drag */ @@ -591,17 +740,13 @@ private: class CursorDrag : public Drag { public: - CursorDrag (Editor *, ArdourCanvas::Item *, bool); + CursorDrag (Editor *, EditorCursor&, bool); void start_grab (GdkEvent *, Gdk::Cursor* c = 0); void motion (GdkEvent *, bool); void finished (GdkEvent *, bool); void aborted (bool); - bool active (Editing::MouseMode) { - return true; - } - bool allow_vertical_autoscroll () const { return false; } @@ -613,6 +758,7 @@ public: private: void fake_locate (framepos_t); + EditorCursor& _cursor; bool _stop; ///< true to stop the transport on starting the drag, otherwise false double _grab_zoom; ///< editor frames per unit when our grab started }; @@ -657,7 +803,7 @@ public: class MarkerDrag : public Drag { public: - MarkerDrag (Editor *, ArdourCanvas::Item *); + MarkerDrag (Editor *, ArdourCanvas::Item *); ~MarkerDrag (); void start_grab (GdkEvent *, Gdk::Cursor* c = 0); @@ -678,8 +824,17 @@ public: private: void update_item (ARDOUR::Location *); - Marker* _marker; ///< marker being dragged - std::list _copied_locations; + ArdourMarker* _marker; ///< marker being dragged + bool _selection_changed; + struct CopiedLocationMarkerInfo { + ARDOUR::Location* location; + std::vector markers; + bool move_both; + CopiedLocationMarkerInfo (ARDOUR::Location* l, ArdourMarker* m); + }; + + typedef std::list CopiedLocationInfo; + CopiedLocationInfo _copied_locations; ArdourCanvas::Points _points; }; @@ -703,6 +858,8 @@ private: double _fixed_grab_y; double _cumulative_x_drag; double _cumulative_y_drag; + bool _pushing; + uint32_t _final_index; static double _zero_gain_fraction; }; @@ -717,18 +874,14 @@ public: void finished (GdkEvent *, bool); void aborted (bool); - bool active (Editing::MouseMode) { - return true; - } - private: AutomationLine* _line; double _fixed_grab_x; double _fixed_grab_y; + double _cumulative_y_drag; uint32_t _before; uint32_t _after; - double _cumulative_y_drag; }; /** Transient feature line drags*/ @@ -742,10 +895,6 @@ public: void finished (GdkEvent *, bool); void aborted (bool); - bool active (Editing::MouseMode) { - return true; - } - private: ArdourCanvas::Line* _line; @@ -784,7 +933,7 @@ public: * @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: @@ -859,7 +1008,8 @@ public: CreateSelection, SelectionStartTrim, SelectionEndTrim, - SelectionMove + SelectionMove, + SelectionExtend }; SelectionDrag (Editor *, ArdourCanvas::Item *, Operation); @@ -873,11 +1023,11 @@ public: private: Operation _operation; - bool _copy; - int _original_pointer_time_axis; - int _last_pointer_time_axis; + bool _add; std::list _added_time_axes; bool _time_selection_at_start; + framepos_t start_at_start; + framepos_t end_at_start; }; /** Range marker drag */ @@ -885,12 +1035,14 @@ class RangeMarkerBarDrag : public Drag { public: enum Operation { + CreateSkipMarker, CreateRangeMarker, CreateTransportMarker, CreateCDMarker }; RangeMarkerBarDrag (Editor *, ArdourCanvas::Item *, Operation); + ~RangeMarkerBarDrag (); void start_grab (GdkEvent *, Gdk::Cursor* c = 0); void motion (GdkEvent *, bool); @@ -909,7 +1061,7 @@ private: void update_item (ARDOUR::Location *); Operation _operation; - ArdourCanvas::SimpleRect* _drag_rect; + ArdourCanvas::Rectangle* _drag_rect; bool _copy; }; @@ -939,7 +1091,7 @@ class AutomationRangeDrag : public Drag { public: AutomationRangeDrag (Editor *, AutomationTimeAxisView *, std::list const &); - AutomationRangeDrag (Editor *, AudioRegionView *, std::list const &); + AutomationRangeDrag (Editor *, RegionView *, std::list const &); void start_grab (GdkEvent *, Gdk::Cursor* c = 0); void motion (GdkEvent *, bool); @@ -950,13 +1102,11 @@ public: 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; + double value (boost::shared_ptr list, double x) const; + std::list _ranges; /** A line that is part of the drag */ @@ -965,11 +1115,13 @@ private: 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; - - bool _nothing_to_drag; + double _y_origin; + bool _nothing_to_drag; + bool _integral; }; /** Drag of one edge of an xfade @@ -983,13 +1135,13 @@ class CrossfadeEdgeDrag : public Drag 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 (1, 1); + return std::make_pair (4, 4); } private: