Widget system

This commit is contained in:
Jiří Maxmilián Stříbrný 2026-03-17 20:53:46 +01:00
parent 958b7714da
commit 51d49b9cf1
2 changed files with 89 additions and 23 deletions

View file

@ -1,4 +1,3 @@
use chrono::Local;
use iced::Color;
use iced::Element;
use iced::Task;
@ -31,15 +30,15 @@ pub fn main() -> Result<(), iced_layershell::Error> {
}
struct App {
time: chrono::DateTime<chrono::Local>,
battery: String,
time_widget: TimeWidget,
battery_widget: BatteryWidget,
}
impl Default for App {
fn default() -> Self {
let mut output = Self {
time: Default::default(),
battery: Default::default(),
time_widget: Default::default(),
battery_widget: Default::default(),
};
let _ = output.update(Message::Clock);
@ -49,12 +48,10 @@ impl Default for App {
impl App {
fn view(&self, _id: iced::window::Id) -> Element<'_, Message> {
let display_time = self.time.format("%H:%M");
let content = row![
text!("{}", display_time),
self.time_widget.view(),
iced::widget::space().width(iced::Length::Fill),
text!("{}", self.battery),
self.battery_widget.view(),
]
.padding(iced::Padding::from([0, 5]))
.height(iced::Length::Fill)
@ -66,33 +63,102 @@ impl App {
fn update(&mut self, message: Message) -> Task<Message> {
if let Message::Clock = message {
self.time = Local::now();
self.battery = format!(
"{} 󰁽",
std::fs::read_to_string(std::path::Path::new(
"/sys/class/power_supply/BAT0/capacity",
))
.unwrap()
.trim_ascii_end()
);
self.time_widget.update();
}
Task::none()
}
fn style(&self, theme: &iced::Theme) -> iced::theme::Style {
iced::theme::Style {
background_color: Color::TRANSPARENT,
text_color: theme.palette().text,
}
}
fn theme(&self, _id: iced::window::Id) -> iced::Theme {
iced::Theme::GruvboxDark
}
fn subscription(&self) -> iced::Subscription<Message> {
iced::time::every(Duration::from_secs(1)).map(|_| Message::Clock)
}
}
trait PanelWidget {
fn update(&mut self);
fn view(&self) -> Element<'_, Message>;
}
#[derive(Default)]
struct BatteryWidget {
battery: Option<usize>,
}
impl PanelWidget for BatteryWidget {
fn update(&mut self) {
let file_content = std::fs::read_to_string(std::path::Path::new(
"/sys/class/power_supply/BAT0/capacity",
));
let Ok(file_string) = file_content else {
self.battery = None;
return;
};
let file_string = file_string.trim();
let Ok(value) = file_string.parse::<usize>() else {
self.battery = None;
return;
};
self.battery = Some(value);
}
fn view(&self) -> Element<'_, Message> {
match self.battery {
Some(battery) => text!("{} {}", battery.to_string(), Self::get_icon(battery)),
None => text("󱉞"),
}
.into()
}
}
impl BatteryWidget {
fn get_icon(battery: usize) -> &'static str {
match battery {
0..6 => "󰂎",
6..11 => "󰁺",
11..21 => "󰁻",
21..31 => "󰁼",
31..41 => "󰁽",
41..51 => "󰁾",
51..61 => "󰁿",
61..71 => "󰂀",
71..81 => "󰂁",
81..91 => "󰂂",
91..101 => "󰁹",
_ => "󰂃",
}
}
}
#[derive(Default)]
struct TimeWidget {
current_time: chrono::DateTime<chrono::Local>,
}
impl PanelWidget for TimeWidget {
fn update(&mut self) {
self.current_time = chrono::Local::now();
}
fn view(&self) -> Element<'_, Message> {
text!("{}", self.current_time.format("%H:%m")).into()
}
}
#[to_layer_message]
#[derive(Debug)]
enum Message {