Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Maximize button for resizable instruments #7514

Open
wants to merge 13 commits into
base: master
Choose a base branch
from
Open
4 changes: 4 additions & 0 deletions include/InstrumentTrackWindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
class QLabel;
class QLineEdit;
class QWidget;
class QMdiSubWindow;

namespace lmms
{
Expand Down Expand Up @@ -134,6 +135,9 @@ protected slots:
//! required to keep the old look when using a variable sized tab widget
void adjustTabSize(QWidget *w);

QMdiSubWindow* findSubWindowInParents();
void updateSubWindow();

InstrumentTrack * m_track;
InstrumentTrackView * m_itv;

Expand Down
4 changes: 4 additions & 0 deletions include/SubWindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@ class LMMS_EXPORT SubWindow : public QMdiSubWindow
int titleBarHeight() const;
int frameWidth() const;

// TODO Needed to update the title bar when replacing instruments.
// Update works automatically if QMdiSubWindows are used.
void updateTitleBar();

protected:
// hook the QWidget move/resize events to update the tracked geometry
void moveEvent( QMoveEvent * event ) override;
Expand Down
4 changes: 4 additions & 0 deletions src/gui/SubWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,10 @@ int SubWindow::frameWidth() const
}


void SubWindow::updateTitleBar()
{
adjustTitleBar();
}


/**
Expand Down
94 changes: 76 additions & 18 deletions src/gui/instrument/InstrumentTrackWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@
#include "MainWindow.h"
#include "PianoView.h"
#include "PluginFactory.h"
#include "PluginView.h"
#include "Song.h"
#include "StringPairDrag.h"
#include "SubWindow.h"
Expand Down Expand Up @@ -284,25 +283,12 @@ InstrumentTrackWindow::InstrumentTrackWindow( InstrumentTrackView * _itv ) :
updateInstrumentView();

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);
}
flags &= ~Qt::WindowMaximizeButtonHint;
subWin->setWindowFlags( flags );

// The previous call should have given us a sub window parent. Therefore
// we can reuse this method.
updateSubWindow();

// 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();
}

Expand Down Expand Up @@ -406,6 +392,8 @@ void InstrumentTrackWindow::modelChanged()
m_tuningView->keymapCombo()->setModel(m_track->m_microtuner.keymapModel());
m_tuningView->rangeImportCheckbox()->setModel(m_track->m_microtuner.keyRangeImportModel());
updateName();

updateSubWindow();
}


Expand Down Expand Up @@ -710,5 +698,75 @@ void InstrumentTrackWindow::adjustTabSize(QWidget *w)
w->update();
}

QMdiSubWindow* InstrumentTrackWindow::findSubWindowInParents()
{
// TODO Move to helper? Does not seem to be provided by Qt.
auto p = parentWidget();

while (p != nullptr)
{
auto mdiSubWindow = dynamic_cast<QMdiSubWindow*>(p);
if (mdiSubWindow)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These 2 are other good candidates for "inlining".

{
return mdiSubWindow;
}
else
{
p = p->parentWidget();
}
}

return nullptr;
}

void InstrumentTrackWindow::updateSubWindow()
{
auto subWindow = findSubWindowInParents();
if (subWindow && m_instrumentView)
{
Qt::WindowFlags flags = subWindow->windowFlags();

const auto instrumentViewResizable = m_instrumentView->isResizable();

if (instrumentViewResizable)
{
// TODO As of writing SlicerT is the only resizable instrument. Is this code specific to SlicerT?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note, this is still not fixed - see my previous comment.

const auto extraSpace = QSize(12, 208);
subWindow->setMaximumSize(m_instrumentView->maximumSize() + extraSpace);
subWindow->setMinimumSize(m_instrumentView->minimumSize() + extraSpace);

flags &= ~Qt::MSWindowsFixedSizeDialogHint;
Copy link
Contributor

@SpomJ SpomJ Nov 20, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider also adding setFixedSize() here. MSWindowsFixedSizeDialogHint annoyingly appears to be a windows-only thing, or at least, isn't respected on wayland, while setFixedSize() or layout->setSizeConstraint(QLayout::SetFixedSize) is.

flags |= Qt::WindowMaximizeButtonHint;
}
else
{
flags |= Qt::MSWindowsFixedSizeDialogHint;
flags &= ~Qt::WindowMaximizeButtonHint;

// The sub window might be reused from an instrument that was maximized. Show the sub window
// as normal, i.e. not maximized, if the instrument view is not resizable.
if (subWindow->isMaximized())
JohannesLorenz marked this conversation as resolved.
Show resolved Hide resolved
{
subWindow->showNormal();
}
}

subWindow->setWindowFlags(flags);

// Show or hide the Size and Maximize options from the system menu depending on whether the view is resizable or not
QMenu * systemMenu = subWindow->systemMenu();
systemMenu->actions().at(2)->setVisible(instrumentViewResizable); // Size
systemMenu->actions().at(4)->setVisible(instrumentViewResizable); // Maximize

// TODO This is only needed if the sub window is implemented with LMMS' own SubWindow class.
// If an QMdiSubWindow is used everything works automatically. It seems that SubWindow is
// missing some implementation details that QMdiSubWindow has.
auto subWin = dynamic_cast<SubWindow*>(subWindow);
if (subWin)
{
subWin->updateTitleBar();
}
}
}

} // namespace lmms::gui
Loading