From: David Steele Date: Tue, 9 Nov 2021 18:19:08 +0000 (+0000) Subject: Refactored more code into Actor::Relayouter X-Git-Tag: dali_2.0.52~1 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-core.git;a=commitdiff_plain;h=128cea946c9d6d4a76ab7bda08bfdd532be549b7 Refactored more code into Actor::Relayouter Change-Id: I19e711ddc963e62a882679ca0afebfc5e25bb339 --- diff --git a/automated-tests/src/dali-internal/CMakeLists.txt b/automated-tests/src/dali-internal/CMakeLists.txt index 29d78b2..64a73b5 100644 --- a/automated-tests/src/dali-internal/CMakeLists.txt +++ b/automated-tests/src/dali-internal/CMakeLists.txt @@ -7,6 +7,7 @@ SET(CAPI_LIB "dali-internal") SET(TC_SOURCES utc-Dali-Internal-ActorObserver.cpp + utc-Dali-Internal-ActorRelayout.cpp utc-Dali-Internal-Core.cpp utc-Dali-Internal-FixedSizeMemoryPool.cpp utc-Dali-Internal-FrustumCulling.cpp @@ -27,6 +28,7 @@ SET(TC_SOURCES LIST(APPEND TC_SOURCES ../dali/dali-test-suite-utils/mesh-builder.cpp + ../dali/dali-test-suite-utils/test-custom-actor.cpp ../dali/dali-test-suite-utils/test-harness.cpp ../dali/dali-test-suite-utils/test-actor-utils.cpp ../dali/dali-test-suite-utils/dali-test-suite-utils.cpp diff --git a/automated-tests/src/dali-internal/utc-Dali-Internal-ActorRelayout.cpp b/automated-tests/src/dali-internal/utc-Dali-Internal-ActorRelayout.cpp new file mode 100644 index 0000000..11babca --- /dev/null +++ b/automated-tests/src/dali-internal/utc-Dali-Internal-ActorRelayout.cpp @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2021 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * 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. + * + */ + +#include +#include +#include +#include "test-custom-actor.h" + +#include + +// Internal headers are allowed here +#include +#include + +using namespace Dali; +using Dali::Internal::Actor; + +void utc_dali_internal_actor_relayouter_startup() +{ + test_return_value = TET_UNDEF; +} + +void utc_dali_internal_actor_relayouter_cleanup() +{ + test_return_value = TET_PASS; +} + +int UtcDaliActorRelayouter_CalculateSize(void) +{ + TestApplication application; + + auto scene = application.GetScene(); + auto actor = Test::TestCustomActor::New(); + auto& testActorImpl = Test::Impl::GetImpl(actor); + auto& actorImpl = GetImplementation(actor); + + scene.Add(actor); + actorImpl.SetSize(Vector2(100.0f, 100.0f)); + actorImpl.SetPreferredSize(Vector2(200.0f, 350.0f)); + + Vector2 maxSize(400.0f, 500.0f); + + DALI_TEST_EQUALS(actorImpl.CalculateSize(Dimension::WIDTH, maxSize), 200.0f, 0.00001f, TEST_LOCATION); + DALI_TEST_EQUALS(actorImpl.CalculateSize(Dimension::HEIGHT, maxSize), 350.0f, 0.00001f, TEST_LOCATION); + + actor.SetResizePolicy(ResizePolicy::USE_ASSIGNED_SIZE, Dimension::HEIGHT); + DALI_TEST_EQUALS(actorImpl.CalculateSize(Dimension::WIDTH, maxSize), 200.0f, 0.00001f, TEST_LOCATION); + DALI_TEST_EQUALS(actorImpl.CalculateSize(Dimension::HEIGHT, maxSize), maxSize.y, 0.00001f, TEST_LOCATION); + + testActorImpl.SetNaturalSize(Vector3(150.0f, 180.0f, 150.0f)); + actor.SetResizePolicy(ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS); + + DALI_TEST_EQUALS(actorImpl.CalculateSize(Dimension::WIDTH, maxSize), 150.0f, 0.00001f, TEST_LOCATION); + DALI_TEST_EQUALS(actorImpl.CalculateSize(Dimension::HEIGHT, maxSize), 180.0f, 0.00001f, TEST_LOCATION); + + actor.SetResizePolicy(ResizePolicy::FIT_TO_CHILDREN, Dimension::ALL_DIMENSIONS); + auto child = Test::TestCustomActor::New(); + child.SetResizePolicy(ResizePolicy::FIXED, Dimension::ALL_DIMENSIONS); + child.SetProperty(Dali::Actor::Property::SIZE, Vector2(20.0f, 40.0f)); + auto& childImpl = GetImplementation(child); + actor.Add(child); + + application.SendNotification(); + application.Render(); + + DALI_TEST_EQUALS(actorImpl.CalculateSize(Dimension::WIDTH, maxSize), 20.0f, 0.00001f, TEST_LOCATION); + DALI_TEST_EQUALS(actorImpl.CalculateSize(Dimension::HEIGHT, maxSize), 40.0f, 0.00001f, TEST_LOCATION); + + testActorImpl.SetWidthForHeightFactor(3.5f); + testActorImpl.SetHeightForWidthFactor(1.7f); + actor.SetResizePolicy(ResizePolicy::DIMENSION_DEPENDENCY, Dimension::WIDTH); + DALI_TEST_EQUALS(actorImpl.CalculateSize(Dimension::WIDTH, maxSize), 140.0f, 0.00001f, TEST_LOCATION); + + actor.SetResizePolicy(ResizePolicy::USE_NATURAL_SIZE, Dimension::WIDTH); + actor.SetResizePolicy(ResizePolicy::DIMENSION_DEPENDENCY, Dimension::HEIGHT); + application.SendNotification(); + application.Render(); + DALI_TEST_EQUALS(actorImpl.CalculateSize(Dimension::HEIGHT, maxSize), 255.0f, 0.00001f, TEST_LOCATION); + + child.SetResizePolicy(ResizePolicy::SIZE_RELATIVE_TO_PARENT, Dimension::ALL_DIMENSIONS); + child[Dali::Actor::Property::SIZE_MODE_FACTOR] = Vector3(0.5f, 1.0f, 1.0f); + application.SendNotification(); + application.Render(); + DALI_TEST_EQUALS(childImpl.CalculateSize(Dimension::WIDTH, maxSize), 75.0f, 0.00001f, TEST_LOCATION); + DALI_TEST_EQUALS(childImpl.CalculateSize(Dimension::HEIGHT, maxSize), 255.0f, 0.00001f, TEST_LOCATION); + + child.SetResizePolicy(ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT, Dimension::ALL_DIMENSIONS); + child[Dali::Actor::Property::SIZE_MODE_FACTOR] = Vector3(-40.0f, -20.0f, 1.0f); + application.SendNotification(); + application.Render(); + DALI_TEST_EQUALS(childImpl.CalculateSize(Dimension::WIDTH, maxSize), 110.0f, 0.00001f, TEST_LOCATION); + DALI_TEST_EQUALS(childImpl.CalculateSize(Dimension::HEIGHT, maxSize), 235.0f, 0.00001f, TEST_LOCATION); + + END_TEST; +} diff --git a/automated-tests/src/dali/dali-test-suite-utils/test-custom-actor.cpp b/automated-tests/src/dali/dali-test-suite-utils/test-custom-actor.cpp index db6cfca..6c7b1d6 100644 --- a/automated-tests/src/dali/dali-test-suite-utils/test-custom-actor.cpp +++ b/automated-tests/src/dali/dali-test-suite-utils/test-custom-actor.cpp @@ -149,17 +149,17 @@ Vector3 TestCustomActor::GetTargetSize() Vector3 TestCustomActor::GetNaturalSize() { - return Vector3(0.0f, 0.0f, 0.0f); + return GetImpl().GetNaturalSize(); } float TestCustomActor::GetHeightForWidth(float width) { - return 0.0f; + return GetImpl().GetHeightForWidth(width); } float TestCustomActor::GetWidthForHeight(float height) { - return 0.0f; + return GetImpl().GetWidthForHeight(height); } void TestCustomActor::OnRelayout(const Vector2& size, RelayoutContainer& container) @@ -356,17 +356,21 @@ void TestCustomActor::OnKeyInputFocusLost() } Vector3 TestCustomActor::GetNaturalSize() { - return Vector3(0.0f, 0.0f, 0.0f); + return mNaturalSize; +} +void TestCustomActor::SetNaturalSize(const Vector3& size) +{ + mNaturalSize = size; } float TestCustomActor::GetHeightForWidth(float width) { - return 0.0f; + return mH4Wfactor * width; } float TestCustomActor::GetWidthForHeight(float height) { - return 0.0f; + return mW4Hfactor * height; } void TestCustomActor::OnRelayout(const Vector2& size, RelayoutContainer& container) @@ -384,7 +388,7 @@ void TestCustomActor::OnCalculateRelayoutSize(Dimension::Type dimension) float TestCustomActor::CalculateChildSize(const Dali::Actor& child, Dimension::Type dimension) { - return 0.0f; + return CustomActorImpl::CalculateChildSizeBase(child, dimension); } void TestCustomActor::OnLayoutNegotiated(float size, Dimension::Type dimension) diff --git a/automated-tests/src/dali/dali-test-suite-utils/test-custom-actor.h b/automated-tests/src/dali/dali-test-suite-utils/test-custom-actor.h index 2a4d483..db0c78f 100644 --- a/automated-tests/src/dali/dali-test-suite-utils/test-custom-actor.h +++ b/automated-tests/src/dali/dali-test-suite-utils/test-custom-actor.h @@ -126,20 +126,29 @@ public: TestCustomActor(); TestCustomActor(bool nego); virtual ~TestCustomActor(); - void Initialize(const char* name = NULL); - virtual void OnInitialize(const char* name); - void ResetCallStack(); - void AddToCallStacks(const char* method); - void OnSceneConnection(int depth) override; - void OnSceneDisconnection() override; - void OnChildAdd(Dali::Actor& child) override; - void OnChildRemove(Dali::Actor& child) override; - void OnPropertySet(Dali::Property::Index index, const Dali::Property::Value& propertyValue) override; - void OnSizeSet(const Dali::Vector3& targetSize) override; - void OnSizeAnimation(Dali::Animation& animation, const Dali::Vector3& targetSize) override; - virtual void OnKeyInputFocusGained(); - virtual void OnKeyInputFocusLost(); - Dali::Vector3 GetNaturalSize() override; + void Initialize(const char* name = NULL); + virtual void OnInitialize(const char* name); + void ResetCallStack(); + void AddToCallStacks(const char* method); + void OnSceneConnection(int depth) override; + void OnSceneDisconnection() override; + void OnChildAdd(Dali::Actor& child) override; + void OnChildRemove(Dali::Actor& child) override; + void OnPropertySet(Dali::Property::Index index, const Dali::Property::Value& propertyValue) override; + void OnSizeSet(const Dali::Vector3& targetSize) override; + void OnSizeAnimation(Dali::Animation& animation, const Dali::Vector3& targetSize) override; + virtual void OnKeyInputFocusGained(); + virtual void OnKeyInputFocusLost(); + Dali::Vector3 GetNaturalSize() override; + void SetNaturalSize(const Dali::Vector3& size); + void SetHeightForWidthFactor(float factor) + { + mH4Wfactor = factor; + } + void SetWidthForHeightFactor(float factor) + { + mW4Hfactor = factor; + } float GetHeightForWidth(float width) override; float GetWidthForHeight(float height) override; void OnRelayout(const Dali::Vector2& size, Dali::RelayoutContainer& container) override; @@ -163,8 +172,11 @@ public: public: Dali::Property::Index mDaliProperty; std::vector mMethodsCalled; + Dali::Vector3 mNaturalSize; Dali::Vector3 mSizeSet; Dali::Vector3 mTargetSize; + float mW4Hfactor; + float mH4Wfactor; bool mNego; uint32_t mDepth; diff --git a/automated-tests/src/dali/utc-Dali-CustomActor.cpp b/automated-tests/src/dali/utc-Dali-CustomActor.cpp index 38d718e..a51242d 100644 --- a/automated-tests/src/dali/utc-Dali-CustomActor.cpp +++ b/automated-tests/src/dali/utc-Dali-CustomActor.cpp @@ -1196,10 +1196,6 @@ int UtcDaliCustomActorImplRelayoutDependentOnChildrenBase(void) v = custom.TestRelayoutDependentOnChildrenBase(Dali::Dimension::WIDTH); DALI_TEST_CHECK(v == false); - // why is this here? - application.SendNotification(); - application.Render(); - END_TEST; } diff --git a/dali/internal/event/actors/actor-coords.cpp b/dali/internal/event/actors/actor-coords.cpp index 55b8bb1..7a7275a 100644 --- a/dali/internal/event/actors/actor-coords.cpp +++ b/dali/internal/event/actors/actor-coords.cpp @@ -15,7 +15,10 @@ */ #include +#include #include +#include +#include namespace Dali::Internal { @@ -122,4 +125,33 @@ bool ConvertScreenToLocalRenderTaskList( return false; }; +const Vector2 CalculateActorScreenPosition(const Actor& actor, BufferIndex bufferIndex) +{ + Scene& scene = actor.GetScene(); + if(actor.OnScene()) + { + const auto& node = actor.GetNode(); + Vector3 worldPosition = node.GetWorldPosition(bufferIndex); + Vector3 cameraPosition = scene.GetDefaultCameraActor().GetNode().GetWorldPosition(bufferIndex); + worldPosition -= cameraPosition; + + Vector3 actorSize = node.GetSize(bufferIndex) * node.GetWorldScale(bufferIndex); + Vector2 halfSceneSize(scene.GetSize() * 0.5f); // World position origin is center of scene + Vector3 halfActorSize(actorSize * 0.5f); + Vector3 anchorPointOffSet = halfActorSize - actorSize * actor.GetAnchorPointForPosition(); + return Vector2(halfSceneSize.width + worldPosition.x - anchorPointOffSet.x, + halfSceneSize.height + worldPosition.y - anchorPointOffSet.y); + } + return Vector2::ZERO; +} + +Rect<> CalculateActorScreenExtents(const Actor& actor, const Vector2& screenPosition, BufferIndex bufferIndex) +{ + const auto& node = actor.GetNode(); + Vector3 size = node.GetSize(bufferIndex) * node.GetWorldScale(bufferIndex); + Vector3 anchorPointOffSet = size * actor.GetAnchorPointForPosition(); + Vector2 position = Vector2(screenPosition.x - anchorPointOffSet.x, screenPosition.y - anchorPointOffSet.y); + return {position.x, position.y, size.x, size.y}; +} + } // namespace Dali::Internal diff --git a/dali/internal/event/actors/actor-coords.h b/dali/internal/event/actors/actor-coords.h index 658d3e9..d6ebd36 100644 --- a/dali/internal/event/actors/actor-coords.h +++ b/dali/internal/event/actors/actor-coords.h @@ -93,6 +93,25 @@ bool ConvertScreenToLocalRenderTaskList( float screenX, float screenY); +/** + * Calculate the screen position of the actor from it's node transform and anchor point + * + * @param[in] actor The actor to calculate the screen position for + * @param[in] bufferIndex The current event buffer index + * @return the screen position + */ +const Vector2 CalculateActorScreenPosition(const Actor& actor, BufferIndex bufferIndex); + +/** + * Calculate the screen extents of the actor from its node transform, anchor point and size + * + * @param[in] actor The actor + * @param[in] screenPosition The actor's screen position + * @param[in] bufferIndex The current event buffer index + * @return the screen extents of the actor + */ +Rect<> CalculateActorScreenExtents(const Actor& actor, const Vector2& screenPosition, BufferIndex bufferIndex); + } // namespace Dali::Internal #endif // DALI_INTERNAL_EVENT_ACTORS_ACTOR_COORDS_H diff --git a/dali/internal/event/actors/actor-impl.cpp b/dali/internal/event/actors/actor-impl.cpp index 85792b6..b201786 100644 --- a/dali/internal/event/actors/actor-impl.cpp +++ b/dali/internal/event/actors/actor-impl.cpp @@ -290,45 +290,6 @@ SignalConnectorType signalConnector11(mType, std::string(SIGNAL_CHILD_REMOVED), TypeAction a1(mType, std::string(ACTION_SHOW), &DoAction); TypeAction a2(mType, std::string(ACTION_HIDE), &DoAction); -/** - * @brief Extract a given dimension from a Vector2 - * - * @param[in] values The values to extract from - * @param[in] dimension The dimension to extract - * @return Return the value for the dimension - */ -constexpr float GetDimensionValue(const Vector2& values, Dimension::Type dimension) -{ - switch(dimension) - { - case Dimension::WIDTH: - { - return values.width; - } - case Dimension::HEIGHT: - { - return values.height; - } - default: - { - break; - } - } - return 0.0f; -} - -/** - * @brief Extract a given dimension from a Vector3 - * - * @param[in] values The values to extract from - * @param[in] dimension The dimension to extract - * @return Return the value for the dimension - */ -float GetDimensionValue(const Vector3& values, Dimension::Type dimension) -{ - return GetDimensionValue(values.GetVectorXY(), dimension); -} - /// Helper for emitting a signal template bool EmitConsumingSignal(Actor& actor, Signal& signal, const Event& event) @@ -355,7 +316,7 @@ void EmitSignal(Actor& actor, Signal& signal, Param... params) } } -using ActorParentSiblingOrderMethod = void (ActorParent::*)(Actor&); +using ActorParentSiblingOrderMethod = void (ActorParent::*)(Actor&); using ActorParentSiblingOrderMethodWithTarget = void (ActorParent::*)(Actor&, Actor&); /// Helper to check and call actor sibling methods in ActorParent @@ -575,21 +536,11 @@ const Vector3& Actor::GetCurrentWorldPosition() const const Vector2 Actor::GetCurrentScreenPosition() const { - if(mScene && OnScene()) + if(mScene) { - Vector3 worldPosition = GetNode().GetWorldPosition(GetEventThreadServices().GetEventBufferIndex()); - Vector3 cameraPosition = mScene->GetDefaultCameraActor().GetNode().GetWorldPosition(GetEventThreadServices().GetEventBufferIndex()); - worldPosition -= cameraPosition; - - Vector3 actorSize = GetCurrentSize() * GetCurrentWorldScale(); - Vector2 halfSceneSize(mScene->GetSize() * 0.5f); // World position origin is center of scene - Vector3 halfActorSize(actorSize * 0.5f); - Vector3 anchorPointOffSet = halfActorSize - actorSize * (mPositionUsesAnchorPoint ? GetCurrentAnchorPoint() : AnchorPoint::TOP_LEFT); - - return Vector2(halfSceneSize.width + worldPosition.x - anchorPointOffSet.x, - halfSceneSize.height + worldPosition.y - anchorPointOffSet.y); + BufferIndex bufferIndex = GetEventThreadServices().GetEventBufferIndex(); + return CalculateActorScreenPosition(*this, bufferIndex); } - return Vector2::ZERO; } @@ -1706,11 +1657,14 @@ void Actor::SetParent(ActorParent* parent, bool notify) Rect<> Actor::CalculateScreenExtents() const { - auto screenPosition = GetCurrentScreenPosition(); - Vector3 size = GetCurrentSize() * GetCurrentWorldScale(); - Vector3 anchorPointOffSet = size * (mPositionUsesAnchorPoint ? GetCurrentAnchorPoint() : AnchorPoint::TOP_LEFT); - Vector2 position = Vector2(screenPosition.x - anchorPointOffSet.x, screenPosition.y - anchorPointOffSet.y); - return {position.x, position.y, size.x, size.y}; + auto screenPosition = GetCurrentScreenPosition(); + BufferIndex bufferIndex = GetEventThreadServices().GetEventBufferIndex(); + return CalculateActorScreenExtents(*this, screenPosition, bufferIndex); +} + +Vector3 Actor::GetAnchorPointForPosition() const +{ + return (mPositionUsesAnchorPoint ? GetCurrentAnchorPoint() : AnchorPoint::TOP_LEFT); } bool Actor::GetCachedPropertyValue(Property::Index index, Property::Value& value) const @@ -1801,29 +1755,7 @@ float Actor::GetWidthForHeightBase(float height) float Actor::CalculateChildSizeBase(const Dali::Actor& child, Dimension::Type dimension) { - // Fill to parent, taking size mode factor into account - switch(child.GetResizePolicy(dimension)) - { - case ResizePolicy::FILL_TO_PARENT: - { - return GetLatestSize(dimension); - } - - case ResizePolicy::SIZE_RELATIVE_TO_PARENT: - { - return GetLatestSize(dimension) * GetDimensionValue(child.GetProperty(Dali::Actor::Property::SIZE_MODE_FACTOR), dimension); - } - - case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT: - { - return GetLatestSize(dimension) + GetDimensionValue(child.GetProperty(Dali::Actor::Property::SIZE_MODE_FACTOR), dimension); - } - - default: - { - return GetLatestSize(dimension); - } - } + return Actor::Relayouter::CalculateChildSize(*this, GetImplementation(child), dimension); } float Actor::CalculateChildSize(const Dali::Actor& child, Dimension::Type dimension) @@ -1858,103 +1790,27 @@ float Actor::GetRelayoutSize(Dimension::Type dimension) const float Actor::NegotiateFromParent(Dimension::Type dimension) { - Actor* parent = GetParent(); - if(parent) - { - Vector2 padding(GetPadding(dimension)); - Vector2 parentPadding(parent->GetPadding(dimension)); - return parent->CalculateChildSize(Dali::Actor(this), dimension) - parentPadding.x - parentPadding.y - padding.x - padding.y; - } - - return 0.0f; + return Relayouter::NegotiateDimensionFromParent(*this, dimension); } float Actor::NegotiateFromChildren(Dimension::Type dimension) { - float maxDimensionPoint = 0.0f; - - for(uint32_t i = 0, count = GetChildCount(); i < count; ++i) - { - ActorPtr child = GetChildAt(i); - - if(!child->RelayoutDependentOnParent(dimension)) - { - // Calculate the min and max points that the children range across - float childPosition = GetDimensionValue(child->GetTargetPosition(), dimension); - float dimensionSize = child->GetRelayoutSize(dimension); - maxDimensionPoint = std::max(maxDimensionPoint, childPosition + dimensionSize); - } - } - - return maxDimensionPoint; + return Relayouter::NegotiateDimensionFromChildren(*this, dimension); } float Actor::GetSize(Dimension::Type dimension) const { - return GetDimensionValue(mTargetSize, dimension); + return Relayouter::GetDimensionValue(mTargetSize, dimension); } float Actor::GetNaturalSize(Dimension::Type dimension) const { - return GetDimensionValue(GetNaturalSize(), dimension); + return Relayouter::GetDimensionValue(GetNaturalSize(), dimension); } float Actor::CalculateSize(Dimension::Type dimension, const Vector2& maximumSize) { - switch(GetResizePolicy(dimension)) - { - case ResizePolicy::USE_NATURAL_SIZE: - { - return GetNaturalSize(dimension); - } - - case ResizePolicy::FIXED: - { - return GetDimensionValue(GetPreferredSize(), dimension); - } - - case ResizePolicy::USE_ASSIGNED_SIZE: - { - return GetDimensionValue(maximumSize, dimension); - } - - case ResizePolicy::FILL_TO_PARENT: - case ResizePolicy::SIZE_RELATIVE_TO_PARENT: - case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT: - { - return NegotiateFromParent(dimension); - } - - case ResizePolicy::FIT_TO_CHILDREN: - { - return NegotiateFromChildren(dimension); - } - - case ResizePolicy::DIMENSION_DEPENDENCY: - { - const Dimension::Type dimensionDependency = GetDimensionDependency(dimension); - - // Custom rules - if(dimension == Dimension::WIDTH && dimensionDependency == Dimension::HEIGHT) - { - return GetWidthForHeight(GetNegotiatedDimension(Dimension::HEIGHT)); - } - - if(dimension == Dimension::HEIGHT && dimensionDependency == Dimension::WIDTH) - { - return GetHeightForWidth(GetNegotiatedDimension(Dimension::WIDTH)); - } - - break; - } - - default: - { - break; - } - } - - return 0.0f; // Default + return Relayouter::CalculateSize(*this, dimension, maximumSize); } Vector2 Actor::ApplySizeSetPolicy(const Vector2& size) diff --git a/dali/internal/event/actors/actor-impl.h b/dali/internal/event/actors/actor-impl.h index b2b38b8..73a98aa 100644 --- a/dali/internal/event/actors/actor-impl.h +++ b/dali/internal/event/actors/actor-impl.h @@ -389,6 +389,13 @@ public: const Vector3& GetCurrentAnchorPoint() const; /** + * If the position uses the anchor point, return the anchor point, otherwise + * return top left. + * @return The anchor point for positioning. + */ + Vector3 GetAnchorPointForPosition() const; + + /** * Sets the position of the Actor. * The coordinates are relative to the Actor's parent. * The Actor's z position will be set to 0.0f. @@ -1047,22 +1054,6 @@ public: float NegotiateFromParent(Dimension::Type dimension); /** - * Negotiate a dimension based on the size of the parent. Fitting inside. - * - * @param[in] dimension The dimension to negotiate on - * @return Return the negotiated size - */ - float NegotiateFromParentFit(Dimension::Type dimension); - - /** - * Negotiate a dimension based on the size of the parent. Flooding the whole space. - * - * @param[in] dimension The dimension to negotiate on - * @return Return the negotiated size - */ - float NegotiateFromParentFlood(Dimension::Type dimension); - - /** * @brief Negotiate a dimension based on the size of the children * * @param[in] dimension The dimension to negotiate on diff --git a/dali/internal/event/actors/actor-relayouter.cpp b/dali/internal/event/actors/actor-relayouter.cpp index 5883a3f..f8e57d1 100644 --- a/dali/internal/event/actors/actor-relayouter.cpp +++ b/dali/internal/event/actors/actor-relayouter.cpp @@ -20,15 +20,45 @@ // INTERNAL INCLUDES #include -#include +#include #include #include +#include + namespace { #if defined(DEBUG_ENABLED) Debug::Filter* gLogRelayoutFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_RELAYOUT_TIMER"); #endif + +/** + * @brief Extract a given dimension from a Vector2 + * + * @param[in] values The values to extract from + * @param[in] dimension The dimension to extract + * @return Return the value for the dimension + */ +constexpr float GetDimensionValue(const Dali::Vector2& values, const Dali::Dimension::Type dimension) +{ + switch(dimension) + { + case Dali::Dimension::WIDTH: + { + return values.width; + } + case Dali::Dimension::HEIGHT: + { + return values.height; + } + default: + { + break; + } + } + return 0.0f; +} + } // unnamed namespace namespace Dali @@ -490,6 +520,41 @@ float Actor::Relayouter::GetNegotiatedDimension(Dimension::Type dimension) return 0.0f; // Default } +float Actor::Relayouter::NegotiateDimensionFromParent(Actor& actor, Dimension::Type dimension) +{ + Actor* parent = actor.GetParent(); + if(parent) + { + Vector2 padding(actor.GetPadding(dimension)); + Vector2 parentPadding(parent->GetPadding(dimension)); + + // Need to use actor API here to allow deriving actors to layout their children + return parent->CalculateChildSize(Dali::Actor(&actor), dimension) - parentPadding.x - parentPadding.y - padding.x - padding.y; + } + + return 0.0f; +} + +float Actor::Relayouter::NegotiateDimensionFromChildren(Actor& actor, Dimension::Type dimension) +{ + float maxDimensionPoint = 0.0f; + + for(uint32_t i = 0, count = actor.GetChildCount(); i < count; ++i) + { + ActorPtr child = actor.GetChildAt(i); + + if(!child->RelayoutDependentOnParent(dimension)) + { + // Calculate the min and max points that the children range across + float childPosition = GetDimensionValue(child->GetTargetPosition(), dimension); + float dimensionSize = child->GetRelayoutSize(dimension); + maxDimensionPoint = std::max(maxDimensionPoint, childPosition + dimensionSize); + } + } + + return maxDimensionPoint; +} + void Actor::Relayouter::NegotiateDimension(Actor& actor, Dimension::Type dimension, const Vector2& allocatedSize, Actor::ActorDimensionStack& recursionStack) { // Check if it needs to be negotiated @@ -636,6 +701,107 @@ void Actor::Relayouter::NegotiateSize(Actor& actor, const Vector2& allocatedSize DALI_LOG_TIMER_END(NegSizeTimer1, gLogRelayoutFilter, Debug::Concise, "NegotiateSize() took: "); } +/** + * @brief Extract a given dimension from a Vector3 + * + * @param[in] values The values to extract from + * @param[in] dimension The dimension to extract + * @return Return the value for the dimension + */ +float Actor::Relayouter::GetDimensionValue(const Vector3& values, const Dimension::Type dimension) +{ + return ::GetDimensionValue(values.GetVectorXY(), dimension); +} + +float Actor::Relayouter::CalculateSize(Actor& actor, Dimension::Type dimension, const Vector2& maximumSize) +{ + switch(actor.GetResizePolicy(dimension)) + { + case ResizePolicy::USE_NATURAL_SIZE: + { + return actor.GetNaturalSize(dimension); + } + + case ResizePolicy::FIXED: + { + return ::GetDimensionValue(actor.GetPreferredSize(), dimension); + } + + case ResizePolicy::USE_ASSIGNED_SIZE: + { + return ::GetDimensionValue(maximumSize, dimension); + } + + case ResizePolicy::FILL_TO_PARENT: + case ResizePolicy::SIZE_RELATIVE_TO_PARENT: + case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT: + { + return NegotiateDimensionFromParent(actor, dimension); + } + + case ResizePolicy::FIT_TO_CHILDREN: + { + return NegotiateDimensionFromChildren(actor, dimension); + } + + case ResizePolicy::DIMENSION_DEPENDENCY: + { + const Dimension::Type dimensionDependency = actor.GetDimensionDependency(dimension); + + // Custom rules + if(dimension == Dimension::WIDTH && dimensionDependency == Dimension::HEIGHT) + { + return actor.GetWidthForHeight(actor.GetNegotiatedDimension(Dimension::HEIGHT)); + } + + if(dimension == Dimension::HEIGHT && dimensionDependency == Dimension::WIDTH) + { + return actor.GetHeightForWidth(actor.GetNegotiatedDimension(Dimension::WIDTH)); + } + + break; + } + + default: + { + break; + } + } + + return 0.0f; // Default +} + +float Actor::Relayouter::CalculateChildSize(Actor& actor, const Actor& child, Dimension::Type dimension) +{ + // Fill to parent, taking size mode factor into account + switch(child.GetResizePolicy(dimension)) + { + case ResizePolicy::FILL_TO_PARENT: + { + return actor.GetLatestSize(dimension); + } + + case ResizePolicy::SIZE_RELATIVE_TO_PARENT: + { + Property::Value value = child.GetProperty(Dali::Actor::Property::SIZE_MODE_FACTOR); + Vector3 childSizeModeFactor = value.Get(); + return actor.GetLatestSize(dimension) * GetDimensionValue(childSizeModeFactor, dimension); + } + + case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT: + { + Property::Value value = child.GetProperty(Dali::Actor::Property::SIZE_MODE_FACTOR); + Vector3 childSizeModeFactor = value.Get(); + return actor.GetLatestSize(dimension) + GetDimensionValue(childSizeModeFactor, dimension); + } + + default: + { + return actor.GetLatestSize(dimension); + } + } +} + } // namespace Internal } // namespace Dali diff --git a/dali/internal/event/actors/actor-relayouter.h b/dali/internal/event/actors/actor-relayouter.h index f34e346..40c4911 100644 --- a/dali/internal/event/actors/actor-relayouter.h +++ b/dali/internal/event/actors/actor-relayouter.h @@ -125,6 +125,22 @@ struct Actor::Relayouter float GetNegotiatedDimension(Dimension::Type dimension); /** + * Negotiate a dimension based on the size of the parent + * + * @param[in] dimension The dimension to negotiate on + * @return Return the negotiated size + */ + static float NegotiateDimensionFromParent(Actor& actor, Dimension::Type dimension); + + /** + * @brief Negotiate a dimension based on the size of the children + * + * @param[in] dimension The dimension to negotiate on + * @return Return the negotiated size + */ + static float NegotiateDimensionFromChildren(Actor& actor, Dimension::Type dimension); + + /** * Negotiate size for a specific dimension * * The algorithm adopts a recursive dependency checking approach. Meaning, that wherever dependencies @@ -163,6 +179,21 @@ struct Actor::Relayouter */ static void NegotiateSize(Actor& actor, const Vector2& allocatedSize, RelayoutContainer& container); + /** + * Get the value for the given dimension + * + * @param[in] values The vector to get values from + * @param[in] dimension The dimension to fetch + * @return the value of the given dimension + */ + static float GetDimensionValue(const Vector3& values, const Dimension::Type dimension); + + /// @copydoc Actor::CalculateSize + static float CalculateSize(Actor& actor, Dimension::Type dimension, const Vector2& maximumSize); + + /// @copydoc Actor::CalculateChildSizeBase + static float CalculateChildSize(Actor& actor, const Actor& child, Dimension::Type dimension); + public: ResizePolicy::Type resizePolicies[Dimension::DIMENSION_COUNT]; ///< Resize policies bool useAssignedSize[Dimension::DIMENSION_COUNT]; ///< The flag to specify whether the size should be assigned to the actor diff --git a/dali/internal/event/common/scene-impl.cpp b/dali/internal/event/common/scene-impl.cpp index 6a251c9..7994cdf 100644 --- a/dali/internal/event/common/scene-impl.cpp +++ b/dali/internal/event/common/scene-impl.cpp @@ -188,7 +188,7 @@ Dali::Layer Scene::GetLayer(uint32_t depth) const return Dali::Layer(mLayerList->GetLayer(depth)); } -CameraActor& Scene::GetDefaultCameraActor() +CameraActor& Scene::GetDefaultCameraActor() const { return *mDefaultCamera; } diff --git a/dali/internal/event/common/scene-impl.h b/dali/internal/event/common/scene-impl.h index 6686d9d..7065c16 100644 --- a/dali/internal/event/common/scene-impl.h +++ b/dali/internal/event/common/scene-impl.h @@ -369,7 +369,7 @@ public: * From RenderTaskDefaults; retrieve the default camera actor. * @return The default camera actor. */ - CameraActor& GetDefaultCameraActor() override; + CameraActor& GetDefaultCameraActor() const override; private: // Constructor diff --git a/dali/internal/event/common/stage-impl.cpp b/dali/internal/event/common/stage-impl.cpp index ee319a4..bd1c15e 100644 --- a/dali/internal/event/common/stage-impl.cpp +++ b/dali/internal/event/common/stage-impl.cpp @@ -148,7 +148,7 @@ Actor& Stage::GetDefaultRootActor() return mScene->GetDefaultRootActor(); } -CameraActor& Stage::GetDefaultCameraActor() +CameraActor& Stage::GetDefaultCameraActor() const { return mScene->GetDefaultCameraActor(); } diff --git a/dali/internal/event/common/stage-impl.h b/dali/internal/event/common/stage-impl.h index d62c663..eee40da 100644 --- a/dali/internal/event/common/stage-impl.h +++ b/dali/internal/event/common/stage-impl.h @@ -135,7 +135,7 @@ public: * From RenderTaskDefaults; retrieve the default camera actor. * @return The default camera actor. */ - CameraActor& GetDefaultCameraActor() override; + CameraActor& GetDefaultCameraActor() const override; // Layers diff --git a/dali/internal/event/render-tasks/render-task-defaults.h b/dali/internal/event/render-tasks/render-task-defaults.h index f5a1580..3076475 100644 --- a/dali/internal/event/render-tasks/render-task-defaults.h +++ b/dali/internal/event/render-tasks/render-task-defaults.h @@ -41,7 +41,7 @@ public: * Retrieve the default camera actor. * @return The default camera actor. */ - virtual CameraActor& GetDefaultCameraActor() = 0; + virtual CameraActor& GetDefaultCameraActor() const = 0; protected: /** diff --git a/dali/public-api/actors/actor-enumerations.h b/dali/public-api/actors/actor-enumerations.h index 5d51597..14c9821 100644 --- a/dali/public-api/actors/actor-enumerations.h +++ b/dali/public-api/actors/actor-enumerations.h @@ -2,7 +2,7 @@ #define DALI_ACTOR_ENUMERATIONS_H /* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. + * Copyright (c) 2021 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -84,8 +84,8 @@ enum Type FIXED, ///< Size is fixed as set by SetSize @SINCE_1_0.0 USE_NATURAL_SIZE, ///< Size is to use the actor's natural size @SINCE_1_0.0 @see Actor::GetNaturalSize() FILL_TO_PARENT, ///< Size is to fill up to the actor's parent's bounds. Aspect ratio is not maintained. @SINCE_1_0.0 - SIZE_RELATIVE_TO_PARENT, ///< The actors size will be ( ParentSize * SizeRelativeToParentFactor ). @SINCE_1_0.0 - SIZE_FIXED_OFFSET_FROM_PARENT, ///< The actors size will be ( ParentSize + SizeRelativeToParentFactor ). @SINCE_1_0.0 + SIZE_RELATIVE_TO_PARENT, ///< The actor's size will be ( ParentSize * SizeModeFactor ). @SINCE_1_0.0 + SIZE_FIXED_OFFSET_FROM_PARENT, ///< The actor's size will be ( ParentSize + SizeModeFactor ). @SINCE_1_0.0 FIT_TO_CHILDREN, ///< Size will adjust to wrap around all children @SINCE_1_0.0 DIMENSION_DEPENDENCY, ///< One dimension is dependent on the other @SINCE_1_0.0 USE_ASSIGNED_SIZE ///< The size will be assigned to the actor @SINCE_1_0.0