diff options
Diffstat (limited to 'gtk2_ardour/editor_drag.h')
-rw-r--r-- | gtk2_ardour/editor_drag.h | 456 |
1 files changed, 456 insertions, 0 deletions
diff --git a/gtk2_ardour/editor_drag.h b/gtk2_ardour/editor_drag.h new file mode 100644 index 0000000000..6a1561ab70 --- /dev/null +++ b/gtk2_ardour/editor_drag.h @@ -0,0 +1,456 @@ +/* + 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#ifndef __gtk2_ardour_editor_drag_h_ +#define __gtk2_ardour_editor_drag_h_ + +#include <list> + +#include <gdk/gdk.h> +#include <stdint.h> + +#include "ardour/types.h" + +#include "canvas.h" +#include "editor_items.h" + +namespace ARDOUR { + class Location; +} + +class Editor; +class EditorCursor; +class TimeAxisView; + +/** Abstract base class for dragging of things within the editor */ +class Drag +{ + +public: + Drag (Editor *, ArdourCanvas::Item *); + virtual ~Drag () {} + + /** @return the canvas item being dragged */ + ArdourCanvas::Item* item () const { + return _item; + } + + void swap_grab (ArdourCanvas::Item *, Gdk::Cursor *, uint32_t); + void break_drag (); + + bool motion_handler (GdkEvent*, bool); + + /** @return true if an end drag is in progress */ + bool ending () const { + 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; + } + + /** @return current pointer y position in item coordinates */ + double current_pointer_y () const { + return _current_pointer_y; + } + + /** @return current pointer frame */ + nframes64_t current_pointer_frame () const { + return _current_pointer_frame; + } + + /** Called to start a grab of an item. + * @param e Event that caused the grab to start. + * @param c Cursor to use, or 0. + */ + virtual void start_grab (GdkEvent* e, Gdk::Cursor* c = 0); + + virtual bool end_grab (GdkEvent *); + + /** Called when a drag motion has occurred. + * @param e Event describing the motion. + */ + virtual void motion (GdkEvent* e) = 0; + + /** Called when a drag has finished. + * @param e Event describing the finish. + */ + virtual void finished (GdkEvent *) = 0; + + /** @param m Mouse mode. + * @return true if this drag should happen in this mouse mode. + */ + virtual bool active (Editing::MouseMode m) { + return (m != Editing::MouseGain); + } + + /** Called when a subclass should update the editor's selection following a drag */ + virtual void update_selection () {} + +protected: + nframes64_t adjusted_current_frame () const; + + Editor* _editor; ///< our editor + ArdourCanvas::Item* _item; ///< our item + nframes64_t _pointer_frame_offset; ///< offset from the mouse's position for the drag + ///< to the start of the thing that is being dragged + nframes64_t _last_frame_position; ///< last position of the thing being dragged + nframes64_t _grab_frame; ///< frame that the mouse was at when start_grab was called, or 0 + nframes64_t _last_pointer_frame; ///< frame that the pointer was at last time a motion occurred + nframes64_t _current_pointer_frame; ///< frame that the pointer is now at + double _original_x; ///< original world x of the thing being dragged + double _original_y; ///< original world y of the thing being dragged + double _grab_x; ///< item x of the grab start position + double _grab_y; ///< item y of the grab start position + double _current_pointer_x; ///< item x of the current pointer + double _current_pointer_y; ///< item y of the current pointer + double _last_pointer_x; ///< item x of the pointer last time a motion occurred + 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 +}; + + +/** Abstract base class for drags that involve region(s) */ +class RegionDrag : public Drag, public sigc::trackable +{ +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 + std::list<RegionView*> _views; ///< all views that are being dragged + +private: + void region_going_away (RegionView *); +}; + + +/** Drags to move regions */ +class RegionMoveDrag : public RegionDrag +{ +public: + RegionMoveDrag (Editor *, ArdourCanvas::Item *, RegionView *, std::list<RegionView*> const &, bool, bool); + virtual ~RegionMoveDrag () {} + + virtual void start_grab (GdkEvent *, Gdk::Cursor *); + virtual void motion (GdkEvent *); + virtual void finished (GdkEvent *); + +protected: + + bool check_possible (RouteTimeAxisView **, ARDOUR::layer_t *); + + TimeAxisView* _source_trackview; + ARDOUR::layer_t _source_layer; + TimeAxisView* _dest_trackview; + ARDOUR::layer_t _dest_layer; + +private: + + void copy_regions (GdkEvent *); + bool y_movement_disallowed (int, int, int, int, int, std::bitset<512> const &, std::vector<int32_t> const &) const; + + bool _brushing; +}; + +/** Region drag in splice mode */ +class RegionSpliceDrag : public RegionMoveDrag +{ +public: + RegionSpliceDrag (Editor *, ArdourCanvas::Item *, RegionView *, std::list<RegionView*> const &); + + void motion (GdkEvent *); + void finished (GdkEvent *); +}; + +/** Drags to create regions */ +class RegionCreateDrag : public Drag +{ +public: + RegionCreateDrag (Editor *, ArdourCanvas::Item *, TimeAxisView *); + + void start_grab (GdkEvent *, Gdk::Cursor* c = 0); + void motion (GdkEvent *); + void finished (GdkEvent *); + +private: + TimeAxisView* _view; + + TimeAxisView* _source_trackview; + ARDOUR::layer_t _source_layer; + TimeAxisView* _dest_trackview; + ARDOUR::layer_t _dest_layer; +}; + +/** Drag of region gain */ +class RegionGainDrag : public Drag +{ +public: + RegionGainDrag (Editor *e, ArdourCanvas::Item *i) : Drag (e, i) {} + + void motion (GdkEvent *); + void finished (GdkEvent *); + bool active (Editing::MouseMode m) { + return (m == Editing::MouseGain); + } +}; + +/** Drag to trim region(s) */ +class TrimDrag : public RegionDrag +{ +public: + enum Operation { + StartTrim, + EndTrim, + ContentsTrim, + }; + + TrimDrag (Editor *, ArdourCanvas::Item *, RegionView*, std::list<RegionView*> const &); + + void start_grab (GdkEvent *, Gdk::Cursor* c = 0); + void motion (GdkEvent *); + void finished (GdkEvent *); + +private: + + Operation _operation; +}; + +/** Meter marker drag */ +class MeterMarkerDrag : public Drag +{ +public: + MeterMarkerDrag (Editor *, ArdourCanvas::Item *, bool); + + void start_grab (GdkEvent *, Gdk::Cursor* c = 0); + void motion (GdkEvent *); + void finished (GdkEvent *); + +private: + MeterMarker* _marker; +}; + +/** Tempo marker drag */ +class TempoMarkerDrag : public Drag +{ +public: + TempoMarkerDrag (Editor *, ArdourCanvas::Item *, bool); + + void start_grab (GdkEvent *, Gdk::Cursor* c = 0); + void motion (GdkEvent *); + void finished (GdkEvent *); + +private: + TempoMarker* _marker; +}; + + +/** Drag of a cursor */ +class CursorDrag : public Drag +{ +public: + CursorDrag (Editor *, ArdourCanvas::Item *, bool); + + void start_grab (GdkEvent *, Gdk::Cursor* c = 0); + void motion (GdkEvent *); + void finished (GdkEvent *); + +private: + EditorCursor* _cursor; ///< cursor being dragged + bool _stop; ///< true to stop the transport on starting the drag, otherwise false + +}; + +/** Region fade-in drag */ +class FadeInDrag : public RegionDrag +{ +public: + FadeInDrag (Editor *, ArdourCanvas::Item *, RegionView *, std::list<RegionView*> const &); + + void start_grab (GdkEvent *, Gdk::Cursor* c = 0); + void motion (GdkEvent *); + void finished (GdkEvent *); +}; + +/** Region fade-out drag */ +class FadeOutDrag : public RegionDrag +{ +public: + FadeOutDrag (Editor *, ArdourCanvas::Item *, RegionView *, std::list<RegionView*> const &); + + void start_grab (GdkEvent *, Gdk::Cursor* c = 0); + void motion (GdkEvent *); + void finished (GdkEvent *); +}; + +/** Marker drag */ +class MarkerDrag : public Drag +{ +public: + MarkerDrag (Editor *, ArdourCanvas::Item *); + ~MarkerDrag (); + + void start_grab (GdkEvent *, Gdk::Cursor* c = 0); + void motion (GdkEvent *); + void finished (GdkEvent *); + +private: + void update_item (ARDOUR::Location *); + + Marker* _marker; ///< marker being dragged + std::list<ARDOUR::Location*> _copied_locations; + ArdourCanvas::Line* _line; + ArdourCanvas::Points _points; +}; + +/** Control point drag */ +class ControlPointDrag : public Drag +{ +public: + ControlPointDrag (Editor *, ArdourCanvas::Item *); + + void start_grab (GdkEvent *, Gdk::Cursor* c = 0); + void motion (GdkEvent *); + void finished (GdkEvent *); + +private: + + ControlPoint* _point; + double _cumulative_x_drag; + double _cumulative_y_drag; + static double const _zero_gain_fraction; +}; + +/** Gain or automation line drag */ +class LineDrag : public Drag +{ +public: + LineDrag (Editor *e, ArdourCanvas::Item *i); + + void start_grab (GdkEvent *, Gdk::Cursor* c = 0); + void motion (GdkEvent *); + void finished (GdkEvent *); + +private: + + AutomationLine* _line; + uint32_t _before; + uint32_t _after; + double _cumulative_y_drag; +}; + +/** Dragging of a rubberband rectangle for selecting things */ +class RubberbandSelectDrag : public Drag +{ +public: + RubberbandSelectDrag (Editor *e, ArdourCanvas::Item *i) : Drag (e, i) {} + + void start_grab (GdkEvent *, Gdk::Cursor* c = 0); + void motion (GdkEvent *); + void finished (GdkEvent *); +}; + +/** Region drag in time-FX mode */ +class TimeFXDrag : public RegionDrag +{ +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 *); +}; + +/** Drag in range selection mode */ +class SelectionDrag : public Drag +{ +public: + enum Operation { + CreateSelection, + SelectionStartTrim, + SelectionEndTrim, + SelectionMove + }; + + SelectionDrag (Editor *, ArdourCanvas::Item *, Operation); + + void start_grab (GdkEvent *, Gdk::Cursor* c = 0); + void motion (GdkEvent *); + void finished (GdkEvent *); + +private: + Operation _operation; +}; + +/** Range marker drag */ +class RangeMarkerBarDrag : public Drag +{ +public: + enum Operation { + CreateRangeMarker, + CreateTransportMarker, + CreateCDMarker + }; + + RangeMarkerBarDrag (Editor *, ArdourCanvas::Item *, Operation); + + void start_grab (GdkEvent *, Gdk::Cursor* c = 0); + void motion (GdkEvent *); + void finished (GdkEvent *); + +private: + void update_item (ARDOUR::Location *); + + Operation _operation; + ArdourCanvas::SimpleRect* _drag_rect; +}; + +/* Drag of rectangle to set zoom */ +class MouseZoomDrag : public Drag +{ +public: + MouseZoomDrag (Editor *e, ArdourCanvas::Item *i) : Drag (e, i) {} + + void start_grab (GdkEvent *, Gdk::Cursor* c = 0); + void motion (GdkEvent *); + void finished (GdkEvent *); +}; + +#endif /* __gtk2_ardour_editor_drag_h_ */ + |