feat(viewport,overlay): drag to select bbox

This commit is contained in:
Alain Emilia Anna Zscheile 2025-01-01 22:53:13 +01:00
parent eaadc60265
commit d703d5c3e3
2 changed files with 26 additions and 8 deletions

View File

@ -3,7 +3,7 @@
// SPDX-License-Identifier: MIT
use geo::Point;
use rstar::AABB;
use rstar::{Point as _, AABB};
use spade::InsertionError;
use topola::{
@ -59,10 +59,24 @@ impl Overlay {
self.reselect_bbox = Some(None);
}
pub fn drag_start(&mut self, board: &Board<impl AccessMesadata>, at: Point) {
if let None | Some(None) = self.reselect_bbox {
// handle bounding box selection
self.reselect_bbox = Some(Some(at));
}
}
pub fn drag_stop(&mut self, board: &Board<impl AccessMesadata>, at: Point) {
if let Some(aabb) = self.get_bbox_reselect(at) {
// handle bounding box selection
self.selected_bbox = aabb;
self.reselect_bbox = None;
}
}
pub fn click(&mut self, board: &Board<impl AccessMesadata>, at: Point) {
if let Some(rsbb) = self.reselect_bbox.take() {
// handle bounding box selection (takes precendence over other interactions)
use rstar::Point;
self.reselect_bbox = match rsbb {
None => Some(Some(at)),
Some(pt) => {

View File

@ -51,11 +51,13 @@ impl Viewport {
ui.ctx().request_repaint();
let (id, viewport_rect) = ui.allocate_space(ui.available_size());
let response = ui.interact(viewport_rect, id, egui::Sense::click());
let response = ui.interact(viewport_rect, id, egui::Sense::click_and_drag());
// NOTE: we use `interact_pos` instead of `latest_pos` to handle "pointer gone"
// events more graceful
let latest_pos = self.transform.inverse()
* (ctx.input(|i| i.pointer.interact_pos().unwrap_or_default()));
* (response.interact_pointer_pos().unwrap_or_else(|| {
ctx.input(|i| i.pointer.interact_pos().unwrap_or_default())
}));
let old_scaling = self.transform.scaling;
self.transform.scaling *= ctx.input(|i| i.zoom_delta());
@ -70,6 +72,7 @@ impl Viewport {
let layers = &mut workspace.appearance_panel;
let overlay = &mut workspace.overlay;
let latest_point = point! {x: latest_pos.x as f64, y: -latest_pos.y as f64};
let board = workspace.interactor.invoker().autorouter().board();
if response.clicked() {
if menu_bar.is_placing_via {
@ -87,11 +90,12 @@ impl Viewport {
maybe_net: Some(1234),
}));
} else {
overlay.click(
workspace.interactor.invoker().autorouter().board(),
latest_point,
);
overlay.click(board, latest_point);
}
} else if response.drag_started() {
overlay.drag_start(board, latest_point);
} else if response.drag_stopped() {
overlay.drag_stop(board, latest_point);
} else if let Some(cur_bbox) = overlay.get_bbox_reselect(latest_point) {
painter.paint_bbox_with_color(cur_bbox, egui::Color32::RED);
}