iced_core/
theme.rs

1//! Use the built-in theme and styles.
2pub mod palette;
3
4pub use palette::Palette;
5
6use std::fmt;
7use std::sync::Arc;
8
9/// A built-in theme.
10#[derive(Debug, Clone, PartialEq)]
11pub enum Theme {
12    /// The built-in light variant.
13    Light,
14    /// The built-in dark variant.
15    Dark,
16    /// The built-in Dracula variant.
17    Dracula,
18    /// The built-in Nord variant.
19    Nord,
20    /// The built-in Solarized Light variant.
21    SolarizedLight,
22    /// The built-in Solarized Dark variant.
23    SolarizedDark,
24    /// The built-in Gruvbox Light variant.
25    GruvboxLight,
26    /// The built-in Gruvbox Dark variant.
27    GruvboxDark,
28    /// The built-in Catppuccin Latte variant.
29    CatppuccinLatte,
30    /// The built-in Catppuccin Frappé variant.
31    CatppuccinFrappe,
32    /// The built-in Catppuccin Macchiato variant.
33    CatppuccinMacchiato,
34    /// The built-in Catppuccin Mocha variant.
35    CatppuccinMocha,
36    /// The built-in Tokyo Night variant.
37    TokyoNight,
38    /// The built-in Tokyo Night Storm variant.
39    TokyoNightStorm,
40    /// The built-in Tokyo Night Light variant.
41    TokyoNightLight,
42    /// The built-in Kanagawa Wave variant.
43    KanagawaWave,
44    /// The built-in Kanagawa Dragon variant.
45    KanagawaDragon,
46    /// The built-in Kanagawa Lotus variant.
47    KanagawaLotus,
48    /// The built-in Moonfly variant.
49    Moonfly,
50    /// The built-in Nightfly variant.
51    Nightfly,
52    /// The built-in Oxocarbon variant.
53    Oxocarbon,
54    /// The built-in Ferra variant:
55    Ferra,
56    /// A [`Theme`] that uses a [`Custom`] palette.
57    Custom(Arc<Custom>),
58}
59
60impl Theme {
61    /// A list with all the defined themes.
62    pub const ALL: &'static [Self] = &[
63        Self::Light,
64        Self::Dark,
65        Self::Dracula,
66        Self::Nord,
67        Self::SolarizedLight,
68        Self::SolarizedDark,
69        Self::GruvboxLight,
70        Self::GruvboxDark,
71        Self::CatppuccinLatte,
72        Self::CatppuccinFrappe,
73        Self::CatppuccinMacchiato,
74        Self::CatppuccinMocha,
75        Self::TokyoNight,
76        Self::TokyoNightStorm,
77        Self::TokyoNightLight,
78        Self::KanagawaWave,
79        Self::KanagawaDragon,
80        Self::KanagawaLotus,
81        Self::Moonfly,
82        Self::Nightfly,
83        Self::Oxocarbon,
84        Self::Ferra,
85    ];
86
87    /// Creates a new custom [`Theme`] from the given [`Palette`].
88    pub fn custom(name: String, palette: Palette) -> Self {
89        Self::custom_with_fn(name, palette, palette::Extended::generate)
90    }
91
92    /// Creates a new custom [`Theme`] from the given [`Palette`], with
93    /// a custom generator of a [`palette::Extended`].
94    pub fn custom_with_fn(
95        name: String,
96        palette: Palette,
97        generate: impl FnOnce(Palette) -> palette::Extended,
98    ) -> Self {
99        Self::Custom(Arc::new(Custom::with_fn(name, palette, generate)))
100    }
101
102    /// Returns the [`Palette`] of the [`Theme`].
103    pub fn palette(&self) -> Palette {
104        match self {
105            Self::Light => Palette::LIGHT,
106            Self::Dark => Palette::DARK,
107            Self::Dracula => Palette::DRACULA,
108            Self::Nord => Palette::NORD,
109            Self::SolarizedLight => Palette::SOLARIZED_LIGHT,
110            Self::SolarizedDark => Palette::SOLARIZED_DARK,
111            Self::GruvboxLight => Palette::GRUVBOX_LIGHT,
112            Self::GruvboxDark => Palette::GRUVBOX_DARK,
113            Self::CatppuccinLatte => Palette::CATPPUCCIN_LATTE,
114            Self::CatppuccinFrappe => Palette::CATPPUCCIN_FRAPPE,
115            Self::CatppuccinMacchiato => Palette::CATPPUCCIN_MACCHIATO,
116            Self::CatppuccinMocha => Palette::CATPPUCCIN_MOCHA,
117            Self::TokyoNight => Palette::TOKYO_NIGHT,
118            Self::TokyoNightStorm => Palette::TOKYO_NIGHT_STORM,
119            Self::TokyoNightLight => Palette::TOKYO_NIGHT_LIGHT,
120            Self::KanagawaWave => Palette::KANAGAWA_WAVE,
121            Self::KanagawaDragon => Palette::KANAGAWA_DRAGON,
122            Self::KanagawaLotus => Palette::KANAGAWA_LOTUS,
123            Self::Moonfly => Palette::MOONFLY,
124            Self::Nightfly => Palette::NIGHTFLY,
125            Self::Oxocarbon => Palette::OXOCARBON,
126            Self::Ferra => Palette::FERRA,
127            Self::Custom(custom) => custom.palette,
128        }
129    }
130
131    /// Returns the [`palette::Extended`] of the [`Theme`].
132    pub fn extended_palette(&self) -> &palette::Extended {
133        match self {
134            Self::Light => &palette::EXTENDED_LIGHT,
135            Self::Dark => &palette::EXTENDED_DARK,
136            Self::Dracula => &palette::EXTENDED_DRACULA,
137            Self::Nord => &palette::EXTENDED_NORD,
138            Self::SolarizedLight => &palette::EXTENDED_SOLARIZED_LIGHT,
139            Self::SolarizedDark => &palette::EXTENDED_SOLARIZED_DARK,
140            Self::GruvboxLight => &palette::EXTENDED_GRUVBOX_LIGHT,
141            Self::GruvboxDark => &palette::EXTENDED_GRUVBOX_DARK,
142            Self::CatppuccinLatte => &palette::EXTENDED_CATPPUCCIN_LATTE,
143            Self::CatppuccinFrappe => &palette::EXTENDED_CATPPUCCIN_FRAPPE,
144            Self::CatppuccinMacchiato => {
145                &palette::EXTENDED_CATPPUCCIN_MACCHIATO
146            }
147            Self::CatppuccinMocha => &palette::EXTENDED_CATPPUCCIN_MOCHA,
148            Self::TokyoNight => &palette::EXTENDED_TOKYO_NIGHT,
149            Self::TokyoNightStorm => &palette::EXTENDED_TOKYO_NIGHT_STORM,
150            Self::TokyoNightLight => &palette::EXTENDED_TOKYO_NIGHT_LIGHT,
151            Self::KanagawaWave => &palette::EXTENDED_KANAGAWA_WAVE,
152            Self::KanagawaDragon => &palette::EXTENDED_KANAGAWA_DRAGON,
153            Self::KanagawaLotus => &palette::EXTENDED_KANAGAWA_LOTUS,
154            Self::Moonfly => &palette::EXTENDED_MOONFLY,
155            Self::Nightfly => &palette::EXTENDED_NIGHTFLY,
156            Self::Oxocarbon => &palette::EXTENDED_OXOCARBON,
157            Self::Ferra => &palette::EXTENDED_FERRA,
158            Self::Custom(custom) => &custom.extended,
159        }
160    }
161}
162
163#[allow(clippy::derivable_impls)]
164impl Default for Theme {
165    fn default() -> Self {
166        #[cfg(feature = "auto-detect-theme")]
167        {
168            use once_cell::sync::Lazy;
169
170            static DEFAULT: Lazy<Theme> =
171                Lazy::new(|| match dark_light::detect() {
172                    dark_light::Mode::Dark => Theme::Dark,
173                    dark_light::Mode::Light | dark_light::Mode::Default => {
174                        Theme::Light
175                    }
176                });
177
178            DEFAULT.clone()
179        }
180
181        #[cfg(not(feature = "auto-detect-theme"))]
182        Theme::Light
183    }
184}
185
186impl fmt::Display for Theme {
187    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
188        match self {
189            Self::Light => write!(f, "Light"),
190            Self::Dark => write!(f, "Dark"),
191            Self::Dracula => write!(f, "Dracula"),
192            Self::Nord => write!(f, "Nord"),
193            Self::SolarizedLight => write!(f, "Solarized Light"),
194            Self::SolarizedDark => write!(f, "Solarized Dark"),
195            Self::GruvboxLight => write!(f, "Gruvbox Light"),
196            Self::GruvboxDark => write!(f, "Gruvbox Dark"),
197            Self::CatppuccinLatte => write!(f, "Catppuccin Latte"),
198            Self::CatppuccinFrappe => write!(f, "Catppuccin Frappé"),
199            Self::CatppuccinMacchiato => write!(f, "Catppuccin Macchiato"),
200            Self::CatppuccinMocha => write!(f, "Catppuccin Mocha"),
201            Self::TokyoNight => write!(f, "Tokyo Night"),
202            Self::TokyoNightStorm => write!(f, "Tokyo Night Storm"),
203            Self::TokyoNightLight => write!(f, "Tokyo Night Light"),
204            Self::KanagawaWave => write!(f, "Kanagawa Wave"),
205            Self::KanagawaDragon => write!(f, "Kanagawa Dragon"),
206            Self::KanagawaLotus => write!(f, "Kanagawa Lotus"),
207            Self::Moonfly => write!(f, "Moonfly"),
208            Self::Nightfly => write!(f, "Nightfly"),
209            Self::Oxocarbon => write!(f, "Oxocarbon"),
210            Self::Ferra => write!(f, "Ferra"),
211            Self::Custom(custom) => custom.fmt(f),
212        }
213    }
214}
215
216/// A [`Theme`] with a customized [`Palette`].
217#[derive(Debug, Clone, PartialEq)]
218pub struct Custom {
219    name: String,
220    palette: Palette,
221    extended: palette::Extended,
222}
223
224impl Custom {
225    /// Creates a [`Custom`] theme from the given [`Palette`].
226    pub fn new(name: String, palette: Palette) -> Self {
227        Self::with_fn(name, palette, palette::Extended::generate)
228    }
229
230    /// Creates a [`Custom`] theme from the given [`Palette`] with
231    /// a custom generator of a [`palette::Extended`].
232    pub fn with_fn(
233        name: String,
234        palette: Palette,
235        generate: impl FnOnce(Palette) -> palette::Extended,
236    ) -> Self {
237        Self {
238            name,
239            palette,
240            extended: generate(palette),
241        }
242    }
243}
244
245impl fmt::Display for Custom {
246    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
247        write!(f, "{}", self.name)
248    }
249}