use taffy::prelude::Node;
use vek::{Extent2, Rect, Vec2};
use crate::input::Input;
use super::button::Button;
#[derive(Debug)]
pub struct Checkbox {
pub offset: Vec2<f64>,
pub label: Option<String>,
pub checked: bool,
pub button: Button,
}
impl Checkbox {
pub fn new(offset: Vec2<f64>, label: Option<String>, checked: bool) -> Self {
let mut button = Button {
offset,
size: Extent2::new(20.0, 20.0),
..Default::default()
};
if let Some(label) = &label {
let char_size = crate::font().char_size;
button.click_region = Some(Rect::new(
20.0,
0.0,
char_size.w as f64 * label.len() as f64 + 5.0,
20.0,
));
}
Self {
offset,
checked,
button,
label,
}
}
pub fn update(&mut self, input: &Input) -> bool {
if self.button.update(input) {
self.checked = !self.checked;
true
} else {
false
}
}
pub fn render(&self, canvas: &mut [u32]) {
self.button.render(canvas);
if self.checked {
crate::sprite("checkmark").render(canvas, self.offset + (2.0, 3.0));
}
if let Some(label) = &self.label {
crate::font().render(label, self.offset + (25.0, 5.0), canvas);
}
}
pub fn set(&mut self, state: bool) {
self.checked = state;
}
pub fn update_layout(&mut self, location: Vec2<f64>) {
self.offset = location;
self.button.offset = location;
}
}
#[derive(Debug)]
pub struct CheckboxGroup<const N: usize> {
pub offset: Vec2<f64>,
pub title: Option<String>,
pub boxes: [Checkbox; N],
pub node: Node,
}
impl<const N: usize> CheckboxGroup<N> {
pub fn new(boxes: [(&str, bool); N], title: Option<String>, node: Node) -> Self {
let offset = Vec2::zero();
let boxes = boxes
.map(|(label, checked)| Checkbox::new(Vec2::zero(), Some(label.to_string()), checked));
Self {
offset,
title,
boxes,
node,
}
}
pub fn update(&mut self, input: &Input) -> Option<usize> {
let mut changed = None;
for index in 0..N {
if self.boxes[index].update(input) {
changed = Some(index);
}
}
changed
}
pub fn render(&self, canvas: &mut [u32]) {
for index in 0..N {
self.boxes[index].render(canvas);
}
if let Some(label) = &self.title {
crate::font().render(label, self.offset, canvas);
}
}
pub fn checked(&self, index: usize) -> bool {
assert!(index < N);
self.boxes[index].checked
}
pub fn update_layout(&mut self, location: Vec2<f64>) {
self.offset = location;
for index in 0..self.boxes.len() {
self.boxes.get_mut(index).unwrap().update_layout(
location
+ (
0.0,
index as f64 * 30.0 + if self.title.is_some() { 20.0 } else { 0.0 },
),
);
}
}
}