X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Feditor_drag.cc;h=91bfb2ce0c4bda4b5249dcdc1ea5df01167128f2;hb=264c62eb2613699902dbdabb777c5f776c17f340;hp=f1d879e32c444ca6fea9520c1ef6ecce4e40dc93;hpb=eca6c9f998feb70c606577f33446c907e0749c73;p=ardour.git diff --git a/gtk2_ardour/editor_drag.cc b/gtk2_ardour/editor_drag.cc index f1d879e32c..91bfb2ce0c 100644 --- a/gtk2_ardour/editor_drag.cc +++ b/gtk2_ardour/editor_drag.cc @@ -50,7 +50,6 @@ #include "ardour_ui.h" #include "gui_thread.h" #include "control_point.h" -#include "utils.h" #include "region_gain_line.h" #include "editor_drag.h" #include "audio_time_axis.h" @@ -177,6 +176,12 @@ DragManager::motion_handler (GdkEvent* e, bool from_autoscroll) { bool r = false; + /* calling this implies that we expect the event to have canvas + * coordinates + * + * Can we guarantee that this is true? + */ + _current_pointer_frame = _editor->canvas_event_sample (e, &_current_pointer_x, &_current_pointer_y); for (list::iterator i = _drags.begin(); i != _drags.end(); ++i) { @@ -193,24 +198,6 @@ DragManager::motion_handler (GdkEvent* e, bool from_autoscroll) return r; } -bool -DragManager::window_motion_handler (GdkEvent* e, bool from_autoscroll) -{ - bool r = false; - - _current_pointer_frame = _editor->canvas_event_sample (e, &_current_pointer_x, &_current_pointer_y); - - for (list::iterator i = _drags.begin(); i != _drags.end(); ++i) { - bool const t = (*i)->motion_handler (e, from_autoscroll); - if (t) { - r = true; - } - - } - - return r; -} - bool DragManager::have_item (ArdourCanvas::Item* i) const { @@ -281,11 +268,10 @@ Drag::start_grab (GdkEvent* event, Gdk::Cursor *cursor) if (cursor == 0) { _item->grab (); - } else { /* CAIROCANVAS need a variant here that passes *cursor */ _item->grab (); - + _editor->push_canvas_cursor (cursor); } if (_editor->session() && _editor->session()->transport_rolling()) { @@ -322,6 +308,7 @@ Drag::end_grab (GdkEvent* event) finished (event, _move_threshold_passed); _editor->verbose_cursor()->hide (); + _editor->pop_canvas_cursor (); return _move_threshold_passed; } @@ -398,6 +385,7 @@ Drag::motion_handler (GdkEvent* event, bool from_autoscroll) return true; } } + return false; } @@ -418,58 +406,22 @@ Drag::abort () void Drag::show_verbose_cursor_time (framepos_t frame) { - /* We use DragManager::current_pointer_y() here - because we need to position the verbose canvas - cursor within the overall canvas, regardless - of this particular drag's _trackview_only - setting. - */ - - _editor->verbose_cursor()->set_time ( - frame, - _drags->current_pointer_x() + 10, - _drags->current_pointer_y() + 10 - ); - + _editor->verbose_cursor()->set_time (frame); _editor->verbose_cursor()->show (); } void -Drag::show_verbose_cursor_duration (framepos_t start, framepos_t end, double xoffset) +Drag::show_verbose_cursor_duration (framepos_t start, framepos_t end, double /*xoffset*/) { - _editor->verbose_cursor()->show (xoffset); - - /* We use DragManager::current_pointer_y() here - because we need to position the verbose canvas - cursor within the overall canvas, regardless - of this particular drag's _trackview_only - setting. - */ - - _editor->verbose_cursor()->set_duration ( - start, end, - _drags->current_pointer_x() + 10, - _drags->current_pointer_y() + 10 - ); + _editor->verbose_cursor()->set_duration (start, end); + _editor->verbose_cursor()->show (); } void Drag::show_verbose_cursor_text (string const & text) { + _editor->verbose_cursor()->set (text); _editor->verbose_cursor()->show (); - - /* We use DragManager::current_pointer_y() here - because we need to position the verbose canvas - cursor within the overall canvas, regardless - of this particular drag's _trackview_only - setting. - */ - - _editor->verbose_cursor()->set ( - text, - _drags->current_pointer_x() + 10, - _drags->current_pointer_y() + 10 - ); } boost::shared_ptr @@ -524,7 +476,7 @@ RegionDrag::RegionDrag (Editor* e, ArdourCanvas::Item* i, RegionView* p, list::const_iterator i = v.begin(); i != v.end(); ++i) { - _views.push_back (DraggingView (*i, this)); + _views.push_back (DraggingView (*i, this, &(*i)->get_time_axis_view())); } RegionView::RegionViewGoingAway.connect (death_connection, invalidator (*this), boost::bind (&RegionDrag::region_going_away, this, _1), gui_context()); @@ -643,7 +595,6 @@ RegionMotionDrag::compute_x_delta (GdkEvent const * event, framepos_t* pending_r } } - _last_frame_position = *pending_region_position; } return dx; @@ -711,11 +662,12 @@ RegionMotionDrag::motion (GdkEvent* event, bool first_move) delta_time_axis_view = current_pointer_time_axis_view - _last_pointer_time_axis_view; delta_layer = current_pointer_layer - _last_pointer_layer; - } + } /* Work out the change in x */ framepos_t pending_region_position; double const x_delta = compute_x_delta (event, &pending_region_position); + _last_frame_position = pending_region_position; /* Verify change in y */ if (!y_movement_allowed (delta_time_axis_view, delta_layer)) { @@ -724,7 +676,7 @@ RegionMotionDrag::motion (GdkEvent* event, bool first_move) delta_layer = 0; } - if (x_delta == 0 && delta_time_axis_view == 0 && delta_layer == 0 && !first_move) { + if (x_delta == 0 && (tv && tv->view() && delta_time_axis_view == 0) && delta_layer == 0 && !first_move) { /* haven't reached next snap point, and we're not switching trackviews nor layers. nothing to do. */ @@ -743,13 +695,12 @@ RegionMotionDrag::motion (GdkEvent* event, bool first_move) if (first_move) { rv->drag_start (); - rv->set_opacity_for_drag (true); /* reparent the regionview into a group above all * others */ - - ArdourCanvas::Group* rvg = rv->get_canvas_group(); + + ArdourCanvas::Item* rvg = rv->get_canvas_group(); Duple rv_canvas_offset = rvg->parent()->canvas_origin (); Duple dmg_canvas_offset = _editor->_drag_motion_group->canvas_origin (); rv->get_canvas_group()->reparent (_editor->_drag_motion_group); @@ -909,7 +860,7 @@ RegionMoveDrag::motion (GdkEvent* event, bool first_move) } nrv->get_canvas_group()->show (); - new_regionviews.push_back (DraggingView (nrv, this)); + new_regionviews.push_back (DraggingView (nrv, this, i->initial_time_axis_view)); /* swap _primary to the copy */ @@ -938,10 +889,6 @@ RegionMoveDrag::motion (GdkEvent* event, bool first_move) void RegionMotionDrag::finished (GdkEvent *, bool) { - for (list::iterator i = _views.begin(); i != _views.end(); ++i) { - i->view->set_opacity_for_drag (false); - } - for (vector::iterator i = _time_axis_views.begin(); i != _time_axis_views.end(); ++i) { if (!(*i)->view()) { continue; @@ -1015,7 +962,7 @@ RegionMoveDrag::finished (GdkEvent* ev, bool movement_occurred) } RouteTimeAxisView* -RegionMoveDrag::create_destination_time_axis (boost::shared_ptr region) +RegionMoveDrag::create_destination_time_axis (boost::shared_ptr region, TimeAxisView* original) { /* Add a new track of the correct type, and return the RouteTimeAxisView that is created to display the new track. @@ -1025,12 +972,20 @@ RegionMoveDrag::create_destination_time_axis (boost::shared_ptr region) if (boost::dynamic_pointer_cast (region)) { list > audio_tracks; audio_tracks = _editor->session()->new_audio_track (region->n_channels(), region->n_channels(), ARDOUR::Normal, 0, 1, region->name()); - return _editor->axis_view_from_route (audio_tracks.front()); + RouteTimeAxisView* rtav = _editor->axis_view_from_route (audio_tracks.front()); + if (rtav) { + rtav->set_height (original->current_height()); + } + return rtav; } else { ChanCount one_midi_port (DataType::MIDI, 1); list > midi_tracks; midi_tracks = _editor->session()->new_midi_track (one_midi_port, one_midi_port, boost::shared_ptr(), ARDOUR::Normal, 0, 1, region->name()); - return _editor->axis_view_from_route (midi_tracks.front()); + RouteTimeAxisView* rtav = _editor->axis_view_from_route (midi_tracks.front()); + if (rtav) { + rtav->set_height (original->current_height()); + } + return rtav; } } catch (...) { error << _("Could not create new track after region placed in the drop zone") << endmsg; @@ -1081,7 +1036,7 @@ RegionMoveDrag::finished_copy (bool const changed_position, bool const /*changed if (i->time_axis_view < 0) { if (!new_time_axis_view) { - new_time_axis_view = create_destination_time_axis (i->view->region()); + new_time_axis_view = create_destination_time_axis (i->view->region(), i->initial_time_axis_view); } dest_rtv = new_time_axis_view; } else { @@ -1156,7 +1111,7 @@ RegionMoveDrag::finished_no_copy ( if (i->time_axis_view < 0) { if (!new_time_axis_view) { - new_time_axis_view = create_destination_time_axis (rv->region()); + new_time_axis_view = create_destination_time_axis (rv->region(), i->initial_time_axis_view); } dest_rtv = new_time_axis_view; } else { @@ -1200,7 +1155,7 @@ RegionMoveDrag::finished_no_copy ( visible. */ rv->hide_region_editor(); - rv->set_opacity_for_drag (false); + remove_region_from_playlist (rv->region(), i->initial_playlist, modified_playlists); @@ -1326,7 +1281,7 @@ RegionMoveDrag::remove_region_from_playlist ( playlist->clear_changes (); } - playlist->remove_region (region); + playlist->remove_region (region); // should be no need to ripple; we better already have rippled the playlist in RegionRippleDrag } @@ -1435,7 +1390,6 @@ RegionMotionDrag::aborted (bool) rv->get_canvas_group()->reparent (rtv->view()->canvas_item()); rv->get_canvas_group()->set_y_position (0); rv->drag_end (); - rv->set_opacity_for_drag (false); rv->move (-_total_x_delta, 0); rv->set_height (rtv->view()->child_height ()); } @@ -1477,7 +1431,7 @@ RegionInsertDrag::RegionInsertDrag (Editor* e, boost::shared_ptr r, Rout _primary->get_canvas_group()->show (); _primary->set_position (pos, 0); - _views.push_back (DraggingView (_primary, this)); + _views.push_back (DraggingView (_primary, this, v)); _last_frame_position = pos; @@ -1497,6 +1451,12 @@ RegionInsertDrag::finished (GdkEvent *, bool) _editor->begin_reversible_command (Operations::insert_region); playlist->clear_changes (); playlist->add_region (_primary->region (), _last_frame_position); + + // Mixbus doesn't seem to ripple when inserting regions from the list: should we? yes, probably + if (Config->get_edit_mode() == Ripple) { + playlist->ripple (_last_frame_position, _primary->region()->length(), _primary->region()); + } + _editor->session()->add_command (new StatefulDiffCommand (playlist)); _editor->commit_reversible_command (); @@ -1539,10 +1499,12 @@ RegionSpliceDrag::motion (GdkEvent* event, bool) if (!tv || !tv->is_track()) { /* To make sure we hide the verbose canvas cursor when the mouse is - not held over and audiotrack. + not held over an audio track. */ _editor->verbose_cursor()->hide (); return; + } else { + _editor->verbose_cursor()->show (); } int dir; @@ -1553,10 +1515,8 @@ RegionSpliceDrag::motion (GdkEvent* event, bool) dir = -1; } - RegionSelection copy (_editor->selection->regions); - - RegionSelectionByPosition cmp; - copy.sort (cmp); + RegionSelection copy; + _editor->selection->regions.by_position(copy); framepos_t const pf = adjusted_current_frame (event); @@ -1605,6 +1565,275 @@ RegionSpliceDrag::aborted (bool) /* XXX: TODO */ } +/*** + * ripple mode... + */ + +void +RegionRippleDrag::add_all_after_to_views(TimeAxisView *tav, framepos_t where, const RegionSelection &exclude, bool drag_in_progress) +{ + RegionSelection to_ripple; + TrackViewList tracks; + tracks.push_back (tav); + _editor->get_regions_after (to_ripple, where, tracks); + + for (RegionSelection::iterator i = to_ripple.begin(); i != to_ripple.end(); ++i) { + if (!exclude.contains (*i)) { + // the selection has already been added to _views + + if (drag_in_progress) { + // do the same things that RegionMotionDrag::motion does when + // first_move is true, for the region views that we're adding + // to _views this time + + (*i)->drag_start(); + ArdourCanvas::Item* rvg = (*i)->get_canvas_group(); + Duple rv_canvas_offset = rvg->item_to_canvas (Duple (0,0)); + Duple dmg_canvas_offset = _editor->_drag_motion_group->canvas_origin (); + rvg->reparent (_editor->_drag_motion_group); + + // we only need to move in the y direction + Duple fudge = rv_canvas_offset - dmg_canvas_offset; + fudge.x = 0; + rvg->move (fudge); + + } + _views.push_back (DraggingView (*i, this, tav)); + } + } +} + +void +RegionRippleDrag::remove_unselected_from_views(framecnt_t amount, bool move_regions) +{ + + for (std::list::iterator i = _views.begin(); i != _views.end(); ) { + // we added all the regions after the selection + + std::list::iterator to_erase = i++; + if (!_editor->selection->regions.contains (to_erase->view)) { + // restore the non-selected regions to their original playlist & positions, + // and then ripple them back by the length of the regions that were dragged away + // do the same things as RegionMotionDrag::aborted + + RegionView *rv = to_erase->view; + TimeAxisView* tv = &(rv->get_time_axis_view ()); + RouteTimeAxisView* rtv = dynamic_cast (tv); + assert (rtv); + + // plonk them back onto their own track + rv->get_canvas_group()->reparent(rtv->view()->canvas_item()); + rv->get_canvas_group()->set_y_position (0); + rv->drag_end (); + + if (move_regions) { + // move the underlying region to match the view + rv->region()->set_position (rv->region()->position() + amount); + } else { + // restore the view to match the underlying region's original position + rv->move(-amount, 0); // second parameter is y delta - seems 0 is OK + } + + rv->set_height (rtv->view()->child_height ()); + _views.erase (to_erase); + } + } +} + +bool +RegionRippleDrag::y_movement_allowed (int delta_track, double delta_layer) const +{ + if (RegionMotionDrag::y_movement_allowed (delta_track, delta_layer)) { + if (delta_track) { + return allow_moves_across_tracks; + } else { + return true; + } + } + return false; +} + +RegionRippleDrag::RegionRippleDrag (Editor* e, ArdourCanvas::Item* i, RegionView* p, list const & v) + : RegionMoveDrag (e, i, p, v, false, false) +{ + DEBUG_TRACE (DEBUG::Drags, "New RegionRippleDrag\n"); + // compute length of selection + RegionSelection selected_regions = _editor->selection->regions; + selection_length = selected_regions.end_frame() - selected_regions.start(); + + // we'll only allow dragging to another track in ripple mode if all the regions + // being dragged start off on the same track + allow_moves_across_tracks = (selected_regions.playlists().size() == 1); + prev_tav = NULL; + prev_amount = 0; + exclude = new RegionList; + for (RegionSelection::iterator i =selected_regions.begin(); i != selected_regions.end(); ++i) { + exclude->push_back((*i)->region()); + } + + // also add regions before start of selection to exclude, to be consistent with how Mixbus does ripple + RegionSelection copy; + selected_regions.by_position(copy); // get selected regions sorted by position into copy + + std::set > playlists = copy.playlists(); + std::set >::const_iterator pi; + + for (pi = playlists.begin(); pi != playlists.end(); ++pi) { + // find ripple start point on each applicable playlist + RegionView *first_selected_on_this_track = NULL; + for (RegionSelection::iterator i = copy.begin(); i != copy.end(); ++i) { + if ((*i)->region()->playlist() == (*pi)) { + // region is on this playlist - it's the first, because they're sorted + first_selected_on_this_track = *i; + break; + } + } + assert (first_selected_on_this_track); // we should always find the region in one of the playlists... + add_all_after_to_views ( + &first_selected_on_this_track->get_time_axis_view(), + first_selected_on_this_track->region()->position() + first_selected_on_this_track->region()->length(), + selected_regions, false); + } + + if (allow_moves_across_tracks) { + orig_tav = &(*selected_regions.begin())->get_time_axis_view(); + } else { + orig_tav = NULL; + } + +} + +void +RegionRippleDrag::motion (GdkEvent* event, bool first_move) +{ + /* Which trackview is this ? */ + + pair const tvp = _editor->trackview_by_y_position (current_pointer_y ()); + RouteTimeAxisView* tv = dynamic_cast (tvp.first); + + /* The region motion is only processed if the pointer is over + an audio track. + */ + + if (!tv || !tv->is_track()) { + /* To make sure we hide the verbose canvas cursor when the mouse is + not held over an audiotrack. + */ + _editor->verbose_cursor()->hide (); + return; + } + + framepos_t where = adjusted_current_frame (event); + assert (where >= 0); + framepos_t after; + double delta = compute_x_delta (event, &after); + + framecnt_t amount = _editor->pixel_to_sample (delta); + + if (allow_moves_across_tracks) { + // all the originally selected regions were on the same track + + framecnt_t adjust = 0; + if (prev_tav && tv != prev_tav) { + // dragged onto a different track + // remove the unselected regions from _views, restore them to their original positions + // and add the regions after the drop point on the new playlist to _views instead. + // undo the effect of rippling the previous playlist, and include the effect of removing + // the dragged region(s) from this track + + remove_unselected_from_views (prev_amount, false); + // ripple previous playlist according to the regions that have been removed onto the new playlist + prev_tav->playlist()->ripple(prev_position, -selection_length, exclude); + prev_amount = 0; + + // move just the selected regions + RegionMoveDrag::motion(event, first_move); + + // ensure that the ripple operation on the new playlist inserts selection_length time + adjust = selection_length; + // ripple the new current playlist + tv->playlist()->ripple (where, amount+adjust, exclude); + + // add regions after point where drag entered this track to subsequent ripples + add_all_after_to_views (tv, where, _editor->selection->regions, true); + + } else { + // motion on same track + RegionMoveDrag::motion(event, first_move); + } + prev_tav = tv; + + // remember what we've done to this playlist so we can undo it if the selection is dragged to another track + prev_position = where; + } else { + // selection encompasses multiple tracks - just drag + // cross-track drags are forbidden + RegionMoveDrag::motion(event, first_move); + } + + if (!_x_constrained) { + prev_amount += amount; + } + + _last_frame_position = after; +} + +void +RegionRippleDrag::finished (GdkEvent* event, bool movement_occurred) +{ + if (!movement_occurred) { + return; + } + + _editor->begin_reversible_command(_("Ripple drag")); + + // remove the regions being rippled from the dragging view, updating them to + // their new positions + remove_unselected_from_views (prev_amount, true); + + if (allow_moves_across_tracks) { + if (orig_tav) { + // if regions were dragged across tracks, we've rippled any later + // regions on the track the regions were dragged off, so we need + // to add the original track to the undo record + orig_tav->playlist()->clear_changes(); + vector cmds; + orig_tav->playlist()->rdiff (cmds); + _editor->session()->add_commands (cmds); + } + if (prev_tav && prev_tav != orig_tav) { + prev_tav->playlist()->clear_changes(); + vector cmds; + prev_tav->playlist()->rdiff (cmds); + _editor->session()->add_commands (cmds); + } + } else { + // selection spanned multiple tracks - all will need adding to undo record + + std::set > playlists = _editor->selection->regions.playlists(); + std::set >::const_iterator pi; + + for (pi = playlists.begin(); pi != playlists.end(); ++pi) { + (*pi)->clear_changes(); + vector cmds; + (*pi)->rdiff (cmds); + _editor->session()->add_commands (cmds); + } + } + + // other modified playlists are added to undo by RegionMoveDrag::finished() + RegionMoveDrag::finished (event, movement_occurred); + _editor->commit_reversible_command(); +} + +void +RegionRippleDrag::aborted (bool movement_occurred) +{ + RegionMoveDrag::aborted (movement_occurred); + _views.clear (); +} + + RegionCreateDrag::RegionCreateDrag (Editor* e, ArdourCanvas::Item* i, TimeAxisView* v) : Drag (e, i), _view (dynamic_cast (v)) @@ -1808,8 +2037,7 @@ VideoTimeLineDrag::start_grab (GdkEvent* event, Gdk::Cursor*) Timecode::Time timecode; _editor->session()->sample_to_timecode(abs(_startdrag_video_offset), timecode, true /* use_offset */, false /* use_subframes */ ); snprintf (buf, sizeof (buf), "Video Start:\n%c%02" PRId32 ":%02" PRId32 ":%02" PRId32 ":%02" PRId32, (_startdrag_video_offset<0?'-':' '), timecode.hours, timecode.minutes, timecode.seconds, timecode.frames); - _editor->verbose_cursor()->set(buf, event->button.x + 10, event->button.y + 10); - _editor->verbose_cursor()->show (); + show_verbose_cursor_text (buf); } void @@ -1837,7 +2065,6 @@ VideoTimeLineDrag::motion (GdkEvent* event, bool first_move) DEBUG_TRACE (DEBUG::Drags, string_compose("SHIFT REGION at %1 by %2\n", i->initial_position, dt)); if (first_move) { rv->drag_start (); - rv->set_opacity_for_drag (true); rv->region()->clear_changes (); rv->region()->suspend_property_changes(); } @@ -1859,8 +2086,7 @@ VideoTimeLineDrag::motion (GdkEvent* event, bool first_move) , _("Diff:"), (dt<0?'-':' '), timediff.hours, timediff.minutes, timediff.seconds, timediff.frames ); - _editor->verbose_cursor()->set(buf, event->button.x + 10, event->button.y + 10); - _editor->verbose_cursor()->show (); + show_verbose_cursor_text (buf); } void @@ -1885,7 +2111,6 @@ VideoTimeLineDrag::finished (GdkEvent * /*event*/, bool movement_occurred) for (list::iterator i = _views.begin(); i != _views.end(); ++i) { i->view->drag_end(); - i->view->set_opacity_for_drag (false); i->view->region()->resume_property_changes (); _editor->session()->add_command (new StatefulDiffCommand (i->view->region())); @@ -1949,11 +2174,20 @@ TrimDrag::start_grab (GdkEvent* event, Gdk::Cursor*) if (pf < (region_start + region_length/2)) { /* closer to front */ _operation = StartTrim; - Drag::start_grab (event, _editor->cursors()->left_side_trim); + + if (Keyboard::modifier_state_equals (event->button.state, Keyboard::TertiaryModifier)) { + Drag::start_grab (event, _editor->cursors()->anchored_left_side_trim); + } else { + Drag::start_grab (event, _editor->cursors()->left_side_trim); + } } else { /* closer to end */ _operation = EndTrim; - Drag::start_grab (event, _editor->cursors()->right_side_trim); + if (Keyboard::modifier_state_equals (event->button.state, Keyboard::TertiaryModifier)) { + Drag::start_grab (event, _editor->cursors()->anchored_right_side_trim); + } else { + Drag::start_grab (event, _editor->cursors()->right_side_trim); + } } } @@ -2021,7 +2255,6 @@ TrimDrag::motion (GdkEvent* event, bool first_move) for (list::const_iterator i = _views.begin(); i != _views.end(); ++i) { RegionView* rv = i->view; - rv->set_opacity_for_drag (false); rv->enable_display (false); rv->region()->playlist()->clear_owned_changes (); @@ -2204,7 +2437,6 @@ TrimDrag::finished (GdkEvent* event, bool movement_occurred) for (list::const_iterator i = _views.begin(); i != _views.end(); ++i) { i->view->thaw_after_trim (); i->view->enable_display (true); - i->view->set_opacity_for_drag (true); /* Trimming one region may affect others on the playlist, so we need to get undo Commands from the whole playlist rather than just the @@ -3293,10 +3525,7 @@ ControlPointDrag::start_grab (GdkEvent* event, Gdk::Cursor* /*cursor*/) _point->line().start_drag_single (_point, _fixed_grab_x, fraction); - _editor->verbose_cursor()->set (_point->line().get_verbose_cursor_string (fraction), - event->button.x + 10, event->button.y + 10); - - _editor->verbose_cursor()->show (); + show_verbose_cursor_text (_point->line().get_verbose_cursor_string (fraction)); _pushing = Keyboard::modifier_state_contains (event->button.state, Keyboard::PrimaryModifier); @@ -3356,7 +3585,7 @@ ControlPointDrag::motion (GdkEvent* event, bool) _point->line().drag_motion (_editor->sample_to_pixel_unrounded (cx_frames), fraction, false, _pushing, _final_index); - _editor->verbose_cursor()->set_text (_point->line().get_verbose_cursor_string (fraction)); + show_verbose_cursor_text (_point->line().get_verbose_cursor_string (fraction)); } void @@ -3442,10 +3671,7 @@ LineDrag::start_grab (GdkEvent* event, Gdk::Cursor* /*cursor*/) _line->start_drag_line (before, after, fraction); - _editor->verbose_cursor()->set (_line->get_verbose_cursor_string (fraction), - event->button.x + 10, event->button.y + 10); - - _editor->verbose_cursor()->show (); + show_verbose_cursor_text (_line->get_verbose_cursor_string (fraction)); } void @@ -3470,7 +3696,7 @@ LineDrag::motion (GdkEvent* event, bool) /* we are ignoring x position for this drag, so we can just pass in anything */ _line->drag_motion (0, fraction, true, false, ignored); - _editor->verbose_cursor()->set_text (_line->get_verbose_cursor_string (fraction)); + show_verbose_cursor_text (_line->get_verbose_cursor_string (fraction)); } void @@ -4850,9 +5076,13 @@ AutomationRangeDrag::aborted (bool) } } -DraggingView::DraggingView (RegionView* v, RegionDrag* parent) +DraggingView::DraggingView (RegionView* v, RegionDrag* parent, TimeAxisView* itav) : view (v) + , initial_time_axis_view (itav) { + /* note that time_axis_view may be null if the regionview was created + * as part of a copy operation. + */ time_axis_view = parent->find_time_axis_view (&v->get_time_axis_view ()); layer = v->region()->layer (); initial_y = v->get_canvas_group()->position().y;