refactor: consolidate font picking into one dialog (#6531)
Instead of three separate dropdowns in the setting dialog, we now expose a single label + button combo for modifying the font. When the button is pressed, we open a custom font dialog allowing the user to customize the font family, font size, and font weight. Reviewed-by: nerix <nerixdev@outlook.de> Reviewed-by: pajlada <rasmus.karlsson@pajlada.com>
This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
- Minor: Added setting for character limit of deleted messages. (#6491)
|
||||
- Minor: Added link support to plugin message API. (#6386, #6527)
|
||||
- Minor: Added a description for the logging option under moderation tab. (#6514)
|
||||
- Minor: Consolidate font picking into one dialog. (#6531)
|
||||
- Minor: Added a menu action to sort tabs alphabetically. (#6551)
|
||||
- Minor: Fixed "edit hotkey" dialog opening like a normal window. (#6540)
|
||||
- Bugfix: Expose the "Extra extension IDs" setting on non-Windows systems too. (#6509)
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
<svg width="24" height="24" fill="none" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M21.03 2.97a3.578 3.578 0 0 1 0 5.06L9.062 20a2.25 2.25 0 0 1-.999.58l-5.116 1.395a.75.75 0 0 1-.92-.921l1.395-5.116a2.25 2.25 0 0 1 .58-.999L15.97 2.97a3.578 3.578 0 0 1 5.06 0ZM15 6.06 5.062 16a.75.75 0 0 0-.193.333l-1.05 3.85 3.85-1.05A.75.75 0 0 0 8 18.938L17.94 9 15 6.06Zm2.03-2.03-.97.97L19 7.94l.97-.97a2.079 2.079 0 0 0-2.94-2.94Z" fill="#c2c2c2"/></svg>
|
||||
|
After Width: | Height: | Size: 468 B |
@@ -646,6 +646,22 @@ set(SOURCE_FILES
|
||||
widgets/dialogs/EditUserNotesDialog.hpp
|
||||
widgets/dialogs/EmotePopup.cpp
|
||||
widgets/dialogs/EmotePopup.hpp
|
||||
|
||||
widgets/dialogs/font/FontDialog.cpp
|
||||
widgets/dialogs/font/FontDialog.hpp
|
||||
widgets/dialogs/font/FontFamilyWidget.cpp
|
||||
widgets/dialogs/font/FontFamilyWidget.hpp
|
||||
widgets/dialogs/font/FontSettingDialog.cpp
|
||||
widgets/dialogs/font/FontSettingDialog.hpp
|
||||
widgets/dialogs/font/FontSizeWidget.cpp
|
||||
widgets/dialogs/font/FontSizeWidget.hpp
|
||||
widgets/dialogs/font/FontWeightWidget.cpp
|
||||
widgets/dialogs/font/FontWeightWidget.hpp
|
||||
widgets/dialogs/font/IntItem.cpp
|
||||
widgets/dialogs/font/IntItem.hpp
|
||||
widgets/dialogs/font/PreviewWidget.cpp
|
||||
widgets/dialogs/font/PreviewWidget.hpp
|
||||
|
||||
widgets/dialogs/LastRunCrashDialog.cpp
|
||||
widgets/dialogs/LastRunCrashDialog.hpp
|
||||
widgets/dialogs/LoginDialog.cpp
|
||||
@@ -700,6 +716,8 @@ set(SOURCE_FILES
|
||||
widgets/helper/DebugPopup.hpp
|
||||
widgets/helper/EditableModelView.cpp
|
||||
widgets/helper/EditableModelView.hpp
|
||||
widgets/helper/FontSettingWidget.cpp
|
||||
widgets/helper/FontSettingWidget.hpp
|
||||
widgets/helper/IconDelegate.cpp
|
||||
widgets/helper/IconDelegate.hpp
|
||||
widgets/helper/InvisibleSizeGrip.cpp
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
#include "widgets/dialogs/font/FontDialog.hpp"
|
||||
|
||||
#include "widgets/dialogs/font/FontFamilyWidget.hpp"
|
||||
#include "widgets/dialogs/font/FontSizeWidget.hpp"
|
||||
#include "widgets/dialogs/font/FontWeightWidget.hpp"
|
||||
#include "widgets/dialogs/font/PreviewWidget.hpp"
|
||||
|
||||
#include <QLabel>
|
||||
#include <QPushButton>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
FontDialog::FontDialog(const QFont &startFont, QWidget *parent)
|
||||
: QDialog(parent)
|
||||
, preview(new PreviewWidget(startFont))
|
||||
, familyW(new FontFamilyWidget(startFont))
|
||||
, sizeW(new FontSizeWidget(startFont))
|
||||
, weightW(new FontWeightWidget(startFont))
|
||||
{
|
||||
auto *layout = new QVBoxLayout;
|
||||
auto *choiceLayout = new QHBoxLayout;
|
||||
auto *choiceSideLayout = new QVBoxLayout;
|
||||
auto *buttonLayout = new QHBoxLayout;
|
||||
|
||||
auto *applyButton = new QPushButton("Apply");
|
||||
auto *acceptButton = new QPushButton("Ok");
|
||||
auto *rejectButton = new QPushButton("Cancel");
|
||||
|
||||
this->setWindowTitle("Pick Font");
|
||||
this->setLayout(layout);
|
||||
this->resize(450, 450);
|
||||
|
||||
layout->addLayout(choiceLayout, 5);
|
||||
layout->addWidget(new QLabel("Preview"));
|
||||
layout->addWidget(this->preview, 1);
|
||||
layout->addLayout(buttonLayout);
|
||||
|
||||
choiceLayout->addWidget(this->familyW, 5);
|
||||
choiceLayout->addLayout(choiceSideLayout, 3);
|
||||
|
||||
choiceSideLayout->addWidget(this->sizeW);
|
||||
choiceSideLayout->addWidget(this->weightW);
|
||||
|
||||
buttonLayout->addWidget(applyButton);
|
||||
buttonLayout->addStretch();
|
||||
buttonLayout->addWidget(acceptButton);
|
||||
buttonLayout->addWidget(rejectButton);
|
||||
|
||||
QObject::connect(applyButton, &QPushButton::clicked, this,
|
||||
&FontDialog::applied);
|
||||
|
||||
QObject::connect(acceptButton, &QPushButton::clicked, this,
|
||||
&FontDialog::accept);
|
||||
|
||||
QObject::connect(rejectButton, &QPushButton::clicked, this,
|
||||
&FontDialog::reject);
|
||||
|
||||
QObject::connect(this->familyW, &FontFamilyWidget::selectedChanged, this,
|
||||
[this] {
|
||||
this->weightW->setFamily(this->familyW->getSelected());
|
||||
this->updatePreview();
|
||||
});
|
||||
|
||||
QObject::connect(this->weightW, &FontWeightWidget::selectedChanged, this,
|
||||
&FontDialog::updatePreview);
|
||||
|
||||
QObject::connect(this->sizeW, &FontSizeWidget::selectedChanged, this,
|
||||
&FontDialog::updatePreview);
|
||||
}
|
||||
|
||||
QFont FontDialog::getSelected() const
|
||||
{
|
||||
return {
|
||||
this->familyW->getSelected(),
|
||||
this->sizeW->getSelected(),
|
||||
this->weightW->getSelected(),
|
||||
};
|
||||
}
|
||||
|
||||
void FontDialog::updatePreview()
|
||||
{
|
||||
this->preview->setFont(this->getSelected());
|
||||
}
|
||||
|
||||
} // namespace chatterino
|
||||
@@ -0,0 +1,36 @@
|
||||
#pragma once
|
||||
|
||||
#include <QDialog>
|
||||
#include <QFont>
|
||||
#include <QWidget>
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
class PreviewWidget;
|
||||
class FontFamilyWidget;
|
||||
class FontSizeWidget;
|
||||
class FontWeightWidget;
|
||||
|
||||
class FontDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
FontDialog(const QFont &startFont, QWidget *parent = nullptr);
|
||||
|
||||
/// Gets the currently selected font.
|
||||
QFont getSelected() const;
|
||||
|
||||
Q_SIGNALS:
|
||||
void applied();
|
||||
|
||||
private:
|
||||
void updatePreview();
|
||||
|
||||
PreviewWidget *preview;
|
||||
FontFamilyWidget *familyW;
|
||||
FontSizeWidget *sizeW;
|
||||
FontWeightWidget *weightW;
|
||||
};
|
||||
|
||||
} // namespace chatterino
|
||||
@@ -0,0 +1,89 @@
|
||||
#include "widgets/dialogs/font/FontFamilyWidget.hpp"
|
||||
|
||||
#include <QBoxLayout>
|
||||
#include <QFontDatabase>
|
||||
#include <QLabel>
|
||||
#include <QLineEdit>
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
namespace {
|
||||
|
||||
/// Gets a list of available font families available on this system
|
||||
QStringList getFontFamilies()
|
||||
{
|
||||
QStringList families = QFontDatabase::families();
|
||||
families.removeIf(QFontDatabase::isPrivateFamily);
|
||||
return families;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
FontFamilyWidget::FontFamilyWidget(const QFont &startFont, QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, list(new QListView)
|
||||
, model(new QStringListModel(getFontFamilies(), this))
|
||||
, proxy(new QSortFilterProxyModel(this))
|
||||
{
|
||||
auto *layout = new QVBoxLayout;
|
||||
auto *header = new QHBoxLayout;
|
||||
auto *search = new QLineEdit;
|
||||
|
||||
this->setLayout(layout);
|
||||
|
||||
this->list->setModel(this->proxy);
|
||||
this->list->setEditTriggers(QAbstractItemView::NoEditTriggers);
|
||||
|
||||
this->proxy->setSourceModel(this->model);
|
||||
this->proxy->setFilterCaseSensitivity(Qt::CaseInsensitive);
|
||||
|
||||
this->setSelected(startFont.family());
|
||||
|
||||
layout->addLayout(header);
|
||||
layout->addWidget(this->list);
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
|
||||
header->addWidget(new QLabel("Font"));
|
||||
header->addWidget(search);
|
||||
|
||||
search->setPlaceholderText("Search...");
|
||||
|
||||
QObject::connect(search, &QLineEdit::textChanged, this->proxy,
|
||||
&QSortFilterProxyModel::setFilterFixedString);
|
||||
|
||||
QObject::connect(
|
||||
this->list->selectionModel(), &QItemSelectionModel::currentChanged,
|
||||
this, [this](const QModelIndex &proxyIndex, const QModelIndex &) {
|
||||
if (proxyIndex.isValid())
|
||||
{
|
||||
Q_EMIT this->selectedChanged();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void FontFamilyWidget::setSelected(const QString &family)
|
||||
{
|
||||
qsizetype row = this->model->stringList().indexOf(family);
|
||||
if (row >= 0)
|
||||
{
|
||||
QModelIndex modelIndex = this->model->index(static_cast<int>(row));
|
||||
QModelIndex proxyIndex = this->proxy->mapFromSource(modelIndex);
|
||||
|
||||
this->list->selectionModel()->setCurrentIndex(
|
||||
proxyIndex, QItemSelectionModel::ClearAndSelect);
|
||||
}
|
||||
}
|
||||
|
||||
QString FontFamilyWidget::getSelected() const
|
||||
{
|
||||
QModelIndex proxyIndex = this->list->currentIndex();
|
||||
if (!proxyIndex.isValid())
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
QModelIndex modelIndex = this->proxy->mapToSource(proxyIndex);
|
||||
return this->model->data(modelIndex).toString();
|
||||
}
|
||||
|
||||
} // namespace chatterino
|
||||
@@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
|
||||
#include <QFont>
|
||||
#include <QListView>
|
||||
#include <QSortFilterProxyModel>
|
||||
#include <QString>
|
||||
#include <QStringListModel>
|
||||
#include <QWidget>
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
class FontFamilyWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
FontFamilyWidget(const QFont &startFont, QWidget *parent = nullptr);
|
||||
|
||||
/// Gets the currently selected font family (e.g. "Arial").
|
||||
QString getSelected() const;
|
||||
|
||||
Q_SIGNALS:
|
||||
void selectedChanged();
|
||||
|
||||
private:
|
||||
void setSelected(const QString &family);
|
||||
|
||||
QListView *list;
|
||||
QStringListModel *model;
|
||||
QSortFilterProxyModel *proxy;
|
||||
};
|
||||
|
||||
} // namespace chatterino
|
||||
@@ -0,0 +1,45 @@
|
||||
#include "widgets/dialogs/font/FontSettingDialog.hpp"
|
||||
|
||||
#include "util/RapidJsonSerializeQString.hpp" // IWYU pragma: keep
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
FontSettingDialog::FontSettingDialog(QStringSetting &family, IntSetting &size,
|
||||
IntSetting &weight, QWidget *parent)
|
||||
: FontDialog({family, size, weight}, parent)
|
||||
, familySetting(family)
|
||||
, sizeSetting(size)
|
||||
, weightSetting(weight)
|
||||
, oldFamily(family)
|
||||
, oldSize(size)
|
||||
, oldWeight(weight)
|
||||
{
|
||||
this->setAttribute(Qt::WA_DeleteOnClose);
|
||||
|
||||
QObject::connect(this, &FontDialog::applied, this,
|
||||
&FontSettingDialog::setSettings);
|
||||
|
||||
QObject::connect(this, &FontDialog::rejected, this,
|
||||
&FontSettingDialog::restoreSettings);
|
||||
|
||||
QObject::connect(this, &FontDialog::accepted, this,
|
||||
&FontSettingDialog::setSettings);
|
||||
}
|
||||
|
||||
void FontSettingDialog::setSettings()
|
||||
{
|
||||
const auto selected = this->getSelected();
|
||||
|
||||
this->familySetting.setValue(selected.family());
|
||||
this->sizeSetting.setValue(selected.pointSize());
|
||||
this->weightSetting.setValue(selected.weight());
|
||||
}
|
||||
|
||||
void FontSettingDialog::restoreSettings()
|
||||
{
|
||||
this->familySetting.setValue(this->oldFamily);
|
||||
this->sizeSetting.setValue(this->oldSize);
|
||||
this->weightSetting.setValue(this->oldWeight);
|
||||
}
|
||||
|
||||
} // namespace chatterino
|
||||
@@ -0,0 +1,34 @@
|
||||
#pragma once
|
||||
|
||||
#include "common/ChatterinoSetting.hpp"
|
||||
#include "widgets/dialogs/font/FontDialog.hpp"
|
||||
|
||||
#include <QObject>
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
class FontSettingDialog : public FontDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
FontSettingDialog(QStringSetting &family, IntSetting &size,
|
||||
IntSetting &weight, QWidget *parent = nullptr);
|
||||
|
||||
private:
|
||||
/// Apply the current dialog's values to the font settings
|
||||
void setSettings();
|
||||
|
||||
/// Restore the original setting values to the font settings
|
||||
void restoreSettings();
|
||||
|
||||
QStringSetting &familySetting;
|
||||
IntSetting &sizeSetting;
|
||||
IntSetting &weightSetting;
|
||||
|
||||
QString oldFamily;
|
||||
int oldSize;
|
||||
int oldWeight;
|
||||
};
|
||||
|
||||
} // namespace chatterino
|
||||
@@ -0,0 +1,79 @@
|
||||
#include "widgets/dialogs/font/FontSizeWidget.hpp"
|
||||
|
||||
#include "widgets/dialogs/font/IntItem.hpp"
|
||||
|
||||
#include <QBoxLayout>
|
||||
#include <QFontDatabase>
|
||||
#include <QLabel>
|
||||
#include <QSignalBlocker>
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
FontSizeWidget::FontSizeWidget(const QFont &startFont, QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, customItem(new IntItem)
|
||||
, list(new QListWidget)
|
||||
, edit(new QSpinBox)
|
||||
{
|
||||
auto *layout = new QVBoxLayout;
|
||||
auto *header = new QHBoxLayout;
|
||||
|
||||
this->setLayout(layout);
|
||||
|
||||
this->edit->setMinimum(1);
|
||||
this->list->setSortingEnabled(true);
|
||||
this->list->addItem(this->customItem);
|
||||
|
||||
for (int size : QFontDatabase::standardSizes())
|
||||
{
|
||||
this->list->addItem(new IntItem(size));
|
||||
}
|
||||
|
||||
this->edit->setValue(startFont.pointSize());
|
||||
this->setListSelected(startFont.pointSize());
|
||||
|
||||
layout->addLayout(header);
|
||||
layout->addWidget(this->list);
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
|
||||
header->addWidget(new QLabel("Size"));
|
||||
header->addWidget(this->edit);
|
||||
|
||||
QObject::connect(this->edit, &QSpinBox::valueChanged, this,
|
||||
[this](int value) {
|
||||
QSignalBlocker listSignalBlocker(this->list);
|
||||
this->setListSelected(value);
|
||||
Q_EMIT this->selectedChanged();
|
||||
});
|
||||
|
||||
QObject::connect(this->list, &QListWidget::currentItemChanged, this,
|
||||
[this](QListWidgetItem *item) {
|
||||
auto *cast = dynamic_cast<IntItem *>(item);
|
||||
assert(cast);
|
||||
QSignalBlocker editSignalBlocker(this->edit);
|
||||
this->edit->setValue(cast->getValue());
|
||||
Q_EMIT this->selectedChanged();
|
||||
});
|
||||
}
|
||||
|
||||
int FontSizeWidget::getSelected() const
|
||||
{
|
||||
auto *item = dynamic_cast<IntItem *>(this->list->currentItem());
|
||||
return item ? item->getValue() : -1;
|
||||
}
|
||||
|
||||
void FontSizeWidget::setListSelected(int size)
|
||||
{
|
||||
if (IntItem *item = findIntItemInList(this->list, size))
|
||||
{
|
||||
this->customItem->setHidden(item != this->customItem);
|
||||
this->list->setCurrentItem(item);
|
||||
return;
|
||||
}
|
||||
|
||||
this->customItem->setValue(size);
|
||||
this->customItem->setHidden(false);
|
||||
this->list->setCurrentItem(this->customItem);
|
||||
}
|
||||
|
||||
} // namespace chatterino
|
||||
@@ -0,0 +1,35 @@
|
||||
#pragma once
|
||||
|
||||
#include <QFont>
|
||||
#include <QListWidget>
|
||||
#include <QSpinBox>
|
||||
#include <QWidget>
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
class IntItem;
|
||||
|
||||
/// FontSizeWidget shows a subset of the possible font sizes in a list,
|
||||
/// alongside a spinbox where the user can enter their exact font size.
|
||||
class FontSizeWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
FontSizeWidget(const QFont &startFont, QWidget *parent = nullptr);
|
||||
|
||||
/// Gets the currently selected font size.
|
||||
int getSelected() const;
|
||||
|
||||
Q_SIGNALS:
|
||||
void selectedChanged();
|
||||
|
||||
private:
|
||||
void setListSelected(int size);
|
||||
|
||||
IntItem *customItem; // displays the value from `edit`
|
||||
QListWidget *list;
|
||||
QSpinBox *edit;
|
||||
};
|
||||
|
||||
} // namespace chatterino
|
||||
@@ -0,0 +1,110 @@
|
||||
#include "widgets/dialogs/font/FontWeightWidget.hpp"
|
||||
|
||||
#include "widgets/dialogs/font/IntItem.hpp"
|
||||
|
||||
#include <QBoxLayout>
|
||||
#include <QFontDatabase>
|
||||
#include <QLabel>
|
||||
#include <QList>
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
namespace {
|
||||
|
||||
/// Get a list of weights available for the given font family
|
||||
QList<int> getWeights(const QString &family)
|
||||
{
|
||||
QList<int> weights;
|
||||
QStringList styles = QFontDatabase::styles(family);
|
||||
|
||||
for (const QString &style : styles)
|
||||
{
|
||||
int weight = QFontDatabase::weight(family, style);
|
||||
if (!weights.contains(weight))
|
||||
{
|
||||
weights.append(weight);
|
||||
}
|
||||
}
|
||||
|
||||
return weights;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
FontWeightWidget::FontWeightWidget(const QFont &startFont, QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, list(new QListWidget)
|
||||
{
|
||||
auto *layout = new QVBoxLayout;
|
||||
|
||||
this->setLayout(layout);
|
||||
|
||||
this->setFamily(startFont.family());
|
||||
if (IntItem *item = findIntItemInList(this->list, startFont.weight()))
|
||||
{
|
||||
this->list->setCurrentItem(item);
|
||||
}
|
||||
|
||||
layout->addWidget(new QLabel("Weight"));
|
||||
layout->addWidget(this->list);
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
|
||||
QObject::connect(this->list, &QListWidget::currentRowChanged, this,
|
||||
[this](int row) {
|
||||
if (row >= 0)
|
||||
{
|
||||
Q_EMIT this->selectedChanged();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void FontWeightWidget::setFamily(const QString &family)
|
||||
{
|
||||
QSignalBlocker listSignalBlocker{this->list};
|
||||
|
||||
QList<int> weights = getWeights(family);
|
||||
int currentCount = this->list->count();
|
||||
int newCount = static_cast<int>(weights.count());
|
||||
int leastCount = std::min(currentCount, newCount);
|
||||
|
||||
std::ranges::sort(weights);
|
||||
|
||||
for (int i = 0; i < leastCount; ++i)
|
||||
{
|
||||
auto *cast = dynamic_cast<IntItem *>(this->list->item(i));
|
||||
assert(cast);
|
||||
cast->setValue(weights[i]);
|
||||
cast->setHidden(false);
|
||||
}
|
||||
for (int i = currentCount; i < newCount; ++i)
|
||||
{
|
||||
this->list->addItem(new IntItem(weights[i]));
|
||||
}
|
||||
for (int i = newCount; i < currentCount; ++i)
|
||||
{
|
||||
this->list->item(i)->setHidden(true);
|
||||
}
|
||||
|
||||
int startRow = 0;
|
||||
for (int closest = INT_MAX, i = 0; i < weights.count(); ++i)
|
||||
{
|
||||
int diff = std::abs(weights[i] - QFont::Normal);
|
||||
if (diff < closest)
|
||||
{
|
||||
closest = diff;
|
||||
startRow = i;
|
||||
}
|
||||
}
|
||||
|
||||
this->list->setCurrentRow(startRow);
|
||||
}
|
||||
|
||||
int FontWeightWidget::getSelected() const
|
||||
{
|
||||
auto *cast = dynamic_cast<IntItem *>(this->list->currentItem());
|
||||
return cast ? cast->getValue() : -1;
|
||||
}
|
||||
|
||||
} // namespace chatterino
|
||||
@@ -0,0 +1,32 @@
|
||||
#pragma once
|
||||
|
||||
#include <QFont>
|
||||
#include <QListWidget>
|
||||
#include <QString>
|
||||
#include <QWidget>
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
/// FontWeightWidget shows a list of available font weights for a given font family.
|
||||
class FontWeightWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
FontWeightWidget(const QFont &startFont, QWidget *parent = nullptr);
|
||||
|
||||
/// Update the font family, resetting the selected font weight to the weight
|
||||
/// that's closest to "normal".
|
||||
void setFamily(const QString &family);
|
||||
|
||||
/// Gets the currently selected font weight.
|
||||
int getSelected() const;
|
||||
|
||||
Q_SIGNALS:
|
||||
void selectedChanged();
|
||||
|
||||
private:
|
||||
QListWidget *list;
|
||||
};
|
||||
|
||||
} // namespace chatterino
|
||||
@@ -0,0 +1,50 @@
|
||||
#include "widgets/dialogs/font/IntItem.hpp"
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
IntItem::IntItem(int v, QListWidget *parent)
|
||||
: QListWidgetItem(QString::number(v), parent, IntItem::TYPE_ID)
|
||||
, value(v)
|
||||
{
|
||||
}
|
||||
|
||||
bool IntItem::operator<(const QListWidgetItem &other) const
|
||||
{
|
||||
const auto *cast = dynamic_cast<const IntItem *>(&other);
|
||||
if (cast == nullptr)
|
||||
{
|
||||
assert(cast && "IntItem may only be compared with other list items");
|
||||
return false;
|
||||
}
|
||||
|
||||
return this->value < cast->value;
|
||||
}
|
||||
|
||||
void IntItem::setValue(int v)
|
||||
{
|
||||
this->value = v;
|
||||
QListWidgetItem::setText(QString::number(v));
|
||||
}
|
||||
|
||||
int IntItem::getValue() const
|
||||
{
|
||||
return this->value;
|
||||
}
|
||||
|
||||
IntItem *findIntItemInList(QListWidget *list, int value)
|
||||
{
|
||||
int numItems = list->count();
|
||||
|
||||
for (int i = 0; i < numItems; ++i)
|
||||
{
|
||||
auto *item = dynamic_cast<IntItem *>(list->item(i));
|
||||
if (item && item->getValue() == value)
|
||||
{
|
||||
return item;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
} // namespace chatterino
|
||||
@@ -0,0 +1,34 @@
|
||||
#pragma once
|
||||
|
||||
#include <QListWidget>
|
||||
#include <QListWidgetItem>
|
||||
#include <QString>
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
class IntItem : public QListWidgetItem
|
||||
{
|
||||
public:
|
||||
static constexpr int TYPE_ID = QListWidgetItem::UserType + 101;
|
||||
|
||||
IntItem(int v = 0, QListWidget *parent = nullptr);
|
||||
|
||||
/// setText should not be used, we only store int values in this item
|
||||
///
|
||||
/// use setValue instead.
|
||||
void setText(const QString &) = delete;
|
||||
|
||||
bool operator<(const QListWidgetItem &other) const override;
|
||||
|
||||
void setValue(int v);
|
||||
int getValue() const;
|
||||
|
||||
private:
|
||||
int value;
|
||||
};
|
||||
|
||||
/// Iterate through all items in the given list and return the item
|
||||
/// matching the given value
|
||||
IntItem *findIntItemInList(QListWidget *list, int value);
|
||||
|
||||
} // namespace chatterino
|
||||
@@ -0,0 +1,32 @@
|
||||
#include "widgets/dialogs/font/PreviewWidget.hpp"
|
||||
|
||||
#include <QPainter>
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
PreviewWidget::PreviewWidget(const QFont &startFont, QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, font(startFont)
|
||||
{
|
||||
this->setMinimumHeight(60);
|
||||
}
|
||||
|
||||
void PreviewWidget::paintEvent(QPaintEvent * /* event */)
|
||||
{
|
||||
QPainter painter{this};
|
||||
|
||||
painter.fillRect(this->rect(), this->palette().base());
|
||||
painter.setFont(this->font);
|
||||
painter.drawText(
|
||||
this->rect().adjusted(3, 3, -3, -3),
|
||||
Qt::AlignCenter | Qt::TextSingleLine,
|
||||
QStringLiteral("The quick brown fox jumps over the lazy dog"));
|
||||
}
|
||||
|
||||
void PreviewWidget::setFont(const QFont &font)
|
||||
{
|
||||
this->font = font;
|
||||
this->update();
|
||||
}
|
||||
|
||||
} // namespace chatterino
|
||||
@@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
#include <QFont>
|
||||
#include <QPaintEvent>
|
||||
#include <QWidget>
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
class PreviewWidget : public QWidget
|
||||
{
|
||||
public:
|
||||
PreviewWidget(const QFont &startFont, QWidget *parent = nullptr);
|
||||
|
||||
void setFont(const QFont &font);
|
||||
|
||||
void paintEvent(QPaintEvent *event) override;
|
||||
|
||||
private:
|
||||
QFont font;
|
||||
};
|
||||
|
||||
} // namespace chatterino
|
||||
@@ -0,0 +1,69 @@
|
||||
#include "widgets/helper/FontSettingWidget.hpp"
|
||||
|
||||
#include "Application.hpp"
|
||||
#include "singletons/Fonts.hpp"
|
||||
#include "singletons/Settings.hpp"
|
||||
#include "widgets/dialogs/font/FontSettingDialog.hpp"
|
||||
|
||||
#include <QFont>
|
||||
#include <QHBoxLayout>
|
||||
#include <QString>
|
||||
#include <QToolButton>
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
FontSettingWidget::FontSettingWidget(QStringSetting &family, IntSetting &size,
|
||||
IntSetting &weight, QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, familySetting(family)
|
||||
, sizeSetting(size)
|
||||
, weightSetting(weight)
|
||||
, currentLabel(new QLabel)
|
||||
, listener([this] {
|
||||
this->updateCurrentLabel();
|
||||
})
|
||||
{
|
||||
auto *layout = new QHBoxLayout;
|
||||
auto *button = new QToolButton;
|
||||
|
||||
this->setLayout(layout);
|
||||
this->updateCurrentLabel();
|
||||
|
||||
this->listener.add(getApp()->getFonts()->fontChanged);
|
||||
|
||||
layout->addWidget(new QLabel("Font:"));
|
||||
layout->addStretch(1);
|
||||
layout->addWidget(this->currentLabel);
|
||||
layout->addWidget(button);
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
|
||||
button->setIcon(QIcon(":/buttons/edit.svg"));
|
||||
|
||||
QObject::connect(button, &QToolButton::clicked, this,
|
||||
&FontSettingWidget::showDialog);
|
||||
}
|
||||
|
||||
void FontSettingWidget::updateCurrentLabel()
|
||||
{
|
||||
QFont font = getApp()->getFonts()->getFont(FontStyle::ChatMedium, 1);
|
||||
QString family = font.family();
|
||||
QString ptSize = QString::number(font.pointSize());
|
||||
this->currentLabel->setText(family + ", " + ptSize + "pt");
|
||||
}
|
||||
|
||||
void FontSettingWidget::showDialog()
|
||||
{
|
||||
if (!this->dialog)
|
||||
{
|
||||
this->dialog = new FontSettingDialog(
|
||||
this->familySetting, this->sizeSetting, this->weightSetting, this);
|
||||
|
||||
QObject::connect(this->dialog, &QObject::destroyed, [this] {
|
||||
this->dialog = nullptr;
|
||||
});
|
||||
}
|
||||
|
||||
this->dialog->show();
|
||||
}
|
||||
|
||||
} // namespace chatterino
|
||||
@@ -0,0 +1,35 @@
|
||||
#pragma once
|
||||
|
||||
#include "common/ChatterinoSetting.hpp"
|
||||
#include "util/SignalListener.hpp"
|
||||
|
||||
#include <QLabel>
|
||||
#include <QWidget>
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
class FontSettingDialog;
|
||||
|
||||
/// FontSettingWidget includes a label showing the current font and its size, with a button
|
||||
/// that opens a FontSettingDialog
|
||||
class FontSettingWidget : public QWidget
|
||||
{
|
||||
public:
|
||||
FontSettingWidget(QStringSetting &family, IntSetting &size,
|
||||
IntSetting &weight, QWidget *parent = nullptr);
|
||||
|
||||
private:
|
||||
void updateCurrentLabel();
|
||||
void showDialog();
|
||||
|
||||
FontSettingDialog *dialog = nullptr;
|
||||
|
||||
QStringSetting &familySetting;
|
||||
IntSetting &sizeSetting;
|
||||
IntSetting &weightSetting;
|
||||
|
||||
QLabel *currentLabel;
|
||||
SignalListener listener;
|
||||
};
|
||||
|
||||
} // namespace chatterino
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "util/Helpers.hpp"
|
||||
#include "util/IncognitoBrowser.hpp"
|
||||
#include "widgets/BaseWindow.hpp"
|
||||
#include "widgets/helper/FontSettingWidget.hpp"
|
||||
#include "widgets/settingspages/GeneralPageView.hpp"
|
||||
#include "widgets/settingspages/SettingWidget.hpp"
|
||||
|
||||
@@ -153,34 +154,6 @@ void GeneralPage::initLayout(GeneralPageView &layout)
|
||||
#endif
|
||||
}
|
||||
|
||||
layout.addDropdown<QString>(
|
||||
"Font", {"Segoe UI", "Arial", "Choose..."}, s.chatFontFamily,
|
||||
[](auto val) {
|
||||
return val;
|
||||
},
|
||||
[this](auto args) {
|
||||
return this->getFont(args);
|
||||
},
|
||||
true, "", true);
|
||||
layout.addDropdown<int>(
|
||||
"Font size", {"9pt", "10pt", "12pt", "14pt", "16pt", "20pt"},
|
||||
s.chatFontSize,
|
||||
[](auto val) {
|
||||
return QString::number(val) + "pt";
|
||||
},
|
||||
[](auto args) {
|
||||
return fuzzyToInt(args.value, 10);
|
||||
});
|
||||
layout.addDropdown<int>(
|
||||
"Font weight",
|
||||
{"100", "200", "300", "400", "500", "600", "700", "800", "900"},
|
||||
s.chatFontWeight,
|
||||
[](auto val) {
|
||||
return QString::number(val);
|
||||
},
|
||||
[](auto args) {
|
||||
return fuzzyToInt(args.value, 400);
|
||||
});
|
||||
layout.addDropdown<float>(
|
||||
"Zoom", ZOOM_LEVELS, s.uiScale,
|
||||
[](auto val) {
|
||||
@@ -263,6 +236,10 @@ void GeneralPage::initLayout(GeneralPageView &layout)
|
||||
|
||||
SettingWidget::dropdown("Tab style", s.tabStyle)->addTo(layout);
|
||||
|
||||
layout.addWidget(new FontSettingWidget(s.chatFontFamily, s.chatFontSize,
|
||||
s.chatFontWeight),
|
||||
{"font", "weight", "size"});
|
||||
|
||||
SettingWidget::inverseCheckbox("Show message reply context",
|
||||
s.hideReplyContext)
|
||||
->setTooltip(
|
||||
@@ -1541,25 +1518,4 @@ void GeneralPage::initExtra()
|
||||
}
|
||||
}
|
||||
|
||||
QString GeneralPage::getFont(const DropdownArgs &args) const
|
||||
{
|
||||
if (args.combobox->currentIndex() == args.combobox->count() - 1)
|
||||
{
|
||||
args.combobox->setEditText("Choosing...");
|
||||
|
||||
auto ok = bool();
|
||||
auto previousFont =
|
||||
getApp()->getFonts()->getFont(FontStyle::ChatMedium, 1.);
|
||||
auto font = QFontDialog::getFont(&ok, previousFont, this->window());
|
||||
|
||||
if (ok)
|
||||
{
|
||||
return font.family();
|
||||
}
|
||||
|
||||
return previousFont.family();
|
||||
}
|
||||
return args.value;
|
||||
}
|
||||
|
||||
} // namespace chatterino
|
||||
|
||||
Reference in New Issue
Block a user