mirror of
https://github.com/slint-ui/slint.git
synced 2025-08-07 04:08:41 +00:00

You can not create this expression manually, but there is a pass in the compiler that adds it to all set properties in a compilation run. All it does is basically associate an id with an expression, so that we can then in a later step have the interpreter do something with that information. Apart from that, it tries to be as transparent as possible. The LLR lowering removes that expression again, just so we can be sure it does not end up in the generated live code.
108 lines
4.8 KiB
Rust
108 lines
4.8 KiB
Rust
// Copyright © SixtyFPS GmbH <info@slint.dev>
|
|
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0
|
|
|
|
//! Pass that lowers synthetic `accessible-*` properties
|
|
|
|
use crate::diagnostics::BuildDiagnostics;
|
|
use crate::expression_tree::{Expression, NamedReference};
|
|
use crate::langtype::EnumerationValue;
|
|
use crate::object_tree::{Component, ElementRc};
|
|
|
|
use smol_str::SmolStr;
|
|
use std::rc::Rc;
|
|
|
|
pub fn lower_accessibility_properties(component: &Rc<Component>, diag: &mut BuildDiagnostics) {
|
|
crate::object_tree::recurse_elem_including_sub_components_no_borrow(
|
|
component,
|
|
&(),
|
|
&mut |elem, _| {
|
|
if elem.borrow().repeated.is_some() {
|
|
return;
|
|
};
|
|
apply_builtin(elem);
|
|
let accessible_role_set = match elem.borrow().bindings.get("accessible-role") {
|
|
Some(role) => {
|
|
if let Expression::EnumerationValue(val) =
|
|
super::ignore_debug_hooks(&role.borrow().expression)
|
|
{
|
|
debug_assert_eq!(val.enumeration.name, "AccessibleRole");
|
|
debug_assert_eq!(val.enumeration.values[0], "none");
|
|
if val.value == 0 {
|
|
return;
|
|
}
|
|
} else {
|
|
diag.push_error(
|
|
"The `accessible-role` property must be a constant expression".into(),
|
|
&*role.borrow(),
|
|
);
|
|
}
|
|
true
|
|
}
|
|
// maybe it was set on the parent
|
|
None => elem.borrow().is_binding_set("accessible-role", false),
|
|
};
|
|
|
|
for prop_name in crate::typeregister::reserved_accessibility_properties()
|
|
.map(|x| x.0)
|
|
.chain(std::iter::once("accessible-role"))
|
|
{
|
|
if accessible_role_set {
|
|
if elem.borrow().is_binding_set(prop_name, false) {
|
|
let nr = NamedReference::new(elem, SmolStr::new_static(prop_name));
|
|
elem.borrow_mut().accessibility_props.0.insert(prop_name.into(), nr);
|
|
}
|
|
} else if let Some(b) = elem.borrow().bindings.get(prop_name) {
|
|
diag.push_error(
|
|
format!("The `{prop_name}` property can only be set in combination to `accessible-role`"),
|
|
&*b.borrow(),
|
|
);
|
|
}
|
|
}
|
|
},
|
|
)
|
|
}
|
|
|
|
fn apply_builtin(e: &ElementRc) {
|
|
let bty = if let Some(bty) = e.borrow().builtin_type() { bty } else { return };
|
|
if bty.name == "Text" {
|
|
e.borrow_mut().set_binding_if_not_set("accessible-role".into(), || {
|
|
let enum_ty = crate::typeregister::BUILTIN.with(|e| e.enums.AccessibleRole.clone());
|
|
Expression::EnumerationValue(EnumerationValue {
|
|
value: enum_ty.values.iter().position(|v| v == "text").unwrap(),
|
|
enumeration: enum_ty,
|
|
})
|
|
});
|
|
let text_prop = NamedReference::new(e, SmolStr::new_static("text"));
|
|
e.borrow_mut().set_binding_if_not_set("accessible-label".into(), || {
|
|
Expression::PropertyReference(text_prop)
|
|
});
|
|
} else if bty.name == "TextInput" {
|
|
e.borrow_mut().set_binding_if_not_set("accessible-role".into(), || {
|
|
let enum_ty = crate::typeregister::BUILTIN.with(|e| e.enums.AccessibleRole.clone());
|
|
Expression::EnumerationValue(EnumerationValue {
|
|
value: enum_ty.values.iter().position(|v| v == "text-input").unwrap(),
|
|
enumeration: enum_ty,
|
|
})
|
|
});
|
|
let text_prop = NamedReference::new(e, SmolStr::new_static("text"));
|
|
e.borrow_mut().set_binding_if_not_set("accessible-value".into(), || {
|
|
Expression::PropertyReference(text_prop)
|
|
});
|
|
let enabled_prop = NamedReference::new(e, SmolStr::new_static("enabled"));
|
|
e.borrow_mut().set_binding_if_not_set("accessible-enabled".into(), || {
|
|
Expression::PropertyReference(enabled_prop)
|
|
});
|
|
let read_only_prop = NamedReference::new(e, SmolStr::new_static("read-only"));
|
|
e.borrow_mut().set_binding_if_not_set("accessible-read-only".into(), || {
|
|
Expression::PropertyReference(read_only_prop)
|
|
});
|
|
} else if bty.name == "Image" {
|
|
e.borrow_mut().set_binding_if_not_set("accessible-role".into(), || {
|
|
let enum_ty = crate::typeregister::BUILTIN.with(|e| e.enums.AccessibleRole.clone());
|
|
Expression::EnumerationValue(EnumerationValue {
|
|
value: enum_ty.values.iter().position(|v| v == "image").unwrap(),
|
|
enumeration: enum_ty,
|
|
})
|
|
});
|
|
}
|
|
}
|