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 <boost/bind.hpp>
22 #include <dali-toolkit/internal/controls/scrollable/scroll-view/scroll-view-effect-impl.h>
23 #include <dali-toolkit/internal/controls/scrollable/scroll-view/scroll-view-carousel-effect-impl.h>
27 namespace // unnamed namespace
31 * Gets a property index. If the property doesn't already exist, then
32 * it will create the property.
33 * @param[in] handle The handle that owns or will own the property
34 * @param[in] name The name for this property
35 * @param[in] propertyValue The initial value for this property
36 * @return The property index for this property is returned.
38 Property::Index SafeRegisterProperty( Handle& handle, const std::string& name, Property::Value propertyValue )
40 Property::Index index = handle.GetPropertyIndex( name );
42 if(index == Property::INVALID_INDEX)
44 index = handle.RegisterProperty( name, propertyValue );
51 * ScrollCarouselEffectInfo
53 * Visibility constraint: switches off the visibility when Actor
54 * is outside of bounds, for performance reasons.
56 * Rotate constraint: adjusts the angle of the Actors
57 * based on their position relative to the edges of the screen.
58 * When in the middle portion of the screen Angle does not change.
59 * When leaving the edge of the screen screen rotation changes.
61 * Position constraint: adjusts the position of the Actors
62 * based on their parent page's position relative to the edges of the screen.
63 * The position constraint compensates for the rotation which would otherwise
64 * move the Actor's edge visually away from the neighboring actor, as they rotate
65 * around their default anchor point.
67 class ScrollCarouselEffectInfo
71 ScrollCarouselEffectInfo(const Vector2& angleSwing)
72 : mAngleSwing(angleSwing),
73 mCanvasMargin( 0.0f, 0.0f ),
74 mVisibilityThreshold( 1.0f, 1.0f )
79 * @param[in] current The current visibility of this Actor
80 * @param[in] positionProperty The Actor's Position.
81 * @param[in] scaleProperty The Actor's Scale.
82 * @param[in] sizeProperty The Actor's Size
83 * @param[in] scrollPositionProperty The scroll-view's position property (SCROLL_POSITION_PROPERTY_NAME)
84 * @param[in] scrollSizeProperty The size of the scroll-view (scrollView SIZE)
85 * @return The new visibility of this Actor.
87 bool VisibilityConstraint(const bool& current,
88 const PropertyInput& positionProperty,
89 const PropertyInput& scaleProperty,
90 const PropertyInput& sizeProperty,
91 const PropertyInput& scrollPositionProperty,
92 const PropertyInput& scrollSizeProperty)
94 const Vector2& anchor(AnchorPoint::CENTER.GetVectorXY());
95 Vector2 position(positionProperty.GetVector3() + scrollPositionProperty.GetVector3());
96 Vector2 scaledSize(sizeProperty.GetVector3() * scaleProperty.GetVector3());
98 Vector2 domain(scrollSizeProperty.GetVector3());
100 position -= (anchor - mVisibilityThreshold) * scaledSize;
101 domain -= (Vector2::ONE - mVisibilityThreshold * 2.0f) * scaledSize;
103 return ( position.x >= 0 &&
104 position.x <= domain.x &&
106 position.y <= domain.y );
110 * @param[in] current The current orientation of this Actor
111 * @param[in] positionProperty The Actor's Position.
112 * @param[in] scaleProperty The Actor's Scale.
113 * @param[in] sizeProperty The Actor's Size
114 * @param[in] scrollPositionProperty The scroll-view's position property (SCROLL_POSITION_PROPERTY_NAME)
115 * @param[in] scrollSizeProperty The size of the scroll-view (scrollView SIZE)
116 * @param[in] activateProperty Activation value (0 - normal, 1.0 - full effect)
117 * @return The new orientation of this Actor.
119 Quaternion RotationConstraint(const Quaternion& current,
120 const PropertyInput& positionProperty,
121 const PropertyInput& scaleProperty,
122 const PropertyInput& sizeProperty,
123 const PropertyInput& scrollPositionProperty,
124 const PropertyInput& scrollSizeProperty,
125 const PropertyInput& activateProperty)
127 const float activate(activateProperty.GetFloat());
129 if(activate <= Math::MACHINE_EPSILON_0)
134 const Vector2& anchor(AnchorPoint::CENTER.GetVectorXY());
135 Vector2 position(positionProperty.GetVector3() + scrollPositionProperty.GetVector3());
136 Vector2 scaledSize(sizeProperty.GetVector3() * scaleProperty.GetVector3());
137 Vector2 domain(scrollSizeProperty.GetVector3());
139 position -= (anchor - mCanvasMargin) * scaledSize;
140 domain -= (Vector2::ONE - mCanvasMargin * 2.0f) * scaledSize;
146 angle.y = (-position.y / scaledSize.height) * mAngleSwing.y;
148 else if( position.y > domain.y )
150 angle.y = ((domain.y - position.y) / scaledSize.height) * mAngleSwing.y;
155 return Quaternion(-angle.x, Vector3::YAXIS) *
156 Quaternion(angle.y, Vector3::XAXIS) *
161 * @param[in] current The current position of this Actor
162 * @param[in] scaleProperty The Actor's Scale.
163 * @param[in] sizeProperty The Actor's Size
164 * @param[in] scrollPositionProperty The scroll-view's position property (SCROLL_POSITION_PROPERTY_NAME)
165 * @param[in] scrollSizeProperty The size of the scroll-view (scrollView SIZE)
166 * @param[in] activateProperty Activation value (0 - normal, 1.0 - full effect)
167 * @return The new position of this Actor.
169 Vector3 PositionConstraint(const Vector3& current,
170 const PropertyInput& scaleProperty,
171 const PropertyInput& sizeProperty,
172 const PropertyInput& scrollPositionProperty,
173 const PropertyInput& scrollSizeProperty,
174 const PropertyInput& activateProperty)
176 const float activate(activateProperty.GetFloat());
177 Vector3 position(current + scrollPositionProperty.GetVector3());
179 if(activate <= Math::MACHINE_EPSILON_0)
184 const Vector2& anchor(AnchorPoint::CENTER.GetVectorXY());
185 Vector2 scaledSize(sizeProperty.GetVector3() * scaleProperty.GetVector3());
186 Vector2 domain(scrollSizeProperty.GetVector3());
188 position.GetVectorXY() -= (anchor - mCanvasMargin) * scaledSize;
189 domain -= (Vector2::ONE - mCanvasMargin * 2.0f) * scaledSize;
195 angle.y = (-position.y / scaledSize.height) * mAngleSwing.y * activate;
196 position.y += (1.0f - cosf(angle.y)) * scaledSize.height * 0.5f;
197 position.z -= sinf(angle.y) * scaledSize.height * 0.5f;
199 else if(position.y > domain.y)
201 angle.y = ((domain.y - position.y) / scaledSize.height) * mAngleSwing.y * activate;
202 position.y -= (1.0f - cosf(angle.y)) * scaledSize.height * 0.5f;
203 position.z -= sinf(-angle.y) * scaledSize.height * 0.5f;
206 position.GetVectorXY() += (anchor - mCanvasMargin) * scaledSize;
211 Vector2 mAngleSwing; ///< Maximum amount in X and Y axes to rotate.
212 Vector2 mCanvasMargin; ///< Margin around the canvas for when to start rotating
213 Vector2 mVisibilityThreshold; ///< Threshold for when to to switch off visibility of Actor (for performance)
217 * Helper: Applies the 3D scroll carousel constraints to the child actor
219 * @param[in] scrollView The ScrollView containing the pages.
220 * @param[in] child The child to be affected with the 3D Effect.
221 * @param[in] info The effect info for the constraints
223 void ApplyScrollCarouselConstraints(Toolkit::ScrollView scrollView,
225 ScrollCarouselEffectInfo& info)
227 // Apply constraints to this actor //
228 Constraint constraint;
230 constraint = Constraint::New<bool>( Actor::VISIBLE,
231 LocalSource( Actor::POSITION ),
232 LocalSource( Actor::SCALE ),
233 LocalSource( Actor::SIZE ),
234 Source(scrollView, scrollView.GetPropertyIndex( Toolkit::ScrollView::SCROLL_POSITION_PROPERTY_NAME ) ),
235 Source(scrollView, Actor::SIZE ),
236 Source(scrollView, scrollView.GetPropertyIndex( Toolkit::ScrollViewCarouselEffect::EFFECT_ACTIVATE ) ),
237 boost::bind( &ScrollCarouselEffectInfo::VisibilityConstraint, info, _1, _2, _3, _4, _5, _6) );
238 constraint.SetRemoveAction( Constraint::Discard );
239 child.ApplyConstraint( constraint );
241 constraint = Constraint::New<Quaternion>( Actor::ROTATION,
242 LocalSource( Actor::POSITION ),
243 LocalSource( Actor::SCALE ),
244 LocalSource( Actor::SIZE ),
245 Source(scrollView, scrollView.GetPropertyIndex( Toolkit::ScrollView::SCROLL_POSITION_PROPERTY_NAME ) ),
246 Source(scrollView, Actor::SIZE ),
247 Source(scrollView, scrollView.GetPropertyIndex( Toolkit::ScrollViewCarouselEffect::EFFECT_ACTIVATE ) ),
248 boost::bind( &ScrollCarouselEffectInfo::RotationConstraint, info, _1, _2, _3, _4, _5, _6, _7) );
249 constraint.SetRemoveAction( Constraint::Discard );
250 child.ApplyConstraint( constraint );
252 constraint = Constraint::New<Vector3>( Actor::POSITION,
253 LocalSource( Actor::SCALE ),
254 LocalSource( Actor::SIZE ),
255 Source(scrollView, scrollView.GetPropertyIndex( Toolkit::ScrollView::SCROLL_POSITION_PROPERTY_NAME ) ),
256 Source(scrollView, Actor::SIZE ),
257 Source(scrollView, scrollView.GetPropertyIndex( Toolkit::ScrollViewCarouselEffect::EFFECT_ACTIVATE ) ),
258 boost::bind( &ScrollCarouselEffectInfo::PositionConstraint, info, _1, _2, _3, _4, _5, _6) );
260 constraint.SetRemoveAction( Constraint::Discard );
261 child.ApplyConstraint( constraint );
264 } // unnamed namespace
275 ScrollViewCarouselEffect::ScrollViewCarouselEffect()
276 : mPropertyActivate(Property::INVALID_INDEX)
280 ScrollViewCarouselEffect::~ScrollViewCarouselEffect()
284 void ScrollViewCarouselEffect::ApplyToActor(Actor child, const Vector2& angleSwing)
286 ScrollCarouselEffectInfo info( angleSwing );
288 ApplyScrollCarouselConstraints( GetScrollView(), child, info );
291 void ScrollViewCarouselEffect::OnAttach(Toolkit::ScrollView& scrollView)
293 if(mPropertyActivate == Property::INVALID_INDEX)
295 mPropertyActivate = SafeRegisterProperty( scrollView, Toolkit::ScrollViewCarouselEffect::EFFECT_ACTIVATE, 1.0f );
299 void ScrollViewCarouselEffect::OnDetach(Toolkit::ScrollView& scrollView)
303 } // namespace Internal
305 } // namespace Toolkit