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