Compare commits

..

9 commits

Author SHA1 Message Date
Lukas Brübach
42895e92a3 [Fonts] Fix font preview leaks and reuse default-font loader 2026-11-02 10:29:11 +01:00
Lukas Brübach
e834339c71 [Fonts] Fix pixel sizes and game overlay fonts from review
- Set the sizes the stylesheets carried with setPixelSize() rather than
  setPointSize(): home buttons (34), banner (24), home group box (20),
  the placeholder labels (14), the analytics drag handle (10), the EDHREC
  navigation buttons (24), the user info popup (11/14/11/10/11) and the
  game overlays (14/16/12). Points at 96 DPI were ~33% larger.
- The drag/total counters and tally columns keep the monospace family the
  stylesheets set, so digit widths stop changing as counts tick and
  white-space: pre stays aligned.
- applyDeckListFont() drops the cached tally rows before re-measuring, so
  previewing a larger DeckList font no longer leaves the tally clipped.
- Tally labels and the constructor/fontsChanged pairs in the shared-deck
  preview, quick setup, analytics panel, home box and public decks build
  their font once in a local lambda instead of twice.
2026-11-02 10:28:01 +01:00
Lukas Brübach
70f0f14665 [Fonts] Drop unused lambda captures in font-refresh handlers 2026-11-02 10:28:01 +01:00
Lukas Brübach
e23efebd71 [Fonts] Migrate DeckList and InterfaceDefault surfaces to theme roles 2026-11-02 10:28:01 +01:00
Lukas Brübach
7b3d43c4ea [Fonts] Keep CardText call sites on the app font and fix px sizes
- CardText's unset fallback is qApp->font() again: only the three counter
  painters (paintNumberEllipse, GeneralCounter, PlayerCounter) were Serif
  before the role existed, and they now ask for it through
  ThemeManager::cardTextFont(). Card names, player names, counters, the
  overlay, the Archidekt and EDHREC labels and the completer delegate keep the
  app font they used before.
- Use setPixelSize for the EDHREC card name (20px) and commander name (28px)
  and details (16px) sizes: the stylesheets said px, and setPointSize made
  them about a third larger.
2026-11-02 10:27:43 +01:00
Lukas Brübach
0ff2c4e246 [Fonts] Migrate CardText surfaces to theme font role 2026-11-02 10:27:15 +01:00
Lukas Brübach
bbf055c483 [Fonts] Keep ChatView on the app font and share the report log font
- ChatLog's unset fallback is qApp->font() again: ChatView never set a font
  before the role existed, so an unset role must not switch chat and the game
  log to monospace at the system GeneralFont size.
- Move the monospace fallback the report dialogs used before into
  report_utils::reportLogFont(), which returns the theme's ChatLog role when it
  is set and the old monospace otherwise. tab_report, dlg_my_reports and
  dlg_report_user now share it, so they cannot drift and they honour a themed
  size instead of overriding it.
2026-11-02 10:26:15 +01:00
Lukas Brübach
eeb5cfc333 [Fonts] Migrate ChatLog surfaces to theme font role 2026-11-02 10:26:15 +01:00
Lukas Brübach
7472f69f01 [Fonts] Make the editor's fallback and Reset preview-independent
- Add ThemeManager::defaultAppFont(), which resolves an unset role against the
  startup font instead of currentFonts, and use it in FontGridWidget::loadFonts
  so the grid never shows the live preview as the theme's default.
- Reload the live theme in PaletteEditorDialog::onReset before re-reading the
  grid, so Reset restores the saved fonts before loadFonts resolves fallbacks.
2026-11-02 10:26:05 +01:00
7 changed files with 14 additions and 30 deletions

View file

@ -117,11 +117,10 @@ GameView::GameView(GameScene *scene, QWidget *parent) : QGraphicsView(scene, par
tallyLayout->setSpacing(2); tallyLayout->setSpacing(2);
tallyContainer->hide(); tallyContainer->hide();
applyDeckListFont(); applyDeckOverlayFonts();
connect(themeManager, &ThemeManager::fontsChanged, this, &GameView::applyDeckListFont);
} }
void GameView::applyDeckListFont() void GameView::applyDeckOverlayFonts()
{ {
dragCountLabel->setFont(deckOverlayFont(14, true)); dragCountLabel->setFont(deckOverlayFont(14, true));
totalCountLabel->setFont(deckOverlayFont(16, true)); totalCountLabel->setFont(deckOverlayFont(16, true));

View file

@ -50,7 +50,7 @@ private slots:
void refreshShortcuts(); void refreshShortcuts();
void updateTotalSelectionCount(const QSize &viewSize = QSize()); void updateTotalSelectionCount(const QSize &viewSize = QSize());
void setFocusDisabled(bool disabled); void setFocusDisabled(bool disabled);
void applyDeckListFont(); void applyDeckOverlayFonts();
public slots: public slots:
void updateSceneRect(const QRectF &rect); void updateSceneRect(const QRectF &rect);

View file

@ -79,11 +79,12 @@ void FontGridWidget::loadFonts(const FontConfig &cfg)
auto role = static_cast<AppFont::Role>(fontEnum.value(i)); auto role = static_cast<AppFont::Role>(fontEnum.value(i));
const FontRow &row = fontRows[role]; const FontRow &row = fontRows[role];
// Roles absent from the file resolve to the startup font, not to the // Roles absent from the file resolve the same way the runtime does: an unset
// live preview: appFont() would return the previewed config, so Reset // role falls back to the config's InterfaceDefault, and only then to the
// and a first load would both show the edited font instead of the // startup font. appFont() would return the live preview instead, so Reset and
// theme's real default. // a first load must not measure against it.
const QFont font = cfg.fonts.value(role, themeManager->defaultAppFont(role)); const QFont fallback = cfg.fonts.value(AppFont::InterfaceDefault, themeManager->defaultAppFont(role));
const QFont font = cfg.fonts.value(role, fallback);
row.familyCombo->setCurrentFont(font); row.familyCombo->setCurrentFont(font);
int size = font.pointSize(); int size = font.pointSize();

View file

@ -285,9 +285,7 @@ void PaletteEditorDialog::loadSchemes()
void PaletteEditorDialog::loadFonts() void PaletteEditorDialog::loadFonts()
{ {
savedFontConfig = ThemeManager::loadDefaultFontConfig(themeDirPath, themeName); savedFontConfig = ThemeManager::loadDefaultFontConfig(themeDirPath, themeName);
fontGrid->blockSignals(true);
fontGrid->loadFonts(savedFontConfig); fontGrid->loadFonts(savedFontConfig);
fontGrid->blockSignals(false);
fontsDirty = false; fontsDirty = false;
} }
@ -394,7 +392,6 @@ void PaletteEditorDialog::onSave()
void PaletteEditorDialog::onReset() void PaletteEditorDialog::onReset()
{ {
const bool hadFontPreview = fontsDirty;
workingConfig[loadedScheme] = savedConfig[loadedScheme]; workingConfig[loadedScheme] = savedConfig[loadedScheme];
paletteGrid->loadPalette(savedConfig[loadedScheme]); paletteGrid->loadPalette(savedConfig[loadedScheme]);
// Restore the live theme before re-reading the grid: loadFonts resolves // Restore the live theme before re-reading the grid: loadFonts resolves
@ -403,9 +400,6 @@ void PaletteEditorDialog::onReset()
themeManager->reloadCurrentTheme(); themeManager->reloadCurrentTheme();
fontGrid->loadFonts(savedFontConfig); fontGrid->loadFonts(savedFontConfig);
fontsDirty = false; fontsDirty = false;
if (hadFontPreview) {
themeManager->previewFonts(savedFontConfig);
}
seedAccentFromScheme(loadedScheme); seedAccentFromScheme(loadedScheme);
} }

View file

@ -19,7 +19,6 @@ class FontGridWidget;
class QuickSetupPanel; class QuickSetupPanel;
class QFrame; class QFrame;
class QWidget; class QWidget;
class QCloseEvent;
class PaletteEditorDialog : public QDialog class PaletteEditorDialog : public QDialog
{ {

View file

@ -657,17 +657,9 @@ QFont ThemeManager::appFont(AppFont::Role role) const
} }
// Role fallbacks preserve the pre-theme defaults when no fonts.toml is // Role fallbacks preserve the pre-theme defaults when no fonts.toml is
// present: chat logs rendered monospace (matching the report dialogs), // present: an unset role resolves to the application font, so the result is
// card text from a serif basis, everything else from the app font. // identical to before. The report dialogs that used to hardcode monospace
if (role == AppFont::ChatLog) { // ask for it explicitly (report_utils::reportLogFont), and the counter
// ChatView never set a font before the theme role existed, so an unset
// ChatLog must keep resolving to the application font. The report
// dialogs that used to hardcode monospace ask for it explicitly
// (report_utils::reportLogFont) instead of through this fallback.
return qApp->font();
}
// No per-role scaling: an unset role resolves to the application font, so
// with no fonts.toml present the result is identical to before. The counter
// painters that used to hardcode Serif ask for it through cardTextFont(). // painters that used to hardcode Serif ask for it through cardTextFont().
return qApp->font(); return qApp->font();
} }

View file

@ -150,9 +150,8 @@ public:
// when present, otherwise a palette-accent-derived fallback. // when present, otherwise a palette-accent-derived fallback.
QColor appColor(AppColor::Role role) const; QColor appColor(AppColor::Role role) const;
/** @brief Resolves an application font role: the theme's stored [Fonts] /** @brief Resolves an application font role: the theme's stored [Fonts]
* value when present, otherwise a per-role fallback (monospace for * value when present, otherwise a per-role fallback (serif basis
* ChatLog, serif basis for CardText, the application font for the * for CardText, the application font for the remaining roles). */
* remaining roles). */
QFont appFont(AppFont::Role role) const; QFont appFont(AppFont::Role role) const;
/** @brief Whether the active theme defines this role in fonts.toml. */ /** @brief Whether the active theme defines this role in fonts.toml. */
bool hasAppFont(AppFont::Role role) const; bool hasAppFont(AppFont::Role role) const;