Added devel-api mirroring of public enumeration.
[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/devel-visual-properties.h>
42 #include <dali-toolkit/devel-api/visual-factory/visual-factory.h>
43 #include <dali-toolkit/devel-api/focus-manager/keyinput-focus-manager.h>
44 #include <dali-toolkit/internal/styling/style-manager-impl.h>
45 #include <dali-toolkit/internal/visuals/color/color-visual.h>
46 #include <dali-toolkit/internal/visuals/transition-data-impl.h>
47
48 namespace Dali
49 {
50
51 namespace Toolkit
52 {
53
54 namespace
55 {
56
57 #if defined(DEBUG_ENABLED)
58 Debug::Filter* gLogFilter = Debug::Filter::New( Debug::General, false, "LOG_CONTROL_VISUALS");
59 #endif
60
61 /**
62  * Struct used to store Visual within the control, index is a unique key for each visual.
63  */
64 struct RegisteredVisual
65 {
66   Property::Index index;
67   Toolkit::Visual::Base visual;
68   Actor placementActor;
69   bool enabled;
70
71   RegisteredVisual( Property::Index aIndex, Toolkit::Visual::Base &aVisual, Actor &aPlacementActor, bool aEnabled) :
72                    index(aIndex), visual(aVisual), placementActor(aPlacementActor), enabled(aEnabled) {}
73 };
74
75 struct HandleIndex
76 {
77   Handle handle; ///< a handle to the target object
78   Property::Index index; ///< The index of a property provided by the referenced object
79
80   HandleIndex( )
81   : handle(),
82     index( Property::INVALID_INDEX )
83   {
84   }
85
86   HandleIndex( Handle& handle, Property::Index index )
87   : handle( handle ),
88     index( index )
89   {
90   }
91 };
92
93
94 typedef Dali::OwnerContainer< RegisteredVisual* > RegisteredVisualContainer;
95
96 /**
97  *  Finds visual in given array, returning true if found along with the iterator for that visual as a out parameter
98  */
99 bool FindVisual( Property::Index targetIndex, RegisteredVisualContainer& visuals, RegisteredVisualContainer::Iterator& iter )
100 {
101   for ( iter = visuals.Begin(); iter != visuals.End(); iter++ )
102   {
103     if ( (*iter)->index ==  targetIndex )
104     {
105       return true;
106     }
107   }
108   return false;
109 }
110
111 HandleIndex GetVisualProperty(
112   Internal::Control& controlImpl,
113   RegisteredVisualContainer& visuals,
114   const std::string& visualName,
115   Property::Key propertyKey )
116 {
117 #if defined(DEBUG_ENABLED)
118   std::ostringstream oss;
119   oss << "Control::GetHandleIndex(" << visualName << ", " << propertyKey << ")" << std::endl;
120   DALI_LOG_INFO( gLogFilter, Debug::General, oss.str().c_str() );
121 #endif
122
123   // Find visualName in the control
124   RegisteredVisualContainer::Iterator iter;
125   for ( iter = visuals.Begin(); iter != visuals.End(); iter++ )
126   {
127     if ( (*iter)->visual.GetName() == visualName )
128     {
129       break;
130     }
131   }
132
133   // Does either it's renderer or placement actor have an associated property?
134   if( iter != visuals.End() )
135   {
136     Actor placementActor = (*iter)->placementActor;
137     if( !placementActor )
138     {
139       placementActor = controlImpl.Self();
140     }
141
142     Property::Index index = placementActor.GetPropertyIndex( propertyKey );
143     if( index != Property::INVALID_INDEX )
144     {
145       // It's a placement actor property:
146       return HandleIndex( placementActor, index );
147     }
148     else
149     {
150       // Check if it is a renderer property:
151       if( placementActor.GetRendererCount() > 0 )
152       {
153         // @todo Need to use correct renderer index when placement actors
154         // are removed
155         Renderer renderer = placementActor.GetRendererAt(0);
156         Property::Index index = renderer.GetPropertyIndex( propertyKey );
157         if( index != Property::INVALID_INDEX )
158         {
159           // It's a renderer property:
160           return HandleIndex( renderer, index );
161         }
162       }
163       else
164       {
165         std::ostringstream oss;
166         oss << propertyKey;
167         DALI_LOG_WARNING( "Control::GetHandleIndex(%s, %s) No renderers\n", visualName.c_str(), oss.str().c_str() );
168       }
169     }
170   }
171   Handle handle;
172   return HandleIndex( handle, Property::INVALID_INDEX );
173 }
174
175
176 /**
177  * Creates control through type registry
178  */
179 BaseHandle Create()
180 {
181   return Internal::Control::New();
182 }
183
184 /**
185  * Performs actions as requested using the action name.
186  * @param[in] object The object on which to perform the action.
187  * @param[in] actionName The action to perform.
188  * @param[in] attributes The attributes with which to perfrom this action.
189  * @return true if action has been accepted by this control
190  */
191 const char* ACTION_ACCESSIBILITY_ACTIVATED = "accessibilityActivated";
192 static bool DoAction( BaseObject* object, const std::string& actionName, const Property::Map& attributes )
193 {
194   bool ret = false;
195
196   if( object && ( 0 == strcmp( actionName.c_str(), ACTION_ACCESSIBILITY_ACTIVATED ) ) )
197   {
198     Toolkit::Control control = Toolkit::Control::DownCast( BaseHandle( object ) );
199     if( control )
200     {
201       // if cast succeeds there is an implementation so no need to check
202       ret = Internal::GetImplementation( control ).OnAccessibilityActivated();
203     }
204   }
205
206   return ret;
207 }
208
209 /**
210  * Connects a callback function with the object's signals.
211  * @param[in] object The object providing the signal.
212  * @param[in] tracker Used to disconnect the signal.
213  * @param[in] signalName The signal to connect to.
214  * @param[in] functor A newly allocated FunctorDelegate.
215  * @return True if the signal was connected.
216  * @post If a signal was connected, ownership of functor was passed to CallbackBase. Otherwise the caller is responsible for deleting the unused functor.
217  */
218 const char* SIGNAL_KEY_EVENT = "keyEvent";
219 const char* SIGNAL_KEY_INPUT_FOCUS_GAINED = "keyInputFocusGained";
220 const char* SIGNAL_KEY_INPUT_FOCUS_LOST = "keyInputFocusLost";
221 const char* SIGNAL_TAPPED = "tapped";
222 const char* SIGNAL_PANNED = "panned";
223 const char* SIGNAL_PINCHED = "pinched";
224 const char* SIGNAL_LONG_PRESSED = "longPressed";
225 static bool DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
226 {
227   Dali::BaseHandle handle( object );
228
229   bool connected( false );
230   Toolkit::Control control = Toolkit::Control::DownCast( handle );
231   if ( control )
232   {
233     Internal::Control& controlImpl( Internal::GetImplementation( control ) );
234     connected = true;
235
236     if ( 0 == strcmp( signalName.c_str(), SIGNAL_KEY_EVENT ) )
237     {
238       controlImpl.KeyEventSignal().Connect( tracker, functor );
239     }
240     else if( 0 == strcmp( signalName.c_str(), SIGNAL_KEY_INPUT_FOCUS_GAINED ) )
241     {
242       controlImpl.KeyInputFocusGainedSignal().Connect( tracker, functor );
243     }
244     else if( 0 == strcmp( signalName.c_str(), SIGNAL_KEY_INPUT_FOCUS_LOST ) )
245     {
246       controlImpl.KeyInputFocusLostSignal().Connect( tracker, functor );
247     }
248     else if( 0 == strcmp( signalName.c_str(), SIGNAL_TAPPED ) )
249     {
250       controlImpl.EnableGestureDetection( Gesture::Tap );
251       controlImpl.GetTapGestureDetector().DetectedSignal().Connect( tracker, functor );
252     }
253     else if( 0 == strcmp( signalName.c_str(), SIGNAL_PANNED ) )
254     {
255       controlImpl.EnableGestureDetection( Gesture::Pan );
256       controlImpl.GetPanGestureDetector().DetectedSignal().Connect( tracker, functor );
257     }
258     else if( 0 == strcmp( signalName.c_str(), SIGNAL_PINCHED ) )
259     {
260       controlImpl.EnableGestureDetection( Gesture::Pinch );
261       controlImpl.GetPinchGestureDetector().DetectedSignal().Connect( tracker, functor );
262     }
263     else if( 0 == strcmp( signalName.c_str(), SIGNAL_LONG_PRESSED ) )
264     {
265       controlImpl.EnableGestureDetection( Gesture::LongPress );
266       controlImpl.GetLongPressGestureDetector().DetectedSignal().Connect( tracker, functor );
267     }
268   }
269   return connected;
270 }
271
272 // Setup signals and actions using the type-registry.
273 DALI_TYPE_REGISTRATION_BEGIN( Control, CustomActor, Create );
274
275 // Note: Properties are registered separately below.
276
277 SignalConnectorType registerSignal1( typeRegistration, SIGNAL_KEY_EVENT, &DoConnectSignal );
278 SignalConnectorType registerSignal2( typeRegistration, SIGNAL_KEY_INPUT_FOCUS_GAINED, &DoConnectSignal );
279 SignalConnectorType registerSignal3( typeRegistration, SIGNAL_KEY_INPUT_FOCUS_LOST, &DoConnectSignal );
280 SignalConnectorType registerSignal4( typeRegistration, SIGNAL_TAPPED, &DoConnectSignal );
281 SignalConnectorType registerSignal5( typeRegistration, SIGNAL_PANNED, &DoConnectSignal );
282 SignalConnectorType registerSignal6( typeRegistration, SIGNAL_PINCHED, &DoConnectSignal );
283 SignalConnectorType registerSignal7( typeRegistration, SIGNAL_LONG_PRESSED, &DoConnectSignal );
284
285 TypeAction registerAction( typeRegistration, ACTION_ACCESSIBILITY_ACTIVATED, &DoAction );
286
287 DALI_TYPE_REGISTRATION_END()
288
289 } // unnamed namespace
290
291 namespace Internal
292 {
293
294 class Control::Impl : public ConnectionTracker
295 {
296 public:
297
298   // Construction & Destruction
299   Impl(Control& controlImpl)
300   : mControlImpl( controlImpl ),
301     mStyleName(""),
302     mBackgroundVisual(),
303     mBackgroundColor(Color::TRANSPARENT),
304     mStartingPinchScale( NULL ),
305     mKeyEventSignal(),
306     mPinchGestureDetector(),
307     mPanGestureDetector(),
308     mTapGestureDetector(),
309     mLongPressGestureDetector(),
310     mFlags( Control::ControlBehaviour( CONTROL_BEHAVIOUR_DEFAULT ) ),
311     mIsKeyboardNavigationSupported( false ),
312     mIsKeyboardFocusGroup( false )
313   {
314   }
315
316   ~Impl()
317   {
318     // All gesture detectors will be destroyed so no need to disconnect.
319     delete mStartingPinchScale;
320   }
321
322   // Gesture Detection Methods
323
324   void PinchDetected(Actor actor, const PinchGesture& pinch)
325   {
326     mControlImpl.OnPinch(pinch);
327   }
328
329   void PanDetected(Actor actor, const PanGesture& pan)
330   {
331     mControlImpl.OnPan(pan);
332   }
333
334   void TapDetected(Actor actor, const TapGesture& tap)
335   {
336     mControlImpl.OnTap(tap);
337   }
338
339   void LongPressDetected(Actor actor, const LongPressGesture& longPress)
340   {
341     mControlImpl.OnLongPress(longPress);
342   }
343
344   // Properties
345
346   /**
347    * Called when a property of an object of this type is set.
348    * @param[in] object The object whose property is set.
349    * @param[in] index The property index.
350    * @param[in] value The new property value.
351    */
352   static void SetProperty( BaseObject* object, Property::Index index, const Property::Value& value )
353   {
354     Toolkit::Control control = Toolkit::Control::DownCast( BaseHandle( object ) );
355
356     if ( control )
357     {
358       Control& controlImpl( GetImplementation( control ) );
359
360       switch ( index )
361       {
362         case Toolkit::Control::Property::STYLE_NAME:
363         {
364           controlImpl.SetStyleName( value.Get< std::string >() );
365           break;
366         }
367
368         case Toolkit::Control::Property::BACKGROUND_COLOR:
369         {
370           DALI_LOG_WARNING( "BACKGROUND_COLOR property is deprecated. Use BACKGROUND property instead\n" );
371           controlImpl.SetBackgroundColor( value.Get< Vector4 >() );
372           break;
373         }
374
375         case Toolkit::Control::Property::BACKGROUND_IMAGE:
376         {
377           DALI_LOG_WARNING( "BACKGROUND_IMAGE property is deprecated. Use BACKGROUND property instead\n" );
378           Image image = Scripting::NewImage( value );
379           if ( image )
380           {
381             controlImpl.SetBackgroundImage( image );
382           }
383           else
384           {
385             // An empty map means the background is no longer required
386             controlImpl.ClearBackground();
387           }
388           break;
389         }
390
391         case Toolkit::Control::Property::KEY_INPUT_FOCUS:
392         {
393           if ( value.Get< bool >() )
394           {
395             controlImpl.SetKeyInputFocus();
396           }
397           else
398           {
399             controlImpl.ClearKeyInputFocus();
400           }
401           break;
402         }
403
404         case Toolkit::Control::Property::BACKGROUND:
405         {
406           const Property::Map* map = value.GetMap();
407           if( map )
408           {
409             controlImpl.SetBackground( *map );
410           }
411           else
412           {
413             // The background is not a property map, so we should clear the background
414             controlImpl.ClearBackground();
415           }
416           break;
417         }
418       }
419     }
420   }
421
422   /**
423    * Called to retrieve a property of an object of this type.
424    * @param[in] object The object whose property is to be retrieved.
425    * @param[in] index The property index.
426    * @return The current value of the property.
427    */
428   static Property::Value GetProperty( BaseObject* object, Property::Index index )
429   {
430     Property::Value value;
431
432     Toolkit::Control control = Toolkit::Control::DownCast( BaseHandle( object ) );
433
434     if ( control )
435     {
436       Control& controlImpl( GetImplementation( control ) );
437
438       switch ( index )
439       {
440         case Toolkit::Control::Property::STYLE_NAME:
441         {
442           value = controlImpl.GetStyleName();
443           break;
444         }
445
446         case Toolkit::Control::Property::BACKGROUND_COLOR:
447         {
448           DALI_LOG_WARNING( "BACKGROUND_COLOR property is deprecated. Use BACKGROUND property instead\n" );
449           value = controlImpl.GetBackgroundColor();
450           break;
451         }
452
453         case Toolkit::Control::Property::BACKGROUND_IMAGE:
454         {
455           DALI_LOG_WARNING( "BACKGROUND_IMAGE property is deprecated. Use BACKGROUND property instead\n" );
456           Property::Map map;
457           if( controlImpl.mImpl->mBackgroundVisual )
458           {
459             controlImpl.mImpl->mBackgroundVisual.CreatePropertyMap( map );
460           }
461           value = map;
462           break;
463         }
464
465         case Toolkit::Control::Property::KEY_INPUT_FOCUS:
466         {
467           value = controlImpl.HasKeyInputFocus();
468           break;
469         }
470
471         case Toolkit::Control::Property::BACKGROUND:
472         {
473           Property::Map map;
474           if( controlImpl.mImpl->mBackgroundVisual )
475           {
476             (controlImpl.mImpl->mBackgroundVisual).CreatePropertyMap( map );
477           }
478
479           value = map;
480           break;
481         }
482
483       }
484     }
485
486     return value;
487   }
488
489   // Data
490
491   Control& mControlImpl;
492   RegisteredVisualContainer mVisuals; // Stores visuals needed by the control, non trivial type so std::vector used.
493   std::string mStyleName;
494   Toolkit::Visual::Base mBackgroundVisual;   ///< The visual to render the background
495   Vector4 mBackgroundColor;                       ///< The color of the background visual
496   Vector3* mStartingPinchScale;      ///< The scale when a pinch gesture starts, TODO: consider removing this
497   Toolkit::Control::KeyEventSignalType mKeyEventSignal;
498   Toolkit::Control::KeyInputFocusSignalType mKeyInputFocusGainedSignal;
499   Toolkit::Control::KeyInputFocusSignalType mKeyInputFocusLostSignal;
500
501   // Gesture Detection
502   PinchGestureDetector mPinchGestureDetector;
503   PanGestureDetector mPanGestureDetector;
504   TapGestureDetector mTapGestureDetector;
505   LongPressGestureDetector mLongPressGestureDetector;
506
507   ControlBehaviour mFlags : CONTROL_BEHAVIOUR_FLAG_COUNT;    ///< Flags passed in from constructor.
508   bool mIsKeyboardNavigationSupported :1;  ///< Stores whether keyboard navigation is supported by the control.
509   bool mIsKeyboardFocusGroup :1;           ///< Stores whether the control is a focus group.
510
511   // Properties - these need to be members of Internal::Control::Impl as they need to function within this class.
512   static const PropertyRegistration PROPERTY_1;
513   static const PropertyRegistration PROPERTY_2;
514   static const PropertyRegistration PROPERTY_3;
515   static const PropertyRegistration PROPERTY_4;
516   static const PropertyRegistration PROPERTY_5;
517 };
518
519 // Properties registered without macro to use specific member variables.
520 const PropertyRegistration Control::Impl::PROPERTY_1( typeRegistration, "styleName",       Toolkit::Control::Property::STYLE_NAME,       Property::STRING,  &Control::Impl::SetProperty, &Control::Impl::GetProperty );
521 const PropertyRegistration Control::Impl::PROPERTY_2( typeRegistration, "backgroundColor", Toolkit::Control::Property::BACKGROUND_COLOR, Property::VECTOR4, &Control::Impl::SetProperty, &Control::Impl::GetProperty );
522 const PropertyRegistration Control::Impl::PROPERTY_3( typeRegistration, "backgroundImage", Toolkit::Control::Property::BACKGROUND_IMAGE, Property::MAP,     &Control::Impl::SetProperty, &Control::Impl::GetProperty );
523 const PropertyRegistration Control::Impl::PROPERTY_4( typeRegistration, "keyInputFocus",   Toolkit::Control::Property::KEY_INPUT_FOCUS,  Property::BOOLEAN, &Control::Impl::SetProperty, &Control::Impl::GetProperty );
524 const PropertyRegistration Control::Impl::PROPERTY_5( typeRegistration, "background",      Toolkit::Control::Property::BACKGROUND,       Property::MAP,     &Control::Impl::SetProperty, &Control::Impl::GetProperty );
525
526 Toolkit::Control Control::New()
527 {
528   // Create the implementation, temporarily owned on stack
529   IntrusivePtr<Control> controlImpl = new Control( ControlBehaviour( CONTROL_BEHAVIOUR_DEFAULT ) );
530
531   // Pass ownership to handle
532   Toolkit::Control handle( *controlImpl );
533
534   // Second-phase init of the implementation
535   // This can only be done after the CustomActor connection has been made...
536   controlImpl->Initialize();
537
538   return handle;
539 }
540
541 Control::~Control()
542 {
543   delete mImpl;
544 }
545
546 void Control::SetStyleName( const std::string& styleName )
547 {
548   if( styleName != mImpl->mStyleName )
549   {
550     mImpl->mStyleName = styleName;
551
552     // Apply new style, if stylemanager is available
553     Toolkit::StyleManager styleManager = Toolkit::StyleManager::Get();
554     if( styleManager )
555     {
556       GetImpl( styleManager ).ApplyThemeStyle( Toolkit::Control( GetOwner() ) );
557     }
558   }
559 }
560
561 const std::string& Control::GetStyleName() const
562 {
563   return mImpl->mStyleName;
564 }
565
566 void Control::SetBackgroundColor( const Vector4& color )
567 {
568   Actor self( Self() );
569   mImpl->mBackgroundColor = color;
570   Property::Map map;
571   map[ Toolkit::VisualProperty::TYPE ] = Toolkit::Visual::COLOR;
572   map[ Toolkit::ColorVisual::Property::MIX_COLOR ] = color;
573   mImpl->mBackgroundVisual = Toolkit::VisualFactory::Get().CreateVisual( map );
574   RegisterVisual( Toolkit::Control::Property::BACKGROUND, self, mImpl->mBackgroundVisual );
575   if( mImpl->mBackgroundVisual )
576   {
577     mImpl->mBackgroundVisual.SetDepthIndex( DepthIndex::BACKGROUND );
578   }
579 }
580
581 Vector4 Control::GetBackgroundColor() const
582 {
583   return mImpl->mBackgroundColor;
584 }
585
586 void Control::SetBackground( const Property::Map& map )
587 {
588   Actor self( Self() );
589   mImpl->mBackgroundVisual = Toolkit::VisualFactory::Get().CreateVisual( map );
590   RegisterVisual( Toolkit::Control::Property::BACKGROUND, self, mImpl->mBackgroundVisual );
591   if( mImpl->mBackgroundVisual )
592   {
593     mImpl->mBackgroundVisual.SetDepthIndex( DepthIndex::BACKGROUND );
594   }
595 }
596
597 void Control::SetBackgroundImage( Image image )
598 {
599   Actor self( Self() );
600   mImpl->mBackgroundVisual = Toolkit::VisualFactory::Get().CreateVisual( image );
601   RegisterVisual( Toolkit::Control::Property::BACKGROUND, self, mImpl->mBackgroundVisual );
602   if( mImpl->mBackgroundVisual )
603   {
604     mImpl->mBackgroundVisual.SetDepthIndex( DepthIndex::BACKGROUND );
605   }
606 }
607
608 void Control::ClearBackground()
609 {
610   Actor self( Self() );
611   mImpl->mBackgroundVisual.RemoveAndReset( self );
612   mImpl->mBackgroundColor = Color::TRANSPARENT;
613 }
614
615 void Control::EnableGestureDetection(Gesture::Type type)
616 {
617   if ( (type & Gesture::Pinch) && !mImpl->mPinchGestureDetector )
618   {
619     mImpl->mPinchGestureDetector = PinchGestureDetector::New();
620     mImpl->mPinchGestureDetector.DetectedSignal().Connect(mImpl, &Impl::PinchDetected);
621     mImpl->mPinchGestureDetector.Attach(Self());
622   }
623
624   if ( (type & Gesture::Pan) && !mImpl->mPanGestureDetector )
625   {
626     mImpl->mPanGestureDetector = PanGestureDetector::New();
627     mImpl->mPanGestureDetector.DetectedSignal().Connect(mImpl, &Impl::PanDetected);
628     mImpl->mPanGestureDetector.Attach(Self());
629   }
630
631   if ( (type & Gesture::Tap) && !mImpl->mTapGestureDetector )
632   {
633     mImpl->mTapGestureDetector = TapGestureDetector::New();
634     mImpl->mTapGestureDetector.DetectedSignal().Connect(mImpl, &Impl::TapDetected);
635     mImpl->mTapGestureDetector.Attach(Self());
636   }
637
638   if ( (type & Gesture::LongPress) && !mImpl->mLongPressGestureDetector )
639   {
640     mImpl->mLongPressGestureDetector = LongPressGestureDetector::New();
641     mImpl->mLongPressGestureDetector.DetectedSignal().Connect(mImpl, &Impl::LongPressDetected);
642     mImpl->mLongPressGestureDetector.Attach(Self());
643   }
644 }
645
646 void Control::DisableGestureDetection(Gesture::Type type)
647 {
648   if ( (type & Gesture::Pinch) && mImpl->mPinchGestureDetector )
649   {
650     mImpl->mPinchGestureDetector.Detach(Self());
651     mImpl->mPinchGestureDetector.Reset();
652   }
653
654   if ( (type & Gesture::Pan) && mImpl->mPanGestureDetector )
655   {
656     mImpl->mPanGestureDetector.Detach(Self());
657     mImpl->mPanGestureDetector.Reset();
658   }
659
660   if ( (type & Gesture::Tap) && mImpl->mTapGestureDetector )
661   {
662     mImpl->mTapGestureDetector.Detach(Self());
663     mImpl->mTapGestureDetector.Reset();
664   }
665
666   if ( (type & Gesture::LongPress) && mImpl->mLongPressGestureDetector)
667   {
668     mImpl->mLongPressGestureDetector.Detach(Self());
669     mImpl->mLongPressGestureDetector.Reset();
670   }
671 }
672
673 PinchGestureDetector Control::GetPinchGestureDetector() const
674 {
675   return mImpl->mPinchGestureDetector;
676 }
677
678 PanGestureDetector Control::GetPanGestureDetector() const
679 {
680   return mImpl->mPanGestureDetector;
681 }
682
683 TapGestureDetector Control::GetTapGestureDetector() const
684 {
685   return mImpl->mTapGestureDetector;
686 }
687
688 LongPressGestureDetector Control::GetLongPressGestureDetector() const
689 {
690   return mImpl->mLongPressGestureDetector;
691 }
692
693 void Control::SetKeyboardNavigationSupport(bool isSupported)
694 {
695   mImpl->mIsKeyboardNavigationSupported = isSupported;
696 }
697
698 bool Control::IsKeyboardNavigationSupported()
699 {
700   return mImpl->mIsKeyboardNavigationSupported;
701 }
702
703 void Control::SetKeyInputFocus()
704 {
705   if( Self().OnStage() )
706   {
707     Toolkit::KeyInputFocusManager::Get().SetFocus(Toolkit::Control::DownCast(Self()));
708   }
709 }
710
711 bool Control::HasKeyInputFocus()
712 {
713   bool result = false;
714   if( Self().OnStage() )
715   {
716     result = Toolkit::KeyInputFocusManager::Get().IsKeyboardListener(Toolkit::Control::DownCast(Self()));
717   }
718   return result;
719 }
720
721 void Control::ClearKeyInputFocus()
722 {
723   if( Self().OnStage() )
724   {
725     Toolkit::KeyInputFocusManager::Get().RemoveFocus(Toolkit::Control::DownCast(Self()));
726   }
727 }
728
729 void Control::SetAsKeyboardFocusGroup(bool isFocusGroup)
730 {
731   mImpl->mIsKeyboardFocusGroup = isFocusGroup;
732
733   // The following line will be removed when the deprecated API in KeyboardFocusManager is deleted
734   Toolkit::KeyboardFocusManager::Get().SetAsFocusGroup(Self(), isFocusGroup);
735 }
736
737 bool Control::IsKeyboardFocusGroup()
738 {
739   return Toolkit::KeyboardFocusManager::Get().IsFocusGroup(Self());
740 }
741
742 void Control::AccessibilityActivate()
743 {
744   // Inform deriving classes
745   OnAccessibilityActivated();
746 }
747
748 void Control::KeyboardEnter()
749 {
750   // Inform deriving classes
751   OnKeyboardEnter();
752 }
753
754 void Control::RegisterVisual( Property::Index index, Actor& placementActor, Toolkit::Visual::Base& visual )
755 {
756   RegisterVisual( index, placementActor, visual, true );
757 }
758
759 void Control::RegisterVisual( Property::Index index, Actor& placementActor, Toolkit::Visual::Base& visual, bool enabled )
760 {
761   bool visualReplaced ( false );
762   Actor actorToRegister; // Null actor, replaced if placement actor not Self
763   Actor self = Self();
764
765   if ( placementActor != self ) // Prevent increasing ref count if actor self
766   {
767     actorToRegister = placementActor;
768   }
769
770   if ( !mImpl->mVisuals.Empty() )
771   {
772       RegisteredVisualContainer::Iterator iter;
773       // Check if visual (index) is already registered.  Replace if so.
774       if ( FindVisual( index, mImpl->mVisuals, iter ) )
775       {
776         if( (*iter)->visual && self.OnStage() )
777         {
778           if( (*iter)->placementActor )
779           {
780             (*iter)->visual.SetOffStage( (*iter)->placementActor );
781           }
782           else
783           {
784             (*iter)->visual.SetOffStage( self );
785           }
786         }
787         (*iter)->visual = visual;
788         (*iter)->placementActor = actorToRegister;
789         visualReplaced = true;
790       }
791   }
792
793   if ( !visualReplaced ) // New registration entry
794   {
795     mImpl->mVisuals.PushBack( new RegisteredVisual( index, visual, actorToRegister, enabled ) );
796   }
797
798   if( visual && self.OnStage() && enabled )
799   {
800     visual.SetOnStage( placementActor );
801   }
802 }
803
804 void Control::UnregisterVisual( Property::Index index )
805 {
806    RegisteredVisualContainer::Iterator iter;
807    if ( FindVisual( index, mImpl->mVisuals, iter ) )
808    {
809      mImpl->mVisuals.Erase( iter );
810    }
811 }
812
813 Toolkit::Visual::Base Control::GetVisual( Property::Index index ) const
814 {
815   RegisteredVisualContainer::Iterator iter;
816   if ( FindVisual( index, mImpl->mVisuals, iter ) )
817   {
818     return (*iter)->visual;
819   }
820
821   return Toolkit::Visual::Base();
822 }
823
824 void Control::EnableVisual( Property::Index index, bool enable )
825 {
826   RegisteredVisualContainer::Iterator iter;
827   if ( FindVisual( index, mImpl->mVisuals, iter ) )
828   {
829     if (  (*iter)->enabled == enable )
830     {
831       return;
832     }
833
834     (*iter)->enabled = enable;
835     Actor parentActor = Self();
836     if ( (*iter)->placementActor )
837     {
838       parentActor = (*iter)->placementActor;
839     }
840
841     if ( Self().OnStage() ) // If control not on Stage then Visual will be added when StageConnection is called.
842     {
843       if ( enable )
844       {
845
846         (*iter)->visual.SetOnStage( parentActor );
847       }
848       else
849       {
850         (*iter)->visual.SetOffStage( parentActor );  // No need to call if control not staged.
851       }
852     }
853   }
854 }
855
856 bool Control::IsVisualEnabled( Property::Index index ) const
857 {
858   RegisteredVisualContainer::Iterator iter;
859   if ( FindVisual( index, mImpl->mVisuals, iter ) )
860   {
861     return (*iter)->enabled;
862   }
863   return false;
864 }
865
866 Actor Control::GetPlacementActor( Property::Index index ) const
867 {
868   RegisteredVisualContainer::Iterator iter;
869   if ( FindVisual( index, mImpl->mVisuals, iter ) )
870   {
871     if( (*iter)->placementActor )
872     {
873       return (*iter)->placementActor;
874     }
875     else
876     {
877       return Self();
878     }
879   }
880
881   return Actor();
882 }
883
884 Dali::Animation Control::CreateTransition( const Toolkit::TransitionData& handle )
885 {
886   Dali::Animation transition;
887   const Internal::TransitionData& transitionData = Toolkit::GetImplementation( handle );
888
889   if( transitionData.Count() > 0 )
890   {
891     // Setup a Transition from TransitionData.
892     TransitionData::Iterator end = transitionData.End();
893     for( TransitionData::Iterator iter = transitionData.Begin() ;
894          iter != end; ++iter )
895     {
896       TransitionData::Animator* animator = (*iter);
897       HandleIndex handleIndex;
898
899       // Attempt to find the object name as a child actor
900       Actor child = Self().FindChildByName( animator->objectName );
901       if( child )
902       {
903         Property::Index propertyIndex = child.GetPropertyIndex( animator->propertyKey );
904         handleIndex = HandleIndex( child, propertyIndex );
905       }
906       else
907       {
908         // Is it a placement actor/visual pair?;
909         handleIndex = GetVisualProperty( *this, mImpl->mVisuals,
910                                             animator->objectName,
911                                             animator->propertyKey );
912       }
913
914       if( handleIndex.handle && handleIndex.index != Property::INVALID_INDEX )
915       {
916         if( animator->animate == false )
917         {
918           if( animator->targetValue.GetType() != Property::NONE )
919           {
920             handleIndex.handle.SetProperty( handleIndex.index, animator->targetValue );
921           }
922         }
923         else
924         {
925           if( animator->initialValue.GetType() != Property::NONE )
926           {
927             handleIndex.handle.SetProperty( handleIndex.index, animator->initialValue );
928           }
929
930           if( ! transition )
931           {
932             // Create an animation with a default .1 second duration - the animators
933             // will automatically force it to the 'right' duration.
934             transition = Dali::Animation::New( 0.1f );
935           }
936
937           transition.AnimateTo( Property( handleIndex.handle, handleIndex.index ),
938                                 animator->targetValue,
939                                 animator->alphaFunction,
940                                 TimePeriod( animator->timePeriodDelay,
941                                             animator->timePeriodDuration ) );
942         }
943       }
944     }
945   }
946
947   return transition;
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