mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-07-18 08:22:15 -07:00
Merge branch 'master' into card-rounding-option
This commit is contained in:
commit
8389884aae
26 changed files with 1608 additions and 1142 deletions
File diff suppressed because it is too large
Load diff
|
|
@ -47,8 +47,6 @@
|
|||
# card_info = false
|
||||
# card_list = false
|
||||
|
||||
# stack_zone = false
|
||||
|
||||
flow_layout.debug = false
|
||||
flow_widget.debug = false
|
||||
flow_widget.size.debug = false
|
||||
|
|
|
|||
|
|
@ -55,6 +55,9 @@ DeckEditorMenu::DeckEditorMenu(QWidget *parent, AbstractTabDeckEditor *_deckEdit
|
|||
aExportDeckDecklist = new QAction(QString(), this);
|
||||
connect(aExportDeckDecklist, SIGNAL(triggered()), deckEditor, SLOT(actExportDeckDecklist()));
|
||||
|
||||
aExportDeckDecklistXyz = new QAction(QString(), this);
|
||||
connect(aExportDeckDecklistXyz, SIGNAL(triggered()), deckEditor, SLOT(actExportDeckDecklistXyz()));
|
||||
|
||||
aAnalyzeDeckDeckstats = new QAction(QString(), this);
|
||||
connect(aAnalyzeDeckDeckstats, SIGNAL(triggered()), deckEditor, SLOT(actAnalyzeDeckDeckstats()));
|
||||
|
||||
|
|
@ -63,6 +66,8 @@ DeckEditorMenu::DeckEditorMenu(QWidget *parent, AbstractTabDeckEditor *_deckEdit
|
|||
|
||||
analyzeDeckMenu = new QMenu(this);
|
||||
analyzeDeckMenu->addAction(aExportDeckDecklist);
|
||||
analyzeDeckMenu->addAction(aExportDeckDecklistXyz);
|
||||
analyzeDeckMenu->addSeparator();
|
||||
analyzeDeckMenu->addAction(aAnalyzeDeckDeckstats);
|
||||
analyzeDeckMenu->addAction(aAnalyzeDeckTappedout);
|
||||
|
||||
|
|
@ -160,6 +165,7 @@ void DeckEditorMenu::retranslateUi()
|
|||
|
||||
analyzeDeckMenu->setTitle(tr("&Send deck to online service"));
|
||||
aExportDeckDecklist->setText(tr("Create decklist (decklist.org)"));
|
||||
aExportDeckDecklistXyz->setText(tr("Create decklist (decklist.xyz)"));
|
||||
aAnalyzeDeckDeckstats->setText(tr("Analyze deck (deckstats.net)"));
|
||||
aAnalyzeDeckTappedout->setText(tr("Analyze deck (tappedout.net)"));
|
||||
|
||||
|
|
@ -172,13 +178,17 @@ void DeckEditorMenu::refreshShortcuts()
|
|||
aNewDeck->setShortcuts(shortcuts.getShortcut("TabDeckEditor/aNewDeck"));
|
||||
aLoadDeck->setShortcuts(shortcuts.getShortcut("TabDeckEditor/aLoadDeck"));
|
||||
aSaveDeck->setShortcuts(shortcuts.getShortcut("TabDeckEditor/aSaveDeck"));
|
||||
aExportDeckDecklist->setShortcuts(shortcuts.getShortcut("TabDeckEditor/aExportDeckDecklist"));
|
||||
aSaveDeckAs->setShortcuts(shortcuts.getShortcut("TabDeckEditor/aSaveDeckAs"));
|
||||
aLoadDeckFromClipboard->setShortcuts(shortcuts.getShortcut("TabDeckEditor/aLoadDeckFromClipboard"));
|
||||
aEditDeckInClipboard->setShortcuts(shortcuts.getShortcut("TabDeckEditor/aEditDeckInClipboard"));
|
||||
aEditDeckInClipboardRaw->setShortcuts(shortcuts.getShortcut("TabDeckEditor/aEditDeckInClipboardRaw"));
|
||||
aPrintDeck->setShortcuts(shortcuts.getShortcut("TabDeckEditor/aPrintDeck"));
|
||||
|
||||
aExportDeckDecklist->setShortcuts(shortcuts.getShortcut("TabDeckEditor/aExportDeckDecklist"));
|
||||
aExportDeckDecklistXyz->setShortcuts(shortcuts.getShortcut("TabDeckEditor/aExportDeckDecklistXyz"));
|
||||
aAnalyzeDeckDeckstats->setShortcuts(shortcuts.getShortcut("TabDeckEditor/aAnalyzeDeck"));
|
||||
aAnalyzeDeckTappedout->setShortcuts(shortcuts.getShortcut("TabDeckEditor/aAnalyzeDeckTappedout"));
|
||||
|
||||
aClose->setShortcuts(shortcuts.getShortcut("TabDeckEditor/aClose"));
|
||||
|
||||
aSaveDeckToClipboard->setShortcuts(shortcuts.getShortcut("TabDeckEditor/aSaveDeckToClipboard"));
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ public:
|
|||
QAction *aNewDeck, *aLoadDeck, *aClearRecents, *aSaveDeck, *aSaveDeckAs, *aLoadDeckFromClipboard,
|
||||
*aEditDeckInClipboard, *aEditDeckInClipboardRaw, *aSaveDeckToClipboard, *aSaveDeckToClipboardNoSetInfo,
|
||||
*aSaveDeckToClipboardRaw, *aSaveDeckToClipboardRawNoSetInfo, *aPrintDeck, *aExportDeckDecklist,
|
||||
*aAnalyzeDeckDeckstats, *aAnalyzeDeckTappedout, *aClose;
|
||||
*aExportDeckDecklistXyz, *aAnalyzeDeckDeckstats, *aAnalyzeDeckTappedout, *aClose;
|
||||
QMenu *loadRecentDeckMenu, *analyzeDeckMenu, *editDeckInClipboardMenu, *saveDeckToClipboardMenu;
|
||||
|
||||
void setSaveStatus(bool newStatus);
|
||||
|
|
|
|||
|
|
@ -455,17 +455,12 @@ void AbstractTabDeckEditor::actPrintDeck()
|
|||
dlg->exec();
|
||||
}
|
||||
|
||||
// Action called when export deck to decklist menu item is pressed.
|
||||
void AbstractTabDeckEditor::actExportDeckDecklist()
|
||||
void AbstractTabDeckEditor::exportToDecklistWebsite(DeckLoader::DecklistWebsite website)
|
||||
{
|
||||
// Get the decklist class for the deck.
|
||||
DeckLoader *const deck = getDeckList();
|
||||
// create a string to load the decklist url into.
|
||||
QString decklistUrlString;
|
||||
// check if deck is not null
|
||||
if (deck) {
|
||||
if (DeckLoader *const deck = getDeckList()) {
|
||||
// Get the decklist url string from the deck loader class.
|
||||
decklistUrlString = deck->exportDeckToDecklist();
|
||||
QString decklistUrlString = deck->exportDeckToDecklist(website);
|
||||
// Check to make sure the string isn't empty.
|
||||
if (QString::compare(decklistUrlString, "", Qt::CaseInsensitive) == 0) {
|
||||
// Show an error if the deck is empty, and return.
|
||||
|
|
@ -481,10 +476,26 @@ void AbstractTabDeckEditor::actExportDeckDecklist()
|
|||
QDesktopServices::openUrl(decklistUrlString);
|
||||
} else {
|
||||
// if there's no deck loader object, return an error
|
||||
QMessageBox::critical(this, tr("Error"), tr("No deck was selected to be saved."));
|
||||
QMessageBox::critical(this, tr("Error"), tr("No deck was selected to be exported."));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Exports the deck to www.decklist.org (the old website)
|
||||
*/
|
||||
void AbstractTabDeckEditor::actExportDeckDecklist()
|
||||
{
|
||||
exportToDecklistWebsite(DeckLoader::DecklistOrg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Exports the deck to www.decklist.xyz (the new website)
|
||||
*/
|
||||
void AbstractTabDeckEditor::actExportDeckDecklistXyz()
|
||||
{
|
||||
exportToDecklistWebsite(DeckLoader::DecklistXyz);
|
||||
}
|
||||
|
||||
void AbstractTabDeckEditor::actAnalyzeDeckDeckstats()
|
||||
{
|
||||
auto *interface = new DeckStatsInterface(*databaseDisplayDockWidget->databaseModel->getDatabase(),
|
||||
|
|
|
|||
|
|
@ -100,6 +100,7 @@ protected slots:
|
|||
void actSaveDeckToClipboardRawNoSetInfo();
|
||||
void actPrintDeck();
|
||||
void actExportDeckDecklist();
|
||||
void actExportDeckDecklistXyz();
|
||||
void actAnalyzeDeckDeckstats();
|
||||
void actAnalyzeDeckTappedout();
|
||||
|
||||
|
|
@ -119,6 +120,7 @@ protected slots:
|
|||
private:
|
||||
virtual void setDeck(DeckLoader *_deck);
|
||||
void editDeckInClipboard(bool annotated);
|
||||
void exportToDecklistWebsite(DeckLoader::DecklistWebsite website);
|
||||
|
||||
protected:
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
#include <QLabel>
|
||||
|
||||
DeckPreviewDeckTagsDisplayWidget::DeckPreviewDeckTagsDisplayWidget(QWidget *_parent, DeckList *_deckList)
|
||||
: QWidget(_parent), deckList(_deckList)
|
||||
: QWidget(_parent), deckList(nullptr)
|
||||
{
|
||||
|
||||
setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
|
||||
|
|
@ -27,8 +27,8 @@ DeckPreviewDeckTagsDisplayWidget::DeckPreviewDeckTagsDisplayWidget(QWidget *_par
|
|||
|
||||
flowWidget = new FlowWidget(this, Qt::Horizontal, Qt::ScrollBarAlwaysOff, Qt::ScrollBarAsNeeded);
|
||||
|
||||
if (deckList) {
|
||||
connectDeckList(deckList);
|
||||
if (_deckList) {
|
||||
connectDeckList(_deckList);
|
||||
}
|
||||
|
||||
layout->addWidget(flowWidget);
|
||||
|
|
@ -36,10 +36,20 @@ DeckPreviewDeckTagsDisplayWidget::DeckPreviewDeckTagsDisplayWidget(QWidget *_par
|
|||
|
||||
void DeckPreviewDeckTagsDisplayWidget::connectDeckList(DeckList *_deckList)
|
||||
{
|
||||
flowWidget->clearLayout();
|
||||
if (deckList) {
|
||||
disconnect(deckList, &DeckList::deckTagsChanged, this, &DeckPreviewDeckTagsDisplayWidget::refreshTags);
|
||||
}
|
||||
|
||||
deckList = _deckList;
|
||||
connect(deckList, &DeckList::deckTagsChanged, this, &DeckPreviewDeckTagsDisplayWidget::refreshTags);
|
||||
|
||||
refreshTags();
|
||||
}
|
||||
|
||||
void DeckPreviewDeckTagsDisplayWidget::refreshTags()
|
||||
{
|
||||
flowWidget->clearLayout();
|
||||
|
||||
for (const QString &tag : deckList->getTags()) {
|
||||
flowWidget->addWidget(new DeckPreviewTagDisplayWidget(this, tag));
|
||||
}
|
||||
|
|
@ -50,16 +60,6 @@ void DeckPreviewDeckTagsDisplayWidget::connectDeckList(DeckList *_deckList)
|
|||
flowWidget->addWidget(tagAdditionWidget);
|
||||
}
|
||||
|
||||
void DeckPreviewDeckTagsDisplayWidget::refreshTags()
|
||||
{
|
||||
flowWidget->clearLayout();
|
||||
QStringList tags = deckList->getTags();
|
||||
for (const QString &tag : tags) {
|
||||
flowWidget->addWidget(new DeckPreviewTagDisplayWidget(this, tag));
|
||||
}
|
||||
flowWidget->addWidget(new DeckPreviewTagAdditionWidget(this, tr("Edit tags ...")));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the filepath of all files (no directories) in target directory and all subdirectories
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ void VisualDeckStorageFolderDisplayWidget::refreshUi()
|
|||
}
|
||||
|
||||
/**
|
||||
* Gets all files in the directory that have a .txt or .cod extension
|
||||
* Gets all files in the directory that have an accepted decklist file extension
|
||||
*
|
||||
* @param filePath The directory to search through
|
||||
* @param recursive Whether to search through subdirectories
|
||||
|
|
|
|||
|
|
@ -226,6 +226,19 @@ bool DeckLoader::updateLastLoadedTimestamp(const QString &fileName, FileFormat f
|
|||
return result;
|
||||
}
|
||||
|
||||
static QString getDomainForWebsite(DeckLoader::DecklistWebsite website)
|
||||
{
|
||||
switch (website) {
|
||||
case DeckLoader::DecklistOrg:
|
||||
return "www.decklist.org";
|
||||
case DeckLoader::DecklistXyz:
|
||||
return "www.decklist.xyz";
|
||||
default:
|
||||
qCWarning(DeckLoaderLog) << "Invalid decklist website enum:" << website;
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
// This struct is here to support the forEachCard function call, defined in decklist. It
|
||||
// requires a function to be called for each card, and passes an inner node and a card for
|
||||
// each card in the decklist.
|
||||
|
|
@ -275,11 +288,14 @@ struct FormatDeckListForExport
|
|||
}
|
||||
};
|
||||
|
||||
// Export deck to decklist function, called to format the deck in a way to be sent to a server
|
||||
QString DeckLoader::exportDeckToDecklist()
|
||||
/**
|
||||
* Export deck to decklist function, called to format the deck in a way to be sent to a server
|
||||
* @param website The website we're sending the deck to
|
||||
*/
|
||||
QString DeckLoader::exportDeckToDecklist(DecklistWebsite website)
|
||||
{
|
||||
// Add the base url
|
||||
QString deckString = "https://www.decklist.org/?";
|
||||
QString deckString = "https://" + getDomainForWebsite(website) + "/?";
|
||||
// Create two strings to pass to function
|
||||
QString mainBoardCards, sideBoardCards;
|
||||
// Set up the struct to call.
|
||||
|
|
|
|||
|
|
@ -31,6 +31,12 @@ public:
|
|||
*/
|
||||
static const QStringList FILE_NAME_FILTERS;
|
||||
|
||||
enum DecklistWebsite
|
||||
{
|
||||
DecklistOrg,
|
||||
DecklistXyz
|
||||
};
|
||||
|
||||
private:
|
||||
QString lastFileName;
|
||||
FileFormat lastFileFormat;
|
||||
|
|
@ -71,7 +77,7 @@ public:
|
|||
bool loadFromRemote(const QString &nativeString, int remoteDeckId);
|
||||
bool saveToFile(const QString &fileName, FileFormat fmt);
|
||||
bool updateLastLoadedTimestamp(const QString &fileName, FileFormat fmt);
|
||||
QString exportDeckToDecklist();
|
||||
QString exportDeckToDecklist(DecklistWebsite website);
|
||||
|
||||
void resolveSetNameAndNumberToProviderID();
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
#include "../game/cards/card_database.h"
|
||||
#include "../game/cards/card_database_manager.h"
|
||||
#include "../game/filters/filter_string.h"
|
||||
#include "trice_limits.h"
|
||||
|
||||
#include <QDialogButtonBox>
|
||||
#include <QLabel>
|
||||
|
|
@ -14,15 +13,17 @@
|
|||
#include <QVBoxLayout>
|
||||
#include <QWidget>
|
||||
|
||||
DlgMoveTopCardsUntil::DlgMoveTopCardsUntil(QWidget *parent, QString _expr, uint _numberOfHits, bool autoPlay)
|
||||
DlgMoveTopCardsUntil::DlgMoveTopCardsUntil(QWidget *parent, QStringList exprs, uint _numberOfHits, bool autoPlay)
|
||||
: QDialog(parent)
|
||||
{
|
||||
exprLabel = new QLabel(tr("Card name (or search expressions):"));
|
||||
|
||||
exprEdit = new QLineEdit(this);
|
||||
exprEdit->setFocus();
|
||||
exprEdit->setText(_expr);
|
||||
exprLabel->setBuddy(exprEdit);
|
||||
exprComboBox = new QComboBox(this);
|
||||
exprComboBox->setFocus();
|
||||
exprComboBox->setEditable(true);
|
||||
exprComboBox->setInsertPolicy(QComboBox::InsertAtTop);
|
||||
exprComboBox->insertItems(0, exprs);
|
||||
exprLabel->setBuddy(exprComboBox);
|
||||
|
||||
numberOfHitsLabel = new QLabel(tr("Number of hits:"));
|
||||
numberOfHitsEdit = new QSpinBox(this);
|
||||
|
|
@ -43,7 +44,7 @@ DlgMoveTopCardsUntil::DlgMoveTopCardsUntil(QWidget *parent, QString _expr, uint
|
|||
|
||||
auto *mainLayout = new QVBoxLayout;
|
||||
mainLayout->addWidget(exprLabel);
|
||||
mainLayout->addWidget(exprEdit);
|
||||
mainLayout->addWidget(exprComboBox);
|
||||
mainLayout->addItem(grid);
|
||||
mainLayout->addWidget(autoPlayCheckBox);
|
||||
mainLayout->addWidget(buttonBox);
|
||||
|
|
@ -92,7 +93,7 @@ bool DlgMoveTopCardsUntil::validateMatchExists(const FilterString &filterString)
|
|||
|
||||
void DlgMoveTopCardsUntil::validateAndAccept()
|
||||
{
|
||||
auto movingCardsUntilFilter = FilterString(exprEdit->text());
|
||||
auto movingCardsUntilFilter = FilterString(exprComboBox->currentText());
|
||||
if (!movingCardsUntilFilter.valid()) {
|
||||
QMessageBox::warning(this, tr("Invalid filter"), movingCardsUntilFilter.error(), QMessageBox::Ok);
|
||||
return;
|
||||
|
|
@ -102,12 +103,29 @@ void DlgMoveTopCardsUntil::validateAndAccept()
|
|||
return;
|
||||
}
|
||||
|
||||
// move currently selected text to top of history list
|
||||
if (exprComboBox->currentIndex() != 0) {
|
||||
QString currentExpr = exprComboBox->currentText();
|
||||
exprComboBox->removeItem(exprComboBox->currentIndex());
|
||||
exprComboBox->insertItem(0, currentExpr);
|
||||
exprComboBox->setCurrentIndex(0);
|
||||
}
|
||||
|
||||
accept();
|
||||
}
|
||||
|
||||
QString DlgMoveTopCardsUntil::getExpr() const
|
||||
{
|
||||
return exprEdit->text();
|
||||
return exprComboBox->currentText();
|
||||
}
|
||||
|
||||
QStringList DlgMoveTopCardsUntil::getExprs() const
|
||||
{
|
||||
QStringList exprs;
|
||||
for (int i = 0; i < exprComboBox->count(); ++i) {
|
||||
exprs.append(exprComboBox->itemText(i));
|
||||
}
|
||||
return exprs;
|
||||
}
|
||||
|
||||
uint DlgMoveTopCardsUntil::getNumberOfHits() const
|
||||
|
|
|
|||
|
|
@ -2,10 +2,10 @@
|
|||
#define DLG_MOVE_TOP_CARDS_UNTIL_H
|
||||
|
||||
#include <QCheckBox>
|
||||
#include <QComboBox>
|
||||
#include <QDialog>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QLabel>
|
||||
#include <QLineEdit>
|
||||
#include <QSpinBox>
|
||||
|
||||
class FilterString;
|
||||
|
|
@ -15,7 +15,7 @@ class DlgMoveTopCardsUntil : public QDialog
|
|||
Q_OBJECT
|
||||
|
||||
QLabel *exprLabel, *numberOfHitsLabel;
|
||||
QLineEdit *exprEdit;
|
||||
QComboBox *exprComboBox;
|
||||
QSpinBox *numberOfHitsEdit;
|
||||
QDialogButtonBox *buttonBox;
|
||||
QCheckBox *autoPlayCheckBox;
|
||||
|
|
@ -25,10 +25,11 @@ class DlgMoveTopCardsUntil : public QDialog
|
|||
|
||||
public:
|
||||
explicit DlgMoveTopCardsUntil(QWidget *parent = nullptr,
|
||||
QString expr = QString(),
|
||||
QStringList exprs = QStringList(),
|
||||
uint numberOfHits = 1,
|
||||
bool autoPlay = false);
|
||||
QString getExpr() const;
|
||||
QStringList getExprs() const;
|
||||
uint getNumberOfHits() const;
|
||||
bool isAutoPlay() const;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@
|
|||
#include <QGraphicsScene>
|
||||
#include <QGraphicsSceneMouseEvent>
|
||||
#include <QPainter>
|
||||
#include <QStyleOption>
|
||||
#include <algorithm>
|
||||
|
||||
AbstractCardItem::AbstractCardItem(QGraphicsItem *parent,
|
||||
|
|
@ -19,7 +18,7 @@ AbstractCardItem::AbstractCardItem(QGraphicsItem *parent,
|
|||
Player *_owner,
|
||||
int _id)
|
||||
: ArrowTarget(_owner, parent), id(_id), name(_name), providerId(_providerId), tapped(false), facedown(false),
|
||||
tapAngle(0), bgColor(Qt::transparent), realZValue(0)
|
||||
tapAngle(0), bgColor(Qt::transparent), isHovered(false), realZValue(0)
|
||||
{
|
||||
setCursor(Qt::OpenHandCursor);
|
||||
setFlag(ItemIsSelectable);
|
||||
|
|
@ -28,8 +27,6 @@ AbstractCardItem::AbstractCardItem(QGraphicsItem *parent,
|
|||
connect(&SettingsCache::instance(), &SettingsCache::displayCardNamesChanged, this, [this] { update(); });
|
||||
refreshCardInfo();
|
||||
|
||||
setAcceptHoverEvents(true);
|
||||
|
||||
connect(&SettingsCache::instance(), &SettingsCache::roundCardCornersChanged, this, [this](bool _roundCardCorners) {
|
||||
Q_UNUSED(_roundCardCorners);
|
||||
|
||||
|
|
@ -168,7 +165,7 @@ void AbstractCardItem::paintPicture(QPainter *painter, const QSizeF &translatedS
|
|||
painter->restore();
|
||||
}
|
||||
|
||||
void AbstractCardItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget * /*widget*/)
|
||||
void AbstractCardItem::paint(QPainter *painter, const QStyleOptionGraphicsItem * /*option*/, QWidget * /*widget*/)
|
||||
{
|
||||
painter->save();
|
||||
|
||||
|
|
@ -177,7 +174,6 @@ void AbstractCardItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *
|
|||
|
||||
painter->setRenderHint(QPainter::Antialiasing, false);
|
||||
|
||||
bool isHovered = option->state.testFlag(QStyle::State_MouseOver);
|
||||
if (isSelected() || isHovered) {
|
||||
QPen pen;
|
||||
if (isHovered)
|
||||
|
|
@ -220,24 +216,17 @@ void AbstractCardItem::setProviderId(const QString &_providerId)
|
|||
refreshCardInfo();
|
||||
}
|
||||
|
||||
void AbstractCardItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
|
||||
void AbstractCardItem::setHovered(bool _hovered)
|
||||
{
|
||||
Q_UNUSED(event);
|
||||
if (isHovered == _hovered)
|
||||
return;
|
||||
|
||||
emit hovered(this);
|
||||
setZValue(2000000004);
|
||||
setScale(SettingsCache::instance().getScaleCards() ? 1.1 : 1);
|
||||
setTransformOriginPoint(CARD_WIDTH / 2, CARD_HEIGHT / 2);
|
||||
update();
|
||||
}
|
||||
|
||||
void AbstractCardItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
|
||||
{
|
||||
Q_UNUSED(event);
|
||||
|
||||
setZValue(realZValue);
|
||||
setScale(1);
|
||||
setTransformOriginPoint(0, 0);
|
||||
if (_hovered)
|
||||
processHoverEvent();
|
||||
isHovered = _hovered;
|
||||
setZValue(_hovered ? 2000000004 : realZValue);
|
||||
setScale(_hovered && SettingsCache::instance().getScaleCards() ? 1.1 : 1);
|
||||
setTransformOriginPoint(_hovered ? CARD_WIDTH / 2 : 0, _hovered ? CARD_HEIGHT / 2 : 0);
|
||||
update();
|
||||
}
|
||||
|
||||
|
|
@ -333,6 +322,11 @@ void AbstractCardItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
|||
event->accept();
|
||||
}
|
||||
|
||||
void AbstractCardItem::processHoverEvent()
|
||||
{
|
||||
emit hovered(this);
|
||||
}
|
||||
|
||||
QVariant AbstractCardItem::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value)
|
||||
{
|
||||
if (change == ItemSelectedHasChanged) {
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ protected:
|
|||
QColor bgColor;
|
||||
|
||||
private:
|
||||
bool isHovered;
|
||||
qreal realZValue;
|
||||
private slots:
|
||||
void pixmapUpdated();
|
||||
|
|
@ -85,6 +86,7 @@ public:
|
|||
return realZValue;
|
||||
}
|
||||
void setRealZValue(qreal _zValue);
|
||||
void setHovered(bool _hovered);
|
||||
QString getColor() const
|
||||
{
|
||||
return color;
|
||||
|
|
@ -100,6 +102,7 @@ public:
|
|||
return facedown;
|
||||
}
|
||||
void setFaceDown(bool _facedown);
|
||||
void processHoverEvent();
|
||||
void deleteCardInfoPopup()
|
||||
{
|
||||
emit deleteCardInfoPopup(name);
|
||||
|
|
@ -111,9 +114,6 @@ protected:
|
|||
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override;
|
||||
QVariant itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value) override;
|
||||
void cacheBgColor();
|
||||
|
||||
void hoverEnterEvent(QGraphicsSceneHoverEvent *event) override;
|
||||
void hoverLeaveEvent(QGraphicsSceneHoverEvent *event) override;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -469,6 +469,7 @@ bool CardItem::animationEvent()
|
|||
.translate(CARD_WIDTH_HALF, CARD_HEIGHT_HALF)
|
||||
.rotate(tapAngle)
|
||||
.translate(-CARD_WIDTH_HALF, -CARD_HEIGHT_HALF));
|
||||
setHovered(false);
|
||||
update();
|
||||
|
||||
return animationIncomplete;
|
||||
|
|
|
|||
|
|
@ -164,6 +164,12 @@ void DeckView::mouseDoubleClickEvent(QMouseEvent *event)
|
|||
}
|
||||
}
|
||||
|
||||
void DeckViewCard::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
|
||||
{
|
||||
event->accept();
|
||||
processHoverEvent();
|
||||
}
|
||||
|
||||
DeckViewCardContainer::DeckViewCardContainer(const QString &_name) : QGraphicsItem(), name(_name), width(0), height(0)
|
||||
{
|
||||
setCacheMode(DeviceCoordinateCache);
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ public:
|
|||
|
||||
protected:
|
||||
void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override;
|
||||
void hoverEnterEvent(QGraphicsSceneHoverEvent *event) override;
|
||||
};
|
||||
|
||||
class DeckViewCardDragItem : public AbstractCardDragItem
|
||||
|
|
|
|||
|
|
@ -253,6 +253,51 @@ void GameScene::processViewSizeChange(const QSize &newSize)
|
|||
}
|
||||
}
|
||||
|
||||
void GameScene::updateHover(const QPointF &scenePos)
|
||||
{
|
||||
QList<QGraphicsItem *> itemList =
|
||||
items(scenePos, Qt::IntersectsItemBoundingRect, Qt::DescendingOrder, getViewTransform());
|
||||
|
||||
// Search for the topmost zone and ignore all cards not belonging to that zone.
|
||||
CardZone *zone = 0;
|
||||
for (int i = 0; i < itemList.size(); ++i)
|
||||
if ((zone = qgraphicsitem_cast<CardZone *>(itemList[i])))
|
||||
break;
|
||||
|
||||
CardItem *maxZCard = 0;
|
||||
if (zone) {
|
||||
qreal maxZ = -1;
|
||||
for (int i = 0; i < itemList.size(); ++i) {
|
||||
CardItem *card = qgraphicsitem_cast<CardItem *>(itemList[i]);
|
||||
if (!card)
|
||||
continue;
|
||||
if (card->getAttachedTo()) {
|
||||
if (card->getAttachedTo()->getZone() != zone)
|
||||
continue;
|
||||
} else if (card->getZone() != zone)
|
||||
continue;
|
||||
|
||||
if (card->getRealZValue() > maxZ) {
|
||||
maxZ = card->getRealZValue();
|
||||
maxZCard = card;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (hoveredCard && (maxZCard != hoveredCard))
|
||||
hoveredCard->setHovered(false);
|
||||
if (maxZCard && (maxZCard != hoveredCard))
|
||||
maxZCard->setHovered(true);
|
||||
hoveredCard = maxZCard;
|
||||
}
|
||||
|
||||
bool GameScene::event(QEvent *event)
|
||||
{
|
||||
if (event->type() == QEvent::GraphicsSceneMouseMove)
|
||||
updateHover(static_cast<QGraphicsSceneMouseEvent *>(event)->scenePos());
|
||||
|
||||
return QGraphicsScene::event(event);
|
||||
}
|
||||
|
||||
void GameScene::timerEvent(QTimerEvent * /*event*/)
|
||||
{
|
||||
QMutableSetIterator<CardItem *> i(cardsToAnimate);
|
||||
|
|
|
|||
|
|
@ -30,9 +30,11 @@ private:
|
|||
QList<QList<Player *>> playersByColumn;
|
||||
QList<ZoneViewWidget *> zoneViews;
|
||||
QSize viewSize;
|
||||
QPointer<CardItem> hoveredCard;
|
||||
QBasicTimer *animationTimer;
|
||||
QSet<CardItem *> cardsToAnimate;
|
||||
int playerRotation;
|
||||
void updateHover(const QPointF &scenePos);
|
||||
|
||||
public:
|
||||
explicit GameScene(PhasesToolbar *_phasesToolbar, QObject *parent = nullptr);
|
||||
|
|
@ -63,6 +65,7 @@ public slots:
|
|||
void rearrange();
|
||||
|
||||
protected:
|
||||
bool event(QEvent *event) override;
|
||||
void timerEvent(QTimerEvent *event) override;
|
||||
signals:
|
||||
void sigStartRubberBand(const QPointF &selectionOrigin);
|
||||
|
|
|
|||
|
|
@ -1443,19 +1443,20 @@ void Player::actMoveTopCardsUntil()
|
|||
{
|
||||
stopMoveTopCardsUntil();
|
||||
|
||||
DlgMoveTopCardsUntil dlg(game, movingCardsUntilExpr, movingCardsUntilNumberOfHits, movingCardsUntilAutoPlay);
|
||||
DlgMoveTopCardsUntil dlg(game, movingCardsUntilExprs, movingCardsUntilNumberOfHits, movingCardsUntilAutoPlay);
|
||||
if (!dlg.exec()) {
|
||||
return;
|
||||
}
|
||||
|
||||
movingCardsUntilExpr = dlg.getExpr();
|
||||
auto expr = dlg.getExpr();
|
||||
movingCardsUntilExprs = dlg.getExprs();
|
||||
movingCardsUntilNumberOfHits = dlg.getNumberOfHits();
|
||||
movingCardsUntilAutoPlay = dlg.isAutoPlay();
|
||||
|
||||
if (zones.value("deck")->getCards().empty()) {
|
||||
stopMoveTopCardsUntil();
|
||||
} else {
|
||||
movingCardsUntilFilter = FilterString(movingCardsUntilExpr);
|
||||
movingCardsUntilFilter = FilterString(expr);
|
||||
movingCardsUntilCounter = movingCardsUntilNumberOfHits;
|
||||
movingCardsUntil = true;
|
||||
actMoveTopCardToPlay();
|
||||
|
|
@ -2386,6 +2387,7 @@ void Player::eventMoveCard(const Event_MoveCard &event, const GameEventContext &
|
|||
card->setFaceDown(event.face_down());
|
||||
if (startZone != targetZone) {
|
||||
card->setBeingPointedAt(false);
|
||||
card->setHovered(false);
|
||||
|
||||
const QList<CardItem *> &attachedCards = card->getAttachedCards();
|
||||
for (auto attachedCard : attachedCards) {
|
||||
|
|
|
|||
|
|
@ -279,7 +279,7 @@ private:
|
|||
|
||||
bool movingCardsUntil;
|
||||
QTimer *moveTopCardTimer;
|
||||
QString movingCardsUntilExpr = {};
|
||||
QStringList movingCardsUntilExprs = {};
|
||||
int movingCardsUntilNumberOfHits = 1;
|
||||
bool movingCardsUntilAutoPlay = false;
|
||||
FilterString movingCardsUntilFilter;
|
||||
|
|
|
|||
|
|
@ -139,7 +139,6 @@ void PileZone::mouseReleaseEvent(QGraphicsSceneMouseEvent * /*event*/)
|
|||
void PileZone::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
|
||||
{
|
||||
if (!cards.isEmpty())
|
||||
emit cards[0]->hovered(cards[0]);
|
||||
|
||||
cards[0]->processHoverEvent();
|
||||
QGraphicsItem::hoverEnterEvent(event);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -66,26 +66,25 @@ void StackZone::handleDropEvent(const QList<CardDragItem *> &dragItems, CardZone
|
|||
cmd.set_target_zone(getName().toStdString());
|
||||
|
||||
int index = 0;
|
||||
if (cards.isEmpty()) {
|
||||
index = 0;
|
||||
} else {
|
||||
|
||||
if (!cards.isEmpty()) {
|
||||
const auto cardCount = static_cast<int>(cards.size());
|
||||
const auto &card = cards.at(0);
|
||||
|
||||
if (card == nullptr) {
|
||||
qCWarning(StackZoneLog) << "Attempted to move card from" << startZone->getName() << ", but was null";
|
||||
return;
|
||||
}
|
||||
|
||||
index = qRound(divideCardSpaceInZone(dropPoint.y(), cardCount, boundingRect().height(),
|
||||
card->boundingRect().height(), true));
|
||||
}
|
||||
|
||||
if (startZone == this) {
|
||||
const auto &dragItem = dragItems.at(0);
|
||||
const auto &card = cards.at(index);
|
||||
if (card != nullptr && dragItem != nullptr && card->getId() == dragItem->getId()) {
|
||||
return;
|
||||
// divideCardSpaceInZone is not guaranteed to return a valid index
|
||||
// currently, so clamp it to avoid crashes.
|
||||
index = qBound(0, index, cardCount - 1);
|
||||
|
||||
if (startZone == this) {
|
||||
const auto &dragItem = dragItems.at(0);
|
||||
const auto &card = cards.at(index);
|
||||
|
||||
if (card->getId() == dragItem->getId()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,8 +3,6 @@
|
|||
|
||||
#include "select_zone.h"
|
||||
|
||||
inline Q_LOGGING_CATEGORY(StackZoneLog, "stack_zone");
|
||||
|
||||
class StackZone : public SelectZone
|
||||
{
|
||||
Q_OBJECT
|
||||
|
|
|
|||
|
|
@ -173,9 +173,13 @@ private:
|
|||
{"MainWindow/aWatchReplay", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Watch Replay..."),
|
||||
parseSequenceString(""),
|
||||
ShortcutGroup::Main_Window)},
|
||||
{"TabDeckEditor/aAnalyzeDeck", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Analyze Deck"),
|
||||
{"TabDeckEditor/aAnalyzeDeck", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Analyze Deck (deckstats.net)"),
|
||||
parseSequenceString(""),
|
||||
ShortcutGroup::Deck_Editor)},
|
||||
{"TabDeckEditor/aAnalyzeDeckTappedout",
|
||||
ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Analyze Deck (tappedout.net)"),
|
||||
parseSequenceString(""),
|
||||
ShortcutGroup::Deck_Editor)},
|
||||
{"TabDeckEditor/aClearFilterAll", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Clear All Filters"),
|
||||
parseSequenceString(""),
|
||||
ShortcutGroup::Deck_Editor)},
|
||||
|
|
@ -193,9 +197,14 @@ private:
|
|||
{"TabDeckEditor/aEditTokens", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Edit Custom Tokens..."),
|
||||
parseSequenceString(""),
|
||||
ShortcutGroup::Deck_Editor)},
|
||||
{"TabDeckEditor/aExportDeckDecklist", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Export Deck"),
|
||||
parseSequenceString(""),
|
||||
ShortcutGroup::Deck_Editor)},
|
||||
{"TabDeckEditor/aExportDeckDecklist",
|
||||
ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Export Deck (decklist.org)"),
|
||||
parseSequenceString(""),
|
||||
ShortcutGroup::Deck_Editor)},
|
||||
{"TabDeckEditor/aExportDeckDecklistXyz",
|
||||
ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Export Deck (decklist.xyz)"),
|
||||
parseSequenceString(""),
|
||||
ShortcutGroup::Deck_Editor)},
|
||||
{"TabDeckEditor/aIncrement", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Add Card"),
|
||||
parseSequenceString("+"),
|
||||
ShortcutGroup::Deck_Editor)},
|
||||
|
|
|
|||
|
|
@ -1,6 +1,29 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE TS>
|
||||
<TS version="2.1" language="en_US">
|
||||
<context>
|
||||
<name>BetaReleaseChannel</name>
|
||||
<message>
|
||||
<location filename="../cockatrice/src/client/network/release_channel.cpp" line="210"/>
|
||||
<source>Beta</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../cockatrice/src/client/network/release_channel.cpp" line="236"/>
|
||||
<source>No reply received from the release update server.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../cockatrice/src/client/network/release_channel.cpp" line="245"/>
|
||||
<source>Invalid reply received from the release update server.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../cockatrice/src/client/network/release_channel.cpp" line="278"/>
|
||||
<source>No reply received from the file update server.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>IntroPage</name>
|
||||
<message>
|
||||
|
|
@ -63,7 +86,8 @@
|
|||
</message>
|
||||
<message>
|
||||
<location filename="src/oraclewizard.cpp" line="287"/>
|
||||
<source>Sets JSON file (%1)</source>
|
||||
<source>Sets file (%1)</source>
|
||||
<oldsource>Sets JSON file (%1)</oldsource>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
|
|
@ -247,7 +271,7 @@
|
|||
<context>
|
||||
<name>OracleImporter</name>
|
||||
<message>
|
||||
<location filename="src/oracleimporter.cpp" line="465"/>
|
||||
<location filename="src/oracleimporter.cpp" line="471"/>
|
||||
<source>Dummy set containing tokens</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
|
|
@ -283,6 +307,15 @@
|
|||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>PictureLoader</name>
|
||||
<message>
|
||||
<location filename="../cockatrice/src/client/ui/picture_loader/picture_to_load.cpp" line="219"/>
|
||||
<source>en</source>
|
||||
<comment>code for scryfall's language property, not available for all languages</comment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>SaveSetsPage</name>
|
||||
<message>
|
||||
|
|
@ -357,6 +390,21 @@
|
|||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>ShortcutsSettings</name>
|
||||
<message>
|
||||
<location filename="../cockatrice/src/settings/shortcuts_settings.cpp" line="54"/>
|
||||
<source>Your configuration file contained invalid shortcuts.
|
||||
Please check your shortcut settings!</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../cockatrice/src/settings/shortcuts_settings.cpp" line="56"/>
|
||||
<source>The following shortcuts have been set to default:
|
||||
</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>SimpleDownloadFilePage</name>
|
||||
<message>
|
||||
|
|
@ -392,6 +440,34 @@
|
|||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>StableReleaseChannel</name>
|
||||
<message>
|
||||
<location filename="../cockatrice/src/client/network/release_channel.cpp" line="104"/>
|
||||
<source>Default</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../cockatrice/src/client/network/release_channel.cpp" line="120"/>
|
||||
<source>No reply received from the release update server.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../cockatrice/src/client/network/release_channel.cpp" line="128"/>
|
||||
<source>Invalid reply received from the release update server.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../cockatrice/src/client/network/release_channel.cpp" line="176"/>
|
||||
<source>No reply received from the tag update server.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../cockatrice/src/client/network/release_channel.cpp" line="183"/>
|
||||
<source>Invalid reply received from the tag update server.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>UnZip</name>
|
||||
<message>
|
||||
|
|
@ -537,6 +613,7 @@
|
|||
<name>i18n</name>
|
||||
<message>
|
||||
<location filename="src/oraclewizard.cpp" line="58"/>
|
||||
<location filename="../cockatrice/src/settings/cache_settings.cpp" line="167"/>
|
||||
<source>English</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue