nightshade 0.8.2

A cross-platform data-oriented game engine.
Documentation
use std::sync::LazyLock;

use super::config::ThemeConfig;

macro_rules! theme_preset {
    ($name:expr, dark_mode: $dark_mode:expr, $($field:ident: $value:expr),* $(,)?) => {
        Self {
            name: $name.to_string(),
            dark_mode: $dark_mode,
            $($field: Some($value),)*
            ..Self::default()
        }
    };
}

static ALL_PRESETS: LazyLock<Vec<ThemeConfig>> = LazyLock::new(|| {
    vec![
        ThemeConfig::preset_dark(),
        ThemeConfig::preset_light(),
        ThemeConfig::preset_dracula(),
        ThemeConfig::preset_nord(),
        ThemeConfig::preset_gruvbox_dark(),
        ThemeConfig::preset_solarized_dark(),
        ThemeConfig::preset_solarized_light(),
        ThemeConfig::preset_monokai(),
        ThemeConfig::preset_one_dark(),
        ThemeConfig::preset_tokyo_night(),
        ThemeConfig::preset_catppuccin_mocha(),
    ]
});

impl ThemeConfig {
    pub fn all_presets() -> &'static [ThemeConfig] {
        &ALL_PRESETS
    }

    fn preset_dark() -> Self {
        Self {
            name: "Dark".to_string(),
            dark_mode: true,
            ..Self::default()
        }
    }

    fn preset_light() -> Self {
        Self {
            name: "Light".to_string(),
            dark_mode: false,
            ..Self::default()
        }
    }

    fn preset_dracula() -> Self {
        theme_preset!("Dracula", dark_mode: true,
            window_fill: [40, 42, 54, 255],
            panel_fill: [40, 42, 54, 255],
            faint_bg_color: [49, 51, 65, 255],
            extreme_bg_color: [30, 31, 41, 255],
            code_bg_color: [49, 51, 65, 255],
            hyperlink_color: [139, 233, 253, 255],
            warn_fg_color: [255, 184, 108, 255],
            error_fg_color: [255, 85, 85, 255],
            override_text_color: [248, 248, 242, 255],
            selection_bg_fill: [68, 71, 90, 255],
            selection_stroke_color: [189, 147, 249, 255],
            noninteractive_bg_fill: [44, 46, 58, 255],
            noninteractive_weak_bg_fill: [44, 46, 58, 255],
            noninteractive_bg_stroke_color: [68, 71, 90, 255],
            noninteractive_fg_stroke_color: [198, 198, 198, 255],
            inactive_bg_fill: [55, 57, 72, 255],
            inactive_weak_bg_fill: [50, 52, 66, 255],
            inactive_bg_stroke_color: [68, 71, 90, 255],
            inactive_fg_stroke_color: [180, 180, 190, 255],
            hovered_bg_fill: [68, 71, 90, 255],
            hovered_weak_bg_fill: [60, 62, 78, 255],
            hovered_bg_stroke_color: [189, 147, 249, 255],
            hovered_fg_stroke_color: [248, 248, 242, 255],
            active_bg_fill: [80, 83, 105, 255],
            active_weak_bg_fill: [70, 73, 92, 255],
            active_bg_stroke_color: [189, 147, 249, 255],
            active_fg_stroke_color: [248, 248, 242, 255],
            open_bg_fill: [55, 57, 72, 255],
            open_weak_bg_fill: [50, 52, 66, 255],
            open_bg_stroke_color: [68, 71, 90, 255],
            open_fg_stroke_color: [248, 248, 242, 255],
            window_stroke_color: [68, 71, 90, 255],
            window_shadow_color: [0, 0, 0, 80],
        )
    }

    fn preset_nord() -> Self {
        theme_preset!("Nord", dark_mode: true,
            window_fill: [46, 52, 64, 255],
            panel_fill: [46, 52, 64, 255],
            faint_bg_color: [59, 66, 82, 255],
            extreme_bg_color: [36, 40, 50, 255],
            code_bg_color: [59, 66, 82, 255],
            hyperlink_color: [136, 192, 208, 255],
            warn_fg_color: [235, 203, 139, 255],
            error_fg_color: [191, 97, 106, 255],
            override_text_color: [216, 222, 233, 255],
            selection_bg_fill: [67, 76, 94, 255],
            selection_stroke_color: [129, 161, 193, 255],
            noninteractive_bg_fill: [52, 58, 72, 255],
            noninteractive_weak_bg_fill: [52, 58, 72, 255],
            noninteractive_bg_stroke_color: [67, 76, 94, 255],
            noninteractive_fg_stroke_color: [180, 190, 205, 255],
            inactive_bg_fill: [59, 66, 82, 255],
            inactive_weak_bg_fill: [55, 62, 78, 255],
            inactive_bg_stroke_color: [67, 76, 94, 255],
            inactive_fg_stroke_color: [170, 180, 195, 255],
            hovered_bg_fill: [67, 76, 94, 255],
            hovered_weak_bg_fill: [63, 72, 88, 255],
            hovered_bg_stroke_color: [129, 161, 193, 255],
            hovered_fg_stroke_color: [216, 222, 233, 255],
            active_bg_fill: [76, 86, 106, 255],
            active_weak_bg_fill: [72, 82, 100, 255],
            active_bg_stroke_color: [129, 161, 193, 255],
            active_fg_stroke_color: [236, 239, 244, 255],
            open_bg_fill: [59, 66, 82, 255],
            open_weak_bg_fill: [55, 62, 78, 255],
            open_bg_stroke_color: [67, 76, 94, 255],
            open_fg_stroke_color: [216, 222, 233, 255],
            window_stroke_color: [67, 76, 94, 255],
            window_shadow_color: [0, 0, 0, 60],
        )
    }

    fn preset_gruvbox_dark() -> Self {
        theme_preset!("Gruvbox Dark", dark_mode: true,
            window_fill: [40, 40, 40, 255],
            panel_fill: [40, 40, 40, 255],
            faint_bg_color: [50, 48, 47, 255],
            extreme_bg_color: [29, 32, 33, 255],
            code_bg_color: [50, 48, 47, 255],
            hyperlink_color: [131, 165, 152, 255],
            warn_fg_color: [250, 189, 47, 255],
            error_fg_color: [251, 73, 52, 255],
            override_text_color: [235, 219, 178, 255],
            selection_bg_fill: [69, 65, 60, 255],
            selection_stroke_color: [214, 93, 14, 255],
            noninteractive_bg_fill: [50, 48, 47, 255],
            noninteractive_weak_bg_fill: [50, 48, 47, 255],
            noninteractive_bg_stroke_color: [80, 73, 69, 255],
            noninteractive_fg_stroke_color: [189, 174, 147, 255],
            inactive_bg_fill: [60, 56, 54, 255],
            inactive_weak_bg_fill: [55, 52, 50, 255],
            inactive_bg_stroke_color: [80, 73, 69, 255],
            inactive_fg_stroke_color: [168, 153, 132, 255],
            hovered_bg_fill: [80, 73, 69, 255],
            hovered_weak_bg_fill: [70, 65, 62, 255],
            hovered_bg_stroke_color: [214, 93, 14, 255],
            hovered_fg_stroke_color: [235, 219, 178, 255],
            active_bg_fill: [102, 92, 84, 255],
            active_weak_bg_fill: [90, 82, 75, 255],
            active_bg_stroke_color: [214, 93, 14, 255],
            active_fg_stroke_color: [235, 219, 178, 255],
            open_bg_fill: [60, 56, 54, 255],
            open_weak_bg_fill: [55, 52, 50, 255],
            open_bg_stroke_color: [80, 73, 69, 255],
            open_fg_stroke_color: [235, 219, 178, 255],
            window_stroke_color: [80, 73, 69, 255],
            window_shadow_color: [0, 0, 0, 80],
        )
    }

    fn preset_solarized_dark() -> Self {
        theme_preset!("Solarized Dark", dark_mode: true,
            window_fill: [0, 43, 54, 255],
            panel_fill: [0, 43, 54, 255],
            faint_bg_color: [7, 54, 66, 255],
            extreme_bg_color: [0, 30, 38, 255],
            code_bg_color: [7, 54, 66, 255],
            hyperlink_color: [38, 139, 210, 255],
            warn_fg_color: [181, 137, 0, 255],
            error_fg_color: [220, 50, 47, 255],
            override_text_color: [147, 161, 161, 255],
            selection_bg_fill: [7, 54, 66, 255],
            selection_stroke_color: [38, 139, 210, 255],
            noninteractive_bg_fill: [7, 54, 66, 255],
            noninteractive_weak_bg_fill: [7, 54, 66, 255],
            noninteractive_bg_stroke_color: [88, 110, 117, 255],
            noninteractive_fg_stroke_color: [131, 148, 150, 255],
            inactive_bg_fill: [18, 65, 78, 255],
            inactive_weak_bg_fill: [12, 58, 70, 255],
            inactive_bg_stroke_color: [88, 110, 117, 255],
            inactive_fg_stroke_color: [119, 136, 138, 255],
            hovered_bg_fill: [30, 78, 92, 255],
            hovered_weak_bg_fill: [22, 70, 84, 255],
            hovered_bg_stroke_color: [38, 139, 210, 255],
            hovered_fg_stroke_color: [147, 161, 161, 255],
            active_bg_fill: [42, 92, 108, 255],
            active_weak_bg_fill: [35, 84, 98, 255],
            active_bg_stroke_color: [38, 139, 210, 255],
            active_fg_stroke_color: [238, 232, 213, 255],
            open_bg_fill: [18, 65, 78, 255],
            open_weak_bg_fill: [12, 58, 70, 255],
            open_bg_stroke_color: [88, 110, 117, 255],
            open_fg_stroke_color: [147, 161, 161, 255],
            window_stroke_color: [88, 110, 117, 255],
            window_shadow_color: [0, 0, 0, 60],
        )
    }

    fn preset_solarized_light() -> Self {
        theme_preset!("Solarized Light", dark_mode: false,
            window_fill: [253, 246, 227, 255],
            panel_fill: [253, 246, 227, 255],
            faint_bg_color: [238, 232, 213, 255],
            extreme_bg_color: [255, 255, 240, 255],
            code_bg_color: [238, 232, 213, 255],
            hyperlink_color: [38, 139, 210, 255],
            warn_fg_color: [181, 137, 0, 255],
            error_fg_color: [220, 50, 47, 255],
            override_text_color: [101, 123, 131, 255],
            selection_bg_fill: [238, 232, 213, 255],
            selection_stroke_color: [38, 139, 210, 255],
            noninteractive_bg_fill: [238, 232, 213, 255],
            noninteractive_weak_bg_fill: [238, 232, 213, 255],
            noninteractive_bg_stroke_color: [147, 161, 161, 255],
            noninteractive_fg_stroke_color: [88, 110, 117, 255],
            inactive_bg_fill: [228, 222, 203, 255],
            inactive_weak_bg_fill: [233, 227, 208, 255],
            inactive_bg_stroke_color: [147, 161, 161, 255],
            inactive_fg_stroke_color: [101, 123, 131, 255],
            hovered_bg_fill: [218, 212, 193, 255],
            hovered_weak_bg_fill: [223, 217, 198, 255],
            hovered_bg_stroke_color: [38, 139, 210, 255],
            hovered_fg_stroke_color: [88, 110, 117, 255],
            active_bg_fill: [208, 202, 183, 255],
            active_weak_bg_fill: [213, 207, 188, 255],
            active_bg_stroke_color: [38, 139, 210, 255],
            active_fg_stroke_color: [7, 54, 66, 255],
            open_bg_fill: [228, 222, 203, 255],
            open_weak_bg_fill: [233, 227, 208, 255],
            open_bg_stroke_color: [147, 161, 161, 255],
            open_fg_stroke_color: [101, 123, 131, 255],
            window_stroke_color: [147, 161, 161, 255],
            window_shadow_color: [0, 0, 0, 30],
        )
    }

    fn preset_monokai() -> Self {
        theme_preset!("Monokai", dark_mode: true,
            window_fill: [39, 40, 34, 255],
            panel_fill: [39, 40, 34, 255],
            faint_bg_color: [49, 50, 44, 255],
            extreme_bg_color: [28, 29, 24, 255],
            code_bg_color: [49, 50, 44, 255],
            hyperlink_color: [102, 217, 239, 255],
            warn_fg_color: [230, 219, 116, 255],
            error_fg_color: [249, 38, 114, 255],
            override_text_color: [248, 248, 242, 255],
            selection_bg_fill: [73, 72, 62, 255],
            selection_stroke_color: [166, 226, 46, 255],
            noninteractive_bg_fill: [49, 50, 44, 255],
            noninteractive_weak_bg_fill: [49, 50, 44, 255],
            noninteractive_bg_stroke_color: [73, 72, 62, 255],
            noninteractive_fg_stroke_color: [190, 190, 182, 255],
            inactive_bg_fill: [58, 60, 52, 255],
            inactive_weak_bg_fill: [53, 55, 47, 255],
            inactive_bg_stroke_color: [73, 72, 62, 255],
            inactive_fg_stroke_color: [170, 170, 162, 255],
            hovered_bg_fill: [73, 72, 62, 255],
            hovered_weak_bg_fill: [65, 66, 56, 255],
            hovered_bg_stroke_color: [166, 226, 46, 255],
            hovered_fg_stroke_color: [248, 248, 242, 255],
            active_bg_fill: [88, 88, 76, 255],
            active_weak_bg_fill: [80, 80, 68, 255],
            active_bg_stroke_color: [166, 226, 46, 255],
            active_fg_stroke_color: [248, 248, 242, 255],
            open_bg_fill: [58, 60, 52, 255],
            open_weak_bg_fill: [53, 55, 47, 255],
            open_bg_stroke_color: [73, 72, 62, 255],
            open_fg_stroke_color: [248, 248, 242, 255],
            window_stroke_color: [73, 72, 62, 255],
            window_shadow_color: [0, 0, 0, 80],
        )
    }

    fn preset_one_dark() -> Self {
        theme_preset!("One Dark", dark_mode: true,
            window_fill: [40, 44, 52, 255],
            panel_fill: [40, 44, 52, 255],
            faint_bg_color: [50, 54, 62, 255],
            extreme_bg_color: [30, 33, 40, 255],
            code_bg_color: [50, 54, 62, 255],
            hyperlink_color: [97, 175, 239, 255],
            warn_fg_color: [229, 192, 123, 255],
            error_fg_color: [224, 108, 117, 255],
            override_text_color: [171, 178, 191, 255],
            selection_bg_fill: [62, 68, 81, 255],
            selection_stroke_color: [97, 175, 239, 255],
            noninteractive_bg_fill: [50, 54, 62, 255],
            noninteractive_weak_bg_fill: [50, 54, 62, 255],
            noninteractive_bg_stroke_color: [62, 68, 81, 255],
            noninteractive_fg_stroke_color: [150, 156, 168, 255],
            inactive_bg_fill: [55, 60, 70, 255],
            inactive_weak_bg_fill: [52, 57, 66, 255],
            inactive_bg_stroke_color: [62, 68, 81, 255],
            inactive_fg_stroke_color: [140, 146, 158, 255],
            hovered_bg_fill: [62, 68, 81, 255],
            hovered_weak_bg_fill: [58, 64, 76, 255],
            hovered_bg_stroke_color: [97, 175, 239, 255],
            hovered_fg_stroke_color: [171, 178, 191, 255],
            active_bg_fill: [75, 82, 98, 255],
            active_weak_bg_fill: [68, 74, 90, 255],
            active_bg_stroke_color: [97, 175, 239, 255],
            active_fg_stroke_color: [198, 204, 215, 255],
            open_bg_fill: [55, 60, 70, 255],
            open_weak_bg_fill: [52, 57, 66, 255],
            open_bg_stroke_color: [62, 68, 81, 255],
            open_fg_stroke_color: [171, 178, 191, 255],
            window_stroke_color: [62, 68, 81, 255],
            window_shadow_color: [0, 0, 0, 70],
        )
    }

    fn preset_tokyo_night() -> Self {
        theme_preset!("Tokyo Night", dark_mode: true,
            window_fill: [26, 27, 38, 255],
            panel_fill: [26, 27, 38, 255],
            faint_bg_color: [36, 37, 48, 255],
            extreme_bg_color: [16, 17, 28, 255],
            code_bg_color: [36, 37, 48, 255],
            hyperlink_color: [125, 207, 255, 255],
            warn_fg_color: [224, 175, 104, 255],
            error_fg_color: [247, 118, 142, 255],
            override_text_color: [169, 177, 214, 255],
            selection_bg_fill: [42, 46, 66, 255],
            selection_stroke_color: [122, 162, 247, 255],
            noninteractive_bg_fill: [36, 37, 48, 255],
            noninteractive_weak_bg_fill: [36, 37, 48, 255],
            noninteractive_bg_stroke_color: [52, 56, 78, 255],
            noninteractive_fg_stroke_color: [140, 148, 180, 255],
            inactive_bg_fill: [42, 44, 58, 255],
            inactive_weak_bg_fill: [38, 40, 52, 255],
            inactive_bg_stroke_color: [52, 56, 78, 255],
            inactive_fg_stroke_color: [130, 138, 170, 255],
            hovered_bg_fill: [52, 56, 78, 255],
            hovered_weak_bg_fill: [46, 50, 70, 255],
            hovered_bg_stroke_color: [122, 162, 247, 255],
            hovered_fg_stroke_color: [169, 177, 214, 255],
            active_bg_fill: [65, 70, 96, 255],
            active_weak_bg_fill: [58, 62, 86, 255],
            active_bg_stroke_color: [122, 162, 247, 255],
            active_fg_stroke_color: [195, 202, 230, 255],
            open_bg_fill: [42, 44, 58, 255],
            open_weak_bg_fill: [38, 40, 52, 255],
            open_bg_stroke_color: [52, 56, 78, 255],
            open_fg_stroke_color: [169, 177, 214, 255],
            window_stroke_color: [52, 56, 78, 255],
            window_shadow_color: [0, 0, 0, 80],
        )
    }

    fn preset_catppuccin_mocha() -> Self {
        theme_preset!("Catppuccin Mocha", dark_mode: true,
            window_fill: [30, 30, 46, 255],
            panel_fill: [30, 30, 46, 255],
            faint_bg_color: [39, 39, 55, 255],
            extreme_bg_color: [17, 17, 27, 255],
            code_bg_color: [39, 39, 55, 255],
            hyperlink_color: [137, 180, 250, 255],
            warn_fg_color: [249, 226, 175, 255],
            error_fg_color: [243, 139, 168, 255],
            override_text_color: [205, 214, 244, 255],
            selection_bg_fill: [49, 50, 68, 255],
            selection_stroke_color: [180, 190, 254, 255],
            noninteractive_bg_fill: [39, 39, 55, 255],
            noninteractive_weak_bg_fill: [39, 39, 55, 255],
            noninteractive_bg_stroke_color: [49, 50, 68, 255],
            noninteractive_fg_stroke_color: [166, 173, 200, 255],
            inactive_bg_fill: [45, 45, 62, 255],
            inactive_weak_bg_fill: [42, 42, 58, 255],
            inactive_bg_stroke_color: [49, 50, 68, 255],
            inactive_fg_stroke_color: [147, 153, 178, 255],
            hovered_bg_fill: [49, 50, 68, 255],
            hovered_weak_bg_fill: [46, 46, 64, 255],
            hovered_bg_stroke_color: [180, 190, 254, 255],
            hovered_fg_stroke_color: [205, 214, 244, 255],
            active_bg_fill: [62, 64, 84, 255],
            active_weak_bg_fill: [55, 56, 76, 255],
            active_bg_stroke_color: [180, 190, 254, 255],
            active_fg_stroke_color: [205, 214, 244, 255],
            open_bg_fill: [45, 45, 62, 255],
            open_weak_bg_fill: [42, 42, 58, 255],
            open_bg_stroke_color: [49, 50, 68, 255],
            open_fg_stroke_color: [205, 214, 244, 255],
            window_stroke_color: [49, 50, 68, 255],
            window_shadow_color: [0, 0, 0, 80],
        )
    }
}