From 72d4ddadb713d5bb6ba7b01fdeb772c8d7645612 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Cerveau?= Date: Fri, 14 Jan 2022 18:14:38 +0100 Subject: [PATCH] graphmanager: save the position as an attribute The position should not be an hidden property but a regular attribute. --- src/graphmanager/graphview.rs | 58 ++++++++++++++++------------------- src/graphmanager/node.rs | 14 +++++++++ 2 files changed, 40 insertions(+), 32 deletions(-) diff --git a/src/graphmanager/graphview.rs b/src/graphmanager/graphview.rs index b16536d..2ebe637 100644 --- a/src/graphmanager/graphview.rs +++ b/src/graphmanager/graphview.rs @@ -647,7 +647,12 @@ impl GraphView { Some(transform.to_translate()) } - pub(super) fn move_node(&self, node: >k::Widget, x: f32, y: f32) { + pub(super) fn move_node(&self, widget: >k::Widget, x: f32, y: f32) { + let node = widget + .clone() + .dynamic_cast::() + .expect("Unable to convert to Node"); + node.set_position(x, y); let layout_manager = self .layout_manager() .expect("Failed to get layout manager") @@ -660,7 +665,7 @@ impl GraphView { .unwrap(); layout_manager - .layout_child(node) + .layout_child(widget) .expect("Could not get layout child") .dynamic_cast::() .expect("Could not cast to FixedLayoutChild") @@ -820,7 +825,9 @@ impl GraphView { XMLWEvent::start_element("Node") .attr("name", &node.name()) .attr("id", &node.id().to_string()) - .attr("type", &node.node_type().unwrap().to_string()), + .attr("type", &node.node_type().unwrap().to_string()) + .attr("pos_x", &node.position().0.to_string()) + .attr("pos_y", &node.position().1.to_string()), )?; for port in node.ports().values() { writer.write( @@ -840,20 +847,6 @@ impl GraphView { )?; writer.write(XMLWEvent::end_element())?; } - if let Some(position) = self.node_position(&node.upcast()) { - writer.write( - XMLWEvent::start_element("Property") - .attr("name", "_pos_x") - .attr("value", &position.0.to_string()), - )?; - writer.write(XMLWEvent::end_element())?; - writer.write( - XMLWEvent::start_element("Property") - .attr("name", "_pos_y") - .attr("value", &position.1.to_string()), - )?; - writer.write(XMLWEvent::end_element())?; - } writer.write(XMLWEvent::end_element())?; } //Get the link and write it. @@ -911,12 +904,23 @@ impl GraphView { let node_type: &String = attrs .get::(&String::from("type")) .expect("Unable to find node type"); - - current_node = Some(Node::new( + let default_value = String::from("0"); + let pos_x: &String = attrs + .get::(&String::from("pos_x")) + .unwrap_or(&default_value); + let pos_y: &String = attrs + .get::(&String::from("pos_y")) + .unwrap_or(&default_value); + let node = Node::new( id.parse::().unwrap(), name, NodeType::from_str(node_type.as_str()), - )); + ); + node.set_position( + pos_x.parse::().unwrap(), + pos_y.parse::().unwrap(), + ); + current_node = Some(node); } "Property" => { let name = attrs @@ -986,20 +990,10 @@ impl GraphView { "Node" => { if let Some(node) = current_node { let id = node.id(); - let mut pos_x = 0 as f32; - let mut pos_y = 0 as f32; - if let Some(value) = node.property("_pos_x") { - pos_x = value.parse::().unwrap(); - } - if let Some(value) = node.property("_pos_y") { - pos_y = value.parse::().unwrap(); - } - + let position = node.position(); self.add_node(id, node); if let Some(node) = self.node(&id) { - if pos_x != 0.0 || pos_y != 0.0 { - self.move_node(&node.upcast(), pos_x, pos_y); - } + self.move_node(&node.upcast(), position.0, position.1); } self.update_current_node_id(id); } diff --git a/src/graphmanager/node.rs b/src/graphmanager/node.rs index 0197057..8ddb51d 100644 --- a/src/graphmanager/node.rs +++ b/src/graphmanager/node.rs @@ -75,6 +75,7 @@ mod imp { // Properties are differnet from GObject properties pub(super) properties: RefCell>, pub(super) selected: Cell, + pub(super) position: Cell<(f32, f32)>, } #[glib::object_subclass] @@ -145,6 +146,7 @@ mod imp { num_ports_out: Cell::new(0), properties: RefCell::new(HashMap::new()), selected: Cell::new(false), + position: Cell::new((0.0, 0.0)), } } } @@ -331,4 +333,16 @@ impl Node { port.set_selected(false); } } + /// Set coordinates for the drawn node. + /// + pub fn set_position(&self, x: f32, y: f32) { + imp::Node::from_instance(self).position.set((x, y)); + } + /// Get coordinates for the drawn node. + /// + /// # Returns + /// `(x, y)` + pub fn position(&self) -> (f32, f32) { + imp::Node::from_instance(self).position.get() + } }