(Control) Remove virtual inlines, better arrange source file & remove one friend
[platform/core/uifw/dali-toolkit.git] / base / dali-toolkit / public-api / controls / control-impl.cpp
index 2666cd7..bea8263 100644 (file)
@@ -606,84 +606,136 @@ Control::~Control()
   delete mImpl;
 }
 
-void Control::Initialize()
+void Control::SetSizePolicy( Toolkit::Control::SizePolicy widthPolicy, Toolkit::Control::SizePolicy heightPolicy )
 {
+  bool relayoutRequest( false );
 
-  // Calling deriving classes
-  OnInitialize();
-
-  if( mImpl->mFlags & REQUIRES_STYLE_CHANGE_SIGNALS )
+  if ( ( mImpl->mWidthPolicy != widthPolicy ) || ( mImpl->mHeightPolicy != heightPolicy ) )
   {
-    Toolkit::StyleManager styleManager = Toolkit::StyleManager::Get();
+    relayoutRequest = true;
+  }
 
-    // Register for style changes
-    styleManager.StyleChangeSignal().Connect( this, &Control::DoStyleChange );
+  mImpl->mWidthPolicy = widthPolicy;
+  mImpl->mHeightPolicy = heightPolicy;
 
-    // SetTheme
-    GetImpl( styleManager ).ApplyThemeStyle( GetOwner() );
+  // Ensure RelayoutRequest is called AFTER new policies have been set.
+  if ( relayoutRequest )
+  {
+    RelayoutRequest();
   }
+}
 
-  SetRequiresHoverEvents(mImpl->mFlags & REQUIRES_HOVER_EVENTS);
-  SetRequiresMouseWheelEvents(mImpl->mFlags & REQUIRES_MOUSE_WHEEL_EVENTS);
-
-  mImpl->mInitialized = true;
+void Control::GetSizePolicy( Toolkit::Control::SizePolicy& widthPolicy, Toolkit::Control::SizePolicy& heightPolicy ) const
+{
+  widthPolicy = mImpl->mWidthPolicy;
+  heightPolicy = mImpl->mHeightPolicy;
 }
 
-void Control::EnableGestureDetection(Gesture::Type type)
+void Control::SetMinimumSize( const Vector3& size )
 {
-  if ( (type & Gesture::Pinch) && !mImpl->mPinchGestureDetector )
+  const Vector3& minSize = mImpl->GetMinimumSize();
+  if ( fabsf( minSize.width - size.width ) > Math::MACHINE_EPSILON_1000 ||
+       fabsf( minSize.height - size.height ) > Math::MACHINE_EPSILON_1000 )
   {
-    mImpl->mPinchGestureDetector = PinchGestureDetector::New();
-    mImpl->mPinchGestureDetector.DetectedSignal().Connect(mImpl, &Impl::PinchDetected);
-    mImpl->mPinchGestureDetector.Attach(Self());
-  }
+    mImpl->SetMinimumSize( size );
 
-  if ( (type & Gesture::Pan) && !mImpl->mPanGestureDetector )
-  {
-    mImpl->mPanGestureDetector = PanGestureDetector::New();
-    mImpl->mPanGestureDetector.DetectedSignal().Connect(mImpl, &Impl::PanDetected);
-    mImpl->mPanGestureDetector.Attach(Self());
+    // Only relayout if our control is using the minimum or range policy.
+    if ( ( mImpl->mHeightPolicy == Toolkit::Control::Minimum ) || ( mImpl->mWidthPolicy  == Toolkit::Control::Minimum ) ||
+         ( mImpl->mHeightPolicy == Toolkit::Control::Range   ) || ( mImpl->mWidthPolicy  == Toolkit::Control::Range   ) )
+    {
+      RelayoutRequest();
+    }
   }
+}
 
-  if ( (type & Gesture::Tap) && !mImpl->mTapGestureDetector )
+const Vector3& Control::GetMinimumSize() const
+{
+  return mImpl->GetMinimumSize();
+}
+
+void Control::SetMaximumSize( const Vector3& size )
+{
+  const Vector3& maxSize = mImpl->GetMaximumSize();
+  if ( fabsf( maxSize.width - size.width ) > Math::MACHINE_EPSILON_1000 ||
+       fabsf( maxSize.height - size.height ) > Math::MACHINE_EPSILON_1000 )
   {
-    mImpl->mTapGestureDetector = TapGestureDetector::New();
-    mImpl->mTapGestureDetector.DetectedSignal().Connect(mImpl, &Impl::TapDetected);
-    mImpl->mTapGestureDetector.Attach(Self());
+    mImpl->SetMaximumSize( size );
+
+    // Only relayout if our control is using the maximum or range policy.
+    if ( ( mImpl->mHeightPolicy == Toolkit::Control::Maximum ) || ( mImpl->mWidthPolicy  == Toolkit::Control::Maximum ) ||
+         ( mImpl->mHeightPolicy == Toolkit::Control::Range   ) || ( mImpl->mWidthPolicy  == Toolkit::Control::Range   ) )
+    {
+      RelayoutRequest();
+    }
   }
+}
 
-  if ( (type & Gesture::LongPress) && !mImpl->mLongPressGestureDetector )
+const Vector3& Control::GetMaximumSize() const
+{
+  return mImpl->GetMaximumSize();
+}
+
+Vector3 Control::GetNaturalSize()
+{
+  // could be overridden in derived classes.
+  return mImpl->mNaturalSize;
+}
+
+float Control::GetHeightForWidth( float width )
+{
+  // could be overridden in derived classes.
+  float height( 0.0f );
+  if ( mImpl->mNaturalSize.width > 0.0f )
   {
-    mImpl->mLongPressGestureDetector = LongPressGestureDetector::New();
-    mImpl->mLongPressGestureDetector.DetectedSignal().Connect(mImpl, &Impl::LongPressDetected);
-    mImpl->mLongPressGestureDetector.Attach(Self());
+    height = mImpl->mNaturalSize.height * width / mImpl->mNaturalSize.width;
   }
+  return height;
 }
 
-void Control::DisableGestureDetection(Gesture::Type type)
+float Control::GetWidthForHeight( float height )
 {
-  if ( (type & Gesture::Pinch) && mImpl->mPinchGestureDetector )
+  // could be overridden in derived classes.
+  float width( 0.0f );
+  if ( mImpl->mNaturalSize.height > 0.0f )
   {
-    mImpl->mPinchGestureDetector.Detach(Self());
-    mImpl->mPinchGestureDetector.Reset();
+    width = mImpl->mNaturalSize.width * height / mImpl->mNaturalSize.height;
   }
+  return width;
+}
 
-  if ( (type & Gesture::Pan) && mImpl->mPanGestureDetector )
+const Vector3& Control::GetControlSize() const
+{
+  return mImpl->mCurrentSize;
+}
+
+const Vector3& Control::GetSizeSet() const
+{
+  return mImpl->mNaturalSize;
+}
+
+void Control::SetKeyInputFocus()
+{
+  if( Self().OnStage() )
   {
-    mImpl->mPanGestureDetector.Detach(Self());
-    mImpl->mPanGestureDetector.Reset();
+    Toolkit::KeyInputFocusManager::Get().SetFocus(Toolkit::Control::DownCast(Self()));
   }
+}
 
-  if ( (type & Gesture::Tap) && mImpl->mTapGestureDetector )
+bool Control::HasKeyInputFocus()
+{
+  bool result = false;
+  if( Self().OnStage() )
   {
-    mImpl->mTapGestureDetector.Detach(Self());
-    mImpl->mTapGestureDetector.Reset();
+    result = Toolkit::KeyInputFocusManager::Get().IsKeyboardListener(Toolkit::Control::DownCast(Self()));
   }
+  return result;
+}
 
-  if ( (type & Gesture::LongPress) && mImpl->mLongPressGestureDetector)
+void Control::ClearKeyInputFocus()
+{
+  if( Self().OnStage() )
   {
-    mImpl->mLongPressGestureDetector.Detach(Self());
-    mImpl->mLongPressGestureDetector.Reset();
+    Toolkit::KeyInputFocusManager::Get().RemoveFocus(Toolkit::Control::DownCast(Self()));
   }
 }
 
@@ -782,165 +834,140 @@ Actor Control::GetBackgroundActor() const
   return Actor();
 }
 
-void Control::OnThemeChange( Toolkit::StyleManager styleManager )
+void Control::SetKeyboardNavigationSupport(bool isSupported)
 {
-  GetImpl( styleManager ).ApplyThemeStyle( GetOwner() );
+  mImpl->mIsKeyboardNavigationSupported = isSupported;
 }
 
-void Control::OnPinch(const PinchGesture& pinch)
+bool Control::IsKeyboardNavigationSupported()
 {
-  if( !( mImpl->mStartingPinchScale ) )
-  {
-    // lazy allocate
-    mImpl->mStartingPinchScale = new Vector3;
-  }
-
-  if( pinch.state == Gesture::Started )
-  {
-    *( mImpl->mStartingPinchScale ) = Self().GetCurrentScale();
-  }
-
-  Self().SetScale( *( mImpl->mStartingPinchScale ) * pinch.scale );
+  return mImpl->mIsKeyboardNavigationSupported;
 }
 
-void Control::OnPan( const PanGesture& pan )
+void Control::Activate()
 {
+  // Inform deriving classes
+  OnActivated();
 }
 
-void Control::OnTap(const TapGesture& tap)
+bool Control::OnAccessibilityPan(PanGesture gesture)
 {
+  return false; // Accessibility pan gesture is not handled by default
 }
 
-void Control::OnLongPress( const LongPressGesture& longPress )
+bool Control::OnAccessibilityTouch(const TouchEvent& touchEvent)
 {
+  return false; // Accessibility touch event is not handled by default
 }
 
-void Control::OnStageConnection()
+bool Control::OnAccessibilityValueChange(bool isIncrease)
 {
-  RelayoutRequest();
-
-  // Notify derived classes.
-  OnControlStageConnection();
+  return false; // Accessibility value change action is not handled by default
 }
 
-void Control::OnStageDisconnection()
+void Control::NegotiateSize( Vector2 allocatedSize, ActorSizeContainer& container )
 {
-  // Notify derived classes
-  OnControlStageDisconnection();
-}
+  Vector2 size;
 
-void Control::OnChildAdd(Actor& child)
-{
-  // If this is the background actor, then we do not want to relayout or inform deriving classes
-  if ( mImpl->mBackground && ( child == mImpl->mBackground->actor ) )
+  if ( mImpl->mWidthPolicy == Toolkit::Control::Fixed )
   {
-    return;
-  }
+    if ( mImpl->mHeightPolicy == Toolkit::Control::Fixed )
+    {
+      // If a control says it has a fixed size, then use the size set by the application / control.
+      Vector2 setSize( mImpl->mNaturalSize );
+      if ( setSize != Vector2::ZERO )
+      {
+        size = setSize;
 
-  // Request for relayout as we may need to position the new child and old ones
-  RelayoutRequest();
+        // Policy is set to Fixed, so if the application / control has not set one of the dimensions,
+        // then we should use the natural size of the control rather than the full allocation.
+        if ( EqualsZero( size.width ) )
+        {
+          size.width = GetWidthForHeight( size.height );
+        }
+        else if ( EqualsZero( size.height ) )
+        {
+          size.height = GetHeightForWidth( size.width );
+        }
+      }
+      else
+      {
+        // If that is not set then set the size to the control's natural size
+        size = Vector2( GetNaturalSize() );
+      }
+    }
+    else
+    {
+      // Width is fixed so if the application / control has set it, then use that.
+      if ( !EqualsZero( mImpl->mNaturalSize.width ) )
+      {
+        size.width = mImpl->mNaturalSize.width;
+      }
+      else
+      {
+        // Otherwise, set the width to what has been allocated.
+        size.width = allocatedSize.width;
+      }
 
-  // Notify derived classes.
-  OnControlChildAdd( child );
-}
+      // Height is flexible so ask control what the height should be for our width.
+      size.height = GetHeightForWidth( size.width );
 
-void Control::OnChildRemove(Actor& child)
-{
-  // If this is the background actor, then we do not want to relayout or inform deriving classes
-  if ( mImpl->mBackground && ( child == mImpl->mBackground->actor ) )
-  {
-    return;
+      // Ensure height is within our policy rules
+      size.height = Calculate( mImpl->mHeightPolicy, GetMinimumSize().height, GetMaximumSize().height, size.height );
+    }
   }
-
-  // Request for relayout as we may need to re-position the old child
-  RelayoutRequest();
-
-  // Notify derived classes.
-  OnControlChildRemove( child );
-}
-
-void Control::OnSizeSet(const Vector3& targetSize)
-{
-  if( ( !mImpl->mInsideRelayout ) && ( targetSize != mImpl->mNaturalSize ) )
+  else
   {
-    // Only updates size if set through Actor's API
-    mImpl->mNaturalSize = targetSize;
-  }
+    if ( mImpl->mHeightPolicy == Toolkit::Control::Fixed )
+    {
+      // Height is fixed so if the application / control has set it, then use that.
+      if ( !EqualsZero( mImpl->mNaturalSize.height ) )
+      {
+        size.height = mImpl->mNaturalSize.height;
+      }
+      else
+      {
+        // Otherwise, set the height to what has been allocated.
+        size.height = allocatedSize.height;
+      }
 
-  if( targetSize != mImpl->mCurrentSize )
-  {
-    // Update control size.
-    mImpl->mCurrentSize = targetSize;
+      // Width is flexible so ask control what the width should be for our height.
+      size.width = GetWidthForHeight( size.height );
 
-    // Notify derived classes.
-    OnControlSizeSet( targetSize );
+      // Ensure width is within our policy rules
+      size.width = Calculate( mImpl->mWidthPolicy, mImpl->GetMinimumSize().width, mImpl->GetMaximumSize().width, size.width );
+    }
+    else
+    {
+      // Width and height are BOTH flexible.
+      // Calculate the width and height using the policy rules.
+      size.width = Calculate( mImpl->mWidthPolicy, mImpl->GetMinimumSize().width, mImpl->GetMaximumSize().width, allocatedSize.width );
+      size.height = Calculate( mImpl->mHeightPolicy, mImpl->GetMinimumSize().height, mImpl->GetMaximumSize().height, allocatedSize.height );
+    }
   }
-}
-
-void Control::OnSizeAnimation(Animation& animation, const Vector3& targetSize)
-{
-  // @todo consider animating negotiated child sizes to target size
-}
-
-bool Control::OnTouchEvent(const TouchEvent& event)
-{
-  return false; // Do not consume
-}
-
-bool Control::OnHoverEvent(const HoverEvent& event)
-{
-  return false; // Do not consume
-}
-
-bool Control::OnKeyEvent(const KeyEvent& event)
-{
-  return false; // Do not consume
-}
-
-bool Control::OnMouseWheelEvent(const MouseWheelEvent& event)
-{
-  return false; // Do not consume
-}
-
-void Control::OnKeyInputFocusGained()
-{
-  // Do Nothing
-}
-
-void Control::OnKeyInputFocusLost()
-{
-  // Do Nothing
-}
-
-Actor Control::GetChildByAlias(const std::string& actorAlias)
-{
-  return Actor();
-}
-
-bool Control::OnAccessibilityPan(PanGesture gesture)
-{
-  return false; // Accessibility pan gesture is not handled by default
-}
-
-bool Control::OnAccessibilityTouch(const TouchEvent& touchEvent)
-{
-  return false; // Accessibility touch event is not handled by default
-}
 
-bool Control::OnAccessibilityValueChange(bool isIncrease)
-{
-  return false; // Accessibility value change action is not handled by default
-}
+  // If the width has not been set, then set to the allocated width.
+  // Also if the width set is greater than the allocated, then set to allocated (no exceed support).
+  if ( EqualsZero( size.width ) || ( size.width > allocatedSize.width ) )
+  {
+    size.width = allocatedSize.width;
+  }
 
+  // If the height has not been set, then set to the allocated height.
+  // Also if the height set is greater than the allocated, then set to allocated (no exceed support).
+  if ( EqualsZero( size.height ) || ( size.height > allocatedSize.height ) )
+  {
+    size.height = allocatedSize.height;
+  }
 
-void Control::SetKeyboardNavigationSupport(bool isSupported)
-{
-  mImpl->mIsKeyboardNavigationSupported = isSupported;
-}
+  DALI_LOG_INFO( gLogFilter, Debug::Verbose,
+                 "%p: Natural: [%.2f, %.2f] Allocated: [%.2f, %.2f] Set: [%.2f, %.2f]\n",
+                 Self().GetObjectPtr(),
+                 GetNaturalSize().x, GetNaturalSize().y,
+                 allocatedSize.x, allocatedSize.y,
+                 size.x, size.y );
 
-bool Control::IsKeyboardNavigationSupported()
-{
-  return mImpl->mIsKeyboardNavigationSupported;
+  Relayout( size, container );
 }
 
 void Control::SetAsKeyboardFocusGroup(bool isFocusGroup)
@@ -961,6 +988,10 @@ Actor Control::GetNextKeyboardFocusableActor(Actor currentFocusedActor, Toolkit:
   return Actor();
 }
 
+void Control::OnKeyboardFocusChangeCommitted(Actor commitedFocusableActor)
+{
+}
+
 bool Control::DoAction(BaseObject* object, const std::string& actionName, const PropertyValueContainer& attributes)
 {
   bool ret = false;
@@ -1022,153 +1053,118 @@ bool Control::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* t
   return connected;
 }
 
-void Control::DoStyleChange( Toolkit::StyleManager styleManager, StyleChange change )
-{
-  if( change.themeChange )
-  {
-    OnThemeChange( styleManager );
-  }
-  else if( change.defaultFontChange || change.defaultFontSizeChange )
-  {
-    OnFontChange( change.defaultFontChange, change.defaultFontSizeChange );
-  }
-}
-
 Toolkit::Control::KeyEventSignalV2& Control::KeyEventSignal()
 {
   return mImpl->mKeyEventSignalV2;
 }
 
-void Control::SetSizePolicy( Toolkit::Control::SizePolicy widthPolicy, Toolkit::Control::SizePolicy heightPolicy )
+bool Control::EmitKeyEventSignal( const KeyEvent& event )
 {
-  bool relayoutRequest( false );
+  // Guard against destruction during signal emission
+  Dali::Toolkit::Control handle( GetOwner() );
 
-  if ( ( mImpl->mWidthPolicy != widthPolicy ) || ( mImpl->mHeightPolicy != heightPolicy ) )
+  bool consumed = false;
+
+  // signals are allocated dynamically when someone connects
+  if ( !mImpl->mKeyEventSignalV2.Empty() )
   {
-    relayoutRequest = true;
+    consumed = mImpl->mKeyEventSignalV2.Emit( handle, event );
   }
 
-  mImpl->mWidthPolicy = widthPolicy;
-  mImpl->mHeightPolicy = heightPolicy;
-
-  // Ensure RelayoutRequest is called AFTER new policies have been set.
-  if ( relayoutRequest )
+  if (!consumed)
   {
-    RelayoutRequest();
+    // Notification for derived classes
+    consumed = OnKeyEvent(event);
   }
+
+  return consumed;
 }
 
-void Control::GetSizePolicy( Toolkit::Control::SizePolicy& widthPolicy, Toolkit::Control::SizePolicy& heightPolicy ) const
+Control::Control( ControlBehaviour behaviourFlags )
+: CustomActorImpl( behaviourFlags & REQUIRES_TOUCH_EVENTS ),
+  mImpl(new Impl(*this))
 {
-  widthPolicy = mImpl->mWidthPolicy;
-  heightPolicy = mImpl->mHeightPolicy;
+  mImpl->mFlags = behaviourFlags;
 }
 
-void Control::SetMinimumSize( const Vector3& size )
+void Control::Initialize()
 {
-  const Vector3& minSize = mImpl->GetMinimumSize();
-  if ( fabsf( minSize.width - size.width ) > Math::MACHINE_EPSILON_1000 ||
-       fabsf( minSize.height - size.height ) > Math::MACHINE_EPSILON_1000 )
+
+  // Calling deriving classes
+  OnInitialize();
+
+  if( mImpl->mFlags & REQUIRES_STYLE_CHANGE_SIGNALS )
   {
-    mImpl->SetMinimumSize( size );
+    Toolkit::StyleManager styleManager = Toolkit::StyleManager::Get();
 
-    // Only relayout if our control is using the minimum or range policy.
-    if ( ( mImpl->mHeightPolicy == Toolkit::Control::Minimum ) || ( mImpl->mWidthPolicy  == Toolkit::Control::Minimum ) ||
-         ( mImpl->mHeightPolicy == Toolkit::Control::Range   ) || ( mImpl->mWidthPolicy  == Toolkit::Control::Range   ) )
-    {
-      RelayoutRequest();
-    }
+    // Register for style changes
+    styleManager.StyleChangeSignal().Connect( this, &Control::DoStyleChange );
+
+    // SetTheme
+    GetImpl( styleManager ).ApplyThemeStyle( GetOwner() );
   }
-}
 
-const Vector3& Control::GetMinimumSize() const
-{
-  return mImpl->GetMinimumSize();
+  SetRequiresHoverEvents(mImpl->mFlags & REQUIRES_HOVER_EVENTS);
+  SetRequiresMouseWheelEvents(mImpl->mFlags & REQUIRES_MOUSE_WHEEL_EVENTS);
+
+  mImpl->mInitialized = true;
 }
 
-void Control::SetMaximumSize( const Vector3& size )
+void Control::EnableGestureDetection(Gesture::Type type)
 {
-  const Vector3& maxSize = mImpl->GetMaximumSize();
-  if ( fabsf( maxSize.width - size.width ) > Math::MACHINE_EPSILON_1000 ||
-       fabsf( maxSize.height - size.height ) > Math::MACHINE_EPSILON_1000 )
+  if ( (type & Gesture::Pinch) && !mImpl->mPinchGestureDetector )
   {
-    mImpl->SetMaximumSize( size );
+    mImpl->mPinchGestureDetector = PinchGestureDetector::New();
+    mImpl->mPinchGestureDetector.DetectedSignal().Connect(mImpl, &Impl::PinchDetected);
+    mImpl->mPinchGestureDetector.Attach(Self());
+  }
 
-    // Only relayout if our control is using the maximum or range policy.
-    if ( ( mImpl->mHeightPolicy == Toolkit::Control::Maximum ) || ( mImpl->mWidthPolicy  == Toolkit::Control::Maximum ) ||
-         ( mImpl->mHeightPolicy == Toolkit::Control::Range   ) || ( mImpl->mWidthPolicy  == Toolkit::Control::Range   ) )
-    {
-      RelayoutRequest();
-    }
+  if ( (type & Gesture::Pan) && !mImpl->mPanGestureDetector )
+  {
+    mImpl->mPanGestureDetector = PanGestureDetector::New();
+    mImpl->mPanGestureDetector.DetectedSignal().Connect(mImpl, &Impl::PanDetected);
+    mImpl->mPanGestureDetector.Attach(Self());
   }
-}
 
-const Vector3& Control::GetMaximumSize() const
-{
-  return mImpl->GetMaximumSize();
-}
+  if ( (type & Gesture::Tap) && !mImpl->mTapGestureDetector )
+  {
+    mImpl->mTapGestureDetector = TapGestureDetector::New();
+    mImpl->mTapGestureDetector.DetectedSignal().Connect(mImpl, &Impl::TapDetected);
+    mImpl->mTapGestureDetector.Attach(Self());
+  }
 
-Vector3 Control::GetNaturalSize()
-{
-  // could be overridden in derived classes.
-  return mImpl->mNaturalSize;
+  if ( (type & Gesture::LongPress) && !mImpl->mLongPressGestureDetector )
+  {
+    mImpl->mLongPressGestureDetector = LongPressGestureDetector::New();
+    mImpl->mLongPressGestureDetector.DetectedSignal().Connect(mImpl, &Impl::LongPressDetected);
+    mImpl->mLongPressGestureDetector.Attach(Self());
+  }
 }
 
-float Control::GetHeightForWidth( float width )
+void Control::DisableGestureDetection(Gesture::Type type)
 {
-  // could be overridden in derived classes.
-  float height( 0.0f );
-  if ( mImpl->mNaturalSize.width > 0.0f )
+  if ( (type & Gesture::Pinch) && mImpl->mPinchGestureDetector )
   {
-    height = mImpl->mNaturalSize.height * width / mImpl->mNaturalSize.width;
+    mImpl->mPinchGestureDetector.Detach(Self());
+    mImpl->mPinchGestureDetector.Reset();
   }
-  return height;
-}
 
-float Control::GetWidthForHeight( float height )
-{
-  // could be overridden in derived classes.
-  float width( 0.0f );
-  if ( mImpl->mNaturalSize.height > 0.0f )
+  if ( (type & Gesture::Pan) && mImpl->mPanGestureDetector )
   {
-    width = mImpl->mNaturalSize.width * height / mImpl->mNaturalSize.height;
+    mImpl->mPanGestureDetector.Detach(Self());
+    mImpl->mPanGestureDetector.Reset();
   }
-  return width;
-}
 
-const Vector3& Control::GetControlSize() const
-{
-  return mImpl->mCurrentSize;
-}
-
-const Vector3& Control::GetSizeSet() const
-{
-  return mImpl->mNaturalSize;
-}
-
-void Control::SetKeyInputFocus()
-{
-  if( Self().OnStage() )
-  {
-    Toolkit::KeyInputFocusManager::Get().SetFocus(Toolkit::Control::DownCast(Self()));
-  }
-}
-
-bool Control::HasKeyInputFocus()
-{
-  bool result = false;
-  if( Self().OnStage() )
+  if ( (type & Gesture::Tap) && mImpl->mTapGestureDetector )
   {
-    result = Toolkit::KeyInputFocusManager::Get().IsKeyboardListener(Toolkit::Control::DownCast(Self()));
+    mImpl->mTapGestureDetector.Detach(Self());
+    mImpl->mTapGestureDetector.Reset();
   }
-  return result;
-}
 
-void Control::ClearKeyInputFocus()
-{
-  if( Self().OnStage() )
+  if ( (type & Gesture::LongPress) && mImpl->mLongPressGestureDetector)
   {
-    Toolkit::KeyInputFocusManager::Get().RemoveFocus(Toolkit::Control::DownCast(Self()));
+    mImpl->mLongPressGestureDetector.Detach(Self());
+    mImpl->mLongPressGestureDetector.Reset();
   }
 }
 
@@ -1182,18 +1178,6 @@ void Control::RelayoutRequest()
   }
 }
 
-void Control::Relayout(Vector2 size, ActorSizeContainer& container)
-{
-  // Avoids relayout again when OnSizeSet callback arrives.
-  mImpl->mInsideRelayout = true;
-  Self().SetSize( size );
-  // @todo this really needs to be at the end of method but not sure why the scope used to be only the SetSize, needs to be cleaned up in size negotiation rework
-  mImpl->mInsideRelayout = false;
-
-  // Only relayout controls which requested to be relaid out.
-  OnRelaidOut( size, container );
-}
-
 void Control::Relayout( Actor actor, Vector2 size, ActorSizeContainer& container )
 {
   if ( actor )
@@ -1210,6 +1194,71 @@ void Control::Relayout( Actor actor, Vector2 size, ActorSizeContainer& container
   }
 }
 
+void Control::OnInitialize()
+{
+}
+
+void Control::OnActivated()
+{
+}
+
+void Control::OnThemeChange( Toolkit::StyleManager styleManager )
+{
+  GetImpl( styleManager ).ApplyThemeStyle( GetOwner() );
+}
+
+void Control::OnFontChange( bool defaultFontChange, bool defaultFontSizeChange )
+{
+}
+
+void Control::OnPinch(const PinchGesture& pinch)
+{
+  if( !( mImpl->mStartingPinchScale ) )
+  {
+    // lazy allocate
+    mImpl->mStartingPinchScale = new Vector3;
+  }
+
+  if( pinch.state == Gesture::Started )
+  {
+    *( mImpl->mStartingPinchScale ) = Self().GetCurrentScale();
+  }
+
+  Self().SetScale( *( mImpl->mStartingPinchScale ) * pinch.scale );
+}
+
+void Control::OnPan( const PanGesture& pan )
+{
+}
+
+void Control::OnTap(const TapGesture& tap)
+{
+}
+
+void Control::OnLongPress( const LongPressGesture& longPress )
+{
+}
+
+void Control::OnControlStageConnection()
+{
+}
+
+void Control::OnControlStageDisconnection()
+{
+}
+
+void Control::OnControlChildAdd( Actor& child )
+{
+}
+
+void Control::OnControlChildRemove( Actor& child )
+{
+}
+
+void Control::OnControlSizeSet( const Vector3& size )
+{
+}
+
 void Control::OnRelaidOut( Vector2 size, ActorSizeContainer& container )
 {
   unsigned int numChildren = Self().GetChildCount();
@@ -1220,131 +1269,106 @@ void Control::OnRelaidOut( Vector2 size, ActorSizeContainer& container )
   }
 }
 
-void Control::NegotiateSize( Vector2 allocatedSize, ActorSizeContainer& container )
+void Control::OnKeyInputFocusGained()
 {
-  Vector2 size;
+  // Do Nothing
+}
 
-  if ( mImpl->mWidthPolicy == Toolkit::Control::Fixed )
-  {
-    if ( mImpl->mHeightPolicy == Toolkit::Control::Fixed )
-    {
-      // If a control says it has a fixed size, then use the size set by the application / control.
-      Vector2 setSize( mImpl->mNaturalSize );
-      if ( setSize != Vector2::ZERO )
-      {
-        size = setSize;
+void Control::OnKeyInputFocusLost()
+{
+  // Do Nothing
+}
 
-        // Policy is set to Fixed, so if the application / control has not set one of the dimensions,
-        // then we should use the natural size of the control rather than the full allocation.
-        if ( EqualsZero( size.width ) )
-        {
-          size.width = GetWidthForHeight( size.height );
-        }
-        else if ( EqualsZero( size.height ) )
-        {
-          size.height = GetHeightForWidth( size.width );
-        }
-      }
-      else
-      {
-        // If that is not set then set the size to the control's natural size
-        size = Vector2( GetNaturalSize() );
-      }
-    }
-    else
-    {
-      // Width is fixed so if the application / control has set it, then use that.
-      if ( !EqualsZero( mImpl->mNaturalSize.width ) )
-      {
-        size.width = mImpl->mNaturalSize.width;
-      }
-      else
-      {
-        // Otherwise, set the width to what has been allocated.
-        size.width = allocatedSize.width;
-      }
+void Control::OnSizeAnimation(Animation& animation, const Vector3& targetSize)
+{
+  // @todo consider animating negotiated child sizes to target size
+}
 
-      // Height is flexible so ask control what the height should be for our width.
-      size.height = GetHeightForWidth( size.width );
+bool Control::OnTouchEvent(const TouchEvent& event)
+{
+  return false; // Do not consume
+}
 
-      // Ensure height is within our policy rules
-      size.height = Calculate( mImpl->mHeightPolicy, GetMinimumSize().height, GetMaximumSize().height, size.height );
-    }
-  }
-  else
-  {
-    if ( mImpl->mHeightPolicy == Toolkit::Control::Fixed )
-    {
-      // Height is fixed so if the application / control has set it, then use that.
-      if ( !EqualsZero( mImpl->mNaturalSize.height ) )
-      {
-        size.height = mImpl->mNaturalSize.height;
-      }
-      else
-      {
-        // Otherwise, set the height to what has been allocated.
-        size.height = allocatedSize.height;
-      }
+bool Control::OnHoverEvent(const HoverEvent& event)
+{
+  return false; // Do not consume
+}
 
-      // Width is flexible so ask control what the width should be for our height.
-      size.width = GetWidthForHeight( size.height );
+bool Control::OnKeyEvent(const KeyEvent& event)
+{
+  return false; // Do not consume
+}
 
-      // Ensure width is within our policy rules
-      size.width = Calculate( mImpl->mWidthPolicy, mImpl->GetMinimumSize().width, mImpl->GetMaximumSize().width, size.width );
-    }
-    else
-    {
-      // Width and height are BOTH flexible.
-      // Calculate the width and height using the policy rules.
-      size.width = Calculate( mImpl->mWidthPolicy, mImpl->GetMinimumSize().width, mImpl->GetMaximumSize().width, allocatedSize.width );
-      size.height = Calculate( mImpl->mHeightPolicy, mImpl->GetMinimumSize().height, mImpl->GetMaximumSize().height, allocatedSize.height );
-    }
-  }
+bool Control::OnMouseWheelEvent(const MouseWheelEvent& event)
+{
+  return false; // Do not consume
+}
 
-  // If the width has not been set, then set to the allocated width.
-  // Also if the width set is greater than the allocated, then set to allocated (no exceed support).
-  if ( EqualsZero( size.width ) || ( size.width > allocatedSize.width ) )
-  {
-    size.width = allocatedSize.width;
-  }
+Actor Control::GetChildByAlias(const std::string& actorAlias)
+{
+  return Actor();
+}
 
-  // If the height has not been set, then set to the allocated height.
-  // Also if the height set is greater than the allocated, then set to allocated (no exceed support).
-  if ( EqualsZero( size.height ) || ( size.height > allocatedSize.height ) )
+void Control::OnStageConnection()
+{
+  RelayoutRequest();
+
+  // Notify derived classes.
+  OnControlStageConnection();
+}
+
+void Control::OnStageDisconnection()
+{
+  // Notify derived classes
+  OnControlStageDisconnection();
+}
+
+void Control::OnChildAdd(Actor& child)
+{
+  // If this is the background actor, then we do not want to relayout or inform deriving classes
+  if ( mImpl->mBackground && ( child == mImpl->mBackground->actor ) )
   {
-    size.height = allocatedSize.height;
+    return;
   }
 
-  DALI_LOG_INFO( gLogFilter, Debug::Verbose,
-                 "%p: Natural: [%.2f, %.2f] Allocated: [%.2f, %.2f] Set: [%.2f, %.2f]\n",
-                 Self().GetObjectPtr(),
-                 GetNaturalSize().x, GetNaturalSize().y,
-                 allocatedSize.x, allocatedSize.y,
-                 size.x, size.y );
+  // Request for relayout as we may need to position the new child and old ones
+  RelayoutRequest();
 
-  Relayout( size, container );
+  // Notify derived classes.
+  OnControlChildAdd( child );
 }
 
-bool Control::EmitKeyEventSignal( const KeyEvent& event )
+void Control::OnChildRemove(Actor& child)
 {
-  // Guard against destruction during signal emission
-  Dali::Toolkit::Control handle( GetOwner() );
+  // If this is the background actor, then we do not want to relayout or inform deriving classes
+  if ( mImpl->mBackground && ( child == mImpl->mBackground->actor ) )
+  {
+    return;
+  }
 
-  bool consumed = false;
+  // Request for relayout as we may need to re-position the old child
+  RelayoutRequest();
 
-  // signals are allocated dynamically when someone connects
-  if ( !mImpl->mKeyEventSignalV2.Empty() )
+  // Notify derived classes.
+  OnControlChildRemove( child );
+}
+
+void Control::OnSizeSet(const Vector3& targetSize)
+{
+  if( ( !mImpl->mInsideRelayout ) && ( targetSize != mImpl->mNaturalSize ) )
   {
-    consumed = mImpl->mKeyEventSignalV2.Emit( handle, event );
+    // Only updates size if set through Actor's API
+    mImpl->mNaturalSize = targetSize;
   }
 
-  if (!consumed)
+  if( targetSize != mImpl->mCurrentSize )
   {
-    // Notification for derived classes
-    consumed = OnKeyEvent(event);
-  }
+    // Update control size.
+    mImpl->mCurrentSize = targetSize;
 
-  return consumed;
+    // Notify derived classes.
+    OnControlSizeSet( targetSize );
+  }
 }
 
 void Control::SignalConnected( SlotObserver* slotObserver, CallbackBase* callback )
@@ -1357,11 +1381,28 @@ void Control::SignalDisconnected( SlotObserver* slotObserver, CallbackBase* call
   mImpl->SignalDisconnected( slotObserver, callback );
 }
 
-Control::Control( ControlBehaviour behaviourFlags )
-: CustomActorImpl( behaviourFlags & REQUIRES_TOUCH_EVENTS ),
-  mImpl(new Impl(*this))
+void Control::DoStyleChange( Toolkit::StyleManager styleManager, StyleChange change )
 {
-  mImpl->mFlags = behaviourFlags;
+  if( change.themeChange )
+  {
+    OnThemeChange( styleManager );
+  }
+  else if( change.defaultFontChange || change.defaultFontSizeChange )
+  {
+    OnFontChange( change.defaultFontChange, change.defaultFontSizeChange );
+  }
+}
+
+void Control::Relayout(Vector2 size, ActorSizeContainer& container)
+{
+  // Avoids relayout again when OnSizeSet callback arrives.
+  mImpl->mInsideRelayout = true;
+  Self().SetSize( size );
+  // @todo this really needs to be at the end of method but not sure why the scope used to be only the SetSize, needs to be cleaned up in size negotiation rework
+  mImpl->mInsideRelayout = false;
+
+  // Only relayout controls which requested to be relaid out.
+  OnRelaidOut( size, container );
 }
 
 } // namespace Internal