summaryrefslogtreecommitdiff
path: root/iced_builder/src/theme.rs
blob: 21ec6e31d89e9e87e81a78038e1cbf4bd08b08e6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
use std::sync::Arc;

use iced::Color;

use crate::config::Config;

pub fn theme_index(theme_name: String, slice: &[iced::Theme]) -> Option<usize> {
    slice
        .iter()
        .position(|theme| theme.to_string() == theme_name)
}

pub fn theme_from_str(
    config: Option<&Config>,
    theme_name: &str,
) -> iced::Theme {
    match theme_name {
        "Light" => iced::Theme::Light,
        "Dark" => iced::Theme::Dark,
        "Dracula" => iced::Theme::Dracula,
        "Nord" => iced::Theme::Nord,
        "Solarized Light" => iced::Theme::SolarizedLight,
        "Solarized Dark" => iced::Theme::SolarizedDark,
        "Gruvbox Light" => iced::Theme::GruvboxLight,
        "Gruvbox Dark" => iced::Theme::GruvboxDark,
        "Catppuccin Latte" => iced::Theme::CatppuccinLatte,
        "Catppuccin Frappé" => iced::Theme::CatppuccinFrappe,
        "Catppuccin Macchiato" => iced::Theme::CatppuccinMacchiato,
        "Catppuccin Mocha" => iced::Theme::CatppuccinMocha,
        "Tokyo Night" => iced::Theme::TokyoNight,
        "Tokyo Night Storm" => iced::Theme::TokyoNightStorm,
        "Tokyo Night Light" => iced::Theme::TokyoNightLight,
        "Kanagawa Wave" => iced::Theme::KanagawaWave,
        "Kanagawa Dragon" => iced::Theme::KanagawaDragon,
        "Kanagawa Lotus" => iced::Theme::KanagawaLotus,
        "Moonfly" => iced::Theme::Moonfly,
        "Nightfly" => iced::Theme::Nightfly,
        "Oxocarbon" => iced::Theme::Oxocarbon,
        "Ferra" => iced::Theme::Ferra,
        _ => {
            if let Some(config) = config {
                if theme_name == config.theme.selected.to_string() {
                    config.theme.selected.clone()
                } else if let Some(index) =
                    theme_index(theme_name.into(), &config.theme.all)
                {
                    config.theme.all[index].clone()
                } else {
                    iced::Theme::default()
                }
            } else {
                iced::Theme::default()
            }
        }
    }
}

#[derive(Debug)]
pub struct Theme {
    pub selected: iced::Theme,
    pub all: Arc<[iced::Theme]>,
}

impl Default for Theme {
    fn default() -> Self {
        Self {
            selected: iced::Theme::default(),
            all: iced::Theme::ALL.into(),
        }
    }
}

#[derive(Debug, serde::Deserialize)]
pub struct ThemePalette {
    #[serde(with = "color_serde")]
    background: Color,
    #[serde(with = "color_serde")]
    text: Color,
    #[serde(with = "color_serde")]
    primary: Color,
    #[serde(with = "color_serde")]
    success: Color,
    #[serde(with = "color_serde")]
    danger: Color,
}

impl Default for ThemePalette {
    fn default() -> Self {
        let palette = iced::Theme::default().palette();
        Self {
            background: palette.background,
            text: palette.text,
            primary: palette.primary,
            success: palette.success,
            danger: palette.danger,
        }
    }
}

impl From<ThemePalette> for iced::theme::Palette {
    fn from(palette: ThemePalette) -> Self {
        iced::theme::Palette {
            background: palette.background,
            text: palette.text,
            primary: palette.primary,
            success: palette.success,
            danger: palette.danger,
        }
    }
}

mod color_serde {
    use iced::Color;
    use serde::{Deserialize, Deserializer};

    pub fn deserialize<'de, D>(deserializer: D) -> Result<Color, D::Error>
    where
        D: Deserializer<'de>,
    {
        Ok(String::deserialize(deserializer)
            .map(|hex| Color::parse(&hex))?
            .unwrap_or(Color::TRANSPARENT))
    }
}