Skip to content

Commit

Permalink
Added AbstractElement and some fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
AxieFeat committed Aug 25, 2024
1 parent 9bf0269 commit b250dc6
Show file tree
Hide file tree
Showing 9 changed files with 187 additions and 24 deletions.
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ plugins {
}

group = "dev.airdead.arender"
version = "1.0.0"
version = "0.1.4"

repositories {
mavenCentral()
Expand Down
6 changes: 3 additions & 3 deletions common/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ plugins {
kotlin("jvm") version "2.0.0"
}

group = "dev.airdead.arender"
version = "1.0.0"
group = rootProject.group
version = rootProject.version

repositories {
mavenCentral()
Expand All @@ -23,7 +23,7 @@ publishing {
publications {
create<MavenPublication>("maven") {
groupId = project.group.toString()
artifactId = "common"
artifactId = project.name
version = project.version.toString()

from(components["java"])
Expand Down
3 changes: 2 additions & 1 deletion common/src/main/kotlin/dev/airdead/common/Render.kt
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,9 @@ abstract class Render {
* Render all elements.
*
* @param matrix Matrix for render.
* @param tickDelta Tick delta.
*/
abstract fun render(matrix: Matrix)
abstract fun render(matrix: Matrix, tickDelta: Float)

/**
* Current mouse position.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,4 @@ interface InteractiveElement : ParentElement {
* @return True if the element is hovered over, false otherwise.
*/
fun isHovered(mouseX: Double, mouseY: Double): Boolean

/**
* Update hover state.
*
* @param mouseMatrix Mouse matrix.
* @param mouseVector Mouse vector.
*
* @see hovered
*/
fun updateHoverState(mouseMatrix: Matrix4f, mouseVector: Vector4f)
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ package dev.airdead.common.element
*/
interface ParentElement : Element {

var lastParent: Element?

/**
* The list of child elements.
*/
Expand All @@ -17,6 +19,7 @@ interface ParentElement : Element {
*/
fun addChild(vararg elements: Element) {
children.addAll(elements)
lastParent = elements.last()
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ interface RendererElement : ParentElement {
* Render the element.
*
* @param matrix The matrix.
* @param tickDelta Tick delta.
*/
fun render(matrix: Matrix)
fun render(matrix: Matrix, tickDelta: Float)
}
6 changes: 3 additions & 3 deletions core/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ plugins {
id("fabric-loom") version "1.6-SNAPSHOT"
}

group = "dev.airdead.arender"
version = "1.0.0"
group = rootProject.group
version = rootProject.version

repositories {
mavenCentral()
Expand Down Expand Up @@ -45,7 +45,7 @@ publishing {
publications {
create<MavenPublication>("maven") {
groupId = project.group.toString()
artifactId = "core"
artifactId = project.name
version = project.version.toString()

from(components["java"])
Expand Down
11 changes: 6 additions & 5 deletions core/src/main/kotlin/dev/airdead/core/ARender.kt
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ object ARender : Render() {
ClientTickEvents.START_CLIENT_TICK.register(::onClientTick)
}

override fun render(matrix: Matrix) {
elements.forEach { it.render(matrix) }
override fun render(matrix: Matrix, tickDelta: Float) {
elements.forEach { it.render(matrix, tickDelta) }
}

/**
Expand All @@ -47,8 +47,8 @@ object ARender : Render() {
* The callback is responsible for rendering the HUD.
*/
private fun registerCallbacks() {
HudRenderCallback.EVENT.register { drawContext, _ ->
render(CraftMatrix.fromStack(drawContext.matrices))
HudRenderCallback.EVENT.register { drawContext, tickDelta ->
render(CraftMatrix.fromStack(drawContext.matrices), tickDelta)
}
}

Expand All @@ -63,7 +63,8 @@ object ARender : Render() {
// TODO Update elements
}

override val mouse: V2 = V2(ClientAPI.minecraft.mouse.x, ClientAPI.minecraft.mouse.y)
override val mouse: V2
get() = V2(ClientAPI.minecraft.mouse.x, ClientAPI.minecraft.mouse.y)

override fun isMouseButtonClicked(button: Int): Boolean = GLFW.glfwGetMouseButton(ClientAPI.minecraft.window.handle, button) == GLFW.GLFW_PRESS

Expand Down
167 changes: 167 additions & 0 deletions core/src/main/kotlin/dev/airdead/core/element/AbstractElement.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
package dev.airdead.core.element

import dev.airdead.common.Matrix
import dev.airdead.common.animation.AnimationChain
import dev.airdead.common.animation.AnimationExecutable
import dev.airdead.common.animation.Easing
import dev.airdead.common.element.Element
import dev.airdead.common.element.InteractiveElement
import dev.airdead.common.element.RendererElement
import dev.airdead.common.element.WorldElement
import dev.airdead.common.handler.ClickHandler
import dev.airdead.common.handler.HoverHandler
import dev.airdead.common.misc.Rotation
import dev.airdead.common.misc.location.CENTER
import dev.airdead.common.misc.location.V3
import dev.airdead.common.misc.location.x
import dev.airdead.common.misc.rotation
import dev.airdead.core.animation.CraftAnimation
import dev.airdead.core.animation.CraftAnimationChain
import dev.airdead.core.animation.CraftAnimationExecutable
import dev.airdead.core.utility.client.CraftResolution

/**
* Abstract element with basic logic. You can use it for render in hud or world.
*/
abstract class AbstractElement : InteractiveElement, RendererElement, WorldElement {

open lateinit var matrix: Matrix

override var lastParent: Element? = null
override val children: MutableList<Element> = mutableListOf()

override var enabled: Boolean = true
override var interactive: Boolean = true

override var hovered: Boolean = false

override var size: V3 = 0 x 0
override var align: V3 = CENTER
override var origin: V3 = CENTER
override var offset: V3 = 0 x 0
override var rotation: Rotation = 0.rotation()
override var location: V3 = 0 x 0

private val onHover = mutableListOf<HoverHandler>()
private val onLeftClick = mutableListOf<ClickHandler>()
private val onRightClick = mutableListOf<ClickHandler>()

private val beforeRender = mutableListOf<() -> Unit>()
private val afterRender = mutableListOf<() -> Unit>()

private val beforeTransform = mutableListOf<() -> Unit>()
private val afterTransform = mutableListOf<() -> Unit>()

private val animations = mutableListOf<AnimationChain>()

override fun onHover(handler: HoverHandler) {
this.onHover.add(handler)
}

override fun onLeftClick(handler: ClickHandler) {
this.onLeftClick.add(handler)
}

override fun onRightClick(handler: ClickHandler) {
this.onRightClick.add(handler)
}

override fun afterRender(action: () -> Unit) {
afterRender.add(action)
}

override fun beforeRender(action: () -> Unit) {
beforeRender.add(action)
}

override fun afterTransform(action: () -> Unit) {
afterTransform.add(action)
}

override fun beforeTransform(action: () -> Unit) {
beforeTransform.add(action)
}

override fun isHovered(mouseX: Double, mouseY: Double): Boolean =
mouseX in location.doubleX..(location.doubleX + size.doubleX) &&
mouseY in location.doubleY..(location.doubleY + size.doubleY)

/**
* Transforms and renders the element.
*
* @param matrix The matrix.
* @param tickDelta The time delta since the last update.
*/
override fun render(matrix: Matrix, tickDelta: Float) {
if (!enabled) return

beforeTransform.forEach { it.invoke() }
updateAnimations(tickDelta)
updateRenderLocation()
afterTransform.forEach { it.invoke() }

matrix.push()
matrix.translate(0.0, offset.doubleY, 0.0)

beforeRender.forEach { it.invoke() }
renderElement(matrix, tickDelta)
afterRender.forEach { it.invoke() }
matrix.pop()

this.matrix = matrix
}

override fun animate(
duration: Double,
easing: Easing,
updateProperties: AnimationExecutable.() -> Unit
): AnimationChain {
val executable = CraftAnimationExecutable()
executable.updateProperties()

val animation = CraftAnimation(executable.properties, duration * 20, easing::ease)
val chain = CraftAnimationChain(this, animation)

animations.add(chain)

return chain
}

/**
* Updates the render location of the element.
*/
private fun updateRenderLocation() {
val defaultSize = V3(CraftResolution.scaledWidth, CraftResolution.scaledHeight, 1.0)
val parentSize = lastParent?.size ?: defaultSize
location = V3(
calculateAbsolutePosition(parentSize.doubleX, size.doubleX, align.doubleX, origin.doubleX, (lastParent as RendererElement?)?.location?.doubleY, offset.doubleX),
calculateAbsolutePosition(parentSize.doubleY, size.doubleY, align.doubleY, origin.doubleY, (lastParent as RendererElement?)?.location?.doubleY, offset.doubleY),
location.z
)
}

/**
* Calculates the absolute position of the element.
*
* @param parentSize The size of the parent element.
* @param size The size of the element.
* @param align The alignment of the element.
* @param origin The origin point of the element.
* @param parentOffset The offset of the parent element.
* @param offset The offset of the element.
* @return The absolute position of the element.
*/
open fun calculateAbsolutePosition(parentSize: Double, size: Double, align: Double, origin: Double, parentOffset: Double?, offset: Double) =
parentSize * align - size * origin + (parentOffset ?: 0.0) + offset

/**
* Updates the animations of the element.
*
* @param tickDelta The time delta since the last update.
*/
open fun updateAnimations(tickDelta: Float) {
animations.removeIf { it.update(tickDelta) }
}

abstract fun renderElement(matrix: Matrix, tickDelta: Float)
}

0 comments on commit b250dc6

Please sign in to comment.