diff --git a/src/drawer.rs b/src/drawer.rs index 3b2aa64..a6ae94a 100644 --- a/src/drawer.rs +++ b/src/drawer.rs @@ -117,7 +117,7 @@ impl<'a, N: Clone, E: Clone> Drawer<'a, N, E> { edge_map .entry((source, target)) .or_insert_with(Vec::new) - .push((e.id(), edge.clone(), self.comp.edge_state(e.id()).unwrap())); + .push((e.id(), edge.clone(), self.comp.edge_state(&e.id()).unwrap())); }); let edges_by_nodes = edge_map @@ -206,7 +206,7 @@ impl<'a, N: Clone, E: Clone> Drawer<'a, N, E> { order: usize, ) -> Vec { let n: Node = self.g.node(*n_idx).unwrap().screen_transform(self.meta); - let comp_node = self.comp.node_state(*n_idx).unwrap(); + let comp_node = self.comp.node_state(n_idx).unwrap(); let pos_start_and_end = n.location.to_pos2(); let loop_size = comp_node.radius(self.meta) * (4. + 1. + order as f32); @@ -282,8 +282,8 @@ impl<'a, N: Clone, E: Clone> Drawer<'a, N, E> { .location .to_pos2(); - let comp_start = self.comp.node_state(*start_idx).unwrap(); - let comp_end = self.comp.node_state(*end_idx).unwrap(); + let comp_start = self.comp.node_state(start_idx).unwrap(); + let comp_end = self.comp.node_state(end_idx).unwrap(); let vec = pos_end - pos_start; let l = vec.length(); diff --git a/src/graph_view.rs b/src/graph_view.rs index 6ae1b64..cb7cdf8 100644 --- a/src/graph_view.rs +++ b/src/graph_view.rs @@ -12,11 +12,11 @@ use crate::{ metadata::Metadata, selections::Selections, settings::{SettingsInteraction, SettingsStyle}, - state_computed::StateComputed, + state_computed::{StateComputed, StateComputedEdge, StateComputedNode}, Edge, SettingsNavigation, }; use egui::{Painter, Pos2, Rect, Response, Sense, Ui, Vec2, Widget}; -use petgraph::stable_graph::{NodeIndex, StableGraph}; +use petgraph::{stable_graph::{NodeIndex, StableGraph}, visit::EdgeRef}; /// `GraphView` is a widget for visualizing and interacting with graphs. /// @@ -337,9 +337,20 @@ impl<'a, N: Clone, E: Clone> GraphView<'a, N, E> { } fn precompute_state(&mut self) -> StateComputed { - let mut state = StateComputed::new(self.g.node_count(), self.g.edge_count()); - let mut selections = Selections::default(); + let nodes_computed = self.g.nodes().map(|(idx, _)| { + let node_state = StateComputedNode::default(); + (idx, node_state) + }); + + let edges_computed = self.g.edges().map(|e| { + let edge_state = StateComputedEdge::default(); + (e.id(), edge_state) + }); + + let mut state = StateComputed::default(); + state.nodes = nodes_computed.collect(); + state.edges = edges_computed.collect(); // compute radiuses and selections let child_mode = self.settings_interaction.selection_depth > 0; @@ -347,7 +358,7 @@ impl<'a, N: Clone, E: Clone> GraphView<'a, N, E> { // compute radii let num = self.g.edges_num(root_idx); state - .node_state_mut(root_idx) + .node_state_mut(&root_idx) .unwrap() .inc_radius(self.settings_style.edge_radius_weight * num as f32); @@ -370,7 +381,7 @@ impl<'a, N: Clone, E: Clone> GraphView<'a, N, E> { return; } - let computed = state.node_state_mut(*idx).unwrap(); + let computed = state.node_state_mut(idx).unwrap(); if child_mode { computed.selected_child = true; return; @@ -379,7 +390,7 @@ impl<'a, N: Clone, E: Clone> GraphView<'a, N, E> { }); edges.iter().for_each(|idx| { - let mut computed = state.edge_state_mut(*idx).unwrap(); + let mut computed = state.edge_state_mut(idx).unwrap(); if child_mode { computed.selected_child = true; return; diff --git a/src/graph_wrapper.rs b/src/graph_wrapper.rs index 400697d..ad4f253 100644 --- a/src/graph_wrapper.rs +++ b/src/graph_wrapper.rs @@ -39,7 +39,7 @@ impl<'a, N: Clone, E: Clone> GraphWrapper<'a, N, E> { ) -> impl Iterator, &StateComputedNode)> { self.g .node_references() - .map(|(i, n)| (i, n, comp.node_state(i).unwrap())) + .map(|(i, n)| (i, n, comp.node_state(&i).unwrap())) } pub fn nodes(&'a self) -> impl Iterator)> { diff --git a/src/state_computed.rs b/src/state_computed.rs index 1d3a7e4..65e8de4 100644 --- a/src/state_computed.rs +++ b/src/state_computed.rs @@ -1,42 +1,35 @@ +use std::collections::HashMap; + use petgraph::{stable_graph::EdgeIndex, stable_graph::NodeIndex}; use crate::{metadata::Metadata, selections::Selections}; /// `StateComputed` is a utility struct for managing ephemerial state which is created and destroyed in one frame. /// -/// The struct stores the selected nodes, dragged node, and cached edges by nodes. -#[derive(Debug, Clone)] +/// The struct stores selections, dragged node and computed elements states. +#[derive(Default, Debug, Clone)] pub struct StateComputed { pub dragged: Option, pub selections: Option, - nodes: Vec, - edges: Vec, + pub nodes: HashMap, + pub edges: HashMap, } impl StateComputed { - pub fn new(node_count: usize, edge_count: usize) -> Self { - Self { - dragged: None, - selections: None, - nodes: vec![Default::default(); node_count], - edges: vec![Default::default(); edge_count], - } - } - - pub fn node_state(&self, idx: NodeIndex) -> Option<&StateComputedNode> { - self.nodes.get(idx.index()) + pub fn node_state(&self, idx: &NodeIndex) -> Option<&StateComputedNode> { + self.nodes.get(idx) } - pub fn node_state_mut(&mut self, idx: NodeIndex) -> Option<&mut StateComputedNode> { - self.nodes.get_mut(idx.index()) + pub fn node_state_mut(&mut self, idx: &NodeIndex) -> Option<&mut StateComputedNode> { + self.nodes.get_mut(idx) } - pub fn edge_state(&self, idx: EdgeIndex) -> Option<&StateComputedEdge> { - self.edges.get(idx.index()) + pub fn edge_state(&self, idx: &EdgeIndex) -> Option<&StateComputedEdge> { + self.edges.get(idx) } - pub fn edge_state_mut(&mut self, idx: EdgeIndex) -> Option<&mut StateComputedEdge> { - self.edges.get_mut(idx.index()) + pub fn edge_state_mut(&mut self, idx: &EdgeIndex) -> Option<&mut StateComputedEdge> { + self.edges.get_mut(idx) } }