graphview: Do not crash when the position of a node not on the graph is requested

While the position of a node not on the graph should never be requested, this seems to occur sometimes,
so instead of panicking, we only log an error now, or ignore that node if it wasn't
important.
This commit is contained in:
Tom A. Wagner
2021-09-11 15:03:03 +02:00
parent da5da90352
commit 497da8b953

View File

@@ -62,12 +62,17 @@ mod imp {
} else if let Some(target) = target.ancestor(Node::static_type()) {
// The user targeted a Node without targeting a specific Port.
// Drag the Node around the screen.
let (x, y) = widget.get_node_position(&target);
if let Some((x, y)) = widget.get_node_position(&target) {
Some((target, x, y))
} else {
error!("Failed to obtain position of dragged node, drag aborted.");
None
}
} else {
None
}
}));
}
));
drag_controller.connect_drag_update(
clone!(@strong drag_state => move |drag_controller, x, y| {
let widget = drag_controller
@@ -259,12 +264,12 @@ impl GraphView {
.nodes
.borrow()
.values()
.map(|node| {
//Map nodes to locations
.filter_map(|node| {
// Map nodes to locations, discard nodes without location
self.get_node_position(&node.clone().upcast())
})
.filter(|&(x2, _y)| {
//Only look in our column
.filter(|(x2, _)| {
// Only look for other nodes that have a similar x coordinate
(x - x2).abs() < 50.0
})
.max_by(|y1, y2| {
@@ -333,7 +338,10 @@ impl GraphView {
self.queue_draw();
}
pub(super) fn get_node_position(&self, node: &gtk::Widget) -> (f32, f32) {
/// Get the position of the specified node inside the graphview.
///
/// Returns `None` if the node is not in the graphview.
pub(super) fn get_node_position(&self, node: &gtk::Widget) -> Option<(f32, f32)> {
let layout_manager = self
.layout_manager()
.expect("Failed to get layout manager")
@@ -341,12 +349,13 @@ impl GraphView {
.expect("Failed to cast to FixedLayout");
let node = layout_manager
.layout_child(node)
.expect("Could not get layout child")
.layout_child(node)?
.dynamic_cast::<gtk::FixedLayoutChild>()
.expect("Could not cast to FixedLayoutChild");
let transform = node.transform().unwrap_or_default();
transform.to_translate()
let transform = node
.transform()
.expect("Failed to obtain transform from layout child");
Some(transform.to_translate())
}
pub(super) fn move_node(&self, node: &gtk::Widget, x: f32, y: f32) {