Merge "Add BuildPickingRay to devel api" into devel/master
[platform/core/uifw/dali-core.git] / dali / internal / event / size-negotiation / relayout-controller-impl.h
1 #ifndef DALI_INTERNAL_RELAYOUT_CONTROLLER_IMPL_H
2 #define DALI_INTERNAL_RELAYOUT_CONTROLLER_IMPL_H
3
4 /*
5  * Copyright (c) 2023 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 // EXTERNAL INCLUDES
22 #include <cstdint>
23 #include <memory> // for unique_ptr
24
25 // INTERNAL INCLUDES
26 #include <dali/internal/common/memory-pool-object-allocator.h>
27 #include <dali/internal/common/ordered-set.h>
28 #include <dali/internal/event/size-negotiation/memory-pool-relayout-container.h>
29 #include <dali/public-api/common/vector-wrapper.h>
30 #include <dali/public-api/object/base-object.h>
31 #include <dali/public-api/size-negotiation/relayout-container.h>
32
33 namespace Dali
34 {
35 namespace Integration
36 {
37 class RenderController;
38 }
39
40 namespace Internal
41 {
42 /**
43  * @brief The relayout controller is responsible for taking request from actors to relayout their sizes.
44  * The requests are actioned on at the end of the frame where all actors that have made a request are
45  * resized.
46  */
47 class RelayoutController : public Dali::BaseObject
48 {
49 public:
50   /**
51    * @brief Constructor.
52    * We should only create a unique instance.
53    * @param[in] controller to request a render from the RenderController if core is not processing events.
54    */
55   RelayoutController(Integration::RenderController& controller);
56
57   /**
58    * Destructor
59    */
60   ~RelayoutController() override;
61
62   /**
63    * @brief Get the singleton of RelayoutController object.
64    *
65    * @return A handle to the RelayoutController control.
66    */
67   static RelayoutController* Get();
68
69   /**
70    * @brief Request to relayout the given actor and all sub-actors of it.
71    *
72    * This flags the actor and all actors dependent on it for relayout. The actual
73    * relayout is performed at the end of the frame. This means that multiple calls to relayout
74    * will not cause multiple relayouts to occur.
75    *
76    * @param[in] actor The actor to request relayout on
77    * @param[in] dimension The dimension(s) to request the relayout on. Defaults to all dimensions
78    */
79   void RequestRelayout(Dali::Actor& actor, Dimension::Type dimension = Dimension::ALL_DIMENSIONS);
80
81   /**
82    * @brief Request to relayout of all actors in the sub-tree below the given actor.
83    *
84    * This flags the actor and all actors below it for relayout. The actual
85    * relayout is performed at the end of the frame. This means that multiple calls to relayout
86    * will not cause multiple relayouts to occur.
87    *
88    * @param[in] actor The actor to request relayout on
89    */
90   void RequestRelayoutTree(Dali::Actor& actor);
91
92   /**
93    * @brief Force propagate relayout flags through the tree. This is similiar to Request Relayout
94    * except all dependencies have their flags reset in spite of whether they are all ready set.
95    *
96    * This is useful for resetting layout flags during the layout process.
97    *
98    * @param[in] actor The actor to propagate from
99    * @param[in] dimension The dimension to propagate on
100    */
101   void PropagateFlags(Dali::Actor& actor, Dimension::Type dimension = Dimension::ALL_DIMENSIONS);
102
103   /**
104    * @brief Relayouts all actors that have been marked as dirty
105    */
106   void Relayout();
107
108   /**
109    * @brief Enable/disable the controller
110    *
111    * @param[in] enabled Flag to indicate whether the controller should be enabled or disabled
112    */
113   void SetEnabled(bool enabled);
114
115   /**
116    * @brief Return true if the relayout controller is currently performing a relayout
117    *
118    * @return Return true if the relayout controller is currently performing a relayout
119    */
120   bool IsPerformingRelayout() const;
121
122   /**
123    * @brief Sets whether core is processing events.
124    *
125    * @param[in] processingEvents whether core is processing events.
126    */
127   void SetProcessingCoreEvents(bool processingEvents);
128
129   /**
130    * Get the capacity of the memory pool containing relayout info
131    * (It Should be regularly purged!)
132    */
133   uint32_t GetMemoryPoolCapacity();
134
135 public: // CALLBACKS
136   /**
137    * @brief Callback raised after the application creates the scene
138    */
139   void OnApplicationSceneCreated();
140
141   /**
142    * @brief Callback for when an object is destroyed
143    *
144    * @param[in] object The object being destroyed
145    */
146   void OnObjectDestroyed(const Dali::RefObject* object);
147
148 private:
149   using RawActorList = Dali::Internal::OrderedSet<Dali::Internal::Actor, false>;
150
151   /**
152    * @brief Request for relayout. Relays out whole scene.
153    */
154   void Request();
155
156   /**
157    * @brief Add actor to request list
158    *
159    * @param[in] actor The root of the sub tree to add
160    */
161   void AddRequest(Dali::Actor& actor);
162
163   /**
164    * @brief Remove actor from request list
165    *
166    * @param[in] actor The root of the sub tree to remove
167    */
168   void RemoveRequest(Dali::Actor& actor);
169
170   /**
171    * @brief Disconnect the Relayout() method from the Stage::EventProcessingFinishedSignal().
172    */
173   void Disconnect();
174
175   /**
176    * @brief Propagate dirty layout flags to actor and all sub-actors. This will stop propagating when a dirty actor
177    * is found.
178    *
179    * @param[in] actor The actor to propagate on
180    * @param[in] dimension The dimension to propagate on
181    * @param[in] topOfSubTreeStack The top of the sub tree that this actor is in
182    * @param[in] potentialRedundantSubRoots Actors collected as potentially already being included in relayout
183    */
184   void PropagateAll(Dali::Actor& actor, Dimension::Type dimension, std::vector<Dali::Actor>& topOfSubTreeStack, std::vector<Dali::Actor>& potentialRedundantSubRoots);
185
186   /**
187    * Queue an actor on the relayout container
188    *
189    * @param[in] actor The actor to be queued
190    * @param[in] actors The container to add the actor to
191    * @param[in] size The size that this actor should be
192    */
193   void QueueActor(Internal::Actor* actor, RelayoutContainer& actors, Vector2 size);
194
195   // Undefined
196   RelayoutController(const RelayoutController&) = delete;
197   RelayoutController& operator=(const RelayoutController&) = delete;
198
199 private:
200   Integration::RenderController&                                       mRenderController;
201   MemoryPoolObjectAllocator<MemoryPoolRelayoutContainer::RelayoutInfo> mRelayoutInfoAllocator;
202
203   SlotDelegate<RelayoutController> mSlotDelegate;
204
205   RawActorList mDirtyLayoutSubTrees; ///< List of roots of sub trees that are dirty
206
207   std::unique_ptr<MemoryPoolRelayoutContainer> mRelayoutStack; ///< Stack for relayouting
208
209   std::vector<Dali::Actor> mPotentialRedundantSubRoots; ///< Stack of Actor when RequestLayout comes. Keep it as member to avoid vector size reserving.
210   std::vector<Dali::Actor> mTopOfSubTreeStack;
211
212   bool mRelayoutConnection : 1;   ///< Whether EventProcessingFinishedSignal signal is connected.
213   bool mRelayoutFlag : 1;         ///< Relayout flag to avoid unnecessary calls
214   bool mEnabled : 1;              ///< Initially disabled. Must be enabled at some point.
215   bool mPerformingRelayout : 1;   ///< The relayout controller is currently performing a relayout
216   bool mProcessingCoreEvents : 1; ///< Whether core is processing events.
217 };
218
219 } // namespace Internal
220
221 } // namespace Dali
222
223 #endif // DALI_INTERNAL_RELAYOUT_CONTROLLER_IMPL_H