From 554e5405fbddb3225ccaba6b33f428e05dc32c1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20Br=C3=BCbach?= Date: Tue, 11 Aug 2026 18:34:21 +0200 Subject: [PATCH] Clip shadow path, reuse mana cost parsing logic Took 14 minutes --- .../cards/additional_info/mana_cost_widget.h | 2 +- .../utility/card_completer_delegate.cpp | 61 +++++++++++-------- .../widgets/utility/card_completer_delegate.h | 4 +- 3 files changed, 40 insertions(+), 27 deletions(-) diff --git a/cockatrice/src/interface/widgets/cards/additional_info/mana_cost_widget.h b/cockatrice/src/interface/widgets/cards/additional_info/mana_cost_widget.h index b2f6b62c0..8bd2e9bc0 100644 --- a/cockatrice/src/interface/widgets/cards/additional_info/mana_cost_widget.h +++ b/cockatrice/src/interface/widgets/cards/additional_info/mana_cost_widget.h @@ -17,7 +17,7 @@ class ManaCostWidget : public QWidget public: explicit ManaCostWidget(QWidget *parent, CardInfoPtr card); - QStringList parseManaCost(const QString &manaString); + static QStringList parseManaCost(const QString &manaString); public slots: void resizeEvent(QResizeEvent *event) override; diff --git a/cockatrice/src/interface/widgets/utility/card_completer_delegate.cpp b/cockatrice/src/interface/widgets/utility/card_completer_delegate.cpp index 6b1d2c255..ef0881a50 100644 --- a/cockatrice/src/interface/widgets/utility/card_completer_delegate.cpp +++ b/cockatrice/src/interface/widgets/utility/card_completer_delegate.cpp @@ -1,9 +1,12 @@ #include "card_completer_delegate.h" +#include "../cards/additional_info/mana_cost_widget.h" + #include #include #include #include +#include #include #include #include @@ -175,36 +178,31 @@ int CardCompleterDelegate::drawManaCost(QPainter *p, const QRect &row, const QSt return row.right(); } - QStringList symbols; + const int diam = radius * 2; - if (manaCost.contains('{')) { - for (const QString &tok : manaCost.split('}', Qt::SkipEmptyParts)) { - symbols << tok.mid(tok.indexOf('{') + 1); - } - } else { - QString cur; + // Split, adventure, aftermath and prepare cards store both halves of the + // cost joined by "//" (e.g. "1W // W"); draw each half as its own group. + static const QRegularExpression splitRegex("\\s*//\\s*"); - for (const QChar c : manaCost) { - if (c.isDigit()) { - cur += c; - } else { - if (!cur.isEmpty()) { - symbols << cur; - cur.clear(); - } + QList parts; - symbols << QString(c); - } - } + for (const QString &part : manaCost.split(splitRegex, Qt::SkipEmptyParts)) { + const QStringList symbols = ManaCostWidget::parseManaCost(part); - if (!cur.isEmpty()) { - symbols << cur; + if (!symbols.isEmpty()) { + parts.append(symbols); } } - const int diam = radius * 2; + int totalW = 0; - const int totalW = symbols.size() * diam + (symbols.size() - 1) * SymbolSpacing; + for (int i = 0; i < parts.size(); ++i) { + if (i > 0) { + totalW += PartGap; + } + + totalW += parts.at(i).size() * diam + qMax(0, parts.at(i).size() - 1) * SymbolSpacing; + } const int rightPad = 14; @@ -212,9 +210,17 @@ int CardCompleterDelegate::drawManaCost(QPainter *p, const QRect &row, const QSt const int cy = row.center().y(); - for (const QString &sym : symbols) { - drawManaSymbol(p, {x, cy}, sym, radius); - x += diam + SymbolSpacing; + for (int i = 0; i < parts.size(); ++i) { + const QStringList &symbols = parts.at(i); + + for (const QString &sym : symbols) { + drawManaSymbol(p, {x, cy}, sym, radius); + x += diam + SymbolSpacing; + } + + if (i < parts.size() - 1) { + x += PartGap - SymbolSpacing; + } } return row.right() - rightPad - totalW - 10; @@ -301,6 +307,9 @@ void CardCompleterDelegate::paint(QPainter *painter, const QStyleOptionViewItem QPainterPath path; path.addRoundedRect(cardRect, 7, 7); + painter->save(); + painter->setClipPath(path); + QLinearGradient bodyGrad(cardRect.topLeft(), cardRect.bottomLeft()); bodyGrad.setColorAt(0.0, blend(tinted, Qt::white, 0.10)); @@ -334,6 +343,8 @@ void CardCompleterDelegate::paint(QPainter *painter, const QStyleOptionViewItem painter->fillRect(manaZone, manaGrad); + painter->restore(); + // ----------------------------------------------------------------------- // Border // ----------------------------------------------------------------------- diff --git a/cockatrice/src/interface/widgets/utility/card_completer_delegate.h b/cockatrice/src/interface/widgets/utility/card_completer_delegate.h index 70b551b4b..18661a21b 100644 --- a/cockatrice/src/interface/widgets/utility/card_completer_delegate.h +++ b/cockatrice/src/interface/widgets/utility/card_completer_delegate.h @@ -43,7 +43,8 @@ private: // Draw a single mana symbol pip at centre point void drawManaSymbol(QPainter *p, QPoint centre, const QString &symbol, int radius) const; - // Draw all mana pips for a cost string like "2RG" or "{2}{R}{G}"; returns the left-most x used + // Draw all mana pips for a cost string like "2RG" or "{2}{R}{G}"; split and + // adventure costs ("1W // W") are drawn as separate groups. Returns the left-most x used int drawManaCost(QPainter *p, const QRect &row, const QString &manaCost, int radius) const; // Load (or return cached) a mana icon pixmap; falls back to painted circle @@ -56,6 +57,7 @@ private: static constexpr int AccentBarWidth = 5; static constexpr int SymbolRadius = 9; static constexpr int SymbolSpacing = 2; + static constexpr int PartGap = 14; }; #endif // CARD_COMPLETER_DELEGATE_H