Compare commits

...

1 Commits

Author SHA1 Message Date
Shadowfacts f474c4c8bf
Add NinePatchTexture and NinePatchView 2019-06-23 20:02:47 -04:00
4 changed files with 162 additions and 15 deletions

View File

@ -3,15 +3,13 @@ package net.shadowfacts.asmr
import net.minecraft.util.Identifier import net.minecraft.util.Identifier
import net.shadowfacts.kiwidsl.dsl import net.shadowfacts.kiwidsl.dsl
import net.shadowfacts.cacao.CacaoScreen import net.shadowfacts.cacao.CacaoScreen
import net.shadowfacts.cacao.view.View
import net.shadowfacts.cacao.Window import net.shadowfacts.cacao.Window
import net.shadowfacts.cacao.geometry.Axis import net.shadowfacts.cacao.geometry.Axis
import net.shadowfacts.cacao.geometry.Size import net.shadowfacts.cacao.geometry.Size
import net.shadowfacts.cacao.util.Color import net.shadowfacts.cacao.util.Color
import net.shadowfacts.cacao.util.NinePatchTexture
import net.shadowfacts.cacao.util.Texture import net.shadowfacts.cacao.util.Texture
import net.shadowfacts.cacao.view.Label import net.shadowfacts.cacao.view.*
import net.shadowfacts.cacao.view.StackView
import net.shadowfacts.cacao.view.TextureView
import net.shadowfacts.cacao.view.button.Button import net.shadowfacts.cacao.view.button.Button
/** /**
@ -27,21 +25,21 @@ class TestCacaoScreen: CacaoScreen() {
val red = stack.addArrangedSubview(TextureView(Texture(Identifier("textures/block/birch_log_top.png"), 0, 0, 16, 16)).apply { val red = stack.addArrangedSubview(TextureView(Texture(Identifier("textures/block/birch_log_top.png"), 0, 0, 16, 16)).apply {
intrinsicContentSize = Size(50.0, 50.0) intrinsicContentSize = Size(50.0, 50.0)
}) })
val green = stack.addArrangedSubview(View().apply { val buttonNinePatch = NinePatchTexture(Texture(Identifier("textures/gui/widgets.png"), 0, 66), 3, 3, 194, 14)
val green = stack.addArrangedSubview(NinePatchView(buttonNinePatch).apply {
intrinsicContentSize = Size(75.0, 100.0) intrinsicContentSize = Size(75.0, 100.0)
backgroundColor = Color(0x00ff00)
}) })
val blue = stack.addArrangedSubview(View().apply { val blue = stack.addArrangedSubview(View().apply {
intrinsicContentSize = Size(50.0, 50.0) intrinsicContentSize = Size(50.0, 50.0)
backgroundColor = Color(0x0000ff) backgroundColor = Color(0x0000ff)
}) })
val purple = blue.addSubview(Button(Label("Hello, button!")).apply { val purple = blue.addSubview(Button(Label("Hello, button!").apply {
textColor = Color.WHITE
}).apply {
handler = { handler = {
println("$it clicked!") println("$it clicked!")
} }
background = View().apply { background = NinePatchView(buttonNinePatch)
backgroundColor = Color(0xebfc00)
}
}) })
solver.dsl { solver.dsl {

View File

@ -0,0 +1,41 @@
package net.shadowfacts.cacao.util
/**
* @author shadowfacts
*/
data class NinePatchTexture(val texture: Texture, val cornerWidth: Int, val cornerHeight: Int, val centerWidth: Int, val centerHeight: Int) {
// Corners
val topLeft by lazy {
texture
}
val topRight by lazy {
Texture(texture.location, texture.u + cornerWidth + centerWidth, texture.v, texture.width, texture.height)
}
val bottomLeft by lazy {
Texture(texture.location, texture.u, texture.v + cornerHeight + centerHeight, texture.width, texture.height)
}
val bottomRight by lazy {
Texture(texture.location, topRight.u, bottomLeft.v, texture.width, texture.height)
}
// Edges
val topMiddle by lazy {
Texture(texture.location, texture.u + cornerWidth, texture.v, texture.width, texture.height)
}
val bottomMiddle by lazy {
Texture(texture.location, topMiddle.u, bottomLeft.v, texture.width, texture.height)
}
val leftMiddle by lazy {
Texture(texture.location, texture.u, texture.v + cornerHeight, texture.width, texture.height)
}
val rightMiddle by lazy {
Texture(texture.location, topRight.u, leftMiddle.v, texture.width, texture.height)
}
// Center
val center by lazy {
Texture(texture.location, texture.u + cornerWidth, texture.v + cornerHeight, texture.width, texture.height)
}
}

View File

@ -3,7 +3,6 @@ package net.shadowfacts.cacao.util
import com.mojang.blaze3d.platform.GlStateManager import com.mojang.blaze3d.platform.GlStateManager
import net.minecraft.client.MinecraftClient import net.minecraft.client.MinecraftClient
import net.minecraft.client.gui.DrawableHelper import net.minecraft.client.gui.DrawableHelper
import net.shadowfacts.cacao.geometry.Point
import net.shadowfacts.cacao.geometry.Rect import net.shadowfacts.cacao.geometry.Rect
/** /**
@ -25,15 +24,21 @@ object RenderHelper {
} }
/** /**
* Draws the given [texture] filling the [rect]. * Binds and draws the given [texture] filling the [rect].
*/ */
fun draw(rect: Rect, texture: Texture) { fun draw(rect: Rect, texture: Texture) {
if (disabled) return if (disabled) return
color(1f, 1f, 1f, 1f) color(1f, 1f, 1f, 1f)
MinecraftClient.getInstance().textureManager.bindTexture(texture.location) MinecraftClient.getInstance().textureManager.bindTexture(texture.location)
val u = texture.u / texture.width.toFloat() draw(rect.left, rect.top, texture.u, texture.v, rect.width, rect.height, texture.width, texture.height)
val v = texture.v / texture.height.toFloat() }
DrawableHelper.blit(rect.left.toInt(), rect.top.toInt(), u, v, rect.width.toInt(), rect.height.toInt(), texture.width, texture.height)
/**
* Draws the bound texture with the given screen and texture position and size.
*/
fun draw(x: Double, y: Double, u: Int, v: Int, width: Double, height: Double, textureWidth: Int, textureHeight: Int) {
if (disabled) return
DrawableHelper.blit(x.toInt(), y.toInt(), u.toFloat(), v.toFloat(), width.toInt(), height.toInt(), textureWidth, textureHeight)
} }
/** /**

View File

@ -0,0 +1,103 @@
package net.shadowfacts.cacao.view
import net.shadowfacts.cacao.geometry.Point
import net.shadowfacts.cacao.geometry.Rect
import net.shadowfacts.cacao.util.NinePatchTexture
import net.shadowfacts.cacao.util.RenderHelper
/**
* @author shadowfacts
*/
class NinePatchView(val ninePatch: NinePatchTexture): View() {
// Corners
private val topLeft: Rect by lazy {
Rect(0.0, 0.0, ninePatch.cornerWidth.toDouble(), ninePatch.cornerHeight.toDouble())
}
private val topRight by lazy {
Rect(bounds.width - ninePatch.cornerWidth, 0.0, ninePatch.cornerWidth.toDouble(), ninePatch.cornerHeight.toDouble())
}
private val bottomLeft by lazy {
Rect(0.0, bounds.height - ninePatch.cornerHeight, ninePatch.cornerWidth.toDouble(), ninePatch.cornerHeight.toDouble())
}
private val bottomRight by lazy {
Rect(bounds.width - ninePatch.cornerWidth, bounds.height - ninePatch.cornerHeight, ninePatch.cornerWidth.toDouble(), ninePatch.cornerHeight.toDouble())
}
// Edges
private val topMiddle by lazy {
Rect(ninePatch.cornerWidth.toDouble(), topLeft.top, bounds.width - 2 * ninePatch.cornerWidth, ninePatch.cornerHeight.toDouble())
}
private val bottomMiddle by lazy {
Rect(topMiddle.left, bottomLeft.top, topMiddle.width, topMiddle.height)
}
private val leftMiddle by lazy {
Rect(topLeft.left, ninePatch.cornerHeight.toDouble(), ninePatch.cornerWidth.toDouble(), bounds.height - 2 * ninePatch.cornerHeight)
}
private val rightMiddle by lazy {
Rect(topRight.left, leftMiddle.top, leftMiddle.width, leftMiddle.height)
}
// Center
private val center by lazy {
Rect(topLeft.right, topLeft.bottom, topMiddle.width, leftMiddle.height)
}
override fun drawContent(mouse: Point, delta: Float) {
drawCorners()
drawEdges()
drawCenter()
}
private fun drawCorners() {
RenderHelper.draw(topLeft, ninePatch.topLeft)
RenderHelper.draw(topRight, ninePatch.topRight)
RenderHelper.draw(bottomLeft, ninePatch.bottomLeft)
RenderHelper.draw(bottomRight, ninePatch.bottomRight)
}
private fun drawEdges() {
// Horizontal
for (i in 0 until (topMiddle.width.toInt() / ninePatch.centerWidth)) {
RenderHelper.draw(topMiddle.left + i * ninePatch.centerWidth, topMiddle.top, ninePatch.topMiddle.u, ninePatch.topMiddle.v, ninePatch.centerWidth.toDouble(), ninePatch.cornerHeight.toDouble(), ninePatch.texture.width, ninePatch.texture.height)
RenderHelper.draw(bottomMiddle.left + i * ninePatch.centerWidth, bottomMiddle.top, ninePatch.bottomMiddle.u, ninePatch.bottomMiddle.v, ninePatch.centerWidth.toDouble(), ninePatch.cornerHeight.toDouble(), ninePatch.texture.width, ninePatch.texture.height)
}
val remWidth = topMiddle.width.toInt() % ninePatch.centerWidth
if (remWidth > 0) {
RenderHelper.draw(topMiddle.right - remWidth, topMiddle.top, ninePatch.topMiddle.u, ninePatch.topMiddle.v, remWidth.toDouble(), ninePatch.cornerHeight.toDouble(), ninePatch.texture.width, ninePatch.texture.height)
RenderHelper.draw(bottomMiddle.right - remWidth, bottomMiddle.top, ninePatch.bottomMiddle.u, ninePatch.bottomMiddle.v, remWidth.toDouble(), ninePatch.cornerHeight.toDouble(), ninePatch.texture.width, ninePatch.texture.height)
}
// Vertical
for (i in 0 until (leftMiddle.height.toInt() / ninePatch.centerHeight)) {
RenderHelper.draw(leftMiddle.left, leftMiddle.top + i * ninePatch.centerHeight, ninePatch.leftMiddle.u, ninePatch.leftMiddle.v, ninePatch.cornerWidth.toDouble(), ninePatch.centerHeight.toDouble(), ninePatch.texture.width, ninePatch.texture.height)
RenderHelper.draw(rightMiddle.left, rightMiddle.top + i * ninePatch.centerHeight, ninePatch.rightMiddle.u, ninePatch.rightMiddle.v, ninePatch.cornerWidth.toDouble(), ninePatch.centerHeight.toDouble(), ninePatch.texture.width, ninePatch.texture.height)
}
val remHeight = leftMiddle.height.toInt() % ninePatch.centerHeight
if (remHeight > 0) {
RenderHelper.draw(leftMiddle.left, leftMiddle.bottom - remHeight, ninePatch.leftMiddle.u, ninePatch.leftMiddle.v, ninePatch.cornerWidth.toDouble(), remHeight.toDouble(), ninePatch.texture.width, ninePatch.texture.height)
RenderHelper.draw(rightMiddle.left, rightMiddle.bottom - remHeight, ninePatch.rightMiddle.u, ninePatch.rightMiddle.v, ninePatch.cornerWidth.toDouble(), remHeight.toDouble(), ninePatch.texture.width, ninePatch.texture.height)
}
}
private fun drawCenter() {
for (i in 0 until (center.height.toInt() / ninePatch.centerHeight)) {
drawCenterRow(center.top + i * ninePatch.centerHeight.toDouble(), ninePatch.centerHeight.toDouble())
}
val remHeight = center.height.toInt() % ninePatch.centerHeight
if (remHeight > 0) {
drawCenterRow(center.bottom - remHeight, remHeight.toDouble())
}
}
private fun drawCenterRow(y: Double, height: Double) {
for (i in 0 until (center.width.toInt() / ninePatch.centerWidth)) {
RenderHelper.draw(center.left + i * ninePatch.centerWidth, y, ninePatch.center.u, ninePatch.center.v, ninePatch.centerWidth.toDouble(), height, ninePatch.texture.width, ninePatch.texture.height)
}
val remWidth = center.width.toInt() % ninePatch.centerWidth
if (remWidth > 0) {
RenderHelper.draw(center.right - remWidth, y, ninePatch.center.u, ninePatch.center.v, remWidth.toDouble(), height, ninePatch.texture.width, ninePatch.texture.height)
}
}
}