graphmanager: save the position as an attribute

The position should not be an hidden property
but a regular attribute.
This commit is contained in:
Stéphane Cerveau 2022-01-14 18:14:38 +01:00
parent 34b134107e
commit 72d4ddadb7
2 changed files with 40 additions and 32 deletions

View file

@ -647,7 +647,12 @@ impl GraphView {
Some(transform.to_translate()) Some(transform.to_translate())
} }
pub(super) fn move_node(&self, node: &gtk::Widget, x: f32, y: f32) { pub(super) fn move_node(&self, widget: &gtk::Widget, x: f32, y: f32) {
let node = widget
.clone()
.dynamic_cast::<Node>()
.expect("Unable to convert to Node");
node.set_position(x, y);
let layout_manager = self let layout_manager = self
.layout_manager() .layout_manager()
.expect("Failed to get layout manager") .expect("Failed to get layout manager")
@ -660,7 +665,7 @@ impl GraphView {
.unwrap(); .unwrap();
layout_manager layout_manager
.layout_child(node) .layout_child(widget)
.expect("Could not get layout child") .expect("Could not get layout child")
.dynamic_cast::<gtk::FixedLayoutChild>() .dynamic_cast::<gtk::FixedLayoutChild>()
.expect("Could not cast to FixedLayoutChild") .expect("Could not cast to FixedLayoutChild")
@ -820,7 +825,9 @@ impl GraphView {
XMLWEvent::start_element("Node") XMLWEvent::start_element("Node")
.attr("name", &node.name()) .attr("name", &node.name())
.attr("id", &node.id().to_string()) .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() { for port in node.ports().values() {
writer.write( writer.write(
@ -840,20 +847,6 @@ impl GraphView {
)?; )?;
writer.write(XMLWEvent::end_element())?; 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())?; writer.write(XMLWEvent::end_element())?;
} }
//Get the link and write it. //Get the link and write it.
@ -911,12 +904,23 @@ impl GraphView {
let node_type: &String = attrs let node_type: &String = attrs
.get::<String>(&String::from("type")) .get::<String>(&String::from("type"))
.expect("Unable to find node type"); .expect("Unable to find node type");
let default_value = String::from("0");
current_node = Some(Node::new( let pos_x: &String = attrs
.get::<String>(&String::from("pos_x"))
.unwrap_or(&default_value);
let pos_y: &String = attrs
.get::<String>(&String::from("pos_y"))
.unwrap_or(&default_value);
let node = Node::new(
id.parse::<u32>().unwrap(), id.parse::<u32>().unwrap(),
name, name,
NodeType::from_str(node_type.as_str()), NodeType::from_str(node_type.as_str()),
)); );
node.set_position(
pos_x.parse::<f32>().unwrap(),
pos_y.parse::<f32>().unwrap(),
);
current_node = Some(node);
} }
"Property" => { "Property" => {
let name = attrs let name = attrs
@ -986,20 +990,10 @@ impl GraphView {
"Node" => { "Node" => {
if let Some(node) = current_node { if let Some(node) = current_node {
let id = node.id(); let id = node.id();
let mut pos_x = 0 as f32; let position = node.position();
let mut pos_y = 0 as f32;
if let Some(value) = node.property("_pos_x") {
pos_x = value.parse::<f32>().unwrap();
}
if let Some(value) = node.property("_pos_y") {
pos_y = value.parse::<f32>().unwrap();
}
self.add_node(id, node); self.add_node(id, node);
if let Some(node) = self.node(&id) { if let Some(node) = self.node(&id) {
if pos_x != 0.0 || pos_y != 0.0 { self.move_node(&node.upcast(), position.0, position.1);
self.move_node(&node.upcast(), pos_x, pos_y);
}
} }
self.update_current_node_id(id); self.update_current_node_id(id);
} }

View file

@ -75,6 +75,7 @@ mod imp {
// Properties are differnet from GObject properties // Properties are differnet from GObject properties
pub(super) properties: RefCell<HashMap<String, String>>, pub(super) properties: RefCell<HashMap<String, String>>,
pub(super) selected: Cell<bool>, pub(super) selected: Cell<bool>,
pub(super) position: Cell<(f32, f32)>,
} }
#[glib::object_subclass] #[glib::object_subclass]
@ -145,6 +146,7 @@ mod imp {
num_ports_out: Cell::new(0), num_ports_out: Cell::new(0),
properties: RefCell::new(HashMap::new()), properties: RefCell::new(HashMap::new()),
selected: Cell::new(false), selected: Cell::new(false),
position: Cell::new((0.0, 0.0)),
} }
} }
} }
@ -331,4 +333,16 @@ impl Node {
port.set_selected(false); 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()
}
} }