From bf866238663b553d5a037a0ef034e6988ee60b3b Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Sat, 2 Apr 2022 14:05:16 +0200 Subject: [PATCH 1/6] Update to egui 0.17 --- egui_node_graph/Cargo.toml | 2 +- egui_node_graph/src/editor_ui.rs | 15 ++++++++------- egui_node_graph_example/Cargo.toml | 2 +- egui_node_graph_example/src/app.rs | 6 +++--- 4 files changed, 13 insertions(+), 12 deletions(-) diff --git a/egui_node_graph/Cargo.toml b/egui_node_graph/Cargo.toml index 6b54af4..e204600 100644 --- a/egui_node_graph/Cargo.toml +++ b/egui_node_graph/Cargo.toml @@ -15,7 +15,7 @@ workspace = ".." persistence = ["serde", "slotmap/serde", "smallvec/serde", "egui/persistence"] [dependencies] -egui = { version = "0.16" } +egui = { version = "0.17" } slotmap = { version = "1.0" } smallvec = { version = "1.7.0" } serde = { version = "1.0", optional = true, features = ["derive"] } diff --git a/egui_node_graph/src/editor_ui.rs b/egui_node_graph/src/editor_ui.rs index 2d0d68e..449159a 100644 --- a/egui_node_graph/src/editor_ui.rs +++ b/egui_node_graph/src/editor_ui.rs @@ -60,7 +60,7 @@ where #[must_use] pub fn draw_graph_editor( &mut self, - ctx: &CtxRef, + ctx: &Context, all_kinds: impl NodeTemplateIter, ) -> GraphResponse { let mouse = &ctx.input().pointer; @@ -467,25 +467,26 @@ where // does not support drawing rectangles with asymmetrical round corners. let (shape, outline) = { - let corner_radius = 4.0; + let rounding_radius = 4.0; + let rounding = Rounding::same(rounding_radius); let titlebar_height = title_height + margin.y; let titlebar_rect = Rect::from_min_size(outer_rect.min, vec2(outer_rect.width(), titlebar_height)); let titlebar = Shape::Rect(RectShape { rect: titlebar_rect, - corner_radius, + rounding, fill: titlebar_color, stroke: Stroke::none(), }); let body_rect = Rect::from_min_size( - outer_rect.min + vec2(0.0, titlebar_height - corner_radius), + outer_rect.min + vec2(0.0, titlebar_height - rounding_radius), vec2(outer_rect.width(), outer_rect.height() - titlebar_height), ); let body = Shape::Rect(RectShape { rect: body_rect, - corner_radius: 0.0, + rounding: Rounding::none(), fill: background_color, stroke: Stroke::none(), }); @@ -496,7 +497,7 @@ where ); let bottom_body = Shape::Rect(RectShape { rect: bottom_body_rect, - corner_radius, + rounding, fill: background_color, stroke: Stroke::none(), }); @@ -507,7 +508,7 @@ where .union(body_rect) .union(bottom_body_rect) .expand(1.0), - corner_radius: 4.0, + rounding, fill: Color32::WHITE.lighten(0.8), stroke: Stroke::none(), }) diff --git a/egui_node_graph_example/Cargo.toml b/egui_node_graph_example/Cargo.toml index 6e4816d..e74a6f0 100644 --- a/egui_node_graph_example/Cargo.toml +++ b/egui_node_graph_example/Cargo.toml @@ -9,7 +9,7 @@ rust-version = "1.56" crate-type = ["cdylib", "rlib"] [dependencies] -eframe = "0.16.0" +eframe = "0.17.0" egui_node_graph = { path = "../egui_node_graph" } anyhow = "1.0" diff --git a/egui_node_graph_example/src/app.rs b/egui_node_graph_example/src/app.rs index ac60aba..ec5b511 100644 --- a/egui_node_graph_example/src/app.rs +++ b/egui_node_graph_example/src/app.rs @@ -1,7 +1,7 @@ use std::collections::HashMap; use eframe::{ - egui::{self, DragValue}, + egui::{self, DragValue, TextStyle}, epi, }; use egui_node_graph::*; @@ -359,7 +359,7 @@ impl epi::App for NodeGraphExample { /// Called each time the UI needs repainting, which may be many times per second. /// Put your widgets into a `SidePanel`, `TopPanel`, `CentralPanel`, `Window` or `Area`. - fn update(&mut self, ctx: &egui::CtxRef, _frame: &epi::Frame) { + fn update(&mut self, ctx: &egui::Context, _frame: &epi::Frame) { let graph_response = self.state.draw_graph_editor(ctx, AllMyNodeTemplates); for node_response in graph_response.node_responses { // Here, we ignore all other graph events. But you may find @@ -384,7 +384,7 @@ impl epi::App for NodeGraphExample { egui::pos2(10.0, 10.0), egui::Align2::LEFT_TOP, text, - egui::TextStyle::Button, + TextStyle::Button.resolve(&ctx.style()), egui::Color32::WHITE, ); } From 441f7856ee366416907be386800c85d9846b7709 Mon Sep 17 00:00:00 2001 From: nodeSpace <28955991+nodeSpace@users.noreply.github.com> Date: Tue, 5 Apr 2022 23:28:59 -0400 Subject: [PATCH 2/6] Make editor ui work inside windows. Fix for #4 --- egui_node_graph/src/editor_ui.rs | 64 +++++++++++++++++++------------- 1 file changed, 39 insertions(+), 25 deletions(-) diff --git a/egui_node_graph/src/editor_ui.rs b/egui_node_graph/src/editor_ui.rs index 2d0d68e..c79e893 100644 --- a/egui_node_graph/src/editor_ui.rs +++ b/egui_node_graph/src/editor_ui.rs @@ -61,10 +61,18 @@ where pub fn draw_graph_editor( &mut self, ctx: &CtxRef, + ui: &mut Ui, all_kinds: impl NodeTemplateIter, ) -> GraphResponse { + // This causes the graph editor to use as much free space as it can. + // (so for windows it will use up to the resizeably set limit + // and for a Panel it will fill it completely) + let editor_rect = ui.max_rect(); + ui.allocate_rect(editor_rect, Sense::hover()); + let mouse = &ctx.input().pointer; let cursor_pos = mouse.hover_pos().unwrap_or(Pos2::ZERO); + let mut cursor_in_editor = editor_rect.contains(cursor_pos); // Gets filled with the port locations as nodes are drawn let mut port_locations = PortLocations::new(); @@ -83,32 +91,30 @@ where inconsistent self. It has either more or less values than the graph." ); - CentralPanel::default().show(ctx, |ui| { - /* Draw nodes */ - for node_id in self.node_order.iter().copied() { - let responses = GraphNodeWidget { - position: self.node_positions.get_mut(node_id).unwrap(), - graph: &mut self.graph, - port_locations: &mut port_locations, - node_id, - ongoing_drag: self.connection_in_progress, - selected: self - .selected_node - .map(|selected| selected == node_id) - .unwrap_or(false), - pan: self.pan_zoom.pan, - } + /* Draw nodes */ + for node_id in self.node_order.iter().copied() { + let responses = GraphNodeWidget { + position: self.node_positions.get_mut(node_id).unwrap(), + graph: &mut self.graph, + port_locations: &mut port_locations, + node_id, + ongoing_drag: self.connection_in_progress, + selected: self + .selected_node + .map(|selected| selected == node_id) + .unwrap_or(false), + pan: self.pan_zoom.pan, + } .show(ui, &self.user_state); - // Actions executed later - delayed_responses.extend(responses); - } + // Actions executed later + delayed_responses.extend(responses); + } - let r = ui.allocate_rect(ui.min_rect(), Sense::click()); - if r.clicked() { - click_on_background = true; - } - }); + let r = ui.allocate_rect(ui.min_rect(), Sense::click()); + if r.clicked() { + click_on_background = true; + } /* Draw the node finder, if open */ let mut should_close_node_finder = false; @@ -131,6 +137,12 @@ where should_close_node_finder = true; delayed_responses.push(NodeResponse::CreatedNode(new_node)); } + let finder_rect = ui.max_rect(); + // If the cursor is not in the main editor, check if the cursor *is* in the finder + // if the cursor is in the finder, then we can consider that also in the editor. + if !cursor_in_editor && finder_rect.contains(cursor_pos){ + cursor_in_editor = true; + } }); } if should_close_node_finder { @@ -228,7 +240,7 @@ where self.connection_in_progress = None; } - if mouse.button_down(PointerButton::Secondary) { + if mouse.button_down(PointerButton::Secondary) && cursor_in_editor{ self.node_finder = Some(NodeFinder::new_at(cursor_pos)); } if ctx.input().key_pressed(Key::Escape) { @@ -239,7 +251,9 @@ where self.pan_zoom.pan += ctx.input().pointer.delta(); } - if click_on_background { + // Deselect and deactivate finder if the editor backround is clicked, + // *or* if the the mouse clicks off the ui + if click_on_background || (mouse.any_click() && !cursor_in_editor){ self.selected_node = None; self.node_finder = None; } From 45adcf7dc973b34f58436e3962cb85e8efc3996d Mon Sep 17 00:00:00 2001 From: nodeSpace <28955991+nodeSpace@users.noreply.github.com> Date: Wed, 6 Apr 2022 01:15:16 -0400 Subject: [PATCH 3/6] Fixed connection lines not displaying properly --- egui_node_graph/src/editor_ui.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/egui_node_graph/src/editor_ui.rs b/egui_node_graph/src/editor_ui.rs index c79e893..727c3e1 100644 --- a/egui_node_graph/src/editor_ui.rs +++ b/egui_node_graph/src/editor_ui.rs @@ -156,16 +156,14 @@ where }; if let Some((_, ref locator)) = self.connection_in_progress { - let painter = ctx.layer_painter(LayerId::background()); let start_pos = port_locations[locator]; - painter.line_segment([start_pos, cursor_pos], connection_stroke) + ui.painter().line_segment([start_pos, cursor_pos], connection_stroke) } for (input, output) in self.graph.iter_connections() { - let painter = ctx.layer_painter(LayerId::background()); let src_pos = port_locations[&AnyParameterId::Output(output)]; let dst_pos = port_locations[&AnyParameterId::Input(input)]; - painter.line_segment([src_pos, dst_pos], connection_stroke); + ui.painter().line_segment([src_pos, dst_pos], connection_stroke); } /* Handle responses from drawing nodes */ From a4730360378c37c90e838c893536fc8474d0ea54 Mon Sep 17 00:00:00 2001 From: nodeSpace <28955991+nodeSpace@users.noreply.github.com> Date: Fri, 15 Apr 2022 01:22:37 -0400 Subject: [PATCH 4/6] Fix for editor contents not moving with window --- egui_node_graph/src/editor_ui.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/egui_node_graph/src/editor_ui.rs b/egui_node_graph/src/editor_ui.rs index 727c3e1..ef63599 100644 --- a/egui_node_graph/src/editor_ui.rs +++ b/egui_node_graph/src/editor_ui.rs @@ -103,7 +103,7 @@ where .selected_node .map(|selected| selected == node_id) .unwrap_or(false), - pan: self.pan_zoom.pan, + pan: self.pan_zoom.pan + editor_rect.min.to_vec2(), } .show(ui, &self.user_state); From 0442d63cb480ab4f063a472a6d7d178f27422f4b Mon Sep 17 00:00:00 2001 From: nodeSpace <28955991+nodeSpace@users.noreply.github.com> Date: Fri, 15 Apr 2022 01:51:00 -0400 Subject: [PATCH 5/6] fix node spawn location bug introduced by last fix --- egui_node_graph/src/editor_ui.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/egui_node_graph/src/editor_ui.rs b/egui_node_graph/src/editor_ui.rs index ef63599..6fb8e1d 100644 --- a/egui_node_graph/src/editor_ui.rs +++ b/egui_node_graph/src/editor_ui.rs @@ -130,8 +130,10 @@ where node_kind.user_data(), |graph, node_id| node_kind.build_node(graph, node_id), ); - self.node_positions - .insert(new_node, cursor_pos - self.pan_zoom.pan); + self.node_positions.insert( + new_node, + cursor_pos - self.pan_zoom.pan - editor_rect.min.to_vec2() + ); self.node_order.push(new_node); should_close_node_finder = true; From 0ca71cec86b02db2af9c987c55eddab9b1602ceb Mon Sep 17 00:00:00 2001 From: Greg Morenz Date: Mon, 9 May 2022 19:10:00 -0400 Subject: [PATCH 6/6] Update to egui 0.18 --- egui_node_graph/Cargo.toml | 2 +- egui_node_graph/src/editor_ui.rs | 6 ++++-- egui_node_graph/src/node_finder.rs | 26 ++++++++++++++------------ egui_node_graph_example/Cargo.toml | 2 +- egui_node_graph_example/src/app.rs | 13 +++---------- egui_node_graph_example/src/main.rs | 13 ++++++++++--- 6 files changed, 33 insertions(+), 29 deletions(-) diff --git a/egui_node_graph/Cargo.toml b/egui_node_graph/Cargo.toml index e204600..2f9e94d 100644 --- a/egui_node_graph/Cargo.toml +++ b/egui_node_graph/Cargo.toml @@ -15,7 +15,7 @@ workspace = ".." persistence = ["serde", "slotmap/serde", "smallvec/serde", "egui/persistence"] [dependencies] -egui = { version = "0.17" } +egui = { version = "0.18" } slotmap = { version = "1.0" } smallvec = { version = "1.7.0" } serde = { version = "1.0", optional = true, features = ["derive"] } diff --git a/egui_node_graph/src/editor_ui.rs b/egui_node_graph/src/editor_ui.rs index 449159a..3ea4005 100644 --- a/egui_node_graph/src/editor_ui.rs +++ b/egui_node_graph/src/editor_ui.rs @@ -63,8 +63,7 @@ where ctx: &Context, all_kinds: impl NodeTemplateIter, ) -> GraphResponse { - let mouse = &ctx.input().pointer; - let cursor_pos = mouse.hover_pos().unwrap_or(Pos2::ZERO); + let cursor_pos = ctx.input().pointer.hover_pos().unwrap_or(Pos2::ZERO); // Gets filled with the port locations as nodes are drawn let mut port_locations = PortLocations::new(); @@ -224,6 +223,9 @@ where /* Mouse input handling */ + // This locks the context, so don't hold on to it for too long. + let mouse = &ctx.input().pointer; + if mouse.any_released() && self.connection_in_progress.is_some() { self.connection_in_progress = None; } diff --git a/egui_node_graph/src/node_finder.rs b/egui_node_graph/src/node_finder.rs index 36f925a..5213c57 100644 --- a/egui_node_graph/src/node_finder.rs +++ b/egui_node_graph/src/node_finder.rs @@ -41,7 +41,7 @@ where let frame = Frame::dark_canvas(ui.style()) .fill(background_color) - .margin(vec2(5.0, 5.0)); + .inner_margin(vec2(5.0, 5.0)); // The archetype that will be returned. let mut submitted_archetype = None; @@ -55,19 +55,21 @@ where let mut query_submit = resp.lost_focus() && ui.input().key_down(Key::Enter); - Frame::default().margin(vec2(10.0, 10.0)).show(ui, |ui| { - for kind in all_kinds.all_kinds() { - let kind_name = kind.node_finder_label().to_string(); - if kind_name.contains(self.query.as_str()) { - if ui.selectable_label(false, kind_name).clicked() { - submitted_archetype = Some(kind); - } else if query_submit { - submitted_archetype = Some(kind); - query_submit = false; + Frame::default() + .inner_margin(vec2(10.0, 10.0)) + .show(ui, |ui| { + for kind in all_kinds.all_kinds() { + let kind_name = kind.node_finder_label().to_string(); + if kind_name.contains(self.query.as_str()) { + if ui.selectable_label(false, kind_name).clicked() { + submitted_archetype = Some(kind); + } else if query_submit { + submitted_archetype = Some(kind); + query_submit = false; + } } } - } - }); + }); }); }); diff --git a/egui_node_graph_example/Cargo.toml b/egui_node_graph_example/Cargo.toml index e74a6f0..2d875a4 100644 --- a/egui_node_graph_example/Cargo.toml +++ b/egui_node_graph_example/Cargo.toml @@ -9,7 +9,7 @@ rust-version = "1.56" crate-type = ["cdylib", "rlib"] [dependencies] -eframe = "0.17.0" +eframe = "0.18.0" egui_node_graph = { path = "../egui_node_graph" } anyhow = "1.0" diff --git a/egui_node_graph_example/src/app.rs b/egui_node_graph_example/src/app.rs index ec5b511..f3a41fe 100644 --- a/egui_node_graph_example/src/app.rs +++ b/egui_node_graph_example/src/app.rs @@ -1,9 +1,6 @@ use std::collections::HashMap; -use eframe::{ - egui::{self, DragValue, TextStyle}, - epi, -}; +use eframe::egui::{self, DragValue, TextStyle}; use egui_node_graph::*; // ========= First, define your user data types ============= @@ -352,14 +349,10 @@ impl Default for NodeGraphExample { } } -impl epi::App for NodeGraphExample { - fn name(&self) -> &str { - "Egui node graph example" - } - +impl eframe::App for NodeGraphExample { /// Called each time the UI needs repainting, which may be many times per second. /// Put your widgets into a `SidePanel`, `TopPanel`, `CentralPanel`, `Window` or `Area`. - fn update(&mut self, ctx: &egui::Context, _frame: &epi::Frame) { + fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) { let graph_response = self.state.draw_graph_editor(ctx, AllMyNodeTemplates); for node_response in graph_response.node_responses { // Here, we ignore all other graph events. But you may find diff --git a/egui_node_graph_example/src/main.rs b/egui_node_graph_example/src/main.rs index 7479fad..489443a 100644 --- a/egui_node_graph_example/src/main.rs +++ b/egui_node_graph_example/src/main.rs @@ -5,7 +5,14 @@ // When compiling natively: #[cfg(not(target_arch = "wasm32"))] fn main() { - let app = egui_node_graph_example::NodeGraphExample::default(); - let native_options = eframe::NativeOptions::default(); - eframe::run_native(Box::new(app), native_options); + use eframe::egui::Visuals; + + eframe::run_native( + "Egui node graph example", + eframe::NativeOptions::default(), + Box::new(|cc| { + cc.egui_ctx.set_visuals(Visuals::dark()); + Box::new(egui_node_graph_example::NodeGraphExample::default()) + }), + ); }