[dali_1.0.21] Merge branch 'tizen'
[platform/core/uifw/dali-toolkit.git] / base / dali-toolkit / public-api / controls / control-impl.cpp
1 /*
2  * Copyright (c) 2014 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 // CLASS HEADER
19 #include <dali-toolkit/public-api/controls/control-impl.h>
20
21 // EXTERNAL INCLUDES
22 #include <stack>
23 #include <dali/public-api/actors/image-actor.h>
24 #include <dali/public-api/actors/mesh-actor.h>
25 #include <dali/public-api/animation/constraints.h>
26 #include <dali/public-api/geometry/mesh.h>
27 #include <dali/public-api/object/type-registry.h>
28 #include <dali/public-api/scripting/scripting.h>
29 #include <dali/integration-api/debug.h>
30
31 #include <dali-toolkit/internal/controls/relayout-controller.h>
32 #include <dali-toolkit/internal/controls/relayout-helper.h>
33 #include <dali-toolkit/public-api/focus-manager/keyinput-focus-manager.h>
34 #include <dali-toolkit/public-api/focus-manager/keyboard-focus-manager.h>
35 #include <dali-toolkit/public-api/controls/control.h>
36 #include <dali-toolkit/public-api/styling/style-manager.h>
37 #include <dali-toolkit/internal/styling/style-manager-impl.h>
38
39 namespace Dali
40 {
41
42 namespace Toolkit
43 {
44
45 const Property::Index Control::PROPERTY_BACKGROUND_COLOR      = Internal::Control::CONTROL_PROPERTY_START_INDEX;
46 const Property::Index Control::PROPERTY_BACKGROUND            = Internal::Control::CONTROL_PROPERTY_START_INDEX + 1;
47 const Property::Index Control::PROPERTY_WIDTH_POLICY          = Internal::Control::CONTROL_PROPERTY_START_INDEX + 2;
48 const Property::Index Control::PROPERTY_HEIGHT_POLICY         = Internal::Control::CONTROL_PROPERTY_START_INDEX + 3;
49 const Property::Index Control::PROPERTY_MINIMUM_SIZE          = Internal::Control::CONTROL_PROPERTY_START_INDEX + 4;
50 const Property::Index Control::PROPERTY_MAXIMUM_SIZE          = Internal::Control::CONTROL_PROPERTY_START_INDEX + 5;
51 const Property::Index Control::PROPERTY_KEY_INPUT_FOCUS       = Internal::Control::CONTROL_PROPERTY_START_INDEX + 6;
52
53 namespace
54 {
55
56 const Scripting::StringEnum< Control::SizePolicy > SIZE_POLICY_STRING_TABLE[] =
57 {
58   { "FIXED",      Control::Fixed      },
59   { "MINIMUM",    Control::Minimum    },
60   { "MAXIMUM",    Control::Maximum    },
61   { "RANGE",      Control::Range      },
62   { "FLEXIBLE",   Control::Flexible   },
63 };
64 const unsigned int SIZE_POLICY_STRING_TABLE_COUNT = sizeof( SIZE_POLICY_STRING_TABLE ) / sizeof( SIZE_POLICY_STRING_TABLE[0] );
65
66 #if defined(DEBUG_ENABLED)
67 Integration::Log::Filter* gLogFilter  = Integration::Log::Filter::New(Debug::NoLogging, false, "LOG_CONTROL");
68 #endif
69
70 const float MAX_FLOAT_VALUE( std::numeric_limits<float>::max() );
71 const Vector3 MAX_SIZE( MAX_FLOAT_VALUE, MAX_FLOAT_VALUE, MAX_FLOAT_VALUE );
72 const float BACKGROUND_ACTOR_Z_POSITION( -0.1f );
73
74 BaseHandle Create()
75 {
76   return Internal::Control::New();
77 }
78
79 TypeRegistration CONTROL_TYPE( typeid(Control), typeid(CustomActor), Create );
80
81 // Property Registration after Internal::Control::Impl definition below
82
83 TypeAction ACTION_TYPE_1( CONTROL_TYPE, Toolkit::Control::ACTION_CONTROL_ACTIVATED, &Internal::Control::DoAction );
84
85 SignalConnectorType SIGNAL_CONNECTOR_1( CONTROL_TYPE, Toolkit::Control::SIGNAL_KEY_EVENT,     &Internal::Control::DoConnectSignal );
86 SignalConnectorType SIGNAL_CONNECTOR_2( CONTROL_TYPE, Toolkit::Control::SIGNAL_TAPPED,        &Internal::Control::DoConnectSignal );
87 SignalConnectorType SIGNAL_CONNECTOR_3( CONTROL_TYPE, Toolkit::Control::SIGNAL_PANNED,        &Internal::Control::DoConnectSignal );
88 SignalConnectorType SIGNAL_CONNECTOR_4( CONTROL_TYPE, Toolkit::Control::SIGNAL_PINCHED,       &Internal::Control::DoConnectSignal );
89 SignalConnectorType SIGNAL_CONNECTOR_5( CONTROL_TYPE, Toolkit::Control::SIGNAL_LONG_PRESSED,  &Internal::Control::DoConnectSignal );
90
91 /**
92  * Structure which holds information about the background of a control
93  */
94 struct Background
95 {
96   Actor actor;   ///< Either a MeshActor or an ImageActor
97   Vector4 color; ///< The color of the actor.
98
99   /**
100    * Constructor
101    */
102   Background()
103   : actor(),
104     color( Color::WHITE )
105   {
106   }
107 };
108
109 /**
110  * Helper function to calculate a dimension given the policy of that dimension; the minimum &
111  * maximum values that dimension can be; and the allocated value for that dimension.
112  *
113  * @param[in]  policy     The size policy for that dimension.
114  * @param[in]  minimum    The minimum value that dimension can be.
115  * @param[in]  maximum    The maximum value that dimension can be.
116  * @param[in]  allocated  The value allocated for that dimension.
117  *
118  * @return The value that the dimension should be.
119  *
120  * @note This does not handle Control::Fixed policy.
121  */
122 float Calculate( Control::SizePolicy policy, float minimum, float maximum, float allocated )
123 {
124   float size( allocated );
125
126   switch( policy )
127   {
128     case Control::Fixed:
129     {
130       // Use allocated value
131       break;
132     }
133
134     case Control::Minimum:
135     {
136       // Size is always at least the minimum.
137       size = std::max( allocated, minimum );
138       break;
139     }
140
141     case Control::Maximum:
142     {
143       // Size can grow but up to a maximum value.
144       size = std::min( allocated, maximum );
145       break;
146     }
147
148     case Control::Range:
149     {
150       // Size is at least the minimum and can grow up to the maximum
151       size = std::max( size, minimum );
152       size = std::min( size, maximum );
153      break;
154     }
155
156     case Control::Flexible:
157     {
158       // Size grows or shrinks with no limits.
159       size = allocated;
160       break;
161     }
162
163     default:
164     {
165       DALI_ASSERT_DEBUG( false && "This function was not intended to be used by any other policy." );
166       break;
167     }
168   }
169
170   return size;
171 }
172
173 /**
174  * Creates a white coloured Mesh.
175  */
176 Mesh CreateMesh()
177 {
178   Vector3 white( Color::WHITE );
179
180   MeshData meshData;
181
182   // Create vertices with a white color (actual color is set by actor color)
183   MeshData::VertexContainer vertices(4);
184   vertices[ 0 ] = MeshData::Vertex( Vector3( -0.5f, -0.5f, 0.0f ), Vector2::ZERO, white );
185   vertices[ 1 ] = MeshData::Vertex( Vector3(  0.5f, -0.5f, 0.0f ), Vector2::ZERO, white );
186   vertices[ 2 ] = MeshData::Vertex( Vector3( -0.5f,  0.5f, 0.0f ), Vector2::ZERO, white );
187   vertices[ 3 ] = MeshData::Vertex( Vector3(  0.5f,  0.5f, 0.0f ), Vector2::ZERO, white );
188
189   // Specify all the faces
190   MeshData::FaceIndices faces;
191   faces.reserve( 6 ); // 2 triangles in Quad
192   faces.push_back( 0 ); faces.push_back( 3 ); faces.push_back( 1 );
193   faces.push_back( 0 ); faces.push_back( 2 ); faces.push_back( 3 );
194
195   // Create the mesh data from the vertices and faces
196   meshData.SetMaterial( Material::New( "ControlMaterial" ) );
197   meshData.SetVertices( vertices );
198   meshData.SetFaceIndices( faces );
199   meshData.SetHasColor( true );
200
201   return Mesh::New( meshData );
202 }
203
204 /**
205  * Sets all the required properties for the background actor.
206  *
207  * @param[in]  actor              The actor to set the properties on.
208  * @param[in]  constrainingIndex  The property index to constrain the parent's size on.
209  * @param[in]  color              The required color of the actor.
210  */
211 void SetupBackgroundActor( Actor actor, Property::Index constrainingIndex, const Vector4& color )
212 {
213   actor.SetColor( color );
214   actor.SetPositionInheritanceMode( USE_PARENT_POSITION_PLUS_LOCAL_POSITION );
215   actor.SetColorMode( USE_OWN_MULTIPLY_PARENT_COLOR );
216   actor.SetZ( BACKGROUND_ACTOR_Z_POSITION );
217
218   Constraint constraint = Constraint::New<Vector3>( constrainingIndex,
219                                                     ParentSource( Actor::SIZE ),
220                                                     EqualToConstraint() );
221   actor.ApplyConstraint( constraint );
222 }
223
224 } // unnamed namespace
225
226 namespace Internal
227 {
228
229 class Control::Impl : public ConnectionTracker
230 {
231 public:
232
233   /**
234    * Size indices for mMinMaxSize array
235    */
236   enum
237   {
238     MIN_SIZE_INDEX = 0,
239     MAX_SIZE_INDEX = 1
240   };
241
242 public:
243   // Construction & Destruction
244   Impl(Control& controlImpl)
245   : mControlImpl( controlImpl ),
246     mBackground( NULL ),
247     mStartingPinchScale( NULL ),
248     mKeyEventSignalV2(),
249     mPinchGestureDetector(),
250     mPanGestureDetector(),
251     mTapGestureDetector(),
252     mLongPressGestureDetector(),
253     mCurrentSize(),
254     mNaturalSize(),
255     mWidthPolicy( Toolkit::Control::Fixed ),
256     mHeightPolicy( Toolkit::Control::Fixed ),
257     mFlags( Control::CONTROL_BEHAVIOUR_NONE ),
258     mInsideRelayout( false ),
259     mIsKeyboardNavigationSupported( false ),
260     mIsKeyboardFocusGroup( false ),
261     mInitialized( false )
262   {
263   }
264
265   ~Impl()
266   {
267     // All gesture detectors will be destroyed so no need to disconnect.
268     delete mBackground;
269     delete mStartingPinchScale;
270   }
271
272   // Gesture Detection Methods
273
274   void PinchDetected(Actor actor, const PinchGesture& pinch)
275   {
276     mControlImpl.OnPinch(pinch);
277   }
278
279   void PanDetected(Actor actor, const PanGesture& pan)
280   {
281     mControlImpl.OnPan(pan);
282   }
283
284   void TapDetected(Actor actor, const TapGesture& tap)
285   {
286     mControlImpl.OnTap(tap);
287   }
288
289   void LongPressDetected(Actor actor, const LongPressGesture& longPress)
290   {
291     mControlImpl.OnLongPress(longPress);
292   }
293
294   // Background Methods
295
296   /**
297    * Only creates an instance of the background if we actually use it.
298    * @return A reference to the Background structure.
299    */
300   Background& GetBackground()
301   {
302     if ( !mBackground )
303     {
304       mBackground = new Background;
305     }
306     return *mBackground;
307   }
308
309   // Properties
310
311   /**
312    * Called when a property of an object of this type is set.
313    * @param[in] object The object whose property is set.
314    * @param[in] index The property index.
315    * @param[in] value The new property value.
316    */
317   static void SetProperty( BaseObject* object, Property::Index index, const Property::Value& value )
318   {
319     Toolkit::Control control = Toolkit::Control::DownCast( BaseHandle( object ) );
320
321     if ( control )
322     {
323       Control& controlImpl( control.GetImplementation() );
324
325       switch ( index )
326       {
327         case Toolkit::Control::PROPERTY_BACKGROUND_COLOR:
328         {
329           controlImpl.SetBackgroundColor( value.Get< Vector4 >() );
330           break;
331         }
332
333         case Toolkit::Control::PROPERTY_BACKGROUND:
334         {
335           if ( value.HasKey( "image" ) )
336           {
337             Property::Map imageMap = value.GetValue( "image" ).Get< Property::Map >();
338             Image image = Scripting::NewImage( imageMap );
339
340             if ( image )
341             {
342               controlImpl.SetBackground( image );
343             }
344           }
345           else if ( value.Get< Property::Map >().Empty() )
346           {
347             // An empty map means the background is no longer required
348             controlImpl.ClearBackground();
349           }
350           break;
351         }
352
353         case Toolkit::Control::PROPERTY_WIDTH_POLICY:
354         {
355           controlImpl.mImpl->mWidthPolicy = Scripting::GetEnumeration< Toolkit::Control::SizePolicy >( value.Get< std::string >(), SIZE_POLICY_STRING_TABLE, SIZE_POLICY_STRING_TABLE_COUNT );
356           break;
357         }
358
359         case Toolkit::Control::PROPERTY_HEIGHT_POLICY:
360         {
361           controlImpl.mImpl->mHeightPolicy = Scripting::GetEnumeration< Toolkit::Control::SizePolicy >( value.Get< std::string >(), SIZE_POLICY_STRING_TABLE, SIZE_POLICY_STRING_TABLE_COUNT );
362           break;
363         }
364
365         case Toolkit::Control::PROPERTY_MINIMUM_SIZE:
366         {
367           controlImpl.SetMinimumSize( value.Get< Vector3 >() );
368           break;
369         }
370
371         case Toolkit::Control::PROPERTY_MAXIMUM_SIZE:
372         {
373           controlImpl.SetMaximumSize( value.Get< Vector3 >() );
374           break;
375         }
376
377         case Toolkit::Control::PROPERTY_KEY_INPUT_FOCUS:
378         {
379           if ( value.Get< bool >() )
380           {
381             controlImpl.SetKeyInputFocus();
382           }
383           else
384           {
385             controlImpl.ClearKeyInputFocus();
386           }
387           break;
388         }
389       }
390     }
391   }
392
393   /**
394    * Called to retrieve a property of an object of this type.
395    * @param[in] object The object whose property is to be retrieved.
396    * @param[in] index The property index.
397    * @return The current value of the property.
398    */
399   static Property::Value GetProperty( BaseObject* object, Property::Index index )
400   {
401     Property::Value value;
402
403     Toolkit::Control control = Toolkit::Control::DownCast( BaseHandle( object ) );
404
405     if ( control )
406     {
407       Control& controlImpl( control.GetImplementation() );
408
409       switch ( index )
410       {
411         case Toolkit::Control::PROPERTY_BACKGROUND_COLOR:
412         {
413           value = controlImpl.GetBackgroundColor();
414           break;
415         }
416
417         case Toolkit::Control::PROPERTY_BACKGROUND:
418         {
419           Property::Map map;
420
421           Actor actor = controlImpl.GetBackgroundActor();
422           if ( actor )
423           {
424             ImageActor imageActor = ImageActor::DownCast( actor );
425             if ( imageActor )
426             {
427               Image image = imageActor.GetImage();
428               Property::Map imageMap;
429               Scripting::CreatePropertyMap( image, imageMap );
430               map[ "image" ] = imageMap;
431             }
432           }
433
434           value = map;
435           break;
436         }
437
438         case Toolkit::Control::PROPERTY_WIDTH_POLICY:
439         {
440           value = std::string( Scripting::GetEnumerationName< Toolkit::Control::SizePolicy >( controlImpl.mImpl->mWidthPolicy, SIZE_POLICY_STRING_TABLE, SIZE_POLICY_STRING_TABLE_COUNT ) );
441           break;
442         }
443
444         case Toolkit::Control::PROPERTY_HEIGHT_POLICY:
445         {
446           value = std::string( Scripting::GetEnumerationName< Toolkit::Control::SizePolicy >( controlImpl.mImpl->mHeightPolicy, SIZE_POLICY_STRING_TABLE, SIZE_POLICY_STRING_TABLE_COUNT ) );
447           break;
448         }
449
450         case Toolkit::Control::PROPERTY_MINIMUM_SIZE:
451         {
452           value = controlImpl.mImpl->GetMinimumSize();
453           break;
454         }
455
456         case Toolkit::Control::PROPERTY_MAXIMUM_SIZE:
457         {
458           value = controlImpl.mImpl->GetMaximumSize();
459           break;
460         }
461
462         case Toolkit::Control::PROPERTY_KEY_INPUT_FOCUS:
463         {
464           value = controlImpl.HasKeyInputFocus();
465           break;
466         }
467       }
468     }
469
470     return value;
471   }
472
473   /**
474    * Helper to get minimum size
475    * @return minimum size
476    */
477   inline const Vector3& GetMinimumSize()
478   {
479     if( mMinMaxSize.Count() > MIN_SIZE_INDEX )
480     {
481       return mMinMaxSize[ MIN_SIZE_INDEX ];
482     }
483     else
484     {
485       // its not been allocated so its ZERO
486       return Vector3::ZERO;
487     }
488   }
489   /**
490    * Helper to Set minimum size
491    * @param size to set
492    */
493   inline void SetMinimumSize( const Vector3& size )
494   {
495     if( mMinMaxSize.Count() > MIN_SIZE_INDEX )
496     {
497       mMinMaxSize[ MIN_SIZE_INDEX ] = size;
498     }
499     else
500     {
501       // its not been allocated so push the new value there
502       mMinMaxSize.PushBack( size );
503     }
504   }
505
506   /**
507    * Helper to get maximum size
508    * @return maximum size
509    */
510   inline const Vector3& GetMaximumSize()
511   {
512     if( mMinMaxSize.Count() > MAX_SIZE_INDEX )
513     {
514       return mMinMaxSize[ MAX_SIZE_INDEX ];
515     }
516     else
517     {
518       // its not been allocated so its MAX_SIZE
519       return MAX_SIZE;
520     }
521   }
522
523   /**
524    * Helper to Set minimum size
525    * @param size to set
526    */
527   inline void SetMaximumSize( const Vector3& size )
528   {
529     if( mMinMaxSize.Count() > MAX_SIZE_INDEX )
530     {
531       mMinMaxSize[ MAX_SIZE_INDEX ] = size;
532     }
533     else if( mMinMaxSize.Count() > MIN_SIZE_INDEX )
534     {
535       // max has not been allocated, but min has
536       mMinMaxSize.PushBack( size );
537     }
538     else
539     {
540       // min and max both unallocated so allocate both
541       mMinMaxSize.Resize( 2u ); // this will reserve and default construct two Vector3s
542       mMinMaxSize[ MAX_SIZE_INDEX ] = size;
543     }
544   }
545
546   // Data
547
548   Control& mControlImpl;
549   Background* mBackground;           ///< Only create the background if we use it
550   Vector3* mStartingPinchScale;      ///< The scale when a pinch gesture starts, TODO: consider removing this
551   Toolkit::Control::KeyEventSignalV2 mKeyEventSignalV2;
552
553   // Gesture Detection
554   PinchGestureDetector mPinchGestureDetector;
555   PanGestureDetector mPanGestureDetector;
556   TapGestureDetector mTapGestureDetector;
557   LongPressGestureDetector mLongPressGestureDetector;
558   // @todo change all these to Vector2 when we have a chance to sanitize the public API as well
559   Vector3 mCurrentSize; ///< Stores the current control's size, this is the negotiated size
560   Vector3 mNaturalSize; ///< Stores the size set through the Actor's API. This is size the actor wants to be. Useful when reset to the initial size is needed.
561   Dali::Vector< Vector3 > mMinMaxSize; ///< Stores the minimum and maximum size if they are set
562
563   Toolkit::Control::SizePolicy mWidthPolicy :3;  ///< Stores the width policy. 3 bits covers 8 values
564   Toolkit::Control::SizePolicy mHeightPolicy :3; ///< Stores the height policy. 3 bits covers 8 values
565   ControlBehaviour mFlags :6;             ///< Flags passed in from constructor. Need to increase this size when new enums are added
566   bool mInsideRelayout:1;                 ///< Detect when were in Relayout
567   bool mIsKeyboardNavigationSupported:1;  ///< Stores whether keyboard navigation is supported by the control.
568   bool mIsKeyboardFocusGroup:1;           ///< Stores whether the control is a focus group.
569   bool mInitialized:1;
570
571   // Properties - these need to be members of Internal::Control::Impl as they need to functions within this class.
572   static PropertyRegistration PROPERTY_1;
573   static PropertyRegistration PROPERTY_2;
574   static PropertyRegistration PROPERTY_3;
575   static PropertyRegistration PROPERTY_4;
576   static PropertyRegistration PROPERTY_5;
577   static PropertyRegistration PROPERTY_6;
578   static PropertyRegistration PROPERTY_7;
579 };
580
581 PropertyRegistration Control::Impl::PROPERTY_1( CONTROL_TYPE, "background-color", Toolkit::Control::PROPERTY_BACKGROUND_COLOR, Property::VECTOR4, &Control::Impl::SetProperty, &Control::Impl::GetProperty );
582 PropertyRegistration Control::Impl::PROPERTY_2( CONTROL_TYPE, "background",       Toolkit::Control::PROPERTY_BACKGROUND,       Property::MAP,     &Control::Impl::SetProperty, &Control::Impl::GetProperty );
583 PropertyRegistration Control::Impl::PROPERTY_3( CONTROL_TYPE, "width-policy",     Toolkit::Control::PROPERTY_WIDTH_POLICY,     Property::STRING,  &Control::Impl::SetProperty, &Control::Impl::GetProperty );
584 PropertyRegistration Control::Impl::PROPERTY_4( CONTROL_TYPE, "height-policy",    Toolkit::Control::PROPERTY_HEIGHT_POLICY,    Property::STRING,  &Control::Impl::SetProperty, &Control::Impl::GetProperty );
585 PropertyRegistration Control::Impl::PROPERTY_5( CONTROL_TYPE, "minimum-size",     Toolkit::Control::PROPERTY_MINIMUM_SIZE,     Property::VECTOR3, &Control::Impl::SetProperty, &Control::Impl::GetProperty );
586 PropertyRegistration Control::Impl::PROPERTY_6( CONTROL_TYPE, "maximum-size",     Toolkit::Control::PROPERTY_MAXIMUM_SIZE,     Property::VECTOR3, &Control::Impl::SetProperty, &Control::Impl::GetProperty );
587 PropertyRegistration Control::Impl::PROPERTY_7( CONTROL_TYPE, "key-input-focus",  Toolkit::Control::PROPERTY_KEY_INPUT_FOCUS,  Property::BOOLEAN, &Control::Impl::SetProperty, &Control::Impl::GetProperty );
588
589 Toolkit::Control Control::New()
590 {
591   // Create the implementation, temporarily owned on stack
592   IntrusivePtr<Control> controlImpl = new Control( CONTROL_BEHAVIOUR_NONE );
593
594   // Pass ownership to handle
595   Toolkit::Control handle( *controlImpl );
596
597   // Second-phase init of the implementation
598   // This can only be done after the CustomActor connection has been made...
599   controlImpl->Initialize();
600
601   return handle;
602 }
603
604 Control::~Control()
605 {
606   delete mImpl;
607 }
608
609 void Control::SetSizePolicy( Toolkit::Control::SizePolicy widthPolicy, Toolkit::Control::SizePolicy heightPolicy )
610 {
611   bool relayoutRequest( false );
612
613   if ( ( mImpl->mWidthPolicy != widthPolicy ) || ( mImpl->mHeightPolicy != heightPolicy ) )
614   {
615     relayoutRequest = true;
616   }
617
618   mImpl->mWidthPolicy = widthPolicy;
619   mImpl->mHeightPolicy = heightPolicy;
620
621   // Ensure RelayoutRequest is called AFTER new policies have been set.
622   if ( relayoutRequest )
623   {
624     RelayoutRequest();
625   }
626 }
627
628 void Control::GetSizePolicy( Toolkit::Control::SizePolicy& widthPolicy, Toolkit::Control::SizePolicy& heightPolicy ) const
629 {
630   widthPolicy = mImpl->mWidthPolicy;
631   heightPolicy = mImpl->mHeightPolicy;
632 }
633
634 void Control::SetMinimumSize( const Vector3& size )
635 {
636   const Vector3& minSize = mImpl->GetMinimumSize();
637   if ( fabsf( minSize.width - size.width ) > Math::MACHINE_EPSILON_1000 ||
638        fabsf( minSize.height - size.height ) > Math::MACHINE_EPSILON_1000 )
639   {
640     mImpl->SetMinimumSize( size );
641
642     // Only relayout if our control is using the minimum or range policy.
643     if ( ( mImpl->mHeightPolicy == Toolkit::Control::Minimum ) || ( mImpl->mWidthPolicy  == Toolkit::Control::Minimum ) ||
644          ( mImpl->mHeightPolicy == Toolkit::Control::Range   ) || ( mImpl->mWidthPolicy  == Toolkit::Control::Range   ) )
645     {
646       RelayoutRequest();
647     }
648   }
649 }
650
651 const Vector3& Control::GetMinimumSize() const
652 {
653   return mImpl->GetMinimumSize();
654 }
655
656 void Control::SetMaximumSize( const Vector3& size )
657 {
658   const Vector3& maxSize = mImpl->GetMaximumSize();
659   if ( fabsf( maxSize.width - size.width ) > Math::MACHINE_EPSILON_1000 ||
660        fabsf( maxSize.height - size.height ) > Math::MACHINE_EPSILON_1000 )
661   {
662     mImpl->SetMaximumSize( size );
663
664     // Only relayout if our control is using the maximum or range policy.
665     if ( ( mImpl->mHeightPolicy == Toolkit::Control::Maximum ) || ( mImpl->mWidthPolicy  == Toolkit::Control::Maximum ) ||
666          ( mImpl->mHeightPolicy == Toolkit::Control::Range   ) || ( mImpl->mWidthPolicy  == Toolkit::Control::Range   ) )
667     {
668       RelayoutRequest();
669     }
670   }
671 }
672
673 const Vector3& Control::GetMaximumSize() const
674 {
675   return mImpl->GetMaximumSize();
676 }
677
678 Vector3 Control::GetNaturalSize()
679 {
680   // could be overridden in derived classes.
681   return mImpl->mNaturalSize;
682 }
683
684 float Control::GetHeightForWidth( float width )
685 {
686   // could be overridden in derived classes.
687   float height( 0.0f );
688   if ( mImpl->mNaturalSize.width > 0.0f )
689   {
690     height = mImpl->mNaturalSize.height * width / mImpl->mNaturalSize.width;
691   }
692   return height;
693 }
694
695 float Control::GetWidthForHeight( float height )
696 {
697   // could be overridden in derived classes.
698   float width( 0.0f );
699   if ( mImpl->mNaturalSize.height > 0.0f )
700   {
701     width = mImpl->mNaturalSize.width * height / mImpl->mNaturalSize.height;
702   }
703   return width;
704 }
705
706 const Vector3& Control::GetControlSize() const
707 {
708   return mImpl->mCurrentSize;
709 }
710
711 const Vector3& Control::GetSizeSet() const
712 {
713   return mImpl->mNaturalSize;
714 }
715
716 void Control::SetKeyInputFocus()
717 {
718   if( Self().OnStage() )
719   {
720     Toolkit::KeyInputFocusManager::Get().SetFocus(Toolkit::Control::DownCast(Self()));
721   }
722 }
723
724 bool Control::HasKeyInputFocus()
725 {
726   bool result = false;
727   if( Self().OnStage() )
728   {
729     result = Toolkit::KeyInputFocusManager::Get().IsKeyboardListener(Toolkit::Control::DownCast(Self()));
730   }
731   return result;
732 }
733
734 void Control::ClearKeyInputFocus()
735 {
736   if( Self().OnStage() )
737   {
738     Toolkit::KeyInputFocusManager::Get().RemoveFocus(Toolkit::Control::DownCast(Self()));
739   }
740 }
741
742 PinchGestureDetector Control::GetPinchGestureDetector() const
743 {
744   return mImpl->mPinchGestureDetector;
745 }
746
747 PanGestureDetector Control::GetPanGestureDetector() const
748 {
749   return mImpl->mPanGestureDetector;
750 }
751
752 TapGestureDetector Control::GetTapGestureDetector() const
753 {
754   return mImpl->mTapGestureDetector;
755 }
756
757 LongPressGestureDetector Control::GetLongPressGestureDetector() const
758 {
759   return mImpl->mLongPressGestureDetector;
760 }
761
762 void Control::SetBackgroundColor( const Vector4& color )
763 {
764   Background& background( mImpl->GetBackground() );
765
766   if ( background.actor )
767   {
768     // Just set the actor color
769     background.actor.SetColor( color );
770   }
771   else
772   {
773     // Create Mesh Actor
774     MeshActor meshActor = MeshActor::New( CreateMesh() );
775
776     meshActor.SetAffectedByLighting( false );
777     SetupBackgroundActor( meshActor, Actor::SCALE, color );
778
779     // Set the background actor before adding so that we do not inform deriving classes
780     background.actor = meshActor;
781     Self().Add( meshActor );
782   }
783
784   background.color = color;
785 }
786
787 Vector4 Control::GetBackgroundColor() const
788 {
789   if ( mImpl->mBackground )
790   {
791     return mImpl->mBackground->color;
792   }
793   return Color::TRANSPARENT;
794 }
795
796 void Control::SetBackground( Image image )
797 {
798   Background& background( mImpl->GetBackground() );
799
800   if ( background.actor )
801   {
802     // Remove Current actor, unset AFTER removal so that we do not inform deriving classes
803     Self().Remove( background.actor );
804     background.actor.Reset();
805   }
806
807   ImageActor imageActor = ImageActor::New( image );
808   SetupBackgroundActor( imageActor, Actor::SIZE, background.color );
809
810   // Set the background actor before adding so that we do not inform derived classes
811   background.actor = imageActor;
812   Self().Add( imageActor );
813 }
814
815 void Control::ClearBackground()
816 {
817   if ( mImpl->mBackground )
818   {
819     Background& background( mImpl->GetBackground() );
820     Self().Remove( background.actor );
821
822     delete mImpl->mBackground;
823     mImpl->mBackground = NULL;
824   }
825 }
826
827 Actor Control::GetBackgroundActor() const
828 {
829   if ( mImpl->mBackground )
830   {
831     return mImpl->mBackground->actor;
832   }
833
834   return Actor();
835 }
836
837 void Control::SetKeyboardNavigationSupport(bool isSupported)
838 {
839   mImpl->mIsKeyboardNavigationSupported = isSupported;
840 }
841
842 bool Control::IsKeyboardNavigationSupported()
843 {
844   return mImpl->mIsKeyboardNavigationSupported;
845 }
846
847 void Control::Activate()
848 {
849   // Inform deriving classes
850   OnActivated();
851 }
852
853 bool Control::OnAccessibilityPan(PanGesture gesture)
854 {
855   return false; // Accessibility pan gesture is not handled by default
856 }
857
858 bool Control::OnAccessibilityTouch(const TouchEvent& touchEvent)
859 {
860   return false; // Accessibility touch event is not handled by default
861 }
862
863 bool Control::OnAccessibilityValueChange(bool isIncrease)
864 {
865   return false; // Accessibility value change action is not handled by default
866 }
867
868 void Control::NegotiateSize( Vector2 allocatedSize, ActorSizeContainer& container )
869 {
870   Vector2 size;
871
872   if ( mImpl->mWidthPolicy == Toolkit::Control::Fixed )
873   {
874     if ( mImpl->mHeightPolicy == Toolkit::Control::Fixed )
875     {
876       // If a control says it has a fixed size, then use the size set by the application / control.
877       Vector2 setSize( mImpl->mNaturalSize );
878       if ( setSize != Vector2::ZERO )
879       {
880         size = setSize;
881
882         // Policy is set to Fixed, so if the application / control has not set one of the dimensions,
883         // then we should use the natural size of the control rather than the full allocation.
884         if ( EqualsZero( size.width ) )
885         {
886           size.width = GetWidthForHeight( size.height );
887         }
888         else if ( EqualsZero( size.height ) )
889         {
890           size.height = GetHeightForWidth( size.width );
891         }
892       }
893       else
894       {
895         // If that is not set then set the size to the control's natural size
896         size = Vector2( GetNaturalSize() );
897       }
898     }
899     else
900     {
901       // Width is fixed so if the application / control has set it, then use that.
902       if ( !EqualsZero( mImpl->mNaturalSize.width ) )
903       {
904         size.width = mImpl->mNaturalSize.width;
905       }
906       else
907       {
908         // Otherwise, set the width to what has been allocated.
909         size.width = allocatedSize.width;
910       }
911
912       // Height is flexible so ask control what the height should be for our width.
913       size.height = GetHeightForWidth( size.width );
914
915       // Ensure height is within our policy rules
916       size.height = Calculate( mImpl->mHeightPolicy, GetMinimumSize().height, GetMaximumSize().height, size.height );
917     }
918   }
919   else
920   {
921     if ( mImpl->mHeightPolicy == Toolkit::Control::Fixed )
922     {
923       // Height is fixed so if the application / control has set it, then use that.
924       if ( !EqualsZero( mImpl->mNaturalSize.height ) )
925       {
926         size.height = mImpl->mNaturalSize.height;
927       }
928       else
929       {
930         // Otherwise, set the height to what has been allocated.
931         size.height = allocatedSize.height;
932       }
933
934       // Width is flexible so ask control what the width should be for our height.
935       size.width = GetWidthForHeight( size.height );
936
937       // Ensure width is within our policy rules
938       size.width = Calculate( mImpl->mWidthPolicy, mImpl->GetMinimumSize().width, mImpl->GetMaximumSize().width, size.width );
939     }
940     else
941     {
942       // Width and height are BOTH flexible.
943       // Calculate the width and height using the policy rules.
944       size.width = Calculate( mImpl->mWidthPolicy, mImpl->GetMinimumSize().width, mImpl->GetMaximumSize().width, allocatedSize.width );
945       size.height = Calculate( mImpl->mHeightPolicy, mImpl->GetMinimumSize().height, mImpl->GetMaximumSize().height, allocatedSize.height );
946     }
947   }
948
949   // If the width has not been set, then set to the allocated width.
950   // Also if the width set is greater than the allocated, then set to allocated (no exceed support).
951   if ( EqualsZero( size.width ) || ( size.width > allocatedSize.width ) )
952   {
953     size.width = allocatedSize.width;
954   }
955
956   // If the height has not been set, then set to the allocated height.
957   // Also if the height set is greater than the allocated, then set to allocated (no exceed support).
958   if ( EqualsZero( size.height ) || ( size.height > allocatedSize.height ) )
959   {
960     size.height = allocatedSize.height;
961   }
962
963   DALI_LOG_INFO( gLogFilter, Debug::Verbose,
964                  "%p: Natural: [%.2f, %.2f] Allocated: [%.2f, %.2f] Set: [%.2f, %.2f]\n",
965                  Self().GetObjectPtr(),
966                  GetNaturalSize().x, GetNaturalSize().y,
967                  allocatedSize.x, allocatedSize.y,
968                  size.x, size.y );
969
970   Relayout( size, container );
971 }
972
973 void Control::SetAsKeyboardFocusGroup(bool isFocusGroup)
974 {
975   mImpl->mIsKeyboardFocusGroup = isFocusGroup;
976
977   // The following line will be removed when the deprecated API in KeyboardFocusManager is deleted
978   Toolkit::KeyboardFocusManager::Get().SetAsFocusGroup(Self(), isFocusGroup);
979 }
980
981 bool Control::IsKeyboardFocusGroup()
982 {
983   return Toolkit::KeyboardFocusManager::Get().IsFocusGroup(Self());
984 }
985
986 Actor Control::GetNextKeyboardFocusableActor(Actor currentFocusedActor, Toolkit::Control::KeyboardFocusNavigationDirection direction, bool loopEnabled)
987 {
988   return Actor();
989 }
990
991 void Control::OnKeyboardFocusChangeCommitted(Actor commitedFocusableActor)
992 {
993 }
994
995 bool Control::DoAction(BaseObject* object, const std::string& actionName, const PropertyValueContainer& attributes)
996 {
997   bool ret = false;
998
999   if( object && (actionName == Toolkit::Control::ACTION_CONTROL_ACTIVATED) )
1000   {
1001     Toolkit::Control control = Toolkit::Control::DownCast( BaseHandle( object ) );
1002     if( control )
1003     {
1004       // if cast succeeds there is an implementation so no need to check
1005       control.GetImplementation().OnActivated();
1006     }
1007   }
1008
1009   return ret;
1010 }
1011
1012 bool Control::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
1013 {
1014   Dali::BaseHandle handle( object );
1015
1016   bool connected( false );
1017   Toolkit::Control control = Toolkit::Control::DownCast(handle);
1018   if ( control )
1019   {
1020     Control& controlImpl( control.GetImplementation() );
1021     connected = true;
1022
1023     if ( Toolkit::Control::SIGNAL_KEY_EVENT == signalName )
1024     {
1025       controlImpl.KeyEventSignal().Connect( tracker, functor );
1026     }
1027     else if( Toolkit::Control::SIGNAL_TAPPED == signalName )
1028     {
1029       controlImpl.EnableGestureDetection( Gesture::Tap );
1030       controlImpl.GetTapGestureDetector().DetectedSignal().Connect( tracker, functor );
1031     }
1032     else if( Toolkit::Control::SIGNAL_PANNED == signalName )
1033     {
1034       controlImpl.EnableGestureDetection( Gesture::Pan );
1035       controlImpl.GetPanGestureDetector().DetectedSignal().Connect( tracker, functor );
1036     }
1037     else if( Toolkit::Control::SIGNAL_PINCHED == signalName )
1038     {
1039       controlImpl.EnableGestureDetection( Gesture::Pinch );
1040       controlImpl.GetPinchGestureDetector().DetectedSignal().Connect( tracker, functor );
1041     }
1042     else if( Toolkit::Control::SIGNAL_LONG_PRESSED == signalName )
1043     {
1044       controlImpl.EnableGestureDetection( Gesture::LongPress );
1045       controlImpl.GetLongPressGestureDetector().DetectedSignal().Connect( tracker, functor );
1046     }
1047     else
1048     {
1049       // signalName does not match any signal
1050       connected = false;
1051     }
1052   }
1053   return connected;
1054 }
1055
1056 Toolkit::Control::KeyEventSignalV2& Control::KeyEventSignal()
1057 {
1058   return mImpl->mKeyEventSignalV2;
1059 }
1060
1061 bool Control::EmitKeyEventSignal( const KeyEvent& event )
1062 {
1063   // Guard against destruction during signal emission
1064   Dali::Toolkit::Control handle( GetOwner() );
1065
1066   bool consumed = false;
1067
1068   // signals are allocated dynamically when someone connects
1069   if ( !mImpl->mKeyEventSignalV2.Empty() )
1070   {
1071     consumed = mImpl->mKeyEventSignalV2.Emit( handle, event );
1072   }
1073
1074   if (!consumed)
1075   {
1076     // Notification for derived classes
1077     consumed = OnKeyEvent(event);
1078   }
1079
1080   return consumed;
1081 }
1082
1083 Control::Control( ControlBehaviour behaviourFlags )
1084 : CustomActorImpl( behaviourFlags & REQUIRES_TOUCH_EVENTS ),
1085   mImpl(new Impl(*this))
1086 {
1087   mImpl->mFlags = behaviourFlags;
1088 }
1089
1090 void Control::Initialize()
1091 {
1092
1093   // Calling deriving classes
1094   OnInitialize();
1095
1096   if( mImpl->mFlags & REQUIRES_STYLE_CHANGE_SIGNALS )
1097   {
1098     Toolkit::StyleManager styleManager = Toolkit::StyleManager::Get();
1099
1100     // Register for style changes
1101     styleManager.StyleChangeSignal().Connect( this, &Control::DoStyleChange );
1102
1103     // SetTheme
1104     GetImpl( styleManager ).ApplyThemeStyle( Toolkit::Control( GetOwner() ) );
1105   }
1106
1107   SetRequiresHoverEvents(mImpl->mFlags & REQUIRES_HOVER_EVENTS);
1108   SetRequiresMouseWheelEvents(mImpl->mFlags & REQUIRES_MOUSE_WHEEL_EVENTS);
1109
1110   mImpl->mInitialized = true;
1111 }
1112
1113 void Control::EnableGestureDetection(Gesture::Type type)
1114 {
1115   if ( (type & Gesture::Pinch) && !mImpl->mPinchGestureDetector )
1116   {
1117     mImpl->mPinchGestureDetector = PinchGestureDetector::New();
1118     mImpl->mPinchGestureDetector.DetectedSignal().Connect(mImpl, &Impl::PinchDetected);
1119     mImpl->mPinchGestureDetector.Attach(Self());
1120   }
1121
1122   if ( (type & Gesture::Pan) && !mImpl->mPanGestureDetector )
1123   {
1124     mImpl->mPanGestureDetector = PanGestureDetector::New();
1125     mImpl->mPanGestureDetector.DetectedSignal().Connect(mImpl, &Impl::PanDetected);
1126     mImpl->mPanGestureDetector.Attach(Self());
1127   }
1128
1129   if ( (type & Gesture::Tap) && !mImpl->mTapGestureDetector )
1130   {
1131     mImpl->mTapGestureDetector = TapGestureDetector::New();
1132     mImpl->mTapGestureDetector.DetectedSignal().Connect(mImpl, &Impl::TapDetected);
1133     mImpl->mTapGestureDetector.Attach(Self());
1134   }
1135
1136   if ( (type & Gesture::LongPress) && !mImpl->mLongPressGestureDetector )
1137   {
1138     mImpl->mLongPressGestureDetector = LongPressGestureDetector::New();
1139     mImpl->mLongPressGestureDetector.DetectedSignal().Connect(mImpl, &Impl::LongPressDetected);
1140     mImpl->mLongPressGestureDetector.Attach(Self());
1141   }
1142 }
1143
1144 void Control::DisableGestureDetection(Gesture::Type type)
1145 {
1146   if ( (type & Gesture::Pinch) && mImpl->mPinchGestureDetector )
1147   {
1148     mImpl->mPinchGestureDetector.Detach(Self());
1149     mImpl->mPinchGestureDetector.Reset();
1150   }
1151
1152   if ( (type & Gesture::Pan) && mImpl->mPanGestureDetector )
1153   {
1154     mImpl->mPanGestureDetector.Detach(Self());
1155     mImpl->mPanGestureDetector.Reset();
1156   }
1157
1158   if ( (type & Gesture::Tap) && mImpl->mTapGestureDetector )
1159   {
1160     mImpl->mTapGestureDetector.Detach(Self());
1161     mImpl->mTapGestureDetector.Reset();
1162   }
1163
1164   if ( (type & Gesture::LongPress) && mImpl->mLongPressGestureDetector)
1165   {
1166     mImpl->mLongPressGestureDetector.Detach(Self());
1167     mImpl->mLongPressGestureDetector.Reset();
1168   }
1169 }
1170
1171 void Control::RelayoutRequest()
1172 {
1173   // unfortunate double negative but thats to guarantee new controls get size negotiation
1174   // by default and have to "opt-out" if they dont want it
1175   if( !(mImpl->mFlags & NO_SIZE_NEGOTIATION) )
1176   {
1177     Internal::RelayoutController::Request();
1178   }
1179 }
1180
1181 void Control::Relayout( Actor actor, Vector2 size, ActorSizeContainer& container )
1182 {
1183   if ( actor )
1184   {
1185     Toolkit::Control control( Toolkit::Control::DownCast( actor ) );
1186     if( control )
1187     {
1188       control.GetImplementation().NegotiateSize( size, container );
1189     }
1190     else
1191     {
1192       container.push_back( ActorSizePair( actor, size ) );
1193     }
1194   }
1195 }
1196
1197 void Control::OnInitialize()
1198 {
1199 }
1200
1201 void Control::OnActivated()
1202 {
1203 }
1204
1205 void Control::OnThemeChange( Toolkit::StyleManager styleManager )
1206 {
1207   GetImpl( styleManager ).ApplyThemeStyle( Toolkit::Control( GetOwner() ) );
1208 }
1209
1210 void Control::OnFontChange( bool defaultFontChange, bool defaultFontSizeChange )
1211 {
1212 }
1213
1214 void Control::OnPinch(const PinchGesture& pinch)
1215 {
1216   if( !( mImpl->mStartingPinchScale ) )
1217   {
1218     // lazy allocate
1219     mImpl->mStartingPinchScale = new Vector3;
1220   }
1221
1222   if( pinch.state == Gesture::Started )
1223   {
1224     *( mImpl->mStartingPinchScale ) = Self().GetCurrentScale();
1225   }
1226
1227   Self().SetScale( *( mImpl->mStartingPinchScale ) * pinch.scale );
1228 }
1229
1230 void Control::OnPan( const PanGesture& pan )
1231 {
1232 }
1233
1234 void Control::OnTap(const TapGesture& tap)
1235 {
1236 }
1237
1238 void Control::OnLongPress( const LongPressGesture& longPress )
1239 {
1240 }
1241
1242 void Control::OnControlStageConnection()
1243 {
1244 }
1245
1246 void Control::OnControlStageDisconnection()
1247 {
1248 }
1249
1250 void Control::OnControlChildAdd( Actor& child )
1251 {
1252 }
1253
1254 void Control::OnControlChildRemove( Actor& child )
1255 {
1256 }
1257
1258 void Control::OnControlSizeSet( const Vector3& size )
1259 {
1260 }
1261
1262 void Control::OnRelaidOut( Vector2 size, ActorSizeContainer& container )
1263 {
1264   unsigned int numChildren = Self().GetChildCount();
1265
1266   for( unsigned int i=0; i<numChildren; ++i )
1267   {
1268     container.push_back( ActorSizePair( Self().GetChildAt(i), size ) );
1269   }
1270 }
1271
1272 void Control::OnKeyInputFocusGained()
1273 {
1274   // Do Nothing
1275 }
1276
1277 void Control::OnKeyInputFocusLost()
1278 {
1279   // Do Nothing
1280 }
1281
1282 void Control::OnSizeAnimation(Animation& animation, const Vector3& targetSize)
1283 {
1284   // @todo consider animating negotiated child sizes to target size
1285 }
1286
1287 bool Control::OnTouchEvent(const TouchEvent& event)
1288 {
1289   return false; // Do not consume
1290 }
1291
1292 bool Control::OnHoverEvent(const HoverEvent& event)
1293 {
1294   return false; // Do not consume
1295 }
1296
1297 bool Control::OnKeyEvent(const KeyEvent& event)
1298 {
1299   return false; // Do not consume
1300 }
1301
1302 bool Control::OnMouseWheelEvent(const MouseWheelEvent& event)
1303 {
1304   return false; // Do not consume
1305 }
1306
1307 Actor Control::GetChildByAlias(const std::string& actorAlias)
1308 {
1309   return Actor();
1310 }
1311
1312 void Control::OnStageConnection()
1313 {
1314   RelayoutRequest();
1315
1316   // Notify derived classes.
1317   OnControlStageConnection();
1318 }
1319
1320 void Control::OnStageDisconnection()
1321 {
1322   // Notify derived classes
1323   OnControlStageDisconnection();
1324 }
1325
1326 void Control::OnChildAdd(Actor& child)
1327 {
1328   // If this is the background actor, then we do not want to relayout or inform deriving classes
1329   if ( mImpl->mBackground && ( child == mImpl->mBackground->actor ) )
1330   {
1331     return;
1332   }
1333
1334   // Request for relayout as we may need to position the new child and old ones
1335   RelayoutRequest();
1336
1337   // Notify derived classes.
1338   OnControlChildAdd( child );
1339 }
1340
1341 void Control::OnChildRemove(Actor& child)
1342 {
1343   // If this is the background actor, then we do not want to relayout or inform deriving classes
1344   if ( mImpl->mBackground && ( child == mImpl->mBackground->actor ) )
1345   {
1346     return;
1347   }
1348
1349   // Request for relayout as we may need to re-position the old child
1350   RelayoutRequest();
1351
1352   // Notify derived classes.
1353   OnControlChildRemove( child );
1354 }
1355
1356 void Control::OnSizeSet(const Vector3& targetSize)
1357 {
1358   if( ( !mImpl->mInsideRelayout ) && ( targetSize != mImpl->mNaturalSize ) )
1359   {
1360     // Only updates size if set through Actor's API
1361     mImpl->mNaturalSize = targetSize;
1362   }
1363
1364   if( targetSize != mImpl->mCurrentSize )
1365   {
1366     // Update control size.
1367     mImpl->mCurrentSize = targetSize;
1368
1369     // Notify derived classes.
1370     OnControlSizeSet( targetSize );
1371   }
1372 }
1373
1374 void Control::SignalConnected( SlotObserver* slotObserver, CallbackBase* callback )
1375 {
1376   mImpl->SignalConnected( slotObserver, callback );
1377 }
1378
1379 void Control::SignalDisconnected( SlotObserver* slotObserver, CallbackBase* callback )
1380 {
1381   mImpl->SignalDisconnected( slotObserver, callback );
1382 }
1383
1384 void Control::DoStyleChange( Toolkit::StyleManager styleManager, StyleChange change )
1385 {
1386   if( change.themeChange )
1387   {
1388     OnThemeChange( styleManager );
1389   }
1390   else if( change.defaultFontChange || change.defaultFontSizeChange )
1391   {
1392     OnFontChange( change.defaultFontChange, change.defaultFontSizeChange );
1393   }
1394 }
1395
1396 void Control::Relayout(Vector2 size, ActorSizeContainer& container)
1397 {
1398   // Avoids relayout again when OnSizeSet callback arrives.
1399   mImpl->mInsideRelayout = true;
1400   Self().SetSize( size );
1401   // @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
1402   mImpl->mInsideRelayout = false;
1403
1404   // Only relayout controls which requested to be relaid out.
1405   OnRelaidOut( size, container );
1406 }
1407
1408 } // namespace Internal
1409
1410 } // namespace Toolkit
1411
1412 } // namespace Dali