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

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

The newest version!
package net.peanuuutz.fork.ui.scene.component

import androidx.compose.runtime.CompositionContext
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import net.peanuuutz.fork.ui.scene.base.DefaultClipboardService
import net.peanuuutz.fork.ui.scene.base.DefaultTextInputDispatcher
import net.peanuuutz.fork.ui.scene.screen.DelegatedPointerService
import net.peanuuutz.fork.ui.scene.screen.ScreenWindowInfo
import net.peanuuutz.fork.ui.ui.context.focus.FocusMoveDirection.Down
import net.peanuuutz.fork.ui.ui.context.focus.FocusMoveDirection.Left
import net.peanuuutz.fork.ui.ui.context.focus.FocusMoveDirection.Next
import net.peanuuutz.fork.ui.ui.context.focus.FocusMoveDirection.Previous
import net.peanuuutz.fork.ui.ui.context.focus.FocusMoveDirection.Right
import net.peanuuutz.fork.ui.ui.context.focus.FocusMoveDirection.Up
import net.peanuuutz.fork.ui.ui.context.key.Key
import net.peanuuutz.fork.ui.ui.context.key.isReleased
import net.peanuuutz.fork.ui.ui.context.key.isShiftPressed
import net.peanuuutz.fork.ui.ui.context.owner.AbstractOwner
import net.peanuuutz.fork.ui.ui.context.owner.OwnerContainer
import net.peanuuutz.fork.ui.ui.context.pointer.PointerService
import net.peanuuutz.fork.ui.ui.context.text.ClipboardService
import net.peanuuutz.fork.ui.ui.context.text.TextInputDispatcher
import net.peanuuutz.fork.ui.ui.context.window.CoordinateConvertor
import net.peanuuutz.fork.ui.ui.context.window.WindowInfo
import net.peanuuutz.fork.ui.ui.draw.canvas.Canvas
import net.peanuuutz.fork.ui.ui.layout.DefaultMeasurePolicy
import net.peanuuutz.fork.ui.ui.modifier.Modifier
import net.peanuuutz.fork.ui.ui.modifier.input.onKeyOut
import net.peanuuutz.fork.ui.ui.modifier.layout.onPlaced
import net.peanuuutz.fork.ui.ui.node.LayoutNode
import net.peanuuutz.fork.ui.ui.unit.FloatOffset
import net.peanuuutz.fork.ui.ui.unit.IntOffset
import net.peanuuutz.fork.ui.ui.unit.IntSize

internal class ComponentOwner(
    context: CompositionContext,
    container: OwnerContainer,
    shouldReceiveEvents: Boolean,
    override val canvas: Canvas
) : AbstractOwner(
        compositionContext = context,
        container = container,
        shouldReceiveEvents = shouldReceiveEvents
    ),
    CoordinateConvertor // Small interfaces don't deserve an object
{
    var position: IntOffset by mutableStateOf(IntOffset.Zero) // Observed by PointerService

    var size: IntSize by mutableStateOf(IntSize.Zero)

    override val root: LayoutNode = LayoutNode().apply {
        modifier = Modifier
            .onKeyOut { event ->
                if (event.isReleased) {
                    return@onKeyOut false
                }
                val direction = when (event.key) {
                    Key.Tab -> if (event.isShiftPressed) Previous else Next
                    Key.Left -> Left
                    Key.Up -> Up
                    Key.Right -> Right
                    Key.Down -> Down
                    else -> return@onKeyOut false
                }
                focusOwner.moveFocus(direction)
            }
            .then(focusOwner.modifier)
            .onPlaced { size = it.size }
        measurePolicy = DefaultMeasurePolicy
    }

    override val clipboardService: ClipboardService
        get() = DefaultClipboardService

    override val coordinateConvertor: CoordinateConvertor
        get() = this

    override val pointerService: PointerService = DelegatedPointerService(this)

    override val textInputDispatcher: TextInputDispatcher = DefaultTextInputDispatcher()

    override val windowInfo: WindowInfo
        get() = ScreenWindowInfo

    override fun doDraw() {
        val (x, y) = position
        val fX = x.toFloat()
        val fY = y.toFloat()
        canvas.translate(fX, fY)
        super.doDraw()
        canvas.translate(-fX, -fY)
    }

    override fun rootToWindow(relativeToRoot: FloatOffset): FloatOffset {
        return relativeToRoot + position
    }

    override fun windowToRoot(relativeToWindow: FloatOffset): FloatOffset {
        return relativeToWindow - position
    }

    override fun exit() {}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy