Skip to content
This repository has been archived by the owner on Apr 9, 2024. It is now read-only.

Update to egui 0.21 & fix the interaction bug #85

Merged
merged 3 commits into from
May 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
/target
Cargo.lock
.idea
4 changes: 2 additions & 2 deletions egui_node_graph/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ workspace = ".."
persistence = ["serde", "slotmap/serde", "smallvec/serde", "egui/persistence"]

[dependencies]
egui = { version = "0.19.0" }
egui = { version = "0.21.0" }
slotmap = { version = "1.0" }
smallvec = { version = "1.7.0" }
smallvec = { version = "1.10.0" }
serde = { version = "1.0", optional = true, features = ["derive"] }
thiserror = "1.0"
78 changes: 52 additions & 26 deletions egui_node_graph/src/editor_ui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,9 @@ where
let editor_rect = ui.max_rect();
ui.allocate_rect(editor_rect, Sense::hover());

let cursor_pos = ui.ctx().input().pointer.hover_pos().unwrap_or(Pos2::ZERO);
let cursor_pos = ui
.ctx()
.input(|i| i.pointer.hover_pos().unwrap_or(Pos2::ZERO));
let mut cursor_in_editor = editor_rect.contains(cursor_pos);
let mut cursor_in_finder = false;

Expand All @@ -142,6 +144,17 @@ where
inconsistent self. It has either more or less values than the graph."
);

// Allocate rect before the nodes, otherwise this will block the interaction
// with the nodes.
let r = ui.allocate_rect(ui.min_rect(), Sense::click().union(Sense::drag()));
if r.clicked() {
click_on_background = true;
} else if r.drag_started() {
drag_started_on_background = true;
} else if r.drag_released() {
drag_released_on_background = true;
}

/* Draw nodes */
for node_id in self.node_order.iter().copied() {
let responses = GraphNodeWidget {
Expand All @@ -163,15 +176,6 @@ where
delayed_responses.extend(responses);
}

let r = ui.allocate_rect(ui.min_rect(), Sense::click().union(Sense::drag()));
if r.clicked() {
click_on_background = true;
} else if r.drag_started() {
drag_started_on_background = true;
} else if r.drag_released() {
drag_released_on_background = true;
}

/* Draw the node finder, if open */
let mut should_close_node_finder = false;
if let Some(ref mut node_finder) = self.node_finder {
Expand Down Expand Up @@ -395,7 +399,7 @@ where
/* Mouse input handling */

// This locks the context, so don't hold on to it for too long.
let mouse = &ui.ctx().input().pointer;
let mouse = &ui.ctx().input(|i| i.pointer.clone());

if mouse.any_released() && self.connection_in_progress.is_some() {
self.connection_in_progress = None;
Expand All @@ -404,12 +408,12 @@ where
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) {
if ui.ctx().input(|i| i.key_pressed(Key::Escape)) {
self.node_finder = None;
}

if r.dragged() && ui.ctx().input().pointer.middle_down() {
self.pan_zoom.pan += ui.ctx().input().pointer.delta();
if r.dragged() && ui.ctx().input(|i| i.pointer.middle_down()) {
self.pan_zoom.pan += ui.ctx().input(|i| i.pointer.delta());
}

// Deselect and deactivate finder if the editor backround is clicked,
Expand Down Expand Up @@ -451,6 +455,9 @@ fn draw_connection(painter: &Painter, src_pos: Pos2, dst_pos: Pos2, color: Color
painter.add(bezier);
}

#[derive(Clone, Copy, Debug)]
struct OuterRectMemory(Rect);

impl<'a, NodeData, DataType, ValueType, UserResponse, UserState>
GraphNodeWidget<'a, NodeData, DataType, ValueType>
where
Expand Down Expand Up @@ -508,13 +515,32 @@ where
let background_shape = ui.painter().add(Shape::Noop);

let outer_rect_bounds = ui.available_rect_before_wrap();

let mut inner_rect = outer_rect_bounds.shrink2(margin);

// Make sure we don't shrink to the negative:
inner_rect.max.x = inner_rect.max.x.max(inner_rect.min.x);
inner_rect.max.y = inner_rect.max.y.max(inner_rect.min.y);

let mut child_ui = ui.child_ui(inner_rect, *ui.layout());

// Get interaction rect from memory, it may expand after the window response on resize.
let interaction_rect = ui
.ctx()
.memory_mut(|mem| {
mem.data
.get_temp::<OuterRectMemory>(child_ui.id())
.map(|stored| stored.0)
})
.unwrap_or(outer_rect_bounds);
// After 0.20, layers added over others can block hover interaction. Call this first
// before creating the node content.
let window_response = ui.interact(
interaction_rect,
Id::new((self.node_id, "window")),
Sense::click_and_drag(),
);

let mut title_height = 0.0;

let mut input_port_heights = vec![];
Expand Down Expand Up @@ -586,6 +612,12 @@ where
let port_left = outer_rect.left();
let port_right = outer_rect.right();

// Save expanded rect to memory.
ui.ctx().memory_mut(|mem| {
mem.data
.insert_temp(child_ui.id(), OuterRectMemory(outer_rect))
});

#[allow(clippy::too_many_arguments)]
fn draw_port<NodeData, DataType, ValueType, UserResponse, UserState>(
ui: &mut Ui,
Expand Down Expand Up @@ -628,7 +660,7 @@ where
port_type.data_type_color(user_state)
};
ui.painter()
.circle(port_rect.center(), 5.0, port_color, Stroke::none());
.circle(port_rect.center(), 5.0, port_color, Stroke::NONE);

if resp.drag_started() {
if is_connected_input {
Expand All @@ -650,7 +682,7 @@ where
// Don't allow self-loops
if graph.any_param_type(origin_param).unwrap() == port_type
&& close_enough
&& ui.input().pointer.any_released()
&& ui.input(|i| i.pointer.any_released())
{
match (param_id, origin_param) {
(AnyParameterId::Input(input), AnyParameterId::Output(output))
Expand Down Expand Up @@ -734,7 +766,7 @@ where
.user_data
.titlebar_color(ui, self.node_id, self.graph, user_state)
.unwrap_or_else(|| background_color.lighten(0.8)),
stroke: Stroke::none(),
stroke: Stroke::NONE,
});

let body_rect = Rect::from_min_size(
Expand All @@ -745,7 +777,7 @@ where
rect: body_rect,
rounding: Rounding::none(),
fill: background_color,
stroke: Stroke::none(),
stroke: Stroke::NONE,
});

let bottom_body_rect = Rect::from_min_size(
Expand All @@ -756,7 +788,7 @@ where
rect: bottom_body_rect,
rounding,
fill: background_color,
stroke: Stroke::none(),
stroke: Stroke::NONE,
});

let node_rect = titlebar_rect.union(body_rect).union(bottom_body_rect);
Expand All @@ -765,7 +797,7 @@ where
rect: node_rect.expand(1.0),
rounding,
fill: Color32::WHITE.lighten(0.8),
stroke: Stroke::none(),
stroke: Stroke::NONE,
})
} else {
Shape::Noop
Expand Down Expand Up @@ -793,12 +825,6 @@ where
responses.push(NodeResponse::DeleteNodeUi(self.node_id));
};

let window_response = ui.interact(
outer_rect,
Id::new((self.node_id, "window")),
Sense::click_and_drag(),
);

// Movement
let drag_delta = window_response.drag_delta();
if drag_delta.length_sq() > 0.0 {
Expand Down
4 changes: 2 additions & 2 deletions egui_node_graph/src/node_finder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,9 @@ where
self.just_spawned = false;
}

let mut query_submit = resp.lost_focus() && ui.input().key_down(Key::Enter);
let mut query_submit = resp.lost_focus() && ui.input(|i| i.key_pressed(Key::Enter));

let max_height = ui.input().screen_rect.height() * 0.5;
let max_height = ui.input(|i| i.screen_rect.height() * 0.5);
let scroll_area_width = resp.rect.width() - 30.0;

Frame::default()
Expand Down
2 changes: 1 addition & 1 deletion egui_node_graph_example/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ rust-version = "1.56"
crate-type = ["cdylib", "rlib"]

[dependencies]
eframe = "0.19.0"
eframe = "0.21.0"
egui_node_graph = { path = "../egui_node_graph" }
anyhow = "1.0"
serde = { version = "1.0", optional = true }
Expand Down
3 changes: 2 additions & 1 deletion egui_node_graph_example/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,6 @@ fn main() {
#[cfg(not(feature = "persistence"))]
Box::new(egui_node_graph_example::NodeGraphExample::default())
}),
);
)
.expect("Failed to run native example");
}