Refactor SquareIconWidget & remove redundant classes

- Eliminate `BatteryWidget`
- Pass all properties to reusable `SquareIconWidget`
- Eliminate need for duplication
This commit is contained in:
Candifloss 2025-11-22 23:00:56 +05:30
parent 42ee42b904
commit 3dca171063
4 changed files with 56 additions and 32 deletions

View File

@ -1,9 +1,9 @@
use super::common::run_cmd; use super::common::run_cmd;
use crate::TopBar; use crate::TopBar;
use slint::{ComponentHandle, SharedString, Timer, TimerMode}; use slint::{Color, ComponentHandle, SharedString, Timer, TimerMode};
use std::{fs, time::Duration}; use std::{fs, time::Duration};
// Read and trim a file // Read and trim a sysfs file
fn read_sys(path: &str) -> String { fn read_sys(path: &str) -> String {
fs::read_to_string(path) fs::read_to_string(path)
.unwrap_or_default() .unwrap_or_default()
@ -11,7 +11,7 @@ fn read_sys(path: &str) -> String {
.to_string() .to_string()
} }
// Convert battery state strings into normalized tokens // Normalize battery status strings
fn normalize_status(s: &str) -> String { fn normalize_status(s: &str) -> String {
s.to_lowercase() s.to_lowercase()
.chars() .chars()
@ -19,7 +19,7 @@ fn normalize_status(s: &str) -> String {
.collect() .collect()
} }
// Map numeric capacity → level tags // Fallback: Derive level from %
fn capacity_level(cap: u8) -> String { fn capacity_level(cap: u8) -> String {
match cap { match cap {
0..=10 => "critical".into(), 0..=10 => "critical".into(),
@ -30,7 +30,7 @@ fn capacity_level(cap: u8) -> String {
} }
} }
// Choose icon from status + level // Pick icon from status + level
fn select_icon(status: &str, level: &str) -> SharedString { fn select_icon(status: &str, level: &str) -> SharedString {
let icon = match status { let icon = match status {
"charging" => match level { "charging" => match level {
@ -51,19 +51,32 @@ fn select_icon(status: &str, level: &str) -> SharedString {
}, },
"notcharging" => "󰂃", "notcharging" => "󰂃",
"full" => "󰂄", "full" => "󰂄",
_ => "󰂑", // Unknown fallback _ => "󰂑", // Unknown -> fallback
}; };
SharedString::from(icon) SharedString::from(icon)
} }
// Main battery updater logic // Pick icon color from level
fn select_color(level: &str) -> Color {
let hex = match level {
"full" => 0xff_24_6c_7a,
"high" => 0xff_0b_aa_75,
"normal" => 0xff_26_a0_34,
"low" => 0xff_d1_67_17,
"critical" => 0xff_e8_19_27,
_ => 0xff_e2_ef_2b, // unknown
};
Color::from_argb_encoded(hex)
}
// Timer loop: Main battery updater logic
fn start_battery_updater(ui: &TopBar) { fn start_battery_updater(ui: &TopBar) {
let weak = ui.as_weak(); let weak = ui.as_weak();
// Timer fires every second (battery can change quickly) // Timer fires every second (battery can change quickly)
let timer = Box::leak(Box::new(Timer::default())); let timer = Box::leak(Box::new(Timer::default()));
timer.start(TimerMode::Repeated, Duration::from_secs(1), move || { timer.start(TimerMode::Repeated, Duration::from_secs(1), move || {
if let Some(ui) = weak.upgrade() { if let Some(ui) = weak.upgrade() {
// Read sysfs values // Read sysfs values
@ -74,31 +87,34 @@ fn start_battery_updater(ui: &TopBar) {
// Normalize values // Normalize values
let status = normalize_status(&status_str); let status = normalize_status(&status_str);
let cap: u8 = cap_str.parse().unwrap_or(0); let cap: u8 = cap_str.parse().unwrap_or(0);
let level = normalize_status(&level_str); // low, normal, full, etc. let level_norm = normalize_status(&level_str); // low, normal, full, etc.
let level_calc = capacity_level(cap); // fallback level let level_calc = capacity_level(cap); // Fallback
// Prefer kernel level if valid; otherwise use cap-based level // Prefer kernel level if valid; otherwise use cap-based level
let final_level = if level.is_empty() { level_calc } else { level }; let final_level = if level_norm.is_empty() {
level_calc
} else {
level_norm
};
// Select icon // Icon + color
let icon = select_icon(&status, &final_level); let icon = select_icon(&status, &final_level);
let color = select_color(&final_level);
// Compose tooltip text (Rust handles it now) // Tooltip
let tooltip = format!("Battery: {cap}% ({status})"); let tooltip = format!("Battery: {cap}% ({status}, {final_level})");
// Update Slint properties // Push properties to Slint UI
ui.set_battery_icon(icon); ui.set_battery_icon(icon);
ui.set_battery_capacity_level(final_level.into()); ui.set_battery_icon_color(color);
ui.set_battery_tooltip(tooltip.into()); ui.set_battery_tooltip(tooltip.into());
} }
}); });
} }
// Public entry: connect click callback + start updater // Connect callback + start updater loop
pub fn install(ui: &TopBar) { pub fn install(ui: &TopBar) {
let weak = ui.as_weak(); let weak = ui.as_weak();
// Click → open battery monitor
ui.on_show_battery(move || { ui.on_show_battery(move || {
if weak.upgrade().is_some() { if weak.upgrade().is_some() {
run_cmd("xclock"); // Placeholder: Fix later run_cmd("xclock"); // Placeholder: Fix later

View File

@ -1,5 +0,0 @@
import { SquareIconWidget } from "square-icon-widget.slint";
export component BatteryWidget inherits SquareIconWidget {
in property <string> battery_capacity_level; // To determine icon color later
}

View File

@ -5,15 +5,21 @@ export component SquareIconWidget {
in property <string> icon_text; in property <string> icon_text;
in property <string> tooltip_text; in property <string> tooltip_text;
// Colors
in property <color> icon_color: #ffffff;
in property <color> bg_normal: #8e9162;
in property <color> bg_hover: #6d8a4d;
in property <color> bg_clicked: #4a5f70;
callback square_btn_callback(); callback square_btn_callback();
height: bar_height * 1px; // Same height as the bar height: bar_height * 1px; // Same height as the bar
width: bar_height * 1px; // Square shape width: bar_height * 1px; // Square shape
Rectangle { Rectangle {
background: touch_area.pressed ? #4a5f70 background: touch_area.pressed ? bg_clicked
: touch_area.has-hover ? #6d8a4d : touch_area.has-hover ? bg_hover
: #8e9162; : bg_normal;
border-radius: 3px; border-radius: 3px;
HorizontalLayout { HorizontalLayout {
@ -22,7 +28,7 @@ export component SquareIconWidget {
Text { Text {
text: icon_text; // Every `SquareIconWidget` has an icon text: icon_text; // Every `SquareIconWidget` has an icon
color: white; color: icon_color;
vertical-alignment: center; vertical-alignment: center;
horizontal-alignment: center; horizontal-alignment: center;
} }

View File

@ -1,6 +1,6 @@
import { TimeWidget } from "time-widget.slint"; import { TimeWidget } from "time-widget.slint";
import { DateWidget } from "date-widget.slint"; import { DateWidget } from "date-widget.slint";
import { BatteryWidget } from "battery-widget.slint"; import { SquareIconWidget } from "square-icon-widget.slint";
export component TopBar inherits Window { export component TopBar inherits Window {
@ -21,7 +21,10 @@ export component TopBar inherits Window {
// Battery widget // Battery widget
in property <string> battery_tooltip; in property <string> battery_tooltip;
in property <string> battery_icon; in property <string> battery_icon;
in property <string> battery_capacity_level; in property <color> battery_icon_color: #ffffff;
in property <color> battery_bg_normal: #8e9162;
in property <color> battery_bg_hover: #6d8a4d;
in property <color> battery_bg_clicked: #4a5f70;
callback show_battery(); callback show_battery();
@ -69,11 +72,15 @@ export component TopBar inherits Window {
HorizontalLayout { HorizontalLayout {
alignment: end; // Right-align alignment: end; // Right-align
BatteryWidget { // SquareIconWidget - Battery
SquareIconWidget {
bar_height: root.bar_height; bar_height: root.bar_height;
icon_text: root.battery_icon; icon_text: root.battery_icon;
tooltip_text: root.battery_tooltip; tooltip_text: root.battery_tooltip;
battery_capacity_level: root.battery_capacity_level; icon_color: root.battery_icon_color;
bg_normal: root.battery_bg_normal;
bg_hover: root.battery_bg_hover;
bg_clicked: root.battery_bg_clicked;
square_btn_callback => root.show_battery(); square_btn_callback => root.show_battery();
} }