mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-06-09 18:14:06 +09:00
nsmenu working submenu navigation; new graphics bug discovered
This commit is contained in:
@@ -938,4 +938,4 @@ fun interpolateLinear(scale: Double, startValue: Double, endValue: Double): Doub
|
|||||||
return endValue
|
return endValue
|
||||||
}
|
}
|
||||||
return (1.0 - scale) * startValue + scale * endValue
|
return (1.0 - scale) * startValue + scale * endValue
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ class UITestPad1 : ScreenAdapter() {
|
|||||||
|
|
||||||
override fun render(delta: Float) {
|
override fun render(delta: Float) {
|
||||||
// UPDATE
|
// UPDATE
|
||||||
|
nsMenu.update(delta)
|
||||||
|
|
||||||
// RENDER
|
// RENDER
|
||||||
|
|
||||||
|
|||||||
@@ -66,9 +66,11 @@ abstract class UICanvas(
|
|||||||
get() = mouseUp && Gdx.input.isButtonPressed(Terrarum.getConfigInt("mouseprimary"))
|
get() = mouseUp && Gdx.input.isButtonPressed(Terrarum.getConfigInt("mouseprimary"))
|
||||||
|
|
||||||
|
|
||||||
|
/** Called by the screen */
|
||||||
fun update(delta: Float) {
|
fun update(delta: Float) {
|
||||||
handler.update(this, delta)
|
handler.update(this, delta)
|
||||||
}
|
}
|
||||||
|
/** Called by the screen */
|
||||||
fun render(batch: SpriteBatch, camera: Camera) {
|
fun render(batch: SpriteBatch, camera: Camera) {
|
||||||
handler.render(this, batch, camera)
|
handler.render(this, batch, camera)
|
||||||
}
|
}
|
||||||
@@ -127,6 +129,8 @@ abstract class UICanvas(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Called by the screen's InputProcessor
|
||||||
|
*
|
||||||
* When implementing this, make sure to use ```mouseInScreen()``` function!
|
* When implementing this, make sure to use ```mouseInScreen()``` function!
|
||||||
*/
|
*/
|
||||||
open fun touchDragged(screenX: Int, screenY: Int, pointer: Int): Boolean {
|
open fun touchDragged(screenX: Int, screenY: Int, pointer: Int): Boolean {
|
||||||
@@ -137,6 +141,7 @@ abstract class UICanvas(
|
|||||||
}
|
}
|
||||||
else return false
|
else return false
|
||||||
}
|
}
|
||||||
|
/** Called by the screen's InputProcessor */
|
||||||
open fun touchDown(screenX: Int, screenY: Int, pointer: Int, button: Int): Boolean {
|
open fun touchDown(screenX: Int, screenY: Int, pointer: Int, button: Int): Boolean {
|
||||||
if (this.isVisible && mouseInScreen(screenX, screenY)) {
|
if (this.isVisible && mouseInScreen(screenX, screenY)) {
|
||||||
uiItems.forEach { it.touchDown(screenX, screenY, pointer, button) }
|
uiItems.forEach { it.touchDown(screenX, screenY, pointer, button) }
|
||||||
@@ -145,6 +150,7 @@ abstract class UICanvas(
|
|||||||
}
|
}
|
||||||
else return false
|
else return false
|
||||||
}
|
}
|
||||||
|
/** Called by the screen's InputProcessor */
|
||||||
open fun touchUp(screenX: Int, screenY: Int, pointer: Int, button: Int): Boolean {
|
open fun touchUp(screenX: Int, screenY: Int, pointer: Int, button: Int): Boolean {
|
||||||
if (this.isVisible) {
|
if (this.isVisible) {
|
||||||
uiItems.forEach { it.touchUp(screenX, screenY, pointer, button) }
|
uiItems.forEach { it.touchUp(screenX, screenY, pointer, button) }
|
||||||
@@ -153,6 +159,7 @@ abstract class UICanvas(
|
|||||||
}
|
}
|
||||||
else return false
|
else return false
|
||||||
}
|
}
|
||||||
|
/** Called by the screen's InputProcessor */
|
||||||
open fun scrolled(amount: Int): Boolean {
|
open fun scrolled(amount: Int): Boolean {
|
||||||
if (this.isVisible) {
|
if (this.isVisible) {
|
||||||
uiItems.forEach { it.scrolled(amount) }
|
uiItems.forEach { it.scrolled(amount) }
|
||||||
@@ -161,6 +168,7 @@ abstract class UICanvas(
|
|||||||
}
|
}
|
||||||
else return false
|
else return false
|
||||||
}
|
}
|
||||||
|
/** Called by the screen's InputProcessor */
|
||||||
open fun keyDown(keycode: Int): Boolean {
|
open fun keyDown(keycode: Int): Boolean {
|
||||||
if (this.isVisible) {
|
if (this.isVisible) {
|
||||||
uiItems.forEach { it.keyDown(keycode) }
|
uiItems.forEach { it.keyDown(keycode) }
|
||||||
@@ -169,6 +177,7 @@ abstract class UICanvas(
|
|||||||
}
|
}
|
||||||
else return false
|
else return false
|
||||||
}
|
}
|
||||||
|
/** Called by the screen's InputProcessor */
|
||||||
open fun keyUp(keycode: Int): Boolean {
|
open fun keyUp(keycode: Int): Boolean {
|
||||||
if (this.isVisible) {
|
if (this.isVisible) {
|
||||||
uiItems.forEach { it.keyUp(keycode) }
|
uiItems.forEach { it.keyUp(keycode) }
|
||||||
@@ -177,6 +186,7 @@ abstract class UICanvas(
|
|||||||
}
|
}
|
||||||
else return false
|
else return false
|
||||||
}
|
}
|
||||||
|
/** Called by the screen's InputProcessor */
|
||||||
open fun keyTyped(character: Char): Boolean {
|
open fun keyTyped(character: Char): Boolean {
|
||||||
return false
|
return false
|
||||||
//uiItems.forEach { it.keyT }
|
//uiItems.forEach { it.keyT }
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import com.badlogic.gdx.graphics.Camera
|
|||||||
import com.badlogic.gdx.graphics.Color
|
import com.badlogic.gdx.graphics.Color
|
||||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
||||||
import net.torvald.terrarum.*
|
import net.torvald.terrarum.*
|
||||||
|
import java.lang.Error
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Nextstep-themed menu bar with mandatory title line
|
* Nextstep-themed menu bar with mandatory title line
|
||||||
@@ -23,56 +24,122 @@ class UINSMenu(
|
|||||||
) : UICanvas() {
|
) : UICanvas() {
|
||||||
|
|
||||||
override var openCloseTime: Second = 0f
|
override var openCloseTime: Second = 0f
|
||||||
val LINE_HEIGHT = 24
|
val LINE_HEIGHT = 30
|
||||||
val TEXT_OFFSETX = 3f
|
val TEXT_OFFSETX = 3f
|
||||||
val TEXT_OFFSETY = (LINE_HEIGHT - Terrarum.fontGame.lineHeight) / 2f
|
val TEXT_OFFSETY = (LINE_HEIGHT - Terrarum.fontGame.lineHeight) / 2f
|
||||||
val CHILD_ARROW = "${0x2023.toChar()}"
|
val CHILD_ARROW = "${0x2023.toChar()}"
|
||||||
|
|
||||||
|
|
||||||
val tree = treeRepresentation.parse()
|
val tree = treeRepresentation.parse()
|
||||||
override var width = maxOf(minimumWidth, tree.getLevelData(1).map { Terrarum.fontGame.getWidth(it ?: "") }.max() ?: 0)
|
override var width = 0
|
||||||
override var height = LINE_HEIGHT * (tree.children.size + 1)
|
override var height = 0
|
||||||
private val treeChildrenLabels = Array<String>(tree.children.size) {
|
//override var width = maxOf(minimumWidth, tree.getLevelData(1).map { Terrarum.fontGame.getWidth(it ?: "") }.max() ?: 0)
|
||||||
tree.children[it].toString() + if (tree.children[it].children.isNotEmpty()) " $CHILD_ARROW" else ""
|
//override var height = LINE_HEIGHT * (tree.children.size + 1)
|
||||||
}
|
|
||||||
|
|
||||||
private val theRealList = UIItemTextButtonList(
|
|
||||||
this,
|
|
||||||
treeChildrenLabels,
|
|
||||||
posX, posY + LINE_HEIGHT,
|
|
||||||
width, height - LINE_HEIGHT,
|
|
||||||
textAreaWidth = width - (2 * TEXT_OFFSETX.toInt()),
|
|
||||||
alignment = UIItemTextButton.Companion.Alignment.LEFT,
|
|
||||||
activeBackCol = Color(0x242424_80),//Color(1f,0f,.75f,1f),
|
|
||||||
inactiveCol = Color(.94f,.94f,.94f,1f),
|
|
||||||
itemHitboxSize = LINE_HEIGHT
|
|
||||||
|
|
||||||
)
|
private val listStack = ArrayList<MenuPack>()
|
||||||
|
private var currentDepth = 0
|
||||||
|
|
||||||
|
private data class MenuPack(val title: String, val list: UIItemTextButtonList)
|
||||||
|
|
||||||
|
private fun ArrayList<MenuPack>.push(item: MenuPack) { this.add(item) }
|
||||||
|
private fun ArrayList<MenuPack>.pop() = this.removeAt(this.lastIndex)!!
|
||||||
|
private fun ArrayList<MenuPack>.peek() = this.last()!!
|
||||||
|
|
||||||
|
|
||||||
val selectedIndex: Int?
|
val selectedIndex: Int?
|
||||||
get() = theRealList.selectedIndex
|
get() = listStack.peek().list.selectedIndex
|
||||||
|
|
||||||
|
init {
|
||||||
|
addSubMenu(tree)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun addSubMenu(tree: QNDTreeNode<String>) {
|
||||||
|
val stringsFromTree = Array<String>(tree.children.size) {
|
||||||
|
tree.children[it].toString() + if (tree.children[it].children.isNotEmpty()) " $CHILD_ARROW" else ""
|
||||||
|
}
|
||||||
|
|
||||||
|
val listWidth = maxOf(minimumWidth, tree.getLevelData(1).map { Terrarum.fontGame.getWidth(it ?: "") }.max() ?: 0)
|
||||||
|
val listHeight = stringsFromTree.size * LINE_HEIGHT
|
||||||
|
|
||||||
|
val list = UIItemTextButtonList(
|
||||||
|
this,
|
||||||
|
stringsFromTree,
|
||||||
|
width, LINE_HEIGHT,
|
||||||
|
listWidth, listHeight,
|
||||||
|
textAreaWidth = listWidth - (2 * TEXT_OFFSETX.toInt()),
|
||||||
|
alignment = UIItemTextButton.Companion.Alignment.LEFT,
|
||||||
|
activeBackCol = Color(0x242424_80),//Color(1f,0f,.75f,1f),
|
||||||
|
inactiveCol = Color(.94f,.94f,.94f,1f),
|
||||||
|
itemHitboxSize = LINE_HEIGHT
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
// List selection change listener
|
||||||
|
list.selectionChangeListener = { old, new ->
|
||||||
|
// if the selection has a child...
|
||||||
|
if (tree.children[new].children.isNotEmpty()) {
|
||||||
|
// 1. pop as far as possible
|
||||||
|
// 2. push the new menu
|
||||||
|
|
||||||
|
// 1. pop as far as possible
|
||||||
|
while (listStack.peek().list != list) {
|
||||||
|
popSubMenu()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. push the new menu
|
||||||
|
addSubMenu(tree.children[new])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// END List selection change listener
|
||||||
|
|
||||||
|
|
||||||
|
// push the processed list
|
||||||
|
listStack.push(MenuPack(tree.data ?: title, list))
|
||||||
|
// increment the memoized width
|
||||||
|
width += listWidth
|
||||||
|
currentDepth += 1
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun popSubMenu() {
|
||||||
|
if (listStack.size == 1) throw Error("Tried to pop root menu")
|
||||||
|
|
||||||
|
val poppedUIItem = listStack.pop()
|
||||||
|
width -= poppedUIItem.list.width
|
||||||
|
}
|
||||||
|
|
||||||
override fun updateUI(delta: Float) {
|
override fun updateUI(delta: Float) {
|
||||||
theRealList.update(delta)
|
/*listStack.forEach {
|
||||||
|
it.list.update(delta)
|
||||||
|
}*/ // fucking concurrent modification
|
||||||
|
|
||||||
|
var c = 0
|
||||||
|
while (c < listStack.size) {
|
||||||
|
listStack[c].list.update(delta)
|
||||||
|
c += 1
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun renderUI(batch: SpriteBatch, camera: Camera) {
|
override fun renderUI(batch: SpriteBatch, camera: Camera) {
|
||||||
// draw title bar
|
listStack.forEach {
|
||||||
batch.color = titleBackCol
|
// draw title bar
|
||||||
BlendMode.resolve(titleBlendMode, batch)
|
batch.color = titleBackCol
|
||||||
batch.fillRect(0f, 0f, width.toFloat(), LINE_HEIGHT.toFloat())
|
BlendMode.resolve(titleBlendMode, batch)
|
||||||
|
batch.fillRect(it.list.posX.toFloat(), it.list.posY.toFloat() - LINE_HEIGHT, it.list.width.toFloat(), LINE_HEIGHT.toFloat())
|
||||||
|
|
||||||
batch.color = titleTextCol
|
batch.color = titleTextCol
|
||||||
blendNormal(batch)
|
blendNormal(batch)
|
||||||
Terrarum.fontGame.draw(batch, title, TEXT_OFFSETX, TEXT_OFFSETY)
|
Terrarum.fontGame.draw(batch, it.title, TEXT_OFFSETX + it.list.posX, TEXT_OFFSETY + it.list.posY - LINE_HEIGHT)
|
||||||
|
|
||||||
|
// draw the list
|
||||||
|
batch.color = Color.WHITE
|
||||||
|
it.list.render(batch, camera)
|
||||||
|
}
|
||||||
|
|
||||||
// draw the list
|
|
||||||
batch.color = Color.WHITE
|
|
||||||
theRealList.render(batch, camera)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun dispose() {
|
override fun dispose() {
|
||||||
theRealList.dispose()
|
listStack.forEach { it.list.dispose() }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun mouseOnTitleBar() =
|
fun mouseOnTitleBar() =
|
||||||
@@ -104,7 +171,7 @@ class UINSMenu(
|
|||||||
if (mouseInScreen(screenX, screenY)) {
|
if (mouseInScreen(screenX, screenY)) {
|
||||||
if (dragForReal) {
|
if (dragForReal) {
|
||||||
handler.setPosition(screenX - dragOriginX, screenY - dragOriginY)
|
handler.setPosition(screenX - dragOriginX, screenY - dragOriginY)
|
||||||
println("drag $screenX, $screenY")
|
//println("drag $screenX, $screenY")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user