mirror of
https://gitlab.freedesktop.org/pipewire/helvum
synced 2026-03-15 11:36:11 +08:00
view: Draw a dashed line for links that are not active
This commit is contained in:
@@ -110,7 +110,8 @@ impl Application {
|
||||
match msg {
|
||||
PipewireMessage::NodeAdded{ id, name } => app.add_node(id, name.as_str()),
|
||||
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} => app.add_link(id, node_from, port_from, node_to, port_to),
|
||||
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
|
||||
PipewireMessage::NodeRemoved { id } => app.remove_node(id),
|
||||
PipewireMessage::PortRemoved { id, node_id } => app.remove_port(id, node_id),
|
||||
PipewireMessage::LinkRemoved { id } => app.remove_link(id)
|
||||
@@ -124,7 +125,7 @@ impl Application {
|
||||
}
|
||||
|
||||
/// Add a new node to the view.
|
||||
pub fn add_node(&self, id: u32, name: &str) {
|
||||
fn add_node(&self, id: u32, name: &str) {
|
||||
info!("Adding node to graph: id {}", id);
|
||||
|
||||
imp::Application::from_instance(self)
|
||||
@@ -133,7 +134,7 @@ impl Application {
|
||||
}
|
||||
|
||||
/// Add a new port to the view.
|
||||
pub fn add_port(
|
||||
fn add_port(
|
||||
&self,
|
||||
id: u32,
|
||||
name: &str,
|
||||
@@ -168,7 +169,15 @@ impl Application {
|
||||
}
|
||||
|
||||
/// Add a new link to the view.
|
||||
pub fn add_link(&self, id: u32, node_from: u32, port_from: u32, node_to: u32, port_to: u32) {
|
||||
fn add_link(
|
||||
&self,
|
||||
id: u32,
|
||||
node_from: u32,
|
||||
port_from: u32,
|
||||
node_to: u32,
|
||||
port_to: u32,
|
||||
active: bool,
|
||||
) {
|
||||
info!("Adding link to graph: id {}", id);
|
||||
|
||||
// FIXME: Links should be colored depending on the data they carry (video, audio, midi) like ports are.
|
||||
@@ -182,9 +191,22 @@ impl Application {
|
||||
node_to,
|
||||
port_to,
|
||||
},
|
||||
active,
|
||||
);
|
||||
}
|
||||
|
||||
fn link_state_changed(&self, id: u32, active: bool) {
|
||||
info!(
|
||||
"Link state changed: Link (id={}) is now {}",
|
||||
id,
|
||||
if active { "active" } else { "inactive" }
|
||||
);
|
||||
|
||||
imp::Application::from_instance(self)
|
||||
.graphview
|
||||
.set_link_state(id, active);
|
||||
}
|
||||
|
||||
// Toggle a link between the two specified ports on the remote pipewire server.
|
||||
fn toggle_link(&self, port_from: u32, port_to: u32) {
|
||||
let imp = imp::Application::from_instance(self);
|
||||
|
||||
@@ -37,6 +37,11 @@ enum PipewireMessage {
|
||||
port_from: u32,
|
||||
node_to: u32,
|
||||
port_to: u32,
|
||||
active: bool,
|
||||
},
|
||||
LinkStateChanged {
|
||||
id: u32,
|
||||
active: bool,
|
||||
},
|
||||
NodeRemoved {
|
||||
id: u32,
|
||||
|
||||
@@ -5,7 +5,7 @@ use std::{cell::RefCell, collections::HashMap, rc::Rc};
|
||||
use gtk::glib::{self, clone};
|
||||
use log::{debug, info, warn};
|
||||
use pipewire::{
|
||||
link::{Link, LinkListener},
|
||||
link::{Link, LinkChangeMask, LinkListener, LinkState},
|
||||
prelude::*,
|
||||
properties,
|
||||
registry::{GlobalObject, Registry},
|
||||
@@ -193,7 +193,13 @@ fn handle_link(
|
||||
let mut state = state.borrow_mut();
|
||||
if let Some(Item::Link { .. }) = state.get(id) {
|
||||
// Info was an update - figure out if we should notify the gtk thread
|
||||
// TODO
|
||||
if info.change_mask().contains(LinkChangeMask::STATE) {
|
||||
sender.send(PipewireMessage::LinkStateChanged {
|
||||
id,
|
||||
active: matches!(info.state(), LinkState::Active)
|
||||
}).expect("Failed to send message");
|
||||
}
|
||||
// TODO -- check other values that might have changed
|
||||
} else {
|
||||
// First time we get info. We can now notify the gtk thread of a new link.
|
||||
let node_from = info.output_node_id();
|
||||
@@ -210,7 +216,8 @@ fn handle_link(
|
||||
node_from,
|
||||
port_from,
|
||||
node_to,
|
||||
port_to
|
||||
port_to,
|
||||
active: matches!(info.state(), LinkState::Active)
|
||||
}).expect(
|
||||
"Failed to send message"
|
||||
);
|
||||
|
||||
@@ -20,7 +20,8 @@ mod imp {
|
||||
#[derive(Default)]
|
||||
pub struct GraphView {
|
||||
pub(super) nodes: RefCell<HashMap<u32, Node>>,
|
||||
pub(super) links: RefCell<HashMap<u32, crate::PipewireLink>>,
|
||||
/// Stores the link and whether it is currently active.
|
||||
pub(super) links: RefCell<HashMap<u32, (crate::PipewireLink, bool)>>,
|
||||
}
|
||||
|
||||
#[glib::object_subclass]
|
||||
@@ -150,10 +151,17 @@ mod imp {
|
||||
.expect("Failed to get cairo context");
|
||||
link_cr.set_line_width(2.0);
|
||||
link_cr.set_source_rgb(0.0, 0.0, 0.0);
|
||||
for link in self.links.borrow().values() {
|
||||
for (link, active) in self.links.borrow().values() {
|
||||
if let Some((from_x, from_y, to_x, to_y)) = self.get_link_coordinates(link) {
|
||||
link_cr.move_to(from_x, from_y);
|
||||
|
||||
// Use dashed line for inactive links, full line otherwise.
|
||||
if *active {
|
||||
link_cr.set_dash(&[], 0.0);
|
||||
} else {
|
||||
link_cr.set_dash(&[10.0, 5.0], 0.0);
|
||||
}
|
||||
|
||||
// Place curve control offset by half the x distance between the two points.
|
||||
// This makes the curve scale well for varying distances between the two ports,
|
||||
// especially when the output port is farther right than the input port.
|
||||
@@ -276,12 +284,22 @@ impl GraphView {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_link(&self, link_id: u32, link: crate::PipewireLink) {
|
||||
pub fn add_link(&self, link_id: u32, link: crate::PipewireLink, active: bool) {
|
||||
let private = imp::GraphView::from_instance(self);
|
||||
private.links.borrow_mut().insert(link_id, link);
|
||||
private.links.borrow_mut().insert(link_id, (link, active));
|
||||
self.queue_draw();
|
||||
}
|
||||
|
||||
pub fn set_link_state(&self, link_id: u32, active: bool) {
|
||||
let private = imp::GraphView::from_instance(self);
|
||||
if let Some((_, state)) = private.links.borrow_mut().get_mut(&link_id) {
|
||||
*state = active;
|
||||
self.queue_draw();
|
||||
} else {
|
||||
warn!("Link state changed on unknown link (id={})", link_id);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn remove_link(&self, id: u32) {
|
||||
let private = imp::GraphView::from_instance(self);
|
||||
let mut links = private.links.borrow_mut();
|
||||
|
||||
Reference in New Issue
Block a user