bleh
This commit is contained in:
@@ -4,8 +4,8 @@ use iced::widget::{column, container, mouse_area, row, stack, text};
|
|||||||
use iced::{alignment, Border, Color, Element, Length, Task, Theme};
|
use iced::{alignment, Border, Color, Element, Length, Task, Theme};
|
||||||
|
|
||||||
use common::{
|
use common::{
|
||||||
BarModule, BatteryAction, BatteryEvent, BatteryMsg, BatteryStatus, Endpoint, ModuleEffect,
|
pill, BarModule, BatteryAction, BatteryEvent, BatteryMsg, BatteryStatus, Endpoint,
|
||||||
PopupSettings, Service, Wire,
|
ModuleEffect, PopupSettings, Service, Wire,
|
||||||
};
|
};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use toml::Table;
|
use toml::Table;
|
||||||
@@ -15,6 +15,8 @@ const SHELL_W: f32 = 28.0;
|
|||||||
const SHELL_H: f32 = 14.0;
|
const SHELL_H: f32 = 14.0;
|
||||||
const BORDER_W: f32 = 1.5;
|
const BORDER_W: f32 = 1.5;
|
||||||
const PAD: f32 = 2.0;
|
const PAD: f32 = 2.0;
|
||||||
|
/// Charge at or below this shows the warning color while discharging.
|
||||||
|
const LOW_PCT: i32 = 20;
|
||||||
|
|
||||||
pub struct Battery {
|
pub struct Battery {
|
||||||
percent: Option<i32>,
|
percent: Option<i32>,
|
||||||
@@ -72,20 +74,22 @@ fn fmt_duration(secs: u64) -> String {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Icon ink: the theme's success green while charging, bar text otherwise.
|
/// Icon ink: success green while charging, danger red when low and
|
||||||
fn ink(status: BatteryStatus, theme: &Theme) -> Color {
|
/// discharging, bar text otherwise.
|
||||||
|
fn ink(status: BatteryStatus, percent: Option<i32>, theme: &Theme) -> Color {
|
||||||
let palette = theme.palette();
|
let palette = theme.palette();
|
||||||
match status {
|
match status {
|
||||||
BatteryStatus::Charging => palette.success,
|
BatteryStatus::Charging => palette.success,
|
||||||
|
BatteryStatus::Discharging if percent.is_some_and(|p| p <= LOW_PCT) => palette.danger,
|
||||||
_ => palette.text,
|
_ => palette.text,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Transparent shell with a rounded outline tinted by charge state.
|
/// Transparent shell with a rounded outline tinted by charge state.
|
||||||
fn shell_style(status: BatteryStatus) -> impl Fn(&Theme) -> container::Style {
|
fn shell_style(status: BatteryStatus, percent: Option<i32>) -> impl Fn(&Theme) -> container::Style {
|
||||||
move |theme: &Theme| container::Style {
|
move |theme: &Theme| container::Style {
|
||||||
border: Border {
|
border: Border {
|
||||||
color: ink(status, theme),
|
color: ink(status, percent, theme),
|
||||||
width: BORDER_W,
|
width: BORDER_W,
|
||||||
radius: 4.0.into(),
|
radius: 4.0.into(),
|
||||||
},
|
},
|
||||||
@@ -95,7 +99,11 @@ fn shell_style(status: BatteryStatus) -> impl Fn(&Theme) -> container::Style {
|
|||||||
|
|
||||||
/// Solid fill (and nub cap) tinted by charge state. `dim` renders the
|
/// Solid fill (and nub cap) tinted by charge state. `dim` renders the
|
||||||
/// Android-style muted fill that sits behind the in-icon number.
|
/// Android-style muted fill that sits behind the in-icon number.
|
||||||
fn solid_style(status: BatteryStatus, dim: bool) -> impl Fn(&Theme) -> container::Style {
|
fn solid_style(
|
||||||
|
status: BatteryStatus,
|
||||||
|
percent: Option<i32>,
|
||||||
|
dim: bool,
|
||||||
|
) -> impl Fn(&Theme) -> container::Style {
|
||||||
move |theme: &Theme| {
|
move |theme: &Theme| {
|
||||||
let palette = theme.palette();
|
let palette = theme.palette();
|
||||||
let background = if dim {
|
let background = if dim {
|
||||||
@@ -104,7 +112,7 @@ fn solid_style(status: BatteryStatus, dim: bool) -> impl Fn(&Theme) -> container
|
|||||||
..palette.text
|
..palette.text
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ink(status, theme)
|
ink(status, percent, theme)
|
||||||
};
|
};
|
||||||
container::Style {
|
container::Style {
|
||||||
background: Some(background.into()),
|
background: Some(background.into()),
|
||||||
@@ -134,12 +142,12 @@ impl Battery {
|
|||||||
container(text(""))
|
container(text(""))
|
||||||
.width(Length::Fixed(self.fill_w()))
|
.width(Length::Fixed(self.fill_w()))
|
||||||
.height(Length::Fill)
|
.height(Length::Fill)
|
||||||
.style(solid_style(status, self.numbers_in_icon)),
|
.style(solid_style(status, self.percent, self.numbers_in_icon)),
|
||||||
)
|
)
|
||||||
.width(Length::Fixed(SHELL_W))
|
.width(Length::Fixed(SHELL_W))
|
||||||
.height(Length::Fixed(SHELL_H))
|
.height(Length::Fixed(SHELL_H))
|
||||||
.padding(PAD)
|
.padding(PAD)
|
||||||
.style(shell_style(status));
|
.style(shell_style(status, self.percent));
|
||||||
// Optional percentage readout centered over the fill, in the frame's
|
// Optional percentage readout centered over the fill, in the frame's
|
||||||
// light color — legible on the dimmed fill, like Android.
|
// light color — legible on the dimmed fill, like Android.
|
||||||
let shell: Element<'_, Wire> = match (self.numbers_in_icon, self.percent) {
|
let shell: Element<'_, Wire> = match (self.numbers_in_icon, self.percent) {
|
||||||
@@ -167,7 +175,7 @@ impl Battery {
|
|||||||
container(text(""))
|
container(text(""))
|
||||||
.width(Length::Fixed(2.5))
|
.width(Length::Fixed(2.5))
|
||||||
.height(Length::Fixed(6.0))
|
.height(Length::Fixed(6.0))
|
||||||
.style(solid_style(status, false)),
|
.style(solid_style(status, self.percent, false)),
|
||||||
]
|
]
|
||||||
.spacing(2)
|
.spacing(2)
|
||||||
.align_y(iced::Alignment::Center);
|
.align_y(iced::Alignment::Center);
|
||||||
@@ -191,15 +199,20 @@ impl Battery {
|
|||||||
BatteryAction::OpenPopup,
|
BatteryAction::OpenPopup,
|
||||||
)),
|
)),
|
||||||
)
|
)
|
||||||
|
.style(pill)
|
||||||
.id(iced::widget::Id::from(self.id()))
|
.id(iced::widget::Id::from(self.id()))
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Popup surface: charge, status, and time to full/empty.
|
/// Popup surface: charge, status, and time to full/empty.
|
||||||
fn popup(&self) -> Element<'_, Wire> {
|
fn popup(&self) -> Element<'_, Wire> {
|
||||||
let charge = match self.percent {
|
let (status, percent) = (self.status, self.percent);
|
||||||
Some(percent) => text(format!("{percent}%")).size(44),
|
let warn = move |theme: &Theme| text::Style {
|
||||||
None => text("--").size(44),
|
color: Some(ink(status, percent, theme)),
|
||||||
|
};
|
||||||
|
let charge = match percent {
|
||||||
|
Some(percent) => text(format!("{percent}%")).size(44).style(warn),
|
||||||
|
None => text("--").size(44).style(warn),
|
||||||
};
|
};
|
||||||
let status = text(match self.status {
|
let status = text(match self.status {
|
||||||
BatteryStatus::Charging => "Charging".to_string(),
|
BatteryStatus::Charging => "Charging".to_string(),
|
||||||
|
|||||||
Reference in New Issue
Block a user