Support per-view connection boundary attachments in ordinary and state diagrams
This commit is contained in:
@@ -14,6 +14,9 @@ pub struct Context {
|
||||
pub enum Event {
|
||||
SelectBend(Id, usize),
|
||||
Commit(Context, EdgeRoute, Option<usize>),
|
||||
CommitAttachment(Context, EdgeRoute, EdgeEnd, Id),
|
||||
ChooseAttachment(EdgeEnd),
|
||||
ResetAttachment(EdgeEnd),
|
||||
AddBend,
|
||||
AddBendAt(oa_core::Position),
|
||||
RemoveBend,
|
||||
@@ -23,7 +26,14 @@ pub enum Event {
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum Handle {
|
||||
Bend(usize),
|
||||
Label { original: Position },
|
||||
Label {
|
||||
original: Position,
|
||||
},
|
||||
Attachment {
|
||||
end: EdgeEnd,
|
||||
owner: projection::ProjectedNode,
|
||||
original: Option<EdgeAttachment>,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
@@ -58,8 +68,57 @@ impl Gesture {
|
||||
};
|
||||
}
|
||||
}
|
||||
Handle::Attachment { .. } => {}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn move_attachment_to(&mut self, point: Point, zoom: f32) {
|
||||
let Handle::Attachment {
|
||||
end,
|
||||
ref owner,
|
||||
original,
|
||||
} = self.handle
|
||||
else {
|
||||
self.move_to(point, zoom);
|
||||
return;
|
||||
};
|
||||
if point.distance(self.start) * zoom < 3. {
|
||||
self.route.set_attachment(end, original);
|
||||
self.changed = false;
|
||||
return;
|
||||
}
|
||||
self.changed = true;
|
||||
let attachment = attachment_from_point(
|
||||
owner,
|
||||
position(point),
|
||||
self.route.attachment(end).map(|a| a.side),
|
||||
6. / zoom,
|
||||
);
|
||||
self.route.set_attachment(end, Some(attachment));
|
||||
}
|
||||
}
|
||||
|
||||
/// The painted endpoint must still be the actual unported placement, not a folded proxy.
|
||||
pub fn attachment_node<'a>(
|
||||
project: &Project,
|
||||
diagram: &Diagram,
|
||||
view: &'a projection::ProjectedView,
|
||||
edge: Id,
|
||||
end: EdgeEnd,
|
||||
) -> Option<&'a projection::ProjectedNode> {
|
||||
if semantic_port_endpoint(project, edge, end).is_some() {
|
||||
return None;
|
||||
}
|
||||
let projected = view.edges.iter().find(|e| e.id == edge)?;
|
||||
let actual = projection::edge_endpoint_placements(project, diagram, edge)?;
|
||||
if actual != (projected.source, projected.target) {
|
||||
return None;
|
||||
}
|
||||
let placement = match end {
|
||||
EdgeEnd::Source => projected.source,
|
||||
EdgeEnd::Target => projected.target,
|
||||
};
|
||||
view.nodes.iter().find(|node| node.id == placement)
|
||||
}
|
||||
|
||||
pub fn stored_route(diagram: &Diagram, edge: Id) -> EdgeRoute {
|
||||
@@ -72,6 +131,8 @@ pub fn stored_route(diagram: &Diagram, edge: Id) -> EdgeRoute {
|
||||
edge,
|
||||
waypoints: Vec::new(),
|
||||
label: None,
|
||||
source_attachment: None,
|
||||
target_attachment: None,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user