embedded_ui/
style.rs

1pub mod monochrome;
2
3use crate::{
4    color::UiColor,
5    kit::{button::ButtonStyler, select::SelectStyler, slider::SliderStyler},
6};
7
8pub trait Styler<C: UiColor>:
9    ButtonStyler<C> + SelectStyler<C> + SliderStyler<C> + Default
10{
11}
12
13macro_rules! component_style {
14    ($vis: vis $name: ident $(: $styler: ident ($status: ty))? {
15        $($prop: ident: $prop_kind: ident $({
16            $($method: ident: $method_kind: ident),* $(,)?
17        })?),* $(,)?
18    }) => {
19        $(
20            $vis trait $styler<C: $crate::color::UiColor> {
21                type Class<'a>;
22
23                fn default<'a>() -> Self::Class<'a>;
24                fn style(&self, class: &Self::Class<'_>, status: $status) -> $name<C>;
25            }
26        )?
27
28        $vis struct $name<C: $crate::color::UiColor> {
29            $($prop: $crate::style::component_style!(@field $prop_kind)),*
30        }
31
32        impl<C: $crate::color::UiColor> $name<C> {
33            pub fn new() -> Self {
34                Self {
35                    $($prop: $crate::style::component_style!(@init $prop_kind)),*
36                }
37            }
38
39            $($crate::style::component_style!{ @build $prop: $prop_kind $({ $($method: $method_kind),* })? })*
40        }
41    };
42
43    // Fields //
44    (@field background) => {
45        C
46    };
47
48    (@field color) => {
49        C
50    };
51
52    (@field border) => {
53        $crate::block::Border<C>
54    };
55
56    // FIXME: Width is not the right word
57    (@field width) => {
58        u32
59    };
60
61    // Constructor //
62    (@init background) => {
63        C::default_background()
64    };
65
66    (@init border) => {
67        $crate::block::Border::new()
68    };
69
70    (@init color) => {
71        C::default_foreground()
72    };
73
74    (@init width) => {
75        // TODO: Defaults
76        1
77    };
78
79    // Builders //
80    (@build $name: ident: background) => {
81        pub fn $name(mut self, background: impl Into<C>) -> Self {
82            self.$name = background.into();
83            self
84        }
85    };
86
87    (@build_method $field: ident . border $method: ident: border_color) => {
88        pub fn $method(mut self, color: impl Into<C>) -> Self {
89            self.$field.color = color.into();
90            self
91        }
92    };
93
94    (@build_method $field: ident . border $method: ident: border_width) => {
95        pub fn $method(mut self, width: u32) -> Self {
96            self.$field.width = width;
97            self
98        }
99    };
100
101    (@build_method $field: ident . border $method: ident: border_radius) => {
102        pub fn $method(mut self, radius: impl Into<$crate::block::BorderRadius>) -> Self {
103            self.$field.radius = radius.into();
104            self
105        }
106    };
107
108    (@build $field: ident: border) => {
109        $crate::style::component_style! {@build $field: border {
110            border_color: border_color,
111            border_width: border_width,
112            border_radius: border_radius
113        }}
114    };
115
116    (@build $field: ident: border {$($method: ident: $method_kind: ident),*}) => {
117        $($crate::style::component_style! {
118            @build_method $field.border $method: $method_kind
119        })*
120    };
121
122    (@build $name: ident: color) => {
123        pub fn $name(mut self, color: impl Into<C>) -> Self {
124            self.$name = color.into();
125            self
126        }
127    };
128
129    (@build $name: ident: width) => {
130        pub fn $name(mut self, width: u32) -> Self {
131            self.$name = width;
132            self
133        }
134    };
135}
136
137pub(crate) use component_style;
138
139// component_style!(Test: TestStyler(()) { background, border });