diff options
author | Berthold Stoeger <bstoeger@mail.tuwien.ac.at> | 2021-01-27 22:06:41 +0100 |
---|---|---|
committer | Dirk Hohndel <dirk@hohndel.org> | 2021-02-06 10:00:39 -0800 |
commit | aefbde93ce161c08b4aca31aee4e3fc45ab72003 (patch) | |
tree | 0188e6c41a6996ef4216e419cdb0e59b96f4e062 /desktop-widgets | |
parent | c584e28f2e0cc97cb2573d66697fdb0c0f160b66 (diff) | |
download | subsurface-aefbde93ce161c08b4aca31aee4e3fc45ab72003.tar.gz |
desktop: be smarter about filling splitters
On state change, the splitters were completely emptied and
refilled. Instead try to reuse already existing splitter
slots. This reduces annoying flickering.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Diffstat (limited to 'desktop-widgets')
-rw-r--r-- | desktop-widgets/mainwindow.cpp | 78 | ||||
-rw-r--r-- | desktop-widgets/mainwindow.h | 4 |
2 files changed, 53 insertions, 29 deletions
diff --git a/desktop-widgets/mainwindow.cpp b/desktop-widgets/mainwindow.cpp index 593457eff..689c6588c 100644 --- a/desktop-widgets/mainwindow.cpp +++ b/desktop-widgets/mainwindow.cpp @@ -338,10 +338,21 @@ MainWindow::MainWindow() : QMainWindow(), #endif } +static void clearSplitter(QSplitter &splitter) +{ + // Qt's ownership model is absolutely hare-brained. + // To remove a widget from a splitter, you reparent it, which + // informs the splitter via a signal. Wow. + while (splitter.count() > 0) + splitter.widget(0)->setParent(nullptr); +} + MainWindow::~MainWindow() { // Remove widgets from the splitters so that they don't delete singletons. - clearSplitters(); + clearSplitter(*topSplitter); + clearSplitter(*bottomSplitter); + clearSplitter(*ui.mainSplitter); write_hashes(); m_Instance = nullptr; } @@ -1575,29 +1586,27 @@ void MainWindow::registerApplicationState(ApplicationState state, Quadrants q) applicationState[(int)state] = q; } -void MainWindow::setQuadrantWidget(const Quadrant &q, QSplitter &splitter) +void MainWindow::setQuadrantWidget(QSplitter &splitter, const Quadrant &q, int pos) { - if (q.widget) { + if (!q.widget) + return; + if (splitter.count() > pos) + splitter.replaceWidget(pos, q.widget); + else splitter.addWidget(q.widget); - splitter.setCollapsible(splitter.count() - 1, false); - q.widget->setEnabled(!(q.flags & FLAG_DISABLED)); - } + splitter.setCollapsible(pos, false); + q.widget->setEnabled(!(q.flags & FLAG_DISABLED)); } -static void clearSplitter(QSplitter &splitter) +void MainWindow::setQuadrantWidgets(QSplitter &splitter, const Quadrant &left, const Quadrant &right) { - // Qt's ownership model is absolutely hare-brained. - // To remove a widget from a splitter, you reparent it, which - // informs the splitter via a signal. Wow. - while (splitter.count() > 0) - splitter.widget(0)->setParent(nullptr); -} + int num = (left.widget != nullptr) + (right.widget != nullptr); + // Remove superfluous widgets by reparenting to null. + while (splitter.count() > num) + splitter.widget(splitter.count() - 1)->setParent(nullptr); -void MainWindow::clearSplitters() -{ - clearSplitter(*topSplitter); - clearSplitter(*bottomSplitter); - clearSplitter(*ui.mainSplitter); + setQuadrantWidget(splitter, left, 0); + setQuadrantWidget(splitter, right, left.widget != nullptr ? 1 : 0); } bool MainWindow::userMayChangeAppState() const @@ -1614,19 +1623,34 @@ void MainWindow::setApplicationState(ApplicationState state) setAppState(state); - clearSplitters(); + clearSplitter(*topSplitter); + clearSplitter(*bottomSplitter); const Quadrants &quadrants = applicationState[(int)state]; - setQuadrantWidget(quadrants.topLeft, *topSplitter); - setQuadrantWidget(quadrants.topRight, *topSplitter); - setQuadrantWidget(quadrants.bottomLeft, *bottomSplitter); - setQuadrantWidget(quadrants.bottomRight, *bottomSplitter); + setQuadrantWidgets(*topSplitter, quadrants.topLeft, quadrants.topRight); + setQuadrantWidgets(*bottomSplitter, quadrants.bottomLeft, quadrants.bottomRight); + if (topSplitter->count() >= 1) { - ui.mainSplitter->addWidget(topSplitter.get()); - ui.mainSplitter->setCollapsible(ui.mainSplitter->count() - 1, false); + // Add topSplitter if it is not already shown + if (ui.mainSplitter->count() == 0 || + ui.mainSplitter->widget(0) != topSplitter.get()) { + ui.mainSplitter->insertWidget(0, topSplitter.get()); + ui.mainSplitter->setCollapsible(ui.mainSplitter->count() - 1, false); + } + } else { + // Remove topSplitter by reparenting it. So weird. + topSplitter->setParent(nullptr); } + if (bottomSplitter->count() >= 1) { - ui.mainSplitter->addWidget(bottomSplitter.get()); - ui.mainSplitter->setCollapsible(ui.mainSplitter->count() - 1, false); + // Add bottomSplitter if it is not already shown + if (ui.mainSplitter->count() == 0 || + ui.mainSplitter->widget(ui.mainSplitter->count() - 1) != bottomSplitter.get()) { + ui.mainSplitter->addWidget(bottomSplitter.get()); + ui.mainSplitter->setCollapsible(ui.mainSplitter->count() - 1, false); + } + } else { + // Remove bottomSplitter by reparenting it. So weird. + bottomSplitter->setParent(nullptr); } restoreSplitterSizes(); diff --git a/desktop-widgets/mainwindow.h b/desktop-widgets/mainwindow.h index 617e53a09..ae8e11740 100644 --- a/desktop-widgets/mainwindow.h +++ b/desktop-widgets/mainwindow.h @@ -184,7 +184,6 @@ private: void saveSplitterSizes(); void restoreSplitterSizes(); void updateLastUsedDir(const QString &s); - void clearSplitters(); bool filesAsArguments; UpdateManager *updateManager; std::unique_ptr<LocationInformationWidget> diveSiteEdit; @@ -220,7 +219,8 @@ private: Quadrants applicationState[(size_t)ApplicationState::Count]; static void addWidgets(const Quadrant &); bool userMayChangeAppState() const; - void setQuadrantWidget(const Quadrant &q, QSplitter &splitter); + void setQuadrantWidget(QSplitter &splitter, const Quadrant &q, int pos); + void setQuadrantWidgets(QSplitter &splitter, const Quadrant &left, const Quadrant &right); void registerApplicationState(ApplicationState state, Quadrants q); QMenu *connections; |