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 <boost/bind.hpp>
20 #include <dali-toolkit/internal/controls/scrollable/scroll-view/scroll-view-effect-impl.h>
21 #include <dali-toolkit/internal/controls/scrollable/scroll-view/scroll-view-carousel-effect-impl.h>
25 namespace // unnamed namespace
29 * Gets a property index. If the property doesn't already exist, then
30 * it will create the property.
31 * @param[in] handle The handle that owns or will own the property
32 * @param[in] name The name for this property
33 * @param[in] propertyValue The initial value for this property
34 * @return The property index for this property is returned.
36 Property::Index SafeRegisterProperty( Handle& handle, const std::string& name, Property::Value propertyValue )
38 Property::Index index = handle.GetPropertyIndex( name );
40 if(index == Property::INVALID_INDEX)
42 index = handle.RegisterProperty( name, propertyValue );
49 * ScrollCarouselEffectInfo
51 * Visibility constraint: switches off the visibility when Actor
52 * is outside of bounds, for performance reasons.
54 * Rotate constraint: adjusts the angle of the Actors
55 * based on their position relative to the edges of the screen.
56 * When in the middle portion of the screen Angle does not change.
57 * When leaving the edge of the screen screen rotation changes.
59 * Position constraint: adjusts the position of the Actors
60 * based on their parent page's position relative to the edges of the screen.
61 * The position constraint compensates for the rotation which would otherwise
62 * move the Actor's edge visually away from the neighboring actor, as they rotate
63 * around their default anchor point.
65 class ScrollCarouselEffectInfo : public Dali::RefObject
69 ScrollCarouselEffectInfo(const Vector2& angleSwing)
70 : mAngleSwing(angleSwing),
71 mCanvasMargin( 0.0f, 0.0f ),
72 mVisibilityThreshold( 1.0f, 1.0f )
77 * @param[in] current The current visibility of this Actor
78 * @param[in] positionProperty The Actor's Position.
79 * @param[in] scaleProperty The Actor's Scale.
80 * @param[in] sizeProperty The Actor's Size
81 * @param[in] scrollPositionProperty The scroll-view's position property (SCROLL_POSITION_PROPERTY_NAME)
82 * @param[in] scrollSizeProperty The size of the scroll-view (scrollView SIZE)
83 * @return The new visibility of this Actor.
85 bool VisibilityConstraint(const bool& current,
86 const PropertyInput& positionProperty,
87 const PropertyInput& scaleProperty,
88 const PropertyInput& sizeProperty,
89 const PropertyInput& scrollPositionProperty,
90 const PropertyInput& scrollSizeProperty)
92 const Vector2& anchor(AnchorPoint::CENTER.GetVectorXY());
93 Vector2 position(positionProperty.GetVector3() + scrollPositionProperty.GetVector3());
94 Vector2 scaledSize(sizeProperty.GetVector3() * scaleProperty.GetVector3());
96 Vector2 domain(scrollSizeProperty.GetVector3());
98 position -= (anchor - mVisibilityThreshold) * scaledSize;
99 domain -= (Vector2::ONE - mVisibilityThreshold * 2.0f) * scaledSize;
101 return ( position.x >= 0 &&
102 position.x <= domain.x &&
104 position.y <= domain.y );
108 * @param[in] current The current orientation of this Actor
109 * @param[in] positionProperty The Actor's Position.
110 * @param[in] scaleProperty The Actor's Scale.
111 * @param[in] sizeProperty The Actor's Size
112 * @param[in] scrollPositionProperty The scroll-view's position property (SCROLL_POSITION_PROPERTY_NAME)
113 * @param[in] scrollSizeProperty The size of the scroll-view (scrollView SIZE)
114 * @param[in] activateProperty Activation value (0 - normal, 1.0 - full effect)
115 * @return The new orientation of this Actor.
117 Quaternion RotationConstraint(const Quaternion& current,
118 const PropertyInput& positionProperty,
119 const PropertyInput& scaleProperty,
120 const PropertyInput& sizeProperty,
121 const PropertyInput& scrollPositionProperty,
122 const PropertyInput& scrollSizeProperty,
123 const PropertyInput& activateProperty)
125 const float activate(activateProperty.GetFloat());
127 if(activate <= Math::MACHINE_EPSILON_0)
132 const Vector2& anchor(AnchorPoint::CENTER.GetVectorXY());
133 Vector2 position(positionProperty.GetVector3() + scrollPositionProperty.GetVector3());
134 Vector2 scaledSize(sizeProperty.GetVector3() * scaleProperty.GetVector3());
135 Vector2 domain(scrollSizeProperty.GetVector3());
137 position -= (anchor - mCanvasMargin) * scaledSize;
138 domain -= (Vector2::ONE - mCanvasMargin * 2.0f) * scaledSize;
144 angle.y = (-position.y / scaledSize.height) * mAngleSwing.y;
146 else if( position.y > domain.y )
148 angle.y = ((domain.y - position.y) / scaledSize.height) * mAngleSwing.y;
153 return Quaternion(-angle.x, Vector3::YAXIS) *
154 Quaternion(angle.y, Vector3::XAXIS) *
159 * @param[in] current The current position of this Actor
160 * @param[in] scaleProperty The Actor's Scale.
161 * @param[in] sizeProperty The Actor's Size
162 * @param[in] scrollPositionProperty The scroll-view's position property (SCROLL_POSITION_PROPERTY_NAME)
163 * @param[in] scrollSizeProperty The size of the scroll-view (scrollView SIZE)
164 * @param[in] activateProperty Activation value (0 - normal, 1.0 - full effect)
165 * @return The new position of this Actor.
167 Vector3 PositionConstraint(const Vector3& current,
168 const PropertyInput& scaleProperty,
169 const PropertyInput& sizeProperty,
170 const PropertyInput& scrollPositionProperty,
171 const PropertyInput& scrollSizeProperty,
172 const PropertyInput& activateProperty)
174 const float activate(activateProperty.GetFloat());
175 Vector3 position(current + scrollPositionProperty.GetVector3());
177 if(activate <= Math::MACHINE_EPSILON_0)
182 const Vector2& anchor(AnchorPoint::CENTER.GetVectorXY());
183 Vector2 scaledSize(sizeProperty.GetVector3() * scaleProperty.GetVector3());
184 Vector2 domain(scrollSizeProperty.GetVector3());
186 position.GetVectorXY() -= (anchor - mCanvasMargin) * scaledSize;
187 domain -= (Vector2::ONE - mCanvasMargin * 2.0f) * scaledSize;
193 angle.y = (-position.y / scaledSize.height) * mAngleSwing.y * activate;
194 position.y += (1.0f - cosf(angle.y)) * scaledSize.height * 0.5f;
195 position.z -= sinf(angle.y) * scaledSize.height * 0.5f;
197 else if(position.y > domain.y)
199 angle.y = ((domain.y - position.y) / scaledSize.height) * mAngleSwing.y * activate;
200 position.y -= (1.0f - cosf(angle.y)) * scaledSize.height * 0.5f;
201 position.z -= sinf(-angle.y) * scaledSize.height * 0.5f;
204 position.GetVectorXY() += (anchor - mCanvasMargin) * scaledSize;
209 Vector2 mAngleSwing; ///< Maximum amount in X and Y axes to rotate.
210 Vector2 mCanvasMargin; ///< Margin around the canvas for when to start rotating
211 Vector2 mVisibilityThreshold; ///< Threshold for when to to switch off visibility of Actor (for performance)
214 typedef IntrusivePtr<ScrollCarouselEffectInfo> ScrollCarouselEffectInfoPtr;
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 ScrollCarouselEffectInfoPtr 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 ScrollCarouselEffectInfoPtr info(new ScrollCarouselEffectInfo(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