1use super::{Status, StyleFn, colors};
5use iced_core::{Background, Color, Theme, theme::palette};
6
7#[derive(Clone, Copy, Debug)]
9pub struct Style {
10 pub background: Background,
12
13 pub border_radius: Option<f32>,
16
17 pub border_width: f32,
19
20 pub border_color: Option<Color>,
22
23 pub text_color: Color,
25}
26
27pub trait Catalog {
29 type Class<'a>;
31
32 fn default<'a>() -> Self::Class<'a>;
34
35 fn style(&self, class: &Self::Class<'_>, status: Status) -> Style;
37}
38
39impl std::default::Default for Style {
40 fn default() -> Self {
41 Self {
42 background: Background::Color([0.87, 0.87, 0.87].into()),
43 border_radius: None,
44 border_width: 1.0,
45 border_color: Some([0.8, 0.8, 0.8].into()),
46 text_color: Color::BLACK,
47 }
48 }
49}
50
51impl Catalog for Theme {
52 type Class<'a> = StyleFn<'a, Self, Style>;
53
54 fn default<'a>() -> Self::Class<'a> {
55 Box::new(primary)
56 }
57
58 fn style(&self, class: &Self::Class<'_>, status: Status) -> Style {
59 class(self, status)
60 }
61}
62
63#[must_use]
65pub fn primary(theme: &Theme, status: Status) -> Style {
66 let palette = theme.extended_palette();
67 let base = styled(palette.primary.strong);
68
69 match status {
70 Status::Hovered => Style {
71 background: Background::Color(palette.primary.base.color),
72 ..base
73 },
74 Status::Disabled => disabled(base),
75 _ => base,
76 }
77}
78
79#[must_use]
81pub fn secondary(theme: &Theme, status: Status) -> Style {
82 let palette = theme.extended_palette();
83 let base = styled(palette.secondary.strong);
84
85 match status {
86 Status::Hovered => Style {
87 background: Background::Color(palette.primary.base.color),
88 ..base
89 },
90 Status::Disabled => disabled(base),
91 _ => base,
92 }
93}
94
95#[must_use]
97pub fn success(theme: &Theme, status: Status) -> Style {
98 let palette = theme.extended_palette();
99 let base = styled(palette.success.strong);
100
101 match status {
102 Status::Hovered => Style {
103 background: Background::Color(palette.primary.base.color),
104 ..base
105 },
106 Status::Disabled => disabled(base),
107 _ => base,
108 }
109}
110
111#[must_use]
113pub fn danger(theme: &Theme, status: Status) -> Style {
114 let palette = theme.extended_palette();
115 let base = styled(palette.danger.strong);
116
117 match status {
118 Status::Hovered => Style {
119 background: Background::Color(palette.primary.base.color),
120 ..base
121 },
122 Status::Disabled => disabled(base),
123 _ => base,
124 }
125}
126
127#[must_use]
129pub fn warning(_theme: &Theme, status: Status) -> Style {
130 let base = from_color(colors::WARNING, colors::BLACK);
131
132 match status {
133 Status::Disabled => disabled(base),
134 _ => base,
135 }
136}
137
138#[must_use]
140pub fn info(_theme: &Theme, status: Status) -> Style {
141 let base = from_color(colors::INFO, colors::BLACK);
142
143 match status {
144 Status::Disabled => disabled(base),
145 _ => base,
146 }
147}
148
149#[must_use]
151pub fn light(_theme: &Theme, status: Status) -> Style {
152 let base = from_color(colors::LIGHT, colors::BLACK);
153
154 match status {
155 Status::Disabled => disabled(base),
156 _ => base,
157 }
158}
159
160#[must_use]
162pub fn dark(_theme: &Theme, status: Status) -> Style {
163 let base = from_color(colors::DARK, colors::WHITE);
164
165 match status {
166 Status::Disabled => disabled(base),
167 _ => base,
168 }
169}
170
171#[must_use]
173pub fn white(_theme: &Theme, status: Status) -> Style {
174 let base = from_color(colors::WHITE, colors::BLACK);
175
176 match status {
177 Status::Disabled => disabled(base),
178 _ => base,
179 }
180}
181
182fn from_color(color: Color, text_color: Color) -> Style {
183 Style {
184 background: Background::Color(color),
185 border_color: Some(color),
186 text_color,
187 ..Style::default()
188 }
189}
190
191fn styled(pair: palette::Pair) -> Style {
192 Style {
193 background: Background::Color(pair.color),
194 border_color: Some(pair.color),
195 text_color: pair.text,
196 ..Style::default()
197 }
198}
199
200fn disabled(style: Style) -> Style {
201 Style {
202 background: style.background.scale_alpha(0.5),
203 text_color: style.text_color.scale_alpha(0.5),
204 ..style
205 }
206}