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=6d4d4b8ab9e50dfe0a6c7116b0c7a66f51378537;hp=0011dff7db2ef47038563df0c5f55c0503b40548;hb=421b1cb023ab3a51842d1c7dab553e241c2301d0;hpb=2359f074da61124b708a31212133c8e06fe2689b 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 0011dff..6d4d4b8 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 @@ -59,8 +59,6 @@ const float MILLISECONDS_PER_SECONDS = 1000.0f; 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 const float DEFAULT_KEYBOARD_FOCUS_SCROLL_DURATION = 0.2f; const string LAYOUT_POSITION_PROPERTY_NAME( "item-view-layout-position" ); @@ -337,6 +335,7 @@ ItemView::ItemView(ItemFactory& factory) mRefreshOrderHint(true/*Refresh item 0 first*/), mMinimumSwipeSpeed(DEFAULT_MINIMUM_SWIPE_SPEED), mMinimumSwipeDistance(DEFAULT_MINIMUM_SWIPE_DISTANCE), + mMouseWheelScrollDistanceStep(0.0f), mScrollDistance(0.0f), mScrollSpeed(0.0f), mTotalPanDisplacement(Vector2::ZERO), @@ -344,6 +343,9 @@ ItemView::ItemView(ItemFactory& factory) mIsFlicking(false), mGestureState(Gesture::Clear), mAddingItems(false), + mPropertyPosition(Property::INVALID_INDEX), + mPropertyMinimumLayoutPosition(Property::INVALID_INDEX), + mPropertyScrollSpeed(Property::INVALID_INDEX), mRefreshEnabled(true), mItemsParentOrigin( ParentOrigin::CENTER), mItemsAnchorPoint( AnchorPoint::CENTER) @@ -626,7 +628,7 @@ float ItemView::GetAnchoringDuration() const void ItemView::SetRefreshInterval(float intervalLayoutPositions) { - if(mRefreshIntervalLayoutPositions != intervalLayoutPositions) + if( !Equals(mRefreshIntervalLayoutPositions, intervalLayoutPositions) ) { mRefreshIntervalLayoutPositions = intervalLayoutPositions; @@ -682,37 +684,58 @@ void ItemView::InsertItem( Item newItem, float durationSeconds ) { mAddingItems = true; - SetupActor( newItem, durationSeconds ); - Self().Add( newItem.second ); + Actor displacedActor; + ItemPoolIter afterDisplacedIter = mItemPool.end(); ItemPoolIter foundIter = mItemPool.find( newItem.first ); if( mItemPool.end() != foundIter ) { - Actor moveMe = foundIter->second; + SetupActor( newItem, durationSeconds ); + Self().Add( newItem.second ); + + displacedActor = foundIter->second; foundIter->second = newItem.second; + afterDisplacedIter = ++foundIter; + } + else + { + // Inserting before the existing item range? + ItemPoolIter iter = mItemPool.begin(); + if( iter != mItemPool.end() && + iter->first > newItem.first ) + { + displacedActor = iter->second; + mItemPool.erase( iter++ ); // iter is still valid after the erase + + afterDisplacedIter = iter; + } + } + + if( displacedActor ) + { // Move the existing actors to make room - for( ItemPoolIter iter = ++foundIter; mItemPool.end() != iter; ++iter ) + for( ItemPoolIter iter = afterDisplacedIter; mItemPool.end() != iter; ++iter ) { Actor temp = iter->second; - iter->second = moveMe; - moveMe = temp; + iter->second = displacedActor; + displacedActor = temp; iter->second.RemoveConstraints(); - mActiveLayout->ApplyConstraints(iter->second, iter->first, durationSeconds, mScrollPositionObject, Self() ); + mActiveLayout->ApplyConstraints( iter->second, iter->first, durationSeconds, mScrollPositionObject, Self() ); } // Create last item - ItemId lastId = mItemPool.rbegin()->first; - Item lastItem( lastId + 1, moveMe ); - mItemPool.insert( lastItem ); + ItemPool::reverse_iterator lastIter = mItemPool.rbegin(); + if ( lastIter != mItemPool.rend() ) + { + ItemId lastId = lastIter->first; + Item lastItem( lastId + 1, displacedActor ); + mItemPool.insert( lastItem ); - lastItem.second.RemoveConstraints(); - mActiveLayout->ApplyConstraints(lastItem.second, lastItem.first, durationSeconds, mScrollPositionObject, Self() ); - } - else - { - mItemPool.insert( newItem ); + lastItem.second.RemoveConstraints(); + mActiveLayout->ApplyConstraints( lastItem.second, lastItem.first, durationSeconds, mScrollPositionObject, Self() ); + } } CalculateDomainSize(Self().GetCurrentSize()); @@ -782,16 +805,18 @@ void ItemView::InsertItems( const ItemContainer& newItems, float durationSeconds void ItemView::RemoveItem( unsigned int itemId, float durationSeconds ) { - bool actorRemoved = RemoveActor( itemId ); - if( actorRemoved ) + bool actorsReordered = RemoveActor( itemId ); + if( actorsReordered ) { ReapplyAllConstraints( durationSeconds ); + + OnItemsRemoved(); } } void ItemView::RemoveItems( const ItemIdContainer& itemIds, float durationSeconds ) { - bool actorRemoved( false ); + bool actorsReordered( false ); // Remove from highest id to lowest set sortedItems; @@ -804,27 +829,44 @@ void ItemView::RemoveItems( const ItemIdContainer& itemIds, float durationSecond { if( RemoveActor( *iter ) ) { - actorRemoved = true; + actorsReordered = true; } } - if( actorRemoved ) + if( actorsReordered ) { ReapplyAllConstraints( durationSeconds ); + + OnItemsRemoved(); } } bool ItemView::RemoveActor(unsigned int itemId) { - bool removed( false ); - - const ItemPoolIter removeIter = mItemPool.find( itemId ); + bool reordered( false ); + ItemPoolIter removeIter = mItemPool.find( itemId ); if( removeIter != mItemPool.end() ) { ReleaseActor(itemId, removeIter->second); + } + else + { + // Removing before the existing item range? + ItemPoolIter iter = mItemPool.begin(); + if( iter != mItemPool.end() && + iter->first > itemId ) + { + // In order to decrement the first visible item ID + mItemPool.insert( Item(iter->first - 1, Actor()) ); - removed = true; + removeIter = mItemPool.begin(); + } + } + + if( removeIter != mItemPool.end() ) + { + reordered = true; // Adjust the remaining item IDs, for example if item 2 is removed: // Initial actors: After insert: @@ -846,7 +888,7 @@ bool ItemView::RemoveActor(unsigned int itemId) } } - return removed; + return reordered; } void ItemView::ReplaceItem( Item replacementItem, float durationSeconds ) @@ -1095,8 +1137,19 @@ void ItemView::ReapplyAllConstraints( float durationSeconds ) actor.RemoveConstraints(); mActiveLayout->ApplyConstraints(actor, id, durationSeconds, mScrollPositionObject, Self()); } +} +void ItemView::OnItemsRemoved() +{ CalculateDomainSize(Self().GetCurrentSize()); + + // Adjust scroll-position after an item is removed + if( mActiveLayout ) + { + float firstItemScrollPosition = ClampFirstItemPosition(GetCurrentLayoutPosition(0), Self().GetCurrentSize(), *mActiveLayout); + + mScrollPositionObject.SetProperty( ScrollConnector::SCROLL_POSITION, firstItemScrollPosition ); + } } float ItemView::ClampFirstItemPosition(float targetPosition, const Vector3& targetSize, ItemLayout& layout) @@ -1110,7 +1163,7 @@ float ItemView::ClampFirstItemPosition(float targetPosition, const Vector3& targ return clamppedPosition; } -void ItemView::OnPan(PanGesture gesture) +void ItemView::OnPan( const PanGesture& gesture ) { Actor self = Self(); const Vector3 layoutSize = Self().GetCurrentSize(); @@ -1201,23 +1254,18 @@ void ItemView::OnPan(PanGesture gesture) float firstItemScrollPosition = ClampFirstItemPosition(layoutPositionDelta, layoutSize, *mActiveLayout); + float currentOvershoot = mScrollPositionObject.GetProperty(ScrollConnector::OVERSHOOT); + mScrollPositionObject.SetProperty( ScrollConnector::SCROLL_POSITION, firstItemScrollPosition ); self.SetProperty(mPropertyPosition, GetScrollPosition(firstItemScrollPosition, layoutSize)); - mTotalPanDisplacement += gesture.displacement; - mScrollOvershoot = layoutPositionDelta - firstItemScrollPosition; - if( mScrollOvershoot > Math::MACHINE_EPSILON_1 ) - { - AnimateScrollOvershoot(1.0f); - } - else if( mScrollOvershoot < -Math::MACHINE_EPSILON_1 ) - { - AnimateScrollOvershoot(-1.0f); - } - else + if( (firstItemScrollPosition >= 0.0f && currentOvershoot < 1.0f) || (firstItemScrollPosition <= mActiveLayout->GetMinimumLayoutPosition(mItemFactory.GetNumberOfItems(), layoutSize) && currentOvershoot > -1.0f) ) { - AnimateScrollOvershoot(0.0f); + mTotalPanDisplacement += gesture.displacement; } + + mScrollOvershoot = CalculateScrollOvershoot(); + mScrollPositionObject.SetProperty( ScrollConnector::OVERSHOOT, mScrollOvershoot ); } break; @@ -1545,7 +1593,6 @@ void ItemView::SetOvershootEnabled( bool enable ) OvershootOverlayVisibilityConstraint() ); mOvershootOverlay.ApplyConstraint(constraint); - Actor self = Self(); constraint = Constraint::New( effectOvershootPropertyIndex, Source( mScrollPositionObject, ScrollConnector::OVERSHOOT ), EqualToConstraint() ); @@ -1578,7 +1625,7 @@ float ItemView::CalculateScrollOvershoot() overshoot = positionDelta - clamppedPosition; } - return overshoot; + return overshoot > 0.0f ? std::min(overshoot, 1.0f) : std::max(overshoot, -1.0f); } void ItemView::AnimateScrollOvershoot(float overshootAmount, bool animateBack) @@ -1594,17 +1641,23 @@ void ItemView::AnimateScrollOvershoot(float overshootAmount, bool animateBack) return; } - Actor self = Self(); - float currentOvershoot = mScrollPositionObject.GetProperty(ScrollConnector::OVERSHOOT); - float duration = DEFAULT_OVERSHOOT_ANIMATION_DURATION * (animatingOn ? (1.0f - fabsf(currentOvershoot)) : fabsf(currentOvershoot)); + if(mOvershootAnimationSpeed > Math::MACHINE_EPSILON_0) + { + float currentOvershoot = mScrollPositionObject.GetProperty(ScrollConnector::OVERSHOOT); + float duration = mOvershootOverlay.GetCurrentSize().height * (animatingOn ? (1.0f - fabsf(currentOvershoot)) : fabsf(currentOvershoot)) / mOvershootAnimationSpeed; - RemoveAnimation(mScrollOvershootAnimation); - mScrollOvershootAnimation = Animation::New(duration); - mScrollOvershootAnimation.FinishedSignal().Connect(this, &ItemView::OnOvershootOnFinished); - mScrollOvershootAnimation.AnimateTo( Property(mScrollPositionObject, ScrollConnector::OVERSHOOT), overshootAmount, TimePeriod(0.0f, duration) ); - mScrollOvershootAnimation.Play(); + RemoveAnimation(mScrollOvershootAnimation); + mScrollOvershootAnimation = Animation::New(duration); + mScrollOvershootAnimation.FinishedSignal().Connect(this, &ItemView::OnOvershootOnFinished); + mScrollOvershootAnimation.AnimateTo( Property(mScrollPositionObject, ScrollConnector::OVERSHOOT), overshootAmount, TimePeriod(0.0f, duration) ); + mScrollOvershootAnimation.Play(); - mAnimatingOvershootOn = animatingOn; + mAnimatingOvershootOn = animatingOn; + } + else + { + mScrollPositionObject.SetProperty( ScrollConnector::OVERSHOOT, overshootAmount ); + } } void ItemView::SetItemsParentOrigin( const Vector3& parentOrigin ) @@ -1643,8 +1696,16 @@ Vector3 ItemView::GetItemsAnchorPoint() const void ItemView::GetItemsRange(ItemRange& range) { - range.begin = mItemPool.begin()->first; - range.end = mItemPool.rbegin()->first + 1; + if( !mItemPool.empty() ) + { + range.begin = mItemPool.begin()->first; + range.end = mItemPool.rbegin()->first + 1; + } + else + { + range.begin = 0; + range.end = 0; + } } void ItemView::OnScrollPositionChanged( float position )