Ensure not to emit the resource ready signal during the callback
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / controls / control / control-data-impl.cpp
old mode 100644 (file)
new mode 100755 (executable)
index 4f26d11..368ab0a
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 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.
 #include "control-data-impl.h"
 
 // EXTERNAL INCLUDES
-#include <dali/public-api/common/dali-common.h>
+#include <dali-toolkit/public-api/dali-toolkit-common.h>
 #include <dali/integration-api/debug.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>
 #include <dali/public-api/object/type-registry-helper.h>
+#include <dali/integration-api/adaptor-framework/adaptor.h>
 #include <cstring>
 #include <limits>
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/internal/visuals/visual-base-impl.h>
-#include <dali-toolkit/devel-api/controls/control-depth-index-ranges.h>
-#include <dali-toolkit/internal/styling/style-manager-impl.h>
 #include <dali-toolkit/public-api/visuals/image-visual-properties.h>
 #include <dali-toolkit/public-api/visuals/visual-properties.h>
-#include <dali-toolkit/internal/visuals/visual-string-constants.h>
+#include <dali-toolkit/devel-api/controls/control-depth-index-ranges.h>
 #include <dali-toolkit/devel-api/controls/control-devel.h>
 #include <dali-toolkit/devel-api/controls/control-wrapper-impl.h>
+#include <dali-toolkit/internal/styling/style-manager-impl.h>
+#include <dali-toolkit/internal/visuals/visual-string-constants.h>
 
 namespace Dali
 {
@@ -229,22 +230,22 @@ static bool DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tra
     }
     else if( 0 == strcmp( signalName.c_str(), SIGNAL_TAPPED ) )
     {
-      controlImpl.EnableGestureDetection( Gesture::Tap );
+      controlImpl.EnableGestureDetection( GestureType::TAP );
       controlImpl.GetTapGestureDetector().DetectedSignal().Connect( tracker, functor );
     }
     else if( 0 == strcmp( signalName.c_str(), SIGNAL_PANNED ) )
     {
-      controlImpl.EnableGestureDetection( Gesture::Pan );
+      controlImpl.EnableGestureDetection( GestureType::PAN );
       controlImpl.GetPanGestureDetector().DetectedSignal().Connect( tracker, functor );
     }
     else if( 0 == strcmp( signalName.c_str(), SIGNAL_PINCHED ) )
     {
-      controlImpl.EnableGestureDetection( Gesture::Pinch );
+      controlImpl.EnableGestureDetection( GestureType::PINCH );
       controlImpl.GetPinchGestureDetector().DetectedSignal().Connect( tracker, functor );
     }
     else if( 0 == strcmp( signalName.c_str(), SIGNAL_LONG_PRESSED ) )
     {
-      controlImpl.EnableGestureDetection( Gesture::LongPress );
+      controlImpl.EnableGestureDetection( GestureType::LONG_PRESS );
       controlImpl.GetLongPressGestureDetector().DetectedSignal().Connect( tracker, functor );
     }
   }
@@ -276,19 +277,19 @@ TypeAction registerAction( typeRegistration, ACTION_ACCESSIBILITY_ACTIVATED, &Do
 DALI_TYPE_REGISTRATION_END()
 
 /**
- * @brief Iterate through given container and setOffStage any visual found
+ * @brief Iterate through given container and setOffScene any visual found
  *
  * @param[in] container Container of visuals
  * @param[in] parent Parent actor to remove visuals from
  */
-void SetVisualsOffStage( const RegisteredVisualContainer& container, Actor parent )
+void SetVisualsOffScene( const RegisteredVisualContainer& container, Actor parent )
 {
   for( auto iter = container.Begin(), end = container.End() ; iter!= end; iter++)
   {
     if( (*iter)->visual )
     {
-      DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Control::SetOffStage Setting visual(%d) off stage\n", (*iter)->index );
-      Toolkit::GetImplementation((*iter)->visual).SetOffStage( parent );
+      DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Control::SetOffScene Setting visual(%d) off stage\n", (*iter)->index );
+      Toolkit::GetImplementation((*iter)->visual).SetOffScene( parent );
     }
   }
 }
@@ -298,8 +299,6 @@ void SetVisualsOffStage( const RegisteredVisualContainer& container, Actor paren
 
 // Properties registered without macro to use specific member variables.
 const PropertyRegistration Control::Impl::PROPERTY_1( typeRegistration, "styleName",              Toolkit::Control::Property::STYLE_NAME,                   Property::STRING,  &Control::Impl::SetProperty, &Control::Impl::GetProperty );
-const PropertyRegistration Control::Impl::PROPERTY_2( typeRegistration, "backgroundColor",        Toolkit::Control::Property::BACKGROUND_COLOR,             Property::VECTOR4, &Control::Impl::SetProperty, &Control::Impl::GetProperty );
-const PropertyRegistration Control::Impl::PROPERTY_3( typeRegistration, "backgroundImage",        Toolkit::Control::Property::BACKGROUND_IMAGE,             Property::MAP,     &Control::Impl::SetProperty, &Control::Impl::GetProperty );
 const PropertyRegistration Control::Impl::PROPERTY_4( typeRegistration, "keyInputFocus",          Toolkit::Control::Property::KEY_INPUT_FOCUS,              Property::BOOLEAN, &Control::Impl::SetProperty, &Control::Impl::GetProperty );
 const PropertyRegistration Control::Impl::PROPERTY_5( typeRegistration, "background",             Toolkit::Control::Property::BACKGROUND,                   Property::MAP,     &Control::Impl::SetProperty, &Control::Impl::GetProperty );
 const PropertyRegistration Control::Impl::PROPERTY_6( typeRegistration, "margin",                 Toolkit::Control::Property::MARGIN,                       Property::EXTENTS, &Control::Impl::SetProperty, &Control::Impl::GetProperty );
@@ -311,6 +310,7 @@ const PropertyRegistration Control::Impl::PROPERTY_11( typeRegistration, "leftFo
 const PropertyRegistration Control::Impl::PROPERTY_12( typeRegistration, "rightFocusableActorId", Toolkit::DevelControl::Property::RIGHT_FOCUSABLE_ACTOR_ID,Property::INTEGER, &Control::Impl::SetProperty, &Control::Impl::GetProperty );
 const PropertyRegistration Control::Impl::PROPERTY_13( typeRegistration, "upFocusableActorId",    Toolkit::DevelControl::Property::UP_FOCUSABLE_ACTOR_ID,   Property::INTEGER, &Control::Impl::SetProperty, &Control::Impl::GetProperty );
 const PropertyRegistration Control::Impl::PROPERTY_14( typeRegistration, "downFocusableActorId",  Toolkit::DevelControl::Property::DOWN_FOCUSABLE_ACTOR_ID, Property::INTEGER, &Control::Impl::SetProperty, &Control::Impl::GetProperty );
+const PropertyRegistration Control::Impl::PROPERTY_15( typeRegistration, "shadow",                Toolkit::DevelControl::Property::SHADOW,                  Property::MAP,     &Control::Impl::SetProperty, &Control::Impl::GetProperty );
 
 
 Control::Impl::Impl( Control& controlImpl )
@@ -323,25 +323,39 @@ Control::Impl::Impl( Control& controlImpl )
   mDownFocusableActorId( -1 ),
   mStyleName(""),
   mBackgroundColor(Color::TRANSPARENT),
-  mStartingPinchScale( NULL ),
+  mStartingPinchScale(nullptr),
   mMargin( 0, 0, 0, 0 ),
   mPadding( 0, 0, 0, 0 ),
   mKeyEventSignal(),
+  mKeyInputFocusGainedSignal(),
+  mKeyInputFocusLostSignal(),
+  mResourceReadySignal(),
+  mVisualEventSignal(),
   mPinchGestureDetector(),
   mPanGestureDetector(),
   mTapGestureDetector(),
   mLongPressGestureDetector(),
+  mTooltip( NULL ),
+  mInputMethodContext(),
+  mIdleCallback(nullptr),
   mFlags( Control::ControlBehaviour( CONTROL_BEHAVIOUR_DEFAULT ) ),
   mIsKeyboardNavigationSupported( false ),
-  mIsKeyboardFocusGroup( false )
+  mIsKeyboardFocusGroup( false ),
+  mIsEmittingResourceReadySignal(false),
+  mNeedToEmitResourceReady(false)
 {
-
 }
 
 Control::Impl::~Impl()
 {
   // All gesture detectors will be destroyed so no need to disconnect.
   delete mStartingPinchScale;
+
+  if(mIdleCallback && Adaptor::IsAvailable())
+  {
+    // Removes the callback from the callback manager in case the control is destroyed before the callback is executed.
+    Adaptor::Get().RemoveIdle(mIdleCallback);
+  }
 }
 
 Control::Impl& Control::Impl::Get( Internal::Control& internalControl )
@@ -428,7 +442,7 @@ void Control::Impl::RegisterVisual( Property::Index index, Toolkit::Visual::Base
         StopObservingVisual( currentRegisteredVisual );
 
         // If control staged and visual enabled then visuals will be swapped once ready
-        if(  self.OnStage() && enabled )
+        if(  self.GetProperty< bool >( Actor::Property::CONNECTED_TO_SCENE ) && enabled )
         {
           // Check if visual is currently in the process of being replaced ( is in removal container )
           RegisteredVisualContainer::Iterator visualQueuedForRemoval;
@@ -436,7 +450,7 @@ void Control::Impl::RegisterVisual( Property::Index index, Toolkit::Visual::Base
           {
             // Visual with same index is already in removal container so current visual pending
             // Only the the last requested visual will be displayed so remove current visual which is staged but not ready.
-            Toolkit::GetImplementation( currentRegisteredVisual ).SetOffStage( self );
+            Toolkit::GetImplementation( currentRegisteredVisual ).SetOffScene( self );
             mVisuals.Erase( registeredVisualsiter );
           }
           else
@@ -468,27 +482,18 @@ void Control::Impl::RegisterVisual( Property::Index index, Toolkit::Visual::Base
   // ( If the control has been type registered )
   if( visual.GetName().empty() )
   {
-    try
-    {
-      std::string visualName = self.GetPropertyName( index );
-      if( !visualName.empty() )
-      {
-        DALI_LOG_INFO( gLogFilter, Debug::Concise, "Setting visual name for property %d to %s\n",
-                       index, visualName.c_str() );
-        visual.SetName( visualName );
-      }
-    }
-    catch( Dali::DaliException e )
+    // returns empty string if index is not found as long as index is not -1
+    std::string visualName = self.GetPropertyName( index );
+    if( !visualName.empty() )
     {
-      DALI_LOG_WARNING( "Attempting to register visual without a registered property, index: %d\n", index );
+      DALI_LOG_INFO( gLogFilter, Debug::Concise, "Setting visual name for property %d to %s\n",
+                     index, visualName.c_str() );
+      visual.SetName( visualName );
     }
   }
 
   if( !visualReplaced ) // New registration entry
   {
-    // monitor when the visual resources are ready
-    StartObservingVisual( visual );
-
     // If we've not set the depth-index value, we have more than one visual and the visual does not have a depth index, then set it to be the highest
     if( ( depthIndexValueSet == DepthIndexValue::NOT_SET ) &&
         ( mVisuals.Size() > 0 ) &&
@@ -525,12 +530,17 @@ void Control::Impl::RegisterVisual( Property::Index index, Toolkit::Visual::Base
                                              ( visualReplaced && enabled ) ) ;
     mVisuals.PushBack( newRegisteredVisual );
 
+    Internal::Visual::Base& visualImpl = Toolkit::GetImplementation( visual );
     // Put on stage if enabled and the control is already on the stage
-    // Visual must be set on stage for the renderer to be created and the ResourceReady triggered.
-    if( ( enabled == VisualState::ENABLED ) && self.OnStage() )
+    if( ( enabled == VisualState::ENABLED ) && self.GetProperty< bool >( Actor::Property::CONNECTED_TO_SCENE ) )
+    {
+      visualImpl.SetOnScene( self );
+    }
+    else if( visualImpl.IsResourceReady() ) // When not being staged, check if visual already 'ResourceReady' before it was Registered. ( Resource may have been loaded already )
     {
-      Toolkit::GetImplementation(visual).SetOnStage( self );
+      ResourceReady( visualImpl );
     }
+
   }
 
   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Control::RegisterVisual() Registered %s(%d), enabled:%s\n",  visual.GetName().c_str(), index, enabled?"true":"false" );
@@ -545,7 +555,7 @@ void Control::Impl::UnregisterVisual( Property::Index index )
     StopObservingVisual( (*iter)->visual );
 
     Actor self( mControlImpl.Self() );
-    Toolkit::GetImplementation((*iter)->visual).SetOffStage( self );
+    Toolkit::GetImplementation((*iter)->visual).SetOffScene( self );
     (*iter)->visual.Reset();
     mVisuals.Erase( iter );
   }
@@ -553,7 +563,7 @@ void Control::Impl::UnregisterVisual( Property::Index index )
   if( FindVisual( index, mRemoveVisuals, iter ) )
   {
     Actor self( mControlImpl.Self() );
-    Toolkit::GetImplementation( (*iter)->visual ).SetOffStage( self );
+    Toolkit::GetImplementation( (*iter)->visual ).SetOffScene( self );
     (*iter)->pending = false;
     (*iter)->visual.Reset();
     mRemoveVisuals.Erase( iter );
@@ -573,7 +583,7 @@ Toolkit::Visual::Base Control::Impl::GetVisual( Property::Index index ) const
 
 void Control::Impl::EnableVisual( Property::Index index, bool enable )
 {
-  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Control::EnableVisual Visual (%d)\n", index);
+  DALI_LOG_INFO( gLogFilter, Debug::General, "Control::EnableVisual(%d, %s)\n", index, enable?"T":"F");
 
   RegisteredVisualContainer::Iterator iter;
   if ( FindVisual( index, mVisuals, iter ) )
@@ -586,20 +596,24 @@ void Control::Impl::EnableVisual( Property::Index index, bool enable )
 
     (*iter)->enabled = enable;
     Actor parentActor = mControlImpl.Self();
-    if ( mControlImpl.Self().OnStage() ) // If control not on Stage then Visual will be added when StageConnection is called.
+    if ( mControlImpl.Self().GetProperty< bool >( Actor::Property::CONNECTED_TO_SCENE ) ) // If control not on Scene then Visual will be added when SceneConnection is called.
     {
       if ( enable )
       {
         DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Control::EnableVisual Setting %s(%d) on stage \n", (*iter)->visual.GetName().c_str(), index );
-        Toolkit::GetImplementation((*iter)->visual).SetOnStage( parentActor );
+        Toolkit::GetImplementation((*iter)->visual).SetOnScene( parentActor );
       }
       else
       {
         DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Control::EnableVisual Setting %s(%d) off stage \n", (*iter)->visual.GetName().c_str(), index );
-        Toolkit::GetImplementation((*iter)->visual).SetOffStage( parentActor );  // No need to call if control not staged.
+        Toolkit::GetImplementation((*iter)->visual).SetOffScene( parentActor );  // No need to call if control not staged.
       }
     }
   }
+  else
+  {
+    DALI_LOG_WARNING( "Control::EnableVisual(%d, %s) FAILED - NO SUCH VISUAL\n", index, enable?"T":"F" );
+  }
 }
 
 bool Control::Impl::IsVisualEnabled( Property::Index index ) const
@@ -617,21 +631,21 @@ void Control::Impl::StopObservingVisual( Toolkit::Visual::Base& visual )
   Internal::Visual::Base& visualImpl = Toolkit::GetImplementation( visual );
 
   // Stop observing the visual
-  visualImpl.RemoveResourceObserver( *this );
+  visualImpl.RemoveEventObserver( *this );
 }
 
 void Control::Impl::StartObservingVisual( Toolkit::Visual::Base& visual)
 {
   Internal::Visual::Base& visualImpl = Toolkit::GetImplementation( visual );
 
-  // start observing the visual for resource ready
-  visualImpl.AddResourceObserver( *this );
+  // start observing the visual for events
+  visualImpl.AddEventObserver( *this );
 }
 
 // Called by a Visual when it's resource is ready
 void Control::Impl::ResourceReady( Visual::Base& object)
 {
-  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "ResourceReady replacements pending[%d]\n", mRemoveVisuals.Count() );
+  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Control::Impl::ResourceReady() replacements pending[%d]\n", mRemoveVisuals.Count() );
 
   Actor self = mControlImpl.Self();
 
@@ -650,21 +664,40 @@ void Control::Impl::ResourceReady( Visual::Base& object)
       if( FindVisual( (*registeredIter)->index, mRemoveVisuals, visualToRemoveIter ) )
       {
         (*registeredIter)->pending = false;
-        Toolkit::GetImplementation( (*visualToRemoveIter)->visual ).SetOffStage( self );
+        Toolkit::GetImplementation( (*visualToRemoveIter)->visual ).SetOffScene( self );
         mRemoveVisuals.Erase( visualToRemoveIter );
       }
       break;
     }
   }
 
-  // A visual is ready so control may need relayouting
-  mControlImpl.RelayoutRequest();
+  // A visual is ready so control may need relayouting if staged
+  if ( self.GetProperty< bool >( Actor::Property::CONNECTED_TO_SCENE ) )
+  {
+    mControlImpl.RelayoutRequest();
+  }
 
   // Emit signal if all enabled visuals registered by the control are ready.
   if( IsResourceReady() )
   {
-    Dali::Toolkit::Control handle( mControlImpl.GetOwner() );
-    mResourceReadySignal.Emit( handle );
+    // Reset the flag
+    mNeedToEmitResourceReady = false;
+
+    EmitResourceReadySignal();
+  }
+}
+
+void Control::Impl::NotifyVisualEvent( Visual::Base& object, Property::Index signalId )
+{
+  for( auto registeredIter = mVisuals.Begin(),  end = mVisuals.End(); registeredIter != end; ++registeredIter )
+  {
+    Internal::Visual::Base& registeredVisualImpl = Toolkit::GetImplementation( (*registeredIter)->visual );
+    if( &object == &registeredVisualImpl )
+    {
+      Dali::Toolkit::Control handle( mControlImpl.GetOwner() );
+      mVisualEventSignal.Emit( handle, (*registeredIter)->index, signalId );
+      break;
+    }
   }
 }
 
@@ -686,83 +719,114 @@ bool Control::Impl::IsResourceReady() const
   return true;
 }
 
+Toolkit::Visual::ResourceStatus Control::Impl::GetVisualResourceStatus( Property::Index index ) const
+{
+  RegisteredVisualContainer::Iterator iter;
+  if ( FindVisual( index, mVisuals, iter ) )
+  {
+    const Toolkit::Visual::Base visual = (*iter)->visual;
+    const Internal::Visual::Base& visualImpl = Toolkit::GetImplementation( visual );
+    return visualImpl.GetResourceStatus( );
+  }
 
-Dali::Animation Control::Impl::CreateTransition( const Toolkit::TransitionData& handle )
+  return Toolkit::Visual::ResourceStatus::PREPARING;
+}
+
+
+
+void Control::Impl::AddTransitions( Dali::Animation& animation,
+                                    const Toolkit::TransitionData& handle,
+                                    bool createAnimation )
 {
-  Dali::Animation transition;
+  // Setup a Transition from TransitionData.
   const Internal::TransitionData& transitionData = Toolkit::GetImplementation( handle );
-
-  if( transitionData.Count() > 0 )
+  TransitionData::Iterator end = transitionData.End();
+  for( TransitionData::Iterator iter = transitionData.Begin() ;
+       iter != end; ++iter )
   {
-    // Setup a Transition from TransitionData.
-    TransitionData::Iterator end = transitionData.End();
-    for( TransitionData::Iterator iter = transitionData.Begin() ;
-         iter != end; ++iter )
-    {
-      TransitionData::Animator* animator = (*iter);
+    TransitionData::Animator* animator = (*iter);
 
-      Toolkit::Visual::Base visual = GetVisualByName( mVisuals, animator->objectName );
+    Toolkit::Visual::Base visual = GetVisualByName( mVisuals, animator->objectName );
 
-      if( visual )
-      {
+    if( visual )
+    {
 #if defined(DEBUG_ENABLED)
-        Dali::TypeInfo typeInfo;
-        ControlWrapper* controlWrapperImpl = dynamic_cast<ControlWrapper*>(&mControlImpl);
-        if( controlWrapperImpl )
-        {
-          typeInfo = controlWrapperImpl->GetTypeInfo();
-        }
+      Dali::TypeInfo typeInfo;
+      ControlWrapper* controlWrapperImpl = dynamic_cast<ControlWrapper*>(&mControlImpl);
+      if( controlWrapperImpl )
+      {
+        typeInfo = controlWrapperImpl->GetTypeInfo();
+      }
 
-        DALI_LOG_INFO( gLogFilter, Debug::Concise, "CreateTransition: Found %s visual for %s\n",
-                       visual.GetName().c_str(), typeInfo?typeInfo.GetName().c_str():"Unknown" );
+      DALI_LOG_INFO( gLogFilter, Debug::Concise, "CreateTransition: Found %s visual for %s\n",
+                     visual.GetName().c_str(), typeInfo?typeInfo.GetName().c_str():"Unknown" );
 #endif
-        Internal::Visual::Base& visualImpl = Toolkit::GetImplementation( visual );
-        visualImpl.AnimateProperty( transition, *animator );
-      }
-      else
+      Internal::Visual::Base& visualImpl = Toolkit::GetImplementation( visual );
+      visualImpl.AnimateProperty( animation, *animator );
+    }
+    else
+    {
+      DALI_LOG_INFO( gLogFilter, Debug::Concise, "CreateTransition: Could not find visual. Trying actors");
+      // Otherwise, try any actor children of control (Including the control)
+      Actor child = mControlImpl.Self().FindChildByName( animator->objectName );
+      if( child )
       {
-        DALI_LOG_INFO( gLogFilter, Debug::Concise, "CreateTransition: Could not find visual. Trying actors");
-        // Otherwise, try any actor children of control (Including the control)
-        Actor child = mControlImpl.Self().FindChildByName( animator->objectName );
-        if( child )
+        Property::Index propertyIndex = child.GetPropertyIndex( animator->propertyKey );
+        if( propertyIndex != Property::INVALID_INDEX )
         {
-          Property::Index propertyIndex = DevelHandle::GetPropertyIndex( child, animator->propertyKey );
-          if( propertyIndex != Property::INVALID_INDEX )
+          if( animator->animate == false )
           {
-            if( animator->animate == false )
+            if( animator->targetValue.GetType() != Property::NONE )
             {
-              if( animator->targetValue.GetType() != Property::NONE )
-              {
-                child.SetProperty( propertyIndex, animator->targetValue );
-              }
+              child.SetProperty( propertyIndex, animator->targetValue );
             }
-            else // animate the property
+          }
+          else // animate the property
+          {
+            if( animator->initialValue.GetType() != Property::NONE )
             {
-              if( animator->initialValue.GetType() != Property::NONE )
-              {
-                child.SetProperty( propertyIndex, animator->initialValue );
-              }
-
-              if( ! transition )
-              {
-                transition = Dali::Animation::New( 0.1f );
-              }
-
-              transition.AnimateTo( Property( child, propertyIndex ),
-                                    animator->targetValue,
-                                    animator->alphaFunction,
-                                    TimePeriod( animator->timePeriodDelay,
-                                                animator->timePeriodDuration ) );
+              child.SetProperty( propertyIndex, animator->initialValue );
             }
+
+            if( createAnimation && !animation )
+            {
+              animation = Dali::Animation::New( 0.1f );
+            }
+
+            animation.AnimateTo( Property( child, propertyIndex ),
+                                 animator->targetValue,
+                                 animator->alphaFunction,
+                                 TimePeriod( animator->timePeriodDelay,
+                                             animator->timePeriodDuration ) );
           }
         }
       }
     }
   }
+}
+
+Dali::Animation Control::Impl::CreateTransition( const Toolkit::TransitionData& transitionData )
+{
+  Dali::Animation transition;
 
+  if( transitionData.Count() > 0 )
+  {
+    AddTransitions( transition, transitionData, true );
+  }
   return transition;
 }
 
+
+
+void Control::Impl::DoAction( Dali::Property::Index visualIndex, Dali::Property::Index actionId, const Dali::Property::Value attributes )
+{
+  RegisteredVisualContainer::Iterator iter;
+  if ( FindVisual( visualIndex, mVisuals, iter ) )
+  {
+    Toolkit::GetImplementation((*iter)->visual).DoAction( actionId, attributes );
+  }
+}
+
 void Control::Impl::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value )
 {
   Toolkit::Control control = Toolkit::Control::DownCast( BaseHandle( object ) );
@@ -783,7 +847,7 @@ void Control::Impl::SetProperty( BaseObject* object, Property::Index index, cons
       {
         bool withTransitions=true;
         const Property::Value* valuePtr=&value;
-        Property::Map* map = value.GetMap();
+        const Property::Map* map = value.GetMap();
         if(map)
         {
           Property::Value* value2 = map->Find("withTransitions");
@@ -856,29 +920,6 @@ void Control::Impl::SetProperty( BaseObject* object, Property::Index index, cons
       }
       break;
 
-      case Toolkit::Control::Property::BACKGROUND_COLOR:
-      {
-        DALI_LOG_WARNING( "BACKGROUND_COLOR property is deprecated. Use BACKGROUND property instead\n" );
-        controlImpl.SetBackgroundColor( value.Get< Vector4 >() );
-        break;
-      }
-
-      case Toolkit::Control::Property::BACKGROUND_IMAGE:
-      {
-        DALI_LOG_WARNING( "BACKGROUND_IMAGE property is deprecated. Use BACKGROUND property instead\n" );
-        Image image = Scripting::NewImage( value );
-        if ( image )
-        {
-          controlImpl.SetBackgroundImage( image );
-        }
-        else
-        {
-          // An empty image means the background is no longer required
-          controlImpl.ClearBackground();
-        }
-        break;
-      }
-
       case Toolkit::Control::Property::KEY_INPUT_FOCUS:
       {
         if ( value.Get< bool >() )
@@ -953,6 +994,21 @@ void Control::Impl::SetProperty( BaseObject* object, Property::Index index, cons
         break;
       }
 
+      case Toolkit::DevelControl::Property::SHADOW:
+      {
+        const Property::Map* map = value.GetMap();
+        if( map && !map->Empty() )
+        {
+          controlImpl.mImpl->SetShadow( *map );
+        }
+        else
+        {
+          // The shadow is an empty property map, so we should clear the shadow
+          controlImpl.mImpl->ClearShadow();
+        }
+        break;
+      }
+
     }
   }
 }
@@ -1011,26 +1067,6 @@ Property::Value Control::Impl::GetProperty( BaseObject* object, Property::Index
         break;
       }
 
-      case Toolkit::Control::Property::BACKGROUND_COLOR:
-      {
-        DALI_LOG_WARNING( "BACKGROUND_COLOR property is deprecated. Use BACKGROUND property instead\n" );
-        value = controlImpl.GetBackgroundColor();
-        break;
-      }
-
-      case Toolkit::Control::Property::BACKGROUND_IMAGE:
-      {
-        DALI_LOG_WARNING( "BACKGROUND_IMAGE property is deprecated. Use BACKGROUND property instead\n" );
-        Property::Map map;
-        Toolkit::Visual::Base visual = controlImpl.mImpl->GetVisual( Toolkit::Control::Property::BACKGROUND );
-        if( visual )
-        {
-          visual.CreatePropertyMap( map );
-        }
-        value = map;
-        break;
-      }
-
       case Toolkit::Control::Property::KEY_INPUT_FOCUS:
       {
         value = controlImpl.HasKeyInputFocus();
@@ -1072,6 +1108,19 @@ Property::Value Control::Impl::GetProperty( BaseObject* object, Property::Index
         value = map;
         break;
       }
+
+      case Toolkit::DevelControl::Property::SHADOW:
+      {
+        Property::Map map;
+        Toolkit::Visual::Base visual = controlImpl.mImpl->GetVisual( Toolkit::DevelControl::Property::SHADOW );
+        if( visual )
+        {
+          visual.CreatePropertyMap( map );
+        }
+
+        value = map;
+        break;
+      }
     }
   }
 
@@ -1103,7 +1152,7 @@ void Control::Impl::RemoveVisual( RegisteredVisualContainer& visuals, const std:
     Toolkit::Visual::Base visual = (*visualIter)->visual;
     if( visual && visual.GetName() == visualName )
     {
-      Toolkit::GetImplementation(visual).SetOffStage( self );
+      Toolkit::GetImplementation(visual).SetOffScene( self );
       (*visualIter)->visual.Reset();
       visuals.Erase( visualIter );
       break;
@@ -1317,22 +1366,22 @@ void Control::Impl::SetSubState( const std::string& subStateName, bool withTrans
   }
 }
 
-void Control::Impl::OnStageDisconnection()
+void Control::Impl::OnSceneDisconnection()
 {
   Actor self = mControlImpl.Self();
 
   // Any visuals set for replacement but not yet ready should still be registered.
-  // Reason: If a request was made to register a new visual but the control removed from stage before visual was ready
+  // Reason: If a request was made to register a new visual but the control removed from scene before visual was ready
   // then when this control appears back on stage it should use that new visual.
 
-  // Iterate through all registered visuals and set off stage
-  SetVisualsOffStage( mVisuals, self );
+  // Iterate through all registered visuals and set off scene
+  SetVisualsOffScene( mVisuals, self );
 
-  // Visuals pending replacement can now be taken out of the removal list and set off stage
-  // Iterate through all replacement visuals and add to a move queue then set off stage
+  // Visuals pending replacement can now be taken out of the removal list and set off scene
+  // Iterate through all replacement visuals and add to a move queue then set off scene
   for( auto removalIter = mRemoveVisuals.Begin(), end = mRemoveVisuals.End(); removalIter != end; removalIter++ )
   {
-    Toolkit::GetImplementation((*removalIter)->visual).SetOffStage( self );
+    Toolkit::GetImplementation((*removalIter)->visual).SetOffScene( self );
   }
 
   for( auto replacedIter = mVisuals.Begin(), end = mVisuals.End(); replacedIter != end; replacedIter++ )
@@ -1346,6 +1395,9 @@ void Control::Impl::OnStageDisconnection()
 void Control::Impl::SetMargin( Extents margin )
 {
   mControlImpl.mImpl->mMargin = margin;
+
+  // Trigger a size negotiation request that may be needed when setting a margin.
+  mControlImpl.RelayoutRequest();
 }
 
 Extents Control::Impl::GetMargin() const
@@ -1356,6 +1408,9 @@ Extents Control::Impl::GetMargin() const
 void Control::Impl::SetPadding( Extents padding )
 {
   mControlImpl.mImpl->mPadding = padding;
+
+  // Trigger a size negotiation request that may be needed when setting a padding.
+  mControlImpl.RelayoutRequest();
 }
 
 Extents Control::Impl::GetPadding() const
@@ -1363,6 +1418,100 @@ Extents Control::Impl::GetPadding() const
   return mControlImpl.mImpl->mPadding;
 }
 
+void Control::Impl::SetInputMethodContext( InputMethodContext& inputMethodContext )
+{
+  mInputMethodContext = inputMethodContext;
+}
+
+bool Control::Impl::FilterKeyEvent( const KeyEvent& event )
+{
+  bool consumed ( false );
+
+  if ( mInputMethodContext )
+  {
+    consumed = mInputMethodContext.FilterEventKey( event );
+  }
+  return consumed;
+}
+
+DevelControl::VisualEventSignalType& Control::Impl::VisualEventSignal()
+{
+  return mVisualEventSignal;
+}
+
+void Control::Impl::SetShadow( const Property::Map& map )
+{
+  Toolkit::Visual::Base visual = Toolkit::VisualFactory::Get().CreateVisual( map );
+  visual.SetName("shadow");
+
+  if( visual )
+  {
+    mControlImpl.mImpl->RegisterVisual( Toolkit::DevelControl::Property::SHADOW, visual, DepthIndex::BACKGROUND_EFFECT );
+
+    mControlImpl.RelayoutRequest();
+  }
+}
+
+void Control::Impl::ClearShadow()
+{
+   mControlImpl.mImpl->UnregisterVisual( Toolkit::DevelControl::Property::SHADOW );
+
+   // Trigger a size negotiation request that may be needed when unregistering a visual.
+   mControlImpl.RelayoutRequest();
+}
+
+void Control::Impl::EmitResourceReadySignal()
+{
+  if(!mIsEmittingResourceReadySignal)
+  {
+    // Guard against calls to emit the signal during the callback
+    mIsEmittingResourceReadySignal = true;
+
+    // If the signal handler changes visual, it may become ready during this call & therefore this method will
+    // get called again recursively. If so, mNeedToEmitResourceReady is set below, and we act on it after that secondary
+    // invocation has completed by notifying in an Idle callback to prevent further recursion.
+    Dali::Toolkit::Control handle(mControlImpl.GetOwner());
+    mResourceReadySignal.Emit(handle);
+
+    if(mNeedToEmitResourceReady)
+    {
+      // Add idler to emit the signal again
+      if(!mIdleCallback)
+      {
+        // The callback manager takes the ownership of the callback object.
+        mIdleCallback = MakeCallback( this, &Control::Impl::OnIdleCallback);
+        Adaptor::Get().AddIdle(mIdleCallback, false);
+      }
+    }
+
+    mIsEmittingResourceReadySignal = false;
+  }
+  else
+  {
+    mNeedToEmitResourceReady = true;
+  }
+}
+
+void Control::Impl::OnIdleCallback()
+{
+  if(mNeedToEmitResourceReady)
+  {
+    // Reset the flag
+    mNeedToEmitResourceReady = false;
+
+    // A visual is ready so control may need relayouting if staged
+    if(mControlImpl.Self().GetProperty<bool>(Actor::Property::CONNECTED_TO_SCENE))
+    {
+      mControlImpl.RelayoutRequest();
+    }
+
+    EmitResourceReadySignal();
+  }
+
+  // Set the pointer to null as the callback manager deletes the callback after execute it.
+  mIdleCallback = nullptr;
+}
+
 } // namespace Internal
 
 } // namespace Toolkit