drag_controller/
lib.rs

1#![deny(missing_docs)]
2#![deny(missing_copy_implementations)]
3
4//! A drag controller
5
6extern crate input;
7
8use input::{
9    GenericEvent,
10    MouseButton,
11};
12use input::Button::Mouse;
13
14/// Describes a drag
15#[derive(Copy, Clone)]
16pub enum Drag {
17    /// When the drag is interrupted by something,
18    /// for example when the window is defocused.
19    /// By returning true, the drag will continue when
20    /// the window retrieves focus.
21    Interrupt,
22    /// Starts the drag.
23    Start(f64, f64),
24    /// Moves the drag.
25    Move(f64, f64),
26    /// Ends the drag.
27    End(f64, f64),
28}
29
30/// Controls dragging.
31#[derive(Copy, Clone)]
32pub struct DragController {
33    /// Whether to drag or not.
34    pub drag: bool,
35    /// The current positon of dragging.
36    pub pos: [f64; 2],
37}
38
39impl DragController {
40    /// Creates a new drag controller.
41    pub fn new() -> DragController {
42        DragController {
43            drag: false,
44            pos: [0.0, 0.0],
45        }
46    }
47
48    /// Handles event.
49    ///
50    /// Calls closure when events for dragging happen.
51    /// If the drag event callback returns `false`, it will cancel dragging.
52    pub fn event<E: GenericEvent, F>(&mut self, e: &E, mut f: F)
53        where
54            F: FnMut(Drag) -> bool
55    {
56        e.mouse_cursor(|pos| {
57            self.pos = pos;
58            if self.drag {
59                self.drag = f(Drag::Move(pos[0], pos[1]));
60            }
61        });
62        e.press(|button| {
63            match button {
64                Mouse(MouseButton::Left) => {
65                    if !self.drag {
66                        self.drag = f(Drag::Start(self.pos[0], self.pos[1]));
67                    }
68                }
69                _ => {}
70            }
71        });
72
73        // Rest of the event are only handled when dragging.
74        if !self.drag { return; }
75
76        e.release(|button| {
77            match button {
78                Mouse(MouseButton::Left) => {
79                    if self.drag {
80                        f(Drag::End(self.pos[0], self.pos[1]));
81                    }
82                    self.drag = false;
83                }
84                _ => {}
85            }
86        });
87        e.focus(|focused| {
88            if focused == false {
89                self.drag = f(Drag::Interrupt);
90            }
91        });
92    }
93}
94