From a36560a0a895a3b0b6f98965b732b41a42e8338f Mon Sep 17 00:00:00 2001 From: "Eunki, Hong" Date: Tue, 16 Apr 2024 16:41:58 +0900 Subject: [PATCH] Implement Visual control logic for NUI 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 --- .../visual-objects/visual-object-impl.cpp | 280 ++++++++++++++ .../visual-objects/visual-object-impl.h | 230 +++++++++++ .../common/visual-objects/visual-object.cpp | 357 ++++++++++++++++++ .../common/visual-objects/visual-object.h | 228 +++++++++++ .../visual-objects-container-impl.cpp | 273 ++++++++++++++ .../visual-objects-container-impl.h | 154 ++++++++ .../visual-objects-container.cpp | 249 ++++++++++++ .../visual-objects/visual-objects-container.h | 164 ++++++++ dali-csharp-binder/file.list | 5 + 9 files changed, 1940 insertions(+) create mode 100644 dali-csharp-binder/common/visual-objects/visual-object-impl.cpp create mode 100644 dali-csharp-binder/common/visual-objects/visual-object-impl.h create mode 100644 dali-csharp-binder/common/visual-objects/visual-object.cpp create mode 100644 dali-csharp-binder/common/visual-objects/visual-object.h create mode 100644 dali-csharp-binder/common/visual-objects/visual-objects-container-impl.cpp create mode 100644 dali-csharp-binder/common/visual-objects/visual-objects-container-impl.h create mode 100644 dali-csharp-binder/common/visual-objects/visual-objects-container.cpp create mode 100644 dali-csharp-binder/common/visual-objects/visual-objects-container.h diff --git a/dali-csharp-binder/common/visual-objects/visual-object-impl.cpp b/dali-csharp-binder/common/visual-objects/visual-object-impl.cpp new file mode 100644 index 00000000..8f54d61c --- /dev/null +++ b/dali-csharp-binder/common/visual-objects/visual-object-impl.cpp @@ -0,0 +1,280 @@ +/* + * 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 + +// EXTERNAL INCLUDES +#include +#include +#include +#include + +// INTERNAL +#include +#include +#include + +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(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 diff --git a/dali-csharp-binder/common/visual-objects/visual-object-impl.h b/dali-csharp-binder/common/visual-objects/visual-object-impl.h new file mode 100644 index 00000000..954cdb1e --- /dev/null +++ b/dali-csharp-binder/common/visual-objects/visual-object-impl.h @@ -0,0 +1,230 @@ +#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 +#include +#include +#include +#include +#include +#include + +// INTERNAL INCLUDES +#include +#include + +namespace Dali +{ +namespace Internal +{ +class VisualObject; +using VisualObjectPtr = Dali::IntrusivePtr; + +class VisualObject : public Dali::BaseObject +{ +public: + using VisualPropertyId = uint32_t; + static constexpr VisualPropertyId INVALID_VISUAL_PROPERTY_ID = std::numeric_limits::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 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(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(object); +} + +} // namespace Dali + +#endif // CSHARP_VISUAL_OBJECT_IMPL_H \ No newline at end of file diff --git a/dali-csharp-binder/common/visual-objects/visual-object.cpp b/dali-csharp-binder/common/visual-objects/visual-object.cpp new file mode 100644 index 00000000..60d3c9c6 --- /dev/null +++ b/dali-csharp-binder/common/visual-objects/visual-object.cpp @@ -0,0 +1,357 @@ +/* + * 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 + +// EXTERNAL INCLUDES +#include +#include + +// INTERNAL INCLUDES +#include +#include + +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 diff --git a/dali-csharp-binder/common/visual-objects/visual-object.h b/dali-csharp-binder/common/visual-objects/visual-object.h new file mode 100644 index 00000000..a06c98d6 --- /dev/null +++ b/dali-csharp-binder/common/visual-objects/visual-object.h @@ -0,0 +1,228 @@ +#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 + +// INTERNAL INCLUDES +#include + +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 diff --git a/dali-csharp-binder/common/visual-objects/visual-objects-container-impl.cpp b/dali-csharp-binder/common/visual-objects/visual-objects-container-impl.cpp new file mode 100644 index 00000000..51296386 --- /dev/null +++ b/dali-csharp-binder/common/visual-objects/visual-objects-container-impl.cpp @@ -0,0 +1,273 @@ +/* + * 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 + +// EXTERNAL INCLUDES +#include +#include +#include +#include +#include +#include + +// INTERNAL INCLUDES +#include +#include + +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(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(Property::INVALID_INDEX)); + + // Register new property to control using propertyId + { + std::ostringstream oss; + oss << VISUAL_OBJECT_PROPERTY_NAME_PREFIX << "_" << static_cast(mRangeType) << "_" << propertyId; + index = control.RegisterProperty(oss.str(), Property::Value(oss.str()), Property::AccessMode::READ_WRITE); + } + + // Change as valid index now. + mVisualIndexConverter[propertyId] = static_cast(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(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(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 diff --git a/dali-csharp-binder/common/visual-objects/visual-objects-container-impl.h b/dali-csharp-binder/common/visual-objects/visual-objects-container-impl.h new file mode 100644 index 00000000..aa4292df --- /dev/null +++ b/dali-csharp-binder/common/visual-objects/visual-objects-container-impl.h @@ -0,0 +1,154 @@ +#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 +#include +#include +#include +#include +#include +#include +#include + +// INTERNAL INCLUDES +#include + +namespace Dali +{ +namespace Internal +{ +class VisualObjectsContainer; +using VisualObjectsContainerPtr = Dali::IntrusivePtr; + +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 mVisualObjects; + Dali::WeakHandle 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(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(object); +} + +} // namespace Dali + +#endif // CSHARP_VISUAL_OBJECTS_CONTAINER_IMPL_H \ No newline at end of file diff --git a/dali-csharp-binder/common/visual-objects/visual-objects-container.cpp b/dali-csharp-binder/common/visual-objects/visual-objects-container.cpp new file mode 100644 index 00000000..3a3c3e87 --- /dev/null +++ b/dali-csharp-binder/common/visual-objects/visual-objects-container.cpp @@ -0,0 +1,249 @@ +/* + * 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 + +// EXTERNAL INCLUDES +#include + +// INTERNAL INCLUDES +#include +#include +#include + +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(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(Dali::VisualObjectsContainer::ContainerRangeType::BACKGROUND_EFFECT); +} + +SWIGEXPORT int SWIGSTDCALL CSharp_Dali_VisualObjectsContainer_ContainerRangeTypeBackgroundGet() +{ + return static_cast(Dali::VisualObjectsContainer::ContainerRangeType::BACKGROUND); +} + +SWIGEXPORT int SWIGSTDCALL CSharp_Dali_VisualObjectsContainer_ContainerRangeTypeContentGet() +{ + return static_cast(Dali::VisualObjectsContainer::ContainerRangeType::CONTENT); +} + +SWIGEXPORT int SWIGSTDCALL CSharp_Dali_VisualObjectsContainer_ContainerRangeTypeDecorationGet() +{ + return static_cast(Dali::VisualObjectsContainer::ContainerRangeType::DECORATION); +} + +SWIGEXPORT int SWIGSTDCALL CSharp_Dali_VisualObjectsContainer_ContainerRangeTypeForegroundEffectGet() +{ + return static_cast(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(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(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 diff --git a/dali-csharp-binder/common/visual-objects/visual-objects-container.h b/dali-csharp-binder/common/visual-objects/visual-objects-container.h new file mode 100644 index 00000000..c6503d78 --- /dev/null +++ b/dali-csharp-binder/common/visual-objects/visual-objects-container.h @@ -0,0 +1,164 @@ +#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 +#include + +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 diff --git a/dali-csharp-binder/file.list b/dali-csharp-binder/file.list index 7a9e931c..6fbca929 100755 --- a/dali-csharp-binder/file.list +++ b/dali-csharp-binder/file.list @@ -7,6 +7,11 @@ SET( dali_csharp_binder_dir ${CMAKE_CURRENT_SOURCE_DIR}/../../dali-csharp-binder # 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 -- 2.34.1