Skip to main content

iced_m3/theme/
mod.rs

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    // TODO: Replace the default material color scheme with a custom one.
121    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        // TODO: Add a default light theme
449        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}