Skip to main content

native_theme_iced/
extended.rs

1//! Extended palette overrides from [`native_theme::ThemeVariant`] colors.
2//!
3//! After iced generates an `Extended` palette from the base `Palette`,
4//! this module overrides specific sub-palette entries with native-theme
5//! values where available.
6
7use crate::palette::to_color;
8
9/// Override auto-generated Extended palette entries with native-theme colors.
10///
11/// Applies these overrides when the corresponding native-theme field is `Some`:
12/// - `secondary.base.color` <- `colors.secondary_background`
13/// - `secondary.base.text` <- `colors.secondary_foreground`
14/// - `background.weak.color` <- `colors.surface`
15/// - `background.weak.text` <- `colors.foreground`
16pub fn apply_overrides(
17    extended: &mut iced_core::theme::palette::Extended,
18    variant: &native_theme::ThemeVariant,
19) {
20    let c = &variant.colors;
21
22    if let Some(secondary_bg) = c.secondary_background {
23        extended.secondary.base.color = to_color(Some(secondary_bg), extended.secondary.base.color);
24    }
25    if let Some(secondary_fg) = c.secondary_foreground {
26        extended.secondary.base.text = to_color(Some(secondary_fg), extended.secondary.base.text);
27    }
28    if let Some(surface) = c.surface {
29        extended.background.weak.color = to_color(Some(surface), extended.background.weak.color);
30    }
31    if let Some(fg) = c.foreground {
32        extended.background.weak.text = to_color(Some(fg), extended.background.weak.text);
33    }
34}
35
36#[cfg(test)]
37mod tests {
38    use super::*;
39    use iced_core::theme::palette::Extended;
40    use native_theme::{Rgba, ThemeVariant};
41
42    fn color_approx_eq(a: iced_core::Color, b: iced_core::Color) -> bool {
43        (a.r - b.r).abs() < 0.01
44            && (a.g - b.g).abs() < 0.01
45            && (a.b - b.b).abs() < 0.01
46            && (a.a - b.a).abs() < 0.01
47    }
48
49    fn make_extended() -> Extended {
50        let palette = iced_core::theme::Palette::DARK;
51        Extended::generate(palette)
52    }
53
54    #[test]
55    fn apply_overrides_sets_secondary_base_color() {
56        let mut extended = make_extended();
57        let mut variant = ThemeVariant::default();
58        variant.colors.secondary_background = Some(Rgba::rgb(100, 150, 200));
59
60        apply_overrides(&mut extended, &variant);
61
62        assert!(color_approx_eq(
63            extended.secondary.base.color,
64            iced_core::Color::from_rgba(100.0 / 255.0, 150.0 / 255.0, 200.0 / 255.0, 1.0)
65        ));
66    }
67
68    #[test]
69    fn apply_overrides_sets_secondary_base_text() {
70        let mut extended = make_extended();
71        let mut variant = ThemeVariant::default();
72        variant.colors.secondary_foreground = Some(Rgba::rgb(240, 240, 240));
73
74        apply_overrides(&mut extended, &variant);
75
76        assert!(color_approx_eq(
77            extended.secondary.base.text,
78            iced_core::Color::from_rgba(240.0 / 255.0, 240.0 / 255.0, 240.0 / 255.0, 1.0)
79        ));
80    }
81
82    #[test]
83    fn apply_overrides_sets_background_weak_color() {
84        let mut extended = make_extended();
85        let mut variant = ThemeVariant::default();
86        variant.colors.surface = Some(Rgba::rgb(50, 50, 50));
87
88        apply_overrides(&mut extended, &variant);
89
90        assert!(color_approx_eq(
91            extended.background.weak.color,
92            iced_core::Color::from_rgba(50.0 / 255.0, 50.0 / 255.0, 50.0 / 255.0, 1.0)
93        ));
94    }
95
96    #[test]
97    fn apply_overrides_sets_background_weak_text() {
98        let mut extended = make_extended();
99        let mut variant = ThemeVariant::default();
100        variant.colors.foreground = Some(Rgba::rgb(200, 200, 200));
101
102        apply_overrides(&mut extended, &variant);
103
104        assert!(color_approx_eq(
105            extended.background.weak.text,
106            iced_core::Color::from_rgba(200.0 / 255.0, 200.0 / 255.0, 200.0 / 255.0, 1.0)
107        ));
108    }
109
110    #[test]
111    fn apply_overrides_leaves_unchanged_when_all_none() {
112        let mut extended = make_extended();
113        let original_secondary_color = extended.secondary.base.color;
114        let original_secondary_text = extended.secondary.base.text;
115        let original_bg_weak_color = extended.background.weak.color;
116        let original_bg_weak_text = extended.background.weak.text;
117
118        let variant = ThemeVariant::default(); // all None
119
120        apply_overrides(&mut extended, &variant);
121
122        assert_eq!(extended.secondary.base.color, original_secondary_color);
123        assert_eq!(extended.secondary.base.text, original_secondary_text);
124        assert_eq!(extended.background.weak.color, original_bg_weak_color);
125        assert_eq!(extended.background.weak.text, original_bg_weak_text);
126    }
127}