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

com.almasb.fxgl.entity.components.ViewComponent.kt Maven / Gradle / Ivy

There is a newer version: 21.1
Show newest version
package com.almasb.fxgl.entity.components

import com.almasb.fxgl.core.View
import com.almasb.fxgl.entity.EntityView
import com.almasb.fxgl.entity.component.Component
import com.almasb.fxgl.entity.component.CoreComponent
import javafx.beans.property.*
import javafx.event.EventHandler
import javafx.scene.Group
import javafx.scene.Node
import javafx.scene.input.MouseEvent
import javafx.scene.layout.Pane
import javafx.scene.transform.Rotate
import javafx.scene.transform.Scale

/**
 *
 * @author Almas Baimagambetov ([email protected])
 */
@CoreComponent
class ViewComponent
@JvmOverloads constructor(initialView: View = EmptyView): Component() {

    /**
     * Only the first child is used when calling setView.
     * The other children can be used by systems such as debug bbox as necessary.
     */
    val parent = Group()

    val z: ReadOnlyIntegerProperty = ReadOnlyIntegerWrapper(0)

    @get:JvmName("opacityProperty")
    val opacityProp = SimpleDoubleProperty(1.0)

    var opacity: Double
        get() = opacityProp.value
        set(value) { opacityProp.value = value }

    private val propView: ObjectProperty = SimpleObjectProperty(initialView)

    var view: View
        get() = propView.value
        set(value) {

            if (parent.children.isEmpty()) {
                parent.children += value.node
            } else {
                parent.children[0] = value.node
            }

            propView.value?.node?.opacityProperty()?.unbind()

            propView.value = value

            // we only apply effects to the first child aka game view
            // so debug views stay unaffected
            propView.value.node.opacityProperty().bind(opacityProp)
        }

    /**
     * "Parent" of views created from Node since Node is not subtype of View.
     */
    private val entityView by lazy { EntityView() }

    private val listeners = arrayListOf()

    private val onClickListener = EventHandler { listeners.forEach { it.onClick() } }

    init {
        parent.addEventHandler(MouseEvent.MOUSE_CLICKED, onClickListener)
    }

    fun setViewFromNode(node: Node) {
        entityView.clearChildren()
        entityView.addNode(node)

        view = entityView
    }

    override fun onAdded() {
        parent.translateXProperty().bind(entity.xProperty().subtract(entity.transformComponent.positionOriginXProperty()))
        parent.translateYProperty().bind(entity.yProperty().subtract(entity.transformComponent.positionOriginYProperty()))

        val scale = Scale()
        scale.xProperty().bind(entity.transformComponent.scaleXProperty())
        scale.yProperty().bind(entity.transformComponent.scaleYProperty())

        scale.pivotXProperty().bind(entity.transformComponent.scaleOriginXProperty())
        scale.pivotYProperty().bind(entity.transformComponent.scaleOriginYProperty())

        val rotate = Rotate()
        rotate.axis = Rotate.Z_AXIS
        rotate.angleProperty().bind(entity.transformComponent.angleProperty())

        rotate.pivotXProperty().bind(entity.transformComponent.rotationOriginXProperty())
        rotate.pivotYProperty().bind(entity.transformComponent.rotationOriginYProperty())

        parent.transforms.addAll(rotate, scale)

        (z as ReadOnlyIntegerWrapper).bind(entity.transformComponent.zProperty())
    }

    override fun onUpdate(tpf: Double) {
        view.onUpdate(tpf)
    }

    override fun onRemoved() {
        parent.removeEventHandler(MouseEvent.MOUSE_CLICKED, onClickListener)
        parent.children.clear()
        view.dispose()
    }

    fun addClickListener(l: ClickListener) {
        listeners += l
    }

    fun removeClickListener(l: ClickListener) {
        listeners -= l
    }
}

interface ClickListener {
    fun onClick()
}

private object EmptyView : View {
    override fun onUpdate(tpf: Double) {
    }

    override fun getNode(): Node {
        return Pane()
    }

    override fun dispose() {
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy