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