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