mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-03-07 20:31:51 +09:00
js cannot be accessed concurrently
This commit is contained in:
@@ -343,7 +343,7 @@ let bufAssemble = (isPreview) => {
|
||||
}
|
||||
//let bufDebugStringify = (buf) => [0,1,2].map(i => (buf[i] == undefined) ? "·" : `\\u${buf[i].codePointAt(0).toString(16).toUpperCase()}`).join(' ')
|
||||
let bufDebugStringify = (buf) => [0,1,2].map(i => (buf[i] == undefined) ? "·" : `${buf[i]}`).join(' ')
|
||||
return Object.freeze({"n":"두벌식 표준","states":states,"c":"CuriousTo\uA75Bvald",
|
||||
return Object.freeze({"n":"두벌식 표준","v":"one","c":"CuriousTo\uA75Bvald",
|
||||
// return: [displayed output, composed output]
|
||||
"accept":(headkey,shiftin,altgrin)=>{
|
||||
let layer = 1*shiftin// + 2*altgrin
|
||||
@@ -472,6 +472,5 @@ return Object.freeze({"n":"두벌식 표준","states":states,"c":"CuriousTo\uA75
|
||||
return ret
|
||||
},
|
||||
"reset":()=>{ reset() },
|
||||
"composing":()=>(states.code!=0),
|
||||
"maxCandidates":()=>1
|
||||
"composing":()=>(states.code!=0)
|
||||
})
|
||||
@@ -369,7 +369,7 @@ let bufAssemble = (isPreview) => {
|
||||
return states.buf.join('')
|
||||
}
|
||||
let bufDebugStringify = (buf) => [0,1,2].map(i => (buf[i] == undefined) ? "·" : `\\u${buf[i].codePointAt(0).toString(16).toUpperCase()}`).join(' ')
|
||||
return Object.freeze({"n":"세벌식 3-90","states":states,"c":"CuriousTo\uA75Bvald",
|
||||
return Object.freeze({"n":"세벌식 3-90","v":"one","c":"CuriousTo\uA75Bvald",
|
||||
// return: [displayed output, composed output]
|
||||
"accept":(headkey,shiftin,altgrin)=>{
|
||||
let layer = 1*shiftin// + 2*altgrin
|
||||
@@ -474,6 +474,5 @@ return Object.freeze({"n":"세벌식 3-90","states":states,"c":"CuriousTo\uA75Bv
|
||||
return ret
|
||||
},
|
||||
"reset":()=>{ reset() },
|
||||
"composing":()=>(states.code!=0),
|
||||
"maxCandidates":()=>1
|
||||
"composing":()=>(states.code!=0)
|
||||
})
|
||||
@@ -380,7 +380,7 @@ let bufAssemble = (isPreview) => {
|
||||
return states.buf.join('')
|
||||
}
|
||||
let bufDebugStringify = (buf) => [0,1,2].map(i => (buf[i] == undefined) ? "·" : `\\u${buf[i].codePointAt(0).toString(16).toUpperCase()}`).join(' ')
|
||||
return Object.freeze({"n":"신세벌식 P2","states":states,"c":"CuriousTo\uA75Bvald",
|
||||
return Object.freeze({"n":"신세벌식 P2","v":"one","c":"CuriousTo\uA75Bvald",
|
||||
// return: [displayed output, composed output]
|
||||
"accept":(headkey,shiftin,altgrin)=>{
|
||||
let layer = 1*shiftin// + 2*altgrin
|
||||
@@ -509,6 +509,5 @@ return Object.freeze({"n":"신세벌식 P2","states":states,"c":"CuriousTo\uA75B
|
||||
return ret
|
||||
},
|
||||
"reset":()=>{ reset() },
|
||||
"composing":()=>(states.code!=0),
|
||||
"maxCandidates":()=>1
|
||||
"composing":()=>(states.code!=0)
|
||||
})
|
||||
@@ -269,7 +269,7 @@ let getCandidatesUsingBuf = () => {
|
||||
// console.log(`cangjie in, buf: ${states.buf}, candidates: ${states.candidates}`)
|
||||
return `${states.buf},${states.candidates}`
|
||||
}
|
||||
return Object.freeze({"n":"五仓简体 Qwerty","states":states,"c":"CuriousTo\uA75Bvald, 倉頡之友 。馬來西亞 http://www.chinesecj.com",
|
||||
return Object.freeze({"n":"五仓简体 Qwerty","v":"many","c":"CuriousTo\uA75Bvald, 倉頡之友 。馬來西亞 http://www.chinesecj.com",
|
||||
// return: [displayed output, composed output]
|
||||
"accept":(headkey,shiftin,altgrin)=>{
|
||||
let layer = 1*shiftin// + 2*altgrin
|
||||
@@ -313,6 +313,5 @@ return Object.freeze({"n":"五仓简体 Qwerty","states":states,"c":"CuriousTo\u
|
||||
return ret
|
||||
},
|
||||
"reset":()=>{ reset() },
|
||||
"composing":()=>(states.code!=0),
|
||||
"maxCandidates":()=>10
|
||||
"composing":()=>(states.code!=0)
|
||||
})
|
||||
@@ -269,7 +269,7 @@ let getCandidatesUsingBuf = () => {
|
||||
// console.log(`cangjie in, buf: ${states.buf}, candidates: ${states.candidates}`)
|
||||
return `${states.buf},${states.candidates}`
|
||||
}
|
||||
return Object.freeze({"n":"五倉正體 Qwerty","states":states,"c":"CuriousTo\uA75Bvald, 倉頡之友 。馬來西亞 http://www.chinesecj.com",
|
||||
return Object.freeze({"n":"五倉正體 Qwerty","v":"many","c":"CuriousTo\uA75Bvald, 倉頡之友 。馬來西亞 http://www.chinesecj.com",
|
||||
// return: [displayed output, composed output]
|
||||
"accept":(headkey,shiftin,altgrin)=>{
|
||||
let layer = 1*shiftin// + 2*altgrin
|
||||
@@ -313,6 +313,5 @@ return Object.freeze({"n":"五倉正體 Qwerty","states":states,"c":"CuriousTo\u
|
||||
return ret
|
||||
},
|
||||
"reset":()=>{ reset() },
|
||||
"composing":()=>(states.code!=0),
|
||||
"maxCandidates":()=>10
|
||||
"composing":()=>(states.code!=0)
|
||||
})
|
||||
@@ -11,17 +11,33 @@ data class TerrarumKeyLayout(
|
||||
val symbols: Array<Array<String?>>?
|
||||
)
|
||||
|
||||
data class TerrarumInputMethod(
|
||||
data class TerrarumIME(
|
||||
val name: String,
|
||||
val config: TerrarumIMEConf,
|
||||
// (headkey, shiftin, altgrin, lowLayerKeysym)
|
||||
val acceptChar: (Int, Boolean, Boolean, String) -> Pair<IMECanditates, IMEOutput>,
|
||||
val backspace: () -> IMECanditates,
|
||||
val endCompose: () -> IMEOutput,
|
||||
val reset: () -> Unit,
|
||||
val composing: () -> Boolean,
|
||||
val maxCandidates: () -> Int
|
||||
val composing: () -> Boolean
|
||||
)
|
||||
|
||||
data class TerrarumIMEConf(
|
||||
val name: String,
|
||||
val copying: String,
|
||||
val candidates: TerrarumIMEViewCount
|
||||
)
|
||||
|
||||
enum class TerrarumIMEViewCount {
|
||||
NONE, ONE, MANY;
|
||||
|
||||
fun toInt() = when (this) {
|
||||
NONE -> 0
|
||||
ONE -> 1
|
||||
MANY -> 10 // an hard-coded config
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Key Layout File Structure for Low Layer:
|
||||
* - n: Displayed name of the keyboard layout
|
||||
@@ -44,7 +60,7 @@ object IME {
|
||||
const val IME_EXTENSION = "ime"
|
||||
|
||||
private val lowLayers = HashMap<String, TerrarumKeyLayout>()
|
||||
private val highLayers = HashMap<String, TerrarumInputMethod>()
|
||||
private val highLayers = HashMap<String, TerrarumIME>()
|
||||
|
||||
private val context = org.graalvm.polyglot.Context.newBuilder("js")
|
||||
.allowHostAccess(org.graalvm.polyglot.HostAccess.EXPLICIT)
|
||||
@@ -73,7 +89,7 @@ object IME {
|
||||
return lowLayers[name.lowercase()]!!
|
||||
}
|
||||
|
||||
fun getHighLayerByName(name: String): TerrarumInputMethod {
|
||||
fun getHighLayerByName(name: String): TerrarumIME {
|
||||
return highLayers[name.lowercase()]!!
|
||||
}
|
||||
|
||||
@@ -85,12 +101,20 @@ object IME {
|
||||
return highLayers.keys.toList()
|
||||
}
|
||||
|
||||
private fun String.toViewCount() = when (this.lowercase()) {
|
||||
"none" -> TerrarumIMEViewCount.NONE
|
||||
"one" -> TerrarumIMEViewCount.ONE
|
||||
"many" -> TerrarumIMEViewCount.MANY
|
||||
else -> throw IllegalArgumentException(this)
|
||||
}
|
||||
|
||||
private fun parseKeylayoutFile(file: File): TerrarumKeyLayout {
|
||||
val src = file.readText(Charsets.UTF_8)
|
||||
val jsval = context.eval("js", "'use strict';Object.freeze($src)")
|
||||
val name = jsval.getMember("n").asString()
|
||||
|
||||
val out = Array(256) { Array<String?>(4) { null } }
|
||||
|
||||
for (keycode in 0L until 256L) {
|
||||
val a = jsval.getMember("t").getArrayElement(keycode)
|
||||
if (!a.isNull) {
|
||||
@@ -113,26 +137,30 @@ object IME {
|
||||
private fun String.toCanditates(): List<String> =
|
||||
this.split(',').mapNotNull { it.ifBlank { null } }
|
||||
|
||||
private fun parseImeFile(file: File): TerrarumInputMethod {
|
||||
private fun parseImeFile(file: File): TerrarumIME {
|
||||
val code = file.readText(Charsets.UTF_8)
|
||||
val jsval = context.eval("js", "\"use strict\";(function(){$code})()")
|
||||
val name = jsval.getMember("n").asString()
|
||||
val candidatesCount = jsval.getMember("v").asString().toViewCount()
|
||||
val copying = jsval.getMember("c").asString()
|
||||
|
||||
|
||||
return TerrarumInputMethod(name, { headkey, shifted, alted, lowLayerKeysym ->
|
||||
val a = jsval.invokeMember("accept", headkey, shifted, alted, lowLayerKeysym)
|
||||
a.getArrayElement(0).asString().toCanditates() to a.getArrayElement(1).asString()
|
||||
}, {
|
||||
jsval.invokeMember("backspace").asString().toCanditates()
|
||||
}, {
|
||||
jsval.invokeMember("end").asString()
|
||||
}, {
|
||||
jsval.invokeMember("reset")
|
||||
}, {
|
||||
jsval.invokeMember("composing").asBoolean()
|
||||
}, {
|
||||
jsval.invokeMember("maxCandidates").asInt()
|
||||
}
|
||||
return TerrarumIME(
|
||||
name,
|
||||
TerrarumIMEConf(
|
||||
name, copying, candidatesCount
|
||||
),
|
||||
{ headkey, shifted, alted, lowLayerKeysym ->
|
||||
val a = jsval.invokeMember("accept", headkey, shifted, alted, lowLayerKeysym)
|
||||
a.getArrayElement(0).asString().toCanditates() to a.getArrayElement(1).asString()
|
||||
}, {
|
||||
jsval.invokeMember("backspace").asString().toCanditates()
|
||||
}, {
|
||||
jsval.invokeMember("end").asString()
|
||||
}, {
|
||||
jsval.invokeMember("reset")
|
||||
}, {
|
||||
jsval.invokeMember("composing").asBoolean()
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ package net.torvald.terrarum.gamecontroller
|
||||
import com.badlogic.gdx.Gdx
|
||||
import com.badlogic.gdx.Input
|
||||
import net.torvald.terrarum.App
|
||||
import net.torvald.terrarum.TerrarumAppConfiguration
|
||||
|
||||
/**
|
||||
* BIG WARNING SIGN: since the strober will run on separate thread, ALWAYS BEWARE OF THE [ConcurrentModificationException]!
|
||||
@@ -23,9 +24,9 @@ object InputStrober {
|
||||
/** always Low Layer */
|
||||
// private var keymap = IME.getLowLayerByName(App.getConfigString("basekeyboardlayout"))
|
||||
|
||||
private val thread = Thread { while (!Thread.interrupted()) {
|
||||
if (Gdx.input != null) withKeyboardEvent()
|
||||
} }
|
||||
private val thread = Thread({ while (!Thread.interrupted()) {
|
||||
try { if (Gdx.input != null) withKeyboardEvent() } catch (e: InterruptedException) { break }
|
||||
} }, "${TerrarumAppConfiguration.GAME_NAME}${this.javaClass.simpleName}")
|
||||
|
||||
init {
|
||||
// println("InputStrobe start")
|
||||
|
||||
@@ -75,7 +75,7 @@ object UILoadGovernor {
|
||||
*/
|
||||
class UILoadDemoSavefiles(val remoCon: UIRemoCon) : UICanvas() {
|
||||
|
||||
private val hash = RandomWordsName(3)
|
||||
// private val hash = RandomWordsName(3)
|
||||
|
||||
init {
|
||||
CommonResourcePool.addToLoadingList("inventory_category") {
|
||||
@@ -359,7 +359,7 @@ class UILoadDemoSavefiles(val remoCon: UIRemoCon) : UICanvas() {
|
||||
batch.draw(saveTex, (width - uiWidth - 10) / 2f, 0f)
|
||||
|
||||
// draw texts
|
||||
val loadGameTitleStr = Lang[titles[mode]] + "$EMDASH$hash"
|
||||
val loadGameTitleStr = Lang[titles[mode]]// + "$EMDASH$hash"
|
||||
// "Game Load"
|
||||
App.fontGame.draw(batch, loadGameTitleStr, (width - App.fontGame.getWidth(loadGameTitleStr)).div(2).toFloat(), titleTextPosY.toFloat())
|
||||
// Control help
|
||||
|
||||
@@ -12,6 +12,7 @@ import net.torvald.terrarum.ccE
|
||||
import net.torvald.terrarum.console.Authenticator
|
||||
import net.torvald.terrarum.console.CommandInterpreter
|
||||
import net.torvald.terrarum.gameactors.AVKey
|
||||
import net.torvald.terrarum.gamecontroller.TerrarumKeyboardEvent
|
||||
import net.torvald.terrarum.langpack.Lang
|
||||
import net.torvald.util.CircularArray
|
||||
|
||||
@@ -32,14 +33,16 @@ class ConsoleWindow : UICanvas() {
|
||||
private var messageDisplayPos: Int = 0
|
||||
private var messagesCount: Int = 0
|
||||
|
||||
private var commandInputPool: StringBuilder? = null
|
||||
// private var commandInputPool: StringBuilder? = null
|
||||
private var commandHistory = CircularArray<String>(COMMAND_HISTORY_MAX, true)
|
||||
|
||||
private val LINE_HEIGHT = 20
|
||||
private val MESSAGES_DISPLAY_COUNT = 11
|
||||
|
||||
private val inputToMsgboxGap = 3
|
||||
|
||||
override var width: Int = App.scr.width
|
||||
override var height: Int = LINE_HEIGHT * (MESSAGES_DISPLAY_COUNT + 1)
|
||||
override var height: Int = LINE_HEIGHT * (MESSAGES_DISPLAY_COUNT + 1) + inputToMsgboxGap
|
||||
|
||||
override var openCloseTime = 0f
|
||||
|
||||
@@ -51,8 +54,12 @@ class ConsoleWindow : UICanvas() {
|
||||
|
||||
private var iMadeTheGameToPause = false
|
||||
|
||||
private val textinput = UIItemTextLineInput(this, 0, 0, this.width)
|
||||
|
||||
init {
|
||||
reset()
|
||||
addUIitem(textinput)
|
||||
textinput.isActive = false
|
||||
}
|
||||
|
||||
private val lb = ArrayList<String>()
|
||||
@@ -73,6 +80,8 @@ class ConsoleWindow : UICanvas() {
|
||||
it.setTooltipMessage(null)
|
||||
}
|
||||
}
|
||||
|
||||
uiItems.forEach { it.update(delta) }
|
||||
}
|
||||
|
||||
override fun renderUI(batch: SpriteBatch, camera: Camera) {
|
||||
@@ -81,65 +90,75 @@ class ConsoleWindow : UICanvas() {
|
||||
Toolkit.fillArea(batch, drawOffX, drawOffY, width.toFloat(), height.toFloat())
|
||||
Toolkit.fillArea(batch, drawOffX, drawOffY, width.toFloat(), LINE_HEIGHT.toFloat())
|
||||
|
||||
val input = commandInputPool!!.toString()
|
||||
val inputDrawWidth = App.fontGame.getWidth(input)
|
||||
val inputDrawHeight = App.fontGame.lineHeight
|
||||
|
||||
// text and cursor
|
||||
batch.color = Color.WHITE
|
||||
App.fontGame.draw(batch, input, 1f + drawOffX, drawOffY)
|
||||
|
||||
batch.color = Color(0x7f7f7f_ff)
|
||||
Toolkit.fillArea(batch, inputDrawWidth.toFloat() + drawOffX + 1, drawOffY, 2f, inputDrawHeight)
|
||||
batch.color = Color.WHITE
|
||||
Toolkit.fillArea(batch, inputDrawWidth.toFloat() + drawOffX + 1, drawOffY, 1f, inputDrawHeight - 1)
|
||||
// val input = commandInputPool!!.toString()
|
||||
// val inputDrawWidth = App.fontGame.getWidth(input)
|
||||
// val inputDrawHeight = App.fontGame.lineHeight
|
||||
//
|
||||
// text and cursor
|
||||
// batch.color = Color.WHITE
|
||||
// App.fontGame.draw(batch, input, 1f + drawOffX, drawOffY)
|
||||
//
|
||||
// batch.color = Color(0x7f7f7f_ff)
|
||||
// Toolkit.fillArea(batch, inputDrawWidth.toFloat() + drawOffX + 1, drawOffY, 2f, inputDrawHeight)
|
||||
// batch.color = Color.WHITE
|
||||
// Toolkit.fillArea(batch, inputDrawWidth.toFloat() + drawOffX + 1, drawOffY, 1f, inputDrawHeight - 1)
|
||||
|
||||
|
||||
// messages
|
||||
batch.color = Color.WHITE
|
||||
|
||||
for (i in 0 until MESSAGES_DISPLAY_COUNT) {
|
||||
val message = messages[messageDisplayPos + i] ?: ""
|
||||
App.fontGame.draw(batch, message, 1f + drawOffX, (LINE_HEIGHT * (MESSAGES_DISPLAY_COUNT - i)).toFloat() + drawOffY)
|
||||
App.fontGame.draw(batch, message, 1f + drawOffX, (LINE_HEIGHT * (MESSAGES_DISPLAY_COUNT - i)).toFloat() + drawOffY + inputToMsgboxGap)
|
||||
}
|
||||
|
||||
uiItems.forEach { it.render(batch, camera) }
|
||||
}
|
||||
|
||||
override fun inputStrobed(e: TerrarumKeyboardEvent) {
|
||||
uiItems.forEach { it.inputStrobed(e) }
|
||||
}
|
||||
|
||||
override fun keyDown(key: Int): Boolean {
|
||||
// history
|
||||
if (key == Input.Keys.UP && historyIndex < commandHistory.elemCount)
|
||||
historyIndex++
|
||||
else if (key == Input.Keys.DOWN && historyIndex >= 0)
|
||||
historyIndex--
|
||||
else if (key != Input.Keys.UP && key != Input.Keys.DOWN)
|
||||
historyIndex = -1
|
||||
try {
|
||||
val textOnBuffer = textinput.getText()
|
||||
|
||||
// execute
|
||||
if (key == Input.Keys.ENTER && commandInputPool!!.isNotEmpty()) {
|
||||
commandHistory.appendHead(commandInputPool!!.toString())
|
||||
executeCommand()
|
||||
commandInputPool = StringBuilder()
|
||||
// history
|
||||
if (key == Input.Keys.UP && historyIndex < commandHistory.elemCount)
|
||||
historyIndex++
|
||||
else if (key == Input.Keys.DOWN && historyIndex >= 0)
|
||||
historyIndex--
|
||||
else if (key != Input.Keys.UP && key != Input.Keys.DOWN)
|
||||
historyIndex = -1
|
||||
|
||||
// execute
|
||||
if (key == Input.Keys.ENTER && textOnBuffer.isNotEmpty()) {
|
||||
commandHistory.appendHead(textOnBuffer)
|
||||
executeCommand(textOnBuffer)
|
||||
textinput.clearText()
|
||||
}
|
||||
// scroll
|
||||
else if (key == Input.Keys.UP || key == Input.Keys.DOWN) {
|
||||
// create new stringbuilder
|
||||
textinput.clearText()
|
||||
if (historyIndex >= 0) // just leave blank if index is -1
|
||||
textinput.setText(commandHistory[historyIndex] ?: "")
|
||||
}
|
||||
// delete input
|
||||
// else if (key == Input.Keys.BACKSPACE) {
|
||||
// commandInputPool = StringBuilder()
|
||||
// }
|
||||
// message scroll up
|
||||
else if (key == Input.Keys.PAGE_UP) {
|
||||
setDisplayPos(-MESSAGES_DISPLAY_COUNT + 1)
|
||||
}
|
||||
// message scroll down
|
||||
else if (key == Input.Keys.PAGE_DOWN) {
|
||||
setDisplayPos(MESSAGES_DISPLAY_COUNT - 1)
|
||||
}
|
||||
}
|
||||
// erase last letter
|
||||
else if (key == Input.Keys.BACKSPACE && commandInputPool!!.isNotEmpty()) {
|
||||
commandInputPool!!.deleteCharAt(commandInputPool!!.length - 1)
|
||||
}
|
||||
// scroll
|
||||
else if (key == Input.Keys.UP || key == Input.Keys.DOWN) {
|
||||
// create new stringbuilder
|
||||
commandInputPool = StringBuilder()
|
||||
if (historyIndex >= 0) // just leave blank if index is -1
|
||||
commandInputPool!!.append(commandHistory[historyIndex])
|
||||
}
|
||||
// delete input
|
||||
else if (key == Input.Keys.BACKSPACE) {
|
||||
commandInputPool = StringBuilder()
|
||||
}
|
||||
// message scroll up
|
||||
else if (key == Input.Keys.PAGE_UP) {
|
||||
setDisplayPos(-MESSAGES_DISPLAY_COUNT + 1)
|
||||
}
|
||||
// message scroll down
|
||||
else if (key == Input.Keys.PAGE_DOWN) {
|
||||
setDisplayPos(MESSAGES_DISPLAY_COUNT - 1)
|
||||
catch (e: ConcurrentModificationException) {
|
||||
System.err.println("[ConsoleWindow] ConcurrentModificationException")
|
||||
}
|
||||
|
||||
|
||||
@@ -148,7 +167,7 @@ class ConsoleWindow : UICanvas() {
|
||||
|
||||
val acceptedChars = "1234567890-=qwfpgjluy;[]\\arstdhneio'zxcvbkm,./!@#$%^&*()_+QWFPGJLUY:{}|ARSTDHNEIO\"ZXCVBKM<>? ".toSet()
|
||||
|
||||
override fun keyTyped(character: Char): Boolean {
|
||||
/*override fun keyTyped(character: Char): Boolean {
|
||||
if (character in acceptedChars) {
|
||||
commandInputPool!!.append(character)
|
||||
inputCursorPos += 1
|
||||
@@ -158,14 +177,14 @@ class ConsoleWindow : UICanvas() {
|
||||
else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
override fun keyUp(keycode: Int): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
private fun executeCommand() {
|
||||
CommandInterpreter.execute(commandInputPool!!.toString())
|
||||
private fun executeCommand(s: String) {
|
||||
CommandInterpreter.execute(s)
|
||||
}
|
||||
|
||||
fun sendMessage(msg: String) {
|
||||
@@ -200,7 +219,7 @@ class ConsoleWindow : UICanvas() {
|
||||
messagesCount = 0
|
||||
inputCursorPos = 0
|
||||
commandHistory = CircularArray<String>(COMMAND_HISTORY_MAX, true)
|
||||
commandInputPool = StringBuilder()
|
||||
textinput.clearText()
|
||||
|
||||
if (Authenticator.b()) {
|
||||
sendMessage("$ccE${TerrarumAppConfiguration.GAME_NAME} ${App.getVERSION_STRING()} $EMDASH ${TerrarumAppConfiguration.COPYRIGHT_DATE_NAME}")
|
||||
@@ -232,11 +251,13 @@ class ConsoleWindow : UICanvas() {
|
||||
drawOffY = MovementInterpolator.fastPullOut(openingTimeCounter.toFloat() / openCloseTime.toFloat(),
|
||||
0f, -height.toFloat()
|
||||
)*/
|
||||
textinput.isActive = false
|
||||
}
|
||||
|
||||
override fun endOpening(delta: Float) {
|
||||
drawOffY = 0f
|
||||
openingTimeCounter = 0f
|
||||
textinput.isActive = true
|
||||
}
|
||||
|
||||
override fun endClosing(delta: Float) {
|
||||
@@ -252,5 +273,6 @@ class ConsoleWindow : UICanvas() {
|
||||
}
|
||||
|
||||
override fun dispose() {
|
||||
uiItems.forEach { it.dispose() }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@ import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
||||
import com.badlogic.gdx.graphics.glutils.FrameBuffer
|
||||
import com.jme3.math.FastMath
|
||||
import net.torvald.terrarum.*
|
||||
import net.torvald.terrarum.App.printdbg
|
||||
import net.torvald.terrarum.gamecontroller.*
|
||||
import net.torvald.terrarum.utils.Clipboard
|
||||
import net.torvald.terrarumsansbitmap.gdx.CodepointSequence
|
||||
@@ -44,7 +43,8 @@ data class InputLenCap(val count: Int, val unit: CharLenUnit) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Make sure `inputStrobed()` of the parentUI is up and running.
|
||||
* UIItemTextLineInput does not require any GDX's input event handlers, but it does require InputStrober
|
||||
* to be running and `inputStrobed()` of the parentUI is calling the same method on this.
|
||||
*
|
||||
* Protip: if there are multiple TextLineInputs on a same UI, draw bottom one first, otherwise the IME's
|
||||
* candidate window will be hidden by the bottom UIItem if they overlaps.
|
||||
@@ -126,7 +126,7 @@ class UIItemTextLineInput(
|
||||
private val candidatesBackCol = TEXTINPUT_COL_BACKGROUND.cpy().mul(1f,1f,1f,1.5f)
|
||||
private val candidateNumberStrWidth = App.fontGame.getWidth("8. ")
|
||||
|
||||
private fun getIME(): TerrarumInputMethod? {
|
||||
private fun getIME(): TerrarumIME? {
|
||||
if (!imeOn) return null
|
||||
|
||||
val selectedIME = App.getConfigString("inputmethod")
|
||||
@@ -165,100 +165,105 @@ class UIItemTextLineInput(
|
||||
|
||||
val (eventType, char, headkey, repeatCount, keycodes) = e
|
||||
|
||||
if (eventType == InputStrober.KEY_DOWN || eventType == InputStrober.KEY_CHANGE) {
|
||||
fboUpdateLatch = true
|
||||
forceLitCursor()
|
||||
val ime = getIME()
|
||||
try {
|
||||
if (eventType == InputStrober.KEY_DOWN || eventType == InputStrober.KEY_CHANGE) {
|
||||
fboUpdateLatch = true
|
||||
forceLitCursor()
|
||||
val ime = getIME()
|
||||
|
||||
if (keycodes.contains(App.getConfigInt("control_key_toggleime")) && repeatCount == 1) {
|
||||
toggleIME()
|
||||
}
|
||||
else if (keycodes.contains(Input.Keys.V) && (keycodes.contains(Input.Keys.CONTROL_LEFT) || keycodes.contains(Input.Keys.CONTROL_RIGHT))) {
|
||||
endComposing()
|
||||
paste(Clipboard.fetch().substringBefore('\n').substringBefore('\t').toCodePoints())
|
||||
}
|
||||
else if (keycodes.contains(Input.Keys.C) && (keycodes.contains(Input.Keys.CONTROL_LEFT) || keycodes.contains(Input.Keys.CONTROL_RIGHT))) {
|
||||
endComposing()
|
||||
copyToClipboard()
|
||||
}
|
||||
else if (keycodes.contains(Input.Keys.BACKSPACE)) {
|
||||
if (ime != null && ime.composing()) {
|
||||
candidates = ime.backspace().map { CodepointSequence(it.toCodePoints()) }
|
||||
if (keycodes.contains(App.getConfigInt("control_key_toggleime")) && repeatCount == 1) {
|
||||
toggleIME()
|
||||
}
|
||||
else if (cursorX <= 0) {
|
||||
cursorX = 0
|
||||
cursorDrawX = 0
|
||||
cursorDrawScroll = 0
|
||||
}
|
||||
else {
|
||||
else if (keycodes.contains(Input.Keys.V) && (keycodes.contains(Input.Keys.CONTROL_LEFT) || keycodes.contains(Input.Keys.CONTROL_RIGHT))) {
|
||||
endComposing()
|
||||
if (cursorX > 0) {
|
||||
while (true) {
|
||||
cursorX -= 1
|
||||
val oldCode = textbuf.removeAt(cursorX)
|
||||
// continue deleting hangul pieces because of the font...
|
||||
if (cursorX == 0 || (oldCode !in 0x115F..0x11FF && oldCode !in 0xD7B0..0xD7FF)) break
|
||||
}
|
||||
|
||||
cursorDrawX = App.fontGame.getWidth(CodepointSequence(textbuf.subList(0, cursorX)))
|
||||
tryCursorForward()
|
||||
}
|
||||
paste(Clipboard.fetch().substringBefore('\n').substringBefore('\t').toCodePoints())
|
||||
}
|
||||
}
|
||||
else if (keycodes.contains(Input.Keys.LEFT)) {
|
||||
endComposing()
|
||||
|
||||
if (cursorX > 0) {
|
||||
cursorX -= 1
|
||||
cursorDrawX = App.fontGame.getWidth(CodepointSequence(textbuf.subList(0, cursorX)))
|
||||
tryCursorForward()
|
||||
if (cursorX <= 0) {
|
||||
else if (keycodes.contains(Input.Keys.C) && (keycodes.contains(Input.Keys.CONTROL_LEFT) || keycodes.contains(Input.Keys.CONTROL_RIGHT))) {
|
||||
endComposing()
|
||||
copyToClipboard()
|
||||
}
|
||||
else if (keycodes.contains(Input.Keys.BACKSPACE)) {
|
||||
if (ime != null && ime.composing()) {
|
||||
candidates = ime.backspace().map { CodepointSequence(it.toCodePoints()) }
|
||||
}
|
||||
else if (cursorX <= 0) {
|
||||
cursorX = 0
|
||||
cursorDrawX = 0
|
||||
cursorDrawScroll = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (keycodes.contains(Input.Keys.RIGHT)) {
|
||||
endComposing()
|
||||
else {
|
||||
endComposing()
|
||||
if (cursorX > 0) {
|
||||
while (true) {
|
||||
cursorX -= 1
|
||||
val oldCode = textbuf.removeAt(cursorX)
|
||||
// continue deleting hangul pieces because of the font...
|
||||
if (cursorX == 0 || (oldCode !in 0x115F..0x11FF && oldCode !in 0xD7B0..0xD7FF)) break
|
||||
}
|
||||
|
||||
if (cursorX < textbuf.size) {
|
||||
cursorX += 1
|
||||
cursorDrawX = App.fontGame.getWidth(CodepointSequence(textbuf.subList(0, cursorX)))
|
||||
tryCursorBack()
|
||||
cursorDrawX = App.fontGame.getWidth(CodepointSequence(textbuf.subList(0, cursorX)))
|
||||
tryCursorForward()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// accept:
|
||||
// - literal "<"
|
||||
// - keysymbol that does not start with "<" (not always has length of 1 because UTF-16)
|
||||
else if (char != null && char.length > 0 && char[0].code >= 32 && (char == "<" || !char.startsWith("<"))) {
|
||||
val shiftin = keycodes.contains(Input.Keys.SHIFT_LEFT) || keycodes.contains(Input.Keys.SHIFT_RIGHT)
|
||||
val altgrin = keycodes.contains(Input.Keys.ALT_RIGHT)
|
||||
else if (keycodes.contains(Input.Keys.LEFT)) {
|
||||
endComposing()
|
||||
|
||||
val codepoints = if (ime != null) {
|
||||
val newStatus = ime.acceptChar(headkey, shiftin, altgrin, char)
|
||||
candidates = newStatus.first.map { CodepointSequence(it.toCodePoints()) }
|
||||
|
||||
newStatus.second.toCodePoints()
|
||||
if (cursorX > 0) {
|
||||
cursorX -= 1
|
||||
cursorDrawX = App.fontGame.getWidth(CodepointSequence(textbuf.subList(0, cursorX)))
|
||||
tryCursorForward()
|
||||
if (cursorX <= 0) {
|
||||
cursorX = 0
|
||||
cursorDrawX = 0
|
||||
cursorDrawScroll = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
else char.toCodePoints()
|
||||
else if (keycodes.contains(Input.Keys.RIGHT)) {
|
||||
endComposing()
|
||||
|
||||
if (cursorX < textbuf.size) {
|
||||
cursorX += 1
|
||||
cursorDrawX = App.fontGame.getWidth(CodepointSequence(textbuf.subList(0, cursorX)))
|
||||
tryCursorBack()
|
||||
}
|
||||
}
|
||||
// accept:
|
||||
// - literal "<"
|
||||
// - keysymbol that does not start with "<" (not always has length of 1 because UTF-16)
|
||||
else if (char != null && char.length > 0 && char[0].code >= 32 && (char == "<" || !char.startsWith("<"))) {
|
||||
val shiftin = keycodes.contains(Input.Keys.SHIFT_LEFT) || keycodes.contains(Input.Keys.SHIFT_RIGHT)
|
||||
val altgrin = keycodes.contains(Input.Keys.ALT_RIGHT)
|
||||
|
||||
val codepoints = if (ime != null) {
|
||||
val newStatus = ime.acceptChar(headkey, shiftin, altgrin, char)
|
||||
candidates = newStatus.first.map { CodepointSequence(it.toCodePoints()) }
|
||||
|
||||
newStatus.second.toCodePoints()
|
||||
}
|
||||
else char.toCodePoints()
|
||||
|
||||
// println("textinput codepoints: ${codepoints.map { it.toString(16) }.joinToString()}")
|
||||
|
||||
if (!maxLen.exceeds(textbuf, codepoints)) {
|
||||
textbuf.addAll(cursorX, codepoints)
|
||||
if (!maxLen.exceeds(textbuf, codepoints)) {
|
||||
textbuf.addAll(cursorX, codepoints)
|
||||
|
||||
cursorX += codepoints.size
|
||||
cursorDrawX = App.fontGame.getWidth(CodepointSequence(textbuf.subList(0, cursorX)))
|
||||
cursorX += codepoints.size
|
||||
cursorDrawX = App.fontGame.getWidth(CodepointSequence(textbuf.subList(0, cursorX)))
|
||||
|
||||
tryCursorBack()
|
||||
tryCursorBack()
|
||||
}
|
||||
}
|
||||
else if (keycodes.contains(Input.Keys.ENTER) || keycodes.contains(Input.Keys.NUMPAD_ENTER)) {
|
||||
endComposing()
|
||||
}
|
||||
}
|
||||
else if (keycodes.contains(Input.Keys.ENTER) || keycodes.contains(Input.Keys.NUMPAD_ENTER)) {
|
||||
endComposing()
|
||||
}
|
||||
|
||||
// don't put innards of tryCursorBack/Forward here -- you absolutely don't want that behaviour
|
||||
// don't put innards of tryCursorBack/Forward here -- you absolutely don't want that behaviour
|
||||
}
|
||||
}
|
||||
catch (e: NullPointerException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
||||
if (textbuf.size == 0) {
|
||||
@@ -454,7 +459,7 @@ class UIItemTextLineInput(
|
||||
// draw candidates view
|
||||
if (candidates.isNotEmpty()) {
|
||||
val textWidths = candidates.map { App.fontGame.getWidth(CodepointSequence(it)) }
|
||||
val candidatesMax = getIME()!!.maxCandidates()
|
||||
val candidatesMax = getIME()!!.config.candidates.toInt()
|
||||
val candidatesCount = minOf(candidatesMax, candidates.size)
|
||||
val isOnecolumn = (candidatesCount <= 3)
|
||||
val halfcount = if (isOnecolumn) candidatesCount else FastMath.ceil(candidatesCount / 2f)
|
||||
@@ -510,6 +515,17 @@ class UIItemTextLineInput(
|
||||
|
||||
fun getText() = textbufToString()
|
||||
fun getTextOrPlaceholder(): String = if (textbuf.isEmpty()) currentPlaceholderText.toJavaString() else getText()
|
||||
fun clearText() {
|
||||
resetIME()
|
||||
textbuf.clear()
|
||||
cursorX = 0
|
||||
cursorDrawScroll = 0
|
||||
cursorDrawX = 0
|
||||
}
|
||||
fun setText(s: String) {
|
||||
clearText()
|
||||
textbuf.addAll(s.toCodePoints())
|
||||
}
|
||||
|
||||
override fun dispose() {
|
||||
fbo.dispose()
|
||||
|
||||
Reference in New Issue
Block a user