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" => {
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                "StyledText" => {
75                    elem.set_binding_if_not_set("default-color".into(), || Expression::Cast {
76                        from: Expression::PropertyReference(NamedReference::new(
77                            &palette.root_element,
78                            SmolStr::new_static("foreground"),
79                        ))
80                        .into(),
81                        to: Type::Brush,
82                    });
83                }
84                "Dialog" | "Window" => {
85                    elem.set_binding_if_not_set("background".into(), || Expression::Cast {
86                        from: Expression::PropertyReference(NamedReference::new(
87                            &palette.root_element,
88                            SmolStr::new_static("background"),
89                        ))
90                        .into(),
91                        to: Type::Brush,
92                    });
93
94                    let mut bind_style_property_if_exists = |property_name, property_type| {
95                        if !matches!(
96                            style_metrics
97                                .root_element
98                                .borrow()
99                                .lookup_property(property_name)
100                                .property_type,
101                            Type::Invalid,
102                        ) {
103                            elem.set_binding_if_not_set(property_name.into(), || {
104                                Expression::Cast {
105                                    from: Expression::PropertyReference(NamedReference::new(
106                                        &style_metrics.root_element,
107                                        SmolStr::new_static(property_name),
108                                    ))
109                                    .into(),
110                                    to: property_type,
111                                }
112                            });
113                        }
114                    };
115
116                    bind_style_property_if_exists("default-font-family", Type::String);
117                }
118
119                _ => {}
120            }
121        },
122    )
123}