use crate::align::Alignment;
use embedded_graphics::primitives::Rectangle;
pub trait ElementSpacing: Copy + Clone {
fn modify_measurement(&self, measured_size: u32, objects: u32) -> u32;
fn align(
&self,
alignment: impl Alignment,
view: Rectangle,
reference: Rectangle,
n: u32,
objects: u32,
total_size: u32,
) -> i32;
}
#[derive(Copy, Clone)]
pub struct Tight;
impl ElementSpacing for Tight {
#[inline]
fn modify_measurement(&self, measured_size: u32, _objects: u32) -> u32 {
measured_size
}
#[inline]
fn align(
&self,
alignment: impl Alignment,
view: Rectangle,
reference: Rectangle,
_n: u32,
_objects: u32,
_total_size: u32,
) -> i32 {
alignment.align_with_offset(view, reference, 0)
}
}
#[derive(Copy, Clone)]
pub struct FixedMargin(pub i32);
impl ElementSpacing for FixedMargin {
#[inline]
fn modify_measurement(&self, measured_size: u32, objects: u32) -> u32 {
if objects == 0 {
measured_size
} else {
(measured_size as i32 + self.0 * (objects as i32 - 1)) as u32
}
}
#[inline]
fn align(
&self,
alignment: impl Alignment,
view: Rectangle,
reference: Rectangle,
n: u32,
_objects: u32,
_total_size: u32,
) -> i32 {
let offset = if n == 0 { 0 } else { self.0 };
alignment.align_with_offset(view, reference, offset)
}
}
#[derive(Copy, Clone)]
pub struct DistributeFill(pub u32);
impl ElementSpacing for DistributeFill {
#[inline]
fn modify_measurement(&self, _measured_size: u32, _objects: u32) -> u32 {
self.0
}
#[inline]
fn align(
&self,
alignment: impl Alignment,
view: Rectangle,
reference: Rectangle,
n: u32,
objects: u32,
total_size: u32,
) -> i32 {
let empty_space = self.0 as i32 - total_size as i32;
let base = empty_space / (objects - 1) as i32;
let remainder = empty_space % (objects - 1) as i32;
let offset = if n == 0 {
0
} else if n as i32 <= remainder {
base + 1
} else {
base
};
alignment.align_with_offset(view, reference, offset)
}
}