Skip to content
This repository has been archived by the owner on Jun 8, 2021. It is now read-only.

Commit

Permalink
Implement Builder::connect_signals_full
Browse files Browse the repository at this point in the history
  • Loading branch information
sfanxiang committed Jul 18, 2019
1 parent 292268a commit 95e3344
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 0 deletions.
4 changes: 4 additions & 0 deletions Gir.toml
Original file line number Diff line number Diff line change
Expand Up @@ -641,6 +641,10 @@ manual_traits = ["BuilderExtManual"]
ignore = true
doc_trait_name = "BuilderExtManual"
[[object.function]]
name = "connect_signals_full"
#manual: connect object and swapped signal not supported
ignore = true
[[object.function]]
name = "get_object"
#downcast
ignore = true
Expand Down
26 changes: 26 additions & 0 deletions src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@

use glib::object::{Cast, IsA};
use glib::translate::*;
use glib::GString;
use glib::Object;
use glib::ObjectExt;
use gtk_sys;
use std::path::Path;
use Builder;
Expand All @@ -24,6 +26,7 @@ impl Builder {
pub trait BuilderExtManual: 'static {
fn get_object<T: IsA<Object>>(&self, name: &str) -> Option<T>;
fn add_from_file<T: AsRef<Path>>(&self, file_path: T) -> Result<(), Error>;
fn connect_signals_full<P: FnMut(&Builder, &str) -> Box<dyn Fn(&[glib::Value]) -> Option<glib::Value> + Send + Sync + 'static>>(&self, func: P);
}

impl<O: IsA<Builder>> BuilderExtManual for O {
Expand Down Expand Up @@ -52,4 +55,27 @@ impl<O: IsA<Builder>> BuilderExtManual for O {
}
}
}

fn connect_signals_full<P: FnMut(&Builder, &str) -> Box<dyn Fn(&[glib::Value]) -> Option<glib::Value> + Send + Sync + 'static>>(&self, func: P) {
let func_data: P = func;
unsafe extern "C" fn func_func<P: FnMut(&Builder, &str) -> Box<dyn Fn(&[glib::Value]) -> Option<glib::Value> + Send + Sync + 'static>>(builder: *mut gtk_sys::GtkBuilder, object: *mut gobject_sys::GObject, signal_name: *const libc::c_char, handler_name: *const libc::c_char, connect_object: *mut gobject_sys::GObject, flags: gobject_sys::GConnectFlags, user_data: glib_sys::gpointer) {
assert!(connect_object.is_null(), "Connect object is not supported");
assert!(flags & gobject_sys::G_CONNECT_SWAPPED == 0, "Swapped signal handler is not supported");

let builder = from_glib_borrow(builder);
let object: glib::Object = from_glib_borrow(object);
let signal_name: GString = from_glib_borrow(signal_name);
let handler_name: GString = from_glib_borrow(handler_name);
let callback: *mut P = user_data as *const _ as usize as *mut P;
let func = (*callback)(&builder, handler_name.as_str());
object
.connect(signal_name.as_str(), flags.contains(gobject_sys::G_CONNECT_AFTER), move |args| func(args))
.expect("Failed to connect to builder signal");
}
let func = Some(func_func::<P> as _);
let super_callback0: &P = &func_data;
unsafe {
gtk_sys::gtk_builder_connect_signals_full(self.as_ref().to_glib_none().0, func, super_callback0 as *const _ as usize as *mut _);
}
}
}

0 comments on commit 95e3344

Please sign in to comment.