mirror of
https://gitlab.freedesktop.org/dabrain34/GstPipelineStudio.git
synced 2024-09-27 06:00:07 +00:00
graphview: introduce PortPresence
The port presence helps to know if the port can be deleted or not. XML Format break.
This commit is contained in:
parent
ef2a6ea1ba
commit
4bae12c011
4 changed files with 100 additions and 14 deletions
|
@ -24,7 +24,11 @@ use xml::reader::XmlEvent as XMLREvent;
|
||||||
use xml::writer::EmitterConfig;
|
use xml::writer::EmitterConfig;
|
||||||
use xml::writer::XmlEvent as XMLWEvent;
|
use xml::writer::XmlEvent as XMLWEvent;
|
||||||
|
|
||||||
use super::{link::Link, node::Node, node::NodeType, port::Port, port::PortDirection};
|
use super::{
|
||||||
|
link::Link,
|
||||||
|
node::{Node, NodeType},
|
||||||
|
port::{Port, PortDirection, PortPresence},
|
||||||
|
};
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::BufReader;
|
use std::io::BufReader;
|
||||||
|
@ -436,13 +440,25 @@ impl GraphView {
|
||||||
let _i = 0;
|
let _i = 0;
|
||||||
for _i in 0..input {
|
for _i in 0..input {
|
||||||
let port_id = self.next_port_id();
|
let port_id = self.next_port_id();
|
||||||
self.add_port(id, port_id, "in", PortDirection::Input);
|
self.add_port(
|
||||||
|
id,
|
||||||
|
port_id,
|
||||||
|
"in",
|
||||||
|
PortDirection::Input,
|
||||||
|
PortPresence::Always,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let _i = 0;
|
let _i = 0;
|
||||||
for _i in 0..output {
|
for _i in 0..output {
|
||||||
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,
|
||||||
|
PortPresence::Always,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
self.graph_updated();
|
self.graph_updated();
|
||||||
}
|
}
|
||||||
|
@ -524,6 +540,7 @@ impl GraphView {
|
||||||
port_id: u32,
|
port_id: u32,
|
||||||
port_name: &str,
|
port_name: &str,
|
||||||
port_direction: PortDirection,
|
port_direction: PortDirection,
|
||||||
|
port_nature: PortPresence,
|
||||||
) {
|
) {
|
||||||
let private = imp::GraphView::from_instance(self);
|
let private = imp::GraphView::from_instance(self);
|
||||||
info!(
|
info!(
|
||||||
|
@ -531,7 +548,7 @@ impl GraphView {
|
||||||
port_id, node_id
|
port_id, node_id
|
||||||
);
|
);
|
||||||
if let Some(node) = private.nodes.borrow_mut().get_mut(&node_id) {
|
if let Some(node) = private.nodes.borrow_mut().get_mut(&node_id) {
|
||||||
node.add_port(port_id, port_name, port_direction);
|
node.add_port(port_id, port_name, port_direction, port_nature);
|
||||||
} else {
|
} else {
|
||||||
error!(
|
error!(
|
||||||
"Node with id {} not found when trying to add port with id {} to graph",
|
"Node with id {} not found when trying to add port with id {} to graph",
|
||||||
|
@ -540,9 +557,19 @@ impl GraphView {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn can_remove_port(&self, node_id: u32, port_id: u32) -> bool {
|
||||||
|
let private = imp::GraphView::from_instance(self);
|
||||||
|
let nodes = private.nodes.borrow();
|
||||||
|
if let Some(node) = nodes.get(&node_id) {
|
||||||
|
return node.can_remove_port(port_id);
|
||||||
|
}
|
||||||
|
warn!("Unable to find a node with the id {}", node_id);
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
/// Remove the port with id from node with id.
|
/// Remove the port with id from node with id.
|
||||||
///
|
///
|
||||||
pub fn remove_port(&self, port_id: u32, node_id: u32) {
|
pub fn remove_port(&self, node_id: u32, port_id: u32) {
|
||||||
let private = imp::GraphView::from_instance(self);
|
let private = imp::GraphView::from_instance(self);
|
||||||
let nodes = private.nodes.borrow();
|
let nodes = private.nodes.borrow();
|
||||||
if let Some(node) = nodes.get(&node_id) {
|
if let Some(node) = nodes.get(&node_id) {
|
||||||
|
@ -835,7 +862,8 @@ impl GraphView {
|
||||||
XMLWEvent::start_element("Port")
|
XMLWEvent::start_element("Port")
|
||||||
.attr("name", &port.name())
|
.attr("name", &port.name())
|
||||||
.attr("id", &port.id().to_string())
|
.attr("id", &port.id().to_string())
|
||||||
.attr("direction", &port.direction().to_string()),
|
.attr("direction", &port.direction().to_string())
|
||||||
|
.attr("presence", &port.presence().to_string()),
|
||||||
)?;
|
)?;
|
||||||
writer.write(XMLWEvent::end_element())?;
|
writer.write(XMLWEvent::end_element())?;
|
||||||
}
|
}
|
||||||
|
@ -944,10 +972,15 @@ impl GraphView {
|
||||||
let direction: &String = attrs
|
let direction: &String = attrs
|
||||||
.get::<String>(&String::from("direction"))
|
.get::<String>(&String::from("direction"))
|
||||||
.expect("Unable to find port direction");
|
.expect("Unable to find port direction");
|
||||||
|
let default_value = PortPresence::Always.to_string();
|
||||||
|
let presence: &String = attrs
|
||||||
|
.get::<String>(&String::from("presence"))
|
||||||
|
.unwrap_or(&default_value);
|
||||||
current_port = Some(Port::new(
|
current_port = Some(Port::new(
|
||||||
id.parse::<u32>().unwrap(),
|
id.parse::<u32>().unwrap(),
|
||||||
name,
|
name,
|
||||||
PortDirection::from_str(direction),
|
PortDirection::from_str(direction),
|
||||||
|
PortPresence::from_str(presence),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
"Link" => {
|
"Link" => {
|
||||||
|
@ -1009,6 +1042,7 @@ impl GraphView {
|
||||||
id,
|
id,
|
||||||
&port.name(),
|
&port.name(),
|
||||||
port.direction(),
|
port.direction(),
|
||||||
|
port.presence(),
|
||||||
);
|
);
|
||||||
self.update_current_port_id(id);
|
self.update_current_port_id(id);
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,4 +8,4 @@ pub use link::Link;
|
||||||
pub use node::Node;
|
pub use node::Node;
|
||||||
pub use node::NodeType;
|
pub use node::NodeType;
|
||||||
pub use port::Port;
|
pub use port::Port;
|
||||||
pub use port::PortDirection;
|
pub use port::{PortDirection, PortPresence};
|
||||||
|
|
|
@ -23,7 +23,7 @@ use gtk::subclass::prelude::*;
|
||||||
use log::trace;
|
use log::trace;
|
||||||
|
|
||||||
use super::Port;
|
use super::Port;
|
||||||
use super::PortDirection;
|
use super::{PortDirection, PortPresence};
|
||||||
|
|
||||||
use std::cell::{Cell, Ref, RefCell};
|
use std::cell::{Cell, Ref, RefCell};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
@ -210,9 +210,15 @@ impl Node {
|
||||||
self.set_description(&description);
|
self.set_description(&description);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_port(&mut self, id: u32, name: &str, direction: PortDirection) {
|
pub fn add_port(
|
||||||
|
&mut self,
|
||||||
|
id: u32,
|
||||||
|
name: &str,
|
||||||
|
direction: PortDirection,
|
||||||
|
presence: PortPresence,
|
||||||
|
) {
|
||||||
let private = imp::Node::from_instance(self);
|
let private = imp::Node::from_instance(self);
|
||||||
let port = Port::new(id, name, direction);
|
let port = Port::new(id, name, direction, presence);
|
||||||
match port.direction() {
|
match port.direction() {
|
||||||
PortDirection::Input => {
|
PortDirection::Input => {
|
||||||
private.inputs.append(&port);
|
private.inputs.append(&port);
|
||||||
|
@ -248,6 +254,16 @@ impl Node {
|
||||||
private.ports.borrow().get(id).cloned()
|
private.ports.borrow().get(id).cloned()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn can_remove_port(&self, id: u32) -> bool {
|
||||||
|
let private = imp::Node::from_instance(self);
|
||||||
|
if let Some(port) = private.ports.borrow().get(&id) {
|
||||||
|
if port.presence() != PortPresence::Always {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
pub fn remove_port(&self, id: u32) {
|
pub fn remove_port(&self, id: u32) {
|
||||||
let private = imp::Node::from_instance(self);
|
let private = imp::Node::from_instance(self);
|
||||||
if let Some(port) = private.ports.borrow_mut().remove(&id) {
|
if let Some(port) = private.ports.borrow_mut().remove(&id) {
|
||||||
|
|
|
@ -25,7 +25,7 @@ use gtk::{
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use std::{borrow::Borrow, fmt};
|
use std::{borrow::Borrow, fmt};
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Copy)]
|
#[derive(Debug, Clone, PartialOrd, PartialEq, Copy)]
|
||||||
pub enum PortDirection {
|
pub enum PortDirection {
|
||||||
Input,
|
Input,
|
||||||
Output,
|
Output,
|
||||||
|
@ -44,23 +44,50 @@ impl PortDirection {
|
||||||
match port_direction_name {
|
match port_direction_name {
|
||||||
"Input" => PortDirection::Input,
|
"Input" => PortDirection::Input,
|
||||||
"Output" => PortDirection::Output,
|
"Output" => PortDirection::Output,
|
||||||
"All" => PortDirection::Output,
|
"All" => PortDirection::All,
|
||||||
_ => PortDirection::Unknown,
|
_ => PortDirection::Unknown,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Port's presence
|
||||||
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Copy)]
|
||||||
|
pub enum PortPresence {
|
||||||
|
/// Can not be removed from his parent independantly
|
||||||
|
Always,
|
||||||
|
/// Can be removed from a node
|
||||||
|
Sometimes,
|
||||||
|
Unknown,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for PortPresence {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
write!(f, "{:?}", self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PortPresence {
|
||||||
|
pub fn from_str(port_direction_name: &str) -> PortPresence {
|
||||||
|
match port_direction_name {
|
||||||
|
"Always" => PortPresence::Always,
|
||||||
|
"Sometimes" => PortPresence::Sometimes,
|
||||||
|
_ => PortPresence::Unknown,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mod imp {
|
mod imp {
|
||||||
use super::*;
|
use super::*;
|
||||||
use once_cell::unsync::OnceCell;
|
use once_cell::unsync::OnceCell;
|
||||||
|
|
||||||
/// Graphical representation of a pipewire port.
|
/// Graphical representation of a port.
|
||||||
#[derive(Default, Clone)]
|
#[derive(Default, Clone)]
|
||||||
pub struct Port {
|
pub struct Port {
|
||||||
pub(super) label: OnceCell<gtk::Label>,
|
pub(super) label: OnceCell<gtk::Label>,
|
||||||
pub(super) id: OnceCell<u32>,
|
pub(super) id: OnceCell<u32>,
|
||||||
pub(super) direction: OnceCell<PortDirection>,
|
pub(super) direction: OnceCell<PortDirection>,
|
||||||
pub(super) selected: Cell<bool>,
|
pub(super) selected: Cell<bool>,
|
||||||
|
pub(super) presence: OnceCell<PortPresence>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[glib::object_subclass]
|
#[glib::object_subclass]
|
||||||
|
@ -93,7 +120,7 @@ glib::wrapper! {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Port {
|
impl Port {
|
||||||
pub fn new(id: u32, name: &str, direction: PortDirection) -> Self {
|
pub fn new(id: u32, name: &str, direction: PortDirection, presence: PortPresence) -> Self {
|
||||||
// Create the widget and initialize needed fields
|
// Create the widget and initialize needed fields
|
||||||
let port: Self = glib::Object::new(&[]).expect("Failed to create Port");
|
let port: Self = glib::Object::new(&[]).expect("Failed to create Port");
|
||||||
port.add_css_class("port");
|
port.add_css_class("port");
|
||||||
|
@ -109,6 +136,10 @@ impl Port {
|
||||||
} else {
|
} else {
|
||||||
port.add_css_class("port-out");
|
port.add_css_class("port-out");
|
||||||
}
|
}
|
||||||
|
private
|
||||||
|
.presence
|
||||||
|
.set(presence)
|
||||||
|
.expect("Port presence already set");
|
||||||
|
|
||||||
let label = gtk::Label::new(Some(name));
|
let label = gtk::Label::new(Some(name));
|
||||||
label.set_parent(&port);
|
label.set_parent(&port);
|
||||||
|
@ -130,6 +161,11 @@ impl Port {
|
||||||
*private.direction.get().expect("Port direction is not set")
|
*private.direction.get().expect("Port direction is not set")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn presence(&self) -> PortPresence {
|
||||||
|
let private = imp::Port::from_instance(self);
|
||||||
|
*private.presence.get().expect("Port presence is not set")
|
||||||
|
}
|
||||||
|
|
||||||
pub fn name(&self) -> String {
|
pub fn name(&self) -> String {
|
||||||
let private = imp::Port::from_instance(self);
|
let private = imp::Port::from_instance(self);
|
||||||
let label = private.label.borrow().get().unwrap();
|
let label = private.label.borrow().get().unwrap();
|
||||||
|
|
Loading…
Reference in a new issue