From ef0938a16d1c5af7157de1c37a94451931fed9f0 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Fri, 27 Oct 2023 11:49:36 -0600 Subject: [PATCH] more improvements to velocity drawing (including straight line) --- gtk2_ardour/editor_drag.cc | 2 +- gtk2_ardour/ghostregion.cc | 3 ++ gtk2_ardour/ghostregion.h | 1 + gtk2_ardour/midi_region_view.cc | 47 ++++--------------- gtk2_ardour/midi_region_view.h | 4 +- gtk2_ardour/velocity_ghost_region.cc | 69 +++++++++++++++++----------- gtk2_ardour/velocity_ghost_region.h | 4 +- 7 files changed, 59 insertions(+), 71 deletions(-) diff --git a/gtk2_ardour/editor_drag.cc b/gtk2_ardour/editor_drag.cc index 0725f543fe..dd8d4f264f 100644 --- a/gtk2_ardour/editor_drag.cc +++ b/gtk2_ardour/editor_drag.cc @@ -7308,7 +7308,7 @@ FreehandLineDrag::maybe_add_point (GdkEvent* ev, double y = ev->motion.y - r.y0; if (drawn_points.empty()) { - line_start_x = x; + line_start_x = pointer_x; line_start_y = y; } diff --git a/gtk2_ardour/ghostregion.cc b/gtk2_ardour/ghostregion.cc index aede3563a5..2756868e20 100644 --- a/gtk2_ardour/ghostregion.cc +++ b/gtk2_ardour/ghostregion.cc @@ -215,6 +215,7 @@ MidiGhostRegion::GhostEvent::GhostEvent (NoteBase* e, ArdourCanvas::Container* g , item (i) , is_hit (false) { + velocity_while_editing = event->note()->velocity(); } MidiGhostRegion::GhostEvent::GhostEvent (NoteBase* e, ArdourCanvas::Container* g) @@ -235,6 +236,8 @@ MidiGhostRegion::GhostEvent::GhostEvent (NoteBase* e, ArdourCanvas::Container* g is_hit = true; } + velocity_while_editing = event->note()->velocity(); + CANVAS_DEBUG_NAME (item, "ghost note item"); } diff --git a/gtk2_ardour/ghostregion.h b/gtk2_ardour/ghostregion.h index 153aada5ce..bf516cae30 100644 --- a/gtk2_ardour/ghostregion.h +++ b/gtk2_ardour/ghostregion.h @@ -108,6 +108,7 @@ public: NoteBase* event; ArdourCanvas::Item* item; bool is_hit; + int velocity_while_editing; }; MidiGhostRegion(MidiRegionView& rv, diff --git a/gtk2_ardour/midi_region_view.cc b/gtk2_ardour/midi_region_view.cc index 160adbe3b6..74b56b3e79 100644 --- a/gtk2_ardour/midi_region_view.cc +++ b/gtk2_ardour/midi_region_view.cc @@ -3402,54 +3402,18 @@ MidiRegionView::begin_drag_edit (std::string const & why) if (!_selected) { trackview.editor().get_selection().set (this, true); } - start_note_diff_command (why); } void -MidiRegionView::drag_apply () +MidiRegionView::end_drag_edit () { - 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_velocities_for_notes (std::vector notes, std::vector velocities) { + start_note_diff_command (_("draw velocities")); + assert (notes.size() == velocities.size()); /* Does not use selection, used when drawing/dragging in velocity lane */ @@ -3472,6 +3436,11 @@ MidiRegionView::set_velocities_for_notes (std::vector notes, std::vec ++veloi; } + apply_note_diff (true /*subcommand, we don't want this to start a new commit*/, false); + trackview.editor().commit_reversible_command (); + delete _note_diff_command; + _note_diff_command = nullptr; + return changed; } diff --git a/gtk2_ardour/midi_region_view.h b/gtk2_ardour/midi_region_view.h index c70f1295d2..5039687fcc 100644 --- a/gtk2_ardour/midi_region_view.h +++ b/gtk2_ardour/midi_region_view.h @@ -181,8 +181,7 @@ public: void extend_active_notes(); void begin_drag_edit (std::string const & why); - void mid_drag_edit (); - void end_drag_edit (bool apply); + void end_drag_edit (); void display_model(std::shared_ptr model); std::shared_ptr model() const { return _model; } @@ -591,7 +590,6 @@ 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 9f1cea4a45..7c1b88ebe5 100644 --- a/gtk2_ardour/velocity_ghost_region.cc +++ b/gtk2_ardour/velocity_ghost_region.cc @@ -73,8 +73,7 @@ VelocityGhostRegion::~VelocityGhostRegion () bool VelocityGhostRegion::line_draw_motion (ArdourCanvas::Duple const & d, ArdourCanvas::Rectangle const & r, double last_x) { - std::vector affected_lollis; - MidiRegionView* mrv = dynamic_cast (&parent_rv); + std::vector affected_lollis; if (last_x < 0) { lollis_close_to_x (d.x, 20., affected_lollis); @@ -91,16 +90,19 @@ VelocityGhostRegion::line_draw_motion (ArdourCanvas::Duple const & d, ArdourCanv } int velocity = y_position_to_velocity (r.height() - (r.y1() - d.y)); - bool ret = mrv->set_velocity_for_notes (affected_lollis, velocity); - mrv->mid_drag_edit (); - return ret; + for (auto & lolli : affected_lollis) { + lolli->velocity_while_editing = velocity; + set_size_and_position (*lolli); + } + + return true; } bool VelocityGhostRegion::line_extended (ArdourCanvas::Duple const & from, ArdourCanvas::Duple const & to, ArdourCanvas::Rectangle const & r, double last_x) { - std::vector affected_lollis; + std::vector affected_lollis; lollis_between (from.x, to.x, affected_lollis); @@ -114,24 +116,16 @@ VelocityGhostRegion::line_extended (ArdourCanvas::Duple const & from, ArdourCanv } double slope = (to.y - from.y) / (to.x - from.x); - std::vector velocities; - for (auto const & nb : affected_lollis) { - ArdourCanvas::Item* it = nb->item(); - ArdourCanvas::Duple pos = it->item_to_canvas (ArdourCanvas::Duple (nb->x0(), 0.0)); + for (auto const & lolli : affected_lollis) { + ArdourCanvas::Item* item = lolli->item; + ArdourCanvas::Duple pos = item->item_to_canvas (ArdourCanvas::Duple (lolli->event->x0(), 0.0)); int y = from.y + (slope * (pos.x - from.x)); - int velocity = y_position_to_velocity (r.height() - (r.y1() - y)); - velocities.push_back (velocity); + lolli->velocity_while_editing = y_position_to_velocity (r.height() - (r.y1() - y)); + set_size_and_position (*lolli); } - MidiRegionView* mrv = dynamic_cast (&parent_rv); - bool ret = mrv->set_velocities_for_notes (affected_lollis, velocities); - - mrv->mid_drag_edit (); - - model_changed (); - - return ret; + return true; } bool @@ -189,7 +183,7 @@ VelocityGhostRegion::set_size_and_position (GhostEvent& ev) { ArdourCanvas::Lollipop* l = dynamic_cast (ev.item); const double available_height = base_rect->y1(); - const double actual_height = (ev.event->note()->velocity() / 127.0) * available_height; + const double actual_height = (ev.velocity_while_editing / 127.0) * available_height; l->set (ArdourCanvas::Duple (ev.event->x0(), base_rect->y1() - actual_height), actual_height, lollipop_radius); } @@ -327,7 +321,7 @@ VelocityGhostRegion::note_selected (NoteBase* ev) } void -VelocityGhostRegion::lollis_between (int x0, int x1, std::vector& within) +VelocityGhostRegion::lollis_between (int x0, int x1, std::vector& within) { MidiRegionView* mrv = dynamic_cast (&parent_rv); assert (mrv); @@ -344,21 +338,21 @@ VelocityGhostRegion::lollis_between (int x0, int x1, std::vector& wit if (l) { ArdourCanvas::Duple pos = l->item_to_canvas (ArdourCanvas::Duple (l->x(), l->y0())); if (pos.x >= x0 && pos.x < x1) { - within.push_back (gev.second->event); + within.push_back (gev.second); } } } } void -VelocityGhostRegion::lollis_close_to_x (int x, double distance, std::vector& within) +VelocityGhostRegion::lollis_close_to_x (int x, double distance, std::vector& within) { for (auto & gev : events) { ArdourCanvas::Lollipop* l = dynamic_cast (gev.second->item); if (l) { ArdourCanvas::Duple pos = l->item_to_canvas (ArdourCanvas::Duple (l->x(), l->y0())); if (std::abs (pos.x - x) < distance) { - within.push_back (gev.second->event); + within.push_back (gev.second); } } } @@ -368,7 +362,14 @@ void VelocityGhostRegion::start_line_drag () { MidiRegionView* mrv = dynamic_cast (&parent_rv); + mrv->begin_drag_edit (_("draw velocities")); + + for (auto & e : events) { + GhostEvent* gev (e.second); + gev->velocity_while_editing = gev->event->note()->velocity(); + } + desensitize_lollis (); } @@ -376,7 +377,23 @@ void VelocityGhostRegion::end_line_drag (bool did_change) { MidiRegionView* mrv = dynamic_cast (&parent_rv); - mrv->end_drag_edit (did_change); + + if (did_change) { + std::vector notes; + std::vector velocities; + + for (auto & e : events) { + GhostEvent* gev (e.second); + if (gev->event->note()->velocity() != gev->velocity_while_editing) { + notes.push_back (gev->event); + velocities.push_back (gev->velocity_while_editing); + } + } + + mrv->set_velocities_for_notes (notes, velocities); + } + + mrv->end_drag_edit (); sensitize_lollis (); } diff --git a/gtk2_ardour/velocity_ghost_region.h b/gtk2_ardour/velocity_ghost_region.h index e00376ede5..9f2c02d495 100644 --- a/gtk2_ardour/velocity_ghost_region.h +++ b/gtk2_ardour/velocity_ghost_region.h @@ -67,8 +67,8 @@ private: bool base_event (GdkEvent*); bool lollevent (GdkEvent*, MidiGhostRegion::GhostEvent*); void set_size_and_position (MidiGhostRegion::GhostEvent&); - void lollis_close_to_x (int x, double distance, std::vector& events); - void lollis_between (int x0, int x1, std::vector& events); + void lollis_close_to_x (int x, double distance, std::vector& events); + void lollis_between (int x0, int x1, std::vector& events); void desensitize_lollis (); void sensitize_lollis (); };