power button implemented (without the power button functionality)

This commit is contained in:
Jiří Maxmilián Stříbrný 2026-03-20 22:46:21 +01:00
parent 23fe371656
commit 3789f5eb7b
4 changed files with 99 additions and 2 deletions

View file

@ -1,6 +1,7 @@
use crate::widget::{Message, PanelWidget};
use crate::widgets::battery::BatteryWidget;
use crate::widgets::clock::ClockWidget;
use crate::widgets::powerbutton::ShutdownWidget;
use crate::widgets::spacer::Spacer;
use iced::Color;
@ -20,6 +21,8 @@ impl App {
widgets: vec![
Box::new(ClockWidget::new()),
Box::new(Spacer::new(iced::Length::Fill)),
Box::new(ShutdownWidget::new()),
Box::new(Spacer::new(iced::Length::Fill)),
Box::new(BatteryWidget::new()),
],
}
@ -33,7 +36,7 @@ impl App {
if let Some(elem) = self
.widgets
.iter()
.find(|widget| widget.own_window(id))
.find(|widget| widget.has_window(id))
.map(|widget| widget.view(id))
{
return elem;

View file

@ -3,11 +3,13 @@ use iced::Subscription;
use iced::Task;
use iced_layershell::to_layer_message;
use crate::widgets::powerbutton::ShutdownEvents;
pub trait PanelWidget {
fn update(&mut self, message: &Message) -> Task<Message>;
fn subscribe(&self) -> Subscription<Message>;
fn view(&self, id: iced::window::Id) -> Element<'_, Message>;
fn own_window(&self, _id: iced::window::Id) -> bool {
fn has_window(&self, _id: iced::window::Id) -> bool {
false
}
}
@ -17,4 +19,5 @@ pub trait PanelWidget {
pub enum Message {
Battery(Option<f64>),
Time,
ShutdownEvent(ShutdownEvents),
}

View file

@ -1,3 +1,4 @@
pub mod battery;
pub mod clock;
pub mod powerbutton;
pub mod spacer;

View file

@ -0,0 +1,90 @@
use crate::widget::{Message, PanelWidget};
use iced::{
Subscription, Task,
widget::{button, row, text},
};
use iced_layershell::reexport::{Anchor, NewLayerShellSettings};
pub struct ShutdownWidget {
window: Option<iced::window::Id>,
}
#[derive(Debug, Clone)]
pub enum ShutdownEvents {
PowerButtonPressed,
ShutdownConfirmed,
ShutdownCanceled,
}
impl ShutdownWidget {
pub fn new() -> Self {
Self { window: None }
}
}
impl PanelWidget for ShutdownWidget {
fn update(&mut self, message: &crate::widget::Message) -> iced::Task<crate::widget::Message> {
let Message::ShutdownEvent(event) = message else {
return Task::none();
};
match event {
ShutdownEvents::PowerButtonPressed => match self.window {
Some(child) => {
self.window = None;
Task::done(Message::RemoveWindow(child))
}
None => {
let id = iced::window::Id::unique();
self.window = Some(id);
Task::done(Message::NewLayerShell {
settings: NewLayerShellSettings {
size: Some((220, 40)),
anchor: Anchor::Top,
layer: iced_layershell::reexport::Layer::Overlay,
keyboard_interactivity:
iced_layershell::reexport::KeyboardInteractivity::OnDemand,
exclusive_zone: None,
..Default::default()
},
id,
})
}
},
ShutdownEvents::ShutdownConfirmed => Task::none(),
ShutdownEvents::ShutdownCanceled => match self.window {
Some(child) => {
self.window = None;
Task::done(Message::RemoveWindow(child))
}
None => Task::none(),
},
}
}
fn subscribe(&self) -> iced::Subscription<crate::widget::Message> {
Subscription::none()
}
fn has_window(&self, id: iced::window::Id) -> bool {
self.window == Some(id)
}
fn view(&self, id: iced::window::Id) -> iced::Element<'_, crate::widget::Message> {
match self.window {
Some(child_id) if id == child_id => row![
text("Shut down?"),
button("").on_press(Message::ShutdownEvent(ShutdownEvents::ShutdownConfirmed)),
button("").on_press(Message::ShutdownEvent(ShutdownEvents::ShutdownCanceled)),
]
.spacing(8)
.align_y(iced::Alignment::Center)
.into(),
_ => button("")
.on_press(Message::ShutdownEvent(ShutdownEvents::PowerButtonPressed))
.into(),
}
}
}