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;
|
double y = ev->motion.y - r.y0;
|
||||||
|
|
||||||
if (drawn_points.empty()) {
|
if (drawn_points.empty()) {
|
||||||
line_start_x = x;
|
line_start_x = pointer_x;
|
||||||
line_start_y = y;
|
line_start_y = y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -215,6 +215,7 @@ MidiGhostRegion::GhostEvent::GhostEvent (NoteBase* e, ArdourCanvas::Container* g
|
|||||||
, item (i)
|
, item (i)
|
||||||
, is_hit (false)
|
, is_hit (false)
|
||||||
{
|
{
|
||||||
|
velocity_while_editing = event->note()->velocity();
|
||||||
}
|
}
|
||||||
|
|
||||||
MidiGhostRegion::GhostEvent::GhostEvent (NoteBase* e, ArdourCanvas::Container* g)
|
MidiGhostRegion::GhostEvent::GhostEvent (NoteBase* e, ArdourCanvas::Container* g)
|
||||||
@ -235,6 +236,8 @@ MidiGhostRegion::GhostEvent::GhostEvent (NoteBase* e, ArdourCanvas::Container* g
|
|||||||
is_hit = true;
|
is_hit = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
velocity_while_editing = event->note()->velocity();
|
||||||
|
|
||||||
CANVAS_DEBUG_NAME (item, "ghost note item");
|
CANVAS_DEBUG_NAME (item, "ghost note item");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,6 +108,7 @@ public:
|
|||||||
NoteBase* event;
|
NoteBase* event;
|
||||||
ArdourCanvas::Item* item;
|
ArdourCanvas::Item* item;
|
||||||
bool is_hit;
|
bool is_hit;
|
||||||
|
int velocity_while_editing;
|
||||||
};
|
};
|
||||||
|
|
||||||
MidiGhostRegion(MidiRegionView& rv,
|
MidiGhostRegion(MidiRegionView& rv,
|
||||||
|
@ -3402,54 +3402,18 @@ MidiRegionView::begin_drag_edit (std::string const & why)
|
|||||||
if (!_selected) {
|
if (!_selected) {
|
||||||
trackview.editor().get_selection().set (this, true);
|
trackview.editor().get_selection().set (this, true);
|
||||||
}
|
}
|
||||||
start_note_diff_command (why);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
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
|
bool
|
||||||
MidiRegionView::set_velocities_for_notes (std::vector<NoteBase*> notes, std::vector<int> velocities)
|
MidiRegionView::set_velocities_for_notes (std::vector<NoteBase*> notes, std::vector<int> velocities)
|
||||||
{
|
{
|
||||||
|
start_note_diff_command (_("draw velocities"));
|
||||||
|
|
||||||
assert (notes.size() == velocities.size());
|
assert (notes.size() == velocities.size());
|
||||||
|
|
||||||
/* Does not use selection, used when drawing/dragging in velocity lane */
|
/* 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;
|
++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;
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -181,8 +181,7 @@ public:
|
|||||||
void extend_active_notes();
|
void extend_active_notes();
|
||||||
|
|
||||||
void begin_drag_edit (std::string const & why);
|
void begin_drag_edit (std::string const & why);
|
||||||
void mid_drag_edit ();
|
void end_drag_edit ();
|
||||||
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; }
|
std::shared_ptr<ARDOUR::MidiModel> model() const { return _model; }
|
||||||
@ -591,7 +590,6 @@ public:
|
|||||||
void model_changed ();
|
void model_changed ();
|
||||||
|
|
||||||
void sync_ghost_selection (NoteBase*);
|
void sync_ghost_selection (NoteBase*);
|
||||||
void drag_apply ();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -73,8 +73,7 @@ VelocityGhostRegion::~VelocityGhostRegion ()
|
|||||||
bool
|
bool
|
||||||
VelocityGhostRegion::line_draw_motion (ArdourCanvas::Duple const & d, ArdourCanvas::Rectangle const & r, double last_x)
|
VelocityGhostRegion::line_draw_motion (ArdourCanvas::Duple const & d, ArdourCanvas::Rectangle const & r, double last_x)
|
||||||
{
|
{
|
||||||
std::vector<NoteBase*> affected_lollis;
|
std::vector<GhostEvent*> affected_lollis;
|
||||||
MidiRegionView* mrv = dynamic_cast<MidiRegionView*> (&parent_rv);
|
|
||||||
|
|
||||||
if (last_x < 0) {
|
if (last_x < 0) {
|
||||||
lollis_close_to_x (d.x, 20., affected_lollis);
|
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));
|
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
|
bool
|
||||||
VelocityGhostRegion::line_extended (ArdourCanvas::Duple const & from, ArdourCanvas::Duple const & to, ArdourCanvas::Rectangle const & r, double last_x)
|
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);
|
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);
|
double slope = (to.y - from.y) / (to.x - from.x);
|
||||||
std::vector<int> velocities;
|
|
||||||
|
|
||||||
for (auto const & nb : affected_lollis) {
|
for (auto const & lolli : affected_lollis) {
|
||||||
ArdourCanvas::Item* it = nb->item();
|
ArdourCanvas::Item* item = lolli->item;
|
||||||
ArdourCanvas::Duple pos = it->item_to_canvas (ArdourCanvas::Duple (nb->x0(), 0.0));
|
ArdourCanvas::Duple pos = item->item_to_canvas (ArdourCanvas::Duple (lolli->event->x0(), 0.0));
|
||||||
int y = from.y + (slope * (pos.x - from.x));
|
int y = from.y + (slope * (pos.x - from.x));
|
||||||
int velocity = y_position_to_velocity (r.height() - (r.y1() - y));
|
lolli->velocity_while_editing = y_position_to_velocity (r.height() - (r.y1() - y));
|
||||||
velocities.push_back (velocity);
|
set_size_and_position (*lolli);
|
||||||
}
|
}
|
||||||
|
|
||||||
MidiRegionView* mrv = dynamic_cast<MidiRegionView*> (&parent_rv);
|
return true;
|
||||||
bool ret = mrv->set_velocities_for_notes (affected_lollis, velocities);
|
|
||||||
|
|
||||||
mrv->mid_drag_edit ();
|
|
||||||
|
|
||||||
model_changed ();
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@ -189,7 +183,7 @@ VelocityGhostRegion::set_size_and_position (GhostEvent& ev)
|
|||||||
{
|
{
|
||||||
ArdourCanvas::Lollipop* l = dynamic_cast<ArdourCanvas::Lollipop*> (ev.item);
|
ArdourCanvas::Lollipop* l = dynamic_cast<ArdourCanvas::Lollipop*> (ev.item);
|
||||||
const double available_height = base_rect->y1();
|
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);
|
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
|
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);
|
MidiRegionView* mrv = dynamic_cast<MidiRegionView*> (&parent_rv);
|
||||||
assert (mrv);
|
assert (mrv);
|
||||||
@ -344,21 +338,21 @@ VelocityGhostRegion::lollis_between (int x0, int x1, std::vector<NoteBase*>& wit
|
|||||||
if (l) {
|
if (l) {
|
||||||
ArdourCanvas::Duple pos = l->item_to_canvas (ArdourCanvas::Duple (l->x(), l->y0()));
|
ArdourCanvas::Duple pos = l->item_to_canvas (ArdourCanvas::Duple (l->x(), l->y0()));
|
||||||
if (pos.x >= x0 && pos.x < x1) {
|
if (pos.x >= x0 && pos.x < x1) {
|
||||||
within.push_back (gev.second->event);
|
within.push_back (gev.second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
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) {
|
for (auto & gev : events) {
|
||||||
ArdourCanvas::Lollipop* l = dynamic_cast<ArdourCanvas::Lollipop*> (gev.second->item);
|
ArdourCanvas::Lollipop* l = dynamic_cast<ArdourCanvas::Lollipop*> (gev.second->item);
|
||||||
if (l) {
|
if (l) {
|
||||||
ArdourCanvas::Duple pos = l->item_to_canvas (ArdourCanvas::Duple (l->x(), l->y0()));
|
ArdourCanvas::Duple pos = l->item_to_canvas (ArdourCanvas::Duple (l->x(), l->y0()));
|
||||||
if (std::abs (pos.x - x) < distance) {
|
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 ()
|
VelocityGhostRegion::start_line_drag ()
|
||||||
{
|
{
|
||||||
MidiRegionView* mrv = dynamic_cast<MidiRegionView*> (&parent_rv);
|
MidiRegionView* mrv = dynamic_cast<MidiRegionView*> (&parent_rv);
|
||||||
|
|
||||||
mrv->begin_drag_edit (_("draw velocities"));
|
mrv->begin_drag_edit (_("draw velocities"));
|
||||||
|
|
||||||
|
for (auto & e : events) {
|
||||||
|
GhostEvent* gev (e.second);
|
||||||
|
gev->velocity_while_editing = gev->event->note()->velocity();
|
||||||
|
}
|
||||||
|
|
||||||
desensitize_lollis ();
|
desensitize_lollis ();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -376,7 +377,23 @@ void
|
|||||||
VelocityGhostRegion::end_line_drag (bool did_change)
|
VelocityGhostRegion::end_line_drag (bool did_change)
|
||||||
{
|
{
|
||||||
MidiRegionView* mrv = dynamic_cast<MidiRegionView*> (&parent_rv);
|
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 ();
|
sensitize_lollis ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,8 +67,8 @@ private:
|
|||||||
bool base_event (GdkEvent*);
|
bool base_event (GdkEvent*);
|
||||||
bool lollevent (GdkEvent*, MidiGhostRegion::GhostEvent*);
|
bool lollevent (GdkEvent*, MidiGhostRegion::GhostEvent*);
|
||||||
void set_size_and_position (MidiGhostRegion::GhostEvent&);
|
void set_size_and_position (MidiGhostRegion::GhostEvent&);
|
||||||
void lollis_close_to_x (int x, double distance, 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<NoteBase*>& events);
|
void lollis_between (int x0, int x1, std::vector<GhostEvent*>& events);
|
||||||
void desensitize_lollis ();
|
void desensitize_lollis ();
|
||||||
void sensitize_lollis ();
|
void sensitize_lollis ();
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user