i_slint_compiler/passes/
deprecated_rotation_origin.rs1use crate::diagnostics::{BuildDiagnostics, Spanned};
7use crate::expression_tree::Expression;
8use crate::namedreference::NamedReference;
9use crate::object_tree::{Component, ElementRc};
10use core::cell::RefCell;
11use smol_str::SmolStr;
12
13pub fn handle_rotation_origin(component: &Component, diag: &mut BuildDiagnostics) {
14 let transform_origin = crate::typeregister::transform_origin_property();
15
16 crate::object_tree::recurse_elem_including_sub_components_no_borrow(
17 component,
18 &(),
19 &mut |elem, _| {
20 let mut must_materialize = false;
21 let mut seen = false;
22 for (prop, _) in crate::typeregister::DEPRECATED_ROTATION_ORIGIN_PROPERTIES {
23 if elem.borrow().is_property_set(prop) {
24 let span = match elem
25 .borrow()
26 .bindings
27 .get(prop)
28 .and_then(|b| b.borrow().span.clone())
29 {
30 Some(span) => span,
31 None => {
32 if seen {
33 return;
34 }
35 elem.borrow().to_source_location()
36 }
37 };
38
39 seen = true;
40
41 if !is_image_or_text(elem) {
42 diag.push_error(format!("'{prop}' cannot be set on this element"), &span);
43 } else {
44 diag.push_property_deprecation_warning(prop, transform_origin.0, &span);
45 must_materialize = true;
46 }
47 }
48 }
49 if !must_materialize {
50 return;
51 }
52
53 let expr = Expression::Struct {
54 ty: transform_origin.1.clone(),
55 values: crate::typeregister::DEPRECATED_ROTATION_ORIGIN_PROPERTIES
56 .iter()
57 .map(|(prop, _)| {
58 (
59 SmolStr::new_static(&prop[prop.len() - 1..]),
60 Expression::PropertyReference(NamedReference::new(
61 elem,
62 SmolStr::new_static(prop),
63 )),
64 )
65 })
66 .collect(),
67 };
68
69 match elem.borrow_mut().bindings.entry(transform_origin.0.into()) {
70 std::collections::btree_map::Entry::Occupied(occupied_entry) => {
71 diag.push_error(
72 "Can't specify transform-origin if rotation-origin-x or rotation-origin-y is used on this element".into(),
73 &occupied_entry.get().borrow().span
74 );
75 }
76 std::collections::btree_map::Entry::Vacant(vacant_entry) => {
77 vacant_entry.insert(RefCell::new(expr.into()));
78 }
79 }
80 },
81 );
82}
83
84fn is_image_or_text(e: &ElementRc) -> bool {
86 e.borrow().builtin_type().is_some_and(|bt| matches!(bt.name.as_str(), "Image" | "Text"))
87}