diff --git a/gtk2_ardour/midi_region_view.cc b/gtk2_ardour/midi_region_view.cc index 678d40b956..d678cb799b 100644 --- a/gtk2_ardour/midi_region_view.cc +++ b/gtk2_ardour/midi_region_view.cc @@ -3384,15 +3384,62 @@ MidiRegionView::change_note_length (NoteBase* event, Temporal::Beats t) { note_diff_add_change (event, MidiModel::NoteDiffCommand::Length, t); } + void +MidiRegionView::begin_drag_edit (std::string const & why) +{ + start_note_diff_command (why); +} + +void +MidiRegionView::drag_apply () +{ + if (!_note_diff_command) { + return; + } + + bool add_or_remove = _note_diff_command->adds_or_removes(); + + if (add_or_remove) { + // Mark all selected notes for selection when model reloads + for (auto const & sel : _selection) { + _marked_for_selection.insert (sel->note()); + } + } + + { + PBD::Unwinder puw (_select_all_notes_after_add, true); + /*note that we don't use as_commit here, because that would BEGIN a new undo record; we already have one underway*/ + _model->apply_diff_command_as_subcommand (*trackview.session(), _note_diff_command); + } +} + +void +MidiRegionView::mid_drag_edit () +{ + drag_apply (); + _note_diff_command = _model->new_note_diff_command (); +} + +void +MidiRegionView::end_drag_edit (bool apply) +{ + if (apply) { + drag_apply (); + trackview.editor().commit_reversible_command (); + _note_diff_command = nullptr; + } else { + abort_note_diff (); + } +} + +bool MidiRegionView::set_velocity_for_notes (std::vector notes, int velocity) { /* Does not use selection, used when drawing/dragging in velocity lane */ bool changed = false; - start_note_diff_command (_("set velocities")); - for (auto & note : notes) { int delta = velocity - note->note()->velocity(); @@ -3405,11 +3452,7 @@ MidiRegionView::set_velocity_for_notes (std::vector notes, int veloci change_note_velocity (note, delta, true); } - if (changed) { - apply_note_diff (); - } else { - abort_note_diff (); - } + return changed; } void diff --git a/gtk2_ardour/midi_region_view.h b/gtk2_ardour/midi_region_view.h index d3ced05530..5e3ffaeacf 100644 --- a/gtk2_ardour/midi_region_view.h +++ b/gtk2_ardour/midi_region_view.h @@ -180,6 +180,10 @@ public: void end_write(); void extend_active_notes(); + void begin_drag_edit (std::string const & why); + void mid_drag_edit (); + void end_drag_edit (bool apply); + void display_model(std::shared_ptr model); /* note_diff commands should start here; this initiates an undo record */ @@ -288,7 +292,7 @@ public: void change_note_lengths (bool, bool, Temporal::Beats beats, bool start, bool end); void change_velocities (bool up, bool fine, bool allow_smush, bool all_together); void set_velocity (NoteBase* primary, int velocity); - void set_velocity_for_notes (std::vector notes, int velocity); + bool set_velocity_for_notes (std::vector notes, int velocity); void transpose (bool up, bool fine, bool allow_smush); void nudge_notes (bool forward, bool fine); void channel_edit (); @@ -583,6 +587,7 @@ public: void model_changed (); void sync_ghost_selection (NoteBase*); + void drag_apply (); }; diff --git a/gtk2_ardour/velocity_ghost_region.cc b/gtk2_ardour/velocity_ghost_region.cc index 010f69d7d8..23dd2a193b 100644 --- a/gtk2_ardour/velocity_ghost_region.cc +++ b/gtk2_ardour/velocity_ghost_region.cc @@ -55,6 +55,7 @@ VelocityGhostRegion::VelocityGhostRegion (MidiRegionView& mrv, TimeAxisView& tv, , dragging (false) , dragging_line (nullptr) , last_drag_x (-1) + , drag_did_change (false) { base_rect->Event.connect (sigc::mem_fun (*this, &VelocityGhostRegion::base_event)); } @@ -79,13 +80,14 @@ VelocityGhostRegion::base_event (GdkEvent* ev) } else if (last_drag_x < ev->motion.x) { /* rightward, "later" motion */ lollis_between (last_drag_x, ev->motion.x, affected_lollis); - } else { + } else { /* leftward, "earlier" motion */ lollis_between (ev->motion.x, last_drag_x, affected_lollis); } if (!affected_lollis.empty()) { int velocity = y_position_to_velocity (r.height() - (r.y1 - ev->motion.y)); - mrv->set_velocity_for_notes (affected_lollis, velocity); + drag_did_change |= mrv->set_velocity_for_notes (affected_lollis, velocity); + mrv->mid_drag_edit (); } if (dragging) { dragging_line->add_point (ArdourCanvas::Duple (ev->motion.x - r.x0, ev->motion.y - r.y0)); @@ -97,6 +99,7 @@ VelocityGhostRegion::base_event (GdkEvent* ev) if (ev->button.button == 1) { desensitize_lollis (); dragging = true; + drag_did_change = false; last_drag_x = -1; if (!dragging_line) { dragging_line = new ArdourCanvas::PolyLine (_note_group); @@ -107,10 +110,12 @@ VelocityGhostRegion::base_event (GdkEvent* ev) dragging_line->show(); dragging_line->raise_to_top(); base_rect->grab(); + mrv->begin_drag_edit (_("draw velocities")); } break; case GDK_BUTTON_RELEASE: if (ev->button.button == 1) { + mrv->end_drag_edit (drag_did_change); base_rect->ungrab(); dragging_line->hide (); dragging = false; diff --git a/gtk2_ardour/velocity_ghost_region.h b/gtk2_ardour/velocity_ghost_region.h index 11f85da18d..9018b2ae54 100644 --- a/gtk2_ardour/velocity_ghost_region.h +++ b/gtk2_ardour/velocity_ghost_region.h @@ -51,6 +51,7 @@ private: bool dragging; ArdourCanvas::PolyLine* dragging_line; int last_drag_x; + bool drag_did_change; bool base_event (GdkEvent*); bool lollevent (GdkEvent*, MidiGhostRegion::GhostEvent*);