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