blockworx_egui/
interaction.rs1use blockworx_geom::Pos2;
8use blockworx_paint::{Event, Interaction, Press, Zoom};
9use egui::Response;
10
11use crate::convert::IntoGeom as _;
12
13pub(crate) fn compute_interaction(
17 response: &Response,
18 screen_to_world: impl Fn(Pos2) -> Pos2,
19 zoom: Zoom,
20 ui: &egui::Ui,
21) -> Interaction {
22 let press = (response.is_pointer_button_down_on() && ui.input(|i| i.pointer.primary_down()))
26 .then(|| ui.input(|i| i.pointer.press_origin()))
27 .flatten()
28 .map(|origin| Press {
29 origin: screen_to_world(origin.geom()),
30 });
31 let event = compute_event(response, screen_to_world, zoom);
32 let clicked = matches!(event, Some(Event::Clicked { .. }));
33 let lost_focus = response.lost_focus() || clicked;
34 let enter_pressed = response.has_focus() && ui.input(|i| i.key_pressed(egui::Key::Enter));
37 let other_focus = ui.memory(|m| m.focused().is_some_and(|id| id != response.id));
42 let delete_pressed = !response.has_focus()
43 && !other_focus
44 && ui.input(|i| i.key_pressed(egui::Key::Delete) || i.key_pressed(egui::Key::Backspace));
45 let escape_pressed =
49 !response.has_focus() && !other_focus && ui.input(|i| i.key_pressed(egui::Key::Escape));
50 let shift = ui.input(|i| i.modifiers.shift);
51 Interaction {
52 event,
53 press,
54 lost_focus,
55 enter_pressed,
56 tab_pressed: false,
59 escape_pressed,
60 delete_pressed,
61 shift,
62 }
63}
64
65pub(crate) fn compute_event(
66 response: &Response,
67 screen_to_world: impl Fn(Pos2) -> Pos2,
68 zoom: Zoom,
69) -> Option<Event> {
70 if response.double_clicked()
71 && let Some(pos) = response.interact_pointer_pos()
72 {
73 Some(Event::DoubleClicked {
74 pos: screen_to_world(pos.geom()),
75 })
76 } else if response.clicked()
77 && let Some(pos) = response.interact_pointer_pos()
78 {
79 Some(Event::Clicked {
80 pos: screen_to_world(pos.geom()),
81 })
82 } else if response.drag_started()
83 && let Some(pos) = response.interact_pointer_pos()
84 {
85 Some(Event::DragStarted {
86 pos: screen_to_world(pos.geom()),
87 })
88 } else if response.dragged()
89 && let Some(pos) = response.interact_pointer_pos()
90 {
91 Some(Event::Dragging {
92 pos: screen_to_world(pos.geom()),
93 delta: response.drag_delta().geom() / zoom.get(),
94 })
95 } else if response.drag_stopped()
96 && let Some(pos) = response.interact_pointer_pos()
97 {
98 Some(Event::DragStopped {
99 pos: screen_to_world(pos.geom()),
100 })
101 } else if response.hovered()
102 && let Some(pos) = response.hover_pos()
103 {
104 Some(Event::HoverAt(screen_to_world(pos.geom())))
105 } else {
106 None
107 }
108}