2 * Copyright (c) 2021 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include "control-data-impl.h"
22 #include <dali-toolkit/public-api/controls/control-impl.h>
23 #include <dali-toolkit/public-api/controls/control.h>
24 #include <dali-toolkit/public-api/dali-toolkit-common.h>
25 #include <dali/devel-api/actors/actor-devel.h>
26 #include <dali/devel-api/adaptor-framework/accessibility.h>
27 #include <dali/devel-api/common/stage.h>
28 #include <dali/devel-api/object/handle-devel.h>
29 #include <dali/devel-api/scripting/enum-helper.h>
30 #include <dali/devel-api/scripting/scripting.h>
31 #include <dali/integration-api/adaptor-framework/adaptor.h>
32 #include <dali/integration-api/debug.h>
33 #include <dali/public-api/object/object-registry.h>
34 #include <dali/public-api/object/type-registry-helper.h>
39 #include <dali-toolkit/devel-api/visuals/visual-actions-devel.h>
40 #include <dali-toolkit/devel-api/asset-manager/asset-manager.h>
41 #include <dali-toolkit/devel-api/controls/control-depth-index-ranges.h>
42 #include <dali-toolkit/devel-api/controls/control-devel.h>
43 #include <dali-toolkit/devel-api/controls/control-wrapper-impl.h>
44 #include <dali-toolkit/internal/styling/style-manager-impl.h>
45 #include <dali-toolkit/internal/visuals/visual-base-impl.h>
46 #include <dali-toolkit/internal/visuals/visual-string-constants.h>
47 #include <dali-toolkit/public-api/controls/image-view/image-view.h>
48 #include <dali-toolkit/public-api/focus-manager/keyboard-focus-manager.h>
49 #include <dali-toolkit/public-api/visuals/image-visual-properties.h>
50 #include <dali-toolkit/public-api/visuals/visual-properties.h>
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 = "|";
68 extern const Dali::Scripting::StringEnum ControlStateTable[];
69 extern const unsigned int ControlStateTableCount;
71 // Not static or anonymous - shared with other translation units
72 const Scripting::StringEnum ControlStateTable[] = {
73 {"NORMAL", Toolkit::DevelControl::NORMAL},
74 {"FOCUSED", Toolkit::DevelControl::FOCUSED},
75 {"DISABLED", Toolkit::DevelControl::DISABLED},
77 const unsigned int ControlStateTableCount = sizeof(ControlStateTable) / sizeof(ControlStateTable[0]);
81 #if defined(DEBUG_ENABLED)
82 Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_CONTROL_VISUALS");
86 void Remove(Dictionary<T>& keyValues, const std::string& name)
88 keyValues.Remove(name);
91 void Remove(DictionaryKeys& keys, const std::string& name)
93 DictionaryKeys::iterator iter = std::find(keys.begin(), keys.end(), name);
94 if(iter != keys.end())
101 * Finds visual in given array, returning true if found along with the iterator for that visual as a out parameter
103 bool FindVisual(Property::Index targetIndex, const RegisteredVisualContainer& visuals, RegisteredVisualContainer::Iterator& iter)
105 for(iter = visuals.Begin(); iter != visuals.End(); iter++)
107 if((*iter)->index == targetIndex)
116 * Finds visual in given array, returning true if found along with the iterator for that visual as a out parameter
118 bool FindVisual(std::string visualName, const RegisteredVisualContainer& visuals, RegisteredVisualContainer::Iterator& iter)
120 for(iter = visuals.Begin(); iter != visuals.End(); iter++)
122 Toolkit::Visual::Base visual = (*iter)->visual;
123 if(visual && visual.GetName() == visualName)
131 void FindChangableVisuals(Dictionary<Property::Map>& stateVisualsToAdd,
132 Dictionary<Property::Map>& stateVisualsToChange,
133 DictionaryKeys& stateVisualsToRemove)
135 DictionaryKeys copyOfStateVisualsToRemove = stateVisualsToRemove;
137 for(DictionaryKeys::iterator iter = copyOfStateVisualsToRemove.begin();
138 iter != copyOfStateVisualsToRemove.end();
141 const std::string& visualName = (*iter);
142 Property::Map* toMap = stateVisualsToAdd.Find(visualName);
145 stateVisualsToChange.Add(visualName, *toMap);
146 stateVisualsToAdd.Remove(visualName);
147 Remove(stateVisualsToRemove, visualName);
152 Toolkit::Visual::Base GetVisualByName(
153 const RegisteredVisualContainer& visuals,
154 const std::string& visualName)
156 Toolkit::Visual::Base visualHandle;
158 RegisteredVisualContainer::Iterator iter;
159 for(iter = visuals.Begin(); iter != visuals.End(); iter++)
161 Toolkit::Visual::Base visual = (*iter)->visual;
162 if(visual && visual.GetName() == visualName)
164 visualHandle = visual;
171 Toolkit::Visual::Base GetVisualByIndex(
172 const RegisteredVisualContainer& visuals,
173 Property::Index index)
175 Toolkit::Visual::Base visualHandle;
177 RegisteredVisualContainer::Iterator iter;
178 for(iter = visuals.Begin(); iter != visuals.End(); iter++)
180 if((*iter)->index == index)
182 visualHandle = (*iter)->visual;
190 * Move visual from source to destination container
192 void MoveVisual(RegisteredVisualContainer::Iterator sourceIter, RegisteredVisualContainer& source, RegisteredVisualContainer& destination)
194 Toolkit::Visual::Base visual = (*sourceIter)->visual;
197 RegisteredVisual* rv = source.Release(sourceIter);
198 destination.PushBack(rv);
203 * Performs actions as requested using the action name.
204 * @param[in] object The object on which to perform the action.
205 * @param[in] actionName The action to perform.
206 * @param[in] attributes The attributes with which to perfrom this action.
207 * @return true if action has been accepted by this control
209 const char* ACTION_ACCESSIBILITY_ACTIVATED = "accessibilityActivated";
210 const char* ACTION_ACCESSIBILITY_READING_CANCELLED = "ReadingCancelled";
211 const char* ACTION_ACCESSIBILITY_READING_PAUSED = "ReadingPaused";
212 const char* ACTION_ACCESSIBILITY_READING_RESUMED = "ReadingResumed";
213 const char* ACTION_ACCESSIBILITY_READING_SKIPPED = "ReadingSkipped";
214 const char* ACTION_ACCESSIBILITY_READING_STOPPED = "ReadingStopped";
216 static bool DoAction(BaseObject* object, const std::string& actionName, const Property::Map& attributes)
220 Dali::BaseHandle handle(object);
222 Toolkit::Control control = Toolkit::Control::DownCast(handle);
224 DALI_ASSERT_ALWAYS(control);
226 if(0 == strcmp(actionName.c_str(), ACTION_ACCESSIBILITY_ACTIVATED) || actionName == "activate")
228 // if cast succeeds there is an implementation so no need to check
229 if(!DevelControl::AccessibilityActivateSignal(control).Empty())
231 DevelControl::AccessibilityActivateSignal(control).Emit();
235 ret = Internal::GetImplementation(control).OnAccessibilityActivated();
238 else if(0 == strcmp(actionName.c_str(), ACTION_ACCESSIBILITY_READING_SKIPPED))
240 // if cast succeeds there is an implementation so no need to check
241 if(!DevelControl::AccessibilityReadingSkippedSignal(control).Empty())
243 DevelControl::AccessibilityReadingSkippedSignal(control).Emit();
246 else if(0 == strcmp(actionName.c_str(), ACTION_ACCESSIBILITY_READING_PAUSED))
248 // if cast succeeds there is an implementation so no need to check
249 if(!DevelControl::AccessibilityReadingPausedSignal(control).Empty())
251 DevelControl::AccessibilityReadingPausedSignal(control).Emit();
254 else if(0 == strcmp(actionName.c_str(), ACTION_ACCESSIBILITY_READING_RESUMED))
256 // if cast succeeds there is an implementation so no need to check
257 if(!DevelControl::AccessibilityReadingResumedSignal(control).Empty())
259 DevelControl::AccessibilityReadingResumedSignal(control).Emit();
262 else if(0 == strcmp(actionName.c_str(), ACTION_ACCESSIBILITY_READING_CANCELLED))
264 // if cast succeeds there is an implementation so no need to check
265 if(!DevelControl::AccessibilityReadingCancelledSignal(control).Empty())
267 DevelControl::AccessibilityReadingCancelledSignal(control).Emit();
270 else if(0 == strcmp(actionName.c_str(), ACTION_ACCESSIBILITY_READING_STOPPED))
272 // if cast succeeds there is an implementation so no need to check
273 if(!DevelControl::AccessibilityReadingStoppedSignal(control).Empty())
275 DevelControl::AccessibilityReadingStoppedSignal(control).Emit();
286 * Connects a callback function with the object's signals.
287 * @param[in] object The object providing the signal.
288 * @param[in] tracker Used to disconnect the signal.
289 * @param[in] signalName The signal to connect to.
290 * @param[in] functor A newly allocated FunctorDelegate.
291 * @return True if the signal was connected.
292 * @post If a signal was connected, ownership of functor was passed to CallbackBase. Otherwise the caller is responsible for deleting the unused functor.
294 const char* SIGNAL_KEY_EVENT = "keyEvent";
295 const char* SIGNAL_KEY_INPUT_FOCUS_GAINED = "keyInputFocusGained";
296 const char* SIGNAL_KEY_INPUT_FOCUS_LOST = "keyInputFocusLost";
297 const char* SIGNAL_TAPPED = "tapped";
298 const char* SIGNAL_PANNED = "panned";
299 const char* SIGNAL_PINCHED = "pinched";
300 const char* SIGNAL_LONG_PRESSED = "longPressed";
301 const char* SIGNAL_GET_NAME = "getName";
302 const char* SIGNAL_GET_DESCRIPTION = "getDescription";
303 const char* SIGNAL_DO_GESTURE = "doGesture";
304 static bool DoConnectSignal(BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor)
306 Dali::BaseHandle handle(object);
308 bool connected(false);
309 Toolkit::Control control = Toolkit::Control::DownCast(handle);
312 Internal::Control& controlImpl(Internal::GetImplementation(control));
315 if(0 == strcmp(signalName.c_str(), SIGNAL_KEY_EVENT))
317 controlImpl.KeyEventSignal().Connect(tracker, functor);
319 else if(0 == strcmp(signalName.c_str(), SIGNAL_KEY_INPUT_FOCUS_GAINED))
321 controlImpl.KeyInputFocusGainedSignal().Connect(tracker, functor);
323 else if(0 == strcmp(signalName.c_str(), SIGNAL_KEY_INPUT_FOCUS_LOST))
325 controlImpl.KeyInputFocusLostSignal().Connect(tracker, functor);
327 else if(0 == strcmp(signalName.c_str(), SIGNAL_TAPPED))
329 controlImpl.EnableGestureDetection(GestureType::TAP);
330 controlImpl.GetTapGestureDetector().DetectedSignal().Connect(tracker, functor);
332 else if(0 == strcmp(signalName.c_str(), SIGNAL_PANNED))
334 controlImpl.EnableGestureDetection(GestureType::PAN);
335 controlImpl.GetPanGestureDetector().DetectedSignal().Connect(tracker, functor);
337 else if(0 == strcmp(signalName.c_str(), SIGNAL_PINCHED))
339 controlImpl.EnableGestureDetection(GestureType::PINCH);
340 controlImpl.GetPinchGestureDetector().DetectedSignal().Connect(tracker, functor);
342 else if(0 == strcmp(signalName.c_str(), SIGNAL_LONG_PRESSED))
344 controlImpl.EnableGestureDetection(GestureType::LONG_PRESS);
345 controlImpl.GetLongPressGestureDetector().DetectedSignal().Connect(tracker, functor);
347 else if(0 == strcmp(signalName.c_str(), SIGNAL_GET_NAME))
349 DevelControl::AccessibilityGetNameSignal(control).Connect(tracker, functor);
351 else if(0 == strcmp(signalName.c_str(), SIGNAL_GET_DESCRIPTION))
353 DevelControl::AccessibilityGetDescriptionSignal(control).Connect(tracker, functor);
355 else if(0 == strcmp(signalName.c_str(), SIGNAL_DO_GESTURE))
357 DevelControl::AccessibilityDoGestureSignal(control).Connect(tracker, functor);
364 * Creates control through type registry
368 return Internal::Control::New();
370 // Setup signals and actions using the type-registry.
371 DALI_TYPE_REGISTRATION_BEGIN(Control, CustomActor, Create);
373 // Note: Properties are registered separately below.
375 SignalConnectorType registerSignal1(typeRegistration, SIGNAL_KEY_EVENT, &DoConnectSignal);
376 SignalConnectorType registerSignal2(typeRegistration, SIGNAL_KEY_INPUT_FOCUS_GAINED, &DoConnectSignal);
377 SignalConnectorType registerSignal3(typeRegistration, SIGNAL_KEY_INPUT_FOCUS_LOST, &DoConnectSignal);
378 SignalConnectorType registerSignal4(typeRegistration, SIGNAL_TAPPED, &DoConnectSignal);
379 SignalConnectorType registerSignal5(typeRegistration, SIGNAL_PANNED, &DoConnectSignal);
380 SignalConnectorType registerSignal6(typeRegistration, SIGNAL_PINCHED, &DoConnectSignal);
381 SignalConnectorType registerSignal7(typeRegistration, SIGNAL_LONG_PRESSED, &DoConnectSignal);
382 SignalConnectorType registerSignal8(typeRegistration, SIGNAL_GET_NAME, &DoConnectSignal);
383 SignalConnectorType registerSignal9(typeRegistration, SIGNAL_GET_DESCRIPTION, &DoConnectSignal);
384 SignalConnectorType registerSignal10(typeRegistration, SIGNAL_DO_GESTURE, &DoConnectSignal);
386 TypeAction registerAction1(typeRegistration, "activate", &DoAction);
387 TypeAction registerAction2(typeRegistration, ACTION_ACCESSIBILITY_ACTIVATED, &DoAction);
388 TypeAction registerAction3(typeRegistration, ACTION_ACCESSIBILITY_READING_SKIPPED, &DoAction);
389 TypeAction registerAction4(typeRegistration, ACTION_ACCESSIBILITY_READING_CANCELLED, &DoAction);
390 TypeAction registerAction5(typeRegistration, ACTION_ACCESSIBILITY_READING_STOPPED, &DoAction);
391 TypeAction registerAction6(typeRegistration, ACTION_ACCESSIBILITY_READING_PAUSED, &DoAction);
392 TypeAction registerAction7(typeRegistration, ACTION_ACCESSIBILITY_READING_RESUMED, &DoAction);
394 DALI_TYPE_REGISTRATION_END()
397 * @brief Iterate through given container and setOffScene any visual found
399 * @param[in] container Container of visuals
400 * @param[in] parent Parent actor to remove visuals from
402 void SetVisualsOffScene(const RegisteredVisualContainer& container, Actor parent)
404 for(auto iter = container.Begin(), end = container.End(); iter != end; iter++)
408 DALI_LOG_INFO(gLogFilter, Debug::Verbose, "Control::SetOffScene Setting visual(%d) off stage\n", (*iter)->index);
409 Toolkit::GetImplementation((*iter)->visual).SetOffScene(parent);
414 Dali::Rect<> GetShowingGeometry(Dali::Rect<> rect, Dali::Toolkit::DevelControl::AccessibleImpl* accessibleImpl)
417 Vector2 currentPosition;
418 auto parent = dynamic_cast<Toolkit::DevelControl::AccessibleImpl*>(accessibleImpl->GetParent());
422 parentRect = parent->GetExtents(Dali::Accessibility::CoordinateType::WINDOW);
424 currentPosition.x = rect.x;
425 currentPosition.y = rect.y;
427 rect.x = rect.x > parentRect.x ? rect.x : parentRect.x;
428 rect.y = rect.y > parentRect.y ? rect.y : parentRect.y;
429 rect.width = currentPosition.x + rect.width < parentRect.x + parentRect.width ? currentPosition.x + rect.width - rect.x : parentRect.x + parentRect.width - rect.x;
430 rect.height = currentPosition.y + rect.height < parentRect.y + parentRect.height ? currentPosition.y + rect.height - rect.y : parentRect.y + parentRect.height - rect.y;
432 if(rect.width < 0 || rect.height < 0)
437 parent = dynamic_cast<Toolkit::DevelControl::AccessibleImpl*>(parent->GetParent());
443 static bool IsShowingGeometryOnScreen(Dali::Rect<> rect)
445 return rect.width > 0 && rect.height > 0;
448 } // unnamed namespace
451 // Properties registered without macro to use specific member variables.
452 const PropertyRegistration Control::Impl::PROPERTY_1(typeRegistration, "styleName", Toolkit::Control::Property::STYLE_NAME, Property::STRING, &Control::Impl::SetProperty, &Control::Impl::GetProperty);
453 const PropertyRegistration Control::Impl::PROPERTY_4(typeRegistration, "keyInputFocus", Toolkit::Control::Property::KEY_INPUT_FOCUS, Property::BOOLEAN, &Control::Impl::SetProperty, &Control::Impl::GetProperty);
454 const PropertyRegistration Control::Impl::PROPERTY_5(typeRegistration, "background", Toolkit::Control::Property::BACKGROUND, Property::MAP, &Control::Impl::SetProperty, &Control::Impl::GetProperty);
455 const PropertyRegistration Control::Impl::PROPERTY_6(typeRegistration, "margin", Toolkit::Control::Property::MARGIN, Property::EXTENTS, &Control::Impl::SetProperty, &Control::Impl::GetProperty);
456 const PropertyRegistration Control::Impl::PROPERTY_7(typeRegistration, "padding", Toolkit::Control::Property::PADDING, Property::EXTENTS, &Control::Impl::SetProperty, &Control::Impl::GetProperty);
457 const PropertyRegistration Control::Impl::PROPERTY_8(typeRegistration, "tooltip", Toolkit::DevelControl::Property::TOOLTIP, Property::MAP, &Control::Impl::SetProperty, &Control::Impl::GetProperty);
458 const PropertyRegistration Control::Impl::PROPERTY_9(typeRegistration, "state", Toolkit::DevelControl::Property::STATE, Property::STRING, &Control::Impl::SetProperty, &Control::Impl::GetProperty);
459 const PropertyRegistration Control::Impl::PROPERTY_10(typeRegistration, "subState", Toolkit::DevelControl::Property::SUB_STATE, Property::STRING, &Control::Impl::SetProperty, &Control::Impl::GetProperty);
460 const PropertyRegistration Control::Impl::PROPERTY_11(typeRegistration, "leftFocusableActorId", Toolkit::DevelControl::Property::LEFT_FOCUSABLE_ACTOR_ID, Property::INTEGER, &Control::Impl::SetProperty, &Control::Impl::GetProperty);
461 const PropertyRegistration Control::Impl::PROPERTY_12(typeRegistration, "rightFocusableActorId", Toolkit::DevelControl::Property::RIGHT_FOCUSABLE_ACTOR_ID, Property::INTEGER, &Control::Impl::SetProperty, &Control::Impl::GetProperty);
462 const PropertyRegistration Control::Impl::PROPERTY_13(typeRegistration, "upFocusableActorId", Toolkit::DevelControl::Property::UP_FOCUSABLE_ACTOR_ID, Property::INTEGER, &Control::Impl::SetProperty, &Control::Impl::GetProperty);
463 const PropertyRegistration Control::Impl::PROPERTY_14(typeRegistration, "downFocusableActorId", Toolkit::DevelControl::Property::DOWN_FOCUSABLE_ACTOR_ID, Property::INTEGER, &Control::Impl::SetProperty, &Control::Impl::GetProperty);
464 const PropertyRegistration Control::Impl::PROPERTY_15(typeRegistration, "shadow", Toolkit::DevelControl::Property::SHADOW, Property::MAP, &Control::Impl::SetProperty, &Control::Impl::GetProperty);
465 const PropertyRegistration Control::Impl::PROPERTY_16(typeRegistration, "accessibilityName", Toolkit::DevelControl::Property::ACCESSIBILITY_NAME, Property::STRING, &Control::Impl::SetProperty, &Control::Impl::GetProperty);
466 const PropertyRegistration Control::Impl::PROPERTY_17(typeRegistration, "accessibilityDescription", Toolkit::DevelControl::Property::ACCESSIBILITY_DESCRIPTION, Property::STRING, &Control::Impl::SetProperty, &Control::Impl::GetProperty);
467 const PropertyRegistration Control::Impl::PROPERTY_18(typeRegistration, "accessibilityTranslationDomain", Toolkit::DevelControl::Property::ACCESSIBILITY_TRANSLATION_DOMAIN, Property::STRING, &Control::Impl::SetProperty, &Control::Impl::GetProperty);
468 const PropertyRegistration Control::Impl::PROPERTY_19(typeRegistration, "accessibilityRole", Toolkit::DevelControl::Property::ACCESSIBILITY_ROLE, Property::INTEGER, &Control::Impl::SetProperty, &Control::Impl::GetProperty);
469 const PropertyRegistration Control::Impl::PROPERTY_20(typeRegistration, "accessibilityHighlightable", Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE, Property::BOOLEAN, &Control::Impl::SetProperty, &Control::Impl::GetProperty);
470 const PropertyRegistration Control::Impl::PROPERTY_21(typeRegistration, "accessibilityAttributes", Toolkit::DevelControl::Property::ACCESSIBILITY_ATTRIBUTES, Property::MAP, &Control::Impl::SetProperty, &Control::Impl::GetProperty);
471 const PropertyRegistration Control::Impl::PROPERTY_22(typeRegistration, "dispatchKeyEvents", Toolkit::DevelControl::Property::DISPATCH_KEY_EVENTS, Property::BOOLEAN, &Control::Impl::SetProperty, &Control::Impl::GetProperty);
475 Control::Impl::Impl(Control& controlImpl)
476 : mControlImpl(controlImpl),
477 mState(Toolkit::DevelControl::NORMAL),
479 mLeftFocusableActorId(-1),
480 mRightFocusableActorId(-1),
481 mUpFocusableActorId(-1),
482 mDownFocusableActorId(-1),
484 mBackgroundColor(Color::TRANSPARENT),
485 mStartingPinchScale(nullptr),
487 mPadding(0, 0, 0, 0),
489 mKeyInputFocusGainedSignal(),
490 mKeyInputFocusLostSignal(),
491 mResourceReadySignal(),
492 mVisualEventSignal(),
493 mAccessibilityGetNameSignal(),
494 mAccessibilityGetDescriptionSignal(),
495 mAccessibilityDoGestureSignal(),
496 mPinchGestureDetector(),
497 mPanGestureDetector(),
498 mTapGestureDetector(),
499 mLongPressGestureDetector(),
501 mInputMethodContext(),
502 mIdleCallback(nullptr),
503 mFlags(Control::ControlBehaviour(CONTROL_BEHAVIOUR_DEFAULT)),
504 mIsKeyboardNavigationSupported(false),
505 mIsKeyboardFocusGroup(false),
506 mIsEmittingResourceReadySignal(false),
507 mNeedToEmitResourceReady(false),
508 mDispatchKeyEvents(true)
510 Dali::Accessibility::Accessible::RegisterControlAccessibilityGetter(
511 [](Dali::Actor actor) -> Dali::Accessibility::Accessible* {
512 return Control::Impl::GetAccessibilityObject(actor);
515 mAccessibilityConstructor = [](Dali::Actor actor) -> std::unique_ptr<Dali::Accessibility::Accessible> {
516 return std::unique_ptr<Dali::Accessibility::Accessible>(new DevelControl::AccessibleImpl(actor, Dali::Accessibility::Role::UNKNOWN));
519 size_t length = static_cast<size_t>(Dali::Accessibility::RelationType::MAX_COUNT);
520 mAccessibilityRelations.reserve(length);
521 for(auto i = 0u; i < length; ++i)
523 mAccessibilityRelations.push_back({});
527 Control::Impl::~Impl()
529 for(auto&& iter : mVisuals)
531 StopObservingVisual(iter->visual);
534 for(auto&& iter : mRemoveVisuals)
536 StopObservingVisual(iter->visual);
539 // All gesture detectors will be destroyed so no need to disconnect.
540 delete mStartingPinchScale;
542 if(mIdleCallback && Adaptor::IsAvailable())
544 // Removes the callback from the callback manager in case the control is destroyed before the callback is executed.
545 Adaptor::Get().RemoveIdle(mIdleCallback);
549 Control::Impl& Control::Impl::Get(Internal::Control& internalControl)
551 return *internalControl.mImpl;
554 const Control::Impl& Control::Impl::Get(const Internal::Control& internalControl)
556 return *internalControl.mImpl;
559 void Control::Impl::CheckHighlightedObjectGeometry()
561 auto accessibleImpl = dynamic_cast<Dali::Toolkit::DevelControl::AccessibleImpl*>(mAccessibilityObject.get());
564 DALI_LOG_ERROR("accessibleImpl is not a pointer to a DevelControl::AccessibleImpl type");
568 auto lastPosition = accessibleImpl->GetLastPosition();
569 auto accessibleRect = accessibleImpl->GetExtents(Dali::Accessibility::CoordinateType::WINDOW);
570 auto rect = GetShowingGeometry(accessibleRect, accessibleImpl);
572 switch(mAccessibilityLastScreenRelativeMoveType)
574 case Dali::Accessibility::ScreenRelativeMoveType::OUTSIDE:
576 if(IsShowingGeometryOnScreen(rect))
578 mAccessibilityLastScreenRelativeMoveType = Dali::Accessibility::ScreenRelativeMoveType::INSIDE;
582 case Dali::Accessibility::ScreenRelativeMoveType::INSIDE:
584 if(rect.width < 0 && accessibleRect.x != lastPosition.x)
586 mAccessibilityLastScreenRelativeMoveType = (accessibleRect.x < lastPosition.x) ? Dali::Accessibility::ScreenRelativeMoveType::OUTGOING_TOP_LEFT : Dali::Accessibility::ScreenRelativeMoveType::OUTGOING_BOTTOM_RIGHT;
588 if(rect.height < 0 && accessibleRect.y != lastPosition.y)
590 mAccessibilityLastScreenRelativeMoveType = (accessibleRect.y < lastPosition.y) ? Dali::Accessibility::ScreenRelativeMoveType::OUTGOING_TOP_LEFT : Dali::Accessibility::ScreenRelativeMoveType::OUTGOING_BOTTOM_RIGHT;
592 // notify AT-clients on outgoing moves only
593 if(mAccessibilityLastScreenRelativeMoveType != Dali::Accessibility::ScreenRelativeMoveType::INSIDE)
595 mAccessibilityObject.get()->EmitMovedOutOfScreen(mAccessibilityLastScreenRelativeMoveType);
599 case Dali::Accessibility::ScreenRelativeMoveType::OUTGOING_TOP_LEFT:
600 case Dali::Accessibility::ScreenRelativeMoveType::OUTGOING_BOTTOM_RIGHT:
602 if(IsShowingGeometryOnScreen(rect))
604 mAccessibilityLastScreenRelativeMoveType = Dali::Accessibility::ScreenRelativeMoveType::INSIDE;
608 mAccessibilityLastScreenRelativeMoveType = Dali::Accessibility::ScreenRelativeMoveType::OUTSIDE;
618 accessibleImpl->SetLastPosition(Vector2(accessibleRect.x, accessibleRect.y));
621 void Control::Impl::RegisterAccessibilityPositionPropertyNotification()
623 if(mIsAccessibilityPositionPropertyNotificationSet)
627 // set default value until first move of object is detected
628 mAccessibilityLastScreenRelativeMoveType = Dali::Accessibility::ScreenRelativeMoveType::OUTSIDE;
629 // recalculate mAccessibilityLastScreenRelativeMoveType accordingly to the initial position
630 CheckHighlightedObjectGeometry();
631 mAccessibilityPositionNotification = mControlImpl.Self().AddPropertyNotification(Actor::Property::WORLD_POSITION, StepCondition(1.0f, 1.0f));
632 mAccessibilityPositionNotification.SetNotifyMode(PropertyNotification::NOTIFY_ON_CHANGED);
633 mAccessibilityPositionNotification.NotifySignal().Connect(this, [this](PropertyNotification&){ CheckHighlightedObjectGeometry(); });
634 mIsAccessibilityPositionPropertyNotificationSet = true;
637 void Control::Impl::UnregisterAccessibilityPositionPropertyNotification()
639 mControlImpl.Self().RemovePropertyNotification(mAccessibilityPositionNotification);
640 mIsAccessibilityPositionPropertyNotificationSet = false;
643 // Gesture Detection Methods
644 void Control::Impl::PinchDetected(Actor actor, const PinchGesture& pinch)
646 mControlImpl.OnPinch(pinch);
649 void Control::Impl::PanDetected(Actor actor, const PanGesture& pan)
651 mControlImpl.OnPan(pan);
654 void Control::Impl::TapDetected(Actor actor, const TapGesture& tap)
656 mControlImpl.OnTap(tap);
659 void Control::Impl::LongPressDetected(Actor actor, const LongPressGesture& longPress)
661 mControlImpl.OnLongPress(longPress);
664 void Control::Impl::RegisterVisual(Property::Index index, Toolkit::Visual::Base& visual)
666 RegisterVisual(index, visual, VisualState::ENABLED, DepthIndexValue::NOT_SET);
669 void Control::Impl::RegisterVisual(Property::Index index, Toolkit::Visual::Base& visual, int depthIndex)
671 RegisterVisual(index, visual, VisualState::ENABLED, DepthIndexValue::SET, depthIndex);
674 void Control::Impl::RegisterVisual(Property::Index index, Toolkit::Visual::Base& visual, bool enabled)
676 RegisterVisual(index, visual, (enabled ? VisualState::ENABLED : VisualState::DISABLED), DepthIndexValue::NOT_SET);
679 void Control::Impl::RegisterVisual(Property::Index index, Toolkit::Visual::Base& visual, bool enabled, int depthIndex)
681 RegisterVisual(index, visual, (enabled ? VisualState::ENABLED : VisualState::DISABLED), DepthIndexValue::SET, depthIndex);
684 void Control::Impl::RegisterVisual(Property::Index index, Toolkit::Visual::Base& visual, VisualState::Type enabled, DepthIndexValue::Type depthIndexValueSet, int depthIndex)
686 DALI_LOG_INFO(gLogFilter, Debug::Concise, "RegisterVisual:%d \n", index);
688 bool visualReplaced(false);
689 Actor self = mControlImpl.Self();
691 // Set the depth index, if not set by caller this will be either the current visual depth, max depth of all visuals
693 int requiredDepthIndex = visual.GetDepthIndex();
695 if(depthIndexValueSet == DepthIndexValue::SET)
697 requiredDepthIndex = depthIndex;
700 // Visual replacement, existing visual should only be removed from stage when replacement ready.
701 if(!mVisuals.Empty())
703 RegisteredVisualContainer::Iterator registeredVisualsiter;
704 // Check if visual (index) is already registered, this is the current visual.
705 if(FindVisual(index, mVisuals, registeredVisualsiter))
707 Toolkit::Visual::Base& currentRegisteredVisual = (*registeredVisualsiter)->visual;
708 if(currentRegisteredVisual)
710 // Store current visual depth index as may need to set the replacement visual to same depth
711 const int currentDepthIndex = (*registeredVisualsiter)->visual.GetDepthIndex();
713 // No longer required to know if the replaced visual's resources are ready
714 StopObservingVisual(currentRegisteredVisual);
716 // If control staged and visual enabled then visuals will be swapped once ready
717 if(self.GetProperty<bool>(Actor::Property::CONNECTED_TO_SCENE) && enabled)
719 // Check if visual is currently in the process of being replaced ( is in removal container )
720 RegisteredVisualContainer::Iterator visualQueuedForRemoval;
721 if(FindVisual(index, mRemoveVisuals, visualQueuedForRemoval))
723 // Visual with same index is already in removal container so current visual pending
724 // Only the the last requested visual will be displayed so remove current visual which is staged but not ready.
725 Toolkit::GetImplementation(currentRegisteredVisual).SetOffScene(self);
726 mVisuals.Erase(registeredVisualsiter);
730 // current visual not already in removal container so add now.
731 DALI_LOG_INFO(gLogFilter, Debug::Verbose, "RegisterVisual Move current registered visual to removal Queue: %d \n", index);
732 MoveVisual(registeredVisualsiter, mVisuals, mRemoveVisuals);
737 // Control not staged or visual disabled so can just erase from registered visuals and new visual will be added later.
738 mVisuals.Erase(registeredVisualsiter);
741 // 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
742 if((depthIndexValueSet == DepthIndexValue::NOT_SET) &&
743 (visual.GetDepthIndex() == 0))
745 requiredDepthIndex = currentDepthIndex;
749 visualReplaced = true;
753 // If not set, set the name of the visual to the same name as the control's property.
754 // ( If the control has been type registered )
755 if(visual.GetName().empty())
757 // returns empty string if index is not found as long as index is not -1
758 std::string visualName = self.GetPropertyName(index);
759 if(!visualName.empty())
761 DALI_LOG_INFO(gLogFilter, Debug::Concise, "Setting visual name for property %d to %s\n", index, visualName.c_str());
762 visual.SetName(visualName);
766 if(!visualReplaced) // New registration entry
768 // 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
769 if((depthIndexValueSet == DepthIndexValue::NOT_SET) &&
770 (mVisuals.Size() > 0) &&
771 (visual.GetDepthIndex() == 0))
773 int maxDepthIndex = std::numeric_limits<int>::min();
775 RegisteredVisualContainer::ConstIterator iter;
776 const RegisteredVisualContainer::ConstIterator endIter = mVisuals.End();
777 for(iter = mVisuals.Begin(); iter != endIter; iter++)
779 const int visualDepthIndex = (*iter)->visual.GetDepthIndex();
780 if(visualDepthIndex > maxDepthIndex)
782 maxDepthIndex = visualDepthIndex;
785 ++maxDepthIndex; // Add one to the current maximum depth index so that our added visual appears on top
786 requiredDepthIndex = std::max(0, maxDepthIndex); // Start at zero if maxDepth index belongs to a background
792 // Set determined depth index
793 visual.SetDepthIndex(requiredDepthIndex);
795 // Monitor when the visual resources are ready
796 StartObservingVisual(visual);
798 DALI_LOG_INFO(gLogFilter, Debug::Concise, "New Visual registration index[%d] depth[%d]\n", index, requiredDepthIndex);
799 RegisteredVisual* newRegisteredVisual = new RegisteredVisual(index, visual, (enabled == VisualState::ENABLED ? true : false), (visualReplaced && enabled));
800 mVisuals.PushBack(newRegisteredVisual);
802 Internal::Visual::Base& visualImpl = Toolkit::GetImplementation(visual);
803 // Put on stage if enabled and the control is already on the stage
804 if((enabled == VisualState::ENABLED) && self.GetProperty<bool>(Actor::Property::CONNECTED_TO_SCENE))
806 visualImpl.SetOnScene(self);
808 else if(visualImpl.IsResourceReady()) // When not being staged, check if visual already 'ResourceReady' before it was Registered. ( Resource may have been loaded already )
810 ResourceReady(visualImpl);
814 DALI_LOG_INFO(gLogFilter, Debug::Verbose, "Control::RegisterVisual() Registered %s(%d), enabled:%s\n", visual.GetName().c_str(), index, enabled ? "true" : "false");
817 void Control::Impl::UnregisterVisual(Property::Index index)
819 RegisteredVisualContainer::Iterator iter;
820 if(FindVisual(index, mVisuals, iter))
822 // stop observing visual
823 StopObservingVisual((*iter)->visual);
825 Actor self(mControlImpl.Self());
826 Toolkit::GetImplementation((*iter)->visual).SetOffScene(self);
827 (*iter)->visual.Reset();
828 mVisuals.Erase(iter);
831 if(FindVisual(index, mRemoveVisuals, iter))
833 Actor self(mControlImpl.Self());
834 Toolkit::GetImplementation((*iter)->visual).SetOffScene(self);
835 (*iter)->pending = false;
836 (*iter)->visual.Reset();
837 mRemoveVisuals.Erase(iter);
841 Toolkit::Visual::Base Control::Impl::GetVisual(Property::Index index) const
843 RegisteredVisualContainer::Iterator iter;
844 if(FindVisual(index, mVisuals, iter))
846 return (*iter)->visual;
849 return Toolkit::Visual::Base();
852 void Control::Impl::EnableVisual(Property::Index index, bool enable)
854 DALI_LOG_INFO(gLogFilter, Debug::General, "Control::EnableVisual(%d, %s)\n", index, enable ? "T" : "F");
856 RegisteredVisualContainer::Iterator iter;
857 if(FindVisual(index, mVisuals, iter))
859 if((*iter)->enabled == enable)
861 DALI_LOG_INFO(gLogFilter, Debug::Verbose, "Control::EnableVisual Visual %s(%d) already %s\n", (*iter)->visual.GetName().c_str(), index, enable ? "enabled" : "disabled");
865 (*iter)->enabled = enable;
866 Actor parentActor = mControlImpl.Self();
867 if(mControlImpl.Self().GetProperty<bool>(Actor::Property::CONNECTED_TO_SCENE)) // If control not on Scene then Visual will be added when SceneConnection is called.
871 DALI_LOG_INFO(gLogFilter, Debug::Verbose, "Control::EnableVisual Setting %s(%d) on stage \n", (*iter)->visual.GetName().c_str(), index);
872 Toolkit::GetImplementation((*iter)->visual).SetOnScene(parentActor);
876 DALI_LOG_INFO(gLogFilter, Debug::Verbose, "Control::EnableVisual Setting %s(%d) off stage \n", (*iter)->visual.GetName().c_str(), index);
877 Toolkit::GetImplementation((*iter)->visual).SetOffScene(parentActor); // No need to call if control not staged.
883 DALI_LOG_WARNING("Control::EnableVisual(%d, %s) FAILED - NO SUCH VISUAL\n", index, enable ? "T" : "F");
887 bool Control::Impl::IsVisualEnabled(Property::Index index) const
889 RegisteredVisualContainer::Iterator iter;
890 if(FindVisual(index, mVisuals, iter))
892 return (*iter)->enabled;
897 void Control::Impl::StopObservingVisual(Toolkit::Visual::Base& visual)
899 Internal::Visual::Base& visualImpl = Toolkit::GetImplementation(visual);
901 // Stop observing the visual
902 visualImpl.RemoveEventObserver(*this);
905 void Control::Impl::StartObservingVisual(Toolkit::Visual::Base& visual)
907 Internal::Visual::Base& visualImpl = Toolkit::GetImplementation(visual);
909 // start observing the visual for events
910 visualImpl.AddEventObserver(*this);
913 // Called by a Visual when it's resource is ready
914 void Control::Impl::ResourceReady(Visual::Base& object)
916 DALI_LOG_INFO(gLogFilter, Debug::Verbose, "Control::Impl::ResourceReady() replacements pending[%d]\n", mRemoveVisuals.Count());
918 Actor self = mControlImpl.Self();
920 // A resource is ready, find resource in the registered visuals container and get its index
921 for(auto registeredIter = mVisuals.Begin(), end = mVisuals.End(); registeredIter != end; ++registeredIter)
923 Internal::Visual::Base& registeredVisualImpl = Toolkit::GetImplementation((*registeredIter)->visual);
925 if(&object == ®isteredVisualImpl)
927 RegisteredVisualContainer::Iterator visualToRemoveIter;
928 // Find visual with the same index in the removal container
929 // Set if off stage as it's replacement is now ready.
930 // Remove if from removal list as now removed from stage.
931 // Set Pending flag on the ready visual to false as now ready.
932 if(FindVisual((*registeredIter)->index, mRemoveVisuals, visualToRemoveIter))
934 (*registeredIter)->pending = false;
935 Toolkit::GetImplementation((*visualToRemoveIter)->visual).SetOffScene(self);
936 mRemoveVisuals.Erase(visualToRemoveIter);
942 // A visual is ready so control may need relayouting if staged
943 if(self.GetProperty<bool>(Actor::Property::CONNECTED_TO_SCENE))
945 mControlImpl.RelayoutRequest();
948 // Emit signal if all enabled visuals registered by the control are ready.
949 if(IsResourceReady())
952 mNeedToEmitResourceReady = false;
954 EmitResourceReadySignal();
958 void Control::Impl::NotifyVisualEvent(Visual::Base& object, Property::Index signalId)
960 for(auto registeredIter = mVisuals.Begin(), end = mVisuals.End(); registeredIter != end; ++registeredIter)
962 Internal::Visual::Base& registeredVisualImpl = Toolkit::GetImplementation((*registeredIter)->visual);
963 if(&object == ®isteredVisualImpl)
965 Dali::Toolkit::Control handle(mControlImpl.GetOwner());
966 mVisualEventSignal.Emit(handle, (*registeredIter)->index, signalId);
972 bool Control::Impl::IsResourceReady() const
974 // Iterate through and check all the enabled visuals are ready
975 for(auto visualIter = mVisuals.Begin();
976 visualIter != mVisuals.End();
979 const Toolkit::Visual::Base visual = (*visualIter)->visual;
980 const Internal::Visual::Base& visualImpl = Toolkit::GetImplementation(visual);
982 // one of the enabled visuals is not ready
983 if(!visualImpl.IsResourceReady() && (*visualIter)->enabled)
991 Toolkit::Visual::ResourceStatus Control::Impl::GetVisualResourceStatus(Property::Index index) const
993 RegisteredVisualContainer::Iterator iter;
994 if(FindVisual(index, mVisuals, iter))
996 const Toolkit::Visual::Base visual = (*iter)->visual;
997 const Internal::Visual::Base& visualImpl = Toolkit::GetImplementation(visual);
998 return visualImpl.GetResourceStatus();
1001 return Toolkit::Visual::ResourceStatus::PREPARING;
1004 void Control::Impl::AddTransitions(Dali::Animation& animation,
1005 const Toolkit::TransitionData& handle,
1006 bool createAnimation)
1008 // Setup a Transition from TransitionData.
1009 const Internal::TransitionData& transitionData = Toolkit::GetImplementation(handle);
1010 TransitionData::Iterator end = transitionData.End();
1011 for(TransitionData::Iterator iter = transitionData.Begin();
1015 TransitionData::Animator* animator = (*iter);
1017 Toolkit::Visual::Base visual = GetVisualByName(mVisuals, animator->objectName);
1021 #if defined(DEBUG_ENABLED)
1022 Dali::TypeInfo typeInfo;
1023 ControlWrapper* controlWrapperImpl = dynamic_cast<ControlWrapper*>(&mControlImpl);
1024 if(controlWrapperImpl)
1026 typeInfo = controlWrapperImpl->GetTypeInfo();
1029 DALI_LOG_INFO(gLogFilter, Debug::Concise, "CreateTransition: Found %s visual for %s\n", visual.GetName().c_str(), typeInfo ? typeInfo.GetName().c_str() : "Unknown");
1031 Internal::Visual::Base& visualImpl = Toolkit::GetImplementation(visual);
1032 visualImpl.AnimateProperty(animation, *animator);
1036 DALI_LOG_INFO(gLogFilter, Debug::Concise, "CreateTransition: Could not find visual. Trying actors");
1037 // Otherwise, try any actor children of control (Including the control)
1038 Actor child = mControlImpl.Self().FindChildByName(animator->objectName);
1041 Property::Index propertyIndex = child.GetPropertyIndex(animator->propertyKey);
1042 if(propertyIndex != Property::INVALID_INDEX)
1044 if(animator->animate == false)
1046 if(animator->targetValue.GetType() != Property::NONE)
1048 child.SetProperty(propertyIndex, animator->targetValue);
1051 else // animate the property
1053 if(animator->initialValue.GetType() != Property::NONE)
1055 child.SetProperty(propertyIndex, animator->initialValue);
1058 if(createAnimation && !animation)
1060 animation = Dali::Animation::New(0.1f);
1063 animation.AnimateTo(Property(child, propertyIndex),
1064 animator->targetValue,
1065 animator->alphaFunction,
1066 TimePeriod(animator->timePeriodDelay,
1067 animator->timePeriodDuration));
1075 Dali::Animation Control::Impl::CreateTransition(const Toolkit::TransitionData& transitionData)
1077 Dali::Animation transition;
1079 if(transitionData.Count() > 0)
1081 AddTransitions(transition, transitionData, true);
1086 void Control::Impl::DoAction(Dali::Property::Index visualIndex, Dali::Property::Index actionId, const Dali::Property::Value attributes)
1088 RegisteredVisualContainer::Iterator iter;
1089 if(FindVisual(visualIndex, mVisuals, iter))
1091 Toolkit::GetImplementation((*iter)->visual).DoAction(actionId, attributes);
1095 void Control::Impl::AppendAccessibilityAttribute(const std::string& key, const std::string value)
1097 Property::Value* checkedValue = mAccessibilityAttributes.Find(key);
1100 mAccessibilityAttributes[key] = Property::Value(value);
1104 mAccessibilityAttributes.Insert(key, value);
1108 void Control::Impl::SetProperty(BaseObject* object, Property::Index index, const Property::Value& value)
1110 Toolkit::Control control = Toolkit::Control::DownCast(BaseHandle(object));
1114 Control& controlImpl(GetImplementation(control));
1118 case Toolkit::Control::Property::STYLE_NAME:
1120 controlImpl.SetStyleName(value.Get<std::string>());
1124 case Toolkit::DevelControl::Property::STATE:
1126 bool withTransitions = true;
1127 const Property::Value* valuePtr = &value;
1128 const Property::Map* map = value.GetMap();
1131 Property::Value* value2 = map->Find("withTransitions");
1134 withTransitions = value2->Get<bool>();
1137 valuePtr = map->Find("state");
1142 Toolkit::DevelControl::State state(controlImpl.mImpl->mState);
1143 if(Scripting::GetEnumerationProperty<Toolkit::DevelControl::State>(*valuePtr, ControlStateTable, ControlStateTableCount, state))
1145 controlImpl.mImpl->SetState(state, withTransitions);
1151 case Toolkit::DevelControl::Property::SUB_STATE:
1153 std::string subState;
1154 if(value.Get(subState))
1156 controlImpl.mImpl->SetSubState(subState);
1161 case Toolkit::DevelControl::Property::LEFT_FOCUSABLE_ACTOR_ID:
1164 if(value.Get(focusId))
1166 controlImpl.mImpl->mLeftFocusableActorId = focusId;
1171 case Toolkit::DevelControl::Property::RIGHT_FOCUSABLE_ACTOR_ID:
1174 if(value.Get(focusId))
1176 controlImpl.mImpl->mRightFocusableActorId = focusId;
1181 case Toolkit::DevelControl::Property::UP_FOCUSABLE_ACTOR_ID:
1184 if(value.Get(focusId))
1186 controlImpl.mImpl->mUpFocusableActorId = focusId;
1191 case Toolkit::DevelControl::Property::DOWN_FOCUSABLE_ACTOR_ID:
1194 if(value.Get(focusId))
1196 controlImpl.mImpl->mDownFocusableActorId = focusId;
1201 case Toolkit::Control::Property::KEY_INPUT_FOCUS:
1203 if(value.Get<bool>())
1205 controlImpl.SetKeyInputFocus();
1209 controlImpl.ClearKeyInputFocus();
1214 case Toolkit::Control::Property::BACKGROUND:
1218 const Property::Map* map = value.GetMap();
1219 if(map && !map->Empty())
1221 controlImpl.SetBackground(*map);
1223 else if(value.Get(url))
1225 // don't know the size to load
1226 Toolkit::Visual::Base visual = Toolkit::VisualFactory::Get().CreateVisual(url, ImageDimensions());
1229 controlImpl.mImpl->RegisterVisual(Toolkit::Control::Property::BACKGROUND, visual, DepthIndex::BACKGROUND);
1232 else if(value.Get(color))
1234 controlImpl.SetBackgroundColor(color);
1238 // The background is an empty property map, so we should clear the background
1239 controlImpl.ClearBackground();
1244 case Toolkit::Control::Property::MARGIN:
1247 if(value.Get(margin))
1249 controlImpl.mImpl->SetMargin(margin);
1254 case Toolkit::Control::Property::PADDING:
1257 if(value.Get(padding))
1259 controlImpl.mImpl->SetPadding(padding);
1264 case Toolkit::DevelControl::Property::TOOLTIP:
1266 TooltipPtr& tooltipPtr = controlImpl.mImpl->mTooltip;
1269 tooltipPtr = Tooltip::New(control);
1271 tooltipPtr->SetProperties(value);
1275 case Toolkit::DevelControl::Property::SHADOW:
1277 const Property::Map* map = value.GetMap();
1278 if(map && !map->Empty())
1280 controlImpl.mImpl->SetShadow(*map);
1284 // The shadow is an empty property map, so we should clear the shadow
1285 controlImpl.mImpl->ClearShadow();
1290 case Toolkit::DevelControl::Property::ACCESSIBILITY_NAME:
1295 controlImpl.mImpl->mAccessibilityName = name;
1296 controlImpl.mImpl->mAccessibilityNameSet = true;
1300 controlImpl.mImpl->mAccessibilityNameSet = false;
1305 case Toolkit::DevelControl::Property::ACCESSIBILITY_DESCRIPTION:
1310 controlImpl.mImpl->mAccessibilityDescription = text;
1311 controlImpl.mImpl->mAccessibilityDescriptionSet = true;
1315 controlImpl.mImpl->mAccessibilityDescriptionSet = false;
1320 case Toolkit::DevelControl::Property::ACCESSIBILITY_TRANSLATION_DOMAIN:
1325 controlImpl.mImpl->mAccessibilityTranslationDomain = text;
1326 controlImpl.mImpl->mAccessibilityTranslationDomainSet = true;
1330 controlImpl.mImpl->mAccessibilityTranslationDomainSet = false;
1335 case Toolkit::DevelControl::Property::ACCESSIBILITY_ROLE:
1337 Dali::Accessibility::Role role;
1340 controlImpl.mImpl->mAccessibilityRole = role;
1345 case Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE:
1348 if(value.Get(highlightable))
1350 controlImpl.mImpl->mAccessibilityHighlightable = highlightable;
1351 controlImpl.mImpl->mAccessibilityHighlightableSet = true;
1355 controlImpl.mImpl->mAccessibilityHighlightableSet = false;
1360 case Toolkit::DevelControl::Property::ACCESSIBILITY_ATTRIBUTES:
1362 const Property::Map* map = value.GetMap();
1363 if(map && !map->Empty())
1365 controlImpl.mImpl->mAccessibilityAttributes = *map;
1370 case Toolkit::DevelControl::Property::DISPATCH_KEY_EVENTS:
1373 if(value.Get(dispatch))
1375 controlImpl.mImpl->mDispatchKeyEvents = dispatch;
1383 Property::Value Control::Impl::GetProperty(BaseObject* object, Property::Index index)
1385 Property::Value value;
1387 Toolkit::Control control = Toolkit::Control::DownCast(BaseHandle(object));
1391 Control& controlImpl(GetImplementation(control));
1395 case Toolkit::Control::Property::STYLE_NAME:
1397 value = controlImpl.GetStyleName();
1401 case Toolkit::DevelControl::Property::STATE:
1403 value = controlImpl.mImpl->mState;
1407 case Toolkit::DevelControl::Property::SUB_STATE:
1409 value = controlImpl.mImpl->mSubStateName;
1413 case Toolkit::DevelControl::Property::LEFT_FOCUSABLE_ACTOR_ID:
1415 value = controlImpl.mImpl->mLeftFocusableActorId;
1419 case Toolkit::DevelControl::Property::RIGHT_FOCUSABLE_ACTOR_ID:
1421 value = controlImpl.mImpl->mRightFocusableActorId;
1425 case Toolkit::DevelControl::Property::UP_FOCUSABLE_ACTOR_ID:
1427 value = controlImpl.mImpl->mUpFocusableActorId;
1431 case Toolkit::DevelControl::Property::DOWN_FOCUSABLE_ACTOR_ID:
1433 value = controlImpl.mImpl->mDownFocusableActorId;
1437 case Toolkit::Control::Property::KEY_INPUT_FOCUS:
1439 value = controlImpl.HasKeyInputFocus();
1443 case Toolkit::Control::Property::BACKGROUND:
1446 Toolkit::Visual::Base visual = controlImpl.mImpl->GetVisual(Toolkit::Control::Property::BACKGROUND);
1449 visual.CreatePropertyMap(map);
1456 case Toolkit::Control::Property::MARGIN:
1458 value = controlImpl.mImpl->GetMargin();
1462 case Toolkit::Control::Property::PADDING:
1464 value = controlImpl.mImpl->GetPadding();
1468 case Toolkit::DevelControl::Property::TOOLTIP:
1471 if(controlImpl.mImpl->mTooltip)
1473 controlImpl.mImpl->mTooltip->CreatePropertyMap(map);
1479 case Toolkit::DevelControl::Property::SHADOW:
1482 Toolkit::Visual::Base visual = controlImpl.mImpl->GetVisual(Toolkit::DevelControl::Property::SHADOW);
1485 visual.CreatePropertyMap(map);
1492 case Toolkit::DevelControl::Property::ACCESSIBILITY_NAME:
1494 if(controlImpl.mImpl->mAccessibilityNameSet)
1496 value = controlImpl.mImpl->mAccessibilityName;
1501 case Toolkit::DevelControl::Property::ACCESSIBILITY_DESCRIPTION:
1503 if(controlImpl.mImpl->mAccessibilityDescriptionSet)
1505 value = controlImpl.mImpl->mAccessibilityDescription;
1510 case Toolkit::DevelControl::Property::ACCESSIBILITY_TRANSLATION_DOMAIN:
1512 if(controlImpl.mImpl->mAccessibilityTranslationDomainSet)
1514 value = controlImpl.mImpl->mAccessibilityTranslationDomain;
1519 case Toolkit::DevelControl::Property::ACCESSIBILITY_ROLE:
1521 value = Property::Value(controlImpl.mImpl->mAccessibilityRole);
1525 case Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE:
1527 if(controlImpl.mImpl->mAccessibilityHighlightableSet)
1529 value = controlImpl.mImpl->mAccessibilityHighlightable;
1534 case Toolkit::DevelControl::Property::ACCESSIBILITY_ATTRIBUTES:
1536 value = controlImpl.mImpl->mAccessibilityAttributes;
1539 case Toolkit::DevelControl::Property::DISPATCH_KEY_EVENTS:
1541 value = controlImpl.mImpl->mDispatchKeyEvents;
1550 void Control::Impl::RemoveAccessibilityAttribute(const std::string& key)
1552 Property::Value* value = mAccessibilityAttributes.Find(key);
1555 mAccessibilityAttributes[key] = Property::Value();
1559 void Control::Impl::ClearAccessibilityAttributes()
1561 mAccessibilityAttributes.Clear();
1564 void Control::Impl::SetAccessibilityReadingInfoType(const Dali::Accessibility::ReadingInfoTypes types)
1566 std::string value{};
1567 if(types[Dali::Accessibility::ReadingInfoType::NAME])
1569 value += READING_INFO_TYPE_NAME;
1571 if(types[Dali::Accessibility::ReadingInfoType::ROLE])
1575 value += READING_INFO_TYPE_SEPARATOR;
1577 value += READING_INFO_TYPE_ROLE;
1579 if(types[Dali::Accessibility::ReadingInfoType::DESCRIPTION])
1583 value += READING_INFO_TYPE_SEPARATOR;
1585 value += READING_INFO_TYPE_DESCRIPTION;
1587 if(types[Dali::Accessibility::ReadingInfoType::STATE])
1591 value += READING_INFO_TYPE_SEPARATOR;
1593 value += READING_INFO_TYPE_STATE;
1595 AppendAccessibilityAttribute(READING_INFO_TYPE_ATTRIBUTE_NAME, value);
1598 Dali::Accessibility::ReadingInfoTypes Control::Impl::GetAccessibilityReadingInfoType() const
1600 std::string value{};
1601 auto place = mAccessibilityAttributes.Find(READING_INFO_TYPE_ATTRIBUTE_NAME);
1608 Dali::Accessibility::ReadingInfoTypes types;
1609 types[Dali::Accessibility::ReadingInfoType::NAME] = true;
1610 types[Dali::Accessibility::ReadingInfoType::ROLE] = true;
1611 types[Dali::Accessibility::ReadingInfoType::DESCRIPTION] = true;
1612 types[Dali::Accessibility::ReadingInfoType::STATE] = true;
1621 Dali::Accessibility::ReadingInfoTypes types;
1623 if(value.find(READING_INFO_TYPE_NAME) != std::string::npos)
1625 types[Dali::Accessibility::ReadingInfoType::NAME] = true;
1627 if(value.find(READING_INFO_TYPE_ROLE) != std::string::npos)
1629 types[Dali::Accessibility::ReadingInfoType::ROLE] = true;
1631 if(value.find(READING_INFO_TYPE_DESCRIPTION) != std::string::npos)
1633 types[Dali::Accessibility::ReadingInfoType::DESCRIPTION] = true;
1635 if(value.find(READING_INFO_TYPE_STATE) != std::string::npos)
1637 types[Dali::Accessibility::ReadingInfoType::STATE] = true;
1643 void Control::Impl::CopyInstancedProperties(RegisteredVisualContainer& visuals, Dictionary<Property::Map>& instancedProperties)
1645 for(RegisteredVisualContainer::Iterator iter = visuals.Begin(); iter != visuals.End(); iter++)
1649 Property::Map instanceMap;
1650 Toolkit::GetImplementation((*iter)->visual).CreateInstancePropertyMap(instanceMap);
1651 instancedProperties.Add((*iter)->visual.GetName(), instanceMap);
1656 void Control::Impl::RemoveVisual(RegisteredVisualContainer& visuals, const std::string& visualName)
1658 Actor self(mControlImpl.Self());
1660 for(RegisteredVisualContainer::Iterator visualIter = visuals.Begin();
1661 visualIter != visuals.End();
1664 Toolkit::Visual::Base visual = (*visualIter)->visual;
1665 if(visual && visual.GetName() == visualName)
1667 Toolkit::GetImplementation(visual).SetOffScene(self);
1668 (*visualIter)->visual.Reset();
1669 visuals.Erase(visualIter);
1675 void Control::Impl::RemoveVisuals(RegisteredVisualContainer& visuals, DictionaryKeys& removeVisuals)
1677 Actor self(mControlImpl.Self());
1678 for(DictionaryKeys::iterator iter = removeVisuals.begin(); iter != removeVisuals.end(); ++iter)
1680 const std::string visualName = *iter;
1681 RemoveVisual(visuals, visualName);
1685 void Control::Impl::RecreateChangedVisuals(Dictionary<Property::Map>& stateVisualsToChange,
1686 Dictionary<Property::Map>& instancedProperties)
1688 Dali::CustomActor handle(mControlImpl.GetOwner());
1689 for(Dictionary<Property::Map>::iterator iter = stateVisualsToChange.Begin();
1690 iter != stateVisualsToChange.End();
1693 const std::string& visualName = (*iter).key;
1694 const Property::Map& toMap = (*iter).entry;
1696 Actor self = mControlImpl.Self();
1697 RegisteredVisualContainer::Iterator registeredVisualsiter;
1698 // Check if visual (visualName) is already registered, this is the current visual.
1699 if(FindVisual(visualName, mVisuals, registeredVisualsiter))
1701 Toolkit::Visual::Base& visual = (*registeredVisualsiter)->visual;
1704 // No longer required to know if the replaced visual's resources are ready
1705 StopObservingVisual(visual);
1707 // If control staged then visuals will be swapped once ready
1708 if(self.GetProperty<bool>(Actor::Property::CONNECTED_TO_SCENE))
1710 // Check if visual is currently in the process of being replaced ( is in removal container )
1711 RegisteredVisualContainer::Iterator visualQueuedForRemoval;
1712 if(FindVisual(visualName, mRemoveVisuals, visualQueuedForRemoval))
1714 // Visual with same visual name is already in removal container so current visual pending
1715 // Only the the last requested visual will be displayed so remove current visual which is staged but not ready.
1716 Toolkit::GetImplementation(visual).SetOffScene(self);
1717 (*registeredVisualsiter)->visual.Reset();
1718 mVisuals.Erase(registeredVisualsiter);
1722 // current visual not already in removal container so add now.
1723 DALI_LOG_INFO(gLogFilter, Debug::Verbose, "RegisterVisual Move current registered visual to removal Queue: %s \n", visualName.c_str());
1724 MoveVisual(registeredVisualsiter, mVisuals, mRemoveVisuals);
1729 // Control not staged or visual disabled so can just erase from registered visuals and new visual will be added later.
1730 (*registeredVisualsiter)->visual.Reset();
1731 mVisuals.Erase(registeredVisualsiter);
1735 const Property::Map* instancedMap = instancedProperties.FindConst(visualName);
1736 Style::ApplyVisual(handle, visualName, toMap, instancedMap);
1741 void Control::Impl::ReplaceStateVisualsAndProperties(const StylePtr oldState, const StylePtr newState, const std::string& subState)
1743 // Collect all old visual names
1744 DictionaryKeys stateVisualsToRemove;
1747 oldState->visuals.GetKeys(stateVisualsToRemove);
1748 if(!subState.empty())
1750 const StylePtr* oldSubState = oldState->subStates.FindConst(subState);
1753 DictionaryKeys subStateVisualsToRemove;
1754 (*oldSubState)->visuals.GetKeys(subStateVisualsToRemove);
1755 Merge(stateVisualsToRemove, subStateVisualsToRemove);
1760 // Collect all new visual properties
1761 Dictionary<Property::Map> stateVisualsToAdd;
1764 stateVisualsToAdd = newState->visuals;
1765 if(!subState.empty())
1767 const StylePtr* newSubState = newState->subStates.FindConst(subState);
1770 stateVisualsToAdd.Merge((*newSubState)->visuals);
1775 // If a name is in both add/remove, move it to change list.
1776 Dictionary<Property::Map> stateVisualsToChange;
1777 FindChangableVisuals(stateVisualsToAdd, stateVisualsToChange, stateVisualsToRemove);
1779 // Copy instanced properties (e.g. text label) of current visuals
1780 Dictionary<Property::Map> instancedProperties;
1781 CopyInstancedProperties(mVisuals, instancedProperties);
1783 // For each visual in remove list, remove from mVisuals
1784 RemoveVisuals(mVisuals, stateVisualsToRemove);
1786 // For each visual in add list, create and add to mVisuals
1787 Dali::CustomActor handle(mControlImpl.GetOwner());
1788 Style::ApplyVisuals(handle, stateVisualsToAdd, instancedProperties);
1790 // For each visual in change list, if it requires a new visual,
1791 // remove old visual, create and add to mVisuals
1792 RecreateChangedVisuals(stateVisualsToChange, instancedProperties);
1795 void Control::Impl::SetState(DevelControl::State newState, bool withTransitions)
1797 DevelControl::State oldState = mState;
1798 Dali::CustomActor handle(mControlImpl.GetOwner());
1799 DALI_LOG_INFO(gLogFilter, Debug::Concise, "Control::Impl::SetState: %s\n", (mState == DevelControl::NORMAL ? "NORMAL" : (mState == DevelControl::FOCUSED ? "FOCUSED" : (mState == DevelControl::DISABLED ? "DISABLED" : "NONE"))));
1801 if(mState != newState)
1803 // If mState was Disabled, and new state is Focused, should probably
1804 // store that fact, e.g. in another property that FocusManager can access.
1807 // Trigger state change and transitions
1808 // Apply new style, if stylemanager is available
1809 Toolkit::StyleManager styleManager = Toolkit::StyleManager::Get();
1812 const StylePtr stylePtr = GetImpl(styleManager).GetRecordedStyle(Toolkit::Control(mControlImpl.GetOwner()));
1816 std::string oldStateName = Scripting::GetEnumerationName<Toolkit::DevelControl::State>(oldState, ControlStateTable, ControlStateTableCount);
1817 std::string newStateName = Scripting::GetEnumerationName<Toolkit::DevelControl::State>(newState, ControlStateTable, ControlStateTableCount);
1819 const StylePtr* newStateStyle = stylePtr->subStates.Find(newStateName);
1820 const StylePtr* oldStateStyle = stylePtr->subStates.Find(oldStateName);
1821 if(oldStateStyle && newStateStyle)
1823 // Only change if both state styles exist
1824 ReplaceStateVisualsAndProperties(*oldStateStyle, *newStateStyle, mSubStateName);
1831 void Control::Impl::SetSubState(const std::string& subStateName, bool withTransitions)
1833 if(mSubStateName != subStateName)
1835 // Get existing sub-state visuals, and unregister them
1836 Dali::CustomActor handle(mControlImpl.GetOwner());
1838 Toolkit::StyleManager styleManager = Toolkit::StyleManager::Get();
1841 const StylePtr stylePtr = GetImpl(styleManager).GetRecordedStyle(Toolkit::Control(mControlImpl.GetOwner()));
1845 std::string stateName = Scripting::GetEnumerationName<Toolkit::DevelControl::State>(mState, ControlStateTable, ControlStateTableCount);
1847 const StylePtr* state = stylePtr->subStates.Find(stateName);
1850 StylePtr stateStyle(*state);
1852 const StylePtr* newStateStyle = stateStyle->subStates.Find(subStateName);
1853 const StylePtr* oldStateStyle = stateStyle->subStates.Find(mSubStateName);
1854 if(oldStateStyle && newStateStyle)
1857 ReplaceStateVisualsAndProperties(*oldStateStyle, *newStateStyle, empty);
1863 mSubStateName = subStateName;
1867 void Control::Impl::OnSceneDisconnection()
1869 Actor self = mControlImpl.Self();
1871 // Any visuals set for replacement but not yet ready should still be registered.
1872 // Reason: If a request was made to register a new visual but the control removed from scene before visual was ready
1873 // then when this control appears back on stage it should use that new visual.
1875 // Iterate through all registered visuals and set off scene
1876 SetVisualsOffScene(mVisuals, self);
1878 // Visuals pending replacement can now be taken out of the removal list and set off scene
1879 // Iterate through all replacement visuals and add to a move queue then set off scene
1880 for(auto removalIter = mRemoveVisuals.Begin(), end = mRemoveVisuals.End(); removalIter != end; removalIter++)
1882 Toolkit::GetImplementation((*removalIter)->visual).SetOffScene(self);
1885 for(auto replacedIter = mVisuals.Begin(), end = mVisuals.End(); replacedIter != end; replacedIter++)
1887 (*replacedIter)->pending = false;
1890 mRemoveVisuals.Clear();
1893 void Control::Impl::SetMargin(Extents margin)
1895 mControlImpl.mImpl->mMargin = margin;
1897 // Trigger a size negotiation request that may be needed when setting a margin.
1898 mControlImpl.RelayoutRequest();
1901 Extents Control::Impl::GetMargin() const
1903 return mControlImpl.mImpl->mMargin;
1906 void Control::Impl::SetPadding(Extents padding)
1908 mControlImpl.mImpl->mPadding = padding;
1910 // Trigger a size negotiation request that may be needed when setting a padding.
1911 mControlImpl.RelayoutRequest();
1914 Extents Control::Impl::GetPadding() const
1916 return mControlImpl.mImpl->mPadding;
1919 void Control::Impl::SetInputMethodContext(InputMethodContext& inputMethodContext)
1921 mInputMethodContext = inputMethodContext;
1924 bool Control::Impl::FilterKeyEvent(const KeyEvent& event)
1926 bool consumed(false);
1928 if(mInputMethodContext)
1930 consumed = mInputMethodContext.FilterEventKey(event);
1935 DevelControl::VisualEventSignalType& Control::Impl::VisualEventSignal()
1937 return mVisualEventSignal;
1940 void Control::Impl::SetShadow(const Property::Map& map)
1942 Toolkit::Visual::Base visual = Toolkit::VisualFactory::Get().CreateVisual(map);
1943 visual.SetName("shadow");
1947 mControlImpl.mImpl->RegisterVisual(Toolkit::DevelControl::Property::SHADOW, visual, DepthIndex::BACKGROUND_EFFECT);
1949 mControlImpl.RelayoutRequest();
1953 void Control::Impl::ClearShadow()
1955 mControlImpl.mImpl->UnregisterVisual(Toolkit::DevelControl::Property::SHADOW);
1957 // Trigger a size negotiation request that may be needed when unregistering a visual.
1958 mControlImpl.RelayoutRequest();
1961 Dali::Property Control::Impl::GetVisualProperty(Dali::Property::Index index, Dali::Property::Key visualPropertyKey)
1963 Toolkit::Visual::Base visual = GetVisualByIndex(mVisuals, index);
1966 Internal::Visual::Base& visualImpl = Toolkit::GetImplementation(visual);
1967 return visualImpl.GetPropertyObject(visualPropertyKey);
1971 return Dali::Property(handle, Property::INVALID_INDEX);
1974 void Control::Impl::CreateTransitions(std::vector<std::pair<Dali::Property::Index, Dali::Property::Map>>& sourceProperties,
1975 std::vector<std::pair<Dali::Property::Index, Dali::Property::Map>>& destinationProperties,
1976 Dali::Toolkit::Control source, Dali::Toolkit::Control destination)
1978 // Retrieves background properties to be transitioned.
1979 Dali::Property::Map backgroundSourcePropertyMap, backgroundDestinationPropertyMap;
1980 mControlImpl.MakeVisualTransition(backgroundSourcePropertyMap, backgroundDestinationPropertyMap, source, destination, Toolkit::Control::Property::BACKGROUND);
1981 if(backgroundSourcePropertyMap.Count() > 0)
1983 sourceProperties.push_back(std::pair<Dali::Property::Index, Dali::Property::Map>(Toolkit::Control::Property::BACKGROUND, backgroundSourcePropertyMap));
1984 destinationProperties.push_back(std::pair<Dali::Property::Index, Dali::Property::Map>(Toolkit::Control::Property::BACKGROUND, backgroundDestinationPropertyMap));
1987 // Retrieves shadow properties to be transitioned.
1988 Dali::Property::Map shadowSourcePropertyMap, shadowDestinationPropertyMap;
1989 mControlImpl.MakeVisualTransition(shadowSourcePropertyMap, shadowDestinationPropertyMap, source, destination, Toolkit::DevelControl::Property::SHADOW);
1990 if(shadowSourcePropertyMap.Count() > 0)
1992 sourceProperties.push_back(std::pair<Dali::Property::Index, Dali::Property::Map>(Toolkit::DevelControl::Property::SHADOW, shadowSourcePropertyMap));
1993 destinationProperties.push_back(std::pair<Dali::Property::Index, Dali::Property::Map>(Toolkit::DevelControl::Property::SHADOW, shadowDestinationPropertyMap));
1996 // Retrieves transition from inherited class.
1997 mControlImpl.OnCreateTransitions(sourceProperties, destinationProperties, source, destination);
2000 void Control::Impl::UpdateVisualProperties(const std::vector<std::pair<Dali::Property::Index, Dali::Property::Map>>& properties)
2002 for(auto&& data : properties)
2004 if(data.first == Toolkit::Control::Property::BACKGROUND)
2006 DoAction(Toolkit::Control::Property::BACKGROUND, DevelVisual::Action::UPDATE_PROPERTY, data.second);
2008 else if(data.first == Toolkit::DevelControl::Property::SHADOW)
2010 DoAction(Toolkit::DevelControl::Property::SHADOW, DevelVisual::Action::UPDATE_PROPERTY, data.second);
2013 mControlImpl.OnUpdateVisualProperties(properties);
2016 void Control::Impl::EmitResourceReadySignal()
2018 if(!mIsEmittingResourceReadySignal)
2020 // Guard against calls to emit the signal during the callback
2021 mIsEmittingResourceReadySignal = true;
2023 // If the signal handler changes visual, it may become ready during this call & therefore this method will
2024 // get called again recursively. If so, mNeedToEmitResourceReady is set below, and we act on it after that secondary
2025 // invocation has completed by notifying in an Idle callback to prevent further recursion.
2026 Dali::Toolkit::Control handle(mControlImpl.GetOwner());
2027 mResourceReadySignal.Emit(handle);
2029 if(mNeedToEmitResourceReady)
2031 // Add idler to emit the signal again
2034 // The callback manager takes the ownership of the callback object.
2035 mIdleCallback = MakeCallback(this, &Control::Impl::OnIdleCallback);
2036 Adaptor::Get().AddIdle(mIdleCallback, false);
2040 mIsEmittingResourceReadySignal = false;
2044 mNeedToEmitResourceReady = true;
2048 void Control::Impl::OnIdleCallback()
2050 if(mNeedToEmitResourceReady)
2053 mNeedToEmitResourceReady = false;
2055 // A visual is ready so control may need relayouting if staged
2056 if(mControlImpl.Self().GetProperty<bool>(Actor::Property::CONNECTED_TO_SCENE))
2058 mControlImpl.RelayoutRequest();
2061 EmitResourceReadySignal();
2064 // Set the pointer to null as the callback manager deletes the callback after execute it.
2065 mIdleCallback = nullptr;
2068 Dali::Accessibility::Accessible* Control::Impl::GetAccessibilityObject()
2070 if(!mAccessibilityObject)
2072 mAccessibilityObject = mAccessibilityConstructor(mControlImpl.Self());
2074 return mAccessibilityObject.get();
2077 Dali::Accessibility::Accessible* Control::Impl::GetAccessibilityObject(Dali::Actor actor)
2081 auto control = Dali::Toolkit::Control::DownCast(actor);
2084 auto controlImpl = static_cast<Internal::Control*>(&control.GetImplementation());
2085 return controlImpl->mImpl->GetAccessibilityObject();
2091 } // namespace Internal
2093 } // namespace Toolkit