1#[cfg(test)]
2mod tests;
3
4use iced::{Color, color};
5
6pub trait ColorScheme {
7 fn primary(&self) -> Color;
8 fn on_primary(&self) -> Color;
9 fn primary_container(&self) -> Color;
10 fn on_primary_container(&self) -> Color;
11 fn primary_fixed(&self) -> Color;
12 fn on_primary_fixed(&self) -> Color;
13 fn primary_fixed_dim(&self) -> Color;
14 fn on_primary_fixed_variant(&self) -> Color;
15 fn inverse_primary(&self) -> Color;
16
17 fn secondary(&self) -> Color;
18 fn on_secondary(&self) -> Color;
19 fn secondary_container(&self) -> Color;
20 fn on_secondary_container(&self) -> Color;
21 fn secondary_fixed(&self) -> Color;
22 fn on_secondary_fixed(&self) -> Color;
23 fn secondary_fixed_dim(&self) -> Color;
24 fn on_secondary_fixed_variant(&self) -> Color;
25
26 fn tertiary(&self) -> Color;
27 fn on_tertiary(&self) -> Color;
28 fn tertiary_container(&self) -> Color;
29 fn on_tertiary_container(&self) -> Color;
30 fn tertiary_fixed(&self) -> Color;
31 fn on_tertiary_fixed(&self) -> Color;
32 fn tertiary_fixed_dim(&self) -> Color;
33 fn on_tertiary_fixed_variant(&self) -> Color;
34
35 fn error(&self) -> Color;
36 fn on_error(&self) -> Color;
37 fn error_container(&self) -> Color;
38 fn on_error_container(&self) -> Color;
39
40 fn surface(&self) -> Color;
41 fn on_surface(&self) -> Color;
42 fn surface_variant(&self) -> Color;
43 fn on_surface_variant(&self) -> Color;
44 fn surface_container_highest(&self) -> Color;
45 fn surface_container_high(&self) -> Color;
46 fn surface_container(&self) -> Color;
47 fn surface_container_low(&self) -> Color;
48 fn surface_container_lowest(&self) -> Color;
49 fn inverse_surface(&self) -> Color;
50 fn inverse_on_surface(&self) -> Color;
51
52 fn background(&self) -> Color;
53 fn on_background(&self) -> Color;
54 fn surface_bright(&self) -> Color;
55 fn surface_dim(&self) -> Color;
56 fn scrim(&self) -> Color;
57 fn shadow(&self) -> Color;
58 fn outline(&self) -> Color;
59 fn outline_variant(&self) -> Color;
60}
61
62#[derive(Debug, Clone, Copy)]
63pub struct Palette {
64 pub primary: Color,
65 pub on_primary: Color,
66 pub primary_container: Color,
67 pub on_primary_container: Color,
68 pub primary_fixed: Color,
69 pub on_primary_fixed: Color,
70 pub primary_fixed_dim: Color,
71 pub on_primary_fixed_variant: Color,
72 pub inverse_primary: Color,
73
74 pub secondary: Color,
75 pub on_secondary: Color,
76 pub secondary_container: Color,
77 pub on_secondary_container: Color,
78 pub secondary_fixed: Color,
79 pub on_secondary_fixed: Color,
80 pub secondary_fixed_dim: Color,
81 pub on_secondary_fixed_variant: Color,
82
83 pub tertiary: Color,
84 pub on_tertiary: Color,
85 pub tertiary_container: Color,
86 pub on_tertiary_container: Color,
87 pub tertiary_fixed: Color,
88 pub on_tertiary_fixed: Color,
89 pub tertiary_fixed_dim: Color,
90 pub on_tertiary_fixed_variant: Color,
91
92 pub error: Color,
93 pub on_error: Color,
94 pub error_container: Color,
95 pub on_error_container: Color,
96
97 pub surface: Color,
98 pub on_surface: Color,
99 pub surface_variant: Color,
100 pub on_surface_variant: Color,
101 pub surface_container_highest: Color,
102 pub surface_container_high: Color,
103 pub surface_container: Color,
104 pub surface_container_low: Color,
105 pub surface_container_lowest: Color,
106 pub inverse_surface: Color,
107 pub inverse_on_surface: Color,
108 pub background: Color,
109 pub on_background: Color,
110 pub surface_bright: Color,
111 pub surface_dim: Color,
112 pub scrim: Color,
113 pub shadow: Color,
114
115 pub outline: Color,
116 pub outline_variant: Color,
117}
118
119impl Palette {
120 pub fn default_dark() -> Self {
122 Self {
123 primary: color!(0xD0BCFF),
124 on_primary: color!(0x381E72),
125 primary_container: color!(0x4F378B),
126 on_primary_container: color!(0xEADDFF),
127 primary_fixed: color!(0xEADDFF),
128 on_primary_fixed: color!(0x21005D),
129 primary_fixed_dim: color!(0xD0BCFF),
130 on_primary_fixed_variant: color!(0x4F378B),
131 inverse_primary: color!(0x6750A4),
132
133 secondary: color!(0xCCC2DC),
134 on_secondary: color!(0x332D41),
135 secondary_container: color!(0x4A4458),
136 on_secondary_container: color!(0xE8DEF8),
137 secondary_fixed: color!(0xE8DEF8),
138 on_secondary_fixed: color!(0x1D192B),
139 secondary_fixed_dim: color!(0xCCC2DC),
140 on_secondary_fixed_variant: color!(0x4A4458),
141
142 tertiary: color!(0xEFB8C8),
143 on_tertiary: color!(0x492532),
144 tertiary_container: color!(0x633B48),
145 on_tertiary_container: color!(0xFFD8E4),
146 tertiary_fixed: color!(0xFFD8E4),
147 on_tertiary_fixed: color!(0x31111D),
148 tertiary_fixed_dim: color!(0xEFB8C8),
149 on_tertiary_fixed_variant: color!(0x633B48),
150
151 error: color!(0xF2B8B5),
152 on_error: color!(0x601410),
153 error_container: color!(0x8C1D18),
154 on_error_container: color!(0xF9DEDC),
155
156 surface: color!(0x141218),
157 on_surface: color!(0xE6E0E9),
158 surface_variant: color!(0x49454F),
159 on_surface_variant: color!(0xCAC4D0),
160 surface_container_highest: color!(0x36343B),
161 surface_container_high: color!(0x2B2930),
162 surface_container: color!(0x211F26),
163 surface_container_low: color!(0x1D1B20),
164 surface_container_lowest: color!(0x0F0D13),
165 inverse_surface: color!(0xE6E0E9),
166 inverse_on_surface: color!(0x322F35),
167 background: color!(0x141218),
168 on_background: color!(0xE6E0E9),
169 surface_bright: color!(0x3B383E),
170 surface_dim: color!(0x141218),
171 scrim: color!(0x000000),
172 shadow: color!(0x000000),
173
174 outline: color!(0x938F99),
175 outline_variant: color!(0x49454F),
176 }
177 }
178
179 pub fn default_light() -> Self {
180 Self {
181 primary: color!(0x6750A4),
182 on_primary: color!(0xFFFFFF),
183 primary_container: color!(0xEADDFF),
184 on_primary_container: color!(0x4F378B),
185 primary_fixed: color!(0xEADDFF),
186 on_primary_fixed: color!(0x21005D),
187 primary_fixed_dim: color!(0xD0BCFF),
188 on_primary_fixed_variant: color!(0x4F378B),
189 inverse_primary: color!(0xD0BCFF),
190
191 secondary: color!(0x625B71),
192 on_secondary: color!(0xFFFFFF),
193 secondary_container: color!(0xE8DEF8),
194 on_secondary_container: color!(0x4A4458),
195 secondary_fixed: color!(0xE8DEF8),
196 on_secondary_fixed: color!(0x1D192B),
197 secondary_fixed_dim: color!(0xCCC2DC),
198 on_secondary_fixed_variant: color!(0x4A4458),
199
200 tertiary: color!(0x7D5260),
201 on_tertiary: color!(0xFFFFFF),
202 tertiary_container: color!(0xFFD8E4),
203 on_tertiary_container: color!(0x633B48),
204 tertiary_fixed: color!(0xFFD8E4),
205 on_tertiary_fixed: color!(0x31111D),
206 tertiary_fixed_dim: color!(0xEFB8C8),
207 on_tertiary_fixed_variant: color!(0x633B48),
208
209 error: color!(0xB3261E),
210 on_error: color!(0xFFFFFF),
211 error_container: color!(0xF9DEDC),
212 on_error_container: color!(0x8C1D18),
213
214 surface: color!(0xFEF7FF),
215 on_surface: color!(0x1D1B20),
216 surface_variant: color!(0xE7E0EC),
217 on_surface_variant: color!(0x49454F),
218 surface_container_highest: color!(0xE6E0E9),
219 surface_container_high: color!(0xECE6F0),
220 surface_container: color!(0xF3EDF7),
221 surface_container_low: color!(0xF7F2FA),
222 surface_container_lowest: color!(0xFFFFFF),
223 inverse_surface: color!(0x322F35),
224 inverse_on_surface: color!(0xF5EFF7),
225 background: color!(0xFEF7FF),
226 on_background: color!(0x1D1B20),
227 surface_bright: color!(0xFEF7FF),
228 surface_dim: color!(0xDED8E1),
229 scrim: color!(0x000000),
230 shadow: color!(0x000000),
231
232 outline: color!(0x79747E),
233 outline_variant: color!(0xCAC4D0),
234 }
235 }
236}
237
238impl ColorScheme for Palette {
239 fn primary(&self) -> Color {
240 self.primary
241 }
242
243 fn on_primary(&self) -> Color {
244 self.on_primary
245 }
246
247 fn primary_container(&self) -> Color {
248 self.primary_container
249 }
250
251 fn on_primary_container(&self) -> Color {
252 self.on_primary_container
253 }
254
255 fn primary_fixed(&self) -> Color {
256 self.primary_fixed
257 }
258
259 fn on_primary_fixed(&self) -> Color {
260 self.on_primary_fixed
261 }
262
263 fn primary_fixed_dim(&self) -> Color {
264 self.primary_fixed_dim
265 }
266
267 fn on_primary_fixed_variant(&self) -> Color {
268 self.on_primary_fixed_variant
269 }
270
271 fn inverse_primary(&self) -> Color {
272 self.inverse_primary
273 }
274
275 fn secondary(&self) -> Color {
276 self.secondary
277 }
278
279 fn on_secondary(&self) -> Color {
280 self.on_secondary
281 }
282
283 fn secondary_container(&self) -> Color {
284 self.secondary_container
285 }
286
287 fn on_secondary_container(&self) -> Color {
288 self.on_secondary_container
289 }
290
291 fn secondary_fixed(&self) -> Color {
292 self.secondary_fixed
293 }
294
295 fn on_secondary_fixed(&self) -> Color {
296 self.on_secondary_fixed
297 }
298
299 fn secondary_fixed_dim(&self) -> Color {
300 self.secondary_fixed_dim
301 }
302
303 fn on_secondary_fixed_variant(&self) -> Color {
304 self.on_secondary_fixed_variant
305 }
306
307 fn tertiary(&self) -> Color {
308 self.tertiary
309 }
310
311 fn on_tertiary(&self) -> Color {
312 self.on_tertiary
313 }
314
315 fn tertiary_container(&self) -> Color {
316 self.tertiary_container
317 }
318
319 fn on_tertiary_container(&self) -> Color {
320 self.on_tertiary_container
321 }
322
323 fn tertiary_fixed(&self) -> Color {
324 self.tertiary_fixed
325 }
326
327 fn on_tertiary_fixed(&self) -> Color {
328 self.on_tertiary_fixed
329 }
330
331 fn tertiary_fixed_dim(&self) -> Color {
332 self.tertiary_fixed_dim
333 }
334
335 fn on_tertiary_fixed_variant(&self) -> Color {
336 self.on_tertiary_fixed_variant
337 }
338
339 fn error(&self) -> Color {
340 self.error
341 }
342
343 fn on_error(&self) -> Color {
344 self.on_error
345 }
346
347 fn error_container(&self) -> Color {
348 self.error_container
349 }
350
351 fn on_error_container(&self) -> Color {
352 self.on_error_container
353 }
354
355 fn surface(&self) -> Color {
356 self.surface
357 }
358
359 fn on_surface(&self) -> Color {
360 self.on_surface
361 }
362
363 fn surface_variant(&self) -> Color {
364 self.surface_variant
365 }
366
367 fn on_surface_variant(&self) -> Color {
368 self.on_surface_variant
369 }
370
371 fn surface_container_highest(&self) -> Color {
372 self.surface_container_highest
373 }
374
375 fn surface_container_high(&self) -> Color {
376 self.surface_container_high
377 }
378
379 fn surface_container(&self) -> Color {
380 self.surface_container
381 }
382
383 fn surface_container_low(&self) -> Color {
384 self.surface_container_low
385 }
386
387 fn surface_container_lowest(&self) -> Color {
388 self.surface_container_lowest
389 }
390
391 fn inverse_surface(&self) -> Color {
392 self.inverse_surface
393 }
394
395 fn inverse_on_surface(&self) -> Color {
396 self.inverse_on_surface
397 }
398
399 fn background(&self) -> Color {
400 self.background
401 }
402
403 fn on_background(&self) -> Color {
404 self.on_background
405 }
406
407 fn surface_bright(&self) -> Color {
408 self.surface_bright
409 }
410
411 fn surface_dim(&self) -> Color {
412 self.surface_dim
413 }
414
415 fn scrim(&self) -> Color {
416 self.scrim
417 }
418
419 fn shadow(&self) -> Color {
420 self.shadow
421 }
422
423 fn outline(&self) -> Color {
424 self.outline
425 }
426
427 fn outline_variant(&self) -> Color {
428 self.outline_variant
429 }
430}
431
432#[derive(Debug, Clone, Copy)]
433pub struct Theme {
434 dark: Palette,
435 light: Palette,
436 dark_mode: bool,
437}
438
439impl Theme {
440 pub fn current(&self) -> &Palette {
441 match self.dark_mode {
442 true => &self.dark,
443 false => &self.light,
444 }
445 }
446
447 pub fn default(dark_mode: bool) -> Self {
448 Self {
450 dark: Palette::default_dark(),
451 light: Palette::default_light(),
452 dark_mode,
453 }
454 }
455}
456
457impl ColorScheme for Theme {
458 fn primary(&self) -> Color {
459 self.current().primary
460 }
461
462 fn on_primary(&self) -> Color {
463 self.current().on_primary
464 }
465
466 fn primary_container(&self) -> Color {
467 self.current().primary_container
468 }
469
470 fn on_primary_container(&self) -> Color {
471 self.current().on_primary_container
472 }
473
474 fn primary_fixed(&self) -> Color {
475 self.current().primary_fixed
476 }
477
478 fn on_primary_fixed(&self) -> Color {
479 self.current().on_primary_fixed
480 }
481
482 fn primary_fixed_dim(&self) -> Color {
483 self.current().primary_fixed_dim
484 }
485
486 fn on_primary_fixed_variant(&self) -> Color {
487 self.current().on_primary_fixed_variant
488 }
489
490 fn inverse_primary(&self) -> Color {
491 self.current().inverse_primary
492 }
493
494 fn secondary(&self) -> Color {
495 self.current().secondary
496 }
497
498 fn on_secondary(&self) -> Color {
499 self.current().on_secondary
500 }
501
502 fn secondary_container(&self) -> Color {
503 self.current().secondary_container
504 }
505
506 fn on_secondary_container(&self) -> Color {
507 self.current().on_secondary_container
508 }
509
510 fn secondary_fixed(&self) -> Color {
511 self.current().secondary_fixed
512 }
513
514 fn on_secondary_fixed(&self) -> Color {
515 self.current().on_secondary_fixed
516 }
517
518 fn secondary_fixed_dim(&self) -> Color {
519 self.current().secondary_fixed_dim
520 }
521
522 fn on_secondary_fixed_variant(&self) -> Color {
523 self.current().on_secondary_fixed_variant
524 }
525
526 fn tertiary(&self) -> Color {
527 self.current().tertiary
528 }
529
530 fn on_tertiary(&self) -> Color {
531 self.current().on_tertiary
532 }
533
534 fn tertiary_container(&self) -> Color {
535 self.current().tertiary_container
536 }
537
538 fn on_tertiary_container(&self) -> Color {
539 self.current().on_tertiary_container
540 }
541
542 fn tertiary_fixed(&self) -> Color {
543 self.current().tertiary_fixed
544 }
545
546 fn on_tertiary_fixed(&self) -> Color {
547 self.current().on_tertiary_fixed
548 }
549
550 fn tertiary_fixed_dim(&self) -> Color {
551 self.current().tertiary_fixed_dim
552 }
553
554 fn on_tertiary_fixed_variant(&self) -> Color {
555 self.current().on_tertiary_fixed_variant
556 }
557
558 fn error(&self) -> Color {
559 self.current().error
560 }
561
562 fn on_error(&self) -> Color {
563 self.current().on_error
564 }
565
566 fn error_container(&self) -> Color {
567 self.current().error_container
568 }
569
570 fn on_error_container(&self) -> Color {
571 self.current().on_error_container
572 }
573
574 fn surface(&self) -> Color {
575 self.current().surface
576 }
577
578 fn on_surface(&self) -> Color {
579 self.current().on_surface
580 }
581
582 fn surface_variant(&self) -> Color {
583 self.current().surface_variant
584 }
585
586 fn on_surface_variant(&self) -> Color {
587 self.current().on_surface_variant
588 }
589
590 fn surface_container_highest(&self) -> Color {
591 self.current().surface_container_highest
592 }
593
594 fn surface_container_high(&self) -> Color {
595 self.current().surface_container_high
596 }
597
598 fn surface_container(&self) -> Color {
599 self.current().surface_container
600 }
601
602 fn surface_container_low(&self) -> Color {
603 self.current().surface_container_low
604 }
605
606 fn surface_container_lowest(&self) -> Color {
607 self.current().surface_container_lowest
608 }
609
610 fn inverse_surface(&self) -> Color {
611 self.current().inverse_surface
612 }
613
614 fn inverse_on_surface(&self) -> Color {
615 self.current().inverse_on_surface
616 }
617
618 fn background(&self) -> Color {
619 self.current().background
620 }
621
622 fn on_background(&self) -> Color {
623 self.current().on_background
624 }
625
626 fn surface_bright(&self) -> Color {
627 self.current().surface_bright
628 }
629
630 fn surface_dim(&self) -> Color {
631 self.current().surface_dim
632 }
633
634 fn scrim(&self) -> Color {
635 self.current().scrim
636 }
637
638 fn shadow(&self) -> Color {
639 self.current().shadow
640 }
641
642 fn outline(&self) -> Color {
643 self.current().outline
644 }
645
646 fn outline_variant(&self) -> Color {
647 self.current().outline_variant
648 }
649}