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