From f75ce14150b48f568d44169f66e3e31bfb3b04c4 Mon Sep 17 00:00:00 2001 From: Shinwoo Kim Date: Tue, 1 Jun 2021 09:53:50 +0900 Subject: [PATCH] [Tizen] Adds transition effect This reverts commit 789bfce68a6dd23c6ee8178ed7db91de485524b3. --- .../dali-test-suite-utils/test-custom-actor.cpp | 20 +++++++ .../dali/dali-test-suite-utils/test-custom-actor.h | 6 +- automated-tests/src/dali/utc-Dali-Actor.cpp | 69 ++++++++++++++++++++++ automated-tests/src/dali/utc-Dali-CustomActor.cpp | 25 +++++++- dali/devel-api/actors/actor-devel.cpp | 7 ++- dali/devel-api/actors/actor-devel.h | 8 +++ dali/internal/event/actors/actor-impl.cpp | 54 +++++++++++++++++ dali/internal/event/actors/actor-impl.h | 27 ++++++++- dali/internal/event/actors/actor-parent-impl.cpp | 60 ++++++++++++------- dali/internal/event/actors/actor-parent-impl.h | 19 ++++++ dali/internal/event/actors/custom-actor-internal.h | 16 +++++ dali/internal/update/nodes/node.cpp | 3 +- dali/internal/update/nodes/node.h | 22 +++++++ .../update/rendering/scene-graph-renderer.cpp | 6 +- dali/public-api/actors/custom-actor-impl.cpp | 12 +++- dali/public-api/actors/custom-actor-impl.h | 10 ++++ dali/public-api/file.list | 1 - 17 files changed, 335 insertions(+), 30 deletions(-) diff --git a/automated-tests/src/dali/dali-test-suite-utils/test-custom-actor.cpp b/automated-tests/src/dali/dali-test-suite-utils/test-custom-actor.cpp index e4f1099..87c141a 100644 --- a/automated-tests/src/dali/dali-test-suite-utils/test-custom-actor.cpp +++ b/automated-tests/src/dali/dali-test-suite-utils/test-custom-actor.cpp @@ -204,6 +204,16 @@ uint32_t TestCustomActor::GetDepth() return GetImpl().mDepth; } +void TestCustomActor::SetTransparent(bool transparent) +{ + return GetImpl().SetTransparent(transparent); +} + +bool TestCustomActor::GetTransparent() +{ + return GetImpl().GetTransparent(); +} + TestCustomActor::TestCustomActor() { } @@ -386,6 +396,16 @@ bool TestCustomActor::RelayoutDependentOnChildren(Dimension::Type dimension) return false; } +void TestCustomActor::SetTransparent(bool transparent) +{ + CustomActorImpl::SetTransparent(transparent); +} + +bool TestCustomActor::GetTransparent() const +{ + return CustomActorImpl::GetTransparent(); +} + void TestCustomActor::SetDaliProperty(std::string s) { Self().SetProperty(mDaliProperty, s); diff --git a/automated-tests/src/dali/dali-test-suite-utils/test-custom-actor.h b/automated-tests/src/dali/dali-test-suite-utils/test-custom-actor.h index ed11c58..83b1fd5 100644 --- a/automated-tests/src/dali/dali-test-suite-utils/test-custom-actor.h +++ b/automated-tests/src/dali/dali-test-suite-utils/test-custom-actor.h @@ -2,7 +2,7 @@ #define TEST_CUSTOM_ACTOR_H /* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. + * Copyright (c) 2021 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. @@ -89,6 +89,8 @@ public: float TestCalculateChildSizeBase(const Dali::Actor& child, Dali::Dimension::Type dimension); bool TestRelayoutDependentOnChildrenBase(Dali::Dimension::Type dimension); uint32_t GetDepth(); + void SetTransparent(bool transparent); + bool GetTransparent(); private: TestCustomActor(Impl::TestCustomActor& impl); @@ -146,6 +148,8 @@ public: float CalculateChildSize(const Dali::Actor& child, Dali::Dimension::Type dimension) override; void OnLayoutNegotiated(float size, Dali::Dimension::Type dimension) override; bool RelayoutDependentOnChildren(Dali::Dimension::Type dimension = Dali::Dimension::ALL_DIMENSIONS) override; + void SetTransparent(bool transparent) override; + bool GetTransparent() const override; static void SetProperty(Dali::BaseObject* object, Dali::Property::Index index, const Dali::Property::Value& value); static Dali::Property::Value GetProperty(Dali::BaseObject* object, Dali::Property::Index index); diff --git a/automated-tests/src/dali/utc-Dali-Actor.cpp b/automated-tests/src/dali/utc-Dali-Actor.cpp index 12dc2b7..eb3f4bc 100644 --- a/automated-tests/src/dali/utc-Dali-Actor.cpp +++ b/automated-tests/src/dali/utc-Dali-Actor.cpp @@ -637,6 +637,75 @@ int UtcDaliActorRemoveP(void) END_TEST; } +int UtcDaliActorSwitchParentP(void) +{ + tet_infoline("Testing Actor::UtcDaliActorSwitchParentP"); + TestApplication application; + + Actor parent1 = Actor::New(); + Actor child = Actor::New(); + + application.GetScene().Add(parent1); + + DALI_TEST_EQUALS(parent1.GetChildCount(), 0u, TEST_LOCATION); + + parent1.Add(child); + + DALI_TEST_EQUALS(parent1.GetChildCount(), 1u, TEST_LOCATION); + + Actor parent2 = Actor::New(); + application.GetScene().Add(parent2); + DevelActor::SwitchParent(child, parent2); + + DALI_TEST_EQUALS(parent1.GetChildCount(), 0u, TEST_LOCATION); + DALI_TEST_EQUALS(parent2.GetChildCount(), 1u, TEST_LOCATION); + + END_TEST; +} + +int UtcDaliActorSwitchParentN(void) +{ + tet_infoline("Testing Actor::UtcDaliActorSwitchParentN"); + TestApplication application; + + Actor parent1 = Actor::New(); + Actor child = Actor::New(); + + DALI_TEST_EQUALS(parent1.GetChildCount(), 0u, TEST_LOCATION); + + parent1.Add(child); + + DALI_TEST_EQUALS(parent1.GetChildCount(), 1u, TEST_LOCATION); + + Actor parent2 = Actor::New(); + + // Try switch parent with that both of parent1 and parent2 are off scene. + try + { + DevelActor::SwitchParent(child, parent2); + tet_printf("Assertion test failed - no Exception\n"); + tet_result(TET_FAIL); + } + catch(Dali::DaliException& e) + { + DALI_TEST_PRINT_ASSERT(e); + DALI_TEST_ASSERT(e, "parent", TEST_LOCATION); + DALI_TEST_EQUALS(parent1.GetChildCount(), 1u, TEST_LOCATION); + DALI_TEST_EQUALS(parent2.GetChildCount(), 0u, TEST_LOCATION); + application.GetScene().Add(parent1); + application.GetScene().Add(parent2); + DevelActor::SwitchParent(child, parent2); + DALI_TEST_EQUALS(parent1.GetChildCount(), 0u, TEST_LOCATION); + DALI_TEST_EQUALS(parent2.GetChildCount(), 1u, TEST_LOCATION); + } + catch(...) + { + tet_printf("Assertion test failed - wrong Exception\n"); + tet_result(TET_FAIL); + } + END_TEST; +} + int UtcDaliActorGetChildCount(void) { TestApplication application; diff --git a/automated-tests/src/dali/utc-Dali-CustomActor.cpp b/automated-tests/src/dali/utc-Dali-CustomActor.cpp index 208f563..235b5a8 100644 --- a/automated-tests/src/dali/utc-Dali-CustomActor.cpp +++ b/automated-tests/src/dali/utc-Dali-CustomActor.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. + * Copyright (c) 2021 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. @@ -1081,6 +1081,29 @@ int UtcDaliCustomActorCustomActor(void) END_TEST; } +int UtcDaliCustomActorImplSetTransparent(void) +{ + TestApplication application; // Need the type registry + + Test::TestCustomActor actor = Test::TestCustomActor::New(); + application.GetScene().Add(actor); + actor.SetProperty(Actor::Property::OPACITY, 0.1f); + actor.SetProperty(Actor::Property::SIZE, Vector2(400, 400)); + + DALI_TEST_EQUALS(false, actor.GetTransparent(), TEST_LOCATION); + + actor.SetTransparent(true); + + // flush the queue and render once + application.SendNotification(); + application.Render(); + + DALI_TEST_EQUALS(true, actor.GetTransparent(), TEST_LOCATION); + + application.GetScene().Remove(actor); + END_TEST; +} + int UtcDaliCustomActorImplRelayoutRequest(void) { TestApplication application; diff --git a/dali/devel-api/actors/actor-devel.cpp b/dali/devel-api/actors/actor-devel.cpp index fd08434..650fe92 100755 --- a/dali/devel-api/actors/actor-devel.cpp +++ b/dali/devel-api/actors/actor-devel.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. + * Copyright (c) 2021 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. @@ -53,6 +53,11 @@ Actor::TouchEventSignalType& InterceptTouchedSignal(Actor actor) return GetImplementation(actor).InterceptTouchedSignal(); } +void SwitchParent(Actor actor, Actor newParent) +{ + return GetImplementation(actor).SwitchParent(GetImplementation(newParent)); +} + } // namespace DevelActor } // namespace Dali diff --git a/dali/devel-api/actors/actor-devel.h b/dali/devel-api/actors/actor-devel.h index c340ccd..b642be4 100755 --- a/dali/devel-api/actors/actor-devel.h +++ b/dali/devel-api/actors/actor-devel.h @@ -291,6 +291,14 @@ DALI_CORE_API ChildOrderChangedSignalType& ChildOrderChangedSignal(Actor actor); */ DALI_CORE_API Actor::TouchEventSignalType& InterceptTouchedSignal(Actor actor); +/** + * Switch parent in the same tree. + * Both of current parent Actor and new parent Actor must be added on Scene. + * If not, use Add() instead. + * This method don't emit any notification such as off scene, on scene, added or removed. + */ +DALI_CORE_API void SwitchParent(Actor actor, Actor newParent); + } // namespace DevelActor } // namespace Dali diff --git a/dali/internal/event/actors/actor-impl.cpp b/dali/internal/event/actors/actor-impl.cpp index 776c3f3..a0cc1ff 100644 --- a/dali/internal/event/actors/actor-impl.cpp +++ b/dali/internal/event/actors/actor-impl.cpp @@ -1118,6 +1118,16 @@ DevelBlendEquation::Type Actor::GetBlendEquation() const return mBlendEquation; } +void Actor::SetTransparent(bool transparent) +{ + SetTransparentMessage(GetEventThreadServices(), GetNode(), transparent); +} + +bool Actor::GetTransparent() const +{ + return GetNode().GetTransparent(); +} + void Actor::SetDrawMode(DrawMode::Type drawMode) { // this flag is not animatable so keep the value @@ -1397,6 +1407,48 @@ void Actor::Remove(Actor& child) mParentImpl.Remove(child); } +void Actor::SwitchParent(Actor& newParent) +{ + DALI_ASSERT_ALWAYS(this != &newParent && "Cannot add actor to itself"); + + DALI_ASSERT_ALWAYS((this->OnScene() && newParent.OnScene()) && "Both of current parent and new parent must be on Scene"); + + Actor* oldParent = this->GetParent(); + if(oldParent->RemoveWithoutNotify(*this)) + { + // Only put in a relayout request if there is a suitable dependency + if(oldParent->RelayoutDependentOnChildren()) + { + oldParent->RelayoutRequest(); + } + } + + newParent.AddWithoutNotify(*this); + mParent = &newParent; + Actor* parentActor = static_cast(&newParent); + mScene = parentActor->mScene; + + // Resolve the name and index for the child properties if any + ResolveChildProperties(); + + this->InheritLayoutDirectionRecursively(newParent.GetLayoutDirection()); + // Only put in a relayout request if there is a suitable dependency + if(newParent.RelayoutDependentOnChildren()) + { + newParent.RelayoutRequest(); + } +} + +void Actor::AddWithoutNotify(Actor& child) +{ + mParentImpl.AddWithoutNotify(child); +} + +bool Actor::RemoveWithoutNotify(Actor& child) +{ + return mParentImpl.RemoveWithoutNotify(child); +} + uint32_t Actor::GetChildCount() const { return mParentImpl.GetChildCount(); @@ -1594,6 +1646,8 @@ void Actor::NotifyStageDisconnection() { mOnSceneSignalled = false; // signal required next time Actor is added } + + SetTransparent(false); } } diff --git a/dali/internal/event/actors/actor-impl.h b/dali/internal/event/actors/actor-impl.h index eb0ee82..c4b5b85 100644 --- a/dali/internal/event/actors/actor-impl.h +++ b/dali/internal/event/actors/actor-impl.h @@ -200,6 +200,21 @@ public: void Remove(Actor& child) override; /** + * @copydoc Dali::DevelActor::SwitchParent() + */ + void SwitchParent(Actor& newParent); + + /** + * @copydoc Dali::Internal::ActorParent::AddWithoutNotify() + */ + void AddWithoutNotify(Actor& child); + + /** + * @copydoc Dali::Internal::ActorParent::RemoveWithoutNotify() + */ + bool RemoveWithoutNotify(Actor& child); + + /** * @copydoc Dali::Actor::Unparent */ void Unparent(); @@ -1214,7 +1229,7 @@ public: void RemoveRenderer(uint32_t index); /** - * Set BlendEquation at each renderer that added on this Actor. + * @brief Set BlendEquation at each renderer that added on this Actor. */ void SetBlendEquation(DevelBlendEquation::Type blendEquation); @@ -1223,6 +1238,16 @@ public: */ DevelBlendEquation::Type GetBlendEquation() const; + /** + * @brief Set this Actor is transparent or not without any affection on the child Actors. + */ + virtual void SetTransparent(bool transparent); + + /** + * @brief Get this Actor is transparent or not. + */ + virtual bool GetTransparent() const; + public: /** * Converts screen coordinates into the actor's coordinate system. diff --git a/dali/internal/event/actors/actor-parent-impl.cpp b/dali/internal/event/actors/actor-parent-impl.cpp index c0101cc..87b02cd 100644 --- a/dali/internal/event/actors/actor-parent-impl.cpp +++ b/dali/internal/event/actors/actor-parent-impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. + * Copyright (c) 2021 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. @@ -62,11 +62,6 @@ void ActorParentImpl::Add(Actor& child) DALI_ASSERT_ALWAYS(&mOwner != &child && "Cannot add actor to itself"); DALI_ASSERT_ALWAYS(!child.IsRoot() && "Cannot add root actor"); - if(!mChildren) - { - mChildren = new ActorContainer; - } - Actor* oldParent = child.GetParent(); // child might already be ours @@ -88,7 +83,7 @@ void ActorParentImpl::Add(Actor& child) if(!child.GetParent()) { // Do this first, since user callbacks from within SetParent() may need to remove child - mChildren->push_back(ActorPtr(&child)); + AddWithoutNotify(child); // SetParent asserts that child can be added child.SetParent(&mOwner); @@ -110,10 +105,44 @@ void ActorParentImpl::Add(Actor& child) void ActorParentImpl::Remove(Actor& child) { + bool removed = RemoveWithoutNotify(child); + + if(removed) + { + child.SetParent(nullptr); + // Only put in a relayout request if there is a suitable dependency + if(mOwner.RelayoutDependentOnChildren()) + { + mOwner.RelayoutRequest(); + } + } + + // Notification for derived classes + mOwner.OnChildRemove(child); + EmitChildRemovedSignal(child); +} + +void ActorParentImpl::AddWithoutNotify(Actor& child) +{ + if(!mChildren) + { + mChildren = new ActorContainer; + } + + // child might already be ours + if(&mOwner != child.GetParent()) + { + // Do this first, since user callbacks from within SetParent() may need to remove child + mChildren->push_back(ActorPtr(&child)); + } +} + +bool ActorParentImpl::RemoveWithoutNotify(Actor& child) +{ if((&mOwner == &child) || (!mChildren)) { // no children or removing itself - return; + return false; } ActorPtr removed; @@ -133,24 +162,11 @@ void ActorParentImpl::Remove(Actor& child) mChildren->erase(iter); DALI_ASSERT_DEBUG(actor->GetParent() == &mOwner); - actor->SetParent(nullptr); break; } } - - if(removed) - { - // Only put in a relayout request if there is a suitable dependency - if(mOwner.RelayoutDependentOnChildren()) - { - mOwner.RelayoutRequest(); - } - } - - // Notification for derived classes - mOwner.OnChildRemove(child); - EmitChildRemovedSignal(child); + return removed; } uint32_t ActorParentImpl::GetChildCount() const diff --git a/dali/internal/event/actors/actor-parent-impl.h b/dali/internal/event/actors/actor-parent-impl.h index 0f05f80..16cea6c 100644 --- a/dali/internal/event/actors/actor-parent-impl.h +++ b/dali/internal/event/actors/actor-parent-impl.h @@ -62,6 +62,25 @@ public: void Remove(Actor& child); /** + * Adds a child Actor to this ActorParent. + * @pre The child actor is not the same as the parent actor. + * @pre The child actor could already have a parent. + * @param [in] child The child. + * @post The child will be referenced by its parent + * @note Even though child has already a parent, this method didn't emit off scene callback. + */ + void AddWithoutNotify(Actor& child); + + /** + * Removes a child Actor from this ActorParent. + * @param [in] child The child. + * @post The child will be unreferenced. + * @note This method do not call off scene callback of child. + * This method must be called just for switching parent Actor. + */ + bool RemoveWithoutNotify(Actor& child); + + /** * Retrieve the number of children held by the actor. * @return The number of children */ diff --git a/dali/internal/event/actors/custom-actor-internal.h b/dali/internal/event/actors/custom-actor-internal.h index a70d884..ab91dfa 100644 --- a/dali/internal/event/actors/custom-actor-internal.h +++ b/dali/internal/event/actors/custom-actor-internal.h @@ -62,6 +62,22 @@ public: */ Dali::TypeInfo GetTypeInfo(); + /** + * @copydoc Internal::CustomActorImpl::SetTransparent() + */ + void SetTransparent(bool transparent) override + { + Actor::SetTransparent(transparent); + } + + /** + * @copydoc Internal::CustomActorImpl::GetTransparent() + */ + bool GetTransparent() const override + { + return Actor::GetTransparent(); + } + protected: /** * A reference counted object may only be deleted by calling Unreference() diff --git a/dali/internal/update/nodes/node.cpp b/dali/internal/update/nodes/node.cpp index 662f3e7..ab3e9a2 100644 --- a/dali/internal/update/nodes/node.cpp +++ b/dali/internal/update/nodes/node.cpp @@ -101,7 +101,8 @@ Node::Node() mClippingMode(ClippingMode::DISABLED), mIsRoot(false), mIsLayer(false), - mPositionUsesAnchorPoint(true) + mPositionUsesAnchorPoint(true), + mTransparent(false) { mUniformMapChanged[0] = 0u; mUniformMapChanged[1] = 0u; diff --git a/dali/internal/update/nodes/node.h b/dali/internal/update/nodes/node.h index 6f6e681..07ce462 100644 --- a/dali/internal/update/nodes/node.h +++ b/dali/internal/update/nodes/node.h @@ -725,6 +725,16 @@ public: return mDrawMode; } + void SetTransparent(bool transparent) + { + mTransparent = transparent; + } + + bool GetTransparent() const + { + return mTransparent; + } + /* * Returns the transform id of the node * @return The transform component id of the node @@ -954,6 +964,7 @@ protected: bool mIsRoot : 1; ///< True if the node cannot have a parent bool mIsLayer : 1; ///< True if the node is a layer bool mPositionUsesAnchorPoint : 1; ///< True if the node should use the anchor-point when calculating the position + bool mTransparent : 1; // Changes scope, should be at end of class DALI_LOG_OBJECT_STRING_DECLARATION; @@ -1038,6 +1049,17 @@ inline void SetDrawModeMessage(EventThreadServices& eventThreadServices, const N new(slot) LocalType(&node, &Node::SetDrawMode, drawMode); } +inline void SetTransparentMessage(EventThreadServices& eventThreadServices, const Node& node, bool transparent) +{ + using LocalType = MessageValue1; + + // Reserve some memory inside the message queue + uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType)); + + // Construct message in the message queue memory; note that delete should not be called on the return value + new(slot) LocalType(&node, &Node::SetTransparent, transparent); +} + inline void DetachRendererMessage(EventThreadServices& eventThreadServices, const Node& node, const Renderer& renderer) { using LocalType = MessageValue1; diff --git a/dali/internal/update/rendering/scene-graph-renderer.cpp b/dali/internal/update/rendering/scene-graph-renderer.cpp index d09f835..075cd38 100644 --- a/dali/internal/update/rendering/scene-graph-renderer.cpp +++ b/dali/internal/update/rendering/scene-graph-renderer.cpp @@ -191,7 +191,6 @@ bool Renderer::PrepareRender(BufferIndex updateBufferIndex) const UniformMap& rendererUniformMap = PropertyOwner::GetUniformMap(); auto size = rendererUniformMap.Count(); - if(mShader) { size += mShader->GetUniformMap().Count(); @@ -696,6 +695,11 @@ Renderer::OpacityType Renderer::GetOpacityType(BufferIndex updateBufferIndex, co { Renderer::OpacityType opacityType = Renderer::OPAQUE; + if(node.GetTransparent()) + { + return Renderer::TRANSPARENT; + } + switch(mBlendMode) { case BlendMode::ON: // If the renderer should always be use blending diff --git a/dali/public-api/actors/custom-actor-impl.cpp b/dali/public-api/actors/custom-actor-impl.cpp index 1ff533b..d42e57e 100644 --- a/dali/public-api/actors/custom-actor-impl.cpp +++ b/dali/public-api/actors/custom-actor-impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. + * Copyright (c) 2021 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. @@ -83,4 +83,14 @@ bool CustomActorImpl::RelayoutDependentOnChildrenBase(Dimension::Type dimension) return mOwner->RelayoutDependentOnChildrenBase(dimension); } +void CustomActorImpl::SetTransparent(bool transparent) +{ + mOwner->SetTransparent(transparent); +} + +bool CustomActorImpl::GetTransparent() const +{ + return mOwner->GetTransparent(); +} + } // namespace Dali diff --git a/dali/public-api/actors/custom-actor-impl.h b/dali/public-api/actors/custom-actor-impl.h index 1400f45..9c512bd 100644 --- a/dali/public-api/actors/custom-actor-impl.h +++ b/dali/public-api/actors/custom-actor-impl.h @@ -353,6 +353,16 @@ protected: // For derived classes */ bool RelayoutDependentOnChildrenBase(Dimension::Type dimension = Dimension::ALL_DIMENSIONS); + /** + * @brief Set this CustomActor is transparent or not without any affection on the child Actors. + */ + virtual void SetTransparent(bool transparent); + + /** + * @brief Get this CustomActor is transparent or not. + */ + virtual bool GetTransparent() const; + public: // Not intended for application developers /** * @brief Initializes a CustomActor. diff --git a/dali/public-api/file.list b/dali/public-api/file.list index 43b1478..32844da 100644 --- a/dali/public-api/file.list +++ b/dali/public-api/file.list @@ -116,7 +116,6 @@ SET( public_api_core_animation_header_files ${public_api_src_dir}/animation/time-period.h ) - SET( public_api_core_common_header_files ${public_api_src_dir}/common/constants.h ${public_api_src_dir}/common/dali-common.h -- 2.7.4