From 9a1eaac8ec1c81e60f639b2d1f9f9da3708495b7 Mon Sep 17 00:00:00 2001 From: Michael Gregorius Date: Fri, 20 Sep 2024 22:17:40 +0200 Subject: [PATCH 01/11] Maximize button for resizable instruments Show the maximize button for resizable instruments. Most other changes have the character of refactorings and code reorganizations. Remove the negation in the if condition for resizable instruments to make the code better readable. Only manipulate the system menu if the instrument is not resizable. Add a TODO to the special code that sets a size. --- src/gui/instrument/InstrumentTrackWindow.cpp | 34 ++++++++++++-------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/src/gui/instrument/InstrumentTrackWindow.cpp b/src/gui/instrument/InstrumentTrackWindow.cpp index 1fb8596625e..60fc5937375 100644 --- a/src/gui/instrument/InstrumentTrackWindow.cpp +++ b/src/gui/instrument/InstrumentTrackWindow.cpp @@ -285,24 +285,30 @@ InstrumentTrackWindow::InstrumentTrackWindow( InstrumentTrackView * _itv ) : QMdiSubWindow* subWin = getGUI()->mainWindow()->addWindowedWidget( this ); Qt::WindowFlags flags = subWin->windowFlags(); - if (!m_instrumentView->isResizable()) { - flags |= Qt::MSWindowsFixedSizeDialogHint; - // any better way than this? - } else { - subWin->setMaximumSize(m_instrumentView->maximumHeight() + 12, m_instrumentView->maximumWidth() + 208); - subWin->setMinimumSize( m_instrumentView->minimumWidth() + 12, m_instrumentView->minimumHeight() + 208); + + if (m_instrumentView->isResizable()) + { + // TODO As of writing SlicerT is the only resizable instrument. Is this code specific to SlicerT? + const auto extraSpace = QSize(12, 208); + subWin->setMaximumSize(m_instrumentView->maximumSize() + extraSpace); + subWin->setMinimumSize(m_instrumentView->minimumSize() + extraSpace); + + flags |= Qt::WindowMaximizeButtonHint; } - flags &= ~Qt::WindowMaximizeButtonHint; - subWin->setWindowFlags( flags ); + else + { + flags |= Qt::MSWindowsFixedSizeDialogHint; + flags &= ~Qt::WindowMaximizeButtonHint; + // Hide the Size and Maximize options from the system menu since the dialog size is fixed. + QMenu * systemMenu = subWin->systemMenu(); + systemMenu->actions().at(2)->setVisible(false); // Size + systemMenu->actions().at(4)->setVisible(false); // Maximize + } - // Hide the Size and Maximize options from the system menu - // since the dialog size is fixed. - QMenu * systemMenu = subWin->systemMenu(); - systemMenu->actions().at( 2 )->setVisible( false ); // Size - systemMenu->actions().at( 4 )->setVisible( false ); // Maximize + subWin->setWindowFlags(flags); - subWin->setWindowIcon( embed::getIconPixmap( "instrument_track" ) ); + subWin->setWindowIcon(embed::getIconPixmap("instrument_track")); subWin->hide(); } From eec9df18732fafe3a3341d3396b4ac7baf17791b Mon Sep 17 00:00:00 2001 From: Michael Gregorius Date: Sun, 22 Sep 2024 13:26:36 +0200 Subject: [PATCH 02/11] Fix rendering of maximized sub windows In `SubWindow::paintEvent` don't paint anything if the sub window is maximized . Otherwise some gradients are visible behind the maximized child content. In `SubWindow::adjustTitleBar` hide the title label and the buttons if the sub window is maximized. Always show the title and close button if not maximized. This is needed to reset the state correctly after maximization. --- src/gui/SubWindow.cpp | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/gui/SubWindow.cpp b/src/gui/SubWindow.cpp index dc6e49297d1..ba9a9fe6413 100644 --- a/src/gui/SubWindow.cpp +++ b/src/gui/SubWindow.cpp @@ -111,6 +111,13 @@ SubWindow::SubWindow(QWidget *parent, Qt::WindowFlags windowFlags) : */ void SubWindow::paintEvent( QPaintEvent * ) { + // Don't paint any of the other stuff if the sub window is maximized + // so that only it child content is painted. + if (isMaximized()) + { + return; + } + QPainter p( this ); QRect rect( 0, 0, width(), m_titleBarHeight ); @@ -295,9 +302,25 @@ void SubWindow::moveEvent( QMoveEvent * event ) */ void SubWindow::adjustTitleBar() { + // Don't show the title or any button if the sub window is maximized. Otherwise they + // might show up behind the actual maximized content of the child widget. + if (isMaximized()) + { + m_closeBtn->hide(); + m_maximizeBtn->hide(); + m_restoreBtn->hide(); + m_windowTitle->hide(); + + return; + } + + // Title adjustments + m_windowTitle->show(); + // button adjustments m_maximizeBtn->hide(); m_restoreBtn->hide(); + m_closeBtn->show(); const int rightSpace = 3; const int buttonGap = 1; From f5d25447cc01b5d453e0716e21ab7b072f99ada0 Mon Sep 17 00:00:00 2001 From: Michael Gregorius Date: Sun, 22 Sep 2024 13:29:54 +0200 Subject: [PATCH 03/11] Add SubWindow::addTitleButton Add the helper method `SubWindow::addTitleButton` to reduce code repetition in the constructor. --- include/SubWindow.h | 2 ++ src/gui/SubWindow.cpp | 33 +++++++++++++++------------------ 2 files changed, 17 insertions(+), 18 deletions(-) diff --git a/include/SubWindow.h b/include/SubWindow.h index d1cc6a7af08..864b17b508f 100644 --- a/include/SubWindow.h +++ b/include/SubWindow.h @@ -78,6 +78,8 @@ class LMMS_EXPORT SubWindow : public QMdiSubWindow void paintEvent( QPaintEvent * pe ) override; void changeEvent( QEvent * event ) override; + QPushButton* addTitleButton(const std::string & iconName, const QString & toolTip); + signals: void focusLost(); diff --git a/src/gui/SubWindow.cpp b/src/gui/SubWindow.cpp index ba9a9fe6413..b8398cfcf1d 100644 --- a/src/gui/SubWindow.cpp +++ b/src/gui/SubWindow.cpp @@ -58,28 +58,13 @@ SubWindow::SubWindow(QWidget *parent, Qt::WindowFlags windowFlags) : m_borderColor = Qt::black; // close, maximize and restore (after maximizing) buttons - m_closeBtn = new QPushButton( embed::getIconPixmap( "close" ), QString(), this ); - m_closeBtn->resize( m_buttonSize ); - m_closeBtn->setFocusPolicy( Qt::NoFocus ); - m_closeBtn->setCursor( Qt::ArrowCursor ); - m_closeBtn->setAttribute( Qt::WA_NoMousePropagation ); - m_closeBtn->setToolTip( tr( "Close" ) ); + m_closeBtn = addTitleButton("close", tr("Close")); connect( m_closeBtn, SIGNAL(clicked(bool)), this, SLOT(close())); - m_maximizeBtn = new QPushButton( embed::getIconPixmap( "maximize" ), QString(), this ); - m_maximizeBtn->resize( m_buttonSize ); - m_maximizeBtn->setFocusPolicy( Qt::NoFocus ); - m_maximizeBtn->setCursor( Qt::ArrowCursor ); - m_maximizeBtn->setAttribute( Qt::WA_NoMousePropagation ); - m_maximizeBtn->setToolTip( tr( "Maximize" ) ); + m_maximizeBtn = addTitleButton("maximize", tr("Maximize")); connect( m_maximizeBtn, SIGNAL(clicked(bool)), this, SLOT(showMaximized())); - m_restoreBtn = new QPushButton( embed::getIconPixmap( "restore" ), QString(), this ); - m_restoreBtn->resize( m_buttonSize ); - m_restoreBtn->setFocusPolicy( Qt::NoFocus ); - m_restoreBtn->setCursor( Qt::ArrowCursor ); - m_restoreBtn->setAttribute( Qt::WA_NoMousePropagation ); - m_restoreBtn->setToolTip( tr( "Restore" ) ); + m_restoreBtn = addTitleButton("restore", tr("Restore")); connect( m_restoreBtn, SIGNAL(clicked(bool)), this, SLOT(showNormal())); // QLabel for the window title and the shadow effect @@ -426,5 +411,17 @@ void SubWindow::resizeEvent( QResizeEvent * event ) } } +QPushButton* SubWindow::addTitleButton(const std::string & iconName, const QString & toolTip) +{ + auto button = new QPushButton(embed::getIconPixmap(iconName), QString(), this); + button->resize(m_buttonSize); + button->setFocusPolicy(Qt::NoFocus); + button->setCursor(Qt::ArrowCursor); + button->setAttribute(Qt::WA_NoMousePropagation); + button->setToolTip(toolTip); + + return button; +} + } // namespace lmms::gui \ No newline at end of file From cdef4b5207b4c220f11fe5aa3f68b358c5f95e58 Mon Sep 17 00:00:00 2001 From: Michael Gregorius Date: Sun, 22 Sep 2024 13:32:04 +0200 Subject: [PATCH 04/11] Only disable the minimize button Disable the minimize button by taking the current flags and removing the minimize button hint from them instead of giving a list which might become incomplete in the future. So only do what we want to do. --- src/gui/SubWindow.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/gui/SubWindow.cpp b/src/gui/SubWindow.cpp index b8398cfcf1d..c266812a5ca 100644 --- a/src/gui/SubWindow.cpp +++ b/src/gui/SubWindow.cpp @@ -79,9 +79,8 @@ SubWindow::SubWindow(QWidget *parent, Qt::WindowFlags windowFlags) : m_windowTitle->setGraphicsEffect( m_shadow ); // disable the minimize button - setWindowFlags( Qt::SubWindow | Qt::WindowMaximizeButtonHint | - Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint | - Qt::CustomizeWindowHint ); + setWindowFlags(this->windowFlags() & ~Qt::WindowMinimizeButtonHint); + connect( mdiArea(), SIGNAL(subWindowActivated(QMdiSubWindow*)), this, SLOT(focusChanged(QMdiSubWindow*))); } From 0921c97f9876d567eb10fdacc5f680f3bd23f3e1 Mon Sep 17 00:00:00 2001 From: Michael Gregorius Date: Sun, 22 Sep 2024 13:33:23 +0200 Subject: [PATCH 05/11] Remove dependency on MdiArea Remove a dependency on the `MdiArea` when checking if the sub window is the active one. Query its own window state to find out if it is active. --- src/gui/SubWindow.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/gui/SubWindow.cpp b/src/gui/SubWindow.cpp index c266812a5ca..ae3497bd212 100644 --- a/src/gui/SubWindow.cpp +++ b/src/gui/SubWindow.cpp @@ -105,9 +105,7 @@ void SubWindow::paintEvent( QPaintEvent * ) QPainter p( this ); QRect rect( 0, 0, width(), m_titleBarHeight ); - bool isActive = mdiArea() - ? mdiArea()->activeSubWindow() == this - : false; + const bool isActive = windowState() & Qt::WindowActive; p.fillRect( rect, isActive ? activeColor() : p.pen().brush() ); From 4b0beb4af64695d08c5bbce8c112818c79d7c886 Mon Sep 17 00:00:00 2001 From: Michael Gregorius Date: Sun, 22 Sep 2024 13:40:04 +0200 Subject: [PATCH 06/11] Typo and newline at end of file Fix a typo and add a newline to the end of the file. --- src/gui/SubWindow.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/SubWindow.cpp b/src/gui/SubWindow.cpp index ae3497bd212..61d816e83fe 100644 --- a/src/gui/SubWindow.cpp +++ b/src/gui/SubWindow.cpp @@ -96,7 +96,7 @@ SubWindow::SubWindow(QWidget *parent, Qt::WindowFlags windowFlags) : void SubWindow::paintEvent( QPaintEvent * ) { // Don't paint any of the other stuff if the sub window is maximized - // so that only it child content is painted. + // so that only its child content is painted. if (isMaximized()) { return; @@ -421,4 +421,4 @@ QPushButton* SubWindow::addTitleButton(const std::string & iconName, const QStri } -} // namespace lmms::gui \ No newline at end of file +} // namespace lmms::gui From f4f4d1140f15b209a5e27f31719fce0d39b359f9 Mon Sep 17 00:00:00 2001 From: Michael Gregorius Date: Thu, 3 Oct 2024 14:58:19 +0200 Subject: [PATCH 07/11] Revert "Maximize button for resizable instruments" This reverts commit 9a1eaac8ec1c81e60f639b2d1f9f9da3708495b7. --- src/gui/instrument/InstrumentTrackWindow.cpp | 34 ++++++++------------ 1 file changed, 14 insertions(+), 20 deletions(-) diff --git a/src/gui/instrument/InstrumentTrackWindow.cpp b/src/gui/instrument/InstrumentTrackWindow.cpp index 60fc5937375..1fb8596625e 100644 --- a/src/gui/instrument/InstrumentTrackWindow.cpp +++ b/src/gui/instrument/InstrumentTrackWindow.cpp @@ -285,30 +285,24 @@ InstrumentTrackWindow::InstrumentTrackWindow( InstrumentTrackView * _itv ) : QMdiSubWindow* subWin = getGUI()->mainWindow()->addWindowedWidget( this ); Qt::WindowFlags flags = subWin->windowFlags(); - - if (m_instrumentView->isResizable()) - { - // TODO As of writing SlicerT is the only resizable instrument. Is this code specific to SlicerT? - const auto extraSpace = QSize(12, 208); - subWin->setMaximumSize(m_instrumentView->maximumSize() + extraSpace); - subWin->setMinimumSize(m_instrumentView->minimumSize() + extraSpace); - - flags |= Qt::WindowMaximizeButtonHint; - } - else - { + if (!m_instrumentView->isResizable()) { flags |= Qt::MSWindowsFixedSizeDialogHint; - flags &= ~Qt::WindowMaximizeButtonHint; - - // Hide the Size and Maximize options from the system menu since the dialog size is fixed. - QMenu * systemMenu = subWin->systemMenu(); - systemMenu->actions().at(2)->setVisible(false); // Size - systemMenu->actions().at(4)->setVisible(false); // Maximize + // any better way than this? + } else { + subWin->setMaximumSize(m_instrumentView->maximumHeight() + 12, m_instrumentView->maximumWidth() + 208); + subWin->setMinimumSize( m_instrumentView->minimumWidth() + 12, m_instrumentView->minimumHeight() + 208); } + flags &= ~Qt::WindowMaximizeButtonHint; + subWin->setWindowFlags( flags ); + - subWin->setWindowFlags(flags); + // Hide the Size and Maximize options from the system menu + // since the dialog size is fixed. + QMenu * systemMenu = subWin->systemMenu(); + systemMenu->actions().at( 2 )->setVisible( false ); // Size + systemMenu->actions().at( 4 )->setVisible( false ); // Maximize - subWin->setWindowIcon(embed::getIconPixmap("instrument_track")); + subWin->setWindowIcon( embed::getIconPixmap( "instrument_track" ) ); subWin->hide(); } From 6b953fc0d58a2824edd84dab421b81c07ad64fb1 Mon Sep 17 00:00:00 2001 From: Michael Gregorius Date: Fri, 4 Oct 2024 19:15:44 +0200 Subject: [PATCH 08/11] Set Qt::CustomizeWindowHint Make sure that `Qt::CustomizeWindowHint` is set like it was before. --- src/gui/SubWindow.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/SubWindow.cpp b/src/gui/SubWindow.cpp index 61d816e83fe..fb6dfd37c06 100644 --- a/src/gui/SubWindow.cpp +++ b/src/gui/SubWindow.cpp @@ -78,8 +78,8 @@ SubWindow::SubWindow(QWidget *parent, Qt::WindowFlags windowFlags) : m_windowTitle->setAttribute( Qt::WA_TransparentForMouseEvents, true ); m_windowTitle->setGraphicsEffect( m_shadow ); - // disable the minimize button - setWindowFlags(this->windowFlags() & ~Qt::WindowMinimizeButtonHint); + // Disable the minimize button and make sure that the custom window hint is set + setWindowFlags((this->windowFlags() & ~Qt::WindowMinimizeButtonHint) | Qt::CustomizeWindowHint); connect( mdiArea(), SIGNAL(subWindowActivated(QMdiSubWindow*)), this, SLOT(focusChanged(QMdiSubWindow*))); } From 40a90ad7a2dc2bfd210ed94ebc70f8eaf0d026bd Mon Sep 17 00:00:00 2001 From: Michael Gregorius Date: Wed, 9 Oct 2024 13:40:59 +0200 Subject: [PATCH 09/11] Remove calls to isMaximized Remove some calls to `isMaximized` where we already know that the sub window is not maximized, i.e. where these calls would always return `false`. One adjustment would have resulted in a call to `setHidden(false)`. This was changed to `setVisible(true)` to get rid of the double negation. The other `false` would have gotten in an or statement and thus could be removed completely. --- src/gui/SubWindow.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/gui/SubWindow.cpp b/src/gui/SubWindow.cpp index fb6dfd37c06..3131b7a3afa 100644 --- a/src/gui/SubWindow.cpp +++ b/src/gui/SubWindow.cpp @@ -296,6 +296,9 @@ void SubWindow::adjustTitleBar() return; } + // The sub window is not maximized, i.e. the title must be shown + // as well as some buttons. + // Title adjustments m_windowTitle->show(); @@ -327,12 +330,12 @@ void SubWindow::adjustTitleBar() buttonBarWidth = buttonBarWidth + m_buttonSize.width() + buttonGap; m_maximizeBtn->move( middleButtonPos ); m_restoreBtn->move( middleButtonPos ); - m_maximizeBtn->setHidden( isMaximized() ); + m_maximizeBtn->setVisible(true); } // we're keeping the restore button around if we open projects // from older versions that have saved minimized windows - m_restoreBtn->setVisible( isMaximized() || isMinimized() ); + m_restoreBtn->setVisible(isMinimized()); if( isMinimized() ) { m_restoreBtn->move( m_maximizeBtn->isHidden() ? middleButtonPos : leftButtonPos ); From e89694a2199a4296f0f16e1d0155732bebf25de8 Mon Sep 17 00:00:00 2001 From: Michael Gregorius Date: Thu, 10 Oct 2024 09:55:54 +0200 Subject: [PATCH 10/11] Code review Fix whitespaces in parameter list of `addTitleButton`. --- include/SubWindow.h | 2 +- src/gui/SubWindow.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/SubWindow.h b/include/SubWindow.h index 864b17b508f..c5e3f02d4d0 100644 --- a/include/SubWindow.h +++ b/include/SubWindow.h @@ -78,7 +78,7 @@ class LMMS_EXPORT SubWindow : public QMdiSubWindow void paintEvent( QPaintEvent * pe ) override; void changeEvent( QEvent * event ) override; - QPushButton* addTitleButton(const std::string & iconName, const QString & toolTip); + QPushButton* addTitleButton(const std::string& iconName, const QString& toolTip); signals: void focusLost(); diff --git a/src/gui/SubWindow.cpp b/src/gui/SubWindow.cpp index 3131b7a3afa..780730de9ff 100644 --- a/src/gui/SubWindow.cpp +++ b/src/gui/SubWindow.cpp @@ -411,7 +411,7 @@ void SubWindow::resizeEvent( QResizeEvent * event ) } } -QPushButton* SubWindow::addTitleButton(const std::string & iconName, const QString & toolTip) +QPushButton* SubWindow::addTitleButton(const std::string& iconName, const QString& toolTip) { auto button = new QPushButton(embed::getIconPixmap(iconName), QString(), this); button->resize(m_buttonSize); From d5be2e5e6ad9318d178b72fa576ac03523e00a00 Mon Sep 17 00:00:00 2001 From: Michael Gregorius Date: Thu, 10 Oct 2024 10:04:22 +0200 Subject: [PATCH 11/11] Make return a one-liner --- src/gui/SubWindow.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/gui/SubWindow.cpp b/src/gui/SubWindow.cpp index 780730de9ff..1fa0f25a71f 100644 --- a/src/gui/SubWindow.cpp +++ b/src/gui/SubWindow.cpp @@ -97,10 +97,7 @@ void SubWindow::paintEvent( QPaintEvent * ) { // Don't paint any of the other stuff if the sub window is maximized // so that only its child content is painted. - if (isMaximized()) - { - return; - } + if (isMaximized()) { return; } QPainter p( this ); QRect rect( 0, 0, width(), m_titleBarHeight );