Skip to content

Instantly share code, notes, and snippets.

struct IndexGetter {
current_serial: u32,
tags: Vec<Tag>,
}
#[derive(Clone)]
struct Tag {
pub serial: u32,
pub tag: String,
}
@saivert
saivert / pwfilteredlistmodel.rs
Created April 28, 2024 10:13
Filter list model with type known at construction time.
// SPDX-License-Identifier: GPL-3.0-or-later
use glib::{Properties, closure_local};
use glib::subclass::prelude::*;
use gtk::{gio, prelude::*, subclass::prelude::*};
use std::cell::RefCell;
use std::cell::OnceCell;
mod imp {
use super::*;
@saivert
saivert / combineprops.rs
Created December 23, 2023 13:50
combine props with derived props.rs
fn properties() -> &'static [ParamSpec] {
static PROPERTIES: Lazy<Vec<ParamSpec>> =
Lazy::new(|| {
let props = vec![
glib::ParamSpecEnum::builder::<crate::NodeType>("nodetype")
.default_value(NodeType::Undefined)
.build(),
];
let derived_props = PwNodeObject::derived_properties();
[props, derived_props.to_vec()].concat()
@saivert
saivert / withdefaultlistmodel.rs
Created September 25, 2023 19:37
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::*;
@saivert
saivert / dropdown_list_factory.rs
Last active September 22, 2023 23:25
Reimplementation of gtk::DropDown's default list factory
let listfactory = gtk::SignalListItemFactory::new();
listfactory.connect_setup(|_, item| setup_handler(item, false));
let dropdown = self.outputdevice_dropdown.get();
listfactory.connect_bind(clone!(@weak dropdown => move |_factory, item| {
let item: gtk::ListItem = item.downcast_ref().cloned().unwrap();
fn selected_item_handler(dropdown: &gtk::DropDown, listitem: &gtk::ListItem) {
if let Some (child) = listitem.child() {
@saivert
saivert / audio_format_using_new_pod_builder_api.rs
Created August 19, 2023 07:02
Creating audio format pod with new pod builder api
let mut v = vec![0u8; 1024];
let mut b = spa::pod::builder::Builder::new(&mut v);
unsafe {
let mut f: MaybeUninit<spa::sys::spa_pod_frame> = MaybeUninit::zeroed();
b.push_array(&mut f);
b.add_id(spa::utils::Id(spa::sys::SPA_AUDIO_CHANNEL_MONO));
b.pop(f.assume_init_mut());
};
@saivert
saivert / bypass_gtkscale_scroll_handler.rs
Created August 15, 2023 21:00
Bypass scroll handling for GtkScale (gtk-rs)
impl WidgetImpl for PwVolumeBox {
fn map(&self) {
self.parent_map();
// Hack until I have a better way of getting at the scrolled window
// ListBox Box Viewport Scrolled window
let p = self.obj().parent().unwrap().parent().unwrap().parent().unwrap().parent().unwrap();
let scrolledwindow: gtk::ScrolledWindow = p.downcast().expect("downcast to scrolled window");
@saivert
saivert / gtk_callback_vs_future.rs
Created August 5, 2023 19:05
Callback vs Future
act.connect_activate(clone!(@weak self as widget => move |_action, _param| {
let dlg = gtk::AlertDialog::builder().buttons(["Yes", "No"]).message("hi").build();
let c = gio::Cancellable::new();
dlg.choose(Some(widget.obj().as_ref()), Some(&c), |x| {
match x {
Ok(x) => { wp::info!("got {x}"); },
Err(_) => { wp::log::warning!("Err in dlg result"); }
}
});
let list_store = gio::ListStore::new(glib::Object::static_type());
let obj: glib::Object = glib::Object::new();
unsafe {
// Use set_data so we don't have to implement a subclass with a real property.
obj.set_data::<String>("hoy", "nice".to_string());
}
list_store.append(&obj);
let v: Vec<glib::Object> = list_store.into_iter().map(|x| {x.unwrap().clone()}).collect();
unsafe {
let o = v[0].data::<String>("hoy").expect("hoy").as_ref();
@saivert
saivert / gettext-search-path.rs
Created August 2, 2023 20:30
gettext-rs development locale dir search path
fn main() -> gtk::glib::ExitCode {
let mut textdomain = gettextrs::TextDomain::new(GETTEXT_PACKAGE);
if cfg!(debug_assertions) {
// Add extra search path for debug builds so we don't have to install
textdomain = textdomain.prepend("../locale-test");
}
_ = textdomain.init().map_err(|x|{
// TranslationNotFound is not a fatal error, fallback to msgid (english)
if !matches!(x, TextDomainError::TranslationNotFound(_)) {
panic!("Unable to setup gettext!")