Skip to main content

fret_ui_kit/recipes/
control.rs

1use fret_core::{Color, Px};
2use fret_ui::Theme;
3
4use crate::{ChromeRefinement, ColorRef, MetricRef};
5
6#[derive(Debug, Clone, Copy)]
7pub struct ControlTokenKeys {
8    pub padding_x: Option<&'static str>,
9    pub padding_y: Option<&'static str>,
10    pub min_height: Option<&'static str>,
11    pub radius: Option<&'static str>,
12    pub border_width: Option<&'static str>,
13    pub background: Option<&'static str>,
14    pub border_color: Option<&'static str>,
15    pub text_color: Option<&'static str>,
16    pub text_px: Option<&'static str>,
17}
18
19#[derive(Debug, Clone, Copy)]
20pub struct ControlFallbacks {
21    pub padding_x: Px,
22    pub padding_y: Px,
23    pub min_height: Px,
24    pub radius: Px,
25    pub border_width: Px,
26    pub background: Color,
27    pub border_color: Color,
28    pub text_color: Color,
29    pub text_px: Px,
30}
31
32#[derive(Debug, Clone, Copy)]
33pub struct ResolvedControlChrome {
34    pub padding_x: Px,
35    pub padding_y: Px,
36    pub min_height: Px,
37    pub radius: Px,
38    pub border_width: Px,
39    pub background: Color,
40    pub border_color: Color,
41    pub text_color: Color,
42    pub text_px: Px,
43}
44
45fn resolve_metric(
46    theme: &Theme,
47    style: Option<&MetricRef>,
48    key: Option<&'static str>,
49    fallback: Px,
50) -> Px {
51    let v = style
52        .map(|m| m.resolve(theme))
53        .or_else(|| key.and_then(|k| theme.metric_by_key(k)))
54        .unwrap_or(fallback);
55    Px(v.0.max(0.0))
56}
57
58fn resolve_color(
59    theme: &Theme,
60    style: Option<&ColorRef>,
61    key: Option<&'static str>,
62    fallback: Color,
63) -> Color {
64    style
65        .map(|c| c.resolve(theme))
66        .or_else(|| key.and_then(|k| theme.color_by_key(k)))
67        .unwrap_or(fallback)
68}
69
70pub fn resolve_control_chrome(
71    theme: &Theme,
72    style: &ChromeRefinement,
73    keys: ControlTokenKeys,
74    fallback: ControlFallbacks,
75) -> ResolvedControlChrome {
76    ResolvedControlChrome {
77        padding_x: resolve_metric(
78            theme,
79            style
80                .padding
81                .as_ref()
82                .and_then(|p| p.left.as_ref().or(p.right.as_ref())),
83            keys.padding_x,
84            fallback.padding_x,
85        ),
86        padding_y: resolve_metric(
87            theme,
88            style
89                .padding
90                .as_ref()
91                .and_then(|p| p.top.as_ref().or(p.bottom.as_ref())),
92            keys.padding_y,
93            fallback.padding_y,
94        ),
95        min_height: resolve_metric(
96            theme,
97            style.min_height.as_ref(),
98            keys.min_height,
99            fallback.min_height,
100        ),
101        radius: resolve_metric(theme, style.radius.as_ref(), keys.radius, fallback.radius),
102        border_width: resolve_metric(
103            theme,
104            style.border_width.as_ref(),
105            keys.border_width,
106            fallback.border_width,
107        ),
108        background: resolve_color(
109            theme,
110            style.background.as_ref(),
111            keys.background,
112            fallback.background,
113        ),
114        border_color: resolve_color(
115            theme,
116            style.border_color.as_ref(),
117            keys.border_color,
118            fallback.border_color,
119        ),
120        text_color: resolve_color(
121            theme,
122            style.text_color.as_ref(),
123            keys.text_color,
124            fallback.text_color,
125        ),
126        text_px: resolve_metric(theme, None, keys.text_px, fallback.text_px),
127    }
128}