freya_core/
events_combos.rs

1use std::time::{
2    Duration,
3    Instant,
4};
5
6use torin::prelude::CursorPoint;
7
8use crate::{
9    integration::ScopeId,
10    prelude::{
11        State,
12        *,
13    },
14};
15
16#[derive(Clone, Copy, PartialEq)]
17pub struct EventsCombos {
18    pub(crate) last_press: State<Option<(Instant, CursorPoint, u8)>>,
19}
20
21impl EventsCombos {
22    pub fn get() -> Self {
23        match try_consume_root_context() {
24            Some(rt) => rt,
25            None => {
26                let context_menu_state = EventsCombos {
27                    last_press: State::create_in_scope(None, ScopeId::ROOT),
28                };
29                provide_context_for_scope_id(context_menu_state, ScopeId::ROOT);
30                context_menu_state
31            }
32        }
33    }
34
35    pub fn pressed(location: CursorPoint) -> PressEventType {
36        let mut combos = Self::get();
37        let (event_type, click_count) = match &*combos.last_press.read() {
38            Some((inst, last_location, count))
39                if last_location == &location && inst.elapsed() <= MULTI_PRESS_ELAPSED =>
40            {
41                match count {
42                    1 => (PressEventType::Double, 2),
43                    2 => (PressEventType::Triple, 3),
44                    _ => (PressEventType::Single, 1),
45                }
46            }
47            _ => (PressEventType::Single, 1),
48        };
49        combos
50            .last_press
51            .set(Some((Instant::now(), location, click_count)));
52        event_type
53    }
54}
55
56const MULTI_PRESS_ELAPSED: Duration = Duration::from_millis(500);
57
58#[derive(Debug, Clone, Copy, PartialEq, Eq)]
59pub enum PressEventType {
60    Single,
61    Double,
62    Triple,
63}
64
65impl PressEventType {
66    pub fn is_single(&self) -> bool {
67        matches!(self, Self::Single)
68    }
69
70    pub fn is_double(&self) -> bool {
71        matches!(self, Self::Double)
72    }
73
74    pub fn is_triple(&self) -> bool {
75        matches!(self, Self::Triple)
76    }
77}