rs-calendar/src/ui/basics.rs

119 lines
3.1 KiB
Rust

#[derive(Copy, Clone, Debug)]
/// A cell within a [CellGrid]
pub struct Cell {
// display coordinates of the cell
pub x: f32,
pub y: f32,
pub width: f32,
pub height: f32,
// position of the cell in the grid (0-based)
pub pos_x: u32,
pub pos_y: u32,
}
/// A grid of equal cells, the grid has a position on the
/// display
pub struct CellGrid {
// display coordinates of the grid
x: f32,
y: f32,
width: f32,
height: f32,
// size of the grid, in number of cells
num_x: u32,
num_y: u32,
}
pub struct CellGridIterator<'a> {
grid: &'a CellGrid,
// current position when iterating
pos_x: u32,
pos_y: u32,
// current cell when iterating
curr: Cell,
}
impl CellGrid {
pub fn new(x: f32, y: f32, width: f32, height: f32, num_x: u32, num_y: u32) -> Self {
Self {
x,
y,
width,
height,
num_x: if num_y > 0 { num_x } else { 0 }, // if one dimension is 0, both shall be 0
num_y: if num_x > 0 { num_y } else { 0 }, // if one dimension is 0, both shall be 0
}
}
pub fn iter(&self) -> CellGridIterator {
CellGridIterator {
grid: self,
pos_x: 0,
pos_y: 0,
curr: Cell {
x: self.x,
y: self.y,
width: self.width,
height: self.height,
pos_x: 0,
pos_y: 0,
},
}
}
pub fn rows(&self) -> Self {
CellGrid::new(self.x, self.y, self.width, self.height, 1, self.num_y)
}
pub fn compute_min_height(&self) -> f32 {
let mut min_height: f32 = self.height;
for cell in self.iter() {
min_height = min_height.min(cell.height)
}
min_height
}
}
impl<'a> CellGridIterator<'a> {
fn compute_cell(&mut self) -> () {
let grid: &'a CellGrid = self.grid;
self.curr.pos_x = self.pos_x;
self.curr.pos_y = self.pos_y;
let beg_x: f32 = grid.x + (grid.width * self.curr.pos_x as f32) / grid.num_x as f32;
let end_x: f32 = grid.x + (grid.width * (self.curr.pos_x + 1) as f32) / grid.num_x as f32;
self.curr.x = beg_x.trunc();
self.curr.width = end_x.trunc() - self.curr.x;
let beg_y: f32 = grid.y + (grid.height * self.curr.pos_y as f32) / grid.num_y as f32;
let end_y: f32 = grid.y + (grid.height * (self.curr.pos_y + 1) as f32) / grid.num_y as f32;
self.curr.y = beg_y.trunc();
self.curr.height = end_y.trunc() - self.curr.y;
}
}
impl<'a> Iterator for CellGridIterator<'a> {
type Item = Cell;
fn next(&mut self) -> Option<Self::Item> {
if self.pos_y >= self.grid.num_y {
None
} else {
// compute current cell (returned by this call)
self.compute_cell();
// advance to next
self.pos_x += 1;
if self.pos_x >= self.grid.num_x {
self.pos_x = 0;
self.pos_y += 1;
}
Some(self.curr)
}
}
}