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