mirror of https://codeberg.org/topola/topola.git
egui,autorouter: implement selecting bands
This commit is contained in:
parent
5da6ec4463
commit
f7126dfa33
|
|
@ -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,15 +63,19 @@ 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) {
|
if self.contains_node(board, node) {
|
||||||
self.deselect(board, &selector);
|
self.deselect(board, &selector);
|
||||||
} else {
|
} else {
|
||||||
self.select(board, selector);
|
self.select(board, selector);
|
||||||
}
|
}
|
||||||
|
} else if let Some(band) = self.node_band(board, node) {
|
||||||
|
if self.contains_node(board, node) {
|
||||||
|
self.deselect_band(board, band);
|
||||||
|
} else {
|
||||||
|
self.select_band(board, band);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn select(&mut self, _board: &Board<impl AccessMesadata>, selector: Selector) {
|
fn select(&mut self, _board: &Board<impl AccessMesadata>, selector: Selector) {
|
||||||
|
|
@ -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(
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -70,15 +70,16 @@ 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 let Some(prev) = maybe_prev {
|
||||||
if bend.petgraph_index() != prev.petgraph_index() {
|
if bend.petgraph_index() != prev.petgraph_index() {
|
||||||
Some(bend.into())
|
Some(bend.into())
|
||||||
} else {
|
} else {
|
||||||
self.seg().map(Into::into)
|
self.seg().map(Into::into)
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
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 let Some(prev) = maybe_prev {
|
||||||
if joints.0.petgraph_index() != prev.petgraph_index() {
|
if joints.0.petgraph_index() != prev.petgraph_index() {
|
||||||
Some(joints.0.into())
|
Some(joints.0.into())
|
||||||
} else {
|
} else {
|
||||||
Some(joints.1.into())
|
Some(joints.1.into())
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
Some(joints.0.into())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue