27ea3f7637bb5c971a46ba63ec45d35bad6a7dca
[platform/core/uifw/dali-core.git] / dali / internal / event / actors / actor-sizer.h
1 #ifndef DALI_INTERNAL_ACTOR_SIZER_H
2 #define DALI_INTERNAL_ACTOR_SIZER_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 #include <dali/internal/event/actors/actor-declarations.h>
21 #include <dali/public-api/math/vector3.h>
22 #include <dali/public-api/size-negotiation/relayout-container.h>
23
24 namespace Dali::Internal
25 {
26 class Actor;
27 class Animation;
28
29 /**
30  * Class to handle sizing of actor. Uses size negotiation and animation.
31  */
32 class ActorSizer
33 {
34 public:
35   struct AnimatedSizeFlag
36   {
37     enum Type
38     {
39       CLEAR  = 0,
40       WIDTH  = 1,
41       HEIGHT = 2,
42       DEPTH  = 4
43     };
44   };
45
46   /**
47    * @brief Struct to hold an actor and a dimension
48    */
49   struct ActorDimensionPair
50   {
51     /**
52      * @brief Constructor
53      *
54      * @param[in] newActor The actor to assign
55      * @param[in] newDimension The dimension to assign
56      */
57     ActorDimensionPair(Actor* newActor, Dimension::Type newDimension)
58     : actor(newActor),
59       dimension(newDimension)
60     {
61     }
62
63     /**
64      * @brief Equality operator
65      *
66      * @param[in] lhs The left hand side argument
67      * @param[in] rhs The right hand side argument
68      */
69     bool operator==(const ActorDimensionPair& rhs)
70     {
71       return (actor == rhs.actor) && (dimension == rhs.dimension);
72     }
73
74     Actor*          actor;     ///< The actor to hold
75     Dimension::Type dimension; ///< The dimension to hold
76   };
77
78   using ActorDimensionStack = std::vector<ActorDimensionPair>;
79
80 public:
81   /// Constructor
82   ActorSizer(Internal::Actor& owner);
83
84   /// Destructor
85   ~ActorSizer();
86
87   // Remove default constructor, copy constructor and assignment operator
88   ActorSizer()                  = delete;
89   ActorSizer(const ActorSizer&) = delete;
90   ActorSizer& operator=(const ActorSizer) = delete;
91
92   ///@copydoc Actor::SetSizerModeFactor
93   void SetSizeModeFactor(const Vector3& factor);
94
95   ///@copydoc Actor::
96   const Vector3& GetSizeModeFactor() const;
97
98   ///@copydoc Actor::SetSize
99   void SetSize(const Vector3& size);
100
101   ///@ Set the target size / preferred size
102   void SetSizeInternal(const Vector3& size);
103
104   ///@copydoc Actor::SetWidth
105   void SetWidth(float width);
106
107   ///@copydoc Actor::SetHeight
108   void SetHeight(float height);
109
110   ///@copydoc Actor::SetDepth
111   void SetDepth(float depth);
112
113   ///@copydoc Actor::GetTargetSize
114   Vector3 GetTargetSize() const;
115
116   ///@copydoc Actor::SetResizePolicy
117   void SetResizePolicy(ResizePolicy::Type policy, Dimension::Type dimension = Dimension::ALL_DIMENSIONS);
118
119   ///@copydoc Actor:::Type
120   ResizePolicy::Type GetResizePolicy(Dimension::Type dimension) const;
121
122   ///@copydoc Actor::SetSizeScalePolicy
123   void SetSizeScalePolicy(SizeScalePolicy::Type policy);
124
125   ///@copydoc Actor:::GetSizeScalePolicy
126   SizeScalePolicy::Type GetSizeScalePolicy() const;
127
128   ///@copydoc Actor::SetDimensionDependency
129   void SetDimensionDependency(Dimension::Type dimension, Dimension::Type dependency);
130
131   ///@copydoc Actor::GetDimensionDependency
132   Dimension::Type GetDimensionDependency(Dimension::Type dimension) const;
133
134   ///@copydoc Actor::SetRelayoutEnabled
135   void SetRelayoutEnabled(bool relayoutEnabled);
136
137   ///@copydoc Actor::IsRelayoutEnabled
138   bool IsRelayoutEnabled() const;
139
140   ///@copydoc Actor::SetLayoutDirty
141   void SetLayoutDirty(bool dirty, Dimension::Type dimension = Dimension::ALL_DIMENSIONS);
142
143   ///@copydoc Actor::IsLayoutDirty
144   bool IsLayoutDirty(Dimension::Type dimension = Dimension::ALL_DIMENSIONS) const;
145
146   ///@copydoc Actor::RelayoutPossible
147   bool RelayoutPossible(Dimension::Type dimension = Dimension::ALL_DIMENSIONS) const;
148
149   ///@copydoc Actor::RelayoutRequired
150   bool RelayoutRequired(Dimension::Type dimension = Dimension::ALL_DIMENSIONS) const;
151
152   ///@copydoc Actor::RelayoutDependentOnParent
153   bool RelayoutDependentOnParent(Dimension::Type dimension = Dimension::ALL_DIMENSIONS);
154
155   ///@copydoc Actor::RelayoutDependentOnChildren
156   bool RelayoutDependentOnChildrenBase(Dimension::Type dimension = Dimension::ALL_DIMENSIONS);
157
158   ///@copydoc Actor::RelayoutDependentOnDimension
159   bool RelayoutDependentOnDimension(Dimension::Type dimension, Dimension::Type dependentDimension);
160
161   ///@copydoc Actor::SetNegotiatedDimension
162   void SetNegotiatedDimension(float negotiatedDimension, Dimension::Type dimension = Dimension::ALL_DIMENSIONS);
163
164   ///@copydoc Actor::GetNegotiatedDimension
165   float GetNegotiatedDimension(Dimension::Type dimension) const;
166
167   ///@copydoc Actor::SetPadding
168   void SetPadding(const Vector2& padding, Dimension::Type dimension);
169
170   ///@copydoc Actor::GetPadding
171   Vector2 GetPadding(Dimension::Type dimension) const;
172
173   ///@copydoc Actor::SetLayoutNegotiated
174   void SetLayoutNegotiated(bool negotiated, Dimension::Type dimension);
175
176   ///@copydoc Actor::IsLayoutNegotiated
177   bool IsLayoutNegotiated(Dimension::Type dimension) const;
178
179   ///@copydoc Actor::GetHeightForWidth
180   float GetHeightForWidthBase(float width);
181
182   ///@copydoc Actor::GetWidthForHeight
183   float GetWidthForHeightBase(float height);
184
185   ///@copydoc Actor::CalculateChildSize
186   float CalculateChildSizeBase(const Dali::Actor& child, Dimension::Type dimension);
187
188   ///@copydoc Actor::GetLatestSize
189   float GetLatestSize(Dimension::Type dimension) const;
190
191   ///@copydoc Actor::GetRelayoutSize
192   float GetRelayoutSize(Dimension::Type dimension) const;
193
194   ///@copydoc Actor::GetSize
195   float GetSize(Dimension::Type dimension) const;
196
197   ///@copydoc Actor::GetNaturalSize
198   float GetNaturalSize(Dimension::Type dimension) const;
199
200   ///@copydoc Actor::ApplySizeSetPolicy
201   Vector2 ApplySizeSetPolicy(const Vector2& size);
202
203   ///@copydoc Actor::SetNegotiatedSize
204   void SetNegotiatedSize(RelayoutContainer& container);
205
206   ///@copydoc Actor::NegotiateSize
207   void NegotiateSize(const Vector2& allocatedSize, RelayoutContainer& container);
208
209   ///@copydoc Actor::RelayoutRequest
210   void RelayoutRequest(Dimension::Type dimension = Dimension::ALL_DIMENSIONS);
211
212   ///@copydoc Actor::SetMinimumSize
213   void SetMinimumSize(float size, Dimension::Type dimension = Dimension::ALL_DIMENSIONS);
214
215   ///@copydoc Actor::GetMinimumSize
216   float GetMinimumSize(Dimension::Type dimension) const;
217
218   ///@copydoc Actor::SetMaximumSize
219   void SetMaximumSize(float size, Dimension::Type dimension = Dimension::ALL_DIMENSIONS);
220
221   ///@copydoc Actor::GetMaximumSize
222   float GetMaximumSize(Dimension::Type dimension) const;
223
224   /**
225    * Update target / preferred / animated size when size animation starts
226    * @param[in] animation The animation modifying the size
227    * @param[in] targetSize The new target size
228    */
229   void OnAnimateSize(Animation& animation, Vector3 targetSize, bool relative);
230
231   /**
232    * Update target / preferred / animated width when size animation starts
233    * @param[in] animation The animation modifying the width
234    * @param[in] targetWidth The new target width
235    */
236   void OnAnimateWidth(Animation& animation, float targetWidth, bool relative);
237
238   /**
239    * Update target / preferred / animated height when size animation starts
240    * @param[in] animation The animation modifying the height
241    * @param[in] targetHeight The new target height
242    */
243   void OnAnimateHeight(Animation& animation, float targetHeight, bool relative);
244
245   /**
246    * Update target / preferred / animated depth when size animation starts
247    * @param[in] animation The animation modifying the depth
248    * @param[in] targetDepth The new target depth
249    */
250   void OnAnimateDepth(Animation& animation, float targetDepth, bool relative);
251
252 private:
253   struct Relayouter;
254
255   /**
256    * @brief Ensure the relayouter is allocated
257    */
258   Relayouter& EnsureRelayouter();
259
260   /**
261   * @brief Extract a given dimension from a Vector3
262   *
263   * @param[in] values The values to extract from
264   * @param[in] dimension The dimension to extract
265   * @return Return the value for the dimension
266   */
267   float GetDimensionValue(const Vector3& values, const Dimension::Type dimension) const;
268
269   /**
270    * @brief Clamp a dimension given the relayout constraints on given actor
271    *
272    * @param[in] size The size to constrain
273    * @param[in] dimension The dimension the size exists in
274    * @return Return the clamped size
275    */
276   float ClampDimension(float size, Dimension::Type dimension) const;
277
278   /**
279    * Negotiate a dimension based on the size of the parent
280    *
281    * @param[in] dimension The dimension to negotiate on
282    * @return Return the negotiated size
283    */
284   float NegotiateFromParent(Dimension::Type dimension);
285
286   /**
287    * @brief Negotiate a dimension based on the size of the children
288    *
289    * @param[in] dimension The dimension to negotiate on
290    * @return Return the negotiated size
291    */
292   float NegotiateFromChildren(Dimension::Type dimension);
293
294   /**
295    * Negotiate size for a specific dimension
296    *
297    * The algorithm adopts a recursive dependency checking approach. Meaning, that wherever dependencies
298    * are found, e.g. an actor dependent on its parent, the dependency will be calculated first with NegotiatedDimension and
299    * LayoutDimensionNegotiated flags being filled in on the actor.
300    *
301    * @post All actors that exist in the dependency chain connected to the given actor will have had their NegotiatedDimensions
302    * calculated and set as well as the LayoutDimensionNegotiated flags.
303    *
304    * @param[in] dimension The dimension to negotiate on
305    * @param[in] allocatedSize The size constraint that the actor must respect
306    */
307   void NegotiateDimension(Dimension::Type dimension, const Vector2& allocatedSize, ActorDimensionStack& recursionStack);
308
309   /**
310    * Negotiate sizes for a control in all dimensions
311    *
312    * @param[in] allocatedSize The size constraint that the control must respect
313    */
314   void NegotiateDimensions(const Vector2& allocatedSize);
315
316   /**
317    * @brief Set whether size negotiation should use the assigned size of the actor
318    * during relayout for the given dimension(s)
319    *
320    * @param[in] use Whether the assigned size of the actor should be used
321    * @param[in] dimension The dimension(s) to set. Can be a bitfield of multiple dimensions
322    */
323   void SetUseAssignedSize(bool use, Dimension::Type dimension = Dimension::ALL_DIMENSIONS);
324
325   /**
326    * @brief Returns whether size negotiation should use the assigned size of the actor
327    * during relayout for a single dimension
328    *
329    * @param[in] dimension The dimension to get
330    * @return Return whether the assigned size of the actor should be used. If more than one dimension is requested, just return the first one found
331    */
332   bool GetUseAssignedSize(Dimension::Type dimension) const;
333
334   /**
335    * @brief Calculate the size of a dimension
336    *
337    * @param[in] dimension The dimension to calculate the size for
338    * @param[in] maximumSize The upper bounds on the size
339    * @return Return the calculated size for the dimension
340    */
341   float CalculateSize(Dimension::Type dimension, const Vector2& maximumSize);
342
343   /**
344    * @brief Set the preferred size for size negotiation
345    *
346    * @param[in] size The preferred size to set
347    */
348   void SetPreferredSize(const Vector2& size);
349
350   /**
351    * @brief Get the preferred size for size negotiation
352    *
353    * @return size The preferred size to set
354    */
355   Vector2 GetPreferredSize() const;
356
357 private:
358   Internal::Actor& mOwner;               // Owner of this actor sizer
359   Relayouter*      mRelayoutData;        ///< Struct to hold optional collection of relayout variables
360   Dali::Vector3    mTargetSize;          ///< Event-side storage for size (not a pointer as most actors will have a size)
361   Dali::Vector3    mAnimatedSize;        ///< Event-side storage for size animation
362   uint16_t         mUseAnimatedSize;     ///< Whether the size is animated.
363   bool             mTargetSizeDirtyFlag; ///< Whether the target size is dirty or not.
364   bool             mInsideOnSizeSet : 1;
365 };
366
367 } // namespace Dali::Internal
368
369 #endif //DALI_INTERNAL_ACTOR_SIZER_H