blockworx_tools/
new_image.rs1use blockworx_geom::{Pos2, Rect, WorldPx};
2
3use crate::theme::Style;
4use crate::{
5 grid::GRID_SIZE,
6 names::ToolName,
7 theme::Role,
8 tool::{Action, ImageTarget, ToolTrait},
9 widget::drawing::Drawing,
10};
11use blockworx_paint::{Canvas, Cursor, Event, Interaction};
12
13pub enum NewImage {
24 Idle,
25 Dragging { start: Pos2 },
26}
27
28pub enum Placement {
31 Box(Rect),
32 Centered(Pos2),
33}
34
35impl ToolTrait for NewImage {
36 fn name(&self) -> ToolName {
37 ToolName::NewImage
38 }
39 fn widget<C: Canvas>(
40 &mut self,
41 data: &mut Drawing,
42 interaction: &Interaction,
43 painter: &mut Style<'_, C>,
44 ) -> Option<Action> {
45 crate::widget::display::widget(data, interaction, painter);
46 painter.set_cursor(Cursor::Crosshair);
47 match self {
48 NewImage::Idle => {
49 if let Some(Event::DragStarted { pos }) = interaction.event {
50 *self = NewImage::Dragging { start: pos };
51 }
52 }
53 NewImage::Dragging { start } => {
54 if let Some(Event::Dragging { pos, .. }) = interaction.event {
55 let rect = Rect::from_two_pos(*start, pos);
56 painter.rect(
57 rect,
58 WorldPx::ZERO,
59 Role::Transparent,
60 (1.0, Role::ImageDragBox),
61 );
62 } else if let Some(Event::DragStopped { pos }) = interaction.event {
63 let candidate = Rect::from_two_pos(*start, pos);
64 *self = NewImage::Idle;
65 if candidate.width() > GRID_SIZE && candidate.height() > GRID_SIZE {
66 return Some(Action::ImageWanted(ImageTarget::Place(Placement::Box(
67 candidate,
68 ))));
69 }
70 }
71 }
72 }
73 None
74 }
75}