X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Feditor_drag.cc;h=0c309d723458ddb727de2def826b36fc0421d27d;hb=2b8fc2a43b155d9a22d68554508181dd0894b69d;hp=8157011c5a9be9a30a7c711f38c4309d2e90df0b;hpb=e89bdcd9ebb774294119cf349b3faaf0fa9ffd1f;p=ardour.git diff --git a/gtk2_ardour/editor_drag.cc b/gtk2_ardour/editor_drag.cc index 8157011c5a..0c309d7234 100644 --- a/gtk2_ardour/editor_drag.cc +++ b/gtk2_ardour/editor_drag.cc @@ -899,9 +899,7 @@ RegionMoveDrag::finished (GdkEvent* ev, bool movement_occurred) } - if (_editor->session() && Config->get_always_play_range()) { - _editor->session()->request_locate (_editor->get_selection().regions.start()); - } + _editor->maybe_locate_with_edit_preroll (_editor->get_selection().regions.start()); } void @@ -1599,10 +1597,11 @@ NoteResizeDrag::aborted (bool) } } -TrimDrag::TrimDrag (Editor* e, ArdourCanvas::Item* i, RegionView* p, list const & v) +TrimDrag::TrimDrag (Editor* e, ArdourCanvas::Item* i, RegionView* p, list const & v, bool preserve_fade_anchor) : RegionDrag (e, i, p, v) { DEBUG_TRACE (DEBUG::Drags, "New TrimDrag\n"); + _preserve_fade_anchor = preserve_fade_anchor; } void @@ -1724,13 +1723,41 @@ TrimDrag::motion (GdkEvent* event, bool first_move) switch (_operation) { case StartTrim: for (list::const_iterator i = _views.begin(); i != _views.end(); ++i) { - i->view->trim_front (i->initial_position + dt, non_overlap_trim); + bool changed = i->view->trim_front (i->initial_position + dt, non_overlap_trim); + if (changed && _preserve_fade_anchor) { + AudioRegionView* arv = dynamic_cast (i->view); + if (arv) { + double distance; + double new_length; + framecnt_t len; + boost::shared_ptr ar (arv->audio_region()); + distance = _drags->current_pointer_x() - grab_x(); + len = ar->fade_in()->back()->when; + new_length = len - _editor->unit_to_frame (distance); + new_length = ar->verify_xfade_bounds (new_length, true /*START*/ ); + arv->reset_fade_in_shape_width (ar, new_length); //the grey shape + } + } } break; case EndTrim: for (list::const_iterator i = _views.begin(); i != _views.end(); ++i) { - i->view->trim_end (i->initial_end + dt, non_overlap_trim); + bool changed = i->view->trim_end (i->initial_end + dt, non_overlap_trim); + if (changed && _preserve_fade_anchor) { + AudioRegionView* arv = dynamic_cast (i->view); + if (arv) { + double distance; + double new_length; + framecnt_t len; + boost::shared_ptr ar (arv->audio_region()); + distance = grab_x() - _drags->current_pointer_x(); + len = ar->fade_out()->back()->when; + new_length = len - _editor->unit_to_frame (distance); + new_length = ar->verify_xfade_bounds (new_length, false /*END*/ ); + arv->reset_fade_out_shape_width (ar, new_length); //the grey shape + } + } } break; @@ -1782,16 +1809,56 @@ TrimDrag::finished (GdkEvent* event, bool movement_occurred) if (movement_occurred) { motion (event, false); - /* This must happen before the region's StatefulDiffCommand is created, as it may - `correct' (ahem) the region's _start from being negative to being zero. It - needs to be zero in the undo record. - */ if (_operation == StartTrim) { for (list::const_iterator i = _views.begin(); i != _views.end(); ++i) { - i->view->trim_front_ending (); + { + /* This must happen before the region's StatefulDiffCommand is created, as it may + `correct' (ahem) the region's _start from being negative to being zero. It + needs to be zero in the undo record. + */ + i->view->trim_front_ending (); + } + if (_preserve_fade_anchor) { + AudioRegionView* arv = dynamic_cast (i->view); + if (arv) { + double distance; + double new_length; + framecnt_t len; + boost::shared_ptr ar (arv->audio_region()); + distance = _drags->current_pointer_x() - grab_x(); + len = ar->fade_in()->back()->when; + new_length = len - _editor->unit_to_frame (distance); + new_length = ar->verify_xfade_bounds (new_length, true /*START*/ ); + ar->set_fade_in_length(new_length); + } + } + } + } else if (_operation == EndTrim) { + for (list::const_iterator i = _views.begin(); i != _views.end(); ++i) { + if (_preserve_fade_anchor) { + AudioRegionView* arv = dynamic_cast (i->view); + if (arv) { + double distance; + double new_length; + framecnt_t len; + boost::shared_ptr ar (arv->audio_region()); + distance = _drags->current_pointer_x() - grab_x(); + len = ar->fade_out()->back()->when; + new_length = len - _editor->unit_to_frame (distance); + new_length = ar->verify_xfade_bounds (new_length, false /*END*/ ); + ar->set_fade_out_length(new_length); + } + } } } - + + if (_operation == StartTrim) { + _editor->maybe_locate_with_edit_preroll ( _views.begin()->view->region()->position() ); + } + if (_operation == EndTrim) { + _editor->maybe_locate_with_edit_preroll ( _views.begin()->view->region()->position() + _views.begin()->view->region()->length() ); + } + if (!_editor->selection->selected (_primary)) { _primary->thaw_after_trim (); } else { @@ -1817,6 +1884,7 @@ TrimDrag::finished (GdkEvent* event, bool movement_occurred) } } } + for (set >::iterator p = _editor->motion_frozen_playlists.begin(); p != _editor->motion_frozen_playlists.end(); ++p) { (*p)->thaw (); } @@ -1824,10 +1892,6 @@ TrimDrag::finished (GdkEvent* event, bool movement_occurred) _editor->motion_frozen_playlists.clear (); _editor->commit_reversible_command(); - for (list::const_iterator i = _views.begin(); i != _views.end(); ++i) { - i->view->drag_end (); - } - } else { /* no mouse movement */ _editor->point_trim (event, adjusted_current_frame (event)); @@ -2248,8 +2312,6 @@ FadeInDrag::start_grab (GdkEvent* event, Gdk::Cursor* cursor) boost::shared_ptr const r = arv->audio_region (); show_verbose_cursor_duration (r->position(), r->position() + r->fade_in()->back()->when, 32); - - arv->show_fade_line((framepos_t) r->fade_in()->back()->when); } void @@ -2285,8 +2347,7 @@ FadeInDrag::motion (GdkEvent* event, bool) continue; } - tmp->reset_fade_in_shape_width (fade_length); - tmp->show_fade_line((framecnt_t) fade_length); + tmp->reset_fade_in_shape_width (tmp->audio_region(), fade_length); } show_verbose_cursor_duration (region->position(), region->position() + fade_length, 32); @@ -2328,7 +2389,6 @@ FadeInDrag::finished (GdkEvent* event, bool movement_occurred) tmp->audio_region()->set_fade_in_length (fade_length); tmp->audio_region()->set_fade_in_active (true); - tmp->hide_fade_line(); XMLNode &after = alist->get_state(); _editor->session()->add_command(new MementoCommand(*alist.get(), &before, &after)); @@ -2347,8 +2407,7 @@ FadeInDrag::aborted (bool) continue; } - tmp->reset_fade_in_shape_width (tmp->audio_region()->fade_in()->back()->when); - tmp->hide_fade_line(); + tmp->reset_fade_in_shape_width (tmp->audio_region(), tmp->audio_region()->fade_in()->back()->when); } } @@ -2367,8 +2426,6 @@ FadeOutDrag::start_grab (GdkEvent* event, Gdk::Cursor* cursor) boost::shared_ptr r = arv->audio_region (); show_verbose_cursor_duration (r->last_frame() - r->fade_out()->back()->when, r->last_frame()); - - arv->show_fade_line(r->length() - r->fade_out()->back()->when); } void @@ -2406,8 +2463,7 @@ FadeOutDrag::motion (GdkEvent* event, bool) continue; } - tmp->reset_fade_out_shape_width (fade_length); - tmp->show_fade_line(region->length() - fade_length); + tmp->reset_fade_out_shape_width (tmp->audio_region(), fade_length); } show_verbose_cursor_duration (region->last_frame() - fade_length, region->last_frame()); @@ -2451,7 +2507,6 @@ FadeOutDrag::finished (GdkEvent* event, bool movement_occurred) tmp->audio_region()->set_fade_out_length (fade_length); tmp->audio_region()->set_fade_out_active (true); - tmp->hide_fade_line(); XMLNode &after = alist->get_state(); _editor->session()->add_command(new MementoCommand(*alist.get(), &before, &after)); @@ -2470,8 +2525,7 @@ FadeOutDrag::aborted (bool) continue; } - tmp->reset_fade_out_shape_width (tmp->audio_region()->fade_out()->back()->when); - tmp->hide_fade_line(); + tmp->reset_fade_out_shape_width (tmp->audio_region(), tmp->audio_region()->fade_out()->back()->when); } } @@ -2831,6 +2885,8 @@ ControlPointDrag::start_grab (GdkEvent* event, Gdk::Cursor* /*cursor*/) _editor->verbose_cursor()->show (); + _pushing = Keyboard::modifier_state_contains (event->button.state, Keyboard::PrimaryModifier); + if (!_point->can_slide ()) { _x_constrained = true; } @@ -2885,9 +2941,7 @@ ControlPointDrag::motion (GdkEvent* event, bool) float const fraction = 1.0 - (cy / _point->line().height()); - bool const push = Keyboard::modifier_state_contains (event->button.state, Keyboard::PrimaryModifier); - - _point->line().drag_motion (_editor->frame_to_unit_unrounded (cx_frames), fraction, false, push); + _point->line().drag_motion (_editor->frame_to_unit_unrounded (cx_frames), fraction, false, _pushing, _final_index); _editor->verbose_cursor()->set_text (_point->line().get_verbose_cursor_string (fraction)); } @@ -2907,7 +2961,7 @@ ControlPointDrag::finished (GdkEvent* event, bool movement_occurred) motion (event, false); } - _point->line().end_drag (); + _point->line().end_drag (_pushing, _final_index); _editor->session()->commit_reversible_command (); } @@ -2998,10 +3052,10 @@ LineDrag::motion (GdkEvent* event, bool) cy = min ((double) _line->height(), cy); double const fraction = 1.0 - (cy / _line->height()); - bool const push = !Keyboard::modifier_state_contains (event->button.state, Keyboard::PrimaryModifier); + uint32_t ignored; /* we are ignoring x position for this drag, so we can just pass in anything */ - _line->drag_motion (0, fraction, true, push); + _line->drag_motion (0, fraction, true, false, ignored); _editor->verbose_cursor()->set_text (_line->get_verbose_cursor_string (fraction)); } @@ -3010,7 +3064,7 @@ void LineDrag::finished (GdkEvent* event, bool) { motion (event, false); - _line->end_drag (); + _line->end_drag (false, 0); _editor->session()->commit_reversible_command (); } @@ -3228,7 +3282,13 @@ RubberbandSelectDrag::finished (GdkEvent* event, bool movement_occurred) } } - if (do_deselect) { + /* do not deselect if Primary or Tertiary (toggle-select or + * extend-select are pressed. + */ + + if (!Keyboard::modifier_state_contains (event->button.state, Keyboard::PrimaryModifier) && + !Keyboard::modifier_state_contains (event->button.state, Keyboard::TertiaryModifier) && + do_deselect) { deselect_things (); } @@ -3356,12 +3416,18 @@ ScrubDrag::aborted (bool) SelectionDrag::SelectionDrag (Editor* e, ArdourCanvas::Item* i, Operation o) : Drag (e, i) , _operation (o) - , _copy (false) + , _add (false) + , _extend (false) , _original_pointer_time_axis (-1) , _last_pointer_time_axis (-1) , _time_selection_at_start (!_editor->get_selection().time.empty()) { DEBUG_TRACE (DEBUG::Drags, "New SelectionDrag\n"); + + if (_time_selection_at_start) { + start_at_start = _editor->get_selection().time.start(); + end_at_start = _editor->get_selection().time.end_frame(); + } } void @@ -3375,10 +3441,10 @@ SelectionDrag::start_grab (GdkEvent* event, Gdk::Cursor*) switch (_operation) { case CreateSelection: - if (Keyboard::modifier_state_equals (event->button.state, Keyboard::TertiaryModifier)) { - _copy = true; + if (Keyboard::modifier_state_equals (event->button.state, Keyboard::CopyModifier)) { + _add = true; } else { - _copy = false; + _add = false; } cursor = _editor->cursors()->selector; Drag::start_grab (event, cursor); @@ -3401,6 +3467,10 @@ SelectionDrag::start_grab (GdkEvent* event, Gdk::Cursor*) case SelectionMove: Drag::start_grab (event, cursor); break; + + case SelectionExtend: + Drag::start_grab (event, cursor); + break; } if (_operation == SelectionMove) { @@ -3428,6 +3498,9 @@ SelectionDrag::setup_pointer_frame_offset () case SelectionEndTrim: _pointer_frame_offset = raw_grab_frame() - _editor->selection->time[_editor->clicked_selection].end; break; + + case SelectionExtend: + break; } } @@ -3436,7 +3509,8 @@ SelectionDrag::motion (GdkEvent* event, bool first_move) { framepos_t start = 0; framepos_t end = 0; - framecnt_t length; + framecnt_t length = 0; + framecnt_t distance = 0; pair const pending_time_axis = _editor->trackview_by_y_position (_drags->current_pointer_y ()); if (pending_time_axis.first == 0) { @@ -3457,10 +3531,15 @@ SelectionDrag::motion (GdkEvent* event, bool first_move) framepos_t grab = grab_frame (); if (first_move) { - _editor->snap_to (grab); + grab = adjusted_current_frame (event, false); + if (grab < pending_position) { + _editor->snap_to (grab, -1); + } else { + _editor->snap_to (grab, 1); + } } - if (pending_position < grab_frame()) { + if (pending_position < grab) { start = pending_position; end = grab; } else { @@ -3474,12 +3553,12 @@ SelectionDrag::motion (GdkEvent* event, bool first_move) if (first_move) { - if (_copy) { + if (_add) { /* adding to the selection */ _editor->set_selected_track_as_side_effect (Selection::Add); //_editor->selection->add (_editor->clicked_axisview); _editor->clicked_selection = _editor->selection->add (start, end); - _copy = false; + _add = false; } else { /* new selection */ @@ -3547,20 +3626,23 @@ SelectionDrag::motion (GdkEvent* event, bool first_move) } break; - + case SelectionMove: start = _editor->selection->time[_editor->clicked_selection].start; end = _editor->selection->time[_editor->clicked_selection].end; length = end - start; - + distance = pending_position - start; start = pending_position; _editor->snap_to (start); end = start + length; break; + + case SelectionExtend: + break; } if (event->button.x >= _editor->horizontal_position() + _editor->_canvas_width) { @@ -3568,7 +3650,15 @@ SelectionDrag::motion (GdkEvent* event, bool first_move) } if (start != end) { - _editor->selection->replace (_editor->clicked_selection, start, end); + switch (_operation) { + case SelectionMove: + if (_time_selection_at_start) { + _editor->selection->move_time (distance); + } + break; + default: + _editor->selection->replace (_editor->clicked_selection, start, end); + } } if (_operation == SelectionMove) { @@ -3592,13 +3682,11 @@ SelectionDrag::finished (GdkEvent* event, bool movement_occurred) /* XXX what if its a music time selection? */ if (s) { - if ((s->config.get_auto_play() || (s->get_play_range() && s->transport_rolling()))) { + if ( s->get_play_range() && s->transport_rolling() ) { s->request_play_range (&_editor->selection->time, true); } else { - if (Config->get_always_play_range()) { - if (_editor->doing_range_stuff()) { - s->request_locate (_editor->get_selection().time.start()); - } + if (Config->get_always_play_range() && !s->transport_rolling()) { + s->request_locate (_editor->get_selection().time.start()); } } } @@ -3607,44 +3695,37 @@ SelectionDrag::finished (GdkEvent* event, bool movement_occurred) /* just a click, no pointer movement. */ - if (Keyboard::no_modifier_keys_pressed (&event->button)) { - if (!_time_selection_at_start) { - if (_editor->clicked_regionview) { - if (_editor->get_selection().selected (_editor->clicked_regionview)) { - /* range select the entire current - region selection - */ - _editor->select_range (_editor->get_selection().regions.start(), - _editor->get_selection().regions.end_frame()); - } else { - /* range select this (unselected) - * region - */ - _editor->select_range (_editor->clicked_regionview->region()->position(), - _editor->clicked_regionview->region()->last_frame()); - } + if (_operation == SelectionExtend) { + if (_time_selection_at_start) { + framepos_t pos = adjusted_current_frame (event, false); + framepos_t start = min (pos, start_at_start); + framepos_t end = max (pos, end_at_start); + _editor->selection->set (start, end); + } + } else { + if (Keyboard::modifier_state_equals (event->button.state, Keyboard::CopyModifier)) { + if (_editor->clicked_selection) { + _editor->selection->remove (_editor->clicked_selection); } } else { - _editor->selection->clear_time(); + if (!_editor->clicked_selection) { + _editor->selection->clear_time(); + } } } if (_editor->clicked_axisview && !_editor->selection->selected (_editor->clicked_axisview)) { _editor->selection->set (_editor->clicked_axisview); } - + if (s && s->get_play_range () && s->transport_rolling()) { s->request_stop (false, false); } - if (Config->get_always_play_range()) { - if (_editor->doing_range_stuff()) { - s->request_locate (_editor->get_selection().time.start()); - } - } } _editor->stop_canvas_autoscroll (); + _editor->clicked_selection = 0; } void @@ -3718,7 +3799,7 @@ RangeMarkerBarDrag::motion (GdkEvent* event, bool first_move) crect = _editor->cd_marker_bar_drag_rect; break; default: - cerr << "Error: unknown range marker op passed to Editor::drag_range_markerbar_op ()" << endl; + error << string_compose (_("programming_error: %1"), "Error: unknown range marker op passed to Editor::drag_range_markerbar_op ()") << endmsg; return; break; } @@ -4106,7 +4187,7 @@ AutomationRangeDrag::AutomationRangeDrag (Editor* editor, AutomationTimeAxisView , _nothing_to_drag (false) { DEBUG_TRACE (DEBUG::Drags, "New AutomationRangeDrag\n"); - track_view = atv; + y_origin = atv->y_position(); setup (atv->lines ()); } @@ -4120,7 +4201,7 @@ AutomationRangeDrag::AutomationRangeDrag (Editor* editor, AudioRegionView* rv, l list > lines; lines.push_back (rv->get_gain_line ()); - track_view = &rv->get_time_axis_view(); + y_origin = rv->get_time_axis_view().y_position(); setup (lines); } @@ -4162,6 +4243,12 @@ AutomationRangeDrag::setup (list > const & lin /* Now ::lines contains the AutomationLines that somehow overlap our drag */ } +double +AutomationRangeDrag::y_fraction (boost::shared_ptr line, double global_y) const +{ + return 1.0 - ((global_y - y_origin) / line->height()); +} + void AutomationRangeDrag::start_grab (GdkEvent* event, Gdk::Cursor* cursor) { @@ -4170,7 +4257,7 @@ AutomationRangeDrag::start_grab (GdkEvent* event, Gdk::Cursor* cursor) /* Get line states before we start changing things */ for (list::iterator i = _lines.begin(); i != _lines.end(); ++i) { i->state = &i->line->get_state (); - i->original_fraction = 1 - ((_drags->current_pointer_y() - track_view->y_position()) / i->line->height()); + i->original_fraction = y_fraction (i->line, _drags->current_pointer_y()); } if (_ranges.empty()) { @@ -4276,7 +4363,7 @@ AutomationRangeDrag::start_grab (GdkEvent* event, Gdk::Cursor* cursor) } for (list::iterator i = _lines.begin(); i != _lines.end(); ++i) { - i->line->start_drag_multiple (i->points, 1 - ((_drags->current_pointer_y() - track_view->y_position()) / i->line->height ()), i->state); + i->line->start_drag_multiple (i->points, y_fraction (i->line, _drags->current_pointer_y()), i->state); } } @@ -4288,10 +4375,10 @@ AutomationRangeDrag::motion (GdkEvent*, bool /*first_move*/) } for (list::iterator l = _lines.begin(); l != _lines.end(); ++l) { - float const f = 1 - ((_drags->current_pointer_y() - track_view->y_position()) / l->line->height()); - + float const f = y_fraction (l->line, _drags->current_pointer_y()); /* we are ignoring x position for this drag, so we can just pass in anything */ - l->line->drag_motion (0, f, true, false); + uint32_t ignored; + l->line->drag_motion (0, f, true, false, ignored); show_verbose_cursor_text (l->line->get_verbose_cursor_relative_string (l->original_fraction, f)); } } @@ -4305,7 +4392,7 @@ AutomationRangeDrag::finished (GdkEvent* event, bool) motion (event, false); for (list::iterator i = _lines.begin(); i != _lines.end(); ++i) { - i->line->end_drag (); + i->line->end_drag (false, 0); } _editor->session()->commit_reversible_command (); @@ -4590,6 +4677,7 @@ CrossfadeEdgeDrag::CrossfadeEdgeDrag (Editor* e, AudioRegionView* rv, ArdourCanv , arv (rv) , start (start_yn) { + std::cout << ("CrossfadeEdgeDrag is DEPRECATED. See TrimDrag::preserve_fade_anchor") << endl; } void