13
0

Brush Drag: refactor Brush-drag into its own Drag class (operation is still weird though)

This commit is contained in:
Ben Loftis 2021-06-15 16:09:24 -05:00
parent 69af0e6964
commit 45bd2c47d8
4 changed files with 129 additions and 84 deletions

View File

@ -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);

View File

@ -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<RegionView*> 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<RegionView*> const & v, bool b)
RegionBrushDrag::RegionBrushDrag (Editor* e, ArdourCanvas::Item* i, RegionView* p, list<RegionView*> 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<RegionView*> 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<MidiRegionView*>(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<RegionView*> const & v, bool b, bool c)
: RegionMotionDrag (e, i, p, v, b)
RegionMoveDrag::RegionMoveDrag (Editor* e, ArdourCanvas::Item* i, RegionView* p, list<RegionView*> 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<Region> r, RouteTimeAxisView* v, samplepos_t pos)
: RegionMotionDrag (e, 0, 0, list<RegionView*> (), false)
: RegionMotionDrag (e, 0, 0, list<RegionView*> ())
{
DEBUG_TRACE (DEBUG::Drags, "New RegionInsertDrag\n");
@ -2178,7 +2207,7 @@ RegionInsertDrag::aborted (bool)
}
RegionSpliceDrag::RegionSpliceDrag (Editor* e, ArdourCanvas::Item* i, RegionView* p, list<RegionView*> 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<RegionView*> 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

View File

@ -365,6 +365,10 @@ protected:
friend class DraggingView;
protected:
typedef std::set<boost::shared_ptr<ARDOUR::Playlist> > 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<RegionView*> 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<samplepos_t> SamplePositionSet;
SamplePositionSet _already_pasted;
};
/** Drags involving region motion from somewhere */
class RegionMotionDrag : public RegionDrag
{
public:
RegionMotionDrag (Editor *, ArdourCanvas::Item *, RegionView *, std::list<RegionView*> const &, bool);
RegionMotionDrag (Editor *, ArdourCanvas::Item *, RegionView *, std::list<RegionView*> 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<RegionView*> const &, bool, bool);
RegionMoveDrag (Editor *, ArdourCanvas::Item *, RegionView *, std::list<RegionView*> const &, bool);
virtual ~RegionMoveDrag () {}
void motion (GdkEvent *, bool);
@ -450,10 +469,6 @@ public:
void setup_pointer_sample_offset ();
protected:
typedef std::set<boost::shared_ptr<ARDOUR::Playlist> > PlaylistSet;
void add_stateful_diff_commands_for_playlists (PlaylistSet const &);
private:
void finished_no_copy (
bool const,

View File

@ -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<RegionView*> 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