net.peanuuutz.fork.ui.scene.component.NativeWidgetComposable.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of fork-ui Show documentation
Show all versions of fork-ui Show documentation
Comprehensive API designed for Minecraft modders
The newest version!
package net.peanuuutz.fork.ui.scene.component
import androidx.compose.runtime.Composable
import androidx.compose.runtime.ComposeNode
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.currentComposer
import androidx.compose.runtime.currentCompositeKeyHash
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.LocalSaveableStateRegistry
import net.minecraft.client.gui.widget.Widget
import net.peanuuutz.fork.ui.ui.modifier.Modifier
import net.peanuuutz.fork.ui.ui.modifier.materialize
import net.peanuuutz.fork.ui.ui.node.LayoutNode
import net.peanuuutz.fork.ui.ui.node.LayoutNodeApplier
import net.peanuuutz.fork.util.common.getValue
import net.peanuuutz.fork.util.common.lazyRef
import net.peanuuutz.fork.util.common.setValue
@Composable
fun NativeWidget(
factory: () -> W,
modifier: Modifier = Modifier,
update: ((W) -> Unit)? = null,
measurePolicy: NativeWidgetMeasurePolicy = DefaultNativeWidgetMeasurePolicy
) {
val materialized = currentComposer.materialize(modifier)
val registry = LocalSaveableStateRegistry.current
val dataKey = currentCompositeKeyHash.toString()
var adapterRef by remember { lazyRef>() }
ComposeNode(
factory = {
val adapter = NativeWidgetAdapter(factory()).also { adapterRef = it }
registry?.consumeRestored(dataKey).let { adapter.widget.restoreData(it) }
adapter.layoutNode
},
update = {
set(materialized) { provided ->
adapterRef.updateModifier(provided)
}
set(measurePolicy) { provided ->
adapterRef.updateMeasurePolicy(provided)
}
set(update) { providedUpdate ->
providedUpdate?.invoke(adapterRef.widget)
}
}
)
DisposableEffect(Unit) {
onDispose(adapterRef.widget::dispose)
}
if (registry != null) {
DisposableEffect(registry, dataKey) {
val entry = registry.registerProvider(dataKey, adapterRef.widget::saveData)
onDispose {
entry.unregister()
}
}
}
}
@Composable
fun DelegatingNativeWidget(
factory: () -> W,
modifier: Modifier = Modifier,
update: ((W) -> Unit)? = null,
measurePolicy: DelegatingNativeWidgetMeasurePolicy = DefaultNativeWidgetMeasurePolicy
) {
val nativeWidgetFactory = { DelegatingNativeWidget(factory()) }
val nativeWidgetUpdate = update?.let { updateBlock ->
{ delegatingNativeWidget: DelegatingNativeWidget ->
updateBlock(delegatingNativeWidget.delegate)
}
}
NativeWidget(
factory = nativeWidgetFactory,
modifier = modifier,
update = nativeWidgetUpdate,
measurePolicy = measurePolicy
)
}