gobbi github repo

Casting

Gtk classes derive in a hierarchy from the GObject class.

In gobbi’s implementation of GObject’s classes, each class does not directly extend (or embed in Go terms) its ancestor classes. Instead, for an class instance it is possible to get a reference to an ancestor or descendant class instance for the same gtk object.

upcasting

In a gtk application there will frequently be a need to access members of an object’s ancestor class.

For example when adding a Label to a Container, this will not work.

window := gtk.WindowNew(gtk.GTK_WINDOW_TOPLEVEL)
label := gtk.LabelNew("a label")
window.Add(label)   // <-- ERROR

gtk.Window does not directly have an Add method. The Add method is a member of gtk.Container, which is an ancestor of gtk.Window.

The gtk.Window’s Container may be obtained by calling the Container() method.

And as the Add method expects a gtk.Widget, the gtk.Label’s Widget method is called to cast to a gtk.Widget.

window := gtk.WindowNew(gtk.GTK_WINDOW_TOPLEVEL)
label := gtk.LabelNew("a label")
window.Container().Add(label.Widget())

All derived classes have receiver functions for directly casting to all ancestor types.

// This will work, but is unnecessary.
widget1 := gtk.WindowNew().Bin().Container().Widget()

// This will achieve the same end result.
widget2 := gtk.WindowNew().Widget()

Classes also have receiver functions for casting to any interfaces that they implement.

// gtk.Buildable is an interface implemented by all Widgets.
widget := gtk.LabelNew("a label")
buildable := widget.Buildable()

downcasting

Downcasting operates in the other direction, from a class to a derived class.

Downcasting is less common that upcasting. It is potentially quite dangerous, in that it makes it very easy to assert that a widget is something that it is not.

To downcast an instance, call one of the CastTo... methods.

A typically use is when obtaining an object from a builder.

builder := gtk.BuilderNewFromString(...)

buttonObject := builder.GetObject("some-button")
button := gtk.CastToButton(buttonObject)
button.ConnectClicked(...)

See the builder example to see this in an application.