1use super::{Status, StyleFn};
10use iced_core::{Background, Color, Theme, border::Radius};
11
12#[derive(Clone, Copy, Debug)]
14pub struct Style {
15 pub background: Option<Background>,
17
18 pub border_color: Option<Color>,
20
21 pub border_width: f32,
23
24 pub tab_label_background: Background,
26
27 pub tab_label_border_color: Color,
29
30 pub tab_label_border_width: f32,
32
33 pub icon_color: Color,
35
36 pub icon_background: Option<Background>,
38
39 pub icon_border_radius: Radius,
41
42 pub text_color: Color,
44}
45
46impl Default for Style {
47 fn default() -> Self {
48 Self {
49 background: None,
50 border_color: None,
51 border_width: 0.0,
52 tab_label_background: Background::Color([0.87, 0.87, 0.87].into()),
53 tab_label_border_color: [0.7, 0.7, 0.7].into(),
54 tab_label_border_width: 1.0,
55 icon_color: Color::BLACK,
56 icon_background: Some(Background::Color(Color::TRANSPARENT)),
57 icon_border_radius: 4.0.into(),
58 text_color: Color::BLACK,
59 }
60 }
61}
62pub trait Catalog {
64 type Class<'a>;
66
67 fn default<'a>() -> Self::Class<'a>;
69
70 fn style(&self, class: &Self::Class<'_>, status: Status) -> Style;
72}
73
74impl Catalog for Theme {
75 type Class<'a> = StyleFn<'a, Self, Style>;
76
77 fn default<'a>() -> Self::Class<'a> {
78 Box::new(primary)
79 }
80
81 fn style(&self, class: &Self::Class<'_>, status: Status) -> Style {
82 class(self, status)
83 }
84}
85
86#[must_use]
88pub fn primary(theme: &Theme, status: Status) -> Style {
89 let mut base = Style::default();
90 let palette = theme.extended_palette();
91
92 base.text_color = palette.background.base.text;
93
94 match status {
95 Status::Disabled => {
96 base.tab_label_background = Background::Color(palette.background.strong.color);
97 }
98 Status::Hovered => {
99 base.tab_label_background = Background::Color(palette.primary.strong.color);
100 }
101 _ => {
102 base.tab_label_background = Background::Color(palette.primary.base.color);
103 }
104 }
105
106 base
107}
108
109#[must_use]
111pub fn dark(_theme: &Theme, status: Status) -> Style {
112 let mut base = Style {
113 tab_label_background: Background::Color([0.1, 0.1, 0.1].into()),
114 tab_label_border_color: [0.3, 0.3, 0.3].into(),
115 icon_color: Color::WHITE,
116 text_color: Color::WHITE,
117 ..Default::default()
118 };
119
120 if status == Status::Disabled {
121 base.tab_label_background = Background::Color([0.13, 0.13, 0.13].into());
122 }
123
124 base
125}
126
127#[must_use]
129pub fn red(_theme: &Theme, status: Status) -> Style {
130 let mut base = Style {
131 tab_label_background: Background::Color([1.0, 0.0, 0.0].into()),
132 tab_label_border_color: Color::TRANSPARENT,
133 tab_label_border_width: 0.0,
134 icon_color: Color::WHITE,
135 text_color: Color::WHITE,
136 ..Default::default()
137 };
138
139 if status == Status::Disabled {
140 base.tab_label_background = Background::Color([0.13, 0.13, 0.13].into());
141 base.icon_color = Color::BLACK;
142 base.text_color = Color::BLACK;
143 }
144
145 base
146}
147
148#[must_use]
150pub fn blue(_theme: &Theme, status: Status) -> Style {
151 let mut base = Style {
152 tab_label_background: Background::Color([0.0, 0.0, 1.0].into()),
153 tab_label_border_color: [0.0, 0.0, 1.0].into(),
154 icon_color: Color::WHITE,
155 text_color: Color::WHITE,
156 ..Default::default()
157 };
158
159 if status == Status::Disabled {
160 base.tab_label_background = Background::Color([0.5, 0.5, 1.0].into());
161 base.tab_label_border_color = [0.5, 0.5, 1.0].into();
162 }
163
164 base
165}
166
167#[must_use]
169pub fn green(_theme: &Theme, status: Status) -> Style {
170 let mut base = Style {
171 tab_label_background: Color::WHITE.into(),
172 icon_color: [0.0, 0.5, 0.0].into(),
173 text_color: [0.0, 0.5, 0.0].into(),
174 ..Default::default()
175 };
176
177 match status {
178 Status::Disabled => {
179 base.icon_color = [0.7, 0.7, 0.7].into();
180 base.text_color = [0.7, 0.7, 0.7].into();
181 base.tab_label_border_color = [0.7, 0.7, 0.7].into();
182 }
183 _ => {
184 base.tab_label_border_color = [0.0, 0.5, 0.0].into();
185 }
186 }
187
188 base
189}
190
191#[must_use]
193pub fn purple(_theme: &Theme, status: Status) -> Style {
194 let mut base = Style {
195 tab_label_background: Color::WHITE.into(),
196 tab_label_border_color: Color::TRANSPARENT,
197 icon_color: [0.7, 0.0, 1.0].into(),
198 text_color: [0.7, 0.0, 1.0].into(),
199 ..Default::default()
200 };
201
202 if status == Status::Disabled {
203 base.icon_color = Color::BLACK;
204 base.text_color = Color::BLACK;
205 }
206
207 base
208}