mirror of
https://gitlab.freedesktop.org/dabrain34/GstPipelineStudio.git
synced 2024-12-24 00:40:29 +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::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 std::fs::File;
|
||||
use std::io::BufReader;
|
||||
|
@ -436,13 +440,25 @@ impl GraphView {
|
|||
let _i = 0;
|
||||
for _i in 0..input {
|
||||
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;
|
||||
for _i in 0..output {
|
||||
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();
|
||||
}
|
||||
|
@ -524,6 +540,7 @@ impl GraphView {
|
|||
port_id: u32,
|
||||
port_name: &str,
|
||||
port_direction: PortDirection,
|
||||
port_nature: PortPresence,
|
||||
) {
|
||||
let private = imp::GraphView::from_instance(self);
|
||||
info!(
|
||||
|
@ -531,7 +548,7 @@ impl GraphView {
|
|||
port_id, 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 {
|
||||
error!(
|
||||
"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.
|
||||
///
|
||||
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 nodes = private.nodes.borrow();
|
||||
if let Some(node) = nodes.get(&node_id) {
|
||||
|
@ -835,7 +862,8 @@ impl GraphView {
|
|||
XMLWEvent::start_element("Port")
|
||||
.attr("name", &port.name())
|
||||
.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())?;
|
||||
}
|
||||
|
@ -944,10 +972,15 @@ impl GraphView {
|
|||
let direction: &String = attrs
|
||||
.get::<String>(&String::from("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(
|
||||
id.parse::<u32>().unwrap(),
|
||||
name,
|
||||
PortDirection::from_str(direction),
|
||||
PortPresence::from_str(presence),
|
||||
));
|
||||
}
|
||||
"Link" => {
|
||||
|
@ -1009,6 +1042,7 @@ impl GraphView {
|
|||
id,
|
||||
&port.name(),
|
||||
port.direction(),
|
||||
port.presence(),
|
||||
);
|
||||
self.update_current_port_id(id);
|
||||
}
|
||||
|
|
|
@ -8,4 +8,4 @@ pub use link::Link;
|
|||
pub use node::Node;
|
||||
pub use node::NodeType;
|
||||
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 super::Port;
|
||||
use super::PortDirection;
|
||||
use super::{PortDirection, PortPresence};
|
||||
|
||||
use std::cell::{Cell, Ref, RefCell};
|
||||
use std::collections::HashMap;
|
||||
|
@ -210,9 +210,15 @@ impl Node {
|
|||
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 port = Port::new(id, name, direction);
|
||||
let port = Port::new(id, name, direction, presence);
|
||||
match port.direction() {
|
||||
PortDirection::Input => {
|
||||
private.inputs.append(&port);
|
||||
|
@ -248,6 +254,16 @@ impl Node {
|
|||
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) {
|
||||
let private = imp::Node::from_instance(self);
|
||||
if let Some(port) = private.ports.borrow_mut().remove(&id) {
|
||||
|
|
|
@ -25,7 +25,7 @@ use gtk::{
|
|||
use std::cell::Cell;
|
||||
use std::{borrow::Borrow, fmt};
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Copy)]
|
||||
#[derive(Debug, Clone, PartialOrd, PartialEq, Copy)]
|
||||
pub enum PortDirection {
|
||||
Input,
|
||||
Output,
|
||||
|
@ -44,23 +44,50 @@ impl PortDirection {
|
|||
match port_direction_name {
|
||||
"Input" => PortDirection::Input,
|
||||
"Output" => PortDirection::Output,
|
||||
"All" => PortDirection::Output,
|
||||
"All" => PortDirection::All,
|
||||
_ => 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 {
|
||||
use super::*;
|
||||
use once_cell::unsync::OnceCell;
|
||||
|
||||
/// Graphical representation of a pipewire port.
|
||||
/// Graphical representation of a port.
|
||||
#[derive(Default, Clone)]
|
||||
pub struct Port {
|
||||
pub(super) label: OnceCell<gtk::Label>,
|
||||
pub(super) id: OnceCell<u32>,
|
||||
pub(super) direction: OnceCell<PortDirection>,
|
||||
pub(super) selected: Cell<bool>,
|
||||
pub(super) presence: OnceCell<PortPresence>,
|
||||
}
|
||||
|
||||
#[glib::object_subclass]
|
||||
|
@ -93,7 +120,7 @@ glib::wrapper! {
|
|||
}
|
||||
|
||||
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
|
||||
let port: Self = glib::Object::new(&[]).expect("Failed to create Port");
|
||||
port.add_css_class("port");
|
||||
|
@ -109,6 +136,10 @@ impl Port {
|
|||
} else {
|
||||
port.add_css_class("port-out");
|
||||
}
|
||||
private
|
||||
.presence
|
||||
.set(presence)
|
||||
.expect("Port presence already set");
|
||||
|
||||
let label = gtk::Label::new(Some(name));
|
||||
label.set_parent(&port);
|
||||
|
@ -130,6 +161,11 @@ impl Port {
|
|||
*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 {
|
||||
let private = imp::Port::from_instance(self);
|
||||
let label = private.label.borrow().get().unwrap();
|
||||
|
|
Loading…
Reference in a new issue