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>
20 #include <dali/public-api/animation/active-constraint.h>
21 #include <dali/public-api/animation/constraint.h>
22 #include <dali/public-api/object/property-input.h>
25 #include <dali-toolkit/internal/controls/scrollable/scroll-view/scroll-view-effect-impl.h>
26 #include <dali-toolkit/internal/controls/scrollable/scroll-view/scroll-view-carousel-effect-impl.h>
30 namespace // unnamed namespace
34 * Gets a property index. If the property doesn't already exist, then
35 * it will create the property.
36 * @param[in] handle The handle that owns or will own the property
37 * @param[in] name The name for this property
38 * @param[in] propertyValue The initial value for this property
39 * @return The property index for this property is returned.
41 Property::Index SafeRegisterProperty( Handle& handle, const std::string& name, Property::Value propertyValue )
43 Property::Index index = handle.GetPropertyIndex( name );
45 if(index == Property::INVALID_INDEX)
47 index = handle.RegisterProperty( name, propertyValue );
54 * ScrollCarouselEffectInfo
56 * Visibility constraint: switches off the visibility when Actor
57 * is outside of bounds, for performance reasons.
59 * Rotate constraint: adjusts the angle of the Actors
60 * based on their position relative to the edges of the screen.
61 * When in the middle portion of the screen Angle does not change.
62 * When leaving the edge of the screen screen rotation changes.
64 * Position constraint: adjusts the position of the Actors
65 * based on their parent page's position relative to the edges of the screen.
66 * The position constraint compensates for the rotation which would otherwise
67 * move the Actor's edge visually away from the neighboring actor, as they rotate
68 * around their default anchor point.
70 class ScrollCarouselEffectInfo
74 ScrollCarouselEffectInfo(const Vector2& angleSwing)
75 : mAngleSwing(angleSwing),
76 mCanvasMargin( 0.0f, 0.0f ),
77 mVisibilityThreshold( 1.0f, 1.0f )
82 * @param[in] current The current visibility of this Actor
83 * @param[in] positionProperty The Actor's Position.
84 * @param[in] scaleProperty The Actor's Scale.
85 * @param[in] sizeProperty The Actor's Size
86 * @param[in] scrollPositionProperty The scroll-view's position property (SCROLL_POSITION_PROPERTY_NAME)
87 * @param[in] scrollSizeProperty The size of the scroll-view (scrollView SIZE)
88 * @return The new visibility of this Actor.
90 bool VisibilityConstraint(const bool& current,
91 const PropertyInput& positionProperty,
92 const PropertyInput& scaleProperty,
93 const PropertyInput& sizeProperty,
94 const PropertyInput& scrollPositionProperty,
95 const PropertyInput& scrollSizeProperty)
97 const Vector2& anchor(AnchorPoint::CENTER.GetVectorXY());
98 Vector2 position(positionProperty.GetVector3() + scrollPositionProperty.GetVector3());
99 Vector2 scaledSize(sizeProperty.GetVector3() * scaleProperty.GetVector3());
101 Vector2 domain(scrollSizeProperty.GetVector3());
103 position -= (anchor - mVisibilityThreshold) * scaledSize;
104 domain -= (Vector2::ONE - mVisibilityThreshold * 2.0f) * scaledSize;
106 return ( position.x >= 0 &&
107 position.x <= domain.x &&
109 position.y <= domain.y );
113 * @param[in] current The current orientation of this Actor
114 * @param[in] positionProperty The Actor's Position.
115 * @param[in] scaleProperty The Actor's Scale.
116 * @param[in] sizeProperty The Actor's Size
117 * @param[in] scrollPositionProperty The scroll-view's position property (SCROLL_POSITION_PROPERTY_NAME)
118 * @param[in] scrollSizeProperty The size of the scroll-view (scrollView SIZE)
119 * @param[in] activateProperty Activation value (0 - normal, 1.0 - full effect)
120 * @return The new orientation of this Actor.
122 Quaternion RotationConstraint(const Quaternion& current,
123 const PropertyInput& positionProperty,
124 const PropertyInput& scaleProperty,
125 const PropertyInput& sizeProperty,
126 const PropertyInput& scrollPositionProperty,
127 const PropertyInput& scrollSizeProperty,
128 const PropertyInput& activateProperty)
130 const float activate(activateProperty.GetFloat());
132 if(activate <= Math::MACHINE_EPSILON_0)
137 const Vector2& anchor(AnchorPoint::CENTER.GetVectorXY());
138 Vector2 position(positionProperty.GetVector3() + scrollPositionProperty.GetVector3());
139 Vector2 scaledSize(sizeProperty.GetVector3() * scaleProperty.GetVector3());
140 Vector2 domain(scrollSizeProperty.GetVector3());
142 position -= (anchor - mCanvasMargin) * scaledSize;
143 domain -= (Vector2::ONE - mCanvasMargin * 2.0f) * scaledSize;
149 angle.y = (-position.y / scaledSize.height) * mAngleSwing.y;
151 else if( position.y > domain.y )
153 angle.y = ((domain.y - position.y) / scaledSize.height) * mAngleSwing.y;
158 return Quaternion(-angle.x, Vector3::YAXIS) *
159 Quaternion(angle.y, Vector3::XAXIS) *
164 * @param[in] current The current position of this Actor
165 * @param[in] scaleProperty The Actor's Scale.
166 * @param[in] sizeProperty The Actor's Size
167 * @param[in] scrollPositionProperty The scroll-view's position property (SCROLL_POSITION_PROPERTY_NAME)
168 * @param[in] scrollSizeProperty The size of the scroll-view (scrollView SIZE)
169 * @param[in] activateProperty Activation value (0 - normal, 1.0 - full effect)
170 * @return The new position of this Actor.
172 Vector3 PositionConstraint(const Vector3& current,
173 const PropertyInput& scaleProperty,
174 const PropertyInput& sizeProperty,
175 const PropertyInput& scrollPositionProperty,
176 const PropertyInput& scrollSizeProperty,
177 const PropertyInput& activateProperty)
179 const float activate(activateProperty.GetFloat());
180 Vector3 position(current + scrollPositionProperty.GetVector3());
182 if(activate <= Math::MACHINE_EPSILON_0)
187 const Vector2& anchor(AnchorPoint::CENTER.GetVectorXY());
188 Vector2 scaledSize(sizeProperty.GetVector3() * scaleProperty.GetVector3());
189 Vector2 domain(scrollSizeProperty.GetVector3());
191 position.GetVectorXY() -= (anchor - mCanvasMargin) * scaledSize;
192 domain -= (Vector2::ONE - mCanvasMargin * 2.0f) * scaledSize;
198 angle.y = (-position.y / scaledSize.height) * mAngleSwing.y * activate;
199 position.y += (1.0f - cosf(angle.y)) * scaledSize.height * 0.5f;
200 position.z -= sinf(angle.y) * scaledSize.height * 0.5f;
202 else if(position.y > domain.y)
204 angle.y = ((domain.y - position.y) / scaledSize.height) * mAngleSwing.y * activate;
205 position.y -= (1.0f - cosf(angle.y)) * scaledSize.height * 0.5f;
206 position.z -= sinf(-angle.y) * scaledSize.height * 0.5f;
209 position.GetVectorXY() += (anchor - mCanvasMargin) * scaledSize;
214 Vector2 mAngleSwing; ///< Maximum amount in X and Y axes to rotate.
215 Vector2 mCanvasMargin; ///< Margin around the canvas for when to start rotating
216 Vector2 mVisibilityThreshold; ///< Threshold for when to to switch off visibility of Actor (for performance)
220 * Helper: Applies the 3D scroll carousel constraints to the child actor
222 * @param[in] scrollView The ScrollView containing the pages.
223 * @param[in] child The child to be affected with the 3D Effect.
224 * @param[in] info The effect info for the constraints
226 void ApplyScrollCarouselConstraints(Toolkit::ScrollView scrollView,
228 ScrollCarouselEffectInfo& info)
230 // Apply constraints to this actor //
231 Constraint constraint;
233 constraint = Constraint::New<bool>( Actor::Property::VISIBLE,
234 LocalSource( Actor::Property::POSITION ),
235 LocalSource( Actor::Property::SCALE ),
236 LocalSource( Actor::Property::SIZE ),
237 Source(scrollView, scrollView.GetPropertyIndex( Toolkit::ScrollView::SCROLL_POSITION_PROPERTY_NAME ) ),
238 Source(scrollView, Actor::Property::SIZE ),
239 Source(scrollView, scrollView.GetPropertyIndex( Toolkit::ScrollViewCarouselEffect::EFFECT_ACTIVATE ) ),
240 boost::bind( &ScrollCarouselEffectInfo::VisibilityConstraint, info, _1, _2, _3, _4, _5, _6) );
241 constraint.SetRemoveAction( Constraint::Discard );
242 child.ApplyConstraint( constraint );
244 constraint = Constraint::New<Quaternion>( Actor::Property::ORIENTATION,
245 LocalSource( Actor::Property::POSITION ),
246 LocalSource( Actor::Property::SCALE ),
247 LocalSource( Actor::Property::SIZE ),
248 Source(scrollView, scrollView.GetPropertyIndex( Toolkit::ScrollView::SCROLL_POSITION_PROPERTY_NAME ) ),
249 Source(scrollView, Actor::Property::SIZE ),
250 Source(scrollView, scrollView.GetPropertyIndex( Toolkit::ScrollViewCarouselEffect::EFFECT_ACTIVATE ) ),
251 boost::bind( &ScrollCarouselEffectInfo::RotationConstraint, info, _1, _2, _3, _4, _5, _6, _7) );
252 constraint.SetRemoveAction( Constraint::Discard );
253 child.ApplyConstraint( constraint );
255 constraint = Constraint::New<Vector3>( Actor::Property::POSITION,
256 LocalSource( Actor::Property::SCALE ),
257 LocalSource( Actor::Property::SIZE ),
258 Source(scrollView, scrollView.GetPropertyIndex( Toolkit::ScrollView::SCROLL_POSITION_PROPERTY_NAME ) ),
259 Source(scrollView, Actor::Property::SIZE ),
260 Source(scrollView, scrollView.GetPropertyIndex( Toolkit::ScrollViewCarouselEffect::EFFECT_ACTIVATE ) ),
261 boost::bind( &ScrollCarouselEffectInfo::PositionConstraint, info, _1, _2, _3, _4, _5, _6) );
263 constraint.SetRemoveAction( Constraint::Discard );
264 child.ApplyConstraint( constraint );
267 } // unnamed namespace
278 ScrollViewCarouselEffect::ScrollViewCarouselEffect()
279 : mPropertyActivate(Property::INVALID_INDEX)
283 ScrollViewCarouselEffect::~ScrollViewCarouselEffect()
287 void ScrollViewCarouselEffect::ApplyToActor(Actor child, const Vector2& angleSwing)
289 ScrollCarouselEffectInfo info( angleSwing );
291 ApplyScrollCarouselConstraints( GetScrollView(), child, info );
294 void ScrollViewCarouselEffect::OnAttach(Toolkit::ScrollView& scrollView)
296 if(mPropertyActivate == Property::INVALID_INDEX)
298 mPropertyActivate = SafeRegisterProperty( scrollView, Toolkit::ScrollViewCarouselEffect::EFFECT_ACTIVATE, 1.0f );
302 void ScrollViewCarouselEffect::OnDetach(Toolkit::ScrollView& scrollView)
306 } // namespace Internal
308 } // namespace Toolkit