Skip to main content

i_slint_compiler/passes/
apply_default_properties_from_style.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 applies the default properties from the style.
5//!
6//! Note that the layout default properties are handled in the lower_layout pass
7
8use crate::diagnostics::BuildDiagnostics;
9use crate::expression_tree::{Expression, NamedReference};
10use crate::langtype::{ElementType, Type};
11use crate::object_tree::Component;
12use smol_str::SmolStr;
13use std::rc::Rc;
14
15/// Ideally we would be able to write this in builtin.slint, but the StyleMetrics is not available there
16pub fn apply_default_properties_from_style(
17    root_component: &Rc<Component>,
18    style_metrics: &Rc<Component>,
19    palette: &Rc<Component>,
20    _diag: &mut BuildDiagnostics,
21) {
22    crate::object_tree::recurse_elem_including_sub_components(
23        root_component,
24        &(),
25        &mut |elem, _| {
26            let mut elem = elem.borrow_mut();
27            let ElementType::Builtin(builtin) = &elem.base_type else { return };
28            let builtin_name = builtin.name.as_str();
29            match builtin_name {
30                "TextInput" => {
31                    elem.set_binding_if_not_set("text-cursor-width".into(), || {
32                        Expression::PropertyReference(NamedReference::new(
33                            &style_metrics.root_element,
34                            SmolStr::new_static("text-cursor-width"),
35                        ))
36                    });
37                    elem.set_binding_if_not_set("color".into(), || {
38                        Expression::PropertyReference(NamedReference::new(
39                            &palette.root_element,
40                            SmolStr::new_static("foreground"),
41                        ))
42                    });
43                    elem.set_binding_if_not_set("selection-background-color".into(), || {
44                        Expression::Cast {
45                            from: Expression::PropertyReference(NamedReference::new(
46                                &palette.root_element,
47                                SmolStr::new_static("selection-background"),
48                            ))
49                            .into(),
50                            to: Type::Color,
51                        }
52                    });
53                    elem.set_binding_if_not_set("selection-foreground-color".into(), || {
54                        Expression::Cast {
55                            from: Expression::PropertyReference(NamedReference::new(
56                                &palette.root_element,
57                                SmolStr::new_static("selection-foreground"),
58                            ))
59                            .into(),
60                            to: Type::Color,
61                        }
62                    });
63                }
64                "Text" | "StyledText" => {
65                    elem.set_binding_if_not_set("color".into(), || Expression::Cast {
66                        from: Expression::PropertyReference(NamedReference::new(
67                            &palette.root_element,
68                            SmolStr::new_static("foreground"),
69                        ))
70                        .into(),
71                        to: Type::Brush,
72                    });
73                }
74                "Dialog" | "Window" => {
75                    elem.set_binding_if_not_set("background".into(), || Expression::Cast {
76                        from: Expression::PropertyReference(NamedReference::new(
77                            &palette.root_element,
78                            SmolStr::new_static("background"),
79                        ))
80                        .into(),
81                        to: Type::Brush,
82                    });
83
84                    let mut bind_style_property_if_exists = |property_name, property_type| {
85                        if !matches!(
86                            style_metrics
87                                .root_element
88                                .borrow()
89                                .lookup_property(property_name)
90                                .property_type,
91                            Type::Invalid,
92                        ) {
93                            elem.set_binding_if_not_set(property_name.into(), || {
94                                Expression::Cast {
95                                    from: Expression::PropertyReference(NamedReference::new(
96                                        &style_metrics.root_element,
97                                        SmolStr::new_static(property_name),
98                                    ))
99                                    .into(),
100                                    to: property_type,
101                                }
102                            });
103                        }
104                    };
105
106                    bind_style_property_if_exists("default-font-family", Type::String);
107                }
108
109                _ => {}
110            }
111        },
112    )
113}