added category navigation to general settings

This commit is contained in:
fourtf 2020-10-22 23:17:31 +02:00
parent 4d676b4c51
commit 0ecea8ad83
9 changed files with 512 additions and 397 deletions

View file

@ -224,6 +224,7 @@ SOURCES += \
src/util/IncognitoBrowser.cpp \
src/util/InitUpdateButton.cpp \
src/util/JsonQuery.cpp \
src/util/LayoutHelper.cpp \
src/util/NuulsUploader.cpp \
src/util/RapidjsonHelpers.cpp \
src/util/StreamerMode.cpp \
@ -283,6 +284,7 @@ SOURCES += \
src/widgets/settingspages/ExternalToolsPage.cpp \
src/widgets/settingspages/FiltersPage.cpp \
src/widgets/settingspages/GeneralPage.cpp \
src/widgets/settingspages/GeneralPageView.cpp \
src/widgets/settingspages/HighlightingPage.cpp \
src/widgets/settingspages/IgnoresPage.cpp \
src/widgets/settingspages/KeyboardSettingsPage.cpp \
@ -534,6 +536,7 @@ HEADERS += \
src/widgets/settingspages/ExternalToolsPage.hpp \
src/widgets/settingspages/FiltersPage.hpp \
src/widgets/settingspages/GeneralPage.hpp \
src/widgets/settingspages/GeneralPageView.hpp \
src/widgets/settingspages/HighlightingPage.hpp \
src/widgets/settingspages/IgnoresPage.hpp \
src/widgets/settingspages/KeyboardSettingsPage.hpp \

View file

@ -16,7 +16,6 @@ QScrollArea {
}
QScrollArea QFrame {
background: #222;
border: none;
}
@ -27,8 +26,6 @@ QComboBox QFrame {
chatterino--SettingsPage {
background: #222;
/*border: 1px solid #555;
border-left: none;*/
}
chatterino--PageHeader {

View file

@ -1,13 +1,18 @@
#pragma once
#include <QLayout>
#include <QWidget>
#include <boost/variant.hpp>
class QWidget;
class QScrollArea;
namespace chatterino {
using LayoutItem = boost::variant<QWidget *, QLayout *>;
QWidget *wrapLayout(QLayout *layout);
QScrollArea *makeScrollArea(LayoutItem item);
template <typename T>
T *makeLayout(std::initializer_list<LayoutItem> items)
{
@ -26,9 +31,19 @@ T *makeLayout(std::initializer_list<LayoutItem> items)
}
}
t->setContentsMargins(0, 0, 0, 0);
return t;
}
template <typename T>
T *makeStretchingLayout(std::initializer_list<LayoutItem> items)
{
auto layout = makeLayout<T>(items);
layout->addStretch(1);
return layout;
}
template <typename T, typename With>
T *makeWidget(With with)
{

View file

@ -16,7 +16,7 @@ void SignalLabel::mousePressEvent(QMouseEvent *event)
{
if (event->button() == Qt::LeftButton)
{
emit mouseDown();
emit leftMouseDown();
}
event->ignore();
@ -26,7 +26,7 @@ void SignalLabel::mouseReleaseEvent(QMouseEvent *event)
{
if (event->button() == Qt::LeftButton)
{
emit mouseUp();
emit leftMouseUp();
}
event->ignore();

View file

@ -18,8 +18,8 @@ public:
signals:
void mouseDoubleClick(QMouseEvent *ev);
void mouseDown();
void mouseUp();
void leftMouseDown();
void leftMouseUp();
void mouseMove(QMouseEvent *event);
protected:

View file

@ -15,9 +15,8 @@
#include "util/IncognitoBrowser.hpp"
#include "util/StreamerMode.hpp"
#include "widgets/BaseWindow.hpp"
#include "widgets/dialogs/ColorPickerDialog.hpp"
#include "widgets/helper/ColorButton.hpp"
#include "widgets/helper/Line.hpp"
#include "widgets/settingspages/GeneralPageView.hpp"
#define CHROME_EXTENSION_LINK \
"https://chrome.google.com/webstore/detail/chatterino-native-host/" \
@ -36,7 +35,7 @@
namespace chatterino {
namespace {
void addKeyboardModifierSetting(SettingsLayout &layout,
void addKeyboardModifierSetting(GeneralPageView &layout,
const QString &title,
EnumSetting<Qt::KeyboardModifier> &setting)
{
@ -76,239 +75,32 @@ namespace {
}
} // namespace
TitleLabel *SettingsLayout::addTitle(const QString &title)
{
// space
if (!this->groups_.empty())
this->addWidget(this->groups_.back().space = new Space);
// title
auto label = new TitleLabel(title + ":");
this->addWidget(label);
// groups
this->groups_.push_back(Group{title, label, nullptr, {}});
return label;
}
QCheckBox *SettingsLayout::addCheckbox(const QString &text,
BoolSetting &setting, bool inverse)
{
auto check = new QCheckBox(text);
// update when setting changes
setting.connect(
[inverse, check](const bool &value, auto) {
check->setChecked(inverse ^ value);
},
this->managedConnections_);
// update setting on toggle
QObject::connect(
check, &QCheckBox::toggled, this,
[&setting, inverse](bool state) { setting = inverse ^ state; });
this->addWidget(check);
// groups
this->groups_.back().widgets.push_back({check, {text}});
return check;
}
ComboBox *SettingsLayout::addDropdown(const QString &text,
const QStringList &list)
{
auto layout = new QHBoxLayout;
auto combo = new ComboBox;
combo->setFocusPolicy(Qt::StrongFocus);
combo->addItems(list);
auto label = new QLabel(text + ":");
layout->addWidget(label);
layout->addStretch(1);
layout->addWidget(combo);
this->addLayout(layout);
// groups
this->groups_.back().widgets.push_back({combo, {text}});
this->groups_.back().widgets.push_back({label, {text}});
return combo;
}
ComboBox *SettingsLayout::addDropdown(
const QString &text, const QStringList &items,
pajlada::Settings::Setting<QString> &setting, bool editable)
{
auto combo = this->addDropdown(text, items);
if (editable)
combo->setEditable(true);
// update when setting changes
setting.connect(
[combo](const QString &value, auto) { combo->setCurrentText(value); },
this->managedConnections_);
QObject::connect(combo, &QComboBox::currentTextChanged,
[&setting](const QString &newValue) {
setting = newValue;
getApp()->windows->forceLayoutChannelViews();
});
return combo;
}
ColorButton *SettingsLayout::addColorButton(
const QString &text, const QColor &color,
pajlada::Settings::Setting<QString> &setting)
{
auto colorButton = new ColorButton(color);
auto layout = new QHBoxLayout();
auto label = new QLabel(text + ":");
layout->addWidget(label);
layout->addStretch(1);
layout->addWidget(colorButton);
this->addLayout(layout);
QObject::connect(
colorButton, &ColorButton::clicked, [&setting, colorButton]() {
auto dialog = new ColorPickerDialog(QColor(setting));
dialog->setAttribute(Qt::WA_DeleteOnClose);
dialog->show();
dialog->closed.connect([&setting, colorButton, &dialog] {
QColor selected = dialog->selectedColor();
if (selected.isValid())
{
setting = selected.name(QColor::HexArgb);
colorButton->setColor(selected);
}
});
});
this->groups_.back().widgets.push_back({label, {text}});
this->groups_.back().widgets.push_back({colorButton, {text}});
return colorButton;
}
DescriptionLabel *SettingsLayout::addDescription(const QString &text)
{
auto label = new DescriptionLabel(text);
label->setTextInteractionFlags(Qt::TextBrowserInteraction |
Qt::LinksAccessibleByKeyboard);
label->setOpenExternalLinks(true);
label->setWordWrap(true);
this->addWidget(label);
// groups
this->groups_.back().widgets.push_back({label, {text}});
return label;
}
void SettingsLayout::addSeperator()
{
this->addWidget(new Line(false));
}
bool SettingsLayout::filterElements(const QString &query)
{
bool any{};
for (auto &&group : this->groups_)
{
// if a description in a group matches `query` then show the entire group
bool descriptionMatches{};
for (auto &&widget : group.widgets)
{
if (auto x = dynamic_cast<DescriptionLabel *>(widget.element); x)
{
if (x->text().contains(query, Qt::CaseInsensitive))
{
descriptionMatches = true;
break;
}
}
}
// if group name matches then all should be visible
if (group.name.contains(query, Qt::CaseInsensitive) ||
descriptionMatches)
{
for (auto &&widget : group.widgets)
widget.element->show();
group.title->show();
any = true;
}
// check if any match
else
{
auto groupAny = false;
for (auto &&widget : group.widgets)
{
for (auto &&keyword : widget.keywords)
{
if (keyword.contains(query, Qt::CaseInsensitive))
{
widget.element->show();
groupAny = true;
}
else
{
widget.element->hide();
}
}
}
if (group.space)
group.space->setVisible(groupAny);
group.title->setVisible(groupAny);
any |= groupAny;
}
}
return any;
}
GeneralPage::GeneralPage()
{
auto y = new QVBoxLayout;
auto scroll = new QScrollArea;
scroll->setWidgetResizable(true);
y->addWidget(scroll);
auto x = new QHBoxLayout;
auto layout = new SettingsLayout;
this->settingsLayout_ = layout;
x->addLayout(layout, 0);
x->addStretch(1);
auto view = new GeneralPageView;
this->view_ = view;
x->addWidget(view);
auto z = new QFrame;
z->setLayout(x);
scroll->setWidget(z);
y->addWidget(z);
this->setLayout(y);
this->initLayout(*layout);
layout->addStretch(1);
this->initLayout(*view);
this->initExtra();
}
bool GeneralPage::filterElements(const QString &query)
{
if (this->settingsLayout_)
return this->settingsLayout_->filterElements(query) || query.isEmpty();
if (this->view_)
return this->view_->filterElements(query) || query.isEmpty();
else
return false;
}
void GeneralPage::initLayout(SettingsLayout &layout)
void GeneralPage::initLayout(GeneralPageView &layout)
{
auto &s = *getSettings();

View file

@ -1,15 +1,5 @@
#pragma once
#include <QDebug>
#include <QLabel>
#include <QVBoxLayout>
#include "Application.hpp"
#include "boost/variant.hpp"
#include "pajlada/signals/signal.hpp"
#include "singletons/Settings.hpp"
#include "singletons/WindowManager.hpp"
#include "widgets/helper/ColorButton.hpp"
#include "widgets/settingspages/SettingsPage.hpp"
class QLabel;
@ -18,165 +8,9 @@ class QComboBox;
namespace chatterino {
class Space : public QLabel
{
Q_OBJECT
};
class TitleLabel : public QLabel
{
Q_OBJECT
public:
TitleLabel(const QString &text)
: QLabel(text)
{
}
};
class DescriptionLabel : public QLabel
{
Q_OBJECT
public:
DescriptionLabel(const QString &text)
: QLabel(text)
{
}
};
struct DropdownArgs {
QString value;
int index;
QComboBox *combobox;
};
class ComboBox : public QComboBox
{
Q_OBJECT
void wheelEvent(QWheelEvent *event) override
{
}
};
class SettingsLayout : public QVBoxLayout
{
Q_OBJECT
public:
TitleLabel *addTitle(const QString &text);
/// @param inverse Inverses true to false and vice versa
QCheckBox *addCheckbox(const QString &text, BoolSetting &setting,
bool inverse = false);
ComboBox *addDropdown(const QString &text, const QStringList &items);
ComboBox *addDropdown(const QString &text, const QStringList &items,
pajlada::Settings::Setting<QString> &setting,
bool editable = false);
ColorButton *addColorButton(const QString &text, const QColor &color,
pajlada::Settings::Setting<QString> &setting);
template <typename OnClick>
QPushButton *makeButton(const QString &text, OnClick onClick)
{
auto button = new QPushButton(text);
this->groups_.back().widgets.push_back({button, {text}});
QObject::connect(button, &QPushButton::clicked, onClick);
return button;
}
template <typename OnClick>
QPushButton *addButton(const QString &text, OnClick onClick)
{
auto button = makeButton(text, onClick);
auto layout = new QHBoxLayout();
layout->addWidget(button);
layout->addStretch(1);
this->addLayout(layout);
return button;
}
template <typename T>
ComboBox *addDropdown(
const QString &text, const QStringList &items,
pajlada::Settings::Setting<T> &setting,
std::function<boost::variant<int, QString>(T)> getValue,
std::function<T(DropdownArgs)> setValue, bool editable = true)
{
auto items2 = items;
auto selected = getValue(setting.getValue());
if (selected.which() == 1)
{
// QString
if (!editable && !items2.contains(boost::get<QString>(selected)))
items2.insert(0, boost::get<QString>(selected));
}
auto combo = this->addDropdown(text, items2);
if (editable)
combo->setEditable(true);
if (selected.which() == 0)
{
// int
auto value = boost::get<int>(selected);
if (value >= 0 && value < items2.size())
combo->setCurrentIndex(value);
}
else if (selected.which() == 1)
{
// QString
combo->setEditText(boost::get<QString>(selected));
}
setting.connect(
[getValue = std::move(getValue), combo](const T &value, auto) {
auto var = getValue(value);
if (var.which() == 0)
combo->setCurrentIndex(boost::get<int>(var));
else
{
combo->setCurrentText(boost::get<QString>(var));
combo->setEditText(boost::get<QString>(var));
}
},
this->managedConnections_);
QObject::connect(
combo,
QOverload<const QString &>::of(&QComboBox::currentIndexChanged),
// &QComboBox::editTextChanged,
[combo, &setting,
setValue = std::move(setValue)](const QString &newValue) {
setting = setValue(
DropdownArgs{newValue, combo->currentIndex(), combo});
getApp()->windows->forceLayoutChannelViews();
});
return combo;
}
DescriptionLabel *addDescription(const QString &text);
void addSeperator();
bool filterElements(const QString &query);
private:
struct Widget {
QWidget *element;
QStringList keywords;
};
struct Group {
QString name;
QWidget *title{};
Space *space{};
std::vector<Widget> widgets;
};
std::vector<Group> groups_;
std::vector<pajlada::Signals::ScopedConnection> managedConnections_;
};
class GeneralPageView;
class DescriptionLabel;
struct DropdownArgs;
class GeneralPage : public SettingsPage
{
@ -188,13 +22,13 @@ public:
bool filterElements(const QString &query);
private:
void initLayout(SettingsLayout &layout);
void initLayout(GeneralPageView &layout);
void initExtra();
QString getFont(const DropdownArgs &args) const;
DescriptionLabel *cachePath_{};
SettingsLayout *settingsLayout_{};
GeneralPageView *view_{};
};
} // namespace chatterino

View file

@ -0,0 +1,270 @@
#include "GeneralPageView.hpp"
#include <QScrollBar>
#include "singletons/Settings.hpp"
#include "singletons/WindowManager.hpp"
#include "util/LayoutHelper.hpp"
#include "widgets/dialogs/ColorPickerDialog.hpp"
#include "widgets/helper/ColorButton.hpp"
#include "widgets/helper/Line.hpp"
namespace chatterino {
GeneralPageView::GeneralPageView(QWidget *parent)
: QWidget(parent)
{
auto scrollArea = this->contentScrollArea_ =
makeScrollArea(this->contentLayout_ = new QVBoxLayout);
auto navigation =
wrapLayout(this->navigationLayout_ = makeLayout<QVBoxLayout>({}));
this->setLayout(makeLayout<QHBoxLayout>({scrollArea, navigation}));
QObject::connect(scrollArea->verticalScrollBar(), &QScrollBar::valueChanged,
this, [=] { this->updateNavigationHighlighting(); });
}
void GeneralPageView::addWidget(QWidget *widget)
{
this->contentLayout_->addWidget(widget);
}
void GeneralPageView::addLayout(QLayout *layout)
{
this->contentLayout_->addLayout(layout);
}
TitleLabel *GeneralPageView::addTitle(const QString &title)
{
// space
if (!this->groups_.empty())
this->addWidget(this->groups_.back().space = new Space);
// title
auto label = new TitleLabel(title + ":");
this->addWidget(label);
// navigation item
auto navLabel = new NavigationLabel(title);
navLabel->setCursor(Qt::PointingHandCursor);
this->navigationLayout_->addWidget(navLabel);
QObject::connect(navLabel, &NavigationLabel::leftMouseUp, label, [=] {
this->contentScrollArea_->verticalScrollBar()->setValue(label->y());
});
// groups
this->groups_.push_back(Group{title, label, navLabel, nullptr, {}});
if (this->groups_.size() == 1)
this->updateNavigationHighlighting();
return label;
}
QCheckBox *GeneralPageView::addCheckbox(const QString &text,
BoolSetting &setting, bool inverse)
{
auto check = new QCheckBox(text);
// update when setting changes
setting.connect(
[inverse, check](const bool &value, auto) {
check->setChecked(inverse ^ value);
},
this->managedConnections_);
// update setting on toggle
QObject::connect(
check, &QCheckBox::toggled, this,
[&setting, inverse](bool state) { setting = inverse ^ state; });
this->addWidget(check);
// groups
this->groups_.back().widgets.push_back({check, {text}});
return check;
}
ComboBox *GeneralPageView::addDropdown(const QString &text,
const QStringList &list)
{
auto layout = new QHBoxLayout;
auto combo = new ComboBox;
combo->setFocusPolicy(Qt::StrongFocus);
combo->addItems(list);
auto label = new QLabel(text + ":");
layout->addWidget(label);
layout->addStretch(1);
layout->addWidget(combo);
this->addLayout(layout);
// groups
this->groups_.back().widgets.push_back({combo, {text}});
this->groups_.back().widgets.push_back({label, {text}});
return combo;
}
ComboBox *GeneralPageView::addDropdown(
const QString &text, const QStringList &items,
pajlada::Settings::Setting<QString> &setting, bool editable)
{
auto combo = this->addDropdown(text, items);
if (editable)
combo->setEditable(true);
// update when setting changes
setting.connect(
[combo](const QString &value, auto) { combo->setCurrentText(value); },
this->managedConnections_);
QObject::connect(combo, &QComboBox::currentTextChanged,
[&setting](const QString &newValue) {
setting = newValue;
getApp()->windows->forceLayoutChannelViews();
});
return combo;
}
ColorButton *GeneralPageView::addColorButton(
const QString &text, const QColor &color,
pajlada::Settings::Setting<QString> &setting)
{
auto colorButton = new ColorButton(color);
auto layout = new QHBoxLayout();
auto label = new QLabel(text + ":");
layout->addWidget(label);
layout->addStretch(1);
layout->addWidget(colorButton);
this->addLayout(layout);
QObject::connect(
colorButton, &ColorButton::clicked, [&setting, colorButton]() {
auto dialog = new ColorPickerDialog(QColor(setting));
dialog->setAttribute(Qt::WA_DeleteOnClose);
dialog->show();
dialog->closed.connect([&setting, colorButton, &dialog] {
QColor selected = dialog->selectedColor();
if (selected.isValid())
{
setting = selected.name(QColor::HexArgb);
colorButton->setColor(selected);
}
});
});
this->groups_.back().widgets.push_back({label, {text}});
this->groups_.back().widgets.push_back({colorButton, {text}});
return colorButton;
}
DescriptionLabel *GeneralPageView::addDescription(const QString &text)
{
auto label = new DescriptionLabel(text);
label->setTextInteractionFlags(Qt::TextBrowserInteraction |
Qt::LinksAccessibleByKeyboard);
label->setOpenExternalLinks(true);
label->setWordWrap(true);
this->addWidget(label);
// groups
this->groups_.back().widgets.push_back({label, {text}});
return label;
}
void GeneralPageView::addSeperator()
{
this->addWidget(new Line(false));
}
bool GeneralPageView::filterElements(const QString &query)
{
bool any{};
for (auto &&group : this->groups_)
{
// if a description in a group matches `query` then show the entire group
bool descriptionMatches{};
for (auto &&widget : group.widgets)
{
if (auto x = dynamic_cast<DescriptionLabel *>(widget.element); x)
{
if (x->text().contains(query, Qt::CaseInsensitive))
{
descriptionMatches = true;
break;
}
}
}
// if group name matches then all should be visible
if (group.name.contains(query, Qt::CaseInsensitive) ||
descriptionMatches)
{
for (auto &&widget : group.widgets)
widget.element->show();
group.title->show();
any = true;
}
// check if any match
else
{
auto groupAny = false;
for (auto &&widget : group.widgets)
{
for (auto &&keyword : widget.keywords)
{
if (keyword.contains(query, Qt::CaseInsensitive))
{
widget.element->show();
groupAny = true;
}
else
{
widget.element->hide();
}
}
}
if (group.space)
group.space->setVisible(groupAny);
group.title->setVisible(groupAny);
any |= groupAny;
}
}
return any;
}
void GeneralPageView::updateNavigationHighlighting()
{
auto scrollY = this->contentScrollArea_->verticalScrollBar()->value();
auto first = true;
for (auto &&group : this->groups_)
{
if (first && (group.title->geometry().bottom() > scrollY ||
&group == &this->groups_.back()))
{
first = false;
group.navigationLink->setStyleSheet("color: #4FC3F7");
}
else
{
group.navigationLink->setStyleSheet("");
}
}
}
} // namespace chatterino

View file

@ -0,0 +1,204 @@
#pragma once
#include <QDebug>
#include <boost/variant.hpp>
#include "common/ChatterinoSetting.hpp"
#include "widgets/helper/SignalLabel.hpp"
class QScrollArea;
namespace chatterino {
class ColorButton;
class Space : public QLabel
{
Q_OBJECT
};
class TitleLabel : public QLabel
{
Q_OBJECT
public:
TitleLabel(const QString &text)
: QLabel(text)
{
}
};
class NavigationLabel : public SignalLabel
{
Q_OBJECT
public:
NavigationLabel(const QString &text)
: SignalLabel()
{
this->setText(text);
}
};
class DescriptionLabel : public QLabel
{
Q_OBJECT
public:
DescriptionLabel(const QString &text)
: QLabel(text)
{
}
};
class ComboBox : public QComboBox
{
Q_OBJECT
void wheelEvent(QWheelEvent *event) override
{
}
};
struct DropdownArgs {
QString value;
int index;
QComboBox *combobox;
};
class GeneralPageView : public QWidget
{
Q_OBJECT
public:
GeneralPageView(QWidget *parent = nullptr);
void addWidget(QWidget *widget);
void addLayout(QLayout *layout);
TitleLabel *addTitle(const QString &text);
/// @param inverse Inverses true to false and vice versa
QCheckBox *addCheckbox(const QString &text, BoolSetting &setting,
bool inverse = false);
ComboBox *addDropdown(const QString &text, const QStringList &items);
ComboBox *addDropdown(const QString &text, const QStringList &items,
pajlada::Settings::Setting<QString> &setting,
bool editable = false);
ColorButton *addColorButton(const QString &text, const QColor &color,
pajlada::Settings::Setting<QString> &setting);
template <typename OnClick>
QPushButton *makeButton(const QString &text, OnClick onClick)
{
auto button = new QPushButton(text);
this->groups_.back().widgets.push_back({button, {text}});
QObject::connect(button, &QPushButton::clicked, onClick);
return button;
}
template <typename OnClick>
QPushButton *addButton(const QString &text, OnClick onClick)
{
auto button = makeButton(text, onClick);
auto layout = new QHBoxLayout();
layout->addWidget(button);
layout->addStretch(1);
this->addLayout(layout);
return button;
}
template <typename T>
ComboBox *addDropdown(
const QString &text, const QStringList &items,
pajlada::Settings::Setting<T> &setting,
std::function<boost::variant<int, QString>(T)> getValue,
std::function<T(DropdownArgs)> setValue, bool editable = true)
{
auto items2 = items;
auto selected = getValue(setting.getValue());
if (selected.which() == 1)
{
// QString
if (!editable && !items2.contains(boost::get<QString>(selected)))
items2.insert(0, boost::get<QString>(selected));
}
auto combo = this->addDropdown(text, items2);
if (editable)
combo->setEditable(true);
if (selected.which() == 0)
{
// int
auto value = boost::get<int>(selected);
if (value >= 0 && value < items2.size())
combo->setCurrentIndex(value);
}
else if (selected.which() == 1)
{
// QString
combo->setEditText(boost::get<QString>(selected));
}
setting.connect(
[getValue = std::move(getValue), combo](const T &value, auto) {
auto var = getValue(value);
if (var.which() == 0)
combo->setCurrentIndex(boost::get<int>(var));
else
{
combo->setCurrentText(boost::get<QString>(var));
combo->setEditText(boost::get<QString>(var));
}
},
this->managedConnections_);
QObject::connect(
combo,
QOverload<const QString &>::of(&QComboBox::currentIndexChanged),
// &QComboBox::editTextChanged,
[combo, &setting,
setValue = std::move(setValue)](const QString &newValue) {
setting = setValue(
DropdownArgs{newValue, combo->currentIndex(), combo});
getApp()->windows->forceLayoutChannelViews();
});
return combo;
}
DescriptionLabel *addDescription(const QString &text);
void addSeperator();
bool filterElements(const QString &query);
protected:
void resizeEvent(QResizeEvent *ev) override
{
qDebug() << ev->size();
}
private:
void updateNavigationHighlighting();
struct Widget {
QWidget *element;
QStringList keywords;
};
struct Group {
QString name;
QWidget *title{};
QWidget *navigationLink{};
Space *space{};
std::vector<Widget> widgets;
};
QScrollArea *contentScrollArea_;
QVBoxLayout *contentLayout_;
QVBoxLayout *navigationLayout_;
std::vector<Group> groups_;
std::vector<pajlada::Signals::ScopedConnection> managedConnections_;
};
} // namespace chatterino