[dali_1.2.22] Merge branch 'devel/master' 97/110297/1
authorDavid Steele <david.steele@samsung.com>
Fri, 13 Jan 2017 14:36:28 +0000 (14:36 +0000)
committerDavid Steele <david.steele@samsung.com>
Fri, 13 Jan 2017 14:36:28 +0000 (14:36 +0000)
Change-Id: Ia0fea2310111418861f2f63a9935cd5c8ca8cdff

70 files changed:
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/dummy-control.cpp
automated-tests/src/dali-toolkit/utc-Dali-Button.cpp
automated-tests/src/dali-toolkit/utc-Dali-Control.cpp
automated-tests/src/dali-toolkit/utc-Dali-ControlImpl.cpp
automated-tests/src/dali-toolkit/utc-Dali-TableView.cpp
dali-toolkit/internal/controls/bloom-view/bloom-view-impl.cpp
dali-toolkit/internal/controls/buttons/button-impl.cpp
dali-toolkit/internal/controls/buttons/button-impl.h
dali-toolkit/internal/controls/effects-view/effects-view-impl.cpp
dali-toolkit/internal/controls/flex-container/flex-container-impl.cpp
dali-toolkit/internal/controls/flex-container/flex-container-impl.h
dali-toolkit/internal/controls/gaussian-blur-view/gaussian-blur-view-impl.cpp
dali-toolkit/internal/controls/magnifier/magnifier-impl.cpp
dali-toolkit/internal/controls/model3d-view/model3d-view-impl.cpp
dali-toolkit/internal/controls/navigation-view/navigation-view-impl.cpp
dali-toolkit/internal/controls/page-turn-view/page-turn-view-impl.cpp
dali-toolkit/internal/controls/popup/popup-impl.cpp
dali-toolkit/internal/controls/scroll-bar/scroll-bar-impl.cpp
dali-toolkit/internal/controls/scrollable/item-view/item-view-impl.cpp
dali-toolkit/internal/controls/scrollable/scroll-view/scroll-view-impl.cpp
dali-toolkit/internal/controls/shadow-view/shadow-view-impl.cpp
dali-toolkit/internal/controls/slider/slider-impl.cpp
dali-toolkit/internal/controls/slider/slider-impl.h
dali-toolkit/internal/controls/super-blur-view/super-blur-view-impl.cpp
dali-toolkit/internal/controls/super-blur-view/super-blur-view-impl.h
dali-toolkit/internal/controls/table-view/table-view-impl.cpp
dali-toolkit/internal/controls/table-view/table-view-impl.h
dali-toolkit/internal/controls/text-controls/text-editor-impl.cpp
dali-toolkit/internal/controls/text-controls/text-field-impl.cpp
dali-toolkit/internal/controls/text-controls/text-label-impl.cpp
dali-toolkit/internal/controls/text-controls/text-label-impl.h
dali-toolkit/internal/controls/text-controls/text-selection-popup-impl.cpp
dali-toolkit/internal/controls/text-controls/text-selection-popup-impl.h
dali-toolkit/internal/controls/text-controls/text-selection-toolbar-impl.cpp
dali-toolkit/internal/controls/text-controls/text-selection-toolbar-impl.h
dali-toolkit/internal/controls/tool-bar/tool-bar-impl.cpp
dali-toolkit/internal/controls/video-view/video-view-impl.cpp
dali-toolkit/internal/transition-effects/cube-transition-effect-impl.cpp
dali-toolkit/public-api/controls/buttons/button.h
dali-toolkit/public-api/controls/control-impl.cpp
dali-toolkit/public-api/controls/control-impl.h
dali-toolkit/public-api/controls/control.cpp
dali-toolkit/public-api/controls/scrollable/item-view/item-view.h
dali-toolkit/public-api/controls/scrollable/scroll-view/scroll-view.h
dali-toolkit/public-api/controls/table-view/table-view.h
dali-toolkit/public-api/dali-toolkit-version.cpp
dali-toolkit/public-api/enums.h
dali-toolkit/styles/720x1280/dali-toolkit-default-theme.json
docs/content/shared-javascript-and-cpp-documentation/creating-custom-controls.md
packaging/dali-addon.spec
packaging/dali-toolkit.spec
plugins/dali-swig/.gitignore
plugins/dali-swig/Makefile.am
plugins/dali-swig/SWIG/dali-core.i
plugins/dali-swig/SWIG/dali.i
plugins/dali-swig/SWIG/events/application-event.i
plugins/dali-swig/SWIG/events/builder-event.i
plugins/dali-swig/SWIG/property-value.i [new file with mode: 0644]
plugins/dali-swig/examples/date-picker-using-json.cs [new file with mode: 0644]
plugins/dali-swig/examples/date-picker.cs [new file with mode: 0644]
plugins/dali-swig/examples/json-loader.cs [new file with mode: 0644]
plugins/dali-swig/examples/json/date-picker-template.json [new file with mode: 0644]
plugins/dali-swig/examples/json/date-picker.json [new file with mode: 0644]
plugins/dali-swig/examples/json/spin.json [new file with mode: 0644]
plugins/dali-swig/examples/spin-control.cs [deleted file]
plugins/dali-swig/manual/csharp/PropertyRangeManager.cs [new file with mode: 0644]
plugins/dali-swig/manual/csharp/ViewRegistry.cs [new file with mode: 0644]
plugins/dali-swig/manual/csharp/ViewRegistryHelper.cs [new file with mode: 0644]
plugins/dali-swig/property-wrapper.rb
plugins/dali-swig/views/spin.cs [new file with mode: 0644]

index e8c266d..ed4d02c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 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.
@@ -207,12 +207,12 @@ void DummyControlImplOverride::OnPinch(const PinchGesture& pinch) { pinchCalled
 void DummyControlImplOverride::OnPan(const PanGesture& pan) { panCalled = true; }
 void DummyControlImplOverride::OnTap(const TapGesture& tap) { tapCalled = true; }
 void DummyControlImplOverride::OnLongPress(const LongPressGesture& longPress) { longPressCalled = true; }
-void DummyControlImplOverride::OnStageConnection( int depth ) { Control::OnStageConnection( depth ); stageConnectionCalled = true; }
+void DummyControlImplOverride::OnStageConnection( int depth ) { stageConnectionCalled = true; Control::OnStageConnection( depth ); }
 void DummyControlImplOverride::OnStageDisconnection() { stageDisconnectionCalled = true; Control::OnStageDisconnection(); }
-void DummyControlImplOverride::OnChildAdd(Actor& child) { childAddCalled = true; }
-void DummyControlImplOverride::OnChildRemove(Actor& child) { childRemoveCalled = true; }
-void DummyControlImplOverride::OnSizeSet(const Vector3& targetSize) { Control::OnSizeSet( targetSize ); sizeSetCalled = true; }
-void DummyControlImplOverride::OnSizeAnimation(Animation& animation, const Vector3& targetSize) { Control::OnSizeAnimation( animation, targetSize ); sizeAnimationCalled = true; }
+void DummyControlImplOverride::OnChildAdd(Actor& child) { childAddCalled = true; Control::OnChildAdd( child ); }
+void DummyControlImplOverride::OnChildRemove(Actor& child) { childRemoveCalled = true; Control::OnChildRemove( child ); }
+void DummyControlImplOverride::OnSizeSet(const Vector3& targetSize) { sizeSetCalled = true; Control::OnSizeSet( targetSize ); }
+void DummyControlImplOverride::OnSizeAnimation(Animation& animation, const Vector3& targetSize) { sizeAnimationCalled = true; Control::OnSizeAnimation( animation, targetSize ); }
 bool DummyControlImplOverride::OnTouchEvent(const TouchEvent& event) { touchEventCalled = true; return false; }
 bool DummyControlImplOverride::OnHoverEvent(const HoverEvent& event) { hoverEventCalled = true; return false; }
 bool DummyControlImplOverride::OnWheelEvent(const WheelEvent& event) { wheelEventCalled = true; return false; }
index a2bf49d..9452649 100644 (file)
@@ -59,6 +59,23 @@ static bool ButtonCallback( Button button )
   return false;
 }
 
+static std::string GetButtonText( Button button )
+{
+  Property::Value value = button.GetProperty( Toolkit::Button::Property::LABEL );
+
+  Property::Map *labelProperty = value.GetMap();
+
+  std::string textLabel;
+
+  if ( labelProperty )
+  {
+    Property::Value* value = labelProperty->Find( Toolkit::TextVisual::Property::TEXT );
+    value->Get( textLabel );
+  }
+
+  return textLabel;
+}
+
 struct CallbackFunctor
 {
   CallbackFunctor(bool* callbackFlag)
@@ -472,7 +489,7 @@ int UtcDaliButtonSetAnimationTimeP(void)
   END_TEST;
 }
 
-int UtcDaliButtonSetLabelStringP(void)
+int UtcDaliButtonSetLabelStringWithPropertyMapP(void)
 {
   ToolkitTestApplication application;
 
@@ -480,11 +497,28 @@ int UtcDaliButtonSetLabelStringP(void)
   button.SetProperty( Toolkit::Button::Property::LABEL,
                       Property::Map().Add( Toolkit::Visual::Property::TYPE, Toolkit::DevelVisual::TEXT )
                                      .Add( Toolkit::TextVisual::Property::POINT_SIZE, 15.0f )
+                                     .Add( Toolkit::TextVisual::Property::TEXT, "Button Label")
                      );
 
-  button.SetLabelText( "Button Label" );
+  DALI_TEST_EQUALS( GetButtonText( button ), "Button Label", TEST_LOCATION );
+  END_TEST;
+}
+
+int UtcDaliButtonSetLabelWithStringP(void)
+{
+  ToolkitTestApplication application;
+
+  Button button = PushButton::New();
+
+  // Set default point size for text visual as style sheet not available.
+  button.SetProperty( Toolkit::Button::Property::LABEL,
+                      Property::Map().Add( Toolkit::Visual::Property::TYPE, Toolkit::DevelVisual::TEXT )
+                                     .Add( Toolkit::TextVisual::Property::POINT_SIZE, 15.0f )
+                                     );
+
+  button.SetProperty( Toolkit::Button::Property::LABEL, "Button Label" );
 
-  DALI_TEST_EQUALS( button.GetLabelText(), "Button Label", TEST_LOCATION );
+  DALI_TEST_EQUALS( GetButtonText( button ), "Button Label", TEST_LOCATION );
   END_TEST;
 }
 
@@ -492,6 +526,9 @@ int UtcDaliButtonSetLabelPropertyP(void)
 {
   ToolkitTestApplication application;
 
+  tet_infoline(" UtcDaliButtonSetLabelPropertyP Set text label and then set again with new text");
+
+
   const std::string TEST_LABEL1 = "test label one";
   const std::string TEST_LABEL2 = "test label two";
 
@@ -500,13 +537,10 @@ int UtcDaliButtonSetLabelPropertyP(void)
   button.SetProperty( Toolkit::Button::Property::LABEL,
                         Property::Map().Add( Toolkit::Visual::Property::TYPE, Toolkit::DevelVisual::TEXT )
                                        .Add( Toolkit::TextVisual::Property::POINT_SIZE, 15.0f )
+                                       .Add( Toolkit::TextVisual::Property::TEXT, TEST_LABEL1 )
                      );
 
-  button.SetProperty( Button::Property::LABEL_TEXT, TEST_LABEL1 );
-
-  std::string labelText = button.GetProperty<std::string>( Button::Property::LABEL_TEXT );
-
-  DALI_TEST_EQUALS( labelText, TEST_LABEL1,  TEST_LOCATION );
+  DALI_TEST_EQUALS( GetButtonText( button ), TEST_LABEL1,  TEST_LOCATION );
 
   Property::Map propertyMap;
   propertyMap.Insert( Toolkit::Visual::Property::TYPE,  Toolkit::DevelVisual::TEXT );
@@ -515,9 +549,7 @@ int UtcDaliButtonSetLabelPropertyP(void)
   propertyMap.Insert( Toolkit::TextVisual::Property::POINT_SIZE, 15.0f );
   button.SetProperty( Button::Property::LABEL, propertyMap );
 
-  labelText = button.GetProperty<std::string>( Button::Property::LABEL_TEXT );
-
-  DALI_TEST_EQUALS( labelText, TEST_LABEL2,  TEST_LOCATION );
+  DALI_TEST_EQUALS( GetButtonText( button ), TEST_LABEL2,  TEST_LOCATION );
 
   END_TEST;
 }
@@ -1238,3 +1270,38 @@ int UtcDaliButtonSetGetDepreciatedPropertiesWithURL(void)
 
 END_TEST;
 }
+
+int UtcDaliButtonSetLabelTextDeprecatedPropertyP(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliButtonSetLabelTextDeprecatedPropertyP");
+
+  const std::string TEST_LABEL1 = "test label one";
+  const std::string TEST_LABEL2 = "test label two";
+
+  Button button = PushButton::New();
+
+  button.SetProperty( Toolkit::Button::Property::LABEL,
+                        Property::Map().Add( Toolkit::Visual::Property::TYPE, Toolkit::DevelVisual::TEXT )
+                                       .Add( Toolkit::TextVisual::Property::POINT_SIZE, 15.0f )
+                     );
+
+  button.SetProperty( Button::Property::LABEL_TEXT, TEST_LABEL1 );
+
+  std::string labelText = button.GetProperty<std::string>( Button::Property::LABEL_TEXT );
+
+  DALI_TEST_EQUALS( labelText, TEST_LABEL1,  TEST_LOCATION );
+
+  Property::Map propertyMap;
+  propertyMap.Insert( Toolkit::Visual::Property::TYPE,  Toolkit::DevelVisual::TEXT );
+  propertyMap.Insert( Toolkit::TextVisual::Property::TEXT,  TEST_LABEL2 );
+  propertyMap.Insert( Toolkit::TextVisual::Property::TEXT_COLOR, Color::BLUE );
+  propertyMap.Insert( Toolkit::TextVisual::Property::POINT_SIZE, 15.0f );
+  button.SetProperty( Button::Property::LABEL, propertyMap );
+
+  labelText = button.GetProperty<std::string>( Button::Property::LABEL_TEXT );
+
+  DALI_TEST_EQUALS( labelText, TEST_LABEL2,  TEST_LOCATION );
+
+  END_TEST;
+}
index 81a5781..93ee34e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 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.
@@ -607,3 +607,117 @@ int UtcDaliControlImplGetControlExtensionP(void)
 
   END_TEST;
 }
+
+int UtcDaliControlAutoClipping(void)
+{
+  ToolkitTestApplication application;
+  Control control = Control::New();
+
+  tet_infoline( "Test to see if a renderer gets added when we are clipping children" );
+
+  DALI_TEST_EQUALS( 0, control.GetRendererCount(), TEST_LOCATION );
+
+  control.SetProperty( Actor::Property::CLIPPING_MODE, ClippingMode::CLIP_CHILDREN );
+
+  Stage::GetCurrent().Add( control );
+
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS( 1, control.GetRendererCount(), TEST_LOCATION );
+
+  END_TEST;
+}
+
+int UtcDaliControlAutoClippingN(void)
+{
+  ToolkitTestApplication application;
+  Control control = Control::New();
+  control.SetProperty( Control::Property::BACKGROUND, Property::Map().Add( Visual::Property::TYPE, Visual::COLOR )
+                                                                     .Add( ColorVisual::Property::MIX_COLOR, Color::RED ) );
+
+  tet_infoline( "Test to ensure that a renderer does NOT get added when we are clipping children and already have renderers/visuals" );
+
+  DALI_TEST_EQUALS( 0, control.GetRendererCount(), TEST_LOCATION );
+
+  control.SetProperty( Actor::Property::CLIPPING_MODE, ClippingMode::CLIP_CHILDREN );
+
+  Stage::GetCurrent().Add( control );
+
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS( 1, control.GetRendererCount(), TEST_LOCATION ); // Only 1, not 2
+
+  // Ensure the background color is still RED rather than what's set by the automatic clipping
+  Property::Value value = control.GetProperty( Control::Property::BACKGROUND );
+  Property::Map* map = value.GetMap();
+  DALI_TEST_CHECK( map );
+  Property::Value* colorValue = map->Find(ColorVisual::Property::MIX_COLOR );
+  DALI_TEST_CHECK( colorValue );
+  DALI_TEST_EQUALS( colorValue->Get< Vector4 >(), Color::RED, TEST_LOCATION );
+
+  END_TEST;
+}
+
+int UtcDaliControlAutoClippingWhenAlreadyOnStage(void)
+{
+  ToolkitTestApplication application;
+  Control control = Control::New();
+
+  tet_infoline( "Test to see if a renderer gets added when we are clipping children and when already on stage" );
+
+  DALI_TEST_EQUALS( 0, control.GetRendererCount(), TEST_LOCATION );
+
+  Stage::GetCurrent().Add( control );
+
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS( 0, control.GetRendererCount(), TEST_LOCATION );
+
+  control.SetProperty( Actor::Property::CLIPPING_MODE, ClippingMode::CLIP_CHILDREN );
+
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS( 1, control.GetRendererCount(), TEST_LOCATION );
+
+  END_TEST;
+}
+
+int UtcDaliControlAutoClippingWhenAlreadyOnStageN(void)
+{
+  ToolkitTestApplication application;
+  Control control = Control::New();
+  control.SetProperty( Control::Property::BACKGROUND, Property::Map().Add( Visual::Property::TYPE, Visual::COLOR )
+                                                                     .Add( ColorVisual::Property::MIX_COLOR, Color::RED ) );
+
+  tet_infoline( "Test to ensure that a renderer does NOT get added when we are clipping children and already have renderers/visuals and when already on stage" );
+
+  DALI_TEST_EQUALS( 0, control.GetRendererCount(), TEST_LOCATION );
+
+  Stage::GetCurrent().Add( control );
+
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS( 1, control.GetRendererCount(), TEST_LOCATION );
+
+  control.SetProperty( Actor::Property::CLIPPING_MODE, ClippingMode::CLIP_CHILDREN );
+
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS( 1, control.GetRendererCount(), TEST_LOCATION ); // Still should be 1
+
+  // Ensure the background color is still RED rather than what's set by the automatic clipping
+  Property::Value value = control.GetProperty( Control::Property::BACKGROUND );
+  Property::Map* map = value.GetMap();
+  DALI_TEST_CHECK( map );
+  Property::Value* colorValue = map->Find(ColorVisual::Property::MIX_COLOR );
+  DALI_TEST_CHECK( colorValue );
+  DALI_TEST_EQUALS( colorValue->Get< Vector4 >(), Color::RED, TEST_LOCATION );
+
+  END_TEST;
+}
index 4a29efc..77c2436 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 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.
@@ -1351,3 +1351,69 @@ int UtcDaliControlImplRegisterTwoVisualsAndEnableOnlyOne(void)
   END_TEST;
 }
 
+int UtcDaliControlImplAutoClippingWithVisuals(void)
+{
+  ToolkitTestApplication application;
+
+  tet_infoline( "Test to ensure a renderer does NOT get added when we've already registered a visual which we haven't enabled" );
+
+  DummyControl control = DummyControl::New();
+  DummyControlImpl& controlImpl = static_cast<DummyControlImpl&>( control.GetImplementation() );
+
+  Toolkit::VisualFactory visualFactory = Toolkit::VisualFactory::Get();
+  Toolkit::Visual::Base visual;
+  Property::Map map;
+  map[Visual::Property::TYPE] = Visual::COLOR;
+  map[ColorVisual::Property::MIX_COLOR] = Color::RED;
+  visual = visualFactory.CreateVisual( map );
+  DALI_TEST_CHECK(visual);
+  controlImpl.RegisterVisual( Control::CONTROL_PROPERTY_END_INDEX + 1, visual, false );
+
+  DALI_TEST_EQUALS( 0, control.GetRendererCount(), TEST_LOCATION );
+
+  control.SetProperty( Actor::Property::CLIPPING_MODE, ClippingMode::CLIP_CHILDREN );
+
+  Stage::GetCurrent().Add( control );
+
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS( 0, control.GetRendererCount(), TEST_LOCATION );
+
+  END_TEST;
+}
+
+int UtcDaliControlImplAutoClippingWithVisualsAlreadyOnStage(void)
+{
+  ToolkitTestApplication application;
+
+  tet_infoline( "Test to ensure a renderer does NOT get added when we've already registered a visual which we haven't enabled and we're already on the stage" );
+
+  DummyControl control = DummyControl::New();
+  DummyControlImpl& controlImpl = static_cast<DummyControlImpl&>( control.GetImplementation() );
+
+  Toolkit::VisualFactory visualFactory = Toolkit::VisualFactory::Get();
+  Toolkit::Visual::Base visual;
+  Property::Map map;
+  map[Visual::Property::TYPE] = Visual::COLOR;
+  map[ColorVisual::Property::MIX_COLOR] = Color::RED;
+  visual = visualFactory.CreateVisual( map );
+  DALI_TEST_CHECK(visual);
+  controlImpl.RegisterVisual( Control::CONTROL_PROPERTY_END_INDEX + 1, visual, false );
+
+  DALI_TEST_EQUALS( 0, control.GetRendererCount(), TEST_LOCATION );
+
+  Stage::GetCurrent().Add( control );
+
+  application.SendNotification();
+  application.Render();
+
+  control.SetProperty( Actor::Property::CLIPPING_MODE, ClippingMode::CLIP_CHILDREN );
+
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS( 0, control.GetRendererCount(), TEST_LOCATION );
+
+  END_TEST;
+}
index 7beeb96..590614e 100644 (file)
@@ -915,3 +915,127 @@ int UtcDaliTableViewKeyboardFocus(void)
 
   END_TEST;
 }
+
+int UtcDaliTableViewKeyboardFocusInNestedTableView(void)
+{
+  ToolkitTestApplication application;
+
+  TableView tableView = TableView::New(3, 3);
+  tableView.SetKeyboardFocusable( true );
+  tableView.SetName( "TableView");
+
+  for ( int row = 0; row < 3; ++row )
+  {
+    for ( int col = 0; col < 3; ++col )
+    {
+      std::ostringstream str;
+      str << row << "-" << col;
+
+      if (row == 1 && col ==1)
+      {
+        // Add a nested 2x2 table view in the middle cell of the parent table view
+        TableView childTableView = TableView::New(2, 2);
+        childTableView.SetName( str.str() );
+
+        for(int childRow = 0; childRow < 2; childRow++)
+        {
+          for(int childCol = 0; childCol < 2; childCol++)
+          {
+            Control control = Control::New();
+            std::ostringstream nameStr;
+            nameStr << row << "-" << col << "-" << childRow << "-" << childCol;
+            control.SetName( nameStr.str() );
+            control.SetKeyboardFocusable( true );
+            childTableView.AddChild( control, TableView::CellPosition( childRow, childCol ) );
+          }
+        }
+        tableView.AddChild( childTableView, TableView::CellPosition( row, col ) );
+      }
+      else
+      {
+        Control control = Control::New();
+        control.SetName( str.str() );
+        control.SetKeyboardFocusable( true );
+        tableView.AddChild( control, TableView::CellPosition( row, col ) );
+      }
+    }
+  }
+
+  Stage::GetCurrent().Add( tableView );
+
+  application.SendNotification();
+  application.Render();
+
+  Actor firstFocusActor = Toolkit::Internal::GetImplementation( tableView ).GetNextKeyboardFocusableActor( Actor(), Control::KeyboardFocus::RIGHT, true );
+  DALI_TEST_CHECK( firstFocusActor );
+  DALI_TEST_CHECK( firstFocusActor.GetName() == "0-0" );
+
+  KeyboardFocusManager manager = KeyboardFocusManager::Get();
+  manager.SetFocusGroupLoop( false );
+  manager.SetCurrentFocusActor( firstFocusActor );
+
+  DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "0-0" );
+  manager.MoveFocus( Control::KeyboardFocus::RIGHT );
+  DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "0-1" );
+  manager.MoveFocus( Control::KeyboardFocus::RIGHT );
+  DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "0-2" );
+  manager.MoveFocus( Control::KeyboardFocus::RIGHT );
+  DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "1-0" );
+  manager.MoveFocus( Control::KeyboardFocus::RIGHT );
+  DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "1-1-0-0" );
+  manager.MoveFocus( Control::KeyboardFocus::RIGHT );
+  DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "1-1-0-1" );
+  manager.MoveFocus( Control::KeyboardFocus::RIGHT );
+  DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "1-1-1-0" );
+  manager.MoveFocus( Control::KeyboardFocus::RIGHT );
+  DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "1-1-1-1" );
+  manager.MoveFocus( Control::KeyboardFocus::RIGHT );
+  DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "1-2" );
+  manager.MoveFocus( Control::KeyboardFocus::RIGHT );
+  DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "2-0" );
+  manager.MoveFocus( Control::KeyboardFocus::RIGHT );
+  DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "2-1" );
+  manager.MoveFocus( Control::KeyboardFocus::RIGHT );
+  DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "2-2" );
+
+  manager.MoveFocus( Control::KeyboardFocus::LEFT );
+  DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "2-1" );
+  manager.MoveFocus( Control::KeyboardFocus::LEFT );
+  DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "2-0" );
+  manager.MoveFocus( Control::KeyboardFocus::LEFT );
+  DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "1-2" );
+  manager.MoveFocus( Control::KeyboardFocus::LEFT );
+  DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "1-1-1-1" );
+  manager.MoveFocus( Control::KeyboardFocus::LEFT );
+  DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "1-1-1-0" );
+  manager.MoveFocus( Control::KeyboardFocus::LEFT );
+  DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "1-1-0-1" );
+  manager.MoveFocus( Control::KeyboardFocus::LEFT );
+  DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "1-1-0-0" );
+  manager.MoveFocus( Control::KeyboardFocus::LEFT );
+  DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "1-0" );
+  manager.MoveFocus( Control::KeyboardFocus::LEFT );
+  DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "0-2" );
+  manager.MoveFocus( Control::KeyboardFocus::LEFT );
+  DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "0-1" );
+  manager.MoveFocus( Control::KeyboardFocus::LEFT );
+  DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "0-0" );
+
+  manager.MoveFocus( Control::KeyboardFocus::RIGHT );
+  DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "0-1" );
+  manager.MoveFocus( Control::KeyboardFocus::DOWN );
+  DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "1-1-0-0" );
+  manager.MoveFocus( Control::KeyboardFocus::DOWN );
+  DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "1-1-1-0" );
+  manager.MoveFocus( Control::KeyboardFocus::DOWN );
+  DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "2-1" );
+
+  manager.MoveFocus( Control::KeyboardFocus::UP );
+  DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "1-1-1-1" );
+  manager.MoveFocus( Control::KeyboardFocus::UP );
+  DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "1-1-0-1" );
+  manager.MoveFocus( Control::KeyboardFocus::UP );
+  DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "0-1" );
+
+  END_TEST;
+}
index 9bfb68c..085772e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 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.
@@ -277,8 +277,6 @@ void BloomView::OnInitialize()
 
 void BloomView::OnSizeSet(const Vector3& targetSize)
 {
-  Control::OnSizeSet( targetSize );
-
   mTargetSize = Vector2(targetSize);
   mChildrenRoot.SetSize(targetSize);
   mCompositeImageView.SetSize(targetSize);
@@ -300,16 +298,18 @@ void BloomView::OnSizeSet(const Vector3& targetSize)
     Deactivate();
     Activate();
   }
+
+  Control::OnSizeSet( targetSize );
 }
 
 void BloomView::OnChildAdd( Actor& child )
 {
-  Control::OnChildAdd( child );
-
   if( child != mChildrenRoot && child != mInternalRoot)
   {
     mChildrenRoot.Add( child );
   }
+
+  Control::OnChildAdd( child );
 }
 
 void BloomView::OnChildRemove( Actor& child )
index 0c7005b..ed9b2c8 100644 (file)
@@ -348,11 +348,7 @@ bool Button::IsSelected() const
 
 void Button::SetLabelText( const std::string& label )
 {
-  Property::Map labelProperty;
-  labelProperty.Add( Toolkit::Visual::Property::TYPE, Toolkit::DevelVisual::TEXT)
-               .Add( Toolkit::TextVisual::Property::TEXT, label );
-
-  Self().SetProperty( Toolkit::Button::Property::LABEL, labelProperty );
+  Self().SetProperty( Toolkit::Button::Property::LABEL, label );
 }
 
 std::string Button::GetLabelText() const
@@ -372,7 +368,7 @@ std::string Button::GetLabelText() const
   return textLabel;
 }
 
-void Button::MergeLabelProperties( const Property::Map& inMap, Property::Map& outMap )
+void Button::MergeWithExistingLabelProperties( const Property::Map& inMap, Property::Map& outMap )
 {
   DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "MergeLabelProperties with %d properties\n", inMap.Count() );
 
@@ -1224,13 +1220,32 @@ void Button::SetProperty( BaseObject* object, Property::Index index, const Prope
 
       case Toolkit::Button::Property::LABEL:
       {
-        // Get a Property::Map from the property if possible.
-        Property::Map* setPropertyMap = value.GetMap();
-        if( setPropertyMap )
+        Property::Map outTextVisualProperties;
+        std::string textString;
+
+        if ( value.Get( textString ) )
+        {
+          DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::SetProperty Setting TextVisual with string[%s]\n", textString.c_str() );
+
+          Property::Map setPropertyMap;
+          setPropertyMap.Add( Toolkit::Visual::Property::TYPE, Toolkit::DevelVisual::TEXT)
+                        .Add( Toolkit::TextVisual::Property::TEXT, textString );
+
+          GetImplementation( button ).MergeWithExistingLabelProperties( setPropertyMap, outTextVisualProperties );
+        }
+        else
+        {
+          // Get a Property::Map from the property if possible.
+          Property::Map* setPropertyMap = value.GetMap();
+          if( setPropertyMap )
+          {
+            GetImplementation( button ).MergeWithExistingLabelProperties( *setPropertyMap, outTextVisualProperties );
+          }
+        }
+
+        if( !outTextVisualProperties.Empty() )
         {
-          Property::Map textVisualProperties;
-          GetImplementation( button ).MergeLabelProperties( *setPropertyMap, textVisualProperties );
-          GetImplementation( button ).CreateVisualsForComponent( index, textVisualProperties, DepthIndex::CONTENT );
+          GetImplementation( button ).CreateVisualsForComponent( index, outTextVisualProperties, DepthIndex::CONTENT );
           GetImplementation( button ).RelayoutRequest();
         }
         break;
index a079cd5..e0b7d50 100644 (file)
@@ -149,13 +149,13 @@ public:
   std::string GetLabelText() const;
 
   /**
-   * @brief Produces a Property::Map of Text properties to create a Text Visual
+   * @brief Produces a Property::Map of Text properties to create a Text Visual, merging existing properties with supplied map
    * If the label does not exist yet, it is created.
    * The derived buttons are notified if any properties are changed.
    * @param[in] properties A Property::Map of key-value pairs of properties to set.
-   * @param[out] properties A Property::Map of text visual  properties to set.
+   * @param[out] properties A Property::Map of text visual properties to set after merging inMap with existing maps
    */
-  void MergeLabelProperties( const Property::Map& inMap, Property::Map& outMap );
+  void MergeWithExistingLabelProperties( const Property::Map& inMap, Property::Map& outMap );
 
   /**
    * Performs actions as requested using the action name.
index 44bc39b..08cfc16 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 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.
@@ -289,8 +289,6 @@ void EffectsView::OnInitialize()
 
 void EffectsView::OnSizeSet(const Vector3& targetSize)
 {
-  Control::OnSizeSet( targetSize );
-
   mTargetSize = Vector2(targetSize);
 
   // if we are already on stage, need to update render target sizes now to reflect the new size of this actor
@@ -304,13 +302,15 @@ void EffectsView::OnSizeSet(const Vector3& targetSize)
   }
 
   mChildrenRoot.SetSize( targetSize );
+
+  Control::OnSizeSet( targetSize );
 }
 
 void EffectsView::OnStageConnection( int depth )
 {
-  Control::OnStageConnection( depth );
-
   Enable();
+
+  Control::OnStageConnection( depth );
 }
 
 void EffectsView::OnStageDisconnection()
@@ -328,12 +328,12 @@ void EffectsView::OnStageDisconnection()
 
 void EffectsView::OnChildAdd( Actor& child )
 {
-  Control::OnChildAdd( child );
-
   if( child != mChildrenRoot && child != mCameraForChildren )
   {
     mChildrenRoot.Add( child );
   }
+
+  Control::OnChildAdd( child );
 }
 
 void EffectsView::OnChildRemove( Actor& child )
index 94a92a7..03d4583 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 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.
@@ -465,8 +465,6 @@ Property::Value FlexContainer::GetProperty( BaseObject* object, Property::Index
 
 void FlexContainer::OnChildAdd( Actor& child )
 {
-  Control::OnChildAdd( child );
-
   // Anchor actor to top left of the container
   child.SetAnchorPoint( AnchorPoint::TOP_LEFT );
   child.SetParentOrigin( ParentOrigin::TOP_LEFT );
@@ -478,6 +476,8 @@ void FlexContainer::OnChildAdd( Actor& child )
   childNode.node->get_child = GetChildNodeAtIndex;
   childNode.node->is_dirty = IsNodeDirty;
   mChildrenNodes.push_back(childNode);
+
+  Control::OnChildAdd( child );
 }
 
 void FlexContainer::OnChildRemove( Actor& child )
@@ -562,11 +562,8 @@ void FlexContainer::OnSizeSet( const Vector3& size )
 
     RelayoutRequest();
   }
-}
 
-void FlexContainer::OnSizeAnimation( Animation& animation, const Vector3& targetSize )
-{
-  // @todo Animate the children to their target size and position
+  Control::OnSizeSet( size );
 }
 
 void FlexContainer::ComputeLayout()
index f89c1f4..ce09e23 100644 (file)
@@ -2,7 +2,7 @@
 #define __DALI_TOOLKIT_INTERNAL_FLEX_CONTAINER_H__
 
 /*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 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.
@@ -205,11 +205,6 @@ private: // From Control
    */
   virtual void OnSizeSet( const Vector3& size );
 
-  /**
-   * @copydoc CustomActorImpl::OnSizeAnimation(Animation&, const Vector3&)
-   */
-  virtual void OnSizeAnimation(Animation& animation, const Vector3& targetSize);
-
 private: // Implementation
 
   /**
index a202236..2dddad7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 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.
@@ -330,8 +330,6 @@ void GaussianBlurView::OnInitialize()
 
 void GaussianBlurView::OnSizeSet(const Vector3& targetSize)
 {
-  Control::OnSizeSet( targetSize );
-
   mTargetSize = Vector2(targetSize);
 
   mChildrenRoot.SetSize(targetSize);
@@ -356,16 +354,18 @@ void GaussianBlurView::OnSizeSet(const Vector3& targetSize)
     Deactivate();
     Activate();
   }
+
+  Control::OnSizeSet( targetSize );
 }
 
 void GaussianBlurView::OnChildAdd( Actor& child )
 {
-  Control::OnChildAdd( child );
-
   if( child != mChildrenRoot && child != mInternalRoot)
   {
     mChildrenRoot.Add( child );
   }
+
+  Control::OnChildAdd( child );
 }
 
 void GaussianBlurView::OnChildRemove( Actor& child )
index 12205a6..bb48404 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 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.
@@ -288,8 +288,6 @@ void Magnifier::SetFrameVisibility(bool visible)
 
 void Magnifier::OnSizeSet(const Vector3& targetSize)
 {
-  Control::OnSizeSet( targetSize );
-
   // TODO: Once Camera/CameraActor properties function as proper animatable properties
   // this code can disappear.
   // whenever the size of the magnifier changes, the field of view needs to change
@@ -297,6 +295,8 @@ void Magnifier::OnSizeSet(const Vector3& targetSize)
   // a constraint yet as Camera/CameraActor properties are not animatable/constrainable.
   mActorSize = targetSize;
   Update();
+
+  Control::OnSizeSet( targetSize );
 }
 
 float Magnifier::GetMagnificationFactor() const
index dd90747..9c22982 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 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.
@@ -428,8 +428,6 @@ Property::Value Model3dView::GetProperty( BaseObject* object, Property::Index in
 
 void Model3dView::OnStageConnection( int depth )
 {
-  Control::OnStageConnection( depth );
-
   CustomActor self = Self();
   self.AddRenderer( mRenderer );
 
@@ -449,6 +447,8 @@ void Model3dView::OnStageConnection( int depth )
     constraint.AddSource( Source( self, Toolkit::Model3dView::Property::LIGHT_POSITION ) );
     constraint.Apply();
   }
+
+  Control::OnStageConnection( depth );
 }
 
 ///////////////////////////////////////////////////////////
index 1d15650..5ddf48c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 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.
@@ -74,6 +74,8 @@ Toolkit::NavigationView NavigationView::New()
 void NavigationView::OnStageConnection( int depth )
 {
   Self().SetSensitive(true);
+
+  Control::OnStageConnection( depth );
 }
 
 void NavigationView::Push( Actor& actor )
index dc60e63..a66813a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 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.
@@ -473,9 +473,9 @@ void PageTurnView::SetupShadowView()
 
 void PageTurnView::OnStageConnection( int depth )
 {
-  Control::OnStageConnection( depth );
-
   SetupShadowView();
+
+  Control::OnStageConnection( depth );
 }
 
 void PageTurnView::OnStageDisconnection()
index d12e273..9794921 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 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.
@@ -1574,16 +1574,14 @@ bool Popup::OnDialogTouched( Actor actor, const TouchData& touch )
 
 void Popup::OnStageConnection( int depth )
 {
-  Control::OnStageConnection( depth );
-
   mLayoutDirty = true;
   RelayoutRequest();
+
+  Control::OnStageConnection( depth );
 }
 
 void Popup::OnChildAdd( Actor& child )
 {
-  Control::OnChildAdd( child );
-
   // Re-parent any children added by user to the body layer.
   if( mAlterAddedChild )
   {
@@ -1594,6 +1592,8 @@ void Popup::OnChildAdd( Actor& child )
     mLayoutDirty = true;
     RelayoutRequest();
   }
+
+  Control::OnChildAdd( child );
 }
 
 void Popup::LayoutContext( const Vector2& size )
index 2192d5e..6e301cb 100755 (executable)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 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.
@@ -496,6 +496,8 @@ void ScrollBar::OnSizeSet( const Vector3& size )
   {
     mIndicator.SetSize(size.width, mIndicatorFixedHeight);
   }
+
+  Control::OnSizeSet( size );
 }
 
 void ScrollBar::SetScrollDirection( Toolkit::ScrollBar::Direction direction )
index 7770147..a5741ab 100755 (executable)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 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.
@@ -997,6 +997,8 @@ void ItemView::OnChildAdd(Actor& child)
                                         Toolkit::ItemView::Property::SCROLL_CONTENT_SIZE);
     }
   }
+
+  Scrollable::OnChildAdd( child );
 }
 
 bool ItemView::OnWheelEvent(const WheelEvent& event)
index 0d8becc..0da1660 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 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.
@@ -701,8 +701,6 @@ void ScrollView::OnInitialize()
 
 void ScrollView::OnStageConnection( int depth )
 {
-  ScrollBase::OnStageConnection( depth );
-
   DALI_LOG_SCROLL_STATE("[0x%X]", this);
 
   if ( mSensitive )
@@ -710,11 +708,14 @@ void ScrollView::OnStageConnection( int depth )
     SetScrollSensitive( false );
     SetScrollSensitive( true );
   }
+
   if(IsOvershootEnabled())
   {
     // try and make sure property notifications are set
     EnableScrollOvershoot(true);
   }
+
+  ScrollBase::OnStageConnection( depth );
 }
 
 void ScrollView::OnStageDisconnection()
@@ -1941,6 +1942,8 @@ void ScrollView::OnSizeSet( const Vector3& size )
   {
     mOvershootIndicator->Reset();
   }
+
+  ScrollBase::OnSizeSet( size );
 }
 
 void ScrollView::OnChildAdd(Actor& child)
index b486fbb..c8605c1 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 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.
@@ -297,12 +297,12 @@ void ShadowView::OnInitialize()
 
 void ShadowView::OnChildAdd( Actor& child )
 {
-  Control::OnChildAdd( child );
-
   if( child != mChildrenRoot && child != mBlurRootActor)
   {
     mChildrenRoot.Add( child );
   }
+
+  Control::OnChildAdd( child );
 }
 
 void ShadowView::OnChildRemove( Actor& child )
index 1d2e001..f322618 100755 (executable)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 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.
@@ -205,10 +205,6 @@ void Slider::OnInitialize()
   self.TouchSignal().Connect( this, &Slider::OnTouch );
 }
 
-void Slider::OnSizeSet( const Vector3& size )
-{
-}
-
 void Slider::OnRelayout( const Vector2& size, RelayoutContainer& container )
 {
   SetHitRegion( Vector2( size.x, GetHitRegion().y ) );
index 7879f37..cbb23b0 100755 (executable)
@@ -2,7 +2,7 @@
 #define __DALI_TOOLKIT_INTERNAL_SLIDER_H__
 
 /*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 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.
@@ -282,11 +282,6 @@ protected:
   virtual ~Slider();
 
   /**
-   * @copydoc CustomActorImpl::OnSizeSet( const Vector3& size )
-   */
-  virtual void OnSizeSet( const Vector3& size );
-
-  /**
    * @copydoc CustomActorImpl::OnRelayout
    */
   virtual void OnRelayout( const Vector2& size, RelayoutContainer& container );
index 4e74276..a93257d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 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.
@@ -292,6 +292,8 @@ void SuperBlurView::OnSizeSet( const Vector3& targetSize )
       SetImage( mInputImage );
     }
   }
+
+  Control::OnSizeSet( targetSize );
 }
 
 void SuperBlurView::OnStageConnection( int depth )
@@ -301,7 +303,7 @@ void SuperBlurView::OnStageConnection( int depth )
     return;
   }
 
-  // Chaining up first ensures visuals have SetOnStage called to create their renderers
+  // Exception to the rule, chaining up first ensures visuals have SetOnStage called to create their renderers
   Control::OnStageConnection( depth );
 
   Actor self = Self();
@@ -310,6 +312,7 @@ void SuperBlurView::OnStageConnection( int depth )
     // Note that the renderer indices are depending on the order they been added to the actor
     // which might be different from the blur level of its texture.
     // We can check the depth index of the renderer to know which blurred image it renders.
+    // All visuals WILL have renderers at this point as we are simply creating visuals with an Image handle.
     Renderer renderer = self.GetRendererAt( i );
     int depthIndex = renderer.GetProperty<int>(Renderer::Property::DEPTH_INDEX);
     if( depthIndex > 0 )
@@ -322,11 +325,6 @@ void SuperBlurView::OnStageConnection( int depth )
   }
 }
 
-void SuperBlurView::OnStageDisconnection( )
-{
-  Control::OnStageDisconnection();
-}
-
 Vector3 SuperBlurView::GetNaturalSize()
 {
   if( mInputImage )
index 4380a6e..0c782c9 100644 (file)
@@ -2,7 +2,7 @@
 #define __DALI_TOOLKIT_INTERNAL_SUPER_BLUR_VIEW_H__
 
 /*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 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.
@@ -132,11 +132,6 @@ private: // from Control
   virtual void OnStageConnection( int depth );
 
   /**
-   * @copydoc CustomActorImpl::OnStageDisconnection()
-   */
-  virtual void OnStageDisconnection();
-
-  /**
    * @copydoc CustomActorImpl::GetNaturalSize()
    */
   virtual Vector3 GetNaturalSize();
index dea576c..a674abb 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 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.
@@ -795,6 +795,8 @@ void TableView::OnSizeSet( const Vector3& size )
   // rows and columns must be recalculated or the new size will not take effect.
   mRowDirty = mColumnDirty = true;
   RelayoutRequest();
+
+  Control::OnSizeSet( size );
 }
 
 void TableView::OnRelayout( const Vector2& size, RelayoutContainer& container )
@@ -961,98 +963,101 @@ Property::Value TableView::GetProperty( BaseObject* object, Property::Index inde
 
 void TableView::OnChildAdd( Actor& child )
 {
-  Control::OnChildAdd( child );
-
-  if( mLayoutingChild )
+  if( ! mLayoutingChild )
   {
-    // we're in the middle of laying out children so no point doing anything here
-    return;
-  }
+    // Ensure we're not in the middle of laying out children
 
-  // Check child properties on actor to decide its position inside the table
-  HorizontalAlignment::Type horizontalAlignment = HorizontalAlignment::LEFT;
-  VerticalAlignment::Type verticalAlignment = VerticalAlignment::TOP;
+    // Check child properties on actor to decide its position inside the table
+    HorizontalAlignment::Type horizontalAlignment = HorizontalAlignment::LEFT;
+    VerticalAlignment::Type verticalAlignment = VerticalAlignment::TOP;
 
-  if( child.GetPropertyType( Toolkit::TableView::ChildProperty::CELL_HORIZONTAL_ALIGNMENT ) != Property::NONE )
-  {
-    std::string value = child.GetProperty( Toolkit::TableView::ChildProperty::CELL_HORIZONTAL_ALIGNMENT ).Get<std::string >();
-    Scripting::GetEnumeration< HorizontalAlignment::Type >( value.c_str(),
-                                                            HORIZONTAL_ALIGNMENT_STRING_TABLE,
-                                                            HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT,
-                                                            horizontalAlignment );
-  }
+    if( child.GetPropertyType( Toolkit::TableView::ChildProperty::CELL_HORIZONTAL_ALIGNMENT ) != Property::NONE )
+    {
+      std::string value = child.GetProperty( Toolkit::TableView::ChildProperty::CELL_HORIZONTAL_ALIGNMENT ).Get<std::string >();
+      Scripting::GetEnumeration< HorizontalAlignment::Type >( value.c_str(),
+                                                              HORIZONTAL_ALIGNMENT_STRING_TABLE,
+                                                              HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT,
+                                                              horizontalAlignment );
+    }
 
-  if( child.GetPropertyType( Toolkit::TableView::ChildProperty::CELL_VERTICAL_ALIGNMENT ) != Property::NONE )
-  {
-    std::string value = child.GetProperty( Toolkit::TableView::ChildProperty::CELL_VERTICAL_ALIGNMENT ).Get<std::string >();
-    Scripting::GetEnumeration< VerticalAlignment::Type >( value.c_str(),
-                                                          VERTICAL_ALIGNMENT_STRING_TABLE,
-                                                          VERTICAL_ALIGNMENT_STRING_TABLE_COUNT,
-                                                          verticalAlignment );
-  }
+    if( child.GetPropertyType( Toolkit::TableView::ChildProperty::CELL_VERTICAL_ALIGNMENT ) != Property::NONE )
+    {
+      std::string value = child.GetProperty( Toolkit::TableView::ChildProperty::CELL_VERTICAL_ALIGNMENT ).Get<std::string >();
+      Scripting::GetEnumeration< VerticalAlignment::Type >( value.c_str(),
+                                                            VERTICAL_ALIGNMENT_STRING_TABLE,
+                                                            VERTICAL_ALIGNMENT_STRING_TABLE_COUNT,
+                                                            verticalAlignment );
+    }
 
-  Toolkit::TableView::CellPosition cellPosition;
-  if( child.GetPropertyType( Toolkit::TableView::ChildProperty::ROW_SPAN ) != Property::NONE )
-  {
-    cellPosition.rowSpan = static_cast<unsigned int>( child.GetProperty( Toolkit::TableView::ChildProperty::ROW_SPAN ).Get<float>() );
-  }
+    Toolkit::TableView::CellPosition cellPosition;
+    if( child.GetPropertyType( Toolkit::TableView::ChildProperty::ROW_SPAN ) != Property::NONE )
+    {
+      cellPosition.rowSpan = static_cast<unsigned int>( child.GetProperty( Toolkit::TableView::ChildProperty::ROW_SPAN ).Get<float>() );
+    }
 
-  if( child.GetPropertyType( Toolkit::TableView::ChildProperty::COLUMN_SPAN ) != Property::NONE )
-  {
-    cellPosition.columnSpan = static_cast<unsigned int>( child.GetProperty( Toolkit::TableView::ChildProperty::COLUMN_SPAN ).Get<float>() );
-  }
+    if( child.GetPropertyType( Toolkit::TableView::ChildProperty::COLUMN_SPAN ) != Property::NONE )
+    {
+      cellPosition.columnSpan = static_cast<unsigned int>( child.GetProperty( Toolkit::TableView::ChildProperty::COLUMN_SPAN ).Get<float>() );
+    }
 
-  if( child.GetPropertyType( Toolkit::TableView::ChildProperty::CELL_INDEX ) != Property::NONE )
-  {
-    Vector2 indices = child.GetProperty( Toolkit::TableView::ChildProperty::CELL_INDEX ).Get<Vector2 >();
-    cellPosition.rowIndex = static_cast<unsigned int>( indices.x );
-    cellPosition.columnIndex = static_cast<unsigned int>( indices.y );
+    if( child.GetPropertyType( Toolkit::TableView::ChildProperty::CELL_INDEX ) != Property::NONE )
+    {
+      Vector2 indices = child.GetProperty( Toolkit::TableView::ChildProperty::CELL_INDEX ).Get<Vector2 >();
+      cellPosition.rowIndex = static_cast<unsigned int>( indices.x );
+      cellPosition.columnIndex = static_cast<unsigned int>( indices.y );
 
-    AddChild( child, cellPosition );
-    SetCellAlignment(cellPosition, horizontalAlignment, verticalAlignment);
+      AddChild( child, cellPosition );
+      SetCellAlignment(cellPosition, horizontalAlignment, verticalAlignment);
+    }
+    else
+    {
+      bool availableCellFound = false;
 
-    // Do not continue
-    return;
-  }
+      // Find the first available cell to store the actor in
+      const unsigned int rowCount = mCellData.GetRows();
+      const unsigned int columnCount = mCellData.GetColumns();
+      for( unsigned int row = 0; row < rowCount && !availableCellFound; ++row )
+      {
+        for( unsigned int column = 0; column < columnCount && !availableCellFound; ++column )
+        {
+          if( !(mCellData[ row ][ column ].actor) )
+          {
+            // Put the actor in the cell
+            CellData data;
+            data.actor = child;
+            data.position.columnIndex = column;
+            data.position.rowIndex = row;
+            data.horizontalAlignment = horizontalAlignment;
+            data.verticalAlignment = verticalAlignment;
+            mCellData[ row ][ column ] = data;
+
+            availableCellFound = true;
+            break;
+          }
+        }
+      }
 
-  // Find the first available cell to store the actor in
-  const unsigned int rowCount = mCellData.GetRows();
-  const unsigned int columnCount = mCellData.GetColumns();
-  for( unsigned int row = 0; row < rowCount; ++row )
-  {
-    for( unsigned int column = 0; column < columnCount; ++column )
-    {
-      if( !(mCellData[ row ][ column ].actor) )
+      if( ! availableCellFound )
       {
-        // Put the actor in the cell
+        // No empty cells, so increase size of the table
+        unsigned int newColumnCount = ( columnCount > 0 ) ? columnCount : 1;
+        ResizeContainers( rowCount + 1, newColumnCount );
+
+        // Put the actor in the first cell of the new row
         CellData data;
         data.actor = child;
-        data.position.columnIndex = column;
-        data.position.rowIndex = row;
+        data.position.rowIndex = rowCount;
+        data.position.columnIndex = 0;
         data.horizontalAlignment = horizontalAlignment;
         data.verticalAlignment = verticalAlignment;
-        mCellData[ row ][ column ] = data;
-
-        // Don't continue
-        RelayoutRequest();
-        return;
+        mCellData[ rowCount ][ 0 ] = data;
       }
+
+      RelayoutRequest();
     }
   }
 
-  // No empty cells, so increase size of the table
-  unsigned int newColumnCount = ( columnCount > 0 ) ? columnCount : 1;
-  ResizeContainers( rowCount + 1, newColumnCount );
-
-  // Put the actor in the first cell of the new row
-  CellData data;
-  data.actor = child;
-  data.position.rowIndex = rowCount;
-  data.position.columnIndex = 0;
-  data.horizontalAlignment = horizontalAlignment;
-  data.verticalAlignment = verticalAlignment;
-  mCellData[ rowCount ][ 0 ] = data;
-  RelayoutRequest();
+  Control::OnChildAdd( child );
 }
 
 void TableView::OnChildRemove( Actor& child )
@@ -1077,6 +1082,8 @@ TableView::TableView( unsigned int initialRows, unsigned int initialColumns )
   mRowDirty( true ),     // Force recalculation first time
   mColumnDirty( true )
 {
+  mCurrentColumn = 0;
+  mCurrentRow = 0;
   SetKeyboardNavigationSupport( true );
   ResizeContainers( initialRows, initialColumns );
 }
@@ -1398,13 +1405,42 @@ Actor TableView::GetNextKeyboardFocusableActor(Actor currentFocusedActor, Toolki
       // Move the focus if we haven't lost it.
       if(!focusLost)
       {
+        // Save the new focus cell positions of TableView.
+        mCurrentColumn = currentColumn;
+        mCurrentRow = currentRow;
+
         nextFocusableActor = GetChildAt(Toolkit::TableView::CellPosition(currentRow, currentColumn));
       }
     }
     else
     {
-      // The current focused actor is not within table view, so the child in the first cell should be focused.
-      nextFocusableActor = GetChildAt(Toolkit::TableView::CellPosition(0, 0));
+      // The current focused actor is not within TableView.
+      // This means that the TableView has gained the Focus again.
+
+      unsigned int numberOfColumns = GetColumns();
+      unsigned int numberOfRows = GetRows();
+
+      if( (mCurrentRow != 0 && mCurrentColumn != 0) && // Last saved cell was not the first cell
+          (mCurrentRow != numberOfRows - 1 && mCurrentColumn != numberOfColumns - 1) ) // Last saved cell was not the last cell
+      {
+        // This condition handles the cases when parent TableView gained the focus again after the child layout
+        // container (i.e. TableView) has no more items (i.e. actors) to be focused on in a given direction.
+
+        // Move the focus to next cell towards the given direction in a TableView if the last saved cell was not the first or last cell.
+        nextFocusableActor = GetNextKeyboardFocusableActor(GetChildAt(Toolkit::TableView::CellPosition(mCurrentRow, mCurrentColumn)), direction, loopEnabled);
+      }
+      else
+      {
+        // Otherwise, move the focus to either the first or the last cell according to the given direction.
+        if(direction == Toolkit::Control::KeyboardFocus::LEFT || direction == Toolkit::Control::KeyboardFocus::UP)
+        {
+          nextFocusableActor = GetChildAt(Toolkit::TableView::CellPosition(numberOfRows - 1, numberOfColumns - 1));
+        }
+        else
+        {
+          nextFocusableActor = GetChildAt(Toolkit::TableView::CellPosition(0, 0));
+        }
+      }
     }
   }
 
index d6e62b6..be1f702 100644 (file)
@@ -497,6 +497,8 @@ private: // Data
   Size mFixedTotals;             ///< Accumulated totals for fixed width and height
 
   Size mPadding;                 ///< Padding to apply to each cell
+  unsigned int mCurrentRow;      ///< Last / current focused row
+  unsigned int mCurrentColumn;   ///< Last / current focused column
   bool mLayoutingChild;          ///< Can't be a bitfield due to Relayouting lock
   bool mRowDirty : 1;            ///< Flag to indicate the row data is dirty
   bool mColumnDirty : 1;         ///< Flag to indicate the column data is dirty
index fec052a..aab4f95 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 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.
@@ -1374,13 +1374,13 @@ void TextEditor::KeyboardStatusChanged(bool keyboardShown)
 
 void TextEditor::OnStageConnection( int depth )
 {
-  // Call the Control::OnStageConnection() to set the depth of the background.
-  Control::OnStageConnection( depth );
-
   // Sets the depth to the visuals inside the text's decorator.
   mDecorator->SetTextDepth( depth );
 
   // The depth of the text renderer is set in the RenderText() called from OnRelayout().
+
+  // Call the Control::OnStageConnection() to set the depth of the background.
+  Control::OnStageConnection( depth );
 }
 
 bool TextEditor::OnTouched( Actor actor, const TouchData& touch )
index 44dc851..63568e6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 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.
@@ -1572,13 +1572,13 @@ void TextField::KeyboardStatusChanged(bool keyboardShown)
 
 void TextField::OnStageConnection( int depth )
 {
-  // Call the Control::OnStageConnection() to set the depth of the background.
-  Control::OnStageConnection( depth );
-
   // Sets the depth to the visuals inside the text's decorator.
   mDecorator->SetTextDepth( depth );
 
   // The depth of the text renderer is set in the RenderText() called from OnRelayout().
+
+  // Call the Control::OnStageConnection() to set the depth of the background.
+  Control::OnStageConnection( depth );
 }
 
 bool TextField::OnTouched( Actor actor, const TouchData& touch )
index e4a8b53..9f7863f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 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.
@@ -790,14 +790,6 @@ void TextLabel::OnStageConnect( Dali::Actor actor )
   }
 }
 
-void TextLabel::OnStageConnection( int depth )
-{
-  // Call the Control::OnStageConnection() to set the depth of the background.
-  Control::OnStageConnection( depth );
-
-  // The depth of the text renderer is set in the RenderText() called from OnRelayout().
-}
-
 void TextLabel::ScrollingFinished()
 {
   // Pure Virtual from TextScroller Interface
index c928763..bc2459f 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_TOOLKIT_INTERNAL_TEXT_LABEL_H
 
 /*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 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.
@@ -95,11 +95,6 @@ private: // From Control
    */
   virtual float GetHeightForWidth( float width );
 
-  /**
-   * @copydoc Control::OnStageConnection()
-   */
-  virtual void OnStageConnection( int depth );
-
 // From ControlInterface
 
   /**
index c91f71d..459e534 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 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.
@@ -394,15 +394,6 @@ void TextSelectionPopup::OnInitialize()
   self.SetProperty( Actor::Property::CLIPPING_MODE, ClippingMode::CLIP_CHILDREN );
 }
 
-void TextSelectionPopup::OnStageConnection( int depth )
-{
-  DALI_LOG_INFO( gLogFilter, Debug::General, "TextSelectionPopup::OnStageConnection\n" );
-  // Call the Control::OnStageConnection() to set the depth of the background.
-  Control::OnStageConnection( depth );
-
-  // TextSelectionToolbar::OnStageConnection() will set the depths of all the popup's components.
-}
-
 void TextSelectionPopup::HideAnimationFinished( Animation& animation )
 {
   Actor self = Self();
index e2a9497..419720f 100644 (file)
@@ -2,7 +2,7 @@
 #define __DALI_TOOLKIT_INTERNAL_TEXT_SELECTION_POPUP_H__
 
 /*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 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.
@@ -142,11 +142,6 @@ private: // From Control
    */
   virtual void OnInitialize();
 
-  /**
-   * @copydoc Control::OnStageConnection()
-   */
-  virtual void OnStageConnection( int depth );
-
 private: // Implementation
 
   void HideAnimationFinished( Animation& animation );
index 00c74f4..cdd2226 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 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.
@@ -151,15 +151,6 @@ void TextSelectionToolbar::OnRelayout( const Vector2& size, RelayoutContainer& c
   mScrollView.SetRulerX( mRulerX );
 }
 
-void TextSelectionToolbar::OnStageConnection( int depth )
-{
-  // Call the Control::OnStageConnection() to set the depth of the background.
-  Control::OnStageConnection( depth );
-
-  // Texts are controls, they have their own OnStageConnection() implementation.
-  // Icons are inside a TableView. It has it's own OnStageConnection() implementation.
-}
-
 void TextSelectionToolbar::SetPopupMaxSize( const Size& maxSize )
 {
   mMaxSize = maxSize;
index 46e633b..d44daf0 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_TOOLKIT_INTERNAL_TEXT_SELECTION_TOOLBAR_H
 
 /*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 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.
@@ -97,11 +97,6 @@ private: // From Control
   virtual void OnRelayout( const Vector2& size, RelayoutContainer& container );
 
   /**
-   * @copydoc Control::OnStageConnection()
-   */
-  virtual void OnStageConnection( int depth );
-
-  /**
    * @brief Set max size of Popup
    * @param[in] maxSize Size (Vector2)
    */
index 851945d..441b640 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 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.
@@ -317,8 +317,6 @@ void ToolBar::OnInitialize()
 
 void ToolBar::OnChildAdd(Actor& child)
 {
-  Control::OnChildAdd( child );
-
   if( !mInitializing )
   {
     // An actor is being added through the Actor's API.
@@ -335,6 +333,8 @@ void ToolBar::OnChildAdd(Actor& child)
   // No OnChildRemove method required because Actors are added to the mLayout table view, so if an
   // actor is removed using the Actor::RemoveChild method it will not remove anything because the
   // actor is in mLayout not in Self().
+
+  Control::OnChildAdd( child );
 }
 
 } // namespace Internal
index 51bf9a2..2ec07ef 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 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.
@@ -439,13 +439,13 @@ void VideoView::SetDepthIndex( int depthIndex )
 
 void VideoView::OnStageConnection( int depth )
 {
-  Control::OnStageConnection( depth );
-
   if( mVisual )
   {
     CustomActor self = Self();
     Toolkit::GetImplementation(mVisual).SetOnStage( self );
   }
+
+  Control::OnStageConnection( depth );
 }
 
 void VideoView::OnStageDisconnection()
index ffa43e0..460ea31 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 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.
@@ -246,8 +246,6 @@ void CubeTransitionEffect::Initialize()
 
 void CubeTransitionEffect::OnStageConnection( int depth )
 {
-  Control::OnStageConnection( depth );
-
   Geometry geometry = VisualFactoryCache::CreateQuadGeometry();
   Shader shader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER );
 
@@ -262,6 +260,8 @@ void CubeTransitionEffect::OnStageConnection( int depth )
 
   mCurrentRenderer.SetProperty( Renderer::Property::DEPTH_INDEX, depth );
   Self().AddRenderer( mCurrentRenderer );
+
+  Control::OnStageConnection( depth );
 }
 
 void CubeTransitionEffect::OnStageDisconnection()
index 3ccf2d4..e447554 100644 (file)
@@ -192,7 +192,7 @@ public:
       SELECTED_COLOR,
 
       /**
-       * @brief name "label", type Property::Map
+       * @brief name "label", type Property::Map or std::string
        * @SINCE_1_0.0
        */
       LABEL,
index 5103060..c62684f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 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.
@@ -31,6 +31,7 @@
 #include <dali/public-api/size-negotiation/relayout-container.h>
 #include <dali/devel-api/common/owner-container.h>
 #include <dali/devel-api/object/handle-devel.h>
+#include <dali/devel-api/scripting/enum-helper.h>
 #include <dali/devel-api/scripting/scripting.h>
 #include <dali/integration-api/debug.h>
 
@@ -63,6 +64,11 @@ namespace
 Debug::Filter* gLogFilter = Debug::Filter::New( Debug::NoLogging, false, "LOG_CONTROL_VISUALS");
 #endif
 
+DALI_ENUM_TO_STRING_TABLE_BEGIN( CLIPPING_MODE )
+DALI_ENUM_TO_STRING_WITH_SCOPE( ClippingMode, DISABLED )
+DALI_ENUM_TO_STRING_WITH_SCOPE( ClippingMode, CLIP_CHILDREN )
+DALI_ENUM_TO_STRING_TABLE_END( CLIPPING_MODE )
+
 /**
  * Struct used to store Visual within the control, index is a unique key for each visual.
  */
@@ -1149,16 +1155,33 @@ void Control::OnStageConnection( int depth )
 {
   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Control::OnStageConnection number of registered visuals(%d)\n",  mImpl->mVisuals.Size() );
 
+  Actor self( Self() );
+
   for(RegisteredVisualContainer::Iterator iter = mImpl->mVisuals.Begin(); iter!= mImpl->mVisuals.End(); iter++)
   {
     // Check whether the visual is empty and enabled
     if( (*iter)->visual && (*iter)->enabled )
     {
       DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Control::OnStageConnection Setting visual(%d) on stage\n", (*iter)->index );
-      Actor self( Self() );
       Toolkit::GetImplementation((*iter)->visual).SetOnStage( self );
     }
   }
+
+  if( mImpl->mVisuals.Empty() && ! self.GetRendererCount() )
+  {
+    Property::Value clippingValue = self.GetProperty( Actor::Property::CLIPPING_MODE );
+    int clippingMode = ClippingMode::DISABLED;
+    if( clippingValue.Get( clippingMode ) )
+    {
+      // Add a transparent background if we do not have any renderers or visuals so we clip our children
+
+      if( clippingMode == ClippingMode::CLIP_CHILDREN )
+      {
+        // Create a transparent background visual which will also get staged.
+        SetBackgroundColor( Color::TRANSPARENT );
+      }
+    }
+  }
 }
 
 void Control::OnStageDisconnection()
@@ -1197,6 +1220,29 @@ void Control::OnChildRemove(Actor& child)
   OnControlChildRemove( child );
 }
 
+void Control::OnPropertySet( Property::Index index, Property::Value propertyValue )
+{
+  Actor self( Self() );
+  if( index == Actor::Property::CLIPPING_MODE )
+  {
+    // Only set the background if we're already on the stage and have no renderers or visuals
+
+    if( mImpl->mVisuals.Empty() && ! self.GetRendererCount() && self.OnStage() )
+    {
+      ClippingMode::Type clippingMode = ClippingMode::DISABLED;
+      if( Scripting::GetEnumerationProperty< ClippingMode::Type >( propertyValue, CLIPPING_MODE_TABLE, CLIPPING_MODE_TABLE_COUNT, clippingMode ) )
+      {
+        // Add a transparent background if we do not have one so we clip children
+
+        if( clippingMode == ClippingMode::CLIP_CHILDREN )
+        {
+          SetBackgroundColor( Color::TRANSPARENT );
+        }
+      }
+    }
+  }
+}
+
 void Control::OnSizeSet(const Vector3& targetSize)
 {
   Toolkit::Visual::Base visual = GetVisual( Toolkit::Control::Property::BACKGROUND );
index 541d489..d850eb4 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_TOOLKIT_CONTROL_IMPL_H
 
 /*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 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.
@@ -393,7 +393,7 @@ protected: // From CustomActorImpl, not to be used by application developers
 
   /**
    * @copydoc CustomActorImpl::OnStageConnection()
-   * @note If overridden, then an up-call to Control::OnStageConnection MUST be made at the start.
+   * @note If overridden, then an up-call to Control::OnStageConnection MUST be made at the end.
    */
   virtual void OnStageConnection( int depth );
 
@@ -405,7 +405,7 @@ protected: // From CustomActorImpl, not to be used by application developers
 
   /**
    * @copydoc CustomActorImpl::OnChildAdd()
-   * @note If overridden, then an up-call to Control::OnChildAdd MUST be made at the start.
+   * @note If overridden, then an up-call to Control::OnChildAdd MUST be made at the end.
    */
   virtual void OnChildAdd( Actor& child );
 
@@ -416,14 +416,20 @@ protected: // From CustomActorImpl, not to be used by application developers
   virtual void OnChildRemove( Actor& child );
 
   /**
+   * @copydoc CustomActorImpl::OnPropertySet()
+   * @note If overridden, then an up-call to Control::OnChildRemove MUST be made at the end.
+   */
+  virtual void OnPropertySet( Property::Index index, Property::Value propertyValue );
+
+  /**
    * @copydoc CustomActorImpl::OnSizeSet()
-   * @note If overridden, then an up-call to Control::OnSizeSet MUST be made at the start.
+   * @note If overridden, then an up-call to Control::OnSizeSet MUST be made at the end.
    */
   virtual void OnSizeSet( const Vector3& targetSize );
 
   /**
    * @copydoc CustomActorImpl::OnSizeAnimation()
-   * @note If overridden, then an up-call to Control::OnSizeAnimation MUST be made at the start.
+   * @note If overridden, then an up-call to Control::OnSizeAnimation MUST be made at the end.
    */
   virtual void OnSizeAnimation( Animation& animation, const Vector3& targetSize );
 
index 415ffb6..b882c1d 100644 (file)
@@ -109,8 +109,6 @@ const std::string& Control::GetStyleName() const
 
 void Control::SetBackgroundColor( const Vector4& color )
 {
-  DALI_LOG_WARNING_NOFN("DEPRECATION WARNING: SetBackgroundColor() is deprecated and will be removed from next release. use Property::BACKGROUND instead.\n" );
-
   Internal::GetImplementation(*this).SetBackgroundColor( color );
 }
 
@@ -123,6 +121,8 @@ Vector4 Control::GetBackgroundColor() const
 
 void Control::SetBackgroundImage( Image image )
 {
+  DALI_LOG_WARNING_NOFN("DEPRECATION WARNING: SetBackgroundImage() is deprecated and will be removed from next release. use Property::BACKGROUND instead.\n" );
+
   Internal::GetImplementation(*this).SetBackgroundImage( image );
 }
 
index d49d32c..60dba05 100755 (executable)
@@ -82,13 +82,13 @@ public:
   };
 
   /**
-   * @brief An enumeration of properties belonging to the ScrollView class.
+   * @brief Enumeration for the instance of properties belonging to the ScrollView class.
    * @SINCE_1_0.0
    */
   struct Property
   {
     /**
-     * @brief An enumeration of properties belonging to the ScrollView class.
+     * @brief Enumeration for the instance of properties belonging to the ScrollView class.
      * @SINCE_1_0.0
      */
     enum
@@ -422,11 +422,12 @@ public:
    *
    * A relayout will occur for the remaining actors; for example if RemoveItem(Item(2, ActorZ), 0) is called,
    * the items with ID 3 or greater will be moved:
-   *   Initial actors:     After remove:
-   *     ID 1 - ActorA       ID 1 - ActorA
-   *     ID 2 - ActorB       ID 2 - ActorC (previously ID 3)
-   *     ID 3 - ActorC       ID 3 - ActorB (previously ID 4)
-   *     ID 4 - ActorD
+   *  | Initial actors:    | After remove:  |
+   *  |:------------------ |:-------------- |
+   *  |  ID 1 - ActorA     |  ID 1 - ActorA |
+   *  |  ID 2 - ActorB     |  ID 2 - ActorC (previously ID 3) |
+   *  |  ID 3 - ActorC     |  ID 3 - ActorB (previously ID 4) |
+   *  |  ID 4 - ActorD     |                |
    * @SINCE_1_0.0
    * @param[in] itemId The Item ID of the item to remove.
    * @param[in] durationSeconds How long the relayout takes in seconds.
index 0028cd7..cb24960 100644 (file)
@@ -492,13 +492,13 @@ public:
   };
 
   /**
-   * @brief An enumeration of properties belonging to the ScrollView class.
+   * @brief Enumeration for the instance of properties belonging to the ScrollView class.
    * @SINCE_1_0.0
    */
   struct Property
   {
     /**
-     * @brief An enumeration of properties belonging to the ScrollView class.
+     * @brief Enumeration for the instance of properties belonging to the ScrollView class.
      * @SINCE_1_0.0
      */
     enum
index be37f50..fb7dd53 100644 (file)
@@ -383,7 +383,7 @@ public:
   void SetFitHeight( unsigned int rowIndex );
 
   /**
-   * @brief Is the row a fit row
+   * @brief Check if the row is a fit row.
    *
    * @SINCE_1_0.0
    * @param[in] rowIndex The row to check
@@ -400,7 +400,7 @@ public:
   void SetFitWidth( unsigned int columnIndex );
 
   /**
-   * @brief Is the column a fit column
+   * @brief Check if the column is a fit column.
    *
    * @SINCE_1_0.0
    * @param[in] columnIndex The column to check
index 4d7751b..0d03d34 100644 (file)
@@ -31,7 +31,7 @@ namespace Toolkit
 
 const unsigned int TOOLKIT_MAJOR_VERSION = 1;
 const unsigned int TOOLKIT_MINOR_VERSION = 2;
-const unsigned int TOOLKIT_MICRO_VERSION = 21;
+const unsigned int TOOLKIT_MICRO_VERSION = 22;
 const char * const TOOLKIT_BUILD_DATE    = __DATE__ " " __TIME__;
 
 #ifdef DEBUG_ENABLED
index 70bddb0..dd8da9b 100644 (file)
@@ -42,7 +42,7 @@ namespace ControlOrientation
 {
 
 /**
- * @brief The internal orientation of a control.
+ * @brief Enumeration for the internal orientation of a control.
  * @SINCE_1_0.0
  */
 enum Type
@@ -59,7 +59,7 @@ enum Type
  * @brief Query whether an orientation is vertical.
  *
  * @param[in] orientation The orientation.
- * @return True if the orientation is vertical.
+ * @return true if the orientation is vertical.
  */
 DALI_IMPORT_API bool IsVertical(ControlOrientation::Type orientation);
 
@@ -68,7 +68,7 @@ DALI_IMPORT_API bool IsVertical(ControlOrientation::Type orientation);
  *
  * @SINCE_1_0.0
  * @param[in] orientation The orientation.
- * @return True if the orientation is horizontal.
+ * @return true if the orientation is horizontal.
  */
 DALI_IMPORT_API bool IsHorizontal(ControlOrientation::Type orientation);
 
index 69abfe1..85d168f 100644 (file)
        {
          "visualType": "TEXT",
          "horizontalAlignment": "CENTER",
-         "pointSize" : 12.0, // Point size must always be provided to Text Visual
+         "pointSize" : 10.0, // Point size must always be provided to Text Visual
          "verticalAlignment": "CENTER"
        },
       "unselectedBackgroundVisual":
       "label":
        {
          "visualType": "TEXT",
-         "pointSize" : 12.0, // Point size must always be provided to Text Visual
+         "pointSize" : 10.0, // Point size must always be provided to Text Visual
          "verticalAlignment": "CENTER"
        },
       "unselectedVisual":
       "label":
        {
          "visualType": "TEXT",
-         "pointSize" : 12.0, // Point size must always be provided to Text Visual
+         "pointSize" : 10.0, // Point size must always be provided to Text Visual
          "verticalAlignment": "CENTER"
        },
       "unselectedVisual":
index a1451ee..54a0220 100644 (file)
@@ -341,10 +341,10 @@ An up call to the Control class is necessary if these methods are overridden.
 // C++
 void MyUIControlImpl::OnChildAdd( Actor& child );
 {
-  // Up call to Control first
-  Control::OnChildAdd( child );
-
   // Do any other operations required upon child addition
+
+  // Up call to Control at the end
+  Control::OnChildAdd( child );
 }
 ~~~
 ~~~{.cpp}
@@ -371,10 +371,10 @@ An up call to the Control class is necessary if these methods are overridden.
 // C++
 void MyUIControlImpl::OnStageConnection( int depth )
 {
-  // Up call to Control first
-  Control::OnStageConnection( depth );
-
   // Do any other operations required upon stage connection
+
+  // Up call to Control at the end
+  Control::OnStageConnection( depth );
 }
 ~~~
 ~~~{.cpp}
@@ -449,6 +449,18 @@ More information on size negotiation can be found [here](@ref size-negotiation-c
  
 ___________________________________________________________________________________________________
 
+### Clipping Support {#creating-controls-clipping}
+
+When an Actor is set to clip its children, the renderers have to be added manually in order to specify what its children need to clip to.
+The Control base class automates the creation of the renderers/visuals when it is set to clip its children.
+This is only done if the application or custom control writer has not added any renderers to the Control or registered any visuals
+(regardless of whether these visuals are enabled or not).
+If custom control writers want to define the clipping visuals themselves, then they should register all required visuals before the control is staged.
+___________________________________________________________________________________________________
+
 ### Other Features {#creating-controls-other}
 
  + [Background](@ref background)
index 66af4d1..81f942c 100644 (file)
@@ -1,6 +1,6 @@
 Name:       dali-addon
 Summary:    DALi module for Node.JS
-Version:    1.2.21
+Version:    1.2.22
 Release:    1
 Group:      Development/Libraries
 License:    Apache License, Version 2.0
index 35d0ed9..0853246 100644 (file)
@@ -1,6 +1,6 @@
 Name:       dali-toolkit
 Summary:    The OpenGLES Canvas Core Library Toolkit
-Version:    1.2.21
+Version:    1.2.22
 Release:    1
 Group:      System/Libraries
 License:    Apache-2.0 and BSD-2-Clause and MIT
index 43660d7..2263391 100644 (file)
@@ -4,6 +4,5 @@ autom4te.cache/
 aclocal.m4
 config/
 config.*
-cpp/dali_wrap.cpp
-cpp/dali_wrap.h
+automatic/*
 configure
index 991c0ee..e1520bf 100755 (executable)
@@ -39,14 +39,16 @@ manual/cpp/callbackbase_wrap.o: $(BUILT_SOURCES)
        g++ -c -fpic $(CXXFLAGS) $(DALICORE_CFLAGS) $(DALIADAPTOR_CFLAGS) $(DALITOOLKIT_CFLAGS) manual/cpp/callbackbase_wrap.cpp -o manual/cpp/callbackbase_wrap.o
 
 NDali.dll: $(BUILT_SOURCES)
-       $(MCS) -nologo -target:library -out:NDali.dll automatic/csharp/*.cs manual/csharp/*.cs
+       $(MCS) -nologo -target:library -out:NDali.dll automatic/csharp/*.cs manual/csharp/*.cs views/*.cs
 
 check-local: examples/dali-test.exe \
              examples/hello-world.exe \
              examples/scroll-view.exe \
              examples/custom-control.exe \
-             examples/spin-control.exe \
+             examples/date-picker.exe \
              examples/control-dashboard.exe \
+             examples/date-picker-using-json.exe \
+             examples/json-loader.exe \
              examples/user-alphafunction.exe \
              examples/image-view.exe \
              examples/libNDalic.so examples/NDali.dll
index 5535ee9..73ce8cc 100755 (executable)
@@ -84,6 +84,7 @@
 %ignore *::AnchorPoint::DEFAULT;
 %ignore *::SetPositionInheritanceMode(PositionInheritanceMode);
 %ignore *::GetKeyValue(SizeType) const;
+%ignore *::TypeInfo::GetCreator() const;
 
 %rename(ParentOriginTop) Dali::ParentOrigin::TOP;
 %rename(ParentOriginBottom) Dali::ParentOrigin::BOTTOM;
@@ -209,6 +210,8 @@ typedef std::pair< Dali::Radian, Dali::Radian > AngleThresholdPair;
 %include <dali/public-api/object/handle.h>
 %include <dali/public-api/object/type-info.h>
 %include <dali/public-api/object/type-registry.h>
+%include <dali/devel-api/object/csharp-type-info.h>
+%include <dali/devel-api/object/csharp-type-registry.h>
 
 %include <dali/public-api/common/constants.h>
 %include <dali/public-api/actors/actor-enumerations.h>
index 1f5149b..e4da86b 100755 (executable)
@@ -53,6 +53,8 @@
 #include <dali/public-api/math/matrix3.h>
 #include <dali/public-api/math/viewport.h>
 #include <dali/public-api/object/property-key.h>
+#include <dali/devel-api/object/csharp-type-info.h>
+#include <dali/devel-api/object/csharp-type-registry.h>
 
 #include <dali/public-api/adaptor-framework/timer.h>
 #include <dali/public-api/adaptor-framework/window.h>
   return $null;
 %}
 
+
+
+
+// Type registry type maps
+%typemap(cstype) Dali::TypeInfo::CreateFunction "System.Delegate"
+%typemap(csin, pre ="System.IntPtr ip = System.Runtime.InteropServices.Marshal.GetFunctionPointerForDelegate($csinput); ")
+  Dali::TypeInfo::CreateFunction "new System.Runtime.InteropServices.HandleRef(null, ip)" // null was this
+
+%typemap(cstype) Dali::CSharpTypeInfo::CreateFunction "System.Delegate"
+%typemap(csin, pre ="System.IntPtr ip = System.Runtime.InteropServices.Marshal.GetFunctionPointerForDelegate($csinput); ")
+   Dali::CSharpTypeInfo::CreateFunction "new System.Runtime.InteropServices.HandleRef(null, ip)" // null was this
+
+
+
+%typemap(cstype) Dali::CSharpTypeInfo::SetPropertyFunction "System.Delegate"
+%typemap(csin, pre ="System.IntPtr ip = System.Runtime.InteropServices.Marshal.GetFunctionPointerForDelegate($csinput); ")
+   Dali::CSharpTypeInfo::SetPropertyFunction "new System.Runtime.InteropServices.HandleRef(null, ip)" // null was this
+
+
+
+%typemap(cstype) Dali::CSharpTypeInfo::GetPropertyFunction "System.Delegate"
+%typemap(csin, pre ="System.IntPtr ip2 = System.Runtime.InteropServices.Marshal.GetFunctionPointerForDelegate($csinput); ")
+   Dali::CSharpTypeInfo::GetPropertyFunction "new System.Runtime.InteropServices.HandleRef(null, ip2)" // null was this
+
+
+
+
+
+
+
 #endif
 
+
+
+/**
+ * Extend the type registry to allow for registering of C# controls and custom properties
+ */
+%extend Dali::TypeRegistration {
+
+
+   static void RegisterControl( const std::string& controlName, Dali::CSharpTypeInfo::CreateFunction createFunc )
+   {
+     Dali::CSharpTypeRegistry::RegisterType( controlName, typeid( Dali::Toolkit::Control), createFunc );
+   };
+
+
+   static void RegisterProperty( const std::string& controlName,
+                    const std::string& propertyName,
+                    int index,
+                    Property::Type type,
+                    Dali::CSharpTypeInfo::SetPropertyFunction setFunc,
+                    Dali::CSharpTypeInfo::GetPropertyFunction getFunc )
+   {
+     Dali::CSharpTypeRegistry::RegisterProperty( controlName, propertyName, index, type, setFunc, getFunc );
+   };
+
+};
+
+
+
+
 %ignore operator<<;
 %ignore *::GetImplementation();
 %ignore *::GetImplementation(Dali::BaseHandle&);
@@ -219,7 +280,7 @@ using namespace Dali::Toolkit;
 
 %include alphafunction.i
 %include name-changed.i
-
+%include property-value.i
 %include dali-operator.i
 %include dali-core.i
 %include dali-adaptor.i
index bc81dec..3db23f4 100644 (file)
 
     public static Application NewApplication(string stylesheet, Application.WINDOW_MODE windowMode) {
 
+      // register all Views with the type registry, so that can be created / styled via JSON
+      ViewRegistryHelper.Initialize();
+
       Application ret = New(1, stylesheet, windowMode);
       if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
 
index db58063..268b7d7 100644 (file)
       }
     }
 
+    ///
+  public void LoadFromFile( string fileName )
+  {
+    try
+    {
+      string json = System.IO.File.ReadAllText( fileName );
+      if( json.Length > 0 )
+      {
+        LoadFromString( json );
+      }
+      else
+      {
+        throw new global::System.InvalidOperationException("Failed to load file " +fileName);
+
+      }
+    }
+    catch ( System.Exception e)
+    {
+      throw new global::System.InvalidOperationException("Failed to parse " +fileName);
+    }
+  }
+
+
     %}
     %enddef
 
diff --git a/plugins/dali-swig/SWIG/property-value.i b/plugins/dali-swig/SWIG/property-value.i
new file mode 100644 (file)
index 0000000..290b4a1
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * 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.
+ *
+ */
+
+#if defined(SWIGCSHARP)
+
+
+ %typemap(cscode) Dali::Property::Value %{
+
+    // Extension to property value class that allows us to create a
+    // PropertyValue from a C# object, e.g. int, float, string
+    static public Property.Value CreateFromObject( System.Object obj)
+    {
+      System.Type type = obj.GetType ();
+
+        Property.Value value;
+
+        if ( type.Equals (typeof(int)) )
+        {
+          System.Console.WriteLine (" got an int property value ");
+          value = new Property.Value ((int) obj );
+        }
+        if ( type.Equals (typeof(System.Int32)) )
+        {
+          System.Console.WriteLine (" got an int property value ");
+          value = new Property.Value ((int) obj );
+        }
+        else if ( type.Equals (typeof(bool)) )
+        {
+          System.Console.WriteLine (" got an bool property value ");
+          value = new Property.Value ((bool) obj );
+        }
+        else if ( type.Equals (typeof(float)) )
+        {
+          System.Console.WriteLine (" got an float property value ");
+          value = new Property.Value ((float) obj );
+        }
+        else if ( type.Equals (typeof(string)) )
+        {
+          System.Console.WriteLine (" got a string property value ");
+          value = new Property.Value ((string) obj );
+        }
+        else if ( type.Equals (typeof(Vector2)) )
+        {
+          System.Console.WriteLine (" got an Vector2 property value ");
+          value = new Property.Value ((Vector2) obj );
+        }
+        else if ( type.Equals (typeof(Vector3)) )
+        {
+          System.Console.WriteLine (" got an Vector3 property value ");
+          value = new Property.Value ((Vector3) obj );
+        }
+        else if ( type.Equals (typeof(Vector4)) )
+        {
+          System.Console.WriteLine (" got an Vector4 property value ");
+
+          value = new Property.Value ((Vector4) obj );
+        }
+        else if ( type.Equals (typeof(Position)) )
+        {
+          System.Console.WriteLine (" got an Position property value ");
+          value = new Property.Value ((Position) obj );
+        }
+        else if ( type.Equals (typeof(Size)) )
+        {
+          System.Console.WriteLine (" got an Size property value ");
+          value = new Property.Value ((Size) obj );
+        }
+        else if ( type.Equals (typeof(Color)) )
+        {
+          System.Console.WriteLine (" got an Color property value ");
+          value = new Property.Value ((Color) obj );
+        }
+        else
+        {
+           throw new global::System.InvalidOperationException("Unimplemented type for Property Value");
+        }
+        return  value;
+    }
+
+
+ %}
+
+
+
+
+#endif
\ No newline at end of file
diff --git a/plugins/dali-swig/examples/date-picker-using-json.cs b/plugins/dali-swig/examples/date-picker-using-json.cs
new file mode 100644 (file)
index 0000000..dbc388c
--- /dev/null
@@ -0,0 +1,170 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * 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.
+ *
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using Dali;
+
+namespace MyCSharpExample
+{
+    // A spin control (for continously changing values when users can easily predict a set of values)
+
+    class Example
+    {
+        private Dali.Application _application;
+        private Spin _spinYear;  // spin control for year
+        private Spin _spinMonth; // spin control for month
+        private Spin _spinDay;   // spin control for day
+        private Builder _builder; // DALi Builder
+
+        public Example(Dali.Application application)
+        {
+            _application = application;
+            _application.Initialized += Initialize;
+        }
+
+        public void Initialize(object source, NUIApplicationInitEventArgs e)
+        {
+
+            Stage stage = Stage.GetCurrent();
+            stage.BackgroundColor = Color.White;
+
+            // load date JSON template...
+
+            _builder = new Builder ();
+
+            // Optional constant to see logging information coming out
+            // of DALi JSON parser (builder)
+            Property.Map constants = new  Property.Map();
+            constants.Insert( "CONFIG_SCRIPT_LOG_LEVEL",  new Property.Value( "Verbose") );
+            _builder.AddConstants( constants );
+
+            _builder.LoadFromFile( "./json/date-picker.json" );
+
+            // create the date-picker from the template in the json file
+            BaseHandle handle =  _builder.Create( "date-picker");
+
+            Actor actorTree =  Actor.DownCast( handle );
+
+            stage.Add( actorTree );
+
+            Actor year  = actorTree.FindChildByName("Year");
+            Actor month  =  actorTree.FindChildByName("Month" );
+            Actor day  = actorTree.FindChildByName("Day");
+
+            // need to get the actual C# View associated with the actor,
+            _spinYear = (Spin ) ViewRegistry.GetCustomViewFromActor( year );
+            _spinMonth = (Spin ) ViewRegistry.GetCustomViewFromActor( month );
+            _spinDay = (Spin ) ViewRegistry.GetCustomViewFromActor( day );
+
+            _spinYear.Value = 2099;
+            _spinMonth.Value = 5;
+            _spinDay.Value = 23;
+
+
+            _spinYear.SetKeyboardFocusable(true);
+            _spinMonth.SetKeyboardFocusable(true);
+            _spinDay.SetKeyboardFocusable(true);
+
+
+            FocusManager keyboardFocusManager = FocusManager.Instance;
+            keyboardFocusManager.PreFocusChange += OnKeyboardPreFocusChange;
+            keyboardFocusManager.FocusedActorEnterKeyPressed += OnFocusedActorEnterKeyPressed;
+
+        }
+
+        private Actor OnKeyboardPreFocusChange(object source, FocusManager.PreFocusChangeEventArgs e)
+        {
+            Actor nextFocusActor = e.Proposed;
+
+            // When nothing has been focused initially, focus the text field in the first spin
+            if (!e.Current && !e.Proposed)
+            {
+                nextFocusActor = _spinYear.SpinText;
+            }
+            else if(e.Direction == View.KeyboardFocus.Direction.LEFT)
+            {
+                // Move the focus to the spin in the left of the current focused spin
+                if(e.Current == _spinMonth.SpinText)
+                {
+                    nextFocusActor = _spinYear.SpinText;
+                }
+                else if(e.Current == _spinDay.SpinText)
+                {
+                    nextFocusActor = _spinMonth.SpinText;
+                }
+            }
+            else if(e.Direction == View.KeyboardFocus.Direction.RIGHT)
+            {
+                // Move the focus to the spin in the right of the current focused spin
+                if(e.Current == _spinYear.SpinText)
+                {
+                    nextFocusActor = _spinMonth.SpinText;
+                }
+                else if(e.Current == _spinMonth.SpinText)
+                {
+                    nextFocusActor = _spinDay.SpinText;
+                }
+            }
+
+            return nextFocusActor;
+        }
+
+        private void OnFocusedActorEnterKeyPressed(object source, FocusManager.FocusedActorEnterKeyEventArgs e)
+        {
+            // Make the text field in the current focused spin to take the key input
+            KeyInputFocusManager manager = KeyInputFocusManager.Get();
+
+            if (e.Actor == _spinYear.SpinText)
+            {
+                if (manager.GetCurrentFocusControl() != _spinYear.SpinText)
+                {
+                    manager.SetFocus(_spinYear.SpinText);
+                }
+            }
+            else if (e.Actor == _spinMonth.SpinText)
+            {
+                if (manager.GetCurrentFocusControl() != _spinMonth.SpinText)
+                {
+                    manager.SetFocus(_spinMonth.SpinText);
+                }
+            }
+            else if (e.Actor == _spinDay.SpinText)
+            {
+                if (manager.GetCurrentFocusControl() != _spinDay.SpinText)
+                {
+                    manager.SetFocus(_spinDay.SpinText);
+                }
+            }
+        }
+
+        public void MainLoop()
+        {
+            _application.MainLoop ();
+        }
+
+        /// <summary>
+        /// The main entry point for the application.
+        /// </summary>
+        [STAThread]
+        static void Main(string[] args)
+        {
+            Example example = new Example(Application.NewApplication());
+            example.MainLoop ();
+        }
+    }
+}
diff --git a/plugins/dali-swig/examples/date-picker.cs b/plugins/dali-swig/examples/date-picker.cs
new file mode 100644 (file)
index 0000000..c9701cf
--- /dev/null
@@ -0,0 +1,196 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * 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.
+ *
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using Dali;
+
+namespace MyCSharpExample
+{
+    // A spin control (for continously changing values when users can easily predict a set of values)
+
+    class Example
+    {
+        private Dali.Application _application;
+        private FlexContainer _container;   // Flex container to hold spin controls
+        private Spin _spinYear;  // spin control for year
+        private Spin _spinMonth; // spin control for month
+        private Spin _spinDay;   // spin control for day
+
+        public Example(Dali.Application application)
+        {
+            _application = application;
+            _application.Initialized += Initialize;
+        }
+
+        public void Initialize(object source, NUIApplicationInitEventArgs e)
+        {
+
+            Stage stage = Stage.GetCurrent();
+            stage.BackgroundColor = Color.White;
+
+            // Create a container for the spins
+            _container = new FlexContainer();
+
+            _container.ParentOrigin = NDalic.ParentOriginCenter;
+            _container.AnchorPoint = NDalic.AnchorPointCenter;
+            _container.FlexDirection = (int)FlexContainer.FlexDirectionType.ROW;
+            _container.Size = new Vector3(480.0f, 150.0f, 0.0f);
+
+            stage.Add(_container);
+
+            // Create a Spin control for year
+            _spinYear = new Spin();
+            _spinYear.ParentOrigin = NDalic.ParentOriginCenter;
+            _spinYear.AnchorPoint = NDalic.AnchorPointCenter;
+            _spinYear.Flex = 0.3f;
+            _spinYear.FlexMargin = new Vector4(5.0f, 0.0f, 5.0f, 0.0f);
+            _container.Add(_spinYear);
+
+            _spinYear.MinValue = 1900;
+            _spinYear.MaxValue = 2100;
+            _spinYear.Value = 2016;
+            _spinYear.Step = 1;
+            _spinYear.MaxTextLength = 4;
+            _spinYear.TextPointSize = 26;
+            _spinYear.TextColor = Color.White;
+            _spinYear.SetKeyboardFocusable(true);
+            _spinYear.Name = "_spinYear";
+
+            // Create a Spin control for month
+            _spinMonth = new Spin();
+            _spinMonth.ParentOrigin = NDalic.ParentOriginCenter;
+            _spinMonth.AnchorPoint = NDalic.AnchorPointCenter;
+            _spinMonth.Flex = 0.3f;
+            _spinMonth.FlexMargin = new Vector4(5.0f, 0.0f, 5.0f, 0.0f);
+            _container.Add(_spinMonth);
+
+            _spinMonth.MinValue = 1;
+            _spinMonth.MaxValue = 12;
+            _spinMonth.Value = 10;
+            _spinMonth.Step = 1;
+            _spinMonth.MaxTextLength = 2;
+            _spinMonth.TextPointSize = 26;
+            _spinMonth.TextColor = Color.White;
+            _spinMonth.SetKeyboardFocusable(true);
+            _spinMonth.Name = "_spinMonth";
+
+            // Create a Spin control for day
+            _spinDay = new Spin();
+            _spinDay.ParentOrigin = NDalic.ParentOriginCenter;
+            _spinDay.AnchorPoint = NDalic.AnchorPointCenter;
+            _spinDay.Flex = 0.3f;
+            _spinDay.FlexMargin = new Vector4(5.0f, 0.0f, 5.0f, 0.0f);
+            _container.Add(_spinDay);
+
+            _spinDay.MinValue = 1;
+            _spinDay.MaxValue = 31;
+            _spinDay.Value = 26;
+            _spinDay.Step = 1;
+            _spinDay.MaxTextLength = 2;
+            _spinDay.TextPointSize = 26;
+            _spinDay.TextColor = Color.White;
+            _spinDay.SetKeyboardFocusable(true);
+            _spinDay.Name = "_spinDay";
+
+            FocusManager keyboardFocusManager = FocusManager.Instance;
+            keyboardFocusManager.PreFocusChange += OnKeyboardPreFocusChange;
+            keyboardFocusManager.FocusedActorEnterKeyPressed += OnFocusedActorEnterKeyPressed;
+
+        }
+
+        private Actor OnKeyboardPreFocusChange(object source, FocusManager.PreFocusChangeEventArgs e)
+        {
+            Actor nextFocusActor = e.Proposed;
+
+            // When nothing has been focused initially, focus the text field in the first spin
+            if (!e.Current && !e.Proposed)
+            {
+                nextFocusActor = _spinYear.SpinText;
+            }
+            else if(e.Direction == View.KeyboardFocus.Direction.LEFT)
+            {
+                // Move the focus to the spin in the left of the current focused spin
+                if(e.Current == _spinMonth.SpinText)
+                {
+                    nextFocusActor = _spinYear.SpinText;
+                }
+                else if(e.Current == _spinDay.SpinText)
+                {
+                    nextFocusActor = _spinMonth.SpinText;
+                }
+            }
+            else if(e.Direction == View.KeyboardFocus.Direction.RIGHT)
+            {
+                // Move the focus to the spin in the right of the current focused spin
+                if(e.Current == _spinYear.SpinText)
+                {
+                    nextFocusActor = _spinMonth.SpinText;
+                }
+                else if(e.Current == _spinMonth.SpinText)
+                {
+                    nextFocusActor = _spinDay.SpinText;
+                }
+            }
+
+            return nextFocusActor;
+        }
+
+        private void OnFocusedActorEnterKeyPressed(object source, FocusManager.FocusedActorEnterKeyEventArgs e)
+        {
+            // Make the text field in the current focused spin to take the key input
+            KeyInputFocusManager manager = KeyInputFocusManager.Get();
+
+            if (e.Actor == _spinYear.SpinText)
+            {
+                if (manager.GetCurrentFocusControl() != _spinYear.SpinText)
+                {
+                    manager.SetFocus(_spinYear.SpinText);
+                }
+            }
+            else if (e.Actor == _spinMonth.SpinText)
+            {
+                if (manager.GetCurrentFocusControl() != _spinMonth.SpinText)
+                {
+                    manager.SetFocus(_spinMonth.SpinText);
+                }
+            }
+            else if (e.Actor == _spinDay.SpinText)
+            {
+                if (manager.GetCurrentFocusControl() != _spinDay.SpinText)
+                {
+                    manager.SetFocus(_spinDay.SpinText);
+                }
+            }
+        }
+
+        public void MainLoop()
+        {
+            _application.MainLoop ();
+        }
+
+        /// <summary>
+        /// The main entry point for the application.
+        /// </summary>
+        [STAThread]
+        static void Main(string[] args)
+        {
+            Example example = new Example(Application.NewApplication());
+            example.MainLoop ();
+        }
+    }
+}
diff --git a/plugins/dali-swig/examples/json-loader.cs b/plugins/dali-swig/examples/json-loader.cs
new file mode 100644 (file)
index 0000000..388b077
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * 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.
+ *
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using Dali;
+
+namespace MyExampleApp
+{
+  class Example
+  {
+    private Dali.Application _application;
+    private Builder _builder;
+    private string _jsonFileName;
+
+    public Example(Dali.Application application, string fileName)
+    {
+      _application = application;
+      _jsonFileName = fileName;
+      _application.Initialized += Initialize;
+    }
+
+    public void Initialize(object source, NUIApplicationInitEventArgs e)
+    {
+        if( _jsonFileName.Length == 0)
+        {
+          Console.WriteLine("Please specify JSON file to load");
+          return;
+        }
+
+        _builder = new Builder ();
+
+        Property.Map constants = new  Property.Map();
+
+        //  In dali-demo we have some JSON files that can be loaded, but they need 3 different macros defining.
+        // The JSON folder is typically installed into dali-env/opt/share/com.samsung.dali-demo/res:
+        //
+        //string demoDirectory = ".../dali-env/opt/share/com.samsung.dali-demo/res";
+        //constants.Insert( "DEMO_IMAGE_DIR" ,  new Property.Value( demoDirectory+"/images") );
+        //constants.Insert( "DEMO_MODEL_DIR" ,  new Property.Value( demoDirectory+"/models") );
+        //constants.Insert( "DEMO_SCRIPT_DIR",  new Property.Value( demoDirectory+"/scripts") );
+        constants.Insert( "CONFIG_SCRIPT_LOG_LEVEL",  new Property.Value( "Verbose") );
+
+         _builder.AddConstants( constants );
+
+
+        Stage stage = Stage.GetCurrent();
+        stage.BackgroundColor = Color.White;
+
+        _builder.LoadFromFile( _jsonFileName );
+
+        _builder.AddActors( stage.GetRootLayer() );
+
+    }
+
+
+    public void MainLoop()
+    {
+      _application.MainLoop ();
+    }
+
+    /// <summary>
+    /// The main entry point for the application.
+    /// </summary>
+    [STAThread]
+    static void Main(string[] args)
+    {
+      string fileName= "";
+
+      if( args.Length > 0)
+      {
+          fileName = args[0];
+      }
+
+      Console.WriteLine("arguments = " + args.Length);
+      Example example = new Example(Application.NewApplication(), fileName);
+      example.MainLoop ();
+    }
+  }
+}
diff --git a/plugins/dali-swig/examples/json/date-picker-template.json b/plugins/dali-swig/examples/json/date-picker-template.json
new file mode 100644 (file)
index 0000000..dd01d8f
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2014 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.
+ *
+ */
+{
+  // Data picker loaded directly on to the stage
+  //
+  "templates": {
+    "date-picker":
+    {
+      "type":"FlexContainer",
+      "name":"exampleDatePicker",
+      "parentOrigin": "CENTER",
+      "anchorPoint": "CENTER",
+      "flexDirection":"ROW",
+      "size":[480.0, 150, 0 ],
+      "actors": [
+      {
+
+        "type": "Spin",
+        "name": "Year",
+        "parentOrigin": "CENTER",
+        "anchorPoint": "CENTER",
+        "Value":2017,
+        "MinValue":1900,
+        "MaxValue":2100,
+        "Step":1,
+        "TextColor":[0.0,0.0,1.0,1.0],
+        "properties": { // properties registered dynamically
+            "flex":0.3,
+            "flexMargin": [5.0,0.0,5.0,0.0]
+        }
+      },
+      {
+
+        "type": "Spin",
+        "name": "Month",
+        "parentOrigin": "CENTER",
+        "anchorPoint": "CENTER",
+        "parentOrigin": "CENTER",
+        "Value":10,
+        "Step":1,
+        "MinValue":1,
+        "MaxValue":12,
+        "TextColor":[1.0,1.0,1.0,1.0],
+        "properties": { // properties registered dynamically
+            "flex":0.3,
+            "flexMargin": [5.0,0.0,5.0,0.0]
+        }
+
+      },
+      {
+
+        "type": "Spin",
+        "name": "Day",
+        "parentOrigin": "CENTER",
+        "anchorPoint": "CENTER",
+        "Value":1,
+        "MinValue":1,
+        "MaxValue":31,
+        "TextColor":[1.0,0.0,0.0,1.0],
+         "properties": { // properties registered dynamically
+            "flex":0.3,
+            "flexMargin": [5.0,0.0,5.0,0.0]
+        }
+      }]
+
+    }
+}
+
+}
+
diff --git a/plugins/dali-swig/examples/json/date-picker.json b/plugins/dali-swig/examples/json/date-picker.json
new file mode 100644 (file)
index 0000000..3126aa3
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2014 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.
+ *
+ */
+{
+  // Data picker loaded directly on to the stage
+  //
+  "stage": [{
+
+      "type":"FlexContainer",
+      "name":"exampleDatePicker",
+      "parentOrigin": "CENTER",
+      "anchorPoint": "CENTER",
+      "flexDirection":"ROW",
+      "size":[480.0, 150, 0 ],
+      "actors": [
+      {
+
+        "type": "Spin",
+        "name": "Year",
+        "parentOrigin": "CENTER",
+        "anchorPoint": "CENTER",
+        "MinValue":1900,
+        "MaxValue":2100,
+        "Value":2017,
+        "Step":1,
+        "TextColor":[0.0,0.0,1.0,1.0],
+        "properties": { // properties registered dynamically
+            "flex":0.3,
+            "flexMargin": [5.0,0.0,5.0,0.0]
+        }
+      },
+      {
+
+        "type": "Spin",
+        "name": "Month",
+        "parentOrigin": "CENTER",
+        "anchorPoint": "CENTER",
+        "parentOrigin": "CENTER",
+        "Step":1,
+        "MinValue":1,
+        "MaxValue":12,
+        "Value":10,
+        "TextColor":[1.0,1.0,1.0,1.0],
+        "properties": { // properties registered dynamically
+            "flex":0.3,
+            "flexMargin": [5.0,0.0,5.0,0.0]
+        }
+
+      },
+      {
+
+        "type": "Spin",
+        "name": "Day",
+        "parentOrigin": "CENTER",
+        "anchorPoint": "CENTER",
+        "MinValue":1,
+        "MaxValue":31,
+        "Value":1,
+        "TextColor":[1.0,0.0,0.0,1.0],
+         "properties": { // properties registered dynamically
+            "flex":0.3,
+            "flexMargin": [5.0,0.0,5.0,0.0]
+        }
+      }]
+
+}]
+
+}
+
diff --git a/plugins/dali-swig/examples/json/spin.json b/plugins/dali-swig/examples/json/spin.json
new file mode 100644 (file)
index 0000000..df9b10c
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2014 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.
+ *
+ */
+{
+  // a tree of actors
+  "stage": [
+    // You can add an array of  Actors / Views here
+    // Lets add a spin to the stage
+    {
+      "type":"Spin",
+      "parentOrigin":"CENTER",
+      "size":[120,120,0]
+      // now lets use the C# app json-loader.exe to load it
+    }
+
+  ]
+}
diff --git a/plugins/dali-swig/examples/spin-control.cs b/plugins/dali-swig/examples/spin-control.cs
deleted file mode 100755 (executable)
index f385852..0000000
+++ /dev/null
@@ -1,460 +0,0 @@
-/*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * 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.
- *
- */
-
-using System;
-using System.Runtime.InteropServices;
-using Dali;
-
-namespace MyCSharpExample
-{
-    // A spin control (for continously changing values when users can easily predict a set of values)
-    class Spin : CustomView
-    {
-        private VisualBase _arrowVisual;
-        private TextField _textField;
-        private int _arrowVisualPropertyIndex;
-        private string _arrowImage;
-        private int _currentValue;
-        private int _minValue;
-        private int _maxValue;
-        private int _singleStep;
-        private bool _wrappingEnabled;
-        private string _fontFamily;
-        private string _fontStyle;
-        private int _pointSize;
-        private Color _textColor;
-        private Color _textBackgroundColor;
-        private int _maxTextLength;
-
-        public Spin() : base(ViewWrapperImpl.CustomViewBehaviour.REQUIRES_KEYBOARD_NAVIGATION_SUPPORT | ViewWrapperImpl.CustomViewBehaviour.DISABLE_STYLE_CHANGE_SIGNALS)
-        {
-        }
-
-        public override void OnInitialize()
-        {
-            // Initialize the properties
-            _arrowImage = "./images/arrow.png";
-            _textBackgroundColor = new Color(0.6f, 0.6f, 0.6f, 1.0f);
-            _currentValue = 0;
-            _minValue = 0;
-            _maxValue = 0;
-            _singleStep = 1;
-            _maxTextLength = 0;
-
-            // Create image visual for the arrow keys
-            _arrowVisualPropertyIndex = RegisterProperty("ArrowImage", new Dali.Property.Value(_arrowImage), Dali.Property.AccessMode.READ_WRITE);
-            _arrowVisual =  VisualFactory.Get().CreateVisual( _arrowImage, new Uint16Pair(150, 150) );
-            RegisterVisual( _arrowVisualPropertyIndex, _arrowVisual );
-
-            // Create a text field
-            _textField = new TextField();
-            _textField.ParentOrigin = NDalic.ParentOriginCenter;
-            _textField.AnchorPoint = NDalic.AnchorPointCenter;
-            _textField.WidthResizePolicy = "SIZE_RELATIVE_TO_PARENT";
-            _textField.HeightResizePolicy = "SIZE_RELATIVE_TO_PARENT";
-            _textField.SizeModeFactor = new Vector3( 1.0f, 0.45f, 1.0f );
-            _textField.PlaceholderText = "----";
-            _textField.BackgroundColor = _textBackgroundColor;
-            _textField.HorizontalAlignment = "Center";
-            _textField.VerticalAlignment = "Center";
-            _textField.SetKeyboardFocusable(true);
-            _textField.Name = "_textField";
-
-            this.Add(_textField);
-
-            _textField.KeyInputFocusGained += TextFieldKeyInputFocusGained;
-            _textField.KeyInputFocusLost += TextFieldKeyInputFocusLost;
-        }
-
-        public override Vector3 GetNaturalSize()
-        {
-            return new Vector3(150.0f, 150.0f, 0.0f);
-        }
-
-        public void TextFieldKeyInputFocusGained(object source, KeyInputFocusGainedEventArgs e)
-        {
-            // Make sure when the current spin that takes input focus also takes the keyboard focus
-            // For example, when you tap the spin directly
-            FocusManager.Instance.SetCurrentFocusActor(_textField);
-        }
-
-        public void TextFieldKeyInputFocusLost(object source, KeyInputFocusLostEventArgs e)
-        {
-            int previousValue = _currentValue;
-
-            // If the input value is invalid, change it back to the previous valid value
-            if(int.TryParse(_textField.Text, out _currentValue))
-            {
-                if (_currentValue < _minValue || _currentValue > _maxValue)
-                {
-                    _currentValue = previousValue;
-                }
-            }
-            else
-            {
-                _currentValue = previousValue;
-            }
-
-            // Otherwise take the new value
-            this.Value = _currentValue;
-        }
-
-        public override Actor GetNextKeyboardFocusableActor(Actor currentFocusedActor, View.KeyboardFocus.Direction direction, bool loopEnabled)
-        {
-            // Respond to Up/Down keys to change the value while keeping the current spin focused
-            Actor nextFocusedActor = currentFocusedActor;
-            if (direction == View.KeyboardFocus.Direction.UP)
-            {
-                this.Value += this.Step;
-                nextFocusedActor = _textField;
-            }
-            else if (direction == View.KeyboardFocus.Direction.DOWN)
-            {
-                this.Value -= this.Step;
-                nextFocusedActor = _textField;
-            }
-            else
-            {
-                // Return a native empty handle as nothing can be focused in the left or right
-                nextFocusedActor = new Actor();
-                nextFocusedActor.Reset();
-            }
-
-            return nextFocusedActor;
-        }
-
-        // Value property of type int:
-        public int Value
-        {
-            get
-            {
-                return _currentValue;
-            }
-            set
-            {
-                _currentValue = value;
-
-                // Make sure no invalid value is accepted
-                if (_currentValue < _minValue)
-                {
-                    _currentValue = _minValue;
-                }
-
-                if (_currentValue > _maxValue)
-                {
-                    _currentValue = _maxValue;
-                }
-
-                _textField.Text = _currentValue.ToString();
-            }
-        }
-
-        // MinValue property of type int:
-        public int MinValue
-        {
-            get
-            {
-                return _minValue;
-            }
-            set
-            {
-              _minValue = value;
-            }
-        }
-
-        // MaxValue property of type int:
-        public int MaxValue
-        {
-            get
-            {
-                return _maxValue;
-            }
-            set
-            {
-              _maxValue = value;
-            }
-        }
-
-        // Step property of type int:
-        public int Step
-        {
-            get
-            {
-                return _singleStep;
-            }
-            set
-            {
-              _singleStep = value;
-            }
-        }
-
-        // WrappingEnabled property of type bool:
-        public bool WrappingEnabled
-        {
-            get
-            {
-                return _wrappingEnabled;
-            }
-            set
-            {
-              _wrappingEnabled = value;
-            }
-        }
-
-        // TextPointSize property of type int:
-        public int TextPointSize
-        {
-            get
-            {
-                return _pointSize;
-            }
-            set
-            {
-              _pointSize = value;
-              _textField.PointSize = _pointSize;
-            }
-        }
-
-        // TextColor property of type Color:
-        public Color TextColor
-        {
-            get
-            {
-                return _textColor;
-            }
-            set
-            {
-              _textColor = value;
-              _textField.TextColor = _textColor;
-            }
-        }
-
-        // MaxTextLength property of type int:
-        public int MaxTextLength
-        {
-            get
-            {
-                return _maxTextLength;
-            }
-            set
-            {
-                _maxTextLength = value;
-                _textField.MaxLength = _maxTextLength;
-            }
-        }
-
-        public TextField SpinText
-        {
-            get
-            {
-                return _textField;
-            }
-            set
-            {
-                _textField = value;
-            }
-        }
-
-        // Indicator property of type string:
-        public string IndicatorImage
-        {
-            get
-            {
-                return _arrowImage;
-            }
-            set
-            {
-              _arrowImage = value;
-              _arrowVisual =  VisualFactory.Get().CreateVisual( _arrowImage, new Uint16Pair(150, 150) );
-              RegisterVisual( _arrowVisualPropertyIndex, _arrowVisual );
-            }
-        }
-    }
-
-    class Example
-    {
-        private Dali.Application _application;
-        private FlexContainer _container;
-        private Spin _spinYear;
-        private Spin _spinMonth;
-        private Spin _spinDay;
-
-        [UnmanagedFunctionPointer(CallingConvention.StdCall)]
-        delegate void CallbackDelegate();
-
-        public Example(Dali.Application application)
-        {
-            _application = application;
-            _application.Initialized += Initialize;
-        }
-
-        public void Initialize(object source, NUIApplicationInitEventArgs e)
-        {
-            Stage stage = Stage.GetCurrent();
-            stage.BackgroundColor = Color.White;
-
-            // Create a container for the spins
-            _container = new FlexContainer();
-
-            _container.ParentOrigin = NDalic.ParentOriginCenter;
-            _container.AnchorPoint = NDalic.AnchorPointCenter;
-            _container.FlexDirection = (int)FlexContainer.FlexDirectionType.ROW;
-            _container.Size = new Vector3(480.0f, 150.0f, 0.0f);
-
-            stage.Add(_container);
-
-            // Create a Spin control for year
-            _spinYear = new Spin();
-            _spinYear.ParentOrigin = NDalic.ParentOriginCenter;
-            _spinYear.AnchorPoint = NDalic.AnchorPointCenter;
-            _spinYear.Flex = 0.3f;
-            _spinYear.FlexMargin = new Vector4(5.0f, 0.0f, 5.0f, 0.0f);
-            _container.Add(_spinYear);
-
-            _spinYear.MinValue = 1900;
-            _spinYear.MaxValue = 2100;
-            _spinYear.Value = 2016;
-            _spinYear.Step = 1;
-            _spinYear.MaxTextLength = 4;
-            _spinYear.TextPointSize = 26;
-            _spinYear.TextColor = Color.White;
-            _spinYear.SetKeyboardFocusable(true);
-            _spinYear.Name = "_spinYear";
-
-            // Create a Spin control for month
-            _spinMonth = new Spin();
-            _spinMonth.ParentOrigin = NDalic.ParentOriginCenter;
-            _spinMonth.AnchorPoint = NDalic.AnchorPointCenter;
-            _spinMonth.Flex = 0.3f;
-            _spinMonth.FlexMargin = new Vector4(5.0f, 0.0f, 5.0f, 0.0f);
-            _container.Add(_spinMonth);
-
-            _spinMonth.MinValue = 1;
-            _spinMonth.MaxValue = 12;
-            _spinMonth.Value = 10;
-            _spinMonth.Step = 1;
-            _spinMonth.MaxTextLength = 2;
-            _spinMonth.TextPointSize = 26;
-            _spinMonth.TextColor = Color.White;
-            _spinMonth.SetKeyboardFocusable(true);
-            _spinMonth.Name = "_spinMonth";
-
-            // Create a Spin control for day
-            _spinDay = new Spin();
-            _spinDay.ParentOrigin = NDalic.ParentOriginCenter;
-            _spinDay.AnchorPoint = NDalic.AnchorPointCenter;
-            _spinDay.Flex = 0.3f;
-            _spinDay.FlexMargin = new Vector4(5.0f, 0.0f, 5.0f, 0.0f);
-            _container.Add(_spinDay);
-
-            _spinDay.MinValue = 1;
-            _spinDay.MaxValue = 31;
-            _spinDay.Value = 26;
-            _spinDay.Step = 1;
-            _spinDay.MaxTextLength = 2;
-            _spinDay.TextPointSize = 26;
-            _spinDay.TextColor = Color.White;
-            _spinDay.SetKeyboardFocusable(true);
-            _spinDay.Name = "_spinDay";
-
-            FocusManager keyboardFocusManager = FocusManager.Instance;
-            keyboardFocusManager.PreFocusChange += OnKeyboardPreFocusChange;
-            keyboardFocusManager.FocusedActorEnterKeyPressed += OnFocusedActorEnterKeyPressed;
-
-        }
-
-        private Actor OnKeyboardPreFocusChange(object source, FocusManager.PreFocusChangeEventArgs e)
-        {
-            Actor nextFocusActor = e.Proposed;
-
-            // When nothing has been focused initially, focus the text field in the first spin
-            if (!e.Current && !e.Proposed)
-            {
-                nextFocusActor = _spinYear.SpinText;
-            }
-            else if(e.Direction == View.KeyboardFocus.Direction.LEFT)
-            {
-                // Move the focus to the spin in the left of the current focused spin
-                if(e.Current == _spinMonth.SpinText)
-                {
-                    nextFocusActor = _spinYear.SpinText;
-                }
-                else if(e.Current == _spinDay.SpinText)
-                {
-                    nextFocusActor = _spinMonth.SpinText;
-                }
-            }
-            else if(e.Direction == View.KeyboardFocus.Direction.RIGHT)
-            {
-                // Move the focus to the spin in the right of the current focused spin
-                if(e.Current == _spinYear.SpinText)
-                {
-                    nextFocusActor = _spinMonth.SpinText;
-                }
-                else if(e.Current == _spinMonth.SpinText)
-                {
-                    nextFocusActor = _spinDay.SpinText;
-                }
-            }
-
-            return nextFocusActor;
-        }
-
-        private void OnFocusedActorEnterKeyPressed(object source, FocusManager.FocusedActorEnterKeyEventArgs e)
-        {
-            // Make the text field in the current focused spin to take the key input
-            KeyInputFocusManager manager = KeyInputFocusManager.Get();
-
-            if (e.Actor == _spinYear.SpinText)
-            {
-                if (manager.GetCurrentFocusControl() != _spinYear.SpinText)
-                {
-                    manager.SetFocus(_spinYear.SpinText);
-                }
-            }
-            else if (e.Actor == _spinMonth.SpinText)
-            {
-                if (manager.GetCurrentFocusControl() != _spinMonth.SpinText)
-                {
-                    manager.SetFocus(_spinMonth.SpinText);
-                }
-            }
-            else if (e.Actor == _spinDay.SpinText)
-            {
-                if (manager.GetCurrentFocusControl() != _spinDay.SpinText)
-                {
-                    manager.SetFocus(_spinDay.SpinText);
-                }
-            }
-        }
-
-        public void MainLoop()
-        {
-            _application.MainLoop ();
-        }
-
-        /// <summary>
-        /// The main entry point for the application.
-        /// </summary>
-        [STAThread]
-        static void Main(string[] args)
-        {
-            Example example = new Example(Application.NewApplication());
-            example.MainLoop ();
-        }
-    }
-}
diff --git a/plugins/dali-swig/manual/csharp/PropertyRangeManager.cs b/plugins/dali-swig/manual/csharp/PropertyRangeManager.cs
new file mode 100644 (file)
index 0000000..7e6c4d4
--- /dev/null
@@ -0,0 +1,138 @@
+using System;
+using System.Runtime.InteropServices;
+using System.Collections.Generic;
+
+namespace Dali
+{
+  /// <summary>
+  /// Helper class for calculating what property indexes should be assigned to C# View (view) classes.
+  /// </summary>
+  public class PropertyRangeManager
+  {
+    private Dictionary<String, PropertyRange > _propertyRange;
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="Dali.PropertyRangeManager"/> class.
+    /// </summary>
+    public PropertyRangeManager ()
+    {
+      _propertyRange = new Dictionary<String, PropertyRange > ();
+    }
+
+    /// <summary>
+    /// Only called if a View has scriptable properties
+    /// </summary>
+    private PropertyRange RegisterView( string viewName, System.Type viewType )
+    {
+      PropertyRange range;
+
+      if ( _propertyRange.TryGetValue (viewName, out range) )
+      {
+        // already registered
+        return range;
+      }
+
+      // Find out the event and animatable start indexes for the type
+      range = new PropertyRange();
+
+      GetPropertyStartRange( viewType, ref range);
+
+      // add it to our dictionary
+      _propertyRange.Add( viewName, range );
+
+      return range;
+
+     }
+
+    /// <summary>
+    /// Gets the index of the property.
+    /// Each property has to have unique index for this view type
+    /// </summary>
+    /// <returns>The property index.</returns>
+    /// <param name="viewName">View name</param>
+    /// <param name="viewType">View type</param>
+    /// <param name="type">Type.</param>
+    public int GetPropertyIndex( string viewName, System.Type viewType, ScriptableProperty.ScriptableType type )
+    {
+
+      PropertyRange range;
+
+      if (!  _propertyRange.TryGetValue (viewName, out range) )
+      {
+         // view not found, register it now
+          range = RegisterView( viewName, viewType);
+      }
+
+      int index =  range.GetNextFreePropertyIndex ( type );
+
+      // update the dictionary
+      _propertyRange[viewName]=range;
+
+      return index;
+
+    }
+
+    ///<summary>
+    /// We calculate the start property indices, based on the type and it's class  heirachy, e.g. DateView (70,000)- > Spin (60,000) -> View (50,000)
+    /// </summary>
+    private void GetPropertyStartRange( System.Type viewType, ref PropertyRange range )
+    {
+      const int maxCountPerDerivation = 1000; // For child and animtable properties we use a gap of 1000 between each
+      // views property range in the heirachy
+
+      // custom views start there property index, at view_PROPERTY_END_INDEX
+      // we add 1000, just incase View class (our C# custom view base) starts using scriptable properties
+      int startEventPropertyIndex = (int)View.PropertyRange.CONTROL_PROPERTY_END_INDEX+maxCountPerDerivation;
+
+      // for animatable properties current range starts at ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX,
+      // we add 1000, just incase View class starts using animatable properties
+      int startAnimatablePropertyIndex = (int)Dali.PropertyRanges.ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX +maxCountPerDerivation;
+
+      while ( viewType.BaseType.Name != "CustomView" )   // custom view is our C# view base class. we don't go any deeper.
+      {
+        // for every base class increase property start index
+        startEventPropertyIndex += (int)Dali.PropertyRanges.DEFAULT_PROPERTY_MAX_COUNT_PER_DERIVATION; // DALi uses 10,000
+        startAnimatablePropertyIndex += maxCountPerDerivation;
+
+        //Console.WriteLine ("getStartPropertyIndex =  " + viewType.Name +"current index " + startEventPropertyIndex);
+        viewType = viewType.BaseType;
+      }
+
+      range.startEventIndex = startEventPropertyIndex;
+      range.lastUsedEventIndex = startEventPropertyIndex;
+
+      range.startAnimationIndex = startAnimatablePropertyIndex;
+      range.lastUsedAnimationIndex = startAnimatablePropertyIndex;
+
+    }
+
+
+    public struct PropertyRange
+    {
+
+      public int GetNextFreePropertyIndex( ScriptableProperty.ScriptableType type)
+      {
+        if ( type == ScriptableProperty.ScriptableType.Default )
+        {
+           lastUsedEventIndex++;
+           return lastUsedEventIndex;
+        }
+        else
+        {
+          lastUsedAnimationIndex++;
+          return lastUsedAnimationIndex ;
+        }
+      }
+
+
+      public int startEventIndex;    /// start of the property range
+      public int lastUsedEventIndex;    /// last used of the property index
+
+      public int startAnimationIndex;  /// start of the property range
+      public int lastUsedAnimationIndex; /// last used of the property index
+    };
+
+
+
+}
+}
diff --git a/plugins/dali-swig/manual/csharp/ViewRegistry.cs b/plugins/dali-swig/manual/csharp/ViewRegistry.cs
new file mode 100644 (file)
index 0000000..29ece3a
--- /dev/null
@@ -0,0 +1,507 @@
+using System;
+using System.Runtime.InteropServices;
+using System.Collections.Generic;
+
+namespace Dali
+{
+  /// <summary>
+  /// Add this attribute to any property belonging to a View (control) you want to be scriptable from JSON
+  /// </summary>
+  /// <remarks>
+  /// Example:
+  ///
+  /// class MyView : public CustomView
+  /// {
+  ///  [ScriptableProperty()]
+  ///  public int MyProperty
+  ///  {
+  ///   get
+  ///   {
+  ///     return _myProperty;
+  ///   }
+  ///   set
+  ///   {
+  ///    _myProperty = value;
+  ///   }
+  ///  }
+  /// }
+  ///
+  /// Internally the following occurs for property registration ( this only occurs once per Type, not per Instance):
+  ///
+  /// - The controls static constructor should call ViewRegistry.Register()  (only called once for the lifecycle of the app)
+  /// - Within Register() the code will introspect the Controls properties, looking for the ScriptableProperty() attribute
+  /// - For every property with the ScriptableProperty() attribute, TypeRegistration.RegisterProperty is called.
+  /// - TypeRegistration.RegisterProperty calls in to DALi C++ Code Dali::CSharpTypeRegistry::RegisterProperty()
+  /// - DALi C++ now knows the existance of the property and will try calling SetProperty, if it finds the property in a JSON file (loaded using builder).
+  ///
+  ///  The DALi C# example
+  ///
+  ///  class MyView : public CustomView
+  ///  {
+  ///
+  ///    [ScriptableProperty()]
+  ///    public double Hours
+  ///    {
+  ///     get { return seconds / 3600; }
+  ///     set { seconds = value * 3600; }
+  ///    }
+  ///  }
+  ///
+  ///  Equivalent code in DALi C++:
+  ///  in MyControl.h
+  ///  class MyControl : public Control
+  ///  {
+  ///      struct Property
+  ///      {
+  ///         enum
+  ///        {
+  ///              HOURS =  Control::CONTROL_PROPERTY_END_INDEX + 1
+  ///        }
+  ///     }
+  ///
+  ///
+  /// in MyControl-impl.cpp
+  ///
+  /// DALI_TYPE_REGISTRATION_BEGIN( Toolkit::MyControl, Toolkit::Control, Create );
+  /// DALI_PROPERTY_REGISTRATION( Toolkit, MyControl, "Hours",  INTEGER, DISABLED                     )
+  /// DALI_TYPE_REGISTRATION_END()
+  /// </remarks>
+  ///
+  ///
+  public class ScriptableProperty : System.Attribute
+  {
+    public enum ScriptableType
+    {
+      Default,    // Read Writable, non-animatable property, event thread only
+    //  Animatable // Animatable property, Currently disabled, UK
+    }
+    public readonly ScriptableType type;
+
+    public ScriptableProperty(ScriptableType type = ScriptableType.Default )
+    {
+      this.type = type;
+    }
+  }
+
+  /// <summary>
+  /// View Registry singleton.
+  /// Used for registering controls and any scriptable properties they have ( see ScriptableProperty )
+  ///
+  /// Internal Design from C# to C++
+  ///
+  /// - Each custom C# view should have it's static constructor called before any JSON file is loaded.
+  /// Static constructors for a class will only run once ( they are run per control type, not per instance).
+  /// Example of running a static constructor:
+  ///      System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor (typeof(Spin).TypeHandle);
+  /// Inside the static constructor the control should register it's type with the ViewRegistry
+  /// e.g.
+  ///
+  ///  static Spin()
+  ///  {
+  ///     ViewRegistry.Instance.RegisterControl("Spin", CreateInstance, typeof(Spin) );
+  ///  }
+  ///
+  ///  The control should also provide a CreateInstance function, which gets passed to the ViewRegistry
+  ///  // Eventually it will be called if DALi Builderfinds a Spin control in a JSON file
+  ///  static CustomView CreateInstance()
+  ///  {
+  ///    return new Spin();
+  ///  }
+  ///
+  ///
+  ///
+  /// The DALi C++ equivalent of this is
+  ///
+  ///  TypeRegistration mType( typeid(Toolkit::Spin), typeid(Toolkit::Control), CreateInstance );
+  ///
+  ///
+  ///
+  /// </summary>
+  public sealed class ViewRegistry
+  {
+    /// <summary>
+    /// ViewRegistry is a singleton
+    /// </summary>
+    private static ViewRegistry instance = null;
+
+    [UnmanagedFunctionPointer(CallingConvention.StdCall)]
+    delegate IntPtr CreateControlDelegate( IntPtr cPtrControlName );
+
+    [UnmanagedFunctionPointer(CallingConvention.StdCall)]
+    delegate IntPtr GetPropertyDelegate( IntPtr controlPtr, IntPtr propertyName );
+
+    [UnmanagedFunctionPointer(CallingConvention.StdCall)]
+    delegate void SetPropertyDelegate( IntPtr controlPtr, IntPtr propertyName, IntPtr propertyValue );
+
+    private CreateControlDelegate _createCallback;
+    private SetPropertyDelegate _setPropertyCallback;
+    private GetPropertyDelegate _getPropertyCallback;
+    private PropertyRangeManager _propertyRangeManager;
+
+    /// <summary>
+    /// Given a C++ custom control the dictionary allows us to find what CustomView it belongs to
+    /// </summary>
+    private Dictionary<IntPtr, Dali.CustomView> _controlMap;
+
+    ///<summary>
+    // Maps the name of a custom view to a create instance function
+    /// E.g. given a string "Spin", we can get a function used to create the Spin View.
+    ///</summary>
+    private Dictionary<String, Func< CustomView > > _constructorMap;
+
+    /// <summary>
+    /// Lookup table to match C# types to DALi types, used for the automatic property registration
+    /// </summary>
+    private static readonly Dictionary<string, Dali.Property.Type> _daliPropertyTypeLookup
+    = new Dictionary< string, Dali.Property.Type  >
+    {
+      { "float",   Property.Type.FLOAT },
+      { "int",     Property.Type.INTEGER },
+      { "Int32",   Property.Type.INTEGER },
+      { "Boolean", Property.Type.BOOLEAN },
+      { "string",  Property.Type.STRING },
+      { "Vector2", Property.Type.VECTOR2 },
+      { "Vector3", Property.Type.VECTOR3 },
+      { "Vector4", Property.Type.VECTOR4 },
+      { "Size",    Property.Type.VECTOR2 },
+      { "Position",Property.Type.VECTOR3 },
+      { "Color",   Property.Type.VECTOR4 },
+    //  { "Matrix3", Property.Type.MATRIX3 }, commented out until we need to use Matrices from JSON
+    //  { "Matrix",  Property.Type.MATRIX },
+    };
+
+
+    public ViewRegistry()
+    {
+      _createCallback = new CreateControlDelegate( CreateControl );
+      _getPropertyCallback = new GetPropertyDelegate (GetProperty);
+      _setPropertyCallback  = new SetPropertyDelegate (SetProperty);
+
+      _controlMap = new Dictionary<IntPtr, CustomView>();
+      _constructorMap = new Dictionary<string, Func<CustomView>>();
+      _propertyRangeManager = new PropertyRangeManager();
+
+    }
+
+    private Dali.Property.Type GetDaliPropertyType( string cSharpTypeName )
+    {
+      Dali.Property.Type daliType;
+      if ( _daliPropertyTypeLookup.TryGetValue (cSharpTypeName, out daliType) )
+      {
+        //Console.WriteLine("mapped "+ cSharpTypeName + " to dAli type " +daliType );
+        return daliType;
+      }
+      else
+      {
+       // Console.WriteLine("Failed to find a mapping between C# property" + cSharpTypeName +" and DALi type");
+        return Property.Type.NONE;
+      }
+    }
+
+    /// <summary>
+    /// Called directly from DALi C++ type registry to create a control (View)  uses no marshalling.
+    /// </summary>
+    /// <returns>Pointer to the Control (Views) handle </returns>
+    /// <param name="cPtrControlName"> C pointer to the Control (View) name</param>
+    private static IntPtr CreateControl( IntPtr cPtrControlName )
+    {
+      string controlName = System.Runtime.InteropServices.Marshal.PtrToStringAnsi (cPtrControlName);
+      // Console.WriteLine ("Create controlled called from C++ create a " + controlName);
+
+      Func< CustomView > controlConstructor;
+
+      // find the control constructor
+      if ( Instance._constructorMap.TryGetValue (controlName, out controlConstructor) )
+      {
+        // Create the control
+        CustomView newControl = controlConstructor ();
+
+        // Store the mapping between this instance of the custom control and native part
+        // We store a pointer to the RefObject for the control
+        IntPtr cPtr = newControl.GetPtrfromActor();
+        RefObject refObj = newControl.GetObjectPtr ();
+        IntPtr refCptr = (IntPtr) RefObject.getCPtr(refObj);
+
+        //Console.WriteLine ("________Storing ref object cptr in control map Hex: {0:X}", refCptr);
+        Instance._controlMap.Add (refCptr , newControl );
+
+        return cPtr;  // return pointer to handle
+      }
+      else
+      {
+        throw new global::System.InvalidOperationException("C# View not registererd with ViewRegistry"+ controlName );
+        return IntPtr.Zero;
+      }
+    }
+
+    private static IntPtr GetProperty( IntPtr controlPtr, IntPtr propertyName )
+    {
+      string name = System.Runtime.InteropServices.Marshal.PtrToStringAnsi (propertyName);
+      return Instance.GetPropertyValue ( controlPtr, name);
+    }
+
+    private static void SetProperty(  IntPtr controlPtr, IntPtr propertyName, IntPtr propertyValue )
+    {
+      string name = System.Runtime.InteropServices.Marshal.PtrToStringAnsi (propertyName);
+      //Console.WriteLine ( SetControlProperty  called for:" + name );
+      Instance.SetPropertyValue ( controlPtr, name, propertyValue);
+
+    }
+
+    public static ViewRegistry Instance
+    {
+      get
+      {
+        if (instance==null)
+        {
+          instance = new ViewRegistry();
+        }
+        return instance;
+      }
+    }
+
+    public static CustomView GetCustomViewFromActor( Actor actor )
+    {
+      // we store a dictionary of ref-obects (C++ land) to custom views (C# land)
+      Dali.CustomView view;
+
+      RefObject refObj = actor.GetObjectPtr ();
+      IntPtr refObjectPtr = (IntPtr) RefObject.getCPtr(refObj);
+
+      if ( Instance._controlMap.TryGetValue ( refObjectPtr, out view) )
+      {
+
+        // call the get property function
+
+        return view;
+      }
+      else
+      {
+        return null;
+      }
+    }
+
+
+    /// <summary>
+    /// Function which registers a view and all it's scriptable properties with DALi's type registry.
+    /// Means the View can be created / configured from a JSON script.
+    ///
+    /// The function uses introspection to scan a Views C# properties, then selects the ones with
+    ///[ScriptableProperty] attribute to be registered.
+    /// Example of a Spin view registering itself
+    ///   static Spin()
+    /// {
+    ///   ViewRegistry registers control type with DALi type registery
+    ///   also uses introspection to find any properties that need to be registered with type registry
+    ///   ViewRegistry.Instance.Register("Spin", CreateInstance, typeof(Spin) );
+    /// }
+    ///
+    /// </summary>
+    public void Register(string viewName, Func< CustomView > createFunction, System.Type viewType )
+    {
+      // add the mapping between the view name and it's create function
+      _constructorMap.Add (viewName, createFunction);
+
+      // Call into DALi C++ to register the control with the type registry
+      TypeRegistration.RegisterControl( viewName, _createCallback );
+
+      // Cycle through each property in the class
+      foreach (System.Reflection.PropertyInfo propertyInfo in viewType.GetProperties())
+      {
+
+        if ( propertyInfo.CanRead )
+        {
+
+          System.Attribute[] attrs = System.Attribute.GetCustomAttributes(propertyInfo);
+          foreach (System.Attribute attr in attrs)
+          {
+            // If the Scriptable attribute exists, then register it with the type registry.
+            if (attr is ScriptableProperty)
+            {
+              //Console.WriteLine ("Got a DALi JSON scriptable property = " + propertyInfo.Name +", of type " + propertyInfo.PropertyType.Name);
+
+              // first get the attribute type, ( default, or animatable)
+              ScriptableProperty scriptableProp = attr as ScriptableProperty;
+
+              // we get the start property index, based on the type and it's heirachy, e.g. DateView (70,000)-> Spin (60,000) -> View (50,000)
+              int propertyIndex =  _propertyRangeManager.GetPropertyIndex( viewName, viewType, scriptableProp.type );
+
+              // get the enum for the property type... E.g. registering a string property returns Dali.PropertyType.String
+              Dali.Property.Type propertyType = GetDaliPropertyType( propertyInfo.PropertyType.Name );
+
+              // Example   RegisterProperty("spin","maxValue", 50001, FLOAT, set, get );
+              // Native call to register the property
+              TypeRegistration.RegisterProperty (viewName, propertyInfo.Name , propertyIndex, propertyType, _setPropertyCallback, _getPropertyCallback);
+            }
+          }
+          // Console.WriteLine ("property name = " + propertyInfo.Name);
+        }
+      }
+    }
+
+    /// <summary>
+    /// Get a property value from a View
+    ///
+    /// </summary>
+    private IntPtr GetPropertyValue ( IntPtr controlPtr, string propertyName)
+    {
+      // Get the C# control that maps to the C++ control
+      Dali.CustomView view;
+
+      BaseHandle baseHandle = new BaseHandle (controlPtr, false);
+
+      RefObject refObj = baseHandle.GetObjectPtr ();
+
+      IntPtr refObjectPtr = (IntPtr) RefObject.getCPtr(refObj);
+
+      if ( _controlMap.TryGetValue ( refObjectPtr, out view) )
+      {
+
+        // call the get property function
+        System.Object val = view.GetType ().GetProperty (propertyName).GetAccessors () [0].Invoke (view, null);
+
+        Property.Value value = Property.Value.CreateFromObject (val);
+
+        return (IntPtr)Property.Value.getCPtr (value);
+      }
+      else
+      {
+        return IntPtr.Zero;
+      }
+    }
+
+    /// <summary>
+    /// Set a property value on a View
+    ///
+    /// </summary>
+    private void SetPropertyValue ( IntPtr controlPtr, string propertyName, IntPtr propertyValuePtr)
+    {
+      // Get the C# control that maps to the C++ control
+      Dali.CustomView view;
+
+      //Console.WriteLine ("SetPropertyValue   refObjectPtr = {0:X}", controlPtr);
+
+      Property.Value propValue = new Property.Value (propertyValuePtr, false);
+
+      if ( _controlMap.TryGetValue ( controlPtr, out view) )
+      {
+
+        System.Reflection.PropertyInfo propertyInfo = view.GetType().GetProperty(propertyName);
+
+        // We know the property name, we know it's type, we just need to convert from a DALi property value to native C# type
+        System.Type type = propertyInfo.PropertyType;
+        bool ok = false;
+
+        if ( type.Equals (typeof(Int32)) )
+        {
+          int value = 0;
+          ok = propValue.Get( ref value );
+          if ( ok )
+          {
+            propertyInfo.SetValue (view, value);
+          }
+        }
+        else if ( type.Equals (typeof(bool)) )
+        {
+          bool value = false;
+          ok = propValue.Get( ref value );
+          if ( ok )
+          {
+            propertyInfo.SetValue (view, value);
+          }
+        }
+        else if ( type.Equals (typeof(float)) )
+        {
+          float value = 0;
+          ok = propValue.Get( ref value );
+          if ( ok )
+          {
+            propertyInfo.SetValue (view, value);
+          }
+        }
+        else if ( type.Equals (typeof(string)) )
+        {
+          string value = "";
+          ok = propValue.Get( out value );
+          if ( ok )
+          {
+            propertyInfo.SetValue (view, value);
+          }
+        }
+        else if ( type.Equals (typeof(Vector2)) )
+        {
+          Vector2 value = new Vector2 ();
+          ok = propValue.Get( value );
+          if ( ok )
+          {
+            propertyInfo.SetValue (view, value);
+          }
+        }
+        else if ( type.Equals (typeof(Vector3)) )
+        {
+          Vector3 value = new Vector3 ();
+          ok = propValue.Get( value );
+          if ( ok )
+          {
+            propertyInfo.SetValue (view, value);
+          }
+        }
+        else if ( type.Equals (typeof(Vector4)) )
+        {
+          Vector4 value = new Vector4 ();
+          ok = propValue.Get( value );
+
+          if ( ok )
+          {
+           propertyInfo.SetValue (view, value);
+          }
+        }
+        else if ( type.Equals (typeof(Position)) )
+        {
+          Position value = new Position ();
+          ok = propValue.Get( value );
+          if ( ok )
+          {
+            propertyInfo.SetValue (view, value);
+          }
+        }
+        else if ( type.Equals (typeof(Size)) )
+        {
+          // DALi sizes are Vector3
+          Vector3 value = new Vector3();
+          ok = propValue.Get( value );
+          if ( ok )
+          {
+            propertyInfo.SetValue(view, new Size(value.X,value.Y));
+          };
+        }
+        else if ( type.Equals (typeof(Color)) )
+        {
+          // Colors are stored as Vector4's in DALi
+          Vector4 value = new Vector4();
+          ok = propValue.Get( value );
+          if ( ok )
+          {
+            propertyInfo.SetValue (view, (Color)value);
+          };
+        }
+        else
+        {
+          throw new global::System.InvalidOperationException("SetPropertyValue Unimplemented type for Property Value");
+        }
+        if ( !ok )
+        {
+          throw new global::System.InvalidOperationException("SetPropertyValue propValue.Get failed");
+        }
+      }
+      else
+      {
+        throw new global::System.InvalidOperationException("failed to find the control to write a property to: cptr = " + controlPtr);
+      }
+
+    }
+
+  }
+
+
+}
\ No newline at end of file
diff --git a/plugins/dali-swig/manual/csharp/ViewRegistryHelper.cs b/plugins/dali-swig/manual/csharp/ViewRegistryHelper.cs
new file mode 100644 (file)
index 0000000..8e9e19a
--- /dev/null
@@ -0,0 +1,15 @@
+using System;
+
+// include all custom views here which will be
+namespace Dali
+{
+  public class ViewRegistryHelper
+  {
+    static public void Initialize()
+    {
+       // Register all views with the type registry
+       System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor (typeof(Dali.Spin).TypeHandle);
+    }
+  }
+}
+
index 4abc698..fe2e91c 100755 (executable)
@@ -335,9 +335,9 @@ def writeCSharpData
               hasChildProperties = true
             end
 
-            property.csharpGetter ="  public #{propertyType} #{property.name} \n"\
-                     "  { \n"\
-                     "    get \n" \
+            property.csharpGetter ="  public #{propertyType} #{property.name}\n"\
+                     "  {\n"\
+                     "    get\n" \
                      "    {\n"\
                      "      #{tempDeclaration}\n"\
                      "      GetProperty( #{propertyName}).Get( #{propertyArg} temp );\n"\
@@ -346,8 +346,8 @@ def writeCSharpData
 
             if property.writable
                   #text.SetProperty(TextLabel.Property.HORIZONTAL_ALIGNMENT, new Property.Value("CENTER"));
-                  property.csharpSetter = "    set \n" \
-                         "    { \n"\
+                  property.csharpSetter = "    set\n" \
+                         "    {\n"\
                          "      SetProperty( #{propertyName}, new Dali.Property.Value( value ) );\n" \
                          "    }\n"\
                          "  }\n"
diff --git a/plugins/dali-swig/views/spin.cs b/plugins/dali-swig/views/spin.cs
new file mode 100644 (file)
index 0000000..06a0210
--- /dev/null
@@ -0,0 +1,313 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * 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.
+ *
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using Dali;
+
+// A spin control (for continously changing values when users can easily predict a set of values)
+
+namespace Dali
+{
+public class Spin : CustomView
+  {
+    private VisualBase _arrowVisual;
+    private TextField _textField;
+    private int _arrowVisualPropertyIndex;
+    private string _arrowImage;
+    private int _currentValue;
+    private int _minValue;
+    private int _maxValue;
+    private int _singleStep;
+    private bool _wrappingEnabled;
+    private string _fontFamily;
+    private string _fontStyle;
+    private int _pointSize;
+    private Color _textColor;
+    private Color _textBackgroundColor;
+    private int _maxTextLength;
+
+    // Called by DALi Builder if it finds a Spin control in a JSON file
+    static CustomView CreateInstance()
+    {
+      return new Spin();
+    }
+
+    // static constructor registers the control type (only runs once)
+    static Spin()
+    {
+      // ViewRegistry registers control type with DALi type registery
+      // also uses introspection to find any properties that need to be registered with type registry
+      ViewRegistry.Instance.Register("Spin", CreateInstance, typeof(Spin) );
+    }
+    public Spin() : base(ViewWrapperImpl.CustomViewBehaviour.REQUIRES_KEYBOARD_NAVIGATION_SUPPORT | ViewWrapperImpl.CustomViewBehaviour.DISABLE_STYLE_CHANGE_SIGNALS)
+    {
+
+    }
+
+    public override void OnInitialize()
+    {
+      // Initialize the propertiesControl
+      _arrowImage = "./images/arrow.png";
+      _textBackgroundColor = new Color(0.6f, 0.6f, 0.6f, 1.0f);
+      _currentValue = 0;
+      _minValue = 0;
+      _maxValue = 0;
+      _singleStep = 1;
+      _maxTextLength = 0;
+
+      // Create image visual for the arrow keys
+      _arrowVisualPropertyIndex = RegisterProperty("ArrowImage", new Dali.Property.Value(_arrowImage), Dali.Property.AccessMode.READ_WRITE);
+      _arrowVisual =  VisualFactory.Get().CreateVisual( _arrowImage, new Uint16Pair(150, 150) );
+      RegisterVisual( _arrowVisualPropertyIndex, _arrowVisual );
+
+      // Create a text field
+      _textField = new TextField();
+      _textField.ParentOrigin = NDalic.ParentOriginCenter;
+      _textField.AnchorPoint = NDalic.AnchorPointCenter;
+      _textField.WidthResizePolicy = "SIZE_RELATIVE_TO_PARENT";
+      _textField.HeightResizePolicy = "SIZE_RELATIVE_TO_PARENT";
+      _textField.SizeModeFactor = new Vector3( 1.0f, 0.45f, 1.0f );
+      _textField.PlaceholderText = "----";
+      _textField.BackgroundColor = _textBackgroundColor;
+      _textField.HorizontalAlignment = "Center";
+      _textField.VerticalAlignment = "Center";
+      _textField.SetKeyboardFocusable(true);
+      _textField.Name = "_textField";
+
+      this.Add(_textField);
+
+      _textField.KeyInputFocusGained += TextFieldKeyInputFocusGained;
+      _textField.KeyInputFocusLost += TextFieldKeyInputFocusLost;
+    }
+
+    public override Vector3 GetNaturalSize()
+    {
+      return new Vector3(150.0f, 150.0f, 0.0f);
+    }
+
+    public void TextFieldKeyInputFocusGained(object source, KeyInputFocusGainedEventArgs e)
+    {
+      // Make sure when the current spin that takes input focus also takes the keyboard focus
+      // For example, when you tap the spin directly
+      FocusManager.Instance.SetCurrentFocusActor(_textField);
+    }
+
+    public void TextFieldKeyInputFocusLost(object source, KeyInputFocusLostEventArgs e)
+    {
+      int previousValue = _currentValue;
+
+      // If the input value is invalid, change it back to the previous valid value
+      if(int.TryParse(_textField.Text, out _currentValue))
+      {
+        if (_currentValue < _minValue || _currentValue > _maxValue)
+        {
+          _currentValue = previousValue;
+        }
+      }
+      else
+      {
+        _currentValue = previousValue;
+      }
+
+      // Otherwise take the new value
+      this.Value = _currentValue;
+    }
+
+    public override Actor GetNextKeyboardFocusableActor(Actor currentFocusedActor, View.KeyboardFocus.Direction direction, bool loopEnabled)
+    {
+      // Respond to Up/Down keys to change the value while keeping the current spin focused
+      Actor nextFocusedActor = currentFocusedActor;
+      if (direction == View.KeyboardFocus.Direction.UP)
+      {
+        this.Value += this.Step;
+        nextFocusedActor = _textField;
+      }
+      else if (direction == View.KeyboardFocus.Direction.DOWN)
+      {
+        this.Value -= this.Step;
+        nextFocusedActor = _textField;
+      }
+      else
+      {
+        // Return a native empty handle as nothing can be focused in the left or right
+        nextFocusedActor = new Actor();
+        nextFocusedActor.Reset();
+      }
+
+      return nextFocusedActor;
+    }
+
+
+    [ScriptableProperty()]
+    public int Value
+    {
+      get
+      {
+        return _currentValue;
+      }
+      set
+      {
+
+        Console.WriteLine ("Value set to "  + value );
+        _currentValue = value;
+
+        // Make sure no invalid value is accepted
+        if (_currentValue < _minValue)
+        {
+          _currentValue = _minValue;
+        }
+
+        if (_currentValue > _maxValue)
+        {
+          _currentValue = _maxValue;
+        }
+
+        _textField.Text = _currentValue.ToString();
+      }
+    }
+    // MinValue property of type int:
+    [ScriptableProperty()]
+    public int MinValue
+    {
+      get
+      {
+        return _minValue;
+      }
+      set
+      {
+        _minValue = value;
+      }
+    }
+
+    // MaxValue property of type int:
+    [ScriptableProperty()]
+    public int MaxValue
+    {
+      get
+      {
+        return _maxValue;
+      }
+      set
+      {
+        _maxValue = value;
+      }
+    }
+
+    // Step property of type int:
+    [ScriptableProperty()]
+    public int Step
+    {
+      get
+      {
+        return _singleStep;
+      }
+      set
+      {
+        _singleStep = value;
+      }
+    }
+
+    // WrappingEnabled property of type bool:
+    [ScriptableProperty()]
+    public bool WrappingEnabled
+    {
+      get
+      {
+        return _wrappingEnabled;
+      }
+      set
+      {
+        _wrappingEnabled = value;
+      }
+    }
+
+    // TextPointSize property of type int:
+    [ScriptableProperty()]
+    public int TextPointSize
+    {
+      get
+      {
+        return _pointSize;
+      }
+      set
+      {
+        _pointSize = value;
+        _textField.PointSize = _pointSize;
+      }
+    }
+
+    // TextColor property of type Color:
+    [ScriptableProperty()]
+    public Color TextColor
+    {
+      get
+      {
+        return _textColor;
+      }
+      set
+      {
+          Console.WriteLine ("TextColor set to "  + value.R + "," + value.G + ","+ value.B);
+
+        _textColor = value;
+        _textField.TextColor = _textColor;
+      }
+    }
+
+    // MaxTextLength property of type int:
+    [ScriptableProperty()]
+    public int MaxTextLength
+    {
+      get
+      {
+        return _maxTextLength;
+      }
+      set
+      {
+        _maxTextLength = value;
+        _textField.MaxLength = _maxTextLength;
+      }
+    }
+
+    public TextField SpinText
+    {
+      get
+      {
+        return _textField;
+      }
+      set
+      {
+        _textField = value;
+      }
+    }
+
+    // Indicator property of type string:
+    public string IndicatorImage
+    {
+      get
+      {
+        return _arrowImage;
+      }
+      set
+      {
+        _arrowImage = value;
+        _arrowVisual =  VisualFactory.Get().CreateVisual( _arrowImage, new Uint16Pair(150, 150) );
+        RegisterVisual( _arrowVisualPropertyIndex, _arrowVisual );
+      }
+  }
+}
+}
\ No newline at end of file