mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-11-05 09:33:25 -08:00
* [Fonts] Restore DeckList Serif default and live-update all role readers * [Fonts] Keep the DeckList fallback on the application font DeckList is read by the deck editor headers, the filter tree and the deck view too, not only by the two surfaces that hardcoded Serif. Resolving the unset role to Serif in appFont() made every user without a fonts.toml see Serif outside the deck list. - appFont(DeckList) falls back to the application font again. - ThemeManager::deckListFont() resolves the role and keeps the Serif fallback for the two historical sites: the deck view zone headers and the printed deck list. - DeckView no longer repaints its viewport on fontsChanged; touching the scene items already schedules the repaint in every attached view. --------- Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
616 lines
20 KiB
C++
616 lines
20 KiB
C++
#include "deck_view.h"
|
|
|
|
#include "../../client/settings/cache_settings.h"
|
|
#include "../../interface/theme_manager.h"
|
|
#include "../board/abstract_card_drag_item.h"
|
|
#include "../card_dimensions.h"
|
|
#include "libcockatrice/card/printing/exact_card.h"
|
|
#include "libcockatrice/deck_list/tree/deck_list_card_node.h"
|
|
#include "libcockatrice/deck_list/tree/inner_deck_list_node.h"
|
|
#include "libcockatrice/protocol/pb/move_card_to_zone.pb.h"
|
|
|
|
#include <QApplication>
|
|
#include <QBrush>
|
|
#include <QColor>
|
|
#include <QCursor>
|
|
#include <QFlags>
|
|
#include <QFont>
|
|
#include <QFontMetrics>
|
|
#include <QGraphicsSceneHoverEvent>
|
|
#include <QGraphicsSceneMouseEvent>
|
|
#include <QMapIterator>
|
|
#include <QMouseEvent>
|
|
#include <QPainter>
|
|
#include <QPen>
|
|
#include <QPoint>
|
|
#include <QSet>
|
|
#include <QSharedPointer>
|
|
#include <QSize>
|
|
#include <QStringList>
|
|
#include <QtGlobal>
|
|
#include <QtMath>
|
|
#include <algorithm>
|
|
#include <compare>
|
|
#include <libcockatrice/card/card_info.h>
|
|
#include <libcockatrice/deck_list/deck_list.h>
|
|
#include <libcockatrice/settings/cards_display_settings.h>
|
|
#include <libcockatrice/utility/card_ref.h>
|
|
#include <qnamespace.h>
|
|
#include <string>
|
|
#include <utility>
|
|
|
|
class QObject;
|
|
class QRectF;
|
|
class QWidget;
|
|
struct CardRef;
|
|
|
|
DeckViewCardDragItem::DeckViewCardDragItem(DeckViewCard *_item,
|
|
const QPointF &_hotSpot,
|
|
AbstractCardDragItem *parentDrag)
|
|
: AbstractCardDragItem(_item, _hotSpot, parentDrag), currentZone(0)
|
|
{
|
|
}
|
|
|
|
void DeckViewCardDragItem::updatePosition(const QPointF &cursorScenePos)
|
|
{
|
|
QList<QGraphicsItem *> colliding = scene()->items(cursorScenePos);
|
|
|
|
DeckViewCardContainer *cursorZone = 0;
|
|
for (int i = colliding.size() - 1; i >= 0; i--) {
|
|
if ((cursorZone = qgraphicsitem_cast<DeckViewCardContainer *>(colliding.at(i)))) {
|
|
break;
|
|
}
|
|
}
|
|
if (!cursorZone) {
|
|
return;
|
|
}
|
|
currentZone = cursorZone;
|
|
|
|
QPointF newPos = cursorScenePos;
|
|
if (newPos != pos()) {
|
|
for (int i = 0; i < childDrags.size(); i++) {
|
|
childDrags[i]->setPos(newPos + childDrags[i]->getHotSpot());
|
|
}
|
|
setPos(newPos);
|
|
}
|
|
}
|
|
|
|
void DeckViewCardDragItem::handleDrop(DeckViewCardContainer *target)
|
|
{
|
|
auto *card = static_cast<DeckViewCard *>(item.data());
|
|
auto *start = static_cast<DeckViewCardContainer *>(item->parentItem());
|
|
start->removeCard(card);
|
|
target->addCard(card);
|
|
card->setParentItem(target);
|
|
}
|
|
|
|
void DeckViewCardDragItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
|
{
|
|
setCursor(Qt::OpenHandCursor);
|
|
auto *sc = static_cast<DeckViewScene *>(scene());
|
|
sc->removeItem(this);
|
|
|
|
if (currentZone) {
|
|
handleDrop(currentZone);
|
|
for (int i = 0; i < childDrags.size(); i++) {
|
|
auto *c = static_cast<DeckViewCardDragItem *>(childDrags[i]);
|
|
c->handleDrop(currentZone);
|
|
sc->removeItem(c);
|
|
}
|
|
|
|
sc->updateContents();
|
|
}
|
|
|
|
event->accept();
|
|
}
|
|
|
|
DeckViewCard::DeckViewCard(QGraphicsItem *parent, const CardRef &cardRef, const QString &_originZone)
|
|
: AbstractCardItem(parent, cardRef, 0, -1), originZone(_originZone), dragItem(0)
|
|
{
|
|
setAcceptHoverEvents(true);
|
|
|
|
connect(&SettingsCache::instance().cardsDisplay(), &CardsDisplaySettings::roundCardCornersChanged, this,
|
|
[this](bool _roundCardCorners) {
|
|
Q_UNUSED(_roundCardCorners);
|
|
|
|
update();
|
|
});
|
|
}
|
|
|
|
DeckViewCard::~DeckViewCard()
|
|
{
|
|
delete dragItem;
|
|
}
|
|
|
|
void DeckViewCard::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
|
|
{
|
|
AbstractCardItem::paint(painter, option, widget);
|
|
|
|
painter->save();
|
|
QPen pen;
|
|
pen.setWidth(3);
|
|
pen.setJoinStyle(Qt::MiterJoin);
|
|
pen.setColor(originZone == DECK_ZONE_MAIN ? Qt::green : Qt::red);
|
|
painter->setPen(pen);
|
|
qreal cardRadius =
|
|
SettingsCache::instance().cardsDisplay().getRoundCardCorners() ? 0.05 * (CardDimensions::WIDTH_F - 3) : 0.0;
|
|
painter->drawRoundedRect(QRectF(1.5, 1.5, CardDimensions::WIDTH_F - 3, CardDimensions::HEIGHT_F - 3), cardRadius,
|
|
cardRadius);
|
|
painter->restore();
|
|
}
|
|
|
|
void DeckViewCard::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
|
{
|
|
if ((event->screenPos() - event->buttonDownScreenPos(Qt::LeftButton)).manhattanLength() <
|
|
2 * QApplication::startDragDistance()) {
|
|
return;
|
|
}
|
|
|
|
if (static_cast<DeckViewScene *>(scene())->getLocked()) {
|
|
return;
|
|
}
|
|
|
|
delete dragItem;
|
|
dragItem = new DeckViewCardDragItem(this, event->pos());
|
|
scene()->addItem(dragItem);
|
|
dragItem->updatePosition(event->scenePos());
|
|
dragItem->grabMouse();
|
|
|
|
QList<QGraphicsItem *> sel = scene()->selectedItems();
|
|
int j = 0;
|
|
for (int i = 0; i < sel.size(); i++) {
|
|
auto *c = static_cast<DeckViewCard *>(sel.at(i));
|
|
if (c == this) {
|
|
continue;
|
|
}
|
|
++j;
|
|
auto childPos = QPointF(j * CardDimensions::WIDTH_HALF_F, 0);
|
|
auto *drag = new DeckViewCardDragItem(c, childPos, dragItem);
|
|
drag->setPos(dragItem->pos() + childPos);
|
|
scene()->addItem(drag);
|
|
}
|
|
setCursor(Qt::OpenHandCursor);
|
|
}
|
|
|
|
void DeckView::mouseDoubleClickEvent(QMouseEvent *event)
|
|
{
|
|
if (static_cast<DeckViewScene *>(scene())->getLocked()) {
|
|
return;
|
|
}
|
|
|
|
if (event->button() == Qt::LeftButton) {
|
|
QList<MoveCard_ToZone> result;
|
|
QList<QGraphicsItem *> sel = scene()->selectedItems();
|
|
|
|
// The double-click goes to the view, not the card, so cancel any pending
|
|
// selection collapse on the cards before reading the selection.
|
|
for (auto *item : sel) {
|
|
if (auto *c = dynamic_cast<DeckViewCard *>(item)) {
|
|
c->cancelPendingSelectionCollapse();
|
|
}
|
|
}
|
|
sel = scene()->selectedItems();
|
|
|
|
for (int i = 0; i < sel.size(); i++) {
|
|
auto *c = static_cast<DeckViewCard *>(sel.at(i));
|
|
auto *zone = static_cast<DeckViewCardContainer *>(c->parentItem());
|
|
MoveCard_ToZone m;
|
|
m.set_card_name(c->getName().toStdString());
|
|
m.set_start_zone(zone->getName().toStdString());
|
|
|
|
if (zone->getName() == DECK_ZONE_MAIN) {
|
|
m.set_target_zone(DECK_ZONE_SIDE);
|
|
} else if (zone->getName() == DECK_ZONE_SIDE) {
|
|
m.set_target_zone(DECK_ZONE_MAIN);
|
|
} else { // Trying to move from another zone
|
|
m.set_target_zone(zone->getName().toStdString());
|
|
}
|
|
|
|
result.append(m);
|
|
}
|
|
|
|
deckViewScene->applySideboardPlan(result);
|
|
deckViewScene->rearrangeItems();
|
|
emit deckViewScene->sideboardPlanChanged();
|
|
}
|
|
}
|
|
|
|
void DeckViewCard::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
|
|
{
|
|
event->accept();
|
|
processHoverEvent();
|
|
}
|
|
|
|
DeckViewCardContainer::DeckViewCardContainer(const QString &_name) : QGraphicsItem(), name(_name), width(0), height(0)
|
|
{
|
|
setCacheMode(DeviceCoordinateCache);
|
|
}
|
|
|
|
QRectF DeckViewCardContainer::boundingRect() const
|
|
{
|
|
return QRectF(0, 0, width, height);
|
|
}
|
|
|
|
void DeckViewCardContainer::paint(QPainter *painter, const QStyleOptionGraphicsItem * /*option*/, QWidget * /*widget*/)
|
|
{
|
|
qreal totalTextWidth = getCardTypeTextWidth();
|
|
|
|
painter->fillRect(boundingRect(), themeManager->getBgBrush(ThemeManager::Table));
|
|
painter->setPen(QColor(255, 255, 255, 100));
|
|
painter->drawLine(QPointF(0, separatorY), QPointF(width, separatorY));
|
|
|
|
painter->setPen(QColor(Qt::white));
|
|
// Family comes from the DeckList theme role; pixel sizes/weights unchanged.
|
|
QFont f = themeManager->deckListFont();
|
|
f.setPixelSize(24);
|
|
f.setWeight(QFont::Bold);
|
|
painter->setFont(f);
|
|
painter->drawText(10, 0, width - 20, separatorY, Qt::AlignLeft | Qt::AlignVCenter | Qt::TextSingleLine,
|
|
InnerDecklistNode::visibleNameFromName(name) + QString(": %1").arg(cards.size()));
|
|
|
|
f.setPixelSize(16);
|
|
painter->setFont(f);
|
|
QList<QString> cardTypeList = cardsByType.uniqueKeys();
|
|
qreal yUntilNow = separatorY + paddingY;
|
|
for (int i = 0; i < cardTypeList.size(); ++i) {
|
|
if (i != 0) {
|
|
painter->setPen(QColor(255, 255, 255, 100));
|
|
painter->drawLine(QPointF(0, yUntilNow - paddingY / 2), QPointF(width, yUntilNow - paddingY / 2));
|
|
}
|
|
qreal thisRowHeight = CardDimensions::HEIGHT_F * currentRowsAndCols[i].first;
|
|
QRectF textRect(0, yUntilNow, totalTextWidth, thisRowHeight);
|
|
yUntilNow += thisRowHeight + paddingY;
|
|
|
|
QString displayString = QString("%1\n(%2)").arg(cardTypeList[i]).arg(cardsByType.count(cardTypeList[i]));
|
|
|
|
painter->setPen(Qt::white);
|
|
painter->drawText(textRect, Qt::AlignHCenter | Qt::AlignVCenter, displayString);
|
|
}
|
|
}
|
|
|
|
void DeckViewCardContainer::addCard(DeckViewCard *card)
|
|
{
|
|
cards.append(card);
|
|
cardsByType.insert(card->getCard().isEmpty() ? "" : card->getCardInfo().getMainCardType(), card);
|
|
}
|
|
|
|
void DeckViewCardContainer::removeCard(DeckViewCard *card)
|
|
{
|
|
cards.removeOne(card);
|
|
cardsByType.remove(card->getCard().isEmpty() ? "" : card->getCardInfo().getMainCardType(), card);
|
|
}
|
|
|
|
QList<QPair<int, int>> DeckViewCardContainer::getRowsAndCols() const
|
|
{
|
|
QList<QPair<int, int>> result;
|
|
QList<QString> cardTypeList = cardsByType.uniqueKeys();
|
|
for (int i = 0; i < cardTypeList.size(); ++i) {
|
|
result.append(QPair<int, int>(1, cardsByType.count(cardTypeList[i])));
|
|
}
|
|
return result;
|
|
}
|
|
|
|
int DeckViewCardContainer::getCardTypeTextWidth() const
|
|
{
|
|
// Family comes from the DeckList theme role; pixel size/weight unchanged.
|
|
QFont f = themeManager->deckListFont();
|
|
f.setPixelSize(16);
|
|
f.setWeight(QFont::Bold);
|
|
QFontMetrics fm(f);
|
|
|
|
int maxCardTypeWidth = 0;
|
|
for (const auto &key : cardsByType.keys()) {
|
|
int cardTypeWidth = fm.size(Qt::TextSingleLine, key).width();
|
|
maxCardTypeWidth = qMax(maxCardTypeWidth, cardTypeWidth);
|
|
}
|
|
|
|
return maxCardTypeWidth + 15;
|
|
}
|
|
|
|
QSizeF DeckViewCardContainer::calculateBoundingRect(const QList<QPair<int, int>> &rowsAndCols) const
|
|
{
|
|
qreal totalHeight = 0;
|
|
qreal totalWidth = 0;
|
|
|
|
// Calculate space needed for cards
|
|
for (int i = 0; i < rowsAndCols.size(); ++i) {
|
|
totalHeight += CardDimensions::HEIGHT_F * rowsAndCols[i].first + paddingY;
|
|
if (CardDimensions::WIDTH_F * rowsAndCols[i].second > totalWidth) {
|
|
totalWidth = CardDimensions::WIDTH_F * rowsAndCols[i].second;
|
|
}
|
|
}
|
|
|
|
return QSizeF(getCardTypeTextWidth() + totalWidth, totalHeight + separatorY + paddingY);
|
|
}
|
|
|
|
bool DeckViewCardContainer::sortCardsByName(DeckViewCard *c1, DeckViewCard *c2)
|
|
{
|
|
if (c1 && c2) {
|
|
return c1->getName() < c2->getName();
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void DeckViewCardContainer::rearrangeItems(const QList<QPair<int, int>> &rowsAndCols)
|
|
{
|
|
currentRowsAndCols = rowsAndCols;
|
|
|
|
qreal yUntilNow = separatorY + paddingY;
|
|
qreal x = (qreal)getCardTypeTextWidth();
|
|
for (int i = 0; i < rowsAndCols.size(); ++i) {
|
|
const int tempRows = rowsAndCols[i].first;
|
|
const int tempCols = rowsAndCols[i].second;
|
|
QList<QString> cardTypeList = cardsByType.uniqueKeys();
|
|
QList<DeckViewCard *> row = cardsByType.values(cardTypeList[i]);
|
|
std::sort(row.begin(), row.end(), DeckViewCardContainer::sortCardsByName);
|
|
for (int j = 0; j < row.size(); ++j) {
|
|
DeckViewCard *card = row[j];
|
|
card->setPos(x + (j % tempCols) * CardDimensions::WIDTH_F,
|
|
yUntilNow + (j / tempCols) * CardDimensions::HEIGHT_F);
|
|
}
|
|
yUntilNow += tempRows * CardDimensions::HEIGHT_F + paddingY;
|
|
}
|
|
|
|
prepareGeometryChange();
|
|
QSizeF bRect = calculateBoundingRect(rowsAndCols);
|
|
width = bRect.width();
|
|
height = bRect.height();
|
|
}
|
|
|
|
void DeckViewCardContainer::setWidth(qreal _width)
|
|
{
|
|
prepareGeometryChange();
|
|
width = _width;
|
|
update();
|
|
}
|
|
|
|
DeckViewScene::DeckViewScene(QObject *parent) : QGraphicsScene(parent), locked(true), deck(0), optimalAspectRatio(1.0)
|
|
{
|
|
// Zone headers read the DeckList role at paint time and cache their
|
|
// rendering, so touch every item to invalidate the caches and pick up the
|
|
// new family on font changes (containers cannot connect this themselves:
|
|
// QGraphicsItem is not a QObject).
|
|
connect(themeManager, &ThemeManager::fontsChanged, this, [this] {
|
|
for (auto *item : items()) {
|
|
item->update();
|
|
}
|
|
});
|
|
}
|
|
|
|
DeckViewScene::~DeckViewScene()
|
|
{
|
|
clearContents();
|
|
delete deck;
|
|
}
|
|
|
|
void DeckViewScene::clearContents()
|
|
{
|
|
QMapIterator<QString, DeckViewCardContainer *> i(cardContainers);
|
|
while (i.hasNext()) {
|
|
delete i.next().value();
|
|
}
|
|
cardContainers.clear();
|
|
}
|
|
|
|
void DeckViewScene::setDeck(const DeckList &_deck)
|
|
{
|
|
if (deck) {
|
|
delete deck;
|
|
}
|
|
|
|
deck = new DeckList(_deck.writeToString_Native());
|
|
rebuildTree();
|
|
applySideboardPlan(deck->getCurrentSideboardPlan());
|
|
rearrangeItems();
|
|
}
|
|
|
|
void DeckViewScene::rebuildTree()
|
|
{
|
|
clearContents();
|
|
|
|
if (!deck) {
|
|
return;
|
|
}
|
|
|
|
QStringList requiredZones = {DECK_ZONE_MAIN, DECK_ZONE_SIDE};
|
|
|
|
for (const QString &zoneName : requiredZones) {
|
|
if (!cardContainers.contains(zoneName)) {
|
|
auto *container = new DeckViewCardContainer(zoneName);
|
|
cardContainers.insert(zoneName, container);
|
|
addItem(container);
|
|
}
|
|
}
|
|
|
|
for (auto *currentZone : deck->getZoneNodes()) {
|
|
DeckViewCardContainer *container = cardContainers.value(currentZone->getName(), 0);
|
|
if (!container) {
|
|
container = new DeckViewCardContainer(currentZone->getName());
|
|
cardContainers.insert(currentZone->getName(), container);
|
|
addItem(container);
|
|
}
|
|
|
|
// Cards in custom zones nested under a board are regular board cards in-game.
|
|
// They are collected recursively (like every other consumer) and reported with
|
|
// the top-level board zone as their origin, so that sideboard plans keep working.
|
|
for (auto *currentCard : deck->getCardNodes({currentZone->getName()})) {
|
|
for (int k = 0; k < currentCard->getNumber(); ++k) {
|
|
auto *newCard = new DeckViewCard(container, currentCard->toCardRef(), currentZone->getName());
|
|
container->addCard(newCard);
|
|
emit newCardAdded(newCard);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void DeckViewScene::applySideboardPlan(const QList<MoveCard_ToZone> &plan)
|
|
{
|
|
for (int i = 0; i < plan.size(); ++i) {
|
|
const MoveCard_ToZone &m = plan[i];
|
|
DeckViewCardContainer *start = cardContainers.value(QString::fromStdString(m.start_zone()));
|
|
DeckViewCardContainer *target = cardContainers.value(QString::fromStdString(m.target_zone()));
|
|
if (!start || !target) {
|
|
continue;
|
|
}
|
|
|
|
DeckViewCard *card = 0;
|
|
const QList<DeckViewCard *> &cardList = start->getCards();
|
|
for (int j = 0; j < cardList.size(); ++j) {
|
|
if (cardList[j]->getName() == QString::fromStdString(m.card_name())) {
|
|
card = cardList[j];
|
|
break;
|
|
}
|
|
}
|
|
if (!card) {
|
|
continue;
|
|
}
|
|
|
|
start->removeCard(card);
|
|
target->addCard(card);
|
|
card->setParentItem(target);
|
|
}
|
|
}
|
|
|
|
void DeckViewScene::rearrangeItems()
|
|
{
|
|
const int spacing = CardDimensions::HEIGHT / 3;
|
|
QList<DeckViewCardContainer *> contList = cardContainers.values();
|
|
|
|
// Initialize space requirements
|
|
QList<QList<QPair<int, int>>> rowsAndColsList;
|
|
QList<QList<int>> cardCountList;
|
|
for (int i = 0; i < contList.size(); ++i) {
|
|
QList<QPair<int, int>> rowsAndCols = contList[i]->getRowsAndCols();
|
|
rowsAndColsList.append(rowsAndCols);
|
|
|
|
cardCountList.append(QList<int>());
|
|
for (int j = 0; j < rowsAndCols.size(); ++j) {
|
|
cardCountList[i].append(rowsAndCols[j].second);
|
|
}
|
|
}
|
|
|
|
qreal totalHeight, totalWidth;
|
|
for (;;) {
|
|
// Calculate total size before this iteration
|
|
totalHeight = -spacing;
|
|
totalWidth = 0;
|
|
for (int i = 0; i < contList.size(); ++i) {
|
|
QSizeF contSize = contList[i]->calculateBoundingRect(rowsAndColsList[i]);
|
|
totalHeight += contSize.height() + spacing;
|
|
if (contSize.width() > totalWidth) {
|
|
totalWidth = contSize.width();
|
|
}
|
|
}
|
|
|
|
// We're done when the aspect ratio shifts from too high to too low.
|
|
if (totalWidth / totalHeight <= optimalAspectRatio) {
|
|
break;
|
|
}
|
|
|
|
// Find category with highest column count
|
|
int maxIndex1 = -1, maxIndex2 = -1, maxCols = 0;
|
|
for (int i = 0; i < rowsAndColsList.size(); ++i) {
|
|
for (int j = 0; j < rowsAndColsList[i].size(); ++j) {
|
|
if (rowsAndColsList[i][j].second > maxCols) {
|
|
maxIndex1 = i;
|
|
maxIndex2 = j;
|
|
maxCols = rowsAndColsList[i][j].second;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Add row to category
|
|
const int maxRows = rowsAndColsList[maxIndex1][maxIndex2].first;
|
|
const int maxCardCount = cardCountList[maxIndex1][maxIndex2];
|
|
rowsAndColsList[maxIndex1][maxIndex2] =
|
|
QPair<int, int>(maxRows + 1, (int)qCeil((qreal)maxCardCount / (qreal)(maxRows + 1)));
|
|
}
|
|
|
|
totalHeight = -spacing;
|
|
for (int i = 0; i < contList.size(); ++i) {
|
|
DeckViewCardContainer *c = contList[i];
|
|
c->rearrangeItems(rowsAndColsList[i]);
|
|
c->setPos(0, totalHeight + spacing);
|
|
totalHeight += c->boundingRect().height() + spacing;
|
|
}
|
|
|
|
totalWidth = totalHeight * optimalAspectRatio;
|
|
for (int i = 0; i < contList.size(); ++i) {
|
|
contList[i]->setWidth(totalWidth);
|
|
}
|
|
|
|
setSceneRect(QRectF(0, 0, totalWidth, totalHeight));
|
|
}
|
|
|
|
void DeckViewScene::updateContents()
|
|
{
|
|
rearrangeItems();
|
|
emit sideboardPlanChanged();
|
|
}
|
|
|
|
QList<MoveCard_ToZone> DeckViewScene::getSideboardPlan() const
|
|
{
|
|
QList<MoveCard_ToZone> result;
|
|
QMapIterator<QString, DeckViewCardContainer *> containerIterator(cardContainers);
|
|
while (containerIterator.hasNext()) {
|
|
DeckViewCardContainer *cont = containerIterator.next().value();
|
|
const QList<DeckViewCard *> cardList = cont->getCards();
|
|
for (int i = 0; i < cardList.size(); ++i) {
|
|
if (cardList[i]->getOriginZone() != cont->getName()) {
|
|
MoveCard_ToZone m;
|
|
m.set_card_name(cardList[i]->getName().toStdString());
|
|
m.set_start_zone(cardList[i]->getOriginZone().toStdString());
|
|
m.set_target_zone(cont->getName().toStdString());
|
|
result.append(m);
|
|
}
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
void DeckViewScene::resetSideboardPlan()
|
|
{
|
|
rebuildTree();
|
|
rearrangeItems();
|
|
}
|
|
|
|
DeckView::DeckView(QWidget *parent) : QGraphicsView(parent)
|
|
{
|
|
deckViewScene = new DeckViewScene(this);
|
|
|
|
setBackgroundBrush(QBrush(QColor(0, 0, 0)));
|
|
setDragMode(RubberBandDrag);
|
|
setRenderHints(QPainter::TextAntialiasing | QPainter::Antialiasing /* | QPainter::SmoothPixmapTransform*/);
|
|
setScene(deckViewScene);
|
|
|
|
connect(deckViewScene, &DeckViewScene::sceneRectChanged, this, &DeckView::updateSceneRect);
|
|
connect(deckViewScene, &DeckViewScene::newCardAdded, this, &DeckView::newCardAdded);
|
|
connect(deckViewScene, &DeckViewScene::sideboardPlanChanged, this, &DeckView::sideboardPlanChanged);
|
|
}
|
|
|
|
void DeckView::resizeEvent(QResizeEvent *event)
|
|
{
|
|
QGraphicsView::resizeEvent(event);
|
|
deckViewScene->setOptimalAspectRatio((qreal)width() / (qreal)height());
|
|
deckViewScene->rearrangeItems();
|
|
}
|
|
|
|
void DeckView::updateSceneRect(const QRectF &rect)
|
|
{
|
|
fitInView(rect, Qt::KeepAspectRatio);
|
|
}
|
|
|
|
void DeckView::setDeck(const DeckList &_deck)
|
|
{
|
|
deckViewScene->setDeck(_deck);
|
|
}
|
|
|
|
void DeckView::clearDeck()
|
|
{
|
|
deckViewScene->clearContents();
|
|
}
|
|
|
|
void DeckView::resetSideboardPlan()
|
|
{
|
|
deckViewScene->resetSideboardPlan();
|
|
}
|