ff0a2bc335248bcc4d61830d3606d7860686cbbf
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / public-api / controls / control-impl.cpp
1 /*
2  * Copyright (c) 2015 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/actors/image-actor.h>
26 #include <dali/devel-api/actors/mesh-actor.h>
27 #include <dali/public-api/animation/constraint.h>
28 #include <dali/public-api/animation/constraints.h>
29 #include <dali/devel-api/geometry/mesh.h>
30 #include <dali/public-api/object/type-registry.h>
31 #include <dali/devel-api/object/type-registry-helper.h>
32 #include <dali/devel-api/scripting/scripting.h>
33 #include <dali/public-api/size-negotiation/relayout-container.h>
34 #include <dali/integration-api/debug.h>
35
36 // INTERNAL INCLUDES
37 #include <dali-toolkit/public-api/focus-manager/keyinput-focus-manager.h>
38 #include <dali-toolkit/public-api/focus-manager/keyboard-focus-manager.h>
39 #include <dali-toolkit/public-api/controls/control.h>
40 #include <dali-toolkit/devel-api/styling/style-manager.h>
41 #include <dali-toolkit/internal/styling/style-manager-impl.h>
42
43 namespace Dali
44 {
45
46 namespace Toolkit
47 {
48
49 namespace
50 {
51
52 #if defined(DEBUG_ENABLED)
53 Integration::Log::Filter* gLogFilter  = Integration::Log::Filter::New(Debug::NoLogging, false, "LOG_CONTROL");
54 #endif
55
56 const float MAX_FLOAT_VALUE( std::numeric_limits<float>::max() );
57 const Vector3 MAX_SIZE( MAX_FLOAT_VALUE, MAX_FLOAT_VALUE, MAX_FLOAT_VALUE );
58 const float BACKGROUND_ACTOR_Z_POSITION( -0.1f );
59
60 BaseHandle Create()
61 {
62   return Internal::Control::New();
63 }
64
65 // Setup signals and actions using the type-registry.
66 DALI_TYPE_REGISTRATION_BEGIN( Control, CustomActor, Create );
67
68 // Note: Properties are registered separately below.
69
70 DALI_SIGNAL_REGISTRATION( Toolkit, Control, "key-event",              SIGNAL_KEY_EVENT              )
71 DALI_SIGNAL_REGISTRATION( Toolkit, Control, "key-input-focus-gained", SIGNAL_KEY_INPUT_FOCUS_GAINED )
72 DALI_SIGNAL_REGISTRATION( Toolkit, Control, "key-input-focus-lost",   SIGNAL_KEY_INPUT_FOCUS_LOST   )
73 DALI_SIGNAL_REGISTRATION( Toolkit, Control, "tapped",                 SIGNAL_TAPPED                 )
74 DALI_SIGNAL_REGISTRATION( Toolkit, Control, "panned",                 SIGNAL_PANNED                 )
75 DALI_SIGNAL_REGISTRATION( Toolkit, Control, "pinched",                SIGNAL_PINCHED                )
76 DALI_SIGNAL_REGISTRATION( Toolkit, Control, "long-pressed",           SIGNAL_LONG_PRESSED           )
77
78 DALI_ACTION_REGISTRATION( Toolkit, Control, "control-activated",      ACTION_CONTROL_ACTIVATED      )
79
80 DALI_TYPE_REGISTRATION_END()
81
82 /**
83  * Structure which holds information about the background of a control
84  */
85 struct Background
86 {
87   Actor actor;   ///< Either a MeshActor or an ImageActor
88   Vector4 color; ///< The color of the actor.
89
90   /**
91    * Constructor
92    */
93   Background()
94   : actor(),
95     color( Color::WHITE )
96   {
97   }
98 };
99
100 /**
101  * Creates a white coloured Mesh.
102  */
103 Mesh CreateMesh()
104 {
105   Vector3 white( Color::WHITE );
106
107   MeshData meshData;
108
109   // Create vertices with a white color (actual color is set by actor color)
110   MeshData::VertexContainer vertices(4);
111   vertices[ 0 ] = MeshData::Vertex( Vector3( -0.5f, -0.5f, 0.0f ), Vector2::ZERO, white );
112   vertices[ 1 ] = MeshData::Vertex( Vector3(  0.5f, -0.5f, 0.0f ), Vector2::ZERO, white );
113   vertices[ 2 ] = MeshData::Vertex( Vector3( -0.5f,  0.5f, 0.0f ), Vector2::ZERO, white );
114   vertices[ 3 ] = MeshData::Vertex( Vector3(  0.5f,  0.5f, 0.0f ), Vector2::ZERO, white );
115
116   // Specify all the faces
117   MeshData::FaceIndices faces;
118   faces.reserve( 6 ); // 2 triangles in Quad
119   faces.push_back( 0 ); faces.push_back( 3 ); faces.push_back( 1 );
120   faces.push_back( 0 ); faces.push_back( 2 ); faces.push_back( 3 );
121
122   // Create the mesh data from the vertices and faces
123   meshData.SetMaterial( Material::New( "ControlMaterial" ) );
124   meshData.SetVertices( vertices );
125   meshData.SetFaceIndices( faces );
126   meshData.SetHasColor( true );
127
128   return Mesh::New( meshData );
129 }
130
131 /**
132  * Sets all the required properties for the background actor.
133  *
134  * @param[in]  actor              The actor to set the properties on.
135  * @param[in]  color              The required color of the actor.
136  */
137 void SetupBackgroundActor( Actor actor, const Vector4& color )
138 {
139   actor.SetColor( color );
140   actor.SetPositionInheritanceMode( USE_PARENT_POSITION_PLUS_LOCAL_POSITION );
141   actor.SetColorMode( USE_OWN_MULTIPLY_PARENT_COLOR );
142   actor.SetZ( BACKGROUND_ACTOR_Z_POSITION );
143   actor.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
144 }
145
146 /**
147  * Sets all the required properties for the background actor.
148  *
149  * @param[in]  actor              The actor to set the properties on.
150  * @param[in]  constrainingIndex  The property index to constrain the parent's size on.
151  * @param[in]  color              The required color of the actor.
152  */
153 void SetupBackgroundActorConstrained( Actor actor, Property::Index constrainingIndex, const Vector4& color )
154 {
155   actor.SetColor( color );
156   actor.SetPositionInheritanceMode( USE_PARENT_POSITION_PLUS_LOCAL_POSITION );
157   actor.SetColorMode( USE_OWN_MULTIPLY_PARENT_COLOR );
158   actor.SetZ( BACKGROUND_ACTOR_Z_POSITION );
159
160   Constraint constraint = Constraint::New<Vector3>( actor,
161                                                     constrainingIndex,
162                                                     EqualToConstraint() );
163   constraint.AddSource( ParentSource( Actor::Property::SIZE ) );
164   constraint.Apply();
165 }
166
167 } // unnamed namespace
168
169 namespace Internal
170 {
171
172 class Control::Impl : public ConnectionTracker
173 {
174 public:
175
176   /**
177    * Size indices for mMinMaxSize array
178    */
179   enum
180   {
181     MIN_SIZE_INDEX = 0,
182     MAX_SIZE_INDEX = 1
183   };
184
185 public:
186   // Construction & Destruction
187   Impl(Control& controlImpl)
188   : mControlImpl( controlImpl ),
189     mStyleName(""),
190     mBackground( NULL ),
191     mStartingPinchScale( NULL ),
192     mKeyEventSignal(),
193     mPinchGestureDetector(),
194     mPanGestureDetector(),
195     mTapGestureDetector(),
196     mLongPressGestureDetector(),
197     mCurrentSize(),
198     mNaturalSize(),
199     mFlags( Control::ControlBehaviour( ACTOR_BEHAVIOUR_NONE ) ),
200     mIsKeyboardNavigationSupported( false ),
201     mIsKeyboardFocusGroup( false ),
202     mInitialized( false )
203   {
204   }
205
206   ~Impl()
207   {
208     // All gesture detectors will be destroyed so no need to disconnect.
209     delete mBackground;
210     delete mStartingPinchScale;
211   }
212
213   // Gesture Detection Methods
214
215   void PinchDetected(Actor actor, const PinchGesture& pinch)
216   {
217     mControlImpl.OnPinch(pinch);
218   }
219
220   void PanDetected(Actor actor, const PanGesture& pan)
221   {
222     mControlImpl.OnPan(pan);
223   }
224
225   void TapDetected(Actor actor, const TapGesture& tap)
226   {
227     mControlImpl.OnTap(tap);
228   }
229
230   void LongPressDetected(Actor actor, const LongPressGesture& longPress)
231   {
232     mControlImpl.OnLongPress(longPress);
233   }
234
235   // Background Methods
236
237   /**
238    * Only creates an instance of the background if we actually use it.
239    * @return A reference to the Background structure.
240    */
241   Background& GetBackground()
242   {
243     if ( !mBackground )
244     {
245       mBackground = new Background;
246     }
247     return *mBackground;
248   }
249
250   // Properties
251
252   /**
253    * Called when a property of an object of this type is set.
254    * @param[in] object The object whose property is set.
255    * @param[in] index The property index.
256    * @param[in] value The new property value.
257    */
258   static void SetProperty( BaseObject* object, Property::Index index, const Property::Value& value )
259   {
260     Toolkit::Control control = Toolkit::Control::DownCast( BaseHandle( object ) );
261
262     if ( control )
263     {
264       Control& controlImpl( control.GetImplementation() );
265
266       switch ( index )
267       {
268         case Toolkit::Control::Property::STYLE_NAME:
269         {
270           controlImpl.SetStyleName( value.Get< std::string >() );
271           break;
272         }
273
274         case Toolkit::Control::Property::BACKGROUND_COLOR:
275         {
276           controlImpl.SetBackgroundColor( value.Get< Vector4 >() );
277           break;
278         }
279
280         case Toolkit::Control::Property::BACKGROUND_IMAGE:
281         {
282           if ( value.HasKey( "image" ) )
283           {
284             Property::Map imageMap = value.GetValue( "image" ).Get< Property::Map >();
285             Image image = Scripting::NewImage( imageMap );
286
287             if ( image )
288             {
289               controlImpl.SetBackgroundImage( image );
290             }
291           }
292           else if ( value.Get< Property::Map >().Empty() )
293           {
294             // An empty map means the background is no longer required
295             controlImpl.ClearBackground();
296           }
297           break;
298         }
299
300         case Toolkit::Control::Property::KEY_INPUT_FOCUS:
301         {
302           if ( value.Get< bool >() )
303           {
304             controlImpl.SetKeyInputFocus();
305           }
306           else
307           {
308             controlImpl.ClearKeyInputFocus();
309           }
310           break;
311         }
312       }
313     }
314   }
315
316   /**
317    * Called to retrieve a property of an object of this type.
318    * @param[in] object The object whose property is to be retrieved.
319    * @param[in] index The property index.
320    * @return The current value of the property.
321    */
322   static Property::Value GetProperty( BaseObject* object, Property::Index index )
323   {
324     Property::Value value;
325
326     Toolkit::Control control = Toolkit::Control::DownCast( BaseHandle( object ) );
327
328     if ( control )
329     {
330       Control& controlImpl( control.GetImplementation() );
331
332       switch ( index )
333       {
334         case Toolkit::Control::Property::STYLE_NAME:
335         {
336           value = controlImpl.GetStyleName();
337           break;
338         }
339
340         case Toolkit::Control::Property::BACKGROUND_COLOR:
341         {
342           value = controlImpl.GetBackgroundColor();
343           break;
344         }
345
346         case Toolkit::Control::Property::BACKGROUND_IMAGE:
347         {
348           Property::Map map;
349
350           Actor actor = controlImpl.GetBackgroundActor();
351           if ( actor )
352           {
353             ImageActor imageActor = ImageActor::DownCast( actor );
354             if ( imageActor )
355             {
356               Image image = imageActor.GetImage();
357               Property::Map imageMap;
358               Scripting::CreatePropertyMap( image, imageMap );
359               map[ "image" ] = imageMap;
360             }
361           }
362
363           value = map;
364           break;
365         }
366
367         case Toolkit::Control::Property::KEY_INPUT_FOCUS:
368         {
369           value = controlImpl.HasKeyInputFocus();
370           break;
371         }
372       }
373     }
374
375     return value;
376   }
377
378   // Data
379
380   Control& mControlImpl;
381   std::string mStyleName;
382   Background* mBackground;           ///< Only create the background if we use it
383   Vector3* mStartingPinchScale;      ///< The scale when a pinch gesture starts, TODO: consider removing this
384   Toolkit::Control::KeyEventSignalType mKeyEventSignal;
385   Toolkit::Control::KeyInputFocusSignalType mKeyInputFocusGainedSignal;
386   Toolkit::Control::KeyInputFocusSignalType mKeyInputFocusLostSignal;
387
388   // Gesture Detection
389   PinchGestureDetector mPinchGestureDetector;
390   PanGestureDetector mPanGestureDetector;
391   TapGestureDetector mTapGestureDetector;
392   LongPressGestureDetector mLongPressGestureDetector;
393   // @todo change all these to Vector2 when we have a chance to sanitize the public API as well
394   Vector3 mCurrentSize; ///< Stores the current control's size, this is the negotiated size
395   Vector3 mNaturalSize; ///< Stores the size set through the Actor's API. This is size the actor wants to be. Useful when reset to the initial size is needed.
396
397   ControlBehaviour mFlags :CONTROL_BEHAVIOUR_FLAG_COUNT;    ///< Flags passed in from constructor.
398   bool mIsKeyboardNavigationSupported :1;  ///< Stores whether keyboard navigation is supported by the control.
399   bool mIsKeyboardFocusGroup :1;           ///< Stores whether the control is a focus group.
400   bool mInitialized :1;
401
402   // Properties - these need to be members of Internal::Control::Impl as they need to function within this class.
403   static PropertyRegistration PROPERTY_1;
404   static PropertyRegistration PROPERTY_2;
405   static PropertyRegistration PROPERTY_3;
406   static PropertyRegistration PROPERTY_4;
407 };
408
409 // Properties registered without macro to use specific member variables.
410 PropertyRegistration Control::Impl::PROPERTY_1( typeRegistration, "style-name",       Toolkit::Control::Property::STYLE_NAME,       Property::STRING,  &Control::Impl::SetProperty, &Control::Impl::GetProperty );
411 PropertyRegistration Control::Impl::PROPERTY_2( typeRegistration, "background-color", Toolkit::Control::Property::BACKGROUND_COLOR, Property::VECTOR4, &Control::Impl::SetProperty, &Control::Impl::GetProperty );
412 PropertyRegistration Control::Impl::PROPERTY_3( typeRegistration, "background-image", Toolkit::Control::Property::BACKGROUND_IMAGE, Property::MAP,     &Control::Impl::SetProperty, &Control::Impl::GetProperty );
413 PropertyRegistration Control::Impl::PROPERTY_4( typeRegistration, "key-input-focus",  Toolkit::Control::Property::KEY_INPUT_FOCUS,  Property::BOOLEAN, &Control::Impl::SetProperty, &Control::Impl::GetProperty );
414
415 Toolkit::Control Control::New()
416 {
417   // Create the implementation, temporarily owned on stack
418   IntrusivePtr<Control> controlImpl = new Control( ControlBehaviour( ACTOR_BEHAVIOUR_NONE ) );
419
420   // Pass ownership to handle
421   Toolkit::Control handle( *controlImpl );
422
423   // Second-phase init of the implementation
424   // This can only be done after the CustomActor connection has been made...
425   controlImpl->Initialize();
426
427   return handle;
428 }
429
430 Control::~Control()
431 {
432   delete mImpl;
433 }
434
435 Vector3 Control::GetNaturalSize()
436 {
437   // could be overridden in derived classes.
438   return mImpl->mNaturalSize;
439 }
440
441 float Control::CalculateChildSize( const Dali::Actor& child, Dimension::Type dimension )
442 {
443   // Could be overridden in derived classes.
444   return CalculateChildSizeBase( child, dimension );
445 }
446
447 bool Control::RelayoutDependentOnChildren( Dimension::Type dimension )
448 {
449   return RelayoutDependentOnChildrenBase( dimension );
450 }
451
452 float Control::GetHeightForWidth( float width )
453 {
454   // could be overridden in derived classes.
455   float height( 0.0f );
456   if ( mImpl->mNaturalSize.width > 0.0f )
457   {
458     height = mImpl->mNaturalSize.height * width / mImpl->mNaturalSize.width;
459   }
460   return height;
461 }
462
463 float Control::GetWidthForHeight( float height )
464 {
465   // could be overridden in derived classes.
466   float width( 0.0f );
467   if ( mImpl->mNaturalSize.height > 0.0f )
468   {
469     width = mImpl->mNaturalSize.width * height / mImpl->mNaturalSize.height;
470   }
471   return width;
472 }
473
474 const Vector3& Control::GetControlSize() const
475 {
476   return mImpl->mCurrentSize;
477 }
478
479 const Vector3& Control::GetSizeSet() const
480 {
481   return mImpl->mNaturalSize;
482 }
483
484 void Control::SetKeyInputFocus()
485 {
486   if( Self().OnStage() )
487   {
488     Toolkit::KeyInputFocusManager::Get().SetFocus(Toolkit::Control::DownCast(Self()));
489   }
490 }
491
492 bool Control::HasKeyInputFocus()
493 {
494   bool result = false;
495   if( Self().OnStage() )
496   {
497     result = Toolkit::KeyInputFocusManager::Get().IsKeyboardListener(Toolkit::Control::DownCast(Self()));
498   }
499   return result;
500 }
501
502 void Control::ClearKeyInputFocus()
503 {
504   if( Self().OnStage() )
505   {
506     Toolkit::KeyInputFocusManager::Get().RemoveFocus(Toolkit::Control::DownCast(Self()));
507   }
508 }
509
510 PinchGestureDetector Control::GetPinchGestureDetector() const
511 {
512   return mImpl->mPinchGestureDetector;
513 }
514
515 PanGestureDetector Control::GetPanGestureDetector() const
516 {
517   return mImpl->mPanGestureDetector;
518 }
519
520 TapGestureDetector Control::GetTapGestureDetector() const
521 {
522   return mImpl->mTapGestureDetector;
523 }
524
525 LongPressGestureDetector Control::GetLongPressGestureDetector() const
526 {
527   return mImpl->mLongPressGestureDetector;
528 }
529
530 void Control::SetStyleName( const std::string& styleName )
531 {
532   if( styleName != mImpl->mStyleName )
533   {
534     mImpl->mStyleName = styleName;
535
536     // Apply new style
537     Toolkit::StyleManager styleManager = Toolkit::StyleManager::Get();
538     GetImpl( styleManager ).ApplyThemeStyle( Toolkit::Control( GetOwner() ) );
539   }
540 }
541
542 const std::string& Control::GetStyleName() const
543 {
544   return mImpl->mStyleName;
545 }
546
547 void Control::SetBackgroundColor( const Vector4& color )
548 {
549   Background& background( mImpl->GetBackground() );
550
551   if ( background.actor )
552   {
553     // Just set the actor color
554     background.actor.SetColor( color );
555   }
556   else
557   {
558     // Create Mesh Actor
559     MeshActor meshActor = MeshActor::New( CreateMesh() );
560
561     SetupBackgroundActorConstrained( meshActor, Actor::Property::SCALE, color );
562
563     // Set the background actor before adding so that we do not inform deriving classes
564     background.actor = meshActor;
565     Self().Add( meshActor );
566   }
567
568   background.color = color;
569 }
570
571 Vector4 Control::GetBackgroundColor() const
572 {
573   if ( mImpl->mBackground )
574   {
575     return mImpl->mBackground->color;
576   }
577   return Color::TRANSPARENT;
578 }
579
580 void Control::SetBackgroundImage( Image image )
581 {
582   Background& background( mImpl->GetBackground() );
583
584   if ( background.actor )
585   {
586     // Remove Current actor, unset AFTER removal so that we do not inform deriving classes
587     Self().Remove( background.actor );
588     background.actor.Reset();
589   }
590
591   ImageActor imageActor = ImageActor::New( image );
592   SetupBackgroundActor( imageActor, background.color );
593
594   // Set the background actor before adding so that we do not inform derived classes
595   background.actor = imageActor;
596   Self().Add( imageActor );
597 }
598
599 void Control::ClearBackground()
600 {
601   if ( mImpl->mBackground )
602   {
603     Background& background( mImpl->GetBackground() );
604     Self().Remove( background.actor );
605
606     delete mImpl->mBackground;
607     mImpl->mBackground = NULL;
608   }
609 }
610
611 Actor Control::GetBackgroundActor() const
612 {
613   if ( mImpl->mBackground )
614   {
615     return mImpl->mBackground->actor;
616   }
617
618   return Actor();
619 }
620
621 void Control::SetKeyboardNavigationSupport(bool isSupported)
622 {
623   mImpl->mIsKeyboardNavigationSupported = isSupported;
624 }
625
626 bool Control::IsKeyboardNavigationSupported()
627 {
628   return mImpl->mIsKeyboardNavigationSupported;
629 }
630
631 void Control::Activate()
632 {
633   // Inform deriving classes
634   OnActivated();
635 }
636
637 bool Control::OnAccessibilityPan(PanGesture gesture)
638 {
639   return false; // Accessibility pan gesture is not handled by default
640 }
641
642 bool Control::OnAccessibilityTouch(const TouchEvent& touchEvent)
643 {
644   return false; // Accessibility touch event is not handled by default
645 }
646
647 bool Control::OnAccessibilityValueChange(bool isIncrease)
648 {
649   return false; // Accessibility value change action is not handled by default
650 }
651
652 void Control::SetAsKeyboardFocusGroup(bool isFocusGroup)
653 {
654   mImpl->mIsKeyboardFocusGroup = isFocusGroup;
655
656   // The following line will be removed when the deprecated API in KeyboardFocusManager is deleted
657   Toolkit::KeyboardFocusManager::Get().SetAsFocusGroup(Self(), isFocusGroup);
658 }
659
660 bool Control::IsKeyboardFocusGroup()
661 {
662   return Toolkit::KeyboardFocusManager::Get().IsFocusGroup(Self());
663 }
664
665 Actor Control::GetNextKeyboardFocusableActor(Actor currentFocusedActor, Toolkit::Control::KeyboardFocusNavigationDirection direction, bool loopEnabled)
666 {
667   return Actor();
668 }
669
670 void Control::OnKeyboardFocusChangeCommitted(Actor commitedFocusableActor)
671 {
672 }
673
674 bool Control::DoAction(BaseObject* object, const std::string& actionName, const PropertyValueContainer& attributes)
675 {
676   bool ret = false;
677
678   if( object && ( 0 == strcmp( actionName.c_str(), ACTION_CONTROL_ACTIVATED ) ) )
679   {
680     Toolkit::Control control = Toolkit::Control::DownCast( BaseHandle( object ) );
681     if( control )
682     {
683       // if cast succeeds there is an implementation so no need to check
684       control.GetImplementation().OnActivated();
685     }
686   }
687
688   return ret;
689 }
690
691 bool Control::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
692 {
693   Dali::BaseHandle handle( object );
694
695   bool connected( false );
696   Toolkit::Control control = Toolkit::Control::DownCast( handle );
697   if ( control )
698   {
699     Control& controlImpl( control.GetImplementation() );
700     connected = true;
701
702     if ( 0 == strcmp( signalName.c_str(), SIGNAL_KEY_EVENT ) )
703     {
704       controlImpl.KeyEventSignal().Connect( tracker, functor );
705     }
706     else if( 0 == strcmp( signalName.c_str(), SIGNAL_KEY_INPUT_FOCUS_GAINED ) )
707     {
708       controlImpl.KeyInputFocusGainedSignal().Connect( tracker, functor );
709     }
710     else if( 0 == strcmp( signalName.c_str(), SIGNAL_KEY_INPUT_FOCUS_LOST ) )
711     {
712       controlImpl.KeyInputFocusLostSignal().Connect( tracker, functor );
713     }
714     else if( 0 == strcmp( signalName.c_str(), SIGNAL_TAPPED ) )
715     {
716       controlImpl.EnableGestureDetection( Gesture::Tap );
717       controlImpl.GetTapGestureDetector().DetectedSignal().Connect( tracker, functor );
718     }
719     else if( 0 == strcmp( signalName.c_str(), SIGNAL_PANNED ) )
720     {
721       controlImpl.EnableGestureDetection( Gesture::Pan );
722       controlImpl.GetPanGestureDetector().DetectedSignal().Connect( tracker, functor );
723     }
724     else if( 0 == strcmp( signalName.c_str(), SIGNAL_PINCHED ) )
725     {
726       controlImpl.EnableGestureDetection( Gesture::Pinch );
727       controlImpl.GetPinchGestureDetector().DetectedSignal().Connect( tracker, functor );
728     }
729     else if( 0 == strcmp( signalName.c_str(), SIGNAL_LONG_PRESSED ) )
730     {
731       controlImpl.EnableGestureDetection( Gesture::LongPress );
732       controlImpl.GetLongPressGestureDetector().DetectedSignal().Connect( tracker, functor );
733     }
734     else
735     {
736       // signalName does not match any signal
737       connected = false;
738     }
739   }
740   return connected;
741 }
742
743 Toolkit::Control::KeyEventSignalType& Control::KeyEventSignal()
744 {
745   return mImpl->mKeyEventSignal;
746 }
747
748 Toolkit::Control::KeyInputFocusSignalType& Control:: KeyInputFocusGainedSignal()
749 {
750   return mImpl->mKeyInputFocusGainedSignal;
751 }
752
753 Toolkit::Control::KeyInputFocusSignalType& Control:: KeyInputFocusLostSignal()
754 {
755   return mImpl->mKeyInputFocusLostSignal;
756 }
757
758 bool Control::EmitKeyEventSignal( const KeyEvent& event )
759 {
760   // Guard against destruction during signal emission
761   Dali::Toolkit::Control handle( GetOwner() );
762
763   bool consumed = false;
764
765   // signals are allocated dynamically when someone connects
766   if ( !mImpl->mKeyEventSignal.Empty() )
767   {
768     consumed = mImpl->mKeyEventSignal.Emit( handle, event );
769   }
770
771   if (!consumed)
772   {
773     // Notification for derived classes
774     consumed = OnKeyEvent(event);
775   }
776
777   return consumed;
778 }
779
780 Control::Control( ControlBehaviour behaviourFlags )
781 : CustomActorImpl( static_cast< ActorFlags >( behaviourFlags ) ),
782   mImpl(new Impl(*this))
783 {
784   mImpl->mFlags = behaviourFlags;
785 }
786
787 void Control::Initialize()
788 {
789   // Calling deriving classes
790   OnInitialize();
791
792   if( mImpl->mFlags & REQUIRES_STYLE_CHANGE_SIGNALS )
793   {
794     Toolkit::StyleManager styleManager = Toolkit::StyleManager::Get();
795
796     // Register for style changes
797     styleManager.StyleChangeSignal().Connect( this, &Control::OnStyleChange );
798
799     // SetTheme
800     GetImpl( styleManager ).ApplyThemeStyle( Toolkit::Control( GetOwner() ) );
801   }
802
803   if( mImpl->mFlags & REQUIRES_KEYBOARD_NAVIGATION_SUPPORT )
804   {
805     SetKeyboardNavigationSupport( true );
806   }
807
808   mImpl->mInitialized = true;
809 }
810
811 void Control::EnableGestureDetection(Gesture::Type type)
812 {
813   if ( (type & Gesture::Pinch) && !mImpl->mPinchGestureDetector )
814   {
815     mImpl->mPinchGestureDetector = PinchGestureDetector::New();
816     mImpl->mPinchGestureDetector.DetectedSignal().Connect(mImpl, &Impl::PinchDetected);
817     mImpl->mPinchGestureDetector.Attach(Self());
818   }
819
820   if ( (type & Gesture::Pan) && !mImpl->mPanGestureDetector )
821   {
822     mImpl->mPanGestureDetector = PanGestureDetector::New();
823     mImpl->mPanGestureDetector.DetectedSignal().Connect(mImpl, &Impl::PanDetected);
824     mImpl->mPanGestureDetector.Attach(Self());
825   }
826
827   if ( (type & Gesture::Tap) && !mImpl->mTapGestureDetector )
828   {
829     mImpl->mTapGestureDetector = TapGestureDetector::New();
830     mImpl->mTapGestureDetector.DetectedSignal().Connect(mImpl, &Impl::TapDetected);
831     mImpl->mTapGestureDetector.Attach(Self());
832   }
833
834   if ( (type & Gesture::LongPress) && !mImpl->mLongPressGestureDetector )
835   {
836     mImpl->mLongPressGestureDetector = LongPressGestureDetector::New();
837     mImpl->mLongPressGestureDetector.DetectedSignal().Connect(mImpl, &Impl::LongPressDetected);
838     mImpl->mLongPressGestureDetector.Attach(Self());
839   }
840 }
841
842 void Control::DisableGestureDetection(Gesture::Type type)
843 {
844   if ( (type & Gesture::Pinch) && mImpl->mPinchGestureDetector )
845   {
846     mImpl->mPinchGestureDetector.Detach(Self());
847     mImpl->mPinchGestureDetector.Reset();
848   }
849
850   if ( (type & Gesture::Pan) && mImpl->mPanGestureDetector )
851   {
852     mImpl->mPanGestureDetector.Detach(Self());
853     mImpl->mPanGestureDetector.Reset();
854   }
855
856   if ( (type & Gesture::Tap) && mImpl->mTapGestureDetector )
857   {
858     mImpl->mTapGestureDetector.Detach(Self());
859     mImpl->mTapGestureDetector.Reset();
860   }
861
862   if ( (type & Gesture::LongPress) && mImpl->mLongPressGestureDetector)
863   {
864     mImpl->mLongPressGestureDetector.Detach(Self());
865     mImpl->mLongPressGestureDetector.Reset();
866   }
867 }
868
869 void Control::OnInitialize()
870 {
871 }
872
873 void Control::OnActivated()
874 {
875 }
876
877 void Control::OnStyleChange( Toolkit::StyleManager styleManager, StyleChange change )
878 {
879   // By default the control is only interested in theme (not font) changes
880   if( change.themeChange )
881   {
882     GetImpl( styleManager ).ApplyThemeStyle( Toolkit::Control( GetOwner() ) );
883   }
884 }
885
886 void Control::OnPinch(const PinchGesture& pinch)
887 {
888   if( !( mImpl->mStartingPinchScale ) )
889   {
890     // lazy allocate
891     mImpl->mStartingPinchScale = new Vector3;
892   }
893
894   if( pinch.state == Gesture::Started )
895   {
896     *( mImpl->mStartingPinchScale ) = Self().GetCurrentScale();
897   }
898
899   Self().SetScale( *( mImpl->mStartingPinchScale ) * pinch.scale );
900 }
901
902 void Control::OnPan( const PanGesture& pan )
903 {
904 }
905
906 void Control::OnTap(const TapGesture& tap)
907 {
908 }
909
910 void Control::OnLongPress( const LongPressGesture& longPress )
911 {
912 }
913
914 void Control::OnControlStageConnection()
915 {
916 }
917
918 void Control::OnControlStageDisconnection()
919 {
920 }
921
922 void Control::OnControlChildAdd( Actor& child )
923 {
924 }
925
926 void Control::OnControlChildRemove( Actor& child )
927 {
928 }
929
930 void Control::OnControlSizeSet( const Vector3& size )
931 {
932 }
933
934 void Control::OnCalculateRelayoutSize( Dimension::Type dimension )
935 {
936 }
937
938 void Control::OnLayoutNegotiated( float size, Dimension::Type dimension )
939 {
940 }
941
942 void Control::OnRelayout( const Vector2& size, RelayoutContainer& container )
943 {
944   for( unsigned int i = 0, numChildren = Self().GetChildCount(); i < numChildren; ++i )
945   {
946     container.Add( Self().GetChildAt( i ), size );
947   }
948 }
949
950 void Control::OnSetResizePolicy( ResizePolicy::Type policy, Dimension::Type dimension )
951 {
952 }
953
954 void Control::EmitKeyInputFocusSignal( bool focusGained )
955 {
956   Dali::Toolkit::Control handle( GetOwner() );
957
958   if ( focusGained )
959   {
960      // signals are allocated dynamically when someone connects
961      if ( !mImpl->mKeyInputFocusGainedSignal.Empty() )
962      {
963       mImpl->mKeyInputFocusGainedSignal.Emit( handle );
964      }
965   }
966   else
967   {
968     // signals are allocated dynamically when someone connects
969     if ( !mImpl->mKeyInputFocusLostSignal.Empty() )
970     {
971       mImpl->mKeyInputFocusLostSignal.Emit( handle );
972     }
973   }
974 }
975
976 void Control::OnKeyInputFocusGained()
977 {
978   EmitKeyInputFocusSignal( true );
979 }
980
981 void Control::OnKeyInputFocusLost()
982 {
983   EmitKeyInputFocusSignal( false );
984 }
985
986 void Control::OnSizeAnimation(Animation& animation, const Vector3& targetSize)
987 {
988   // @todo consider animating negotiated child sizes to target size
989 }
990
991 bool Control::OnTouchEvent(const TouchEvent& event)
992 {
993   return false; // Do not consume
994 }
995
996 bool Control::OnHoverEvent(const HoverEvent& event)
997 {
998   return false; // Do not consume
999 }
1000
1001 bool Control::OnKeyEvent(const KeyEvent& event)
1002 {
1003   return false; // Do not consume
1004 }
1005
1006 bool Control::OnMouseWheelEvent(const MouseWheelEvent& event)
1007 {
1008   return false; // Do not consume
1009 }
1010
1011 void Control::OnStageConnection()
1012 {
1013   // Notify derived classes.
1014   OnControlStageConnection();
1015 }
1016
1017 void Control::OnStageDisconnection()
1018 {
1019   // Notify derived classes
1020   OnControlStageDisconnection();
1021 }
1022
1023 void Control::OnChildAdd(Actor& child)
1024 {
1025   // If this is the background actor, then we do not want to relayout or inform deriving classes
1026   if ( mImpl->mBackground && ( child == mImpl->mBackground->actor ) )
1027   {
1028     return;
1029   }
1030
1031   // Notify derived classes.
1032   OnControlChildAdd( child );
1033 }
1034
1035 void Control::OnChildRemove(Actor& child)
1036 {
1037   // If this is the background actor, then we do not want to relayout or inform deriving classes
1038   if ( mImpl->mBackground && ( child == mImpl->mBackground->actor ) )
1039   {
1040     return;
1041   }
1042
1043   // Notify derived classes.
1044   OnControlChildRemove( child );
1045 }
1046
1047 void Control::OnSizeSet(const Vector3& targetSize)
1048 {
1049   if( targetSize != mImpl->mNaturalSize )
1050   {
1051     // Only updates size if set through Actor's API
1052     mImpl->mNaturalSize = targetSize;
1053   }
1054
1055   if( targetSize != mImpl->mCurrentSize )
1056   {
1057     // Update control size.
1058     mImpl->mCurrentSize = targetSize;
1059
1060     // Notify derived classes.
1061     OnControlSizeSet( targetSize );
1062   }
1063 }
1064
1065 void Control::SignalConnected( SlotObserver* slotObserver, CallbackBase* callback )
1066 {
1067   mImpl->SignalConnected( slotObserver, callback );
1068 }
1069
1070 void Control::SignalDisconnected( SlotObserver* slotObserver, CallbackBase* callback )
1071 {
1072   mImpl->SignalDisconnected( slotObserver, callback );
1073 }
1074
1075 } // namespace Internal
1076
1077 } // namespace Toolkit
1078
1079 } // namespace Dali