pub const HYDRA: egui::Color32 = egui::Color32::from_rgb(110, 222, 148);
pub const SPECTRE: egui::Color32 = egui::Color32::from_rgb(118, 188, 242);
pub const BRAZEN: egui::Color32 = egui::Color32::from_rgb(232, 176, 96);
pub const BRAZEN_DIM: egui::Color32 = egui::Color32::from_rgb(184, 152, 104);
pub const ICHOR: egui::Color32 = egui::Color32::from_rgb(242, 108, 120);
pub const ASH: egui::Color32 = egui::Color32::from_rgb(150, 150, 166);
pub const SIGIL: egui::Color32 = egui::Color32::from_rgb(230, 118, 214);
pub const GATE: egui::Color32 = egui::Color32::from_rgb(160, 112, 240);
pub const TAGLINE: &str = "the key and the gate";
const VOID_WINDOW: egui::Color32 = egui::Color32::from_rgb(15, 12, 22);
const VOID_PANEL: egui::Color32 = egui::Color32::from_rgb(19, 15, 27);
const VOID_DEEP: egui::Color32 = egui::Color32::from_rgb(10, 8, 15);
const VOID_FAINT: egui::Color32 = egui::Color32::from_rgb(30, 24, 43);
const VOID_EDGE: egui::Color32 = egui::Color32::from_rgb(54, 43, 78);
const MOONLIT: egui::Color32 = egui::Color32::from_rgb(198, 190, 216);
const MOONLIT_BRIGHT: egui::Color32 = egui::Color32::from_rgb(216, 208, 234);
const MOONLIT_FULL: egui::Color32 = egui::Color32::from_rgb(240, 234, 250);
pub const PULSE_REPAINT_DELAY: std::time::Duration = std::time::Duration::from_millis(33);
const PULSE_RATE_RAD_PER_SEC: f64 = 4.0;
pub fn pulse(time: f64) -> egui::Color32 {
let alpha = (0.5 + 0.5 * (time * PULSE_RATE_RAD_PER_SEC).sin()).clamp(0.0, 1.0);
SPECTRE.gamma_multiply(0.35 + 0.65 * alpha as f32)
}
pub fn visuals() -> egui::Visuals {
let mut v = egui::Visuals::dark();
v.panel_fill = VOID_PANEL;
v.window_fill = VOID_WINDOW;
v.extreme_bg_color = VOID_DEEP;
v.code_bg_color = VOID_DEEP;
v.faint_bg_color = VOID_FAINT;
v.window_stroke = egui::Stroke::new(1.0, VOID_EDGE);
v.selection.bg_fill = GATE.gamma_multiply(0.35);
v.selection.stroke = egui::Stroke::new(1.0, GATE);
v.hyperlink_color = SPECTRE;
v.warn_fg_color = BRAZEN;
v.error_fg_color = ICHOR;
v.widgets.noninteractive.bg_fill = egui::Color32::from_rgb(24, 19, 34);
v.widgets.noninteractive.weak_bg_fill = VOID_FAINT;
v.widgets.noninteractive.bg_stroke = egui::Stroke::new(1.0, VOID_EDGE);
v.widgets.noninteractive.fg_stroke.color = MOONLIT;
v.widgets.inactive.bg_fill = egui::Color32::from_rgb(36, 29, 52);
v.widgets.inactive.weak_bg_fill = egui::Color32::from_rgb(28, 22, 40);
v.widgets.inactive.fg_stroke.color = MOONLIT_BRIGHT;
v.widgets.hovered.bg_fill = egui::Color32::from_rgb(48, 38, 70);
v.widgets.hovered.bg_stroke = egui::Stroke::new(1.0, GATE.gamma_multiply(0.6));
v.widgets.hovered.fg_stroke.color = MOONLIT_FULL;
v.widgets.active.bg_fill = egui::Color32::from_rgb(60, 47, 88);
v.widgets.active.bg_stroke = egui::Stroke::new(1.0, GATE);
v.widgets.active.fg_stroke.color = MOONLIT_FULL;
v.widgets.open.bg_fill = egui::Color32::from_rgb(36, 29, 52);
v.widgets.open.fg_stroke.color = MOONLIT_BRIGHT;
v
}
pub fn apply(ctx: &egui::Context) {
ctx.set_visuals(visuals());
}
pub fn state_badge(state: crate::git_tree::AgentState) -> (&'static str, egui::Color32) {
use crate::git_tree::AgentState;
match state {
AgentState::Live => ("●", HYDRA),
AgentState::InFlight => ("◐", SPECTRE),
AgentState::Quiescent => ("○", BRAZEN_DIM),
AgentState::Stopped => ("■", ASH),
}
}
pub fn integration_hue(tool: &str) -> egui::Color32 {
match tool {
"lernie" => HYDRA,
"bz" => BRAZEN,
"bl" => GATE,
_ => MOONLIT,
}
}
pub fn ball_hue(state: crate::projects::join::JoinState) -> egui::Color32 {
use crate::projects::join::JoinState;
match state {
JoinState::Bound => HYDRA,
JoinState::Delivered => ASH,
JoinState::Blocked | JoinState::ClaimedElsewhere => BRAZEN,
JoinState::OrphanedProject => ICHOR,
JoinState::ReadyStartable | JoinState::UnassignedWorkspace => MOONLIT,
}
}
pub fn wordmark(ui: &mut egui::Ui) {
ui.horizontal(|ui| {
ui.spacing_mut().item_spacing.x = 1.5;
for (hue, sphere) in [(HYDRA, "•"), (GATE, "●"), (BRAZEN, "•")] {
ui.colored_label(hue, sphere);
}
ui.add_space(5.0);
ui.heading(egui::RichText::new("yog").color(GATE).strong());
});
}
#[cfg(test)]
mod tests;