aboutsummaryrefslogtreecommitdiff
path: root/games/rstnode/rst-client/src/viewport.rs
blob: 3f9e803e387b55a08e4e3f9b9fef13b0324b220c (plain)
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
62
63
//! Viewport utilities

use crate::{graphics::Vector2, input::InputHandle};
use ggez::{
    error::GameResult,
    graphics::{self, Rect},
    Context,
};

#[derive(Default)]
pub struct Viewport {
    start: Vector2,
    prev_start: Vector2,
    size: Vector2,
}

impl Viewport {
    pub fn new() -> Self {
        Self::default()
    }

    pub fn start(&self) -> &Vector2 {
        &self.start
    }

    /// Must be called at least once before calling
    /// [`update`](Self::update)
    pub fn init(&mut self, ctx: &mut Context) {
        let Rect { x, y, w, h } = graphics::screen_coordinates(&ctx);
        self.start = Vector2::new(x, y);
        self.prev_start = self.start;
        self.size = Vector2::new(w, h);
    }

    /// Update the game state with the curent viewport data
    pub fn update(&self, ctx: &mut Context) -> GameResult<()> {
        graphics::set_screen_coordinates(
            ctx,
            Rect {
                x: self.start.x,
                y: self.start.y,
                w: self.size.x,
                h: self.size.y,
            },
        )?;

        Ok(())
    }

    /// Apply changes from the input handle to the viewport
    pub fn apply(&mut self, _: &mut Context, input: &InputHandle) -> GameResult<()> {
        if input.middle_pressed {
            let drag = input.drag_point.as_ref().unwrap().clone();
            let pos = input.mouse_pos.clone();
            self.start = self.prev_start + (drag - pos);
            debug!("Changing VP start: {}", self.start);
        } else {
            self.prev_start = self.start;
        }

        Ok(())
    }
}