167 lines
4.2 KiB
Rust
167 lines
4.2 KiB
Rust
use iced::Color;
|
|
use iced::Element;
|
|
use iced::Task;
|
|
use iced::widget::container;
|
|
use iced::widget::row;
|
|
use iced::widget::text;
|
|
use iced_layershell::daemon;
|
|
use iced_layershell::reexport::Anchor;
|
|
use iced_layershell::settings::LayerShellSettings;
|
|
use iced_layershell::settings::Settings;
|
|
use iced_layershell::to_layer_message;
|
|
use std::time::Duration;
|
|
|
|
pub fn main() -> Result<(), iced_layershell::Error> {
|
|
daemon(App::default, || "rbaw".into(), App::update, App::view)
|
|
.style(App::style)
|
|
.theme(App::theme)
|
|
.subscription(App::subscription)
|
|
.settings(Settings {
|
|
layer_settings: LayerShellSettings {
|
|
size: Some((0, 32)),
|
|
exclusive_zone: 32,
|
|
anchor: Anchor::Top | Anchor::Left | Anchor::Right,
|
|
start_mode: iced_layershell::settings::StartMode::AllScreens, // valid here in daemon
|
|
..Default::default()
|
|
},
|
|
..Default::default()
|
|
})
|
|
.run()
|
|
}
|
|
|
|
struct App {
|
|
time_widget: TimeWidget,
|
|
battery_widget: BatteryWidget,
|
|
}
|
|
|
|
impl Default for App {
|
|
fn default() -> Self {
|
|
let mut output = Self {
|
|
time_widget: Default::default(),
|
|
battery_widget: Default::default(),
|
|
};
|
|
let _ = output.update(Message::Clock);
|
|
|
|
output
|
|
}
|
|
}
|
|
|
|
impl App {
|
|
fn view(&self, _id: iced::window::Id) -> Element<'_, Message> {
|
|
let content = row![
|
|
self.time_widget.view(),
|
|
iced::widget::space().width(iced::Length::Fill),
|
|
self.battery_widget.view(),
|
|
]
|
|
.padding(iced::Padding::from([0, 5]))
|
|
.height(iced::Length::Fill)
|
|
.width(iced::Length::Fill)
|
|
.align_y(iced::Alignment::Center);
|
|
|
|
container(content).into()
|
|
}
|
|
|
|
fn update(&mut self, message: Message) -> Task<Message> {
|
|
if let Message::Clock = message {
|
|
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 {
|
|
IcedEvent(iced::Event),
|
|
Clock,
|
|
}
|