Skip to content

Commit

Permalink
Use gio::ListStore for profiles
Browse files Browse the repository at this point in the history
  • Loading branch information
saivert committed Dec 25, 2023
1 parent 60befbe commit 4c25092
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 43 deletions.
62 changes: 21 additions & 41 deletions src/backend/pwdeviceobject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@

use crate::backend::pwprofileobject::PwProfileObject;
use glib::{self, clone, subclass::{prelude::*, Signal}, Object, ObjectExt, ParamSpec, Properties, Value};
use gtk::{gio, prelude::*, subclass::prelude::*};
use gtk::{gio, prelude::*};
use wireplumber as wp;
use wp::{
pw::{PipewireObjectExt, PipewireObjectExt2},
spa::SpaPodBuilder,
};
use im_rc::Vector;

use once_cell::sync::{OnceCell, Lazy};
use std::cell::{Cell, RefCell};

Expand All @@ -28,31 +28,14 @@ pub mod imp {
#[property(get, set, construct_only)]
pub(super) wpdevice: OnceCell<wp::pw::Device>,

pub(super) profiles: RefCell<Vector<PwProfileObject>>,
#[property(get)]
pub(super) profilemodel: OnceCell<gio::ListStore>,
}

#[glib::object_subclass]
impl ObjectSubclass for PwDeviceObject {
const NAME: &'static str = "PwDeviceObject";
type Type = super::PwDeviceObject;
type Interfaces = (gio::ListModel,);
}

impl ListModelImpl for PwDeviceObject {
fn item_type(&self) -> glib::Type {
PwProfileObject::static_type()
}

fn n_items(&self) -> u32 {
self.profiles.borrow().len() as u32
}

fn item(&self, position: u32) -> Option<glib::Object> {
self.profiles
.borrow()
.get(position as usize)
.map(|o| o.clone().upcast::<glib::Object>())
}
}

// Trait shared by all GObjects
Expand Down Expand Up @@ -85,6 +68,8 @@ pub mod imp {
fn constructed(&self) {
self.parent_constructed();

self.profilemodel.set(gio::ListStore::new::<PwProfileObject>()).expect("profilemodel not set");

let obj = self.obj();

obj.label_set_name();
Expand Down Expand Up @@ -128,7 +113,7 @@ pub mod imp {
}

glib::wrapper! {
pub struct PwDeviceObject(ObjectSubclass<imp::PwDeviceObject>) @implements gio::ListModel;
pub struct PwDeviceObject(ObjectSubclass<imp::PwDeviceObject>);
}

impl PwDeviceObject {
Expand All @@ -147,34 +132,29 @@ impl PwDeviceObject {
let available_key = keys.find_value_from_short_name("available").expect("available key");

if let Ok(Some(iter)) = res {
let removed = widget.imp().profiles.borrow().len();

let inserted = {
let mut profiles = widget.imp().profiles.borrow_mut();
profiles.clear();

for a in iter {
let pod: wp::spa::SpaPod = a.get().unwrap();
if !pod.is_object() {
continue;
}
let removed = widget.profilemodel().n_items();
widget.emit_by_name::<()>("pre-update", &[]);

let index = pod.find_spa_property(&index_key).expect("Index!").int().expect("Int");
let description = pod.find_spa_property(&description_key).expect("Format!").string().expect("String");
let available = pod.find_spa_property(&available_key).expect("Availability!").id().expect("Id");
let mut profiles: Vec<PwProfileObject> = Vec::new();

profiles.push_back(PwProfileObject::new(index as u32, &description, available));
for a in iter {
let pod: wp::spa::SpaPod = a.get().unwrap();
if !pod.is_object() {
continue;
}

profiles.len()
};
let index = pod.find_spa_property(&index_key).expect("Index!").int().expect("Int");
let description = pod.find_spa_property(&description_key).expect("Format!").string().expect("String");
let available = pod.find_spa_property(&available_key).expect("Availability!").id().expect("Id");

profiles.push(PwProfileObject::new(index as u32, &description, available));
}
widget.profilemodel().splice(0, removed as u32, &profiles);

// Set profile_index property without notify by setting internal storage directly
widget.imp().profile_index.set(widget.get_current_profile_index().unwrap() as u32);

// Notify update of list model
widget.emit_by_name::<()>("pre-update", &[]);
widget.items_changed(0, removed as u32, inserted as u32);
widget.emit_by_name::<()>("post-update", &[]);

//widget.emit_by_name::<()>("profiles-changed", &[]);
Expand Down
1 change: 0 additions & 1 deletion src/ui/devicebox.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ mod imp {
.sync_create()
.build();


self.profile_dropdown.set_deviceobject(obj.deviceobject());
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/ui/profile_dropdown.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ mod imp {
if let Some(deviceobject) = new_deviceobject {
self.block_signal.set(true);
wp::log::info!("self.profile_dropdown.set_model({});", deviceobject.wpdevice().bound_id());
self.profile_dropdown.set_model(Some(deviceobject));
self.profile_dropdown.set_model(Some(&deviceobject.profilemodel()));
wp::log::info!("self.profile_dropdown.set_selected({});", deviceobject.profile_index());

self.profile_dropdown.set_selected(deviceobject.profile_index());
Expand Down

0 comments on commit 4c25092

Please sign in to comment.