Remove set and map wrappers from ItemView 74/132374/5
authorRichard Huang <r.huang@samsung.com>
Fri, 2 Jun 2017 15:24:45 +0000 (16:24 +0100)
committerRichard Huang <r.huang@samsung.com>
Mon, 5 Jun 2017 13:56:41 +0000 (14:56 +0100)
Change-Id: I1e827af982842d6bc3a9ee9fdacb51c88aa77483

automated-tests/src/dali-toolkit/utc-Dali-ItemView.cpp
dali-toolkit/internal/controls/scrollable/item-view/item-view-impl.cpp
dali-toolkit/internal/controls/scrollable/item-view/item-view-impl.h

index 040fb1c..3b5cefb 100755 (executable)
@@ -45,7 +45,7 @@ void utc_dali_toolkit_item_view_cleanup(void)
 namespace
 {
 
-const unsigned int TOTAL_ITEM_NUMBER = 100;
+const unsigned int TOTAL_ITEM_NUMBER = 400;
 const char* TEST_IMAGE_FILE_NAME = "gallery_image_01.jpg";
 
 const int RENDER_FRAME_INTERVAL = 16;                     ///< Duration of each frame in ms. (at approx 60FPS)
@@ -423,13 +423,34 @@ int UtcDaliItemViewRemoveItem(void)
   // Remove the item with ID 2
   view.RemoveItem(2, 0.0f);
 
-  // Get the new item given the item ID 2
+  // Get the new item given the item ID 2 and 3
   Actor newItemActorID2 = view.GetItem(2);
+  Actor newItemActorID3 = view.GetItem(3);
 
   // Check the original item with item ID 2 was deleted and now item ID 2 represents the original item with ID 3
   DALI_TEST_CHECK(view.GetItemId(newItemActorID2) == 2);
   DALI_TEST_CHECK(oldItemActorID2 != newItemActorID2);
-  DALI_TEST_CHECK(newItemActorID2 = oldItemActorID3);
+  DALI_TEST_CHECK(newItemActorID2 == oldItemActorID3);
+
+  // scroll to the end of item view
+  view.ScrollToItem(TOTAL_ITEM_NUMBER - 1, 0.00f);
+
+  application.SendNotification();
+  application.Render(0);
+
+  // Refresh the item view
+  view.Refresh();
+
+  Actor itemActorID390 = view.GetItem(390);
+  DALI_TEST_CHECK(view.GetItemId(itemActorID390) == 390);
+
+  // Remove the item with ID 2 (which is now before the current item range)
+  view.RemoveItem(2, 0.0f);
+
+  // Check the original item with item ID 2 was deleted and now item ID 389 represents the original item with ID 390
+  DALI_TEST_CHECK(view.GetItemId(itemActorID390) == 389);
+  DALI_TEST_CHECK(view.GetItem(389) == itemActorID390);
+
   END_TEST;
 }
 
@@ -636,16 +657,16 @@ int UtcDaliItemViewInsertItemP(void)
   TestItemFactory factory;
   ItemView view = ItemView::New(factory);
 
-  // Create a depth layout and add it to ItemView
-  ItemLayoutPtr depthLayout = DefaultItemLayout::New( DefaultItemLayout::DEPTH);
-  depthLayout->SetOrientation(ControlOrientation::Left);
-  view.AddLayout(*depthLayout);
+  // Create a grid layout and add it to ItemView
+  ItemLayoutPtr gridLayout = DefaultItemLayout::New( DefaultItemLayout::GRID);
+  gridLayout->SetOrientation(ControlOrientation::Left);
+  view.AddLayout(*gridLayout);
 
   // Activate the grid layout so that the items will be created and added to ItemView
   Vector3 stageSize(Dali::Stage::GetCurrent().GetSize());
-  view.ActivateLayout(0, stageSize, 0.5f);
+  view.ActivateLayout(0, stageSize, 0.0f);
 
-  // Get the item given the item ID
+  // Get the specified item where new item to be inserted before that
   Actor itemActor = view.GetItem(2);
 
   ItemId id = view.GetItemId( itemActor );
@@ -655,9 +676,33 @@ int UtcDaliItemViewInsertItemP(void)
 
   Actor newActor = Actor::New();
 
-  view.InsertItem(Item(id, newActor), 0.5f);
+  view.InsertItem(Item(id, newActor), 0.0f);
 
   DALI_TEST_CHECK(view.GetItem(2) == newActor);
+
+  DALI_TEST_CHECK(view.GetItemId(itemActor) == 3);
+  DALI_TEST_CHECK(view.GetItem(3) == itemActor);
+
+  // scroll to the end of item view
+  view.ScrollToItem(TOTAL_ITEM_NUMBER - 1, 0.00f);
+
+  application.SendNotification();
+  application.Render(0);
+
+  // Refresh the item view
+  view.Refresh();
+
+  Actor itemActorID390 = view.GetItem(390);
+  DALI_TEST_CHECK(view.GetItemId(itemActorID390) == 390);
+
+  // Insert the item with ID 2 (which is now before the current item range)
+  Actor anotherNewActor = Actor::New();
+  view.InsertItem(Item(id, anotherNewActor), 0.0f);
+
+  // Check that item ID 391 now represents the original item with ID 390
+  DALI_TEST_CHECK(view.GetItemId(itemActorID390) == 391);
+  DALI_TEST_CHECK(view.GetItem(391) == itemActorID390);
+
   END_TEST;
 }
 
@@ -680,9 +725,15 @@ int UtcDaliItemViewInsertItemsP(void)
 
   unsigned int itemCount = view.GetChildCount();
 
+  // Get the specified item where new items to be inserted before that
+  Actor itemActor = view.GetItem(1);
+
+  // Check we are getting the correct Item ID given the specified item
+  DALI_TEST_CHECK(view.GetItemId(itemActor) == 1);
+
   ItemContainer insertList;
 
-  for( unsigned int i = 0u; i < 10; ++i )
+  for( unsigned int i = 1u; i < 11; ++i )
   {
     Actor child = view.GetChildAt( i );
     Actor newActor = Actor::New();
@@ -697,6 +748,10 @@ int UtcDaliItemViewInsertItemsP(void)
 
   DALI_TEST_CHECK(view.GetChildCount() == itemCount + 10);
 
+  // Check that new items are inserted in the correct positions
+  DALI_TEST_CHECK(view.GetItemId(itemActor) == 11);
+  DALI_TEST_CHECK(view.GetItem(11) == itemActor);
+
   ItemIdContainer removeList;
 
   for( unsigned int i = 0u; i < view.GetChildCount(); ++i )
@@ -715,6 +770,11 @@ int UtcDaliItemViewInsertItemsP(void)
   }
 
   DALI_TEST_CHECK(view.GetChildCount() == itemCount);
+
+  // Check that new items are removed correctly so that we are getting the correct Item ID given the specified item
+  DALI_TEST_CHECK(view.GetItemId(itemActor) == 1);
+  DALI_TEST_CHECK(view.GetItem(1) == itemActor);
+
   END_TEST;
 }
 
@@ -736,9 +796,10 @@ int UtcDaliItemViewReplaceItemP(void)
 
   Actor newActor = Actor::New();
 
-  view.ReplaceItem( Item( 0, newActor ), 0.5f );
+  view.ReplaceItem( Item( 5, newActor ), 0.5f );
+
+  DALI_TEST_CHECK(view.GetItem(5) == newActor);
 
-  DALI_TEST_CHECK(view.GetItem(0) == newActor);
   END_TEST;
 }
 
index 7f27217..9e4f57e 100755 (executable)
@@ -25,7 +25,6 @@
 
 #include <dali/public-api/animation/constraint.h>
 #include <dali/public-api/animation/constraints.h>
-#include <dali/devel-api/common/set-wrapper.h>
 #include <dali/public-api/common/stage.h>
 #include <dali/public-api/events/wheel-event.h>
 #include <dali/public-api/events/touch-data.h>
@@ -45,7 +44,6 @@
 #include <dali-toolkit/internal/controls/scrollable/bouncing-effect-actor.h>
 
 using std::string;
-using std::set;
 using namespace Dali;
 
 namespace // Unnamed namespace
@@ -280,19 +278,29 @@ DALI_ACTION_REGISTRATION(              Toolkit, ItemView, "disableRefresh",
 
 DALI_TYPE_REGISTRATION_END()
 
-bool FindById( const ItemContainer& items, ItemId id )
+const ItemIter FindItemById( ItemContainer& items, ItemId id )
 {
-  for( ConstItemIter iter = items.begin(); items.end() != iter; ++iter )
+  for( ItemIter iter = items.begin(); items.end() != iter; ++iter )
   {
     if( iter->first == id )
     {
-      return true;
+      return iter;
     }
   }
 
-  return false;
+  return items.end();
 }
 
+void InsertToItemContainer( ItemContainer& items, Item item )
+{
+  if( items.end() == FindItemById( items, item.first ) )
+  {
+    ItemIter iterToInsert = std::lower_bound( items.begin(), items.end(), item );
+    items.insert( iterToInsert, item );
+  }
+}
+
+
 /**
   * Helper to apply size constraint to mOvershootOverlay
   * @param[in] overshootOverlay The overshootOverlay actor
@@ -427,7 +435,7 @@ void ItemView::ActivateLayout(unsigned int layoutIndex, const Vector3& targetSiz
 
   // Move the items to the new layout positions...
 
-  for (ConstItemPoolIter iter = mItemPool.begin(); iter != mItemPool.end(); ++iter)
+  for (ConstItemIter iter = mItemPool.begin(); iter != mItemPool.end(); ++iter)
   {
     unsigned int itemId = iter->first;
     Actor actor = iter->second;
@@ -494,7 +502,7 @@ void ItemView::DeactivateCurrentLayout()
 {
   if (mActiveLayout)
   {
-    for (ConstItemPoolIter iter = mItemPool.begin(); iter != mItemPool.end(); ++iter)
+    for (ConstItemIter iter = mItemPool.begin(); iter != mItemPool.end(); ++iter)
     {
       Actor actor = iter->second;
       actor.RemoveConstraints();
@@ -521,7 +529,7 @@ void ItemView::OnRefreshNotification(PropertyNotification& source)
 
 void ItemView::Refresh()
 {
-  for (ItemPoolIter iter = mItemPool.begin(); iter != mItemPool.end(); ++iter )
+  for (ConstItemIter iter = mItemPool.begin(); iter != mItemPool.end(); ++iter )
   {
     ReleaseActor( iter->first, iter->second );
   }
@@ -622,10 +630,13 @@ Actor ItemView::GetItem(unsigned int itemId) const
 {
   Actor actor;
 
-  ConstItemPoolIter iter = mItemPool.find( itemId );
-  if( iter != mItemPool.end() )
+  for ( ConstItemIter iter = mItemPool.begin(); iter != mItemPool.end(); ++iter )
   {
-    actor = iter->second;
+    if( iter->first == itemId )
+    {
+      actor = iter->second;
+      break;
+    }
   }
 
   return actor;
@@ -635,7 +646,7 @@ unsigned int ItemView::GetItemId( Actor actor ) const
 {
   unsigned int itemId( 0 );
 
-  for ( ConstItemPoolIter iter = mItemPool.begin(); iter != mItemPool.end(); ++iter )
+  for ( ConstItemIter iter = mItemPool.begin(); iter != mItemPool.end(); ++iter )
   {
     if( iter->second == actor )
     {
@@ -653,9 +664,9 @@ void ItemView::InsertItem( Item newItem, float durationSeconds )
   Vector3 layoutSize = Self().GetCurrentSize();
 
   Actor displacedActor;
-  ItemPoolIter afterDisplacedIter = mItemPool.end();
+  ItemIter afterDisplacedIter = mItemPool.end();
 
-  ItemPoolIter foundIter = mItemPool.find( newItem.first );
+  ItemIter foundIter = FindItemById( mItemPool, newItem.first );
   if( mItemPool.end() != foundIter )
   {
     SetupActor( newItem, layoutSize );
@@ -669,12 +680,12 @@ void ItemView::InsertItem( Item newItem, float durationSeconds )
   else
   {
     // Inserting before the existing item range?
-    ItemPoolIter iter = mItemPool.begin();
+    ItemIter iter = mItemPool.begin();
     if( iter != mItemPool.end() &&
         iter->first > newItem.first )
     {
       displacedActor = iter->second;
-      mItemPool.erase( iter++ ); // iter is still valid after the erase
+      iter = mItemPool.erase( iter ); // iter is still valid after the erase
 
       afterDisplacedIter = iter;
     }
@@ -683,7 +694,7 @@ void ItemView::InsertItem( Item newItem, float durationSeconds )
   if( displacedActor )
   {
     // Move the existing actors to make room
-    for( ItemPoolIter iter = afterDisplacedIter; mItemPool.end() != iter; ++iter )
+    for( ItemIter iter = afterDisplacedIter; mItemPool.end() != iter; ++iter )
     {
       Actor temp = iter->second;
       iter->second = displacedActor;
@@ -694,12 +705,12 @@ void ItemView::InsertItem( Item newItem, float durationSeconds )
     }
 
     // Create last item
-    ItemPool::reverse_iterator lastIter = mItemPool.rbegin();
+    ItemContainer::reverse_iterator lastIter = mItemPool.rbegin();
     if ( lastIter != mItemPool.rend() )
     {
       ItemId lastId = lastIter->first;
       Item lastItem( lastId + 1, displacedActor );
-      mItemPool.insert( lastItem );
+      InsertToItemContainer( mItemPool, lastItem );
 
       lastItem.second.RemoveConstraints();
       mActiveLayout->ApplyConstraints( lastItem.second, lastItem.first, layoutSize, Self() );
@@ -717,24 +728,21 @@ void ItemView::InsertItems( const ItemContainer& newItems, float durationSeconds
   Vector3 layoutSize = Self().GetCurrentSize();
 
   // Insert from lowest id to highest
-  std::set<Item> sortedItems;
-  for( ConstItemIter iter = newItems.begin(); newItems.end() != iter; ++iter )
-  {
-    sortedItems.insert( *iter );
-  }
+  ItemContainer sortedItems(newItems);
+  std::sort( sortedItems.begin(), sortedItems.end() );
 
-  for( std::set<Item>::iterator iter = sortedItems.begin(); sortedItems.end() != iter; ++iter )
+  for( ItemIter iter = sortedItems.begin(); sortedItems.end() != iter; ++iter )
   {
     Self().Add( iter->second );
 
-    ItemPoolIter foundIter = mItemPool.find( iter->first );
+    ItemIter foundIter = FindItemById( mItemPool, iter->first );
     if( mItemPool.end() != foundIter )
     {
       Actor moveMe = foundIter->second;
       foundIter->second = iter->second;
 
       // Move the existing actors to make room
-      for( ItemPoolIter iter = ++foundIter; mItemPool.end() != iter; ++iter )
+      for( ItemIter iter = ++foundIter; mItemPool.end() != iter; ++iter )
       {
         Actor temp = iter->second;
         iter->second = moveMe;
@@ -744,19 +752,19 @@ void ItemView::InsertItems( const ItemContainer& newItems, float durationSeconds
       // Create last item
       ItemId lastId = mItemPool.rbegin()->first;
       Item lastItem( lastId + 1, moveMe );
-      mItemPool.insert( lastItem );
+      InsertToItemContainer( mItemPool, lastItem );
     }
     else
     {
-      mItemPool.insert( *iter );
+      InsertToItemContainer( mItemPool, *iter );
     }
   }
 
   // Relayout everything
-  for (ItemPoolIter iter = mItemPool.begin(); iter != mItemPool.end(); ++iter)
+  for (ItemIter iter = mItemPool.begin(); iter != mItemPool.end(); ++iter)
   {
     // If newly inserted
-    if( FindById( newItems, iter->first ) )
+    if( std::binary_search( sortedItems.begin(), sortedItems.end(), *iter ) )
     {
       SetupActor( *iter, layoutSize );
     }
@@ -788,13 +796,10 @@ void ItemView::RemoveItems( const ItemIdContainer& itemIds, float durationSecond
   bool actorsReordered( false );
 
   // Remove from highest id to lowest
-  set<ItemId> sortedItems;
-  for( ConstItemIdIter iter = itemIds.begin(); itemIds.end() != iter; ++iter )
-  {
-    sortedItems.insert( *iter );
-  }
+  ItemIdContainer sortedItems(itemIds);
+  std::sort( sortedItems.begin(), sortedItems.end() );
 
-  for( set<ItemId>::reverse_iterator iter = sortedItems.rbegin(); sortedItems.rend() != iter; ++iter )
+  for( ItemIdContainer::reverse_iterator iter = sortedItems.rbegin(); sortedItems.rend() != iter; ++iter )
   {
     if( RemoveActor( *iter ) )
     {
@@ -814,7 +819,7 @@ bool ItemView::RemoveActor(unsigned int itemId)
 {
   bool reordered( false );
 
-  ItemPoolIter removeIter = mItemPool.find( itemId );
+  ItemIter removeIter = FindItemById( mItemPool, itemId );
   if( removeIter != mItemPool.end() )
   {
     ReleaseActor(itemId, removeIter->second);
@@ -822,12 +827,12 @@ bool ItemView::RemoveActor(unsigned int itemId)
   else
   {
     // Removing before the existing item range?
-    ItemPoolIter iter = mItemPool.begin();
+    ItemIter 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()) );
+      InsertToItemContainer( mItemPool, Item(iter->first - 1, Actor()) );
 
       removeIter = mItemPool.begin();
     }
@@ -843,11 +848,11 @@ bool ItemView::RemoveActor(unsigned int itemId)
     //     ID 2 - ActorB       ID 2 - ActorC (previously ID 3)
     //     ID 3 - ActorC       ID 3 - ActorB (previously ID 4)
     //     ID 4 - ActorD
-    for (ItemPoolIter iter = removeIter; iter != mItemPool.end(); ++iter)
+    for (ItemIter iter = removeIter; iter != mItemPool.end(); ++iter)
     {
       if( iter->first < mItemPool.rbegin()->first )
       {
-        iter->second = mItemPool[ iter->first + 1 ];
+        iter->second = ( iter + 1 )->second;
       }
       else
       {
@@ -868,7 +873,7 @@ void ItemView::ReplaceItem( Item replacementItem, float durationSeconds )
   SetupActor( replacementItem, layoutSize );
   Self().Add( replacementItem.second );
 
-  const ItemPoolIter iter = mItemPool.find( replacementItem.first );
+  const ItemIter iter = FindItemById( mItemPool, replacementItem.first );
   if( mItemPool.end() != iter )
   {
     ReleaseActor(iter->first, iter->second);
@@ -876,7 +881,7 @@ void ItemView::ReplaceItem( Item replacementItem, float durationSeconds )
   }
   else
   {
-    mItemPool.insert( replacementItem );
+    InsertToItemContainer( mItemPool, replacementItem );
   }
 
   CalculateDomainSize( layoutSize );
@@ -895,7 +900,7 @@ void ItemView::ReplaceItems( const ItemContainer& replacementItems, float durati
 void ItemView::RemoveActorsOutsideRange( ItemRange range )
 {
   // Remove unwanted actors from the ItemView & ItemPool
-  for (ItemPoolIter iter = mItemPool.begin(); iter != mItemPool.end(); )
+  for (ItemIter iter = mItemPool.begin(); iter != mItemPool.end(); )
   {
     unsigned int current = iter->first;
 
@@ -903,7 +908,7 @@ void ItemView::RemoveActorsOutsideRange( ItemRange range )
     {
       ReleaseActor(iter->first, iter->second);
 
-      mItemPool.erase( iter++ ); // erase invalidates the return value of post-increment; iter remains valid
+      iter = mItemPool.erase( iter ); // iter is still valid after the erase
     }
     else
     {
@@ -941,7 +946,7 @@ void ItemView::AddNewActor( unsigned int itemId, const Vector3& layoutSize )
 {
   mAddingItems = true;
 
-  if( mItemPool.end() == mItemPool.find( itemId ) )
+  if( mItemPool.end() == FindItemById( mItemPool, itemId ) )
   {
     Actor actor = mItemFactory.NewItem( itemId );
 
@@ -949,7 +954,7 @@ void ItemView::AddNewActor( unsigned int itemId, const Vector3& layoutSize )
     {
       Item newItem( itemId, actor );
 
-      mItemPool.insert( newItem );
+      InsertToItemContainer( mItemPool, newItem );
 
       SetupActor( newItem, layoutSize );
       Self().Add( actor );
@@ -1073,7 +1078,7 @@ void ItemView::ReapplyAllConstraints()
 {
   Vector3 layoutSize = Self().GetCurrentSize();
 
-  for (ConstItemPoolIter iter = mItemPool.begin(); iter != mItemPool.end(); ++iter)
+  for (ConstItemIter iter = mItemPool.begin(); iter != mItemPool.end(); ++iter)
   {
     unsigned int id = iter->first;
     Actor actor = iter->second;
@@ -1673,7 +1678,7 @@ void ItemView::SetItemsParentOrigin( const Vector3& parentOrigin )
   if( parentOrigin != mItemsParentOrigin )
   {
     mItemsParentOrigin = parentOrigin;
-    for (ItemPoolIter iter = mItemPool.begin(); iter != mItemPool.end(); ++iter)
+    for (ItemIter iter = mItemPool.begin(); iter != mItemPool.end(); ++iter)
     {
       iter->second.SetParentOrigin(parentOrigin);
     }
@@ -1690,7 +1695,7 @@ void ItemView::SetItemsAnchorPoint( const Vector3& anchorPoint )
   if( anchorPoint != mItemsAnchorPoint )
   {
     mItemsAnchorPoint = anchorPoint;
-    for (ItemPoolIter iter = mItemPool.begin(); iter != mItemPool.end(); ++iter)
+    for (ItemIter iter = mItemPool.begin(); iter != mItemPool.end(); ++iter)
     {
       iter->second.SetAnchorPoint(anchorPoint);
     }
index d0a2bf1..1bb4d2a 100755 (executable)
@@ -22,7 +22,6 @@
 #include <dali/public-api/adaptor-framework/timer.h>
 #include <dali/public-api/animation/animation.h>
 #include <dali/public-api/object/property-notification.h>
-#include <dali/devel-api/common/map-wrapper.h>
 #include <dali/public-api/object/property-map.h>
 #include <dali/public-api/object/property-array.h>
 
@@ -608,13 +607,9 @@ private:
 
 private:
 
-  typedef std::map<unsigned int, Actor> ItemPool;
-  typedef ItemPool::iterator            ItemPoolIter;
-  typedef ItemPool::const_iterator      ConstItemPoolIter;
-
   Property::Array mlayoutArray;
 
-  ItemPool mItemPool;
+  ItemContainer mItemPool;
   ItemFactory& mItemFactory;
   std::vector< ItemLayoutPtr > mLayouts;            ///< Container of Dali::Toolkit::ItemLayout objects
   Actor mOvershootOverlay;                          ///< The overlay actor for overshoot effect