Fixed various SVACE errors
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / controls / scrollable / item-view / item-view-impl.cpp
old mode 100644 (file)
new mode 100755 (executable)
index aa6443d..7770147
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 // EXTERNAL INCLUDES
 #include <cstring> // for strcmp
 #include <algorithm>
+#include <dali/public-api/actors/layer.h>
+
 #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-event.h>
+#include <dali/public-api/events/touch-data.h>
 #include <dali/public-api/object/type-registry.h>
-#include <dali/devel-api/object/type-registry-helper.h>
+#include <dali/public-api/object/type-registry-helper.h>
+#include <dali/devel-api/object/property-helper-devel.h>
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/public-api/controls/scroll-bar/scroll-bar.h>
 #include <dali-toolkit/public-api/controls/scrollable/item-view/item-factory.h>
+#include <dali-toolkit/public-api/controls/scrollable/item-view/default-item-layout.h>
+#include <dali-toolkit/devel-api/controls/scrollable/item-view/default-item-layout-property.h>
+#include <dali-toolkit/devel-api/controls/scrollable/item-view/item-view-devel.h>
+#include <dali-toolkit/internal/controls/scrollable/item-view/grid-layout.h>
+#include <dali-toolkit/internal/controls/scrollable/item-view/depth-layout.h>
+#include <dali-toolkit/internal/controls/scrollable/item-view/spiral-layout.h>
 #include <dali-toolkit/internal/controls/scrollable/bouncing-effect-actor.h>
 
 using std::string;
@@ -42,21 +51,6 @@ using namespace Dali;
 namespace // Unnamed namespace
 {
 
-//Type registration
-
-DALI_TYPE_REGISTRATION_BEGIN( Toolkit::ItemView, Toolkit::Scrollable, NULL)
-
-DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, ItemView, "layoutPosition",      FLOAT,    LAYOUT_POSITION)
-DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, ItemView, "scrollSpeed",         FLOAT,    SCROLL_SPEED)
-DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, ItemView, "overshoot",           FLOAT,    OVERSHOOT)
-DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, ItemView, "scrollDirection",     VECTOR2,  SCROLL_DIRECTION)
-DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, ItemView, "layoutOrientation",   INTEGER,  LAYOUT_ORIENTATION)
-DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, ItemView, "scrollContentSize",   FLOAT,    SCROLL_CONTENT_SIZE)
-
-DALI_SIGNAL_REGISTRATION(              Toolkit, ItemView, "layoutActivated",     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_WHEEL_SCROLL_DISTANCE_STEP_PROPORTION = 0.1f;
@@ -256,6 +250,34 @@ namespace Internal
 namespace // unnamed namespace
 {
 
+//Type registration
+
+DALI_TYPE_REGISTRATION_BEGIN( Toolkit::ItemView, Toolkit::Scrollable, NULL)
+
+DALI_PROPERTY_REGISTRATION( Toolkit, ItemView, "minimumSwipeSpeed",          FLOAT,     MINIMUM_SWIPE_SPEED          )
+DALI_PROPERTY_REGISTRATION( Toolkit, ItemView, "minimumSwipeDistance",       FLOAT,     MINIMUM_SWIPE_DISTANCE       )
+DALI_PROPERTY_REGISTRATION( Toolkit, ItemView, "wheelScrollDistanceStep",    FLOAT,     WHEEL_SCROLL_DISTANCE_STEP   )
+DALI_PROPERTY_REGISTRATION( Toolkit, ItemView, "snapToItemEnabled",          BOOLEAN,   SNAP_TO_ITEM_ENABLED         )
+DALI_PROPERTY_REGISTRATION( Toolkit, ItemView, "refreshInterval",            FLOAT,     REFRESH_INTERVAL             )
+DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, ItemView, "layout",               ARRAY,     LAYOUT                       )
+
+
+DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, ItemView, "layoutPosition",      FLOAT,    LAYOUT_POSITION)
+DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, ItemView, "scrollSpeed",         FLOAT,    SCROLL_SPEED)
+DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, ItemView, "overshoot",           FLOAT,    OVERSHOOT)
+DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, ItemView, "scrollDirection",     VECTOR2,  SCROLL_DIRECTION)
+DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, ItemView, "layoutOrientation",   INTEGER,  LAYOUT_ORIENTATION)
+DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, ItemView, "scrollContentSize",   FLOAT,    SCROLL_CONTENT_SIZE)
+
+DALI_SIGNAL_REGISTRATION(              Toolkit, ItemView, "layoutActivated",     LAYOUT_ACTIVATED_SIGNAL )
+
+DALI_ACTION_REGISTRATION(              Toolkit, ItemView, "stopScrolling",       ACTION_STOP_SCROLLING   )
+
+DALI_ACTION_REGISTRATION(              Toolkit, ItemView, "enableRefresh",       ACTION_ENABLE_REFRESH   )
+DALI_ACTION_REGISTRATION(              Toolkit, ItemView, "disableRefresh",      ACTION_DISABLE_REFRESH  )
+
+DALI_TYPE_REGISTRATION_END()
+
 bool FindById( const ItemContainer& items, ItemId id )
 {
   for( ConstItemIter iter = items.begin(); items.end() != iter; ++iter )
@@ -287,7 +309,7 @@ Dali::Toolkit::ItemView ItemView::New(ItemFactory& factory)
 }
 
 ItemView::ItemView(ItemFactory& factory)
-: Scrollable( ControlBehaviour( DISABLE_SIZE_NEGOTIATION | REQUIRES_WHEEL_EVENTS | REQUIRES_KEYBOARD_NAVIGATION_SUPPORT ) ),
+: Scrollable( ControlBehaviour( DISABLE_SIZE_NEGOTIATION | DISABLE_STYLE_CHANGE_SIGNALS | REQUIRES_WHEEL_EVENTS | REQUIRES_KEYBOARD_NAVIGATION_SUPPORT ) ),
   mItemFactory(factory),
   mItemsParentOrigin(ParentOrigin::CENTER),
   mItemsAnchorPoint(AnchorPoint::CENTER),
@@ -309,6 +331,7 @@ ItemView::ItemView(ItemFactory& factory)
   mIsFlicking(false),
   mAddingItems(false),
   mRefreshEnabled(true),
+  mRefreshNotificationEnabled(true),
   mInAnimation(false)
 {
 }
@@ -320,6 +343,7 @@ void ItemView::OnInitialize()
   Vector2 stageSize = Stage::GetCurrent().GetSize();
   mWheelScrollDistanceStep = stageSize.y * DEFAULT_WHEEL_SCROLL_DISTANCE_STEP_PROPORTION;
 
+  self.TouchSignal().Connect( this, &ItemView::OnTouch );
   EnableGestureDetection(Gesture::Type(Gesture::Pan));
 
   mWheelEventFinishedTimer = Timer::New( WHEEL_EVENT_FINISHED_TIME_OUT );
@@ -394,11 +418,11 @@ void ItemView::ActivateLayout(unsigned int layoutIndex, const Vector3& targetSiz
     // Remove constraints from previous layout
     actor.RemoveConstraints();
 
+    mActiveLayout->ApplyConstraints(actor, itemId, targetSize, Self() );
+
     Vector3 size;
     mActiveLayout->GetItemSize( itemId, targetSize, size );
     actor.SetSize( size.GetVectorXY() );
-
-    mActiveLayout->ApplyConstraints(actor, itemId, targetSize, Self() );
   }
 
   // Refresh the new layout
@@ -465,14 +489,17 @@ void ItemView::DeactivateCurrentLayout()
 
 void ItemView::OnRefreshNotification(PropertyNotification& source)
 {
-  // Cancel scroll animation to prevent any fighting of setting the scroll position property by scroll bar during fast scroll.
-  if(!mRefreshEnabled && mScrollAnimation)
+  if( mRefreshNotificationEnabled )
   {
-    RemoveAnimation(mScrollAnimation);
-  }
+    // Cancel scroll animation to prevent any fighting of setting the scroll position property by scroll bar during fast scroll.
+    if(!mRefreshEnabled && mScrollAnimation)
+    {
+      RemoveAnimation(mScrollAnimation);
+    }
 
-  // Only cache extra items when it is not a fast scroll
-  DoRefresh(GetCurrentLayoutPosition(0), mRefreshEnabled || mScrollAnimation);
+    // Only cache extra items when it is not a fast scroll
+    DoRefresh(GetCurrentLayoutPosition(0), mRefreshEnabled || mScrollAnimation);
+  }
 }
 
 void ItemView::Refresh()
@@ -972,37 +999,6 @@ void ItemView::OnChildAdd(Actor& child)
   }
 }
 
-bool ItemView::OnTouchEvent(const TouchEvent& event)
-{
-  // Ignore events with multiple-touch points
-  if (event.GetPointCount() != 1)
-  {
-    return false;
-  }
-
-  if (event.GetPoint(0).state == TouchPoint::Down)
-  {
-    // Cancel ongoing scrolling etc.
-    mGestureState = Gesture::Clear;
-
-    mScrollDistance = 0.0f;
-    mScrollSpeed = 0.0f;
-    Self().SetProperty(Toolkit::ItemView::Property::SCROLL_SPEED, mScrollSpeed);
-
-    mScrollOvershoot = 0.0f;
-    AnimateScrollOvershoot(0.0f);
-
-    if(mScrollAnimation)
-    {
-      mScrollCompletedSignal.Emit(GetCurrentScrollPosition());
-    }
-
-    RemoveAnimation(mScrollAnimation);
-  }
-
-  return true; // consume since we're potentially scrolling
-}
-
 bool ItemView::OnWheelEvent(const WheelEvent& event)
 {
   // Respond the wheel event to scroll
@@ -1095,6 +1091,37 @@ float ItemView::ClampFirstItemPosition( float targetPosition, const Vector3& tar
   return clamppedPosition;
 }
 
+bool ItemView::OnTouch( Actor actor, const TouchData& touch )
+{
+  // Ignore events with multiple-touch points
+  if (touch.GetPointCount() != 1)
+  {
+    return false;
+  }
+
+  if ( touch.GetState( 0 ) == PointState::DOWN )
+  {
+    // Cancel ongoing scrolling etc.
+    mGestureState = Gesture::Clear;
+
+    mScrollDistance = 0.0f;
+    mScrollSpeed = 0.0f;
+    Self().SetProperty(Toolkit::ItemView::Property::SCROLL_SPEED, mScrollSpeed);
+
+    mScrollOvershoot = 0.0f;
+    AnimateScrollOvershoot(0.0f);
+
+    if(mScrollAnimation)
+    {
+      mScrollCompletedSignal.Emit(GetCurrentScrollPosition());
+    }
+
+    RemoveAnimation(mScrollAnimation);
+  }
+
+  return true; // consume since we're potentially scrolling
+}
+
 void ItemView::OnPan( const PanGesture& gesture )
 {
   Actor self = Self();
@@ -1372,7 +1399,7 @@ void ItemView::ScrollToItem(unsigned int itemId, float durationSeconds)
   {
     RemoveAnimation(mScrollAnimation);
     mScrollAnimation = Animation::New(durationSeconds);
-    mScrollAnimation.AnimateTo( Property(self, Toolkit::ItemView::Property::LAYOUT_POSITION), firstItemScrollPosition, AlphaFunction::EASE_OUT );
+    mScrollAnimation.AnimateTo( Property(self, Toolkit::ItemView::Property::LAYOUT_POSITION), firstItemScrollPosition, mScrollToAlphaFunction );
     mScrollAnimation.FinishedSignal().Connect(this, &ItemView::OnScrollFinished);
     mScrollAnimation.Play();
   }
@@ -1432,16 +1459,6 @@ void ItemView::CalculateDomainSize(const Vector3& layoutSize)
   }
 }
 
-Vector2 ItemView::GetDomainSize() const
-{
-  Actor self = Self();
-
-  float minScrollPosition = self.GetProperty<float>(Toolkit::Scrollable::Property::SCROLL_POSITION_MIN_Y);
-  float maxScrollPosition = self.GetProperty<float>(Toolkit::Scrollable::Property::SCROLL_POSITION_MAX_Y);
-
-  return Vector2(0.0f, fabs(GetScrollPosition(minScrollPosition, self.GetCurrentSize()) - GetScrollPosition(-maxScrollPosition, self.GetCurrentSize())));
-}
-
 bool ItemView::IsLayoutScrollable(const Vector3& layoutSize)
 {
   Actor self = Self();
@@ -1486,7 +1503,7 @@ void ItemView::ScrollTo(const Vector2& position, float duration)
   {
     RemoveAnimation(mScrollAnimation);
     mScrollAnimation = Animation::New(duration);
-    mScrollAnimation.AnimateTo( Property(self, Toolkit::ItemView::Property::LAYOUT_POSITION), firstItemScrollPosition, AlphaFunction::EASE_OUT );
+    mScrollAnimation.AnimateTo( Property(self, Toolkit::ItemView::Property::LAYOUT_POSITION), firstItemScrollPosition, mScrollToAlphaFunction );
     mScrollAnimation.FinishedSignal().Connect(this, &ItemView::OnScrollFinished);
     mScrollAnimation.Play();
   }
@@ -1692,6 +1709,215 @@ bool ItemView::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface*
   return connected;
 }
 
+void ItemView::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value )
+{
+  Toolkit::ItemView itemView = Toolkit::ItemView::DownCast( Dali::BaseHandle( object ) );
+
+  if( itemView )
+  {
+    ItemView& itemViewImpl( GetImpl( itemView ) );
+    switch( index )
+    {
+      case Toolkit::ItemView::Property::MINIMUM_SWIPE_SPEED:
+      {
+        itemViewImpl.SetMinimumSwipeSpeed( value.Get<float>() );
+        break;
+      }
+      case Toolkit::ItemView::Property::MINIMUM_SWIPE_DISTANCE:
+      {
+        itemViewImpl.SetMinimumSwipeDistance( value.Get<float>() );
+        break;
+      }
+      case Toolkit::ItemView::Property::WHEEL_SCROLL_DISTANCE_STEP:
+      {
+        itemViewImpl.SetWheelScrollDistanceStep( value.Get<float>() );
+        break;
+      }
+      case Toolkit::ItemView::Property::SNAP_TO_ITEM_ENABLED:
+      {
+        itemViewImpl.SetAnchoring( value.Get<bool>() );
+        break;
+      }
+      case Toolkit::ItemView::Property::REFRESH_INTERVAL:
+      {
+        itemViewImpl.SetRefreshInterval( value.Get<float>() );
+        break;
+      }
+      case Toolkit::DevelItemView::Property::LAYOUT:
+      {
+        // Get a Property::Array from the property if possible.
+        Property::Array layoutArray;
+        if( value.Get( layoutArray ) )
+        {
+          itemViewImpl.SetLayoutArray( layoutArray );
+        }
+        break;
+      }
+    }
+  }
+}
+
+Property::Array ItemView::GetLayoutArray()
+{
+  return mlayoutArray;
+}
+
+void ItemView::SetLayoutArray( const Property::Array& layouts )
+{
+  mlayoutArray = layouts;
+  const int layoutCount = GetLayoutCount();
+  if( layoutCount > 0 )
+  {
+    for(int index = layoutCount - 1; index >= 0; --index)
+    {
+      RemoveLayout(index);
+      if(index == 0) break;
+    }
+  }
+
+  for( unsigned int arrayIdx = 0, arrayCount = layouts.Count(); arrayIdx < arrayCount; ++arrayIdx )
+  {
+    const Property::Value& element = layouts.GetElementAt( arrayIdx );
+
+    Property::Map* layout = element.GetMap();
+    if( layout != NULL )
+    {
+      for( unsigned int mapIdx = 0, mapCount = (*layout).Count(); mapIdx < mapCount; ++mapIdx )
+      {
+        KeyValuePair propertyPair( (*layout).GetKeyValue( mapIdx ) );
+
+        if(propertyPair.first == DefaultItemLayoutProperty::TYPE)
+        {
+          int layoutType = propertyPair.second.Get<int>();
+          if(layoutType <= DefaultItemLayout::SPIRAL && layoutType >= DefaultItemLayout::DEPTH)
+          {
+            //DEPTH, GRID, LIST, SPIRAL
+            switch(DefaultItemLayout::Type(layoutType))
+            {
+              case DefaultItemLayout::DEPTH:
+              {
+                Internal::DepthLayoutPtr depthLayout = Internal::DepthLayout::New();
+                (*depthLayout).SetLayoutProperties(*layout);
+                AddLayout(*depthLayout);
+                break;
+              }
+              case DefaultItemLayout::GRID:
+              {
+                Internal::GridLayoutPtr gridLayout = Internal::GridLayout::New();
+                (*gridLayout).SetLayoutProperties(*layout);
+                AddLayout(*gridLayout);
+                break;
+              }
+              case DefaultItemLayout::LIST:
+              {
+                Internal::GridLayoutPtr listLayout = Internal::GridLayout::New();
+                listLayout->SetNumberOfColumns( 1 );
+                (*listLayout).SetLayoutProperties(*layout);
+                AddLayout(*listLayout);
+                break;
+              }
+              case DefaultItemLayout::SPIRAL:
+              {
+                Internal::SpiralLayoutPtr spiralLayout = Internal::SpiralLayout::New();
+                (*spiralLayout).SetLayoutProperties(*layout);
+                AddLayout(*spiralLayout);
+                break;
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+}
+
+Property::Value ItemView::GetProperty( BaseObject* object, Property::Index index )
+{
+  Property::Value value;
+
+  Toolkit::ItemView itemView = Toolkit::ItemView::DownCast( Dali::BaseHandle( object ) );
+
+  if( itemView )
+  {
+    ItemView& itemViewImpl( GetImpl( itemView ) );
+    switch( index )
+    {
+      case Toolkit::ItemView::Property::MINIMUM_SWIPE_SPEED:
+      {
+        value = itemViewImpl.GetMinimumSwipeSpeed();
+        break;
+      }
+      case Toolkit::ItemView::Property::MINIMUM_SWIPE_DISTANCE:
+      {
+        value = itemViewImpl.GetMinimumSwipeDistance();
+        break;
+      }
+      case Toolkit::ItemView::Property::WHEEL_SCROLL_DISTANCE_STEP:
+      {
+        value = itemViewImpl.GetWheelScrollDistanceStep();
+        break;
+      }
+      case Toolkit::ItemView::Property::SNAP_TO_ITEM_ENABLED:
+      {
+        value = itemViewImpl.GetAnchoring();
+        break;
+      }
+      case Toolkit::ItemView::Property::REFRESH_INTERVAL:
+      {
+        value = itemViewImpl.GetRefreshInterval();
+        break;
+      }
+      case Toolkit::DevelItemView::Property::LAYOUT:
+      {
+        Property::Array layouts= itemViewImpl.GetLayoutArray();
+        value = layouts;
+        break;
+      }
+
+    }
+  }
+
+  return value;
+}
+
+bool ItemView::DoAction( BaseObject* object, const std::string& actionName, const Property::Map& attributes )
+{
+  Dali::BaseHandle handle( object );
+
+  Toolkit::ItemView itemView = Toolkit::ItemView::DownCast( handle );
+
+  DALI_ASSERT_ALWAYS( itemView );
+
+  if( 0 == strcmp( actionName.c_str(), ACTION_STOP_SCROLLING ) )
+  {
+    GetImpl( itemView ).DoStopScrolling();
+  }
+  else if ( 0 == strcmp( actionName.c_str(), ACTION_ENABLE_REFRESH ) )
+  {
+    GetImpl( itemView ).SetRefreshNotificationEnabled( true );
+  }
+  else if ( 0 == strcmp( actionName.c_str(), ACTION_DISABLE_REFRESH ) )
+  {
+    GetImpl( itemView ).SetRefreshNotificationEnabled( false );
+  }
+
+  return true;
+}
+
+void ItemView::DoStopScrolling()
+{
+  if( mScrollAnimation )
+  {
+    mScrollAnimation.Stop();
+    mScrollAnimation.Reset();
+  }
+}
+
+void ItemView::SetRefreshNotificationEnabled( bool enabled )
+{
+  mRefreshNotificationEnabled = enabled;
+}
+
 } // namespace Internal
 
 } // namespace Toolkit