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>
21 #include <dali-toolkit/internal/controls/scrollable/scroll-view/scroll-view-effect-impl.h>
22 #include <dali-toolkit/internal/controls/scrollable/scroll-view/scroll-view-carousel-effect-impl.h>
26 namespace // unnamed namespace
30 * Gets a property index. If the property doesn't already exist, then
31 * it will create the property.
32 * @param[in] handle The handle that owns or will own the property
33 * @param[in] name The name for this property
34 * @param[in] propertyValue The initial value for this property
35 * @return The property index for this property is returned.
37 Property::Index SafeRegisterProperty( Handle& handle, const std::string& name, Property::Value propertyValue )
39 Property::Index index = handle.GetPropertyIndex( name );
41 if(index == Property::INVALID_INDEX)
43 index = handle.RegisterProperty( name, propertyValue );
50 * ScrollCarouselEffectInfo
52 * Visibility constraint: switches off the visibility when Actor
53 * is outside of bounds, for performance reasons.
55 * Rotate constraint: adjusts the angle of the Actors
56 * based on their position relative to the edges of the screen.
57 * When in the middle portion of the screen Angle does not change.
58 * When leaving the edge of the screen screen rotation changes.
60 * Position constraint: adjusts the position of the Actors
61 * based on their parent page's position relative to the edges of the screen.
62 * The position constraint compensates for the rotation which would otherwise
63 * move the Actor's edge visually away from the neighboring actor, as they rotate
64 * around their default anchor point.
66 class ScrollCarouselEffectInfo
70 ScrollCarouselEffectInfo(const Vector2& angleSwing)
71 : mAngleSwing(angleSwing),
72 mCanvasMargin( 0.0f, 0.0f ),
73 mVisibilityThreshold( 1.0f, 1.0f )
78 * @param[in] current The current visibility of this Actor
79 * @param[in] positionProperty The Actor's Position.
80 * @param[in] scaleProperty The Actor's Scale.
81 * @param[in] sizeProperty The Actor's Size
82 * @param[in] scrollPositionProperty The scroll-view's position property (SCROLL_POSITION_PROPERTY_NAME)
83 * @param[in] scrollSizeProperty The size of the scroll-view (scrollView SIZE)
84 * @return The new visibility of this Actor.
86 bool VisibilityConstraint(const bool& current,
87 const PropertyInput& positionProperty,
88 const PropertyInput& scaleProperty,
89 const PropertyInput& sizeProperty,
90 const PropertyInput& scrollPositionProperty,
91 const PropertyInput& scrollSizeProperty)
93 const Vector2& anchor(AnchorPoint::CENTER.GetVectorXY());
94 Vector2 position(positionProperty.GetVector3() + scrollPositionProperty.GetVector3());
95 Vector2 scaledSize(sizeProperty.GetVector3() * scaleProperty.GetVector3());
97 Vector2 domain(scrollSizeProperty.GetVector3());
99 position -= (anchor - mVisibilityThreshold) * scaledSize;
100 domain -= (Vector2::ONE - mVisibilityThreshold * 2.0f) * scaledSize;
102 return ( position.x >= 0 &&
103 position.x <= domain.x &&
105 position.y <= domain.y );
109 * @param[in] current The current orientation of this Actor
110 * @param[in] positionProperty The Actor's Position.
111 * @param[in] scaleProperty The Actor's Scale.
112 * @param[in] sizeProperty The Actor's Size
113 * @param[in] scrollPositionProperty The scroll-view's position property (SCROLL_POSITION_PROPERTY_NAME)
114 * @param[in] scrollSizeProperty The size of the scroll-view (scrollView SIZE)
115 * @param[in] activateProperty Activation value (0 - normal, 1.0 - full effect)
116 * @return The new orientation of this Actor.
118 Quaternion RotationConstraint(const Quaternion& current,
119 const PropertyInput& positionProperty,
120 const PropertyInput& scaleProperty,
121 const PropertyInput& sizeProperty,
122 const PropertyInput& scrollPositionProperty,
123 const PropertyInput& scrollSizeProperty,
124 const PropertyInput& activateProperty)
126 const float activate(activateProperty.GetFloat());
128 if(activate <= Math::MACHINE_EPSILON_0)
133 const Vector2& anchor(AnchorPoint::CENTER.GetVectorXY());
134 Vector2 position(positionProperty.GetVector3() + scrollPositionProperty.GetVector3());
135 Vector2 scaledSize(sizeProperty.GetVector3() * scaleProperty.GetVector3());
136 Vector2 domain(scrollSizeProperty.GetVector3());
138 position -= (anchor - mCanvasMargin) * scaledSize;
139 domain -= (Vector2::ONE - mCanvasMargin * 2.0f) * scaledSize;
145 angle.y = (-position.y / scaledSize.height) * mAngleSwing.y;
147 else if( position.y > domain.y )
149 angle.y = ((domain.y - position.y) / scaledSize.height) * mAngleSwing.y;
154 return Quaternion(-angle.x, Vector3::YAXIS) *
155 Quaternion(angle.y, Vector3::XAXIS) *
160 * @param[in] current The current position of this Actor
161 * @param[in] scaleProperty The Actor's Scale.
162 * @param[in] sizeProperty The Actor's Size
163 * @param[in] scrollPositionProperty The scroll-view's position property (SCROLL_POSITION_PROPERTY_NAME)
164 * @param[in] scrollSizeProperty The size of the scroll-view (scrollView SIZE)
165 * @param[in] activateProperty Activation value (0 - normal, 1.0 - full effect)
166 * @return The new position of this Actor.
168 Vector3 PositionConstraint(const Vector3& current,
169 const PropertyInput& scaleProperty,
170 const PropertyInput& sizeProperty,
171 const PropertyInput& scrollPositionProperty,
172 const PropertyInput& scrollSizeProperty,
173 const PropertyInput& activateProperty)
175 const float activate(activateProperty.GetFloat());
176 Vector3 position(current + scrollPositionProperty.GetVector3());
178 if(activate <= Math::MACHINE_EPSILON_0)
183 const Vector2& anchor(AnchorPoint::CENTER.GetVectorXY());
184 Vector2 scaledSize(sizeProperty.GetVector3() * scaleProperty.GetVector3());
185 Vector2 domain(scrollSizeProperty.GetVector3());
187 position.GetVectorXY() -= (anchor - mCanvasMargin) * scaledSize;
188 domain -= (Vector2::ONE - mCanvasMargin * 2.0f) * scaledSize;
194 angle.y = (-position.y / scaledSize.height) * mAngleSwing.y * activate;
195 position.y += (1.0f - cosf(angle.y)) * scaledSize.height * 0.5f;
196 position.z -= sinf(angle.y) * scaledSize.height * 0.5f;
198 else if(position.y > domain.y)
200 angle.y = ((domain.y - position.y) / scaledSize.height) * mAngleSwing.y * activate;
201 position.y -= (1.0f - cosf(angle.y)) * scaledSize.height * 0.5f;
202 position.z -= sinf(-angle.y) * scaledSize.height * 0.5f;
205 position.GetVectorXY() += (anchor - mCanvasMargin) * scaledSize;
210 Vector2 mAngleSwing; ///< Maximum amount in X and Y axes to rotate.
211 Vector2 mCanvasMargin; ///< Margin around the canvas for when to start rotating
212 Vector2 mVisibilityThreshold; ///< Threshold for when to to switch off visibility of Actor (for performance)
216 * Helper: Applies the 3D scroll carousel constraints to the child actor
218 * @param[in] scrollView The ScrollView containing the pages.
219 * @param[in] child The child to be affected with the 3D Effect.
220 * @param[in] info The effect info for the constraints
222 void ApplyScrollCarouselConstraints(Toolkit::ScrollView scrollView,
224 ScrollCarouselEffectInfo& info)
226 // Apply constraints to this actor //
227 Constraint constraint;
229 constraint = Constraint::New<bool>( Actor::VISIBLE,
230 LocalSource( Actor::POSITION ),
231 LocalSource( Actor::SCALE ),
232 LocalSource( Actor::SIZE ),
233 Source(scrollView, scrollView.GetPropertyIndex( Toolkit::ScrollView::SCROLL_POSITION_PROPERTY_NAME ) ),
234 Source(scrollView, Actor::SIZE ),
235 Source(scrollView, scrollView.GetPropertyIndex( Toolkit::ScrollViewCarouselEffect::EFFECT_ACTIVATE ) ),
236 boost::bind( &ScrollCarouselEffectInfo::VisibilityConstraint, info, _1, _2, _3, _4, _5, _6) );
237 constraint.SetRemoveAction( Constraint::Discard );
238 child.ApplyConstraint( constraint );
240 constraint = Constraint::New<Quaternion>( Actor::ROTATION,
241 LocalSource( Actor::POSITION ),
242 LocalSource( Actor::SCALE ),
243 LocalSource( Actor::SIZE ),
244 Source(scrollView, scrollView.GetPropertyIndex( Toolkit::ScrollView::SCROLL_POSITION_PROPERTY_NAME ) ),
245 Source(scrollView, Actor::SIZE ),
246 Source(scrollView, scrollView.GetPropertyIndex( Toolkit::ScrollViewCarouselEffect::EFFECT_ACTIVATE ) ),
247 boost::bind( &ScrollCarouselEffectInfo::RotationConstraint, info, _1, _2, _3, _4, _5, _6, _7) );
248 constraint.SetRemoveAction( Constraint::Discard );
249 child.ApplyConstraint( constraint );
251 constraint = Constraint::New<Vector3>( Actor::POSITION,
252 LocalSource( Actor::SCALE ),
253 LocalSource( Actor::SIZE ),
254 Source(scrollView, scrollView.GetPropertyIndex( Toolkit::ScrollView::SCROLL_POSITION_PROPERTY_NAME ) ),
255 Source(scrollView, Actor::SIZE ),
256 Source(scrollView, scrollView.GetPropertyIndex( Toolkit::ScrollViewCarouselEffect::EFFECT_ACTIVATE ) ),
257 boost::bind( &ScrollCarouselEffectInfo::PositionConstraint, info, _1, _2, _3, _4, _5, _6) );
259 constraint.SetRemoveAction( Constraint::Discard );
260 child.ApplyConstraint( constraint );
263 } // unnamed namespace
274 ScrollViewCarouselEffect::ScrollViewCarouselEffect()
275 : mPropertyActivate(Property::INVALID_INDEX)
279 ScrollViewCarouselEffect::~ScrollViewCarouselEffect()
283 void ScrollViewCarouselEffect::ApplyToActor(Actor child, const Vector2& angleSwing)
285 ScrollCarouselEffectInfo info( angleSwing );
287 ApplyScrollCarouselConstraints( GetScrollView(), child, info );
290 void ScrollViewCarouselEffect::OnAttach(Toolkit::ScrollView& scrollView)
292 if(mPropertyActivate == Property::INVALID_INDEX)
294 mPropertyActivate = SafeRegisterProperty( scrollView, Toolkit::ScrollViewCarouselEffect::EFFECT_ACTIVATE, 1.0f );
298 void ScrollViewCarouselEffect::OnDetach(Toolkit::ScrollView& scrollView)
302 } // namespace Internal
304 } // namespace Toolkit