Skip to content

Commit f001ef7

Browse files
committed
Refactor layout state and metadata key handling
Replace string-based keys with egui::Id for layout state and metadata persistence. Simplified set of AnimatedState methods. Rename `build_tree` to `layout_tree` and simplify hierarchical layout logic.
1 parent 04be7b0 commit f001ef7

File tree

5 files changed

+27
-41
lines changed

5 files changed

+27
-41
lines changed

crates/egui_graphs/src/layouts/force_directed/implementations/fruchterman_reingold/core.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ impl ForceAlgorithm for FruchtermanReingold {
170170
params.max_step,
171171
);
172172
self.state.last_avg_displacement = avg;
173-
self.state.inc_step_count();
173+
self.state.set_step_count(self.state.step_count + 1);
174174
}
175175

176176
fn state(&self) -> Self::State {

crates/egui_graphs/src/layouts/force_directed/implementations/fruchterman_reingold/with_extras.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,9 @@ impl<E: ExtrasTuple> ForceAlgorithm for FruchtermanReingoldWithExtras<E> {
123123
base.max_step,
124124
);
125125
self.state.base.last_avg_displacement = avg;
126-
self.state.base.inc_step_count();
126+
self.state
127+
.base
128+
.set_step_count(self.state.base.step_count() + 1);
127129
}
128130

129131
fn state(&self) -> Self::State {

crates/egui_graphs/src/layouts/hierarchical/layout.rs

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,9 @@ impl Layout<State> for Hierarchical {
8181
if visited.contains(root) {
8282
continue;
8383
}
84-
let curr_max_col = build_tree(g, &mut visited, root, &self.state, 0, next_col);
85-
next_col = curr_max_col.saturating_add(1);
84+
85+
let curr_max_col = layout_tree(g, &mut visited, root, &self.state, 0, next_col);
86+
next_col = curr_max_col + 1;
8687
}
8788

8889
// Fallback: if the graph has cycles or no formal roots, lay out any remaining components.
@@ -91,8 +92,9 @@ impl Layout<State> for Hierarchical {
9192
if visited.contains(n) {
9293
continue;
9394
}
94-
let curr_max_col = build_tree(g, &mut visited, n, &self.state, 0, next_col);
95-
next_col = curr_max_col.saturating_add(1);
95+
96+
let curr_max_col = layout_tree(g, &mut visited, n, &self.state, 0, next_col);
97+
next_col = curr_max_col + 1;
9698
}
9799

98100
self.state.triggered = true;
@@ -107,7 +109,7 @@ impl Layout<State> for Hierarchical {
107109
}
108110
}
109111

110-
fn build_tree<N, E, Ty, Ix, Dn, De>(
112+
fn layout_tree<N, E, Ty, Ix, Dn, De>(
111113
g: &mut Graph<N, E, Ty, Ix, Dn, De>,
112114
visited: &mut HashSet<NodeIndex<Ix>>,
113115
root_idx: &NodeIndex<Ix>,
@@ -128,34 +130,26 @@ where
128130
visited.insert(*root_idx);
129131
}
130132

131-
// Traverse children first to compute the horizontal span of this subtree.
132-
let mut had_child = false;
133-
let mut max_col = start_col;
134-
let mut child_col = start_col;
135-
136133
let children: Vec<NodeIndex<Ix>> = g.g().neighbors_directed(*root_idx, Outgoing).collect();
137134

135+
// Traverse children to compute the horizontal span of this subtree.
136+
let mut max_col = start_col;
137+
let mut child_col = start_col;
138138
for neighbour_idx in children.iter() {
139139
if visited.contains(neighbour_idx) {
140140
continue;
141141
}
142142
visited.insert(*neighbour_idx);
143-
had_child = true;
144143

145-
let child_max_col = build_tree(g, visited, neighbour_idx, state, start_row + 1, child_col);
144+
let child_max_col = layout_tree(g, visited, neighbour_idx, state, start_row + 1, child_col);
146145
if child_max_col > max_col {
147146
max_col = child_max_col;
148147
}
149148
child_col = child_max_col.saturating_add(1);
150149
}
151150

152151
// Column where the current node will be placed.
153-
let place_col = if state.center_parent && had_child {
154-
// Center above/beside the span [start_col..=max_col]
155-
(start_col + max_col) / 2
156-
} else {
157-
start_col
158-
};
152+
let place_col = start_col;
159153

160154
// Compute actual coordinates based on orientation.
161155
let (x, y) = match state.orientation {

crates/egui_graphs/src/layouts/layout.rs

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,19 @@ use std::fmt::Debug;
55
use crate::{DisplayEdge, DisplayNode, Graph};
66

77
const KEY_PREFIX: &str = "egui_graphs_layout";
8-
fn get_key(id: Option<String>) -> String {
9-
format!("{KEY_PREFIX}_{}", id.unwrap_or_default())
8+
9+
fn get_id(id: Option<String>) -> egui::Id {
10+
egui::Id::new(format!("{KEY_PREFIX}_{}", id.unwrap_or_default()))
1011
}
1112

1213
pub trait LayoutState: SerializableAny + Default + Debug {
1314
fn load(ui: &egui::Ui, id: Option<String>) -> Self {
14-
ui.data_mut(|data| {
15-
data.get_persisted::<Self>(egui::Id::new(get_key(id)))
16-
.unwrap_or_default()
17-
})
15+
ui.data_mut(|data| data.get_persisted::<Self>(get_id(id)).unwrap_or_default())
1816
}
1917

2018
fn save(self, ui: &mut egui::Ui, id: Option<String>) {
2119
ui.data_mut(|data| {
22-
data.insert_persisted(egui::Id::new(get_key(id)), self);
20+
data.insert_persisted(get_id(id), self);
2321
});
2422
}
2523
}
@@ -30,8 +28,8 @@ pub trait LayoutState: SerializableAny + Default + Debug {
3028
pub trait AnimatedState {
3129
fn is_running(&self) -> bool;
3230
fn set_running(&mut self, v: bool);
31+
3332
/// Average per-node displacement from the last simulation step (graph units).
34-
/// Default: None (not provided by the layout).
3533
fn last_avg_displacement(&self) -> Option<f32> {
3634
None
3735
}
@@ -42,17 +40,9 @@ pub trait AnimatedState {
4240
fn step_count(&self) -> u64 {
4341
0
4442
}
43+
4544
/// Set total step count.
4645
fn set_step_count(&mut self, _v: u64) {}
47-
/// Convenience: increment step count (saturating add).
48-
fn inc_step_count(&mut self) {
49-
let n = self.step_count();
50-
self.set_step_count(n.saturating_add(1));
51-
}
52-
/// Convenience: reset step count to zero.
53-
fn reset_step_count(&mut self) {
54-
self.set_step_count(0);
55-
}
5646
}
5747

5848
// Note: Step counting is part of AnimatedState for animated layouts.

crates/egui_graphs/src/metadata.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -91,14 +91,14 @@ impl MetadataFrame {
9191

9292
pub fn load(self, ui: &egui::Ui) -> Self {
9393
ui.data_mut(|data| {
94-
data.get_persisted::<MetadataFrame>(Id::new(self.get_key()))
94+
data.get_persisted::<MetadataFrame>(Id::new(self.get_id()))
9595
.unwrap_or(self.clone())
9696
})
9797
}
9898

9999
pub fn save(self, ui: &mut egui::Ui) {
100100
ui.data_mut(|data| {
101-
data.insert_persisted(Id::new(self.get_key()), self);
101+
data.insert_persisted(Id::new(self.get_id()), self);
102102
});
103103
}
104104

@@ -154,8 +154,8 @@ impl MetadataFrame {
154154
}
155155

156156
/// Get key which is used to store metadata in egui cache.
157-
pub fn get_key(&self) -> String {
158-
format!("{KEY_PREFIX}_{}", self.id.clone())
157+
pub fn get_id(&self) -> Id {
158+
egui::Id::new(format!("{KEY_PREFIX}_{}", self.id.clone()))
159159
}
160160
}
161161

0 commit comments

Comments
 (0)