18b0a8cb748b8c7dce91a54bb47616d3aa73abfc
[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::OnAccessibilityValueChange(bool isIncrease)
850 {
851   return false; // Accessibility value change action is not handled by default
852 }
853
854
855 void Control::SetKeyboardNavigationSupport(bool isSupported)
856 {
857   mImpl->mIsKeyboardNavigationSupported = isSupported;
858 }
859
860 bool Control::IsKeyboardNavigationSupported()
861 {
862   return mImpl->mIsKeyboardNavigationSupported;
863 }
864
865 void Control::SetAsKeyboardFocusGroup(bool isFocusGroup)
866 {
867   mImpl->mIsKeyboardFocusGroup = isFocusGroup;
868
869   // The following line will be removed when the deprecated API in KeyboardFocusManager is deleted
870   Toolkit::KeyboardFocusManager::Get().SetAsFocusGroup(Self(), isFocusGroup);
871 }
872
873 bool Control::IsKeyboardFocusGroup()
874 {
875   return Toolkit::KeyboardFocusManager::Get().IsFocusGroup(Self());
876 }
877
878 Actor Control::GetNextKeyboardFocusableActor(Actor currentFocusedActor, Toolkit::Control::KeyboardFocusNavigationDirection direction, bool loopEnabled)
879 {
880   return Actor();
881 }
882
883 bool Control::DoAction(BaseObject* object, const std::string& actionName, const std::vector<Property::Value>& attributes)
884 {
885   bool ret = false;
886
887   return ret;
888 }
889
890 void Control::DoActivatedAction(const PropertyValueContainer& attributes)
891 {
892   OnActivated();
893 }
894
895 Toolkit::Control::KeyEventSignalV2& Control::KeyEventSignal()
896 {
897   return mImpl->mKeyEventSignalV2;
898 }
899
900 void Control::SetSizePolicy( Toolkit::Control::SizePolicy widthPolicy, Toolkit::Control::SizePolicy heightPolicy )
901 {
902   bool relayoutRequest( false );
903
904   if ( ( mImpl->mWidthPolicy != widthPolicy ) || ( mImpl->mHeightPolicy != heightPolicy ) )
905   {
906     relayoutRequest = true;
907   }
908
909   mImpl->mWidthPolicy = widthPolicy;
910   mImpl->mHeightPolicy = heightPolicy;
911
912   // Ensure RelayoutRequest is called AFTER new policies have been set.
913   if ( relayoutRequest )
914   {
915     RelayoutRequest();
916   }
917 }
918
919 void Control::GetSizePolicy( Toolkit::Control::SizePolicy& widthPolicy, Toolkit::Control::SizePolicy& heightPolicy ) const
920 {
921   widthPolicy = mImpl->mWidthPolicy;
922   heightPolicy = mImpl->mHeightPolicy;
923 }
924
925 void Control::SetMinimumSize( const Vector3& size )
926 {
927   if ( mImpl->mMinimumSize != size )
928   {
929     mImpl->mMinimumSize = size;
930
931     // Only relayout if our control is using the minimum or range policy.
932     if ( ( mImpl->mHeightPolicy == Toolkit::Control::Minimum ) || ( mImpl->mWidthPolicy  == Toolkit::Control::Minimum ) ||
933          ( mImpl->mHeightPolicy == Toolkit::Control::Range   ) || ( mImpl->mWidthPolicy  == Toolkit::Control::Range   ) )
934     {
935       RelayoutRequest();
936     }
937   }
938 }
939
940 const Vector3& Control::GetMinimumSize() const
941 {
942   return mImpl->mMinimumSize;
943 }
944
945 void Control::SetMaximumSize( const Vector3& size )
946 {
947   if ( mImpl->mMaximumSize != size )
948   {
949     mImpl->mMaximumSize = size;
950
951     // Only relayout if our control is using the maximum or range policy.
952     if ( ( mImpl->mHeightPolicy == Toolkit::Control::Maximum ) || ( mImpl->mWidthPolicy  == Toolkit::Control::Maximum ) ||
953          ( mImpl->mHeightPolicy == Toolkit::Control::Range   ) || ( mImpl->mWidthPolicy  == Toolkit::Control::Range   ) )
954     {
955       RelayoutRequest();
956     }
957   }
958 }
959
960 const Vector3& Control::GetMaximumSize() const
961 {
962   return mImpl->mMaximumSize;
963 }
964
965 Vector3 Control::GetNaturalSize()
966 {
967   // could be overridden in derived classes.
968   return mImpl->mSetSize;
969 }
970
971 float Control::GetHeightForWidth( float width )
972 {
973   // could be overridden in derived classes.
974   float height( 0.0f );
975   if ( mImpl->mSetSize.width > 0.0f )
976   {
977     height = mImpl->mSetSize.height * width / mImpl->mSetSize.width;
978   }
979   return height;
980 }
981
982 float Control::GetWidthForHeight( float height )
983 {
984   // could be overridden in derived classes.
985   float width( 0.0f );
986   if ( mImpl->mSetSize.height > 0.0f )
987   {
988     width = mImpl->mSetSize.width * height / mImpl->mSetSize.height;
989   }
990   return width;
991 }
992
993 const Vector3& Control::GetControlSize() const
994 {
995   return mImpl->mSize;
996 }
997
998 const Vector3& Control::GetSizeSet() const
999 {
1000   return mImpl->mSetSize;
1001 }
1002
1003 void Control::SetKeyInputFocus()
1004 {
1005   if( Self().OnStage() )
1006   {
1007     Toolkit::KeyInputFocusManager::Get().SetFocus(Toolkit::Control::DownCast(Self()));
1008   }
1009 }
1010
1011 bool Control::HasKeyInputFocus()
1012 {
1013   bool result = false;
1014   if( Self().OnStage() )
1015   {
1016     result = Toolkit::KeyInputFocusManager::Get().IsKeyboardListener(Toolkit::Control::DownCast(Self()));
1017   }
1018   return result;
1019 }
1020
1021 void Control::ClearKeyInputFocus()
1022 {
1023   if( Self().OnStage() )
1024   {
1025     Toolkit::KeyInputFocusManager::Get().RemoveFocus(Toolkit::Control::DownCast(Self()));
1026   }
1027 }
1028
1029 void Control::RelayoutRequest()
1030 {
1031   Internal::RelayoutController::Get().Request();
1032 }
1033
1034 void Control::Relayout( Vector2 size, ActorSizeContainer& container )
1035 {
1036   // Avoids relayout again when OnSizeSet callback arrives.
1037   {
1038     SetSizeLock lock( mImpl->mLockSetSize );
1039     Self().SetSize( size );
1040   }
1041
1042   // Only relayout controls which requested to be relaid out.
1043   OnRelaidOut( size, container );
1044 }
1045
1046 void Control::Relayout( Actor actor, Vector2 size, ActorSizeContainer& container )
1047 {
1048   if ( actor )
1049   {
1050     Toolkit::Control control( Toolkit::Control::DownCast( actor ) );
1051     if( control )
1052     {
1053       control.GetImplementation().NegotiateSize( size, container );
1054     }
1055     else
1056     {
1057       container.push_back( ActorSizePair( actor, size ) );
1058     }
1059   }
1060 }
1061
1062 void Control::OnRelaidOut( Vector2 size, ActorSizeContainer& container )
1063 {
1064   unsigned int numChildren = Self().GetChildCount();
1065
1066   for( unsigned int i=0; i<numChildren; ++i )
1067   {
1068     container.push_back( ActorSizePair( Self().GetChildAt(i), size ) );
1069   }
1070 }
1071
1072 void Control::NegotiateSize( Vector2 allocatedSize, ActorSizeContainer& container )
1073 {
1074   Vector2 size;
1075
1076   if ( mImpl->mWidthPolicy == Toolkit::Control::Fixed )
1077   {
1078     if ( mImpl->mHeightPolicy == Toolkit::Control::Fixed )
1079     {
1080       // If a control says it has a fixed size, then use the size set by the application / control.
1081       Vector2 setSize( mImpl->mSetSize );
1082       if ( setSize != Vector2::ZERO )
1083       {
1084         size = setSize;
1085
1086         // Policy is set to Fixed, so if the application / control has not set one of the dimensions,
1087         // then we should use the natural size of the control rather than the full allocation.
1088         if ( EqualsZero( size.width ) )
1089         {
1090           size.width = GetWidthForHeight( size.height );
1091         }
1092         else if ( EqualsZero( size.height ) )
1093         {
1094           size.height = GetHeightForWidth( size.width );
1095         }
1096       }
1097       else
1098       {
1099         // If that is not set then set the size to the control's natural size
1100         size = Vector2( GetNaturalSize() );
1101       }
1102     }
1103     else
1104     {
1105       // Width is fixed so if the application / control has set it, then use that.
1106       if ( !EqualsZero( mImpl->mSetSize.width ) )
1107       {
1108         size.width = mImpl->mSetSize.width;
1109       }
1110       else
1111       {
1112         // Otherwise, set the width to what has been allocated.
1113         size.width = allocatedSize.width;
1114       }
1115
1116       // Height is flexible so ask control what the height should be for our width.
1117       size.height = GetHeightForWidth( size.width );
1118
1119       // Ensure height is within our policy rules
1120       size.height = Calculate( mImpl->mHeightPolicy, mImpl->mMinimumSize.height, mImpl->mMaximumSize.height, size.height );
1121     }
1122   }
1123   else
1124   {
1125     if ( mImpl->mHeightPolicy == Toolkit::Control::Fixed )
1126     {
1127       // Height is fixed so if the application / control has set it, then use that.
1128       if ( !EqualsZero( mImpl->mSetSize.height ) )
1129       {
1130         size.height = mImpl->mSetSize.height;
1131       }
1132       else
1133       {
1134         // Otherwise, set the height to what has been allocated.
1135         size.height = allocatedSize.height;
1136       }
1137
1138       // Width is flexible so ask control what the width should be for our height.
1139       size.width = GetWidthForHeight( size.height );
1140
1141       // Ensure width is within our policy rules
1142       size.width = Calculate( mImpl->mWidthPolicy, mImpl->mMinimumSize.width, mImpl->mMaximumSize.width, size.width );
1143     }
1144     else
1145     {
1146       // Width and height are BOTH flexible.
1147       // Calculate the width and height using the policy rules.
1148       size.width = Calculate( mImpl->mWidthPolicy, mImpl->mMinimumSize.width, mImpl->mMaximumSize.width, allocatedSize.width );
1149       size.height = Calculate( mImpl->mHeightPolicy, mImpl->mMinimumSize.height, mImpl->mMaximumSize.height, allocatedSize.height );
1150     }
1151   }
1152
1153   // If the width has not been set, then set to the allocated width.
1154   // Also if the width set is greater than the allocated, then set to allocated (no exceed support).
1155   if ( EqualsZero( size.width ) || ( size.width > allocatedSize.width ) )
1156   {
1157     size.width = allocatedSize.width;
1158   }
1159
1160   // If the height has not been set, then set to the allocated height.
1161   // Also if the height set is greater than the allocated, then set to allocated (no exceed support).
1162   if ( EqualsZero( size.height ) || ( size.height > allocatedSize.height ) )
1163   {
1164     size.height = allocatedSize.height;
1165   }
1166
1167   DALI_LOG_INFO( gLogFilter, Debug::Verbose,
1168                  "%p: Natural: [%.2f, %.2f] Allocated: [%.2f, %.2f] Set: [%.2f, %.2f]\n",
1169                  Self().GetObjectPtr(),
1170                  GetNaturalSize().x, GetNaturalSize().y,
1171                  allocatedSize.x, allocatedSize.y,
1172                  size.x, size.y );
1173
1174   Relayout( size, container );
1175 }
1176
1177 bool Control::EmitKeyEventSignal( const KeyEvent& event )
1178 {
1179   // Guard against destruction during signal emission
1180   Dali::Toolkit::Control handle( GetOwner() );
1181
1182   bool consumed = false;
1183
1184   // signals are allocated dynamically when someone connects
1185   if ( !mImpl->mKeyEventSignalV2.Empty() )
1186   {
1187     consumed = mImpl->mKeyEventSignalV2.Emit( handle, event );
1188   }
1189
1190   if (!consumed)
1191   {
1192     // Notification for derived classes
1193     consumed = OnKeyEvent(event);
1194   }
1195
1196   return consumed;
1197 }
1198
1199 void Control::SignalConnected( SlotObserver* slotObserver, CallbackBase* callback )
1200 {
1201   mImpl->SignalConnected( slotObserver, callback );
1202 }
1203
1204 void Control::SignalDisconnected( SlotObserver* slotObserver, CallbackBase* callback )
1205 {
1206   mImpl->SignalDisconnected( slotObserver, callback );
1207 }
1208
1209 std::size_t Control::GetConnectionCount() const
1210 {
1211   return mImpl->GetConnectionCount();
1212 }
1213
1214 Control::Control( bool requiresTouchEvents )
1215 : CustomActorImpl( requiresTouchEvents ),
1216   mImpl(new Impl(*this))
1217 {
1218 }
1219
1220 } // namespace Internal
1221
1222 } // namespace Toolkit
1223
1224 } // namespace Dali