mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-07-02 19:43:55 -07:00
refactor DeckViewContainer into own file (#5455)
* cut-and-paste * remove some includes * move refreshShortcuts * move deck_view into src/game/deckview * move deck_view_container to src/game/deckview * fix build failure
This commit is contained in:
parent
9df71fe1e8
commit
686645c1e4
7 changed files with 495 additions and 467 deletions
523
cockatrice/src/game/deckview/deck_view.cpp
Normal file
523
cockatrice/src/game/deckview/deck_view.cpp
Normal file
|
|
@ -0,0 +1,523 @@
|
|||
#include "deck_view.h"
|
||||
|
||||
#include "../../client/ui/theme_manager.h"
|
||||
#include "../../game/cards/card_database.h"
|
||||
#include "../../settings/cache_settings.h"
|
||||
#include "decklist.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QGraphicsSceneMouseEvent>
|
||||
#include <QMouseEvent>
|
||||
#include <QtMath>
|
||||
#include <algorithm>
|
||||
|
||||
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)
|
||||
{
|
||||
DeckViewCard *card = static_cast<DeckViewCard *>(item);
|
||||
DeckViewCardContainer *start = static_cast<DeckViewCardContainer *>(item->parentItem());
|
||||
start->removeCard(card);
|
||||
target->addCard(card);
|
||||
card->setParentItem(target);
|
||||
}
|
||||
|
||||
void DeckViewCardDragItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
setCursor(Qt::OpenHandCursor);
|
||||
DeckViewScene *sc = static_cast<DeckViewScene *>(scene());
|
||||
sc->removeItem(this);
|
||||
|
||||
if (currentZone) {
|
||||
handleDrop(currentZone);
|
||||
for (int i = 0; i < childDrags.size(); i++) {
|
||||
DeckViewCardDragItem *c = static_cast<DeckViewCardDragItem *>(childDrags[i]);
|
||||
c->handleDrop(currentZone);
|
||||
sc->removeItem(c);
|
||||
}
|
||||
|
||||
sc->updateContents();
|
||||
}
|
||||
|
||||
event->accept();
|
||||
}
|
||||
|
||||
DeckViewCard::DeckViewCard(QGraphicsItem *parent,
|
||||
const QString &_name,
|
||||
const QString &_providerId,
|
||||
const QString &_originZone)
|
||||
: AbstractCardItem(parent, _name, _providerId, 0, -1), originZone(_originZone), dragItem(0)
|
||||
{
|
||||
setAcceptHoverEvents(true);
|
||||
}
|
||||
|
||||
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 = 0.05 * (CARD_WIDTH - 3);
|
||||
painter->drawRoundedRect(QRectF(1.5, 1.5, CARD_WIDTH - 3., CARD_HEIGHT - 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++) {
|
||||
DeckViewCard *c = static_cast<DeckViewCard *>(sel.at(i));
|
||||
if (c == this)
|
||||
continue;
|
||||
++j;
|
||||
QPointF childPos = QPointF(j * CARD_WIDTH / 2, 0);
|
||||
DeckViewCardDragItem *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();
|
||||
|
||||
for (int i = 0; i < sel.size(); i++) {
|
||||
DeckViewCard *c = static_cast<DeckViewCard *>(sel.at(i));
|
||||
DeckViewCardContainer *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->getTableBgBrush());
|
||||
painter->setPen(QColor(255, 255, 255, 100));
|
||||
painter->drawLine(QPointF(0, separatorY), QPointF(width, separatorY));
|
||||
|
||||
painter->setPen(QColor(Qt::white));
|
||||
QFont f("Serif");
|
||||
f.setStyleHint(QFont::Serif);
|
||||
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 = CARD_HEIGHT * 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->getInfo() ? card->getInfo()->getMainCardType() : "", card);
|
||||
}
|
||||
|
||||
void DeckViewCardContainer::removeCard(DeckViewCard *card)
|
||||
{
|
||||
cards.removeOne(card);
|
||||
cardsByType.remove(card->getInfo() ? card->getInfo()->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
|
||||
{
|
||||
QFont f("Serif");
|
||||
f.setStyleHint(QFont::Serif);
|
||||
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 += CARD_HEIGHT * rowsAndCols[i].first + paddingY;
|
||||
if (CARD_WIDTH * rowsAndCols[i].second > totalWidth)
|
||||
totalWidth = CARD_WIDTH * 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) * CARD_WIDTH, yUntilNow + (j / tempCols) * CARD_HEIGHT);
|
||||
}
|
||||
yUntilNow += tempRows * CARD_HEIGHT + 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)
|
||||
{
|
||||
}
|
||||
|
||||
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);
|
||||
rebuildTree();
|
||||
applySideboardPlan(deck->getCurrentSideboardPlan());
|
||||
rearrangeItems();
|
||||
}
|
||||
|
||||
void DeckViewScene::rebuildTree()
|
||||
{
|
||||
clearContents();
|
||||
|
||||
if (!deck)
|
||||
return;
|
||||
|
||||
InnerDecklistNode *listRoot = deck->getRoot();
|
||||
for (int i = 0; i < listRoot->size(); i++) {
|
||||
InnerDecklistNode *currentZone = dynamic_cast<InnerDecklistNode *>(listRoot->at(i));
|
||||
|
||||
DeckViewCardContainer *container = cardContainers.value(currentZone->getName(), 0);
|
||||
if (!container) {
|
||||
container = new DeckViewCardContainer(currentZone->getName());
|
||||
cardContainers.insert(currentZone->getName(), container);
|
||||
addItem(container);
|
||||
}
|
||||
|
||||
for (int j = 0; j < currentZone->size(); j++) {
|
||||
DecklistCardNode *currentCard = dynamic_cast<DecklistCardNode *>(currentZone->at(j));
|
||||
if (!currentCard)
|
||||
continue;
|
||||
|
||||
for (int k = 0; k < currentCard->getNumber(); ++k) {
|
||||
DeckViewCard *newCard = new DeckViewCard(container, currentCard->getName(),
|
||||
currentCard->getCardProviderId(), 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 = CARD_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::resetSideboardPlan()
|
||||
{
|
||||
deckViewScene->resetSideboardPlan();
|
||||
}
|
||||
167
cockatrice/src/game/deckview/deck_view.h
Normal file
167
cockatrice/src/game/deckview/deck_view.h
Normal file
|
|
@ -0,0 +1,167 @@
|
|||
#ifndef DECKVIEW_H
|
||||
#define DECKVIEW_H
|
||||
|
||||
#include "../../game/cards/abstract_card_drag_item.h"
|
||||
#include "pb/move_card_to_zone.pb.h"
|
||||
|
||||
#include <QGraphicsScene>
|
||||
#include <QGraphicsView>
|
||||
#include <QMap>
|
||||
#include <QMultiMap>
|
||||
#include <QPixmap>
|
||||
|
||||
class DeckList;
|
||||
class InnerDecklistNode;
|
||||
class CardInfo;
|
||||
class DeckViewCardContainer;
|
||||
class DeckViewCardDragItem;
|
||||
class MoveCardToZone;
|
||||
|
||||
class DeckViewCard : public AbstractCardItem
|
||||
{
|
||||
private:
|
||||
QString originZone;
|
||||
DeckViewCardDragItem *dragItem;
|
||||
|
||||
public:
|
||||
DeckViewCard(QGraphicsItem *parent = nullptr,
|
||||
const QString &_name = QString(),
|
||||
const QString &_providerId = QString(),
|
||||
const QString &_originZone = QString());
|
||||
~DeckViewCard();
|
||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
|
||||
const QString &getOriginZone() const
|
||||
{
|
||||
return originZone;
|
||||
}
|
||||
|
||||
protected:
|
||||
void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
|
||||
void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
|
||||
};
|
||||
|
||||
class DeckViewCardDragItem : public AbstractCardDragItem
|
||||
{
|
||||
private:
|
||||
DeckViewCardContainer *currentZone;
|
||||
void handleDrop(DeckViewCardContainer *target);
|
||||
|
||||
public:
|
||||
DeckViewCardDragItem(DeckViewCard *_item, const QPointF &_hotSpot, AbstractCardDragItem *parentDrag = 0);
|
||||
void updatePosition(const QPointF &cursorScenePos);
|
||||
|
||||
protected:
|
||||
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
|
||||
};
|
||||
|
||||
class DeckViewCardContainer : public QGraphicsItem
|
||||
{
|
||||
private:
|
||||
static const int separatorY = 20;
|
||||
static const int paddingY = 10;
|
||||
static bool sortCardsByName(DeckViewCard *c1, DeckViewCard *c2);
|
||||
|
||||
QString name;
|
||||
QList<DeckViewCard *> cards;
|
||||
QMultiMap<QString, DeckViewCard *> cardsByType;
|
||||
QList<QPair<int, int>> currentRowsAndCols;
|
||||
qreal width, height;
|
||||
int getCardTypeTextWidth() const;
|
||||
|
||||
public:
|
||||
enum
|
||||
{
|
||||
Type = typeDeckViewCardContainer
|
||||
};
|
||||
int type() const
|
||||
{
|
||||
return Type;
|
||||
}
|
||||
DeckViewCardContainer(const QString &_name);
|
||||
QRectF boundingRect() const;
|
||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
|
||||
void addCard(DeckViewCard *card);
|
||||
void removeCard(DeckViewCard *card);
|
||||
const QList<DeckViewCard *> &getCards() const
|
||||
{
|
||||
return cards;
|
||||
}
|
||||
const QString &getName() const
|
||||
{
|
||||
return name;
|
||||
}
|
||||
void setWidth(qreal _width);
|
||||
|
||||
QList<QPair<int, int>> getRowsAndCols() const;
|
||||
QSizeF calculateBoundingRect(const QList<QPair<int, int>> &rowsAndCols) const;
|
||||
void rearrangeItems(const QList<QPair<int, int>> &rowsAndCols);
|
||||
};
|
||||
|
||||
class DeckViewScene : public QGraphicsScene
|
||||
{
|
||||
Q_OBJECT
|
||||
signals:
|
||||
void newCardAdded(AbstractCardItem *card);
|
||||
void sideboardPlanChanged();
|
||||
|
||||
private:
|
||||
bool locked;
|
||||
DeckList *deck;
|
||||
QMap<QString, DeckViewCardContainer *> cardContainers;
|
||||
qreal optimalAspectRatio;
|
||||
void clearContents();
|
||||
void rebuildTree();
|
||||
|
||||
public:
|
||||
DeckViewScene(QObject *parent = nullptr);
|
||||
~DeckViewScene();
|
||||
void setLocked(bool _locked)
|
||||
{
|
||||
locked = _locked;
|
||||
}
|
||||
bool getLocked() const
|
||||
{
|
||||
return locked;
|
||||
}
|
||||
void setDeck(const DeckList &_deck);
|
||||
void setOptimalAspectRatio(qreal _optimalAspectRatio)
|
||||
{
|
||||
optimalAspectRatio = _optimalAspectRatio;
|
||||
}
|
||||
void rearrangeItems();
|
||||
void updateContents();
|
||||
QList<MoveCard_ToZone> getSideboardPlan() const;
|
||||
void resetSideboardPlan();
|
||||
void applySideboardPlan(const QList<MoveCard_ToZone> &plan);
|
||||
};
|
||||
|
||||
class DeckView : public QGraphicsView
|
||||
{
|
||||
Q_OBJECT
|
||||
private:
|
||||
DeckViewScene *deckViewScene;
|
||||
|
||||
protected:
|
||||
void resizeEvent(QResizeEvent *event);
|
||||
public slots:
|
||||
void updateSceneRect(const QRectF &rect);
|
||||
signals:
|
||||
void newCardAdded(AbstractCardItem *card);
|
||||
void sideboardPlanChanged();
|
||||
|
||||
public:
|
||||
DeckView(QWidget *parent = nullptr);
|
||||
void setDeck(const DeckList &_deck);
|
||||
void setLocked(bool _locked)
|
||||
{
|
||||
deckViewScene->setLocked(_locked);
|
||||
}
|
||||
QList<MoveCard_ToZone> getSideboardPlan() const
|
||||
{
|
||||
return deckViewScene->getSideboardPlan();
|
||||
}
|
||||
void mouseDoubleClickEvent(QMouseEvent *event);
|
||||
void resetSideboardPlan();
|
||||
};
|
||||
|
||||
#endif
|
||||
307
cockatrice/src/game/deckview/deck_view_container.cpp
Normal file
307
cockatrice/src/game/deckview/deck_view_container.cpp
Normal file
|
|
@ -0,0 +1,307 @@
|
|||
#include "deck_view_container.h"
|
||||
|
||||
#include "../../client/tabs/tab_game.h"
|
||||
#include "../../client/ui/picture_loader/picture_loader.h"
|
||||
#include "../../deck/deck_loader.h"
|
||||
#include "../../dialogs/dlg_load_deck.h"
|
||||
#include "../../dialogs/dlg_load_remote_deck.h"
|
||||
#include "../../server/pending_command.h"
|
||||
#include "../../settings/cache_settings.h"
|
||||
#include "../cards/card_database.h"
|
||||
#include "../cards/card_database_manager.h"
|
||||
#include "../game_scene.h"
|
||||
#include "deck_view.h"
|
||||
#include "pb/command_deck_select.pb.h"
|
||||
#include "pb/command_ready_start.pb.h"
|
||||
#include "pb/command_set_sideboard_lock.pb.h"
|
||||
#include "pb/command_set_sideboard_plan.pb.h"
|
||||
#include "pb/response_deck_download.pb.h"
|
||||
#include "trice_limits.h"
|
||||
|
||||
#include <QMessageBox>
|
||||
#include <QMouseEvent>
|
||||
#include <QToolButton>
|
||||
#include <google/protobuf/descriptor.h>
|
||||
|
||||
ToggleButton::ToggleButton(QWidget *parent) : QPushButton(parent), state(false)
|
||||
{
|
||||
}
|
||||
|
||||
void ToggleButton::paintEvent(QPaintEvent *event)
|
||||
{
|
||||
QPushButton::paintEvent(event);
|
||||
|
||||
QPainter painter(this);
|
||||
QPen pen;
|
||||
pen.setWidth(3);
|
||||
pen.setJoinStyle(Qt::MiterJoin);
|
||||
pen.setColor(state ? Qt::green : Qt::red);
|
||||
painter.setPen(pen);
|
||||
painter.drawRect(QRect(1, 1, width() - 3, height() - 3));
|
||||
}
|
||||
|
||||
void ToggleButton::setState(bool _state)
|
||||
{
|
||||
state = _state;
|
||||
emit stateChanged();
|
||||
update();
|
||||
}
|
||||
|
||||
DeckViewContainer::DeckViewContainer(int _playerId, TabGame *parent)
|
||||
: QWidget(nullptr), parentGame(parent), playerId(_playerId)
|
||||
{
|
||||
loadLocalButton = new QPushButton;
|
||||
loadRemoteButton = new QPushButton;
|
||||
unloadDeckButton = new QPushButton;
|
||||
unloadDeckButton->setEnabled(false);
|
||||
readyStartButton = new ToggleButton;
|
||||
readyStartButton->setEnabled(false);
|
||||
forceStartGameButton = new QPushButton;
|
||||
forceStartGameButton->setEnabled(parent->isHost());
|
||||
sideboardLockButton = new ToggleButton;
|
||||
sideboardLockButton->setEnabled(false);
|
||||
|
||||
connect(loadLocalButton, SIGNAL(clicked()), this, SLOT(loadLocalDeck()));
|
||||
connect(readyStartButton, SIGNAL(clicked()), this, SLOT(readyStart()));
|
||||
connect(unloadDeckButton, &QPushButton::clicked, this, &DeckViewContainer::unloadDeck);
|
||||
connect(forceStartGameButton, &QPushButton::clicked, this, &DeckViewContainer::forceStart);
|
||||
connect(sideboardLockButton, SIGNAL(clicked()), this, SLOT(sideboardLockButtonClicked()));
|
||||
connect(sideboardLockButton, SIGNAL(stateChanged()), this, SLOT(updateSideboardLockButtonText()));
|
||||
|
||||
if (parentGame->getIsLocalGame()) {
|
||||
loadRemoteButton->setEnabled(false);
|
||||
} else {
|
||||
connect(loadRemoteButton, SIGNAL(clicked()), this, SLOT(loadRemoteDeck()));
|
||||
}
|
||||
|
||||
auto *buttonHBox = new QHBoxLayout;
|
||||
buttonHBox->addWidget(loadLocalButton);
|
||||
buttonHBox->addWidget(loadRemoteButton);
|
||||
buttonHBox->addWidget(unloadDeckButton);
|
||||
buttonHBox->addWidget(readyStartButton);
|
||||
buttonHBox->addWidget(sideboardLockButton);
|
||||
if (forceStartGameButton->isEnabled()) {
|
||||
buttonHBox->addWidget(forceStartGameButton);
|
||||
forceStartGameButton->setEnabled(false);
|
||||
}
|
||||
buttonHBox->setContentsMargins(0, 0, 0, 0);
|
||||
buttonHBox->addStretch();
|
||||
|
||||
deckView = new DeckView;
|
||||
connect(deckView, SIGNAL(newCardAdded(AbstractCardItem *)), this, SIGNAL(newCardAdded(AbstractCardItem *)));
|
||||
connect(deckView, SIGNAL(sideboardPlanChanged()), this, SLOT(sideboardPlanChanged()));
|
||||
deckView->setVisible(false);
|
||||
|
||||
visualDeckStorageWidget = new VisualDeckStorageWidget(this);
|
||||
connect(visualDeckStorageWidget, &VisualDeckStorageWidget::deckPreviewDoubleClicked, this,
|
||||
&DeckViewContainer::replaceDeckStorageWithDeckView);
|
||||
|
||||
deckViewLayout = new QVBoxLayout;
|
||||
deckViewLayout->addLayout(buttonHBox);
|
||||
deckViewLayout->addWidget(deckView);
|
||||
deckViewLayout->addWidget(visualDeckStorageWidget);
|
||||
deckViewLayout->setContentsMargins(0, 0, 0, 0);
|
||||
setLayout(deckViewLayout);
|
||||
|
||||
retranslateUi();
|
||||
connect(&SettingsCache::instance().shortcuts(), SIGNAL(shortCutChanged()), this, SLOT(refreshShortcuts()));
|
||||
refreshShortcuts();
|
||||
}
|
||||
|
||||
void DeckViewContainer::retranslateUi()
|
||||
{
|
||||
loadLocalButton->setText(tr("Load deck..."));
|
||||
loadRemoteButton->setText(tr("Load remote deck..."));
|
||||
unloadDeckButton->setText(tr("Unload deck"));
|
||||
readyStartButton->setText(tr("Ready to start"));
|
||||
forceStartGameButton->setText(tr("Force start"));
|
||||
updateSideboardLockButtonText();
|
||||
}
|
||||
|
||||
void DeckViewContainer::setButtonsVisible(bool _visible)
|
||||
{
|
||||
loadLocalButton->setVisible(_visible);
|
||||
loadRemoteButton->setVisible(_visible);
|
||||
readyStartButton->setVisible(_visible);
|
||||
forceStartGameButton->setVisible(_visible);
|
||||
sideboardLockButton->setVisible(_visible);
|
||||
}
|
||||
|
||||
void DeckViewContainer::updateSideboardLockButtonText()
|
||||
{
|
||||
if (sideboardLockButton->getState()) {
|
||||
sideboardLockButton->setText(tr("Sideboard unlocked"));
|
||||
} else {
|
||||
sideboardLockButton->setText(tr("Sideboard locked"));
|
||||
}
|
||||
// setting text on a button removes its shortcut
|
||||
ShortcutsSettings &shortcuts = SettingsCache::instance().shortcuts();
|
||||
sideboardLockButton->setShortcut(shortcuts.getSingleShortcut("DeckViewContainer/sideboardLockButton"));
|
||||
}
|
||||
|
||||
void DeckViewContainer::refreshShortcuts()
|
||||
{
|
||||
ShortcutsSettings &shortcuts = SettingsCache::instance().shortcuts();
|
||||
loadLocalButton->setShortcut(shortcuts.getSingleShortcut("DeckViewContainer/loadLocalButton"));
|
||||
loadRemoteButton->setShortcut(shortcuts.getSingleShortcut("DeckViewContainer/loadRemoteButton"));
|
||||
readyStartButton->setShortcut(shortcuts.getSingleShortcut("DeckViewContainer/readyStartButton"));
|
||||
sideboardLockButton->setShortcut(shortcuts.getSingleShortcut("DeckViewContainer/sideboardLockButton"));
|
||||
}
|
||||
|
||||
void DeckViewContainer::replaceDeckStorageWithDeckView(QMouseEvent *event, DeckPreviewWidget *instance)
|
||||
{
|
||||
Q_UNUSED(event);
|
||||
QString deckString = instance->deckLoader->writeToString_Native();
|
||||
|
||||
if (deckString.length() > MAX_FILE_LENGTH) {
|
||||
QMessageBox::critical(this, tr("Error"), tr("The selected file could not be loaded."));
|
||||
return;
|
||||
}
|
||||
|
||||
Command_DeckSelect cmd;
|
||||
cmd.set_deck(deckString.toStdString());
|
||||
PendingCommand *pend = parentGame->prepareGameCommand(cmd);
|
||||
connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this,
|
||||
SLOT(deckSelectFinished(const Response &)));
|
||||
parentGame->sendGameCommand(pend, playerId);
|
||||
}
|
||||
|
||||
void DeckViewContainer::unloadDeck()
|
||||
{
|
||||
deckView->setVisible(false);
|
||||
visualDeckStorageWidget->setVisible(true);
|
||||
deckViewLayout->update();
|
||||
unloadDeckButton->setEnabled(false);
|
||||
readyStartButton->setEnabled(false);
|
||||
readyStartButton->setState(false);
|
||||
sideboardLockButton->setEnabled(false);
|
||||
sideboardLockButton->setState(false);
|
||||
forceStartGameButton->setEnabled(false);
|
||||
setReadyStart(false);
|
||||
}
|
||||
|
||||
void DeckViewContainer::loadLocalDeck()
|
||||
{
|
||||
DlgLoadDeck dialog(this);
|
||||
if (!dialog.exec())
|
||||
return;
|
||||
|
||||
loadDeckFromFile(dialog.selectedFiles().at(0));
|
||||
}
|
||||
|
||||
void DeckViewContainer::loadDeckFromFile(const QString &filePath)
|
||||
{
|
||||
DeckLoader::FileFormat fmt = DeckLoader::getFormatFromName(filePath);
|
||||
QString deckString;
|
||||
DeckLoader deck;
|
||||
|
||||
bool error = !deck.loadFromFile(filePath, fmt, true);
|
||||
if (!error) {
|
||||
deckString = deck.writeToString_Native();
|
||||
error = deckString.length() > MAX_FILE_LENGTH;
|
||||
}
|
||||
if (error) {
|
||||
QMessageBox::critical(this, tr("Error"), tr("The selected file could not be loaded."));
|
||||
return;
|
||||
}
|
||||
|
||||
Command_DeckSelect cmd;
|
||||
cmd.set_deck(deckString.toStdString());
|
||||
PendingCommand *pend = parentGame->prepareGameCommand(cmd);
|
||||
connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this,
|
||||
SLOT(deckSelectFinished(const Response &)));
|
||||
parentGame->sendGameCommand(pend, playerId);
|
||||
}
|
||||
|
||||
void DeckViewContainer::loadRemoteDeck()
|
||||
{
|
||||
DlgLoadRemoteDeck dlg(parentGame->getClientForPlayer(playerId), this);
|
||||
if (dlg.exec()) {
|
||||
Command_DeckSelect cmd;
|
||||
cmd.set_deck_id(dlg.getDeckId());
|
||||
PendingCommand *pend = parentGame->prepareGameCommand(cmd);
|
||||
connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this,
|
||||
SLOT(deckSelectFinished(const Response &)));
|
||||
parentGame->sendGameCommand(pend, playerId);
|
||||
}
|
||||
}
|
||||
|
||||
void DeckViewContainer::deckSelectFinished(const Response &r)
|
||||
{
|
||||
const Response_DeckDownload &resp = r.GetExtension(Response_DeckDownload::ext);
|
||||
DeckLoader newDeck(QString::fromStdString(resp.deck()));
|
||||
// TODO CHANGE THIS TO BE SELECTED BY UUID
|
||||
PictureLoader::cacheCardPixmaps(CardDatabaseManager::getInstance()->getCards(newDeck.getCardList()));
|
||||
setDeck(newDeck);
|
||||
deckView->setVisible(true);
|
||||
visualDeckStorageWidget->setVisible(false);
|
||||
unloadDeckButton->setEnabled(true);
|
||||
}
|
||||
|
||||
void DeckViewContainer::readyStart()
|
||||
{
|
||||
Command_ReadyStart cmd;
|
||||
cmd.set_ready(!readyStartButton->getState());
|
||||
parentGame->sendGameCommand(cmd, playerId);
|
||||
}
|
||||
|
||||
void DeckViewContainer::forceStart()
|
||||
{
|
||||
Command_ReadyStart cmd;
|
||||
cmd.set_force_start(true);
|
||||
cmd.set_ready(true);
|
||||
parentGame->sendGameCommand(cmd, playerId);
|
||||
}
|
||||
|
||||
void DeckViewContainer::sideboardLockButtonClicked()
|
||||
{
|
||||
Command_SetSideboardLock cmd;
|
||||
cmd.set_locked(sideboardLockButton->getState());
|
||||
|
||||
parentGame->sendGameCommand(cmd, playerId);
|
||||
}
|
||||
|
||||
void DeckViewContainer::sideboardPlanChanged()
|
||||
{
|
||||
Command_SetSideboardPlan cmd;
|
||||
const QList<MoveCard_ToZone> &newPlan = deckView->getSideboardPlan();
|
||||
for (const auto &i : newPlan)
|
||||
cmd.add_move_list()->CopyFrom(i);
|
||||
parentGame->sendGameCommand(cmd, playerId);
|
||||
}
|
||||
|
||||
void DeckViewContainer::setReadyStart(bool ready)
|
||||
{
|
||||
readyStartButton->setState(ready);
|
||||
deckView->setLocked(ready || !sideboardLockButton->getState());
|
||||
sideboardLockButton->setEnabled(!readyStartButton->getState() && readyStartButton->isEnabled());
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the ready start to true, then sends the ready command so the server responds to the update
|
||||
*/
|
||||
void DeckViewContainer::readyAndUpdate()
|
||||
{
|
||||
setReadyStart(true);
|
||||
|
||||
Command_ReadyStart cmd;
|
||||
cmd.set_ready(true);
|
||||
parentGame->sendGameCommand(cmd, playerId);
|
||||
}
|
||||
|
||||
void DeckViewContainer::setSideboardLocked(bool locked)
|
||||
{
|
||||
sideboardLockButton->setState(!locked);
|
||||
deckView->setLocked(readyStartButton->getState() || !sideboardLockButton->getState());
|
||||
if (locked)
|
||||
deckView->resetSideboardPlan();
|
||||
}
|
||||
|
||||
void DeckViewContainer::setDeck(const DeckLoader &deck)
|
||||
{
|
||||
deckView->setDeck(deck);
|
||||
readyStartButton->setEnabled(true);
|
||||
sideboardLockButton->setState(false);
|
||||
sideboardLockButton->setEnabled(true);
|
||||
forceStartGameButton->setEnabled(true);
|
||||
}
|
||||
80
cockatrice/src/game/deckview/deck_view_container.h
Normal file
80
cockatrice/src/game/deckview/deck_view_container.h
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
#ifndef DECK_VIEW_CONTAINER_H
|
||||
#define DECK_VIEW_CONTAINER_H
|
||||
|
||||
#include "../../deck/deck_loader.h"
|
||||
|
||||
#include <QPushButton>
|
||||
|
||||
class QVBoxLayout;
|
||||
class AbstractCardItem;
|
||||
class VisualDeckStorageWidget;
|
||||
class DeckPreviewWidget;
|
||||
class Response;
|
||||
class TabGame;
|
||||
class DeckView;
|
||||
|
||||
/**
|
||||
* Custom QButton implementation in order to have the red/green toggling square around the button
|
||||
*/
|
||||
class ToggleButton : public QPushButton
|
||||
{
|
||||
Q_OBJECT
|
||||
private:
|
||||
bool state;
|
||||
signals:
|
||||
void stateChanged();
|
||||
|
||||
public:
|
||||
explicit ToggleButton(QWidget *parent = nullptr);
|
||||
bool getState() const
|
||||
{
|
||||
return state;
|
||||
}
|
||||
void setState(bool _state);
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *event) override;
|
||||
};
|
||||
|
||||
/**
|
||||
* This widget contains the deck selection view that is used before a game begins.
|
||||
*/
|
||||
class DeckViewContainer : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
private:
|
||||
QVBoxLayout *deckViewLayout;
|
||||
QPushButton *loadLocalButton, *loadRemoteButton, *unloadDeckButton, *forceStartGameButton;
|
||||
ToggleButton *readyStartButton, *sideboardLockButton;
|
||||
DeckView *deckView;
|
||||
VisualDeckStorageWidget *visualDeckStorageWidget;
|
||||
TabGame *parentGame;
|
||||
int playerId;
|
||||
private slots:
|
||||
void replaceDeckStorageWithDeckView(QMouseEvent *event, DeckPreviewWidget *instance);
|
||||
void loadLocalDeck();
|
||||
void loadRemoteDeck();
|
||||
void unloadDeck();
|
||||
void readyStart();
|
||||
void forceStart();
|
||||
void deckSelectFinished(const Response &r);
|
||||
void sideboardPlanChanged();
|
||||
void sideboardLockButtonClicked();
|
||||
void updateSideboardLockButtonText();
|
||||
void refreshShortcuts();
|
||||
signals:
|
||||
void newCardAdded(AbstractCardItem *card);
|
||||
void notIdle();
|
||||
|
||||
public:
|
||||
DeckViewContainer(int _playerId, TabGame *parent);
|
||||
void retranslateUi();
|
||||
void setButtonsVisible(bool _visible);
|
||||
void setReadyStart(bool ready);
|
||||
void readyAndUpdate();
|
||||
void setSideboardLocked(bool locked);
|
||||
void setDeck(const DeckLoader &deck);
|
||||
void loadDeckFromFile(const QString &filePath);
|
||||
};
|
||||
|
||||
#endif // DECK_VIEW_CONTAINER_H
|
||||
Loading…
Add table
Add a link
Reference in a new issue