diff --git a/src/net/torvald/terrarum/Terrarum.kt b/src/net/torvald/terrarum/Terrarum.kt index 184aef6f6..d8d5c2897 100644 --- a/src/net/torvald/terrarum/Terrarum.kt +++ b/src/net/torvald/terrarum/Terrarum.kt @@ -684,7 +684,7 @@ fun AppUpdateListOfSavegames() { println("listing savegames...") // create list of worlds - (File(App.worldsDir).listFiles().filter { !it.isDirectory && !it.name.contains('.') }.map { file -> + (File(worldsDir).listFiles().filter { !it.isDirectory && !it.name.contains('.') }.mapNotNull { file -> try { DiskSkimmer(file, Common.CHARSET, true) } @@ -693,7 +693,7 @@ fun AppUpdateListOfSavegames() { e.printStackTrace() null } - }.filter { it != null }.sortedByDescending { it!!.getLastModifiedOfFirstFile() } as List).forEach { + }.sortedByDescending { it.getLastModifiedOfFirstFile() }).forEach { println(it.diskFile.absolutePath) it.rebuild() // disk skimmer was created without initialisation, so do it now @@ -707,7 +707,7 @@ fun AppUpdateListOfSavegames() { // create list of players - (File(App.playersDir).listFiles().filter { !it.isDirectory && !it.name.contains('.') }.map { file -> + (File(playersDir).listFiles().filter { !it.isDirectory && !it.name.contains('.') }.mapNotNull { file -> try { DiskSkimmer(file, Common.CHARSET, true) } @@ -716,7 +716,7 @@ fun AppUpdateListOfSavegames() { e.printStackTrace() null } - }.filter { it != null }.sortedByDescending { it!!.getLastModifiedOfFirstFile() } as List).forEach { + }.sortedByDescending { it.getLastModifiedOfFirstFile() }).forEach { println(it.diskFile.absolutePath) it.rebuild() // disk skimmer was created without initialisation, so do it now diff --git a/src/net/torvald/terrarum/console/CommandDict.kt b/src/net/torvald/terrarum/console/CommandDict.kt index 45106dccd..cdea5d3d3 100644 --- a/src/net/torvald/terrarum/console/CommandDict.kt +++ b/src/net/torvald/terrarum/console/CommandDict.kt @@ -17,7 +17,7 @@ object CommandDict { printdbg(this, ModMgr.loadOrder.reversed()) printdbg(this, ModMgr.loadOrder.reversed().map { ModMgr.moduleInfo[it]?.packageName }) - (listOf("net.torvald.terrarum") + ModMgr.loadOrder.reversed().map { ModMgr.moduleInfo[it]?.packageName }.filter { it != null }).forEach{ packageRoot -> + (listOf("net.torvald.terrarum") + ModMgr.loadOrder.reversed().mapNotNull { ModMgr.moduleInfo[it]?.packageName }).forEach{ packageRoot -> printdbg(this, packageRoot) val packageConsole = "$packageRoot.console" val stream = ClassLoader.getSystemClassLoader().getResourceAsStream(packageConsole.replace('.','/')) diff --git a/src/net/torvald/terrarum/gamecontroller/IME.kt b/src/net/torvald/terrarum/gamecontroller/IME.kt index 2eeec5cb1..80e4995f0 100644 --- a/src/net/torvald/terrarum/gamecontroller/IME.kt +++ b/src/net/torvald/terrarum/gamecontroller/IME.kt @@ -3,6 +3,9 @@ package net.torvald.terrarum.gamecontroller import net.torvald.terrarum.App.printdbg import java.io.File +typealias IMECanditates = List +typealias IMEOutput = String + data class TerrarumKeyLayout( val name: String, val symbols: Array>? @@ -11,9 +14,9 @@ data class TerrarumKeyLayout( data class TerrarumInputMethod( val name: String, // (headkey, shiftin, altgrin) - val acceptChar: (Int, Boolean, Boolean) -> Pair, // Pair - val backspace: () -> String, - val endCompose: () -> String, + val acceptChar: (Int, Boolean, Boolean) -> Pair, + val backspace: () -> IMECanditates, + val endCompose: () -> IMEOutput, val reset: () -> Unit, val composing: () -> Boolean ) @@ -103,6 +106,9 @@ object IME { return TerrarumKeyLayout(name, out) } + private fun String.toCanditates(): List = + this.split(',').mapNotNull { it.ifBlank { null } } + private fun parseImeFile(file: File): TerrarumInputMethod { val code = file.readText(Charsets.UTF_8) val jsval = context.eval("js", "\"use strict\";(function(){$code})()") @@ -111,9 +117,9 @@ object IME { return TerrarumInputMethod(name, { headkey, shifted, alted -> val a = jsval.invokeMember("accept", headkey, shifted, alted) - a.getArrayElement(0).asString() to a.getArrayElement(1).asString() + a.getArrayElement(0).asString().toCanditates() to a.getArrayElement(1).asString() }, { - jsval.invokeMember("backspace").asString() + jsval.invokeMember("backspace").asString().toCanditates() }, { jsval.invokeMember("end").asString() }, { diff --git a/src/net/torvald/terrarum/ui/UIItemTextLineInput.kt b/src/net/torvald/terrarum/ui/UIItemTextLineInput.kt index 88eb15541..1768b2c8f 100644 --- a/src/net/torvald/terrarum/ui/UIItemTextLineInput.kt +++ b/src/net/torvald/terrarum/ui/UIItemTextLineInput.kt @@ -115,7 +115,7 @@ class UIItemTextLineInput( get() = buttonsShown > 0 && relativeMouseX in btn2PosX - posX until btn2PosX - posX + WIDTH_ONEBUTTON && relativeMouseY in 0 until height private var imeOn = false - private var composingView = CodepointSequence() + private var candidates: List = listOf() private fun getIME(): TerrarumInputMethod? { if (!imeOn) return null @@ -176,7 +176,7 @@ class UIItemTextLineInput( } else if (keycodes.contains(Input.Keys.BACKSPACE)) { if (ime != null && ime.composing()) { - composingView = CodepointSequence(ime.backspace().toCodePoints()) + candidates = ime.backspace().map { CodepointSequence(it.toCodePoints()) } } else if (cursorX <= 0) { cursorX = 0 @@ -230,7 +230,7 @@ class UIItemTextLineInput( val codepoints = if (ime != null) { val newStatus = ime.acceptChar(headkey, shiftin, altgrin) - composingView = CodepointSequence(newStatus.first.toCodePoints()) + candidates = newStatus.first.map { CodepointSequence(it.toCodePoints()) } newStatus.second.toCodePoints() } @@ -291,7 +291,7 @@ class UIItemTextLineInput( paste(s.toCodePoints()) } fboUpdateLatch = true - composingView = CodepointSequence() + candidates = listOf() // resetIME() // not needed; IME will reset itself } @@ -308,7 +308,7 @@ class UIItemTextLineInput( private fun resetIME() { getIME()?.reset?.invoke() - composingView = CodepointSequence() + candidates = listOf() } private fun paste(codepoints: List) { @@ -432,17 +432,25 @@ class UIItemTextLineInput( } - // compose view background - if (composingView.size > 0) { - val previewTextWidth = App.fontGame.getWidth(composingView) - val previewWindowWidth = previewTextWidth.coerceAtLeast(20) + // draw candidates view + if (candidates.isNotEmpty()) { + val textWidths = candidates.map { App.fontGame.getWidth(CodepointSequence(it)) } + + val candidateWinW = (textWidths.maxOrNull() ?: 0).coerceAtLeast(20) + val candidateWinH = App.fontGame.lineHeight.toInt() * candidates.size + + // candidate view background batch.color = TEXTINPUT_COL_BACKGROUND - Toolkit.fillArea(batch, cursorXOnScreen + 2, posY + 27, previewWindowWidth, 20) - // compose view border + Toolkit.fillArea(batch, cursorXOnScreen + 2, posY + 27, candidateWinW, candidateWinH) + // candidate view border batch.color = Toolkit.Theme.COL_ACTIVE - Toolkit.drawBoxBorder(batch, cursorXOnScreen + 1, posY + 26, previewWindowWidth + 2, 22) - // compose view text - App.fontGame.draw(batch, composingView, cursorXOnScreen + 2 + (previewWindowWidth - previewTextWidth) / 2, posY + 27) + Toolkit.drawBoxBorder(batch, cursorXOnScreen + 1, posY + 26, candidateWinW + 2, candidateWinH + 2) + + // candidate view text + for (i in candidates.indices) { + val previewTextWidth = textWidths[i] + App.fontGame.draw(batch, candidates[i], cursorXOnScreen + 2 + (candidateWinW - previewTextWidth) / 2, posY + 27 + i * 20) + } } super.render(batch, camera)