Only show Piano Roll when editable (#6295)

- Display a message when a user attempts to open the piano roll in a project with no MIDI clips instead of opening a non-functional piano roll.
- Create a MIDI clip in the first instrument track when the piano roll is opened in an empty project.
This commit is contained in:
Alex
2025-11-07 23:36:45 +01:00
committed by GitHub
parent 51529cefb1
commit c79d6af3ab
2 changed files with 77 additions and 0 deletions

View File

@@ -146,6 +146,7 @@ public:
return m_midiClip;
}
// TODO remove this since PianoRoll should no longer be visible without a valid midi clip
bool hasValidMidiClip() const
{
return m_midiClip != nullptr;
@@ -588,6 +589,8 @@ private slots:
private:
void clipRenamed();
void focusInEvent(QFocusEvent * event) override;
void showEvent(QShowEvent* se) override;
void stopStepRecording();
void updateStepRecordingIcon();

View File

@@ -5388,8 +5388,82 @@ bool PianoRollWindow::hasFocus() const
void PianoRollWindow::showEvent(QShowEvent*)
{
// PianoRoll can ONLY be shown if hasValidMidiClip is true
// TODO remove hasValidMidiClip checks throughout the code
if (m_editor->hasValidMidiClip()) { return; }
// A new user might try to open PianoRoll in an empty project unaware that they first need to create a clip.
// To make life easier for them we create and/or open the first clip in an empty project.
// If there are multiple non-empty clips, we tell the user to double click one of them instead.
InstrumentTrack* firstTrack = nullptr;
MidiClip* firstEmptyClip = nullptr;
MidiClip* firstMelodyClip = nullptr;
// Iterate through all instrument tracks in the Song
for (auto track: Engine::getSong()->tracks())
{
if (track->type() != Track::Type::Instrument) { continue; }
auto instrumentTrack = static_cast<InstrumentTrack*>(track);
if (!firstTrack) { firstTrack = instrumentTrack; }
// Iterate through all midi clips in each track
for (auto clip: instrumentTrack->getClips())
{
auto midiClip = static_cast<MidiClip*>(clip);
// Remember the first empty clip in the Song (ignore subsequent empty clips)
if (midiClip->notes().empty())
{
if (!firstEmptyClip) { firstEmptyClip = midiClip; }
}
// Remember the first non-empty clip in the Song
else if (!firstMelodyClip)
{
firstMelodyClip = midiClip;
}
// If there are multiple non-empty clips in the Song, show a hint
else
{
TextFloat::displayMessage(tr("No clip selected"),
tr("Double click a melody clip in the Song Editor to open it."),
embed::getIconPixmap("error"), 5000);
parentWidget()->hide();
return;
}
}
}
// If we found a clip, open it
if (firstMelodyClip || firstEmptyClip)
{
m_editor->setCurrentMidiClip(firstMelodyClip ? firstMelodyClip : firstEmptyClip);
}
// If we found a track with no clips, create a clip and open it
else if (firstTrack)
{
m_editor->setCurrentMidiClip(new MidiClip(firstTrack));
}
// If we found no instrument tracks, show a hint
else
{
TextFloat::displayMessage(tr("No instrument tracks"),
tr("Drag an instrument plugin or preset from the sidebar to the Song Editor."),
embed::getIconPixmap("error"), 5000);
parentWidget()->hide();
}
}
void PianoRollWindow::updateAfterMidiClipChange()
{
if (!m_editor->hasValidMidiClip())
{
parentWidget()->hide();
return;
}
clipRenamed();
updateStepRecordingIcon(); //MIDI clip change turn step recording OFF - update icon accordingly
}