Skip to content

Commit

Permalink
Initial Implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
regulus79 committed Feb 17, 2025
1 parent d145f78 commit a4b4cf1
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 0 deletions.
1 change: 1 addition & 0 deletions include/PianoRoll.h
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,7 @@ protected slots:
void clearGhostClip();
void glueNotes();
void fitNoteLengths(bool fill);
void invertSelection(bool up);
void constrainNoteLengths(bool constrainMax);

void changeSnapMode();
Expand Down
46 changes: 46 additions & 0 deletions src/gui/editors/PianoRoll.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -765,6 +765,42 @@ void PianoRoll::fitNoteLengths(bool fill)
Engine::getSong()->setModified();
}

void PianoRoll::invertSelection(bool up)
{
if (!hasValidMidiClip()) { return; }
m_midiClip->addJournalCheckPoint();

// Notes to edit
const NoteVector selectedNotes = getSelectedNotes();
const auto& notes = selectedNotes.empty() ? m_midiClip->notes() : selectedNotes;

const auto [minNote, maxNote] = std::minmax_element(notes.begin(), notes.end(), [](Note* n1, Note* n2) { return n1->key() < n2->key(); });
const int minKey = (*minNote)->key();
const int maxKey = (*maxNote)->key();

const auto microtuner = m_midiClip->instrumentTrack()->microtuner();
const int octaveSize = microtuner->enabled() ? microtuner->octaveSize() : 12;
const int numOctaves = (maxKey - minKey) / octaveSize + 1;

for (Note* note : notes)
{
if (up)
{
if (note->key() == minKey)
{
note->setKey(minKey + numOctaves * octaveSize);
}
}
else
{
if (note->key() == maxKey)
{
note->setKey(maxKey - numOctaves * octaveSize);
}
}
}
}


void PianoRoll::constrainNoteLengths(bool constrainMax)
{
Expand Down Expand Up @@ -4869,12 +4905,22 @@ 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 upwardInversionAction = new QAction(embed::getIconPixmap("flip_y"), tr("Upward Inversion"), noteToolsButton);
connect(upwardInversionAction, &QAction::triggered, [this](){ m_editor->invertSelection(true); });
upwardInversionAction->setShortcut(combine(Qt::SHIFT, Qt::Key_I));

auto downwardInversionAction = new QAction(embed::getIconPixmap("flip_y"), tr("Downward Inversion"), noteToolsButton);
connect(downwardInversionAction, &QAction::triggered, [this](){ m_editor->invertSelection(false); });
downwardInversionAction->setShortcut(combine(Qt::SHIFT, Qt::Key_U));

noteToolsButton->addAction(glueAction);
noteToolsButton->addAction(knifeAction);
noteToolsButton->addAction(fillAction);
noteToolsButton->addAction(cutOverlapsAction);
noteToolsButton->addAction(minLengthAction);
noteToolsButton->addAction(maxLengthAction);
noteToolsButton->addAction(upwardInversionAction);
noteToolsButton->addAction(downwardInversionAction);

notesActionsToolBar->addWidget(noteToolsButton);

Expand Down

0 comments on commit a4b4cf1

Please sign in to comment.