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