Clip shadow path, reuse mana cost parsing logic

Took 14 minutes
This commit is contained in:
Lukas Brübach 2026-08-11 18:34:21 +02:00
parent 62c188dc62
commit 554e5405fb
3 changed files with 40 additions and 27 deletions

View file

@ -17,7 +17,7 @@ class ManaCostWidget : public QWidget
public: public:
explicit ManaCostWidget(QWidget *parent, CardInfoPtr card); explicit ManaCostWidget(QWidget *parent, CardInfoPtr card);
QStringList parseManaCost(const QString &manaString); static QStringList parseManaCost(const QString &manaString);
public slots: public slots:
void resizeEvent(QResizeEvent *event) override; void resizeEvent(QResizeEvent *event) override;

View file

@ -1,9 +1,12 @@
#include "card_completer_delegate.h" #include "card_completer_delegate.h"
#include "../cards/additional_info/mana_cost_widget.h"
#include <QFontMetrics> #include <QFontMetrics>
#include <QLinearGradient> #include <QLinearGradient>
#include <QPainter> #include <QPainter>
#include <QPainterPath> #include <QPainterPath>
#include <QRegularExpression>
#include <QSet> #include <QSet>
#include <QStyleOptionViewItem> #include <QStyleOptionViewItem>
#include <libcockatrice/card/card_info.h> #include <libcockatrice/card/card_info.h>
@ -175,36 +178,31 @@ int CardCompleterDelegate::drawManaCost(QPainter *p, const QRect &row, const QSt
return row.right(); return row.right();
} }
QStringList symbols; const int diam = radius * 2;
if (manaCost.contains('{')) { // Split, adventure, aftermath and prepare cards store both halves of the
for (const QString &tok : manaCost.split('}', Qt::SkipEmptyParts)) { // cost joined by "//" (e.g. "1W // W"); draw each half as its own group.
symbols << tok.mid(tok.indexOf('{') + 1); static const QRegularExpression splitRegex("\\s*//\\s*");
}
} else {
QString cur;
for (const QChar c : manaCost) { QList<QStringList> parts;
if (c.isDigit()) {
cur += c;
} else {
if (!cur.isEmpty()) {
symbols << cur;
cur.clear();
}
symbols << QString(c); for (const QString &part : manaCost.split(splitRegex, Qt::SkipEmptyParts)) {
} const QStringList symbols = ManaCostWidget::parseManaCost(part);
}
if (!cur.isEmpty()) { if (!symbols.isEmpty()) {
symbols << cur; 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; const int rightPad = 14;
@ -212,9 +210,17 @@ int CardCompleterDelegate::drawManaCost(QPainter *p, const QRect &row, const QSt
const int cy = row.center().y(); const int cy = row.center().y();
for (const QString &sym : symbols) { for (int i = 0; i < parts.size(); ++i) {
drawManaSymbol(p, {x, cy}, sym, radius); const QStringList &symbols = parts.at(i);
x += diam + SymbolSpacing;
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; return row.right() - rightPad - totalW - 10;
@ -301,6 +307,9 @@ void CardCompleterDelegate::paint(QPainter *painter, const QStyleOptionViewItem
QPainterPath path; QPainterPath path;
path.addRoundedRect(cardRect, 7, 7); path.addRoundedRect(cardRect, 7, 7);
painter->save();
painter->setClipPath(path);
QLinearGradient bodyGrad(cardRect.topLeft(), cardRect.bottomLeft()); QLinearGradient bodyGrad(cardRect.topLeft(), cardRect.bottomLeft());
bodyGrad.setColorAt(0.0, blend(tinted, Qt::white, 0.10)); 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->fillRect(manaZone, manaGrad);
painter->restore();
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
// Border // Border
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------

View file

@ -43,7 +43,8 @@ private:
// Draw a single mana symbol pip at centre point // Draw a single mana symbol pip at centre point
void drawManaSymbol(QPainter *p, QPoint centre, const QString &symbol, int radius) const; 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; 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 // 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 AccentBarWidth = 5;
static constexpr int SymbolRadius = 9; static constexpr int SymbolRadius = 9;
static constexpr int SymbolSpacing = 2; static constexpr int SymbolSpacing = 2;
static constexpr int PartGap = 14;
}; };
#endif // CARD_COMPLETER_DELEGATE_H #endif // CARD_COMPLETER_DELEGATE_H