mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-06-08 17:44:06 +09:00
246 lines
11 KiB
Kotlin
246 lines
11 KiB
Kotlin
package net.torvald.terrarum.modulebasegame.ui
|
|
|
|
import com.badlogic.gdx.Gdx
|
|
import com.badlogic.gdx.Input
|
|
import com.badlogic.gdx.graphics.Color
|
|
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
|
import net.torvald.terrarum.App
|
|
import net.torvald.terrarum.CommonResourcePool
|
|
import net.torvald.terrarum.langpack.Lang
|
|
import net.torvald.terrarum.ui.*
|
|
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
|
|
|
|
typealias ControlPanelOptions = Array<Array<Any>>
|
|
|
|
/**
|
|
* Created by minjaesong on 2023-07-14.
|
|
*/
|
|
object ControlPanelCommon {
|
|
|
|
init {
|
|
CommonResourcePool.addToLoadingList("gui_hrule") {
|
|
TextureRegionPack(Gdx.files.internal("assets/graphics/gui/hrule.tga"), 216, 20)
|
|
}
|
|
CommonResourcePool.loadAll()
|
|
}
|
|
|
|
var CONFIG_SPINNER_WIDTH = 140
|
|
var CONFIG_TYPEIN_WIDTH = 240
|
|
var CONFIG_SLIDER_WIDTH = 240
|
|
var CONFIG_TEXTSEL_WIDTH = 240
|
|
|
|
// @return Pair of <UIItem, Init job for the item>
|
|
fun makeButton(parent: UICanvas, args: String, x: Int, y: Int, optionNames0: String): Pair<UIItem, (UIItem, String) -> Unit> {
|
|
val optionNames = optionNames0.split(",")
|
|
val optionName = optionNames.first()
|
|
val arg = args.split(',')
|
|
|
|
return if (args.equals("h1") || args.equals("p")) {
|
|
(object : UIItem(parent, x, y) {
|
|
override val width = 1
|
|
override val height = 1
|
|
override fun dispose() {}
|
|
}) to { _, _ -> }
|
|
}
|
|
else if (args.startsWith("toggle")) {
|
|
UIItemToggleButton(parent, x, y, CONFIG_SPINNER_WIDTH, App.getConfigBoolean(optionName)) to { it: UIItem, optionStr: String ->
|
|
(it as UIItemToggleButton).clickOnceListener = { _, _ ->
|
|
it.toggle()
|
|
App.setConfig(optionStr, it.getStatus())
|
|
}
|
|
}
|
|
}
|
|
else if (args.startsWith("textsel,")) {
|
|
val labelFuns = arg.subList(1, arg.size).map { { Lang[it.substringAfter("=")] } }
|
|
val optionsList = arg.subList(1, arg.size).map { it.substringBefore("=") }
|
|
|
|
val initialSel = optionsList.indexOf(App.getConfigString(optionName))
|
|
|
|
// println("labelFuns = ${labelFuns.map { it.invoke() }}")
|
|
// println("optionsList = $optionsList")
|
|
// println("optionName = $optionName; value = ${App.getConfigString(optionName)}")
|
|
// println("initialSel = $initialSel")
|
|
|
|
if (initialSel < 0) throw IllegalArgumentException("config value '${App.getConfigString(optionName)}' for option '$optionName' is not found on the options list")
|
|
|
|
UIItemTextSelector(parent, x, y, labelFuns, initialSel, CONFIG_TEXTSEL_WIDTH, clickToShowPalette = false) to { it: UIItem, optionStr: String ->
|
|
(it as UIItemTextSelector).selectionChangeListener = {
|
|
App.setConfig(optionStr, optionsList[it])
|
|
}
|
|
}
|
|
}
|
|
else if (args.startsWith("spinnersel,")) {
|
|
val labelFuns = arg.subList(1, arg.size).map { { it } }
|
|
val optionsList = arg.subList(1, arg.size).map { it.toInt() }
|
|
|
|
val initialSel = optionsList.indexOf(App.getConfigInt(optionName))
|
|
if (initialSel < 0) throw IllegalArgumentException("config value '${App.getConfigInt(optionName)}' for option '$optionName' is not found on the options list")
|
|
|
|
UIItemTextSelector(parent, x, y, labelFuns, initialSel, CONFIG_SPINNER_WIDTH, clickToShowPalette = false, useSpinnerButtons = true) to { it: UIItem, optionStr: String ->
|
|
(it as UIItemTextSelector).selectionChangeListener = {
|
|
App.setConfig(optionStr, optionsList[it])
|
|
}
|
|
}
|
|
}
|
|
else if (args.startsWith("spinner,")) {
|
|
UIItemSpinner(parent, x, y, App.getConfigInt(optionName), arg[1].toInt(), arg[2].toInt(), arg[3].toInt(), CONFIG_SPINNER_WIDTH, numberToTextFunction = { "${it.toLong()}" }) to { it: UIItem, optionStr: String ->
|
|
(it as UIItemSpinner).selectionChangeListener = {
|
|
App.setConfig(optionStr, it)
|
|
}
|
|
}
|
|
}
|
|
else if (args.startsWith("spinnerd,")) {
|
|
UIItemSpinner(parent, x, y, App.getConfigDouble(optionName), arg[1].toDouble(), arg[2].toDouble(), arg[3].toDouble(), CONFIG_SPINNER_WIDTH, numberToTextFunction = { "${((it as Double)*100).toInt()}%" }) to { it: UIItem, optionStr: String ->
|
|
(it as UIItemSpinner).selectionChangeListener = {
|
|
App.setConfig(optionStr, it)
|
|
}
|
|
}
|
|
}
|
|
else if (args.startsWith("sliderd,")) {
|
|
UIItemHorzSlider(parent, x, y, App.getConfigDouble(optionName), arg[1].toDouble(), arg[2].toDouble(), CONFIG_SLIDER_WIDTH) to { it: UIItem, optionStr: String ->
|
|
(it as UIItemHorzSlider).selectionChangeListener = {
|
|
App.setConfig(optionStr, it)
|
|
}
|
|
}
|
|
}
|
|
else if (args.startsWith("spinnerimul,")) {
|
|
val mult = arg[4].toInt()
|
|
UIItemSpinner(parent, x, y, App.getConfigInt(optionName) / mult, arg[1].toInt(), arg[2].toInt(), arg[3].toInt(), CONFIG_SPINNER_WIDTH, numberToTextFunction = { "${it.toLong()}" }) to { it: UIItem, optionStr: String ->
|
|
(it as UIItemSpinner).selectionChangeListener = {
|
|
App.setConfig(optionStr, it.toInt() * mult)
|
|
}
|
|
}
|
|
}
|
|
else if (args.startsWith("typeinint")) {
|
|
// val arg = args.split(',') // args: none
|
|
UIItemTextLineInput(parent, x, y, CONFIG_SPINNER_WIDTH,
|
|
defaultValue = { "${App.getConfigInt(optionName)}" },
|
|
maxLen = InputLenCap(4, InputLenCap.CharLenUnit.CODEPOINTS),
|
|
keyFilter = { it.headkey in Input.Keys.NUM_0..Input.Keys.NUM_9 || it.headkey == Input.Keys.BACKSPACE }
|
|
) to { it: UIItem, optionStr: String ->
|
|
(it as UIItemTextLineInput).textCommitListener = {
|
|
App.setConfig(optionStr, it.toInt()) // HAXXX!!!
|
|
}
|
|
}
|
|
}
|
|
else if (args.startsWith("typeinres")) {
|
|
val keyWidth = optionNames[0]
|
|
val keyHeight = optionNames[1]
|
|
UIItemTextLineInput(parent, x, y, CONFIG_SPINNER_WIDTH,
|
|
defaultValue = { "${App.getConfigInt(keyWidth)}x${App.getConfigInt(keyHeight)}" },
|
|
maxLen = InputLenCap(9, InputLenCap.CharLenUnit.CODEPOINTS),
|
|
keyFilter = { it.headkey == Input.Keys.ENTER || it.headkey == Input.Keys.BACKSPACE || it.character?.matches(Regex("[0-9xX]")) == true },
|
|
alignment = UIItemTextButton.Companion.Alignment.CENTRE
|
|
) to { it: UIItem, optionStr: String ->
|
|
(it as UIItemTextLineInput).textCommitListener = { text ->
|
|
val text = text.lowercase()
|
|
if (text.matches(Regex("""[0-9]+x[0-9]+"""))) {
|
|
it.markAsNormal()
|
|
val width = text.substringBefore('x').toInt()
|
|
val height = text.substringAfter('x').toInt()
|
|
App.setConfig(keyWidth, width)
|
|
App.setConfig(keyHeight, height)
|
|
}
|
|
else it.markAsInvalid()
|
|
}
|
|
}
|
|
}
|
|
else if (args.startsWith("typein")) {
|
|
//args: none
|
|
UIItemTextLineInput(parent, x, y, CONFIG_TYPEIN_WIDTH, defaultValue = { App.getConfigString(optionName) }) to { it: UIItem, optionStr: String ->
|
|
(it as UIItemTextLineInput).textCommitListener = {
|
|
App.setConfig(optionStr, it)
|
|
}
|
|
}
|
|
}
|
|
else throw IllegalArgumentException(args)
|
|
}
|
|
|
|
private val linegap = 14
|
|
private val panelgap = 20
|
|
|
|
private val rowheight = 20 + linegap
|
|
|
|
private val h1MarginTop = 16
|
|
private val h1MarginBottom = 4
|
|
|
|
private val optionsYposCache = HashMap<String, IntArray>()
|
|
private val optionsCache = HashMap<String, ControlPanelOptions>()
|
|
|
|
fun register(ui: UICanvas, width: Int, identifier: String, options: ControlPanelOptions) {
|
|
optionsCache[identifier] = options
|
|
val optionsYpos = IntArray(options.size + 1)
|
|
var akku = 0
|
|
options.forEachIndexed { index, row ->
|
|
val option = row[2]
|
|
|
|
if (index > 0 && option == "h1") {
|
|
akku += h1MarginTop
|
|
}
|
|
|
|
optionsYpos[index] = akku
|
|
|
|
akku += when (option) {
|
|
"h1" -> rowheight + h1MarginBottom
|
|
else -> rowheight
|
|
}
|
|
}
|
|
optionsYpos[optionsYpos.lastIndex] = akku
|
|
optionsYposCache[identifier] = optionsYpos
|
|
|
|
val height = optionsYpos.last()
|
|
val drawX = (App.scr.width - width) / 2
|
|
val drawY = (App.scr.height - height) / 2
|
|
|
|
options.forEachIndexed { index, args ->
|
|
val (item, job) = makeButton(
|
|
ui, args[2] as String,
|
|
drawX + width / 2 + panelgap,
|
|
drawY - 2 + optionsYpos[index],
|
|
args[0] as String
|
|
)
|
|
job.invoke(item, args[0] as String)
|
|
ui.addUIitem(item)
|
|
}
|
|
}
|
|
|
|
private val hrule = CommonResourcePool.getAsTextureRegionPack("gui_hrule")
|
|
|
|
fun getMenuHeight(identifier: String) = optionsYposCache[identifier]!!.last()
|
|
|
|
fun render(identifier: String, width: Int, batch: SpriteBatch) {
|
|
val height = optionsYposCache[identifier]!!.last()
|
|
val drawX = (App.scr.width - width) / 2
|
|
val drawY = (App.scr.height - height) / 2
|
|
|
|
val optionsYpos = optionsYposCache[identifier]!!
|
|
optionsCache[identifier]!!.forEachIndexed { index, args ->
|
|
val mode = args[2]
|
|
|
|
val font = if (mode == "h1") App.fontUITitle else App.fontGame
|
|
|
|
val label = (args[1] as () -> String).invoke()
|
|
val labelWidth = font.getWidth(label)
|
|
batch.color = when (mode) {
|
|
"h1" -> Toolkit.Theme.COL_MOUSE_UP
|
|
"p" -> Color.LIGHT_GRAY
|
|
else -> Color.WHITE
|
|
}
|
|
|
|
val xpos = if (mode == "p" || mode == "h1")
|
|
drawX + (width - labelWidth)/2 // centre-aligned
|
|
else
|
|
drawX + width/2 - panelgap - labelWidth // right aligned at the middle of the panel, offsetted by panelgap
|
|
|
|
font.draw(batch, label, xpos.toFloat(), drawY + optionsYpos[index] - 2f)
|
|
|
|
// draw hrule
|
|
if (mode == "h1") {
|
|
val ruleWidth = ((width - 24 - labelWidth) / 2).toFloat()
|
|
batch.draw(hrule.get(0,0), xpos - 24f - ruleWidth, drawY + optionsYpos[index].toFloat(), ruleWidth, hrule.tileH.toFloat())
|
|
batch.draw(hrule.get(0,1), xpos + 24f + labelWidth, drawY + optionsYpos[index].toFloat(), ruleWidth, hrule.tileH.toFloat())
|
|
}
|
|
}
|
|
}
|
|
|
|
} |