pub struct TileCamera { /* private fields */ }Expand description
The tile-map sibling of Camera.
Panning and clamping are paced in tiles rather than screen cells, and
tile_rect/tile_surface project one tile to a
zoom.width() x zoom.height() block of screen cells instead of Camera’s
one-cell-to-one-cell picture.
Internally this owns a Camera counted in tiles instead of screen cells, so panning,
clamping, and centering are exactly Camera’s own logic, applied to a tile grid; zoom only
enters when projecting a tile to its screen-cell footprint.
§Examples
use retroglyph_core::grid::{Pos, Rect, Size};
use retroglyph_ui::camera::TileCamera;
// A 12x8 screen viewport onto a 20x20 tile world, at 3x2 screen cells per tile.
let mut cam = TileCamera::new(Rect::new(0, 0, 12, 8), Size::new(20, 20), Size::new(3, 2));
cam.center_on(Pos::new(10, 10));
assert_eq!(cam.tile_rect(Pos::new(10, 10)).width(), 3);Implementations§
Source§impl TileCamera
impl TileCamera
Sourcepub fn cells(&self) -> impl Iterator<Item = (Pos, Pos)>
pub fn cells(&self) -> impl Iterator<Item = (Pos, Pos)>
Iterate the visible tiles as (tile, screen) position pairs, in row-major order, where
screen is the tile’s top-left screen cell. Only tiles that exist in the world are
yielded, so the caller can fill the rest of the viewport with a background. The tile
equivalent of Camera::cells: one entry per tile, not
per screen cell, so cells().count() is a tile count even at a zoom where each tile
covers several screen cells.
Sourcepub fn screen_to_tile(&self, screen: Pos) -> Option<Pos>
pub fn screen_to_tile(&self, screen: Pos) -> Option<Pos>
Map a screen position back to a tile position, or None if it is outside the viewport
or beyond the world (useful for mouse picking at a non-default zoom). The tile
equivalent of Camera::screen_to_world: where
that divides by 1, this divides by zoom, so it agrees with
tile_rect about which tile a screen cell belongs to.
§Examples
use retroglyph_core::grid::{Pos, Rect, Size};
use retroglyph_ui::camera::TileCamera;
let cam = TileCamera::new(Rect::new(0, 0, 12, 8), Size::new(20, 20), Size::new(3, 2));
// Any screen cell inside tile (1, 0)'s 3x2 footprint maps back to (1, 0).
assert_eq!(cam.screen_to_tile(Pos::new(4, 1)), Some(Pos::new(1, 0)));Sourcepub fn tile_rect(&self, tile: Pos) -> Rect
pub fn tile_rect(&self, tile: Pos) -> Rect
The absolute screen rect a tile’s footprint covers at this camera’s
zoom, clipped to the viewport. An empty Rect (zero width or height)
means no part of the tile is visible.
tile_rect only clips to the viewport, not to world: a tile’s existence
in the world is the caller’s own concern.
A tile straddling the viewport edge reports only the visible slice of its full,
ideal-sized footprint, not the full footprint or an empty Rect, matching how
Camera::surface clips a multi-cell draw that’s only
partially on screen instead of dropping it entirely.
§Examples
use retroglyph_core::grid::{Pos, Rect, Size};
use retroglyph_ui::camera::TileCamera;
let mut cam = TileCamera::new(Rect::new(0, 0, 10, 10), Size::new(20, 20), Size::new(3, 2));
// tile (0, 0) is drawn at origin (0, 0) here, so its footprint covers a 3x2 block.
assert_eq!(cam.tile_rect(Pos::new(0, 0)), Rect::new(0, 0, 3, 2));
// A tile straddling the viewport's right edge is clipped to what's actually visible.
let cam = TileCamera::new(Rect::new(0, 0, 4, 4), Size::new(20, 20), Size::new(3, 3));
assert_eq!(cam.tile_rect(Pos::new(1, 0)), Rect::new(3, 0, 1, 3));Sourcepub fn tile_surface<'a>(
&self,
tile: Pos,
surface: &'a mut Surface<'_>,
) -> Option<Surface<'a>>
pub fn tile_surface<'a>( &self, tile: Pos, surface: &'a mut Surface<'_>, ) -> Option<Surface<'a>>
A view of surface scoped to one tile’s footprint at this camera’s
zoom, or None if none of that footprint is visible.
The returned surface’s own coordinate space is tile-local: (0, 0) is the tile’s own
top-left corner, and put/print/the rest of Surface’s drawing methods take positions
in 0..zoom.width() by 0..zoom.height(), the same way a small standalone Surface
would for a zoom.width() x zoom.height() sprite. A tile straddling the viewport edge is
still clipped automatically: only the on-screen slice of it accepts writes.
Calling this once per visible tile (for example every (tile, _) pair from
cells) replaces hand-rolled tile-range-plus-offset math with one
drawable region per tile.
§Examples
use retroglyph_core::color::Style;
use retroglyph_core::grid::{Grid, Pos, Rect, Size};
use retroglyph_core::surface::Surface;
use retroglyph_ui::camera::TileCamera;
let mut grid = Grid::new(10, 10);
let mut root = Surface::new(&mut grid, Rect::new(0, 0, 10, 10), 0);
let cam = TileCamera::new(Rect::new(0, 0, 10, 10), Size::new(20, 20), Size::new(3, 2));
// tile (1, 0)'s footprint covers screen cells (3, 0)..(6, 2); draw distinct glyphs at
// two corners of it in tile-local coordinates.
let mut tile = cam.tile_surface(Pos::new(1, 0), &mut root).expect("tile is visible");
tile.put(Pos::new(0, 0), '[', Style::default());
tile.put(Pos::new(2, 1), ']', Style::default());
assert_eq!(grid[Pos::new(3, 0)].glyph(), '[');
assert_eq!(grid[Pos::new(5, 1)].glyph(), ']');A tile straddling the viewport edge only accepts writes to its visible slice; the rest is
silently dropped, like any other out-of-clip Surface write.
use retroglyph_core::color::Style;
use retroglyph_core::grid::{Grid, Pos, Rect, Size};
use retroglyph_core::surface::Surface;
use retroglyph_ui::camera::TileCamera;
let mut grid = Grid::new(10, 10);
let cam = TileCamera::new(Rect::new(0, 0, 4, 4), Size::new(20, 20), Size::new(3, 3));
// This tile's ideal footprint is (3, 0, 3, 3); only its leftmost column (3, 0)..(4, 3)
// is inside the 4-wide viewport.
{
let mut root = Surface::new(&mut grid, Rect::new(0, 0, 10, 10), 0);
let mut tile = cam.tile_surface(Pos::new(1, 0), &mut root).expect("tile is visible");
tile.put(Pos::new(0, 0), 'L', Style::default()); // the tile's own visible column.
tile.put(Pos::new(2, 0), 'R', Style::default()); // clipped off past the viewport edge.
}
assert_eq!(grid[Pos::new(3, 0)].glyph(), 'L');
assert_eq!(grid[Pos::new(5, 0)].glyph(), ' ');
// A tile entirely outside the viewport has nothing visible to draw into.
let mut root = Surface::new(&mut grid, Rect::new(0, 0, 10, 10), 0);
assert!(cam.tile_surface(Pos::new(10, 10), &mut root).is_none());Source§impl TileCamera
impl TileCamera
Sourcepub const fn zoom(&self) -> Size
pub const fn zoom(&self) -> Size
How many screen cells one tile covers, per axis. (1, 1) by default: one tile to one
screen cell, same as an un-zoomed Camera.
Sourcepub fn set_zoom(&mut self, zoom: Size)
pub fn set_zoom(&mut self, zoom: Size)
Set how many screen cells one tile covers, per axis, re-deriving the tile-unit viewport
from the current screen viewport and re-clamping the origin so it
stays in bounds for the new tile-count viewport.
A zero width or height clamps to 1: a zero-size tile has no meaningful footprint to
draw into, so this refuses to create one rather than silently making every tile
disappear.
§Examples
use retroglyph_core::grid::{Rect, Size};
use retroglyph_ui::camera::TileCamera;
let mut cam = TileCamera::new(Rect::new(0, 0, 10, 10), Size::new(20, 20), Size::new(1, 1));
cam.set_zoom(Size::new(3, 2));
assert_eq!(cam.zoom(), Size::new(3, 2));
// A zero axis clamps to 1 rather than producing an empty tile footprint.
cam.set_zoom(Size::new(0, 4));
assert_eq!(cam.zoom(), Size::new(1, 4));Sourcepub fn set_viewport(&mut self, viewport: Rect)
pub fn set_viewport(&mut self, viewport: Rect)
Replace the viewport (for example after a terminal resize), keeping the world and zoom unchanged and re-clamping the origin so it stays in bounds.
Sourcepub fn set_world(&mut self, world: Size)
pub fn set_world(&mut self, world: Size)
Replace the world dimensions, in tiles, keeping the viewport and zoom unchanged and re-clamping the origin so it stays in bounds.
Sourcepub fn center_on(&mut self, target: Pos)
pub fn center_on(&mut self, target: Pos)
Center the view on target (a tile position), clamped to the world edges so the
viewport never scrolls past [0, world) tiles. The tile equivalent of
Camera::center_on.
Sourcepub fn set_origin(&mut self, origin: Pos)
pub fn set_origin(&mut self, origin: Pos)
Set the top-left tile directly, clamped to the world edges like
center_on. The tile equivalent of
Camera::set_origin.
Sourcepub fn scroll_by(&mut self, dx: i32, dy: i32)
pub fn scroll_by(&mut self, dx: i32, dy: i32)
Scroll the view by a signed tile delta, clamped to the world edges like
set_origin. The tile equivalent of
Camera::scroll_by.
Sourcepub fn visible_bounds(&self) -> Rect
pub fn visible_bounds(&self) -> Rect
The tile rectangle currently visible, in tile coordinates, clamped to world bounds. The
tile equivalent of Camera::visible_bounds.
Trait Implementations§
Source§impl Clone for TileCamera
impl Clone for TileCamera
Source§fn clone(&self) -> TileCamera
fn clone(&self) -> TileCamera
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreimpl Copy for TileCamera
Source§impl Debug for TileCamera
impl Debug for TileCamera
impl Eq for TileCamera
Source§impl PartialEq for TileCamera
impl PartialEq for TileCamera
Source§fn eq(&self, other: &TileCamera) -> bool
fn eq(&self, other: &TileCamera) -> bool
self and other values to be equal, and is used by ==.impl StructuralPartialEq for TileCamera
Auto Trait Implementations§
impl Freeze for TileCamera
impl RefUnwindSafe for TileCamera
impl Send for TileCamera
impl Sync for TileCamera
impl Unpin for TileCamera
impl UnsafeUnpin for TileCamera
impl UnwindSafe for TileCamera
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§impl<C> WithAlpha for Cwhere
C: Copy,
impl<C> WithAlpha for Cwhere
C: Copy,
§fn with_alpha_first<A>(self, alpha: A) -> AlphaFirst<A, Self>
fn with_alpha_first<A>(self, alpha: A) -> AlphaFirst<A, Self>
self with alpha, storing alpha before the color in memory
(see [AlphaFirst]).§fn with_alpha_last<A>(self, alpha: A) -> AlphaLast<A, Self>
fn with_alpha_last<A>(self, alpha: A) -> AlphaLast<A, Self>
self with alpha, storing alpha after the color in memory
(see [AlphaLast]).