[Tizen] Add AutofillContainer class and autofill implementation
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / controls / control / control-data-impl.cpp
1 /*
2  * Copyright (c) 2019 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 // CLASS HEADER
19 #include "control-data-impl.h"
20
21 // EXTERNAL INCLUDES
22 #include <dali-toolkit/public-api/dali-toolkit-common.h>
23 #include <dali/integration-api/debug.h>
24 #include <dali/devel-api/object/handle-devel.h>
25 #include <dali/devel-api/scripting/enum-helper.h>
26 #include <dali/devel-api/scripting/scripting.h>
27 #include <dali/integration-api/debug.h>
28 #include <dali/public-api/object/type-registry-helper.h>
29 #include <dali/integration-api/adaptor-framework/adaptor.h>
30 #include <dali/devel-api/common/stage.h>
31 #include <dali-toolkit/public-api/controls/control.h>
32 #include <dali/public-api/object/object-registry.h>
33 #include <dali/devel-api/adaptor-framework/accessibility.h>
34 #include <dali-toolkit/public-api/controls/control-impl.h>
35 #include <dali/devel-api/actors/actor-devel.h>
36 #include <cstring>
37 #include <limits>
38
39 // INTERNAL INCLUDES
40 #include <dali-toolkit/internal/visuals/visual-base-impl.h>
41 #include <dali-toolkit/public-api/visuals/image-visual-properties.h>
42 #include <dali-toolkit/public-api/visuals/visual-properties.h>
43 #include <dali-toolkit/devel-api/controls/control-depth-index-ranges.h>
44 #include <dali-toolkit/devel-api/controls/control-devel.h>
45 #include <dali-toolkit/devel-api/controls/control-wrapper-impl.h>
46 #include <dali-toolkit/internal/styling/style-manager-impl.h>
47 #include <dali-toolkit/internal/visuals/visual-string-constants.h>
48 #include <dali-toolkit/public-api/focus-manager/keyboard-focus-manager.h>
49 #include <dali-toolkit/public-api/controls/image-view/image-view.h>
50 #include <dali-toolkit/devel-api/asset-manager/asset-manager.h>
51
52 namespace
53 {
54   const std::string READING_INFO_TYPE_NAME = "name";
55   const std::string READING_INFO_TYPE_ROLE = "role";
56   const std::string READING_INFO_TYPE_DESCRIPTION = "description";
57   const std::string READING_INFO_TYPE_STATE = "state";
58   const std::string READING_INFO_TYPE_ATTRIBUTE_NAME = "reading_info_type";
59   const std::string READING_INFO_TYPE_SEPARATOR = "|";
60 }
61
62 namespace Dali
63 {
64
65 namespace Toolkit
66 {
67
68 namespace Internal
69 {
70
71 extern const Dali::Scripting::StringEnum ControlStateTable[];
72 extern const unsigned int ControlStateTableCount;
73
74
75 // Not static or anonymous - shared with other translation units
76 const Scripting::StringEnum ControlStateTable[] = {
77   { "NORMAL",   Toolkit::DevelControl::NORMAL   },
78   { "FOCUSED",  Toolkit::DevelControl::FOCUSED  },
79   { "DISABLED", Toolkit::DevelControl::DISABLED },
80 };
81 const unsigned int ControlStateTableCount = sizeof( ControlStateTable ) / sizeof( ControlStateTable[0] );
82
83
84
85 namespace
86 {
87
88 #if defined(DEBUG_ENABLED)
89 Debug::Filter* gLogFilter = Debug::Filter::New( Debug::NoLogging, false, "LOG_CONTROL_VISUALS");
90 #endif
91
92
93 template<typename T>
94 void Remove( Dictionary<T>& keyValues, const std::string& name )
95 {
96   keyValues.Remove(name);
97 }
98
99 void Remove( DictionaryKeys& keys, const std::string& name )
100 {
101   DictionaryKeys::iterator iter = std::find( keys.begin(), keys.end(), name );
102   if( iter != keys.end())
103   {
104     keys.erase(iter);
105   }
106 }
107
108 /**
109  *  Finds visual in given array, returning true if found along with the iterator for that visual as a out parameter
110  */
111 bool FindVisual( Property::Index targetIndex, const RegisteredVisualContainer& visuals, RegisteredVisualContainer::Iterator& iter )
112 {
113   for ( iter = visuals.Begin(); iter != visuals.End(); iter++ )
114   {
115     if ( (*iter)->index ==  targetIndex )
116     {
117       return true;
118     }
119   }
120   return false;
121 }
122
123 /**
124  *  Finds visual in given array, returning true if found along with the iterator for that visual as a out parameter
125  */
126 bool FindVisual( std::string visualName, const RegisteredVisualContainer& visuals, RegisteredVisualContainer::Iterator& iter )
127 {
128   for ( iter = visuals.Begin(); iter != visuals.End(); iter++ )
129   {
130     Toolkit::Visual::Base visual = (*iter)->visual;
131     if( visual && visual.GetName() == visualName )
132     {
133       return true;
134     }
135   }
136   return false;
137 }
138
139 void FindChangableVisuals( Dictionary<Property::Map>& stateVisualsToAdd,
140                            Dictionary<Property::Map>& stateVisualsToChange,
141                            DictionaryKeys& stateVisualsToRemove)
142 {
143   DictionaryKeys copyOfStateVisualsToRemove = stateVisualsToRemove;
144
145   for( DictionaryKeys::iterator iter = copyOfStateVisualsToRemove.begin();
146        iter != copyOfStateVisualsToRemove.end(); ++iter )
147   {
148     const std::string& visualName = (*iter);
149     Property::Map* toMap = stateVisualsToAdd.Find( visualName );
150     if( toMap )
151     {
152       stateVisualsToChange.Add( visualName, *toMap );
153       stateVisualsToAdd.Remove( visualName );
154       Remove( stateVisualsToRemove, visualName );
155     }
156   }
157 }
158
159 Toolkit::Visual::Base GetVisualByName(
160   const RegisteredVisualContainer& visuals,
161   const std::string& visualName )
162 {
163   Toolkit::Visual::Base visualHandle;
164
165   RegisteredVisualContainer::Iterator iter;
166   for ( iter = visuals.Begin(); iter != visuals.End(); iter++ )
167   {
168     Toolkit::Visual::Base visual = (*iter)->visual;
169     if( visual && visual.GetName() == visualName )
170     {
171       visualHandle = visual;
172       break;
173     }
174   }
175   return visualHandle;
176 }
177
178 Toolkit::Visual::Base GetVisualByIndex(
179   const RegisteredVisualContainer& visuals,
180   Property::Index                  index)
181 {
182   Toolkit::Visual::Base visualHandle;
183
184   RegisteredVisualContainer::Iterator iter;
185   for(iter = visuals.Begin(); iter != visuals.End(); iter++)
186   {
187     if((*iter)->index == index)
188     {
189       visualHandle = (*iter)->visual;
190       break;
191     }
192   }
193   return visualHandle;
194 }
195
196 /**
197  * Move visual from source to destination container
198  */
199 void MoveVisual( RegisteredVisualContainer::Iterator sourceIter, RegisteredVisualContainer& source, RegisteredVisualContainer& destination )
200 {
201    Toolkit::Visual::Base visual = (*sourceIter)->visual;
202    if( visual )
203    {
204      RegisteredVisual* rv = source.Release( sourceIter );
205      destination.PushBack( rv );
206    }
207 }
208
209 /**
210  * Performs actions as requested using the action name.
211  * @param[in] object The object on which to perform the action.
212  * @param[in] actionName The action to perform.
213  * @param[in] attributes The attributes with which to perfrom this action.
214  * @return true if action has been accepted by this control
215  */
216 const char* ACTION_ACCESSIBILITY_ACTIVATED         = "accessibilityActivated";
217 const char* ACTION_ACCESSIBILITY_READING_CANCELLED = "ReadingCancelled";
218 const char* ACTION_ACCESSIBILITY_READING_PAUSED    = "ReadingPaused";
219 const char* ACTION_ACCESSIBILITY_READING_RESUMED   = "ReadingResumed";
220 const char* ACTION_ACCESSIBILITY_READING_SKIPPED   = "ReadingSkipped";
221 const char* ACTION_ACCESSIBILITY_READING_STOPPED   = "ReadingStopped";
222
223 static bool DoAction( BaseObject* object, const std::string& actionName, const Property::Map& attributes )
224 {
225   bool ret = true;
226
227   Dali::BaseHandle handle( object );
228
229   Toolkit::Control control = Toolkit::Control::DownCast( handle );
230
231   DALI_ASSERT_ALWAYS( control );
232
233   if( 0 == strcmp( actionName.c_str(), ACTION_ACCESSIBILITY_ACTIVATED ) ||
234      actionName == "activate" )
235   {
236     // if cast succeeds there is an implementation so no need to check
237     if( !DevelControl::AccessibilityActivateSignal( control ).Empty() )
238       DevelControl::AccessibilityActivateSignal( control ).Emit();
239     else ret = Internal::GetImplementation( control ).OnAccessibilityActivated();
240   }
241   else if( 0 == strcmp( actionName.c_str(), ACTION_ACCESSIBILITY_READING_SKIPPED ) )
242   {
243     // if cast succeeds there is an implementation so no need to check
244     if( !DevelControl::AccessibilityReadingSkippedSignal( control ).Empty() )
245       DevelControl::AccessibilityReadingSkippedSignal( control ).Emit();
246   }
247   else if( 0 == strcmp( actionName.c_str(), ACTION_ACCESSIBILITY_READING_PAUSED ) )
248   {
249     // if cast succeeds there is an implementation so no need to check
250     if( !DevelControl::AccessibilityReadingPausedSignal( control ).Empty() )
251       DevelControl::AccessibilityReadingPausedSignal( control ).Emit();
252   }
253   else if( 0 == strcmp( actionName.c_str(), ACTION_ACCESSIBILITY_READING_RESUMED ) )
254   {
255     // if cast succeeds there is an implementation so no need to check
256     if( !DevelControl::AccessibilityReadingResumedSignal( control ).Empty() )
257       DevelControl::AccessibilityReadingResumedSignal( control ).Emit();
258   }
259   else if( 0 == strcmp( actionName.c_str(), ACTION_ACCESSIBILITY_READING_CANCELLED ) )
260   {
261     // if cast succeeds there is an implementation so no need to check
262     if( !DevelControl::AccessibilityReadingCancelledSignal( control ).Empty() )
263       DevelControl::AccessibilityReadingCancelledSignal( control ).Emit();
264   }
265   else if( 0 == strcmp( actionName.c_str(), ACTION_ACCESSIBILITY_READING_STOPPED ) )
266   {
267     // if cast succeeds there is an implementation so no need to check
268     if(!DevelControl::AccessibilityReadingStoppedSignal( control ).Empty())
269       DevelControl::AccessibilityReadingStoppedSignal( control ).Emit();
270   } else
271   {
272     ret = false;
273   }
274   return ret;
275 }
276
277 /**
278  * Connects a callback function with the object's signals.
279  * @param[in] object The object providing the signal.
280  * @param[in] tracker Used to disconnect the signal.
281  * @param[in] signalName The signal to connect to.
282  * @param[in] functor A newly allocated FunctorDelegate.
283  * @return True if the signal was connected.
284  * @post If a signal was connected, ownership of functor was passed to CallbackBase. Otherwise the caller is responsible for deleting the unused functor.
285  */
286 const char* SIGNAL_KEY_EVENT = "keyEvent";
287 const char* SIGNAL_KEY_INPUT_FOCUS_GAINED = "keyInputFocusGained";
288 const char* SIGNAL_KEY_INPUT_FOCUS_LOST = "keyInputFocusLost";
289 const char* SIGNAL_TAPPED = "tapped";
290 const char* SIGNAL_PANNED = "panned";
291 const char* SIGNAL_PINCHED = "pinched";
292 const char* SIGNAL_LONG_PRESSED = "longPressed";
293 const char* SIGNAL_GET_NAME = "getName";
294 const char* SIGNAL_GET_DESCRIPTION = "getDescription";
295 const char* SIGNAL_DO_GESTURE = "doGesture";
296 static bool DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
297 {
298   Dali::BaseHandle handle( object );
299
300   bool connected( false );
301   Toolkit::Control control = Toolkit::Control::DownCast( handle );
302   if ( control )
303   {
304     Internal::Control& controlImpl( Internal::GetImplementation( control ) );
305     connected = true;
306
307     if ( 0 == strcmp( signalName.c_str(), SIGNAL_KEY_EVENT ) )
308     {
309       controlImpl.KeyEventSignal().Connect( tracker, functor );
310     }
311     else if( 0 == strcmp( signalName.c_str(), SIGNAL_KEY_INPUT_FOCUS_GAINED ) )
312     {
313       controlImpl.KeyInputFocusGainedSignal().Connect( tracker, functor );
314     }
315     else if( 0 == strcmp( signalName.c_str(), SIGNAL_KEY_INPUT_FOCUS_LOST ) )
316     {
317       controlImpl.KeyInputFocusLostSignal().Connect( tracker, functor );
318     }
319     else if( 0 == strcmp( signalName.c_str(), SIGNAL_TAPPED ) )
320     {
321       controlImpl.EnableGestureDetection( GestureType::TAP );
322       controlImpl.GetTapGestureDetector().DetectedSignal().Connect( tracker, functor );
323     }
324     else if( 0 == strcmp( signalName.c_str(), SIGNAL_PANNED ) )
325     {
326       controlImpl.EnableGestureDetection( GestureType::PAN );
327       controlImpl.GetPanGestureDetector().DetectedSignal().Connect( tracker, functor );
328     }
329     else if( 0 == strcmp( signalName.c_str(), SIGNAL_PINCHED ) )
330     {
331       controlImpl.EnableGestureDetection( GestureType::PINCH );
332       controlImpl.GetPinchGestureDetector().DetectedSignal().Connect( tracker, functor );
333     }
334     else if( 0 == strcmp( signalName.c_str(), SIGNAL_LONG_PRESSED ) )
335     {
336       controlImpl.EnableGestureDetection( GestureType::LONG_PRESS );
337       controlImpl.GetLongPressGestureDetector().DetectedSignal().Connect( tracker, functor );
338     }
339     else if( 0 == strcmp( signalName.c_str(), SIGNAL_GET_NAME ) )
340     {
341       DevelControl::AccessibilityGetNameSignal( control ).Connect( tracker, functor );
342     }
343     else if( 0 == strcmp( signalName.c_str(), SIGNAL_GET_DESCRIPTION ) )
344     {
345       DevelControl::AccessibilityGetDescriptionSignal( control ).Connect( tracker, functor );
346     }
347     else if( 0 == strcmp( signalName.c_str(), SIGNAL_DO_GESTURE ) )
348     {
349       DevelControl::AccessibilityDoGestureSignal( control ).Connect( tracker, functor );
350     }
351
352   }
353   return connected;
354 }
355
356 /**
357  * Creates control through type registry
358  */
359 BaseHandle Create()
360 {
361   return Internal::Control::New();
362 }
363 // Setup signals and actions using the type-registry.
364 DALI_TYPE_REGISTRATION_BEGIN( Control, CustomActor, Create );
365
366 // Note: Properties are registered separately below.
367
368 SignalConnectorType registerSignal1( typeRegistration, SIGNAL_KEY_EVENT, &DoConnectSignal );
369 SignalConnectorType registerSignal2( typeRegistration, SIGNAL_KEY_INPUT_FOCUS_GAINED, &DoConnectSignal );
370 SignalConnectorType registerSignal3( typeRegistration, SIGNAL_KEY_INPUT_FOCUS_LOST, &DoConnectSignal );
371 SignalConnectorType registerSignal4( typeRegistration, SIGNAL_TAPPED, &DoConnectSignal );
372 SignalConnectorType registerSignal5( typeRegistration, SIGNAL_PANNED, &DoConnectSignal );
373 SignalConnectorType registerSignal6( typeRegistration, SIGNAL_PINCHED, &DoConnectSignal );
374 SignalConnectorType registerSignal7( typeRegistration, SIGNAL_LONG_PRESSED, &DoConnectSignal );
375 SignalConnectorType registerSignal8( typeRegistration, SIGNAL_GET_NAME, &DoConnectSignal );
376 SignalConnectorType registerSignal9( typeRegistration, SIGNAL_GET_DESCRIPTION, &DoConnectSignal );
377 SignalConnectorType registerSignal10( typeRegistration, SIGNAL_DO_GESTURE, &DoConnectSignal );
378
379 TypeAction registerAction1( typeRegistration, "activate", &DoAction );
380 TypeAction registerAction2( typeRegistration, ACTION_ACCESSIBILITY_ACTIVATED, &DoAction );
381 TypeAction registerAction3( typeRegistration, ACTION_ACCESSIBILITY_READING_SKIPPED, &DoAction );
382 TypeAction registerAction4( typeRegistration, ACTION_ACCESSIBILITY_READING_CANCELLED, &DoAction );
383 TypeAction registerAction5( typeRegistration, ACTION_ACCESSIBILITY_READING_STOPPED, &DoAction );
384 TypeAction registerAction6( typeRegistration, ACTION_ACCESSIBILITY_READING_PAUSED, &DoAction );
385 TypeAction registerAction7( typeRegistration, ACTION_ACCESSIBILITY_READING_RESUMED, &DoAction );
386
387 DALI_TYPE_REGISTRATION_END()
388
389 /**
390  * @brief Iterate through given container and setOffScene any visual found
391  *
392  * @param[in] container Container of visuals
393  * @param[in] parent Parent actor to remove visuals from
394  */
395 void SetVisualsOffScene( const RegisteredVisualContainer& container, Actor parent )
396 {
397   for( auto iter = container.Begin(), end = container.End() ; iter!= end; iter++)
398   {
399     if( (*iter)->visual )
400     {
401       DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Control::SetOffScene Setting visual(%d) off stage\n", (*iter)->index );
402       Toolkit::GetImplementation((*iter)->visual).SetOffScene( parent );
403     }
404   }
405 }
406
407 } // unnamed namespace
408
409
410 // Properties registered without macro to use specific member variables.
411 const PropertyRegistration Control::Impl::PROPERTY_1( typeRegistration, "styleName",              Toolkit::Control::Property::STYLE_NAME,                   Property::STRING,  &Control::Impl::SetProperty, &Control::Impl::GetProperty );
412 const PropertyRegistration Control::Impl::PROPERTY_4( typeRegistration, "keyInputFocus",          Toolkit::Control::Property::KEY_INPUT_FOCUS,              Property::BOOLEAN, &Control::Impl::SetProperty, &Control::Impl::GetProperty );
413 const PropertyRegistration Control::Impl::PROPERTY_5( typeRegistration, "background",             Toolkit::Control::Property::BACKGROUND,                   Property::MAP,     &Control::Impl::SetProperty, &Control::Impl::GetProperty );
414 const PropertyRegistration Control::Impl::PROPERTY_6( typeRegistration, "margin",                 Toolkit::Control::Property::MARGIN,                       Property::EXTENTS, &Control::Impl::SetProperty, &Control::Impl::GetProperty );
415 const PropertyRegistration Control::Impl::PROPERTY_7( typeRegistration, "padding",                Toolkit::Control::Property::PADDING,                      Property::EXTENTS, &Control::Impl::SetProperty, &Control::Impl::GetProperty );
416 const PropertyRegistration Control::Impl::PROPERTY_8( typeRegistration, "tooltip",                Toolkit::DevelControl::Property::TOOLTIP,                 Property::MAP,     &Control::Impl::SetProperty, &Control::Impl::GetProperty );
417 const PropertyRegistration Control::Impl::PROPERTY_9( typeRegistration, "state",                  Toolkit::DevelControl::Property::STATE,                   Property::STRING,  &Control::Impl::SetProperty, &Control::Impl::GetProperty );
418 const PropertyRegistration Control::Impl::PROPERTY_10( typeRegistration, "subState",               Toolkit::DevelControl::Property::SUB_STATE,               Property::STRING,  &Control::Impl::SetProperty, &Control::Impl::GetProperty );
419 const PropertyRegistration Control::Impl::PROPERTY_11( typeRegistration, "leftFocusableActorId",   Toolkit::DevelControl::Property::LEFT_FOCUSABLE_ACTOR_ID, Property::INTEGER, &Control::Impl::SetProperty, &Control::Impl::GetProperty );
420 const PropertyRegistration Control::Impl::PROPERTY_12( typeRegistration, "rightFocusableActorId", Toolkit::DevelControl::Property::RIGHT_FOCUSABLE_ACTOR_ID,Property::INTEGER, &Control::Impl::SetProperty, &Control::Impl::GetProperty );
421 const PropertyRegistration Control::Impl::PROPERTY_13( typeRegistration, "upFocusableActorId",    Toolkit::DevelControl::Property::UP_FOCUSABLE_ACTOR_ID,   Property::INTEGER, &Control::Impl::SetProperty, &Control::Impl::GetProperty );
422 const PropertyRegistration Control::Impl::PROPERTY_14( typeRegistration, "downFocusableActorId",  Toolkit::DevelControl::Property::DOWN_FOCUSABLE_ACTOR_ID, Property::INTEGER, &Control::Impl::SetProperty, &Control::Impl::GetProperty );
423 const PropertyRegistration Control::Impl::PROPERTY_15( typeRegistration, "shadow",                Toolkit::DevelControl::Property::SHADOW,                  Property::MAP,     &Control::Impl::SetProperty, &Control::Impl::GetProperty );
424 const PropertyRegistration Control::Impl::PROPERTY_16( typeRegistration, "accessibilityAttributes",         Toolkit::DevelControl::Property::ACCESSIBILITY_ATTRIBUTES,         Property::MAP,     &Control::Impl::SetProperty, &Control::Impl::GetProperty );
425 const PropertyRegistration Control::Impl::PROPERTY_17( typeRegistration, "accessibilityName",              Toolkit::DevelControl::Property::ACCESSIBILITY_NAME,               Property::STRING,  &Control::Impl::SetProperty, &Control::Impl::GetProperty );
426 const PropertyRegistration Control::Impl::PROPERTY_18( typeRegistration, "accessibilityDescription",       Toolkit::DevelControl::Property::ACCESSIBILITY_DESCRIPTION,         Property::STRING,  &Control::Impl::SetProperty, &Control::Impl::GetProperty );
427 const PropertyRegistration Control::Impl::PROPERTY_19( typeRegistration, "accessibilityTranslationDomain", Toolkit::DevelControl::Property::ACCESSIBILITY_TRANSLATION_DOMAIN, Property::STRING,  &Control::Impl::SetProperty, &Control::Impl::GetProperty );
428 const PropertyRegistration Control::Impl::PROPERTY_20( typeRegistration, "accessibilityRole",              Toolkit::DevelControl::Property::ACCESSIBILITY_ROLE,               Property::INTEGER, &Control::Impl::SetProperty, &Control::Impl::GetProperty );
429 const PropertyRegistration Control::Impl::PROPERTY_21( typeRegistration, "accessibilityHighlightable",     Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE,      Property::BOOLEAN, &Control::Impl::SetProperty, &Control::Impl::GetProperty );
430 const PropertyRegistration Control::Impl::PROPERTY_22( typeRegistration, "accessibilityAnimated",          Toolkit::DevelControl::Property::ACCESSIBILITY_ANIMATED,      Property::BOOLEAN, &Control::Impl::SetProperty, &Control::Impl::GetProperty );
431
432 Control::Impl::Impl( Control& controlImpl )
433 : mControlImpl( controlImpl ),
434   mState( Toolkit::DevelControl::NORMAL ),
435   mSubStateName(""),
436   mLeftFocusableActorId( -1 ),
437   mRightFocusableActorId( -1 ),
438   mUpFocusableActorId( -1 ),
439   mDownFocusableActorId( -1 ),
440   mStyleName(""),
441   mBackgroundColor(Color::TRANSPARENT),
442   mStartingPinchScale(nullptr),
443   mMargin( 0, 0, 0, 0 ),
444   mPadding( 0, 0, 0, 0 ),
445   mKeyEventSignal(),
446   mKeyInputFocusGainedSignal(),
447   mKeyInputFocusLostSignal(),
448   mResourceReadySignal(),
449   mVisualEventSignal(),
450   mAccessibilityGetNameSignal(),
451   mAccessibilityGetDescriptionSignal(),
452   mAccessibilityDoGestureSignal(),
453   mPinchGestureDetector(),
454   mPanGestureDetector(),
455   mTapGestureDetector(),
456   mLongPressGestureDetector(),
457   mTooltip( NULL ),
458   mInputMethodContext(),
459   mIdleCallback(nullptr),
460   mAutofillItem(),
461   mAutofillContainer(),
462   mFlags( Control::ControlBehaviour( CONTROL_BEHAVIOUR_DEFAULT ) ),
463   mIsKeyboardNavigationSupported( false ),
464   mIsKeyboardFocusGroup( false ),
465   mIsEmittingResourceReadySignal(false),
466   mNeedToEmitResourceReady(false),
467   mIsAutofillEnabled( false )
468 {
469   Dali::Accessibility::Accessible::RegisterControlAccessibilityGetter(
470       []( Dali::Actor actor ) -> Dali::Accessibility::Accessible* {
471         return Control::Impl::GetAccessibilityObject( actor );
472       } );
473
474   accessibilityConstructor =  []( Dali::Actor actor ) -> std::unique_ptr< Dali::Accessibility::Accessible > {
475         return std::unique_ptr< Dali::Accessibility::Accessible >( new AccessibleImpl( actor,
476                                 Dali::Accessibility::Role::UNKNOWN ) );
477       };
478
479   size_t len = static_cast<size_t>(Dali::Accessibility::RelationType::MAX_COUNT);
480   mAccessibilityRelations.reserve(len);
481   for (auto i = 0u; i < len; ++i)
482   {
483     mAccessibilityRelations.push_back({});
484   }
485 }
486
487 Control::Impl::~Impl()
488 {
489   for( auto&& iter : mVisuals )
490   {
491     StopObservingVisual( iter->visual );
492   }
493
494   for( auto&& iter : mRemoveVisuals )
495   {
496     StopObservingVisual( iter->visual );
497   }
498
499   AccessibilityDeregister();
500   // All gesture detectors will be destroyed so no need to disconnect.
501   delete mStartingPinchScale;
502
503   if(mIdleCallback && Adaptor::IsAvailable())
504   {
505     // Removes the callback from the callback manager in case the control is destroyed before the callback is executed.
506     Adaptor::Get().RemoveIdle(mIdleCallback);
507   }
508 }
509
510 Control::Impl& Control::Impl::Get( Internal::Control& internalControl )
511 {
512   return *internalControl.mImpl;
513 }
514
515 const Control::Impl& Control::Impl::Get( const Internal::Control& internalControl )
516 {
517   return *internalControl.mImpl;
518 }
519
520 // Gesture Detection Methods
521 void Control::Impl::PinchDetected(Actor actor, const PinchGesture& pinch)
522 {
523   mControlImpl.OnPinch(pinch);
524 }
525
526 void Control::Impl::PanDetected(Actor actor, const PanGesture& pan)
527 {
528   mControlImpl.OnPan(pan);
529 }
530
531 void Control::Impl::TapDetected(Actor actor, const TapGesture& tap)
532 {
533   mControlImpl.OnTap(tap);
534 }
535
536 void Control::Impl::LongPressDetected(Actor actor, const LongPressGesture& longPress)
537 {
538   mControlImpl.OnLongPress(longPress);
539 }
540
541 void Control::Impl::RegisterVisual( Property::Index index, Toolkit::Visual::Base& visual )
542 {
543   RegisterVisual( index, visual, VisualState::ENABLED, DepthIndexValue::NOT_SET );
544 }
545
546 void Control::Impl::RegisterVisual( Property::Index index, Toolkit::Visual::Base& visual, int depthIndex )
547 {
548   RegisterVisual( index, visual, VisualState::ENABLED, DepthIndexValue::SET, depthIndex );
549 }
550
551 void Control::Impl::RegisterVisual( Property::Index index, Toolkit::Visual::Base& visual, bool enabled )
552 {
553   RegisterVisual( index, visual, ( enabled ? VisualState::ENABLED : VisualState::DISABLED ), DepthIndexValue::NOT_SET );
554 }
555
556 void Control::Impl::RegisterVisual( Property::Index index, Toolkit::Visual::Base& visual, bool enabled, int depthIndex )
557 {
558   RegisterVisual( index, visual, ( enabled ? VisualState::ENABLED : VisualState::DISABLED ), DepthIndexValue::SET, depthIndex );
559 }
560
561 void Control::Impl::RegisterVisual( Property::Index index, Toolkit::Visual::Base& visual, VisualState::Type enabled, DepthIndexValue::Type depthIndexValueSet, int depthIndex )
562 {
563   DALI_LOG_INFO( gLogFilter, Debug::Concise, "RegisterVisual:%d \n", index );
564
565   bool visualReplaced ( false );
566   Actor self = mControlImpl.Self();
567
568   // Set the depth index, if not set by caller this will be either the current visual depth, max depth of all visuals
569   // or zero.
570   int requiredDepthIndex = visual.GetDepthIndex();
571
572   if( depthIndexValueSet == DepthIndexValue::SET )
573   {
574     requiredDepthIndex = depthIndex;
575   }
576
577   // Visual replacement, existing visual should only be removed from stage when replacement ready.
578   if( !mVisuals.Empty() )
579   {
580     RegisteredVisualContainer::Iterator registeredVisualsiter;
581     // Check if visual (index) is already registered, this is the current visual.
582     if( FindVisual( index, mVisuals, registeredVisualsiter ) )
583     {
584       Toolkit::Visual::Base& currentRegisteredVisual = (*registeredVisualsiter)->visual;
585       if( currentRegisteredVisual )
586       {
587         // Store current visual depth index as may need to set the replacement visual to same depth
588         const int currentDepthIndex = (*registeredVisualsiter)->visual.GetDepthIndex();
589
590         // No longer required to know if the replaced visual's resources are ready
591         StopObservingVisual( currentRegisteredVisual );
592
593         // If control staged and visual enabled then visuals will be swapped once ready
594         if(  self.GetProperty< bool >( Actor::Property::CONNECTED_TO_SCENE ) && enabled )
595         {
596           // Check if visual is currently in the process of being replaced ( is in removal container )
597           RegisteredVisualContainer::Iterator visualQueuedForRemoval;
598           if ( FindVisual( index, mRemoveVisuals, visualQueuedForRemoval ) )
599           {
600             // Visual with same index is already in removal container so current visual pending
601             // Only the the last requested visual will be displayed so remove current visual which is staged but not ready.
602             Toolkit::GetImplementation( currentRegisteredVisual ).SetOffScene( self );
603             mVisuals.Erase( registeredVisualsiter );
604           }
605           else
606           {
607             // current visual not already in removal container so add now.
608             DALI_LOG_INFO( gLogFilter, Debug::Verbose, "RegisterVisual Move current registered visual to removal Queue: %d \n", index );
609             MoveVisual( registeredVisualsiter, mVisuals, mRemoveVisuals );
610           }
611         }
612         else
613         {
614           // Control not staged or visual disabled so can just erase from registered visuals and new visual will be added later.
615           mVisuals.Erase( registeredVisualsiter );
616         }
617
618         // If we've not set the depth-index value and the new visual does not have a depth index applied to it, then use the previously set depth-index for this index
619         if( ( depthIndexValueSet == DepthIndexValue::NOT_SET ) &&
620             ( visual.GetDepthIndex() == 0 ) )
621         {
622           requiredDepthIndex = currentDepthIndex;
623         }
624       }
625
626       visualReplaced = true;
627     }
628   }
629
630   // If not set, set the name of the visual to the same name as the control's property.
631   // ( If the control has been type registered )
632   if( visual.GetName().empty() )
633   {
634     // returns empty string if index is not found as long as index is not -1
635     std::string visualName = self.GetPropertyName( index );
636     if( !visualName.empty() )
637     {
638       DALI_LOG_INFO( gLogFilter, Debug::Concise, "Setting visual name for property %d to %s\n",
639                      index, visualName.c_str() );
640       visual.SetName( visualName );
641     }
642   }
643
644   if( !visualReplaced ) // New registration entry
645   {
646     // If we've not set the depth-index value, we have more than one visual and the visual does not have a depth index, then set it to be the highest
647     if( ( depthIndexValueSet == DepthIndexValue::NOT_SET ) &&
648         ( mVisuals.Size() > 0 ) &&
649         ( visual.GetDepthIndex() == 0 ) )
650     {
651       int maxDepthIndex = std::numeric_limits< int >::min();
652
653       RegisteredVisualContainer::ConstIterator iter;
654       const RegisteredVisualContainer::ConstIterator endIter = mVisuals.End();
655       for ( iter = mVisuals.Begin(); iter != endIter; iter++ )
656       {
657         const int visualDepthIndex = (*iter)->visual.GetDepthIndex();
658         if ( visualDepthIndex > maxDepthIndex )
659         {
660           maxDepthIndex = visualDepthIndex;
661         }
662       }
663       ++maxDepthIndex; // Add one to the current maximum depth index so that our added visual appears on top
664       requiredDepthIndex = std::max( 0, maxDepthIndex ); // Start at zero if maxDepth index belongs to a background
665     }
666   }
667
668   if( visual )
669   {
670     // Set determined depth index
671     visual.SetDepthIndex( requiredDepthIndex );
672
673     // Monitor when the visual resources are ready
674     StartObservingVisual( visual );
675
676     DALI_LOG_INFO( gLogFilter, Debug::Concise, "New Visual registration index[%d] depth[%d]\n", index, requiredDepthIndex );
677     RegisteredVisual* newRegisteredVisual  = new RegisteredVisual( index, visual,
678                                              ( enabled == VisualState::ENABLED ? true : false ),
679                                              ( visualReplaced && enabled ) ) ;
680     mVisuals.PushBack( newRegisteredVisual );
681
682     Internal::Visual::Base& visualImpl = Toolkit::GetImplementation( visual );
683     // Put on stage if enabled and the control is already on the stage
684     if( ( enabled == VisualState::ENABLED ) && self.GetProperty< bool >( Actor::Property::CONNECTED_TO_SCENE ) )
685     {
686       visualImpl.SetOnScene( self );
687     }
688     else if( visualImpl.IsResourceReady() ) // When not being staged, check if visual already 'ResourceReady' before it was Registered. ( Resource may have been loaded already )
689     {
690       ResourceReady( visualImpl );
691     }
692
693   }
694
695   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Control::RegisterVisual() Registered %s(%d), enabled:%s\n",  visual.GetName().c_str(), index, enabled?"true":"false" );
696 }
697
698 void Control::Impl::UnregisterVisual( Property::Index index )
699 {
700   RegisteredVisualContainer::Iterator iter;
701   if ( FindVisual( index, mVisuals, iter ) )
702   {
703     // stop observing visual
704     StopObservingVisual( (*iter)->visual );
705
706     Actor self( mControlImpl.Self() );
707     Toolkit::GetImplementation((*iter)->visual).SetOffScene( self );
708     (*iter)->visual.Reset();
709     mVisuals.Erase( iter );
710   }
711
712   if( FindVisual( index, mRemoveVisuals, iter ) )
713   {
714     Actor self( mControlImpl.Self() );
715     Toolkit::GetImplementation( (*iter)->visual ).SetOffScene( self );
716     (*iter)->pending = false;
717     (*iter)->visual.Reset();
718     mRemoveVisuals.Erase( iter );
719   }
720 }
721
722 Toolkit::Visual::Base Control::Impl::GetVisual( Property::Index index ) const
723 {
724   RegisteredVisualContainer::Iterator iter;
725   if ( FindVisual( index, mVisuals, iter ) )
726   {
727     return (*iter)->visual;
728   }
729
730   return Toolkit::Visual::Base();
731 }
732
733 void Control::Impl::EnableVisual( Property::Index index, bool enable )
734 {
735   DALI_LOG_INFO( gLogFilter, Debug::General, "Control::EnableVisual(%d, %s)\n", index, enable?"T":"F");
736
737   RegisteredVisualContainer::Iterator iter;
738   if ( FindVisual( index, mVisuals, iter ) )
739   {
740     if (  (*iter)->enabled == enable )
741     {
742       DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Control::EnableVisual Visual %s(%d) already %s\n", (*iter)->visual.GetName().c_str(), index, enable?"enabled":"disabled");
743       return;
744     }
745
746     (*iter)->enabled = enable;
747     Actor parentActor = mControlImpl.Self();
748     if ( mControlImpl.Self().GetProperty< bool >( Actor::Property::CONNECTED_TO_SCENE ) ) // If control not on Scene then Visual will be added when SceneConnection is called.
749     {
750       if ( enable )
751       {
752         DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Control::EnableVisual Setting %s(%d) on stage \n", (*iter)->visual.GetName().c_str(), index );
753         Toolkit::GetImplementation((*iter)->visual).SetOnScene( parentActor );
754       }
755       else
756       {
757         DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Control::EnableVisual Setting %s(%d) off stage \n", (*iter)->visual.GetName().c_str(), index );
758         Toolkit::GetImplementation((*iter)->visual).SetOffScene( parentActor );  // No need to call if control not staged.
759       }
760     }
761   }
762   else
763   {
764     DALI_LOG_WARNING( "Control::EnableVisual(%d, %s) FAILED - NO SUCH VISUAL\n", index, enable?"T":"F" );
765   }
766 }
767
768 bool Control::Impl::IsVisualEnabled( Property::Index index ) const
769 {
770   RegisteredVisualContainer::Iterator iter;
771   if ( FindVisual( index, mVisuals, iter ) )
772   {
773     return (*iter)->enabled;
774   }
775   return false;
776 }
777
778 void Control::Impl::StopObservingVisual( Toolkit::Visual::Base& visual )
779 {
780   Internal::Visual::Base& visualImpl = Toolkit::GetImplementation( visual );
781
782   // Stop observing the visual
783   visualImpl.RemoveEventObserver( *this );
784 }
785
786 void Control::Impl::StartObservingVisual( Toolkit::Visual::Base& visual)
787 {
788   Internal::Visual::Base& visualImpl = Toolkit::GetImplementation( visual );
789
790   // start observing the visual for events
791   visualImpl.AddEventObserver( *this );
792 }
793
794 // Called by a Visual when it's resource is ready
795 void Control::Impl::ResourceReady( Visual::Base& object)
796 {
797   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Control::Impl::ResourceReady() replacements pending[%d]\n", mRemoveVisuals.Count() );
798
799   Actor self = mControlImpl.Self();
800
801   // A resource is ready, find resource in the registered visuals container and get its index
802   for( auto registeredIter = mVisuals.Begin(),  end = mVisuals.End(); registeredIter != end; ++registeredIter )
803   {
804     Internal::Visual::Base& registeredVisualImpl = Toolkit::GetImplementation( (*registeredIter)->visual );
805
806     if( &object == &registeredVisualImpl )
807     {
808       RegisteredVisualContainer::Iterator visualToRemoveIter;
809       // Find visual with the same index in the removal container
810       // Set if off stage as it's replacement is now ready.
811       // Remove if from removal list as now removed from stage.
812       // Set Pending flag on the ready visual to false as now ready.
813       if( FindVisual( (*registeredIter)->index, mRemoveVisuals, visualToRemoveIter ) )
814       {
815         (*registeredIter)->pending = false;
816         Toolkit::GetImplementation( (*visualToRemoveIter)->visual ).SetOffScene( self );
817         mRemoveVisuals.Erase( visualToRemoveIter );
818       }
819       break;
820     }
821   }
822
823   // A visual is ready so control may need relayouting if staged
824   if ( self.GetProperty< bool >( Actor::Property::CONNECTED_TO_SCENE ) )
825   {
826     mControlImpl.RelayoutRequest();
827   }
828
829   // Emit signal if all enabled visuals registered by the control are ready.
830   if( IsResourceReady() )
831   {
832     // Reset the flag
833     mNeedToEmitResourceReady = false;
834
835     EmitResourceReadySignal();
836   }
837 }
838
839 void Control::Impl::NotifyVisualEvent( Visual::Base& object, Property::Index signalId )
840 {
841   for( auto registeredIter = mVisuals.Begin(),  end = mVisuals.End(); registeredIter != end; ++registeredIter )
842   {
843     Internal::Visual::Base& registeredVisualImpl = Toolkit::GetImplementation( (*registeredIter)->visual );
844     if( &object == &registeredVisualImpl )
845     {
846       Dali::Toolkit::Control handle( mControlImpl.GetOwner() );
847       mVisualEventSignal.Emit( handle, (*registeredIter)->index, signalId );
848       break;
849     }
850   }
851 }
852
853 bool Control::Impl::IsResourceReady() const
854 {
855   // Iterate through and check all the enabled visuals are ready
856   for( auto visualIter = mVisuals.Begin();
857          visualIter != mVisuals.End(); ++visualIter )
858   {
859     const Toolkit::Visual::Base visual = (*visualIter)->visual;
860     const Internal::Visual::Base& visualImpl = Toolkit::GetImplementation( visual );
861
862     // one of the enabled visuals is not ready
863     if( !visualImpl.IsResourceReady() && (*visualIter)->enabled )
864     {
865       return false;
866     }
867   }
868   return true;
869 }
870
871 Toolkit::Visual::ResourceStatus Control::Impl::GetVisualResourceStatus( Property::Index index ) const
872 {
873   RegisteredVisualContainer::Iterator iter;
874   if ( FindVisual( index, mVisuals, iter ) )
875   {
876     const Toolkit::Visual::Base visual = (*iter)->visual;
877     const Internal::Visual::Base& visualImpl = Toolkit::GetImplementation( visual );
878     return visualImpl.GetResourceStatus( );
879   }
880
881   return Toolkit::Visual::ResourceStatus::PREPARING;
882 }
883
884
885
886 void Control::Impl::AddTransitions( Dali::Animation& animation,
887                                     const Toolkit::TransitionData& handle,
888                                     bool createAnimation )
889 {
890   // Setup a Transition from TransitionData.
891   const Internal::TransitionData& transitionData = Toolkit::GetImplementation( handle );
892   TransitionData::Iterator end = transitionData.End();
893   for( TransitionData::Iterator iter = transitionData.Begin() ;
894        iter != end; ++iter )
895   {
896     TransitionData::Animator* animator = (*iter);
897
898     Toolkit::Visual::Base visual = GetVisualByName( mVisuals, animator->objectName );
899
900     if( visual )
901     {
902 #if defined(DEBUG_ENABLED)
903       Dali::TypeInfo typeInfo;
904       ControlWrapper* controlWrapperImpl = dynamic_cast<ControlWrapper*>(&mControlImpl);
905       if( controlWrapperImpl )
906       {
907         typeInfo = controlWrapperImpl->GetTypeInfo();
908       }
909
910       DALI_LOG_INFO( gLogFilter, Debug::Concise, "CreateTransition: Found %s visual for %s\n",
911                      visual.GetName().c_str(), typeInfo?typeInfo.GetName().c_str():"Unknown" );
912 #endif
913       Internal::Visual::Base& visualImpl = Toolkit::GetImplementation( visual );
914       visualImpl.AnimateProperty( animation, *animator );
915     }
916     else
917     {
918       DALI_LOG_INFO( gLogFilter, Debug::Concise, "CreateTransition: Could not find visual. Trying actors");
919       // Otherwise, try any actor children of control (Including the control)
920       Actor child = mControlImpl.Self().FindChildByName( animator->objectName );
921       if( child )
922       {
923         Property::Index propertyIndex = child.GetPropertyIndex( animator->propertyKey );
924         if( propertyIndex != Property::INVALID_INDEX )
925         {
926           if( animator->animate == false )
927           {
928             if( animator->targetValue.GetType() != Property::NONE )
929             {
930               child.SetProperty( propertyIndex, animator->targetValue );
931             }
932           }
933           else // animate the property
934           {
935             if( animator->initialValue.GetType() != Property::NONE )
936             {
937               child.SetProperty( propertyIndex, animator->initialValue );
938             }
939
940             if( createAnimation && !animation )
941             {
942               animation = Dali::Animation::New( 0.1f );
943             }
944
945             animation.AnimateTo( Property( child, propertyIndex ),
946                                  animator->targetValue,
947                                  animator->alphaFunction,
948                                  TimePeriod( animator->timePeriodDelay,
949                                              animator->timePeriodDuration ) );
950           }
951         }
952       }
953     }
954   }
955 }
956
957 Dali::Animation Control::Impl::CreateTransition( const Toolkit::TransitionData& transitionData )
958 {
959   Dali::Animation transition;
960
961   if( transitionData.Count() > 0 )
962   {
963     AddTransitions( transition, transitionData, true );
964   }
965   return transition;
966 }
967
968
969
970 void Control::Impl::DoAction( Dali::Property::Index visualIndex, Dali::Property::Index actionId, const Dali::Property::Value attributes )
971 {
972   RegisteredVisualContainer::Iterator iter;
973   if ( FindVisual( visualIndex, mVisuals, iter ) )
974   {
975     Toolkit::GetImplementation((*iter)->visual).DoAction( actionId, attributes );
976   }
977 }
978
979 void Control::Impl::AppendAccessibilityAttribute( const std::string& key,
980                                                const std::string value )
981 {
982   Property::Value* val = mAccessibilityAttributes.Find( key );
983   if( val )
984   {
985     mAccessibilityAttributes[key] = Property::Value( value );
986   }
987   else
988   {
989     mAccessibilityAttributes.Insert( key, value );
990   }
991 }
992
993 void Control::Impl::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value )
994 {
995   Toolkit::Control control = Toolkit::Control::DownCast( BaseHandle( object ) );
996
997   if ( control )
998   {
999     Control& controlImpl( GetImplementation( control ) );
1000
1001     switch ( index )
1002     {
1003       case Toolkit::Control::Property::STYLE_NAME:
1004       {
1005         controlImpl.SetStyleName( value.Get< std::string >() );
1006         break;
1007       }
1008
1009       case Toolkit::DevelControl::Property::STATE:
1010       {
1011         bool withTransitions=true;
1012         const Property::Value* valuePtr=&value;
1013         const Property::Map* map = value.GetMap();
1014         if(map)
1015         {
1016           Property::Value* value2 = map->Find("withTransitions");
1017           if( value2 )
1018           {
1019             withTransitions = value2->Get<bool>();
1020           }
1021
1022           valuePtr = map->Find("state");
1023         }
1024
1025         if( valuePtr )
1026         {
1027           Toolkit::DevelControl::State state( controlImpl.mImpl->mState );
1028           if( Scripting::GetEnumerationProperty< Toolkit::DevelControl::State >( *valuePtr, ControlStateTable, ControlStateTableCount, state ) )
1029           {
1030             controlImpl.mImpl->SetState( state, withTransitions );
1031           }
1032         }
1033       }
1034       break;
1035
1036       case Toolkit::DevelControl::Property::SUB_STATE:
1037       {
1038         std::string subState;
1039         if( value.Get( subState ) )
1040         {
1041           controlImpl.mImpl->SetSubState( subState );
1042         }
1043       }
1044       break;
1045
1046       case Toolkit::DevelControl::Property::LEFT_FOCUSABLE_ACTOR_ID:
1047       {
1048         int focusId;
1049         if( value.Get( focusId ) )
1050         {
1051           controlImpl.mImpl->mLeftFocusableActorId = focusId;
1052         }
1053       }
1054       break;
1055
1056       case Toolkit::DevelControl::Property::RIGHT_FOCUSABLE_ACTOR_ID:
1057       {
1058         int focusId;
1059         if( value.Get( focusId ) )
1060         {
1061           controlImpl.mImpl->mRightFocusableActorId = focusId;
1062         }
1063       }
1064       break;
1065
1066       case Toolkit::DevelControl::Property::ACCESSIBILITY_NAME:
1067       {
1068         std::string name;
1069         if( value.Get( name ) )
1070         {
1071           controlImpl.mImpl->mAccessibilityName = name;
1072           controlImpl.mImpl->mAccessibilityNameSet = true;
1073         }
1074         else
1075         {
1076           controlImpl.mImpl->mAccessibilityNameSet = false;
1077         }
1078       }
1079       break;
1080
1081       case Toolkit::DevelControl::Property::ACCESSIBILITY_DESCRIPTION:
1082       {
1083         std::string txt;
1084         if( value.Get( txt ) )
1085         {
1086           controlImpl.mImpl->mAccessibilityDescription = txt;
1087           controlImpl.mImpl->mAccessibilityDescriptionSet = true;
1088         }
1089         else
1090         {
1091           controlImpl.mImpl->mAccessibilityDescriptionSet = false;
1092         }
1093       }
1094       break;
1095
1096       case Toolkit::DevelControl::Property::ACCESSIBILITY_TRANSLATION_DOMAIN:
1097       {
1098         std::string txt;
1099         if( value.Get( txt ) )
1100         {
1101           controlImpl.mImpl->mAccessibilityTranslationDomain = txt;
1102           controlImpl.mImpl->mAccessibilityTranslationDomainSet = true;
1103         }
1104         else
1105         {
1106           controlImpl.mImpl->mAccessibilityTranslationDomainSet = false;
1107         }
1108       }
1109       break;
1110
1111       case Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE:
1112       {
1113         bool highlightable;
1114         if( value.Get( highlightable ) )
1115         {
1116           controlImpl.mImpl->mAccessibilityHighlightable = highlightable;
1117           controlImpl.mImpl->mAccessibilityHighlightableSet = true;
1118         }
1119         else
1120         {
1121           controlImpl.mImpl->mAccessibilityHighlightableSet = false;
1122         }
1123       }
1124       break;
1125
1126       case Toolkit::DevelControl::Property::ACCESSIBILITY_ROLE:
1127       {
1128         Dali::Accessibility::Role val;
1129         if( value.Get( val ) )
1130         {
1131           controlImpl.mImpl->mAccessibilityRole = val;
1132         }
1133       }
1134       break;
1135
1136       case Toolkit::DevelControl::Property::UP_FOCUSABLE_ACTOR_ID:
1137       {
1138         int focusId;
1139         if( value.Get( focusId ) )
1140         {
1141           controlImpl.mImpl->mUpFocusableActorId = focusId;
1142         }
1143       }
1144       break;
1145
1146       case Toolkit::DevelControl::Property::DOWN_FOCUSABLE_ACTOR_ID:
1147       {
1148         int focusId;
1149         if( value.Get( focusId ) )
1150         {
1151           controlImpl.mImpl->mDownFocusableActorId = focusId;
1152         }
1153       }
1154       break;
1155
1156       case Toolkit::Control::Property::KEY_INPUT_FOCUS:
1157       {
1158         if ( value.Get< bool >() )
1159         {
1160           controlImpl.SetKeyInputFocus();
1161         }
1162         else
1163         {
1164           controlImpl.ClearKeyInputFocus();
1165         }
1166         break;
1167       }
1168
1169       case Toolkit::Control::Property::BACKGROUND:
1170       {
1171         std::string url;
1172         Vector4 color;
1173         const Property::Map* map = value.GetMap();
1174         if( map && !map->Empty() )
1175         {
1176           controlImpl.SetBackground( *map );
1177         }
1178         else if( value.Get( url ) )
1179         {
1180           // don't know the size to load
1181           Toolkit::Visual::Base visual = Toolkit::VisualFactory::Get().CreateVisual( url, ImageDimensions() );
1182           if( visual )
1183           {
1184             controlImpl.mImpl->RegisterVisual( Toolkit::Control::Property::BACKGROUND, visual, DepthIndex::BACKGROUND );
1185           }
1186         }
1187         else if( value.Get( color ) )
1188         {
1189           controlImpl.SetBackgroundColor(color);
1190         }
1191         else
1192         {
1193           // The background is an empty property map, so we should clear the background
1194           controlImpl.ClearBackground();
1195         }
1196         break;
1197       }
1198
1199       case Toolkit::Control::Property::MARGIN:
1200       {
1201         Extents margin;
1202         if( value.Get( margin ) )
1203         {
1204           controlImpl.mImpl->SetMargin( margin );
1205         }
1206         break;
1207       }
1208
1209       case Toolkit::Control::Property::PADDING:
1210       {
1211         Extents padding;
1212         if( value.Get( padding ) )
1213         {
1214           controlImpl.mImpl->SetPadding( padding );
1215         }
1216         break;
1217       }
1218
1219       case Toolkit::DevelControl::Property::TOOLTIP:
1220       {
1221         TooltipPtr& tooltipPtr = controlImpl.mImpl->mTooltip;
1222         if( ! tooltipPtr )
1223         {
1224           tooltipPtr = Tooltip::New( control );
1225         }
1226         tooltipPtr->SetProperties( value );
1227         break;
1228       }
1229
1230       case Toolkit::DevelControl::Property::SHADOW:
1231       {
1232         const Property::Map* map = value.GetMap();
1233         if( map && !map->Empty() )
1234         {
1235           controlImpl.mImpl->SetShadow( *map );
1236         }
1237         else
1238         {
1239           // The shadow is an empty property map, so we should clear the shadow
1240           controlImpl.mImpl->ClearShadow();
1241         }
1242         break;
1243       }
1244
1245       case Toolkit::DevelControl::Property::ACCESSIBILITY_ATTRIBUTES:
1246       {
1247         const Property::Map* map = value.GetMap();
1248         if( map && !map->Empty() )
1249         {
1250           controlImpl.mImpl->mAccessibilityAttributes = *map;
1251         }
1252         break;
1253       }
1254
1255       case Toolkit::DevelControl::Property::ACCESSIBILITY_ANIMATED:
1256       {
1257         bool animated;
1258         if( value.Get( animated ) )
1259         {
1260           controlImpl.mImpl->mAccessibilityAnimated = animated;
1261         }
1262         break;
1263       }
1264     }
1265   }
1266 }
1267
1268 Property::Value Control::Impl::GetProperty( BaseObject* object, Property::Index index )
1269 {
1270   Property::Value value;
1271
1272   Toolkit::Control control = Toolkit::Control::DownCast( BaseHandle( object ) );
1273
1274   if ( control )
1275   {
1276     Control& controlImpl( GetImplementation( control ) );
1277
1278     switch ( index )
1279     {
1280       case Toolkit::Control::Property::STYLE_NAME:
1281       {
1282         value = controlImpl.GetStyleName();
1283         break;
1284       }
1285
1286       case Toolkit::DevelControl::Property::STATE:
1287       {
1288         value = controlImpl.mImpl->mState;
1289         break;
1290       }
1291
1292       case Toolkit::DevelControl::Property::SUB_STATE:
1293       {
1294         value = controlImpl.mImpl->mSubStateName;
1295         break;
1296       }
1297
1298       case Toolkit::DevelControl::Property::LEFT_FOCUSABLE_ACTOR_ID:
1299       {
1300         value = controlImpl.mImpl->mLeftFocusableActorId;
1301         break;
1302       }
1303
1304       case Toolkit::DevelControl::Property::RIGHT_FOCUSABLE_ACTOR_ID:
1305       {
1306         value = controlImpl.mImpl->mRightFocusableActorId;
1307         break;
1308       }
1309
1310       case Toolkit::DevelControl::Property::ACCESSIBILITY_NAME:
1311       {
1312         if (controlImpl.mImpl->mAccessibilityNameSet)
1313         {
1314           value = controlImpl.mImpl->mAccessibilityName;
1315         }
1316         break;
1317       }
1318
1319       case Toolkit::DevelControl::Property::ACCESSIBILITY_DESCRIPTION:
1320       {
1321         if (controlImpl.mImpl->mAccessibilityDescriptionSet)
1322         {
1323           value = controlImpl.mImpl->mAccessibilityDescription;
1324         }
1325         break;
1326       }
1327
1328       case Toolkit::DevelControl::Property::ACCESSIBILITY_TRANSLATION_DOMAIN:
1329       {
1330         if (controlImpl.mImpl->mAccessibilityTranslationDomainSet)
1331         {
1332           value = controlImpl.mImpl->mAccessibilityTranslationDomain;
1333         }
1334         break;
1335       }
1336
1337       case Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE:
1338       {
1339         if (controlImpl.mImpl->mAccessibilityHighlightableSet)
1340         {
1341           value = controlImpl.mImpl->mAccessibilityHighlightable;
1342         }
1343         break;
1344       }
1345
1346       case Toolkit::DevelControl::Property::ACCESSIBILITY_ROLE:
1347       {
1348         value = Property::Value(controlImpl.mImpl->mAccessibilityRole);
1349         break;
1350       }
1351
1352       case Toolkit::DevelControl::Property::UP_FOCUSABLE_ACTOR_ID:
1353       {
1354         value = controlImpl.mImpl->mUpFocusableActorId;
1355         break;
1356       }
1357
1358       case Toolkit::DevelControl::Property::DOWN_FOCUSABLE_ACTOR_ID:
1359       {
1360         value = controlImpl.mImpl->mDownFocusableActorId;
1361         break;
1362       }
1363
1364       case Toolkit::Control::Property::KEY_INPUT_FOCUS:
1365       {
1366         value = controlImpl.HasKeyInputFocus();
1367         break;
1368       }
1369
1370       case Toolkit::Control::Property::BACKGROUND:
1371       {
1372         Property::Map map;
1373         Toolkit::Visual::Base visual = controlImpl.mImpl->GetVisual( Toolkit::Control::Property::BACKGROUND );
1374         if( visual )
1375         {
1376           visual.CreatePropertyMap( map );
1377         }
1378
1379         value = map;
1380         break;
1381       }
1382
1383       case Toolkit::Control::Property::MARGIN:
1384       {
1385         value = controlImpl.mImpl->GetMargin();
1386         break;
1387       }
1388
1389       case Toolkit::Control::Property::PADDING:
1390       {
1391         value = controlImpl.mImpl->GetPadding();
1392         break;
1393       }
1394
1395       case Toolkit::DevelControl::Property::TOOLTIP:
1396       {
1397         Property::Map map;
1398         if( controlImpl.mImpl->mTooltip )
1399         {
1400           controlImpl.mImpl->mTooltip->CreatePropertyMap( map );
1401         }
1402         value = map;
1403         break;
1404       }
1405
1406       case Toolkit::DevelControl::Property::SHADOW:
1407       {
1408         Property::Map map;
1409         Toolkit::Visual::Base visual = controlImpl.mImpl->GetVisual( Toolkit::DevelControl::Property::SHADOW );
1410         if( visual )
1411         {
1412           visual.CreatePropertyMap( map );
1413         }
1414
1415         value = map;
1416         break;
1417       }
1418
1419       case Toolkit::DevelControl::Property::ACCESSIBILITY_ATTRIBUTES:
1420       {
1421         value = controlImpl.mImpl->mAccessibilityAttributes;
1422         break;
1423       }
1424
1425       case Toolkit::DevelControl::Property::ACCESSIBILITY_ANIMATED:
1426       {
1427         value = controlImpl.mImpl->mAccessibilityAnimated;
1428         break;
1429       }
1430     }
1431   }
1432
1433   return value;
1434 }
1435
1436 void Control::Impl::RemoveAccessibilityAttribute( const std::string& key )
1437 {
1438   Property::Value* val = mAccessibilityAttributes.Find( key );
1439   if( val )
1440     mAccessibilityAttributes[key] = Property::Value();
1441 }
1442
1443 void Control::Impl::ClearAccessibilityAttributes()
1444 {
1445   mAccessibilityAttributes.Clear();
1446 }
1447
1448 void Control::Impl::SetAccessibilityReadingInfoType( const Dali::Accessibility::ReadingInfoTypes types )
1449 {
1450   std::string value;
1451   if ( types[ Dali::Accessibility::ReadingInfoType::NAME ] )
1452   {
1453     value += READING_INFO_TYPE_NAME;
1454   }
1455   if ( types[ Dali::Accessibility::ReadingInfoType::ROLE ] )
1456   {
1457     if( !value.empty() )
1458     {
1459       value += READING_INFO_TYPE_SEPARATOR;
1460     }
1461     value += READING_INFO_TYPE_ROLE;
1462   }
1463   if ( types[ Dali::Accessibility::ReadingInfoType::DESCRIPTION ] )
1464   {
1465     if( !value.empty() )
1466     {
1467       value += READING_INFO_TYPE_SEPARATOR;
1468     }
1469     value += READING_INFO_TYPE_DESCRIPTION;
1470   }
1471   if ( types[ Dali::Accessibility::ReadingInfoType::STATE ] )
1472   {
1473     if( !value.empty() )
1474     {
1475       value += READING_INFO_TYPE_SEPARATOR;
1476     }
1477     value += READING_INFO_TYPE_STATE;
1478   }
1479   AppendAccessibilityAttribute( READING_INFO_TYPE_ATTRIBUTE_NAME, value );
1480 }
1481
1482 Dali::Accessibility::ReadingInfoTypes Control::Impl::GetAccessibilityReadingInfoType() const
1483 {
1484   std::string value;
1485   auto place = mAccessibilityAttributes.Find( READING_INFO_TYPE_ATTRIBUTE_NAME );
1486   if( place )
1487   {
1488     place->Get( value );
1489   }
1490
1491   if ( value.empty() )
1492   {
1493     return {};
1494   }
1495
1496   Dali::Accessibility::ReadingInfoTypes types;
1497
1498   if ( value.find( READING_INFO_TYPE_NAME ) != std::string::npos )
1499   {
1500     types[ Dali::Accessibility::ReadingInfoType::NAME ] = true;
1501   }
1502   if ( value.find( READING_INFO_TYPE_ROLE ) != std::string::npos )
1503   {
1504     types[ Dali::Accessibility::ReadingInfoType::ROLE ] = true;
1505   }
1506   if ( value.find( READING_INFO_TYPE_DESCRIPTION ) != std::string::npos )
1507   {
1508     types[ Dali::Accessibility::ReadingInfoType::DESCRIPTION ] = true;
1509   }
1510   if ( value.find( READING_INFO_TYPE_STATE ) != std::string::npos )
1511   {
1512     types[ Dali::Accessibility::ReadingInfoType::STATE ] = true;
1513   }
1514
1515   return types;
1516 }
1517
1518 void  Control::Impl::CopyInstancedProperties( RegisteredVisualContainer& visuals, Dictionary<Property::Map>& instancedProperties )
1519 {
1520   for(RegisteredVisualContainer::Iterator iter = visuals.Begin(); iter!= visuals.End(); iter++)
1521   {
1522     if( (*iter)->visual )
1523     {
1524       Property::Map instanceMap;
1525       Toolkit::GetImplementation((*iter)->visual).CreateInstancePropertyMap(instanceMap);
1526       instancedProperties.Add( (*iter)->visual.GetName(), instanceMap );
1527     }
1528   }
1529 }
1530
1531
1532 void Control::Impl::RemoveVisual( RegisteredVisualContainer& visuals, const std::string& visualName )
1533 {
1534   Actor self( mControlImpl.Self() );
1535
1536   for ( RegisteredVisualContainer::Iterator visualIter = visuals.Begin();
1537         visualIter != visuals.End(); ++visualIter )
1538   {
1539     Toolkit::Visual::Base visual = (*visualIter)->visual;
1540     if( visual && visual.GetName() == visualName )
1541     {
1542       Toolkit::GetImplementation(visual).SetOffScene( self );
1543       (*visualIter)->visual.Reset();
1544       visuals.Erase( visualIter );
1545       break;
1546     }
1547   }
1548 }
1549
1550 void Control::Impl::RemoveVisuals( RegisteredVisualContainer& visuals, DictionaryKeys& removeVisuals )
1551 {
1552   Actor self( mControlImpl.Self() );
1553   for( DictionaryKeys::iterator iter = removeVisuals.begin(); iter != removeVisuals.end(); ++iter )
1554   {
1555     const std::string visualName = *iter;
1556     RemoveVisual( visuals, visualName );
1557   }
1558 }
1559
1560 void Control::Impl::RecreateChangedVisuals( Dictionary<Property::Map>& stateVisualsToChange,
1561                              Dictionary<Property::Map>& instancedProperties )
1562 {
1563   Dali::CustomActor handle( mControlImpl.GetOwner() );
1564   for( Dictionary<Property::Map>::iterator iter = stateVisualsToChange.Begin();
1565        iter != stateVisualsToChange.End(); ++iter )
1566   {
1567     const std::string& visualName = (*iter).key;
1568     const Property::Map& toMap = (*iter).entry;
1569
1570     Actor self = mControlImpl.Self();
1571     RegisteredVisualContainer::Iterator registeredVisualsiter;
1572     // Check if visual (visualName) is already registered, this is the current visual.
1573     if(FindVisual(visualName, mVisuals, registeredVisualsiter))
1574     {
1575       Toolkit::Visual::Base& visual = (*registeredVisualsiter)->visual;
1576       if(visual)
1577       {
1578         // No longer required to know if the replaced visual's resources are ready
1579         StopObservingVisual(visual);
1580
1581         // If control staged then visuals will be swapped once ready
1582         if(self.GetProperty<bool>(Actor::Property::CONNECTED_TO_SCENE))
1583         {
1584           // Check if visual is currently in the process of being replaced ( is in removal container )
1585           RegisteredVisualContainer::Iterator visualQueuedForRemoval;
1586           if(FindVisual(visualName, mRemoveVisuals, visualQueuedForRemoval))
1587           {
1588             // Visual with same visual name is already in removal container so current visual pending
1589             // Only the the last requested visual will be displayed so remove current visual which is staged but not ready.
1590             Toolkit::GetImplementation(visual).SetOffScene(self);
1591             (*registeredVisualsiter)->visual.Reset();
1592             mVisuals.Erase(registeredVisualsiter);
1593           }
1594           else
1595           {
1596             // current visual not already in removal container so add now.
1597             DALI_LOG_INFO(gLogFilter, Debug::Verbose, "RegisterVisual Move current registered visual to removal Queue: %s \n", visualName.c_str());
1598             MoveVisual(registeredVisualsiter, mVisuals, mRemoveVisuals);
1599           }
1600         }
1601         else
1602         {
1603           // Control not staged or visual disabled so can just erase from registered visuals and new visual will be added later.
1604           (*registeredVisualsiter)->visual.Reset();
1605           mVisuals.Erase(registeredVisualsiter);
1606         }
1607       }
1608
1609       const Property::Map* instancedMap = instancedProperties.FindConst(visualName);
1610       Style::ApplyVisual(handle, visualName, toMap, instancedMap);
1611     }
1612   }
1613 }
1614
1615 void Control::Impl::ReplaceStateVisualsAndProperties( const StylePtr oldState, const StylePtr newState, const std::string& subState )
1616 {
1617   // Collect all old visual names
1618   DictionaryKeys stateVisualsToRemove;
1619   if( oldState )
1620   {
1621     oldState->visuals.GetKeys( stateVisualsToRemove );
1622     if( ! subState.empty() )
1623     {
1624       const StylePtr* oldSubState = oldState->subStates.FindConst(subState);
1625       if( oldSubState )
1626       {
1627         DictionaryKeys subStateVisualsToRemove;
1628         (*oldSubState)->visuals.GetKeys( subStateVisualsToRemove );
1629         Merge( stateVisualsToRemove, subStateVisualsToRemove );
1630       }
1631     }
1632   }
1633
1634   // Collect all new visual properties
1635   Dictionary<Property::Map> stateVisualsToAdd;
1636   if( newState )
1637   {
1638     stateVisualsToAdd = newState->visuals;
1639     if( ! subState.empty() )
1640     {
1641       const StylePtr* newSubState = newState->subStates.FindConst(subState);
1642       if( newSubState )
1643       {
1644         stateVisualsToAdd.Merge( (*newSubState)->visuals );
1645       }
1646     }
1647   }
1648
1649   // If a name is in both add/remove, move it to change list.
1650   Dictionary<Property::Map> stateVisualsToChange;
1651   FindChangableVisuals( stateVisualsToAdd, stateVisualsToChange, stateVisualsToRemove);
1652
1653   // Copy instanced properties (e.g. text label) of current visuals
1654   Dictionary<Property::Map> instancedProperties;
1655   CopyInstancedProperties( mVisuals, instancedProperties );
1656
1657   // For each visual in remove list, remove from mVisuals
1658   RemoveVisuals( mVisuals, stateVisualsToRemove );
1659
1660   // For each visual in add list, create and add to mVisuals
1661   Dali::CustomActor handle( mControlImpl.GetOwner() );
1662   Style::ApplyVisuals( handle, stateVisualsToAdd, instancedProperties );
1663
1664   // For each visual in change list, if it requires a new visual,
1665   // remove old visual, create and add to mVisuals
1666   RecreateChangedVisuals( stateVisualsToChange, instancedProperties );
1667 }
1668
1669 void Control::Impl::SetState( DevelControl::State newState, bool withTransitions )
1670 {
1671   DevelControl::State oldState = mState;
1672   Dali::CustomActor handle( mControlImpl.GetOwner() );
1673   DALI_LOG_INFO(gLogFilter, Debug::Concise, "Control::Impl::SetState: %s\n",
1674                 (mState == DevelControl::NORMAL ? "NORMAL" :(
1675                   mState == DevelControl::FOCUSED ?"FOCUSED" : (
1676                     mState == DevelControl::DISABLED?"DISABLED":"NONE" ))));
1677
1678   if( mState != newState )
1679   {
1680     // If mState was Disabled, and new state is Focused, should probably
1681     // store that fact, e.g. in another property that FocusManager can access.
1682     mState = newState;
1683
1684     // Trigger state change and transitions
1685     // Apply new style, if stylemanager is available
1686     Toolkit::StyleManager styleManager = Toolkit::StyleManager::Get();
1687     if( styleManager )
1688     {
1689       const StylePtr stylePtr = GetImpl( styleManager ).GetRecordedStyle( Toolkit::Control( mControlImpl.GetOwner() ) );
1690
1691       if( stylePtr )
1692       {
1693         std::string oldStateName = Scripting::GetEnumerationName< Toolkit::DevelControl::State >( oldState, ControlStateTable, ControlStateTableCount );
1694         std::string newStateName = Scripting::GetEnumerationName< Toolkit::DevelControl::State >( newState, ControlStateTable, ControlStateTableCount );
1695
1696         const StylePtr* newStateStyle = stylePtr->subStates.Find( newStateName );
1697         const StylePtr* oldStateStyle = stylePtr->subStates.Find( oldStateName );
1698         if( oldStateStyle && newStateStyle )
1699         {
1700           // Only change if both state styles exist
1701           ReplaceStateVisualsAndProperties( *oldStateStyle, *newStateStyle, mSubStateName );
1702         }
1703       }
1704     }
1705   }
1706 }
1707
1708 void Control::Impl::SetSubState( const std::string& subStateName, bool withTransitions )
1709 {
1710   if( mSubStateName != subStateName )
1711   {
1712     // Get existing sub-state visuals, and unregister them
1713     Dali::CustomActor handle( mControlImpl.GetOwner() );
1714
1715     Toolkit::StyleManager styleManager = Toolkit::StyleManager::Get();
1716     if( styleManager )
1717     {
1718       const StylePtr stylePtr = GetImpl( styleManager ).GetRecordedStyle( Toolkit::Control( mControlImpl.GetOwner() ) );
1719       if( stylePtr )
1720       {
1721         // Stringify state
1722         std::string stateName = Scripting::GetEnumerationName< Toolkit::DevelControl::State >( mState, ControlStateTable, ControlStateTableCount );
1723
1724         const StylePtr* state = stylePtr->subStates.Find( stateName );
1725         if( state )
1726         {
1727           StylePtr stateStyle(*state);
1728
1729           const StylePtr* newStateStyle = stateStyle->subStates.Find( subStateName );
1730           const StylePtr* oldStateStyle = stateStyle->subStates.Find( mSubStateName );
1731           if( oldStateStyle && newStateStyle )
1732           {
1733             std::string empty;
1734             ReplaceStateVisualsAndProperties( *oldStateStyle, *newStateStyle, empty );
1735           }
1736         }
1737       }
1738     }
1739
1740     mSubStateName = subStateName;
1741   }
1742 }
1743
1744 void Control::Impl::OnSceneDisconnection()
1745 {
1746   Actor self = mControlImpl.Self();
1747
1748   // Any visuals set for replacement but not yet ready should still be registered.
1749   // Reason: If a request was made to register a new visual but the control removed from scene before visual was ready
1750   // then when this control appears back on stage it should use that new visual.
1751
1752   // Iterate through all registered visuals and set off scene
1753   SetVisualsOffScene( mVisuals, self );
1754
1755   // Visuals pending replacement can now be taken out of the removal list and set off scene
1756   // Iterate through all replacement visuals and add to a move queue then set off scene
1757   for( auto removalIter = mRemoveVisuals.Begin(), end = mRemoveVisuals.End(); removalIter != end; removalIter++ )
1758   {
1759     Toolkit::GetImplementation((*removalIter)->visual).SetOffScene( self );
1760   }
1761
1762   for( auto replacedIter = mVisuals.Begin(), end = mVisuals.End(); replacedIter != end; replacedIter++ )
1763   {
1764     (*replacedIter)->pending = false;
1765   }
1766
1767   mRemoveVisuals.Clear();
1768 }
1769
1770 void Control::Impl::SetMargin( Extents margin )
1771 {
1772   mControlImpl.mImpl->mMargin = margin;
1773
1774   // Trigger a size negotiation request that may be needed when setting a margin.
1775   mControlImpl.RelayoutRequest();
1776 }
1777
1778 Extents Control::Impl::GetMargin() const
1779 {
1780   return mControlImpl.mImpl->mMargin;
1781 }
1782
1783 void Control::Impl::SetPadding( Extents padding )
1784 {
1785   mControlImpl.mImpl->mPadding = padding;
1786
1787   // Trigger a size negotiation request that may be needed when setting a padding.
1788   mControlImpl.RelayoutRequest();
1789 }
1790
1791 Extents Control::Impl::GetPadding() const
1792 {
1793   return mControlImpl.mImpl->mPadding;
1794 }
1795
1796 void Control::Impl::SetInputMethodContext( InputMethodContext& inputMethodContext )
1797 {
1798   mInputMethodContext = inputMethodContext;
1799 }
1800
1801 bool Control::Impl::FilterKeyEvent( const KeyEvent& event )
1802 {
1803   bool consumed ( false );
1804
1805   if ( mInputMethodContext )
1806   {
1807     consumed = mInputMethodContext.FilterEventKey( event );
1808   }
1809   return consumed;
1810 }
1811
1812 DevelControl::VisualEventSignalType& Control::Impl::VisualEventSignal()
1813 {
1814   return mVisualEventSignal;
1815 }
1816
1817 void Control::Impl::SetShadow( const Property::Map& map )
1818 {
1819   Toolkit::Visual::Base visual = Toolkit::VisualFactory::Get().CreateVisual( map );
1820   visual.SetName("shadow");
1821
1822   if( visual )
1823   {
1824     mControlImpl.mImpl->RegisterVisual( Toolkit::DevelControl::Property::SHADOW, visual, DepthIndex::BACKGROUND_EFFECT );
1825
1826     mControlImpl.RelayoutRequest();
1827   }
1828 }
1829
1830 void Control::Impl::ClearShadow()
1831 {
1832    mControlImpl.mImpl->UnregisterVisual( Toolkit::DevelControl::Property::SHADOW );
1833
1834    // Trigger a size negotiation request that may be needed when unregistering a visual.
1835    mControlImpl.RelayoutRequest();
1836 }
1837
1838 Dali::Property Control::Impl::GetVisualProperty(Dali::Property::Index index, Dali::Property::Key visualPropertyKey)
1839 {
1840   Toolkit::Visual::Base visual = GetVisualByIndex(mVisuals, index);
1841   if(visual)
1842   {
1843     Internal::Visual::Base& visualImpl = Toolkit::GetImplementation(visual);
1844     return visualImpl.GetPropertyObject(visualPropertyKey);
1845   }
1846
1847   Handle handle;
1848   return Dali::Property(handle, Property::INVALID_INDEX);
1849 }
1850
1851 void Control::Impl::EmitResourceReadySignal()
1852 {
1853   if(!mIsEmittingResourceReadySignal)
1854   {
1855     // Guard against calls to emit the signal during the callback
1856     mIsEmittingResourceReadySignal = true;
1857
1858     // If the signal handler changes visual, it may become ready during this call & therefore this method will
1859     // get called again recursively. If so, mNeedToEmitResourceReady is set below, and we act on it after that secondary
1860     // invocation has completed by notifying in an Idle callback to prevent further recursion.
1861     Dali::Toolkit::Control handle(mControlImpl.GetOwner());
1862     mResourceReadySignal.Emit(handle);
1863
1864     if(mNeedToEmitResourceReady)
1865     {
1866       // Add idler to emit the signal again
1867       if(!mIdleCallback)
1868       {
1869         // The callback manager takes the ownership of the callback object.
1870         mIdleCallback = MakeCallback( this, &Control::Impl::OnIdleCallback);
1871         Adaptor::Get().AddIdle(mIdleCallback, false);
1872       }
1873     }
1874
1875     mIsEmittingResourceReadySignal = false;
1876   }
1877   else
1878   {
1879     mNeedToEmitResourceReady = true;
1880   }
1881 }
1882
1883 void Control::Impl::OnIdleCallback()
1884 {
1885   if(mNeedToEmitResourceReady)
1886   {
1887     // Reset the flag
1888     mNeedToEmitResourceReady = false;
1889
1890     // A visual is ready so control may need relayouting if staged
1891     if(mControlImpl.Self().GetProperty<bool>(Actor::Property::CONNECTED_TO_SCENE))
1892     {
1893       mControlImpl.RelayoutRequest();
1894     }
1895
1896     EmitResourceReadySignal();
1897   }
1898
1899   // Set the pointer to null as the callback manager deletes the callback after execute it.
1900   mIdleCallback = nullptr;
1901 }
1902
1903 Dali::Accessibility::Accessible *Control::Impl::GetAccessibilityObject()
1904 {
1905   if( !accessibilityObject )
1906     accessibilityObject = accessibilityConstructor( mControlImpl.Self() );
1907   return accessibilityObject.get();
1908 }
1909
1910 Dali::Accessibility::Accessible *Control::Impl::GetAccessibilityObject(Dali::Actor actor)
1911 {
1912   if( actor )
1913   {
1914     auto q = Dali::Toolkit::Control::DownCast( actor );
1915     if( q )
1916     {
1917       auto q2 = static_cast< Internal::Control* >( &q.GetImplementation() );
1918       return q2->mImpl->GetAccessibilityObject();
1919     }
1920   }
1921   return nullptr;
1922 }
1923
1924 Control::Impl::AccessibleImpl::AccessibleImpl(Dali::Actor self, Dali::Accessibility::Role role, bool modal)
1925   : self(self), modal(modal)
1926 {
1927   auto control = Dali::Toolkit::Control::DownCast(self);
1928
1929   Internal::Control& internalControl = Toolkit::Internal::GetImplementation( control );
1930   Internal::Control::Impl& controlImpl = Internal::Control::Impl::Get( internalControl );
1931   if( controlImpl.mAccessibilityRole == Dali::Accessibility::Role::UNKNOWN )
1932     controlImpl.mAccessibilityRole = role;
1933
1934   self.PropertySetSignal().Connect(&controlImpl, [this, &controlImpl](Dali::Handle &handle, Dali::Property::Index index, Dali::Property::Value value)
1935   {
1936     if (this->self != Dali::Accessibility::Accessible::GetCurrentlyHighlightedActor())
1937     {
1938       return;
1939     }
1940
1941     if (index == DevelControl::Property::ACCESSIBILITY_NAME
1942       || (index == GetNamePropertyIndex() && !controlImpl.mAccessibilityNameSet))
1943     {
1944       if (controlImpl.mAccessibilityGetNameSignal.Empty())
1945       {
1946         Emit(Dali::Accessibility::ObjectPropertyChangeEvent::NAME);
1947       }
1948     }
1949
1950     if (index == DevelControl::Property::ACCESSIBILITY_DESCRIPTION
1951       || (index == GetDescriptionPropertyIndex() && !controlImpl.mAccessibilityDescriptionSet))
1952     {
1953       if (controlImpl.mAccessibilityGetDescriptionSignal.Empty())
1954       {
1955         Emit(Dali::Accessibility::ObjectPropertyChangeEvent::DESCRIPTION);
1956       }
1957     }
1958   });
1959 }
1960
1961 std::string Control::Impl::AccessibleImpl::GetName()
1962 {
1963   auto control = Dali::Toolkit::Control::DownCast(self);
1964
1965   Internal::Control& internalControl = Toolkit::Internal::GetImplementation( control );
1966   Internal::Control::Impl& controlImpl = Internal::Control::Impl::Get( internalControl );
1967
1968   if (!controlImpl.mAccessibilityGetNameSignal.Empty()) {
1969       std::string ret;
1970       controlImpl.mAccessibilityGetNameSignal.Emit(ret);
1971       return ret;
1972   }
1973
1974   if (controlImpl.mAccessibilityNameSet)
1975     return controlImpl.mAccessibilityName;
1976
1977   if (auto raw = GetNameRaw(); !raw.empty())
1978     return raw;
1979
1980   return self.GetProperty< std::string >( Actor::Property::NAME );
1981 }
1982
1983 std::string Control::Impl::AccessibleImpl::GetNameRaw()
1984 {
1985   return {};
1986 }
1987
1988 std::string Control::Impl::AccessibleImpl::GetDescription()
1989 {
1990   auto control = Dali::Toolkit::Control::DownCast(self);
1991
1992   Internal::Control& internalControl = Toolkit::Internal::GetImplementation( control );
1993   Internal::Control::Impl& controlImpl = Internal::Control::Impl::Get( internalControl );
1994
1995   if (!controlImpl.mAccessibilityGetDescriptionSignal.Empty()) {
1996       std::string ret;
1997       controlImpl.mAccessibilityGetDescriptionSignal.Emit(ret);
1998       return ret;
1999   }
2000
2001   if (controlImpl.mAccessibilityDescriptionSet)
2002     return controlImpl.mAccessibilityDescription;
2003
2004   return GetDescriptionRaw();
2005 }
2006
2007 std::string Control::Impl::AccessibleImpl::GetDescriptionRaw()
2008 {
2009   return "";
2010 }
2011
2012 Dali::Accessibility::Accessible* Control::Impl::AccessibleImpl::GetParent()
2013 {
2014   return Dali::Accessibility::Accessible::Get( self.GetParent() );
2015 }
2016
2017 size_t Control::Impl::AccessibleImpl::GetChildCount()
2018 {
2019   return self.GetChildCount();
2020 }
2021
2022 Dali::Accessibility::Accessible* Control::Impl::AccessibleImpl::GetChildAtIndex( size_t index )
2023 {
2024   return Dali::Accessibility::Accessible::Get( self.GetChildAt( static_cast< unsigned int >( index ) ) );
2025 }
2026
2027 size_t Control::Impl::AccessibleImpl::GetIndexInParent()
2028 {
2029   auto s = self;
2030   auto parent = s.GetParent();
2031   DALI_ASSERT_ALWAYS( parent && "can't call GetIndexInParent on object without parent" );
2032   auto count = parent.GetChildCount();
2033   for( auto i = 0u; i < count; ++i )
2034   {
2035     auto c = parent.GetChildAt( i );
2036     if( c == s )
2037       return i;
2038   }
2039   DALI_ASSERT_ALWAYS( false && "object isn't child of it's parent" );
2040   return static_cast<size_t>(-1);
2041 }
2042
2043 Dali::Accessibility::Role Control::Impl::AccessibleImpl::GetRole()
2044 {
2045   return self.GetProperty<Dali::Accessibility::Role>( Toolkit::DevelControl::Property::ACCESSIBILITY_ROLE );
2046 }
2047
2048 Dali::Accessibility::States Control::Impl::AccessibleImpl::CalculateStates()
2049 {
2050   Dali::Accessibility::States s;
2051   s[Dali::Accessibility::State::FOCUSABLE] = self.GetProperty< bool >( Actor::Property::KEYBOARD_FOCUSABLE );
2052   s[Dali::Accessibility::State::FOCUSED] = Toolkit::KeyboardFocusManager::Get().GetCurrentFocusActor() == self;
2053   if(self.GetProperty( Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE ).GetType() == Property::NONE )
2054     s[Dali::Accessibility::State::HIGHLIGHTABLE] = false;
2055   else
2056     s[Dali::Accessibility::State::HIGHLIGHTABLE] = self.GetProperty( Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE ).Get< bool >();
2057   s[Dali::Accessibility::State::HIGHLIGHTED] = GetCurrentlyHighlightedActor() == self;
2058   s[Dali::Accessibility::State::ENABLED] = true;
2059   s[Dali::Accessibility::State::SENSITIVE] = true;
2060   s[Dali::Accessibility::State::ANIMATED] = self.GetProperty( Toolkit::DevelControl::Property::ACCESSIBILITY_ANIMATED ).Get< bool >();
2061   s[Dali::Accessibility::State::VISIBLE] = true;
2062   if( modal )
2063   {
2064     s[Dali::Accessibility::State::MODAL] = true;
2065   }
2066   s[Dali::Accessibility::State::SHOWING] = !self.GetProperty( Dali::DevelActor::Property::CULLED ).Get< bool >()
2067                                          && self.GetCurrentProperty< bool >( Actor::Property::VISIBLE );
2068
2069   s[Dali::Accessibility::State::DEFUNCT] = !self.GetProperty( Dali::DevelActor::Property::CONNECTED_TO_SCENE ).Get< bool >();
2070   return s;
2071 }
2072
2073 Dali::Accessibility::States Control::Impl::AccessibleImpl::GetStates()
2074 {
2075   return CalculateStates();
2076 }
2077
2078 Dali::Accessibility::Attributes Control::Impl::AccessibleImpl::GetAttributes()
2079 {
2080   std::unordered_map< std::string, std::string > attribute_map;
2081   auto q = Dali::Toolkit::Control::DownCast( self );
2082   auto w =
2083       q.GetProperty( Dali::Toolkit::DevelControl::Property::ACCESSIBILITY_ATTRIBUTES );
2084   auto z = w.GetMap();
2085
2086   if( z )
2087   {
2088     auto map_size = z->Count();
2089
2090     for( unsigned int i = 0; i < map_size; i++ )
2091     {
2092       auto map_key = z->GetKeyAt( i );
2093       if( map_key.type == Property::Key::STRING )
2094       {
2095         std::string map_value;
2096         if( z->GetValue( i ).Get( map_value ) )
2097         {
2098           attribute_map.emplace( std::move( map_key.stringKey ),
2099                                  std::move( map_value ) );
2100         }
2101       }
2102     }
2103   }
2104
2105   return attribute_map;
2106 }
2107
2108 Dali::Accessibility::ComponentLayer Control::Impl::AccessibleImpl::GetLayer()
2109 {
2110   return Dali::Accessibility::ComponentLayer::WINDOW;
2111 }
2112
2113 Dali::Rect<> Control::Impl::AccessibleImpl::GetExtents( Dali::Accessibility::CoordType ctype )
2114 {
2115   Vector2 screenPosition =
2116       self.GetProperty( Dali::DevelActor::Property::SCREEN_POSITION )
2117           .Get< Vector2 >();
2118   auto size = self.GetCurrentProperty< Vector3 >( Actor::Property::SIZE ) * self.GetCurrentProperty< Vector3 >( Actor::Property::WORLD_SCALE );
2119   bool positionUsesAnchorPoint =
2120       self.GetProperty( Dali::DevelActor::Property::POSITION_USES_ANCHOR_POINT )
2121           .Get< bool >();
2122   Vector3 anchorPointOffSet =
2123       size * ( positionUsesAnchorPoint ? self.GetCurrentProperty< Vector3 >( Actor::Property::ANCHOR_POINT )
2124                                        : AnchorPoint::TOP_LEFT );
2125   Vector2 position = Vector2( screenPosition.x - anchorPointOffSet.x,
2126                               screenPosition.y - anchorPointOffSet.y );
2127
2128   return { position.x, position.y, size.x, size.y };
2129 }
2130
2131 int16_t Control::Impl::AccessibleImpl::GetMdiZOrder() { return 0; }
2132 double Control::Impl::AccessibleImpl::GetAlpha() { return 0; }
2133
2134 bool Control::Impl::AccessibleImpl::GrabFocus()
2135 {
2136   return Toolkit::KeyboardFocusManager::Get().SetCurrentFocusActor( self );
2137 }
2138
2139 static Dali::Actor CreateHighlightIndicatorActor()
2140 {
2141   std::string focusBorderImagePath(AssetManager::GetDaliImagePath());
2142   focusBorderImagePath += "/keyboard_focus.9.png";
2143   // Create the default if it hasn't been set and one that's shared by all the
2144   // keyboard focusable actors
2145   auto actor = Toolkit::ImageView::New( focusBorderImagePath );
2146   actor.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
2147   DevelControl::AppendAccessibilityAttribute( actor, "highlight", "" );
2148   actor.SetProperty( Toolkit::DevelControl::Property::ACCESSIBILITY_ANIMATED, true);
2149   actor.SetProperty( Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE, false );
2150
2151   return actor;
2152 }
2153
2154 bool Control::Impl::AccessibleImpl::GrabHighlight()
2155 {
2156   auto old = GetCurrentlyHighlightedActor();
2157
2158   if( !Dali::Accessibility::IsUp() )
2159       return false;
2160   if( self == old )
2161     return true;
2162   if( old )
2163   {
2164     auto c = dynamic_cast< Dali::Accessibility::Component* >( GetAccessibilityObject( old ) );
2165     if( c )
2166       c->ClearHighlight();
2167   }
2168   auto highlight = GetHighlightActor();
2169   if ( !highlight )
2170   {
2171     highlight = CreateHighlightIndicatorActor();
2172     SetHighlightActor( highlight );
2173   }
2174   highlight.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER );
2175   highlight.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER );
2176   highlight.SetProperty( Actor::Property::POSITION_Z, 1.0f );
2177   highlight.SetProperty( Actor::Property::POSITION, Vector2( 0.0f, 0.0f ));
2178
2179   EnsureSelfVisible();
2180   self.Add( highlight );
2181   SetCurrentlyHighlightedActor( self );
2182   EmitHighlighted( true );
2183
2184   return true;
2185 }
2186
2187
2188
2189 bool Control::Impl::AccessibleImpl::ClearHighlight()
2190 {
2191   if( !Dali::Accessibility::IsUp() )
2192     return false;
2193   if( GetCurrentlyHighlightedActor() == self )
2194   {
2195     self.Remove( GetHighlightActor() );
2196     SetCurrentlyHighlightedActor( {} );
2197     EmitHighlighted( false );
2198     return true;
2199   }
2200   return false;
2201 }
2202
2203 std::string Control::Impl::AccessibleImpl::GetActionName( size_t index )
2204 {
2205   if ( index >= GetActionCount() ) return "";
2206   Dali::TypeInfo type;
2207   self.GetTypeInfo( type );
2208   DALI_ASSERT_ALWAYS( type && "no TypeInfo object" );
2209   return type.GetActionName( index );
2210 }
2211 std::string Control::Impl::AccessibleImpl::GetLocalizedActionName( size_t index )
2212 {
2213   // TODO: add localization
2214   return GetActionName( index );
2215 }
2216 std::string Control::Impl::AccessibleImpl::GetActionDescription( size_t index )
2217 {
2218   return "";
2219 }
2220 size_t Control::Impl::AccessibleImpl::GetActionCount()
2221 {
2222   Dali::TypeInfo type;
2223   self.GetTypeInfo( type );
2224   DALI_ASSERT_ALWAYS( type && "no TypeInfo object" );
2225   return type.GetActionCount();
2226 }
2227 std::string Control::Impl::AccessibleImpl::GetActionKeyBinding( size_t index )
2228 {
2229   return "";
2230 }
2231 bool Control::Impl::AccessibleImpl::DoAction( size_t index )
2232 {
2233   std::string actionName = GetActionName( index );
2234   return self.DoAction( actionName, {} );
2235 }
2236 bool Control::Impl::AccessibleImpl::DoAction(const std::string& name)
2237 {
2238   return self.DoAction( name, {} );
2239 }
2240
2241 bool Control::Impl::AccessibleImpl::DoGesture(const Dali::Accessibility::GestureInfo &gestureInfo)
2242 {
2243   auto control = Dali::Toolkit::Control::DownCast(self);
2244
2245   Internal::Control& internalControl = Toolkit::Internal::GetImplementation( control );
2246   Internal::Control::Impl& controlImpl = Internal::Control::Impl::Get( internalControl );
2247
2248   if (!controlImpl.mAccessibilityDoGestureSignal.Empty()) {
2249       auto ret = std::make_pair(gestureInfo, false);
2250       controlImpl.mAccessibilityDoGestureSignal.Emit(ret);
2251       return ret.second;
2252   }
2253
2254   return false;
2255 }
2256
2257 std::vector<Dali::Accessibility::Relation> Control::Impl::AccessibleImpl::GetRelationSet()
2258 {
2259   auto control = Dali::Toolkit::Control::DownCast(self);
2260
2261   Internal::Control& internalControl = Toolkit::Internal::GetImplementation( control );
2262   Internal::Control::Impl& controlImpl = Internal::Control::Impl::Get( internalControl );
2263
2264   std::vector<Dali::Accessibility::Relation> ret;
2265
2266   auto &v = controlImpl.mAccessibilityRelations;
2267   for (auto i = 0u; i < v.size(); ++i)
2268   {
2269     if ( v[i].empty() )
2270       continue;
2271
2272     ret.emplace_back( Accessibility::Relation{ static_cast<Accessibility::RelationType>(i), v[i] } );
2273   }
2274
2275   return ret;
2276 }
2277
2278 void Control::Impl::AccessibleImpl::EnsureChildVisible(Actor child)
2279 {
2280 }
2281
2282 void Control::Impl::AccessibleImpl::EnsureSelfVisible()
2283 {
2284   auto parent = dynamic_cast<Control::Impl::AccessibleImpl*>(GetParent());
2285   if (parent)
2286   {
2287     parent->EnsureChildVisible(self);
2288   }
2289 }
2290
2291 Property::Index Control::Impl::AccessibleImpl::GetNamePropertyIndex()
2292 {
2293   return Actor::Property::NAME;
2294 }
2295
2296 Property::Index Control::Impl::AccessibleImpl::GetDescriptionPropertyIndex()
2297 {
2298   return Property::INVALID_INDEX;
2299 }
2300
2301 void Control::Impl::PositionOrSizeChangedCallback( PropertyNotification &p )
2302 {
2303   auto self = Dali::Actor::DownCast(p.GetTarget());
2304   if (Dali::Accessibility::IsUp() && !self.GetProperty( Toolkit::DevelControl::Property::ACCESSIBILITY_ANIMATED ).Get< bool >())
2305   {
2306     auto extents = DevelActor::CalculateScreenExtents( self );
2307     Dali::Accessibility::Accessible::Get( self )->EmitBoundsChanged( extents );
2308   }
2309 }
2310
2311 void Control::Impl::CulledChangedCallback( PropertyNotification &p)
2312 {
2313   if (Dali::Accessibility::IsUp())
2314   {
2315     auto self = Dali::Actor::DownCast(p.GetTarget());
2316     Dali::Accessibility::Accessible::Get(self)->EmitShowing( !self.GetProperty( DevelActor::Property::CULLED ).Get<bool>() );
2317   }
2318 }
2319
2320 void Control::Impl::AccessibilityRegister()
2321 {
2322   if (!accessibilityNotificationSet)
2323   {
2324     accessibilityNotificationPosition = mControlImpl.Self().AddPropertyNotification( Actor::Property::POSITION, StepCondition( 0.01f ) );
2325     accessibilityNotificationPosition.SetNotifyMode( PropertyNotification::NOTIFY_ON_CHANGED );
2326     accessibilityNotificationPosition.NotifySignal().Connect( &Control::Impl::PositionOrSizeChangedCallback );
2327
2328     accessibilityNotificationSize = mControlImpl.Self().AddPropertyNotification( Actor::Property::SIZE, StepCondition( 0.01f ) );
2329     accessibilityNotificationSize.SetNotifyMode( PropertyNotification::NOTIFY_ON_CHANGED );
2330     accessibilityNotificationSize.NotifySignal().Connect( &Control::Impl::PositionOrSizeChangedCallback );
2331
2332     accessibilityNotificationCulled = mControlImpl.Self().AddPropertyNotification( DevelActor::Property::CULLED, LessThanCondition( 0.5f ) );
2333     accessibilityNotificationCulled.SetNotifyMode( PropertyNotification::NOTIFY_ON_CHANGED );
2334     accessibilityNotificationCulled.NotifySignal().Connect( &Control::Impl::CulledChangedCallback );
2335
2336     accessibilityNotificationSet = true;
2337   }
2338 }
2339
2340 void Control::Impl::AccessibilityDeregister()
2341 {
2342   if (accessibilityNotificationSet)
2343   {
2344     accessibilityNotificationPosition = {};
2345     accessibilityNotificationSize = {};
2346     accessibilityNotificationCulled = {};
2347     accessibilityNotificationSet = false;
2348   }
2349 }
2350
2351 void Control::Impl::SetAutofillEnabled( bool autofillEnabled )
2352 {
2353   mIsAutofillEnabled = autofillEnabled;
2354 }
2355
2356 bool Control::Impl::IsAutofillEnabled()
2357 {
2358   return mIsAutofillEnabled;
2359 }
2360
2361 void Control::Impl::SetAutofillItemHandle( Dali::AutofillItem item )
2362 {
2363   mAutofillItem = item;
2364 }
2365
2366 Dali::AutofillItem Control::Impl::GetAutofillItemHandle()
2367 {
2368   return mAutofillItem;
2369 }
2370
2371 void Control::Impl::SetAutofillContainer( Toolkit::AutofillContainer container )
2372 {
2373   mAutofillContainer = container;
2374 }
2375
2376 Toolkit::AutofillContainer Control::Impl::GetAutofillContainer()
2377 {
2378   return mAutofillContainer;
2379 }
2380
2381 } // namespace Internal
2382
2383 } // namespace Toolkit
2384
2385 } // namespace Dali