egui,autorouter: implement selecting bands

This commit is contained in:
Mikolaj Wielgus 2024-07-23 13:36:57 +02:00
parent 5da6ec4463
commit f7126dfa33
4 changed files with 79 additions and 24 deletions

View File

@ -4,7 +4,10 @@ use serde::{Deserialize, Serialize};
use crate::{ use crate::{
board::{mesadata::AccessMesadata, Board}, board::{mesadata::AccessMesadata, Board},
drawing::graph::{GetLayer, MakePrimitive}, drawing::{
band::BandUid,
graph::{GetLayer, MakePrimitive, PrimitiveIndex},
},
geometry::{compound::ManageCompounds, GenericNode}, geometry::{compound::ManageCompounds, GenericNode},
graph::{GenericIndex, GetPetgraphIndex}, graph::{GenericIndex, GetPetgraphIndex},
layout::{poly::PolyWeight, CompoundWeight, NodeIndex}, layout::{poly::PolyWeight, CompoundWeight, NodeIndex},
@ -19,12 +22,15 @@ pub struct Selector {
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Selection { pub struct Selection {
selectors: HashSet<Selector>, selectors: HashSet<Selector>,
#[serde(skip)]
selected_bands: HashSet<BandUid>,
} }
impl Selection { impl Selection {
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
selectors: HashSet::new(), selectors: HashSet::new(),
selected_bands: HashSet::new(),
} }
} }
@ -57,14 +63,18 @@ impl Selection {
} }
pub fn toggle_at_node(&mut self, board: &Board<impl AccessMesadata>, node: NodeIndex) { pub fn toggle_at_node(&mut self, board: &Board<impl AccessMesadata>, node: NodeIndex) {
let Some(selector) = self.node_selector(board, node) else { if let Some(selector) = self.node_selector(board, node) {
return; if self.contains_node(board, node) {
}; self.deselect(board, &selector);
} else {
if self.contains_node(board, node) { self.select(board, selector);
self.deselect(board, &selector); }
} else { } else if let Some(band) = self.node_band(board, node) {
self.select(board, selector); if self.contains_node(board, node) {
self.deselect_band(board, band);
} else {
self.select_band(board, band);
}
} }
} }
@ -76,12 +86,38 @@ impl Selection {
self.selectors.remove(selector); self.selectors.remove(selector);
} }
fn select_band(&mut self, board: &Board<impl AccessMesadata>, band: BandUid) {
self.selected_bands.insert(band);
}
fn deselect_band(&mut self, board: &Board<impl AccessMesadata>, band: BandUid) {
self.selected_bands.remove(&band);
}
pub fn contains_node(&self, board: &Board<impl AccessMesadata>, node: NodeIndex) -> bool { pub fn contains_node(&self, board: &Board<impl AccessMesadata>, node: NodeIndex) -> bool {
let Some(selector) = self.node_selector(board, node) else { if let Some(selector) = self.node_selector(board, node) {
return false; self.selectors.contains(&selector)
} else if let Some(band) = self.node_band(board, node) {
self.selected_bands.contains(&band)
} else {
false
}
}
fn node_band(&self, board: &Board<impl AccessMesadata>, node: NodeIndex) -> Option<BandUid> {
let NodeIndex::Primitive(primitive) = node else {
return None;
}; };
self.selectors.contains(&selector) let loose = match primitive {
PrimitiveIndex::LooseDot(dot) => dot.into(),
PrimitiveIndex::LoneLooseSeg(seg) => seg.into(),
PrimitiveIndex::SeqLooseSeg(seg) => seg.into(),
PrimitiveIndex::LooseBend(bend) => bend.into(),
_ => return None,
};
Some(board.layout().drawing().collect().loose_band_uid(loose))
} }
fn node_selector( fn node_selector(

View File

@ -28,6 +28,15 @@ impl BandUid {
} }
} }
impl PartialEq for BandUid {
fn eq(&self, other: &Self) -> bool {
self.0.petgraph_index() == other.0.petgraph_index()
&& self.1.petgraph_index() == other.1.petgraph_index()
}
}
impl Eq for BandUid {}
#[enum_dispatch(GetPetgraphIndex)] #[enum_dispatch(GetPetgraphIndex)]
#[derive(Debug, Hash, Clone, Copy)] #[derive(Debug, Hash, Clone, Copy)]
pub enum BandTerminatingSegIndex { pub enum BandTerminatingSegIndex {

View File

@ -29,6 +29,10 @@ impl<'a, CW: Copy, R: AccessRules> Collect<'a, CW, R> {
} }
fn loose_band_first_seg(&self, start_loose: LooseIndex) -> BandTerminatingSegIndex { fn loose_band_first_seg(&self, start_loose: LooseIndex) -> BandTerminatingSegIndex {
if let LooseIndex::LoneSeg(seg) = start_loose {
return BandTerminatingSegIndex::Straight(seg);
}
let mut loose = start_loose; let mut loose = start_loose;
let mut prev = None; let mut prev = None;
@ -43,6 +47,10 @@ impl<'a, CW: Copy, R: AccessRules> Collect<'a, CW, R> {
} }
fn loose_band_last_seg(&self, start_loose: LooseIndex) -> BandTerminatingSegIndex { fn loose_band_last_seg(&self, start_loose: LooseIndex) -> BandTerminatingSegIndex {
if let LooseIndex::LoneSeg(seg) = start_loose {
return BandTerminatingSegIndex::Straight(seg);
}
let mut loose = start_loose; let mut loose = start_loose;
let mut next = None; let mut next = None;

View File

@ -70,14 +70,15 @@ impl<'a, CW: Copy, R: AccessRules> Loose<'a, CW, R> {
impl<'a, CW: Copy, R: AccessRules> GetPrevNextLoose for LooseDot<'a, CW, R> { impl<'a, CW: Copy, R: AccessRules> GetPrevNextLoose for LooseDot<'a, CW, R> {
fn next_loose(&self, maybe_prev: Option<LooseIndex>) -> Option<LooseIndex> { fn next_loose(&self, maybe_prev: Option<LooseIndex>) -> Option<LooseIndex> {
let bend = self.bend(); let bend = self.bend();
let Some(prev) = maybe_prev else {
unreachable!();
};
if bend.petgraph_index() != prev.petgraph_index() { if let Some(prev) = maybe_prev {
Some(bend.into()) if bend.petgraph_index() != prev.petgraph_index() {
Some(bend.into())
} else {
self.seg().map(Into::into)
}
} else { } else {
self.seg().map(Into::into) Some(bend.into())
} }
} }
} }
@ -109,14 +110,15 @@ impl<'a, CW: Copy, R: AccessRules> GetPrevNextLoose for SeqLooseSeg<'a, CW, R> {
impl<'a, CW: Copy, R: AccessRules> GetPrevNextLoose for LooseBend<'a, CW, R> { impl<'a, CW: Copy, R: AccessRules> GetPrevNextLoose for LooseBend<'a, CW, R> {
fn next_loose(&self, maybe_prev: Option<LooseIndex>) -> Option<LooseIndex> { fn next_loose(&self, maybe_prev: Option<LooseIndex>) -> Option<LooseIndex> {
let joints = self.joints(); let joints = self.joints();
let Some(prev) = maybe_prev else {
unreachable!();
};
if joints.0.petgraph_index() != prev.petgraph_index() { if let Some(prev) = maybe_prev {
Some(joints.0.into()) if joints.0.petgraph_index() != prev.petgraph_index() {
Some(joints.0.into())
} else {
Some(joints.1.into())
}
} else { } else {
Some(joints.1.into()) Some(joints.0.into())
} }
} }
} }