first steps towards improving straight line drags for velocity
This commit is contained in:
parent
68f55d62d0
commit
91fbb1c65b
|
@ -7243,6 +7243,8 @@ FreehandLineDrag<OrderedPointList,OrderedPoint>::FreehandLineDrag (Editor* edito
|
||||||
, edge_x (0)
|
, edge_x (0)
|
||||||
, did_snap (false)
|
, did_snap (false)
|
||||||
, line_break_pending (false)
|
, line_break_pending (false)
|
||||||
|
, line_start_x (-1)
|
||||||
|
, line_start_y (-1)
|
||||||
{
|
{
|
||||||
DEBUG_TRACE (DEBUG::Drags, "New FreehandLinDrag\n");
|
DEBUG_TRACE (DEBUG::Drags, "New FreehandLinDrag\n");
|
||||||
}
|
}
|
||||||
|
@ -7305,6 +7307,11 @@ FreehandLineDrag<OrderedPointList,OrderedPoint>::maybe_add_point (GdkEvent* ev,
|
||||||
double x = pointer_x - r.x0;
|
double x = pointer_x - r.x0;
|
||||||
double y = ev->motion.y - r.y0;
|
double y = ev->motion.y - r.y0;
|
||||||
|
|
||||||
|
if (drawn_points.empty()) {
|
||||||
|
line_start_x = x;
|
||||||
|
line_start_y = y;
|
||||||
|
}
|
||||||
|
|
||||||
if (x < 0) {
|
if (x < 0) {
|
||||||
dragging_line->clear ();
|
dragging_line->clear ();
|
||||||
drawn_points.clear ();
|
drawn_points.clear ();
|
||||||
|
@ -7319,12 +7326,12 @@ FreehandLineDrag<OrderedPointList,OrderedPoint>::maybe_add_point (GdkEvent* ev,
|
||||||
bool add_point = false;
|
bool add_point = false;
|
||||||
bool pop_point = false;
|
bool pop_point = false;
|
||||||
|
|
||||||
const bool 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() && (line || (pointer_x > edge_x) || (pointer_x == edge_x && ev->motion.y != last_pointer_y()))) {
|
if (x < r.width() && (straight_line || (pointer_x > edge_x) || (pointer_x == edge_x && ev->motion.y != last_pointer_y()))) {
|
||||||
|
|
||||||
if (line && dragging_line->get().size() > 1) {
|
if (straight_line && dragging_line->get().size() > 1) {
|
||||||
pop_point = true;
|
pop_point = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7333,9 +7340,9 @@ FreehandLineDrag<OrderedPointList,OrderedPoint>::maybe_add_point (GdkEvent* ev,
|
||||||
|
|
||||||
|
|
||||||
} else if (direction < 0) {
|
} else if (direction < 0) {
|
||||||
if (x >= 0. && (line || (pointer_x < edge_x) || (pointer_x == edge_x && ev->motion.y != last_pointer_y()))) {
|
if (x >= 0. && (straight_line || (pointer_x < edge_x) || (pointer_x == edge_x && ev->motion.y != last_pointer_y()))) {
|
||||||
|
|
||||||
if (line && dragging_line->get().size() > 1) {
|
if (straight_line && dragging_line->get().size() > 1) {
|
||||||
pop_point = true;
|
pop_point = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7343,6 +7350,13 @@ FreehandLineDrag<OrderedPointList,OrderedPoint>::maybe_add_point (GdkEvent* ev,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (straight_line) {
|
||||||
|
if (dragging_line->get().size() > 1) {
|
||||||
|
pop_point = true;
|
||||||
|
}
|
||||||
|
add_point = true;
|
||||||
|
}
|
||||||
|
|
||||||
bool child_call = false;
|
bool child_call = false;
|
||||||
|
|
||||||
if (pop_point) {
|
if (pop_point) {
|
||||||
|
@ -7364,7 +7378,11 @@ FreehandLineDrag<OrderedPointList,OrderedPoint>::maybe_add_point (GdkEvent* ev,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (child_call) {
|
if (child_call) {
|
||||||
point_added (ArdourCanvas::Duple (pointer_x, y), base_rect, first_move ? -1 : edge_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);
|
||||||
|
} else {
|
||||||
|
point_added (ArdourCanvas::Duple (pointer_x, y), base_rect, first_move ? -1 : edge_x);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (add_point) {
|
if (add_point) {
|
||||||
|
@ -7483,6 +7501,12 @@ VelocityLineDrag::point_added (Duple const & d, ArdourCanvas::Rectangle const &
|
||||||
drag_did_change |= grv->line_draw_motion (d, r, last_x);
|
drag_did_change |= grv->line_draw_motion (d, r, last_x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
VelocityLineDrag::line_extended (Duple const & from, Duple const & to, ArdourCanvas::Rectangle const & r, double last_x)
|
||||||
|
{
|
||||||
|
drag_did_change |= grv->line_extended (from, to, r, last_x);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
VelocityLineDrag::finished (GdkEvent* event, bool motion_occured)
|
VelocityLineDrag::finished (GdkEvent* event, bool motion_occured)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1582,6 +1582,9 @@ class FreehandLineDrag : public Drag
|
||||||
void finished (GdkEvent*, bool);
|
void finished (GdkEvent*, bool);
|
||||||
bool mid_drag_key_event (GdkEventKey*);
|
bool mid_drag_key_event (GdkEventKey*);
|
||||||
virtual void point_added (ArdourCanvas::Duple const & d, ArdourCanvas::Rectangle const & r, double last_x) {}
|
virtual void point_added (ArdourCanvas::Duple const & d, ArdourCanvas::Rectangle const & r, double last_x) {}
|
||||||
|
virtual void line_extended (ArdourCanvas::Duple const & from, ArdourCanvas::Duple const & to, ArdourCanvas::Rectangle const & r, double last_x) {
|
||||||
|
point_added (to, r, last_x);
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
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 */
|
||||||
|
@ -1592,6 +1595,8 @@ class FreehandLineDrag : public Drag
|
||||||
bool did_snap;
|
bool did_snap;
|
||||||
bool line_break_pending;
|
bool line_break_pending;
|
||||||
OrderedPointList drawn_points;
|
OrderedPointList drawn_points;
|
||||||
|
ArdourCanvas::Coord line_start_x;
|
||||||
|
ArdourCanvas::Coord line_start_y;
|
||||||
|
|
||||||
void maybe_add_point (GdkEvent*, Temporal::timepos_t const &, bool first_move);
|
void maybe_add_point (GdkEvent*, Temporal::timepos_t const &, bool first_move);
|
||||||
};
|
};
|
||||||
|
@ -1616,6 +1621,7 @@ class VelocityLineDrag : public FreehandLineDrag<Evoral::ControlList::OrderedPoi
|
||||||
void finished (GdkEvent*, bool);
|
void finished (GdkEvent*, bool);
|
||||||
void aborted (bool);
|
void aborted (bool);
|
||||||
void point_added (ArdourCanvas::Duple const & d, ArdourCanvas::Rectangle const & r, double last_x);
|
void point_added (ArdourCanvas::Duple const & d, ArdourCanvas::Rectangle const & r, double last_x);
|
||||||
|
void line_extended (ArdourCanvas::Duple const & from, ArdourCanvas::Duple const & to, ArdourCanvas::Rectangle const & r, double last_x);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
VelocityGhostRegion* grv;
|
VelocityGhostRegion* grv;
|
||||||
|
|
|
@ -3447,6 +3447,34 @@ MidiRegionView::end_drag_edit (bool apply)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
MidiRegionView::set_velocities_for_notes (std::vector<NoteBase*> notes, std::vector<int> velocities)
|
||||||
|
{
|
||||||
|
assert (notes.size() == velocities.size());
|
||||||
|
|
||||||
|
/* Does not use selection, used when drawing/dragging in velocity lane */
|
||||||
|
|
||||||
|
bool changed = false;
|
||||||
|
|
||||||
|
auto notei = notes.begin();
|
||||||
|
auto veloi = velocities.begin();
|
||||||
|
|
||||||
|
while (notei != notes.end()) {
|
||||||
|
|
||||||
|
int delta = (*veloi) - (*notei)->note()->velocity();
|
||||||
|
|
||||||
|
if (delta) {
|
||||||
|
changed = true;
|
||||||
|
change_note_velocity (*notei, delta, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
++notei;
|
||||||
|
++veloi;
|
||||||
|
}
|
||||||
|
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
MidiRegionView::set_velocity_for_notes (std::vector<NoteBase*> notes, int velocity)
|
MidiRegionView::set_velocity_for_notes (std::vector<NoteBase*> notes, int velocity)
|
||||||
{
|
{
|
||||||
|
|
|
@ -185,6 +185,7 @@ public:
|
||||||
void end_drag_edit (bool apply);
|
void end_drag_edit (bool apply);
|
||||||
|
|
||||||
void display_model(std::shared_ptr<ARDOUR::MidiModel> model);
|
void display_model(std::shared_ptr<ARDOUR::MidiModel> model);
|
||||||
|
std::shared_ptr<ARDOUR::MidiModel> model() const { return _model; }
|
||||||
|
|
||||||
/* note_diff commands should start here; this initiates an undo record */
|
/* note_diff commands should start here; this initiates an undo record */
|
||||||
void start_note_diff_command (std::string name = "midi edit");
|
void start_note_diff_command (std::string name = "midi edit");
|
||||||
|
@ -295,6 +296,7 @@ public:
|
||||||
void change_velocities (bool up, bool fine, bool allow_smush, bool all_together);
|
void change_velocities (bool up, bool fine, bool allow_smush, bool all_together);
|
||||||
void set_velocity (NoteBase* primary, int velocity);
|
void set_velocity (NoteBase* primary, int velocity);
|
||||||
bool set_velocity_for_notes (std::vector<NoteBase*> notes, int velocity);
|
bool set_velocity_for_notes (std::vector<NoteBase*> notes, int velocity);
|
||||||
|
bool set_velocities_for_notes (std::vector<NoteBase*> notes, std::vector<int> velocities);
|
||||||
void transpose (bool up, bool fine, bool allow_smush);
|
void transpose (bool up, bool fine, bool allow_smush);
|
||||||
void nudge_notes (bool forward, bool fine);
|
void nudge_notes (bool forward, bool fine);
|
||||||
void channel_edit ();
|
void channel_edit ();
|
||||||
|
|
|
@ -132,7 +132,7 @@ class NoteBase : public sigc::trackable
|
||||||
|
|
||||||
/// hue circle divided into 16 equal-looking parts, courtesy Thorsten Wilms
|
/// hue circle divided into 16 equal-looking parts, courtesy Thorsten Wilms
|
||||||
static const uint32_t midi_channel_colors[16];
|
static const uint32_t midi_channel_colors[16];
|
||||||
|
|
||||||
bool mouse_near_ends () const;
|
bool mouse_near_ends () const;
|
||||||
virtual bool big_enough_to_trim () const;
|
virtual bool big_enough_to_trim () const;
|
||||||
|
|
||||||
|
|
|
@ -86,14 +86,51 @@ VelocityGhostRegion::line_draw_motion (ArdourCanvas::Duple const & d, ArdourCanv
|
||||||
lollis_between (d.x, last_x, affected_lollis);
|
lollis_between (d.x, last_x, affected_lollis);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ret = false;
|
if (affected_lollis.empty()) {
|
||||||
|
return false;
|
||||||
if (!affected_lollis.empty()) {
|
|
||||||
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 ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int velocity = y_position_to_velocity (r.height() - (r.y1() - d.y));
|
||||||
|
bool ret = mrv->set_velocity_for_notes (affected_lollis, velocity);
|
||||||
|
mrv->mid_drag_edit ();
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
VelocityGhostRegion::line_extended (ArdourCanvas::Duple const & from, ArdourCanvas::Duple const & to, ArdourCanvas::Rectangle const & r, double last_x)
|
||||||
|
{
|
||||||
|
std::vector<NoteBase*> affected_lollis;
|
||||||
|
|
||||||
|
lollis_between (from.x, to.x, affected_lollis);
|
||||||
|
|
||||||
|
if (affected_lollis.empty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (to.x == from.x) {
|
||||||
|
/* no x-axis motion */
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
double slope = (to.y - from.y) / (to.x - from.x);
|
||||||
|
std::vector<int> velocities;
|
||||||
|
|
||||||
|
for (auto const & nb : affected_lollis) {
|
||||||
|
ArdourCanvas::Item* it = nb->item();
|
||||||
|
ArdourCanvas::Duple pos = it->item_to_canvas (ArdourCanvas::Duple (nb->x0(), 0.0));
|
||||||
|
int y = from.y + (slope * (pos.x - from.x));
|
||||||
|
int velocity = y_position_to_velocity (r.height() - (r.y1() - y));
|
||||||
|
velocities.push_back (velocity);
|
||||||
|
}
|
||||||
|
|
||||||
|
MidiRegionView* mrv = dynamic_cast<MidiRegionView*> (&parent_rv);
|
||||||
|
bool ret = mrv->set_velocities_for_notes (affected_lollis, velocities);
|
||||||
|
|
||||||
|
mrv->mid_drag_edit ();
|
||||||
|
|
||||||
|
model_changed ();
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -50,6 +50,8 @@ public:
|
||||||
void set_selected (bool);
|
void set_selected (bool);
|
||||||
|
|
||||||
bool line_draw_motion (ArdourCanvas::Duple const & d, ArdourCanvas::Rectangle const & r, double last_x);
|
bool line_draw_motion (ArdourCanvas::Duple const & d, ArdourCanvas::Rectangle const & r, double last_x);
|
||||||
|
bool line_extended (ArdourCanvas::Duple const & from, ArdourCanvas::Duple const & to, ArdourCanvas::Rectangle const & r, double last_x);
|
||||||
|
|
||||||
void start_line_drag ();
|
void start_line_drag ();
|
||||||
void end_line_drag (bool did_change);
|
void end_line_drag (bool did_change);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue