X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=blobdiff_plain;f=base%2Fdali-toolkit%2Finternal%2Fcontrols%2Fscrollable%2Fitem-view%2Fitem-view-impl.cpp;h=0011dff7db2ef47038563df0c5f55c0503b40548;hp=be23888a61fd402484e641572494ccde90ae7dd8;hb=680c5587a1478717393d3a03cf6a17801edd00e0;hpb=dfd5e2bb9fad25b532ebed9713414ee9700c3255 diff --git a/base/dali-toolkit/internal/controls/scrollable/item-view/item-view-impl.cpp b/base/dali-toolkit/internal/controls/scrollable/item-view/item-view-impl.cpp index be23888..0011dff 100644 --- a/base/dali-toolkit/internal/controls/scrollable/item-view/item-view-impl.cpp +++ b/base/dali-toolkit/internal/controls/scrollable/item-view/item-view-impl.cpp @@ -20,14 +20,20 @@ // EXTERNAL INCLUDES #include +#include +#include +#include +#include +#include +#include // INTERNAL INCLUDES -#include #include #include -#include +#include -using namespace std; +using std::string; +using std::set; using namespace Dali; namespace // unnamed namespace @@ -40,15 +46,18 @@ const float DEFAULT_MINIMUM_SWIPE_SPEED = 1.0f; const float DEFAULT_MINIMUM_SWIPE_DISTANCE = 3.0f; const float DEFAULT_MOUSE_WHEEL_SCROLL_DISTANCE_STEP_PROPORTION = 0.1f; +const float DEFAULT_MINIMUM_SWIPE_DURATION = 0.45f; +const float DEFAULT_MAXIMUM_SWIPE_DURATION = 2.6f; + const float DEFAULT_REFRESH_INTERVAL_LAYOUT_POSITIONS = 20.0f; // 1 updates per 20 items const int MOUSE_WHEEL_EVENT_FINISHED_TIME_OUT = 500; // 0.5 second const float DEFAULT_ANCHORING_DURATION = 1.0f; // 1 second -const float DEFAULT_COLOR_VISIBILITY_REMOVE_TIME = 0.5f; // 0.5 second const float MILLISECONDS_PER_SECONDS = 1000.0f; -const Rect OVERSHOOT_BOUNCE_IMAGE_1_PIXEL_AREA( 0, 0, 720, 58 ); +const Vector2 OVERSHOOT_BOUNCE_ACTOR_DEFAULT_SIZE( 720.0f, 42.0f ); +const float OVERSHOOT_BOUNCE_ACTOR_RESIZE_THRESHOLD = 180.0f; const Vector4 OVERSHOOT_OVERLAY_NINE_PATCH_BORDER(0.0f, 0.0f, 1.0f, 12.0f); const float MAXIMUM_OVERSHOOT_HEIGHT = 36.0f; // 36 pixels const float DEFAULT_OVERSHOOT_ANIMATION_DURATION = 0.5f; // 0.5 second @@ -61,84 +70,6 @@ const string SCROLL_SPEED_PROPERTY_NAME( "item-view-scroll-speed" ); const string SCROLL_DIRECTION_PROPERTY_NAME( "item-view-scroll-direction" ); const string OVERSHOOT_PROPERTY_NAME( "item-view-overshoot" ); -// Functors which wrap constraint functions with stored item IDs - -struct WrappedVector3Constraint -{ - WrappedVector3Constraint(Toolkit::ItemLayout::Vector3Function wrapMe, unsigned int itemId) - : mWrapMe(wrapMe), - mItemId(itemId) - { - } - - Vector3 operator()(const Vector3& current, const PropertyInput& layoutPosition, const PropertyInput& scrollSpeed, const PropertyInput& layoutSize) - { - float offsetLayoutPosition = layoutPosition.GetFloat() + static_cast(mItemId); - - return mWrapMe(current, offsetLayoutPosition, scrollSpeed.GetFloat(), layoutSize.GetVector3()); - } - - Toolkit::ItemLayout::Vector3Function mWrapMe; - unsigned int mItemId; -}; - -struct WrappedQuaternionConstraint -{ - WrappedQuaternionConstraint(Toolkit::ItemLayout::QuaternionFunction wrapMe, unsigned int itemId) - : mWrapMe(wrapMe), - mItemId(itemId) - { - } - - Quaternion operator()(const Quaternion& current, const PropertyInput& layoutPosition, const PropertyInput& scrollSpeed, const PropertyInput& layoutSize) - { - float offsetLayoutPosition = layoutPosition.GetFloat() + static_cast(mItemId); - - return mWrapMe(current, offsetLayoutPosition, scrollSpeed.GetFloat(), layoutSize.GetVector3()); - } - - Toolkit::ItemLayout::QuaternionFunction mWrapMe; - unsigned int mItemId; -}; - -struct WrappedVector4Constraint -{ - WrappedVector4Constraint(Toolkit::ItemLayout::Vector4Function wrapMe, unsigned int itemId) - : mWrapMe(wrapMe), - mItemId(itemId) - { - } - - Vector4 operator()(const Vector4& current, const PropertyInput& layoutPosition, const PropertyInput& scrollSpeed, const PropertyInput& layoutSize) - { - float offsetLayoutPosition = layoutPosition.GetFloat() + static_cast(mItemId); - - return mWrapMe(current, offsetLayoutPosition, scrollSpeed.GetFloat(), layoutSize.GetVector3()); - } - - Toolkit::ItemLayout::Vector4Function mWrapMe; - unsigned int mItemId; -}; - -struct WrappedBoolConstraint -{ - WrappedBoolConstraint(Toolkit::ItemLayout::BoolFunction wrapMe, unsigned int itemId) - : mWrapMe(wrapMe), - mItemId(itemId) - { - } - - bool operator()(const bool& current, const PropertyInput& layoutPosition, const PropertyInput& scrollSpeed, const PropertyInput& layoutSize) - { - float offsetLayoutPosition = layoutPosition.GetFloat() + static_cast(mItemId); - - return mWrapMe(current, offsetLayoutPosition, scrollSpeed.GetFloat(), layoutSize.GetVector3()); - } - - Toolkit::ItemLayout::BoolFunction mWrapMe; - unsigned int mItemId; -}; - /** * Local helper to convert pan distance (in actor coordinates) to the layout-specific scrolling direction */ @@ -156,7 +87,7 @@ float CalculateScrollDistance(Vector2 panDistance, Toolkit::ItemLayout& layout) struct OvershootOverlaySizeConstraint { - float operator()(const float& current, + Vector3 operator()(const Vector3& current, const PropertyInput& parentScrollDirectionProperty, const PropertyInput& parentOvershootProperty, const PropertyInput& parentSizeProperty) @@ -176,7 +107,9 @@ struct OvershootOverlaySizeConstraint overlayWidth = fabsf(parentScrollDirection.x) > Math::MACHINE_EPSILON_1 ? parentSize.y : parentSize.x; } - return overlayWidth; + float overlayHeight = (overlayWidth > OVERSHOOT_BOUNCE_ACTOR_RESIZE_THRESHOLD) ? OVERSHOOT_BOUNCE_ACTOR_DEFAULT_SIZE.height : OVERSHOOT_BOUNCE_ACTOR_DEFAULT_SIZE.height*0.5f; + + return Vector3( overlayWidth, overlayHeight, current.depth ); } }; @@ -396,12 +329,11 @@ ItemView::ItemView(ItemFactory& factory) : Scrollable(), mItemFactory(factory), mActiveLayout(NULL), - mDefaultAlphaFunction(Dali::Constraint::DEFAULT_ALPHA_FUNCTION), mAnimatingOvershootOn(false), mAnimateOvershootOff(false), mAnchoringEnabled(true), mAnchoringDuration(DEFAULT_ANCHORING_DURATION), - mRefreshIntervalLayoutPositions(DEFAULT_REFRESH_INTERVAL_LAYOUT_POSITIONS), + mRefreshIntervalLayoutPositions(0.0f), mRefreshOrderHint(true/*Refresh item 0 first*/), mMinimumSwipeSpeed(DEFAULT_MINIMUM_SWIPE_SPEED), mMinimumSwipeDistance(DEFAULT_MINIMUM_SWIPE_DISTANCE), @@ -430,6 +362,7 @@ void ItemView::OnInitialize() mScrollConnector = Dali::Toolkit::ScrollConnector::New(); mScrollPositionObject = mScrollConnector.GetScrollPositionObject(); + mScrollConnector.ScrollPositionChangedSignal().Connect( this, &ItemView::OnScrollPositionChanged ); mPropertyMinimumLayoutPosition = self.RegisterProperty(MINIMUM_LAYOUT_POSITION_PROPERTY_NAME, 0.0f); mPropertyPosition = self.RegisterProperty(POSITION_PROPERTY_NAME, 0.0f); @@ -453,7 +386,7 @@ void ItemView::OnInitialize() mMouseWheelEventFinishedTimer = Timer::New( MOUSE_WHEEL_EVENT_FINISHED_TIME_OUT ); mMouseWheelEventFinishedTimer.TickSignal().Connect( this, &ItemView::OnMouseWheelEventFinished ); - SetRefreshInterval(mRefreshIntervalLayoutPositions); + SetRefreshInterval(DEFAULT_REFRESH_INTERVAL_LAYOUT_POSITIONS); } ItemView::~ItemView() @@ -499,13 +432,15 @@ ItemLayoutPtr ItemView::GetActiveLayout() const float ItemView::GetCurrentLayoutPosition(unsigned int itemId) const { - return mScrollPositionObject.GetProperty( ScrollConnector::SCROLL_POSITION ) + static_cast( itemId ); + return mScrollConnector.GetScrollPosition() + static_cast( itemId ); } void ItemView::ActivateLayout(unsigned int layoutIndex, const Vector3& targetSize, float durationSeconds) { DALI_ASSERT_ALWAYS(layoutIndex < mLayouts.size()); + mRefreshEnabled = false; + Actor self = Self(); // The ItemView size should match the active layout size @@ -518,7 +453,6 @@ void ItemView::ActivateLayout(unsigned int layoutIndex, const Vector3& targetSiz // Move the items to the new layout positions... bool resizeAnimationNeeded(false); - for (ConstItemPoolIter iter = mItemPool.begin(); iter != mItemPool.end(); ++iter) { unsigned int itemId = iter->first; @@ -550,7 +484,7 @@ void ItemView::ActivateLayout(unsigned int layoutIndex, const Vector3& targetSiz } } - ApplyConstraints(actor, *mActiveLayout, itemId, durationSeconds); + mActiveLayout->ApplyConstraints(actor, itemId, durationSeconds, mScrollPositionObject, Self() ); } if (resizeAnimationNeeded) @@ -559,7 +493,7 @@ void ItemView::ActivateLayout(unsigned int layoutIndex, const Vector3& targetSiz } // Refresh the new layout - ItemRange range = GetItemRange(*mActiveLayout, targetSize, GetCurrentLayoutPosition(0), true/*reserve extra*/); + ItemRange range = GetItemRange(*mActiveLayout, targetSize, GetCurrentLayoutPosition(0), false/* don't reserve extra*/); AddActorsWithinRange( range, durationSeconds ); // Scroll to an appropriate layout position @@ -585,9 +519,10 @@ void ItemView::ActivateLayout(unsigned int layoutIndex, const Vector3& targetSiz if (scrollAnimationNeeded) { RemoveAnimation(mScrollAnimation); - mScrollAnimation = Animation::New(mAnchoringDuration); + mScrollAnimation = Animation::New(durationSeconds); mScrollAnimation.AnimateTo( Property( mScrollPositionObject, ScrollConnector::SCROLL_POSITION ), firstItemScrollPosition, AlphaFunctions::EaseOut ); mScrollAnimation.AnimateTo( Property(self, mPropertyPosition), GetScrollPosition(firstItemScrollPosition, targetSize), AlphaFunctions::EaseOut ); + mScrollAnimation.FinishedSignal().Connect(this, &ItemView::OnLayoutActivationScrollFinished); mScrollAnimation.Play(); } @@ -618,19 +553,9 @@ void ItemView::DeactivateCurrentLayout() } } -void ItemView::SetDefaultAlphaFunction(AlphaFunction func) -{ - mDefaultAlphaFunction = func; -} - -AlphaFunction ItemView::GetDefaultAlphaFunction() const -{ - return mDefaultAlphaFunction; -} - void ItemView::OnRefreshNotification(PropertyNotification& source) { - if(mRefreshEnabled) + if(mRefreshEnabled || mScrollAnimation) { // Only refresh the cache during normal scrolling DoRefresh(GetCurrentLayoutPosition(0), true); @@ -701,14 +626,17 @@ float ItemView::GetAnchoringDuration() const void ItemView::SetRefreshInterval(float intervalLayoutPositions) { - mRefreshIntervalLayoutPositions = intervalLayoutPositions; - - if(mRefreshNotification) + if(mRefreshIntervalLayoutPositions != intervalLayoutPositions) { - mScrollPositionObject.RemovePropertyNotification(mRefreshNotification); + mRefreshIntervalLayoutPositions = intervalLayoutPositions; + + if(mRefreshNotification) + { + mScrollPositionObject.RemovePropertyNotification(mRefreshNotification); + } + mRefreshNotification = mScrollPositionObject.AddPropertyNotification( ScrollConnector::SCROLL_POSITION, StepCondition(mRefreshIntervalLayoutPositions, 0.0f) ); + mRefreshNotification.NotifySignal().Connect( this, &ItemView::OnRefreshNotification ); } - mRefreshNotification = mScrollPositionObject.AddPropertyNotification( ScrollConnector::SCROLL_POSITION, StepCondition(mRefreshIntervalLayoutPositions, 0.0f) ); - mRefreshNotification.NotifySignal().Connect( this, &ItemView::OnRefreshNotification ); } float ItemView::GetRefreshInterval() const @@ -771,7 +699,7 @@ void ItemView::InsertItem( Item newItem, float durationSeconds ) moveMe = temp; iter->second.RemoveConstraints(); - ApplyConstraints( iter->second, *mActiveLayout, iter->first, durationSeconds ); + mActiveLayout->ApplyConstraints(iter->second, iter->first, durationSeconds, mScrollPositionObject, Self() ); } // Create last item @@ -780,7 +708,7 @@ void ItemView::InsertItem( Item newItem, float durationSeconds ) mItemPool.insert( lastItem ); lastItem.second.RemoveConstraints(); - ApplyConstraints( lastItem.second, *mActiveLayout, lastItem.first, durationSeconds ); + mActiveLayout->ApplyConstraints(lastItem.second, lastItem.first, durationSeconds, mScrollPositionObject, Self() ); } else { @@ -797,18 +725,16 @@ void ItemView::InsertItems( const ItemContainer& newItems, float durationSeconds mAddingItems = true; // Insert from lowest id to highest - set sortedItems; + std::set sortedItems; for( ConstItemIter iter = newItems.begin(); newItems.end() != iter; ++iter ) { sortedItems.insert( *iter ); } - for( set::iterator iter = sortedItems.begin(); sortedItems.end() != iter; ++iter ) + for( std::set::iterator iter = sortedItems.begin(); sortedItems.end() != iter; ++iter ) { Self().Add( iter->second ); - cout << "inserting item: " << iter->first << endl; - ItemPoolIter foundIter = mItemPool.find( iter->first ); if( mItemPool.end() != foundIter ) { @@ -845,7 +771,7 @@ void ItemView::InsertItems( const ItemContainer& newItems, float durationSeconds else { iter->second.RemoveConstraints(); - ApplyConstraints( iter->second, *mActiveLayout, iter->first, durationSeconds ); + mActiveLayout->ApplyConstraints( iter->second, iter->first, durationSeconds, mScrollPositionObject, Self() ); } } @@ -896,7 +822,8 @@ bool ItemView::RemoveActor(unsigned int itemId) if( removeIter != mItemPool.end() ) { - Self().Remove( removeIter->second ); + ReleaseActor(itemId, removeIter->second); + removed = true; // Adjust the remaining item IDs, for example if item 2 is removed: @@ -932,7 +859,7 @@ void ItemView::ReplaceItem( Item replacementItem, float durationSeconds ) const ItemPoolIter iter = mItemPool.find( replacementItem.first ); if( mItemPool.end() != iter ) { - Self().Remove( iter->second ); + ReleaseActor(iter->first, iter->second); iter->second = replacementItem.second; } else @@ -962,7 +889,7 @@ void ItemView::RemoveActorsOutsideRange( ItemRange range ) if( ! range.Within( current ) ) { - Self().Remove( iter->second ); + ReleaseActor(iter->first, iter->second); mItemPool.erase( iter++ ); // erase invalidates the return value of post-increment; iter remains valid } @@ -975,7 +902,7 @@ void ItemView::RemoveActorsOutsideRange( ItemRange range ) void ItemView::AddActorsWithinRange( ItemRange range, float durationSeconds ) { - range.end = min(mItemFactory.GetNumberOfItems(), range.end); + range.end = std::min(mItemFactory.GetNumberOfItems(), range.end); // The order of addition depends on the scroll direction. if (mRefreshOrderHint) @@ -1033,10 +960,16 @@ void ItemView::SetupActor( Item item, float durationSeconds ) item.second.SetSize( size ); } - ApplyConstraints( item.second, *mActiveLayout, item.first, durationSeconds ); + mActiveLayout->ApplyConstraints( item.second, item.first, durationSeconds, mScrollPositionObject, Self() ); } } +void ItemView::ReleaseActor( ItemId item, Actor actor ) +{ + Self().Remove( actor ); + mItemFactory.ItemReleased(item, actor); +} + ItemRange ItemView::GetItemRange(ItemLayout& layout, const Vector3& layoutSize, float layoutPosition, bool reserveExtra) { unsigned int itemCount = mItemFactory.GetNumberOfItems(); @@ -1090,7 +1023,10 @@ bool ItemView::OnTouchEvent(const TouchEvent& event) mScrollOvershoot = 0.0f; AnimateScrollOvershoot(0.0f); - mScrollCompletedSignalV2.Emit(GetCurrentScrollPosition()); + if(mScrollAnimation) + { + mScrollCompletedSignalV2.Emit(GetCurrentScrollPosition()); + } RemoveAnimation(mScrollAnimation); } @@ -1111,6 +1047,7 @@ bool ItemView::OnMouseWheelEvent(const MouseWheelEvent& event) mScrollPositionObject.SetProperty( ScrollConnector::SCROLL_POSITION, firstItemScrollPosition ); self.SetProperty(mPropertyPosition, GetScrollPosition(firstItemScrollPosition, layoutSize)); mScrollStartedSignalV2.Emit(GetCurrentScrollPosition()); + mRefreshEnabled = true; } if (mMouseWheelEventFinishedTimer.IsRunning()) @@ -1148,97 +1085,6 @@ bool ItemView::OnMouseWheelEventFinished() return false; } -void ItemView::ApplyConstraints(Actor& actor, ItemLayout& layout, unsigned int itemId, float duration) -{ - ItemLayout::Vector3Function positionConstraint; - if (layout.GetPositionConstraint(itemId, positionConstraint)) - { - WrappedVector3Constraint wrapped(positionConstraint, itemId); - - Constraint constraint = Constraint::New( Actor::POSITION, - Source( mScrollPositionObject, ScrollConnector::SCROLL_POSITION ), - ParentSource( mPropertyScrollSpeed ), - ParentSource( Actor::SIZE ), - wrapped ); - constraint.SetApplyTime(duration); - constraint.SetAlphaFunction(mDefaultAlphaFunction); - - actor.ApplyConstraint(constraint); - } - - ItemLayout::QuaternionFunction rotationConstraint; - if (layout.GetRotationConstraint(itemId, rotationConstraint)) - { - WrappedQuaternionConstraint wrapped(rotationConstraint, itemId); - - Constraint constraint = Constraint::New( Actor::ROTATION, - Source( mScrollPositionObject, ScrollConnector::SCROLL_POSITION ), - ParentSource( mPropertyScrollSpeed ), - ParentSource( Actor::SIZE ), - wrapped ); - constraint.SetApplyTime(duration); - constraint.SetAlphaFunction(mDefaultAlphaFunction); - - actor.ApplyConstraint(constraint); - } - - ItemLayout::Vector3Function scaleConstraint; - if (layout.GetScaleConstraint(itemId, scaleConstraint)) - { - WrappedVector3Constraint wrapped(scaleConstraint, itemId); - - Constraint constraint = Constraint::New( Actor::SCALE, - Source( mScrollPositionObject, ScrollConnector::SCROLL_POSITION ), - ParentSource( mPropertyScrollSpeed ), - ParentSource( Actor::SIZE ), - wrapped ); - constraint.SetApplyTime(duration); - constraint.SetAlphaFunction(mDefaultAlphaFunction); - - actor.ApplyConstraint(constraint); - } - - ItemLayout::Vector4Function colorConstraint; - if (layout.GetColorConstraint(itemId, colorConstraint)) - { - WrappedVector4Constraint wrapped(colorConstraint, itemId); - - Constraint constraint = Constraint::New( Actor::COLOR, - Source( mScrollPositionObject, ScrollConnector::SCROLL_POSITION ), - ParentSource( mPropertyScrollSpeed ), - ParentSource( Actor::SIZE ), - wrapped ); - constraint.SetApplyTime(duration); - constraint.SetAlphaFunction(mDefaultAlphaFunction); - - // Release color constraints slowly; this allows ItemView to co-exist with ImageActor fade-in - constraint.SetRemoveTime(DEFAULT_COLOR_VISIBILITY_REMOVE_TIME); - constraint.SetRemoveAction(Dali::Constraint::Discard); - - actor.ApplyConstraint(constraint); - } - - ItemLayout::BoolFunction visibilityConstraint; - if (layout.GetVisibilityConstraint(itemId, visibilityConstraint)) - { - WrappedBoolConstraint wrapped(visibilityConstraint, itemId); - - Constraint constraint = Constraint::New( Actor::VISIBLE, - Source( mScrollPositionObject, ScrollConnector::SCROLL_POSITION ), - ParentSource( mPropertyScrollSpeed ), - ParentSource( Actor::SIZE ), - wrapped ); - constraint.SetApplyTime(duration); - constraint.SetAlphaFunction(mDefaultAlphaFunction); - - // Release visibility constraints the same time as the color constraint - constraint.SetRemoveTime(DEFAULT_COLOR_VISIBILITY_REMOVE_TIME); - constraint.SetRemoveAction(Dali::Constraint::Discard); - - actor.ApplyConstraint(constraint); - } -} - void ItemView::ReapplyAllConstraints( float durationSeconds ) { for (ConstItemPoolIter iter = mItemPool.begin(); iter != mItemPool.end(); ++iter) @@ -1247,7 +1093,7 @@ void ItemView::ReapplyAllConstraints( float durationSeconds ) Actor actor = iter->second; actor.RemoveConstraints(); - ApplyConstraints(actor, *mActiveLayout, id, durationSeconds); + mActiveLayout->ApplyConstraints(actor, id, durationSeconds, mScrollPositionObject, Self()); } CalculateDomainSize(Self().GetCurrentSize()); @@ -1257,7 +1103,7 @@ float ItemView::ClampFirstItemPosition(float targetPosition, const Vector3& targ { Actor self = Self(); float minLayoutPosition = layout.GetMinimumLayoutPosition(mItemFactory.GetNumberOfItems(), targetSize); - float clamppedPosition = min(0.0f, max(minLayoutPosition, targetPosition)); + float clamppedPosition = std::min(0.0f, std::max(minLayoutPosition, targetPosition)); mScrollOvershoot = targetPosition - clamppedPosition; self.SetProperty(mPropertyMinimumLayoutPosition, minLayoutPosition); @@ -1304,7 +1150,9 @@ void ItemView::OnPan(PanGesture gesture) RemoveAnimation(mScrollAnimation); - float flickAnimationDuration = mActiveLayout->GetItemFlickAnimationDuration() * max(1.0f, fabsf(firstItemScrollPosition - GetCurrentLayoutPosition(0))); + float flickAnimationDuration = Clamp( mActiveLayout->GetItemFlickAnimationDuration() * std::max(1.0f, fabsf(firstItemScrollPosition - GetCurrentLayoutPosition(0))) + , DEFAULT_MINIMUM_SWIPE_DURATION, DEFAULT_MAXIMUM_SWIPE_DURATION); + mScrollAnimation = Animation::New(flickAnimationDuration); mScrollAnimation.AnimateTo( Property( mScrollPositionObject, ScrollConnector::SCROLL_POSITION ), firstItemScrollPosition, AlphaFunctions::EaseOut ); mScrollAnimation.AnimateTo( Property(self, mPropertyPosition), GetScrollPosition(firstItemScrollPosition, layoutSize), AlphaFunctions::EaseOut ); @@ -1337,12 +1185,14 @@ void ItemView::OnPan(PanGesture gesture) case Gesture::Started: // Fall through { mTotalPanDisplacement = Vector2::ZERO; + mScrollStartedSignalV2.Emit(GetCurrentScrollPosition()); + mRefreshEnabled = true; } case Gesture::Continuing: { mScrollDistance = CalculateScrollDistance(gesture.displacement, *mActiveLayout); - mScrollSpeed = Clamp((gesture.GetSpeed() * mActiveLayout->GetScrollSpeedFactor() * MILLISECONDS_PER_SECONDS), 0.0f, mActiveLayout->GetMaximumSwipeSpeed()); + mScrollSpeed = Clamp((gesture.GetSpeed() * gesture.GetSpeed() * mActiveLayout->GetFlickSpeedFactor() * MILLISECONDS_PER_SECONDS), 0.0f, mActiveLayout->GetMaximumSwipeSpeed()); // Refresh order depends on the direction of the scroll; negative is towards the last item. mRefreshOrderHint = mScrollDistance < 0.0f; @@ -1353,7 +1203,6 @@ void ItemView::OnPan(PanGesture gesture) mScrollPositionObject.SetProperty( ScrollConnector::SCROLL_POSITION, firstItemScrollPosition ); self.SetProperty(mPropertyPosition, GetScrollPosition(firstItemScrollPosition, layoutSize)); - mScrollStartedSignalV2.Emit(GetCurrentScrollPosition()); mTotalPanDisplacement += gesture.displacement; mScrollOvershoot = layoutPositionDelta - firstItemScrollPosition; @@ -1438,12 +1287,6 @@ void ItemView::OnKeyboardFocusChangeCommitted(Actor commitedFocusableActor) int nextItemID = GetItemId(commitedFocusableActor); float layoutPosition = GetCurrentLayoutPosition(0); Vector3 layoutSize = Self().GetCurrentSize(); - Vector3 focusItemPosition = Vector3::ZERO; - ItemLayout::Vector3Function itemPositionConstraint; - if (mActiveLayout->GetPositionConstraint(nextItemID, itemPositionConstraint)) - { - focusItemPosition = itemPositionConstraint(Vector3::ZERO, layoutPosition + nextItemID, 0.0f, layoutSize); - } float scrollTo = mActiveLayout->GetClosestOnScreenLayoutPosition(nextItemID, layoutPosition, layoutSize); ScrollTo(Vector3(0.0f, scrollTo, 0.0f), DEFAULT_KEYBOARD_FOCUS_SCROLL_DURATION); @@ -1494,6 +1337,13 @@ void ItemView::OnScrollFinished(Animation& source) mScrollOvershoot = 0.0f; } +void ItemView::OnLayoutActivationScrollFinished(Animation& source) +{ + RemoveAnimation(mScrollAnimation); + mRefreshEnabled = true; + DoRefresh(GetCurrentLayoutPosition(0), true); +} + void ItemView::OnOvershootOnFinished(Animation& animation) { mAnimatingOvershootOn = false; @@ -1527,6 +1377,7 @@ void ItemView::ScrollToItem(unsigned int itemId, float durationSeconds) } mScrollStartedSignalV2.Emit(GetCurrentScrollPosition()); + mRefreshEnabled = true; } void ItemView::RemoveAnimation(Animation& animation) @@ -1548,20 +1399,11 @@ void ItemView::CalculateDomainSize(const Vector3& layoutSize) if(mActiveLayout) { - ItemLayout::Vector3Function firstItemPositionConstraint; - if (mActiveLayout->GetPositionConstraint(0, firstItemPositionConstraint)) - { - firstItemPosition = firstItemPositionConstraint(Vector3::ZERO, 0, 0.0f, layoutSize); - } + firstItemPosition = mActiveLayout->GetItemPosition( 0,0,layoutSize ); float minLayoutPosition = mActiveLayout->GetMinimumLayoutPosition(mItemFactory.GetNumberOfItems(), layoutSize); self.SetProperty(mPropertyMinimumLayoutPosition, minLayoutPosition); - - ItemLayout::Vector3Function lastItemPositionConstraint; - if (mActiveLayout->GetPositionConstraint(fabs(minLayoutPosition), lastItemPositionConstraint)) - { - lastItemPosition = lastItemPositionConstraint(Vector3::ZERO, fabs(minLayoutPosition), 0.0f, layoutSize); - } + lastItemPosition = mActiveLayout->GetItemPosition( fabs(minLayoutPosition),fabs(minLayoutPosition),layoutSize ); float domainSize; @@ -1609,13 +1451,7 @@ bool ItemView::IsLayoutScrollable(const Vector3& layoutSize) float ItemView::GetScrollPosition(float layoutPosition, const Vector3& layoutSize) const { - Vector3 firstItemPosition(Vector3::ZERO); - ItemLayout::Vector3Function firstItemPositionConstraint; - if (mActiveLayout->GetPositionConstraint(0, firstItemPositionConstraint)) - { - firstItemPosition = firstItemPositionConstraint(Vector3::ZERO, layoutPosition, 0.0f, layoutSize); - } - + Vector3 firstItemPosition( mActiveLayout->GetItemPosition(0, layoutPosition, layoutSize ) ); return IsHorizontal(mActiveLayout->GetOrientation()) ? firstItemPosition.x: firstItemPosition.y; } @@ -1658,6 +1494,16 @@ void ItemView::ScrollTo(const Vector3& position, float duration) } mScrollStartedSignalV2.Emit(GetCurrentScrollPosition()); + mRefreshEnabled = true; +} + +void ItemView::SetOvershootEffectColor( const Vector4& color ) +{ + mOvershootEffectColor = color; + if( mOvershootOverlay ) + { + mOvershootOverlay.SetColor( color ); + } } void ItemView::SetOvershootEnabled( bool enable ) @@ -1665,20 +1511,21 @@ void ItemView::SetOvershootEnabled( bool enable ) Actor self = Self(); if( enable ) { - mOvershootEffect = BouncingEffect::New(Scrollable::DEFAULT_OVERSHOOT_COLOUR); - mOvershootOverlay = CreateSolidColorActor(Vector4::ONE); + Property::Index effectOvershootPropertyIndex = Property::INVALID_INDEX; + mOvershootOverlay = CreateBouncingEffectActor( effectOvershootPropertyIndex ); + mOvershootOverlay.SetColor(mOvershootEffectColor); mOvershootOverlay.SetParentOrigin(ParentOrigin::TOP_LEFT); mOvershootOverlay.SetAnchorPoint(AnchorPoint::TOP_LEFT); mOvershootOverlay.SetDrawMode(DrawMode::OVERLAY); - mOvershootOverlay.SetShaderEffect(mOvershootEffect); self.Add(mOvershootOverlay); - Constraint constraint = Constraint::New( Actor::SIZE_WIDTH, + + Constraint constraint = Constraint::New( Actor::SIZE, ParentSource( mPropertyScrollDirection ), Source( mScrollPositionObject, ScrollConnector::OVERSHOOT ), ParentSource( Actor::SIZE ), OvershootOverlaySizeConstraint() ); mOvershootOverlay.ApplyConstraint(constraint); - mOvershootOverlay.SetSize(OVERSHOOT_BOUNCE_IMAGE_1_PIXEL_AREA.width, OVERSHOOT_BOUNCE_IMAGE_1_PIXEL_AREA.height); + mOvershootOverlay.SetSize(OVERSHOOT_BOUNCE_ACTOR_DEFAULT_SIZE.width, OVERSHOOT_BOUNCE_ACTOR_DEFAULT_SIZE.height); constraint = Constraint::New( Actor::ROTATION, ParentSource( mPropertyScrollDirection ), @@ -1698,12 +1545,11 @@ void ItemView::SetOvershootEnabled( bool enable ) OvershootOverlayVisibilityConstraint() ); mOvershootOverlay.ApplyConstraint(constraint); - int effectOvershootPropertyIndex = mOvershootEffect.GetPropertyIndex(mOvershootEffect.GetProgressRatePropertyName()); Actor self = Self(); constraint = Constraint::New( effectOvershootPropertyIndex, Source( mScrollPositionObject, ScrollConnector::OVERSHOOT ), EqualToConstraint() ); - mOvershootEffect.ApplyConstraint(constraint); + mOvershootOverlay.ApplyConstraint(constraint); } else { @@ -1712,7 +1558,6 @@ void ItemView::SetOvershootEnabled( bool enable ) self.Remove(mOvershootOverlay); mOvershootOverlay.Reset(); } - mOvershootEffect.Reset(); } } @@ -1729,7 +1574,7 @@ float ItemView::CalculateScrollOvershoot() float positionDelta = GetCurrentLayoutPosition(0) + scrollDistance; float minLayoutPosition = mActiveLayout->GetMinimumLayoutPosition(mItemFactory.GetNumberOfItems(), Self().GetCurrentSize()); self.SetProperty(mPropertyMinimumLayoutPosition, minLayoutPosition); - float clamppedPosition = min(0.0f, max(minLayoutPosition, positionDelta)); + float clamppedPosition = std::min(0.0f, std::max(minLayoutPosition, positionDelta)); overshoot = positionDelta - clamppedPosition; } @@ -1796,6 +1641,21 @@ Vector3 ItemView::GetItemsAnchorPoint() const return mItemsAnchorPoint; } +void ItemView::GetItemsRange(ItemRange& range) +{ + range.begin = mItemPool.begin()->first; + range.end = mItemPool.rbegin()->first + 1; +} + +void ItemView::OnScrollPositionChanged( float position ) +{ + // Cancel scroll animation to prevent any fighting of setting the scroll position property. + RemoveAnimation(mScrollAnimation); + + // Refresh the cache immediately when the scroll position is changed. + DoRefresh(position, false); // No need to cache extra items. +} + } // namespace Internal } // namespace Toolkit