Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remnants For Composite Template Support #77

Closed
3 tasks done
BrainBlasted opened this issue Nov 24, 2020 · 25 comments
Closed
3 tasks done

Remnants For Composite Template Support #77

BrainBlasted opened this issue Nov 24, 2020 · 25 comments
Labels
enhancement New feature or request gtk

Comments

@BrainBlasted
Copy link
Contributor

BrainBlasted commented Nov 24, 2020

After #51 is merged, there's still some work left to do:

  • Find a way to use the CompositeTemplate trait's bind_template_children fn
    as klass.bind_template_children()
  • Find a way to handle instance_init() so that init_template() can be called
    from it.
  • Add support for signals/callbacks in templates
@sdroege
Copy link
Member

sdroege commented Nov 24, 2020

Add support for signals/callbacks in templates

For this one there is #24 https://github.com/gtk-rs/gtk-rs/issues/173 gtk-rs/gtk3-rs#128

@BrainBlasted
Copy link
Contributor Author

I don't think BuilderScope is required. See https://gnome.pages.gitlab.gnome.org/gtk/gtk/GtkWidget.html#gtk-widget-class-bind-template-callback for templates

@sdroege
Copy link
Member

sdroege commented Nov 24, 2020

That only works for C function callbacks (with pointers and stuff). Bindings should go via GClosures based signal API that allows to do things safely via a &[glib::Value] parameter instead, which is basically half of what the builder scope does.

@BrainBlasted
Copy link
Contributor Author

Ah, I see

@bilelmoussaoui bilelmoussaoui added enhancement New feature or request gtk labels Nov 24, 2020
@bilelmoussaoui
Copy link
Member

Not sure if something like Vala & Python's possibility to set the path/uri to a UI file with a decorator would be possible in how things are handled from Rust I was thinking of an attribute of CompositeTemplate to automatically generate a class_init with the proper set_template & call to bind_template_children.

Vala:

[GtkTemplate (ui = "/org/gnome/clocks/ui/alarm-day-picker-row.ui")]
public class DayPickerRow : Hdy.ActionRow {
} 

Python:

@Gtk.Template(resource_path='/com/github/bilelmoussaoui/Authenticator/settings.ui')
class SettingsWindow(Handy.PreferencesWindow):
    __gtype_name__ = 'SettingsWindow'

@bilelmoussaoui
Copy link
Member

Something I have noticed while porting some of my code to use templates is that often the id is the same name you give to the field and having to always specify it as an attribute is not great? maybe we should fallback to the field name in case the id attribute wasn't passed

@sdroege
Copy link
Member

sdroege commented Dec 5, 2020

Sounds like an easy improvement, yes

@felinira
Copy link
Contributor

felinira commented Dec 6, 2020

What is the blocker in handling instance_init? Can't it be exposed via ObjectSubclass in glib?

@sdroege
Copy link
Member

sdroege commented Dec 6, 2020

What is the blocker in handling instance_init? Can't it be exposed via ObjectSubclass in glib?

That's doable but not so easy. At that point the object is not fully constructed and it's generally unsafe to do anything at all with it except for a few limited operations. If someone wants to work on that, go ahead :) But I didn't need that for anything so I didn't spend more time on it when implementing the subclassing support in gtk-rs.

From a Rust point of view it should be sufficient to call this in ObjectImpl::constructed exactly because we don't have instance_init. So if you call it before chaining up to the parent class' constructed, there can't at least be any Rust code expecting the templates to be bound already.

@bilelmoussaoui
Copy link
Member

One thing that we should do is that every type defined in the UI file should be ensured by calling gobject_sys::g_type_ensure. This would allow us to use types defined from Rust inside the templates which would be super useful for things like GtkExpression support or just simply using a widget defined in template 1 inside template 2.

@sdroege
Copy link
Member

sdroege commented Dec 8, 2020

Where do you want to call that and how do you want to find the types to call it on?

@bilelmoussaoui
Copy link
Member

bilelmoussaoui commented Dec 8, 2020

Where do you want to call that and how do you want to find the types to call it on?

Good question, we can at least do so for the types that were explicitly tagged by template_child attribute ? :)

@sdroege
Copy link
Member

sdroege commented Dec 8, 2020

Yeah but not sure how useful that is :)

@BrainBlasted
Copy link
Contributor Author

BrainBlasted commented Dec 8, 2020

That's taken care of already by gtk::init() and libhandy::init() (as examples); For types created in applications, you'd call SomeType::static_type() before using it in a template/UI file. This is how it works in C as well, though they use type_ensure() instead of static_type()

@felinira
Copy link
Contributor

felinira commented Dec 8, 2020

I was wondering if it would be useful to expose a second method for each major initialization function. Something like class_init_private that would be called before (or after? would need to think about it) the regular function. This would allow composite template code to generate code for these functions without colliding with custom user implementations.

@sdroege
Copy link
Member

sdroege commented Dec 8, 2020

How would that compose with other (derive, etc) macros producing code for them too?

@felinira
Copy link
Contributor

felinira commented Dec 8, 2020

Maybe that would become clearer once those are written. I guess those derive macros are supposed to be independent from composite template support? I still can't really imagine how they would look like in that case. Especially ObjectSubclass isn't really easy to automate without having any way to gather the ParentClass and NAME from. And ::new()/withClass() seems to be nearly impossible in any case.

@felinira
Copy link
Contributor

felinira commented Dec 8, 2020

TemplateChild might also benefit from some more work. Currently it will panic on the first use of the widget if the template didn't load properly. It would probably be nicer if all TemplateChildren would be gathered somewhere and initialized together in gtk::init or at least in class_init. This would maybe even allow to store the rust struct alongside the gtk object in the TemplateChildren struct and implement Deref on TemplateChild to avoid having to write .get() every time.

@sdroege
Copy link
Member

sdroege commented Dec 9, 2020

implement Deref on TemplateChild to avoid having to write .get() every time.

I'm not sure why that wasn't done yet btw. It should just implement Deref instead of having to call get(). @BrainBlasted, @bilelmoussaoui ? :)

I guess those derive macros are supposed to be independent from composite template support?

I'm planning a derive macro for properties and that would also have to interfere with the same functions. For that very reason I'm not planning to inject code into those functions there for now until we figure out a solution how to do this in a composable way, and until then require a function call in user code to not paint ourselves into a corner.

I don't know what other derive macros there could be. Maybe something for signals, that would also seem useful but I don't know how that could look in practice. And I'm sure you'll find more things in GTK :)

@YaLTeR
Copy link
Contributor

YaLTeR commented Dec 14, 2020

instance_init() is here => #121

@ids1024
Copy link
Contributor

ids1024 commented Jan 21, 2021

Even with the Deref implementation, it seems a reference to a TemplateChild can't be used in argument position where the argument has a type bound like T: IsA<Widget>. Not sure the based way to deal with that.

@BrainBlasted
Copy link
Contributor Author

You can use it, you just need to deref it when passing it as an argument. foo<W: IsA<gtk::Widget>>(bar: &W) would be called as foo(&*self.some_template_child)

@ids1024
Copy link
Contributor

ids1024 commented Jan 22, 2021

Ah, I hadn't though of the &* notation.

That's relatively concise, but it would be nice if that weren't necessary.

@sdroege
Copy link
Member

sdroege commented Jan 22, 2021

That would need a blanket implementation that can't really exist

impl<T: Deref<Target=U>, U: IsA<V>, V: ...> IsA<V> for T { ... }`

@bilelmoussaoui
Copy link
Member

#945 should handle the last remaining part of this issue

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request gtk
Projects
None yet
Development

No branches or pull requests

6 participants