widgetry/mapspace/
mod.rs

1mod unzoomed;
2mod world;
3
4use geom::Polygon;
5
6use crate::{Drawable, EventCtx, Fill, GeomBatch, GfxCtx, RewriteColor};
7pub use unzoomed::{DrawCustomUnzoomedShapes, DrawUnzoomedShapes, PerZoom};
8pub use world::{DummyID, ObjectID, World, WorldOutcome};
9
10/// Draws one of two versions of something, based on whether the canvas is zoomed in past a threshold.
11pub struct ToggleZoomed {
12    // Some callers access directly for minimaps
13    pub unzoomed: Drawable,
14    pub zoomed: Drawable,
15    // Draw the same thing whether zoomed or unzoomed
16    always_draw_unzoomed: bool,
17}
18
19impl ToggleZoomed {
20    pub fn new(ctx: &EventCtx, unzoomed: GeomBatch, zoomed: GeomBatch) -> ToggleZoomed {
21        ToggleZoomed {
22            unzoomed: ctx.upload(unzoomed),
23            zoomed: ctx.upload(zoomed),
24            always_draw_unzoomed: false,
25        }
26    }
27
28    pub fn empty(ctx: &EventCtx) -> ToggleZoomed {
29        ToggleZoomed {
30            unzoomed: Drawable::empty(ctx),
31            zoomed: Drawable::empty(ctx),
32            always_draw_unzoomed: false,
33        }
34    }
35
36    pub fn builder() -> ToggleZoomedBuilder {
37        ToggleZoomedBuilder {
38            unzoomed: GeomBatch::new(),
39            zoomed: GeomBatch::new(),
40            always_draw_unzoomed: false,
41        }
42    }
43
44    pub fn draw(&self, g: &mut GfxCtx) {
45        if self.always_draw_unzoomed || g.canvas.cam_zoom < g.canvas.settings.min_zoom_for_detail {
46            g.redraw(&self.unzoomed);
47        } else {
48            g.redraw(&self.zoomed);
49        }
50    }
51}
52
53#[derive(Clone)]
54pub struct ToggleZoomedBuilder {
55    pub unzoomed: GeomBatch,
56    pub zoomed: GeomBatch,
57    always_draw_unzoomed: bool,
58}
59
60impl ToggleZoomedBuilder {
61    /// Transforms all colors in both batches.
62    pub fn color(mut self, transformation: RewriteColor) -> Self {
63        self.unzoomed = self.unzoomed.color(transformation);
64        if !self.always_draw_unzoomed {
65            self.zoomed = self.zoomed.color(transformation);
66        }
67        self
68    }
69
70    /// Adds a single polygon to both batches, painted according to `Fill`
71    pub fn push<F: Into<Fill>>(mut self, fill: F, p: Polygon) -> Self {
72        let fill = fill.into();
73        if !self.always_draw_unzoomed {
74            self.zoomed.push(fill.clone(), p.clone());
75        }
76        self.unzoomed.push(fill, p);
77        self
78    }
79
80    /// Mark that this object will be drawn differently when zoomed and unzoomed, undoing the
81    /// effects of converting from a single `GeomBatch`. Idempotent.
82    pub fn draw_differently_zoomed(mut self) -> Self {
83        if self.always_draw_unzoomed {
84            self.always_draw_unzoomed = false;
85            self.zoomed = self.unzoomed.clone();
86        }
87        self
88    }
89
90    pub fn append(&mut self, other: ToggleZoomedBuilder) {
91        assert_eq!(self.always_draw_unzoomed, other.always_draw_unzoomed);
92        self.unzoomed.append(other.unzoomed);
93        self.zoomed.append(other.zoomed);
94    }
95
96    pub fn build(self, ctx: &EventCtx) -> ToggleZoomed {
97        if self.always_draw_unzoomed {
98            assert!(self.zoomed.is_empty());
99        }
100        ToggleZoomed {
101            unzoomed: ctx.upload(self.unzoomed),
102            zoomed: ctx.upload(self.zoomed),
103            always_draw_unzoomed: self.always_draw_unzoomed,
104        }
105    }
106}
107
108// Drawing just one batch means the same thing will appear whether zoomed or unzoomed
109impl std::convert::From<GeomBatch> for ToggleZoomedBuilder {
110    fn from(unzoomed: GeomBatch) -> Self {
111        Self {
112            unzoomed,
113            zoomed: GeomBatch::new(),
114            always_draw_unzoomed: true,
115        }
116    }
117}