1use embedded_graphics::prelude::*;
4
5#[derive(Debug, Clone)]
7pub struct LegendStyle<C: PixelColor> {
8 pub text: TextStyle<C>,
10 pub symbol: SymbolStyle<C>,
12 pub background: BackgroundStyle<C>,
14 pub spacing: SpacingStyle,
16}
17
18#[derive(Debug, Clone)]
20pub struct TextStyle<C: PixelColor> {
21 pub color: C,
23 pub font_size: u32,
25 pub line_height: u32,
27 pub char_width: u32,
29 pub max_text_width: u32,
31 pub alignment: TextAlignment,
33}
34
35#[derive(Debug, Clone)]
37pub struct SymbolStyle<C: PixelColor> {
38 pub size: u32,
40 pub border_width: u32,
42 pub default_color: C,
44 pub quality: SymbolQuality,
46}
47
48#[derive(Debug, Clone)]
50pub struct BackgroundStyle<C: PixelColor> {
51 pub color: Option<C>,
53 pub border_color: Option<C>,
55 pub border_width: u32,
57 pub corner_radius: u32,
59 pub opacity: u8,
61}
62
63#[derive(Debug, Clone)]
65pub struct SpacingStyle {
66 pub symbol_width: u32,
68 pub symbol_text_gap: u32,
70 pub entry_spacing: u32,
72 pub padding: Padding,
74 pub margins: Margins,
76}
77
78#[derive(Debug, Clone, Copy, PartialEq, Eq)]
80pub enum TextAlignment {
81 Left,
83 Center,
85 Right,
87}
88
89#[derive(Debug, Clone, Copy, PartialEq, Eq)]
91pub enum SymbolQuality {
92 Fast,
94 Standard,
96 High,
98}
99
100#[derive(Debug, Clone, Copy, PartialEq, Eq)]
102pub struct Padding {
103 pub top: u32,
105 pub right: u32,
107 pub bottom: u32,
109 pub left: u32,
111}
112
113#[derive(Debug, Clone, Copy, PartialEq, Eq)]
115pub struct Margins {
116 pub top: u32,
118 pub right: u32,
120 pub bottom: u32,
122 pub left: u32,
124}
125
126impl<C: PixelColor> LegendStyle<C> {
127 pub fn new() -> Self
129 where
130 C: From<embedded_graphics::pixelcolor::Rgb565>,
131 {
132 Self {
133 text: TextStyle::new(),
134 symbol: SymbolStyle::new(),
135 background: BackgroundStyle::new(),
136 spacing: SpacingStyle::new(),
137 }
138 }
139
140 pub fn minimal() -> Self
142 where
143 C: From<embedded_graphics::pixelcolor::Rgb565>,
144 {
145 Self {
146 text: TextStyle::minimal(),
147 symbol: SymbolStyle::minimal(),
148 background: BackgroundStyle::minimal(),
149 spacing: SpacingStyle::minimal(),
150 }
151 }
152
153 pub fn professional() -> Self
155 where
156 C: From<embedded_graphics::pixelcolor::Rgb565>,
157 {
158 Self {
159 text: TextStyle::professional(),
160 symbol: SymbolStyle::professional(),
161 background: BackgroundStyle::professional(),
162 spacing: SpacingStyle::professional(),
163 }
164 }
165
166 pub fn compact() -> Self
168 where
169 C: From<embedded_graphics::pixelcolor::Rgb565>,
170 {
171 Self {
172 text: TextStyle::compact(),
173 symbol: SymbolStyle::compact(),
174 background: BackgroundStyle::compact(),
175 spacing: SpacingStyle::compact(),
176 }
177 }
178}
179
180impl<C: PixelColor> TextStyle<C> {
181 pub fn new() -> Self
183 where
184 C: From<embedded_graphics::pixelcolor::Rgb565>,
185 {
186 Self {
187 color: C::from(embedded_graphics::pixelcolor::Rgb565::BLACK),
188 font_size: 12,
189 line_height: 16,
190 char_width: 6,
191 max_text_width: 120,
192 alignment: TextAlignment::Left,
193 }
194 }
195
196 pub fn minimal() -> Self
198 where
199 C: From<embedded_graphics::pixelcolor::Rgb565>,
200 {
201 Self {
202 color: C::from(embedded_graphics::pixelcolor::Rgb565::BLACK),
203 font_size: 8,
204 line_height: 10,
205 char_width: 4,
206 max_text_width: 60,
207 alignment: TextAlignment::Left,
208 }
209 }
210
211 pub fn professional() -> Self
213 where
214 C: From<embedded_graphics::pixelcolor::Rgb565>,
215 {
216 Self {
217 color: C::from(embedded_graphics::pixelcolor::Rgb565::new(8, 16, 8)), font_size: 14,
219 line_height: 18,
220 char_width: 7,
221 max_text_width: 150,
222 alignment: TextAlignment::Left,
223 }
224 }
225
226 pub fn compact() -> Self
228 where
229 C: From<embedded_graphics::pixelcolor::Rgb565>,
230 {
231 Self {
232 color: C::from(embedded_graphics::pixelcolor::Rgb565::BLACK),
233 font_size: 10,
234 line_height: 12,
235 char_width: 5,
236 max_text_width: 80,
237 alignment: TextAlignment::Left,
238 }
239 }
240}
241
242impl<C: PixelColor> SymbolStyle<C> {
243 pub fn new() -> Self
245 where
246 C: From<embedded_graphics::pixelcolor::Rgb565>,
247 {
248 Self {
249 size: 16,
250 border_width: 1,
251 default_color: C::from(embedded_graphics::pixelcolor::Rgb565::BLUE),
252 quality: SymbolQuality::Standard,
253 }
254 }
255
256 pub fn minimal() -> Self
258 where
259 C: From<embedded_graphics::pixelcolor::Rgb565>,
260 {
261 Self {
262 size: 8,
263 border_width: 0,
264 default_color: C::from(embedded_graphics::pixelcolor::Rgb565::BLUE),
265 quality: SymbolQuality::Fast,
266 }
267 }
268
269 pub fn professional() -> Self
271 where
272 C: From<embedded_graphics::pixelcolor::Rgb565>,
273 {
274 Self {
275 size: 20,
276 border_width: 2,
277 default_color: C::from(embedded_graphics::pixelcolor::Rgb565::new(14, 28, 14)), quality: SymbolQuality::High,
279 }
280 }
281
282 pub fn compact() -> Self
284 where
285 C: From<embedded_graphics::pixelcolor::Rgb565>,
286 {
287 Self {
288 size: 12,
289 border_width: 1,
290 default_color: C::from(embedded_graphics::pixelcolor::Rgb565::BLUE),
291 quality: SymbolQuality::Standard,
292 }
293 }
294}
295
296impl<C: PixelColor> BackgroundStyle<C> {
297 pub fn new() -> Self {
299 Self {
300 color: None, border_color: None,
302 border_width: 0,
303 corner_radius: 0,
304 opacity: 255,
305 }
306 }
307
308 pub fn minimal() -> Self {
310 Self {
311 color: None,
312 border_color: None,
313 border_width: 0,
314 corner_radius: 0,
315 opacity: 255,
316 }
317 }
318
319 pub fn professional() -> Self
321 where
322 C: From<embedded_graphics::pixelcolor::Rgb565>,
323 {
324 Self {
325 color: Some(C::from(embedded_graphics::pixelcolor::Rgb565::new(
326 31, 63, 31,
327 ))), border_color: Some(C::from(embedded_graphics::pixelcolor::Rgb565::new(
329 16, 32, 16,
330 ))), border_width: 1,
332 corner_radius: 4,
333 opacity: 240,
334 }
335 }
336
337 pub fn compact() -> Self {
339 Self {
340 color: None,
341 border_color: None,
342 border_width: 0,
343 corner_radius: 0,
344 opacity: 255,
345 }
346 }
347}
348
349impl SpacingStyle {
350 pub fn new() -> Self {
352 Self {
353 symbol_width: 20,
354 symbol_text_gap: 8,
355 entry_spacing: 4,
356 padding: Padding::all(8),
357 margins: Margins::all(4),
358 }
359 }
360
361 pub fn minimal() -> Self {
363 Self {
364 symbol_width: 12,
365 symbol_text_gap: 4,
366 entry_spacing: 2,
367 padding: Padding::all(2),
368 margins: Margins::all(1),
369 }
370 }
371
372 pub fn professional() -> Self {
374 Self {
375 symbol_width: 24,
376 symbol_text_gap: 12,
377 entry_spacing: 8,
378 padding: Padding::all(12),
379 margins: Margins::all(8),
380 }
381 }
382
383 pub fn compact() -> Self {
385 Self {
386 symbol_width: 16,
387 symbol_text_gap: 6,
388 entry_spacing: 3,
389 padding: Padding::all(4),
390 margins: Margins::all(2),
391 }
392 }
393}
394
395impl Padding {
396 pub const fn all(value: u32) -> Self {
398 Self {
399 top: value,
400 right: value,
401 bottom: value,
402 left: value,
403 }
404 }
405
406 pub const fn symmetric(horizontal: u32, vertical: u32) -> Self {
408 Self {
409 top: vertical,
410 right: horizontal,
411 bottom: vertical,
412 left: horizontal,
413 }
414 }
415
416 pub const fn new(top: u32, right: u32, bottom: u32, left: u32) -> Self {
418 Self {
419 top,
420 right,
421 bottom,
422 left,
423 }
424 }
425
426 pub const fn horizontal(&self) -> u32 {
428 self.left + self.right
429 }
430
431 pub const fn vertical(&self) -> u32 {
433 self.top + self.bottom
434 }
435}
436
437impl Margins {
438 pub const fn all(value: u32) -> Self {
440 Self {
441 top: value,
442 right: value,
443 bottom: value,
444 left: value,
445 }
446 }
447
448 pub const fn symmetric(horizontal: u32, vertical: u32) -> Self {
450 Self {
451 top: vertical,
452 right: horizontal,
453 bottom: vertical,
454 left: horizontal,
455 }
456 }
457
458 pub const fn new(top: u32, right: u32, bottom: u32, left: u32) -> Self {
460 Self {
461 top,
462 right,
463 bottom,
464 left,
465 }
466 }
467
468 pub const fn horizontal(&self) -> u32 {
470 self.left + self.right
471 }
472
473 pub const fn vertical(&self) -> u32 {
475 self.top + self.bottom
476 }
477}
478
479impl<C: PixelColor> Default for LegendStyle<C>
481where
482 C: From<embedded_graphics::pixelcolor::Rgb565>,
483{
484 fn default() -> Self {
485 Self::new()
486 }
487}
488
489impl<C: PixelColor> Default for TextStyle<C>
490where
491 C: From<embedded_graphics::pixelcolor::Rgb565>,
492{
493 fn default() -> Self {
494 Self::new()
495 }
496}
497
498impl<C: PixelColor> Default for SymbolStyle<C>
499where
500 C: From<embedded_graphics::pixelcolor::Rgb565>,
501{
502 fn default() -> Self {
503 Self::new()
504 }
505}
506
507impl<C: PixelColor> Default for BackgroundStyle<C> {
508 fn default() -> Self {
509 Self::new()
510 }
511}
512
513impl Default for SpacingStyle {
514 fn default() -> Self {
515 Self::new()
516 }
517}
518
519impl Default for TextAlignment {
520 fn default() -> Self {
521 Self::Left
522 }
523}
524
525impl Default for SymbolQuality {
526 fn default() -> Self {
527 Self::Standard
528 }
529}
530
531impl Default for Padding {
532 fn default() -> Self {
533 Self::all(4)
534 }
535}
536
537impl Default for Margins {
538 fn default() -> Self {
539 Self::all(2)
540 }
541}