Revert to tizen branch.
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / controls / scrollable / scroll-view / scroll-view-page-carousel-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 // CLASS HEADER
19 #include <dali-toolkit/internal/controls/scrollable/scroll-view/scroll-view-page-carousel-effect-impl.h>
20
21 // EXTERNAL INCLUDES
22 #include <dali/public-api/animation/constraint.h>
23 #include <dali/public-api/object/property-input.h>
24
25 // INTERNAL INCLUDES
26 #include <dali-toolkit/internal/controls/scrollable/scroll-view/scroll-view-helper-functions.h>
27
28 namespace Dali
29 {
30
31 namespace Toolkit
32 {
33
34 namespace Internal
35 {
36
37 namespace // unnamed namespace
38 {
39
40 const float PAGE_SIZE_MULTIPLIER( 1.15f );
41
42 using namespace ScrollViewHelperFunctions;
43
44 /**
45  * ScrollPageCarouselEffectInfo
46  *
47  * Color constraint: adjusts the alpha of the page based on their parent page's position relative
48  * to the middle of the screen.
49  * When at middle of screen Alpha is 100% opacity.
50  * When outside the viewable area, the opacity is 0%.
51  *
52  * Position constraint: adjusts the position of the page based on their parent page's position
53  * relative to the middle of the screen.
54  * When at middle of the screen the position is not altered.
55  * When one screen away from middle the position is rotated as per expected in a 3D carousel.
56  */
57 class ScrollPageCarouselEffectInfo
58 {
59 public:
60
61   ScrollPageCarouselEffectInfo( const Vector2& positionToPageSizeRatio )
62   : mPositionToPageSizeRatio( positionToPageSizeRatio )
63   {
64   }
65
66   /**
67    * @param[in,out] current The current color of this Actor
68    * @param[in] inputs Contains:
69    *                    The page's position.
70    *                    The scroll-view's position property (SCROLL_POSITION)
71    *                    The minimum extent of this scroll domain. (SCROLL_POSITION_MIN)
72    *                    The maximum extent of this scroll domain. (SCROLL_POSITION_MIN)
73    *                    The size of the page. (scrollView SIZE)
74    *                    Whether scroll wrap has been enabled or not (SCROLL_WRAP)
75    * @return The new color of this Actor.
76    */
77   void ColorConstraint( Vector4& current, const PropertyInputContainer& inputs )
78   {
79     const Vector3& pagePosition = inputs[0]->GetVector3();
80     const Vector3& scrollPosition = inputs[1]->GetVector3();
81
82     // Get position of page.
83     Vector3 position = pagePosition + scrollPosition;
84
85     // short circuit: if we're looking straight on at the page.
86     if( IsStraightOnView( position ) )
87     {
88       return;
89     }
90
91     const Vector3& pageSize = inputs[4]->GetVector3();
92
93     if( inputs[5]->GetBoolean() )
94     {
95       WrapPositionWithinDomain( position, pageSize, inputs[2]->GetVector3(), inputs[3]->GetVector3() );
96     }
97
98     // short circuit: for pages outside of view.
99     if( IsOutsideView( position, pageSize ) )
100     {
101       // note preserve color channels incase there is a shader/further constraint
102       // that wishes to do something with that information.
103       current.a = 0.0f;
104       return;
105     }
106
107     Vector2 distance( position / pageSize * PAGE_SIZE_MULTIPLIER );
108     current.a = Clamp( 1.0f - distance.Length(), 0.0f, 1.0f );
109   }
110
111   /**
112    * @param[in,out] current The current position
113    * @param[in] inputs Contains:
114    *                    The page's position.
115    *                    The scroll-view's position property (SCROLL_POSITION)
116    *                    The minimum extent of this scroll domain. (SCROLL_POSITION_MIN)
117    *                    The maximum extent of this scroll domain. (SCROLL_POSITION_MIN)
118    *                    The size of the page. (scrollView SIZE)
119    *                    Whether scroll wrap has been enabled or not (SCROLL_WRAP)
120    * @return The new position of this Actor.
121    */
122   void PositionConstraint( Vector3& current, const PropertyInputContainer& inputs )
123   {
124     const Vector3& pagePosition = inputs[0]->GetVector3();
125     const Vector3& scrollPosition = inputs[1]->GetVector3();
126
127     // Get position of page.
128     Vector3 position = pagePosition + scrollPosition;
129
130     // short circuit: if we're looking straight on at the page.
131     if( IsStraightOnView( position ) )
132     {
133       current += scrollPosition;
134       return;
135     }
136
137     const Vector3& pageSize = inputs[4]->GetVector3();
138
139     if( inputs[5]->GetBoolean() )
140     {
141       WrapPositionWithinDomain( position, pageSize, inputs[2]->GetVector3(), inputs[3]->GetVector3() );
142     }
143
144     // short circuit: for pages outside of view.
145     if( IsOutsideView( position, pageSize ) )
146     {
147       // position actors at: scrollposition (Property) + pagePosition (Parent) + current (this)
148       // they will be invisible so doesn't have to be precise, just away from stage.
149       current += scrollPosition;
150       return;
151     }
152
153     Vector3 angle( position / pageSize * PAGE_SIZE_MULTIPLIER );
154
155     position.x = pageSize.x * sinf( angle.x );
156     position.y = pageSize.y * sinf( angle.y );
157
158     Vector2 zMovement( pageSize );
159     zMovement *= mPositionToPageSizeRatio;
160     position.z = - ( ( zMovement.x - ( zMovement.x * cos( angle.x ) ) ) + ( zMovement.y - ( zMovement.y * cos( angle.y ) ) ) );
161
162     current = position;
163   }
164
165   const Vector2 mPositionToPageSizeRatio; ///< The page will move its position according to this ratio.
166 };
167
168 /**
169  * Helper: Applies the 3D scroll cube constraints to the child actor
170  *
171  * @param[in] scrollView The ScrollView containing the pages.
172  * @param[in] child The child to be affected with the 3D Effect.
173  * @param[in] info The effect info for the constraints
174  */
175 void ApplyScrollCubeConstraints(Toolkit::ScrollView scrollView,
176                                 Actor child,
177                                 ScrollPageCarouselEffectInfo& info)
178 {
179   // Apply constraints to this actor //
180   Constraint constraint;
181   constraint = Constraint::New<Vector4>( child, Actor::Property::COLOR, info, &ScrollPageCarouselEffectInfo::ColorConstraint );
182   constraint.AddSource( LocalSource(Actor::Property::POSITION) );
183   constraint.AddSource( Source(scrollView, Toolkit::ScrollView::Property::SCROLL_FINAL ) );
184   constraint.AddSource( Source(scrollView, Toolkit::Scrollable::Property::SCROLL_POSITION_MIN ) );
185   constraint.AddSource( Source(scrollView, Toolkit::Scrollable::Property::SCROLL_POSITION_MAX ) );
186   constraint.AddSource( Source(scrollView, Actor::Property::SIZE ) );
187   constraint.AddSource( Source(scrollView, Toolkit::ScrollView::Property::WRAP ) );
188   constraint.SetRemoveAction( Constraint::Discard );
189   constraint.Apply();
190
191   constraint = Constraint::New<Vector3>( child, Actor::Property::POSITION, info, &ScrollPageCarouselEffectInfo::PositionConstraint );
192   constraint.AddSource( LocalSource(Actor::Property::POSITION) );
193   constraint.AddSource( Source(scrollView, Toolkit::ScrollView::Property::SCROLL_FINAL ) );
194   constraint.AddSource( Source(scrollView, Toolkit::Scrollable::Property::SCROLL_POSITION_MIN ) );
195   constraint.AddSource( Source(scrollView, Toolkit::Scrollable::Property::SCROLL_POSITION_MAX ) );
196   constraint.AddSource( Source(scrollView, Actor::Property::SIZE ) );
197   constraint.AddSource( Source(scrollView, Toolkit::ScrollView::Property::WRAP ) );
198   constraint.SetRemoveAction( Constraint::Discard );
199   constraint.Apply();
200 }
201
202 } // unnamed namespace
203
204 ScrollViewPageCarouselEffect::ScrollViewPageCarouselEffect()
205 {
206
207 }
208
209 ScrollViewPageCarouselEffect::~ScrollViewPageCarouselEffect()
210 {
211 }
212
213 void ScrollViewPageCarouselEffect::ApplyToPage( Actor page, const Vector2& positionToPageSizeRatio )
214 {
215   ScrollPageCarouselEffectInfo info( positionToPageSizeRatio );
216
217   ApplyScrollCubeConstraints( GetScrollView(), page, info );
218 }
219
220 void ScrollViewPageCarouselEffect::OnAttach(Toolkit::ScrollView& scrollView)
221 {
222 }
223
224 void ScrollViewPageCarouselEffect::OnDetach(Toolkit::ScrollView& scrollView)
225 {
226 }
227
228 } // namespace Internal
229
230 } // namespace Toolkit
231
232 } // namespace Dali