Remove handle::operator=(NULL) as it is duplicating handle.Reset() functionality...
[platform/core/uifw/dali-toolkit.git] / base / 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/constraints.h>
26 #include <dali/public-api/geometry/mesh.h>
27 #include <dali/public-api/object/type-registry.h>
28 #include <dali/public-api/scripting/scripting.h>
29 #include <dali/integration-api/debug.h>
30
31 #include <dali-toolkit/internal/controls/relayout-controller.h>
32 #include <dali-toolkit/internal/controls/relayout-helper.h>
33 #include <dali-toolkit/public-api/focus-manager/keyinput-focus-manager.h>
34 #include <dali-toolkit/public-api/focus-manager/keyboard-focus-manager.h>
35 #include <dali-toolkit/public-api/controls/control.h>
36 #include <dali-toolkit/public-api/styling/style-manager.h>
37 #include <dali-toolkit/internal/styling/style-manager-impl.h>
38
39 namespace Dali
40 {
41
42 namespace Toolkit
43 {
44
45 const Property::Index Control::PROPERTY_BACKGROUND_COLOR      = Internal::Control::CONTROL_PROPERTY_START_INDEX;
46 const Property::Index Control::PROPERTY_BACKGROUND            = Internal::Control::CONTROL_PROPERTY_START_INDEX + 1;
47 const Property::Index Control::PROPERTY_WIDTH_POLICY          = Internal::Control::CONTROL_PROPERTY_START_INDEX + 2;
48 const Property::Index Control::PROPERTY_HEIGHT_POLICY         = Internal::Control::CONTROL_PROPERTY_START_INDEX + 3;
49 const Property::Index Control::PROPERTY_MINIMUM_SIZE          = Internal::Control::CONTROL_PROPERTY_START_INDEX + 4;
50 const Property::Index Control::PROPERTY_MAXIMUM_SIZE          = Internal::Control::CONTROL_PROPERTY_START_INDEX + 5;
51 const Property::Index Control::PROPERTY_KEY_INPUT_FOCUS       = Internal::Control::CONTROL_PROPERTY_START_INDEX + 6;
52
53 namespace
54 {
55
56 const Scripting::StringEnum< Control::SizePolicy > SIZE_POLICY_STRING_TABLE[] =
57 {
58   { "FIXED",      Control::Fixed      },
59   { "MINIMUM",    Control::Minimum    },
60   { "MAXIMUM",    Control::Maximum    },
61   { "RANGE",      Control::Range      },
62   { "FLEXIBLE",   Control::Flexible   },
63 };
64 const unsigned int SIZE_POLICY_STRING_TABLE_COUNT = sizeof( SIZE_POLICY_STRING_TABLE ) / sizeof( SIZE_POLICY_STRING_TABLE[0] );
65
66 #if defined(DEBUG_ENABLED)
67 Integration::Log::Filter* gLogFilter  = Integration::Log::Filter::New(Debug::NoLogging, false, "LOG_CONTROL");
68 #endif
69
70 const float MAX_FLOAT_VALUE( std::numeric_limits<float>::max() );
71 const Vector3 MAX_SIZE( MAX_FLOAT_VALUE, MAX_FLOAT_VALUE, MAX_FLOAT_VALUE );
72 const float BACKGROUND_ACTOR_Z_POSITION( -0.1f );
73
74 BaseHandle Create()
75 {
76   return Internal::Control::New();
77 }
78
79 TypeRegistration CONTROL_TYPE( typeid(Control), typeid(CustomActor), Create );
80
81 // Property Registration after Internal::Control::Impl definition below
82
83 TypeAction ACTION_TYPE_1( CONTROL_TYPE, Toolkit::Control::ACTION_CONTROL_ACTIVATED, &Internal::Control::DoAction );
84
85 SignalConnectorType SIGNAL_CONNECTOR_1( CONTROL_TYPE, Toolkit::Control::SIGNAL_KEY_EVENT,     &Internal::Control::DoConnectSignal );
86 SignalConnectorType SIGNAL_CONNECTOR_2( CONTROL_TYPE, Toolkit::Control::SIGNAL_TAPPED,        &Internal::Control::DoConnectSignal );
87 SignalConnectorType SIGNAL_CONNECTOR_3( CONTROL_TYPE, Toolkit::Control::SIGNAL_PANNED,        &Internal::Control::DoConnectSignal );
88 SignalConnectorType SIGNAL_CONNECTOR_4( CONTROL_TYPE, Toolkit::Control::SIGNAL_PINCHED,       &Internal::Control::DoConnectSignal );
89 SignalConnectorType SIGNAL_CONNECTOR_5( CONTROL_TYPE, Toolkit::Control::SIGNAL_LONG_PRESSED,  &Internal::Control::DoConnectSignal );
90
91 /**
92  * Structure which holds information about the background of a control
93  */
94 struct Background
95 {
96   Actor actor;   ///< Either a MeshActor or an ImageActor
97   Vector4 color; ///< The color of the actor.
98
99   /**
100    * Constructor
101    */
102   Background()
103   : actor(),
104     color( Color::WHITE )
105   {
106   }
107 };
108
109 /**
110  * Helper function to calculate a dimension given the policy of that dimension; the minimum &
111  * maximum values that dimension can be; and the allocated value for that dimension.
112  *
113  * @param[in]  policy     The size policy for that dimension.
114  * @param[in]  minimum    The minimum value that dimension can be.
115  * @param[in]  maximum    The maximum value that dimension can be.
116  * @param[in]  allocated  The value allocated for that dimension.
117  *
118  * @return The value that the dimension should be.
119  *
120  * @note This does not handle Control::Fixed policy.
121  */
122 float Calculate( Control::SizePolicy policy, float minimum, float maximum, float allocated )
123 {
124   float size( allocated );
125
126   switch( policy )
127   {
128     case Control::Fixed:
129     {
130       // Use allocated value
131       break;
132     }
133
134     case Control::Minimum:
135     {
136       // Size is always at least the minimum.
137       size = std::max( allocated, minimum );
138       break;
139     }
140
141     case Control::Maximum:
142     {
143       // Size can grow but up to a maximum value.
144       size = std::min( allocated, maximum );
145       break;
146     }
147
148     case Control::Range:
149     {
150       // Size is at least the minimum and can grow up to the maximum
151       size = std::max( size, minimum );
152       size = std::min( size, maximum );
153      break;
154     }
155
156     case Control::Flexible:
157     {
158       // Size grows or shrinks with no limits.
159       size = allocated;
160       break;
161     }
162
163     default:
164     {
165       DALI_ASSERT_DEBUG( false && "This function was not intended to be used by any other policy." );
166       break;
167     }
168   }
169
170   return size;
171 }
172
173 /**
174  * Creates a white coloured Mesh.
175  */
176 Mesh CreateMesh()
177 {
178   Vector3 white( Color::WHITE );
179
180   MeshData meshData;
181
182   // Create vertices with a white color (actual color is set by actor color)
183   MeshData::VertexContainer vertices(4);
184   vertices[ 0 ] = MeshData::Vertex( Vector3( -0.5f, -0.5f, 0.0f ), Vector2::ZERO, white );
185   vertices[ 1 ] = MeshData::Vertex( Vector3(  0.5f, -0.5f, 0.0f ), Vector2::ZERO, white );
186   vertices[ 2 ] = MeshData::Vertex( Vector3( -0.5f,  0.5f, 0.0f ), Vector2::ZERO, white );
187   vertices[ 3 ] = MeshData::Vertex( Vector3(  0.5f,  0.5f, 0.0f ), Vector2::ZERO, white );
188
189   // Specify all the faces
190   MeshData::FaceIndices faces;
191   faces.reserve( 6 ); // 2 triangles in Quad
192   faces.push_back( 0 ); faces.push_back( 3 ); faces.push_back( 1 );
193   faces.push_back( 0 ); faces.push_back( 2 ); faces.push_back( 3 );
194
195   // Create the mesh data from the vertices and faces
196   meshData.SetMaterial( Material::New( "ControlMaterial" ) );
197   meshData.SetVertices( vertices );
198   meshData.SetFaceIndices( faces );
199   meshData.SetHasColor( true );
200
201   return Mesh::New( meshData );
202 }
203
204 /**
205  * Sets all the required properties for the background actor.
206  *
207  * @param[in]  actor              The actor to set the properties on.
208  * @param[in]  constrainingIndex  The property index to constrain the parent's size on.
209  * @param[in]  color              The required color of the actor.
210  */
211 void SetupBackgroundActor( Actor actor, Property::Index constrainingIndex, const Vector4& color )
212 {
213   actor.SetColor( color );
214   actor.SetPositionInheritanceMode( USE_PARENT_POSITION_PLUS_LOCAL_POSITION );
215   actor.SetColorMode( USE_OWN_MULTIPLY_PARENT_COLOR );
216   actor.SetZ( BACKGROUND_ACTOR_Z_POSITION );
217
218   Constraint constraint = Constraint::New<Vector3>( constrainingIndex,
219                                                     ParentSource( Actor::SIZE ),
220                                                     EqualToConstraint() );
221   actor.ApplyConstraint( constraint );
222 }
223
224 } // unnamed namespace
225
226 namespace Internal
227 {
228
229 class Control::Impl : public ConnectionTracker
230 {
231 public:
232
233   /**
234    * Size indices for mMinMaxSize array
235    */
236   enum
237   {
238     MIN_SIZE_INDEX = 0,
239     MAX_SIZE_INDEX = 1
240   };
241
242 public:
243   // Construction & Destruction
244   Impl(Control& controlImpl)
245   : mControlImpl( controlImpl ),
246     mBackground( NULL ),
247     mStartingPinchScale( NULL ),
248     mKeyEventSignalV2(),
249     mPinchGestureDetector(),
250     mPanGestureDetector(),
251     mTapGestureDetector(),
252     mLongPressGestureDetector(),
253     mCurrentSize(),
254     mNaturalSize(),
255     mWidthPolicy( Toolkit::Control::Fixed ),
256     mHeightPolicy( Toolkit::Control::Fixed ),
257     mFlags( Control::CONTROL_BEHAVIOUR_NONE ),
258     mInsideRelayout( false ),
259     mIsKeyboardNavigationSupported( false ),
260     mIsKeyboardFocusGroup( false ),
261     mInitialized( false )
262   {
263   }
264
265   ~Impl()
266   {
267     // All gesture detectors will be destroyed so no need to disconnect.
268     delete mBackground;
269     delete mStartingPinchScale;
270   }
271
272   // Gesture Detection Methods
273
274   void PinchDetected(Actor actor, PinchGesture pinch)
275   {
276     mControlImpl.OnPinch(pinch);
277   }
278
279   void PanDetected(Actor actor, PanGesture pan)
280   {
281     mControlImpl.OnPan(pan);
282   }
283
284   void TapDetected(Actor actor, TapGesture tap)
285   {
286     mControlImpl.OnTap(tap);
287   }
288
289   void LongPressDetected(Actor actor, LongPressGesture longPress)
290   {
291     mControlImpl.OnLongPress(longPress);
292   }
293
294   // Background Methods
295
296   /**
297    * Only creates an instance of the background if we actually use it.
298    * @return A reference to the Background structure.
299    */
300   Background& GetBackground()
301   {
302     if ( !mBackground )
303     {
304       mBackground = new Background;
305     }
306     return *mBackground;
307   }
308
309   // Properties
310
311   /**
312    * Called when a property of an object of this type is set.
313    * @param[in] object The object whose property is set.
314    * @param[in] index The property index.
315    * @param[in] value The new property value.
316    */
317   static void SetProperty( BaseObject* object, Property::Index index, const Property::Value& value )
318   {
319     Toolkit::Control control = Toolkit::Control::DownCast( BaseHandle( object ) );
320
321     if ( control )
322     {
323       Control& controlImpl( control.GetImplementation() );
324
325       switch ( index )
326       {
327         case Toolkit::Control::PROPERTY_BACKGROUND_COLOR:
328         {
329           controlImpl.SetBackgroundColor( value.Get< Vector4 >() );
330           break;
331         }
332
333         case Toolkit::Control::PROPERTY_BACKGROUND:
334         {
335           if ( value.HasKey( "image" ) )
336           {
337             Property::Map imageMap = value.GetValue( "image" ).Get< Property::Map >();
338             Image image = Scripting::NewImage( imageMap );
339
340             if ( image )
341             {
342               controlImpl.SetBackground( image );
343             }
344           }
345           else if ( value.Get< Property::Map >().Empty() )
346           {
347             // An empty map means the background is no longer required
348             controlImpl.ClearBackground();
349           }
350           break;
351         }
352
353         case Toolkit::Control::PROPERTY_WIDTH_POLICY:
354         {
355           controlImpl.mImpl->mWidthPolicy = Scripting::GetEnumeration< Toolkit::Control::SizePolicy >( value.Get< std::string >(), SIZE_POLICY_STRING_TABLE, SIZE_POLICY_STRING_TABLE_COUNT );
356           break;
357         }
358
359         case Toolkit::Control::PROPERTY_HEIGHT_POLICY:
360         {
361           controlImpl.mImpl->mHeightPolicy = Scripting::GetEnumeration< Toolkit::Control::SizePolicy >( value.Get< std::string >(), SIZE_POLICY_STRING_TABLE, SIZE_POLICY_STRING_TABLE_COUNT );
362           break;
363         }
364
365         case Toolkit::Control::PROPERTY_MINIMUM_SIZE:
366         {
367           controlImpl.SetMinimumSize( value.Get< Vector3 >() );
368           break;
369         }
370
371         case Toolkit::Control::PROPERTY_MAXIMUM_SIZE:
372         {
373           controlImpl.SetMaximumSize( value.Get< Vector3 >() );
374           break;
375         }
376
377         case Toolkit::Control::PROPERTY_KEY_INPUT_FOCUS:
378         {
379           if ( value.Get< bool >() )
380           {
381             controlImpl.SetKeyInputFocus();
382           }
383           else
384           {
385             controlImpl.ClearKeyInputFocus();
386           }
387           break;
388         }
389       }
390     }
391   }
392
393   /**
394    * Called to retrieve a property of an object of this type.
395    * @param[in] object The object whose property is to be retrieved.
396    * @param[in] index The property index.
397    * @return The current value of the property.
398    */
399   static Property::Value GetProperty( BaseObject* object, Property::Index index )
400   {
401     Property::Value value;
402
403     Toolkit::Control control = Toolkit::Control::DownCast( BaseHandle( object ) );
404
405     if ( control )
406     {
407       Control& controlImpl( control.GetImplementation() );
408
409       switch ( index )
410       {
411         case Toolkit::Control::PROPERTY_BACKGROUND_COLOR:
412         {
413           value = controlImpl.GetBackgroundColor();
414           break;
415         }
416
417         case Toolkit::Control::PROPERTY_BACKGROUND:
418         {
419           Property::Map map;
420
421           Actor actor = controlImpl.GetBackgroundActor();
422           if ( actor )
423           {
424             ImageActor imageActor = ImageActor::DownCast( actor );
425             if ( imageActor )
426             {
427               Image image = imageActor.GetImage();
428               Property::Map imageMap;
429               Scripting::CreatePropertyMap( image, imageMap );
430               map[ "image" ] = imageMap;
431             }
432           }
433
434           value = map;
435           break;
436         }
437
438         case Toolkit::Control::PROPERTY_WIDTH_POLICY:
439         {
440           value = std::string( Scripting::GetEnumerationName< Toolkit::Control::SizePolicy >( controlImpl.mImpl->mWidthPolicy, SIZE_POLICY_STRING_TABLE, SIZE_POLICY_STRING_TABLE_COUNT ) );
441           break;
442         }
443
444         case Toolkit::Control::PROPERTY_HEIGHT_POLICY:
445         {
446           value = std::string( Scripting::GetEnumerationName< Toolkit::Control::SizePolicy >( controlImpl.mImpl->mHeightPolicy, SIZE_POLICY_STRING_TABLE, SIZE_POLICY_STRING_TABLE_COUNT ) );
447           break;
448         }
449
450         case Toolkit::Control::PROPERTY_MINIMUM_SIZE:
451         {
452           value = controlImpl.mImpl->GetMinimumSize();
453           break;
454         }
455
456         case Toolkit::Control::PROPERTY_MAXIMUM_SIZE:
457         {
458           value = controlImpl.mImpl->GetMaximumSize();
459           break;
460         }
461
462         case Toolkit::Control::PROPERTY_KEY_INPUT_FOCUS:
463         {
464           value = controlImpl.HasKeyInputFocus();
465           break;
466         }
467       }
468     }
469
470     return value;
471   }
472
473   /**
474    * Helper to get minimum size
475    * @return minimum size
476    */
477   inline const Vector3& GetMinimumSize()
478   {
479     if( mMinMaxSize.Count() > MIN_SIZE_INDEX )
480     {
481       return mMinMaxSize[ MIN_SIZE_INDEX ];
482     }
483     else
484     {
485       // its not been allocated so its ZERO
486       return Vector3::ZERO;
487     }
488   }
489   /**
490    * Helper to Set minimum size
491    * @param size to set
492    */
493   inline void SetMinimumSize( const Vector3& size )
494   {
495     if( mMinMaxSize.Count() > MIN_SIZE_INDEX )
496     {
497       mMinMaxSize[ MIN_SIZE_INDEX ] = size;
498     }
499     else
500     {
501       // its not been allocated so push the new value there
502       mMinMaxSize.PushBack( size );
503     }
504   }
505
506   /**
507    * Helper to get maximum size
508    * @return maximum size
509    */
510   inline const Vector3& GetMaximumSize()
511   {
512     if( mMinMaxSize.Count() > MAX_SIZE_INDEX )
513     {
514       return mMinMaxSize[ MAX_SIZE_INDEX ];
515     }
516     else
517     {
518       // its not been allocated so its MAX_SIZE
519       return MAX_SIZE;
520     }
521   }
522
523   /**
524    * Helper to Set minimum size
525    * @param size to set
526    */
527   inline void SetMaximumSize( const Vector3& size )
528   {
529     if( mMinMaxSize.Count() > MAX_SIZE_INDEX )
530     {
531       mMinMaxSize[ MAX_SIZE_INDEX ] = size;
532     }
533     else if( mMinMaxSize.Count() > MIN_SIZE_INDEX )
534     {
535       // max has not been allocated, but min has
536       mMinMaxSize.PushBack( size );
537     }
538     else
539     {
540       // min and max both unallocated so allocate both
541       mMinMaxSize.Resize( 2u ); // this will reserve and default construct two Vector3s
542       mMinMaxSize[ MAX_SIZE_INDEX ] = size;
543     }
544   }
545
546   // Data
547
548   Control& mControlImpl;
549   Background* mBackground;           ///< Only create the background if we use it
550   Vector3* mStartingPinchScale;      ///< The scale when a pinch gesture starts, TODO: consider removing this
551   Toolkit::Control::KeyEventSignalV2 mKeyEventSignalV2;
552
553   // Gesture Detection
554   PinchGestureDetector mPinchGestureDetector;
555   PanGestureDetector mPanGestureDetector;
556   TapGestureDetector mTapGestureDetector;
557   LongPressGestureDetector mLongPressGestureDetector;
558   // @todo change all these to Vector2 when we have a chance to sanitize the public API as well
559   Vector3 mCurrentSize; ///< Stores the current control's size, this is the negotiated size
560   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.
561   Dali::Vector< Vector3 > mMinMaxSize; ///< Stores the minimum and maximum size if they are set
562
563   Toolkit::Control::SizePolicy mWidthPolicy :3;  ///< Stores the width policy. 3 bits covers 8 values
564   Toolkit::Control::SizePolicy mHeightPolicy :3; ///< Stores the height policy. 3 bits covers 8 values
565   ControlBehaviour mFlags :6;             ///< Flags passed in from constructor. Need to increase this size when new enums are added
566   bool mInsideRelayout:1;                 ///< Detect when were in Relayout
567   bool mIsKeyboardNavigationSupported:1;  ///< Stores whether keyboard navigation is supported by the control.
568   bool mIsKeyboardFocusGroup:1;           ///< Stores whether the control is a focus group.
569   bool mInitialized:1;
570
571   // Properties - these need to be members of Internal::Control::Impl as they need to functions within this class.
572   static PropertyRegistration PROPERTY_1;
573   static PropertyRegistration PROPERTY_2;
574   static PropertyRegistration PROPERTY_3;
575   static PropertyRegistration PROPERTY_4;
576   static PropertyRegistration PROPERTY_5;
577   static PropertyRegistration PROPERTY_6;
578   static PropertyRegistration PROPERTY_7;
579 };
580
581 PropertyRegistration Control::Impl::PROPERTY_1( CONTROL_TYPE, "background-color", Toolkit::Control::PROPERTY_BACKGROUND_COLOR, Property::VECTOR4, &Control::Impl::SetProperty, &Control::Impl::GetProperty );
582 PropertyRegistration Control::Impl::PROPERTY_2( CONTROL_TYPE, "background",       Toolkit::Control::PROPERTY_BACKGROUND,       Property::MAP,     &Control::Impl::SetProperty, &Control::Impl::GetProperty );
583 PropertyRegistration Control::Impl::PROPERTY_3( CONTROL_TYPE, "width-policy",     Toolkit::Control::PROPERTY_WIDTH_POLICY,     Property::STRING,  &Control::Impl::SetProperty, &Control::Impl::GetProperty );
584 PropertyRegistration Control::Impl::PROPERTY_4( CONTROL_TYPE, "height-policy",    Toolkit::Control::PROPERTY_HEIGHT_POLICY,    Property::STRING,  &Control::Impl::SetProperty, &Control::Impl::GetProperty );
585 PropertyRegistration Control::Impl::PROPERTY_5( CONTROL_TYPE, "minimum-size",     Toolkit::Control::PROPERTY_MINIMUM_SIZE,     Property::VECTOR3, &Control::Impl::SetProperty, &Control::Impl::GetProperty );
586 PropertyRegistration Control::Impl::PROPERTY_6( CONTROL_TYPE, "maximum-size",     Toolkit::Control::PROPERTY_MAXIMUM_SIZE,     Property::VECTOR3, &Control::Impl::SetProperty, &Control::Impl::GetProperty );
587 PropertyRegistration Control::Impl::PROPERTY_7( CONTROL_TYPE, "key-input-focus",  Toolkit::Control::PROPERTY_KEY_INPUT_FOCUS,  Property::BOOLEAN, &Control::Impl::SetProperty, &Control::Impl::GetProperty );
588
589 Toolkit::Control Control::New()
590 {
591   // Create the implementation, temporarily owned on stack
592   IntrusivePtr<Control> controlImpl = new Control( CONTROL_BEHAVIOUR_NONE );
593
594   // Pass ownership to handle
595   Toolkit::Control handle( *controlImpl );
596
597   // Second-phase init of the implementation
598   // This can only be done after the CustomActor connection has been made...
599   controlImpl->Initialize();
600
601   return handle;
602 }
603
604 Control::~Control()
605 {
606   delete mImpl;
607 }
608
609 void Control::Initialize()
610 {
611
612   // Calling deriving classes
613   OnInitialize();
614
615   if( mImpl->mFlags & REQUIRES_STYLE_CHANGE_SIGNALS )
616   {
617     Toolkit::StyleManager styleManager = Toolkit::StyleManager::Get();
618
619     // Register for style changes
620     styleManager.StyleChangeSignal().Connect( this, &Control::DoStyleChange );
621
622     // SetTheme
623     GetImpl( styleManager ).ApplyThemeStyle( GetOwner() );
624   }
625
626   SetRequiresHoverEvents(mImpl->mFlags & REQUIRES_HOVER_EVENTS);
627   SetRequiresMouseWheelEvents(mImpl->mFlags & REQUIRES_MOUSE_WHEEL_EVENTS);
628
629   mImpl->mInitialized = true;
630 }
631
632 void Control::EnableGestureDetection(Gesture::Type type)
633 {
634   if ( (type & Gesture::Pinch) && !mImpl->mPinchGestureDetector )
635   {
636     mImpl->mPinchGestureDetector = PinchGestureDetector::New();
637     mImpl->mPinchGestureDetector.DetectedSignal().Connect(mImpl, &Impl::PinchDetected);
638     mImpl->mPinchGestureDetector.Attach(Self());
639   }
640
641   if ( (type & Gesture::Pan) && !mImpl->mPanGestureDetector )
642   {
643     mImpl->mPanGestureDetector = PanGestureDetector::New();
644     mImpl->mPanGestureDetector.DetectedSignal().Connect(mImpl, &Impl::PanDetected);
645     mImpl->mPanGestureDetector.Attach(Self());
646   }
647
648   if ( (type & Gesture::Tap) && !mImpl->mTapGestureDetector )
649   {
650     mImpl->mTapGestureDetector = TapGestureDetector::New();
651     mImpl->mTapGestureDetector.DetectedSignal().Connect(mImpl, &Impl::TapDetected);
652     mImpl->mTapGestureDetector.Attach(Self());
653   }
654
655   if ( (type & Gesture::LongPress) && !mImpl->mLongPressGestureDetector )
656   {
657     mImpl->mLongPressGestureDetector = LongPressGestureDetector::New();
658     mImpl->mLongPressGestureDetector.DetectedSignal().Connect(mImpl, &Impl::LongPressDetected);
659     mImpl->mLongPressGestureDetector.Attach(Self());
660   }
661 }
662
663 void Control::DisableGestureDetection(Gesture::Type type)
664 {
665   if ( (type & Gesture::Pinch) && mImpl->mPinchGestureDetector )
666   {
667     mImpl->mPinchGestureDetector.Detach(Self());
668     mImpl->mPinchGestureDetector.Reset();
669   }
670
671   if ( (type & Gesture::Pan) && mImpl->mPanGestureDetector )
672   {
673     mImpl->mPanGestureDetector.Detach(Self());
674     mImpl->mPanGestureDetector.Reset();
675   }
676
677   if ( (type & Gesture::Tap) && mImpl->mTapGestureDetector )
678   {
679     mImpl->mTapGestureDetector.Detach(Self());
680     mImpl->mTapGestureDetector.Reset();
681   }
682
683   if ( (type & Gesture::LongPress) && mImpl->mLongPressGestureDetector)
684   {
685     mImpl->mLongPressGestureDetector.Detach(Self());
686     mImpl->mLongPressGestureDetector.Reset();
687   }
688 }
689
690 PinchGestureDetector Control::GetPinchGestureDetector() const
691 {
692   return mImpl->mPinchGestureDetector;
693 }
694
695 PanGestureDetector Control::GetPanGestureDetector() const
696 {
697   return mImpl->mPanGestureDetector;
698 }
699
700 TapGestureDetector Control::GetTapGestureDetector() const
701 {
702   return mImpl->mTapGestureDetector;
703 }
704
705 LongPressGestureDetector Control::GetLongPressGestureDetector() const
706 {
707   return mImpl->mLongPressGestureDetector;
708 }
709
710 void Control::SetBackgroundColor( const Vector4& color )
711 {
712   Background& background( mImpl->GetBackground() );
713
714   if ( background.actor )
715   {
716     // Just set the actor color
717     background.actor.SetColor( color );
718   }
719   else
720   {
721     // Create Mesh Actor
722     MeshActor meshActor = MeshActor::New( CreateMesh() );
723
724     meshActor.SetAffectedByLighting( false );
725     SetupBackgroundActor( meshActor, Actor::SCALE, color );
726
727     // Set the background actor before adding so that we do not inform deriving classes
728     background.actor = meshActor;
729     Self().Add( meshActor );
730   }
731
732   background.color = color;
733 }
734
735 Vector4 Control::GetBackgroundColor() const
736 {
737   if ( mImpl->mBackground )
738   {
739     return mImpl->mBackground->color;
740   }
741   return Color::TRANSPARENT;
742 }
743
744 void Control::SetBackground( Image image )
745 {
746   Background& background( mImpl->GetBackground() );
747
748   if ( background.actor )
749   {
750     // Remove Current actor, unset AFTER removal so that we do not inform deriving classes
751     Self().Remove( background.actor );
752     background.actor.Reset();
753   }
754
755   ImageActor imageActor = ImageActor::New( image );
756   SetupBackgroundActor( imageActor, Actor::SIZE, background.color );
757
758   // Set the background actor before adding so that we do not inform derived classes
759   background.actor = imageActor;
760   Self().Add( imageActor );
761 }
762
763 void Control::ClearBackground()
764 {
765   if ( mImpl->mBackground )
766   {
767     Background& background( mImpl->GetBackground() );
768     Self().Remove( background.actor );
769
770     delete mImpl->mBackground;
771     mImpl->mBackground = NULL;
772   }
773 }
774
775 Actor Control::GetBackgroundActor() const
776 {
777   if ( mImpl->mBackground )
778   {
779     return mImpl->mBackground->actor;
780   }
781
782   return Actor();
783 }
784
785 void Control::OnThemeChange( Toolkit::StyleManager styleManager )
786 {
787   GetImpl( styleManager ).ApplyThemeStyle( GetOwner() );
788 }
789
790 void Control::OnPinch(PinchGesture pinch)
791 {
792   if( !( mImpl->mStartingPinchScale ) )
793   {
794     // lazy allocate
795     mImpl->mStartingPinchScale = new Vector3;
796   }
797
798   if( pinch.state == Gesture::Started )
799   {
800     *( mImpl->mStartingPinchScale ) = Self().GetCurrentScale();
801   }
802
803   Self().SetScale( *( mImpl->mStartingPinchScale ) * pinch.scale );
804 }
805
806 void Control::OnStageConnection()
807 {
808   RelayoutRequest();
809
810   // Notify derived classes.
811   OnControlStageConnection();
812 }
813
814 void Control::OnStageDisconnection()
815 {
816   // Notify derived classes
817   OnControlStageDisconnection();
818 }
819
820 void Control::OnChildAdd(Actor& child)
821 {
822   // If this is the background actor, then we do not want to relayout or inform deriving classes
823   if ( mImpl->mBackground && ( child == mImpl->mBackground->actor ) )
824   {
825     return;
826   }
827
828   // Request for relayout as we may need to position the new child and old ones
829   RelayoutRequest();
830
831   // Notify derived classes.
832   OnControlChildAdd( child );
833 }
834
835 void Control::OnChildRemove(Actor& child)
836 {
837   // If this is the background actor, then we do not want to relayout or inform deriving classes
838   if ( mImpl->mBackground && ( child == mImpl->mBackground->actor ) )
839   {
840     return;
841   }
842
843   // Request for relayout as we may need to re-position the old child
844   RelayoutRequest();
845
846   // Notify derived classes.
847   OnControlChildRemove( child );
848 }
849
850 void Control::OnSizeSet(const Vector3& targetSize)
851 {
852   if( ( !mImpl->mInsideRelayout ) && ( targetSize != mImpl->mNaturalSize ) )
853   {
854     // Only updates size if set through Actor's API
855     mImpl->mNaturalSize = targetSize;
856   }
857
858   if( targetSize != mImpl->mCurrentSize )
859   {
860     // Update control size.
861     mImpl->mCurrentSize = targetSize;
862
863     // Notify derived classes.
864     OnControlSizeSet( targetSize );
865   }
866 }
867
868 void Control::OnSizeAnimation(Animation& animation, const Vector3& targetSize)
869 {
870   // @todo consider animating negotiated child sizes to target size
871 }
872
873 bool Control::OnTouchEvent(const TouchEvent& event)
874 {
875   return false; // Do not consume
876 }
877
878 bool Control::OnHoverEvent(const HoverEvent& event)
879 {
880   return false; // Do not consume
881 }
882
883 bool Control::OnKeyEvent(const KeyEvent& event)
884 {
885   return false; // Do not consume
886 }
887
888 bool Control::OnMouseWheelEvent(const MouseWheelEvent& event)
889 {
890   return false; // Do not consume
891 }
892
893 void Control::OnKeyInputFocusGained()
894 {
895   // Do Nothing
896 }
897
898 void Control::OnKeyInputFocusLost()
899 {
900   // Do Nothing
901 }
902
903 Actor Control::GetChildByAlias(const std::string& actorAlias)
904 {
905   return Actor();
906 }
907
908 bool Control::OnAccessibilityPan(PanGesture gesture)
909 {
910   return false; // Accessibility pan gesture is not handled by default
911 }
912
913 bool Control::OnAccessibilityTouch(const TouchEvent& touchEvent)
914 {
915   return false; // Accessibility touch event is not handled by default
916 }
917
918 bool Control::OnAccessibilityValueChange(bool isIncrease)
919 {
920   return false; // Accessibility value change action is not handled by default
921 }
922
923
924 void Control::SetKeyboardNavigationSupport(bool isSupported)
925 {
926   mImpl->mIsKeyboardNavigationSupported = isSupported;
927 }
928
929 bool Control::IsKeyboardNavigationSupported()
930 {
931   return mImpl->mIsKeyboardNavigationSupported;
932 }
933
934 void Control::SetAsKeyboardFocusGroup(bool isFocusGroup)
935 {
936   mImpl->mIsKeyboardFocusGroup = isFocusGroup;
937
938   // The following line will be removed when the deprecated API in KeyboardFocusManager is deleted
939   Toolkit::KeyboardFocusManager::Get().SetAsFocusGroup(Self(), isFocusGroup);
940 }
941
942 bool Control::IsKeyboardFocusGroup()
943 {
944   return Toolkit::KeyboardFocusManager::Get().IsFocusGroup(Self());
945 }
946
947 Actor Control::GetNextKeyboardFocusableActor(Actor currentFocusedActor, Toolkit::Control::KeyboardFocusNavigationDirection direction, bool loopEnabled)
948 {
949   return Actor();
950 }
951
952 bool Control::DoAction(BaseObject* object, const std::string& actionName, const std::vector<Property::Value>& attributes)
953 {
954   bool ret = false;
955
956   if( object && (actionName == Toolkit::Control::ACTION_CONTROL_ACTIVATED) )
957   {
958     Toolkit::Control control = Toolkit::Control::DownCast( BaseHandle( object ) );
959     if( control )
960     {
961       // if cast succeeds there is an implementation so no need to check
962       control.GetImplementation().OnActivated();
963     }
964   }
965
966   return ret;
967 }
968
969 bool Control::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
970 {
971   Dali::BaseHandle handle( object );
972
973   bool connected( false );
974   Toolkit::Control control = Toolkit::Control::DownCast(handle);
975   if ( control )
976   {
977     Control& controlImpl( control.GetImplementation() );
978     connected = true;
979
980     if ( Toolkit::Control::SIGNAL_KEY_EVENT == signalName )
981     {
982       controlImpl.KeyEventSignal().Connect( tracker, functor );
983     }
984     else if( Toolkit::Control::SIGNAL_TAPPED == signalName )
985     {
986       controlImpl.EnableGestureDetection( Gesture::Tap );
987       controlImpl.GetTapGestureDetector().DetectedSignal().Connect( tracker, functor );
988     }
989     else if( Toolkit::Control::SIGNAL_PANNED == signalName )
990     {
991       controlImpl.EnableGestureDetection( Gesture::Pan );
992       controlImpl.GetPanGestureDetector().DetectedSignal().Connect( tracker, functor );
993     }
994     else if( Toolkit::Control::SIGNAL_PINCHED == signalName )
995     {
996       controlImpl.EnableGestureDetection( Gesture::Pinch );
997       controlImpl.GetPinchGestureDetector().DetectedSignal().Connect( tracker, functor );
998     }
999     else if( Toolkit::Control::SIGNAL_LONG_PRESSED == signalName )
1000     {
1001       controlImpl.EnableGestureDetection( Gesture::LongPress );
1002       controlImpl.GetLongPressGestureDetector().DetectedSignal().Connect( tracker, functor );
1003     }
1004     else
1005     {
1006       // signalName does not match any signal
1007       connected = false;
1008     }
1009   }
1010   return connected;
1011 }
1012
1013 void Control::DoStyleChange( Toolkit::StyleManager styleManager, StyleChange change )
1014 {
1015   if( change.themeChange )
1016   {
1017     OnThemeChange( styleManager );
1018   }
1019   else if( change.defaultFontChange || change.defaultFontSizeChange )
1020   {
1021     OnFontChange( change.defaultFontChange, change.defaultFontSizeChange );
1022   }
1023 }
1024
1025 Toolkit::Control::KeyEventSignalV2& Control::KeyEventSignal()
1026 {
1027   return mImpl->mKeyEventSignalV2;
1028 }
1029
1030 void Control::SetSizePolicy( Toolkit::Control::SizePolicy widthPolicy, Toolkit::Control::SizePolicy heightPolicy )
1031 {
1032   bool relayoutRequest( false );
1033
1034   if ( ( mImpl->mWidthPolicy != widthPolicy ) || ( mImpl->mHeightPolicy != heightPolicy ) )
1035   {
1036     relayoutRequest = true;
1037   }
1038
1039   mImpl->mWidthPolicy = widthPolicy;
1040   mImpl->mHeightPolicy = heightPolicy;
1041
1042   // Ensure RelayoutRequest is called AFTER new policies have been set.
1043   if ( relayoutRequest )
1044   {
1045     RelayoutRequest();
1046   }
1047 }
1048
1049 void Control::GetSizePolicy( Toolkit::Control::SizePolicy& widthPolicy, Toolkit::Control::SizePolicy& heightPolicy ) const
1050 {
1051   widthPolicy = mImpl->mWidthPolicy;
1052   heightPolicy = mImpl->mHeightPolicy;
1053 }
1054
1055 void Control::SetMinimumSize( const Vector3& size )
1056 {
1057   const Vector3& minSize = mImpl->GetMinimumSize();
1058   if ( fabsf( minSize.width - size.width ) > Math::MACHINE_EPSILON_1000 ||
1059        fabsf( minSize.height - size.height ) > Math::MACHINE_EPSILON_1000 )
1060   {
1061     mImpl->SetMinimumSize( size );
1062
1063     // Only relayout if our control is using the minimum or range policy.
1064     if ( ( mImpl->mHeightPolicy == Toolkit::Control::Minimum ) || ( mImpl->mWidthPolicy  == Toolkit::Control::Minimum ) ||
1065          ( mImpl->mHeightPolicy == Toolkit::Control::Range   ) || ( mImpl->mWidthPolicy  == Toolkit::Control::Range   ) )
1066     {
1067       RelayoutRequest();
1068     }
1069   }
1070 }
1071
1072 const Vector3& Control::GetMinimumSize() const
1073 {
1074   return mImpl->GetMinimumSize();
1075 }
1076
1077 void Control::SetMaximumSize( const Vector3& size )
1078 {
1079   const Vector3& maxSize = mImpl->GetMaximumSize();
1080   if ( fabsf( maxSize.width - size.width ) > Math::MACHINE_EPSILON_1000 ||
1081        fabsf( maxSize.height - size.height ) > Math::MACHINE_EPSILON_1000 )
1082   {
1083     mImpl->SetMaximumSize( size );
1084
1085     // Only relayout if our control is using the maximum or range policy.
1086     if ( ( mImpl->mHeightPolicy == Toolkit::Control::Maximum ) || ( mImpl->mWidthPolicy  == Toolkit::Control::Maximum ) ||
1087          ( mImpl->mHeightPolicy == Toolkit::Control::Range   ) || ( mImpl->mWidthPolicy  == Toolkit::Control::Range   ) )
1088     {
1089       RelayoutRequest();
1090     }
1091   }
1092 }
1093
1094 const Vector3& Control::GetMaximumSize() const
1095 {
1096   return mImpl->GetMaximumSize();
1097 }
1098
1099 Vector3 Control::GetNaturalSize()
1100 {
1101   // could be overridden in derived classes.
1102   return mImpl->mNaturalSize;
1103 }
1104
1105 float Control::GetHeightForWidth( float width )
1106 {
1107   // could be overridden in derived classes.
1108   float height( 0.0f );
1109   if ( mImpl->mNaturalSize.width > 0.0f )
1110   {
1111     height = mImpl->mNaturalSize.height * width / mImpl->mNaturalSize.width;
1112   }
1113   return height;
1114 }
1115
1116 float Control::GetWidthForHeight( float height )
1117 {
1118   // could be overridden in derived classes.
1119   float width( 0.0f );
1120   if ( mImpl->mNaturalSize.height > 0.0f )
1121   {
1122     width = mImpl->mNaturalSize.width * height / mImpl->mNaturalSize.height;
1123   }
1124   return width;
1125 }
1126
1127 const Vector3& Control::GetControlSize() const
1128 {
1129   return mImpl->mCurrentSize;
1130 }
1131
1132 const Vector3& Control::GetSizeSet() const
1133 {
1134   return mImpl->mNaturalSize;
1135 }
1136
1137 void Control::SetKeyInputFocus()
1138 {
1139   if( Self().OnStage() )
1140   {
1141     Toolkit::KeyInputFocusManager::Get().SetFocus(Toolkit::Control::DownCast(Self()));
1142   }
1143 }
1144
1145 bool Control::HasKeyInputFocus()
1146 {
1147   bool result = false;
1148   if( Self().OnStage() )
1149   {
1150     result = Toolkit::KeyInputFocusManager::Get().IsKeyboardListener(Toolkit::Control::DownCast(Self()));
1151   }
1152   return result;
1153 }
1154
1155 void Control::ClearKeyInputFocus()
1156 {
1157   if( Self().OnStage() )
1158   {
1159     Toolkit::KeyInputFocusManager::Get().RemoveFocus(Toolkit::Control::DownCast(Self()));
1160   }
1161 }
1162
1163 void Control::RelayoutRequest()
1164 {
1165   // unfortunate double negative but thats to guarantee new controls get size negotiation
1166   // by default and have to "opt-out" if they dont want it
1167   if( !(mImpl->mFlags & NO_SIZE_NEGOTIATION) )
1168   {
1169     Internal::RelayoutController::Request();
1170   }
1171 }
1172
1173 void Control::Relayout(Vector2 size, ActorSizeContainer& container)
1174 {
1175   // Avoids relayout again when OnSizeSet callback arrives.
1176   mImpl->mInsideRelayout = true;
1177   Self().SetSize( size );
1178   // @todo this really needs to be at the end of method but not sure why the scope used to be only the SetSize, needs to be cleaned up in size negotiation rework
1179   mImpl->mInsideRelayout = false;
1180
1181   // Only relayout controls which requested to be relaid out.
1182   OnRelaidOut( size, container );
1183 }
1184
1185 void Control::Relayout( Actor actor, Vector2 size, ActorSizeContainer& container )
1186 {
1187   if ( actor )
1188   {
1189     Toolkit::Control control( Toolkit::Control::DownCast( actor ) );
1190     if( control )
1191     {
1192       control.GetImplementation().NegotiateSize( size, container );
1193     }
1194     else
1195     {
1196       container.push_back( ActorSizePair( actor, size ) );
1197     }
1198   }
1199 }
1200
1201 void Control::OnRelaidOut( Vector2 size, ActorSizeContainer& container )
1202 {
1203   unsigned int numChildren = Self().GetChildCount();
1204
1205   for( unsigned int i=0; i<numChildren; ++i )
1206   {
1207     container.push_back( ActorSizePair( Self().GetChildAt(i), size ) );
1208   }
1209 }
1210
1211 void Control::NegotiateSize( Vector2 allocatedSize, ActorSizeContainer& container )
1212 {
1213   Vector2 size;
1214
1215   if ( mImpl->mWidthPolicy == Toolkit::Control::Fixed )
1216   {
1217     if ( mImpl->mHeightPolicy == Toolkit::Control::Fixed )
1218     {
1219       // If a control says it has a fixed size, then use the size set by the application / control.
1220       Vector2 setSize( mImpl->mNaturalSize );
1221       if ( setSize != Vector2::ZERO )
1222       {
1223         size = setSize;
1224
1225         // Policy is set to Fixed, so if the application / control has not set one of the dimensions,
1226         // then we should use the natural size of the control rather than the full allocation.
1227         if ( EqualsZero( size.width ) )
1228         {
1229           size.width = GetWidthForHeight( size.height );
1230         }
1231         else if ( EqualsZero( size.height ) )
1232         {
1233           size.height = GetHeightForWidth( size.width );
1234         }
1235       }
1236       else
1237       {
1238         // If that is not set then set the size to the control's natural size
1239         size = Vector2( GetNaturalSize() );
1240       }
1241     }
1242     else
1243     {
1244       // Width is fixed so if the application / control has set it, then use that.
1245       if ( !EqualsZero( mImpl->mNaturalSize.width ) )
1246       {
1247         size.width = mImpl->mNaturalSize.width;
1248       }
1249       else
1250       {
1251         // Otherwise, set the width to what has been allocated.
1252         size.width = allocatedSize.width;
1253       }
1254
1255       // Height is flexible so ask control what the height should be for our width.
1256       size.height = GetHeightForWidth( size.width );
1257
1258       // Ensure height is within our policy rules
1259       size.height = Calculate( mImpl->mHeightPolicy, GetMinimumSize().height, GetMaximumSize().height, size.height );
1260     }
1261   }
1262   else
1263   {
1264     if ( mImpl->mHeightPolicy == Toolkit::Control::Fixed )
1265     {
1266       // Height is fixed so if the application / control has set it, then use that.
1267       if ( !EqualsZero( mImpl->mNaturalSize.height ) )
1268       {
1269         size.height = mImpl->mNaturalSize.height;
1270       }
1271       else
1272       {
1273         // Otherwise, set the height to what has been allocated.
1274         size.height = allocatedSize.height;
1275       }
1276
1277       // Width is flexible so ask control what the width should be for our height.
1278       size.width = GetWidthForHeight( size.height );
1279
1280       // Ensure width is within our policy rules
1281       size.width = Calculate( mImpl->mWidthPolicy, mImpl->GetMinimumSize().width, mImpl->GetMaximumSize().width, size.width );
1282     }
1283     else
1284     {
1285       // Width and height are BOTH flexible.
1286       // Calculate the width and height using the policy rules.
1287       size.width = Calculate( mImpl->mWidthPolicy, mImpl->GetMinimumSize().width, mImpl->GetMaximumSize().width, allocatedSize.width );
1288       size.height = Calculate( mImpl->mHeightPolicy, mImpl->GetMinimumSize().height, mImpl->GetMaximumSize().height, allocatedSize.height );
1289     }
1290   }
1291
1292   // If the width has not been set, then set to the allocated width.
1293   // Also if the width set is greater than the allocated, then set to allocated (no exceed support).
1294   if ( EqualsZero( size.width ) || ( size.width > allocatedSize.width ) )
1295   {
1296     size.width = allocatedSize.width;
1297   }
1298
1299   // If the height has not been set, then set to the allocated height.
1300   // Also if the height set is greater than the allocated, then set to allocated (no exceed support).
1301   if ( EqualsZero( size.height ) || ( size.height > allocatedSize.height ) )
1302   {
1303     size.height = allocatedSize.height;
1304   }
1305
1306   DALI_LOG_INFO( gLogFilter, Debug::Verbose,
1307                  "%p: Natural: [%.2f, %.2f] Allocated: [%.2f, %.2f] Set: [%.2f, %.2f]\n",
1308                  Self().GetObjectPtr(),
1309                  GetNaturalSize().x, GetNaturalSize().y,
1310                  allocatedSize.x, allocatedSize.y,
1311                  size.x, size.y );
1312
1313   Relayout( size, container );
1314 }
1315
1316 bool Control::EmitKeyEventSignal( const KeyEvent& event )
1317 {
1318   // Guard against destruction during signal emission
1319   Dali::Toolkit::Control handle( GetOwner() );
1320
1321   bool consumed = false;
1322
1323   // signals are allocated dynamically when someone connects
1324   if ( !mImpl->mKeyEventSignalV2.Empty() )
1325   {
1326     consumed = mImpl->mKeyEventSignalV2.Emit( handle, event );
1327   }
1328
1329   if (!consumed)
1330   {
1331     // Notification for derived classes
1332     consumed = OnKeyEvent(event);
1333   }
1334
1335   return consumed;
1336 }
1337
1338 void Control::SignalConnected( SlotObserver* slotObserver, CallbackBase* callback )
1339 {
1340   mImpl->SignalConnected( slotObserver, callback );
1341 }
1342
1343 void Control::SignalDisconnected( SlotObserver* slotObserver, CallbackBase* callback )
1344 {
1345   mImpl->SignalDisconnected( slotObserver, callback );
1346 }
1347
1348 Control::Control( ControlBehaviour behaviourFlags )
1349 : CustomActorImpl( behaviourFlags & REQUIRES_TOUCH_EVENTS ),
1350   mImpl(new Impl(*this))
1351 {
1352   mImpl->mFlags = behaviourFlags;
1353 }
1354
1355 } // namespace Internal
1356
1357 } // namespace Toolkit
1358
1359 } // namespace Dali