All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.peanuuutz.fork.ui.scene.component.NativeWidgetComposable.kt Maven / Gradle / Ivy

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
    )
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy