From 45bd2c47d80d337c01bddecf99f8fed2aae8b44d Mon Sep 17 00:00:00 2001 From: Ben Loftis Date: Tue, 15 Jun 2021 16:09:24 -0500 Subject: [PATCH] Brush Drag: refactor Brush-drag into its own Drag class (operation is still weird though) --- gtk2_ardour/editor.h | 4 +- gtk2_ardour/editor_drag.cc | 171 +++++++++++++++++++++--------------- gtk2_ardour/editor_drag.h | 29 ++++-- gtk2_ardour/editor_mouse.cc | 9 +- 4 files changed, 129 insertions(+), 84 deletions(-) diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h index 9281c2378b..3fbd0d756a 100644 --- a/gtk2_ardour/editor.h +++ b/gtk2_ardour/editor.h @@ -576,6 +576,8 @@ public: void do_remove_gaps (); void remove_gaps (samplecnt_t threshold, samplecnt_t leave, bool markers_too); + void mouse_brush_insert_region (RegionView*, samplepos_t pos); + void mouse_add_new_tempo_event (samplepos_t where); void mouse_add_new_meter_event (samplepos_t where); void edit_tempo_section (ARDOUR::TempoSection*); @@ -1608,8 +1610,6 @@ private: bool can_remove_control_point (ArdourCanvas::Item*); void remove_control_point (ArdourCanvas::Item*); - void mouse_brush_insert_region (RegionView*, samplepos_t pos); - /* Canvas event handlers */ bool canvas_scroll_event (GdkEventScroll* event, bool from_canvas); diff --git a/gtk2_ardour/editor_drag.cc b/gtk2_ardour/editor_drag.cc index 3b7acdbf4f..2e7a8c98eb 100644 --- a/gtk2_ardour/editor_drag.cc +++ b/gtk2_ardour/editor_drag.cc @@ -675,6 +675,20 @@ RegionDrag::setup_video_sample_offset () _preview_video = true; } +void +RegionDrag::add_stateful_diff_commands_for_playlists (PlaylistSet const & playlists) +{ + for (PlaylistSet::const_iterator i = playlists.begin(); i != playlists.end(); ++i) { + StatefulDiffCommand* c = new StatefulDiffCommand (*i); + if (!c->empty()) { + _editor->session()->add_command (c); + } else { + delete c; + } + } +} + + RegionSlipContentsDrag::RegionSlipContentsDrag (Editor* e, ArdourCanvas::Item* i, RegionView* p, list const & v) : RegionDrag (e, i, p, v) { @@ -731,9 +745,61 @@ RegionSlipContentsDrag::aborted (bool movement_occurred) } -RegionMotionDrag::RegionMotionDrag (Editor* e, ArdourCanvas::Item* i, RegionView* p, list const & v, bool b) +RegionBrushDrag::RegionBrushDrag (Editor* e, ArdourCanvas::Item* i, RegionView* p, list const & v) + : RegionDrag (e, i, p, v) +{ + DEBUG_TRACE (DEBUG::Drags, "New RegionBrushDrag\n"); + _y_constrained = true; +} + +void +RegionBrushDrag::start_grab (GdkEvent* event, Gdk::Cursor* cursor) +{ + Drag::start_grab (event, _editor->cursors()->trimmer); +} + +void +RegionBrushDrag::motion (GdkEvent* event, bool first_move) +{ + if (first_move) { + _editor->begin_reversible_command (_("Region brush drag")); + _already_pasted.insert(_primary->region()->position()); + } else { + MusicSample snapped (0, 0); + snapped.sample = adjusted_current_sample(event, false); + _editor->snap_to (snapped, RoundDownAlways, SnapToGrid_Scaled, false); + if(_already_pasted.find(snapped.sample) == _already_pasted.end()) { + _editor->mouse_brush_insert_region (_primary, snapped.sample); + _already_pasted.insert(snapped.sample); + } + } +} + +void +RegionBrushDrag::finished (GdkEvent *, bool movement_occurred) +{ + if (!movement_occurred) { + return; + } + + PlaylistSet modified_playlists; + modified_playlists.insert(_primary->region()->playlist()); + add_stateful_diff_commands_for_playlists(modified_playlists); + _editor->commit_reversible_command (); + _already_pasted.clear(); +} + +void +RegionBrushDrag::aborted (bool movement_occurred) +{ + _already_pasted.clear(); + + /* ToDo: revert to the original playlist properties */ + _editor->abort_reversible_command (); +} + +RegionMotionDrag::RegionMotionDrag (Editor* e, ArdourCanvas::Item* i, RegionView* p, list const & v) : RegionDrag (e, i, p, v) - , _brushing (b) , _ignore_video_lock (false) , _last_position (0, 0) , _total_x_delta (0) @@ -765,11 +831,6 @@ RegionMotionDrag::start_grab (GdkEvent* event, Gdk::Cursor* cursor) if (Keyboard::modifier_state_equals (event->button.state, Keyboard::ModifierMask (Keyboard::TertiaryModifier))) { _ignore_video_lock = true; } - - if (_brushing) { - /* cross track dragging seems broken here. disabled for now. */ - _y_constrained = true; - } } double @@ -1277,37 +1338,32 @@ RegionMotionDrag::motion (GdkEvent* event, bool first_move) i->time_axis_view = track_index; i->layer += this_delta_layer; - if (_brushing) { - _editor->mouse_brush_insert_region (rv, pending_region_position.sample); - } else { - Duple track_origin; + Duple track_origin; - /* Get the y coordinate of the top of the track that this region is now over */ - track_origin = current_tv->canvas_display()->item_to_canvas (track_origin); - - /* And adjust for the layer that it should be on */ - StreamView* cv = current_tv->view (); - switch (cv->layer_display ()) { - case Overlaid: - break; - case Stacked: - track_origin.y += (cv->layers() - i->layer - 1) * cv->child_height (); - break; - case Expanded: - track_origin.y += (cv->layers() - i->layer - 0.5) * 2 * cv->child_height (); - break; - } - - /* need to get the parent of the regionview - * canvas group and get its position in - * equivalent coordinate space as the trackview - * we are now dragging over. - */ - - y_delta = track_origin.y - rv->get_canvas_group()->canvas_origin().y; + /* Get the y coordinate of the top of the track that this region is now over */ + track_origin = current_tv->canvas_display()->item_to_canvas (track_origin); + /* And adjust for the layer that it should be on */ + StreamView* cv = current_tv->view (); + switch (cv->layer_display ()) { + case Overlaid: + break; + case Stacked: + track_origin.y += (cv->layers() - i->layer - 1) * cv->child_height (); + break; + case Expanded: + track_origin.y += (cv->layers() - i->layer - 0.5) * 2 * cv->child_height (); + break; } + /* need to get the parent of the regionview + * canvas group and get its position in + * equivalent coordinate space as the trackview + * we are now dragging over. + */ + + y_delta = track_origin.y - rv->get_canvas_group()->canvas_origin().y; + MidiRegionView* mrv = dynamic_cast(rv); if (mrv) { MidiStreamView* msv; @@ -1327,12 +1383,11 @@ RegionMotionDrag::motion (GdkEvent* event, bool first_move) } else { rv->move (x_delta, y_delta); } - } /* foreach region */ _total_x_delta += x_delta; - if (x_delta != 0 && !_brushing) { + if (x_delta != 0) { show_verbose_cursor_time (_last_position.sample); show_view_preview (_last_position.sample + _video_sample_offset); } @@ -1404,12 +1459,10 @@ void RegionMoveDrag::motion (GdkEvent* event, bool first_move) { if (_copy && first_move) { - if (_x_constrained && !_brushing) { + if (_x_constrained) { _editor->begin_reversible_command (Operations::fixed_time_region_copy); - } else if (!_brushing) { + } else { _editor->begin_reversible_command (Operations::region_copy); - } else if (_brushing) { - _editor->begin_reversible_command (Operations::drag_region_brush); } /* duplicate the regionview(s) and region(s) */ @@ -1470,12 +1523,10 @@ RegionMoveDrag::motion (GdkEvent* event, bool first_move) } } else if (!_copy && first_move) { - if (_x_constrained && !_brushing) { + if (_x_constrained) { _editor->begin_reversible_command (_("fixed time region drag")); - } else if (!_brushing) { + } else { _editor->begin_reversible_command (Operations::region_drag); - } else if (_brushing) { - _editor->begin_reversible_command (Operations::drag_region_brush); } } RegionMotionDrag::motion (event, first_move); @@ -1627,13 +1678,6 @@ RegionMoveDrag::finished_copy (bool const changed_position, bool const changed_t const double last_pos_qn = tmap.exact_qn_at_sample (last_position.sample, last_position.division); const double qn_delta = _primary->region()->quarter_note() - last_pos_qn; - if (_brushing) { - /* all changes were made during motion event handlers */ - clear_draggingview_list(); - _editor->commit_reversible_command (); - return; - } - /*x_contrained on the same track: this will just make a duplicate region in the same place: abort the operation */ if (_x_constrained && !changed_tracks) { clear_draggingview_list(); @@ -1947,7 +1991,6 @@ RegionMoveDrag::finished_no_copy ( /* write commands for the accumulated diffs for all our modified playlists */ add_stateful_diff_commands_for_playlists (modified_playlists); - /* applies to _brushing */ _editor->commit_reversible_command (); /* We have futzed with the layering of canvas items on our streamviews. @@ -2043,20 +2086,6 @@ RegionMoveDrag::collect_new_region_view (RegionView* rv) _new_region_view = rv; } -void -RegionMoveDrag::add_stateful_diff_commands_for_playlists (PlaylistSet const & playlists) -{ - for (PlaylistSet::const_iterator i = playlists.begin(); i != playlists.end(); ++i) { - StatefulDiffCommand* c = new StatefulDiffCommand (*i); - if (!c->empty()) { - _editor->session()->add_command (c); - } else { - delete c; - } - } -} - - void RegionMoveDrag::aborted (bool movement_occurred) { @@ -2097,8 +2126,8 @@ RegionMotionDrag::aborted (bool) /** @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) +RegionMoveDrag::RegionMoveDrag (Editor* e, ArdourCanvas::Item* i, RegionView* p, list const & v, bool c) + : RegionMotionDrag (e, i, p, v) , _copy (c) , _new_region_view (0) { @@ -2114,7 +2143,7 @@ RegionMoveDrag::setup_pointer_sample_offset () } RegionInsertDrag::RegionInsertDrag (Editor* e, boost::shared_ptr r, RouteTimeAxisView* v, samplepos_t pos) - : RegionMotionDrag (e, 0, 0, list (), false) + : RegionMotionDrag (e, 0, 0, list ()) { DEBUG_TRACE (DEBUG::Drags, "New RegionInsertDrag\n"); @@ -2178,7 +2207,7 @@ RegionInsertDrag::aborted (bool) } RegionSpliceDrag::RegionSpliceDrag (Editor* e, ArdourCanvas::Item* i, RegionView* p, list const & v) - : RegionMoveDrag (e, i, p, v, false, false) + : RegionMoveDrag (e, i, p, v, false) { DEBUG_TRACE (DEBUG::Drags, "New RegionSpliceDrag\n"); } @@ -2367,7 +2396,7 @@ RegionRippleDrag::y_movement_allowed (int delta_track, double delta_layer, int s } RegionRippleDrag::RegionRippleDrag (Editor* e, ArdourCanvas::Item* i, RegionView* p, list const & v) - : RegionMoveDrag (e, i, p, v, false, false) + : RegionMoveDrag (e, i, p, v, false) { DEBUG_TRACE (DEBUG::Drags, "New RegionRippleDrag\n"); // compute length of selection diff --git a/gtk2_ardour/editor_drag.h b/gtk2_ardour/editor_drag.h index 0c29cf36ed..802a150ddf 100644 --- a/gtk2_ardour/editor_drag.h +++ b/gtk2_ardour/editor_drag.h @@ -365,6 +365,10 @@ protected: friend class DraggingView; +protected: + typedef std::set > PlaylistSet; + void add_stateful_diff_commands_for_playlists (PlaylistSet const &); + private: void region_going_away (RegionView *); @@ -385,12 +389,28 @@ public: virtual void aborted (bool); }; +/** Brush on a region to repeat it */ +class RegionBrushDrag : public RegionDrag +{ +public: + RegionBrushDrag (Editor *, ArdourCanvas::Item *, RegionView *, std::list const &); + virtual ~RegionBrushDrag () {} + + virtual void start_grab (GdkEvent *, Gdk::Cursor *); + virtual void motion (GdkEvent *, bool); + virtual void finished (GdkEvent *, bool); + virtual void aborted (bool); +private: + typedef std::set SamplePositionSet; + SamplePositionSet _already_pasted; +}; + /** Drags involving region motion from somewhere */ class RegionMotionDrag : public RegionDrag { public: - RegionMotionDrag (Editor *, ArdourCanvas::Item *, RegionView *, std::list const &, bool); + RegionMotionDrag (Editor *, ArdourCanvas::Item *, RegionView *, std::list const &); virtual ~RegionMotionDrag () {} virtual void start_grab (GdkEvent *, Gdk::Cursor *); @@ -408,7 +428,6 @@ protected: double compute_x_delta (GdkEvent const *, ARDOUR::MusicSample *); virtual bool y_movement_allowed (int, double, int skip_invisible = 0) const; - bool _brushing; bool _ignore_video_lock; ARDOUR::MusicSample _last_position; ///< last position of the thing being dragged double _total_x_delta; @@ -427,7 +446,7 @@ private: class RegionMoveDrag : public RegionMotionDrag { public: - RegionMoveDrag (Editor *, ArdourCanvas::Item *, RegionView *, std::list const &, bool, bool); + RegionMoveDrag (Editor *, ArdourCanvas::Item *, RegionView *, std::list const &, bool); virtual ~RegionMoveDrag () {} void motion (GdkEvent *, bool); @@ -450,10 +469,6 @@ public: void setup_pointer_sample_offset (); -protected: - typedef std::set > PlaylistSet; - void add_stateful_diff_commands_for_playlists (PlaylistSet const &); - private: void finished_no_copy ( bool const, diff --git a/gtk2_ardour/editor_mouse.cc b/gtk2_ardour/editor_mouse.cc index e9a7cf440e..e5ac0cd529 100644 --- a/gtk2_ardour/editor_mouse.cc +++ b/gtk2_ardour/editor_mouse.cc @@ -2586,7 +2586,7 @@ Editor::add_region_drag (ArdourCanvas::Item* item, GdkEvent*, RegionView* region _drags->add (new RegionRippleDrag (this, item, region_view, selection->regions.by_layer())); break; default: - _drags->add (new RegionMoveDrag (this, item, region_view, selection->regions.by_layer(), false, false)); + _drags->add (new RegionMoveDrag (this, item, region_view, selection->regions.by_layer(), false)); break; } @@ -2601,7 +2601,7 @@ Editor::add_region_copy_drag (ArdourCanvas::Item* item, GdkEvent*, RegionView* r return; } - _drags->add (new RegionMoveDrag (this, item, region_view, selection->regions.by_layer(), false, true)); + _drags->add (new RegionMoveDrag (this, item, region_view, selection->regions.by_layer(), true)); } void @@ -2617,7 +2617,8 @@ Editor::add_region_brush_drag (ArdourCanvas::Item* item, GdkEvent*, RegionView* return; } - _drags->add (new RegionMoveDrag (this, item, region_view, selection->regions.by_layer(), true, false)); + std::list empty; + _drags->add (new RegionBrushDrag (this, item, region_view, empty)); } /** Start a grab where a time range is selected, track(s) are selected, and the @@ -2681,7 +2682,7 @@ Editor::start_selection_grab (ArdourCanvas::Item* /*item*/, GdkEvent* event) commit_reversible_command (); - _drags->set (new RegionMoveDrag (this, latest_regionviews.front()->get_canvas_group(), latest_regionviews.front(), latest_regionviews, false, false), event); + _drags->set (new RegionMoveDrag (this, latest_regionviews.front()->get_canvas_group(), latest_regionviews.front(), latest_regionviews, false), event); } void