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-overshoot-indicator-impl.h>
22 #include <boost/bind.hpp>
25 #include <dali-toolkit/internal/controls/scrollable/scrollable-impl.h>
26 #include <dali-toolkit/public-api/controls/scrollable/scroll-view/scroll-view.h>
32 const Vector2 OVERSHOOT_BOUNCE_ACTOR_DEFAULT_SIZE( 720.0f, 42.0f );
33 const float OVERSHOOT_BOUNCE_ACTOR_RESIZE_THRESHOLD = 180.0f;
35 // local helper function to resize the height of the bounce actor
36 float GetBounceActorHeight( float width )
38 return (width > OVERSHOOT_BOUNCE_ACTOR_RESIZE_THRESHOLD) ? OVERSHOOT_BOUNCE_ACTOR_DEFAULT_SIZE.height : OVERSHOOT_BOUNCE_ACTOR_DEFAULT_SIZE.height * 0.5f;
41 const float MAX_OVERSHOOT_NOTIFY_AMOUNT = 0.99f; // maximum amount to set notification for increased overshoot, beyond this we just wait for it to reduce again
42 const float MIN_OVERSHOOT_NOTIFY_AMOUNT = Math::MACHINE_EPSILON_0; // minimum amount to set notification for reduced overshoot, beyond this we just wait for it to increase again
43 const float OVERSHOOT_NOTIFY_STEP = 0.01f; // amount to set notifications beyond current overshoot value
56 ScrollOvershootIndicator::ScrollOvershootIndicator() :
62 ScrollOvershootIndicator::~ScrollOvershootIndicator()
67 ScrollOvershootIndicator* ScrollOvershootIndicator::New()
69 ScrollOvershootIndicator* scrollOvershootPtr = new ScrollOvershootIndicator();
70 return scrollOvershootPtr;
73 void ScrollOvershootIndicator::AttachToScrollable(Scrollable& scrollable)
77 mEffectX = ScrollOvershootEffectRipple::New(false, scrollable);
82 mEffectY = ScrollOvershootEffectRipple::New(true, scrollable);
87 void ScrollOvershootIndicator::DetachFromScrollable(Scrollable& scrollable)
91 mEffectX->Remove(scrollable);
95 mEffectY->Remove(scrollable);
99 void ScrollOvershootIndicator::Reset()
105 void ScrollOvershootIndicator::SetOvershootEffectColor( const Vector4& color )
109 mEffectX->SetOvershootEffectColor(color);
113 mEffectY->SetOvershootEffectColor(color);
117 void ScrollOvershootIndicator::ClearOvershoot()
121 mEffectX->SetOvershoot(0.0f);
125 mEffectY->SetOvershoot(0.0f);
129 ScrollOvershootEffect::ScrollOvershootEffect( bool vertical ) :
135 bool ScrollOvershootEffect::IsVertical() const
140 ScrollOvershootEffectRipple::ScrollOvershootEffectRipple( bool vertical, Scrollable& scrollable ) :
141 ScrollOvershootEffect( vertical ),
142 mAttachedScrollView(scrollable),
143 mOvershootProperty(Property::INVALID_INDEX),
144 mEffectOvershootProperty(Property::INVALID_INDEX),
146 mAnimationStateFlags(0)
151 void ScrollOvershootEffectRipple::Apply()
153 Actor self = mAttachedScrollView.Self();
154 mOvershootProperty = self.GetPropertyIndex(IsVertical() ? Toolkit::ScrollView::SCROLL_OVERSHOOT_Y_PROPERTY_NAME : Toolkit::ScrollView::SCROLL_OVERSHOOT_X_PROPERTY_NAME);
156 // make sure height is set, since we only create a constraint for image width
159 UpdatePropertyNotifications();
162 void ScrollOvershootEffectRipple::Remove( Scrollable& scrollable )
166 void ScrollOvershootEffectRipple::Reset()
170 void ScrollOvershootEffectRipple::UpdatePropertyNotifications()
172 float absOvershoot = fabsf(mOvershoot);
174 Actor self = mAttachedScrollView.Self();
175 // update overshoot increase notify
176 if( mOvershootIncreaseNotification )
178 self.RemovePropertyNotification( mOvershootIncreaseNotification );
179 mOvershootIncreaseNotification.Reset();
181 if( absOvershoot < MAX_OVERSHOOT_NOTIFY_AMOUNT )
183 float increaseStep = absOvershoot + OVERSHOOT_NOTIFY_STEP;
184 if( increaseStep > MAX_OVERSHOOT_NOTIFY_AMOUNT )
186 increaseStep = MAX_OVERSHOOT_NOTIFY_AMOUNT;
188 mOvershootIncreaseNotification = self.AddPropertyNotification( mOvershootProperty, OutsideCondition(-increaseStep, increaseStep) );
189 mOvershootIncreaseNotification.SetNotifyMode(PropertyNotification::NotifyOnTrue);
190 mOvershootIncreaseNotification.NotifySignal().Connect(this, &ScrollOvershootEffectRipple::OnOvershootNotification);
193 // update overshoot decrease notify
194 if( mOvershootDecreaseNotification )
196 self.RemovePropertyNotification( mOvershootDecreaseNotification );
197 mOvershootDecreaseNotification.Reset();
199 if( absOvershoot > MIN_OVERSHOOT_NOTIFY_AMOUNT )
201 float reduceStep = absOvershoot - OVERSHOOT_NOTIFY_STEP;
202 if( reduceStep < MIN_OVERSHOOT_NOTIFY_AMOUNT )
204 reduceStep = MIN_OVERSHOOT_NOTIFY_AMOUNT;
206 mOvershootDecreaseNotification = self.AddPropertyNotification( mOvershootProperty, InsideCondition(-reduceStep, reduceStep) );
207 mOvershootDecreaseNotification.SetNotifyMode(PropertyNotification::NotifyOnTrue);
208 mOvershootDecreaseNotification.NotifySignal().Connect(this, &ScrollOvershootEffectRipple::OnOvershootNotification);
212 void ScrollOvershootEffectRipple::SetOvershootEffectColor( const Vector4& color )
216 void ScrollOvershootEffectRipple::UpdateVisibility( bool visible )
220 void ScrollOvershootEffectRipple::OnOvershootNotification(PropertyNotification& source)
222 Actor self = mAttachedScrollView.Self();
223 mOvershoot = self.GetProperty<float>(mOvershootProperty);
224 SetOvershoot(mOvershoot, false);
225 UpdatePropertyNotifications();
228 void ScrollOvershootEffectRipple::SetOvershoot(float amount, bool animate)
232 void ScrollOvershootEffectRipple::OnOvershootAnimFinished(Animation& animation)
234 bool animateOff = false;
235 if( mAnimationStateFlags & AnimatingOut )
238 if( (mAnimationStateFlags & AnimateBack) )
242 mScrollOvershootAnimation.FinishedSignal().Disconnect( this, &ScrollOvershootEffectRipple::OnOvershootAnimFinished );
243 mScrollOvershootAnimation.Stop();
244 mScrollOvershootAnimation.Reset();
245 mAnimationStateFlags = 0;
248 SetOvershoot(0.0f, true);
252 ScrollOvershootEffectRipplePtr ScrollOvershootEffectRipple::New( bool vertical, Scrollable& scrollable )
254 return new ScrollOvershootEffectRipple(vertical, scrollable);
257 } // namespace Internal
259 } // namespace Toolkit