Add the accessible-placeholder-text property (#5464)

This commit is contained in:
Arnold Loubriat 2024-06-26 12:59:22 +02:00 committed by GitHub
parent bd18d8dc0a
commit ce2db77e88
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
19 changed files with 48 additions and 11 deletions

View file

@ -232,6 +232,13 @@ public:
return get_accessible_string_property(cbindgen_private::AccessibleStringProperty::Value); return get_accessible_string_property(cbindgen_private::AccessibleStringProperty::Value);
} }
/// Returns the accessible-placeholder-text of that element, if any.
std::optional<SharedString> accessible_placeholder_text() const
{
return get_accessible_string_property(
cbindgen_private::AccessibleStringProperty::PlaceholderText);
}
/// Returns the accessible-description of that element, if any. /// Returns the accessible-description of that element, if any.
std::optional<SharedString> accessible_description() const std::optional<SharedString> accessible_description() const
{ {

View file

@ -73,6 +73,7 @@ Use the following `accessible-` properties to make your items interact well with
- **`accessible-value-minimum`** (_in_ _float_): The minimum value of the item. - **`accessible-value-minimum`** (_in_ _float_): The minimum value of the item.
- **`accessible-value-step`** (_in_ _float_) The smallest increment or decrement by which the current value can change. This corresponds to the step by which a handle on a slider can be dragged. - **`accessible-value-step`** (_in_ _float_) The smallest increment or decrement by which the current value can change. This corresponds to the step by which a handle on a slider can be dragged.
- **`accessible-value`** (_in_ _string_): The current value of the item. - **`accessible-value`** (_in_ _string_): The current value of the item.
- **`accessible-placeholder-text`** (_in_ _string_): A placeholder text to use when the item's value is empty. Applies to text elements.
You can also use the following callbacks that are going to be called by the accessibility framework: You can also use the following callbacks that are going to be called by the accessibility framework:

View file

@ -58,7 +58,7 @@ export component CreateTaskView {
VerticalLayout { VerticalLayout {
spacing: SpaceSettings.default-spacing; spacing: SpaceSettings.default-spacing;
Text { title-label := Text {
text: @tr("Task name"); text: @tr("Task name");
color: TodoPalette.foreground; color: TodoPalette.foreground;
font-size: FontSettings.body-strong.font-size; font-size: FontSettings.body-strong.font-size;
@ -69,6 +69,7 @@ export component CreateTaskView {
title-input := LineEdit { title-input := LineEdit {
placeholder-text: @tr("Describe your task"); placeholder-text: @tr("Describe your task");
accessible-label: title-label.text;
} }
} }

View file

@ -18,7 +18,7 @@ SCENARIO("Basic TEST")
state.mainWindow, state.mainWindow,
[](slint::testing::ElementHandle element) [](slint::testing::ElementHandle element)
-> std::optional<slint::testing::ElementHandle> { -> std::optional<slint::testing::ElementHandle> {
if (element.accessible_label() == "What needs to be done?") { if (element.accessible_placeholder_text() == "What needs to be done?") {
return element; return element;
} else { } else {
return {}; return {};

View file

@ -174,10 +174,14 @@ fn press_add_adds_one_todo() {
use i_slint_backend_testing::ElementHandle; use i_slint_backend_testing::ElementHandle;
let state = init(); let state = init();
state.todo_model.set_vec(vec![TodoItem { checked: false, title: "first".into() }]); state.todo_model.set_vec(vec![TodoItem { checked: false, title: "first".into() }]);
let line_edit = let line_edit = ElementHandle::visit_elements(&state.main_window, |element| {
ElementHandle::find_by_accessible_label(&state.main_window, "What needs to be done?") if element.accessible_placeholder_text().as_deref() == Some("What needs to be done?") {
.next() std::ops::ControlFlow::Break(element)
.unwrap(); } else {
std::ops::ControlFlow::Continue(())
}
})
.unwrap();
assert_eq!(line_edit.accessible_value().unwrap(), ""); assert_eq!(line_edit.accessible_value().unwrap(), "");
line_edit.set_accessible_value("second"); line_edit.set_accessible_value("second");

View file

@ -352,6 +352,16 @@ impl ElementHandle {
.and_then(|item| item.accessible_string_property(AccessibleStringProperty::Value)) .and_then(|item| item.accessible_string_property(AccessibleStringProperty::Value))
} }
/// Returns the value of the element's `accessible-placeholder-text` property, if present.
pub fn accessible_placeholder_text(&self) -> Option<SharedString> {
if self.element_index != 0 {
return None;
}
self.item.upgrade().and_then(|item| {
item.accessible_string_property(AccessibleStringProperty::PlaceholderText)
})
}
/// Sets the value of the element's `accessible-value` property. Note that you can only set this /// Sets the value of the element's `accessible-value` property. Note that you can only set this
/// property if it is declared in your Slint code. /// property if it is declared in your Slint code.
pub fn set_accessible_value(&self, value: impl Into<SharedString>) { pub fn set_accessible_value(&self, value: impl Into<SharedString>) {

View file

@ -445,6 +445,13 @@ impl NodeCollection {
} }
} }
if let Some(placeholder) = item
.accessible_string_property(AccessibleStringProperty::PlaceholderText)
.filter(|x| !x.is_empty())
{
builder.set_placeholder(placeholder.to_string());
}
let supported = item.supported_accessibility_actions(); let supported = item.supported_accessibility_actions();
if supported.contains(SupportedAccessibilityAction::Default) { if supported.contains(SupportedAccessibilityAction::Default) {
builder.add_action(accesskit::Action::Default); builder.add_action(accesskit::Action::Default);

View file

@ -111,6 +111,7 @@ pub fn reserved_accessibility_properties() -> impl Iterator<Item = (&'static str
("accessible-value-maximum", Type::Float32), ("accessible-value-maximum", Type::Float32),
("accessible-value-minimum", Type::Float32), ("accessible-value-minimum", Type::Float32),
("accessible-value-step", Type::Float32), ("accessible-value-step", Type::Float32),
("accessible-placeholder-text", Type::String),
("accessible-action-default", Type::Callback { return_type: None, args: vec![] }), ("accessible-action-default", Type::Callback { return_type: None, args: vec![] }),
("accessible-action-increment", Type::Callback { return_type: None, args: vec![] }), ("accessible-action-increment", Type::Callback { return_type: None, args: vec![] }),
("accessible-action-decrement", Type::Callback { return_type: None, args: vec![] }), ("accessible-action-decrement", Type::Callback { return_type: None, args: vec![] }),

View file

@ -18,7 +18,7 @@ export component LineEdit {
callback edited <=> base.edited; callback edited <=> base.edited;
accessible-role: text-input; accessible-role: text-input;
accessible-value <=> text; accessible-value <=> text;
accessible-label: placeholder-text; accessible-placeholder-text: text == "" ? placeholder-text : "";
accessible-action-set-value(v) => { text = v; edited(v); } accessible-action-set-value(v) => { text = v; edited(v); }
public function set-selection-offsets(start: int, end: int) { public function set-selection-offsets(start: int, end: int) {

View file

@ -24,6 +24,7 @@ export component TextEdit {
callback edited(/* text */ string); callback edited(/* text */ string);
accessible-role: AccessibleRole.text-input; accessible-role: AccessibleRole.text-input;
accessible-value <=> text; accessible-value <=> text;
accessible-placeholder-text: text == "" ? placeholder-text : "";
public function set-selection-offsets(start: int, end: int) { public function set-selection-offsets(start: int, end: int) {
base.set-selection-offsets(start, end); base.set-selection-offsets(start, end);

View file

@ -19,7 +19,7 @@ export component LineEdit {
callback edited <=> i-base.edited; callback edited <=> i-base.edited;
accessible-role: text-input; accessible-role: text-input;
accessible-value <=> text; accessible-value <=> text;
accessible-label: placeholder-text; accessible-placeholder-text: text == "" ? placeholder-text : "";
accessible-action-set-value(v) => { text = v; edited(v); } accessible-action-set-value(v) => { text = v; edited(v); }
public function set-selection-offsets(start: int, end: int) { public function set-selection-offsets(start: int, end: int) {

View file

@ -80,6 +80,7 @@ export component TextEdit {
callback edited(/* text */ string); callback edited(/* text */ string);
accessible-role: AccessibleRole.text-input; accessible-role: AccessibleRole.text-input;
accessible-value <=> text; accessible-value <=> text;
accessible-placeholder-text: text == "" ? placeholder-text : "";
public function set-selection-offsets(start: int,end: int){ public function set-selection-offsets(start: int,end: int){
text-input.set-selection-offsets(start, end); text-input.set-selection-offsets(start, end);

View file

@ -18,7 +18,7 @@ export component LineEdit {
callback edited <=> i-base.edited; callback edited <=> i-base.edited;
accessible-role: text-input; accessible-role: text-input;
accessible-value <=> text; accessible-value <=> text;
accessible-label: placeholder-text; accessible-placeholder-text: text == "" ? placeholder-text : "";
accessible-action-set-value(v) => { text = v; edited(v); } accessible-action-set-value(v) => { text = v; edited(v); }
public function set-selection-offsets(start: int, end: int) { public function set-selection-offsets(start: int, end: int) {

View file

@ -24,6 +24,7 @@ export component TextEdit {
callback edited(/* text */ string); callback edited(/* text */ string);
accessible-role: AccessibleRole.text-input; accessible-role: AccessibleRole.text-input;
accessible-value <=> text; accessible-value <=> text;
accessible-placeholder-text: text == "" ? placeholder-text : "";
public function set-selection-offsets(start: int,end: int){ public function set-selection-offsets(start: int,end: int){
base.set-selection-offsets(start, end); base.set-selection-offsets(start, end);

View file

@ -19,7 +19,7 @@ export component LineEdit {
callback edited <=> i-base.edited; callback edited <=> i-base.edited;
accessible-role: text-input; accessible-role: text-input;
accessible-value <=> text; accessible-value <=> text;
accessible-label: placeholder-text; accessible-placeholder-text: text == "" ? placeholder-text : "";
accessible-action-set-value(v) => { text = v; edited(v); } accessible-action-set-value(v) => { text = v; edited(v); }
public function set-selection-offsets(start: int, end: int) { public function set-selection-offsets(start: int, end: int) {

View file

@ -24,6 +24,7 @@ export component TextEdit {
callback edited(/* text */ string); callback edited(/* text */ string);
accessible-role: AccessibleRole.text-input; accessible-role: AccessibleRole.text-input;
accessible-value <=> text; accessible-value <=> text;
accessible-placeholder-text: text == "" ? placeholder-text : "";
public function set-selection-offsets(start: int,end: int){ public function set-selection-offsets(start: int,end: int){
base.set-selection-offsets(start, end); base.set-selection-offsets(start, end);

View file

@ -17,7 +17,7 @@ export component LineEdit {
callback edited <=> inner.edited; callback edited <=> inner.edited;
accessible-role: text-input; accessible-role: text-input;
accessible-value <=> text; accessible-value <=> text;
accessible-label: placeholder-text; accessible-placeholder-text: text == "" ? placeholder-text : "";
accessible-action-set-value(v) => { text = v; edited(v); } accessible-action-set-value(v) => { text = v; edited(v); }
public function set-selection-offsets(start: int, end: int) { public function set-selection-offsets(start: int, end: int) {

View file

@ -23,6 +23,7 @@ export component TextEdit {
callback edited(/* text */ string); callback edited(/* text */ string);
accessible-role: AccessibleRole.text-input; accessible-role: AccessibleRole.text-input;
accessible-value <=> text; accessible-value <=> text;
accessible-placeholder-text: text == "" ? placeholder-text : "";
public function set-selection-offsets(start: int,end: int){ public function set-selection-offsets(start: int,end: int){
base.set-selection-offsets(start, end); base.set-selection-offsets(start, end);

View file

@ -20,6 +20,7 @@ pub enum AccessibleStringProperty {
DelegateFocus, DelegateFocus,
Description, Description,
Label, Label,
PlaceholderText,
Value, Value,
ValueMaximum, ValueMaximum,
ValueMinimum, ValueMinimum,