Add the accessible-expanded property

This commit is contained in:
Arnold Loubriat 2024-12-22 16:37:56 +01:00 committed by Simon Hausmann
parent 53fd7b12e4
commit f30f953ffd
13 changed files with 66 additions and 1 deletions

View file

@ -382,6 +382,18 @@ public:
return std::nullopt;
}
/// Returns the accessible-expanded of that element, if any.
std::optional<bool> accessible_expanded() const
{
if (auto result = get_accessible_string_property(
cbindgen_private::AccessibleStringProperty::Expanded)) {
if (*result == "true")
return true;
else if (*result == "false")
return false;
}
return std::nullopt;
}
/// Returns the accessible-expandable of that element, if any.
std::optional<bool> accessible_expandable() const
{

View file

@ -212,6 +212,12 @@ Whether the element is enabled or not. This maps to the "enabled" state of most
Whether the element can be expanded or not.
</SlintProperty>
### accessible-expanded
<SlintProperty typeName="bool" propName="accessible-expanded" default="false">
Whether the element is expanded or not. Applies to combo boxes, menu items,
tree view items and other widgets.
</SlintProperty>
### accessible-label
<SlintProperty typeName="string" propName="accessible-label" default='""'>
The label for an interactive element. (default value: empty for most elements, or the value of the `text` property for Text elements)

View file

@ -31,6 +31,7 @@ const VALUE_MAXIMUM: u32 = VALUE_MINIMUM + 1;
const VALUE_STEP: u32 = VALUE_MAXIMUM + 1;
const CHECKABLE: u32 = VALUE_STEP + 1;
const EXPANDABLE: u32 = CHECKABLE + 1;
const EXPANDED: u32 = EXPANDABLE + 1;
pub struct AccessibleItemPropertiesTracker {
obj: *mut c_void,
@ -210,6 +211,7 @@ impl SlintAccessibleItemData {
item_rc.accessible_string_property(AccessibleStringProperty::Checkable);
item_rc.accessible_string_property(AccessibleStringProperty::Checked);
item_rc.accessible_string_property(AccessibleStringProperty::Expandable);
item_rc.accessible_string_property(AccessibleStringProperty::Expanded);
}
});
}
@ -270,6 +272,7 @@ cpp! {{
const uint32_t VALUE_STEP { VALUE_MAXIMUM + 1 };
const uint32_t CHECKABLE { VALUE_STEP + 1 };
const uint32_t EXPANDABLE { CHECKABLE + 1 };
const uint32_t EXPANDED { EXPANDABLE + 1 };
// ------------------------------------------------------------------------------
// Helper:
@ -366,6 +369,7 @@ cpp! {{
VALUE_STEP => item.accessible_string_property(AccessibleStringProperty::ValueStep),
CHECKABLE => item.accessible_string_property(AccessibleStringProperty::Checkable),
EXPANDABLE => item.accessible_string_property(AccessibleStringProperty::Expandable),
EXPANDED => item.accessible_string_property(AccessibleStringProperty::Expanded),
_ => None,
};
if let Some(string) = string {
@ -625,7 +629,14 @@ cpp! {{
state.focused = has_focus_delegation;
state.checked = (checked == "true") ? 1 : 0;
state.checkable = (item_string_property(m_data, CHECKABLE) == "true") ? 1 : 0;
state.expandable = (item_string_property(m_data, EXPANDABLE) == "true") ? 1 : 0;
if (item_string_property(m_data, EXPANDABLE) == "true") {
state.expandable = 1;
if (item_string_property(m_data, EXPANDED) == "true") {
state.expanded = 1;
} else {
state.collapsed = 1;
}
}
return state; /* FIXME */
}

View file

@ -647,6 +647,17 @@ impl ElementHandle {
})
}
/// Returns the value of the `accessible-expanded` property, if present
pub fn accessible_expanded(&self) -> Option<bool> {
if self.element_index != 0 {
return None;
}
self.item
.upgrade()
.and_then(|item| item.accessible_string_property(AccessibleStringProperty::Expanded))
.and_then(|item| item.parse().ok())
}
/// Returns the value of the `accessible-expandable` property, if present
pub fn accessible_expandable(&self) -> Option<bool> {
if self.element_index != 0 {

View file

@ -520,6 +520,16 @@ impl NodeCollection {
node.set_description(description.to_string());
}
if item
.accessible_string_property(AccessibleStringProperty::Expandable)
.is_some_and(|x| x == "true")
{
node.set_expanded(
item.accessible_string_property(AccessibleStringProperty::Expanded)
.is_some_and(|x| x == "true"),
);
}
if matches!(
role,
Role::Button

View file

@ -198,6 +198,7 @@ pub fn reserved_accessibility_properties() -> impl Iterator<Item = (&'static str
("accessible-description", Type::String),
("accessible-enabled", Type::Bool),
("accessible-expandable", Type::Bool),
("accessible-expanded", Type::Bool),
("accessible-label", Type::String),
("accessible-value", Type::String),
("accessible-value-maximum", Type::Float32),

View file

@ -27,6 +27,7 @@ export component ComboBox {
accessible-role: combobox;
accessible-enabled: root.enabled;
accessible-expandable: true;
accessible-expanded: base.popup-has-focus;
accessible-value <=> root.current-value;
states [

View file

@ -27,6 +27,7 @@ export component ComboBox {
accessible-role: combobox;
accessible-enabled: root.enabled;
accessible-expandable: true;
accessible-expanded: base.popup-has-focus;
accessible-value <=> root.current-value;
states [

View file

@ -27,6 +27,7 @@ export component ComboBox {
accessible-role: combobox;
accessible-enabled: root.enabled;
accessible-expandable: true;
accessible-expanded: base.popup-has-focus;
accessible-value <=> root.current-value;
states [

View file

@ -26,6 +26,7 @@ export component ComboBox {
accessible-role: combobox;
accessible-enabled: root.enabled;
accessible-expandable: true;
accessible-expanded: base.popup-has-focus;
accessible-value <=> root.current-value;
states [

View file

@ -16,6 +16,7 @@ export component ComboBox {
accessible-role: combobox;
accessible-enabled: root.enabled;
accessible-expandable: true;
accessible-expanded: base.popup-has-focus;
accessible-value <=> root.current-value;
forward-focus: base;

View file

@ -18,6 +18,7 @@ pub enum AccessibleStringProperty {
Description,
Enabled,
Expandable,
Expanded,
ItemCount,
ItemIndex,
ItemSelectable,

View file

@ -46,6 +46,7 @@ assert_eq!(instance.get_has_focus(), false);
let mut combobox_search = slint_testing::ElementHandle::find_by_element_id(&instance, "TestCase::box");
let combobox = combobox_search.next().unwrap();
assert_eq!(combobox.accessible_expandable(), Some(true));
assert_eq!(combobox.accessible_expanded(), Some(false));
assert_eq!(combobox.accessible_value(), Some(SharedString::from("Aaa")));
// Change the index programmatically
@ -65,6 +66,7 @@ assert_eq!(instance.get_has_focus(), false);
slint_testing::send_mouse_click(&instance, 100., 100.);
assert_eq!(instance.get_output(), "");
assert_eq!(instance.get_has_focus(), true);
assert_eq!(combobox.accessible_expanded(), Some(true));
// click outside of the combobox, this should close it
slint_testing::send_mouse_click(&instance, 100., 10.);
@ -73,6 +75,7 @@ assert_eq!(instance.get_current_value(), "Aaa");
assert_eq!(instance.get_current_index(), 0);
assert_eq!(combobox.accessible_value(), Some(SharedString::from("Aaa")));
assert_eq!(instance.get_has_focus(), true);
assert_eq!(combobox.accessible_expanded(), Some(false));
// click outside of the combobox again
slint_testing::send_mouse_click(&instance, 100., 10.);
@ -82,6 +85,7 @@ assert_eq!(instance.get_current_value(), "Aaa");
assert_eq!(instance.get_current_index(), 0);
assert_eq!(combobox.accessible_value(), Some(SharedString::from("Aaa")));
assert_eq!(instance.get_has_focus(), true);
assert_eq!(combobox.accessible_expanded(), Some(false));
// The arrow change the values
@ -105,13 +109,16 @@ instance.set_output(Default::default());
// show the popup
slint_testing::send_keyboard_string_sequence(&instance, &SharedString::from(Key::Return));
assert_eq!(instance.get_output(), "");
assert_eq!(combobox.accessible_expanded(), Some(true));
// click outside causes the popup to close
slint_testing::send_mouse_click(&instance, 100., 10.);
assert_eq!(instance.get_output(), "");
assert_eq!(instance.get_has_focus(), true);
assert_eq!(combobox.accessible_expanded(), Some(false));
slint_testing::send_mouse_click(&instance, 100., 10.);
assert_eq!(instance.get_output(), "clicked-under\n");
assert_eq!(instance.get_has_focus(), true);
assert_eq!(combobox.accessible_expanded(), Some(false));
instance.set_output(Default::default());
instance.set_current_index(0);
@ -144,6 +151,7 @@ assert_eq!(instance.get_output(), "selected(Bbb,1)\nselected(Ccc,2)\nselected(Bb
instance.set_output(Default::default());
slint_testing::send_mouse_click(&instance, 100., 10.);
assert_eq!(instance.get_output(), "clicked-under\n");
assert_eq!(combobox.accessible_expanded(), Some(false));
assert_eq!(instance.get_has_focus(), true);