Add the accessible-read-only property

This commit is contained in:
Arnold Loubriat 2025-02-18 23:20:17 +01:00 committed by Simon Hausmann
parent e5c27d57ca
commit cc91de2d38
18 changed files with 60 additions and 1 deletions

View file

@ -394,6 +394,7 @@ public:
}
return std::nullopt;
}
/// Returns the accessible-expandable of that element, if any.
std::optional<bool> accessible_expandable() const
{
@ -407,6 +408,19 @@ public:
return std::nullopt;
}
/// Returns the accessible-read-only of that element, if any.
std::optional<bool> accessible_read_only() const
{
if (auto result = get_accessible_string_property(
cbindgen_private::AccessibleStringProperty::ReadOnly)) {
if (*result == "true")
return true;
else if (*result == "false")
return false;
}
return std::nullopt;
}
/// Invokes the expand accessibility action of that element
/// (`accessible-action-expand`).
void invoke_accessible_expand_action() const

View file

@ -401,6 +401,11 @@ The current value of the item.
A placeholder text to use when the item's value is empty. Applies to text elements.
</SlintProperty>
### accessible-read-only
<SlintProperty typeName="bool" propName="accessible-read-only" default="false">
Whether the element's content can be edited. This maps to the "read-only" state of line edit and text edit widgets.
</SlintProperty>
### accessible-item-selectable
<SlintProperty typeName="bool" propName="accessible-value" >
Whether the element can be selected or not.

View file

@ -32,6 +32,7 @@ const VALUE_STEP: u32 = VALUE_MAXIMUM + 1;
const CHECKABLE: u32 = VALUE_STEP + 1;
const EXPANDABLE: u32 = CHECKABLE + 1;
const EXPANDED: u32 = EXPANDABLE + 1;
const READ_ONLY: u32 = EXPANDED + 1;
pub struct AccessibleItemPropertiesTracker {
obj: *mut c_void,
@ -212,6 +213,7 @@ impl SlintAccessibleItemData {
item_rc.accessible_string_property(AccessibleStringProperty::Checked);
item_rc.accessible_string_property(AccessibleStringProperty::Expandable);
item_rc.accessible_string_property(AccessibleStringProperty::Expanded);
item_rc.accessible_string_property(AccessibleStringProperty::ReadOnly);
}
});
}
@ -273,6 +275,7 @@ cpp! {{
const uint32_t CHECKABLE { VALUE_STEP + 1 };
const uint32_t EXPANDABLE { CHECKABLE + 1 };
const uint32_t EXPANDED { EXPANDABLE + 1 };
const uint32_t READ_ONLY { EXPANDED + 1 };
// ------------------------------------------------------------------------------
// Helper:
@ -371,6 +374,7 @@ cpp! {{
CHECKABLE => item.accessible_string_property(AccessibleStringProperty::Checkable),
EXPANDABLE => item.accessible_string_property(AccessibleStringProperty::Expandable),
EXPANDED => item.accessible_string_property(AccessibleStringProperty::Expanded),
READ_ONLY => item.accessible_string_property(AccessibleStringProperty::ReadOnly),
_ => None,
};
if let Some(string) = string {
@ -638,6 +642,7 @@ cpp! {{
state.collapsed = 1;
}
}
state.readOnly = (item_string_property(m_data, READ_ONLY) == "true") ? 1 : 0;
return state; /* FIXME */
}

View file

@ -716,6 +716,17 @@ impl ElementHandle {
.and_then(|item| item.parse().ok())
}
/// Returns the value of the `accessible-read-only` property, if present
pub fn accessible_read_only(&self) -> Option<bool> {
if self.element_index != 0 {
return None;
}
self.item
.upgrade()
.and_then(|item| item.accessible_string_property(AccessibleStringProperty::ReadOnly))
.and_then(|item| item.parse().ok())
}
/// Returns the size of the element in logical pixels. This corresponds to the value of the `width` and
/// `height` properties in Slint code. Returns a zero size if the element is not valid.
pub fn size(&self) -> i_slint_core::api::LogicalSize {

View file

@ -594,6 +594,13 @@ impl NodeCollection {
node.set_placeholder(placeholder.to_string());
}
if item
.accessible_string_property(AccessibleStringProperty::ReadOnly)
.is_some_and(|x| x == "true")
{
node.set_read_only();
}
if item
.accessible_string_property(AccessibleStringProperty::ItemSelectable)
.is_some_and(|x| x == "true")

View file

@ -214,6 +214,7 @@ pub fn reserved_accessibility_properties() -> impl Iterator<Item = (&'static str
("accessible-item-selected", Type::Bool),
("accessible-item-index", Type::Int32),
("accessible-item-count", Type::Int32),
("accessible-read-only", Type::Bool),
]
.into_iter()
}

View file

@ -22,6 +22,7 @@ export component LineEdit {
accessible-enabled: root.enabled;
accessible-value <=> text;
accessible-placeholder-text: text == "" ? placeholder-text : "";
accessible-read-only: root.read-only;
accessible-action-set-value(v) => { text = v; edited(v); }
public function set-selection-offsets(start: int, end: int) {

View file

@ -29,6 +29,7 @@ export component TextEdit {
accessible-enabled: root.enabled;
accessible-value <=> text;
accessible-placeholder-text: text == "" ? placeholder-text : "";
accessible-read-only: root.read-only;
public function set-selection-offsets(start: int, end: int) {
base.set-selection-offsets(start, end);

View file

@ -23,6 +23,7 @@ export component LineEdit {
accessible-enabled: root.enabled;
accessible-value <=> text;
accessible-placeholder-text: text == "" ? placeholder-text : "";
accessible-read-only: root.read-only;
accessible-action-set-value(v) => {
text = v;
edited(v);

View file

@ -85,6 +85,7 @@ export component TextEdit {
accessible-enabled: root.enabled;
accessible-value <=> text;
accessible-placeholder-text: text == "" ? placeholder-text : "";
accessible-read-only: root.read-only;
public function set-selection-offsets(start: int, end: int) {
text-input.set-selection-offsets(start, end);

View file

@ -22,6 +22,7 @@ export component LineEdit {
accessible-enabled: root.enabled;
accessible-value <=> text;
accessible-placeholder-text: text == "" ? placeholder-text : "";
accessible-read-only: root.read-only;
accessible-action-set-value(v) => { text = v; edited(v); }
public function set-selection-offsets(start: int, end: int) {

View file

@ -29,6 +29,7 @@ export component TextEdit {
accessible-enabled: root.enabled;
accessible-value <=> text;
accessible-placeholder-text: text == "" ? placeholder-text : "";
accessible-read-only: root.read-only;
public function set-selection-offsets(start: int, end: int) {
base.set-selection-offsets(start, end);

View file

@ -23,6 +23,7 @@ export component LineEdit {
accessible-enabled: root.enabled;
accessible-value <=> text;
accessible-placeholder-text: text == "" ? placeholder-text : "";
accessible-read-only: root.read-only;
accessible-action-set-value(v) => { text = v; edited(v); }
public function set-selection-offsets(start: int, end: int) {

View file

@ -29,6 +29,7 @@ export component TextEdit {
accessible-enabled: root.enabled;
accessible-value <=> text;
accessible-placeholder-text: text == "" ? placeholder-text : "";
accessible-read-only: root.read-only;
public function set-selection-offsets(start: int, end: int) {
base.set-selection-offsets(start, end);

View file

@ -21,6 +21,7 @@ export component LineEdit {
accessible-enabled: root.enabled;
accessible-value <=> text;
accessible-placeholder-text: text == "" ? placeholder-text : "";
accessible-read-only: root.read-only;
accessible-action-set-value(v) => { text = v; edited(v); }
public function set-selection-offsets(start: int, end: int) {

View file

@ -28,6 +28,7 @@ export component TextEdit {
accessible-enabled: root.enabled;
accessible-value <=> text;
accessible-placeholder-text: text == "" ? placeholder-text : "";
accessible-read-only: root.read-only;
public function set-selection-offsets(start: int, end: int) {
base.set-selection-offsets(start, end);

View file

@ -25,6 +25,7 @@ pub enum AccessibleStringProperty {
ItemSelected,
Label,
PlaceholderText,
ReadOnly,
Value,
ValueMaximum,
ValueMinimum,

View file

@ -15,6 +15,7 @@ export component TestCase inherits Window {
out property <bool> textedit-focused <=> edit.has_focus;
callback edited <=> edit.edited;
in-out property <string> text <=> edit.text;
in-out property <bool> read-only <=> edit.read-only;
public function paste() {
edit.paste();
}
@ -92,7 +93,11 @@ assert_eq!(instance.get_text(), "Xxx");
instance.invoke_paste();
assert_eq!(instance.get_text(), "XxxHello👋");
let mut edit_search = slint_testing::ElementHandle::find_by_element_id(&instance, "TestCase::edit");
let edit = edit_search.next().unwrap();
assert_eq!(edit.accessible_read_only(), Some(false));
instance.set_read_only(true);
assert_eq!(edit.accessible_read_only(), Some(true));
```
*/