GPSApp: Can now request pads on element

Add menu entries to add new pad/port to an element/node.
This commit is contained in:
Stéphane Cerveau 2021-12-10 15:26:18 +01:00
parent 1c96a78afe
commit 39e39767a3
6 changed files with 70 additions and 38 deletions

View file

@ -19,6 +19,9 @@ TODO:
- [x] Run the pipeline with GStreamer
- [x] Control the pipeline with GStreamer
- [x] Define the license
- [] check that that a node accept to create a port on request (input/output)
- [] select nodes/links with a Trait Selectable
- [] be able to remove a link by selecting it
- [] Connect the logs to the window
- [] Create a window for the video output
- [] Add multiple graphviews with tabs.
@ -27,6 +30,7 @@ TODO:
- [] crash with x11 on contextual menu
- [] check that element exists before creating it on file load.
- [] open multiple times dialog (About) prevent to close it.
## Code cleanup

View file

@ -32,7 +32,7 @@ use std::{error, ops};
use crate::pipeline::{Pipeline, PipelineState};
use crate::plugindialogs;
use crate::graphmanager::{GraphView, Node};
use crate::graphmanager::{GraphView, Node, PortDirection};
#[derive(Debug)]
pub struct GPSAppInner {
@ -419,13 +419,30 @@ impl GPSApp {
}));
application.add_action(&action);
let action = gio::SimpleAction::new("node.request-pad", None);
let action = gio::SimpleAction::new("node.request-pad-input", None);
let app_weak = app.downgrade();
action.connect_activate(glib::clone!(@weak pop_menu => move |_,_| {
println!("node.request-pad {}", node_id);
let app = upgrade_weak!(app_weak);
println!("node.request-pad-input {}", node_id);
let mut node = app.graphview.borrow_mut().node(&node_id).unwrap();
let port_id = app.graphview.borrow().next_port_id();
node.add_port(port_id, "in", PortDirection::Input);
pop_menu.unparent();
}));
application.add_action(&action);
let action = gio::SimpleAction::new("node.request-pad-output", None);
let app_weak = app.downgrade();
action.connect_activate(glib::clone!(@weak pop_menu => move |_,_| {
let app = upgrade_weak!(app_weak);
println!("node.request-pad-output {}", node_id);
let mut node = app.graphview.borrow_mut().node(&node_id).unwrap();
let port_id = app.graphview.borrow().next_port_id();
node.add_port(port_id, "out", PortDirection::Output);
pop_menu.unparent();
}));
application.add_action(&action);
let action = gio::SimpleAction::new("node.properties", None);
action.connect_activate(glib::clone!(@weak pop_menu => move |_,_| {
println!("node.properties {}", node_id);

View file

@ -43,11 +43,19 @@
<attribute name="action">app.node.delete</attribute>
<attribute name="accel">&lt;primary&gt;n</attribute>
</item>
<item>
<submenu>
<attribute name="label" translatable="yes" comments="Node menu entry request pad">_Request pad</attribute>
<attribute name="action">app.node.request-pad</attribute>
<attribute name="accel">&lt;primary&gt;n</attribute>
</item>
<item>
<attribute name="label" translatable="yes" comments="Node menu entry request pad">_Request input pad</attribute>
<attribute name="action">app.node.request-pad-input</attribute>
<attribute name="accel">&lt;primary&gt;n</attribute>
</item>
<item>
<attribute name="label" translatable="yes" comments="Node menu entry request pad">_Request output pad</attribute>
<attribute name="action">app.node.request-pad-output</attribute>
<attribute name="accel">&lt;primary&gt;n</attribute>
</item>
</submenu>
<item>
<attribute name="label" translatable="yes" comments="Node menu entry request pad">_Properties</attribute>
<attribute name="action">app.node.properties</attribute>

View file

@ -176,7 +176,7 @@ mod imp {
let mut node_from = port_from.ancestor(Node::static_type()).expect("Unable to reach parent").dynamic_cast::<Node>().expect("Unable to cast to Node");
let mut node_to = port_to.ancestor(Node::static_type()).expect("Unable to reach parent").dynamic_cast::<Node>().expect("Unable to cast to Node");
println!("add link");
if *port_to.direction() == PortDirection::Output {
if port_to.direction() == PortDirection::Output {
println!("swap ports and nodes to create the link");
std::mem::swap(&mut node_from, &mut node_to);
std::mem::swap(&mut port_from, &mut port_to);
@ -392,15 +392,13 @@ impl GraphView {
let _i = 0;
for _i in 0..input {
let port_id = self.next_port_id();
let port = Port::new(port_id, "in", PortDirection::Input);
self.add_port(id, port_id, port);
self.add_port(id, port_id, "in", PortDirection::Input);
}
let _i = 0;
for _i in 0..output {
let port_id = self.next_port_id();
let port = Port::new(port_id, "out", PortDirection::Output);
self.add_port(id, port_id, port);
self.add_port(id, port_id, "out", PortDirection::Output);
}
}
@ -463,14 +461,20 @@ impl GraphView {
}
// Port related methods
pub fn add_port(&self, node_id: u32, port_id: u32, port: Port) {
pub fn add_port(
&self,
node_id: u32,
port_id: u32,
port_name: &str,
port_direction: PortDirection,
) {
let private = imp::GraphView::from_instance(self);
println!(
"adding a port with port id {} to node id {}",
port_id, node_id
);
if let Some(node) = private.nodes.borrow_mut().get_mut(&node_id) {
node.add_port(port_id, port);
node.add_port(port_id, port_name, port_direction);
} else {
error!(
"Node with id {} not found when trying to add port with id {} to graph",
@ -664,21 +668,20 @@ impl GraphView {
let private = imp::GraphView::from_instance(self);
let unique_name = node.unique_name();
description.push_str(&format!("{} name={}", node.name(), unique_name));
let ports = node.all_ports(PortDirection::Output);
if ports.len() > 1 {
description.push_str(&format!(" {}. ! ", unique_name));
} else if ports.len() > 0 {
description.push_str(" ! ");
}
for (name, value) in node.properties().iter() {
description.push_str(&format!(" {}={}", name, value));
}
println!("{}", description);
let ports = node.all_ports(PortDirection::Output);
let n_ports = ports.len();
for port in ports {
if let Some((_port_to, node_to)) = self.port_connected_to(port.id()) {
if n_ports > 1 {
description.push_str(&format!(" {}. ! ", unique_name));
} else {
description.push_str(" ! ");
}
if let Some(node) = private.nodes.borrow().get(&node_to) {
description = self.process_node(node, description.clone());
}
@ -867,8 +870,11 @@ impl GraphView {
"Port" => {
if let Some(port) = current_port {
let node = current_node.clone();
node.expect("No current node, error...")
.add_port(port.id(), port);
node.expect("No current node, error...").add_port(
port.id(),
&port.name(),
port.direction(),
);
}
current_port = None;
}

View file

@ -141,9 +141,9 @@ impl Node {
println!("{}", name);
}
pub fn add_port(&mut self, id: u32, port: super::port::Port) {
pub fn add_port(&mut self, id: u32, name: &str, direction: PortDirection) {
let private = imp::Node::from_instance(self);
let port = Port::new(id, name, direction);
match port.direction() {
PortDirection::Input => {
private
@ -172,7 +172,7 @@ impl Node {
let ports_list: Vec<_> = self
.ports()
.iter()
.filter(|(_, port)| *port.direction() == direction || direction == PortDirection::All)
.filter(|(_, port)| port.direction() == direction || direction == PortDirection::All)
.map(|(_, port)| port.clone())
.collect();
ports_list

View file

@ -22,9 +22,9 @@ use gtk::{
prelude::*,
subclass::prelude::*,
};
use std::fmt;
use std::{borrow::Borrow, fmt};
#[derive(Debug, Clone, PartialEq)]
#[derive(Debug, Clone, PartialEq, Copy)]
pub enum PortDirection {
Input,
Output,
@ -137,17 +137,14 @@ impl Port {
private.id.get().copied().expect("Port id is not set")
}
pub fn direction(&self) -> &PortDirection {
pub fn direction(&self) -> PortDirection {
let private = imp::Port::from_instance(self);
private.direction.get().expect("Port direction is not set")
*private.direction.get().expect("Port direction is not set")
}
pub fn name(&self) -> String {
let private = imp::Port::from_instance(self);
private
.direction
.get()
.expect("direction is not set")
.to_string()
let label = private.label.borrow().get().unwrap();
label.text().to_string()
}
}