I have just shipped v0.2 of package gintro. Its connect macro can now deal with arbitrary number of arguments, which is needed for a few callbacks like the "draw" callback for DrawingArea widget. (Additional, module gtksourceview is now included, as well as a preliminary version of full cairo drawing module, but that one still needs some manual tuning, because cairo is not really supported by gobject introspection.)
Seems to work fine, but one minor problem is the name conflict of modules gio and gtk -- gio has type Application, and gtk has a subclass of it. Import with except works, but using module name prefix seems not to work:
# nim c connect_args.nim
import gintro/[gtk, glib, gobject]
import gintro/gio #except Application, newApplication
type
O = object
i: int
proc b1Callback(button: Button; str: string) =
echo str
proc b2Callback(button: Button; o: O) =
echo "Value of field i in object o = ", o.i
proc b3Callback(button: Button; r: ref O) =
echo "Value of field i in ref to object O = ", r.i
proc b4Callback(button: Button; w: ApplicationWindow) =
if w.title == "Nim with GTK3":
w.title = "GTK3 with Nim"
else:
w.title = "Nim with GTK3"
proc activate (app: gtk.Application) =
var o: O
var r: ref O
new r
o.i = 1234567
r.i = 7654321
let window = gtk.newApplicationWindow(app)
let box = newBox(Orientation.vertical, 0)
window.title = "Parameters for callbacks"
let b1 = newButton("Nim with GTK3")
let b2 = newButton("Passing an object from stack")
let b3 = newButton("Passing an object from heap")
let b4 = newButton("Passing a Widget")
b1.connect("clicked", b1Callback, "is much fun.")
b2.connect("clicked", b2Callback, o)
b3.connect("clicked", b3Callback, r)
b4.connect("clicked", b4Callback, window)
box.add(b1)
box.add(b2)
box.add(b3)
box.add(b4)
window.add(box)
window.showAll
proc main =
let app = gtk.newApplication("org.gtk.example")
connect(app, "activate", activate)
discard app.run
main()
connect_args.nim(50, 10) template/generic instantiation from here
lib/core/macros.nim(368, 17) Error: Error: ambiguous identifier: 'Application' --use gtk.Application or gio.Application
Such macro related error message are a big demand for me, for a few I spent some hours to find the true origin. AS this one is not really a showstopper, I have not tried finding the source or a fix myself yet.
The connect macro is located at
https://github.com/StefanSalewski/gintro/blob/master/gintro/gimpl.nim#L30
I assume that users may not really like an import with mandatory except. And I hesitate to rename gio.Application to GApplication, because it may generate some confusion, and is not really straight forward, because other modules may refer to gio.Application as well.
I had the hope that someone would see the solution immediately. Testing (Linux) is possible with only a few commands of course, as we have a nimble package:
cd /tmp
git clone https://github.com/stefansalewski/gintro
cd gintro
nimble prepare
nimble install
But I will try to provide a shorter example...
Seems to be the same problem again. Compiling
https://github.com/StefanSalewski/gintro/blob/master/examples/gtk3/css_colored_listview.nim
does only work with
import gintro/gdk except Window
without the except we get
/tmp/gtk3/css_colored_listview.nim(61, 10) template/generic instantiation of `connect` from here
/home/stefan/Nim/lib/core/macros.nim(549, 12) Error: ambiguous identifier: 'Window' -- use one of the following:
gtk.Window: Window
gdk.Window: Window
For gio.Application I solved that issue years ago by renaming it to GApplication. But renaming all conflicting data types, like GtkWindow vs GdkWindow?
The error message does not give a location, but I assume that the ambiguous identifiers are generated in the mconnect macro in https://github.com/StefanSalewski/gintro/blob/master/gintro/gimpl.nim. I would guess that it is the first parameter in macro mconnect(widget: gobject.Object;. Is there a way to get the module name of the passed object?
I think Araq recommended some years ago to rewrite the full macro to use no string manipulation, but only AST manipulation. But can you guaranty that this will solve the issue. If yes, than I may try it in winter, or maybe hire someone.
Is there a way to get the module name of the passed object?
maybe something like:
proc getTypeOwner(x: NimNode): string =
result = x.getTypeInst.owner.strVal
Ah yes, macros.owner() seems to be what I need.
Have just added line
echo widget.getTypeInst.owner.strVal
to mconnect() macro and output is gtk, exactly the module name what I need.
It was not really obvious for me that term owner is related to module identifier from API docs: