#include "utils.h"
#include "region_gain_line.h"
#include "editor_drag.h"
+#include "audio_time_axis.h"
+#include "midi_time_axis.h"
using namespace std;
using namespace ARDOUR;
_grab_frame (0),
_last_pointer_frame (0),
_current_pointer_frame (0),
- _copy (false)
+ _had_movement (false),
+ _move_threshold_passed (false)
{
}
_current_pointer_y = _grab_y;
_last_pointer_x = _current_pointer_x;
_last_pointer_y = _current_pointer_y;
- _first_move = true;
- _move_threshold_passed = false;
- _want_move_threshold = false;
_original_x = 0;
_original_y = 0;
}
}
-/* @param event GDK event, or 0 */
+/** @param event GDK event, or 0.
+ * @return true if some movement occurred, otherwise false.
+ */
bool
Drag::end_grab (GdkEvent* event)
{
_ending = true;
- bool did_drag = false;
-
_editor->stop_canvas_autoscroll ();
_item->ungrab (event ? event->button.time : 0);
- if (event) {
- _last_pointer_x = _current_pointer_x;
- _last_pointer_y = _current_pointer_y;
- finished (event);
- }
-
- did_drag = !_first_move;
+ _last_pointer_x = _current_pointer_x;
+ _last_pointer_y = _current_pointer_y;
+ finished (event, _had_movement);
_editor->hide_verbose_canvas_cursor();
_ending = false;
- update_selection ();
-
- return did_drag;
+ return _had_movement;
}
nframes64_t
-Drag::adjusted_current_frame () const
+Drag::adjusted_current_frame (GdkEvent* event) const
{
+ nframes64_t pos = 0;
+
if (_current_pointer_frame > _pointer_frame_offset) {
- return _current_pointer_frame - _pointer_frame_offset;
+ pos = _current_pointer_frame - _pointer_frame_offset;
}
- return 0;
+ _editor->snap_to_with_modifier (pos, event);
+
+ return pos;
}
bool
_current_pointer_frame = _editor->event_frame (event, &_current_pointer_x, &_current_pointer_y);
if (!from_autoscroll && !_move_threshold_passed) {
- bool xp = (::llabs ((nframes64_t) (_current_pointer_x - _grab_x)) > 4LL);
- bool yp = (::llabs ((nframes64_t) (_current_pointer_y - _grab_y)) > 4LL);
+
+ bool const xp = (::llabs ((nframes64_t) (_current_pointer_x - _grab_x)) > 4LL);
+ bool const yp = (::llabs ((nframes64_t) (_current_pointer_y - _grab_y)) > 4LL);
_move_threshold_passed = (xp || yp);
+
+ if (apply_move_threshold() && _move_threshold_passed) {
- if (_want_move_threshold && _move_threshold_passed) {
_grab_frame = _current_pointer_frame;
_grab_x = _current_pointer_x;
_grab_y = _current_pointer_y;
_last_pointer_frame = _grab_frame;
_pointer_frame_offset = _grab_frame - _last_frame_position;
+
}
}
+ bool old_had_movement = _had_movement;
+
+ /* a motion event has happened, so we've had movement... */
+ _had_movement = true;
+
+ /* ... unless we're using a move threshold and we've not yet passed it */
+ if (apply_move_threshold() && !_move_threshold_passed) {
+ _had_movement = false;
+ }
+
if (active (_editor->mouse_mode)) {
if (event->motion.state & Gdk::BUTTON1_MASK || event->motion.state & Gdk::BUTTON2_MASK) {
if (!from_autoscroll) {
- _editor->maybe_autoscroll (&event->motion);
+ _editor->maybe_autoscroll (&event->motion, allow_vertical_autoscroll ());
}
- motion (event);
+ motion (event, _had_movement != old_had_movement);
return true;
}
}
_views.remove (v);
}
-void
-RegionDrag::update_selection ()
-{
- list<Selectable*> s;
- copy (_views.begin(), _views.end(), back_inserter (s));
- _editor->selection->set (s);
-}
-
-RegionMoveDrag::RegionMoveDrag (Editor* e, ArdourCanvas::Item* i, RegionView* p, list<RegionView*> const & v, bool b, bool c)
+RegionMotionDrag::RegionMotionDrag (Editor* e, ArdourCanvas::Item* i, RegionView* p, list<RegionView*> const & v, bool b)
: RegionDrag (e, i, p, v),
+ _dest_trackview (0),
+ _dest_layer (0),
_brushing (b)
{
- _want_move_threshold = true;
- _copy = c;
- _source_trackview = &_primary->get_time_axis_view ();
- _source_layer = _primary->region()->layer ();
- _dest_trackview = _source_trackview;
- _dest_layer = _source_layer;
-
- double speed = 1;
- RouteTimeAxisView* tv = dynamic_cast<RouteTimeAxisView*> (_source_trackview);
- if (tv && tv->is_track()) {
- speed = tv->get_diskstream()->speed ();
- }
-
- _last_frame_position = static_cast<nframes64_t> (_primary->region()->position() / speed);
}
+
void
-RegionMoveDrag::start_grab (GdkEvent* event, Gdk::Cursor *)
+RegionMotionDrag::start_grab (GdkEvent* event, Gdk::Cursor *)
{
Drag::start_grab (event);
- _pointer_frame_offset = _grab_frame - _last_frame_position;
_editor->show_verbose_time_cursor (_last_frame_position, 10);
}
-void
-RegionMoveDrag::motion (GdkEvent* event)
+RegionMotionDrag::TimeAxisViewSummary
+RegionMotionDrag::get_time_axis_view_summary ()
{
- double x_delta;
- double y_delta = 0;
- nframes64_t pending_region_position = 0;
- int32_t pointer_order_span = 0, canvas_pointer_order_span = 0;
- int32_t pointer_layer_span = 0;
-
- bool clamp_y_axis = false;
- vector<int32_t>::iterator j;
+ int32_t children = 0;
+ TimeAxisViewSummary sum;
- if (_copy && _move_threshold_passed && _want_move_threshold) {
- copy_regions (event);
- _want_move_threshold = false; // don't copy again
- }
-
- /* *pointer* variables reflect things about the pointer; as we may be moving
- multiple regions, much detail must be computed per-region */
+ _editor->visible_order_range (&sum.visible_y_low, &sum.visible_y_high);
+
+ /* get a bitmask representing the visible tracks */
- /* current_pointer_view will become the TimeAxisView that we're currently pointing at, and
- current_pointer_layer the current layer on that TimeAxisView */
- RouteTimeAxisView* current_pointer_view;
- layer_t current_pointer_layer;
- if (!check_possible (¤t_pointer_view, ¤t_pointer_layer)) {
- return;
+ for (Editor::TrackViewList::iterator i = _editor->track_views.begin(); i != _editor->track_views.end(); ++i) {
+ RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*> (*i);
+ TimeAxisView::Children children_list;
+
+ /* zeroes are audio/MIDI tracks. ones are other types. */
+
+ if (!rtv->hidden()) {
+
+ if (!rtv->is_track()) {
+ /* not an audio nor MIDI track */
+ sum.tracks = sum.tracks |= (0x01 << rtv->order());
+ }
+
+ sum.height_list[rtv->order()] = (*i)->current_height();
+ children = 1;
+
+ if ((children_list = rtv->get_child_list()).size() > 0) {
+ for (TimeAxisView::Children::iterator j = children_list.begin(); j != children_list.end(); ++j) {
+ sum.tracks = sum.tracks |= (0x01 << (rtv->order() + children));
+ sum.height_list[rtv->order() + children] = (*j)->current_height();
+ children++;
+ }
+ }
+ }
}
- /* TimeAxisView that we were pointing at last time we entered this method */
- TimeAxisView const * const last_pointer_view = _dest_trackview;
- /* the order of the track that we were pointing at last time we entered this method */
- int32_t const last_pointer_order = last_pointer_view->order ();
- /* the layer that we were pointing at last time we entered this method */
- layer_t const last_pointer_layer = _dest_layer;
-
- /************************************************************
- Y DELTA COMPUTATION
- ************************************************************/
+ return sum;
+}
- /* Height of TimeAxisViews, indexed by order */
- /* XXX: hard-coded limit of TimeAxisViews */
- vector<int32_t> height_list (512);
-
+bool
+RegionMotionDrag::compute_y_delta (
+ TimeAxisView const * last_pointer_view, TimeAxisView* current_pointer_view,
+ int32_t last_pointer_layer, int32_t current_pointer_layer,
+ TimeAxisViewSummary const & tavs,
+ int32_t* pointer_order_span, int32_t* pointer_layer_span,
+ int32_t* canvas_pointer_order_span
+ )
+{
if (_brushing) {
- clamp_y_axis = true;
- pointer_order_span = 0;
- goto y_axis_done;
+ *pointer_order_span = 0;
+ *pointer_layer_span = 0;
+ return true;
}
+ bool clamp_y_axis = false;
+
/* the change in track order between this callback and the last */
- pointer_order_span = last_pointer_view->order() - current_pointer_view->order();
+ *pointer_order_span = last_pointer_view->order() - current_pointer_view->order();
/* the change in layer between this callback and the last;
only meaningful if pointer_order_span == 0 (ie we've not moved tracks) */
- pointer_layer_span = last_pointer_layer - current_pointer_layer;
+ *pointer_layer_span = last_pointer_layer - current_pointer_layer;
- if (pointer_order_span != 0) {
-
- int32_t children = 0;
- /* XXX: hard-coded limit of tracks */
- bitset <512> tracks (0x00);
-
- int visible_y_high;
- int visible_y_low;
- _editor->visible_order_range (&visible_y_low, &visible_y_high);
-
- /* get a bitmask representing the visible tracks */
-
- for (Editor::TrackViewList::iterator i = _editor->track_views.begin(); i != _editor->track_views.end(); ++i) {
- RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*> (*i);
- TimeAxisView::Children children_list;
-
- /* zeroes are audio/MIDI tracks. ones are other types. */
-
- if (!rtv->hidden()) {
-
- if (!rtv->is_track()) {
- /* not an audio nor MIDI track */
- tracks = tracks |= (0x01 << rtv->order());
- }
-
- height_list[rtv->order()] = (*i)->current_height();
- children = 1;
+ if (*pointer_order_span != 0) {
- if ((children_list = rtv->get_child_list()).size() > 0) {
- for (TimeAxisView::Children::iterator j = children_list.begin(); j != children_list.end(); ++j) {
- tracks = tracks |= (0x01 << (rtv->order() + children));
- height_list[rtv->order() + children] = (*j)->current_height();
- children++;
- }
- }
- }
- }
-
/* find the actual pointer span, in terms of the number of visible tracks;
to do this, we reduce |pointer_order_span| by the number of hidden tracks
over the span */
- canvas_pointer_order_span = pointer_order_span;
+ *canvas_pointer_order_span = *pointer_order_span;
if (last_pointer_view->order() >= current_pointer_view->order()) {
for (int32_t y = current_pointer_view->order(); y < last_pointer_view->order(); y++) {
- if (height_list[y] == 0) {
- canvas_pointer_order_span--;
+ if (tavs.height_list[y] == 0) {
+ *canvas_pointer_order_span--;
}
}
} else {
for (int32_t y = last_pointer_view->order(); y <= current_pointer_view->order(); y++) {
- if (height_list[y] == 0) {
- canvas_pointer_order_span++;
+ if (tavs.height_list[y] == 0) {
+ *canvas_pointer_order_span++;
}
}
}
- for (list<RegionView*>::const_iterator i = _editor->selection->regions.by_layer().begin(); i != _editor->selection->regions.by_layer().end(); ++i) {
+ for (list<RegionView*>::const_iterator i = _views.begin(); i != _views.end(); ++i) {
RegionView* rv = (*i);
assert (tvp.first);
RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*> (tvp.first);
- /* I know this method has a slightly excessive argument list, but I think
- it's nice to separate the code out all the same, since it has such a
- simple result, and it makes it clear that there are no other
- side-effects.
- */
-
/* XXX: not sure that we should be passing canvas_pointer_order_span in here,
as surely this is a per-region thing... */
clamp_y_axis = y_movement_disallowed (
- rtv->order(), last_pointer_order, canvas_pointer_order_span, visible_y_low, visible_y_high,
- tracks, height_list
+ rtv->order(), last_pointer_view->order(), *canvas_pointer_order_span, tavs
);
if (clamp_y_axis) {
}
}
- y_axis_done:
if (!clamp_y_axis) {
_dest_trackview = current_pointer_view;
_dest_layer = current_pointer_layer;
}
-
- /************************************************************
- X DELTA COMPUTATION
- ************************************************************/
+ return clamp_y_axis;
+}
+
+
+double
+RegionMotionDrag::compute_x_delta (GdkEvent const * event, nframes64_t* pending_region_position)
+{
+ *pending_region_position = 0;
+
/* compute the amount of pointer motion in frames, and where
the region would be if we moved it by that much.
*/
- if (_move_threshold_passed) {
+ if (_current_pointer_frame >= _pointer_frame_offset) {
- if (_current_pointer_frame >= _pointer_frame_offset) {
-
- nframes64_t sync_frame;
- nframes64_t sync_offset;
- int32_t sync_dir;
-
- pending_region_position = _current_pointer_frame - _pointer_frame_offset;
-
- sync_offset = _primary->region()->sync_offset (sync_dir);
-
- /* we don't handle a sync point that lies before zero.
- */
- if (sync_dir >= 0 || (sync_dir < 0 && pending_region_position >= sync_offset)) {
- sync_frame = pending_region_position + (sync_dir*sync_offset);
-
- /* we snap if the snap modifier is not enabled.
- */
-
- if (!Keyboard::modifier_state_contains (event->button.state, Keyboard::snap_modifier())) {
- _editor->snap_to (sync_frame);
- }
-
- pending_region_position = _primary->region()->adjust_to_sync (sync_frame);
-
- } else {
- pending_region_position = _last_frame_position;
- }
-
+ nframes64_t sync_frame;
+ nframes64_t sync_offset;
+ int32_t sync_dir;
+
+ *pending_region_position = _current_pointer_frame - _pointer_frame_offset;
+
+ sync_offset = _primary->region()->sync_offset (sync_dir);
+
+ /* we don't handle a sync point that lies before zero.
+ */
+ if (sync_dir >= 0 || (sync_dir < 0 && *pending_region_position >= sync_offset)) {
+
+ sync_frame = *pending_region_position + (sync_dir*sync_offset);
+
+ _editor->snap_to_with_modifier (sync_frame, event);
+
+ *pending_region_position = _primary->region()->adjust_to_sync (sync_frame);
+
} else {
- pending_region_position = 0;
- }
-
- if (pending_region_position > max_frames - _primary->region()->length()) {
- pending_region_position = _last_frame_position;
+ *pending_region_position = _last_frame_position;
}
+
+ }
+
+ if (*pending_region_position > max_frames - _primary->region()->length()) {
+ *pending_region_position = _last_frame_position;
+ }
- bool x_move_allowed;
+ double x_delta = 0;
+
+ if ((*pending_region_position != _last_frame_position) && x_move_allowed ()) {
- if (Config->get_edit_mode() == Lock) {
- if (_copy) {
- x_move_allowed = !_x_constrained;
- } else {
- /* in locked edit mode, reverse the usual meaning of _x_constrained */
- x_move_allowed = _x_constrained;
+ /* now compute the canvas unit distance we need to move the regionview
+ to make it appear at the new location.
+ */
+
+ x_delta = (static_cast<double> (*pending_region_position) - _last_frame_position) / _editor->frames_per_unit;
+
+ if (*pending_region_position <= _last_frame_position) {
+
+ for (list<RegionView*>::const_iterator i = _views.begin(); i != _views.end(); ++i) {
+
+ RegionView* rv = (*i);
+
+ // If any regionview is at zero, we need to know so we can stop further leftward motion.
+
+ double ix1, ix2, iy1, iy2;
+ rv->get_canvas_frame()->get_bounds (ix1, iy1, ix2, iy2);
+ rv->get_canvas_frame()->i2w (ix1, iy1);
+
+ if (-x_delta > ix1 + _editor->horizontal_adjustment.get_value()) {
+ x_delta = 0;
+ *pending_region_position = _last_frame_position;
+ break;
+ }
}
- } else {
- x_move_allowed = !_x_constrained;
+
}
+
+ _last_frame_position = *pending_region_position;
+ }
- if (( pending_region_position != _last_frame_position) && x_move_allowed ) {
+ return x_delta;
+}
- /* now compute the canvas unit distance we need to move the regionview
- to make it appear at the new location.
- */
+void
+RegionMotionDrag::motion (GdkEvent* event, bool first_move)
+{
+ double y_delta = 0;
- if (pending_region_position > _last_frame_position) {
- x_delta = ((double) (pending_region_position - _last_frame_position) / _editor->frames_per_unit);
- } else {
- x_delta = -((double) (_last_frame_position - pending_region_position) / _editor->frames_per_unit);
- for (list<RegionView*>::const_iterator i = _views.begin(); i != _views.end(); ++i) {
+ TimeAxisViewSummary tavs = get_time_axis_view_summary ();
- RegionView* rv = (*i);
+ vector<int32_t>::iterator j;
- // If any regionview is at zero, we need to know so we can stop further leftward motion.
-
- double ix1, ix2, iy1, iy2;
- rv->get_canvas_frame()->get_bounds (ix1, iy1, ix2, iy2);
- rv->get_canvas_frame()->i2w (ix1, iy1);
+ /* *pointer* variables reflect things about the pointer; as we may be moving
+ multiple regions, much detail must be computed per-region */
- if (-x_delta > ix1 + _editor->horizontal_adjustment.get_value()) {
- x_delta = 0;
- pending_region_position = _last_frame_position;
- break;
- }
- }
+ /* current_pointer_view will become the TimeAxisView that we're currently pointing at, and
+ current_pointer_layer the current layer on that TimeAxisView; in this code layer numbers
+ are with respect to how the view's layers are displayed; if we are in Overlaid mode, layer
+ is always 0 regardless of what the region's "real" layer is */
+ RouteTimeAxisView* current_pointer_view;
+ layer_t current_pointer_layer;
+ if (!check_possible (¤t_pointer_view, ¤t_pointer_layer)) {
+ return;
+ }
- }
-
- _last_frame_position = pending_region_position;
+ /* TimeAxisView that we were pointing at last time we entered this method */
+ TimeAxisView const * const last_pointer_view = _dest_trackview;
+ /* the order of the track that we were pointing at last time we entered this method */
+ int32_t const last_pointer_order = last_pointer_view->order ();
+ /* the layer that we were pointing at last time we entered this method */
+ layer_t const last_pointer_layer = _dest_layer;
- } else {
- x_delta = 0;
- }
+ int32_t pointer_order_span;
+ int32_t pointer_layer_span;
+ int32_t canvas_pointer_order_span;
+
+ bool const clamp_y_axis = compute_y_delta (
+ last_pointer_view, current_pointer_view,
+ last_pointer_layer, current_pointer_layer, tavs,
+ &pointer_order_span, &pointer_layer_span,
+ &canvas_pointer_order_span
+ );
- } else {
- /* threshold not passed */
+ nframes64_t pending_region_position;
+ double const x_delta = compute_x_delta (event, &pending_region_position);
- x_delta = 0;
- }
-
/*************************************************************
PREPARE TO MOVE
************************************************************/
/*************************************************************
MOTION
************************************************************/
- bool do_move = true;
- if (_first_move) {
- if (!_move_threshold_passed) {
- do_move = false;
- }
- }
-
- if (do_move) {
- pair<set<boost::shared_ptr<Playlist> >::iterator,bool> insert_result;
+ pair<set<boost::shared_ptr<Playlist> >::iterator,bool> insert_result;
+
+ for (list<RegionView*>::const_iterator i = _views.begin(); i != _views.end(); ++i) {
- for (list<RegionView*>::const_iterator i = _views.begin(); i != _views.end(); ++i) {
-
- RegionView* rv = (*i);
-
- if (rv->region()->locked()) {
- continue;
- }
-
- /* here we are calculating the y distance from the
- top of the first track view to the top of the region
- area of the track view that we're working on */
-
- /* this x value is just a dummy value so that we have something
- to pass to i2w () */
-
- double ix1 = 0;
-
- /* distance from the top of this track view to the region area
- of our track view is always 1 */
+ RegionView* rv = (*i);
+
+ if (rv->region()->locked()) {
+ continue;
+ }
+
+ /* here we are calculating the y distance from the
+ top of the first track view to the top of the region
+ area of the track view that we're working on */
+
+ /* this x value is just a dummy value so that we have something
+ to pass to i2w () */
+
+ double ix1 = 0;
+
+ /* distance from the top of this track view to the region area
+ of our track view is always 1 */
+
+ double iy1 = 1;
+
+ /* convert to world coordinates, ie distance from the top of
+ the ruler section */
+
+ rv->get_canvas_frame()->i2w (ix1, iy1);
+
+ /* compensate for the ruler section and the vertical scrollbar position */
+ iy1 += _editor->get_trackview_group_vertical_offset ();
+
+ if (first_move) {
- double iy1 = 1;
-
- /* convert to world coordinates, ie distance from the top of
- the ruler section */
+ // hide any dependent views
- rv->get_canvas_frame()->i2w (ix1, iy1);
-
- /* compensate for the ruler section and the vertical scrollbar position */
- iy1 += _editor->get_trackview_group_vertical_offset ();
-
- if (_first_move) {
-
- // hide any dependent views
-
- rv->get_time_axis_view().hide_dependent_views (*rv);
-
- /*
- reparent to a non scrolling group so that we can keep the
- region selection above all time axis views.
- reparenting means we have to move the rv as the two
- parent groups have different coordinates.
- */
-
- rv->get_canvas_group()->property_y() = iy1 - 1;
- rv->get_canvas_group()->reparent(*(_editor->_region_motion_group));
-
- rv->fake_set_opaque (true);
+ rv->get_time_axis_view().hide_dependent_views (*rv);
+
+ /*
+ reparent to a non scrolling group so that we can keep the
+ region selection above all time axis views.
+ reparenting means we have to move the rv as the two
+ parent groups have different coordinates.
+ */
+
+ rv->get_canvas_group()->property_y() = iy1 - 1;
+ rv->get_canvas_group()->reparent(*(_editor->_region_motion_group));
+
+ rv->fake_set_opaque (true);
+ }
+
+ /* current view for this particular region */
+ pair<TimeAxisView*, int> pos = _editor->trackview_by_y_position (iy1);
+ RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*> (pos.first);
+
+ if (pointer_order_span != 0 && !clamp_y_axis) {
+
+ /* INTER-TRACK MOVEMENT */
+
+ /* move through the height list to the track that the region is currently on */
+ vector<int32_t>::iterator j = tavs.height_list.begin ();
+ int32_t x = 0;
+ while (j != tavs.height_list.end () && x != rtv->order ()) {
+ ++x;
+ ++j;
}
-
- /* current view for this particular region */
- pair<TimeAxisView*, int> pos = _editor->trackview_by_y_position (iy1);
- RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*> (pos.first);
-
- if (pointer_order_span != 0 && !clamp_y_axis) {
-
- /* INTER-TRACK MOVEMENT */
-
- /* move through the height list to the track that the region is currently on */
- vector<int32_t>::iterator j = height_list.begin ();
- int32_t x = 0;
- while (j != height_list.end () && x != rtv->order ()) {
- ++x;
- ++j;
+
+ y_delta = 0;
+ int32_t temp_pointer_order_span = canvas_pointer_order_span;
+
+ if (j != tavs.height_list.end ()) {
+
+ /* Account for layers in the original and
+ destination tracks. If we're moving around in layers we assume
+ that only one track is involved, so it's ok to use *pointer*
+ variables here. */
+
+ StreamView* lv = last_pointer_view->view ();
+ assert (lv);
+
+ /* move to the top of the last trackview */
+ if (lv->layer_display () == Stacked) {
+ y_delta -= (lv->layers() - last_pointer_layer - 1) * lv->child_height ();
}
-
- y_delta = 0;
- int32_t temp_pointer_order_span = canvas_pointer_order_span;
-
- if (j != height_list.end ()) {
-
- /* Account for layers in the original and
- destination tracks. If we're moving around in layers we assume
- that only one track is involved, so it's ok to use *pointer*
- variables here. */
-
- StreamView* lv = last_pointer_view->view ();
- assert (lv);
-
- /* move to the top of the last trackview */
- if (lv->layer_display () == Stacked) {
- y_delta -= (lv->layers() - last_pointer_layer - 1) * lv->child_height ();
- }
- StreamView* cv = current_pointer_view->view ();
- assert (cv);
+ StreamView* cv = current_pointer_view->view ();
+ assert (cv);
- /* move to the right layer on the current trackview */
- if (cv->layer_display () == Stacked) {
- y_delta += (cv->layers() - current_pointer_layer - 1) * cv->child_height ();
+ /* move to the right layer on the current trackview */
+ if (cv->layer_display () == Stacked) {
+ y_delta += (cv->layers() - current_pointer_layer - 1) * cv->child_height ();
+ }
+
+ /* And for being on a non-topmost layer on the new
+ track */
+
+ while (temp_pointer_order_span > 0) {
+ /* we're moving up canvas-wise,
+ so we need to find the next track height
+ */
+ if (j != tavs.height_list.begin()) {
+ j--;
}
-
- /* And for being on a non-topmost layer on the new
- track */
-
- while (temp_pointer_order_span > 0) {
- /* we're moving up canvas-wise,
- so we need to find the next track height
- */
- if (j != height_list.begin()) {
- j--;
- }
-
- if (x != last_pointer_order) {
- if ((*j) == 0) {
- ++temp_pointer_order_span;
- }
+
+ if (x != last_pointer_order) {
+ if ((*j) == 0) {
+ ++temp_pointer_order_span;
}
-
- y_delta -= (*j);
- temp_pointer_order_span--;
}
-
- while (temp_pointer_order_span < 0) {
-
- y_delta += (*j);
-
- if (x != last_pointer_order) {
- if ((*j) == 0) {
- --temp_pointer_order_span;
- }
- }
-
- if (j != height_list.end()) {
- j++;
+
+ y_delta -= (*j);
+ temp_pointer_order_span--;
+ }
+
+ while (temp_pointer_order_span < 0) {
+
+ y_delta += (*j);
+
+ if (x != last_pointer_order) {
+ if ((*j) == 0) {
+ --temp_pointer_order_span;
}
-
- temp_pointer_order_span++;
}
-
- /* find out where we'll be when we move and set height accordingly */
-
- pair<TimeAxisView*, int> const pos = _editor->trackview_by_y_position (iy1 + y_delta);
- RouteTimeAxisView const * temp_rtv = dynamic_cast<RouteTimeAxisView*> (pos.first);
- rv->set_height (temp_rtv->view()->child_height());
-
- /* if you un-comment the following, the region colours will follow
- the track colours whilst dragging; personally
- i think this can confuse things, but never mind.
- */
+ if (j != tavs.height_list.end()) {
+ j++;
+ }
- //const GdkColor& col (temp_rtv->view->get_region_color());
- //rv->set_color (const_cast<GdkColor&>(col));
+ temp_pointer_order_span++;
}
+
+
+ /* find out where we'll be when we move and set height accordingly */
+
+ pair<TimeAxisView*, int> const pos = _editor->trackview_by_y_position (iy1 + y_delta);
+ RouteTimeAxisView const * temp_rtv = dynamic_cast<RouteTimeAxisView*> (pos.first);
+ rv->set_height (temp_rtv->view()->child_height());
+
+ /* if you un-comment the following, the region colours will follow
+ the track colours whilst dragging; personally
+ i think this can confuse things, but never mind.
+ */
+
+ //const GdkColor& col (temp_rtv->view->get_region_color());
+ //rv->set_color (const_cast<GdkColor&>(col));
}
+ }
+
+ if (pointer_order_span == 0 && pointer_layer_span != 0 && !clamp_y_axis) {
+
+ /* INTER-LAYER MOVEMENT in the same track */
+ y_delta = rtv->view()->child_height () * pointer_layer_span;
+ }
+
+
+ if (_brushing) {
+ _editor->mouse_brush_insert_region (rv, pending_region_position);
+ } else {
+ rv->move (x_delta, y_delta);
+ }
+
+ } /* foreach region */
- if (pointer_order_span == 0 && pointer_layer_span != 0 && !clamp_y_axis) {
-
- /* INTER-LAYER MOVEMENT in the same track */
- y_delta = rtv->view()->child_height () * pointer_layer_span;
- }
-
-
- if (_brushing) {
- _editor->mouse_brush_insert_region (rv, pending_region_position);
- } else {
- rv->move (x_delta, y_delta);
- }
-
- } /* foreach region */
-
- } /* if do_move */
-
- if (_first_move && _move_threshold_passed) {
+ if (first_move) {
_editor->cursor_group->raise_to_top();
- _first_move = false;
}
if (x_delta != 0 && !_brushing) {
_editor->show_verbose_time_cursor (_last_frame_position, 10);
}
-}
+}
+
+void
+RegionMoveDrag::motion (GdkEvent* event, bool first_move)
+{
+ if (_copy && first_move) {
+ copy_regions (event);
+ }
+
+ RegionMotionDrag::motion (event, first_move);
+}
void
-RegionMoveDrag::finished (GdkEvent* event)
+RegionMoveDrag::finished (GdkEvent* /*event*/, bool movement_occurred)
{
- bool nocommit = true;
vector<RegionView*> copies;
- RouteTimeAxisView* source_tv;
boost::shared_ptr<Diskstream> ds;
boost::shared_ptr<Playlist> from_playlist;
list<RegionView*> new_views;
pair<PlaylistSet::iterator,bool> insert_result, frozen_insert_result;
nframes64_t drag_delta;
bool changed_tracks, changed_position;
- pair<TimeAxisView*, int> tvp;
map<RegionView*, RouteTimeAxisView*> final;
+ RouteTimeAxisView* source_tv;
- /* _first_move is set to false if the regionview has been moved in the
- motion handler.
- */
-
- if (_first_move) {
+ if (!movement_occurred) {
/* just a click */
- goto out;
+ return;
}
- nocommit = false;
-
if (Config->get_edit_mode() == Splice && !_editor->pre_drag_region_selection.empty()) {
_editor->selection->set (_editor->pre_drag_region_selection);
_editor->pre_drag_region_selection.clear ();
goto out;
}
- char* op_string;
-
/* reverse this here so that we have the correct logic to finalize
the drag.
*/
if (_copy) {
if (_x_constrained) {
- op_string = _("fixed time region copy");
+ _editor->begin_reversible_command (_("fixed time region copy"));
} else {
- op_string = _("region copy");
+ _editor->begin_reversible_command (_("region copy"));
}
} else {
if (_x_constrained) {
- op_string = _("fixed time region drag");
+ _editor->begin_reversible_command (_("fixed time region drag"));
} else {
- op_string = _("region drag");
+ _editor->begin_reversible_command (_("region drag"));
}
}
- _editor->begin_reversible_command (op_string);
changed_position = (_last_frame_position != (nframes64_t) (_primary->region()->position()));
- tvp = _editor->trackview_by_y_position (_current_pointer_y);
- changed_tracks = (tvp.first != &_primary->get_time_axis_view());
+ changed_tracks = (_dest_trackview != &_primary->get_time_axis_view());
drag_delta = _primary->region()->position() - _last_frame_position;
- _editor->track_canvas->update_now ();
+ _editor->update_canvas_now ();
/* make a list of where each region ended up */
- for (list<RegionView*>::const_iterator i = _views.begin(); i != _views.end(); ++i) {
-
- double ix1, ix2, iy1, iy2;
- (*i)->get_canvas_frame()->get_bounds (ix1, iy1, ix2, iy2);
- (*i)->get_canvas_frame()->i2w (ix1, iy1);
- iy1 += _editor->vertical_adjustment.get_value() - _editor->canvas_timebars_vsize;
-
- pair<TimeAxisView*, int> tv = _editor->trackview_by_y_position (iy1);
- final[*i] = dynamic_cast<RouteTimeAxisView*> (tv.first);
- }
+ final = find_time_axis_views ();
for (list<RegionView*>::const_iterator i = _views.begin(); i != _views.end(); ) {
/* get the playlist where this drag started. we can't use rv->region()->playlist()
because we may have copied the region and it has not been attached to a playlist.
*/
+
+ source_tv = dynamic_cast<RouteTimeAxisView*> (&rv->get_time_axis_view());
+ ds = source_tv->get_diskstream();
+ from_playlist = ds->playlist();
- assert ((source_tv = dynamic_cast<RouteTimeAxisView*> (&rv->get_time_axis_view())));
- assert ((ds = source_tv->get_diskstream()));
- assert ((from_playlist = ds->playlist()));
+ assert (source_tv);
+ assert (ds);
+ assert (from_playlist);
/* moved to a different audio track, without copying */
}
out:
- if (!nocommit) {
- for (set<boost::shared_ptr<Playlist> >::iterator p = modified_playlists.begin(); p != modified_playlists.end(); ++p) {
- _editor->session->add_command (new MementoCommand<Playlist>(*(*p), 0, &(*p)->get_state()));
- }
-
- _editor->commit_reversible_command ();
+ for (set<boost::shared_ptr<Playlist> >::iterator p = modified_playlists.begin(); p != modified_playlists.end(); ++p) {
+ _editor->session->add_command (new MementoCommand<Playlist>(*(*p), 0, &(*p)->get_state()));
}
+
+ _editor->commit_reversible_command ();
for (vector<RegionView*>::iterator x = copies.begin(); x != copies.end(); ++x) {
delete *x;
}
}
+
+
+bool
+RegionMoveDrag::x_move_allowed () const
+{
+ if (Config->get_edit_mode() == Lock) {
+ if (_copy) {
+ return !_x_constrained;
+ } else {
+ /* in locked edit mode, reverse the usual meaning of _x_constrained */
+ return _x_constrained;
+ }
+ }
+ return !_x_constrained;
+}
+
+bool
+RegionInsertDrag::x_move_allowed () const
+{
+ if (Config->get_edit_mode() == Lock) {
+ return _x_constrained;
+ }
+
+ return !_x_constrained;
+}
void
-RegionMoveDrag::copy_regions (GdkEvent* event)
+RegionMotionDrag::copy_regions (GdkEvent* event)
{
/* duplicate the regionview(s) and region(s) */
_primary = new_regionviews.front();
_views = new_regionviews;
- swap_grab (new_regionviews.front()->get_canvas_group (), 0, event->motion.time);
+ swap_grab (new_regionviews.front()->get_canvas_group (), 0, event ? event->motion.time : 0);
+
/*
sync the canvas to what we think is its current state
without it, the canvas seems to
..only if the mouse is in rapid motion at the time of the grab.
something to do with regionview creation raking so long?
*/
- _editor->track_canvas->update_now();
+ _editor->update_canvas_now();
}
bool
-RegionMoveDrag::check_possible (RouteTimeAxisView** tv, layer_t* layer)
+RegionMotionDrag::check_possible (RouteTimeAxisView** tv, layer_t* layer)
{
/* Which trackview is this ? */
(*tv) = dynamic_cast<RouteTimeAxisView*> (tvp.first);
(*layer) = tvp.second;
+ if (*tv && (*tv)->layer_display() == Overlaid) {
+ *layer = 0;
+ }
+
/* The region motion is only processed if the pointer is over
an audio track.
*/
/** @param new_order New track order.
* @param old_order Old track order.
* @param visible_y_low Lowest visible order.
- * @param visible_y_high Highest visible order.
- * @param tracks Bitset of tracks indexed by order; 0 means a audio/MIDI track, 1 means something else.
- * @param heigh_list Heights of tracks indexed by order.
* @return true if y movement should not happen, otherwise false.
*/
bool
-RegionMoveDrag::y_movement_disallowed (
- int new_order, int old_order, int y_span, int visible_y_low, int visible_y_high,
- bitset<512> const & tracks, vector<int32_t> const & height_list
- ) const
+RegionMotionDrag::y_movement_disallowed (int new_order, int old_order, int y_span, TimeAxisViewSummary const & tavs) const
{
if (new_order != old_order) {
if (y_span > 0) {
/* moving up the canvas */
- if ( (new_order - y_span) >= visible_y_low) {
+ if ( (new_order - y_span) >= tavs.visible_y_low) {
int32_t n = 0;
int32_t visible_tracks = 0;
while (visible_tracks < y_span ) {
visible_tracks++;
- while (height_list[new_order - (visible_tracks - n)] == 0) {
+ while (tavs.height_list[new_order - (visible_tracks - n)] == 0) {
/* passing through a hidden track */
n--;
}
}
- if (tracks[new_order - (y_span - n)] != 0x00) {
+ if (tavs.tracks[new_order - (y_span - n)] != 0x00) {
/* moving to a non-track; disallow */
return true;
}
} else if (y_span < 0) {
/* moving down the canvas */
- if ((new_order - y_span) <= visible_y_high) {
+ if ((new_order - y_span) <= tavs.visible_y_high) {
int32_t visible_tracks = 0;
int32_t n = 0;
while (visible_tracks > y_span ) {
visible_tracks--;
- while (height_list[new_order - (visible_tracks - n)] == 0) {
+ while (tavs.height_list[new_order - (visible_tracks - n)] == 0) {
/* passing through a hidden track */
n++;
}
}
- if (tracks[new_order - (y_span - n)] != 0x00) {
+ if (tavs.tracks[new_order - (y_span - n)] != 0x00) {
/* moving to a non-track; disallow */
return true;
}
/* this is the pointer's track */
- if ((new_order - y_span) > visible_y_high) {
+ if ((new_order - y_span) > tavs.visible_y_high) {
/* we will overflow */
return true;
- } else if ((new_order - y_span) < visible_y_low) {
+ } else if ((new_order - y_span) < tavs.visible_y_low) {
/* we will overflow */
return true;
}
return false;
}
+
+RegionMoveDrag::RegionMoveDrag (Editor* e, ArdourCanvas::Item* i, RegionView* p, list<RegionView*> const & v, bool b, bool c)
+ : RegionMotionDrag (e, i, p, v, b),
+ _copy (c)
+{
+ TimeAxisView* const tv = &_primary->get_time_axis_view ();
+
+ _dest_trackview = tv;
+ if (tv->layer_display() == Overlaid) {
+ _dest_layer = 0;
+ } else {
+ _dest_layer = _primary->region()->layer ();
+ }
+
+ double speed = 1;
+ RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*> (tv);
+ if (rtv && rtv->is_track()) {
+ speed = rtv->get_diskstream()->speed ();
+ }
+
+ _last_frame_position = static_cast<nframes64_t> (_primary->region()->position() / speed);
+}
+
+void
+RegionMoveDrag::start_grab (GdkEvent* event, Gdk::Cursor* c)
+{
+ RegionMotionDrag::start_grab (event, c);
+
+ _pointer_frame_offset = _grab_frame - _last_frame_position;
+}
+
+RegionInsertDrag::RegionInsertDrag (Editor* e, boost::shared_ptr<Region> r, RouteTimeAxisView* v, nframes64_t pos)
+ : RegionMotionDrag (e, 0, 0, list<RegionView*> (), false)
+{
+ assert ((boost::dynamic_pointer_cast<AudioRegion> (r) && dynamic_cast<AudioTimeAxisView*> (v)) ||
+ (boost::dynamic_pointer_cast<MidiRegion> (r) && dynamic_cast<MidiTimeAxisView*> (v)));
+
+ _primary = v->view()->create_region_view (r, false, false);
+
+ _primary->get_canvas_group()->show ();
+ _primary->set_position (pos, 0);
+ _views.push_back (_primary);
+
+ _last_frame_position = pos;
+
+ _item = _primary->get_canvas_group ();
+ _dest_trackview = v;
+ _dest_layer = _primary->region()->layer ();
+}
+
+map<RegionView*, RouteTimeAxisView*>
+RegionMotionDrag::find_time_axis_views ()
+{
+ map<RegionView*, RouteTimeAxisView*> tav;
+
+ for (list<RegionView*>::const_iterator i = _views.begin(); i != _views.end(); ++i) {
+
+ double ix1, ix2, iy1, iy2;
+ (*i)->get_canvas_frame()->get_bounds (ix1, iy1, ix2, iy2);
+ (*i)->get_canvas_frame()->i2w (ix1, iy1);
+ iy1 += _editor->vertical_adjustment.get_value() - _editor->canvas_timebars_vsize;
+
+ pair<TimeAxisView*, int> tv = _editor->trackview_by_y_position (iy1);
+ tav[*i] = dynamic_cast<RouteTimeAxisView*> (tv.first);
+ }
+
+ return tav;
+}
+
+
+void
+RegionInsertDrag::finished (GdkEvent* /*event*/, bool /*movement_occurred*/)
+{
+ _editor->update_canvas_now ();
+
+ map<RegionView*, RouteTimeAxisView*> final = find_time_axis_views ();
+
+ RouteTimeAxisView* dest_rtv = final[_primary];
+
+ _primary->get_canvas_group()->reparent (*dest_rtv->view()->canvas_item());
+ _primary->get_canvas_group()->property_y() = 0;
+
+ boost::shared_ptr<Playlist> playlist = dest_rtv->playlist();
+
+ _editor->begin_reversible_command (_("insert region"));
+ XMLNode& before = playlist->get_state ();
+ playlist->add_region (_primary->region (), _last_frame_position);
+ _editor->session->add_command (new MementoCommand<Playlist> (*playlist, &before, &playlist->get_state()));
+ _editor->commit_reversible_command ();
+
+ delete _primary;
+ _primary = 0;
+ _views.clear ();
+}
+
RegionSpliceDrag::RegionSpliceDrag (Editor* e, ArdourCanvas::Item* i, RegionView* p, list<RegionView*> const & v)
: RegionMoveDrag (e, i, p, v, false, false)
{
};
void
-RegionSpliceDrag::motion (GdkEvent* event)
+RegionSpliceDrag::motion (GdkEvent* /*event*/, bool)
{
RouteTimeAxisView* tv;
layer_t layer;
return;
}
- if (!_move_threshold_passed) {
- return;
- }
-
int dir;
if (_current_pointer_x - _grab_x > 0) {
}
void
-RegionSpliceDrag::finished (GdkEvent* event)
+RegionSpliceDrag::finished (GdkEvent* /*event*/, bool)
{
}
void
RegionCreateDrag::start_grab (GdkEvent* event, Gdk::Cursor *)
{
- _source_trackview = _view;
_dest_trackview = _view;
- _dest_layer = _source_layer;
Drag::start_grab (event);
}
void
-RegionCreateDrag::motion (GdkEvent* event)
+RegionCreateDrag::motion (GdkEvent* /*event*/, bool first_move)
{
- if (_move_threshold_passed) {
- if (_first_move) {
- // TODO: create region-create-drag region view here
- _first_move = false;
- }
-
- // TODO: resize region-create-drag region view here
+ if (first_move) {
+ // TODO: create region-create-drag region view here
}
+
+ // TODO: resize region-create-drag region view here
}
void
-RegionCreateDrag::finished (GdkEvent* event)
+RegionCreateDrag::finished (GdkEvent* event, bool movement_occurred)
{
MidiTimeAxisView* mtv = dynamic_cast<MidiTimeAxisView*> (_dest_trackview);
if (!mtv) {
return;
}
- if (_first_move) {
+ if (!movement_occurred) {
_editor->begin_reversible_command (_("create region"));
XMLNode &before = mtv->playlist()->get_state();
_editor->commit_reversible_command();
} else {
- motion (event);
+ motion (event, false);
// TODO: create region-create-drag region here
}
}
void
-RegionGainDrag::motion (GdkEvent* event)
+RegionGainDrag::motion (GdkEvent* /*event*/, bool)
{
- if (_first_move && _move_threshold_passed) {
- _first_move = false;
- }
+
}
void
-RegionGainDrag::finished (GdkEvent *)
+RegionGainDrag::finished (GdkEvent *, bool)
{
}
}
void
-TrimDrag::motion (GdkEvent* event)
+TrimDrag::motion (GdkEvent* event, bool first_move)
{
RegionView* rv = _primary;
nframes64_t frame_delta = 0;
left_direction = false;
}
- if (obey_snap) {
- _editor->snap_to (_current_pointer_frame);
- }
+ _editor->snap_to_with_modifier (_current_pointer_frame, event);
- if (_current_pointer_frame == _last_pointer_frame) {
- return;
- }
+ if (first_move) {
- if (_first_move) {
-
string trim_type;
switch (_operation) {
}
}
+ if (_current_pointer_frame == _last_pointer_frame) {
+ return;
+ }
+
if (left_direction) {
frame_delta = (_last_pointer_frame - _current_pointer_frame);
} else {
}
_last_pointer_frame = _current_pointer_frame;
- _first_move = false;
}
void
-TrimDrag::finished (GdkEvent* event)
+TrimDrag::finished (GdkEvent* event, bool movement_occurred)
{
- if (!_first_move) {
- motion (event);
+ if (movement_occurred) {
+ motion (event, false);
if (!_editor->selection->selected (_primary)) {
_editor->thaw_region_after_trim (*_primary);
}
MeterMarkerDrag::MeterMarkerDrag (Editor* e, ArdourCanvas::Item* i, bool c)
- : Drag (e, i)
+ : Drag (e, i),
+ _copy (c)
{
- _copy = c;
-
_marker = reinterpret_cast<MeterMarker*> (_item->get_data ("marker"));
assert (_marker);
}
}
void
-MeterMarkerDrag::motion (GdkEvent* event)
+MeterMarkerDrag::motion (GdkEvent* event, bool)
{
- nframes64_t adjusted_frame = adjusted_current_frame ();
-
- if (!Keyboard::modifier_state_contains (event->button.state, Keyboard::snap_modifier())) {
- _editor->snap_to (adjusted_frame);
- }
+ nframes64_t const adjusted_frame = adjusted_current_frame (event);
if (adjusted_frame == _last_pointer_frame) {
return;
_marker->set_position (adjusted_frame);
_last_pointer_frame = adjusted_frame;
- _first_move = false;
_editor->show_verbose_time_cursor (adjusted_frame, 10);
}
void
-MeterMarkerDrag::finished (GdkEvent* event)
+MeterMarkerDrag::finished (GdkEvent* event, bool movement_occurred)
{
- if (_first_move) {
+ if (!movement_occurred) {
return;
}
- motion (event);
+ motion (event, false);
BBT_Time when;
}
TempoMarkerDrag::TempoMarkerDrag (Editor* e, ArdourCanvas::Item* i, bool c)
- : Drag (e, i)
+ : Drag (e, i),
+ _copy (c)
{
- _copy = c;
-
- TempoMarker* _marker = reinterpret_cast<TempoMarker*> (_item->get_data ("marker"));
+ _marker = reinterpret_cast<TempoMarker*> (_item->get_data ("marker"));
assert (_marker);
}
}
void
-TempoMarkerDrag::motion (GdkEvent* event)
+TempoMarkerDrag::motion (GdkEvent* event, bool)
{
- nframes64_t adjusted_frame = adjusted_current_frame ();
-
- if (!Keyboard::modifier_state_contains (event->button.state, Keyboard::snap_modifier())) {
- _editor->snap_to (adjusted_frame);
- }
+ nframes64_t const adjusted_frame = adjusted_current_frame (event);
if (adjusted_frame == _last_pointer_frame) {
return;
_editor->show_verbose_time_cursor (adjusted_frame, 10);
_last_pointer_frame = adjusted_frame;
- _first_move = false;
}
void
-TempoMarkerDrag::finished (GdkEvent* event)
+TempoMarkerDrag::finished (GdkEvent* event, bool movement_occurred)
{
- if (_first_move) {
+ if (!movement_occurred) {
return;
}
- motion (event);
+ motion (event, false);
BBT_Time when;
nframes64_t where = _editor->event_frame (event, 0, 0);
- _editor->snap_to (where);
+ _editor->snap_to_with_modifier (where, event);
_editor->playhead_cursor->set_position (where);
}
}
}
- _pointer_frame_offset = _grab_frame - _cursor->current_frame;
-
_editor->show_verbose_time_cursor (_cursor->current_frame, 10);
}
void
-CursorDrag::motion (GdkEvent* event)
+CursorDrag::motion (GdkEvent* event, bool)
{
- nframes64_t adjusted_frame = adjusted_current_frame ();
-
- if (!Keyboard::modifier_state_contains (event->button.state, Keyboard::snap_modifier())) {
- if (_cursor == _editor->playhead_cursor) {
- _editor->snap_to (adjusted_frame);
- }
- }
-
+ nframes64_t const adjusted_frame = adjusted_current_frame (event);
+
if (adjusted_frame == _last_pointer_frame) {
return;
}
_editor->show_verbose_time_cursor (_cursor->current_frame, 10);
#ifdef GTKOSX
- _editor->track_canvas->update_now ();
+ _editor->update_canvas_now ();
#endif
_editor->UpdateAllTransportClocks (_cursor->current_frame);
_last_pointer_frame = adjusted_frame;
- _first_move = false;
}
void
-CursorDrag::finished (GdkEvent* event)
+CursorDrag::finished (GdkEvent* event, bool movement_occurred)
{
_editor->_dragging_playhead = false;
- if (_first_move && _stop) {
+ if (!movement_occurred && _stop) {
return;
}
- motion (event);
+ motion (event, false);
if (_item == &_editor->playhead_cursor->canvas_item) {
if (_editor->session) {
}
void
-FadeInDrag::motion (GdkEvent* event)
+FadeInDrag::motion (GdkEvent* event, bool)
{
nframes64_t fade_length;
- nframes64_t pos = adjusted_current_frame ();
-
- if (!Keyboard::modifier_state_contains (event->button.state, Keyboard::snap_modifier())) {
- _editor->snap_to (pos);
- }
+ nframes64_t const pos = adjusted_current_frame (event);
boost::shared_ptr<Region> region = _primary->region ();
}
_editor->show_verbose_duration_cursor (region->position(), region->position() + fade_length, 10);
-
- _first_move = false;
}
void
-FadeInDrag::finished (GdkEvent* event)
+FadeInDrag::finished (GdkEvent* event, bool movement_occurred)
{
- nframes64_t fade_length;
-
- if (_first_move) {
+ if (!movement_occurred) {
return;
}
- nframes64_t const pos = adjusted_current_frame ();
+ nframes64_t fade_length;
+ nframes64_t const pos = adjusted_current_frame (event);
+
boost::shared_ptr<Region> region = _primary->region ();
if (pos < (region->position() + 64)) {
}
void
-FadeOutDrag::motion (GdkEvent* event)
+FadeOutDrag::motion (GdkEvent* event, bool)
{
nframes64_t fade_length;
- nframes64_t pos = adjusted_current_frame ();
-
- if (!Keyboard::modifier_state_contains (event->button.state, Keyboard::snap_modifier())) {
- _editor->snap_to (pos);
- }
+ nframes64_t const pos = adjusted_current_frame (event);
boost::shared_ptr<Region> region = _primary->region ();
}
_editor->show_verbose_duration_cursor (region->last_frame() - fade_length, region->last_frame(), 10);
-
- _first_move = false;
}
void
-FadeOutDrag::finished (GdkEvent* event)
+FadeOutDrag::finished (GdkEvent* event, bool movement_occurred)
{
- if (_first_move) {
+ if (!movement_occurred) {
return;
}
nframes64_t fade_length;
- nframes64_t pos = adjusted_current_frame ();
-
- if (!Keyboard::modifier_state_contains (event->button.state, Keyboard::snap_modifier())) {
- _editor->snap_to (pos);
- }
+ nframes64_t const pos = adjusted_current_frame (event);
boost::shared_ptr<Region> region = _primary->region ();
}
void
-MarkerDrag::motion (GdkEvent* event)
+MarkerDrag::motion (GdkEvent* event, bool)
{
nframes64_t f_delta = 0;
bool is_start;
Location *real_location;
Location *copy_location = 0;
- nframes64_t newframe = adjusted_current_frame ();
+ nframes64_t const newframe = adjusted_current_frame (event);
nframes64_t next = newframe;
-
- if (!Keyboard::modifier_state_contains (event->button.state, Keyboard::snap_modifier())) {
- _editor->snap_to (newframe, 0, true);
- }
if (_current_pointer_frame == _last_pointer_frame) {
return;
}
_last_pointer_frame = _current_pointer_frame;
- _first_move = false;
assert (!_copied_locations.empty());
_editor->show_verbose_time_cursor (newframe, 10);
#ifdef GTKOSX
- _editor->track_canvas->update_now ();
+ _editor->update_canvas_now ();
#endif
_editor->edit_point_clock.set (copy_location->start());
}
void
-MarkerDrag::finished (GdkEvent* event)
+MarkerDrag::finished (GdkEvent* event, bool movement_occurred)
{
- if (_first_move) {
+ if (!movement_occurred) {
/* just a click, do nothing but finish
off the selection process
_editor->_dragging_edit_point = false;
-
_editor->begin_reversible_command ( _("move marker") );
XMLNode &before = _editor->session->locations()->get_state();
_cumulative_x_drag (0),
_cumulative_y_drag (0)
{
- ControlPoint* _point = reinterpret_cast<ControlPoint*> (_item->get_data ("control_point"));
+ _point = reinterpret_cast<ControlPoint*> (_item->get_data ("control_point"));
assert (_point);
}
void
-ControlPointDrag::start_grab (GdkEvent* event, Gdk::Cursor* cursor)
+ControlPointDrag::start_grab (GdkEvent* event, Gdk::Cursor* /*cursor*/)
{
Drag::start_grab (event, _editor->fader_cursor);
}
void
-ControlPointDrag::motion (GdkEvent* event)
+ControlPointDrag::motion (GdkEvent* event, bool)
{
double dx = _current_pointer_x - _last_pointer_x;
double dy = _current_pointer_y - _last_pointer_y;
//translate cx to frames
nframes64_t cx_frames = _editor->unit_to_frame (cx);
- if (!Keyboard::modifier_state_contains (event->button.state, Keyboard::snap_modifier()) && !_x_constrained) {
- _editor->snap_to (cx_frames);
+ if (!_x_constrained) {
+ _editor->snap_to_with_modifier (cx_frames, event);
}
float const fraction = 1.0 - (cy / _point->line().height());
_point->line().point_drag (*_point, cx_frames, fraction, push);
_editor->set_verbose_canvas_cursor_text (_point->line().get_verbose_cursor_string (fraction));
-
- _first_move = false;
}
void
-ControlPointDrag::finished (GdkEvent* event)
+ControlPointDrag::finished (GdkEvent* event, bool movement_occurred)
{
- if (_first_move) {
+ if (!movement_occurred) {
/* just a click */
}
} else {
- motion (event);
+ motion (event, false);
}
_point->line().end_drag (_point);
}
+bool
+ControlPointDrag::active (Editing::MouseMode m)
+{
+ if (m == Editing::MouseGain) {
+ /* always active in mouse gain */
+ return true;
+ }
+
+ /* otherwise active if the point is on an automation line (ie not if its on a region gain line) */
+ return dynamic_cast<AutomationLine*> (&(_point->line())) != 0;
+}
+
LineDrag::LineDrag (Editor* e, ArdourCanvas::Item* i)
: Drag (e, i),
_line (0),
}
void
-LineDrag::start_grab (GdkEvent* event, Gdk::Cursor* cursor)
+LineDrag::start_grab (GdkEvent* event, Gdk::Cursor* /*cursor*/)
{
_line = reinterpret_cast<AutomationLine*> (_item->get_data ("line"));
assert (_line);
}
void
-LineDrag::motion (GdkEvent* event)
+LineDrag::motion (GdkEvent* event, bool)
{
double dy = _current_pointer_y - _last_pointer_y;
}
void
-LineDrag::finished (GdkEvent* event)
+LineDrag::finished (GdkEvent* event, bool)
{
- motion (event);
+ motion (event, false);
_line->end_drag (0);
}
}
void
-RubberbandSelectDrag::motion (GdkEvent* event)
+RubberbandSelectDrag::motion (GdkEvent* event, bool first_move)
{
nframes64_t start;
nframes64_t end;
return;
}
- if (!Keyboard::modifier_state_contains (event->button.state, Keyboard::snap_modifier()) && Config->get_rubberbanding_snaps_to_grid()) {
- if (_first_move) {
- _editor->snap_to (_grab_frame);
+ if (Config->get_rubberbanding_snaps_to_grid()) {
+ if (first_move) {
+ _editor->snap_to_with_modifier (_grab_frame, event);
}
- _editor->snap_to (_current_pointer_frame);
+ _editor->snap_to_with_modifier (_current_pointer_frame, event);
}
/* base start and end on initial click position */
_editor->rubberband_rect->raise_to_top();
_last_pointer_frame = _current_pointer_frame;
- _first_move = false;
_editor->show_verbose_time_cursor (_current_pointer_frame, 10);
}
}
void
-RubberbandSelectDrag::finished (GdkEvent* event)
+RubberbandSelectDrag::finished (GdkEvent* event, bool movement_occurred)
{
- if (!_first_move) {
+ if (movement_occurred) {
- motion (event);
+ motion (event, false);
double y1,y2;
if (_current_pointer_y < _grab_y) {
Selection::Operation op = Keyboard::selection_type (event->button.state);
- bool commit;
+ bool committed;
_editor->begin_reversible_command (_("rubberband selection"));
if (_grab_frame < _last_pointer_frame) {
- commit = _editor->select_all_within (_grab_frame, _last_pointer_frame, y1, y2, _editor->track_views, op);
+ committed = _editor->select_all_within (_grab_frame, _last_pointer_frame, y1, y2, _editor->track_views, op);
} else {
- commit = _editor->select_all_within (_last_pointer_frame, _grab_frame, y1, y2, _editor->track_views, op);
+ committed = _editor->select_all_within (_last_pointer_frame, _grab_frame, y1, y2, _editor->track_views, op);
}
- if (commit) {
+ if (!committed) {
_editor->commit_reversible_command ();
}
}
void
-TimeFXDrag::motion (GdkEvent* event)
+TimeFXDrag::motion (GdkEvent* event, bool)
{
RegionView* rv = _primary;
- if (!Keyboard::modifier_state_contains (event->button.state, Keyboard::snap_modifier())) {
- _editor->snap_to (_current_pointer_frame);
- }
+ _editor->snap_to_with_modifier (_current_pointer_frame, event);
if (_current_pointer_frame == _last_pointer_frame) {
return;
}
_last_pointer_frame = _current_pointer_frame;
- _first_move = false;
_editor->show_verbose_time_cursor (_current_pointer_frame, 10);
}
void
-TimeFXDrag::finished (GdkEvent* event)
+TimeFXDrag::finished (GdkEvent* /*event*/, bool movement_occurred)
{
_primary->get_time_axis_view().hide_timestretch ();
- if (_first_move) {
+ if (!movement_occurred) {
return;
}
}
}
+void
+ScrubDrag::start_grab (GdkEvent* event, Gdk::Cursor *)
+{
+ Drag::start_grab (event);
+}
+
+void
+ScrubDrag::motion (GdkEvent* /*event*/, bool)
+{
+ _editor->scrub ();
+}
+
+void
+ScrubDrag::finished (GdkEvent* /*event*/, bool movement_occurred)
+{
+ if (movement_occurred && _editor->session) {
+ /* make sure we stop */
+ _editor->session->request_transport_speed (0.0);
+ }
+}
+
SelectionDrag::SelectionDrag (Editor* e, ArdourCanvas::Item* i, Operation o)
: Drag (e, i),
- _operation (o)
+ _operation (o),
+ _copy (false)
{
}
}
void
-SelectionDrag::motion (GdkEvent* event)
+SelectionDrag::motion (GdkEvent* event, bool first_move)
{
nframes64_t start = 0;
nframes64_t end = 0;
nframes64_t length;
- nframes64_t pending_position = adjusted_current_frame ();
+ nframes64_t const pending_position = adjusted_current_frame (event);
- if (!Keyboard::modifier_state_contains (event->button.state, Keyboard::snap_modifier())) {
- _editor->snap_to (pending_position);
- }
-
/* only alter selection if the current frame is
different from the last frame position (adjusted)
*/
switch (_operation) {
case CreateSelection:
- if (_first_move) {
+ if (first_move) {
_editor->snap_to (_grab_frame);
}
or create a new selection->
*/
- if (_first_move) {
+ if (first_move) {
_editor->begin_reversible_command (_("range selection"));
case SelectionStartTrim:
- if (_first_move) {
+ if (first_move) {
_editor->begin_reversible_command (_("trim selection start"));
}
case SelectionEndTrim:
- if (_first_move) {
+ if (first_move) {
_editor->begin_reversible_command (_("trim selection end"));
}
case SelectionMove:
- if (_first_move) {
+ if (first_move) {
_editor->begin_reversible_command (_("move selection"));
}
break;
}
- if (event->button.x >= _editor->horizontal_adjustment.get_value() + _editor->canvas_width) {
+ if (event->button.x >= _editor->horizontal_adjustment.get_value() + _editor->_canvas_width) {
_editor->start_canvas_autoscroll (1, 0);
}
}
_last_pointer_frame = pending_position;
- _first_move = false;
if (_operation == SelectionMove) {
_editor->show_verbose_time_cursor(start, 10);
}
void
-SelectionDrag::finished (GdkEvent* event)
+SelectionDrag::finished (GdkEvent* event, bool movement_occurred)
{
- if (!_first_move) {
- motion (event);
+ if (movement_occurred) {
+ motion (event, false);
/* XXX this is not object-oriented programming at all. ick */
if (_editor->selection->time.consolidate()) {
_editor->selection->TimeChanged ();
RangeMarkerBarDrag::RangeMarkerBarDrag (Editor* e, ArdourCanvas::Item* i, Operation o)
: Drag (e, i),
- _operation (o)
+ _operation (o),
+ _copy (false)
{
_drag_rect = new ArdourCanvas::SimpleRect (*_editor->time_line_group, 0.0, 0.0, 0.0, _editor->physical_screen_height);
_drag_rect->hide ();
}
void
-RangeMarkerBarDrag::motion (GdkEvent* event)
+RangeMarkerBarDrag::motion (GdkEvent* event, bool first_move)
{
nframes64_t start = 0;
nframes64_t end = 0;
break;
}
- if (!Keyboard::modifier_state_contains (event->button.state, Keyboard::snap_modifier())) {
- _editor->snap_to (_current_pointer_frame);
- }
+ _editor->snap_to_with_modifier (_current_pointer_frame, event);
/* only alter selection if the current frame is
different from the last frame position.
case CreateRangeMarker:
case CreateTransportMarker:
case CreateCDMarker:
- if (_first_move) {
+ if (first_move) {
_editor->snap_to (_grab_frame);
}
or create a new selection.
*/
- if (_first_move) {
+ if (first_move) {
_editor->temp_location->set (start, end);
break;
}
- if (event->button.x >= _editor->horizontal_adjustment.get_value() + _editor->canvas_width) {
+ if (event->button.x >= _editor->horizontal_adjustment.get_value() + _editor->_canvas_width) {
_editor->start_canvas_autoscroll (1, 0);
}
}
_last_pointer_frame = _current_pointer_frame;
- _first_move = false;
_editor->show_verbose_time_cursor (_current_pointer_frame, 10);
}
void
-RangeMarkerBarDrag::finished (GdkEvent* event)
+RangeMarkerBarDrag::finished (GdkEvent* event, bool movement_occurred)
{
Location * newloc = 0;
string rangename;
int flags;
- if (!_first_move) {
- motion (event);
+ if (movement_occurred) {
+ motion (event, false);
+ _drag_rect->hide();
switch (_operation) {
case CreateRangeMarker:
XMLNode &after = _editor->session->locations()->get_state();
_editor->session->add_command(new MementoCommand<Locations>(*(_editor->session->locations()), &before, &after));
_editor->commit_reversible_command ();
-
- _drag_rect->hide();
break;
}
case CreateTransportMarker:
// popup menu to pick loop or punch
_editor->new_transport_marker_context_menu (&event->button, _item);
-
break;
}
} else {
}
void
-MouseZoomDrag::motion (GdkEvent* event)
+MouseZoomDrag::motion (GdkEvent* event, bool first_move)
{
nframes64_t start;
nframes64_t end;
- if (!Keyboard::modifier_state_contains (event->button.state, Keyboard::snap_modifier())) {
- _editor->snap_to (_current_pointer_frame);
-
- if (_first_move) {
- _editor->snap_to (_grab_frame);
- }
+ _editor->snap_to_with_modifier (_current_pointer_frame, event);
+
+ if (first_move) {
+ _editor->snap_to_with_modifier (_grab_frame, event);
}
if (_current_pointer_frame == _last_pointer_frame) {
if (start != end) {
- if (_first_move) {
+ if (first_move) {
_editor->zoom_rect->show();
_editor->zoom_rect->raise_to_top();
}
_editor->reposition_zoom_rect(start, end);
_last_pointer_frame = _current_pointer_frame;
- _first_move = false;
_editor->show_verbose_time_cursor (_current_pointer_frame, 10);
}
}
void
-MouseZoomDrag::finished (GdkEvent* event)
+MouseZoomDrag::finished (GdkEvent* event, bool movement_occurred)
{
- if (!_first_move) {
- motion (event);
+ if (movement_occurred) {
+ motion (event, false);
if (_grab_frame < _last_pointer_frame) {
_editor->temporal_zoom_by_frame (_grab_frame, _last_pointer_frame, "mouse zoom");