Property enum name changes in dali-core: Toolkit changes for compiling
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / public-api / controls / scrollable / item-view / item-layout.cpp
1 /*
2  * Copyright (c) 2014 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 // CLASS HEADER
19 #include <dali-toolkit/public-api/controls/scrollable/item-view/item-layout.h>
20
21 // EXTERNAL INCLUDES
22 #include <dali/public-api/animation/active-constraint.h>
23 #include <dali/public-api/animation/constraint.h>
24 #include <dali/public-api/animation/time-period.h>
25
26 // INTERNAL INCLUDES
27 #include <dali-toolkit/public-api/controls/scrollable/item-view/item-view.h>
28
29 namespace
30 {
31
32   // Functors which wrap constraint functions with stored item IDs
33   struct WrappedQuaternionConstraint
34   {
35     WrappedQuaternionConstraint(Dali::Toolkit::ItemLayout::QuaternionFunction wrapMe, unsigned int itemId)
36     :mWrapMe(wrapMe),
37      mItemId(itemId)
38     {
39     }
40
41     Dali::Quaternion operator()(const Dali::Quaternion& current, const Dali::PropertyInput& layoutPosition, const Dali::PropertyInput& scrollSpeed, const Dali::PropertyInput& layoutSize)
42     {
43       float offsetLayoutPosition = layoutPosition.GetFloat() + static_cast<float>(mItemId);
44
45       return mWrapMe(current, offsetLayoutPosition, scrollSpeed.GetFloat(), layoutSize.GetVector3());
46     }
47
48     Dali::Toolkit::ItemLayout::QuaternionFunction mWrapMe;
49     unsigned int mItemId;
50   };
51
52   struct WrappedVector3Constraint
53   {
54     WrappedVector3Constraint(Dali::Toolkit::ItemLayout::Vector3Function wrapMe, unsigned int itemId)
55     : mWrapMe(wrapMe),
56       mItemId(itemId)
57     {
58     }
59
60     Dali::Vector3 operator()(const Dali::Vector3& current, const Dali::PropertyInput& layoutPosition, const Dali::PropertyInput& scrollSpeed, const Dali::PropertyInput& layoutSize)
61     {
62       float offsetLayoutPosition = layoutPosition.GetFloat() + static_cast<float>(mItemId);
63
64       return mWrapMe(current, offsetLayoutPosition, scrollSpeed.GetFloat(), layoutSize.GetVector3());
65     }
66
67     Dali::Toolkit::ItemLayout::Vector3Function mWrapMe;
68     unsigned int mItemId;
69   };
70
71   struct WrappedVector4Constraint
72   {
73     WrappedVector4Constraint(Dali::Toolkit::ItemLayout::Vector4Function wrapMe, unsigned int itemId)
74     : mWrapMe(wrapMe),
75       mItemId(itemId)
76     {
77     }
78
79     Dali::Vector4 operator()(const Dali::Vector4& current, const Dali::PropertyInput& layoutPosition, const Dali::PropertyInput& scrollSpeed, const Dali::PropertyInput& layoutSize)
80     {
81       float offsetLayoutPosition = layoutPosition.GetFloat() + static_cast<float>(mItemId);
82
83       return mWrapMe(current, offsetLayoutPosition, scrollSpeed.GetFloat(), layoutSize.GetVector3());
84     }
85
86     Dali::Toolkit::ItemLayout::Vector4Function mWrapMe;
87     unsigned int mItemId;
88   };
89
90   struct WrappedBoolConstraint
91   {
92     WrappedBoolConstraint(Dali::Toolkit::ItemLayout::BoolFunction wrapMe, unsigned int itemId)
93     : mWrapMe(wrapMe),
94       mItemId(itemId)
95     {
96     }
97
98     bool operator()(const bool& current, const Dali::PropertyInput& layoutPosition, const Dali::PropertyInput& scrollSpeed, const Dali::PropertyInput& layoutSize)
99     {
100       float offsetLayoutPosition = layoutPosition.GetFloat() + static_cast<float>(mItemId);
101
102       return mWrapMe(current, offsetLayoutPosition, scrollSpeed.GetFloat(), layoutSize.GetVector3());
103     }
104
105     Dali::Toolkit::ItemLayout::BoolFunction mWrapMe;
106     unsigned int mItemId;
107   };
108
109 }  //Unnamed namespace
110
111 namespace Dali
112 {
113
114 namespace Toolkit
115 {
116
117 ItemLayout::ItemLayout()
118 : mOrientation(ControlOrientation::Up),
119   mAlphaFunction(Dali::Constraint::DEFAULT_ALPHA_FUNCTION)
120 {
121 }
122
123 ItemLayout::~ItemLayout()
124 {
125 }
126
127 void ItemLayout::SetOrientation(ControlOrientation::Type orientation)
128 {
129   mOrientation = orientation;
130 }
131
132 ControlOrientation::Type ItemLayout::GetOrientation() const
133 {
134   return mOrientation;
135 }
136
137 float ItemLayout::GetClosestOnScreenLayoutPosition(int itemID, float currentLayoutPosition, const Vector3& layoutSize)
138 {
139   Vector3 itemPosition = GetItemPosition( itemID, currentLayoutPosition, layoutSize );
140   Vector3 itemSize;
141   GetItemSize(itemID, layoutSize, itemSize);
142   Vector3 onScreenArea = (layoutSize - itemSize) * 0.5f;
143   if (itemPosition.x < -onScreenArea.x
144       || itemPosition.x > onScreenArea.x
145       || itemPosition.y < -onScreenArea.y
146       || itemPosition.y > onScreenArea.y)
147   {
148     // item not within viewable area
149     // safest thing to do here since we have no idea how the implementation will work is to return the scroll to position
150     return GetItemScrollToPosition(itemID);
151   }
152   return currentLayoutPosition;
153 }
154
155 int ItemLayout::GetNextFocusItemID(int itemID, int maxItems, Dali::Toolkit::Control::KeyboardFocusNavigationDirection direction, bool loopEnabled)
156 {
157   switch( direction )
158   {
159     case Control::Left:
160     case Control::Up:
161     {
162       itemID--;
163       if( itemID < 0 )
164       {
165         itemID = loopEnabled ? maxItems - 1 : 0;
166       }
167       break;
168     }
169     case Control::Right:
170     case Control::Down:
171     {
172       itemID++;
173       if( itemID >= maxItems )
174       {
175         itemID = loopEnabled ? 0 : maxItems - 1;
176       }
177       break;
178     }
179   }
180   return itemID;
181 }
182
183 float ItemLayout::GetFlickSpeedFactor() const
184 {
185   // By default, the speed factor while dragging and swiping is the same.
186   return GetScrollSpeedFactor();
187 }
188
189 void ItemLayout::ApplyConstraints( Actor& actor, const int itemId, const float durationSeconds, Handle scrollPositionObject, const Actor& itemViewActor )
190 {
191   // This just implements the default behaviour of constraint application.
192   // Custom layouts can override this function to apply their custom constraints.
193   Dali::Toolkit::ItemView itemView = Dali::Toolkit::ItemView::DownCast( itemViewActor );
194   if(itemView && scrollPositionObject)
195   {
196     Property::Index scrollSpeedProperty = itemView.GetPropertyIndex("item-view-scroll-speed");
197     Property::Index scrollPositionProperty = scrollPositionObject.GetPropertyIndex("scroll-position");
198
199     ItemLayout::Vector3Function positionConstraint;
200     if (GetPositionConstraint(itemId, positionConstraint))
201     {
202       WrappedVector3Constraint wrapped(positionConstraint, itemId);
203       Constraint constraint = Constraint::New<Vector3>( Actor::Property::POSITION,
204                                                         Source( scrollPositionObject, scrollPositionProperty ),
205                                                         ParentSource( scrollSpeedProperty ),
206                                                         ParentSource( Actor::Property::SIZE ),
207                                                         wrapped );
208       constraint.SetApplyTime(durationSeconds);
209       constraint.SetAlphaFunction(mAlphaFunction);
210       actor.ApplyConstraint(constraint);
211     }
212
213     ItemLayout::QuaternionFunction rotationConstraint;
214     if (GetRotationConstraint(itemId, rotationConstraint))
215     {
216       WrappedQuaternionConstraint wrapped(rotationConstraint, itemId);
217
218       Constraint constraint = Constraint::New<Quaternion>( Actor::Property::ROTATION,
219                                                            Source( scrollPositionObject, scrollPositionProperty ),
220                                                            ParentSource( scrollSpeedProperty ),
221                                                            ParentSource( Actor::Property::SIZE ),
222                                                            wrapped );
223       constraint.SetApplyTime(durationSeconds);
224       constraint.SetAlphaFunction(mAlphaFunction);
225
226       actor.ApplyConstraint(constraint);
227     }
228
229     ItemLayout::Vector3Function scaleConstraint;
230     if (GetScaleConstraint(itemId, scaleConstraint))
231     {
232       WrappedVector3Constraint wrapped(scaleConstraint, itemId);
233
234       Constraint constraint = Constraint::New<Vector3>( Actor::Property::SCALE,
235                                                         Source( scrollPositionObject, scrollPositionProperty ),
236                                                         ParentSource( scrollSpeedProperty ),
237                                                         ParentSource( Actor::Property::SIZE ),
238                                                         wrapped );
239       constraint.SetApplyTime(durationSeconds);
240       constraint.SetAlphaFunction(mAlphaFunction);
241
242       actor.ApplyConstraint(constraint);
243     }
244
245     ItemLayout::Vector4Function colorConstraint;
246     if (GetColorConstraint(itemId, colorConstraint))
247     {
248       WrappedVector4Constraint wrapped(colorConstraint, itemId);
249
250       Constraint constraint = Constraint::New<Vector4>( Actor::Property::COLOR,
251                                                         Source( scrollPositionObject, scrollPositionProperty ),
252                                                         ParentSource( scrollSpeedProperty ),
253                                                         ParentSource( Actor::Property::SIZE ),
254                                                         wrapped );
255
256       constraint.SetApplyTime(durationSeconds);
257       constraint.SetAlphaFunction(mAlphaFunction);
258       constraint.SetRemoveAction(Dali::Constraint::Discard);
259
260       actor.ApplyConstraint(constraint);
261     }
262
263     ItemLayout::BoolFunction visibilityConstraint;
264     if (GetVisibilityConstraint(itemId, visibilityConstraint))
265     {
266       WrappedBoolConstraint wrapped(visibilityConstraint, itemId);
267
268       Constraint constraint = Constraint::New<bool>( Actor::Property::VISIBLE,
269                                                      Source( scrollPositionObject, scrollPositionProperty ),
270                                                      ParentSource( scrollSpeedProperty ),
271                                                      ParentSource( Actor::Property::SIZE ),
272                                                      wrapped );
273
274       constraint.SetApplyTime(durationSeconds);
275       constraint.SetAlphaFunction(mAlphaFunction);
276
277       // Release visibility constraints the same time as the color constraint
278       constraint.SetRemoveAction(Dali::Constraint::Discard);
279
280       actor.ApplyConstraint(constraint);
281     }
282   }
283 }
284
285 Vector3 ItemLayout::GetItemPosition(int itemID, float currentLayoutPosition, const Vector3& layoutSize) const
286 {
287   Vector3 itemPosition = Vector3::ZERO;
288
289   ItemLayout::Vector3Function positionConstraint;
290   if (GetPositionConstraint(itemID, positionConstraint))
291   {
292     itemPosition = positionConstraint(Vector3::ZERO, currentLayoutPosition + itemID, 0.0f, layoutSize);
293   }
294
295   return itemPosition;
296 }
297
298 void ItemLayout::SetAlphaFunction(AlphaFunction func)
299 {
300   mAlphaFunction = func;
301 }
302
303 AlphaFunction ItemLayout::GetAlphaFunction() const
304 {
305   return mAlphaFunction;
306 }
307
308
309 } // namespace Toolkit
310
311 } // namespace Dali