1use indexmap::IndexMap;
2use peniko::{Brush, Color, Gradient};
3
4#[derive(Clone, Debug)]
6pub struct Style {
7 map: IndexMap<String, StyleVal>,
8}
9
10impl Style {
11 pub fn new() -> Self {
13 Self {
14 map: IndexMap::with_capacity(16),
15 }
16 }
17
18 pub fn from_values(values: impl IntoIterator<Item = (String, StyleVal)>) -> Self {
20 Self {
21 map: IndexMap::from_iter(values),
22 }
23 }
24
25 pub fn remove(&mut self, name: impl ToString) {
27 self.map.swap_remove(&name.to_string());
28 }
29
30 pub fn with_value(mut self, name: impl ToString, value: StyleVal) -> Self {
32 self.map.insert(name.to_string(), value);
33 self
34 }
35
36 pub fn set(&mut self, name: impl ToString, value: StyleVal) {
38 self.map.insert(name.to_string(), value);
39 }
40
41 pub fn set_color(&mut self, name: impl ToString, color: Color) {
43 self.map.insert(name.to_string(), StyleVal::Color(color));
44 }
45
46 pub fn set_gradient(&mut self, name: impl ToString, gradient: Gradient) {
48 self.map
49 .insert(name.to_string(), StyleVal::Gradient(gradient));
50 }
51
52 pub fn set_bool(&mut self, name: impl ToString, value: bool) {
54 self.map.insert(name.to_string(), StyleVal::Bool(value));
55 }
56
57 pub fn set_brush(&mut self, name: impl ToString, brush: Brush) {
59 self.map.insert(name.to_string(), StyleVal::Brush(brush));
60 }
61
62 pub fn set_float(&mut self, name: impl ToString, value: f32) {
64 self.map.insert(name.to_string(), StyleVal::Float(value));
65 }
66
67 pub fn set_int(&mut self, name: impl ToString, value: i32) {
69 self.map.insert(name.to_string(), StyleVal::Int(value));
70 }
71
72 pub fn set_uint(&mut self, name: impl ToString, value: u32) {
74 self.map.insert(name.to_string(), StyleVal::UInt(value));
75 }
76
77 pub fn get(&self, name: impl ToString) -> Option<StyleVal> {
79 self.map.get(&name.to_string()).cloned()
80 }
81
82 pub fn get_color(&self, name: impl ToString) -> Option<Color> {
84 if let Some(val) = self.map.get(&name.to_string()) {
85 match val {
86 StyleVal::Color(color) => Some(*color),
87 _ => None,
88 }
89 } else {
90 None
91 }
92 }
93
94 pub fn get_gradient(&self, name: impl ToString) -> Option<Gradient> {
96 if let Some(val) = self.map.get(&name.to_string()) {
97 match val {
98 StyleVal::Gradient(gradient) => Some(gradient.clone()),
99 _ => None,
100 }
101 } else {
102 None
103 }
104 }
105
106 pub fn get_brush(&self, name: impl ToString) -> Option<Brush> {
108 if let Some(val) = self.map.get(&name.to_string()) {
109 match val {
110 StyleVal::Brush(brush) => Some(brush.clone()),
111 _ => None,
112 }
113 } else {
114 None
115 }
116 }
117
118 pub fn get_float(&self, name: impl ToString) -> Option<f32> {
120 if let Some(val) = self.map.get(&name.to_string()) {
121 match val {
122 StyleVal::Float(float) => Some(*float),
123 _ => None,
124 }
125 } else {
126 None
127 }
128 }
129
130 pub fn get_int(&self, name: impl ToString) -> Option<i32> {
132 if let Some(val) = self.map.get(&name.to_string()) {
133 match val {
134 StyleVal::Int(int) => Some(*int),
135 _ => None,
136 }
137 } else {
138 None
139 }
140 }
141
142 pub fn get_uint(&self, name: impl ToString) -> Option<u32> {
144 if let Some(val) = self.map.get(&name.to_string()) {
145 match val {
146 StyleVal::UInt(uint) => Some(*uint),
147 _ => None,
148 }
149 } else {
150 None
151 }
152 }
153
154 pub fn get_bool(&self, name: impl ToString) -> Option<bool> {
156 if let Some(val) = self.map.get(&name.to_string()) {
157 match val {
158 StyleVal::Bool(bool) => Some(*bool),
159 _ => None,
160 }
161 } else {
162 None
163 }
164 }
165}
166
167impl Default for Style {
168 fn default() -> Self {
169 Self::new()
170 }
171}
172
173#[derive(Clone, PartialEq, Debug)]
175pub struct DefaultStyles {
176 text: DefaultTextStyles,
177 container: DefaultContainerStyles,
178 interactive: DefaultInteractiveStyles,
179}
180
181impl DefaultStyles {
182 pub fn new(
184 text: DefaultTextStyles,
185 container: DefaultContainerStyles,
186 interactive: DefaultInteractiveStyles,
187 ) -> Self {
188 Self {
189 text,
190 container,
191 interactive,
192 }
193 }
194
195 pub fn text(&self) -> &DefaultTextStyles {
197 &self.text
198 }
199
200 pub fn container(&self) -> &DefaultContainerStyles {
202 &self.container
203 }
204
205 pub fn interactive(&self) -> &DefaultInteractiveStyles {
207 &self.interactive
208 }
209}
210
211#[derive(Clone, PartialEq, Debug)]
213pub struct DefaultTextStyles {
214 foreground: Color,
215 background: Color,
216}
217
218impl DefaultTextStyles {
219 pub fn new(foreground: Color, background: Color) -> Self {
221 Self {
222 foreground,
223 background,
224 }
225 }
226
227 pub fn foreground(&self) -> Color {
229 self.foreground
230 }
231
232 pub fn background(&self) -> Color {
234 self.background
235 }
236}
237
238#[derive(Clone, PartialEq, Debug)]
240pub struct DefaultContainerStyles {
241 foreground: Color,
242 background: Color,
243}
244
245impl DefaultContainerStyles {
246 pub fn new(foreground: Color, background: Color) -> Self {
248 Self {
249 foreground,
250 background,
251 }
252 }
253
254 pub fn foreground(&self) -> Color {
256 self.foreground
257 }
258
259 pub fn background(&self) -> Color {
261 self.background
262 }
263}
264
265#[derive(Clone, PartialEq, Debug)]
267pub struct DefaultInteractiveStyles {
268 active: Color,
269 inactive: Color,
270 hover: Color,
271 disabled: Color,
272}
273
274impl DefaultInteractiveStyles {
275 pub fn new(active: Color, inactive: Color, hover: Color, disabled: Color) -> Self {
277 Self {
278 active,
279 inactive,
280 hover,
281 disabled,
282 }
283 }
284
285 pub fn active(&self) -> Color {
287 self.active
288 }
289
290 pub fn inactive(&self) -> Color {
292 self.inactive
293 }
294
295 pub fn hover(&self) -> Color {
297 self.hover
298 }
299
300 pub fn disabled(&self) -> Color {
302 self.disabled
303 }
304}
305
306#[derive(Clone, Debug)]
308pub enum StyleVal {
309 Color(Color),
311 Gradient(Gradient),
313 Brush(Brush),
315 Float(f32),
317 Int(i32),
319 UInt(u32),
321 Bool(bool),
323}