Integrate contextual source creation with lifecycle rendering

This commit is contained in:
2026-09-11 10:38:05 -07:00
parent 4da92ab481
commit 321897fd55
21 changed files with 4250 additions and 471 deletions
+70 -11
View File
@@ -854,8 +854,12 @@ impl App {
let scenario_selection = self
.behavior
.scenario
.created_selection(&command)
.or_else(|| self.behavior.topology.created_selection(&command));
.created_selection(self.project(), &command)
.or_else(|| {
self.behavior
.topology
.created_selection(self.project(), &command)
});
match self.document.execute(command) {
Ok(selected) => {
if let Some(created) = created {
@@ -1031,8 +1035,10 @@ impl App {
window::close_requests().map(|id| Message::Request(Pending::Close(id))),
window::resize_events().map(|(_, size)| Message::WindowResized(size)),
architecture_authoring::subscription(self),
behavior::creation::subscription(self.behavior.creation.has_pending())
.map(|()| Message::Escape),
behavior::creation::subscription(
self.behavior.creation.has_pending() || self.behavior.source_active(),
)
.map(|()| Message::Escape),
iced::event::listen_with(|event, status, _| {
let iced::Event::Keyboard(keyboard::Event::KeyPressed {
key,
@@ -1519,6 +1525,37 @@ impl App {
return Task::none();
}
match mutation {
CanvasEvent::First(_, tool) => {
let empty = match tool {
scenario::Tool::Lifeline => !self
.project()
.children(context.scenario)
.any(|e| e.kind() == Kind::Lifeline),
scenario::Tool::Message | scenario::Tool::Action => {
self.project()
.children(context.scenario)
.any(|e| e.kind() == Kind::Lifeline)
&& !self
.project()
.children(context.scenario)
.any(|e| e.kind() == Kind::Occurrence)
}
_ => false,
};
if !empty {
self.status="This scenario already has content. Use its current authoring tools.".into();
return Task::none();
}
let mut state = std::mem::take(&mut self.behavior.scenario);
let result = state.update(
self.project(),
scenario::Event::Start(context.scenario, tool),
);
self.behavior.scenario = state;
if let Err(error) = result {
self.status = error;
}
}
CanvasEvent::BeginOccurrence {
tool,
slot,
@@ -1754,7 +1791,15 @@ impl App {
return self.update(Message::Add(child));
}
Message::Escape => {
if self.behavior.creation.has_pending() {
if self.behavior.source_back() {
self.status =
"Returned to the unchanged parent form; no source was created.".into();
return Task::none();
}
if self.behavior.source_active() {
self.behavior.acknowledge_commit();
self.status = "Behavior form cancelled; no staged source was created.".into();
} else if self.behavior.creation.has_pending() {
self.behavior.creation.acknowledge_commit();
self.status = "Behavior creation cancelled".into();
}
@@ -2321,10 +2366,13 @@ impl App {
self.status = "Apply or cancel the current draft before starting a new behavior. Your inputs are retained.".into();
return Task::none();
}
if !creating && event.starts_form() && !self.behavior.has_pending() && !self.apply()
if (event.starts_form() || (event.is_source() && !event.is_source_back()))
&& (self.source_dirty() || self.draft_dirty())
{
self.status="Apply or cancel the other editors before starting this form. Your inputs are retained.".into();
return Task::none();
}
let source_was_open = self.behavior.source_open();
if event.is_submit() && (self.source_dirty() || self.draft_dirty()) {
self.status = "Revert the other drafts before applying the behavior form. Your inputs are retained.".into();
return Task::none();
@@ -2342,6 +2390,11 @@ impl App {
}
}
Ok(None) => {
if !source_was_open && self.behavior.source_open() {
return iced::widget::operation::focus(
behavior::source_draft::NAME_INPUT,
);
}
if focus_name {
return iced::widget::operation::focus(behavior::creation::NAME_INPUT);
}
@@ -2537,13 +2590,19 @@ impl App {
Message::Undo | Message::Redo => {
let redo = matches!(message, Message::Redo);
if self.apply() {
if redo {
self.document.redo();
let changed = if redo {
self.document.redo()
} else {
self.document.undo();
self.document.undo()
};
if changed {
self.sync();
}
self.sync();
self.status = if redo {
self.status = if !changed && redo {
"Nothing to redo"
} else if !changed {
"Nothing to undo"
} else if redo {
"Model change redone"
} else {
"Model change undone"