mirror of
https://github.com/Chatterino/chatterino2.git
synced 2024-11-21 22:24:07 +01:00
Merge branch 'search-settings'
This commit is contained in:
commit
ab816e18bd
15 changed files with 398 additions and 146 deletions
BIN
resources/buttons/search.png
Normal file
BIN
resources/buttons/search.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.2 KiB |
|
@ -18,10 +18,10 @@ def isNotIgnored(file):
|
|||
|
||||
return file.as_posix() not in ignored_files
|
||||
|
||||
all_files = list(filter(isNotIgnored, \
|
||||
filter(Path.is_file, Path('.').glob('**/*'))))
|
||||
image_files = list(filter(isNotIgnored, \
|
||||
filter(Path.is_file, Path('.').glob('**/*.png'))))
|
||||
all_files = sorted(list(filter(isNotIgnored, \
|
||||
filter(Path.is_file, Path('.').glob('**/*')))))
|
||||
image_files = sorted(list(filter(isNotIgnored, \
|
||||
filter(Path.is_file, Path('.').glob('**/*.png')))))
|
||||
|
||||
with open('./resources_autogenerated.qrc', 'w') as out:
|
||||
out.write(resources_header)
|
||||
|
|
|
@ -8,7 +8,7 @@ QCheckBox::indicator {
|
|||
}
|
||||
|
||||
chatterino--ComboBox {
|
||||
width: 100px;
|
||||
width: 120px;
|
||||
}
|
||||
|
||||
QScrollArea {
|
||||
|
@ -27,19 +27,19 @@ QComboBox QFrame {
|
|||
|
||||
chatterino--SettingsPage {
|
||||
background: #222;
|
||||
border: 1px solid #555;
|
||||
/*border: 1px solid #555;
|
||||
border-left: none;*/
|
||||
}
|
||||
|
||||
chatterino--PageHeader {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
chatterino--TitleLabel {
|
||||
font-family: "Segoe UI light";
|
||||
font-size: 24px;
|
||||
color: #4FC3F7;
|
||||
}
|
||||
|
||||
chatterino--TitleLabel2 {
|
||||
font-family: "Segoe UI light";
|
||||
font-size: 24px;
|
||||
color: #bbb;
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
chatterino--DescriptionLabel {
|
||||
|
|
|
@ -1,86 +1,88 @@
|
|||
<RCC>
|
||||
<qresource prefix="/"> <file>icon.png</file>
|
||||
<file>emojidata.txt</file>
|
||||
<file>chatterino.desktop</file>
|
||||
<file>error.png</file>
|
||||
<file>.gitignore</file>
|
||||
<file>tlds.txt</file>
|
||||
<file>contributors.txt</file>
|
||||
<file>pajaDank.png</file>
|
||||
<file>chatterino.icns</file>
|
||||
<file>icon.ico</file>
|
||||
<file>emoji.json</file>
|
||||
<file>buttons/mod.png</file>
|
||||
<file>buttons/copyDark.svg</file>
|
||||
<file>buttons/modModeDisabled.png</file>
|
||||
<file>buttons/unmod.png</file>
|
||||
<qresource prefix="/"> <file>.gitignore</file>
|
||||
<file>avatars/fourtf.png</file>
|
||||
<file>avatars/pajlada.png</file>
|
||||
<file>buttons/addSplit.png</file>
|
||||
<file>buttons/addSplitDark.png</file>
|
||||
<file>buttons/ban.png</file>
|
||||
<file>buttons/banRed.png</file>
|
||||
<file>buttons/copyDark.png</file>
|
||||
<file>buttons/copyDark.svg</file>
|
||||
<file>buttons/copyDarkTheme.png</file>
|
||||
<file>buttons/copyLight.png</file>
|
||||
<file>buttons/copyLight.svg</file>
|
||||
<file>buttons/emote.svg</file>
|
||||
<file>buttons/emoteDark.svg</file>
|
||||
<file>buttons/menuDark.png</file>
|
||||
<file>buttons/menuLight.png</file>
|
||||
<file>buttons/mod.png</file>
|
||||
<file>buttons/modModeDisabled.png</file>
|
||||
<file>buttons/modModeDisabled2.png</file>
|
||||
<file>buttons/modModeEnabled.png</file>
|
||||
<file>buttons/modModeEnabled2.png</file>
|
||||
<file>buttons/search.png</file>
|
||||
<file>buttons/timeout.png</file>
|
||||
<file>buttons/trashCan.png</file>
|
||||
<file>buttons/trashcan.svg</file>
|
||||
<file>buttons/modModeEnabled.png</file>
|
||||
<file>buttons/copyLight.svg</file>
|
||||
<file>buttons/modModeEnabled2.png</file>
|
||||
<file>buttons/banRed.png</file>
|
||||
<file>buttons/ban.png</file>
|
||||
<file>buttons/emoteDark.svg</file>
|
||||
<file>buttons/menuLight.png</file>
|
||||
<file>buttons/emote.svg</file>
|
||||
<file>buttons/update.png</file>
|
||||
<file>buttons/addSplit.png</file>
|
||||
<file>buttons/menuDark.png</file>
|
||||
<file>buttons/updateError.png</file>
|
||||
<file>buttons/unban.png</file>
|
||||
<file>buttons/copyLight.png</file>
|
||||
<file>buttons/modModeDisabled2.png</file>
|
||||
<file>buttons/copyDark.png</file>
|
||||
<file>buttons/unmod.png</file>
|
||||
<file>buttons/update.png</file>
|
||||
<file>buttons/updateError.png</file>
|
||||
<file>chatterino.desktop</file>
|
||||
<file>chatterino.icns</file>
|
||||
<file>contributors.txt</file>
|
||||
<file>emoji.json</file>
|
||||
<file>emojidata.txt</file>
|
||||
<file>error.png</file>
|
||||
<file>examples/moving.gif</file>
|
||||
<file>examples/splitting.gif</file>
|
||||
<file>twitch/prime.png</file>
|
||||
<file>twitch/vip.png</file>
|
||||
<file>twitch/cheer1.png</file>
|
||||
<file>twitch/admin.png</file>
|
||||
<file>twitch/broadcaster.png</file>
|
||||
<file>twitch/verified.png</file>
|
||||
<file>twitch/moderator.png</file>
|
||||
<file>twitch/globalmod.png</file>
|
||||
<file>twitch/automod.png</file>
|
||||
<file>twitch/subscriber.png</file>
|
||||
<file>twitch/staff.png</file>
|
||||
<file>twitch/turbo.png</file>
|
||||
<file>licenses/qt_lgpl-3.0.txt</file>
|
||||
<file>licenses/emoji-data-source.txt</file>
|
||||
<file>licenses/pajlada_settings.txt</file>
|
||||
<file>licenses/openssl.txt</file>
|
||||
<file>licenses/pajlada_signals.txt</file>
|
||||
<file>licenses/rapidjson.txt</file>
|
||||
<file>licenses/libcommuni_BSD3.txt</file>
|
||||
<file>icon.ico</file>
|
||||
<file>icon.png</file>
|
||||
<file>licenses/boost_boost.txt</file>
|
||||
<file>licenses/websocketpp.txt</file>
|
||||
<file>licenses/emoji-data-source.txt</file>
|
||||
<file>licenses/fmt_bsd2.txt</file>
|
||||
<file>settings/aboutlogo.png</file>
|
||||
<file>settings/ignore.svg</file>
|
||||
<file>settings/notification2.svg</file>
|
||||
<file>settings/theme.svg</file>
|
||||
<file>settings/externaltools.svg</file>
|
||||
<file>settings/advanced.svg</file>
|
||||
<file>licenses/libcommuni_BSD3.txt</file>
|
||||
<file>licenses/openssl.txt</file>
|
||||
<file>licenses/pajlada_settings.txt</file>
|
||||
<file>licenses/pajlada_signals.txt</file>
|
||||
<file>licenses/qt_lgpl-3.0.txt</file>
|
||||
<file>licenses/rapidjson.txt</file>
|
||||
<file>licenses/websocketpp.txt</file>
|
||||
<file>pajaDank.png</file>
|
||||
<file>qss/settings.qss</file>
|
||||
<file>settings/about.svg</file>
|
||||
<file>settings/notifications.svg</file>
|
||||
<file>settings/behave.svg</file>
|
||||
<file>settings/aboutlogo.png</file>
|
||||
<file>settings/accounts.svg</file>
|
||||
<file>settings/emote.svg</file>
|
||||
<file>settings/advanced.svg</file>
|
||||
<file>settings/behave.svg</file>
|
||||
<file>settings/browser.svg</file>
|
||||
<file>settings/commands.svg</file>
|
||||
<file>settings/emote.svg</file>
|
||||
<file>settings/externaltools.svg</file>
|
||||
<file>settings/ignore.svg</file>
|
||||
<file>settings/keybinds.svg</file>
|
||||
<file>settings/moderation.svg</file>
|
||||
<file>settings/browser.svg</file>
|
||||
<file>avatars/pajlada.png</file>
|
||||
<file>avatars/fourtf.png</file>
|
||||
<file>qss/settings.qss</file>
|
||||
<file>settings/notification2.svg</file>
|
||||
<file>settings/notifications.svg</file>
|
||||
<file>settings/theme.svg</file>
|
||||
<file>sounds/ping2.wav</file>
|
||||
<file>split/down.png</file>
|
||||
<file>split/left.png</file>
|
||||
<file>split/move.png</file>
|
||||
<file>split/right.png</file>
|
||||
<file>split/down.png</file>
|
||||
<file>split/up.png</file>
|
||||
<file>tlds.txt</file>
|
||||
<file>twitch/admin.png</file>
|
||||
<file>twitch/automod.png</file>
|
||||
<file>twitch/broadcaster.png</file>
|
||||
<file>twitch/cheer1.png</file>
|
||||
<file>twitch/globalmod.png</file>
|
||||
<file>twitch/moderator.png</file>
|
||||
<file>twitch/prime.png</file>
|
||||
<file>twitch/staff.png</file>
|
||||
<file>twitch/subscriber.png</file>
|
||||
<file>twitch/turbo.png</file>
|
||||
<file>twitch/verified.png</file>
|
||||
<file>twitch/vip.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
|
@ -11,6 +11,7 @@ Resources2::Resources2()
|
|||
this->buttons.ban = QPixmap(":/buttons/ban.png");
|
||||
this->buttons.banRed = QPixmap(":/buttons/banRed.png");
|
||||
this->buttons.copyDark = QPixmap(":/buttons/copyDark.png");
|
||||
this->buttons.copyDarkTheme = QPixmap(":/buttons/copyDarkTheme.png");
|
||||
this->buttons.copyLight = QPixmap(":/buttons/copyLight.png");
|
||||
this->buttons.menuDark = QPixmap(":/buttons/menuDark.png");
|
||||
this->buttons.menuLight = QPixmap(":/buttons/menuLight.png");
|
||||
|
@ -19,6 +20,7 @@ Resources2::Resources2()
|
|||
this->buttons.modModeDisabled2 = QPixmap(":/buttons/modModeDisabled2.png");
|
||||
this->buttons.modModeEnabled = QPixmap(":/buttons/modModeEnabled.png");
|
||||
this->buttons.modModeEnabled2 = QPixmap(":/buttons/modModeEnabled2.png");
|
||||
this->buttons.search = QPixmap(":/buttons/search.png");
|
||||
this->buttons.timeout = QPixmap(":/buttons/timeout.png");
|
||||
this->buttons.trashCan = QPixmap(":/buttons/trashCan.png");
|
||||
this->buttons.unban = QPixmap(":/buttons/unban.png");
|
||||
|
|
|
@ -3,8 +3,7 @@
|
|||
|
||||
namespace chatterino {
|
||||
|
||||
class Resources2 : public Singleton
|
||||
{
|
||||
class Resources2 : public Singleton {
|
||||
public:
|
||||
Resources2();
|
||||
|
||||
|
@ -18,6 +17,7 @@ public:
|
|||
QPixmap ban;
|
||||
QPixmap banRed;
|
||||
QPixmap copyDark;
|
||||
QPixmap copyDarkTheme;
|
||||
QPixmap copyLight;
|
||||
QPixmap menuDark;
|
||||
QPixmap menuLight;
|
||||
|
@ -26,6 +26,7 @@ public:
|
|||
QPixmap modModeDisabled2;
|
||||
QPixmap modModeEnabled;
|
||||
QPixmap modModeEnabled2;
|
||||
QPixmap search;
|
||||
QPixmap timeout;
|
||||
QPixmap trashCan;
|
||||
QPixmap unban;
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
#include "widgets/dialogs/SettingsDialog.hpp"
|
||||
|
||||
#include "Application.hpp"
|
||||
#include "singletons/Resources.hpp"
|
||||
#include "util/LayoutCreator.hpp"
|
||||
#include "widgets/helper/Button.hpp"
|
||||
#include "widgets/helper/SettingsDialogTab.hpp"
|
||||
#include "widgets/settingspages/AboutPage.hpp"
|
||||
#include "widgets/settingspages/AccountsPage.hpp"
|
||||
|
@ -22,6 +24,7 @@
|
|||
#include "widgets/settingspages/SpecialChannelsPage.hpp"
|
||||
|
||||
#include <QDialogButtonBox>
|
||||
#include <QLineEdit>
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
|
@ -43,39 +46,55 @@ SettingsDialog::SettingsDialog()
|
|||
|
||||
void SettingsDialog::initUi()
|
||||
{
|
||||
LayoutCreator<SettingsDialog> layoutCreator(this);
|
||||
auto outerBox = LayoutCreator<SettingsDialog>(this)
|
||||
.setLayoutType<QVBoxLayout>()
|
||||
.withoutSpacing();
|
||||
|
||||
// tab pages
|
||||
layoutCreator.setLayoutType<QHBoxLayout>()
|
||||
.withoutSpacing()
|
||||
.emplace<QWidget>()
|
||||
// TOP
|
||||
auto title = outerBox.emplace<PageHeader>();
|
||||
auto edit = LayoutCreator<PageHeader>(title.getElement())
|
||||
.setLayoutType<QHBoxLayout>()
|
||||
.withoutMargin()
|
||||
.emplace<QLineEdit>()
|
||||
.assign(&this->ui_.search);
|
||||
edit->setPlaceholderText("Find in settings...");
|
||||
|
||||
QObject::connect(edit.getElement(), &QLineEdit::textChanged, this,
|
||||
&SettingsDialog::filterElements);
|
||||
|
||||
// CENTER
|
||||
auto centerBox =
|
||||
outerBox.emplace<QHBoxLayout>().withoutMargin().withoutSpacing();
|
||||
|
||||
// left side (tabs)
|
||||
centerBox.emplace<QWidget>()
|
||||
.assign(&this->ui_.tabContainerContainer)
|
||||
.emplace<QVBoxLayout>()
|
||||
.setLayoutType<QVBoxLayout>()
|
||||
.withoutMargin()
|
||||
.assign(&this->ui_.tabContainer);
|
||||
|
||||
this->ui_.tabContainerContainer->layout()->setContentsMargins(8, 8, 0, 39);
|
||||
|
||||
this->layout()->setSpacing(0);
|
||||
|
||||
// right side layout
|
||||
auto right = layoutCreator.emplace<QVBoxLayout>().withoutMargin();
|
||||
// right side (pages)
|
||||
auto right =
|
||||
centerBox.emplace<QVBoxLayout>().withoutMargin().withoutSpacing();
|
||||
{
|
||||
right.emplace<QStackedLayout>()
|
||||
.assign(&this->ui_.pageStack)
|
||||
.withoutMargin();
|
||||
|
||||
auto buttons = right.emplace<QDialogButtonBox>(Qt::Horizontal);
|
||||
{
|
||||
this->ui_.okButton =
|
||||
buttons->addButton("Ok", QDialogButtonBox::YesRole);
|
||||
this->ui_.cancelButton =
|
||||
buttons->addButton("Cancel", QDialogButtonBox::NoRole);
|
||||
}
|
||||
}
|
||||
|
||||
this->ui_.pageStack->setMargin(0);
|
||||
|
||||
outerBox->addSpacing(12);
|
||||
|
||||
// BOTTOM
|
||||
auto buttons = outerBox.emplace<QDialogButtonBox>(Qt::Horizontal);
|
||||
{
|
||||
this->ui_.okButton =
|
||||
buttons->addButton("Ok", QDialogButtonBox::YesRole);
|
||||
this->ui_.cancelButton =
|
||||
buttons->addButton("Cancel", QDialogButtonBox::NoRole);
|
||||
}
|
||||
|
||||
// ---- misc
|
||||
this->ui_.tabContainerContainer->setObjectName("tabWidget");
|
||||
this->ui_.pageStack->setObjectName("pages");
|
||||
|
@ -86,6 +105,50 @@ void SettingsDialog::initUi()
|
|||
&SettingsDialog::onCancelClicked);
|
||||
}
|
||||
|
||||
void SettingsDialog::filterElements(const QString &text)
|
||||
{
|
||||
// filter elements and hide pages
|
||||
for (auto &&page : this->pages_)
|
||||
{
|
||||
// filterElements returns true if anything on the page matches the search query
|
||||
page->tab()->setVisible(page->filterElements(text));
|
||||
}
|
||||
|
||||
// find next visible page
|
||||
if (this->lastSelectedByUser_ && this->lastSelectedByUser_->isVisible())
|
||||
{
|
||||
this->selectTab(this->lastSelectedByUser_, false);
|
||||
}
|
||||
else if (!this->selectedTab_->isVisible())
|
||||
{
|
||||
for (auto &&tab : this->tabs_)
|
||||
{
|
||||
if (tab->isVisible())
|
||||
{
|
||||
this->selectTab(tab, false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// remove duplicate spaces
|
||||
bool shouldShowSpace = false;
|
||||
|
||||
for (int i = 0; i < this->ui_.tabContainer->count(); i++)
|
||||
{
|
||||
auto item = this->ui_.tabContainer->itemAt(i);
|
||||
if (auto x = dynamic_cast<QSpacerItem *>(item); x)
|
||||
{
|
||||
x->changeSize(10, shouldShowSpace ? int(16 * this->scale()) : 0);
|
||||
shouldShowSpace = false;
|
||||
}
|
||||
else if (item->widget())
|
||||
{
|
||||
shouldShowSpace |= item->widget()->isVisible();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SettingsDialog *SettingsDialog::getHandle()
|
||||
{
|
||||
return SettingsDialog::handle;
|
||||
|
@ -96,7 +159,7 @@ void SettingsDialog::addTabs()
|
|||
this->ui_.tabContainer->setMargin(0);
|
||||
this->ui_.tabContainer->setSpacing(0);
|
||||
|
||||
this->ui_.tabContainer->addSpacing(16);
|
||||
this->ui_.tabContainer->setContentsMargins(0, 20, 0, 20);
|
||||
|
||||
this->addTab(new GeneralPage);
|
||||
|
||||
|
@ -104,32 +167,22 @@ void SettingsDialog::addTabs()
|
|||
|
||||
this->addTab(new AccountsPage);
|
||||
|
||||
// this->ui_.tabContainer->addSpacing(16);
|
||||
|
||||
// this->addTab(new LookPage);
|
||||
// this->addTab(new FeelPage);
|
||||
|
||||
this->ui_.tabContainer->addSpacing(16);
|
||||
|
||||
this->addTab(new CommandPage);
|
||||
// this->addTab(new EmotesPage);
|
||||
this->addTab(new HighlightingPage);
|
||||
this->addTab(new IgnoresPage);
|
||||
|
||||
this->ui_.tabContainer->addSpacing(16);
|
||||
|
||||
this->addTab(new KeyboardSettingsPage);
|
||||
// this->addTab(new LogsPage);
|
||||
this->addTab(this->ui_.moderationPage = new ModerationPage);
|
||||
this->addTab(new NotificationPage);
|
||||
// this->addTab(new SpecialChannelsPage);
|
||||
// this->addTab(new BrowserExtensionPage);
|
||||
this->addTab(new ExternalToolsPage);
|
||||
this->addTab(new AdvancedPage);
|
||||
|
||||
this->ui_.tabContainer->addStretch(1);
|
||||
this->addTab(new AboutPage, Qt::AlignBottom);
|
||||
this->ui_.tabContainer->addSpacing(16);
|
||||
}
|
||||
|
||||
void SettingsDialog::addTab(SettingsPage *page, Qt::Alignment alignment)
|
||||
|
@ -140,6 +193,7 @@ void SettingsDialog::addTab(SettingsPage *page, Qt::Alignment alignment)
|
|||
this->ui_.pageStack->addWidget(page);
|
||||
this->ui_.tabContainer->addWidget(tab, 0, alignment);
|
||||
this->tabs_.push_back(tab);
|
||||
this->pages_.push_back(page);
|
||||
|
||||
if (this->tabs_.size() == 1)
|
||||
{
|
||||
|
@ -147,7 +201,7 @@ void SettingsDialog::addTab(SettingsPage *page, Qt::Alignment alignment)
|
|||
}
|
||||
}
|
||||
|
||||
void SettingsDialog::selectTab(SettingsDialogTab *tab)
|
||||
void SettingsDialog::selectTab(SettingsDialogTab *tab, bool byUser)
|
||||
{
|
||||
this->ui_.pageStack->setCurrentWidget(tab->getSettingsPage());
|
||||
|
||||
|
@ -159,10 +213,12 @@ void SettingsDialog::selectTab(SettingsDialogTab *tab)
|
|||
|
||||
tab->setSelected(true);
|
||||
tab->setStyleSheet("background: #222; color: #4FC3F7;"
|
||||
"border-left: 1px solid #444;"
|
||||
"border-top: 1px solid #444;"
|
||||
"border-bottom: 1px solid #444;");
|
||||
"/*border: 1px solid #555; border-right: none;*/");
|
||||
this->selectedTab_ = tab;
|
||||
if (byUser)
|
||||
{
|
||||
this->lastSelectedByUser_ = tab;
|
||||
}
|
||||
}
|
||||
|
||||
void SettingsDialog::selectPage(SettingsPage *page)
|
||||
|
|
|
@ -8,12 +8,19 @@
|
|||
#include <QWidget>
|
||||
#include <pajlada/settings/setting.hpp>
|
||||
|
||||
class QLineEdit;
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
class SettingsPage;
|
||||
class SettingsDialogTab;
|
||||
class ModerationPage;
|
||||
|
||||
class PageHeader : public QFrame
|
||||
{
|
||||
Q_OBJECT
|
||||
};
|
||||
|
||||
enum class SettingsDialogPreference {
|
||||
NoPreference,
|
||||
Accounts,
|
||||
|
@ -41,8 +48,9 @@ private:
|
|||
void initUi();
|
||||
void addTabs();
|
||||
void addTab(SettingsPage *page, Qt::Alignment alignment = Qt::AlignTop);
|
||||
void selectTab(SettingsDialogTab *tab);
|
||||
void selectTab(SettingsDialogTab *tab, bool byUser = true);
|
||||
void selectPage(SettingsPage *page);
|
||||
void filterElements(const QString &query);
|
||||
|
||||
void onOkClicked();
|
||||
void onCancelClicked();
|
||||
|
@ -54,9 +62,12 @@ private:
|
|||
QPushButton *okButton{};
|
||||
QPushButton *cancelButton{};
|
||||
ModerationPage *moderationPage{};
|
||||
QLineEdit *search{};
|
||||
} ui_;
|
||||
std::vector<SettingsDialogTab *> tabs_;
|
||||
std::vector<SettingsPage *> pages_;
|
||||
SettingsDialogTab *selectedTab_{};
|
||||
SettingsDialogTab *lastSelectedByUser_{};
|
||||
|
||||
friend class SettingsDialogTab;
|
||||
};
|
||||
|
|
|
@ -68,6 +68,8 @@ void SettingsDialogTab::mousePressEvent(QMouseEvent *event)
|
|||
}
|
||||
|
||||
this->dialog_->selectTab(this);
|
||||
|
||||
this->setFocus();
|
||||
}
|
||||
|
||||
} // namespace chatterino
|
||||
|
|
|
@ -38,7 +38,7 @@ CommandPage::CommandPage()
|
|||
auto app = getApp();
|
||||
|
||||
LayoutCreator<CommandPage> layoutCreator(this);
|
||||
auto layout = layoutCreator.emplace<QVBoxLayout>().withoutMargin();
|
||||
auto layout = layoutCreator.setLayoutType<QVBoxLayout>();
|
||||
|
||||
EditableModelView *view =
|
||||
layout.emplace<EditableModelView>(app->commands->createModel(nullptr))
|
||||
|
|
|
@ -38,20 +38,13 @@ TitleLabel *SettingsLayout::addTitle(const QString &title)
|
|||
{
|
||||
auto label = new TitleLabel(title + ":");
|
||||
|
||||
if (this->count() != 0)
|
||||
this->addSpacing(16);
|
||||
|
||||
if (this->count() == 0)
|
||||
label->setStyleSheet("margin-top: 0");
|
||||
this->addWidget(label);
|
||||
return label;
|
||||
}
|
||||
|
||||
TitleLabel2 *SettingsLayout::addTitle2(const QString &title)
|
||||
{
|
||||
auto label = new TitleLabel2(title + ":");
|
||||
// groups
|
||||
this->groups_.push_back(Group{title, label, {}});
|
||||
|
||||
this->addSpacing(16);
|
||||
|
||||
this->addWidget(label);
|
||||
return label;
|
||||
}
|
||||
|
||||
|
@ -73,6 +66,10 @@ QCheckBox *SettingsLayout::addCheckbox(const QString &text,
|
|||
[&setting, inverse](bool state) { setting = inverse ^ state; });
|
||||
|
||||
this->addWidget(check);
|
||||
|
||||
// groups
|
||||
this->groups_.back().widgets.push_back({check, {text}});
|
||||
|
||||
return check;
|
||||
}
|
||||
|
||||
|
@ -84,11 +81,17 @@ ComboBox *SettingsLayout::addDropdown(const QString &text,
|
|||
combo->setFocusPolicy(Qt::StrongFocus);
|
||||
combo->addItems(list);
|
||||
|
||||
layout->addWidget(new QLabel(text + ":"));
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -126,6 +129,9 @@ DescriptionLabel *SettingsLayout::addDescription(const QString &text)
|
|||
|
||||
this->addWidget(label);
|
||||
|
||||
// groups
|
||||
this->groups_.back().widgets.push_back({label, {text}});
|
||||
|
||||
return label;
|
||||
}
|
||||
|
||||
|
@ -134,6 +140,64 @@ 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
group.title->setVisible(groupAny);
|
||||
any |= groupAny;
|
||||
}
|
||||
}
|
||||
|
||||
return any;
|
||||
}
|
||||
|
||||
GeneralPage::GeneralPage()
|
||||
: SettingsPage("General", ":/settings/about.svg")
|
||||
{
|
||||
|
@ -143,6 +207,7 @@ GeneralPage::GeneralPage()
|
|||
y->addWidget(scroll);
|
||||
auto x = new QHBoxLayout;
|
||||
auto layout = new SettingsLayout;
|
||||
this->settingsLayout_ = layout;
|
||||
x->addLayout(layout, 0);
|
||||
x->addStretch(1);
|
||||
auto z = new QFrame;
|
||||
|
@ -157,6 +222,16 @@ GeneralPage::GeneralPage()
|
|||
this->initExtra();
|
||||
}
|
||||
|
||||
bool GeneralPage::filterElements(const QString &query)
|
||||
{
|
||||
if (this->settingsLayout_)
|
||||
return this->settingsLayout_->filterElements(query) ||
|
||||
this->name_.contains(query, Qt::CaseInsensitive) ||
|
||||
query.isEmpty();
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
void GeneralPage::initLayout(SettingsLayout &layout)
|
||||
{
|
||||
auto &s = *getSettings();
|
||||
|
@ -353,15 +428,19 @@ void GeneralPage::initLayout(SettingsLayout &layout)
|
|||
"store in this directory.");
|
||||
layout.addWidget(makeOpenSettingDirButton());
|
||||
|
||||
} // namespace chatterino
|
||||
// invisible element for width
|
||||
auto inv = new BaseWidget(this);
|
||||
inv->setScaleIndependantWidth(500);
|
||||
layout.addWidget(inv);
|
||||
}
|
||||
|
||||
void GeneralPage::initExtra()
|
||||
{
|
||||
/// update cache path
|
||||
if (this->cachePath)
|
||||
if (this->cachePath_)
|
||||
{
|
||||
getSettings()->cachePath.connect(
|
||||
[cachePath = this->cachePath](const auto &, auto) mutable {
|
||||
[cachePath = this->cachePath_](const auto &, auto) mutable {
|
||||
QString newPath = getPaths()->cacheDirectory();
|
||||
|
||||
QString pathShortened = "Current location: <a href=\"file:///" +
|
||||
|
|
|
@ -28,17 +28,6 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
class TitleLabel2 : public QLabel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
TitleLabel2(const QString &text)
|
||||
: QLabel(text)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class DescriptionLabel : public QLabel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
@ -71,7 +60,6 @@ class SettingsLayout : public QVBoxLayout
|
|||
|
||||
public:
|
||||
TitleLabel *addTitle(const QString &text);
|
||||
TitleLabel2 *addTitle2(const QString &text);
|
||||
/// @param inverse Inverses true to false and vice versa
|
||||
QCheckBox *addCheckbox(const QString &text, BoolSetting &setting,
|
||||
bool inverse = false);
|
||||
|
@ -141,9 +129,23 @@ public:
|
|||
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{};
|
||||
std::vector<Widget> widgets;
|
||||
};
|
||||
|
||||
std::vector<Group> groups_;
|
||||
std::vector<pajlada::Signals::ScopedConnection> managedConnections_;
|
||||
};
|
||||
|
||||
|
@ -154,13 +156,16 @@ class GeneralPage : public SettingsPage
|
|||
public:
|
||||
GeneralPage();
|
||||
|
||||
bool filterElements(const QString &query);
|
||||
|
||||
private:
|
||||
void initLayout(SettingsLayout &layout);
|
||||
void initExtra();
|
||||
|
||||
QString getFont(const DropdownArgs &args) const;
|
||||
|
||||
DescriptionLabel *cachePath{};
|
||||
DescriptionLabel *cachePath_{};
|
||||
SettingsLayout *settingsLayout_{};
|
||||
};
|
||||
|
||||
} // namespace chatterino
|
||||
|
|
|
@ -13,7 +13,7 @@ KeyboardSettingsPage::KeyboardSettingsPage()
|
|||
auto layout =
|
||||
LayoutCreator<KeyboardSettingsPage>(this).setLayoutType<QVBoxLayout>();
|
||||
|
||||
auto form = layout.emplace<QFormLayout>();
|
||||
auto form = layout.emplace<QFormLayout>().withoutMargin();
|
||||
|
||||
form->addRow(new QLabel("Hold Ctrl"), new QLabel("Show resize handles"));
|
||||
form->addRow(new QLabel("Hold Ctrl + Alt"),
|
||||
|
|
|
@ -5,15 +5,77 @@
|
|||
|
||||
#include <QDebug>
|
||||
#include <QPainter>
|
||||
#include <util/FunctionEventFilter.hpp>
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
bool filterItemsRec(QObject *object, const QString &query)
|
||||
{
|
||||
bool any{};
|
||||
|
||||
for (auto &&child : object->children())
|
||||
{
|
||||
auto setOpacity = [&](auto *widget, bool condition) {
|
||||
any |= condition;
|
||||
widget->greyedOut = !condition;
|
||||
widget->update();
|
||||
};
|
||||
|
||||
if (auto x = dynamic_cast<SCheckBox *>(child); x)
|
||||
{
|
||||
setOpacity(x, x->text().contains(query, Qt::CaseInsensitive));
|
||||
}
|
||||
else if (auto x = dynamic_cast<SLabel *>(child); x)
|
||||
{
|
||||
setOpacity(x, x->text().contains(query, Qt::CaseInsensitive));
|
||||
}
|
||||
else if (auto x = dynamic_cast<SComboBox *>(child); x)
|
||||
{
|
||||
setOpacity(x, [=]() {
|
||||
for (int i = 0; i < x->count(); i++)
|
||||
{
|
||||
if (x->itemText(i).contains(query, Qt::CaseInsensitive))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}());
|
||||
}
|
||||
else if (auto x = dynamic_cast<QTabWidget *>(child); x)
|
||||
{
|
||||
for (int i = 0; i < x->count(); i++)
|
||||
{
|
||||
bool tabAny{};
|
||||
|
||||
if (x->tabText(i).contains(query, Qt::CaseInsensitive))
|
||||
{
|
||||
tabAny = true;
|
||||
}
|
||||
auto widget = x->widget(i);
|
||||
tabAny |= filterItemsRec(widget, query);
|
||||
|
||||
any |= tabAny;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
any |= filterItemsRec(child, query);
|
||||
}
|
||||
}
|
||||
return any;
|
||||
}
|
||||
|
||||
SettingsPage::SettingsPage(const QString &name, const QString &iconResource)
|
||||
: name_(name)
|
||||
, iconResource_(iconResource)
|
||||
{
|
||||
}
|
||||
|
||||
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_;
|
||||
|
@ -42,7 +104,7 @@ void SettingsPage::cancel()
|
|||
QCheckBox *SettingsPage::createCheckBox(
|
||||
const QString &text, pajlada::Settings::Setting<bool> &setting)
|
||||
{
|
||||
QCheckBox *checkbox = new QCheckBox(text);
|
||||
QCheckBox *checkbox = new SCheckBox(text);
|
||||
|
||||
// update when setting changes
|
||||
setting.connect(
|
||||
|
@ -64,7 +126,7 @@ QCheckBox *SettingsPage::createCheckBox(
|
|||
QComboBox *SettingsPage::createComboBox(
|
||||
const QStringList &items, pajlada::Settings::Setting<QString> &setting)
|
||||
{
|
||||
QComboBox *combo = new QComboBox();
|
||||
QComboBox *combo = new SComboBox();
|
||||
|
||||
// update setting on toogle
|
||||
combo->addItems(items);
|
||||
|
|
|
@ -8,8 +8,38 @@
|
|||
|
||||
#include "singletons/Settings.hpp"
|
||||
|
||||
#define SETTINGS_PAGE_WIDGET_BOILERPLATE(type, parent) \
|
||||
class type : public parent \
|
||||
{ \
|
||||
using parent::parent; \
|
||||
\
|
||||
public: \
|
||||
bool greyedOut{}; \
|
||||
\
|
||||
protected: \
|
||||
void paintEvent(QPaintEvent *e) override \
|
||||
{ \
|
||||
parent::paintEvent(e); \
|
||||
\
|
||||
if (this->greyedOut) \
|
||||
{ \
|
||||
QPainter painter(this); \
|
||||
QColor color = QColor("#222222"); \
|
||||
color.setAlphaF(0.7); \
|
||||
painter.fillRect(this->rect(), color); \
|
||||
} \
|
||||
} \
|
||||
};
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
// S* widgets are the same as their Q* counterparts,
|
||||
// but they can be greyed out and will be if you search.
|
||||
SETTINGS_PAGE_WIDGET_BOILERPLATE(SCheckBox, QCheckBox)
|
||||
SETTINGS_PAGE_WIDGET_BOILERPLATE(SLabel, QLabel)
|
||||
SETTINGS_PAGE_WIDGET_BOILERPLATE(SComboBox, QComboBox)
|
||||
SETTINGS_PAGE_WIDGET_BOILERPLATE(SPushButton, QPushButton)
|
||||
|
||||
class SettingsDialogTab;
|
||||
|
||||
class SettingsPage : public QFrame
|
||||
|
@ -22,6 +52,8 @@ public:
|
|||
const QString &getName();
|
||||
const QString &getIconResource();
|
||||
|
||||
virtual bool filterElements(const QString &query);
|
||||
|
||||
SettingsDialogTab *tab() const;
|
||||
void setTab(SettingsDialogTab *tab);
|
||||
|
||||
|
|
Loading…
Reference in a new issue