From 500ad94442a377321363b07ab248c1422a2fcd38 Mon Sep 17 00:00:00 2001 From: Shadowfacts Date: Sat, 27 Feb 2021 21:48:40 -0500 Subject: [PATCH] Convert console screen to use Cacao --- .../phycon/api/util/IPAddress.java | 3 + .../net/shadowfacts/cacao/CacaoScreen.kt | 7 +- .../net/shadowfacts/cacao/util/Color.kt | 4 +- .../net/shadowfacts/cacao/view/Label.kt | 4 +- .../cacao/view/button/EnumButton.kt | 7 +- .../cacao/viewcontroller/TabViewController.kt | 30 +++--- .../shadowfacts/phycon/item/ConsoleItem.kt | 15 +-- .../screen/ActivatableDeviceConsoleScreen.kt | 64 ------------- .../phycon/screen/DeviceConsoleScreen.kt | 40 -------- .../screen/RedstoneControllerConsoleScreen.kt | 96 ------------------- .../ActivatableDeviceViewController.kt | 50 ++++++++++ .../screen/console/DeviceConsoleScreen.kt | 94 ++++++++++++++++++ .../console/DeviceDetailsViewController.kt | 44 +++++++++ .../RedstoneControllerViewController.kt | 73 ++++++++++++++ .../resources/assets/phycon/lang/en_us.json | 7 ++ 15 files changed, 307 insertions(+), 231 deletions(-) delete mode 100644 src/main/kotlin/net/shadowfacts/phycon/screen/ActivatableDeviceConsoleScreen.kt delete mode 100644 src/main/kotlin/net/shadowfacts/phycon/screen/DeviceConsoleScreen.kt delete mode 100644 src/main/kotlin/net/shadowfacts/phycon/screen/RedstoneControllerConsoleScreen.kt create mode 100644 src/main/kotlin/net/shadowfacts/phycon/screen/console/ActivatableDeviceViewController.kt create mode 100644 src/main/kotlin/net/shadowfacts/phycon/screen/console/DeviceConsoleScreen.kt create mode 100644 src/main/kotlin/net/shadowfacts/phycon/screen/console/DeviceDetailsViewController.kt create mode 100644 src/main/kotlin/net/shadowfacts/phycon/screen/console/RedstoneControllerViewController.kt diff --git a/src/main/java/net/shadowfacts/phycon/api/util/IPAddress.java b/src/main/java/net/shadowfacts/phycon/api/util/IPAddress.java index e15ed87..63e6a9b 100644 --- a/src/main/java/net/shadowfacts/phycon/api/util/IPAddress.java +++ b/src/main/java/net/shadowfacts/phycon/api/util/IPAddress.java @@ -39,6 +39,9 @@ public final class IPAddress { int b = Integer.parseInt(matcher.group(2)); int c = Integer.parseInt(matcher.group(3)); 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); } diff --git a/src/main/kotlin/net/shadowfacts/cacao/CacaoScreen.kt b/src/main/kotlin/net/shadowfacts/cacao/CacaoScreen.kt index 3d712da..c5d8c0e 100644 --- a/src/main/kotlin/net/shadowfacts/cacao/CacaoScreen.kt +++ b/src/main/kotlin/net/shadowfacts/cacao/CacaoScreen.kt @@ -1,16 +1,15 @@ package net.shadowfacts.cacao -import com.mojang.blaze3d.platform.GlStateManager import net.minecraft.client.gui.screen.Screen import net.minecraft.client.util.math.MatrixStack import net.minecraft.sound.SoundEvents import net.minecraft.text.LiteralText +import net.minecraft.text.Text import net.shadowfacts.cacao.geometry.Point import net.shadowfacts.cacao.util.KeyModifiers import net.shadowfacts.cacao.util.MouseButton import net.shadowfacts.cacao.util.RenderHelper import net.shadowfacts.cacao.window.Window -import org.lwjgl.glfw.GLFW import java.util.* /** @@ -19,7 +18,7 @@ import java.util.* * * @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. private val _windows = LinkedList() @@ -147,4 +146,4 @@ open class CacaoScreen: Screen(LiteralText("CacaoScreen")), AbstractCacaoScreen return false } -} \ No newline at end of file +} diff --git a/src/main/kotlin/net/shadowfacts/cacao/util/Color.kt b/src/main/kotlin/net/shadowfacts/cacao/util/Color.kt index f7775d2..0b7a863 100644 --- a/src/main/kotlin/net/shadowfacts/cacao/util/Color.kt +++ b/src/main/kotlin/net/shadowfacts/cacao/util/Color.kt @@ -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 GREEN = Color(0x00ff00) val BLUE = Color(0x0000ff) + + val TEXT = Color(0x404040) } -} \ No newline at end of file +} diff --git a/src/main/kotlin/net/shadowfacts/cacao/view/Label.kt b/src/main/kotlin/net/shadowfacts/cacao/view/Label.kt index 35303f8..f45d6f7 100644 --- a/src/main/kotlin/net/shadowfacts/cacao/view/Label.kt +++ b/src/main/kotlin/net/shadowfacts/cacao/view/Label.kt @@ -26,7 +26,7 @@ import net.shadowfacts.cacao.util.RenderHelper */ class Label( text: Text, - val shadow: Boolean = true, + val shadow: Boolean = false, val maxLines: Int = 0, val wrappingMode: WrappingMode = WrappingMode.WRAP, val textAlignment: TextAlignment = TextAlignment.LEFT @@ -47,7 +47,7 @@ class Label( constructor( text: String, - shadow: Boolean = true, + shadow: Boolean = false, maxLines: Int = 0, wrappingMode: WrappingMode = WrappingMode.WRAP, textAlignment: TextAlignment = TextAlignment.LEFT, diff --git a/src/main/kotlin/net/shadowfacts/cacao/view/button/EnumButton.kt b/src/main/kotlin/net/shadowfacts/cacao/view/button/EnumButton.kt index 2f848e4..21daf7d 100644 --- a/src/main/kotlin/net/shadowfacts/cacao/view/button/EnumButton.kt +++ b/src/main/kotlin/net/shadowfacts/cacao/view/button/EnumButton.kt @@ -16,7 +16,12 @@ import net.shadowfacts.cacao.view.Label * @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>(initialValue: E, val localizer: (E) -> Text): AbstractButton>(Label(localizer(initialValue))) { +class EnumButton>( + initialValue: E, + val localizer: (E) -> Text +): AbstractButton>( + Label(localizer(initialValue), shadow = true) +) { private val label: Label get() = content as Label diff --git a/src/main/kotlin/net/shadowfacts/cacao/viewcontroller/TabViewController.kt b/src/main/kotlin/net/shadowfacts/cacao/viewcontroller/TabViewController.kt index 7c02b02..6f36181 100644 --- a/src/main/kotlin/net/shadowfacts/cacao/viewcontroller/TabViewController.kt +++ b/src/main/kotlin/net/shadowfacts/cacao/viewcontroller/TabViewController.kt @@ -7,6 +7,7 @@ import net.shadowfacts.cacao.geometry.Axis import net.shadowfacts.cacao.geometry.Point import net.shadowfacts.cacao.geometry.Rect import net.shadowfacts.cacao.geometry.Size +import net.shadowfacts.cacao.util.Color import net.shadowfacts.cacao.util.MouseButton import net.shadowfacts.cacao.util.texture.NinePatchTexture import net.shadowfacts.cacao.util.texture.Texture @@ -21,7 +22,7 @@ import net.shadowfacts.kiwidsl.dsl * @author shadowfacts */ class TabViewController( - val tabs: Array, + val tabs: List, initalTab: T = tabs.first() ): ViewController() { @@ -38,11 +39,14 @@ class TabViewController( private lateinit var outerStack: 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() { 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 outerStack = StackView(Axis.VERTICAL, StackView.Distribution.FILL, -4.0) view.addSubview(outerStack) @@ -51,9 +55,6 @@ class TabViewController( tabStack.zIndex = 1.0 outerStack.addArrangedSubview(tabStack) - tabVCContainer = View() - outerStack.addArrangedSubview(tabVCContainer) - tabButtons = tabs.mapIndexed { index, tab -> val btn = TabButton(tab) btn.handler = this::selectTab @@ -69,8 +70,11 @@ class TabViewController( tabStack.addArrangedSubview(View()) val background = NinePatchView(NinePatchTexture.PANEL_BG) - background.zIndex = -1.0 - tabVCContainer.addSubview(background) + outerStack.addArrangedSubview(background) + + tabVCContainer = View() + tabVCContainer.zIndex = 1.0 + view.addSubview(tabVCContainer) embedChild(currentTab.controller, tabVCContainer) @@ -80,10 +84,10 @@ class TabViewController( outerStack.topAnchor equalTo view.topAnchor outerStack.bottomAnchor equalTo view.bottomAnchor - background.leftAnchor equalTo tabVCContainer.leftAnchor - background.rightAnchor equalTo tabVCContainer.rightAnchor - background.topAnchor equalTo tabVCContainer.topAnchor - background.bottomAnchor equalTo tabVCContainer.bottomAnchor + tabVCContainer.leftAnchor equalTo (background.leftAnchor + 6) + tabVCContainer.rightAnchor equalTo (background.rightAnchor - 6) + tabVCContainer.topAnchor equalTo (background.topAnchor + 6) + tabVCContainer.bottomAnchor equalTo (background.bottomAnchor - 6) } } @@ -125,7 +129,11 @@ class TabViewController( super.wasAdded() backgroundView.usesConstraintBasedLayout = false backgroundView.frame = Rect(0.0, 0.0, 28.0, 32.0) + backgroundView.zIndex = -1.0 addSubview(backgroundView) + solver.dsl { + content.bottomAnchor lessThanOrEqualTo (bottomAnchor - 4) + } } override fun didLayout() { diff --git a/src/main/kotlin/net/shadowfacts/phycon/item/ConsoleItem.kt b/src/main/kotlin/net/shadowfacts/phycon/item/ConsoleItem.kt index 8df0680..9180ad9 100644 --- a/src/main/kotlin/net/shadowfacts/phycon/item/ConsoleItem.kt +++ b/src/main/kotlin/net/shadowfacts/phycon/item/ConsoleItem.kt @@ -8,12 +8,7 @@ import net.minecraft.util.Identifier import net.shadowfacts.phycon.PhysicalConnectivity import net.shadowfacts.phycon.network.DeviceBlock import net.shadowfacts.phycon.network.DeviceBlockEntity -import net.shadowfacts.phycon.network.block.redstone.RedstoneControllerBlockEntity -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 +import net.shadowfacts.phycon.screen.console.DeviceConsoleScreen /** * @author shadowfacts @@ -41,12 +36,8 @@ class ConsoleItem: Item(Settings()) { } private fun openScreen(be: DeviceBlockEntity) { - val screen = TestCacaoScreen() -// val screen = when (be) { -// is ActivationController.ActivatableDevice -> ActivatableDeviceConsoleScreen(be) -// is RedstoneControllerBlockEntity -> RedstoneControllerConsoleScreen(be) -// else -> DeviceConsoleScreen(be) -// } +// val screen = TestCacaoScreen() + val screen = DeviceConsoleScreen(be) MinecraftClient.getInstance().openScreen(screen) } diff --git a/src/main/kotlin/net/shadowfacts/phycon/screen/ActivatableDeviceConsoleScreen.kt b/src/main/kotlin/net/shadowfacts/phycon/screen/ActivatableDeviceConsoleScreen.kt deleted file mode 100644 index b1ffa81..0000000 --- a/src/main/kotlin/net/shadowfacts/phycon/screen/ActivatableDeviceConsoleScreen.kt +++ /dev/null @@ -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( - 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) - } - -} diff --git a/src/main/kotlin/net/shadowfacts/phycon/screen/DeviceConsoleScreen.kt b/src/main/kotlin/net/shadowfacts/phycon/screen/DeviceConsoleScreen.kt deleted file mode 100644 index 2336157..0000000 --- a/src/main/kotlin/net/shadowfacts/phycon/screen/DeviceConsoleScreen.kt +++ /dev/null @@ -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) - } -} diff --git a/src/main/kotlin/net/shadowfacts/phycon/screen/RedstoneControllerConsoleScreen.kt b/src/main/kotlin/net/shadowfacts/phycon/screen/RedstoneControllerConsoleScreen.kt deleted file mode 100644 index 9f30544..0000000 --- a/src/main/kotlin/net/shadowfacts/phycon/screen/RedstoneControllerConsoleScreen.kt +++ /dev/null @@ -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() - - 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) - } - -} diff --git a/src/main/kotlin/net/shadowfacts/phycon/screen/console/ActivatableDeviceViewController.kt b/src/main/kotlin/net/shadowfacts/phycon/screen/console/ActivatableDeviceViewController.kt new file mode 100644 index 0000000..6af152b --- /dev/null +++ b/src/main/kotlin/net/shadowfacts/phycon/screen/console/ActivatableDeviceViewController.kt @@ -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( + 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) + } + } + +} diff --git a/src/main/kotlin/net/shadowfacts/phycon/screen/console/DeviceConsoleScreen.kt b/src/main/kotlin/net/shadowfacts/phycon/screen/console/DeviceConsoleScreen.kt new file mode 100644 index 0000000..22dc0ce --- /dev/null +++ b/src/main/kotlin/net/shadowfacts/phycon/screen/console/DeviceConsoleScreen.kt @@ -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 + + 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 + +} diff --git a/src/main/kotlin/net/shadowfacts/phycon/screen/console/DeviceDetailsViewController.kt b/src/main/kotlin/net/shadowfacts/phycon/screen/console/DeviceDetailsViewController.kt new file mode 100644 index 0000000..ab54834 --- /dev/null +++ b/src/main/kotlin/net/shadowfacts/phycon/screen/console/DeviceDetailsViewController.kt @@ -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 + } + } + +} diff --git a/src/main/kotlin/net/shadowfacts/phycon/screen/console/RedstoneControllerViewController.kt b/src/main/kotlin/net/shadowfacts/phycon/screen/console/RedstoneControllerViewController.kt new file mode 100644 index 0000000..0b24f9b --- /dev/null +++ b/src/main/kotlin/net/shadowfacts/phycon/screen/console/RedstoneControllerViewController.kt @@ -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) + } + } + +} diff --git a/src/main/resources/assets/phycon/lang/en_us.json b/src/main/resources/assets/phycon/lang/en_us.json index ea4ce28..389a51c 100644 --- a/src/main/resources/assets/phycon/lang/en_us.json +++ b/src/main/resources/assets/phycon/lang/en_us.json @@ -11,6 +11,13 @@ "item.phycon.console": "Console", "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.low": "Low", "gui.phycon.redstone_mode.toggle": "Toggle",