Skip to content

Commit

Permalink
Add support for changing card profiles
Browse files Browse the repository at this point in the history
  • Loading branch information
saivert committed Dec 20, 2023
1 parent a442f3e commit 9da7256
Show file tree
Hide file tree
Showing 12 changed files with 704 additions and 19 deletions.
2 changes: 2 additions & 0 deletions data/resources/resources.gresource.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
<file preprocess="xml-stripblanks" alias="gtk/output-dropdown.ui">ui/output-dropdown.ui</file>
<file preprocess="xml-stripblanks" alias="gtk/sinkbox.ui">ui/sinkbox.ui</file>
<file preprocess="xml-stripblanks" alias="gtk/outputbox.ui">ui/outputbox.ui</file>
<file preprocess="xml-stripblanks" alias="gtk/profile-dropdown.ui">ui/profile-dropdown.ui</file>
<file preprocess="xml-stripblanks" alias="gtk/devicebox.ui">ui/devicebox.ui</file>
</gresource>
<gresource prefix="/com/saivert/pwvucontrol/icons/scalable/actions">
<file preprocess="xml-stripblanks" alias="com.saivert.pwvucontrol.svg">../icons/com.saivert.pwvucontrol.svg</file>
Expand Down
22 changes: 22 additions & 0 deletions data/resources/ui/devicebox.ui
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- SPDX-License-Identifier: GPL-3.0-or-later -->
<interface>
<requires lib="gtk" version="4.0" />
<requires lib="Adw" version="1.0" />
<template class="PwDeviceBox" parent="GtkListBoxRow">
<child>
<object class="GtkBox">
<property name="orientation">horizontal</property>
<property name="spacing">6</property>
<child>
<object class="GtkLabel" id="label">
</object>
</child>
<child>
<object class="PwProfileDropDown" id="profile_dropdown">
</object>
</child>
</object>
</child>
</template>
</interface>
20 changes: 20 additions & 0 deletions data/resources/ui/profile-dropdown.ui
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- SPDX-License-Identifier: GPL-3.0-or-later -->
<interface>
<requires lib="gtk" version="4.0" />
<requires lib="Adw" version="1.0" />
<template class="PwProfileDropDown" parent="GtkWidget">
<property name="layout-manager">
<object class="GtkBinLayout" />
</property>
<child>
<object class="GtkDropDown" id="profile_dropdown">
<property name="hexpand">0</property>
<property name="valign">center</property>
<style>
<class name="suffixes" />
</style>
</object>
</child>
</template>
</interface>
25 changes: 15 additions & 10 deletions data/resources/ui/sinkbox.ui
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,22 @@
<requires lib="Adw" version="1.0" />
<template class="PwSinkBox" parent="PwVolumeBox">
<child type="extra">
<object class="GtkToggleButton" id="default_sink_toggle">
<property name="hexpand">0</property>
<property name="valign">center</property>
<signal name="toggled" handler="default_sink_toggle_toggled" swapped="true" />
<style>
<class name="suffixes" />
<class name="expander-row-arrow" />
</style>
<property name="icon-name">emblem-default-symbolic</property>
<object class="GtkBox">
<property name="orientation">horizontal</property>
<property name="spacing">6</property>
<child>
<object class="GtkToggleButton" id="default_sink_toggle">
<property name="hexpand">0</property>
<property name="valign">center</property>
<signal name="toggled" handler="default_sink_toggle_toggled" swapped="true" />
<style>
<class name="suffixes" />
<class name="expander-row-arrow" />
</style>
<property name="icon-name">emblem-default-symbolic</property>
</object>
</child>
</object>
</child>
</template>

</interface>
41 changes: 41 additions & 0 deletions data/resources/ui/window.ui
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,47 @@
</child>


<child>
<object class="AdwViewStackPage">
<property name="visible">true</property>
<property name="name">cards</property>
<property name="title" translatable="yes">Cards</property>
<property name="icon-name">soundcard-symbolic</property>
<property name="child">
<object class="GtkScrolledWindow">
<property name="hscrollbar-policy">never</property>
<property name="min-content-height">200</property>
<property name="hexpand">0</property>
<property name="vexpand">1</property>
<child>
<object class="GtkViewport">
<property name="scroll-to-focus">1</property>
<child>
<object class="GtkBox">
<property name="orientation">vertical</property>
<property name="margin-start">10</property>
<property name="margin-end">10</property>
<property name="margin-top">5</property>
<property name="margin-bottom">5</property>
<child>
<object class="GtkListBox" id="cardlist">
<property name="selection-mode">none</property>
<property name="show-separators">1</property>
<style>
<class name="boxed-list" />
</style>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</property>
</object>
</child>


</object>
</child>
<child type="end">
Expand Down
75 changes: 75 additions & 0 deletions src/devicebox.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
// SPDX-License-Identifier: GPL-3.0-or-later

use crate::{profile_dropdown::PwProfileDropDown, pwdeviceobject::PwDeviceObject};
use gtk::{prelude::*, subclass::prelude::*};
use std::cell::RefCell;

mod imp {
use super::*;

#[derive(Default, gtk::CompositeTemplate, glib::Properties)]
#[template(resource = "/com/saivert/pwvucontrol/gtk/devicebox.ui")]
#[properties(wrapper_type = super::PwDeviceBox)]
pub struct PwDeviceBox {
#[template_child]
pub label: TemplateChild<gtk::Label>,
#[template_child]
pub profile_dropdown: TemplateChild<PwProfileDropDown>,

#[property(get, set, construct_only)]
pub deviceobject: RefCell<Option<PwDeviceObject>>,
}

#[glib::object_subclass]
impl ObjectSubclass for PwDeviceBox {
const NAME: &'static str = "PwDeviceBox";
type Type = super::PwDeviceBox;
type ParentType = gtk::ListBoxRow;

fn class_init(klass: &mut Self::Class) {
klass.bind_template();
klass.bind_template_callbacks();
}

fn instance_init(obj: &glib::subclass::InitializingObject<Self>) {
obj.init_template();
}
}

#[glib::derived_properties]
impl ObjectImpl for PwDeviceBox {
fn constructed(&self) {
self.parent_constructed();

let obj = self.obj();

let deviceobject = obj.deviceobject().expect("Device object");

deviceobject
.bind_property("name", &self.label.get(), "label")
.sync_create()
.build();

self.profile_dropdown.set_deviceobject(obj.deviceobject());
}
}
impl WidgetImpl for PwDeviceBox {}
impl ListBoxRowImpl for PwDeviceBox {}

#[gtk::template_callbacks]
impl PwDeviceBox {}
}

glib::wrapper! {
pub struct PwDeviceBox(ObjectSubclass<imp::PwDeviceBox>)
@extends gtk::Widget, gtk::ListBoxRow,
@implements gtk::Actionable;
}

impl PwDeviceBox {
pub(crate) fn new(deviceobject: &PwDeviceObject) -> Self {
glib::Object::builder()
.property("deviceobject", deviceobject)
.build()
}
}
3 changes: 3 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ mod withdefaultlistmodel;
mod output_dropdown;
mod sinkbox;
mod outputbox;
mod profile_dropdown;
mod pwdeviceobject;
mod devicebox;

use std::{ffi::{OsStr, OsString}, path::PathBuf};

Expand Down
17 changes: 12 additions & 5 deletions src/manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use crate::{PwvucontrolWindow, PwvucontrolApplication};
mod imp {
use std::{str::FromStr, cell::RefCell};

use crate::{pwnodeobject::PwNodeObject, window::PwvucontrolWindowView, pwnodemodel::PwNodeModel};
use crate::{pwnodeobject::PwNodeObject, window::PwvucontrolWindowView, pwnodemodel::PwNodeModel, pwdeviceobject::PwDeviceObject};

use super::*;
use glib::Properties;
Expand Down Expand Up @@ -49,7 +49,7 @@ mod imp {
impl ObjectImpl for PwvucontrolManager {
fn constructed(&self) {
self.parent_constructed();
self.devicemodel.set(gio::ListStore::new::<wp::pw::Device>()).expect("devicemodel not set");
self.devicemodel.set(gio::ListStore::new::<PwDeviceObject>()).expect("devicemodel not set");

self.setup_wp_connection();
self.setup_metadata_om();
Expand Down Expand Up @@ -165,7 +165,7 @@ mod imp {
let n: String = device.pw_property("device.name").unwrap();
wp::log::info!("Got device {} {n}", device.bound_id());

devicemodel.append(device);
devicemodel.append(&PwDeviceObject::new(device));

} else {
unreachable!("Object must be one of the above, but is {:?} instead", object.type_());
Expand All @@ -184,8 +184,15 @@ mod imp {
model.remove(node.bound_id());

} else if let Some(device) = object.dynamic_cast_ref::<wp::pw::Device>() {
if let Some(pos) = devicemodel.find(device) {
devicemodel.remove(pos);
for item in devicemodel.iter::<PwDeviceObject>() {
if let Ok(item) = item {
if item.wpdevice().bound_id() == device.bound_id() {
if let Some(pos) = devicemodel.find(&item) {
wp::log::info!("Removed device {} @ pos {pos}", device.bound_id());
devicemodel.remove(pos);
}
}
}
}
} else {
wp::log::info!("Object must be one of the above, but is {:?} instead", object.type_());
Expand Down
Loading

0 comments on commit 9da7256

Please sign in to comment.