# HG changeset patch # User Chris Cannam # Date 1570193484 -3600 # Node ID 0f1601d870db0eb73ae9de8c25cc31b487d2e0e9 # Parent 284a38c437213e9016ae6cb4977d775b625fb137 Rework PaneStack so that the options that generally aren't (or can't be) changed after construction are supplied to the constructor instead of being set through setter methods. This is a more sensible way of doing things in general, but also a workaround for https://code.soundsoftware.ac.uk/issues/1930, a problem that arises when reinitialising hidden property boxes in a context in which they will never be visible at all. diff -r 284a38c43721 -r 0f1601d870db view/PaneStack.cpp --- a/view/PaneStack.cpp Fri Oct 04 13:37:39 2019 +0100 +++ b/view/PaneStack.cpp Fri Oct 04 13:51:24 2019 +0100 @@ -37,37 +37,47 @@ //#define DEBUG_PANE_STACK 1 -PaneStack::PaneStack(QWidget *parent, ViewManager *viewManager) : +PaneStack::PaneStack(QWidget *parent, + ViewManager *viewManager, + int options) : QFrame(parent), m_currentPane(nullptr), - m_showAccessories(true), - m_showCloseButtonOnFirstPane(true), - m_showAlignmentViews(false), - m_splitter(new QSplitter), - m_autoResizeStack(new QWidget), + m_options(options), + m_splitter(nullptr), + m_autoResizeStack(nullptr), m_propertyStackStack(new QStackedWidget), m_viewManager(viewManager), m_propertyStackMinWidth(100), - m_layoutStyle(PropertyStackPerPaneLayout), - m_resizeMode(UserResizeable) + m_layoutStyle(PropertyStackPerPaneLayout) { QHBoxLayout *layout = new QHBoxLayout; layout->setMargin(0); layout->setSpacing(0); - m_autoResizeLayout = new QVBoxLayout; - m_autoResizeLayout->setMargin(0); - m_autoResizeLayout->setSpacing(0); - m_autoResizeStack->setLayout(m_autoResizeLayout); - m_autoResizeStack->hide(); - layout->addWidget(m_autoResizeStack); - layout->setStretchFactor(m_autoResizeStack, 1); + if (m_options & int(Option::NoUserResize)) { - m_splitter->setOrientation(Qt::Vertical); - m_splitter->setOpaqueResize(false); - m_splitter->show(); - layout->addWidget(m_splitter); - layout->setStretchFactor(m_splitter, 1); + m_autoResizeStack = new QWidget; + m_autoResizeLayout = new QVBoxLayout; + m_autoResizeLayout->setMargin(0); + m_autoResizeLayout->setSpacing(0); + m_autoResizeStack->setLayout(m_autoResizeLayout); + m_autoResizeStack->hide(); + layout->addWidget(m_autoResizeStack); + layout->setStretchFactor(m_autoResizeStack, 1); + + } else { + + m_splitter = new QSplitter; + m_splitter->setOrientation(Qt::Vertical); + m_splitter->setOpaqueResize(false); + m_splitter->show(); + layout->addWidget(m_splitter); + layout->setStretchFactor(m_splitter, 1); + } + + if (m_options & int(Option::NoPropertyStacks)) { + m_layoutStyle = HiddenPropertyStacksLayout; + } m_propertyStackStack->hide(); layout->addWidget(m_propertyStackStack); @@ -75,38 +85,15 @@ setLayout(layout); } -void -PaneStack::setShowPaneAccessories(bool show) -{ - m_showAccessories = show; -} - -void -PaneStack::setShowCloseButtonOnFirstPane(bool show) -{ - m_showCloseButtonOnFirstPane = show; -} - -void -PaneStack::setShowAlignmentViews(bool show) -{ - m_showAlignmentViews = show; - // each alignment view shows alignment between the pane above and - // the pane it is attached to: so pane 0 doesn't have a visible one - for (int i = 1; in_range_for(m_panes, i); ++i) { - m_panes[i].alignmentView->setVisible(m_showAlignmentViews); - } -} - Pane * -PaneStack::addPane(bool suppressPropertyBox) +PaneStack::addPane() { QFrame *frame = new QFrame; QGridLayout *layout = new QGridLayout; layout->setMargin(0); layout->setHorizontalSpacing(m_viewManager->scalePixelSize(2)); - if (m_showAlignmentViews) { + if (m_options & int(Option::ShowAlignmentViews)) { layout->setVerticalSpacing(0); } else { layout->setVerticalSpacing(m_viewManager->scalePixelSize(2)); @@ -122,8 +109,8 @@ xButton->setIcon(IconLoader().load("cross")); xButton->setFixedSize(QSize(16, 16)); xButton->setFlat(true); - xButton->setVisible(m_showAccessories); - if (m_panes.empty() && !m_showCloseButtonOnFirstPane) { + xButton->setVisible(!(m_options & int(Option::NoPaneAccessories))); + if (m_panes.empty() && (m_options & int(Option::NoCloseOnFirstPane))) { xButton->setVisible(false); } layout->addWidget(xButton, 1, 0); @@ -136,7 +123,7 @@ currentIndicator->setMinimumWidth(16); currentIndicator->setMinimumHeight(16); currentIndicator->setScaledContents(true); - currentIndicator->setVisible(m_showAccessories); + currentIndicator->setVisible(!(m_options & int(Option::NoPaneAccessories))); sv_frame_t initialCentreFrame = -1; if (!m_panes.empty()) { @@ -153,7 +140,7 @@ layout->setColumnStretch(1, 20); QWidget *properties = nullptr; - if (suppressPropertyBox) { + if (m_options & int(Option::NoPropertyStacks)) { properties = new QFrame(); } else { properties = new PropertyStack(frame, pane); @@ -184,11 +171,11 @@ frame->setLayout(layout); - if (m_resizeMode == UserResizeable) { - m_splitter->addWidget(frame); - } else { + if (m_options & int(Option::NoUserResize)) { m_autoResizeLayout->addWidget(frame); frame->adjustSize(); + } else { + m_splitter->addWidget(frame); } connect(pane, SIGNAL(propertyContainerAdded(PropertyContainer *)), @@ -223,12 +210,15 @@ PaneStack::relinkAlignmentViews() { if (m_panes.empty()) return; - if (!m_showAlignmentViews) return; m_panes[0].alignmentView->hide(); for (int i = 1; in_range_for(m_panes, i); ++i) { - m_panes[i].alignmentView->setViewAbove(m_panes[i-1].pane); - m_panes[i].alignmentView->setViewBelow(m_panes[i].pane); - m_panes[i].alignmentView->setVisible(true); + if (!(m_options & int(Option::ShowAlignmentViews))) { + m_panes[i].alignmentView->hide(); + } else { + m_panes[i].alignmentView->setViewAbove(m_panes[i-1].pane); + m_panes[i].alignmentView->setViewBelow(m_panes[i].pane); + m_panes[i].alignmentView->show(); + } } } @@ -254,6 +244,11 @@ void PaneStack::setLayoutStyle(LayoutStyle style) { + if (m_options & int(Option::NoPropertyStacks)) { + SVCERR << "NOTE: PaneStack::setLayoutStyle called on PaneStack with NoPropertyStacks option set - this does nothing, its style is always equivalent to HiddenPropertyStacksLayout" << endl; + return; + } + if (style == m_layoutStyle) return; m_layoutStyle = style; @@ -261,7 +256,7 @@ switch (style) { - case NoPropertyStacks: + case HiddenPropertyStacksLayout: case SinglePropertyStackLayout: for (i = m_panes.begin(); i != m_panes.end(); ++i) { @@ -269,7 +264,7 @@ i->propertyStack->setParent(m_propertyStackStack); m_propertyStackStack->addWidget(i->propertyStack); } - m_propertyStackStack->setVisible(style != NoPropertyStacks); + m_propertyStackStack->setVisible(style != HiddenPropertyStacksLayout); break; case PropertyStackPerPaneLayout: @@ -393,10 +388,10 @@ bool multi = (getPaneCount() > 1); for (std::vector::iterator i = m_panes.begin(); i != m_panes.end(); ++i) { - bool visible = (multi && m_showAccessories); + bool visible = (multi && !(m_options & int(Option::NoPaneAccessories))); bool xvisible = visible; if (i == m_panes.begin()) { - if (!m_showCloseButtonOnFirstPane) { + if (m_options & int(Option::NoCloseOnFirstPane)) { xvisible = false; } } @@ -689,7 +684,7 @@ void PaneStack::sizePanesEqually() { - if (m_resizeMode == AutoResizeOnly) { + if (m_options & int(Option::NoUserResize)) { return; } @@ -750,19 +745,3 @@ m_splitter->setSizes(sizes); } -void -PaneStack::setResizeMode(ResizeMode mode) -{ - if (mode == UserResizeable) { - m_autoResizeStack->hide(); - m_splitter->show(); - } else { - m_autoResizeStack->show(); - m_splitter->hide(); - } - m_resizeMode = mode; - - // we don't actually move any existing panes yet! let's do that - // only if we turn out to need it, shall we? -} - diff -r 284a38c43721 -r 0f1601d870db view/PaneStack.h --- a/view/PaneStack.h Fri Oct 04 13:37:39 2019 +0100 +++ b/view/PaneStack.h Fri Oct 04 13:51:24 2019 +0100 @@ -42,10 +42,23 @@ Q_OBJECT public: + /// These options are for things that must be set on construction, + /// and can't be changed afterwards + enum class Option { + Default = 0x0, + NoUserResize = 0x1, // Suppress resize handles, auto-size only + NoPropertyStacks = 0x2, // Never create property stacks + NoPaneAccessories = 0x4, // Suppress current-pane and close button + NoCloseOnFirstPane = 0x8, // Omit close button from the top pane + ShowAlignmentViews = 0x10 // Include AlignmentViews between panes + }; + typedef int Options; + PaneStack(QWidget *parent, - ViewManager *viewManager); + ViewManager *viewManager, + Options options = 0); - Pane *addPane(bool suppressPropertyBox = false); // I own the returned value + Pane *addPane(); // I own the returned value void deletePane(Pane *pane); // Deletes the pane, but _not_ its layers int getPaneCount() const; // Returns only count of visible panes @@ -62,8 +75,9 @@ void setCurrentLayer(Pane *pane, Layer *layer); Pane *getCurrentPane(); + /// Runtime-switchable layout style for property stacks enum LayoutStyle { - NoPropertyStacks = 0, + HiddenPropertyStacksLayout = 0, SinglePropertyStackLayout = 1, PropertyStackPerPaneLayout = 2 }; @@ -71,28 +85,8 @@ LayoutStyle getLayoutStyle() const { return m_layoutStyle; } void setLayoutStyle(LayoutStyle style); - enum ResizeMode { - UserResizeable = 0, - AutoResizeOnly = 1 - }; - - ResizeMode getResizeMode() const { return m_resizeMode; } - void setResizeMode(ResizeMode); - - // Set whether the current-pane indicators and close buttons are - // shown. The default is true. - void setShowPaneAccessories(bool show); - - // Set whether a close button is shown on the first pane as well - // as others. (It may be reasonable to omit the close button from - // what is presumably the main pane in some applications.) The - // default is true. - void setShowCloseButtonOnFirstPane(bool); - void setPropertyStackMinWidth(int mw); - void setShowAlignmentViews(bool show); - void sizePanesEqually(); signals: @@ -146,12 +140,9 @@ std::vector m_panes; std::vector m_hiddenPanes; - bool m_showAccessories; - bool m_showCloseButtonOnFirstPane; - bool m_showAlignmentViews; - - QSplitter *m_splitter; // constitutes the stack in UserResizeable mode - QWidget *m_autoResizeStack; // constitutes the stack in AutoResizeOnly mode + int m_options; + QSplitter *m_splitter; // constitutes the stack in default mode + QWidget *m_autoResizeStack; // constitutes the stack in NoUserResize mode QVBoxLayout *m_autoResizeLayout; QStackedWidget *m_propertyStackStack; @@ -166,7 +157,6 @@ void relinkAlignmentViews(); LayoutStyle m_layoutStyle; - ResizeMode m_resizeMode; }; #endif