system_theme/theme/
palette.rs

1//! Theme palettes
2
3use crate::ThemeKind;
4
5use super::{ThemeColor, ThemeContrast, ThemeScheme};
6
7/// Windows Fluent light theme palette
8///
9/// Source: https://storybooks.fluentui.dev/react/?path=/docs/theme-colors--docs
10const FLUENT_LIGHT: ThemePalette = ThemePalette {
11    background: ThemeColor::from_rgb8(250, 250, 250),
12    foreground: ThemeColor::from_rgb8(36, 36, 36),
13    accent: ThemeColor::from_rgb8(15, 108, 189),
14    success: ThemeColor::from_rgb8(14, 112, 14),
15    warning: ThemeColor::from_rgb8(188, 75, 9),
16    danger: ThemeColor::from_rgb8(177, 14, 28),
17};
18
19/// Windows Fluent dark theme palette
20///
21/// Source: https://storybooks.fluentui.dev/react/?path=/docs/theme-colors--docs
22const FLUENT_DARK: ThemePalette = ThemePalette {
23    background: ThemeColor::from_rgb8(31, 31, 31),
24    foreground: ThemeColor::from_rgb8(255, 255, 255),
25    accent: ThemeColor::from_rgb8(71, 158, 245),
26    success: ThemeColor::from_rgb8(84, 176, 84),
27    warning: ThemeColor::from_rgb8(250, 160, 107),
28    danger: ThemeColor::from_rgb8(220, 98, 109),
29};
30
31/// Apple Aqua light theme palette
32///
33/// Source: https://developer.apple.com/design/human-interface-guidelines/color
34const AQUA_LIGHT: ThemePalette = ThemePalette {
35    background: ThemeColor::from_rgb8(229, 229, 234),
36    foreground: ThemeColor::from_rgb8(28, 28, 30),
37    accent: ThemeColor::from_rgb8(0, 136, 255),
38    success: ThemeColor::from_rgb8(52, 199, 89),
39    warning: ThemeColor::from_rgb8(255, 141, 40),
40    danger: ThemeColor::from_rgb8(255, 56, 60),
41};
42
43/// Apple Aqua dark theme palette
44///
45/// Source: https://developer.apple.com/design/human-interface-guidelines/color
46const AQUA_DARK: ThemePalette = ThemePalette {
47    background: ThemeColor::from_rgb8(44, 44, 46),
48    foreground: ThemeColor::from_rgb8(242, 242, 247),
49    accent: ThemeColor::from_rgb8(0, 145, 255),
50    success: ThemeColor::from_rgb8(48, 209, 88),
51    warning: ThemeColor::from_rgb8(255, 146, 48),
52    danger: ThemeColor::from_rgb8(255, 66, 69),
53};
54
55/// GNOME Adwaita light theme palette
56///
57/// Source: https://github.com/FedoraQt/QGnomePlatform/blob/master/src/color-schemes/Adwaita.colors
58const ADWAITA_LIGHT: ThemePalette = ThemePalette {
59    background: ThemeColor::from_rgb8(246, 245, 244),
60    foreground: ThemeColor::from_rgb8(25, 25, 25),
61    accent: ThemeColor::from_rgb8(61, 174, 233),
62    success: ThemeColor::from_rgb8(39, 174, 96),
63    warning: ThemeColor::from_rgb8(246, 116, 0),
64    danger: ThemeColor::from_rgb8(218, 68, 83),
65};
66
67/// GNOME Adwaita dark theme palette
68///
69/// Source: https://github.com/FedoraQt/QGnomePlatform/blob/master/src/color-schemes/AdwaitaDark.colors
70const ADWAITA_DARK: ThemePalette = ThemePalette {
71    background: ThemeColor::from_rgb8(45, 45, 45),
72    foreground: ThemeColor::from_rgb8(255, 255, 255),
73    accent: ThemeColor::from_rgb8(61, 174, 233),
74    success: ThemeColor::from_rgb8(39, 174, 96),
75    warning: ThemeColor::from_rgb8(246, 116, 0),
76    danger: ThemeColor::from_rgb8(218, 68, 83),
77};
78
79/// KDE Breeze light theme palette
80///
81/// Source: https://github.com/KDE/breeze/blob/master/colors/BreezeLight.colors
82const BREEZE_LIGHT: ThemePalette = ThemePalette {
83    background: ThemeColor::from_rgb8(255, 255, 255),
84    foreground: ThemeColor::from_rgb8(35, 38, 41),
85    accent: ThemeColor::from_rgb8(61, 174, 233),
86    success: ThemeColor::from_rgb8(39, 174, 96),
87    warning: ThemeColor::from_rgb8(246, 116, 0),
88    danger: ThemeColor::from_rgb8(218, 68, 83),
89};
90
91/// KDE Breeze dark theme palette
92///
93/// Source: https://github.com/KDE/breeze/blob/master/colors/BreezeDark.colors
94const BREEZE_DARK: ThemePalette = ThemePalette {
95    background: ThemeColor::from_rgb8(20, 22, 24),
96    foreground: ThemeColor::from_rgb8(252, 252, 252),
97    accent: ThemeColor::from_rgb8(61, 174, 233),
98    success: ThemeColor::from_rgb8(39, 174, 96),
99    warning: ThemeColor::from_rgb8(246, 116, 0),
100    danger: ThemeColor::from_rgb8(218, 68, 83),
101};
102
103/// Theme Palette
104pub struct ThemePalette {
105    /// Background color
106    pub background: ThemeColor,
107    /// Foreground color
108    pub foreground: ThemeColor,
109    /// Accent color
110    pub accent: ThemeColor,
111    /// Success color
112    pub success: ThemeColor,
113    /// Warning color
114    pub warning: ThemeColor,
115    /// Danger color
116    pub danger: ThemeColor,
117}
118
119impl ThemePalette {
120    /// Get the system palette for the given theme kind, scheme, and contrast.
121    pub fn system_palette(kind: ThemeKind, scheme: ThemeScheme, contrast: ThemeContrast) -> Self {
122        let mut palette = match kind {
123            ThemeKind::Windows => match scheme {
124                ThemeScheme::Light => FLUENT_LIGHT,
125                ThemeScheme::Dark => FLUENT_DARK,
126            },
127            ThemeKind::MacOS => match scheme {
128                ThemeScheme::Light => AQUA_LIGHT,
129                ThemeScheme::Dark => AQUA_DARK,
130            },
131            ThemeKind::Gtk => match scheme {
132                ThemeScheme::Light => ADWAITA_LIGHT,
133                ThemeScheme::Dark => ADWAITA_DARK,
134            },
135            ThemeKind::Qt => match scheme {
136                ThemeScheme::Light => BREEZE_LIGHT,
137                ThemeScheme::Dark => BREEZE_DARK,
138            },
139        };
140
141        // Change background/foreground colors if high contrast
142        if contrast == ThemeContrast::High {
143            match scheme {
144                ThemeScheme::Light => {
145                    palette.background = ThemeColor::WHITE;
146                    palette.foreground = ThemeColor::BLACK;
147                }
148                ThemeScheme::Dark => {
149                    palette.background = ThemeColor::BLACK;
150                    palette.foreground = ThemeColor::WHITE;
151                }
152            }
153        }
154
155        palette
156    }
157}