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#[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
21pub 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#[derive(Debug, Clone)]
45pub struct ColorTheme(pub Vec<ColorMap>);
46
47impl ColorTheme {
48 pub fn from_colormap(map: &[ColorMap]) -> ColorTheme {
50 ColorTheme(map.to_vec())
51 }
52
53 pub fn new(map: &[ColorMap]) -> ColorTheme {
55 ColorTheme(map.to_vec())
56 }
57
58 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#[derive(Debug, Clone, Copy)]
85pub enum ThemeType {
86 Classic,
88 Aero,
90 Metro,
92 AquaClassic,
94 Greybird,
96 Blue,
98 Dark,
100 HighContrast,
102}
103
104#[derive(Debug, Clone, Copy)]
106pub struct WidgetTheme {
107 theme: ThemeType,
108}
109
110impl WidgetTheme {
111 pub fn new(theme: ThemeType) -> Self {
113 Self { theme }
114 }
115
116 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#[derive(Debug, Clone, Copy)]
133pub enum SchemeType {
134 Aqua,
136 Clean,
138 Crystal,
140 Fluent,
142 Gleam,
144 SvgBased,
154 Sweet,
156 Fleet1,
158 Fleet2,
160}
161
162#[derive(Debug, Clone, Copy)]
164pub struct WidgetScheme {
165 scheme: SchemeType,
166}
167
168impl WidgetScheme {
169 pub fn new(scheme: SchemeType) -> Self {
171 Self { scheme }
172 }
173
174 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}