diff --git a/examples/basic/src/main.rs b/examples/basic/src/main.rs index 31db89c..f0653cc 100644 --- a/examples/basic/src/main.rs +++ b/examples/basic/src/main.rs @@ -1,10 +1,13 @@ use eframe::{run_native, App, CreationContext}; use egui::Context; use egui_graphs::{Graph, GraphView}; -use petgraph::{stable_graph::StableGraph, Directed}; +use petgraph::{ + stable_graph::{DefaultIx, StableGraph}, + Directed, +}; pub struct BasicApp { - g: Graph<(), (), Directed>, + g: Graph<(), (), Directed, DefaultIx>, } impl BasicApp { diff --git a/examples/configurable/src/main.rs b/examples/configurable/src/main.rs index fdc7bb5..596db6e 100644 --- a/examples/configurable/src/main.rs +++ b/examples/configurable/src/main.rs @@ -7,7 +7,7 @@ use egui_graphs::events::Event; use egui_graphs::{to_graph, Edge, Graph, GraphView, Node}; use fdg_sim::glam::Vec3; use fdg_sim::{ForceGraph, ForceGraphHelper, Simulation, SimulationParameters}; -use petgraph::stable_graph::{EdgeIndex, NodeIndex, StableGraph}; +use petgraph::stable_graph::{DefaultIx, EdgeIndex, NodeIndex, StableGraph}; use petgraph::visit::EdgeRef; use petgraph::Directed; use rand::Rng; @@ -19,7 +19,7 @@ const SIMULATION_DT: f32 = 0.035; const EVENTS_LIMIT: usize = 100; pub struct ConfigurableApp { - g: Graph<(), (), Directed>, + g: Graph<(), (), Directed, DefaultIx>, sim: Simulation<(), f32>, settings_graph: SettingsGraph, @@ -168,7 +168,7 @@ impl ConfigurableApp { self.settings_graph = settings_graph; self.last_events = Default::default(); - GraphView::<(), (), Directed>::reset_metadata(ui); + GraphView::<(), (), Directed, DefaultIx>::reset_metadata(ui); } fn handle_events(&mut self) { @@ -552,14 +552,14 @@ impl App for ConfigurableApp { } } -fn generate(settings: &SettingsGraph) -> (Graph<(), (), Directed>, Simulation<(), f32>) { +fn generate(settings: &SettingsGraph) -> (Graph<(), (), Directed, DefaultIx>, Simulation<(), f32>) { let g = generate_random_graph(settings.count_node, settings.count_edge); let sim = construct_simulation(&g); (g, sim) } -fn construct_simulation(g: &Graph<(), (), Directed>) -> Simulation<(), f32> { +fn construct_simulation(g: &Graph<(), (), Directed, DefaultIx>) -> Simulation<(), f32> { // create force graph let mut force_graph = ForceGraph::with_capacity(g.g.node_count(), g.g.edge_count()); g.g.node_indices().for_each(|idx| { @@ -579,7 +579,10 @@ fn construct_simulation(g: &Graph<(), (), Directed>) -> Simulation<(), f32> { Simulation::from_graph(force_graph, params) } -fn generate_random_graph(node_count: usize, edge_count: usize) -> Graph<(), (), Directed> { +fn generate_random_graph( + node_count: usize, + edge_count: usize, +) -> Graph<(), (), Directed, DefaultIx> { let mut rng = rand::thread_rng(); let mut graph = StableGraph::new(); diff --git a/examples/custom_draw/src/main.rs b/examples/custom_draw/src/main.rs index f69debd..f95faba 100644 --- a/examples/custom_draw/src/main.rs +++ b/examples/custom_draw/src/main.rs @@ -1,12 +1,13 @@ use eframe::{run_native, App, CreationContext}; -use egui::{ - epaint::TextShape, Context, FontFamily, FontId, Rect, Rounding, Shape, Stroke, Vec2, -}; +use egui::{epaint::TextShape, Context, FontFamily, FontId, Rect, Rounding, Shape, Stroke, Vec2}; use egui_graphs::{default_edges_draw, Graph, GraphView, SettingsInteraction}; -use petgraph::{stable_graph::StableGraph, Directed}; +use petgraph::{ + stable_graph::{DefaultIx, StableGraph}, + Directed, +}; pub struct BasicApp { - g: Graph<(), (), Directed>, + g: Graph<(), (), Directed, DefaultIx>, } impl BasicApp { diff --git a/examples/interactive/src/main.rs b/examples/interactive/src/main.rs index b6aa7ef..0c80010 100644 --- a/examples/interactive/src/main.rs +++ b/examples/interactive/src/main.rs @@ -1,10 +1,13 @@ use eframe::{run_native, App, CreationContext}; use egui::Context; use egui_graphs::{Graph, GraphView, SettingsInteraction, SettingsStyle}; -use petgraph::{stable_graph::StableGraph, Directed}; +use petgraph::{ + stable_graph::{DefaultIx, StableGraph}, + Directed, +}; pub struct BasicInteractiveApp { - g: Graph<(), (), Directed>, + g: Graph<(), (), Directed, DefaultIx>, } impl BasicInteractiveApp { @@ -32,7 +35,7 @@ impl App for BasicInteractiveApp { } } -fn generate_graph() -> Graph<(), (), Directed> { +fn generate_graph() -> Graph<(), (), Directed, DefaultIx> { let mut g: StableGraph<(), ()> = StableGraph::new(); let a = g.add_node(()); diff --git a/examples/undirected/src/main.rs b/examples/undirected/src/main.rs index 8aaef7d..13594f5 100644 --- a/examples/undirected/src/main.rs +++ b/examples/undirected/src/main.rs @@ -2,12 +2,12 @@ use eframe::{run_native, App, CreationContext}; use egui::Context; use egui_graphs::{Graph, GraphView}; use petgraph::{ - stable_graph::{StableGraph, StableUnGraph}, + stable_graph::{DefaultIx, StableGraph, StableUnGraph}, Undirected, }; pub struct BasicUndirectedApp { - g: Graph<(), (), Undirected>, + g: Graph<(), (), Undirected, DefaultIx>, } impl BasicUndirectedApp { diff --git a/src/computed.rs b/src/computed.rs index f8bb4b7..4384d7c 100644 --- a/src/computed.rs +++ b/src/computed.rs @@ -1,20 +1,24 @@ use egui::{Rect, Vec2}; +use petgraph::graph::IndexType; use petgraph::{stable_graph::NodeIndex, EdgeType}; use crate::{Graph, Node, SettingsStyle}; /// The struct stores selections, dragged node and computed elements states. #[derive(Debug, Clone)] -pub struct ComputedState { - pub dragged: Option, - pub selected: Vec, +pub struct ComputedState { + pub dragged: Option>, + pub selected: Vec>, min: Vec2, max: Vec2, max_rad: f32, } -impl Default for ComputedState { +impl Default for ComputedState +where + Ix: IndexType, +{ fn default() -> Self { Self { dragged: None, @@ -28,11 +32,14 @@ impl Default for ComputedState { } } -impl ComputedState { +impl ComputedState +where + Ix: IndexType, +{ pub fn compute_for_node( &mut self, - g: &Graph, - idx: NodeIndex, + g: &Graph, + idx: NodeIndex, ) -> ComputedNode { let n = g.node(idx).unwrap(); diff --git a/src/draw/custom.rs b/src/draw/custom.rs index c2025da..322c0b2 100644 --- a/src/draw/custom.rs +++ b/src/draw/custom.rs @@ -1,4 +1,5 @@ use egui::Context; +use petgraph::graph::IndexType; use petgraph::{stable_graph::NodeIndex, EdgeType}; use crate::{Edge, Graph, Metadata, Node, SettingsStyle}; @@ -6,8 +7,8 @@ use crate::{Edge, Graph, Metadata, Node, SettingsStyle}; use super::Layers; /// Contains all the data about current widget state which is needed for custom drawing functions. -pub struct WidgetState<'a, N: Clone, E: Clone, Ty: EdgeType> { - pub g: &'a Graph, +pub struct WidgetState<'a, N: Clone, E: Clone, Ty: EdgeType, Ix: IndexType> { + pub g: &'a Graph, pub style: &'a SettingsStyle, pub meta: &'a Metadata, } @@ -20,8 +21,8 @@ pub struct WidgetState<'a, N: Clone, E: Clone, Ty: EdgeType> { /// - node reference, contains all node data; /// - widget state with references to graph, style and metadata; /// - when you create a shape, add it to the layers. -pub type FnCustomNodeDraw = - fn(&Context, n: &Node, &WidgetState, &mut Layers); +pub type FnCustomNodeDraw = + fn(&Context, n: &Node, &WidgetState, &mut Layers); /// Allows to fully customize what shape would be drawn for an edge. /// The function is **called once for every node pair** which has edges connecting them. So make sure you have drawn all the edges which are passed to the function. @@ -32,5 +33,10 @@ pub type FnCustomNodeDraw = /// - vector of edges, all edges between start and end nodes; /// - widget state with references to graph, style and metadata; /// - when you create a shape, add it to the layers. -pub type FnCustomEdgeDraw = - fn(&Context, (NodeIndex, NodeIndex), Vec<&Edge>, &WidgetState, &mut Layers); +pub type FnCustomEdgeDraw = fn( + &Context, + (NodeIndex, NodeIndex), + Vec<&Edge>, + &WidgetState, + &mut Layers, +); diff --git a/src/draw/drawer.rs b/src/draw/drawer.rs index 2a5bef0..346c126 100644 --- a/src/draw/drawer.rs +++ b/src/draw/drawer.rs @@ -1,6 +1,7 @@ use std::collections::HashMap; use egui::Painter; +use petgraph::graph::IndexType; use petgraph::{stable_graph::NodeIndex, EdgeType}; use crate::{settings::SettingsStyle, Edge, Graph, Metadata}; @@ -12,27 +13,27 @@ use super::{ }; /// Mapping for 2 nodes and all edges between them -type EdgeMap<'a, E> = HashMap<(NodeIndex, NodeIndex), Vec<&'a Edge>>; +type EdgeMap<'a, E, Ix> = HashMap<(NodeIndex, NodeIndex), Vec<&'a Edge>>; -pub struct Drawer<'a, N: Clone, E: Clone, Ty: EdgeType> { +pub struct Drawer<'a, N: Clone, E: Clone, Ty: EdgeType, Ix: IndexType> { p: Painter, - g: &'a Graph, + g: &'a Graph, style: &'a SettingsStyle, meta: &'a Metadata, - custom_node_draw: Option>, - custom_edge_draw: Option>, + custom_node_draw: Option>, + custom_edge_draw: Option>, } -impl<'a, N: Clone, E: Clone, Ty: EdgeType> Drawer<'a, N, E, Ty> { +impl<'a, N: Clone, E: Clone, Ty: EdgeType, Ix: IndexType> Drawer<'a, N, E, Ty, Ix> { pub fn new( p: Painter, - g: &'a Graph, + g: &'a Graph, style: &'a SettingsStyle, meta: &'a Metadata, - custom_node_draw: Option>, - custom_edge_draw: Option>, + custom_node_draw: Option>, + custom_edge_draw: Option>, ) -> Self { Drawer { g, @@ -68,7 +69,7 @@ impl<'a, N: Clone, E: Clone, Ty: EdgeType> Drawer<'a, N, E, Ty> { } fn fill_layers_edges(&self, l: &mut Layers) { - let mut edge_map: EdgeMap = HashMap::new(); + let mut edge_map: EdgeMap = HashMap::new(); self.g.edges_iter().for_each(|(idx, e)| { let (source, target) = self.g.edge_endpoints(idx).unwrap(); diff --git a/src/draw/edge.rs b/src/draw/edge.rs index f46d9ab..489546c 100644 --- a/src/draw/edge.rs +++ b/src/draw/edge.rs @@ -4,17 +4,18 @@ use egui::{ epaint::{CubicBezierShape, QuadraticBezierShape}, Color32, Context, Pos2, Shape, Stroke, Vec2, }; +use petgraph::graph::IndexType; use petgraph::{stable_graph::NodeIndex, EdgeType}; use crate::{Edge, Node}; use super::{custom::WidgetState, Layers}; -pub fn default_edges_draw( +pub fn default_edges_draw( ctx: &Context, - bounds: (NodeIndex, NodeIndex), + bounds: (NodeIndex, NodeIndex), edges: Vec<&Edge>, - state: &WidgetState, + state: &WidgetState, l: &mut Layers, ) { let (idx_start, idx_end) = bounds; @@ -33,14 +34,14 @@ pub fn default_edges_draw( }); } -fn draw_edge_basic( +fn draw_edge_basic( ctx: &Context, l: &mut Layers, n_start: &Node, n_end: &Node, e: &Edge, order: usize, - state: &WidgetState, + state: &WidgetState, ) { let loc_start = n_start.screen_location(state.meta).to_pos2(); let loc_end = n_end.screen_location(state.meta).to_pos2(); @@ -119,13 +120,13 @@ fn draw_edge_basic( l.add(shape_tip_curved); } -fn draw_edge_looped( +fn draw_edge_looped( ctx: &Context, l: &mut Layers, node: &Node, e: &Edge, order: usize, - state: &WidgetState, + state: &WidgetState, ) { let rad = node.screen_radius(state.meta, state.style); let center = node.screen_location(state.meta); diff --git a/src/draw/node.rs b/src/draw/node.rs index e7f7047..08e8a11 100644 --- a/src/draw/node.rs +++ b/src/draw/node.rs @@ -2,16 +2,17 @@ use egui::{ epaint::{CircleShape, TextShape}, Context, FontFamily, FontId, Pos2, Stroke, }; +use petgraph::graph::IndexType; use petgraph::EdgeType; use crate::Node; use super::{custom::WidgetState, Layers}; -pub fn default_node_draw( +pub fn default_node_draw( ctx: &Context, n: &Node, - state: &WidgetState, + state: &WidgetState, l: &mut Layers, ) { let is_interacted = n.selected() || n.dragged(); diff --git a/src/graph.rs b/src/graph.rs index a4ecae2..6c171b2 100644 --- a/src/graph.rs +++ b/src/graph.rs @@ -1,4 +1,5 @@ use egui::Pos2; +use petgraph::graph::IndexType; use petgraph::{ stable_graph::{EdgeIndex, EdgeReference, NodeIndex, StableGraph}, @@ -10,18 +11,20 @@ use crate::{metadata::Metadata, transform, Edge, Node, SettingsStyle}; /// Graph type compatible with [`super::GraphView`]. #[derive(Debug, Clone)] -pub struct Graph { - pub g: StableGraph, Edge, Ty>, +pub struct Graph { + pub g: StableGraph, Edge, Ty, Ix>, } -impl From<&StableGraph> for Graph { - fn from(value: &StableGraph) -> Self { +impl From<&StableGraph> + for Graph +{ + fn from(value: &StableGraph) -> Self { transform::to_graph(value) } } -impl<'a, N: Clone, E: Clone, Ty: EdgeType> Graph { - pub fn new(g: StableGraph, Edge, Ty>) -> Self { +impl<'a, N: Clone, E: Clone, Ty: EdgeType, Ix: IndexType> Graph { + pub fn new(g: StableGraph, Edge, Ty, Ix>) -> Self { Self { g } } @@ -31,7 +34,7 @@ impl<'a, N: Clone, E: Clone, Ty: EdgeType> Graph { meta: &'a Metadata, style: &'a SettingsStyle, screen_pos: Pos2, - ) -> Option<(NodeIndex, &Node)> { + ) -> Option<(NodeIndex, &Node)> { let pos_in_graph = (screen_pos.to_vec2() - meta.pan) / meta.zoom; self.nodes_iter().find(|(_, n)| { let dist_to_node = (n.location() - pos_in_graph).length(); @@ -39,37 +42,37 @@ impl<'a, N: Clone, E: Clone, Ty: EdgeType> Graph { }) } - pub fn g(&mut self) -> &mut StableGraph, Edge, Ty> { + pub fn g(&mut self) -> &mut StableGraph, Edge, Ty, Ix> { &mut self.g } ///Provides iterator over all nodes and their indices. - pub fn nodes_iter(&'a self) -> impl Iterator)> { + pub fn nodes_iter(&'a self) -> impl Iterator, &Node)> { self.g.node_references() } /// Provides iterator over all edges and their indices. - pub fn edges_iter(&'a self) -> impl Iterator)> { + pub fn edges_iter(&'a self) -> impl Iterator, &Edge)> { self.g.edge_references().map(|e| (e.id(), e.weight())) } - pub fn node(&self, i: NodeIndex) -> Option<&Node> { + pub fn node(&self, i: NodeIndex) -> Option<&Node> { self.g.node_weight(i) } - pub fn edge(&self, i: EdgeIndex) -> Option<&Edge> { + pub fn edge(&self, i: EdgeIndex) -> Option<&Edge> { self.g.edge_weight(i) } - pub fn edge_endpoints(&self, i: EdgeIndex) -> Option<(NodeIndex, NodeIndex)> { + pub fn edge_endpoints(&self, i: EdgeIndex) -> Option<(NodeIndex, NodeIndex)> { self.g.edge_endpoints(i) } - pub fn node_mut(&mut self, i: NodeIndex) -> Option<&mut Node> { + pub fn node_mut(&mut self, i: NodeIndex) -> Option<&mut Node> { self.g.node_weight_mut(i) } - pub fn edge_mut(&mut self, i: EdgeIndex) -> Option<&mut Edge> { + pub fn edge_mut(&mut self, i: EdgeIndex) -> Option<&mut Edge> { self.g.edge_weight_mut(i) } @@ -77,15 +80,15 @@ impl<'a, N: Clone, E: Clone, Ty: EdgeType> Graph { self.g.is_directed() } - pub fn edges_num(&self, idx: NodeIndex) -> usize { + pub fn edges_num(&self, idx: NodeIndex) -> usize { self.g.edges(idx).count() } pub fn edges_directed( &self, - idx: NodeIndex, + idx: NodeIndex, dir: Direction, - ) -> impl Iterator>> { + ) -> impl Iterator, Ix>> { self.g.edges_directed(idx, dir) } } diff --git a/src/graph_view.rs b/src/graph_view.rs index 2da1100..97fa73e 100644 --- a/src/graph_view.rs +++ b/src/graph_view.rs @@ -14,6 +14,7 @@ use crate::{ #[cfg(feature = "events")] use crossbeam::channel::Sender; use egui::{Pos2, Rect, Response, Sense, Ui, Vec2, Widget}; +use petgraph::graph::IndexType; use petgraph::{stable_graph::NodeIndex, EdgeType}; /// Widget for visualizing and interacting with graphs. @@ -31,20 +32,22 @@ use petgraph::{stable_graph::NodeIndex, EdgeType}; /// When the user performs navigation actions (zoom & pan or fit to screen), they do not /// produce changes. This is because these actions are performed on the global coordinates and do not change any /// properties of the nodes or edges. -pub struct GraphView<'a, N: Clone, E: Clone, Ty: EdgeType> { +pub struct GraphView<'a, N: Clone, E: Clone, Ty: EdgeType, Ix: IndexType> { settings_interaction: SettingsInteraction, settings_navigation: SettingsNavigation, settings_style: SettingsStyle, - g: &'a mut Graph, + g: &'a mut Graph, - custom_edge_draw: Option>, - custom_node_draw: Option>, + custom_edge_draw: Option>, + custom_node_draw: Option>, #[cfg(feature = "events")] events_publisher: Option<&'a Sender>, } -impl<'a, N: Clone, E: Clone, Ty: EdgeType> Widget for &mut GraphView<'a, N, E, Ty> { +impl<'a, N: Clone, E: Clone, Ty: EdgeType, Ix: IndexType> Widget + for &mut GraphView<'a, N, E, Ty, Ix> +{ fn ui(self, ui: &mut Ui) -> Response { let (resp, p) = ui.allocate_painter(ui.available_size(), Sense::click_and_drag()); @@ -74,10 +77,10 @@ impl<'a, N: Clone, E: Clone, Ty: EdgeType> Widget for &mut GraphView<'a, N, E, T } } -impl<'a, N: Clone, E: Clone, Ty: EdgeType> GraphView<'a, N, E, Ty> { +impl<'a, N: Clone, E: Clone, Ty: EdgeType, Ix: IndexType> GraphView<'a, N, E, Ty, Ix> { /// Creates a new `GraphView` widget with default navigation and interactions settings. /// To customize navigation and interactions use `with_interactions` and `with_navigations` methods. - pub fn new(g: &'a mut Graph) -> Self { + pub fn new(g: &'a mut Graph) -> Self { Self { g, @@ -94,13 +97,13 @@ impl<'a, N: Clone, E: Clone, Ty: EdgeType> GraphView<'a, N, E, Ty> { } /// Sets a function that will be called instead of the default drawer for every node to draw custom shapes. - pub fn with_custom_node_draw(mut self, func: FnCustomNodeDraw) -> Self { + pub fn with_custom_node_draw(mut self, func: FnCustomNodeDraw) -> Self { self.custom_node_draw = Some(func); self } /// Sets a function that will be called instead of the default drawer for every pair of nodes connected with edges to draw custom shapes. - pub fn with_custom_edge_draw(mut self, func: FnCustomEdgeDraw) -> Self { + pub fn with_custom_edge_draw(mut self, func: FnCustomEdgeDraw) -> Self { self.custom_edge_draw = Some(func); self } @@ -134,8 +137,8 @@ impl<'a, N: Clone, E: Clone, Ty: EdgeType> GraphView<'a, N, E, Ty> { self } - fn compute_state(&mut self) -> ComputedState { - let mut computed = ComputedState::default(); + fn compute_state(&mut self) -> ComputedState { + let mut computed = ComputedState::::default(); let n_idxs = self.g.g.node_indices().collect::>(); n_idxs.iter().for_each(|idx| { @@ -152,7 +155,7 @@ impl<'a, N: Clone, E: Clone, Ty: EdgeType> GraphView<'a, N, E, Ty> { /// Fits the graph to the screen if it is the first frame or /// fit to screen setting is enabled; - fn handle_fit_to_screen(&self, r: &Response, meta: &mut Metadata, comp: &ComputedState) { + fn handle_fit_to_screen(&self, r: &Response, meta: &mut Metadata, comp: &ComputedState) { if !meta.first_frame && !self.settings_navigation.fit_to_screen_enabled { return; } @@ -161,7 +164,7 @@ impl<'a, N: Clone, E: Clone, Ty: EdgeType> GraphView<'a, N, E, Ty> { meta.first_frame = false; } - fn handle_click(&mut self, resp: &Response, meta: &mut Metadata, comp: &ComputedState) { + fn handle_click(&mut self, resp: &Response, meta: &mut Metadata, comp: &ComputedState) { if !resp.clicked() && !resp.double_clicked() { return; } @@ -198,7 +201,7 @@ impl<'a, N: Clone, E: Clone, Ty: EdgeType> GraphView<'a, N, E, Ty> { self.handle_node_click(node_idx, comp); } - fn handle_node_double_click(&mut self, idx: NodeIndex) { + fn handle_node_double_click(&mut self, idx: NodeIndex) { if !self.settings_interaction.clicking_enabled { return; } @@ -208,7 +211,7 @@ impl<'a, N: Clone, E: Clone, Ty: EdgeType> GraphView<'a, N, E, Ty> { } } - fn handle_node_click(&mut self, idx: NodeIndex, comp: &ComputedState) { + fn handle_node_click(&mut self, idx: NodeIndex, comp: &ComputedState) { if !self.settings_interaction.clicking_enabled && !self.settings_interaction.selection_enabled { @@ -236,7 +239,12 @@ impl<'a, N: Clone, E: Clone, Ty: EdgeType> GraphView<'a, N, E, Ty> { self.select_node(idx); } - fn handle_node_drag(&mut self, resp: &Response, comp: &mut ComputedState, meta: &mut Metadata) { + fn handle_node_drag( + &mut self, + resp: &Response, + comp: &mut ComputedState, + meta: &mut Metadata, + ) { if !self.settings_interaction.dragging_enabled { return; } @@ -265,7 +273,7 @@ impl<'a, N: Clone, E: Clone, Ty: EdgeType> GraphView<'a, N, E, Ty> { } } - fn fit_to_screen(&self, rect: &Rect, meta: &mut Metadata, comp: &ComputedState) { + fn fit_to_screen(&self, rect: &Rect, meta: &mut Metadata, comp: &ComputedState) { // calculate graph dimensions with decorative padding let bounds = comp.graph_bounds(); let mut diag = bounds.max - bounds.min; @@ -306,7 +314,7 @@ impl<'a, N: Clone, E: Clone, Ty: EdgeType> GraphView<'a, N, E, Ty> { ui: &Ui, resp: &Response, meta: &mut Metadata, - comp: &ComputedState, + comp: &ComputedState, ) { self.handle_zoom(ui, resp, meta); self.handle_pan(resp, meta, comp); @@ -328,7 +336,7 @@ impl<'a, N: Clone, E: Clone, Ty: EdgeType> GraphView<'a, N, E, Ty> { }); } - fn handle_pan(&self, resp: &Response, meta: &mut Metadata, comp: &ComputedState) { + fn handle_pan(&self, resp: &Response, meta: &mut Metadata, comp: &ComputedState) { if !self.settings_navigation.zoom_and_pan_enabled { return; } @@ -359,7 +367,7 @@ impl<'a, N: Clone, E: Clone, Ty: EdgeType> GraphView<'a, N, E, Ty> { self.set_zoom(new_zoom, meta); } - fn select_node(&mut self, idx: NodeIndex) { + fn select_node(&mut self, idx: NodeIndex) { let n = self.g.node_mut(idx).unwrap(); n.set_selected(true); @@ -367,7 +375,7 @@ impl<'a, N: Clone, E: Clone, Ty: EdgeType> GraphView<'a, N, E, Ty> { self.publish_event(Event::NodeSelect(PayloadNodeSelect { id: idx.index() })); } - fn deselect_node(&mut self, idx: NodeIndex) { + fn deselect_node(&mut self, idx: NodeIndex) { let n = self.g.node_mut(idx).unwrap(); n.set_selected(false); @@ -376,26 +384,26 @@ impl<'a, N: Clone, E: Clone, Ty: EdgeType> GraphView<'a, N, E, Ty> { } #[allow(unused_variables)] - fn set_node_clicked(&mut self, idx: NodeIndex) { + fn set_node_clicked(&mut self, idx: NodeIndex) { #[cfg(feature = "events")] self.publish_event(Event::NodeClick(PayloadNodeClick { id: idx.index() })); } #[allow(unused_variables)] - fn set_node_double_clicked(&mut self, idx: NodeIndex) { + fn set_node_double_clicked(&mut self, idx: NodeIndex) { #[cfg(feature = "events")] self.publish_event(Event::NodeDoubleClick(PayloadNodeDoubleClick { id: idx.index(), })); } - fn deselect_all(&mut self, comp: &ComputedState) { + fn deselect_all(&mut self, comp: &ComputedState) { comp.selected.iter().for_each(|idx| { self.deselect_node(*idx); }); } - fn move_node(&mut self, idx: NodeIndex, delta: Vec2) { + fn move_node(&mut self, idx: NodeIndex, delta: Vec2) { let n = self.g.node_mut(idx).unwrap(); n.set_location(n.location() + delta); @@ -406,7 +414,7 @@ impl<'a, N: Clone, E: Clone, Ty: EdgeType> GraphView<'a, N, E, Ty> { })); } - fn set_drag_start(&mut self, idx: NodeIndex) { + fn set_drag_start(&mut self, idx: NodeIndex) { let n = self.g.node_mut(idx).unwrap(); n.set_dragged(true); @@ -416,7 +424,7 @@ impl<'a, N: Clone, E: Clone, Ty: EdgeType> GraphView<'a, N, E, Ty> { })); } - fn set_drag_end(&mut self, idx: NodeIndex) { + fn set_drag_end(&mut self, idx: NodeIndex) { let n = self.g.node_mut(idx).unwrap(); n.set_dragged(false); diff --git a/src/transform.rs b/src/transform.rs index 7a18294..a26bb37 100644 --- a/src/transform.rs +++ b/src/transform.rs @@ -1,6 +1,7 @@ use crate::{Edge, Graph, Node}; use egui::Vec2; use petgraph::{ + graph::IndexType, stable_graph::{EdgeIndex, NodeIndex, StableGraph}, visit::IntoNodeReferences, EdgeType, @@ -13,43 +14,49 @@ pub const DEFAULT_SPAWN_SIZE: f32 = 250.; /// Helper function which adds user's node to the [`super::Graph`] instance. /// /// If graph is not empty it picks any node position and adds new node in the vicinity of it. -pub fn add_node(g: &mut Graph, n: &N) -> NodeIndex { +pub fn add_node( + g: &mut Graph, + n: &N, +) -> NodeIndex { add_node_custom(g, n, default_node_transform) } /// Helper function which adds user's node to the [`super::Graph`] instance with custom node transform function. /// /// If graph is not empty it picks any node position and adds new node in the vicinity of it. -pub fn add_node_custom( - g: &mut Graph, +pub fn add_node_custom( + g: &mut Graph, n: &N, - node_transform: impl Fn(NodeIndex, &N) -> Node, -) -> NodeIndex { - g.g.add_node(node_transform(NodeIndex::new(g.g.node_count() + 1), n)) + node_transform: impl Fn(NodeIndex, &N) -> Node, +) -> NodeIndex { + g.g.add_node(node_transform( + NodeIndex::::new(g.g.node_count() + 1), + n, + )) } /// Helper function which adds user's edge to the [`super::Graph`] instance. -pub fn add_edge( - g: &mut Graph, - start: NodeIndex, - end: NodeIndex, +pub fn add_edge( + g: &mut Graph, + start: NodeIndex, + end: NodeIndex, e: &E, -) -> EdgeIndex { +) -> EdgeIndex { add_edge_custom(g, start, end, e, default_edge_transform) } /// Helper function which adds user's edge to the [`super::Graph`] instance with custom edge transform function. -pub fn add_edge_custom( - g: &mut Graph, - start: NodeIndex, - end: NodeIndex, +pub fn add_edge_custom( + g: &mut Graph, + start: NodeIndex, + end: NodeIndex, e: &E, - edge_transform: impl Fn(EdgeIndex, &E) -> Edge, -) -> EdgeIndex { + edge_transform: impl Fn(EdgeIndex, &E) -> Edge, +) -> EdgeIndex { g.g.add_edge( start, end, - edge_transform(EdgeIndex::new(g.g.edge_count() + 1), e), + edge_transform(EdgeIndex::::new(g.g.edge_count() + 1), e), ) } @@ -99,28 +106,30 @@ pub fn add_edge_custom( /// assert!(loc_1 != Vec2::ZERO); /// assert!(loc_2 != Vec2::ZERO); /// ``` -pub fn to_graph(g: &StableGraph) -> Graph { +pub fn to_graph( + g: &StableGraph, +) -> Graph { transform(g, default_node_transform, default_edge_transform) } /// The same as [`to_graph`], but allows to define custom transformation procedures for nodes and edges. -pub fn to_graph_custom( - g: &StableGraph, - node_transform: impl Fn(NodeIndex, &N) -> Node, - edge_transform: impl Fn(EdgeIndex, &E) -> Edge, -) -> Graph { +pub fn to_graph_custom( + g: &StableGraph, + node_transform: impl Fn(NodeIndex, &N) -> Node, + edge_transform: impl Fn(EdgeIndex, &E) -> Edge, +) -> Graph { transform(g, node_transform, edge_transform) } /// Default node transform function. Keeps original data and creates a new node with a random location and /// label equal to the index of the node in the graph. -pub fn default_node_transform(idx: NodeIndex, data: &N) -> Node { +pub fn default_node_transform(idx: NodeIndex, data: &N) -> Node { let loc = random_location(DEFAULT_SPAWN_SIZE); Node::new(loc, data.clone()).with_label(idx.index().to_string()) } /// Default edge transform function. Keeps original data and creates a new edge. -pub fn default_edge_transform(_: EdgeIndex, data: &E) -> Edge { +pub fn default_edge_transform(_: EdgeIndex, data: &E) -> Edge { Edge::new(data.clone()) } @@ -129,12 +138,12 @@ fn random_location(size: f32) -> Vec2 { Vec2::new(rng.gen_range(0. ..size), rng.gen_range(0. ..size)) } -fn transform( - g: &StableGraph, - node_transform: impl Fn(NodeIndex, &N) -> Node, - edge_transform: impl Fn(EdgeIndex, &E) -> Edge, -) -> Graph { - let mut input_g = StableGraph::, Edge, Ty>::default(); +fn transform( + g: &StableGraph, + node_transform: impl Fn(NodeIndex, &N) -> Node, + edge_transform: impl Fn(EdgeIndex, &E) -> Edge, +) -> Graph { + let mut input_g = StableGraph::, Edge, Ty, Ix>::default(); let input_by_user = g .node_references() @@ -142,7 +151,7 @@ fn transform( let input_n_index = input_g.add_node(node_transform(user_n_idx, user_n)); (user_n_idx, input_n_index) }) - .collect::>(); + .collect::, NodeIndex>>(); g.edge_indices().for_each(|user_e_idx| { let (user_source_n_idx, user_target_n_idx) = g.edge_endpoints(user_e_idx).unwrap();