-
-
Notifications
You must be signed in to change notification settings - Fork 90
Add automatic signal connection in combination with gtk::Builder #128
Comments
Could maybe make use of https://crates.io/crates/label for this |
The basic problem is that we have a function with a fixed signature of dynamic types that needs to downcast to static types and call the special function. My current best solution to this is by implementing a common trait for that function: pub trait SignalCallback {
fn call(&self, args: &[glib::Value]) -> Option<glib::Value>;
}
impl SignalCallback for Fn<>k::Button> {
fn call(&self, args: &[glib::Value]) -> Option<glib::Value> {
let button = args[0].get::<gtk::Button>().expect("Wrong type").expect("Unexpected None");
self(&button);
None
}
}
…
let callback: impl SignalCallback = button_clicked_handler as SignalCallback; Obviously this has a few drawbacks and I left out a few important things like the actual |
Some prior art: https://idanarye.github.io/woab/woab/derive.BuilderSignal.html It's a derive macro that for an enum with one variant per signal type. |
Looking at
That uses the It seems better to instead use a proc macro on the #[gtk::composite_template]
impl Foo {
#[signal]
foo_bar(&self, widget: &Self::Class) {}
} Though if it's on |
My idea is that with the example code I gave, every function being registered would be within the same block, processed through one invocation of a |
ah, you just make some local state for every implementation. And you annotate the functions you want. Though It'd be awesome to see my library used in some larger project, that's I think an objectively better approach. |
The idea here would be to annotate the signal handler functions with a procedural macro that would export the signature of the function so it can be checked at runtime.
E.g.
This would then expand to something like
The nullability of the arguments would have to be detected/handled automatically based on the types.
Now for connecting the whole thing we would do a new function on
BuilderExt
that callsbuilder.connect_signals()
, assumes/requires that&self
is cloneable, and then viadlsym
(etc) checks for each name ifgtk_rs_priv_NAME
does exist, e.g.gtk_rs_priv_my_button_clicked
.Instead of only supporting a
&self
first parameter we should also allow arbitrary other types that are cloneable, which shouldn't be too hard in addition either.The text was updated successfully, but these errors were encountered: