Make cards rounded (#4765)
* Make cards rounded Magic cards have rounded corners, and playing cards tend to have rounded corners as well, but Cockatrice currently displays rectangular cards. This can cause visual glitches when using image scans where the border does not extend in the corner, and for this reason Cockatrice always draws a (rectangular) border around the card to try and make it look a bit better. In this patch I take a different approach: rather than try to make rounded pegs, er, cards, go into a square hole, the hole is now rounded. More precisely, the AbstractCardItem now has a rounded rectangular shape (with a corner of 5% of the width of the card, identical to that of modern M:TG physical cards). As a side effect, the card drawing gets a bit simplified by getting rid of transformPainter() when drawing the card outline and using the QPainter::drawPixmap overloads that takes a target QRectF instead. This means we no longer have to bother about card rotation when painting since that's taken care of by the Graphics View framework (which transformPainter() undoes). * format * Also give PileZone rounded corners * Forgot untap status + bits of CardDragItem * fix deckviewcard calculations * Rounded CardInfoPicture
This commit is contained in:
parent
a416ee8f2b
commit
55a2f75d16
10 changed files with 48 additions and 34 deletions
|
@ -45,12 +45,19 @@ AbstractCardDragItem::~AbstractCardDragItem()
|
||||||
delete childDrags[i];
|
delete childDrags[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QPainterPath AbstractCardDragItem::shape() const
|
||||||
|
{
|
||||||
|
QPainterPath shape;
|
||||||
|
shape.addRoundedRect(boundingRect(), 0.05 * CARD_WIDTH, 0.05 * CARD_WIDTH);
|
||||||
|
return shape;
|
||||||
|
}
|
||||||
|
|
||||||
void AbstractCardDragItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
|
void AbstractCardDragItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
|
||||||
{
|
{
|
||||||
item->paint(painter, option, widget);
|
item->paint(painter, option, widget);
|
||||||
|
|
||||||
// adds a mask to the card so it looks like the card hasnt been placed yet
|
// adds a mask to the card so it looks like the card hasnt been placed yet
|
||||||
painter->fillRect(boundingRect(), GHOST_MASK);
|
painter->fillPath(shape(), GHOST_MASK);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AbstractCardDragItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
void AbstractCardDragItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
||||||
|
|
|
@ -31,6 +31,7 @@ public:
|
||||||
{
|
{
|
||||||
return QRectF(0, 0, CARD_WIDTH, CARD_HEIGHT);
|
return QRectF(0, 0, CARD_WIDTH, CARD_HEIGHT);
|
||||||
}
|
}
|
||||||
|
QPainterPath shape() const override;
|
||||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
|
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
|
||||||
AbstractCardItem *getItem() const
|
AbstractCardItem *getItem() const
|
||||||
{
|
{
|
||||||
|
|
|
@ -34,6 +34,13 @@ QRectF AbstractCardItem::boundingRect() const
|
||||||
return QRectF(0, 0, CARD_WIDTH, CARD_HEIGHT);
|
return QRectF(0, 0, CARD_WIDTH, CARD_HEIGHT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QPainterPath AbstractCardItem::shape() const
|
||||||
|
{
|
||||||
|
QPainterPath shape;
|
||||||
|
shape.addRoundedRect(boundingRect(), 0.05 * CARD_WIDTH, 0.05 * CARD_WIDTH);
|
||||||
|
return shape;
|
||||||
|
}
|
||||||
|
|
||||||
void AbstractCardItem::pixmapUpdated()
|
void AbstractCardItem::pixmapUpdated()
|
||||||
{
|
{
|
||||||
update();
|
update();
|
||||||
|
@ -113,24 +120,14 @@ void AbstractCardItem::paintPicture(QPainter *painter, const QSizeF &translatedS
|
||||||
|
|
||||||
if (paintImage) {
|
if (paintImage) {
|
||||||
painter->save();
|
painter->save();
|
||||||
transformPainter(painter, translatedSize, angle);
|
painter->setClipPath(shape());
|
||||||
painter->drawPixmap(QPointF(1, 1), translatedPixmap);
|
painter->drawPixmap(boundingRect(), translatedPixmap, QRectF({0, 0}, translatedPixmap.size()));
|
||||||
painter->restore();
|
painter->restore();
|
||||||
} else {
|
} else {
|
||||||
painter->setBrush(bgColor);
|
painter->setBrush(bgColor);
|
||||||
|
painter->drawPath(shape());
|
||||||
}
|
}
|
||||||
|
|
||||||
QPen pen(Qt::black);
|
|
||||||
pen.setJoinStyle(Qt::MiterJoin);
|
|
||||||
const int penWidth = 2;
|
|
||||||
pen.setWidth(penWidth);
|
|
||||||
painter->setPen(pen);
|
|
||||||
|
|
||||||
if (!angle)
|
|
||||||
painter->drawRect(QRectF(0, 0, CARD_WIDTH - 1, CARD_HEIGHT - penWidth));
|
|
||||||
else
|
|
||||||
painter->drawRect(QRectF(1, 1, CARD_WIDTH - 2, CARD_HEIGHT - 1.5));
|
|
||||||
|
|
||||||
if (translatedPixmap.isNull() || SettingsCache::instance().getDisplayCardNames() || facedown) {
|
if (translatedPixmap.isNull() || SettingsCache::instance().getDisplayCardNames() || facedown) {
|
||||||
painter->save();
|
painter->save();
|
||||||
transformPainter(painter, translatedSize, angle);
|
transformPainter(painter, translatedSize, angle);
|
||||||
|
@ -158,9 +155,7 @@ void AbstractCardItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *
|
||||||
QSizeF translatedSize = getTranslatedSize(painter);
|
QSizeF translatedSize = getTranslatedSize(painter);
|
||||||
paintPicture(painter, translatedSize, tapAngle);
|
paintPicture(painter, translatedSize, tapAngle);
|
||||||
|
|
||||||
painter->save();
|
|
||||||
painter->setRenderHint(QPainter::Antialiasing, false);
|
painter->setRenderHint(QPainter::Antialiasing, false);
|
||||||
transformPainter(painter, translatedSize, tapAngle);
|
|
||||||
|
|
||||||
if (isSelected() || isHovered) {
|
if (isSelected() || isHovered) {
|
||||||
QPen pen;
|
QPen pen;
|
||||||
|
@ -168,15 +163,12 @@ void AbstractCardItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *
|
||||||
pen.setColor(Qt::yellow);
|
pen.setColor(Qt::yellow);
|
||||||
if (isSelected())
|
if (isSelected())
|
||||||
pen.setColor(Qt::red);
|
pen.setColor(Qt::red);
|
||||||
const int penWidth = 1;
|
pen.setWidth(0); // Cosmetic pen
|
||||||
pen.setWidth(penWidth);
|
|
||||||
painter->setPen(pen);
|
painter->setPen(pen);
|
||||||
painter->drawRect(QRectF(0, 0, translatedSize.width() + penWidth, translatedSize.height() - penWidth));
|
painter->drawPath(shape());
|
||||||
}
|
}
|
||||||
|
|
||||||
painter->restore();
|
painter->restore();
|
||||||
|
|
||||||
painter->restore();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AbstractCardItem::setName(const QString &_name)
|
void AbstractCardItem::setName(const QString &_name)
|
||||||
|
|
|
@ -54,6 +54,7 @@ public:
|
||||||
QGraphicsItem *parent = nullptr);
|
QGraphicsItem *parent = nullptr);
|
||||||
~AbstractCardItem();
|
~AbstractCardItem();
|
||||||
QRectF boundingRect() const;
|
QRectF boundingRect() const;
|
||||||
|
QPainterPath shape() const override;
|
||||||
QSizeF getTranslatedSize(QPainter *painter) const;
|
QSizeF getTranslatedSize(QPainter *painter) const;
|
||||||
void paintPicture(QPainter *painter, const QSizeF &translatedSize, int angle);
|
void paintPicture(QPainter *painter, const QSizeF &translatedSize, int angle);
|
||||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
|
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
|
||||||
|
|
|
@ -24,7 +24,7 @@ void CardDragItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *opti
|
||||||
AbstractCardDragItem::paint(painter, option, widget);
|
AbstractCardDragItem::paint(painter, option, widget);
|
||||||
|
|
||||||
if (occupied)
|
if (occupied)
|
||||||
painter->fillRect(boundingRect(), QColor(200, 0, 0, 100));
|
painter->fillPath(shape(), QColor(200, 0, 0, 100));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CardDragItem::updatePosition(const QPointF &cursorScenePos)
|
void CardDragItem::updatePosition(const QPointF &cursorScenePos)
|
||||||
|
|
|
@ -4,8 +4,7 @@
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "pictureloader.h"
|
#include "pictureloader.h"
|
||||||
|
|
||||||
#include <QPainter>
|
#include <QStylePainter>
|
||||||
#include <QStyle>
|
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
|
||||||
CardInfoPicture::CardInfoPicture(QWidget *parent) : QWidget(parent), info(nullptr), pixmapDirty(true)
|
CardInfoPicture::CardInfoPicture(QWidget *parent) : QWidget(parent), info(nullptr), pixmapDirty(true)
|
||||||
|
@ -55,6 +54,13 @@ void CardInfoPicture::paintEvent(QPaintEvent *)
|
||||||
if (pixmapDirty)
|
if (pixmapDirty)
|
||||||
loadPixmap();
|
loadPixmap();
|
||||||
|
|
||||||
QPainter painter(this);
|
QSize scaledSize = resizedPixmap.size().scaled(size(), Qt::KeepAspectRatio);
|
||||||
style()->drawItemPixmap(&painter, rect(), Qt::AlignHCenter, resizedPixmap);
|
QPoint topLeft{(width() - scaledSize.width()) / 2, (height() - scaledSize.height()) / 2};
|
||||||
|
qreal radius = 0.05 * scaledSize.width();
|
||||||
|
|
||||||
|
QStylePainter painter(this);
|
||||||
|
QPainterPath shape;
|
||||||
|
shape.addRoundedRect(QRect(topLeft, scaledSize), radius, radius);
|
||||||
|
painter.setClipPath(shape);
|
||||||
|
painter.drawItemPixmap(QRect(topLeft, scaledSize), Qt::AlignCenter, resizedPixmap);
|
||||||
}
|
}
|
||||||
|
|
|
@ -141,21 +141,19 @@ void CardItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getBeingPointedAt()) {
|
if (getBeingPointedAt()) {
|
||||||
painter->fillRect(boundingRect(), QBrush(QColor(255, 0, 0, 100)));
|
painter->fillPath(shape(), QBrush(QColor(255, 0, 0, 100)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (doesntUntap) {
|
if (doesntUntap) {
|
||||||
painter->save();
|
painter->save();
|
||||||
|
|
||||||
painter->setRenderHint(QPainter::Antialiasing, false);
|
painter->setRenderHint(QPainter::Antialiasing, false);
|
||||||
transformPainter(painter, translatedSize, tapAngle);
|
|
||||||
|
|
||||||
QPen pen;
|
QPen pen;
|
||||||
pen.setColor(Qt::magenta);
|
pen.setColor(Qt::magenta);
|
||||||
const int penWidth = 1;
|
pen.setWidth(0); // Cosmetic pen
|
||||||
pen.setWidth(penWidth);
|
|
||||||
painter->setPen(pen);
|
painter->setPen(pen);
|
||||||
painter->drawRect(QRectF(0, 0, translatedSize.width() + penWidth, translatedSize.height() - penWidth));
|
painter->drawPath(shape());
|
||||||
|
|
||||||
painter->restore();
|
painter->restore();
|
||||||
}
|
}
|
||||||
|
|
|
@ -89,7 +89,8 @@ void DeckViewCard::paint(QPainter *painter, const QStyleOptionGraphicsItem *opti
|
||||||
pen.setJoinStyle(Qt::MiterJoin);
|
pen.setJoinStyle(Qt::MiterJoin);
|
||||||
pen.setColor(originZone == DECK_ZONE_MAIN ? Qt::green : Qt::red);
|
pen.setColor(originZone == DECK_ZONE_MAIN ? Qt::green : Qt::red);
|
||||||
painter->setPen(pen);
|
painter->setPen(pen);
|
||||||
painter->drawRect(QRectF(1, 1, CARD_WIDTH - 2, CARD_HEIGHT - 2.5));
|
qreal cardRadius = 0.05 * (CARD_WIDTH - 3);
|
||||||
|
painter->drawRoundedRect(QRectF(1.5, 1.5, CARD_WIDTH - 3., CARD_HEIGHT - 3.), cardRadius, cardRadius);
|
||||||
painter->restore();
|
painter->restore();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,13 +28,20 @@ QRectF PileZone::boundingRect() const
|
||||||
return QRectF(0, 0, CARD_WIDTH, CARD_HEIGHT);
|
return QRectF(0, 0, CARD_WIDTH, CARD_HEIGHT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QPainterPath PileZone::shape() const
|
||||||
|
{
|
||||||
|
QPainterPath shape;
|
||||||
|
shape.addRoundedRect(boundingRect(), 0.05 * CARD_WIDTH, 0.05 * CARD_WIDTH);
|
||||||
|
return shape;
|
||||||
|
}
|
||||||
|
|
||||||
void PileZone::paint(QPainter *painter, const QStyleOptionGraphicsItem * /*option*/, QWidget * /*widget*/)
|
void PileZone::paint(QPainter *painter, const QStyleOptionGraphicsItem * /*option*/, QWidget * /*widget*/)
|
||||||
{
|
{
|
||||||
|
painter->drawPath(shape());
|
||||||
|
|
||||||
if (!cards.isEmpty())
|
if (!cards.isEmpty())
|
||||||
cards.at(0)->paintPicture(painter, cards.at(0)->getTranslatedSize(painter), 90);
|
cards.at(0)->paintPicture(painter, cards.at(0)->getTranslatedSize(painter), 90);
|
||||||
|
|
||||||
painter->drawRect(QRectF(0.5, 0.5, CARD_WIDTH - 1, CARD_HEIGHT - 1));
|
|
||||||
|
|
||||||
painter->translate((float)CARD_WIDTH / 2, (float)CARD_HEIGHT / 2);
|
painter->translate((float)CARD_WIDTH / 2, (float)CARD_HEIGHT / 2);
|
||||||
painter->rotate(-90);
|
painter->rotate(-90);
|
||||||
painter->translate((float)-CARD_WIDTH / 2, (float)-CARD_HEIGHT / 2);
|
painter->translate((float)-CARD_WIDTH / 2, (float)-CARD_HEIGHT / 2);
|
||||||
|
|
|
@ -19,6 +19,7 @@ public:
|
||||||
bool _contentsKnown,
|
bool _contentsKnown,
|
||||||
QGraphicsItem *parent = nullptr);
|
QGraphicsItem *parent = nullptr);
|
||||||
QRectF boundingRect() const;
|
QRectF boundingRect() const;
|
||||||
|
QPainterPath shape() const override;
|
||||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
|
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
|
||||||
void reorganizeCards();
|
void reorganizeCards();
|
||||||
void handleDropEvent(const QList<CardDragItem *> &dragItems, CardZone *startZone, const QPoint &dropPoint);
|
void handleDropEvent(const QList<CardDragItem *> &dragItems, CardZone *startZone, const QPoint &dropPoint);
|
||||||
|
|
Loading…
Reference in a new issue