From 2e595563482c0953e2212cc8ddcc65f5e7291030 Mon Sep 17 00:00:00 2001 From: regulus79 <117475203+regulus79@users.noreply.github.com> Date: Thu, 28 Nov 2024 11:40:34 -0500 Subject: [PATCH 1/3] Add midi reversing --- include/PianoRoll.h | 1 + src/gui/editors/PianoRoll.cpp | 30 ++++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/include/PianoRoll.h b/include/PianoRoll.h index a85e50a163b..1280bc44638 100644 --- a/include/PianoRoll.h +++ b/include/PianoRoll.h @@ -246,6 +246,7 @@ protected slots: void clearGhostClip(); void glueNotes(); void fitNoteLengths(bool fill); + void reverseNotes(); void constrainNoteLengths(bool constrainMax); void changeSnapMode(); diff --git a/src/gui/editors/PianoRoll.cpp b/src/gui/editors/PianoRoll.cpp index a2d7c832aaa..b01f595431c 100644 --- a/src/gui/editors/PianoRoll.cpp +++ b/src/gui/editors/PianoRoll.cpp @@ -788,6 +788,31 @@ void PianoRoll::constrainNoteLengths(bool constrainMax) Engine::getSong()->setModified(); } +void PianoRoll::reverseNotes() +{ + if (!hasValidMidiClip()) { return; } + m_midiClip->addJournalCheckPoint(); + + const NoteVector selectedNotes = getSelectedNotes(); + const auto& notes = selectedNotes.empty() ? m_midiClip->notes() : selectedNotes; + const auto firstNote = notes.front(); + const auto lastNote = notes.back(); + const TimePos firstPos = firstNote->pos(); + const TimePos lastPos = lastNote->endPos(); + + for (auto note : notes) + { + TimePos oldStart = note->pos(); + TimePos newEnd = lastPos - (oldStart - firstPos); + TimePos newStart = newEnd - note->length(); + note->setPos(newStart); + } + + update(); + getGUI()->songEditor()->update(); + Engine::getSong()->setModified(); +} + void PianoRoll::loadMarkedSemiTones(const QDomElement & de) { @@ -4869,12 +4894,17 @@ PianoRollWindow::PianoRollWindow() : auto maxLengthAction = new QAction(embed::getIconPixmap("max_length"), tr("Max length as last"), noteToolsButton); connect(maxLengthAction, &QAction::triggered, [this](){ m_editor->constrainNoteLengths(true); }); + auto reverseAction = new QAction(embed::getIconPixmap("back_to_start"), tr("Reverse Notes"), noteToolsButton); + connect(reverseAction, &QAction::triggered, [this](){ m_editor->reverseNotes(); }); + reverseAction->setShortcut(combine(Qt::SHIFT, Qt::Key_R)); + noteToolsButton->addAction(glueAction); noteToolsButton->addAction(knifeAction); noteToolsButton->addAction(fillAction); noteToolsButton->addAction(cutOverlapsAction); noteToolsButton->addAction(minLengthAction); noteToolsButton->addAction(maxLengthAction); + noteToolsButton->addAction(reverseAction); notesActionsToolBar->addWidget(noteToolsButton); From 42838f6d833120c58edd51dbc45bcdc911d829ef Mon Sep 17 00:00:00 2001 From: regulus79 <117475203+regulus79@users.noreply.github.com> Date: Thu, 28 Nov 2024 11:57:01 -0500 Subject: [PATCH 2/3] Fix bugs --- src/gui/editors/PianoRoll.cpp | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/gui/editors/PianoRoll.cpp b/src/gui/editors/PianoRoll.cpp index b01f595431c..5941c9d0580 100644 --- a/src/gui/editors/PianoRoll.cpp +++ b/src/gui/editors/PianoRoll.cpp @@ -795,10 +795,15 @@ void PianoRoll::reverseNotes() const NoteVector selectedNotes = getSelectedNotes(); const auto& notes = selectedNotes.empty() ? m_midiClip->notes() : selectedNotes; - const auto firstNote = notes.front(); - const auto lastNote = notes.back(); - const TimePos firstPos = firstNote->pos(); - const TimePos lastPos = lastNote->endPos(); + + TimePos firstPos = notes.front()->pos(); + TimePos lastPos = notes.back()->endPos(); + // Find the actual min/max positions + for (auto note : notes) + { + if (note->pos() < firstPos) { firstPos = note->pos(); } + if (note->endPos() > lastPos) { lastPos = note->endPos(); } + } for (auto note : notes) { @@ -807,6 +812,9 @@ void PianoRoll::reverseNotes() TimePos newStart = newEnd - note->length(); note->setPos(newStart); } + + m_midiClip->rearrangeAllNotes(); + m_midiClip->dataChanged(); update(); getGUI()->songEditor()->update(); From 276643b5103e2d3d8596f4686d3b3640f66e0f80 Mon Sep 17 00:00:00 2001 From: regulus79 <117475203+regulus79@users.noreply.github.com> Date: Thu, 28 Nov 2024 14:18:39 -0500 Subject: [PATCH 3/3] Put calculation of new pos on single line Co-authored-by: szeli1 <143485814+szeli1@users.noreply.github.com> --- src/gui/editors/PianoRoll.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/gui/editors/PianoRoll.cpp b/src/gui/editors/PianoRoll.cpp index 5941c9d0580..da2c8b89093 100644 --- a/src/gui/editors/PianoRoll.cpp +++ b/src/gui/editors/PianoRoll.cpp @@ -808,8 +808,7 @@ void PianoRoll::reverseNotes() for (auto note : notes) { TimePos oldStart = note->pos(); - TimePos newEnd = lastPos - (oldStart - firstPos); - TimePos newStart = newEnd - note->length(); + TimePos newStart = lastPos - (oldStart - firstPos) - note->length(); note->setPos(newStart); }