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