/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#include <cstring> // for strcmp
#include <dali/public-api/animation/constraints.h>
#include <dali/public-api/common/stage.h>
-#include <dali/public-api/events/mouse-wheel-event.h>
-#include <dali/public-api/events/touch-event.h>
+#include <dali/public-api/events/wheel-event.h>
+#include <dali/public-api/events/touch-data.h>
#include <dali/public-api/object/type-registry.h>
#include <dali/public-api/object/type-registry-helper.h>
+#include <dali/public-api/object/property-map.h>
+#include <dali/devel-api/object/property-helper-devel.h>
#include <dali/integration-api/debug.h>
// INTERNAL INCLUDES
-#include <dali-toolkit/public-api/controls/scrollable/scroll-component-impl.h>
+#include <dali-toolkit/public-api/controls/scroll-bar/scroll-bar.h>
#include <dali-toolkit/public-api/controls/scrollable/scroll-view/scroll-view.h>
#include <dali-toolkit/public-api/controls/scrollable/scroll-view/scroll-view-constraints.h>
+#include <dali-toolkit/public-api/controls/scrollable/scroll-view/scroll-mode.h>
#include <dali-toolkit/internal/controls/scrollable/scroll-view/scroll-overshoot-indicator-impl.h>
#include <dali-toolkit/internal/controls/scrollable/scroll-view/scroll-view-effect-impl.h>
namespace
{
-
-const Vector2 DEFAULT_MIN_FLICK_DISTANCE(30.0f, 30.0f); ///< minimum distance for pan before flick allowed
-const float DEFAULT_MIN_FLICK_SPEED_THRESHOLD(500.0f); ///< Minimum pan speed required for flick in pixels/s
-const float FREE_FLICK_SPEED_THRESHOLD = 200.0f; ///< Free-Flick threshold in pixels/ms
-const float AUTOLOCK_AXIS_MINIMUM_DISTANCE2 = 100.0f; ///< Auto-lock axis after minimum distance squared.
-const float FLICK_ORTHO_ANGLE_RANGE = 75.0f; ///< degrees. (if >45, then supports diagonal flicking)
-const Vector2 DEFAULT_MOUSE_WHEEL_SCROLL_DISTANCE_STEP_PROPORTION = Vector2(0.17f, 0.1f); ///< The step of horizontal scroll distance in the proportion of stage size for each mouse wheel event received.
+const float DEFAULT_SLOW_SNAP_ANIMATION_DURATION(0.5f); ///< Default Drag-Release animation time.
+const float DEFAULT_FAST_SNAP_ANIMATION_DURATION(0.25f); ///< Default Drag-Flick animation time.
+const float DEFAULT_SNAP_OVERSHOOT_DURATION(0.5f); ///< Default Overshoot snapping animation time.
+const float DEFAULT_MAX_OVERSHOOT(100.0f); ///< Default maximum allowed overshoot in pixels
+
+const float DEFAULT_AXIS_AUTO_LOCK_GRADIENT(0.36f); ///< Default Axis-AutoLock gradient threshold. default is 0.36:1 (20 degrees)
+const float DEFAULT_FRICTION_COEFFICIENT(1.0f); ///< Default Friction Co-efficient. (in stage diagonals per second)
+const float DEFAULT_FLICK_SPEED_COEFFICIENT(1.0f); ///< Default Flick speed coefficient (multiples input touch velocity)
+const float DEFAULT_MAX_FLICK_SPEED(3.0f); ///< Default Maximum flick speed. (in stage diagonals per second)
+
+const Vector2 DEFAULT_MIN_FLICK_DISTANCE(30.0f, 30.0f); ///< minimum distance for pan before flick allowed
+const float DEFAULT_MIN_FLICK_SPEED_THRESHOLD(500.0f); ///< Minimum pan speed required for flick in pixels/s
+const float FREE_FLICK_SPEED_THRESHOLD = 200.0f; ///< Free-Flick threshold in pixels/ms
+const float AUTOLOCK_AXIS_MINIMUM_DISTANCE2 = 100.0f; ///< Auto-lock axis after minimum distance squared.
+const float FLICK_ORTHO_ANGLE_RANGE = 75.0f; ///< degrees. (if >45, then supports diagonal flicking)
+const Vector2 DEFAULT_WHEEL_SCROLL_DISTANCE_STEP_PROPORTION = Vector2(0.17f, 0.1f); ///< The step of horizontal scroll distance in the proportion of stage size for each wheel event received.
const unsigned long MINIMUM_TIME_BETWEEN_DOWN_AND_UP_FOR_RESET( 150u );
const float TOUCH_DOWN_TIMER_INTERVAL = 100.0f;
-const float DEFAULT_SCROLL_UPDATE_DISTANCE( 30.0f ); ///< Default distance to travel in pixels for scroll update signal
+const float DEFAULT_SCROLL_UPDATE_DISTANCE( 30.0f ); ///< Default distance to travel in pixels for scroll update signal
+
+const std::string INTERNAL_MAX_POSITION_PROPERTY_NAME( "internalMaxPosition" );
// Helpers ////////////////////////////////////////////////////////////////////////////////////////
* scroll domain. This is a value from 0.0f to 1.0f in each
* scroll position axis.
*/
-void InternalRelativePositionConstraint( Vector3& relativePosition, const PropertyInputContainer& inputs)
+void InternalRelativePositionConstraint( Vector2& relativePosition, const PropertyInputContainer& inputs)
{
- Vector3 position = -inputs[0]->GetVector3();
- const Vector3& min = inputs[1]->GetVector3();
- const Vector3& max = inputs[2]->GetVector3();
+ Vector2 position = -inputs[0]->GetVector2();
+ const Vector2& min = inputs[1]->GetVector2();
+ const Vector2& max = inputs[2]->GetVector2();
const Vector3& size = inputs[3]->GetVector3();
position.x = WrapInDomain(position.x, min.x, max.x);
position.y = WrapInDomain(position.y, min.y, max.y);
- Vector3 domainSize = (max - min) - size;
+ Vector2 domainSize = (max - min) - size.GetVectorXY();
relativePosition.x = domainSize.x > Math::MACHINE_EPSILON_1 ? fabsf((position.x - min.x) / domainSize.x) : 0.0f;
relativePosition.y = domainSize.y > Math::MACHINE_EPSILON_1 ? fabsf((position.y - min.y) / domainSize.y) : 0.0f;
- relativePosition.z = 0.0f;
+}
+
+/**
+ * Internal scroll domain Constraint
+ * Generates the scroll domain of the scroll view.
+ */
+void InternalScrollDomainConstraint( Vector2& scrollDomain, const PropertyInputContainer& inputs)
+{
+ const Vector2& min = inputs[0]->GetVector2();
+ const Vector2& max = inputs[1]->GetVector2();
+ const Vector3& size = inputs[2]->GetVector3();
+
+ scrollDomain = (max - min) - size.GetVectorXY();
+}
+
+/**
+ * Internal maximum scroll position Constraint
+ * Generates the maximum scroll position of the scroll view.
+ */
+void InternalPrePositionMaxConstraint( Vector2& scrollMax, const PropertyInputContainer& inputs)
+{
+ const Vector2& max = inputs[0]->GetVector2();
+ const Vector3& size = inputs[1]->GetVector3();
+
+ scrollMax = max - size.GetVectorXY();
}
} // unnamed namespace
// Setup properties, signals and actions using the type-registry.
DALI_TYPE_REGISTRATION_BEGIN( Toolkit::ScrollView, Toolkit::Scrollable, Create )
-DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, ScrollView, "scroll-position", VECTOR3, SCROLL_POSITION )
-DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, ScrollView, "scroll-pre-position", VECTOR3, SCROLL_PRE_POSITION )
-DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, ScrollView, "overshoot-x", FLOAT, OVERSHOOT_X )
-DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, ScrollView, "overshoot-y", FLOAT, OVERSHOOT_Y )
-DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, ScrollView, "scroll-final", VECTOR3, SCROLL_FINAL )
-DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, ScrollView, "wrap", BOOLEAN, WRAP )
-DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, ScrollView, "panning", BOOLEAN, PANNING )
-DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, ScrollView, "scrolling", BOOLEAN, SCROLLING )
-DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, ScrollView, "scroll-domain-offset", VECTOR3, SCROLL_DOMAIN_OFFSET )
-DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, ScrollView, "scroll-position-delta", VECTOR3, SCROLL_POSITION_DELTA )
-DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, ScrollView, "start-page-position", VECTOR3, START_PAGE_POSITION )
-
-DALI_SIGNAL_REGISTRATION( Toolkit, ScrollView, "value-changed", SIGNAL_SNAP_STARTED )
+DALI_PROPERTY_REGISTRATION( Toolkit, ScrollView, "wrapEnabled", BOOLEAN, WRAP_ENABLED )
+DALI_PROPERTY_REGISTRATION( Toolkit, ScrollView, "panningEnabled", BOOLEAN, PANNING_ENABLED )
+DALI_PROPERTY_REGISTRATION( Toolkit, ScrollView, "axisAutoLockEnabled", BOOLEAN, AXIS_AUTO_LOCK_ENABLED )
+DALI_PROPERTY_REGISTRATION( Toolkit, ScrollView, "wheelScrollDistanceStep", VECTOR2, WHEEL_SCROLL_DISTANCE_STEP )
+DALI_PROPERTY_REGISTRATION( Toolkit, ScrollView, "scrollMode", MAP, SCROLL_MODE )
+
+DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, ScrollView, "scrollPosition", VECTOR2, SCROLL_POSITION)
+DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, ScrollView, "scrollPrePosition", VECTOR2, SCROLL_PRE_POSITION)
+DALI_ANIMATABLE_PROPERTY_COMPONENT_REGISTRATION( Toolkit, ScrollView, "scrollPrePositionX", SCROLL_PRE_POSITION_X, SCROLL_PRE_POSITION, 0)
+DALI_ANIMATABLE_PROPERTY_COMPONENT_REGISTRATION( Toolkit, ScrollView, "scrollPrePositionY", SCROLL_PRE_POSITION_Y, SCROLL_PRE_POSITION, 1)
+DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, ScrollView, "scrollPrePositionMax", VECTOR2, SCROLL_PRE_POSITION_MAX)
+DALI_ANIMATABLE_PROPERTY_COMPONENT_REGISTRATION( Toolkit, ScrollView, "scrollPrePositionMaxX", SCROLL_PRE_POSITION_MAX_X, SCROLL_PRE_POSITION_MAX, 0)
+DALI_ANIMATABLE_PROPERTY_COMPONENT_REGISTRATION( Toolkit, ScrollView, "scrollPrePositionMaxY", SCROLL_PRE_POSITION_MAX_Y, SCROLL_PRE_POSITION_MAX, 1)
+DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, ScrollView, "overshootX", FLOAT, OVERSHOOT_X)
+DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, ScrollView, "overshootY", FLOAT, OVERSHOOT_Y)
+DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, ScrollView, "scrollFinal", VECTOR2, SCROLL_FINAL)
+DALI_ANIMATABLE_PROPERTY_COMPONENT_REGISTRATION( Toolkit, ScrollView, "scrollFinalX", SCROLL_FINAL_X, SCROLL_FINAL,0)
+DALI_ANIMATABLE_PROPERTY_COMPONENT_REGISTRATION( Toolkit, ScrollView, "scrollFinalY", SCROLL_FINAL_Y, SCROLL_FINAL,1)
+DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, ScrollView, "wrap", BOOLEAN, WRAP)
+DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, ScrollView, "panning", BOOLEAN, PANNING)
+DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, ScrollView, "scrolling", BOOLEAN, SCROLLING)
+DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, ScrollView, "scrollDomainSize", VECTOR2, SCROLL_DOMAIN_SIZE)
+DALI_ANIMATABLE_PROPERTY_COMPONENT_REGISTRATION( Toolkit, ScrollView, "scrollDomainSizeX", SCROLL_DOMAIN_SIZE_X, SCROLL_DOMAIN_SIZE, 0)
+DALI_ANIMATABLE_PROPERTY_COMPONENT_REGISTRATION( Toolkit, ScrollView, "scrollDomainSizeY", SCROLL_DOMAIN_SIZE_Y, SCROLL_DOMAIN_SIZE, 1)
+DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, ScrollView, "scrollDomainOffset", VECTOR2, SCROLL_DOMAIN_OFFSET)
+DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, ScrollView, "scrollPositionDelta", VECTOR2, SCROLL_POSITION_DELTA)
+DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, ScrollView, "startPagePosition", VECTOR3, START_PAGE_POSITION)
+
+DALI_SIGNAL_REGISTRATION( Toolkit, ScrollView, "valueChanged", SIGNAL_SNAP_STARTED )
DALI_TYPE_REGISTRATION_END()
*/
struct InternalPrePositionConstraint
{
- InternalPrePositionConstraint(const Vector2& initialPanPosition,
- const Vector2& initialPanMask,
- bool axisAutoLock,
- float axisAutoLockGradient,
- ScrollView::LockAxis initialLockAxis,
- const Vector2& maxOvershoot,
- const RulerDomain& domainX, const RulerDomain& domainY)
- : mLocalStart(initialPanPosition),
- mInitialPanMask(initialPanMask),
- mDomainMin( -domainX.min, -domainY.min ),
- mDomainMax( -domainX.max, -domainY.max ),
- mMaxOvershoot(maxOvershoot),
- mAxisAutoLockGradient(axisAutoLockGradient),
- mLockAxis(initialLockAxis),
- mAxisAutoLock(axisAutoLock),
- mWasPanning(false),
- mClampX( domainX.enabled ),
- mClampY( domainY.enabled )
- {
- }
-
- void operator()( Vector3& scrollPostPosition, const PropertyInputContainer& inputs )
+ InternalPrePositionConstraint( const Vector2& initialPanPosition,
+ const Vector2& initialPanMask,
+ bool axisAutoLock,
+ float axisAutoLockGradient,
+ ScrollView::LockAxis initialLockAxis,
+ const Vector2& maxOvershoot,
+ const RulerPtr& rulerX, const RulerPtr& rulerY )
+ : mLocalStart( initialPanPosition ),
+ mInitialPanMask( initialPanMask ),
+ mMaxOvershoot( maxOvershoot ),
+ mAxisAutoLockGradient( axisAutoLockGradient ),
+ mLockAxis( initialLockAxis ),
+ mAxisAutoLock( axisAutoLock ),
+ mWasPanning( false )
+ {
+ const RulerDomain& rulerDomainX = rulerX->GetDomain();
+ const RulerDomain& rulerDomainY = rulerY->GetDomain();
+ mDomainMin = Vector2( rulerDomainX.min, -rulerDomainY.min );
+ mDomainMax = Vector2( -rulerDomainX.max, -rulerDomainY.max );
+ mClampX = rulerDomainX.enabled;
+ mClampY = rulerDomainY.enabled;
+ mFixedRulerX = rulerX->GetType() == Ruler::Fixed;
+ mFixedRulerY = rulerY->GetType() == Ruler::Fixed;
+ }
+
+ void operator()( Vector2& scrollPostPosition, const PropertyInputContainer& inputs )
{
const Vector2& panPosition = inputs[0]->GetVector2();
+ const bool& inGesture = inputs[1]->GetBoolean();
- if(!mWasPanning)
- {
- mPrePosition = scrollPostPosition;
- mCurrentPanMask = mInitialPanMask;
- mWasPanning = true;
- }
-
- // Calculate Deltas...
- const Vector2& currentPosition = panPosition;
- Vector2 panDelta( currentPosition - mLocalStart );
-
- // Axis Auto Lock - locks the panning to the horizontal or vertical axis if the pan
- // appears mostly horizontal or mostly vertical respectively...
- if( mAxisAutoLock )
+ // First check if we are within a gesture.
+ // The ScrollView may have received a start gesture from ::OnPan()
+ // while the finish gesture is received now in this constraint.
+ // This gesture must then be rejected as the value will be "old".
+ // Typically the last value from the end of the last gesture.
+ // If we are rejecting the gesture, we simply don't modify the constraint target.
+ if( inGesture )
{
- mLockAxis = GetLockAxis(panDelta, mLockAxis, mAxisAutoLockGradient);
- if( mLockAxis == ScrollView::LockVertical )
+ if( !mWasPanning )
{
- mCurrentPanMask.y = 0.0f;
+ mPrePosition = scrollPostPosition;
+ mStartPosition = mPrePosition;
+ mCurrentPanMask = mInitialPanMask;
+ mWasPanning = true;
}
- else if( mLockAxis == ScrollView::LockHorizontal )
+
+ // Calculate Deltas...
+ const Vector2& currentPosition = panPosition;
+ Vector2 panDelta( currentPosition - mLocalStart );
+
+ // Axis Auto Lock - locks the panning to the horizontal or vertical axis if the pan
+ // appears mostly horizontal or mostly vertical respectively...
+ if( mAxisAutoLock )
{
- mCurrentPanMask.x = 0.0f;
+ mLockAxis = GetLockAxis( panDelta, mLockAxis, mAxisAutoLockGradient );
+ if( mLockAxis == ScrollView::LockVertical )
+ {
+ mCurrentPanMask.y = 0.0f;
+ }
+ else if( mLockAxis == ScrollView::LockHorizontal )
+ {
+ mCurrentPanMask.x = 0.0f;
+ }
}
- }
- // Restrict deltas based on ruler enable/disable and axis-lock state...
- panDelta *= mCurrentPanMask;
+ // Restrict deltas based on ruler enable/disable and axis-lock state...
+ panDelta *= mCurrentPanMask;
- // Perform Position transform based on input deltas...
- scrollPostPosition = mPrePosition;
- scrollPostPosition.GetVectorXY() += panDelta;
+ // Perform Position transform based on input deltas...
+ scrollPostPosition = mPrePosition;
+ scrollPostPosition += panDelta;
- // if no wrapping then clamp preposition to maximum overshoot amount
- const Vector3& size = inputs[1]->GetVector3();
- if( mClampX )
- {
- float newXPosition = Clamp(scrollPostPosition.x, (mDomainMax.x + size.x) - mMaxOvershoot.x, mDomainMin.x + mMaxOvershoot.x );
- if( (newXPosition < scrollPostPosition.x - Math::MACHINE_EPSILON_1)
- || (newXPosition > scrollPostPosition.x + Math::MACHINE_EPSILON_1) )
+ // if no wrapping then clamp preposition to maximum overshoot amount
+ const Vector3& size = inputs[2]->GetVector3();
+ if( mClampX )
{
- mPrePosition.x = newXPosition;
- mLocalStart.x = panPosition.x;
+ float newXPosition = Clamp( scrollPostPosition.x, ( mDomainMax.x + size.x ) - mMaxOvershoot.x, mDomainMin.x + mMaxOvershoot.x );
+ if( (newXPosition < scrollPostPosition.x - Math::MACHINE_EPSILON_1)
+ || (newXPosition > scrollPostPosition.x + Math::MACHINE_EPSILON_1) )
+ {
+ mPrePosition.x = newXPosition;
+ mLocalStart.x = panPosition.x;
+ }
+ scrollPostPosition.x = newXPosition;
}
- scrollPostPosition.x = newXPosition;
- }
- if( mClampY )
- {
- float newYPosition = Clamp(scrollPostPosition.y, (mDomainMax.y + size.y) - mMaxOvershoot.y, mDomainMin.y + mMaxOvershoot.y );
- if( (newYPosition < scrollPostPosition.y - Math::MACHINE_EPSILON_1)
- || (newYPosition > scrollPostPosition.y + Math::MACHINE_EPSILON_1) )
+ if( mClampY )
{
- mPrePosition.y = newYPosition;
- mLocalStart.y = panPosition.y;
+ float newYPosition = Clamp( scrollPostPosition.y, ( mDomainMax.y + size.y ) - mMaxOvershoot.y, mDomainMin.y + mMaxOvershoot.y );
+ if( ( newYPosition < scrollPostPosition.y - Math::MACHINE_EPSILON_1 )
+ || ( newYPosition > scrollPostPosition.y + Math::MACHINE_EPSILON_1 ) )
+ {
+ mPrePosition.y = newYPosition;
+ mLocalStart.y = panPosition.y;
+ }
+ scrollPostPosition.y = newYPosition;
+ }
+
+ // If we are using a fixed ruler in a particular axis, limit the maximum pages scrolled on that axis.
+ if( mFixedRulerX || mFixedRulerY )
+ {
+ // Here we limit the maximum amount that can be moved from the starting position of the gesture to one page.
+ // We do this only if we have a fixed ruler (on that axis) and the mode is enabled.
+ // Note: 1.0f is subtracted to keep the value within one page size (otherwise we stray on to the page after).
+ // Note: A further 1.0f is subtracted to handle a compensation that happens later within the flick handling code in SnapWithVelocity().
+ // When a flick is completed, an adjustment of 1.0f is sometimes made to allow for the scenario where:
+ // A flick finishes before the update thread has advanced the scroll position past the previous snap point.
+ Vector2 pageSizeLimit( size.x - ( 1.0f + 1.0f ), size.y - ( 1.0f - 1.0f ) );
+ Vector2 minPosition( mStartPosition.x - pageSizeLimit.x, mStartPosition.y - pageSizeLimit.y );
+ Vector2 maxPosition( mStartPosition.x + pageSizeLimit.x, mStartPosition.y + pageSizeLimit.y );
+
+ if( mFixedRulerX )
+ {
+ scrollPostPosition.x = Clamp( scrollPostPosition.x, minPosition.x, maxPosition.x );
+ }
+ if( mFixedRulerY )
+ {
+ scrollPostPosition.y = Clamp( scrollPostPosition.y, minPosition.y, maxPosition.y );
+ }
}
- scrollPostPosition.y = newYPosition;
}
}
- Vector3 mPrePosition;
+ Vector2 mPrePosition;
Vector2 mLocalStart;
- Vector2 mInitialPanMask; ///< Initial pan mask (based on ruler settings)
+ Vector2 mStartPosition; ///< The start position of the gesture - used to limit scroll amount (not modified by clamping).
+ Vector2 mInitialPanMask; ///< Initial pan mask (based on ruler settings).
Vector2 mCurrentPanMask; ///< Current pan mask that can be altered by axis lock mode.
Vector2 mDomainMin;
Vector2 mDomainMax;
float mAxisAutoLockGradient; ///< Set by ScrollView
ScrollView::LockAxis mLockAxis;
- bool mAxisAutoLock:1; ///< Set by ScrollView
+ bool mAxisAutoLock:1; ///< Set by ScrollView
bool mWasPanning:1;
bool mClampX:1;
bool mClampY:1;
+ bool mFixedRulerX:1;
+ bool mFixedRulerY:1;
};
/**
{
}
- void operator()( Vector3& position, const PropertyInputContainer& inputs )
+ void operator()( Vector2& position, const PropertyInputContainer& inputs )
{
- position = inputs[0]->GetVector3();
+ position = inputs[0]->GetVector2();
const Vector2& size = inputs[3]->GetVector3().GetVectorXY();
- const Vector3& min = inputs[1]->GetVector3();
- const Vector3& max = inputs[2]->GetVector3();
+ const Vector2& min = inputs[1]->GetVector2();
+ const Vector2& max = inputs[2]->GetVector2();
if( mWrap )
{
{
if( inputs[2]->GetBoolean() )
{
- const Vector3& scrollPrePosition = inputs[0]->GetVector3();
- const Vector3& scrollPostPosition = inputs[1]->GetVector3();
+ const Vector2& scrollPrePosition = inputs[0]->GetVector2();
+ const Vector2& scrollPostPosition = inputs[1]->GetVector2();
float newOvershoot = scrollPrePosition.x - scrollPostPosition.x;
current = (newOvershoot > 0.0f ? std::min(newOvershoot, mMaxOvershoot) : std::max(newOvershoot, -mMaxOvershoot)) / mMaxOvershoot;
}
{
if( inputs[2]->GetBoolean() )
{
- const Vector3& scrollPrePosition = inputs[0]->GetVector3();
- const Vector3& scrollPostPosition = inputs[1]->GetVector3();
+ const Vector2& scrollPrePosition = inputs[0]->GetVector2();
+ const Vector2& scrollPostPosition = inputs[1]->GetVector2();
float newOvershoot = scrollPrePosition.y - scrollPostPosition.y;
current = (newOvershoot > 0.0f ? std::min(newOvershoot, mMaxOvershoot) : std::max(newOvershoot, -mMaxOvershoot)) / mMaxOvershoot;
}
*
* Generates position-delta property based on scroll-position + scroll-offset properties.
*/
-void InternalPositionDeltaConstraint( Vector3& current, const PropertyInputContainer& inputs )
+void InternalPositionDeltaConstraint( Vector2& current, const PropertyInputContainer& inputs )
{
- const Vector3& scrollPosition = inputs[0]->GetVector3();
- const Vector3& scrollOffset = inputs[1]->GetVector3();
+ const Vector2& scrollPosition = inputs[0]->GetVector2();
+ const Vector2& scrollOffset = inputs[1]->GetVector2();
current = scrollPosition + scrollOffset;
}
{
}
- void operator()( Vector3& current, const PropertyInputContainer& inputs )
+ void operator()( Vector2& current, const PropertyInputContainer& inputs )
{
const float& overshootx = inputs[1]->GetFloat();
const float& overshooty = inputs[2]->GetFloat();
- Vector3 offset( mFunctionX(overshootx),
- mFunctionY(overshooty),
- 0.0f);
+ Vector2 offset( mFunctionX(overshootx),
+ mFunctionY(overshooty) );
- current = inputs[0]->GetVector3() - offset;
+ current = inputs[0]->GetVector2() - offset;
}
AlphaFunctionPrototype mFunctionX;
}
ScrollView::ScrollView()
-: ScrollBase( ControlBehaviour( REQUIRES_MOUSE_WHEEL_EVENTS ) ), // Enable size negotiation
+: ScrollBase( ControlBehaviour( REQUIRES_WHEEL_EVENTS | DISABLE_STYLE_CHANGE_SIGNALS ) ), // Enable size negotiation
mTouchDownTime(0u),
mGestureStackDepth(0),
mScrollStateFlags(0),
mLockAxis(LockPossible),
mScrollUpdateDistance(DEFAULT_SCROLL_UPDATE_DISTANCE),
- mMaxOvershoot(Toolkit::ScrollView::DEFAULT_MAX_OVERSHOOT, Toolkit::ScrollView::DEFAULT_MAX_OVERSHOOT),
- mUserMaxOvershoot(Toolkit::ScrollView::DEFAULT_MAX_OVERSHOOT, Toolkit::ScrollView::DEFAULT_MAX_OVERSHOOT),
- mSnapOvershootDuration(Toolkit::ScrollView::DEFAULT_SNAP_OVERSHOOT_DURATION),
+ mMaxOvershoot(DEFAULT_MAX_OVERSHOOT, DEFAULT_MAX_OVERSHOOT),
+ mUserMaxOvershoot(DEFAULT_MAX_OVERSHOOT, DEFAULT_MAX_OVERSHOOT),
+ mSnapOvershootDuration(DEFAULT_SNAP_OVERSHOOT_DURATION),
mSnapOvershootAlphaFunction(AlphaFunction::EASE_OUT),
- mSnapDuration(Toolkit::ScrollView::DEFAULT_SLOW_SNAP_ANIMATION_DURATION),
+ mSnapDuration(DEFAULT_SLOW_SNAP_ANIMATION_DURATION),
mSnapAlphaFunction(AlphaFunction::EASE_OUT),
mMinFlickDistance(DEFAULT_MIN_FLICK_DISTANCE),
mFlickSpeedThreshold(DEFAULT_MIN_FLICK_SPEED_THRESHOLD),
- mFlickDuration(Toolkit::ScrollView::DEFAULT_FAST_SNAP_ANIMATION_DURATION),
+ mFlickDuration(DEFAULT_FAST_SNAP_ANIMATION_DURATION),
mFlickAlphaFunction(AlphaFunction::EASE_OUT),
- mAxisAutoLockGradient(Toolkit::ScrollView::DEFAULT_AXIS_AUTO_LOCK_GRADIENT),
- mFrictionCoefficient(Toolkit::ScrollView::DEFAULT_FRICTION_COEFFICIENT),
- mFlickSpeedCoefficient(Toolkit::ScrollView::DEFAULT_FLICK_SPEED_COEFFICIENT),
- mMaxFlickSpeed(Toolkit::ScrollView::DEFAULT_MAX_FLICK_SPEED),
+ mAxisAutoLockGradient(DEFAULT_AXIS_AUTO_LOCK_GRADIENT),
+ mFrictionCoefficient(DEFAULT_FRICTION_COEFFICIENT),
+ mFlickSpeedCoefficient(DEFAULT_FLICK_SPEED_COEFFICIENT),
+ mMaxFlickSpeed(DEFAULT_MAX_FLICK_SPEED),
+ mWheelScrollDistanceStep(Vector2::ZERO),
mInAccessibilityPan(false),
- mInitialized(false),
mScrolling(false),
mScrollInterrupted(false),
mPanning(false),
mAlterChild(false),
mDefaultMaxOvershoot(true),
mCanScrollHorizontal(true),
- mCanScrollVertical(true)
+ mCanScrollVertical(true),
+ mTransientScrollBar(true)
{
}
// Internal Actor, used to hide actors from enumerations.
// Also actors added to Internal actor appear as overlays e.g. ScrollBar components.
mInternalActor = Actor::New();
- mInternalActor.SetDrawMode(DrawMode::OVERLAY);
self.Add(mInternalActor);
- Constraint constraint = Constraint::New<Vector3>( mInternalActor, Actor::Property::SIZE, EqualToConstraint() );
- constraint.AddSource( ParentSource( Actor::Property::SIZE ) );
- constraint.Apply();
+
mInternalActor.SetParentOrigin(ParentOrigin::CENTER);
mInternalActor.SetAnchorPoint(AnchorPoint::CENTER);
+ mInternalActor.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
mAlterChild = true;
- mScrollPostPosition = mScrollPrePosition = Vector3::ZERO;
+ mScrollPostPosition = mScrollPrePosition = Vector2::ZERO;
- mMouseWheelScrollDistanceStep = Stage::GetCurrent().GetSize() * DEFAULT_MOUSE_WHEEL_SCROLL_DISTANCE_STEP_PROPORTION;
-
- mInitialized = true;
+ mWheelScrollDistanceStep = Stage::GetCurrent().GetSize() * DEFAULT_WHEEL_SCROLL_DISTANCE_STEP_PROPORTION;
mGestureStackDepth = 0;
+ self.TouchSignal().Connect( this, &ScrollView::OnTouch );
EnableGestureDetection( Gesture::Type( Gesture::Pan ) );
// By default we'll allow the user to freely drag the scroll view,
mRulerX = ruler;
mRulerY = ruler;
- EnableScrollComponent(Toolkit::Scrollable::OvershootIndicator);
-
self.SetProperty(Toolkit::Scrollable::Property::CAN_SCROLL_VERTICAL, mCanScrollVertical);
self.SetProperty(Toolkit::Scrollable::Property::CAN_SCROLL_HORIZONTAL, mCanScrollHorizontal);
- Vector3 size = GetControlSize();
- UpdatePropertyDomain(size);
+ UpdatePropertyDomain();
SetInternalConstraints();
}
-void ScrollView::OnControlStageConnection()
+void ScrollView::OnStageConnection( int depth )
{
DALI_LOG_SCROLL_STATE("[0x%X]", this);
SetScrollSensitive( false );
SetScrollSensitive( true );
}
- if(IsScrollComponentEnabled(Toolkit::Scrollable::OvershootIndicator))
+
+ if(IsOvershootEnabled())
{
// try and make sure property notifications are set
- EnableScrollComponent(Toolkit::Scrollable::OvershootIndicator);
+ EnableScrollOvershoot(true);
}
+
+ ScrollBase::OnStageConnection( depth );
}
-void ScrollView::OnControlStageDisconnection()
+void ScrollView::OnStageDisconnection()
{
DALI_LOG_SCROLL_STATE("[0x%X]", this);
StopAnimation();
+
+ ScrollBase::OnStageDisconnection();
}
ScrollView::~ScrollView()
{
mRulerX = ruler;
- Vector3 size = GetControlSize();
- UpdatePropertyDomain(size);
+ UpdatePropertyDomain();
UpdateMainInternalConstraint();
}
{
mRulerY = ruler;
- Vector3 size = GetControlSize();
- UpdatePropertyDomain(size);
+ UpdatePropertyDomain();
UpdateMainInternalConstraint();
}
-void ScrollView::UpdatePropertyDomain(const Vector3& size)
+void ScrollView::UpdatePropertyDomain()
{
Actor self = Self();
- Vector3 min = mMinScroll;
- Vector3 max = mMaxScroll;
+ Vector3 size = self.GetTargetSize();
+ Vector2 min = mMinScroll;
+ Vector2 max = mMaxScroll;
bool scrollPositionChanged = false;
bool domainChanged = false;
}
}
+bool ScrollView::GetScrollSensitive()
+{
+ return mSensitive;
+}
+
void ScrollView::SetScrollSensitive(bool sensitive)
{
Actor self = Self();
mSnapOvershootAlphaFunction = alpha;
}
+float ScrollView::GetSnapOvershootDuration()
+{
+ return mSnapOvershootDuration;
+}
+
void ScrollView::SetSnapOvershootDuration(float duration)
{
mSnapOvershootDuration = duration;
}
+bool ScrollView::GetActorAutoSnap()
+{
+ return mActorAutoSnapEnabled;
+}
+
void ScrollView::SetActorAutoSnap(bool enable)
{
mActorAutoSnapEnabled = enable;
mMaxFlickSpeed = speed;
}
-void ScrollView::SetMouseWheelScrollDistanceStep(Vector2 step)
+void ScrollView::SetWheelScrollDistanceStep(Vector2 step)
{
- mMouseWheelScrollDistanceStep = step;
+ mWheelScrollDistanceStep = step;
}
-Vector2 ScrollView::GetMouseWheelScrollDistanceStep() const
+Vector2 ScrollView::GetWheelScrollDistanceStep() const
{
- return mMouseWheelScrollDistanceStep;
+ return mWheelScrollDistanceStep;
}
unsigned int ScrollView::GetCurrentPage() const
{
// in case animation is currently taking place.
- Vector3 position = GetPropertyPosition();
+ Vector2 position = GetPropertyPosition();
Actor self = Self();
unsigned int page = 0;
return volume * pagesPerVolume + page;
}
-Vector3 ScrollView::GetCurrentScrollPosition() const
+Vector2 ScrollView::GetCurrentScrollPosition() const
{
return -GetPropertyPosition();
}
-void ScrollView::SetScrollPosition(const Vector3& position)
-{
- mScrollPrePosition = position;
-}
-
-Vector3 ScrollView::GetDomainSize() const
-{
- Vector3 size = Self().GetCurrentSize();
-
- const RulerDomain& xDomain = GetRulerX()->GetDomain();
- const RulerDomain& yDomain = GetRulerY()->GetDomain();
-
- Vector3 domainSize = Vector3( xDomain.max - xDomain.min, yDomain.max - yDomain.min, 0.0f ) - size;
- return domainSize;
-}
-
-void ScrollView::TransformTo(const Vector3& position,
+void ScrollView::TransformTo(const Vector2& position,
DirectionBias horizontalBias, DirectionBias verticalBias)
{
TransformTo(position, mSnapDuration, mSnapAlphaFunction, horizontalBias, verticalBias);
}
-void ScrollView::TransformTo(const Vector3& position, float duration, AlphaFunction alpha,
+void ScrollView::TransformTo(const Vector2& position, float duration, AlphaFunction alpha,
DirectionBias horizontalBias, DirectionBias verticalBias)
{
// If this is called while the timer is running, then cancel it
DALI_LOG_SCROLL_STATE("[0x%X] pos[%.2f,%.2f], duration[%.2f] bias[%d, %d]",
this, position.x, position.y, duration, int(horizontalBias), int(verticalBias));
- Vector3 currentScrollPosition = GetCurrentScrollPosition();
- self.SetProperty( Toolkit::ScrollView::Property::START_PAGE_POSITION, currentScrollPosition );
+ Vector2 currentScrollPosition = GetCurrentScrollPosition();
+ self.SetProperty( Toolkit::ScrollView::Property::START_PAGE_POSITION, Vector3(currentScrollPosition) );
if( mScrolling ) // are we interrupting a current scroll?
{
DALI_LOG_SCROLL_STATE("[0x%X] mScrollStartedSignal 1 [%.2f, %.2f]", this, currentScrollPosition.x, currentScrollPosition.y);
mScrollStartedSignal.Emit( currentScrollPosition );
bool animating = AnimateTo(-position,
- Vector3::ONE * duration,
+ Vector2::ONE * duration,
alpha,
true,
horizontalBias,
// If we have no duration, then in the next update frame, we will be at the position specified as we just set.
// In this scenario, we cannot return the currentScrollPosition as this is out-of-date and should instead return the requested final position
- Vector3 completedPosition( currentScrollPosition );
+ Vector2 completedPosition( currentScrollPosition );
if( duration <= Math::MACHINE_EPSILON_10 )
{
completedPosition = position;
}
}
-void ScrollView::ScrollTo(const Vector3& position)
+void ScrollView::ScrollTo(const Vector2& position)
{
ScrollTo(position, mSnapDuration );
}
-void ScrollView::ScrollTo(const Vector3& position, float duration)
+void ScrollView::ScrollTo(const Vector2& position, float duration)
{
ScrollTo(position, duration, DirectionBiasNone, DirectionBiasNone);
}
-void ScrollView::ScrollTo(const Vector3& position, float duration, AlphaFunction alpha)
+void ScrollView::ScrollTo(const Vector2& position, float duration, AlphaFunction alpha)
{
ScrollTo(position, duration, alpha, DirectionBiasNone, DirectionBiasNone);
}
-void ScrollView::ScrollTo(const Vector3& position, float duration,
+void ScrollView::ScrollTo(const Vector2& position, float duration,
DirectionBias horizontalBias, DirectionBias verticalBias)
{
ScrollTo(position, duration, mSnapAlphaFunction, horizontalBias, verticalBias);
}
-void ScrollView::ScrollTo(const Vector3& position, float duration, AlphaFunction alpha,
+void ScrollView::ScrollTo(const Vector2& position, float duration, AlphaFunction alpha,
DirectionBias horizontalBias, DirectionBias verticalBias)
{
DALI_LOG_SCROLL_STATE("[0x%X] position[%.2f, %.2f] duration[%.2f], bias[%d, %d]", this, position.x, position.y, duration, int(horizontalBias), int(verticalBias));
void ScrollView::ScrollTo(unsigned int page, float duration, DirectionBias bias)
{
- Vector3 position;
+ Vector2 position;
unsigned int volume;
unsigned int libraries;
Actor self = Self();
Vector3 size = self.GetCurrentSize();
Vector3 position = actor.GetCurrentPosition();
- position -= GetPropertyPrePosition();
+ Vector2 prePosition = GetPropertyPrePosition();
+ position.GetVectorXY() -= prePosition;
- ScrollTo(Vector3(position.x - size.width * 0.5f, position.y - size.height * 0.5f, 0.0f), duration);
+ ScrollTo(Vector2(position.x - size.width * 0.5f, position.y - size.height * 0.5f), duration);
}
Actor ScrollView::FindClosestActor()
float angle = atan2(velocity.y, velocity.x);
float speed2 = velocity.LengthSquared();
AlphaFunction alphaFunction = mSnapAlphaFunction;
- Vector3 positionDuration = Vector3::ONE * mSnapDuration;
+ Vector2 positionDuration = Vector2::ONE * mSnapDuration;
float biasX = 0.5f;
float biasY = 0.5f;
FindDirection horizontal = None;
const float orthoAngleRange = FLICK_ORTHO_ANGLE_RANGE * M_PI / 180.0f;
const float flickSpeedThreshold2 = mFlickSpeedThreshold * mFlickSpeedThreshold;
- Vector3 positionSnap = mScrollPrePosition;
+ Vector2 positionSnap = mScrollPrePosition;
// Flick logic X Axis
if(isFlick || isFreeFlick)
{
- positionDuration = Vector3::ONE * mFlickDuration;
+ positionDuration = Vector2::ONE * mFlickDuration;
alphaFunction = mFlickAlphaFunction;
}
if(child)
{
- Vector3 position = Self().GetProperty<Vector3>(Toolkit::ScrollView::Property::SCROLL_POSITION);
+ Vector2 position = Self().GetCurrentProperty<Vector2>( Toolkit::ScrollView::Property::SCROLL_POSITION );
// Get center-point of the Actor.
Vector3 childPosition = GetPositionOfAnchor(child, AnchorPoint::CENTER);
}
}
- Vector3 startPosition = positionSnap;
+ Vector2 startPosition = positionSnap;
positionSnap.x = -mRulerX->Snap(-positionSnap.x, biasX); // NOTE: X & Y rulers think in -ve coordinate system.
positionSnap.y = -mRulerY->Snap(-positionSnap.y, biasY); // That is scrolling RIGHT (e.g. 100.0, 0.0) means moving LEFT.
- Vector3 clampDelta(Vector3::ZERO);
+ Vector2 clampDelta(Vector2::ZERO);
ClampPosition(positionSnap);
if( (mRulerX->GetType() == Ruler::Free || mRulerY->GetType() == Ruler::Free)
}
else
{
- clampDelta = Vector3::ZERO;
+ clampDelta = Vector2::ZERO;
}
// If Axis is Free and has velocity, then calculate time taken
}
}
- if(IsScrollComponentEnabled(Toolkit::Scrollable::OvershootIndicator))
+ if(IsOvershootEnabled())
{
// Scroll to the end of the overshoot only when overshoot is enabled.
positionSnap += clampDelta;
}
}
-bool ScrollView::AnimateTo(const Vector3& position, const Vector3& positionDuration,
+bool ScrollView::AnimateTo(const Vector2& position, const Vector2& positionDuration,
AlphaFunction alpha, bool findShortcuts,
DirectionBias horizontalBias, DirectionBias verticalBias,
SnapType snapType)
// Position Delta ///////////////////////////////////////////////////////
if(positionChanged)
{
+ UpdateMainInternalConstraint();
if(mWrapMode && findShortcuts)
{
// In Wrap Mode, the shortest distance is a little less intuitive...
}
DALI_LOG_SCROLL_STATE("[0x%X] position-changed, mScrollTargetPosition[%.2f, %.2f], mScrollPrePosition[%.2f, %.2f], mScrollPostPosition[%.2f, %.2f]", this, mScrollTargetPosition.x, mScrollTargetPosition.y, mScrollPrePosition.x, mScrollPrePosition.y, mScrollPostPosition.x, mScrollPostPosition.y );
- DALI_LOG_SCROLL_STATE("[0x%X] SCROLL_PRE_POSITION[%.2f, %.2f], SCROLL_POSITION[%.2f, %.2f]", this, self.GetProperty( Toolkit::ScrollView::Property::SCROLL_PRE_POSITION ).Get<Vector3>().x, self.GetProperty( Toolkit::ScrollView::Property::SCROLL_PRE_POSITION ).Get<Vector3>().y, self.GetProperty( Toolkit::ScrollView::Property::SCROLL_POSITION ).Get<Vector3>().x, self.GetProperty( Toolkit::ScrollView::Property::SCROLL_POSITION ).Get<Vector3>().y );
+ DALI_LOG_SCROLL_STATE("[0x%X] SCROLL_PRE_POSITION[%.2f, %.2f], SCROLL_POSITION[%.2f, %.2f]", this, self.GetCurrentProperty( Toolkit::ScrollView::Property::SCROLL_PRE_POSITION ).Get<Vector2>().x, self.GetCurrentProperty( Toolkit::ScrollView::Property::SCROLL_PRE_POSITION ).Get<Vector2>().y, self.GetCurrentProperty( Toolkit::ScrollView::Property::SCROLL_POSITION ).Get<Vector2>().x, self.GetCurrentProperty( Toolkit::ScrollView::Property::SCROLL_POSITION ).Get<Vector2>().y );
}
SetScrollUpdateNotification(true);
return (mScrollStateFlags & SCROLL_ANIMATION_FLAGS) != 0;
}
-void ScrollView::SetOvershootEnabled(bool enabled)
+void ScrollView::EnableScrollOvershoot(bool enable)
{
- if(enabled && !mOvershootIndicator)
- {
- mOvershootIndicator = ScrollOvershootIndicator::New();
- }
- if( enabled )
+ if (enable)
{
+ if (!mOvershootIndicator)
+ {
+ mOvershootIndicator = ScrollOvershootIndicator::New();
+ }
+
mOvershootIndicator->AttachToScrollable(*this);
}
else
{
mMaxOvershoot = mUserMaxOvershoot;
- mOvershootIndicator->DetachFromScrollable(*this);
+
+ if (mOvershootIndicator)
+ {
+ mOvershootIndicator->DetachFromScrollable(*this);
+ }
}
+
UpdateMainInternalConstraint();
}
void ScrollView::AddOverlay(Actor actor)
{
+ actor.SetDrawMode( DrawMode::OVERLAY_2D );
mInternalActor.Add( actor );
}
mInternalActor.Remove( actor );
}
+void ScrollView::SetOvershootSize( const Vector2& size )
+{
+ mOvershootSize = size;
+ if( IsOvershootEnabled() && mOvershootIndicator )
+ {
+ mOvershootIndicator->AttachToScrollable(*this);
+ }
+}
+
void ScrollView::SetOvershootEffectColor( const Vector4& color )
{
mOvershootEffectColor = color;
UnbindActor(child);
}
-Vector3 ScrollView::GetPropertyPrePosition() const
+Vector2 ScrollView::GetPropertyPrePosition() const
{
- Vector3 position = Self().GetProperty<Vector3>(Toolkit::ScrollView::Property::SCROLL_PRE_POSITION);
+ Vector2 position = Self().GetCurrentProperty< Vector2 >( Toolkit::ScrollView::Property::SCROLL_PRE_POSITION );
WrapPosition(position);
return position;
}
-Vector3 ScrollView::GetPropertyPosition() const
+Vector2 ScrollView::GetPropertyPosition() const
{
- Vector3 position = Self().GetProperty<Vector3>(Toolkit::ScrollView::Property::SCROLL_POSITION);
+ Vector2 position = Self().GetCurrentProperty< Vector2 >( Toolkit::ScrollView::Property::SCROLL_POSITION );
WrapPosition(position);
return position;
Actor self = Self();
self.SetProperty(Toolkit::ScrollView::Property::SCROLLING, false);
- Vector3 deltaPosition(mScrollPrePosition);
+ Vector2 deltaPosition(mScrollPrePosition);
UpdateLocalScrollProperties();
WrapPosition(mScrollPrePosition);
DALI_LOG_SCROLL_STATE("[0x%X] Setting SCROLL_PRE_POSITION To[%.2f, %.2f]", this, mScrollPrePosition.x, mScrollPrePosition.y );
self.SetProperty(Toolkit::ScrollView::Property::SCROLL_PRE_POSITION, mScrollPrePosition);
- Vector3 currentScrollPosition = GetCurrentScrollPosition();
+ Vector2 currentScrollPosition = GetCurrentScrollPosition();
DALI_LOG_SCROLL_STATE("[0x%X] mScrollCompletedSignal 3 current[%.2f, %.2f], mScrollTargetPosition[%.2f, %.2f]", this, currentScrollPosition.x, currentScrollPosition.y, -mScrollTargetPosition.x, -mScrollTargetPosition.y );
mScrollCompletedSignal.Emit( currentScrollPosition );
// Guard against destruction during signal emission
Toolkit::ScrollView handle( GetOwner() );
- Vector3 currentScrollPosition = GetCurrentScrollPosition();
+ Vector2 currentScrollPosition = GetCurrentScrollPosition();
mScrollUpdatedSignal.Emit( currentScrollPosition );
}
void ScrollView::OnSizeAnimation(Animation& animation, const Vector3& targetSize)
{
// need to update domain properties for new size
- UpdatePropertyDomain(targetSize);
+ UpdatePropertyDomain();
}
-void ScrollView::OnControlSizeSet( const Vector3& size )
+void ScrollView::OnSizeSet( const Vector3& size )
{
// need to update domain properties for new size
if( mDefaultMaxOvershoot )
{
mUserMaxOvershoot.x = size.x * 0.5f;
mUserMaxOvershoot.y = size.y * 0.5f;
- if( !IsScrollComponentEnabled(Toolkit::Scrollable::OvershootIndicator) )
+ if( !IsOvershootEnabled() )
{
mMaxOvershoot = mUserMaxOvershoot;
}
}
- UpdatePropertyDomain(size);
+ UpdatePropertyDomain();
UpdateMainInternalConstraint();
- if( IsScrollComponentEnabled(Toolkit::Scrollable::OvershootIndicator) )
+ if( IsOvershootEnabled() )
{
mOvershootIndicator->Reset();
}
+
+ ScrollBase::OnSizeSet( size );
}
void ScrollView::OnChildAdd(Actor& child)
{
- if(mAlterChild)
+ ScrollBase::OnChildAdd( child );
+
+ Dali::Toolkit::ScrollBar scrollBar = Dali::Toolkit::ScrollBar::DownCast(child);
+ if( scrollBar )
+ {
+ mScrollBar = scrollBar;
+ scrollBar.SetName("ScrollBar");
+
+ mInternalActor.Add( scrollBar );
+ if( scrollBar.GetScrollDirection() == Toolkit::ScrollBar::Horizontal )
+ {
+ scrollBar.SetScrollPropertySource( Self(),
+ Toolkit::ScrollView::Property::SCROLL_PRE_POSITION_X,
+ Toolkit::Scrollable::Property::SCROLL_POSITION_MIN_X,
+ Toolkit::ScrollView::Property::SCROLL_PRE_POSITION_MAX_X,
+ Toolkit::ScrollView::Property::SCROLL_DOMAIN_SIZE_X );
+ }
+ else
+ {
+ scrollBar.SetScrollPropertySource( Self(),
+ Toolkit::ScrollView::Property::SCROLL_PRE_POSITION_Y,
+ Toolkit::Scrollable::Property::SCROLL_POSITION_MIN_Y,
+ Toolkit::ScrollView::Property::SCROLL_PRE_POSITION_MAX_Y,
+ Toolkit::ScrollView::Property::SCROLL_DOMAIN_SIZE_Y );
+ }
+
+ if( mTransientScrollBar )
+ {
+ // Show the scroll-indicator for a brief period
+ Property::Map emptyMap;
+ scrollBar.DoAction( "ShowTransientIndicator", emptyMap );
+ }
+ }
+ else if(mAlterChild)
{
BindActor(child);
}
{
// TODO: Actor needs a RemoveConstraint method to take out an individual constraint.
UnbindActor(child);
+
+ ScrollBase::OnChildRemove( child );
}
void ScrollView::StartTouchDownTimer()
mScrollInterrupted = true;
// reset domain offset as scrolling from original plane.
- mDomainOffset = Vector3::ZERO;
- Self().SetProperty(Toolkit::ScrollView::Property::SCROLL_DOMAIN_OFFSET, Vector3::ZERO);
+ mDomainOffset = Vector2::ZERO;
+ Self().SetProperty(Toolkit::ScrollView::Property::SCROLL_DOMAIN_OFFSET, Vector2::ZERO);
UpdateLocalScrollProperties();
- Vector3 currentScrollPosition = GetCurrentScrollPosition();
+ Vector2 currentScrollPosition = GetCurrentScrollPosition();
DALI_LOG_SCROLL_STATE("[0x%X] mScrollCompletedSignal 4 [%.2f, %.2f]", this, currentScrollPosition.x, currentScrollPosition.y);
mScrollCompletedSignal.Emit( currentScrollPosition );
}
return false;
}
-bool ScrollView::OnTouchEvent(const TouchEvent& event)
+bool ScrollView::OnTouch( Actor actor, const TouchData& touch )
{
if(!mSensitive)
{
}
// Ignore events with multiple-touch points
- if (event.GetPointCount() != 1)
+ if (touch.GetPointCount() != 1)
{
DALI_LOG_SCROLL_STATE("[0x%X], multiple touch, ignoring", this);
return false;
}
- const TouchPoint::State pointState = event.GetPoint(0).state;
- if( pointState == TouchPoint::Down )
+ const PointState::Type pointState = touch.GetState( 0 );
+ if( pointState == PointState::DOWN )
{
DALI_LOG_SCROLL_STATE("[0x%X] Down", this);
if(mGestureStackDepth==0)
{
- mTouchDownTime = event.time;
+ mTouchDownTime = touch.GetTime();
// This allows time for a pan-gesture to start, to avoid breaking snap-animation behavior with fast flicks.
// If touch-down does not become a pan (after timeout interval), then snap-animation can be interrupted.
StartTouchDownTimer();
}
}
- else if( ( pointState == TouchPoint::Up ) ||
- ( ( pointState == TouchPoint::Interrupted ) && ( event.GetPoint(0).hitActor == Self() ) ) )
+ else if( ( pointState == PointState::UP ) ||
+ ( ( pointState == PointState::INTERRUPTED ) && ( touch.GetHitActor( 0 )== Self() ) ) )
{
DALI_LOG_SCROLL_STATE("[0x%X] %s", this, ( ( pointState == TouchPoint::Up ) ? "Up" : "Interrupted" ) );
// otherwise our scroll could be stopped (interrupted) half way through an animation.
if(mGestureStackDepth==0 && mTouchDownTimeoutReached)
{
- if( ( event.GetPoint(0).state == TouchPoint::Interrupted ) ||
- ( ( event.time - mTouchDownTime ) >= MINIMUM_TIME_BETWEEN_DOWN_AND_UP_FOR_RESET ) )
+ if( ( pointState == PointState::INTERRUPTED ) ||
+ ( ( touch.GetTime() - mTouchDownTime ) >= MINIMUM_TIME_BETWEEN_DOWN_AND_UP_FOR_RESET ) )
{
// Reset the velocity only if down was received a while ago
mLastVelocity = Vector2( 0.0f, 0.0f );
return true;
}
-bool ScrollView::OnMouseWheelEvent(const MouseWheelEvent& event)
+bool ScrollView::OnWheelEvent(const WheelEvent& event)
{
if(!mSensitive)
{
- // Ignore this mouse wheel event, if scrollview is insensitive.
+ // Ignore this wheel event, if scrollview is insensitive.
return false;
}
- Vector3 targetScrollPosition = GetPropertyPosition();
+ Vector2 targetScrollPosition = GetPropertyPosition();
if(mRulerX->IsEnabled() && !mRulerY->IsEnabled())
{
if(mRulerX->GetType() == Ruler::Free)
{
// Free panning mode
- targetScrollPosition.x += event.z * mMouseWheelScrollDistanceStep.x;
+ targetScrollPosition.x += event.z * mWheelScrollDistanceStep.x;
ClampPosition(targetScrollPosition);
ScrollTo(-targetScrollPosition);
}
if(mRulerY->GetType() == Ruler::Free)
{
// Free panning mode
- targetScrollPosition.y += event.z * mMouseWheelScrollDistanceStep.y;
+ targetScrollPosition.y += event.z * mWheelScrollDistanceStep.y;
ClampPosition(targetScrollPosition);
ScrollTo(-targetScrollPosition);
}
void ScrollView::ResetScrolling()
{
Actor self = Self();
- self.GetProperty(Toolkit::ScrollView::Property::SCROLL_POSITION).Get(mScrollPostPosition);
+ self.GetCurrentProperty( Toolkit::ScrollView::Property::SCROLL_POSITION ).Get( mScrollPostPosition );
mScrollPrePosition = mScrollPostPosition;
DALI_LOG_SCROLL_STATE("[0x%X] Setting SCROLL_PRE_POSITION To[%.2f, %.2f]", this, mScrollPostPosition.x, mScrollPostPosition.y );
self.SetProperty(Toolkit::ScrollView::Property::SCROLL_PRE_POSITION, mScrollPostPosition);
void ScrollView::UpdateLocalScrollProperties()
{
Actor self = Self();
- self.GetProperty(Toolkit::ScrollView::Property::SCROLL_PRE_POSITION).Get(mScrollPrePosition);
- self.GetProperty(Toolkit::ScrollView::Property::SCROLL_POSITION).Get(mScrollPostPosition);
+ self.GetCurrentProperty( Toolkit::ScrollView::Property::SCROLL_PRE_POSITION ).Get( mScrollPrePosition );
+ self.GetCurrentProperty( Toolkit::ScrollView::Property::SCROLL_POSITION ).Get( mScrollPostPosition );
}
// private functions
Actor self = Self();
- Vector3 deltaPosition(mScrollPostPosition);
+ Vector2 deltaPosition(mScrollPostPosition);
WrapPosition(mScrollPostPosition);
mDomainOffset += deltaPosition - mScrollPostPosition;
Self().SetProperty(Toolkit::ScrollView::Property::SCROLL_DOMAIN_OFFSET, mDomainOffset);
if( duration > Math::MACHINE_EPSILON_10 )
{
Actor self = Self();
- DALI_LOG_SCROLL_STATE("[0x%X], Animating from[%.2f] to[%.2f]", this, self.GetProperty(Toolkit::ScrollView::Property::SCROLL_PRE_POSITION).Get<Vector3>().x, position );
+ DALI_LOG_SCROLL_STATE("[0x%X], Animating from[%.2f] to[%.2f]", this, self.GetCurrentProperty( Toolkit::ScrollView::Property::SCROLL_PRE_POSITION ).Get< Vector2 >().x, position );
mInternalXAnimation = Animation::New(duration);
DALI_LOG_SCROLL_STATE("[0x%X], mInternalXAnimation[0x%X]", this, mInternalXAnimation.GetObjectPtr() );
mInternalXAnimation.FinishedSignal().Connect(this, &ScrollView::OnScrollAnimationFinished);
if( duration > Math::MACHINE_EPSILON_10 )
{
Actor self = Self();
- DALI_LOG_SCROLL_STATE("[0x%X], Animating from[%.2f] to[%.2f]", this, self.GetProperty(Toolkit::ScrollView::Property::SCROLL_PRE_POSITION).Get<Vector3>().y, position );
+ DALI_LOG_SCROLL_STATE("[0x%X], Animating from[%.2f] to[%.2f]", this, self.GetCurrentProperty( Toolkit::ScrollView::Property::SCROLL_PRE_POSITION ).Get< Vector2 >().y, position );
mInternalYAnimation = Animation::New(duration);
DALI_LOG_SCROLL_STATE("[0x%X], mInternalYAnimation[0x%X]", this, mInternalYAnimation.GetObjectPtr() );
mInternalYAnimation.FinishedSignal().Connect(this, &ScrollView::OnScrollAnimationFinished);
if( source == mInternalXAnimation )
{
- DALI_LOG_SCROLL_STATE("[0x%X] mInternalXAnimation[0x%X], expected[%.2f], actual[%.2f], post[%.2f]", this, mInternalXAnimation.GetObjectPtr(), mScrollTargetPosition.x, Self().GetProperty(SCROLL_PRE_POSITION).Get<Vector3>().x, mScrollPostPosition.x );
+ DALI_LOG_SCROLL_STATE("[0x%X] mInternalXAnimation[0x%X], expected[%.2f], actual[%.2f], post[%.2f]", this, mInternalXAnimation.GetObjectPtr(), mScrollTargetPosition.x, Self().GetCurrentProperty( SCROLL_PRE_POSITION ).Get< Vector2 >().x, mScrollPostPosition.x );
if( !(mScrollStateFlags & AnimatingInternalY) )
{
if( source == mInternalYAnimation )
{
- DALI_LOG_SCROLL_STATE("[0x%X] mInternalYAnimation[0x%X], expected[%.2f], actual[%.2f], post[%.2f]", this, mInternalYAnimation.GetObjectPtr(), mScrollTargetPosition.y, Self().GetProperty(SCROLL_PRE_POSITION).Get<Vector3>().y, mScrollPostPosition.y );
+ DALI_LOG_SCROLL_STATE("[0x%X] mInternalYAnimation[0x%X], expected[%.2f], actual[%.2f], post[%.2f]", this, mInternalYAnimation.GetObjectPtr(), mScrollTargetPosition.y, DevelHandle::GetProperty( Self(), SCROLL_PRE_POSITION ).Get< Vector2 >().y, mScrollPostPosition.y );
if( !(mScrollStateFlags & AnimatingInternalX) )
{
Actor self = Self();
StopTouchDownTimer();
StopAnimation();
- mPanDelta = Vector3::ZERO;
- mLastVelocity = Vector2(0.0f, 0.0f);
+ mPanDelta = Vector2::ZERO;
+ mLastVelocity = Vector2::ZERO;
if( !mScrolling )
{
mLockAxis = LockPossible;
// appears mostly horizontal or mostly vertical respectively.
if(mAxisAutoLock)
{
- mLockAxis = GetLockAxis(mPanDelta.GetVectorXY(), mLockAxis, mAxisAutoLockGradient);
+ mLockAxis = GetLockAxis(mPanDelta, mLockAxis, mAxisAutoLockGradient);
} // end if mAxisAutoLock
}
self.SetProperty( Toolkit::ScrollView::Property::START_PAGE_POSITION, Vector3(gesture.position.x, gesture.position.y, 0.0f) );
UpdateMainInternalConstraint();
+ Toolkit::ScrollBar scrollBar = mScrollBar.GetHandle();
+ if( scrollBar && mTransientScrollBar )
+ {
+ Vector3 size = Self().GetCurrentSize();
+ const Toolkit::RulerDomain& rulerDomainX = mRulerX->GetDomain();
+ const Toolkit::RulerDomain& rulerDomainY = mRulerY->GetDomain();
+
+ if( ( rulerDomainX.max > size.width ) || ( rulerDomainY.max > size.height ) )
+ {
+ scrollBar.ShowIndicator();
+ }
+ }
break;
}
mScrollMainInternalPrePositionConstraint.Remove();
}
- if( mOvershootIndicator )
+ Toolkit::ScrollBar scrollBar = mScrollBar.GetHandle();
+ if( scrollBar && mTransientScrollBar )
{
- mOvershootIndicator->ClearOvershoot();
+ scrollBar.HideIndicator();
}
}
else
if(state == Gesture::Started)
{
- Vector3 currentScrollPosition = GetCurrentScrollPosition();
+ Vector2 currentScrollPosition = GetCurrentScrollPosition();
Self().SetProperty(Toolkit::ScrollView::Property::SCROLLING, true);
mScrolling = true;
DALI_LOG_SCROLL_STATE("[0x%X] mScrollStartedSignal 2 [%.2f, %.2f]", this, currentScrollPosition.x, currentScrollPosition.y);
{
SnapInternalYTo(mScrollTargetPosition.y);
}
- Vector3 currentScrollPosition = GetCurrentScrollPosition();
+ Vector2 currentScrollPosition = GetCurrentScrollPosition();
DALI_LOG_SCROLL_STATE("[0x%X] mScrollCompletedSignal 6 [%.2f, %.2f]", this, currentScrollPosition.x, currentScrollPosition.y);
mScrollCompletedSignal.Emit( currentScrollPosition );
}
}
-Vector3 ScrollView::GetOvershoot(Vector3& position) const
+Vector2 ScrollView::GetOvershoot(Vector2& position) const
{
Vector3 size = Self().GetCurrentSize();
- Vector3 overshoot;
+ Vector2 overshoot;
const RulerDomain rulerDomainX = mRulerX->GetDomain();
const RulerDomain rulerDomainY = mRulerY->GetDomain();
return true;
}
-void ScrollView::ClampPosition(Vector3& position) const
+void ScrollView::ClampPosition(Vector2& position) const
{
- ClampState3D clamped;
+ ClampState2D clamped;
ClampPosition(position, clamped);
}
-void ScrollView::ClampPosition(Vector3& position, ClampState3D &clamped) const
+void ScrollView::ClampPosition(Vector2& position, ClampState2D &clamped) const
{
Vector3 size = Self().GetCurrentSize();
position.x = -mRulerX->Clamp(-position.x, size.width, 1.0f, clamped.x); // NOTE: X & Y rulers think in -ve coordinate system.
position.y = -mRulerY->Clamp(-position.y, size.height, 1.0f, clamped.y); // That is scrolling RIGHT (e.g. 100.0, 0.0) means moving LEFT.
-
- clamped.z = NotClamped;
}
-void ScrollView::WrapPosition(Vector3& position) const
+void ScrollView::WrapPosition(Vector2& position) const
{
if(mWrapMode)
{
mScrollMainInternalDeltaConstraint.Remove();
mScrollMainInternalFinalConstraint.Remove();
mScrollMainInternalRelativeConstraint.Remove();
+ mScrollMainInternalDomainConstraint.Remove();
+ mScrollMainInternalPrePositionMaxConstraint.Remove();
}
if( mScrollMainInternalPrePositionConstraint )
{
if( mPanning )
{
- mScrollMainInternalPrePositionConstraint = Constraint::New<Vector3>( self,
+ mScrollMainInternalPrePositionConstraint = Constraint::New<Vector2>( self,
Toolkit::ScrollView::Property::SCROLL_PRE_POSITION,
InternalPrePositionConstraint( mPanStartPosition,
initialPanMask,
mAxisAutoLockGradient,
mLockAxis,
mMaxOvershoot,
- mRulerX->GetDomain(),
- mRulerY->GetDomain() ) );
+ mRulerX,
+ mRulerY ) );
mScrollMainInternalPrePositionConstraint.AddSource( Source( detector, PanGestureDetector::Property::LOCAL_POSITION ) );
+ mScrollMainInternalPrePositionConstraint.AddSource( Source( detector, PanGestureDetector::Property::PANNING ) );
mScrollMainInternalPrePositionConstraint.AddSource( Source( self, Actor::Property::SIZE ) );
mScrollMainInternalPrePositionConstraint.Apply();
}
// 2. Second calculate the clamped position (actual position)
- mScrollMainInternalPositionConstraint = Constraint::New<Vector3>( self,
+ mScrollMainInternalPositionConstraint = Constraint::New<Vector2>( self,
Toolkit::ScrollView::Property::SCROLL_POSITION,
InternalPositionConstraint( mRulerX->GetDomain(),
mRulerY->GetDomain(),
mScrollMainInternalPositionConstraint.AddSource( Source( self, Actor::Property::SIZE ) );
mScrollMainInternalPositionConstraint.Apply();
- mScrollMainInternalDeltaConstraint = Constraint::New<Vector3>( self, Toolkit::ScrollView::Property::SCROLL_POSITION_DELTA, InternalPositionDeltaConstraint );
+ mScrollMainInternalDeltaConstraint = Constraint::New<Vector2>( self, Toolkit::ScrollView::Property::SCROLL_POSITION_DELTA, InternalPositionDeltaConstraint );
mScrollMainInternalDeltaConstraint.AddSource( LocalSource( Toolkit::ScrollView::Property::SCROLL_POSITION ) );
mScrollMainInternalDeltaConstraint.AddSource( LocalSource( Toolkit::ScrollView::Property::SCROLL_DOMAIN_OFFSET ) );
mScrollMainInternalDeltaConstraint.Apply();
- mScrollMainInternalFinalConstraint = Constraint::New<Vector3>( self, Toolkit::ScrollView::Property::SCROLL_FINAL,
+ mScrollMainInternalFinalConstraint = Constraint::New<Vector2>( self, Toolkit::ScrollView::Property::SCROLL_FINAL,
InternalFinalConstraint( FinalDefaultAlphaFunction,
FinalDefaultAlphaFunction ) );
- mScrollMainInternalFinalConstraint .AddSource( LocalSource( Toolkit::ScrollView::Property::SCROLL_POSITION ) );
- mScrollMainInternalFinalConstraint .AddSource( LocalSource( Toolkit::ScrollView::Property::OVERSHOOT_X ) );
- mScrollMainInternalFinalConstraint .AddSource( LocalSource( Toolkit::ScrollView::Property::OVERSHOOT_Y ) );
+ mScrollMainInternalFinalConstraint.AddSource( LocalSource( Toolkit::ScrollView::Property::SCROLL_POSITION ) );
+ mScrollMainInternalFinalConstraint.AddSource( LocalSource( Toolkit::ScrollView::Property::OVERSHOOT_X ) );
+ mScrollMainInternalFinalConstraint.AddSource( LocalSource( Toolkit::ScrollView::Property::OVERSHOOT_Y ) );
mScrollMainInternalFinalConstraint.Apply();
- mScrollMainInternalRelativeConstraint = Constraint::New<Vector3>( self, Toolkit::Scrollable::Property::SCROLL_RELATIVE_POSITION, InternalRelativePositionConstraint );
+ mScrollMainInternalRelativeConstraint = Constraint::New<Vector2>( self, Toolkit::Scrollable::Property::SCROLL_RELATIVE_POSITION, InternalRelativePositionConstraint );
mScrollMainInternalRelativeConstraint.AddSource( LocalSource( Toolkit::ScrollView::Property::SCROLL_POSITION ) );
mScrollMainInternalRelativeConstraint.AddSource( LocalSource( Toolkit::Scrollable::Property::SCROLL_POSITION_MIN ) );
mScrollMainInternalRelativeConstraint.AddSource( LocalSource( Toolkit::Scrollable::Property::SCROLL_POSITION_MAX ) );
mScrollMainInternalRelativeConstraint.AddSource( LocalSource( Actor::Property::SIZE ) );
mScrollMainInternalRelativeConstraint.Apply();
+ mScrollMainInternalDomainConstraint = Constraint::New<Vector2>( self, Toolkit::ScrollView::Property::SCROLL_DOMAIN_SIZE, InternalScrollDomainConstraint );
+ mScrollMainInternalDomainConstraint.AddSource( LocalSource( Toolkit::Scrollable::Property::SCROLL_POSITION_MIN ) );
+ mScrollMainInternalDomainConstraint.AddSource( LocalSource( Toolkit::Scrollable::Property::SCROLL_POSITION_MAX ) );
+ mScrollMainInternalDomainConstraint.AddSource( LocalSource( Actor::Property::SIZE ) );
+ mScrollMainInternalDomainConstraint.Apply();
+
+ mScrollMainInternalPrePositionMaxConstraint = Constraint::New<Vector2>( self, Toolkit::ScrollView::Property::SCROLL_PRE_POSITION_MAX, InternalPrePositionMaxConstraint );
+ mScrollMainInternalPrePositionMaxConstraint.AddSource( LocalSource( Toolkit::Scrollable::Property::SCROLL_POSITION_MAX ) );
+ mScrollMainInternalPrePositionMaxConstraint.AddSource( LocalSource( Actor::Property::SIZE ) );
+ mScrollMainInternalPrePositionMaxConstraint.Apply();
+
// When panning we want to make sure overshoot values are affected by pre position and post position
SetOvershootConstraintsEnabled(!mWrapMode);
}
ApplyConstraintToBoundActors(constraint);
}
+void ScrollView::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value )
+{
+ Toolkit::ScrollView scrollView = Toolkit::ScrollView::DownCast( Dali::BaseHandle( object ) );
+
+ if( scrollView )
+ {
+ ScrollView& scrollViewImpl( GetImpl( scrollView ) );
+ switch( index )
+ {
+ case Toolkit::ScrollView::Property::WRAP_ENABLED:
+ {
+ scrollViewImpl.SetWrapMode( value.Get<bool>() );
+ break;
+ }
+ case Toolkit::ScrollView::Property::PANNING_ENABLED:
+ {
+ scrollViewImpl.SetScrollSensitive( value.Get<bool>() );
+ break;
+ }
+ case Toolkit::ScrollView::Property::AXIS_AUTO_LOCK_ENABLED:
+ {
+ scrollViewImpl.SetAxisAutoLock( value.Get<bool>() );
+ break;
+ }
+ case Toolkit::ScrollView::Property::WHEEL_SCROLL_DISTANCE_STEP:
+ {
+ scrollViewImpl.SetWheelScrollDistanceStep( value.Get<Vector2>() );
+ break;
+ }
+ case Toolkit::ScrollView::Property::SCROLL_MODE:
+ {
+ Property::Map* map = value.GetMap();
+ if( map )
+ {
+ scrollViewImpl.SetScrollMode( *map );
+ }
+ }
+ }
+ }
+}
+
+Property::Value ScrollView::GetProperty( BaseObject* object, Property::Index index )
+{
+ Property::Value value;
+
+ Toolkit::ScrollView scrollView = Toolkit::ScrollView::DownCast( Dali::BaseHandle( object ) );
+
+ if( scrollView )
+ {
+ ScrollView& scrollViewImpl( GetImpl( scrollView ) );
+ switch( index )
+ {
+ case Toolkit::ScrollView::Property::WRAP_ENABLED:
+ {
+ value = scrollViewImpl.GetWrapMode();
+ break;
+ }
+ case Toolkit::ScrollView::Property::PANNING_ENABLED:
+ {
+ value = scrollViewImpl.GetScrollSensitive();
+ break;
+ }
+ case Toolkit::ScrollView::Property::AXIS_AUTO_LOCK_ENABLED:
+ {
+ value = scrollViewImpl.GetAxisAutoLock();
+ break;
+ }
+ case Toolkit::ScrollView::Property::WHEEL_SCROLL_DISTANCE_STEP:
+ {
+ value = scrollViewImpl.GetWheelScrollDistanceStep();
+ break;
+ }
+ }
+ }
+
+ return value;
+}
+
+void ScrollView::SetScrollMode( const Property::Map& scrollModeMap )
+{
+ Toolkit::RulerPtr rulerX, rulerY;
+
+ // Check the scroll mode in the X axis
+ bool xAxisScrollEnabled = true;
+ Property::Value* valuePtr = scrollModeMap.Find( Toolkit::ScrollMode::X_AXIS_SCROLL_ENABLED, "xAxisScrollEnabled" );
+ if( valuePtr && valuePtr->GetType() == Property::BOOLEAN )
+ {
+ valuePtr->Get( xAxisScrollEnabled );
+ }
+
+ if( !xAxisScrollEnabled )
+ {
+ // Default ruler and disabled
+ rulerX = new Toolkit::DefaultRuler();
+ rulerX->Disable();
+ }
+ else
+ {
+ valuePtr = scrollModeMap.Find( Toolkit::ScrollMode::X_AXIS_SNAP_TO_INTERVAL, "xAxisSnapToInterval" );
+ float xAxisSnapToInterval = 0.0f;
+ if( valuePtr && valuePtr->Get( xAxisSnapToInterval ) )
+ {
+ // Fixed ruler and enabled
+ rulerX = new Toolkit::FixedRuler( xAxisSnapToInterval );
+ }
+ else
+ {
+ // Default ruler and enabled
+ rulerX = new Toolkit::DefaultRuler();
+ }
+
+ valuePtr = scrollModeMap.Find( Toolkit::ScrollMode::X_AXIS_SCROLL_BOUNDARY, "xAxisScrollBoundary" );
+ float xAxisScrollBoundary = 0.0f;
+ if( valuePtr && valuePtr->Get( xAxisScrollBoundary ) )
+ {
+ // By default ruler domain is disabled unless set
+ rulerX->SetDomain( Toolkit::RulerDomain( 0, xAxisScrollBoundary, true ) );
+ }
+ }
+
+ // Check the scroll mode in the Y axis
+ bool yAxisScrollEnabled = true;
+ valuePtr = scrollModeMap.Find( Toolkit::ScrollMode::Y_AXIS_SCROLL_ENABLED, "yAxisScrollEnabled" );
+ if( valuePtr && valuePtr->GetType() == Property::BOOLEAN )
+ {
+ valuePtr->Get( yAxisScrollEnabled );
+ }
+
+ if( !yAxisScrollEnabled )
+ {
+ // Default ruler and disabled
+ rulerY = new Toolkit::DefaultRuler();
+ rulerY->Disable();
+ }
+ else
+ {
+ valuePtr = scrollModeMap.Find( Toolkit::ScrollMode::Y_AXIS_SNAP_TO_INTERVAL, "yAxisSnapToInterval" );
+ float yAxisSnapToInterval = 0.0f;
+ if( valuePtr && valuePtr->Get( yAxisSnapToInterval ) )
+ {
+ // Fixed ruler and enabled
+ rulerY = new Toolkit::FixedRuler(yAxisSnapToInterval);
+ }
+ else
+ {
+ // Default ruler and enabled
+ rulerY = new Toolkit::DefaultRuler();
+ }
+
+ valuePtr = scrollModeMap.Find( Toolkit::ScrollMode::Y_AXIS_SCROLL_BOUNDARY, "yAxisScrollBoundary" );
+ float yAxisScrollBoundary = 0.0f;
+ if( valuePtr && valuePtr->Get( yAxisScrollBoundary ) )
+ {
+ // By default ruler domain is disabled unless set
+ rulerY->SetDomain( Toolkit::RulerDomain( 0, yAxisScrollBoundary, true ) );
+ }
+ }
+
+ SetRulerX(rulerX);
+ SetRulerY(rulerY);
+}
+
} // namespace Internal
} // namespace Toolkit