Merge "Updated control transitions to work with visual transform" into devel/master
authorAdeel Kazmi <adeel.kazmi@samsung.com>
Thu, 15 Dec 2016 16:01:36 +0000 (08:01 -0800)
committerGerrit Code Review <gerrit@review.vlan103.tizen.org>
Thu, 15 Dec 2016 16:01:45 +0000 (08:01 -0800)
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/dummy-control.cpp
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/dummy-control.h
automated-tests/src/dali-toolkit/utc-Dali-TransitionData.cpp
automated-tests/src/dali-toolkit/utc-Dali-Visual.cpp
dali-toolkit/devel-api/visual-factory/visual-base.cpp
dali-toolkit/internal/visuals/visual-base-data-impl.cpp
dali-toolkit/internal/visuals/visual-base-impl.cpp
dali-toolkit/internal/visuals/visual-base-impl.h
dali-toolkit/public-api/controls/control-impl.cpp

index f44fa71..e8c266d 100644 (file)
@@ -67,6 +67,10 @@ BaseHandle Create()
 
 DALI_TYPE_REGISTRATION_BEGIN( Toolkit::DummyControl, Toolkit::Control, Create );
 DALI_TYPE_REGISTRATION_END()
+
+Dali::PropertyRegistration dummyControlVisualProperty(
+  typeRegistration, "testVisual", Dali::Toolkit::DummyControl::Property::TEST_VISUAL, Dali::Property::MAP, &Dali::Toolkit::DummyControlImpl::SetProperty, &Dali::Toolkit::DummyControlImpl::GetProperty );
+
 }
 
 DummyControl DummyControlImpl::New()
@@ -135,6 +139,18 @@ Animation DummyControlImpl::CreateTransition( const Toolkit::TransitionData& tra
   return Control::CreateTransition( transition );
 }
 
+void DummyControlImpl::SetProperty( BaseObject* object, Dali::Property::Index index, const Dali::Property::Value& value )
+{
+}
+
+Property::Value DummyControlImpl::GetProperty( BaseObject* object, Dali::Property::Index propertyIndex )
+{
+  Dali::Property::Value value;
+  return value;
+}
+
+
+
 DummyControl DummyControlImplOverride::New()
 {
   IntrusivePtr< DummyControlImplOverride > impl = new DummyControlImplOverride;
index 95b4126..a425330 100644 (file)
@@ -28,13 +28,26 @@ namespace Toolkit
 {
 
 class DummyControlImpl;
-class ControlRenderer;
+
 /**
  * Control does not have a New method so use this dummy class for the handle.
  */
 class DummyControl : public Control
 {
 public:
+  enum PropertyRange
+  {
+    PROPERTY_START_INDEX = Control::CONTROL_PROPERTY_END_INDEX + 1, ///< @SINCE_1_0.0
+    PROPERTY_END_INDEX =   PROPERTY_START_INDEX + 1000              ///< Reserve property index
+  };
+
+  struct Property
+  {
+    enum Type
+    {
+      TEST_VISUAL = PROPERTY_START_INDEX
+    };
+  };
 
   DummyControl();
   DummyControl(const DummyControl& control);
@@ -80,6 +93,10 @@ public:
   Toolkit::Visual::Base GetVisual( Property::Index index );
   Animation CreateTransition( const Toolkit::TransitionData& transition );
 
+  static void SetProperty( BaseObject* object, Dali::Property::Index index, const Dali::Property::Value& value );
+
+  static Property::Value GetProperty( BaseObject* object, Dali::Property::Index propertyIndex );
+
   // Used to test signal connections
   void CustomSlot1( Actor actor );
 
index c0f7982..58559d5 100644 (file)
@@ -338,22 +338,21 @@ int UtcDaliTransitionDataMap2P(void)
   END_TEST;
 }
 
-
 int UtcDaliTransitionDataMap3P(void)
 {
   TestApplication application;
 
-  tet_printf("Testing animation of a visual's placement actor property\n");
+  tet_printf("Testing animation of an actor's position property using bezier curve\n");
 
   Property::Map map;
-  map["target"] = "visual1";
-  map["property"] = "color";
-  map["initialValue"] = Color::MAGENTA;
-  map["targetValue"] = Color::RED;
+  map["target"] = "Actor1";
+  map["property"] = "position";
+  map["initialValue"] = Vector3(0, 0, 0);
+  map["targetValue"] = Vector3(100, 100, 0);
   map["animator"] = Property::Map()
-    .Add("alphaFunction", "EASE_IN_OUT")
+    .Add("alphaFunction", Vector4(0.71, -0.57, 0.42, 1.38) )
     .Add("timePeriod", Property::Map()
-         .Add("delay", 0.5f)
+         .Add("delay", 0.0f)
          .Add("duration", 1.0f));
 
   Dali::Toolkit::TransitionData transition = TransitionData::New( map );
@@ -361,39 +360,36 @@ int UtcDaliTransitionDataMap3P(void)
   DummyControl actor = DummyControl::New();
   actor.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS);
   actor.SetName("Actor1");
-  actor.SetColor(Color::CYAN);
   Stage::GetCurrent().Add(actor);
 
   DummyControlImpl& dummyImpl = static_cast<DummyControlImpl&>(actor.GetImplementation());
-
-  Property::Map visualMap;
-  visualMap[Visual::Property::TYPE] = Visual::COLOR;
-  visualMap[ColorVisual::Property::MIX_COLOR] = Color::MAGENTA;
-  Visual::Base visual = VisualFactory::Get().CreateVisual( visualMap );
-  visual.SetName( "visual1" );
-
-  Property::Index visualIndex = Control::CONTROL_PROPERTY_END_INDEX + 1;
-  dummyImpl.RegisterVisual( visualIndex, visual );
-
   Animation anim = dummyImpl.CreateTransition( transition );
   DALI_TEST_CHECK( anim );
 
   application.SendNotification();
   application.Render(0);
-  DALI_TEST_EQUALS( actor.GetCurrentColor(), Color::MAGENTA, TEST_LOCATION);
+  DALI_TEST_EQUALS( actor.GetCurrentPosition(), Vector3(0,0,0), 0.001f, TEST_LOCATION);
 
   anim.Play();
 
   application.SendNotification();
   application.Render(0);
-  application.Render(500);
-  application.Render(500); // Halfway thru map1 anim
+
+  application.Render(250); // 25%
   application.SendNotification();
-  DALI_TEST_EQUALS( actor.GetCurrentColor(), (Color::MAGENTA+Color::RED)*0.5f, TEST_LOCATION);
+  DALI_TEST_EQUALS( actor.GetCurrentPosition(), Vector3(-10,-10,0), 1.0, TEST_LOCATION); // High epsilon as we don't have exact figure for bezier curve at 50%
 
-  application.Render(500); // End of map1 anim
+  application.Render(250); // Halfway thru map1 anim
   application.SendNotification();
-  DALI_TEST_EQUALS( actor.GetCurrentColor(), Color::RED, TEST_LOCATION );
+  DALI_TEST_EQUALS( actor.GetCurrentPosition(), Vector3(24,24,0), 1.0, TEST_LOCATION); // High epsilon as we don't have exact figure for bezier curve at 50%
+
+  application.Render(250); // End of map1 anim
+  application.SendNotification();
+  DALI_TEST_EQUALS( actor.GetCurrentPosition(), Vector3(100,100,0), 1.0, TEST_LOCATION); // High epsilon as we don't have exact figure for bezier curve
+
+  application.Render(250); // End of map1 anim
+  application.SendNotification();
+  DALI_TEST_EQUALS( actor.GetCurrentPosition(), Vector3(100,100,0), TEST_LOCATION );
   END_TEST;
 }
 
@@ -402,20 +398,31 @@ int UtcDaliTransitionDataMap4P(void)
 {
   TestApplication application;
 
-  tet_printf("Testing animation of a visual's placement actor property using bezier curve\n");
+  tet_printf("Testing animation of a visual's transform property using programmatic maps\n");
 
-  Property::Map map;
-  map["target"] = "Actor1";
-  map["property"] = "position";
-  map["initialValue"] = Vector3(0, 0, 0);
-  map["targetValue"] = Vector3(100, 100, 0);
-  map["animator"] = Property::Map()
-    .Add("alphaFunction", Vector4(0.71, -0.57, 0.42, 1.38) )
+  Property::Map map1;
+  map1["target"] = "testVisual";
+  map1["property"] = "offset";
+  map1["initialValue"] = Vector2(0.0f, 0.0f);
+  map1["targetValue"] = Vector2(100.0f, 100.0f);
+  map1["animator"] = Property::Map()
+    .Add("alphaFunction", "LINEAR")
     .Add("timePeriod", Property::Map()
-         .Add("delay", 0.0f)
+         .Add("delay", 0.5f)
          .Add("duration", 1.0f));
 
-  Dali::Toolkit::TransitionData transition = TransitionData::New( map );
+  Property::Map map2;
+  map2["target"] = "testVisual";
+  map2["property"] = "size";
+  map2["initialValue"] = Vector2(10.0f, 10.0f);
+  map2["targetValue"] = Vector2(110.0f, 110.0f);
+  map2["animator"] = Property::Map()
+    .Add("alphaFunction", "LINEAR")
+    .Add("timePeriod", Property::Map()
+         .Add("delay", 0.5f)
+         .Add("duration", 1.0f));
+
+  Dali::Toolkit::TransitionData transition = TransitionData::New( Property::Array().Add(map1).Add(map2) );
 
   DummyControl actor = DummyControl::New();
   actor.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS);
@@ -423,36 +430,42 @@ int UtcDaliTransitionDataMap4P(void)
   Stage::GetCurrent().Add(actor);
 
   DummyControlImpl& dummyImpl = static_cast<DummyControlImpl&>(actor.GetImplementation());
+
+  Property::Map visualMap;
+  visualMap[Visual::Property::TYPE] = Visual::COLOR;
+  visualMap[ColorVisual::Property::MIX_COLOR] = Color::MAGENTA;
+  Visual::Base visual = VisualFactory::Get().CreateVisual( visualMap );
+
+  visual.SetName( "testVisual" );
+  dummyImpl.RegisterVisual( DummyControl::Property::TEST_VISUAL, visual );
+
   Animation anim = dummyImpl.CreateTransition( transition );
   DALI_TEST_CHECK( anim );
 
+  Renderer renderer = actor.GetRendererAt(0);
+  Property::Index sizeIndex = renderer.GetPropertyIndex( "size" );
   application.SendNotification();
   application.Render(0);
-  DALI_TEST_EQUALS( actor.GetCurrentPosition(), Vector3(0,0,0), 0.001f, TEST_LOCATION);
+
+  DALI_TEST_EQUALS( renderer.GetProperty<Vector2>(sizeIndex), Vector2(10.0f, 10.0f), TEST_LOCATION);
 
   anim.Play();
 
   application.SendNotification();
   application.Render(0);
-
-  application.Render(250); // 25%
-  application.SendNotification();
-  DALI_TEST_EQUALS( actor.GetCurrentPosition(), Vector3(-10,-10,0), 1.0, TEST_LOCATION); // High epsilon as we don't have exact figure for bezier curve at 50%
-
-  application.Render(250); // Halfway thru map1 anim
+  application.Render(500); // Start animation
+  application.Render(500); // Halfway thru anim
   application.SendNotification();
-  DALI_TEST_EQUALS( actor.GetCurrentPosition(), Vector3(24,24,0), 1.0, TEST_LOCATION); // High epsilon as we don't have exact figure for bezier curve at 50%
+  DALI_TEST_EQUALS( renderer.GetProperty<Vector2>(sizeIndex), Vector2(60.0f, 60.0f), TEST_LOCATION);
 
-  application.Render(250); // End of map1 anim
+  application.Render(500); // End of anim
   application.SendNotification();
-  DALI_TEST_EQUALS( actor.GetCurrentPosition(), Vector3(100,100,0), 1.0, TEST_LOCATION); // High epsilon as we don't have exact figure for bezier curve
+  DALI_TEST_EQUALS( renderer.GetProperty<Vector2>(sizeIndex), Vector2(110.0f, 110.0f), TEST_LOCATION );
 
-  application.Render(250); // End of map1 anim
-  application.SendNotification();
-  DALI_TEST_EQUALS( actor.GetCurrentPosition(), Vector3(100,100,0), TEST_LOCATION );
   END_TEST;
 }
 
+
 int UtcDaliTransitionDataMap1N(void)
 {
   TestApplication application;
index 563c593..fae713a 100644 (file)
@@ -1532,6 +1532,15 @@ int UtcDaliNPatchVisualCustomShader(void)
   Property::Map shader;
   const std::string fragmentShader = "Foobar";
   shader[Dali::Toolkit::Visual::Shader::Property::FRAGMENT_SHADER] = fragmentShader;
+
+  Property::Map transformMap;
+  transformMap["size"] = Vector2( 0.5f, 0.5f ) ;
+  transformMap["offset"] = Vector2( 20.0f, 0.0f ) ;
+  transformMap["offsetSizeMode"] = Vector4( 1.0f, 1.0f, 0.0f, 0.0f );
+  transformMap["anchorPoint"] = Align::CENTER;
+  transformMap["origin"] = Align::CENTER;
+  properties[DevelVisual::Property::TRANSFORM] = transformMap;
+
   properties[Dali::Toolkit::Visual::Property::TYPE] = Dali::Toolkit::Visual::IMAGE;
   properties[Dali::Toolkit::Visual::Property::SHADER]=shader;
   properties[Dali::Toolkit::ImageVisual::Property::URL] = TEST_NPATCH_FILE_NAME;
@@ -1545,6 +1554,7 @@ int UtcDaliNPatchVisualCustomShader(void)
   dummy.SetSize(2000, 2000);
   dummy.SetParentOrigin(ParentOrigin::CENTER);
   Stage::GetCurrent().Add(dummy);
+  application.SendNotification();
 
   Renderer renderer = dummy.GetRendererAt( 0 );
   Shader shader2 = renderer.GetShader();
@@ -1552,6 +1562,9 @@ int UtcDaliNPatchVisualCustomShader(void)
   Property::Map* map = value.GetMap();
   DALI_TEST_CHECK( map );
 
+  Property::Index index = renderer.GetPropertyIndex("size");
+  DALI_TEST_EQUALS( renderer.GetProperty( index ), Property::Value(Vector2(0.5, 0.5)), 0.001, TEST_LOCATION );
+
   Property::Value* fragment = map->Find( "fragment" ); // fragment key name from shader-impl.cpp
   // *map["vertex"]; is default here so not verifying it
 
@@ -1677,6 +1690,7 @@ int UtcDaliVisualTextVisualRender(void)
   DALI_TEST_EQUALS( dummyControl.GetRendererCount(), 0, TEST_LOCATION );
 
   dummyControl.SetSize(200.f, 200.f);
+  dummyControl.SetParentOrigin( ParentOrigin::CENTER );
 
   Stage::GetCurrent().Add( dummyControl );
   application.SendNotification();
@@ -1691,7 +1705,7 @@ int UtcDaliVisualTextVisualRender(void)
   propertyMap.Insert( TextVisual::Property::MULTI_LINE, true );
 
   Property::Map transformMap;
-  transformMap.Insert( DevelVisual::Transform::Property::SIZE, Vector2( 720.f, 640.f ) );
+  transformMap.Insert( "size", Vector2( 0.5f, 0.5f ) );
   propertyMap.Insert( DevelVisual::Property::TRANSFORM, transformMap );
 
   textVisual = factory.CreateVisual( propertyMap );
@@ -1700,9 +1714,16 @@ int UtcDaliVisualTextVisualRender(void)
   dummyImpl.RegisterVisual( Control::CONTROL_PROPERTY_END_INDEX + 1, textVisual );
   dummyControl.SetSize( 720.f, 640.f );
 
-  application.SendNotification();
+  application.SendNotification(); // force process events to ensure text visual
+  // adds renderer to the dummy control in OnRelayout
   application.Render();
 
+  Renderer renderer = dummyControl.GetRendererAt(0u);
+  Property::Index index = renderer.GetPropertyIndex("size");
+
+  tet_infoline( "Test that the TextVisual overrides anything set by developer" );
+  DALI_TEST_EQUALS( renderer.GetProperty<Vector2>(index), Vector2( 1.0, 1.0 ), 0.001f, TEST_LOCATION );
+
   END_TEST;
 }
 
index eea2b44..6a19c9b 100644 (file)
@@ -96,6 +96,9 @@ void Visual::Base::CreatePropertyMap( Property::Map& map ) const
   GetImplementation( *this ).CreatePropertyMap( map );
 }
 
+
+
+
 } // namespace Toolkit
 
 } // namespace Dali
index 489dfb6..f8d3e5f 100644 (file)
@@ -208,7 +208,7 @@ Internal::Visual::Base::Impl::Transform::Transform()
 
 void Internal::Visual::Base::Impl::Transform::SetPropertyMap( const Property::Map& map )
 {
-  //Set default values
+  // Set default values
   mOffset = Vector2( 0.0f,0.0f );
   mSize = Vector2( 1.0f,1.0f );
   mOffsetSizeMode = Vector4( 0.0f,0.0f,0.0f,0.0f );
@@ -218,33 +218,67 @@ void Internal::Visual::Base::Impl::Transform::SetPropertyMap( const Property::Ma
   for( Property::Map::SizeType i(0); i<map.Count(); ++i )
   {
     KeyValuePair keyValue = map.GetKeyValue( i );
-    if( keyValue.first == Toolkit::DevelVisual::Transform::Property::OFFSET )
+    if( keyValue.first.type == Property::Key::INDEX )
     {
-      keyValue.second.Get( mOffset );
-    }
-    else if( keyValue.first == Toolkit::DevelVisual::Transform::Property::SIZE )
-    {
-      keyValue.second.Get( mSize );
-    }
-    else if( keyValue.first == Toolkit::DevelVisual::Transform::Property::ORIGIN )
-    {
-      Toolkit::Align::Type align(Toolkit::Align::CENTER);
-      if( Scripting::GetEnumerationProperty< Toolkit::Align::Type >( keyValue.second, ALIGN_TABLE, ALIGN_TABLE_COUNT, align ) )
+      switch( keyValue.first.indexKey )
       {
-        mOrigin = align;
+        case Toolkit::DevelVisual::Transform::Property::OFFSET:
+        {
+          keyValue.second.Get( mOffset );
+          break;
+        }
+        case Toolkit::DevelVisual::Transform::Property::SIZE:
+        {
+          keyValue.second.Get( mSize );
+          break;
+        }
+        case Toolkit::DevelVisual::Transform::Property::ORIGIN:
+        {
+          Scripting::GetEnumerationProperty< Toolkit::Align::Type >( keyValue.second, ALIGN_TABLE, ALIGN_TABLE_COUNT, mOrigin );
+          break;
+        }
+        case Toolkit::DevelVisual::Transform::Property::ANCHOR_POINT:
+        {
+          Scripting::GetEnumerationProperty< Toolkit::Align::Type >( keyValue.second, ALIGN_TABLE, ALIGN_TABLE_COUNT, mAnchorPoint );
+          break;
+        }
+        case Toolkit::DevelVisual::Transform::Property::OFFSET_SIZE_MODE:
+        {
+          keyValue.second.Get( mOffsetSizeMode );
+          break;
+        }
       }
     }
-    else if( keyValue.first == Toolkit::DevelVisual::Transform::Property::ANCHOR_POINT )
+    else  // Key type is STRING
     {
-      Toolkit::Align::Type align(Toolkit::Align::CENTER);
-      if( Scripting::GetEnumerationProperty< Toolkit::Align::Type >( keyValue.second, ALIGN_TABLE, ALIGN_TABLE_COUNT, align ) )
+      if( keyValue.first == "offset" )
       {
-        mAnchorPoint = align;
+        keyValue.second.Get( mOffset );
+      }
+      else if( keyValue.first == "size" )
+      {
+        keyValue.second.Get( mSize );
+      }
+      else if( keyValue.first == "origin" )
+      {
+        Toolkit::Align::Type align(Toolkit::Align::CENTER);
+        if( Scripting::GetEnumerationProperty< Toolkit::Align::Type >( keyValue.second, ALIGN_TABLE, ALIGN_TABLE_COUNT, align ) )
+        {
+          mOrigin = align;
+        }
+      }
+      else if( keyValue.first == "anchorPoint" )
+      {
+        Toolkit::Align::Type align(Toolkit::Align::CENTER);
+        if( Scripting::GetEnumerationProperty< Toolkit::Align::Type >( keyValue.second, ALIGN_TABLE, ALIGN_TABLE_COUNT, align ) )
+        {
+          mAnchorPoint = align;
+        }
+      }
+      else if( keyValue.first == "offsetSizeMode" )
+      {
+        keyValue.second.Get( mOffsetSizeMode );
       }
-    }
-    else if( keyValue.first == Toolkit::DevelVisual::Transform::Property::OFFSET_SIZE_MODE )
-    {
-      keyValue.second.Get( mOffsetSizeMode );
     }
   }
 }
index 0958afa..5815c4a 100644 (file)
 #include <dali-toolkit/internal/visuals/visual-base-data-impl.h>
 #include <dali-toolkit/internal/visuals/visual-string-constants.h>
 
+namespace
+{
+#if defined(DEBUG_ENABLED)
+Debug::Filter* gVisualBaseLogFilter = Debug::Filter::New( Debug::NoLogging, false, "LOG_VISUAL_BASE" );
+#endif
+}
+
 namespace Dali
 {
 
@@ -107,6 +114,14 @@ void Visual::Base::SetTransformAndSize( const Property::Map& transform, Size con
 {
   mImpl->mControlSize = controlSize;
   mImpl->mTransform.SetPropertyMap( transform );
+
+#if defined(DEBUG_ENABLED)
+  std::ostringstream oss;
+  oss << transform;
+  DALI_LOG_INFO( gVisualBaseLogFilter, Debug::General, "Visual::Base::SetTransformAndSize(%s) - [\e[1;32mtransform: %s  controlSize: (%3.1f, %3.1f)]\e[0m\n",
+                 GetName().c_str(), oss.str().c_str(), controlSize.x, controlSize.y );
+#endif
+
   OnSetTransform();
 }
 
@@ -245,6 +260,11 @@ bool Visual::Base::IsFromCache() const
   return mImpl->mFlags & Impl::IS_FROM_CACHE;
 }
 
+Renderer Visual::Base::GetRenderer()
+{
+  return mImpl->mRenderer;
+}
+
 } // namespace Internal
 
 } // namespace Toolkit
index 1a84b2d..f496467 100644 (file)
@@ -22,6 +22,7 @@
 #include <dali/public-api/common/intrusive-ptr.h>
 #include <dali/public-api/images/image-operations.h>
 #include <dali/public-api/object/base-object.h>
+#include <dali/public-api/rendering/renderer.h>
 #include <dali/public-api/rendering/shader.h>
 
 // INTERNAL INCLUDES
@@ -157,6 +158,11 @@ public:
    */
   Dali::Property::Value GetProperty( Dali::Property::Index index );
 
+  /**
+   * Gets currently staged renderer, or an empty handle if not staged
+   */
+  Renderer GetRenderer();
+
 protected:
 
   /**
index ab171ad..9fa9291 100644 (file)
@@ -22,6 +22,7 @@
 #include <cstring> // for strcmp
 #include <limits>
 #include <stack>
+#include <typeinfo>
 #include <dali/public-api/animation/constraint.h>
 #include <dali/public-api/animation/constraints.h>
 #include <dali/public-api/object/type-registry.h>
@@ -57,7 +58,7 @@ namespace
 {
 
 #if defined(DEBUG_ENABLED)
-Debug::Filter* gLogFilter = Debug::Filter::New( Debug::General, false, "LOG_CONTROL_VISUALS");
+Debug::Filter* gLogFilter = Debug::Filter::New( Debug::NoLogging, false, "LOG_CONTROL_VISUALS");
 #endif
 
 /**
@@ -117,7 +118,7 @@ HandleIndex GetVisualProperty(
 {
 #if defined(DEBUG_ENABLED)
   std::ostringstream oss;
-  oss << "Control::GetHandleIndex(" << visualName << ", " << propertyKey << ")" << std::endl;
+  oss << "Control::GetVisualProperty(" << visualName << ", " << propertyKey << ")" << std::endl;
   DALI_LOG_INFO( gLogFilter, Debug::General, oss.str().c_str() );
 #endif
 
@@ -125,44 +126,25 @@ HandleIndex GetVisualProperty(
   RegisteredVisualContainer::Iterator iter;
   for ( iter = visuals.Begin(); iter != visuals.End(); iter++ )
   {
-    if ( (*iter)->visual.GetName() == visualName )
+    Toolkit::Visual::Base visual = (*iter)->visual;
+    if( visual && visual.GetName() == visualName )
     {
-      break;
-    }
-  }
-
-  // Does it's renderer have an associated property?
-  if( iter != visuals.End() )
-  {
-    Actor self = controlImpl.Self();
-    Property::Index index = DevelHandle::GetPropertyIndex( self, propertyKey );
-    if( index != Property::INVALID_INDEX )
-    {
-      // It's an actor property:
-      return HandleIndex( self, index );
-    }
-    else
-    {
-      // Check if it is a renderer property:
-      if( self.GetRendererCount() > 0 )
+      Internal::Visual::Base& visualImpl = GetImplementation(visual);
+      Renderer renderer = visualImpl.GetRenderer();
+      if( renderer )
       {
-        // @todo Need to use correct renderer index
-        Renderer renderer = self.GetRendererAt(0);
         Property::Index index = DevelHandle::GetPropertyIndex( renderer, propertyKey );
         if( index != Property::INVALID_INDEX )
         {
-          // It's a renderer property:
           return HandleIndex( renderer, index );
         }
       }
-      else
-      {
-        std::ostringstream oss;
-        oss << propertyKey;
-        DALI_LOG_WARNING( "Control::GetHandleIndex(%s, %s) No renderers\n", visualName.c_str(), oss.str().c_str() );
-      }
     }
   }
+
+  std::ostringstream noRenderers;
+  noRenderers << propertyKey;
+  DALI_LOG_WARNING( "Control::GetVisualProperty(%s, %s) No renderers\n", visualName.c_str(), noRenderers.str().c_str() );
   Handle handle;
   return HandleIndex( handle, Property::INVALID_INDEX );
 }
@@ -785,6 +767,27 @@ void Control::RegisterVisual( Property::Index index, Toolkit::Visual::Base& visu
     }
   }
 
+  // If not set, set the name of the visual to the same name as the control's property.
+  // ( If the control has been type registered )
+  if( visual.GetName().empty() )
+  {
+    // Check if the control has been type registered:
+    TypeInfo typeInfo = TypeRegistry::Get().GetTypeInfo( typeid(*this) );
+    if( typeInfo )
+    {
+      // Check if the property index has been registered:
+      Property::IndexContainer indices;
+      typeInfo.GetPropertyIndices( indices );
+      Property::IndexContainer::Iterator iter = std::find( indices.Begin(), indices.End(), index );
+      if( iter != indices.End() )
+      {
+        // If it has, then get it's name and use that for the visual
+        std::string visualName = typeInfo.GetPropertyName( index );
+        visual.SetName( visualName );
+      }
+    }
+  }
+
   if( !visualReplaced ) // New registration entry
   {
     mImpl->mVisuals.PushBack( new RegisteredVisual( index, visual, enabled ) );