diff --git a/cockatrice/cockatrice.pro b/cockatrice/cockatrice.pro index 14df413b..eb7f0978 100644 --- a/cockatrice/cockatrice.pro +++ b/cockatrice/cockatrice.pro @@ -21,8 +21,6 @@ HEADERS += src/counter.h \ src/tablezone.h \ src/handzone.h \ src/handcounter.h \ - src/handzone_vert.h \ - src/handzone_horiz.h \ src/carddatabase.h \ src/gameview.h \ src/deck_picturecacher.h \ @@ -78,8 +76,6 @@ SOURCES += src/counter.cpp \ src/tablezone.cpp \ src/handzone.cpp \ src/handcounter.cpp \ - src/handzone_vert.cpp \ - src/handzone_horiz.cpp \ src/carddatabase.cpp \ src/gameview.cpp \ src/deck_picturecacher.cpp \ diff --git a/cockatrice/resources/hand.svg b/cockatrice/resources/hand.svg new file mode 100644 index 00000000..8c28fd59 --- /dev/null +++ b/cockatrice/resources/hand.svg @@ -0,0 +1,487 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cockatrice/src/gamescene.cpp b/cockatrice/src/gamescene.cpp index 22fcf6d8..4e068904 100644 --- a/cockatrice/src/gamescene.cpp +++ b/cockatrice/src/gamescene.cpp @@ -35,7 +35,7 @@ void GameScene::removePlayer(Player *player) void GameScene::rearrange() { struct PlayerProcessor { - static void processPlayer(Player *p, qreal &w, qreal &h, QPointF &b) + static void processPlayer(Player *p, qreal &w, qreal &h, QPointF &b, bool singlePlayer) { const QRectF br = p->boundingRect(); if (br.width() > w) @@ -44,6 +44,7 @@ void GameScene::rearrange() h += playerAreaSpacing; h += br.height(); p->setPos(b); + p->setMirrored((b.y() < playerAreaSpacing) && !singlePlayer); b += QPointF(0, br.height() + playerAreaSpacing); } }; @@ -55,11 +56,11 @@ void GameScene::rearrange() for (int i = 0; i < players.size(); ++i) if (!players[i]->getLocal()) - PlayerProcessor::processPlayer(players[i], sceneWidth, sceneHeight, base); + PlayerProcessor::processPlayer(players[i], sceneWidth, sceneHeight, base, players.size() == 1); else localPlayer = players[i]; if (localPlayer) - PlayerProcessor::processPlayer(localPlayer, sceneWidth, sceneHeight, base); + PlayerProcessor::processPlayer(localPlayer, sceneWidth, sceneHeight, base, players.size() == 1); playersRect = QRectF(0, 0, sceneWidth, sceneHeight); diff --git a/cockatrice/src/handcounter.cpp b/cockatrice/src/handcounter.cpp new file mode 100644 index 00000000..dbc85a30 --- /dev/null +++ b/cockatrice/src/handcounter.cpp @@ -0,0 +1,38 @@ +#include +#include +#include "handcounter.h" +#include "cardzone.h" + +HandCounter::HandCounter(QGraphicsItem *parent) + : AbstractGraphicsItem(parent), number(0) +{ + setCacheMode(DeviceCoordinateCache); + + QSvgRenderer svg(QString(":/resources/hand.svg")); + handImage = new QPixmap(72, 72); + handImage->fill(Qt::transparent); + QPainter painter(handImage); + svg.render(&painter, QRectF(0, 0, 72, 72)); +} + +HandCounter::~HandCounter() +{ + delete handImage; +} + +void HandCounter::updateNumber() +{ + number = static_cast(sender())->getCards().size(); + update(); +} + +QRectF HandCounter::boundingRect() const +{ + return QRectF(0, 0, 72, 72); +} + +void HandCounter::paint(QPainter *painter, const QStyleOptionGraphicsItem * /*option*/, QWidget * /*widget*/) +{ + painter->drawPixmap(handImage->rect(), *handImage, handImage->rect()); + paintNumberEllipse(number, painter); +} diff --git a/cockatrice/src/handcounter.h b/cockatrice/src/handcounter.h new file mode 100644 index 00000000..33afe8c3 --- /dev/null +++ b/cockatrice/src/handcounter.h @@ -0,0 +1,27 @@ +#ifndef HANDCOUNTER_H +#define HANDCOUNTER_H + +#include +#include "abstractcarditem.h" + +class QPainter; +class QPixmap; + +class HandCounter : public QObject, public AbstractGraphicsItem { + Q_OBJECT +private: + int number; + QPixmap *handImage; +public slots: + void updateNumber(); +public: + enum { Type = typeOther }; + int type() const { return Type; } + HandCounter(QGraphicsItem *parent = 0); + ~HandCounter(); + QRectF boundingRect() const; + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); +}; + +#endif + diff --git a/cockatrice/src/handzone.cpp b/cockatrice/src/handzone.cpp index ad09449c..25b71201 100644 --- a/cockatrice/src/handzone.cpp +++ b/cockatrice/src/handzone.cpp @@ -1,13 +1,15 @@ +#include #include "handzone.h" #include "settingscache.h" #include "player.h" #include "protocol_items.h" -HandZone::HandZone(Player *_p, bool _contentsKnown, QGraphicsItem *parent) - : CardZone(_p, "hand", false, false, _contentsKnown, parent) +HandZone::HandZone(Player *_p, bool _contentsKnown, int _zoneHeight, QGraphicsItem *parent) + : CardZone(_p, "hand", false, false, _contentsKnown, parent), zoneHeight(_zoneHeight) { connect(settingsCache, SIGNAL(handBgPathChanged()), this, SLOT(updateBgPixmap())); updateBgPixmap(); + setCacheMode(DeviceCoordinateCache); } void HandZone::updateBgPixmap() @@ -38,3 +40,79 @@ void HandZone::handleDropEvent(int cardId, CardZone *startZone, const QPoint &/* { player->sendGameCommand(new Command_MoveCard(-1, startZone->getName(), cardId, getName(), cards.size(), -1, false)); } + +QRectF HandZone::boundingRect() const +{ + if (settingsCache->getHorizontalHand()) + return QRectF(0, 0, width, CARD_HEIGHT + 10); + else + return QRectF(0, 0, 100, zoneHeight); +} + +void HandZone::paint(QPainter *painter, const QStyleOptionGraphicsItem */*option*/, QWidget */*widget*/) +{ + if (bgPixmap.isNull()) + painter->fillRect(boundingRect(), Qt::darkGreen); + else + painter->fillRect(boundingRect(), QBrush(bgPixmap)); +} + +void HandZone::reorganizeCards() +{ + if (!cards.isEmpty()) { + const int cardCount = cards.size(); + if (settingsCache->getHorizontalHand()) { + const int xPadding = 5; + qreal totalWidth = boundingRect().width() - 2 * xPadding; + qreal cardWidth = cards.at(0)->boundingRect().width(); + + for (int i = 0; i < cardCount; i++) { + CardItem *c = cards.at(i); + + // If the total width of the cards is smaller than the available width, + // the cards do not need to overlap and are displayed in the center of the area. + if (cardWidth * cardCount > totalWidth) + c->setPos(xPadding + ((qreal) i) * (totalWidth - cardWidth) / (cardCount - 1), 5); + else + c->setPos(xPadding + ((qreal) i) * cardWidth + (totalWidth - cardCount * cardWidth) / 2, 5); + c->setZValue(i); + } + } else { + qreal totalWidth = boundingRect().width(); + qreal totalHeight = boundingRect().height(); + qreal cardWidth = cards.at(0)->boundingRect().width(); + qreal cardHeight = cards.at(0)->boundingRect().height(); + qreal xspace = 5; + qreal x1 = xspace; + qreal x2 = totalWidth - xspace - cardWidth; + + for (int i = 0; i < cardCount; i++) { + CardItem *c = cards.at(i); + qreal x = i % 2 ? x2 : x1; + // If the total height of the cards is smaller than the available height, + // the cards do not need to overlap and are displayed in the center of the area. + if (cardHeight * cardCount > totalHeight) + c->setPos(x, ((qreal) i) * (totalHeight - cardHeight) / (cardCount - 1)); + else + c->setPos(x, ((qreal) i) * cardHeight + (totalHeight - cardCount * cardHeight) / 2); + c->setZValue(i); + } + } + } + update(); +} + +void HandZone::setWidth(qreal _width) +{ + if (settingsCache->getHorizontalHand()) { + prepareGeometryChange(); + width = _width; + reorganizeCards(); + } +} + +void HandZone::updateOrientation() +{ + prepareGeometryChange(); + reorganizeCards(); +} diff --git a/cockatrice/src/handzone.h b/cockatrice/src/handzone.h index cd8eb578..1392fa16 100644 --- a/cockatrice/src/handzone.h +++ b/cockatrice/src/handzone.h @@ -5,14 +5,20 @@ class HandZone : public CardZone { Q_OBJECT -protected: +private: + qreal width, zoneHeight; QPixmap bgPixmap; private slots: void updateBgPixmap(); +public slots: + void updateOrientation(); public: - HandZone(Player *_p, bool _contentsKnown, QGraphicsItem *parent = 0); + HandZone(Player *_p, bool _contentsKnown, int _zoneHeight, QGraphicsItem *parent = 0); void handleDropEvent(int cardId, CardZone *startZone, const QPoint &dropPoint, bool faceDown); - virtual void setWidth(qreal _width) = 0; + QRectF boundingRect() const; + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); + void reorganizeCards(); + void setWidth(qreal _width); protected: void addCardImpl(CardItem *card, int x, int y); }; diff --git a/cockatrice/src/handzone_horiz.cpp b/cockatrice/src/handzone_horiz.cpp deleted file mode 100644 index 4a1da8c2..00000000 --- a/cockatrice/src/handzone_horiz.cpp +++ /dev/null @@ -1,52 +0,0 @@ -#include -#include "handzone_horiz.h" -#include "player.h" - -HandZoneHoriz::HandZoneHoriz(Player *_p, bool _contentsKnown, QGraphicsItem *parent) - : HandZone(_p, _contentsKnown, parent), width(CARD_WIDTH * 10) -{ - setCacheMode(DeviceCoordinateCache); -} - -QRectF HandZoneHoriz::boundingRect() const -{ - return QRectF(0, 0, width, CARD_HEIGHT + 10); -} - -void HandZoneHoriz::paint(QPainter *painter, const QStyleOptionGraphicsItem */*option*/, QWidget */*widget*/) -{ - if (bgPixmap.isNull()) - painter->fillRect(boundingRect(), Qt::darkGreen); - else - painter->fillRect(boundingRect(), QBrush(bgPixmap)); -} - -void HandZoneHoriz::reorganizeCards() -{ - if (!cards.isEmpty()) { - const int cardCount = cards.size(); - const int xPadding = 5; - qreal totalWidth = boundingRect().width() - 2 * xPadding; - qreal cardWidth = cards.at(0)->boundingRect().width(); - - for (int i = 0; i < cardCount; i++) { - CardItem *c = cards.at(i); - - // If the total width of the cards is smaller than the available width, - // the cards do not need to overlap and are displayed in the center of the area. - if (cardWidth * cardCount > totalWidth) - c->setPos(xPadding + ((qreal) i) * (totalWidth - cardWidth) / (cardCount - 1), 5); - else - c->setPos(xPadding + ((qreal) i) * cardWidth + (totalWidth - cardCount * cardWidth) / 2, 5); - c->setZValue(i); - } - } - update(); -} - -void HandZoneHoriz::setWidth(qreal _width) -{ - prepareGeometryChange(); - width = _width; - reorganizeCards(); -} diff --git a/cockatrice/src/handzone_horiz.h b/cockatrice/src/handzone_horiz.h deleted file mode 100644 index 37b76d41..00000000 --- a/cockatrice/src/handzone_horiz.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef HANDZONE_HORIZ_H -#define HANDZONE_HORIZ_H - -#include "handzone.h" - -class HandZoneHoriz : public HandZone { - Q_OBJECT -private: - qreal width; -public: - HandZoneHoriz(Player *_p, bool _contentsKnown, QGraphicsItem *parent = 0); - QRectF boundingRect() const; - void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); - void reorganizeCards(); - void setWidth(qreal _width); -}; - -#endif diff --git a/cockatrice/src/handzone_vert.cpp b/cockatrice/src/handzone_vert.cpp deleted file mode 100644 index 3e1ffdfd..00000000 --- a/cockatrice/src/handzone_vert.cpp +++ /dev/null @@ -1,52 +0,0 @@ -#include -#include "handzone_vert.h" -#include "player.h" -#include "client.h" -#include "protocol_items.h" -#include "settingscache.h" - -HandZoneVert::HandZoneVert(Player *_p, bool _contentsKnown, int _zoneHeight, QGraphicsItem *parent) - : HandZone(_p, _contentsKnown, parent), zoneHeight(_zoneHeight) -{ - setCacheMode(DeviceCoordinateCache); -} - -QRectF HandZoneVert::boundingRect() const -{ - return QRectF(0, 0, 100, zoneHeight); -} - -void HandZoneVert::paint(QPainter *painter, const QStyleOptionGraphicsItem */*option*/, QWidget */*widget*/) -{ - if (bgPixmap.isNull()) - painter->fillRect(boundingRect(), Qt::darkGreen); - else - painter->fillRect(boundingRect(), QBrush(bgPixmap)); -} - -void HandZoneVert::reorganizeCards() -{ - if (!cards.isEmpty()) { - const int cardCount = cards.size(); - qreal totalWidth = boundingRect().width(); - qreal totalHeight = boundingRect().height(); - qreal cardWidth = cards.at(0)->boundingRect().width(); - qreal cardHeight = cards.at(0)->boundingRect().height(); - qreal xspace = 5; - qreal x1 = xspace; - qreal x2 = totalWidth - xspace - cardWidth; - - for (int i = 0; i < cardCount; i++) { - CardItem *c = cards.at(i); - qreal x = i % 2 ? x2 : x1; - // If the total height of the cards is smaller than the available height, - // the cards do not need to overlap and are displayed in the center of the area. - if (cardHeight * cardCount > totalHeight) - c->setPos(x, ((qreal) i) * (totalHeight - cardHeight) / (cardCount - 1)); - else - c->setPos(x, ((qreal) i) * cardHeight + (totalHeight - cardCount * cardHeight) / 2); - c->setZValue(i); - } - } - update(); -} diff --git a/cockatrice/src/handzone_vert.h b/cockatrice/src/handzone_vert.h deleted file mode 100644 index 71ae261d..00000000 --- a/cockatrice/src/handzone_vert.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef HANDZONE_VERT_H -#define HANDZONE_VERT_H - -#include "handzone.h" - -class HandZoneVert : public HandZone { - Q_OBJECT -private: - int zoneHeight; -public: - HandZoneVert(Player *_p, bool _contentsKnown, int _zoneHeight, QGraphicsItem *parent = 0); - QRectF boundingRect() const; - void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); - void reorganizeCards(); - void setWidth(qreal /*_width*/) { } -}; - -#endif diff --git a/cockatrice/src/player.cpp b/cockatrice/src/player.cpp index f57e345a..f6211562 100644 --- a/cockatrice/src/player.cpp +++ b/cockatrice/src/player.cpp @@ -9,8 +9,6 @@ #include "tablezone.h" #include "handzone.h" #include "handcounter.h" -#include "handzone_vert.h" -#include "handzone_horiz.h" #include "cardlist.h" #include "tab_game.h" #include "protocol_items.h" @@ -20,11 +18,12 @@ #include #include -Player::Player(const QString &_name, int _id, bool _local, bool _mirrored, Client *_client, TabGame *_parent) - : QObject(_parent), defaultNumberTopCards(3), name(_name), id(_id), active(false), local(_local), mirrored(_mirrored), client(_client) +Player::Player(const QString &_name, int _id, bool _local, Client *_client, TabGame *_parent) + : QObject(_parent), defaultNumberTopCards(3), name(_name), id(_id), active(false), local(_local), mirrored(false), client(_client) { setCacheMode(DeviceCoordinateCache); + connect(settingsCache, SIGNAL(horizontalHandChanged()), this, SLOT(rearrangeZones())); connect(settingsCache, SIGNAL(playerBgPathChanged()), this, SLOT(updateBgPixmap())); updateBgPixmap(); @@ -33,7 +32,7 @@ Player::Player(const QString &_name, int _id, bool _local, bool _mirrored, Clien PileZone *deck = new PileZone(this, "deck", true, false, this); deck->setPos(base); - qreal h = deck->boundingRect().height() + 20; + qreal h = deck->boundingRect().height() + 10; PileZone *grave = new PileZone(this, "grave", false, true, this); grave->setPos(base + QPointF(0, h)); @@ -50,24 +49,7 @@ Player::Player(const QString &_name, int _id, bool _local, bool _mirrored, Clien table = new TableZone(this, this); connect(table, SIGNAL(sizeChanged()), this, SLOT(updateBoundingRect())); - base = QPointF(deck->boundingRect().width() + counterAreaWidth + 5, 0); - - if (settingsCache->getHorizontalHand()) { - hand = new HandZoneHoriz(this, _local || (_parent->getSpectator() && _parent->getSpectatorsSeeEverything()), this); - - if (mirrored) { - hand->setPos(counterAreaWidth + CARD_WIDTH + 5, base.y()); - table->setPos(base.x(), base.y() + hand->boundingRect().height()); - } else { - table->setPos(base); - hand->setPos(counterAreaWidth + CARD_WIDTH + 5, base.y() + table->boundingRect().height()); - } - } else { - hand = new HandZoneVert(this, _local || (_parent->getSpectator() && _parent->getSpectatorsSeeEverything()), (int) table->boundingRect().height(), this); - hand->setPos(base); - base += QPointF(hand->boundingRect().width(), 0); - table->setPos(base); - } + hand = new HandZone(this, _local || (_parent->getSpectator() && _parent->getSpectatorsSeeEverything()), (int) table->boundingRect().height(), this); connect(hand, SIGNAL(cardCountChanged()), handCounter, SLOT(updateNumber())); updateBoundingRect(); @@ -269,6 +251,7 @@ Player::Player(const QString &_name, int _id, bool _local, bool _mirrored, Clien cardMenu = 0; } + rearrangeZones(); retranslateUi(); } @@ -288,6 +271,29 @@ Player::~Player() delete cardMenu; } +void Player::rearrangeZones() +{ + QPointF base = QPointF(CARD_WIDTH + counterAreaWidth + 5, 0); + + if (settingsCache->getHorizontalHand()) { + if (mirrored) { + hand->setPos(counterAreaWidth + CARD_WIDTH + 5, base.y()); + table->setPos(base.x(), base.y() + hand->boundingRect().height()); + } else { + table->setPos(base); + hand->setPos(counterAreaWidth + CARD_WIDTH + 5, base.y() + table->boundingRect().height()); + } + hand->setWidth(table->getWidth()); + } else { + hand->setPos(base); + base += QPointF(hand->boundingRect().width(), 0); + table->setPos(base); + } + hand->updateOrientation(); + updateBoundingRect(); + rearrangeCounters(); +} + void Player::updateBgPixmap() { QString bgPath = settingsCache->getPlayerBgPath(); @@ -1023,6 +1029,14 @@ qreal Player::getMinimumWidth() const return table->getMinimumWidth() + CARD_WIDTH + 5 + counterAreaWidth; } +void Player::setMirrored(bool _mirrored) +{ + if (mirrored != _mirrored) { + mirrored = _mirrored; + rearrangeZones(); + } +} + void Player::processSceneSizeChange(const QSizeF &newSize) { // This will need to be changed if player areas are displayed side by side (e.g. 2x2 for a 4-player game) diff --git a/cockatrice/src/player.h b/cockatrice/src/player.h index 4935d04b..e9d4da32 100644 --- a/cockatrice/src/player.h +++ b/cockatrice/src/player.h @@ -80,6 +80,7 @@ private slots: void updateBoundingRect(); void cardMenuAction(); void actSetCounters(); + void rearrangeZones(); private: QMenu *playerMenu, *handMenu, *graveMenu, *rfgMenu, *libraryMenu, *sbMenu, *countersMenu, *sayMenu; QAction *aMoveHandToTopLibrary, *aMoveHandToBottomLibrary, *aMoveHandToGrave, *aMoveHandToRfg, @@ -165,7 +166,7 @@ public: void clearArrows(); Client *client; - Player(const QString &_name, int _id, bool _local, bool _mirrored, Client *_client, TabGame *_parent); + Player(const QString &_name, int _id, bool _local, Client *_client, TabGame *_parent); ~Player(); void retranslateUi(); QMenu *getPlayerMenu() const { return playerMenu; } @@ -181,6 +182,7 @@ public: void setActive(bool _active); qreal getMinimumWidth() const; + void setMirrored(bool _mirrored); void processSceneSizeChange(const QSizeF &newSize); void processPlayerInfo(ServerInfo_Player *info); diff --git a/cockatrice/src/settingscache.cpp b/cockatrice/src/settingscache.cpp index f9aeddd0..8f9fbb0e 100644 --- a/cockatrice/src/settingscache.cpp +++ b/cockatrice/src/settingscache.cpp @@ -89,6 +89,7 @@ void SettingsCache::setHorizontalHand(int _horizontalHand) { horizontalHand = _horizontalHand; settings->setValue("hand/horizontal", horizontalHand); + emit horizontalHandChanged(); } void SettingsCache::setEconomicGrid(int _economicGrid) diff --git a/cockatrice/src/settingscache.h b/cockatrice/src/settingscache.h index dc88cbaa..319f036d 100644 --- a/cockatrice/src/settingscache.h +++ b/cockatrice/src/settingscache.h @@ -15,6 +15,7 @@ signals: void tableBgPathChanged(); void playerBgPathChanged(); void picDownloadChanged(); + void horizontalHandChanged(); void economicGridChanged(); private: QSettings *settings; diff --git a/cockatrice/src/tab_game.cpp b/cockatrice/src/tab_game.cpp index c4535f03..127c2158 100644 --- a/cockatrice/src/tab_game.cpp +++ b/cockatrice/src/tab_game.cpp @@ -208,8 +208,7 @@ void TabGame::actRemoveLocalArrows() Player *TabGame::addPlayer(int playerId, const QString &playerName) { - // XXX Find a different criterion for the 'mirrored' flag. When spectating, both players are not local, but only one should be mirrored. - Player *newPlayer = new Player(playerName, playerId, playerId == localPlayerId, playerId != localPlayerId, client, this); + Player *newPlayer = new Player(playerName, playerId, playerId == localPlayerId, client, this); scene->addPlayer(newPlayer); connect(newPlayer, SIGNAL(newCardAdded(AbstractCardItem *)), this, SLOT(newCardAdded(AbstractCardItem *))); diff --git a/cockatrice/src/tablezone.cpp b/cockatrice/src/tablezone.cpp index cef7b027..40a4866c 100644 --- a/cockatrice/src/tablezone.cpp +++ b/cockatrice/src/tablezone.cpp @@ -76,7 +76,7 @@ void TableZone::reorganizeCards() qreal x = mapPoint.x(); qreal y = mapPoint.y(); - if (!player->getLocal()) + if (player->getMirrored()) y = height - CARD_HEIGHT - y; cards[i]->setPos(x, y); cards[i]->setZValue((y + CARD_HEIGHT) * 10000000 + x + 1000); diff --git a/cockatrice/src/tablezone.h b/cockatrice/src/tablezone.h index 3fd39285..d543ae32 100644 --- a/cockatrice/src/tablezone.h +++ b/cockatrice/src/tablezone.h @@ -35,6 +35,7 @@ public: void resizeToContents(); int getMinimumWidth() const { return currentMinimumWidth; } void setWidth(qreal _width); + qreal getWidth() const { return width; } protected: void addCardImpl(CardItem *card, int x, int y); };