Skip to main content

freya_devtools_app/
property.rs

1use freya::prelude::*;
2use freya_core::style::color::Color;
3
4const NAME_COLOR: (u8, u8, u8) = (102, 163, 217);
5const SEPARATOR_COLOR: (u8, u8, u8) = (215, 215, 215);
6const VALUE_COLOR: (u8, u8, u8) = (252, 181, 172);
7
8fn color_swatch(color: Color) -> impl IntoElement {
9    rect()
10        .width(Size::px(17.))
11        .height(Size::px(17.))
12        .corner_radius(CornerRadius::new_all(5.))
13        .background(Color::WHITE)
14        .padding(2.5)
15        .child(
16            rect()
17                .corner_radius(CornerRadius::new_all(3.))
18                .width(Size::fill())
19                .height(Size::fill())
20                .background(color),
21        )
22}
23
24/// A single `name: value` row in a node inspector tab.
25///
26/// Use [`Property::swatch`] to append a color preview, shared by the color,
27/// shadow, border and text shadow attributes.
28#[derive(Clone, PartialEq)]
29pub struct Property {
30    name: String,
31    value: String,
32    swatch: Option<(Color, String)>,
33}
34
35impl Property {
36    pub fn new(name: impl Into<String>, value: impl Into<String>) -> Self {
37        Self {
38            name: name.into(),
39            value: value.into(),
40            swatch: None,
41        }
42    }
43
44    /// Appends a color swatch followed by `label` to the row.
45    pub fn swatch(mut self, color: Color, label: impl Into<String>) -> Self {
46        self.swatch = Some((color, label.into()));
47        self
48    }
49}
50
51impl Component for Property {
52    fn render(&self) -> impl IntoElement {
53        rect()
54            .overflow(Overflow::Clip)
55            .width(Size::fill())
56            .horizontal()
57            .cross_align(Alignment::center())
58            .child(
59                paragraph()
60                    .font_size(15.)
61                    .maybe(self.swatch.is_none(), |p| p.width(Size::fill()))
62                    .span(Span::new(self.name.clone()).color(NAME_COLOR))
63                    .span(Span::new(": ").color(SEPARATOR_COLOR))
64                    .span(Span::new(self.value.clone()).color(VALUE_COLOR)),
65            )
66            .map(self.swatch.clone(), |row, (color, label_text)| {
67                row.child(rect().width(Size::px(5.)))
68                    .child(color_swatch(color))
69                    .child(rect().width(Size::px(5.)))
70                    .child(
71                        label()
72                            .font_size(15.)
73                            .color(Color::from_rgb(VALUE_COLOR.0, VALUE_COLOR.1, VALUE_COLOR.2))
74                            .text(label_text),
75                    )
76            })
77    }
78}
79
80/// A `name: value` row for fills, kept separate so gradients can wrap onto
81/// multiple lines instead of being clipped.
82#[derive(Clone, PartialEq)]
83pub struct FillProperty {
84    name: String,
85    fill: Fill,
86}
87
88impl FillProperty {
89    pub fn new(name: impl Into<String>, fill: Fill) -> Self {
90        Self {
91            name: name.into(),
92            fill,
93        }
94    }
95}
96
97impl Component for FillProperty {
98    fn render(&self) -> impl IntoElement {
99        paragraph()
100            .line_height(1.9)
101            .font_size(15.)
102            .span(Span::new(self.name.to_string()).color(NAME_COLOR))
103            .span(Span::new(": ").color(SEPARATOR_COLOR))
104            .span(Span::new(format!("{:?}", self.fill)).color(VALUE_COLOR))
105    }
106}