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, PropertyLookupMode, Type};
11use crate::object_tree::Component;
12use smol_str::SmolStr;
13use std::rc::Rc;
14
15/// Ideally the builtin element declarations would set these defaults, 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    // There are no styles in Slint SC; the defaults are part of the
23    // generated code
24    #[cfg(feature = "slint-sc")]
25    if _diag.slint_sc {
26        return;
27    }
28    crate::object_tree::recurse_elem_including_sub_components(
29        root_component,
30        &(),
31        &mut |elem, _| {
32            let mut elem = elem.borrow_mut();
33            let ElementType::Builtin(builtin) = &elem.base_type else { return };
34            let builtin_name = builtin.name.as_str();
35            match builtin_name {
36                "TextInput" => {
37                    elem.set_binding_if_not_set("text-cursor-width".into(), || {
38                        Expression::PropertyReference(NamedReference::new(
39                            &style_metrics.root_element,
40                            SmolStr::new_static("text-cursor-width"),
41                        ))
42                    });
43                    elem.set_binding_if_not_set("color".into(), || {
44                        Expression::PropertyReference(NamedReference::new(
45                            &palette.root_element,
46                            SmolStr::new_static("foreground"),
47                        ))
48                    });
49                    elem.set_binding_if_not_set("selection-background-color".into(), || {
50                        Expression::Cast {
51                            from: Expression::PropertyReference(NamedReference::new(
52                                &palette.root_element,
53                                SmolStr::new_static("selection-background"),
54                            ))
55                            .into(),
56                            to: Type::Color,
57                        }
58                    });
59                    elem.set_binding_if_not_set("selection-foreground-color".into(), || {
60                        Expression::Cast {
61                            from: Expression::PropertyReference(NamedReference::new(
62                                &palette.root_element,
63                                SmolStr::new_static("selection-foreground"),
64                            ))
65                            .into(),
66                            to: Type::Color,
67                        }
68                    });
69                }
70                "Text" => {
71                    elem.set_binding_if_not_set("color".into(), || Expression::Cast {
72                        from: Expression::PropertyReference(NamedReference::new(
73                            &palette.root_element,
74                            SmolStr::new_static("foreground"),
75                        ))
76                        .into(),
77                        to: Type::Brush,
78                    });
79                }
80                "StyledText" => {
81                    elem.set_binding_if_not_set("default-color".into(), || Expression::Cast {
82                        from: Expression::PropertyReference(NamedReference::new(
83                            &palette.root_element,
84                            SmolStr::new_static("foreground"),
85                        ))
86                        .into(),
87                        to: Type::Brush,
88                    });
89                }
90                "Dialog" | "Window" => {
91                    elem.set_binding_if_not_set("background".into(), || Expression::Cast {
92                        from: Expression::PropertyReference(NamedReference::new(
93                            &palette.root_element,
94                            SmolStr::new_static("background"),
95                        ))
96                        .into(),
97                        to: Type::Brush,
98                    });
99
100                    let mut bind_style_property_if_exists = |property_name, property_type| {
101                        if !matches!(
102                            style_metrics
103                                .root_element
104                                .borrow()
105                                .lookup_property(property_name, PropertyLookupMode::ComponentLocal)
106                                .property_type,
107                            Type::Invalid,
108                        ) {
109                            elem.set_binding_if_not_set(property_name.into(), || {
110                                Expression::Cast {
111                                    from: Expression::PropertyReference(NamedReference::new(
112                                        &style_metrics.root_element,
113                                        SmolStr::new_static(property_name),
114                                    ))
115                                    .into(),
116                                    to: property_type,
117                                }
118                            });
119                        }
120                    };
121
122                    bind_style_property_if_exists("default-font-family", Type::String);
123                }
124
125                _ => {}
126            }
127        },
128    )
129}