fltk_theme/
lib.rs

1#![doc = include_str!("../README.md")]
2#![allow(clippy::needless_doctest_main)]
3
4use fltk::{app, enums::Color, utils::oncelock::OnceCell};
5pub mod color_themes;
6pub mod colors;
7pub mod widget_schemes;
8pub mod widget_themes;
9
10/// Color map struct. (index, r, g, b)
11#[derive(Copy, Default, Clone, Debug)]
12pub struct ColorMap {
13    pub index: u8,
14    pub r: u8,
15    pub g: u8,
16    pub b: u8,
17}
18
19static DEFAULT_COLOR_MAP: OnceCell<Vec<ColorMap>> = OnceCell::new();
20
21/// Resets the current map to the default color map
22pub fn reset_color_map() {
23    if let Some(old_map) = DEFAULT_COLOR_MAP.get() {
24        for elem in old_map {
25            app::set_color(Color::by_index(elem.index), elem.r, elem.g, elem.b);
26        }
27        app::redraw();
28    }
29}
30
31#[macro_export]
32macro_rules! cmap {
33    ($i:tt, $r:tt, $g:tt, $b:tt) => {
34        ColorMap {
35            index: $i,
36            r: $r,
37            g: $g,
38            b: $b,
39        }
40    };
41}
42
43/// A theme is just a Vec of colormaps
44#[derive(Debug, Clone)]
45pub struct ColorTheme(pub Vec<ColorMap>);
46
47impl ColorTheme {
48    /// Load from a color map
49    pub fn from_colormap(map: &[ColorMap]) -> ColorTheme {
50        ColorTheme(map.to_vec())
51    }
52
53    /// Load from a color map
54    pub fn new(map: &[ColorMap]) -> ColorTheme {
55        ColorTheme(map.to_vec())
56    }
57
58    /// apply() the theme
59    pub fn apply(&self) {
60        if DEFAULT_COLOR_MAP.get().is_none() {
61            let mut default_map = Vec::with_capacity(256);
62            for index in 0..=255 {
63                let (r, g, b) = Color::by_index(index).to_rgb();
64                default_map.push(ColorMap { index, r, g, b });
65            }
66            DEFAULT_COLOR_MAP.set(default_map).unwrap();
67        }
68        for elem in &self.0 {
69            app::set_color(Color::by_index(elem.index), elem.r, elem.g, elem.b);
70        }
71        app::redraw();
72    }
73}
74
75pub(crate) fn activated_color(c: Color) -> Color {
76    if fltk::app::draw_frame_active() {
77        c
78    } else {
79        c.inactive()
80    }
81}
82
83/// Lists supported themes
84#[derive(Debug, Clone, Copy)]
85pub enum ThemeType {
86    /// Windows classic
87    Classic,
88    /// Windows 7
89    Aero,
90    /// Windows 8
91    Metro,
92    /// Classic MacOS
93    AquaClassic,
94    /// Xfce
95    Greybird,
96    /// Windows 2000
97    Blue,
98    /// Dark
99    Dark,
100    /// High Contrast
101    HighContrast,
102}
103
104/// A widget theme is a scheme + a set of default colors
105#[derive(Debug, Clone, Copy)]
106pub struct WidgetTheme {
107    theme: ThemeType,
108}
109
110impl WidgetTheme {
111    /// Create a Widget theme object
112    pub fn new(theme: ThemeType) -> Self {
113        Self { theme }
114    }
115
116    /// Apply the widget theme
117    pub fn apply(&self) {
118        match self.theme {
119            ThemeType::Classic => widget_themes::classic::use_classic_theme(),
120            ThemeType::Aero => widget_themes::aero::use_aero_theme(),
121            ThemeType::AquaClassic => widget_themes::aqua_classic::use_aqua_classic_theme(),
122            ThemeType::Dark => widget_themes::dark::use_dark_theme(),
123            ThemeType::HighContrast => widget_themes::high_contrast::use_high_contrast_theme(),
124            ThemeType::Blue => widget_themes::blue::use_blue_theme(),
125            ThemeType::Metro => widget_themes::metro::use_metro_theme(),
126            ThemeType::Greybird => widget_themes::greybird::use_greybird_theme(),
127        }
128    }
129}
130
131/// Lists supported schemes
132#[derive(Debug, Clone, Copy)]
133pub enum SchemeType {
134    /// A scheme mimicking modern Aqua
135    Aqua,
136    /// Taken from the NTK fork
137    Clean,
138    /// Taken from the NTK fork
139    Crystal,
140    /// Windows 10
141    Fluent,
142    /// Taken from the NTK fork, a modification of the FLTK Gleam scheme
143    Gleam,
144    /**
145    Draws the following FrameTypes using scalable vector graphics:
146    - RoundedFrame
147    - RoundedBox
148    - RFlatBox
149    - OvalBox
150    - OvalFrame
151    - OFlatFrame
152    */
153    SvgBased,
154    /// A scheme mimicking the Sweet theme for GNOME/KDE
155    Sweet,
156    /// A 3D scheme designed for good looks in both dark and light colors
157    Fleet1,
158    /// A gradient scheme designed for good looks in both dark and light colors
159    Fleet2,
160}
161
162/// A widget scheme sets the style of drawing a widget without interfering with coloring
163#[derive(Debug, Clone, Copy)]
164pub struct WidgetScheme {
165    scheme: SchemeType,
166}
167
168impl WidgetScheme {
169    /// Create a Widget theme object
170    pub fn new(scheme: SchemeType) -> Self {
171        Self { scheme }
172    }
173
174    /// Apply the widget theme
175    pub fn apply(&self) {
176        match self.scheme {
177            SchemeType::Aqua => widget_schemes::aqua::use_aqua_scheme(),
178            SchemeType::Clean => widget_schemes::clean::use_clean_scheme(),
179            SchemeType::Crystal => widget_schemes::crystal::use_crystal_scheme(),
180            SchemeType::Fluent => widget_schemes::fluent::use_fluent_scheme(),
181            SchemeType::Gleam => widget_schemes::gleam::use_gleam_scheme(),
182            SchemeType::SvgBased => widget_schemes::svg_based::use_svg_based_scheme(),
183            SchemeType::Sweet => widget_schemes::sweet::use_sweet_scheme(),
184            SchemeType::Fleet1 => widget_schemes::fleet::use_fleet_scheme1(),
185            SchemeType::Fleet2 => widget_schemes::fleet::use_fleet_scheme2(),
186        }
187    }
188}