step 3+4: pywal theme loader, three-section CenterBox layout

This commit is contained in:
Breadway 2026-05-17 01:00:32 +08:00
parent ccf5f67fde
commit 542cbae939
3 changed files with 100 additions and 1 deletions

View file

@ -4,7 +4,7 @@ version = "0.1.0"
edition = "2021" edition = "2021"
[dependencies] [dependencies]
gtk4 = "0.11" gtk4 = { version = "0.11", features = ["v4_12"] }
gtk4-layer-shell = "0.8" gtk4-layer-shell = "0.8"
relm4 = { version = "0.11", features = ["macros"] } relm4 = { version = "0.11", features = ["macros"] }
hyprland = "0.4.0-beta.3" hyprland = "0.4.0-beta.3"

View file

@ -16,8 +16,38 @@ impl SimpleComponent for App {
view! { view! {
gtk::ApplicationWindow { gtk::ApplicationWindow {
add_css_class: "aster-bar",
set_title: Some("aster"), set_title: Some("aster"),
set_default_height: 32, set_default_height: 32,
gtk::CenterBox {
#[wrap(Some)]
set_start_widget = &gtk::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 = &gtk::Label {
set_label: "00:00",
},
#[wrap(Some)]
set_end_widget = &gtk::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 model = App;
let widgets = view_output!(); let widgets = view_output!();
theme::apply();
ComponentParts { model, widgets } ComponentParts { model, widgets }
} }

View file

@ -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::<WalColors>(&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(
&gtk4::gdk::Display::default().expect("no display"),
&provider,
gtk4::STYLE_PROVIDER_PRIORITY_APPLICATION,
);
}