Skip to content

Instantly share code, notes, and snippets.

@andreas-mausch
Created October 14, 2018 20:18
Show Gist options
  • Save andreas-mausch/f52c9a4c49edd8ffa0c4f68cea85d9d7 to your computer and use it in GitHub Desktop.
Save andreas-mausch/f52c9a4c49edd8ffa0c4f68cea85d9d7 to your computer and use it in GitHub Desktop.
kotlin-native-gtk3
import kotlinx.cinterop.*
import gtk3.*
// Note that all callback parameters must be primitive types or nullable C pointers.
fun <F : CFunction<*>> g_signal_connect(obj: CPointer<*>, actionName: String,
action: CPointer<F>, data: gpointer? = null, connect_flags: GConnectFlags = 0u) {
g_signal_connect_data(obj.reinterpret(), actionName, action.reinterpret(),
data = data, destroy_data = null, connect_flags = connect_flags)
}
abstract class Button(val id: String) {
val ref = StableRef.create(this)
abstract fun clicked()
fun dispose() {
ref.dispose()
}
}
class Builder {
val gtkBuilder = gtk_builder_new()
constructor(xml: String) {
gtk_builder_add_from_string(gtkBuilder, xml, xml.length.toULong(), null)
}
fun connect(button: Button) {
val buttonWidget = gtk_builder_get_object(gtkBuilder, button.id)!!
g_signal_connect(buttonWidget, "clicked",
staticCFunction { _: CPointer<GtkWidget>?, data: gpointer? ->
data!!.asStableRef<Button>().get().clicked()
}, button.ref.asCPointer())
}
}
fun main(args: Array<String>) {
val xml = "<interface>" +
" <object class=\"GtkWindow\" id=\"main-window\">" +
" <child>" +
" <object class=\"GtkVBox\" id=\"vbox-layout\">" +
" <property name=\"homogeneous\">FALSE</property>" +
" <child>" +
" <object class=\"GtkButton\" id=\"first-button\">" +
" <property name=\"label\">First button!</property>" +
" </object>" +
" </child>" +
" <child>" +
" <object class=\"GtkButton\" id=\"second-button\">" +
" <property name=\"label\">Second button!</property>" +
" </object>" +
" </child>" +
" </object>" +
" </child>" +
" </object>" +
"</interface>"
gtk_init(cValuesOf(0), null)
val builder = Builder(xml)
val window = gtk_builder_get_object(builder.gtkBuilder, "main-window")!!.reinterpret<GtkWidget>()
g_signal_connect(window, "destroy", staticCFunction { _: CPointer<GtkWidget>?, _: gpointer? ->
println("Window closed")
gtk_main_quit()
}, null)
val firstButton = object : Button("first-button") {
override fun clicked() {
println("First Button clicked")
}
}
builder.connect(firstButton)
val secondButton = object : Button("second-button") {
override fun clicked() {
println("Second Button clicked")
}
}
builder.connect(secondButton)
gtk_widget_show_all(window)
gtk_main()
println("Main finished")
firstButton.dispose()
secondButton.dispose()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment