Support state relation row removal and verify F2 at widget focus boundary
This commit is contained in:
@@ -402,6 +402,48 @@ fn state_action_rows<'a>(
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// Action and internal-transition rows are selectable relations, not edges or
|
||||
/// placements. Match the exact rows rendered in this dedicated machine view.
|
||||
pub(crate) fn visible_row_relation(
|
||||
project: &Project,
|
||||
diagram: Id,
|
||||
view: &ProjectedView,
|
||||
id: Id,
|
||||
) -> bool {
|
||||
let Some(machine) = project
|
||||
.diagrams
|
||||
.get(&diagram)
|
||||
.and_then(|d| d.projection.state_machine())
|
||||
else {
|
||||
return false;
|
||||
};
|
||||
let Some(relation) = project.relations.get(&id) else {
|
||||
return false;
|
||||
};
|
||||
let source = match relation.body {
|
||||
RelationBody::StateAction { source, .. } => source,
|
||||
RelationBody::StateTransition {
|
||||
source,
|
||||
target,
|
||||
transition_kind: TransitionKind::Internal,
|
||||
..
|
||||
} if projection::state_machine_contains(project, machine, target) => source,
|
||||
_ => return false,
|
||||
};
|
||||
if !projection::state_machine_contains(project, machine, source) {
|
||||
return false;
|
||||
}
|
||||
view.nodes
|
||||
.iter()
|
||||
.filter(|node| node.element == source)
|
||||
.any(|node| {
|
||||
state_action_rows(project, node)
|
||||
.into_iter()
|
||||
.chain(internal_rows(project, node))
|
||||
.any(|(row, _)| row.id == id)
|
||||
})
|
||||
}
|
||||
|
||||
fn state_action_label(project: &Project, relation: &Relation) -> String {
|
||||
let RelationBody::StateAction { target, phase, .. } = relation.body else {
|
||||
return String::new();
|
||||
@@ -798,7 +840,10 @@ impl canvas::Program<Event> for StateCanvas<'_> {
|
||||
.iter()
|
||||
.find(|node| node.element == self.selected || node.id == self.selected);
|
||||
let object = placement.map_or(self.selected, |node| node.element);
|
||||
if placement.is_none() && !scene.view.edges.iter().any(|edge| edge.id == object) {
|
||||
if placement.is_none()
|
||||
&& !scene.view.edges.iter().any(|edge| edge.id == object)
|
||||
&& !visible_row_relation(self.project, self.diagram, &scene.view, object)
|
||||
{
|
||||
return None;
|
||||
}
|
||||
return Some(
|
||||
|
||||
@@ -194,7 +194,13 @@ pub fn popup(app: &App, opened: &Opened, clean: bool) -> Option<Menu<Message>> {
|
||||
|| projection::project_view(project, context.diagram)
|
||||
.edges
|
||||
.iter()
|
||||
.any(|edge| edge.id == id))
|
||||
.any(|edge| edge.id == id)
|
||||
|| super::state_canvas::visible_row_relation(
|
||||
project,
|
||||
context.diagram,
|
||||
&projection::project_view(project, context.diagram),
|
||||
id,
|
||||
))
|
||||
}) {
|
||||
if request.placement.is_some() {
|
||||
"Shift+Delete"
|
||||
|
||||
Reference in New Issue
Block a user