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