Generates smart wrappers for GLib modules using GObject-Introspection.
Features of the wrappers:
- Using smart pointers
- Type safe signals
- Information generated by GObject-Introspection, not from the C headers
- Syntactic sugar, for example static methods: Instead of gdk_display_get_default, you can use Display.getDefault
- Idiomatic "new" methods:
newLabel
instead oflabelNew
forgtk_label_new
- Handle GError, convert to exceptions
- Make it easier to inherit from types and interfaces (e.g. important for CellRenderers, TreeModels)
Make sure nim
and the Gtk+-3 libraries are on the search paths. Then call it like smartgi GObject-2.0
to generate bindings for GObject version 2.0. To quickly generate all bindings for the
Gtk+/GLib suite, call rebuild_all.cmd or rebuild_all.sh.
On Windows, it is recommended to us the GObject all-in-one installer from http://sourceforge.net/projects/pygobjectwin32/ (which is actually for Python, but the DLLs work fine with Nim).
Smart pointers are wrappers for objects that automatically free the object when it is no longer
used. There are two ways to implement smart pointers, one is ref
based, and one is based on RAII
and reference counting. The current smart pointers are based on ref
:
type
GSmartPtr*[T] = object
pointer*: ptr T
TObject* = object of TRoot
Object* = ref GSmartPtr[TObject]
The smart pointer object GSmartPtr[T] is essentially just a pointer to the object. The object
struct uses the naming convention TObject
. The C API uses pointers to these objects (ptr TObject
), but in the Nim interface we use the wrapped objects Object
everywhere.
Wrapped objects are not castable to unwrapped objects, as wrapped objects contain another level of
indirection (via ref
). However, it is possible to use implicit and explicit conversion to get a
dumb pointer out of a wrapped object.
The other way to implement smart objects would be to use the structs-containing-pointers directly, and to put copy constructors and destructors on these structs (sorry for not using the correct Nim terminology). In this case, you could cast these smart pointers directly to dumb pointers, as there would be no extra level of indirection.
You can use Gtk3.Object.connect to connect callbacks to signals:
let button = buttonNew()
button.setLabel(u"Hello")
proc buttonClicked(bttn: Button) =
echo "Hello World!"
button.connect("clicked", buttonClicked)
Using some template magic, the callback is checked for the correct argument types. You can pass additional parameters:
proc buttonClicked(bttn: Button, name: string) =
echo "Hello ", name, "!"
button.connect("clicked", buttonClicked, "Nim")
# this will not compile:
# button.connect("clicked", buttonClicked, 10)
(Todo: add some details about how this is implemented.)