X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Feditor_drag.h;h=df54c6bda7f57b39e5232fa5f7ee8dd589e23a3d;hb=746665e89cf66c5688cd584555168bb8323b824e;hp=3c1eef70f6152fb3424ccfcd074eb917fab9fa38;hpb=ad017365f7a73f8ba57f667cc1aa36478b48c50e;p=ardour.git diff --git a/gtk2_ardour/editor_drag.h b/gtk2_ardour/editor_drag.h index 3c1eef70f6..df54c6bda7 100644 --- a/gtk2_ardour/editor_drag.h +++ b/gtk2_ardour/editor_drag.h @@ -25,12 +25,26 @@ #include #include +#include "ardour/tempo.h" #include "ardour/types.h" +#include "canvas/types.h" + +#include "cursor_context.h" #include "editor_items.h" +#include "mouse_cursors.h" +#include "editing.h" +#include "track_selection.h" namespace ARDOUR { class Location; + class TempoSection; +} + +namespace ArdourCanvas { + class Item; + class Line; + class Rectangle; } namespace PBD { @@ -44,6 +58,18 @@ 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 @@ -57,12 +83,12 @@ 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 (); + void mark_double_click (); /** @return true if an end drag or abort is in progress */ bool ending () const { @@ -102,7 +128,7 @@ private: class Drag { public: - Drag (Editor *, ArdourCanvas::Item *, bool trackview_only = true); + Drag (Editor *, ArdourCanvas::Item *, bool trackview_only = true); virtual ~Drag () {} void set_manager (DragManager* m) { @@ -118,11 +144,11 @@ public: bool motion_handler (GdkEvent*, bool); void abort (); - ARDOUR::framepos_t adjusted_frame (ARDOUR::framepos_t, GdkEvent const *, bool snap = true) const; + ARDOUR::MusicFrame 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; } + 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. @@ -154,7 +180,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 */ @@ -176,6 +202,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; @@ -207,13 +237,20 @@ protected: return _last_pointer_y; } - double last_pointer_frame () const { + ARDOUR::framepos_t last_pointer_frame () const { return _last_pointer_frame; } + ARDOUR::frameoffset_t snap_delta (guint const) const; + double snap_delta_music (guint const) const; + + double current_pointer_x () const; double current_pointer_y () const; - boost::shared_ptr add_midi_region (MidiTimeAxisView*); + /* sets snap delta from unsnapped pos */ + void setup_snap_delta (ARDOUR::MusicFrame 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); @@ -231,7 +268,9 @@ protected: 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 _was_double_click; ///< true if drag initiated by a double click event + 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; ///< 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 @@ -239,6 +278,14 @@ private: 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. + */ + framepos_t _snap_delta; + double _snap_delta_music; + CursorContext::Handle _cursor_ctx; ///< cursor change context + bool _constraint_pressed; ///< if the keyboard indicated constraint modifier was pressed on start_grab() }; class RegionDrag; @@ -282,9 +329,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; @@ -315,14 +364,19 @@ public: protected: - double compute_x_delta (GdkEvent const *, ARDOUR::framepos_t *); - virtual bool y_movement_allowed (int, double) const; + double compute_x_delta (GdkEvent const *, ARDOUR::MusicFrame *); + virtual bool y_movement_allowed (int, double, int skip_invisible = 0) const; bool _brushing; - ARDOUR::framepos_t _last_frame_position; ///< last position of the thing being dragged + bool _ignore_video_lock; + ARDOUR::MusicFrame _last_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; }; @@ -357,21 +411,25 @@ private: void finished_no_copy ( bool const, bool const, - ARDOUR::framecnt_t const + ARDOUR::MusicFrame, + int32_t const ev_state ); void finished_copy ( bool const, bool const, - ARDOUR::framecnt_t const + ARDOUR::MusicFrame, + int32_t const ev_state ); RegionView* insert_region_into_playlist ( boost::shared_ptr, RouteTimeAxisView*, ARDOUR::layer_t, - ARDOUR::framecnt_t, - PlaylistSet& + ARDOUR::MusicFrame, + double quarter_note, + PlaylistSet&, + bool for_music = false ); void remove_region_from_playlist ( @@ -425,33 +483,34 @@ public: void finished (GdkEvent *, bool); void aborted (bool); protected: - bool y_movement_allowed (int delta_track, double delta_layer) const; + 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 - framecnt_t prev_amount; - framepos_t prev_position; - framecnt_t selection_length; + 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, framepos_t where, const RegionSelection &exclude, bool drag_in_progress); - void remove_unselected_from_views (framecnt_t amount, bool move_regions); + 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: +public: RegionCutDrag (Editor*, ArdourCanvas::Item*, framepos_t); ~RegionCutDrag (); + void start_grab (GdkEvent *, Gdk::Cursor* c = 0); void motion (GdkEvent*, bool); void finished (GdkEvent*, bool); void aborted (bool); - private: +private: EditorCursor* line; }; @@ -485,12 +544,14 @@ private: MidiRegionView* region; bool relative; bool at_front; + bool _was_selected; + double _snap_delta; }; /** Drags to move MIDI notes */ class NoteDrag : public Drag { - public: +public: NoteDrag (Editor*, ArdourCanvas::Item*); void start_grab (GdkEvent *, Gdk::Cursor* c = 0); @@ -498,17 +559,20 @@ class NoteDrag : public Drag void finished (GdkEvent *, bool); void aborted (bool); - private: + void setup_pointer_frame_offset (); +private: - ARDOUR::frameoffset_t total_dx () const; + double total_dx (GdkEvent * event) const; // total movement in quarter notes int8_t total_dy () const; MidiRegionView* _region; NoteBase* _primary; double _cumulative_dx; double _cumulative_dy; - bool _was_selected; + double _earliest; // earliest quarter note in note selection + bool _was_selected; double _note_height; + bool _copy; }; class NoteCreateDrag : public Drag @@ -522,15 +586,62 @@ 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; + + /** @return minimum number of frames (in x) and pixels (in y) that should be considered a movement */ + virtual std::pair move_threshold () const { + return std::make_pair (0, 0); + } + MidiRegionView* _region_view; ArdourCanvas::Rectangle* _drag_rect; framepos_t _note[2]; }; +class HitCreateDrag : public Drag +{ +public: + HitCreateDrag (Editor *, ArdourCanvas::Item *, MidiRegionView *); + ~HitCreateDrag (); + + void start_grab (GdkEvent *, Gdk::Cursor* c = 0); + void motion (GdkEvent *, bool); + 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; + ARDOUR::framecnt_t grid_frames (framepos_t) const; + + /** @return minimum number of frames (in x) and pixels (in y) that should be considered a movement */ + virtual std::pair move_threshold () const { + return std::make_pair (0, 0); + } + + MidiRegionView* _region_view; + framepos_t _last_pos; + double _y; + +}; + /** Drag to move MIDI patch changes */ class PatchChangeDrag : public Drag { @@ -589,6 +700,7 @@ protected: private: ARDOUR::frameoffset_t _startdrag_video_offset; ARDOUR::frameoffset_t _max_backwards_drag; + bool _stuck; }; /** Drag to trim region(s) */ @@ -617,7 +729,7 @@ public: private: Operation _operation; - + bool _preserve_fade_anchor; bool _jump_position_when_done; }; @@ -645,7 +757,11 @@ public: private: MeterMarker* _marker; + ARDOUR::MeterSection* _real_section; + bool _copy; + Editing::SnapType _old_snap_type; + Editing::SnapMode _old_snap_mode; XMLNode* before_state; }; @@ -665,33 +781,120 @@ public: } bool y_movement_matters () const { - return false; + return true; } void setup_pointer_frame_offset (); private: TempoMarker* _marker; + ARDOUR::TempoSection* _real_section; + bool _copy; - XMLNode* before_state; + bool _movable; + ARDOUR::Tempo _grab_bpm; + double _grab_qn; + XMLNode* _before_state; }; +/** BBT Ruler drag */ +class BBTRulerDrag : public Drag +{ +public: + BBTRulerDrag (Editor *, ArdourCanvas::Item *); + + void start_grab (GdkEvent *, Gdk::Cursor* c = 0); + void motion (GdkEvent *, bool); + void finished (GdkEvent *, bool); + void aborted (bool); -/** Drag of the playhead cursor */ -class CursorDrag : public Drag + bool allow_vertical_autoscroll () const { + return false; + } + + bool y_movement_matters () const { + return false; + } + + void setup_pointer_frame_offset (); + +private: + double _grab_qn; + ARDOUR::TempoSection* _tempo; + XMLNode* _before_state; + bool _drag_valid; +}; + +/** tempo curve twist drag */ +class TempoTwistDrag : public Drag { public: - CursorDrag (Editor *, EditorCursor&, bool); + TempoTwistDrag (Editor *, ArdourCanvas::Item *); + + void start_grab (GdkEvent *, Gdk::Cursor* c = 0); + void motion (GdkEvent *, bool); + void finished (GdkEvent *, bool); + void aborted (bool); + + bool allow_vertical_autoscroll () const { + return false; + } + + bool y_movement_matters () const { + return true; + } + + void setup_pointer_frame_offset (); + +private: + double _grab_qn; + ARDOUR::Tempo _grab_tempo; + ARDOUR::TempoSection* _tempo; + ARDOUR::TempoSection* _next_tempo; + bool _drag_valid; + XMLNode* _before_state; +}; + + +/** tempo curve twist drag */ +class TempoEndDrag : public Drag +{ +public: + TempoEndDrag (Editor *, ArdourCanvas::Item *); void start_grab (GdkEvent *, Gdk::Cursor* c = 0); void motion (GdkEvent *, bool); void finished (GdkEvent *, bool); void aborted (bool); - bool active (Editing::MouseMode) { + bool allow_vertical_autoscroll () const { + return false; + } + + bool y_movement_matters () const { return true; } + void setup_pointer_frame_offset (); + +private: + double _grab_qn; + ARDOUR::TempoSection* _tempo; + XMLNode* _before_state; + bool _drag_valid; +}; + +/** Drag of the playhead cursor */ +class CursorDrag : public Drag +{ +public: + CursorDrag (Editor *, EditorCursor&, bool); + + void start_grab (GdkEvent *, Gdk::Cursor* c = 0); + void motion (GdkEvent *, bool); + void finished (GdkEvent *, bool); + void aborted (bool); + bool allow_vertical_autoscroll () const { return false; } @@ -703,9 +906,15 @@ public: private: void fake_locate (framepos_t); - EditorCursor& _cursor; + 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 + + //used for zooming + int _last_mx; + int _last_my; + int _last_dx; + int _last_y_delta; }; /** Region fade-in drag */ @@ -748,7 +957,7 @@ public: class MarkerDrag : public Drag { public: - MarkerDrag (Editor *, ArdourCanvas::Item *); + MarkerDrag (Editor *, ArdourCanvas::Item *); ~MarkerDrag (); void start_grab (GdkEvent *, Gdk::Cursor* c = 0); @@ -769,18 +978,18 @@ public: private: void update_item (ARDOUR::Location *); - Marker* _marker; ///< marker being dragged - - struct CopiedLocationMarkerInfo { - ARDOUR::Location* location; - std::vector markers; - bool move_both; - CopiedLocationMarkerInfo (ARDOUR::Location* l, Marker* m); + 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; + typedef std::list CopiedLocationInfo; + CopiedLocationInfo _copied_locations; + ArdourCanvas::Points _points; }; /** Control point drag */ @@ -803,7 +1012,7 @@ private: double _fixed_grab_y; double _cumulative_x_drag; double _cumulative_y_drag; - bool _pushing; + bool _pushing; uint32_t _final_index; static double _zero_gain_fraction; }; @@ -819,18 +1028,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*/ @@ -844,10 +1049,6 @@ public: void finished (GdkEvent *, bool); void aborted (bool); - bool active (Editing::MouseMode) { - return true; - } - private: ArdourCanvas::Line* _line; @@ -886,7 +1087,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: @@ -977,13 +1178,10 @@ public: private: Operation _operation; bool _add; - bool _extend; - int _original_pointer_time_axis; - int _last_pointer_time_axis; - std::list _added_time_axes; + TrackSelection _track_selection_at_start; bool _time_selection_at_start; - framepos_t start_at_start; - framepos_t end_at_start; + framepos_t start_at_start; + framepos_t end_at_start; }; /** Range marker drag */ @@ -998,6 +1196,7 @@ public: }; RangeMarkerBarDrag (Editor *, ArdourCanvas::Item *, Operation); + ~RangeMarkerBarDrag (); void start_grab (GdkEvent *, Gdk::Cursor* c = 0); void motion (GdkEvent *, bool); @@ -1046,7 +1245,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); @@ -1057,13 +1256,10 @@ 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 y_fraction (boost::shared_ptr, double global_y_position) const; + double value (boost::shared_ptr list, double x) const; std::list _ranges; @@ -1073,26 +1269,27 @@ 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 + double original_fraction; ///< initial y-fraction before the drag }; std::list _lines; - double y_origin; - bool _nothing_to_drag; + double _y_origin; + bool _nothing_to_drag; + bool _integral; }; /** Drag of one edge of an xfade */ class CrossfadeEdgeDrag : public Drag { - public: +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; } @@ -1101,7 +1298,7 @@ class CrossfadeEdgeDrag : public Drag return std::make_pair (4, 4); } - private: +private: AudioRegionView* arv; bool start; };