diff --git a/cockatrice/src/dlg_settings.cpp b/cockatrice/src/dlg_settings.cpp index b14bdc62..80526f9b 100644 --- a/cockatrice/src/dlg_settings.cpp +++ b/cockatrice/src/dlg_settings.cpp @@ -299,6 +299,7 @@ void GeneralSettingsPage::retranslateUi() AppearanceSettingsPage::AppearanceSettingsPage() { + SettingsCache &settings = SettingsCache::instance(); QString themeName = SettingsCache::instance().getThemeName(); QStringList themeDirs = themeManager->getAvailableThemes().keys(); @@ -319,27 +320,31 @@ AppearanceSettingsPage::AppearanceSettingsPage() themeGroupBox = new QGroupBox; themeGroupBox->setLayout(themeGrid); - displayCardNamesCheckBox.setChecked(SettingsCache::instance().getDisplayCardNames()); - connect(&displayCardNamesCheckBox, SIGNAL(stateChanged(int)), &SettingsCache::instance(), - SLOT(setDisplayCardNames(int))); + displayCardNamesCheckBox.setChecked(settings.getDisplayCardNames()); + connect(&displayCardNamesCheckBox, SIGNAL(stateChanged(int)), &settings, SLOT(setDisplayCardNames(int))); - cardScalingCheckBox.setChecked(SettingsCache::instance().getScaleCards()); - connect(&cardScalingCheckBox, SIGNAL(stateChanged(int)), &SettingsCache::instance(), SLOT(setCardScaling(int))); + cardScalingCheckBox.setChecked(settings.getScaleCards()); + connect(&cardScalingCheckBox, SIGNAL(stateChanged(int)), &settings, SLOT(setCardScaling(int))); + + verticalCardOverlapPercentBox.setValue(settings.getStackCardOverlapPercent()); + verticalCardOverlapPercentBox.setRange(0, 80); + connect(&verticalCardOverlapPercentBox, SIGNAL(valueChanged(int)), &settings, + SLOT(setStackCardOverlapPercent(int))); auto *cardsGrid = new QGridLayout; cardsGrid->addWidget(&displayCardNamesCheckBox, 0, 0, 1, 2); cardsGrid->addWidget(&cardScalingCheckBox, 1, 0, 1, 2); + cardsGrid->addWidget(&verticalCardOverlapPercentLabel, 2, 0, 1, 1); + cardsGrid->addWidget(&verticalCardOverlapPercentBox, 2, 1, 1, 1); cardsGroupBox = new QGroupBox; cardsGroupBox->setLayout(cardsGrid); - horizontalHandCheckBox.setChecked(SettingsCache::instance().getHorizontalHand()); - connect(&horizontalHandCheckBox, SIGNAL(stateChanged(int)), &SettingsCache::instance(), - SLOT(setHorizontalHand(int))); + horizontalHandCheckBox.setChecked(settings.getHorizontalHand()); + connect(&horizontalHandCheckBox, SIGNAL(stateChanged(int)), &settings, SLOT(setHorizontalHand(int))); - leftJustifiedHandCheckBox.setChecked(SettingsCache::instance().getLeftJustified()); - connect(&leftJustifiedHandCheckBox, SIGNAL(stateChanged(int)), &SettingsCache::instance(), - SLOT(setLeftJustified(int))); + leftJustifiedHandCheckBox.setChecked(settings.getLeftJustified()); + connect(&leftJustifiedHandCheckBox, SIGNAL(stateChanged(int)), &settings, SLOT(setLeftJustified(int))); auto *handGrid = new QGridLayout; handGrid->addWidget(&horizontalHandCheckBox, 0, 0, 1, 2); @@ -348,18 +353,18 @@ AppearanceSettingsPage::AppearanceSettingsPage() handGroupBox = new QGroupBox; handGroupBox->setLayout(handGrid); - invertVerticalCoordinateCheckBox.setChecked(SettingsCache::instance().getInvertVerticalCoordinate()); - connect(&invertVerticalCoordinateCheckBox, SIGNAL(stateChanged(int)), &SettingsCache::instance(), + invertVerticalCoordinateCheckBox.setChecked(settings.getInvertVerticalCoordinate()); + connect(&invertVerticalCoordinateCheckBox, SIGNAL(stateChanged(int)), &settings, SLOT(setInvertVerticalCoordinate(int))); minPlayersForMultiColumnLayoutEdit.setMinimum(2); - minPlayersForMultiColumnLayoutEdit.setValue(SettingsCache::instance().getMinPlayersForMultiColumnLayout()); - connect(&minPlayersForMultiColumnLayoutEdit, SIGNAL(valueChanged(int)), &SettingsCache::instance(), + minPlayersForMultiColumnLayoutEdit.setValue(settings.getMinPlayersForMultiColumnLayout()); + connect(&minPlayersForMultiColumnLayoutEdit, SIGNAL(valueChanged(int)), &settings, SLOT(setMinPlayersForMultiColumnLayout(int))); minPlayersForMultiColumnLayoutLabel.setBuddy(&minPlayersForMultiColumnLayoutEdit); - connect(&maxFontSizeForCardsEdit, SIGNAL(valueChanged(int)), &SettingsCache::instance(), SLOT(setMaxFontSize(int))); - maxFontSizeForCardsEdit.setValue(SettingsCache::instance().getMaxFontSize()); + connect(&maxFontSizeForCardsEdit, SIGNAL(valueChanged(int)), &settings, SLOT(setMaxFontSize(int))); + maxFontSizeForCardsEdit.setValue(settings.getMaxFontSize()); maxFontSizeForCardsLabel.setBuddy(&maxFontSizeForCardsEdit); maxFontSizeForCardsEdit.setMinimum(9); maxFontSizeForCardsEdit.setMaximum(100); @@ -413,6 +418,8 @@ void AppearanceSettingsPage::retranslateUi() cardsGroupBox->setTitle(tr("Card rendering")); displayCardNamesCheckBox.setText(tr("Display card names on cards having a picture")); cardScalingCheckBox.setText(tr("Scale cards on mouse over")); + verticalCardOverlapPercentLabel.setText( + tr("Minimum overlap percentage of cards on the stack and in vertical hand")); handGroupBox->setTitle(tr("Hand layout")); horizontalHandCheckBox.setText(tr("Display hand horizontally (wastes space)")); diff --git a/cockatrice/src/dlg_settings.h b/cockatrice/src/dlg_settings.h index d6dd1718..1856c5e8 100644 --- a/cockatrice/src/dlg_settings.h +++ b/cockatrice/src/dlg_settings.h @@ -90,6 +90,8 @@ private: QLabel maxFontSizeForCardsLabel; QCheckBox displayCardNamesCheckBox; QCheckBox cardScalingCheckBox; + QLabel verticalCardOverlapPercentLabel; + QSpinBox verticalCardOverlapPercentBox; QCheckBox horizontalHandCheckBox; QCheckBox leftJustifiedHandCheckBox; QCheckBox invertVerticalCoordinateCheckBox; diff --git a/cockatrice/src/handzone.cpp b/cockatrice/src/handzone.cpp index 57c8b48b..e7afb963 100644 --- a/cockatrice/src/handzone.cpp +++ b/cockatrice/src/handzone.cpp @@ -114,23 +114,18 @@ void HandZone::reorganizeCards() } } 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); + CardItem *card = 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->setRealZValue(i); + qreal y = + divideCardSpaceInZone(i, cardCount, boundingRect().height(), cards.at(0)->boundingRect().height()); + card->setPos(x, y); + card->setRealZValue(i); } } } diff --git a/cockatrice/src/player.cpp b/cockatrice/src/player.cpp index 13ef543e..1d0b6099 100644 --- a/cockatrice/src/player.cpp +++ b/cockatrice/src/player.cpp @@ -2567,7 +2567,7 @@ void Player::playCard(CardItem *card, bool faceDown, bool tapped) } else if (!faceDown && ((!playToStack && tableRow == 3) || ((playToStack && tableRow != 0) && currentZone != "stack"))) { cmd.set_target_zone("stack"); - cmd.set_x(0); + cmd.set_x(-1); cmd.set_y(0); } else { tableRow = faceDown ? 2 : info->getTableRow(); diff --git a/cockatrice/src/selectzone.cpp b/cockatrice/src/selectzone.cpp index 7250e6ca..7eba8bac 100644 --- a/cockatrice/src/selectzone.cpp +++ b/cockatrice/src/selectzone.cpp @@ -2,10 +2,36 @@ #include "carditem.h" #include "gamescene.h" +#include "settingscache.h" #include #include +qreal divideCardSpaceInZone(qreal index, int cardCount, qreal totalHeight, qreal cardHeight, bool reverse) +{ + qreal cardMinOverlap = cardHeight * SettingsCache::instance().getStackCardOverlapPercent() / 100; + qreal desiredHeight = cardHeight * cardCount - cardMinOverlap * (cardCount - 1); + qreal y; + if (desiredHeight > totalHeight) { + if (reverse) { + y = index / ((totalHeight - cardHeight) / (cardCount - 1)); + } else { + y = index * (totalHeight - cardHeight) / (cardCount - 1); + } + } else { + qreal start = (totalHeight - desiredHeight) / 2; + if (reverse) { + if (index <= start) { + return 0; + } + y = (index - start) / (cardHeight - cardMinOverlap); + } else { + y = index * (cardHeight - cardMinOverlap) + start; + } + } + return y; +} + SelectZone::SelectZone(Player *_player, const QString &_name, bool _hasCardAttr, diff --git a/cockatrice/src/selectzone.h b/cockatrice/src/selectzone.h index 2ac924dc..77f9eead 100644 --- a/cockatrice/src/selectzone.h +++ b/cockatrice/src/selectzone.h @@ -24,4 +24,6 @@ public: bool isView = false); }; +qreal divideCardSpaceInZone(qreal index, int cardCount, qreal totalHeight, qreal cardHeight, bool reverse = false); + #endif diff --git a/cockatrice/src/settingscache.cpp b/cockatrice/src/settingscache.cpp index f880b541..ca289fd0 100644 --- a/cockatrice/src/settingscache.cpp +++ b/cockatrice/src/settingscache.cpp @@ -262,6 +262,7 @@ SettingsCache::SettingsCache() ignoreUnregisteredUserMessages = settings->value("chat/ignore_unregistered_messages", false).toBool(); scaleCards = settings->value("cards/scaleCards", true).toBool(); + verticalCardOverlapPercent = settings->value("cards/verticalCardOverlapPercent", 33).toInt(); showMessagePopups = settings->value("chat/showmessagepopups", true).toBool(); showMentionPopups = settings->value("chat/showmentionpopups", true).toBool(); roomHistory = settings->value("chat/roomhistory", true).toBool(); @@ -332,6 +333,12 @@ void SettingsCache::setCardScaling(const int _scaleCards) settings->setValue("cards/scaleCards", scaleCards); } +void SettingsCache::setStackCardOverlapPercent(const int _verticalCardOverlapPercent) +{ + verticalCardOverlapPercent = _verticalCardOverlapPercent; + settings->setValue("cards/verticalCardOverlapPercent", verticalCardOverlapPercent); +} + void SettingsCache::setShowMessagePopups(const int _showMessagePopups) { showMessagePopups = (bool)_showMessagePopups; diff --git a/cockatrice/src/settingscache.h b/cockatrice/src/settingscache.h index 6f45a0a1..b9c4d3fb 100644 --- a/cockatrice/src/settingscache.h +++ b/cockatrice/src/settingscache.h @@ -115,6 +115,7 @@ private: int pixmapCacheSize; int networkCacheSize; bool scaleCards; + int verticalCardOverlapPercent; bool showMessagePopups; bool showMentionPopups; bool roomHistory; @@ -352,6 +353,10 @@ public: { return scaleCards; } + int getStackCardOverlapPercent() const + { + return verticalCardOverlapPercent; + } bool getShowMessagePopup() const { return showMessagePopups; @@ -541,6 +546,7 @@ public slots: void setPixmapCacheSize(const int _pixmapCacheSize); void setNetworkCacheSizeInMB(const int _networkCacheSize); void setCardScaling(const int _scaleCards); + void setStackCardOverlapPercent(const int _verticalCardOverlapPercent); void setShowMessagePopups(const int _showMessagePopups); void setShowMentionPopups(const int _showMentionPopups); void setRoomHistory(const int _roomHistory); diff --git a/cockatrice/src/stackzone.cpp b/cockatrice/src/stackzone.cpp index 648ed7bc..fb3664b9 100644 --- a/cockatrice/src/stackzone.cpp +++ b/cockatrice/src/stackzone.cpp @@ -58,23 +58,32 @@ void StackZone::paint(QPainter *painter, const QStyleOptionGraphicsItem * /*opti painter->fillRect(boundingRect(), brush); } -void StackZone::handleDropEvent(const QList &dragItems, - CardZone *startZone, - const QPoint & /*dropPoint*/) +void StackZone::handleDropEvent(const QList &dragItems, CardZone *startZone, const QPoint &dropPoint) { - if (startZone == this) - return; - Command_MoveCard cmd; cmd.set_start_player_id(startZone->getPlayer()->getId()); cmd.set_start_zone(startZone->getName().toStdString()); cmd.set_target_player_id(player->getId()); cmd.set_target_zone(getName().toStdString()); - cmd.set_x(0); + int index; + if (cards.isEmpty()) { + index = 0; + } else { + const int cardCount = cards.size(); + index = qRound(divideCardSpaceInZone(dropPoint.y(), cardCount, boundingRect().height(), + cards.at(0)->boundingRect().height(), true)); + } + if (startZone == this) { + if (cards.at(index)->getId() == dragItems.at(0)->getId()) { + return; + } + } + cmd.set_x(index); cmd.set_y(0); - for (int i = 0; i < dragItems.size(); ++i) - cmd.mutable_cards_to_move()->add_card()->set_card_id(dragItems[i]->getId()); + for (CardDragItem *item : dragItems) { + cmd.mutable_cards_to_move()->add_card()->set_card_id(item->getId()); + } player->sendGameCommand(cmd); } @@ -86,28 +95,23 @@ void StackZone::reorganizeCards() 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); + CardItem *card = 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->setRealZValue(i); + qreal y = + divideCardSpaceInZone(i, cardCount, boundingRect().height(), cards.at(0)->boundingRect().height()); + card->setPos(x, y); + card->setRealZValue(i); - for (ArrowItem *item : c->getArrowsFrom()) { + for (ArrowItem *item : card->getArrowsFrom()) { arrowsToUpdate.insert(item); } - for (ArrowItem *item : c->getArrowsTo()) { + for (ArrowItem *item : card->getArrowsTo()) { arrowsToUpdate.insert(item); } } diff --git a/dbconverter/src/mocks.cpp b/dbconverter/src/mocks.cpp index fbf65e15..199e9f4d 100644 --- a/dbconverter/src/mocks.cpp +++ b/dbconverter/src/mocks.cpp @@ -67,6 +67,9 @@ void SettingsCache::setLeftJustified(const int /* _leftJustified */) void SettingsCache::setCardScaling(const int /* _scaleCards */) { } +void SettingsCache::setStackCardOverlapPercent(const int /* _verticalCardOverlapPercent */) +{ +} void SettingsCache::setShowMessagePopups(const int /* _showMessagePopups */) { } diff --git a/tests/carddatabase/mocks.cpp b/tests/carddatabase/mocks.cpp index 5fc6104f..fddee9b8 100644 --- a/tests/carddatabase/mocks.cpp +++ b/tests/carddatabase/mocks.cpp @@ -71,6 +71,9 @@ void SettingsCache::setLeftJustified(const int /* _leftJustified */) void SettingsCache::setCardScaling(const int /* _scaleCards */) { } +void SettingsCache::setStackCardOverlapPercent(const int /* _verticalCardOverlapPercent */) +{ +} void SettingsCache::setShowMessagePopups(const int /* _showMessagePopups */) { }