//! Places on the canvas. //! //! The canvas is a grid of terminal cells (at Normal zoom) with no edges, so //! coordinates can be negative. `x` grows to the right and `y` downward, as in //! the terminal. use std::ops::{Add, AddAssign, Neg, Sub}; /// A point on the canvas. #[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash)] pub struct CanvasPos { pub x: i32, pub y: i32, } impl CanvasPos { /// The point at `x`, `y`. pub const fn new(x: i32, y: i32) -> CanvasPos { CanvasPos { x, y } } } /// A movement on the canvas: `dx` cells to the right, `dy` cells down. #[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash)] pub struct CanvasOffset { pub dx: i32, pub dy: i32, } impl CanvasOffset { /// A movement of `dx` cells to the right and `dy` cells down. pub const fn new(dx: i32, dy: i32) -> CanvasOffset { CanvasOffset { dx, dy } } } impl Add for CanvasPos { type Output = CanvasPos; fn add(self, offset: CanvasOffset) -> CanvasPos { CanvasPos::new(self.x + offset.dx, self.y + offset.dy) } } impl AddAssign for CanvasPos { fn add_assign(&mut self, offset: CanvasOffset) { *self = *self + offset; } } impl Sub for CanvasPos { type Output = CanvasOffset; /// The movement that goes from `other` to `self`. fn sub(self, other: CanvasPos) -> CanvasOffset { CanvasOffset::new(self.x - other.x, self.y - other.y) } } impl Neg for CanvasOffset { type Output = CanvasOffset; fn neg(self) -> CanvasOffset { CanvasOffset::new(-self.dx, -self.dy) } }