diff --git a/Cargo.toml b/Cargo.toml index 465401d..1ddbab0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2021" [dependencies] -gtk4 = "0.11" +gtk4 = { version = "0.11", features = ["v4_12"] } gtk4-layer-shell = "0.8" relm4 = { version = "0.11", features = ["macros"] } hyprland = "0.4.0-beta.3" diff --git a/src/main.rs b/src/main.rs index 1ad4518..163ca6b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -16,8 +16,38 @@ impl SimpleComponent for App { view! { gtk::ApplicationWindow { + add_css_class: "aster-bar", set_title: Some("aster"), set_default_height: 32, + + gtk::CenterBox { + #[wrap(Some)] + set_start_widget = >k::Box { + set_orientation: gtk::Orientation::Horizontal, + set_spacing: 4, + set_margin_start: 8, + + gtk::Label { + set_label: "1 2 3", + } + }, + + #[wrap(Some)] + set_center_widget = >k::Label { + set_label: "00:00", + }, + + #[wrap(Some)] + set_end_widget = >k::Box { + set_orientation: gtk::Orientation::Horizontal, + set_spacing: 8, + set_margin_end: 8, + + gtk::Label { + set_label: "— — — —", + } + }, + } } } @@ -35,6 +65,9 @@ impl SimpleComponent for App { let model = App; let widgets = view_output!(); + + theme::apply(); + ComponentParts { model, widgets } } diff --git a/src/theme.rs b/src/theme.rs index 8b13789..460f594 100644 --- a/src/theme.rs +++ b/src/theme.rs @@ -1 +1,67 @@ +use gtk4::CssProvider; +use serde::Deserialize; +#[derive(Deserialize)] +struct WalColors { + special: Special, + colors: Colors, +} + +#[derive(Deserialize)] +struct Special { + background: String, +} + +#[derive(Deserialize)] +struct Colors { + color0: String, + color1: String, + color15: String, +} + +fn hex_to_rgba(hex: &str, alpha: f32) -> String { + let h = hex.trim_start_matches('#'); + let r = u8::from_str_radix(&h[0..2], 16).unwrap_or(0); + let g = u8::from_str_radix(&h[2..4], 16).unwrap_or(0); + let b = u8::from_str_radix(&h[4..6], 16).unwrap_or(0); + format!("rgba({r},{g},{b},{alpha})") +} + +fn load_css() -> String { + let home = std::env::var("HOME").unwrap_or_default(); + let text = std::fs::read_to_string(format!("{home}/.cache/wal/colors.json")) + .unwrap_or_default(); + + let (bg, surface, fg, accent) = if let Ok(wal) = serde_json::from_str::(&text) { + (wal.special.background, wal.colors.color0, wal.colors.color15, wal.colors.color1) + } else { + ( + "#1e1e2e".to_string(), + "#181825".to_string(), + "#cdd6f4".to_string(), + "#89b4fa".to_string(), + ) + }; + + format!( + "window.aster-bar {{ background-color: {bg_rgba}; }}\ + .workspace-btn {{ background: {surface}; color: {fg}; border-radius: 4px;\ + border: none; min-width: 24px; padding: 0 8px; }}\ + .workspace-btn:hover, .workspace-btn.active {{ background: {accent}; }}\ + label {{ color: {fg}; }}", + bg_rgba = hex_to_rgba(&bg, 0.92), + surface = surface, + fg = fg, + accent = accent, + ) +} + +pub fn apply() { + let provider = CssProvider::new(); + provider.load_from_string(&load_css()); + gtk4::style_context_add_provider_for_display( + >k4::gdk::Display::default().expect("no display"), + &provider, + gtk4::STYLE_PROVIDER_PRIORITY_APPLICATION, + ); +}