/*
* Skytils - Hypixel Skyblock Quality of Life Mod
* Copyright (C) 2021 Skytils
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
*/
package skytils.skytilsmod.gui
import gg.essential.elementa.WindowScreen
import gg.essential.elementa.components.ScrollComponent
import gg.essential.elementa.components.UIContainer
import gg.essential.elementa.components.UIText
import gg.essential.elementa.components.input.UITextInput
import gg.essential.elementa.constraints.CenterConstraint
import gg.essential.elementa.constraints.ChildBasedSizeConstraint
import gg.essential.elementa.constraints.RelativeConstraint
import gg.essential.elementa.constraints.SiblingConstraint
import gg.essential.elementa.dsl.*
import gg.essential.elementa.effects.OutlineEffect
import gg.essential.universal.UKeyboard
import gg.essential.vigilance.utils.onLeftClick
import net.minecraft.util.ChatAllowedCharacters
import skytils.skytilsmod.core.PersistentSave
import skytils.skytilsmod.features.impl.handlers.KeyShortcuts
import skytils.skytilsmod.gui.components.SimpleButton
import skytils.skytilsmod.utils.Utils
import java.awt.Color
class KeyShortcutsGui : WindowScreen(newGuiScale = 2), ReopenableGUI {
private val scrollComponent: ScrollComponent
private var clickedButton: Entry? = null
private val components = HashMap()
init {
UIText("Key Shortcuts").childOf(window).constrain {
x = CenterConstraint()
y = RelativeConstraint(0.075f)
height = 14.pixels()
}
scrollComponent = ScrollComponent(
innerPadding = 4f,
).childOf(window).constrain {
x = CenterConstraint()
y = 15.percent()
width = 90.percent()
height = 70.percent() + 2.pixels()
}
val bottomButtons = UIContainer().childOf(window).constrain {
x = CenterConstraint()
y = 90.percent()
width = ChildBasedSizeConstraint()
height = ChildBasedSizeConstraint()
}
SimpleButton("Save and Exit").childOf(bottomButtons).constrain {
x = 0.pixels()
y = 0.pixels()
}.onLeftClick {
mc.displayGuiScreen(null)
}
SimpleButton("Add Shortcut").childOf(bottomButtons).constrain {
x = SiblingConstraint(5f)
y = 0.pixels()
}.onLeftClick {
addNewShortcut()
}
KeyShortcuts.shortcuts.onEach {
addNewShortcut(it.key, it.value)
}
}
private fun addNewShortcut(command: String = "", keyCode: Int = 0) {
val container = UIContainer().childOf(scrollComponent).constrain {
x = CenterConstraint()
y = SiblingConstraint(5f)
width = 80.percent()
height = 9.5.percent()
}.effect(OutlineEffect(Color(0, 243, 255), 1f))
val commandToRun = (UITextInput("Executed Command").childOf(container).constrain {
x = 5.pixels()
y = CenterConstraint()
width = 70.percent()
}.onLeftClick {
if (clickedButton == null) grabWindowFocus()
} as UITextInput).also {
it.setText(command)
it.onKeyType { _, _ ->
it.setText(it.getText().filter(ChatAllowedCharacters::isAllowedCharacter).take(255))
}
}
val keybindButton = SimpleButton(Utils.getKeyDisplayStringSafe(keyCode)).childOf(container).constrain {
x = SiblingConstraint(5f)
y = CenterConstraint()
height = 75.percent()
}
SimpleButton("Remove").childOf(container).constrain {
x = 85.percent()
y = CenterConstraint()
height = 75.percent()
}.onLeftClick {
container.parent.removeChild(container)
components.remove(container)
}
val entry = Entry(container, commandToRun, keybindButton, keyCode)
keybindButton.onLeftClick {
clickedButton = entry
}
components[container] = entry
}
override fun onScreenClose() {
super.onScreenClose()
KeyShortcuts.shortcuts.clear()
for ((_, entry) in components) {
val command = entry.input.getText()
val keyCode = entry.keyCode
if (command.isBlank() || keyCode == 0) continue
KeyShortcuts.shortcuts[command] = keyCode
}
PersistentSave.markDirty()
}
override fun onKeyPressed(keyCode: Int, typedChar: Char, modifiers: UKeyboard.Modifiers?) {
if (clickedButton != null) {
when {
keyCode == 1 -> clickedButton!!.keyCode = 0
keyCode != 0 -> clickedButton!!.keyCode = keyCode
typedChar.code > 0 -> clickedButton!!.keyCode = typedChar.code + 256
}
clickedButton = null
} else super.onKeyPressed(keyCode, typedChar, modifiers)
}
override fun onMouseClicked(mouseX: Double, mouseY: Double, mouseButton: Int) {
if (clickedButton != null) {
clickedButton!!.keyCode = -100 + mouseButton
clickedButton = null
} else super.onMouseClicked(mouseX, mouseY, mouseButton)
}
override fun onTick() {
super.onTick()
for (item in components) {
val button = item.value.button
val keyCode = item.value.keyCode
button.text.setText(Utils.getKeyDisplayStringSafe(keyCode))
val pressed = clickedButton === item.value
val reused =
keyCode != 0 && (mc.gameSettings.keyBindings.any { it.keyCode == keyCode } || components.any { it.value.keyCode != 0 && it !== item && it.value.keyCode == keyCode })
if (pressed) {
button.text.setText("§f> §e${button.text.getText()}§f <")
} else if (reused) {
button.text.setText("§c${button.text.getText()}")
}
}
}
data class Entry(val container: UIContainer, val input: UITextInput, val button: SimpleButton, var keyCode: Int)
}