Compose reviewed attachments and State bends with saved Scenario

This commit is contained in:
2026-09-23 00:48:36 -07:00
parent 0b61771d07
commit a9b9c81eab
55 changed files with 5500 additions and 67 deletions
+84 -1
View File
@@ -501,6 +501,7 @@ pub struct App {
pub camera_epoch: u64,
camera_boundary_epoch: u64,
pub selected_bend: Option<(Id, usize)>,
pub selected_attachment: Option<(crate::route_edit::Context, Id, EdgeEnd)>,
pub exact_strings: bool,
pub document: Document,
pub page: Page,
@@ -622,6 +623,7 @@ impl App {
camera_epoch: 0,
camera_boundary_epoch: 0,
selected_bend: None,
selected_attachment: None,
exact_strings: false,
document,
page: Page::Diagram,
@@ -1145,6 +1147,9 @@ impl App {
previous != (self.layer, self.active_diagram)
}
fn select(&mut self, id: Id) {
if id != self.selected {
self.selected_attachment = None;
}
if self.selected == id {
return;
}
@@ -2582,6 +2587,15 @@ impl App {
} else if self.behavior.creation.has_pending() {
self.behavior.creation.acknowledge_commit();
self.status = "Behavior creation cancelled".into();
} else if self.page == Page::Behavior
&& matches!(
self.behavior.diagram.tool,
behavior::state_edit::Tool::AdjustAttachment { .. }
)
{
// Menu arming invalidates canvas keyboard ownership. Escape
// must also cancel before the next canvas click grants it.
self.behavior.diagram.tool = behavior::state_edit::Tool::Select;
}
if self.connection.take().is_some() {
self.status = "Drawing cancelled · Select / move is active".into();
@@ -4846,7 +4860,7 @@ impl App {
}
fn edit_route(&mut self, event: crate::route_edit::Event) {
use crate::route_edit::{Event, insert_pin, stored_route};
if self.connection.is_some() {
if self.connection.is_some() || self.page != Page::Diagram {
return;
}
let Some(context) = self.route_context() else {
@@ -4874,6 +4888,75 @@ impl App {
.filter(|(id, _)| *id == self.selected)
.map(|(_, i)| i);
let command = match event {
Event::ChooseAttachment(end) => {
if crate::route_edit::attachment_node(
self.project(),
diagram,
&view,
self.selected,
end,
)
.is_some()
{
self.selected_attachment = Some((context, self.selected, end));
self.selected_bend = None;
self.status = format!(
"Drag the {} attachment handle along its element boundary · Esc cancels",
if end == EdgeEnd::Source {
"source"
} else {
"target"
}
);
}
return;
}
Event::ResetAttachment(end) => {
if crate::route_edit::attachment_node(
self.project(),
diagram,
&view,
self.selected,
end,
)
.is_none()
|| route.attachment(end).is_none()
{
return;
}
route.set_attachment(end, None);
selected_bend = None;
Command::SetEdgeRoute {
diagram: context.diagram,
route,
}
}
Event::CommitAttachment(expected, changed, end, owner) => {
if expected != context
|| changed.edge != self.selected
|| crate::route_edit::attachment_node(
self.project(),
diagram,
&view,
self.selected,
end,
)
.is_none_or(|node| node.id != owner)
{
return;
}
// A boundary gesture owns exactly one presentation field.
let mut intended = route.clone();
intended.set_attachment(end, changed.attachment(end));
if changed != intended || intended == route {
return;
}
selected_bend = None;
Command::SetEdgeRoute {
diagram: context.diagram,
route: intended,
}
}
Event::SelectBend(id, index) => {
if id == self.selected && index < route.waypoints.len() {
self.selected_bend = Some((id, index));