Closed megatux closed 5 years ago
I guess you could use super Gtk::Application.new("org.crystal.sample", Gio::ApplicationFlags::FLAGS_NONE).to_unsafe.as LibGtk::Application*
for now
That works but can not move forward a lot because I can not instantiate a custom inherited Windows class:
require "gtk"
class ExampleAppWindow < Gtk::ApplicationWindow
end
class ExampleApp < Gtk::Application
def initialize
super Gtk::Application.new("org.crystal.sample", Gio::ApplicationFlags::FLAGS_NONE).to_unsafe.as LibGtk::Application*
on_activate do |application|
window = ExampleAppWindow.new(application)
window.present
end
end
end
app = ExampleApp.new
puts app.run(ARGC_UNSAFE, ARGV_UNSAFE)
There is an error in ExampleAppWindow.new(application)
I don't understand.
The error is this one:
$ crystal samples/tutorial/example_app1/example_app1.cr
Error in samples/tutorial/example_app1/example_app1.cr:54: instantiating 'ExampleApp:Class#new()'
app = ExampleApp.new
^~~
in samples/tutorial/example_app1/example_app1.cr:34: instantiating 'ExampleAppWindow:Class#new(Gio::Application+)'
window = ExampleAppWindow.new(application)
^~~
in src/generated/gtk/application_window.cr:26: instantiating 'cast(Gtk::Widget)'
cast Gtk::Widget.new(__return_value)
^~~~
in samples/tutorial/example_app1/example_app1.cr:24: expanding macro
class ExampleAppWindow < Gtk::ApplicationWindow
^
in macro 'inherited' expanded macro: included:1, line 3:
1. # Add run-time check
2. def self.cast(object) : self
> 3. new(object.to_unsafe.as(LibExampleAppWindow*))
4. end
5.
undefined constant LibExampleAppWindow (did you mean 'ExampleAppWindow')
@megatux it looks like crystal-gobject doesn't support user-defined gobject types yet. Is it possible to rewrite the example without inheritance?
It's absolutely possible, I just wanted to stay as close as possible to the Ruby-Gtk+ binding examples.
add inherit_gobject
macro to wrapped_type.cr
its use is explicit.
module GObject
module WrappedType
macro included
macro inherited
# Add run-time check
def self.cast(object) : self
new(object.to_unsafe.as(Lib\{{@type}}*))
end
end
macro inherit_gobject
# Add run-time check
def self.cast(object) : self
new(object.to_unsafe.as(Lib\{{@type.superclass}}*))
end
end
# Add run-time check
def self.cast(object) : self
new(object.to_unsafe.as(Lib{{@type}}*))
end
end
end
end
and the example runs.
class ExampleAppWindow < Gtk::ApplicationWindow
inherit_gobject
end
class ExampleApp < Gtk::Application
inherit_gobject
def initialize(ptr)
super
on_activate do |application|
window = ExampleAppWindow.new(self)
window.present
end
end
def self.new(id, flags)
super
end
end
app = ExampleApp.new("org.crystal.sample", Gio::ApplicationFlags::FLAGS_NONE)
puts app.run(ARGC_UNSAFE, ARGV_UNSAFE)
Mh, I'm not convinced since this only works one level down. Maybe we can try to check for the presence of Lib\{{@type}}
and chase up the inheritance chain until we find an existing constant? That is in the inherited
macro, so it would work seamlessly. Not sure it's possible right now with the macro language (checking for a constants presence).
This seems to work.
wrapped_type.cr
module GObject
module WrappedType
macro _g_if_defined?(path, &blok)
{% if path.resolve? %}
{{blok.body}}
{% else %}
super
{% end %}
end # === macro _g_if_defined
macro included
macro inherited
# Add run-time check
def self.cast(object) : self
_g_if_defined?(::Lib\{{@type}}) do
return self.new(object.to_unsafe.as(Lib\{{@type}}*))
end
end
end
# Add run-time check
def self.cast(object) : self
new(object.to_unsafe.as(Lib{{@type}}*))
end
end
end
end
@ppibburr Thanks that gave me the right thinking, I went for a slight variation of that :)
I hate how you have to redefine the self.new
overloads when you subclass and override initialize
, maybe we can provide some kind of after_initialize
hook or so to avoid that, but that's for another time.
Glad to see this issue fixed. I'll resume my tests examples.
Hi, I'm translating some examples from Ruby-gnome2 bindings. The example Apps dir contains classes that inherits from Gtk::Application . I tried this:
I got: