Skip to main content

i_slint_compiler/passes/
deprecated_rotation_origin.rs

1// Copyright © SixtyFPS GmbH <info@slint.dev>
2// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0
3
4//! This pass handles the deprecated `rotation-origin-*` properties on Text and Image that were replaced by `transform-origin`
5
6use 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
84/// true if this element had a rotation-origin property
85fn is_image_or_text(e: &ElementRc) -> bool {
86    e.borrow().builtin_type().is_some_and(|bt| matches!(bt.name.as_str(), "Image" | "Text"))
87}