From f7130f5c0268aa7a5bd30e66dd4d4272e6dfc4ae Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Tue, 20 Jun 2023 13:47:12 -0600 Subject: [PATCH] lollipop drag: move all selected notes --- gtk2_ardour/editor_drag.cc | 8 +++++++- gtk2_ardour/editor_drag.h | 1 + gtk2_ardour/midi_region_view.h | 2 +- gtk2_ardour/velocity_ghost_region.cc | 25 ++++++++++++++++++------- 4 files changed, 27 insertions(+), 9 deletions(-) diff --git a/gtk2_ardour/editor_drag.cc b/gtk2_ardour/editor_drag.cc index d9430e07c1..83d918b07b 100644 --- a/gtk2_ardour/editor_drag.cc +++ b/gtk2_ardour/editor_drag.cc @@ -7183,6 +7183,7 @@ RegionMarkerDrag::setup_pointer_sample_offset () LollipopDrag::LollipopDrag (Editor* ed, ArdourCanvas::Item* l) : Drag (ed, l, Temporal::BeatTime) , _primary (dynamic_cast (l)) + , cumulative_delta (0.) { _region = reinterpret_cast (_item->get_data ("ghostregionview")); } @@ -7203,7 +7204,9 @@ LollipopDrag::start_grab (GdkEvent *ev, Gdk::Cursor* c) bool add = Keyboard::modifier_state_equals (ev->button.state, Keyboard::PrimaryModifier); bool extend = Keyboard::modifier_state_equals (ev->button.state, Keyboard::TertiaryModifier); - mrv->note_selected (note, add, extend); + if (mrv->selection().find (note) == mrv->selection().end()) { + mrv->note_selected (note, add, extend); + } } void @@ -7224,6 +7227,9 @@ LollipopDrag::finished (GdkEvent *ev, bool did_move) MidiRegionView* mrv = dynamic_cast (&_region->parent_rv); assert (mrv); + double this_delta = velocity - note->note()->velocity(); + cumulative_delta += this_delta; + mrv->set_velocity (note, velocity); } diff --git a/gtk2_ardour/editor_drag.h b/gtk2_ardour/editor_drag.h index e0327444dd..7401698398 100644 --- a/gtk2_ardour/editor_drag.h +++ b/gtk2_ardour/editor_drag.h @@ -1577,6 +1577,7 @@ class LollipopDrag : public Drag private: VelocityGhostRegion* _region; ArdourCanvas::Lollipop* _primary; + double cumulative_delta; }; #endif /* __gtk2_ardour_editor_drag_h_ */ diff --git a/gtk2_ardour/midi_region_view.h b/gtk2_ardour/midi_region_view.h index a716e2a2b1..7ec8193dd3 100644 --- a/gtk2_ardour/midi_region_view.h +++ b/gtk2_ardour/midi_region_view.h @@ -296,7 +296,7 @@ public: void show_list_editor (); typedef std::set Selection; - Selection selection () const { + Selection const & selection () const { return _selection; } diff --git a/gtk2_ardour/velocity_ghost_region.cc b/gtk2_ardour/velocity_ghost_region.cc index 74b9506e41..9a007005e4 100644 --- a/gtk2_ardour/velocity_ghost_region.cc +++ b/gtk2_ardour/velocity_ghost_region.cc @@ -37,6 +37,7 @@ #include "editor_drag.h" #include "gui_thread.h" #include "midi_automation_line.h" +#include "midi_region_view.h" #include "note_base.h" #include "public_editor.h" #include "ui_config.h" @@ -133,20 +134,32 @@ VelocityGhostRegion::drag_lolli (ArdourCanvas::Lollipop* l, GdkEventMotion* ev) { ArdourCanvas::Rect r (base_rect->item_to_window (base_rect->get())); - /* translate event y-coord so that zero matches the top of base_rect */ + /* translate event y-coord so that zero matches the top of base_rect + * (event coordinates use window coordinate space) + */ ev->y -= r.y0; /* clamp y to be within the range defined by the base_rect height minus - * the lollipop radius at top and bottom + * the lollipop radius at top and bottom */ const double effective_y = std::max (lollipop_radius, std::min (r.height() - (2.0 * lollipop_radius), ev->y)); + const double newlen = r.height() - effective_y - lollipop_radius; + const double delta = newlen - l->length(); - std::cerr << "new y " << effective_y << std::endl; + MidiRegionView* mrv = dynamic_cast (&parent_rv); + assert (mrv); + MidiRegionView::Selection const & sel (mrv->selection()); - l->set (ArdourCanvas::Duple (l->x(), effective_y), r.height() - effective_y - lollipop_radius, lollipop_radius); + for (auto & s : sel) { + GhostEvent* x = find_event (s->note()); + if (x) { + ArdourCanvas::Lollipop* l = dynamic_cast (x->item); + l->set (ArdourCanvas::Duple (l->x(), l->y0() - delta), l->length() + delta, lollipop_radius); + } + } } int @@ -155,14 +168,12 @@ VelocityGhostRegion::y_position_to_velocity (double y) const const ArdourCanvas::Rect r (base_rect->get()); int velocity; - std::cerr << "y = " << y << " h = " << r.height() << std::endl; - if (y >= r.height() - (2.0 * lollipop_radius)) { velocity = 0; } else if (y <= lollipop_radius) { velocity = 127; } else { - velocity = floor (127. * ((r.height() - y) / r.height())); + velocity = floor (127. * (((r.height() - 2.0 * lollipop_radius)- y) / r.height())); } std::cerr << " y = " << y << " vel = " << velocity << std::endl;