Revert internals of the last layering-related commit, and go back a slightly-cleaned...
[ardour.git] / gtk2_ardour / editor_drag.h
index e40975b5a5250c4947c4513cbfcad8570c396001..4170315294c20f7279a680ab1b27e5e719326982 100644 (file)
@@ -124,7 +124,7 @@ 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;
-       
+
        /** Called to start a grab of an item.
         *  @param e Event that caused the grab to start.
         *  @param c Cursor to use, or 0.
@@ -213,7 +213,7 @@ protected:
        }
 
        void show_verbose_cursor_time (framepos_t);
-       void show_verbose_cursor_duration (framepos_t, 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
@@ -245,10 +245,15 @@ struct DraggingView
        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
@@ -275,9 +280,9 @@ protected:
        int _visible_y_high;
 
        friend class DraggingView;
-       
+
 private:
-       
+
        void region_going_away (RegionView *);
        PBD::ScopedConnection death_connection;
 };
@@ -293,7 +298,7 @@ public:
 
        virtual void start_grab (GdkEvent *, Gdk::Cursor *);
        virtual void motion (GdkEvent *, bool);
-       virtual void finished (GdkEvent *, bool) = 0;
+       virtual void finished (GdkEvent *, bool);
        virtual void aborted (bool);
 
        /** @return true if the regions being `moved' came from somewhere on the canvas;
@@ -304,13 +309,13 @@ public:
 protected:
 
        double compute_x_delta (GdkEvent const *, ARDOUR::framecnt_t *);
-       bool y_movement_allowed (int, ARDOUR::layer_t) const;
+       bool y_movement_allowed (int, double) const;
 
        bool _brushing;
        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;
 };
 
 
@@ -369,7 +374,7 @@ private:
        void add_stateful_diff_commands_for_playlists (PlaylistSet const &);
 
        void collect_new_region_view (RegionView *);
-       
+
        bool _copy;
        RegionView* _new_region_view;
 };
@@ -447,7 +452,7 @@ class NoteDrag : public Drag
 
        ARDOUR::frameoffset_t total_dx () const;
        int8_t total_dy () const;
-       
+
        MidiRegionView* _region;
        Gnome::Canvas::CanvasNoteEvent* _primary;
        double _cumulative_dx;
@@ -456,6 +461,26 @@ class NoteDrag : public Drag
        double _note_height;
 };
 
+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
 {
@@ -515,7 +540,7 @@ public:
        }
 
        void setup_pointer_frame_offset ();
-       
+
 private:
 
        Operation _operation;
@@ -541,7 +566,7 @@ public:
        }
 
        void setup_pointer_frame_offset ();
-       
+
 private:
        MeterMarker* _marker;
        bool _copy;
@@ -567,7 +592,7 @@ public:
        }
 
        void setup_pointer_frame_offset ();
-       
+
 private:
        TempoMarker* _marker;
        bool _copy;
@@ -594,13 +619,14 @@ public:
        }
 
        bool y_movement_matters () const {
-               return false;
+               return true;
        }
-       
+
 private:
        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 */
@@ -660,7 +686,7 @@ public:
        }
 
        void setup_pointer_frame_offset ();
-       
+
 private:
        void update_item (ARDOUR::Location *);
 
@@ -689,7 +715,7 @@ private:
        double _fixed_grab_y;
        double _cumulative_x_drag;
        double _cumulative_y_drag;
-       static double const _zero_gain_fraction;
+       static double _zero_gain_fraction;
 };
 
 /** Gain or automation line drag */
@@ -736,10 +762,10 @@ private:
 
        ArdourCanvas::Line* _line;
        AudioRegionView* _arv;
-       
+
        double _region_view_grab_x;
        double _cumulative_x_drag;
-       
+
        float _before;
        uint32_t _max_x;
 };
@@ -758,6 +784,43 @@ public:
        std::pair<ARDOUR::framecnt_t, int> 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;
+};
+
+/** 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;
 };
 
 /** Region drag in time-FX mode */
@@ -890,9 +953,9 @@ private:
                std::pair<ARDOUR::framepos_t, ARDOUR::framepos_t> range; ///< the range of all points on the line, in session frames
                XMLNode* state; ///< the XML state node before the drag
        };
-       
+
        std::list<Line> _lines;
-       
+
        bool _nothing_to_drag;
 };