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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
use glutin;
use event::{EventHandler, EventArgs};
use widget::Widget;
use input::mouse::{MouseMoved, MouseButton, WidgetMouseButton};
use geometry::{Point, Vector};
use app::App;
#[derive(Debug, Copy, Clone)]
pub struct DragEvent {
pub state: DragState,
pub position: Point,
pub offset: Vector,
pub change: Vector,
}
#[derive(Debug, Copy, Clone, PartialEq)]
pub enum DragState {
Start,
Moved,
End,
}
#[derive(Debug, Clone)]
struct DragInputHandler {
widget: Option<Widget>,
position: Point,
start_position: Point,
prev_position: Point,
}
impl DragInputHandler {
pub fn new() -> Self {
DragInputHandler {
widget: None,
position: Point::new(0.0, 0.0),
start_position: Point::new(0.0, 0.0),
prev_position: Point::new(0.0, 0.0),
}
}
pub fn drag_event(&self, state: DragState) -> DragEvent {
DragEvent {
state: state,
position: self.position,
offset: self.position - self.start_position,
change: self.position - self.prev_position,
}
}
}
impl EventHandler<DragInputEvent> for DragInputHandler {
fn handle(&mut self, event: &DragInputEvent, _: EventArgs) {
match *event {
DragInputEvent::WidgetPressed(ref widget) => {
self.widget = Some(widget.clone());
self.start_position = self.position;
widget.event(self.drag_event(DragState::Start));
}
DragInputEvent::MouseMoved(point) => {
self.prev_position = self.position;
self.position = point;
if let Some(ref widget) = self.widget {
widget.event(self.drag_event(DragState::Moved));
}
}
DragInputEvent::MouseReleased => {
if let Some(widget) = self.widget.take() {
widget.event(self.drag_event(DragState::End));
}
}
}
}
}
#[derive(Debug, Clone)]
enum DragInputEvent {
WidgetPressed(Widget),
MouseMoved(Point),
MouseReleased,
}
impl Widget {
pub fn make_draggable(&mut self) -> &mut Self {
self.add_handler(|event: &WidgetMouseButton, args: EventArgs| {
if let WidgetMouseButton(glutin::ElementState::Pressed, _) = *event {
let event = DragInputEvent::WidgetPressed(args.widget);
args.ui.event(event);
}
});
self
}
}
impl App {
pub fn add_drag_handlers(&mut self) {
self.add_handler(DragInputHandler::new());
self.add_handler(|event: &MouseMoved, args: EventArgs| {
args.ui.event(DragInputEvent::MouseMoved(event.0));
});
self.add_handler(|event: &MouseButton, args: EventArgs| {
if let MouseButton(glutin::ElementState::Released, _) = *event {
args.ui.event(DragInputEvent::MouseReleased);
}
});
}
}