Files
rlogg/src/theme.rs
2025-12-09 20:50:10 +01:00

179 lines
6.3 KiB
Rust

use eframe::egui;
/// Modern dark purple color palette
pub struct ColorPalette {
// Background colors
pub bg_primary: egui::Color32, // Main background
pub bg_secondary: egui::Color32, // Secondary panels
pub bg_tertiary: egui::Color32, // Elevated elements
// Accent colors
pub accent_primary: egui::Color32, // Primary purple accent
pub accent_secondary: egui::Color32, // Secondary accent
pub accent_bright: egui::Color32, // Bright highlights
// Text colors
pub text_primary: egui::Color32,
pub text_secondary: egui::Color32,
pub text_muted: egui::Color32,
// UI element colors
pub selection: egui::Color32,
pub line_number: egui::Color32,
pub border: egui::Color32,
}
impl ColorPalette {
pub fn dark_purple() -> Self {
Self {
// Deep purple-gray backgrounds
bg_primary: egui::Color32::from_rgb(24, 20, 32), // #18141F
bg_secondary: egui::Color32::from_rgb(32, 26, 42), // #201A2A
bg_tertiary: egui::Color32::from_rgb(42, 35, 54), // #2A2336
// Purple accents - modern and vibrant
accent_primary: egui::Color32::from_rgb(138, 98, 208), // #8A62D0
accent_secondary: egui::Color32::from_rgb(108, 68, 178), // #6C44B2
accent_bright: egui::Color32::from_rgb(168, 128, 238), // #A880EE
// Text colors with good contrast
text_primary: egui::Color32::from_rgb(230, 230, 240), // #E6E6F0
text_secondary: egui::Color32::from_rgb(190, 190, 210), // #BEBED2
text_muted: egui::Color32::from_rgb(140, 140, 165), // #8C8CA5
// UI elements
selection: egui::Color32::from_rgb(108, 68, 178), // #6C44B2
line_number: egui::Color32::from_rgb(110, 100, 130), // #6E6482
border: egui::Color32::from_rgb(60, 50, 75), // #3C324B
}
}
}
/// Apply the dark purple theme to the egui context
pub fn apply_theme(ctx: &egui::Context) {
let palette = ColorPalette::dark_purple();
let mut style = (*ctx.style()).clone();
// === Spacing and sizing for better UX ===
style.spacing.item_spacing = egui::vec2(8.0, 6.0);
style.spacing.button_padding = egui::vec2(12.0, 6.0);
style.spacing.menu_margin = egui::Margin::same(8.0);
style.spacing.indent = 20.0;
style.spacing.scroll = egui::style::ScrollStyle {
bar_width: 10.0,
handle_min_length: 20.0,
bar_inner_margin: 2.0,
bar_outer_margin: 0.0,
..Default::default()
};
// === Color scheme ===
let visuals = &mut style.visuals;
// Dark mode
visuals.dark_mode = true;
// Window and panel backgrounds
visuals.window_fill = palette.bg_primary;
visuals.panel_fill = palette.bg_primary;
visuals.faint_bg_color = palette.bg_secondary;
visuals.extreme_bg_color = palette.bg_tertiary;
// Text colors (using override_text_color to set custom text color)
visuals.override_text_color = Some(palette.text_primary);
// Widget colors
visuals.widgets.noninteractive.bg_fill = palette.bg_secondary;
visuals.widgets.noninteractive.weak_bg_fill = palette.bg_secondary;
visuals.widgets.noninteractive.bg_stroke = egui::Stroke::new(1.0, palette.border);
visuals.widgets.noninteractive.fg_stroke = egui::Stroke::new(1.0, palette.text_secondary);
// Inactive/hovered widgets
visuals.widgets.inactive.bg_fill = palette.bg_secondary;
visuals.widgets.inactive.weak_bg_fill = palette.bg_secondary;
visuals.widgets.inactive.bg_stroke = egui::Stroke::new(1.0, palette.border);
visuals.widgets.inactive.fg_stroke = egui::Stroke::new(1.0, palette.text_primary);
visuals.widgets.hovered.bg_fill = palette.bg_tertiary;
visuals.widgets.hovered.weak_bg_fill = palette.bg_tertiary;
visuals.widgets.hovered.bg_stroke = egui::Stroke::new(1.5, palette.accent_primary);
visuals.widgets.hovered.fg_stroke = egui::Stroke::new(1.5, palette.text_primary);
// Active/clicked widgets
visuals.widgets.active.bg_fill = palette.accent_secondary;
visuals.widgets.active.weak_bg_fill = palette.accent_secondary;
visuals.widgets.active.bg_stroke = egui::Stroke::new(2.0, palette.accent_bright);
visuals.widgets.active.fg_stroke = egui::Stroke::new(2.0, palette.text_primary);
visuals.widgets.open.bg_fill = palette.accent_secondary;
visuals.widgets.open.weak_bg_fill = palette.accent_secondary;
visuals.widgets.open.bg_stroke = egui::Stroke::new(1.5, palette.accent_primary);
visuals.widgets.open.fg_stroke = egui::Stroke::new(1.5, palette.text_primary);
// Selection
visuals.selection.bg_fill = palette.selection;
visuals.selection.stroke = egui::Stroke::new(1.0, palette.accent_bright);
// Hyperlinks
visuals.hyperlink_color = palette.accent_bright;
// Window styling
visuals.window_rounding = egui::Rounding::same(8.0);
visuals.window_shadow = egui::epaint::Shadow {
offset: egui::vec2(0.0, 8.0),
blur: 20.0,
spread: 0.0,
color: egui::Color32::from_black_alpha(80),
};
visuals.window_stroke = egui::Stroke::new(1.0, palette.border);
// Popup styling
visuals.popup_shadow = egui::epaint::Shadow {
offset: egui::vec2(0.0, 4.0),
blur: 16.0,
spread: 0.0,
color: egui::Color32::from_black_alpha(100),
};
// Resize handle
visuals.resize_corner_size = 12.0;
// Menu rounding
visuals.menu_rounding = egui::Rounding::same(6.0);
// Indent guide
visuals.indent_has_left_vline = true;
visuals.striped = true;
// Borders and separators
visuals.window_stroke = egui::Stroke::new(1.0, palette.border);
// === Text styles with better readability ===
style.text_styles.insert(
egui::TextStyle::Body,
egui::FontId::proportional(14.0),
);
style.text_styles.insert(
egui::TextStyle::Button,
egui::FontId::proportional(14.0),
);
style.text_styles.insert(
egui::TextStyle::Heading,
egui::FontId::proportional(18.0),
);
style.text_styles.insert(
egui::TextStyle::Monospace,
egui::FontId::monospace(13.0),
);
// Apply the style
ctx.set_style(style);
}
/// Get the color palette for use in custom rendering
pub fn get_palette() -> ColorPalette {
ColorPalette::dark_purple()
}