map_gui/tools/
camera.rs

1use serde::{Deserialize, Serialize};
2
3use abstio::MapName;
4use abstutil::Timer;
5use widgetry::{Canvas, EventCtx};
6
7/// Represents the state of a widgetry Canvas.
8#[derive(Serialize, Deserialize, Debug)]
9pub struct CameraState {
10    cam_x: f64,
11    cam_y: f64,
12    cam_zoom: f64,
13}
14
15/// Track the last map used, to resume next session.
16#[derive(Serialize, Deserialize, Debug)]
17pub struct DefaultMap {
18    pub last_map: MapName,
19}
20
21impl CameraState {
22    /// Save the camera's configuration for the specified map, and also remember this map was the
23    /// last to be used.
24    pub fn save(canvas: &Canvas, name: &MapName) {
25        if name == &MapName::blank() {
26            return;
27        }
28
29        let state = CameraState {
30            cam_x: canvas.cam_x,
31            cam_y: canvas.cam_y,
32            cam_zoom: canvas.cam_zoom,
33        };
34        abstio::write_json(abstio::path_camera_state(name), &state);
35
36        abstio::write_json(
37            abstio::path_player("maps.json"),
38            &DefaultMap {
39                last_map: name.clone(),
40            },
41        );
42    }
43
44    /// Load the camera's configuration for the specified map. Returns true if successful, has no
45    /// effect if the file is missing or broken.
46    pub fn load(ctx: &mut EventCtx, name: &MapName) -> bool {
47        // Special case: if this is a one-shot imported map without an explicit name, ignore any
48        // saved file. It's likely for a previously imported and different map!
49        if name.city.city == "oneshot" && name.map.starts_with("imported_") {
50            return false;
51        }
52
53        match abstio::maybe_read_json::<CameraState>(
54            abstio::path_camera_state(name),
55            &mut Timer::throwaway(),
56        ) {
57            Ok(ref loaded) => {
58                ctx.canvas.cam_x = loaded.cam_x;
59                ctx.canvas.cam_y = loaded.cam_y;
60                ctx.canvas.cam_zoom = loaded.cam_zoom;
61                true
62            }
63            Err(_) => false,
64        }
65    }
66}