mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-11-11 12:33:25 -08:00
Draw the token preview P/T as the hover-panel pill
The preview painted the name and P/T unconditionally: the name duplicated the artwork, and the raw P/T text was drawn even when it matched the printed value, which looked wrong at non-default dialog sizes. - Suppress the card name over a token picture via a small AbstractCardItem hook; cards without art still show it. - Draw only a P/T that differs from the printed getPowTough() as the #7700 hover-panel pill: dark rounded scrim, bold white text, anchored on the printed P/T box and clamped inside the card. - Use designated CardRef initializers in the new code. The face-up draft still previews while face-down creation is selected.
This commit is contained in:
parent
e62c250152
commit
60941f5c70
4 changed files with 99 additions and 13 deletions
|
|
@ -181,6 +181,11 @@ QSizeF AbstractCardItem::getTranslatedSize(QPainter *painter) const
|
||||||
painter->combinedTransform().map(QLineF(0, 0, 0, boundingRect().height())).length());
|
painter->combinedTransform().map(QLineF(0, 0, 0, boundingRect().height())).length());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool AbstractCardItem::shouldPaintNameOverPicture() const
|
||||||
|
{
|
||||||
|
return SettingsCache::instance().cardsDisplay().getDisplayCardNames();
|
||||||
|
}
|
||||||
|
|
||||||
void AbstractCardItem::transformPainter(QPainter *painter, const QSizeF &translatedSize, int angle)
|
void AbstractCardItem::transformPainter(QPainter *painter, const QSizeF &translatedSize, int angle)
|
||||||
{
|
{
|
||||||
const int MAX_FONT_SIZE = SettingsCache::instance().appearance().getMaxFontSize();
|
const int MAX_FONT_SIZE = SettingsCache::instance().appearance().getMaxFontSize();
|
||||||
|
|
@ -233,8 +238,7 @@ void AbstractCardItem::paintPicture(QPainter *painter, const QSizeF &translatedS
|
||||||
painter->drawPath(shape());
|
painter->drawPath(shape());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (translatedPixmap.isNull() || SettingsCache::instance().cardsDisplay().getDisplayCardNames() ||
|
if (translatedPixmap.isNull() || state->getFaceDown() || shouldPaintNameOverPicture()) {
|
||||||
state->getFaceDown()) {
|
|
||||||
painter->save();
|
painter->save();
|
||||||
transformPainter(painter, translatedSize, angle);
|
transformPainter(painter, translatedSize, angle);
|
||||||
painter->setPen(Qt::white);
|
painter->setPen(Qt::white);
|
||||||
|
|
|
||||||
|
|
@ -190,6 +190,13 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void transformPainter(QPainter *painter, const QSizeF &translatedSize, int angle);
|
void transformPainter(QPainter *painter, const QSizeF &translatedSize, int angle);
|
||||||
|
/**
|
||||||
|
* @brief Whether the card name is painted over its artwork.
|
||||||
|
*
|
||||||
|
* Follows the "Display card names on cards having a picture" setting. Views
|
||||||
|
* that already show the name elsewhere, such as the token preview, turn it off.
|
||||||
|
*/
|
||||||
|
[[nodiscard]] virtual bool shouldPaintNameOverPicture() const;
|
||||||
void mousePressEvent(QGraphicsSceneMouseEvent *event) override;
|
void mousePressEvent(QGraphicsSceneMouseEvent *event) override;
|
||||||
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override;
|
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override;
|
||||||
QVariant itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value) override;
|
QVariant itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value) override;
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,7 @@
|
||||||
#include <libcockatrice/settings/cards_display_settings.h>
|
#include <libcockatrice/settings/cards_display_settings.h>
|
||||||
#include <libcockatrice/settings/interface_settings.h>
|
#include <libcockatrice/settings/interface_settings.h>
|
||||||
#include <libcockatrice/settings/layouts_settings.h>
|
#include <libcockatrice/settings/layouts_settings.h>
|
||||||
|
#include <libcockatrice/utility/card_ref.h>
|
||||||
#include <libcockatrice/utility/string_limits.h>
|
#include <libcockatrice/utility/string_limits.h>
|
||||||
#include <qnamespace.h>
|
#include <qnamespace.h>
|
||||||
|
|
||||||
|
|
@ -285,7 +286,8 @@ TokenInfo DlgCreateToken::tokenDraft() const
|
||||||
|
|
||||||
// Match the normalization applied when the player creates the token, so
|
// Match the normalization applied when the player creates the token, so
|
||||||
// manually typed aliases and the default P/T preview the actual result.
|
// manually typed aliases and the default P/T preview the actual result.
|
||||||
const ExactCard correctedCard = CardDatabaseManager::query()->guessCard({token.name, token.providerId});
|
const ExactCard correctedCard =
|
||||||
|
CardDatabaseManager::query()->guessCard(CardRef{.name = token.name, .providerId = token.providerId});
|
||||||
if (correctedCard) {
|
if (correctedCard) {
|
||||||
token.name = correctedCard.getName();
|
token.name = correctedCard.getName();
|
||||||
if (token.pt.isEmpty()) {
|
if (token.pt.isEmpty()) {
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,34 @@
|
||||||
#include "token_preview_widget.h"
|
#include "token_preview_widget.h"
|
||||||
|
|
||||||
|
#include "../../interface/theme_manager.h"
|
||||||
#include "../board/abstract_card_item.h"
|
#include "../board/abstract_card_item.h"
|
||||||
|
|
||||||
|
#include <QColor>
|
||||||
|
#include <QFont>
|
||||||
|
#include <QFontMetricsF>
|
||||||
#include <QGraphicsScene>
|
#include <QGraphicsScene>
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
|
#include <QPointF>
|
||||||
#include <QResizeEvent>
|
#include <QResizeEvent>
|
||||||
|
#include <QString>
|
||||||
|
#include <algorithm>
|
||||||
#include <libcockatrice/card/card_info.h>
|
#include <libcockatrice/card/card_info.h>
|
||||||
|
#include <libcockatrice/utility/card_ref.h>
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
// P/T pill, matching the #7700 hover panel. Its sizes are given for a 270 px picture
|
||||||
|
// (CardHoverWidget::CARD_IMAGE_WIDTH) and scale with the preview.
|
||||||
|
constexpr qreal PILL_REFERENCE_WIDTH = 270.0;
|
||||||
|
constexpr qreal PILL_MIN_WIDTH = 48.0;
|
||||||
|
constexpr qreal PILL_MIN_HEIGHT = 22.0;
|
||||||
|
constexpr qreal PILL_TEXT_PADDING = 4.0;
|
||||||
|
constexpr qreal PILL_CORNER_RADIUS = 4.0;
|
||||||
|
constexpr qreal PILL_FONT_PIXELS = 12.0;
|
||||||
|
constexpr qreal PILL_ANCHOR_X = 0.92;
|
||||||
|
constexpr qreal PILL_ANCHOR_Y = 0.94;
|
||||||
|
constexpr int PILL_SCRIM_ALPHA = 180;
|
||||||
|
} // namespace
|
||||||
|
|
||||||
class TokenPreviewCardItem : public AbstractCardItem
|
class TokenPreviewCardItem : public AbstractCardItem
|
||||||
{
|
{
|
||||||
|
|
@ -26,19 +49,69 @@ public:
|
||||||
AbstractCardItem::paint(painter, option, widget);
|
AbstractCardItem::paint(painter, option, widget);
|
||||||
|
|
||||||
const QSizeF translatedSize = getTranslatedSize(painter);
|
const QSizeF translatedSize = getTranslatedSize(painter);
|
||||||
|
if (translatedSize.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const qreal scale = translatedSize.width() / boundingRect().width();
|
const qreal scale = translatedSize.width() / boundingRect().width();
|
||||||
|
|
||||||
painter->save();
|
painter->save();
|
||||||
transformPainter(painter, translatedSize, 0);
|
transformPainter(painter, translatedSize, 0);
|
||||||
painter->setPen(Qt::white);
|
|
||||||
painter->setBackground(Qt::black);
|
if (!state->getAnnotation().isEmpty()) {
|
||||||
painter->setBackgroundMode(Qt::OpaqueMode);
|
painter->setPen(Qt::white);
|
||||||
const QRectF textRect(4 * scale, 4 * scale, translatedSize.width() - 8 * scale,
|
painter->setBackground(Qt::black);
|
||||||
translatedSize.height() - 8 * scale);
|
painter->setBackgroundMode(Qt::OpaqueMode);
|
||||||
painter->drawText(textRect, Qt::AlignCenter | Qt::TextWrapAnywhere, state->getAnnotation());
|
const QRectF textRect(4 * scale, 4 * scale, translatedSize.width() - 8 * scale,
|
||||||
if (state->getPT() != getCardInfo().getPowTough()) {
|
translatedSize.height() - 8 * scale);
|
||||||
painter->setPen(QColor(255, 150, 0));
|
painter->drawText(textRect, Qt::AlignCenter | Qt::TextWrapAnywhere, state->getAnnotation());
|
||||||
}
|
}
|
||||||
painter->drawText(textRect, Qt::AlignRight | Qt::AlignBottom, state->getPT());
|
|
||||||
|
// The card picture already shows the printed P/T, so only a different value
|
||||||
|
// needs the pill. A custom token with no picture also has no printed value.
|
||||||
|
const QString pt = state->getPT();
|
||||||
|
if (!pt.isEmpty() && pt != getCardInfo().getPowTough()) {
|
||||||
|
paintPtPill(painter, translatedSize, pt);
|
||||||
|
}
|
||||||
|
|
||||||
|
painter->restore();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// The artwork carries the name; the dialog's own fields already show it.
|
||||||
|
[[nodiscard]] bool shouldPaintNameOverPicture() const override
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void paintPtPill(QPainter *painter, const QSizeF &translatedSize, const QString &pt) const
|
||||||
|
{
|
||||||
|
const qreal ratio = translatedSize.width() / PILL_REFERENCE_WIDTH;
|
||||||
|
|
||||||
|
QFont font = themeManager->appFont(AppFont::CardText);
|
||||||
|
font.setBold(true);
|
||||||
|
font.setPixelSize(std::max(1, qRound(PILL_FONT_PIXELS * ratio)));
|
||||||
|
|
||||||
|
const QFontMetricsF metrics(font);
|
||||||
|
const QSizeF pillSize(
|
||||||
|
qMax(PILL_MIN_WIDTH * ratio, metrics.horizontalAdvance(pt) + 2 * PILL_TEXT_PADDING * ratio),
|
||||||
|
qMax(PILL_MIN_HEIGHT * ratio, metrics.height()));
|
||||||
|
const QPointF anchor(translatedSize.width() * PILL_ANCHOR_X, translatedSize.height() * PILL_ANCHOR_Y);
|
||||||
|
// Centred on the card's printed P/T box, then kept inside the card.
|
||||||
|
const QRectF pill(qBound(0.0, anchor.x() - pillSize.width() / 2, translatedSize.width() - pillSize.width()),
|
||||||
|
qBound(0.0, anchor.y() - pillSize.height() / 2, translatedSize.height() - pillSize.height()),
|
||||||
|
pillSize.width(), pillSize.height());
|
||||||
|
|
||||||
|
painter->save();
|
||||||
|
painter->setRenderHint(QPainter::Antialiasing, true);
|
||||||
|
painter->setBackgroundMode(Qt::TransparentMode);
|
||||||
|
painter->setPen(Qt::NoPen);
|
||||||
|
painter->setBrush(QColor(0, 0, 0, PILL_SCRIM_ALPHA));
|
||||||
|
const qreal radius = PILL_CORNER_RADIUS * ratio;
|
||||||
|
painter->drawRoundedRect(pill, radius, radius);
|
||||||
|
painter->setFont(font);
|
||||||
|
painter->setPen(Qt::white);
|
||||||
|
painter->drawText(pill, Qt::AlignCenter, pt);
|
||||||
painter->restore();
|
painter->restore();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -61,7 +134,7 @@ TokenPreviewWidget::TokenPreviewWidget(QWidget *parent) : QGraphicsView(parent),
|
||||||
|
|
||||||
void TokenPreviewWidget::setToken(const TokenInfo &token)
|
void TokenPreviewWidget::setToken(const TokenInfo &token)
|
||||||
{
|
{
|
||||||
card->setCardRef({token.name, token.providerId});
|
card->setCardRef(CardRef{.name = token.name, .providerId = token.providerId});
|
||||||
card->setColor(token.color);
|
card->setColor(token.color);
|
||||||
card->setFaceDown(false);
|
card->setFaceDown(false);
|
||||||
card->getState()->setPT(token.pt);
|
card->getState()->setPT(token.pt);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue