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
use geom::{Distance, PolyLine, Polygon, Pt2D, Ring};
use crate::{Color, EventCtx, GfxCtx};
pub struct Lasso {
points: Vec<Pt2D>,
polygon: Option<Polygon>,
}
impl Lasso {
pub fn new() -> Self {
Self {
points: Vec::new(),
polygon: None,
}
}
pub fn event(&mut self, ctx: &mut EventCtx) -> Option<Polygon> {
if self.points.is_empty() {
if let Some(pt) = ctx.canvas.get_cursor_in_map_space() {
if ctx.input.left_mouse_button_pressed() {
self.points.push(pt);
}
}
return None;
}
if ctx.input.left_mouse_button_released() {
return self.polygon.take();
}
if ctx.redo_mouseover() {
if let Some(pt) = ctx.canvas.get_cursor_in_map_space() {
if self.points.last().as_ref().unwrap().dist_to(pt) > Distance::meters(0.1) {
self.points.push(pt);
let mut copy = self.points.clone();
copy.push(copy[0]);
self.polygon = Ring::new(copy)
.ok()
.map(|ring| ring.into_polygon().simplify(1.0));
}
}
}
None
}
pub fn draw(&self, g: &mut GfxCtx) {
if let Ok(pl) = PolyLine::new(self.points.clone()) {
g.draw_polygon(
Color::RED.alpha(0.8),
pl.make_polygons(Distance::meters(5.0) / g.canvas.cam_zoom),
);
}
if let Some(ref polygon) = self.polygon {
g.draw_polygon(Color::RED.alpha(0.5), polygon.clone());
}
}
}
pub struct PolyLineLasso {
pl: Option<PolyLine>,
}
impl PolyLineLasso {
pub fn new() -> Self {
Self { pl: None }
}
pub fn event(&mut self, ctx: &mut EventCtx) -> Option<PolyLine> {
if self.pl.is_none() {
if let Some(pt) = ctx.canvas.get_cursor_in_map_space() {
if ctx.input.left_mouse_button_pressed() {
self.pl = Some(PolyLine::must_new(vec![pt, pt.offset(0.1, 0.1)]));
}
}
return None;
}
if ctx.input.left_mouse_button_released() {
return self.pl.take();
}
if ctx.redo_mouseover() {
if let Some(pt) = ctx.canvas.get_cursor_in_map_space() {
let pl = self.pl.take().unwrap();
self.pl = Some(pl.optionally_push(pt));
}
}
None
}
pub fn draw(&self, g: &mut GfxCtx) {
if let Some(ref pl) = self.pl {
g.draw_polygon(
Color::RED.alpha(0.8),
pl.make_polygons(Distance::meters(5.0) / g.canvas.cam_zoom),
);
}
}
}