From 2607f557461fc3a2c421a6efe4fc4c9559a1590c Mon Sep 17 00:00:00 2001 From: Setzer22 Date: Sun, 13 Nov 2022 15:54:24 +0100 Subject: [PATCH 1/6] Fix mouse-related bugs - The box selection should only be activated by the primary mouse - Now that egui finally supports it, make the node finder trigger be a mouse click, not a "mouse down". This prevents a weird behavior where you could drag around the node finder when clicking and dragging with the left mouse button --- egui_node_graph/src/editor_ui.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/egui_node_graph/src/editor_ui.rs b/egui_node_graph/src/editor_ui.rs index 8af69f2..87cae96 100644 --- a/egui_node_graph/src/editor_ui.rs +++ b/egui_node_graph/src/editor_ui.rs @@ -112,7 +112,7 @@ where // Gets filled with the node metrics as they are drawn let mut port_locations = PortLocations::new(); - let mut node_sizes = NodeRects::new(); + let mut node_rects = NodeRects::new(); // The responses returned from node drawing have side effects that are best // executed at the end of this function. @@ -138,7 +138,7 @@ where position: self.node_positions.get_mut(node_id).unwrap(), graph: &mut self.graph, port_locations: &mut port_locations, - node_rects: &mut node_sizes, + node_rects: &mut node_rects, node_id, ongoing_drag: self.connection_in_progress, selected: self @@ -365,7 +365,7 @@ where Stroke::new(3.0, stroke_color), ); - self.selected_nodes = node_sizes + self.selected_nodes = node_rects .into_iter() .filter_map(|(node_id, rect)| { if selection_rect.intersects(rect) { @@ -391,7 +391,7 @@ where self.connection_in_progress = None; } - if mouse.secondary_down() && cursor_in_editor && !cursor_in_finder { + if mouse.secondary_clicked() && cursor_in_editor && !cursor_in_finder { self.node_finder = Some(NodeFinder::new_at(cursor_pos)); } if ui.ctx().input().key_pressed(Key::Escape) { @@ -409,7 +409,7 @@ where self.node_finder = None; } - if drag_started_on_background { + if drag_started_on_background && mouse.primary_down() { self.ongoing_box_selection = Some(cursor_pos); } if mouse.primary_released() || drag_released_on_background { From 9f7826ae95b8ce392156c6ee85dca430863f4b0b Mon Sep 17 00:00:00 2001 From: Setzer22 Date: Sun, 13 Nov 2022 16:05:46 +0100 Subject: [PATCH 2/6] Add a scrollbar to the node finder --- egui_node_graph/src/node_finder.rs | 34 ++++++++++++++++++------------ 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/egui_node_graph/src/node_finder.rs b/egui_node_graph/src/node_finder.rs index 6bb77d7..87a9596 100644 --- a/egui_node_graph/src/node_finder.rs +++ b/egui_node_graph/src/node_finder.rs @@ -65,23 +65,31 @@ where let mut query_submit = resp.lost_focus() && ui.input().key_down(Key::Enter); + let max_height = ui.input().screen_rect.height() * 0.5; + let scroll_area_width = resp.rect.width() - 30.0; + 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(user_state).to_string(); - if kind_name - .to_lowercase() - .contains(self.query.to_lowercase().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; + ScrollArea::vertical() + .max_height(max_height) + .show(ui, |ui| { + ui.set_width(scroll_area_width); + for kind in all_kinds.all_kinds() { + let kind_name = kind.node_finder_label(user_state).to_string(); + if kind_name + .to_lowercase() + .contains(self.query.to_lowercase().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; + } + } } - } - } + }); }); }); }); From 50b2ff94b218d82a50062e3314f2e8d843c6942f Mon Sep 17 00:00:00 2001 From: Setzer22 Date: Tue, 15 Nov 2022 18:55:34 +0100 Subject: [PATCH 3/6] Expose cursor_in_editor and cursor_in_finder --- egui_node_graph/src/editor_ui.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/egui_node_graph/src/editor_ui.rs b/egui_node_graph/src/editor_ui.rs index 87cae96..636614a 100644 --- a/egui_node_graph/src/editor_ui.rs +++ b/egui_node_graph/src/editor_ui.rs @@ -51,7 +51,15 @@ pub enum NodeResponse /// user code react to specific events that happened when drawing the graph. #[derive(Clone, Debug)] pub struct GraphResponse { + /// Events that occurred during this frame of rendering the graph. Check the + /// [`UserResponse`] type for a description of each event. pub node_responses: Vec>, + /// Is the mouse currently hovering the graph editor? Note that the node + /// finder is considered part of the graph editor, even when it floats + /// outside the graph editor rect. + pub cursor_in_editor: bool, + /// Is the mouse currently hovering the node finder? + pub cursor_in_finder: bool, } impl Default for GraphResponse @@ -59,6 +67,8 @@ impl Default fn default() -> Self { Self { node_responses: Default::default(), + cursor_in_editor: false, + cursor_in_finder: false, } } } @@ -418,6 +428,8 @@ where GraphResponse { node_responses: delayed_responses, + cursor_in_editor, + cursor_in_finder, } } } From 1f79e61a72792651ada11eaad70416cfe7457365 Mon Sep 17 00:00:00 2001 From: Setzer22 Date: Tue, 15 Nov 2022 19:06:33 +0100 Subject: [PATCH 4/6] Fix bug in `cursor_in_finder` computation --- egui_node_graph/src/editor_ui.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/egui_node_graph/src/editor_ui.rs b/egui_node_graph/src/editor_ui.rs index 636614a..1f1fd26 100644 --- a/egui_node_graph/src/editor_ui.rs +++ b/egui_node_graph/src/editor_ui.rs @@ -196,9 +196,9 @@ where 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 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) { + if finder_rect.contains(cursor_pos) { cursor_in_editor = true; cursor_in_finder = true; } From 70b60071acd52141bb2bd63db09eb642315ce285 Mon Sep 17 00:00:00 2001 From: Setzer22 Date: Tue, 15 Nov 2022 19:33:07 +0100 Subject: [PATCH 5/6] Hack to fix node finder focus --- egui_node_graph/src/node_finder.rs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/egui_node_graph/src/node_finder.rs b/egui_node_graph/src/node_finder.rs index 87a9596..6b6f9e5 100644 --- a/egui_node_graph/src/node_finder.rs +++ b/egui_node_graph/src/node_finder.rs @@ -10,7 +10,7 @@ pub struct NodeFinder { pub query: String, /// Reset every frame. When set, the node finder will be moved at that position pub position: Option, - pub just_spawned: bool, + pub frames_since_spawned: u32, _phantom: PhantomData, } @@ -22,7 +22,7 @@ where NodeFinder { query: "".into(), position: Some(pos), - just_spawned: true, + frames_since_spawned: 0, _phantom: Default::default(), } } @@ -58,9 +58,13 @@ where frame.show(ui, |ui| { ui.vertical(|ui| { let resp = ui.text_edit_singleline(&mut self.query); - if self.just_spawned { + // HACK: The request_focus call doesn't succeed if we do it + // right after spawning the node finder, so we do it for a few + // frames until it works. This is could be a bug inside egui. + // The value 3 is the smallest number of frames that works. + if self.frames_since_spawned <= 3 { resp.request_focus(); - self.just_spawned = false; + self.frames_since_spawned += 1; } let mut query_submit = resp.lost_focus() && ui.input().key_down(Key::Enter); From f4009fccc92a5f2132109a661e9bb57cc38b7e51 Mon Sep 17 00:00:00 2001 From: Setzer22 Date: Tue, 15 Nov 2022 19:41:03 +0100 Subject: [PATCH 6/6] No more hack --- egui_node_graph/src/editor_ui.rs | 4 ++-- egui_node_graph/src/node_finder.rs | 12 ++++-------- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/egui_node_graph/src/editor_ui.rs b/egui_node_graph/src/editor_ui.rs index 1f1fd26..d7f90c5 100644 --- a/egui_node_graph/src/editor_ui.rs +++ b/egui_node_graph/src/editor_ui.rs @@ -195,7 +195,7 @@ where should_close_node_finder = true; delayed_responses.push(NodeResponse::CreatedNode(new_node)); } - let finder_rect = ui.max_rect(); + let finder_rect = ui.min_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 finder_rect.contains(cursor_pos) { @@ -401,7 +401,7 @@ where self.connection_in_progress = None; } - if mouse.secondary_clicked() && cursor_in_editor && !cursor_in_finder { + if mouse.secondary_released() && cursor_in_editor && !cursor_in_finder { self.node_finder = Some(NodeFinder::new_at(cursor_pos)); } if ui.ctx().input().key_pressed(Key::Escape) { diff --git a/egui_node_graph/src/node_finder.rs b/egui_node_graph/src/node_finder.rs index 6b6f9e5..87a9596 100644 --- a/egui_node_graph/src/node_finder.rs +++ b/egui_node_graph/src/node_finder.rs @@ -10,7 +10,7 @@ pub struct NodeFinder { pub query: String, /// Reset every frame. When set, the node finder will be moved at that position pub position: Option, - pub frames_since_spawned: u32, + pub just_spawned: bool, _phantom: PhantomData, } @@ -22,7 +22,7 @@ where NodeFinder { query: "".into(), position: Some(pos), - frames_since_spawned: 0, + just_spawned: true, _phantom: Default::default(), } } @@ -58,13 +58,9 @@ where frame.show(ui, |ui| { ui.vertical(|ui| { let resp = ui.text_edit_singleline(&mut self.query); - // HACK: The request_focus call doesn't succeed if we do it - // right after spawning the node finder, so we do it for a few - // frames until it works. This is could be a bug inside egui. - // The value 3 is the smallest number of frames that works. - if self.frames_since_spawned <= 3 { + if self.just_spawned { resp.request_focus(); - self.frames_since_spawned += 1; + self.just_spawned = false; } let mut query_submit = resp.lost_focus() && ui.input().key_down(Key::Enter);