Skip to main content

egui_graphs/layouts/
layout.rs

1use egui::util::id_type_map::SerializableAny;
2use petgraph::{stable_graph::IndexType, EdgeType};
3use std::fmt::Debug;
4
5use crate::{DisplayEdge, DisplayNode, Graph};
6
7const KEY_PREFIX: &str = "egui_graphs_layout";
8
9fn get_id(id: Option<String>) -> egui::Id {
10    egui::Id::new(format!("{KEY_PREFIX}_{}", id.unwrap_or_default()))
11}
12
13pub trait LayoutState: SerializableAny + Default + Debug {
14    fn load(ui: &egui::Ui, id: Option<String>) -> Self {
15        ui.data_mut(|data| data.get_persisted::<Self>(get_id(id)).unwrap_or_default())
16    }
17
18    fn save(self, ui: &mut egui::Ui, id: Option<String>) {
19        ui.data_mut(|data| {
20            data.insert_persisted(get_id(id), self);
21        });
22    }
23}
24
25/// Optional hooks for animated/simulated layout states.
26/// Implement on your layout state to allow `GraphView` helpers to force-run steps
27/// even when paused and to read/write the last average displacement metric.
28pub trait AnimatedState {
29    fn is_running(&self) -> bool;
30    fn set_running(&mut self, v: bool);
31
32    /// Average per-node displacement from the last simulation step (graph units).
33    fn last_avg_displacement(&self) -> Option<f32> {
34        None
35    }
36    /// Store average displacement metric. Default: no-op.
37    fn set_last_avg_displacement(&mut self, _v: Option<f32>) {}
38
39    /// Retrieve current total step count (for animated/simulated layouts).
40    fn step_count(&self) -> u64 {
41        0
42    }
43
44    /// Set total step count.
45    fn set_step_count(&mut self, _v: u64) {}
46}
47
48// Note: Step counting is part of AnimatedState for animated layouts.
49
50pub trait Layout<S>: Default
51where
52    S: LayoutState,
53{
54    /// Creates a new layout from the given state. State is loaded and saved on every frame.
55    fn from_state(state: S) -> impl Layout<S>;
56
57    /// Called on every frame. It should update the graph layout aka nodes locations.
58    fn next<N, E, Ty, Ix, Dn, De>(&mut self, g: &mut Graph<N, E, Ty, Ix, Dn, De>, ui: &egui::Ui)
59    where
60        N: Clone,
61        E: Clone,
62        Ty: EdgeType,
63        Ix: IndexType,
64        Dn: DisplayNode<N, E, Ty, Ix>,
65        De: DisplayEdge<N, E, Ty, Ix, Dn>;
66
67    /// Returns the current state of the layout.
68    fn state(&self) -> S;
69}