1 #ifndef DALI_INTERNAL_ACTOR_SIZER_H
2 #define DALI_INTERNAL_ACTOR_SIZER_H
5 * Copyright (c) 2021 Samsung Electronics Co., Ltd.
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
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>
24 namespace Dali::Internal
30 * Class to handle sizing of actor. Uses size negotiation and animation.
35 struct AnimatedSizeFlag
47 * @brief Struct to hold an actor and a dimension
49 struct ActorDimensionPair
54 * @param[in] newActor The actor to assign
55 * @param[in] newDimension The dimension to assign
57 ActorDimensionPair(Actor* newActor, Dimension::Type newDimension)
59 dimension(newDimension)
64 * @brief Equality operator
66 * @param[in] lhs The left hand side argument
67 * @param[in] rhs The right hand side argument
69 bool operator==(const ActorDimensionPair& rhs)
71 return (actor == rhs.actor) && (dimension == rhs.dimension);
74 Actor* actor; ///< The actor to hold
75 Dimension::Type dimension; ///< The dimension to hold
78 using ActorDimensionStack = std::vector<ActorDimensionPair>;
82 ActorSizer(Internal::Actor& owner);
87 // Remove default constructor, copy constructor and assignment operator
88 ActorSizer() = delete;
89 ActorSizer(const ActorSizer&) = delete;
90 ActorSizer& operator=(const ActorSizer) = delete;
92 ///@copydoc Actor::SetSizerModeFactor
93 void SetSizeModeFactor(const Vector3& factor);
96 const Vector3& GetSizeModeFactor() const;
98 ///@copydoc Actor::SetSize
99 void SetSize(const Vector3& size);
101 ///@ Set the target size / preferred size
102 void SetSizeInternal(const Vector3& size);
104 ///@copydoc Actor::SetWidth
105 void SetWidth(float width);
107 ///@copydoc Actor::SetHeight
108 void SetHeight(float height);
110 ///@copydoc Actor::SetDepth
111 void SetDepth(float depth);
113 ///@copydoc Actor::GetTargetSize
114 Vector3 GetTargetSize() const;
116 ///@copydoc Actor::SetResizePolicy
117 void SetResizePolicy(ResizePolicy::Type policy, Dimension::Type dimension = Dimension::ALL_DIMENSIONS);
119 ///@copydoc Actor:::Type
120 ResizePolicy::Type GetResizePolicy(Dimension::Type dimension) const;
122 ///@copydoc Actor::SetSizeScalePolicy
123 void SetSizeScalePolicy(SizeScalePolicy::Type policy);
125 ///@copydoc Actor:::GetSizeScalePolicy
126 SizeScalePolicy::Type GetSizeScalePolicy() const;
128 ///@copydoc Actor::SetDimensionDependency
129 void SetDimensionDependency(Dimension::Type dimension, Dimension::Type dependency);
131 ///@copydoc Actor::GetDimensionDependency
132 Dimension::Type GetDimensionDependency(Dimension::Type dimension) const;
134 ///@copydoc Actor::SetRelayoutEnabled
135 void SetRelayoutEnabled(bool relayoutEnabled);
137 ///@copydoc Actor::IsRelayoutEnabled
138 bool IsRelayoutEnabled() const;
140 ///@copydoc Actor::SetLayoutDirty
141 void SetLayoutDirty(bool dirty, Dimension::Type dimension = Dimension::ALL_DIMENSIONS);
143 ///@copydoc Actor::IsLayoutDirty
144 bool IsLayoutDirty(Dimension::Type dimension = Dimension::ALL_DIMENSIONS) const;
146 ///@copydoc Actor::RelayoutPossible
147 bool RelayoutPossible(Dimension::Type dimension = Dimension::ALL_DIMENSIONS) const;
149 ///@copydoc Actor::RelayoutRequired
150 bool RelayoutRequired(Dimension::Type dimension = Dimension::ALL_DIMENSIONS) const;
152 ///@copydoc Actor::RelayoutDependentOnParent
153 bool RelayoutDependentOnParent(Dimension::Type dimension = Dimension::ALL_DIMENSIONS);
155 ///@copydoc Actor::RelayoutDependentOnChildren
156 bool RelayoutDependentOnChildrenBase(Dimension::Type dimension = Dimension::ALL_DIMENSIONS);
158 ///@copydoc Actor::RelayoutDependentOnDimension
159 bool RelayoutDependentOnDimension(Dimension::Type dimension, Dimension::Type dependentDimension);
161 ///@copydoc Actor::SetNegotiatedDimension
162 void SetNegotiatedDimension(float negotiatedDimension, Dimension::Type dimension = Dimension::ALL_DIMENSIONS);
164 ///@copydoc Actor::GetNegotiatedDimension
165 float GetNegotiatedDimension(Dimension::Type dimension) const;
167 ///@copydoc Actor::SetPadding
168 void SetPadding(const Vector2& padding, Dimension::Type dimension);
170 ///@copydoc Actor::GetPadding
171 Vector2 GetPadding(Dimension::Type dimension) const;
173 ///@copydoc Actor::SetLayoutNegotiated
174 void SetLayoutNegotiated(bool negotiated, Dimension::Type dimension);
176 ///@copydoc Actor::IsLayoutNegotiated
177 bool IsLayoutNegotiated(Dimension::Type dimension) const;
179 ///@copydoc Actor::GetHeightForWidth
180 float GetHeightForWidthBase(float width);
182 ///@copydoc Actor::GetWidthForHeight
183 float GetWidthForHeightBase(float height);
185 ///@copydoc Actor::CalculateChildSize
186 float CalculateChildSizeBase(const Dali::Actor& child, Dimension::Type dimension);
188 ///@copydoc Actor::GetLatestSize
189 float GetLatestSize(Dimension::Type dimension) const;
191 ///@copydoc Actor::GetRelayoutSize
192 float GetRelayoutSize(Dimension::Type dimension) const;
194 ///@copydoc Actor::GetSize
195 float GetSize(Dimension::Type dimension) const;
197 ///@copydoc Actor::GetNaturalSize
198 float GetNaturalSize(Dimension::Type dimension) const;
200 ///@copydoc Actor::ApplySizeSetPolicy
201 Vector2 ApplySizeSetPolicy(const Vector2& size);
203 ///@copydoc Actor::SetNegotiatedSize
204 void SetNegotiatedSize(RelayoutContainer& container);
206 ///@copydoc Actor::NegotiateSize
207 void NegotiateSize(const Vector2& allocatedSize, RelayoutContainer& container);
209 ///@copydoc Actor::RelayoutRequest
210 void RelayoutRequest(Dimension::Type dimension = Dimension::ALL_DIMENSIONS);
212 ///@copydoc Actor::SetMinimumSize
213 void SetMinimumSize(float size, Dimension::Type dimension = Dimension::ALL_DIMENSIONS);
215 ///@copydoc Actor::GetMinimumSize
216 float GetMinimumSize(Dimension::Type dimension) const;
218 ///@copydoc Actor::SetMaximumSize
219 void SetMaximumSize(float size, Dimension::Type dimension = Dimension::ALL_DIMENSIONS);
221 ///@copydoc Actor::GetMaximumSize
222 float GetMaximumSize(Dimension::Type dimension) const;
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
229 void OnAnimateSize(Animation& animation, Vector3 targetSize, bool relative);
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
236 void OnAnimateWidth(Animation& animation, float targetWidth, bool relative);
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
243 void OnAnimateHeight(Animation& animation, float targetHeight, bool relative);
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
250 void OnAnimateDepth(Animation& animation, float targetDepth, bool relative);
256 * @brief Ensure the relayouter is allocated
258 Relayouter& EnsureRelayouter();
261 * @brief Extract a given dimension from a Vector3
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
267 float GetDimensionValue(const Vector3& values, const Dimension::Type dimension) const;
270 * @brief Clamp a dimension given the relayout constraints on given actor
272 * @param[in] size The size to constrain
273 * @param[in] dimension The dimension the size exists in
274 * @return Return the clamped size
276 float ClampDimension(float size, Dimension::Type dimension) const;
279 * Negotiate a dimension based on the size of the parent
281 * @param[in] dimension The dimension to negotiate on
282 * @return Return the negotiated size
284 float NegotiateFromParent(Dimension::Type dimension);
287 * @brief Negotiate a dimension based on the size of the children
289 * @param[in] dimension The dimension to negotiate on
290 * @return Return the negotiated size
292 float NegotiateFromChildren(Dimension::Type dimension);
295 * Negotiate size for a specific dimension
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.
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.
304 * @param[in] dimension The dimension to negotiate on
305 * @param[in] allocatedSize The size constraint that the actor must respect
307 void NegotiateDimension(Dimension::Type dimension, const Vector2& allocatedSize, ActorDimensionStack& recursionStack);
310 * Negotiate sizes for a control in all dimensions
312 * @param[in] allocatedSize The size constraint that the control must respect
314 void NegotiateDimensions(const Vector2& allocatedSize);
317 * @brief Set whether size negotiation should use the assigned size of the actor
318 * during relayout for the given dimension(s)
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
323 void SetUseAssignedSize(bool use, Dimension::Type dimension = Dimension::ALL_DIMENSIONS);
326 * @brief Returns whether size negotiation should use the assigned size of the actor
327 * during relayout for a single dimension
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
332 bool GetUseAssignedSize(Dimension::Type dimension) const;
335 * @brief Calculate the size of a dimension
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
341 float CalculateSize(Dimension::Type dimension, const Vector2& maximumSize);
344 * @brief Set the preferred size for size negotiation
346 * @param[in] size The preferred size to set
348 void SetPreferredSize(const Vector2& size);
351 * @brief Get the preferred size for size negotiation
353 * @return size The preferred size to set
355 Vector2 GetPreferredSize() const;
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;
367 } // namespace Dali::Internal
369 #endif //DALI_INTERNAL_ACTOR_SIZER_H