From 0ffcfe3bff21e28ca2d41344826f98c55e26be92 Mon Sep 17 00:00:00 2001 From: Alex Date: Sun, 14 Dec 2025 14:40:35 +0100 Subject: [PATCH] Allow PianoRoll to open empty again, but with a help icon (#8148) Fixes #8152 Revert PianoRoll closing when empty (caused issues with detached windows) Remove TextFloat warning when there are no instruments/multiple clips (showed up when reloading project) (Keep clip creation for empty projects) Add an icon and updated message in empty PianoRoll. Mark PianoRollWindow invalid when there is no clip, making buttons impossible to click --------- Co-authored-by: Fawn --- data/themes/classic/pr_no_clip.svg | 31 +++++++++++++++++ data/themes/default/pr_no_clip.svg | 20 +++++++++++ include/PianoRoll.h | 1 - src/gui/MainWindow.cpp | 7 ++-- src/gui/editors/PianoRoll.cpp | 56 +++++++++++------------------- 5 files changed, 77 insertions(+), 38 deletions(-) create mode 100644 data/themes/classic/pr_no_clip.svg create mode 100644 data/themes/default/pr_no_clip.svg diff --git a/data/themes/classic/pr_no_clip.svg b/data/themes/classic/pr_no_clip.svg new file mode 100644 index 000000000..a1c992f8c --- /dev/null +++ b/data/themes/classic/pr_no_clip.svg @@ -0,0 +1,31 @@ + + + + + + Graphic for piano roll without clip + allejok96 + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data/themes/default/pr_no_clip.svg b/data/themes/default/pr_no_clip.svg new file mode 100644 index 000000000..b30ed99c2 --- /dev/null +++ b/data/themes/default/pr_no_clip.svg @@ -0,0 +1,20 @@ + + + + + + Graphic for piano roll without clip + allejok96 + + + + + + + + + + + + + diff --git a/include/PianoRoll.h b/include/PianoRoll.h index 5548d73ec..b92b65234 100644 --- a/include/PianoRoll.h +++ b/include/PianoRoll.h @@ -146,7 +146,6 @@ 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; diff --git a/src/gui/MainWindow.cpp b/src/gui/MainWindow.cpp index 27cd91a70..69360111c 100644 --- a/src/gui/MainWindow.cpp +++ b/src/gui/MainWindow.cpp @@ -919,7 +919,9 @@ void MainWindow::help() void MainWindow::toggleWindow( QWidget *window, bool forceShow ) { - QWidget *parent = window->parentWidget(); + // All "windows" should be inside a SubWindow, because the use of activeSubWindow() depends on it + auto parent = dynamic_cast(window->parentWidget()); + if (parent == nullptr) { return; } if( forceShow || m_workspace->activeSubWindow() != parent || @@ -927,7 +929,8 @@ void MainWindow::toggleWindow( QWidget *window, bool forceShow ) { parent->show(); window->show(); - window->setFocus(); + if (window->isEnabled()) { window->setFocus(); } + else { m_workspace->setActiveSubWindow(parent); } } else { diff --git a/src/gui/editors/PianoRoll.cpp b/src/gui/editors/PianoRoll.cpp index 917d2550a..149bbc36a 100644 --- a/src/gui/editors/PianoRoll.cpp +++ b/src/gui/editors/PianoRoll.cpp @@ -3141,6 +3141,20 @@ void PianoRoll::paintEvent(QPaintEvent * pe ) // fill with bg color p.fillRect( 0, 0, width(), height(), bgColor ); + if (!hasValidMidiClip()) + { + const auto icon = embed::getIconPixmap("pr_no_clip"); + const int x = (width() - icon.width()) / 2; + const int y = (height() - icon.height()) / 2; + p.drawPixmap(x, y, icon); + + p.setPen(QApplication::palette().color(QPalette::Active, QPalette::Text)); + QRect textRect(0, y + icon.height() + 5, width(), 30); + p.drawText(textRect, Qt::AlignHCenter | Qt::AlignTop, + tr("Double-click on an instrument clip in Song Editor to open it here")); + return; + } + // set font-size to 80% of key line height QFont f = p.font(); int keyFontSize = m_keyLineHeight * 0.8; @@ -3725,17 +3739,6 @@ void PianoRoll::paintEvent(QPaintEvent * pe ) p.drawPoints( editHandles ); } - else - { - QFont f = font(); - f.setBold(true); - p.setFont(f); - p.setPen( QApplication::palette().color( QPalette::Active, - QPalette::BrightText ) ); - p.drawText(m_whiteKeyWidth + 20, PR_TOP_MARGIN + 40, - tr( "Please open a clip by double-clicking " - "on it!" ) ); - } p.setClipRect( m_whiteKeyWidth, @@ -4666,7 +4669,7 @@ void PianoRoll::updatePosition(const TimePos & t) // > width = outside viewport right const int pos = (static_cast(m_timeLine->pos()) - m_currentPosition) * m_ppb / TimePos::ticksPerBar(); // if pos is within visible range, show it - if (pos >= 0 && pos <= width() - m_whiteKeyWidth) + if (hasValidMidiClip() && pos >= 0 && pos <= width() - m_whiteKeyWidth) { m_positionLine->show(); // adjust pos for piano keys width and self line width (align to rightmost of line) @@ -5406,13 +5409,11 @@ 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. + + // Has a clip already, do nothing + if (m_editor->hasValidMidiClip()) { return; } InstrumentTrack* firstTrack = nullptr; MidiClip* firstEmptyClip = nullptr; @@ -5440,13 +5441,9 @@ void PianoRollWindow::showEvent(QShowEvent*) { firstMelodyClip = midiClip; } - // If there are multiple non-empty clips in the Song, show a hint + // If there are multiple clips with notes, do nothing 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; } } @@ -5461,24 +5458,13 @@ void PianoRollWindow::showEvent(QShowEvent*) { 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; - } + setEnabled(m_editor->hasValidMidiClip()); + m_editor->m_timeLine->setVisible(m_editor->hasValidMidiClip()); clipRenamed(); updateStepRecordingIcon(); //MIDI clip change turn step recording OFF - update icon accordingly