refactored the settings dialog

This commit is contained in:
fourtf
2018-01-12 23:09:05 +01:00
parent 4cbc3b8b61
commit e0bb061c81
39 changed files with 953 additions and 894 deletions
+13
View File
@@ -0,0 +1,13 @@
#include "aboutpage.hpp"
namespace chatterino {
namespace widgets {
namespace settingspages {
AboutPage::AboutPage()
: SettingsPage("About", ":/images/about.svg")
{
}
} // namespace settingspages
} // namespace widgets
} // namespace chatterino
+16
View File
@@ -0,0 +1,16 @@
#pragma once
#include "widgets/settingspages/settingspage.hpp"
namespace chatterino {
namespace widgets {
namespace settingspages {
class AboutPage : public SettingsPage
{
public:
AboutPage();
};
} // namespace settingspages
} // namespace widgets
} // namespace chatterino
@@ -0,0 +1,46 @@
#include "accountspage.hpp"
#include <QDialogButtonBox>
#include <QVBoxLayout>
#include "const.hpp"
#include "singletons/accountmanager.hpp"
#include "util/layoutcreator.hpp"
#include "widgets/logindialog.hpp"
namespace chatterino {
namespace widgets {
namespace settingspages {
AccountsPage::AccountsPage()
: SettingsPage("Accounts", ":/images/accounts.svg")
{
util::LayoutCreator<AccountsPage> layoutCreator(this);
auto layout = layoutCreator.emplace<QVBoxLayout>().withoutMargin();
auto buttons = layout.emplace<QDialogButtonBox>();
{
this->addButton = buttons->addButton("Add", QDialogButtonBox::YesRole);
this->removeButton = buttons->addButton("Remove", QDialogButtonBox::NoRole);
}
auto accountSwitch = layout.emplace<AccountSwitchWidget>(this).assign(&this->accSwitchWidget);
// ----
QObject::connect(this->addButton, &QPushButton::clicked, []() {
static auto loginWidget = new LoginWidget();
loginWidget->show();
});
QObject::connect(this->removeButton, &QPushButton::clicked, [this] {
auto selectedUser = this->accSwitchWidget->currentItem()->text();
if (selectedUser == ANONYMOUS_USERNAME_LABEL) {
// Do nothing
return;
}
singletons::AccountManager::getInstance().Twitch.removeUser(selectedUser);
});
}
} // namespace settingspages
} // namespace widgets
} // namespace chatterino
@@ -0,0 +1,24 @@
#pragma once
#include <QPushButton>
#include "widgets/accountswitchwidget.hpp"
#include "widgets/settingspages/settingspage.hpp"
namespace chatterino {
namespace widgets {
namespace settingspages {
class AccountsPage : public SettingsPage
{
public:
AccountsPage();
private:
QPushButton *addButton;
QPushButton *removeButton;
AccountSwitchWidget *accSwitchWidget;
};
} // namespace settingspages
} // namespace widgets
} // namespace chatterino
@@ -0,0 +1,148 @@
#include "appearancepage.hpp"
#include <QFontDialog>
#include <QFormLayout>
#include <QGroupBox>
#include <QLabel>
#include <QPushButton>
#include <QVBoxLayout>
#include <util/layoutcreator.hpp>
#define THEME_ITEMS "White", "Light", "Dark", "Black"
#define TAB_X "Hide tab x"
#define TAB_PREF "Hide preferences button (ctrl+p to show)"
#define TAB_USER "Hide user button"
#define SCROLL_SMOOTH "Enable smooth scrolling"
#define SCROLL_NEWMSG "Enable smooth scrolling for new messages"
#define TIMESTAMP_FORMATS "hh:mm a", "h:mm a", "HH:mm", "H:mm"
namespace chatterino {
namespace widgets {
namespace settingspages {
AppearancePage::AppearancePage()
: SettingsPage("Appearance", ":/images/theme.svg")
{
singletons::SettingManager &settings = singletons::SettingManager::getInstance();
util::LayoutCreator<AppearancePage> layoutCreator(this);
auto layout = layoutCreator.emplace<QVBoxLayout>().withoutMargin();
auto application =
layout.emplace<QGroupBox>("Application").emplace<QVBoxLayout>().withoutMargin();
{
auto form = application.emplace<QFormLayout>();
// clang-format off
form->addRow("Theme:", this->createComboBox({THEME_ITEMS}, singletons::ThemeManager::getInstance().themeName));
form->addRow("Theme color:", this->createThemeColorChanger());
form->addRow("Font:", this->createFontChanger());
form->addRow("Tab bar:", this->createCheckBox(TAB_X, settings.hideTabX));
form->addRow("", this->createCheckBox(TAB_PREF, settings.hidePreferencesButton));
form->addRow("", this->createCheckBox(TAB_USER, settings.hideUserButton));
form->addRow("Scrolling:", this->createCheckBox(SCROLL_SMOOTH, settings.enableSmoothScrolling));
form->addRow("", this->createCheckBox(SCROLL_NEWMSG, settings.enableSmoothScrollingNewMessages));
// clang-format on
}
auto messages = layout.emplace<QGroupBox>("Messages").emplace<QVBoxLayout>().withoutMargin();
{
messages.append(this->createCheckBox("Show timestamp", settings.showTimestamps));
auto tbox = messages.emplace<QHBoxLayout>();
{
tbox.emplace<QLabel>("timestamp format:");
tbox.append(this->createComboBox({TIMESTAMP_FORMATS}, settings.timestampFormat));
}
messages.append(this->createCheckBox("Show badges", settings.showBadges));
messages.append(this->createCheckBox("Seperate messages", settings.seperateMessages));
messages.append(this->createCheckBox("Show message length", settings.showMessageLength));
}
layout->addStretch(1);
}
QLayout *AppearancePage::createThemeColorChanger()
{
QHBoxLayout *layout = new QHBoxLayout;
auto &themeHue = singletons::ThemeManager::getInstance().themeHue;
// SLIDER
QSlider *slider = new QSlider(Qt::Horizontal);
layout->addWidget(slider);
slider->setValue(std::min(std::max(themeHue.getValue(), 0.0), 1.0) * 1000);
// BUTTON
QPushButton *button = new QPushButton;
layout->addWidget(button);
button->setFlat(true);
button->setFixedWidth(64);
// SIGNALS
QObject::connect(slider, &QSlider::valueChanged, this, [button, &themeHue](int value) mutable {
double newValue = value / 1000.0;
themeHue.setValue(newValue);
QPalette pal = button->palette();
QColor color;
color.setHsvF(newValue, 1.0, 1.0, 1.0);
pal.setColor(QPalette::Button, color);
button->setAutoFillBackground(true);
button->setPalette(pal);
button->update();
// TODO(pajlada): re-implement
// this->windowManager.updateAll();
});
return layout;
}
QLayout *AppearancePage::createFontChanger()
{
QHBoxLayout *layout = new QHBoxLayout;
auto &fontManager = singletons::FontManager::getInstance();
// LABEL
QLabel *label = new QLabel();
layout->addWidget(label);
auto updateFontFamilyLabel = [label, &fontManager](auto) {
label->setText(QString::fromStdString(fontManager.currentFontFamily.getValue()) + ", " +
QString::number(fontManager.currentFontSize) + "pt");
};
fontManager.currentFontFamily.connectSimple(updateFontFamilyLabel, this->managedConnections);
fontManager.currentFontSize.connectSimple(updateFontFamilyLabel, this->managedConnections);
// BUTTON
QPushButton *button = new QPushButton("Select");
layout->addWidget(button);
button->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Policy::Fixed);
QObject::connect(button, &QPushButton::clicked, []() {
auto &fontManager = singletons::FontManager::getInstance();
QFontDialog dialog(fontManager.getFont(singletons::FontManager::Medium, 1.));
dialog.connect(&dialog, &QFontDialog::fontSelected, [](const QFont &font) {
auto &fontManager = singletons::FontManager::getInstance();
fontManager.currentFontFamily = font.family().toStdString();
fontManager.currentFontSize = font.pointSize();
});
dialog.show();
dialog.exec();
});
return layout;
}
} // namespace settingspages
} // namespace widgets
} // namespace chatterino
@@ -0,0 +1,22 @@
#pragma once
#include "widgets/settingspages/settingspage.hpp"
#include <QSlider>
namespace chatterino {
namespace widgets {
namespace settingspages {
class AppearancePage : public SettingsPage
{
public:
AppearancePage();
QLayout *createThemeColorChanger();
QLayout *createFontChanger();
};
} // namespace settingspages
} // namespace widgets
} // namespace chatterino
@@ -0,0 +1,57 @@
#include "behaviourpage.hpp"
#include <QFormLayout>
#include <QLabel>
#include <QVBoxLayout>
#include <util/layoutcreator.hpp>
#define WINDOW_TOPMOST "Window always on top (requires restart)"
#define INPUT_EMPTY "Hide input box when empty"
#define LAST_MSG "Show last read message indicator"
#define PAUSE_HOVERING "When hovering"
#define STREAMLINK_QUALITY "Source", "High", "Medium", "Low", "Audio only"
namespace chatterino {
namespace widgets {
namespace settingspages {
BehaviourPage::BehaviourPage()
: SettingsPage("Behaviour", nullptr)
{
singletons::SettingManager &settings = singletons::SettingManager::getInstance();
util::LayoutCreator<BehaviourPage> layoutCreator(this);
auto form = layoutCreator.emplace<QFormLayout>().withoutMargin();
{
form->addRow("Window:", this->createCheckBox(WINDOW_TOPMOST, settings.windowTopMost));
form->addRow("Messages:", this->createCheckBox(INPUT_EMPTY, settings.windowTopMost));
form->addRow("", this->createCheckBox(LAST_MSG, settings.windowTopMost));
form->addRow("Pause chat:", this->createCheckBox(PAUSE_HOVERING, settings.windowTopMost));
form->addRow("Mouse scroll speed:", this->createMouseScrollSlider());
form->addRow("Streamlink path:", this->createLineEdit(settings.streamlinkPath));
form->addRow("Prefered quality:",
this->createComboBox({STREAMLINK_QUALITY}, settings.preferredQuality));
}
}
QSlider *BehaviourPage::createMouseScrollSlider()
{
QSlider *slider = new QSlider(Qt::Horizontal);
float currentValue = singletons::SettingManager::getInstance().mouseScrollMultiplier;
int sliderValue = ((currentValue - 0.1f) / 2.f) * 99.f;
slider->setValue(sliderValue);
QObject::connect(slider, &QSlider::valueChanged, [](int newValue) {
float mul = static_cast<float>(newValue) / 99.f;
float newSliderValue = (mul * 2.1f) + 0.1f;
singletons::SettingManager::getInstance().mouseScrollMultiplier = newSliderValue;
});
return slider;
}
} // namespace settingspages
} // namespace widgets
} // namespace chatterino
@@ -0,0 +1,22 @@
#pragma once
#include <QSlider>
#include "widgets/settingspages/settingspage.hpp"
namespace chatterino {
namespace widgets {
namespace settingspages {
class BehaviourPage : public SettingsPage
{
public:
BehaviourPage();
private:
QSlider *createMouseScrollSlider();
};
} // namespace settingspages
} // namespace widgets
} // namespace chatterino
+65
View File
@@ -0,0 +1,65 @@
#include "commandpage.hpp"
#include <QLabel>
#include <QTextEdit>
#include <util/layoutcreator.hpp>
#include "singletons/commandmanager.hpp"
// clang-format off
#define TEXT "One command per line.\n"\
"\"/cmd example command\" will print \"example command\" when you type /cmd in chat.\n"\
"{1} will be replaced with the first word you type after then command, {2} with the second and so on.\n"\
"{1+} will be replaced with first word and everything after, {2+} with everything after the second word and so on\n"\
"Duplicate commands will be ignored."
// clang-format on
namespace chatterino {
namespace widgets {
namespace settingspages {
CommandPage::CommandPage()
: SettingsPage("Commands", ":/images/commands.svg")
{
util::LayoutCreator<CommandPage> layoutCreator(this);
auto layout = layoutCreator.emplace<QVBoxLayout>();
layout.emplace<QLabel>(TEXT)->setWordWrap(true);
layout.append(this->getCommandsTextEdit());
// ---- end of layout
this->commandsEditTimer.setSingleShot(true);
}
QTextEdit *CommandPage::getCommandsTextEdit()
{
singletons::CommandManager &commandManager = singletons::CommandManager::getInstance();
// cancel
QStringList currentCommands = commandManager.getCommands();
this->onCancel.connect(
[currentCommands, &commandManager] { commandManager.setCommands(currentCommands); });
// create text edit
QTextEdit *textEdit = new QTextEdit;
textEdit->setPlainText(QString(commandManager.getCommands().join('\n')));
QObject::connect(textEdit, &QTextEdit::textChanged,
[this] { this->commandsEditTimer.start(200); });
QObject::connect(&this->commandsEditTimer, &QTimer::timeout, [textEdit, &commandManager] {
QString text = textEdit->toPlainText();
QStringList lines = text.split(QRegularExpression("(\r?\n|\r\n?)"));
commandManager.setCommands(lines);
});
return textEdit;
}
} // namespace settingspages
} // namespace widgets
} // namespace chatterino
+25
View File
@@ -0,0 +1,25 @@
#pragma once
#include <QTextEdit>
#include <QTimer>
#include "widgets/settingspages/settingspage.hpp"
namespace chatterino {
namespace widgets {
namespace settingspages {
class CommandPage : public SettingsPage
{
public:
CommandPage();
private:
QTextEdit *getCommandsTextEdit();
QTimer commandsEditTimer;
};
} // namespace settingspages
} // namespace widgets
} // namespace chatterino
+27
View File
@@ -0,0 +1,27 @@
#include "emotespage.hpp"
#include <util/layoutcreator.hpp>
namespace chatterino {
namespace widgets {
namespace settingspages {
EmotesPage::EmotesPage()
: SettingsPage("Emotes", ":/images/emote.svg")
{
singletons::SettingManager &settings = singletons::SettingManager::getInstance();
util::LayoutCreator<EmotesPage> layoutCreator(this);
auto layout = layoutCreator.emplace<QVBoxLayout>().withoutMargin();
// clang-format off
layout.append(this->createCheckBox("Enable Twitch emotes", settings.enableTwitchEmotes));
layout.append(this->createCheckBox("Enable BetterTTV emotes", settings.enableBttvEmotes));
layout.append(this->createCheckBox("Enable FrankerFaceZ emotes", settings.enableFfzEmotes));
layout.append(this->createCheckBox("Enable emojis", settings.enableEmojis));
layout.append(this->createCheckBox("Enable gif animations", settings.enableGifAnimations));
// clang-format on
layout->addStretch(1);
}
} // namespace settingspages
} // namespace widgets
} // namespace chatterino
+16
View File
@@ -0,0 +1,16 @@
#pragma once
#include "widgets/settingspages/settingspage.hpp"
namespace chatterino {
namespace widgets {
namespace settingspages {
class EmotesPage : public SettingsPage
{
public:
EmotesPage();
};
} // namespace settingspages
} // namespace widgets
} // namespace chatterino
@@ -0,0 +1,12 @@
#include "highlightingpage.hpp"
namespace chatterino {
namespace widgets {
namespace settingspages {
HighlightingPage::HighlightingPage()
: SettingsPage("Highlights", ":/images/VSO_Link_blue_16x.png")
{
}
} // namespace settingspages
} // namespace widgets
} // namespace chatterino
@@ -0,0 +1,17 @@
#pragma once
#include "widgets/settingspages/settingspage.hpp"
namespace chatterino {
namespace widgets {
namespace settingspages {
class HighlightingPage : public SettingsPage
{
public:
HighlightingPage();
};
} // namespace settingspages
} // namespace widgets
} // namespace chatterino
+12
View File
@@ -0,0 +1,12 @@
#include "logspage.hpp"
namespace chatterino {
namespace widgets {
namespace settingspages {
LogsPage::LogsPage()
: SettingsPage("Logs", ":/images/VSO_Link_blue_16x.png")
{
}
} // namespace settingspages
} // namespace widgets
} // namespace chatterino
+16
View File
@@ -0,0 +1,16 @@
#pragma once
#include "widgets/settingspages/settingspage.hpp"
namespace chatterino {
namespace widgets {
namespace settingspages {
class LogsPage : public SettingsPage
{
public:
LogsPage();
};
} // namespace settingspages
} // namespace widgets
} // namespace chatterino
@@ -0,0 +1,12 @@
#include "moderationpage.hpp"
namespace chatterino {
namespace widgets {
namespace settingspages {
ModerationPage::ModerationPage()
: SettingsPage("Moderation", ":/images/VSO_Link_blue_16x.png")
{
}
} // namespace settingspages
} // namespace widgets
} // namespace chatterino
@@ -0,0 +1,16 @@
#pragma once
#include "widgets/settingspages/settingspage.hpp"
namespace chatterino {
namespace widgets {
namespace settingspages {
class ModerationPage : public SettingsPage
{
public:
ModerationPage();
};
} // namespace settingspages
} // namespace widgets
} // namespace chatterino
@@ -0,0 +1,78 @@
#include "settingspage.hpp"
#include <QDebug>
namespace chatterino {
namespace widgets {
namespace settingspages {
SettingsPage::SettingsPage(const QString &_name, const QString &_resourceName)
: name(_name)
, resourceName(_resourceName)
{
}
const QString &SettingsPage::getName()
{
return this->name;
}
void SettingsPage::cancel()
{
this->onCancel.invoke();
}
QCheckBox *SettingsPage::createCheckBox(const QString &text,
pajlada::Settings::Setting<bool> &setting)
{
QCheckBox *checkbox = new QCheckBox(text);
// update when setting changes
setting.connect(
[checkbox](const bool &value, auto) {
checkbox->setChecked(value); //
},
this->managedConnections);
// update setting on toggle
QObject::connect(checkbox, &QCheckBox::toggled, this, [&setting](bool state) {
qDebug() << "update checkbox value";
setting = state; //
});
return checkbox;
}
QComboBox *SettingsPage::createComboBox(const QStringList &items,
pajlada::Settings::Setting<QString> &setting)
{
QComboBox *combo = new QComboBox();
// update setting on toogle
combo->addItems(items);
// 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; });
return combo;
}
QLineEdit *SettingsPage::createLineEdit(pajlada::Settings::Setting<QString> &setting)
{
QLineEdit *edit = new QLineEdit();
edit->setText(setting);
// update when setting changes
QObject::connect(edit, &QLineEdit::textChanged,
[&setting](const QString &newValue) { setting = newValue; });
return edit;
}
} // namespace settingspages
} // namespace widgets
} // namespace chatterino
@@ -0,0 +1,37 @@
#pragma once
#include <QCheckBox>
#include <QComboBox>
#include <QLineEdit>
#include <pajlada/signals/signal.hpp>
#include "singletons/settingsmanager.hpp"
namespace chatterino {
namespace widgets {
namespace settingspages {
class SettingsPage : public QWidget
{
public:
SettingsPage(const QString &name, const QString &resourceName);
const QString &getName();
void cancel();
QCheckBox *createCheckBox(const QString &text, pajlada::Settings::Setting<bool> &setting);
QComboBox *createComboBox(const QStringList &items,
pajlada::Settings::Setting<QString> &setting);
QLineEdit *createLineEdit(pajlada::Settings::Setting<QString> &setting);
protected:
QString name;
QString resourceName;
pajlada::Signals::NoArgSignal onCancel;
std::vector<pajlada::Signals::ScopedConnection> managedConnections;
};
} // namespace settingspages
} // namespace widgets
} // namespace chatterino