Let we implement NUI specific Visual policy.
1. Let we allow to set visual as BaseHandle class.
2. Allow to change the property of visual
- Previous implements only able to change the PropertyMap.
This concept is not matched with C# standard coding rule.
Thus, we need to make a class, that keep whole properties at C# side.
3. Allow to change the order of rendering order.
- For limitation ; We allow this visual only used between Background and Contents.
4. Do not allow to make AnimatedImageVisual if we don't use Animated flags
Change-Id: I47940c91ed853b83235119e16221aea1b27087c5
Signed-off-by: Eunki, Hong <eunkiki.hong@samsung.com>
--- /dev/null
+/*
+ * Copyright (c) 2024 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <dali-csharp-binder/common/visual-objects/visual-object-impl.h>
+
+// EXTERNAL INCLUDES
+#include <dali-toolkit/devel-api/controls/control-depth-index-ranges.h>
+#include <dali-toolkit/devel-api/visual-factory/visual-factory.h>
+#include <dali/integration-api/adaptor-framework/adaptor.h>
+#include <dali/integration-api/debug.h>
+
+// INTERNAL
+#include <dali-csharp-binder/common/visual-objects/visual-object.h>
+#include <dali-csharp-binder/common/visual-objects/visual-objects-container-impl.h>
+#include <dali-csharp-binder/common/visual-objects/visual-objects-container.h>
+
+namespace Dali::Internal
+{
+VisualObjectPtr VisualObject::New()
+{
+ VisualObjectPtr visualObject(new VisualObject());
+ return visualObject;
+}
+
+///< Public API
+
+void VisualObject::DetachFromContainer()
+{
+ if(auto container = mContainer.GetHandle())
+ {
+ container.RemoveVisualObject(Dali::VisualObject(this));
+ }
+ DetachFromContainerInternal();
+}
+
+Dali::VisualObjectsContainer VisualObject::GetContainer()
+{
+ return mContainer.GetHandle();
+}
+
+void VisualObject::CreateVisual(const Dali::Property::Map& map)
+{
+ if(Dali::Adaptor::IsAvailable())
+ {
+ auto visualFactory = Dali::Toolkit::VisualFactory::Get();
+ if(visualFactory)
+ {
+ if(!map.Empty())
+ {
+ mVisual = visualFactory.CreateVisual(map, Dali::Toolkit::VisualFactory::CreationOptions::IMAGE_VISUAL_LOAD_STATIC_IMAGES_ONLY);
+ }
+ else
+ {
+ // Special behavior, if map is empty, unregister the visual.
+ mVisual.Reset();
+ }
+ }
+
+ // Replace as newly created visual now.
+ if(auto container = mContainer.GetHandle())
+ {
+ GetImplementation(container).ReplaceVisualObject(*this);
+ }
+ }
+}
+
+void VisualObject::RetrieveVisualPropertyMap(Dali::Property::Map& map) const
+{
+ if(mVisual)
+ {
+ mVisual.CreatePropertyMap(map);
+ }
+}
+
+void VisualObject::DoAction(Dali::Property::Index actionId, const Dali::Property::Value& attributes)
+{
+ if(mVisual)
+ {
+ mVisual.DoAction(actionId, attributes);
+ }
+}
+
+/// Sibling Order Change API
+
+void VisualObject::SetSiblingOrder(uint32_t siblingOrder)
+{
+ auto container = mContainer.GetHandle();
+ if(container && mSiblingOrder != siblingOrder)
+ {
+ GetImplementation(container).ChangeSiblingOrder(mSiblingOrder, siblingOrder);
+ }
+}
+
+uint32_t VisualObject::GetSiblingOrder() const
+{
+ // If we are not in container, return 0.
+ if(!mContainer.GetHandle())
+ {
+ return 0u;
+ }
+ return mSiblingOrder;
+}
+
+void VisualObject::Raise()
+{
+ auto container = mContainer.GetHandle();
+ if(container)
+ {
+ if(mSiblingOrder + 1u < container.GetVisualObjectsCount())
+ {
+ SetSiblingOrder(mSiblingOrder + 1u);
+ }
+ }
+}
+
+void VisualObject::Lower()
+{
+ auto container = mContainer.GetHandle();
+ if(container)
+ {
+ if(mSiblingOrder > 0u)
+ {
+ SetSiblingOrder(mSiblingOrder - 1u);
+ }
+ }
+}
+
+void VisualObject::RaiseToTop()
+{
+ auto container = mContainer.GetHandle();
+ if(container && container.GetVisualObjectsCount() > 0u)
+ {
+ SetSiblingOrder(container.GetVisualObjectsCount() - 1u);
+ }
+}
+
+void VisualObject::LowerToBottom()
+{
+ auto container = mContainer.GetHandle();
+ if(container)
+ {
+ SetSiblingOrder(0u);
+ }
+}
+
+void VisualObject::RaiseAbove(Dali::Internal::VisualObject& target)
+{
+ auto container = mContainer.GetHandle();
+ // Check whether target and this is in the same container.
+ if(container && container == target.GetContainer())
+ {
+ uint32_t fromIndex = mSiblingOrder;
+ uint32_t toIndex = target.GetSiblingOrder();
+
+ // Change sibling order only if fromIndex is less than toIndex.
+ // Note : target's sibling order will be updated automatically.
+ if(fromIndex < toIndex)
+ {
+ SetSiblingOrder(toIndex);
+ }
+ }
+}
+
+void VisualObject::LowerBelow(Dali::Internal::VisualObject& target)
+{
+ auto container = mContainer.GetHandle();
+ // Check whether target and this is in the same container.
+ if(container && container == target.GetContainer())
+ {
+ uint32_t fromIndex = mSiblingOrder;
+ uint32_t toIndex = target.GetSiblingOrder();
+
+ // Change sibling order only if fromIndex is greater than toIndex.
+ // Note : target's sibling order will be updated automatically.
+ if(fromIndex > toIndex)
+ {
+ SetSiblingOrder(toIndex);
+ }
+ }
+}
+
+// Private and internal
+
+void VisualObject::AttachToContainerInternal(Dali::VisualObjectsContainer container)
+{
+ mContainer = WeakHandle(container);
+ mRangeType = container.GetContainerRangeType();
+}
+
+void VisualObject::DetachFromContainerInternal()
+{
+ mContainer.Reset();
+ mSiblingOrder = 0u;
+ mVisualPropertyId = INVALID_VISUAL_PROPERTY_ID;
+}
+
+void VisualObject::SetSiblingOrderInternal(uint32_t siblingOrder)
+{
+ mSiblingOrder = siblingOrder;
+ if(mVisual)
+ {
+ mVisual.SetDepthIndex(GetDepthIndex());
+ }
+}
+
+int32_t VisualObject::GetDepthIndex() const
+{
+ int32_t baseDepthIndex = 0;
+ switch(mRangeType)
+ {
+ case Dali::VisualObjectsContainer::ContainerRangeType::BACKGROUND_EFFECT:
+ {
+ baseDepthIndex = Dali::Toolkit::DepthIndex::Ranges::MINIMUM_DEPTH_INDEX + 1;
+ break;
+ }
+ case Dali::VisualObjectsContainer::ContainerRangeType::BACKGROUND:
+ {
+ baseDepthIndex = Dali::Toolkit::DepthIndex::Ranges::BACKGROUND_EFFECT + 1;
+ break;
+ }
+ case Dali::VisualObjectsContainer::ContainerRangeType::CONTENT:
+ {
+ baseDepthIndex = Dali::Toolkit::DepthIndex::Ranges::BACKGROUND + 1;
+ break;
+ }
+ case Dali::VisualObjectsContainer::ContainerRangeType::DECORATION:
+ {
+ baseDepthIndex = Dali::Toolkit::DepthIndex::Ranges::CONTENT + 4; /* Give some gap from CONTENT. */
+ break;
+ }
+ case Dali::VisualObjectsContainer::ContainerRangeType::FOREGROUND_EFFECT:
+ {
+ baseDepthIndex = Dali::Toolkit::DepthIndex::Ranges::DECORATION + 1;
+ break;
+ }
+ }
+ return baseDepthIndex + static_cast<int32_t>(mSiblingOrder);
+}
+
+VisualObject::VisualObject()
+: mContainer(),
+ mVisual(),
+ mSiblingOrder(0u),
+ mVisualPropertyId(VisualObject::INVALID_VISUAL_PROPERTY_ID)
+{
+}
+
+VisualObject::~VisualObject()
+{
+ if(DALI_LIKELY(Dali::Adaptor::IsAvailable()))
+ {
+ DetachFromContainerInternal();
+
+ if(mVisual)
+ {
+ auto visualFactory = Dali::Toolkit::VisualFactory::Get();
+ if(visualFactory)
+ {
+ visualFactory.DiscardVisual(std::move(mVisual));
+ }
+ }
+ }
+}
+
+} // namespace Dali::Internal
\ No newline at end of file
--- /dev/null
+#ifndef CSHARP_VISUAL_OBJECT_IMPL_H
+#define CSHARP_VISUAL_OBJECT_IMPL_H
+
+/*
+ * Copyright (c) 2024 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali-toolkit/devel-api/visual-factory/visual-base.h>
+#include <dali/public-api/common/dali-common.h>
+#include <dali/public-api/common/intrusive-ptr.h>
+#include <dali/public-api/object/base-object.h>
+#include <dali/public-api/object/property-map.h>
+#include <dali/public-api/object/weak-handle.h>
+#include <limits>
+
+// INTERNAL INCLUDES
+#include <dali-csharp-binder/common/visual-objects/visual-object.h>
+#include <dali-csharp-binder/common/visual-objects/visual-objects-container.h>
+
+namespace Dali
+{
+namespace Internal
+{
+class VisualObject;
+using VisualObjectPtr = Dali::IntrusivePtr<VisualObject>;
+
+class VisualObject : public Dali::BaseObject
+{
+public:
+ using VisualPropertyId = uint32_t;
+ static constexpr VisualPropertyId INVALID_VISUAL_PROPERTY_ID = std::numeric_limits<VisualPropertyId>::max();
+
+ /**
+ * @brief Creates a VisualObject object.
+ *
+ * @SINCE_2_3.27
+ * @return The newly created visual object.
+ */
+ static VisualObjectPtr New();
+
+public: ///< Public API
+ /**
+ * @copydoc Dali::VisualObject::DetachFromContainer()
+ */
+ void DetachFromContainer();
+
+ /**
+ * @copydoc Dali::VisualObject::GetContainer()
+ */
+ Dali::VisualObjectsContainer GetContainer();
+
+ /**
+ * @copydoc Dali::VisualObject::CreateVisual()
+ */
+ void CreateVisual(const Dali::Property::Map& map);
+
+ /**
+ * @copydoc Dali::VisualObject::RetrieveVisualProperty()
+ */
+ void RetrieveVisualPropertyMap(Dali::Property::Map& map) const;
+
+ /**
+ * @copydoc Dali::VisualObject::DoAction()
+ */
+ void DoAction(Dali::Property::Index actionId, const Dali::Property::Value& attributes);
+
+ /// Sibling Order Change API
+
+ /**
+ * @copydoc Dali::VisualObject::SetSiblingOrder()
+ */
+ void SetSiblingOrder(uint32_t siblingOrder);
+
+ /**
+ * @copydoc Dali::VisualObject::GetSiblingOrder()
+ */
+ uint32_t GetSiblingOrder() const;
+
+ /**
+ * @copydoc Dali::VisualObject::Raise()
+ */
+ void Raise();
+
+ /**
+ * @copydoc Dali::VisualObject::Lower()
+ */
+ void Lower();
+
+ /**
+ * @copydoc Dali::VisualObject::RaiseToTop()
+ */
+ void RaiseToTop();
+
+ /**
+ * @copydoc Dali::VisualObject::LowerToBottom()
+ */
+ void LowerToBottom();
+
+ /**
+ * @copydoc Dali::VisualObject::RaiseAbove()
+ */
+ void RaiseAbove(Dali::Internal::VisualObject& target);
+
+ /**
+ * @copydoc Dali::VisualObject::LowerBelow()
+ */
+ void LowerBelow(Dali::Internal::VisualObject& target);
+
+public: ///< Called from Internal::VisualObjectsContainer
+ /**
+ * @brief Set the container who contain this visual object.
+ * @note It should be called only from Internal::VisualObject or Internal::VisualObjectsContainer.
+ *
+ * @param[in] container VisualObjectsContainer who contain this visual object. Or empty container if visual object is not in container.
+ */
+ void AttachToContainerInternal(Dali::VisualObjectsContainer container);
+
+ /**
+ * @brief Detach from container without change the container.
+ * @note It should be called only from Internal::VisualObject or Internal::VisualObjectsContainer.
+ */
+ void DetachFromContainerInternal();
+
+ /**
+ * @brief Set the sibling order without change the container.
+ * @note It should be called only from Internal::VisualObject or Internal::VisualObjectsContainer.
+ *
+ * @param[in] siblingOrder The sibling order inside of the container.
+ */
+ void SetSiblingOrderInternal(uint32_t siblingOrder);
+
+ /**
+ * @brief Get the depth index of visual, depend by sibling order.
+ * @note It should be called only from Internal::VisualObject or Internal::VisualObjectsContainer.
+ *
+ * @return The depth index of visual.
+ */
+ int32_t GetDepthIndex() const;
+
+ /**
+ * @brief Get the Visual::Base object what this object hold.
+ * @note It should be called only from Internal::VisualObject or Internal::VisualObjectsContainer.
+ *
+ * @return Latest created Visual::Base object created by VisualObject::CreateVisual();
+ */
+ Dali::Toolkit::Visual::Base GetVisual()
+ {
+ return mVisual;
+ }
+
+ /**
+ * @brief Set the unique id of visual what it registered into control.
+ *
+ * @param[in] visualPropertyId The id of visual property registered.
+ */
+ void SetVisualPropertyId(VisualPropertyId visualPropertyId)
+ {
+ mVisualPropertyId = visualPropertyId;
+ }
+
+ /**
+ * @brief Get the unique id of visual what it registered into control.
+ *
+ * @return The id of visual property registered
+ */
+ VisualPropertyId GetVisualPropertyId() const
+ {
+ return mVisualPropertyId;
+ }
+
+public:
+ /**
+ * @brief Constructor - creates a VisualObject.
+ */
+ VisualObject();
+
+ /**
+ * @brief Destructor.
+ */
+ ~VisualObject() override;
+
+private:
+ Dali::WeakHandle<Dali::VisualObjectsContainer> mContainer;
+
+ Dali::Toolkit::Visual::Base mVisual;
+
+ Dali::VisualObjectsContainer::ContainerRangeType mRangeType{Dali::VisualObjectsContainer::ContainerRangeType::CONTENT};
+
+ uint32_t mSiblingOrder{0u};
+ uint32_t mVisualPropertyId{INVALID_VISUAL_PROPERTY_ID};
+};
+} // namespace Internal
+
+// Helpers for api forwarding methods
+
+inline static Internal::VisualObject& GetImplementation(Dali::VisualObject& handle)
+{
+ DALI_ASSERT_ALWAYS(handle && "VisualObject handle is empty.");
+
+ Dali::BaseObject& object = handle.GetBaseObject();
+
+ return static_cast<Internal::VisualObject&>(object);
+}
+
+inline static const Internal::VisualObject& GetImplementation(const Dali::VisualObject& handle)
+{
+ DALI_ASSERT_ALWAYS(handle && "VisualObject handle is empty.");
+
+ const Dali::BaseObject& object = handle.GetBaseObject();
+
+ return static_cast<const Internal::VisualObject&>(object);
+}
+
+} // namespace Dali
+
+#endif // CSHARP_VISUAL_OBJECT_IMPL_H
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2024 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <dali-csharp-binder/common/visual-objects/visual-object.h>
+
+// EXTERNAL INCLUDES
+#include <dali-toolkit/devel-api/visuals/visual-actions-devel.h>
+#include <dali/integration-api/debug.h>
+
+// INTERNAL INCLUDES
+#include <dali-csharp-binder/common/common.h>
+#include <dali-csharp-binder/common/visual-objects/visual-object-impl.h>
+
+namespace Dali
+{
+VisualObject::VisualObject(Dali::Internal::VisualObject* object)
+: BaseHandle(object)
+{
+}
+
+VisualObject VisualObject::New()
+{
+ Internal::VisualObjectPtr internal = Internal::VisualObject::New();
+ return VisualObject(internal.Get());
+}
+
+///< Public API
+
+void VisualObject::DetachFromContainer()
+{
+ GetImplementation(*this).DetachFromContainer();
+}
+
+Dali::VisualObjectsContainer VisualObject::GetContainer()
+{
+ return GetImplementation(*this).GetContainer();
+}
+
+void VisualObject::CreateVisual(const Dali::Property::Map& map)
+{
+ GetImplementation(*this).CreateVisual(map);
+}
+
+void VisualObject::DoAction(Dali::Property::Index actionId, const Dali::Property::Value& attributes)
+{
+ GetImplementation(*this).DoAction(actionId, attributes);
+}
+
+void VisualObject::RetrieveVisualPropertyMap(Dali::Property::Map& map) const
+{
+ GetImplementation(*this).RetrieveVisualPropertyMap(map);
+}
+
+/// Sibling Order Change API
+
+void VisualObject::SetSiblingOrder(uint32_t siblingOrder)
+{
+ GetImplementation(*this).SetSiblingOrder(siblingOrder);
+}
+
+uint32_t VisualObject::GetSiblingOrder() const
+{
+ return GetImplementation(*this).GetSiblingOrder();
+}
+
+void VisualObject::Raise()
+{
+ GetImplementation(*this).Raise();
+}
+
+void VisualObject::Lower()
+{
+ GetImplementation(*this).Lower();
+}
+
+void VisualObject::RaiseToTop()
+{
+ GetImplementation(*this).RaiseToTop();
+}
+
+void VisualObject::LowerToBottom()
+{
+ GetImplementation(*this).LowerToBottom();
+}
+
+void VisualObject::RaiseAbove(Dali::VisualObject target)
+{
+ GetImplementation(*this).RaiseAbove(GetImplementation(target));
+}
+
+void VisualObject::LowerBelow(Dali::VisualObject target)
+{
+ GetImplementation(*this).LowerBelow(GetImplementation(target));
+}
+
+} // namespace Dali
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+SWIGEXPORT void* SWIGSTDCALL CSharp_Dali_new_VisualObject__SWIG_0()
+{
+ Dali::VisualObject* result = 0;
+
+ try_catch(([&]() {
+ result = (Dali::VisualObject*)new Dali::VisualObject();
+ }));
+
+ return (void*)result;
+}
+
+SWIGEXPORT void* SWIGSTDCALL CSharp_Dali_VisualObject_New()
+{
+ void* jresult = 0;
+ Dali::VisualObject result;
+
+ try_catch(([&]() {
+ result = Dali::VisualObject::New();
+ }));
+
+ jresult = new Dali::VisualObject((const Dali::VisualObject&)result);
+ return jresult;
+}
+
+SWIGEXPORT void SWIGSTDCALL CSharp_Dali_delete_VisualObject(void* nuiVisualObject)
+{
+ Dali::VisualObject* visualObject = (Dali::VisualObject*)0;
+
+ visualObject = (Dali::VisualObject*)nuiVisualObject;
+ try_catch(([&]() {
+ delete visualObject;
+ }));
+}
+
+SWIGEXPORT void SWIGSTDCALL CSharp_Dali_VisualObject_DetachFromContainer(void* nuiVisualObject)
+{
+ Dali::VisualObject* visualObject = (Dali::VisualObject*)0;
+
+ GUARD_ON_NULL_RET(nuiVisualObject);
+
+ visualObject = (Dali::VisualObject*)nuiVisualObject;
+ try_catch(([&]() {
+ visualObject->DetachFromContainer();
+ }));
+}
+
+SWIGEXPORT void* SWIGSTDCALL CSharp_Dali_VisualObject_GetContainer(void* nuiVisualObject)
+{
+ void* jresult = 0;
+ Dali::VisualObject* visualObject = (Dali::VisualObject*)0;
+ Dali::VisualObjectsContainer result;
+
+ GUARD_ON_NULL_RET0(nuiVisualObject);
+
+ visualObject = (Dali::VisualObject*)nuiVisualObject;
+ try_catch(([&]() {
+ result = visualObject->GetContainer();
+ }));
+
+ jresult = new Dali::VisualObjectsContainer((const Dali::VisualObjectsContainer&)result);
+ return jresult;
+}
+
+SWIGEXPORT void SWIGSTDCALL CSharp_Dali_VisualObject_CreateVisual(void* nuiVisualObject, void* nuiPropertyMap)
+{
+ Dali::VisualObject* visualObject = (Dali::VisualObject*)0;
+ Dali::Property::Map propertyMap;
+
+ GUARD_ON_NULL_RET(nuiVisualObject);
+
+ // We allow to set null for nuiPropertyMap.
+
+ visualObject = (Dali::VisualObject*)nuiVisualObject;
+ propertyMap = nuiPropertyMap ? *((const Dali::Property::Map*)nuiPropertyMap) : Dali::Property::Map();
+ try_catch(([&]() {
+ visualObject->CreateVisual(propertyMap);
+ }));
+}
+
+SWIGEXPORT void SWIGSTDCALL CSharp_Dali_VisualObject_RetrieveVisualPropertyMap(void* nuiVisualObject, void* nuiPropertyMap)
+{
+ const Dali::VisualObject* visualObject = (const Dali::VisualObject*)0;
+ Dali::Property::Map* propertyMap = (Dali::Property::Map*)0;
+
+ GUARD_ON_NULL_RET(nuiVisualObject);
+ GUARD_ON_NULL_RET(nuiPropertyMap);
+
+ visualObject = (const Dali::VisualObject*)nuiVisualObject;
+ propertyMap = (Dali::Property::Map*)nuiPropertyMap;
+ try_catch(([&]() {
+ visualObject->RetrieveVisualPropertyMap(*propertyMap);
+ }));
+}
+
+SWIGEXPORT void SWIGSTDCALL CSharp_Dali_VisualObject_DoAction_UpdatePropertyMap(void* nuiVisualObject, void* nuiPropertyMap)
+{
+ Dali::VisualObject* visualObject = (Dali::VisualObject*)0;
+ Dali::Property::Map* propertyMap = (Dali::Property::Map*)0;
+
+ GUARD_ON_NULL_RET(nuiVisualObject);
+ GUARD_ON_NULL_RET(nuiPropertyMap);
+
+ visualObject = (Dali::VisualObject*)nuiVisualObject;
+ propertyMap = (Dali::Property::Map*)nuiPropertyMap;
+ try_catch(([&]() {
+ visualObject->DoAction(Dali::Toolkit::DevelVisual::Action::UPDATE_PROPERTY, *propertyMap);
+ }));
+}
+
+SWIGEXPORT void SWIGSTDCALL CSharp_Dali_VisualObject_DoActionWithEmptyAttributes(void* nuiVisualObject, int actionId)
+{
+ Dali::VisualObject* visualObject = (Dali::VisualObject*)0;
+
+ GUARD_ON_NULL_RET(nuiVisualObject);
+
+ visualObject = (Dali::VisualObject*)nuiVisualObject;
+ try_catch(([&]() {
+ visualObject->DoAction(actionId, Dali::Property::Value());
+ }));
+}
+
+SWIGEXPORT void SWIGSTDCALL CSharp_Dali_VisualObject_DoActionWithSingleIntAttributes(void* nuiVisualObject, int actionId, int actionValue)
+{
+ Dali::VisualObject* visualObject = (Dali::VisualObject*)0;
+
+ GUARD_ON_NULL_RET(nuiVisualObject);
+
+ visualObject = (Dali::VisualObject*)nuiVisualObject;
+ try_catch(([&]() {
+ visualObject->DoAction(actionId, Dali::Property::Value(actionValue));
+ }));
+}
+
+SWIGEXPORT void SWIGSTDCALL CSharp_Dali_VisualObject_SetSiblingOrder(void* nuiVisualObject, uint32_t index)
+{
+ Dali::VisualObject* visualObject = (Dali::VisualObject*)0;
+
+ GUARD_ON_NULL_RET(nuiVisualObject);
+
+ visualObject = (Dali::VisualObject*)nuiVisualObject;
+ try_catch(([&]() {
+ visualObject->SetSiblingOrder(index);
+ }));
+}
+
+SWIGEXPORT uint32_t SWIGSTDCALL CSharp_Dali_VisualObject_GetSiblingOrder(void* nuiVisualObject)
+{
+ const Dali::VisualObject* visualObject = (const Dali::VisualObject*)0;
+ uint32_t result = 0u;
+
+ GUARD_ON_NULL_RET0(nuiVisualObject);
+
+ visualObject = (const Dali::VisualObject*)nuiVisualObject;
+ try_catch(([&]() {
+ result = visualObject->GetSiblingOrder();
+ }));
+
+ return result;
+}
+
+SWIGEXPORT void SWIGSTDCALL CSharp_Dali_VisualObject_Raise(void* nuiVisualObject)
+{
+ Dali::VisualObject* visualObject = (Dali::VisualObject*)0;
+
+ GUARD_ON_NULL_RET(nuiVisualObject);
+
+ visualObject = (Dali::VisualObject*)nuiVisualObject;
+ try_catch(([&]() {
+ visualObject->Raise();
+ }));
+}
+
+SWIGEXPORT void SWIGSTDCALL CSharp_Dali_VisualObject_Lower(void* nuiVisualObject)
+{
+ Dali::VisualObject* visualObject = (Dali::VisualObject*)0;
+
+ GUARD_ON_NULL_RET(nuiVisualObject);
+
+ visualObject = (Dali::VisualObject*)nuiVisualObject;
+ try_catch(([&]() {
+ visualObject->Lower();
+ }));
+}
+
+SWIGEXPORT void SWIGSTDCALL CSharp_Dali_VisualObject_RaiseToTop(void* nuiVisualObject)
+{
+ Dali::VisualObject* visualObject = (Dali::VisualObject*)0;
+
+ GUARD_ON_NULL_RET(nuiVisualObject);
+
+ visualObject = (Dali::VisualObject*)nuiVisualObject;
+ try_catch(([&]() {
+ visualObject->RaiseToTop();
+ }));
+}
+
+SWIGEXPORT void SWIGSTDCALL CSharp_Dali_VisualObject_LowerToBottom(void* nuiVisualObject)
+{
+ Dali::VisualObject* visualObject = (Dali::VisualObject*)0;
+
+ GUARD_ON_NULL_RET(nuiVisualObject);
+
+ visualObject = (Dali::VisualObject*)nuiVisualObject;
+ try_catch(([&]() {
+ visualObject->LowerToBottom();
+ }));
+}
+
+SWIGEXPORT void SWIGSTDCALL CSharp_Dali_VisualObject_RaiseAbove(void* nuiVisualObject, void* nuiTargetVisualObject)
+{
+ Dali::VisualObject* visualObject = (Dali::VisualObject*)0;
+ Dali::VisualObject* targetVisualObject = (Dali::VisualObject*)0;
+
+ GUARD_ON_NULL_RET(nuiVisualObject);
+ GUARD_ON_NULL_RET(nuiTargetVisualObject);
+
+ visualObject = (Dali::VisualObject*)nuiVisualObject;
+ targetVisualObject = (Dali::VisualObject*)nuiTargetVisualObject;
+ try_catch(([&]() {
+ visualObject->RaiseAbove(*targetVisualObject);
+ }));
+}
+
+SWIGEXPORT void SWIGSTDCALL CSharp_Dali_VisualObject_LowerBelow(void* nuiVisualObject, void* nuiTargetVisualObject)
+{
+ Dali::VisualObject* visualObject = (Dali::VisualObject*)0;
+ Dali::VisualObject* targetVisualObject = (Dali::VisualObject*)0;
+
+ GUARD_ON_NULL_RET(nuiVisualObject);
+ GUARD_ON_NULL_RET(nuiTargetVisualObject);
+
+ visualObject = (Dali::VisualObject*)nuiVisualObject;
+ targetVisualObject = (Dali::VisualObject*)nuiTargetVisualObject;
+ try_catch(([&]() {
+ visualObject->LowerBelow(*targetVisualObject);
+ }));
+}
+
+#ifdef __cplusplus
+}
+#endif
\ No newline at end of file
--- /dev/null
+#ifndef CSHARP_VISUAL_OBJECT_H
+#define CSHARP_VISUAL_OBJECT_H
+
+/*
+ * Copyright (c) 2024 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/object/base-handle.h>
+
+// INTERNAL INCLUDES
+#include <dali-csharp-binder/common/visual-objects/visual-objects-container.h>
+
+namespace Dali
+{
+namespace Internal
+{
+class VisualObject;
+}
+/**
+ * @brief VisualObject is a owner of Visual::Base.
+ * It will be used when we want to Attach / Detach from control,
+ * and change rendering order for C# specific policy.
+ *
+ * VisualObject could be added to only one VisualObjectsContainer.
+ * If user try to add VisualObject to another VisualObjectsContainer,
+ * it will be removed from previous container and added to new container.
+ *
+ * @code
+ *
+ * TextLabel textLabel = TextLabel::New("Hello World");
+ * textLabel.SetBackgroundColor(Color::RED);
+ *
+ * VisualObjectsContainer container = VisualObjectsContainer.New(textLabel);
+ *
+ * VisualObject visualObject1 = VisualObject.New();
+ * VisualObject visualObject2 = VisualObject.New();
+ * VisualObject visualObject3 = VisualObject.New();
+ * container.AddVisualObject(visualObject1);
+ * container.AddVisualObject(visualObject2);
+ * container.AddVisualObject(visualObject3);
+ *
+ * // Current textLabel will show RED background and text.
+ *
+ * visualObject1.CreateVisual(TRANSLUCENT_BLUE_COLOR_PROPERTY_MAP);
+ *
+ * // textLabel will show text, translucent blue, and red (top to bottom)
+ *
+ * visualObject3.CreateVisual(SOME_IMAGE_PROPERTY_MAP);
+ *
+ * // textLabel will show text, some image, translucent blue, and red (top to bottom)
+ *
+ * visualObject2.CreateVisual(GREEN_BORDER_PROPERTY_MAP);
+ *
+ * // textLabel will show text, some image, green border, translucent blue, and red (top to bottom)
+ *
+ * visualObject2.RaiseToTop();
+ *
+ * // textLabel will show text, green border, some image, translucent blue, and red (top to bottom)
+ *
+ * @endcode
+ *
+ * @SINCE_2_3.27
+ */
+class VisualObject : public Dali::BaseHandle
+{
+public:
+ /**
+ * @brief Creates a VisualObject object.
+ *
+ * @SINCE_2_3.27
+ * @return The newly created visual object.
+ */
+ static VisualObject New();
+
+public: ///< Public API
+ /**
+ * @brief Detach from the Container. Now container will be empty handle.
+ *
+ * @SINCE_2_3.27
+ */
+ void DetachFromContainer();
+
+ /**
+ * @brief Get the Container who contain this visual object.
+ *
+ * @SINCE_2_3.27
+ * @return VisualObjectsContainer who contain this visual object. Or empty container if visual object is not in container.
+ */
+ Dali::VisualObjectsContainer GetContainer();
+
+ /**
+ * @brief Create Visual with Property::Map.
+ * @note It will remove previous visual.
+ *
+ * @SINCE_2_3.27
+ * @param[in] map The Creation information of the visual.
+ */
+ void CreateVisual(const Dali::Property::Map& map);
+
+ /**
+ * @brief Get the visual property map.
+ *
+ * @SINCE_2_3.27
+ * @param[out] map The visual property map.
+ */
+ void RetrieveVisualPropertyMap(Dali::Property::Map& map) const;
+
+ /**
+ * @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.
+ * @note If visual is not been registered to the control, action should be ignored.
+ *
+ * @SINCE_2_3.27
+ * @param[in] actionId The action to perform. See Visual to find supported actions.
+ * @param[in] attributes Optional attributes for the action.
+ */
+ void DoAction(Dali::Property::Index actionId, const Dali::Property::Value& attributes);
+
+ /// Sibling Order Change API
+
+ /**
+ * @brief Set the sibling order of the visual object inside of the container.
+ * @note It will change other VisualObject's sibling order to keep the order.
+ *
+ * @SINCE_2_3.27
+ * @param[in] siblingOrder The sibling order inside of the container.
+ */
+ void SetSiblingOrder(uint32_t siblingOrder);
+
+ /**
+ * @brief Get the sibling order of the visual object inside of the container.
+ *
+ * @SINCE_2_3.27
+ * @return The sibling order inside of the container. Or 0 if visual object is not in container.
+ */
+ uint32_t GetSiblingOrder() const;
+
+ /**
+ * @brief Raise the visual object above the next sibling visual object.
+ *
+ * @SINCE_2_3.27
+ * @pre The VisualObject has been initialized.
+ * @pre The VisualObject has been parented.
+ */
+ void Raise();
+
+ /**
+ * @brief Lower the visual object below the previous sibling visual object.
+ *
+ * @SINCE_2_3.27
+ * @pre The VisualObject has been initialized.
+ * @pre The VisualObject has been parented.
+ */
+ void Lower();
+
+ /**
+ * @brief Raise visual object above all other sibling visual objects.
+ *
+ * @SINCE_2_3.27
+ * @pre The VisualObject has been initialized.
+ * @pre The VisualObject has been parented.
+ */
+ void RaiseToTop();
+
+ /**
+ * @brief Lower visual object to the bottom of all other sibling visual objects.
+ *
+ * @SINCE_2_3.27
+ * @pre The VisualObject has been initialized.
+ * @pre The VisualObject has been parented.
+ */
+ void LowerToBottom();
+
+ /**
+ * @brief Raises the visual object above the target visual object.
+ *
+ * @SINCE_2_3.27
+ * @param[in] target The target visual object
+ * @pre The VisualObject has been initialized.
+ * @pre The VisualObject has been parented.
+ * @pre The target visual object is a sibling.
+ */
+ void RaiseAbove(VisualObject target);
+
+ /**
+ * @brief Lower the visual object to below the target visual object.
+ *
+ * @SINCE_2_3.27
+ * @param[in] target The target visual object
+ * @pre The VisualObject has been initialized.
+ * @pre The VisualObject has been parented.
+ * @pre The target visual object is a sibling.
+ */
+ void LowerBelow(VisualObject target);
+
+public:
+ VisualObject() = default;
+ ~VisualObject() = default;
+ VisualObject(const VisualObject& handle) = default;
+ VisualObject& operator=(const VisualObject& rhs) = default;
+ VisualObject(VisualObject&& rhs) noexcept = default;
+ VisualObject& operator=(VisualObject&& rhs) noexcept = default;
+
+public:
+ /**
+ * @brief This constructor is used by Dali New() methods.
+ *
+ * @param[in] object A pointer to a newly allocated Dali resource
+ */
+ VisualObject(Dali::Internal::VisualObject* object);
+};
+} // namespace Dali
+
+#endif // CSHARP_VISUAL_OBJECT_H
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2024 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <dali-csharp-binder/common/visual-objects/visual-objects-container-impl.h>
+
+// EXTERNAL INCLUDES
+#include <dali-toolkit/devel-api/controls/control-depth-index-ranges.h>
+#include <dali-toolkit/devel-api/controls/control-devel.h>
+#include <dali-toolkit/public-api/controls/control-impl.h>
+#include <dali-toolkit/public-api/controls/control.h>
+#include <dali/integration-api/adaptor-framework/adaptor.h>
+#include <dali/integration-api/debug.h>
+
+// INTERNAL INCLUDES
+#include <dali-csharp-binder/common/visual-objects/visual-object-impl.h>
+#include <dali-csharp-binder/common/visual-objects/visual-object.h>
+
+namespace Dali::Internal
+{
+namespace
+{
+constexpr std::string_view VISUAL_OBJECT_PROPERTY_NAME_PREFIX("VisualObject");
+
+constexpr uint32_t MAXIMUM_VISUAL_OBJECTS_COUNT = (Dali::Toolkit::DepthIndex::Ranges::CONTENT - Dali::Toolkit::DepthIndex::Ranges::BACKGROUND - 1u - 3u /* Placeholder + Transition + RenderEffect */);
+} // namespace
+VisualObjectsContainerPtr VisualObjectsContainer::New(Dali::Toolkit::Control control, Dali::VisualObjectsContainer::ContainerRangeType rangeType)
+{
+ VisualObjectsContainerPtr container(new VisualObjectsContainer(control, rangeType));
+ return container;
+}
+
+///< Public API
+
+Dali::Toolkit::Control VisualObjectsContainer::GetOwner() const
+{
+ return mControl.GetHandle();
+}
+
+Dali::VisualObjectsContainer::ContainerRangeType VisualObjectsContainer::GetContainerRangeType() const
+{
+ return mRangeType;
+}
+
+uint32_t VisualObjectsContainer::GetVisualObjectsCount() const
+{
+ return static_cast<uint32_t>(mVisualObjects.size());
+}
+
+Dali::VisualObject VisualObjectsContainer::GetVisualObjectAt(uint32_t index) const
+{
+ DALI_ASSERT_ALWAYS(index < mVisualObjects.size() && "Visual object index out of bounds");
+ return mVisualObjects[index];
+}
+
+bool VisualObjectsContainer::AddVisualObject(Dali::VisualObject visualObject)
+{
+ if(visualObject)
+ {
+ if(DALI_UNLIKELY(!Dali::Adaptor::IsAvailable()))
+ {
+ DALI_LOG_ERROR("Application is terminated, or worker thread call this API. Add VisualObject failed.\n");
+ return false;
+ }
+
+ Dali::VisualObjectsContainer self(this); // Keep reference for safety
+
+ auto oldContainer = visualObject.GetContainer();
+
+ // Skip below logic if visual object is already in this container.
+ if(self != oldContainer)
+ {
+ if(mVisualObjects.size() >= MAXIMUM_VISUAL_OBJECTS_COUNT)
+ {
+ DALI_LOG_ERROR("Visual objects container is full. Add VisualObject failed.\n");
+ return false;
+ }
+
+ if(oldContainer)
+ {
+ visualObject.DetachFromContainer();
+ }
+
+ // Add to this container.
+ auto& visualObjectImpl = GetImplementation(visualObject);
+ visualObjectImpl.AttachToContainerInternal(self);
+ visualObjectImpl.SetSiblingOrderInternal(mVisualObjects.size());
+
+ ReplaceVisualObject(visualObjectImpl);
+
+ mVisualObjects.push_back(visualObject);
+ return true;
+ }
+ }
+ return false;
+}
+
+void VisualObjectsContainer::RemoveVisualObject(Dali::VisualObject visualObject)
+{
+ if(visualObject)
+ {
+ if(DALI_UNLIKELY(!Dali::Adaptor::IsAvailable()))
+ {
+ return;
+ }
+
+ Dali::VisualObjectsContainer self(this); // Keep reference for safety
+
+ auto iter = std::find(mVisualObjects.begin(), mVisualObjects.end(), visualObject);
+ if(iter != mVisualObjects.end())
+ {
+ // Shift down other visual objects sibling order
+ uint32_t siblingOrder = visualObject.GetSiblingOrder();
+ for(auto jter = iter + 1; jter != mVisualObjects.end(); ++jter)
+ {
+ GetImplementation(*jter).SetSiblingOrderInternal(siblingOrder++);
+ }
+ mVisualObjects.erase(iter);
+
+ auto& visualObjectImpl = GetImplementation(visualObject);
+ UnregisterVisualObject(visualObjectImpl);
+ visualObjectImpl.DetachFromContainerInternal();
+ }
+ }
+}
+
+void VisualObjectsContainer::ChangeSiblingOrder(uint32_t fromIndex, uint32_t toIndex)
+{
+ DALI_ASSERT_ALWAYS(fromIndex < mVisualObjects.size() && "fromIndex is out of bounds");
+ DALI_ASSERT_ALWAYS(toIndex < mVisualObjects.size() && "toIndex is out of bounds");
+ if(fromIndex != toIndex)
+ {
+ // Keep reference of visual object.
+ Dali::VisualObject visualObject = mVisualObjects[fromIndex];
+
+ if(fromIndex < toIndex)
+ {
+ for(uint32_t i = fromIndex; i != toIndex; ++i)
+ {
+ GetImplementation(mVisualObjects[i + 1]).SetSiblingOrderInternal(i);
+ mVisualObjects[i] = mVisualObjects[i + 1];
+ }
+ }
+ else if(fromIndex > toIndex)
+ {
+ for(uint32_t i = fromIndex; i != toIndex; --i)
+ {
+ GetImplementation(mVisualObjects[i - 1]).SetSiblingOrderInternal(i);
+ mVisualObjects[i] = mVisualObjects[i - 1];
+ }
+ }
+ GetImplementation(visualObject).SetSiblingOrderInternal(toIndex);
+ mVisualObjects[toIndex] = visualObject;
+ }
+}
+
+// Private and internal
+
+void VisualObjectsContainer::ReplaceVisualObject(Dali::Internal::VisualObject& visualObjectImpl)
+{
+ if(DALI_LIKELY(Dali::Adaptor::IsAvailable()))
+ {
+ Dali::Toolkit::Control control = mControl.GetHandle();
+ if(control)
+ {
+ VisualObject::VisualPropertyId propertyId = visualObjectImpl.GetVisualPropertyId();
+
+ Property::Index index = Property::INVALID_INDEX;
+
+ if(propertyId == VisualObject::INVALID_VISUAL_PROPERTY_ID)
+ {
+ // Add dummy index to converter, and get unique id.
+ propertyId = mVisualIndexConverter.Add(static_cast<uint32_t>(Property::INVALID_INDEX));
+
+ // Register new property to control using propertyId
+ {
+ std::ostringstream oss;
+ oss << VISUAL_OBJECT_PROPERTY_NAME_PREFIX << "_" << static_cast<int>(mRangeType) << "_" << propertyId;
+ index = control.RegisterProperty(oss.str(), Property::Value(oss.str()), Property::AccessMode::READ_WRITE);
+ }
+
+ // Change as valid index now.
+ mVisualIndexConverter[propertyId] = static_cast<uint32_t>(index);
+
+ visualObjectImpl.SetVisualPropertyId(propertyId);
+ }
+ else
+ {
+ index = mVisualIndexConverter[propertyId];
+ }
+
+ if(index != Property::INVALID_INDEX)
+ {
+ // Replace visual.
+ auto visualBase = visualObjectImpl.GetVisual();
+ if(visualBase)
+ {
+ // Register the visual to the control.
+ Dali::Toolkit::DevelControl::RegisterVisual(Dali::Toolkit::Internal::GetImplementation(control), index, visualBase, static_cast<int>(visualObjectImpl.GetDepthIndex()));
+ }
+ else
+ {
+ // Unregister the visual from the control.
+ Dali::Toolkit::DevelControl::UnregisterVisual(Dali::Toolkit::Internal::GetImplementation(control), index);
+ }
+ }
+ }
+ }
+}
+
+void VisualObjectsContainer::UnregisterVisualObject(Dali::Internal::VisualObject& visualObjectImpl)
+{
+ if(DALI_LIKELY(Dali::Adaptor::IsAvailable()))
+ {
+ Dali::Toolkit::Control control = mControl.GetHandle();
+ if(control)
+ {
+ VisualObject::VisualPropertyId propertyId = visualObjectImpl.GetVisualPropertyId();
+
+ DALI_ASSERT_ALWAYS(propertyId != VisualObject::INVALID_VISUAL_PROPERTY_ID && "VisualObject is not registered before!");
+
+ Property::Index index = static_cast<Property::Index>(mVisualIndexConverter[propertyId]);
+ if(index != Property::INVALID_INDEX)
+ {
+ Dali::Toolkit::DevelControl::UnregisterVisual(Dali::Toolkit::Internal::GetImplementation(control), index);
+ }
+ mVisualIndexConverter.Remove(propertyId);
+
+ visualObjectImpl.SetVisualPropertyId(VisualObject::INVALID_VISUAL_PROPERTY_ID);
+ }
+ }
+}
+
+VisualObjectsContainer::VisualObjectsContainer(Dali::Toolkit::Control control, Dali::VisualObjectsContainer::ContainerRangeType rangeType)
+: BaseObject(),
+ mVisualObjects(),
+ mControl(control),
+ mRangeType(rangeType),
+ mVisualIndexConverter()
+{
+}
+
+VisualObjectsContainer::~VisualObjectsContainer()
+{
+ if(DALI_LIKELY(Dali::Adaptor::IsAvailable()))
+ {
+ // Detach visual objects without touch the containers.
+ for(auto&& visualObject : mVisualObjects)
+ {
+ auto& visualObjectImpl = GetImplementation(visualObject);
+
+ UnregisterVisualObject(visualObjectImpl);
+ visualObjectImpl.DetachFromContainerInternal();
+ }
+ mVisualObjects.clear();
+ }
+}
+
+} // namespace Dali::Internal
\ No newline at end of file
--- /dev/null
+#ifndef CSHARP_VISUAL_OBJECTS_CONTAINER_IMPL_H
+#define CSHARP_VISUAL_OBJECTS_CONTAINER_IMPL_H
+
+/*
+ * Copyright (c) 2024 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali-toolkit/devel-api/visual-factory/visual-base.h>
+#include <dali-toolkit/public-api/controls/control.h>
+#include <dali/devel-api/common/free-list.h>
+#include <dali/public-api/common/dali-common.h>
+#include <dali/public-api/common/intrusive-ptr.h>
+#include <dali/public-api/common/vector-wrapper.h>
+#include <dali/public-api/object/base-object.h>
+#include <dali/public-api/object/weak-handle.h>
+
+// INTERNAL INCLUDES
+#include <dali-csharp-binder/common/visual-objects/visual-object.h>
+
+namespace Dali
+{
+namespace Internal
+{
+class VisualObjectsContainer;
+using VisualObjectsContainerPtr = Dali::IntrusivePtr<VisualObjectsContainer>;
+
+class VisualObjectsContainer : public Dali::BaseObject
+{
+public:
+ /**
+ * @brief Creates a VisualObjectsContainer object.
+ *
+ * @SINCE_2_3.27
+ * @param[in] control The control that owns this VisualObjectsContainer.
+ * @param[in] rangeType The range type of this VisualObjectsContainer.
+ * @return The newly created visual object container.
+ */
+ static VisualObjectsContainerPtr New(Dali::Toolkit::Control control, Dali::VisualObjectsContainer::ContainerRangeType rangeType);
+
+public: ///< Public API
+ /**
+ * @copydoc Dali::VisualObjectsContainer::GetOwner()
+ */
+ Dali::Toolkit::Control GetOwner() const;
+
+ /**
+ * @copydoc Dali::VisualObjectsContainer::GetContainerRangeType()
+ */
+ Dali::VisualObjectsContainer::ContainerRangeType GetContainerRangeType() const;
+
+ /**
+ * @copydoc Dali::VisualObjectsContainer::GetVisualObjectsCount()
+ */
+ uint32_t GetVisualObjectsCount() const;
+
+ /**
+ * @copydoc Dali::VisualObjectsContainer::GetVisualObjectAt()
+ */
+ Dali::VisualObject GetVisualObjectAt(uint32_t index) const;
+
+ /**
+ * @copydoc Dali::VisualObjectsContainer::AddVisualObject()
+ */
+ bool AddVisualObject(Dali::VisualObject visualObject);
+
+ /**
+ * @copydoc Dali::VisualObjectsContainer::RemoveVisualObject()
+ */
+ void RemoveVisualObject(Dali::VisualObject visualObject);
+
+public: ///< Called from Internal::VisualObject
+ /**
+ * @brief Replace visual object's visual into the control.
+ * If the visual object is already registered, it will be replaced.
+ * If VisualObject doesn't have visual yet, it will unregister visual.
+ *
+ * @param[in] visualObjectImpl visual object implements.
+ */
+ void ReplaceVisualObject(Dali::Internal::VisualObject& visualObjectImpl);
+
+ /**
+ * @copydoc Dali::VisualObjectsContainer::ChangeSiblingOrder()
+ */
+ void ChangeSiblingOrder(uint32_t fromIndex, uint32_t toIndex);
+
+private:
+ /**
+ * @brief Unregister visual object's visual from the control.
+ *
+ * @param[in] visualObjectImpl visual object implements.
+ */
+ void UnregisterVisualObject(Dali::Internal::VisualObject& visualObjectImpl);
+
+public:
+ /**
+ * @brief Constructor - creates a VisualObjectsContainer.
+ *
+ * @param[in] control The control that owns this VisualObjectsContainer.
+ * @param[in] rangeType The range type of this VisualObjectsContainer.
+ */
+ VisualObjectsContainer(Dali::Toolkit::Control control, Dali::VisualObjectsContainer::ContainerRangeType rangeType);
+
+ /**
+ * @brief Destructor.
+ */
+ ~VisualObjectsContainer() override;
+
+private:
+ std::vector<Dali::VisualObject> mVisualObjects;
+ Dali::WeakHandle<Dali::Toolkit::Control> mControl;
+
+ const Dali::VisualObjectsContainer::ContainerRangeType mRangeType;
+
+ Dali::FreeList mVisualIndexConverter; ///< Convert from virtual visual index of VisualObject to actual visual index of mControl.
+};
+} // namespace Internal
+
+// Helpers for api forwarding methods
+
+inline static Internal::VisualObjectsContainer& GetImplementation(Dali::VisualObjectsContainer& handle)
+{
+ DALI_ASSERT_ALWAYS(handle && "VisualObjectsContainer handle is empty.");
+
+ Dali::BaseObject& object = handle.GetBaseObject();
+
+ return static_cast<Internal::VisualObjectsContainer&>(object);
+}
+
+inline static const Internal::VisualObjectsContainer& GetImplementation(const Dali::VisualObjectsContainer& handle)
+{
+ DALI_ASSERT_ALWAYS(handle && "VisualObjectsContainer handle is empty.");
+
+ const Dali::BaseObject& object = handle.GetBaseObject();
+
+ return static_cast<const Internal::VisualObjectsContainer&>(object);
+}
+
+} // namespace Dali
+
+#endif // CSHARP_VISUAL_OBJECTS_CONTAINER_IMPL_H
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2024 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <dali-csharp-binder/common/visual-objects/visual-objects-container.h>
+
+// EXTERNAL INCLUDES
+#include <dali/integration-api/debug.h>
+
+// INTERNAL INCLUDES
+#include <dali-csharp-binder/common/common.h>
+#include <dali-csharp-binder/common/visual-objects/visual-object.h>
+#include <dali-csharp-binder/common/visual-objects/visual-objects-container-impl.h>
+
+namespace Dali
+{
+VisualObjectsContainer::VisualObjectsContainer(Dali::Internal::VisualObjectsContainer* object)
+: BaseHandle(object)
+{
+}
+
+VisualObjectsContainer VisualObjectsContainer::New(Dali::Toolkit::Control control, VisualObjectsContainer::ContainerRangeType rangeType)
+{
+ Internal::VisualObjectsContainerPtr internal = Internal::VisualObjectsContainer::New(control, rangeType);
+ return VisualObjectsContainer(internal.Get());
+}
+
+VisualObjectsContainer VisualObjectsContainer::DownCast(BaseHandle handle)
+{
+ return VisualObjectsContainer(dynamic_cast<Dali::Internal::VisualObjectsContainer*>(handle.GetObjectPtr()));
+}
+
+///< Public API
+
+Dali::Toolkit::Control VisualObjectsContainer::GetOwner() const
+{
+ return GetImplementation(*this).GetOwner();
+}
+
+VisualObjectsContainer::ContainerRangeType VisualObjectsContainer::GetContainerRangeType() const
+{
+ return GetImplementation(*this).GetContainerRangeType();
+}
+
+uint32_t VisualObjectsContainer::GetVisualObjectsCount() const
+{
+ return GetImplementation(*this).GetVisualObjectsCount();
+}
+
+Dali::VisualObject VisualObjectsContainer::GetVisualObjectAt(uint32_t index) const
+{
+ return GetImplementation(*this).GetVisualObjectAt(index);
+}
+
+bool VisualObjectsContainer::AddVisualObject(Dali::VisualObject visualObject)
+{
+ return GetImplementation(*this).AddVisualObject(visualObject);
+}
+
+void VisualObjectsContainer::RemoveVisualObject(Dali::VisualObject visualObject)
+{
+ GetImplementation(*this).RemoveVisualObject(visualObject);
+}
+
+} // namespace Dali
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+SWIGEXPORT int SWIGSTDCALL CSharp_Dali_VisualObjectsContainer_ContainerRangeTypeBackgroundEffectGet()
+{
+ return static_cast<int>(Dali::VisualObjectsContainer::ContainerRangeType::BACKGROUND_EFFECT);
+}
+
+SWIGEXPORT int SWIGSTDCALL CSharp_Dali_VisualObjectsContainer_ContainerRangeTypeBackgroundGet()
+{
+ return static_cast<int>(Dali::VisualObjectsContainer::ContainerRangeType::BACKGROUND);
+}
+
+SWIGEXPORT int SWIGSTDCALL CSharp_Dali_VisualObjectsContainer_ContainerRangeTypeContentGet()
+{
+ return static_cast<int>(Dali::VisualObjectsContainer::ContainerRangeType::CONTENT);
+}
+
+SWIGEXPORT int SWIGSTDCALL CSharp_Dali_VisualObjectsContainer_ContainerRangeTypeDecorationGet()
+{
+ return static_cast<int>(Dali::VisualObjectsContainer::ContainerRangeType::DECORATION);
+}
+
+SWIGEXPORT int SWIGSTDCALL CSharp_Dali_VisualObjectsContainer_ContainerRangeTypeForegroundEffectGet()
+{
+ return static_cast<int>(Dali::VisualObjectsContainer::ContainerRangeType::FOREGROUND_EFFECT);
+}
+
+SWIGEXPORT void* SWIGSTDCALL CSharp_Dali_new_VisualObjectsContainer__SWIG_0()
+{
+ Dali::VisualObjectsContainer* result = 0;
+
+ try_catch(([&]() {
+ result = (Dali::VisualObjectsContainer*)new Dali::VisualObjectsContainer();
+ }));
+
+ return (void*)result;
+}
+
+SWIGEXPORT void* SWIGSTDCALL CSharp_Dali_VisualObjectsContainer_New(void* nuiView, int rangeType)
+{
+ void* jresult = 0;
+ Dali::VisualObjectsContainer result;
+
+ GUARD_ON_NULL_RET0(nuiView);
+
+ try_catch(([&]() {
+ auto handle = (Dali::BaseHandle*)nuiView;
+ auto control = Dali::Toolkit::Control::DownCast(*handle);
+ if(control)
+ {
+ result = Dali::VisualObjectsContainer::New(control, static_cast<Dali::VisualObjectsContainer::ContainerRangeType>(rangeType));
+ }
+ }));
+
+ jresult = new Dali::VisualObjectsContainer((const Dali::VisualObjectsContainer&)result);
+ return jresult;
+}
+
+SWIGEXPORT void SWIGSTDCALL CSharp_Dali_delete_VisualObjectsContainer(void* nuiVisualObjectsContainer)
+{
+ Dali::VisualObjectsContainer* arg1 = (Dali::VisualObjectsContainer*)0;
+
+ arg1 = (Dali::VisualObjectsContainer*)nuiVisualObjectsContainer;
+ try_catch(([&]() {
+ delete arg1;
+ }));
+}
+
+SWIGEXPORT void* SWIGSTDCALL CSharp_Dali_VisualObjectsContainer_GetOwner(void* nuiVisualObjectsContainer)
+{
+ void* jresult = 0;
+ const Dali::VisualObjectsContainer* container = (const Dali::VisualObjectsContainer*)0;
+ Dali::Toolkit::Control result;
+
+ GUARD_ON_NULL_RET0(nuiVisualObjectsContainer);
+
+ container = (const Dali::VisualObjectsContainer*)nuiVisualObjectsContainer;
+ try_catch(([&]() {
+ result = container->GetOwner();
+ }));
+
+ jresult = new Dali::Toolkit::Control((const Dali::Toolkit::Control&)result);
+ return jresult;
+}
+
+SWIGEXPORT int SWIGSTDCALL CSharp_Dali_VisualObjectsContainer_GetContainerRangeType(void* nuiVisualObjectsContainer)
+{
+ const Dali::VisualObjectsContainer* container = (const Dali::VisualObjectsContainer*)0;
+ Dali::VisualObjectsContainer::ContainerRangeType result = Dali::VisualObjectsContainer::ContainerRangeType::CONTENT;
+
+ GUARD_ON_NULL_RET0(nuiVisualObjectsContainer);
+
+ container = (const Dali::VisualObjectsContainer*)nuiVisualObjectsContainer;
+ try_catch(([&]() {
+ result = container->GetContainerRangeType();
+ }));
+
+ return static_cast<int>(result);
+}
+
+SWIGEXPORT uint32_t SWIGSTDCALL CSharp_Dali_VisualObjectsContainer_GetVisualObjectsCount(void* nuiVisualObjectsContainer)
+{
+ const Dali::VisualObjectsContainer* container = (const Dali::VisualObjectsContainer*)0;
+ uint32_t result = 0u;
+
+ GUARD_ON_NULL_RET0(nuiVisualObjectsContainer);
+
+ container = (const Dali::VisualObjectsContainer*)nuiVisualObjectsContainer;
+ try_catch(([&]() {
+ result = container->GetVisualObjectsCount();
+ }));
+
+ return result;
+}
+
+SWIGEXPORT void* SWIGSTDCALL CSharp_Dali_VisualObjectsContainer_GetVisualObjectAt(void* nuiVisualObjectsContainer, uint32_t index)
+{
+ void* jresult = 0;
+ const Dali::VisualObjectsContainer* container = (const Dali::VisualObjectsContainer*)0;
+ Dali::VisualObject result;
+
+ GUARD_ON_NULL_RET0(nuiVisualObjectsContainer);
+
+ container = (const Dali::VisualObjectsContainer*)nuiVisualObjectsContainer;
+ try_catch(([&]() {
+ result = container->GetVisualObjectAt(index);
+ }));
+
+ jresult = new Dali::VisualObject((const Dali::VisualObject&)result);
+ return jresult;
+}
+
+SWIGEXPORT bool SWIGSTDCALL CSharp_Dali_VisualObjectsContainer_AddVisualObject(void* nuiVisualObjectsContainer, void* nuiVisualObject)
+{
+ Dali::VisualObjectsContainer* container = (Dali::VisualObjectsContainer*)0;
+ Dali::VisualObject* visualObject = (Dali::VisualObject*)0;
+ bool result = false;
+
+ GUARD_ON_NULL_RET0(nuiVisualObjectsContainer);
+ GUARD_ON_NULL_RET0(nuiVisualObject);
+
+ container = (Dali::VisualObjectsContainer*)nuiVisualObjectsContainer;
+ visualObject = (Dali::VisualObject*)nuiVisualObject;
+ try_catch(([&]() {
+ result = container->AddVisualObject(*visualObject);
+ }));
+ return result;
+}
+
+SWIGEXPORT void SWIGSTDCALL CSharp_Dali_VisualObjectsContainer_RemoveVisualObject(void* nuiVisualObjectsContainer, void* nuiVisualObject)
+{
+ Dali::VisualObjectsContainer* container = (Dali::VisualObjectsContainer*)0;
+ Dali::VisualObject* visualObject = (Dali::VisualObject*)0;
+
+ GUARD_ON_NULL_RET(nuiVisualObjectsContainer);
+ GUARD_ON_NULL_RET(nuiVisualObject);
+
+ container = (Dali::VisualObjectsContainer*)nuiVisualObjectsContainer;
+ visualObject = (Dali::VisualObject*)nuiVisualObject;
+ try_catch(([&]() {
+ container->RemoveVisualObject(*visualObject);
+ }));
+}
+
+#ifdef __cplusplus
+}
+#endif
\ No newline at end of file
--- /dev/null
+#ifndef CSHARP_VISUAL_OBJECTS_CONTAINER_H
+#define CSHARP_VISUAL_OBJECTS_CONTAINER_H
+
+/*
+ * Copyright (c) 2024 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali-toolkit/public-api/controls/control.h>
+#include <dali/public-api/object/base-handle.h>
+
+namespace Dali
+{
+namespace Internal
+{
+class VisualObjectsContainer;
+}
+
+class VisualObject;
+
+/**
+ * @brief VisualObjectsContainer is a container for visual objects for C# specific policy.
+ *
+ * For each VisualObjectContainer, there is a corresponding control.
+ * Each control can has only one VisualObjectsContainer per each ContainerRangeType.
+ *
+ * It is used to manage visual objects properties to owned control;
+ * e.g. SiblingOrder of visual objects to DepthIndex of visual.
+ *
+ * To avoid the collision between Dali toolkit logic and C# specific policy,
+ * there is some limitation of visual object counts per each ContainerRangeType.
+ *
+ * For example, if ContainerRangeType is ContainerRangeType::CONTENT,
+ * it will use visual object's depth index only between
+ * Dali::Toolkit::DepthIndex::Ranges::BACKGROUND and Dali::Toolkit::DepthIndex::Ranges::CONTENT.
+ * If user try to add over the Dali::Toolkit::DepthIndex::Ranges::CONTENT, it will be ignored.
+ *
+ * @SINCE_2_3.27
+ */
+class VisualObjectsContainer : public Dali::BaseHandle
+{
+public:
+ /**
+ * @brief Enumeration for the visual objects container range.
+ * It will be used when we determine the visual's depth index.
+ *
+ * @SINCE_2_3.27
+ */
+ enum class ContainerRangeType
+ {
+ BACKGROUND_EFFECT, ///< The visual object exist under Dali::Toolkit::DepthIndex::Ranges::BACKGROUND_EFFECT
+ BACKGROUND, ///< The visual object exist between Dali::Toolkit::DepthIndex::Ranges::BACKGROUND_EFFECT and Dali::Toolkit::DepthIndex::Ranges::BACKGROUND
+ CONTENT, ///< The visual object exist between Dali::Toolkit::DepthIndex::Ranges::BACKGROUND and Dali::Toolkit::DepthIndex::Ranges::CONTENT
+ DECORATION, ///< The visual object exist between Dali::Toolkit::DepthIndex::Ranges::CONTENT and Dali::Toolkit::DepthIndex::Ranges::DECORATION
+ FOREGROUND_EFFECT, ///< The visual object exist between Dali::Toolkit::DepthIndex::Ranges::DECORATION and Dali::Toolkit::DepthIndex::Ranges::FOREGROUND_EFFECT
+ };
+
+ /**
+ * @brief Creates a VisualObjectsContainer object.
+ *
+ * @SINCE_2_3.27
+ * @param[in] control The control that owns this VisualObjectsContainer.
+ * @param[in] rangeType The range type of this VisualObjectsContainer.
+ * @return The newly created visual objects container
+ * @post The control should not create another VisualObjectsContainer for each rangeType.
+ */
+ static VisualObjectsContainer New(Dali::Toolkit::Control control, ContainerRangeType rangeType = ContainerRangeType::CONTENT);
+
+public: ///< Public API
+ /**
+ * @brief Adds a visual object to the container.
+ *
+ * @SINCE_2_3.27
+ * @return The owner of this container, or empty handle if owner is invalid.
+ */
+ Dali::Toolkit::Control GetOwner() const;
+
+ /**
+ * @brief Gets the range type of VisualObjectsContainer.
+ *
+ * @SINCE_2_3.27
+ * @return The range type of VisualObjectsContainer.
+ */
+ ContainerRangeType GetContainerRangeType() const;
+
+ /**
+ * @brief Gets the number of visual objects in the container.
+ *
+ * @SINCE_2_3.27
+ * @return The number of visual objects in the container.
+ */
+ uint32_t GetVisualObjectsCount() const;
+
+ /**
+ * @brief Get the visual objects from the container.
+ * @note If index is out of range, will throw exception.
+ *
+ * @SINCE_2_3.27
+ * @param[in] index The index of the visual object to get.
+ * @return The visual object at the given index.
+ */
+ Dali::VisualObject GetVisualObjectAt(uint32_t index) const;
+
+ /**
+ * @brief Adds a visual object to the container.
+ * Added visual object will be placed top of other visuals.
+ * If the container cannot add more than maxium count of objects
+ * or the visual object is already added, It will be ignored.
+ *
+ * @SINCE_2_3.27
+ * @param[in] visualObject The visual object to be added.
+ * @return True if the visual object is added successfully.
+ */
+ bool AddVisualObject(Dali::VisualObject visualObject);
+
+ /**
+ * @brief Removes a visual object from the container.
+ * All other visual objects will be shifted down.
+ *
+ * @SINCE_2_3.27
+ * @param[in] visualObject The visual object to be added.
+ */
+ void RemoveVisualObject(Dali::VisualObject visualObject);
+
+public:
+ VisualObjectsContainer() = default;
+ ~VisualObjectsContainer() = default;
+ VisualObjectsContainer(const VisualObjectsContainer& handle) = default;
+ VisualObjectsContainer& operator=(const VisualObjectsContainer& rhs) = default;
+ VisualObjectsContainer(VisualObjectsContainer&& rhs) noexcept = default;
+ VisualObjectsContainer& operator=(VisualObjectsContainer&& rhs) noexcept = default;
+
+ /**
+ * @brief Downcasts a handle to VisualObjectsContainer handle.
+ *
+ * @param[in] handle Handle to an object
+ * @return A handle to a VisualObjectsContainer or an uninitialized handle
+ */
+ static VisualObjectsContainer DownCast(BaseHandle handle);
+
+public:
+ /**
+ * @brief This constructor is used by Dali New() methods.
+ *
+ * @param[in] object A pointer to a newly allocated Dali resource
+ */
+ VisualObjectsContainer(Dali::Internal::VisualObjectsContainer* object);
+};
+} // namespace Dali
+
+#endif // CSHARP_VISUAL_OBJECTS_CONTAINER_H
\ No newline at end of file
# module: csharp-binder, backend: common - ubuntu,mobile,tv,ivi,tizen-wearable,common
SET( dali_csharp_binder_common_src_files
+ ${dali_csharp_binder_dir}/common/visual-objects/visual-object-impl.cpp
+ ${dali_csharp_binder_dir}/common/visual-objects/visual-object.cpp
+ ${dali_csharp_binder_dir}/common/visual-objects/visual-objects-container-impl.cpp
+ ${dali_csharp_binder_dir}/common/visual-objects/visual-objects-container.cpp
+
${dali_csharp_binder_dir}/common/common.cpp
${dali_csharp_binder_dir}/common/dali-wrap.cpp
${dali_csharp_binder_dir}/common/callbackbase-wrap.cpp