Merge "Removed feedback controller Boost dependency" into devel/master
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / controls / scrollable / item-view / item-view-impl.cpp
index 68141c3..c70b792 100644 (file)
 #include <algorithm>
 #include <dali/public-api/animation/constraint.h>
 #include <dali/public-api/animation/constraints.h>
-#include <dali/public-api/common/set-wrapper.h>
+#include <dali/devel-api/common/set-wrapper.h>
 #include <dali/public-api/common/stage.h>
-#include <dali/public-api/events/mouse-wheel-event.h>
+#include <dali/public-api/events/wheel-event.h>
 #include <dali/public-api/events/touch-event.h>
 #include <dali/public-api/object/type-registry.h>
-#include <dali/public-api/object/type-registry-helper.h>
+#include <dali/devel-api/object/type-registry-helper.h>
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/public-api/controls/scroll-bar/scroll-bar.h>
@@ -53,17 +53,19 @@ DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, ItemView, "scroll-direction",
 DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, ItemView, "layout-orientation",  INTEGER,  LAYOUT_ORIENTATION)
 DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, ItemView, "scroll-content-size", FLOAT,    SCROLL_CONTENT_SIZE)
 
+DALI_SIGNAL_REGISTRATION(              Toolkit, ItemView, "layout-activated",    LAYOUT_ACTIVATED_SIGNAL )
+
 DALI_TYPE_REGISTRATION_END()
 
 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_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 int WHEEL_EVENT_FINISHED_TIME_OUT = 500;  // 0.5 second
 
 const float DEFAULT_ANCHORING_DURATION = 1.0f;  // 1 second
 
@@ -276,18 +278,18 @@ Dali::Toolkit::ItemView ItemView::New(ItemFactory& factory)
 }
 
 ItemView::ItemView(ItemFactory& factory)
-: Scrollable( ControlBehaviour( DISABLE_SIZE_NEGOTIATION | REQUIRES_MOUSE_WHEEL_EVENTS | REQUIRES_KEYBOARD_NAVIGATION_SUPPORT ) ),
+: Scrollable( ControlBehaviour( DISABLE_SIZE_NEGOTIATION | REQUIRES_WHEEL_EVENTS | REQUIRES_KEYBOARD_NAVIGATION_SUPPORT ) ),
   mItemFactory(factory),
   mActiveLayout(NULL),
   mAnimatingOvershootOn(false),
   mAnimateOvershootOff(false),
-  mAnchoringEnabled(true),
+  mAnchoringEnabled(false),
   mAnchoringDuration(DEFAULT_ANCHORING_DURATION),
   mRefreshIntervalLayoutPositions(0.0f),
   mRefreshOrderHint(true/*Refresh item 0 first*/),
   mMinimumSwipeSpeed(DEFAULT_MINIMUM_SWIPE_SPEED),
   mMinimumSwipeDistance(DEFAULT_MINIMUM_SWIPE_DISTANCE),
-  mMouseWheelScrollDistanceStep(0.0f),
+  mWheelScrollDistanceStep(0.0f),
   mScrollDistance(0.0f),
   mScrollSpeed(0.0f),
   mTotalPanDisplacement(Vector2::ZERO),
@@ -308,12 +310,12 @@ void ItemView::OnInitialize()
   SetOvershootEnabled(true);
 
   Vector2 stageSize = Stage::GetCurrent().GetSize();
-  mMouseWheelScrollDistanceStep = stageSize.y * DEFAULT_MOUSE_WHEEL_SCROLL_DISTANCE_STEP_PROPORTION;
+  mWheelScrollDistanceStep = stageSize.y * DEFAULT_WHEEL_SCROLL_DISTANCE_STEP_PROPORTION;
 
   EnableGestureDetection(Gesture::Type(Gesture::Pan));
 
-  mMouseWheelEventFinishedTimer = Timer::New( MOUSE_WHEEL_EVENT_FINISHED_TIME_OUT );
-  mMouseWheelEventFinishedTimer.TickSignal().Connect( this, &ItemView::OnMouseWheelEventFinished );
+  mWheelEventFinishedTimer = Timer::New( WHEEL_EVENT_FINISHED_TIME_OUT );
+  mWheelEventFinishedTimer.TickSignal().Connect( this, &ItemView::OnWheelEventFinished );
 
   SetRefreshInterval(DEFAULT_REFRESH_INTERVAL_LAYOUT_POSITIONS);
 }
@@ -385,18 +387,15 @@ void ItemView::ActivateLayout(unsigned int layoutIndex, const Vector3& targetSiz
     actor.RemoveConstraints();
 
     Vector3 size;
-    if(mActiveLayout->GetItemSize(itemId, targetSize, size))
-    {
-      // resize immediately
-      actor.SetSize( size.GetVectorXY() );
-    }
+    mActiveLayout->GetItemSize( itemId, targetSize, size );
+    actor.SetSize( size.GetVectorXY() );
 
-    mActiveLayout->ApplyConstraints(actor, itemId, durationSeconds, Self() );
+    mActiveLayout->ApplyConstraints(actor, itemId, targetSize, Self() );
   }
 
   // Refresh the new layout
   ItemRange range = GetItemRange(*mActiveLayout, targetSize, GetCurrentLayoutPosition(0), false/* don't reserve extra*/);
-  AddActorsWithinRange( range, durationSeconds );
+  AddActorsWithinRange( range, targetSize );
 
   // Scroll to an appropriate layout position
 
@@ -425,6 +424,11 @@ void ItemView::ActivateLayout(unsigned int layoutIndex, const Vector3& targetSiz
     mScrollAnimation.FinishedSignal().Connect(this, &ItemView::OnLayoutActivationScrollFinished);
     mScrollAnimation.Play();
   }
+  else
+  {
+    // Emit the layout activated signal
+    mLayoutActivatedSignal.Emit();
+  }
 
   AnimateScrollOvershoot(0.0f);
   mScrollOvershoot = 0.0f;
@@ -477,7 +481,7 @@ void ItemView::DoRefresh(float currentLayoutPosition, bool cacheExtra)
   {
     ItemRange range = GetItemRange(*mActiveLayout, mActiveLayoutTargetSize, currentLayoutPosition, cacheExtra/*reserve extra*/);
     RemoveActorsOutsideRange( range );
-    AddActorsWithinRange( range, 0.0f/*immediate*/ );
+    AddActorsWithinRange( range, Self().GetCurrentSize() );
 
     mScrollUpdatedSignal.Emit( Vector2(0.0f, currentLayoutPosition) );
   }
@@ -503,14 +507,14 @@ float ItemView::GetMinimumSwipeDistance() const
   return mMinimumSwipeDistance;
 }
 
-void ItemView::SetMouseWheelScrollDistanceStep(float step)
+void ItemView::SetWheelScrollDistanceStep(float step)
 {
-  mMouseWheelScrollDistanceStep = step;
+  mWheelScrollDistanceStep = step;
 }
 
-float ItemView::GetMouseWheelScrollDistanceStep() const
+float ItemView::GetWheelScrollDistanceStep() const
 {
-  return mMouseWheelScrollDistanceStep;
+  return mWheelScrollDistanceStep;
 }
 
 void ItemView::SetAnchoring(bool enabled)
@@ -591,6 +595,7 @@ unsigned int ItemView::GetItemId( Actor actor ) const
 void ItemView::InsertItem( Item newItem, float durationSeconds )
 {
   mAddingItems = true;
+  Vector3 layoutSize = Self().GetCurrentSize();
 
   Actor displacedActor;
   ItemPoolIter afterDisplacedIter = mItemPool.end();
@@ -598,7 +603,7 @@ void ItemView::InsertItem( Item newItem, float durationSeconds )
   ItemPoolIter foundIter = mItemPool.find( newItem.first );
   if( mItemPool.end() != foundIter )
   {
-    SetupActor( newItem, durationSeconds );
+    SetupActor( newItem, layoutSize );
     Self().Add( newItem.second );
 
     displacedActor = foundIter->second;
@@ -630,7 +635,7 @@ void ItemView::InsertItem( Item newItem, float durationSeconds )
       displacedActor = temp;
 
       iter->second.RemoveConstraints();
-      mActiveLayout->ApplyConstraints( iter->second, iter->first, durationSeconds, Self() );
+      mActiveLayout->ApplyConstraints( iter->second, iter->first, layoutSize, Self() );
     }
 
     // Create last item
@@ -642,11 +647,11 @@ void ItemView::InsertItem( Item newItem, float durationSeconds )
       mItemPool.insert( lastItem );
 
       lastItem.second.RemoveConstraints();
-      mActiveLayout->ApplyConstraints( lastItem.second, lastItem.first, durationSeconds, Self() );
+      mActiveLayout->ApplyConstraints( lastItem.second, lastItem.first, layoutSize, Self() );
     }
   }
 
-  CalculateDomainSize(Self().GetCurrentSize());
+  CalculateDomainSize( layoutSize );
 
   mAddingItems = false;
 }
@@ -654,6 +659,7 @@ void ItemView::InsertItem( Item newItem, float durationSeconds )
 void ItemView::InsertItems( const ItemContainer& newItems, float durationSeconds )
 {
   mAddingItems = true;
+  Vector3 layoutSize = Self().GetCurrentSize();
 
   // Insert from lowest id to highest
   std::set<Item> sortedItems;
@@ -697,16 +703,16 @@ void ItemView::InsertItems( const ItemContainer& newItems, float durationSeconds
     // If newly inserted
     if( FindById( newItems, iter->first ) )
     {
-      SetupActor( *iter, durationSeconds );
+      SetupActor( *iter, layoutSize );
     }
     else
     {
       iter->second.RemoveConstraints();
-      mActiveLayout->ApplyConstraints( iter->second, iter->first, durationSeconds, Self() );
+      mActiveLayout->ApplyConstraints( iter->second, iter->first, layoutSize, Self() );
     }
   }
 
-  CalculateDomainSize(Self().GetCurrentSize());
+  CalculateDomainSize( layoutSize );
 
   mAddingItems = false;
 }
@@ -716,7 +722,7 @@ void ItemView::RemoveItem( unsigned int itemId, float durationSeconds )
   bool actorsReordered = RemoveActor( itemId );
   if( actorsReordered )
   {
-    ReapplyAllConstraints( durationSeconds );
+    ReapplyAllConstraints();
 
     OnItemsRemoved();
   }
@@ -743,7 +749,7 @@ void ItemView::RemoveItems( const ItemIdContainer& itemIds, float durationSecond
 
   if( actorsReordered )
   {
-    ReapplyAllConstraints( durationSeconds );
+    ReapplyAllConstraints();
 
     OnItemsRemoved();
   }
@@ -802,8 +808,9 @@ bool ItemView::RemoveActor(unsigned int itemId)
 void ItemView::ReplaceItem( Item replacementItem, float durationSeconds )
 {
   mAddingItems = true;
+  Vector3 layoutSize = Self().GetCurrentSize();
 
-  SetupActor( replacementItem, durationSeconds );
+  SetupActor( replacementItem, layoutSize );
   Self().Add( replacementItem.second );
 
   const ItemPoolIter iter = mItemPool.find( replacementItem.first );
@@ -817,7 +824,7 @@ void ItemView::ReplaceItem( Item replacementItem, float durationSeconds )
     mItemPool.insert( replacementItem );
   }
 
-  CalculateDomainSize(Self().GetCurrentSize());
+  CalculateDomainSize( layoutSize );
 
   mAddingItems = false;
 }
@@ -850,7 +857,7 @@ void ItemView::RemoveActorsOutsideRange( ItemRange range )
   }
 }
 
-void ItemView::AddActorsWithinRange( ItemRange range, float durationSeconds )
+void ItemView::AddActorsWithinRange( ItemRange range, const Vector3& layoutSize )
 {
   range.end = std::min(mItemFactory.GetNumberOfItems(), range.end);
 
@@ -859,14 +866,14 @@ void ItemView::AddActorsWithinRange( ItemRange range, float durationSeconds )
   {
     for (unsigned int itemId = range.begin; itemId < range.end; ++itemId)
     {
-      AddNewActor( itemId, durationSeconds );
+      AddNewActor( itemId, layoutSize );
     }
   }
   else
   {
     for (unsigned int itemId = range.end; itemId > range.begin; --itemId)
     {
-      AddNewActor( itemId-1, durationSeconds );
+      AddNewActor( itemId-1, layoutSize );
     }
   }
 
@@ -875,7 +882,7 @@ void ItemView::AddActorsWithinRange( ItemRange range, float durationSeconds )
   CalculateDomainSize(Self().GetCurrentSize());
 }
 
-void ItemView::AddNewActor( unsigned int itemId, float durationSeconds )
+void ItemView::AddNewActor( unsigned int itemId, const Vector3& layoutSize )
 {
   mAddingItems = true;
 
@@ -889,7 +896,7 @@ void ItemView::AddNewActor( unsigned int itemId, float durationSeconds )
 
       mItemPool.insert( newItem );
 
-      SetupActor( newItem, durationSeconds );
+      SetupActor( newItem, layoutSize );
       Self().Add( actor );
     }
   }
@@ -897,7 +904,7 @@ void ItemView::AddNewActor( unsigned int itemId, float durationSeconds )
   mAddingItems = false;
 }
 
-void ItemView::SetupActor( Item item, float durationSeconds )
+void ItemView::SetupActor( Item item, const Vector3& layoutSize )
 {
   item.second.SetParentOrigin( mItemsParentOrigin );
   item.second.SetAnchorPoint( mItemsAnchorPoint );
@@ -905,12 +912,10 @@ void ItemView::SetupActor( Item item, float durationSeconds )
   if( mActiveLayout )
   {
     Vector3 size;
-    if( mActiveLayout->GetItemSize( item.first, mActiveLayoutTargetSize, size ) )
-    {
-      item.second.SetSize( size.GetVectorXY() );
-    }
+    mActiveLayout->GetItemSize( item.first, mActiveLayoutTargetSize, size );
+    item.second.SetSize( size.GetVectorXY() );
 
-    mActiveLayout->ApplyConstraints( item.second, item.first, durationSeconds, Self() );
+    mActiveLayout->ApplyConstraints( item.second, item.first, layoutSize, Self() );
   }
 }
 
@@ -988,14 +993,14 @@ bool ItemView::OnTouchEvent(const TouchEvent& event)
   return true; // consume since we're potentially scrolling
 }
 
-bool ItemView::OnMouseWheelEvent(const MouseWheelEvent& event)
+bool ItemView::OnWheelEvent(const WheelEvent& event)
 {
-  // Respond the mouse wheel event to scroll
+  // Respond the wheel event to scroll
   if (mActiveLayout)
   {
     Actor self = Self();
     const Vector3 layoutSize = Self().GetCurrentSize();
-    float layoutPositionDelta = GetCurrentLayoutPosition(0) - (event.z * mMouseWheelScrollDistanceStep * mActiveLayout->GetScrollSpeedFactor());
+    float layoutPositionDelta = GetCurrentLayoutPosition(0) - (event.z * mWheelScrollDistanceStep * mActiveLayout->GetScrollSpeedFactor());
     float firstItemScrollPosition = ClampFirstItemPosition(layoutPositionDelta, layoutSize, *mActiveLayout);
 
     self.SetProperty(Toolkit::ItemView::Property::LAYOUT_POSITION, firstItemScrollPosition );
@@ -1004,23 +1009,23 @@ bool ItemView::OnMouseWheelEvent(const MouseWheelEvent& event)
     mRefreshEnabled = true;
   }
 
-  if (mMouseWheelEventFinishedTimer.IsRunning())
+  if (mWheelEventFinishedTimer.IsRunning())
   {
-    mMouseWheelEventFinishedTimer.Stop();
+    mWheelEventFinishedTimer.Stop();
   }
 
-  mMouseWheelEventFinishedTimer.Start();
+  mWheelEventFinishedTimer.Start();
 
   return true;
 }
 
-bool ItemView::OnMouseWheelEventFinished()
+bool ItemView::OnWheelEventFinished()
 {
   if (mActiveLayout)
   {
     RemoveAnimation(mScrollAnimation);
 
-    // No more mouse wheel events coming. Do the anchoring if enabled.
+    // No more wheel events coming. Do the anchoring if enabled.
     mScrollAnimation = DoAnchoring();
     if (mScrollAnimation)
     {
@@ -1039,15 +1044,17 @@ bool ItemView::OnMouseWheelEventFinished()
   return false;
 }
 
-void ItemView::ReapplyAllConstraints( float durationSeconds )
+void ItemView::ReapplyAllConstraints()
 {
+  Vector3 layoutSize = Self().GetCurrentSize();
+
   for (ConstItemPoolIter iter = mItemPool.begin(); iter != mItemPool.end(); ++iter)
   {
     unsigned int id = iter->first;
     Actor actor = iter->second;
 
     actor.RemoveConstraints();
-    mActiveLayout->ApplyConstraints(actor, id, durationSeconds, Self());
+    mActiveLayout->ApplyConstraints(actor, id, layoutSize, Self());
   }
 }
 
@@ -1201,7 +1208,7 @@ bool ItemView::OnAccessibilityPan(PanGesture gesture)
   return true;
 }
 
-Actor ItemView::GetNextKeyboardFocusableActor(Actor actor, Toolkit::Control::KeyboardFocusNavigationDirection direction, bool loopEnabled)
+Actor ItemView::GetNextKeyboardFocusableActor(Actor actor, Toolkit::Control::KeyboardFocus::Direction direction, bool loopEnabled)
 {
   Actor nextFocusActor;
   if(mActiveLayout)
@@ -1260,7 +1267,7 @@ Animation ItemView::DoAnchoring()
     float anchorPosition = mActiveLayout->GetClosestAnchorPosition( GetCurrentLayoutPosition(0) );
 
     anchoringAnimation = Animation::New(mAnchoringDuration);
-    anchoringAnimation.AnimateTo( Property(self, Toolkit::ItemView::Property::LAYOUT_POSITION), -anchorPosition, AlphaFunction::EASE_OUT );
+    anchoringAnimation.AnimateTo( Property(self, Toolkit::ItemView::Property::LAYOUT_POSITION), anchorPosition, AlphaFunction::EASE_OUT );
     anchoringAnimation.AnimateTo( Property(self, Toolkit::ItemView::Property::SCROLL_SPEED), 0.0f, AlphaFunction::EASE_OUT );
     if(!mIsFlicking)
     {
@@ -1298,6 +1305,9 @@ void ItemView::OnLayoutActivationScrollFinished(Animation& source)
   RemoveAnimation(mScrollAnimation);
   mRefreshEnabled = true;
   DoRefresh(GetCurrentLayoutPosition(0), true);
+
+  // Emit the layout activated signal
+  mLayoutActivatedSignal.Emit();
 }
 
 void ItemView::OnOvershootOnFinished(Animation& animation)
@@ -1467,7 +1477,6 @@ void ItemView::EnableScrollOvershoot( bool enable )
     mOvershootOverlay.SetColor(mOvershootEffectColor);
     mOvershootOverlay.SetParentOrigin(ParentOrigin::TOP_LEFT);
     mOvershootOverlay.SetAnchorPoint(AnchorPoint::TOP_LEFT);
-    mOvershootOverlay.SetDrawMode(DrawMode::OVERLAY);
     self.Add(mOvershootOverlay);
 
     Constraint constraint = Constraint::New<Vector3>( mOvershootOverlay, Actor::Property::SIZE, OvershootOverlaySizeConstraint );
@@ -1619,12 +1628,35 @@ void ItemView::GetItemsRange(ItemRange& range)
 void ItemView::OnScrollPositionChanged( float position )
 {
   // Cancel scroll animation to prevent any fighting of setting the scroll position property.
-  RemoveAnimation(mScrollAnimation);
+  if(!mRefreshEnabled)
+  {
+    RemoveAnimation(mScrollAnimation);
+  }
 
   // Refresh the cache immediately when the scroll position is changed.
   DoRefresh(position, false); // No need to cache extra items.
 }
 
+bool ItemView::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
+{
+  Dali::BaseHandle handle( object );
+
+  bool connected( true );
+  Toolkit::ItemView itemView = Toolkit::ItemView::DownCast( handle );
+
+  if( 0 == strcmp( signalName.c_str(), LAYOUT_ACTIVATED_SIGNAL ) )
+  {
+    itemView.LayoutActivatedSignal().Connect( tracker, functor );
+  }
+  else
+  {
+    // signalName does not match any signal
+    connected = false;
+  }
+
+  return connected;
+}
+
 } // namespace Internal
 
 } // namespace Toolkit