use nalgebra_glm::Vec4;
#[derive(Clone, Debug)]
pub struct UiTheme {
pub name: String,
pub dark_mode: bool,
pub text_color: Vec4,
pub text_color_disabled: Vec4,
pub text_color_accent: Vec4,
pub background_color: Vec4,
pub background_color_hovered: Vec4,
pub background_color_active: Vec4,
pub panel_color: Vec4,
pub panel_header_color: Vec4,
pub border_color: Vec4,
pub border_color_focused: Vec4,
pub accent_color: Vec4,
pub accent_color_hovered: Vec4,
pub accent_color_active: Vec4,
pub success_color: Vec4,
pub warning_color: Vec4,
pub error_color: Vec4,
pub slider_track_color: Vec4,
pub slider_fill_color: Vec4,
pub input_background_color: Vec4,
pub input_background_focused: Vec4,
pub selection_color: Vec4,
pub scrollbar_color: Vec4,
pub scrollbar_color_hovered: Vec4,
pub border_width: f32,
pub corner_radius: f32,
pub padding: f32,
pub spacing: f32,
pub font_size: f32,
pub button_height: f32,
pub slider_height: f32,
pub checkbox_size: f32,
pub toggle_width: f32,
pub toggle_height: f32,
pub panel_header_height: f32,
}
impl Default for UiTheme {
fn default() -> Self {
Self::dark()
}
}
impl UiTheme {
pub fn dark() -> Self {
Self {
name: "Dark".to_string(),
dark_mode: true,
text_color: Vec4::new(1.0, 1.0, 1.0, 1.0),
text_color_disabled: Vec4::new(0.5, 0.5, 0.5, 1.0),
text_color_accent: Vec4::new(0.4, 0.8, 1.0, 1.0),
background_color: Vec4::new(0.15, 0.15, 0.15, 1.0),
background_color_hovered: Vec4::new(0.25, 0.25, 0.25, 1.0),
background_color_active: Vec4::new(0.35, 0.35, 0.35, 1.0),
panel_color: Vec4::new(0.12, 0.12, 0.12, 1.0),
panel_header_color: Vec4::new(0.18, 0.18, 0.18, 1.0),
border_color: Vec4::new(0.4, 0.4, 0.4, 1.0),
border_color_focused: Vec4::new(0.5, 0.7, 1.0, 1.0),
accent_color: Vec4::new(0.3, 0.5, 0.9, 1.0),
accent_color_hovered: Vec4::new(0.4, 0.6, 1.0, 1.0),
accent_color_active: Vec4::new(0.2, 0.4, 0.8, 1.0),
success_color: Vec4::new(0.3, 0.8, 0.4, 1.0),
warning_color: Vec4::new(1.0, 0.7, 0.2, 1.0),
error_color: Vec4::new(0.9, 0.3, 0.3, 1.0),
slider_track_color: Vec4::new(0.25, 0.25, 0.25, 1.0),
slider_fill_color: Vec4::new(0.3, 0.5, 0.9, 1.0),
input_background_color: Vec4::new(0.1, 0.1, 0.1, 1.0),
input_background_focused: Vec4::new(0.12, 0.12, 0.15, 1.0),
selection_color: Vec4::new(0.3, 0.5, 0.9, 0.4),
scrollbar_color: Vec4::new(0.3, 0.3, 0.3, 0.6),
scrollbar_color_hovered: Vec4::new(0.4, 0.4, 0.4, 0.8),
border_width: 1.0,
corner_radius: 4.0,
padding: 8.0,
spacing: 6.0,
font_size: 18.0,
button_height: 32.0,
slider_height: 24.0,
checkbox_size: 20.0,
toggle_width: 40.0,
toggle_height: 22.0,
panel_header_height: 28.0,
}
}
pub fn light() -> Self {
Self {
name: "Light".to_string(),
dark_mode: false,
text_color: Vec4::new(0.1, 0.1, 0.1, 1.0),
text_color_disabled: Vec4::new(0.5, 0.5, 0.5, 1.0),
text_color_accent: Vec4::new(0.2, 0.4, 0.8, 1.0),
background_color: Vec4::new(0.95, 0.95, 0.95, 1.0),
background_color_hovered: Vec4::new(0.88, 0.88, 0.88, 1.0),
background_color_active: Vec4::new(0.8, 0.8, 0.8, 1.0),
panel_color: Vec4::new(1.0, 1.0, 1.0, 1.0),
panel_header_color: Vec4::new(0.92, 0.92, 0.92, 1.0),
border_color: Vec4::new(0.75, 0.75, 0.75, 1.0),
border_color_focused: Vec4::new(0.3, 0.5, 0.9, 1.0),
accent_color: Vec4::new(0.2, 0.45, 0.85, 1.0),
accent_color_hovered: Vec4::new(0.3, 0.55, 0.95, 1.0),
accent_color_active: Vec4::new(0.15, 0.35, 0.75, 1.0),
success_color: Vec4::new(0.2, 0.7, 0.3, 1.0),
warning_color: Vec4::new(0.9, 0.6, 0.1, 1.0),
error_color: Vec4::new(0.85, 0.2, 0.2, 1.0),
slider_track_color: Vec4::new(0.8, 0.8, 0.8, 1.0),
slider_fill_color: Vec4::new(0.2, 0.45, 0.85, 1.0),
input_background_color: Vec4::new(1.0, 1.0, 1.0, 1.0),
input_background_focused: Vec4::new(0.98, 0.98, 1.0, 1.0),
selection_color: Vec4::new(0.2, 0.45, 0.85, 0.3),
scrollbar_color: Vec4::new(0.7, 0.7, 0.7, 0.5),
scrollbar_color_hovered: Vec4::new(0.6, 0.6, 0.6, 0.7),
border_width: 1.0,
corner_radius: 4.0,
padding: 8.0,
spacing: 6.0,
font_size: 18.0,
button_height: 32.0,
slider_height: 24.0,
checkbox_size: 20.0,
toggle_width: 40.0,
toggle_height: 22.0,
panel_header_height: 28.0,
}
}
pub fn dracula() -> Self {
Self {
name: "Dracula".to_string(),
dark_mode: true,
text_color: Vec4::new(0.973, 0.973, 0.949, 1.0),
text_color_disabled: Vec4::new(0.384, 0.447, 0.643, 1.0),
text_color_accent: Vec4::new(0.545, 0.914, 0.992, 1.0),
background_color: Vec4::new(0.157, 0.165, 0.212, 1.0),
background_color_hovered: Vec4::new(0.267, 0.278, 0.353, 1.0),
background_color_active: Vec4::new(0.337, 0.349, 0.424, 1.0),
panel_color: Vec4::new(0.157, 0.165, 0.212, 1.0),
panel_header_color: Vec4::new(0.267, 0.278, 0.353, 1.0),
border_color: Vec4::new(0.384, 0.447, 0.643, 1.0),
border_color_focused: Vec4::new(0.741, 0.576, 0.976, 1.0),
accent_color: Vec4::new(0.741, 0.576, 0.976, 1.0),
accent_color_hovered: Vec4::new(0.827, 0.686, 1.0, 1.0),
accent_color_active: Vec4::new(0.639, 0.475, 0.855, 1.0),
success_color: Vec4::new(0.314, 0.980, 0.482, 1.0),
warning_color: Vec4::new(1.0, 0.722, 0.424, 1.0),
error_color: Vec4::new(1.0, 0.333, 0.333, 1.0),
slider_track_color: Vec4::new(0.267, 0.278, 0.353, 1.0),
slider_fill_color: Vec4::new(0.741, 0.576, 0.976, 1.0),
input_background_color: Vec4::new(0.118, 0.125, 0.165, 1.0),
input_background_focused: Vec4::new(0.157, 0.165, 0.212, 1.0),
selection_color: Vec4::new(0.384, 0.447, 0.643, 0.5),
scrollbar_color: Vec4::new(0.384, 0.447, 0.643, 0.4),
scrollbar_color_hovered: Vec4::new(0.384, 0.447, 0.643, 0.7),
border_width: 1.0,
corner_radius: 4.0,
padding: 8.0,
spacing: 6.0,
font_size: 18.0,
button_height: 32.0,
slider_height: 24.0,
checkbox_size: 20.0,
toggle_width: 40.0,
toggle_height: 22.0,
panel_header_height: 28.0,
}
}
pub fn nord() -> Self {
Self {
name: "Nord".to_string(),
dark_mode: true,
text_color: Vec4::new(0.847, 0.871, 0.914, 1.0),
text_color_disabled: Vec4::new(0.369, 0.420, 0.506, 1.0),
text_color_accent: Vec4::new(0.533, 0.753, 0.816, 1.0),
background_color: Vec4::new(0.180, 0.204, 0.251, 1.0),
background_color_hovered: Vec4::new(0.231, 0.259, 0.322, 1.0),
background_color_active: Vec4::new(0.263, 0.298, 0.369, 1.0),
panel_color: Vec4::new(0.180, 0.204, 0.251, 1.0),
panel_header_color: Vec4::new(0.231, 0.259, 0.322, 1.0),
border_color: Vec4::new(0.369, 0.420, 0.506, 1.0),
border_color_focused: Vec4::new(0.533, 0.753, 0.816, 1.0),
accent_color: Vec4::new(0.533, 0.753, 0.816, 1.0),
accent_color_hovered: Vec4::new(0.565, 0.792, 0.863, 1.0),
accent_color_active: Vec4::new(0.427, 0.671, 0.757, 1.0),
success_color: Vec4::new(0.639, 0.745, 0.549, 1.0),
warning_color: Vec4::new(0.922, 0.796, 0.545, 1.0),
error_color: Vec4::new(0.749, 0.380, 0.416, 1.0),
slider_track_color: Vec4::new(0.231, 0.259, 0.322, 1.0),
slider_fill_color: Vec4::new(0.533, 0.753, 0.816, 1.0),
input_background_color: Vec4::new(0.141, 0.165, 0.204, 1.0),
input_background_focused: Vec4::new(0.180, 0.204, 0.251, 1.0),
selection_color: Vec4::new(0.533, 0.753, 0.816, 0.4),
scrollbar_color: Vec4::new(0.369, 0.420, 0.506, 0.4),
scrollbar_color_hovered: Vec4::new(0.369, 0.420, 0.506, 0.7),
border_width: 1.0,
corner_radius: 4.0,
padding: 8.0,
spacing: 6.0,
font_size: 18.0,
button_height: 32.0,
slider_height: 24.0,
checkbox_size: 20.0,
toggle_width: 40.0,
toggle_height: 22.0,
panel_header_height: 28.0,
}
}
pub fn gruvbox_dark() -> Self {
Self {
name: "Gruvbox Dark".to_string(),
dark_mode: true,
text_color: Vec4::new(0.922, 0.859, 0.698, 1.0),
text_color_disabled: Vec4::new(0.502, 0.502, 0.502, 1.0),
text_color_accent: Vec4::new(0.514, 0.647, 0.596, 1.0),
background_color: Vec4::new(0.157, 0.157, 0.157, 1.0),
background_color_hovered: Vec4::new(0.235, 0.220, 0.212, 1.0),
background_color_active: Vec4::new(0.314, 0.294, 0.278, 1.0),
panel_color: Vec4::new(0.157, 0.157, 0.157, 1.0),
panel_header_color: Vec4::new(0.235, 0.220, 0.212, 1.0),
border_color: Vec4::new(0.400, 0.361, 0.329, 1.0),
border_color_focused: Vec4::new(0.514, 0.647, 0.596, 1.0),
accent_color: Vec4::new(0.514, 0.647, 0.596, 1.0),
accent_color_hovered: Vec4::new(0.557, 0.694, 0.639, 1.0),
accent_color_active: Vec4::new(0.427, 0.561, 0.518, 1.0),
success_color: Vec4::new(0.722, 0.733, 0.149, 1.0),
warning_color: Vec4::new(0.980, 0.741, 0.184, 1.0),
error_color: Vec4::new(0.984, 0.286, 0.204, 1.0),
slider_track_color: Vec4::new(0.235, 0.220, 0.212, 1.0),
slider_fill_color: Vec4::new(0.514, 0.647, 0.596, 1.0),
input_background_color: Vec4::new(0.114, 0.125, 0.129, 1.0),
input_background_focused: Vec4::new(0.157, 0.157, 0.157, 1.0),
selection_color: Vec4::new(0.400, 0.361, 0.329, 0.5),
scrollbar_color: Vec4::new(0.400, 0.361, 0.329, 0.4),
scrollbar_color_hovered: Vec4::new(0.400, 0.361, 0.329, 0.7),
border_width: 1.0,
corner_radius: 4.0,
padding: 8.0,
spacing: 6.0,
font_size: 18.0,
button_height: 32.0,
slider_height: 24.0,
checkbox_size: 20.0,
toggle_width: 40.0,
toggle_height: 22.0,
panel_header_height: 28.0,
}
}
pub fn monokai() -> Self {
Self {
name: "Monokai".to_string(),
dark_mode: true,
text_color: Vec4::new(0.973, 0.973, 0.949, 1.0),
text_color_disabled: Vec4::new(0.467, 0.467, 0.412, 1.0),
text_color_accent: Vec4::new(0.400, 0.851, 0.937, 1.0),
background_color: Vec4::new(0.153, 0.157, 0.133, 1.0),
background_color_hovered: Vec4::new(0.286, 0.282, 0.243, 1.0),
background_color_active: Vec4::new(0.369, 0.365, 0.32, 1.0),
panel_color: Vec4::new(0.153, 0.157, 0.133, 1.0),
panel_header_color: Vec4::new(0.286, 0.282, 0.243, 1.0),
border_color: Vec4::new(0.467, 0.467, 0.412, 1.0),
border_color_focused: Vec4::new(0.651, 0.886, 0.180, 1.0),
accent_color: Vec4::new(0.651, 0.886, 0.180, 1.0),
accent_color_hovered: Vec4::new(0.741, 0.929, 0.32, 1.0),
accent_color_active: Vec4::new(0.549, 0.773, 0.110, 1.0),
success_color: Vec4::new(0.651, 0.886, 0.180, 1.0),
warning_color: Vec4::new(0.902, 0.859, 0.455, 1.0),
error_color: Vec4::new(0.976, 0.149, 0.447, 1.0),
slider_track_color: Vec4::new(0.286, 0.282, 0.243, 1.0),
slider_fill_color: Vec4::new(0.651, 0.886, 0.180, 1.0),
input_background_color: Vec4::new(0.118, 0.122, 0.098, 1.0),
input_background_focused: Vec4::new(0.153, 0.157, 0.133, 1.0),
selection_color: Vec4::new(0.286, 0.282, 0.243, 0.6),
scrollbar_color: Vec4::new(0.467, 0.467, 0.412, 0.4),
scrollbar_color_hovered: Vec4::new(0.467, 0.467, 0.412, 0.7),
border_width: 1.0,
corner_radius: 4.0,
padding: 8.0,
spacing: 6.0,
font_size: 18.0,
button_height: 32.0,
slider_height: 24.0,
checkbox_size: 20.0,
toggle_width: 40.0,
toggle_height: 22.0,
panel_header_height: 28.0,
}
}
pub fn tokyo_night() -> Self {
Self {
name: "Tokyo Night".to_string(),
dark_mode: true,
text_color: Vec4::new(0.753, 0.792, 0.961, 1.0),
text_color_disabled: Vec4::new(0.329, 0.369, 0.502, 1.0),
text_color_accent: Vec4::new(0.478, 0.635, 0.969, 1.0),
background_color: Vec4::new(0.102, 0.106, 0.149, 1.0),
background_color_hovered: Vec4::new(0.141, 0.157, 0.231, 1.0),
background_color_active: Vec4::new(0.220, 0.243, 0.353, 1.0),
panel_color: Vec4::new(0.102, 0.106, 0.149, 1.0),
panel_header_color: Vec4::new(0.141, 0.157, 0.231, 1.0),
border_color: Vec4::new(0.220, 0.243, 0.353, 1.0),
border_color_focused: Vec4::new(0.478, 0.635, 0.969, 1.0),
accent_color: Vec4::new(0.478, 0.635, 0.969, 1.0),
accent_color_hovered: Vec4::new(0.549, 0.694, 1.0, 1.0),
accent_color_active: Vec4::new(0.376, 0.533, 0.859, 1.0),
success_color: Vec4::new(0.451, 0.824, 0.451, 1.0),
warning_color: Vec4::new(0.878, 0.686, 0.408, 1.0),
error_color: Vec4::new(0.969, 0.463, 0.557, 1.0),
slider_track_color: Vec4::new(0.141, 0.157, 0.231, 1.0),
slider_fill_color: Vec4::new(0.478, 0.635, 0.969, 1.0),
input_background_color: Vec4::new(0.063, 0.067, 0.110, 1.0),
input_background_focused: Vec4::new(0.102, 0.106, 0.149, 1.0),
selection_color: Vec4::new(0.220, 0.243, 0.353, 0.6),
scrollbar_color: Vec4::new(0.329, 0.369, 0.502, 0.4),
scrollbar_color_hovered: Vec4::new(0.329, 0.369, 0.502, 0.7),
border_width: 1.0,
corner_radius: 4.0,
padding: 8.0,
spacing: 6.0,
font_size: 18.0,
button_height: 32.0,
slider_height: 24.0,
checkbox_size: 20.0,
toggle_width: 40.0,
toggle_height: 22.0,
panel_header_height: 28.0,
}
}
pub fn catppuccin_mocha() -> Self {
Self {
name: "Catppuccin Mocha".to_string(),
dark_mode: true,
text_color: Vec4::new(0.804, 0.839, 0.957, 1.0),
text_color_disabled: Vec4::new(0.345, 0.357, 0.439, 1.0),
text_color_accent: Vec4::new(0.537, 0.706, 0.980, 1.0),
background_color: Vec4::new(0.118, 0.118, 0.180, 1.0),
background_color_hovered: Vec4::new(0.192, 0.196, 0.267, 1.0),
background_color_active: Vec4::new(0.271, 0.278, 0.353, 1.0),
panel_color: Vec4::new(0.118, 0.118, 0.180, 1.0),
panel_header_color: Vec4::new(0.192, 0.196, 0.267, 1.0),
border_color: Vec4::new(0.345, 0.357, 0.439, 1.0),
border_color_focused: Vec4::new(0.537, 0.706, 0.980, 1.0),
accent_color: Vec4::new(0.537, 0.706, 0.980, 1.0),
accent_color_hovered: Vec4::new(0.608, 0.765, 1.0, 1.0),
accent_color_active: Vec4::new(0.431, 0.612, 0.878, 1.0),
success_color: Vec4::new(0.651, 0.890, 0.631, 1.0),
warning_color: Vec4::new(0.976, 0.886, 0.686, 1.0),
error_color: Vec4::new(0.953, 0.545, 0.659, 1.0),
slider_track_color: Vec4::new(0.192, 0.196, 0.267, 1.0),
slider_fill_color: Vec4::new(0.537, 0.706, 0.980, 1.0),
input_background_color: Vec4::new(0.067, 0.067, 0.106, 1.0),
input_background_focused: Vec4::new(0.118, 0.118, 0.180, 1.0),
selection_color: Vec4::new(0.345, 0.357, 0.439, 0.5),
scrollbar_color: Vec4::new(0.345, 0.357, 0.439, 0.4),
scrollbar_color_hovered: Vec4::new(0.345, 0.357, 0.439, 0.7),
border_width: 1.0,
corner_radius: 4.0,
padding: 8.0,
spacing: 6.0,
font_size: 18.0,
button_height: 32.0,
slider_height: 24.0,
checkbox_size: 20.0,
toggle_width: 40.0,
toggle_height: 22.0,
panel_header_height: 28.0,
}
}
pub fn solarized_dark() -> Self {
Self {
name: "Solarized Dark".to_string(),
dark_mode: true,
text_color: Vec4::new(0.514, 0.580, 0.588, 1.0),
text_color_disabled: Vec4::new(0.345, 0.431, 0.459, 1.0),
text_color_accent: Vec4::new(0.149, 0.545, 0.824, 1.0),
background_color: Vec4::new(0.000, 0.169, 0.212, 1.0),
background_color_hovered: Vec4::new(0.027, 0.212, 0.259, 1.0),
background_color_active: Vec4::new(0.055, 0.263, 0.32, 1.0),
panel_color: Vec4::new(0.000, 0.169, 0.212, 1.0),
panel_header_color: Vec4::new(0.027, 0.212, 0.259, 1.0),
border_color: Vec4::new(0.345, 0.431, 0.459, 1.0),
border_color_focused: Vec4::new(0.149, 0.545, 0.824, 1.0),
accent_color: Vec4::new(0.149, 0.545, 0.824, 1.0),
accent_color_hovered: Vec4::new(0.204, 0.600, 0.867, 1.0),
accent_color_active: Vec4::new(0.102, 0.463, 0.714, 1.0),
success_color: Vec4::new(0.522, 0.600, 0.000, 1.0),
warning_color: Vec4::new(0.710, 0.537, 0.000, 1.0),
error_color: Vec4::new(0.863, 0.196, 0.184, 1.0),
slider_track_color: Vec4::new(0.027, 0.212, 0.259, 1.0),
slider_fill_color: Vec4::new(0.149, 0.545, 0.824, 1.0),
input_background_color: Vec4::new(0.000, 0.118, 0.149, 1.0),
input_background_focused: Vec4::new(0.000, 0.169, 0.212, 1.0),
selection_color: Vec4::new(0.345, 0.431, 0.459, 0.4),
scrollbar_color: Vec4::new(0.345, 0.431, 0.459, 0.4),
scrollbar_color_hovered: Vec4::new(0.345, 0.431, 0.459, 0.7),
border_width: 1.0,
corner_radius: 4.0,
padding: 8.0,
spacing: 6.0,
font_size: 18.0,
button_height: 32.0,
slider_height: 24.0,
checkbox_size: 20.0,
toggle_width: 40.0,
toggle_height: 22.0,
panel_header_height: 28.0,
}
}
pub fn one_dark() -> Self {
Self {
name: "One Dark".to_string(),
dark_mode: true,
text_color: Vec4::new(0.671, 0.698, 0.749, 1.0),
text_color_disabled: Vec4::new(0.353, 0.376, 0.431, 1.0),
text_color_accent: Vec4::new(0.380, 0.686, 0.937, 1.0),
background_color: Vec4::new(0.157, 0.173, 0.204, 1.0),
background_color_hovered: Vec4::new(0.196, 0.220, 0.259, 1.0),
background_color_active: Vec4::new(0.239, 0.259, 0.302, 1.0),
panel_color: Vec4::new(0.129, 0.145, 0.169, 1.0),
panel_header_color: Vec4::new(0.157, 0.173, 0.204, 1.0),
border_color: Vec4::new(0.239, 0.259, 0.302, 1.0),
border_color_focused: Vec4::new(0.380, 0.686, 0.937, 1.0),
accent_color: Vec4::new(0.380, 0.686, 0.937, 1.0),
accent_color_hovered: Vec4::new(0.451, 0.741, 0.980, 1.0),
accent_color_active: Vec4::new(0.290, 0.596, 0.847, 1.0),
success_color: Vec4::new(0.596, 0.765, 0.478, 1.0),
warning_color: Vec4::new(0.898, 0.753, 0.482, 1.0),
error_color: Vec4::new(0.878, 0.424, 0.459, 1.0),
slider_track_color: Vec4::new(0.196, 0.220, 0.259, 1.0),
slider_fill_color: Vec4::new(0.380, 0.686, 0.937, 1.0),
input_background_color: Vec4::new(0.082, 0.090, 0.106, 1.0),
input_background_focused: Vec4::new(0.129, 0.145, 0.169, 1.0),
selection_color: Vec4::new(0.239, 0.259, 0.302, 0.5),
scrollbar_color: Vec4::new(0.353, 0.376, 0.431, 0.4),
scrollbar_color_hovered: Vec4::new(0.353, 0.376, 0.431, 0.7),
border_width: 1.0,
corner_radius: 4.0,
padding: 8.0,
spacing: 6.0,
font_size: 18.0,
button_height: 32.0,
slider_height: 24.0,
checkbox_size: 20.0,
toggle_width: 40.0,
toggle_height: 22.0,
panel_header_height: 28.0,
}
}
pub fn all_presets() -> Vec<Self> {
vec![
Self::dark(),
Self::dracula(),
Self::nord(),
Self::gruvbox_dark(),
Self::monokai(),
Self::tokyo_night(),
Self::catppuccin_mocha(),
Self::solarized_dark(),
Self::one_dark(),
Self::light(),
]
}
}
#[derive(Clone, Debug)]
pub struct ThemeState {
pub current_theme: UiTheme,
pub presets: Vec<UiTheme>,
pub selected_preset_index: Option<usize>,
pub preview_theme_index: Option<usize>,
pub generation: u64,
pub last_applied_generation: u64,
}
impl Default for ThemeState {
fn default() -> Self {
let presets = UiTheme::all_presets();
Self {
current_theme: presets[0].clone(),
presets,
selected_preset_index: Some(0),
preview_theme_index: None,
generation: 0,
last_applied_generation: 0,
}
}
}
impl ThemeState {
pub fn active_theme(&self) -> &UiTheme {
self.preview_theme_index
.and_then(|index| self.presets.get(index))
.unwrap_or(&self.current_theme)
}
pub fn select_theme(&mut self, index: usize) {
if let Some(preset) = self.presets.get(index) {
self.current_theme = preset.clone();
self.selected_preset_index = Some(index);
self.generation += 1;
}
}
pub fn set_preview(&mut self, index: Option<usize>) {
if self.preview_theme_index != index {
self.preview_theme_index = index;
self.generation += 1;
}
}
pub fn clear_preview(&mut self) {
if self.preview_theme_index.is_some() {
self.preview_theme_index = None;
self.generation += 1;
}
}
}