move note drag & note resize mouse handling up into the Drag/Editor infrastructure...
[ardour.git] / gtk2_ardour / editor_drag.h
index 6a1561ab708882bce6773be4e42137a0f69fd8e9..64989c96fef6373a4981eccbe81f35cedcdc9c4d 100644 (file)
@@ -61,11 +61,6 @@ public:
                return _ending;
        }
 
-       /** @return true if the first move (past any move threshold) has occurred */
-       bool first_move () const {
-               return _first_move;
-       }
-
        /** @return current pointer x position in item coordinates */
        double current_pointer_x () const {
                return _current_pointer_x;
@@ -91,13 +86,15 @@ public:
 
        /** Called when a drag motion has occurred.
         *  @param e Event describing the motion.
+        *  @param f true if this is the first movement, otherwise false.
         */
-       virtual void motion (GdkEvent* e) = 0;
+       virtual void motion (GdkEvent* e, bool f) = 0;
 
        /** Called when a drag has finished.
         *  @param e Event describing the finish.
+        *  @param m true if some movement occurred, otherwise false.
         */
-       virtual void finished (GdkEvent *) = 0;
+       virtual void finished (GdkEvent* e, bool m) = 0;
 
        /** @param m Mouse mode.
         *  @return true if this drag should happen in this mouse mode.
@@ -106,11 +103,19 @@ public:
                return (m != Editing::MouseGain);
        }
 
-       /** Called when a subclass should update the editor's selection following a drag */
-       virtual void update_selection () {}
+       /** @return true if a small threshold should be applied before a mouse movement
+        *  is considered a drag, otherwise false.
+        */
+       virtual bool apply_move_threshold () const {
+               return false;
+       }
+
+       virtual bool allow_vertical_autoscroll () const {
+               return true;
+       }
 
 protected:
-       nframes64_t adjusted_current_frame () const;
+       nframes64_t adjusted_current_frame (GdkEvent *) const;
        
        Editor* _editor; ///< our editor
        ArdourCanvas::Item* _item; ///< our item
@@ -130,15 +135,13 @@ protected:
        double _last_pointer_y; ///< item y of the pointer last time a motion occurred
        bool _x_constrained; ///< true if x motion is constrained, otherwise false
        bool _y_constrained; ///< true if y motion is constrained, otherwise false
-       bool _copy; ///< true if we're copying the things that we're dragging
        bool _was_rolling; ///< true if the session was rolling before the drag started, otherwise false
-       bool _first_move; ///< true if some movement has occurred, otherwise false
-       bool _move_threshold_passed; ///< true if the move threshold has been passed, otherwise false
-       bool _want_move_threshold; ///< true if a move threshold should be applied, otherwise false
 
 private:
        
        bool _ending; ///< true if end_grab is in progress, otherwise false
+       bool _had_movement; ///< true if movement has occurred, otherwise false
+       bool _move_threshold_passed; ///< true if the move threshold has been passed, otherwise false
 };
 
 
@@ -149,8 +152,6 @@ public:
        RegionDrag (Editor *, ArdourCanvas::Item *, RegionView *, std::list<RegionView*> const &);
        virtual ~RegionDrag () {}
 
-       void update_selection ();
-
 protected:
        
        RegionView* _primary; ///< the view that was clicked on (or whatever) to start the drag
@@ -161,32 +162,80 @@ private:
 };
 
 
-/** Drags to move regions */
-class RegionMoveDrag : public RegionDrag
+/** Drags involving region motion from somewhere */
+class RegionMotionDrag : public RegionDrag
 {
 public:
-       RegionMoveDrag (Editor *, ArdourCanvas::Item *, RegionView *, std::list<RegionView*> const &, bool, bool);
-       virtual ~RegionMoveDrag () {}
+       
+       RegionMotionDrag (Editor *, ArdourCanvas::Item *, RegionView *, std::list<RegionView*> const &, bool);
+       virtual ~RegionMotionDrag () {}
 
        virtual void start_grab (GdkEvent *, Gdk::Cursor *);
-       virtual void motion (GdkEvent *);
-       virtual void finished (GdkEvent *);
+       virtual void motion (GdkEvent *, bool);
+       virtual void finished (GdkEvent *, bool) = 0;
 
 protected:
-
-       bool check_possible (RouteTimeAxisView **, ARDOUR::layer_t *);
-
-       TimeAxisView* _source_trackview;
-       ARDOUR::layer_t _source_layer;
+       struct TimeAxisViewSummary {
+               TimeAxisViewSummary () : height_list(512) {}
+               
+               std::bitset<512> tracks;
+               std::vector<int32_t> 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<RegionView*, std::pair<RouteTimeAxisView*, int> > 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 ();
+       virtual bool x_move_allowed () const = 0;
+       
        TimeAxisView* _dest_trackview;
        ARDOUR::layer_t _dest_layer;
+       bool check_possible (RouteTimeAxisView **, ARDOUR::layer_t *);
+       bool _brushing;
+};
+
+
+/** Drags to move (or copy) regions that are already shown in the GUI to
+ *  somewhere different.
+ */
+class RegionMoveDrag : public RegionMotionDrag
+{
+public:
+       RegionMoveDrag (Editor *, ArdourCanvas::Item *, RegionView *, std::list<RegionView*> const &, bool, bool);
+       virtual ~RegionMoveDrag () {}
+
+       virtual void start_grab (GdkEvent *, Gdk::Cursor *);
+       void motion (GdkEvent *, bool);
+       void finished (GdkEvent *, bool);
+       
+       bool apply_move_threshold () const {
+               return true;
+       }
 
 private:
+       bool x_move_allowed () const;
 
-       void copy_regions (GdkEvent *);
-       bool y_movement_disallowed (int, int, int, int, int, std::bitset<512> const &, std::vector<int32_t> const &) const;
+       bool _copy;
+};
 
-       bool _brushing;
+/** Drag to insert a region from somewhere */
+class RegionInsertDrag : public RegionMotionDrag
+{
+public:
+       RegionInsertDrag (Editor *, boost::shared_ptr<ARDOUR::Region>, RouteTimeAxisView*, nframes64_t);
+
+       void finished (GdkEvent *, bool);
+       
+private:
+       bool x_move_allowed () const;
 };
 
 /** Region drag in splice mode */
@@ -195,8 +244,8 @@ class RegionSpliceDrag : public RegionMoveDrag
 public:
        RegionSpliceDrag (Editor *, ArdourCanvas::Item *, RegionView *, std::list<RegionView*> const &);
 
-       void motion (GdkEvent *);
-       void finished (GdkEvent *);
+       void motion (GdkEvent *, bool);
+       void finished (GdkEvent *, bool);
 };
 
 /** Drags to create regions */
@@ -206,16 +255,45 @@ public:
        RegionCreateDrag (Editor *, ArdourCanvas::Item *, TimeAxisView *);
 
        void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
-       void motion (GdkEvent *);
-       void finished (GdkEvent *);
+       void motion (GdkEvent *, bool);
+       void finished (GdkEvent *, bool);
 
 private:
        TimeAxisView* _view;
-
-       TimeAxisView* _source_trackview;
-       ARDOUR::layer_t _source_layer;
        TimeAxisView* _dest_trackview;
-       ARDOUR::layer_t _dest_layer;
+};
+
+/** Drags to resize MIDI notes */
+class NoteResizeDrag : public Drag
+{
+public:
+       NoteResizeDrag (Editor *, ArdourCanvas::Item *);
+
+       void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
+       void motion (GdkEvent *, bool);
+       void finished (GdkEvent *, bool);
+
+private:
+       MidiRegionView*     region;
+       bool                relative;
+       bool                at_front;
+};
+
+class NoteDrag : public Drag
+{
+  public:      
+       NoteDrag (Editor*, ArdourCanvas::Item*);
+
+       void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
+       void motion (GdkEvent *, bool);
+       void finished (GdkEvent *, bool);
+
+  private:
+       MidiRegionView* region;
+       double last_x;
+       double last_y;
+       double drag_delta_x;
+       double drag_delta_note;
 };
 
 /** Drag of region gain */
@@ -224,8 +302,8 @@ class RegionGainDrag : public Drag
 public:
        RegionGainDrag (Editor *e, ArdourCanvas::Item *i) : Drag (e, i) {}
 
-       void motion (GdkEvent *);
-       void finished (GdkEvent *);
+       void motion (GdkEvent *, bool);
+       void finished (GdkEvent *, bool);
        bool active (Editing::MouseMode m) {
                return (m == Editing::MouseGain);
        }
@@ -244,8 +322,8 @@ public:
        TrimDrag (Editor *, ArdourCanvas::Item *, RegionView*, std::list<RegionView*> const &);
 
        void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
-       void motion (GdkEvent *);
-       void finished (GdkEvent *);
+       void motion (GdkEvent *, bool);
+       void finished (GdkEvent *, bool);
 
 private:
 
@@ -259,11 +337,12 @@ public:
        MeterMarkerDrag (Editor *, ArdourCanvas::Item *, bool);
 
        void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
-       void motion (GdkEvent *);
-       void finished (GdkEvent *);
+       void motion (GdkEvent *, bool);
+       void finished (GdkEvent *, bool);
 
 private:
        MeterMarker* _marker;
+       bool _copy;
 };
 
 /** Tempo marker drag */
@@ -273,11 +352,12 @@ public:
        TempoMarkerDrag (Editor *, ArdourCanvas::Item *, bool);
 
        void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
-       void motion (GdkEvent *);
-       void finished (GdkEvent *);
+       void motion (GdkEvent *, bool);
+       void finished (GdkEvent *, bool);
 
 private:
        TempoMarker* _marker;
+       bool _copy;
 };
 
 
@@ -288,8 +368,16 @@ public:
        CursorDrag (Editor *, ArdourCanvas::Item *, bool);
 
        void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
-       void motion (GdkEvent *);
-       void finished (GdkEvent *);
+       void motion (GdkEvent *, bool);
+       void finished (GdkEvent *, bool);
+
+       bool active (Editing::MouseMode) {
+               return true;
+       }
+
+       bool allow_vertical_autoscroll () const {
+               return false;
+       }
 
 private:
        EditorCursor* _cursor; ///< cursor being dragged
@@ -304,8 +392,8 @@ public:
        FadeInDrag (Editor *, ArdourCanvas::Item *, RegionView *, std::list<RegionView*> const &);
 
        void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
-       void motion (GdkEvent *);
-       void finished (GdkEvent *);
+       void motion (GdkEvent *, bool);
+       void finished (GdkEvent *, bool);
 };
 
 /** Region fade-out drag */
@@ -315,8 +403,8 @@ public:
        FadeOutDrag (Editor *, ArdourCanvas::Item *, RegionView *, std::list<RegionView*> const &);
 
        void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
-       void motion (GdkEvent *);
-       void finished (GdkEvent *);
+       void motion (GdkEvent *, bool);
+       void finished (GdkEvent *, bool);
 };
 
 /** Marker drag */
@@ -327,8 +415,8 @@ public:
        ~MarkerDrag ();
 
        void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
-       void motion (GdkEvent *);
-       void finished (GdkEvent *);
+       void motion (GdkEvent *, bool);
+       void finished (GdkEvent *, bool);
 
 private:
        void update_item (ARDOUR::Location *);
@@ -346,8 +434,10 @@ public:
        ControlPointDrag (Editor *, ArdourCanvas::Item *);
 
        void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
-       void motion (GdkEvent *);
-       void finished (GdkEvent *);
+       void motion (GdkEvent *, bool);
+       void finished (GdkEvent *, bool);
+
+       bool active (Editing::MouseMode m);
 
 private:
        
@@ -364,8 +454,12 @@ public:
        LineDrag (Editor *e, ArdourCanvas::Item *i);
 
        void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
-       void motion (GdkEvent *);
-       void finished (GdkEvent *);
+       void motion (GdkEvent *, bool);
+       void finished (GdkEvent *, bool);
+       
+       bool active (Editing::MouseMode) {
+               return true;
+       }
 
 private:
 
@@ -382,8 +476,8 @@ public:
        RubberbandSelectDrag (Editor *e, ArdourCanvas::Item *i) : Drag (e, i) {}
 
        void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
-       void motion (GdkEvent *);
-       void finished (GdkEvent *);
+       void motion (GdkEvent *, bool);
+       void finished (GdkEvent *, bool);
 };
 
 /** Region drag in time-FX mode */
@@ -393,11 +487,22 @@ public:
        TimeFXDrag (Editor *e, ArdourCanvas::Item *i, RegionView* p, std::list<RegionView*> const & v) : RegionDrag (e, i, p, v) {}
 
        void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
-       void motion (GdkEvent *);
-       void finished (GdkEvent *);
+       void motion (GdkEvent *, bool);
+       void finished (GdkEvent *, bool);
+};
+
+/** Scrub drag in audition mode */
+class ScrubDrag : public Drag
+{
+public:
+       ScrubDrag (Editor *e, ArdourCanvas::Item *i) : Drag (e, i) {}
+       
+       void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
+       void motion (GdkEvent *, bool);
+       void finished (GdkEvent *, bool);
 };
 
-/** Drag in range selection mode */
+/** Drag in range select(gc_owner.get()) moAutomatable */
 class SelectionDrag : public Drag
 {
 public:
@@ -411,11 +516,12 @@ public:
        SelectionDrag (Editor *, ArdourCanvas::Item *, Operation);
 
        void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
-       void motion (GdkEvent *);
-       void finished (GdkEvent *);
+       void motion (GdkEvent *, bool);
+       void finished (GdkEvent *, bool);
 
 private:
        Operation _operation;
+       bool _copy;
 };
 
 /** Range marker drag */
@@ -431,14 +537,15 @@ public:
        RangeMarkerBarDrag (Editor *, ArdourCanvas::Item *, Operation);
 
        void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
-       void motion (GdkEvent *);
-       void finished (GdkEvent *);
+       void motion (GdkEvent *, bool);
+       void finished (GdkEvent *, bool);
 
 private:
        void update_item (ARDOUR::Location *);
 
        Operation _operation;
        ArdourCanvas::SimpleRect* _drag_rect;
+       bool _copy;
 };
 
 /* Drag of rectangle to set zoom */
@@ -448,8 +555,8 @@ public:
        MouseZoomDrag (Editor *e, ArdourCanvas::Item *i) : Drag (e, i) {}
 
        void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
-       void motion (GdkEvent *);
-       void finished (GdkEvent *);
+       void motion (GdkEvent *, bool);
+       void finished (GdkEvent *, bool);
 };
 
 #endif /* __gtk2_ardour_editor_drag_h_ */