Skip to main content

egui_map_view/layers/
tile.rs

1//! A layer for tile maps on the map.
2
3use egui::{Color32, Painter, Response};
4use std::{any::Any, collections::HashMap};
5
6use crate::{
7    Tile, TileId, config::MapConfig, draw_tile, layers::Layer, load_tile,
8    projection::MapProjection, visible_tiles,
9};
10
11/// A layer that manages and renders map tiles on the map view.
12pub struct TileLayer {
13    tiles: HashMap<TileId, Tile>,
14    visible_tiles: Vec<(TileId, egui::Pos2)>,
15    /// Color tint applied to the tile images when rendering
16    pub tint: Color32,
17    config: Box<dyn MapConfig>,
18    /// The opacity of the layer.
19    pub opacity: f32,
20}
21
22impl TileLayer {
23    /// Creates a new tile layer with the given map configuration.
24    pub fn new(config: impl MapConfig + 'static) -> Self {
25        Self {
26            tiles: Default::default(),
27            visible_tiles: Default::default(),
28            tint: Color32::WHITE,
29            config: Box::new(config),
30            opacity: 1.0,
31        }
32    }
33}
34
35impl Layer for TileLayer {
36    fn as_any(&self) -> &dyn Any {
37        self
38    }
39
40    fn as_any_mut(&mut self) -> &mut dyn Any {
41        self
42    }
43
44    fn opacity(&self) -> f32 {
45        self.opacity
46    }
47
48    fn set_opacity(&mut self, opacity: f32) {
49        self.opacity = opacity;
50    }
51
52    fn handle_input(&mut self, response: &Response, projection: &MapProjection) -> bool {
53        self.visible_tiles = visible_tiles(projection).collect();
54        for (tile_id, _) in &self.visible_tiles {
55            load_tile(
56                &mut self.tiles,
57                self.config.as_ref(),
58                &response.ctx,
59                *tile_id,
60            );
61        }
62        false
63    }
64
65    fn draw(&self, painter: &Painter, _: &MapProjection) {
66        for (tile_id, tile_pos) in &self.visible_tiles {
67            draw_tile(
68                &self.tiles,
69                painter,
70                tile_id,
71                *tile_pos,
72                self.tint.gamma_multiply(self.opacity),
73            );
74        }
75    }
76}