2023-01-12 00:13:27 +01:00
|
|
|
use std::{cmp::min, default::Default};
|
2023-01-11 00:28:54 +01:00
|
|
|
|
|
|
|
|
use crate::{
|
|
|
|
|
buffer::BufferView,
|
|
|
|
|
color::Color,
|
|
|
|
|
draw::{draw_bar, draw_box},
|
2023-02-08 22:53:41 +01:00
|
|
|
event::{Event, PointerButton},
|
2023-01-11 00:28:54 +01:00
|
|
|
fonts::FontMap,
|
|
|
|
|
widgets::{Geometry, Widget},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
pub trait BarWidgetImpl {
|
2023-01-16 00:25:34 +01:00
|
|
|
fn get_dirty(&self) -> bool {
|
|
|
|
|
false
|
|
|
|
|
}
|
2023-01-11 00:28:54 +01:00
|
|
|
fn name(&self) -> &'static str;
|
2023-02-06 18:34:07 +01:00
|
|
|
fn value(&mut self) -> f32;
|
2023-01-11 00:28:54 +01:00
|
|
|
fn color(&self) -> Color;
|
2023-02-02 23:52:59 +01:00
|
|
|
fn click(&mut self, _pos: f32, _btn: PointerButton) {}
|
2023-01-11 00:28:54 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub struct BarWidget {
|
2023-01-13 21:53:07 +01:00
|
|
|
font: &'static str,
|
|
|
|
|
size: f32,
|
2023-01-11 00:28:54 +01:00
|
|
|
geometry: Geometry,
|
|
|
|
|
inner_widget: Box<dyn BarWidgetImpl>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl BarWidget {
|
2023-02-08 22:53:41 +01:00
|
|
|
pub fn new(
|
|
|
|
|
inner_widget: Box<dyn BarWidgetImpl>,
|
|
|
|
|
fm: &mut FontMap,
|
|
|
|
|
font: &'static str,
|
|
|
|
|
size: f32,
|
|
|
|
|
) -> BarWidget {
|
2023-02-02 23:52:59 +01:00
|
|
|
fm.queue_font(font, size, inner_widget.name());
|
2023-01-11 00:28:54 +01:00
|
|
|
BarWidget {
|
|
|
|
|
geometry: Default::default(),
|
2023-01-16 00:25:34 +01:00
|
|
|
inner_widget,
|
|
|
|
|
font,
|
|
|
|
|
size,
|
2023-01-11 00:28:54 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Widget for BarWidget {
|
|
|
|
|
fn geometry(&self) -> Geometry {
|
|
|
|
|
self.geometry
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn get_dirty(&self) -> bool {
|
|
|
|
|
self.inner_widget.get_dirty()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn draw(&mut self, fonts: &mut FontMap, view: &mut BufferView) -> Geometry {
|
2023-01-13 21:53:07 +01:00
|
|
|
let font = fonts.get_font(self.font, self.size);
|
2023-02-02 23:52:59 +01:00
|
|
|
let fg = Color::WHITE;
|
2023-01-11 00:28:54 +01:00
|
|
|
|
2023-02-08 22:53:41 +01:00
|
|
|
font.draw_text(view, fg, self.inner_widget.name()).unwrap();
|
2023-01-13 21:53:07 +01:00
|
|
|
let size = self.size.ceil() as u32;
|
2023-01-11 00:28:54 +01:00
|
|
|
let bar_offset = 4 * size;
|
|
|
|
|
let val = self.inner_widget.value();
|
|
|
|
|
|
|
|
|
|
let c = self.inner_widget.color();
|
2026-10-03 09:15:54 +00:00
|
|
|
let bar_width = self.geometry.width.saturating_sub(bar_offset);
|
|
|
|
|
if bar_width < 2 {
|
|
|
|
|
return self.geometry;
|
|
|
|
|
}
|
|
|
|
|
draw_bar(&mut view.offset((bar_offset, 0)), c, bar_width, size, val).unwrap();
|
2023-01-11 00:28:54 +01:00
|
|
|
|
2026-10-03 09:15:54 +00:00
|
|
|
draw_box(&mut view.offset((bar_offset, 0)), c, (bar_width, size)).unwrap();
|
2023-01-11 00:28:54 +01:00
|
|
|
self.geometry
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn geometry_update(&mut self, _fonts: &mut FontMap, geometry: &Geometry) -> Geometry {
|
|
|
|
|
let w = min(geometry.width, 768);
|
|
|
|
|
let mut x = geometry.x;
|
|
|
|
|
if geometry.width > w {
|
|
|
|
|
x += geometry.width - w;
|
|
|
|
|
}
|
|
|
|
|
self.geometry = Geometry {
|
|
|
|
|
x: x,
|
|
|
|
|
y: geometry.y,
|
|
|
|
|
width: w,
|
2023-01-13 21:53:07 +01:00
|
|
|
height: self.size.ceil() as u32,
|
2023-01-11 00:28:54 +01:00
|
|
|
};
|
|
|
|
|
self.geometry
|
|
|
|
|
}
|
2023-02-02 23:52:59 +01:00
|
|
|
|
2023-02-08 22:53:41 +01:00
|
|
|
fn minimum_size(&mut self, _fonts: &mut FontMap) -> Geometry {
|
|
|
|
|
Geometry {
|
|
|
|
|
x: 0,
|
|
|
|
|
y: 0,
|
|
|
|
|
width: self.size.ceil() as u32 * 6,
|
|
|
|
|
height: self.size.ceil() as u32,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-02-02 23:52:59 +01:00
|
|
|
fn event(&mut self, event: &Event) {
|
|
|
|
|
match event {
|
|
|
|
|
Event::PointerEvent(ev) => {
|
|
|
|
|
let offset = 4 * self.size.ceil() as u32;
|
2026-10-03 09:15:54 +00:00
|
|
|
if ev.pos.0 >= offset && self.geometry.width > offset {
|
2023-02-02 23:52:59 +01:00
|
|
|
let val = (ev.pos.0 - offset) as f32 / (self.geometry.width - offset) as f32;
|
|
|
|
|
self.inner_widget.click(val, ev.button);
|
|
|
|
|
}
|
2023-02-08 22:53:41 +01:00
|
|
|
}
|
2023-02-02 23:52:59 +01:00
|
|
|
_ => (),
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-01-11 00:28:54 +01:00
|
|
|
}
|