Add EnumButton
This commit is contained in:
parent
b48b72d5bb
commit
204731e03c
|
@ -1,6 +1,7 @@
|
||||||
package net.shadowfacts.asmr
|
package net.shadowfacts.asmr
|
||||||
|
|
||||||
import net.minecraft.util.Identifier
|
import net.minecraft.util.Identifier
|
||||||
|
import net.shadowfacts.asmr.util.RedstoneMode
|
||||||
import net.shadowfacts.kiwidsl.dsl
|
import net.shadowfacts.kiwidsl.dsl
|
||||||
import net.shadowfacts.cacao.CacaoScreen
|
import net.shadowfacts.cacao.CacaoScreen
|
||||||
import net.shadowfacts.cacao.Window
|
import net.shadowfacts.cacao.Window
|
||||||
|
@ -11,6 +12,7 @@ import net.shadowfacts.cacao.util.NinePatchTexture
|
||||||
import net.shadowfacts.cacao.util.Texture
|
import net.shadowfacts.cacao.util.Texture
|
||||||
import net.shadowfacts.cacao.view.*
|
import net.shadowfacts.cacao.view.*
|
||||||
import net.shadowfacts.cacao.view.button.Button
|
import net.shadowfacts.cacao.view.button.Button
|
||||||
|
import net.shadowfacts.cacao.view.button.EnumButton
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author shadowfacts
|
* @author shadowfacts
|
||||||
|
@ -33,11 +35,9 @@ class TestCacaoScreen: CacaoScreen() {
|
||||||
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(EnumButton(RedstoneMode.HIGH, RedstoneMode.Companion::localize).apply {
|
||||||
textColor = Color.WHITE
|
|
||||||
}).apply {
|
|
||||||
handler = {
|
handler = {
|
||||||
println("$it clicked!")
|
println("enum button clicked, new value: ${it.value}")
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -47,6 +47,7 @@ class TestCacaoScreen: CacaoScreen() {
|
||||||
stack.rightAnchor equalTo 150
|
stack.rightAnchor equalTo 150
|
||||||
purple.centerXAnchor equalTo blue.centerXAnchor
|
purple.centerXAnchor equalTo blue.centerXAnchor
|
||||||
purple.centerYAnchor equalTo blue.centerYAnchor
|
purple.centerYAnchor equalTo blue.centerYAnchor
|
||||||
|
purple.widthAnchor equalTo 50
|
||||||
}
|
}
|
||||||
|
|
||||||
layout()
|
layout()
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
package net.shadowfacts.asmr.util
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author shadowfacts
|
||||||
|
*/
|
||||||
|
enum class RedstoneMode {
|
||||||
|
HIGH, LOW, TOGGLE;
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun localize(value: RedstoneMode): String {
|
||||||
|
return value.name.toLowerCase().capitalize()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -15,7 +15,7 @@ import net.shadowfacts.cacao.geometry.Rect
|
||||||
*/
|
*/
|
||||||
object RenderHelper {
|
object RenderHelper {
|
||||||
|
|
||||||
private val disabled = (System.getProperty("cacao.drawing.disabled") ?: "false").toBoolean()
|
val disabled = (System.getProperty("cacao.drawing.disabled") ?: "false").toBoolean()
|
||||||
|
|
||||||
// TODO: find a better place for this
|
// TODO: find a better place for this
|
||||||
fun playSound(event: SoundEvent) {
|
fun playSound(event: SoundEvent) {
|
||||||
|
|
|
@ -5,6 +5,7 @@ import net.minecraft.client.font.TextRenderer
|
||||||
import net.shadowfacts.cacao.geometry.Point
|
import net.shadowfacts.cacao.geometry.Point
|
||||||
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.RenderHelper
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A simple View that displays text. Allows for controlling the color and shadow of the text. Label cannot be used
|
* A simple View that displays text. Allows for controlling the color and shadow of the text. Label cannot be used
|
||||||
|
@ -29,7 +30,7 @@ class Label(text: String): View() {
|
||||||
updateIntrinsicContentSize()
|
updateIntrinsicContentSize()
|
||||||
}
|
}
|
||||||
|
|
||||||
var textColor = Color(0x404040)
|
var textColor = Color.WHITE
|
||||||
|
|
||||||
override fun wasAdded() {
|
override fun wasAdded() {
|
||||||
super.wasAdded()
|
super.wasAdded()
|
||||||
|
@ -38,6 +39,8 @@ class Label(text: String): View() {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateIntrinsicContentSize() {
|
private fun updateIntrinsicContentSize() {
|
||||||
|
if (RenderHelper.disabled) return
|
||||||
|
|
||||||
val width = textRenderer.getStringWidth(text)
|
val width = textRenderer.getStringWidth(text)
|
||||||
val height = textRenderer.fontHeight
|
val height = textRenderer.fontHeight
|
||||||
intrinsicContentSize = Size(width.toDouble(), height.toDouble())
|
intrinsicContentSize = Size(width.toDouble(), height.toDouble())
|
||||||
|
|
|
@ -126,7 +126,7 @@ abstract class AbstractButton<Impl: AbstractButton<Impl>>(val content: View, val
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
handler(this as Impl)
|
handler(this as Impl)
|
||||||
|
|
||||||
if (clickSoundEnabled) {
|
if (clickSoundEnabled && !RenderHelper.disabled) {
|
||||||
RenderHelper.playSound(SoundEvents.UI_BUTTON_CLICK)
|
RenderHelper.playSound(SoundEvents.UI_BUTTON_CLICK)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
package net.shadowfacts.cacao.view.button
|
||||||
|
|
||||||
|
import net.shadowfacts.cacao.geometry.Point
|
||||||
|
import net.shadowfacts.cacao.util.EnumHelper
|
||||||
|
import net.shadowfacts.cacao.util.MouseButton
|
||||||
|
import net.shadowfacts.cacao.view.Label
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A button that cycles through enum values.
|
||||||
|
* Left click: forwards
|
||||||
|
* Right click: backwards
|
||||||
|
* All other mouse buttons call the handler with the unchanged value
|
||||||
|
*
|
||||||
|
* @author shadowfacts
|
||||||
|
* @param initialValue The initial enum value for this button.
|
||||||
|
* @param localizer A function that takes an enum value and converts into a string for the button's label.
|
||||||
|
*/
|
||||||
|
class EnumButton<E: Enum<E>>(initialValue: E, val localizer: (E) -> String, padding: Double = 4.0): AbstractButton<EnumButton<E>>(Label(localizer(initialValue)), padding) {
|
||||||
|
|
||||||
|
private val label: Label
|
||||||
|
get() = content as Label
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The current value of the enum button.
|
||||||
|
* Updating this property will use the [localizer] to update the label.
|
||||||
|
*/
|
||||||
|
var value: E = initialValue
|
||||||
|
set(value) {
|
||||||
|
field = value
|
||||||
|
label.text = localizer(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun mouseClicked(point: Point, mouseButton: MouseButton) {
|
||||||
|
if (!disabled) {
|
||||||
|
value = when (mouseButton) {
|
||||||
|
MouseButton.LEFT -> EnumHelper.next(value)
|
||||||
|
MouseButton.RIGHT -> EnumHelper.previous(value)
|
||||||
|
else -> value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
super.mouseClicked(point, mouseButton)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,95 @@
|
||||||
|
package net.shadowfacts.cacao.view
|
||||||
|
|
||||||
|
import net.shadowfacts.cacao.Window
|
||||||
|
import net.shadowfacts.cacao.geometry.Point
|
||||||
|
import net.shadowfacts.cacao.geometry.Rect
|
||||||
|
import net.shadowfacts.cacao.util.MouseButton
|
||||||
|
import net.shadowfacts.cacao.view.button.EnumButton
|
||||||
|
import net.shadowfacts.kiwidsl.dsl
|
||||||
|
import org.junit.jupiter.api.Assertions.assertEquals
|
||||||
|
import org.junit.jupiter.api.BeforeAll
|
||||||
|
import org.junit.jupiter.api.BeforeEach
|
||||||
|
import org.junit.jupiter.api.Test
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author shadowfacts
|
||||||
|
*/
|
||||||
|
class EnumButtonTests {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
@BeforeAll
|
||||||
|
@JvmStatic
|
||||||
|
fun setupAll() {
|
||||||
|
System.setProperty("cacao.drawing.disabled", "true")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum class MyEnum {
|
||||||
|
ONE, TWO, THREE
|
||||||
|
}
|
||||||
|
|
||||||
|
lateinit var window: Window
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
fun setup() {
|
||||||
|
window = Window()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testCyclesValues() {
|
||||||
|
val values = mutableListOf<MyEnum>()
|
||||||
|
window.addView(EnumButton(MyEnum.ONE, MyEnum::name).apply {
|
||||||
|
frame = Rect(0.0, 0.0, 25.0, 25.0)
|
||||||
|
content.frame = Rect(0.0, 0.0, 25.0, 25.0)
|
||||||
|
handler = {
|
||||||
|
values.add(it.value)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
window.mouseClicked(Point(5.0, 5.0), MouseButton.LEFT)
|
||||||
|
assertEquals(1, values.size)
|
||||||
|
assertEquals(MyEnum.TWO, values.last())
|
||||||
|
window.mouseClicked(Point(5.0, 5.0), MouseButton.LEFT)
|
||||||
|
assertEquals(2, values.size)
|
||||||
|
assertEquals(MyEnum.THREE, values.last())
|
||||||
|
window.mouseClicked(Point(5.0, 5.0), MouseButton.LEFT)
|
||||||
|
assertEquals(3, values.size)
|
||||||
|
assertEquals(MyEnum.ONE, values.last())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testCyclesValuesBackwards() {
|
||||||
|
val values = mutableListOf<MyEnum>()
|
||||||
|
window.addView(EnumButton(MyEnum.ONE, MyEnum::name).apply {
|
||||||
|
frame = Rect(0.0, 0.0, 25.0, 25.0)
|
||||||
|
content.frame = Rect(0.0, 0.0, 25.0, 25.0)
|
||||||
|
handler = {
|
||||||
|
values.add(it.value)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
window.mouseClicked(Point(5.0, 5.0), MouseButton.LEFT)
|
||||||
|
assertEquals(1, values.size)
|
||||||
|
assertEquals(MyEnum.TWO, values.last())
|
||||||
|
window.mouseClicked(Point(5.0, 5.0), MouseButton.RIGHT)
|
||||||
|
assertEquals(2, values.size)
|
||||||
|
assertEquals(MyEnum.ONE, values.last())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testMiddleClickDoesNotChangeValue() {
|
||||||
|
val values = mutableListOf<MyEnum>()
|
||||||
|
window.addView(EnumButton(MyEnum.ONE, MyEnum::name).apply {
|
||||||
|
frame = Rect(0.0, 0.0, 25.0, 25.0)
|
||||||
|
content.frame = Rect(0.0, 0.0, 25.0, 25.0)
|
||||||
|
handler = {
|
||||||
|
values.add(it.value)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
window.mouseClicked(Point(5.0, 5.0), MouseButton.MIDDLE)
|
||||||
|
assertEquals(1, values.size)
|
||||||
|
assertEquals(MyEnum.ONE, values.last())
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue