147 lines
5.9 KiB
Rust
147 lines
5.9 KiB
Rust
//! Complete a navigation camera after the destination reports its real viewport.
|
|
use super::*;
|
|
use crate::diagram_usage::{Context, Surface};
|
|
#[cfg(test)]
|
|
mod tests;
|
|
|
|
impl App {
|
|
pub(super) fn is_diagram_viewport(message: &Message) -> bool {
|
|
matches!(
|
|
message,
|
|
Message::CanvasResized(_)
|
|
| Message::DiagramRevealViewport(..)
|
|
| Message::TopologyCanvas(behavior::topology::CanvasEvent::Viewport(..))
|
|
| Message::ScenarioCanvas(behavior::scenario::CanvasEvent::Viewport(..))
|
|
| Message::StateDiagram(behavior::state_edit::Event::Viewport(..))
|
|
)
|
|
}
|
|
pub(crate) fn architecture_reveal_stamp(&self, diagram: Id) -> Option<(Context, u64)> {
|
|
self.pending_diagram_reveal
|
|
.as_ref()
|
|
.filter(|(_, u, _)| u.surface == Surface::Saved(diagram))
|
|
.map(|(context, _, epoch)| (*context, *epoch))
|
|
}
|
|
|
|
pub(super) fn diagram_reveal_viewport(&self, message: &Message) -> Option<Surface> {
|
|
let (context, usage, epoch) = self.pending_diagram_reveal.as_ref()?;
|
|
if context.document != self.canvas_document
|
|
|| context.revision != self.document.revision()
|
|
|| *epoch != self.canvas_epoch
|
|
{
|
|
return None;
|
|
}
|
|
let (surface, size, valid) = match message {
|
|
Message::DiagramRevealViewport(c, e, size) => (
|
|
usage.surface,
|
|
*size,
|
|
c == context
|
|
&& e == epoch
|
|
&& self.page == Page::Diagram
|
|
&& Some(usage.surface.id()) == self.active_diagram,
|
|
),
|
|
Message::TopologyCanvas(behavior::topology::CanvasEvent::Viewport(c, size)) => (
|
|
Surface::Process(c.owner),
|
|
*size,
|
|
c.document == context.document
|
|
&& c.revision == context.revision
|
|
&& c.epoch == *epoch,
|
|
),
|
|
Message::ScenarioCanvas(behavior::scenario::CanvasEvent::Viewport(c, size)) => (
|
|
Surface::Scenario(c.scenario),
|
|
*size,
|
|
c.document == context.document
|
|
&& c.revision == context.revision
|
|
&& c.epoch == *epoch,
|
|
),
|
|
Message::StateDiagram(behavior::state_edit::Event::Viewport(c, size)) => (
|
|
Surface::Saved(c.diagram),
|
|
*size,
|
|
c.document == context.document
|
|
&& c.revision == context.revision
|
|
&& c.epoch == *epoch,
|
|
),
|
|
_ => return None,
|
|
};
|
|
(valid
|
|
&& surface == usage.surface
|
|
&& size.width.is_finite()
|
|
&& size.height.is_finite()
|
|
&& size.width > 0.
|
|
&& size.height > 0.)
|
|
.then_some(surface)
|
|
}
|
|
|
|
pub(super) fn reconcile_pending_diagram_reveal(&mut self, message: &Message) {
|
|
if !matches!(
|
|
message,
|
|
Message::CheckpointTick
|
|
| Message::CheckpointWritten(..)
|
|
| Message::Lint(_)
|
|
| Message::Linted(..)
|
|
| Message::SourceViewport(_)
|
|
| Message::WindowResized(_)
|
|
| Message::CanvasResized(_)
|
|
| Message::DiagramRevealViewport(..)
|
|
| Message::DiagramUsage(_)
|
|
| Message::DiagramUsagesReady(_)
|
|
| Message::SourceSymbolsReady(_)
|
|
| Message::SourceRenameReady(_)
|
|
| Message::TopologyCanvas(behavior::topology::CanvasEvent::Viewport(..))
|
|
| Message::ScenarioCanvas(behavior::scenario::CanvasEvent::Viewport(..))
|
|
| Message::StateDiagram(behavior::state_edit::Event::Viewport(..))
|
|
) {
|
|
self.pending_diagram_reveal = None;
|
|
if !Self::is_navigation_camera(message) {
|
|
self.diagram_navigation_focus = None;
|
|
}
|
|
}
|
|
}
|
|
|
|
fn is_navigation_camera(message: &Message) -> bool {
|
|
if let Message::BehaviorControl(intent) = message {
|
|
return Self::is_navigation_camera(&intent.message);
|
|
}
|
|
matches!(
|
|
message,
|
|
Message::Pan(_)
|
|
| Message::Zoom(_)
|
|
| Message::Fit
|
|
| Message::TopologyCanvas(
|
|
behavior::topology::CanvasEvent::Camera(..)
|
|
| behavior::topology::CanvasEvent::Zoom(..)
|
|
| behavior::topology::CanvasEvent::Scrolled(..)
|
|
| behavior::topology::CanvasEvent::Focus(..)
|
|
)
|
|
| Message::ScenarioCanvas(
|
|
behavior::scenario::CanvasEvent::Camera(..)
|
|
| behavior::scenario::CanvasEvent::Zoom(..)
|
|
| behavior::scenario::CanvasEvent::Scrolled(..)
|
|
| behavior::scenario::CanvasEvent::Focus(..)
|
|
)
|
|
| Message::StateDiagram(
|
|
behavior::state_edit::Event::Pan(..)
|
|
| behavior::state_edit::Event::Zoom(..)
|
|
| behavior::state_edit::Event::Fit(..)
|
|
)
|
|
)
|
|
}
|
|
|
|
pub(super) fn finish_diagram_reveal(&mut self, surface: Surface) {
|
|
let Some((context, usage, _)) = self.pending_diagram_reveal.take() else {
|
|
return;
|
|
};
|
|
if context.document == self.canvas_document
|
|
&& context.revision == self.document.revision()
|
|
&& usage.surface == surface
|
|
&& !self.draft_dirty()
|
|
&& !self.source_dirty()
|
|
&& !self.behavior.has_pending()
|
|
{
|
|
// The normal viewport handler has now stored the measured size.
|
|
// Target identity was validated for this revision before navigation.
|
|
self.reveal_diagram_usage(&usage);
|
|
}
|
|
self.pending_diagram_reveal = None;
|
|
}
|
|
}
|