mirror of
https://gitlab.freedesktop.org/dabrain34/GstPipelineStudio.git
synced 2024-11-25 18:41:03 +00:00
graphview: save position as a hidden property
- Save/load node position in XML file - Introduce a graph ID
This commit is contained in:
parent
1ac03c16ae
commit
e9b905230a
2 changed files with 85 additions and 6 deletions
|
@ -56,6 +56,7 @@ mod imp {
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct GraphView {
|
pub struct GraphView {
|
||||||
|
pub(super) id: Cell<u32>,
|
||||||
pub(super) nodes: RefCell<HashMap<u32, Node>>,
|
pub(super) nodes: RefCell<HashMap<u32, Node>>,
|
||||||
pub(super) links: RefCell<HashMap<u32, Link>>,
|
pub(super) links: RefCell<HashMap<u32, Link>>,
|
||||||
pub(super) current_node_id: Cell<u32>,
|
pub(super) current_node_id: Cell<u32>,
|
||||||
|
@ -126,6 +127,18 @@ mod imp {
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
drag_controller.connect_drag_end(
|
||||||
|
clone!(@strong drag_state => move |drag_controller, _x, _y| {
|
||||||
|
let widget = drag_controller
|
||||||
|
.widget()
|
||||||
|
.expect("drag-end event has no widget")
|
||||||
|
.dynamic_cast::<Self::Type>()
|
||||||
|
.expect("drag-end event is not on the GraphView");
|
||||||
|
widget.graph_updated();
|
||||||
|
}
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
obj.add_controller(&drag_controller);
|
obj.add_controller(&drag_controller);
|
||||||
|
|
||||||
let gesture = gtk::GestureClick::new();
|
let gesture = gtk::GestureClick::new();
|
||||||
|
@ -252,6 +265,13 @@ mod imp {
|
||||||
<()>::static_type().into(),
|
<()>::static_type().into(),
|
||||||
)
|
)
|
||||||
.build(),
|
.build(),
|
||||||
|
Signal::builder(
|
||||||
|
"graph-updated",
|
||||||
|
// returns graph ID
|
||||||
|
&[u32::static_type().into()],
|
||||||
|
<()>::static_type().into(),
|
||||||
|
)
|
||||||
|
.build(),
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
SIGNALS.as_ref()
|
SIGNALS.as_ref()
|
||||||
|
@ -374,6 +394,16 @@ impl GraphView {
|
||||||
);
|
);
|
||||||
glib::Object::new(&[]).expect("Failed to create GraphView")
|
glib::Object::new(&[]).expect("Failed to create GraphView")
|
||||||
}
|
}
|
||||||
|
pub fn set_id(&self, id: u32) {
|
||||||
|
let private = imp::GraphView::from_instance(self);
|
||||||
|
private.id.set(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn graph_updated(&self) {
|
||||||
|
let private = imp::GraphView::from_instance(self);
|
||||||
|
self.emit_by_name("graph-updated", &[&private.id.get()])
|
||||||
|
.expect("unable to send signal");
|
||||||
|
}
|
||||||
|
|
||||||
pub fn add_node_with_port(&self, id: u32, node: Node, input: u32, output: u32) {
|
pub fn add_node_with_port(&self, id: u32, node: Node, input: u32, output: u32) {
|
||||||
let private = imp::GraphView::from_instance(self);
|
let private = imp::GraphView::from_instance(self);
|
||||||
|
@ -423,6 +453,7 @@ impl GraphView {
|
||||||
let port_id = self.next_port_id();
|
let port_id = self.next_port_id();
|
||||||
self.add_port(id, port_id, "out", PortDirection::Output);
|
self.add_port(id, port_id, "out", PortDirection::Output);
|
||||||
}
|
}
|
||||||
|
self.graph_updated();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_node(&self, id: u32, node: Node) {
|
pub fn add_node(&self, id: u32, node: Node) {
|
||||||
|
@ -544,6 +575,7 @@ impl GraphView {
|
||||||
let private = imp::GraphView::from_instance(self);
|
let private = imp::GraphView::from_instance(self);
|
||||||
if !self.link_exists(&link) {
|
if !self.link_exists(&link) {
|
||||||
private.links.borrow_mut().insert(link.id, link);
|
private.links.borrow_mut().insert(link.id, link);
|
||||||
|
self.graph_updated();
|
||||||
self.queue_draw();
|
self.queue_draw();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -772,12 +804,14 @@ impl GraphView {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render_xml(&self, filename: &str) -> anyhow::Result<()> {
|
pub fn render_xml(&self, filename: &str) -> anyhow::Result<()> {
|
||||||
|
let private = imp::GraphView::from_instance(self);
|
||||||
let mut file = File::create(filename).unwrap();
|
let mut file = File::create(filename).unwrap();
|
||||||
let mut writer = EmitterConfig::new()
|
let mut writer = EmitterConfig::new()
|
||||||
.perform_indent(true)
|
.perform_indent(true)
|
||||||
.create_writer(&mut file);
|
.create_writer(&mut file);
|
||||||
|
|
||||||
writer.write(XMLWEvent::start_element("Graph"))?;
|
writer
|
||||||
|
.write(XMLWEvent::start_element("Graph").attr("id", &private.id.get().to_string()))?;
|
||||||
|
|
||||||
//Get the nodes
|
//Get the nodes
|
||||||
let nodes = self.all_nodes(NodeType::All);
|
let nodes = self.all_nodes(NodeType::All);
|
||||||
|
@ -806,6 +840,20 @@ 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.
|
||||||
|
@ -826,7 +874,7 @@ impl GraphView {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn load_xml(&self, filename: &str) -> anyhow::Result<()> {
|
pub fn load_xml(&self, filename: &str) -> anyhow::Result<()> {
|
||||||
let file = File::open(filename).unwrap();
|
let file = File::open(filename)?;
|
||||||
let file = BufReader::new(file);
|
let file = BufReader::new(file);
|
||||||
|
|
||||||
let parser = EventReader::new(file);
|
let parser = EventReader::new(file);
|
||||||
|
@ -849,6 +897,9 @@ impl GraphView {
|
||||||
match name.to_string().as_str() {
|
match name.to_string().as_str() {
|
||||||
"Graph" => {
|
"Graph" => {
|
||||||
println!("New graph detected");
|
println!("New graph detected");
|
||||||
|
if let Some(id) = attrs.get::<String>(&String::from("id")) {
|
||||||
|
self.set_id(id.parse::<u32>().expect("id should be an u32"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
"Node" => {
|
"Node" => {
|
||||||
let id = attrs
|
let id = attrs
|
||||||
|
@ -935,7 +986,21 @@ 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 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 pos_x != 0.0 || pos_y != 0.0 {
|
||||||
|
self.move_node(&node.upcast(), pos_x, pos_y);
|
||||||
|
}
|
||||||
|
}
|
||||||
self.update_current_node_id(id);
|
self.update_current_node_id(id);
|
||||||
}
|
}
|
||||||
current_node = None;
|
current_node = None;
|
||||||
|
|
|
@ -71,6 +71,7 @@ mod imp {
|
||||||
pub(super) ports: RefCell<HashMap<u32, Port>>,
|
pub(super) ports: RefCell<HashMap<u32, Port>>,
|
||||||
pub(super) num_ports_in: Cell<i32>,
|
pub(super) num_ports_in: Cell<i32>,
|
||||||
pub(super) num_ports_out: Cell<i32>,
|
pub(super) num_ports_out: Cell<i32>,
|
||||||
|
// 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>,
|
||||||
}
|
}
|
||||||
|
@ -190,13 +191,18 @@ impl Node {
|
||||||
self_.description.set_text(description);
|
self_.description.set_text(description);
|
||||||
println!("{}", description);
|
println!("{}", description);
|
||||||
}
|
}
|
||||||
|
pub fn hidden_property(&self, name: &str) -> bool {
|
||||||
|
name.starts_with('_')
|
||||||
|
}
|
||||||
|
|
||||||
fn update_description(&self) {
|
fn update_description(&self) {
|
||||||
let self_ = imp::Node::from_instance(self);
|
let self_ = imp::Node::from_instance(self);
|
||||||
let mut description = String::from("");
|
let mut description = String::from("");
|
||||||
for (name, value) in self_.properties.borrow().iter() {
|
for (name, value) in self_.properties.borrow().iter() {
|
||||||
description.push_str(&format!("{}:{}", name, value));
|
if !self.hidden_property(name) {
|
||||||
description.push('\n');
|
description.push_str(&format!("{}:{}", name, value));
|
||||||
|
description.push('\n');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
self.set_description(&description);
|
self.set_description(&description);
|
||||||
}
|
}
|
||||||
|
@ -280,8 +286,8 @@ impl Node {
|
||||||
self.update_description();
|
self.update_description();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_node_properties(&self, new_properties: &HashMap<String, String>) {
|
pub fn update_properties(&self, new_node_properties: &HashMap<String, String>) {
|
||||||
for (key, value) in new_properties {
|
for (key, value) in new_node_properties {
|
||||||
self.add_property(key.clone(), value.clone());
|
self.add_property(key.clone(), value.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -291,6 +297,14 @@ impl Node {
|
||||||
private.properties.borrow()
|
private.properties.borrow()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn property(&self, name: &str) -> Option<String> {
|
||||||
|
let private = imp::Node::from_instance(self);
|
||||||
|
if let Some(property) = private.properties.borrow().get(name) {
|
||||||
|
return Some(property.clone());
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
pub fn toggle_selected(&self) {
|
pub fn toggle_selected(&self) {
|
||||||
self.set_selected(!self.selected());
|
self.set_selected(!self.selected());
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue