Inceptum/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/control/KSignalListItemFactory.kt

58 lines
2.0 KiB
Kotlin

package io.gitlab.jfronny.inceptum.gtk.control
import io.github.jwharm.javagi.gobject.SignalConnection
import org.gnome.gtk.ListItem
import org.gnome.gtk.SignalListItemFactory
import org.gnome.gtk.StringObject
import org.gnome.gtk.Widget
abstract class KSignalListItemFactory<TData, TWidget : Widget> : SignalListItemFactory() {
private val toDisconnect: MutableMap<String, MutableSet<SignalConnection<*>>> = HashMap()
init {
onSetup {
val li = it as ListItem
li.child = setup()
}
onBind {
val li = it as ListItem
val id = (li.item as StringObject).string
val context = BindContextImpl(id, li)
val widget = context.castWidget(li.child!!)
context.bind(widget, context.lookup(id, widget))
}
onUnbind {
val li = it as ListItem
val id = (li.item as StringObject).string
val context = UnbindContextImpl(li)
val widget = context.castWidget(li.child!!)
toDisconnect.remove(id)?.forEach { it.disconnect() }
context.unbind(widget, context.lookup(id, widget))
}
}
abstract fun setup(): TWidget
abstract fun BindContext.bind(widget: TWidget, data: TData)
abstract fun UnbindContext.unbind(widget: TWidget, data: TData)
abstract fun ActionContext.lookup(id: String, widget: TWidget): TData
abstract fun ActionContext.castWidget(widget: Widget): TWidget
interface ActionContext {
val listItem: ListItem
}
interface BindContext: ActionContext {
fun registerForUnbind(signal: SignalConnection<*>)
}
interface UnbindContext: ActionContext {
}
private inner class BindContextImpl(private val id: String, override val listItem: ListItem) : BindContext {
override fun registerForUnbind(signal: SignalConnection<*>) {
toDisconnect.computeIfAbsent(id) { _ -> HashSet() }
.add(signal)
}
}
private inner class UnbindContextImpl(override val listItem: ListItem): UnbindContext
}