blockworx/tools/
new_area.rs1use crate::theme::Style;
2use blockworx_geom::{Pos2, Rect, WorldPx};
3use blockworx_paint::{Canvas, Cursor, Event, Interaction};
4
5use crate::{
6 grid::GRID_SIZE,
7 theme::Role,
8 tools::{
9 RenameTitle,
10 names::ToolName,
11 tool::{Action, ToolTrait},
12 },
13 widget::drawing::Drawing,
14};
15
16pub enum NewArea {
21 Idle,
22 Dragging { start: Pos2 },
23}
24
25impl ToolTrait for NewArea {
26 fn name(&self) -> ToolName {
27 ToolName::NewArea
28 }
29 fn widget<C: Canvas>(
30 &mut self,
31 data: &mut Drawing,
32 interaction: &Interaction,
33 painter: &mut Style<'_, C>,
34 ) -> Option<Action> {
35 crate::widget::display::widget(data, interaction, painter);
36 painter.set_cursor(Cursor::Crosshair);
37 match self {
38 NewArea::Idle => {
39 if let Some(Event::DragStarted { pos }) = interaction.event {
40 *self = NewArea::Dragging { start: pos };
41 }
42 }
43 NewArea::Dragging { start } => {
44 if let Some(Event::Dragging { pos, .. }) = interaction.event {
45 let rect = Rect::from_two_pos(*start, pos);
46 painter.rect(
47 rect,
48 WorldPx::ZERO,
49 Role::Transparent,
50 (1.0, Role::AreaStroke),
51 );
52 } else if let Some(Event::DragStopped { pos }) = interaction.event {
53 let start_pos = *start;
54 let candidate = Rect::from_two_pos(start_pos, pos);
55 *self = NewArea::Idle;
56 if candidate.width() > GRID_SIZE && candidate.height() > GRID_SIZE {
57 let shape = data.add_area(start_pos, pos);
58 return Some(RenameTitle::action(data, shape));
60 }
61 }
62 }
63 }
64 None
65 }
66}