Skip to content

Commit

Permalink
Allow implementing a GAction interface
Browse files Browse the repository at this point in the history
  • Loading branch information
andy128k committed Jan 28, 2025
1 parent 35e15b7 commit 59cbb3a
Show file tree
Hide file tree
Showing 5 changed files with 546 additions and 0 deletions.
4 changes: 4 additions & 0 deletions examples/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,7 @@ path = "object_subclass/main.rs"
[[bin]]
name = "virtual_methods"
path = "virtual_methods/main.rs"

[[bin]]
name = "gio_action_impl"
path = "gio_action_impl/main.rs"
91 changes: 91 additions & 0 deletions examples/gio_action_impl/action.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
use gio::{prelude::*, subclass::prelude::*};
use glib;

mod imp {
use super::*;
use std::cell::OnceCell;

#[derive(glib::Properties, Default)]
#[properties(wrapper_type = super::RenamedAction)]
pub struct RenamedAction {
#[property(get, construct_only)]
pub new_name: OnceCell<glib::GString>,

#[property(get, construct_only)]
pub action: OnceCell<gio::Action>,
}

#[glib::object_subclass]
impl ObjectSubclass for RenamedAction {
const NAME: &str = "ExampleRenamedAction";
type Type = super::RenamedAction;
type Interfaces = (gio::Action,);
}

#[glib::derived_properties]
impl ObjectImpl for RenamedAction {
fn properties() -> &'static [glib::ParamSpec] {
Self::derived_properties()
}

fn set_property(&self, id: usize, value: &glib::Value, pspec: &glib::ParamSpec) {
let _ = self.delegate_set_property(id, value, pspec) || {
self.derived_set_property(id, value, pspec);
true
};
}

fn property(&self, id: usize, pspec: &glib::ParamSpec) -> glib::Value {
self.delegate_get_property(id, pspec)
.unwrap_or_else(|| self.derived_property(id, pspec))
}
}

impl ActionImpl for RenamedAction {
fn name(&self) -> glib::GString {
self.obj().new_name()
}

fn parameter_type(&self) -> Option<glib::VariantType> {
self.obj().action().parameter_type()
}

fn state_type(&self) -> Option<glib::VariantType> {
self.obj().action().state_type()
}

fn state_hint(&self) -> Option<glib::Variant> {
self.obj().action().state_hint()
}

fn is_enabled(&self) -> bool {
self.obj().action().is_enabled()
}

fn state(&self) -> Option<glib::Variant> {
self.obj().action().state()
}

fn change_state(&self, value: glib::Variant) {
self.obj().action().change_state(&value);
}

fn activate(&self, parameter: Option<glib::Variant>) {
self.obj().action().activate(parameter.as_ref());
}
}
}

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

impl RenamedAction {
pub fn new(name: &str, action: &impl IsA<gio::Action>) -> Self {
glib::Object::builder()
.property("new-name", name)
.property("action", action)
.build()
}
}
22 changes: 22 additions & 0 deletions examples/gio_action_impl/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
mod action;

use gio::prelude::*;

fn main() {
let action = gio::SimpleAction::new("bark", Some(glib::VariantTy::STRING));
action.connect_activate(|_, p| {
let target = p.unwrap().str().unwrap();
println!("Woof, {}!", target);
});

let renamed_action = action::RenamedAction::new("meow", &action);

let group = gio::SimpleActionGroup::new();
group.add_action(&action);
group.add_action(&renamed_action);

println!("actions = {:?}", group.list_actions());

group.activate_action("bark", Some(&"postman".to_variant()));
group.activate_action("meow", Some(&"milkman".to_variant()));
}
Loading

0 comments on commit 59cbb3a

Please sign in to comment.