Refactored more code into Actor::Relayouter 48/266248/1
authorDavid Steele <david.steele@samsung.com>
Tue, 9 Nov 2021 18:19:08 +0000 (18:19 +0000)
committerDavid Steele <david.steele@samsung.com>
Tue, 9 Nov 2021 18:19:08 +0000 (18:19 +0000)
Change-Id: I19e711ddc963e62a882679ca0afebfc5e25bb339

17 files changed:
automated-tests/src/dali-internal/CMakeLists.txt
automated-tests/src/dali-internal/utc-Dali-Internal-ActorRelayout.cpp [new file with mode: 0644]
automated-tests/src/dali/dali-test-suite-utils/test-custom-actor.cpp
automated-tests/src/dali/dali-test-suite-utils/test-custom-actor.h
automated-tests/src/dali/utc-Dali-CustomActor.cpp
dali/internal/event/actors/actor-coords.cpp
dali/internal/event/actors/actor-coords.h
dali/internal/event/actors/actor-impl.cpp
dali/internal/event/actors/actor-impl.h
dali/internal/event/actors/actor-relayouter.cpp
dali/internal/event/actors/actor-relayouter.h
dali/internal/event/common/scene-impl.cpp
dali/internal/event/common/scene-impl.h
dali/internal/event/common/stage-impl.cpp
dali/internal/event/common/stage-impl.h
dali/internal/event/render-tasks/render-task-defaults.h
dali/public-api/actors/actor-enumerations.h

index 29d78b2..64a73b5 100644 (file)
@@ -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 (file)
index 0000000..11babca
--- /dev/null
@@ -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 <dali-test-suite-utils.h>
+#include <dali/public-api/signals/callback.h>
+#include <stdlib.h>
+#include "test-custom-actor.h"
+
+#include <iostream>
+
+// Internal headers are allowed here
+#include <dali/internal/event/actors/actor-impl.h>
+#include <dali/internal/event/actors/actor-relayouter.h>
+
+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;
+}
index db6cfca..6c7b1d6 100644 (file)
@@ -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)
index 2a4d483..db0c78f 100644 (file)
@@ -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<std::string> mMethodsCalled;
+  Dali::Vector3            mNaturalSize;
   Dali::Vector3            mSizeSet;
   Dali::Vector3            mTargetSize;
+  float                    mW4Hfactor;
+  float                    mH4Wfactor;
   bool                     mNego;
   uint32_t                 mDepth;
 
index 38d718e..a51242d 100644 (file)
@@ -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;
 }
 
index 55b8bb1..7a7275a 100644 (file)
  */
 
 #include <dali/internal/event/actors/actor-coords.h>
+#include <dali/internal/event/common/event-thread-services.h>
 #include <dali/internal/event/common/projection.h>
+#include <dali/internal/event/common/scene-impl.h>
+#include <dali/internal/update/nodes/node.h>
 
 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
index 658d3e9..d6ebd36 100644 (file)
@@ -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
index 85792b6..b201786 100644 (file)
@@ -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<typename Signal, typename Event>
 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<Vector3>(Dali::Actor::Property::SIZE_MODE_FACTOR), dimension);
-    }
-
-    case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
-    {
-      return GetLatestSize(dimension) + GetDimensionValue(child.GetProperty<Vector3>(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)
index b2b38b8..73a98aa 100644 (file)
@@ -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
index 5883a3f..f8e57d1 100644 (file)
 
 // INTERNAL INCLUDES
 #include <dali/integration-api/debug.h>
-#include <dali/internal/event/size-negotiation/relayout-controller-impl.h>
+#include <dali/public-api/actors/actor.h>
 #include <dali/public-api/math/vector2.h>
 #include <dali/public-api/math/vector3.h>
 
+#include <dali/internal/event/size-negotiation/relayout-controller-impl.h>
+
 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<Vector3>();
+      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<Vector3>();
+      return actor.GetLatestSize(dimension) + GetDimensionValue(childSizeModeFactor, dimension);
+    }
+
+    default:
+    {
+      return actor.GetLatestSize(dimension);
+    }
+  }
+}
+
 } // namespace Internal
 
 } // namespace Dali
index f34e346..40c4911 100644 (file)
@@ -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
index 6a251c9..7994cdf 100644 (file)
@@ -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;
 }
index 6686d9d..7065c16 100644 (file)
@@ -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
index ee319a4..bd1c15e 100644 (file)
@@ -148,7 +148,7 @@ Actor& Stage::GetDefaultRootActor()
   return mScene->GetDefaultRootActor();
 }
 
-CameraActor& Stage::GetDefaultCameraActor()
+CameraActor& Stage::GetDefaultCameraActor() const
 {
   return mScene->GetDefaultCameraActor();
 }
index d62c663..eee40da 100644 (file)
@@ -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
 
index f5a1580..3076475 100644 (file)
@@ -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:
   /**
index 5d51597..14c9821 100644 (file)
@@ -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