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)
|
||||
, did_snap (false)
|
||||
, line_break_pending (false)
|
||||
, line_start_x (-1)
|
||||
, line_start_y (-1)
|
||||
{
|
||||
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 y = ev->motion.y - r.y0;
|
||||
|
||||
if (drawn_points.empty()) {
|
||||
line_start_x = x;
|
||||
line_start_y = y;
|
||||
}
|
||||
|
||||
if (x < 0) {
|
||||
dragging_line->clear ();
|
||||
drawn_points.clear ();
|
||||
@ -7319,12 +7326,12 @@ FreehandLineDrag<OrderedPointList,OrderedPoint>::maybe_add_point (GdkEvent* ev,
|
||||
bool add_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 (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;
|
||||
}
|
||||
|
||||
@ -7333,9 +7340,9 @@ FreehandLineDrag<OrderedPointList,OrderedPoint>::maybe_add_point (GdkEvent* ev,
|
||||
|
||||
|
||||
} 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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
if (pop_point) {
|
||||
@ -7364,7 +7378,11 @@ FreehandLineDrag<OrderedPointList,OrderedPoint>::maybe_add_point (GdkEvent* ev,
|
||||
}
|
||||
|
||||
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) {
|
||||
@ -7483,6 +7501,12 @@ VelocityLineDrag::point_added (Duple const & d, ArdourCanvas::Rectangle const &
|
||||
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
|
||||
VelocityLineDrag::finished (GdkEvent* event, bool motion_occured)
|
||||
{
|
||||
|
@ -1582,6 +1582,9 @@ class FreehandLineDrag : public Drag
|
||||
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) {}
|
||||
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:
|
||||
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 line_break_pending;
|
||||
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);
|
||||
};
|
||||
@ -1616,6 +1621,7 @@ class VelocityLineDrag : public FreehandLineDrag<Evoral::ControlList::OrderedPoi
|
||||
void finished (GdkEvent*, bool);
|
||||
void aborted (bool);
|
||||
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:
|
||||
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
|
||||
MidiRegionView::set_velocity_for_notes (std::vector<NoteBase*> notes, int velocity)
|
||||
{
|
||||
|
@ -185,6 +185,7 @@ public:
|
||||
void end_drag_edit (bool apply);
|
||||
|
||||
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 */
|
||||
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 set_velocity (NoteBase* primary, 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 nudge_notes (bool forward, bool fine);
|
||||
void channel_edit ();
|
||||
|
@ -132,7 +132,7 @@ class NoteBase : public sigc::trackable
|
||||
|
||||
/// hue circle divided into 16 equal-looking parts, courtesy Thorsten Wilms
|
||||
static const uint32_t midi_channel_colors[16];
|
||||
|
||||
|
||||
bool mouse_near_ends () 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);
|
||||
}
|
||||
|
||||
bool ret = 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 ();
|
||||
if (affected_lollis.empty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -50,6 +50,8 @@ public:
|
||||
void set_selected (bool);
|
||||
|
||||
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 end_line_drag (bool did_change);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user