diff --git a/src/widgets/brightnesswidget.rs b/src/widgets/brightnesswidget.rs new file mode 100644 index 0000000..ff8be29 --- /dev/null +++ b/src/widgets/brightnesswidget.rs @@ -0,0 +1,84 @@ +use super::common::run_cmd; +use crate::TopBar; +use slint::{ComponentHandle, SharedString, Timer, TimerMode}; +use std::{fs, time::Duration}; + +/// Read a file and trim whitespace +fn read_file(path: &str) -> Option { + fs::read_to_string(path).ok().map(|s| s.trim().to_string()) +} + +/// Return (`brightness`, `max_brightness`) +/// Use the first device listed under /sys/class/backlight/ +fn read_brightness_raw() -> Option<(u32, u32)> { + let base = "/sys/class/backlight"; + let mut entries = fs::read_dir(base).ok()?; + + // First device (intel_backlight, amdgpu_bl0, acpi_video0, etc.) + let dev = entries.next()?.ok()?.path(); + + let b = read_file(dev.join("brightness").to_str()?)?.parse().ok()?; + let m = read_file(dev.join("max_brightness").to_str()?)? + .parse() + .ok()?; + + Some((b, m)) +} + +/// Convert brightness raw values into a 0–100% percentage +fn brightness_percent() -> u8 { + if let Some((b, m)) = read_brightness_raw() + && m > 0 + { + return ((b as f32 / m as f32) * 100.0).round() as u8; + } + 0 +} + +/// Pick an icon based on percentage +fn brightness_icon(p: u8) -> SharedString { + let icon = match p { + 0 => "󰃞", // off + 1..=20 => "󰃝", // low + 21..=60 => "󰃟", // medium + _ => "󰃠", // high + }; + SharedString::from(icon) +} + +/// Tooltip text displayed when hovering the icon +fn brightness_tooltip(p: u8) -> String { + format!("Brightness: {p}%") +} + +/// Start timer to update brightness every second +fn start_brightness_updater(ui: &TopBar) { + let weak = ui.as_weak(); + + let timer = Box::leak(Box::new(Timer::default())); + timer.start(TimerMode::Repeated, Duration::from_secs(1), move || { + if let Some(ui) = weak.upgrade() { + // Read brightness + let p = brightness_percent(); + + // Update properties on the root component + ui.set_brightness_icon(brightness_icon(p)); + ui.set_brightness_tooltip(brightness_tooltip(p).into()); + } + }); +} + +/// Public entry for this widget +pub fn install(ui: &TopBar) { + let weak = ui.as_weak(); + + // Click callback (open brightness settings) + ui.on_show_brightness(move || { + if weak.upgrade().is_some() { + run_cmd("xclock"); // Fix later + } + }); + + // Start updating + start_brightness_updater(ui); +} diff --git a/src/widgets/mod.rs b/src/widgets/mod.rs index dd6e650..0f4a8ba 100644 --- a/src/widgets/mod.rs +++ b/src/widgets/mod.rs @@ -1,4 +1,5 @@ mod batterywidget; +mod brightnesswidget; mod common; mod datewidget; mod timewidget; @@ -11,6 +12,7 @@ pub fn install_callbacks(ui: &TopBar) { datewidget::install(ui); batterywidget::install(ui); volumewidget::install(ui); + brightnesswidget::install(ui); // In the future: // networkwidget::install(ui); diff --git a/ui/topbar.slint b/ui/topbar.slint index b90a04c..8cee5c4 100644 --- a/ui/topbar.slint +++ b/ui/topbar.slint @@ -27,7 +27,6 @@ export component TopBar inherits Window { in property battery_bg_clicked;*/ callback show_battery(); - // Volume widget in property volume_tooltip; in property volume_icon; @@ -37,6 +36,15 @@ export component TopBar inherits Window { in property volume_bg_clicked;*/ callback show_volume(); + // brightness widget + in property brightness_tooltip; + in property brightness_icon; + /*in property brightness_icon_color; + in property brightness_bg_normal; + in property brightness_bg_hover; + in property brightness_bg_clicked;*/ + callback show_brightness(); + title: "chocobar"; width: bar_width *1px; height: bar_height *1px; @@ -81,6 +89,18 @@ export component TopBar inherits Window { HorizontalLayout { alignment: end; // Right-align + // SquareIconWidget - brightness + SquareIconWidget { + bar_height: root.bar_height; + icon_text: root.brightness_icon; + tooltip_text: root.brightness_tooltip; + /*icon_color: root.brightness_icon_color; + bg_normal: root.brightness_bg_normal; + bg_hover: root.brightness_bg_hover; + bg_clicked: root.brightness_bg_clicked;*/ + square_btn_callback => root.show_brightness(); + } + // SquareIconWidget - Volume SquareIconWidget { bar_height: root.bar_height;