mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-06 14:54:56 +01:00
freehand line drawing: automation & velocity share the same basic code
This commit is contained in:
parent
2c48aabe08
commit
df52c39ce0
9 changed files with 235 additions and 107 deletions
|
|
@ -1702,6 +1702,7 @@ private:
|
|||
bool canvas_scroll_event (GdkEventScroll* event, bool from_canvas);
|
||||
bool canvas_control_point_event (GdkEvent* event,ArdourCanvas::Item*, ControlPoint*);
|
||||
bool canvas_velocity_event (GdkEvent* event,ArdourCanvas::Item*);
|
||||
bool canvas_velocity_base_event (GdkEvent* event,ArdourCanvas::Item*);
|
||||
bool canvas_line_event (GdkEvent* event,ArdourCanvas::Item*, AutomationLine*);
|
||||
bool canvas_selection_rect_event (GdkEvent* event,ArdourCanvas::Item*, SelectionRect*);
|
||||
bool canvas_selection_start_trim_event (GdkEvent* event,ArdourCanvas::Item*, SelectionRect*);
|
||||
|
|
|
|||
|
|
@ -693,10 +693,15 @@ Editor::canvas_control_point_event (GdkEvent *event, ArdourCanvas::Item* item, C
|
|||
bool
|
||||
Editor::canvas_velocity_event (GdkEvent *event, ArdourCanvas::Item* item)
|
||||
{
|
||||
// std::cerr << "Velocity event: " << Gtkmm2ext::event_type_string (event->type) << std::endl;
|
||||
return typed_event (item, event, VelocityItem);
|
||||
}
|
||||
|
||||
bool
|
||||
Editor::canvas_velocity_base_event (GdkEvent *event, ArdourCanvas::Item* item)
|
||||
{
|
||||
return typed_event (item, event, VelocityBaseItem);
|
||||
}
|
||||
|
||||
bool
|
||||
Editor::canvas_line_event (GdkEvent *event, ArdourCanvas::Item* item, AutomationLine* al)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -7199,6 +7199,7 @@ LollipopDrag::LollipopDrag (Editor* ed, ArdourCanvas::Item* l)
|
|||
: Drag (ed, l, Temporal::BeatTime)
|
||||
, _primary (dynamic_cast<ArdourCanvas::Lollipop*> (l))
|
||||
{
|
||||
DEBUG_TRACE (DEBUG::Drags, "New LollipopDrag\n");
|
||||
_region = reinterpret_cast<VelocityGhostRegion*> (_item->get_data ("ghostregionview"));
|
||||
}
|
||||
|
||||
|
|
@ -7257,7 +7258,10 @@ LollipopDrag::setup_pointer_offset ()
|
|||
_pointer_offset = _region->parent_rv.region()->source_beats_to_absolute_time (note->note()->time ()).distance (raw_grab_time ());
|
||||
}
|
||||
|
||||
AutomationDrawDrag::AutomationDrawDrag (Editor* editor, ArdourCanvas::Rectangle& r, Temporal::TimeDomain time_domain)
|
||||
/********/
|
||||
|
||||
template<typename OrderedPointList, typename OrderedPoint>
|
||||
FreehandLineDrag<OrderedPointList,OrderedPoint>::FreehandLineDrag (Editor* editor, ArdourCanvas::Rectangle& r, Temporal::TimeDomain time_domain)
|
||||
: Drag (editor, &r, time_domain)
|
||||
, base_rect (r)
|
||||
, dragging_line (nullptr)
|
||||
|
|
@ -7269,13 +7273,15 @@ AutomationDrawDrag::AutomationDrawDrag (Editor* editor, ArdourCanvas::Rectangle&
|
|||
DEBUG_TRACE (DEBUG::Drags, "New AutomationDrawDrag\n");
|
||||
}
|
||||
|
||||
AutomationDrawDrag::~AutomationDrawDrag ()
|
||||
template<typename OrderedPointList, typename OrderedPoint>
|
||||
FreehandLineDrag<OrderedPointList,OrderedPoint>::~FreehandLineDrag ()
|
||||
{
|
||||
delete dragging_line;
|
||||
}
|
||||
|
||||
template<typename OrderedPointList, typename OrderedPoint>
|
||||
void
|
||||
AutomationDrawDrag::motion (GdkEvent* ev, bool first_move)
|
||||
FreehandLineDrag<OrderedPointList,OrderedPoint>::motion (GdkEvent* ev, bool first_move)
|
||||
{
|
||||
if (first_move) {
|
||||
dragging_line = new ArdourCanvas::PolyLine (item());
|
||||
|
|
@ -7293,14 +7299,15 @@ AutomationDrawDrag::motion (GdkEvent* ev, bool first_move)
|
|||
|
||||
/* Add a point correspding to the start of the drag */
|
||||
|
||||
maybe_add_point (ev, raw_grab_time());
|
||||
maybe_add_point (ev, raw_grab_time(), true);
|
||||
}
|
||||
|
||||
maybe_add_point (ev, _drags->current_pointer_time());
|
||||
maybe_add_point (ev, _drags->current_pointer_time(), first_move);
|
||||
}
|
||||
|
||||
template<typename OrderedPointList, typename OrderedPoint>
|
||||
void
|
||||
AutomationDrawDrag::maybe_add_point (GdkEvent* ev, timepos_t const & cpos)
|
||||
FreehandLineDrag<OrderedPointList,OrderedPoint>::maybe_add_point (GdkEvent* ev, timepos_t const & cpos, bool first_move)
|
||||
{
|
||||
timepos_t pos (cpos);
|
||||
|
||||
|
|
@ -7347,24 +7354,91 @@ AutomationDrawDrag::maybe_add_point (GdkEvent* ev, timepos_t const & cpos)
|
|||
}
|
||||
}
|
||||
|
||||
bool child_call = false;
|
||||
|
||||
if (pop_point) {
|
||||
if (line_break_pending) {
|
||||
line_break_pending = false;
|
||||
} else {
|
||||
dragging_line->pop_back();
|
||||
drawn_points.pop_back ();
|
||||
child_call = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (add_point) {
|
||||
if (drawn_points.empty() || (pos != drawn_points.back().when)) {
|
||||
dragging_line->add_point (ArdourCanvas::Duple (x, y));
|
||||
drawn_points.push_back (Evoral::ControlList::OrderedPoint (pos, y));
|
||||
drawn_points.push_back (OrderedPoint (pos, y));
|
||||
child_call = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (child_call) {
|
||||
point_added (ArdourCanvas::Duple (pointer_x, y), base_rect, first_move ? -1 : edge_x);
|
||||
}
|
||||
|
||||
if (add_point) {
|
||||
edge_x = pointer_x;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename OrderedPointList, typename OrderedPoint>
|
||||
void
|
||||
FreehandLineDrag<OrderedPointList,OrderedPoint>::finished (GdkEvent* event, bool motion_occured)
|
||||
{
|
||||
if (!motion_occured) {
|
||||
/* DragManager will tell editor that no motion happened, and
|
||||
Editor::button_release_handler() will do the right thing.
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
if (drawn_points.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Points must be in time order, so if the user draw right to left, fix
|
||||
* that here
|
||||
*/
|
||||
|
||||
if (drawn_points.front().when > drawn_points.back().when) {
|
||||
std::reverse (drawn_points.begin(), drawn_points.end());
|
||||
}
|
||||
}
|
||||
|
||||
template<typename OrderedPointList, typename OrderedPoint>
|
||||
bool
|
||||
FreehandLineDrag<OrderedPointList,OrderedPoint>::mid_drag_key_event (GdkEventKey* ev)
|
||||
{
|
||||
if (ev->type == GDK_KEY_PRESS) {
|
||||
switch (ev->keyval) {
|
||||
|
||||
case GDK_Alt_R:
|
||||
case GDK_Alt_L:
|
||||
line_break_pending = true;
|
||||
return true;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**********************/
|
||||
|
||||
AutomationDrawDrag::AutomationDrawDrag (Editor* editor, ArdourCanvas::Rectangle& r, Temporal::TimeDomain time_domain)
|
||||
: FreehandLineDrag<Evoral::ControlList::OrderedPoints,Evoral::ControlList::OrderedPoint> (editor, r, time_domain)
|
||||
{
|
||||
DEBUG_TRACE (DEBUG::Drags, "New AutomationDrawDrag\n");
|
||||
}
|
||||
|
||||
AutomationDrawDrag::~AutomationDrawDrag ()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
AutomationDrawDrag::finished (GdkEvent* event, bool motion_occured)
|
||||
{
|
||||
|
|
@ -7384,37 +7458,58 @@ AutomationDrawDrag::finished (GdkEvent* event, bool motion_occured)
|
|||
return;
|
||||
}
|
||||
|
||||
/* Points must be in time order, so if the user draw right to left, fix
|
||||
* that here
|
||||
*/
|
||||
|
||||
if (drawn_points.front().when > drawn_points.back().when) {
|
||||
std::reverse (drawn_points.begin(), drawn_points.end());
|
||||
}
|
||||
FreehandLineDrag<Evoral::ControlList::OrderedPoints,Evoral::ControlList::OrderedPoint>::finished (event, motion_occured);
|
||||
|
||||
atv->merge_drawn_line (drawn_points, !did_snap);
|
||||
}
|
||||
|
||||
/*****************/
|
||||
|
||||
VelocityLineDrag::VelocityLineDrag (Editor* editor, ArdourCanvas::Rectangle& r, Temporal::TimeDomain time_domain)
|
||||
: FreehandLineDrag<Evoral::ControlList::OrderedPoints,Evoral::ControlList::OrderedPoint> (editor, r, time_domain)
|
||||
, grv (static_cast<VelocityGhostRegion*> (r.get_data ("ghostregionview")))
|
||||
, drag_did_change (false)
|
||||
{
|
||||
DEBUG_TRACE (DEBUG::Drags, "New VelocityLineDrag\n");
|
||||
assert (grv);
|
||||
}
|
||||
|
||||
VelocityLineDrag::~VelocityLineDrag ()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
AutomationDrawDrag::aborted (bool)
|
||||
VelocityLineDrag::start_grab (GdkEvent* ev, Gdk::Cursor* c)
|
||||
{
|
||||
FreehandLineDrag<Evoral::ControlList::OrderedPoints,Evoral::ControlList::OrderedPoint>::start_grab (ev, c);
|
||||
grv->start_line_drag ();
|
||||
}
|
||||
|
||||
bool
|
||||
AutomationDrawDrag::mid_drag_key_event (GdkEventKey* ev)
|
||||
void
|
||||
VelocityLineDrag::point_added (Duple const & d, Rectangle const & r, double last_x)
|
||||
{
|
||||
if (ev->type == GDK_KEY_PRESS) {
|
||||
switch (ev->keyval) {
|
||||
|
||||
case GDK_Alt_R:
|
||||
case GDK_Alt_L:
|
||||
line_break_pending = true;
|
||||
return true;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
drag_did_change |= grv->line_draw_motion (d, r, last_x);
|
||||
}
|
||||
|
||||
return false;
|
||||
void
|
||||
VelocityLineDrag::finished (GdkEvent* event, bool motion_occured)
|
||||
{
|
||||
if (!motion_occured) {
|
||||
/* DragManager will tell editor that no motion happened, and
|
||||
Editor::button_release_handler() will do the right thing.
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
/* no need to call FreehandLineDrag::finished(), because we do not use
|
||||
* drawn_points
|
||||
*/
|
||||
|
||||
grv->end_line_drag (drag_did_change);
|
||||
}
|
||||
|
||||
void
|
||||
VelocityLineDrag::aborted (bool)
|
||||
{
|
||||
grv->end_line_drag (false);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1583,27 +1583,56 @@ class LollipopDrag : public Drag
|
|||
ArdourCanvas::Lollipop* _primary;
|
||||
};
|
||||
|
||||
class AutomationDrawDrag : public Drag
|
||||
template<typename OrderedPointList, typename OrderedPoint>
|
||||
class FreehandLineDrag : public Drag
|
||||
{
|
||||
public:
|
||||
FreehandLineDrag (Editor*, ArdourCanvas::Rectangle&, Temporal::TimeDomain);
|
||||
~FreehandLineDrag ();
|
||||
|
||||
void motion (GdkEvent*, bool);
|
||||
void finished (GdkEvent*, bool);
|
||||
bool mid_drag_key_event (GdkEventKey*);
|
||||
virtual void point_added (ArdourCanvas::Duple const & d, ArdourCanvas::Rectangle const & r, double last_x) {}
|
||||
|
||||
protected:
|
||||
ArdourCanvas::Rectangle& base_rect; /* we do not own this */
|
||||
ArdourCanvas::PolyLine* dragging_line;
|
||||
int direction;
|
||||
int edge_x;
|
||||
bool did_snap;
|
||||
bool line_break_pending;
|
||||
OrderedPointList drawn_points;
|
||||
|
||||
void maybe_add_point (GdkEvent*, Temporal::timepos_t const &, bool first_move);
|
||||
};
|
||||
|
||||
class AutomationDrawDrag : public FreehandLineDrag<Evoral::ControlList::OrderedPoints, Evoral::ControlList::OrderedPoint>
|
||||
{
|
||||
public:
|
||||
AutomationDrawDrag (Editor*, ArdourCanvas::Rectangle&, Temporal::TimeDomain);
|
||||
~AutomationDrawDrag ();
|
||||
|
||||
void motion (GdkEvent*, bool);
|
||||
void finished (GdkEvent*, bool);
|
||||
void aborted (bool);
|
||||
bool mid_drag_key_event (GdkEventKey*);
|
||||
|
||||
private:
|
||||
ArdourCanvas::Rectangle& base_rect; /* we do not own this */
|
||||
ArdourCanvas::PolyLine* dragging_line;
|
||||
int direction;
|
||||
int edge_x;
|
||||
Evoral::ControlList::OrderedPoints drawn_points;
|
||||
bool did_snap;
|
||||
bool line_break_pending;
|
||||
|
||||
void maybe_add_point (GdkEvent*, Temporal::timepos_t const &);
|
||||
void aborted (bool) {}
|
||||
};
|
||||
|
||||
class VelocityLineDrag : public FreehandLineDrag<Evoral::ControlList::OrderedPoints, Evoral::ControlList::OrderedPoint>
|
||||
{
|
||||
public:
|
||||
VelocityLineDrag (Editor*, ArdourCanvas::Rectangle&, Temporal::TimeDomain);
|
||||
~VelocityLineDrag ();
|
||||
|
||||
void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
|
||||
void finished (GdkEvent*, bool);
|
||||
void aborted (bool);
|
||||
void point_added (ArdourCanvas::Duple const & d, ArdourCanvas::Rectangle const & r, double last_x);
|
||||
|
||||
private:
|
||||
VelocityGhostRegion* grv;
|
||||
bool drag_did_change;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif /* __gtk2_ardour_editor_drag_h_ */
|
||||
|
|
|
|||
|
|
@ -69,6 +69,7 @@ enum ItemType {
|
|||
SelectionMarkerItem,
|
||||
DropZoneItem,
|
||||
VelocityItem,
|
||||
VelocityBaseItem,
|
||||
|
||||
/* don't remove this */
|
||||
|
||||
|
|
|
|||
|
|
@ -82,6 +82,7 @@
|
|||
#include "mouse_cursors.h"
|
||||
#include "editor_cursors.h"
|
||||
#include "region_peak_cursor.h"
|
||||
#include "velocity_ghost_region.h"
|
||||
#include "verbose_cursor.h"
|
||||
#include "note.h"
|
||||
|
||||
|
|
@ -902,6 +903,16 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT
|
|||
return true;
|
||||
break;
|
||||
|
||||
case VelocityBaseItem:
|
||||
{
|
||||
VelocityGhostRegion* grv = static_cast<VelocityGhostRegion*> (item->get_data ("ghostregionview"));
|
||||
if (grv) {
|
||||
_drags->set (new VelocityLineDrag (this, grv->base_item(), Temporal::BeatTime), event);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -1569,6 +1580,7 @@ Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemT
|
|||
/* see if we're finishing a drag */
|
||||
|
||||
if (_drags->active ()) {
|
||||
|
||||
bool const r = _drags->end_grab (event);
|
||||
if (r) {
|
||||
/* grab dragged, so do nothing else */
|
||||
|
|
|
|||
|
|
@ -451,6 +451,7 @@ public:
|
|||
virtual bool canvas_scroll_event (GdkEventScroll* event, bool from_canvas) = 0;
|
||||
virtual bool canvas_control_point_event (GdkEvent* event, ArdourCanvas::Item*, ControlPoint*) = 0;
|
||||
virtual bool canvas_velocity_event (GdkEvent* event, ArdourCanvas::Item*) = 0;
|
||||
virtual bool canvas_velocity_base_event (GdkEvent* event, ArdourCanvas::Item*) = 0;
|
||||
virtual bool canvas_line_event (GdkEvent* event, ArdourCanvas::Item*, AutomationLine*) = 0;
|
||||
virtual bool canvas_selection_rect_event (GdkEvent* event, ArdourCanvas::Item*, SelectionRect*) = 0;
|
||||
virtual bool canvas_selection_start_trim_event (GdkEvent* event, ArdourCanvas::Item*, SelectionRect*) = 0;
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@ VelocityGhostRegion::VelocityGhostRegion (MidiRegionView& mrv, TimeAxisView& tv,
|
|||
, drag_did_change (false)
|
||||
, selected (false)
|
||||
{
|
||||
base_rect->set_data (X_("ghostregionview"), this);
|
||||
base_rect->Event.connect (sigc::mem_fun (*this, &VelocityGhostRegion::base_event));
|
||||
base_rect->set_fill_color (UIConfiguration::instance().color_mod ("ghost track base", "ghost track midi fill"));
|
||||
base_rect->set_outline_color (UIConfiguration::instance().color ("automation track outline"));
|
||||
|
|
@ -70,74 +71,36 @@ VelocityGhostRegion::~VelocityGhostRegion ()
|
|||
}
|
||||
|
||||
bool
|
||||
VelocityGhostRegion::base_event (GdkEvent* ev)
|
||||
VelocityGhostRegion::line_draw_motion (ArdourCanvas::Duple const & d, ArdourCanvas::Rectangle const & r, double last_x)
|
||||
{
|
||||
std::vector<NoteBase*> affected_lollis;
|
||||
|
||||
MidiRegionView* mrv = dynamic_cast<MidiRegionView*> (&parent_rv);
|
||||
ArdourCanvas::Rect r = base_rect->item_to_canvas (base_rect->get());
|
||||
|
||||
switch (ev->type) {
|
||||
case GDK_MOTION_NOTIFY:
|
||||
if (dragging) {
|
||||
if (last_drag_x < 0) {
|
||||
lollis_close_to_x (ev->motion.x, 20., affected_lollis);
|
||||
} else if (last_drag_x < ev->motion.x) {
|
||||
if (last_x < 0) {
|
||||
lollis_close_to_x (d.x, 20., affected_lollis);
|
||||
} else if (last_x < d.x) {
|
||||
/* rightward, "later" motion */
|
||||
lollis_between (last_drag_x, ev->motion.x, affected_lollis);
|
||||
lollis_between (last_x, d.x, affected_lollis);
|
||||
} else {
|
||||
/* leftward, "earlier" motion */
|
||||
lollis_between (ev->motion.x, last_drag_x, affected_lollis);
|
||||
lollis_between (d.x, last_x, affected_lollis);
|
||||
}
|
||||
|
||||
bool ret = false;
|
||||
|
||||
if (!affected_lollis.empty()) {
|
||||
int velocity = y_position_to_velocity (r.height() - (r.y1 - ev->motion.y));
|
||||
drag_did_change |= mrv->set_velocity_for_notes (affected_lollis, velocity);
|
||||
int velocity = y_position_to_velocity (r.height() - (r.y1() - d.y));
|
||||
ret = mrv->set_velocity_for_notes (affected_lollis, velocity);
|
||||
mrv->mid_drag_edit ();
|
||||
}
|
||||
if (dragging) {
|
||||
dragging_line->add_point (ArdourCanvas::Duple (ev->motion.x - r.x0, ev->motion.y - r.y0));
|
||||
last_drag_x = ev->motion.x;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case GDK_BUTTON_PRESS:
|
||||
if (ev->button.button == 1) {
|
||||
assert (!dragging);
|
||||
desensitize_lollis ();
|
||||
dragging = true;
|
||||
drag_did_change = false;
|
||||
last_drag_x = -1;
|
||||
if (!dragging_line) {
|
||||
dragging_line = new ArdourCanvas::PolyLine (_note_group);
|
||||
dragging_line->set_ignore_events (true);
|
||||
dragging_line->set_outline_color (UIConfiguration::instance().color ("midi note selected outline"));
|
||||
}
|
||||
dragging_line->set (ArdourCanvas::Points());
|
||||
dragging_line->show();
|
||||
dragging_line->raise_to_top();
|
||||
base_rect->grab();
|
||||
mrv->begin_drag_edit (_("draw velocities"));
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case GDK_BUTTON_RELEASE:
|
||||
if (ev->button.button == 1 && dragging) {
|
||||
mrv->end_drag_edit (drag_did_change);
|
||||
base_rect->ungrab();
|
||||
dragging_line->hide ();
|
||||
dragging = false;
|
||||
sensitize_lollis ();
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// std::cerr << "vgr event type " << Gtkmm2ext::event_type_string (ev->type) << std::endl;
|
||||
break;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
bool
|
||||
VelocityGhostRegion::base_event (GdkEvent* ev)
|
||||
{
|
||||
return trackview.editor().canvas_velocity_base_event (ev, base_rect);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -234,7 +197,6 @@ VelocityGhostRegion::drag_lolli (ArdourCanvas::Lollipop* l, GdkEventMotion* ev)
|
|||
* (event coordinates use window coordinate space)
|
||||
*/
|
||||
|
||||
|
||||
ev->y -= r.y0;
|
||||
|
||||
/* clamp y to be within the range defined by the base_rect height minus
|
||||
|
|
@ -357,6 +319,22 @@ VelocityGhostRegion::lollis_close_to_x (int x, double distance, std::vector<Note
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
VelocityGhostRegion::start_line_drag ()
|
||||
{
|
||||
MidiRegionView* mrv = dynamic_cast<MidiRegionView*> (&parent_rv);
|
||||
mrv->begin_drag_edit (_("draw velocities"));
|
||||
desensitize_lollis ();
|
||||
}
|
||||
|
||||
void
|
||||
VelocityGhostRegion::end_line_drag (bool did_change)
|
||||
{
|
||||
MidiRegionView* mrv = dynamic_cast<MidiRegionView*> (&parent_rv);
|
||||
mrv->end_drag_edit (did_change);
|
||||
sensitize_lollis ();
|
||||
}
|
||||
|
||||
void
|
||||
VelocityGhostRegion::desensitize_lollis ()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -49,6 +49,12 @@ public:
|
|||
|
||||
void set_selected (bool);
|
||||
|
||||
bool line_draw_motion (ArdourCanvas::Duple const & d, ArdourCanvas::Rectangle const & r, double last_x);
|
||||
void start_line_drag ();
|
||||
void end_line_drag (bool did_change);
|
||||
|
||||
ArdourCanvas::Rectangle& base_item() { return *base_rect; }
|
||||
|
||||
private:
|
||||
bool dragging;
|
||||
ArdourCanvas::PolyLine* dragging_line;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue