refactor: DockWidget::isOpen() now keeps its state in the controller
No longer tied to QtWidget visibility. This will make it easier to make new frontends.
This commit is contained in:
@@ -58,8 +58,11 @@ void Controller::setVisible(bool is)
|
||||
{
|
||||
if (m_view)
|
||||
m_view->setVisible(is);
|
||||
else
|
||||
qWarning() << Q_FUNC_INFO << "No view";
|
||||
|
||||
if (m_isVisible == is)
|
||||
return;
|
||||
|
||||
Q_EMIT visibleChanged(is);
|
||||
}
|
||||
|
||||
QRect Controller::rect() const
|
||||
|
||||
@@ -92,6 +92,9 @@ Q_SIGNALS:
|
||||
///@brief signal counterpart for setParentView()
|
||||
void parentViewChanged(View *parent);
|
||||
|
||||
///@brief signal counterpart for setVisible()
|
||||
void visibleChanged(bool);
|
||||
|
||||
protected:
|
||||
virtual void setParentView_impl(View *parent);
|
||||
|
||||
@@ -99,6 +102,7 @@ private:
|
||||
void setParent(QObject *) = delete;
|
||||
View *m_view = nullptr;
|
||||
bool m_inDtor = false;
|
||||
bool m_isVisible = true;
|
||||
const Type m_type;
|
||||
};
|
||||
|
||||
|
||||
@@ -402,7 +402,7 @@ Controllers::TitleBar *DockWidget::titleBar() const
|
||||
|
||||
bool DockWidget::isOpen() const
|
||||
{
|
||||
return d->toggleAction->isChecked();
|
||||
return d->m_isOpen;
|
||||
}
|
||||
|
||||
QStringList DockWidget::affinities() const
|
||||
@@ -418,6 +418,7 @@ void DockWidget::show()
|
||||
// This reduces flickering on some platforms
|
||||
d->morphIntoFloatingWindow();
|
||||
} else {
|
||||
d->setIsOpen(true);
|
||||
view()->show();
|
||||
}
|
||||
}
|
||||
@@ -582,6 +583,7 @@ Controllers::FloatingWindow *DockWidget::Private::morphIntoFloatingWindow()
|
||||
|
||||
Layouting::AtomicSanityChecks checks(floatingWindow->dropArea()->rootItem());
|
||||
floatingWindow->view()->show();
|
||||
setIsOpen(true);
|
||||
|
||||
return floatingWindow;
|
||||
} else {
|
||||
@@ -702,6 +704,7 @@ void DockWidget::Private::toggle(bool enabled)
|
||||
{
|
||||
if (Controllers::SideBar *sb = sideBar()) {
|
||||
// The widget is in the sidebar, let's toggle its overlayed state
|
||||
QScopedValueRollback<bool> guard(m_removingFromOverlay, true);
|
||||
sb->toggleOverlay(q);
|
||||
} else {
|
||||
// The most common case. The dock widget is not in the sidebar. just close or open it.
|
||||
@@ -727,7 +730,7 @@ void DockWidget::Private::updateToggleAction()
|
||||
|
||||
void DockWidget::Private::updateFloatAction()
|
||||
{
|
||||
if (m_willUpdateActions)
|
||||
if (m_willUpdateActions || m_removingFromOverlay)
|
||||
return;
|
||||
|
||||
QScopedValueRollback<bool> recursionGuard(m_updatingFloatAction,
|
||||
@@ -758,6 +761,10 @@ void DockWidget::Private::onDockWidgetHidden()
|
||||
|
||||
void DockWidget::Private::close()
|
||||
{
|
||||
if (m_inClose)
|
||||
return;
|
||||
QScopedValueRollback<bool> guard(m_inClose, true);
|
||||
|
||||
if (!m_processingToggleAction && !q->isOpen()) {
|
||||
q->setParentView(nullptr);
|
||||
return;
|
||||
@@ -766,6 +773,8 @@ void DockWidget::Private::close()
|
||||
if (m_isPersistentCentralDockWidget)
|
||||
return;
|
||||
|
||||
setIsOpen(false);
|
||||
|
||||
// If it's overlayed and we're closing, we need to close the overlay
|
||||
if (Controllers::SideBar *sb = DockRegistry::self()->sideBarForDockWidget(q)) {
|
||||
auto mainWindow = sb->mainWindow();
|
||||
@@ -1060,3 +1069,16 @@ void DockWidget::Private::onCloseEvent(QCloseEvent *e)
|
||||
if (e->isAccepted())
|
||||
close();
|
||||
}
|
||||
|
||||
void DockWidget::Private::setIsOpen(bool is)
|
||||
{
|
||||
if (is == m_isOpen || m_inOpenSetter)
|
||||
return;
|
||||
|
||||
QScopedValueRollback<bool> guard(m_inOpenSetter, true);
|
||||
|
||||
if (!is)
|
||||
close();
|
||||
|
||||
m_isOpen = is;
|
||||
}
|
||||
|
||||
@@ -277,7 +277,7 @@ public:
|
||||
|
||||
/**
|
||||
* @brief Returns whether this dock widget is open.
|
||||
* Equivalent to calling toggleAction().isChecked() or isVisible()
|
||||
* Equivalent to calling toggleAction().isChecked()
|
||||
*/
|
||||
bool isOpen() const;
|
||||
|
||||
|
||||
@@ -179,6 +179,8 @@ public:
|
||||
/// widget This goes up the hierarchy, while mdiDropAreaWrapper goes down.
|
||||
DockWidget *mdiDockWidgetWrapper() const;
|
||||
|
||||
void setIsOpen(bool);
|
||||
|
||||
const QString name;
|
||||
QStringList affinities;
|
||||
QString title;
|
||||
@@ -199,6 +201,10 @@ public:
|
||||
bool m_isMovingToSideBar = false;
|
||||
bool m_isSettingCurrent =
|
||||
false; // TODOm4: Remove once DockWidget::onShown() doesn't drive things
|
||||
bool m_isOpen = false;
|
||||
bool m_inOpenSetter = false;
|
||||
bool m_inClose = false;
|
||||
bool m_removingFromOverlay = false; // TODOm4: Remove soon
|
||||
QSize m_lastOverlayedSize = QSize(0, 0);
|
||||
int m_userType = 0;
|
||||
bool m_willUpdateActions = false;
|
||||
|
||||
@@ -258,7 +258,7 @@ void Group::insertWidget(DockWidget *dockWidget, int index, InitialOption adding
|
||||
insertDockWidget(dockWidget, index);
|
||||
|
||||
if (addingOption.startsHidden()) {
|
||||
dockWidget->view()->close(); // Ensure closed
|
||||
dockWidget->view()->close(); // Ensure closed. TODOm4: Call controller instead.
|
||||
} else {
|
||||
if (hasSingleDockWidget()) {
|
||||
setObjectName(dockWidget->uniqueName());
|
||||
@@ -272,6 +272,8 @@ void Group::insertWidget(DockWidget *dockWidget, int index, InitialOption adding
|
||||
} else if (addingOption.preservesCurrentTab() && originalCurrentIndex != -1) {
|
||||
setCurrentTabIndex(originalCurrentIndex);
|
||||
}
|
||||
|
||||
dockWidget->d->setIsOpen(true);
|
||||
}
|
||||
|
||||
connect(dockWidget, &DockWidget::titleChanged, this, &Group::onDockWidgetTitleChanged);
|
||||
|
||||
@@ -616,28 +616,32 @@ void MainWindow::clearSideBarOverlay(bool deleteFrame)
|
||||
if (!d->m_overlayedDockWidget)
|
||||
return;
|
||||
|
||||
Controllers::Group *group = d->m_overlayedDockWidget->d->group();
|
||||
auto overlayedDockWidget = d->m_overlayedDockWidget;
|
||||
d->m_overlayedDockWidget = nullptr;
|
||||
|
||||
Controllers::Group *group = overlayedDockWidget->d->group();
|
||||
if (!group) { // prophylactic check
|
||||
d->m_overlayedDockWidget = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
const SideBarLocation loc = d->m_overlayedDockWidget->sideBarLocation();
|
||||
d->m_overlayedDockWidget->d->lastPosition()->setLastOverlayedGeometry(loc, group->geometry());
|
||||
const SideBarLocation loc = overlayedDockWidget->sideBarLocation();
|
||||
overlayedDockWidget->d->lastPosition()->setLastOverlayedGeometry(loc, group->geometry());
|
||||
|
||||
group->unoverlay();
|
||||
|
||||
if (deleteFrame) {
|
||||
d->m_overlayedDockWidget->QObject::setParent(nullptr);
|
||||
d->m_overlayedDockWidget->setParentView(nullptr);
|
||||
Q_EMIT d->m_overlayedDockWidget->isOverlayedChanged(false);
|
||||
d->m_overlayedDockWidget = nullptr;
|
||||
overlayedDockWidget->QObject::setParent(nullptr);
|
||||
overlayedDockWidget->d->m_removingFromOverlay = true; // TODOm4: Remove soon
|
||||
overlayedDockWidget->setParentView(nullptr);
|
||||
overlayedDockWidget->d->m_removingFromOverlay = false;
|
||||
Q_EMIT overlayedDockWidget->isOverlayedChanged(false);
|
||||
overlayedDockWidget = nullptr;
|
||||
delete group;
|
||||
} else {
|
||||
// No cleanup, just unset. When we drag the overlay it becomes a normal floating window
|
||||
// meaning we reuse Frame. Don't delete it.
|
||||
Q_EMIT d->m_overlayedDockWidget->isOverlayedChanged(false);
|
||||
d->m_overlayedDockWidget = nullptr;
|
||||
Q_EMIT overlayedDockWidget->isOverlayedChanged(false);
|
||||
overlayedDockWidget = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -77,7 +77,9 @@ TEST_CASE("isOpen")
|
||||
CHECK(dw->isOpen());
|
||||
CHECK(dw->isFloating());
|
||||
auto dw2 = Config::self().viewFactory()->createDockWidget("dw2")->asDockWidgetController();
|
||||
CHECK(dw->isCurrentTab());
|
||||
dw->addDockWidgetAsTab(dw2);
|
||||
CHECK(dw2->isOpen());
|
||||
dw2->setAsCurrentTab();
|
||||
CHECK(!dw->isCurrentTab());
|
||||
CHECK(dw2->isCurrentTab());
|
||||
|
||||
@@ -819,6 +819,7 @@ void TestQtWidgets::tst_sidebarOverlayGetsHiddenOnClick()
|
||||
|
||||
Tests::clickOn(dw2->mapToGlobal(dw2->rect().bottomLeft() + QPoint(5, -5)), dw2->view());
|
||||
QVERIFY(!dw1->isOverlayed());
|
||||
QVERIFY(dw1->isInSideBar());
|
||||
|
||||
auto widget2 = Platform::instance()->tests_createView({ true });
|
||||
dw2->setGuestView(widget2->asWrapper());
|
||||
|
||||
Reference in New Issue
Block a user