Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 96 additions & 8 deletions src/qt/appearancewidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,63 @@

#include <QComboBox>
#include <QDataWidgetMapper>
#include <QFontDialog>
#include <QFontInfo>
#include <QSettings>
#include <QSlider>

int setFontChoice(QComboBox* cb, const OptionsModel::FontChoice& fc)
{
int i;
for (i = cb->count(); --i >= 0; ) {
QVariant item_data = cb->itemData(i);
if (!item_data.canConvert<OptionsModel::FontChoice>()) continue;
if (item_data.value<OptionsModel::FontChoice>() == fc) {
break;
}
}
if (i == -1) {
// New item needed
QFont chosen_font = OptionsModel::getFontForChoice(fc);
QSignalBlocker block_currentindexchanged_signal(cb); // avoid triggering QFontDialog
cb->insertItem(0, QFontInfo(chosen_font).family(), QVariant::fromValue(fc));
i = 0;
}

cb->setCurrentIndex(i);
return i;
}

void setupFontOptions(QComboBox* cb)
{
QFont embedded_font{GUIUtil::fixedPitchFont(true)};
QFont system_font{GUIUtil::fixedPitchFont(false)};
cb->addItem(QObject::tr("Default monospace font \"%1\"").arg(QFontInfo(system_font).family()), QVariant::fromValue(OptionsModel::FontChoice{OptionsModel::FontChoiceAbstract::BestSystemFont}));
cb->addItem(QObject::tr("Embedded \"%1\"").arg(QFontInfo(embedded_font).family()), QVariant::fromValue(OptionsModel::FontChoice{OptionsModel::FontChoiceAbstract::EmbeddedFont}));
cb->addItem(QObject::tr("Use existing font"), QVariant::fromValue(OptionsModel::FontChoice{OptionsModel::FontChoiceAbstract::ApplicationFont}));
cb->addItem(QObject::tr("Custom…"));

const auto& on_font_choice_changed = [cb](int index) {
static int previous_index = -1;
QVariant item_data = cb->itemData(index);
if (item_data.canConvert<OptionsModel::FontChoice>()) {
// Valid predefined choice, nothing to do
} else {
// "Custom..." was selected, show font dialog
bool ok;
QFont f = QFontDialog::getFont(&ok, GUIUtil::fixedPitchFont(false), cb->parentWidget());
if (!ok) {
cb->setCurrentIndex(previous_index);
return;
}
index = setFontChoice(cb, OptionsModel::FontChoice{f});
}
previous_index = index;
};
QObject::connect(cb, QOverload<int>::of(&QComboBox::currentIndexChanged), on_font_choice_changed);
on_font_choice_changed(cb->currentIndex());
}

AppearanceWidget::AppearanceWidget(QWidget* parent) :
QWidget(parent),
ui{new Ui::AppearanceWidget()},
Expand All @@ -34,7 +88,8 @@ AppearanceWidget::AppearanceWidget(QWidget* parent) :
}

for (size_t idx{0}; idx < GUIUtil::g_fonts_known.size(); idx++) {
ui->fontFamily->addItem(GUIUtil::g_fonts_known[idx], QVariant((uint16_t)idx));
const auto& [font, selectable] = GUIUtil::g_fonts_known[idx];
if (selectable) { ui->fontFamily->addItem(font, QVariant((uint16_t)idx)); }
}

updateWeightSlider();
Expand All @@ -43,17 +98,25 @@ AppearanceWidget::AppearanceWidget(QWidget* parent) :
mapper->setSubmitPolicy(QDataWidgetMapper::ManualSubmit);
mapper->setOrientation(Qt::Vertical);

connect(ui->theme, &QComboBox::currentTextChanged, this, &AppearanceWidget::updateTheme);
setupFontOptions(ui->moneyFont);

connect(ui->fontFamily, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &AppearanceWidget::updateFontFamily);
connect(ui->fontFamily, QOverload<int>::of(&QComboBox::currentIndexChanged), [this]() { Q_EMIT appearanceChanged(); });

connect(ui->fontScaleSlider, &QSlider::sliderReleased, [this]() { Q_EMIT appearanceChanged(); });
connect(ui->fontScaleSlider, &QSlider::valueChanged, this, &AppearanceWidget::updateFontScale);
connect(ui->fontWeightNormalSlider, &QSlider::valueChanged, [this](auto nValue) { updateFontWeightNormal(nValue); });

connect(ui->fontWeightBoldSlider, &QSlider::sliderReleased, [this]() { Q_EMIT appearanceChanged(); });
connect(ui->fontWeightBoldSlider, &QSlider::valueChanged, [this](auto nValue) { updateFontWeightBold(nValue); });

connect(ui->theme, &QComboBox::currentTextChanged, [this]() { Q_EMIT appearanceChanged(); });
connect(ui->fontFamily, &QComboBox::currentTextChanged, [this]() { Q_EMIT appearanceChanged(); });
connect(ui->fontScaleSlider, &QSlider::sliderReleased, [this]() { Q_EMIT appearanceChanged(); });
connect(ui->fontWeightNormalSlider, &QSlider::sliderReleased, [this]() { Q_EMIT appearanceChanged(); });
connect(ui->fontWeightBoldSlider, &QSlider::sliderReleased, [this]() { Q_EMIT appearanceChanged(); });
connect(ui->fontWeightNormalSlider, &QSlider::valueChanged, [this](auto nValue) { updateFontWeightNormal(nValue); });

connect(ui->moneyFont, &QComboBox::currentTextChanged, [this]() { Q_EMIT appearanceChanged(); });
connect(ui->moneyFont, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &AppearanceWidget::updateMoneyFont);

connect(ui->theme, &QComboBox::currentTextChanged, this, &AppearanceWidget::updateTheme);
connect(ui->theme, &QComboBox::currentTextChanged, [this]() { Q_EMIT appearanceChanged(); });
}

AppearanceWidget::~AppearanceWidget()
Expand All @@ -78,6 +141,13 @@ AppearanceWidget::~AppearanceWidget()
if (prevWeightBold != GUIUtil::g_font_registry.GetWeightBold()) {
GUIUtil::g_font_registry.SetWeightBold(prevWeightBold);
}
// Restore monospace font if cancelled
if (model) {
const auto& current_money_font = model->data(model->index(OptionsModel::FontForMoney, 0), Qt::EditRole).value<OptionsModel::FontChoice>();
if (current_money_font != prevMoneyFont) {
model->setData(model->index(OptionsModel::FontForMoney, 0), QVariant::fromValue(prevMoneyFont));
}
}
GUIUtil::setApplicationFont();
GUIUtil::updateFonts();
}
Expand All @@ -103,6 +173,10 @@ void AppearanceWidget::setModel(OptionsModel* _model)

mapper->toFirst();

const auto& font_for_money = _model->data(_model->index(OptionsModel::FontForMoney, 0), Qt::EditRole).value<OptionsModel::FontChoice>();
prevMoneyFont = font_for_money; // Save original value for cancel
setFontChoice(ui->moneyFont, font_for_money);

const bool override_family{_model->isOptionOverridden("-font-family")};
if (override_family) {
ui->fontFamily->setEnabled(false);
Expand Down Expand Up @@ -138,6 +212,7 @@ void AppearanceWidget::setModel(OptionsModel* _model)
void AppearanceWidget::accept()
{
fAcceptChanges = true;
// Note: FontForMoney is now updated immediately via updateMoneyFont()
}

void AppearanceWidget::updateTheme(const QString& theme)
Expand All @@ -154,7 +229,7 @@ void AppearanceWidget::updateTheme(const QString& theme)

void AppearanceWidget::updateFontFamily(int index)
{
const bool setfont_ret{GUIUtil::g_font_registry.SetFont(GUIUtil::g_fonts_known[ui->fontFamily->itemData(index).toInt()])};
const bool setfont_ret{GUIUtil::g_font_registry.SetFont(GUIUtil::g_fonts_known[ui->fontFamily->itemData(index).toInt()].first)};
assert(setfont_ret);
GUIUtil::setApplicationFont();
GUIUtil::updateFonts();
Expand Down Expand Up @@ -193,6 +268,19 @@ void AppearanceWidget::updateFontWeightBold(int nValue, bool fForce)
GUIUtil::updateFonts();
}

void AppearanceWidget::updateMoneyFont(int index)
{
if (!model) {
return;
}
QVariant item_data = ui->moneyFont->itemData(index);
if (!item_data.canConvert<OptionsModel::FontChoice>()) {
return;
}
// Update the model immediately to trigger live preview in Overview page
model->setData(model->index(OptionsModel::FontForMoney, 0), item_data);
}

void AppearanceWidget::updateWeightSlider(const bool fForce)
{
int nMaximum = GUIUtil::g_font_registry.GetSupportedWeights().size() - 1;
Expand Down
5 changes: 3 additions & 2 deletions src/qt/appearancewidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,12 @@

#include <qt/guiutil.h>
#include <qt/guiutil_font.h>
#include <qt/optionsmodel.h>

namespace Ui {
class AppearanceWidget;
}

class OptionsModel;

class QDataWidgetMapper;
class QSlider;
class QComboBox;
Expand All @@ -42,6 +41,7 @@ private Q_SLOTS:
void updateFontScale(int nScale);
void updateFontWeightNormal(int nValue, bool fForce = false);
void updateFontWeightBold(int nValue, bool fForce = false);
void updateMoneyFont(int index);

private:
Ui::AppearanceWidget* ui;
Expand All @@ -53,6 +53,7 @@ private Q_SLOTS:
QString prevFontFamily;
QFont::Weight prevWeightNormal;
QFont::Weight prevWeightBold;
OptionsModel::FontChoice prevMoneyFont{OptionsModel::FontChoiceAbstract::ApplicationFont};

void updateWeightSlider(bool fForce = false);
};
Expand Down
4 changes: 2 additions & 2 deletions src/qt/bitcoin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -489,7 +489,7 @@ static void SetupUIArgs(ArgsManager& argsman)
{
argsman.AddArg("-choosedatadir", strprintf(QObject::tr("Choose data directory on startup (default: %u)").toStdString(), DEFAULT_CHOOSE_DATADIR), ArgsManager::ALLOW_ANY, OptionsCategory::GUI);
argsman.AddArg("-custom-css-dir", "Set a directory which contains custom css files. Those will be used as stylesheets for the UI.", ArgsManager::ALLOW_ANY, OptionsCategory::GUI);
argsman.AddArg("-font-family", QObject::tr("Set the font family. Possible values: %1. (default: %2)").arg(Join(GUIUtil::g_fonts_known, ", ")).arg(GUIUtil::FontRegistry::DEFAULT_FONT).toStdString(), ArgsManager::ALLOW_ANY, OptionsCategory::GUI);
argsman.AddArg("-font-family", QObject::tr("Set the font family. Possible values: %1. (default: %2)").arg(Join(GUIUtil::getFonts(/*selectable_only=*/true), ", ")).arg(GUIUtil::FontRegistry::DEFAULT_FONT).toStdString(), ArgsManager::ALLOW_ANY, OptionsCategory::GUI);
argsman.AddArg("-font-scale", QObject::tr("Set a scale factor which gets applied to the base font size. Possible range %1 (smallest fonts) to %2 (largest fonts). (default: %3)").arg(-100).arg(100).arg(GUIUtil::FontRegistry::DEFAULT_FONT_SCALE).toStdString(), ArgsManager::ALLOW_ANY, OptionsCategory::GUI);
argsman.AddArg("-font-weight-bold", QObject::tr("Set the font weight for bold texts. Possible range %1 to %2 (default: %3)").arg(0).arg(8).arg(GUIUtil::weightToArg(GUIUtil::FontRegistry::TARGET_WEIGHT_BOLD)).toStdString(), ArgsManager::ALLOW_ANY, OptionsCategory::GUI);
argsman.AddArg("-font-weight-normal", QObject::tr("Set the font weight for normal texts. Possible range %1 to %2 (default: %3)").arg(0).arg(8).arg(GUIUtil::weightToArg(GUIUtil::FontRegistry::TARGET_WEIGHT_NORMAL)).toStdString(), ArgsManager::ALLOW_ANY, OptionsCategory::GUI);
Expand Down Expand Up @@ -673,7 +673,7 @@ int GuiMain(int argc, char* argv[])
// Validate/set font family
if (gArgs.IsArgSet("-font-family")) {
QString family = gArgs.GetArg("-font-family", GUIUtil::FontRegistry::DEFAULT_FONT.toUtf8().toStdString()).c_str();
if (!GUIUtil::g_font_registry.RegisterFont(family) || !GUIUtil::g_font_registry.SetFont(family)) {
if (!GUIUtil::g_font_registry.RegisterFont(family, /*selectable=*/true) || !GUIUtil::g_font_registry.SetFont(family)) {
QMessageBox::critical(nullptr, PACKAGE_NAME, QObject::tr("Error: Font \"%1\" could not be loaded.").arg(family));
return EXIT_FAILURE;
}
Expand Down
43 changes: 43 additions & 0 deletions src/qt/forms/appearancewidget.ui
Original file line number Diff line number Diff line change
Expand Up @@ -479,6 +479,49 @@
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="hLayoutMoneyFont">
<item>
<widget class="QLabel" name="moneyFontLabel">
<property name="text">
<string>Font in the Overview tab: </string>
</property>
<property name="buddy">
<cstring>moneyFont</cstring>
</property>
</widget>
</item>
<item>
<spacer name="moneyFont_horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QComboBox" name="moneyFont">
<property name="minimumSize">
<size>
<width>282</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>282</width>
<height>16777215</height>
</size>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
Expand Down
8 changes: 0 additions & 8 deletions src/qt/guiutil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -230,14 +230,6 @@ QString dateTimeStr(qint64 nTime)
return dateTimeStr(QDateTime::fromSecsSinceEpoch((qint32)nTime));
}

QFont fixedPitchFont(bool use_embedded_font)
{
if (use_embedded_font) {
return {"Roboto Mono"};
}
return QFontDatabase::systemFont(QFontDatabase::FixedFont);
}

// Just some dummy data to generate a convincing random-looking (but consistent) address
static const uint8_t dummydata[] = {0xeb,0x15,0x23,0x1d,0xfc,0xeb,0x60,0x92,0x58,0x86,0xb6,0x7d,0x06,0x52,0x99,0x92,0x59,0x15,0xae,0xb1,0x72,0xc0,0x66,0x47};

Expand Down
3 changes: 0 additions & 3 deletions src/qt/guiutil.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,9 +125,6 @@ namespace GUIUtil
QString dateTimeStr(const QDateTime &datetime);
QString dateTimeStr(qint64 nTime);

// Return a monospace font
QFont fixedPitchFont(bool use_embedded_font = false);

// Set up widget for address
void setupAddressWidget(QValidatedLineEdit *widget, QWidget *parent, bool fAllowURI = false);

Expand Down
Loading
Loading