2 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include <dali-toolkit/internal/controls/scrollable/scroll-view/scroll-view-page-carousel-effect-impl.h>
22 #include <boost/bind.hpp>
23 #include <dali/public-api/animation/active-constraint.h>
24 #include <dali/public-api/animation/constraint.h>
25 #include <dali/public-api/object/property-input.h>
28 #include <dali-toolkit/internal/controls/scrollable/scroll-view/scroll-view-helper-functions.h>
39 namespace // unnamed namespace
42 const float PAGE_SIZE_MULTIPLIER( 1.15f );
44 using namespace ScrollViewHelperFunctions;
47 * ScrollPageCarouselEffectInfo
49 * Color constraint: adjusts the alpha of the page based on their parent page's position relative
50 * to the middle of the screen.
51 * When at middle of screen Alpha is 100% opacity.
52 * When outside the viewable area, the opacity is 0%.
54 * Position constraint: adjusts the position of the page based on their parent page's position
55 * relative to the middle of the screen.
56 * When at middle of the screen the position is not altered.
57 * When one screen away from middle the position is rotated as per expected in a 3D carousel.
59 class ScrollPageCarouselEffectInfo
63 ScrollPageCarouselEffectInfo( const Vector2& positionToPageSizeRatio )
64 : mPositionToPageSizeRatio( positionToPageSizeRatio )
69 * @param[in] current The current color of this Actor
70 * @param[in] pagePositionProperty The page's position.
71 * @param[in] scrollPositionProperty The scroll-view's position property (SCROLL_POSITION_PROPERTY_NAME)
72 * @param[in] scrollPositionMin The minimum extent of this scroll domain. (SCROLL_POSITION_MIN_PROPERTY_NAME)
73 * @param[in] scrollPositionMax The maximum extent of this scroll domain. (SCROLL_POSITION_MIN_PROPERTY_NAME)
74 * @param[in] pageSizeProperty The size of the page. (scrollView SIZE)
75 * @param[in] scrollWrap Whether scroll wrap has been enabled or not (SCROLL_WRAP_PROPERTY_NAME)
76 * @return The new color of this Actor.
78 Vector4 ColorConstraint(const Vector4& current,
79 const PropertyInput& pagePositionProperty,
80 const PropertyInput& scrollPositionProperty,
81 const PropertyInput& scrollPositionMin,
82 const PropertyInput& scrollPositionMax,
83 const PropertyInput& pageSizeProperty,
84 const PropertyInput& scrollWrap)
86 const Vector3& pagePosition = pagePositionProperty.GetVector3();
87 const Vector3& scrollPosition = scrollPositionProperty.GetVector3();
89 // Get position of page.
90 Vector3 position = pagePosition + scrollPosition;
92 // short circuit: if we're looking straight on at the page.
93 if( IsStraightOnView( position ) )
98 const Vector3& pageSize = pageSizeProperty.GetVector3();
100 if( scrollWrap.GetBoolean() )
102 WrapPositionWithinDomain( position, pageSize, scrollPositionMin.GetVector3(), scrollPositionMax.GetVector3() );
105 // short circuit: for pages outside of view.
106 if( IsOutsideView( position, pageSize ) )
108 // note preserve color channels incase there is a shader/further constraint
109 // that wishes to do something with that information.
110 return Vector4(current.r, current.g, current.b, 0.0f);
113 Vector4 color( current );
114 Vector2 distance( position / pageSize * PAGE_SIZE_MULTIPLIER );
115 color.a = Clamp( 1.0f - distance.Length(), 0.0f, 1.0f );
121 * @param[in] current The current position
122 * @param[in] pagePositionProperty The page's position.
123 * @param[in] scrollPositionProperty The scroll-view's position property (SCROLL_POSITION_PROPERTY_NAME)
124 * @param[in] scrollPositionMin The minimum extent of this scroll domain. (SCROLL_POSITION_MIN_PROPERTY_NAME)
125 * @param[in] scrollPositionMax The maximum extent of this scroll domain. (SCROLL_POSITION_MIN_PROPERTY_NAME)
126 * @param[in] pageSizeProperty The size of the page. (scrollView SIZE)
127 * @param[in] scrollWrap Whether scroll wrap has been enabled or not (SCROLL_WRAP_PROPERTY_NAME)
128 * @return The new position of this Actor.
130 Vector3 PositionConstraint(const Vector3& current,
131 const PropertyInput& pagePositionProperty,
132 const PropertyInput& scrollPositionProperty,
133 const PropertyInput& scrollPositionMin,
134 const PropertyInput& scrollPositionMax,
135 const PropertyInput& pageSizeProperty,
136 const PropertyInput& scrollWrap)
138 const Vector3& pagePosition = pagePositionProperty.GetVector3();
139 const Vector3& scrollPosition = scrollPositionProperty.GetVector3();
141 // Get position of page.
142 Vector3 position = pagePosition + scrollPosition;
144 // short circuit: if we're looking straight on at the page.
145 if( IsStraightOnView( position ) )
147 return current + scrollPosition;
150 const Vector3& pageSize = pageSizeProperty.GetVector3();
152 if( scrollWrap.GetBoolean() )
154 WrapPositionWithinDomain( position, pageSize, scrollPositionMin.GetVector3(), scrollPositionMax.GetVector3() );
157 // short circuit: for pages outside of view.
158 if( IsOutsideView( position, pageSize ) )
160 // position actors at: scrollposition (Property) + pagePosition (Parent) + current (this)
161 // they will be invisible so doesn't have to be precise, just away from stage.
162 return current + scrollPosition;
165 Vector3 angle( position / pageSize * PAGE_SIZE_MULTIPLIER );
167 position.x = pageSize.x * sinf( angle.x );
168 position.y = pageSize.y * sinf( angle.y );
170 Vector2 zMovement( pageSize );
171 zMovement *= mPositionToPageSizeRatio;
172 position.z = - ( ( zMovement.x - ( zMovement.x * cos( angle.x ) ) ) + ( zMovement.y - ( zMovement.y * cos( angle.y ) ) ) );
177 const Vector2 mPositionToPageSizeRatio; ///< The page will move its position according to this ratio.
181 * Helper: Applies the 3D scroll cube constraints to the child actor
183 * @param[in] scrollView The ScrollView containing the pages.
184 * @param[in] child The child to be affected with the 3D Effect.
185 * @param[in] info The effect info for the constraints
187 void ApplyScrollCubeConstraints(Toolkit::ScrollView scrollView,
189 ScrollPageCarouselEffectInfo& info)
191 // Apply constraints to this actor //
192 Constraint constraint;
193 constraint = Constraint::New<Vector4>( Actor::Property::Color,
194 LocalSource(Actor::Property::Position),
195 Source(scrollView, scrollView.GetPropertyIndex( Toolkit::ScrollView::SCROLL_FINAL_PROPERTY_NAME ) ),
196 Source(scrollView, scrollView.GetPropertyIndex( Toolkit::ScrollView::SCROLL_POSITION_MIN_PROPERTY_NAME ) ),
197 Source(scrollView, scrollView.GetPropertyIndex( Toolkit::ScrollView::SCROLL_POSITION_MAX_PROPERTY_NAME ) ),
198 Source(scrollView, Actor::Property::Size ),
199 Source(scrollView, scrollView.GetPropertyIndex( Toolkit::ScrollView::SCROLL_WRAP_PROPERTY_NAME ) ),
200 boost::bind( &ScrollPageCarouselEffectInfo::ColorConstraint, info, _1, _2, _3, _4, _5, _6, _7) );
202 constraint.SetRemoveAction( Constraint::Discard );
203 child.ApplyConstraint( constraint );
205 constraint = Constraint::New<Vector3>( Actor::Property::Position,
206 LocalSource(Actor::Property::Position),
207 Source(scrollView, scrollView.GetPropertyIndex( Toolkit::ScrollView::SCROLL_FINAL_PROPERTY_NAME ) ),
208 Source(scrollView, scrollView.GetPropertyIndex( Toolkit::ScrollView::SCROLL_POSITION_MIN_PROPERTY_NAME ) ),
209 Source(scrollView, scrollView.GetPropertyIndex( Toolkit::ScrollView::SCROLL_POSITION_MAX_PROPERTY_NAME ) ),
210 Source(scrollView, Actor::Property::Size ),
211 Source(scrollView, scrollView.GetPropertyIndex( Toolkit::ScrollView::SCROLL_WRAP_PROPERTY_NAME ) ),
212 boost::bind( &ScrollPageCarouselEffectInfo::PositionConstraint, info, _1, _2, _3, _4, _5, _6, _7) );
214 constraint.SetRemoveAction( Constraint::Discard );
215 child.ApplyConstraint( constraint );
218 } // unnamed namespace
220 ScrollViewPageCarouselEffect::ScrollViewPageCarouselEffect()
225 ScrollViewPageCarouselEffect::~ScrollViewPageCarouselEffect()
229 void ScrollViewPageCarouselEffect::ApplyToPage( Actor page, const Vector2& positionToPageSizeRatio )
231 ScrollPageCarouselEffectInfo info( positionToPageSizeRatio );
233 ApplyScrollCubeConstraints( GetScrollView(), page, info );
236 void ScrollViewPageCarouselEffect::OnAttach(Toolkit::ScrollView& scrollView)
240 void ScrollViewPageCarouselEffect::OnDetach(Toolkit::ScrollView& scrollView)
244 } // namespace Internal
246 } // namespace Toolkit