ferrum_flow/plugin/
utils.rs1use std::collections::HashMap;
2
3use gpui::{KeyDownEvent, Pixels, Point};
4
5use crate::{
6 Edge, EdgeId, Graph, NodeId, Port, PortId, RendererRegistry, Viewport, canvas::PortLayoutCache,
7};
8
9pub fn primary_platform_modifier(ev: &KeyDownEvent) -> bool {
11 #[cfg(target_os = "macos")]
12 {
13 ev.keystroke.modifiers.platform
14 }
15 #[cfg(not(target_os = "macos"))]
16 {
17 ev.keystroke.modifiers.control
18 }
19}
20
21pub fn is_node_visible(graph: &Graph, viewport: &Viewport, node_id: &NodeId) -> bool {
22 let Some(node) = graph.get_node(node_id) else {
23 return false;
24 };
25
26 viewport.is_node_visible(node)
27}
28
29pub fn is_edge_visible(graph: &Graph, viewport: &Viewport, edge: &Edge) -> bool {
30 let Edge {
31 source_port,
32 target_port,
33 ..
34 } = edge;
35
36 let Some(Port { node_id: n1, .. }) = graph.ports.get(source_port) else {
37 return false;
38 };
39
40 let Some(Port { node_id: n2, .. }) = graph.ports.get(target_port) else {
41 return false;
42 };
43
44 let node1_visible = graph
45 .get_node(n1)
46 .map(|n| viewport.is_node_visible(n))
47 .unwrap_or(false);
48
49 let node2_visible = graph
50 .get_node(n2)
51 .map(|n| viewport.is_node_visible(n))
52 .unwrap_or(false);
53
54 node1_visible || node2_visible
55}
56
57pub fn port_offset_cached(
58 cache: &PortLayoutCache,
59 node_id: &NodeId,
60 port_id: &PortId,
61) -> Option<Point<Pixels>> {
62 cache.map.get(node_id)?.get(port_id).copied()
63}
64
65pub fn cache_node_port_offset(
66 graph: &Graph,
67 renderers: &RendererRegistry,
68 cache: &mut PortLayoutCache,
69 node_id: &NodeId,
70) {
71 if cache.map.contains_key(node_id) {
72 return;
73 }
74
75 let Some(node) = graph.get_node(node_id) else {
76 return;
77 };
78
79 let renderer = renderers.get(&node.node_type);
80
81 let mut result = HashMap::new();
82
83 for port in graph.ports.values().filter(|p| p.node_id == node.id) {
84 let pos = renderer.port_offset(node, port, graph);
85 result.insert(port.id, pos);
86 }
87
88 cache.map.insert(node.id, result);
89}
90
91pub fn cache_all_node_port_offset(
92 graph: &Graph,
93 renderers: &RendererRegistry,
94 cache: &mut PortLayoutCache,
95) {
96 let node_ids: Vec<NodeId> = graph.nodes().iter().map(|(id, _)| *id).collect();
97
98 for node_id in node_ids {
99 cache_node_port_offset(graph, renderers, cache, &node_id);
100 }
101}
102
103pub fn cache_port_offset_with_edge(
104 graph: &Graph,
105 renderers: &RendererRegistry,
106 cache: &mut PortLayoutCache,
107 edge_id: &EdgeId,
108) {
109 let Some(edge) = graph.edges.get(edge_id) else {
110 return;
111 };
112
113 cache_port_offset_with_port(graph, renderers, cache, &edge.source_port);
114 cache_port_offset_with_port(graph, renderers, cache, &edge.target_port);
115}
116
117pub fn cache_port_offset_with_port(
118 graph: &Graph,
119 renderers: &RendererRegistry,
120 cache: &mut PortLayoutCache,
121 port_id: &PortId,
122) {
123 let Some(port) = graph.ports.get(port_id) else {
124 return;
125 };
126
127 cache_node_port_offset(graph, renderers, cache, &port.node_id);
128}