diff --git a/topola-egui/src/viewport.rs b/topola-egui/src/viewport.rs index 6864127..d8986ea 100644 --- a/topola-egui/src/viewport.rs +++ b/topola-egui/src/viewport.rs @@ -91,6 +91,40 @@ impl Viewport { workspace.appearance_panel.active, InteractiveInput::new(pointer_on_scene, false, false, false), ); + + if let Some(selection_interactor) = + interactor.selection_interactor().as_ref() + { + let origin = *selection_interactor.origin(); + let drag_rect_scene = egui::Rect::from_min_max( + egui::pos2( + origin.x.min(pointer_on_scene.x) as f32, + origin.y.min(pointer_on_scene.y) as f32, + ), + egui::pos2( + origin.x.max(pointer_on_scene.x) as f32, + origin.y.max(pointer_on_scene.y) as f32, + ), + ); + + let drag_rect_on_viewport = egui::Rect::from_min_max( + scene_to_viewport * drag_rect_scene.min, + scene_to_viewport * drag_rect_scene.max, + ); + let boundary_color = if pointer_on_scene.x >= origin.x { + egui::Color32::YELLOW + } else { + egui::Color32::from_rgb(80, 160, 255) + }; + + ui.painter().rect( + drag_rect_on_viewport, + egui::CornerRadius::ZERO, + egui::Color32::from_rgba_unmultiplied(80, 160, 255, 48), + egui::Stroke::new(1.5, boundary_color), + egui::StrokeKind::Outside, + ); + } } } } diff --git a/topola/src/board/interactors/drag_selection.rs b/topola/src/board/interactors/drag_selection.rs index b5de923..d1f7b82 100644 --- a/topola/src/board/interactors/drag_selection.rs +++ b/topola/src/board/interactors/drag_selection.rs @@ -13,6 +13,7 @@ use crate::{ interactors::{InteractiveInput, SelectionCombineMode, SelectionContainMode}, selections::PersistableSelection, }, + layout::LayerId, }; #[derive(Clone, Constructor, Debug, Deserialize, Eq, PartialEq, Serialize)] @@ -24,6 +25,7 @@ pub struct DragSelectionOptions { #[derive(Clone, Debug, Eq, Getters, PartialEq)] pub struct DragSelectionInteractor { origin: Vector2, + layer: LayerId, original_selection: PersistableSelection, selection: PersistableSelection, options: DragSelectionOptions, @@ -32,11 +34,13 @@ pub struct DragSelectionInteractor { impl DragSelectionInteractor { pub fn new( origin: Vector2, + layer: LayerId, original_selection: PersistableSelection, options: DragSelectionOptions, ) -> Self { Self { origin, + layer, original_selection, selection: PersistableSelection::new(), options, @@ -51,45 +55,43 @@ impl DragSelectionInteractor { self.selection = PersistableSelection::new(); - for layer_index in 0..*board.layout().layer_count() { - let rect = Rect3::new( - Vector3::new(self.origin.x, self.origin.y, layer_index as i64), - Vector3::new(input.pointer.x, input.pointer.y, layer_index as i64), - ); + let rect = Rect3::new( + Vector3::new(self.origin.x, self.origin.y, self.layer.index() as i64), + Vector3::new(input.pointer.x, input.pointer.y, self.layer.index() as i64), + ); - match self.options.contain { - SelectionContainMode::Crossing => { - self.selection - .components - .add(board.locate_components_intersecting_rect(rect)); - } - SelectionContainMode::Window => { - self.selection - .components - .add(board.locate_components_inside_rect(rect)); - } + match self.options.contain { + SelectionContainMode::Crossing => { + self.selection + .components + .add(board.locate_components_intersecting_rect(rect)); } - - match self.options.contain { - SelectionContainMode::Crossing => { - self.selection - .nets - .add(board.locate_nets_intersecting_rect(rect)); - } - SelectionContainMode::Window => { - self.selection.nets.add(board.locate_nets_inside_rect(rect)); - } + SelectionContainMode::Window => { + self.selection + .components + .add(board.locate_components_inside_rect(rect)); } + } - match self.options.contain { - SelectionContainMode::Crossing => { - self.selection - .pins - .add(board.locate_pins_intersecting_rect(rect)); - } - SelectionContainMode::Window => { - self.selection.pins.add(board.locate_pins_inside_rect(rect)); - } + match self.options.contain { + SelectionContainMode::Crossing => { + self.selection + .nets + .add(board.locate_nets_intersecting_rect(rect)); + } + SelectionContainMode::Window => { + self.selection.nets.add(board.locate_nets_inside_rect(rect)); + } + } + + match self.options.contain { + SelectionContainMode::Crossing => { + self.selection + .pins + .add(board.locate_pins_intersecting_rect(rect)); + } + SelectionContainMode::Window => { + self.selection.pins.add(board.locate_pins_inside_rect(rect)); } } diff --git a/topola/src/board/interactors/selection.rs b/topola/src/board/interactors/selection.rs index 4fe6aa9..20cc315 100644 --- a/topola/src/board/interactors/selection.rs +++ b/topola/src/board/interactors/selection.rs @@ -82,8 +82,13 @@ impl SelectionInteractor { }; let options = DragSelectionOptions::new(self.combine.clone(), contain); - let mut drag_selection_interactor = - DragSelectionInteractor::new(self.origin, self.original_selection.clone(), options); + let mut drag_selection_interactor = DragSelectionInteractor::new( + self.origin, + layer, + self.original_selection.clone(), + options, + ); + drag_selection_interactor.update(board, input); self.selection = drag_selection_interactor.selection().clone(); }