multiple candidates display for IME

This commit is contained in:
minjaesong
2021-10-24 10:38:16 +09:00
parent a1bad044fd
commit 9678338079
4 changed files with 38 additions and 24 deletions

View File

@@ -684,7 +684,7 @@ fun AppUpdateListOfSavegames() {
println("listing savegames...") println("listing savegames...")
// create list of worlds // 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 { try {
DiskSkimmer(file, Common.CHARSET, true) DiskSkimmer(file, Common.CHARSET, true)
} }
@@ -693,7 +693,7 @@ fun AppUpdateListOfSavegames() {
e.printStackTrace() e.printStackTrace()
null null
} }
}.filter { it != null }.sortedByDescending { it!!.getLastModifiedOfFirstFile() } as List<DiskSkimmer>).forEach { }.sortedByDescending { it.getLastModifiedOfFirstFile() }).forEach {
println(it.diskFile.absolutePath) println(it.diskFile.absolutePath)
it.rebuild() // disk skimmer was created without initialisation, so do it now it.rebuild() // disk skimmer was created without initialisation, so do it now
@@ -707,7 +707,7 @@ fun AppUpdateListOfSavegames() {
// create list of players // 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 { try {
DiskSkimmer(file, Common.CHARSET, true) DiskSkimmer(file, Common.CHARSET, true)
} }
@@ -716,7 +716,7 @@ fun AppUpdateListOfSavegames() {
e.printStackTrace() e.printStackTrace()
null null
} }
}.filter { it != null }.sortedByDescending { it!!.getLastModifiedOfFirstFile() } as List<DiskSkimmer>).forEach { }.sortedByDescending { it.getLastModifiedOfFirstFile() }).forEach {
println(it.diskFile.absolutePath) println(it.diskFile.absolutePath)
it.rebuild() // disk skimmer was created without initialisation, so do it now it.rebuild() // disk skimmer was created without initialisation, so do it now

View File

@@ -17,7 +17,7 @@ object CommandDict {
printdbg(this, ModMgr.loadOrder.reversed()) printdbg(this, ModMgr.loadOrder.reversed())
printdbg(this, ModMgr.loadOrder.reversed().map { ModMgr.moduleInfo[it]?.packageName }) 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) printdbg(this, packageRoot)
val packageConsole = "$packageRoot.console" val packageConsole = "$packageRoot.console"
val stream = ClassLoader.getSystemClassLoader().getResourceAsStream(packageConsole.replace('.','/')) val stream = ClassLoader.getSystemClassLoader().getResourceAsStream(packageConsole.replace('.','/'))

View File

@@ -3,6 +3,9 @@ package net.torvald.terrarum.gamecontroller
import net.torvald.terrarum.App.printdbg import net.torvald.terrarum.App.printdbg
import java.io.File import java.io.File
typealias IMECanditates = List<String>
typealias IMEOutput = String
data class TerrarumKeyLayout( data class TerrarumKeyLayout(
val name: String, val name: String,
val symbols: Array<Array<String?>>? val symbols: Array<Array<String?>>?
@@ -11,9 +14,9 @@ data class TerrarumKeyLayout(
data class TerrarumInputMethod( data class TerrarumInputMethod(
val name: String, val name: String,
// (headkey, shiftin, altgrin) // (headkey, shiftin, altgrin)
val acceptChar: (Int, Boolean, Boolean) -> Pair<String, String>, // Pair<Display Char, Output Char if any> val acceptChar: (Int, Boolean, Boolean) -> Pair<IMECanditates, IMEOutput>,
val backspace: () -> String, val backspace: () -> IMECanditates,
val endCompose: () -> String, val endCompose: () -> IMEOutput,
val reset: () -> Unit, val reset: () -> Unit,
val composing: () -> Boolean val composing: () -> Boolean
) )
@@ -103,6 +106,9 @@ object IME {
return TerrarumKeyLayout(name, out) return TerrarumKeyLayout(name, out)
} }
private fun String.toCanditates(): List<String> =
this.split(',').mapNotNull { it.ifBlank { null } }
private fun parseImeFile(file: File): TerrarumInputMethod { private fun parseImeFile(file: File): TerrarumInputMethod {
val code = file.readText(Charsets.UTF_8) val code = file.readText(Charsets.UTF_8)
val jsval = context.eval("js", "\"use strict\";(function(){$code})()") val jsval = context.eval("js", "\"use strict\";(function(){$code})()")
@@ -111,9 +117,9 @@ object IME {
return TerrarumInputMethod(name, { headkey, shifted, alted -> return TerrarumInputMethod(name, { headkey, shifted, alted ->
val a = jsval.invokeMember("accept", 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() jsval.invokeMember("end").asString()
}, { }, {

View File

@@ -115,7 +115,7 @@ class UIItemTextLineInput(
get() = buttonsShown > 0 && relativeMouseX in btn2PosX - posX until btn2PosX - posX + WIDTH_ONEBUTTON && relativeMouseY in 0 until height get() = buttonsShown > 0 && relativeMouseX in btn2PosX - posX until btn2PosX - posX + WIDTH_ONEBUTTON && relativeMouseY in 0 until height
private var imeOn = false private var imeOn = false
private var composingView = CodepointSequence() private var candidates: List<CodepointSequence> = listOf()
private fun getIME(): TerrarumInputMethod? { private fun getIME(): TerrarumInputMethod? {
if (!imeOn) return null if (!imeOn) return null
@@ -176,7 +176,7 @@ class UIItemTextLineInput(
} }
else if (keycodes.contains(Input.Keys.BACKSPACE)) { else if (keycodes.contains(Input.Keys.BACKSPACE)) {
if (ime != null && ime.composing()) { if (ime != null && ime.composing()) {
composingView = CodepointSequence(ime.backspace().toCodePoints()) candidates = ime.backspace().map { CodepointSequence(it.toCodePoints()) }
} }
else if (cursorX <= 0) { else if (cursorX <= 0) {
cursorX = 0 cursorX = 0
@@ -230,7 +230,7 @@ class UIItemTextLineInput(
val codepoints = if (ime != null) { val codepoints = if (ime != null) {
val newStatus = ime.acceptChar(headkey, shiftin, altgrin) val newStatus = ime.acceptChar(headkey, shiftin, altgrin)
composingView = CodepointSequence(newStatus.first.toCodePoints()) candidates = newStatus.first.map { CodepointSequence(it.toCodePoints()) }
newStatus.second.toCodePoints() newStatus.second.toCodePoints()
} }
@@ -291,7 +291,7 @@ class UIItemTextLineInput(
paste(s.toCodePoints()) paste(s.toCodePoints())
} }
fboUpdateLatch = true fboUpdateLatch = true
composingView = CodepointSequence() candidates = listOf()
// resetIME() // not needed; IME will reset itself // resetIME() // not needed; IME will reset itself
} }
@@ -308,7 +308,7 @@ class UIItemTextLineInput(
private fun resetIME() { private fun resetIME() {
getIME()?.reset?.invoke() getIME()?.reset?.invoke()
composingView = CodepointSequence() candidates = listOf()
} }
private fun paste(codepoints: List<Int>) { private fun paste(codepoints: List<Int>) {
@@ -432,17 +432,25 @@ class UIItemTextLineInput(
} }
// compose view background // draw candidates view
if (composingView.size > 0) { if (candidates.isNotEmpty()) {
val previewTextWidth = App.fontGame.getWidth(composingView) val textWidths = candidates.map { App.fontGame.getWidth(CodepointSequence(it)) }
val previewWindowWidth = previewTextWidth.coerceAtLeast(20)
val candidateWinW = (textWidths.maxOrNull() ?: 0).coerceAtLeast(20)
val candidateWinH = App.fontGame.lineHeight.toInt() * candidates.size
// candidate view background
batch.color = TEXTINPUT_COL_BACKGROUND batch.color = TEXTINPUT_COL_BACKGROUND
Toolkit.fillArea(batch, cursorXOnScreen + 2, posY + 27, previewWindowWidth, 20) Toolkit.fillArea(batch, cursorXOnScreen + 2, posY + 27, candidateWinW, candidateWinH)
// compose view border // candidate view border
batch.color = Toolkit.Theme.COL_ACTIVE batch.color = Toolkit.Theme.COL_ACTIVE
Toolkit.drawBoxBorder(batch, cursorXOnScreen + 1, posY + 26, previewWindowWidth + 2, 22) Toolkit.drawBoxBorder(batch, cursorXOnScreen + 1, posY + 26, candidateWinW + 2, candidateWinH + 2)
// compose view text
App.fontGame.draw(batch, composingView, cursorXOnScreen + 2 + (previewWindowWidth - previewTextWidth) / 2, posY + 27) // 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) super.render(batch, camera)