more improvements to velocity drawing (including straight line)
This commit is contained in:
parent
91fbb1c65b
commit
ef0938a16d
@ -7308,7 +7308,7 @@ FreehandLineDrag<OrderedPointList,OrderedPoint>::maybe_add_point (GdkEvent* ev,
|
||||
double y = ev->motion.y - r.y0;
|
||||
|
||||
if (drawn_points.empty()) {
|
||||
line_start_x = x;
|
||||
line_start_x = pointer_x;
|
||||
line_start_y = y;
|
||||
}
|
||||
|
||||
|
@ -215,6 +215,7 @@ MidiGhostRegion::GhostEvent::GhostEvent (NoteBase* e, ArdourCanvas::Container* g
|
||||
, item (i)
|
||||
, is_hit (false)
|
||||
{
|
||||
velocity_while_editing = event->note()->velocity();
|
||||
}
|
||||
|
||||
MidiGhostRegion::GhostEvent::GhostEvent (NoteBase* e, ArdourCanvas::Container* g)
|
||||
@ -235,6 +236,8 @@ MidiGhostRegion::GhostEvent::GhostEvent (NoteBase* e, ArdourCanvas::Container* g
|
||||
is_hit = true;
|
||||
}
|
||||
|
||||
velocity_while_editing = event->note()->velocity();
|
||||
|
||||
CANVAS_DEBUG_NAME (item, "ghost note item");
|
||||
}
|
||||
|
||||
|
@ -108,6 +108,7 @@ public:
|
||||
NoteBase* event;
|
||||
ArdourCanvas::Item* item;
|
||||
bool is_hit;
|
||||
int velocity_while_editing;
|
||||
};
|
||||
|
||||
MidiGhostRegion(MidiRegionView& rv,
|
||||
|
@ -3402,54 +3402,18 @@ MidiRegionView::begin_drag_edit (std::string const & why)
|
||||
if (!_selected) {
|
||||
trackview.editor().get_selection().set (this, true);
|
||||
}
|
||||
start_note_diff_command (why);
|
||||
}
|
||||
|
||||
void
|
||||
MidiRegionView::drag_apply ()
|
||||
MidiRegionView::end_drag_edit ()
|
||||
{
|
||||
if (!_note_diff_command) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool add_or_remove = _note_diff_command->adds_or_removes();
|
||||
|
||||
if (add_or_remove) {
|
||||
// Mark all selected notes for selection when model reloads
|
||||
for (auto const & sel : _selection) {
|
||||
_marked_for_selection.insert (sel->note());
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
PBD::Unwinder<bool> puw (_select_all_notes_after_add, true);
|
||||
/*note that we don't use as_commit here, because that would BEGIN a new undo record; we already have one underway*/
|
||||
_model->apply_diff_command_as_subcommand (*trackview.session(), _note_diff_command);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MidiRegionView::mid_drag_edit ()
|
||||
{
|
||||
drag_apply ();
|
||||
_note_diff_command = _model->new_note_diff_command ();
|
||||
}
|
||||
|
||||
void
|
||||
MidiRegionView::end_drag_edit (bool apply)
|
||||
{
|
||||
if (apply) {
|
||||
drag_apply ();
|
||||
trackview.editor().commit_reversible_command ();
|
||||
_note_diff_command = nullptr;
|
||||
} else {
|
||||
abort_note_diff ();
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
MidiRegionView::set_velocities_for_notes (std::vector<NoteBase*> notes, std::vector<int> velocities)
|
||||
{
|
||||
start_note_diff_command (_("draw velocities"));
|
||||
|
||||
assert (notes.size() == velocities.size());
|
||||
|
||||
/* Does not use selection, used when drawing/dragging in velocity lane */
|
||||
@ -3472,6 +3436,11 @@ MidiRegionView::set_velocities_for_notes (std::vector<NoteBase*> notes, std::vec
|
||||
++veloi;
|
||||
}
|
||||
|
||||
apply_note_diff (true /*subcommand, we don't want this to start a new commit*/, false);
|
||||
trackview.editor().commit_reversible_command ();
|
||||
delete _note_diff_command;
|
||||
_note_diff_command = nullptr;
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
|
@ -181,8 +181,7 @@ public:
|
||||
void extend_active_notes();
|
||||
|
||||
void begin_drag_edit (std::string const & why);
|
||||
void mid_drag_edit ();
|
||||
void end_drag_edit (bool apply);
|
||||
void end_drag_edit ();
|
||||
|
||||
void display_model(std::shared_ptr<ARDOUR::MidiModel> model);
|
||||
std::shared_ptr<ARDOUR::MidiModel> model() const { return _model; }
|
||||
@ -591,7 +590,6 @@ public:
|
||||
void model_changed ();
|
||||
|
||||
void sync_ghost_selection (NoteBase*);
|
||||
void drag_apply ();
|
||||
};
|
||||
|
||||
|
||||
|
@ -73,8 +73,7 @@ VelocityGhostRegion::~VelocityGhostRegion ()
|
||||
bool
|
||||
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);
|
||||
std::vector<GhostEvent*> affected_lollis;
|
||||
|
||||
if (last_x < 0) {
|
||||
lollis_close_to_x (d.x, 20., affected_lollis);
|
||||
@ -91,16 +90,19 @@ VelocityGhostRegion::line_draw_motion (ArdourCanvas::Duple const & d, ArdourCanv
|
||||
}
|
||||
|
||||
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;
|
||||
for (auto & lolli : affected_lollis) {
|
||||
lolli->velocity_while_editing = velocity;
|
||||
set_size_and_position (*lolli);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
VelocityGhostRegion::line_extended (ArdourCanvas::Duple const & from, ArdourCanvas::Duple const & to, ArdourCanvas::Rectangle const & r, double last_x)
|
||||
{
|
||||
std::vector<NoteBase*> affected_lollis;
|
||||
std::vector<GhostEvent*> affected_lollis;
|
||||
|
||||
lollis_between (from.x, to.x, affected_lollis);
|
||||
|
||||
@ -114,24 +116,16 @@ VelocityGhostRegion::line_extended (ArdourCanvas::Duple const & from, ArdourCanv
|
||||
}
|
||||
|
||||
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));
|
||||
for (auto const & lolli : affected_lollis) {
|
||||
ArdourCanvas::Item* item = lolli->item;
|
||||
ArdourCanvas::Duple pos = item->item_to_canvas (ArdourCanvas::Duple (lolli->event->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);
|
||||
lolli->velocity_while_editing = y_position_to_velocity (r.height() - (r.y1() - y));
|
||||
set_size_and_position (*lolli);
|
||||
}
|
||||
|
||||
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 true;
|
||||
}
|
||||
|
||||
bool
|
||||
@ -189,7 +183,7 @@ VelocityGhostRegion::set_size_and_position (GhostEvent& ev)
|
||||
{
|
||||
ArdourCanvas::Lollipop* l = dynamic_cast<ArdourCanvas::Lollipop*> (ev.item);
|
||||
const double available_height = base_rect->y1();
|
||||
const double actual_height = (ev.event->note()->velocity() / 127.0) * available_height;
|
||||
const double actual_height = (ev.velocity_while_editing / 127.0) * available_height;
|
||||
l->set (ArdourCanvas::Duple (ev.event->x0(), base_rect->y1() - actual_height), actual_height, lollipop_radius);
|
||||
}
|
||||
|
||||
@ -327,7 +321,7 @@ VelocityGhostRegion::note_selected (NoteBase* ev)
|
||||
}
|
||||
|
||||
void
|
||||
VelocityGhostRegion::lollis_between (int x0, int x1, std::vector<NoteBase*>& within)
|
||||
VelocityGhostRegion::lollis_between (int x0, int x1, std::vector<GhostEvent*>& within)
|
||||
{
|
||||
MidiRegionView* mrv = dynamic_cast<MidiRegionView*> (&parent_rv);
|
||||
assert (mrv);
|
||||
@ -344,21 +338,21 @@ VelocityGhostRegion::lollis_between (int x0, int x1, std::vector<NoteBase*>& wit
|
||||
if (l) {
|
||||
ArdourCanvas::Duple pos = l->item_to_canvas (ArdourCanvas::Duple (l->x(), l->y0()));
|
||||
if (pos.x >= x0 && pos.x < x1) {
|
||||
within.push_back (gev.second->event);
|
||||
within.push_back (gev.second);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
VelocityGhostRegion::lollis_close_to_x (int x, double distance, std::vector<NoteBase*>& within)
|
||||
VelocityGhostRegion::lollis_close_to_x (int x, double distance, std::vector<GhostEvent*>& within)
|
||||
{
|
||||
for (auto & gev : events) {
|
||||
ArdourCanvas::Lollipop* l = dynamic_cast<ArdourCanvas::Lollipop*> (gev.second->item);
|
||||
if (l) {
|
||||
ArdourCanvas::Duple pos = l->item_to_canvas (ArdourCanvas::Duple (l->x(), l->y0()));
|
||||
if (std::abs (pos.x - x) < distance) {
|
||||
within.push_back (gev.second->event);
|
||||
within.push_back (gev.second);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -368,7 +362,14 @@ void
|
||||
VelocityGhostRegion::start_line_drag ()
|
||||
{
|
||||
MidiRegionView* mrv = dynamic_cast<MidiRegionView*> (&parent_rv);
|
||||
|
||||
mrv->begin_drag_edit (_("draw velocities"));
|
||||
|
||||
for (auto & e : events) {
|
||||
GhostEvent* gev (e.second);
|
||||
gev->velocity_while_editing = gev->event->note()->velocity();
|
||||
}
|
||||
|
||||
desensitize_lollis ();
|
||||
}
|
||||
|
||||
@ -376,7 +377,23 @@ void
|
||||
VelocityGhostRegion::end_line_drag (bool did_change)
|
||||
{
|
||||
MidiRegionView* mrv = dynamic_cast<MidiRegionView*> (&parent_rv);
|
||||
mrv->end_drag_edit (did_change);
|
||||
|
||||
if (did_change) {
|
||||
std::vector<NoteBase*> notes;
|
||||
std::vector<int> velocities;
|
||||
|
||||
for (auto & e : events) {
|
||||
GhostEvent* gev (e.second);
|
||||
if (gev->event->note()->velocity() != gev->velocity_while_editing) {
|
||||
notes.push_back (gev->event);
|
||||
velocities.push_back (gev->velocity_while_editing);
|
||||
}
|
||||
}
|
||||
|
||||
mrv->set_velocities_for_notes (notes, velocities);
|
||||
}
|
||||
|
||||
mrv->end_drag_edit ();
|
||||
sensitize_lollis ();
|
||||
}
|
||||
|
||||
|
@ -67,8 +67,8 @@ private:
|
||||
bool base_event (GdkEvent*);
|
||||
bool lollevent (GdkEvent*, MidiGhostRegion::GhostEvent*);
|
||||
void set_size_and_position (MidiGhostRegion::GhostEvent&);
|
||||
void lollis_close_to_x (int x, double distance, std::vector<NoteBase*>& events);
|
||||
void lollis_between (int x0, int x1, std::vector<NoteBase*>& events);
|
||||
void lollis_close_to_x (int x, double distance, std::vector<GhostEvent*>& events);
|
||||
void lollis_between (int x0, int x1, std::vector<GhostEvent*>& events);
|
||||
void desensitize_lollis ();
|
||||
void sensitize_lollis ();
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user