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 crate::TopBar;
use slint::{ComponentHandle, SharedString, Timer, TimerMode};
use slint::{Color, ComponentHandle, SharedString, Timer, TimerMode};
use std::{fs, time::Duration};
// Read and trim a file
// Read and trim a sysfs file
fn read_sys(path: &str) -> String {
fs::read_to_string(path)
.unwrap_or_default()
@ -11,7 +11,7 @@ fn read_sys(path: &str) -> String {
.to_string()
}
// Convert battery state strings into normalized tokens
// Normalize battery status strings
fn normalize_status(s: &str) -> String {
s.to_lowercase()
.chars()
@ -19,7 +19,7 @@ fn normalize_status(s: &str) -> String {
.collect()
}
// Map numeric capacity → level tags
// Fallback: Derive level from %
fn capacity_level(cap: u8) -> String {
match cap {
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 {
let icon = match status {
"charging" => match level {
@ -51,19 +51,32 @@ fn select_icon(status: &str, level: &str) -> SharedString {
},
"notcharging" => "󰂃",
"full" => "󰂄",
_ => "󰂑", // Unknown fallback
_ => "󰂑", // Unknown -> fallback
};
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) {
let weak = ui.as_weak();
// Timer fires every second (battery can change quickly)
let timer = Box::leak(Box::new(Timer::default()));
timer.start(TimerMode::Repeated, Duration::from_secs(1), move || {
if let Some(ui) = weak.upgrade() {
// Read sysfs values
@ -74,31 +87,34 @@ fn start_battery_updater(ui: &TopBar) {
// Normalize values
let status = normalize_status(&status_str);
let cap: u8 = cap_str.parse().unwrap_or(0);
let level = normalize_status(&level_str); // low, normal, full, etc.
let level_calc = capacity_level(cap); // fallback level
let level_norm = normalize_status(&level_str); // low, normal, full, etc.
let level_calc = capacity_level(cap); // Fallback
// 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 color = select_color(&final_level);
// Compose tooltip text (Rust handles it now)
let tooltip = format!("Battery: {cap}% ({status})");
// Tooltip
let tooltip = format!("Battery: {cap}% ({status}, {final_level})");
// Update Slint properties
// Push properties to Slint UI
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());
}
});
}
// Public entry: connect click callback + start updater
// Connect callback + start updater loop
pub fn install(ui: &TopBar) {
let weak = ui.as_weak();
// Click → open battery monitor
ui.on_show_battery(move || {
if weak.upgrade().is_some() {
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> 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();
height: bar_height * 1px; // Same height as the bar
width: bar_height * 1px; // Square shape
Rectangle {
background: touch_area.pressed ? #4a5f70
: touch_area.has-hover ? #6d8a4d
: #8e9162;
background: touch_area.pressed ? bg_clicked
: touch_area.has-hover ? bg_hover
: bg_normal;
border-radius: 3px;
HorizontalLayout {
@ -22,7 +28,7 @@ export component SquareIconWidget {
Text {
text: icon_text; // Every `SquareIconWidget` has an icon
color: white;
color: icon_color;
vertical-alignment: center;
horizontal-alignment: center;
}

View File

@ -1,6 +1,6 @@
import { TimeWidget } from "time-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 {
@ -21,7 +21,10 @@ export component TopBar inherits Window {
// Battery widget
in property <string> battery_tooltip;
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();
@ -69,11 +72,15 @@ export component TopBar inherits Window {
HorizontalLayout {
alignment: end; // Right-align
BatteryWidget {
// SquareIconWidget - Battery
SquareIconWidget {
bar_height: root.bar_height;
icon_text: root.battery_icon;
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();
}