diff --git a/src/Makefile.qt.include b/src/Makefile.qt.include index 04652688dbef..16296207eca1 100644 --- a/src/Makefile.qt.include +++ b/src/Makefile.qt.include @@ -151,7 +151,6 @@ BITCOIN_QT_H = \ qt/donutchart.h \ qt/editaddressdialog.h \ qt/guiconstants.h \ - qt/guiutil_font.h \ qt/guiutil.h \ qt/informationwidget.h \ qt/initexecutor.h \ diff --git a/src/qt/addressbookpage.cpp b/src/qt/addressbookpage.cpp index 5ffc72846032..1f8d62191325 100644 --- a/src/qt/addressbookpage.cpp +++ b/src/qt/addressbookpage.cpp @@ -14,7 +14,6 @@ #include #include #include -#include #include #include diff --git a/src/qt/addresstablemodel.cpp b/src/qt/addresstablemodel.cpp index f13723d560fc..12a13e1458ca 100644 --- a/src/qt/addresstablemodel.cpp +++ b/src/qt/addresstablemodel.cpp @@ -6,7 +6,6 @@ #include #include -#include #include #include diff --git a/src/qt/appearancewidget.cpp b/src/qt/appearancewidget.cpp index 0f5bdda5c96e..7cba5922dccd 100644 --- a/src/qt/appearancewidget.cpp +++ b/src/qt/appearancewidget.cpp @@ -9,17 +9,23 @@ #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include +#include + int setFontChoice(QComboBox* cb, const OptionsModel::FontChoice& fc) { int i; @@ -76,10 +82,10 @@ AppearanceWidget::AppearanceWidget(QWidget* parent) : QWidget(parent), ui{new Ui::AppearanceWidget()}, prevTheme{GUIUtil::getActiveTheme()}, - prevScale{GUIUtil::g_font_registry.GetFontScale()}, - prevFontFamily{GUIUtil::g_font_registry.GetFont()}, - prevWeightNormal{GUIUtil::g_font_registry.GetWeightNormal()}, - prevWeightBold{GUIUtil::g_font_registry.GetWeightBold()} + prevScale{GUIUtil::fontScale()}, + prevFontFamily{GUIUtil::activeFont()}, + prevWeightNormalArg{GUIUtil::currentWeightArg(GUIUtil::FontWeight::Normal)}, + prevWeightBoldArg{GUIUtil::currentWeightArg(GUIUtil::FontWeight::Bold)} { ui->setupUi(this); @@ -87,8 +93,9 @@ AppearanceWidget::AppearanceWidget(QWidget* parent) : ui->theme->addItem(entry, QVariant(entry)); } - for (size_t idx{0}; idx < GUIUtil::g_fonts_known.size(); idx++) { - const auto& [font, selectable] = GUIUtil::g_fonts_known[idx]; + const auto& known = GUIUtil::knownFonts(); + for (size_t idx{0}; idx < known.size(); idx++) { + const auto& [font, selectable] = known[idx]; if (selectable) { ui->fontFamily->addItem(font, QVariant((uint16_t)idx)); } } @@ -127,19 +134,19 @@ AppearanceWidget::~AppearanceWidget() if (prevTheme != GUIUtil::getActiveTheme()) { updateTheme(prevTheme); } - if (prevFontFamily != GUIUtil::g_font_registry.GetFont()) { - const bool setfont_ret{GUIUtil::g_font_registry.SetFont(prevFontFamily)}; + if (prevFontFamily != GUIUtil::activeFont()) { + const bool setfont_ret{GUIUtil::setActiveFont(prevFontFamily)}; assert(setfont_ret); GUIUtil::setApplicationFont(); } - if (prevScale != GUIUtil::g_font_registry.GetFontScale()) { - GUIUtil::g_font_registry.SetFontScale(prevScale); + if (prevScale != GUIUtil::fontScale()) { + GUIUtil::setFontScale(prevScale); } - if (prevWeightNormal != GUIUtil::g_font_registry.GetWeightNormal()) { - GUIUtil::g_font_registry.SetWeightNormal(prevWeightNormal); + if (prevWeightNormalArg != GUIUtil::currentWeightArg(GUIUtil::FontWeight::Normal)) { + GUIUtil::setWeightFromArg(GUIUtil::FontWeight::Normal, prevWeightNormalArg); } - if (prevWeightBold != GUIUtil::g_font_registry.GetWeightBold()) { - GUIUtil::g_font_registry.SetWeightBold(prevWeightBold); + if (prevWeightBoldArg != GUIUtil::currentWeightArg(GUIUtil::FontWeight::Bold)) { + GUIUtil::setWeightFromArg(GUIUtil::FontWeight::Bold, prevWeightBoldArg); } // Restore monospace font if cancelled if (model) { @@ -180,32 +187,28 @@ void AppearanceWidget::setModel(OptionsModel* _model) const bool override_family{_model->isOptionOverridden("-font-family")}; if (override_family) { ui->fontFamily->setEnabled(false); - if (const auto idx{ui->fontFamily->findText(GUIUtil::g_font_registry.GetFont())}; idx != -1) { + if (const auto idx{ui->fontFamily->findText(GUIUtil::activeFont())}; idx != -1) { ui->fontFamily->setCurrentIndex(idx); } } if (_model->isOptionOverridden("-font-scale")) { ui->fontScaleSlider->setEnabled(false); - ui->fontScaleSlider->setValue(GUIUtil::g_font_registry.GetFontScale()); + ui->fontScaleSlider->setValue(GUIUtil::fontScale()); } if (bool is_overridden{_model->isOptionOverridden("-font-weight-normal")}; is_overridden || override_family) { if (is_overridden) { ui->fontWeightNormalSlider->setEnabled(false); } - if (const auto idx{GUIUtil::g_font_registry.WeightToIdx(GUIUtil::g_font_registry.GetWeightNormal())}; idx != -1) { - ui->fontWeightNormalSlider->setValue(idx); - } + ui->fontWeightNormalSlider->setValue(GUIUtil::currentWeightArg(GUIUtil::FontWeight::Normal)); } if (bool is_overridden{_model->isOptionOverridden("-font-weight-bold")}; is_overridden || override_family) { if (is_overridden) { ui->fontWeightBoldSlider->setEnabled(false); } - if (const auto idx{GUIUtil::g_font_registry.WeightToIdx(GUIUtil::g_font_registry.GetWeightBold())}; idx != -1) { - ui->fontWeightBoldSlider->setValue(idx); - } + ui->fontWeightBoldSlider->setValue(GUIUtil::currentWeightArg(GUIUtil::FontWeight::Bold)); } } @@ -229,7 +232,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()].first)}; + const bool setfont_ret{GUIUtil::setActiveFont(GUIUtil::knownFonts()[ui->fontFamily->itemData(index).toInt()].first)}; assert(setfont_ret); GUIUtil::setApplicationFont(); GUIUtil::updateFonts(); @@ -238,7 +241,7 @@ void AppearanceWidget::updateFontFamily(int index) void AppearanceWidget::updateFontScale(int nScale) { - GUIUtil::g_font_registry.SetFontScale(nScale); + GUIUtil::setFontScale(nScale); GUIUtil::updateFonts(); } @@ -248,9 +251,11 @@ void AppearanceWidget::updateFontWeightNormal(int nValue, bool fForce) if (nValue > ui->fontWeightBoldSlider->value() && !fForce) { nSliderValue = ui->fontWeightBoldSlider->value(); } + nSliderValue = std::ranges::min(GUIUtil::supportedWeightArgs(), {}, + [nSliderValue](int x) { return std::abs(x - nSliderValue); }); const QSignalBlocker blocker(ui->fontWeightNormalSlider); ui->fontWeightNormalSlider->setValue(nSliderValue); - GUIUtil::g_font_registry.SetWeightNormal(GUIUtil::g_font_registry.IdxToWeight(ui->fontWeightNormalSlider->value())); + GUIUtil::setWeightFromArg(GUIUtil::FontWeight::Normal, nSliderValue); GUIUtil::setApplicationFont(); GUIUtil::updateFonts(); } @@ -261,9 +266,11 @@ void AppearanceWidget::updateFontWeightBold(int nValue, bool fForce) if (nValue < ui->fontWeightNormalSlider->value() && !fForce) { nSliderValue = ui->fontWeightNormalSlider->value(); } + nSliderValue = std::ranges::min(GUIUtil::supportedWeightArgs(), {}, + [nSliderValue](int x) { return std::abs(x - nSliderValue); }); const QSignalBlocker blocker(ui->fontWeightBoldSlider); ui->fontWeightBoldSlider->setValue(nSliderValue); - GUIUtil::g_font_registry.SetWeightBold(GUIUtil::g_font_registry.IdxToWeight(ui->fontWeightBoldSlider->value())); + GUIUtil::setWeightFromArg(GUIUtil::FontWeight::Bold, nSliderValue); GUIUtil::setApplicationFont(); GUIUtil::updateFonts(); } @@ -283,19 +290,60 @@ void AppearanceWidget::updateMoneyFont(int index) void AppearanceWidget::updateWeightSlider(const bool fForce) { - int nMaximum = GUIUtil::g_font_registry.GetSupportedWeights().size() - 1; + const auto supported = GUIUtil::supportedWeightArgs(); + const int nMin = supported.front(); + const int nMax = supported.back(); - ui->fontWeightNormalSlider->setMinimum(0); - ui->fontWeightNormalSlider->setMaximum(nMaximum); + ui->fontWeightNormalSlider->setMinimum(nMin); + ui->fontWeightNormalSlider->setMaximum(nMax); - ui->fontWeightBoldSlider->setMinimum(0); - ui->fontWeightBoldSlider->setMaximum(nMaximum); + ui->fontWeightBoldSlider->setMinimum(nMin); + ui->fontWeightBoldSlider->setMaximum(nMax); - if (fForce || !GUIUtil::g_font_registry.IsValidWeight(prevWeightNormal) || !GUIUtil::g_font_registry.IsValidWeight(prevWeightBold)) { - int nIndexNormal = GUIUtil::g_font_registry.WeightToIdx(GUIUtil::g_font_registry.GetWeightNormalDefault()); - int nIndexBold = GUIUtil::g_font_registry.WeightToIdx(GUIUtil::g_font_registry.GetWeightBoldDefault()); - assert(nIndexNormal != -1 && nIndexBold != -1); - updateFontWeightNormal(nIndexNormal, true); - updateFontWeightBold(nIndexBold, true); + if (fForce) { + updateFontWeightNormal(GUIUtil::defaultWeightArg(GUIUtil::FontWeight::Normal), true); + updateFontWeightBold(GUIUtil::defaultWeightArg(GUIUtil::FontWeight::Bold), true); + } +} + +void AppearanceWidget::setupAppearance(QWidget* parent, OptionsModel* model) +{ + if (!QSettings().value("fAppearanceSetupDone", false).toBool()) { + // Create the dialog + QDialog dlg(parent); + dlg.setObjectName("AppearanceSetup"); + dlg.setWindowTitle(QObject::tr("Appearance Setup")); + dlg.setWindowIcon(QIcon(":icons/dash")); + // And the widgets we add to it + QLabel lblHeading(QObject::tr("Please choose your preferred settings for the appearance of %1").arg(PACKAGE_NAME), &dlg); + lblHeading.setObjectName("lblHeading"); + lblHeading.setWordWrap(true); + QLabel lblSubHeading(QObject::tr("This can also be adjusted later in the \"Appearance\" tab of the preferences."), &dlg); + lblSubHeading.setObjectName("lblSubHeading"); + lblSubHeading.setWordWrap(true); + AppearanceWidget appearance(&dlg); + appearance.setModel(model); + QFrame line(&dlg); + line.setFrameShape(QFrame::HLine); + QDialogButtonBox buttonBox(QDialogButtonBox::Save); + // Put them into a vbox and add the vbox to the dialog + QVBoxLayout layout; + layout.addWidget(&lblHeading); + layout.addWidget(&lblSubHeading); + layout.addWidget(&line); + layout.addWidget(&appearance); + layout.addWidget(&buttonBox); + dlg.setLayout(&layout); + // Adjust the headings + GUIUtil::setFont({&lblHeading}, GUIUtil::FontWeight::Bold, 16); + GUIUtil::setFont({&lblSubHeading}, GUIUtil::FontWeight::Normal, 14, true); + // Make sure the dialog closes and accepts the settings if save has been pressed + QObject::connect(&buttonBox, &QDialogButtonBox::accepted, [&]() { + QSettings().setValue("fAppearanceSetupDone", true); + appearance.accept(); + dlg.accept(); + }); + // And fire it! + dlg.exec(); } } diff --git a/src/qt/appearancewidget.h b/src/qt/appearancewidget.h index 3080a5f87e76..2fa1f9b8b769 100644 --- a/src/qt/appearancewidget.h +++ b/src/qt/appearancewidget.h @@ -7,8 +7,6 @@ #include -#include -#include #include namespace Ui { @@ -51,11 +49,17 @@ private Q_SLOTS: QString prevTheme; int prevScale; QString prevFontFamily; - QFont::Weight prevWeightNormal; - QFont::Weight prevWeightBold; + //! Snapshots stored as -font-weight-* arg ints (0..8), matching slider values. + int prevWeightNormalArg; + int prevWeightBoldArg; OptionsModel::FontChoice prevMoneyFont{OptionsModel::FontChoiceAbstract::ApplicationFont}; void updateWeightSlider(bool fForce = false); + +public: + // Setup appearance settings if not done yet + static void setupAppearance(QWidget* parent, OptionsModel* model); + }; #endif // BITCOIN_QT_APPEARANCEWIDGET_H diff --git a/src/qt/askpassphrasedialog.cpp b/src/qt/askpassphrasedialog.cpp index e79a97e33afd..ffdc26c12dfc 100644 --- a/src/qt/askpassphrasedialog.cpp +++ b/src/qt/askpassphrasedialog.cpp @@ -12,7 +12,6 @@ #include #include -#include #include #include @@ -29,7 +28,7 @@ AskPassphraseDialog::AskPassphraseDialog(Mode _mode, QWidget *parent, SecureStri { ui->setupUi(this); - GUIUtil::setFont({ui->capsLabel}, {GUIUtil::FontWeight::Bold}); + GUIUtil::setFont({ui->capsLabel}, GUIUtil::FontWeight::Bold); GUIUtil::updateFonts(); diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index 08132c0a3848..1adb129f5bb8 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -18,11 +18,11 @@ #include #include #include +#include #include #include #include #include -#include #include #include #include @@ -412,7 +412,7 @@ void BitcoinApplication::initializeResult(bool success, interfaces::BlockAndHead m_splash = nullptr; // Log this only after AppInitMain finishes, as then logging setup is guaranteed complete - qInfo() << "Platform customization:" << gArgs.GetArg("-uiplatform", BitcoinGUI::DEFAULT_UIPLATFORM).c_str(); + qInfo() << "Platform customization:" << gArgs.GetArg("-uiplatform", GUIUtil::defaultUIPlatform()).c_str(); clientModel = new ClientModel(node(), optionsModel); window->setClientModel(clientModel, &tip_info); @@ -439,7 +439,7 @@ void BitcoinApplication::initializeResult(bool success, interfaces::BlockAndHead Q_EMIT windowShown(window); // Let the users setup their preferred appearance if there are no settings for it defined yet. - GUIUtil::setupAppearance(window, clientModel->getOptionsModel()); + AppearanceWidget::setupAppearance(window, clientModel->getOptionsModel()); #ifdef ENABLE_WALLET // Now that initialization/startup is done, process any command-line @@ -500,15 +500,19 @@ 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::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); + std::vector selectable_fonts; + for (const auto& [name, selectable] : GUIUtil::knownFonts()) { + if (selectable) selectable_fonts.push_back(name); + } + argsman.AddArg("-font-family", QObject::tr("Set the font family. Possible values: %1. (default: %2)").arg(Join(selectable_fonts, ", ")).arg(GUIUtil::defaultFontFamily()).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::defaultFontScale()).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::defaultWeightArg(GUIUtil::FontWeight::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::defaultWeightArg(GUIUtil::FontWeight::Normal)).toStdString(), ArgsManager::ALLOW_ANY, OptionsCategory::GUI); argsman.AddArg("-lang=", QObject::tr("Set language, for example \"de_DE\" (default: system locale)").toStdString(), ArgsManager::ALLOW_ANY, OptionsCategory::GUI); argsman.AddArg("-min", QObject::tr("Start minimized").toStdString(), ArgsManager::ALLOW_ANY, OptionsCategory::GUI); argsman.AddArg("-resetguisettings", QObject::tr("Reset all settings changed in the GUI").toStdString(), ArgsManager::ALLOW_ANY, OptionsCategory::GUI); argsman.AddArg("-splash", strprintf(QObject::tr("Show splash screen on startup (default: %u)").toStdString(), DEFAULT_SPLASHSCREEN), ArgsManager::ALLOW_ANY, OptionsCategory::GUI); - argsman.AddArg("-uiplatform", strprintf("Select platform to customize UI for (one of windows, macosx, other; default: %s)", BitcoinGUI::DEFAULT_UIPLATFORM), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::GUI); + argsman.AddArg("-uiplatform", strprintf("Select platform to customize UI for (one of windows, macosx, other; default: %s)", GUIUtil::defaultUIPlatform()), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::GUI); argsman.AddArg("-debug-ui", "Updates the UI's stylesheets in realtime with changes made to the css files in -custom-css-dir and forces some widgets to show up which are usually only visible under certain circumstances. (default: 0)", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::GUI); argsman.AddArg("-windowtitle=", _("Sets a window title which is appended to \"Dash Core - \"").translated, ArgsManager::ALLOW_ANY, OptionsCategory::GUI); } @@ -546,7 +550,6 @@ int GuiMain(int argc, char* argv[]) #endif BitcoinApplication app; - GUIUtil::LoadFont(QStringLiteral(":/fonts/monospace")); /// 2. Parse command-line options. We do this after qt in order to show an error if there are problems parsing these // Command-line options take precedence: @@ -719,42 +722,40 @@ 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, /*selectable=*/true) || !GUIUtil::g_font_registry.SetFont(family)) { + const QString family = QString::fromStdString(gArgs.GetArg("-font-family", "")); + if (!GUIUtil::setActiveFont(family)) { QMessageBox::critical(nullptr, PACKAGE_NAME, QObject::tr("Error: Font \"%1\" could not be loaded.").arg(family)); return EXIT_FAILURE; } } // Validate/set normal font weight if (gArgs.IsArgSet("-font-weight-normal")) { - QFont::Weight weight; - if (!GUIUtil::weightFromArg(gArgs.GetIntArg("-font-weight-normal", GUIUtil::weightToArg(GUIUtil::g_font_registry.GetWeightNormal())), weight)) { + const int arg = gArgs.GetIntArg("-font-weight-normal", GUIUtil::currentWeightArg(GUIUtil::FontWeight::Normal)); + if (!GUIUtil::setWeightFromArg(GUIUtil::FontWeight::Normal, arg)) { QMessageBox::critical(nullptr, PACKAGE_NAME, QObject::tr("Error: Specified font-weight-normal invalid. Valid range %1 to %2.").arg(0).arg(8)); return EXIT_FAILURE; } - GUIUtil::g_font_registry.SetWeightNormal(weight); } // Validate/set bold font weight if (gArgs.IsArgSet("-font-weight-bold")) { - QFont::Weight weight; - if (!GUIUtil::weightFromArg(gArgs.GetIntArg("-font-weight-bold", GUIUtil::weightToArg(GUIUtil::g_font_registry.GetWeightBold())), weight)) { + const int arg = gArgs.GetIntArg("-font-weight-bold", GUIUtil::currentWeightArg(GUIUtil::FontWeight::Bold)); + if (!GUIUtil::setWeightFromArg(GUIUtil::FontWeight::Bold, arg)) { QMessageBox::critical(nullptr, PACKAGE_NAME, QObject::tr("Error: Specified font-weight-bold invalid. Valid range %1 to %2.").arg(0).arg(8)); return EXIT_FAILURE; } - GUIUtil::g_font_registry.SetWeightBold(weight); } // Validate/set font scale if (gArgs.IsArgSet("-font-scale")) { const int nScaleMin = -100, nScaleMax = 100; - int nScale = gArgs.GetIntArg("-font-scale", GUIUtil::g_font_registry.GetFontScale()); + int nScale = gArgs.GetIntArg("-font-scale", GUIUtil::fontScale()); if (nScale < nScaleMin || nScale > nScaleMax) { QMessageBox::critical(nullptr, PACKAGE_NAME, QObject::tr("Error: Specified font-scale invalid. Valid range %1 to %2.").arg(nScaleMin).arg(nScaleMax)); return EXIT_FAILURE; } - GUIUtil::g_font_registry.SetFontScale(nScale); + GUIUtil::setFontScale(nScale); } // Apply font changes GUIUtil::updateFonts(); diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 8f6800b482ec..4c581111961a 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include @@ -87,16 +86,6 @@ constexpr int GOV_CYCLE_FRAME_MS{STATUSBAR_ICON_CYCLE_MS / (GOV_CYCLE_FRAME_COUN constexpr int SPINNER_FRAME_MS{STATUSBAR_ICON_CYCLE_MS / SPINNER_FRAMES}; } // anonymous namespace -const std::string BitcoinGUI::DEFAULT_UIPLATFORM = -#if defined(Q_OS_MACOS) - "macosx" -#elif defined(Q_OS_WIN) - "windows" -#else - "other" -#endif - ; - BitcoinGUI::BitcoinGUI(interfaces::Node& node, const NetworkStyle* networkStyle, QWidget* parent) : QMainWindow(parent), m_node(node), @@ -795,7 +784,7 @@ void BitcoinGUI::createToolBars() connect(tabGroup, qOverload(&QButtonGroup::buttonToggled), this, &BitcoinGUI::highlightTabButton); for (auto button : tabGroup->buttons()) { - GUIUtil::setFont({button}, {GUIUtil::FontWeight::Normal, 16}); + GUIUtil::setFont({button}, GUIUtil::FontWeight::Normal, 16); button->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); button->setToolTip(button->statusTip()); button->setCheckable(true); @@ -1305,7 +1294,7 @@ void BitcoinGUI::openClicked() void BitcoinGUI::highlightTabButton(QAbstractButton *button, bool checked) { - GUIUtil::setFont({button}, {checked ? GUIUtil::FontWeight::Bold : GUIUtil::FontWeight::Normal, 16}); + GUIUtil::setFont({button}, checked ? GUIUtil::FontWeight::Bold : GUIUtil::FontWeight::Normal, 16); GUIUtil::updateFonts(); } diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h index 670ce48f084b..333ef538d412 100644 --- a/src/qt/bitcoingui.h +++ b/src/qt/bitcoingui.h @@ -74,8 +74,6 @@ class BitcoinGUI : public QMainWindow Q_OBJECT public: - static const std::string DEFAULT_UIPLATFORM; - explicit BitcoinGUI(interfaces::Node& node, const NetworkStyle* networkStyle, QWidget* parent = nullptr); ~BitcoinGUI(); diff --git a/src/qt/coincontroldialog.cpp b/src/qt/coincontroldialog.cpp index 74e6167ac8aa..487693a498a3 100644 --- a/src/qt/coincontroldialog.cpp +++ b/src/qt/coincontroldialog.cpp @@ -13,7 +13,6 @@ #include #include #include -#include #include #include @@ -67,7 +66,7 @@ CoinControlDialog::CoinControlDialog(CCoinControl& coin_control, WalletModel* _m ui->labelCoinControlFeeText, ui->labelCoinControlAfterFeeText, ui->labelCoinControlChangeText - }, {GUIUtil::FontWeight::Bold}); + }, GUIUtil::FontWeight::Bold); GUIUtil::updateFonts(); diff --git a/src/qt/descriptiondialog.cpp b/src/qt/descriptiondialog.cpp index 164939d3f284..4665727a1a6a 100644 --- a/src/qt/descriptiondialog.cpp +++ b/src/qt/descriptiondialog.cpp @@ -6,7 +6,6 @@ #include #include -#include #include @@ -16,7 +15,7 @@ DescriptionDialog::DescriptionDialog(const QString& title, const QString& html, { ui->setupUi(this); setWindowTitle(title); - GUIUtil::registerWidget(ui->detailText, html); + GUIUtil::setStyledHtml(ui->detailText, html); GUIUtil::updateFonts(); GUIUtil::handleCloseWindowShortcut(this); } diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp index 2b02ac80e1a4..af5210ce36c0 100644 --- a/src/qt/guiutil.cpp +++ b/src/qt/guiutil.cpp @@ -5,9 +5,7 @@ #include -#include #include -#include #include #include #include @@ -41,7 +39,6 @@ #include #include #include -#include #include #include #include @@ -166,6 +163,17 @@ static const std::map themedDarkStyles = { { ThemedStyle::TS_SECONDARY, "color:#aaa;" }, }; +std::string defaultUIPlatform() +{ +#if defined(Q_OS_MACOS) + return "macosx"; +#elif defined(Q_OS_WIN) + return "windows"; +#else + return "other"; +#endif +} + QColor getThemedQColor(ThemedColor color) { QString theme = QSettings().value("theme", "").toString(); @@ -260,48 +268,6 @@ void setupAddressWidget(QValidatedLineEdit *widget, QWidget *parent, bool fAllow widget->setCheckValidator(new BitcoinAddressCheckValidator(parent)); } -void setupAppearance(QWidget* parent, OptionsModel* model) -{ - if (!QSettings().value("fAppearanceSetupDone", false).toBool()) { - // Create the dialog - QDialog dlg(parent); - dlg.setObjectName("AppearanceSetup"); - dlg.setWindowTitle(QObject::tr("Appearance Setup")); - dlg.setWindowIcon(QIcon(":icons/dash")); - // And the widgets we add to it - QLabel lblHeading(QObject::tr("Please choose your preferred settings for the appearance of %1").arg(PACKAGE_NAME), &dlg); - lblHeading.setObjectName("lblHeading"); - lblHeading.setWordWrap(true); - QLabel lblSubHeading(QObject::tr("This can also be adjusted later in the \"Appearance\" tab of the preferences."), &dlg); - lblSubHeading.setObjectName("lblSubHeading"); - lblSubHeading.setWordWrap(true); - AppearanceWidget appearance(&dlg); - appearance.setModel(model); - QFrame line(&dlg); - line.setFrameShape(QFrame::HLine); - QDialogButtonBox buttonBox(QDialogButtonBox::Save); - // Put them into a vbox and add the vbox to the dialog - QVBoxLayout layout; - layout.addWidget(&lblHeading); - layout.addWidget(&lblSubHeading); - layout.addWidget(&line); - layout.addWidget(&appearance); - layout.addWidget(&buttonBox); - dlg.setLayout(&layout); - // Adjust the headings - setFont({&lblHeading}, {GUIUtil::FontWeight::Bold, 16}); - setFont({&lblSubHeading}, {GUIUtil::FontWeight::Normal, 14, true}); - // Make sure the dialog closes and accepts the settings if save has been pressed - QObject::connect(&buttonBox, &QDialogButtonBox::accepted, [&]() { - QSettings().setValue("fAppearanceSetupDone", true); - appearance.accept(); - dlg.accept(); - }); - // And fire it! - dlg.exec(); - } -} - void AddButtonShortcut(QAbstractButton* button, const QKeySequence& shortcut) { QObject::connect(new QShortcut(shortcut, button), &QShortcut::activated, [button]() { button->animateClick(); }); @@ -475,12 +441,6 @@ bool hasEntryData(const QAbstractItemView *view, int column, int role) return !selection.at(0).data(role).toString().isEmpty(); } -void LoadFont(const QString& file_name) -{ - const int id = QFontDatabase::addApplicationFont(file_name); - assert(id != -1); -} - QString getDefaultDataDirectory() { return PathToQString(GetDefaultDataDir()); @@ -926,7 +886,7 @@ void loadStyleSheet(bool fForceUpdate) return false; } - std::string platformName = gArgs.GetArg("-uiplatform", BitcoinGUI::DEFAULT_UIPLATFORM); + std::string platformName = gArgs.GetArg("-uiplatform", defaultUIPlatform()); stylesheet = std::make_unique(); for (const auto& file : vecFiles) { diff --git a/src/qt/guiutil.h b/src/qt/guiutil.h index 3a9b9240400a..33db7b82c511 100644 --- a/src/qt/guiutil.h +++ b/src/qt/guiutil.h @@ -25,11 +25,13 @@ #include #include +#include #include +#include #include +#include class QValidatedLineEdit; -class OptionsModel; class SendCoinsRecipient; namespace interfaces @@ -50,6 +52,7 @@ class QLineEdit; class QMenu; class QPoint; class QProgressDialog; +class QTextEdit; class QUrl; class QWidget; QT_END_NAMESPACE @@ -58,6 +61,9 @@ QT_END_NAMESPACE */ namespace GUIUtil { + /** Default value for the `-uiplatform` arg ("macosx" / "windows" / "other"). */ + std::string defaultUIPlatform(); + /* Enumeration of possible "colors" */ enum class ThemedColor { /* Transaction list -- TX status decoration - default color */ @@ -128,12 +134,12 @@ 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); - // Setup appearance settings if not done yet - void setupAppearance(QWidget* parent, OptionsModel* model); - /** * Connects an additional shortcut to a QAbstractButton. Works around the * one shortcut limitation of the button's shortcut property. @@ -182,10 +188,60 @@ namespace GUIUtil void setClipboard(const QString& str); - /** - * Loads the font from the file specified by file_name, aborts if it fails. - */ - void LoadFont(const QString& file_name); + enum class FontWeight : uint8_t { + Normal, + Bold, + }; + + /** Load Dash-specific application fonts. Returns false if any failed to load. */ + bool loadFonts(); + /** True once loadFonts() has completed successfully. */ + bool fontsLoaded(); + /** Set the application-wide default font (depends on active font/theme). */ + void setApplicationFont(); + + /** Defaults for the `-font-*` CLI options (used in arg help and as persistence fallbacks). */ + int defaultFontScale(); + int defaultFontSize(); + QString defaultFontFamily(); + + /** Switch the active font family. Registers `font_name` if unknown and applies it to qApp. + * Empty `font_name` means "use defaultFontFamily()". No-op if loadFonts() hasn't run. */ + bool setActiveFont(const QString& font_name = {}); + QString activeFont(); + /** Known fonts and their "selectable in UI" flag, in registration order. */ + const std::vector>& knownFonts(); + + void setFontScale(int font_scale); + int fontScale(); + + /* Weight operations expressed as caller-friendly arg ints 0..8 -- the format used by + * `-font-weight-*` CLI args and QSettings persistence. */ + int currentWeightArg(FontWeight slot); + /** Default-best-match weight for `slot`. Valid before loadFonts() too. */ + int defaultWeightArg(FontWeight slot); + /** Apply a weight. Returns false if `arg` is out of 0..8 or unsupported by the active + * font (no state change in that case). */ + bool setWeightFromArg(FontWeight slot, int arg); + /** Active font's supported weight args, low-to-high. */ + std::vector supportedWeightArgs(); + + /** Register `widgets` to receive the given font attributes on the next updateFonts() pass. + * Uses the currently active font family unless one is given explicitly. */ + void setFont(const std::vector& widgets, FontWeight weight, double point_size = -1, bool is_italic = false); + void setFont(const std::vector& widgets, const QString& font, FontWeight weight, double point_size = -1, bool is_italic = false); + /** Re-apply fonts to all widgets previously registered via setFont(). */ + void updateFonts(); + + /** Get the default bold / normal QFont. */ + QFont getFontBold(); + QFont getFontNormal(); + /** Get a scaled font with the given base size, weight, and optional multiplier. */ + QFont getScaledFont(double baseSize, bool bold, double multiplier = 1); + + /** Set HTML content on a QTextEdit with font-aware styling. Captures the widget's base + * point size on first call so re-application on font/theme changes preserves it. */ + void setStyledHtml(QTextEdit* widget, const QString& html); /** * Determine default data directory for operating system. diff --git a/src/qt/guiutil_font.cpp b/src/qt/guiutil_font.cpp index d7cd9c7895be..966c0ecd1f36 100644 --- a/src/qt/guiutil_font.cpp +++ b/src/qt/guiutil_font.cpp @@ -2,7 +2,7 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include +#include #include @@ -10,16 +10,17 @@ #include #include -#include - #include #include +#include #include #include #include +#include #include #include #include +#include #include #include @@ -28,6 +29,119 @@ #include namespace { +// TODO: Switch to QUtf8StringView when we switch to Qt 6 +constexpr QStringView MONTSERRAT_FONT_STR{u"Montserrat"}; +constexpr QStringView OS_FONT_STR{u"SystemDefault"}; +constexpr QStringView OS_MONO_FONT_STR{u"SystemMonospace"}; +constexpr QStringView ROBOTO_MONO_FONT_STR{u"Roboto Mono"}; + +constexpr int DEFAULT_FONT_SCALE{0}; +constexpr int DEFAULT_FONT_SIZE{12}; +constexpr QStringView DEFAULT_FONT{OS_FONT_STR}; +constexpr QFont::Weight TARGET_WEIGHT_BOLD{QFont::Medium}; +constexpr QFont::Weight TARGET_WEIGHT_NORMAL{ +#ifdef Q_OS_MACOS + QFont::ExtraLight +#else + QFont::Light +#endif // Q_OS_MACOS +}; + +//! Per-widget styling request — what setFont() captures into mapFontUpdates. +struct FontAttrib { + QString m_font; + GUIUtil::FontWeight m_weight_type; + double m_point_size{-1}; + bool m_is_italic{false}; +}; + +//! Per-font weight cache (defaults + user-selected bold/normal + supported list). +struct FontInfo { + QFont::Weight m_bold; + QFont::Weight m_bold_default; + QFont::Weight m_normal; + QFont::Weight m_normal_default; + std::vector m_supported_weights; + + FontInfo() = delete; + explicit FontInfo(const QString& font_name); + ~FontInfo(); + +private: + QFont::Weight GetBestMatch(const QString& font_name, QFont::Weight target); + void CalcDefaultWeights(const QString& font_name); + void CalcSupportedWeights(const QString& font_name); +}; + +//! Global font state (active family, scale, per-font cache). File-private — +//! external callers go through the free-function API in qt/guiutil.h. +class FontRegistry { +public: + [[nodiscard]] bool RegisterFont(const QString& font, bool selectable, bool skip_checks = false); + + bool IsValidWeight(const QFont::Weight& weight) const; + + [[nodiscard]] bool SetFont(const QString& font); + void SetFontScale(int font_scale) { m_font_scale = font_scale; } + void SetWeightBold(const QFont::Weight& bold) + { + assert(m_weights.count(m_font)); + m_weights.at(m_font).m_bold = bold; + } + void SetWeightNormal(const QFont::Weight& normal) + { + assert(m_weights.count(m_font)); + m_weights.at(m_font).m_normal = normal; + } + + double GetScaledFontSize(double size) const { return std::round(size * (1 + (m_font_scale * m_scale_steps)) * 4) / 4.0; } + QString GetFont() const { return m_font; } + int GetFontScale() const { return m_font_scale; } + int GetFontSize() const { return m_font_size; } + QFont::Weight GetWeightBold() const + { + if (auto it = m_weights.find(m_font); it != m_weights.end()) { return it->second.m_bold; } + return TARGET_WEIGHT_BOLD; + } + QFont::Weight GetWeightNormal() const + { + if (auto it = m_weights.find(m_font); it != m_weights.end()) { return it->second.m_normal; } + return TARGET_WEIGHT_NORMAL; + } + QFont::Weight GetWeightBoldDefault() const + { + if (auto it = m_weights.find(m_font); it != m_weights.end()) { return it->second.m_bold_default; } + return TARGET_WEIGHT_BOLD; + } + QFont::Weight GetWeightNormalDefault() const + { + if (auto it = m_weights.find(m_font); it != m_weights.end()) { return it->second.m_normal_default; } + return TARGET_WEIGHT_NORMAL; + } + std::vector GetSupportedWeights() const + { + if (auto it = m_weights.find(m_font); it != m_weights.end()) { return it->second.m_supported_weights; } + return {TARGET_WEIGHT_NORMAL, TARGET_WEIGHT_BOLD}; + } + +private: + double m_scale_steps{0.01}; + QString m_font{DEFAULT_FONT.toUtf8()}; + int m_font_scale{DEFAULT_FONT_SCALE}; + int m_font_size{DEFAULT_FONT_SIZE}; + std::map m_weights; +}; + +FontRegistry g_font_registry; + +//! Fonts known by the client +std::vector> g_fonts_known{ + {MONTSERRAT_FONT_STR.toUtf8(), true}, + {OS_FONT_STR.toUtf8(), true}, + {OS_MONO_FONT_STR.toUtf8(), false}, + {ROBOTO_MONO_FONT_STR.toUtf8(), false}, +}; + //! Instance of font database shared among calls std::unique_ptr g_font_db{nullptr}; @@ -42,7 +156,7 @@ std::map mapClassFontUpdates{ }; //! Contains all widgets and its font attributes (weight, italic, size) with font changes due to GUIUtil::setFont -std::map, GUIUtil::FontAttrib> mapFontUpdates; +std::map, FontAttrib> mapFontUpdates; //! Contains QTextEdit widgets with the original base font size and HTML struct TextEditStyleData { @@ -127,8 +241,24 @@ QString qstrprintf(const std::string& fmt, const Args&... args) return QString::fromStdString(tfm::format(fmt, args...)); } +bool weightFromArg(int nArg, QFont::Weight& weight) +{ + auto it = mapWeightArgs.first.find(nArg); + if (it == mapWeightArgs.first.end()) { + return false; + } + weight = it->second; + return true; +} + +int weightToArg(const QFont::Weight weight) +{ + assert(mapWeightArgs.second.count(weight)); + return mapWeightArgs.second.find(weight)->second; +} + //! Returns a properly weighted QFont object with the selected font -QFont getFont(const GUIUtil::FontAttrib& font_attrib) +QFont getFont(const FontAttrib& font_attrib) { QFont font; if (!GUIUtil::fontsLoaded()) { @@ -137,9 +267,9 @@ QFont getFont(const GUIUtil::FontAttrib& font_attrib) // Resolve weight from FontWeight type const QFont::Weight weight = (font_attrib.m_weight_type == GUIUtil::FontWeight::Bold) - ? GUIUtil::g_font_registry.GetWeightBold() : GUIUtil::g_font_registry.GetWeightNormal(); + ? g_font_registry.GetWeightBold() : g_font_registry.GetWeightNormal(); - if (font_attrib.m_font == GUIUtil::MONTSERRAT_FONT_STR) { + if (font_attrib.m_font == MONTSERRAT_FONT_STR) { assert(mapMontserrat.count(weight)); #ifdef Q_OS_MACOS font.setFamily(font_attrib.m_font); @@ -161,20 +291,20 @@ QFont getFont(const GUIUtil::FontAttrib& font_attrib) font.setFamily(qstrprintf("%s %s", font_attrib.m_font.toStdString(), mapMontserrat.at(weight).first)); } #endif // Q_OS_MACOS - } else if (font_attrib.m_font == GUIUtil::OS_FONT_STR) { + } else if (font_attrib.m_font == OS_FONT_STR) { font.setFamily(g_default_font->family()); - } else if (font_attrib.m_font == GUIUtil::OS_MONO_FONT_STR) { + } else if (font_attrib.m_font == OS_MONO_FONT_STR) { font.setFamily(QFontDatabase::systemFont(QFontDatabase::FixedFont).family()); } else { font.setFamily(font_attrib.m_font); } - if (font_attrib.m_font == GUIUtil::ROBOTO_MONO_FONT_STR || font_attrib.m_font == GUIUtil::OS_MONO_FONT_STR) { + if (font_attrib.m_font == ROBOTO_MONO_FONT_STR || font_attrib.m_font == OS_MONO_FONT_STR) { font.setStyleHint(QFont::Monospace); } #ifdef Q_OS_MACOS - if (font_attrib.m_font != GUIUtil::MONTSERRAT_FONT_STR) + if (font_attrib.m_font != MONTSERRAT_FONT_STR) #endif // Q_OS_MACOS { font.setWeight(weight); @@ -182,7 +312,7 @@ QFont getFont(const GUIUtil::FontAttrib& font_attrib) } if (font_attrib.m_point_size != -1) { - font.setPointSizeF(GUIUtil::g_font_registry.GetScaledFontSize(font_attrib.m_point_size)); + font.setPointSizeF(g_font_registry.GetScaledFontSize(font_attrib.m_point_size)); } if (gArgs.GetBoolArg("-debug-ui", false)) { @@ -257,88 +387,16 @@ void setFontBodyHTML(QTextEdit* widget, const QString& src, double base_size) } #endif // Q_OS_MACOS if (scale_add > 0) { - fmt.setFontPointSize(GUIUtil::g_font_registry.GetScaledFontSize(base_size * (1 + scale_add))); + fmt.setFontPointSize(g_font_registry.GetScaledFontSize(base_size * (1 + scale_add))); } cursor.mergeCharFormat(fmt); } } } } -} // anonymous namespace - -namespace GUIUtil { -//! Fonts known by the client -std::vector> g_fonts_known{ - {MONTSERRAT_FONT_STR.toUtf8(), true}, - {OS_FONT_STR.toUtf8(), true}, - {OS_MONO_FONT_STR.toUtf8(), false}, - {ROBOTO_MONO_FONT_STR.toUtf8(), false}, -}; - -FontRegistry g_font_registry; - -FontInfo::FontInfo(const QString& font_name) -{ - CalcSupportedWeights(font_name); - CalcDefaultWeights(font_name); - m_bold = m_bold_default; - m_normal = m_normal_default; -} - -FontInfo::~FontInfo() = default; - -bool FontRegistry::RegisterFont(const QString& font, bool selectable, bool skip_checks) -{ - const auto font_strs{getFonts(/*selectable_only=*/false)}; - auto font_it{std::find(font_strs.begin(), font_strs.end(), font)}; - if (m_weights.count(font)) { - // Font's already registered - assert(font_it != font_strs.end()); - // Overwrite selectable flag - g_fonts_known.at(std::distance(font_strs.begin(), font_it)).second = selectable; - return true; - } - if (!skip_checks) { - if (!g_font_db) { g_font_db = std::make_unique(); } - if (!g_font_db->families().contains(font, Qt::CaseInsensitive)) { - // Font doesn't exist - return false; - } - } - m_weights.emplace(font, FontInfo(font)); - if (font_it == font_strs.end()) { - g_fonts_known.emplace_back(font, selectable); - } - return true; -} - -bool FontRegistry::SetFont(const QString& font) -{ - if (!m_weights.count(font)) { - return false; - } - m_font = font; - return true; -} - -bool weightFromArg(int nArg, QFont::Weight& weight) -{ - auto it = mapWeightArgs.first.find(nArg); - if (it == mapWeightArgs.first.end()) { - return false; - } - weight = it->second; - return true; -} - -int weightToArg(const QFont::Weight weight) -{ - assert(mapWeightArgs.second.count(weight)); - return mapWeightArgs.second.find(weight)->second; -} //! Internal helper to create a font with explicit weight (used for font detection) -static QFont getFontWithWeight(const QString& font_name, QFont::Weight weight, double point_size) +QFont getFontWithWeight(const QString& font_name, QFont::Weight weight, double point_size) { QFont font; if (font_name == MONTSERRAT_FONT_STR) { @@ -369,11 +427,21 @@ static QFont getFontWithWeight(const QString& font_name, QFont::Weight weight, d return font; } +FontInfo::FontInfo(const QString& font_name) +{ + CalcSupportedWeights(font_name); + CalcDefaultWeights(font_name); + m_bold = m_bold_default; + m_normal = m_normal_default; +} + +FontInfo::~FontInfo() = default; + void FontInfo::CalcSupportedWeights(const QString& font_name) { auto getTestWidth = [](const QString& font_name, QFont::Weight weight) -> int { - QFont font = getFontWithWeight(font_name, weight, FontRegistry::DEFAULT_FONT_SIZE); - return TextWidth(QFontMetrics(font), ("Check the width of this text to see if the weight change has an impact!")); + QFont font = getFontWithWeight(font_name, weight, DEFAULT_FONT_SIZE); + return GUIUtil::TextWidth(QFontMetrics(font), ("Check the width of this text to see if the weight change has an impact!")); }; QFont::Weight prevWeight = vecWeightConsider.front(); bool isFirst = true; @@ -415,8 +483,8 @@ void FontInfo::CalcDefaultWeights(const QString& font_name) { assert(!m_supported_weights.empty()); - m_normal_default = GetBestMatch(font_name, FontRegistry::TARGET_WEIGHT_NORMAL); - m_bold_default = GetBestMatch(font_name, FontRegistry::TARGET_WEIGHT_BOLD); + m_normal_default = GetBestMatch(font_name, TARGET_WEIGHT_NORMAL); + m_bold_default = GetBestMatch(font_name, TARGET_WEIGHT_BOLD); if (m_normal_default == m_bold_default) { // If the results are the same use the next possible weight for bold font auto it = std::find(m_supported_weights.begin(), m_supported_weights.end(), m_normal_default); @@ -426,23 +494,99 @@ void FontInfo::CalcDefaultWeights(const QString& font_name) } } -FontAttrib::FontAttrib(QString font, FontWeight weight_type, double point_size, bool is_italic) : - m_font{font}, - m_weight_type{weight_type}, - m_point_size{point_size}, - m_is_italic{is_italic} +bool FontRegistry::RegisterFont(const QString& font, bool selectable, bool skip_checks) { + auto font_it = std::find_if(g_fonts_known.begin(), g_fonts_known.end(), + [&](const auto& p) { return p.first == font; }); + if (m_weights.count(font)) { + // Font's already registered — overwrite selectable flag + assert(font_it != g_fonts_known.end()); + font_it->second = selectable; + return true; + } + if (!skip_checks) { + if (!g_font_db) { g_font_db = std::make_unique(); } + if (!g_font_db->families().contains(font, Qt::CaseInsensitive)) { + // Font doesn't exist + return false; + } + } + m_weights.emplace(font, FontInfo(font)); + if (font_it == g_fonts_known.end()) { + g_fonts_known.emplace_back(font, selectable); + } + return true; } -FontAttrib::FontAttrib(FontWeight weight_type, double point_size, bool is_italic) : - m_font{g_font_registry.GetFont()}, - m_weight_type{weight_type}, - m_point_size{point_size}, - m_is_italic{is_italic} +bool FontRegistry::SetFont(const QString& font) { + if (!m_weights.count(font)) { + return false; + } + m_font = font; + return true; } -FontAttrib::~FontAttrib() = default; +bool FontRegistry::IsValidWeight(const QFont::Weight& weight) const +{ + const auto supported = GetSupportedWeights(); + return std::find(supported.begin(), supported.end(), weight) != supported.end(); +} +} // anonymous namespace + +namespace GUIUtil { + +int defaultFontScale() { return DEFAULT_FONT_SCALE; } +int defaultFontSize() { return DEFAULT_FONT_SIZE; } +QString defaultFontFamily() { return DEFAULT_FONT.toString(); } + +bool setActiveFont(const QString& font_name) +{ + if (!fontsLoaded()) return false; + const QString name = font_name.isEmpty() ? defaultFontFamily() : font_name; + if (!g_font_registry.RegisterFont(name, /*selectable=*/true)) return false; + if (!g_font_registry.SetFont(name)) return false; + setApplicationFont(); + return true; +} +QString activeFont() { return g_font_registry.GetFont(); } +const std::vector>& knownFonts() { return g_fonts_known; } + +void setFontScale(int font_scale) { g_font_registry.SetFontScale(font_scale); } +int fontScale() { return g_font_registry.GetFontScale(); } + +int currentWeightArg(FontWeight slot) +{ + return weightToArg(slot == FontWeight::Bold ? g_font_registry.GetWeightBold() + : g_font_registry.GetWeightNormal()); +} + +int defaultWeightArg(FontWeight slot) +{ + return weightToArg(slot == FontWeight::Bold ? g_font_registry.GetWeightBoldDefault() + : g_font_registry.GetWeightNormalDefault()); +} + +bool setWeightFromArg(FontWeight slot, int arg) +{ + QFont::Weight weight; + if (!weightFromArg(arg, weight) || !g_font_registry.IsValidWeight(weight)) return false; + if (slot == FontWeight::Bold) { + g_font_registry.SetWeightBold(weight); + } else { + g_font_registry.SetWeightNormal(weight); + } + return true; +} + +std::vector supportedWeightArgs() +{ + std::vector ret; + for (const auto& w : g_font_registry.GetSupportedWeights()) { + ret.push_back(weightToArg(w)); + } + return ret; +} bool loadFonts() { @@ -455,6 +599,8 @@ bool loadFonts() qDebug() << qstrprintf("%s: %s loaded with id %d", __func__, font_name.toStdString(), vecFontIds.back()); }; + // Import the embedded Roboto Mono used by fixedPitchFont(use_embedded_font=true) + importFont(":fonts/monospace"); // Import the italic Montserrat variant as it doesn't map to a weight importFont(qstrprintf(":fonts/%s-Italic", MONTSERRAT_FONT_STR.toUtf8().toStdString())); // Import the rest of Montserrat variants @@ -538,8 +684,9 @@ void setApplicationFont() util::to_string(qApp->font().exactMatch())); } -void setFont(const std::vector& vecWidgets, const FontAttrib& font_attrib) +void setFont(const std::vector& vecWidgets, const QString& font, FontWeight weight, double point_size, bool is_italic) { + const FontAttrib font_attrib{font, weight, point_size, is_italic}; for (auto it : vecWidgets) { auto itFontUpdate = mapFontUpdates.emplace(std::make_pair(it, font_attrib)); if (!itFontUpdate.second) { @@ -548,6 +695,11 @@ void setFont(const std::vector& vecWidgets, const FontAttrib& font_att } } +void setFont(const std::vector& vecWidgets, FontWeight weight, double point_size, bool is_italic) +{ + setFont(vecWidgets, g_font_registry.GetFont(), weight, point_size, is_italic); +} + void updateFonts() { // Fonts need to be loaded by GUIUtil::loadFonts(), if not just return. @@ -636,51 +788,25 @@ void updateFonts() } } -std::vector getFonts(bool selectable_only) -{ - std::vector ret; - for (const auto& [font, selectable] : g_fonts_known) { - if (selectable || !selectable_only) { ret.emplace_back(font); } - } - return ret; -} - QFont getFontBold() { - return getFont({FontWeight::Bold}); + return getFont({g_font_registry.GetFont(), FontWeight::Bold}); } QFont getFontNormal() { - return getFont({FontWeight::Normal}); + return getFont({g_font_registry.GetFont(), FontWeight::Normal}); } QFont getScaledFont(double baseSize, bool bold, double multiplier) { return getFont({ + g_font_registry.GetFont(), bold ? FontWeight::Bold : FontWeight::Normal, baseSize * multiplier }); } -QFont::Weight FontRegistry::IdxToWeight(int index) const -{ - const auto vecWeights = GetSupportedWeights(); - assert(vecWeights.size() > uint64_t(index)); - return vecWeights.at(index); -} - -int FontRegistry::WeightToIdx(const QFont::Weight& weight) const -{ - const auto vecWeights = GetSupportedWeights(); - for (uint64_t index = 0; index < vecWeights.size(); ++index) { - if (weight == vecWeights.at(index)) { - return index; - } - } - return -1; -} - QFont fixedPitchFont(bool use_embedded_font) { return getFont({ @@ -689,10 +815,10 @@ QFont fixedPitchFont(bool use_embedded_font) }); } -void registerWidget(QTextEdit* widget, const QString& html) +void setStyledHtml(QTextEdit* widget, const QString& html) { if (!widget) return; - double base_size{FontRegistry::DEFAULT_FONT_SIZE}; + double base_size{DEFAULT_FONT_SIZE}; auto it{mapTextEditStyleUpdates.find(widget)}; if (it != mapTextEditStyleUpdates.end()) { // Widget already registered, preserve stored base_size and update HTML diff --git a/src/qt/guiutil_font.h b/src/qt/guiutil_font.h deleted file mode 100644 index 3268c2169524..000000000000 --- a/src/qt/guiutil_font.h +++ /dev/null @@ -1,180 +0,0 @@ -// Copyright (c) 2014-2025 The Dash Core developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#ifndef BITCOIN_QT_GUIUTIL_FONT_H -#define BITCOIN_QT_GUIUTIL_FONT_H - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -namespace GUIUtil { -// TODO: Switch to QUtf8StringView when we switch to Qt 6 -constexpr QStringView MONTSERRAT_FONT_STR{u"Montserrat"}; -constexpr QStringView OS_FONT_STR{u"SystemDefault"}; -constexpr QStringView OS_MONO_FONT_STR{u"SystemMonospace"}; -constexpr QStringView ROBOTO_MONO_FONT_STR{u"Roboto Mono"}; - -extern std::vector> g_fonts_known; - -enum class FontWeight : uint8_t { - Normal, - Bold, -}; - -struct FontInfo { - QFont::Weight m_bold; - QFont::Weight m_bold_default; - QFont::Weight m_normal; - QFont::Weight m_normal_default; - std::vector m_supported_weights; - - FontInfo() = delete; - explicit FontInfo(const QString& font_name); - ~FontInfo(); - -private: - QFont::Weight GetBestMatch(const QString& font_name, QFont::Weight target); - void CalcDefaultWeights(const QString& font_name); - void CalcSupportedWeights(const QString& font_name); -}; - -class FontRegistry { -public: - static constexpr int DEFAULT_FONT_SCALE{0}; - static constexpr int DEFAULT_FONT_SIZE{12}; - static constexpr QStringView DEFAULT_FONT{OS_FONT_STR}; - static constexpr QFont::Weight TARGET_WEIGHT_BOLD{QFont::Medium}; - static constexpr QFont::Weight TARGET_WEIGHT_NORMAL{ -#ifdef Q_OS_MACOS - QFont::ExtraLight -#else - QFont::Light -#endif // Q_OS_MACOS - }; - -public: - [[nodiscard]] bool RegisterFont(const QString& font, bool selectable, bool skip_checks = false); - - bool IsValidWeight(const QFont::Weight& weight) const { return WeightToIdx(weight) != -1; } - int WeightToIdx(const QFont::Weight& weight) const; - QFont::Weight IdxToWeight(int index) const; - - [[nodiscard]] bool SetFont(const QString& font); - void SetFontScale(int font_scale) { m_font_scale = font_scale; } - void SetWeightBold(const QFont::Weight& bold) - { - assert(m_weights.count(m_font)); - m_weights.at(m_font).m_bold = bold; - } - void SetWeightNormal(const QFont::Weight& normal) - { - assert(m_weights.count(m_font)); - m_weights.at(m_font).m_normal = normal; - } - - double GetScaleSteps() const { return m_scale_steps; } - double GetScaledFontSize(double size) const { return std::round(size * (1 + (m_font_scale * m_scale_steps)) * 4) / 4.0; } - QString GetFont() const { return m_font; } - int GetFontScale() const { return m_font_scale; } - int GetFontSize() const { return m_font_size; } - QFont::Weight GetWeightBold() const - { - if (auto it = m_weights.find(m_font); it != m_weights.end()) { return it->second.m_bold; } - return TARGET_WEIGHT_BOLD; - } - QFont::Weight GetWeightNormal() const - { - if (auto it = m_weights.find(m_font); it != m_weights.end()) { return it->second.m_normal; } - return TARGET_WEIGHT_NORMAL; - } - QFont::Weight GetWeightBoldDefault() const - { - if (auto it = m_weights.find(m_font); it != m_weights.end()) { return it->second.m_bold_default; } - return TARGET_WEIGHT_BOLD; - } - QFont::Weight GetWeightNormalDefault() const - { - if (auto it = m_weights.find(m_font); it != m_weights.end()) { return it->second.m_normal_default; } - return TARGET_WEIGHT_NORMAL; - } - std::vector GetSupportedWeights() const - { - if (auto it = m_weights.find(m_font); it != m_weights.end()) { return it->second.m_supported_weights; } - return {TARGET_WEIGHT_NORMAL, TARGET_WEIGHT_BOLD}; - } - -private: - double m_scale_steps{0.01}; - QString m_font{DEFAULT_FONT.toUtf8()}; - int m_font_scale{DEFAULT_FONT_SCALE}; - int m_font_size{DEFAULT_FONT_SIZE}; - std::map m_weights; -}; - -extern FontRegistry g_font_registry; - -struct FontAttrib { - QString m_font; - FontWeight m_weight_type; - double m_point_size{-1}; - bool m_is_italic{false}; - - FontAttrib(QString font, FontWeight weight_type, double point_size = -1, bool is_italic = false); - // cppcheck-suppress noExplicitConstructor - FontAttrib(FontWeight weight_type, double point_size = -1, bool is_italic = false); - ~FontAttrib(); -}; - -/** Convert weight value from args (0-8) to QFont::Weight */ -bool weightFromArg(int nArg, QFont::Weight& weight); - -/** Convert QFont::Weight to an arg value (0-8) */ -int weightToArg(const QFont::Weight weight); - -/** Load dash specific application fonts */ -bool loadFonts(); - -/** Check if the fonts have been loaded successfully */ -bool fontsLoaded(); - -/** Register a QTextEdit for font styling. Applies immediately and updates when fonts change. */ -void registerWidget(QTextEdit* widget, const QString& html); - -/** Set an application wide default font, depends on the selected theme */ -void setApplicationFont(); - -/** Workaround to set correct font styles in all themes since there is a bug in macOS which leads to - issues loading variations of montserrat in css it also keeps track of the set fonts to update on - theme changes. */ -void setFont(const std::vector& vecWidgets, const FontAttrib& font_attrib); - -/** Update the font of all widgets where a custom font has been set with - GUIUtil::setFont */ -void updateFonts(); - -/** Get list of all selectable fonts */ -std::vector getFonts(bool selectable_only); - -/** Get the default bold QFont */ -QFont getFontBold(); - -/** Get the default normal QFont */ -QFont getFontNormal(); - -/** Get a scaled font with the specified base size, weight, and optional multiplier. */ -QFont getScaledFont(double baseSize, bool bold, double multiplier = 1); - -/** (Bitcoin) Return a monospace font */ -QFont fixedPitchFont(bool use_embedded_font = false); -} // namespace GUIUtil - -#endif // BITCOIN_QT_GUIUTIL_FONT_H diff --git a/src/qt/informationwidget.cpp b/src/qt/informationwidget.cpp index d0c9e9bc9ece..1d26c30922a5 100644 --- a/src/qt/informationwidget.cpp +++ b/src/qt/informationwidget.cpp @@ -11,7 +11,6 @@ #include #include -#include #include @@ -28,7 +27,7 @@ InformationWidget::InformationWidget(QWidget* parent) : ui->label_10, ui->labelMempoolTitle, ui->labelNetwork}, - {GUIUtil::FontWeight::Bold, 16}); + GUIUtil::FontWeight::Bold, 16); for (auto* element : {ui->label_10, ui->labelNetwork, ui->labelMempoolTitle}) { element->setContentsMargins(0, 10, 0, 0); diff --git a/src/qt/masternodelist.cpp b/src/qt/masternodelist.cpp index 4305752f8bba..2ba9e46a78dc 100644 --- a/src/qt/masternodelist.cpp +++ b/src/qt/masternodelist.cpp @@ -11,7 +11,6 @@ #include #include #include -#include #include #include @@ -88,7 +87,7 @@ MasternodeList::MasternodeList(QWidget* parent) : { ui->setupUi(this); - GUIUtil::setFont({ui->label_count, ui->countLabel}, {GUIUtil::FontWeight::Bold, 14}); + GUIUtil::setFont({ui->label_count, ui->countLabel}, GUIUtil::FontWeight::Bold, 14); // Set up proxy model m_proxy_model->setSourceModel(m_model); diff --git a/src/qt/modaloverlay.cpp b/src/qt/modaloverlay.cpp index 154cb60f4cee..dc4c6a1a0bcb 100644 --- a/src/qt/modaloverlay.cpp +++ b/src/qt/modaloverlay.cpp @@ -7,7 +7,6 @@ #include #include -#include #include #include @@ -25,7 +24,7 @@ ModalOverlay::ModalOverlay(bool enable_wallet, QWidget* parent) ui->labelSyncDone, ui->labelProgressIncrease, ui->labelEstimatedTimeLeft, - }, {GUIUtil::FontWeight::Bold}); + }, GUIUtil::FontWeight::Bold); ui->warningIcon->setPixmap(GUIUtil::getIcon("warning", GUIUtil::ThemedColor::ORANGE).pixmap(48, 48)); diff --git a/src/qt/networkwidget.cpp b/src/qt/networkwidget.cpp index 790057764d51..58912161610b 100644 --- a/src/qt/networkwidget.cpp +++ b/src/qt/networkwidget.cpp @@ -10,7 +10,6 @@ #include #include -#include #include #include @@ -43,7 +42,7 @@ NetworkWidget::NetworkWidget(QWidget* parent) : ui->labelInstantSend, ui->labelMasternodes, ui->labelQuorums}, - {GUIUtil::FontWeight::Bold, 16}); + GUIUtil::FontWeight::Bold, 16); for (auto* element : {ui->labelInstantSend, ui->labelMasternodes, ui->labelChainLocks}) { element->setContentsMargins(0, 10, 0, 0); diff --git a/src/qt/openuridialog.cpp b/src/qt/openuridialog.cpp index afd2e6e0807c..324241ce86ae 100644 --- a/src/qt/openuridialog.cpp +++ b/src/qt/openuridialog.cpp @@ -7,7 +7,6 @@ #include #include -#include #include #include diff --git a/src/qt/optionsdialog.cpp b/src/qt/optionsdialog.cpp index 39c71a1649ac..76d0e5934bae 100644 --- a/src/qt/optionsdialog.cpp +++ b/src/qt/optionsdialog.cpp @@ -14,7 +14,6 @@ #include #include #include -#include #include #include @@ -46,7 +45,7 @@ OptionsDialog::OptionsDialog(QWidget* parent, bool enableWallet) { ui->setupUi(this); - GUIUtil::setFont({ui->statusLabel}, {GUIUtil::FontWeight::Bold, 16}); + GUIUtil::setFont({ui->statusLabel}, GUIUtil::FontWeight::Bold, 16); GUIUtil::updateFonts(); @@ -417,8 +416,8 @@ void OptionsDialog::showPage(int index) } } - GUIUtil::setFont({btnActive}, {GUIUtil::FontWeight::Bold, 16}); - GUIUtil::setFont(vecNormal, {GUIUtil::FontWeight::Normal, 16}); + GUIUtil::setFont({btnActive}, GUIUtil::FontWeight::Bold, 16); + GUIUtil::setFont(vecNormal, GUIUtil::FontWeight::Normal, 16); GUIUtil::updateFonts(); ui->stackedWidgetOptions->setCurrentIndex(index); diff --git a/src/qt/optionsmodel.cpp b/src/qt/optionsmodel.cpp index 057751997f17..3ab17fc63eb8 100644 --- a/src/qt/optionsmodel.cpp +++ b/src/qt/optionsmodel.cpp @@ -12,7 +12,6 @@ #include #include #include -#include #include #include @@ -146,28 +145,6 @@ static int ParsePruneSizeGB(const QVariant& prune_size) return std::max(1, prune_size.toInt()); } -static int GetFallbackWeightIndex(bool is_bold) -{ - if (is_bold) { - // If the currently selected weight is not supported fallback to the second lightest weight for bold font - // or the lightest if there is only one. - return GUIUtil::g_font_registry.GetSupportedWeights().size() > 1 ? 1 : 0; - } else { - // If the currently selected weight is not supported fallback to the lightest weight for normal font. - return 0; - } -} - -static int WeightArgToIdx(bool is_bold, int weight_arg) -{ - if (QFont::Weight weight; GUIUtil::weightFromArg(weight_arg, weight)) { - if (int index = GUIUtil::g_font_registry.WeightToIdx(weight); index != -1) { - return index; - } - } - return GetFallbackWeightIndex(is_bold); -} - struct ProxySetting { bool is_set; QString ip; @@ -279,10 +256,9 @@ bool OptionsModel::Init(bilingual_str& error) addOverriddenOption("-font-family"); } if (GUIUtil::fontsLoaded()) { - if (auto font_name = QString::fromStdString(SettingToString(node().getPersistentSetting("font-family"), GUIUtil::FontRegistry::DEFAULT_FONT.toUtf8().toStdString())); - GUIUtil::g_font_registry.RegisterFont(font_name, /*selectable=*/true) && GUIUtil::g_font_registry.SetFont(font_name)) { - GUIUtil::setApplicationFont(); - } + const QString font_name = QString::fromStdString( + SettingToString(node().getPersistentSetting("font-family"), "")); + GUIUtil::setActiveFont(font_name); } // Font Scale @@ -290,7 +266,7 @@ bool OptionsModel::Init(bilingual_str& error) addOverriddenOption("-font-scale"); } if (GUIUtil::fontsLoaded()) { - GUIUtil::g_font_registry.SetFontScale(SettingToInt(node().getPersistentSetting("font-scale"), GUIUtil::FontRegistry::DEFAULT_FONT_SCALE)); + GUIUtil::setFontScale(SettingToInt(node().getPersistentSetting("font-scale"), GUIUtil::defaultFontScale())); } // Font Weight (Normal) @@ -301,15 +277,14 @@ bool OptionsModel::Init(bilingual_str& error) const bool override_family{isOptionOverridden("-font-family")}; if (GUIUtil::fontsLoaded()) { // If font was overridden by CLI but weight wasn't, use the font's default weight - QFont::Weight weight{GUIUtil::g_font_registry.GetWeightNormalDefault()}; - if (!override_family || isOptionOverridden("-font-weight-normal")) { - const auto raw_weight{SettingToInt(node().getPersistentSetting("font-weight-normal"), GUIUtil::weightToArg(GUIUtil::FontRegistry::TARGET_WEIGHT_NORMAL))}; - if (!GUIUtil::weightFromArg(raw_weight, weight) || !GUIUtil::g_font_registry.IsValidWeight(weight)) { - weight = GUIUtil::g_font_registry.IdxToWeight(GetFallbackWeightIndex(/*is_bold=*/false)); - node().forceSetting("font-weight-normal", GUIUtil::weightToArg(weight)); - } + const int default_arg = GUIUtil::defaultWeightArg(GUIUtil::FontWeight::Normal); + const int arg = (!override_family || isOptionOverridden("-font-weight-normal")) + ? SettingToInt(node().getPersistentSetting("font-weight-normal"), default_arg) + : default_arg; + if (!GUIUtil::setWeightFromArg(GUIUtil::FontWeight::Normal, arg)) { + node().forceSetting("font-weight-normal", default_arg); + GUIUtil::setWeightFromArg(GUIUtil::FontWeight::Normal, default_arg); } - GUIUtil::g_font_registry.SetWeightNormal(weight); } // Font Weight (Bold) @@ -318,15 +293,14 @@ bool OptionsModel::Init(bilingual_str& error) } if (GUIUtil::fontsLoaded()) { // If font was overridden by CLI but weight wasn't, use the font's default weight - QFont::Weight weight{GUIUtil::g_font_registry.GetWeightBoldDefault()}; - if (!override_family || isOptionOverridden("-font-weight-bold")) { - const auto raw_weight{SettingToInt(node().getPersistentSetting("font-weight-bold"), GUIUtil::weightToArg(GUIUtil::FontRegistry::TARGET_WEIGHT_BOLD))}; - if (!GUIUtil::weightFromArg(raw_weight, weight) || !GUIUtil::g_font_registry.IsValidWeight(weight)) { - weight = GUIUtil::g_font_registry.IdxToWeight(GetFallbackWeightIndex(/*is_bold=*/true)); - node().forceSetting("font-weight-bold", GUIUtil::weightToArg(weight)); - } + const int default_arg = GUIUtil::defaultWeightArg(GUIUtil::FontWeight::Bold); + const int arg = (!override_family || isOptionOverridden("-font-weight-bold")) + ? SettingToInt(node().getPersistentSetting("font-weight-bold"), default_arg) + : default_arg; + if (!GUIUtil::setWeightFromArg(GUIUtil::FontWeight::Bold, arg)) { + node().forceSetting("font-weight-bold", default_arg); + GUIUtil::setWeightFromArg(GUIUtil::FontWeight::Bold, default_arg); } - GUIUtil::g_font_registry.SetWeightBold(weight); } // Apply font changes @@ -561,7 +535,7 @@ QFont OptionsModel::getFontForChoice(const FontChoice& fc) if (std::holds_alternative(fc)) { switch (std::get(fc)) { case FontChoiceAbstract::ApplicationFont: - f.setFamily(GUIUtil::g_font_registry.GetFont()); + f.setFamily(GUIUtil::activeFont()); break; case FontChoiceAbstract::EmbeddedFont: f = GUIUtil::fixedPitchFont(true); @@ -722,13 +696,13 @@ QVariant OptionsModel::getOption(OptionID option, const std::string& suffix) con case Theme: return settings.value("theme"); case FontFamily: - return QString::fromStdString(SettingToString(setting(), GUIUtil::FontRegistry::DEFAULT_FONT.toUtf8().toStdString())); + return QString::fromStdString(SettingToString(setting(), GUIUtil::defaultFontFamily().toStdString())); case FontScale: - return qlonglong(SettingToInt(setting(), GUIUtil::FontRegistry::DEFAULT_FONT_SCALE)); + return qlonglong(SettingToInt(setting(), GUIUtil::defaultFontScale())); case FontWeightNormal: - return WeightArgToIdx(/*is_bold=*/false, SettingToInt(setting(), GUIUtil::g_font_registry.GetWeightNormalDefault())); + return qlonglong(SettingToInt(setting(), GUIUtil::defaultWeightArg(GUIUtil::FontWeight::Normal))); case FontWeightBold: - return WeightArgToIdx(/*is_bold=*/true, SettingToInt(setting(), GUIUtil::g_font_registry.GetWeightBoldDefault())); + return qlonglong(SettingToInt(setting(), GUIUtil::defaultWeightArg(GUIUtil::FontWeight::Bold))); case Language: return QString::fromStdString(SettingToString(setting(), "")); case FontForMoney: @@ -997,18 +971,12 @@ bool OptionsModel::setOption(OptionID option, const QVariant& value, const std:: update(value.toInt()); } break; - case FontWeightNormal: { - if (changed()) { - update(GUIUtil::weightToArg(GUIUtil::g_font_registry.IdxToWeight(value.toInt()))); - } - break; - } - case FontWeightBold: { + case FontWeightNormal: + case FontWeightBold: if (changed()) { - update(GUIUtil::weightToArg(GUIUtil::g_font_registry.IdxToWeight(value.toInt()))); + update(value.toInt()); } break; - } case Language: if (changed()) { update(value.toString().toStdString()); @@ -1200,8 +1168,6 @@ void OptionsModel::checkAndMigrate() ProxySetting parsed = ParseProxyString(value.toString()); setOption(ProxyIPTor, parsed.ip); setOption(ProxyPortTor, parsed.port); - } else if (option == FontWeightNormal || option == FontWeightBold) { - setOption(option, WeightArgToIdx(/*is_bold=*/option == FontWeightBold, value.toInt())); } else { setOption(option, value); } diff --git a/src/qt/overviewpage.cpp b/src/qt/overviewpage.cpp index 7f11fde0f9a8..bc3846dd25b7 100644 --- a/src/qt/overviewpage.cpp +++ b/src/qt/overviewpage.cpp @@ -9,7 +9,6 @@ #include #include #include -#include #include #include #include @@ -63,7 +62,7 @@ class TxViewDelegate : public QAbstractItemDelegate QRect rectBottomHalf(mainRect.left() + xspace, mainRect.top() + ypad + halfheight + 5, mainRect.width() - xspace, halfheight); QRect rectBounding; QColor colorForeground; - constexpr auto initial_size{GUIUtil::FontRegistry::DEFAULT_FONT_SIZE}; + const auto initial_size{GUIUtil::defaultFontSize()}; // Grab model indexes for desired data from TransactionTableModel QModelIndex indexDate = index.sibling(index.row(), TransactionTableModel::Date); @@ -150,16 +149,16 @@ OverviewPage::OverviewPage(QWidget* parent) : GUIUtil::setFont({ui->label_4, ui->label_5, ui->labelCoinJoinHeader - }, {GUIUtil::FontWeight::Bold, 16}); + }, GUIUtil::FontWeight::Bold, 16); - GUIUtil::setFont({ui->labelTotalText}, {GUIUtil::FontWeight::Bold, 14}); + GUIUtil::setFont({ui->labelTotalText}, GUIUtil::FontWeight::Bold, 14); GUIUtil::setFont({ui->labelBalanceText, ui->labelPendingText, ui->labelImmatureText, ui->labelWatchonly, ui->labelSpendable - }, {GUIUtil::FontWeight::Bold}); + }, GUIUtil::FontWeight::Bold); GUIUtil::updateFonts(); @@ -380,7 +379,7 @@ void OverviewPage::setMonospacedFont(const QFont& f) GUIUtil::setFont({ ui->labelTotal, ui->labelWatchTotal, - }, {f.family(), GUIUtil::FontWeight::Bold, 14}); + }, f.family(), GUIUtil::FontWeight::Bold, 14); GUIUtil::setFont({ ui->labelAmountRounds, @@ -392,7 +391,7 @@ void OverviewPage::setMonospacedFont(const QFont& f) ui->labelWatchAvailable, ui->labelWatchPending, ui->labelWatchImmature, - }, {f.family(), GUIUtil::FontWeight::Bold}); + }, f.family(), GUIUtil::FontWeight::Bold); GUIUtil::updateFonts(); } diff --git a/src/qt/proposalcreate.cpp b/src/qt/proposalcreate.cpp index 322e9ef475e0..0d0597bd7b6c 100644 --- a/src/qt/proposalcreate.cpp +++ b/src/qt/proposalcreate.cpp @@ -11,11 +11,9 @@ #include #include -#include -#include - #include #include +#include #include #include #include @@ -39,7 +37,7 @@ ProposalCreate::ProposalCreate(WalletModel* walletModel, QWidget* parent) : m_ui->setupUi(this); m_ui->labelError->setStyleSheet(GUIUtil::getThemedStyleQString(GUIUtil::ThemedStyle::TS_ERROR)); m_ui->labelTotalValue->setFont( - GUIUtil::getScaledFont(GUIUtil::FontRegistry::DEFAULT_FONT_SIZE, /*bold=*/true, /*multiplier=*/1.05)); + GUIUtil::getScaledFont(GUIUtil::defaultFontSize(), /*bold=*/true, /*multiplier=*/1.05)); // Allow payment amount field to stretch horizontally if (auto* lineEdit = m_ui->paymentAmount->findChild()) { diff --git a/src/qt/proposalinfo.cpp b/src/qt/proposalinfo.cpp index daa8e211ba81..510471ed9159 100644 --- a/src/qt/proposalinfo.cpp +++ b/src/qt/proposalinfo.cpp @@ -15,7 +15,6 @@ #include #include #include -#include #include #include @@ -55,7 +54,7 @@ ProposalInfo::ProposalInfo(QWidget* parent) : ui->labelNode, ui->labelParticipation, ui->labelProposals}, - {GUIUtil::FontWeight::Bold, 16}); + GUIUtil::FontWeight::Bold, 16); for (auto* element : {ui->labelNode, ui->labelParticipation, ui->labelProposals}) { element->setContentsMargins(0, 10, 0, 0); diff --git a/src/qt/proposallist.cpp b/src/qt/proposallist.cpp index 27241a021726..03b0f9e618b0 100644 --- a/src/qt/proposallist.cpp +++ b/src/qt/proposallist.cpp @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include @@ -58,7 +57,7 @@ ProposalList::ProposalList(QWidget* parent) : ui->setupUi(this); GUIUtil::setFont({ui->label_count_2, ui->countLabel}, - {GUIUtil::FontWeight::Bold, 14}); + GUIUtil::FontWeight::Bold, 14); ui->govTableView->setContextMenuPolicy(Qt::CustomContextMenu); ui->govTableView->setModel(proposalModelProxy); diff --git a/src/qt/proposalmodel.cpp b/src/qt/proposalmodel.cpp index 8580075cc021..ace256893cd6 100644 --- a/src/qt/proposalmodel.cpp +++ b/src/qt/proposalmodel.cpp @@ -8,14 +8,12 @@ #include #include -#include +#include +#include #include #include -#include -#include - #include #include diff --git a/src/qt/proposalresume.cpp b/src/qt/proposalresume.cpp index 6b1fcd641563..0acb321de757 100644 --- a/src/qt/proposalresume.cpp +++ b/src/qt/proposalresume.cpp @@ -7,7 +7,7 @@ #include -#include +#include #include #include @@ -163,7 +163,7 @@ void ProposalResume::addProposal(const Governance::Object& proposal) entry.description->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); entry.description->setTextInteractionFlags(Qt::NoTextInteraction); entry.description->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum); - GUIUtil::registerWidget(entry.description, formatProposalHtml(proposal, -1)); + GUIUtil::setStyledHtml(entry.description, formatProposalHtml(proposal, -1)); // Create "Broadcast" action entry.broadcast_btn = new QPushButton(tr("Broadcast"), entry.container); @@ -259,7 +259,7 @@ void ProposalResume::refreshConfirmations() const int confs = queryConfirmations(entry.proposal.collateralHash); if (confs != entry.collateral_confs) { entry.collateral_confs = confs; - GUIUtil::registerWidget(entry.description, formatProposalHtml(entry.proposal, confs)); + GUIUtil::setStyledHtml(entry.description, formatProposalHtml(entry.proposal, confs)); entry.broadcast_btn->setEnabled(confs >= m_relay_confs); } if (confs < m_relay_confs) { diff --git a/src/qt/qrdialog.cpp b/src/qt/qrdialog.cpp index 4c94c389fce3..28c2db1f0c9b 100644 --- a/src/qt/qrdialog.cpp +++ b/src/qt/qrdialog.cpp @@ -8,7 +8,6 @@ #include #include #include -#include #include #if defined(HAVE_CONFIG_H) @@ -21,7 +20,7 @@ QRDialog::QRDialog(QWidget *parent) : { ui->setupUi(this); - GUIUtil::setFont({ui->labelQRCodeTitle}, {GUIUtil::FontWeight::Bold, 16}); + GUIUtil::setFont({ui->labelQRCodeTitle}, GUIUtil::FontWeight::Bold, 16); GUIUtil::updateFonts(); diff --git a/src/qt/qrimagewidget.cpp b/src/qt/qrimagewidget.cpp index 3d937bf7f680..cbe15a1c5c16 100644 --- a/src/qt/qrimagewidget.cpp +++ b/src/qt/qrimagewidget.cpp @@ -5,7 +5,6 @@ #include #include -#include #include #include diff --git a/src/qt/receivecoinsdialog.cpp b/src/qt/receivecoinsdialog.cpp index bf4d9d8322c7..0401dca9229c 100644 --- a/src/qt/receivecoinsdialog.cpp +++ b/src/qt/receivecoinsdialog.cpp @@ -7,7 +7,6 @@ #include #include -#include #include #include #include @@ -22,10 +21,10 @@ ReceiveCoinsDialog::ReceiveCoinsDialog(QWidget* parent) : { ui->setupUi(this); - GUIUtil::setFont({ui->label_6}, {GUIUtil::FontWeight::Bold, 16}); + GUIUtil::setFont({ui->label_6}, GUIUtil::FontWeight::Bold, 16); GUIUtil::setFont({ui->label, ui->label_2, - ui->label_3}, {GUIUtil::FontWeight::Normal, 15}); + ui->label_3}, GUIUtil::FontWeight::Normal, 15); GUIUtil::updateFonts(); // context menu diff --git a/src/qt/receiverequestdialog.cpp b/src/qt/receiverequestdialog.cpp index dee027526167..942090e9d383 100644 --- a/src/qt/receiverequestdialog.cpp +++ b/src/qt/receiverequestdialog.cpp @@ -7,7 +7,6 @@ #include #include -#include #include #include #include diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index 1c5596baafb7..395fd669abb1 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -14,7 +14,6 @@ #include #include #include -#include #include #include #include @@ -489,7 +488,7 @@ RPCConsole::RPCConsole(interfaces::Node& node, QWidget* parent, Qt::WindowFlags GUIUtil::setFont({ui->peerHeading, ui->label_repair_header, ui->banHeading - }, {GUIUtil::FontWeight::Bold, 16}); + }, GUIUtil::FontWeight::Bold, 16); GUIUtil::updateFonts(); @@ -1073,8 +1072,8 @@ void RPCConsole::showPage(int index) } } - GUIUtil::setFont({btnActive}, {GUIUtil::FontWeight::Bold, 16}); - GUIUtil::setFont(vecNormal, {GUIUtil::FontWeight::Normal, 16}); + GUIUtil::setFont({btnActive}, GUIUtil::FontWeight::Bold, 16); + GUIUtil::setFont(vecNormal, GUIUtil::FontWeight::Normal, 16); GUIUtil::updateFonts(); ui->stackedWidgetRPC->setCurrentIndex(index); diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp index c09783e2ab08..db2a304b2410 100644 --- a/src/qt/sendcoinsdialog.cpp +++ b/src/qt/sendcoinsdialog.cpp @@ -15,7 +15,6 @@ #include #include #include -#include #include #include @@ -77,14 +76,14 @@ SendCoinsDialog::SendCoinsDialog(bool _fCoinJoin, QWidget* parent) : ui->labelCoinControlChangeText, ui->labelFeeHeadline, ui->fallbackFeeWarningLabel - }, {GUIUtil::FontWeight::Bold}); + }, GUIUtil::FontWeight::Bold); GUIUtil::setFont({ui->labelBalance, ui->labelBalanceName, - }, {GUIUtil::FontWeight::Bold, 14}); + }, GUIUtil::FontWeight::Bold, 14); GUIUtil::setFont({ui->labelCoinControlFeatures - }, {GUIUtil::FontWeight::Bold, 16}); + }, GUIUtil::FontWeight::Bold, 16); ui->checkBoxCoinControlChange->setEnabled(!_fCoinJoin); GUIUtil::setupAddressWidget(ui->lineEditCoinControlChange, this); diff --git a/src/qt/sendcoinsentry.cpp b/src/qt/sendcoinsentry.cpp index b22f950ec090..0b3f1548ccbf 100644 --- a/src/qt/sendcoinsentry.cpp +++ b/src/qt/sendcoinsentry.cpp @@ -13,7 +13,6 @@ #include #include #include -#include #include #include @@ -36,7 +35,7 @@ SendCoinsEntry::SendCoinsEntry(QWidget* parent) : GUIUtil::setFont({ui->payToLabel, ui->labellLabel, ui->amountLabel, - ui->messageLabel}, {GUIUtil::FontWeight::Normal, 15}); + ui->messageLabel}, GUIUtil::FontWeight::Normal, 15); GUIUtil::updateFonts(); diff --git a/src/qt/signverifymessagedialog.cpp b/src/qt/signverifymessagedialog.cpp index 78f9776a0646..e1bdb63275cd 100644 --- a/src/qt/signverifymessagedialog.cpp +++ b/src/qt/signverifymessagedialog.cpp @@ -8,7 +8,6 @@ #include #include -#include #include #include @@ -52,9 +51,9 @@ SignVerifyMessageDialog::SignVerifyMessageDialog(QWidget* parent) : ui->messageIn_VM->installEventFilter(this); ui->signatureIn_VM->installEventFilter(this); - GUIUtil::setFont({ui->signatureOut_SM, ui->signatureIn_VM}, {GUIUtil::FontWeight::Normal, 11, true}); - GUIUtil::setFont({ui->signatureLabel_SM}, {GUIUtil::FontWeight::Bold, 16}); - GUIUtil::setFont({ui->statusLabel_SM, ui->statusLabel_VM}, {GUIUtil::FontWeight::Bold}); + GUIUtil::setFont({ui->signatureOut_SM, ui->signatureIn_VM}, GUIUtil::FontWeight::Normal, 11, true); + GUIUtil::setFont({ui->signatureLabel_SM}, GUIUtil::FontWeight::Bold, 16); + GUIUtil::setFont({ui->statusLabel_SM, ui->statusLabel_VM}, GUIUtil::FontWeight::Bold); GUIUtil::updateFonts(); @@ -110,8 +109,8 @@ void SignVerifyMessageDialog::showPage(int index) } } - GUIUtil::setFont({btnActive}, {GUIUtil::FontWeight::Bold, 16}); - GUIUtil::setFont(vecNormal, {GUIUtil::FontWeight::Normal, 16}); + GUIUtil::setFont({btnActive}, GUIUtil::FontWeight::Bold, 16); + GUIUtil::setFont(vecNormal, GUIUtil::FontWeight::Normal, 16); GUIUtil::updateFonts(); ui->stackedWidgetSig->setCurrentIndex(index); diff --git a/src/qt/splashscreen.cpp b/src/qt/splashscreen.cpp index d7039def9ea8..32a24535553b 100644 --- a/src/qt/splashscreen.cpp +++ b/src/qt/splashscreen.cpp @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include diff --git a/src/qt/test/apptests.cpp b/src/qt/test/apptests.cpp index 9b97b2bad89e..30d6223cb21a 100644 --- a/src/qt/test/apptests.cpp +++ b/src/qt/test/apptests.cpp @@ -8,7 +8,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/qt/trafficgraphwidget.cpp b/src/qt/trafficgraphwidget.cpp index c88bf1c9513b..1c204448d5cd 100644 --- a/src/qt/trafficgraphwidget.cpp +++ b/src/qt/trafficgraphwidget.cpp @@ -6,7 +6,6 @@ #include #include #include -#include #include #include diff --git a/src/qt/utilitydialog.cpp b/src/qt/utilitydialog.cpp index 27eb09a270cf..0b1d55ac9cdf 100644 --- a/src/qt/utilitydialog.cpp +++ b/src/qt/utilitydialog.cpp @@ -12,7 +12,6 @@ #include #include -#include #include #include diff --git a/src/qt/walletview.cpp b/src/qt/walletview.cpp index 11c85d1b615e..face06ba7ade 100644 --- a/src/qt/walletview.cpp +++ b/src/qt/walletview.cpp @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include @@ -69,7 +68,7 @@ WalletView::WalletView(WalletModel* wallet_model, QWidget* parent) GUIUtil::setFont({transactionSumLabel, transactionSum, - }, {GUIUtil::FontWeight::Bold, 14}); + }, GUIUtil::FontWeight::Bold, 14); GUIUtil::updateFonts(); hbox_buttons->addWidget(transactionSum); diff --git a/test/lint/lint-circular-dependencies.py b/test/lint/lint-circular-dependencies.py index cb3f4c80e89a..76367c2ddb07 100755 --- a/test/lint/lint-circular-dependencies.py +++ b/test/lint/lint-circular-dependencies.py @@ -47,9 +47,7 @@ "masternode/payments -> validation -> masternode/payments", "net -> netmessagemaker -> net", "netaddress -> netbase -> netaddress", - "qt/appearancewidget -> qt/guiutil -> qt/appearancewidget", "qt/bitcoinaddressvalidator -> qt/guiutil -> qt/bitcoinaddressvalidator", - "qt/bitcoingui -> qt/guiutil -> qt/bitcoingui", "qt/clientfeeds -> qt/clientmodel -> qt/clientfeeds", "qt/guiutil -> qt/qvalidatedlineedit -> qt/guiutil", "wallet/coinjoin -> wallet/receive -> wallet/coinjoin",