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