X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=blobdiff_plain;f=dali-toolkit%2Fdevel-api%2Fcontrols%2Faccessible-impl.cpp;h=1cf9a2697b8ab4d6663d75c1a87d29c15c9d5320;hp=be4735b211ea4e6807930766a375dc90e045fef9;hb=refs%2Fchanges%2F78%2F266578%2F9;hpb=396e6317556d73a06f49b0e26aac8fd6c1866ec2 diff --git a/dali-toolkit/devel-api/controls/accessible-impl.cpp b/dali-toolkit/devel-api/controls/accessible-impl.cpp index be4735b..1cf9a26 100644 --- a/dali-toolkit/devel-api/controls/accessible-impl.cpp +++ b/dali-toolkit/devel-api/controls/accessible-impl.cpp @@ -19,7 +19,12 @@ #include "accessible-impl.h" // EXTERNAL INCLUDES +#ifdef DGETTEXT_ENABLED +#include +#endif + #include +#include // INTERNAL INCLUDES #include @@ -29,21 +34,53 @@ #include #include -namespace Dali::Toolkit::DevelControl { +namespace Dali::Toolkit::DevelControl +{ +namespace +{ +static std::string GetLocaleText(std::string string, const char *domain = "dali-toolkit") +{ +#ifdef DGETTEXT_ENABLED + /*TODO: currently non-localized string is used as a key for translation lookup. In case the lookup key formatting is forced + consider calling utility function for converting non-localized string into well-formatted key before lookup. */ + return dgettext(domain, string.c_str()); +#else + return string; +#endif +} + +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", std::string()); + actor.SetProperty(Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE, false); + + return actor; +} +} // unnamed namespace AccessibleImpl::AccessibleImpl(Dali::Actor self, Dali::Accessibility::Role role, bool modal) -: self(self), - modal(modal) +: mSelf(self), + mIsModal(modal) { - auto control = Dali::Toolkit::Control::DownCast(self); + 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()) + 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; } @@ -68,25 +105,35 @@ AccessibleImpl::AccessibleImpl(Dali::Actor self, Dali::Accessibility::Role role, std::string AccessibleImpl::GetName() { - auto control = Dali::Toolkit::Control::DownCast(self); + auto control = Dali::Toolkit::Control::DownCast(Self()); Internal::Control& internalControl = Toolkit::Internal::GetImplementation(control); Internal::Control::Impl& controlImpl = Internal::Control::Impl::Get(internalControl); + std::string name; if(!controlImpl.mAccessibilityGetNameSignal.Empty()) { - std::string ret; - controlImpl.mAccessibilityGetNameSignal.Emit(ret); - return ret; + controlImpl.mAccessibilityGetNameSignal.Emit(name); + } + else if(controlImpl.mAccessibilityNameSet) + { + name = controlImpl.mAccessibilityName; + } + else if(auto raw = GetNameRaw(); !raw.empty()) + { + name = raw; + } + else + { + name = Self().GetProperty(Actor::Property::NAME); } - if(controlImpl.mAccessibilityNameSet) - return controlImpl.mAccessibilityName; - - if(auto raw = GetNameRaw(); !raw.empty()) - return raw; + if(controlImpl.mAccessibilityTranslationDomainSet) + { + return GetLocaleText(name, controlImpl.mAccessibilityTranslationDomain.c_str()); + } - return self.GetProperty(Actor::Property::NAME); + return GetLocaleText(name); } std::string AccessibleImpl::GetNameRaw() @@ -96,55 +143,66 @@ std::string AccessibleImpl::GetNameRaw() std::string AccessibleImpl::GetDescription() { - auto control = Dali::Toolkit::Control::DownCast(self); + auto control = Dali::Toolkit::Control::DownCast(Self()); Internal::Control& internalControl = Toolkit::Internal::GetImplementation(control); Internal::Control::Impl& controlImpl = Internal::Control::Impl::Get(internalControl); + std::string description; if(!controlImpl.mAccessibilityGetDescriptionSignal.Empty()) { - std::string ret; - controlImpl.mAccessibilityGetDescriptionSignal.Emit(ret); - return ret; + controlImpl.mAccessibilityGetDescriptionSignal.Emit(description); + } + else if(controlImpl.mAccessibilityDescriptionSet) + { + description = controlImpl.mAccessibilityDescription; + } + else + { + description = GetDescriptionRaw(); + } + if(controlImpl.mAccessibilityTranslationDomainSet) + { + return GetLocaleText(description, controlImpl.mAccessibilityTranslationDomain.c_str()); } - if(controlImpl.mAccessibilityDescriptionSet) - return controlImpl.mAccessibilityDescription; - - return GetDescriptionRaw(); + return GetLocaleText(description); } std::string AccessibleImpl::GetDescriptionRaw() { - return ""; + return {}; } Dali::Accessibility::Accessible* AccessibleImpl::GetParent() { - return Dali::Accessibility::Accessible::Get(self.GetParent()); + return Dali::Accessibility::Accessible::Get(Self().GetParent()); } size_t AccessibleImpl::GetChildCount() { - return self.GetChildCount(); + return Self().GetChildCount(); } Dali::Accessibility::Accessible* AccessibleImpl::GetChildAtIndex(size_t index) { - return Dali::Accessibility::Accessible::Get(self.GetChildAt(static_cast(index))); + return Dali::Accessibility::Accessible::Get(Self().GetChildAt(static_cast(index))); } size_t AccessibleImpl::GetIndexInParent() { - auto s = self; - auto parent = s.GetParent(); + auto self = Self(); + auto parent = self.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) + auto child = parent.GetChildAt(i); + if(child == self) + { return i; + } } DALI_ASSERT_ALWAYS(false && "object isn't child of it's parent"); return static_cast(-1); @@ -152,31 +210,77 @@ size_t AccessibleImpl::GetIndexInParent() Dali::Accessibility::Role AccessibleImpl::GetRole() { - return self.GetProperty(Toolkit::DevelControl::Property::ACCESSIBILITY_ROLE); + return Self().GetProperty(Toolkit::DevelControl::Property::ACCESSIBILITY_ROLE); +} + +std::string AccessibleImpl::GetLocalizedRoleName() +{ + return GetLocaleText(GetRoleName()); +} + +bool AccessibleImpl::IsShowing() +{ + Dali::Actor self = Self(); + if(!self.GetProperty(Actor::Property::VISIBLE) || self.GetProperty(Actor::Property::WORLD_COLOR).a == 0 || self.GetProperty(Dali::DevelActor::Property::CULLED)) + { + return false; + } + + auto* child = this; + auto* parent = dynamic_cast(child->GetParent()); + if(!parent) + { + return true; + } + + auto childExtent = child->GetExtents(Dali::Accessibility::CoordinateType::WINDOW); + while(parent) + { + auto control = Dali::Toolkit::Control::DownCast(parent->Self()); + if(!control.GetProperty(Actor::Property::VISIBLE)) + { + return false; + } + auto clipMode = control.GetProperty(Actor::Property::CLIPPING_MODE).Get(); + auto parentExtent = parent->GetExtents(Dali::Accessibility::CoordinateType::WINDOW); + if ((clipMode != ClippingMode::DISABLED) && !parentExtent.Intersects(childExtent)) + { + return false; + } + parent = dynamic_cast(parent->GetParent()); + } + + return true; } Dali::Accessibility::States 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; + Dali::Actor self = Self(); + Dali::Accessibility::States state; + state[Dali::Accessibility::State::FOCUSABLE] = self.GetProperty(Actor::Property::KEYBOARD_FOCUSABLE); + state[Dali::Accessibility::State::FOCUSED] = Toolkit::KeyboardFocusManager::Get().GetCurrentFocusActor() == self; + if(self.GetProperty(Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE).GetType() == Dali::Property::NONE) - s[Dali::Accessibility::State::HIGHLIGHTABLE] = false; + { + state[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; + state[Dali::Accessibility::State::HIGHLIGHTABLE] = self.GetProperty(Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE).Get(); } - 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; + state[Dali::Accessibility::State::HIGHLIGHTED] = GetCurrentlyHighlightedActor() == self; + state[Dali::Accessibility::State::ENABLED] = true; + state[Dali::Accessibility::State::SENSITIVE] = true; + state[Dali::Accessibility::State::VISIBLE] = self.GetProperty(Actor::Property::VISIBLE); + + if(mIsModal) + { + state[Dali::Accessibility::State::MODAL] = true; + } + state[Dali::Accessibility::State::SHOWING] = IsShowing(); + state[Dali::Accessibility::State::DEFUNCT] = !self.GetProperty(Dali::DevelActor::Property::CONNECTED_TO_SCENE).Get(); + return state; } Dali::Accessibility::States AccessibleImpl::GetStates() @@ -186,32 +290,30 @@ Dali::Accessibility::States AccessibleImpl::GetStates() Dali::Accessibility::Attributes 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(); + std::unordered_map attributeMap; + auto control = Dali::Toolkit::Control::DownCast(Self()); + auto attribute = control.GetProperty(Dali::Toolkit::DevelControl::Property::ACCESSIBILITY_ATTRIBUTES); + auto map = attribute.GetMap(); - if(z) + if(map) { - auto map_size = z->Count(); + auto mapSize = map->Count(); - for(unsigned int i = 0; i < map_size; i++) + for(unsigned int i = 0; i < mapSize; i++) { - auto map_key = z->GetKeyAt(i); - if(map_key.type == Dali::Property::Key::STRING) + auto mapKey = map->GetKeyAt(i); + if(mapKey.type == Dali::Property::Key::STRING) { - std::string map_value; - if(z->GetValue(i).Get(map_value)) + std::string mapValue; + if(map->GetValue(i).Get(mapValue)) { - attribute_map.emplace(std::move(map_key.stringKey), - std::move(map_value)); + attributeMap.emplace(std::move(mapKey.stringKey), std::move(mapValue)); } } } } - return attribute_map; + return attributeMap; } Dali::Accessibility::ComponentLayer AccessibleImpl::GetLayer() @@ -219,22 +321,26 @@ Dali::Accessibility::ComponentLayer AccessibleImpl::GetLayer() return Dali::Accessibility::ComponentLayer::WINDOW; } -Dali::Rect<> AccessibleImpl::GetExtents(Dali::Accessibility::CoordType ctype) +Dali::Rect<> AccessibleImpl::GetExtents(Dali::Accessibility::CoordinateType type) { - Vector2 screenPosition = - self.GetProperty(Dali::DevelActor::Property::SCREEN_POSITION) - .Get(); + Dali::Actor self = Self(); + + 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); + 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}; + if(type == Dali::Accessibility::CoordinateType::WINDOW) + { + return {position.x, position.y, size.x, size.y}; + } + else // Dali::Accessibility::CoordinateType::SCREEN + { + auto window = Dali::DevelWindow::Get(self); + auto windowPosition = window.GetPosition(); + return {position.x + windowPosition.GetX(), position.y + windowPosition.GetY(), size.x, size.y}; + } } int16_t AccessibleImpl::GetMdiZOrder() @@ -248,68 +354,108 @@ double AccessibleImpl::GetAlpha() bool AccessibleImpl::GrabFocus() { - return Toolkit::KeyboardFocusManager::Get().SetCurrentFocusActor(self); + return Toolkit::KeyboardFocusManager::Get().SetCurrentFocusActor(Self()); } -static Dali::Actor CreateHighlightIndicatorActor() +void AccessibleImpl::ScrollToSelf() { - 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); + auto* child = this; + auto* parent = dynamic_cast(child->GetParent()); - return actor; + while (parent) + { + if (parent->IsScrollable()) + { + parent->ScrollToChild(child->Self()); + } + + parent = dynamic_cast(parent->GetParent()); + } +} + +void AccessibleImpl::RegisterPositionPropertyNotification() +{ + auto control = Dali::Toolkit::Control::DownCast(Self()); + Internal::Control& internalControl = Toolkit::Internal::GetImplementation(control); + Internal::Control::Impl& controlImpl = Internal::Control::Impl::Get(internalControl); + controlImpl.RegisterAccessibilityPositionPropertyNotification(); +} + +void AccessibleImpl::UnregisterPositionPropertyNotification() +{ + auto control = Dali::Toolkit::Control::DownCast(Self()); + Internal::Control& internalControl = Toolkit::Internal::GetImplementation(control); + Internal::Control::Impl& controlImpl = Internal::Control::Impl::Get(internalControl); + controlImpl.UnregisterAccessibilityPositionPropertyNotification(); } bool AccessibleImpl::GrabHighlight() { - auto old = GetCurrentlyHighlightedActor(); + Dali::Actor self = Self(); + auto oldHighlightedActor = GetCurrentlyHighlightedActor(); if(!Dali::Accessibility::IsUp()) + { return false; - if(self == old) + } + + if(self == oldHighlightedActor) + { return true; - if(old) + } + + // Clear the old highlight. + if(oldHighlightedActor) { - auto c = dynamic_cast(Internal::Control::Impl::GetAccessibilityObject(old)); - if(c) - c->ClearHighlight(); + auto oldHighlightObject = dynamic_cast(Internal::Control::Impl::GetAccessibilityObject(oldHighlightedActor)); + if(oldHighlightObject) + { + oldHighlightObject->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::ANCHOR_POINT, AnchorPoint::TOP_LEFT); highlight.SetProperty(Actor::Property::POSITION_Z, 1.0f); highlight.SetProperty(Actor::Property::POSITION, Vector2(0.0f, 0.0f)); + // Need to set resize policy again, to update SIZE property which is set by + // AccessibleImpl_NUI. The highlight could move from AccessibleImpl_NUI to + // AccessibleImpl. In this case, highlight has incorrect size. + highlight.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS); + // Remember the highlight actor, so that when the default is changed with // SetHighlightActor(), the currently displayed highlight can still be cleared. - currentHighlightActor = highlight; - EnsureSelfVisible(); + mCurrentHighlightActor = highlight; + ScrollToSelf(); self.Add(highlight); SetCurrentlyHighlightedActor(self); EmitHighlighted(true); + RegisterPositionPropertyNotification(); return true; } bool AccessibleImpl::ClearHighlight() { + Dali::Actor self = Self(); + if(!Dali::Accessibility::IsUp()) + { return false; + } + if(GetCurrentlyHighlightedActor() == self) { - self.Remove(currentHighlightActor.GetHandle()); - currentHighlightActor = {}; + UnregisterPositionPropertyNotification(); + self.Remove(mCurrentHighlightActor.GetHandle()); + mCurrentHighlightActor = {}; SetCurrentlyHighlightedActor({}); EmitHighlighted(false); return true; @@ -319,51 +465,54 @@ bool AccessibleImpl::ClearHighlight() std::string AccessibleImpl::GetActionName(size_t index) { - if(index >= GetActionCount()) return ""; + if(index >= GetActionCount()) + { + return {}; + } + Dali::TypeInfo type; - self.GetTypeInfo(type); + Self().GetTypeInfo(type); DALI_ASSERT_ALWAYS(type && "no TypeInfo object"); return type.GetActionName(index); } std::string AccessibleImpl::GetLocalizedActionName(size_t index) { - // TODO: add localization - return GetActionName(index); + return GetLocaleText(GetActionName(index)); } std::string AccessibleImpl::GetActionDescription(size_t index) { - return ""; + return {}; } size_t AccessibleImpl::GetActionCount() { Dali::TypeInfo type; - self.GetTypeInfo(type); + Self().GetTypeInfo(type); DALI_ASSERT_ALWAYS(type && "no TypeInfo object"); return type.GetActionCount(); } std::string AccessibleImpl::GetActionKeyBinding(size_t index) { - return ""; + return {}; } bool AccessibleImpl::DoAction(size_t index) { std::string actionName = GetActionName(index); - return self.DoAction(actionName, {}); + return Self().DoAction(actionName, {}); } bool AccessibleImpl::DoAction(const std::string& name) { - return self.DoAction(name, {}); + return Self().DoAction(name, {}); } bool AccessibleImpl::DoGesture(const Dali::Accessibility::GestureInfo& gestureInfo) { - auto control = Dali::Toolkit::Control::DownCast(self); + auto control = Dali::Toolkit::Control::DownCast(Self()); Internal::Control& internalControl = Toolkit::Internal::GetImplementation(control); Internal::Control::Impl& controlImpl = Internal::Control::Impl::Get(internalControl); @@ -380,36 +529,32 @@ bool AccessibleImpl::DoGesture(const Dali::Accessibility::GestureInfo& gestureIn std::vector AccessibleImpl::GetRelationSet() { - auto control = Dali::Toolkit::Control::DownCast(self); + 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) + auto& relation = controlImpl.mAccessibilityRelations; + for(auto i = 0u; i < relation.size(); ++i) { - if(v[i].empty()) - continue; + if(relation[i].empty()) continue; - ret.emplace_back(Accessibility::Relation{static_cast(i), v[i]}); + ret.emplace_back(Accessibility::Relation{static_cast(i), relation[i]}); } return ret; } -void AccessibleImpl::EnsureChildVisible(Actor child) +Dali::Actor AccessibleImpl::GetInternalActor() { + return Dali::Actor{}; } -void AccessibleImpl::EnsureSelfVisible() +bool AccessibleImpl::ScrollToChild(Actor child) { - auto parent = dynamic_cast(GetParent()); - if(parent) - { - parent->EnsureChildVisible(self); - } + return false; } Dali::Property::Index AccessibleImpl::GetNamePropertyIndex() @@ -422,4 +567,14 @@ Dali::Property::Index AccessibleImpl::GetDescriptionPropertyIndex() return Dali::Property::INVALID_INDEX; } +void AccessibleImpl::SetLastPosition(Vector2 position) +{ + mLastPosition = position; +} + +Vector2 AccessibleImpl::GetLastPosition() const +{ + return mLastPosition; +} + } // namespace Dali::Toolkit::DevelControl