Add exact Process selection and atomic column-slot group reorder
Preserve the full-desktop-1 captured source. Qualified previews inspect their exact subject read-only; group movement preserves source order and other columns. Native acceptance and strict-lint payload-size corrections follow separately.
This commit is contained in:
@@ -268,6 +268,7 @@ mod direct_scenario_tests {
|
||||
#[cfg(test)]
|
||||
mod behavior_lifecycle_tests;
|
||||
mod process_canvas;
|
||||
mod process_multiselect;
|
||||
mod state_diagram;
|
||||
#[cfg(test)]
|
||||
mod state_diagram_tests;
|
||||
@@ -818,6 +819,9 @@ impl App {
|
||||
.map(|n| n.id);
|
||||
}
|
||||
self.draft = Draft::from_project(self.project(), self.selected);
|
||||
if self.process_preview_primary().is_some() {
|
||||
self.draft = None;
|
||||
}
|
||||
if self.exact_strings
|
||||
&& let Some(d) = &mut self.draft
|
||||
{
|
||||
@@ -1294,6 +1298,7 @@ impl App {
|
||||
])
|
||||
}
|
||||
pub fn update(&mut self, message: Message) -> Task<Message> {
|
||||
let preview_read_only = self.process_preview_primary().is_some();
|
||||
let selection_boundary = self.multiselect_boundary();
|
||||
// Reject delayed gestures before they can retire newer input ownership.
|
||||
if let Message::DiagramSelection(event)
|
||||
@@ -1326,6 +1331,52 @@ impl App {
|
||||
// or allocation ownership before its edit is refused.
|
||||
return Task::none();
|
||||
}
|
||||
if let Message::TopologyCanvas(event) = &message {
|
||||
use crate::behavior::topology::CanvasEvent;
|
||||
if !matches!(
|
||||
event,
|
||||
CanvasEvent::Camera(..) | CanvasEvent::Scrolled(..) | CanvasEvent::Viewport(..)
|
||||
) && self.topology_context() != Some(event.context())
|
||||
{
|
||||
return Task::none();
|
||||
}
|
||||
if matches!(
|
||||
event,
|
||||
CanvasEvent::Select(..)
|
||||
| CanvasEvent::SelectQualified(..)
|
||||
| CanvasEvent::Remove(..)
|
||||
| CanvasEvent::Reorder { .. }
|
||||
| CanvasEvent::Reconnect { .. }
|
||||
) && self
|
||||
.multiselect_snapshot()
|
||||
.is_some_and(|s| s.targets().len() > 1)
|
||||
{
|
||||
return Task::none();
|
||||
}
|
||||
}
|
||||
if self.process_order_noop(&message) {
|
||||
return Task::none();
|
||||
}
|
||||
if self.process_preview_primary().is_some()
|
||||
&& matches!(
|
||||
&message,
|
||||
Message::Field(..)
|
||||
| Message::FieldText(..)
|
||||
| Message::FieldShape(..)
|
||||
| Message::FieldAppend(..)
|
||||
| Message::FieldValuePath(..)
|
||||
| Message::FieldVariant(..)
|
||||
| Message::FieldArray(..)
|
||||
| Message::ElementKind(_)
|
||||
| Message::RelationKind(_)
|
||||
| Message::Apply
|
||||
| Message::Delete
|
||||
| Message::DiagramRemove(_)
|
||||
)
|
||||
{
|
||||
self.status = "Open the referenced definition to edit its contents.".into();
|
||||
return Task::none();
|
||||
}
|
||||
// Captured Text commands validate their origin before they can
|
||||
// invalidate that same origin or pass into existing command handlers.
|
||||
if let Message::TextWorkspace(event) = message {
|
||||
@@ -1420,6 +1471,9 @@ impl App {
|
||||
{
|
||||
self.reconcile_multiselect();
|
||||
}
|
||||
if preview_read_only && self.process_preview_primary().is_none() && self.draft.is_none() {
|
||||
self.refresh_draft();
|
||||
}
|
||||
task
|
||||
}
|
||||
fn behavior_control(&mut self, intent: behavior::canvas_workspace::Intent) -> Task<Message> {
|
||||
@@ -2333,6 +2387,9 @@ impl App {
|
||||
self.route_context()
|
||||
};
|
||||
}
|
||||
if request.process.is_some() {
|
||||
request.process = self.topology_context();
|
||||
}
|
||||
self.model_menu = crate::model_menu::Opened::new(self, request, self.menu_sequence);
|
||||
}
|
||||
Message::Menu(crate::model_menu::Event::Close) => {
|
||||
@@ -2362,7 +2419,10 @@ impl App {
|
||||
"Apply or revert pending edits before using modeling actions.".into();
|
||||
return Task::none();
|
||||
}
|
||||
if matches!(*action, Message::DiagramSelection(_)) {
|
||||
if matches!(*action, Message::DiagramSelection(_))
|
||||
|| (menu.request.process.is_some()
|
||||
&& matches!(*action, Message::TopologyCanvas(_)))
|
||||
{
|
||||
return self.update(*action);
|
||||
}
|
||||
self.select(menu.request.object);
|
||||
@@ -3215,7 +3275,11 @@ impl App {
|
||||
.multiselect_snapshot()
|
||||
.is_some_and(|s| s.targets().len() > 1)
|
||||
{
|
||||
self.status = "Group model-deletion review is not available yet. Select one element or use Hide selected.".into();
|
||||
self.status = if self.topology_context().is_some() {
|
||||
"Group removal needs an aggregate review. Select one contribution to remove it individually."
|
||||
} else {
|
||||
"Group model-deletion review is not available yet. Select one element or use Hide selected."
|
||||
}.into();
|
||||
return Task::none();
|
||||
}
|
||||
if self.selected != self.project().id && self.apply() {
|
||||
|
||||
Reference in New Issue
Block a user