X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Feditor_drag.cc;h=00313d06720b41d00cba917179c48c96f185fa18;hb=ad942b104a80c74c689e0c1b5c016d1870850830;hp=d069e2e984f107e56b18ac70cdaa59e34d433f80;hpb=d83219706fe8d3f6350848e7e0f5db7c710399dd;p=ardour.git diff --git a/gtk2_ardour/editor_drag.cc b/gtk2_ardour/editor_drag.cc index d069e2e984..00313d0672 100644 --- a/gtk2_ardour/editor_drag.cc +++ b/gtk2_ardour/editor_drag.cc @@ -32,6 +32,8 @@ #include "ardour/session.h" #include "ardour/dB.h" #include "ardour/region_factory.h" +#include "ardour/operations.h" + #include "editor.h" #include "i18n.h" #include "keyboard.h" @@ -91,6 +93,8 @@ DragManager::abort () _drags.clear (); + _editor->set_follow_playhead (_old_follow_playhead, false); + _ending = false; } @@ -112,6 +116,10 @@ DragManager::set (Drag* d, GdkEvent* e, Gdk::Cursor* c) void DragManager::start_grab (GdkEvent* e, Gdk::Cursor* c) { + /* Prevent follow playhead during the drag to be nice to the user */ + _old_follow_playhead = _editor->follow_playhead (); + _editor->set_follow_playhead (false); + _current_pointer_frame = _editor->event_frame (e, &_current_pointer_x, &_current_pointer_y); for (list::const_iterator i = _drags.begin(); i != _drags.end(); ++i) { @@ -139,6 +147,8 @@ DragManager::end_grab (GdkEvent* e) _drags.clear (); _ending = false; + + _editor->set_follow_playhead (_old_follow_playhead, false); return r; } @@ -306,7 +316,7 @@ Drag::motion_handler (GdkEvent* event, bool from_autoscroll) if (!from_autoscroll && !_move_threshold_passed) { - bool const xp = (::llabs (_drags->current_pointer_frame () - _grab_frame) >= threshold.first); + bool const xp = (::llabs (_drags->current_pointer_frame () - _raw_grab_frame) >= threshold.first); bool const yp = (::fabs ((_drags->current_pointer_y () - _grab_y)) >= threshold.second); _move_threshold_passed = ((xp && x_movement_matters()) || (yp && y_movement_matters())); @@ -339,7 +349,7 @@ Drag::abort () _item->ungrab (0); } - aborted (); + aborted (_move_threshold_passed); _editor->stop_canvas_autoscroll (); _editor->hide_verbose_canvas_cursor (); @@ -897,7 +907,7 @@ RegionMoveDrag::finished_no_copy ( if (_x_constrained) { _editor->begin_reversible_command (_("fixed time region drag")); } else { - _editor->begin_reversible_command (_("region drag")); + _editor->begin_reversible_command (Operations::region_drag); } for (list::const_iterator i = _views.begin(); i != _views.end(); ) { @@ -1124,7 +1134,7 @@ RegionMoveDrag::add_stateful_diff_commands_for_playlists (PlaylistSet const & pl for (PlaylistSet::const_iterator i = playlists.begin(); i != playlists.end(); ++i) { StatefulDiffCommand* c = new StatefulDiffCommand (*i); if (!c->empty()) { - _editor->session()->add_command (new StatefulDiffCommand (*i)); + _editor->session()->add_command (c); } else { delete c; } @@ -1133,7 +1143,7 @@ RegionMoveDrag::add_stateful_diff_commands_for_playlists (PlaylistSet const & pl void -RegionMoveDrag::aborted () +RegionMoveDrag::aborted (bool movement_occurred) { if (_copy) { @@ -1144,12 +1154,12 @@ RegionMoveDrag::aborted () _views.clear (); } else { - RegionMotionDrag::aborted (); + RegionMotionDrag::aborted (movement_occurred); } } void -RegionMotionDrag::aborted () +RegionMotionDrag::aborted (bool) { for (list::const_iterator i = _views.begin(); i != _views.end(); ++i) { RegionView* rv = i->view; @@ -1166,7 +1176,10 @@ RegionMotionDrag::aborted () _editor->update_canvas_now (); } - + +/** @param b true to brush, otherwise false. + * @param c true to make copies of the regions being moved, otherwise false. + */ RegionMoveDrag::RegionMoveDrag (Editor* e, ArdourCanvas::Item* i, RegionView* p, list const & v, bool b, bool c) : RegionMotionDrag (e, i, p, v, b), _copy (c) @@ -1219,7 +1232,7 @@ RegionInsertDrag::finished (GdkEvent *, bool) boost::shared_ptr playlist = dest_rtv->playlist(); - _editor->begin_reversible_command (_("insert region")); + _editor->begin_reversible_command (Operations::insert_region); playlist->clear_changes (); playlist->add_region (_primary->region (), _last_frame_position); _editor->session()->add_command (new StatefulDiffCommand (playlist)); @@ -1231,7 +1244,7 @@ RegionInsertDrag::finished (GdkEvent *, bool) } void -RegionInsertDrag::aborted () +RegionInsertDrag::aborted (bool) { delete _primary; _primary = 0; @@ -1330,7 +1343,7 @@ RegionSpliceDrag::finished (GdkEvent* event, bool movement_occurred) } void -RegionSpliceDrag::aborted () +RegionSpliceDrag::aborted (bool) { /* XXX: TODO */ } @@ -1349,6 +1362,7 @@ RegionCreateDrag::motion (GdkEvent* event, bool first_move) { if (first_move) { add_region(); + _view->playlist()->freeze (); } else { if (_region) { framepos_t const f = adjusted_current_frame (event); @@ -1368,6 +1382,8 @@ RegionCreateDrag::finished (GdkEvent*, bool movement_occurred) { if (!movement_occurred) { add_region (); + } else { + _view->playlist()->thaw (); } if (_region) { @@ -1391,8 +1407,12 @@ RegionCreateDrag::add_region () } void -RegionCreateDrag::aborted () +RegionCreateDrag::aborted (bool) { + if (_region) { + _view->playlist()->thaw (); + } + /* XXX */ } @@ -1479,7 +1499,7 @@ NoteResizeDrag::finished (GdkEvent*, bool /*movement_occurred*/) } void -NoteResizeDrag::aborted () +NoteResizeDrag::aborted (bool) { /* XXX: TODO */ } @@ -1503,14 +1523,13 @@ RegionGainDrag::finished (GdkEvent *, bool) } void -RegionGainDrag::aborted () +RegionGainDrag::aborted (bool) { /* XXX: TODO */ } TrimDrag::TrimDrag (Editor* e, ArdourCanvas::Item* i, RegionView* p, list const & v) : RegionDrag (e, i, p, v) - , _have_transaction (false) { DEBUG_TRACE (DEBUG::Drags, "New TrimDrag\n"); } @@ -1602,13 +1621,12 @@ TrimDrag::motion (GdkEvent* event, bool first_move) } _editor->begin_reversible_command (trim_type); - _have_transaction = true; for (list::const_iterator i = _views.begin(); i != _views.end(); ++i) { RegionView* rv = i->view; rv->fake_set_opaque (false); rv->enable_display (false); - rv->region()->clear_changes (); + rv->region()->playlist()->clear_owned_changes (); AudioRegionView* const arv = dynamic_cast (rv); @@ -1706,12 +1724,24 @@ TrimDrag::finished (GdkEvent* event, bool movement_occurred) _primary->thaw_after_trim (); } else { + set > diffed_playlists; + for (list::const_iterator i = _views.begin(); i != _views.end(); ++i) { - i->view->thaw_after_trim (); + i->view->thaw_after_trim (); i->view->enable_display (true); i->view->fake_set_opaque (true); - if (_have_transaction) { - _editor->session()->add_command (new StatefulDiffCommand (i->view->region())); + + /* Trimming one region may affect others on the playlist, so we need + to get undo Commands from the whole playlist rather than just the + region. Use diffed_playlists to make sure we don't diff a given + playlist more than once. + */ + boost::shared_ptr p = i->view->region()->playlist (); + if (diffed_playlists.find (p) == diffed_playlists.end()) { + vector cmds; + p->rdiff (cmds); + _editor->session()->add_commands (cmds); + diffed_playlists.insert (p); } } } @@ -1720,9 +1750,7 @@ TrimDrag::finished (GdkEvent* event, bool movement_occurred) } _editor->motion_frozen_playlists.clear (); - if (_have_transaction) { - _editor->commit_reversible_command(); - } + _editor->commit_reversible_command(); } else { /* no mouse movement */ @@ -1739,7 +1767,7 @@ TrimDrag::finished (GdkEvent* event, bool movement_occurred) } void -TrimDrag::aborted () +TrimDrag::aborted (bool movement_occurred) { /* Our motion method is changing model state, so use the Undo system to cancel. Perhaps not ideal, as this will leave an Undo point @@ -1748,7 +1776,7 @@ TrimDrag::aborted () finished (0, true); - if (_have_transaction) { + if (movement_occurred) { _editor->undo (); } @@ -1776,6 +1804,8 @@ TrimDrag::setup_pointer_frame_offset () case EndTrim: _pointer_frame_offset = raw_grab_frame() - i->initial_end; break; + case ContentsTrim: + break; } } @@ -1801,7 +1831,6 @@ MeterMarkerDrag::start_grab (GdkEvent* event, Gdk::Cursor* cursor) MeterMarker* new_marker = new MeterMarker ( *_editor, *_editor->meter_group, - *_editor->cursor_group, ARDOUR_UI::config()->canvasvar_MeterMarker.get(), name, *new MeterSection (_marker->meter()) @@ -1877,7 +1906,7 @@ MeterMarkerDrag::finished (GdkEvent* event, bool movement_occurred) } void -MeterMarkerDrag::aborted () +MeterMarkerDrag::aborted (bool) { _marker->set_position (_marker->meter().frame ()); } @@ -1905,7 +1934,6 @@ TempoMarkerDrag::start_grab (GdkEvent* event, Gdk::Cursor* cursor) TempoMarker* new_marker = new TempoMarker ( *_editor, *_editor->tempo_group, - *_editor->cursor_group, ARDOUR_UI::config()->canvasvar_TempoMarker.get(), name, *new TempoSection (_marker->tempo()) @@ -1971,7 +1999,7 @@ TempoMarkerDrag::finished (GdkEvent* event, bool movement_occurred) } void -TempoMarkerDrag::aborted () +TempoMarkerDrag::aborted (bool) { _marker->set_position (_marker->tempo().frame()); } @@ -1983,17 +2011,33 @@ CursorDrag::CursorDrag (Editor* e, ArdourCanvas::Item* i, bool s) DEBUG_TRACE (DEBUG::Drags, "New CursorDrag\n"); } +/** Do all the things we do when dragging the playhead to make it look as though + * we have located, without actually doing the locate (because that would cause + * the diskstream buffers to be refilled, which is too slow). + */ +void +CursorDrag::fake_locate (framepos_t t) +{ + _editor->playhead_cursor->set_position (t); + + Session* s = _editor->session (); + if (s->timecode_transmission_suspended ()) { + framepos_t const f = _editor->playhead_cursor->current_frame; + s->send_mmc_locate (f); + s->send_full_time_code (f); + } + + _editor->show_verbose_time_cursor (t, 10); + _editor->UpdateAllTransportClocks (t); +} + void CursorDrag::start_grab (GdkEvent* event, Gdk::Cursor* c) { Drag::start_grab (event, c); - if (!_stop) { - framepos_t where = _editor->event_frame (event, 0, 0); - - _editor->snap_to_with_modifier (where, event); - _editor->playhead_cursor->set_position (where); - } + framepos_t where = _editor->event_frame (event, 0, 0); + _editor->snap_to_with_modifier (where, event); _editor->_dragging_playhead = true; @@ -2009,16 +2053,12 @@ CursorDrag::start_grab (GdkEvent* event, Gdk::Cursor* c) } s->request_suspend_timecode_transmission (); - - if (s->timecode_transmission_suspended ()) { - framepos_t const f = _editor->playhead_cursor->current_frame; - s->send_mmc_locate (f); - s->send_full_time_code (f); + while (!s->timecode_transmission_suspended ()) { + /* twiddle our thumbs */ } } - - _editor->show_verbose_time_cursor (_editor->playhead_cursor->current_frame, 10); - _editor->UpdateAllTransportClocks (_editor->playhead_cursor->current_frame); + + fake_locate (where); } void @@ -2030,22 +2070,11 @@ CursorDrag::motion (GdkEvent* event, bool) return; } - _editor->playhead_cursor->set_position (adjusted_frame); - - _editor->show_verbose_time_cursor (_editor->playhead_cursor->current_frame, 10); - - Session* s = _editor->session (); - if (s && s->timecode_transmission_suspended ()) { - framepos_t const f = _editor->playhead_cursor->current_frame; - s->send_mmc_locate (f); - s->send_full_time_code (f); - } + fake_locate (adjusted_frame); - #ifdef GTKOSX _editor->update_canvas_now (); #endif - _editor->UpdateAllTransportClocks (_editor->playhead_cursor->current_frame); } void @@ -2068,7 +2097,7 @@ CursorDrag::finished (GdkEvent* event, bool movement_occurred) } void -CursorDrag::aborted () +CursorDrag::aborted (bool) { if (_editor->_dragging_playhead) { _editor->session()->request_resume_timecode_transmission (); @@ -2183,7 +2212,7 @@ FadeInDrag::finished (GdkEvent* event, bool movement_occurred) } void -FadeInDrag::aborted () +FadeInDrag::aborted (bool) { for (list::iterator i = _views.begin(); i != _views.end(); ++i) { AudioRegionView* tmp = dynamic_cast (i->view); @@ -2306,7 +2335,7 @@ FadeOutDrag::finished (GdkEvent* event, bool movement_occurred) } void -FadeOutDrag::aborted () +FadeOutDrag::aborted (bool) { for (list::iterator i = _views.begin(); i != _views.end(); ++i) { AudioRegionView* tmp = dynamic_cast (i->view); @@ -2330,13 +2359,6 @@ MarkerDrag::MarkerDrag (Editor* e, ArdourCanvas::Item* i) _points.push_back (Gnome::Art::Point (0, 0)); _points.push_back (Gnome::Art::Point (0, physical_screen_height (_editor->get_window()))); - - _line = new ArdourCanvas::Line (*_editor->timebar_group); - _line->property_width_pixels() = 1; - _line->property_points () = _points; - _line->hide (); - - _line->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_MarkerDragLine.get(); } MarkerDrag::~MarkerDrag () @@ -2443,10 +2465,6 @@ MarkerDrag::motion (GdkEvent* event, bool) framepos_t next = newframe; - if (newframe == last_pointer_frame()) { - return; - } - if (Keyboard::modifier_state_equals (event->button.state, Keyboard::PrimaryModifier)) { move_both = true; } @@ -2540,7 +2558,7 @@ MarkerDrag::motion (GdkEvent* event, bool) copy_location->set_end (new_end); } else if (new_start < copy_location->end()) { copy_location->set_start (new_start); - } else { + } else if (newframe > 0) { _editor->snap_to (next, 1, true); copy_location->set_end (next); copy_location->set_start (newframe); @@ -2638,12 +2656,10 @@ MarkerDrag::finished (GdkEvent* event, bool movement_occurred) XMLNode &after = _editor->session()->locations()->get_state(); _editor->session()->add_command(new MementoCommand(*(_editor->session()->locations()), &before, &after)); _editor->commit_reversible_command (); - - _line->hide(); } void -MarkerDrag::aborted () +MarkerDrag::aborted (bool) { /* XXX: TODO */ } @@ -2651,11 +2667,7 @@ MarkerDrag::aborted () void MarkerDrag::update_item (Location* location) { - double const x1 = _editor->frame_to_pixel (location->start()); - - _points.front().set_x(x1); - _points.back().set_x(x1); - _line->property_points() = _points; + /* noop */ } ControlPointDrag::ControlPointDrag (Editor* e, ArdourCanvas::Item* i) @@ -2766,7 +2778,7 @@ ControlPointDrag::finished (GdkEvent* event, bool movement_occurred) } void -ControlPointDrag::aborted () +ControlPointDrag::aborted (bool) { _point->line().reset (); } @@ -2876,7 +2888,7 @@ LineDrag::finished (GdkEvent* event, bool) } void -LineDrag::aborted () +LineDrag::aborted (bool) { _line->reset (); } @@ -2894,7 +2906,7 @@ FeatureLineDrag::start_grab (GdkEvent* event, Gdk::Cursor* /*cursor*/) { Drag::start_grab (event); - _line = reinterpret_cast (_item); + _line = reinterpret_cast (_item); assert (_line); /* need to get x coordinate in terms of parent (AudioRegionView) origin. */ @@ -2907,10 +2919,10 @@ FeatureLineDrag::start_grab (GdkEvent* event, Gdk::Cursor* /*cursor*/) /* store grab start in parent frame */ _region_view_grab_x = cx; - _before = _line->property_x1(); + _before = *(float*) _item->get_data ("position"); _arv = reinterpret_cast (_item->get_data ("regionview")); - + _max_x = _editor->frame_to_pixel(_arv->get_duration()); } @@ -2932,21 +2944,34 @@ FeatureLineDrag::motion (GdkEvent*, bool) cx = 0; } - _line->property_x1() = cx; - _line->property_x2() = cx; + ArdourCanvas::Points points; + + double x1 = 0, x2 = 0, y1 = 0, y2 = 0; + + _line->get_bounds(x1, y2, x2, y2); + + points.push_back(Gnome::Art::Point(cx, 2.0)); // first x-coord needs to be a non-normal value + points.push_back(Gnome::Art::Point(cx, y2 - y1)); - _before = _line->property_x1(); + _line->property_points() = points; + + float *pos = new float; + *pos = cx; + + _line->set_data ("position", pos); + + _before = cx; } void FeatureLineDrag::finished (GdkEvent*, bool) { _arv = reinterpret_cast (_item->get_data ("regionview")); - _arv->update_transient(_before, _line->property_x1()); + _arv->update_transient(_before, _before); } void -FeatureLineDrag::aborted () +FeatureLineDrag::aborted (bool) { //_line->reset (); } @@ -3033,19 +3058,16 @@ RubberbandSelectDrag::finished (GdkEvent* event, bool movement_occurred) Selection::Operation op = ArdourKeyboard::selection_type (event->button.state); - bool committed; _editor->begin_reversible_command (_("rubberband selection")); if (grab_frame() < last_pointer_frame()) { - committed = _editor->select_all_within (grab_frame(), last_pointer_frame() - 1, y1, y2, _editor->track_views, op, false); + _editor->select_all_within (grab_frame(), last_pointer_frame() - 1, y1, y2, _editor->track_views, op, false); } else { - committed = _editor->select_all_within (last_pointer_frame(), grab_frame() - 1, y1, y2, _editor->track_views, op, false); + _editor->select_all_within (last_pointer_frame(), grab_frame() - 1, y1, y2, _editor->track_views, op, false); } - if (!committed) { - _editor->commit_reversible_command (); - } + _editor->commit_reversible_command (); } else { if (!getenv("ARDOUR_SAE")) { @@ -3060,7 +3082,7 @@ RubberbandSelectDrag::finished (GdkEvent* event, bool movement_occurred) } void -RubberbandSelectDrag::aborted () +RubberbandSelectDrag::aborted (bool) { _editor->rubberband_rect->hide (); } @@ -3131,7 +3153,7 @@ TimeFXDrag::finished (GdkEvent* /*event*/, bool movement_occurred) } void -TimeFXDrag::aborted () +TimeFXDrag::aborted (bool) { _primary->get_time_axis_view().hide_timestretch (); } @@ -3164,7 +3186,7 @@ ScrubDrag::finished (GdkEvent* /*event*/, bool movement_occurred) } void -ScrubDrag::aborted () +ScrubDrag::aborted (bool) { /* XXX: TODO */ } @@ -3432,7 +3454,7 @@ SelectionDrag::finished (GdkEvent* event, bool movement_occurred) } void -SelectionDrag::aborted () +SelectionDrag::aborted (bool) { /* XXX: TODO */ } @@ -3638,7 +3660,7 @@ RangeMarkerBarDrag::finished (GdkEvent* event, bool movement_occurred) } void -RangeMarkerBarDrag::aborted () +RangeMarkerBarDrag::aborted (bool) { /* XXX: TODO */ } @@ -3719,14 +3741,18 @@ MouseZoomDrag::finished (GdkEvent* event, bool movement_occurred) _editor->temporal_zoom_by_frame (last_pointer_frame(), grab_frame(), "mouse zoom"); } } else { - _editor->temporal_zoom_to_frame (_zoom_out, grab_frame()); + if (Keyboard::the_keyboard().key_is_down (GDK_Shift_L)) { + _editor->tav_zoom_step (_zoom_out); + } else { + _editor->temporal_zoom_to_frame (_zoom_out, grab_frame()); + } } _editor->zoom_rect->hide(); } void -MouseZoomDrag::aborted () +MouseZoomDrag::aborted (bool) { _editor->zoom_rect->hide (); } @@ -3868,7 +3894,7 @@ NoteDrag::finished (GdkEvent* ev, bool moved) } void -NoteDrag::aborted () +NoteDrag::aborted (bool) { /* XXX: TODO */ } @@ -4071,7 +4097,7 @@ AutomationRangeDrag::finished (GdkEvent* event, bool) } void -AutomationRangeDrag::aborted () +AutomationRangeDrag::aborted (bool) { for (list::iterator i = _lines.begin(); i != _lines.end(); ++i) { i->line->clear_always_in_view (); @@ -4090,17 +4116,17 @@ DraggingView::DraggingView (RegionView* v, RegionDrag* parent) initial_end = v->region()->position () + v->region()->length (); } -ProgramChangeDrag::ProgramChangeDrag (Editor* e, CanvasProgramChange* i, MidiRegionView* r) +PatchChangeDrag::PatchChangeDrag (Editor* e, CanvasPatchChange* i, MidiRegionView* r) : Drag (e, i) , _region_view (r) - , _program_change (i) + , _patch_change (i) , _cumulative_dx (0) { - DEBUG_TRACE (DEBUG::Drags, "New ProgramChangeDrag\n"); + DEBUG_TRACE (DEBUG::Drags, "New PatchChangeDrag\n"); } void -ProgramChangeDrag::motion (GdkEvent* ev, bool) +PatchChangeDrag::motion (GdkEvent* ev, bool) { framepos_t f = adjusted_current_frame (ev); boost::shared_ptr r = _region_view->region (); @@ -4109,12 +4135,12 @@ ProgramChangeDrag::motion (GdkEvent* ev, bool) framecnt_t const dxf = f - grab_frame(); double const dxu = _editor->frame_to_unit (dxf); - _program_change->move (dxu - _cumulative_dx, 0); + _patch_change->move (dxu - _cumulative_dx, 0); _cumulative_dx = dxu; } void -ProgramChangeDrag::finished (GdkEvent* ev, bool movement_occurred) +PatchChangeDrag::finished (GdkEvent* ev, bool movement_occurred) { if (!movement_occurred) { return; @@ -4126,22 +4152,22 @@ ProgramChangeDrag::finished (GdkEvent* ev, bool movement_occurred) f = max (f, r->position ()); f = min (f, r->last_frame ()); - _region_view->move_program_change ( - MidiRegionView::PCEvent (_program_change->event_time(), _program_change->program(), _program_change->channel()), + _region_view->move_patch_change ( + *_patch_change, _region_view->frames_to_beats (f - r->position() - r->start()) ); } void -ProgramChangeDrag::aborted () +PatchChangeDrag::aborted (bool) { - _program_change->move (-_cumulative_dx, 0); + _patch_change->move (-_cumulative_dx, 0); } void -ProgramChangeDrag::setup_pointer_frame_offset () +PatchChangeDrag::setup_pointer_frame_offset () { boost::shared_ptr region = _region_view->region (); - _pointer_frame_offset = raw_grab_frame() - _region_view->beats_to_frames (_program_change->event_time()) - region->position() + region->start(); + _pointer_frame_offset = raw_grab_frame() - _region_view->beats_to_frames (_patch_change->patch()->time()) - region->position() + region->start(); }