From: Heeyong Song Date: Mon, 18 Jul 2022 06:13:17 +0000 (+0900) Subject: (Vector) Support dynamic properties X-Git-Tag: dali_2.1.33~5^2 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=commitdiff_plain;h=6fcd54cf99718c78d77cb8a9bf836059111afe16 (Vector) Support dynamic properties Change-Id: I562e33197a9515dcdd6ce76ea7805cddc2e7f131 --- diff --git a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-vector-animation-renderer.cpp b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-vector-animation-renderer.cpp index e6456ec..a8f3ab8 100644 --- a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-vector-animation-renderer.cpp +++ b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-vector-animation-renderer.cpp @@ -129,6 +129,11 @@ public: mNeedDroppedFrames = false; } + if(mDynamicPropertyCallback) + { + CallbackBase::ExecuteReturn(*mDynamicPropertyCallback, 0, 0, frameNumber); + } + if(mNeedTrigger) { mEventThreadCallback->Trigger(); @@ -190,6 +195,11 @@ public: } } + void AddPropertyValueCallback(const std::string& keyPath, Dali::VectorAnimationRenderer::VectorProperty property, CallbackBase* callback, int32_t id) + { + mDynamicPropertyCallback = std::unique_ptr(callback); + } + Dali::VectorAnimationRenderer::UploadCompletedSignalType& UploadCompletedSignal() { return mUploadCompletedSignal; @@ -216,23 +226,25 @@ public: public: static uint32_t mCount; - std::string mUrl; - Dali::Renderer mRenderer; - Dali::Mutex mMutex; - uint32_t mWidth; - uint32_t mHeight; - uint32_t mDefaultWidth; - uint32_t mDefaultHeight; - uint32_t mTotalFrameNumber; - uint32_t mPreviousFrame; - uint32_t mDelayTime; - uint32_t mDroppedFrames; - float mFrameRate; - bool mTestFrameDrop; - bool mNeedDroppedFrames; - bool mLoadFailed{false}; - bool mResourceReady{false}; - bool mNeedTrigger{true}; + std::string mUrl; + Dali::Renderer mRenderer; + Dali::Mutex mMutex; + std::unique_ptr mDynamicPropertyCallback{nullptr}; + + uint32_t mWidth; + uint32_t mHeight; + uint32_t mDefaultWidth; + uint32_t mDefaultHeight; + uint32_t mTotalFrameNumber; + uint32_t mPreviousFrame; + uint32_t mDelayTime; + uint32_t mDroppedFrames; + float mFrameRate; + bool mTestFrameDrop; + bool mNeedDroppedFrames; + bool mLoadFailed{false}; + bool mResourceReady{false}; + bool mNeedTrigger{true}; Dali::VectorAnimationRenderer::UploadCompletedSignalType mUploadCompletedSignal; std::unique_ptr mEventThreadCallback; @@ -348,6 +360,11 @@ void VectorAnimationRenderer::InvalidateBuffer() return Internal::Adaptor::GetImplementation(*this).InvalidateBuffer(); } +void VectorAnimationRenderer::AddPropertyValueCallback(const std::string& keyPath, VectorProperty property, CallbackBase* callback, int32_t id) +{ + Internal::Adaptor::GetImplementation(*this).AddPropertyValueCallback(keyPath, property, callback, id); +} + VectorAnimationRenderer::UploadCompletedSignalType& VectorAnimationRenderer::UploadCompletedSignal() { return Internal::Adaptor::GetImplementation(*this).UploadCompletedSignal(); diff --git a/automated-tests/src/dali-toolkit/utc-Dali-AnimatedVectorImageVisual.cpp b/automated-tests/src/dali-toolkit/utc-Dali-AnimatedVectorImageVisual.cpp index 6299c0c..4ca6308 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-AnimatedVectorImageVisual.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-AnimatedVectorImageVisual.cpp @@ -34,6 +34,8 @@ #include #include #include + +#include #include #include @@ -1898,3 +1900,63 @@ int UtcDaliAnimatedVectorImageVisualSize(void) END_TEST; } + +namespace +{ +bool gDynamicPropertyCallbackFired = false; + +Property::Value FillColorCallback(int32_t id, VectorAnimationRenderer::VectorProperty property, uint32_t frameNumber) +{ + gDynamicPropertyCallbackFired = true; + + if(frameNumber < 3) + { + return Vector3(0, 0, 1); + } + else + { + return Vector3(1, 0, 0); + } +} +} // namespace + +int UtcDaliAnimatedVectorImageVisualDynamicProperty(void) +{ + ToolkitTestApplication application; + tet_infoline("UtcDaliAnimatedVectorImageVisualDynamicProperty"); + + VisualFactory factory = VisualFactory::Get(); + Visual::Base visual = factory.CreateVisual(TEST_VECTOR_IMAGE_FILE_NAME, ImageDimensions()); + DALI_TEST_CHECK(visual); + + DummyControl actor = DummyControl::New(true); + DummyControlImpl& dummyImpl = static_cast(actor.GetImplementation()); + dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, visual); + + application.GetScene().Add(actor); + + gDynamicPropertyCallbackFired = false; + + // Set dynamic property + DevelAnimatedVectorImageVisual::DynamicPropertyInfo info; + info.id = 1; + info.keyPath = "Test.Path"; + info.property = static_cast(VectorAnimationRenderer::VectorProperty::FILL_COLOR); + info.callback = MakeCallback(FillColorCallback); + + DevelControl::DoActionExtension(actor, DummyControl::Property::TEST_VISUAL, DevelAnimatedVectorImageVisual::Action::SET_DYNAMIC_PROPERTY, Any(info)); + + Property::Map attributes; + DevelControl::DoAction(actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedVectorImageVisual::Action::PLAY, attributes); + + application.SendNotification(); + application.Render(); + + // Trigger count is 2 - load & render a frame + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION); + + // Test whether the property callback is called + DALI_TEST_EQUALS(gDynamicPropertyCallbackFired, true, TEST_LOCATION); + + END_TEST; +} diff --git a/dali-toolkit/devel-api/controls/control-devel.cpp b/dali-toolkit/devel-api/controls/control-devel.cpp index 51e0564..ef1265b 100644 --- a/dali-toolkit/devel-api/controls/control-devel.cpp +++ b/dali-toolkit/devel-api/controls/control-devel.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Samsung Electronics Co., Ltd. + * Copyright (c) 2022 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -114,6 +114,13 @@ void DoAction(Control& control, Dali::Property::Index visualIndex, Dali::Propert controlDataImpl.DoAction(visualIndex, actionId, attributes); } +void DoActionExtension(Control& control, Dali::Property::Index visualIndex, Dali::Property::Index actionId, Dali::Any attributes) +{ + Internal::Control& controlInternal = Toolkit::Internal::GetImplementation(control); + Internal::Control::Impl& controlDataImpl = Internal::Control::Impl::Get(controlInternal); + controlDataImpl.DoActionExtension(visualIndex, actionId, attributes); +} + void SetInputMethodContext(Internal::Control& control, InputMethodContext& inputMethodContext) { Internal::Control::Impl::Get(control).SetInputMethodContext(inputMethodContext); diff --git a/dali-toolkit/devel-api/controls/control-devel.h b/dali-toolkit/devel-api/controls/control-devel.h index 34b733b..abfba65 100644 --- a/dali-toolkit/devel-api/controls/control-devel.h +++ b/dali-toolkit/devel-api/controls/control-devel.h @@ -2,7 +2,7 @@ #define DALI_TOOLKIT_CONTROL_DEVEL_H /* - * Copyright (c) 2021 Samsung Electronics Co., Ltd. + * Copyright (c) 2022 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -360,6 +360,18 @@ DALI_TOOLKIT_API Dali::Animation CreateTransition(Internal::Control& DALI_TOOLKIT_API void DoAction(Control& control, Dali::Property::Index visualIndex, Dali::Property::Index actionId, const Dali::Property::Value attributes); /** + * @brief Perform an action on a visual registered to this control. + * + * Visuals will have actions, this API is used to perform one of these actions with the given attributes. + * + * @param[in] control The control. + * @param[in] visualIndex The Property index of the visual. + * @param[in] actionId The action to perform. See Visual to find supported actions. + * @param[in] attributes Optional attributes for the action. + */ +DALI_TOOLKIT_API void DoActionExtension(Control& control, Dali::Property::Index visualIndex, Dali::Property::Index actionId, Dali::Any attributes); + +/** * @brief Set input method context. * * @param[in] control The control. diff --git a/dali-toolkit/devel-api/visuals/animated-vector-image-visual-actions-devel.h b/dali-toolkit/devel-api/visuals/animated-vector-image-visual-actions-devel.h index ecb91ae..33c88e0 100644 --- a/dali-toolkit/devel-api/visuals/animated-vector-image-visual-actions-devel.h +++ b/dali-toolkit/devel-api/visuals/animated-vector-image-visual-actions-devel.h @@ -2,7 +2,7 @@ #define DALI_TOOLKIT_DEVEL_API_VISUALS_ANIMATED_VECTOR_IMAGE_VISUAL_ACTIONS_DEVEL_H /* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. + * Copyright (c) 2022 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,7 +17,11 @@ * limitations under the License. * */ + +// EXTERNAL INCLUDES #include +#include +#include namespace Dali { @@ -39,10 +43,35 @@ enum Type PAUSE, ///< Pause the animated vector image. STOP, ///< Stop the animated vector image. This is also Default playback mode. JUMP_TO, ///< Jump to the specified frame. Property::INTEGER value should be passed. + SET_DYNAMIC_PROPERTY ///< Set the dynamic property. }; } // namespace Action +/** + * @brief The dynamic property info + * + * @note A callback of the following type may be used: + * @code + * Property::Value MyFunction(int32_t id, VectorAnimationRenderer::VectorProperty property, uint32_t frameNumber); + * @endcode + * + * id The id to specify the callback. + * property The property that represent what you are trying to change. + * frameNumber The current frame number. + * It returns a Property::Value to set according to the property type. + * + * The callback will be called on the worker thread. You MUST not call other DALi methods in the callback. + * And the object must still be alive when the callback occurs if you make the callback from a class member function. + */ +struct DynamicPropertyInfo +{ + int32_t id; ///< The Id to specify the callback. It should be unique and will be passed when the callback is called. + std::string keyPath; ///< The key path used to target a specific content or a set of contents that will be updated. + int32_t property; ///< The property to set. + CallbackBase* callback; ///< The callback that gets called every time the animation is rendered. Ownership of the callback is passed onto the visual. +}; + } // namespace DevelAnimatedVectorImageVisual } // namespace Toolkit diff --git a/dali-toolkit/internal/controls/control/control-data-impl.cpp b/dali-toolkit/internal/controls/control/control-data-impl.cpp index d4de79a..5b638e8 100644 --- a/dali-toolkit/internal/controls/control/control-data-impl.cpp +++ b/dali-toolkit/internal/controls/control/control-data-impl.cpp @@ -1095,6 +1095,15 @@ void Control::Impl::DoAction(Dali::Property::Index visualIndex, Dali::Property:: } } +void Control::Impl::DoActionExtension(Dali::Property::Index visualIndex, Dali::Property::Index actionId, Dali::Any attributes) +{ + RegisteredVisualContainer::Iterator iter; + if(FindVisual(visualIndex, mVisuals, iter)) + { + Toolkit::GetImplementation((*iter)->visual).DoActionExtension(actionId, attributes); + } +} + void Control::Impl::AppendAccessibilityAttribute(const std::string& key, const std::string value) { Property::Value* checkedValue = mAccessibilityAttributes.Find(key); diff --git a/dali-toolkit/internal/controls/control/control-data-impl.h b/dali-toolkit/internal/controls/control/control-data-impl.h index 593ab7d..f72d121 100644 --- a/dali-toolkit/internal/controls/control/control-data-impl.h +++ b/dali-toolkit/internal/controls/control/control-data-impl.h @@ -224,6 +224,11 @@ public: void DoAction(Dali::Property::Index visualIndex, Dali::Property::Index actionId, const Dali::Property::Value attributes); /** + * @copydoc Dali::Toolkit::DevelControl::DoActionExtension() + */ + void DoActionExtension(Dali::Property::Index visualIndex, Dali::Property::Index actionId, Dali::Any attributes); + + /** * @brief Function used to set control properties. * @param[in] object The object whose property to set * @param[in] index The index of the property to set diff --git a/dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.cpp b/dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.cpp index 4b547b4..1f73f80 100644 --- a/dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.cpp +++ b/dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.cpp @@ -489,6 +489,22 @@ void AnimatedVectorImageVisual::OnDoAction(const Property::Index actionId, const TriggerVectorRasterization(); } +void AnimatedVectorImageVisual::OnDoActionExtension(const Property::Index actionId, Dali::Any attributes) +{ + switch(actionId) + { + case DevelAnimatedVectorImageVisual::Action::SET_DYNAMIC_PROPERTY: + { + DevelAnimatedVectorImageVisual::DynamicPropertyInfo info = AnyCast(attributes); + mAnimationData.dynamicProperties.push_back(info); + mAnimationData.resendFlag |= VectorAnimationTask::RESEND_DYNAMIC_PROPERTY; + break; + } + } + + TriggerVectorRasterization(); +} + void AnimatedVectorImageVisual::OnResourceReady(VectorAnimationTask::ResourceStatus status) { if(status == VectorAnimationTask::ResourceStatus::LOADED) diff --git a/dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.h b/dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.h index 221cf23..72c8e60 100644 --- a/dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.h +++ b/dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.h @@ -159,6 +159,11 @@ protected: */ void OnDoAction(const Property::Index actionId, const Property::Value& attributes) override; + /** + * @copydoc Visual::Base::OnDoActionExtension + */ + void OnDoActionExtension(const Property::Index actionId, Dali::Any attributes) override; + private: /** * Helper method to set individual values by index key. diff --git a/dali-toolkit/internal/visuals/animated-vector-image/vector-animation-task.cpp b/dali-toolkit/internal/visuals/animated-vector-image/vector-animation-task.cpp index 302fce7..a202747 100644 --- a/dali-toolkit/internal/visuals/animated-vector-image/vector-animation-task.cpp +++ b/dali-toolkit/internal/visuals/animated-vector-image/vector-animation-task.cpp @@ -631,6 +631,14 @@ void VectorAnimationTask::ApplyAnimationData() mVectorRenderer.InvalidateBuffer(); } + if(mAnimationData[index].resendFlag & VectorAnimationTask::RESEND_DYNAMIC_PROPERTY) + { + for(auto&& iter : mAnimationData[index].dynamicProperties) + { + mVectorRenderer.AddPropertyValueCallback(iter.keyPath, static_cast(iter.property), iter.callback, iter.id); + } + } + if(mAnimationData[index].resendFlag & VectorAnimationTask::RESEND_PLAY_STATE) { if(mAnimationData[index].playState == DevelImageVisual::PlayState::PLAYING) @@ -647,6 +655,8 @@ void VectorAnimationTask::ApplyAnimationData() } } + // reset data + mAnimationData[index].dynamicProperties.clear(); mAnimationData[index].resendFlag = 0; } diff --git a/dali-toolkit/internal/visuals/animated-vector-image/vector-animation-task.h b/dali-toolkit/internal/visuals/animated-vector-image/vector-animation-task.h index 0ca2295..42d13f8 100644 --- a/dali-toolkit/internal/visuals/animated-vector-image/vector-animation-task.h +++ b/dali-toolkit/internal/visuals/animated-vector-image/vector-animation-task.h @@ -21,11 +21,13 @@ #include #include #include +#include #include #include #include // INTERNAL INCLUDES +#include #include namespace Dali @@ -54,7 +56,8 @@ public: using ResourceReadySignalType = Signal; - using TimePoint = std::chrono::time_point; + using TimePoint = std::chrono::time_point; + using DynamicPropertyType = std::vector; /** * Flags for re-sending data to the vector animation thread @@ -68,7 +71,8 @@ public: RESEND_CURRENT_FRAME = 1 << 4, RESEND_SIZE = 1 << 5, RESEND_PLAY_STATE = 1 << 6, - RESEND_NEED_RESOURCE_READY = 1 << 7 + RESEND_NEED_RESOURCE_READY = 1 << 7, + RESEND_DYNAMIC_PROPERTY = 1 << 8 }; /** @@ -79,6 +83,7 @@ public: AnimationData() : resendFlag(0), playRange(), + dynamicProperties(), playState(), stopBehavior(DevelImageVisual::StopBehavior::CURRENT_FRAME), loopingMode(DevelImageVisual::LoopingMode::RESTART), @@ -100,11 +105,13 @@ public: width = rhs.width; height = rhs.height; loopCount = rhs.loopCount; + dynamicProperties.insert(dynamicProperties.end(), rhs.dynamicProperties.begin(), rhs.dynamicProperties.end()); return *this; } uint32_t resendFlag; Property::Array playRange; + DynamicPropertyType dynamicProperties; DevelImageVisual::PlayState::Type playState; DevelImageVisual::StopBehavior::Type stopBehavior; DevelImageVisual::LoopingMode::Type loopingMode; diff --git a/dali-toolkit/internal/visuals/visual-base-impl.cpp b/dali-toolkit/internal/visuals/visual-base-impl.cpp index 99b6c38..ce78b7e 100644 --- a/dali-toolkit/internal/visuals/visual-base-impl.cpp +++ b/dali-toolkit/internal/visuals/visual-base-impl.cpp @@ -517,6 +517,11 @@ void Visual::Base::DoAction(const Property::Index actionId, const Property::Valu } } +void Visual::Base::DoActionExtension(const Dali::Property::Index actionId, const Dali::Any attributes) +{ + OnDoActionExtension(actionId, attributes); +} + void Visual::Base::SetDepthIndex(int index) { mImpl->mDepthIndex = index; @@ -698,6 +703,11 @@ void Visual::Base::OnDoAction(const Property::Index actionId, const Property::Va // May be overriden by derived class } +void Visual::Base::OnDoActionExtension(const Property::Index actionId, const Dali::Any attributes) +{ + // May be overriden by derived class +} + void Visual::Base::RegisterMixColor() { if(mImpl->mRenderer) diff --git a/dali-toolkit/internal/visuals/visual-base-impl.h b/dali-toolkit/internal/visuals/visual-base-impl.h index bdcb193..7ebf239 100644 --- a/dali-toolkit/internal/visuals/visual-base-impl.h +++ b/dali-toolkit/internal/visuals/visual-base-impl.h @@ -100,6 +100,14 @@ public: void DoAction(const Dali::Property::Index actionId, const Dali::Property::Value attributes); /** + * @brief Performs an action on the visual with the given action id and attributes. + * + * @param[in] actionId The id of the action to perform this API only takes an Index + * @param[in] attributes The list of attributes for the action. ( optional for this data structure to have content ) + */ + void DoActionExtension(const Dali::Property::Index actionId, const Dali::Any attributes); + + /** * @copydoc Toolkit::Visual::Base::GetHeightForWidth */ virtual float GetHeightForWidth(float width); @@ -363,6 +371,14 @@ protected: virtual void OnDoAction(const Property::Index actionId, const Property::Value& attributes); /** + * @brief Called by DoActionExtension() allowing sub classes to do the given action. + * + * @param[in] actionId The action to perform + * @param[in] attributes The list of attributes for the action. ( optional for this data structure to have content ) + */ + virtual void OnDoActionExtension(const Property::Index actionId, Dali::Any attributes); + + /** * @brief Update the shader when some properties are changed. */ virtual void UpdateShader()