Emit a signal when layout is activated in ItemView
authorRichard Huang <r.huang@samsung.com>
Tue, 16 Jun 2015 14:20:57 +0000 (15:20 +0100)
committerYoonsang Lee <ysang114.lee@samsung.com>
Tue, 23 Jun 2015 02:34:02 +0000 (11:34 +0900)
Change-Id: If10b9c5c7c4b278f0400ee51fca72af4d06dea5f

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
dali-toolkit/public-api/controls/scrollable/item-view/item-view.cpp
dali-toolkit/public-api/controls/scrollable/item-view/item-view.h

index 82527f4..b85524d 100644 (file)
@@ -40,16 +40,47 @@ void utc_dali_toolkit_item_view_cleanup(void)
 
 namespace
 {
+
 const unsigned int TOTAL_ITEM_NUMBER = 100;
 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)
+
 static bool gObjectCreatedCallBackCalled;
+static bool gOnLayoutActivatedCalled;                     ///< Whether the LayoutActivated signal was invoked.
 
 static void TestCallback(BaseHandle handle)
 {
   gObjectCreatedCallBackCalled = true;
 }
 
+static void OnLayoutActivated()
+{
+  gOnLayoutActivatedCalled = true;
+}
+
+/*
+ * Simulate time passed by.
+ *
+ * @note this will always process at least 1 frame (1/60 sec)
+ *
+ * @param application Test application instance
+ * @param duration Time to pass in milliseconds.
+ * @return The actual time passed in milliseconds
+ */
+int Wait(ToolkitTestApplication& application, int duration = 0)
+{
+  int time = 0;
+
+  for(int i = 0; i <= ( duration / RENDER_FRAME_INTERVAL); i++)
+  {
+    application.SendNotification();
+    application.Render(RENDER_FRAME_INTERVAL);
+    time += RENDER_FRAME_INTERVAL;
+  }
+
+  return time;
+}
 
 // Implementation of ItemFactory for providing actors to ItemView
 class TestItemFactory : public ItemFactory
@@ -771,3 +802,38 @@ int UtcDaliItemFactoryGetExtention(void)
   DALI_TEST_CHECK( factory.GetExtension() == NULL );
   END_TEST;
 }
+
+int UtcDaliItemViewLayoutActivatedSignalP(void)
+{
+  ToolkitTestApplication application;
+
+  // Create the ItemView actor
+  TestItemFactory factory;
+  ItemView view = ItemView::New(factory);
+
+  // Create a grid layout and add it to ItemView
+  ItemLayoutPtr gridLayout = DefaultItemLayout::New( DefaultItemLayout::GRID );
+  view.AddLayout(*gridLayout);
+
+  Stage::GetCurrent().Add( view );
+
+  // Connect the layout activated signal
+  view.LayoutActivatedSignal().Connect( &OnLayoutActivated );
+
+  gOnLayoutActivatedCalled = false;
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  // 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.1f);
+
+  // Wait for 0.1 second
+  Wait(application, 100);
+
+  DALI_TEST_EQUALS( gOnLayoutActivatedCalled, true, TEST_LOCATION );
+
+  END_TEST;
+}
index e56760f..38e6216 100644 (file)
@@ -53,6 +53,8 @@ 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;
@@ -422,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;
@@ -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)
@@ -1625,6 +1635,26 @@ void ItemView::OnScrollPositionChanged( float position )
   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
index 16f0b0a..b6a2d96 100644 (file)
@@ -53,6 +53,11 @@ class ItemView : public Scrollable
 {
 public:
 
+  // Signals
+  typedef Toolkit::ItemView::LayoutActivatedSignalType LayoutActivatedSignalType;
+
+public:
+
   /**
    * Create a new ItemView.
    * @param[in] factory The factory which provides ItemView with items.
@@ -284,6 +289,25 @@ public:
    */
   void GetItemsRange(ItemRange& range);
 
+  /**
+   * @copydoc Toolkit::ItemView::LayoutActivatedSignal()
+   */
+  LayoutActivatedSignalType& LayoutActivatedSignal()
+  {
+    return mLayoutActivatedSignal;
+  }
+
+  /**
+   * Connects a callback function with the object's signals.
+   * @param[in] object The object providing the signal.
+   * @param[in] tracker Used to disconnect the signal.
+   * @param[in] signalName The signal to connect to.
+   * @param[in] functor A newly allocated FunctorDelegate.
+   * @return True if the signal was connected.
+   * @post If a signal was connected, ownership of functor was passed to CallbackBase. Otherwise the caller is responsible for deleting the unused functor.
+   */
+  static bool DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor );
+
 private:
 
   /**
@@ -593,6 +617,8 @@ private:
 
   Vector3 mItemsParentOrigin;
   Vector3 mItemsAnchorPoint;
+
+  LayoutActivatedSignalType mLayoutActivatedSignal;
 };
 
 } // namespace Internal
index 6daa933..12a6baf 100644 (file)
@@ -243,6 +243,11 @@ void ItemView::GetItemsRange(ItemRange& range)
   GetImpl(*this).GetItemsRange(range);
 }
 
+ItemView::LayoutActivatedSignalType& ItemView::LayoutActivatedSignal()
+{
+  return GetImpl(*this).LayoutActivatedSignal();
+}
+
 } // namespace Toolkit
 
 } // namespace Dali
index ca51a44..cb0859d 100644 (file)
@@ -46,7 +46,13 @@ typedef IntrusivePtr<ItemLayout> ItemLayoutPtr;
  *
  * Multiple ItemLayouts may be provided, to determine the logical position of each item a layout.
  * Actors are provided from an external ItemFactory, to display the currently visible items.
+ *
+ * Signals
+ * | %Signal Name                     | Method                                     |
+ * |----------------------------------|--------------------------------------------|
+ * | layout-activated                 | @ref LayoutActivatedSignal()               |
  */
+
 class DALI_IMPORT_API ItemView : public Scrollable
 {
 public:
@@ -73,6 +79,10 @@ public:
     };
   };
 
+  // Signals
+
+  typedef Signal< void () > LayoutActivatedSignalType;
+
 public:
 
   /**
@@ -421,6 +431,20 @@ public:
    */
   void GetItemsRange(ItemRange& range);
 
+public: // Signals
+
+  /**
+   * @brief Signal emitted when layout activation is finished.
+   *
+   * A callback of the following type may be connected:
+   * @code
+   *   void YourCallbackName();
+   * @endcode
+   * @pre The Object has been initialized.
+   * @return The signal to connect to.
+   */
+  ItemView::LayoutActivatedSignalType& LayoutActivatedSignal();
+
 public: // Not intended for application developers
 
   /**