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}