diff --git a/cockatrice/src/abstractcarditem.cpp b/cockatrice/src/abstractcarditem.cpp index 62be0113..4489ee21 100644 --- a/cockatrice/src/abstractcarditem.cpp +++ b/cockatrice/src/abstractcarditem.cpp @@ -3,13 +3,16 @@ #include #include #include +#include #include "carddatabase.h" #include "abstractcarditem.h" +#include "settingscache.h" #include "main.h" #include +#include AbstractCardItem::AbstractCardItem(const QString &_name, Player *_owner, QGraphicsItem *parent) - : ArrowTarget(_owner, parent), info(db->getCard(_name)), name(_name), tapped(false) + : ArrowTarget(_owner, parent), info(db->getCard(_name)), name(_name), tapped(false), tapAngle(0) { setCursor(Qt::OpenHandCursor); setFlag(ItemIsSelectable); @@ -17,6 +20,10 @@ AbstractCardItem::AbstractCardItem(const QString &_name, Player *_owner, QGraphi setCacheMode(DeviceCoordinateCache); connect(info, SIGNAL(pixmapUpdated()), this, SLOT(pixmapUpdated())); + + animationTimer = new QTimer(this); + animationTimer->setSingleShot(false); + connect(animationTimer, SIGNAL(timeout()), this, SLOT(animationEvent())); } AbstractCardItem::~AbstractCardItem() @@ -37,19 +44,22 @@ void AbstractCardItem::pixmapUpdated() void AbstractCardItem::paint(QPainter *painter, const QStyleOptionGraphicsItem */*option*/, QWidget */*widget*/) { painter->save(); - QSizeF translatedSize = painter->combinedTransform().mapRect(boundingRect()).size(); - if (tapped) - translatedSize.transpose(); + qreal w = painter->combinedTransform().map(QLineF(0, 0, boundingRect().width(), 0)).length(); + qreal h = painter->combinedTransform().map(QLineF(0, 0, 0, boundingRect().height())).length(); + QSizeF translatedSize(w, h); + QRectF totalBoundingRect = painter->combinedTransform().mapRect(boundingRect()); QPixmap *translatedPixmap = info->getPixmap(translatedSize.toSize()); painter->save(); if (translatedPixmap) { painter->resetTransform(); - if (tapped) { - painter->translate(((qreal) translatedSize.height()) / 2, ((qreal) translatedSize.width()) / 2); - painter->rotate(90); - painter->translate(-((qreal) translatedSize.width()) / 2, -((qreal) translatedSize.height()) / 2); - } - painter->drawPixmap(translatedPixmap->rect(), *translatedPixmap, translatedPixmap->rect()); + QTransform pixmapTransform; + pixmapTransform.translate(totalBoundingRect.width() / 2, totalBoundingRect.height() / 2); + pixmapTransform.rotate(tapAngle); + QPointF transPoint = QPointF(-w / 2, -h / 2); + pixmapTransform.translate(transPoint.x(), transPoint.y()); + painter->setTransform(pixmapTransform); + + painter->drawPixmap(QPointF(0, 0), *translatedPixmap); } else { QFont f("Times"); f.setStyleHint(QFont::Serif); @@ -105,6 +115,21 @@ void AbstractCardItem::paint(QPainter *painter, const QStyleOptionGraphicsItem * painter->restore(); } +void AbstractCardItem::animationEvent() +{ + int delta = 10; + if (!tapped) + delta *= -1; + + tapAngle += delta; + + setTransform(QTransform().translate((float) CARD_WIDTH / 2, (float) CARD_HEIGHT / 2).rotate(tapAngle).translate((float) -CARD_WIDTH / 2, (float) -CARD_HEIGHT / 2)); + update(); + + if ((tapped && (tapAngle >= 90)) || (!tapped && (tapAngle <= 0))) + animationTimer->stop(); +} + void AbstractCardItem::setName(const QString &_name) { disconnect(info, 0, this, 0); @@ -120,14 +145,19 @@ void AbstractCardItem::setColor(const QString &_color) update(); } -void AbstractCardItem::setTapped(bool _tapped) +void AbstractCardItem::setTapped(bool _tapped, bool canAnimate) { + if (tapped == _tapped) + return; + tapped = _tapped; - if (tapped) - setTransform(QTransform().translate((float) CARD_WIDTH / 2, (float) CARD_HEIGHT / 2).rotate(90).translate((float) -CARD_WIDTH / 2, (float) -CARD_HEIGHT / 2)); - else - setTransform(QTransform()); - update(); + if (settingsCache->getTapAnimation() && canAnimate) + animationTimer->start(25); + else { + tapAngle = tapped ? 90 : 0; + setTransform(QTransform().translate((float) CARD_WIDTH / 2, (float) CARD_HEIGHT / 2).rotate(tapAngle).translate((float) -CARD_WIDTH / 2, (float) -CARD_HEIGHT / 2)); + update(); + } } void AbstractCardItem::mousePressEvent(QGraphicsSceneMouseEvent *event) diff --git a/cockatrice/src/abstractcarditem.h b/cockatrice/src/abstractcarditem.h index 6d77f6f3..d87ba1a9 100644 --- a/cockatrice/src/abstractcarditem.h +++ b/cockatrice/src/abstractcarditem.h @@ -5,6 +5,7 @@ class CardInfo; class Player; +class QTimer; const int CARD_WIDTH = 72; const int CARD_HEIGHT = 102; @@ -15,8 +16,12 @@ protected: CardInfo *info; QString name; bool tapped; + int tapAngle; QString color; +private: + QTimer *animationTimer; private slots: + void animationEvent(); void pixmapUpdated(); signals: void hovered(AbstractCardItem *card); @@ -33,7 +38,7 @@ public: QString getColor() const { return color; } void setColor(const QString &_color); bool getTapped() const { return tapped; } - void setTapped(bool _tapped); + void setTapped(bool _tapped, bool canAnimate = false); void processHoverEvent(); protected: void mousePressEvent(QGraphicsSceneMouseEvent *event); diff --git a/cockatrice/src/carddatabase.cpp b/cockatrice/src/carddatabase.cpp index 2d1bc248..4bb24da5 100644 --- a/cockatrice/src/carddatabase.cpp +++ b/cockatrice/src/carddatabase.cpp @@ -252,6 +252,7 @@ CardDatabase::CardDatabase(QObject *parent) CardDatabase::~CardDatabase() { clear(); + delete noCard; } void CardDatabase::clear() diff --git a/cockatrice/src/dlg_settings.cpp b/cockatrice/src/dlg_settings.cpp index d7365adb..a27d4b37 100644 --- a/cockatrice/src/dlg_settings.cpp +++ b/cockatrice/src/dlg_settings.cpp @@ -202,12 +202,12 @@ AppearanceSettingsPage::AppearanceSettingsPage() handGroupBox = new QGroupBox; handGroupBox->setLayout(handGrid); - economicGridCheckBox = new QCheckBox; - economicGridCheckBox->setChecked(settingsCache->getEconomicGrid()); - connect(economicGridCheckBox, SIGNAL(stateChanged(int)), settingsCache, SLOT(setEconomicGrid(int))); + economicalGridCheckBox = new QCheckBox; + economicalGridCheckBox->setChecked(settingsCache->getEconomicalGrid()); + connect(economicalGridCheckBox, SIGNAL(stateChanged(int)), settingsCache, SLOT(setEconomicalGrid(int))); QGridLayout *tableGrid = new QGridLayout; - tableGrid->addWidget(economicGridCheckBox, 0, 0, 1, 2); + tableGrid->addWidget(economicalGridCheckBox, 0, 0, 1, 2); tableGroupBox = new QGroupBox; tableGroupBox->setLayout(tableGrid); @@ -248,7 +248,7 @@ void AppearanceSettingsPage::retranslateUi() horizontalHandCheckBox->setText(tr("Display hand horizontally (wastes space)")); tableGroupBox->setTitle(tr("Table grid layout")); - economicGridCheckBox->setText(tr("Economic layout")); + economicalGridCheckBox->setText(tr("Economical layout")); zoneViewGroupBox->setTitle(tr("Zone view layout")); zoneViewSortByNameCheckBox->setText(tr("Sort by name")); @@ -307,8 +307,19 @@ UserInterfaceSettingsPage::UserInterfaceSettingsPage() generalGroupBox = new QGroupBox; generalGroupBox->setLayout(generalGrid); + tapAnimationCheckBox = new QCheckBox; + tapAnimationCheckBox->setChecked(settingsCache->getTapAnimation()); + connect(tapAnimationCheckBox, SIGNAL(stateChanged(int)), settingsCache, SLOT(setTapAnimation(int))); + + QGridLayout *animationGrid = new QGridLayout; + animationGrid->addWidget(tapAnimationCheckBox, 0, 0); + + animationGroupBox = new QGroupBox; + animationGroupBox->setLayout(animationGrid); + QVBoxLayout *mainLayout = new QVBoxLayout; mainLayout->addWidget(generalGroupBox); + mainLayout->addWidget(animationGroupBox); setLayout(mainLayout); } @@ -317,6 +328,8 @@ void UserInterfaceSettingsPage::retranslateUi() { generalGroupBox->setTitle(tr("General interface settings")); doubleClickToPlayCheckBox->setText(tr("&Double-click cards to play them (instead of single-click)")); + animationGroupBox->setTitle(tr("Animation settings")); + tapAnimationCheckBox->setText(tr("&Tap/untap animation")); } MessagesSettingsPage::MessagesSettingsPage() diff --git a/cockatrice/src/dlg_settings.h b/cockatrice/src/dlg_settings.h index b8575fb9..f9cb71a1 100644 --- a/cockatrice/src/dlg_settings.h +++ b/cockatrice/src/dlg_settings.h @@ -60,7 +60,7 @@ signals: private: QLabel *handBgLabel, *tableBgLabel, *playerAreaBgLabel, *cardBackPicturePathLabel; QLineEdit *handBgEdit, *tableBgEdit, *playerAreaBgEdit, *cardBackPicturePathEdit; - QCheckBox *horizontalHandCheckBox, *economicGridCheckBox, *zoneViewSortByNameCheckBox, *zoneViewSortByTypeCheckBox; + QCheckBox *horizontalHandCheckBox, *economicalGridCheckBox, *zoneViewSortByNameCheckBox, *zoneViewSortByTypeCheckBox; QGroupBox *zoneBgGroupBox, *handGroupBox, *tableGroupBox, *zoneViewGroupBox; public: AppearanceSettingsPage(); @@ -71,7 +71,8 @@ class UserInterfaceSettingsPage : public AbstractSettingsPage { Q_OBJECT private: QCheckBox *doubleClickToPlayCheckBox; - QGroupBox *generalGroupBox; + QCheckBox *tapAnimationCheckBox; + QGroupBox *generalGroupBox, *animationGroupBox; public: UserInterfaceSettingsPage(); void retranslateUi(); diff --git a/cockatrice/src/player.cpp b/cockatrice/src/player.cpp index 8eee6880..dd7e56aa 100644 --- a/cockatrice/src/player.cpp +++ b/cockatrice/src/player.cpp @@ -526,7 +526,7 @@ void Player::setCardAttrHelper(CardItem *card, const QString &aname, const QStri if (!(!tapped && card->getDoesntUntap() && allCards)) { if (!allCards) emit logSetTapped(this, card->getName(), tapped); - card->setTapped(tapped); + card->setTapped(tapped, true); } } else if (aname == "attacking") card->setAttacking(avalue == "1"); diff --git a/cockatrice/src/settingscache.cpp b/cockatrice/src/settingscache.cpp index 3d291f7e..177d119a 100644 --- a/cockatrice/src/settingscache.cpp +++ b/cockatrice/src/settingscache.cpp @@ -19,7 +19,8 @@ SettingsCache::SettingsCache() picDownload = settings->value("personal/picturedownload", false).toBool(); doubleClickToPlay = settings->value("interface/doubleclicktoplay", true).toBool(); horizontalHand = settings->value("hand/horizontal", false).toBool(); - economicGrid = settings->value("table/economic", false).toBool(); + economicalGrid = settings->value("table/economic", false).toBool(); + tapAnimation = settings->value("cards/tapanimation", true).toBool(); zoneViewSortByName = settings->value("zoneview/sortbyname", false).toBool(); zoneViewSortByType = settings->value("zoneview/sortbytype", false).toBool(); @@ -100,11 +101,17 @@ void SettingsCache::setHorizontalHand(int _horizontalHand) emit horizontalHandChanged(); } -void SettingsCache::setEconomicGrid(int _economicGrid) +void SettingsCache::setEconomicalGrid(int _economicalGrid) { - economicGrid = _economicGrid; - settings->setValue("table/economic", economicGrid); - emit economicGridChanged(); + economicalGrid = _economicalGrid; + settings->setValue("table/economic", economicalGrid); + emit economicalGridChanged(); +} + +void SettingsCache::setTapAnimation(int _tapAnimation) +{ + tapAnimation = _tapAnimation; + settings->setValue("cards/tapanimation", tapAnimation); } void SettingsCache::setZoneViewSortByName(int _zoneViewSortByName) diff --git a/cockatrice/src/settingscache.h b/cockatrice/src/settingscache.h index d501d44b..2232ef99 100644 --- a/cockatrice/src/settingscache.h +++ b/cockatrice/src/settingscache.h @@ -17,7 +17,7 @@ signals: void cardBackPicturePathChanged(); void picDownloadChanged(); void horizontalHandChanged(); - void economicGridChanged(); + void economicalGridChanged(); private: QSettings *settings; @@ -27,7 +27,8 @@ private: bool picDownload; bool doubleClickToPlay; bool horizontalHand; - bool economicGrid; + bool economicalGrid; + bool tapAnimation; bool zoneViewSortByName, zoneViewSortByType; public: SettingsCache(); @@ -42,7 +43,8 @@ public: bool getPicDownload() const { return picDownload; } bool getDoubleClickToPlay() const { return doubleClickToPlay; } bool getHorizontalHand() const { return horizontalHand; } - bool getEconomicGrid() const { return economicGrid; } + bool getEconomicalGrid() const { return economicalGrid; } + bool getTapAnimation() const { return tapAnimation; } bool getZoneViewSortByName() const { return zoneViewSortByName; } bool getZoneViewSortByType() const { return zoneViewSortByType; } public slots: @@ -57,7 +59,8 @@ public slots: void setPicDownload(int _picDownload); void setDoubleClickToPlay(int _doubleClickToPlay); void setHorizontalHand(int _horizontalHand); - void setEconomicGrid(int _economicGrid); + void setEconomicalGrid(int _economicalGrid); + void setTapAnimation(int _tapAnimation); void setZoneViewSortByName(int _zoneViewSortByName); void setZoneViewSortByType(int _zoneViewSortByType); }; diff --git a/cockatrice/src/tablezone.cpp b/cockatrice/src/tablezone.cpp index 139bed6e..9593105f 100644 --- a/cockatrice/src/tablezone.cpp +++ b/cockatrice/src/tablezone.cpp @@ -12,10 +12,10 @@ TableZone::TableZone(Player *_p, QGraphicsItem *parent) : CardZone(_p, "table", true, false, true, parent), active(false) { connect(settingsCache, SIGNAL(tableBgPathChanged()), this, SLOT(updateBgPixmap())); - connect(settingsCache, SIGNAL(economicGridChanged()), this, SLOT(reorganizeCards())); + connect(settingsCache, SIGNAL(economicalGridChanged()), this, SLOT(reorganizeCards())); updateBgPixmap(); - if (settingsCache->getEconomicGrid()) + if (settingsCache->getEconomicalGrid()) height = 2 * boxLineWidth + (int) (14.0 / 3 * CARD_HEIGHT + 3 * paddingY); else height = 2 * boxLineWidth + 4 * CARD_HEIGHT + 3 * paddingY; @@ -210,7 +210,7 @@ CardItem *TableZone::getCardFromCoords(const QPointF &point) const QPointF TableZone::mapFromGrid(const QPoint &gridPoint) const { qreal x, y; - if ((gridPoint.y() == 3) && (settingsCache->getEconomicGrid())) { + if ((gridPoint.y() == 3) && (settingsCache->getEconomicalGrid())) { x = marginX + (CARD_WIDTH * gridPoint.x() + CARD_WIDTH * (gridPoint.x() / 3)) / 2; y = boxLineWidth + (CARD_HEIGHT + paddingY) * gridPoint.y() + (gridPoint.x() % 3 * CARD_HEIGHT) / 3; } else { @@ -245,7 +245,7 @@ QPoint TableZone::mapToGrid(const QPointF &mapPoint) const int resultY = (int) (y / (CARD_HEIGHT + paddingY)); - if ((resultY == 3) && (settingsCache->getEconomicGrid())) + if ((resultY == 3) && (settingsCache->getEconomicalGrid())) return QPoint( (int) (x * 2 / CARD_WIDTH - floor(x / (2 * CARD_WIDTH))), 3