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;
|
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_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_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;
|
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 */
|
/* we set up x/y dragging constraints on first move */
|
||||||
_constraint_pressed = ArdourKeyboard::indicates_constraint (event->button.state);
|
_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);
|
const samplepos_t pos = editing_context.canvas_event_sample (event, &_grab_x, &_grab_y);
|
||||||
|
|
||||||
if (_bounding_item) {
|
if (_bounding_item) {
|
||||||
@ -7271,11 +7276,12 @@ LollipopDrag::setup_pointer_offset ()
|
|||||||
/********/
|
/********/
|
||||||
|
|
||||||
template<typename OrderedPointList, typename OrderedPoint>
|
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())
|
: Drag (ec, &r, time_domain, ec.get_trackview_group())
|
||||||
, parent (p)
|
, parent (p)
|
||||||
, base_rect (r)
|
, base_rect (r)
|
||||||
, dragging_line (nullptr)
|
, dragging_line (nullptr)
|
||||||
|
, horizontally_bounded (hbounded)
|
||||||
, direction (0)
|
, direction (0)
|
||||||
, edge_x (0)
|
, edge_x (0)
|
||||||
, did_snap (false)
|
, did_snap (false)
|
||||||
@ -7310,7 +7316,6 @@ FreehandLineDrag<OrderedPointList,OrderedPoint>::motion (GdkEvent* ev, bool firs
|
|||||||
...start_grab() already occurred so this is non-trivial */
|
...start_grab() already occurred so this is non-trivial */
|
||||||
|
|
||||||
/* Add a point correspding to the start of the drag */
|
/* Add a point correspding to the start of the drag */
|
||||||
|
|
||||||
maybe_add_point (ev, raw_grab_time(), true);
|
maybe_add_point (ev, raw_grab_time(), true);
|
||||||
} else {
|
} else {
|
||||||
maybe_add_point (ev, _drags->current_pointer_time(), false);
|
maybe_add_point (ev, _drags->current_pointer_time(), false);
|
||||||
@ -7335,17 +7340,24 @@ FreehandLineDrag<OrderedPointList,OrderedPoint>::maybe_add_point (GdkEvent* ev,
|
|||||||
did_snap = true;
|
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());
|
ArdourCanvas::Rect r = base_rect.item_to_canvas (base_rect.get());
|
||||||
|
|
||||||
/* Adjust event coordinates to be relative to the base rectangle */
|
/* 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;
|
double y = ev->motion.y - r.y0;
|
||||||
|
|
||||||
if (drawn_points.empty()) {
|
if (drawn_points.empty()) {
|
||||||
line_start_x = pointer_x;
|
line_start_x = editing_context.timeline_to_canvas (timeline_x);
|
||||||
line_start_y = y;
|
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);
|
const bool straight_line = Keyboard::modifier_state_equals (ev->motion.state, Keyboard::PrimaryModifier);
|
||||||
|
|
||||||
if (direction > 0) {
|
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) {
|
if (straight_line && dragging_line->get().size() > 1) {
|
||||||
pop_point = true;
|
pop_point = true;
|
||||||
@ -7377,7 +7389,7 @@ FreehandLineDrag<OrderedPointList,OrderedPoint>::maybe_add_point (GdkEvent* ev,
|
|||||||
|
|
||||||
|
|
||||||
} else if (direction < 0) {
|
} 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) {
|
if (straight_line && dragging_line->get().size() > 1) {
|
||||||
pop_point = true;
|
pop_point = true;
|
||||||
@ -7415,15 +7427,16 @@ FreehandLineDrag<OrderedPointList,OrderedPoint>::maybe_add_point (GdkEvent* ev,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (child_call) {
|
if (child_call) {
|
||||||
|
x = editing_context.timeline_to_canvas (timeline_x);
|
||||||
if (straight_line && !first_move) {
|
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 {
|
} 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) {
|
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)
|
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, time_domain)
|
: FreehandLineDrag<Evoral::ControlList::OrderedPoints,Evoral::ControlList::OrderedPoint> (ec, p, r, hbounded, time_domain)
|
||||||
{
|
{
|
||||||
DEBUG_TRACE (DEBUG::Drags, "New AutomationDrawDrag\n");
|
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)
|
VelocityLineDrag::VelocityLineDrag (EditingContext& ec, ArdourCanvas::Rectangle& r, bool hbounded, Temporal::TimeDomain time_domain)
|
||||||
: FreehandLineDrag<Evoral::ControlList::OrderedPoints,Evoral::ControlList::OrderedPoint> (ec, nullptr, r, time_domain)
|
: FreehandLineDrag<Evoral::ControlList::OrderedPoints,Evoral::ControlList::OrderedPoint> (ec, nullptr, r, hbounded, time_domain)
|
||||||
, vd (static_cast<VelocityDisplay*> (r.get_data ("ghostregionview")))
|
, vd (static_cast<VelocityDisplay*> (r.get_data ("ghostregionview")))
|
||||||
, drag_did_change (false)
|
, drag_did_change (false)
|
||||||
{
|
{
|
||||||
|
@ -1597,7 +1597,7 @@ template<typename OrderedPointList, typename OrderedPoint>
|
|||||||
class FreehandLineDrag : public Drag
|
class FreehandLineDrag : public Drag
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
FreehandLineDrag (EditingContext&, ArdourCanvas::Item*, ArdourCanvas::Rectangle&, Temporal::TimeDomain);
|
FreehandLineDrag (EditingContext&, ArdourCanvas::Item*, ArdourCanvas::Rectangle&, bool, Temporal::TimeDomain);
|
||||||
~FreehandLineDrag ();
|
~FreehandLineDrag ();
|
||||||
|
|
||||||
void motion (GdkEvent*, bool);
|
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::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::Rectangle& base_rect; /* we do not own this */
|
||||||
ArdourCanvas::PolyLine* dragging_line;
|
ArdourCanvas::PolyLine* dragging_line;
|
||||||
|
bool horizontally_bounded;
|
||||||
int direction;
|
int direction;
|
||||||
int edge_x;
|
int edge_x;
|
||||||
bool did_snap;
|
bool did_snap;
|
||||||
@ -1626,7 +1627,7 @@ class FreehandLineDrag : public Drag
|
|||||||
class AutomationDrawDrag : public FreehandLineDrag<Evoral::ControlList::OrderedPoints, Evoral::ControlList::OrderedPoint>
|
class AutomationDrawDrag : public FreehandLineDrag<Evoral::ControlList::OrderedPoints, Evoral::ControlList::OrderedPoint>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
AutomationDrawDrag (EditingContext&, ArdourCanvas::Item*, ArdourCanvas::Rectangle&, Temporal::TimeDomain);
|
AutomationDrawDrag (EditingContext&, ArdourCanvas::Item*, ArdourCanvas::Rectangle&, bool, Temporal::TimeDomain);
|
||||||
~AutomationDrawDrag ();
|
~AutomationDrawDrag ();
|
||||||
|
|
||||||
void finished (GdkEvent*, bool);
|
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>
|
class VelocityLineDrag : public FreehandLineDrag<Evoral::ControlList::OrderedPoints, Evoral::ControlList::OrderedPoint>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
VelocityLineDrag (EditingContext&, ArdourCanvas::Rectangle&, Temporal::TimeDomain);
|
VelocityLineDrag (EditingContext&, ArdourCanvas::Rectangle&, bool, Temporal::TimeDomain);
|
||||||
~VelocityLineDrag ();
|
~VelocityLineDrag ();
|
||||||
|
|
||||||
void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
|
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"));
|
VelocityDisplay* vd = static_cast<VelocityDisplay*> (item->get_data ("ghostregionview"));
|
||||||
VelocityGhostRegion* grv = dynamic_cast<VelocityGhostRegion*> (vd);
|
VelocityGhostRegion* grv = dynamic_cast<VelocityGhostRegion*> (vd);
|
||||||
std::cerr << "VBI with item " << item << " vd " << vd << " data for grv pointed at " << grv << std::endl;
|
|
||||||
if (grv) {
|
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;
|
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"));
|
AutomationTimeAxisView* atv = static_cast<AutomationTimeAxisView*> (item->get_data ("trackview"));
|
||||||
if (atv) {
|
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;
|
break;
|
||||||
@ -1234,7 +1233,7 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT
|
|||||||
RegionView* rv;
|
RegionView* rv;
|
||||||
if ((rv = dynamic_cast<RegionView*> (clicked_regionview))) {
|
if ((rv = dynamic_cast<RegionView*> (clicked_regionview))) {
|
||||||
ArdourCanvas::Rectangle* r = dynamic_cast<ArdourCanvas::Rectangle*> (rv->get_canvas_frame());
|
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;
|
break;
|
||||||
|
@ -41,6 +41,7 @@
|
|||||||
#include "note_base.h"
|
#include "note_base.h"
|
||||||
#include "prh.h"
|
#include "prh.h"
|
||||||
#include "ui_config.h"
|
#include "ui_config.h"
|
||||||
|
#include "velocity_ghost_region.h"
|
||||||
#include "verbose_cursor.h"
|
#include "verbose_cursor.h"
|
||||||
|
|
||||||
#include "pbd/i18n.h"
|
#include "pbd/i18n.h"
|
||||||
@ -400,6 +401,19 @@ MidiCueEditor::canvas_note_event (GdkEvent* event, ArdourCanvas::Item* item)
|
|||||||
return typed_event (item, event, NoteItem);
|
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&
|
Gtk::Widget&
|
||||||
MidiCueEditor::viewport()
|
MidiCueEditor::viewport()
|
||||||
{
|
{
|
||||||
@ -505,6 +519,17 @@ MidiCueEditor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
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:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -66,6 +66,8 @@ class MidiCueEditor : public CueEditor
|
|||||||
Temporal::Beats get_draw_length_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;
|
||||||
|
|
||||||
bool canvas_note_event (GdkEvent* event, ArdourCanvas::Item*);
|
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_beat_divisions (Editing::GridType gt) const { return 1; }
|
||||||
int32_t get_grid_music_divisions (Editing::GridType gt, uint32_t event_state) 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
|
void
|
||||||
MidiCueVelocityDisplay::remove_note (NoteBase* nb)
|
MidiCueVelocityDisplay::remove_note (NoteBase* nb)
|
||||||
{
|
{
|
||||||
std::cerr << "mcVD:remove\n";
|
|
||||||
GhostEvent::EventList::iterator f = events.find (nb->note());
|
GhostEvent::EventList::iterator f = events.find (nb->note());
|
||||||
if (f == events.end()) {
|
if (f == events.end()) {
|
||||||
return;
|
return;
|
||||||
@ -64,12 +63,12 @@ MidiCueVelocityDisplay::remove_note (NoteBase* nb)
|
|||||||
bool
|
bool
|
||||||
MidiCueVelocityDisplay::base_event (GdkEvent* ev)
|
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
|
bool
|
||||||
MidiCueVelocityDisplay::lollevent (GdkEvent* ev, GhostEvent* gev)
|
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