diff --git a/applets/cosmic-applet-audio/src/main.rs b/applets/cosmic-applet-audio/src/main.rs index ebb0c722..d36ea700 100644 --- a/applets/cosmic-applet-audio/src/main.rs +++ b/applets/cosmic-applet-audio/src/main.rs @@ -12,6 +12,7 @@ use pa::PA; mod task; mod volume; mod volume_scale; +use volume_scale::VolumeScale; use futures::{channel::mpsc, stream::StreamExt}; use gtk4::{ @@ -94,7 +95,7 @@ fn app(application: &Application) { append: output_icon = &Image { set_icon_name: Some("audio-speakers-symbolic"), }, - append: output_volume = &Scale::with_range(Orientation::Horizontal, 0., 100., 1.) { + append: output_volume = &VolumeScale::new(pa.clone(), true) { set_format_value_func: |_, value| { format!("{:.0}%", value) }, @@ -108,7 +109,7 @@ fn app(application: &Application) { append: input_icon = &Image { set_icon_name: Some("audio-input-microphone-symbolic"), }, - append: input_volume = &Scale::with_range(Orientation::Horizontal, 0., 100., 1.) { + append: input_volume = &VolumeScale::new(pa.clone(), false) { set_format_value_func: |_, value| { format!("{:.0}%", value) }, diff --git a/applets/cosmic-applet-audio/src/volume.rs b/applets/cosmic-applet-audio/src/volume.rs index 0cc163f1..3df4d6f1 100644 --- a/applets/cosmic-applet-audio/src/volume.rs +++ b/applets/cosmic-applet-audio/src/volume.rs @@ -1,8 +1,9 @@ -use gtk4::{prelude::*, Scale}; +use gtk4::prelude::*; use libpulse_binding::volume::Volume; -use crate::pa::DeviceInfo; +use crate::{pa::DeviceInfo, volume_scale::VolumeScale}; -pub fn update_volume(device: &DeviceInfo, scale: &Scale) { - scale.set_value((device.volume.avg().0 as f64 / Volume::NORMAL.0 as f64) * 100.); +pub fn update_volume(device: &DeviceInfo, scale: &VolumeScale) { + scale.set_name(device.name.clone()); + scale.set_volume(&device.volume); } diff --git a/applets/cosmic-applet-audio/src/volume_scale.rs b/applets/cosmic-applet-audio/src/volume_scale.rs index 822a8795..0b17a1ea 100644 --- a/applets/cosmic-applet-audio/src/volume_scale.rs +++ b/applets/cosmic-applet-audio/src/volume_scale.rs @@ -1,4 +1,4 @@ -use gtk4::{glib, prelude::*}; +use gtk4::{glib, prelude::*, subclass::prelude::*}; use libpulse_binding::volume::{ChannelVolumes, Volume}; use std::{ cell::{Cell, RefCell}, @@ -11,21 +11,41 @@ use crate::PA; // Component -struct VolumeScale { - scale: gtk4::Scale, +#[derive(Default)] +pub struct VolumeScaleImp { name: Rc>>, } +#[glib::object_subclass] +impl ObjectSubclass for VolumeScaleImp { + const NAME: &'static str = "VolumeScale"; + type Type = VolumeScale; + type ParentType = gtk4::Scale; +} + +impl ObjectImpl for VolumeScaleImp {} +impl WidgetImpl for VolumeScaleImp {} +impl RangeImpl for VolumeScaleImp {} +impl ScaleImpl for VolumeScaleImp {} + +glib::wrapper! { + pub struct VolumeScale(ObjectSubclass) + @extends gtk4::Scale, gtk4::Range, gtk4::Widget, + @implements gtk4::Accessible, gtk4::Orientable; +} + impl VolumeScale { - fn new(pa: PA, sink: bool) { - let name: Rc>> = Rc::new(RefCell::new(None)); - let scale = gtk4::Scale::with_range(gtk4::Orientation::Horizontal, 0., 100., 1.); + pub fn new(pa: PA, sink: bool) -> Self { + let scale: VolumeScale = glib::Object::new(&[]).unwrap(); + scale.set_range(0., 100.); + let name = scale.imp().name.clone(); let updater = Updater::new(move |value: f64| { let name = name.clone(); let pa = pa.clone(); async move { let mut volumes = ChannelVolumes::default(); - volumes.set(0, Volume((value * 100.) as _)); // XXX ? + let volume = value * (Volume::NORMAL.0 as f64) / 100.; + volumes.set(1, Volume(volume as _)); // XXX ? let name_ref = name.borrow(); if let Some(name) = name_ref.as_deref() { @@ -45,14 +65,16 @@ impl VolumeScale { updater.update(value); gtk4::Inhibit(false) }); + scale } - fn set_value(&self, value: f64) { - self.scale.set_value(value); + pub fn set_volume(&self, volume: &ChannelVolumes) { + let value = volume.avg().0 as f64 / (Volume::NORMAL.0 as f64) * 100.; + self.set_value(value); } - fn set_name(&self, name: Option) { - *self.name.borrow_mut() = name; + pub fn set_name(&self, name: Option) { + *self.imp().name.borrow_mut() = name; } }