lazily initialize settings pages

This commit is contained in:
fourtf 2020-02-21 01:59:58 +01:00
parent 78ca0cb84f
commit 70e5bd1bfd
16 changed files with 63 additions and 66 deletions

View file

@ -107,7 +107,8 @@ void SettingsDialog::filterElements(const QString &text)
for (auto &&tab : this->tabs_) for (auto &&tab : this->tabs_)
{ {
// filterElements returns true if anything on the page matches the search query // 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 // find next visible page
@ -157,36 +158,30 @@ void SettingsDialog::addTabs()
this->ui_.tabContainer->setContentsMargins(0, 20, 0, 20); 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->ui_.tabContainer->addSpacing(16);
this->addTab([]{return new AccountsPage;}, "Accounts", ":/settings/accounts.svg");
this->addTab(new AccountsPage, ":/settings/accounts.svg");
this->ui_.tabContainer->addSpacing(16); this->ui_.tabContainer->addSpacing(16);
this->addTab([]{return new CommandPage;}, "Commands", ":/settings/commands.svg");
this->addTab(new CommandPage, ":/settings/commands.svg"); this->addTab([]{return new HighlightingPage;}, "Highlights", ":/settings/notifications.svg");
this->addTab(new HighlightingPage, ":/settings/notifications.svg"); this->addTab([]{return new IgnoresPage;}, "Ignores", ":/settings/ignore.svg");
this->addTab(new IgnoresPage, ":/settings/ignore.svg");
this->ui_.tabContainer->addSpacing(16); this->ui_.tabContainer->addSpacing(16);
this->addTab([]{return new KeyboardSettingsPage;}, "Keybindings", ":/settings/keybinds.svg");
this->addTab(new KeyboardSettingsPage, ":/settings/keybinds.svg"); this->addTab([]{return new ModerationPage;}, "Moderation", ":/settings/moderation.svg");
this->addTab(new ModerationPage, ":/settings/moderation.svg"); this->addTab([]{return new NotificationPage;}, "Notifications", ":/settings/notification2.svg");
this->addTab(new NotificationPage, ":/settings/notification2.svg"); this->addTab([]{return new ExternalToolsPage;}, "External tools", ":/settings/externaltools.svg");
this->addTab(new ExternalToolsPage, ":/settings/externaltools.svg");
this->ui_.tabContainer->addStretch(1); 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<SettingsPage *()> page,
const QString &name, const QString &iconPath,
Qt::Alignment alignment) Qt::Alignment alignment)
{ {
auto tab = new SettingsDialogTab(this, page, iconPath); auto tab = new SettingsDialogTab(this, std::move(page), name, iconPath);
page->setTab(tab);
this->ui_.pageStack->addWidget(page);
this->ui_.tabContainer->addWidget(tab, 0, alignment); this->ui_.tabContainer->addWidget(tab, 0, alignment);
this->tabs_.push_back(tab); this->tabs_.push_back(tab);
@ -198,6 +193,15 @@ void SettingsDialog::addTab(SettingsPage *page, const QString &iconPath,
void SettingsDialog::selectTab(SettingsDialogTab *tab, bool byUser) 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()); this->ui_.pageStack->setCurrentWidget(tab->page());
if (this->selectedTab_ != nullptr) if (this->selectedTab_ != nullptr)
@ -231,18 +235,13 @@ SettingsDialogTab *SettingsDialog::tab(SettingsTabId id)
return nullptr; return nullptr;
} }
void SettingsDialog::selectPage(SettingsPage *page)
{
assert(page);
assert(page->tab());
this->selectTab(page->tab());
}
void SettingsDialog::showDialog(SettingsDialogPreference preferredTab) void SettingsDialog::showDialog(SettingsDialogPreference preferredTab)
{ {
static SettingsDialog *instance = new SettingsDialog(); static SettingsDialog *instance = new SettingsDialog();
instance->refresh(); static bool hasShownBefore = false;
if (hasShownBefore)
instance->refresh();
hasShownBefore = true;
switch (preferredTab) switch (preferredTab)
{ {

View file

@ -6,6 +6,7 @@
#include <QStackedLayout> #include <QStackedLayout>
#include <QVBoxLayout> #include <QVBoxLayout>
#include <QWidget> #include <QWidget>
#include <functional>
#include <pajlada/settings/setting.hpp> #include <pajlada/settings/setting.hpp>
#include "widgets/helper/SettingsDialogTab.hpp" #include "widgets/helper/SettingsDialogTab.hpp"
@ -49,10 +50,10 @@ private:
void initUi(); void initUi();
void addTabs(); void addTabs();
void addTab(SettingsPage *page, const QString &iconPath, void addTab(std::function<SettingsPage *()> page, const QString &name,
const QString &iconPath,
Qt::Alignment alignment = Qt::AlignTop); Qt::Alignment alignment = Qt::AlignTop);
void selectTab(SettingsDialogTab *tab, const bool byUser = true); void selectTab(SettingsDialogTab *tab, const bool byUser = true);
void selectPage(SettingsPage *page);
void selectTab(SettingsTabId id); void selectTab(SettingsTabId id);
SettingsDialogTab *tab(SettingsTabId id); SettingsDialogTab *tab(SettingsTabId id);
void filterElements(const QString &query); void filterElements(const QString &query);

View file

@ -8,14 +8,16 @@
namespace chatterino { namespace chatterino {
SettingsDialogTab::SettingsDialogTab(SettingsDialog *_dialog, SettingsDialogTab::SettingsDialogTab(SettingsDialog *_dialog,
SettingsPage *_page, QString imageFileName, std::function<SettingsPage *()> _lazyPage,
const QString &name, QString imageFileName,
SettingsTabId id) SettingsTabId id)
: BaseWidget(_dialog) : BaseWidget(_dialog)
, dialog_(_dialog) , dialog_(_dialog)
, page_(_page) , lazyPage_(std::move(_lazyPage))
, id_(id) , id_(id)
, name_(name)
{ {
this->ui_.labelText = page_->getName(); this->ui_.labelText = name;
this->ui_.icon.addFile(imageFileName); this->ui_.icon.addFile(imageFileName);
this->setCursor(QCursor(Qt::PointingHandCursor)); this->setCursor(QCursor(Qt::PointingHandCursor));
@ -38,6 +40,11 @@ void SettingsDialogTab::setSelected(bool _selected)
SettingsPage *SettingsDialogTab::page() SettingsPage *SettingsDialogTab::page()
{ {
if (this->page_)
return this->page_;
this->page_ = this->lazyPage_();
this->page_->setTab(this);
return this->page_; return this->page_;
} }
@ -74,6 +81,11 @@ void SettingsDialogTab::mousePressEvent(QMouseEvent *event)
this->setFocus(); this->setFocus();
} }
const QString &SettingsDialogTab::name() const
{
return name_;
}
SettingsTabId SettingsDialogTab::id() const SettingsTabId SettingsDialogTab::id() const
{ {
return id_; return id_;

View file

@ -5,6 +5,7 @@
#include <QIcon> #include <QIcon>
#include <QPaintEvent> #include <QPaintEvent>
#include <QWidget> #include <QWidget>
#include <functional>
namespace chatterino { namespace chatterino {
@ -22,13 +23,17 @@ class SettingsDialogTab : public BaseWidget
Q_OBJECT Q_OBJECT
public: public:
SettingsDialogTab(SettingsDialog *dialog_, SettingsPage *page_, SettingsDialogTab(SettingsDialog *dialog_,
QString imageFileName, SettingsTabId id = {}); std::function<SettingsPage *()> page_,
const QString &name, QString imageFileName,
SettingsTabId id = {});
void setSelected(bool selected_); void setSelected(bool selected_);
SettingsPage *page(); SettingsPage *page();
SettingsTabId id() const; SettingsTabId id() const;
const QString &name() const;
signals: signals:
void selectedChanged(bool); void selectedChanged(bool);
@ -42,9 +47,11 @@ private:
} ui_; } ui_;
// Parent settings dialog // Parent settings dialog
SettingsDialog *dialog_; SettingsDialog *dialog_{};
SettingsPage *page_; SettingsPage *page_{};
std::function<SettingsPage *()> lazyPage_;
SettingsTabId id_; SettingsTabId id_;
QString name_;
bool selected_ = false; bool selected_ = false;
}; };

View file

@ -18,7 +18,6 @@
namespace chatterino { namespace chatterino {
AboutPage::AboutPage() AboutPage::AboutPage()
: SettingsPage("About")
{ {
LayoutCreator<AboutPage> layoutCreator(this); LayoutCreator<AboutPage> layoutCreator(this);

View file

@ -17,7 +17,6 @@
namespace chatterino { namespace chatterino {
AccountsPage::AccountsPage() AccountsPage::AccountsPage()
: SettingsPage("Accounts")
{ {
auto *app = getApp(); auto *app = getApp();

View file

@ -33,7 +33,6 @@ namespace {
} // namespace } // namespace
CommandPage::CommandPage() CommandPage::CommandPage()
: SettingsPage("Commands")
{ {
auto app = getApp(); auto app = getApp();

View file

@ -12,7 +12,6 @@
namespace chatterino { namespace chatterino {
ExternalToolsPage::ExternalToolsPage() ExternalToolsPage::ExternalToolsPage()
: SettingsPage("External tools")
{ {
LayoutCreator<ExternalToolsPage> layoutCreator(this); LayoutCreator<ExternalToolsPage> layoutCreator(this);
auto layout = layoutCreator.setLayoutType<QVBoxLayout>(); auto layout = layoutCreator.setLayoutType<QVBoxLayout>();

View file

@ -237,7 +237,6 @@ bool SettingsLayout::filterElements(const QString &query)
} }
GeneralPage::GeneralPage() GeneralPage::GeneralPage()
: SettingsPage("General")
{ {
auto y = new QVBoxLayout; auto y = new QVBoxLayout;
auto scroll = new QScrollArea; auto scroll = new QScrollArea;
@ -263,9 +262,7 @@ GeneralPage::GeneralPage()
bool GeneralPage::filterElements(const QString &query) bool GeneralPage::filterElements(const QString &query)
{ {
if (this->settingsLayout_) if (this->settingsLayout_)
return this->settingsLayout_->filterElements(query) || return this->settingsLayout_->filterElements(query) || query.isEmpty();
this->name_.contains(query, Qt::CaseInsensitive) ||
query.isEmpty();
else else
return false; return false;
} }

View file

@ -29,7 +29,6 @@
namespace chatterino { namespace chatterino {
HighlightingPage::HighlightingPage() HighlightingPage::HighlightingPage()
: SettingsPage("Highlights")
{ {
auto app = getApp(); auto app = getApp();
LayoutCreator<HighlightingPage> layoutCreator(this); LayoutCreator<HighlightingPage> layoutCreator(this);

View file

@ -29,7 +29,6 @@ static void addUsersTab(IgnoresPage &page, LayoutCreator<QVBoxLayout> box,
QStringListModel &model); QStringListModel &model);
IgnoresPage::IgnoresPage() IgnoresPage::IgnoresPage()
: SettingsPage("Ignores")
{ {
LayoutCreator<IgnoresPage> layoutCreator(this); LayoutCreator<IgnoresPage> layoutCreator(this);
auto layout = layoutCreator.setLayoutType<QVBoxLayout>(); auto layout = layoutCreator.setLayoutType<QVBoxLayout>();

View file

@ -8,7 +8,6 @@
namespace chatterino { namespace chatterino {
KeyboardSettingsPage::KeyboardSettingsPage() KeyboardSettingsPage::KeyboardSettingsPage()
: SettingsPage("Keybindings")
{ {
auto layout = auto layout =
LayoutCreator<KeyboardSettingsPage>(this).setLayoutType<QVBoxLayout>(); LayoutCreator<KeyboardSettingsPage>(this).setLayoutType<QVBoxLayout>();

View file

@ -73,7 +73,6 @@ QString fetchLogDirectorySize()
} }
ModerationPage::ModerationPage() ModerationPage::ModerationPage()
: SettingsPage("Moderation")
{ {
auto app = getApp(); auto app = getApp();
LayoutCreator<ModerationPage> layoutCreator(this); LayoutCreator<ModerationPage> layoutCreator(this);

View file

@ -21,7 +21,6 @@
namespace chatterino { namespace chatterino {
NotificationPage::NotificationPage() NotificationPage::NotificationPage()
: SettingsPage("Notifications")
{ {
LayoutCreator<NotificationPage> layoutCreator(this); LayoutCreator<NotificationPage> layoutCreator(this);
auto layout = layoutCreator.emplace<QVBoxLayout>().withoutMargin(); auto layout = layoutCreator.emplace<QVBoxLayout>().withoutMargin();

View file

@ -64,20 +64,13 @@ bool filterItemsRec(QObject *object, const QString &query)
return any; return any;
} }
SettingsPage::SettingsPage(const QString &name) SettingsPage::SettingsPage()
: name_(name)
{ {
} }
bool SettingsPage::filterElements(const QString &query) bool SettingsPage::filterElements(const QString &query)
{ {
return filterItemsRec(this, query) || query.isEmpty() || return filterItemsRec(this, query) || query.isEmpty();
this->name_.contains(query, Qt::CaseInsensitive);
}
const QString &SettingsPage::getName()
{
return this->name_;
} }
SettingsDialogTab *SettingsPage::tab() const SettingsDialogTab *SettingsPage::tab() const

View file

@ -47,9 +47,7 @@ class SettingsPage : public QFrame
Q_OBJECT Q_OBJECT
public: public:
SettingsPage(const QString &name); SettingsPage();
const QString &getName();
virtual bool filterElements(const QString &query); virtual bool filterElements(const QString &query);
@ -71,7 +69,6 @@ public:
} }
protected: protected:
QString name_;
SettingsDialogTab *tab_; SettingsDialogTab *tab_;
pajlada::Signals::NoArgSignal onCancel_; pajlada::Signals::NoArgSignal onCancel_;
std::vector<pajlada::Signals::ScopedConnection> managedConnections_; std::vector<pajlada::Signals::ScopedConnection> managedConnections_;