diff --git a/cockatrice/src/deckview.cpp b/cockatrice/src/deckview.cpp index 5a14ec3f..101a2a11 100644 --- a/cockatrice/src/deckview.cpp +++ b/cockatrice/src/deckview.cpp @@ -146,8 +146,15 @@ void DeckViewCardContainer::paint(QPainter *painter, const QStyleOptionGraphicsI { qreal totalTextWidth = getCardTypeTextWidth(); - if (bgPixmap.isNull()) - painter->fillRect(boundingRect(), QColor(0, 0, 100)); + if (bgPixmap.isNull()) { + QLinearGradient grad1(0, 0, 1, 0); + grad1.setCoordinateMode(QGradient::ObjectBoundingMode); + grad1.setColorAt(0, QColor(48, 34, 69)); + grad1.setColorAt(1, QColor(110, 90, 140)); + painter->fillRect(QRectF(0, 0, width, height), QBrush(grad1)); + + painter->fillRect(boundingRect(), QColor(0, 0, 0, 80)); + } else painter->fillRect(boundingRect(), QBrush(bgPixmap)); painter->setPen(QColor(255, 255, 255, 100)); diff --git a/cockatrice/src/handzone.cpp b/cockatrice/src/handzone.cpp index cd9ba959..3a4e6f1d 100644 --- a/cockatrice/src/handzone.cpp +++ b/cockatrice/src/handzone.cpp @@ -78,7 +78,7 @@ QRectF HandZone::boundingRect() const void HandZone::paint(QPainter *painter, const QStyleOptionGraphicsItem * /*option*/, QWidget * /*widget*/) { if (bgPixmap.isNull()) - painter->fillRect(boundingRect(), Qt::darkGreen); + painter->fillRect(boundingRect(), QColor(80, 100, 50)); else painter->fillRect(boundingRect(), QBrush(bgPixmap)); } diff --git a/cockatrice/src/tablezone.cpp b/cockatrice/src/tablezone.cpp index f716cfbc..68d22c47 100644 --- a/cockatrice/src/tablezone.cpp +++ b/cockatrice/src/tablezone.cpp @@ -16,16 +16,24 @@ #include "pb/command_move_card.pb.h" #include "pb/command_set_card_attr.pb.h" + +const QColor TableZone::BACKGROUND_COLOR = QColor(70, 50, 100); +const QColor TableZone::FADE_MASK = QColor(0, 0, 0, 80); +const QColor TableZone::GRADIENT_COLOR = QColor(255, 255, 255, 150); +const QColor TableZone::GRADIENT_COLORLESS = QColor(255, 255, 255, 0); + + TableZone::TableZone(Player *_p, QGraphicsItem *parent) : SelectZone(_p, "table", true, false, true, parent), active(false) { connect(settingsCache, SIGNAL(tableBgPathChanged()), this, SLOT(updateBgPixmap())); connect(settingsCache, SIGNAL(invertVerticalCoordinateChanged()), this, SLOT(reorganizeCards())); + updateBgPixmap(); - height = 2 * boxLineWidth + 3 * (CARD_HEIGHT + 20) + 2 * paddingY; - width = minWidth + 2 * marginX + 2 * boxLineWidth; - currentMinimumWidth = minWidth; + height = 2 * BOX_LINE_WIDTH + 3 * (CARD_HEIGHT + 20) + 2 * PADDING_Y; + width = MIN_WIDTH + 2 * MARGIN_X + 2 * BOX_LINE_WIDTH; + currentMinimumWidth = MIN_WIDTH; setCacheMode(DeviceCoordinateCache); #if QT_VERSION < 0x050000 @@ -35,57 +43,86 @@ TableZone::TableZone(Player *_p, QGraphicsItem *parent) #endif } + void TableZone::updateBgPixmap() { QString bgPath = settingsCache->getTableBgPath(); if (!bgPath.isEmpty()) - bgPixmap.load(bgPath); + backgroundPixelMap.load(bgPath); update(); } + QRectF TableZone::boundingRect() const { return QRectF(0, 0, width, height); } + bool TableZone::isInverted() const { return ((player->getMirrored() && !settingsCache->getInvertVerticalCoordinate()) || (!player->getMirrored() && settingsCache->getInvertVerticalCoordinate())); } + void TableZone::paint(QPainter *painter, const QStyleOptionGraphicsItem * /*option*/, QWidget * /*widget*/) { - if (bgPixmap.isNull()) - painter->fillRect(boundingRect(), QColor(0, 0, 100)); + // if no custom background is provided then use the default color + if (backgroundPixelMap.isNull()) + painter->fillRect(boundingRect(), BACKGROUND_COLOR); else - painter->fillRect(boundingRect(), QBrush(bgPixmap)); + painter->fillRect(boundingRect(), QBrush(backgroundPixelMap)); + + if (active) { + paintZoneOutline(painter); + } else { + // inactive player gets a darker table zone with a semi transparent black mask + // this means if the user provides a custom background it will fade + painter->fillRect(boundingRect(), FADE_MASK); + } + + paintLandDivider(painter); +} + + +/** + Render a soft outline around the edge of the TableZone. + + @param painter QPainter object + */ +void TableZone::paintZoneOutline(QPainter *painter) { + QLinearGradient grad1(0, 0, 0, 1); + grad1.setCoordinateMode(QGradient::ObjectBoundingMode); + grad1.setColorAt(0, GRADIENT_COLOR); + grad1.setColorAt(1, GRADIENT_COLORLESS); + painter->fillRect(QRectF(0, 0, width, BOX_LINE_WIDTH), QBrush(grad1)); + + grad1.setFinalStop(1, 0); + painter->fillRect(QRectF(0, 0, BOX_LINE_WIDTH, height), QBrush(grad1)); + + grad1.setStart(0, 1); + grad1.setFinalStop(0, 0); + painter->fillRect(QRectF(0, height - BOX_LINE_WIDTH, width, BOX_LINE_WIDTH), QBrush(grad1)); + + grad1.setStart(1, 0); + painter->fillRect(QRectF(width - BOX_LINE_WIDTH, 0, BOX_LINE_WIDTH, height), QBrush(grad1)); +} + + +/** + Render a division line for land placement + + @painter QPainter object + */ +void TableZone::paintLandDivider(QPainter *painter){ painter->setPen(QColor(255, 255, 255, 40)); - qreal separatorY = 2 * (CARD_HEIGHT + 20 + paddingY) + boxLineWidth - paddingY / 2; + qreal separatorY = 2 * (CARD_HEIGHT + 20 + PADDING_Y) + BOX_LINE_WIDTH - PADDING_Y / 2; if (isInverted()) separatorY = height - separatorY; painter->drawLine(QPointF(0, separatorY), QPointF(width, separatorY)); - - if (active) { - QColor color1(255, 255, 255, 150); - QColor color2(255, 255, 255, 0); - QLinearGradient grad1(0, 0, 0, 1); - grad1.setCoordinateMode(QGradient::ObjectBoundingMode); - grad1.setColorAt(0, color1); - grad1.setColorAt(1, color2); - painter->fillRect(QRectF(0, 0, width, boxLineWidth), QBrush(grad1)); - - grad1.setFinalStop(1, 0); - painter->fillRect(QRectF(0, 0, boxLineWidth, height), QBrush(grad1)); - - grad1.setStart(0, 1); - grad1.setFinalStop(0, 0); - painter->fillRect(QRectF(0, height - boxLineWidth, width, boxLineWidth), QBrush(grad1)); - - grad1.setStart(1, 0); - painter->fillRect(QRectF(width - boxLineWidth, 0, boxLineWidth, height), QBrush(grad1)); - } } + void TableZone::addCardImpl(CardItem *card, int _x, int _y) { cards.append(card); @@ -96,11 +133,13 @@ void TableZone::addCardImpl(CardItem *card, int _x, int _y) card->update(); } + void TableZone::handleDropEvent(const QList &dragItems, CardZone *startZone, const QPoint &dropPoint) { handleDropEventByGrid(dragItems, startZone, mapToGrid(dropPoint)); } + void TableZone::handleDropEventByGrid(const QList &dragItems, CardZone *startZone, const QPoint &gridPoint) { Command_MoveCard cmd; @@ -121,6 +160,7 @@ void TableZone::handleDropEventByGrid(const QList &dragItems, Ca startZone->getPlayer()->sendGameCommand(cmd); } + void TableZone::reorganizeCards() { QList arrowsToUpdate; @@ -193,6 +233,7 @@ void TableZone::reorganizeCards() update(); } + void TableZone::toggleTapped() { QList selectedItems = scene()->selectedItems(); @@ -217,6 +258,7 @@ void TableZone::toggleTapped() player->sendGameCommand(player->prepareGameCommand(cmdList)); } + CardItem *TableZone::takeCard(int position, int cardId, bool canResize) { CardItem *result = CardZone::takeCard(position, cardId); @@ -225,6 +267,7 @@ CardItem *TableZone::takeCard(int position, int cardId, bool canResize) return result; } + void TableZone::resizeToContents() { int xMax = 0; @@ -232,9 +275,9 @@ void TableZone::resizeToContents() if (cards[i]->pos().x() > xMax) xMax = (int) cards[i]->pos().x(); xMax += 2 * CARD_WIDTH; - if (xMax < minWidth) - xMax = minWidth; - currentMinimumWidth = xMax + 2 * marginX + 2 * boxLineWidth; + if (xMax < MIN_WIDTH) + xMax = MIN_WIDTH; + currentMinimumWidth = xMax + 2 * MARGIN_X + 2 * BOX_LINE_WIDTH; if (currentMinimumWidth != width) { prepareGeometryChange(); width = currentMinimumWidth; @@ -242,6 +285,7 @@ void TableZone::resizeToContents() } } + CardItem *TableZone::getCardFromGrid(const QPoint &gridPoint) const { for (int i = 0; i < cards.size(); i++) @@ -256,17 +300,18 @@ CardItem *TableZone::getCardFromCoords(const QPointF &point) const return getCardFromGrid(gridPoint); } + QPointF TableZone::mapFromGrid(QPoint gridPoint) const { qreal x, y; - x = marginX + (gridPoint.x() % 3) * CARD_WIDTH / 3.0; + x = MARGIN_X + (gridPoint.x() % 3) * CARD_WIDTH / 3.0; for (int i = 0; i < gridPoint.x() / 3; ++i) - x += gridPointWidth.value(gridPoint.y() * 1000 + i, CARD_WIDTH) + paddingX; + x += gridPointWidth.value(gridPoint.y() * 1000 + i, CARD_WIDTH) + PADDING_X; if (isInverted()) gridPoint.setY(2 - gridPoint.y()); - y = boxLineWidth + gridPoint.y() * (CARD_HEIGHT + paddingY + 20) + (gridPoint.x() % 3) * 10; + y = BOX_LINE_WIDTH + gridPoint.y() * (CARD_HEIGHT + PADDING_Y + 20) + (gridPoint.x() % 3) * 10; /* if (isInverted()) y = height - CARD_HEIGHT - y; @@ -274,24 +319,25 @@ QPointF TableZone::mapFromGrid(QPoint gridPoint) const return QPointF(x, y); } + QPoint TableZone::mapToGrid(const QPointF &mapPoint) const { - qreal x = mapPoint.x() - marginX; + qreal x = mapPoint.x() - MARGIN_X; qreal y = mapPoint.y(); /* if (isInverted()) y = height - y; -*/ y -= boxLineWidth; +*/ y -= BOX_LINE_WIDTH; if (x < 0) x = 0; - else if (x > width - CARD_WIDTH - marginX) - x = width - CARD_WIDTH - marginX; + else if (x > width - CARD_WIDTH - MARGIN_X) + x = width - CARD_WIDTH - MARGIN_X; if (y < 0) y = 0; else if (y > height - CARD_HEIGHT) y = height - CARD_HEIGHT; - int resultY = round(y / (CARD_HEIGHT + paddingY + 20)); + int resultY = round(y / (CARD_HEIGHT + PADDING_Y + 20)); if (isInverted()) resultY = 2 - resultY; @@ -300,7 +346,7 @@ QPoint TableZone::mapToGrid(const QPointF &mapPoint) const do { ++baseX; oldTempX = tempX; - tempX += gridPointWidth.value(resultY * 1000 + baseX, CARD_WIDTH) + paddingX; + tempX += gridPointWidth.value(resultY * 1000 + baseX, CARD_WIDTH) + PADDING_X; } while (tempX < x + 1); qreal xdiff = x - oldTempX; @@ -308,6 +354,7 @@ QPoint TableZone::mapToGrid(const QPointF &mapPoint) const return QPoint(resultX, resultY); } + QPointF TableZone::closestGridPoint(const QPointF &point) { QPoint gridPoint = mapToGrid(point + QPoint(1, 1)); @@ -318,9 +365,3 @@ QPointF TableZone::closestGridPoint(const QPointF &point) gridPoint.setX(gridPoint.x() + 1); return mapFromGrid(gridPoint); } - -void TableZone::setWidth(qreal _width) -{ - prepareGeometryChange(); - width = _width; -} diff --git a/cockatrice/src/tablezone.h b/cockatrice/src/tablezone.h index 297f097f..9b362efa 100644 --- a/cockatrice/src/tablezone.h +++ b/cockatrice/src/tablezone.h @@ -1,50 +1,149 @@ #ifndef TABLEZONE_H #define TABLEZONE_H + #include "selectzone.h" #include "abstractcarditem.h" + +/* +* TableZone is the grid based rect where CardItems may be placed. +* It is the main play zone and can be customized with background images. +* +* TODO: Refactor methods to make more readable, extract some logic to +* private methods (Im looking at you TableZone::reorganizeCards()) +*/ class TableZone : public SelectZone { Q_OBJECT + signals: void sizeChanged(); -private: - static const int boxLineWidth = 10; - static const int paddingX = 35; - static const int paddingY = 10; - static const int marginX = 20; - static const int minWidth = 15 * CARD_WIDTH / 2; +private: + static const int BOX_LINE_WIDTH = 10; + static const int PADDING_X = 35; + static const int PADDING_Y = 10; + static const int MARGIN_X = 20; + static const int MIN_WIDTH = 15 * CARD_WIDTH / 2; + + /* + Default background color, inactive mask and boarder gradient + */ + static const QColor BACKGROUND_COLOR; + static const QColor FADE_MASK; + static const QColor GRADIENT_COLOR; + static const QColor GRADIENT_COLORLESS; + + /* + Size and shape variables + */ QMap gridPointWidth; - int width, height; + int width; + int height; int currentMinimumWidth; - QPixmap bgPixmap; + + /* + Holds any custom background image for the TableZone + */ + QPixmap backgroundPixelMap; + + /* + If this TableZone is currently active + */ bool active; + bool isInverted() const; -private slots: + +private slots: + /** + Loads in any found custom background and updates + */ void updateBgPixmap(); + public slots: + /** + Reorganizes CardItems in the TableZone + */ void reorganizeCards(); + public: + /** + Constructs TableZone. + + @param _p the Player + @param parent defaults to null + */ TableZone(Player *_p, QGraphicsItem *parent = 0); + + /** + @return a QRectF of the TableZone bounding box. + */ QRectF boundingRect() const; + + /** + Render the TableZone + + @param painter + @param option + */ void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); + + /** + Toggles the selected items as tapped. + */ void toggleTapped(); + + /** + See HandleDropEventByGrid + */ void handleDropEvent(const QList &dragItems, CardZone *startZone, const QPoint &dropPoint); + + /** + Handles the placement of cards + */ void handleDropEventByGrid(const QList &dragItems, CardZone *startZone, const QPoint &gridPoint); + + /** + @return CardItem from grid location + */ CardItem *getCardFromGrid(const QPoint &gridPoint) const; + + /** + @return CardItem from coordinate location + */ CardItem *getCardFromCoords(const QPointF &point) const; + QPointF mapFromGrid(QPoint gridPoint) const; QPoint mapToGrid(const QPointF &mapPoint) const; QPointF closestGridPoint(const QPointF &point); + + /** + Removes a card from view. + + @param position card position + @param cardId id of card to take + @param canResize defaults to true + @return CardItem that has been removed + */ CardItem *takeCard(int position, int cardId, bool canResize = true); + + /** + Resizes the TableZone in case CardItems are within or + outside of the TableZone constraints. + */ void resizeToContents(); + int getMinimumWidth() const { return currentMinimumWidth; } - void setWidth(qreal _width); + void setWidth(qreal _width){ prepareGeometryChange(); width = _width;}; qreal getWidth() const { return width; } void setActive(bool _active) { active = _active; update(); } + protected: void addCardImpl(CardItem *card, int x, int y); + +private: + void paintZoneOutline(QPainter *painter); + void paintLandDivider(QPainter *painter); }; #endif