Group nodes into columns by major type

This commit is contained in:
Roger Roger
2021-08-18 07:23:50 +00:00
committed by Ryuukyu
parent 2ee7bca68a
commit 487dc3b2d3
4 changed files with 73 additions and 14 deletions

View File

@@ -11,7 +11,7 @@ use pipewire::{channel::Sender, spa::Direction};
use crate::{
view::{self},
GtkMessage, MediaType, PipewireLink, PipewireMessage,
GtkMessage, MediaType, NodeType, PipewireLink, PipewireMessage,
};
static STYLE: &str = include_str!("style.css");
@@ -108,7 +108,7 @@ impl Application {
@weak app => @default-return Continue(true),
move |msg| {
match msg {
PipewireMessage::NodeAdded{ id, name } => app.add_node(id, name.as_str()),
PipewireMessage::NodeAdded{ id, name, node_type } => app.add_node(id, name.as_str(), node_type),
PipewireMessage::PortAdded{ id, node_id, name, direction, media_type } => app.add_port(id, name.as_str(), node_id, direction, media_type),
PipewireMessage::LinkAdded{ id, node_from, port_from, node_to, port_to, active} => app.add_link(id, node_from, port_from, node_to, port_to, active),
PipewireMessage::LinkStateChanged { id, active } => app.link_state_changed(id, active), // TODO
@@ -125,12 +125,14 @@ impl Application {
}
/// Add a new node to the view.
fn add_node(&self, id: u32, name: &str) {
fn add_node(&self, id: u32, name: &str, node_type: Option<NodeType>) {
info!("Adding node to graph: id {}", id);
imp::Application::from_instance(self)
.graphview
.add_node(id, view::Node::new(name));
imp::Application::from_instance(self).graphview.add_node(
id,
view::Node::new(name),
node_type,
);
}
/// Add a new port to the view.

View File

@@ -23,6 +23,7 @@ enum PipewireMessage {
NodeAdded {
id: u32,
name: String,
node_type: Option<NodeType>,
},
PortAdded {
id: u32,
@@ -55,6 +56,12 @@ enum PipewireMessage {
},
}
#[derive(Debug, Clone)]
pub enum NodeType {
Input,
Output,
}
#[derive(Debug, Copy, Clone)]
pub enum MediaType {
Audio,

View File

@@ -14,7 +14,7 @@ use pipewire::{
Context, Core, MainLoop,
};
use crate::{GtkMessage, MediaType, PipewireMessage};
use crate::{GtkMessage, MediaType, NodeType, PipewireMessage};
use state::{Item, State};
enum ProxyItem {
@@ -112,6 +112,27 @@ fn handle_node(
}
});
let media_class = |class: &str| {
if class.contains("Sink") || class.contains("Input") {
Some(NodeType::Input)
} else if class.contains("Source") || class.contains("Output") {
Some(NodeType::Output)
} else {
None
}
};
let node_type = props
.get("media.category")
.and_then(|class| {
if class.contains("Duplex") {
None
} else {
props.get("media.class").and_then(media_class)
}
})
.or_else(|| props.get("media.class").and_then(media_class));
state.borrow_mut().insert(
node.id,
Item::Node {
@@ -121,7 +142,11 @@ fn handle_node(
);
sender
.send(PipewireMessage::NodeAdded { id: node.id, name })
.send(PipewireMessage::NodeAdded {
id: node.id,
name,
node_type,
})
.expect("Failed to send message");
}

View File

@@ -8,7 +8,9 @@ use gtk::{
};
use log::{error, warn};
use std::collections::HashMap;
use std::{cmp::Ordering, collections::HashMap};
use crate::NodeType;
mod imp {
use super::*;
@@ -239,14 +241,37 @@ impl GraphView {
glib::Object::new(&[]).expect("Failed to create GraphView")
}
pub fn add_node(&self, id: u32, node: Node) {
pub fn add_node(&self, id: u32, node: Node, node_type: Option<NodeType>) {
let private = imp::GraphView::from_instance(self);
node.set_parent(self);
// Place widgets in colums of 4, growing down, then right.
// TODO: Make a better positioning algorithm.
let x = ((private.nodes.borrow().len() / 4) as f32 * 400.0) + 20.0; // This relies on integer division rounding down.
let y = (private.nodes.borrow().len() as f32 % 4.0 * 100.0) + 20.0;
// Place widgets in colums of 3, growing down
let x = if let Some(node_type) = node_type {
match node_type {
NodeType::Output => 20.0,
NodeType::Input => 820.0,
}
} else {
420.0
};
let y = private
.nodes
.borrow()
.values()
.map(|node| {
//Map nodes to locations
self.get_node_position(&node.clone().upcast())
})
.filter(|&(x2, _y)| {
//Only look in our column
(x - x2).abs() < 50.0
})
.max_by(|y1, y2| {
//Get max in column
y1.partial_cmp(y2).unwrap_or(Ordering::Equal)
})
.map_or(20_f32, |(_x, y)| y + 100.0);
self.move_node(&node.clone().upcast(), x, y);