//! Grid that can be moved and scaled, and which gives the appearance of being infinite, while //! staying easily renderable. use crate::transform::Transform; use piston_window::grid::Grid; use piston_window::line::{Line, Shape}; use piston_window::{Context, Graphics, Size, Transformed}; /// The line used to draw the grids lines const GRID_LINE: Line = Line { color: [1., 1., 1., 0.3], radius: 1.2, shape: Shape::Square, }; pub struct InfiniteGrid(Grid); impl InfiniteGrid { pub fn new(transform: &Transform, draw_size: Size) -> InfiniteGrid { /* Create a grid with two extra columns and rows per draw_size, so when the user moves the * grid up and down they can be seen, before the grid position is reset to create the * infinitness illusion. * The +3 instead of the +2 is necessary, since the amount needed may be underestimated * because of rounding errors (I think) */ InfiniteGrid(Grid { cols: (draw_size.width / transform.pixels_per_m()) as u32 + 3, rows: (draw_size.height / transform.pixels_per_m()) as u32 + 3, units: transform.pixels_per_m(), }) } // TODO: Yes, this is ugly af pub fn on_scale_change(&mut self, transform: &Transform, draw_size: Size) { self.0.cols = (draw_size.width / transform.pixels_per_m()) as u32 + 3; self.0.rows = (draw_size.height / transform.pixels_per_m()) as u32 + 3; self.0.units = transform.pixels_per_m() } pub fn draw(&self, map_trans: &Transform, context: &Context, g: &mut G) where G: Graphics, { /* Since mouse movement is actually always provided as whole pixels, this is fine. * the - cell_size (i.e. pixels_per_m) is provided, so that the grid is centered in the * screen,and not at position 0.x, 0.x, which would mean there would be no row at the top * and/or no column to the left. */ let actual_trans_px = [ (map_trans.translation_px()[0] as i64 % self.0.units as i64) as f64 - map_trans.pixels_per_m(), (map_trans.translation_px()[1] as i64 % self.0.units as i64) as f64 - map_trans.pixels_per_m(), ]; self.0.draw( &GRID_LINE, &context.draw_state, context.trans_pos(actual_trans_px).transform, g, ); } }