jellyflow_runtime/io/view_state/
state.rs1use serde::{Deserialize, Serialize};
2
3use jellyflow_core::core::{CanvasPoint, EdgeId, Graph, GroupId, NodeId};
4
5use super::default_zoom;
6use super::pure::NodeGraphPureViewState;
7
8#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
12pub struct NodeGraphViewState {
13 #[serde(default)]
15 pub pan: CanvasPoint,
16 #[serde(default = "default_zoom")]
18 pub zoom: f32,
19 #[serde(default, skip_serializing_if = "Vec::is_empty")]
21 pub selected_nodes: Vec<NodeId>,
22 #[serde(default, skip_serializing_if = "Vec::is_empty")]
24 pub selected_edges: Vec<EdgeId>,
25 #[serde(default, skip_serializing_if = "Vec::is_empty")]
27 pub selected_groups: Vec<GroupId>,
28 #[serde(default, skip_serializing_if = "Vec::is_empty")]
30 pub draw_order: Vec<NodeId>,
31 #[serde(default, skip_serializing_if = "Vec::is_empty")]
33 pub edge_draw_order: Vec<EdgeId>,
34 #[serde(default, skip_serializing_if = "Vec::is_empty")]
36 pub group_draw_order: Vec<GroupId>,
37}
38
39impl Default for NodeGraphViewState {
40 fn default() -> Self {
41 Self {
42 pan: CanvasPoint::default(),
43 zoom: default_zoom(),
44 selected_nodes: Vec::new(),
45 selected_edges: Vec::new(),
46 selected_groups: Vec::new(),
47 draw_order: Vec::new(),
48 edge_draw_order: Vec::new(),
49 group_draw_order: Vec::new(),
50 }
51 }
52}
53
54impl NodeGraphViewState {
55 pub fn set_viewport(&mut self, pan: CanvasPoint, zoom: f32) {
56 self.pan = sanitize_pan(pan);
57 self.zoom = sanitize_zoom(zoom);
58 }
59
60 pub fn set_selection(&mut self, nodes: Vec<NodeId>, edges: Vec<EdgeId>, groups: Vec<GroupId>) {
61 self.selected_nodes = nodes;
62 self.selected_edges = edges;
63 self.selected_groups = groups;
64 }
65
66 pub fn sanitize_for_graph(&mut self, graph: &Graph) {
68 self.sanitize_viewport();
69
70 let visible_node = |id: &NodeId| graph.nodes.get(id).is_some_and(|node| !node.hidden);
71
72 self.selected_nodes.retain(visible_node);
73 let visible_edge = |id: &EdgeId| {
74 let Some(edge) = graph.edges.get(id) else {
75 return false;
76 };
77 if edge.hidden {
78 return false;
79 }
80 let Some(from) = graph.ports.get(&edge.from) else {
81 return false;
82 };
83 let Some(to) = graph.ports.get(&edge.to) else {
84 return false;
85 };
86 visible_node(&from.node) && visible_node(&to.node)
87 };
88
89 self.selected_edges.retain(|id| visible_edge(id));
90 self.selected_groups
91 .retain(|id| graph.groups.contains_key(id));
92 self.draw_order.retain(visible_node);
93 self.edge_draw_order.retain(|id| visible_edge(id));
94 self.group_draw_order
95 .retain(|id| graph.groups.contains_key(id));
96 }
97
98 pub fn sanitize_viewport(&mut self) {
99 self.pan = sanitize_pan(self.pan);
100 self.zoom = sanitize_zoom(self.zoom);
101 }
102}
103
104fn sanitize_pan(pan: CanvasPoint) -> CanvasPoint {
105 if pan.is_finite() {
106 pan
107 } else {
108 CanvasPoint::default()
109 }
110}
111
112fn sanitize_zoom(zoom: f32) -> f32 {
113 if zoom.is_finite() && zoom > 0.0 {
114 zoom
115 } else {
116 default_zoom()
117 }
118}
119
120impl From<NodeGraphPureViewState> for NodeGraphViewState {
121 fn from(value: NodeGraphPureViewState) -> Self {
122 Self {
123 pan: value.pan,
124 zoom: value.zoom,
125 selected_nodes: value.selected_nodes,
126 selected_edges: value.selected_edges,
127 selected_groups: value.selected_groups,
128 draw_order: value.draw_order,
129 edge_draw_order: value.edge_draw_order,
130 group_draw_order: value.group_draw_order,
131 }
132 }
133}
134
135impl From<NodeGraphViewState> for NodeGraphPureViewState {
136 fn from(value: NodeGraphViewState) -> Self {
137 Self {
138 pan: value.pan,
139 zoom: value.zoom,
140 selected_nodes: value.selected_nodes,
141 selected_edges: value.selected_edges,
142 selected_groups: value.selected_groups,
143 draw_order: value.draw_order,
144 edge_draw_order: value.edge_draw_order,
145 group_draw_order: value.group_draw_order,
146 }
147 }
148}
149
150impl From<&NodeGraphViewState> for NodeGraphPureViewState {
151 fn from(value: &NodeGraphViewState) -> Self {
152 Self {
153 pan: value.pan,
154 zoom: value.zoom,
155 selected_nodes: value.selected_nodes.clone(),
156 selected_edges: value.selected_edges.clone(),
157 selected_groups: value.selected_groups.clone(),
158 draw_order: value.draw_order.clone(),
159 edge_draw_order: value.edge_draw_order.clone(),
160 group_draw_order: value.group_draw_order.clone(),
161 }
162 }
163}