battery module test
This commit is contained in:
@@ -35,6 +35,7 @@ fn bar_view(bar: &Bar) -> Element<'_, Message> {
|
||||
})
|
||||
.collect::<Vec<Element<Message>>>())
|
||||
.spacing(bar.spacing)
|
||||
.width(Length::Shrink)
|
||||
.align_y(Alignment::Center);
|
||||
|
||||
let middle = row(bar
|
||||
@@ -50,6 +51,7 @@ fn bar_view(bar: &Bar) -> Element<'_, Message> {
|
||||
})
|
||||
.collect::<Vec<Element<Message>>>())
|
||||
.spacing(bar.spacing)
|
||||
.width(Length::Shrink)
|
||||
.align_y(Alignment::Center);
|
||||
let right = row(bar
|
||||
.order
|
||||
@@ -64,6 +66,7 @@ fn bar_view(bar: &Bar) -> Element<'_, Message> {
|
||||
})
|
||||
.collect::<Vec<Element<Message>>>())
|
||||
.spacing(bar.spacing)
|
||||
.width(Length::Shrink)
|
||||
.align_y(Alignment::Center);
|
||||
|
||||
let row = row![
|
||||
|
||||
@@ -1,17 +1,69 @@
|
||||
//! Battery module: prints the charge percentage from the battery service.
|
||||
//! Battery module: Android-style battery icon fed by the battery service.
|
||||
|
||||
use iced::widget::text;
|
||||
use iced::{Element, Task};
|
||||
use iced::widget::{container, row, text};
|
||||
use iced::{Border, Color, Element, Length, Task, Theme};
|
||||
|
||||
use common::{BarModule, BatteryEvent, BatteryMsg, ModuleEffect, Service, Wire};
|
||||
use common::{BarModule, BatteryEvent, BatteryMsg, BatteryStatus, ModuleEffect, Service, Wire};
|
||||
|
||||
/// Icon shell size (logical px); fill scales inside it.
|
||||
const SHELL_W: f32 = 28.0;
|
||||
const SHELL_H: f32 = 14.0;
|
||||
const BORDER_W: f32 = 1.5;
|
||||
const PAD: f32 = 2.0;
|
||||
|
||||
pub struct Battery {
|
||||
percent: Option<i32>,
|
||||
status: BatteryStatus,
|
||||
}
|
||||
|
||||
impl Battery {
|
||||
pub fn new() -> Self {
|
||||
Self { percent: None }
|
||||
Self {
|
||||
percent: None,
|
||||
status: BatteryStatus::default(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Fill width for the level, leaving a sliver visible below 100%.
|
||||
fn fill_w(&self) -> f32 {
|
||||
match self.percent {
|
||||
Some(p) => ((SHELL_W - 2.0 * (BORDER_W + PAD)) * p as f32 / 100.0)
|
||||
.clamp(0.0, SHELL_W)
|
||||
.max(if p > 0 { 2.0 } else { 0.0 }),
|
||||
None => 0.0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Icon ink: green while charging, white otherwise.
|
||||
fn ink(status: BatteryStatus) -> Color {
|
||||
match status {
|
||||
BatteryStatus::Charging => Color::from_rgb8(0x76, 0xFF, 0x03),
|
||||
_ => Color::WHITE,
|
||||
}
|
||||
}
|
||||
|
||||
/// Transparent shell with a rounded outline tinted by charge state.
|
||||
fn shell_style(status: BatteryStatus) -> impl Fn(&Theme) -> container::Style {
|
||||
move |_theme: &Theme| container::Style {
|
||||
border: Border {
|
||||
color: ink(status),
|
||||
width: BORDER_W,
|
||||
radius: 4.0.into(),
|
||||
},
|
||||
..container::Style::default()
|
||||
}
|
||||
}
|
||||
|
||||
/// Solid fill (and nub cap) tinted by charge state.
|
||||
fn solid_style(status: BatteryStatus) -> impl Fn(&Theme) -> container::Style {
|
||||
move |_theme: &Theme| container::Style {
|
||||
background: Some(ink(status).into()),
|
||||
border: Border {
|
||||
radius: 2.0.into(),
|
||||
..Default::default()
|
||||
},
|
||||
..container::Style::default()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,16 +73,37 @@ impl BarModule for Battery {
|
||||
}
|
||||
|
||||
fn view(&self, _window_id: Option<iced::window::Id>) -> Element<'_, Wire> {
|
||||
match self.percent {
|
||||
Some(percent) => text(format!("{percent}%")).into(),
|
||||
None => text("--").into(),
|
||||
}
|
||||
let status = self.status;
|
||||
let icon = row![
|
||||
container(
|
||||
container(text(""))
|
||||
.width(Length::Fixed(self.fill_w()))
|
||||
.height(Length::Fill)
|
||||
.style(solid_style(status)),
|
||||
)
|
||||
.width(Length::Fixed(SHELL_W))
|
||||
.height(Length::Fixed(SHELL_H))
|
||||
.padding(PAD)
|
||||
.style(shell_style(status)),
|
||||
// Nub cap on the right edge.
|
||||
container(text(""))
|
||||
.width(Length::Fixed(2.5))
|
||||
.height(Length::Fixed(6.0))
|
||||
.style(solid_style(status)),
|
||||
]
|
||||
.spacing(2)
|
||||
.align_y(iced::Alignment::Center);
|
||||
row![icon]
|
||||
.spacing(6)
|
||||
.align_y(iced::Alignment::Center)
|
||||
.into()
|
||||
}
|
||||
|
||||
fn update(&mut self, msg: Wire) -> Task<ModuleEffect> {
|
||||
if let Some(BatteryEvent::PercentageChanged(percent)) = msg.downcast::<BatteryEvent>()
|
||||
{
|
||||
self.percent = Some(*percent);
|
||||
match msg.downcast::<BatteryEvent>() {
|
||||
Some(BatteryEvent::PercentageChanged(percent)) => self.percent = Some(*percent),
|
||||
Some(BatteryEvent::StatusChanged(status)) => self.status = *status,
|
||||
_ => {}
|
||||
}
|
||||
Task::none()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user