2 // Copyright (c) 2014 Samsung Electronics Co., Ltd.
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
8 // http://floralicense.org/license/
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.
18 #include <dali-toolkit/internal/controls/scrollable/scroll-view/scroll-view-page-carousel-effect-impl.h>
21 #include <boost/bind.hpp>
24 #include <dali-toolkit/internal/controls/scrollable/scroll-view/scroll-view-helper-functions.h>
35 namespace // unnamed namespace
38 const float PAGE_SIZE_MULTIPLIER( 1.15f );
40 using namespace ScrollViewHelperFunctions;
43 * ScrollPageCarouselEffectInfo
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%.
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.
55 class ScrollPageCarouselEffectInfo : public Dali::RefObject
59 ScrollPageCarouselEffectInfo( const Vector2& positionToPageSizeRatio )
60 : mPositionToPageSizeRatio( positionToPageSizeRatio )
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.
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)
82 const Vector3& pagePosition = pagePositionProperty.GetVector3();
83 const Vector3& scrollPosition = scrollPositionProperty.GetVector3();
85 // Get position of page.
86 Vector3 position = pagePosition + scrollPosition;
88 // short circuit: if we're looking straight on at the page.
89 if( IsStraightOnView( position ) )
94 const Vector3& pageSize = pageSizeProperty.GetVector3();
96 if( scrollWrap.GetBoolean() )
98 WrapPositionWithinDomain( position, pageSize, scrollPositionMin.GetVector3(), scrollPositionMax.GetVector3() );
101 // short circuit: for pages outside of view.
102 if( IsOutsideView( position, pageSize ) )
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);
109 Vector4 color( current );
110 Vector2 distance( position / pageSize * PAGE_SIZE_MULTIPLIER );
111 color.a = Clamp( 1.0f - distance.Length(), 0.0f, 1.0f );
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.
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)
134 const Vector3& pagePosition = pagePositionProperty.GetVector3();
135 const Vector3& scrollPosition = scrollPositionProperty.GetVector3();
137 // Get position of page.
138 Vector3 position = pagePosition + scrollPosition;
140 // short circuit: if we're looking straight on at the page.
141 if( IsStraightOnView( position ) )
143 return current + scrollPosition;
146 const Vector3& pageSize = pageSizeProperty.GetVector3();
148 if( scrollWrap.GetBoolean() )
150 WrapPositionWithinDomain( position, pageSize, scrollPositionMin.GetVector3(), scrollPositionMax.GetVector3() );
153 // short circuit: for pages outside of view.
154 if( IsOutsideView( position, pageSize ) )
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;
161 Vector3 angle( position / pageSize * PAGE_SIZE_MULTIPLIER );
163 position.x = pageSize.x * sinf( angle.x );
164 position.y = pageSize.y * sinf( angle.y );
166 Vector2 zMovement( pageSize );
167 zMovement *= mPositionToPageSizeRatio;
168 position.z = - ( ( zMovement.x - ( zMovement.x * cos( angle.x ) ) ) + ( zMovement.y - ( zMovement.y * cos( angle.y ) ) ) );
173 const Vector2 mPositionToPageSizeRatio; ///< The page will move its position according to this ratio.
176 typedef IntrusivePtr<ScrollPageCarouselEffectInfo> ScrollPageCarouselEffectInfoPtr;
179 * Helper: Applies the 3D scroll cube constraints to the child actor
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
185 void ApplyScrollCubeConstraints(Toolkit::ScrollView scrollView,
187 ScrollPageCarouselEffectInfoPtr info)
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) );
200 constraint.SetRemoveAction( Constraint::Discard );
201 child.ApplyConstraint( constraint );
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) );
212 constraint.SetRemoveAction( Constraint::Discard );
213 child.ApplyConstraint( constraint );
216 } // unnamed namespace
218 ScrollViewPageCarouselEffect::ScrollViewPageCarouselEffect()
223 ScrollViewPageCarouselEffect::~ScrollViewPageCarouselEffect()
227 void ScrollViewPageCarouselEffect::ApplyToPage( Actor page, const Vector2& positionToPageSizeRatio )
229 ScrollPageCarouselEffectInfoPtr info(new ScrollPageCarouselEffectInfo( positionToPageSizeRatio ) );
231 ApplyScrollCubeConstraints( GetScrollView(), page, info );
234 void ScrollViewPageCarouselEffect::OnAttach(Toolkit::ScrollView& scrollView)
238 void ScrollViewPageCarouselEffect::OnDetach(Toolkit::ScrollView& scrollView)
242 } // namespace Internal
244 } // namespace Toolkit