[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.
This commit is contained in:
Lukas Brübach 2026-11-01 17:03:17 +01:00
parent 70f0f14665
commit e834339c71
15 changed files with 80 additions and 91 deletions

View file

@ -26,6 +26,21 @@
#include <libcockatrice/utility/qt_utils.h>
#include <qnamespace.h>
namespace
{
QFont deckOverlayFont(int pixelSize, bool bold)
{
// The drag/total counters and the tally columns are in-game overlays, not
// deck list text: keep the monospace family the stylesheets used to set so
// digit widths stay stable as counts tick and `white-space: pre` lines up.
QFont font(QStringLiteral("monospace"));
font.setStyleHint(QFont::Monospace);
font.setPixelSize(pixelSize);
font.setBold(bold);
return font;
}
} // namespace
// QRubberBand calls raise() in showEvent() and changeEvent() to stay on top of siblings.
// This subclass disables that behavior so dragCountLabel can appear above it.
class SelectionRubberBand : public QRubberBand
@ -102,40 +117,26 @@ GameView::GameView(GameScene *scene, QWidget *parent) : QGraphicsView(scene, par
tallyLayout->setSpacing(2);
tallyContainer->hide();
applyDeckListFont();
connect(themeManager, &ThemeManager::fontsChanged, this, &GameView::applyDeckListFont);
applyDeckOverlayFonts();
}
void GameView::applyDeckListFont()
void GameView::applyDeckOverlayFonts()
{
// Family comes from the DeckList theme role; the pixel sizes and bold
// weights previously carried by the stylesheets stay caller-side.
QFont dragFont = themeManager->appFont(AppFont::DeckList);
dragFont.setPointSize(14);
dragFont.setWeight(QFont::Bold);
dragCountLabel->setFont(dragFont);
QFont totalFont = themeManager->appFont(AppFont::DeckList);
totalFont.setPointSize(16);
totalFont.setWeight(QFont::Bold);
totalCountLabel->setFont(totalFont);
QFont tallyFont = themeManager->appFont(AppFont::DeckList);
tallyFont.setPointSize(12);
tallyContainer->setFont(tallyFont);
dragCountLabel->setFont(deckOverlayFont(14, true));
totalCountLabel->setFont(deckOverlayFont(16, true));
tallyContainer->setFont(deckOverlayFont(12, false));
for (int i = 0; i < tallyLayout->count(); ++i) {
if (auto *label = qobject_cast<QLabel *>(tallyLayout->itemAt(i)->widget())) {
QFont labelFont = themeManager->appFont(AppFont::DeckList);
// Count column (odd positions) keeps the 14px bold emphasis.
if (i % 2 == 1) {
labelFont.setPointSize(14);
labelFont.setWeight(QFont::Bold);
} else {
labelFont.setPointSize(12);
}
label->setFont(labelFont);
// Count column (odd positions) keeps the bold emphasis.
const bool count = i % 2 == 1;
label->setFont(deckOverlayFont(count ? 14 : 12, count));
}
}
// The container keeps the size computed from the previous fonts, so force
// rebuildTallyLabels() to re-measure it instead of reusing cachedTallyRows.
cachedTallyRows.clear();
updateTotalSelectionCount();
}
void GameView::resizeEvent(QResizeEvent *event)
@ -266,18 +267,13 @@ QSize GameView::rebuildTallyLabels(const QList<TallyRow> &entries)
for (const TallyRow &entry : entries) {
auto *nameLabel = new QLabel(entry.name, tallyContainer);
nameLabel->setStyleSheet(nameStyle);
QFont nameFont = themeManager->appFont(AppFont::DeckList);
nameFont.setPointSize(12);
nameLabel->setFont(nameFont);
nameLabel->setFont(deckOverlayFont(12, false));
nameLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
tallyLayout->addWidget(nameLabel, row, 0);
auto *countLabel = new QLabel(entry.value, tallyContainer);
countLabel->setStyleSheet(countStyle);
QFont countFont = themeManager->appFont(AppFont::DeckList);
countFont.setPointSize(14);
countFont.setWeight(QFont::Bold);
countLabel->setFont(countFont);
countLabel->setFont(deckOverlayFont(14, true));
countLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
tallyLayout->addWidget(countLabel, row, 1);

View file

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

View file

@ -30,16 +30,14 @@ QuickSetupPanel::QuickSetupPanel(QWidget *parent) : QWidget(parent)
labelLow = new QLabel(this);
labelHigh = new QLabel(this);
// Family comes from the InterfaceDefault theme role; the *0.82 size stays caller-side.
QFont small = themeManager->appFont(AppFont::InterfaceDefault);
small.setPointSizeF(small.pointSizeF() * 0.82);
labelLow->setFont(small);
labelHigh->setFont(small);
connect(themeManager, &ThemeManager::fontsChanged, this, [this]() {
QFont refreshedSmall = themeManager->appFont(AppFont::InterfaceDefault);
refreshedSmall.setPointSizeF(refreshedSmall.pointSizeF() * 0.82);
labelLow->setFont(refreshedSmall);
labelHigh->setFont(refreshedSmall);
});
auto applySmallFont = [this]() {
QFont small = themeManager->appFont(AppFont::InterfaceDefault);
small.setPointSizeF(small.pointSizeF() * 0.82);
labelLow->setFont(small);
labelHigh->setFont(small);
};
applySmallFont();
connect(themeManager, &ThemeManager::fontsChanged, this, applySmallFont);
QPalette dimmed = labelLow->palette();
dimmed.setColor(QPalette::WindowText, qApp->palette().color(QPalette::Mid));
labelLow->setPalette(dimmed);

View file

@ -104,14 +104,13 @@ ResizablePanel::ResizablePanel(const QString &_typeId, AbstractAnalyticsPanelWid
"QPushButton:hover { background: %4; }")
.arg(mid.name(), dark.name(), placeholderText.name(), midLight.name()));
// Family comes from the InterfaceDefault theme role; the 10px size stays caller-side.
QFont dragFont = themeManager->appFont(AppFont::InterfaceDefault);
dragFont.setPointSize(10);
dragButton->setFont(dragFont);
connect(themeManager, &ThemeManager::fontsChanged, this, [this]() {
QFont refreshedFont = themeManager->appFont(AppFont::InterfaceDefault);
refreshedFont.setPointSize(10);
dragButton->setFont(refreshedFont);
});
auto applyDragFont = [this]() {
QFont dragFont = themeManager->appFont(AppFont::InterfaceDefault);
dragFont.setPixelSize(10);
dragButton->setFont(dragFont);
};
applyDragFont();
connect(themeManager, &ThemeManager::fontsChanged, this, applyDragFont);
resizeHandle->setStyleSheet(QString("QWidget { background: qlineargradient(x1:0, y1:0, x2:0, y2:1, "
"stop:0 %1, stop:1 %2); }")

View file

@ -36,16 +36,14 @@ DlgSharedDecksPreview::DlgSharedDecksPreview(QWidget *parent,
auto *titleLabel =
new QLabel(tr("Share: %1").arg((shareName.isEmpty() ? tr("Untitled") : shareName).toHtmlEscaped()), this);
// Family comes from the InterfaceDefault theme role; the +2 size and bold stay caller-side.
QFont titleFont = themeManager->appFont(AppFont::InterfaceDefault);
titleFont.setBold(true);
titleFont.setPointSize(titleFont.pointSize() + 2);
titleLabel->setFont(titleFont);
connect(themeManager, &ThemeManager::fontsChanged, this, [titleLabel]() {
QFont refreshedFont = themeManager->appFont(AppFont::InterfaceDefault);
refreshedFont.setBold(true);
refreshedFont.setPointSize(refreshedFont.pointSize() + 2);
titleLabel->setFont(refreshedFont);
});
auto applyTitleFont = [titleLabel]() {
QFont titleFont = themeManager->appFont(AppFont::InterfaceDefault);
titleFont.setBold(true);
titleFont.setPointSize(titleFont.pointSize() + 2);
titleLabel->setFont(titleFont);
};
applyTitleFont();
connect(themeManager, &ThemeManager::fontsChanged, this, applyTitleFont);
mainLayout->addWidget(titleLabel);
if (!serverText.isEmpty()) {

View file

@ -65,7 +65,7 @@ void BannerWidget::applyInterfaceDefaultFont()
// Family comes from the InterfaceDefault theme role; the 24px size and
// bold weight previously carried by the stylesheet stay caller-side.
QFont bannerFont = themeManager->appFont(AppFont::InterfaceDefault);
bannerFont.setPointSize(24);
bannerFont.setPixelSize(24);
bannerFont.setWeight(QFont::Bold);
bannerLabel->setFont(bannerFont);
}

View file

@ -33,7 +33,7 @@ void HomeStyledButton::applyInterfaceDefaultFont()
// Family comes from the InterfaceDefault theme role; the 34px size and
// bold weight previously carried by the stylesheet stay caller-side.
QFont buttonFont = themeManager->appFont(AppFont::InterfaceDefault);
buttonFont.setPointSize(34);
buttonFont.setPixelSize(34);
buttonFont.setWeight(QFont::Bold);
setFont(buttonFont);
}

View file

@ -274,14 +274,13 @@ QGroupBox *HomeWidget::createButtons()
}
)");
// Family comes from the InterfaceDefault theme role; the 20px size stays caller-side.
QFont boxFont = themeManager->appFont(AppFont::InterfaceDefault);
boxFont.setPointSize(20);
box->setFont(boxFont);
connect(themeManager, &ThemeManager::fontsChanged, this, [box]() {
QFont refreshedFont = themeManager->appFont(AppFont::InterfaceDefault);
refreshedFont.setPointSize(20);
box->setFont(refreshedFont);
});
auto applyBoxFont = [box]() {
QFont boxFont = themeManager->appFont(AppFont::InterfaceDefault);
boxFont.setPixelSize(20);
box->setFont(boxFont);
};
applyBoxFont();
connect(themeManager, &ThemeManager::fontsChanged, this, applyBoxFont);
box->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
QVBoxLayout *boxLayout = new QVBoxLayout;
boxLayout->setAlignment(Qt::AlignHCenter);

View file

@ -55,6 +55,6 @@ void PrintingSelectorPlaceholderWidget::applyInterfaceDefaultFont()
{
// Family comes from the InterfaceDefault theme role; the 14px size stays caller-side.
QFont placeholderFont = themeManager->appFont(AppFont::InterfaceDefault);
placeholderFont.setPointSize(14);
placeholderFont.setPixelSize(14);
textLabel->setFont(placeholderFont);
}

View file

@ -482,7 +482,7 @@ void UserInfoPopup::applyTheme()
gamesLabel->setStyleSheet(QStringLiteral("color:%1; background:transparent;").arg(colorStr(theme.subText)));
QFont gamesLabelFont = themeManager->appFont(AppFont::InterfaceDefault);
gamesLabelFont.setPointSize(11);
gamesLabelFont.setPixelSize(11);
gamesLabelFont.setWeight(QFont::Bold);
gamesLabel->setFont(gamesLabelFont);
@ -490,13 +490,13 @@ void UserInfoPopup::applyTheme()
"QPushButton:hover{color:%2;}")
.arg(colorStr(theme.subText), colorStr(theme.text)));
QFont refreshFont = themeManager->appFont(AppFont::InterfaceDefault);
refreshFont.setPointSize(14);
refreshFont.setPixelSize(14);
refreshBtn->setFont(refreshFont);
gamesStatus->setStyleSheet(
QStringLiteral("color:%1; padding:10px; background:transparent;").arg(colorStr(theme.statusText)));
QFont statusFont = themeManager->appFont(AppFont::InterfaceDefault);
statusFont.setPointSize(11);
statusFont.setPixelSize(11);
gamesStatus->setFont(statusFont);
gamesView->setStyleSheet(QStringLiteral("QListView{background:%1;border:none;}"
@ -509,7 +509,7 @@ void UserInfoPopup::applyTheme()
"QPushButton:hover{color:%3;background:%4;}")
.arg(colorStr(theme.closeBg), colorStr(theme.subText), colorStr(theme.text), colorStr(theme.closeHover)));
QFont closeFont = themeManager->appFont(AppFont::InterfaceDefault);
closeFont.setPointSize(10);
closeFont.setPixelSize(10);
closeBtn->setFont(closeFont);
header->update();
@ -534,7 +534,7 @@ static QPushButton *makeBtn(const QString &label, const QString &tip, QWidget *p
colorStr(t.text), colorStr(t.buttonPressed), colorStr(t.buttonDisabled)));
// Family comes from the InterfaceDefault theme role; the 11px size stays caller-side.
QFont btnFont = themeManager->appFont(AppFont::InterfaceDefault);
btnFont.setPointSize(11);
btnFont.setPixelSize(11);
b->setFont(btnFont);
return b;
}

View file

@ -104,7 +104,7 @@ void EdhrecCommanderApiResponseBracketNavigationWidget::updateOptionButtonSelect
const bool selected = (it.key() == selectedKey);
it.value()->setStyleSheet(selected ? QStringLiteral("background-color: lightblue;") : QString());
QFont buttonFont = themeManager->appFont(AppFont::InterfaceDefault);
buttonFont.setPointSize(24);
buttonFont.setPixelSize(24);
buttonFont.setWeight(selected ? QFont::Bold : QFont::Normal);
it.value()->setFont(buttonFont);
}

View file

@ -106,7 +106,7 @@ void EdhrecCommanderApiResponseBudgetNavigationWidget::updateOptionButtonSelecti
const bool selected = (it.key() == selectedKey);
it.value()->setStyleSheet(selected ? QStringLiteral("background-color: lightblue;") : QString());
QFont buttonFont = themeManager->appFont(AppFont::InterfaceDefault);
buttonFont.setPointSize(24);
buttonFont.setPixelSize(24);
buttonFont.setWeight(selected ? QFont::Bold : QFont::Normal);
it.value()->setFont(buttonFont);
}

View file

@ -78,7 +78,7 @@ void EdhrecCommanderApiResponseNavigationWidget::applyInterfaceDefaultFont()
{
// Family comes from the InterfaceDefault theme role; the 24px size stays caller-side.
QFont navFont = themeManager->appFont(AppFont::InterfaceDefault);
navFont.setPointSize(24);
navFont.setPixelSize(24);
comboPushButton->setFont(navFont);
averageDeckPushButton->setFont(navFont);
}

View file

@ -46,14 +46,13 @@ TabPublicDecks::TabPublicDecks(TabSupervisor *_tabSupervisor, AbstractClient *_c
titleLabel = new QLabel(tr("Public decks of %1").arg(userName.toHtmlEscaped()), this);
// Family comes from the InterfaceDefault theme role; bold stays caller-side.
QFont titleFont = themeManager->appFont(AppFont::InterfaceDefault);
titleFont.setBold(true);
titleLabel->setFont(titleFont);
connect(themeManager, &ThemeManager::fontsChanged, this, [this]() {
QFont refreshedFont = themeManager->appFont(AppFont::InterfaceDefault);
refreshedFont.setBold(true);
titleLabel->setFont(refreshedFont);
});
auto applyTitleFont = [this]() {
QFont titleFont = themeManager->appFont(AppFont::InterfaceDefault);
titleFont.setBold(true);
titleLabel->setFont(titleFont);
};
applyTitleFont();
connect(themeManager, &ThemeManager::fontsChanged, this, applyTitleFont);
auto *headerLayout = new QHBoxLayout;
headerLayout->addWidget(titleLabel);

View file

@ -53,6 +53,6 @@ void VisualDeckEditorPlaceholderWidget::applyInterfaceDefaultFont()
{
// Family comes from the InterfaceDefault theme role; the 14px size stays caller-side.
QFont placeholderFont = themeManager->appFont(AppFont::InterfaceDefault);
placeholderFont.setPointSize(14);
placeholderFont.setPixelSize(14);
textLabel->setFont(placeholderFont);
}