Merge "Add Visual descriptions to generate doxygen page" into devel/master
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / public-api / controls / control-impl.cpp
1 /*
2  * Copyright (c) 2017 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 <cstring> // for strcmp
23 #include <limits>
24 #include <stack>
25 #include <typeinfo>
26 #include <dali/public-api/animation/constraint.h>
27 #include <dali/public-api/animation/constraints.h>
28 #include <dali/public-api/object/type-registry.h>
29 #include <dali/public-api/object/type-registry-helper.h>
30 #include <dali/public-api/rendering/renderer.h>
31 #include <dali/public-api/size-negotiation/relayout-container.h>
32 #include <dali/devel-api/common/owner-container.h>
33 #include <dali/devel-api/object/handle-devel.h>
34 #include <dali/devel-api/scripting/enum-helper.h>
35 #include <dali/devel-api/scripting/scripting.h>
36 #include <dali/integration-api/debug.h>
37
38 // INTERNAL INCLUDES
39 #include <dali-toolkit/public-api/focus-manager/keyboard-focus-manager.h>
40 #include <dali-toolkit/public-api/controls/control.h>
41 #include <dali-toolkit/public-api/styling/style-manager.h>
42 #include <dali-toolkit/public-api/visuals/color-visual-properties.h>
43 #include <dali-toolkit/devel-api/controls/control-depth-index-ranges.h>
44 #include <dali-toolkit/devel-api/controls/control-devel.h>
45 #include <dali-toolkit/devel-api/visuals/visual-properties-devel.h>
46 #include <dali-toolkit/devel-api/visual-factory/visual-factory.h>
47 #include <dali-toolkit/devel-api/focus-manager/keyinput-focus-manager.h>
48 #include <dali-toolkit/internal/styling/style-manager-impl.h>
49 #include <dali-toolkit/internal/visuals/color/color-visual.h>
50 #include <dali-toolkit/internal/visuals/transition-data-impl.h>
51 #include <dali-toolkit/internal/visuals/visual-string-constants.h>
52 #include <dali-toolkit/devel-api/align-enums.h>
53 #include <dali-toolkit/internal/controls/tooltip/tooltip.h>
54
55 namespace Dali
56 {
57 extern bool CaseInsensitiveStringCompare( const std::string& a, const std::string& b );
58
59 namespace Toolkit
60 {
61
62 namespace
63 {
64
65 #if defined(DEBUG_ENABLED)
66 Debug::Filter* gLogFilter = Debug::Filter::New( Debug::NoLogging, false, "LOG_CONTROL_VISUALS");
67 #endif
68
69 DALI_ENUM_TO_STRING_TABLE_BEGIN( CLIPPING_MODE )
70 DALI_ENUM_TO_STRING_WITH_SCOPE( ClippingMode, DISABLED )
71 DALI_ENUM_TO_STRING_WITH_SCOPE( ClippingMode, CLIP_CHILDREN )
72 DALI_ENUM_TO_STRING_TABLE_END( CLIPPING_MODE )
73
74 /**
75  * Struct used to store Visual within the control, index is a unique key for each visual.
76  */
77 struct RegisteredVisual
78 {
79   Property::Index index;
80   Toolkit::Visual::Base visual;
81   bool enabled;
82
83   RegisteredVisual( Property::Index aIndex, Toolkit::Visual::Base &aVisual, bool aEnabled)
84   : index(aIndex), visual(aVisual), enabled(aEnabled)
85   {
86   }
87 };
88
89 typedef Dali::OwnerContainer< RegisteredVisual* > RegisteredVisualContainer;
90
91 /**
92  *  Finds visual in given array, returning true if found along with the iterator for that visual as a out parameter
93  */
94 bool FindVisual( Property::Index targetIndex, RegisteredVisualContainer& visuals, RegisteredVisualContainer::Iterator& iter )
95 {
96   for ( iter = visuals.Begin(); iter != visuals.End(); iter++ )
97   {
98     if ( (*iter)->index ==  targetIndex )
99     {
100       return true;
101     }
102   }
103   return false;
104 }
105
106 Toolkit::Visual::Base GetVisualByName(
107   RegisteredVisualContainer& visuals,
108   const std::string& visualName )
109 {
110   Toolkit::Visual::Base visualHandle;
111
112   RegisteredVisualContainer::Iterator iter;
113   for ( iter = visuals.Begin(); iter != visuals.End(); iter++ )
114   {
115     Toolkit::Visual::Base visual = (*iter)->visual;
116     if( visual && visual.GetName() == visualName )
117     {
118       visualHandle = visual;
119       break;
120     }
121   }
122   return visualHandle;
123 }
124
125 /**
126  * Creates control through type registry
127  */
128 BaseHandle Create()
129 {
130   return Internal::Control::New();
131 }
132
133 /**
134  * Performs actions as requested using the action name.
135  * @param[in] object The object on which to perform the action.
136  * @param[in] actionName The action to perform.
137  * @param[in] attributes The attributes with which to perfrom this action.
138  * @return true if action has been accepted by this control
139  */
140 const char* ACTION_ACCESSIBILITY_ACTIVATED = "accessibilityActivated";
141 static bool DoAction( BaseObject* object, const std::string& actionName, const Property::Map& attributes )
142 {
143   bool ret = false;
144
145   if( object && ( 0 == strcmp( actionName.c_str(), ACTION_ACCESSIBILITY_ACTIVATED ) ) )
146   {
147     Toolkit::Control control = Toolkit::Control::DownCast( BaseHandle( object ) );
148     if( control )
149     {
150       // if cast succeeds there is an implementation so no need to check
151       ret = Internal::GetImplementation( control ).OnAccessibilityActivated();
152     }
153   }
154
155   return ret;
156 }
157
158 /**
159  * Connects a callback function with the object's signals.
160  * @param[in] object The object providing the signal.
161  * @param[in] tracker Used to disconnect the signal.
162  * @param[in] signalName The signal to connect to.
163  * @param[in] functor A newly allocated FunctorDelegate.
164  * @return True if the signal was connected.
165  * @post If a signal was connected, ownership of functor was passed to CallbackBase. Otherwise the caller is responsible for deleting the unused functor.
166  */
167 const char* SIGNAL_KEY_EVENT = "keyEvent";
168 const char* SIGNAL_KEY_INPUT_FOCUS_GAINED = "keyInputFocusGained";
169 const char* SIGNAL_KEY_INPUT_FOCUS_LOST = "keyInputFocusLost";
170 const char* SIGNAL_TAPPED = "tapped";
171 const char* SIGNAL_PANNED = "panned";
172 const char* SIGNAL_PINCHED = "pinched";
173 const char* SIGNAL_LONG_PRESSED = "longPressed";
174 static bool DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
175 {
176   Dali::BaseHandle handle( object );
177
178   bool connected( false );
179   Toolkit::Control control = Toolkit::Control::DownCast( handle );
180   if ( control )
181   {
182     Internal::Control& controlImpl( Internal::GetImplementation( control ) );
183     connected = true;
184
185     if ( 0 == strcmp( signalName.c_str(), SIGNAL_KEY_EVENT ) )
186     {
187       controlImpl.KeyEventSignal().Connect( tracker, functor );
188     }
189     else if( 0 == strcmp( signalName.c_str(), SIGNAL_KEY_INPUT_FOCUS_GAINED ) )
190     {
191       controlImpl.KeyInputFocusGainedSignal().Connect( tracker, functor );
192     }
193     else if( 0 == strcmp( signalName.c_str(), SIGNAL_KEY_INPUT_FOCUS_LOST ) )
194     {
195       controlImpl.KeyInputFocusLostSignal().Connect( tracker, functor );
196     }
197     else if( 0 == strcmp( signalName.c_str(), SIGNAL_TAPPED ) )
198     {
199       controlImpl.EnableGestureDetection( Gesture::Tap );
200       controlImpl.GetTapGestureDetector().DetectedSignal().Connect( tracker, functor );
201     }
202     else if( 0 == strcmp( signalName.c_str(), SIGNAL_PANNED ) )
203     {
204       controlImpl.EnableGestureDetection( Gesture::Pan );
205       controlImpl.GetPanGestureDetector().DetectedSignal().Connect( tracker, functor );
206     }
207     else if( 0 == strcmp( signalName.c_str(), SIGNAL_PINCHED ) )
208     {
209       controlImpl.EnableGestureDetection( Gesture::Pinch );
210       controlImpl.GetPinchGestureDetector().DetectedSignal().Connect( tracker, functor );
211     }
212     else if( 0 == strcmp( signalName.c_str(), SIGNAL_LONG_PRESSED ) )
213     {
214       controlImpl.EnableGestureDetection( Gesture::LongPress );
215       controlImpl.GetLongPressGestureDetector().DetectedSignal().Connect( tracker, functor );
216     }
217   }
218   return connected;
219 }
220
221 const Scripting::StringEnum ControlStateTable[] = {
222   { "NORMAL",   Toolkit::DevelControl::NORMAL   },
223   { "FOCUSED",  Toolkit::DevelControl::FOCUSED  },
224   { "DISABLED", Toolkit::DevelControl::DISABLED },
225 }; const unsigned int ControlStateTableCount = sizeof( ControlStateTable ) / sizeof( ControlStateTable[0] );
226
227 // Setup signals and actions using the type-registry.
228 DALI_TYPE_REGISTRATION_BEGIN( Control, CustomActor, Create );
229
230 // Note: Properties are registered separately below.
231
232 SignalConnectorType registerSignal1( typeRegistration, SIGNAL_KEY_EVENT, &DoConnectSignal );
233 SignalConnectorType registerSignal2( typeRegistration, SIGNAL_KEY_INPUT_FOCUS_GAINED, &DoConnectSignal );
234 SignalConnectorType registerSignal3( typeRegistration, SIGNAL_KEY_INPUT_FOCUS_LOST, &DoConnectSignal );
235 SignalConnectorType registerSignal4( typeRegistration, SIGNAL_TAPPED, &DoConnectSignal );
236 SignalConnectorType registerSignal5( typeRegistration, SIGNAL_PANNED, &DoConnectSignal );
237 SignalConnectorType registerSignal6( typeRegistration, SIGNAL_PINCHED, &DoConnectSignal );
238 SignalConnectorType registerSignal7( typeRegistration, SIGNAL_LONG_PRESSED, &DoConnectSignal );
239
240 TypeAction registerAction( typeRegistration, ACTION_ACCESSIBILITY_ACTIVATED, &DoAction );
241
242 DALI_TYPE_REGISTRATION_END()
243
244 } // unnamed namespace
245
246 namespace Internal
247 {
248
249 class Control::Impl : public ConnectionTracker
250 {
251 public:
252
253   // Construction & Destruction
254   Impl(Control& controlImpl)
255   : mControlImpl( controlImpl ),
256     mState( Toolkit::DevelControl::NORMAL ),
257     mSubState(""),
258     mStyleName(""),
259     mBackgroundColor(Color::TRANSPARENT),
260     mStartingPinchScale( NULL ),
261     mKeyEventSignal(),
262     mPinchGestureDetector(),
263     mPanGestureDetector(),
264     mTapGestureDetector(),
265     mLongPressGestureDetector(),
266     mFlags( Control::ControlBehaviour( CONTROL_BEHAVIOUR_DEFAULT ) ),
267     mIsKeyboardNavigationSupported( false ),
268     mIsKeyboardFocusGroup( false )
269   {
270   }
271
272   ~Impl()
273   {
274     // All gesture detectors will be destroyed so no need to disconnect.
275     delete mStartingPinchScale;
276   }
277
278   // Gesture Detection Methods
279
280   void PinchDetected(Actor actor, const PinchGesture& pinch)
281   {
282     mControlImpl.OnPinch(pinch);
283   }
284
285   void PanDetected(Actor actor, const PanGesture& pan)
286   {
287     mControlImpl.OnPan(pan);
288   }
289
290   void TapDetected(Actor actor, const TapGesture& tap)
291   {
292     mControlImpl.OnTap(tap);
293   }
294
295   void LongPressDetected(Actor actor, const LongPressGesture& longPress)
296   {
297     mControlImpl.OnLongPress(longPress);
298   }
299
300   // Properties
301
302   /**
303    * Called when a property of an object of this type is set.
304    * @param[in] object The object whose property is set.
305    * @param[in] index The property index.
306    * @param[in] value The new property value.
307    */
308   static void SetProperty( BaseObject* object, Property::Index index, const Property::Value& value )
309   {
310     Toolkit::Control control = Toolkit::Control::DownCast( BaseHandle( object ) );
311
312     if ( control )
313     {
314       Control& controlImpl( GetImplementation( control ) );
315
316       switch ( index )
317       {
318         case Toolkit::Control::Property::STYLE_NAME:
319         {
320           controlImpl.SetStyleName( value.Get< std::string >() );
321           break;
322         }
323
324         case Toolkit::DevelControl::Property::STATE:
325         {
326           Toolkit::DevelControl::State state( controlImpl.mImpl->mState );
327
328           if( Scripting::GetEnumerationProperty< Toolkit::DevelControl::State >( value, ControlStateTable, ControlStateTableCount, state ) )
329           {
330             controlImpl.mImpl->SetState( state );
331           }
332         }
333         break;
334
335         case Toolkit::DevelControl::Property::SUB_STATE:
336         {
337           std::string subState;
338           if( value.Get( subState ) )
339           {
340             controlImpl.mImpl->SetSubState( subState );
341           }
342         }
343         break;
344
345         case Toolkit::Control::Property::BACKGROUND_COLOR:
346         {
347           DALI_LOG_WARNING( "BACKGROUND_COLOR property is deprecated. Use BACKGROUND property instead\n" );
348           controlImpl.SetBackgroundColor( value.Get< Vector4 >() );
349           break;
350         }
351
352         case Toolkit::Control::Property::BACKGROUND_IMAGE:
353         {
354           DALI_LOG_WARNING( "BACKGROUND_IMAGE property is deprecated. Use BACKGROUND property instead\n" );
355           Image image = Scripting::NewImage( value );
356           if ( image )
357           {
358             controlImpl.SetBackgroundImage( image );
359           }
360           else
361           {
362             // An empty image means the background is no longer required
363             controlImpl.ClearBackground();
364           }
365           break;
366         }
367
368         case Toolkit::Control::Property::KEY_INPUT_FOCUS:
369         {
370           if ( value.Get< bool >() )
371           {
372             controlImpl.SetKeyInputFocus();
373           }
374           else
375           {
376             controlImpl.ClearKeyInputFocus();
377           }
378           break;
379         }
380
381         case Toolkit::Control::Property::BACKGROUND:
382         {
383           std::string url;
384           const Property::Map* map = value.GetMap();
385           if( map && !map->Empty() )
386           {
387             controlImpl.SetBackground( *map );
388           }
389           else if( value.Get( url ) )
390           {
391             // don't know the size to load
392             Toolkit::Visual::Base visual = Toolkit::VisualFactory::Get().CreateVisual( url, ImageDimensions() );
393             if( visual )
394             {
395               controlImpl.RegisterVisual( Toolkit::Control::Property::BACKGROUND, visual );
396               visual.SetDepthIndex( DepthIndex::BACKGROUND );
397             }
398           }
399           else
400           {
401             // The background is an empty property map, so we should clear the background
402             controlImpl.ClearBackground();
403           }
404           break;
405         }
406
407         case Toolkit::DevelControl::Property::TOOLTIP:
408         {
409           TooltipPtr& tooltipPtr = controlImpl.mImpl->mTooltip;
410           if( ! tooltipPtr )
411           {
412             tooltipPtr = Tooltip::New( control );
413           }
414           tooltipPtr->SetProperties( value );
415         }
416       }
417     }
418   }
419
420   /**
421    * Called to retrieve a property of an object of this type.
422    * @param[in] object The object whose property is to be retrieved.
423    * @param[in] index The property index.
424    * @return The current value of the property.
425    */
426   static Property::Value GetProperty( BaseObject* object, Property::Index index )
427   {
428     Property::Value value;
429
430     Toolkit::Control control = Toolkit::Control::DownCast( BaseHandle( object ) );
431
432     if ( control )
433     {
434       Control& controlImpl( GetImplementation( control ) );
435
436       switch ( index )
437       {
438         case Toolkit::Control::Property::STYLE_NAME:
439         {
440           value = controlImpl.GetStyleName();
441           break;
442         }
443
444         case Toolkit::DevelControl::Property::STATE:
445         {
446           value = Scripting::GetEnumerationName< Toolkit::DevelControl::State >( controlImpl.mImpl->mState, ControlStateTable, ControlStateTableCount );
447           break;
448         }
449
450         case Toolkit::Control::Property::BACKGROUND_COLOR:
451         {
452           DALI_LOG_WARNING( "BACKGROUND_COLOR property is deprecated. Use BACKGROUND property instead\n" );
453           value = controlImpl.GetBackgroundColor();
454           break;
455         }
456
457         case Toolkit::Control::Property::BACKGROUND_IMAGE:
458         {
459           DALI_LOG_WARNING( "BACKGROUND_IMAGE property is deprecated. Use BACKGROUND property instead\n" );
460           Property::Map map;
461           Toolkit::Visual::Base visual = controlImpl.GetVisual( Toolkit::Control::Property::BACKGROUND );
462           if( visual )
463           {
464             visual.CreatePropertyMap( map );
465           }
466           value = map;
467           break;
468         }
469
470         case Toolkit::Control::Property::KEY_INPUT_FOCUS:
471         {
472           value = controlImpl.HasKeyInputFocus();
473           break;
474         }
475
476         case Toolkit::Control::Property::BACKGROUND:
477         {
478           Property::Map map;
479           Toolkit::Visual::Base visual = controlImpl.GetVisual( Toolkit::Control::Property::BACKGROUND );
480           if( visual )
481           {
482             visual.CreatePropertyMap( map );
483           }
484
485           value = map;
486           break;
487         }
488
489         case Toolkit::DevelControl::Property::TOOLTIP:
490         {
491           Property::Map map;
492           if( controlImpl.mImpl->mTooltip )
493           {
494             controlImpl.mImpl->mTooltip->CreatePropertyMap( map );
495           }
496           value = map;
497           break;
498         }
499
500       }
501     }
502
503     return value;
504   }
505
506   void SetState( DevelControl::State state )
507   {
508     if( mState != state )
509     {
510       // If mState was Disabled, and new state is Focused, should probably
511       // store that fact, e.g. in another property that FocusManager can access.
512       mState = state;
513
514       // Trigger state change and transitions
515       // Apply new style, if stylemanager is available
516       Toolkit::StyleManager styleManager = Toolkit::StyleManager::Get();
517       if( styleManager )
518       {
519         const StylePtr stylePtr = GetImpl( styleManager ).GetRecordedStyle( Toolkit::Control( mControlImpl.GetOwner() ) );
520         if( stylePtr )
521         {
522           for( int i=mVisuals.Count()-1; i >= 0; i-- )
523           {
524             mControlImpl.UnregisterVisual( mVisuals[i]->index );
525           }
526
527           Dali::CustomActor handle( mControlImpl.GetOwner() );
528           stylePtr->ApplyVisualsAndPropertiesRecursively( handle );
529         }
530       }
531     }
532   }
533
534   void SetSubState( const std::string& state )
535   {
536     if( mSubState != state )
537     {
538       mSubState = state;
539       // Trigger transitions
540
541     }
542   }
543
544   // Data
545
546   Control& mControlImpl;
547   DevelControl::State mState;
548   std::string mSubState;
549
550   RegisteredVisualContainer mVisuals; // Stores visuals needed by the control, non trivial type so std::vector used.
551   std::string mStyleName;
552   Vector4 mBackgroundColor;                       ///< The color of the background visual
553   Vector3* mStartingPinchScale;      ///< The scale when a pinch gesture starts, TODO: consider removing this
554   Toolkit::Control::KeyEventSignalType mKeyEventSignal;
555   Toolkit::Control::KeyInputFocusSignalType mKeyInputFocusGainedSignal;
556   Toolkit::Control::KeyInputFocusSignalType mKeyInputFocusLostSignal;
557
558   // Gesture Detection
559   PinchGestureDetector mPinchGestureDetector;
560   PanGestureDetector mPanGestureDetector;
561   TapGestureDetector mTapGestureDetector;
562   LongPressGestureDetector mLongPressGestureDetector;
563
564   // Tooltip
565   TooltipPtr mTooltip;
566
567   ControlBehaviour mFlags : CONTROL_BEHAVIOUR_FLAG_COUNT;    ///< Flags passed in from constructor.
568   bool mIsKeyboardNavigationSupported :1;  ///< Stores whether keyboard navigation is supported by the control.
569   bool mIsKeyboardFocusGroup :1;           ///< Stores whether the control is a focus group.
570
571   // Properties - these need to be members of Internal::Control::Impl as they access private methods/data of Internal::Control and Internal::Control::Impl.
572   static const PropertyRegistration PROPERTY_1;
573   static const PropertyRegistration PROPERTY_2;
574   static const PropertyRegistration PROPERTY_3;
575   static const PropertyRegistration PROPERTY_4;
576   static const PropertyRegistration PROPERTY_5;
577   static const PropertyRegistration PROPERTY_6;
578   static const PropertyRegistration PROPERTY_7;
579   static const PropertyRegistration PROPERTY_8;
580 };
581
582 // Properties registered without macro to use specific member variables.
583 const PropertyRegistration Control::Impl::PROPERTY_1( typeRegistration, "styleName",       Toolkit::Control::Property::STYLE_NAME,       Property::STRING,  &Control::Impl::SetProperty, &Control::Impl::GetProperty );
584 const PropertyRegistration Control::Impl::PROPERTY_2( typeRegistration, "backgroundColor", Toolkit::Control::Property::BACKGROUND_COLOR, Property::VECTOR4, &Control::Impl::SetProperty, &Control::Impl::GetProperty );
585 const PropertyRegistration Control::Impl::PROPERTY_3( typeRegistration, "backgroundImage", Toolkit::Control::Property::BACKGROUND_IMAGE, Property::MAP,     &Control::Impl::SetProperty, &Control::Impl::GetProperty );
586 const PropertyRegistration Control::Impl::PROPERTY_4( typeRegistration, "keyInputFocus",   Toolkit::Control::Property::KEY_INPUT_FOCUS,  Property::BOOLEAN, &Control::Impl::SetProperty, &Control::Impl::GetProperty );
587 const PropertyRegistration Control::Impl::PROPERTY_5( typeRegistration, "background",      Toolkit::Control::Property::BACKGROUND,       Property::MAP,     &Control::Impl::SetProperty, &Control::Impl::GetProperty );
588 const PropertyRegistration Control::Impl::PROPERTY_6( typeRegistration, "tooltip",         Toolkit::DevelControl::Property::TOOLTIP,     Property::MAP,     &Control::Impl::SetProperty, &Control::Impl::GetProperty );
589 const PropertyRegistration Control::Impl::PROPERTY_7( typeRegistration, "state",           Toolkit::DevelControl::Property::STATE,       Property::STRING,  &Control::Impl::SetProperty, &Control::Impl::GetProperty );
590 const PropertyRegistration Control::Impl::PROPERTY_8( typeRegistration, "subState",        Toolkit::DevelControl::Property::SUB_STATE,   Property::STRING,  &Control::Impl::SetProperty, &Control::Impl::GetProperty );
591
592 Toolkit::Control Control::New()
593 {
594   // Create the implementation, temporarily owned on stack
595   IntrusivePtr<Control> controlImpl = new Control( ControlBehaviour( CONTROL_BEHAVIOUR_DEFAULT ) );
596
597   // Pass ownership to handle
598   Toolkit::Control handle( *controlImpl );
599
600   // Second-phase init of the implementation
601   // This can only be done after the CustomActor connection has been made...
602   controlImpl->Initialize();
603
604   return handle;
605 }
606
607 void Control::SetStyleName( const std::string& styleName )
608 {
609   if( styleName != mImpl->mStyleName )
610   {
611     mImpl->mStyleName = styleName;
612
613     // Apply new style, if stylemanager is available
614     Toolkit::StyleManager styleManager = Toolkit::StyleManager::Get();
615     if( styleManager )
616     {
617       GetImpl( styleManager ).ApplyThemeStyle( Toolkit::Control( GetOwner() ) );
618     }
619   }
620 }
621
622 const std::string& Control::GetStyleName() const
623 {
624   return mImpl->mStyleName;
625 }
626
627 void Control::SetBackgroundColor( const Vector4& color )
628 {
629   mImpl->mBackgroundColor = color;
630   Property::Map map;
631   map[ Toolkit::DevelVisual::Property::TYPE ] = Toolkit::Visual::COLOR;
632   map[ Toolkit::ColorVisual::Property::MIX_COLOR ] = color;
633
634   SetBackground( map );
635 }
636
637 Vector4 Control::GetBackgroundColor() const
638 {
639   return mImpl->mBackgroundColor;
640 }
641
642 void Control::SetBackground( const Property::Map& map )
643 {
644   Toolkit::Visual::Base visual = Toolkit::VisualFactory::Get().CreateVisual( map );
645   if( visual )
646   {
647     RegisterVisual( Toolkit::Control::Property::BACKGROUND, visual );
648     visual.SetDepthIndex( DepthIndex::BACKGROUND );
649
650     // Trigger a size negotiation request that may be needed by the new visual to relayout its contents.
651     RelayoutRequest();
652   }
653 }
654
655 void Control::SetBackgroundImage( Image image )
656 {
657   Toolkit::Visual::Base visual = Toolkit::VisualFactory::Get().CreateVisual( image );
658   if( visual )
659   {
660     RegisterVisual( Toolkit::Control::Property::BACKGROUND, visual );
661     visual.SetDepthIndex( DepthIndex::BACKGROUND );
662   }
663 }
664
665 void Control::ClearBackground()
666 {
667    UnregisterVisual( Toolkit::Control::Property::BACKGROUND );
668    mImpl->mBackgroundColor = Color::TRANSPARENT;
669
670    // Trigger a size negotiation request that may be needed when unregistering a visual.
671    RelayoutRequest();
672 }
673
674 void Control::EnableGestureDetection(Gesture::Type type)
675 {
676   if ( (type & Gesture::Pinch) && !mImpl->mPinchGestureDetector )
677   {
678     mImpl->mPinchGestureDetector = PinchGestureDetector::New();
679     mImpl->mPinchGestureDetector.DetectedSignal().Connect(mImpl, &Impl::PinchDetected);
680     mImpl->mPinchGestureDetector.Attach(Self());
681   }
682
683   if ( (type & Gesture::Pan) && !mImpl->mPanGestureDetector )
684   {
685     mImpl->mPanGestureDetector = PanGestureDetector::New();
686     mImpl->mPanGestureDetector.DetectedSignal().Connect(mImpl, &Impl::PanDetected);
687     mImpl->mPanGestureDetector.Attach(Self());
688   }
689
690   if ( (type & Gesture::Tap) && !mImpl->mTapGestureDetector )
691   {
692     mImpl->mTapGestureDetector = TapGestureDetector::New();
693     mImpl->mTapGestureDetector.DetectedSignal().Connect(mImpl, &Impl::TapDetected);
694     mImpl->mTapGestureDetector.Attach(Self());
695   }
696
697   if ( (type & Gesture::LongPress) && !mImpl->mLongPressGestureDetector )
698   {
699     mImpl->mLongPressGestureDetector = LongPressGestureDetector::New();
700     mImpl->mLongPressGestureDetector.DetectedSignal().Connect(mImpl, &Impl::LongPressDetected);
701     mImpl->mLongPressGestureDetector.Attach(Self());
702   }
703 }
704
705 void Control::DisableGestureDetection(Gesture::Type type)
706 {
707   if ( (type & Gesture::Pinch) && mImpl->mPinchGestureDetector )
708   {
709     mImpl->mPinchGestureDetector.Detach(Self());
710     mImpl->mPinchGestureDetector.Reset();
711   }
712
713   if ( (type & Gesture::Pan) && mImpl->mPanGestureDetector )
714   {
715     mImpl->mPanGestureDetector.Detach(Self());
716     mImpl->mPanGestureDetector.Reset();
717   }
718
719   if ( (type & Gesture::Tap) && mImpl->mTapGestureDetector )
720   {
721     mImpl->mTapGestureDetector.Detach(Self());
722     mImpl->mTapGestureDetector.Reset();
723   }
724
725   if ( (type & Gesture::LongPress) && mImpl->mLongPressGestureDetector)
726   {
727     mImpl->mLongPressGestureDetector.Detach(Self());
728     mImpl->mLongPressGestureDetector.Reset();
729   }
730 }
731
732 PinchGestureDetector Control::GetPinchGestureDetector() const
733 {
734   return mImpl->mPinchGestureDetector;
735 }
736
737 PanGestureDetector Control::GetPanGestureDetector() const
738 {
739   return mImpl->mPanGestureDetector;
740 }
741
742 TapGestureDetector Control::GetTapGestureDetector() const
743 {
744   return mImpl->mTapGestureDetector;
745 }
746
747 LongPressGestureDetector Control::GetLongPressGestureDetector() const
748 {
749   return mImpl->mLongPressGestureDetector;
750 }
751
752 void Control::SetKeyboardNavigationSupport(bool isSupported)
753 {
754   mImpl->mIsKeyboardNavigationSupported = isSupported;
755 }
756
757 bool Control::IsKeyboardNavigationSupported()
758 {
759   return mImpl->mIsKeyboardNavigationSupported;
760 }
761
762 void Control::SetKeyInputFocus()
763 {
764   if( Self().OnStage() )
765   {
766     Toolkit::KeyInputFocusManager::Get().SetFocus(Toolkit::Control::DownCast(Self()));
767   }
768 }
769
770 bool Control::HasKeyInputFocus()
771 {
772   bool result = false;
773   if( Self().OnStage() )
774   {
775     result = Toolkit::KeyInputFocusManager::Get().IsKeyboardListener(Toolkit::Control::DownCast(Self()));
776   }
777   return result;
778 }
779
780 void Control::ClearKeyInputFocus()
781 {
782   if( Self().OnStage() )
783   {
784     Toolkit::KeyInputFocusManager::Get().RemoveFocus(Toolkit::Control::DownCast(Self()));
785   }
786 }
787
788 void Control::SetAsKeyboardFocusGroup(bool isFocusGroup)
789 {
790   mImpl->mIsKeyboardFocusGroup = isFocusGroup;
791
792   // The following line will be removed when the deprecated API in KeyboardFocusManager is deleted
793   Toolkit::KeyboardFocusManager::Get().SetAsFocusGroup(Self(), isFocusGroup);
794 }
795
796 bool Control::IsKeyboardFocusGroup()
797 {
798   return Toolkit::KeyboardFocusManager::Get().IsFocusGroup(Self());
799 }
800
801 void Control::AccessibilityActivate()
802 {
803   // Inform deriving classes
804   OnAccessibilityActivated();
805 }
806
807 void Control::KeyboardEnter()
808 {
809   // Inform deriving classes
810   OnKeyboardEnter();
811 }
812
813 void Control::RegisterVisual( Property::Index index, Toolkit::Visual::Base& visual )
814 {
815   RegisterVisual( index, visual, true );
816 }
817
818 void Control::RegisterVisual( Property::Index index, Toolkit::Visual::Base& visual, bool enabled )
819 {
820   bool visualReplaced ( false );
821   Actor self = Self();
822
823   if( !mImpl->mVisuals.Empty() )
824   {
825     RegisteredVisualContainer::Iterator iter;
826     // Check if visual (index) is already registered.  Replace if so.
827     if ( FindVisual( index, mImpl->mVisuals, iter ) )
828     {
829       if( (*iter)->visual && self.OnStage() )
830       {
831         Toolkit::GetImplementation((*iter)->visual).SetOffStage( self );
832       }
833       (*iter)->visual = visual;
834       visualReplaced = true;
835     }
836   }
837
838   // If not set, set the name of the visual to the same name as the control's property.
839   // ( If the control has been type registered )
840   if( visual.GetName().empty() )
841   {
842     // Check if the control has been type registered:
843     TypeInfo typeInfo = TypeRegistry::Get().GetTypeInfo( typeid(*this) );
844     if( typeInfo )
845     {
846       // Check if the property index has been registered:
847       Property::IndexContainer indices;
848       typeInfo.GetPropertyIndices( indices );
849       Property::IndexContainer::Iterator iter = std::find( indices.Begin(), indices.End(), index );
850       if( iter != indices.End() )
851       {
852         // If it has, then get it's name and use that for the visual
853         std::string visualName = typeInfo.GetPropertyName( index );
854         visual.SetName( visualName );
855       }
856     }
857   }
858
859   if( !visualReplaced ) // New registration entry
860   {
861     mImpl->mVisuals.PushBack( new RegisteredVisual( index, visual, enabled ) );
862   }
863
864   if( visual && self.OnStage() && enabled )
865   {
866     Toolkit::GetImplementation(visual).SetOnStage( self );
867   }
868
869   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Control::RegisterVisual() Registered %s(%d), enabled:%s\n",  visual.GetName().c_str(), index, enabled?"T":"F" );
870 }
871
872 void Control::UnregisterVisual( Property::Index index )
873 {
874    RegisteredVisualContainer::Iterator iter;
875    if ( FindVisual( index, mImpl->mVisuals, iter ) )
876    {
877      Actor self( Self() );
878      Toolkit::GetImplementation((*iter)->visual).SetOffStage( self );
879      (*iter)->visual.Reset();
880      mImpl->mVisuals.Erase( iter );
881    }
882 }
883
884 Toolkit::Visual::Base Control::GetVisual( Property::Index index ) const
885 {
886   RegisteredVisualContainer::Iterator iter;
887   if ( FindVisual( index, mImpl->mVisuals, iter ) )
888   {
889     return (*iter)->visual;
890   }
891
892   return Toolkit::Visual::Base();
893 }
894
895 void Control::EnableVisual( Property::Index index, bool enable )
896 {
897   RegisteredVisualContainer::Iterator iter;
898   if ( FindVisual( index, mImpl->mVisuals, iter ) )
899   {
900     if (  (*iter)->enabled == enable )
901     {
902       DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Control::EnableVisual Visual %s(%d) already %s\n", (*iter)->visual.GetName().c_str(), index, enable?"enabled":"disabled");
903       return;
904     }
905
906     (*iter)->enabled = enable;
907     Actor parentActor = Self();
908     if ( Self().OnStage() ) // If control not on Stage then Visual will be added when StageConnection is called.
909     {
910       if ( enable )
911       {
912         DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Control::EnableVisual Setting %s(%d) on stage \n", (*iter)->visual.GetName().c_str(), index );
913         Toolkit::GetImplementation((*iter)->visual).SetOnStage( parentActor );
914       }
915       else
916       {
917         DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Control::EnableVisual Setting %s(%d) off stage \n", (*iter)->visual.GetName().c_str(), index );
918         Toolkit::GetImplementation((*iter)->visual).SetOffStage( parentActor );  // No need to call if control not staged.
919       }
920     }
921   }
922 }
923
924 bool Control::IsVisualEnabled( Property::Index index ) const
925 {
926   RegisteredVisualContainer::Iterator iter;
927   if ( FindVisual( index, mImpl->mVisuals, iter ) )
928   {
929     return (*iter)->enabled;
930   }
931   return false;
932 }
933
934 Dali::Animation Control::CreateTransition( const Toolkit::TransitionData& handle )
935 {
936   Dali::Animation transition;
937   const Internal::TransitionData& transitionData = Toolkit::GetImplementation( handle );
938
939   if( transitionData.Count() > 0 )
940   {
941     // Setup a Transition from TransitionData.
942     TransitionData::Iterator end = transitionData.End();
943     for( TransitionData::Iterator iter = transitionData.Begin() ;
944          iter != end; ++iter )
945     {
946       TransitionData::Animator* animator = (*iter);
947
948       Toolkit::Visual::Base visual = GetVisualByName( mImpl->mVisuals, animator->objectName );
949
950       if( visual )
951       {
952         Internal::Visual::Base& visualImpl = Toolkit::GetImplementation( visual );
953         visualImpl.AnimateProperty( transition, *animator );
954       }
955       else
956       {
957         // Otherwise, try any actor children of control (Including the control)
958         Actor child = Self().FindChildByName( animator->objectName );
959         if( child )
960         {
961           Property::Index propertyIndex = DevelHandle::GetPropertyIndex( child, animator->propertyKey );
962           if( propertyIndex != Property::INVALID_INDEX )
963           {
964             if( animator->animate == false )
965             {
966               if( animator->targetValue.GetType() != Property::NONE )
967               {
968                 child.SetProperty( propertyIndex, animator->targetValue );
969               }
970             }
971             else // animate the property
972             {
973               if( animator->initialValue.GetType() != Property::NONE )
974               {
975                 child.SetProperty( propertyIndex, animator->initialValue );
976               }
977
978               if( ! transition )
979               {
980                 transition = Dali::Animation::New( 0.1f );
981               }
982
983               transition.AnimateTo( Property( child, propertyIndex ),
984                                     animator->targetValue,
985                                     animator->alphaFunction,
986                                     TimePeriod( animator->timePeriodDelay,
987                                                 animator->timePeriodDuration ) );
988             }
989           }
990         }
991       }
992     }
993   }
994
995   return transition;
996 }
997
998 bool Control::OnAccessibilityActivated()
999 {
1000   return false; // Accessibility activation is not handled by default
1001 }
1002
1003 bool Control::OnKeyboardEnter()
1004 {
1005   return false; // Keyboard enter is not handled by default
1006 }
1007
1008 bool Control::OnAccessibilityPan(PanGesture gesture)
1009 {
1010   return false; // Accessibility pan gesture is not handled by default
1011 }
1012
1013 bool Control::OnAccessibilityTouch(const TouchEvent& touchEvent)
1014 {
1015   return false; // Accessibility touch event is not handled by default
1016 }
1017
1018 bool Control::OnAccessibilityValueChange(bool isIncrease)
1019 {
1020   return false; // Accessibility value change action is not handled by default
1021 }
1022
1023 bool Control::OnAccessibilityZoom()
1024 {
1025   return false; // Accessibility zoom action is not handled by default
1026 }
1027
1028 Actor Control::GetNextKeyboardFocusableActor(Actor currentFocusedActor, Toolkit::Control::KeyboardFocus::Direction direction, bool loopEnabled)
1029 {
1030   return Actor();
1031 }
1032
1033 void Control::OnKeyboardFocusChangeCommitted(Actor commitedFocusableActor)
1034 {
1035 }
1036
1037 Toolkit::Control::KeyEventSignalType& Control::KeyEventSignal()
1038 {
1039   return mImpl->mKeyEventSignal;
1040 }
1041
1042 Toolkit::Control::KeyInputFocusSignalType& Control::KeyInputFocusGainedSignal()
1043 {
1044   return mImpl->mKeyInputFocusGainedSignal;
1045 }
1046
1047 Toolkit::Control::KeyInputFocusSignalType& Control::KeyInputFocusLostSignal()
1048 {
1049   return mImpl->mKeyInputFocusLostSignal;
1050 }
1051
1052 bool Control::EmitKeyEventSignal( const KeyEvent& event )
1053 {
1054   // Guard against destruction during signal emission
1055   Dali::Toolkit::Control handle( GetOwner() );
1056
1057   bool consumed = false;
1058
1059   // signals are allocated dynamically when someone connects
1060   if ( !mImpl->mKeyEventSignal.Empty() )
1061   {
1062     consumed = mImpl->mKeyEventSignal.Emit( handle, event );
1063   }
1064
1065   if (!consumed)
1066   {
1067     // Notification for derived classes
1068     consumed = OnKeyEvent(event);
1069   }
1070
1071   return consumed;
1072 }
1073
1074 Control::Control( ControlBehaviour behaviourFlags )
1075 : CustomActorImpl( static_cast< ActorFlags >( behaviourFlags ) ),
1076   mImpl(new Impl(*this))
1077 {
1078   mImpl->mFlags = behaviourFlags;
1079 }
1080
1081 Control::~Control()
1082 {
1083   delete mImpl;
1084 }
1085
1086 void Control::Initialize()
1087 {
1088   // Call deriving classes so initialised before styling is applied to them.
1089   OnInitialize();
1090
1091   if( (mImpl->mFlags & REQUIRES_STYLE_CHANGE_SIGNALS) ||
1092       !(mImpl->mFlags & DISABLE_STYLE_CHANGE_SIGNALS) )
1093   {
1094     Toolkit::StyleManager styleManager = StyleManager::Get();
1095
1096     // if stylemanager is available
1097     if( styleManager )
1098     {
1099       StyleManager& styleManagerImpl = GetImpl( styleManager );
1100
1101       // Register for style changes
1102       styleManagerImpl.ControlStyleChangeSignal().Connect( this, &Control::OnStyleChange );
1103
1104       // Apply the current style
1105       styleManagerImpl.ApplyThemeStyleAtInit( Toolkit::Control( GetOwner() ) );
1106     }
1107   }
1108
1109   if( mImpl->mFlags & REQUIRES_KEYBOARD_NAVIGATION_SUPPORT )
1110   {
1111     SetKeyboardNavigationSupport( true );
1112   }
1113 }
1114
1115 void Control::OnInitialize()
1116 {
1117 }
1118
1119 void Control::OnControlChildAdd( Actor& child )
1120 {
1121 }
1122
1123 void Control::OnControlChildRemove( Actor& child )
1124 {
1125 }
1126
1127 void Control::OnStyleChange( Toolkit::StyleManager styleManager, StyleChange::Type change )
1128 {
1129   // By default the control is only interested in theme (not font) changes
1130   if( styleManager && change == StyleChange::THEME_CHANGE )
1131   {
1132     GetImpl( styleManager ).ApplyThemeStyle( Toolkit::Control( GetOwner() ) );
1133   }
1134   RelayoutRequest();
1135 }
1136
1137 void Control::OnPinch(const PinchGesture& pinch)
1138 {
1139   if( !( mImpl->mStartingPinchScale ) )
1140   {
1141     // lazy allocate
1142     mImpl->mStartingPinchScale = new Vector3;
1143   }
1144
1145   if( pinch.state == Gesture::Started )
1146   {
1147     *( mImpl->mStartingPinchScale ) = Self().GetCurrentScale();
1148   }
1149
1150   Self().SetScale( *( mImpl->mStartingPinchScale ) * pinch.scale );
1151 }
1152
1153 void Control::OnPan( const PanGesture& pan )
1154 {
1155 }
1156
1157 void Control::OnTap(const TapGesture& tap)
1158 {
1159 }
1160
1161 void Control::OnLongPress( const LongPressGesture& longPress )
1162 {
1163 }
1164
1165 void Control::EmitKeyInputFocusSignal( bool focusGained )
1166 {
1167   Dali::Toolkit::Control handle( GetOwner() );
1168
1169   if ( focusGained )
1170   {
1171     // signals are allocated dynamically when someone connects
1172     if ( !mImpl->mKeyInputFocusGainedSignal.Empty() )
1173     {
1174       mImpl->mKeyInputFocusGainedSignal.Emit( handle );
1175     }
1176   }
1177   else
1178   {
1179     // signals are allocated dynamically when someone connects
1180     if ( !mImpl->mKeyInputFocusLostSignal.Empty() )
1181     {
1182       mImpl->mKeyInputFocusLostSignal.Emit( handle );
1183     }
1184   }
1185 }
1186
1187 void Control::OnStageConnection( int depth )
1188 {
1189   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Control::OnStageConnection number of registered visuals(%d)\n",  mImpl->mVisuals.Size() );
1190
1191   Actor self( Self() );
1192
1193   for(RegisteredVisualContainer::Iterator iter = mImpl->mVisuals.Begin(); iter!= mImpl->mVisuals.End(); iter++)
1194   {
1195     // Check whether the visual is empty and enabled
1196     if( (*iter)->visual && (*iter)->enabled )
1197     {
1198       DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Control::OnStageConnection Setting visual(%d) on stage\n", (*iter)->index );
1199       Toolkit::GetImplementation((*iter)->visual).SetOnStage( self );
1200     }
1201   }
1202
1203   if( mImpl->mVisuals.Empty() && ! self.GetRendererCount() )
1204   {
1205     Property::Value clippingValue = self.GetProperty( Actor::Property::CLIPPING_MODE );
1206     int clippingMode = ClippingMode::DISABLED;
1207     if( clippingValue.Get( clippingMode ) )
1208     {
1209       // Add a transparent background if we do not have any renderers or visuals so we clip our children
1210
1211       if( clippingMode == ClippingMode::CLIP_CHILDREN )
1212       {
1213         // Create a transparent background visual which will also get staged.
1214         SetBackgroundColor( Color::TRANSPARENT );
1215       }
1216     }
1217   }
1218 }
1219
1220 void Control::OnStageDisconnection()
1221 {
1222   for(RegisteredVisualContainer::Iterator iter = mImpl->mVisuals.Begin(); iter!= mImpl->mVisuals.End(); iter++)
1223   {
1224     // Check whether the visual is empty
1225     if( (*iter)->visual )
1226     {
1227       DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Control::OnStageDisconnection Setting visual(%d) off stage\n", (*iter)->index );
1228       Actor self( Self() );
1229       Toolkit::GetImplementation((*iter)->visual).SetOffStage( self );
1230     }
1231   }
1232 }
1233
1234 void Control::OnKeyInputFocusGained()
1235 {
1236   EmitKeyInputFocusSignal( true );
1237 }
1238
1239 void Control::OnKeyInputFocusLost()
1240 {
1241   EmitKeyInputFocusSignal( false );
1242 }
1243
1244 void Control::OnChildAdd(Actor& child)
1245 {
1246   // Notify derived classes.
1247   OnControlChildAdd( child );
1248 }
1249
1250 void Control::OnChildRemove(Actor& child)
1251 {
1252   // Notify derived classes.
1253   OnControlChildRemove( child );
1254 }
1255
1256 void Control::OnPropertySet( Property::Index index, Property::Value propertyValue )
1257 {
1258   Actor self( Self() );
1259   if( index == Actor::Property::CLIPPING_MODE )
1260   {
1261     // Only set the background if we're already on the stage and have no renderers or visuals
1262
1263     if( mImpl->mVisuals.Empty() && ! self.GetRendererCount() && self.OnStage() )
1264     {
1265       ClippingMode::Type clippingMode = ClippingMode::DISABLED;
1266       if( Scripting::GetEnumerationProperty< ClippingMode::Type >( propertyValue, CLIPPING_MODE_TABLE, CLIPPING_MODE_TABLE_COUNT, clippingMode ) )
1267       {
1268         // Add a transparent background if we do not have one so we clip children
1269
1270         if( clippingMode == ClippingMode::CLIP_CHILDREN )
1271         {
1272           SetBackgroundColor( Color::TRANSPARENT );
1273         }
1274       }
1275     }
1276   }
1277 }
1278
1279 void Control::OnSizeSet(const Vector3& targetSize)
1280 {
1281   Toolkit::Visual::Base visual = GetVisual( Toolkit::Control::Property::BACKGROUND );
1282   if( visual )
1283   {
1284     Vector2 size( targetSize );
1285     visual.SetTransformAndSize( Property::Map(), size ); // Send an empty map as we do not want to modify the visual's set transform
1286   }
1287 }
1288
1289 void Control::OnSizeAnimation(Animation& animation, const Vector3& targetSize)
1290 {
1291   // @todo size negotiate background to new size, animate as well?
1292 }
1293
1294 bool Control::OnTouchEvent(const TouchEvent& event)
1295 {
1296   return false; // Do not consume
1297 }
1298
1299 bool Control::OnHoverEvent(const HoverEvent& event)
1300 {
1301   return false; // Do not consume
1302 }
1303
1304 bool Control::OnKeyEvent(const KeyEvent& event)
1305 {
1306   return false; // Do not consume
1307 }
1308
1309 bool Control::OnWheelEvent(const WheelEvent& event)
1310 {
1311   return false; // Do not consume
1312 }
1313
1314 void Control::OnRelayout( const Vector2& size, RelayoutContainer& container )
1315 {
1316   for( unsigned int i = 0, numChildren = Self().GetChildCount(); i < numChildren; ++i )
1317   {
1318     container.Add( Self().GetChildAt( i ), size );
1319   }
1320
1321   Toolkit::Visual::Base visual = GetVisual( Toolkit::Control::Property::BACKGROUND );
1322   if( visual )
1323   {
1324     visual.SetTransformAndSize( Property::Map(), size ); // Send an empty map as we do not want to modify the visual's set transform
1325   }
1326 }
1327
1328 void Control::OnSetResizePolicy( ResizePolicy::Type policy, Dimension::Type dimension )
1329 {
1330 }
1331
1332 Vector3 Control::GetNaturalSize()
1333 {
1334   Toolkit::Visual::Base visual = GetVisual( Toolkit::Control::Property::BACKGROUND );
1335   if( visual )
1336   {
1337     Vector2 naturalSize;
1338     visual.GetNaturalSize( naturalSize );
1339     return Vector3( naturalSize );
1340   }
1341   return Vector3::ZERO;
1342 }
1343
1344 float Control::CalculateChildSize( const Dali::Actor& child, Dimension::Type dimension )
1345 {
1346   return CalculateChildSizeBase( child, dimension );
1347 }
1348
1349 float Control::GetHeightForWidth( float width )
1350 {
1351   return GetHeightForWidthBase( width );
1352 }
1353
1354 float Control::GetWidthForHeight( float height )
1355 {
1356   return GetWidthForHeightBase( height );
1357 }
1358
1359 bool Control::RelayoutDependentOnChildren( Dimension::Type dimension )
1360 {
1361   return RelayoutDependentOnChildrenBase( dimension );
1362 }
1363
1364 void Control::OnCalculateRelayoutSize( Dimension::Type dimension )
1365 {
1366 }
1367
1368 void Control::OnLayoutNegotiated( float size, Dimension::Type dimension )
1369 {
1370 }
1371
1372 void Control::SignalConnected( SlotObserver* slotObserver, CallbackBase* callback )
1373 {
1374   mImpl->SignalConnected( slotObserver, callback );
1375 }
1376
1377 void Control::SignalDisconnected( SlotObserver* slotObserver, CallbackBase* callback )
1378 {
1379   mImpl->SignalDisconnected( slotObserver, callback );
1380 }
1381
1382 Control& GetImplementation( Dali::Toolkit::Control& handle )
1383 {
1384   CustomActorImpl& customInterface = handle.GetImplementation();
1385   // downcast to control
1386   Control& impl = dynamic_cast< Internal::Control& >( customInterface );
1387   return impl;
1388 }
1389
1390 const Control& GetImplementation( const Dali::Toolkit::Control& handle )
1391 {
1392   const CustomActorImpl& customInterface = handle.GetImplementation();
1393   // downcast to control
1394   const Control& impl = dynamic_cast< const Internal::Control& >( customInterface );
1395   return impl;
1396 }
1397
1398 } // namespace Internal
1399
1400 } // namespace Toolkit
1401
1402 } // namespace Dali