Add persisted per-view port anchors and connection-aware border placement

This commit is contained in:
2026-09-06 01:20:28 +03:00
parent 93fd32c684
commit 35133de650
13 changed files with 1435 additions and 149 deletions
+49
View File
@@ -44,6 +44,16 @@ pub enum Command {
diagram: Id,
edge: Id,
},
SetPortAnchor {
diagram: Id,
node: Id,
anchor: PortAnchor,
},
RemovePortAnchor {
diagram: Id,
node: Id,
port: Id,
},
RelocateNode {
node: Id,
diagram: Id,
@@ -679,6 +689,45 @@ fn apply_command(
.ok_or_else(missing)? = value.clone();
Some(*owner)
}
Command::SetPortAnchor {
diagram,
node,
anchor,
} => {
let n = p
.diagrams
.get_mut(diagram)
.and_then(|d| d.nodes.get_mut(node))
.ok_or_else(missing)?;
if let Some(existing) = n.port_anchors.iter_mut().find(|a| a.port == anchor.port) {
*existing = anchor.clone();
} else {
n.port_anchors.push(anchor.clone());
}
Some(anchor.port)
}
Command::RemovePortAnchor {
diagram,
node,
port,
} => {
let n = p
.diagrams
.get_mut(diagram)
.and_then(|d| d.nodes.get_mut(node))
.ok_or_else(missing)?;
if !p
.elements
.get(port)
.is_some_and(|e| e.kind() == Kind::Port && e.parent == Some(n.element))
{
return Err(ModelError(
"Port positioning requires a direct child port of the owner placement.".into(),
));
}
n.port_anchors.retain(|anchor| anchor.port != *port);
Some(*port)
}
Command::SetEdgeRoute { diagram, route } => {
let d = p.diagrams.get_mut(diagram).ok_or_else(missing)?;
if let Some(existing) = d.routes.iter_mut().find(|r| r.edge == route.edge) {