aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorArne Dußin2020-10-29 15:02:08 +0100
committerArne Dußin2020-10-29 15:02:08 +0100
commit20c73199167ce3ef1b4a256db5a95acab8f467b3 (patch)
tree73895c6361bfabdd744a97b7933368349f0fcaff /src
parentb12d0494f54d781a0b9f467a4fc3e4e255dd9839 (diff)
downloadgraf_karto-20c73199167ce3ef1b4a256db5a95acab8f467b3.tar.gz
graf_karto-20c73199167ce3ef1b4a256db5a95acab8f467b3.zip
Make grid "infinite"
Diffstat (limited to 'src')
-rw-r--r--src/infinite_grid.rs63
-rw-r--r--src/main.rs29
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 {