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