i_slint_compiler/passes/
lower_absolute_coordinates.rs1use smol_str::SmolStr;
8use std::cell::RefCell;
9use std::rc::Rc;
10
11use crate::expression_tree::{BuiltinFunction, Expression};
12use crate::langtype::Type;
13use crate::namedreference::NamedReference;
14use crate::object_tree::Component;
15
16pub fn lower_absolute_coordinates(component: &Rc<Component>) {
17 let mut to_materialize = std::collections::HashSet::new();
18
19 crate::object_tree::visit_all_named_references(component, &mut |nr| {
20 if nr.name() == "absolute-position" {
21 to_materialize.insert(nr.clone());
22 }
23 });
24
25 let Type::Struct(point_type) = BuiltinFunction::ItemAbsolutePosition.ty().return_type.clone()
26 else {
27 unreachable!()
28 };
29
30 for nr in to_materialize {
31 let elem = nr.element();
32
33 let parent_position_var = Box::new(Expression::ReadLocalVariable {
37 name: "parent_position".into(),
38 ty: point_type.clone().into(),
39 });
40
41 let binding = Expression::CodeBlock(vec![
42 Expression::StoreLocalVariable {
43 name: "parent_position".into(),
44 value: Expression::FunctionCall {
45 function: BuiltinFunction::ItemAbsolutePosition.into(),
46 arguments: vec![Expression::ElementReference(Rc::downgrade(&elem))],
47 source_location: None,
48 }
49 .into(),
50 },
51 Expression::Struct {
52 ty: point_type.clone(),
53 values: IntoIterator::into_iter(["x", "y"])
54 .map(|coord| {
55 (
56 coord.into(),
57 Expression::BinaryExpression {
58 lhs: Expression::StructFieldAccess {
59 base: parent_position_var.clone(),
60 name: coord.into(),
61 }
62 .into(),
63 rhs: Expression::PropertyReference(NamedReference::new(
64 &elem,
65 SmolStr::new_static(coord),
66 ))
67 .into(),
68 op: '+',
69 },
70 )
71 })
72 .collect(),
73 },
74 ]);
75
76 elem.borrow_mut().bindings.insert(nr.name().clone(), RefCell::new(binding.into()));
77 }
78}