Remove dead slide effect code and incorrect ref-objects from scroll effects
[platform/core/uifw/dali-toolkit.git] / base / dali-toolkit / internal / controls / scrollable / scroll-view / scroll-view-cube-effect-impl.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 // EXTERNAL INCLUDES
19 #include <boost/bind.hpp>
20
21 #include <dali-toolkit/internal/controls/scrollable/scroll-view/scroll-view-effect-impl.h>
22 #include <dali-toolkit/internal/controls/scrollable/scroll-view/scroll-view-cube-effect-impl.h>
23
24 using namespace Dali;
25
26 namespace // unnamed namespace
27 {
28
29 /**
30  * ScrollCubeEffectInfo
31  *
32  * Rotate constraint: adjusts the angle of the Actors
33  * based on their parent page's position relative to the middle of the screen.
34  * When at middle of screen Angles on X and Y Axes is 0.
35  * When one screen away from the middle Angle is 90 degrees (pi/2)
36  *
37  * Color constraint: adjusts the alpha of the Actors
38  * based on their parent page's position relative to the middle of the screen.
39  * When at middle of screen Alpha is 100% opacity.
40  * When one screen away from middle Alpha is at 0% opacity (invisble).
41  *
42  * Position constraint: adjusts the position of the Actors
43  * based on their parent page's position relative to the middle of the screen.
44  * When at middle of the screen the position is not altered.
45  * When one screen away from middle the position is rotated about it's origin + mAnchor
46  */
47 class ScrollCubeEffectInfo
48 {
49 public:
50
51   ScrollCubeEffectInfo(const Vector3& anchor,
52                        const Vector2& angleSwing,
53                        const Vector2& positionSwing)
54   : mAnchor(anchor),
55     mAngleSwing(angleSwing),
56     mPositionSwing(positionSwing)
57   {
58   }
59
60   /**
61    * @param[in] current The current orientation of this Actor
62    * @param[in] pagePositionProperty The page's position.
63    * @param[in] scrollPositionProperty The scroll-view's position property (SCROLL_POSITION_PROPERTY_NAME)
64    * @param[in] scrollPositionMin The minimum extent of this scroll domain. (SCROLL_POSITION_MIN_PROPERTY_NAME)
65    * @param[in] scrollPositionMax The maximum extent of this scroll domain. (SCROLL_POSITION_MIN_PROPERTY_NAME)
66    * @param[in] pageSizeProperty The size of the page. (scrollView SIZE)
67    * @param[in] scrollWrap Whether scroll wrap has been enabled or not (SCROLL_WRAP_PROPERTY_NAME)
68    * @return The new orientation of this Actor.
69    */
70   Quaternion RotationConstraint(const Quaternion& current,
71                                 const PropertyInput& pagePositionProperty,
72                                 const PropertyInput& scrollPositionProperty,
73                                 const PropertyInput& scrollPositionMin,
74                                 const PropertyInput& scrollPositionMax,
75                                 const PropertyInput& pageSizeProperty,
76                                 const PropertyInput& scrollWrap)
77   {
78     const Vector3& pagePosition = pagePositionProperty.GetVector3();
79     const Vector3& scrollPosition = scrollPositionProperty.GetVector3();
80
81     // Get position of page.
82     Vector3 position = pagePosition + scrollPosition;
83
84     // short circuit: for orthognal view.
85     if( (fabsf(position.x) < Math::MACHINE_EPSILON_1) && (fabsf(position.y) < Math::MACHINE_EPSILON_1) )
86     {
87       return current;
88     }
89
90     const Vector3& pageSize = pageSizeProperty.GetVector3();
91     bool wrap = scrollWrap.GetBoolean();
92
93     if(wrap)
94     {
95       const Vector3& min = scrollPositionMin.GetVector3();
96       const Vector3& max = scrollPositionMax.GetVector3();
97
98       if(fabsf(min.x - max.x) > Math::MACHINE_EPSILON_1)
99       {
100         // WRAP X (based on the position of the right side)
101         position.x = WrapInDomain(position.x + pageSize.x, min.x, max.x) - pageSize.x;
102       }
103
104       if(fabsf(min.y - max.y) > Math::MACHINE_EPSILON_1)
105       {
106         // WRAP Y (based on the position of the bottom side)
107         position.y = WrapInDomain(position.y + pageSize.y, min.y, max.y) - pageSize.y;
108       }
109     }
110
111     // short circuit: for pages outside of view.
112     if( (fabsf(position.x) >= pageSize.x) || (fabsf(position.y) >= pageSize.y) )
113     {
114       return current;
115     }
116
117     position.x /= pageSize.x;
118     position.y /= pageSize.y;
119
120     Vector2 angle( Clamp(position.x, -1.0f,1.0f),
121                    Clamp(position.y, -1.0f,1.0f) );
122
123     Quaternion rotation = Quaternion(angle.x * mAngleSwing.x, Vector3::YAXIS) *
124                           Quaternion(-angle.y * mAngleSwing.y, Vector3::XAXIS) *
125                           current;
126
127     return rotation;
128   }
129
130   /**
131    * @param[in] current The current color of this Actor
132    * @param[in] pagePositionProperty The page's position.
133    * @param[in] scrollPositionProperty The scroll-view's position property (SCROLL_POSITION_PROPERTY_NAME)
134    * @param[in] scrollPositionMin The minimum extent of this scroll domain. (SCROLL_POSITION_MIN_PROPERTY_NAME)
135    * @param[in] scrollPositionMax The maximum extent of this scroll domain. (SCROLL_POSITION_MIN_PROPERTY_NAME)
136    * @param[in] pageSizeProperty The size of the page. (scrollView SIZE)
137    * @param[in] scrollWrap Whether scroll wrap has been enabled or not (SCROLL_WRAP_PROPERTY_NAME)
138    * @return The new color of this Actor.
139    */
140   Vector4 ColorConstraint(const Vector4& current,
141                           const PropertyInput& pagePositionProperty,
142                           const PropertyInput& scrollPositionProperty,
143                           const PropertyInput& scrollPositionMin,
144                           const PropertyInput& scrollPositionMax,
145                           const PropertyInput& pageSizeProperty,
146                           const PropertyInput& scrollWrap)
147   {
148     const Vector3& pagePosition = pagePositionProperty.GetVector3();
149     const Vector3& scrollPosition = scrollPositionProperty.GetVector3();
150
151     // Get position of page.
152     Vector3 position = pagePosition + scrollPosition;
153
154     // short circuit: for orthognal view.
155     if( (fabsf(position.x) < Math::MACHINE_EPSILON_1) && (fabsf(position.y) < Math::MACHINE_EPSILON_1) )
156     {
157       return current;
158     }
159
160     const Vector3& pageSize = pageSizeProperty.GetVector3();
161     bool wrap = scrollWrap.GetBoolean();
162
163     if(wrap)
164     {
165       const Vector3& min = scrollPositionMin.GetVector3();
166       const Vector3& max = scrollPositionMax.GetVector3();
167
168       if(fabsf(min.x - max.x) > Math::MACHINE_EPSILON_1)
169       {
170         // WRAP X (based on the position of the right side)
171         position.x = WrapInDomain(position.x + pageSize.x, min.x, max.x) - pageSize.x;
172       }
173
174       if(fabsf(min.y - max.y) > Math::MACHINE_EPSILON_1)
175       {
176         // WRAP Y (based on the position of the bottom side)
177         position.y = WrapInDomain(position.y + pageSize.y, min.y, max.y) - pageSize.y;
178       }
179     }
180
181     // short circuit: for pages outside of view.
182     if( (fabsf(position.x) >= pageSize.x) || (fabsf(position.y) >= pageSize.y) )
183     {
184       // note preserve color channels incase there is a shader/further constraint
185       // that wishes to do something with that information.
186       return Vector4(current.r, current.g, current.b, 0.0f);
187     }
188
189     position.x /= pageSize.x;
190     position.y /= pageSize.y;
191
192     Vector2 angle( Clamp(position.x, -1.0f,1.0f),
193                    Clamp(position.y, -1.0f,1.0f) );
194
195     float f = (1.0f - fabsf(angle.x)) * (1.0f - fabsf(angle.y));
196     f = f*f;
197
198     Vector4 color = current;
199     color.a *= f;
200
201     return color;
202   }
203
204   /**
205    * @param[in] current The current position
206    * @param[in] pagePositionProperty The page's position.
207    * @param[in] scrollPositionProperty The scroll-view's position property (SCROLL_POSITION_PROPERTY_NAME)
208    * @param[in] scrollPositionMin The minimum extent of this scroll domain. (SCROLL_POSITION_MIN_PROPERTY_NAME)
209    * @param[in] scrollPositionMax The maximum extent of this scroll domain. (SCROLL_POSITION_MIN_PROPERTY_NAME)
210    * @param[in] pageSizeProperty The size of the page. (scrollView SIZE)
211    * @param[in] scrollWrap Whether scroll wrap has been enabled or not (SCROLL_WRAP_PROPERTY_NAME)
212    * @return The new position of this Actor.
213    */
214   Vector3 PositionConstraint(const Vector3& current,
215                              const PropertyInput& pagePositionProperty,
216                              const PropertyInput& scrollPositionProperty,
217                              const PropertyInput& scrollPositionMin,
218                              const PropertyInput& scrollPositionMax,
219                              const PropertyInput& pageSizeProperty,
220                              const PropertyInput& scrollWrap)
221   {
222     const Vector3& pagePosition = pagePositionProperty.GetVector3();
223     const Vector3& scrollPosition = scrollPositionProperty.GetVector3();
224
225     // Get position of page.
226     Vector3 relativePosition = pagePosition + scrollPosition;
227
228     // short circuit: for orthognal view.
229     if( (fabsf(relativePosition.x) < Math::MACHINE_EPSILON_1) && (fabsf(relativePosition.y) < Math::MACHINE_EPSILON_1) )
230     {
231       return current + scrollPosition;
232     }
233
234     const Vector3& pageSize = pageSizeProperty.GetVector3();
235     bool wrap = scrollWrap.GetBoolean();
236
237     if(wrap)
238     {
239       const Vector3& min = scrollPositionMin.GetVector3();
240       const Vector3& max = scrollPositionMax.GetVector3();
241
242       if(fabsf(min.x - max.x) > Math::MACHINE_EPSILON_1)
243       {
244         // WRAP X (based on the position of the right side)
245         relativePosition.x = WrapInDomain(relativePosition.x + pageSize.x, min.x, max.x) - pageSize.x;
246       }
247
248       if(fabsf(min.y - max.y) > Math::MACHINE_EPSILON_1)
249       {
250         // WRAP Y (based on the position of the bottom side)
251         relativePosition.y = WrapInDomain(relativePosition.y + pageSize.y, min.y, max.y) - pageSize.y;
252       }
253     }
254
255     // short circuit: for pages outside of view.
256     if( (fabsf(relativePosition.x) >= pageSize.x) || (fabsf(relativePosition.y) >= pageSize.y) )
257     {
258       // position actors at: scrollposition (Property) + pagePosition (Parent) + current (this)
259       // they will be invisible so doesn't have to be precise, just away from stage.
260       return current + scrollPosition;
261     }
262
263     relativePosition.x /= pageSize.x;
264     relativePosition.y /= pageSize.y;
265     relativePosition.z = 0.0f;
266
267     Vector3 angle( Clamp(relativePosition.x, -1.0f,1.0f) * mAngleSwing.x,
268                    Clamp(relativePosition.y, -1.0f,1.0f) * mAngleSwing.y,
269                    0.0f);
270
271     // Rotate position (current) about point.
272     Vector3 position = current - mAnchor;
273     Quaternion rotatorY(angle.x, Vector3::YAXIS);
274     position = rotatorY.Rotate(position);
275     Quaternion rotatorX(-angle.y, Vector3::XAXIS);
276     position = rotatorX.Rotate(position);
277     position += mAnchor;
278     position += relativePosition * mPositionSwing;
279
280     return position - pagePosition;
281   }
282
283   Vector3 mAnchor;                                        ///< Anchor point where Actor should rotate about.
284   Vector2 mAngleSwing;                                    ///< Maximum amount in X and Y axes to rotate.
285   Vector3 mPositionSwing;                                 ///< Maximum amount in X and Y axes to alter position.
286 };
287
288 /**
289  * Helper: Applies the 3D scroll cube constraints to the child actor
290  *
291  * @param[in] scrollView The ScrollView containing the pages.
292  * @param[in] child The child to be affected with the 3D Effect.
293  * @param[in] info The effect info for the constraints
294  */
295 void ApplyScrollCubeConstraints(Toolkit::ScrollView scrollView,
296                                 Actor child,
297                                 Actor parentPage,
298                                 const ScrollCubeEffectInfo& info)
299 {
300   // Apply constraints to this actor //
301   Constraint constraint;
302   constraint = Constraint::New<Quaternion>( Actor::ROTATION,
303                                          Source(parentPage, Actor::POSITION),
304                                          Source(scrollView, scrollView.GetPropertyIndex( Toolkit::ScrollView::SCROLL_FINAL_PROPERTY_NAME ) ),
305                                          Source(scrollView, scrollView.GetPropertyIndex( Toolkit::ScrollView::SCROLL_POSITION_MIN_PROPERTY_NAME ) ),
306                                          Source(scrollView, scrollView.GetPropertyIndex( Toolkit::ScrollView::SCROLL_POSITION_MAX_PROPERTY_NAME ) ),
307                                          Source(scrollView, Actor::SIZE ),
308                                          Source(scrollView, scrollView.GetPropertyIndex( Toolkit::ScrollView::SCROLL_WRAP_PROPERTY_NAME ) ),
309                                          boost::bind( &ScrollCubeEffectInfo::RotationConstraint, info, _1, _2, _3, _4, _5, _6, _7) );
310
311   constraint.SetRemoveAction( Constraint::Discard );
312   child.ApplyConstraint( constraint );
313
314   constraint = Constraint::New<Vector4>( Actor::COLOR,
315                                          Source(parentPage, Actor::POSITION),
316                                          Source(scrollView, scrollView.GetPropertyIndex( Toolkit::ScrollView::SCROLL_FINAL_PROPERTY_NAME ) ),
317                                          Source(scrollView, scrollView.GetPropertyIndex( Toolkit::ScrollView::SCROLL_POSITION_MIN_PROPERTY_NAME ) ),
318                                          Source(scrollView, scrollView.GetPropertyIndex( Toolkit::ScrollView::SCROLL_POSITION_MAX_PROPERTY_NAME ) ),
319                                          Source(scrollView, Actor::SIZE ),
320                                          Source(scrollView, scrollView.GetPropertyIndex( Toolkit::ScrollView::SCROLL_WRAP_PROPERTY_NAME ) ),
321                                          boost::bind( &ScrollCubeEffectInfo::ColorConstraint, info, _1, _2, _3, _4, _5, _6, _7) );
322
323   constraint.SetRemoveAction( Constraint::Discard );
324   child.ApplyConstraint( constraint );
325
326   constraint = Constraint::New<Vector3>( Actor::POSITION,
327                                          Source(parentPage, Actor::POSITION),
328                                          Source(scrollView, scrollView.GetPropertyIndex( Toolkit::ScrollView::SCROLL_FINAL_PROPERTY_NAME ) ),
329                                          Source(scrollView, scrollView.GetPropertyIndex( Toolkit::ScrollView::SCROLL_POSITION_MIN_PROPERTY_NAME ) ),
330                                          Source(scrollView, scrollView.GetPropertyIndex( Toolkit::ScrollView::SCROLL_POSITION_MAX_PROPERTY_NAME ) ),
331                                          Source(scrollView, Actor::SIZE ),
332                                          Source(scrollView, scrollView.GetPropertyIndex( Toolkit::ScrollView::SCROLL_WRAP_PROPERTY_NAME ) ),
333                                          boost::bind( &ScrollCubeEffectInfo::PositionConstraint, info, _1, _2, _3, _4, _5, _6, _7) );
334
335   constraint.SetRemoveAction( Constraint::Discard );
336   child.ApplyConstraint( constraint );
337 }
338
339 } // unnamed namespace
340
341 namespace Dali
342 {
343
344 namespace Toolkit
345 {
346
347 namespace Internal
348 {
349
350 ScrollViewCubeEffect::ScrollViewCubeEffect()
351 {
352
353 }
354
355 ScrollViewCubeEffect::~ScrollViewCubeEffect()
356 {
357 }
358
359 void ScrollViewCubeEffect::ApplyToActor(Actor child,
360                                         const Vector3& anchor,
361                                         const Vector2& angleSwing,
362                                         const Vector2& positionSwing)
363 {
364   ScrollCubeEffectInfo info( anchor, angleSwing, positionSwing );
365
366   ApplyScrollCubeConstraints( GetScrollView(), child, child.GetParent(), info );
367 }
368
369 void ScrollViewCubeEffect::ApplyToActor(Actor child,
370                                         Actor parentPage,
371                                         const Vector3& anchor,
372                                         const Vector2& angleSwing,
373                                         const Vector2& positionSwing)
374 {
375   ScrollCubeEffectInfo info( anchor, angleSwing, positionSwing );
376
377   ApplyScrollCubeConstraints( GetScrollView(), child, parentPage, info );
378 }
379
380 void ScrollViewCubeEffect::OnAttach(Toolkit::ScrollView& scrollView)
381 {
382 }
383
384 void ScrollViewCubeEffect::OnDetach(Toolkit::ScrollView& scrollView)
385 {
386 }
387
388 } // namespace Internal
389
390 } // namespace Toolkit
391
392 } // namespace Dali