X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=blobdiff_plain;f=dali-toolkit%2Finternal%2Fcontrols%2Fcontrol%2Fcontrol-data-impl.cpp;h=4c747047df1f9cb19daea3ba8666378a6a3e0c21;hp=ff1ca1e0cd8b5dcc29466a1baef47b0797459d37;hb=6da98d4f526029d51c8404964dd954afe9752401;hpb=2ca1c3856ce848a94f54444f1014a820e91ee207 diff --git a/dali-toolkit/internal/controls/control/control-data-impl.cpp b/dali-toolkit/internal/controls/control/control-data-impl.cpp index ff1ca1e..4c74704 100644 --- a/dali-toolkit/internal/controls/control/control-data-impl.cpp +++ b/dali-toolkit/internal/controls/control/control-data-impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Samsung Electronics Co., Ltd. + * Copyright (c) 2022 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -222,44 +223,57 @@ static bool DoAction(BaseObject* object, const std::string& actionName, const Pr DALI_ASSERT_ALWAYS(control); - if(0 == strcmp(actionName.c_str(), ACTION_ACCESSIBILITY_ACTIVATED) || - actionName == "activate") + if(0 == strcmp(actionName.c_str(), ACTION_ACCESSIBILITY_ACTIVATED) || actionName == "activate") { // if cast succeeds there is an implementation so no need to check if(!DevelControl::AccessibilityActivateSignal(control).Empty()) + { DevelControl::AccessibilityActivateSignal(control).Emit(); + } else + { ret = Internal::GetImplementation(control).OnAccessibilityActivated(); + } } else if(0 == strcmp(actionName.c_str(), ACTION_ACCESSIBILITY_READING_SKIPPED)) { // if cast succeeds there is an implementation so no need to check if(!DevelControl::AccessibilityReadingSkippedSignal(control).Empty()) + { DevelControl::AccessibilityReadingSkippedSignal(control).Emit(); + } } else if(0 == strcmp(actionName.c_str(), ACTION_ACCESSIBILITY_READING_PAUSED)) { // if cast succeeds there is an implementation so no need to check if(!DevelControl::AccessibilityReadingPausedSignal(control).Empty()) + { DevelControl::AccessibilityReadingPausedSignal(control).Emit(); + } } else if(0 == strcmp(actionName.c_str(), ACTION_ACCESSIBILITY_READING_RESUMED)) { // if cast succeeds there is an implementation so no need to check if(!DevelControl::AccessibilityReadingResumedSignal(control).Empty()) + { DevelControl::AccessibilityReadingResumedSignal(control).Emit(); + } } else if(0 == strcmp(actionName.c_str(), ACTION_ACCESSIBILITY_READING_CANCELLED)) { // if cast succeeds there is an implementation so no need to check if(!DevelControl::AccessibilityReadingCancelledSignal(control).Empty()) + { DevelControl::AccessibilityReadingCancelledSignal(control).Emit(); + } } else if(0 == strcmp(actionName.c_str(), ACTION_ACCESSIBILITY_READING_STOPPED)) { // if cast succeeds there is an implementation so no need to check if(!DevelControl::AccessibilityReadingStoppedSignal(control).Empty()) + { DevelControl::AccessibilityReadingStoppedSignal(control).Emit(); + } } else { @@ -397,6 +411,53 @@ void SetVisualsOffScene(const RegisteredVisualContainer& container, Actor parent } } +Dali::Rect<> GetShowingGeometry(Dali::Rect<> rect, Dali::Toolkit::DevelControl::ControlAccessible* accessible) +{ + Rect<> parentRect; + Vector2 currentPosition; + auto parent = dynamic_cast(accessible->GetParent()); + + while(parent) + { + parentRect = parent->GetExtents(Dali::Accessibility::CoordinateType::WINDOW); + + currentPosition.x = rect.x; + currentPosition.y = rect.y; + + rect.x = rect.x > parentRect.x ? rect.x : parentRect.x; + rect.y = rect.y > parentRect.y ? rect.y : parentRect.y; + rect.width = currentPosition.x + rect.width < parentRect.x + parentRect.width ? currentPosition.x + rect.width - rect.x : parentRect.x + parentRect.width - rect.x; + rect.height = currentPosition.y + rect.height < parentRect.y + parentRect.height ? currentPosition.y + rect.height - rect.y : parentRect.y + parentRect.height - rect.y; + + if(rect.width < 0 || rect.height < 0) + { + return rect; + } + + parent = dynamic_cast(parent->GetParent()); + } + + return rect; +} + +static bool IsShowingGeometryOnScreen(Dali::Rect<> rect) +{ + return rect.width > 0 && rect.height > 0; +} + +Dali::Accessibility::Accessible* ExternalAccessibleGetter(Dali::Actor actor) +{ + auto control = Toolkit::Control::DownCast(actor); + if(!control) + { + return nullptr; + } + + auto& controlImpl = Toolkit::Internal::GetImplementation(control); + + return controlImpl.GetAccessibleObject(); +} + } // unnamed namespace // clang-format off @@ -414,13 +475,18 @@ const PropertyRegistration Control::Impl::PROPERTY_12(typeRegistration, "rightFo const PropertyRegistration Control::Impl::PROPERTY_13(typeRegistration, "upFocusableActorId", Toolkit::DevelControl::Property::UP_FOCUSABLE_ACTOR_ID, Property::INTEGER, &Control::Impl::SetProperty, &Control::Impl::GetProperty); const PropertyRegistration Control::Impl::PROPERTY_14(typeRegistration, "downFocusableActorId", Toolkit::DevelControl::Property::DOWN_FOCUSABLE_ACTOR_ID, Property::INTEGER, &Control::Impl::SetProperty, &Control::Impl::GetProperty); const PropertyRegistration Control::Impl::PROPERTY_15(typeRegistration, "shadow", Toolkit::DevelControl::Property::SHADOW, Property::MAP, &Control::Impl::SetProperty, &Control::Impl::GetProperty); -const PropertyRegistration Control::Impl::PROPERTY_16(typeRegistration, "accessibilityAttributes", Toolkit::DevelControl::Property::ACCESSIBILITY_ATTRIBUTES, Property::MAP, &Control::Impl::SetProperty, &Control::Impl::GetProperty); -const PropertyRegistration Control::Impl::PROPERTY_17(typeRegistration, "accessibilityName", Toolkit::DevelControl::Property::ACCESSIBILITY_NAME, Property::STRING, &Control::Impl::SetProperty, &Control::Impl::GetProperty); -const PropertyRegistration Control::Impl::PROPERTY_18(typeRegistration, "accessibilityDescription", Toolkit::DevelControl::Property::ACCESSIBILITY_DESCRIPTION, Property::STRING, &Control::Impl::SetProperty, &Control::Impl::GetProperty); -const PropertyRegistration Control::Impl::PROPERTY_19(typeRegistration, "accessibilityTranslationDomain", Toolkit::DevelControl::Property::ACCESSIBILITY_TRANSLATION_DOMAIN, Property::STRING, &Control::Impl::SetProperty, &Control::Impl::GetProperty); -const PropertyRegistration Control::Impl::PROPERTY_20(typeRegistration, "accessibilityRole", Toolkit::DevelControl::Property::ACCESSIBILITY_ROLE, Property::INTEGER, &Control::Impl::SetProperty, &Control::Impl::GetProperty); -const PropertyRegistration Control::Impl::PROPERTY_21(typeRegistration, "accessibilityHighlightable", Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE, Property::BOOLEAN, &Control::Impl::SetProperty, &Control::Impl::GetProperty); -const PropertyRegistration Control::Impl::PROPERTY_22(typeRegistration, "accessibilityAnimated", Toolkit::DevelControl::Property::ACCESSIBILITY_ANIMATED, Property::BOOLEAN, &Control::Impl::SetProperty, &Control::Impl::GetProperty); +const PropertyRegistration Control::Impl::PROPERTY_16(typeRegistration, "accessibilityName", Toolkit::DevelControl::Property::ACCESSIBILITY_NAME, Property::STRING, &Control::Impl::SetProperty, &Control::Impl::GetProperty); +const PropertyRegistration Control::Impl::PROPERTY_17(typeRegistration, "accessibilityDescription", Toolkit::DevelControl::Property::ACCESSIBILITY_DESCRIPTION, Property::STRING, &Control::Impl::SetProperty, &Control::Impl::GetProperty); +const PropertyRegistration Control::Impl::PROPERTY_18(typeRegistration, "accessibilityTranslationDomain", Toolkit::DevelControl::Property::ACCESSIBILITY_TRANSLATION_DOMAIN, Property::STRING, &Control::Impl::SetProperty, &Control::Impl::GetProperty); +const PropertyRegistration Control::Impl::PROPERTY_19(typeRegistration, "accessibilityRole", Toolkit::DevelControl::Property::ACCESSIBILITY_ROLE, Property::INTEGER, &Control::Impl::SetProperty, &Control::Impl::GetProperty); +const PropertyRegistration Control::Impl::PROPERTY_20(typeRegistration, "accessibilityHighlightable", Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE, Property::BOOLEAN, &Control::Impl::SetProperty, &Control::Impl::GetProperty); +const PropertyRegistration Control::Impl::PROPERTY_21(typeRegistration, "accessibilityAttributes", Toolkit::DevelControl::Property::ACCESSIBILITY_ATTRIBUTES, Property::MAP, &Control::Impl::SetProperty, &Control::Impl::GetProperty); +const PropertyRegistration Control::Impl::PROPERTY_22(typeRegistration, "dispatchKeyEvents", Toolkit::DevelControl::Property::DISPATCH_KEY_EVENTS, Property::BOOLEAN, &Control::Impl::SetProperty, &Control::Impl::GetProperty); +const PropertyRegistration Control::Impl::PROPERTY_23(typeRegistration, "accessibilityHidden", Toolkit::DevelControl::Property::ACCESSIBILITY_HIDDEN, Property::BOOLEAN, &Control::Impl::SetProperty, &Control::Impl::GetProperty); +const PropertyRegistration Control::Impl::PROPERTY_24(typeRegistration, "clockwiseFocusableActorId", Toolkit::DevelControl::Property::CLOCKWISE_FOCUSABLE_ACTOR_ID, Property::INTEGER, &Control::Impl::SetProperty, &Control::Impl::GetProperty); +const PropertyRegistration Control::Impl::PROPERTY_25(typeRegistration, "counterClockwiseFocusableActorId", Toolkit::DevelControl::Property::COUNTER_CLOCKWISE_FOCUSABLE_ACTOR_ID, Property::INTEGER, &Control::Impl::SetProperty, &Control::Impl::GetProperty); +const PropertyRegistration Control::Impl::PROPERTY_26(typeRegistration, "automationId", Toolkit::DevelControl::Property::AUTOMATION_ID, Property::STRING, &Control::Impl::SetProperty, &Control::Impl::GetProperty); + // clang-format on Control::Impl::Impl(Control& controlImpl) @@ -431,6 +497,8 @@ Control::Impl::Impl(Control& controlImpl) mRightFocusableActorId(-1), mUpFocusableActorId(-1), mDownFocusableActorId(-1), + mClockwiseFocusableActorId(-1), + mCounterClockwiseFocusableActorId(-1), mStyleName(""), mBackgroundColor(Color::TRANSPARENT), mStartingPinchScale(nullptr), @@ -455,24 +523,10 @@ Control::Impl::Impl(Control& controlImpl) mIsKeyboardNavigationSupported(false), mIsKeyboardFocusGroup(false), mIsEmittingResourceReadySignal(false), - mNeedToEmitResourceReady(false) + mNeedToEmitResourceReady(false), + mDispatchKeyEvents(true) { - Dali::Accessibility::Accessible::RegisterControlAccessibilityGetter( - [](Dali::Actor actor) -> Dali::Accessibility::Accessible* { - return Control::Impl::GetAccessibilityObject(actor); - }); - - accessibilityConstructor = [](Dali::Actor actor) -> std::unique_ptr { - return std::unique_ptr(new AccessibleImpl(actor, - Dali::Accessibility::Role::UNKNOWN)); - }; - - size_t len = static_cast(Dali::Accessibility::RelationType::MAX_COUNT); - mAccessibilityRelations.reserve(len); - for(auto i = 0u; i < len; ++i) - { - mAccessibilityRelations.push_back({}); - } + Dali::Accessibility::Accessible::RegisterExternalAccessibleGetter(&ExternalAccessibleGetter); } Control::Impl::~Impl() @@ -487,7 +541,6 @@ Control::Impl::~Impl() StopObservingVisual(iter->visual); } - AccessibilityDeregister(); // All gesture detectors will be destroyed so no need to disconnect. delete mStartingPinchScale; @@ -508,6 +561,84 @@ const Control::Impl& Control::Impl::Get(const Internal::Control& internalControl return *internalControl.mImpl; } +void Control::Impl::CheckHighlightedObjectGeometry() +{ + auto accessible = GetAccessibleObject(); + auto lastPosition = accessible->GetLastPosition(); + auto accessibleRect = accessible->GetExtents(Dali::Accessibility::CoordinateType::WINDOW); + auto rect = GetShowingGeometry(accessibleRect, accessible); + + switch(mAccessibilityLastScreenRelativeMoveType) + { + case Dali::Accessibility::ScreenRelativeMoveType::OUTSIDE: + { + if(IsShowingGeometryOnScreen(rect)) + { + mAccessibilityLastScreenRelativeMoveType = Dali::Accessibility::ScreenRelativeMoveType::INSIDE; + } + break; + } + case Dali::Accessibility::ScreenRelativeMoveType::INSIDE: + { + if(rect.width < 0 && accessibleRect.x != lastPosition.x) + { + mAccessibilityLastScreenRelativeMoveType = (accessibleRect.x < lastPosition.x) ? Dali::Accessibility::ScreenRelativeMoveType::OUTGOING_TOP_LEFT : Dali::Accessibility::ScreenRelativeMoveType::OUTGOING_BOTTOM_RIGHT; + } + if(rect.height < 0 && accessibleRect.y != lastPosition.y) + { + mAccessibilityLastScreenRelativeMoveType = (accessibleRect.y < lastPosition.y) ? Dali::Accessibility::ScreenRelativeMoveType::OUTGOING_TOP_LEFT : Dali::Accessibility::ScreenRelativeMoveType::OUTGOING_BOTTOM_RIGHT; + } + // notify AT-clients on outgoing moves only + if(mAccessibilityLastScreenRelativeMoveType != Dali::Accessibility::ScreenRelativeMoveType::INSIDE) + { + accessible->EmitMovedOutOfScreen(mAccessibilityLastScreenRelativeMoveType); + } + break; + } + case Dali::Accessibility::ScreenRelativeMoveType::OUTGOING_TOP_LEFT: + case Dali::Accessibility::ScreenRelativeMoveType::OUTGOING_BOTTOM_RIGHT: + { + if(IsShowingGeometryOnScreen(rect)) + { + mAccessibilityLastScreenRelativeMoveType = Dali::Accessibility::ScreenRelativeMoveType::INSIDE; + } + else + { + mAccessibilityLastScreenRelativeMoveType = Dali::Accessibility::ScreenRelativeMoveType::OUTSIDE; + } + break; + } + default: + { + break; + } + } + + accessible->SetLastPosition(Vector2(accessibleRect.x, accessibleRect.y)); +} + +void Control::Impl::RegisterAccessibilityPositionPropertyNotification() +{ + if(mIsAccessibilityPositionPropertyNotificationSet) + { + return; + } + // set default value until first move of object is detected + mAccessibilityLastScreenRelativeMoveType = Dali::Accessibility::ScreenRelativeMoveType::OUTSIDE; + // recalculate mAccessibilityLastScreenRelativeMoveType accordingly to the initial position + CheckHighlightedObjectGeometry(); + mAccessibilityPositionNotification = mControlImpl.Self().AddPropertyNotification(Actor::Property::WORLD_POSITION, StepCondition(1.0f, 1.0f)); + mAccessibilityPositionNotification.SetNotifyMode(PropertyNotification::NOTIFY_ON_CHANGED); + mAccessibilityPositionNotification.NotifySignal().Connect(this, [this](PropertyNotification&) { CheckHighlightedObjectGeometry(); }); + mIsAccessibilityPositionPropertyNotificationSet = true; +} + +void Control::Impl::UnregisterAccessibilityPositionPropertyNotification() +{ + mControlImpl.Self().RemovePropertyNotification(mAccessibilityPositionNotification); + mIsAccessibilityPositionPropertyNotificationSet = false; +} + // Gesture Detection Methods void Control::Impl::PinchDetected(Actor actor, const PinchGesture& pinch) { @@ -837,6 +968,11 @@ void Control::Impl::NotifyVisualEvent(Visual::Base& object, Property::Index sign } } +void Control::Impl::RelayoutRequest(Visual::Base& object) +{ + mControlImpl.RelayoutRequest(); +} + bool Control::Impl::IsResourceReady() const { // Iterate through and check all the enabled visuals are ready @@ -960,11 +1096,19 @@ void Control::Impl::DoAction(Dali::Property::Index visualIndex, Dali::Property:: } } -void Control::Impl::AppendAccessibilityAttribute(const std::string& key, - const std::string value) +void Control::Impl::DoActionExtension(Dali::Property::Index visualIndex, Dali::Property::Index actionId, Dali::Any attributes) +{ + RegisteredVisualContainer::Iterator iter; + if(FindVisual(visualIndex, mVisuals, iter)) + { + Toolkit::GetImplementation((*iter)->visual).DoActionExtension(actionId, attributes); + } +} + +void Control::Impl::AppendAccessibilityAttribute(const std::string& key, const std::string value) { - Property::Value* val = mAccessibilityAttributes.Find(key); - if(val) + Property::Value* checkedValue = mAccessibilityAttributes.Find(key); + if(checkedValue) { mAccessibilityAttributes[key] = Property::Value(value); } @@ -1047,76 +1191,6 @@ void Control::Impl::SetProperty(BaseObject* object, Property::Index index, const } break; - case Toolkit::DevelControl::Property::ACCESSIBILITY_NAME: - { - std::string name; - if(value.Get(name)) - { - controlImpl.mImpl->mAccessibilityName = name; - controlImpl.mImpl->mAccessibilityNameSet = true; - } - else - { - controlImpl.mImpl->mAccessibilityNameSet = false; - } - } - break; - - case Toolkit::DevelControl::Property::ACCESSIBILITY_DESCRIPTION: - { - std::string txt; - if(value.Get(txt)) - { - controlImpl.mImpl->mAccessibilityDescription = txt; - controlImpl.mImpl->mAccessibilityDescriptionSet = true; - } - else - { - controlImpl.mImpl->mAccessibilityDescriptionSet = false; - } - } - break; - - case Toolkit::DevelControl::Property::ACCESSIBILITY_TRANSLATION_DOMAIN: - { - std::string txt; - if(value.Get(txt)) - { - controlImpl.mImpl->mAccessibilityTranslationDomain = txt; - controlImpl.mImpl->mAccessibilityTranslationDomainSet = true; - } - else - { - controlImpl.mImpl->mAccessibilityTranslationDomainSet = false; - } - } - break; - - case Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE: - { - bool highlightable; - if(value.Get(highlightable)) - { - controlImpl.mImpl->mAccessibilityHighlightable = highlightable; - controlImpl.mImpl->mAccessibilityHighlightableSet = true; - } - else - { - controlImpl.mImpl->mAccessibilityHighlightableSet = false; - } - } - break; - - case Toolkit::DevelControl::Property::ACCESSIBILITY_ROLE: - { - Dali::Accessibility::Role val; - if(value.Get(val)) - { - controlImpl.mImpl->mAccessibilityRole = val; - } - } - break; - case Toolkit::DevelControl::Property::UP_FOCUSABLE_ACTOR_ID: { int focusId; @@ -1226,6 +1300,56 @@ void Control::Impl::SetProperty(BaseObject* object, Property::Index index, const break; } + case Toolkit::DevelControl::Property::ACCESSIBILITY_NAME: + { + std::string name; + if(value.Get(name)) + { + controlImpl.mImpl->mAccessibilityName = name; + } + break; + } + + case Toolkit::DevelControl::Property::ACCESSIBILITY_DESCRIPTION: + { + std::string text; + if(value.Get(text)) + { + controlImpl.mImpl->mAccessibilityDescription = text; + } + break; + } + + case Toolkit::DevelControl::Property::ACCESSIBILITY_TRANSLATION_DOMAIN: + { + std::string text; + if(value.Get(text)) + { + controlImpl.mImpl->mAccessibilityTranslationDomain = text; + } + break; + } + + case Toolkit::DevelControl::Property::ACCESSIBILITY_ROLE: + { + Dali::Accessibility::Role role; + if(value.Get(role)) + { + controlImpl.mImpl->mAccessibilityRole = role; + } + break; + } + + case Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE: + { + bool highlightable; + if(value.Get(highlightable)) + { + controlImpl.mImpl->mAccessibilityHighlightable = highlightable; + } + break; + } + case Toolkit::DevelControl::Property::ACCESSIBILITY_ATTRIBUTES: { const Property::Map* map = value.GetMap(); @@ -1236,12 +1360,57 @@ void Control::Impl::SetProperty(BaseObject* object, Property::Index index, const break; } - case Toolkit::DevelControl::Property::ACCESSIBILITY_ANIMATED: + case Toolkit::DevelControl::Property::DISPATCH_KEY_EVENTS: { - bool animated; - if(value.Get(animated)) + bool dispatch; + if(value.Get(dispatch)) { - controlImpl.mImpl->mAccessibilityAnimated = animated; + controlImpl.mImpl->mDispatchKeyEvents = dispatch; + } + break; + } + + case Toolkit::DevelControl::Property::ACCESSIBILITY_HIDDEN: + { + bool hidden; + if(value.Get(hidden)) + { + controlImpl.mImpl->mAccessibilityHidden = hidden; + + auto* accessible = controlImpl.GetAccessibleObject(); + auto* parent = dynamic_cast(accessible->GetParent()); + if(parent) + { + parent->OnChildrenChanged(); + } + } + break; + } + case Toolkit::DevelControl::Property::CLOCKWISE_FOCUSABLE_ACTOR_ID: + { + int focusId; + if(value.Get(focusId)) + { + controlImpl.mImpl->mClockwiseFocusableActorId = focusId; + } + break; + } + case Toolkit::DevelControl::Property::COUNTER_CLOCKWISE_FOCUSABLE_ACTOR_ID: + { + int focusId; + if(value.Get(focusId)) + { + controlImpl.mImpl->mCounterClockwiseFocusableActorId = focusId; + } + break; + } + + case Toolkit::DevelControl::Property::AUTOMATION_ID: + { + std::string automationId; + if(value.Get(automationId)) + { + controlImpl.mImpl->mAutomationId = automationId; } break; } @@ -1291,48 +1460,6 @@ Property::Value Control::Impl::GetProperty(BaseObject* object, Property::Index i break; } - case Toolkit::DevelControl::Property::ACCESSIBILITY_NAME: - { - if(controlImpl.mImpl->mAccessibilityNameSet) - { - value = controlImpl.mImpl->mAccessibilityName; - } - break; - } - - case Toolkit::DevelControl::Property::ACCESSIBILITY_DESCRIPTION: - { - if(controlImpl.mImpl->mAccessibilityDescriptionSet) - { - value = controlImpl.mImpl->mAccessibilityDescription; - } - break; - } - - case Toolkit::DevelControl::Property::ACCESSIBILITY_TRANSLATION_DOMAIN: - { - if(controlImpl.mImpl->mAccessibilityTranslationDomainSet) - { - value = controlImpl.mImpl->mAccessibilityTranslationDomain; - } - break; - } - - case Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE: - { - if(controlImpl.mImpl->mAccessibilityHighlightableSet) - { - value = controlImpl.mImpl->mAccessibilityHighlightable; - } - break; - } - - case Toolkit::DevelControl::Property::ACCESSIBILITY_ROLE: - { - value = Property::Value(controlImpl.mImpl->mAccessibilityRole); - break; - } - case Toolkit::DevelControl::Property::UP_FOCUSABLE_ACTOR_ID: { value = controlImpl.mImpl->mUpFocusableActorId; @@ -1400,15 +1527,69 @@ Property::Value Control::Impl::GetProperty(BaseObject* object, Property::Index i break; } + case Toolkit::DevelControl::Property::ACCESSIBILITY_NAME: + { + value = controlImpl.mImpl->mAccessibilityName; + break; + } + + case Toolkit::DevelControl::Property::ACCESSIBILITY_DESCRIPTION: + { + value = controlImpl.mImpl->mAccessibilityDescription; + break; + } + + case Toolkit::DevelControl::Property::ACCESSIBILITY_TRANSLATION_DOMAIN: + { + value = controlImpl.mImpl->mAccessibilityTranslationDomain; + break; + } + + case Toolkit::DevelControl::Property::ACCESSIBILITY_ROLE: + { + value = Property::Value(controlImpl.mImpl->mAccessibilityRole); + break; + } + + case Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE: + { + value = controlImpl.mImpl->mAccessibilityHighlightable; + break; + } + case Toolkit::DevelControl::Property::ACCESSIBILITY_ATTRIBUTES: { value = controlImpl.mImpl->mAccessibilityAttributes; break; } - case Toolkit::DevelControl::Property::ACCESSIBILITY_ANIMATED: + case Toolkit::DevelControl::Property::DISPATCH_KEY_EVENTS: + { + value = controlImpl.mImpl->mDispatchKeyEvents; + break; + } + + case Toolkit::DevelControl::Property::ACCESSIBILITY_HIDDEN: + { + value = controlImpl.mImpl->mAccessibilityHidden; + break; + } + + case Toolkit::DevelControl::Property::CLOCKWISE_FOCUSABLE_ACTOR_ID: + { + value = controlImpl.mImpl->mClockwiseFocusableActorId; + break; + } + + case Toolkit::DevelControl::Property::COUNTER_CLOCKWISE_FOCUSABLE_ACTOR_ID: + { + value = controlImpl.mImpl->mCounterClockwiseFocusableActorId; + break; + } + + case Toolkit::DevelControl::Property::AUTOMATION_ID: { - value = controlImpl.mImpl->mAccessibilityAnimated; + value = controlImpl.mImpl->mAutomationId; break; } } @@ -1419,9 +1600,11 @@ Property::Value Control::Impl::GetProperty(BaseObject* object, Property::Index i void Control::Impl::RemoveAccessibilityAttribute(const std::string& key) { - Property::Value* val = mAccessibilityAttributes.Find(key); - if(val) + Property::Value* value = mAccessibilityAttributes.Find(key); + if(value) + { mAccessibilityAttributes[key] = Property::Value(); + } } void Control::Impl::ClearAccessibilityAttributes() @@ -1431,7 +1614,7 @@ void Control::Impl::ClearAccessibilityAttributes() void Control::Impl::SetAccessibilityReadingInfoType(const Dali::Accessibility::ReadingInfoTypes types) { - std::string value; + std::string value{}; if(types[Dali::Accessibility::ReadingInfoType::NAME]) { value += READING_INFO_TYPE_NAME; @@ -1465,12 +1648,21 @@ void Control::Impl::SetAccessibilityReadingInfoType(const Dali::Accessibility::R Dali::Accessibility::ReadingInfoTypes Control::Impl::GetAccessibilityReadingInfoType() const { - std::string value; + std::string value{}; auto place = mAccessibilityAttributes.Find(READING_INFO_TYPE_ATTRIBUTE_NAME); if(place) { place->Get(value); } + else + { + Dali::Accessibility::ReadingInfoTypes types; + types[Dali::Accessibility::ReadingInfoType::NAME] = true; + types[Dali::Accessibility::ReadingInfoType::ROLE] = true; + types[Dali::Accessibility::ReadingInfoType::DESCRIPTION] = true; + types[Dali::Accessibility::ReadingInfoType::STATE] = true; + return types; + } if(value.empty()) { @@ -1830,6 +2022,49 @@ Dali::Property Control::Impl::GetVisualProperty(Dali::Property::Index index, Dal return Dali::Property(handle, Property::INVALID_INDEX); } +void Control::Impl::CreateTransitions(std::vector>& sourceProperties, + std::vector>& destinationProperties, + Dali::Toolkit::Control source, + Dali::Toolkit::Control destination) +{ + // Retrieves background properties to be transitioned. + Dali::Property::Map backgroundSourcePropertyMap, backgroundDestinationPropertyMap; + mControlImpl.MakeVisualTransition(backgroundSourcePropertyMap, backgroundDestinationPropertyMap, source, destination, Toolkit::Control::Property::BACKGROUND); + if(backgroundSourcePropertyMap.Count() > 0) + { + sourceProperties.push_back(std::pair(Toolkit::Control::Property::BACKGROUND, backgroundSourcePropertyMap)); + destinationProperties.push_back(std::pair(Toolkit::Control::Property::BACKGROUND, backgroundDestinationPropertyMap)); + } + + // Retrieves shadow properties to be transitioned. + Dali::Property::Map shadowSourcePropertyMap, shadowDestinationPropertyMap; + mControlImpl.MakeVisualTransition(shadowSourcePropertyMap, shadowDestinationPropertyMap, source, destination, Toolkit::DevelControl::Property::SHADOW); + if(shadowSourcePropertyMap.Count() > 0) + { + sourceProperties.push_back(std::pair(Toolkit::DevelControl::Property::SHADOW, shadowSourcePropertyMap)); + destinationProperties.push_back(std::pair(Toolkit::DevelControl::Property::SHADOW, shadowDestinationPropertyMap)); + } + + // Retrieves transition from inherited class. + mControlImpl.OnCreateTransitions(sourceProperties, destinationProperties, source, destination); +} + +void Control::Impl::UpdateVisualProperties(const std::vector>& properties) +{ + for(auto&& data : properties) + { + if(data.first == Toolkit::Control::Property::BACKGROUND) + { + DoAction(Toolkit::Control::Property::BACKGROUND, DevelVisual::Action::UPDATE_PROPERTY, data.second); + } + else if(data.first == Toolkit::DevelControl::Property::SHADOW) + { + DoAction(Toolkit::DevelControl::Property::SHADOW, DevelVisual::Action::UPDATE_PROPERTY, data.second); + } + } + mControlImpl.OnUpdateVisualProperties(properties); +} + void Control::Impl::EmitResourceReadySignal() { if(!mIsEmittingResourceReadySignal) @@ -1882,456 +2117,14 @@ void Control::Impl::OnIdleCallback() mIdleCallback = nullptr; } -Dali::Accessibility::Accessible* Control::Impl::GetAccessibilityObject() -{ - if(!accessibilityObject) - accessibilityObject = accessibilityConstructor(mControlImpl.Self()); - return accessibilityObject.get(); -} - -Dali::Accessibility::Accessible* Control::Impl::GetAccessibilityObject(Dali::Actor actor) -{ - if(actor) - { - auto q = Dali::Toolkit::Control::DownCast(actor); - if(q) - { - auto q2 = static_cast(&q.GetImplementation()); - return q2->mImpl->GetAccessibilityObject(); - } - } - return nullptr; -} - -Control::Impl::AccessibleImpl::AccessibleImpl(Dali::Actor self, Dali::Accessibility::Role role, bool modal) -: self(self), - modal(modal) -{ - auto control = Dali::Toolkit::Control::DownCast(self); - - Internal::Control& internalControl = Toolkit::Internal::GetImplementation(control); - Internal::Control::Impl& controlImpl = Internal::Control::Impl::Get(internalControl); - if(controlImpl.mAccessibilityRole == Dali::Accessibility::Role::UNKNOWN) - controlImpl.mAccessibilityRole = role; - - self.PropertySetSignal().Connect(&controlImpl, [this, &controlImpl](Dali::Handle& handle, Dali::Property::Index index, Dali::Property::Value value) { - if(this->self != Dali::Accessibility::Accessible::GetCurrentlyHighlightedActor()) - { - return; - } - - if(index == DevelControl::Property::ACCESSIBILITY_NAME || (index == GetNamePropertyIndex() && !controlImpl.mAccessibilityNameSet)) - { - if(controlImpl.mAccessibilityGetNameSignal.Empty()) - { - Emit(Dali::Accessibility::ObjectPropertyChangeEvent::NAME); - } - } - - if(index == DevelControl::Property::ACCESSIBILITY_DESCRIPTION || (index == GetDescriptionPropertyIndex() && !controlImpl.mAccessibilityDescriptionSet)) - { - if(controlImpl.mAccessibilityGetDescriptionSignal.Empty()) - { - Emit(Dali::Accessibility::ObjectPropertyChangeEvent::DESCRIPTION); - } - } - }); -} - -std::string Control::Impl::AccessibleImpl::GetName() -{ - auto control = Dali::Toolkit::Control::DownCast(self); - - Internal::Control& internalControl = Toolkit::Internal::GetImplementation(control); - Internal::Control::Impl& controlImpl = Internal::Control::Impl::Get(internalControl); - - if(!controlImpl.mAccessibilityGetNameSignal.Empty()) - { - std::string ret; - controlImpl.mAccessibilityGetNameSignal.Emit(ret); - return ret; - } - - if(controlImpl.mAccessibilityNameSet) - return controlImpl.mAccessibilityName; - - if(auto raw = GetNameRaw(); !raw.empty()) - return raw; - - return self.GetProperty(Actor::Property::NAME); -} - -std::string Control::Impl::AccessibleImpl::GetNameRaw() -{ - return {}; -} - -std::string Control::Impl::AccessibleImpl::GetDescription() -{ - auto control = Dali::Toolkit::Control::DownCast(self); - - Internal::Control& internalControl = Toolkit::Internal::GetImplementation(control); - Internal::Control::Impl& controlImpl = Internal::Control::Impl::Get(internalControl); - - if(!controlImpl.mAccessibilityGetDescriptionSignal.Empty()) - { - std::string ret; - controlImpl.mAccessibilityGetDescriptionSignal.Emit(ret); - return ret; - } - - if(controlImpl.mAccessibilityDescriptionSet) - return controlImpl.mAccessibilityDescription; - - return GetDescriptionRaw(); -} - -std::string Control::Impl::AccessibleImpl::GetDescriptionRaw() -{ - return ""; -} - -Dali::Accessibility::Accessible* Control::Impl::AccessibleImpl::GetParent() -{ - return Dali::Accessibility::Accessible::Get(self.GetParent()); -} - -size_t Control::Impl::AccessibleImpl::GetChildCount() -{ - return self.GetChildCount(); -} - -Dali::Accessibility::Accessible* Control::Impl::AccessibleImpl::GetChildAtIndex(size_t index) -{ - return Dali::Accessibility::Accessible::Get(self.GetChildAt(static_cast(index))); -} - -size_t Control::Impl::AccessibleImpl::GetIndexInParent() -{ - auto s = self; - auto parent = s.GetParent(); - DALI_ASSERT_ALWAYS(parent && "can't call GetIndexInParent on object without parent"); - auto count = parent.GetChildCount(); - for(auto i = 0u; i < count; ++i) - { - auto c = parent.GetChildAt(i); - if(c == s) - return i; - } - DALI_ASSERT_ALWAYS(false && "object isn't child of it's parent"); - return static_cast(-1); -} - -Dali::Accessibility::Role Control::Impl::AccessibleImpl::GetRole() -{ - return self.GetProperty(Toolkit::DevelControl::Property::ACCESSIBILITY_ROLE); -} - -Dali::Accessibility::States Control::Impl::AccessibleImpl::CalculateStates() -{ - Dali::Accessibility::States s; - s[Dali::Accessibility::State::FOCUSABLE] = self.GetProperty(Actor::Property::KEYBOARD_FOCUSABLE); - s[Dali::Accessibility::State::FOCUSED] = Toolkit::KeyboardFocusManager::Get().GetCurrentFocusActor() == self; - if(self.GetProperty(Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE).GetType() == Property::NONE) - s[Dali::Accessibility::State::HIGHLIGHTABLE] = false; - else - s[Dali::Accessibility::State::HIGHLIGHTABLE] = self.GetProperty(Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE).Get(); - s[Dali::Accessibility::State::HIGHLIGHTED] = GetCurrentlyHighlightedActor() == self; - s[Dali::Accessibility::State::ENABLED] = true; - s[Dali::Accessibility::State::SENSITIVE] = true; - s[Dali::Accessibility::State::ANIMATED] = self.GetProperty(Toolkit::DevelControl::Property::ACCESSIBILITY_ANIMATED).Get(); - s[Dali::Accessibility::State::VISIBLE] = true; - if(modal) - { - s[Dali::Accessibility::State::MODAL] = true; - } - s[Dali::Accessibility::State::SHOWING] = !self.GetProperty(Dali::DevelActor::Property::CULLED).Get() && self.GetCurrentProperty(Actor::Property::VISIBLE); - - s[Dali::Accessibility::State::DEFUNCT] = !self.GetProperty(Dali::DevelActor::Property::CONNECTED_TO_SCENE).Get(); - return s; -} - -Dali::Accessibility::States Control::Impl::AccessibleImpl::GetStates() -{ - return CalculateStates(); -} - -Dali::Accessibility::Attributes Control::Impl::AccessibleImpl::GetAttributes() -{ - std::unordered_map attribute_map; - auto q = Dali::Toolkit::Control::DownCast(self); - auto w = - q.GetProperty(Dali::Toolkit::DevelControl::Property::ACCESSIBILITY_ATTRIBUTES); - auto z = w.GetMap(); - - if(z) - { - auto map_size = z->Count(); - - for(unsigned int i = 0; i < map_size; i++) - { - auto map_key = z->GetKeyAt(i); - if(map_key.type == Property::Key::STRING) - { - std::string map_value; - if(z->GetValue(i).Get(map_value)) - { - attribute_map.emplace(std::move(map_key.stringKey), - std::move(map_value)); - } - } - } - } - - return attribute_map; -} - -Dali::Accessibility::ComponentLayer Control::Impl::AccessibleImpl::GetLayer() -{ - return Dali::Accessibility::ComponentLayer::WINDOW; -} - -Dali::Rect<> Control::Impl::AccessibleImpl::GetExtents(Dali::Accessibility::CoordType ctype) -{ - Vector2 screenPosition = - self.GetProperty(Dali::DevelActor::Property::SCREEN_POSITION) - .Get(); - auto size = self.GetCurrentProperty(Actor::Property::SIZE) * self.GetCurrentProperty(Actor::Property::WORLD_SCALE); - bool positionUsesAnchorPoint = - self.GetProperty(Dali::DevelActor::Property::POSITION_USES_ANCHOR_POINT) - .Get(); - Vector3 anchorPointOffSet = - size * (positionUsesAnchorPoint ? self.GetCurrentProperty(Actor::Property::ANCHOR_POINT) - : AnchorPoint::TOP_LEFT); - Vector2 position = Vector2(screenPosition.x - anchorPointOffSet.x, - screenPosition.y - anchorPointOffSet.y); - - return {position.x, position.y, size.x, size.y}; -} - -int16_t Control::Impl::AccessibleImpl::GetMdiZOrder() +Toolkit::DevelControl::ControlAccessible* Control::Impl::GetAccessibleObject() { - return 0; -} -double Control::Impl::AccessibleImpl::GetAlpha() -{ - return 0; -} - -bool Control::Impl::AccessibleImpl::GrabFocus() -{ - return Toolkit::KeyboardFocusManager::Get().SetCurrentFocusActor(self); -} - -static Dali::Actor CreateHighlightIndicatorActor() -{ - std::string focusBorderImagePath(AssetManager::GetDaliImagePath()); - focusBorderImagePath += "/keyboard_focus.9.png"; - // Create the default if it hasn't been set and one that's shared by all the - // keyboard focusable actors - auto actor = Toolkit::ImageView::New(focusBorderImagePath); - actor.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS); - DevelControl::AppendAccessibilityAttribute(actor, "highlight", ""); - actor.SetProperty(Toolkit::DevelControl::Property::ACCESSIBILITY_ANIMATED, true); - actor.SetProperty(Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE, false); - - return actor; -} - -bool Control::Impl::AccessibleImpl::GrabHighlight() -{ - auto old = GetCurrentlyHighlightedActor(); - - if(!Dali::Accessibility::IsUp()) - return false; - if(self == old) - return true; - if(old) - { - auto c = dynamic_cast(GetAccessibilityObject(old)); - if(c) - c->ClearHighlight(); - } - auto highlight = GetHighlightActor(); - if(!highlight) - { - highlight = CreateHighlightIndicatorActor(); - SetHighlightActor(highlight); - } - highlight.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER); - highlight.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER); - highlight.SetProperty(Actor::Property::POSITION_Z, 1.0f); - highlight.SetProperty(Actor::Property::POSITION, Vector2(0.0f, 0.0f)); - - EnsureSelfVisible(); - self.Add(highlight); - SetCurrentlyHighlightedActor(self); - EmitHighlighted(true); - - return true; -} - -bool Control::Impl::AccessibleImpl::ClearHighlight() -{ - if(!Dali::Accessibility::IsUp()) - return false; - if(GetCurrentlyHighlightedActor() == self) + if(!mAccessibleObject) { - self.Remove(GetHighlightActor()); - SetCurrentlyHighlightedActor({}); - EmitHighlighted(false); - return true; + mAccessibleObject.reset(mControlImpl.CreateAccessibleObject()); } - return false; -} -std::string Control::Impl::AccessibleImpl::GetActionName(size_t index) -{ - if(index >= GetActionCount()) return ""; - Dali::TypeInfo type; - self.GetTypeInfo(type); - DALI_ASSERT_ALWAYS(type && "no TypeInfo object"); - return type.GetActionName(index); -} -std::string Control::Impl::AccessibleImpl::GetLocalizedActionName(size_t index) -{ - // TODO: add localization - return GetActionName(index); -} -std::string Control::Impl::AccessibleImpl::GetActionDescription(size_t index) -{ - return ""; -} -size_t Control::Impl::AccessibleImpl::GetActionCount() -{ - Dali::TypeInfo type; - self.GetTypeInfo(type); - DALI_ASSERT_ALWAYS(type && "no TypeInfo object"); - return type.GetActionCount(); -} -std::string Control::Impl::AccessibleImpl::GetActionKeyBinding(size_t index) -{ - return ""; -} -bool Control::Impl::AccessibleImpl::DoAction(size_t index) -{ - std::string actionName = GetActionName(index); - return self.DoAction(actionName, {}); -} -bool Control::Impl::AccessibleImpl::DoAction(const std::string& name) -{ - return self.DoAction(name, {}); -} - -bool Control::Impl::AccessibleImpl::DoGesture(const Dali::Accessibility::GestureInfo& gestureInfo) -{ - auto control = Dali::Toolkit::Control::DownCast(self); - - Internal::Control& internalControl = Toolkit::Internal::GetImplementation(control); - Internal::Control::Impl& controlImpl = Internal::Control::Impl::Get(internalControl); - - if(!controlImpl.mAccessibilityDoGestureSignal.Empty()) - { - auto ret = std::make_pair(gestureInfo, false); - controlImpl.mAccessibilityDoGestureSignal.Emit(ret); - return ret.second; - } - - return false; -} - -std::vector Control::Impl::AccessibleImpl::GetRelationSet() -{ - auto control = Dali::Toolkit::Control::DownCast(self); - - Internal::Control& internalControl = Toolkit::Internal::GetImplementation(control); - Internal::Control::Impl& controlImpl = Internal::Control::Impl::Get(internalControl); - - std::vector ret; - - auto& v = controlImpl.mAccessibilityRelations; - for(auto i = 0u; i < v.size(); ++i) - { - if(v[i].empty()) - continue; - - ret.emplace_back(Accessibility::Relation{static_cast(i), v[i]}); - } - - return ret; -} - -void Control::Impl::AccessibleImpl::EnsureChildVisible(Actor child) -{ -} - -void Control::Impl::AccessibleImpl::EnsureSelfVisible() -{ - auto parent = dynamic_cast(GetParent()); - if(parent) - { - parent->EnsureChildVisible(self); - } -} - -Property::Index Control::Impl::AccessibleImpl::GetNamePropertyIndex() -{ - return Actor::Property::NAME; -} - -Property::Index Control::Impl::AccessibleImpl::GetDescriptionPropertyIndex() -{ - return Property::INVALID_INDEX; -} - -void Control::Impl::PositionOrSizeChangedCallback(PropertyNotification& p) -{ - auto self = Dali::Actor::DownCast(p.GetTarget()); - if(Dali::Accessibility::IsUp() && !self.GetProperty(Toolkit::DevelControl::Property::ACCESSIBILITY_ANIMATED).Get()) - { - auto extents = DevelActor::CalculateScreenExtents(self); - Dali::Accessibility::Accessible::Get(self)->EmitBoundsChanged(extents); - } -} - -void Control::Impl::CulledChangedCallback(PropertyNotification& p) -{ - if(Dali::Accessibility::IsUp()) - { - auto self = Dali::Actor::DownCast(p.GetTarget()); - Dali::Accessibility::Accessible::Get(self)->EmitShowing(!self.GetProperty(DevelActor::Property::CULLED).Get()); - } -} - -void Control::Impl::AccessibilityRegister() -{ - if(!accessibilityNotificationSet) - { - accessibilityNotificationPosition = mControlImpl.Self().AddPropertyNotification(Actor::Property::POSITION, StepCondition(0.01f)); - accessibilityNotificationPosition.SetNotifyMode(PropertyNotification::NOTIFY_ON_CHANGED); - accessibilityNotificationPosition.NotifySignal().Connect(&Control::Impl::PositionOrSizeChangedCallback); - - accessibilityNotificationSize = mControlImpl.Self().AddPropertyNotification(Actor::Property::SIZE, StepCondition(0.01f)); - accessibilityNotificationSize.SetNotifyMode(PropertyNotification::NOTIFY_ON_CHANGED); - accessibilityNotificationSize.NotifySignal().Connect(&Control::Impl::PositionOrSizeChangedCallback); - - accessibilityNotificationCulled = mControlImpl.Self().AddPropertyNotification(DevelActor::Property::CULLED, LessThanCondition(0.5f)); - accessibilityNotificationCulled.SetNotifyMode(PropertyNotification::NOTIFY_ON_CHANGED); - accessibilityNotificationCulled.NotifySignal().Connect(&Control::Impl::CulledChangedCallback); - - accessibilityNotificationSet = true; - } -} - -void Control::Impl::AccessibilityDeregister() -{ - if(accessibilityNotificationSet) - { - accessibilityNotificationPosition = {}; - accessibilityNotificationSize = {}; - accessibilityNotificationCulled = {}; - accessibilityNotificationSet = false; - } + return mAccessibleObject.get(); } } // namespace Internal