[problem] When ItemView is still scrolling, touch and drag the fast scroll bar,
the fast scroll bar is not responsive for some time and ItemView scrolls
to the wrong position sometimes.
[cause] When scroll position property is being animated by ItemView, if something
else (e.g. ScrollBar) tries to modify the scroll position property at the
same time, there is a fighting of setting the same property between the two.
[solution] Cancel scroll animation when it is in fast scroll mode.
Change-Id: I3de03d7b21b929fe527b907e58464896b774c489
Signed-off-by: Adeel Kazmi <adeel.kazmi@samsung.com>
void ScrollBar::OnScrollPositionNotified(PropertyNotification& source)
{
// Emit the signal to notify the scroll position crossing
- mScrollPositionNotifiedSignal.Emit(mScrollPositionObject.GetProperty<float>( Toolkit::ScrollConnector::SCROLL_POSITION ));
+ mScrollPositionNotifiedSignal.Emit(mScrollConnector.GetScrollPosition());
}
void ScrollBar::Show()
bool ScrollBar::OnPanGestureProcessTick()
{
// Update the scroll position property.
- mScrollPositionObject.SetProperty( Toolkit::ScrollConnector::SCROLL_POSITION, mCurrentScrollPosition );
-
- Dali::Toolkit::ItemView itemView = Dali::Toolkit::ItemView::DownCast(Self().GetParent());
- if(itemView)
+ if( mScrollConnector )
{
- // Refresh ItemView immediately when the scroll position is changed.
- GetImpl(itemView).DoRefresh(mCurrentScrollPosition, false); // No need to cache extra items.
+ mScrollConnector.SetScrollPosition(mCurrentScrollPosition);
}
return true;
void ScrollBar::OnPan( PanGesture gesture )
{
- if(mScrollPositionObject)
+ if(mScrollConnector)
{
+ Dali::Toolkit::ItemView itemView = Dali::Toolkit::ItemView::DownCast(Self().GetParent());
+
switch(gesture.state)
{
case Gesture::Started:
}
Show();
- mScrollStart = mScrollPositionObject.GetProperty<float>( Toolkit::ScrollConnector::SCROLL_POSITION );
+ mScrollStart = mScrollConnector.GetScrollPosition();
mGestureDisplacement = Vector3::ZERO;
mIsPanning = true;
mTimer.Reset();
}
+ if(itemView)
+ {
+ // Refresh the ItemView cache with extra items
+ GetImpl(itemView).DoRefresh(mCurrentScrollPosition, true);
+ }
+
break;
}
}
- Dali::Toolkit::ItemView itemView = Dali::Toolkit::ItemView::DownCast(Self().GetParent());
if(itemView)
{
// Disable automatic refresh in ItemView during fast scrolling
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);
float ItemView::GetCurrentLayoutPosition(unsigned int itemId) const
{
- return mScrollPositionObject.GetProperty<float>( ScrollConnector::SCROLL_POSITION ) + static_cast<float>( itemId );
+ return mScrollConnector.GetScrollPosition() + static_cast<float>( itemId );
}
void ItemView::ActivateLayout(unsigned int layoutIndex, const Vector3& targetSize, float durationSeconds)
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
*/
void OnRefreshNotification(PropertyNotification& source);
+ /**
+ * This is called when scroll position has been changed by ScrollConnector::SetScrollPosition.
+ * @param[in] position The new scroll position
+ */
+ void OnScrollPositionChanged( float position );
+
private:
ItemFactory& mItemFactory;
mDomainChangedSignal.Emit( mMinLimit, mMaxLimit, mContentLength );
}
+void ScrollConnector::SetScrollPosition( float position )
+{
+ mScrollPositionObject.SetProperty( Toolkit::ScrollConnector::SCROLL_POSITION, position );
+ mScrollPositionChangedSignal.Emit( position );
+}
+
ScrollConnector::ScrollConnector()
: mMinLimit( 0.0f ),
mMaxLimit( 0.0f ),
public:
typedef Toolkit::ScrollConnector::DomainChangedSignalType DomainChangedSignalType;
+ typedef Toolkit::ScrollConnector::ScrollPositionChangedSignalType ScrollPositionChangedSignalType;
static const Property::Index SCROLL_POSITION;
static const Property::Index OVERSHOOT;
return mContentLength;
}
+ /**
+ * @copydoc Toolkit::ScrollConnector::SetScrollPosition()
+ */
+ void SetScrollPosition( float position );
+
+ /**
+ * @copydoc Toolkit::ScrollConnector::GetScrollPosition()
+ */
+ float GetScrollPosition() const
+ {
+ return mScrollPositionObject.GetProperty<float>( Toolkit::ScrollConnector::SCROLL_POSITION );
+ }
+
+ /**
+ * Signal emitted after the SetScrollPosition() method has been called.
+ */
+ ScrollPositionChangedSignalType& ScrollPositionChangedSignal()
+ {
+ return mScrollPositionChangedSignal;
+ }
+
/**
* Signal emitted after the SetScrollDomain() method has been called.
*/
Constrainable mScrollPositionObject;
DomainChangedSignalType mDomainChangedSignal;
+ ScrollPositionChangedSignalType mScrollPositionChangedSignal;
float mMinLimit;
float mMaxLimit;
const Property::Index ScrollConnector::OVERSHOOT = Internal::ScrollConnector::OVERSHOOT;
const char* const ScrollConnector::DOMAIN_CHANGED_SIGNAL_NAME = "domain-changed";
+const char* const ScrollConnector::SCROLL_POSITION_CHANGED_SIGNAL_NAME = "scroll-position-changed";
ScrollConnector ScrollConnector::New()
{
return GetImpl(*this).GetScrollPositionObject();
}
+void ScrollConnector::SetScrollPosition( float position )
+{
+ GetImpl(*this).SetScrollPosition( position );
+}
+
+float ScrollConnector::GetScrollPosition() const
+{
+ return GetImpl(*this).GetScrollPosition();
+}
+
+ScrollConnector::ScrollPositionChangedSignalType& ScrollConnector::ScrollPositionChangedSignal()
+{
+ return GetImpl(*this).ScrollPositionChangedSignal();
+}
+
ScrollConnector::DomainChangedSignalType& ScrollConnector::DomainChangedSignal()
{
return GetImpl(*this).DomainChangedSignal();
static const char* const DOMAIN_CHANGED_SIGNAL_NAME; ///< "domain-changed" signal name
typedef SignalV2< void ( float min, float max, float size ) > DomainChangedSignalType;
+ static const char* const SCROLL_POSITION_CHANGED_SIGNAL_NAME; ///< "scroll-position-changed" signal name
+ typedef SignalV2< void ( float position ) > ScrollPositionChangedSignalType;
+
/**
* Create a ScrollConnector.
* @return A handle to a newly allocated ScrollConnector.
~ScrollConnector();
/**
- * Downcast a BaseHandle to ScrollConnector handle.
+ * @brief Downcast a BaseHandle to ScrollConnector handle.
* @return A handle to a ScrollConnector or an empty handle.
*/
static ScrollConnector DownCast( BaseHandle handle );
/**
- * Set the scroll domain, corresponding to the start & end position, and size of the scrollable content in actor coordinates.
+ * @brief Set the scroll domain, corresponding to the start & end position, and size of the scrollable content in actor coordinates.
* @param[in] min The minimum scroll position limit.
* @param[in] max The maximum scroll position limit.
* @param[in] length The length of the scrollable content in actor coordinates.
void SetScrollDomain( float min, float max, float length );
/**
- * Retrieve the min limit.
+ * @brief Retrieve the min limit.
* @return The minimum value.
*/
float GetMinLimit() const;
/**
- * Retrieve the max limit.
+ * @brief Retrieve the max limit.
* @return The maximum value.
*/
float GetMaxLimit() const;
/**
- * Retrieve the length of the scrollable content in actor coordinates.
+ * @brief Retrieve the length of the scrollable content in actor coordinates.
* @return The length of the scrollable content.
*/
float GetContentLength() const;
/**
- * Signal emitted after the SetScrollDomain() method has been called.
+ * @brief Set the scroll position.
+ *
+ * This will set the "scroll-position" property and emit the ScrollPositionChanged signal.
+ *
+ * @param[in] position The scroll position.
+ */
+ void SetScrollPosition( float position );
+
+ /**
+ * @brief Retrieve the scroll position.
+ * @return The scroll position.
+ */
+ float GetScrollPosition() const;
+
+ /**
+ * @brief Signal emitted after the SetScrollPosition() method has been called.
+ */
+ ScrollConnector::ScrollPositionChangedSignalType& ScrollPositionChangedSignal();
+
+ /**
+ * @brief Signal emitted after the SetScrollDomain() method has been called.
*/
ScrollConnector::DomainChangedSignalType& DomainChangedSignal();
/**
- * Retrieve the object which provides the "scroll-position" property.
+ * @brief Retrieve the object which provides the "scroll-position" property.
* @return The scroll-position object.
*/
Constrainable GetScrollPositionObject() const;