#[flags]
Expand description
Attribute macro for defining flags using the bitflags
crate.
This macro will also define a GFlags::type_
function and
the glib::Value
traits.
The expected GType
name has to be passed as macro attribute.
The name and nick of each flag can also be optionally defined.
Default name is the flag identifier in CamelCase and default nick
is the identifier in kebab-case.
Combined flags should not be registered with the GType
system
and so need to be tagged with the #[flags_value(skip)]
attribute.
§Example
use glib::prelude::*;
use glib::subclass::prelude::*;
#[glib::flags(name = "MyFlags")]
enum MyFlags {
#[flags_value(name = "Flag A", nick = "nick-a")]
A = 0b00000001,
#[flags_value(name = "Flag B")]
B = 0b00000010,
#[flags_value(skip)]
AB = Self::A.bits() | Self::B.bits(),
C = 0b00000100,
}
The flags can be registered as a dynamic type by setting the macro helper
attribute flags_dynamic
:
use glib::prelude::*;
use glib::subclass::prelude::*;
#[glib::flags(name = "MyFlags")]
#[flags_dynamic]
enum MyFlags {
...
}
As a dynamic type, the flags must be explicitly registered when the system
loads the implementation (see TypePlugin
and TypeModule
).
Therefore, whereas the flags can be registered only once as a static type,
they can be registered several times as a dynamic type.
The flags registered as a dynamic type are never unregistered. The system
calls TypePluginExt::unuse
to unload the implementation. If the
TypePlugin
subclass is a TypeModule
, the flags registered as a
dynamic type are marked as unloaded and must be registered again when the
module is reloaded.
The macro helper attribute flags_dynamic
provides two behaviors when
registering the flags as a dynamic type:
- lazy registration: by default the flags are registered as a dynamic type
when the system loads the implementation (e.g. when the module is loaded).
Optionally setting
lazy_registration
totrue
postpones registration on the first use (whenstatic_type()
is called for the first time):
#[glib::flags(name = "MyFlags")]
#[flags_dynamic(lazy_registration = true)]
enum MyFlags {
...
}
- registration within
TypeModule
subclass or withinTypePlugin
subclass: the flags are usually registered as a dynamic type within aTypeModule
subclass:
#[glib::flags(name = "MyModuleFlags")]
#[flags_dynamic]
enum MyModuleFlags {
...
}
...
#[derive(Default)]
pub struct MyModule;
...
impl TypeModuleImpl for MyModule {
fn load(&self) -> bool {
// registers flags as dynamic types.
let my_module = self.obj();
let type_module: &glib::TypeModule = my_module.upcast_ref();
MyModuleFlags::on_implementation_load(type_module)
}
...
}
Optionally setting plugin_type
allows to register the flags as a dynamic
type within a TypePlugin
subclass that is not a TypeModule
:
#[glib::flags(name = "MyModuleFlags")]
#[flags_dynamic(plugin_type = MyPlugin)]
enum MyModuleFlags {
...
}
...
#[derive(Default)]
pub struct MyPlugin;
...
impl TypePluginImpl for MyPlugin {
fn use_plugin(&self) {
// register flags as dynamic types.
let my_plugin = self.obj();
MyPluginFlags::on_implementation_load(my_plugin.as_ref());
}
...
}