ScrollView - Store properties in local values for GetCurrentScrollPosition
[platform/core/uifw/dali-toolkit.git] / base / dali-toolkit / public-api / controls / scrollable / scroll-view / scroll-view.cpp
1 /*
2  * Copyright (c) 2014 Samsung Electronics Co., Ltd.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  *
16  */
17
18 #include <dali-toolkit/public-api/controls/scrollable/scrollable.h>
19 #include <dali-toolkit/public-api/controls/scrollable/scroll-view/scroll-view.h>
20 #include <dali-toolkit/internal/controls/scrollable/scroll-view/scroll-view-impl.h>
21
22 using namespace Dali;
23
24 namespace Dali
25 {
26
27 namespace Toolkit
28 {
29
30 ///////////////////////////////////////////////////////////////////////////////////////////////////
31 // RulerDomain
32 ///////////////////////////////////////////////////////////////////////////////////////////////////
33
34 RulerDomain::RulerDomain(float min, float max, bool enabled)
35 : min(min),
36   max(max),
37   enabled(enabled)
38 {
39 }
40
41 float RulerDomain::Clamp(float x, float length, float scale) const
42 {
43   ClampState clamped;
44
45   return Clamp(x, length, scale, clamped);
46 }
47
48 float RulerDomain::Clamp(float x, float length, float scale, ClampState &clamped) const
49 {
50   if(!enabled)
51   {
52     clamped = NotClamped;
53     return x;
54   }
55
56   const float minExtent = min * scale;
57   const float maxExtent = max * scale - length;
58   if(x < minExtent)
59   {
60     clamped = ClampedToMin;
61     return minExtent;
62   }
63   else if(x > maxExtent)
64   {
65     clamped = ClampedToMax;
66     return maxExtent;
67   }
68
69   clamped = NotClamped;
70   return x;
71 }
72
73 float RulerDomain::GetSize() const
74 {
75   return max-min;
76 }
77
78 ///////////////////////////////////////////////////////////////////////////////////////////////////
79 // Ruler
80 ///////////////////////////////////////////////////////////////////////////////////////////////////
81
82 Ruler::Ruler()
83 : mType(Free),
84   mEnabled(true),
85   mDomain(RulerDomain(0.0f,1.0f,false))
86 {
87 }
88
89 Ruler::~Ruler()
90 {
91 }
92
93 Ruler::RulerType Ruler::GetType() const
94 {
95   return mType;
96 }
97
98 bool Ruler::IsEnabled() const
99 {
100   return mEnabled;
101 }
102
103 void Ruler::Enable()
104 {
105   mEnabled = true;
106 }
107
108 void Ruler::Disable()
109 {
110   mEnabled = false;
111 }
112
113 void Ruler::SetDomain(RulerDomain domain)
114 {
115   mDomain = domain;
116 }
117
118 const RulerDomain &Ruler::GetDomain() const
119 {
120   return mDomain;
121 }
122
123 void Ruler::DisableDomain()
124 {
125   mDomain = RulerDomain(0.0f,1.0f,false);
126 }
127
128 float Ruler::Clamp(float x, float length, float scale) const
129 {
130   return mDomain.Clamp(x, length, scale);
131 }
132
133 float Ruler::Clamp(float x, float length, float scale, ClampState &clamped) const
134 {
135   return mDomain.Clamp(x, length, scale, clamped);
136 }
137
138 float Ruler::SnapAndClamp(float x, float bias, float length, float scale) const
139 {
140   return Clamp(Snap(x, bias), length, scale);
141 }
142
143 float Ruler::SnapAndClamp(float x, float bias, float length, float scale, ClampState &clamped) const
144 {
145   return Clamp(Snap(x, bias), length, scale, clamped);
146 }
147
148 ///////////////////////////////////////////////////////////////////////////////////////////////////
149 // DefaultRuler
150 ///////////////////////////////////////////////////////////////////////////////////////////////////
151
152 DefaultRuler::DefaultRuler()
153 {
154   mType = Free;
155 }
156
157 float DefaultRuler::Snap(float x, float bias) const
158 {
159   return x;
160 }
161
162 float DefaultRuler::GetPositionFromPage(unsigned int page, unsigned int &volume, bool wrap) const
163 {
164   volume = 0;
165   return 0.0f;
166 }
167
168 unsigned int DefaultRuler::GetPageFromPosition(float position, bool wrap) const
169 {
170   return 0;
171 }
172
173 unsigned int DefaultRuler::GetTotalPages() const
174 {
175   return 1;
176 }
177
178 ///////////////////////////////////////////////////////////////////////////////////////////////////
179 // FixedRuler
180 ///////////////////////////////////////////////////////////////////////////////////////////////////
181
182 FixedRuler::FixedRuler(float spacing)
183 : mSpacing(spacing)
184 {
185   mType = Fixed;
186 }
187
188 float FixedRuler::Snap(float x, float bias) const
189 {
190   return floor(x / mSpacing + bias) * mSpacing;
191 }
192
193 float FixedRuler::GetPositionFromPage(unsigned int page, unsigned int &volume, bool wrap) const
194 {
195   float position = mDomain.min;
196
197   volume = 0;
198
199   // spacing must be present.
200   if(mEnabled && fabsf(mSpacing) > Math::MACHINE_EPSILON_1)
201   {
202     unsigned int column = page;
203
204     // In carry mode, a volume (carry) is produced when page exceeds limit within domain
205     if(wrap)
206     {
207       unsigned int pagesPerVolume = mDomain.GetSize() / mSpacing;
208       if(pagesPerVolume>0)
209       {
210         column += pagesPerVolume;
211         column %= pagesPerVolume;
212         volume = page/pagesPerVolume;
213       }
214     }
215
216     position = mDomain.min + column * mSpacing;
217   }
218   else  // Domain (or Spacing) is not present, carry page to volume.
219   {
220     if(wrap)
221     {
222       volume = page;
223     }
224   }
225
226   return position;
227 }
228
229 unsigned int FixedRuler::GetPageFromPosition(float position, bool wrap) const
230 {
231   unsigned int page = 0;
232
233   // spacing must be present.
234   if(mEnabled && fabsf(mSpacing) > Math::MACHINE_EPSILON_1)
235   {
236     if( wrap )
237     {
238       position = WrapInDomain(position, mDomain.min, mDomain.max);
239     }
240     page = floor((position - mDomain.min) / mSpacing + 0.5f);
241
242     if(wrap)
243     {
244       unsigned int pagesPerVolume = mDomain.GetSize() / mSpacing;
245       page %= pagesPerVolume;
246     }
247   }
248
249   return page;
250 }
251
252 unsigned int FixedRuler::GetTotalPages() const
253 {
254   unsigned int pagesPerVolume = 1;
255
256   // spacing must be present.
257   if(mEnabled && fabsf(mSpacing) > Math::MACHINE_EPSILON_1)
258   {
259     pagesPerVolume = mDomain.GetSize() / mSpacing;
260   }
261
262   return pagesPerVolume;
263 }
264
265 ///////////////////////////////////////////////////////////////////////////////////////////////////
266 // ScrollView
267 ///////////////////////////////////////////////////////////////////////////////////////////////////
268
269 const std::string ScrollView::SCROLL_PAGE_CURRENT( "scroll-page-current" );
270 const std::string ScrollView::SCROLL_TIME_PROPERTY_NAME( "scroll-time" );
271 const std::string ScrollView::SCROLL_POSITION_PROPERTY_NAME( "scroll-position" );
272 const std::string ScrollView::SCROLL_PRE_POSITION_PROPERTY_NAME( "scroll-pre-position" );
273 const std::string ScrollView::SCROLL_OVERSHOOT_X_PROPERTY_NAME( "scroll-overshoot-x" );
274 const std::string ScrollView::SCROLL_OVERSHOOT_Y_PROPERTY_NAME( "scroll-overshoot-y" );
275 const std::string ScrollView::SCROLL_FINAL_PROPERTY_NAME( "scroll-final" );
276 const std::string ScrollView::SCROLL_X_PROPERTY_NAME( "scroll-x" );
277 const std::string ScrollView::SCROLL_Y_PROPERTY_NAME( "scroll-y" );
278 const std::string ScrollView::SCROLL_SCALE_PROPERTY_NAME( "scroll-scale" );
279 const std::string ScrollView::SCROLL_WRAP_PROPERTY_NAME( "scroll-wrap" );
280 const std::string ScrollView::SCROLL_PANNING_PROPERTY_NAME( "scroll-panning" );
281 const std::string ScrollView::SCROLL_SCROLLING_PROPERTY_NAME( "scroll-scrolling" );
282 const std::string ScrollView::SCROLL_POSITION_DELTA_PROPERTY_NAME( "scroll-position-delta" );
283 const std::string ScrollView::SCROLL_START_PAGE_POSITION_PROPERTY_NAME( "scroll-start-page-position" );
284
285 const float ScrollView::DEFAULT_SLOW_SNAP_ANIMATION_DURATION(0.5f);
286 const float ScrollView::DEFAULT_FAST_SNAP_ANIMATION_DURATION(0.25f);
287 const float ScrollView::DEFAULT_SNAP_OVERSHOOT_DURATION(0.5f);
288 const float ScrollView::DEFAULT_MAX_OVERSHOOT(100.0f);  // 100 pixels
289
290 const float ScrollView::DEFAULT_AXIS_AUTO_LOCK_GRADIENT(0.36f);
291 const float ScrollView::DEFAULT_FRICTION_COEFFICIENT(1.0f);
292 const float ScrollView::DEFAULT_FLICK_SPEED_COEFFICIENT(1.0f);
293 const float ScrollView::DEFAULT_MAX_FLICK_SPEED(3.0f);
294
295 const char* const ScrollView::SIGNAL_SNAP_STARTED = "snap-started";
296
297 ScrollView::ScrollView()
298 {
299 }
300
301 ScrollView::ScrollView(Internal::ScrollView& implementation)
302 : Scrollable(implementation)
303 {
304 }
305
306 ScrollView::ScrollView( Dali::Internal::CustomActor* internal )
307 : Scrollable( internal )
308 {
309   VerifyCustomActorPointer<Internal::ScrollView>(internal);
310 }
311
312 ScrollView::ScrollView( const ScrollView& handle )
313 : Scrollable( handle )
314 {
315 }
316
317 ScrollView& ScrollView::operator=( const ScrollView& handle )
318 {
319   if( &handle != this )
320   {
321     Control::operator=( handle );
322   }
323   return *this;
324 }
325
326 ScrollView ScrollView::New()
327 {
328   return Internal::ScrollView::New();
329 }
330
331 ScrollView::~ScrollView()
332 {
333 }
334
335 ScrollView ScrollView::DownCast( BaseHandle handle )
336 {
337   return Control::DownCast<ScrollView, Internal::ScrollView>(handle);
338 }
339
340 AlphaFunction ScrollView::GetScrollSnapAlphaFunction() const
341 {
342   return GetImpl(*this).GetScrollSnapAlphaFunction();
343 }
344
345 void ScrollView::SetScrollSnapAlphaFunction(AlphaFunction alpha)
346 {
347   GetImpl(*this).SetScrollSnapAlphaFunction(alpha);
348 }
349
350 AlphaFunction ScrollView::GetScrollFlickAlphaFunction() const
351 {
352   return GetImpl(*this).GetScrollFlickAlphaFunction();
353 }
354
355 void ScrollView::SetScrollFlickAlphaFunction(AlphaFunction alpha)
356 {
357   GetImpl(*this).SetScrollFlickAlphaFunction(alpha);
358 }
359
360 float ScrollView::GetScrollSnapDuration() const
361 {
362   return GetImpl(*this).GetScrollSnapDuration();
363 }
364
365 void ScrollView::SetScrollSnapDuration(float time)
366 {
367   GetImpl(*this).SetScrollSnapDuration(time);
368 }
369
370 float ScrollView::GetScrollFlickDuration() const
371 {
372   return GetImpl(*this).GetScrollFlickDuration();
373 }
374
375 void ScrollView::SetScrollFlickDuration(float time)
376 {
377   GetImpl(*this).SetScrollFlickDuration(time);
378 }
379
380 void ScrollView::SetRulerX(RulerPtr ruler)
381 {
382   GetImpl(*this).SetRulerX(ruler);
383 }
384
385 void ScrollView::SetRulerY(RulerPtr ruler)
386 {
387   GetImpl(*this).SetRulerY(ruler);
388 }
389
390 void ScrollView::SetRulerScaleX(RulerPtr ruler)
391 {
392   GetImpl(*this).SetRulerScaleX(ruler);
393 }
394
395 void ScrollView::SetRulerScaleY(RulerPtr ruler)
396 {
397   GetImpl(*this).SetRulerScaleY(ruler);
398 }
399
400 void ScrollView::SetScrollSensitive(bool sensitive)
401 {
402   GetImpl(*this).SetScrollSensitive(sensitive);
403 }
404
405 void ScrollView::SetMaxOvershoot(float overshootX, float overshootY)
406 {
407   GetImpl(*this).SetMaxOvershoot(overshootX, overshootY);
408 }
409
410 void ScrollView::SetSnapOvershootAlphaFunction(AlphaFunction alpha)
411 {
412   GetImpl(*this).SetSnapOvershootAlphaFunction(alpha);
413 }
414
415 void ScrollView::SetSnapOvershootDuration(float duration)
416 {
417   GetImpl(*this).SetSnapOvershootDuration(duration);
418 }
419
420 void ScrollView::SetTouchesRequiredForPanning(unsigned int minTouches, unsigned int maxTouches, bool endOutside)
421 {
422   GetImpl(*this).SetTouchesRequiredForPanning(minTouches, maxTouches, endOutside);
423 }
424
425 void ScrollView::SetActorAutoSnap(bool enable)
426 {
427   GetImpl(*this).SetActorAutoSnap(enable);
428 }
429
430 void ScrollView::SetWrapMode(bool enable)
431 {
432   GetImpl(*this).SetWrapMode(enable);
433 }
434
435 int ScrollView::GetRefreshInterval() const
436 {
437   return GetImpl(*this).GetRefreshInterval();
438 }
439
440 void ScrollView::SetRefreshInterval(int milliseconds)
441 {
442   GetImpl(*this).SetRefreshInterval(milliseconds);
443 }
444
445 int ScrollView::GetScrollUpdateDistance() const
446 {
447   return GetImpl(*this).GetScrollUpdateDistance();
448 }
449
450 void ScrollView::SetScrollUpdateDistance(int distance)
451 {
452   GetImpl(*this).SetScrollUpdateDistance(distance);
453 }
454
455 bool ScrollView::GetAxisAutoLock() const
456 {
457   return GetImpl(*this).GetAxisAutoLock();
458 }
459
460 void ScrollView::SetAxisAutoLock(bool enable)
461 {
462   GetImpl(*this).SetAxisAutoLock(enable);
463 }
464
465 float ScrollView::GetAxisAutoLockGradient() const
466 {
467   return GetImpl(*this).GetAxisAutoLockGradient();
468 }
469
470 void ScrollView::SetAxisAutoLockGradient(float gradient)
471 {
472   GetImpl(*this).SetAxisAutoLockGradient(gradient);
473 }
474
475 float ScrollView::GetFrictionCoefficient() const
476 {
477   return GetImpl(*this).GetFrictionCoefficient();
478 }
479
480 void ScrollView::SetFrictionCoefficient(float friction)
481 {
482   GetImpl(*this).SetFrictionCoefficient(friction);
483 }
484
485 float ScrollView::GetFlickSpeedCoefficient() const
486 {
487   return GetImpl(*this).GetFlickSpeedCoefficient();
488 }
489
490 void ScrollView::SetFlickSpeedCoefficient(float speed)
491 {
492   GetImpl(*this).SetFlickSpeedCoefficient(speed);
493 }
494
495 float ScrollView::GetMaxFlickSpeed() const
496 {
497   return GetImpl(*this).GetMaxFlickSpeed();
498 }
499
500 void ScrollView::SetMaxFlickSpeed(float speed)
501 {
502   GetImpl(*this).SetMaxFlickSpeed(speed);
503 }
504
505 Vector2 ScrollView::GetMouseWheelScrollDistanceStep() const
506 {
507   return GetImpl(*this).GetMouseWheelScrollDistanceStep();
508 }
509
510 void ScrollView::SetMouseWheelScrollDistanceStep(Vector2 step)
511 {
512   GetImpl(*this).SetMouseWheelScrollDistanceStep(step);
513 }
514
515 Vector3 ScrollView::GetCurrentScrollPosition() const
516 {
517   return GetImpl(*this).GetCurrentScrollPosition();
518 }
519
520 void ScrollView::SetScrollPosition(const Vector3& position)
521 {
522   GetImpl(*this).SetScrollPosition(position);
523 }
524
525 Vector3 ScrollView::GetCurrentScrollScale() const
526 {
527   return GetImpl(*this).GetCurrentScrollScale();
528 }
529
530 unsigned int ScrollView::GetCurrentPage() const
531 {
532   return GetImpl(*this).GetCurrentPage();
533 }
534
535 void ScrollView::TransformTo(const Vector3& position, const Vector3& scale, float rotation)
536 {
537   GetImpl(*this).TransformTo(position, scale, rotation);
538 }
539
540 void ScrollView::TransformTo(const Vector3& position, const Vector3& scale, float rotation, float duration)
541 {
542   GetImpl(*this).TransformTo(position, scale, rotation, duration);
543 }
544
545 void ScrollView::ScrollTo(const Vector3 &position)
546 {
547   GetImpl(*this).ScrollTo(position);
548 }
549
550 void ScrollView::ScrollTo(const Vector3 &position, float duration)
551 {
552   GetImpl(*this).ScrollTo(position, duration);
553 }
554
555 void ScrollView::ScrollTo(const Vector3 &position, float duration,
556                           DirectionBias horizontalBias, DirectionBias verticalBias)
557 {
558   GetImpl(*this).ScrollTo(position, duration, horizontalBias, verticalBias);
559 }
560
561 void ScrollView::ScrollTo(unsigned int page)
562 {
563   GetImpl(*this).ScrollTo(page);
564 }
565
566 void ScrollView::ScrollTo(unsigned int page, float duration)
567 {
568   GetImpl(*this).ScrollTo(page, duration);
569 }
570
571 void ScrollView::ScrollTo(unsigned int page, float duration, DirectionBias bias)
572 {
573   GetImpl(*this).ScrollTo(page, duration, bias);
574 }
575
576 void ScrollView::ScrollTo(Actor &actor)
577 {
578   GetImpl(*this).ScrollTo(actor);
579 }
580
581 void ScrollView::ScrollTo(Actor &actor, float duration)
582 {
583   GetImpl(*this).ScrollTo(actor, duration);
584 }
585
586 bool ScrollView::ScrollToSnapPoint()
587 {
588   return GetImpl(*this).ScrollToSnapPoint();
589 }
590
591 void ScrollView::ScaleTo(const Vector3 &scale)
592 {
593   GetImpl(*this).ScaleTo(scale);
594 }
595
596 void ScrollView::ScaleTo(const Vector3 &scale, float duration)
597 {
598   GetImpl(*this).ScaleTo(scale, duration);
599 }
600
601 void ScrollView::ApplyConstraintToChildren(Constraint constraint)
602 {
603   GetImpl(*this).ApplyConstraintToChildren(constraint);
604 }
605
606 void ScrollView::RemoveConstraintsFromChildren()
607 {
608   GetImpl(*this).RemoveConstraintsFromChildren();
609 }
610
611 void ScrollView::ApplyEffect(ScrollViewEffect effect)
612 {
613   GetImpl(*this).ApplyEffect(effect);
614 }
615
616 ScrollViewEffect ScrollView::ApplyEffect(ScrollView::PageEffect effect)
617 {
618   return GetImpl(*this).ApplyEffect(effect);
619 }
620
621 void ScrollView::RemoveEffect(ScrollViewEffect effect)
622 {
623   GetImpl(*this).RemoveEffect(effect);
624 }
625
626 void ScrollView::RemoveAllEffects()
627 {
628   GetImpl(*this).RemoveAllEffects();
629 }
630
631 void ScrollView::BindActor(Actor child)
632 {
633   GetImpl(*this).BindActor(child);
634 }
635
636 void ScrollView::UnbindActor(Actor child)
637 {
638   GetImpl(*this).UnbindActor(child);
639 }
640
641 ScrollView::SnapStartedSignalV2& ScrollView::SnapStartedSignal()
642 {
643   return GetImpl(*this).SnapStartedSignal();
644 }
645
646 void ScrollView::SetScrollingDirection( Radian direction, Radian threshold )
647 {
648   GetImpl(*this).SetScrollingDirection( direction, threshold );
649 }
650
651 void ScrollView::RemoveScrollingDirection( Radian direction )
652 {
653   GetImpl(*this).RemoveScrollingDirection( direction );
654 }
655
656 } // namespace Toolkit
657
658 } // namespace Dali