Skip to content

Instantly share code, notes, and snippets.

@Takhion
Created May 26, 2019 11:20
Show Gist options
  • Save Takhion/454e947de50bc73722c4e55a0b29d5e2 to your computer and use it in GitHub Desktop.
Save Takhion/454e947de50bc73722c4e55a0b29d5e2 to your computer and use it in GitHub Desktop.
[Kotlin/Native] CallbackUtils.kt
import kotlinx.cinterop.ObjCAction
import kotlinx.cinterop.StableRef
import platform.AppKit.NSControl
import platform.Foundation.NSSelectorFromString
import platform.darwin.NSObject
import platform.objc.OBJC_ASSOCIATION_RETAIN
import platform.objc.objc_setAssociatedObject
/**
* Specify a [callback][onAction] for an [NSControl] action, instead of setting
* [NSControl.target] and [NSControl.action] with a delegate.
*/
fun NSControl.action(
onAction: () -> Unit
) =
ActionCallback(onAction).bindTo(this)
private class ActionCallback(
private val onAction: () -> Unit
) : NSObject() {
@ObjCAction
private fun invokeAction() = onAction()
fun bindTo(view: NSControl) {
view.target = this
view.action = NSSelectorFromString(::invokeAction.name)
/** attach to the view lifecycle, since [NSControl.target] is a weak ref! */
objc_setAssociatedObject(
`object` = view,
key = associatedObjectKey,
value = this@ActionCallback,
policy = OBJC_ASSOCIATION_RETAIN
)
}
private companion object {
private val associatedObjectKey = StableRef.create(Any()).asCPointer()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment