JavaScript binding for ItemView 22/56422/15
authorRichard Huang <r.huang@samsung.com>
Thu, 7 Jan 2016 16:05:12 +0000 (16:05 +0000)
committerRichard Huang <r.huang@samsung.com>
Tue, 19 Jan 2016 15:28:22 +0000 (07:28 -0800)
Change-Id: If4ba2434a2ea7a22cacd13d431dbe54bf56540b9

41 files changed:
dali-toolkit/internal/controls/scrollable/item-view/item-view-impl.cpp
dali-toolkit/internal/controls/scrollable/item-view/item-view-impl.h
dali-toolkit/internal/controls/scrollable/scrollable-impl.cpp
dali-toolkit/public-api/controls/scrollable/item-view/item-view.h
dali-toolkit/public-api/controls/scrollable/scrollable.h
docs/content/images/item-view/list.png [new file with mode: 0755]
node-addon/binding.gyp
node-addon/examples/images/icon-0.png [new file with mode: 0755]
node-addon/examples/images/icon-1.png [new file with mode: 0755]
node-addon/examples/images/icon-2.png [new file with mode: 0755]
node-addon/examples/images/image-1.jpg [moved from node-addon/image-1.jpg with 100% similarity]
node-addon/examples/images/image-2.jpg [moved from node-addon/image-2.jpg with 100% similarity]
node-addon/examples/item-view.js [new file with mode: 0644]
node-addon/examples/line-mesh.js [moved from node-addon/line-mesh.js with 98% similarity]
node-addon/examples/mesh-morph.js [moved from node-addon/mesh-morph.js with 99% similarity]
node-addon/examples/point-mesh.js [moved from node-addon/point-mesh.js with 98% similarity]
node-addon/examples/scripts/item-template.json [new file with mode: 0644]
node-addon/examples/texture-mesh.js [moved from node-addon/texture-mesh.js with 98% similarity]
node-addon/item-template.json [new file with mode: 0644]
packaging/dali-addon.spec
plugins/dali-script-v8/docs/content/constants.js
plugins/dali-script-v8/docs/content/item-factory.js [new file with mode: 0644]
plugins/dali-script-v8/docs/content/item-view.js [new file with mode: 0644]
plugins/dali-script-v8/file.list
plugins/dali-script-v8/src/actors/actor-api.cpp
plugins/dali-script-v8/src/actors/actor-api.h
plugins/dali-script-v8/src/actors/actor-wrapper.cpp
plugins/dali-script-v8/src/actors/actor-wrapper.h
plugins/dali-script-v8/src/constants/constants-wrapper.cpp
plugins/dali-script-v8/src/controls/control-wrapper.cpp [new file with mode: 0644]
plugins/dali-script-v8/src/controls/control-wrapper.h [new file with mode: 0644]
plugins/dali-script-v8/src/controls/item-factory-wrapper.cpp [new file with mode: 0644]
plugins/dali-script-v8/src/controls/item-factory-wrapper.h [new file with mode: 0644]
plugins/dali-script-v8/src/controls/item-view-api.cpp [new file with mode: 0644]
plugins/dali-script-v8/src/controls/item-view-api.h [new file with mode: 0644]
plugins/dali-script-v8/src/dali-wrapper.cpp
plugins/dali-script-v8/src/object/handle-wrapper.cpp
plugins/dali-script-v8/src/object/handle-wrapper.h
plugins/dali-script-v8/src/shared/base-wrapped-object.h
plugins/dali-script-v8/src/utils/v8-utils.cpp
plugins/dali-script-v8/src/utils/v8-utils.h

index aa6443d..86a869e 100644 (file)
@@ -42,21 +42,6 @@ using namespace Dali;
 namespace // Unnamed namespace
 {
 
 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;
 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 +241,27 @@ namespace Internal
 namespace // unnamed namespace
 {
 
 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,     WHELL_SCROLL_DISTANCE_SPEED  )
+DALI_PROPERTY_REGISTRATION( Toolkit, ItemView, "snapToItemEnabled",          BOOLEAN,   SNAP_TO_ITEM_ENABLED         )
+DALI_PROPERTY_REGISTRATION( Toolkit, ItemView, "refreshInterval",            FLOAT,     REFRESH_INTERVAL             )
+
+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()
+
 bool FindById( const ItemContainer& items, ItemId id )
 {
   for( ConstItemIter iter = items.begin(); items.end() != iter; ++iter )
 bool FindById( const ItemContainer& items, ItemId id )
 {
   for( ConstItemIter iter = items.begin(); items.end() != iter; ++iter )
@@ -1692,6 +1698,86 @@ bool ItemView::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface*
   return connected;
 }
 
   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::WHELL_SCROLL_DISTANCE_SPEED:
+      {
+        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;
+      }
+    }
+  }
+}
+
+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::WHELL_SCROLL_DISTANCE_SPEED:
+      {
+        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;
+      }
+    }
+  }
+
+  return value;
+}
+
 } // namespace Internal
 
 } // namespace Toolkit
 } // namespace Internal
 
 } // namespace Toolkit
index a18618d..2b3a52f 100644 (file)
@@ -308,6 +308,24 @@ public:
    */
   static bool DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor );
 
    */
   static bool DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor );
 
+  //properties
+
+  /**
+   * Called when a property of an object of this type is set.
+   * @param[in] object The object whose property is set.
+   * @param[in] index The property index.
+   * @param[in] value The new property value.
+   */
+  static void SetProperty( BaseObject* object, Property::Index index, const Property::Value& value );
+
+  /**
+   * Called to retrieve a property of an object of this type.
+   * @param[in] object The object whose property is to be retrieved.
+   * @param[in] index The property index.
+   * @return The current value of the property.
+   */
+  static Property::Value GetProperty( BaseObject* object, Property::Index index );
+
 private:
 
   /**
 private:
 
   /**
index 98ab55b..e1f79ca 100644 (file)
@@ -48,7 +48,8 @@ DALI_TYPE_REGISTRATION_BEGIN( Toolkit::Scrollable, Toolkit::Control, Create );
 
 DALI_PROPERTY_REGISTRATION( Toolkit, Scrollable, "overshootEffectColor",      VECTOR4, OVERSHOOT_EFFECT_COLOR    )
 DALI_PROPERTY_REGISTRATION( Toolkit, Scrollable, "overshootAnimationSpeed",   FLOAT,   OVERSHOOT_ANIMATION_SPEED )
 
 DALI_PROPERTY_REGISTRATION( Toolkit, Scrollable, "overshootEffectColor",      VECTOR4, OVERSHOOT_EFFECT_COLOR    )
 DALI_PROPERTY_REGISTRATION( Toolkit, Scrollable, "overshootAnimationSpeed",   FLOAT,   OVERSHOOT_ANIMATION_SPEED )
-const int OVERSHOOT_SIZE = Dali::Toolkit::Scrollable::Property::OVERSHOOT_ANIMATION_SPEED + 1; // OVERSHOOT_SIZE is not public yet
+DALI_PROPERTY_REGISTRATION( Toolkit, Scrollable, "overshootEnabled",          BOOLEAN, OVERSHOOT_ENABLED )
+const int OVERSHOOT_SIZE = Dali::Toolkit::Scrollable::Property::OVERSHOOT_ENABLED + 1; // OVERSHOOT_SIZE is not public yet
 Dali::PropertyRegistration p1( typeRegistration, "overshootSize",  OVERSHOOT_SIZE, Property::VECTOR2, Dali::Toolkit::Internal::Scrollable::SetProperty, Dali::Toolkit::Internal::Scrollable::GetProperty );
 
 DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, Scrollable, "scrollRelativePosition",   VECTOR2, SCROLL_RELATIVE_POSITION)
 Dali::PropertyRegistration p1( typeRegistration, "overshootSize",  OVERSHOOT_SIZE, Property::VECTOR2, Dali::Toolkit::Internal::Scrollable::SetProperty, Dali::Toolkit::Internal::Scrollable::GetProperty );
 
 DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, Scrollable, "scrollRelativePosition",   VECTOR2, SCROLL_RELATIVE_POSITION)
@@ -194,6 +195,11 @@ void Scrollable::SetProperty( BaseObject* object, Property::Index index, const P
         scrollableImpl.SetOvershootAnimationSpeed( value.Get<float>() );
         break;
       }
         scrollableImpl.SetOvershootAnimationSpeed( value.Get<float>() );
         break;
       }
+      case Toolkit::Scrollable::Property::OVERSHOOT_ENABLED:
+      {
+        scrollableImpl.SetOvershootEnabled( value.Get<bool>() );
+        break;
+      }
       case OVERSHOOT_SIZE: // OVERSHOOT_SIZE is not public yet
       {
         Vector2 input;
       case OVERSHOOT_SIZE: // OVERSHOOT_SIZE is not public yet
       {
         Vector2 input;
@@ -229,6 +235,11 @@ Property::Value Scrollable::GetProperty( BaseObject* object, Property::Index ind
         value = scrollableImpl.GetOvershootAnimationSpeed();
         break;
       }
         value = scrollableImpl.GetOvershootAnimationSpeed();
         break;
       }
+      case Toolkit::Scrollable::Property::OVERSHOOT_ENABLED:
+      {
+        value = scrollableImpl.IsOvershootEnabled();
+        break;
+      }
       case OVERSHOOT_SIZE: // OVERSHOOT_SIZE is not public yet
       {
         value = scrollableImpl.mOvershootSize;
       case OVERSHOOT_SIZE: // OVERSHOOT_SIZE is not public yet
       {
         value = scrollableImpl.mOvershootSize;
index e790a82..5431d25 100644 (file)
@@ -63,6 +63,9 @@ public:
 
   enum PropertyRange
   {
 
   enum PropertyRange
   {
+    PROPERTY_START_INDEX = Toolkit::Scrollable::PROPERTY_END_INDEX + 1,                        ///< @since DALi 1.1.18
+    PROPERTY_END_INDEX =   PROPERTY_START_INDEX + 1000,                                        ///< Reserve property indices, @since DALi 1.1.18
+
     ANIMATABLE_PROPERTY_START_INDEX = Toolkit::Scrollable::ANIMATABLE_PROPERTY_END_INDEX + 1,
     ANIMATABLE_PROPERTY_END_INDEX   = ANIMATABLE_PROPERTY_START_INDEX + 1000                   ///< Reserve animatable property indices
   };
     ANIMATABLE_PROPERTY_START_INDEX = Toolkit::Scrollable::ANIMATABLE_PROPERTY_END_INDEX + 1,
     ANIMATABLE_PROPERTY_END_INDEX   = ANIMATABLE_PROPERTY_START_INDEX + 1000                   ///< Reserve animatable property indices
   };
@@ -74,12 +77,20 @@ public:
   {
     enum
     {
   {
     enum
     {
-      LAYOUT_POSITION = ANIMATABLE_PROPERTY_START_INDEX, ///< Property, name "layoutPosition",        type float
-      SCROLL_SPEED,                                      ///< Property, name "scrollSpeed",           type float
-      OVERSHOOT,                                         ///< Property, name "overshoot",             type float
-      SCROLL_DIRECTION,                                  ///< Property, name "scrollDirection",       type Vector2
-      LAYOUT_ORIENTATION,                                ///< Property, name "layoutOrientation",     type integer
-      SCROLL_CONTENT_SIZE                                ///< Property, name "scrollContentSize",     type float
+      // Event side properties
+      MINIMUM_SWIPE_SPEED = PROPERTY_START_INDEX,        ///< Property, name "minimumSwipeSpeed",        @see SetMinimumSwipeSpeed(),       type float,    @since DALi 1.1.18
+      MINIMUM_SWIPE_DISTANCE,                            ///< Property, name "minimumSwipeDistance",     @see SetMinimumSwipeDistance(),    type float,    @since DALi 1.1.18
+      WHELL_SCROLL_DISTANCE_SPEED,                       ///< Property, name "wheelScrollDistanceStep",  @see SetWheelScrollDistanceStep(), type float,    @since DALi 1.1.18
+      SNAP_TO_ITEM_ENABLED,                              ///< Property, name "snapToItemEnabled",        @see SetAnchoring(),               type bool,     @since DALi 1.1.18
+      REFRESH_INTERVAL,                                  ///< Property, name "refreshInterval",          @see SetRefreshInterval(),         type float,    @since DALi 1.1.18
+
+      // Animatable properties
+      LAYOUT_POSITION = ANIMATABLE_PROPERTY_START_INDEX, ///< Property, name "layoutPosition",           type float
+      SCROLL_SPEED,                                      ///< Property, name "scrollSpeed",              type float
+      OVERSHOOT,                                         ///< Property, name "overshoot",                type float
+      SCROLL_DIRECTION,                                  ///< Property, name "scrollDirection",          type Vector2
+      LAYOUT_ORIENTATION,                                ///< Property, name "layoutOrientation",        type integer
+      SCROLL_CONTENT_SIZE                                ///< Property, name "scrollContentSize",        type float
     };
   };
 
     };
   };
 
index 76dbb07..3c22468 100644 (file)
@@ -58,8 +58,8 @@ public:
    */
   enum PropertyRange
   {
    */
   enum PropertyRange
   {
-    PROPERTY_START_INDEX = Control::CONTROL_PROPERTY_END_INDEX + 1,
-    PROPERTY_END_INDEX =   PROPERTY_START_INDEX + 1000,             ///< Reserve property indices
+    PROPERTY_START_INDEX = Control::CONTROL_PROPERTY_END_INDEX + 1, ///< @since DALi 1.1.18
+    PROPERTY_END_INDEX =   PROPERTY_START_INDEX + 1000,             ///< Reserve property indices, @since DALi 1.1.18
 
     ANIMATABLE_PROPERTY_START_INDEX = ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX,
     ANIMATABLE_PROPERTY_END_INDEX =   ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX + 1000              ///< Reserve animatable property indices
 
     ANIMATABLE_PROPERTY_START_INDEX = ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX,
     ANIMATABLE_PROPERTY_END_INDEX =   ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX + 1000              ///< Reserve animatable property indices
@@ -75,6 +75,7 @@ public:
       // Event side properties
       OVERSHOOT_EFFECT_COLOR = PROPERTY_START_INDEX, ///< Property, name "overshootEffectColor",      @see SetOvershootEffectColor(),    type Vector4
       OVERSHOOT_ANIMATION_SPEED,                     ///< Property, name "overshootAnimationSpeed",   @see SetOvershootAnimationSpeed(), type float
       // Event side properties
       OVERSHOOT_EFFECT_COLOR = PROPERTY_START_INDEX, ///< Property, name "overshootEffectColor",      @see SetOvershootEffectColor(),    type Vector4
       OVERSHOOT_ANIMATION_SPEED,                     ///< Property, name "overshootAnimationSpeed",   @see SetOvershootAnimationSpeed(), type float
+      OVERSHOOT_ENABLED,                             ///< Property, name "overshootEnabled",          @see SetOvershootEnabled(),        type bool,    @since DALi 1.1.18
 
       // Animatable properties
       SCROLL_RELATIVE_POSITION = ANIMATABLE_PROPERTY_START_INDEX, ///< Property, name "scrollRelativePosition",   type Vector2
 
       // Animatable properties
       SCROLL_RELATIVE_POSITION = ANIMATABLE_PROPERTY_START_INDEX, ///< Property, name "scrollRelativePosition",   type Vector2
diff --git a/docs/content/images/item-view/list.png b/docs/content/images/item-view/list.png
new file mode 100755 (executable)
index 0000000..d588929
Binary files /dev/null and b/docs/content/images/item-view/list.png differ
index dad473d..142cc74 100644 (file)
@@ -18,6 +18,9 @@
       '<(DALI_JS_DIR)/actors/layer-api.cpp',
       '<(DALI_JS_DIR)/actors/camera-actor-api.cpp',
       '<(DALI_JS_DIR)/constants/constants-wrapper.cpp',
       '<(DALI_JS_DIR)/actors/layer-api.cpp',
       '<(DALI_JS_DIR)/actors/camera-actor-api.cpp',
       '<(DALI_JS_DIR)/constants/constants-wrapper.cpp',
+      '<(DALI_JS_DIR)/controls/control-wrapper.cpp',
+      '<(DALI_JS_DIR)/controls/item-factory-wrapper.cpp',
+      '<(DALI_JS_DIR)/controls/item-view-api.cpp',
       '<(DALI_JS_DIR)/animation/animation-api.cpp',
       '<(DALI_JS_DIR)/animation/animation-wrapper.cpp',
       '<(DALI_JS_DIR)/animation/constrainer-api.cpp',
       '<(DALI_JS_DIR)/animation/animation-api.cpp',
       '<(DALI_JS_DIR)/animation/animation-wrapper.cpp',
       '<(DALI_JS_DIR)/animation/constrainer-api.cpp',
diff --git a/node-addon/examples/images/icon-0.png b/node-addon/examples/images/icon-0.png
new file mode 100755 (executable)
index 0000000..8d300e9
Binary files /dev/null and b/node-addon/examples/images/icon-0.png differ
diff --git a/node-addon/examples/images/icon-1.png b/node-addon/examples/images/icon-1.png
new file mode 100755 (executable)
index 0000000..bfed8ac
Binary files /dev/null and b/node-addon/examples/images/icon-1.png differ
diff --git a/node-addon/examples/images/icon-2.png b/node-addon/examples/images/icon-2.png
new file mode 100755 (executable)
index 0000000..db892fb
Binary files /dev/null and b/node-addon/examples/images/icon-2.png differ
diff --git a/node-addon/examples/item-view.js b/node-addon/examples/item-view.js
new file mode 100644 (file)
index 0000000..5abfcfc
--- /dev/null
@@ -0,0 +1,142 @@
+ var window= {
+           x:0,
+           y:0,
+           width:1920,
+           height: 1080,
+           transparent: false,
+           name:'itemview-example'
+ };
+
+ var viewMode={
+       'stereoscopic-mode':'mono', // stereo-horizontal, stereo-vertical, stereo-interlaced,
+       'stereoBase': 65 // Distance in millimeters between left/right cameras typically between (50-70mm)
+ };
+
+ var options= {
+    'window': window,
+    'viewMode': viewMode,
+ }
+
+//desktop
+//var dali = require('../build/Release/dali')( options );
+
+//target
+var dali = require('dali')( options );
+
+var items = [];
+var button;
+var stageSize;
+
+var itemView;
+var itemFactory;
+
+var currentLayoutIndex = 0;
+var totalItemCount = 100;
+
+var imageDir = "./images/";
+
+var daliApp = {};
+
+daliApp.createItemView = function() {
+
+  // Create item view data
+  var itemViewData = [];
+  for (var itemId = 0; itemId < totalItemCount; itemId++)
+  {
+    var data = {};
+    data["template"] = "template-item-list"; // Create items initially with list template
+    data["icon_path"] = imageDir + "icon-" + itemId % 3 + ".png";
+    data["title_text"] = "Item " + itemId;
+    itemViewData[itemId] = data;
+  }
+
+  // Create item factory and set the data
+  itemFactory = new dali.ItemFactory();
+  itemFactory.jsonTemplateFile = "./scripts/item-template.json";
+  itemFactory.data = itemViewData;
+
+  // Create item view
+  stageSize = dali.stage.getSize();
+  itemView = new dali.Control("ItemView", itemFactory);
+  itemView.size = [stageSize.x, stageSize.y, 0.0];
+  itemView.parentOrigin = dali.CENTER_LEFT;
+  itemView.anchorPoint = dali.CENTER_LEFT;
+  itemView.refreshInterval = 4.0;
+
+  // Add item view to the stage
+  dali.stage.add( itemView );
+
+  // Create scroll bar for item view
+  var scrollBar = new dali.Control("ScrollBar");
+  scrollBar.parentOrigin = dali.TOP_RIGHT;
+  scrollBar.anchorPoint = dali.TOP_RIGHT;
+  scrollBar.widthResizePolicy = "FIT_TO_CHILDREN";
+  scrollBar.heightResizePolicy = "FILL_TO_PARENT";
+  itemView.add(scrollBar);
+
+  // Add the list and grid layouts
+  itemView.addLayout(dali.ITEM_LAYOUT_LIST); // layout index 0
+  itemView.addLayout(dali.ITEM_LAYOUT_GRID); // layout index 1
+
+  // Set custom item size for list layout
+  itemView.setItemSize(0, [stageSize.x, stageSize.y * 0.1, 0.0]);
+
+  // Set custom item size for grid layout
+  var layoutMargin = 120;
+  itemView.setItemSize(1, [(stageSize.x - layoutMargin) / 4, stageSize.y * 0.2, 0.0]);
+
+  // Activate the list layout
+  itemView.activateLayout(0, itemView.size);
+
+  // Create button for layout switching
+  button = new dali.Control("PushButton");
+  button.size = [100.0, 60.0, 0.0];
+  button.position = [-20.0, 20.0, 0.0];
+  button.parentOrigin = dali.TOP_RIGHT;
+  button.anchorPoint = dali.TOP_RIGHT;
+  button.labelText = "Switch";
+  dali.stage.add( button );
+
+  // Connect a signal callback to button pressed signal
+  button.on("pressed", daliApp.buttonPressedEvent);
+}
+
+daliApp.buttonPressedEvent = function( button ) {
+
+  // Calculate the layout index for the next layout to switch to
+  currentLayoutIndex++;
+  currentLayoutIndex = currentLayoutIndex % itemView.getLayoutCount();
+
+  // Activate the next layout
+  itemView.activateLayout(currentLayoutIndex, [stageSize.x, stageSize.y, 0.0], 0.0);
+
+  // Change the item template in item view data as we want to change the layout of the items
+  var data = itemFactory.data;
+  for (var itemId = 0; itemId < totalItemCount; itemId++)
+  {
+    if(currentLayoutIndex == 0)
+    {
+      // List layout
+      data[itemId]["template"] = "template-item-list"; // Create items with list template
+    }
+    else
+    {
+      // Grid layout
+      data[itemId]["template"] = "template-item-grid"; // Create items with grid template
+    }
+  }
+  itemFactory.data = data;
+}
+
+function startup()
+{
+  daliApp.init();
+}
+
+daliApp.init = function()
+{
+  daliApp.createItemView();
+}
+
+startup();
+
similarity index 98%
rename from node-addon/line-mesh.js
rename to node-addon/examples/line-mesh.js
index f1c9532..faaedb9 100644 (file)
@@ -18,7 +18,7 @@
  }
 
 // desktop
  }
 
 // desktop
-//var dali = require('./build/Release/dali')( options );
+//var dali = require('../build/Release/dali')( options );
 
 // target
 var dali = require('dali')( options );
 
 // target
 var dali = require('dali')( options );
similarity index 99%
rename from node-addon/mesh-morph.js
rename to node-addon/examples/mesh-morph.js
index dd4527a..edbdcf9 100644 (file)
@@ -17,9 +17,8 @@
     'view-mode': viewMode,
  }
 
     'view-mode': viewMode,
  }
 
-
 // desktop
 // desktop
-//var dali = require('./build/Release/dali')( options );
+//var dali = require('../build/Release/dali')( options );
 
 // target
 var dali = require('dali')( options );
 
 // target
 var dali = require('dali')( options );
similarity index 98%
rename from node-addon/point-mesh.js
rename to node-addon/examples/point-mesh.js
index f9c7186..ceb9b1e 100644 (file)
     'view-mode': viewMode,
  }
 
     'view-mode': viewMode,
  }
 
-var imageDir = "./";
+var imageDir = "./images/";
 
 
 // desktop
 
 
 // desktop
-//var dali = require('./build/Release/dali')( options );
+//var dali = require('../build/Release/dali')( options );
 
 // target
 var dali = require('dali')( options );
 
 // target
 var dali = require('dali')( options );
diff --git a/node-addon/examples/scripts/item-template.json b/node-addon/examples/scripts/item-template.json
new file mode 100644 (file)
index 0000000..f909edd
--- /dev/null
@@ -0,0 +1,92 @@
+{
+  "templates":
+  {
+    "template-item-list":
+    {
+      "name":"item",
+      "type":"Actor",
+      "position":[0,0,0],
+      "anchorPoint":"TOP_LEFT",
+      "parentOrigin":"TOP_LEFT",
+      "actors":
+       [
+        {
+          "name":"icon",
+          "type":"ImageView",
+          "image":
+          {
+            "rendererType" : "imageRenderer",
+            "imageUrl": "{icon_path}"
+          },
+          "position":[20.0, 0.0, 0.0],
+          "size":[70.0, 70.0, 0.0],
+          "color":[1.0,1.0,1.0,1.0],
+          "anchorPoint":"CENTER_LEFT",
+          "parentOrigin":"CENTER_LEFT",
+          "actors":
+          [
+            {
+              "name":"title",
+              "anchorPoint":"CENTER_LEFT",
+              "parentOrigin":"CENTER_RIGHT",
+              "type":"TextLabel",
+              "position": [30.0, 0.0, 0.0],
+              "size":[200.0, 70.0, 0.0],
+              "pointSize":30,
+              "fontFamily":"HelveticaNeue",
+              "fontStyle":"Bold",
+              "horizontalAlignment":"BEGIN",
+              "verticalAlignment":"CENTER",
+              "textColor": [1.0,0.0,1.0,1.0],
+              "text":"{title_text}"
+            }
+          ]
+        }
+      ]
+    },
+
+    "template-item-grid":
+    {
+      "name":"item",
+      "type":"Actor",
+      "position":[0,0,0],
+      "anchorPoint":"TOP_LEFT",
+      "parentOrigin":"TOP_LEFT",
+      "actors":
+       [
+        {
+          "name":"icon",
+          "type":"ImageView",
+          "image":
+          {
+            "rendererType" : "imageRenderer",
+            "imageUrl": "{icon_path}"
+          },
+          "position":[0.0, -10.0, 0.0],
+          "size":[70.0, 70.0, 0.0],
+          "color":[1.0,1.0,1.0,1.0],
+          "anchorPoint":"CENTER",
+          "parentOrigin":"CENTER",
+          "actors":
+          [
+            {
+              "name":"title",
+              "anchorPoint":"TOP_CENTER",
+              "parentOrigin":"BOTTOM_CENTER",
+              "type":"TextLabel",
+              "position": [0.0,10.0,0.0],
+              "size":[100.0, 100.0, 0.0],
+              "pointSize":22,
+              "fontFamily":"HelveticaNeue",
+              "fontStyle":"Bold",
+              "horizontalAlignment":"CENTER",
+              "textColor": [1.0,0.0,1.0,1.0],
+              "text":"{title_text}"
+            }
+          ]
+        }
+      ]
+    }
+  }
+}
+
similarity index 98%
rename from node-addon/texture-mesh.js
rename to node-addon/examples/texture-mesh.js
index 7f6173e..016a7a9 100644 (file)
     'view-mode': viewMode,
  }
 
     'view-mode': viewMode,
  }
 
-var imageDir = "./";
+var imageDir = "./images/";
 
 
 // desktop
 
 
 // desktop
-//var dali = require('./build/Release/dali')( options );
+//var dali = require('../build/Release/dali')( options );
 
 // target
 var dali = require('dali')( options );
 
 // target
 var dali = require('dali')( options );
diff --git a/node-addon/item-template.json b/node-addon/item-template.json
new file mode 100644 (file)
index 0000000..f909edd
--- /dev/null
@@ -0,0 +1,92 @@
+{
+  "templates":
+  {
+    "template-item-list":
+    {
+      "name":"item",
+      "type":"Actor",
+      "position":[0,0,0],
+      "anchorPoint":"TOP_LEFT",
+      "parentOrigin":"TOP_LEFT",
+      "actors":
+       [
+        {
+          "name":"icon",
+          "type":"ImageView",
+          "image":
+          {
+            "rendererType" : "imageRenderer",
+            "imageUrl": "{icon_path}"
+          },
+          "position":[20.0, 0.0, 0.0],
+          "size":[70.0, 70.0, 0.0],
+          "color":[1.0,1.0,1.0,1.0],
+          "anchorPoint":"CENTER_LEFT",
+          "parentOrigin":"CENTER_LEFT",
+          "actors":
+          [
+            {
+              "name":"title",
+              "anchorPoint":"CENTER_LEFT",
+              "parentOrigin":"CENTER_RIGHT",
+              "type":"TextLabel",
+              "position": [30.0, 0.0, 0.0],
+              "size":[200.0, 70.0, 0.0],
+              "pointSize":30,
+              "fontFamily":"HelveticaNeue",
+              "fontStyle":"Bold",
+              "horizontalAlignment":"BEGIN",
+              "verticalAlignment":"CENTER",
+              "textColor": [1.0,0.0,1.0,1.0],
+              "text":"{title_text}"
+            }
+          ]
+        }
+      ]
+    },
+
+    "template-item-grid":
+    {
+      "name":"item",
+      "type":"Actor",
+      "position":[0,0,0],
+      "anchorPoint":"TOP_LEFT",
+      "parentOrigin":"TOP_LEFT",
+      "actors":
+       [
+        {
+          "name":"icon",
+          "type":"ImageView",
+          "image":
+          {
+            "rendererType" : "imageRenderer",
+            "imageUrl": "{icon_path}"
+          },
+          "position":[0.0, -10.0, 0.0],
+          "size":[70.0, 70.0, 0.0],
+          "color":[1.0,1.0,1.0,1.0],
+          "anchorPoint":"CENTER",
+          "parentOrigin":"CENTER",
+          "actors":
+          [
+            {
+              "name":"title",
+              "anchorPoint":"TOP_CENTER",
+              "parentOrigin":"BOTTOM_CENTER",
+              "type":"TextLabel",
+              "position": [0.0,10.0,0.0],
+              "size":[100.0, 100.0, 0.0],
+              "pointSize":22,
+              "fontFamily":"HelveticaNeue",
+              "fontStyle":"Bold",
+              "horizontalAlignment":"CENTER",
+              "textColor": [1.0,0.0,1.0,1.0],
+              "text":"{title_text}"
+            }
+          ]
+        }
+      ]
+    }
+  }
+}
+
index 7bb302f..22bfeae 100644 (file)
@@ -69,7 +69,7 @@ rm -rf %{buildroot}
 
 cd "%{addonBuildDir}"
 %make_install
 
 cd "%{addonBuildDir}"
 %make_install
-cp %{addonDir}/line-mesh.js %{installDir}/line-mesh.js
+cp -R %{addonDir}/examples %{installDir}/examples
 
 
 %clean
 
 
 %clean
index d321285..a09ed33 100644 (file)
@@ -184,6 +184,13 @@ Constants accessible under the dali global object.
 |PROPERTY_ARRAY                       | integer value  |
 |PROPERTY_MAP                         | integer value  |
 |PROPERTY_INVALID_INDEX               | integer value  |
 |PROPERTY_ARRAY                       | integer value  |
 |PROPERTY_MAP                         | integer value  |
 |PROPERTY_INVALID_INDEX               | integer value  |
+|PROPERTY_READ_ONLY                   | integer value  |
+|PROPERTY_READ_WRITE                  | integer value  |
+|PROPERTY_ANIMATABLE                  | integer value  |
+
+|**Item layout type ** | |
+|ITEM_LAYOUT_LIST                     | integer value  |
+|ITEM_LAYOUT_GRID                     | integer value  |
 
  * @class Constants
  */
 
  * @class Constants
  */
diff --git a/plugins/dali-script-v8/docs/content/item-factory.js b/plugins/dali-script-v8/docs/content/item-factory.js
new file mode 100644 (file)
index 0000000..b7ae5ab
--- /dev/null
@@ -0,0 +1,177 @@
+/**
+ *
+## ItemFactory API
+
+ ItemFactory is for storing the data of {{#crossLink "ItemView"}}ItemView{{/crossLink}}
+ and creating actors for ItemView on request. Each item in ItemView is identified by a
+ unique ID, and has a linear order from 0.
+ A JSON file should be provided to ItemFactory which defines the templates of items
+ to be used to create the actors. Multiple templates can be defined in the JSON file
+ for different type of items.
+### Simple example of creating a JSON template for items
+```
+  {
+    "templates":
+    {
+      "template-item":
+      {
+        "name":"item",
+        "type":"Actor",
+        "position":[0,0,0],
+        "anchorPoint":"TOP_LEFT",
+        "parentOrigin":"TOP_LEFT",
+        "actors":
+         [
+          {
+            "name":"icon",
+            "type":"ImageView",
+            "image":
+            {
+              "rendererType" : "imageRenderer",
+              "imageUrl": "{icon_path}"
+            },
+            "position":[20.0, 0.0, 0.0],
+            "size":[70.0, 70.0, 0.0],
+            "color":[1.0,1.0,1.0,1.0],
+            "anchorPoint":"CENTER_LEFT",
+            "parentOrigin":"CENTER_LEFT",
+            "actors":
+            [
+              {
+                "name":"title",
+                "anchorPoint":"CENTER_LEFT",
+                "parentOrigin":"CENTER_RIGHT",
+                "type":"TextLabel",
+                "position": [30.0, 0.0, 0.0],
+                "size":[200.0, 70.0, 0.0],
+                "pointSize":30,
+                "fontFamily":"HelveticaNeue",
+                "fontStyle":"Bold",
+                "horizontalAlignment":"BEGIN",
+                "verticalAlignment":"CENTER",
+                "textColor": [1.0,0.0,1.0,1.0],
+                "text":"{title_text}"
+              }
+            ]
+          }
+        ]
+      }
+    }
+  }
+```
+ The data of items should be provided to ItemFactory as an array of property maps
+ in which each map contains the data for each item, including the template to be used
+ to build the actor and the pairs of key/value to be used to replace the constants
+ defined in the template. The order of property maps in the array represents the actual
+ order of items in ItemView.
+ ### Example of defining the data of an ItemView with two items
+```
+  var itemViewData = [
+                       { "template" : "template-item",
+                         "icon_path" : "icon0.png",
+                         "title_text" : "Item 0" },
+                       { "template" : "template-item",
+                         "icon_path" : "icon1.png",
+                         "title_text" : "Item 1" }
+                     ];
+```
+ This means ItemFactory will use the template "template-item" defined in the JSON file
+ to create the item for ItemView and replace the constants "icon_path" and "title_text"
+ in the template with their actual values, e.g. "icon0.png" and "Item 0". Each item can
+ have different template and different data.
+ ### Example of creating an ItemFactory with the above JSON template and link it with an ItemView
+
+![ ](../assets/img/item-view/list.png)
+
+```
+  // Define the data of 100 items
+  var itemViewData = [];
+  for (var itemId = 0; itemId < 100; itemId++)
+  {
+    var itemData = {};
+    itemData["template"] = "template-item";
+    itemData["icon_path"] = "icon" + itemId + ".png";
+    itemData["title_text"] = "Item " + itemId;
+    itemViewData[itemId] = itemData;
+  }
+  // Create the item factory and set the JSON template file and item view data
+  var itemFactory = new dali.ItemFactory();
+  itemFactory.jsonTemplateFile = "./item-template.json"; // Set the JSON template file
+  itemFactory.data = itemViewData; // Set the ItemView data
+  // Create the item view with the given item factory
+  var itemView = new dali.Control("ItemView", itemFactory);
+  itemView.size = [stageSize.x, stageSize.y, 0.0];
+  itemView.parentOrigin = dali.CENTER_LEFT;
+  itemView.anchorPoint = dali.CENTER_LEFT;
+  dali.stage.add( itemView );
+
+  // Add a list layout to ItemView (multiple layouts can be added to the same ItemView)
+  itemView.addLayout(dali.ITEM_LAYOUT_LIST);
+  // Set custom item size for the list layout
+  // If set, this will overide the predefined item size in the list layout
+  itemView.setItemSize(0, [350, 100, 0]); // 0 means the first layout added to ItemView
+  // Acticate the list layout (which will layout the items as a list)
+  itemView.activateLayout(0, itemView.size); // 0 means the first layout added to ItemView
+```
+ ### Example of changing the data of items in ItemView dynamically
+```
+  var data = itemFactory.data;
+  data[itemId]["icon_path"] = "new-icon.png";
+  data[itemId]["title_text"] = "New Item";
+  itemFactory.data = data; // ItemView will update the changed items immediately
+```
+ @class ItemFactory
+
+*/
+
+/**
+ * Sets the file name of JSON template that contains the templates for items.
+ *
+ * @example
+ *    itemFactory.jsonTemplateFile = "item-template.json"; // ItemFactory will look for the template from this JSON file
+ *
+ * @type String
+ * @property jsonTemplateFile
+ */
+JSON_TEMPLATE_FILE
+
+/**
+ * Sets the data of ItemView
+ *
+ *  The data is an array of property maps in which each map contains the data
+ *  for each item, including the template to be used to build the actor and
+ *  the pairs of key/value to be used to replace the constants defined in the
+ *  template. The order of property maps in the array represents the actual
+ *  order of items in ItemView.
+ *
+ * @example
+ *   var itemViewData = [
+ *                        { "template" : "template-item",
+ *                          "icon_path" : "icon0.png",
+ *                          "title_text" : "Item 0" },
+ *                        { "template" : "template-item",
+ *                          "icon_path" : "icon1.png",
+ *                          "title_text" : "Item 1" }
+ *                     ];
+ *
+ *    itemFactory.data = itemViewData; // ItemFactory will look for the template from this JSON file
+ *
+ * @type Array
+ * @property data
+ */
+DATA
diff --git a/plugins/dali-script-v8/docs/content/item-view.js b/plugins/dali-script-v8/docs/content/item-view.js
new file mode 100644 (file)
index 0000000..776c5ea
--- /dev/null
@@ -0,0 +1,62 @@
+/**
+ *
+## ItemView API
+
+ ItemView is a scrollable layout container with built-in layouts to determine
+ the logical position of each item in a layout.
+ Actors are provided from an external {{#crossLink "ItemFactory"}}ItemFactory{{/crossLink}},
+ to display the currently visible items. ItemFactory is for storing the data of ItemView and
+ creating actors for ItemView on request. Each item in ItemView is identified by a unique ID,
+ and has a linear order from 0.
+ ### Example of creating an ItemView (see {{#crossLink "ItemFactory"}}ItemFactory{{/crossLink}} API for a full example)
+```
+  // Define the data of 100 items
+  var itemViewData = [];
+  for (var itemId = 0; itemId < 100; itemId++)
+  {
+    var itemData = {};
+    itemData["template"] = "template-item";
+    itemData["title_text"] = "Item " + itemId;
+    itemViewData[itemId] = itemData;
+  }
+  // Create an item factory and set the JSON template file and item view data
+  var itemFactory = new dali.ItemFactory();
+  itemFactory.jsonTemplateFile = "./item-template.json"; // Set the JSON template file
+  itemFactory.data = itemViewData; // Set the ItemView data
+  // Create the item view with the given item factory
+  var itemView = new dali.Control("ItemView", itemFactory);
+  itemView.size = [stageSize.x, stageSize.y, 0.0];
+  itemView.parentOrigin = dali.CENTER_LEFT;
+  itemView.anchorPoint = dali.CENTER_LEFT;
+  dali.stage.add( itemView );
+  // Add a scroll bar to ItemView (optional)
+  var scrollBar = new dali.Control("ScrollBar");
+  scrollBar.parentOrigin = dali.TOP_RIGHT;
+  scrollBar.anchorPoint = dali.TOP_RIGHT;
+  scrollBar.widthResizePolicy = "FIT_TO_CHILDREN";
+  scrollBar.heightResizePolicy = "FILL_TO_PARENT";
+  scrollBar.indicatorHeightPolicy = "Fixed";
+  scrollBar.indicatorFixedHeight = 60.0;
+  itemView.add(scrollBar);
+  // Add a list layout to ItemView (multiple layouts can be added to the same ItemView)
+  itemView.addLayout(dali.ITEM_LAYOUT_LIST);
+  // Set custom item size for the list layout
+  // If set, this will overide the predefined item size in the list layout
+  itemView.setItemSize(0, [350, 100, 0]); // 0 means the first layout added to ItemView
+  // Acticate the list layout (which will layout the items as a list)
+  itemView.activateLayout(0, itemView.size); // 0 means the first layout added to ItemView
+```
+ @class ItemView
+ @extends Actor
+
+*/
index e50d5cd..598d90e 100644 (file)
@@ -13,6 +13,9 @@ script_v8_plugin_src_files = \
    $(v8_plugin_dir)/actors/actor-api.cpp \
    $(v8_plugin_dir)/actors/layer-api.cpp \
    $(v8_plugin_dir)/actors/camera-actor-api.cpp \
    $(v8_plugin_dir)/actors/actor-api.cpp \
    $(v8_plugin_dir)/actors/layer-api.cpp \
    $(v8_plugin_dir)/actors/camera-actor-api.cpp \
+   $(v8_plugin_dir)/controls/control-wrapper.cpp \
+   $(v8_plugin_dir)/controls/item-factory-wrapper.cpp \
+   $(v8_plugin_dir)/controls/item-view-api.cpp \
    $(v8_plugin_dir)/constants/constants-wrapper.cpp \
    $(v8_plugin_dir)/animation/animation-api.cpp \
    $(v8_plugin_dir)/animation/animation-wrapper.cpp \
    $(v8_plugin_dir)/constants/constants-wrapper.cpp \
    $(v8_plugin_dir)/animation/animation-api.cpp \
    $(v8_plugin_dir)/animation/animation-wrapper.cpp \
index 5bac818..371639d 100644 (file)
@@ -36,21 +36,14 @@ namespace V8Plugin
 
 namespace  // unanmed namespace
 {
 
 namespace  // unanmed namespace
 {
+
 Actor GetActor( v8::Isolate* isolate, const v8::FunctionCallbackInfo<v8::Value>& args )
 {
   HandleWrapper* handleWrapper = HandleWrapper::Unwrap( isolate, args.This() );
   return Actor::DownCast( handleWrapper->mHandle );
 }
 Actor GetActor( v8::Isolate* isolate, const v8::FunctionCallbackInfo<v8::Value>& args )
 {
   HandleWrapper* handleWrapper = HandleWrapper::Unwrap( isolate, args.This() );
   return Actor::DownCast( handleWrapper->mHandle );
 }
-} //unanmed namespace
-
 
 
-namespace TextLabelApi
-{
- Actor New( const v8::FunctionCallbackInfo< v8::Value >& args )
- {
-   return Dali::Toolkit::TextLabel::New();
- }
-}
+} //unanmed namespace
 
 /***************************************
  * ACTOR API FUNCTIONS
 
 /***************************************
  * ACTOR API FUNCTIONS
@@ -279,7 +272,7 @@ void ActorApi::GetChildCount( const v8::FunctionCallbackInfo<v8::Value>& args )
 }
 
 /**
 }
 
 /**
- * Retrieve and child actor by index.
+ * Retrieve a child actor by index.
  *
  * @for Actor
  * @method getChildAt
  *
  * @for Actor
  * @method getChildAt
index 26f8991..bcd600e 100644 (file)
@@ -28,14 +28,6 @@ namespace Dali
 namespace V8Plugin
 {
 
 namespace V8Plugin
 {
 
-namespace TextLabelApi
-{
-  /**
-   * Temporary TextView constructor
-   */
-  Actor New( const v8::FunctionCallbackInfo< v8::Value >& args );
-}
-
 namespace ActorApi
 {
 
 namespace ActorApi
 {
 
index 336ed23..a1c0f78 100644 (file)
@@ -84,7 +84,7 @@ struct ActorApiStruct
 
 /**
  * Lookup table to match a actor type with a constructor and supported API's.
 
 /**
  * Lookup table to match a actor type with a constructor and supported API's.
- * HandleWrapper::ActorType is used to index this table
+ * ActorWrapper::ActorType is used to index this table
  */
 const ActorApiStruct ActorApiLookup[]=
 {
  */
 const ActorApiStruct ActorApiLookup[]=
 {
@@ -305,7 +305,7 @@ v8::Handle<v8::Object> ActorWrapper::WrapActor( v8::Isolate* isolate, Actor acto
   // create an instance of the template
   v8::Local<v8::Object> localObject = objectTemplate->NewInstance();
 
   // create an instance of the template
   v8::Local<v8::Object> localObject = objectTemplate->NewInstance();
 
-  // create teh actor object
+  // create the actor object
   ActorWrapper* pointer = new ActorWrapper( actor, Dali::V8Plugin::DaliWrapper::Get().GetDaliGarbageCollector() );
 
   // assign the JavaScript object to the wrapper.
   ActorWrapper* pointer = new ActorWrapper( actor, Dali::V8Plugin::DaliWrapper::Get().GetDaliGarbageCollector() );
 
   // assign the JavaScript object to the wrapper.
@@ -392,42 +392,6 @@ void ActorWrapper::NewActor( const v8::FunctionCallbackInfo< v8::Value >& args)
   args.GetReturnValue().Set( localObject );
 }
 
   args.GetReturnValue().Set( localObject );
 }
 
-void ActorWrapper::NewControl( const v8::FunctionCallbackInfo< v8::Value >& args)
-{
-  v8::Isolate* isolate = args.GetIsolate();
-  v8::HandleScope handleScope( isolate );
-
-  if( !args.IsConstructCall() )
-  {
-    DALI_SCRIPT_EXCEPTION( isolate, "constructor called without 'new" );
-    return;
-  }
-
-  bool found( false );
-  std::string controlName = V8Utils::GetStringParameter( PARAMETER_0, found, isolate,  args );
-
-  if( !found )
-  {
-    DALI_SCRIPT_EXCEPTION( isolate, "missing control name" );
-    return;
-  }
-  Actor control;
-  Dali::TypeInfo typeInfo = Dali::TypeRegistry::Get().GetTypeInfo( controlName );
-  if( typeInfo ) // handle, check if it has a value
-  {
-    Dali::BaseHandle handle = typeInfo.CreateInstance();
-    if( handle )
-    {
-      control = Actor::DownCast( handle );
-    }
-  }
-
-  v8::Local<v8::Object> localObject = WrapActor( isolate, control, ACTOR );
-
-  args.GetReturnValue().Set( localObject );
-}
-
-
 /**
  * given an actor type name, e.g. CameraActor returns the type, e.g. ActorWrapper::CAMERA_ACTOR
  */
 /**
  * given an actor type name, e.g. CameraActor returns the type, e.g. ActorWrapper::CAMERA_ACTOR
  */
@@ -443,8 +407,6 @@ ActorWrapper::ActorType ActorWrapper::GetActorType( const std::string& name )
   return ActorWrapper::UNKNOWN_ACTOR;
 }
 
   return ActorWrapper::UNKNOWN_ACTOR;
 }
 
-
-
 } // namespace V8Plugin
 
 } // namespace Dali
 } // namespace V8Plugin
 
 } // namespace Dali
index fd12185..e84559f 100644 (file)
@@ -76,13 +76,6 @@ public:
   static void NewActor( const v8::FunctionCallbackInfo< v8::Value >& args);
 
   /**
   static void NewActor( const v8::FunctionCallbackInfo< v8::Value >& args);
 
   /**
-   * @brief Creates a new Control wrapped inside a Javascript Object.
-   * @note: the control type is passed as a parameter e.g. 'TextField'
-   * @param[in] args v8 function call arguments interpreted
-   */
-  static void NewControl( const v8::FunctionCallbackInfo< v8::Value >& args);
-
-  /**
    * @brief Wraps an actor of a given type
    */
   static v8::Handle<v8::Object> WrapActor(v8::Isolate* isolate, Dali::Actor actor,ActorType actorType);
    * @brief Wraps an actor of a given type
    */
   static v8::Handle<v8::Object> WrapActor(v8::Isolate* isolate, Dali::Actor actor,ActorType actorType);
@@ -107,14 +100,16 @@ public:
    */
   static ActorWrapper::ActorType GetActorType( const std::string& name );
 
    */
   static ActorWrapper::ActorType GetActorType( const std::string& name );
 
-private:
+protected:
 
   /**
 
   /**
-   * Helper to make the actor template
+   * @brief Helper to make the actor template
    *
    */
   static v8::Handle<v8::ObjectTemplate> MakeDaliActorTemplate( v8::Isolate* isolate, ActorType actorType );
 
    *
    */
   static v8::Handle<v8::ObjectTemplate> MakeDaliActorTemplate( v8::Isolate* isolate, ActorType actorType );
 
+private:
+
   /**
    * Helper, get an actor template given an actor type
    */
   /**
    * Helper, get an actor template given an actor type
    */
index acaacb6..edbd62b 100644 (file)
@@ -35,6 +35,7 @@
 #include <dali/public-api/common/loading-state.h>
 #include <dali/devel-api/rendering/material.h>
 #include <dali/devel-api/rendering/geometry.h>
 #include <dali/public-api/common/loading-state.h>
 #include <dali/devel-api/rendering/material.h>
 #include <dali/devel-api/rendering/geometry.h>
+#include <dali-toolkit/public-api/controls/scrollable/item-view/default-item-layout.h>
 
 namespace Dali
 {
 
 namespace Dali
 {
@@ -243,6 +244,12 @@ const IntegerPair EnumTable[] =
     { "PROPERTY_ARRAY",                       Property::ARRAY          },
     { "PROPERTY_MAP",                         Property::MAP            },
     { "PROPERTY_INVALID_INDEX",               Property::INVALID_INDEX  },
     { "PROPERTY_ARRAY",                       Property::ARRAY          },
     { "PROPERTY_MAP",                         Property::MAP            },
     { "PROPERTY_INVALID_INDEX",               Property::INVALID_INDEX  },
+    { "PROPERTY_READ_ONLY",                   Property::READ_ONLY      },
+    { "PROPERTY_READ_WRITE",                  Property::READ_WRITE     },
+    { "PROPERTY_ANIMATABLE",                  Property::ANIMATABLE     },
+
+    { "ITEM_LAYOUT_LIST",                     Toolkit::DefaultItemLayout::LIST     },
+    { "ITEM_LAYOUT_GRID",                     Toolkit::DefaultItemLayout::GRID     },
 
 };
 const unsigned int EnumTableCount = sizeof(EnumTable)/sizeof(EnumTable[0]);
 
 };
 const unsigned int EnumTableCount = sizeof(EnumTable)/sizeof(EnumTable[0]);
diff --git a/plugins/dali-script-v8/src/controls/control-wrapper.cpp b/plugins/dali-script-v8/src/controls/control-wrapper.cpp
new file mode 100644 (file)
index 0000000..09093a2
--- /dev/null
@@ -0,0 +1,340 @@
+/*
+ * Copyright (c) 2015 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <actors/actor-wrapper.h>
+#include "control-wrapper.h"
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/object/type-registry.h>
+
+// INTERNAL INCLUDES
+#include <controls/item-view-api.h>
+#include <v8-utils.h>
+#include <dali-wrapper.h>
+
+namespace Dali
+{
+
+namespace V8Plugin
+{
+
+v8::Persistent<v8::ObjectTemplate> ControlWrapper::mControlTemplate;
+v8::Persistent<v8::ObjectTemplate> ControlWrapper::mItemViewTemplate;
+
+Vector< void* > ControlWrapper::mControlGarbageContainer;
+
+namespace
+{
+
+
+/**
+ * pointer to a persistent template handle
+ */
+struct ControlTemplate
+{
+  v8::Persistent<v8::ObjectTemplate>* controlTemplate;
+};
+
+/**
+ * array of templates for each type of control
+ */
+const ControlTemplate ControlTemplateLookup[]=
+{
+    { &ControlWrapper::mControlTemplate },        // CONTROL
+    { &ControlWrapper::mItemViewTemplate }        // ITEMVIEW
+};
+
+/**
+ * Bitmask of API's that an control can support
+ */
+enum ControlApiBitMask
+{
+  CONTROL_API             = 1 << 0,
+  ITEMVIEW_API            = 1 << 1
+};
+
+/**
+ * structure used for the ControlApiLookup.
+ */
+struct ControlApiStruct
+{
+  const char* controlName;
+  ControlWrapper::ControlType controlType;
+  Toolkit::Control (*constructor)( const v8::FunctionCallbackInfo< v8::Value >& args);
+  int supportApis;
+};
+
+/**
+ * Lookup table to match a control type with a constructor and supported API's.
+ * ControlWrapper::ControlType is used to index this table
+ */
+const ControlApiStruct ControlApiLookup[]=
+{
+  {"Control",      ControlWrapper::CONTROL,      NULL,                 CONTROL_API },
+  {"ItemView",     ControlWrapper::ITEMVIEW,     ItemViewApi::New,     CONTROL_API | ITEMVIEW_API },
+};
+
+const unsigned int ControlApiLookupCount = sizeof(ControlApiLookup)/sizeof(ControlApiLookup[0]);
+
+
+/**
+ * Creates a control given a type name
+ * Uses the type registry to create an control of the correct type
+ */
+Toolkit::Control CreateControl( const v8::FunctionCallbackInfo< v8::Value >& args,
+                        const std::string& typeName )
+{
+  Toolkit::Control control;
+
+  ControlWrapper::ControlType controlType = ControlWrapper::GetControlType( typeName );
+
+  // if we don't currently have specific binding for the given control type,
+  // try to use type registry to create it
+  if( controlType == ControlWrapper::UNKNOWN_CONTROL )
+  {
+    Dali::TypeInfo typeInfo = Dali::TypeRegistry::Get().GetTypeInfo( typeName );
+    if( typeInfo )
+    {
+      Dali::BaseHandle handle = typeInfo.CreateInstance();
+      if( handle )
+      {
+        control = Toolkit::Control::DownCast( handle );
+        if( !control )
+        {
+          DALI_SCRIPT_EXCEPTION( args.GetIsolate(), "Unknown control type" );
+          return Toolkit::Control();
+        }
+      }
+    }
+  }
+  else
+  {
+    // run the constructor for this type of control so it can pull out custom parameters
+    control = (ControlApiLookup[controlType].constructor)( args );
+  }
+
+  return control;
+}
+
+/**
+ * given a control type return what api's it supports
+ */
+int GetControlSupportedApis( ControlWrapper::ControlType type )
+{
+  return ControlApiLookup[type].supportApis;
+}
+
+/**
+ * Used for the ControlFunctionTable to map function names to functions
+ * with for a specific API
+ */
+struct ControlFunctions
+{
+  const char* name;               ///< function name
+  void (*function)( const v8::FunctionCallbackInfo< v8::Value >& args);
+  ControlApiBitMask api;
+};
+
+/**
+ * Contains a list of all functions that can be called in
+ * ItemView
+ */
+const ControlFunctions ControlFunctionTable[]=
+{
+
+    /**************************************
+     * ItemView  API
+     **************************************/
+    { "GetLayoutCount",                  ItemViewApi::GetLayoutCount,                   ITEMVIEW_API  },
+    { "AddLayout",                       ItemViewApi::AddLayout,                        ITEMVIEW_API  },
+    { "RemoveLayout",                    ItemViewApi::RemoveLayout,                     ITEMVIEW_API  },
+    { "ActivateLayout",                  ItemViewApi::ActivateLayout,                   ITEMVIEW_API  },
+    { "GetItemSize",                     ItemViewApi::GetItemSize,                      ITEMVIEW_API  },
+    { "SetItemSize",                     ItemViewApi::SetItemSize,                      ITEMVIEW_API  },
+    { "ScrollToItem",                    ItemViewApi::ScrollToItem,                     ITEMVIEW_API  },
+    { "GetItem",                         ItemViewApi::GetItem,                          ITEMVIEW_API  },
+    { "GetItemId",                       ItemViewApi::GetItemId,                        ITEMVIEW_API  },
+    { "GetItemsRange",                   ItemViewApi::GetItemsRange,                    ITEMVIEW_API  },
+
+};
+
+const unsigned int ControlFunctionTableCount = sizeof(ControlFunctionTable)/sizeof(ControlFunctionTable[0]);
+} //un-named space
+
+
+ControlWrapper::ControlWrapper( Toolkit::Control control,
+              GarbageCollectorInterface& gc )
+: ActorWrapper( control, gc ),
+  mControl( control )
+
+{
+}
+
+ControlWrapper::~ControlWrapper()
+{
+  mControlGarbageContainer.Release();
+}
+
+v8::Handle<v8::Object> ControlWrapper::WrapControl(v8::Isolate* isolate, Toolkit::Control control )
+{
+  v8::EscapableHandleScope handleScope( isolate );
+
+  // Check whether the control is a Control
+  ControlWrapper::ControlType controlType = GetControlType( control.GetTypeName() );
+
+  if( controlType == ControlWrapper::UNKNOWN_CONTROL && Toolkit::Control::DownCast(control) )
+  {
+    controlType = ControlWrapper::CONTROL;
+  }
+
+  v8::Local<v8::Object> object = WrapControl( isolate, control, controlType );
+
+  return handleScope.Escape( object );
+}
+
+Toolkit::Control ControlWrapper::GetControl()
+{
+  return mControl;
+}
+
+v8::Handle<v8::Object> ControlWrapper::WrapControl( v8::Isolate* isolate, Toolkit::Control control, ControlType controlType )
+{
+  v8::EscapableHandleScope handleScope( isolate );
+  v8::Local<v8::ObjectTemplate> objectTemplate;
+
+  objectTemplate = GetControlTemplate( isolate, controlType );
+
+  // create an instance of the template
+  v8::Local<v8::Object> localObject = objectTemplate->NewInstance();
+
+  // create the control object
+  ControlWrapper* pointer = new ControlWrapper( control, Dali::V8Plugin::DaliWrapper::Get().GetDaliGarbageCollector() );
+
+  // assign the JavaScript object to the wrapper.
+  // This also stores Dali object, in an internal field inside the JavaScript object.
+  pointer->SetJavascriptObject( isolate, localObject );
+
+  return handleScope.Escape( localObject );
+}
+
+v8::Local<v8::ObjectTemplate> ControlWrapper::GetControlTemplate( v8::Isolate* isolate, ControlWrapper::ControlType type )
+{
+  v8::EscapableHandleScope handleScope( isolate );
+  v8::Local<v8::ObjectTemplate> objectTemplate;
+
+  if( ControlTemplateLookup[type].controlTemplate->IsEmpty() )
+  {
+    objectTemplate = MakeDaliControlTemplate( isolate, type );
+    ControlTemplateLookup[type].controlTemplate->Reset( isolate, objectTemplate );
+  }
+  else
+  {
+    // get the object template
+    objectTemplate = v8::Local<v8::ObjectTemplate>::New( isolate, *ControlTemplateLookup[type].controlTemplate );
+  }
+
+  return handleScope.Escape( objectTemplate );
+}
+
+v8::Handle<v8::ObjectTemplate> ControlWrapper::MakeDaliControlTemplate( v8::Isolate* isolate, ControlType controlType )
+{
+  v8::EscapableHandleScope handleScope( isolate );
+
+  // all the controls support actor APIs
+  v8::Local<v8::ObjectTemplate> objTemplate = ActorWrapper::MakeDaliActorTemplate( isolate, ActorWrapper::ACTOR );
+
+  // find out what API's this control supports
+  int supportApis = GetControlSupportedApis( controlType );
+
+  // add our function properties
+  for( unsigned int i = 0; i < ControlFunctionTableCount; ++i )
+  {
+    const ControlFunctions property =  ControlFunctionTable[i];
+
+    // check to see if the control supports a certain type of API
+    // e.g. ItemView will support CONTROL_API and ITEMVIEW_API
+    if( supportApis &  property.api )
+    {
+      std::string funcName = V8Utils::GetJavaScriptFunctionName( property.name);
+
+      objTemplate->Set( v8::String::NewFromUtf8( isolate, funcName.c_str() ),
+                      v8::FunctionTemplate::New( isolate, property.function ) );
+    }
+  }
+
+  return handleScope.Escape( objTemplate );
+}
+
+void ControlWrapper::NewControl( const v8::FunctionCallbackInfo< v8::Value >& args)
+{
+  v8::Isolate* isolate = args.GetIsolate();
+  v8::HandleScope handleScope( isolate );
+
+  if( !args.IsConstructCall() )
+  {
+    DALI_SCRIPT_EXCEPTION( isolate, "constructor called without 'new" );
+    return;
+  }
+
+  bool found( false );
+  std::string controlName = V8Utils::GetStringParameter( PARAMETER_0, found, isolate,  args );
+
+  Toolkit::Control control;
+  if( found && controlName != ControlApiLookup[0].controlName )
+  {
+    control = CreateControl( args, controlName ); // create the control with the given type
+  }
+  else
+  {
+    control = Toolkit::Control::New(); // no given type, so create the base type of control
+  }
+
+  if( control )
+  {
+    v8::Local<v8::Object> localObject = WrapControl( isolate, control );
+    args.GetReturnValue().Set( localObject );
+  }
+  else
+  {
+    DALI_SCRIPT_EXCEPTION( isolate, "unsupported control type" );
+  }
+}
+
+/**
+ * Given a control type name, e.g. ItemView returns the type, e.g. ControlWrapper::ITEMVIEW
+ */
+ControlWrapper::ControlType ControlWrapper::GetControlType( const std::string& name )
+{
+  for( unsigned int i = 0 ; i < ControlApiLookupCount ; i++ )
+  {
+    if( ControlApiLookup[i].controlName == name )
+    {
+      return ControlApiLookup[i].controlType;
+    }
+  }
+  return ControlWrapper::UNKNOWN_CONTROL;
+}
+
+void ControlWrapper::RegisterGarbage(void* garbage)
+{
+  mControlGarbageContainer.PushBack(garbage);
+}
+
+} // namespace V8Plugin
+
+} // namespace Dali
diff --git a/plugins/dali-script-v8/src/controls/control-wrapper.h b/plugins/dali-script-v8/src/controls/control-wrapper.h
new file mode 100644 (file)
index 0000000..dc4b636
--- /dev/null
@@ -0,0 +1,127 @@
+#ifndef __DALI_V8PLUGIN_CONTROL_WRAPPER_H__
+#define __DALI_V8PLUGIN_CONTROL_WRAPPER_H__
+
+/*
+ * Copyright (c) 2015 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <v8.h>
+#include <dali/public-api/common/dali-vector.h>
+#include <dali-toolkit/public-api/controls/control.h>
+
+// INTERNAL INCLUDES
+#include <actors/actor-wrapper.h>
+
+namespace Dali
+{
+
+namespace V8Plugin
+{
+
+
+/**
+ * Wraps a Dali Control.
+ */
+class ControlWrapper : public ActorWrapper
+{
+
+public:
+
+  /**
+   * Control type used an index.
+   * These enums are used to index the ControlApiLookup table in control-wrapper.cpp.
+   * Any changes made must be reflected in the ControlApiLookup otherwise it may segfault when creating a control
+   */
+  enum ControlType
+  {
+    UNKNOWN_CONTROL = -1,
+    CONTROL         = 0,
+    ITEMVIEW        = 1
+  };
+
+  /**
+   * Constructor
+   * @param control DALi control
+   * @param gc garbage collection interface
+   */
+  ControlWrapper( Toolkit::Control control,
+                GarbageCollectorInterface& gc );
+
+  /**
+   * destructor
+   */
+  virtual ~ControlWrapper();
+
+  /**
+   * @brief Creates a new Control wrapped inside a Javascript Object.
+   * @note: the control type is passed as a parameter e.g. 'ItemView'
+   * @param[in] args v8 function call arguments interpreted
+   */
+  static void NewControl( const v8::FunctionCallbackInfo< v8::Value >& args);
+
+  /**
+   * @brief Wraps a control of a given type
+   */
+  static v8::Handle<v8::Object> WrapControl(v8::Isolate* isolate, Toolkit::Control control, ControlType controlType);
+
+  /**
+   * @brief Wraps a control, the type is looked up from the control
+   */
+  static v8::Handle<v8::Object> WrapControl(v8::Isolate* isolate, Toolkit::Control control );
+
+  // The Control ObjectTemplates.
+  static v8::Persistent<v8::ObjectTemplate> mControlTemplate;
+  static v8::Persistent<v8::ObjectTemplate> mItemViewTemplate;
+  static v8::Persistent<v8::ObjectTemplate> mScrollViewTemplate;
+
+  /**
+   * @return the wrapped control
+   */
+  Toolkit::Control GetControl();
+
+  /**
+   * @return the control type
+   */
+  static ControlWrapper::ControlType GetControlType( const std::string& name );
+
+  /**
+   * @brief Register the garbage to be released when the wrapped control is deleted.
+   */
+  static void RegisterGarbage(void* garbage);
+
+private:
+
+  /**
+   * Helper to make the control template
+   */
+  static v8::Handle<v8::ObjectTemplate> MakeDaliControlTemplate( v8::Isolate* isolate, ControlType controlType );
+
+  /**
+   * Helper, get a control template given a control type
+   */
+  static v8::Local<v8::ObjectTemplate> GetControlTemplate( v8::Isolate* isolate, ControlType type );
+
+  Toolkit::Control mControl;
+  static Vector< void* > mControlGarbageContainer;
+
+};
+
+} // namespace V8Plugin
+
+} // namespace Dali
+
+#endif // header
diff --git a/plugins/dali-script-v8/src/controls/item-factory-wrapper.cpp b/plugins/dali-script-v8/src/controls/item-factory-wrapper.cpp
new file mode 100644 (file)
index 0000000..62535cb
--- /dev/null
@@ -0,0 +1,467 @@
+/*
+ * Copyright (c) 2015 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include "item-factory-wrapper.h"
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/common/vector-wrapper.h>
+#include <dali/devel-api/object/weak-handle.h>
+#include <dali-toolkit/devel-api/builder/builder.h>
+#include <dali-toolkit/public-api/controls/scrollable/item-view/item-view.h>
+#include <dali-toolkit/public-api/controls/scrollable/item-view/item-layout.h>
+
+// INTERNAL INCLUDES
+#include <v8-utils.h>
+#include <dali-wrapper.h>
+#include <shared/api-function.h>
+#include <shared/object-template-helper.h>
+
+namespace Dali
+{
+
+namespace V8Plugin
+{
+
+v8::Persistent<v8::ObjectTemplate> ItemFactoryWrapper::mItemFactoryTemplate;
+
+namespace
+{
+
+typedef std::vector< Property::Map > ItemDataContainer;
+
+// Implementation of ItemFactory for providing actors to ItemView
+class ItemFactory : public Toolkit::ItemFactory
+{
+public:
+
+  /**
+   * Constructor
+   * @param application class, stored as reference
+   */
+  ItemFactory()
+  : mJsonFileLoaded(false),
+    mNumberOfItems(0)
+  {
+    mBuilder = Toolkit::Builder::New();
+  }
+
+  /**
+   * Set the name of the JSON file which defines the templates of items.
+   * @param jsonFile The JSON file
+   */
+  void SetJsonTemplateFile(std::string jsonFile)
+  {
+    if(mJsonFile != jsonFile)
+    {
+      mJsonFile = jsonFile;
+      LoadJsonFile(mJsonFile);
+
+      // Check whether any layout activated in ItemView
+      Toolkit::ItemView itemView = mItemView.GetHandle();
+      if(itemView && itemView.GetActiveLayout() != NULL)
+      {
+        // Refresh ItemView if item templates are changed
+        itemView.Refresh();
+      }
+    }
+  }
+
+  /**
+   * Returns the name of the JSON file.
+   * @return The JSON file name
+   */
+  std::string GetJsonTemplate()
+  {
+    return mJsonFile;
+  }
+
+  /**
+   * Set the data to be used to create new items.
+   *
+   * If ItemView is already created, this will immediately update ItemView with the
+   * new data.
+   *
+   * The data is an array of property maps in which each map contains the data for
+   * each item, including the template to be used to build the actor and the pairs
+   * of key/value to be used to replace the constants defined in the template.
+   * The order of property maps in the array represents the actual order of items
+   * in ItemView.
+   *
+   * @param data The array of property maps
+   */
+  void SetData(ItemDataContainer data)
+  {
+    ItemDataContainer currentData = mData;
+    mData = data;
+    mNumberOfItems = mData.size();
+
+    // Check whether any layout activated in ItemView
+    Toolkit::ItemView itemView = mItemView.GetHandle();
+    if(itemView && itemView.GetActiveLayout() != NULL)
+    {
+      unsigned int currentNumberOfItems = currentData.size();
+      unsigned int newNumberOfItems = data.size();
+
+      // Check whether any items added or deleted from the data
+      // which requires ItemView to be refreshed with the new data
+      if(currentNumberOfItems != newNumberOfItems)
+      {
+        itemView.Refresh();
+      }
+      else
+      {
+        for( unsigned int itemId = 0; itemId < newNumberOfItems; itemId++)
+        {
+          // Check whether the item is already built in ItemView
+          Actor itemActor = itemView.GetItem(itemId);
+          if(itemActor)
+          {
+            // Check if the item needs to be rebuilt
+            if( !V8Utils::IsPropertyMapIdentical(currentData[itemId], data[itemId]) )
+            {
+              // Rebuild the item with the new data
+              Actor newItemActor = NewItem(itemId);
+
+              // Replace the old item with the new one
+              itemView.ReplaceItem( Toolkit::Item( itemId, newItemActor ), 0.0f );
+            }
+          }
+        }
+      }
+    }
+  }
+
+  /**
+   * Retrieve the data.
+   * @return the data.
+   */
+  ItemDataContainer GetData()
+  {
+    return mData;
+  }
+
+  /**
+   * Store a weak handle of ItemView in order to access ItemView APIs
+   * from this ItemFactory implementation
+   * @return the data.
+   */
+  void SetItemView(Toolkit::ItemView itemView)
+  {
+    mItemView = itemView;
+  }
+
+public: // From Toolkit::ItemFactory
+
+  /**
+   * Query the number of items available from the factory.
+   * The maximum available item has an ID of GetNumberOfItems() - 1.
+   */
+  virtual unsigned int GetNumberOfItems()
+  {
+    return mJsonFileLoaded ? mNumberOfItems : 0;
+  }
+
+  /**
+   * Create an Actor to represent a visible item.
+   * @param itemId
+   * @return the created actor.
+   */
+  virtual Actor NewItem(unsigned int itemId)
+  {
+    std::string itemTemplate;
+
+    Property::Map constantsMap = mData[itemId];
+    for ( unsigned int i = 0, count = constantsMap.Count(); i < count; ++i )
+    {
+      Property::Value& constantValue = constantsMap.GetValue(i);
+      if(constantsMap.GetKey(i) == "template")
+      {
+        constantValue.Get(itemTemplate);
+      }
+      else
+      {
+        mBuilder.AddConstant( constantsMap.GetKey(i), constantValue );
+      }
+    }
+
+    Actor item = Actor::DownCast( mBuilder.Create(itemTemplate) );
+    return item;
+  }
+
+private:
+
+  /**
+   * Load the JSON file.
+   * @param The JSON file name
+   */
+  void LoadJsonFile(std::string jsonFile)
+  {
+    try
+    {
+      std::string data;
+      V8Utils::GetFileContents(jsonFile, data);
+
+      mBuilder.LoadFromString(data);
+
+      mJsonFileLoaded = true;
+    }
+    catch(...)
+    {
+//      printf("invalid JSON data\n");
+      mJsonFileLoaded = false;
+    }
+  }
+
+private:
+
+  std::string mJsonFile;
+  bool mJsonFileLoaded;
+  Toolkit::Builder mBuilder;
+  unsigned int mNumberOfItems;
+  ItemDataContainer mData;
+  WeakHandle< Toolkit::ItemView > mItemView;
+};
+
+} //un-named space
+
+ItemFactoryWrapper::ItemFactoryWrapper( Toolkit::ItemFactory& factory, GarbageCollectorInterface& gc )
+: BaseWrappedObject( BaseWrappedObject::ITEMFACTORY , gc ),
+  mItemFactory( factory )
+{
+}
+
+ItemFactoryWrapper::~ItemFactoryWrapper()
+{
+}
+
+v8::Handle<v8::Object> ItemFactoryWrapper::WrapItemFactory(v8::Isolate* isolate, Toolkit::ItemFactory& factory )
+{
+  v8::EscapableHandleScope handleScope( isolate );
+  v8::Local<v8::ObjectTemplate> objectTemplate;
+
+  objectTemplate = GetItemFactoryTemplate( isolate );
+
+  // create an instance of the template
+  v8::Local<v8::Object> localObject = objectTemplate->NewInstance();
+
+  // create the ItemFactory wrapper
+  ItemFactoryWrapper* pointer =  new ItemFactoryWrapper( factory, Dali::V8Plugin::DaliWrapper::Get().GetDaliGarbageCollector() );
+
+  // assign the JavaScript object to the wrapper.
+  pointer->SetJavascriptObject( isolate, localObject );
+
+  return handleScope.Escape( localObject );
+}
+
+v8::Local<v8::ObjectTemplate> ItemFactoryWrapper::GetItemFactoryTemplate( v8::Isolate* isolate)
+{
+  v8::EscapableHandleScope handleScope( isolate );
+  v8::Local<v8::ObjectTemplate> objectTemplate;
+
+  if( mItemFactoryTemplate.IsEmpty() )
+  {
+    objectTemplate = MakeItemFactoryTemplate( isolate );
+    mItemFactoryTemplate.Reset( isolate, objectTemplate );
+  }
+  else
+  {
+    // get the object template
+    objectTemplate = v8::Local<v8::ObjectTemplate>::New( isolate, mItemFactoryTemplate );
+  }
+  return handleScope.Escape( objectTemplate );
+}
+
+v8::Handle<v8::ObjectTemplate> ItemFactoryWrapper::MakeItemFactoryTemplate( v8::Isolate* isolate )
+{
+  v8::EscapableHandleScope handleScope( isolate );
+
+  v8::Local<v8::ObjectTemplate> objTemplate = v8::ObjectTemplate::New();
+
+  objTemplate->SetInternalFieldCount( BaseWrappedObject::FIELD_COUNT );
+
+  // set property setter and getter
+  objTemplate->SetNamedPropertyHandler( ItemFactoryWrapper::PropertyGet, ItemFactoryWrapper::PropertySet);
+
+  return handleScope.Escape( objTemplate );
+}
+
+void ItemFactoryWrapper::NewItemFactory( const v8::FunctionCallbackInfo< v8::Value >& args)
+{
+  v8::Isolate* isolate = args.GetIsolate();
+  v8::HandleScope handleScope( isolate);
+
+  if( !args.IsConstructCall() )
+  {
+    DALI_SCRIPT_EXCEPTION( isolate, "ItemFactory constructor called without 'new'" );
+    return;
+  }
+
+  Toolkit::ItemFactory* factory = new ItemFactory();
+
+  v8::Local<v8::Object> localObject = WrapItemFactory( isolate, *factory );
+  args.GetReturnValue().Set( localObject );
+}
+
+Toolkit::ItemFactory& ItemFactoryWrapper::GetItemFactoryFromParams( int paramIndex,
+                                             bool& found,
+                                             v8::Isolate* isolate,
+                                             const v8::FunctionCallbackInfo< v8::Value >& args )
+{
+  found = false;
+
+  v8::HandleScope handleScope( isolate );
+  BaseWrappedObject* wrappedObject = V8Utils::GetWrappedDaliObjectParameter( paramIndex, BaseWrappedObject::ITEMFACTORY, isolate, args );
+  if( wrappedObject )
+  {
+    found = true;
+    ItemFactoryWrapper* wrapper = static_cast< ItemFactoryWrapper *>(wrappedObject);
+    return wrapper->GetItemFactory();
+  }
+  else
+  {
+    DALI_SCRIPT_EXCEPTION( isolate, "no valid ItemFactory parameter" );
+    Toolkit::ItemFactory* dummyFactory = new ItemFactory();
+    return *dummyFactory; // avoid build error
+  }
+}
+
+ItemFactoryWrapper* ItemFactoryWrapper::Unwrap( v8::Isolate* isolate, v8::Handle< v8::Object> obj)
+{
+  v8::HandleScope handleScope( isolate );
+
+  v8::Local<v8::External> field = v8::Local<v8::External>::Cast( obj->GetInternalField(0) );
+  void* ptr = field->Value();
+  return static_cast< ItemFactoryWrapper *>(ptr);
+}
+
+void ItemFactoryWrapper::PropertyGet( v8::Local<v8::String> propertyName,
+                                        const v8::PropertyCallbackInfo<v8::Value>& info)
+{
+  v8::Isolate* isolate = info.GetIsolate();
+  v8::HandleScope handleScope( isolate );
+
+  // get the property name
+  std::string name = V8Utils::v8StringToStdString( propertyName );
+
+  if( std::isupper( name[0] ))
+  {
+    return;
+  }
+
+  // unwrap the object
+  ItemFactoryWrapper* itemFactoryWrapper = Unwrap( isolate, info.This() );
+  if( !itemFactoryWrapper )
+  {
+    return;
+  }
+
+  ItemFactory& factory = static_cast<ItemFactory&>( itemFactoryWrapper->GetItemFactory() );
+
+  if( name == "jsonTemplateFile" )
+  {
+    std::string jsonTemplateFile = factory.GetJsonTemplate();
+    info.GetReturnValue().Set(v8::String::NewFromUtf8(isolate, jsonTemplateFile.c_str()));
+  }
+  else if( name == "data" )
+  {
+    ItemDataContainer data = factory.GetData();
+    unsigned int itemCount = data.size();
+
+    v8::Local<v8::Array> array= v8::Array::New( isolate, itemCount );
+    for( unsigned int i = 0; i < itemCount; i++)
+    {
+      v8::Local<v8::Object> mapObject = v8::Object::New( isolate );
+      V8Utils::CreatePropertyMap( isolate, data[i], mapObject );
+
+      array->Set( i, mapObject);
+    }
+
+    info.GetReturnValue().Set(array);
+  }
+  else
+  {
+    std::string error="Invalid property Get for "+name + "\n";
+    DALI_SCRIPT_EXCEPTION( isolate, error );
+  }
+}
+
+void ItemFactoryWrapper::PropertySet( v8::Local<v8::String> propertyName,
+                  v8::Local<v8::Value> javaScriptValue,
+                  const v8::PropertyCallbackInfo<v8::Value>& info)
+{
+
+  v8::Isolate* isolate = info.GetIsolate();
+  v8::HandleScope handleScope( isolate );
+
+  // get the property name
+  std::string name = V8Utils::v8StringToStdString( propertyName );
+
+  // unwrap the object
+  ItemFactoryWrapper* itemFactoryWrapper = Unwrap( isolate, info.This() );
+  if( !itemFactoryWrapper )
+  {
+    return;
+  }
+
+  ItemFactory& factory = static_cast<ItemFactory&>( itemFactoryWrapper->GetItemFactory() );
+
+  if( name == "jsonTemplateFile" && javaScriptValue->IsString() )
+  {
+    std::string jsonTemplateFile = V8Utils::v8StringToStdString( javaScriptValue );
+    factory.SetJsonTemplateFile(jsonTemplateFile);
+  }
+  else if( name == "data" && javaScriptValue->IsArray() )
+  {
+    v8::Local<v8::Array> array = v8::Local<v8::Array>::Cast(javaScriptValue);
+
+    ItemDataContainer data;
+
+    for( unsigned int i = 0; i < array->Length(); ++i )
+    {
+      v8::Local<v8::Value> itemData = array->Get(i);
+
+      if( itemData->IsObject() )
+      {
+        Dali::Property::Map map = V8Utils::GetPropertyMapFromObject( isolate, itemData->ToObject() );
+        data.push_back(map);
+      }
+    }
+
+    factory.SetData(data);
+  }
+  else
+  {
+    std::string error = "Invalid property Set for " + name + "\n";
+    DALI_SCRIPT_EXCEPTION( isolate, error );
+  }
+}
+
+Toolkit::ItemFactory& ItemFactoryWrapper::GetItemFactory()
+{
+  return mItemFactory;
+}
+
+void ItemFactoryWrapper::SetItemView(Toolkit::ItemFactory& itemFactory, Toolkit::ItemView itemView)
+{
+  ItemFactory& factory = static_cast<ItemFactory&>( itemFactory );
+  factory.SetItemView(itemView);
+}
+
+} // namespace V8Plugin
+
+} // namespace Dali
diff --git a/plugins/dali-script-v8/src/controls/item-factory-wrapper.h b/plugins/dali-script-v8/src/controls/item-factory-wrapper.h
new file mode 100644 (file)
index 0000000..cfb21fb
--- /dev/null
@@ -0,0 +1,146 @@
+#ifndef __DALI_V8PLUGIN_ITEM_FACTORY_WRAPPER_H__
+#define __DALI_V8PLUGIN_ITEM_FACTORY_WRAPPER_H__
+
+/*
+ * Copyright (c) 2015 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <v8.h>
+#include <dali/public-api/common/dali-vector.h>
+#include <dali-toolkit/public-api/controls/scrollable/item-view/item-factory.h>
+#include <dali-toolkit/public-api/controls/scrollable/item-view/item-view.h>
+
+// INTERNAL INCLUDES
+#include <shared/base-wrapped-object.h>
+
+namespace Dali
+{
+
+namespace V8Plugin
+{
+
+
+/**
+ * Wraps a Dali ItemFactory.
+ */
+class ItemFactoryWrapper : public BaseWrappedObject
+{
+
+public:
+
+  /**
+   * Constructor
+   * @param factory DALi ItemFactory
+   * @param gc garbage collection interface
+   */
+  ItemFactoryWrapper( Toolkit::ItemFactory& factory,
+                GarbageCollectorInterface& gc );
+
+  /**
+   * destructor
+   */
+  virtual ~ItemFactoryWrapper();
+
+  /**
+   * @brief Creates a new ItemFactory wrapped inside a Javascript Object.
+   * @note: the item template and data are passed as a parameter e.g. 'template'
+   * @param[in] args v8 function call arguments interpreted
+   */
+  static void NewItemFactory( const v8::FunctionCallbackInfo< v8::Value >& args);
+
+  /**
+   * @brief Wraps an ItemFactory
+   */
+  static v8::Handle<v8::Object> WrapItemFactory(v8::Isolate* isolate, Toolkit::ItemFactory& factory );
+
+  // The ItemFactory ObjectTemplates.
+  static v8::Persistent<v8::ObjectTemplate> mItemFactoryTemplate;
+
+  /**
+   * @brief Helper to get ItemFactory from the JavaScript object held in the given function argument
+   * @param[in] paramIndex Argument index the object is held in
+   * @param[in] found Whether ItemFactory is found in the given function parameter
+   * @param[in] isolate v8 isolated instance
+   * @param[in] args v8 function call arguments interpreted
+   */
+  static Toolkit::ItemFactory& GetItemFactoryFromParams( int paramIndex,
+                                                             bool& found,
+                                                             v8::Isolate* isolate,
+                                                             const v8::FunctionCallbackInfo< v8::Value >& args );
+
+  /**
+   * @brief Helper to store a weak handle of ItemView in the given ItemFactory
+   * @param[in] itemFactory The item factory used to provide items to the given item view
+   * @param[in] itemView The ItemView which uses the given item factory to create items
+   */
+  static void SetItemView(Toolkit::ItemFactory& itemFactory, Toolkit::ItemView itemView);
+
+  /**
+   * @return the wrapped item factory
+   */
+  Toolkit::ItemFactory& GetItemFactory();
+
+private:
+
+  /**
+   * Helper to make the item factory template
+   */
+  static v8::Handle<v8::ObjectTemplate> MakeItemFactoryTemplate( v8::Isolate* isolate );
+
+  /**
+   * Helper, get a item factory template
+   */
+  static v8::Local<v8::ObjectTemplate> GetItemFactoryTemplate( v8::Isolate* isolate );
+
+  /**
+   * @brief get the value for a property for JavaScript object than contains a Dali ItemFactory.
+   * E.g. Get( "data", JavaScript object that wraps a Dali ItemFactory )
+   * @param[in] propertyName property name
+   * @param[in] info reference to PropertyCallbackInfo structure (contains the Javascript
+   * object and the return value).
+   */
+  static void PropertyGet( v8::Local<v8::String> propertyName,
+                              const v8::PropertyCallbackInfo<v8::Value>& info);
+
+  /**
+   * @brief Set the value for a property for JavaScript object than contains a Dali ItemFactory.
+   * E.g. Set( "data", itemData, JavaScript object that wraps a Dali ItemFactory)
+   * @param[in] propertyName property name
+   * @param[in] javaScriptValue javascript value to set, this is typically a number
+   * @param[in] info reference to PropertyCallbackInfo structure (contains the Javascript
+   * object).
+   */
+  static void PropertySet( v8::Local<v8::String> propertyName,
+                              v8::Local<v8::Value> javaScriptValue,
+                              const v8::PropertyCallbackInfo<v8::Value>& info);
+
+
+  /**
+   * @brief Extract a item factory wrapper from a javascript object
+   * @return item factory wrapper
+   */
+  static ItemFactoryWrapper* Unwrap( v8::Isolate* isolate, v8::Handle< v8::Object> obj);
+
+  Toolkit::ItemFactory& mItemFactory;
+
+};
+
+} // namespace V8Plugin
+
+} // namespace Dali
+
+#endif // header
diff --git a/plugins/dali-script-v8/src/controls/item-view-api.cpp b/plugins/dali-script-v8/src/controls/item-view-api.cpp
new file mode 100644 (file)
index 0000000..4852a61
--- /dev/null
@@ -0,0 +1,412 @@
+/*
+ * Copyright (c) 2015 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include "item-view-api.h"
+
+// EXTERNAL INCLUDES
+#include <fstream>
+#include <dali-toolkit/public-api/controls/scrollable/item-view/item-layout.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>
+
+// INTERNAL INCLUDES
+#include <v8-utils.h>
+#include <actors/actor-wrapper.h>
+#include <controls/control-wrapper.h>
+#include <controls/item-factory-wrapper.h>
+
+namespace Dali
+{
+
+namespace V8Plugin
+{
+
+namespace  // unanmed namespace
+{
+
+Toolkit::ItemView GetItemView( v8::Isolate* isolate, const v8::FunctionCallbackInfo<v8::Value>& args )
+{
+  HandleWrapper* handleWrapper = HandleWrapper::Unwrap( isolate, args.This() );
+  return Toolkit::ItemView::DownCast( handleWrapper->mHandle );
+}
+
+} //unanmed namespace
+
+/***************************************
+ * ITEMVIEW API FUNCTIONS
+ ***************************************/
+
+/**
+ * Constructor
+ *
+ * @for ItemView
+ * @constructor
+ * @method ItemView
+ * @return {Object} itemView
+ */
+Toolkit::Control ItemViewApi::New( const v8::FunctionCallbackInfo< v8::Value >& args )
+{
+  v8::Isolate* isolate = args.GetIsolate();
+  v8::HandleScope handleScope( isolate );
+
+  bool found( false );
+  Toolkit::ItemFactory& factory = ItemFactoryWrapper::GetItemFactoryFromParams( 1, found, isolate, args );
+  if( !found )
+  {
+    DALI_SCRIPT_EXCEPTION( isolate, "invalid ItemFactory parameter" );
+    return Toolkit::Control();
+  }
+  else
+  {
+    Toolkit::ItemView itemView = Toolkit::ItemView::New(factory);
+    ItemFactoryWrapper::SetItemView(factory, itemView);
+    return itemView;
+  }
+}
+
+/**
+ * Query the number of layouts.
+ *
+ * @for ItemView
+ * @method getLayoutCount
+ * @return {Integer} The number of layouts.
+ */
+void ItemViewApi::GetLayoutCount( const v8::FunctionCallbackInfo< v8::Value >& args)
+{
+  v8::Isolate* isolate = args.GetIsolate();
+  v8::HandleScope handleScope( isolate );
+
+  Toolkit::ItemView itemView = GetItemView( isolate, args );
+
+  args.GetReturnValue().Set( v8::Integer::New( isolate, itemView.GetLayoutCount() ) );
+}
+
+/**
+ * Add a layout
+ *
+ * @for ItemView
+ * @method addLayout
+ * @param {Integer} layout The layout to be added
+ * @example
+ *      // layout is one of the following
+ *      dali.ITEM_LAYOUT_LIST
+ *      dali.ITEM_LAYOUT_GRID
+ *
+ *      itemView.addLayout( dali.ITEM_LAYOUT_LIST );
+ */
+void ItemViewApi::AddLayout( const v8::FunctionCallbackInfo<v8::Value>& args )
+{
+  v8::Isolate* isolate = args.GetIsolate();
+  v8::HandleScope handleScope( isolate );
+
+  Toolkit::ItemView itemView = GetItemView( isolate, args );
+
+  bool found( false );
+  int layout = V8Utils::GetIntegerParameter( PARAMETER_0, found, isolate, args, 0 /* default */);
+  if( !found )
+  {
+    DALI_SCRIPT_EXCEPTION( isolate, "invalid layout parameter" );
+    return;
+  }
+
+  Toolkit::ItemLayoutPtr layoutPtr = Toolkit::DefaultItemLayout::New( static_cast<Toolkit::DefaultItemLayout::Type>(layout) );
+  itemView.AddLayout( *layoutPtr );
+}
+
+/**
+ * Remove a layout.
+ *
+ * @for ItemView
+ * @method removeLayout
+ * @param {Integer} layoutIndex The index of the ItemView layouts which must be less than getLayoutCount().
+ */
+void ItemViewApi::RemoveLayout( const v8::FunctionCallbackInfo<v8::Value>& args )
+{
+  v8::Isolate* isolate = args.GetIsolate();
+  v8::HandleScope handleScope( isolate );
+
+  Toolkit::ItemView itemView = GetItemView( isolate, args );
+
+  bool found( false );
+  int layoutIndex = V8Utils::GetIntegerParameter( PARAMETER_0, found, isolate, args, 0 /* default */);
+  if( !found )
+  {
+    DALI_SCRIPT_EXCEPTION( isolate, "invalid index parameter" );
+    return;
+  }
+
+  itemView.RemoveLayout( layoutIndex );
+}
+
+/**
+ * Activate one of the layouts. This will resize the ItemView and relayout actors within the ItemView.
+ *
+ * @for ItemView
+ * @method activateLayout
+ * @param {Integer} layoutIndex The index of the ItemView layout which must be less than getLayoutCount().
+ * @param {Object} targetSize An array of 3 numbers for the target ItemView and layout size.
+ * @param {Float} [durationSeconds] The time taken to relayout in seconds (0 by default for immediate).
+ */
+void ItemViewApi::ActivateLayout( const v8::FunctionCallbackInfo<v8::Value>& args )
+{
+  v8::Isolate* isolate = args.GetIsolate();
+  v8::HandleScope handleScope( isolate );
+
+  Toolkit::ItemView itemView = GetItemView( isolate, args );
+
+  bool found( false );
+  int layoutIndex = V8Utils::GetIntegerParameter( PARAMETER_0, found, isolate, args, 0 );
+  if( !found )
+  {
+    DALI_SCRIPT_EXCEPTION( isolate, "invalid layout index parameter" );
+    return;
+  }
+
+  found = false;
+  Vector3 targetSize = V8Utils::GetVector3Parameter( PARAMETER_1, found, isolate, args );
+  if( !found )
+  {
+    DALI_SCRIPT_EXCEPTION( isolate, "Vector3 targetSize size parameter missing" );
+    return;
+  }
+
+  found = false;
+  float durationSeconds = V8Utils::GetFloatParameter( PARAMETER_2, found, isolate, args, 0.0f ); // 0 by default for immediate activation
+
+  itemView.ActivateLayout( layoutIndex, targetSize, durationSeconds );
+}
+
+/**
+ * Retrieve the target size of an item in the given layout.
+ * This will return the default size for the layout unless overridden by calling setLayoutItemSize().
+ *
+ * @for ItemView
+ * @method getItemSize
+ * @param {Integer} layoutIndex The index of the ItemView layout which must be less than getLayoutCount().
+ * @param {Integer} itemId The ID of an item in the layout.
+ * @param {Object} targetLayoutSize An array of 3 numbers for the target ItemView and layout size.
+ * @return {Object} The target size of the item {x, y, z}.
+ */
+void ItemViewApi::GetItemSize( const v8::FunctionCallbackInfo<v8::Value>& args )
+{
+  v8::Isolate* isolate = args.GetIsolate();
+  v8::HandleScope handleScope( isolate );
+
+  Toolkit::ItemView itemView = GetItemView( isolate, args );
+
+  bool found( false );
+  int layoutIndex = V8Utils::GetIntegerParameter( PARAMETER_0, found, isolate, args, 0 /* default */);
+  if( !found )
+  {
+    DALI_SCRIPT_EXCEPTION( isolate, "invalid layout index parameter" );
+    return;
+  }
+
+  found = false;
+  int itemId = V8Utils::GetIntegerParameter( PARAMETER_1, found, isolate, args, 0 /* default */);
+  if( !found )
+  {
+    DALI_SCRIPT_EXCEPTION( isolate, "invalid item ID parameter" );
+    return;
+  }
+
+  found = false;
+  Vector3 targetLayoutSize = V8Utils::GetVector3Parameter( PARAMETER_2, found, isolate, args );
+  if( found )
+  {
+    Toolkit::ItemLayoutPtr layoutPtr = itemView.GetLayout(layoutIndex);
+    Vector3 itemSize;
+    layoutPtr->GetItemSize( itemId, targetLayoutSize, itemSize );
+
+    v8::Local<v8::Object> itemSizeObject = v8::Object::New( isolate );
+
+    itemSizeObject->Set( v8::String::NewFromUtf8( isolate, "x" ), v8::Integer::New( isolate, itemSize.width ) );
+    itemSizeObject->Set( v8::String::NewFromUtf8( isolate, "y" ), v8::Integer::New( isolate, itemSize.height ) );
+    itemSizeObject->Set( v8::String::NewFromUtf8( isolate, "z" ), v8::Integer::New( isolate, itemSize.depth ) );
+
+    args.GetReturnValue().Set( itemSizeObject );
+  }
+  else
+  {
+    DALI_SCRIPT_EXCEPTION( isolate, "invalid Vector3 target size parameter" );
+  }
+}
+
+/**
+ * Set the size of the item for the given layout which overrides the default item size for the layout.
+ *
+ * @for ItemView
+ * @method setItemSize
+ * @param {Integer} layoutIndex The index of the ItemView layout which must be less than getLayoutCount().
+ * @param {Object} itemSize An array of 3 numbers for the size of the item.
+ * @example
+ *      itemView.setLayoutItemSize( 0, [100.0, 50.0, 0.0] );
+ */
+void ItemViewApi::SetItemSize( const v8::FunctionCallbackInfo<v8::Value>& args )
+{
+  v8::Isolate* isolate = args.GetIsolate();
+  v8::HandleScope handleScope( isolate );
+
+  Toolkit::ItemView itemView = GetItemView( isolate, args );
+
+  bool found( false );
+  int layoutIndex = V8Utils::GetIntegerParameter( PARAMETER_0, found, isolate, args, 0 /* default */);
+  if( !found )
+  {
+    DALI_SCRIPT_EXCEPTION( isolate, "invalid layout index parameter" );
+    return;
+  }
+
+  found = false;
+  Vector3 itemSize = V8Utils::GetVector3Parameter( PARAMETER_1, found, isolate, args );
+  if( found )
+  {
+    Toolkit::ItemLayoutPtr layoutPtr = itemView.GetLayout(layoutIndex);
+    layoutPtr->SetItemSize( itemSize );
+  }
+  else
+  {
+    DALI_SCRIPT_EXCEPTION( isolate, "invalid item size parameter" );
+  }
+}
+
+/**
+ * Scroll the current layout to a particular item.
+ * If calling this with zero second of duration immediately after calling activateLayout(),
+ * it will not work unless the duration of relayout animation for activateLayout is also
+ * set to zero.
+ *
+ * @for ItemView
+ * @method scrollToItem
+ * @param {Integer} itemId The ID of an item in the layout.
+ * @param {Float} [durationSeconds] How long the scrolling takes in seconds (0 by default for instant scrolling to the particular item).
+ */
+void ItemViewApi::ScrollToItem( const v8::FunctionCallbackInfo<v8::Value>& args )
+{
+  v8::Isolate* isolate = args.GetIsolate();
+  v8::HandleScope handleScope( isolate );
+
+  Toolkit::ItemView itemView = GetItemView( isolate, args );
+
+  bool found( false );
+  int itemId = V8Utils::GetIntegerParameter( PARAMETER_0, found, isolate, args, 0 /* default */);
+  if( !found )
+  {
+    DALI_SCRIPT_EXCEPTION( isolate, "invalid item Id parameter" );
+    return;
+  }
+
+  found = false;
+  float durationSeconds = V8Utils::GetFloatParameter( PARAMETER_1, found, isolate, args, 0.0f ); // 0 by default for instant scrolling
+
+  itemView.ScrollToItem( itemId, durationSeconds );
+}
+
+/**
+ * Given the Item ID, this returns the accompanying actor.
+ *
+ * @for ItemView
+ * @method getItem
+ * @param {Integer} itemId The Item ID of the actor required.
+ * @return {Object} The Actor corresponding to the Item ID.
+ */
+void ItemViewApi::GetItem( const v8::FunctionCallbackInfo<v8::Value>& args )
+{
+  v8::Isolate* isolate = args.GetIsolate();
+  v8::HandleScope handleScope( isolate );
+
+  Toolkit::ItemView itemView = GetItemView( isolate, args );
+
+  bool found( false );
+  int itemId = V8Utils::GetIntegerParameter( PARAMETER_0, found, isolate, args, 0 /* default */);
+  if( found )
+  {
+    found = false;
+    Actor actor = itemView.GetItem( itemId );
+    if( actor )
+    {
+      found = true;
+      // wrap the actor
+      v8::Handle < v8::Object > wrappedActor = ActorWrapper::WrapActor( isolate, actor );
+      args.GetReturnValue().Set( wrappedActor );
+    }
+  }
+
+  if( !found )
+  {
+    DALI_SCRIPT_EXCEPTION( isolate, "invalid item ID" );
+    return;
+  }
+}
+
+/**
+ * Returns the Item ID of the specified actor. The actor must be an item of ItemView.
+ *
+ * @for ItemView
+ * @method getItemId
+ * @param {Object} actor The actor whose Item ID is required.
+ * @return {Integer} The Item ID of the item.
+ */
+void ItemViewApi::GetItemId( const v8::FunctionCallbackInfo<v8::Value>& args )
+{
+  v8::Isolate* isolate = args.GetIsolate();
+  v8::HandleScope handleScope( isolate );
+
+  Toolkit::ItemView itemView = GetItemView( isolate, args );
+
+  bool found( false );
+  Actor actor = V8Utils::GetActorParameter( 0, found, isolate, args );
+  if( found )
+  {
+    args.GetReturnValue().Set( itemView.GetItemId(actor) );
+  }
+  else
+  {
+    DALI_SCRIPT_EXCEPTION( isolate, "invalid item actor parameter" );
+    return;
+  }
+}
+
+/**
+ * Get the range of items that are currently in ItemView.
+ *
+ * @for ItemView
+ * @method getItemsRange
+ * @return {Object} The range of items in the item ID {begin, end}.
+ */
+void ItemViewApi::GetItemsRange( const v8::FunctionCallbackInfo<v8::Value>& args )
+{
+  v8::Isolate* isolate = args.GetIsolate();
+  v8::HandleScope handleScope( isolate );
+
+  Toolkit::ItemView itemView = GetItemView( isolate, args );
+
+  Toolkit::ItemRange range(0, 0);
+  itemView.GetItemsRange(range);
+
+  v8::Local<v8::Object> itemRangeObject = v8::Object::New( isolate );
+
+  itemRangeObject->Set( v8::String::NewFromUtf8( isolate, "begin" ), v8::Integer::New( isolate, range.begin ) );
+  itemRangeObject->Set( v8::String::NewFromUtf8( isolate, "end" ), v8::Integer::New( isolate, range.end ) );
+
+  args.GetReturnValue().Set( itemRangeObject );
+}
+
+} // namespace V8Plugin
+
+} // namespace Dali
diff --git a/plugins/dali-script-v8/src/controls/item-view-api.h b/plugins/dali-script-v8/src/controls/item-view-api.h
new file mode 100644 (file)
index 0000000..7f56653
--- /dev/null
@@ -0,0 +1,59 @@
+#ifndef __DALI_V8PLUGIN_ITEM_VIEW_API_H__
+#define __DALI_V8PLUGIN_ITEM_VIEW_API_H__
+
+/*
+ * Copyright (c) 2015 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <v8.h>
+#include <dali-toolkit/public-api/controls/scrollable/item-view/item-view.h>
+
+namespace Dali
+{
+
+namespace V8Plugin
+{
+
+namespace ItemViewApi
+{
+
+  /**
+   * constructor
+   */
+  Toolkit::Control New( const v8::FunctionCallbackInfo< v8::Value >& args );
+
+  /**
+   * ItemView API. See item-view.h for description of functions
+   */
+  void GetLayoutCount( const v8::FunctionCallbackInfo< v8::Value >& args);
+  void AddLayout( const v8::FunctionCallbackInfo< v8::Value >& args );
+  void RemoveLayout( const v8::FunctionCallbackInfo< v8::Value >& args );
+  void ActivateLayout( const v8::FunctionCallbackInfo< v8::Value >& args);
+  void GetItemSize( const v8::FunctionCallbackInfo< v8::Value >& args);
+  void SetItemSize( const v8::FunctionCallbackInfo< v8::Value >& args);
+  void ScrollToItem( const v8::FunctionCallbackInfo< v8::Value >& args);
+  void GetItem( const v8::FunctionCallbackInfo< v8::Value >& args);
+  void GetItemId( const v8::FunctionCallbackInfo< v8::Value >& args);
+  void GetItemsRange( const v8::FunctionCallbackInfo< v8::Value >& args);
+
+}; // namespace ItemViewApi
+
+} // namespace V8Plugin
+
+} // namespace Dali
+
+#endif // header __DALI_V8PLUGIN_ITEM_VIEW_API_H__
index 132dc5e..92719c7 100644 (file)
 #include <object/property-value-wrapper.h>
 #include <dali/integration-api/debug.h>
 #include <actors/actor-wrapper.h>
 #include <object/property-value-wrapper.h>
 #include <dali/integration-api/debug.h>
 #include <actors/actor-wrapper.h>
+#include <controls/control-wrapper.h>
 #include <stage/stage-wrapper.h>
 #include <image/image-wrapper.h>
 #include <animation/linear-constrainer-wrapper.h>
 #include <animation/path-constrainer-wrapper.h>
 #include <animation/path-wrapper.h>
 #include <animation/animation-wrapper.h>
 #include <stage/stage-wrapper.h>
 #include <image/image-wrapper.h>
 #include <animation/linear-constrainer-wrapper.h>
 #include <animation/path-constrainer-wrapper.h>
 #include <animation/path-wrapper.h>
 #include <animation/animation-wrapper.h>
+#include <controls/item-factory-wrapper.h>
 #include <events/pan-gesture-detector-wrapper.h>
 #include <object/property-buffer-wrapper.h>
 #include <rendering/geometry-wrapper.h>
 #include <events/pan-gesture-detector-wrapper.h>
 #include <object/property-buffer-wrapper.h>
 #include <rendering/geometry-wrapper.h>
@@ -70,11 +72,12 @@ const ApiFunction ConstructorFunctionTable[]=
     { "Actor",              ActorWrapper::NewActor },
     { "CameraActor",        ActorWrapper::NewActor },
     { "Layer",              ActorWrapper::NewActor },
     { "Actor",              ActorWrapper::NewActor },
     { "CameraActor",        ActorWrapper::NewActor },
     { "Layer",              ActorWrapper::NewActor },
-    { "Control",            ActorWrapper::NewControl },
+    { "Control",            ControlWrapper::NewControl },
     { "ResourceImage",      ImageWrapper::NewImage },
     { "BufferImage",        ImageWrapper::NewImage },
     { "FrameBufferImage",   ImageWrapper::NewImage },
     { "Animation",          AnimationWrapper::NewAnimation},
     { "ResourceImage",      ImageWrapper::NewImage },
     { "BufferImage",        ImageWrapper::NewImage },
     { "FrameBufferImage",   ImageWrapper::NewImage },
     { "Animation",          AnimationWrapper::NewAnimation},
+    { "ItemFactory",        ItemFactoryWrapper::NewItemFactory},
     { "Shader",             ShaderWrapper::NewShader},
     { "Sampler",            SamplerWrapper::NewSampler},
     { "Material",           MaterialWrapper::NewMaterial},
     { "Shader",             ShaderWrapper::NewShader},
     { "Sampler",            SamplerWrapper::NewSampler},
     { "Material",           MaterialWrapper::NewMaterial},
index 2915670..be1739d 100644 (file)
@@ -42,6 +42,7 @@ namespace // un-named name space
 const ApiFunction HandleFunctionTable[]=
 {
   { "RegisterAnimatableProperty",            HandleWrapper::RegisterAnimatableProperty },
 const ApiFunction HandleFunctionTable[]=
 {
   { "RegisterAnimatableProperty",            HandleWrapper::RegisterAnimatableProperty },
+  { "RegisterCustomProperty",                HandleWrapper::RegisterCustomProperty     },
 };
 
 const unsigned int HandleFunctionTableCount = sizeof(HandleFunctionTable)/sizeof(HandleFunctionTable[0]);
 };
 
 const unsigned int HandleFunctionTableCount = sizeof(HandleFunctionTable)/sizeof(HandleFunctionTable[0]);
@@ -212,8 +213,8 @@ void HandleWrapper::AddInterceptsToTemplate( v8::Isolate* isolate, v8::Local<v8:
  * @return {integer} The index of the property or dali.PROPERTY_INVALID_INDEX if registration failed
  * @example
  *
  * @return {integer} The index of the property or dali.PROPERTY_INVALID_INDEX if registration failed
  * @example
  *
- *     var morphPropertyIdex = actor.registerAnimatableProperty("uMorphAmount", 0.0f);
- *     var fadeColorPropertyIdex = handle.registerAnimatableProperty("uFadeColor", [1.0, 0.0, 0.0, 1.0]);
+ *     var morphPropertyIndex = actor.registerAnimatableProperty("uMorphAmount", 0.0f);
+ *     var fadeColorPropertyIndex = handle.registerAnimatableProperty("uFadeColor", [1.0, 0.0, 0.0, 1.0]);
  *
  */
 void HandleWrapper::RegisterAnimatableProperty( const v8::FunctionCallbackInfo< v8::Value >& args )
  *
  */
 void HandleWrapper::RegisterAnimatableProperty( const v8::FunctionCallbackInfo< v8::Value >& args )
@@ -251,6 +252,75 @@ void HandleWrapper::RegisterAnimatableProperty( const v8::FunctionCallbackInfo<
   }
 }
 
   }
 }
 
+/**
+ * Register a new custom property.
+ *
+ * The object should support dynamic properties.
+ * Property names must be unused.
+ * Property indices are unique to each registered custom property in a given object.
+ * Properties can be set as non animatable using property attributes.
+ * returns dali.PROPERTY_INVALID_INDEX if registration failed.
+ *
+ * @method registerCustomProperty
+ * @for Handle
+ * @param {string} name The name of the property.
+ * @param {Object} propertyValue The new value of the property.
+ * @param {integer} accessMode The property access mode (writable, animatable etc).
+ * @return {integer} The index of the property or dali.PROPERTY_INVALID_INDEX if registration failed
+ * @example
+ *
+ *     // access mode is one of the following
+ *     dali.PROPERTY_READ_ONLY
+ *     dali.PROPERTY_READ_WRITE
+ *     dali.PROPERTY_ANIMATABLE
+ *
+ *     var cellIndexPropertyIndex = actor.registerCustomProperty("cellIndex", 2, dali.PROPERTY_READ_WRITE);
+ *     var myCustomPropertyIndex = handle.registerCustomProperty("myCustomProperty", [10.0, 25.0, 0.0], dali.PROPERTY_READ_ONLY);
+ *
+ */
+void HandleWrapper::RegisterCustomProperty( const v8::FunctionCallbackInfo< v8::Value >& args )
+{
+  v8::Isolate* isolate = args.GetIsolate();
+  v8::HandleScope handleScope( isolate );
+
+  // unwrap the object
+  HandleWrapper* handleWrapper = Unwrap( isolate, args.This() );
+  if( !handleWrapper )
+  {
+    return;
+  }
+
+  Handle handle =  handleWrapper->mHandle;
+
+  bool found( false );
+  std::string propertyName = V8Utils::GetStringParameter( PARAMETER_0, found, isolate, args );
+  if( !found )
+  {
+    DALI_SCRIPT_EXCEPTION( isolate, "bad property name parameter" );
+    return;
+  }
+
+  found = false;
+  Dali::Property::Value daliPropertyValue = V8Utils::GetPropertyValueParameter(PARAMETER_1, found, isolate, args );
+  if( !found || Dali::Property::NONE == daliPropertyValue.GetType() )
+  {
+    DALI_SCRIPT_EXCEPTION( isolate, "bad property value parameter" );
+    return;
+  }
+
+  found = false;
+  int accessMode = V8Utils::GetIntegerParameter( PARAMETER_2, found, isolate, args, 0 /* default */);
+  if( !found )
+  {
+    DALI_SCRIPT_EXCEPTION( isolate, "invalid access mode parameter" );
+    return;
+  }
+  else
+  {
+    args.GetReturnValue().Set( v8::Integer::New( isolate, handle.RegisterProperty( propertyName, daliPropertyValue, static_cast<Property::AccessMode>(accessMode) ) ) );
+  }
+}
+
 } // namespace V8Plugin
 
 } // namespace Dali
 } // namespace V8Plugin
 
 } // namespace Dali
index 2e612c7..7356f01 100644 (file)
@@ -81,6 +81,13 @@ public:
    */
   static void RegisterAnimatableProperty( const v8::FunctionCallbackInfo< v8::Value >& args );
 
    */
   static void RegisterAnimatableProperty( const v8::FunctionCallbackInfo< v8::Value >& args );
 
+  /**
+   * @brief Register a custom property for a JavaScript object that
+   * contains a Dali Handle.
+   * @param[in] args v8 function call arguments interpreted
+   */
+  static void RegisterCustomProperty( const v8::FunctionCallbackInfo< v8::Value >& args );
+
   Handle GetHandle() { return mHandle; }
   Handle mHandle;
   ConnectionTracker mConnectionTracker;
   Handle GetHandle() { return mHandle; }
   Handle mHandle;
   ConnectionTracker mConnectionTracker;
index db1c8a8..0bd9840 100644 (file)
@@ -80,6 +80,8 @@ public:
       IMAGE_ATTRIBUTES,
       ACTOR,
       ACTOR_PROPERTY,
       IMAGE_ATTRIBUTES,
       ACTOR,
       ACTOR_PROPERTY,
+      ITEMVIEW,
+      ITEMFACTORY,
       RENDER_TASK,
       RENDER_TASK_LIST,
       TIMER,
       RENDER_TASK,
       RENDER_TASK_LIST,
       TIMER,
index 4d09da9..b77d458 100644 (file)
@@ -149,6 +149,118 @@ void GetModuleName( const std::string& fileName, std::string& moduleName )
   }
 }
 
   }
 }
 
+bool IsPropertyMapIdentical(Property::Map map1, Property::Map map2)
+{
+  bool dirty = false;
+
+  // Compare number of properties
+  if ( map1.Count() != map2.Count() )
+  {
+    dirty = true;
+  }
+  else
+  {
+    for ( unsigned int i = 0, count = map1.Count(); i < count; ++i )
+    {
+      // Compare the key first
+      if(map1.GetKey(i) != map2.GetKey(i))
+      {
+        dirty = true;
+      }
+      else
+      {
+        Property::Value& value = map1.GetValue(i);
+        Property::Value& newValue = map2.GetValue(i);
+
+        // Compare the value type
+        if(value.GetType() != newValue.GetType())
+        {
+          dirty = true;
+        }
+        else
+        {
+          // Compare the value
+          switch( value.GetType() )
+          {
+            case Property::BOOLEAN:
+            {
+              dirty = ( value.Get<bool>() != newValue.Get<bool>() );
+              break;
+            }
+            case Property::FLOAT:
+            {
+              dirty = ( value.Get<float>() != newValue.Get<float>() );
+              break;
+            }
+            case Property::INTEGER:
+            {
+              dirty = ( value.Get<int>() != newValue.Get<int>() );
+              break;
+            }
+            case Property::RECTANGLE:
+            {
+              dirty = ( value.Get< Rect<int> >() != newValue.Get< Rect<int> >() );
+              break;
+            }
+            case Property::VECTOR2:
+            {
+              dirty = ( value.Get<Vector2>() != newValue.Get<Vector2>() );
+              break;
+            }
+            case Property::VECTOR3:
+            {
+              dirty = ( value.Get<Vector3>() != newValue.Get<Vector3>() );
+              break;
+            }
+            case Property::VECTOR4:
+            {
+              dirty = ( value.Get<Vector4>() != newValue.Get<Vector4>() );
+              break;
+            }
+            case Property::MATRIX3:
+            {
+              dirty = ( value.Get<Matrix3>() != newValue.Get<Matrix3>() );
+              break;
+            }
+            case Property::MATRIX:
+            {
+              dirty = ( value.Get<Matrix>() != newValue.Get<Matrix>() );
+              break;
+            }
+            case Property::ROTATION:
+            {
+              dirty = ( value.Get<Quaternion>() != newValue.Get<Quaternion>() );
+              break;
+            }
+            case Property::STRING:
+            {
+              dirty = ( value.Get<std::string>() != newValue.Get<std::string>() );
+              break;
+            }
+            case Property::MAP:
+            {
+              dirty = ( !IsPropertyMapIdentical( value.Get<Property::Map>(), newValue.Get<Property::Map>() ) );
+              break;
+            }
+            default:
+            {
+              break;
+            }
+          }
+        }
+      }
+
+      if(dirty)
+      {
+        // Different already, no need any further comparison
+        break;
+      }
+    }
+  }
+
+  return !dirty;
+}
+
 void ReportException(  v8::Isolate* isolate, v8::TryCatch* tryCatch)
 {
   v8::HandleScope handleScope( isolate );
 void ReportException(  v8::Isolate* isolate, v8::TryCatch* tryCatch)
 {
   v8::HandleScope handleScope( isolate );
@@ -879,7 +991,7 @@ void CreatePropertyMap( v8::Isolate* isolate, const Property::Map& map, v8::Loca
     return;
   }
 
     return;
   }
 
-  for( unsigned int index = 0; index < map.Count() - 1; ++index )
+  for( unsigned int index = 0; index < map.Count(); ++index )
   {
     const std::string& key = map.GetKey( index );
     Property::Value& value = map.GetValue( index );
   {
     const std::string& key = map.GetKey( index );
     Property::Value& value = map.GetValue( index );
index 1551868..5a86f39 100644 (file)
@@ -96,6 +96,14 @@ void GetFileName( const std::string& fullPathName, std::string& fileName);
 void GetModuleName( const std::string& fileName, std::string& moduleName );
 
 /**
 void GetModuleName( const std::string& fileName, std::string& moduleName );
 
 /**
+ * Compare whether two DALi property maps are identical
+ * @param[in] map1 The first property map to be compared
+ * @param[in] map2 The second property map to be compared
+ * @return true if the two specified property maps are identical or false if not.
+ */
+bool IsPropertyMapIdentical(Property::Map map1, Property::Map map2);
+
+/**
  * Report an exception by writing as a warning to the Dali Log
  *
  * @param[in] try_catch The v8 TryCatch exception object
  * Report an exception by writing as a warning to the Dali Log
  *
  * @param[in] try_catch The v8 TryCatch exception object