return GetImpl().mDepth;
}
+void TestCustomActor::SetTransparent(bool transparent)
+{
+ return GetImpl().SetTransparent(transparent);
+}
+
+bool TestCustomActor::GetTransparent()
+{
+ return GetImpl().GetTransparent();
+}
+
TestCustomActor::TestCustomActor()
{
}
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);
#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.
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);
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);
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;
/*
- * 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.
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;
/*
- * 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.
{
}
- virtual void Process()
+ virtual void Process(bool postProcessor)
{
processRun = true;
}
DALI_TEST_CHECK(testProcessor3.processRun);
END_TEST;
+}
+
+int UtcDaliCorePostProcessorP(void)
+{
+ TestApplication application;
+
+ TestProcessor testProcessor;
+ Integration::Core& core = application.GetCore();
+ core.RegisterProcessor(testProcessor, true);
+
+ tet_infoline("Test that the processor has not been executed yet:");
+ DALI_TEST_CHECK(testProcessor.processRun == false);
+
+ application.SendNotification();
+
+ tet_infoline("Test that the processor has been executed:");
+ DALI_TEST_CHECK(testProcessor.processRun);
+
+ // Clear down for next part of test
+ testProcessor.processRun = false;
+
+ core.UnregisterProcessor(testProcessor);
+ application.SendNotification();
+ tet_infoline("Test that the processor is still executed:");
+ DALI_TEST_CHECK(testProcessor.processRun);
+
+ // Clear down for next part of test
+ testProcessor.processRun = false;
+
+ core.UnregisterProcessor(testProcessor, true);
+ application.SendNotification();
+ tet_infoline("Test that the processor has not been executed again:");
+ DALI_TEST_CHECK(testProcessor.processRun == false);
+
+ END_TEST;
}
\ No newline at end of file
/*
- * 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.
return GetImplementation(actor).InterceptTouchedSignal();
}
+void SwitchParent(Actor actor, Actor newParent)
+{
+ return GetImplementation(actor).SwitchParent(GetImplementation(newParent));
+}
+
} // namespace DevelActor
} // namespace Dali
#define DALI_ACTOR_DEVEL_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.
*/
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
mImpl->PostRender(uploadOnly);
}
-void Core::RegisterProcessor(Processor& processor)
+void Core::RegisterProcessor(Processor& processor, bool postProcessor)
{
- mImpl->RegisterProcessor(processor);
+ mImpl->RegisterProcessor(processor, postProcessor);
}
-void Core::UnregisterProcessor(Processor& processor)
+void Core::UnregisterProcessor(Processor& processor, bool postProcessor)
{
- mImpl->UnregisterProcessor(processor);
+ mImpl->UnregisterProcessor(processor, postProcessor);
}
ObjectRegistry Core::GetObjectRegistry() const
*
* Note, Core does not take ownership of this processor.
* @param[in] processor The process to register
+ * @param[in] postProcessor set this processor required to be called after size negotiation. Default is false.
*/
- void RegisterProcessor(Processor& processor);
+ void RegisterProcessor(Processor& processor, bool postProcessor = false);
/**
* @brief Unregister a processor
* @param[in] processor The process to unregister
+ * @param[in] postProcessor True if the processor to be unregister is for post processor.
*/
- void UnregisterProcessor(Processor& processor);
+ void UnregisterProcessor(Processor& processor, bool postProcessor = false);
/**
* @brief Gets the Object registry.
#define DALI_INTEGRATION_PROCESSOR_INTERFACE_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.
/**
* @brief Run the processor
*/
- virtual void Process() = 0;
+ virtual void Process(bool postProcessor = false) = 0;
protected:
/**
// Run the size negotiation after event processing finished signal
mRelayoutController->Relayout();
+ // Run any registered post processors
+ RunPostProcessors();
+
// Rebuild depth tree after event processing has finished
for(auto scene : scenes)
{
return MAXIMUM_UPDATE_COUNT;
}
-void Core::RegisterProcessor(Integration::Processor& processor)
+void Core::RegisterProcessor(Integration::Processor& processor, bool postProcessor)
{
- mProcessors.PushBack(&processor);
+ if(postProcessor)
+ {
+ mPostProcessors.PushBack(&processor);
+ }
+ else
+ {
+ mProcessors.PushBack(&processor);
+ }
}
-void Core::UnregisterProcessor(Integration::Processor& processor)
+void Core::UnregisterProcessor(Integration::Processor& processor, bool postProcessor)
{
- auto iter = std::find(mProcessors.Begin(), mProcessors.End(), &processor);
- if(iter != mProcessors.End())
+ if(postProcessor)
{
- mProcessors.Erase(iter);
+ auto iter = std::find(mPostProcessors.Begin(), mPostProcessors.End(), &processor);
+ if(iter != mPostProcessors.End())
+ {
+ mPostProcessors.Erase(iter);
+ }
+ }
+ else
+ {
+ auto iter = std::find(mProcessors.Begin(), mProcessors.End(), &processor);
+ if(iter != mProcessors.End())
+ {
+ mProcessors.Erase(iter);
+ }
}
}
{
if(processor)
{
- processor->Process();
+ processor->Process(false);
+ }
+ }
+}
+
+void Core::RunPostProcessors()
+{
+ // Copy processor pointers to prevent changes to vector affecting loop iterator.
+ Dali::Vector<Integration::Processor*> processors(mPostProcessors);
+
+ for(auto processor : processors)
+ {
+ if(processor)
+ {
+ processor->Process(true);
}
}
}
/**
* @copydoc Dali::Integration::Core::RegisterProcessor
*/
- void RegisterProcessor(Dali::Integration::Processor& processor);
+ void RegisterProcessor(Integration::Processor& processor, bool postProcessor = false);
/**
* @copydoc Dali::Integration::Core::UnregisterProcessor
*/
- void UnregisterProcessor(Dali::Integration::Processor& processor);
+ void UnregisterProcessor(Dali::Integration::Processor& processor, bool postProcessor = false);
/**
* @copydoc Dali::Internal::ThreadLocalStorage::AddScene()
*/
void RunProcessors();
+ /**
+ * Run each registered postprocessor
+ */
+ void RunPostProcessors();
+
// for use by ThreadLocalStorage
/**
OwnerPointer<NotificationManager> mNotificationManager; ///< Notification manager
OwnerPointer<GestureEventProcessor> mGestureEventProcessor; ///< The gesture event processor
Dali::Vector<Integration::Processor*> mProcessors; ///< Registered processors (not owned)
+ Dali::Vector<Integration::Processor*> mPostProcessors; ///< Registered post processors those will called after relayout(not owned)
using SceneContainer = std::vector<ScenePtr>;
SceneContainer mScenes; ///< A container of scenes that bound to a surface for rendering, owned by Core
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
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<Actor*>(&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();
{
mOnSceneSignalled = false; // signal required next time Actor is added
}
+
+ SetTransparent(false);
}
}
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();
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);
*/
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.
/*
- * 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.
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
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);
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;
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
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
*/
/*
- * 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.
*/
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()
mClippingMode(ClippingMode::DISABLED),
mIsRoot(false),
mIsLayer(false),
- mPositionUsesAnchorPoint(true)
+ mPositionUsesAnchorPoint(true),
+ mTransparent(false)
{
mUniformMapChanged[0] = 0u;
mUniformMapChanged[1] = 0u;
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
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;
new(slot) LocalType(&node, &Node::SetDrawMode, drawMode);
}
+inline void SetTransparentMessage(EventThreadServices& eventThreadServices, const Node& node, bool transparent)
+{
+ using LocalType = MessageValue1<Node, bool>;
+
+ // 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<Node, const Renderer*>;
const UniformMap& rendererUniformMap = PropertyOwner::GetUniformMap();
auto size = rendererUniformMap.Count();
-
if(mShader)
{
size += mShader->GetUniformMap().Count();
{
Renderer::OpacityType opacityType = Renderer::OPAQUE;
+ if(node.GetTransparent())
+ {
+ return Renderer::TRANSPARENT;
+ }
+
switch(mBlendMode)
{
case BlendMode::ON: // If the renderer should always be use blending
/*
- * 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.
return mOwner->RelayoutDependentOnChildrenBase(dimension);
}
+void CustomActorImpl::SetTransparent(bool transparent)
+{
+ mOwner->SetTransparent(transparent);
+}
+
+bool CustomActorImpl::GetTransparent() const
+{
+ return mOwner->GetTransparent();
+}
+
} // namespace Dali
*/
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.
${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