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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
use std::collections::VecDeque;

use crate::{shared::*, screen::ZelData};
use super::{MouseButton, MouseEvent};

#[derive(Clone, Copy)]
pub struct DragMonitor {
    start: Option<State>,
    old: Option<State>,
    event_to_send: Option<ToSend>, 
}

#[derive(Clone, Copy)]
struct ToSend {
    start: Zel,
    last: Zel,
    now: Zel,
}

#[derive(Clone, Copy)]
pub struct State {
    point: Zel,
}

impl DragMonitor {
    pub fn new() -> DragMonitor {
        DragMonitor {
            start: None,
            old: None,
            event_to_send: None,  // use this to rate-limit
        }
    }

    pub(crate) fn down(&mut self, point: Zel) {
        self.start = Some(State { point });
        self.old = self.start
    }

    pub(crate) fn at(
        &mut self, 
        point: Zel, 
    ) {
        if self.start.is_none() { return; }
        let start = self.start.unwrap();
        let old = self.old.unwrap();  // set when start is set
        let new = State { point };

        if old.point == new.point { return }

        if let Some(e) = &mut self.event_to_send {
            e.now = new.point;
        } else {
            self.event_to_send = Some(ToSend { start: start.point, last: old.point, now: new.point });
        }
        self.old = Some(new);
    }

    pub(crate) fn post_events(
        &mut self,
        events: &mut VecDeque<crate::input::MouseEvent>, 
        mouse_button: MouseButton,
        get_zel: &impl Fn(Zel) -> ZelData,
    ) {
        if let Some(ToSend { start, last, now }) = self.event_to_send.take() {
            let zel = get_zel(now);

            events.push_back(MouseEvent::Drag {
                mouse_button,
                start,
                last,
                now,
                now_click_selection: zel.click,
                now_scroll_selection: zel.scroll,
            });
        }
    }

    pub(crate) fn up(
        &mut self,
        events: &mut VecDeque<crate::input::MouseEvent>,
        mouse_button: MouseButton,
        get_zel: &impl Fn(Zel) -> ZelData,
    ) {
        self.post_events(events, mouse_button, get_zel);

        self.event_to_send = None;
        self.start = None;
        self.old = None;
    }
}