/*
- Copyright (C) 2009 Paul Davis
+ Copyright (C) 2009 Paul Davis
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
/** Abstract base class for dragging of things within the editor */
class Drag
{
-
+
public:
Drag (Editor *, ArdourCanvas::Item *);
virtual ~Drag () {}
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;
/** 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.
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
nframes64_t _pointer_frame_offset; ///< offset from the mouse's position for the drag
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
+ bool _have_transaction; ///< true if a transaction has been started, false otherwise. Must be set true by derived class.
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
};
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
std::list<RegionView*> _views; ///< all views that are being dragged
};
-/** 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:
+ struct TimeAxisViewSummary {
+ TimeAxisViewSummary () : height_list(512) {}
- bool check_possible (RouteTimeAxisView **, ARDOUR::layer_t *);
+ 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 ();
+ bool x_move_allowed () const;
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 _copy;
+};
- void copy_regions (GdkEvent *);
- bool y_movement_disallowed (int, int, int, int, int, std::bitset<512> const &, std::vector<int32_t> const &) const;
+/** Drag to insert a region from somewhere */
+class RegionInsertDrag : public RegionMotionDrag
+{
+public:
+ RegionInsertDrag (Editor *, boost::shared_ptr<ARDOUR::Region>, RouteTimeAxisView*, nframes64_t);
- bool _brushing;
+ void finished (GdkEvent *, bool);
};
/** Region drag in splice mode */
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 */
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* _dest_trackview;
};
+/** 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;
+ bool was_selected;
+};
+
/** Drag of region gain */
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);
}
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:
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 */
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;
};
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
bool _stop; ///< true to stop the transport on starting the drag, otherwise false
-
+
};
/** Region fade-in drag */
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 */
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 */
~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 *);
-
+
Marker* _marker; ///< marker being dragged
std::list<ARDOUR::Location*> _copied_locations;
ArdourCanvas::Line* _line;
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:
-
+
ControlPoint* _point;
double _cumulative_x_drag;
double _cumulative_y_drag;
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:
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 */
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:
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 */
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 */
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_ */