From 7cbc2ecbc26f01971823c7ed7547e06e7afa18ab Mon Sep 17 00:00:00 2001 From: adazem009 <68537469+adazem009@users.noreply.github.com> Date: Tue, 30 Jan 2024 19:41:26 +0100 Subject: [PATCH 1/3] Add bubble API to Target --- include/scratchcpp/target.h | 12 +++++++++++ src/scratch/target.cpp | 30 ++++++++++++++++++++++++++++ src/scratch/target_p.h | 3 +++ test/scratch_classes/target_test.cpp | 24 ++++++++++++++++++++++ 4 files changed, 69 insertions(+) diff --git a/include/scratchcpp/target.h b/include/scratchcpp/target.h index 6bd8a977..1b4a7874 100644 --- a/include/scratchcpp/target.h +++ b/include/scratchcpp/target.h @@ -24,6 +24,12 @@ class TargetPrivate; class LIBSCRATCHCPP_EXPORT Target { public: + enum class BubbleType + { + Say, + Think + }; + Target(); Target(const Target &) = delete; virtual ~Target() { } @@ -83,6 +89,12 @@ class LIBSCRATCHCPP_EXPORT Target virtual void clearGraphicsEffects(); + BubbleType bubbleType() const; + virtual void setBubbleType(BubbleType type); + + const std::string &bubbleText() const; + virtual void setBubbleText(const std::string &text); + IEngine *engine() const; void setEngine(IEngine *engine); diff --git a/src/scratch/target.cpp b/src/scratch/target.cpp index e0bce348..3392bef2 100644 --- a/src/scratch/target.cpp +++ b/src/scratch/target.cpp @@ -439,6 +439,36 @@ void Target::clearGraphicsEffects() impl->graphicsEffects.clear(); } +/*! Returns the type of the bubble (say or think). */ +Target::BubbleType Target::bubbleType() const +{ + return impl->bubbleType; +} + +/*! Sets the type of the bubble (say or think). */ +void Target::setBubbleType(BubbleType type) +{ + impl->bubbleType = type; +} + +/*! + * Returns the text of the bubble. + * \note If the text is an empty string, the bubble is supposed to be hidden. + */ +const std::string &Target::bubbleText() const +{ + return impl->bubbleText; +} + +/*! + * Sets the text of the bubble. + * \note If the text is an empty string, the bubble is supposed to be hidden. + */ +void Target::setBubbleText(const std::string &text) +{ + impl->bubbleText = text; +} + /*! Returns the engine. */ IEngine *Target::engine() const { diff --git a/src/scratch/target_p.h b/src/scratch/target_p.h index fc920922..73db4087 100644 --- a/src/scratch/target_p.h +++ b/src/scratch/target_p.h @@ -8,6 +8,7 @@ #include #include #include +#include namespace libscratchcpp { @@ -36,6 +37,8 @@ struct TargetPrivate int layerOrder = 0; double volume = 100; std::unordered_map graphicsEffects; + Target::BubbleType bubbleType = Target::BubbleType::Say; + std::string bubbleText; }; } // namespace libscratchcpp diff --git a/test/scratch_classes/target_test.cpp b/test/scratch_classes/target_test.cpp index 9feabeb6..c0e2ffec 100644 --- a/test/scratch_classes/target_test.cpp +++ b/test/scratch_classes/target_test.cpp @@ -581,6 +581,30 @@ TEST(TargetTest, GraphicsEffects) ASSERT_EQ(target.graphicsEffectValue(&effect2), 0); } +TEST(TargetTest, BubbleType) +{ + Target target; + ASSERT_EQ(target.bubbleType(), Target::BubbleType::Say); + + target.setBubbleType(Target::BubbleType::Think); + ASSERT_EQ(target.bubbleType(), Target::BubbleType::Think); + + target.setBubbleType(Target::BubbleType::Say); + ASSERT_EQ(target.bubbleType(), Target::BubbleType::Say); +} + +TEST(TargetTest, BubbleText) +{ + Target target; + ASSERT_TRUE(target.bubbleText().empty()); + + target.setBubbleText("hello"); + ASSERT_EQ(target.bubbleText(), "hello"); + + target.setBubbleText("world"); + ASSERT_EQ(target.bubbleText(), "world"); +} + TEST(TargetTest, Engine) { Target target; From 2e48d293fadb215dbbfedadbecd49af3228bf533 Mon Sep 17 00:00:00 2001 From: adazem009 <68537469+adazem009@users.noreply.github.com> Date: Tue, 30 Jan 2024 20:29:32 +0100 Subject: [PATCH 2/3] Add bubble change methods to ISpriteHandler --- include/scratchcpp/ispritehandler.h | 6 +++++ include/scratchcpp/sprite.h | 3 +++ src/scratch/sprite.cpp | 25 +++++++++++++++++++ test/mocks/spritehandlermock.h | 2 ++ test/scratch_classes/sprite_test.cpp | 24 ++++++++++++++++++ .../target_interfaces/ispritehandler_test.cpp | 16 ++++++++++++ 6 files changed, 76 insertions(+) diff --git a/include/scratchcpp/ispritehandler.h b/include/scratchcpp/ispritehandler.h index 546d18f4..663bffad 100644 --- a/include/scratchcpp/ispritehandler.h +++ b/include/scratchcpp/ispritehandler.h @@ -59,6 +59,12 @@ class LIBSCRATCHCPP_EXPORT ISpriteHandler /*! Called when all graphics effects are cleared. */ virtual void onGraphicsEffectsCleared() = 0; + /*! Called when the bubble type changes. */ + virtual void onBubbleTypeChanged(Target::BubbleType type) = 0; + + /*! Called when the bubble text changes. */ + virtual void onBubbleTextChanged(const std::string &text) = 0; + /*! * Used to get the bounding rectangle of the sprite. * \note The rectangle must be relative to the stage, so make sure to use the sprite's coordinates. diff --git a/include/scratchcpp/sprite.h b/include/scratchcpp/sprite.h index b9087c1f..23191429 100644 --- a/include/scratchcpp/sprite.h +++ b/include/scratchcpp/sprite.h @@ -76,6 +76,9 @@ class LIBSCRATCHCPP_EXPORT Sprite void clearGraphicsEffects() override; + virtual void setBubbleType(Target::BubbleType type) override; + virtual void setBubbleText(const std::string &text) override; + private: Target *dataSource() const override; void setXY(double x, double y); diff --git a/src/scratch/sprite.cpp b/src/scratch/sprite.cpp index ec648076..8db496c8 100644 --- a/src/scratch/sprite.cpp +++ b/src/scratch/sprite.cpp @@ -429,6 +429,31 @@ void Sprite::clearGraphicsEffects() impl->iface->onGraphicsEffectsCleared(); } +/*! Overrides Target#setBubbleType(). */ +void Sprite::setBubbleType(BubbleType type) +{ + Target::setBubbleType(type); + + if (impl->iface) + impl->iface->onBubbleTypeChanged(type); +} + +/*! Overrides Target#setBubbleText(). */ +void Sprite::setBubbleText(const std::string &text) +{ + Target::setBubbleText(text); + + if (impl->visible && !text.empty()) { + IEngine *eng = engine(); + + if (eng) + eng->requestRedraw(); + } + + if (impl->iface) + impl->iface->onBubbleTextChanged(text); +} + Target *Sprite::dataSource() const { return impl->cloneSprite; diff --git a/test/mocks/spritehandlermock.h b/test/mocks/spritehandlermock.h index cf4b331e..5b9642ba 100644 --- a/test/mocks/spritehandlermock.h +++ b/test/mocks/spritehandlermock.h @@ -25,6 +25,8 @@ class SpriteHandlerMock : public ISpriteHandler MOCK_METHOD(void, onLayerOrderChanged, (int), (override)); MOCK_METHOD(void, onGraphicsEffectChanged, (IGraphicsEffect *, double), (override)); MOCK_METHOD(void, onGraphicsEffectsCleared, (), (override)); + MOCK_METHOD(void, onBubbleTypeChanged, (Target::BubbleType), (override)); + MOCK_METHOD(void, onBubbleTextChanged, (const std::string &), (override)); MOCK_METHOD(Rect, boundingRect, (), (const, override)); }; diff --git a/test/scratch_classes/sprite_test.cpp b/test/scratch_classes/sprite_test.cpp index 2309359c..8abec5ec 100644 --- a/test/scratch_classes/sprite_test.cpp +++ b/test/scratch_classes/sprite_test.cpp @@ -632,3 +632,27 @@ TEST(SpriteTest, GraphicsEffects) ASSERT_EQ(sprite.graphicsEffectValue(&effect1), 0); ASSERT_EQ(sprite.graphicsEffectValue(&effect2), 0); } + +TEST(SpriteTest, BubbleType) +{ + Sprite sprite; + ASSERT_EQ(sprite.bubbleType(), Target::BubbleType::Say); + + sprite.setBubbleType(Target::BubbleType::Think); + ASSERT_EQ(sprite.bubbleType(), Target::BubbleType::Think); + + sprite.setBubbleType(Target::BubbleType::Say); + ASSERT_EQ(sprite.bubbleType(), Target::BubbleType::Say); +} + +TEST(SpriteTest, BubbleText) +{ + Sprite sprite; + ASSERT_TRUE(sprite.bubbleText().empty()); + + sprite.setBubbleText("hello"); + ASSERT_EQ(sprite.bubbleText(), "hello"); + + sprite.setBubbleText("world"); + ASSERT_EQ(sprite.bubbleText(), "world"); +} diff --git a/test/target_interfaces/ispritehandler_test.cpp b/test/target_interfaces/ispritehandler_test.cpp index 81953a67..777fb2ed 100644 --- a/test/target_interfaces/ispritehandler_test.cpp +++ b/test/target_interfaces/ispritehandler_test.cpp @@ -174,6 +174,22 @@ TEST_F(ISpriteHandlerTest, GraphicsEffects) m_sprite.clearGraphicsEffects(); } +TEST_F(ISpriteHandlerTest, BubbleType) +{ + EXPECT_CALL(m_handler, onBubbleTypeChanged(Target::BubbleType::Say)); + m_sprite.setBubbleType(Target::BubbleType::Say); + + EXPECT_CALL(m_handler, onBubbleTypeChanged(Target::BubbleType::Think)); + m_sprite.setBubbleType(Target::BubbleType::Think); +} + +TEST_F(ISpriteHandlerTest, BubbleText) +{ + EXPECT_CALL(m_handler, onBubbleTextChanged("test")); + EXPECT_CALL(m_engine, requestRedraw()); + m_sprite.setBubbleText("test"); +} + TEST_F(ISpriteHandlerTest, BoundingRect) { EXPECT_CALL(m_handler, boundingRect()).WillOnce(Return(Rect(-44.6, 89.1, 20.5, -0.48))); From 60e9fc9f81c14187d96cf70b7801c5b4e3efa5be Mon Sep 17 00:00:00 2001 From: adazem009 <68537469+adazem009@users.noreply.github.com> Date: Tue, 30 Jan 2024 20:30:06 +0100 Subject: [PATCH 3/3] Add bubble change methods to IStageHandler --- include/scratchcpp/istagehandler.h | 6 +++++ include/scratchcpp/stage.h | 3 +++ src/scratch/stage.cpp | 25 +++++++++++++++++++ test/mocks/stagehandlermock.h | 2 ++ test/scratch_classes/stage_test.cpp | 24 ++++++++++++++++++ test/target_interfaces/istagehandler_test.cpp | 16 ++++++++++++ 6 files changed, 76 insertions(+) diff --git a/include/scratchcpp/istagehandler.h b/include/scratchcpp/istagehandler.h index 09a61ccd..354144d9 100644 --- a/include/scratchcpp/istagehandler.h +++ b/include/scratchcpp/istagehandler.h @@ -37,6 +37,12 @@ class LIBSCRATCHCPP_EXPORT IStageHandler /*! Called when all graphics effects are cleared. */ virtual void onGraphicsEffectsCleared() = 0; + + /*! Called when the bubble type changes. */ + virtual void onBubbleTypeChanged(Target::BubbleType type) = 0; + + /*! Called when the bubble text changes. */ + virtual void onBubbleTextChanged(const std::string &text) = 0; }; } // namespace libscratchcpp diff --git a/include/scratchcpp/stage.h b/include/scratchcpp/stage.h index 90ae1c6f..902f9b73 100644 --- a/include/scratchcpp/stage.h +++ b/include/scratchcpp/stage.h @@ -52,6 +52,9 @@ class LIBSCRATCHCPP_EXPORT Stage : public Target void clearGraphicsEffects() override; + virtual void setBubbleType(Target::BubbleType type) override; + virtual void setBubbleText(const std::string &text) override; + private: spimpl::unique_impl_ptr impl; }; diff --git a/src/scratch/stage.cpp b/src/scratch/stage.cpp index 524a6b02..7f55b70a 100644 --- a/src/scratch/stage.cpp +++ b/src/scratch/stage.cpp @@ -156,3 +156,28 @@ void Stage::clearGraphicsEffects() if (impl->iface) impl->iface->onGraphicsEffectsCleared(); } + +/*! Overrides Target#setBubbleType(). */ +void Stage::setBubbleType(BubbleType type) +{ + Target::setBubbleType(type); + + if (impl->iface) + impl->iface->onBubbleTypeChanged(type); +} + +/*! Overrides Target#setBubbleText(). */ +void Stage::setBubbleText(const std::string &text) +{ + Target::setBubbleText(text); + + if (!text.empty()) { + IEngine *eng = engine(); + + if (eng) + eng->requestRedraw(); + } + + if (impl->iface) + impl->iface->onBubbleTextChanged(text); +} diff --git a/test/mocks/stagehandlermock.h b/test/mocks/stagehandlermock.h index 4188eb8d..d00c569c 100644 --- a/test/mocks/stagehandlermock.h +++ b/test/mocks/stagehandlermock.h @@ -17,4 +17,6 @@ class StageHandlerMock : public IStageHandler MOCK_METHOD(void, onVideoTransparencyChanged, (int), (override)); MOCK_METHOD(void, onGraphicsEffectChanged, (IGraphicsEffect *, double), (override)); MOCK_METHOD(void, onGraphicsEffectsCleared, (), (override)); + MOCK_METHOD(void, onBubbleTypeChanged, (Target::BubbleType), (override)); + MOCK_METHOD(void, onBubbleTextChanged, (const std::string &), (override)); }; diff --git a/test/scratch_classes/stage_test.cpp b/test/scratch_classes/stage_test.cpp index f567b074..2a0a6048 100644 --- a/test/scratch_classes/stage_test.cpp +++ b/test/scratch_classes/stage_test.cpp @@ -141,6 +141,30 @@ TEST(StageTest, GraphicsEffects) ASSERT_EQ(stage.graphicsEffectValue(&effect2), 0); } +TEST(StageTest, BubbleType) +{ + Stage stage; + ASSERT_EQ(stage.bubbleType(), Target::BubbleType::Say); + + stage.setBubbleType(Target::BubbleType::Think); + ASSERT_EQ(stage.bubbleType(), Target::BubbleType::Think); + + stage.setBubbleType(Target::BubbleType::Say); + ASSERT_EQ(stage.bubbleType(), Target::BubbleType::Say); +} + +TEST(StageTest, BubbleText) +{ + Stage stage; + ASSERT_TRUE(stage.bubbleText().empty()); + + stage.setBubbleText("hello"); + ASSERT_EQ(stage.bubbleText(), "hello"); + + stage.setBubbleText("world"); + ASSERT_EQ(stage.bubbleText(), "world"); +} + TEST(StageTest, LayerOrder) { Stage stage; diff --git a/test/target_interfaces/istagehandler_test.cpp b/test/target_interfaces/istagehandler_test.cpp index 38119aa1..a109624a 100644 --- a/test/target_interfaces/istagehandler_test.cpp +++ b/test/target_interfaces/istagehandler_test.cpp @@ -66,3 +66,19 @@ TEST_F(IStageHandlerTest, GraphicsEffects) EXPECT_CALL(m_engine, requestRedraw()); m_stage.clearGraphicsEffects(); } + +TEST_F(IStageHandlerTest, BubbleType) +{ + EXPECT_CALL(m_handler, onBubbleTypeChanged(Target::BubbleType::Say)); + m_stage.setBubbleType(Target::BubbleType::Say); + + EXPECT_CALL(m_handler, onBubbleTypeChanged(Target::BubbleType::Think)); + m_stage.setBubbleType(Target::BubbleType::Think); +} + +TEST_F(IStageHandlerTest, BubbleText) +{ + EXPECT_CALL(m_handler, onBubbleTextChanged("test")); + EXPECT_CALL(m_engine, requestRedraw()); + m_stage.setBubbleText("test"); +}