1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
use serde::{Deserialize, Serialize};
use widgetry::{Canvas, EventCtx};

use abstio::MapName;
use abstutil::Timer;
use map_model::Map;

/// Represents the state of a widgetry Canvas.
#[derive(Serialize, Deserialize, Debug)]
pub struct CameraState {
    cam_x: f64,
    cam_y: f64,
    cam_zoom: f64,
}

/// Track the last map used, to resume next session.
#[derive(Serialize, Deserialize, Debug)]
pub struct DefaultMap {
    pub last_map: MapName,
}

impl CameraState {
    /// Save the camera's configuration for the specified map, and also remember this map was the
    /// last to be used.
    pub fn save(canvas: &Canvas, name: &MapName) {
        if name == Map::blank().get_name() {
            return;
        }

        let state = CameraState {
            cam_x: canvas.cam_x,
            cam_y: canvas.cam_y,
            cam_zoom: canvas.cam_zoom,
        };
        abstio::write_json(abstio::path_camera_state(name), &state);

        abstio::write_json(
            abstio::path_player("maps.json"),
            &DefaultMap {
                last_map: name.clone(),
            },
        );
    }

    /// Load the camera's configuration for the specified map. Returns true if successful, has no
    /// effect if the file is missing or broken.
    pub fn load(ctx: &mut EventCtx, name: &MapName) -> bool {
        match abstio::maybe_read_json::<CameraState>(
            abstio::path_camera_state(name),
            &mut Timer::throwaway(),
        ) {
            Ok(ref loaded) => {
                ctx.canvas.cam_x = loaded.cam_x;
                ctx.canvas.cam_y = loaded.cam_y;
                ctx.canvas.cam_zoom = loaded.cam_zoom;
                true
            }
            Err(_) => false,
        }
    }
}