diff --git a/cocos/2d/CCActionInterval.cpp b/cocos/2d/CCActionInterval.cpp index 3068bd8a31..5b8eacfca7 100644 --- a/cocos/2d/CCActionInterval.cpp +++ b/cocos/2d/CCActionInterval.cpp @@ -1460,6 +1460,129 @@ SkewBy* SkewBy::reverse() const return SkewBy::create(_duration, -_skewX, -_skewY); } +ResizeTo* ResizeTo::create(float duration, const cocos2d::Size& final_size) +{ + ResizeTo *ret = new (std::nothrow) ResizeTo(); + + if (ret) + { + if (ret->initWithDuration(duration, final_size)) + { + ret->autorelease(); + } + else + { + delete ret; + ret = nullptr; + } + } + + return ret; +} + +ResizeTo* ResizeTo::clone(void) const +{ + // no copy constructor + ResizeTo* a = new (std::nothrow) ResizeTo(); + a->initWithDuration(_duration, _finalSize); + a->autorelease(); + + return a; +} + +void ResizeTo::startWithTarget(cocos2d::Node* target) +{ + ActionInterval::startWithTarget(target); + _initialSize = target->getContentSize(); + _sizeDelta = _finalSize - _initialSize; +} + +void ResizeTo::update(float time) +{ + if (_target) + { + auto new_size = _initialSize + (_sizeDelta * time); + _target->setContentSize(new_size); + } +} + +bool ResizeTo::initWithDuration(float duration, const cocos2d::Size& final_size) +{ + if (cocos2d::ActionInterval::initWithDuration(duration)) + { + _finalSize = final_size; + return true; + } + + return false; +} + +// +// ResizeBy +// + +ResizeBy* ResizeBy::create(float duration, const cocos2d::Size& deltaSize) +{ + ResizeBy *ret = new (std::nothrow) ResizeBy(); + + if (ret) + { + if (ret->initWithDuration(duration, deltaSize)) + { + ret->autorelease(); + } + else + { + delete ret; + ret = nullptr; + } + } + + return ret; +} + +ResizeBy* ResizeBy::clone() const +{ + // no copy constructor + auto a = new (std::nothrow) ResizeBy(); + a->initWithDuration(_duration, _sizeDelta); + a->autorelease(); + return a; +} + +void ResizeBy::startWithTarget(Node *target) +{ + ActionInterval::startWithTarget(target); + _previousSize = _startSize = target->getContentSize(); +} + +ResizeBy* ResizeBy::reverse() const +{ + cocos2d::Size newSize(-_sizeDelta.width, -_sizeDelta.height); + return ResizeBy::create(_duration, newSize); +} + +void ResizeBy::update(float t) +{ + if (_target) + { + _target->setContentSize(_startSize + (_sizeDelta * t)); + } +} + +bool ResizeBy::initWithDuration(float duration, const cocos2d::Size& deltaSize) +{ + bool ret = false; + + if (ActionInterval::initWithDuration(duration)) + { + _sizeDelta = deltaSize; + ret = true; + } + + return ret; +} + // // JumpBy // diff --git a/cocos/2d/CCActionInterval.h b/cocos/2d/CCActionInterval.h index bfaa044682..966983ff50 100644 --- a/cocos/2d/CCActionInterval.h +++ b/cocos/2d/CCActionInterval.h @@ -768,6 +768,92 @@ private: CC_DISALLOW_COPY_AND_ASSIGN(SkewBy); }; +/** @class ResizeTo +* @brief Resize a Node object to the final size by modifying it's Size attribute. +*/ +class CC_DLL ResizeTo : public ActionInterval +{ +public: + /** + * Creates the action. + * @brief Resize a Node object to the final size by modifying it's Size attribute. Works on all nodes where setContentSize is effective. But it's mostly useful for nodes where 9-slice is enabled + * @param duration Duration time, in seconds. + * @param final_size The target size to reach + * @return An autoreleased RotateTo object. + */ + static ResizeTo* create(float duration, const cocos2d::Size& final_size); + + // + // Overrides + // + virtual ResizeTo* clone() const override; + void startWithTarget(cocos2d::Node* target) override; + void update(float time) override; + +CC_CONSTRUCTOR_ACCESS: + ResizeTo() {} + virtual ~ResizeTo() {} + + /** + * initializes the action + * @param duration in seconds + * @param final_size in Size type + */ + bool initWithDuration(float duration, const cocos2d::Size& final_size); + +protected: + cocos2d::Size _initialSize; + cocos2d::Size _finalSize; + cocos2d::Size _sizeDelta; + +private: + CC_DISALLOW_COPY_AND_ASSIGN(ResizeTo); +}; + + +/** @class ResizeBy +* @brief Resize a Node object by a Size. Works on all nodes where setContentSize is effective. But it's mostly useful for nodes where 9-slice is enabled +*/ +class CC_DLL ResizeBy : public ActionInterval +{ +public: + /** + * Creates the action. + * + * @param duration Duration time, in seconds. + * @param deltaSize The delta size. + * @return An autoreleased ResizeBy object. + */ + static ResizeBy* create(float duration, const cocos2d::Size& deltaSize); + + // + // Overrides + // + virtual ResizeBy* clone() const override; + virtual ResizeBy* reverse(void) const override; + virtual void startWithTarget(Node *target) override; + /** + * @param time in seconds + */ + virtual void update(float time) override; + +CC_CONSTRUCTOR_ACCESS: + ResizeBy() {} + virtual ~ResizeBy() {} + + /** initializes the action */ + bool initWithDuration(float duration, const cocos2d::Size& deltaSize); + +protected: + cocos2d::Size _sizeDelta; + cocos2d::Size _startSize; + cocos2d::Size _previousSize; + +private: + CC_DISALLOW_COPY_AND_ASSIGN(ResizeBy); +}; + + /** @class JumpBy * @brief Moves a Node object simulating a parabolic jump movement by modifying it's position attribute. */ diff --git a/tests/cpp-tests/Classes/ActionsTest/ActionsTest.cpp b/tests/cpp-tests/Classes/ActionsTest/ActionsTest.cpp index f71284d153..4f1930f952 100644 --- a/tests/cpp-tests/Classes/ActionsTest/ActionsTest.cpp +++ b/tests/cpp-tests/Classes/ActionsTest/ActionsTest.cpp @@ -26,12 +26,14 @@ #include "ActionsTest.h" #include "../testResource.h" #include "cocos2d.h" +#include "ui/CocosGUI.h" #include "renderer/CCRenderer.h" #include "renderer/CCCustomCommand.h" #include "renderer/CCGroupCommand.h" USING_NS_CC; +using namespace cocos2d::ui; ActionsTests::ActionsTests() { @@ -79,6 +81,7 @@ ActionsTests::ActionsTests() ADD_TEST_CASE(ActionCardinalSplineStacked); ADD_TEST_CASE(ActionCatmullRomStacked); ADD_TEST_CASE(PauseResumeActions); + ADD_TEST_CASE(ActionResize); ADD_TEST_CASE(Issue1305); ADD_TEST_CASE(Issue1305_2); ADD_TEST_CASE(Issue1288); @@ -2201,6 +2204,69 @@ std::string PauseResumeActions::subtitle() const return "All actions pause at 3s and resume at 5s"; } +//------------------------------------------------------------------ +// +// ActionResize +// Works on all nodes where setContentSize is effective. +// But it's mostly useful for nodes where 9-slice is enabled +// +//------------------------------------------------------------------ +void ActionResize::onEnter() +{ + ActionsDemo::onEnter(); + + _grossini->setVisible(false); + _tamara->setVisible(false); + _kathia->setVisible(false); + + Size widgetSize = getContentSize(); + + Text* alert = Text::create("ImageView Content ResizeTo ResizeBy action. \nTop: ResizeTo/ResizeBy on a 9-slice ImageView \nBottom: ScaleTo/ScaleBy on a 9-slice ImageView (for comparison)", "fonts/Marker Felt.ttf", 14); + alert->setColor(Color3B(159, 168, 176)); + alert->setPosition(Vec2(widgetSize.width / 2.0f, + widgetSize.height / 2.0f - alert->getContentSize().height * 1.125f)); + + addChild(alert); + + // Create the imageview + Vec2 offset(0.0f, 50.0f); + ImageView* imageViewResize = ImageView::create("cocosui/buttonHighlighted.png"); + imageViewResize->setScale9Enabled(true); + imageViewResize->setContentSize(Size(50, 40)); + imageViewResize->setPosition(Vec2((widgetSize.width / 2.0f) + offset.x, + (widgetSize.height / 2.0f) + offset.y)); + + auto resizeDown = cocos2d::ResizeTo::create(2.8f, Size(50, 40)); + auto resizeUp = cocos2d::ResizeTo::create(2.8f, Size(300, 40)); + + auto resizeByDown = cocos2d::ResizeBy::create(1.8f, Size(0, -30)); + auto resizeByUp = cocos2d::ResizeBy::create(1.8f, Size(0, 30)); + addChild(imageViewResize); + auto rep = RepeatForever::create(Sequence::create(resizeUp, resizeDown, resizeByDown, resizeByUp, nullptr)); + imageViewResize->runAction(rep); + + // Create another imageview that scale to see the difference + ImageView* imageViewScale = ImageView::create("cocosui/buttonHighlighted.png"); + imageViewScale->setScale9Enabled(true); + imageViewScale->setContentSize(Size(50, 40)); + imageViewScale->setPosition(Vec2(widgetSize.width / 2.0f, + widgetSize.height / 2.0f)); + + auto scaleDownScale = cocos2d::ScaleTo::create(2.8f, 1.0f); + auto scaleUpScale = cocos2d::ScaleTo::create(2.8f, 6.0f, 1.0f); + + auto scaleByDownScale = cocos2d::ScaleBy::create(1.8f, 1.0f, 0.25f); + auto scaleByUpScale = cocos2d::ScaleBy::create(1.8f, 1.0f, 4.0f); + addChild(imageViewScale); + auto rep2 = RepeatForever::create(Sequence::create(scaleUpScale, scaleDownScale, scaleByDownScale, scaleByUpScale, nullptr)); + imageViewScale->runAction(rep2); +} + +std::string ActionResize::subtitle() const +{ + return "ResizeTo / ResizeBy"; +} + //------------------------------------------------------------------ // // ActionRemoveSelf diff --git a/tests/cpp-tests/Classes/ActionsTest/ActionsTest.h b/tests/cpp-tests/Classes/ActionsTest/ActionsTest.h index 610238f358..0a0b77e06e 100644 --- a/tests/cpp-tests/Classes/ActionsTest/ActionsTest.h +++ b/tests/cpp-tests/Classes/ActionsTest/ActionsTest.h @@ -578,6 +578,15 @@ private: cocos2d::Vector _pausedTargets; }; +class ActionResize : public ActionsDemo +{ +public: + CREATE_FUNC(ActionResize); + + virtual void onEnter() override; + virtual std::string subtitle() const override; +}; + class ActionFloatTest : public ActionsDemo { public: