mirror of
https://github.com/LMMS/lmms.git
synced 2026-05-18 19:55:00 -04:00
4 new note modification tools (#5857)
* Add new note length modification tools * "Last" instead of "latest" * Code formatting Co-authored-by: IanCaio <iancaio_dev@hotmail.com> * Fix sort * Fix incorrect cut of last note * Fix Fill not stretching last note to end * Fill from end positions * Rename limitNoteLengths * Compare with non-selected notes when filling * Style changes by IanCaio + bugfix * break instead of continue Co-authored-by: IanCaio <iancaio_dev@hotmail.com>
This commit is contained in:
BIN
data/themes/default/cut_overlaps.png
Normal file
BIN
data/themes/default/cut_overlaps.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 7.1 KiB |
BIN
data/themes/default/fill.png
Normal file
BIN
data/themes/default/fill.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 405 B |
BIN
data/themes/default/max_length.png
Normal file
BIN
data/themes/default/max_length.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 192 B |
BIN
data/themes/default/min_length.png
Normal file
BIN
data/themes/default/min_length.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 193 B |
@@ -211,6 +211,8 @@ protected slots:
|
||||
|
||||
void clearGhostPattern();
|
||||
void glueNotes();
|
||||
void fitNoteLengths(bool fill);
|
||||
void constrainNoteLengths(bool constrainMax);
|
||||
|
||||
|
||||
signals:
|
||||
|
||||
@@ -718,6 +718,86 @@ void PianoRoll::glueNotes()
|
||||
}
|
||||
}
|
||||
|
||||
void PianoRoll::fitNoteLengths(bool fill)
|
||||
{
|
||||
if (!hasValidPattern()) { return; }
|
||||
m_pattern->addJournalCheckPoint();
|
||||
|
||||
// Reference notes
|
||||
NoteVector refNotes = m_pattern->notes();
|
||||
std::sort(refNotes.begin(), refNotes.end(), Note::lessThan);
|
||||
|
||||
// Notes to edit
|
||||
NoteVector notes = getSelectedNotes();
|
||||
if (notes.empty())
|
||||
{
|
||||
notes = refNotes;
|
||||
}
|
||||
else if (!fill)
|
||||
{
|
||||
std::sort(notes.begin(), notes.end(), Note::lessThan);
|
||||
}
|
||||
if (fill)
|
||||
{
|
||||
std::sort(notes.begin(), notes.end(), [](Note* n1, Note* n2) { return n1->endPos() < n2->endPos(); });
|
||||
}
|
||||
|
||||
int length;
|
||||
NoteVector::iterator ref = refNotes.begin();
|
||||
for (Note* note : notes)
|
||||
{
|
||||
// Fast forward to next reference note
|
||||
while (ref != refNotes.end() && (fill ? (*ref)->pos() < note->endPos() : (*ref)->pos() <= note->pos()))
|
||||
{
|
||||
ref++;
|
||||
}
|
||||
if (ref == refNotes.end())
|
||||
{
|
||||
if (!fill) { break; }
|
||||
// Last notes stretch to end of last bar
|
||||
length = notes.last()->endPos().nextFullBar() * TimePos::ticksPerBar() - note->pos();
|
||||
}
|
||||
else
|
||||
{
|
||||
length = (*ref)->pos() - note->pos();
|
||||
}
|
||||
if (fill ? note->length() < length : note->length() > length)
|
||||
{
|
||||
note->setLength(length);
|
||||
}
|
||||
}
|
||||
|
||||
update();
|
||||
gui->songEditor()->update();
|
||||
Engine::getSong()->setModified();
|
||||
}
|
||||
|
||||
|
||||
void PianoRoll::constrainNoteLengths(bool constrainMax)
|
||||
{
|
||||
if (!hasValidPattern()) { return; }
|
||||
m_pattern->addJournalCheckPoint();
|
||||
|
||||
NoteVector notes = getSelectedNotes();
|
||||
if (notes.empty())
|
||||
{
|
||||
notes = m_pattern->notes();
|
||||
}
|
||||
|
||||
TimePos bound = m_lenOfNewNotes; // will be length of last note
|
||||
for (Note* note : notes)
|
||||
{
|
||||
if (constrainMax ? note->length() > bound : note->length() < bound)
|
||||
{
|
||||
note->setLength(bound);
|
||||
}
|
||||
}
|
||||
|
||||
update();
|
||||
gui->songEditor()->update();
|
||||
Engine::getSong()->setModified();
|
||||
}
|
||||
|
||||
|
||||
void PianoRoll::loadMarkedSemiTones(const QDomElement & de)
|
||||
{
|
||||
@@ -4603,25 +4683,40 @@ PianoRollWindow::PianoRollWindow() :
|
||||
m_editor->m_timeLine->addToolButtons( timeLineToolBar );
|
||||
|
||||
// -- Note modifier tools
|
||||
// Toolbar
|
||||
QToolButton * noteToolsButton = new QToolButton(m_toolBar);
|
||||
noteToolsButton->setIcon(embed::getIconPixmap("tool"));
|
||||
noteToolsButton->setPopupMode(QToolButton::InstantPopup);
|
||||
|
||||
// Glue
|
||||
QAction * glueAction = new QAction(embed::getIconPixmap("glue"),
|
||||
tr("Glue"), noteToolsButton);
|
||||
connect(glueAction, SIGNAL(triggered()), m_editor, SLOT(glueNotes()));
|
||||
glueAction->setShortcut( Qt::SHIFT | Qt::Key_G );
|
||||
|
||||
// Knife
|
||||
QAction * knifeAction = new QAction(embed::getIconPixmap("edit_knife"),
|
||||
tr("Knife"), noteToolsButton);
|
||||
connect(knifeAction, &QAction::triggered, m_editor, &PianoRoll::setKnifeAction);
|
||||
knifeAction->setShortcut( Qt::SHIFT | Qt::Key_K );
|
||||
|
||||
QAction* fillAction = new QAction(embed::getIconPixmap("fill"), tr("Fill"), noteToolsButton);
|
||||
connect(fillAction, &QAction::triggered, [this](){ m_editor->fitNoteLengths(true); });
|
||||
fillAction->setShortcut(Qt::SHIFT | Qt::Key_F);
|
||||
|
||||
QAction* cutOverlapsAction = new QAction(embed::getIconPixmap("cut_overlaps"), tr("Cut overlaps"), noteToolsButton);
|
||||
connect(cutOverlapsAction, &QAction::triggered, [this](){ m_editor->fitNoteLengths(false); });
|
||||
cutOverlapsAction->setShortcut(Qt::SHIFT | Qt::Key_C);
|
||||
|
||||
QAction* minLengthAction = new QAction(embed::getIconPixmap("min_length"), tr("Min length as last"), noteToolsButton);
|
||||
connect(minLengthAction, &QAction::triggered, [this](){ m_editor->constrainNoteLengths(false); });
|
||||
|
||||
QAction* maxLengthAction = new QAction(embed::getIconPixmap("max_length"), tr("Max length as last"), noteToolsButton);
|
||||
connect(maxLengthAction, &QAction::triggered, [this](){ m_editor->constrainNoteLengths(true); });
|
||||
|
||||
noteToolsButton->addAction(glueAction);
|
||||
noteToolsButton->addAction(knifeAction);
|
||||
noteToolsButton->addAction(fillAction);
|
||||
noteToolsButton->addAction(cutOverlapsAction);
|
||||
noteToolsButton->addAction(minLengthAction);
|
||||
noteToolsButton->addAction(maxLengthAction);
|
||||
|
||||
notesActionsToolBar->addWidget(noteToolsButton);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user