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