mirror of https://codeberg.org/topola/topola.git
Add master interactor to rule all interactors (WIP, not used yet)
This commit is contained in:
parent
623dc967ca
commit
da7585b135
|
|
@ -85,7 +85,7 @@ impl Viewport {
|
|||
let _ = interactor.update(
|
||||
workspace.autorouter.router().navmesher_board().board(),
|
||||
workspace.appearance_panel.active,
|
||||
InteractiveInput::new(pointer_on_scene, false, false),
|
||||
InteractiveInput::new(pointer_on_scene, false, false, false),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -98,7 +98,7 @@ impl Viewport {
|
|||
let _ = interactor.update(
|
||||
workspace.autorouter.router().navmesher_board().board(),
|
||||
workspace.appearance_panel.active,
|
||||
InteractiveInput::new(pointer_for_scene, true, false),
|
||||
InteractiveInput::new(pointer_for_scene, true, false, false),
|
||||
);
|
||||
|
||||
workspace.selection = interactor.selection().clone();
|
||||
|
|
|
|||
|
|
@ -1,26 +0,0 @@
|
|||
// SPDX-FileCopyrightText: 2026 Topola contributors
|
||||
//
|
||||
// SPDX-License-Identifier: MIT OR Apache-2.0
|
||||
|
||||
use crate::{
|
||||
board::Board,
|
||||
primitives::{JointId, PolygonId, SegmentId, ViaId},
|
||||
};
|
||||
|
||||
impl Board {
|
||||
pub fn delete_joint(&mut self, joint_id: JointId) {
|
||||
self.layout.delete_joint(joint_id);
|
||||
}
|
||||
|
||||
pub fn delete_segment(&mut self, segment_id: SegmentId) {
|
||||
self.layout.delete_segment(segment_id);
|
||||
}
|
||||
|
||||
pub fn delete_via(&mut self, via_id: ViaId) {
|
||||
self.layout.delete_via(via_id);
|
||||
}
|
||||
|
||||
pub fn delete_polygon(&mut self, polygon_id: PolygonId) {
|
||||
self.layout.delete_polygon(polygon_id);
|
||||
}
|
||||
}
|
||||
|
|
@ -15,13 +15,13 @@ use crate::{
|
|||
},
|
||||
};
|
||||
|
||||
#[derive(Clone, Constructor, Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize)]
|
||||
#[derive(Clone, Constructor, Debug, Deserialize, Eq, PartialEq, Serialize)]
|
||||
pub struct DragSelectionOptions {
|
||||
combine: SelectionCombineMode,
|
||||
contain: SelectionContainMode,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, Getters, Ord, PartialEq, PartialOrd)]
|
||||
#[derive(Clone, Debug, Eq, Getters, PartialEq)]
|
||||
pub struct DragSelectionInteractor {
|
||||
origin: Vector2<i64>,
|
||||
original_selection: PersistableSelection,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,50 @@
|
|||
// SPDX-FileCopyrightText: 2026 Topola contributors
|
||||
//
|
||||
// SPDX-License-Identifier: MIT OR Apache-2.0
|
||||
|
||||
use derive_getters::Getters;
|
||||
use derive_more::Constructor;
|
||||
|
||||
use crate::{
|
||||
InteractiveInput,
|
||||
board::{
|
||||
Board,
|
||||
interactors::{SelectionCombineMode, SelectionInteractor},
|
||||
selections::PersistableSelection,
|
||||
},
|
||||
layout::LayerId,
|
||||
};
|
||||
|
||||
#[derive(Clone, Constructor, Debug, Eq, Getters, PartialEq)]
|
||||
pub struct MasterInteractor {
|
||||
selection: PersistableSelection,
|
||||
selection_interactor: Option<SelectionInteractor>,
|
||||
}
|
||||
|
||||
impl MasterInteractor {
|
||||
pub fn update(&mut self, board: &mut Board, input: InteractiveInput) {
|
||||
if input.delete {
|
||||
board.delete_net_free_primitives(self.selection.nets.clone());
|
||||
}
|
||||
|
||||
if self.selection_interactor.is_none() {
|
||||
self.selection_interactor = Some(SelectionInteractor::new(
|
||||
input.pointer,
|
||||
self.selection.clone(),
|
||||
SelectionCombineMode::Additive,
|
||||
));
|
||||
}
|
||||
|
||||
if let Some(selection_interactor) = self.selection_interactor.as_mut() {
|
||||
if let Some(selection) =
|
||||
selection_interactor.update(board, LayerId::new(0), input.clone())
|
||||
{
|
||||
self.selection = selection;
|
||||
}
|
||||
}
|
||||
|
||||
if input.release || input.cancel {
|
||||
self.selection_interactor = None;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3,31 +3,24 @@
|
|||
// SPDX-License-Identifier: MIT OR Apache-2.0
|
||||
|
||||
mod drag_selection;
|
||||
mod master;
|
||||
mod selection;
|
||||
|
||||
use derive_more::Constructor;
|
||||
pub use drag_selection::{DragSelectionInteractor, DragSelectionOptions};
|
||||
pub use selection::SelectionInteractor;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::Vector2;
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize)]
|
||||
#[derive(Clone, Constructor, Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize)]
|
||||
pub struct InteractiveInput {
|
||||
pointer: Vector2<i64>,
|
||||
released: bool,
|
||||
release: bool,
|
||||
delete: bool,
|
||||
cancel: bool,
|
||||
}
|
||||
|
||||
impl InteractiveInput {
|
||||
pub fn new(pointer: Vector2<i64>, released: bool, cancel: bool) -> Self {
|
||||
Self {
|
||||
pointer,
|
||||
released,
|
||||
cancel,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize)]
|
||||
pub enum SelectionCombineMode {
|
||||
Replace,
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ use crate::{
|
|||
layout::LayerId,
|
||||
};
|
||||
|
||||
#[derive(Clone, Debug, Eq, Getters, Ord, PartialEq, PartialOrd)]
|
||||
#[derive(Clone, Debug, Eq, Getters, PartialEq)]
|
||||
pub struct SelectionInteractor {
|
||||
origin: Vector2<i64>,
|
||||
original_selection: PersistableSelection,
|
||||
|
|
@ -50,7 +50,7 @@ impl SelectionInteractor {
|
|||
return Some(self.selection.clone());
|
||||
}
|
||||
|
||||
if input.released && input.pointer == self.origin {
|
||||
if input.release && input.pointer == self.origin {
|
||||
let mut selection = self.original_selection.clone();
|
||||
|
||||
// Pins have intentional precedence over nets and components.
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT OR Apache-2.0
|
||||
|
||||
mod delete;
|
||||
mod insert;
|
||||
pub mod interactors;
|
||||
mod layer;
|
||||
|
|
|
|||
|
|
@ -5,15 +5,91 @@
|
|||
use crate::{
|
||||
board::{Board, selections::ComponentSelection},
|
||||
layout::compounds::ComponentId,
|
||||
primitives::{JointId, PolygonId, SegmentId, ViaId},
|
||||
selections::NetSelection,
|
||||
};
|
||||
|
||||
impl Board {
|
||||
pub fn resolve_components(&self, selection: ComponentSelection) -> Vec<ComponentId> {
|
||||
pub fn resolve_components(
|
||||
&self,
|
||||
selection: ComponentSelection,
|
||||
) -> impl Iterator<Item = ComponentId> {
|
||||
selection
|
||||
.0
|
||||
.clone()
|
||||
.into_iter()
|
||||
.filter_map(|selector| self.component_id(&selector.component))
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn resolve_net_joints(&self, selection: NetSelection) -> impl Iterator<Item = JointId> {
|
||||
let mut resolved_joints = Vec::new();
|
||||
|
||||
for (index, _) in self.layout.joints().container() {
|
||||
let joint_id = JointId::new(index);
|
||||
|
||||
let Some(selector) = self.joint_net_selector(joint_id) else {
|
||||
continue;
|
||||
};
|
||||
|
||||
if selection.0.contains(&selector) {
|
||||
resolved_joints.push(joint_id);
|
||||
}
|
||||
}
|
||||
|
||||
resolved_joints.into_iter()
|
||||
}
|
||||
|
||||
pub fn resolve_net_segments(&self, selection: NetSelection) -> impl Iterator<Item = SegmentId> {
|
||||
let mut resolved_segments = Vec::new();
|
||||
|
||||
for (index, _) in self.layout.segments().container() {
|
||||
let segment_id = SegmentId::new(index);
|
||||
|
||||
let Some(selector) = self.segment_net_selector(segment_id) else {
|
||||
continue;
|
||||
};
|
||||
|
||||
if selection.0.contains(&selector) {
|
||||
resolved_segments.push(segment_id);
|
||||
}
|
||||
}
|
||||
|
||||
resolved_segments.into_iter()
|
||||
}
|
||||
|
||||
pub fn resolve_net_vias(&self, selection: NetSelection) -> impl Iterator<Item = ViaId> {
|
||||
let mut resolved_vias = Vec::new();
|
||||
|
||||
for (index, _) in self.layout.vias().container() {
|
||||
let via_id = ViaId::new(index);
|
||||
|
||||
let Some(selector) = self.via_net_selector(via_id) else {
|
||||
continue;
|
||||
};
|
||||
|
||||
if selection.0.contains(&selector) {
|
||||
resolved_vias.push(via_id);
|
||||
}
|
||||
}
|
||||
|
||||
resolved_vias.into_iter()
|
||||
}
|
||||
|
||||
pub fn resolve_net_polygons(&self, selection: NetSelection) -> impl Iterator<Item = PolygonId> {
|
||||
let mut resolved_polygons = Vec::new();
|
||||
|
||||
for (index, _) in self.layout.polygons().container() {
|
||||
let polygon_id = PolygonId::new(index);
|
||||
|
||||
let Some(selector) = self.polygon_net_selector(polygon_id) else {
|
||||
continue;
|
||||
};
|
||||
|
||||
if selection.0.contains(&selector) {
|
||||
resolved_polygons.push(polygon_id);
|
||||
}
|
||||
}
|
||||
|
||||
resolved_polygons.into_iter()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
use std::collections::BTreeSet;
|
||||
|
||||
use derive_more::Constructor;
|
||||
use derive_more::{Constructor, IntoIterator};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Clone, Constructor, Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize)]
|
||||
|
|
@ -12,7 +12,9 @@ pub struct ComponentSelector {
|
|||
pub component: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize)]
|
||||
#[derive(
|
||||
Clone, Debug, Default, Deserialize, Eq, IntoIterator, Ord, PartialEq, PartialOrd, Serialize,
|
||||
)]
|
||||
pub struct ComponentSelection(pub BTreeSet<ComponentSelector>);
|
||||
|
||||
impl ComponentSelection {
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
use std::collections::BTreeSet;
|
||||
|
||||
use derive_more::IntoIterator;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Clone, Debug, Default, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize)]
|
||||
|
|
@ -17,7 +18,9 @@ impl NetSelector {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize)]
|
||||
#[derive(
|
||||
Clone, Debug, Default, Deserialize, Eq, IntoIterator, Ord, PartialEq, PartialOrd, Serialize,
|
||||
)]
|
||||
pub struct NetSelection(pub BTreeSet<NetSelector>);
|
||||
|
||||
impl NetSelection {
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
use std::collections::BTreeSet;
|
||||
|
||||
use derive_more::Constructor;
|
||||
use derive_more::{Constructor, IntoIterator};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(
|
||||
|
|
@ -15,7 +15,9 @@ pub struct PinSelector {
|
|||
pub layer: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize)]
|
||||
#[derive(
|
||||
Clone, Debug, Default, Deserialize, Eq, IntoIterator, Ord, PartialEq, PartialOrd, Serialize,
|
||||
)]
|
||||
pub struct PinSelection(pub BTreeSet<PinSelector>);
|
||||
|
||||
impl PinSelection {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,41 @@
|
|||
// SPDX-FileCopyrightText: 2026 Topola contributors
|
||||
//
|
||||
// SPDX-License-Identifier: MIT OR Apache-2.0
|
||||
|
||||
use crate::{Board, selections::NetSelection};
|
||||
|
||||
impl Board {
|
||||
pub fn delete_net_free_primitives(&mut self, selection: NetSelection) {
|
||||
for joint_id in self
|
||||
.resolve_net_joints(selection.clone())
|
||||
.collect::<Vec<_>>()
|
||||
.clone()
|
||||
{
|
||||
self.layout.delete_joint(joint_id);
|
||||
}
|
||||
|
||||
for segment_id in self
|
||||
.resolve_net_segments(selection.clone())
|
||||
.collect::<Vec<_>>()
|
||||
.clone()
|
||||
{
|
||||
self.layout.delete_segment(segment_id);
|
||||
}
|
||||
|
||||
for via_id in self
|
||||
.resolve_net_vias(selection.clone())
|
||||
.collect::<Vec<_>>()
|
||||
.clone()
|
||||
{
|
||||
self.layout.delete_via(via_id);
|
||||
}
|
||||
|
||||
for polygon_id in self
|
||||
.resolve_net_polygons(selection.clone())
|
||||
.collect::<Vec<_>>()
|
||||
.clone()
|
||||
{
|
||||
self.layout.delete_polygon(polygon_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,4 +2,5 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT OR Apache-2.0
|
||||
|
||||
mod delete;
|
||||
mod move_by;
|
||||
|
|
|
|||
|
|
@ -5,12 +5,11 @@
|
|||
use crate::{Board, Vector2, layout::compounds::ComponentId, selections::ComponentSelection};
|
||||
|
||||
impl Board {
|
||||
pub fn move_components_by(
|
||||
&mut self,
|
||||
selection: &ComponentSelection,
|
||||
translation: Vector2<i64>,
|
||||
) {
|
||||
self.move_resolved_components_by(&self.resolve_components(selection.clone()), translation);
|
||||
pub fn move_components_by(&mut self, selection: ComponentSelection, translation: Vector2<i64>) {
|
||||
self.move_resolved_components_by(
|
||||
&self.resolve_components(selection).collect::<Vec<_>>(),
|
||||
translation,
|
||||
);
|
||||
}
|
||||
|
||||
pub fn move_resolved_components_by(
|
||||
|
|
|
|||
|
|
@ -9,8 +9,7 @@ use serde::{Deserialize, Serialize};
|
|||
use crate::layout::LayerId;
|
||||
use crate::layout::compounds::{ComponentId, NetId, PinId};
|
||||
use crate::math::Vector2;
|
||||
|
||||
use super::{SegmentId, ViaId};
|
||||
use crate::primitives::{SegmentId, ViaId};
|
||||
|
||||
#[derive(
|
||||
Clone,
|
||||
|
|
|
|||
|
|
@ -18,5 +18,6 @@ pub use via::*;
|
|||
pub enum PrimitiveId {
|
||||
Joint(JointId),
|
||||
Segment(SegmentId),
|
||||
Via(ViaId),
|
||||
Polygon(PolygonId),
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue