Skip to content

Instantly share code, notes, and snippets.

@saivert
Created September 25, 2023 19:37
Show Gist options
  • Save saivert/9e470129296345fa75f7a867450695f6 to your computer and use it in GitHub Desktop.
Save saivert/9e470129296345fa75f7a867450695f6 to your computer and use it in GitHub Desktop.
Experiment with list model with a default item in position 0
use crate::pwnodemodel::PwNodeModel;
use crate::pwnodeobject::PwNodeObject;
use gtk::{gio, glib, prelude::*, subclass::prelude::*};
use std::cell::{Cell, RefCell};
use wireplumber as wp;
mod imp {
use glib::Properties;
use super::*;
#[derive(Debug, Default, Properties)]
#[properties(wrapper_type = super::WithDefaultListModel)]
pub struct WithDefaultListModel{
pub(super) default_item: Cell<u32>,
pub(super) default: RefCell<Option<gtk::StringObject>>,
#[property(get, set = Self::set_model)]
pub(super) model: RefCell<Option<PwNodeModel>>,
}
/// Basic declaration of our type for the GObject type system
#[glib::object_subclass]
impl ObjectSubclass for WithDefaultListModel {
const NAME: &'static str = "WithDefaultListModel";
type Type = super::WithDefaultListModel;
type Interfaces = (gio::ListModel,);
}
#[glib::derived_properties]
impl ObjectImpl for WithDefaultListModel {
}
impl ListModelImpl for WithDefaultListModel {
fn item_type(&self) -> glib::Type {
glib::Object::static_type()
}
fn n_items(&self) -> u32 {
let model = self.model.borrow();
if let Some(model) = model.as_ref() {
wp::info!("Sending {} items", model.n_items() + 1);
model.n_items() + 1
} else {
0
}
}
fn item(&self, position: u32) -> Option<glib::Object> {
let model = self.model.borrow();
let model = model.as_ref().cloned().unwrap();
if position == 0 {
if let Ok(node) = model.get_node(self.default_item.get()) {
let string = format!("Default ({})", node.name().unwrap_or_default());
self.default.replace(Some(gtk::StringObject::new(&string)));
let item = self.default.borrow();
let item = item.as_ref().cloned().unwrap();
return Some(item.upcast::<glib::Object>());
}
self.default.replace(Some(gtk::StringObject::new("Default")));
let item = self.default.borrow();
let item = item.as_ref().cloned().unwrap();
return Some(item.upcast::<glib::Object>());
} else {
model.item(position-1).clone()
}
}
}
impl WithDefaultListModel {
pub fn set_model(&self, new_model: Option<&PwNodeModel>) {
let removed = if let Some(model) = self.model.borrow().as_ref() {
model.n_items()
} else {
0
};
self.model.set(new_model.cloned());
if let Some(model) = new_model {
let added = model.n_items();
self.obj().items_changed(0, removed, added);
wp::info!("{removed} removed, {added} added");
}
}
}
}
glib::wrapper! {
pub struct WithDefaultListModel(ObjectSubclass<imp::WithDefaultListModel>) @implements gio::ListModel;
}
impl WithDefaultListModel {
pub(crate) fn new(model: Option<&PwNodeModel>) -> Self {
glib::Object::builder().property("model", model).build()
}
pub(crate) fn set_default_node_id(&self, id: u32) {
self.imp().default_item.set(id);
self.items_changed(0, 1, 1);
}
}
impl Default for WithDefaultListModel {
fn default() -> Self {
Self::new(None)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment