add patch
[framework/osp/uifw.git] / src / ui / controls / FUiCtrl_ScrollPanelPresenter.cpp
1 //
2 // Open Service Platform
3 // Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0/
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17
18 /**
19  * @file        FUiCtrl_ScrollPanelPresenter.cpp
20  * @brief       This is the implementation file for the %_ScrollPanelPresenter class.
21  *
22  */
23
24 #include <FBaseCol.h>
25 #include <FBaseErrorDefine.h>
26 #include <FBaseRtTimer.h>
27 #include <FBaseUtilMath.h>
28 #include <FBaseSysLog.h>
29 #include <FUiAnimVisualElementValueAnimation.h>
30 #include "FUi_Math.h"
31 #include "FUi_ResourceManager.h"
32 #include "FUi_UiTouchEvent.h"
33 #include "FUi_IAccessibilityListener.h"
34 #include "FUi_AccessibilityContainer.h"
35 #include "FUi_AccessibilityElement.h"
36 #include "FUiAnim_VisualElement.h"
37 #include "FUiCtrl_Scroll.h"
38 #include "FUiCtrl_ScrollPanelImpl.h"
39 #include "FUiCtrl_ScrollPanelPresenter.h"
40 #include "FUiCtrl_ScrollPanelModel.h"
41
42 using namespace Tizen::Base;
43 using namespace Tizen::Graphics;
44 using namespace Tizen::Ui::Animations;
45
46 namespace
47 {
48 static const float SCROLL_PANEL_OVERSCROLLING_MAX_DISTANCCE = 100.0f;
49 static const float SCROLL_PANEL_FIXED_FLICK_AMOUNT = 1000.0f;
50
51 static const int SCROLL_PANEL_SCROLLING_ANIMATION_DURATION = 1000;
52 static const int SCROLL_PANEL_SCROLL_BAR_LOAD_EFFECT_TIMER_DURATION = 1000;
53
54 static const String SCROLLING_ANIMATION_NAME(L"SCROLL_PANEL_SCROLLING_ANIMATION");
55 }
56
57 namespace Tizen { namespace Ui { namespace Controls
58 {
59
60 _ScrollPanelPresenter::_ScrollPanelPresenter(void)
61         : __pScrollPanel(null)
62         , __pScrollPanelModel(null)
63         , __limitAnimationDistance(0.0f)
64         , __pPressedControl(null)
65         , __subControlMoved(false)
66         , __touchPressed(false)
67         , __scrollOccured(false)
68         , __modelUpdating(false)
69         , __scrollAnimationRunning(false)
70         , __flickRunning(false)
71         , __pScrollBarLoadEffectTimer(null)
72         , __scrollBarLoadEffectStatus(_SCROLL_PANEL_SCROLL_BAR_LOAD_EFFECT_UNLOAD)
73         , __firstDrawn(false)
74         , __firstTouchMove(true)
75         , __firstScrollMoveDirection(SCROLL_PANEL_SCROLL_DIRECTION_VERTICAL)
76         , __jumpToTopRunning(false)
77 {
78         // nothing
79 }
80
81 _ScrollPanelPresenter::~_ScrollPanelPresenter(void)
82 {
83         delete __pScrollBarLoadEffectTimer;
84         __pScrollBarLoadEffectTimer = null;
85
86         delete __pScrollPanelModel;
87         __pScrollPanelModel = null;
88 }
89
90 result
91 _ScrollPanelPresenter::Initialize(_ScrollPanel& scrollPanel)
92 {
93         result r = _PanelPresenter::Initialize(scrollPanel);
94         SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
95
96         __pScrollPanel = &scrollPanel;
97
98         // create model
99         _ScrollPanelModel* pModel = new (std::nothrow) _ScrollPanelModel;
100         SysTryReturn(NID_UI_CTRL, pModel != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] The memory is insufficient", GetErrorMessage(E_OUT_OF_MEMORY));
101
102         __pScrollPanelModel = pModel;
103
104         return E_SUCCESS;
105 }
106
107 result
108 _ScrollPanelPresenter::Draw(void)
109 {
110
111         if (!__firstDrawn)
112         {
113                 if (__scrollBarLoadEffectStatus == _SCROLL_PANEL_SCROLL_BAR_LOAD_EFFECT_LOADING)
114                 {
115                         DoScrollBarLoadEffect();
116                 }
117
118                 __firstDrawn = true;
119         }
120
121         if (__pScrollPanel->GetBackgroundBitmap() == null)
122         {
123                 return E_SUCCESS;
124         }
125
126         Canvas* pCanvas = __pScrollPanel->GetVisualElement()->GetCanvasN();
127         result r = GetLastResult();
128         SysTryReturn(NID_UI_CTRL, pCanvas != null, r, r, "[%s] Propagating.", GetErrorMessage(r));
129         SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
130
131         pCanvas->SetBackgroundColor(Color(0, 0, 0, 0));
132         r = GetLastResult();
133         SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
134
135         r = pCanvas->Clear();
136         SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
137
138         DrawBackgrounBitmap(pCanvas);
139         r = GetLastResult();
140         SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
141
142         // fall throw
143 CATCH:
144         delete pCanvas;
145
146         return r;
147 }
148
149 result
150 _ScrollPanelPresenter::OnBoundsChanging(const FloatRectangle& bounds)
151 {
152         if (__scrollAnimationRunning)
153         {
154                 StopScrollingAnimation();
155         }
156
157         if (!__modelUpdating)
158         {
159                 __modelUpdating = true;
160                 __previousBounds = __pScrollPanel->GetBoundsF();
161                 __previousScrollAreaBounds = GetScrollAreaBounds();
162         }
163
164         return E_SUCCESS;
165 }
166
167 void
168 _ScrollPanelPresenter::OnBoundsChanged(void)
169 {
170         AdjustModel();
171 }
172
173 void
174 _ScrollPanelPresenter::OnChildAttached(const _Control& child)
175 {
176         if (child.GetArea() != _CONTROL_AREA_SYSTEM)
177         {
178                 if (__pScrollPanel->IsScrollAreaAutoResizingEnabled())
179                 {
180                         UpdateLayout();
181
182                         if (!__modelUpdating)
183                         {
184                                 __modelUpdating = true;
185                                 __previousBounds = __pScrollPanel->GetBoundsF();
186                                 __previousScrollAreaBounds = GetScrollAreaBounds();
187                         }
188                         AdjustModel();
189                 }
190
191                 _AccessibilityContainer* pChildAccessibilityContainer = (const_cast<_Control&>(child)).GetAccessibilityContainer();
192                 pChildAccessibilityContainer->AddListener(*__pScrollPanel);
193         }
194
195 }
196
197 void
198 _ScrollPanelPresenter::OnChildDetached(const _Control& child)
199 {
200         if (child.GetArea() != _CONTROL_AREA_SYSTEM)
201         {
202                 if (__pScrollPanel->IsScrollAreaAutoResizingEnabled())
203                 {
204                         UpdateLayout();
205
206                         if (!__modelUpdating)
207                         {
208                                 __modelUpdating = true;
209                                 __previousBounds = __pScrollPanel->GetBoundsF();
210                                 __previousScrollAreaBounds = GetScrollAreaBounds();
211                         }
212                         AdjustModel();
213                 }
214
215                 _AccessibilityContainer* pChildAccessibilityContainer = (const_cast<_Control&>(child)).GetAccessibilityContainer();
216                 pChildAccessibilityContainer->RemoveListener(*__pScrollPanel);
217         }
218
219 }
220
221 void
222 _ScrollPanelPresenter::OnChildBoundsChanged(const _Control& child)
223 {
224         if (child.GetArea() != _CONTROL_AREA_SYSTEM)
225         {
226                 if (__pScrollPanel->IsScrollAreaAutoResizingEnabled())
227                 {
228                         if (!__modelUpdating)
229                         {
230                                 __modelUpdating = true;
231                                 __previousBounds = __pScrollPanel->GetBoundsF();
232                                 __previousScrollAreaBounds = GetScrollAreaBounds();
233                         }
234                         AdjustModel();
235                 }
236         }
237 }
238
239 void
240 _ScrollPanelPresenter::SetScrollPosition(FloatPoint position, bool withAnimation)
241 {
242         if (__pScrollPanel->GetScrollDirection() == SCROLL_PANEL_SCROLL_DIRECTION_HORIZONTAL)
243         {
244                 SetScrollPosition(position.x, withAnimation);
245         }
246         else
247         {
248                 SetScrollPosition(position.y, withAnimation);
249         }
250 }
251
252 void
253 _ScrollPanelPresenter::SetScrollPosition(float position, bool withAnimation)
254 {
255         // change scroll position
256         if (withAnimation)
257         {
258                 FadeInScrollBar();
259                 result r = GetLastResult();
260                 SysTryReturnVoidResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
261         }
262
263         position = FixScrollPositionIntoScrollAreaBounds(position);
264         ScrollTo(position, withAnimation);
265         result r = GetLastResult();
266         SysTryReturnVoidResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
267 }
268
269 float
270 _ScrollPanelPresenter::GetScrollPosition(void) const
271 {
272         float scrollPosition = GetScrollPositionInternal();
273         return FixScrollPositionIntoScrollAreaBounds(scrollPosition);
274 }
275
276 float
277 _ScrollPanelPresenter::GetVerticalScrollPosition(void) const
278 {
279         float scrollPosition = GetVerticalScrollPositionInternal();
280         return FixScrollPositionIntoScrollAreaBounds(scrollPosition);
281 }
282
283 void
284 _ScrollPanelPresenter::SetVerticalScrollPosition(float position)
285 {
286         SetScrollPosition(position, true);
287 }
288
289 float
290 _ScrollPanelPresenter::GetHorizontalScrollPosition(void) const
291 {
292         float scrollPosition = GetHorizontalScrollPositionInternal();
293         return FixScrollPositionIntoScrollAreaBounds(scrollPosition);
294 }
295
296 void
297 _ScrollPanelPresenter::SetHorizontalScrollPosition(float position)
298 {
299         SetScrollPosition(position, true);
300 }
301
302 float
303 _ScrollPanelPresenter::GetScrollPositionInternal(void) const
304 {
305         ScrollPanelScrollDirection scrollDirection = __pScrollPanel->GetScrollDirection();
306
307         if (scrollDirection == SCROLL_PANEL_SCROLL_DIRECTION_HORIZONTAL)
308         {
309                 return GetHorizontalScrollPositionInternal();
310         }
311         else
312         {
313                 return GetVerticalScrollPositionInternal();
314         }
315 }
316
317 void
318 _ScrollPanelPresenter::SetScrollPositionInternal(float position)
319 {
320         ScrollPanelScrollDirection scrollDirection = __pScrollPanel->GetScrollDirection();
321         if (scrollDirection == SCROLL_PANEL_SCROLL_DIRECTION_HORIZONTAL)
322         {
323                 SetHorizontalScrollPositionInternal(position);
324         }
325         else
326         {
327                 SetVerticalScrollPositionInternal(position);
328         }
329 }
330
331 float
332 _ScrollPanelPresenter::GetVerticalScrollPositionInternal(void) const
333 {
334         return __pScrollPanelModel->GetCurrentVerticalScrollPosition();
335 }
336
337 void
338 _ScrollPanelPresenter::SetVerticalScrollPositionInternal(float position)
339 {
340         __pScrollPanelModel->SetCurrentVerticalScrollPosition(position);
341 }
342
343 float
344 _ScrollPanelPresenter::GetHorizontalScrollPositionInternal(void) const
345 {
346         return __pScrollPanelModel->GetCurrentHorizontalScrollPosition();
347 }
348
349 void
350 _ScrollPanelPresenter::SetHorizontalScrollPositionInternal(float position)
351 {
352         __pScrollPanelModel->SetCurrentHorizontalScrollPosition(position);
353 }
354
355 void
356 _ScrollPanelPresenter::StopScrollingAnimation(void)
357 {
358         __scrollAnimationRunning = false;
359         __pScrollPanel->GetVisualElement()->RemoveAnimation(SCROLLING_ANIMATION_NAME);
360 }
361
362 float
363 _ScrollPanelPresenter::FixScrollPositionIntoScrollAreaBounds(float position) const
364 {
365         return FixScrollPositionIntoScrollAreaBounds(position, __pScrollPanel->GetBoundsF(), GetScrollAreaBounds());
366 }
367
368 float
369 _ScrollPanelPresenter::FixScrollPositionIntoScrollAreaBounds(float position, FloatRectangle bounds, FloatRectangle scrollArea) const
370 {
371         float minScrollPosition = 0.0f;
372         float maxScrollPosition = 0.0f;
373         if (__pScrollPanel->GetScrollDirection() == SCROLL_PANEL_SCROLL_DIRECTION_HORIZONTAL)
374         {
375                 minScrollPosition = scrollArea.x;
376                 maxScrollPosition = scrollArea.x + scrollArea.width - bounds.width;
377         }
378         else
379         {
380                 minScrollPosition = scrollArea.y;
381                 maxScrollPosition = scrollArea.y + scrollArea.height - bounds.height;
382         }
383
384         if (minScrollPosition > maxScrollPosition)
385         {
386                 maxScrollPosition = minScrollPosition;
387         }
388         if (position < minScrollPosition)
389         {
390                 position = minScrollPosition;
391         }
392         if (position > maxScrollPosition)
393         {
394                 position = maxScrollPosition;
395         }
396
397         return position;
398 }
399
400 void
401 _ScrollPanelPresenter::ScrollToTop(void)
402 {
403         SetVerticalScrollPosition(GetScrollAreaBounds().y);
404 }
405
406 void
407 _ScrollPanelPresenter::ScrollToBottom(void)
408 {
409         SetVerticalScrollPosition(GetScrollAreaBounds().height - __pScrollPanel->GetBoundsF().height);
410 }
411
412 void
413 _ScrollPanelPresenter::ScrollToLeft(void)
414 {
415         SetHorizontalScrollPosition(GetScrollAreaBounds().x);
416 }
417
418 void
419 _ScrollPanelPresenter::ScrollToRight(void)
420 {
421         SetHorizontalScrollPosition(GetScrollAreaBounds().width - __pScrollPanel->GetBoundsF().width);
422 }
423
424 result
425 _ScrollPanelPresenter::RunTouchPressed(const _Control& source, const _TouchInfo& touchInfo)
426 {
427         // stop flick, stop scroll animation
428         if (__flickRunning || __scrollAnimationRunning)
429         {
430                 if (!__jumpToTopRunning)
431                 {
432                         StopScrollingAnimation();
433                 }
434
435                 __jumpToTopRunning = false;
436         }
437
438         __currentMovedPosition = FloatPoint(touchInfo.GetCurrentPosition().x, touchInfo.GetCurrentPosition().y);
439         __previousTouchedPosition = __currentMovedPosition;
440         __pPressedControl = &(const_cast<_Control&>(source));
441         __subControlMoved = false;
442         __touchPressed = true;
443         __firstTouchMove = true;
444
445         return E_SUCCESS;
446 }
447
448 result
449 _ScrollPanelPresenter::RunPreviewTouchMoved(const _Control& source, const _TouchInfo& touchInfo)
450 {
451         if (__pPressedControl == &source && __touchPressed)
452         {
453                 __previousTouchedPosition = __currentMovedPosition;
454                 __currentMovedPosition = FloatPoint(touchInfo.GetCurrentPosition().x, touchInfo.GetCurrentPosition().y);
455
456                 if (__pScrollPanel != &source)
457                 {
458                         __subControlMoved = true;
459                 }
460
461                 if (__firstTouchMove)
462                 {
463                         ScrollPanelScrollDirection scrollDirection = __pScrollPanel->GetScrollDirection();
464                         float scrollDistanceX = __previousTouchedPosition.x - __currentMovedPosition.x;
465                         float scrollDistanceY = __previousTouchedPosition.y - __currentMovedPosition.y;
466
467                         if (_Abs(scrollDistanceY) < _Abs(scrollDistanceX))
468                         {
469                                 __firstScrollMoveDirection = SCROLL_PANEL_SCROLL_DIRECTION_HORIZONTAL;
470                         }
471                         else if (_Abs(scrollDistanceY) > _Abs(scrollDistanceX))
472                         {
473                                 __firstScrollMoveDirection = SCROLL_PANEL_SCROLL_DIRECTION_VERTICAL;
474                         }
475                         else
476                         {
477                                 __firstScrollMoveDirection = scrollDirection;
478                         }
479
480                         __firstTouchMove = false;
481                 }
482         }
483
484         return E_SUCCESS;
485 }
486
487 result
488 _ScrollPanelPresenter::RunTouchReleased(const _Control& source, const _TouchInfo& touchInfo)
489 {
490         SysTryReturn(NID_UI_CTRL, __pPressedControl == &source, E_INVALID_OPERATION, E_INVALID_OPERATION, "[%s] source has changed during touch process.", GetErrorMessage(E_INVALID_OPERATION));
491
492         __touchPressed = false;
493         __firstTouchMove = true;
494
495         if (__pScrollPanel->IsPageScrollEnabled() && !__flickRunning && !__jumpToTopRunning)
496         {
497                 float currentPosition = GetScrollPosition();
498                 float targetPosition = CalculatePagingScrollPosition(currentPosition);
499
500                 if (targetPosition > currentPosition || targetPosition < currentPosition)
501                 {
502                         SetScrollPosition(targetPosition, true);
503                         result r = GetLastResult();
504                         SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
505                 }
506         }
507
508         // scrollpanel child control touch released
509         if (__pScrollPanel != &source)
510         {
511                 // for ScrollPanelEventListener
512                 if (__subControlMoved)
513                 {
514                         __pScrollPanel->FireScrollPanelEvent(source, CORE_OTHER_CONTROL_SELECTED);
515                 }
516         }
517
518         __pPressedControl = null;
519         __subControlMoved = false;
520
521         if (!__scrollAnimationRunning)
522         {
523                 RollbackBouncing(true);
524                 result r = GetLastResult();
525                 SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
526
527                 FadeOutScrollBar();
528                 r = GetLastResult();
529                 SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
530
531                 if (__scrollOccured)
532                 {
533                         __scrollOccured = false;
534                         __pScrollPanel->FireOnScrollStoppedEvent();
535                 }
536         }
537
538         return E_SUCCESS;
539 }
540
541 result
542 _ScrollPanelPresenter::RunTouchCanceled(const _Control& source, const _TouchInfo& touchinfo)
543 {
544         SysTryReturn(NID_UI_CTRL, __pPressedControl == &source, E_INVALID_OPERATION, E_INVALID_OPERATION, "[%s] source has changed during touch process.", GetErrorMessage(E_INVALID_OPERATION));
545
546         __touchPressed = false;
547         __firstTouchMove = true;
548
549         __pPressedControl = null;
550         __subControlMoved = false;
551
552         if (!__scrollAnimationRunning)
553         {
554                 RollbackBouncing(true);
555                 result r = GetLastResult();
556                 SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
557
558                 FadeOutScrollBar();
559                 r = GetLastResult();
560                 SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
561         }
562
563         if (__scrollOccured && !__scrollAnimationRunning)
564         {
565                 __scrollOccured = false;
566                 __pScrollPanel->FireOnScrollStoppedEvent();
567         }
568
569         return E_SUCCESS;
570 }
571
572 _UiTouchEventDelivery
573 _ScrollPanelPresenter::OnPreviewTouchPressed(const _Control& source, const _TouchInfo& touchInfo)
574 {
575         return _UI_TOUCH_EVENT_DELIVERY_FORCED_YES;
576 }
577
578 _UiTouchEventDelivery
579 _ScrollPanelPresenter::OnPreviewTouchMoved(const _Control& source, const _TouchInfo& touchInfo)
580 {
581         RunPreviewTouchMoved(source, touchInfo);
582
583         return _UI_TOUCH_EVENT_DELIVERY_YES;
584 }
585
586 _UiTouchEventDelivery
587 _ScrollPanelPresenter::OnPreviewTouchReleased(const _Control& source, const _TouchInfo& touchInfo)
588 {
589         return _UI_TOUCH_EVENT_DELIVERY_FORCED_YES;
590 }
591
592 _UiTouchEventDelivery
593 _ScrollPanelPresenter::OnPreviewTouchCanceled(const _Control& source, const _TouchInfo& touchInfo)
594 {
595         return _UI_TOUCH_EVENT_DELIVERY_FORCED_YES;
596 }
597
598 bool
599 _ScrollPanelPresenter::OnTouchPressed(const _Control& source, const _TouchInfo& touchInfo)
600 {
601         result r = RunTouchPressed(source, touchInfo);
602         SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, true, r, "[%s] Propagating.", GetErrorMessage(r));
603
604         return true;
605 }
606
607 bool
608 _ScrollPanelPresenter::OnTouchMoved(const _Control& source, const _TouchInfo& touchInfo)
609 {
610         if (__pPressedControl != &source)
611         {
612                 return false;
613         }
614
615         if (!__touchPressed)
616         {
617                 return false;
618         }
619
620         if (!IsScrollable())
621         {
622                 return false;
623         }
624
625         FloatPoint touchPoint = FloatPoint(touchInfo.GetCurrentPosition().x, touchInfo.GetCurrentPosition().y);
626         if (!_FloatCompare(__currentMovedPosition.x, touchPoint.x)
627                 || !_FloatCompare(__currentMovedPosition.y, touchPoint.y))
628         {
629                 RunPreviewTouchMoved(source, touchInfo);
630         }
631
632         // calculate move distance
633         ScrollPanelScrollDirection scrollDirection = __pScrollPanel->GetScrollDirection();
634         ScrollInputMode scrollInputMode = __pScrollPanel->GetScrollInputMode();
635         float scrollDistance = 0.0f;
636         float scrollDistanceX = __previousTouchedPosition.x - __currentMovedPosition.x;
637         float scrollDistanceY = __previousTouchedPosition.y - __currentMovedPosition.y;
638
639         if (scrollInputMode == SCROLL_INPUT_MODE_RESTRICT_TO_INITIAL_DIRECTION)
640         {
641                 if (scrollDirection == __firstScrollMoveDirection)
642                 {
643                         if (scrollDirection == SCROLL_PANEL_SCROLL_DIRECTION_HORIZONTAL)
644                         {
645                                 scrollDistance = scrollDistanceX;
646                         }
647                         else if (scrollDirection == SCROLL_PANEL_SCROLL_DIRECTION_VERTICAL)
648                         {
649                                 scrollDistance = scrollDistanceY;
650                         }
651                 }
652                 else
653                 {
654                         RollbackBouncing(true);
655                         result r = GetLastResult();
656                         SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, false, r, "[%s] Propagating.", GetErrorMessage(r));
657
658                         FadeOutScrollBar();
659                         r = GetLastResult();
660                         SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, false, r, "[%s] Propagating.", GetErrorMessage(r));
661
662                         if ((__firstScrollMoveDirection == SCROLL_PANEL_SCROLL_DIRECTION_HORIZONTAL && _Abs(scrollDistanceY) > _Abs(scrollDistanceX))
663                                 || (__firstScrollMoveDirection == SCROLL_PANEL_SCROLL_DIRECTION_VERTICAL && _Abs(scrollDistanceY) < _Abs(scrollDistanceX)))
664                         {
665                                 return true;
666                         }
667                         else
668                         {
669                                 return false;
670                         }
671                 }
672         }
673         else
674         {
675                 if (scrollDirection == SCROLL_PANEL_SCROLL_DIRECTION_HORIZONTAL)
676                 {
677                         if (_Abs(scrollDistanceY) <= _Abs(scrollDistanceX))
678                         {
679                                 scrollDistance = scrollDistanceX;
680                         }
681                         else
682                         {
683                                 return false;
684                         }
685                 }
686                 else if (scrollDirection == SCROLL_PANEL_SCROLL_DIRECTION_VERTICAL)
687                 {
688                         if (_Abs(scrollDistanceY) >= _Abs(scrollDistanceX))
689                         {
690                                 scrollDistance = scrollDistanceY;
691                         }
692                         else
693                         {
694                                 return false;
695                         }
696                 }
697         }
698
699         if (!_FloatCompare(scrollDistance, 0.0f))
700         {
701                 FadeInScrollBar();
702                 result r = GetLastResult();
703                 SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, true, r, "[%s] Propagating.", GetErrorMessage(r));
704
705                 float realMoveDistance = ScrollTo(scrollDistance + GetScrollPositionInternal());
706                 r = GetLastResult();
707                 SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, false, r, "[%s] Propagating.", GetErrorMessage(r));
708
709                 if (_FloatCompare(realMoveDistance, 0.0f))
710                 {
711                         // not moved and bubbling
712                         if (scrollInputMode == SCROLL_INPUT_MODE_RESTRICT_TO_INITIAL_DIRECTION)
713                         {
714                                 if (scrollDirection == SCROLL_PANEL_SCROLL_DIRECTION_HORIZONTAL)
715                                 {
716                                         if (_Abs(scrollDistanceY) < _Abs(scrollDistanceX))
717                                         {
718                                                 return false;
719                                         }
720                                         else
721                                         {
722                                                 return true;
723                                         }
724                                 }
725                                 else if (scrollDirection == SCROLL_PANEL_SCROLL_DIRECTION_VERTICAL)
726                                 {
727                                         if (_Abs(scrollDistanceY) > _Abs(scrollDistanceX))
728                                         {
729                                                 return false;
730                                         }
731                                         else
732                                         {
733                                                 return true;
734                                         }
735                                 }
736                         }
737                         else
738                         {
739                                 return false;
740                         }
741                 }
742
743         }
744         else
745         {
746                 return true;
747         }
748
749         return true;
750 }
751
752 bool
753 _ScrollPanelPresenter::OnTouchReleased(const _Control& source, const _TouchInfo& touchInfo)
754 {
755         result r = RunTouchReleased(source, touchInfo);
756         SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, true, r, "[%s] Propagating.", GetErrorMessage(r));
757
758         return true;
759 }
760
761 bool
762 _ScrollPanelPresenter::OnTouchCanceled(const _Control& source, const _TouchInfo& touchInfo)
763 {
764         result r = RunTouchCanceled(source, touchInfo);
765         SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, true, r, "[%s] Propagating.", GetErrorMessage(r));
766
767         return true;
768 }
769
770 void
771 _ScrollPanelPresenter::OnTouchMoveHandled(const _Control& control)
772 {
773         RollbackBouncing(true);
774         result r = GetLastResult();
775         SysTryReturnVoidResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
776
777         FadeOutScrollBar();
778         r = GetLastResult();
779         SysTryReturnVoidResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
780 }
781
782 void
783 _ScrollPanelPresenter::OnScrollEndReached(_Control& source, ScrollEndEvent type)
784 {
785 }
786
787 void
788 _ScrollPanelPresenter::OnScrollPositionChanged(_Control& source, float scrollPosition)
789 {
790         if (&source != __pScrollPanel->GetScrollBar())
791         {
792                 return;
793         }
794
795         FadeInScrollBar();
796         result r = GetLastResult();
797         SysTryReturnVoidResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
798
799         SetScrollPosition(scrollPosition, false);
800 }
801
802 void
803 _ScrollPanelPresenter::OnScrollStopped(_Control& source)
804 {
805         if (&source != __pScrollPanel->GetScrollBar())
806         {
807                 return;
808         }
809
810         FadeOutScrollBar();
811         result r = GetLastResult();
812         SysTryReturnVoidResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
813 }
814
815 void
816 _ScrollPanelPresenter::OnScrollJumpToTop(_Control& source)
817 {
818         if (&source != __pScrollPanel->GetScrollBar())
819         {
820                 return;
821         }
822
823         __jumpToTopRunning = true;
824         SetScrollPosition(0, true);
825 }
826
827 bool
828 _ScrollPanelPresenter::DoFlickGestureRecognized(_TouchFlickGestureDetector& gesture)
829 {
830         if (!IsScrollable())
831         {
832                 return false;
833         }
834
835         FloatRectangle scrollArea = GetScrollAreaBounds();
836         FloatRectangle scrollPanelBounds = __pScrollPanel->GetBoundsF();
837
838         float distanceX = 0.0f;
839         float distanceY = 0.0f;
840         gesture.GetDistance(distanceX, distanceY);
841         _FlickDirection moveDirection = _FLICK_DIRECTION_NONE;
842
843         if (_Abs(distanceX) > _Abs(distanceY))
844         {
845                 if (distanceX < 0.0f)
846                 {
847                         moveDirection = _FLICK_DIRECTION_LEFT;
848                 }
849                 else if (distanceX > 0.0f)
850                 {
851                         moveDirection = _FLICK_DIRECTION_RIGHT;
852                 }
853         }
854         else
855         {
856                 if (distanceY < 0.0f)
857                 {
858                         moveDirection = _FLICK_DIRECTION_UP;
859                 }
860                 else if (distanceY > 0.0f)
861                 {
862                         moveDirection = _FLICK_DIRECTION_DOWN;
863                 }
864         }
865
866         if (__pScrollPanel->GetScrollDirection() == SCROLL_PANEL_SCROLL_DIRECTION_HORIZONTAL)
867         {
868                 if (moveDirection != _FLICK_DIRECTION_RIGHT && moveDirection != _FLICK_DIRECTION_LEFT)
869                 {
870                         return false;
871                 }
872         }
873         else
874         {
875                 if (moveDirection != _FLICK_DIRECTION_DOWN && moveDirection != _FLICK_DIRECTION_UP)
876                 {
877                         return false;
878                 }
879         }
880
881         if (__pScrollPanel->IsPageScrollEnabled() && __pScrollPanel->IsPageScrollFlickMoveLimitedOnePage())
882         {
883                 float currentScrollPosition = GetScrollPosition();
884                 float targetPosition = currentScrollPosition;
885
886                 if (__pScrollPanel->GetScrollDirection() == SCROLL_PANEL_SCROLL_DIRECTION_HORIZONTAL)
887                 {
888                         float pageSize = __pScrollPanel->GetPageScrollAlignSize().width;
889
890                         // to right page
891                         if (moveDirection == _FLICK_DIRECTION_LEFT)
892                         {
893                                 targetPosition = (((int)(currentScrollPosition / pageSize)) + 1) * pageSize;
894                         }
895                         // to left page
896                         else if (moveDirection == _FLICK_DIRECTION_RIGHT)
897                         {
898                                 targetPosition = ((int)(currentScrollPosition / pageSize)) * pageSize;
899                         }
900                 }
901                 else
902                 {
903                         float pageSize = __pScrollPanel->GetPageScrollAlignSize().height;
904
905                         // to down page
906                         if (moveDirection == _FLICK_DIRECTION_UP)
907                         {
908                                 targetPosition = (((int)(currentScrollPosition / pageSize)) + 1) * pageSize;
909                         }
910                         // to up page
911                         else if (moveDirection == _FLICK_DIRECTION_DOWN)
912                         {
913                                 targetPosition = ((int)(currentScrollPosition / pageSize)) * pageSize;
914                         }
915                 }
916
917                 targetPosition = FixScrollPositionIntoScrollAreaBounds(targetPosition);
918                 if (_FloatCompare(targetPosition, currentScrollPosition))
919                 {
920                         return false;
921                 }
922
923                 __flickRunning = true;
924
925                 ScrollTo(targetPosition, true);
926                 result r = GetLastResult();
927                 SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, false, r, "[%s] Propagating.", GetErrorMessage(r));
928
929                 FadeInScrollBar();
930                 r = GetLastResult();
931                 SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, false, r, "[%s] Propagating.", GetErrorMessage(r));
932
933                 return true;
934         }
935         else
936         {
937                 float moveAmount = 0.0f;
938                 float flickAmount = 0.0f;
939
940                 // calculate flick amount
941                 if (__pScrollPanel->GetScrollDirection() == SCROLL_PANEL_SCROLL_DIRECTION_HORIZONTAL)
942                 {
943                         flickAmount = CalculateFlickAmount(distanceX, gesture.GetDuration());
944                 }
945                 else
946                 {
947                         flickAmount = CalculateFlickAmount(distanceY, gesture.GetDuration());
948                 }
949
950                 moveAmount = -flickAmount;
951
952                 // page align
953                 if (__pScrollPanel->IsPageScrollEnabled())
954                 {
955                         float scrollPosition = 0.0f;
956                         float maxPosition = 0.0f;
957                         float pageSize = 0.0f;
958
959                         if (__pScrollPanel->GetScrollDirection() == SCROLL_PANEL_SCROLL_DIRECTION_HORIZONTAL)
960                         {
961                                 pageSize = __pScrollPanel->GetPageScrollAlignSize().width;
962                                 maxPosition = scrollArea.width - scrollPanelBounds.width;
963                                 scrollPosition = __pScrollPanelModel->GetCurrentHorizontalScrollPosition();
964                         }
965                         else
966                         {
967                                 pageSize = __pScrollPanel->GetPageScrollAlignSize().height;
968                                 maxPosition = scrollArea.height - scrollPanelBounds.height;
969                                 scrollPosition = __pScrollPanelModel->GetCurrentVerticalScrollPosition();
970                         }
971
972                         int lowerPageIndex = (scrollPosition + moveAmount) / pageSize;
973                         float targetPageMin = pageSize * lowerPageIndex;
974                         float pageGap = (scrollPosition + moveAmount) - targetPageMin;
975                         float targetPageMax = targetPageMin + pageSize;
976
977                         if (pageGap <= targetPageMax - targetPageMin - pageGap)
978                         {
979                                 moveAmount = targetPageMin - scrollPosition;
980                         }
981                         else
982                         {
983                                 moveAmount = targetPageMax - scrollPosition;
984                         }
985                 }
986
987                 if (!_FloatCompare(moveAmount, 0.0f))
988                 {
989                         // scroll with animation
990                         __flickRunning = true;
991
992                         if (AccumulateFlickGesture(moveDirection))
993                         {
994                                 return true;
995                         }
996
997                         // limited flick amount
998                         float targetPosition = moveAmount + GetScrollPositionInternal();
999                         float scrollToPosition = FixScrollPositionIntoScrollAreaBounds(targetPosition);
1000                         if (_Abs(scrollToPosition - targetPosition) > SCROLL_PANEL_OVERSCROLLING_MAX_DISTANCCE)
1001                         {
1002                                 switch (moveDirection)
1003                                 {
1004                                 case _FLICK_DIRECTION_UP:
1005                                         targetPosition = scrollArea.height - scrollPanelBounds.height + SCROLL_PANEL_OVERSCROLLING_MAX_DISTANCCE;
1006                                         break;
1007                                 case _FLICK_DIRECTION_DOWN:
1008                                         targetPosition = scrollArea.y - SCROLL_PANEL_OVERSCROLLING_MAX_DISTANCCE;
1009                                         break;
1010                                 case _FLICK_DIRECTION_LEFT:
1011                                         targetPosition = scrollArea.width - scrollPanelBounds.width + SCROLL_PANEL_OVERSCROLLING_MAX_DISTANCCE;
1012                                         break;
1013                                 case _FLICK_DIRECTION_RIGHT:
1014                                         targetPosition = scrollArea.x - SCROLL_PANEL_OVERSCROLLING_MAX_DISTANCCE;
1015                                         break;
1016                                 default:
1017                                         break;
1018                                 }
1019                         }
1020
1021                         FlickTo(targetPosition, gesture.GetDuration());
1022                         result r = GetLastResult();
1023                         SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, false, r, "[%s] Propagating.", GetErrorMessage(r));
1024
1025                         FadeInScrollBar();
1026                         r = GetLastResult();
1027                         SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, false, r, "[%s] Propagating.", GetErrorMessage(r));
1028
1029                         return true;
1030                 }
1031                 else
1032                 {
1033                         return false;
1034                 }
1035         }
1036 }
1037
1038 bool
1039 _ScrollPanelPresenter::OnFlickGestureDetected(_TouchFlickGestureDetector& gesture)
1040 {
1041         return DoFlickGestureRecognized(gesture);
1042 }
1043
1044 bool
1045 _ScrollPanelPresenter::OnFlickGestureCanceled(_TouchFlickGestureDetector& gesture)
1046 {
1047         StopScrollingAnimation();
1048         RollbackBouncing(true);
1049         result r = GetLastResult();
1050         SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, false, r, "[%s] Propagating.", GetErrorMessage(r));
1051
1052         return false;
1053 }
1054
1055 bool
1056 _ScrollPanelPresenter::IsControlOutOfView(const _Control& control) const
1057 {
1058         FloatRectangle controlBounds = control.GetAbsoluteBoundsF();
1059         FloatRectangle scrollPanelBounds = __pScrollPanel->GetAbsoluteBoundsF();
1060
1061         // is control out of view area
1062         if (__pScrollPanel->GetScrollDirection() == SCROLL_PANEL_SCROLL_DIRECTION_HORIZONTAL)
1063         {
1064                 if (controlBounds.x < scrollPanelBounds.x || controlBounds.x + controlBounds.width > scrollPanelBounds.x + scrollPanelBounds.width)
1065                 {
1066                         return true;
1067                 }
1068         }
1069         else
1070         {
1071                 if (controlBounds.y < scrollPanelBounds.y || controlBounds.y + controlBounds.height > scrollPanelBounds.y + scrollPanelBounds.height)
1072                 {
1073                         return true;
1074                 }
1075         }
1076
1077         return false;
1078 }
1079
1080 void
1081 _ScrollPanelPresenter::ScrollToControlWhenOutOfView(const _Control& control)
1082 {
1083         if (IsControlOutOfView(control))
1084         {
1085                 ScrollToControl(control, true);
1086                 result r = GetLastResult();
1087                 SysTryReturnVoidResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
1088         }
1089 }
1090
1091 float
1092 _ScrollPanelPresenter::CalculatePagingScrollPosition(float position) const
1093 {
1094         float maxPosition = 0.0f;
1095         float pageSize = 0.0f;
1096
1097         if (__pScrollPanel->GetScrollDirection() == SCROLL_PANEL_SCROLL_DIRECTION_HORIZONTAL)
1098         {
1099                 pageSize = __pScrollPanel->GetPageScrollAlignSize().width;
1100                 maxPosition = GetScrollAreaBounds().width - __pScrollPanel->GetBoundsF().width;
1101         }
1102         else
1103         {
1104                 pageSize = __pScrollPanel->GetPageScrollAlignSize().height;
1105                 maxPosition = GetScrollAreaBounds().height - __pScrollPanel->GetBoundsF().height;
1106         }
1107
1108         float targetPosition = 0.0f;
1109         int lowerPageIndex = position / pageSize;
1110         float currentPageMin = pageSize * lowerPageIndex;
1111         float pageGap = position - currentPageMin;
1112         float currentPageMax = currentPageMin + pageSize;
1113         if (currentPageMax > maxPosition)
1114         {
1115                 currentPageMax = maxPosition;
1116         }
1117
1118         if (pageGap <= currentPageMax - currentPageMin - pageGap)
1119         {
1120                 targetPosition = currentPageMin;
1121         }
1122         else
1123         {
1124                 targetPosition = currentPageMax;
1125         }
1126
1127         return targetPosition;
1128 }
1129
1130 void
1131 _ScrollPanelPresenter::RollbackBouncing(bool withAnimation)
1132 {
1133         if (!IsScrollable())
1134         {
1135                 return;
1136         }
1137
1138         float scrollPosition = GetScrollPositionInternal();
1139         float fixedScrollPosition = FixScrollPositionIntoScrollAreaBounds(scrollPosition);
1140
1141         // there are no rollbacking animation
1142         withAnimation = false;
1143
1144         if (!_FloatCompare(scrollPosition, fixedScrollPosition))
1145         {
1146                 FadeInScrollBar();
1147                 result r = GetLastResult();
1148                 SysTryReturnVoidResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
1149
1150                 ScrollTo(fixedScrollPosition, withAnimation);
1151                 r = GetLastResult();
1152                 SysTryReturnVoidResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
1153
1154                 if (!__scrollAnimationRunning)
1155                 {
1156                         FadeOutScrollBar();
1157                         r = GetLastResult();
1158                         SysTryReturnVoidResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
1159                 }
1160         }
1161 }
1162
1163 bool
1164 _ScrollPanelPresenter::OnAccessibilityFocusMovedNext(const _AccessibilityContainer& control, const _AccessibilityElement& element)
1165 {
1166         const _Control& controlObj = control.GetOwner();
1167         ScrollToControlWhenOutOfView(controlObj);
1168         result r = GetLastResult();
1169         SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, false, r, "[%s] Propagating.", GetErrorMessage(r));
1170
1171         return false;
1172 }
1173
1174 bool
1175 _ScrollPanelPresenter::OnAccessibilityFocusMovedPrevious(const _AccessibilityContainer& control, const _AccessibilityElement& element)
1176 {
1177         const _Control& controlObj = control.GetOwner();
1178         ScrollToControlWhenOutOfView(controlObj);
1179         result r = GetLastResult();
1180         SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, false, r, "[%s] Propagating.", GetErrorMessage(r));
1181
1182         return false;
1183 }
1184
1185 bool
1186 _ScrollPanelPresenter::OnAccessibilityReadingElement(const _AccessibilityContainer& control, const _AccessibilityElement& element)
1187 {
1188         return false;
1189 }
1190 bool
1191 _ScrollPanelPresenter::OnAccessibilityReadElement(const _AccessibilityContainer& control, const _AccessibilityElement& element)
1192 {
1193         return false;
1194 }
1195 bool
1196 _ScrollPanelPresenter::OnAccessibilityFocusIn(const _AccessibilityContainer& control, const _AccessibilityElement& element)
1197 {
1198         return false;
1199 }
1200
1201 bool
1202 _ScrollPanelPresenter::OnAccessibilityFocusOut(const _AccessibilityContainer& control, const _AccessibilityElement& element)
1203 {
1204         return false;
1205 }
1206
1207 bool
1208 _ScrollPanelPresenter::OnAccessibilityActionPerformed(const _AccessibilityContainer& control, const _AccessibilityElement& element)
1209 {
1210         return false;
1211 }
1212
1213 void
1214 _ScrollPanelPresenter::OnChildControlFocusMoved(const _Control& control)
1215 {
1216         ScrollToControlWhenOutOfView(control);
1217 }
1218
1219 void
1220 _ScrollPanelPresenter::OnDescendantControlFocusMoved(const _Control& control)
1221 {
1222         ScrollToControlWhenOutOfView(control);
1223 }
1224
1225 bool
1226 _ScrollPanelPresenter::OnAccessibilityItemRefreshed(const _AccessibilityContainer& control, const _AccessibilityElement& element, _AccessibilityFocusDirection direction)
1227 {
1228         return false;
1229 }
1230
1231 void
1232 _ScrollPanelPresenter::OnTimerExpired(Tizen::Base::Runtime::Timer& timer)
1233 {
1234         if (&timer == __pScrollBarLoadEffectTimer)
1235         {
1236                 __scrollBarLoadEffectStatus = _SCROLL_PANEL_SCROLL_BAR_LOAD_EFFECT_LOADED;
1237
1238                 delete __pScrollBarLoadEffectTimer;
1239                 __pScrollBarLoadEffectTimer = null;
1240
1241                 FadeOutScrollBar();
1242                 result r = GetLastResult();
1243                 SysTryReturnVoidResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
1244         }
1245 }
1246
1247 void
1248 _ScrollPanelPresenter::OnVisualElementAnimationStarted(const VisualElementAnimation& animation, const String& keyName, VisualElement& target)
1249 {
1250         // nothing
1251 }
1252
1253 void
1254 _ScrollPanelPresenter::OnVisualElementAnimationRepeated(const VisualElementAnimation& animation, const String& keyName, VisualElement& target, long currentRepeatCount)
1255 {
1256         // nothing
1257 }
1258
1259 void
1260 _ScrollPanelPresenter::OnVisualElementAnimationFinished(const VisualElementAnimation& animation, const String& keyName, VisualElement& target, bool completedNormally)
1261 {
1262         __scrollAnimationRunning = false;
1263         __flickRunning = false;
1264
1265         if (__scrollOccured)
1266         {
1267                 __scrollOccured = false;
1268                 __pScrollPanel->FireOnScrollStoppedEvent();
1269         }
1270
1271         if (!__jumpToTopRunning && !__modelUpdating)
1272         {
1273                 RollbackBouncing(completedNormally);
1274                 result r = GetLastResult();
1275                 SysTryReturnVoidResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
1276         }
1277         __jumpToTopRunning = false;
1278
1279         if (!__scrollAnimationRunning)
1280         {
1281                 FadeOutScrollBar();
1282                 result r = GetLastResult();
1283                 SysTryReturnVoidResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
1284         }
1285 }
1286
1287 void
1288 _ScrollPanelPresenter::OnTickOccurred(const VisualElementAnimation& animation, const String& keyName, VisualElement& target, const Variant& currentValue)
1289 {
1290         _VisualElement* pVisualElement = __pScrollPanel->GetVisualElement();
1291
1292         if (&target != pVisualElement)
1293         {
1294                 return;
1295         }
1296
1297         if (keyName == SCROLLING_ANIMATION_NAME)
1298         {
1299                 if (!__scrollAnimationRunning)
1300                 {
1301                         return;
1302                 }
1303
1304                 ScrollToInternal(currentValue.ToFloat());
1305         }
1306 }
1307
1308 void
1309 _ScrollPanelPresenter::UpdateLayout(void)
1310 {
1311         __pScrollPanel->PartialUpdateLayout();
1312 }
1313
1314 void
1315 _ScrollPanelPresenter::AdjustModel()
1316 {
1317         _Scroll* pHorizontalScrollBar = __pScrollPanel->GetHorizontalScrollBar();
1318         _Scroll* pVerticalScrollBar = __pScrollPanel->GetVerticalScrollBar();
1319
1320         FloatRectangle scrollPanelBounds = __pScrollPanel->GetBoundsF();
1321         ScrollPanelScrollDirection scrollDirection = __pScrollPanel->GetScrollDirection();
1322         FloatRectangle scrollArea = FloatRectangle(0.0f, 0.0f, scrollPanelBounds.width, scrollPanelBounds.height);
1323
1324         if (__pScrollPanel->IsScrollAreaAutoResizingEnabled())
1325         {
1326                 int count = __pScrollPanel->GetChildCount();
1327
1328                 if (__pScrollPanel->GetScrollDirection() == SCROLL_PANEL_SCROLL_DIRECTION_VERTICAL)
1329                 {
1330                         for (int i = 0; i < count; i++)
1331                         {
1332                                 _Control* pControl = __pScrollPanel->GetChild(i);
1333                                 SysTryReturnVoidResult(NID_UI_CTRL, pControl != null, E_SYSTEM, "[%s] pControl(child) is invalid pointer.", GetErrorMessage(E_SYSTEM));
1334
1335                                 if (pControl->GetArea() == _CONTROL_AREA_SYSTEM)
1336                                 {
1337                                         continue;
1338                                 }
1339
1340                                 float targetMaxPos = pControl->GetBoundsF().GetBottomRight().y;
1341                                 if (scrollArea.height < targetMaxPos)
1342                                 {
1343                                         scrollArea.height = targetMaxPos;
1344                                 }
1345                         }
1346                 }
1347                 else if (__pScrollPanel->GetScrollDirection() == SCROLL_PANEL_SCROLL_DIRECTION_HORIZONTAL)
1348                 {
1349                         for (int i = 0; i < count; i++)
1350                         {
1351                                 _Control* pControl = __pScrollPanel->GetChild(i);
1352                                 SysTryReturnVoidResult(NID_UI_CTRL, pControl != null, E_SYSTEM, "[%s] pControl(child) is invalid pointer.", GetErrorMessage(E_SYSTEM));
1353
1354                                 if (pControl->GetArea() == _CONTROL_AREA_SYSTEM)
1355                                 {
1356                                         continue;
1357                                 }
1358
1359                                 float targetMaxPos = pControl->GetBoundsF().GetBottomRight().x;
1360                                 if (scrollArea.width < targetMaxPos)
1361                                 {
1362                                         scrollArea.width = targetMaxPos;
1363                                 }
1364                         }
1365                 }
1366         }
1367         else
1368         {
1369                 scrollArea = GetScrollAreaBounds();
1370                 if (scrollDirection == SCROLL_PANEL_SCROLL_DIRECTION_HORIZONTAL)
1371                 {
1372                         if (scrollArea.width < scrollPanelBounds.width)
1373                         {
1374                                 scrollArea.width = scrollPanelBounds.width;
1375                         }
1376                         scrollArea.height = scrollPanelBounds.height;
1377                 }
1378                 else
1379                 {
1380                         scrollArea.width = scrollPanelBounds.width;
1381                         if (scrollArea.height < scrollPanelBounds.height)
1382                         {
1383                                 scrollArea.height = scrollPanelBounds.height;
1384                         }
1385                 }
1386         }
1387
1388         // change model values
1389         SetScrollAreaBoundsInternal(scrollArea);
1390         FloatDimension alignSize = FloatDimension(scrollPanelBounds.width, scrollPanelBounds.height);
1391         __pScrollPanel->SetPageScrollAlignSize(alignSize);
1392
1393         // before change model ScrollPosition fix
1394         if (__modelUpdating)
1395         {
1396                 float scrollPosition = GetScrollPositionInternal();
1397                 float fixedScrollPosition = FixScrollPositionIntoScrollAreaBounds(scrollPosition);
1398                 float previousFixedScrollPosition = FixScrollPositionIntoScrollAreaBounds(scrollPosition, __previousBounds, __previousScrollAreaBounds);
1399                 if (!_FloatCompare(scrollPosition, fixedScrollPosition)
1400                         || !_FloatCompare(scrollPosition, previousFixedScrollPosition))
1401                 {
1402                         ScrollTo(fixedScrollPosition, false);
1403                         result r = GetLastResult();
1404                         SysTryReturnVoidResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
1405                 }
1406
1407                 __modelUpdating = false;
1408                 __previousBounds = __pScrollPanel->GetBoundsF();
1409                 __previousScrollAreaBounds = GetScrollAreaBounds();
1410         }
1411
1412         // Adjust ScrollBar
1413         if (scrollDirection == SCROLL_PANEL_SCROLL_DIRECTION_HORIZONTAL)
1414         {
1415                 if (scrollPanelBounds.width > 0)
1416                 {
1417                         if (pHorizontalScrollBar != null)
1418                         {
1419                                 pHorizontalScrollBar->OnParentBoundsChanged();
1420                         }
1421
1422                         if (!IsScrollable() && !_FloatCompare(scrollArea.x, GetScrollPosition()))
1423                         {
1424                                 SetScrollPosition(scrollArea.x, false);
1425                                 result r = GetLastResult();
1426                                 SysTryReturnVoidResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
1427                         }
1428                 }
1429         }
1430         else
1431         {
1432                 if (scrollPanelBounds.height > 0)
1433                 {
1434                         if (pVerticalScrollBar != null)
1435                         {
1436                                 pVerticalScrollBar->OnParentBoundsChanged();
1437                         }
1438
1439                         if (!IsScrollable() && !_FloatCompare(scrollArea.y, GetScrollPosition()))
1440                         {
1441                                 SetScrollPosition(scrollArea.y, false);
1442                                 result r = GetLastResult();
1443                                 SysTryReturnVoidResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
1444                         }
1445                 }
1446         }
1447
1448         // update scrollbar range
1449         ChangeScrollBarRange();
1450         result r = GetLastResult();
1451         SysTryReturnVoidResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
1452
1453         if (!__scrollAnimationRunning)
1454         {
1455                 FadeOutScrollBar();
1456                 result r = GetLastResult();
1457                 SysTryReturnVoidResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
1458         }
1459 }
1460
1461 bool
1462 _ScrollPanelPresenter::ScrollToControl(const _Control& source, bool recursive)
1463 {
1464         SysTryReturn(NID_UI_CTRL, __pScrollPanel->GetChildCount() != 0, false, E_INVALID_ARG, "[%s] ScrollPanel have no child control.", GetErrorMessage(E_INVALID_ARG));
1465
1466         FloatPoint controlPosition = source.GetPositionF();
1467         if (!recursive)
1468         {
1469                 SysTryReturn(NID_UI_CTRL, __pScrollPanel->GetChildIndex(source) != -1, false, E_INVALID_ARG, "[%s] source is not a child control.", GetErrorMessage(E_INVALID_ARG));
1470         }
1471         else
1472         {
1473                 SysTryReturn(NID_UI_CTRL, __pScrollPanel->IsAncestorOf(source), false, E_INVALID_ARG, "[%s] source is not a child control.", GetErrorMessage(E_INVALID_ARG));
1474
1475                 _Control* pParent = source.GetParent();
1476                 while (pParent != null && pParent != __pScrollPanel)
1477                 {
1478                         _ScrollPanel* pScrollPanelParent = dynamic_cast<_ScrollPanel*> (pParent);
1479                         if (pScrollPanelParent != null)
1480                         {
1481                                 FloatDimension pagingGap(0.0f, 0.0f);
1482                                 if (pScrollPanelParent->IsPageScrollEnabled())
1483                                 {
1484                                         FloatPoint pagingPosition = controlPosition;
1485                                         if (pScrollPanelParent->GetScrollDirection() == SCROLL_PANEL_SCROLL_DIRECTION_HORIZONTAL)
1486                                         {
1487                                                 pagingPosition.x = pScrollPanelParent->CalculatePagingScrollPosition(controlPosition.x);
1488                                                 pagingGap.width = controlPosition.x - pagingPosition.x;
1489                                                 if (pagingGap.width < 0.0f)
1490                                                 {
1491                                                         pagingPosition.x -= pScrollPanelParent->GetPageScrollAlignSize().width;
1492                                                         pagingGap.width += pScrollPanelParent->GetPageScrollAlignSize().width;
1493                                                 }
1494                                         }
1495                                         else
1496                                         {
1497                                                 pagingPosition.y = pScrollPanelParent->CalculatePagingScrollPosition(controlPosition.y);
1498                                                 pagingGap.height = controlPosition.y - pagingPosition.y;
1499                                                 if (pagingGap.height < 0.0f)
1500                                                 {
1501                                                         pagingPosition.y -= pScrollPanelParent->GetPageScrollAlignSize().height;
1502                                                         pagingGap.height += pScrollPanelParent->GetPageScrollAlignSize().height;
1503                                                 }
1504                                         }
1505
1506                                         pScrollPanelParent->SetScrollPosition(pagingPosition, false);
1507                                 }
1508                                 else
1509                                 {
1510                                         pScrollPanelParent->SetScrollPosition(controlPosition, false);
1511                                 }
1512
1513                                 controlPosition.x -= pScrollPanelParent->GetHorizontalScrollPosition() + pagingGap.width;
1514                                 controlPosition.y -= pScrollPanelParent->GetVerticalScrollPosition() + pagingGap.height;
1515                         }
1516
1517                         FloatPoint parentPosition = pParent->GetPositionF();
1518                         controlPosition.x += parentPosition.x;
1519                         controlPosition.y += parentPosition.y;
1520
1521                         pParent = pParent->GetParent();
1522                 }
1523         }
1524
1525         if (__pScrollPanel->IsPageScrollEnabled())
1526         {
1527                 FloatPoint pagingPosition = controlPosition;
1528                 if (__pScrollPanel->GetScrollDirection() == SCROLL_PANEL_SCROLL_DIRECTION_HORIZONTAL)
1529                 {
1530                         pagingPosition.x  = CalculatePagingScrollPosition(controlPosition.x);
1531                         if (pagingPosition.x > controlPosition.x)
1532                         {
1533                                 controlPosition.x = pagingPosition.x - __pScrollPanel->GetPageScrollAlignSize().width;
1534                         }
1535                         else
1536                         {
1537                                 controlPosition.x = pagingPosition.x;
1538                         }
1539                 }
1540                 else
1541                 {
1542                         pagingPosition.y  = CalculatePagingScrollPosition(controlPosition.y);
1543                         if (pagingPosition.y > controlPosition.y)
1544                         {
1545                                 controlPosition.y = pagingPosition.y - __pScrollPanel->GetPageScrollAlignSize().height;
1546                         }
1547                         else
1548                         {
1549                                 controlPosition.y = pagingPosition.y;
1550                         }
1551                 }
1552         }
1553         SetScrollPosition(controlPosition, true);
1554         result r = GetLastResult();
1555         SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, false, r, "[%s] Propagating.", GetErrorMessage(r));
1556
1557         return true;
1558 }
1559
1560 float
1561 _ScrollPanelPresenter::ScrollTo(float targetPosition)
1562 {
1563         return ScrollTo(targetPosition, false);
1564 }
1565
1566 float
1567 _ScrollPanelPresenter::ScrollTo(float targetPosition, bool withAnimation)
1568 {
1569         StopScrollingAnimation();
1570
1571         if (withAnimation)
1572         {
1573                 // Calculate real move distance
1574                 float scrollToPosition = FixScrollPositionIntoScrollAreaBounds(targetPosition);
1575
1576                 float oldPosition = GetScrollPositionInternal();
1577                 VisualElementValueAnimation* pScrollingAnimation = __pScrollPanel->GetScrollingAnimation();
1578                 pScrollingAnimation->SetStartValue(Variant(oldPosition));
1579                 pScrollingAnimation->SetEndValue(Variant(targetPosition));
1580                 pScrollingAnimation->SetDuration(SCROLL_PANEL_SCROLLING_ANIMATION_DURATION);
1581                 _VisualElement* pVisualElement = __pScrollPanel->GetVisualElement();
1582                 __scrollAnimationRunning = true;
1583                 pVisualElement->AddAnimation(SCROLLING_ANIMATION_NAME, *pScrollingAnimation);
1584
1585                 return scrollToPosition - oldPosition;
1586         }
1587         else
1588         {
1589                 return ScrollToInternal(targetPosition);
1590         }
1591 }
1592
1593 float
1594 _ScrollPanelPresenter::ScrollToInternal(float targetPosition)
1595 {
1596         ScrollPanelScrollDirection scrollDirection = __pScrollPanel->GetScrollDirection();
1597         _VisualElement* pVisualElement = __pScrollPanel->GetVisualElement();
1598         float previousScrollPosition = GetScrollPositionInternal();
1599         float distance = 0.0f;
1600         FloatPoint floatPointDistance;
1601
1602         float scrollToPosition = FixScrollPositionIntoScrollAreaBounds(targetPosition);
1603
1604         if (scrollDirection == SCROLL_PANEL_SCROLL_DIRECTION_HORIZONTAL)
1605         {
1606                 distance = scrollToPosition - FixScrollPositionIntoScrollAreaBounds(previousScrollPosition, __previousBounds, __previousScrollAreaBounds);
1607                 floatPointDistance.SetPosition(-distance, 0.0f);
1608         }
1609         else
1610         {
1611                 distance = scrollToPosition - FixScrollPositionIntoScrollAreaBounds(previousScrollPosition, __previousBounds, __previousScrollAreaBounds);
1612                 floatPointDistance.SetPosition(0.0f, -distance);
1613         }
1614
1615         if (!_FloatCompare(distance, 0))
1616         {
1617                 result r = pVisualElement->ScrollByPoint(floatPointDistance, false);
1618                 SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, 0, r, "[%s] Propagating.", GetErrorMessage(r));
1619
1620                 __scrollOccured = true;
1621         }
1622
1623         ChangeScrollBarPosition(targetPosition);
1624         SetScrollPositionInternal(targetPosition);
1625
1626         if (!_FloatCompare(distance, 0))
1627         {
1628                 FloatRectangle scrollPanelBounds = __pScrollPanel->GetBoundsF();
1629                 FloatRectangle scrollArea = GetScrollAreaBounds();
1630
1631                 if (scrollDirection == SCROLL_PANEL_SCROLL_DIRECTION_HORIZONTAL)
1632                 {
1633                         if (scrollArea.width > scrollPanelBounds.width)
1634                         {
1635                                 float minScrollPos = scrollArea.x;
1636                                 float maxScrollPos = scrollArea.width - scrollPanelBounds.width;
1637
1638                                 if ((targetPosition >= minScrollPos && targetPosition <= maxScrollPos)
1639                                         || (previousScrollPosition > minScrollPos || previousScrollPosition < maxScrollPos))
1640                                 {
1641                                         __pScrollPanel->FireOnScrollPositionChangedEvent();
1642                                 }
1643
1644                                 if (previousScrollPosition > minScrollPos && previousScrollPosition < maxScrollPos)
1645                                 {
1646                                         if (targetPosition <= minScrollPos)
1647                                         {
1648                                                 __pScrollPanel->FireOnScrollEndEvent(SCROLL_END_EVENT_END_LEFT);
1649                                         }
1650                                         else if (targetPosition >= maxScrollPos)
1651                                         {
1652                                                 __pScrollPanel->FireOnScrollEndEvent(SCROLL_END_EVENT_END_RIGHT);
1653                                         }
1654                                 }
1655                         }
1656                 }
1657                 else
1658                 {
1659                         if (scrollArea.height > scrollPanelBounds.height)
1660                         {
1661                                 float minScrollPos = scrollArea.y;
1662                                 float maxScrollPos = scrollArea.height - scrollPanelBounds.height;
1663
1664                                 if ((targetPosition >= minScrollPos && targetPosition <= maxScrollPos)
1665                                         || (previousScrollPosition > minScrollPos || previousScrollPosition < maxScrollPos))
1666                                 {
1667                                         __pScrollPanel->FireOnScrollPositionChangedEvent();
1668                                 }
1669
1670                                 if (previousScrollPosition > minScrollPos && previousScrollPosition < maxScrollPos)
1671                                 {
1672                                         if (targetPosition <= minScrollPos)
1673                                         {
1674                                                 __pScrollPanel->FireOnScrollEndEvent(SCROLL_END_EVENT_END_TOP);
1675                                         }
1676                                         else if (targetPosition >= maxScrollPos)
1677                                         {
1678                                                 __pScrollPanel->FireOnScrollEndEvent(SCROLL_END_EVENT_END_BOTTOM);
1679                                         }
1680                                 }
1681                         }
1682                 }
1683         }
1684
1685         return distance;
1686 }
1687
1688 void
1689 _ScrollPanelPresenter::ChangeScrollBarPosition(float position)
1690 {
1691         _Scroll* pScrollBar = __pScrollPanel->GetScrollBar();
1692
1693         if (pScrollBar != null && __pScrollPanel->IsAncestorOf(*pScrollBar))
1694         {
1695                 if (__pScrollPanel->GetScrollDirection() == SCROLL_PANEL_SCROLL_DIRECTION_HORIZONTAL)
1696                 {
1697                         result r = pScrollBar->SetScrollPosition(position);
1698                         SysTryReturnVoidResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
1699                 }
1700                 else
1701                 {
1702                         result r = pScrollBar->SetScrollPosition(position);
1703                         SysTryReturnVoidResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
1704                 }
1705         }
1706 }
1707
1708 void
1709 _ScrollPanelPresenter::ChangeScrollBarRange(void)
1710 {
1711         _Scroll* pScrollBar = __pScrollPanel->GetScrollBar();
1712
1713         if (pScrollBar != null)
1714         {
1715                 float viewRange = 0.0f;
1716                 float scrollRange = 0.0f;
1717
1718                 if (__pScrollPanel->GetScrollDirection() == SCROLL_PANEL_SCROLL_DIRECTION_HORIZONTAL)
1719                 {
1720                         viewRange = __pScrollPanel->GetBoundsF().width;
1721                         scrollRange = GetScrollAreaBounds().width;
1722                 }
1723                 else
1724                 {
1725                         viewRange = __pScrollPanel->GetBoundsF().height;
1726                         scrollRange = GetScrollAreaBounds().height;
1727                 }
1728
1729                 if (viewRange <= scrollRange)
1730                 {
1731                         result r = pScrollBar->SetScrollRange(viewRange, scrollRange);
1732                         SysTryReturnVoidResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
1733
1734                         if (!_FloatCompare(viewRange, scrollRange))
1735                         {
1736                                 if (__scrollBarLoadEffectStatus == _SCROLL_PANEL_SCROLL_BAR_LOAD_EFFECT_UNLOAD)
1737                                 {
1738                                         __scrollBarLoadEffectStatus = _SCROLL_PANEL_SCROLL_BAR_LOAD_EFFECT_LOADING;
1739
1740                                         if (__firstDrawn)
1741                                         {
1742                                                 DoScrollBarLoadEffect();
1743                                         }
1744                                 }
1745                         }
1746                         else
1747                         {
1748                                 __scrollBarLoadEffectStatus = _SCROLL_PANEL_SCROLL_BAR_LOAD_EFFECT_UNLOAD;
1749                         }
1750                 }
1751         }
1752 }
1753
1754 void
1755 _ScrollPanelPresenter::DoScrollBarLoadEffect(void)
1756 {
1757         if (__pScrollPanel->IsScrollBarVisible())
1758         {
1759                 FadeInScrollBar();
1760                 result r = GetLastResult();
1761                 SysTryReturnVoidResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
1762
1763                 StartScrollBarLoadEffectTimer();
1764                 r = GetLastResult();
1765                 SysTryReturnVoidResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
1766         }
1767         else
1768         {
1769                 __scrollBarLoadEffectStatus = _SCROLL_PANEL_SCROLL_BAR_LOAD_EFFECT_UNLOAD;
1770         }
1771 }
1772
1773 void
1774 _ScrollPanelPresenter::StartScrollBarLoadEffectTimer(void)
1775 {
1776         result r = E_SUCCESS;
1777
1778         if (__pScrollBarLoadEffectTimer == null && __scrollBarLoadEffectStatus == _SCROLL_PANEL_SCROLL_BAR_LOAD_EFFECT_LOADING)
1779         {
1780                 __pScrollBarLoadEffectTimer = new (std::nothrow) Tizen::Base::Runtime::Timer;
1781                 SysTryReturnVoidResult(NID_UI_CTRL, __pScrollBarLoadEffectTimer != null, E_OUT_OF_MEMORY, "[%s] The memory is insufficient", GetErrorMessage(E_OUT_OF_MEMORY));
1782
1783                 r = __pScrollBarLoadEffectTimer->Construct(*this);
1784                 SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
1785
1786                 r = __pScrollBarLoadEffectTimer->Start(SCROLL_PANEL_SCROLL_BAR_LOAD_EFFECT_TIMER_DURATION);
1787                 SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
1788         }
1789
1790         return;
1791
1792 CATCH:
1793         delete __pScrollBarLoadEffectTimer;
1794         __pScrollBarLoadEffectTimer = null;
1795
1796         SetLastResult(r);
1797 }
1798
1799 void
1800 _ScrollPanelPresenter::StopScrollBarLoadEffectTimer(void)
1801 {
1802         if (__pScrollBarLoadEffectTimer)
1803         {
1804                 __pScrollBarLoadEffectTimer->Cancel();
1805         }
1806 }
1807
1808 void
1809 _ScrollPanelPresenter::FadeOutScrollBar(void)
1810 {
1811         if (!__scrollAnimationRunning)
1812         {
1813                 _Scroll* pScrollBar = __pScrollPanel->GetScrollBar();
1814                 if (pScrollBar != null)
1815                 {
1816                         if ((!__pScrollPanel->IsScrollBarVisible() || !IsScrollable())
1817                                 || (!pScrollBar->IsEnabledHandler() && __scrollBarLoadEffectStatus == _SCROLL_PANEL_SCROLL_BAR_LOAD_EFFECT_LOADED))
1818                         {
1819                                 result r = pScrollBar->SetScrollVisibility(false);
1820                                 SysTryReturnVoidResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
1821                         }
1822
1823                         result r = pScrollBar->SetScrollingEffectVisibility(false);
1824                         SysTryReturnVoidResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
1825                 }
1826         }
1827 }
1828
1829 void
1830 _ScrollPanelPresenter::StopFadeOutScrollBar(void)
1831 {
1832         _Scroll* pScrollBar = __pScrollPanel->GetScrollBar();
1833
1834         if (pScrollBar != null)
1835         {
1836                 pScrollBar->CancelFadeEffect();
1837         }
1838 }
1839
1840 void
1841 _ScrollPanelPresenter::FadeInScrollBar(void)
1842 {
1843         if (!IsScrollable())
1844         {
1845                 return;
1846         }
1847
1848         _Scroll* pScrollBar = __pScrollPanel->GetScrollBar();
1849
1850         if (pScrollBar != null)
1851         {
1852                 if (__pScrollPanel->IsScrollBarVisible())
1853                 {
1854                         result r = pScrollBar->SetScrollVisibility(true);
1855                         SysTryReturnVoidResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
1856                 }
1857
1858                 result r = pScrollBar->SetScrollingEffectVisibility(true);
1859                 SysTryReturnVoidResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
1860         }
1861 }
1862
1863 bool
1864 _ScrollPanelPresenter::IsScrollable(void) const
1865 {
1866         if (__pScrollPanel->GetScrollDirection() == SCROLL_PANEL_SCROLL_DIRECTION_HORIZONTAL)
1867         {
1868                 return __pScrollPanel->GetBoundsF().width >0 && __pScrollPanel->GetBoundsF().width < GetScrollAreaBounds().width;
1869         }
1870         else
1871         {
1872                 return __pScrollPanel->GetBoundsF().height > 0 && __pScrollPanel->GetBoundsF().height < GetScrollAreaBounds().height;
1873         }
1874 }
1875
1876 FloatRectangle
1877 _ScrollPanelPresenter::GetScrollAreaBounds(void) const
1878 {
1879         return __pScrollPanelModel->GetScrollAreaBounds();
1880 }
1881
1882 result
1883 _ScrollPanelPresenter::SetClientAreaHeight(float height)
1884 {
1885         SysTryReturn(NID_UI_CTRL, __pScrollPanel->GetScrollDirection() == SCROLL_PANEL_SCROLL_DIRECTION_VERTICAL, E_INVALID_OPERATION, E_INVALID_OPERATION, "[%s]  The height of the client area cannot be set when the scroll direction is horizontal.", GetErrorMessage(E_INVALID_OPERATION));
1886         FloatRectangle bounds = GetScrollAreaBounds();
1887         bounds.height = height;
1888
1889         return SetScrollAreaBounds(bounds);
1890 }
1891
1892 result
1893 _ScrollPanelPresenter::SetClientAreaWidth(float width)
1894 {
1895         SysTryReturn(NID_UI_CTRL, __pScrollPanel->GetScrollDirection() == SCROLL_PANEL_SCROLL_DIRECTION_HORIZONTAL, E_INVALID_OPERATION, E_INVALID_OPERATION, "[%s]  The width of the client area cannot be set when the scroll direction is vertical.", GetErrorMessage(E_INVALID_OPERATION));
1896         FloatRectangle bounds = GetScrollAreaBounds();
1897         bounds.width = width;
1898
1899         return SetScrollAreaBounds(bounds);
1900 }
1901
1902 void
1903 _ScrollPanelPresenter::SetScrollAreaBoundsInternal(FloatRectangle& bounds)
1904 {
1905         if (__pScrollPanel->IsFixingClientBoundsEnabled())
1906         {
1907                 __pScrollPanel->SetClientBounds(bounds);
1908         }
1909         __pScrollPanelModel->SetScrollAreaBounds(bounds);
1910 }
1911
1912 void
1913 _ScrollPanelPresenter::UpdateClientBounds(const Tizen::Graphics::FloatDimension& size, Tizen::Graphics::FloatRectangle& clientBounds)
1914 {
1915         if (__pScrollPanel->IsFixingClientBoundsEnabled())
1916         {
1917                 clientBounds = GetScrollAreaBounds();
1918                 if (IsScrollable())
1919                 {
1920                         if (size.height > clientBounds.height)
1921                         {
1922                                 clientBounds.height = size.height;
1923                         }
1924                         if (size.width > clientBounds.width)
1925                         {
1926                                 clientBounds.width = size.width;
1927                         }
1928                 }
1929                 else
1930                 {
1931                         clientBounds.width = size.width;
1932                         clientBounds.height = size.height;
1933                 }
1934         }
1935         else
1936         {
1937                 clientBounds.width = size.width;
1938                 clientBounds.height = size.height;
1939         }
1940 }
1941
1942 result
1943 _ScrollPanelPresenter::SetScrollAreaBounds(FloatRectangle& bounds)
1944 {
1945         SysTryReturn(NID_UI_CTRL, !__pScrollPanel->IsScrollAreaAutoResizingEnabled(), E_INVALID_OPERATION, E_INVALID_OPERATION, "[%s] The width of the client area cannot be set when auto resizing of the client area is on.", GetErrorMessage(E_INVALID_OPERATION));
1946
1947         bounds.x = 0.0f;
1948         bounds.y = 0.0f;
1949
1950         if (__pScrollPanel->GetScrollDirection() == SCROLL_PANEL_SCROLL_DIRECTION_HORIZONTAL)
1951         {
1952                 SysTryReturn(NID_UI_CTRL, __pScrollPanel->GetBoundsF().width <= bounds.width, E_INVALID_ARG, E_INVALID_ARG, "[%s] width is less than the width of ScrollPanel", GetErrorMessage(E_INVALID_ARG));
1953                 bounds.height = __pScrollPanel->GetBoundsF().height;
1954         }
1955         else
1956         {
1957                 SysTryReturn(NID_UI_CTRL, __pScrollPanel->GetBoundsF().height <= bounds.height, E_INVALID_ARG, E_INVALID_ARG, "[%s] height is less than the height of ScrollPanel", GetErrorMessage(E_INVALID_ARG));
1958                 bounds.width = __pScrollPanel->GetBoundsF().width;
1959         }
1960
1961         if (__scrollAnimationRunning)
1962         {
1963                 if (IsScrollable())
1964                 {
1965                         float scrollPosition = GetScrollPositionInternal();
1966                         float fixedScrollPosition = FixScrollPositionIntoScrollAreaBounds(scrollPosition);
1967
1968                         if (!_FloatCompare(scrollPosition, fixedScrollPosition))
1969                         {
1970                                 StopScrollingAnimation();
1971                         }
1972                 }
1973         }
1974
1975         if (!__modelUpdating)
1976         {
1977                 __modelUpdating = true;
1978                 __previousBounds = __pScrollPanel->GetBoundsF();
1979                 __previousScrollAreaBounds = GetScrollAreaBounds();
1980         }
1981
1982         SetScrollAreaBoundsInternal(bounds);
1983
1984         AdjustModel();
1985         result r = GetLastResult();
1986         SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
1987
1988         return E_SUCCESS;
1989 }
1990
1991 const _Control*
1992 _ScrollPanelPresenter::GetPressedControl(void) const
1993 {
1994         return __pPressedControl;
1995 }
1996
1997 FloatPoint
1998 _ScrollPanelPresenter::GetPreviousTouchPosition(void) const
1999 {
2000         return __previousTouchedPosition;
2001 }
2002
2003 FloatPoint
2004 _ScrollPanelPresenter::GetCurrentTouchPosition(void) const
2005 {
2006         return __currentMovedPosition;
2007 }
2008
2009 bool
2010 _ScrollPanelPresenter::IsScrollAnimationRunning(void) const
2011 {
2012         return __scrollAnimationRunning;
2013 }
2014
2015 bool
2016 _ScrollPanelPresenter::IsModelUpdating(void) const
2017 {
2018         return __modelUpdating;
2019 }
2020
2021 float
2022 _ScrollPanelPresenter::CalculateFlickAmount(float flickDistance, float flickDuration)
2023 {
2024         if (_FloatCompare(flickDistance, 0.0f))
2025         {
2026                 return 0.0f;
2027         }
2028         else if (flickDistance < 0.0)
2029         {
2030                 return -SCROLL_PANEL_FIXED_FLICK_AMOUNT;
2031         }
2032         else
2033         {
2034                 return SCROLL_PANEL_FIXED_FLICK_AMOUNT;
2035         }
2036 }
2037
2038 bool
2039 _ScrollPanelPresenter::AccumulateFlickGesture(_FlickDirection direction)
2040 {
2041         return false;
2042 }
2043
2044
2045 float
2046 _ScrollPanelPresenter::FlickTo(float targetPosition, float duration)
2047 {
2048         return ScrollTo(targetPosition, true);
2049 }
2050
2051 }}}     // Tizen::Ui::Controls
2052