get velocity editing working in both the cue editor and MIDI region views
Quite a bit of hairy coordinate system stuff in here that ought to be commented more clearly
This commit is contained in:
parent
ee305a7169
commit
afa15a0061
@ -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;
|
||||
|
@ -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<typename OrderedPointList, typename OrderedPoint>
|
||||
FreehandLineDrag<OrderedPointList,OrderedPoint>::FreehandLineDrag (EditingContext& ec, ArdourCanvas::Item* p, ArdourCanvas::Rectangle& r, Temporal::TimeDomain time_domain)
|
||||
FreehandLineDrag<OrderedPointList,OrderedPoint>::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<OrderedPointList,OrderedPoint>::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<OrderedPointList,OrderedPoint>::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<OrderedPointList,OrderedPoint>::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<OrderedPointList,OrderedPoint>::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<OrderedPointList,OrderedPoint>::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<OrderedPointList,OrderedPoint>::mid_drag_key_event (GdkEventKey
|
||||
|
||||
/**********************/
|
||||
|
||||
AutomationDrawDrag::AutomationDrawDrag (EditingContext& ec, ArdourCanvas::Item* p, ArdourCanvas::Rectangle& r, Temporal::TimeDomain time_domain)
|
||||
: FreehandLineDrag<Evoral::ControlList::OrderedPoints,Evoral::ControlList::OrderedPoint> (ec, p, r, time_domain)
|
||||
AutomationDrawDrag::AutomationDrawDrag (EditingContext& ec, ArdourCanvas::Item* p, ArdourCanvas::Rectangle& r, bool hbounded, Temporal::TimeDomain time_domain)
|
||||
: FreehandLineDrag<Evoral::ControlList::OrderedPoints,Evoral::ControlList::OrderedPoint> (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<Evoral::ControlList::OrderedPoints,Evoral::ControlList::OrderedPoint> (ec, nullptr, r, time_domain)
|
||||
VelocityLineDrag::VelocityLineDrag (EditingContext& ec, ArdourCanvas::Rectangle& r, bool hbounded, Temporal::TimeDomain time_domain)
|
||||
: FreehandLineDrag<Evoral::ControlList::OrderedPoints,Evoral::ControlList::OrderedPoint> (ec, nullptr, r, hbounded, time_domain)
|
||||
, vd (static_cast<VelocityDisplay*> (r.get_data ("ghostregionview")))
|
||||
, drag_did_change (false)
|
||||
{
|
||||
|
@ -1597,7 +1597,7 @@ template<typename OrderedPointList, typename OrderedPoint>
|
||||
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<Evoral::ControlList::OrderedPoints, Evoral::ControlList::OrderedPoint>
|
||||
{
|
||||
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<Evoral::ControlList::OrderedP
|
||||
class VelocityLineDrag : public FreehandLineDrag<Evoral::ControlList::OrderedPoints, Evoral::ControlList::OrderedPoint>
|
||||
{
|
||||
public:
|
||||
VelocityLineDrag (EditingContext&, ArdourCanvas::Rectangle&, Temporal::TimeDomain);
|
||||
VelocityLineDrag (EditingContext&, ArdourCanvas::Rectangle&, bool, Temporal::TimeDomain);
|
||||
~VelocityLineDrag ();
|
||||
|
||||
void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
|
||||
|
@ -765,9 +765,8 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT
|
||||
{
|
||||
VelocityDisplay* vd = static_cast<VelocityDisplay*> (item->get_data ("ghostregionview"));
|
||||
VelocityGhostRegion* grv = dynamic_cast<VelocityGhostRegion*> (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<AutomationTimeAxisView*> (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<RegionView*> (clicked_regionview))) {
|
||||
ArdourCanvas::Rectangle* r = dynamic_cast<ArdourCanvas::Rectangle*> (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;
|
||||
|
@ -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<ArdourCanvas::Rectangle*>(item), false, Temporal::BeatTime), event);
|
||||
return true;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -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; }
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user