mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-08-19 23:34:59 -05:00
[Game] Animate Arrows (#7099)
* Add an arrow draw animation setting - New arrowDrawAnimation cards-display setting, default on - The arrow draw animation checkbox joins the animation settings group - Visual Deck Storage selection animation checkbox moves next to the other animation checkboxes, and the enable/disable-all buttons now cover it and the arrow animation Took 2 minutes Took 21 minutes Took 7 minutes Took 11 minutes Took 20 seconds * Animate arrows drawing from start to target - The arrow stroke reveals itself along the arc with an eased timing, followed by a short light sheen that sweeps down the shaft - The arrow head pops in once the reveal reaches it, then the whole arrow fades from its initial glow - Decay is driven by GameScene's shared animation timer through the IAnimatedItem interface (QElapsedTimer based), respecting the arrowDrawAnimation setting - GameScene adds the arrow item to the scene before starting its animation so the item is registered against a valid scene Took 6 minutes Took 1 minute * Defer animation start so arrows don't start halfway materialized Took 13 minutes * Don't draw tip/shaft outline Took 12 minutes --------- Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
This commit is contained in:
@@ -4,12 +4,14 @@
|
||||
#include "../../client/settings/cache_settings.h"
|
||||
#include "../../game/player/player_actions.h"
|
||||
#include "../../game/player/player_logic.h"
|
||||
#include "../game_scene.h"
|
||||
#include "../player/player_target.h"
|
||||
#include "../z_values.h"
|
||||
#include "../zones/card_zone.h"
|
||||
#include "card_item.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QElapsedTimer>
|
||||
#include <QGraphicsScene>
|
||||
#include <QGraphicsSceneMouseEvent>
|
||||
#include <QPainter>
|
||||
@@ -18,10 +20,27 @@
|
||||
#include <libcockatrice/protocol/pb/command_attach_card.pb.h>
|
||||
#include <libcockatrice/protocol/pb/command_create_arrow.pb.h>
|
||||
#include <libcockatrice/protocol/pb/command_delete_arrow.pb.h>
|
||||
#include <libcockatrice/settings/cards_display_settings.h>
|
||||
#include <libcockatrice/settings/interface_settings.h>
|
||||
#include <libcockatrice/utility/color.h>
|
||||
#include <libcockatrice/utility/zone_names.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
constexpr qreal kMinStrokeDurationMs = 200.0;
|
||||
constexpr qreal kMaxStrokeDurationMs = 450.0;
|
||||
constexpr qreal kMsPerPixel = 0.8;
|
||||
constexpr qreal kGlowFadeDurationMs = 120.0;
|
||||
constexpr qreal kSheenHalfWidth = 14.0;
|
||||
|
||||
/// @brief Ease-out cubic, for a natural "slow in / slow out" reveal.
|
||||
qreal easeOutCubic(qreal t)
|
||||
{
|
||||
const qreal inverse = 1.0 - t;
|
||||
return 1.0 - inverse * inverse * inverse;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
ArrowItem::ArrowItem(QSharedPointer<const ArrowData> _data, ArrowTarget *_startItem, ArrowTarget *_targetItem)
|
||||
: data(std::move(_data)), startItem(_startItem), targetItem(_targetItem)
|
||||
{
|
||||
@@ -47,6 +66,13 @@ ArrowItem::ArrowItem(QSharedPointer<const ArrowData> _data, ArrowTarget *_startI
|
||||
}
|
||||
}
|
||||
|
||||
ArrowItem::~ArrowItem()
|
||||
{
|
||||
if (auto *scene = qobject_cast<GameScene *>(this->scene())) {
|
||||
scene->unregisterAnimationItem(this);
|
||||
}
|
||||
}
|
||||
|
||||
void ArrowItem::onTargetDestroyed()
|
||||
{
|
||||
emit requestDeletion(data->creatorId, data->id);
|
||||
@@ -91,16 +117,21 @@ void ArrowItem::updatePath(const QPointF &endPoint)
|
||||
prepareGeometryChange();
|
||||
if (lineLength < 30) {
|
||||
path = QPainterPath();
|
||||
bodyPath = QPainterPath();
|
||||
headPath = QPainterPath();
|
||||
shaftOutlinePath = QPainterPath();
|
||||
centerLine = QPainterPath();
|
||||
headBaseFraction = 1.0;
|
||||
} else {
|
||||
QPointF c(lineLength / 2, qTan(phi * M_PI / 180) * lineLength);
|
||||
|
||||
QPainterPath centerLine;
|
||||
centerLine = QPainterPath();
|
||||
centerLine.moveTo(0, 0);
|
||||
centerLine.quadTo(c, QPointF(lineLength, 0));
|
||||
|
||||
double percentage = 1 - headLength / lineLength;
|
||||
QPointF arrowBodyEndPoint = centerLine.pointAtPercent(percentage);
|
||||
QLineF testLine(arrowBodyEndPoint, centerLine.pointAtPercent(percentage + 0.001));
|
||||
headBaseFraction = 1 - headLength / lineLength;
|
||||
QPointF arrowBodyEndPoint = centerLine.pointAtPercent(headBaseFraction);
|
||||
QLineF testLine(arrowBodyEndPoint, centerLine.pointAtPercent(headBaseFraction + 0.001));
|
||||
qreal alpha = testLine.angle() - 90;
|
||||
QPointF endPoint1 =
|
||||
arrowBodyEndPoint + arrowWidth / 2 * QPointF(qCos(alpha * M_PI / 180), -qSin(alpha * M_PI / 180));
|
||||
@@ -111,20 +142,89 @@ void ArrowItem::updatePath(const QPointF &endPoint)
|
||||
QPointF point2 =
|
||||
endPoint2 + (headWidth - arrowWidth) / 2 * QPointF(-qCos(alpha * M_PI / 180), qSin(alpha * M_PI / 180));
|
||||
|
||||
path = QPainterPath(-arrowWidth / 2 * QPointF(qCos((phi - 90) * M_PI / 180), qSin((phi - 90) * M_PI / 180)));
|
||||
QPointF start1 = -arrowWidth / 2 * QPointF(qCos((phi - 90) * M_PI / 180), qSin((phi - 90) * M_PI / 180));
|
||||
QPointF start2 = arrowWidth / 2 * QPointF(qCos((phi - 90) * M_PI / 180), qSin((phi - 90) * M_PI / 180));
|
||||
|
||||
path = QPainterPath(start1);
|
||||
path.quadTo(c, endPoint1);
|
||||
path.lineTo(point1);
|
||||
path.lineTo(QPointF(lineLength, 0));
|
||||
path.lineTo(point2);
|
||||
path.lineTo(endPoint2);
|
||||
path.quadTo(c, arrowWidth / 2 * QPointF(qCos((phi - 90) * M_PI / 180), qSin((phi - 90) * M_PI / 180)));
|
||||
path.lineTo(-arrowWidth / 2 * QPointF(qCos((phi - 90) * M_PI / 180), qSin((phi - 90) * M_PI / 180)));
|
||||
path.quadTo(c, start2);
|
||||
path.lineTo(start1);
|
||||
|
||||
bodyPath = QPainterPath(start1);
|
||||
bodyPath.quadTo(c, endPoint1);
|
||||
bodyPath.lineTo(endPoint2);
|
||||
bodyPath.quadTo(c, start2);
|
||||
bodyPath.lineTo(start1);
|
||||
|
||||
headPath = QPainterPath(endPoint1);
|
||||
headPath.lineTo(point1);
|
||||
headPath.lineTo(QPointF(lineLength, 0));
|
||||
headPath.lineTo(point2);
|
||||
headPath.lineTo(endPoint2);
|
||||
|
||||
shaftOutlinePath = QPainterPath(start1);
|
||||
shaftOutlinePath.quadTo(c, endPoint1);
|
||||
shaftOutlinePath.moveTo(endPoint2);
|
||||
shaftOutlinePath.quadTo(c, start2);
|
||||
shaftOutlinePath.lineTo(start1);
|
||||
}
|
||||
|
||||
setPos(startPoint);
|
||||
setTransform(QTransform().rotate(-line.angle()));
|
||||
}
|
||||
|
||||
void ArrowItem::startDrawAnimation()
|
||||
{
|
||||
if (!SettingsCache::instance().cardsDisplay().getArrowDrawAnimation() || centerLine.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
strokeDurationMs = qBound(kMinStrokeDurationMs, centerLine.length() * kMsPerPixel, kMaxStrokeDurationMs);
|
||||
glowFadeDurationMs = kGlowFadeDurationMs;
|
||||
// The clock is started on the first animationEvent() tick so that t=0
|
||||
// corresponds to the first rendered frame. Starting it here would count
|
||||
// the time spent before the item's first paint (event-loop delays, bursts
|
||||
// of arrows created together), making the arrow appear already partway
|
||||
// drawn when it first shows up.
|
||||
animationStarted = false;
|
||||
drawProgress = 0.0;
|
||||
glowAlpha = 1.0;
|
||||
update();
|
||||
if (auto *scene = qobject_cast<GameScene *>(this->scene())) {
|
||||
scene->registerAnimationItem(this);
|
||||
}
|
||||
}
|
||||
|
||||
bool ArrowItem::animationEvent()
|
||||
{
|
||||
if (!animationStarted) {
|
||||
animationClock.start();
|
||||
animationStarted = true;
|
||||
}
|
||||
|
||||
const qint64 elapsed = animationClock.elapsed();
|
||||
if (elapsed >= strokeDurationMs + glowFadeDurationMs) {
|
||||
drawProgress = 1.0;
|
||||
glowAlpha = 0.0;
|
||||
update();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (elapsed < strokeDurationMs) {
|
||||
drawProgress = easeOutCubic(qBound<qreal>(0.0, elapsed / strokeDurationMs, 1.0));
|
||||
glowAlpha = 1.0;
|
||||
} else {
|
||||
drawProgress = 1.0;
|
||||
glowAlpha = 1.0 - (elapsed - strokeDurationMs) / glowFadeDurationMs;
|
||||
}
|
||||
update();
|
||||
return true;
|
||||
}
|
||||
|
||||
void ArrowItem::paint(QPainter *painter, const QStyleOptionGraphicsItem * /*option*/, QWidget * /*widget*/)
|
||||
{
|
||||
QColor paintColor(data->color);
|
||||
@@ -133,8 +233,66 @@ void ArrowItem::paint(QPainter *painter, const QStyleOptionGraphicsItem * /*opti
|
||||
} else {
|
||||
paintColor.setAlpha(150);
|
||||
}
|
||||
|
||||
painter->save();
|
||||
const QPen outlinePen = painter->pen();
|
||||
painter->setBrush(paintColor);
|
||||
painter->drawPath(path);
|
||||
|
||||
const auto drawShaft = [this, painter, &outlinePen, paintColor]() {
|
||||
painter->setPen(Qt::NoPen);
|
||||
painter->drawPath(bodyPath);
|
||||
painter->setPen(outlinePen);
|
||||
painter->setBrush(Qt::NoBrush);
|
||||
painter->drawPath(shaftOutlinePath);
|
||||
painter->setBrush(paintColor);
|
||||
};
|
||||
|
||||
if (drawProgress >= 1.0 || path.isEmpty()) {
|
||||
painter->drawPath(path);
|
||||
} else if (drawProgress < headBaseFraction) {
|
||||
// The reveal edge and the sheen share the same arc-length parameterization,
|
||||
// so the stroke stays exactly in sync with the trailing sheen.
|
||||
const qreal revealX = centerLine.pointAtPercent(drawProgress).x();
|
||||
QPainterPath clip;
|
||||
clip.addRect(QRectF(-glowExtent, path.boundingRect().top() - glowExtent, revealX + glowExtent,
|
||||
path.boundingRect().height() + 2 * glowExtent));
|
||||
painter->setClipPath(clip);
|
||||
drawShaft();
|
||||
} else {
|
||||
// Once the reveal reaches the head base, pop the whole head in with a fade
|
||||
// instead of slicing the triangle into a growing stub.
|
||||
drawShaft();
|
||||
const qreal headFadeIn = (drawProgress - headBaseFraction) / (1.0 - headBaseFraction);
|
||||
painter->setOpacity(headFadeIn);
|
||||
painter->setPen(Qt::NoPen);
|
||||
painter->drawPath(headPath);
|
||||
painter->setPen(outlinePen);
|
||||
painter->setBrush(Qt::NoBrush);
|
||||
painter->drawPath(headPath);
|
||||
painter->setOpacity(1.0);
|
||||
painter->setBrush(paintColor);
|
||||
}
|
||||
|
||||
if (glowAlpha > 0.0 && !centerLine.isEmpty()) {
|
||||
// Sweep a bright band across the arrow. Clipping to the
|
||||
// silhouette keeps it flat against the shaft so it reads as a light reflection.
|
||||
const qreal anticipation = qMin<qreal>(1.0, drawProgress / 0.08);
|
||||
const QPointF sweep = centerLine.pointAtPercent(qMin<qreal>(drawProgress, 1.0));
|
||||
QLinearGradient sheen(sweep.x() - kSheenHalfWidth, 0.0, sweep.x() + kSheenHalfWidth, 0.0);
|
||||
sheen.setColorAt(0.0, QColor(paintColor.red(), paintColor.green(), paintColor.blue(), 0));
|
||||
sheen.setColorAt(0.5, QColor(255, 255, 255, 200));
|
||||
sheen.setColorAt(1.0, QColor(paintColor.red(), paintColor.green(), paintColor.blue(), 0));
|
||||
painter->save();
|
||||
painter->setPen(Qt::NoPen);
|
||||
painter->setClipPath(path);
|
||||
painter->setBrush(sheen);
|
||||
painter->setOpacity(glowAlpha * anticipation);
|
||||
painter->drawRect(QRectF(sweep.x() - kSheenHalfWidth - glowExtent, path.boundingRect().top() - glowExtent,
|
||||
(kSheenHalfWidth + glowExtent) * 2.0,
|
||||
path.boundingRect().height() + glowExtent * 2.0));
|
||||
painter->restore();
|
||||
}
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
void ArrowItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
|
||||
|
||||
@@ -2,9 +2,12 @@
|
||||
#define ARROWITEM_H
|
||||
|
||||
#include "../../game/board/arrow_data.h"
|
||||
#include "../animated_item.h"
|
||||
#include "arrow_target.h"
|
||||
|
||||
#include <QElapsedTimer>
|
||||
#include <QGraphicsItem>
|
||||
#include <QPainterPath>
|
||||
#include <QPointer>
|
||||
#include <QSharedPointer>
|
||||
|
||||
@@ -12,7 +15,7 @@ class CardItem;
|
||||
class QGraphicsSceneMouseEvent;
|
||||
class PlayerLogic;
|
||||
|
||||
class ArrowItem : public QObject, public QGraphicsItem
|
||||
class ArrowItem : public QObject, public QGraphicsItem, public IAnimatedItem
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(QGraphicsItem)
|
||||
@@ -21,6 +24,19 @@ signals:
|
||||
|
||||
private:
|
||||
QPainterPath path;
|
||||
QPainterPath bodyPath;
|
||||
QPainterPath headPath;
|
||||
QPainterPath shaftOutlinePath;
|
||||
QPainterPath centerLine;
|
||||
qreal headBaseFraction = 1.0;
|
||||
QElapsedTimer animationClock;
|
||||
qreal strokeDurationMs = 0;
|
||||
qreal glowFadeDurationMs = 0;
|
||||
qreal drawProgress = 1.0;
|
||||
qreal glowAlpha = 0.0;
|
||||
bool animationStarted = false;
|
||||
|
||||
static constexpr qreal glowExtent = 12.0;
|
||||
|
||||
protected:
|
||||
QSharedPointer<const ArrowData> data;
|
||||
@@ -33,16 +49,19 @@ protected:
|
||||
|
||||
public:
|
||||
ArrowItem(QSharedPointer<const ArrowData> _data, ArrowTarget *_startItem, ArrowTarget *_targetItem);
|
||||
~ArrowItem() override;
|
||||
|
||||
void onTargetDestroyed();
|
||||
void delArrow();
|
||||
void updatePath();
|
||||
void updatePath(const QPointF &endPoint);
|
||||
void startDrawAnimation();
|
||||
bool animationEvent() override;
|
||||
|
||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
|
||||
[[nodiscard]] QRectF boundingRect() const override
|
||||
{
|
||||
return path.boundingRect();
|
||||
return path.boundingRect().adjusted(-glowExtent, -glowExtent, glowExtent, glowExtent);
|
||||
}
|
||||
[[nodiscard]] QPainterPath shape() const override
|
||||
{
|
||||
@@ -106,4 +125,4 @@ protected:
|
||||
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override;
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -502,6 +502,7 @@ void GameScene::addArrow(QSharedPointer<ArrowData> data)
|
||||
|
||||
auto *arrow = new ArrowItem(data, startCard, targetItem);
|
||||
addItem(arrow);
|
||||
arrow->startDrawAnimation();
|
||||
arrowRegistry.insert(data, arrow);
|
||||
connect(arrow, &ArrowItem::requestDeletion, this, &GameScene::requestArrowDeletion);
|
||||
}
|
||||
|
||||
@@ -116,6 +116,10 @@ UserInterfaceSettingsPage::UserInterfaceSettingsPage()
|
||||
connect(&tapAnimationCheckBox, &QCheckBox::QT_STATE_CHANGED, &SettingsCache::instance().cardsDisplay(),
|
||||
&CardsDisplaySettings::setTapAnimation);
|
||||
|
||||
arrowDrawAnimationCheckBox.setChecked(SettingsCache::instance().cardsDisplay().getArrowDrawAnimation());
|
||||
connect(&arrowDrawAnimationCheckBox, &QCheckBox::QT_STATE_CHANGED, &SettingsCache::instance().cardsDisplay(),
|
||||
&CardsDisplaySettings::setArrowDrawAnimation);
|
||||
|
||||
lifeCounterAnimationsCheckBox.setChecked(
|
||||
SettingsCache::instance().userInterface().getLifeCounterAnimationsEnabled());
|
||||
connect(&lifeCounterAnimationsCheckBox, &QCheckBox::QT_STATE_CHANGED, &SettingsCache::instance().userInterface(),
|
||||
@@ -132,8 +136,9 @@ UserInterfaceSettingsPage::UserInterfaceSettingsPage()
|
||||
animationGrid->addWidget(&enableAllAnimationsButton, 0, 0);
|
||||
animationGrid->addWidget(&disableAllAnimationsButton, 0, 1);
|
||||
animationGrid->addWidget(&tapAnimationCheckBox, 1, 0);
|
||||
animationGrid->addWidget(&lifeCounterAnimationsCheckBox, 2, 0);
|
||||
animationGrid->addWidget(&battlefieldFlashCheckBox, 3, 0);
|
||||
animationGrid->addWidget(&arrowDrawAnimationCheckBox, 2, 0);
|
||||
animationGrid->addWidget(&lifeCounterAnimationsCheckBox, 3, 0);
|
||||
animationGrid->addWidget(&battlefieldFlashCheckBox, 4, 0);
|
||||
|
||||
animationGroupBox = new QGroupBox;
|
||||
animationGroupBox->setLayout(animationGrid);
|
||||
@@ -287,6 +292,7 @@ void UserInterfaceSettingsPage::setNotificationEnabled(QT_STATE_CHANGED_T i)
|
||||
void UserInterfaceSettingsPage::enableAllAnimations()
|
||||
{
|
||||
tapAnimationCheckBox.setChecked(true);
|
||||
arrowDrawAnimationCheckBox.setChecked(true);
|
||||
lifeCounterAnimationsCheckBox.setChecked(true);
|
||||
battlefieldFlashCheckBox.setChecked(true);
|
||||
}
|
||||
@@ -294,6 +300,7 @@ void UserInterfaceSettingsPage::enableAllAnimations()
|
||||
void UserInterfaceSettingsPage::disableAllAnimations()
|
||||
{
|
||||
tapAnimationCheckBox.setChecked(false);
|
||||
arrowDrawAnimationCheckBox.setChecked(false);
|
||||
lifeCounterAnimationsCheckBox.setChecked(false);
|
||||
battlefieldFlashCheckBox.setChecked(false);
|
||||
}
|
||||
@@ -343,6 +350,7 @@ void UserInterfaceSettingsPage::retranslateUi()
|
||||
enableAllAnimationsButton.setText(tr("&Enable all animations"));
|
||||
disableAllAnimationsButton.setText(tr("&Disable all animations"));
|
||||
tapAnimationCheckBox.setText(tr("&Tap/untap animation"));
|
||||
arrowDrawAnimationCheckBox.setText(tr("&Arrow draw animation"));
|
||||
lifeCounterAnimationsCheckBox.setText(tr("Life counter flash"));
|
||||
battlefieldFlashCheckBox.setText(tr("Battlefield flash on damage"));
|
||||
deckEditorGroupBox->setTitle(tr("Deck editor/storage settings"));
|
||||
|
||||
@@ -40,6 +40,7 @@ private:
|
||||
QPushButton enableAllAnimationsButton;
|
||||
QPushButton disableAllAnimationsButton;
|
||||
QCheckBox tapAnimationCheckBox;
|
||||
QCheckBox arrowDrawAnimationCheckBox;
|
||||
QCheckBox lifeCounterAnimationsCheckBox;
|
||||
QCheckBox battlefieldFlashCheckBox;
|
||||
QCheckBox openDeckInNewTabCheckBox;
|
||||
|
||||
@@ -15,6 +15,7 @@ public:
|
||||
[[nodiscard]] virtual bool getIncludeRebalancedCards() const = 0;
|
||||
[[nodiscard]] virtual bool getPrintingSelectorNavigationButtonsVisible() const = 0;
|
||||
[[nodiscard]] virtual bool getTapAnimation() const = 0;
|
||||
[[nodiscard]] virtual bool getArrowDrawAnimation() const = 0;
|
||||
[[nodiscard]] virtual bool getAutoRotateSidewaysLayoutCards() const = 0;
|
||||
[[nodiscard]] virtual bool getScaleCards() const = 0;
|
||||
[[nodiscard]] virtual int getStackCardOverlapPercent() const = 0;
|
||||
|
||||
@@ -50,6 +50,11 @@ bool CardsDisplaySettings::getTapAnimation() const
|
||||
return getValue("tapAnimation", QString(), QString(), true).toBool();
|
||||
}
|
||||
|
||||
bool CardsDisplaySettings::getArrowDrawAnimation() const
|
||||
{
|
||||
return getValue("arrowDrawAnimation", QString(), QString(), true).toBool();
|
||||
}
|
||||
|
||||
bool CardsDisplaySettings::getAutoRotateSidewaysLayoutCards() const
|
||||
{
|
||||
return getValue("autoRotateSidewaysLayoutCards", QString(), QString(), true).toBool();
|
||||
@@ -159,6 +164,11 @@ void CardsDisplaySettings::setTapAnimation(bool _tapAnimation)
|
||||
setValue(_tapAnimation, "tapAnimation");
|
||||
}
|
||||
|
||||
void CardsDisplaySettings::setArrowDrawAnimation(bool _arrowDrawAnimation)
|
||||
{
|
||||
setValue(_arrowDrawAnimation, "arrowDrawAnimation");
|
||||
}
|
||||
|
||||
void CardsDisplaySettings::setAutoRotateSidewaysLayoutCards(bool _autoRotateSidewaysLayoutCards)
|
||||
{
|
||||
setValue(_autoRotateSidewaysLayoutCards, "autoRotateSidewaysLayoutCards");
|
||||
|
||||
@@ -20,6 +20,7 @@ public:
|
||||
[[nodiscard]] bool getIncludeRebalancedCards() const override;
|
||||
[[nodiscard]] bool getPrintingSelectorNavigationButtonsVisible() const override;
|
||||
[[nodiscard]] bool getTapAnimation() const override;
|
||||
[[nodiscard]] bool getArrowDrawAnimation() const override;
|
||||
[[nodiscard]] bool getAutoRotateSidewaysLayoutCards() const override;
|
||||
[[nodiscard]] bool getScaleCards() const override;
|
||||
[[nodiscard]] int getStackCardOverlapPercent() const override;
|
||||
@@ -40,6 +41,7 @@ public:
|
||||
void setIncludeRebalancedCards(bool _includeRebalancedCards);
|
||||
void setPrintingSelectorNavigationButtonsVisible(bool _navigationButtonsVisible);
|
||||
void setTapAnimation(bool _tapAnimation);
|
||||
void setArrowDrawAnimation(bool _arrowDrawAnimation);
|
||||
void setAutoRotateSidewaysLayoutCards(bool _autoRotateSidewaysLayoutCards);
|
||||
void setCardScaling(bool _scaleCards);
|
||||
void setStackCardOverlapPercent(int _verticalCardOverlapPercent);
|
||||
|
||||
@@ -476,6 +476,12 @@ TEST_F(SettingsDefaultsTest, CardsDisplay_SampleHandSize_Default)
|
||||
ASSERT_EQ(s.getSampleHandSize(), 7);
|
||||
}
|
||||
|
||||
TEST_F(SettingsDefaultsTest, CardsDisplay_ArrowDrawAnimation_Default)
|
||||
{
|
||||
CardsDisplaySettings s(settingsPath, nullptr);
|
||||
ASSERT_EQ(s.getArrowDrawAnimation(), true);
|
||||
}
|
||||
|
||||
// --- VisualDeckStorageSettings ---
|
||||
|
||||
TEST_F(SettingsDefaultsTest, VisualDeckStorage_SortingOrder_Default)
|
||||
|
||||
Reference in New Issue
Block a user