mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-07 07:14:56 +01:00
lollis: make a single drag be represented by a single Command object (for undo/redo)
This commit is contained in:
parent
006779d4c3
commit
60256282e3
4 changed files with 64 additions and 10 deletions
|
|
@ -3384,15 +3384,62 @@ MidiRegionView::change_note_length (NoteBase* event, Temporal::Beats t)
|
||||||
{
|
{
|
||||||
note_diff_add_change (event, MidiModel::NoteDiffCommand::Length, t);
|
note_diff_add_change (event, MidiModel::NoteDiffCommand::Length, t);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
MidiRegionView::begin_drag_edit (std::string const & why)
|
||||||
|
{
|
||||||
|
start_note_diff_command (why);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MidiRegionView::drag_apply ()
|
||||||
|
{
|
||||||
|
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_velocity_for_notes (std::vector<NoteBase*> notes, int velocity)
|
MidiRegionView::set_velocity_for_notes (std::vector<NoteBase*> notes, int velocity)
|
||||||
{
|
{
|
||||||
/* Does not use selection, used when drawing/dragging in velocity lane */
|
/* Does not use selection, used when drawing/dragging in velocity lane */
|
||||||
|
|
||||||
bool changed = false;
|
bool changed = false;
|
||||||
|
|
||||||
start_note_diff_command (_("set velocities"));
|
|
||||||
|
|
||||||
for (auto & note : notes) {
|
for (auto & note : notes) {
|
||||||
|
|
||||||
int delta = velocity - note->note()->velocity();
|
int delta = velocity - note->note()->velocity();
|
||||||
|
|
@ -3405,11 +3452,7 @@ MidiRegionView::set_velocity_for_notes (std::vector<NoteBase*> notes, int veloci
|
||||||
change_note_velocity (note, delta, true);
|
change_note_velocity (note, delta, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (changed) {
|
return changed;
|
||||||
apply_note_diff ();
|
|
||||||
} else {
|
|
||||||
abort_note_diff ();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
||||||
|
|
@ -180,6 +180,10 @@ public:
|
||||||
void end_write();
|
void end_write();
|
||||||
void extend_active_notes();
|
void extend_active_notes();
|
||||||
|
|
||||||
|
void begin_drag_edit (std::string const & why);
|
||||||
|
void mid_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);
|
||||||
|
|
||||||
/* note_diff commands should start here; this initiates an undo record */
|
/* note_diff commands should start here; this initiates an undo record */
|
||||||
|
|
@ -288,7 +292,7 @@ public:
|
||||||
void change_note_lengths (bool, bool, Temporal::Beats beats, bool start, bool end);
|
void change_note_lengths (bool, bool, Temporal::Beats beats, bool start, bool end);
|
||||||
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);
|
||||||
void set_velocity_for_notes (std::vector<NoteBase*> notes, int velocity);
|
bool set_velocity_for_notes (std::vector<NoteBase*> notes, int velocity);
|
||||||
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 ();
|
||||||
|
|
@ -583,6 +587,7 @@ public:
|
||||||
void model_changed ();
|
void model_changed ();
|
||||||
|
|
||||||
void sync_ghost_selection (NoteBase*);
|
void sync_ghost_selection (NoteBase*);
|
||||||
|
void drag_apply ();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -55,6 +55,7 @@ VelocityGhostRegion::VelocityGhostRegion (MidiRegionView& mrv, TimeAxisView& tv,
|
||||||
, dragging (false)
|
, dragging (false)
|
||||||
, dragging_line (nullptr)
|
, dragging_line (nullptr)
|
||||||
, last_drag_x (-1)
|
, last_drag_x (-1)
|
||||||
|
, drag_did_change (false)
|
||||||
{
|
{
|
||||||
base_rect->Event.connect (sigc::mem_fun (*this, &VelocityGhostRegion::base_event));
|
base_rect->Event.connect (sigc::mem_fun (*this, &VelocityGhostRegion::base_event));
|
||||||
}
|
}
|
||||||
|
|
@ -85,7 +86,8 @@ VelocityGhostRegion::base_event (GdkEvent* ev)
|
||||||
}
|
}
|
||||||
if (!affected_lollis.empty()) {
|
if (!affected_lollis.empty()) {
|
||||||
int velocity = y_position_to_velocity (r.height() - (r.y1 - ev->motion.y));
|
int velocity = y_position_to_velocity (r.height() - (r.y1 - ev->motion.y));
|
||||||
mrv->set_velocity_for_notes (affected_lollis, velocity);
|
drag_did_change |= mrv->set_velocity_for_notes (affected_lollis, velocity);
|
||||||
|
mrv->mid_drag_edit ();
|
||||||
}
|
}
|
||||||
if (dragging) {
|
if (dragging) {
|
||||||
dragging_line->add_point (ArdourCanvas::Duple (ev->motion.x - r.x0, ev->motion.y - r.y0));
|
dragging_line->add_point (ArdourCanvas::Duple (ev->motion.x - r.x0, ev->motion.y - r.y0));
|
||||||
|
|
@ -97,6 +99,7 @@ VelocityGhostRegion::base_event (GdkEvent* ev)
|
||||||
if (ev->button.button == 1) {
|
if (ev->button.button == 1) {
|
||||||
desensitize_lollis ();
|
desensitize_lollis ();
|
||||||
dragging = true;
|
dragging = true;
|
||||||
|
drag_did_change = false;
|
||||||
last_drag_x = -1;
|
last_drag_x = -1;
|
||||||
if (!dragging_line) {
|
if (!dragging_line) {
|
||||||
dragging_line = new ArdourCanvas::PolyLine (_note_group);
|
dragging_line = new ArdourCanvas::PolyLine (_note_group);
|
||||||
|
|
@ -107,10 +110,12 @@ VelocityGhostRegion::base_event (GdkEvent* ev)
|
||||||
dragging_line->show();
|
dragging_line->show();
|
||||||
dragging_line->raise_to_top();
|
dragging_line->raise_to_top();
|
||||||
base_rect->grab();
|
base_rect->grab();
|
||||||
|
mrv->begin_drag_edit (_("draw velocities"));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GDK_BUTTON_RELEASE:
|
case GDK_BUTTON_RELEASE:
|
||||||
if (ev->button.button == 1) {
|
if (ev->button.button == 1) {
|
||||||
|
mrv->end_drag_edit (drag_did_change);
|
||||||
base_rect->ungrab();
|
base_rect->ungrab();
|
||||||
dragging_line->hide ();
|
dragging_line->hide ();
|
||||||
dragging = false;
|
dragging = false;
|
||||||
|
|
|
||||||
|
|
@ -51,6 +51,7 @@ private:
|
||||||
bool dragging;
|
bool dragging;
|
||||||
ArdourCanvas::PolyLine* dragging_line;
|
ArdourCanvas::PolyLine* dragging_line;
|
||||||
int last_drag_x;
|
int last_drag_x;
|
||||||
|
bool drag_did_change;
|
||||||
|
|
||||||
bool base_event (GdkEvent*);
|
bool base_event (GdkEvent*);
|
||||||
bool lollevent (GdkEvent*, MidiGhostRegion::GhostEvent*);
|
bool lollevent (GdkEvent*, MidiGhostRegion::GhostEvent*);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue