Rearrange and rename selections and compounds

This commit is contained in:
Mikolaj Wielgus 2026-05-19 12:43:09 +02:00
parent e536e94039
commit 25efbd1627
11 changed files with 129 additions and 58 deletions

View File

@ -3,7 +3,7 @@
// SPDX-License-Identifier: MIT OR Apache-2.0 // SPDX-License-Identifier: MIT OR Apache-2.0
use crate::{viewport::Viewport, workspace::Workspace}; use crate::{viewport::Viewport, workspace::Workspace};
use topola::{Joint, Polygon, Segment}; use topola::primitives::{Joint, Polygon, Segment};
pub struct Display {} pub struct Display {}
@ -53,7 +53,10 @@ impl Display {
workspace.appearance_panel.layer_color( workspace.appearance_panel.layer_color(
ctx, ctx,
board.layer_name(joint.spec.layer), board.layer_name(joint.spec.layer),
board.pin_selection_contains_joint(&workspace.pin_selection, joint_id), board.pin_with_layer_selection_contains_joint(
&workspace.selection.pins,
joint_id,
),
), ),
); );
} }
@ -68,7 +71,10 @@ impl Display {
workspace.appearance_panel.layer_color( workspace.appearance_panel.layer_color(
ctx, ctx,
board.layer_name(segment.layer), board.layer_name(segment.layer),
board.pin_selection_contains_segment(&workspace.pin_selection, segment_id), board.pin_with_layer_selection_contains_segment(
&workspace.selection.pins,
segment_id,
),
), ),
); );
} }
@ -85,7 +91,10 @@ impl Display {
workspace.appearance_panel.layer_color( workspace.appearance_panel.layer_color(
ctx, ctx,
board.layer_name(polygon.layer), board.layer_name(polygon.layer),
board.pin_selection_contains_polygon(&workspace.pin_selection, polygon_id), board.pin_with_layer_selection_contains_polygon(
&workspace.selection.pins,
polygon_id,
),
), ),
); );
} }

View File

@ -58,7 +58,7 @@ impl Viewport {
.router() .router()
.navmesher_board() .navmesher_board()
.board() .board()
.point_pin_selector( .point_pin_with_layer_selector(
0, 0,
Vector2::new( Vector2::new(
pointer_scene_pos.x as i64, pointer_scene_pos.x as i64,
@ -66,7 +66,7 @@ impl Viewport {
), ),
) )
{ {
workspace.pin_selection.toggle(pin_selector); workspace.selection.pins.toggle(pin_selector);
} }
} }
} }

View File

@ -2,14 +2,14 @@
// //
// SPDX-License-Identifier: MIT OR Apache-2.0 // SPDX-License-Identifier: MIT OR Apache-2.0
use topola::{Autorouter, Board, PinSelection}; use topola::{Autorouter, Board, selections::PersistableSelection};
use crate::{appearance_panel::AppearancePanel, translator::Translator}; use crate::{appearance_panel::AppearancePanel, translator::Translator};
pub struct Workspace { pub struct Workspace {
pub autorouter: Autorouter, pub autorouter: Autorouter,
pub appearance_panel: AppearancePanel, pub appearance_panel: AppearancePanel,
pub pin_selection: PinSelection, pub selection: PersistableSelection,
} }
impl Workspace { impl Workspace {
@ -19,7 +19,7 @@ impl Workspace {
Self { Self {
autorouter: Autorouter::new(board), autorouter: Autorouter::new(board),
appearance_panel, appearance_panel,
pin_selection: PinSelection::new(), selection: PersistableSelection::new(),
} }
} }

View File

@ -14,7 +14,7 @@ use crate::{
JointId, JointSpec, Polygon, PolygonId, Segment, SegmentId, SegmentSpec, Via, ViaId, JointId, JointSpec, Polygon, PolygonId, Segment, SegmentId, SegmentSpec, Via, ViaId,
ViaSpec, ViaSpec,
}, },
selection::{PinSelection, PinSelector}, selections::{ComponentSelector, PinWithLayerSelection, PinWithLayerSelector},
}; };
#[derive(Clone, Debug, Getters)] #[derive(Clone, Debug, Getters)]
@ -91,19 +91,19 @@ impl Board {
self.layout.add_polygon(polygon) self.layout.add_polygon(polygon)
} }
pub fn joint_pin_selector(&self, joint_id: JointId) -> Option<PinSelector> { pub fn joint_pin_with_layer_selector(&self, id: JointId) -> Option<PinWithLayerSelector> {
let joint = self.layout.joint(joint_id); let joint = self.layout.joint(id);
Some(PinSelector { Some(PinWithLayerSelector {
pin: self.pin_name(joint.spec.pin?)?.to_string(), pin: self.pin_name(joint.spec.pin?)?.to_string(),
layer: self.layer_name(joint.spec.layer)?.to_string(), layer: self.layer_name(joint.spec.layer)?.to_string(),
}) })
} }
pub fn segment_pin_selector(&self, segment_id: SegmentId) -> Option<PinSelector> { pub fn segment_pin_with_layer_selector(&self, id: SegmentId) -> Option<PinWithLayerSelector> {
let segment = self.layout.segment(segment_id); let segment = self.layout.segment(id);
Some(PinSelector { Some(PinWithLayerSelector {
pin: self.pin_name(segment.spec.pin?)?.to_string(), pin: self.pin_name(segment.spec.pin?)?.to_string(),
layer: self.layer_name(segment.layer)?.to_string(), layer: self.layer_name(segment.layer)?.to_string(),
}) })
@ -111,69 +111,73 @@ impl Board {
// TODO: Vias. // TODO: Vias.
pub fn polygon_pin_selector(&self, polygon_id: PolygonId) -> Option<PinSelector> { pub fn polygon_pin_with_layer_selector(&self, id: PolygonId) -> Option<PinWithLayerSelector> {
let polygon = self.layout.polygon(polygon_id); let polygon = self.layout.polygon(id);
Some(PinSelector { Some(PinWithLayerSelector {
pin: self.pin_name(polygon.pin?)?.to_string(), pin: self.pin_name(polygon.pin?)?.to_string(),
layer: self.layer_name(polygon.layer)?.to_string(), layer: self.layer_name(polygon.layer)?.to_string(),
}) })
} }
pub fn point_pin_selector(&self, layer: usize, point: Vector2<i64>) -> Option<PinSelector> { pub fn point_pin_with_layer_selector(
&self,
layer: usize,
point: Vector2<i64>,
) -> Option<PinWithLayerSelector> {
if let Some(joint_id) = self.layout.locate_joints_at_point(layer, point).next() { if let Some(joint_id) = self.layout.locate_joints_at_point(layer, point).next() {
return self.joint_pin_selector(joint_id); return self.joint_pin_with_layer_selector(joint_id);
} }
if let Some(segment_id) = self.layout.locate_segments_at_point(layer, point).next() { if let Some(segment_id) = self.layout.locate_segments_at_point(layer, point).next() {
return self.segment_pin_selector(segment_id); return self.segment_pin_with_layer_selector(segment_id);
} }
// TODO: Vias. // TODO: Vias.
if let Some(polygon_id) = self.layout.locate_polygons_at_point(layer, point).next() { if let Some(polygon_id) = self.layout.locate_polygons_at_point(layer, point).next() {
return self.polygon_pin_selector(polygon_id); return self.polygon_pin_with_layer_selector(polygon_id);
} }
None None
} }
pub fn pin_selection_contains_joint( pub fn pin_with_layer_selection_contains_joint(
&self, &self,
pin_selection: &PinSelection, selection: &PinWithLayerSelection,
joint_id: JointId, id: JointId,
) -> bool { ) -> bool {
let Some(pin_selector) = self.joint_pin_selector(joint_id) else { let Some(pin_selector) = self.joint_pin_with_layer_selector(id) else {
return false; return false;
}; };
pin_selection.0.contains(&pin_selector) selection.0.contains(&pin_selector)
} }
pub fn pin_selection_contains_segment( pub fn pin_with_layer_selection_contains_segment(
&self, &self,
pin_selection: &PinSelection, selection: &PinWithLayerSelection,
segment_id: SegmentId, id: SegmentId,
) -> bool { ) -> bool {
let Some(pin_selector) = self.segment_pin_selector(segment_id) else { let Some(pin_selector) = self.segment_pin_with_layer_selector(id) else {
return false; return false;
}; };
pin_selection.0.contains(&pin_selector) selection.0.contains(&pin_selector)
} }
// TODO: Vias. // TODO: Vias.
pub fn pin_selection_contains_polygon( pub fn pin_with_layer_selection_contains_polygon(
&self, &self,
pin_selection: &PinSelection, selection: &PinWithLayerSelection,
polygon_id: PolygonId, id: PolygonId,
) -> bool { ) -> bool {
let Some(pin_selector) = self.polygon_pin_selector(polygon_id) else { let Some(pin_selector) = self.polygon_pin_with_layer_selector(id) else {
return false; return false;
}; };
pin_selection.0.contains(&pin_selector) selection.0.contains(&pin_selector)
} }
pub fn pin_name(&self, pin: PinId) -> Option<&str> { pub fn pin_name(&self, pin: PinId) -> Option<&str> {

View File

@ -6,6 +6,6 @@ mod component;
mod net; mod net;
mod pin; mod pin;
pub use component::{Component, ComponentId}; pub use component::*;
pub use net::NetId; pub use net::*;
pub use pin::{Pin, PinId}; pub use pin::*;

View File

@ -10,10 +10,10 @@ mod layout;
mod math; mod math;
mod navmesher; mod navmesher;
mod pathfinder; mod pathfinder;
mod primitives; pub mod primitives;
mod ratsnest; mod ratsnest;
mod router; mod router;
mod selection; pub mod selections;
mod specctra; mod specctra;
pub use crate::autorouter::Autorouter; pub use crate::autorouter::Autorouter;
@ -21,8 +21,4 @@ pub use crate::board::Board;
pub use crate::compounds::{Pin, PinId}; pub use crate::compounds::{Pin, PinId};
pub use crate::layout::Layout; pub use crate::layout::Layout;
pub use crate::math::Vector2; pub use crate::math::Vector2;
pub use crate::primitives::{
Joint, JointId, Polygon, PolygonId, PrimitiveId, Segment, SegmentId, Via, ViaId,
};
pub use crate::ratsnest::{Ratline, Ratsnest}; pub use crate::ratsnest::{Ratline, Ratsnest};
pub use crate::selection::{PinSelection, PinSelector};

View File

@ -9,10 +9,10 @@ mod polygon;
mod segment; mod segment;
mod via; mod via;
pub use joint::{Joint, JointId, JointSpec}; pub use joint::*;
pub use polygon::{Polygon, PolygonId}; pub use polygon::*;
pub use segment::{Segment, SegmentId, SegmentSpec}; pub use segment::*;
pub use via::{Via, ViaId, ViaSpec}; pub use via::*;
#[derive(Clone, Copy, Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize)] #[derive(Clone, Copy, Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize)]
pub enum PrimitiveId { pub enum PrimitiveId {

View File

@ -0,0 +1,29 @@
// SPDX-FileCopyrightText: 2026 Topola contributors
//
// SPDX-License-Identifier: MIT OR Apache-2.0
use std::collections::BTreeSet;
use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize)]
pub struct ComponentSelector {
pub component: String,
}
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub struct ComponentSelection(pub BTreeSet<ComponentSelector>);
impl ComponentSelection {
pub fn new() -> Self {
Self(BTreeSet::new())
}
pub fn toggle(&mut self, selector: ComponentSelector) {
if self.0.contains(&selector) {
self.0.remove(&selector);
} else {
self.0.insert(selector);
}
}
}

View File

@ -0,0 +1,11 @@
// SPDX-FileCopyrightText: 2026 Topola contributors
//
// SPDX-License-Identifier: MIT OR Apache-2.0
mod component;
mod persistable;
mod pin_with_layer;
pub use component::*;
pub use persistable::*;
pub use pin_with_layer::*;

View File

@ -0,0 +1,22 @@
// SPDX-FileCopyrightText: 2026 Topola contributors
//
// SPDX-License-Identifier: MIT OR Apache-2.0
use serde::{Deserialize, Serialize};
use crate::selections::{ComponentSelection, PinWithLayerSelection};
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub struct PersistableSelection {
pub components: ComponentSelection,
pub pins: PinWithLayerSelection,
}
impl PersistableSelection {
pub fn new() -> Self {
Self {
components: ComponentSelection::new(),
pins: PinWithLayerSelection::new(),
}
}
}

View File

@ -7,24 +7,24 @@ use std::collections::BTreeSet;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize)] #[derive(Clone, Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize)]
pub struct PinSelector { pub struct PinWithLayerSelector {
pub pin: String, pub pin: String,
pub layer: String, pub layer: String,
} }
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] #[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub struct PinSelection(pub BTreeSet<PinSelector>); pub struct PinWithLayerSelection(pub BTreeSet<PinWithLayerSelector>);
impl PinSelection { impl PinWithLayerSelection {
pub fn new() -> Self { pub fn new() -> Self {
Self(BTreeSet::new()) Self(BTreeSet::new())
} }
pub fn toggle(&mut self, pin_selector: PinSelector) { pub fn toggle(&mut self, selector: PinWithLayerSelector) {
if self.0.contains(&pin_selector) { if self.0.contains(&selector) {
self.0.remove(&pin_selector); self.0.remove(&selector);
} else { } else {
self.0.insert(pin_selector); self.0.insert(selector);
} }
} }
} }