Derive Macro glib_macros::Properties

source ·
#[derive(Properties)]
{
    // Attributes available to this derive:
    #[properties]
    #[property]
}
Expand description

This macro enables you to derive object properties in a quick way.

Getters and setters

By default, they are generated for you. You can use a custom getter/setter by assigning an expression to get/set. Example: #[property(get = |_| 2, set)].

The macro will always generate, on the wrapper type, the corresponding $property() and set_$property() methods. Notice: you can’t reimplement the generated methods on the wrapper type, but you can change their behavior using a custom getter/setter.

Supported types

Every type implementing the trait Property is supported. If you want to support a custom type, you should consider implementing Property and PropertyGet. If your type supports interior mutability, you should implement also PropertySet and PropertySetNested if possible. The type Option<T> is supported as a property only if Option<T> implements ToValueOptional. If your type doesn’t support PropertySet, you can’t use the generated setter, but you can always define a custom one. If you want to support a custom type with a custom ParamSpec, you should implement the trait HasParamSpec instead of Property.

Example

use std::cell::RefCell;
use std::marker::PhantomData;
use std::sync::Mutex;
use glib::prelude::*;
use glib::subclass::prelude::*;
use glib_macros::Properties;

#[derive(Default, Clone)]
struct Author {
    name: String,
    nick: String,
}

pub mod imp {
    use glib::{ParamSpec, Value};
    use std::rc::Rc;

    use super::*;

    #[derive(Properties, Default)]
    #[properties(wrapper_type = super::Foo)]
    pub struct Foo {
        #[property(get, set = Self::set_fizz)]
        fizz: RefCell<String>,
        #[property(name = "author-name", get, set, type = String, member = name)]
        #[property(name = "author-nick", get, set, type = String, member = nick)]
        author: RefCell<Author>,
        #[property(get, set, explicit_notify, lax_validation)]
        custom_flags: RefCell<String>,
        #[property(get, set, minimum = 0, maximum = 3)]
        numeric_builder: RefCell<u32>,
        #[property(get, set, builder('c'))]
        builder_with_required_param: RefCell<char>,
        #[property(get, set)]
        optional: RefCell<Option<String>>,
        #[property(get, set)]
        smart_pointer: Rc<RefCell<String>>,
    }

    impl ObjectImpl for Foo {
        fn properties() -> &'static [ParamSpec] {
            Self::derived_properties()
        }
        fn set_property(
            &self,
            _id: usize,
            _value: &Value,
            _pspec: &ParamSpec,
        ) {
            Self::derived_set_property(self, _id, _value, _pspec)
        }
        fn property(&self, _id: usize, _pspec: &ParamSpec) -> Value {
            Self::derived_property(self, _id, _pspec)
        }
    }

    #[glib::object_subclass]
    impl ObjectSubclass for Foo {
        const NAME: &'static str = "MyFoo";
        type Type = super::Foo;
    }

    impl Foo {
        fn set_fizz(&self, value: String) {
            *self.fizz.borrow_mut() = format!("custom set: {}", value);
        }
    }
}

glib::wrapper! {
    pub struct Foo(ObjectSubclass<imp::Foo>);
}

fn main() {
  let myfoo: Foo = glib::object::Object::new();

  myfoo.set_fizz("test value");
  assert_eq!(myfoo.fizz(), "custom set: test value".to_string());
}