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 <dali/public-api/animation/constraint.h>
23 #include <dali/public-api/object/property-input.h>
26 #include <dali-toolkit/internal/controls/scrollable/scroll-view/scroll-view-helper-functions.h>
37 namespace // unnamed namespace
40 const float PAGE_SIZE_MULTIPLIER( 1.15f );
42 using namespace ScrollViewHelperFunctions;
45 * ScrollPageCarouselEffectInfo
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%.
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.
57 class ScrollPageCarouselEffectInfo
61 ScrollPageCarouselEffectInfo( const Vector2& positionToPageSizeRatio )
62 : mPositionToPageSizeRatio( positionToPageSizeRatio )
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.
77 void ColorConstraint( Vector4& current, const PropertyInputContainer& inputs )
79 const Vector3& pagePosition = inputs[0]->GetVector3();
80 const Vector3& scrollPosition = inputs[1]->GetVector3();
82 // Get position of page.
83 Vector3 position = pagePosition + scrollPosition;
85 // short circuit: if we're looking straight on at the page.
86 if( IsStraightOnView( position ) )
91 const Vector3& pageSize = inputs[4]->GetVector3();
93 if( inputs[5]->GetBoolean() )
95 WrapPositionWithinDomain( position, pageSize, inputs[2]->GetVector3(), inputs[3]->GetVector3() );
98 // short circuit: for pages outside of view.
99 if( IsOutsideView( position, pageSize ) )
101 // note preserve color channels incase there is a shader/further constraint
102 // that wishes to do something with that information.
107 Vector2 distance( position / pageSize * PAGE_SIZE_MULTIPLIER );
108 current.a = Clamp( 1.0f - distance.Length(), 0.0f, 1.0f );
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.
122 void PositionConstraint( Vector3& current, const PropertyInputContainer& inputs )
124 const Vector3& pagePosition = inputs[0]->GetVector3();
125 const Vector3& scrollPosition = inputs[1]->GetVector3();
127 // Get position of page.
128 Vector3 position = pagePosition + scrollPosition;
130 // short circuit: if we're looking straight on at the page.
131 if( IsStraightOnView( position ) )
133 current += scrollPosition;
137 const Vector3& pageSize = inputs[4]->GetVector3();
139 if( inputs[5]->GetBoolean() )
141 WrapPositionWithinDomain( position, pageSize, inputs[2]->GetVector3(), inputs[3]->GetVector3() );
144 // short circuit: for pages outside of view.
145 if( IsOutsideView( position, pageSize ) )
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;
153 Vector3 angle( position / pageSize * PAGE_SIZE_MULTIPLIER );
155 position.x = pageSize.x * sinf( angle.x );
156 position.y = pageSize.y * sinf( angle.y );
158 Vector2 zMovement( pageSize );
159 zMovement *= mPositionToPageSizeRatio;
160 position.z = - ( ( zMovement.x - ( zMovement.x * cos( angle.x ) ) ) + ( zMovement.y - ( zMovement.y * cos( angle.y ) ) ) );
165 const Vector2 mPositionToPageSizeRatio; ///< The page will move its position according to this ratio.
169 * Helper: Applies the 3D scroll cube constraints to the child actor
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
175 void ApplyScrollCubeConstraints(Toolkit::ScrollView scrollView,
177 ScrollPageCarouselEffectInfo& info)
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 );
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 );
202 } // unnamed namespace
204 ScrollViewPageCarouselEffect::ScrollViewPageCarouselEffect()
209 ScrollViewPageCarouselEffect::~ScrollViewPageCarouselEffect()
213 void ScrollViewPageCarouselEffect::ApplyToPage( Actor page, const Vector2& positionToPageSizeRatio )
215 ScrollPageCarouselEffectInfo info( positionToPageSizeRatio );
217 ApplyScrollCubeConstraints( GetScrollView(), page, info );
220 void ScrollViewPageCarouselEffect::OnAttach(Toolkit::ScrollView& scrollView)
224 void ScrollViewPageCarouselEffect::OnDetach(Toolkit::ScrollView& scrollView)
228 } // namespace Internal
230 } // namespace Toolkit