gardesk/garshot / 3eb67f9

Browse files

annotate: add line tool

Authored by mfwolffe <wolffemf@dukes.jmu.edu>
SHA
3eb67f9448fbe1150bb0cbe83377b556ec984c88
Parents
c1ae587
Tree
36ff4ec

1 changed file

StatusFile+-
A garshot/src/annotate/tools/line.rs 99 0
garshot/src/annotate/tools/line.rsadded
@@ -0,0 +1,99 @@
1
+//! Line tool - draw straight lines.
2
+
3
+use super::Tool;
4
+use crate::annotate::state::ToolProperties;
5
+use gartk_core::{InputEvent, MouseButton, Point};
6
+use gartk_render::cairo::Context;
7
+use gartk_render::line as draw_line;
8
+use gartk_x11::CursorShape;
9
+
10
+/// Line drawing tool.
11
+pub struct LineTool {
12
+    /// Starting point of the line.
13
+    start: Option<Point>,
14
+    /// Ending point of the line.
15
+    end: Option<Point>,
16
+    /// Whether we're currently drawing.
17
+    drawing: bool,
18
+}
19
+
20
+impl LineTool {
21
+    /// Create a new line tool.
22
+    pub fn new() -> Self {
23
+        Self {
24
+            start: None,
25
+            end: None,
26
+            drawing: false,
27
+        }
28
+    }
29
+}
30
+
31
+impl Default for LineTool {
32
+    fn default() -> Self {
33
+        Self::new()
34
+    }
35
+}
36
+
37
+impl Tool for LineTool {
38
+    fn handle_event(&mut self, event: &InputEvent, _props: &ToolProperties) -> bool {
39
+        match event {
40
+            InputEvent::MousePress(e) if e.button == Some(MouseButton::Left) => {
41
+                self.start = Some(e.position);
42
+                self.end = Some(e.position);
43
+                self.drawing = true;
44
+                true
45
+            }
46
+            InputEvent::MouseMove(e) if self.drawing => {
47
+                self.end = Some(e.position);
48
+                true
49
+            }
50
+            InputEvent::MouseRelease(e) if e.button == Some(MouseButton::Left) && self.drawing => {
51
+                self.end = Some(e.position);
52
+                self.drawing = false;
53
+                true
54
+            }
55
+            _ => false,
56
+        }
57
+    }
58
+
59
+    fn draw_preview(&self, ctx: &Context, props: &ToolProperties) {
60
+        if let (Some(start), Some(end)) = (self.start, self.end) {
61
+            draw_line(
62
+                ctx,
63
+                start.x as f64,
64
+                start.y as f64,
65
+                end.x as f64,
66
+                end.y as f64,
67
+                props.color,
68
+                props.line_width,
69
+            );
70
+        }
71
+    }
72
+
73
+    fn commit(&self, ctx: &Context, props: &ToolProperties) {
74
+        self.draw_preview(ctx, props);
75
+    }
76
+
77
+    fn reset(&mut self) {
78
+        self.start = None;
79
+        self.end = None;
80
+        self.drawing = false;
81
+    }
82
+
83
+    fn cursor(&self) -> CursorShape {
84
+        CursorShape::Crosshair
85
+    }
86
+
87
+    fn is_drawing(&self) -> bool {
88
+        self.drawing
89
+    }
90
+
91
+    fn can_commit(&self) -> bool {
92
+        if let (Some(start), Some(end)) = (self.start, self.end) {
93
+            // Line is valid if it has some length
94
+            start.x != end.x || start.y != end.y
95
+        } else {
96
+            false
97
+        }
98
+    }
99
+}