Skip to content

Instantly share code, notes, and snippets.

@saivert
Created July 30, 2023 00:10
Show Gist options
  • Save saivert/a888cf6ba6dd303916100fea58b09335 to your computer and use it in GitHub Desktop.
Save saivert/a888cf6ba6dd303916100fea58b09335 to your computer and use it in GitHub Desktop.
/*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
use crate::{application::PwvucontrolApplication, pwnodeobject::PwNodeObject};
use glib::{self, clone, ParamSpec, Properties, Value};
use gtk::{gio, prelude::*, subclass::prelude::*};
use std::cell::RefCell;
use wireplumber as wp;
mod imp {
use std::cell::Cell;
use glib::SignalHandlerId;
use once_cell::sync::OnceCell;
use super::*;
use crate::{
channelbox::PwChannelBox, levelprovider::LevelbarProvider,
pwchannelobject::PwChannelObject, window::PwvucontrolWindow, NodeType,
};
#[derive(Default, gtk::CompositeTemplate, Properties)]
#[template(resource = "/com/saivert/pwvucontrol/gtk/volumebox.ui")]
#[properties(wrapper_type = super::PwVolumeBox)]
pub struct PwVolumeBox {
levelbarprovider: OnceCell<LevelbarProvider>,
timeoutid: Cell<Option<glib::SourceId>>,
pub(super) level: Cell<f32>,
}
#[glib::object_subclass]
impl ObjectSubclass for PwVolumeBox {
const NAME: &'static str = "PwVolumeBox";
type Type = super::PwVolumeBox;
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();
}
}
impl ObjectImpl for PwVolumeBox {
fn properties() -> &'static [ParamSpec] {
Self::derived_properties()
}
fn set_property(&self, id: usize, value: &Value, pspec: &ParamSpec) {
self.derived_set_property(id, value, pspec)
}
fn property(&self, id: usize, pspec: &ParamSpec) -> Value {
self.derived_property(id, pspec)
}
fn constructed(&self) {
if let Ok(provider) = LevelbarProvider::new(&self.obj()) {
provider
.connect(item.boundid())
.expect("levelprovider connect");
self.levelbarprovider
.set(provider)
.expect("Provider not set already");
glib::MainContext::default().spawn_local(clone!(@weak self as obj => async move {
loop {
glib::timeout_future(std::time::Duration::from_millis(25)).await;
obj.level_bar.set_value(obj.level.get() as f64);
}
}));
// self.timeoutid.set(Some(glib::timeout_add_local(
// std::time::Duration::from_millis(25),
// clone!(@weak self as obj => @default-return Continue(false), move || {
// obj.level_bar.set_value(obj.level.get() as f64);
// Continue(true)
// }),
// )));
}
}
fn dispose(&self) {
if let Some(t) = self.timeoutid.take() {
t.remove();
}
}
}
impl WidgetImpl for PwVolumeBox {}
impl ListBoxRowImpl for PwVolumeBox {}
impl PwVolumeBox {}
}
glib::wrapper! {
pub struct PwVolumeBox(ObjectSubclass<imp::PwVolumeBox>)
@extends gtk::Widget, gtk::ListBoxRow,
@implements gtk::Actionable;
}
impl PwVolumeBox {
pub(crate) fn new(row_data: &impl glib::IsA<PwNodeObject>) -> Self {
glib::Object::builder()
.property("row-data", &row_data)
.build()
}
pub(crate) fn set_level(&self, level: f32) {
self.imp().level.set(level);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment