@@ -0,0 +1,70 @@ |
| 1 | +//! Annotation tools. |
| 2 | +//! |
| 3 | +//! Each tool implements the [`Tool`] trait for consistent behavior. |
| 4 | + |
| 5 | +mod arrow; |
| 6 | +mod blur; |
| 7 | +mod brush; |
| 8 | +mod ellipse; |
| 9 | +mod highlight; |
| 10 | +mod line; |
| 11 | +mod rectangle; |
| 12 | +mod text; |
| 13 | + |
| 14 | +pub use arrow::ArrowTool; |
| 15 | +pub use blur::BlurTool; |
| 16 | +pub use brush::BrushTool; |
| 17 | +pub use ellipse::EllipseTool; |
| 18 | +pub use highlight::HighlightTool; |
| 19 | +pub use line::LineTool; |
| 20 | +pub use rectangle::RectangleTool; |
| 21 | +pub use text::TextTool; |
| 22 | + |
| 23 | +use crate::annotate::state::ToolProperties; |
| 24 | +use cairo::Context; |
| 25 | +use gartk_core::InputEvent; |
| 26 | +use gartk_x11::CursorShape; |
| 27 | + |
| 28 | +/// Tool behavior trait. |
| 29 | +/// |
| 30 | +/// All annotation tools implement this trait for consistent handling. |
| 31 | +pub trait Tool { |
| 32 | + /// Handle an input event. |
| 33 | + /// |
| 34 | + /// Returns `true` if the preview needs to be redrawn. |
| 35 | + fn handle_event(&mut self, event: &InputEvent, props: &ToolProperties) -> bool; |
| 36 | + |
| 37 | + /// Draw the current preview to the context. |
| 38 | + fn draw_preview(&self, ctx: &Context, props: &ToolProperties); |
| 39 | + |
| 40 | + /// Commit the current drawing to the annotations layer. |
| 41 | + fn commit(&self, ctx: &Context, props: &ToolProperties); |
| 42 | + |
| 43 | + /// Reset the tool state (clear current drawing). |
| 44 | + fn reset(&mut self); |
| 45 | + |
| 46 | + /// Get the cursor shape for this tool. |
| 47 | + fn cursor(&self) -> CursorShape; |
| 48 | + |
| 49 | + /// Check if the tool has an active drawing in progress. |
| 50 | + fn is_drawing(&self) -> bool; |
| 51 | + |
| 52 | + /// Check if the tool is ready to commit (has a valid drawing). |
| 53 | + fn can_commit(&self) -> bool; |
| 54 | +} |
| 55 | + |
| 56 | +/// Create a boxed tool instance for the given tool type. |
| 57 | +pub fn create_tool(tool_type: super::state::ToolType) -> Box<dyn Tool> { |
| 58 | + use super::state::ToolType; |
| 59 | + |
| 60 | + match tool_type { |
| 61 | + ToolType::Brush => Box::new(BrushTool::new()), |
| 62 | + ToolType::Line => Box::new(LineTool::new()), |
| 63 | + ToolType::Arrow => Box::new(ArrowTool::new()), |
| 64 | + ToolType::Rectangle => Box::new(RectangleTool::new()), |
| 65 | + ToolType::Ellipse => Box::new(EllipseTool::new()), |
| 66 | + ToolType::Text => Box::new(TextTool::new()), |
| 67 | + ToolType::Blur => Box::new(BlurTool::new()), |
| 68 | + ToolType::Highlight => Box::new(HighlightTool::new()), |
| 69 | + } |
| 70 | +} |