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