Resolve diagram Delete target after placement properties selection

This commit is contained in:
2026-09-12 05:04:09 -07:00
parent 5b174a9fa6
commit dc1506f2e8
3 changed files with 96 additions and 6 deletions
+14 -4
View File
@@ -43,7 +43,13 @@ impl App {
}
_ => None,
};
if current != Some(intent.context) || self.selected != intent.object {
let selected_object = self
.project()
.diagrams
.get(&intent.context.diagram)
.and_then(|diagram| diagram.nodes.get(&self.selected))
.map_or(self.selected, |node| node.element);
if current != Some(intent.context) || selected_object != intent.object {
return;
}
let view = projection::project_view(self.project(), intent.context.diagram);
@@ -81,15 +87,19 @@ impl App {
self.status = "Hidden from this diagram · Model element preserved · Undo restores the placement".into();
}
} else {
self.begin_model_delete(Some(intent.context));
self.begin_model_delete_target(intent.object, Some(intent.context));
}
}
pub(super) fn begin_model_delete(&mut self, canvas: Option<Context>) {
if self.selected == self.project().id || self.behavior.has_pending() {
self.begin_model_delete_target(self.selected, canvas);
}
fn begin_model_delete_target(&mut self, object: Id, canvas: Option<Context>) {
if object == self.project().id || self.behavior.has_pending() {
return;
}
let mut request = model_menu::Request::object(self.selected, iced::Point::ORIGIN);
let mut request = model_menu::Request::object(object, iced::Point::ORIGIN);
request.canvas = canvas;
request.placement = if self.page == Page::Behavior {
self.behavior.diagram.placement
@@ -205,6 +205,86 @@ async fn mounted_shift_delete_captures_target_cancel_escape_and_confirmation_rep
}
struct FocusField(Rectangle);
#[tokio::test]
async fn mounted_placement_properties_selection_supports_hide_and_model_delete() {
for layer in [Layer::Oa, Layer::Sa] {
for model in [false, true] {
let (mut f, mut mounted) = mount(layer).await;
let before = f.app.document.snapshot();
let mut request = crate::model_menu::Request::object(f.object, Point::ORIGIN);
request.placement = Some(f.node);
request.canvas = f.app.route_context();
let task = f
.app
.update(Message::Menu(crate::model_menu::Event::Open(request)));
mounted.perform(&mut f.app, task).await;
let action = crate::model_menu::popup(&f.app)
.unwrap()
.entries
.into_iter()
.find_map(|entry| match entry {
crate::context_menu::Entry::Action { label, message, .. }
if label == "Placement properties" =>
{
message
}
_ => None,
})
.unwrap();
let task = f.app.update(action);
mounted.perform(&mut f.app, task).await;
assert_eq!(f.app.selected, f.node);
assert_eq!(f.app.selected_node, Some(f.node));
let bounds = mounted
.geometry(&f.app)
.bounds(crate::allocation_input::CANVAS_ID);
mounted
.click(&mut f.app, Point::new(bounds.x + 20., bounds.y + 20.))
.await;
assert_eq!(
f.app.selected, f.node,
"blank canvas preserves placement selection"
);
delete(&mut mounted, &mut f.app, model).await;
if model {
let target = f
.app
.delete_target
.as_ref()
.expect("model confirmation opens");
assert_eq!(target.snapshot.request.object, f.object);
assert_eq!(target.selection, f.node);
let token = target.snapshot.token;
let task = f.app.update(Message::ConfirmDelete(token));
mounted.perform(&mut f.app, task).await;
assert!(!f.app.project().contains(f.object));
assert!(
!f.app.project().diagrams[&f.copy]
.nodes
.values()
.any(|n| n.element == f.object)
);
} else {
assert!(f.app.project().contains(f.object));
assert!(!f.app.project().contains(f.node));
assert!(
f.app.project().diagrams[&f.copy]
.nodes
.values()
.any(|n| n.element == f.object)
);
}
consistent(&f.app);
let task = f.app.update(Message::Undo);
mounted.perform(&mut f.app, task).await;
assert_eq!(f.app.document.bundle(), &before.bundle);
assert_eq!(f.app.project(), &before.decoded.project);
assert!(!f.app.document.can_undo());
}
}
}
impl Operation for FocusField {
fn traverse(&mut self, visit: &mut dyn FnMut(&mut dyn Operation)) {
visit(self);