cleaner UI
This commit is contained in:
191
src/theme.rs
Normal file
191
src/theme.rs
Normal file
@@ -0,0 +1,191 @@
|
||||
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
|
||||
pub bg_hover: egui::Color32, // Hover states
|
||||
|
||||
// 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 highlight: egui::Color32,
|
||||
pub line_number: egui::Color32,
|
||||
pub border: egui::Color32,
|
||||
|
||||
// Status colors
|
||||
pub success: egui::Color32,
|
||||
pub warning: egui::Color32,
|
||||
pub error: 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
|
||||
bg_hover: egui::Color32::from_rgba_premultiplied(90, 75, 115, 40),
|
||||
|
||||
// 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
|
||||
highlight: egui::Color32::from_rgba_premultiplied(138, 98, 208, 60),
|
||||
line_number: egui::Color32::from_rgb(110, 100, 130), // #6E6482
|
||||
border: egui::Color32::from_rgb(60, 50, 75), // #3C324B
|
||||
|
||||
// Status colors
|
||||
success: egui::Color32::from_rgb(100, 200, 130), // #64C882
|
||||
warning: egui::Color32::from_rgb(255, 180, 80), // #FFB450
|
||||
error: egui::Color32::from_rgb(240, 100, 120), // #F06478
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 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()
|
||||
}
|
||||
Reference in New Issue
Block a user