348f2d9aa67be5c77b183113df57ac15a38b3bdb
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / layouting / layout-transition-data-impl.h
1 #ifndef DALI_TOOLKIT_INTERNAL_LAYOUTING_LAYOUT_TRANSITION_DATA_IMPL_H
2 #define DALI_TOOLKIT_INTERNAL_LAYOUTING_LAYOUT_TRANSITION_DATA_IMPL_H
3 /*
4  * Copyright (c) 2018 Samsung Electronics Co., Ltd.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18
19 #include <memory>
20
21 #include <dali/public-api/common/intrusive-ptr.h>
22 #include <dali/public-api/object/base-object.h>
23 #include <dali/public-api/object/property-map.h>
24 #include <dali/public-api/object/type-registry.h>
25 #include <dali/public-api/actors/actor-enumerations.h>
26 #include <dali/public-api/animation/animation.h>
27
28 #include <dali-toolkit/devel-api/layouting/layout-item-impl.h>
29 #include <dali-toolkit/devel-api/layouting/layout-transition-data.h>
30
31 namespace Dali
32 {
33 namespace Toolkit
34 {
35 namespace Internal
36 {
37
38 struct LayoutTransition
39 {
40   LayoutTransition( LayoutItem& layoutItem, int layoutTransitionType, Actor gainedChild, Actor lostChild )
41   : layoutItem( &layoutItem )
42   , layoutTransitionType( layoutTransitionType )
43   , gainedChild( gainedChild )
44   , lostChild( lostChild )
45   {
46   }
47
48   LayoutTransition()
49   : layoutTransitionType( -1 )
50   {
51   }
52
53   bool operator==( const LayoutTransition& rhs )
54   {
55     return ( layoutItem.Get() == rhs.layoutItem.Get()
56         && layoutTransitionType == rhs.layoutTransitionType
57         && gainedChild == rhs.gainedChild
58         && lostChild == rhs.lostChild );
59   }
60
61   LayoutItemPtr layoutItem;
62   int layoutTransitionType;
63   Actor gainedChild;
64   Actor lostChild;
65 };
66
67 const float DEFAULT_TRANSITION_DURATION( 0.5f );
68
69 struct LayoutDataAnimator
70 {
71    LayoutDataAnimator()
72    : animatorType( Toolkit::LayoutTransitionData::Animator::ANIMATE_TO ),
73      alphaFunction( AlphaFunction::LINEAR ),
74      timePeriod( 0.0f, DEFAULT_TRANSITION_DURATION ),
75      interpolation( Animation::Linear )
76    {
77    }
78
79    std::string name;
80    Toolkit::LayoutTransitionData::Animator::Type animatorType;
81    AlphaFunction alphaFunction;
82    TimePeriod timePeriod;
83
84    KeyFrames keyFrames;
85    Animation::Interpolation interpolation;
86
87    Path path;
88    Vector3 forward;
89 };
90
91 using LayoutAnimatorArray = std::vector< LayoutDataAnimator >;
92
93 struct LayoutPositionData
94 {
95   LayoutPositionData( Handle handle, float left, float top, float right, float bottom, bool animated ) :
96       handle( handle ), left( left ), top( top ), right( right ), bottom( bottom ), animated( animated ), updateWithCurrentSize(false)
97   {
98   };
99
100   BaseHandle handle;
101   float left;
102   float top;
103   float right;
104   float bottom;
105   bool animated;
106   bool updateWithCurrentSize;
107 };
108
109 using LayoutPositionDataArray = std::vector< LayoutPositionData >;
110
111 struct LayoutDataElement
112 {
113   LayoutDataElement()
114   : propertyIndex( Property::INVALID_KEY ),
115     animatorIndex( -1 ),
116     positionDataIndex(-1 ),
117     condition( Dali::Toolkit::LayoutTransitionData::Condition::NONE ),
118     updateMeasuredSize( false )
119   {
120   };
121
122   bool AdjustMeasuredSize( float& width, float& height, Toolkit::LayoutTransitionData::Animator::Type animatorType );
123   void UpdatePropertyIndex();
124   void UpdateAnimatorIndex( const LayoutAnimatorArray& animators );
125   void UpdatePositionDataIndex( LayoutData& layoutData );
126
127   BaseHandle handle;
128   std::string propertyName;
129   Property::Index propertyIndex;
130   Property::Value initialValue;
131   Property::Value targetValue;
132   std::string animatorName;
133   int animatorIndex;
134   int positionDataIndex;
135   int condition;
136   bool updateMeasuredSize;
137 };
138
139 using LayoutDataArray = std::vector< LayoutDataElement >;
140
141 class LayoutTransitionData;
142 using LayoutTransitionDataPtr = IntrusivePtr<LayoutTransitionData>;
143
144 /**
145  * LayoutTransitionData implementation class.
146  */
147 class DALI_TOOLKIT_API LayoutTransitionData : public BaseObject
148 {
149 public:
150   struct PropertyAnimator
151   {
152     PropertyAnimator();
153     PropertyAnimator( Actor actor, Property::Map map );
154     PropertyAnimator( Actor actor, Property::Map map, Path path, Vector3 forward );
155     PropertyAnimator( Actor actor, Property::Map map, KeyFrames keyFrames, Animation::Interpolation interpolation );
156
157     BaseHandle handle;
158
159     Property::Map map;
160
161     KeyFrames keyFrames;
162     Animation::Interpolation interpolation;
163
164     Path path;
165     Vector3 forward;
166   };
167   using PropertyAnimatorArray = std::vector< PropertyAnimator >;
168
169   static LayoutTransitionDataPtr New();
170
171   LayoutTransitionData( const LayoutTransitionData& ) = delete;
172   LayoutTransitionData& operator=( const LayoutTransitionData& ) = delete;
173
174   /**
175    * @brief Add a property animator for an actor in the transition
176    * @param[in] actor The actor
177    * @param[in] map The map containing the transition animator keys
178    *
179    * This will parse the property animator map and add the layout data element to the array of layout data elements related to this transition
180    */
181   void AddPropertyAnimator( Actor actor, Property::Map map );
182
183   /**
184    * @brief Add a property animator for an actor in the transition
185    * @param[in] actor The actor
186    * @param[in] map The map containing the transition animator keys
187    * @param[in] keyFrames The key frames used by the property animator
188    * @param[in] interpolation The interpolation used by the property animator
189    *
190    * This will parse the property animator map and add the layout data element to the array of layout data elements related to this transition
191    */
192   void AddPropertyAnimator( Actor actor, Property::Map map, KeyFrames keyFrames, Animation::Interpolation interpolation );
193
194   /**
195    * @brief Add a property animator for an actor in the transition
196    * @param[in] actor The actor
197    * @param[in] map The map containing the transition animator keys
198    * @param[in] path The path for the property animator
199    * @param[in] forward The forward vector for the property animator
200    *
201    * This will parse the property animator map and add the layout data element to the array of layout data elements related to this transition
202    */
203   void AddPropertyAnimator( Actor actor, Property::Map map, Path path, Vector3 forward );
204
205   /**
206    * @brief Collect the transition layout data elements
207    * @param[in] actor The actor the transition property animators are applied to
208    * @param[in] layoutData The layout data containing layout data elements array for the layout update
209    *
210    * This will copy the transition layout data elements to the layout data elements array
211    */
212   void CollectLayoutDataElements( Actor, LayoutData& layoutData );
213
214   /**
215    * @brief Collect the transition children layout data elements
216    * @param[in] actor The actor the transition property animators are applied to
217    * @param[in] layoutData The layout data containing layout data elements array for the layout update
218    *
219    * This will copy the children transition layout data elements to the layout data elements array
220    */
221   static void CollectChildrenLayoutDataElements( Actor, LayoutData& layoutData );
222
223   /**
224    * @copydoc Dali::Toolkit::LayoutTransitionData::FinishedSignal()
225    */
226   Dali::Toolkit::LayoutTransitionData::LayoutTransitionSignalType& FinishedSignal();
227
228   /**
229    * @brief Emit the transition finish signal
230    * @param[in] layoutTransitionType The transition type
231    */
232   void EmitSignalFinish( int layoutTransitionType );
233
234   /**
235    * @brief Check if one of the layout data elements has updateMeasuredSize flag set
236    */
237   bool HasUpdateMeasuredSize();
238
239 private:
240   /**
241    * @brief Convert the property animator data to the layout data animator
242    * @param[in] animatorData The animator data map
243    * @param[in] propertyAnimator The property animator
244    * @param[in] layoutAnimator The layout animator
245    *
246    * This will parse the property animator map and add the layout data element animator to the layout animators array
247    */
248   bool ConvertToLayoutAnimator( const Property::Map& animatorData, const PropertyAnimator& propertyAnimator, LayoutDataAnimator& layoutAnimator );
249
250   /**
251    * @brief Convert the property animator to the layout data element
252    * @param[in] propertyAnimator The property animator
253    * @param[in] layoutDataElement The layout data element
254    * @param[in] layoutDataElement The layout data
255    *
256    * This will parse the property animator map and add the layout data element to the layout data elements array
257    */
258   bool ConvertToLayoutDataElement( const PropertyAnimator& propertyAnimator, LayoutDataElement& layoutDataElement );
259
260   void UpdateAnimatorsIndices();
261
262   bool mUpdateMeasuredSize;
263   LayoutAnimatorArray mLayoutAnimators;
264   LayoutDataArray mLayoutDataElements;
265
266   /**
267    * Ref counted object - Only allow construction via New().
268    */
269   LayoutTransitionData();
270
271 protected:
272   /**
273    *  A ref counted object may only be deleted by calling Unreference
274    */
275   virtual ~LayoutTransitionData();
276
277   Dali::Toolkit::LayoutTransitionData::LayoutTransitionSignalType mFinishedSignal;
278 };
279
280 using PropertyAnimatorArray = std::vector< LayoutTransitionData::PropertyAnimator >;
281 using LayoutTransitionDataArray = std::vector< LayoutTransitionDataPtr >;
282 using LayoutDataArray = std::vector< LayoutDataElement >;
283
284 struct LayoutData
285 {
286   LayoutData( LayoutTransition& layoutTransition, LayoutPositionDataArray& layoutPositionDataArray, LayoutAnimatorArray& layoutAnimatorArray,
287       LayoutDataArray& layoutDataArray, LayoutDataArray& childrenLayoutDataArray )
288   : speculativeLayout( false ),
289     updateMeasuredSize( false ),
290     layoutTransition( layoutTransition ),
291     layoutPositionDataArray( layoutPositionDataArray ),
292     layoutAnimatorArray( layoutAnimatorArray ),
293     layoutDataArray( layoutDataArray),
294     childrenLayoutDataArray( childrenLayoutDataArray )
295   {
296   };
297
298   bool speculativeLayout;
299   bool updateMeasuredSize;
300   LayoutTransition& layoutTransition;
301   LayoutPositionDataArray& layoutPositionDataArray;
302   LayoutAnimatorArray& layoutAnimatorArray;
303   LayoutDataArray& layoutDataArray;
304   LayoutDataArray& childrenLayoutDataArray;
305 };
306
307 } //namespace Internal
308
309 inline Internal::LayoutTransitionData& GetImplementation( Dali::Toolkit::LayoutTransitionData& handle )
310 {
311   DALI_ASSERT_ALWAYS( handle && "LayoutTransitionData handle is empty" );
312   BaseObject& object = handle.GetBaseObject();
313   return static_cast< Internal::LayoutTransitionData& >( object );
314 }
315
316 inline const Internal::LayoutTransitionData& GetImplementation( const Dali::Toolkit::LayoutTransitionData& handle )
317 {
318   DALI_ASSERT_ALWAYS( handle && "LayoutTransitionData handle is empty" );
319   const BaseObject& object = handle.GetBaseObject();
320   return static_cast< const Internal::LayoutTransitionData& >( object );
321 }
322
323 } //namespace Toolkit
324 } //namespace Dali
325
326 #endif // DALI_TOOLKIT_INTERNAL_LAYOUTING_LAYOUT_TRANSITION_DATA_IMPL_H