mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-06-13 03:54:06 +09:00
working text selector; text input needs more work
This commit is contained in:
@@ -87,7 +87,7 @@ abstract class UIItem(var parentUI: UICanvas, val initialX: Int, val initialY: I
|
||||
|
||||
/** If mouse is hovering over it */
|
||||
open val mouseUp: Boolean
|
||||
get() = relativeMouseX in 0..width - 1 && relativeMouseY in 0..height - 1
|
||||
get() = relativeMouseX in 0 until width && relativeMouseY in 0 until height
|
||||
/** If mouse is hovering over it and mouse is down */
|
||||
open val mousePushed: Boolean
|
||||
get() = mouseUp && Terrarum.mouseDown
|
||||
|
||||
@@ -20,16 +20,17 @@ class UIItemTextLineInput(
|
||||
parentUI: UICanvas,
|
||||
initialX: Int, initialY: Int,
|
||||
override val width: Int,
|
||||
override val height: Int = 24,
|
||||
var placeholder: String? = null,
|
||||
var placeholder: () -> String = { "" },
|
||||
val enablePasteButton: Boolean = true,
|
||||
val enableLanguageButton: Boolean = false
|
||||
) : UIItem(parentUI, initialX, initialY) {
|
||||
|
||||
override val height = 24
|
||||
|
||||
companion object {
|
||||
val TEXTINPUT_COL_TEXT = Color.WHITE
|
||||
val TEXTINPUT_COL_BORDER = Toolkit.Theme.COL_ACTIVE
|
||||
val TEXTINPUT_COL_BORDER_INACTIVE = Toolkit.Theme.COL_INACTIVE
|
||||
val TEXTINPUT_COL_TEXT_HALF = Color.WHITE.cpy().mul(1f,1f,1f,0.5f)
|
||||
val TEXTINPUT_COL_TEXT_DISABLED = Toolkit.Theme.COL_DISABLED
|
||||
val TEXTINPUT_COL_BACKGROUND = Toolkit.Theme.COL_CELL_FILL
|
||||
const val CURSOR_BLINK_TIME = 1f / 3f
|
||||
}
|
||||
@@ -37,7 +38,6 @@ class UIItemTextLineInput(
|
||||
private val fbo = FrameBuffer(Pixmap.Format.RGBA8888, width - 4, height - 4, true)
|
||||
|
||||
var isActive = true
|
||||
var isGreyedOut = false
|
||||
|
||||
var cursorX = 0 // 1 per char (not codepoint)
|
||||
var cursorCodepoint = 0
|
||||
@@ -46,10 +46,12 @@ class UIItemTextLineInput(
|
||||
var cursorBlinkCounter = 0f
|
||||
var cursorOn = true
|
||||
|
||||
val keybuf = StringBuilder()
|
||||
private val textbuf = StringBuilder()
|
||||
|
||||
private var fboUpdateLatch = true
|
||||
|
||||
private var currentPlaceholderText = placeholder() // the placeholder text may change every time you call it
|
||||
|
||||
override fun update(delta: Float) {
|
||||
super.update(delta)
|
||||
|
||||
@@ -64,22 +66,22 @@ class UIItemTextLineInput(
|
||||
|
||||
if (cursorX > 0 && keycodes.contains(Input.Keys.BACKSPACE)) {
|
||||
cursorCodepoint -= 1
|
||||
val lastCp = keybuf.codePointAt(cursorCodepoint)
|
||||
val lastCp = textbuf.codePointAt(cursorCodepoint)
|
||||
val charCount = Character.charCount(lastCp)
|
||||
cursorX -= charCount
|
||||
keybuf.delete(cursorX, cursorX + charCount)
|
||||
textbuf.delete(cursorX, cursorX + charCount)
|
||||
|
||||
cursorDrawX -= App.fontGame.getWidth(String(Character.toChars(lastCp))) - 1
|
||||
codepointCount -= 1
|
||||
}
|
||||
else if (cursorX > 0 && keycodes.contains(Input.Keys.LEFT)) {
|
||||
cursorCodepoint -= 1
|
||||
cursorX -= Character.charCount(keybuf.codePointAt(cursorCodepoint))
|
||||
val lastCp = keybuf.codePointAt(cursorCodepoint)
|
||||
cursorX -= Character.charCount(textbuf.codePointAt(cursorCodepoint))
|
||||
val lastCp = textbuf.codePointAt(cursorCodepoint)
|
||||
cursorDrawX -= App.fontGame.getWidth(String(Character.toChars(lastCp))) - 1
|
||||
}
|
||||
else if (cursorX < codepointCount && keycodes.contains(Input.Keys.RIGHT)) {
|
||||
val lastCp = keybuf.codePointAt(cursorCodepoint)
|
||||
val lastCp = textbuf.codePointAt(cursorCodepoint)
|
||||
cursorDrawX += App.fontGame.getWidth(String(Character.toChars(lastCp))) - 1
|
||||
cursorX += Character.charCount(lastCp)
|
||||
cursorCodepoint += 1
|
||||
@@ -88,7 +90,7 @@ class UIItemTextLineInput(
|
||||
// - literal "<"
|
||||
// - keysymbol that does not start with "<" (not always has length of 1 because UTF-16)
|
||||
else if (char != null && char[0].code >= 32 && (char == "<" || !char.startsWith("<"))) {
|
||||
keybuf.insert(cursorX, char)
|
||||
textbuf.insert(cursorX, char)
|
||||
|
||||
cursorDrawX += App.fontGame.getWidth(char) - 1
|
||||
cursorX += char.length
|
||||
@@ -97,6 +99,10 @@ class UIItemTextLineInput(
|
||||
}
|
||||
}
|
||||
|
||||
if (cursorCodepoint == 0) {
|
||||
currentPlaceholderText = placeholder()
|
||||
}
|
||||
|
||||
cursorBlinkCounter += delta
|
||||
|
||||
while (cursorBlinkCounter >= CURSOR_BLINK_TIME) {
|
||||
@@ -117,7 +123,7 @@ class UIItemTextLineInput(
|
||||
gdxClearAndSetBlend(0f, 0f, 0f, 0f)
|
||||
|
||||
it.color = Color.WHITE
|
||||
App.fontGame.draw(it, "$keybuf", 0f, 0f)
|
||||
App.fontGameFBO.draw(it, if (textbuf.isEmpty()) currentPlaceholderText else "$textbuf", 0f, 0f)
|
||||
} }
|
||||
}
|
||||
|
||||
@@ -126,19 +132,17 @@ class UIItemTextLineInput(
|
||||
batch.color = TEXTINPUT_COL_BACKGROUND
|
||||
Toolkit.fillArea(batch, posX, posY, width, height)
|
||||
|
||||
batch.color = if (isActive) TEXTINPUT_COL_BORDER else TEXTINPUT_COL_BORDER_INACTIVE
|
||||
batch.color = if (isActive) Toolkit.Theme.COL_HIGHLIGHT else if (mouseUp) Toolkit.Theme.COL_ACTIVE else Toolkit.Theme.COL_INACTIVE
|
||||
Toolkit.drawBoxBorder(batch, posX - 1, posY - 1, width + 2, height + 2)
|
||||
|
||||
batch.color = TEXTINPUT_COL_TEXT
|
||||
batch.color = if (textbuf.isEmpty()) TEXTINPUT_COL_TEXT_DISABLED else TEXTINPUT_COL_TEXT
|
||||
batch.draw(fbo.colorBufferTexture, posX + 2f, posY + 2f, fbo.width.toFloat(), fbo.height.toFloat())
|
||||
|
||||
if (isActive && cursorOn) {
|
||||
val oldBatchCol = batch.color.cpy()
|
||||
|
||||
batch.color = batch.color.mul(0.5f,0.5f,0.5f,1f)
|
||||
batch.color = TEXTINPUT_COL_TEXT_HALF
|
||||
Toolkit.fillArea(batch, posX + cursorDrawX + 3, posY, 2, 24)
|
||||
|
||||
batch.color = oldBatchCol
|
||||
batch.color = TEXTINPUT_COL_TEXT
|
||||
Toolkit.fillArea(batch, posX + cursorDrawX + 3, posY, 1, 23)
|
||||
}
|
||||
|
||||
@@ -146,6 +150,9 @@ class UIItemTextLineInput(
|
||||
super.render(batch, camera)
|
||||
}
|
||||
|
||||
fun getText() = textbuf.toString()
|
||||
fun getTextOrPlaceholder() = if (textbuf.isEmpty()) currentPlaceholderText else getText()
|
||||
|
||||
override fun dispose() {
|
||||
fbo.dispose()
|
||||
}
|
||||
|
||||
158
src/net/torvald/terrarum/ui/UIItemTextSelector.kt
Normal file
158
src/net/torvald/terrarum/ui/UIItemTextSelector.kt
Normal file
@@ -0,0 +1,158 @@
|
||||
package net.torvald.terrarum.ui
|
||||
|
||||
import com.badlogic.gdx.graphics.Camera
|
||||
import com.badlogic.gdx.graphics.Color
|
||||
import com.badlogic.gdx.graphics.OrthographicCamera
|
||||
import com.badlogic.gdx.graphics.Pixmap
|
||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
||||
import com.badlogic.gdx.graphics.glutils.FrameBuffer
|
||||
import net.torvald.terrarum.*
|
||||
import net.torvald.terrarum.gameworld.fmod
|
||||
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
|
||||
|
||||
/**
|
||||
* @param width width of the text input where the text gets drawn, not the entire item
|
||||
* @param height height of the text input where the text gets drawn, not the entire item
|
||||
*
|
||||
* Created by minjaesong on 2021-10-21.
|
||||
*/
|
||||
class UIItemTextSelector(
|
||||
parentUI: UICanvas,
|
||||
initialX: Int, initialY: Int,
|
||||
val labelfuns: List<() -> String>,
|
||||
intialSelection: Int,
|
||||
override val width: Int,
|
||||
private val drawBorder: Boolean = true
|
||||
) : UIItem(parentUI, initialX, initialY) {
|
||||
|
||||
init {
|
||||
CommonResourcePool.addToLoadingList("inventory_category") {
|
||||
TextureRegionPack("assets/graphics/gui/inventory/category.tga", 20, 20)
|
||||
}
|
||||
CommonResourcePool.loadAll()
|
||||
}
|
||||
|
||||
private val labels = CommonResourcePool.getAsTextureRegionPack("inventory_category")
|
||||
|
||||
override val height = 24
|
||||
private val buttonW = 30
|
||||
|
||||
private val fbo = FrameBuffer(Pixmap.Format.RGBA8888, width - 54 - 4, height - 4, true)
|
||||
|
||||
var selection = intialSelection
|
||||
private var fboUpdateLatch = true
|
||||
|
||||
private var mouseOnButton = 0 // 0: nothing, 1: left, 2: right
|
||||
|
||||
var selectionChangeListener: (Int) -> Unit = {}
|
||||
|
||||
override fun update(delta: Float) {
|
||||
super.update(delta)
|
||||
|
||||
mouseOnButton =
|
||||
if (relativeMouseX in 0..buttonW && relativeMouseY in 0..height)
|
||||
1
|
||||
else if (relativeMouseX in width - buttonW..width && relativeMouseY in 0..height)
|
||||
2
|
||||
else
|
||||
0
|
||||
|
||||
if (!mouseLatched && Terrarum.mouseDown && mouseOnButton != 0) {
|
||||
mouseLatched = true
|
||||
selection = (selection + (mouseOnButton * 2) - 3) fmod labelfuns.size
|
||||
fboUpdateLatch = true
|
||||
selectionChangeListener(selection)
|
||||
}
|
||||
else if (!Terrarum.mouseDown) mouseLatched = false
|
||||
}
|
||||
|
||||
override fun render(batch: SpriteBatch, camera: Camera) {
|
||||
|
||||
batch.end()
|
||||
|
||||
if (fboUpdateLatch) {
|
||||
fboUpdateLatch = false
|
||||
fbo.inAction(camera as OrthographicCamera, batch) { batch.inUse {
|
||||
gdxClearAndSetBlend(0f, 0f, 0f, 0f)
|
||||
|
||||
it.color = Color.WHITE
|
||||
val t = labelfuns[selection]()
|
||||
val tw = App.fontGame.getWidth(t)
|
||||
App.fontGameFBO.draw(it, t, (fbo.width - tw) / 2, 0)
|
||||
} }
|
||||
}
|
||||
|
||||
batch.begin()
|
||||
|
||||
if (drawBorder) {
|
||||
batch.color = UIItemTextLineInput.TEXTINPUT_COL_BACKGROUND
|
||||
// left button cell back
|
||||
Toolkit.fillArea(batch, posX, posY, buttonW, height)
|
||||
// text area cell back
|
||||
Toolkit.fillArea(batch, posX + buttonW + 3, posY, width - 2*buttonW - 6, height)
|
||||
// right button cell back
|
||||
Toolkit.fillArea(batch, posX + width - buttonW, posY, buttonW, height)
|
||||
|
||||
// text area border
|
||||
batch.color = Toolkit.Theme.COL_INACTIVE
|
||||
Toolkit.drawBoxBorder(batch, posX + buttonW + 2, posY - 1, width - 2*buttonW - 6 + 2, height + 2)
|
||||
|
||||
// left button border
|
||||
batch.color = if (mouseOnButton == 1 && mousePushed) Toolkit.Theme.COL_HIGHLIGHT
|
||||
else if (mouseOnButton == 1) Toolkit.Theme.COL_ACTIVE else Toolkit.Theme.COL_INACTIVE
|
||||
Toolkit.drawBoxBorder(batch, posX - 1, posY - 1, buttonW + 2, height + 2)
|
||||
|
||||
// right button border
|
||||
batch.color = if (mouseOnButton == 2 && mousePushed) Toolkit.Theme.COL_HIGHLIGHT
|
||||
else if (mouseOnButton == 2) Toolkit.Theme.COL_ACTIVE else Toolkit.Theme.COL_INACTIVE
|
||||
Toolkit.drawBoxBorder(batch, posX + width - buttonW - 1, posY - 1, buttonW + 2, height + 2)
|
||||
}
|
||||
|
||||
// left button icon
|
||||
batch.color = if (mouseOnButton == 1 && mousePushed) Toolkit.Theme.COL_HIGHLIGHT
|
||||
else if (mouseOnButton == 1) Toolkit.Theme.COL_ACTIVE else UIItemTextLineInput.TEXTINPUT_COL_TEXT
|
||||
batch.draw(labels.get(16,0), posX + (buttonW - labels.tileW) / 2f, posY + (height - labels.tileH) / 2f)
|
||||
|
||||
// right button icon
|
||||
batch.color = if (mouseOnButton == 2 && mousePushed) Toolkit.Theme.COL_HIGHLIGHT
|
||||
else if (mouseOnButton == 2) Toolkit.Theme.COL_ACTIVE else UIItemTextLineInput.TEXTINPUT_COL_TEXT
|
||||
batch.draw(labels.get(17,0), posX + width - buttonW + (buttonW - labels.tileW) / 2f, posY + (height - labels.tileH) / 2f)
|
||||
|
||||
// draw text
|
||||
batch.color = UIItemTextLineInput.TEXTINPUT_COL_TEXT
|
||||
batch.draw(fbo.colorBufferTexture, posX + buttonW + 5f, posY + 2f, fbo.width.toFloat(), fbo.height.toFloat())
|
||||
|
||||
|
||||
super.render(batch, camera)
|
||||
}
|
||||
|
||||
override fun dispose() {
|
||||
fbo.dispose()
|
||||
}
|
||||
}
|
||||
|
||||
class UIItemSpinner(
|
||||
parentUI: UICanvas,
|
||||
initialX: Int, initialY: Int,
|
||||
intialValue: Int,
|
||||
val min: Int,
|
||||
val max: Int,
|
||||
val step: Int,
|
||||
override val width: Int
|
||||
) : UIItem(parentUI, initialX, initialY) {
|
||||
|
||||
init {
|
||||
CommonResourcePool.addToLoadingList("inventory_category") {
|
||||
TextureRegionPack("assets/graphics/gui/inventory/category.tga", 20, 20)
|
||||
}
|
||||
CommonResourcePool.loadAll()
|
||||
}
|
||||
|
||||
private val labels = CommonResourcePool.getAsTextureRegionPack("inventory_category")
|
||||
|
||||
override val height = 24
|
||||
|
||||
override fun dispose() {
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user