2 // Open Service Platform
3 // Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
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
9 // http://www.apache.org/licenses/LICENSE-2.0/
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.
19 * @file FUiCtrl_ScrollPanelPresenter.cpp
20 * @brief This is the implementation file for the %_ScrollPanelPresenter class.
25 #include <FBaseErrorDefine.h>
26 #include <FBaseRtTimer.h>
27 #include <FBaseUtilMath.h>
28 #include <FBaseSysLog.h>
29 #include <FUiAnimVisualElementValueAnimation.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"
42 using namespace Tizen::Base;
43 using namespace Tizen::Graphics;
44 using namespace Tizen::Ui::Animations;
48 static const float SCROLL_PANEL_OVERSCROLLING_MAX_DISTANCCE = 100.0f;
49 static const float SCROLL_PANEL_FIXED_FLICK_AMOUNT = 1000.0f;
51 static const int SCROLL_PANEL_SCROLLING_ANIMATION_DURATION = 1000;
52 static const int SCROLL_PANEL_SCROLL_BAR_LOAD_EFFECT_TIMER_DURATION = 1000;
54 static const String SCROLLING_ANIMATION_NAME(L"SCROLL_PANEL_SCROLLING_ANIMATION");
57 namespace Tizen { namespace Ui { namespace Controls
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)
74 , __firstTouchMove(true)
75 , __firstScrollMoveDirection(SCROLL_PANEL_SCROLL_DIRECTION_VERTICAL)
76 , __jumpToTopRunning(false)
81 _ScrollPanelPresenter::~_ScrollPanelPresenter(void)
83 delete __pScrollBarLoadEffectTimer;
84 __pScrollBarLoadEffectTimer = null;
86 delete __pScrollPanelModel;
87 __pScrollPanelModel = null;
91 _ScrollPanelPresenter::Initialize(_ScrollPanel& scrollPanel)
93 result r = _PanelPresenter::Initialize(scrollPanel);
94 SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
96 __pScrollPanel = &scrollPanel;
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));
102 __pScrollPanelModel = pModel;
108 _ScrollPanelPresenter::Draw(void)
113 if (__scrollBarLoadEffectStatus == _SCROLL_PANEL_SCROLL_BAR_LOAD_EFFECT_LOADING)
115 DoScrollBarLoadEffect();
121 if (__pScrollPanel->GetBackgroundBitmap() == null)
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));
131 pCanvas->SetBackgroundColor(Color(0, 0, 0, 0));
133 SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
135 r = pCanvas->Clear();
136 SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
138 DrawBackgrounBitmap(pCanvas);
140 SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
150 _ScrollPanelPresenter::OnBoundsChanging(const FloatRectangle& bounds)
152 if (__scrollAnimationRunning)
154 StopScrollingAnimation();
157 if (!__modelUpdating)
159 __modelUpdating = true;
160 __previousBounds = __pScrollPanel->GetBoundsF();
161 __previousScrollAreaBounds = GetScrollAreaBounds();
168 _ScrollPanelPresenter::OnBoundsChanged(void)
174 _ScrollPanelPresenter::OnChildAttached(const _Control& child)
176 if (child.GetArea() != _CONTROL_AREA_SYSTEM)
178 if (__pScrollPanel->IsScrollAreaAutoResizingEnabled())
182 if (!__modelUpdating)
184 __modelUpdating = true;
185 __previousBounds = __pScrollPanel->GetBoundsF();
186 __previousScrollAreaBounds = GetScrollAreaBounds();
191 _AccessibilityContainer* pChildAccessibilityContainer = (const_cast<_Control&>(child)).GetAccessibilityContainer();
192 pChildAccessibilityContainer->AddListener(*__pScrollPanel);
198 _ScrollPanelPresenter::OnChildDetached(const _Control& child)
200 if (child.GetArea() != _CONTROL_AREA_SYSTEM)
202 if (__pScrollPanel->IsScrollAreaAutoResizingEnabled())
206 if (!__modelUpdating)
208 __modelUpdating = true;
209 __previousBounds = __pScrollPanel->GetBoundsF();
210 __previousScrollAreaBounds = GetScrollAreaBounds();
215 _AccessibilityContainer* pChildAccessibilityContainer = (const_cast<_Control&>(child)).GetAccessibilityContainer();
216 pChildAccessibilityContainer->RemoveListener(*__pScrollPanel);
222 _ScrollPanelPresenter::OnChildBoundsChanged(const _Control& child)
224 if (child.GetArea() != _CONTROL_AREA_SYSTEM)
226 if (__pScrollPanel->IsScrollAreaAutoResizingEnabled())
228 if (!__modelUpdating)
230 __modelUpdating = true;
231 __previousBounds = __pScrollPanel->GetBoundsF();
232 __previousScrollAreaBounds = GetScrollAreaBounds();
240 _ScrollPanelPresenter::SetScrollPosition(FloatPoint position, bool withAnimation)
242 if (__pScrollPanel->GetScrollDirection() == SCROLL_PANEL_SCROLL_DIRECTION_HORIZONTAL)
244 SetScrollPosition(position.x, withAnimation);
248 SetScrollPosition(position.y, withAnimation);
253 _ScrollPanelPresenter::SetScrollPosition(float position, bool withAnimation)
255 // change scroll position
259 result r = GetLastResult();
260 SysTryReturnVoidResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
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));
270 _ScrollPanelPresenter::GetScrollPosition(void) const
272 float scrollPosition = GetScrollPositionInternal();
273 return FixScrollPositionIntoScrollAreaBounds(scrollPosition);
277 _ScrollPanelPresenter::GetVerticalScrollPosition(void) const
279 float scrollPosition = GetVerticalScrollPositionInternal();
280 return FixScrollPositionIntoScrollAreaBounds(scrollPosition);
284 _ScrollPanelPresenter::SetVerticalScrollPosition(float position)
286 SetScrollPosition(position, true);
290 _ScrollPanelPresenter::GetHorizontalScrollPosition(void) const
292 float scrollPosition = GetHorizontalScrollPositionInternal();
293 return FixScrollPositionIntoScrollAreaBounds(scrollPosition);
297 _ScrollPanelPresenter::SetHorizontalScrollPosition(float position)
299 SetScrollPosition(position, true);
303 _ScrollPanelPresenter::GetScrollPositionInternal(void) const
305 ScrollPanelScrollDirection scrollDirection = __pScrollPanel->GetScrollDirection();
307 if (scrollDirection == SCROLL_PANEL_SCROLL_DIRECTION_HORIZONTAL)
309 return GetHorizontalScrollPositionInternal();
313 return GetVerticalScrollPositionInternal();
318 _ScrollPanelPresenter::SetScrollPositionInternal(float position)
320 ScrollPanelScrollDirection scrollDirection = __pScrollPanel->GetScrollDirection();
321 if (scrollDirection == SCROLL_PANEL_SCROLL_DIRECTION_HORIZONTAL)
323 SetHorizontalScrollPositionInternal(position);
327 SetVerticalScrollPositionInternal(position);
332 _ScrollPanelPresenter::GetVerticalScrollPositionInternal(void) const
334 return __pScrollPanelModel->GetCurrentVerticalScrollPosition();
338 _ScrollPanelPresenter::SetVerticalScrollPositionInternal(float position)
340 __pScrollPanelModel->SetCurrentVerticalScrollPosition(position);
344 _ScrollPanelPresenter::GetHorizontalScrollPositionInternal(void) const
346 return __pScrollPanelModel->GetCurrentHorizontalScrollPosition();
350 _ScrollPanelPresenter::SetHorizontalScrollPositionInternal(float position)
352 __pScrollPanelModel->SetCurrentHorizontalScrollPosition(position);
356 _ScrollPanelPresenter::StopScrollingAnimation(void)
358 __scrollAnimationRunning = false;
359 __pScrollPanel->GetVisualElement()->RemoveAnimation(SCROLLING_ANIMATION_NAME);
363 _ScrollPanelPresenter::FixScrollPositionIntoScrollAreaBounds(float position) const
365 return FixScrollPositionIntoScrollAreaBounds(position, __pScrollPanel->GetBoundsF(), GetScrollAreaBounds());
369 _ScrollPanelPresenter::FixScrollPositionIntoScrollAreaBounds(float position, FloatRectangle bounds, FloatRectangle scrollArea) const
371 float minScrollPosition = 0.0f;
372 float maxScrollPosition = 0.0f;
373 if (__pScrollPanel->GetScrollDirection() == SCROLL_PANEL_SCROLL_DIRECTION_HORIZONTAL)
375 minScrollPosition = scrollArea.x;
376 maxScrollPosition = scrollArea.x + scrollArea.width - bounds.width;
380 minScrollPosition = scrollArea.y;
381 maxScrollPosition = scrollArea.y + scrollArea.height - bounds.height;
384 if (minScrollPosition > maxScrollPosition)
386 maxScrollPosition = minScrollPosition;
388 if (position < minScrollPosition)
390 position = minScrollPosition;
392 if (position > maxScrollPosition)
394 position = maxScrollPosition;
401 _ScrollPanelPresenter::ScrollToTop(void)
403 SetVerticalScrollPosition(GetScrollAreaBounds().y);
407 _ScrollPanelPresenter::ScrollToBottom(void)
409 SetVerticalScrollPosition(GetScrollAreaBounds().height - __pScrollPanel->GetBoundsF().height);
413 _ScrollPanelPresenter::ScrollToLeft(void)
415 SetHorizontalScrollPosition(GetScrollAreaBounds().x);
419 _ScrollPanelPresenter::ScrollToRight(void)
421 SetHorizontalScrollPosition(GetScrollAreaBounds().width - __pScrollPanel->GetBoundsF().width);
425 _ScrollPanelPresenter::RunTouchPressed(const _Control& source, const _TouchInfo& touchInfo)
427 // stop flick, stop scroll animation
428 if (__flickRunning || __scrollAnimationRunning)
430 if (!__jumpToTopRunning)
432 StopScrollingAnimation();
435 __jumpToTopRunning = false;
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;
449 _ScrollPanelPresenter::RunPreviewTouchMoved(const _Control& source, const _TouchInfo& touchInfo)
451 if (__pPressedControl == &source && __touchPressed)
453 __previousTouchedPosition = __currentMovedPosition;
454 __currentMovedPosition = FloatPoint(touchInfo.GetCurrentPosition().x, touchInfo.GetCurrentPosition().y);
456 if (__pScrollPanel != &source)
458 __subControlMoved = true;
461 if (__firstTouchMove)
463 ScrollPanelScrollDirection scrollDirection = __pScrollPanel->GetScrollDirection();
464 float scrollDistanceX = __previousTouchedPosition.x - __currentMovedPosition.x;
465 float scrollDistanceY = __previousTouchedPosition.y - __currentMovedPosition.y;
467 if (_Abs(scrollDistanceY) < _Abs(scrollDistanceX))
469 __firstScrollMoveDirection = SCROLL_PANEL_SCROLL_DIRECTION_HORIZONTAL;
471 else if (_Abs(scrollDistanceY) > _Abs(scrollDistanceX))
473 __firstScrollMoveDirection = SCROLL_PANEL_SCROLL_DIRECTION_VERTICAL;
477 __firstScrollMoveDirection = scrollDirection;
480 __firstTouchMove = false;
488 _ScrollPanelPresenter::RunTouchReleased(const _Control& source, const _TouchInfo& touchInfo)
490 SysTryReturn(NID_UI_CTRL, __pPressedControl == &source, E_INVALID_OPERATION, E_INVALID_OPERATION, "[%s] source has changed during touch process.", GetErrorMessage(E_INVALID_OPERATION));
492 __touchPressed = false;
493 __firstTouchMove = true;
495 if (__pScrollPanel->IsPageScrollEnabled() && !__flickRunning && !__jumpToTopRunning)
497 float currentPosition = GetScrollPosition();
498 float targetPosition = CalculatePagingScrollPosition(currentPosition);
500 if (targetPosition > currentPosition || targetPosition < currentPosition)
502 SetScrollPosition(targetPosition, true);
503 result r = GetLastResult();
504 SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
508 // scrollpanel child control touch released
509 if (__pScrollPanel != &source)
511 // for ScrollPanelEventListener
512 if (__subControlMoved)
514 __pScrollPanel->FireScrollPanelEvent(source, CORE_OTHER_CONTROL_SELECTED);
518 __pPressedControl = null;
519 __subControlMoved = false;
521 if (!__scrollAnimationRunning)
523 RollbackBouncing(true);
524 result r = GetLastResult();
525 SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
529 SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
533 __scrollOccured = false;
534 __pScrollPanel->FireOnScrollStoppedEvent();
542 _ScrollPanelPresenter::RunTouchCanceled(const _Control& source, const _TouchInfo& touchinfo)
544 SysTryReturn(NID_UI_CTRL, __pPressedControl == &source, E_INVALID_OPERATION, E_INVALID_OPERATION, "[%s] source has changed during touch process.", GetErrorMessage(E_INVALID_OPERATION));
546 __touchPressed = false;
547 __firstTouchMove = true;
549 __pPressedControl = null;
550 __subControlMoved = false;
552 if (!__scrollAnimationRunning)
554 RollbackBouncing(true);
555 result r = GetLastResult();
556 SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
560 SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
563 if (__scrollOccured && !__scrollAnimationRunning)
565 __scrollOccured = false;
566 __pScrollPanel->FireOnScrollStoppedEvent();
572 _UiTouchEventDelivery
573 _ScrollPanelPresenter::OnPreviewTouchPressed(const _Control& source, const _TouchInfo& touchInfo)
575 return _UI_TOUCH_EVENT_DELIVERY_FORCED_YES;
578 _UiTouchEventDelivery
579 _ScrollPanelPresenter::OnPreviewTouchMoved(const _Control& source, const _TouchInfo& touchInfo)
581 RunPreviewTouchMoved(source, touchInfo);
583 return _UI_TOUCH_EVENT_DELIVERY_YES;
586 _UiTouchEventDelivery
587 _ScrollPanelPresenter::OnPreviewTouchReleased(const _Control& source, const _TouchInfo& touchInfo)
589 return _UI_TOUCH_EVENT_DELIVERY_FORCED_YES;
592 _UiTouchEventDelivery
593 _ScrollPanelPresenter::OnPreviewTouchCanceled(const _Control& source, const _TouchInfo& touchInfo)
595 return _UI_TOUCH_EVENT_DELIVERY_FORCED_YES;
599 _ScrollPanelPresenter::OnTouchPressed(const _Control& source, const _TouchInfo& touchInfo)
601 result r = RunTouchPressed(source, touchInfo);
602 SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, true, r, "[%s] Propagating.", GetErrorMessage(r));
608 _ScrollPanelPresenter::OnTouchMoved(const _Control& source, const _TouchInfo& touchInfo)
610 if (__pPressedControl != &source)
625 FloatPoint touchPoint = FloatPoint(touchInfo.GetCurrentPosition().x, touchInfo.GetCurrentPosition().y);
626 if (!_FloatCompare(__currentMovedPosition.x, touchPoint.x)
627 || !_FloatCompare(__currentMovedPosition.y, touchPoint.y))
629 RunPreviewTouchMoved(source, touchInfo);
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;
639 if (scrollInputMode == SCROLL_INPUT_MODE_RESTRICT_TO_INITIAL_DIRECTION)
641 if (scrollDirection == __firstScrollMoveDirection)
643 if (scrollDirection == SCROLL_PANEL_SCROLL_DIRECTION_HORIZONTAL)
645 scrollDistance = scrollDistanceX;
647 else if (scrollDirection == SCROLL_PANEL_SCROLL_DIRECTION_VERTICAL)
649 scrollDistance = scrollDistanceY;
654 RollbackBouncing(true);
655 result r = GetLastResult();
656 SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, false, r, "[%s] Propagating.", GetErrorMessage(r));
660 SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, false, r, "[%s] Propagating.", GetErrorMessage(r));
662 if ((__firstScrollMoveDirection == SCROLL_PANEL_SCROLL_DIRECTION_HORIZONTAL && _Abs(scrollDistanceY) > _Abs(scrollDistanceX))
663 || (__firstScrollMoveDirection == SCROLL_PANEL_SCROLL_DIRECTION_VERTICAL && _Abs(scrollDistanceY) < _Abs(scrollDistanceX)))
675 if (scrollDirection == SCROLL_PANEL_SCROLL_DIRECTION_HORIZONTAL)
677 if (_Abs(scrollDistanceY) <= _Abs(scrollDistanceX))
679 scrollDistance = scrollDistanceX;
686 else if (scrollDirection == SCROLL_PANEL_SCROLL_DIRECTION_VERTICAL)
688 if (_Abs(scrollDistanceY) >= _Abs(scrollDistanceX))
690 scrollDistance = scrollDistanceY;
699 if (!_FloatCompare(scrollDistance, 0.0f))
702 result r = GetLastResult();
703 SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, true, r, "[%s] Propagating.", GetErrorMessage(r));
705 float realMoveDistance = ScrollTo(scrollDistance + GetScrollPositionInternal());
707 SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, false, r, "[%s] Propagating.", GetErrorMessage(r));
709 if (_FloatCompare(realMoveDistance, 0.0f))
711 // not moved and bubbling
712 if (scrollInputMode == SCROLL_INPUT_MODE_RESTRICT_TO_INITIAL_DIRECTION)
714 if (scrollDirection == SCROLL_PANEL_SCROLL_DIRECTION_HORIZONTAL)
716 if (_Abs(scrollDistanceY) < _Abs(scrollDistanceX))
725 else if (scrollDirection == SCROLL_PANEL_SCROLL_DIRECTION_VERTICAL)
727 if (_Abs(scrollDistanceY) > _Abs(scrollDistanceX))
753 _ScrollPanelPresenter::OnTouchReleased(const _Control& source, const _TouchInfo& touchInfo)
755 result r = RunTouchReleased(source, touchInfo);
756 SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, true, r, "[%s] Propagating.", GetErrorMessage(r));
762 _ScrollPanelPresenter::OnTouchCanceled(const _Control& source, const _TouchInfo& touchInfo)
764 result r = RunTouchCanceled(source, touchInfo);
765 SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, true, r, "[%s] Propagating.", GetErrorMessage(r));
771 _ScrollPanelPresenter::OnTouchMoveHandled(const _Control& control)
773 RollbackBouncing(true);
774 result r = GetLastResult();
775 SysTryReturnVoidResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
779 SysTryReturnVoidResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
783 _ScrollPanelPresenter::OnScrollEndReached(_Control& source, ScrollEndEvent type)
788 _ScrollPanelPresenter::OnScrollPositionChanged(_Control& source, float scrollPosition)
790 if (&source != __pScrollPanel->GetScrollBar())
796 result r = GetLastResult();
797 SysTryReturnVoidResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
799 SetScrollPosition(scrollPosition, false);
803 _ScrollPanelPresenter::OnScrollStopped(_Control& source)
805 if (&source != __pScrollPanel->GetScrollBar())
811 result r = GetLastResult();
812 SysTryReturnVoidResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
816 _ScrollPanelPresenter::OnScrollJumpToTop(_Control& source)
818 if (&source != __pScrollPanel->GetScrollBar())
823 __jumpToTopRunning = true;
824 SetScrollPosition(0, true);
828 _ScrollPanelPresenter::DoFlickGestureRecognized(_TouchFlickGestureDetector& gesture)
835 FloatRectangle scrollArea = GetScrollAreaBounds();
836 FloatRectangle scrollPanelBounds = __pScrollPanel->GetBoundsF();
838 float distanceX = 0.0f;
839 float distanceY = 0.0f;
840 gesture.GetDistance(distanceX, distanceY);
841 _FlickDirection moveDirection = _FLICK_DIRECTION_NONE;
843 if (_Abs(distanceX) > _Abs(distanceY))
845 if (distanceX < 0.0f)
847 moveDirection = _FLICK_DIRECTION_LEFT;
849 else if (distanceX > 0.0f)
851 moveDirection = _FLICK_DIRECTION_RIGHT;
856 if (distanceY < 0.0f)
858 moveDirection = _FLICK_DIRECTION_UP;
860 else if (distanceY > 0.0f)
862 moveDirection = _FLICK_DIRECTION_DOWN;
866 if (__pScrollPanel->GetScrollDirection() == SCROLL_PANEL_SCROLL_DIRECTION_HORIZONTAL)
868 if (moveDirection != _FLICK_DIRECTION_RIGHT && moveDirection != _FLICK_DIRECTION_LEFT)
875 if (moveDirection != _FLICK_DIRECTION_DOWN && moveDirection != _FLICK_DIRECTION_UP)
881 if (__pScrollPanel->IsPageScrollEnabled() && __pScrollPanel->IsPageScrollFlickMoveLimitedOnePage())
883 float currentScrollPosition = GetScrollPosition();
884 float targetPosition = currentScrollPosition;
886 if (__pScrollPanel->GetScrollDirection() == SCROLL_PANEL_SCROLL_DIRECTION_HORIZONTAL)
888 float pageSize = __pScrollPanel->GetPageScrollAlignSize().width;
891 if (moveDirection == _FLICK_DIRECTION_LEFT)
893 targetPosition = (((int)(currentScrollPosition / pageSize)) + 1) * pageSize;
896 else if (moveDirection == _FLICK_DIRECTION_RIGHT)
898 targetPosition = ((int)(currentScrollPosition / pageSize)) * pageSize;
903 float pageSize = __pScrollPanel->GetPageScrollAlignSize().height;
906 if (moveDirection == _FLICK_DIRECTION_UP)
908 targetPosition = (((int)(currentScrollPosition / pageSize)) + 1) * pageSize;
911 else if (moveDirection == _FLICK_DIRECTION_DOWN)
913 targetPosition = ((int)(currentScrollPosition / pageSize)) * pageSize;
917 targetPosition = FixScrollPositionIntoScrollAreaBounds(targetPosition);
918 if (_FloatCompare(targetPosition, currentScrollPosition))
923 __flickRunning = true;
925 ScrollTo(targetPosition, true);
926 result r = GetLastResult();
927 SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, false, r, "[%s] Propagating.", GetErrorMessage(r));
931 SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, false, r, "[%s] Propagating.", GetErrorMessage(r));
937 float moveAmount = 0.0f;
938 float flickAmount = 0.0f;
940 // calculate flick amount
941 if (__pScrollPanel->GetScrollDirection() == SCROLL_PANEL_SCROLL_DIRECTION_HORIZONTAL)
943 flickAmount = CalculateFlickAmount(distanceX, gesture.GetDuration());
947 flickAmount = CalculateFlickAmount(distanceY, gesture.GetDuration());
950 moveAmount = -flickAmount;
953 if (__pScrollPanel->IsPageScrollEnabled())
955 float scrollPosition = 0.0f;
956 float maxPosition = 0.0f;
957 float pageSize = 0.0f;
959 if (__pScrollPanel->GetScrollDirection() == SCROLL_PANEL_SCROLL_DIRECTION_HORIZONTAL)
961 pageSize = __pScrollPanel->GetPageScrollAlignSize().width;
962 maxPosition = scrollArea.width - scrollPanelBounds.width;
963 scrollPosition = __pScrollPanelModel->GetCurrentHorizontalScrollPosition();
967 pageSize = __pScrollPanel->GetPageScrollAlignSize().height;
968 maxPosition = scrollArea.height - scrollPanelBounds.height;
969 scrollPosition = __pScrollPanelModel->GetCurrentVerticalScrollPosition();
972 int lowerPageIndex = (scrollPosition + moveAmount) / pageSize;
973 float targetPageMin = pageSize * lowerPageIndex;
974 float pageGap = (scrollPosition + moveAmount) - targetPageMin;
975 float targetPageMax = targetPageMin + pageSize;
977 if (pageGap <= targetPageMax - targetPageMin - pageGap)
979 moveAmount = targetPageMin - scrollPosition;
983 moveAmount = targetPageMax - scrollPosition;
987 if (!_FloatCompare(moveAmount, 0.0f))
989 // scroll with animation
990 __flickRunning = true;
992 if (AccumulateFlickGesture(moveDirection))
997 // limited flick amount
998 float targetPosition = moveAmount + GetScrollPositionInternal();
999 float scrollToPosition = FixScrollPositionIntoScrollAreaBounds(targetPosition);
1000 if (_Abs(scrollToPosition - targetPosition) > SCROLL_PANEL_OVERSCROLLING_MAX_DISTANCCE)
1002 switch (moveDirection)
1004 case _FLICK_DIRECTION_UP:
1005 targetPosition = scrollArea.height - scrollPanelBounds.height + SCROLL_PANEL_OVERSCROLLING_MAX_DISTANCCE;
1007 case _FLICK_DIRECTION_DOWN:
1008 targetPosition = scrollArea.y - SCROLL_PANEL_OVERSCROLLING_MAX_DISTANCCE;
1010 case _FLICK_DIRECTION_LEFT:
1011 targetPosition = scrollArea.width - scrollPanelBounds.width + SCROLL_PANEL_OVERSCROLLING_MAX_DISTANCCE;
1013 case _FLICK_DIRECTION_RIGHT:
1014 targetPosition = scrollArea.x - SCROLL_PANEL_OVERSCROLLING_MAX_DISTANCCE;
1021 FlickTo(targetPosition, gesture.GetDuration());
1022 result r = GetLastResult();
1023 SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, false, r, "[%s] Propagating.", GetErrorMessage(r));
1026 r = GetLastResult();
1027 SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, false, r, "[%s] Propagating.", GetErrorMessage(r));
1039 _ScrollPanelPresenter::OnFlickGestureDetected(_TouchFlickGestureDetector& gesture)
1041 return DoFlickGestureRecognized(gesture);
1045 _ScrollPanelPresenter::OnFlickGestureCanceled(_TouchFlickGestureDetector& gesture)
1047 StopScrollingAnimation();
1048 RollbackBouncing(true);
1049 result r = GetLastResult();
1050 SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, false, r, "[%s] Propagating.", GetErrorMessage(r));
1056 _ScrollPanelPresenter::IsControlOutOfView(const _Control& control) const
1058 FloatRectangle controlBounds = control.GetAbsoluteBoundsF();
1059 FloatRectangle scrollPanelBounds = __pScrollPanel->GetAbsoluteBoundsF();
1061 // is control out of view area
1062 if (__pScrollPanel->GetScrollDirection() == SCROLL_PANEL_SCROLL_DIRECTION_HORIZONTAL)
1064 if (controlBounds.x < scrollPanelBounds.x || controlBounds.x + controlBounds.width > scrollPanelBounds.x + scrollPanelBounds.width)
1071 if (controlBounds.y < scrollPanelBounds.y || controlBounds.y + controlBounds.height > scrollPanelBounds.y + scrollPanelBounds.height)
1081 _ScrollPanelPresenter::ScrollToControlWhenOutOfView(const _Control& control)
1083 if (IsControlOutOfView(control))
1085 ScrollToControl(control, true);
1086 result r = GetLastResult();
1087 SysTryReturnVoidResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
1092 _ScrollPanelPresenter::CalculatePagingScrollPosition(float position) const
1094 float maxPosition = 0.0f;
1095 float pageSize = 0.0f;
1097 if (__pScrollPanel->GetScrollDirection() == SCROLL_PANEL_SCROLL_DIRECTION_HORIZONTAL)
1099 pageSize = __pScrollPanel->GetPageScrollAlignSize().width;
1100 maxPosition = GetScrollAreaBounds().width - __pScrollPanel->GetBoundsF().width;
1104 pageSize = __pScrollPanel->GetPageScrollAlignSize().height;
1105 maxPosition = GetScrollAreaBounds().height - __pScrollPanel->GetBoundsF().height;
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)
1115 currentPageMax = maxPosition;
1118 if (pageGap <= currentPageMax - currentPageMin - pageGap)
1120 targetPosition = currentPageMin;
1124 targetPosition = currentPageMax;
1127 return targetPosition;
1131 _ScrollPanelPresenter::RollbackBouncing(bool withAnimation)
1133 if (!IsScrollable())
1138 float scrollPosition = GetScrollPositionInternal();
1139 float fixedScrollPosition = FixScrollPositionIntoScrollAreaBounds(scrollPosition);
1141 // there are no rollbacking animation
1142 withAnimation = false;
1144 if (!_FloatCompare(scrollPosition, fixedScrollPosition))
1147 result r = GetLastResult();
1148 SysTryReturnVoidResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
1150 ScrollTo(fixedScrollPosition, withAnimation);
1151 r = GetLastResult();
1152 SysTryReturnVoidResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
1154 if (!__scrollAnimationRunning)
1157 r = GetLastResult();
1158 SysTryReturnVoidResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
1164 _ScrollPanelPresenter::OnAccessibilityFocusMovedNext(const _AccessibilityContainer& control, const _AccessibilityElement& element)
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));
1175 _ScrollPanelPresenter::OnAccessibilityFocusMovedPrevious(const _AccessibilityContainer& control, const _AccessibilityElement& element)
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));
1186 _ScrollPanelPresenter::OnAccessibilityReadingElement(const _AccessibilityContainer& control, const _AccessibilityElement& element)
1191 _ScrollPanelPresenter::OnAccessibilityReadElement(const _AccessibilityContainer& control, const _AccessibilityElement& element)
1196 _ScrollPanelPresenter::OnAccessibilityFocusIn(const _AccessibilityContainer& control, const _AccessibilityElement& element)
1202 _ScrollPanelPresenter::OnAccessibilityFocusOut(const _AccessibilityContainer& control, const _AccessibilityElement& element)
1208 _ScrollPanelPresenter::OnAccessibilityActionPerformed(const _AccessibilityContainer& control, const _AccessibilityElement& element)
1214 _ScrollPanelPresenter::OnChildControlFocusMoved(const _Control& control)
1216 ScrollToControlWhenOutOfView(control);
1220 _ScrollPanelPresenter::OnDescendantControlFocusMoved(const _Control& control)
1222 ScrollToControlWhenOutOfView(control);
1226 _ScrollPanelPresenter::OnAccessibilityItemRefreshed(const _AccessibilityContainer& control, const _AccessibilityElement& element, _AccessibilityFocusDirection direction)
1232 _ScrollPanelPresenter::OnTimerExpired(Tizen::Base::Runtime::Timer& timer)
1234 if (&timer == __pScrollBarLoadEffectTimer)
1236 __scrollBarLoadEffectStatus = _SCROLL_PANEL_SCROLL_BAR_LOAD_EFFECT_LOADED;
1238 delete __pScrollBarLoadEffectTimer;
1239 __pScrollBarLoadEffectTimer = null;
1242 result r = GetLastResult();
1243 SysTryReturnVoidResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
1248 _ScrollPanelPresenter::OnVisualElementAnimationStarted(const VisualElementAnimation& animation, const String& keyName, VisualElement& target)
1254 _ScrollPanelPresenter::OnVisualElementAnimationRepeated(const VisualElementAnimation& animation, const String& keyName, VisualElement& target, long currentRepeatCount)
1260 _ScrollPanelPresenter::OnVisualElementAnimationFinished(const VisualElementAnimation& animation, const String& keyName, VisualElement& target, bool completedNormally)
1262 __scrollAnimationRunning = false;
1263 __flickRunning = false;
1265 if (__scrollOccured)
1267 __scrollOccured = false;
1268 __pScrollPanel->FireOnScrollStoppedEvent();
1271 if (!__jumpToTopRunning && !__modelUpdating)
1273 RollbackBouncing(completedNormally);
1274 result r = GetLastResult();
1275 SysTryReturnVoidResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
1277 __jumpToTopRunning = false;
1279 if (!__scrollAnimationRunning)
1282 result r = GetLastResult();
1283 SysTryReturnVoidResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
1288 _ScrollPanelPresenter::OnTickOccurred(const VisualElementAnimation& animation, const String& keyName, VisualElement& target, const Variant& currentValue)
1290 _VisualElement* pVisualElement = __pScrollPanel->GetVisualElement();
1292 if (&target != pVisualElement)
1297 if (keyName == SCROLLING_ANIMATION_NAME)
1299 if (!__scrollAnimationRunning)
1304 ScrollToInternal(currentValue.ToFloat());
1309 _ScrollPanelPresenter::UpdateLayout(void)
1311 __pScrollPanel->PartialUpdateLayout();
1315 _ScrollPanelPresenter::AdjustModel()
1317 _Scroll* pHorizontalScrollBar = __pScrollPanel->GetHorizontalScrollBar();
1318 _Scroll* pVerticalScrollBar = __pScrollPanel->GetVerticalScrollBar();
1320 FloatRectangle scrollPanelBounds = __pScrollPanel->GetBoundsF();
1321 ScrollPanelScrollDirection scrollDirection = __pScrollPanel->GetScrollDirection();
1322 FloatRectangle scrollArea = FloatRectangle(0.0f, 0.0f, scrollPanelBounds.width, scrollPanelBounds.height);
1324 if (__pScrollPanel->IsScrollAreaAutoResizingEnabled())
1326 int count = __pScrollPanel->GetChildCount();
1328 if (__pScrollPanel->GetScrollDirection() == SCROLL_PANEL_SCROLL_DIRECTION_VERTICAL)
1330 for (int i = 0; i < count; i++)
1332 _Control* pControl = __pScrollPanel->GetChild(i);
1333 SysTryReturnVoidResult(NID_UI_CTRL, pControl != null, E_SYSTEM, "[%s] pControl(child) is invalid pointer.", GetErrorMessage(E_SYSTEM));
1335 if (pControl->GetArea() == _CONTROL_AREA_SYSTEM)
1340 float targetMaxPos = pControl->GetBoundsF().GetBottomRight().y;
1341 if (scrollArea.height < targetMaxPos)
1343 scrollArea.height = targetMaxPos;
1347 else if (__pScrollPanel->GetScrollDirection() == SCROLL_PANEL_SCROLL_DIRECTION_HORIZONTAL)
1349 for (int i = 0; i < count; i++)
1351 _Control* pControl = __pScrollPanel->GetChild(i);
1352 SysTryReturnVoidResult(NID_UI_CTRL, pControl != null, E_SYSTEM, "[%s] pControl(child) is invalid pointer.", GetErrorMessage(E_SYSTEM));
1354 if (pControl->GetArea() == _CONTROL_AREA_SYSTEM)
1359 float targetMaxPos = pControl->GetBoundsF().GetBottomRight().x;
1360 if (scrollArea.width < targetMaxPos)
1362 scrollArea.width = targetMaxPos;
1369 scrollArea = GetScrollAreaBounds();
1370 if (scrollDirection == SCROLL_PANEL_SCROLL_DIRECTION_HORIZONTAL)
1372 if (scrollArea.width < scrollPanelBounds.width)
1374 scrollArea.width = scrollPanelBounds.width;
1376 scrollArea.height = scrollPanelBounds.height;
1380 scrollArea.width = scrollPanelBounds.width;
1381 if (scrollArea.height < scrollPanelBounds.height)
1383 scrollArea.height = scrollPanelBounds.height;
1388 // change model values
1389 SetScrollAreaBoundsInternal(scrollArea);
1390 FloatDimension alignSize = FloatDimension(scrollPanelBounds.width, scrollPanelBounds.height);
1391 __pScrollPanel->SetPageScrollAlignSize(alignSize);
1393 // before change model ScrollPosition fix
1394 if (__modelUpdating)
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))
1402 ScrollTo(fixedScrollPosition, false);
1403 result r = GetLastResult();
1404 SysTryReturnVoidResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
1407 __modelUpdating = false;
1408 __previousBounds = __pScrollPanel->GetBoundsF();
1409 __previousScrollAreaBounds = GetScrollAreaBounds();
1413 if (scrollDirection == SCROLL_PANEL_SCROLL_DIRECTION_HORIZONTAL)
1415 if (scrollPanelBounds.width > 0)
1417 if (pHorizontalScrollBar != null)
1419 pHorizontalScrollBar->OnParentBoundsChanged();
1422 if (!IsScrollable() && !_FloatCompare(scrollArea.x, GetScrollPosition()))
1424 SetScrollPosition(scrollArea.x, false);
1425 result r = GetLastResult();
1426 SysTryReturnVoidResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
1432 if (scrollPanelBounds.height > 0)
1434 if (pVerticalScrollBar != null)
1436 pVerticalScrollBar->OnParentBoundsChanged();
1439 if (!IsScrollable() && !_FloatCompare(scrollArea.y, GetScrollPosition()))
1441 SetScrollPosition(scrollArea.y, false);
1442 result r = GetLastResult();
1443 SysTryReturnVoidResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
1448 // update scrollbar range
1449 ChangeScrollBarRange();
1450 result r = GetLastResult();
1451 SysTryReturnVoidResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
1453 if (!__scrollAnimationRunning)
1456 result r = GetLastResult();
1457 SysTryReturnVoidResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
1462 _ScrollPanelPresenter::ScrollToControl(const _Control& source, bool recursive)
1464 SysTryReturn(NID_UI_CTRL, __pScrollPanel->GetChildCount() != 0, false, E_INVALID_ARG, "[%s] ScrollPanel have no child control.", GetErrorMessage(E_INVALID_ARG));
1466 FloatPoint controlPosition = source.GetPositionF();
1469 SysTryReturn(NID_UI_CTRL, __pScrollPanel->GetChildIndex(source) != -1, false, E_INVALID_ARG, "[%s] source is not a child control.", GetErrorMessage(E_INVALID_ARG));
1473 SysTryReturn(NID_UI_CTRL, __pScrollPanel->IsAncestorOf(source), false, E_INVALID_ARG, "[%s] source is not a child control.", GetErrorMessage(E_INVALID_ARG));
1475 _Control* pParent = source.GetParent();
1476 while (pParent != null && pParent != __pScrollPanel)
1478 _ScrollPanel* pScrollPanelParent = dynamic_cast<_ScrollPanel*> (pParent);
1479 if (pScrollPanelParent != null)
1481 FloatDimension pagingGap(0.0f, 0.0f);
1482 if (pScrollPanelParent->IsPageScrollEnabled())
1484 FloatPoint pagingPosition = controlPosition;
1485 if (pScrollPanelParent->GetScrollDirection() == SCROLL_PANEL_SCROLL_DIRECTION_HORIZONTAL)
1487 pagingPosition.x = pScrollPanelParent->CalculatePagingScrollPosition(controlPosition.x);
1488 pagingGap.width = controlPosition.x - pagingPosition.x;
1489 if (pagingGap.width < 0.0f)
1491 pagingPosition.x -= pScrollPanelParent->GetPageScrollAlignSize().width;
1492 pagingGap.width += pScrollPanelParent->GetPageScrollAlignSize().width;
1497 pagingPosition.y = pScrollPanelParent->CalculatePagingScrollPosition(controlPosition.y);
1498 pagingGap.height = controlPosition.y - pagingPosition.y;
1499 if (pagingGap.height < 0.0f)
1501 pagingPosition.y -= pScrollPanelParent->GetPageScrollAlignSize().height;
1502 pagingGap.height += pScrollPanelParent->GetPageScrollAlignSize().height;
1506 pScrollPanelParent->SetScrollPosition(pagingPosition, false);
1510 pScrollPanelParent->SetScrollPosition(controlPosition, false);
1513 controlPosition.x -= pScrollPanelParent->GetHorizontalScrollPosition() + pagingGap.width;
1514 controlPosition.y -= pScrollPanelParent->GetVerticalScrollPosition() + pagingGap.height;
1517 FloatPoint parentPosition = pParent->GetPositionF();
1518 controlPosition.x += parentPosition.x;
1519 controlPosition.y += parentPosition.y;
1521 pParent = pParent->GetParent();
1525 if (__pScrollPanel->IsPageScrollEnabled())
1527 FloatPoint pagingPosition = controlPosition;
1528 if (__pScrollPanel->GetScrollDirection() == SCROLL_PANEL_SCROLL_DIRECTION_HORIZONTAL)
1530 pagingPosition.x = CalculatePagingScrollPosition(controlPosition.x);
1531 if (pagingPosition.x > controlPosition.x)
1533 controlPosition.x = pagingPosition.x - __pScrollPanel->GetPageScrollAlignSize().width;
1537 controlPosition.x = pagingPosition.x;
1542 pagingPosition.y = CalculatePagingScrollPosition(controlPosition.y);
1543 if (pagingPosition.y > controlPosition.y)
1545 controlPosition.y = pagingPosition.y - __pScrollPanel->GetPageScrollAlignSize().height;
1549 controlPosition.y = pagingPosition.y;
1553 SetScrollPosition(controlPosition, true);
1554 result r = GetLastResult();
1555 SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, false, r, "[%s] Propagating.", GetErrorMessage(r));
1561 _ScrollPanelPresenter::ScrollTo(float targetPosition)
1563 return ScrollTo(targetPosition, false);
1567 _ScrollPanelPresenter::ScrollTo(float targetPosition, bool withAnimation)
1569 StopScrollingAnimation();
1573 // Calculate real move distance
1574 float scrollToPosition = FixScrollPositionIntoScrollAreaBounds(targetPosition);
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);
1585 return scrollToPosition - oldPosition;
1589 return ScrollToInternal(targetPosition);
1594 _ScrollPanelPresenter::ScrollToInternal(float targetPosition)
1596 ScrollPanelScrollDirection scrollDirection = __pScrollPanel->GetScrollDirection();
1597 _VisualElement* pVisualElement = __pScrollPanel->GetVisualElement();
1598 float previousScrollPosition = GetScrollPositionInternal();
1599 float distance = 0.0f;
1600 FloatPoint floatPointDistance;
1602 float scrollToPosition = FixScrollPositionIntoScrollAreaBounds(targetPosition);
1604 if (scrollDirection == SCROLL_PANEL_SCROLL_DIRECTION_HORIZONTAL)
1606 distance = scrollToPosition - FixScrollPositionIntoScrollAreaBounds(previousScrollPosition, __previousBounds, __previousScrollAreaBounds);
1607 floatPointDistance.SetPosition(-distance, 0.0f);
1611 distance = scrollToPosition - FixScrollPositionIntoScrollAreaBounds(previousScrollPosition, __previousBounds, __previousScrollAreaBounds);
1612 floatPointDistance.SetPosition(0.0f, -distance);
1615 if (!_FloatCompare(distance, 0))
1617 result r = pVisualElement->ScrollByPoint(floatPointDistance, false);
1618 SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, 0, r, "[%s] Propagating.", GetErrorMessage(r));
1620 __scrollOccured = true;
1623 ChangeScrollBarPosition(targetPosition);
1624 SetScrollPositionInternal(targetPosition);
1626 if (!_FloatCompare(distance, 0))
1628 FloatRectangle scrollPanelBounds = __pScrollPanel->GetBoundsF();
1629 FloatRectangle scrollArea = GetScrollAreaBounds();
1631 if (scrollDirection == SCROLL_PANEL_SCROLL_DIRECTION_HORIZONTAL)
1633 if (scrollArea.width > scrollPanelBounds.width)
1635 float minScrollPos = scrollArea.x;
1636 float maxScrollPos = scrollArea.width - scrollPanelBounds.width;
1638 if ((targetPosition >= minScrollPos && targetPosition <= maxScrollPos)
1639 || (previousScrollPosition > minScrollPos || previousScrollPosition < maxScrollPos))
1641 __pScrollPanel->FireOnScrollPositionChangedEvent();
1644 if (previousScrollPosition > minScrollPos && previousScrollPosition < maxScrollPos)
1646 if (targetPosition <= minScrollPos)
1648 __pScrollPanel->FireOnScrollEndEvent(SCROLL_END_EVENT_END_LEFT);
1650 else if (targetPosition >= maxScrollPos)
1652 __pScrollPanel->FireOnScrollEndEvent(SCROLL_END_EVENT_END_RIGHT);
1659 if (scrollArea.height > scrollPanelBounds.height)
1661 float minScrollPos = scrollArea.y;
1662 float maxScrollPos = scrollArea.height - scrollPanelBounds.height;
1664 if ((targetPosition >= minScrollPos && targetPosition <= maxScrollPos)
1665 || (previousScrollPosition > minScrollPos || previousScrollPosition < maxScrollPos))
1667 __pScrollPanel->FireOnScrollPositionChangedEvent();
1670 if (previousScrollPosition > minScrollPos && previousScrollPosition < maxScrollPos)
1672 if (targetPosition <= minScrollPos)
1674 __pScrollPanel->FireOnScrollEndEvent(SCROLL_END_EVENT_END_TOP);
1676 else if (targetPosition >= maxScrollPos)
1678 __pScrollPanel->FireOnScrollEndEvent(SCROLL_END_EVENT_END_BOTTOM);
1689 _ScrollPanelPresenter::ChangeScrollBarPosition(float position)
1691 _Scroll* pScrollBar = __pScrollPanel->GetScrollBar();
1693 if (pScrollBar != null && __pScrollPanel->IsAncestorOf(*pScrollBar))
1695 if (__pScrollPanel->GetScrollDirection() == SCROLL_PANEL_SCROLL_DIRECTION_HORIZONTAL)
1697 result r = pScrollBar->SetScrollPosition(position);
1698 SysTryReturnVoidResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
1702 result r = pScrollBar->SetScrollPosition(position);
1703 SysTryReturnVoidResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
1709 _ScrollPanelPresenter::ChangeScrollBarRange(void)
1711 _Scroll* pScrollBar = __pScrollPanel->GetScrollBar();
1713 if (pScrollBar != null)
1715 float viewRange = 0.0f;
1716 float scrollRange = 0.0f;
1718 if (__pScrollPanel->GetScrollDirection() == SCROLL_PANEL_SCROLL_DIRECTION_HORIZONTAL)
1720 viewRange = __pScrollPanel->GetBoundsF().width;
1721 scrollRange = GetScrollAreaBounds().width;
1725 viewRange = __pScrollPanel->GetBoundsF().height;
1726 scrollRange = GetScrollAreaBounds().height;
1729 if (viewRange <= scrollRange)
1731 result r = pScrollBar->SetScrollRange(viewRange, scrollRange);
1732 SysTryReturnVoidResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
1734 if (!_FloatCompare(viewRange, scrollRange))
1736 if (__scrollBarLoadEffectStatus == _SCROLL_PANEL_SCROLL_BAR_LOAD_EFFECT_UNLOAD)
1738 __scrollBarLoadEffectStatus = _SCROLL_PANEL_SCROLL_BAR_LOAD_EFFECT_LOADING;
1742 DoScrollBarLoadEffect();
1748 __scrollBarLoadEffectStatus = _SCROLL_PANEL_SCROLL_BAR_LOAD_EFFECT_UNLOAD;
1755 _ScrollPanelPresenter::DoScrollBarLoadEffect(void)
1757 if (__pScrollPanel->IsScrollBarVisible())
1760 result r = GetLastResult();
1761 SysTryReturnVoidResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
1763 StartScrollBarLoadEffectTimer();
1764 r = GetLastResult();
1765 SysTryReturnVoidResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
1769 __scrollBarLoadEffectStatus = _SCROLL_PANEL_SCROLL_BAR_LOAD_EFFECT_UNLOAD;
1774 _ScrollPanelPresenter::StartScrollBarLoadEffectTimer(void)
1776 result r = E_SUCCESS;
1778 if (__pScrollBarLoadEffectTimer == null && __scrollBarLoadEffectStatus == _SCROLL_PANEL_SCROLL_BAR_LOAD_EFFECT_LOADING)
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));
1783 r = __pScrollBarLoadEffectTimer->Construct(*this);
1784 SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
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));
1793 delete __pScrollBarLoadEffectTimer;
1794 __pScrollBarLoadEffectTimer = null;
1800 _ScrollPanelPresenter::StopScrollBarLoadEffectTimer(void)
1802 if (__pScrollBarLoadEffectTimer)
1804 __pScrollBarLoadEffectTimer->Cancel();
1809 _ScrollPanelPresenter::FadeOutScrollBar(void)
1811 if (!__scrollAnimationRunning)
1813 _Scroll* pScrollBar = __pScrollPanel->GetScrollBar();
1814 if (pScrollBar != null)
1816 if ((!__pScrollPanel->IsScrollBarVisible() || !IsScrollable())
1817 || (!pScrollBar->IsEnabledHandler() && __scrollBarLoadEffectStatus == _SCROLL_PANEL_SCROLL_BAR_LOAD_EFFECT_LOADED))
1819 result r = pScrollBar->SetScrollVisibility(false);
1820 SysTryReturnVoidResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
1823 result r = pScrollBar->SetScrollingEffectVisibility(false);
1824 SysTryReturnVoidResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
1830 _ScrollPanelPresenter::StopFadeOutScrollBar(void)
1832 _Scroll* pScrollBar = __pScrollPanel->GetScrollBar();
1834 if (pScrollBar != null)
1836 pScrollBar->CancelFadeEffect();
1841 _ScrollPanelPresenter::FadeInScrollBar(void)
1843 if (!IsScrollable())
1848 _Scroll* pScrollBar = __pScrollPanel->GetScrollBar();
1850 if (pScrollBar != null)
1852 if (__pScrollPanel->IsScrollBarVisible())
1854 result r = pScrollBar->SetScrollVisibility(true);
1855 SysTryReturnVoidResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
1858 result r = pScrollBar->SetScrollingEffectVisibility(true);
1859 SysTryReturnVoidResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
1864 _ScrollPanelPresenter::IsScrollable(void) const
1866 if (__pScrollPanel->GetScrollDirection() == SCROLL_PANEL_SCROLL_DIRECTION_HORIZONTAL)
1868 return __pScrollPanel->GetBoundsF().width >0 && __pScrollPanel->GetBoundsF().width < GetScrollAreaBounds().width;
1872 return __pScrollPanel->GetBoundsF().height > 0 && __pScrollPanel->GetBoundsF().height < GetScrollAreaBounds().height;
1877 _ScrollPanelPresenter::GetScrollAreaBounds(void) const
1879 return __pScrollPanelModel->GetScrollAreaBounds();
1883 _ScrollPanelPresenter::SetClientAreaHeight(float height)
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;
1889 return SetScrollAreaBounds(bounds);
1893 _ScrollPanelPresenter::SetClientAreaWidth(float width)
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;
1899 return SetScrollAreaBounds(bounds);
1903 _ScrollPanelPresenter::SetScrollAreaBoundsInternal(FloatRectangle& bounds)
1905 if (__pScrollPanel->IsFixingClientBoundsEnabled())
1907 __pScrollPanel->SetClientBounds(bounds);
1909 __pScrollPanelModel->SetScrollAreaBounds(bounds);
1913 _ScrollPanelPresenter::UpdateClientBounds(const Tizen::Graphics::FloatDimension& size, Tizen::Graphics::FloatRectangle& clientBounds)
1915 if (__pScrollPanel->IsFixingClientBoundsEnabled())
1917 clientBounds = GetScrollAreaBounds();
1920 if (size.height > clientBounds.height)
1922 clientBounds.height = size.height;
1924 if (size.width > clientBounds.width)
1926 clientBounds.width = size.width;
1931 clientBounds.width = size.width;
1932 clientBounds.height = size.height;
1937 clientBounds.width = size.width;
1938 clientBounds.height = size.height;
1943 _ScrollPanelPresenter::SetScrollAreaBounds(FloatRectangle& bounds)
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));
1950 if (__pScrollPanel->GetScrollDirection() == SCROLL_PANEL_SCROLL_DIRECTION_HORIZONTAL)
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;
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;
1961 if (__scrollAnimationRunning)
1965 float scrollPosition = GetScrollPositionInternal();
1966 float fixedScrollPosition = FixScrollPositionIntoScrollAreaBounds(scrollPosition);
1968 if (!_FloatCompare(scrollPosition, fixedScrollPosition))
1970 StopScrollingAnimation();
1975 if (!__modelUpdating)
1977 __modelUpdating = true;
1978 __previousBounds = __pScrollPanel->GetBoundsF();
1979 __previousScrollAreaBounds = GetScrollAreaBounds();
1982 SetScrollAreaBoundsInternal(bounds);
1985 result r = GetLastResult();
1986 SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
1992 _ScrollPanelPresenter::GetPressedControl(void) const
1994 return __pPressedControl;
1998 _ScrollPanelPresenter::GetPreviousTouchPosition(void) const
2000 return __previousTouchedPosition;
2004 _ScrollPanelPresenter::GetCurrentTouchPosition(void) const
2006 return __currentMovedPosition;
2010 _ScrollPanelPresenter::IsScrollAnimationRunning(void) const
2012 return __scrollAnimationRunning;
2016 _ScrollPanelPresenter::IsModelUpdating(void) const
2018 return __modelUpdating;
2022 _ScrollPanelPresenter::CalculateFlickAmount(float flickDistance, float flickDuration)
2024 if (_FloatCompare(flickDistance, 0.0f))
2028 else if (flickDistance < 0.0)
2030 return -SCROLL_PANEL_FIXED_FLICK_AMOUNT;
2034 return SCROLL_PANEL_FIXED_FLICK_AMOUNT;
2039 _ScrollPanelPresenter::AccumulateFlickGesture(_FlickDirection direction)
2046 _ScrollPanelPresenter::FlickTo(float targetPosition, float duration)
2048 return ScrollTo(targetPosition, true);
2051 }}} // Tizen::Ui::Controls