watch: smarter battery display
This commit is contained in:
@@ -248,9 +248,10 @@ impl OpenVrInputSource {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
app.input_state.devices.sort_by(|a, b| {
|
app.input_state.devices.sort_by(|a, b| {
|
||||||
(a.role as u8)
|
(a.soc.is_none() as u8)
|
||||||
.cmp(&(b.role as u8))
|
.cmp(&(b.soc.is_none() as u8))
|
||||||
.then(a.index.0.cmp(&b.index.0))
|
.then((a.role as u8).cmp(&(b.role as u8)))
|
||||||
|
.then(a.soc.unwrap_or(999.).total_cmp(&b.soc.unwrap_or(999.)))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -563,6 +563,15 @@ impl<D, S> Control<D, S> {
|
|||||||
self.dirty = true;
|
self.dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn set_fg_color(&mut self, color: Vec3) {
|
||||||
|
if self.fg_color == color {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
self.fg_color = color;
|
||||||
|
self.dirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
fn render_rect(
|
fn render_rect(
|
||||||
&self,
|
&self,
|
||||||
canvas: &CanvasData<D>,
|
canvas: &CanvasData<D>,
|
||||||
|
|||||||
@@ -152,6 +152,9 @@ where
|
|||||||
font_size,
|
font_size,
|
||||||
num_devices,
|
num_devices,
|
||||||
normal_fg_color,
|
normal_fg_color,
|
||||||
|
low_fg_color,
|
||||||
|
charging_fg_color,
|
||||||
|
low_threshold,
|
||||||
layout,
|
layout,
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
@@ -163,8 +166,11 @@ where
|
|||||||
ListLayout::Vertical => (w, h / num_buttons),
|
ListLayout::Vertical => (w, h / num_buttons),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let fg_color = color_parse(&normal_fg_color).unwrap_or(FALLBACK_COLOR);
|
||||||
|
let fg_color_low = color_parse(&low_fg_color).unwrap_or(FALLBACK_COLOR);
|
||||||
|
let fg_color_charging = color_parse(&charging_fg_color).unwrap_or(FALLBACK_COLOR);
|
||||||
canvas.font_size = font_size;
|
canvas.font_size = font_size;
|
||||||
canvas.fg_color = color_parse(&normal_fg_color).unwrap_or(FALLBACK_COLOR);
|
canvas.fg_color = fg_color;
|
||||||
|
|
||||||
for i in 0..num_devices {
|
for i in 0..num_devices {
|
||||||
let label = canvas.label_centered(
|
let label = canvas.label_centered(
|
||||||
@@ -174,7 +180,13 @@ where
|
|||||||
button_h - 4.,
|
button_h - 4.,
|
||||||
empty_str.clone(),
|
empty_str.clone(),
|
||||||
);
|
);
|
||||||
label.state = Some(ElemState::Battery { device: i as _ });
|
label.state = Some(ElemState::Battery {
|
||||||
|
device: i as _,
|
||||||
|
low_threshold: low_threshold * 0.01,
|
||||||
|
fg_color,
|
||||||
|
fg_color_low,
|
||||||
|
fg_color_charging,
|
||||||
|
});
|
||||||
label.on_update = Some(battery_update);
|
label.on_update = Some(battery_update);
|
||||||
|
|
||||||
button_x += match layout {
|
button_x += match layout {
|
||||||
@@ -284,6 +296,10 @@ where
|
|||||||
enum ElemState {
|
enum ElemState {
|
||||||
Battery {
|
Battery {
|
||||||
device: usize,
|
device: usize,
|
||||||
|
low_threshold: f32,
|
||||||
|
fg_color: Vec3,
|
||||||
|
fg_color_low: Vec3,
|
||||||
|
fg_color_charging: Vec3,
|
||||||
},
|
},
|
||||||
Clock {
|
Clock {
|
||||||
timezone: Option<Tz>,
|
timezone: Option<Tz>,
|
||||||
@@ -376,22 +392,45 @@ fn btn_func_dn(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn battery_update(control: &mut Control<(), ElemState>, _: &mut (), app: &mut AppState) {
|
fn battery_update(control: &mut Control<(), ElemState>, _: &mut (), app: &mut AppState) {
|
||||||
let ElemState::Battery { device } = control.state.as_ref().unwrap() else {
|
let ElemState::Battery {
|
||||||
|
device,
|
||||||
|
low_threshold,
|
||||||
|
fg_color,
|
||||||
|
fg_color_low,
|
||||||
|
fg_color_charging,
|
||||||
|
} = control.state.as_ref().unwrap()
|
||||||
|
else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
let device = app.input_state.devices.get(*device);
|
let device = app.input_state.devices.get(*device);
|
||||||
|
|
||||||
let tags = ["", "H", "L", "R", "T"];
|
let tags = ["", "H", "L", "R", "T"];
|
||||||
|
|
||||||
let text = match device {
|
if let Some(device) = device {
|
||||||
Some(d) => d
|
let (text, color) = device
|
||||||
.soc
|
.soc
|
||||||
.map(|soc| format!("{}{}", tags[d.role as usize], (soc * 100.).min(99.) as u32))
|
.map(|soc| {
|
||||||
.unwrap_or_else(|| "".into()),
|
let text = format!(
|
||||||
None => "".into(),
|
"{}{}",
|
||||||
};
|
tags[device.role as usize],
|
||||||
|
(soc * 100.).min(99.) as u32
|
||||||
|
);
|
||||||
|
let color = if device.charging {
|
||||||
|
*fg_color_charging
|
||||||
|
} else if soc < *low_threshold {
|
||||||
|
*fg_color_low
|
||||||
|
} else {
|
||||||
|
*fg_color
|
||||||
|
};
|
||||||
|
(text, color)
|
||||||
|
})
|
||||||
|
.unwrap_or_else(|| ("".into(), Vec3::ZERO));
|
||||||
|
|
||||||
control.set_text(&text);
|
control.set_text(&text);
|
||||||
|
control.set_fg_color(color);
|
||||||
|
} else {
|
||||||
|
control.set_text("");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn exec_button(
|
fn exec_button(
|
||||||
|
|||||||
@@ -114,14 +114,14 @@ watch_elements:
|
|||||||
rect: [0, 0, 400, 30]
|
rect: [0, 0, 400, 30]
|
||||||
font_size: 14
|
font_size: 14
|
||||||
num_devices: 9
|
num_devices: 9
|
||||||
low_threshold: 15
|
low_threshold: 20
|
||||||
layout: Horizontal
|
layout: Horizontal
|
||||||
normal_fg_color: "#99BBAA"
|
normal_fg_color: "#99BBAA"
|
||||||
# below is not yet implemented
|
# below is not yet implemented
|
||||||
normal_bg_color: "#353535"
|
normal_bg_color: "#353535"
|
||||||
low_fg_color: "#604040"
|
low_fg_color: "#B06060"
|
||||||
low_bg_color: "#353535"
|
low_bg_color: "#353535"
|
||||||
charging_fg_color: "#204070"
|
charging_fg_color: "#6080A0"
|
||||||
charging_bg_color: "#353535"
|
charging_bg_color: "#353535"
|
||||||
|
|
||||||
# sample
|
# sample
|
||||||
|
|||||||
Reference in New Issue
Block a user