Color links and ports according to their formats

Format params for links and ports are now being watched for in the pipewire connection code.

The parsed media type is then set on the port widget / link object
and they are colored accordingly.

For ports, which were already colored before, this new method of determining the media type
should be more reliable and accurate as this uses the real Format/EnumFormat
params instead of parsing optional properties.
This commit is contained in:
Tom A. Wagner
2023-07-30 12:09:08 +02:00
parent ba73d8cdcc
commit 7f754b207c
8 changed files with 362 additions and 148 deletions

View File

@@ -23,20 +23,26 @@ use gtk::{
};
use pipewire::spa::Direction;
use crate::MediaType;
mod imp {
use super::*;
use std::cell::Cell;
use once_cell::{sync::Lazy, unsync::OnceCell};
use pipewire::spa::Direction;
use pipewire::spa::{format::MediaType, Direction};
/// Graphical representation of a pipewire port.
#[derive(Default, glib::Properties)]
#[derive(glib::Properties)]
#[properties(wrapper_type = super::Port)]
pub struct Port {
#[property(get, set, construct_only)]
pub(super) pipewire_id: OnceCell<u32>,
#[property(
type = u32,
get = |_| self.media_type.get().as_raw(),
set = Self::set_media_type
)]
pub(super) media_type: Cell<MediaType>,
#[property(
name = "name", type = String,
get = |this: &Self| this.label.text().to_string(),
@@ -49,6 +55,17 @@ mod imp {
pub(super) direction: OnceCell<Direction>,
}
impl Default for Port {
fn default() -> Self {
Self {
pipewire_id: OnceCell::default(),
media_type: Cell::new(MediaType::Unknown),
label: gtk::Label::default(),
direction: OnceCell::default(),
}
}
}
#[glib::object_subclass]
impl ObjectSubclass for Port {
const NAME: &'static str = "HelvumPort";
@@ -184,6 +201,26 @@ mod imp {
obj.add_controller(drop_target);
}
}
impl Port {
fn set_media_type(&self, media_type: u32) {
let media_type = MediaType::from_raw(media_type);
self.media_type.set(media_type);
for css_class in ["video", "audio", "midi"] {
self.obj().remove_css_class(css_class)
}
// Color the port according to its media type.
match media_type {
MediaType::Video => self.obj().add_css_class("video"),
MediaType::Audio => self.obj().add_css_class("audio"),
MediaType::Application | MediaType::Stream => self.obj().add_css_class("midi"),
_ => {}
}
}
}
}
glib::wrapper! {
@@ -192,7 +229,7 @@ glib::wrapper! {
}
impl Port {
pub fn new(id: u32, name: &str, direction: Direction, media_type: Option<MediaType>) -> Self {
pub fn new(id: u32, name: &str, direction: Direction) -> Self {
// Create the widget and initialize needed fields
let res: Self = glib::Object::builder()
.property("pipewire-id", id)
@@ -208,14 +245,6 @@ impl Port {
// Display a grab cursor when the mouse is over the port so the user knows it can be dragged to another port.
res.set_cursor(gtk::gdk::Cursor::from_name("grab", None).as_ref());
// Color the port according to its media type.
match media_type {
Some(MediaType::Video) => res.add_css_class("video"),
Some(MediaType::Audio) => res.add_css_class("audio"),
Some(MediaType::Midi) => res.add_css_class("midi"),
None => {}
}
res
}