This patch allows setting arbitrary attributes on the Accessible level.
Previously this was only possible for Control, and thus application-side
customization of the attributes was unavailable for some other classes (most
notably Layer, which stands in for Window in the AT-SPI tree).
Change-Id: If6855d57faf05547d38460263b0a6184ba604339
END_TEST;
}
+#if 0
int utcDaliAccessibilityControlAttributes(void)
{
ToolkitTestApplication application;
END_TEST;
}
+#endif
int UtcDaliControlDoGesture(void)
{
return CalculateStates();
}
-Dali::Accessibility::Attributes ControlAccessible::GetAttributes() const
+void ControlAccessible::UpdateAttributes(Accessibility::Attributes& attributes) const
{
- std::unordered_map<std::string, std::string> attributeMap;
- auto control = Dali::Toolkit::Control::DownCast(Self());
- auto attribute = control.GetProperty(Dali::Toolkit::DevelControl::Property::ACCESSIBILITY_ATTRIBUTES);
- auto map = attribute.GetMap();
+ static const std::string automationIdKey = "automationId";
- if(map)
- {
- auto mapSize = map->Count();
+ ActorAccessible::UpdateAttributes(attributes);
- for(unsigned int i = 0; i < mapSize; i++)
- {
- auto mapKey = map->GetKeyAt(i);
- if(mapKey.type == Dali::Property::Key::STRING)
- {
- std::string mapValue;
- if(map->GetValue(i).Get(mapValue))
- {
- attributeMap.emplace(std::move(mapKey.stringKey), std::move(mapValue));
- }
- }
- }
- }
+ Toolkit::Control control = Toolkit::Control::DownCast(Self());
+ auto automationId = control.GetProperty<std::string>(DevelControl::Property::AUTOMATION_ID);
- auto automationId = control.GetProperty<std::string>(Dali::Toolkit::DevelControl::Property::AUTOMATION_ID);
- if(!automationId.empty())
+ if(automationId.empty())
{
- attributeMap.emplace("automationId", std::move(automationId));
+ attributes.erase(automationIdKey);
+ }
+ else
+ {
+ attributes.insert_or_assign(automationIdKey, std::move(automationId));
}
-
- return attributeMap;
}
bool ControlAccessible::IsHidden() const
*/
bool IsShowing();
+ /**
+ * @copydoc Dali::Accessibility::Accessible::UpdateAttributes()
+ */
+ void UpdateAttributes(Dali::Accessibility::Attributes& attributes) const override;
+
public:
ControlAccessible(Dali::Actor self);
Dali::Accessibility::States GetStates() override;
/**
- * @copydoc Dali::Accessibility::Accessible::GetAttributes()
- */
- Dali::Accessibility::Attributes GetAttributes() const override;
-
- /**
* @copydoc Dali::Accessibility::Accessible::IsHidden()
*/
bool IsHidden() const override;
return Dali::Toolkit::Internal::Control::Impl::Get(internalControl);
}
+Dali::Toolkit::DevelControl::ControlAccessible* GetControlAccessible(Dali::Toolkit::Control control)
+{
+ auto* controlAccessible = GetControlImplementation(control).GetAccessibleObject();
+
+ if(DALI_UNLIKELY(!controlAccessible))
+ {
+ DALI_LOG_ERROR("Accessibility API used on Control without an Accessible");
+ }
+
+ return controlAccessible;
+}
+
} // unnamed namespace
namespace Dali
void AppendAccessibilityAttribute(Toolkit::Control control, const std::string& key, const std::string& value)
{
- GetControlImplementation(control).AppendAccessibilityAttribute(key, value);
+ auto* controlAccessible = GetControlAccessible(control);
+ if(DALI_LIKELY(controlAccessible))
+ {
+ controlAccessible->SetAttribute(key, value);
+ }
}
void RemoveAccessibilityAttribute(Toolkit::Control control, const std::string& key)
{
- GetControlImplementation(control).RemoveAccessibilityAttribute(key);
+ auto* controlAccessible = GetControlAccessible(control);
+ if(DALI_LIKELY(controlAccessible))
+ {
+ controlAccessible->UnsetAttribute(key);
+ }
}
void ClearAccessibilityAttributes(Toolkit::Control control)
{
- GetControlImplementation(control).ClearAccessibilityAttributes();
+ auto* controlAccessible = GetControlAccessible(control);
+ if(DALI_LIKELY(controlAccessible))
+ {
+ controlAccessible->ClearAttributes();
+ }
}
-void SetAccessibilityReadingInfoType(Toolkit::Control control, const Dali::Accessibility::ReadingInfoTypes types)
+void SetAccessibilityReadingInfoType(Toolkit::Control control, Dali::Accessibility::ReadingInfoTypes types)
{
- GetControlImplementation(control).SetAccessibilityReadingInfoType(types);
+ auto* controlAccessible = GetControlAccessible(control);
+ if(DALI_LIKELY(controlAccessible))
+ {
+ return controlAccessible->SetReadingInfoTypes(types);
+ }
}
Dali::Accessibility::ReadingInfoTypes GetAccessibilityReadingInfoType(Toolkit::Control control)
{
- return GetControlImplementation(control).GetAccessibilityReadingInfoType();
+ auto* controlAccessible = GetControlAccessible(control);
+ if(DALI_LIKELY(controlAccessible))
+ {
+ return controlAccessible->GetReadingInfoTypes();
+ }
+ return ~Dali::Accessibility::ReadingInfoTypes();
}
bool ClearAccessibilityHighlight(Toolkit::Control control)
{
- auto* controlAccessible = GetControlImplementation(control).GetAccessibleObject();
+ auto* controlAccessible = GetControlAccessible(control);
if(DALI_LIKELY(controlAccessible))
{
return controlAccessible->ClearHighlight();
bool GrabAccessibilityHighlight(Toolkit::Control control)
{
- auto* controlAccessible = GetControlImplementation(control).GetAccessibleObject();
+ auto* controlAccessible = GetControlAccessible(control);
if(DALI_LIKELY(controlAccessible))
{
return controlAccessible->GrabHighlight();
Dali::Accessibility::States GetAccessibilityStates(Toolkit::Control control)
{
- auto* controlAccessible = GetControlImplementation(control).GetAccessibleObject();
+ auto* controlAccessible = GetControlAccessible(control);
if(DALI_LIKELY(controlAccessible))
{
return controlAccessible->GetStates();
void NotifyAccessibilityStateChange(Toolkit::Control control, Dali::Accessibility::States states, bool recurse)
{
- auto* controlAccessible = GetControlImplementation(control).GetAccessibleObject();
+ auto* controlAccessible = GetControlAccessible(control);
if(DALI_LIKELY(controlAccessible))
{
controlAccessible->NotifyAccessibilityStateChange(std::move(states), recurse);
ACCESSIBILITY_HIGHLIGHTABLE,
/**
- * @brief Set of accessibility attributes describing object in accessibility hierarchy
- * @details Name "accessibilityAttributes", type Property::MAP
- */
- ACCESSIBILITY_ATTRIBUTES,
-
- /**
* @brief Whether a Control and its descendants can emit key signals.
* @details Name "dispatchKeyEvents", type Property::BOOLEAN
* @note If a control's dispatchKeyEvents is set to false, then it's children will not emit a key event signal either.
* @param control object to append attribute to
* @param types Reading information types
*/
-DALI_TOOLKIT_API void SetAccessibilityReadingInfoType(Toolkit::Control control, const Dali::Accessibility::ReadingInfoTypes types);
+DALI_TOOLKIT_API void SetAccessibilityReadingInfoType(Toolkit::Control control, Dali::Accessibility::ReadingInfoTypes types);
/**
* @brief The method returns reading information of an accessible object
#include <dali-toolkit/public-api/visuals/image-visual-properties.h>
#include <dali-toolkit/public-api/visuals/visual-properties.h>
-namespace
-{
-const char* READING_INFO_TYPE_NAME = "name";
-const char* READING_INFO_TYPE_ROLE = "role";
-const char* READING_INFO_TYPE_DESCRIPTION = "description";
-const char* READING_INFO_TYPE_STATE = "state";
-const char* READING_INFO_TYPE_ATTRIBUTE_NAME = "reading_info_type";
-const char* READING_INFO_TYPE_SEPARATOR = "|";
-} // namespace
-
namespace Dali
{
namespace Toolkit
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);
}
}
-void Control::Impl::AppendAccessibilityAttribute(const std::string& key, const std::string value)
-{
- Property::Value* checkedValue = mAccessibilityAttributes.Find(key);
- if(checkedValue)
- {
- mAccessibilityAttributes[key] = Property::Value(value);
- }
- else
- {
- mAccessibilityAttributes.Insert(key, value);
- }
-}
-
void Control::Impl::SetProperty(BaseObject* object, Property::Index index, const Property::Value& value)
{
Toolkit::Control control = Toolkit::Control::DownCast(BaseHandle(object));
break;
}
- case Toolkit::DevelControl::Property::ACCESSIBILITY_ATTRIBUTES:
- {
- const Property::Map* map = value.GetMap();
- if(map && !map->Empty())
- {
- controlImpl.mImpl->mAccessibilityAttributes = *map;
- }
- break;
- }
-
case Toolkit::DevelControl::Property::DISPATCH_KEY_EVENTS:
{
bool dispatch;
break;
}
- case Toolkit::DevelControl::Property::ACCESSIBILITY_ATTRIBUTES:
- {
- value = controlImpl.mImpl->mAccessibilityAttributes;
- break;
- }
-
case Toolkit::DevelControl::Property::DISPATCH_KEY_EVENTS:
{
value = controlImpl.mImpl->mDispatchKeyEvents;
return value;
}
-void Control::Impl::RemoveAccessibilityAttribute(const std::string& key)
-{
- Property::Value* value = mAccessibilityAttributes.Find(key);
- if(value)
- {
- mAccessibilityAttributes[key] = Property::Value();
- }
-}
-
-void Control::Impl::ClearAccessibilityAttributes()
-{
- mAccessibilityAttributes.Clear();
-}
-
-void Control::Impl::SetAccessibilityReadingInfoType(const Dali::Accessibility::ReadingInfoTypes types)
-{
- std::string value{};
- if(types[Dali::Accessibility::ReadingInfoType::NAME])
- {
- value += READING_INFO_TYPE_NAME;
- }
- if(types[Dali::Accessibility::ReadingInfoType::ROLE])
- {
- if(!value.empty())
- {
- value += READING_INFO_TYPE_SEPARATOR;
- }
- value += READING_INFO_TYPE_ROLE;
- }
- if(types[Dali::Accessibility::ReadingInfoType::DESCRIPTION])
- {
- if(!value.empty())
- {
- value += READING_INFO_TYPE_SEPARATOR;
- }
- value += READING_INFO_TYPE_DESCRIPTION;
- }
- if(types[Dali::Accessibility::ReadingInfoType::STATE])
- {
- if(!value.empty())
- {
- value += READING_INFO_TYPE_SEPARATOR;
- }
- value += READING_INFO_TYPE_STATE;
- }
- AppendAccessibilityAttribute(READING_INFO_TYPE_ATTRIBUTE_NAME, value);
-}
-
-Dali::Accessibility::ReadingInfoTypes Control::Impl::GetAccessibilityReadingInfoType() const
-{
- 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())
- {
- return {};
- }
-
- Dali::Accessibility::ReadingInfoTypes types;
-
- if(value.find(READING_INFO_TYPE_NAME) != std::string::npos)
- {
- types[Dali::Accessibility::ReadingInfoType::NAME] = true;
- }
- if(value.find(READING_INFO_TYPE_ROLE) != std::string::npos)
- {
- types[Dali::Accessibility::ReadingInfoType::ROLE] = true;
- }
- if(value.find(READING_INFO_TYPE_DESCRIPTION) != std::string::npos)
- {
- types[Dali::Accessibility::ReadingInfoType::DESCRIPTION] = true;
- }
- if(value.find(READING_INFO_TYPE_STATE) != std::string::npos)
- {
- types[Dali::Accessibility::ReadingInfoType::STATE] = true;
- }
-
- return types;
-}
-
void Control::Impl::CopyInstancedProperties(RegisteredVisualContainer& visuals, Dictionary<Property::Map>& instancedProperties)
{
for(RegisteredVisualContainer::Iterator iter = visuals.Begin(); iter != visuals.End(); iter++)
bool FilterKeyEvent(const KeyEvent& event);
/**
- * @brief Adds accessibility attribute
- * @param[in] key Attribute name to set
- * @param[in] value Attribute value to set
- *
- * Attribute is added if not existed previously or updated
- * if existed.
- */
- void AppendAccessibilityAttribute(const std::string& key, const std::string value);
-
- /**
- * @brief Removes accessibility attribute
- * @param[in] key Attribute name to remove
- *
- * Function does nothing if attribute doesn't exist.
- */
- void RemoveAccessibilityAttribute(const std::string& key);
-
- /**
- * @brief Removes all accessibility attributes
- */
- void ClearAccessibilityAttributes();
-
- /**
- * @brief Sets reading info type attributes
- * @param[in] types info type attributes to set
- *
- * This function sets, which part of object will be read out
- * by screen-reader.
- */
- void SetAccessibilityReadingInfoType(const Dali::Accessibility::ReadingInfoTypes types);
-
- /**
- * @brief Gets currently active reading info type attributes
- */
- Dali::Accessibility::ReadingInfoTypes GetAccessibilityReadingInfoType() const;
-
- /**
* @copydoc DevelControl::VisualEventSignal()
*/
DevelControl::VisualEventSignalType& VisualEventSignal();
Control& mControlImpl;
DevelControl::State mState;
std::string mSubStateName;
- Property::Map mAccessibilityAttributes;
int mLeftFocusableActorId; ///< Actor ID of Left focusable control.
int mRightFocusableActorId; ///< Actor ID of Right focusable control.
}
}
-Dali::Accessibility::Attributes WebView::WebViewAccessible::GetAttributes() const
+void WebView::WebViewAccessible::UpdateAttributes(Dali::Accessibility::Attributes& attributes) const
{
- auto attributes = DevelControl::ControlAccessible::GetAttributes();
+ static const std::string childBusKey = "child_bus";
+
+ ControlAccessible::UpdateAttributes(attributes);
if(mRemoteChild.GetAddress())
{
- attributes.insert_or_assign("child_bus", mRemoteChild.GetAddress().GetBus());
+ attributes.insert_or_assign(childBusKey, mRemoteChild.GetAddress().GetBus());
+ }
+ else
+ {
+ attributes.erase(childBusKey);
}
-
- return attributes;
}
void WebView::WebViewAccessible::DoGetChildren(std::vector<Dali::Accessibility::Accessible*>& children)
protected:
/**
- * @copydoc Dali::Accessibility::Accessible::GetAttributes()
+ * @copydoc Dali::Accessibility::Accessible::UpdateAttributes()
*/
- Dali::Accessibility::Attributes GetAttributes() const override;
+ void UpdateAttributes(Dali::Accessibility::Attributes& attributes) const override;
/**
* @copydoc Dali::Accessibility::ActorAccessible::DoGetChildren()