Convert console screen to use Cacao

This commit is contained in:
Shadowfacts 2021-02-27 21:48:40 -05:00
parent 3926da0c3c
commit 500ad94442
Signed by: shadowfacts
GPG Key ID: 94A5AB95422746E5
15 changed files with 307 additions and 231 deletions

View File

@ -39,6 +39,9 @@ public final class IPAddress {
int b = Integer.parseInt(matcher.group(2)); int b = Integer.parseInt(matcher.group(2));
int c = Integer.parseInt(matcher.group(3)); int c = Integer.parseInt(matcher.group(3));
int d = Integer.parseInt(matcher.group(4)); int d = Integer.parseInt(matcher.group(4));
if (a > 255 || b > 255 || c > 255 || d > 255) {
return null;
}
return new IPAddress(a, b, c, d); return new IPAddress(a, b, c, d);
} }

View File

@ -1,16 +1,15 @@
package net.shadowfacts.cacao package net.shadowfacts.cacao
import com.mojang.blaze3d.platform.GlStateManager
import net.minecraft.client.gui.screen.Screen import net.minecraft.client.gui.screen.Screen
import net.minecraft.client.util.math.MatrixStack import net.minecraft.client.util.math.MatrixStack
import net.minecraft.sound.SoundEvents import net.minecraft.sound.SoundEvents
import net.minecraft.text.LiteralText import net.minecraft.text.LiteralText
import net.minecraft.text.Text
import net.shadowfacts.cacao.geometry.Point import net.shadowfacts.cacao.geometry.Point
import net.shadowfacts.cacao.util.KeyModifiers import net.shadowfacts.cacao.util.KeyModifiers
import net.shadowfacts.cacao.util.MouseButton import net.shadowfacts.cacao.util.MouseButton
import net.shadowfacts.cacao.util.RenderHelper import net.shadowfacts.cacao.util.RenderHelper
import net.shadowfacts.cacao.window.Window import net.shadowfacts.cacao.window.Window
import org.lwjgl.glfw.GLFW
import java.util.* import java.util.*
/** /**
@ -19,7 +18,7 @@ import java.util.*
* *
* @author shadowfacts * @author shadowfacts
*/ */
open class CacaoScreen: Screen(LiteralText("CacaoScreen")), AbstractCacaoScreen { open class CacaoScreen(title: Text = LiteralText("CacaoScreen")): Screen(title), AbstractCacaoScreen {
// _windows is the internal, mutable object, since we only want it to by mutated by the add/removeWindow methods. // _windows is the internal, mutable object, since we only want it to by mutated by the add/removeWindow methods.
private val _windows = LinkedList<Window>() private val _windows = LinkedList<Window>()
@ -147,4 +146,4 @@ open class CacaoScreen: Screen(LiteralText("CacaoScreen")), AbstractCacaoScreen
return false return false
} }
} }

View File

@ -29,6 +29,8 @@ data class Color(val red: Int, val green: Int, val blue: Int, val alpha: Int = 2
val RED = Color(0xff0000) val RED = Color(0xff0000)
val GREEN = Color(0x00ff00) val GREEN = Color(0x00ff00)
val BLUE = Color(0x0000ff) val BLUE = Color(0x0000ff)
val TEXT = Color(0x404040)
} }
} }

View File

@ -26,7 +26,7 @@ import net.shadowfacts.cacao.util.RenderHelper
*/ */
class Label( class Label(
text: Text, text: Text,
val shadow: Boolean = true, val shadow: Boolean = false,
val maxLines: Int = 0, val maxLines: Int = 0,
val wrappingMode: WrappingMode = WrappingMode.WRAP, val wrappingMode: WrappingMode = WrappingMode.WRAP,
val textAlignment: TextAlignment = TextAlignment.LEFT val textAlignment: TextAlignment = TextAlignment.LEFT
@ -47,7 +47,7 @@ class Label(
constructor( constructor(
text: String, text: String,
shadow: Boolean = true, shadow: Boolean = false,
maxLines: Int = 0, maxLines: Int = 0,
wrappingMode: WrappingMode = WrappingMode.WRAP, wrappingMode: WrappingMode = WrappingMode.WRAP,
textAlignment: TextAlignment = TextAlignment.LEFT, textAlignment: TextAlignment = TextAlignment.LEFT,

View File

@ -16,7 +16,12 @@ import net.shadowfacts.cacao.view.Label
* @param initialValue The initial enum value for this button. * @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. * @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) -> Text): AbstractButton<EnumButton<E>>(Label(localizer(initialValue))) { class EnumButton<E: Enum<E>>(
initialValue: E,
val localizer: (E) -> Text
): AbstractButton<EnumButton<E>>(
Label(localizer(initialValue), shadow = true)
) {
private val label: Label private val label: Label
get() = content as Label get() = content as Label

View File

@ -7,6 +7,7 @@ import net.shadowfacts.cacao.geometry.Axis
import net.shadowfacts.cacao.geometry.Point import net.shadowfacts.cacao.geometry.Point
import net.shadowfacts.cacao.geometry.Rect import net.shadowfacts.cacao.geometry.Rect
import net.shadowfacts.cacao.geometry.Size import net.shadowfacts.cacao.geometry.Size
import net.shadowfacts.cacao.util.Color
import net.shadowfacts.cacao.util.MouseButton import net.shadowfacts.cacao.util.MouseButton
import net.shadowfacts.cacao.util.texture.NinePatchTexture import net.shadowfacts.cacao.util.texture.NinePatchTexture
import net.shadowfacts.cacao.util.texture.Texture import net.shadowfacts.cacao.util.texture.Texture
@ -21,7 +22,7 @@ import net.shadowfacts.kiwidsl.dsl
* @author shadowfacts * @author shadowfacts
*/ */
class TabViewController<T: TabViewController.Tab>( class TabViewController<T: TabViewController.Tab>(
val tabs: Array<T>, val tabs: List<T>,
initalTab: T = tabs.first() initalTab: T = tabs.first()
): ViewController() { ): ViewController() {
@ -38,11 +39,14 @@ class TabViewController<T: TabViewController.Tab>(
private lateinit var outerStack: StackView private lateinit var outerStack: StackView
private lateinit var tabStack: StackView private lateinit var tabStack: StackView
private lateinit var tabVCContainer: View // todo: this shouldn't be public, use layout guides
lateinit var tabVCContainer: View
private set
override fun viewDidLoad() { override fun viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
// todo: might be simpler to just not use a stack view
// padding is -4 so tab button texture overlaps with panel BG as expected // padding is -4 so tab button texture overlaps with panel BG as expected
outerStack = StackView(Axis.VERTICAL, StackView.Distribution.FILL, -4.0) outerStack = StackView(Axis.VERTICAL, StackView.Distribution.FILL, -4.0)
view.addSubview(outerStack) view.addSubview(outerStack)
@ -51,9 +55,6 @@ class TabViewController<T: TabViewController.Tab>(
tabStack.zIndex = 1.0 tabStack.zIndex = 1.0
outerStack.addArrangedSubview(tabStack) outerStack.addArrangedSubview(tabStack)
tabVCContainer = View()
outerStack.addArrangedSubview(tabVCContainer)
tabButtons = tabs.mapIndexed { index, tab -> tabButtons = tabs.mapIndexed { index, tab ->
val btn = TabButton(tab) val btn = TabButton(tab)
btn.handler = this::selectTab btn.handler = this::selectTab
@ -69,8 +70,11 @@ class TabViewController<T: TabViewController.Tab>(
tabStack.addArrangedSubview(View()) tabStack.addArrangedSubview(View())
val background = NinePatchView(NinePatchTexture.PANEL_BG) val background = NinePatchView(NinePatchTexture.PANEL_BG)
background.zIndex = -1.0 outerStack.addArrangedSubview(background)
tabVCContainer.addSubview(background)
tabVCContainer = View()
tabVCContainer.zIndex = 1.0
view.addSubview(tabVCContainer)
embedChild(currentTab.controller, tabVCContainer) embedChild(currentTab.controller, tabVCContainer)
@ -80,10 +84,10 @@ class TabViewController<T: TabViewController.Tab>(
outerStack.topAnchor equalTo view.topAnchor outerStack.topAnchor equalTo view.topAnchor
outerStack.bottomAnchor equalTo view.bottomAnchor outerStack.bottomAnchor equalTo view.bottomAnchor
background.leftAnchor equalTo tabVCContainer.leftAnchor tabVCContainer.leftAnchor equalTo (background.leftAnchor + 6)
background.rightAnchor equalTo tabVCContainer.rightAnchor tabVCContainer.rightAnchor equalTo (background.rightAnchor - 6)
background.topAnchor equalTo tabVCContainer.topAnchor tabVCContainer.topAnchor equalTo (background.topAnchor + 6)
background.bottomAnchor equalTo tabVCContainer.bottomAnchor tabVCContainer.bottomAnchor equalTo (background.bottomAnchor - 6)
} }
} }
@ -125,7 +129,11 @@ class TabViewController<T: TabViewController.Tab>(
super.wasAdded() super.wasAdded()
backgroundView.usesConstraintBasedLayout = false backgroundView.usesConstraintBasedLayout = false
backgroundView.frame = Rect(0.0, 0.0, 28.0, 32.0) backgroundView.frame = Rect(0.0, 0.0, 28.0, 32.0)
backgroundView.zIndex = -1.0
addSubview(backgroundView) addSubview(backgroundView)
solver.dsl {
content.bottomAnchor lessThanOrEqualTo (bottomAnchor - 4)
}
} }
override fun didLayout() { override fun didLayout() {

View File

@ -8,12 +8,7 @@ import net.minecraft.util.Identifier
import net.shadowfacts.phycon.PhysicalConnectivity import net.shadowfacts.phycon.PhysicalConnectivity
import net.shadowfacts.phycon.network.DeviceBlock import net.shadowfacts.phycon.network.DeviceBlock
import net.shadowfacts.phycon.network.DeviceBlockEntity import net.shadowfacts.phycon.network.DeviceBlockEntity
import net.shadowfacts.phycon.network.block.redstone.RedstoneControllerBlockEntity import net.shadowfacts.phycon.screen.console.DeviceConsoleScreen
import net.shadowfacts.phycon.network.component.ActivationController
import net.shadowfacts.phycon.screen.ActivatableDeviceConsoleScreen
import net.shadowfacts.phycon.screen.DeviceConsoleScreen
import net.shadowfacts.phycon.screen.RedstoneControllerConsoleScreen
import net.shadowfacts.phycon.screen.TestCacaoScreen
/** /**
* @author shadowfacts * @author shadowfacts
@ -41,12 +36,8 @@ class ConsoleItem: Item(Settings()) {
} }
private fun openScreen(be: DeviceBlockEntity) { private fun openScreen(be: DeviceBlockEntity) {
val screen = TestCacaoScreen() // val screen = TestCacaoScreen()
// val screen = when (be) { val screen = DeviceConsoleScreen(be)
// is ActivationController.ActivatableDevice -> ActivatableDeviceConsoleScreen(be)
// is RedstoneControllerBlockEntity -> RedstoneControllerConsoleScreen(be)
// else -> DeviceConsoleScreen(be)
// }
MinecraftClient.getInstance().openScreen(screen) MinecraftClient.getInstance().openScreen(screen)
} }

View File

@ -1,64 +0,0 @@
package net.shadowfacts.phycon.screen
import com.mojang.blaze3d.systems.RenderSystem
import net.minecraft.client.gui.screen.Screen
import net.minecraft.client.gui.widget.ButtonWidget
import net.minecraft.client.util.math.MatrixStack
import net.shadowfacts.phycon.network.DeviceBlockEntity
import net.shadowfacts.phycon.network.component.ActivationController
import net.shadowfacts.phycon.networking.C2SConfigureActivationMode
import net.shadowfacts.phycon.util.ActivationMode
import net.shadowfacts.phycon.util.next
import org.lwjgl.glfw.GLFW
/**
* @author shadowfacts
*/
class ActivatableDeviceConsoleScreen<T>(
val device: T
): Screen(device.cachedState.block.name) where T: DeviceBlockEntity, T: ActivationController.ActivatableDevice {
private val backgroundWidth = 252
private val backgroundHeight = 222
override fun init() {
super.init()
buttons.clear()
val minX = (width - backgroundWidth) / 2
val minY = (height - backgroundHeight) / 2
val mode = EnumButton(device.controller::activationMode, minX + 5, minY + 25, 55, 20) {
client!!.player!!.networkHandler.sendPacket(C2SConfigureActivationMode(device))
}
addButton(mode)
}
override fun isPauseScreen() = false
override fun keyPressed(key: Int, j: Int, k: Int): Boolean {
if (key == GLFW.GLFW_KEY_E) {
onClose()
return true
}
return super.keyPressed(key, j, k)
}
override fun render(matrixStack: MatrixStack, mouseX: Int, mouseY: Int, delta: Float) {
renderBackground(matrixStack)
val minX = (width - backgroundWidth) / 2
val minY = (height - backgroundHeight) / 2
RenderSystem.color4f(1f, 1f, 1f, 1f)
client!!.textureManager.bindTexture(DeviceConsoleScreen.BACKGROUND)
drawTexture(matrixStack, minX, minY, 0, 0, backgroundWidth, backgroundHeight)
super.render(matrixStack, mouseX, mouseY, delta)
textRenderer.draw(matrixStack, "IP Address: ${device.ipAddress}", minX + 5f, minY + 5f, 0x404040)
textRenderer.draw(matrixStack, "MAC Address: ${device.macAddress}", minX + 5f, minY + 15f, 0x404040)
}
}

View File

@ -1,40 +0,0 @@
package net.shadowfacts.phycon.screen
import net.minecraft.client.gui.screen.Screen
import net.minecraft.client.util.math.MatrixStack
import net.minecraft.text.TranslatableText
import net.minecraft.util.Identifier
import net.shadowfacts.phycon.PhysicalConnectivity
import net.shadowfacts.phycon.network.DeviceBlockEntity
import org.lwjgl.glfw.GLFW
/**
* @author shadowfacts
*/
class DeviceConsoleScreen(
val device: DeviceBlockEntity,
): Screen(TranslatableText("item.phycon.console")) {
companion object {
val BACKGROUND = Identifier(PhysicalConnectivity.MODID, "textures/gui/console.png")
}
override fun isPauseScreen() = false
override fun keyPressed(key: Int, j: Int, k: Int): Boolean {
if (key == GLFW.GLFW_KEY_E) {
onClose()
return true
}
return super.keyPressed(key, j, k)
}
override fun render(matrixStack: MatrixStack, mouseX: Int, mouseY: Int, delta: Float) {
renderBackground(matrixStack)
super.render(matrixStack, mouseX, mouseY, delta)
drawCenteredString(matrixStack, textRenderer, device.macAddress.toString(), width / 2, height / 2 - 5, 0xffffff)
drawCenteredString(matrixStack, textRenderer, device.ipAddress.toString(), width / 2, height / 2 + 5, 0xffffff)
}
}

View File

@ -1,96 +0,0 @@
package net.shadowfacts.phycon.screen
import com.mojang.blaze3d.systems.RenderSystem
import net.minecraft.client.gui.screen.Screen
import net.minecraft.client.gui.widget.ButtonWidget
import net.minecraft.client.gui.widget.TextFieldWidget
import net.minecraft.client.util.math.MatrixStack
import net.minecraft.text.LiteralText
import net.shadowfacts.phycon.api.util.IPAddress
import net.shadowfacts.phycon.network.block.redstone.RedstoneControllerBlockEntity
import net.shadowfacts.phycon.networking.C2SConfigureRedstoneController
import net.shadowfacts.phycon.util.next
import org.lwjgl.glfw.GLFW
/**
* @author shadowfacts
*/
class RedstoneControllerConsoleScreen(
val device: RedstoneControllerBlockEntity
): Screen(device.cachedState.block.name) {
private val backgroundWidth = 252
private val backgroundHeight = 222
private val ipAddressTextFields = mutableListOf<TextFieldWidget>()
override fun init() {
super.init()
buttons.clear()
ipAddressTextFields.clear()
val minX = (width - backgroundWidth) / 2
val minY = (height - backgroundHeight) / 2
val mode = EnumButton(device::redstoneMode, minX + 5, minY + 25, 75, 20) {
client!!.player!!.networkHandler.sendPacket(C2SConfigureRedstoneController(device))
}
addButton(mode)
for (i in 0 until 5) {
// todo: field name
val field = TextFieldWidget(textRenderer, minX + 5, minY + 50 + 22 * i, backgroundWidth / 2, 20, LiteralText(""))
field.setMaxLength(15)
field.setHasBorder(true)
field.isVisible = true
field.setEditableColor(0xffffff)
field.text = device.managedDevices[i]?.toString()
field.setChangedListener { newVal ->
device.managedDevices[i] = IPAddress.parse(newVal)
client!!.player!!.networkHandler.sendPacket(C2SConfigureRedstoneController(device))
}
addChild(field)
ipAddressTextFields.add(field)
}
}
override fun isPauseScreen() = false
override fun keyPressed(key: Int, j: Int, k: Int): Boolean {
if (key == GLFW.GLFW_KEY_E) {
onClose()
return true
}
return super.keyPressed(key, j, k)
}
override fun mouseClicked(mouseX: Double, mouseY: Double, button: Int): Boolean {
val clickedField = ipAddressTextFields.find { it.x <= mouseX && it.x + it.width >= mouseX && it.y <= mouseY && it.y + it.height >= mouseY }
if (clickedField != null) {
ipAddressTextFields.forEach {
if (it !== clickedField) it.setSelected(false)
}
}
return super.mouseClicked(mouseX, mouseY, button)
}
override fun render(matrixStack: MatrixStack, mouseX: Int, mouseY: Int, delta: Float) {
renderBackground(matrixStack)
val minX = (width - backgroundWidth) / 2
val minY = (height - backgroundHeight) / 2
RenderSystem.color4f(1f, 1f, 1f, 1f)
client!!.textureManager.bindTexture(DeviceConsoleScreen.BACKGROUND)
drawTexture(matrixStack, minX, minY, 0, 0, backgroundWidth, backgroundHeight)
super.render(matrixStack, mouseX, mouseY, delta)
ipAddressTextFields.forEach { it.render(matrixStack, mouseX, mouseY, delta) }
textRenderer.draw(matrixStack, "IP Address: ${device.ipAddress}", minX + 5f, minY + 5f, 0x404040)
textRenderer.draw(matrixStack, "MAC Address: ${device.macAddress}", minX + 5f, minY + 15f, 0x404040)
}
}

View File

@ -0,0 +1,50 @@
package net.shadowfacts.phycon.screen.console
import net.minecraft.client.MinecraftClient
import net.minecraft.text.TranslatableText
import net.shadowfacts.cacao.geometry.Axis
import net.shadowfacts.cacao.util.Color
import net.shadowfacts.cacao.view.Label
import net.shadowfacts.cacao.view.StackView
import net.shadowfacts.cacao.view.button.EnumButton
import net.shadowfacts.cacao.viewcontroller.ViewController
import net.shadowfacts.kiwidsl.dsl
import net.shadowfacts.phycon.network.DeviceBlockEntity
import net.shadowfacts.phycon.network.component.ActivationController
import net.shadowfacts.phycon.networking.C2SConfigureActivationMode
import net.shadowfacts.phycon.util.ActivationMode
/**
* @author shadowfacts
*/
class ActivatableDeviceViewController<T>(
val device: T,
): ViewController() where T: DeviceBlockEntity, T: ActivationController.ActivatableDevice {
override fun viewDidLoad() {
super.viewDidLoad()
val label = Label(TranslatableText("gui.phycon.console.remote.mode")).apply {
textColor = Color.TEXT
}
view.addSubview(label)
val mode = EnumButton(device.controller.activationMode, ActivationMode::friendlyName)
mode.handler = {
device.controller.activationMode = it.value
MinecraftClient.getInstance().player!!.networkHandler.sendPacket(C2SConfigureActivationMode(device))
}
view.addSubview(mode)
view.solver.dsl {
mode.widthAnchor equalTo 100
mode.heightAnchor equalTo 20
mode.topAnchor equalTo view.topAnchor
mode.rightAnchor equalTo view.rightAnchor
label.centerYAnchor equalTo mode.centerYAnchor
label.rightAnchor equalTo (mode.leftAnchor - 4)
}
}
}

View File

@ -0,0 +1,94 @@
package net.shadowfacts.phycon.screen.console
import net.minecraft.text.Text
import net.minecraft.text.TranslatableText
import net.minecraft.util.Identifier
import net.shadowfacts.cacao.CacaoScreen
import net.shadowfacts.cacao.geometry.Rect
import net.shadowfacts.cacao.geometry.Size
import net.shadowfacts.cacao.util.Color
import net.shadowfacts.cacao.util.texture.Texture
import net.shadowfacts.cacao.view.Label
import net.shadowfacts.cacao.view.TextureView
import net.shadowfacts.cacao.view.View
import net.shadowfacts.cacao.viewcontroller.TabViewController
import net.shadowfacts.cacao.viewcontroller.ViewController
import net.shadowfacts.cacao.window.Window
import net.shadowfacts.kiwidsl.dsl
import net.shadowfacts.phycon.PhysicalConnectivity
import net.shadowfacts.phycon.network.DeviceBlockEntity
import net.shadowfacts.phycon.network.block.redstone.RedstoneControllerBlockEntity
import net.shadowfacts.phycon.network.component.ActivationController
import org.lwjgl.glfw.GLFW
/**
* @author shadowfacts
*/
class DeviceConsoleScreen(
val device: DeviceBlockEntity,
): CacaoScreen(TranslatableText("item.phycon.console")) {
private val tabController: TabViewController<Tab>
init {
val tabs = mutableListOf(
Tab(
Label("IP").apply { textColor = Color.TEXT },
TranslatableText("gui.phycon.console.details"),
DeviceDetailsViewController(device)
)
)
if (device is ActivationController.ActivatableDevice) {
tabs.add(Tab(
TextureView(Texture(Identifier("textures/item/ender_pearl.png"), 0, 0, 16, 16)).apply {
intrinsicContentSize = Size(16.0, 16.0)
},
TranslatableText("gui.phycon.console.remote"),
ActivatableDeviceViewController(device)
))
}
if (device is RedstoneControllerBlockEntity) {
tabs.add(Tab(
TextureView(Texture(Identifier("textures/block/redstone_torch.png"), 0, 0, 16, 16)).apply {
intrinsicContentSize = Size(16.0, 16.0)
},
TranslatableText("block.phycon.redstone_controller"),
RedstoneControllerViewController(device)
))
}
tabController = TabViewController(tabs)
val root = object: ViewController() {
override fun viewDidLoad() {
super.viewDidLoad()
embedChild(tabController, pinEdges = false)
view.solver.dsl {
tabController.view.centerXAnchor equalTo view.centerXAnchor
tabController.view.centerYAnchor equalTo view.centerYAnchor
tabController.tabVCContainer.widthAnchor equalTo 200
tabController.tabVCContainer.heightAnchor equalTo 150
}
}
}
addWindow(Window(root))
}
override fun isPauseScreen() = false
override fun keyPressed(keyCode: Int, scanCode: Int, modifiers: Int): Boolean {
if (keyCode == GLFW.GLFW_KEY_E) {
onClose()
return true
}
return super.keyPressed(keyCode, scanCode, modifiers)
}
data class Tab(
override val tabView: View,
override val tooltip: Text?,
override val controller: ViewController,
): TabViewController.Tab
}

View File

@ -0,0 +1,44 @@
package net.shadowfacts.phycon.screen.console
import net.minecraft.text.TranslatableText
import net.shadowfacts.cacao.geometry.Axis
import net.shadowfacts.cacao.util.Color
import net.shadowfacts.cacao.view.Label
import net.shadowfacts.cacao.view.StackView
import net.shadowfacts.cacao.viewcontroller.ViewController
import net.shadowfacts.kiwidsl.dsl
import net.shadowfacts.phycon.network.DeviceBlockEntity
/**
* @author shadowfacts
*/
class DeviceDetailsViewController(val device: DeviceBlockEntity): ViewController() {
override fun viewDidLoad() {
super.viewDidLoad()
val stack = StackView(Axis.VERTICAL, StackView.Distribution.LEADING, spacing = 4.0)
view.addSubview(stack)
val name = device.cachedState.block.name.styled { it.withBold(true) }
val deviceNameLabel = Label(name).apply {
textColor = Color.TEXT
}
stack.addArrangedSubview(deviceNameLabel)
val ipLabel = Label(TranslatableText("gui.phycon.console.details.ip", device.ipAddress.toString())).apply {
textColor = Color.TEXT
}
stack.addArrangedSubview(ipLabel)
val macLabel = Label(TranslatableText("gui.phycon.console.details.mac", device.macAddress.toString())).apply {
textColor = Color.TEXT
}
stack.addArrangedSubview(macLabel)
view.solver.dsl {
stack.leftAnchor equalTo view.leftAnchor
stack.topAnchor equalTo view.topAnchor
}
}
}

View File

@ -0,0 +1,73 @@
package net.shadowfacts.phycon.screen.console
import net.minecraft.client.MinecraftClient
import net.minecraft.text.TranslatableText
import net.shadowfacts.cacao.geometry.Axis
import net.shadowfacts.cacao.util.Color
import net.shadowfacts.cacao.view.Label
import net.shadowfacts.cacao.view.StackView
import net.shadowfacts.cacao.view.button.EnumButton
import net.shadowfacts.cacao.view.textfield.TextField
import net.shadowfacts.cacao.viewcontroller.ViewController
import net.shadowfacts.kiwidsl.dsl
import net.shadowfacts.phycon.api.util.IPAddress
import net.shadowfacts.phycon.network.block.redstone.RedstoneControllerBlockEntity
import net.shadowfacts.phycon.networking.C2SConfigureRedstoneController
import net.shadowfacts.phycon.util.RedstoneMode
/**
* @author shadowfacts
*/
class RedstoneControllerViewController(val device: RedstoneControllerBlockEntity): ViewController() {
override fun viewDidLoad() {
super.viewDidLoad()
val modeLabel = Label(TranslatableText("gui.phycon.console.redstone.mode")).apply {
textColor = Color.TEXT
}
view.addSubview(modeLabel)
val managedDevicesLabel = Label(TranslatableText("gui.phycon.console.redstone.devices")).apply {
textColor = Color.TEXT
}
view.addSubview(managedDevicesLabel)
val controls = StackView(Axis.VERTICAL, StackView.Distribution.FILL, spacing = 4.0)
view.addSubview(controls)
val mode = EnumButton(device.redstoneMode, RedstoneMode::friendlyName)
mode.handler = {
device.redstoneMode = it.value
MinecraftClient.getInstance().player!!.networkHandler.sendPacket(C2SConfigureRedstoneController(device))
}
controls.addArrangedSubview(mode)
val textFields = (0 until 5).map { i ->
TextField(device.managedDevices[i]?.toString() ?: "") {
device.managedDevices[i] = IPAddress.parse(it.text)
MinecraftClient.getInstance().player!!.networkHandler.sendPacket(C2SConfigureRedstoneController(device))
}
}
textFields.forEach(controls::addArrangedSubview)
view.solver.dsl {
controls.widthAnchor equalTo 100
controls.rightAnchor equalTo view.rightAnchor
controls.topAnchor equalTo view.topAnchor
mode.heightAnchor equalTo 20
textFields.forEach {
it.heightAnchor equalTo 20
}
modeLabel.centerYAnchor equalTo mode.centerYAnchor
modeLabel.rightAnchor equalTo (mode.leftAnchor - 4)
managedDevicesLabel.centerYAnchor equalTo textFields.first().centerYAnchor
managedDevicesLabel.rightAnchor equalTo (textFields.first().leftAnchor - 4)
}
}
}

View File

@ -11,6 +11,13 @@
"item.phycon.console": "Console", "item.phycon.console": "Console",
"gui.phycon.terminal_buffer": "Buffer", "gui.phycon.terminal_buffer": "Buffer",
"gui.phycon.console.details": "Device Details",
"gui.phycon.console.details.ip": "IP Address: %s",
"gui.phycon.console.details.mac": "MAC Address: %s",
"gui.phycon.console.redstone.mode": "Redstone Mode",
"gui.phycon.console.redstone.devices": "Managed Devices",
"gui.phycon.console.remote": "Remote Management",
"gui.phycon.console.remote.mode": "Activation Mode",
"gui.phycon.redstone_mode.high": "High", "gui.phycon.redstone_mode.high": "High",
"gui.phycon.redstone_mode.low": "Low", "gui.phycon.redstone_mode.low": "Low",
"gui.phycon.redstone_mode.toggle": "Toggle", "gui.phycon.redstone_mode.toggle": "Toggle",