364e92cc17446442efe183b4c65ba5c1865a070e
[platform/core/uifw/dali-core.git] / dali / internal / event / actors / actor-relayouter.h
1 #ifndef DALI_INTERNAL_ACTOR_RELAYOUTER_H
2 #define DALI_INTERNAL_ACTOR_RELAYOUTER_H
3
4 /*
5  * Copyright (c) 2021 Samsung Electronics Co., Ltd.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  */
20
21 // INTERNAL INCLUDES
22 #include <dali/internal/event/actors/actor-impl.h>
23 #include <dali/public-api/math/vector2.h>
24 #include <dali/public-api/math/vector3.h>
25
26 namespace Dali
27 {
28 namespace Internal
29 {
30 /**
31  * Struct to do some actor specific relayouting and store related variables
32  */
33 struct Actor::Relayouter
34 {
35   // Defaults
36   static constexpr Vector3               DEFAULT_SIZE_MODE_FACTOR{1.0f, 1.0f, 1.0f};
37   static constexpr Vector2               DEFAULT_PREFERRED_SIZE{0.0f, 0.0f};
38   static constexpr Vector2               DEFAULT_DIMENSION_PADDING{0.0f, 0.0f};
39   static constexpr SizeScalePolicy::Type DEFAULT_SIZE_SCALE_POLICY = SizeScalePolicy::USE_SIZE_SET;
40
41   /// Constructor
42   Relayouter();
43
44   /// Default Destructor
45   ~Relayouter() = default;
46
47   /// @copydoc Actor::GetResizePolicy
48   ResizePolicy::Type GetResizePolicy(Dimension::Type dimension) const;
49
50   /// @copydoc Actor::SetPadding
51   void SetPadding(const Vector2& padding, Dimension::Type dimension);
52
53   /// @copydoc Actor::SetLayoutNegotiated
54   void SetLayoutNegotiated(bool negotiated, Dimension::Type dimension);
55
56   /// @copydoc Actor::IsLayoutNegotiated
57   bool IsLayoutNegotiated(Dimension::Type dimension) const;
58
59   /// @copydoc Actor::ApplySizeSetPolicy
60   Vector2 ApplySizeSetPolicy(Internal::Actor& actor, const Vector2& size);
61
62   /// @copydoc Actor::SetUseAssignedSize
63   void SetUseAssignedSize(bool use, Dimension::Type dimension);
64
65   /// @copydoc Actor::GetUseAssignedSize
66   bool GetUseAssignedSize(Dimension::Type dimension) const;
67
68   /// @copydoc Actor::SetMinimumSize
69   void SetMinimumSize(float size, Dimension::Type dimension);
70
71   /// @copydoc Actor::GetMinimumSize
72   float GetMinimumSize(Dimension::Type dimension) const;
73
74   /// @copydoc Actor::SetMaximumSize
75   void SetMaximumSize(float size, Dimension::Type dimension);
76
77   /// @copydoc Actor::GetMaximumSize
78   float GetMaximumSize(Dimension::Type dimension) const;
79
80   /// @copydoc Actor::SetResizePolicy
81   void SetResizePolicy(ResizePolicy::Type policy, Dimension::Type dimension, Vector3& targetSize);
82
83   /// @copydoc Actor::SetDimensionDependency
84   void SetDimensionDependency(Dimension::Type dimension, Dimension::Type dependency);
85
86   /// @copydoc Actor::GetDimensionDependency
87   Dimension::Type GetDimensionDependency(Dimension::Type dimension) const;
88
89   /// @copydoc Actor::SetLayoutDirty
90   void SetLayoutDirty(bool dirty, Dimension::Type dimension);
91
92   /// @copydoc Actor::IsLayoutDirty
93   bool IsLayoutDirty(Dimension::Type dimension) const;
94
95   /// @copydoc Actor::SetPreferredSize
96   /// @actor[in] actor The Actor whose preferred size we wish to set
97   void SetPreferredSize(Actor& actor, const Vector2& size);
98
99   /**
100    * @brief Clamp a dimension given the relayout constraints on given actor
101    *
102    * @param[in] actor The actor to clamp
103    * @param[in] size The size to constrain
104    * @param[in] dimension The dimension the size exists in
105    * @return Return the clamped size
106    */
107   static float ClampDimension(const Internal::Actor& actor, float size, Dimension::Type dimension);
108
109   /**
110    * Negotiate size for a specific dimension
111    *
112    * The algorithm adopts a recursive dependency checking approach. Meaning, that wherever dependencies
113    * are found, e.g. an actor dependent on its parent, the dependency will be calculated first with NegotiatedDimension and
114    * LayoutDimensionNegotiated flags being filled in on the actor.
115    *
116    * @post All actors that exist in the dependency chain connected to the given actor will have had their NegotiatedDimensions
117    * calculated and set as well as the LayoutDimensionNegotiated flags.
118    *
119    * @param[in] actor The actor whose dimension we are negotiating
120    * @param[in] dimension The dimension to negotiate on
121    * @param[in] allocatedSize The size constraint that the actor must respect
122    */
123   static void NegotiateDimension(Actor& actor, Dimension::Type dimension, const Vector2& allocatedSize, Actor::ActorDimensionStack& recursionStack);
124
125   /**
126    * Negotiate sizes for a control in all dimensions
127    *
128    * @param[in] actor The actor whose dimensions we are negotiating
129    * @param[in] allocatedSize The size constraint that the control must respect
130    */
131   static void NegotiateDimensions(Actor& actor, const Vector2& allocatedSize);
132
133   /**
134    * @brief Called by the RelayoutController to negotiate the size of an actor.
135    *
136    * The size allocated by the the algorithm is passed in which the
137    * actor must adhere to.  A container is passed in as well which
138    * the actor should populate with actors it has not / or does not
139    * need to handle in its size negotiation.
140    *
141    * @param[in] actor The actor whose size we are negotiating
142    * @param[in]      size       The allocated size.
143    * @param[in,out]  container  The container that holds actors that are fed back into the
144    *                            RelayoutController algorithm.
145    */
146   static void NegotiateSize(Actor& actor, const Vector2& allocatedSize, RelayoutContainer& container);
147
148 public:
149   ResizePolicy::Type resizePolicies[Dimension::DIMENSION_COUNT];  ///< Resize policies
150   bool               useAssignedSize[Dimension::DIMENSION_COUNT]; ///< The flag to specify whether the size should be assigned to the actor
151
152   Dimension::Type dimensionDependencies[Dimension::DIMENSION_COUNT]; ///< A list of dimension dependencies
153
154   Vector2 dimensionPadding[Dimension::DIMENSION_COUNT]; ///< Padding for each dimension. X = start (e.g. left, bottom), y = end (e.g. right, top)
155
156   float negotiatedDimensions[Dimension::DIMENSION_COUNT]; ///< Storage for when a dimension is negotiated but before set on actor
157
158   float minimumSize[Dimension::DIMENSION_COUNT]; ///< The minimum size an actor can be
159   float maximumSize[Dimension::DIMENSION_COUNT]; ///< The maximum size an actor can be
160
161   bool dimensionNegotiated[Dimension::DIMENSION_COUNT]; ///< Has the dimension been negotiated
162   bool dimensionDirty[Dimension::DIMENSION_COUNT];      ///< Flags indicating whether the layout dimension is dirty or not
163
164   Vector3 sizeModeFactor; ///< Factor of size used for certain SizeModes
165
166   Vector2 preferredSize; ///< The preferred size of the actor
167
168   SizeScalePolicy::Type sizeSetPolicy : 3; ///< Policy to apply when setting size. Enough room for the enum
169
170   bool relayoutEnabled : 1;   ///< Flag to specify if this actor should be included in size negotiation or not (defaults to true)
171   bool insideRelayout : 1;    ///< Locking flag to prevent recursive relayouts on size set
172   bool relayoutRequested : 1; ///< Whether the relayout is requested.
173 };
174
175 } // namespace Internal
176
177 } // namespace Dali
178
179 #endif // DALI_INTERNAL_ACTOR_RELAYOUTER_H