From 70e5bd1bfd6ba12c285969550e6c24a3e13537b9 Mon Sep 17 00:00:00 2001 From: fourtf Date: Fri, 21 Feb 2020 01:59:58 +0100 Subject: [PATCH] lazily initialize settings pages --- src/widgets/dialogs/SettingsDialog.cpp | 61 +++++++++---------- src/widgets/dialogs/SettingsDialog.hpp | 5 +- src/widgets/helper/SettingsDialogTab.cpp | 18 +++++- src/widgets/helper/SettingsDialogTab.hpp | 15 +++-- src/widgets/settingspages/AboutPage.cpp | 1 - src/widgets/settingspages/AccountsPage.cpp | 1 - src/widgets/settingspages/CommandPage.cpp | 1 - .../settingspages/ExternalToolsPage.cpp | 1 - src/widgets/settingspages/GeneralPage.cpp | 5 +- .../settingspages/HighlightingPage.cpp | 1 - src/widgets/settingspages/IgnoresPage.cpp | 1 - .../settingspages/KeyboardSettingsPage.cpp | 1 - src/widgets/settingspages/ModerationPage.cpp | 1 - .../settingspages/NotificationPage.cpp | 1 - src/widgets/settingspages/SettingsPage.cpp | 11 +--- src/widgets/settingspages/SettingsPage.hpp | 5 +- 16 files changed, 63 insertions(+), 66 deletions(-) diff --git a/src/widgets/dialogs/SettingsDialog.cpp b/src/widgets/dialogs/SettingsDialog.cpp index 8deaa830c..a3dbf3455 100644 --- a/src/widgets/dialogs/SettingsDialog.cpp +++ b/src/widgets/dialogs/SettingsDialog.cpp @@ -107,7 +107,8 @@ void SettingsDialog::filterElements(const QString &text) for (auto &&tab : this->tabs_) { // filterElements returns true if anything on the page matches the search query - tab->setVisible(tab->page()->filterElements(text)); + tab->setVisible(tab->name().contains(text, Qt::CaseInsensitive) || + tab->page()->filterElements(text)); } // find next visible page @@ -157,36 +158,30 @@ void SettingsDialog::addTabs() this->ui_.tabContainer->setContentsMargins(0, 20, 0, 20); - this->addTab(new GeneralPage, ":/settings/about.svg"); - + // clang-format off + this->addTab([]{return new GeneralPage;}, "General", ":/settings/about.svg"); this->ui_.tabContainer->addSpacing(16); - - this->addTab(new AccountsPage, ":/settings/accounts.svg"); - + this->addTab([]{return new AccountsPage;}, "Accounts", ":/settings/accounts.svg"); this->ui_.tabContainer->addSpacing(16); - - this->addTab(new CommandPage, ":/settings/commands.svg"); - this->addTab(new HighlightingPage, ":/settings/notifications.svg"); - this->addTab(new IgnoresPage, ":/settings/ignore.svg"); - + this->addTab([]{return new CommandPage;}, "Commands", ":/settings/commands.svg"); + this->addTab([]{return new HighlightingPage;}, "Highlights", ":/settings/notifications.svg"); + this->addTab([]{return new IgnoresPage;}, "Ignores", ":/settings/ignore.svg"); this->ui_.tabContainer->addSpacing(16); - - this->addTab(new KeyboardSettingsPage, ":/settings/keybinds.svg"); - this->addTab(new ModerationPage, ":/settings/moderation.svg"); - this->addTab(new NotificationPage, ":/settings/notification2.svg"); - this->addTab(new ExternalToolsPage, ":/settings/externaltools.svg"); - + this->addTab([]{return new KeyboardSettingsPage;}, "Keybindings", ":/settings/keybinds.svg"); + this->addTab([]{return new ModerationPage;}, "Moderation", ":/settings/moderation.svg"); + this->addTab([]{return new NotificationPage;}, "Notifications", ":/settings/notification2.svg"); + this->addTab([]{return new ExternalToolsPage;}, "External tools", ":/settings/externaltools.svg"); this->ui_.tabContainer->addStretch(1); - this->addTab(new AboutPage, ":/settings/about.svg", Qt::AlignBottom); + this->addTab([]{return new AboutPage;}, "About", ":/settings/about.svg", Qt::AlignBottom); + // clang-format on } -void SettingsDialog::addTab(SettingsPage *page, const QString &iconPath, +void SettingsDialog::addTab(std::function page, + const QString &name, const QString &iconPath, Qt::Alignment alignment) { - auto tab = new SettingsDialogTab(this, page, iconPath); - page->setTab(tab); + auto tab = new SettingsDialogTab(this, std::move(page), name, iconPath); - this->ui_.pageStack->addWidget(page); this->ui_.tabContainer->addWidget(tab, 0, alignment); this->tabs_.push_back(tab); @@ -198,6 +193,15 @@ void SettingsDialog::addTab(SettingsPage *page, const QString &iconPath, void SettingsDialog::selectTab(SettingsDialogTab *tab, bool byUser) { + // add page if it's not been added yet + [&] { + for (int i = 0; i < this->ui_.pageStack->count(); i++) + if (this->ui_.pageStack->itemAt(i)->widget() == tab->page()) + return; + + this->ui_.pageStack->addWidget(tab->page()); + }(); + this->ui_.pageStack->setCurrentWidget(tab->page()); if (this->selectedTab_ != nullptr) @@ -231,18 +235,13 @@ SettingsDialogTab *SettingsDialog::tab(SettingsTabId id) return nullptr; } -void SettingsDialog::selectPage(SettingsPage *page) -{ - assert(page); - assert(page->tab()); - - this->selectTab(page->tab()); -} - void SettingsDialog::showDialog(SettingsDialogPreference preferredTab) { static SettingsDialog *instance = new SettingsDialog(); - instance->refresh(); + static bool hasShownBefore = false; + if (hasShownBefore) + instance->refresh(); + hasShownBefore = true; switch (preferredTab) { diff --git a/src/widgets/dialogs/SettingsDialog.hpp b/src/widgets/dialogs/SettingsDialog.hpp index 6e282d130..84cdb98de 100644 --- a/src/widgets/dialogs/SettingsDialog.hpp +++ b/src/widgets/dialogs/SettingsDialog.hpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include "widgets/helper/SettingsDialogTab.hpp" @@ -49,10 +50,10 @@ private: void initUi(); void addTabs(); - void addTab(SettingsPage *page, const QString &iconPath, + void addTab(std::function page, const QString &name, + const QString &iconPath, Qt::Alignment alignment = Qt::AlignTop); void selectTab(SettingsDialogTab *tab, const bool byUser = true); - void selectPage(SettingsPage *page); void selectTab(SettingsTabId id); SettingsDialogTab *tab(SettingsTabId id); void filterElements(const QString &query); diff --git a/src/widgets/helper/SettingsDialogTab.cpp b/src/widgets/helper/SettingsDialogTab.cpp index a5bc7145f..5ad366ab1 100644 --- a/src/widgets/helper/SettingsDialogTab.cpp +++ b/src/widgets/helper/SettingsDialogTab.cpp @@ -8,14 +8,16 @@ namespace chatterino { SettingsDialogTab::SettingsDialogTab(SettingsDialog *_dialog, - SettingsPage *_page, QString imageFileName, + std::function _lazyPage, + const QString &name, QString imageFileName, SettingsTabId id) : BaseWidget(_dialog) , dialog_(_dialog) - , page_(_page) + , lazyPage_(std::move(_lazyPage)) , id_(id) + , name_(name) { - this->ui_.labelText = page_->getName(); + this->ui_.labelText = name; this->ui_.icon.addFile(imageFileName); this->setCursor(QCursor(Qt::PointingHandCursor)); @@ -38,6 +40,11 @@ void SettingsDialogTab::setSelected(bool _selected) SettingsPage *SettingsDialogTab::page() { + if (this->page_) + return this->page_; + + this->page_ = this->lazyPage_(); + this->page_->setTab(this); return this->page_; } @@ -74,6 +81,11 @@ void SettingsDialogTab::mousePressEvent(QMouseEvent *event) this->setFocus(); } +const QString &SettingsDialogTab::name() const +{ + return name_; +} + SettingsTabId SettingsDialogTab::id() const { return id_; diff --git a/src/widgets/helper/SettingsDialogTab.hpp b/src/widgets/helper/SettingsDialogTab.hpp index 29b994785..49dc9ff23 100644 --- a/src/widgets/helper/SettingsDialogTab.hpp +++ b/src/widgets/helper/SettingsDialogTab.hpp @@ -5,6 +5,7 @@ #include #include #include +#include namespace chatterino { @@ -22,13 +23,17 @@ class SettingsDialogTab : public BaseWidget Q_OBJECT public: - SettingsDialogTab(SettingsDialog *dialog_, SettingsPage *page_, - QString imageFileName, SettingsTabId id = {}); + SettingsDialogTab(SettingsDialog *dialog_, + std::function page_, + const QString &name, QString imageFileName, + SettingsTabId id = {}); void setSelected(bool selected_); SettingsPage *page(); SettingsTabId id() const; + const QString &name() const; + signals: void selectedChanged(bool); @@ -42,9 +47,11 @@ private: } ui_; // Parent settings dialog - SettingsDialog *dialog_; - SettingsPage *page_; + SettingsDialog *dialog_{}; + SettingsPage *page_{}; + std::function lazyPage_; SettingsTabId id_; + QString name_; bool selected_ = false; }; diff --git a/src/widgets/settingspages/AboutPage.cpp b/src/widgets/settingspages/AboutPage.cpp index 1371bbee6..4a51feda0 100644 --- a/src/widgets/settingspages/AboutPage.cpp +++ b/src/widgets/settingspages/AboutPage.cpp @@ -18,7 +18,6 @@ namespace chatterino { AboutPage::AboutPage() - : SettingsPage("About") { LayoutCreator layoutCreator(this); diff --git a/src/widgets/settingspages/AccountsPage.cpp b/src/widgets/settingspages/AccountsPage.cpp index 1969e3fc7..555738771 100644 --- a/src/widgets/settingspages/AccountsPage.cpp +++ b/src/widgets/settingspages/AccountsPage.cpp @@ -17,7 +17,6 @@ namespace chatterino { AccountsPage::AccountsPage() - : SettingsPage("Accounts") { auto *app = getApp(); diff --git a/src/widgets/settingspages/CommandPage.cpp b/src/widgets/settingspages/CommandPage.cpp index d565a10f3..99b83ec90 100644 --- a/src/widgets/settingspages/CommandPage.cpp +++ b/src/widgets/settingspages/CommandPage.cpp @@ -33,7 +33,6 @@ namespace { } // namespace CommandPage::CommandPage() - : SettingsPage("Commands") { auto app = getApp(); diff --git a/src/widgets/settingspages/ExternalToolsPage.cpp b/src/widgets/settingspages/ExternalToolsPage.cpp index f7aad15b5..648af25ba 100644 --- a/src/widgets/settingspages/ExternalToolsPage.cpp +++ b/src/widgets/settingspages/ExternalToolsPage.cpp @@ -12,7 +12,6 @@ namespace chatterino { ExternalToolsPage::ExternalToolsPage() - : SettingsPage("External tools") { LayoutCreator layoutCreator(this); auto layout = layoutCreator.setLayoutType(); diff --git a/src/widgets/settingspages/GeneralPage.cpp b/src/widgets/settingspages/GeneralPage.cpp index 38b3b4e35..bbc972a73 100644 --- a/src/widgets/settingspages/GeneralPage.cpp +++ b/src/widgets/settingspages/GeneralPage.cpp @@ -237,7 +237,6 @@ bool SettingsLayout::filterElements(const QString &query) } GeneralPage::GeneralPage() - : SettingsPage("General") { auto y = new QVBoxLayout; auto scroll = new QScrollArea; @@ -263,9 +262,7 @@ GeneralPage::GeneralPage() bool GeneralPage::filterElements(const QString &query) { if (this->settingsLayout_) - return this->settingsLayout_->filterElements(query) || - this->name_.contains(query, Qt::CaseInsensitive) || - query.isEmpty(); + return this->settingsLayout_->filterElements(query) || query.isEmpty(); else return false; } diff --git a/src/widgets/settingspages/HighlightingPage.cpp b/src/widgets/settingspages/HighlightingPage.cpp index 05a71bd75..2612454be 100644 --- a/src/widgets/settingspages/HighlightingPage.cpp +++ b/src/widgets/settingspages/HighlightingPage.cpp @@ -29,7 +29,6 @@ namespace chatterino { HighlightingPage::HighlightingPage() - : SettingsPage("Highlights") { auto app = getApp(); LayoutCreator layoutCreator(this); diff --git a/src/widgets/settingspages/IgnoresPage.cpp b/src/widgets/settingspages/IgnoresPage.cpp index af36ecad2..9cc657880 100644 --- a/src/widgets/settingspages/IgnoresPage.cpp +++ b/src/widgets/settingspages/IgnoresPage.cpp @@ -29,7 +29,6 @@ static void addUsersTab(IgnoresPage &page, LayoutCreator box, QStringListModel &model); IgnoresPage::IgnoresPage() - : SettingsPage("Ignores") { LayoutCreator layoutCreator(this); auto layout = layoutCreator.setLayoutType(); diff --git a/src/widgets/settingspages/KeyboardSettingsPage.cpp b/src/widgets/settingspages/KeyboardSettingsPage.cpp index 0dd557a75..d09bb97d1 100644 --- a/src/widgets/settingspages/KeyboardSettingsPage.cpp +++ b/src/widgets/settingspages/KeyboardSettingsPage.cpp @@ -8,7 +8,6 @@ namespace chatterino { KeyboardSettingsPage::KeyboardSettingsPage() - : SettingsPage("Keybindings") { auto layout = LayoutCreator(this).setLayoutType(); diff --git a/src/widgets/settingspages/ModerationPage.cpp b/src/widgets/settingspages/ModerationPage.cpp index 88d8ac9eb..479d0a7cb 100644 --- a/src/widgets/settingspages/ModerationPage.cpp +++ b/src/widgets/settingspages/ModerationPage.cpp @@ -73,7 +73,6 @@ QString fetchLogDirectorySize() } ModerationPage::ModerationPage() - : SettingsPage("Moderation") { auto app = getApp(); LayoutCreator layoutCreator(this); diff --git a/src/widgets/settingspages/NotificationPage.cpp b/src/widgets/settingspages/NotificationPage.cpp index 968c34f54..27c1da4b5 100644 --- a/src/widgets/settingspages/NotificationPage.cpp +++ b/src/widgets/settingspages/NotificationPage.cpp @@ -21,7 +21,6 @@ namespace chatterino { NotificationPage::NotificationPage() - : SettingsPage("Notifications") { LayoutCreator layoutCreator(this); auto layout = layoutCreator.emplace().withoutMargin(); diff --git a/src/widgets/settingspages/SettingsPage.cpp b/src/widgets/settingspages/SettingsPage.cpp index 40f6e049b..78b9d9387 100644 --- a/src/widgets/settingspages/SettingsPage.cpp +++ b/src/widgets/settingspages/SettingsPage.cpp @@ -64,20 +64,13 @@ bool filterItemsRec(QObject *object, const QString &query) return any; } -SettingsPage::SettingsPage(const QString &name) - : name_(name) +SettingsPage::SettingsPage() { } bool SettingsPage::filterElements(const QString &query) { - return filterItemsRec(this, query) || query.isEmpty() || - this->name_.contains(query, Qt::CaseInsensitive); -} - -const QString &SettingsPage::getName() -{ - return this->name_; + return filterItemsRec(this, query) || query.isEmpty(); } SettingsDialogTab *SettingsPage::tab() const diff --git a/src/widgets/settingspages/SettingsPage.hpp b/src/widgets/settingspages/SettingsPage.hpp index eeb8b9609..d3a9ee111 100644 --- a/src/widgets/settingspages/SettingsPage.hpp +++ b/src/widgets/settingspages/SettingsPage.hpp @@ -47,9 +47,7 @@ class SettingsPage : public QFrame Q_OBJECT public: - SettingsPage(const QString &name); - - const QString &getName(); + SettingsPage(); virtual bool filterElements(const QString &query); @@ -71,7 +69,6 @@ public: } protected: - QString name_; SettingsDialogTab *tab_; pajlada::Signals::NoArgSignal onCancel_; std::vector managedConnections_;