diff --git a/gtk2_ardour/editing_context.h b/gtk2_ardour/editing_context.h index 8299ba1473..cb92d3b055 100644 --- a/gtk2_ardour/editing_context.h +++ b/gtk2_ardour/editing_context.h @@ -254,6 +254,8 @@ class EditingContext : public ARDOUR::SessionHandlePtr, public AxisViewProvider samplepos_t canvas_event_sample (GdkEvent const * event, double* pcx = nullptr, double* pcy = nullptr) const; virtual bool canvas_note_event (GdkEvent* event, ArdourCanvas::Item*) = 0; + virtual bool canvas_velocity_base_event (GdkEvent* event, ArdourCanvas::Item*) = 0; + virtual bool canvas_velocity_event (GdkEvent* event, ArdourCanvas::Item*) = 0; Temporal::Beats get_grid_type_as_beats (bool& success, Temporal::timepos_t const & position) const; Temporal::Beats get_draw_length_as_beats (bool& success, Temporal::timepos_t const & position) const; diff --git a/gtk2_ardour/editor_drag.cc b/gtk2_ardour/editor_drag.cc index d7f66c797a..20a4b93381 100644 --- a/gtk2_ardour/editor_drag.cc +++ b/gtk2_ardour/editor_drag.cc @@ -352,6 +352,11 @@ Drag::start_grab (GdkEvent* event, Gdk::Cursor* cursor) /* we set up x/y dragging constraints on first move */ _constraint_pressed = ArdourKeyboard::indicates_constraint (event->button.state); + /* Note that pos is already adjusted for any timeline origin offset + * within the canvas. It reflects the true sample position of the event + * x coordinate. + */ + const samplepos_t pos = editing_context.canvas_event_sample (event, &_grab_x, &_grab_y); if (_bounding_item) { @@ -7271,11 +7276,12 @@ LollipopDrag::setup_pointer_offset () /********/ template -FreehandLineDrag::FreehandLineDrag (EditingContext& ec, ArdourCanvas::Item* p, ArdourCanvas::Rectangle& r, Temporal::TimeDomain time_domain) +FreehandLineDrag::FreehandLineDrag (EditingContext& ec, ArdourCanvas::Item* p, ArdourCanvas::Rectangle& r, bool hbounded, Temporal::TimeDomain time_domain) : Drag (ec, &r, time_domain, ec.get_trackview_group()) , parent (p) , base_rect (r) , dragging_line (nullptr) + , horizontally_bounded (hbounded) , direction (0) , edge_x (0) , did_snap (false) @@ -7310,7 +7316,6 @@ FreehandLineDrag::motion (GdkEvent* ev, bool firs ...start_grab() already occurred so this is non-trivial */ /* Add a point correspding to the start of the drag */ - maybe_add_point (ev, raw_grab_time(), true); } else { maybe_add_point (ev, _drags->current_pointer_time(), false); @@ -7335,17 +7340,24 @@ FreehandLineDrag::maybe_add_point (GdkEvent* ev, did_snap = true; } - double const pointer_x = editing_context.time_to_pixel (pos); + /* timeline_x is a pixel offset within the timeline; it is not an absolute + * canvas coordinate. + */ + + double const timeline_x = editing_context.time_to_pixel (pos); ArdourCanvas::Rect r = base_rect.item_to_canvas (base_rect.get()); /* Adjust event coordinates to be relative to the base rectangle */ - double x = pointer_x - r.x0; + double x = timeline_x; + if (horizontally_bounded) { + x -= r.x0; + } double y = ev->motion.y - r.y0; if (drawn_points.empty()) { - line_start_x = pointer_x; + line_start_x = editing_context.timeline_to_canvas (timeline_x); line_start_y = y; } @@ -7366,7 +7378,7 @@ FreehandLineDrag::maybe_add_point (GdkEvent* ev, const bool straight_line = Keyboard::modifier_state_equals (ev->motion.state, Keyboard::PrimaryModifier); if (direction > 0) { - if (x < r.width() && (straight_line || (pointer_x > edge_x) || (pointer_x == edge_x && ev->motion.y != last_pointer_y()))) { + if (x < r.width() && (straight_line || (timeline_x > edge_x) || (timeline_x == edge_x && ev->motion.y != last_pointer_y()))) { if (straight_line && dragging_line->get().size() > 1) { pop_point = true; @@ -7377,7 +7389,7 @@ FreehandLineDrag::maybe_add_point (GdkEvent* ev, } else if (direction < 0) { - if (x >= 0. && (straight_line || (pointer_x < edge_x) || (pointer_x == edge_x && ev->motion.y != last_pointer_y()))) { + if (x >= 0. && (straight_line || (timeline_x < edge_x) || (timeline_x == edge_x && ev->motion.y != last_pointer_y()))) { if (straight_line && dragging_line->get().size() > 1) { pop_point = true; @@ -7415,15 +7427,16 @@ FreehandLineDrag::maybe_add_point (GdkEvent* ev, } if (child_call) { + x = editing_context.timeline_to_canvas (timeline_x); if (straight_line && !first_move) { - line_extended (ArdourCanvas::Duple (line_start_x, line_start_y), ArdourCanvas::Duple (pointer_x, y), base_rect, first_move ? -1 : edge_x); + line_extended (ArdourCanvas::Duple (line_start_x, line_start_y), ArdourCanvas::Duple (x, y), base_rect, first_move ? -1 : edge_x); } else { - point_added (ArdourCanvas::Duple (pointer_x, y), base_rect, first_move ? -1 : edge_x); + point_added (ArdourCanvas::Duple (x, y), base_rect, first_move ? -1 : edge_x); } } if (add_point) { - edge_x = pointer_x; + edge_x = timeline_x; } } @@ -7473,8 +7486,8 @@ FreehandLineDrag::mid_drag_key_event (GdkEventKey /**********************/ -AutomationDrawDrag::AutomationDrawDrag (EditingContext& ec, ArdourCanvas::Item* p, ArdourCanvas::Rectangle& r, Temporal::TimeDomain time_domain) - : FreehandLineDrag (ec, p, r, time_domain) +AutomationDrawDrag::AutomationDrawDrag (EditingContext& ec, ArdourCanvas::Item* p, ArdourCanvas::Rectangle& r, bool hbounded, Temporal::TimeDomain time_domain) + : FreehandLineDrag (ec, p, r, hbounded, time_domain) { DEBUG_TRACE (DEBUG::Drags, "New AutomationDrawDrag\n"); } @@ -7512,8 +7525,8 @@ AutomationDrawDrag::finished (GdkEvent* event, bool motion_occured) /*****************/ -VelocityLineDrag::VelocityLineDrag (EditingContext& ec, ArdourCanvas::Rectangle& r, Temporal::TimeDomain time_domain) - : FreehandLineDrag (ec, nullptr, r, time_domain) +VelocityLineDrag::VelocityLineDrag (EditingContext& ec, ArdourCanvas::Rectangle& r, bool hbounded, Temporal::TimeDomain time_domain) + : FreehandLineDrag (ec, nullptr, r, hbounded, time_domain) , vd (static_cast (r.get_data ("ghostregionview"))) , drag_did_change (false) { diff --git a/gtk2_ardour/editor_drag.h b/gtk2_ardour/editor_drag.h index a905e45ba6..0c7740834a 100644 --- a/gtk2_ardour/editor_drag.h +++ b/gtk2_ardour/editor_drag.h @@ -1597,7 +1597,7 @@ template class FreehandLineDrag : public Drag { public: - FreehandLineDrag (EditingContext&, ArdourCanvas::Item*, ArdourCanvas::Rectangle&, Temporal::TimeDomain); + FreehandLineDrag (EditingContext&, ArdourCanvas::Item*, ArdourCanvas::Rectangle&, bool, Temporal::TimeDomain); ~FreehandLineDrag (); void motion (GdkEvent*, bool); @@ -1612,6 +1612,7 @@ class FreehandLineDrag : public Drag ArdourCanvas::Item* parent; /* we do not own this. If null, use base_rect as the parent */ ArdourCanvas::Rectangle& base_rect; /* we do not own this */ ArdourCanvas::PolyLine* dragging_line; + bool horizontally_bounded; int direction; int edge_x; bool did_snap; @@ -1626,7 +1627,7 @@ class FreehandLineDrag : public Drag class AutomationDrawDrag : public FreehandLineDrag { public: - AutomationDrawDrag (EditingContext&, ArdourCanvas::Item*, ArdourCanvas::Rectangle&, Temporal::TimeDomain); + AutomationDrawDrag (EditingContext&, ArdourCanvas::Item*, ArdourCanvas::Rectangle&, bool, Temporal::TimeDomain); ~AutomationDrawDrag (); void finished (GdkEvent*, bool); @@ -1636,7 +1637,7 @@ class AutomationDrawDrag : public FreehandLineDrag { public: - VelocityLineDrag (EditingContext&, ArdourCanvas::Rectangle&, Temporal::TimeDomain); + VelocityLineDrag (EditingContext&, ArdourCanvas::Rectangle&, bool, Temporal::TimeDomain); ~VelocityLineDrag (); void start_grab (GdkEvent *, Gdk::Cursor* c = 0); diff --git a/gtk2_ardour/editor_mouse.cc b/gtk2_ardour/editor_mouse.cc index 38c17486c5..e580a52bdd 100644 --- a/gtk2_ardour/editor_mouse.cc +++ b/gtk2_ardour/editor_mouse.cc @@ -765,9 +765,8 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT { VelocityDisplay* vd = static_cast (item->get_data ("ghostregionview")); VelocityGhostRegion* grv = dynamic_cast (vd); - std::cerr << "VBI with item " << item << " vd " << vd << " data for grv pointed at " << grv << std::endl; if (grv) { - _drags->set (new VelocityLineDrag (*this, grv->base_item(), Temporal::BeatTime), event); + _drags->set (new VelocityLineDrag (*this, grv->base_item(), true, Temporal::BeatTime), event); } } return true; @@ -1207,7 +1206,7 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT { AutomationTimeAxisView* atv = static_cast (item->get_data ("trackview")); if (atv) { - _drags->set (new AutomationDrawDrag (*this, nullptr, atv->base_item(), Temporal::AudioTime), event); + _drags->set (new AutomationDrawDrag (*this, nullptr, atv->base_item(), false, Temporal::AudioTime), event); } } break; @@ -1234,7 +1233,7 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT RegionView* rv; if ((rv = dynamic_cast (clicked_regionview))) { ArdourCanvas::Rectangle* r = dynamic_cast (rv->get_canvas_frame()); - _drags->set (new AutomationDrawDrag (*this, rv->get_canvas_group(), *r, Temporal::AudioTime), event); + _drags->set (new AutomationDrawDrag (*this, rv->get_canvas_group(), *r, true, Temporal::AudioTime), event); } } break; diff --git a/gtk2_ardour/midi_cue_editor.cc b/gtk2_ardour/midi_cue_editor.cc index 5791c27297..8a131fdfc6 100644 --- a/gtk2_ardour/midi_cue_editor.cc +++ b/gtk2_ardour/midi_cue_editor.cc @@ -41,6 +41,7 @@ #include "note_base.h" #include "prh.h" #include "ui_config.h" +#include "velocity_ghost_region.h" #include "verbose_cursor.h" #include "pbd/i18n.h" @@ -400,6 +401,19 @@ MidiCueEditor::canvas_note_event (GdkEvent* event, ArdourCanvas::Item* item) return typed_event (item, event, NoteItem); } +bool +MidiCueEditor::canvas_velocity_base_event (GdkEvent* event, ArdourCanvas::Item* item) +{ + return typed_event (item, event, VelocityBaseItem); +} + +bool +MidiCueEditor::canvas_velocity_event (GdkEvent* event, ArdourCanvas::Item* item) +{ + return typed_event (item, event, VelocityItem); +} + + Gtk::Widget& MidiCueEditor::viewport() { @@ -505,6 +519,17 @@ MidiCueEditor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event } } return true; + + case VelocityItem: + _drags->set (new LollipopDrag (*this, item), event); + return true; + break; + + case VelocityBaseItem: + _drags->set (new VelocityLineDrag (*this, *static_cast(item), false, Temporal::BeatTime), event); + return true; + break; + default: break; } diff --git a/gtk2_ardour/midi_cue_editor.h b/gtk2_ardour/midi_cue_editor.h index 6ef448d6ac..134f43c992 100644 --- a/gtk2_ardour/midi_cue_editor.h +++ b/gtk2_ardour/midi_cue_editor.h @@ -66,6 +66,8 @@ class MidiCueEditor : public CueEditor Temporal::Beats get_draw_length_as_beats (bool& success, Temporal::timepos_t const & position) const; bool canvas_note_event (GdkEvent* event, ArdourCanvas::Item*); + bool canvas_velocity_base_event (GdkEvent* event, ArdourCanvas::Item*); + bool canvas_velocity_event (GdkEvent* event, ArdourCanvas::Item*); int32_t get_grid_beat_divisions (Editing::GridType gt) const { return 1; } int32_t get_grid_music_divisions (Editing::GridType gt, uint32_t event_state) const { return 1; } diff --git a/gtk2_ardour/midi_cue_velocity.cc b/gtk2_ardour/midi_cue_velocity.cc index 276ab6c3a3..8d8d978bfc 100644 --- a/gtk2_ardour/midi_cue_velocity.cc +++ b/gtk2_ardour/midi_cue_velocity.cc @@ -49,7 +49,6 @@ MidiCueVelocityDisplay::set_colors () void MidiCueVelocityDisplay::remove_note (NoteBase* nb) { - std::cerr << "mcVD:remove\n"; GhostEvent::EventList::iterator f = events.find (nb->note()); if (f == events.end()) { return; @@ -64,12 +63,12 @@ MidiCueVelocityDisplay::remove_note (NoteBase* nb) bool MidiCueVelocityDisplay::base_event (GdkEvent* ev) { - return true; // editing_context.canvas_velocity_base_event (ev, base_rect); + return editing_context.canvas_velocity_base_event (ev, &base); } bool MidiCueVelocityDisplay::lollevent (GdkEvent* ev, GhostEvent* gev) { - return true; // editing_context.canvas_velocity_event (ev, gev->item); + return editing_context.canvas_velocity_event (ev, gev->item); }