diff options
| -rw-r--r-- | src/infinite_grid.rs | 63 | ||||
| -rw-r--r-- | src/main.rs | 29 |
2 files changed, 71 insertions, 21 deletions
diff --git a/src/infinite_grid.rs b/src/infinite_grid.rs new file mode 100644 index 0000000..163c2b2 --- /dev/null +++ b/src/infinite_grid.rs @@ -0,0 +1,63 @@ +//! 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<G>(&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, + ); + } +} diff --git a/src/main.rs b/src/main.rs index 81677e2..4969261 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,7 @@ +pub mod infinite_grid; pub mod transform; + +use infinite_grid::*; use transform::*; use piston_window::grid::Grid; @@ -25,6 +28,7 @@ fn main() { // The amount of on-screen pixels used to represent a meter of actual terrain. let mut transform = Transform::new(); + let mut grid = InfiniteGrid::new(&transform, window.draw_size()); /* Create a rectangle that is used to draw all rectangles that were created by the user. It has * a thicc blacc border and white colour. @@ -37,13 +41,11 @@ fn main() { let mut starting_rect_point: Option<[f64; 2]> = None; let mut rectangles = Vec::new(); - // Line used to draw the square grid. - let grid_line = Line::new([1., 1., 1., 0.3], 1.5); - let mut mouse_pos_px = [0., 0.]; let mut mouse_pos_m = [0., 0.]; - let mut events = Events::new(EventSettings::new().lazy(true)); let mut canvas_follows_mouse = false; + + let mut events = Events::new(EventSettings::new().lazy(true)); while let Some(e) = events.next(&mut window) { // Update the mouse cursor position and possibly the canvas position too, in case the user // is currently dragging the canvas. @@ -69,6 +71,7 @@ fn main() { // Notify the user of the change if there was any if scale_changed { + grid.on_scale_change(&transform, window.draw_size()); println!( "Changed scale to {} pixels per m.", transform.pixels_per_m() @@ -105,26 +108,10 @@ fn main() { window.set_should_close(true); } - /* Update the Grid draw size to the actual window draw size. - * TODO: Currently, the window canvas draw size is never updated. This has to be changed in - * order to deal with the user resizing the window. - */ - let win_size = window.draw_size(); - let grid = Grid { - cols: (win_size.width / transform.pixels_per_m()) as u32 + 1, - rows: (win_size.height / transform.pixels_per_m()) as u32 + 1, - units: transform.pixels_per_m(), - }; - window.draw_2d(&e, |c, g, _device| { clear([0.4, 0.2, 0., 1.], g); - grid.draw( - &grid_line, - &c.draw_state, - c.trans_pos(transform.translation_px()).transform, - g, - ); + grid.draw(&transform, &c, g); // Draw all rectangles that are part of the map for &rect in &rectangles { |
