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