mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-06-15 13:04:05 +09:00
327 lines
12 KiB
Kotlin
327 lines
12 KiB
Kotlin
package net.torvald.terrarum.ui
|
|
|
|
import com.badlogic.gdx.graphics.*
|
|
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
|
import net.torvald.terrarum.*
|
|
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
|
|
import kotlin.math.roundToInt
|
|
|
|
/**
|
|
* Created by minjaesong on 2017-10-20.
|
|
*/
|
|
class UIItemCatBar(
|
|
parentUI: UICanvas,
|
|
initialX: Int,
|
|
initialY: Int,
|
|
uiInternalWidth: Int,
|
|
override val width: Int,
|
|
val showSideButtons: Boolean = false,
|
|
|
|
val catIcons: TextureRegionPack = CommonResourcePool.getAsTextureRegionPack("inventory_category"),
|
|
/** XY index of the icon in the `catIcons`. When the number is written in decimal, low three digits denote X-axis (index=YYYXXX in decimal). The indices are ordered so that the first element is the icon on the left in the catbar. */
|
|
private val catArrangement: IntArray,
|
|
internal val catIconsMeaning: List<Array<String>>,
|
|
internal val catIconsLabels: List<() -> String>,
|
|
internal val superLabels: List<() -> String> = listOf({ "" }, { "" }, { "" }), // ["Crafting", "Inventory", "Menu"]
|
|
|
|
val panelTransitionReqFun: (Int) -> Unit = {} // for side buttons; for the selection change, override selectionChangeListener
|
|
) : UIItem(parentUI, initialX, initialY) {
|
|
|
|
companion object {
|
|
const val CAT_ALL = "__all__"
|
|
val FILTER_CAT_ALL = arrayOf(CAT_ALL)
|
|
|
|
const val CATBAR_UNDERLINE_OFFSET = 5
|
|
}
|
|
|
|
|
|
private val inventoryUI = parentUI
|
|
override val height = catIcons.tileH + CATBAR_UNDERLINE_OFFSET
|
|
|
|
|
|
private val mainButtons: Array<UIItemImageButton>
|
|
private val buttonGapSize = (width.toFloat() - (catArrangement.size * catIcons.tileW)) / (catArrangement.size)
|
|
/** raw order */
|
|
var selectedIndex = 0 // default to ALL
|
|
private set
|
|
/** re-arranged order */
|
|
// val selectedIcon: Int
|
|
// get() = catArrangement[selectedIndex]
|
|
|
|
private lateinit var sideButtons: Array<UIItemImageButton>
|
|
|
|
// set up all the buttons
|
|
init {
|
|
// place sub UIs: Image Buttons
|
|
mainButtons = Array(catArrangement.size) { index ->
|
|
val iconPosX = ((buttonGapSize / 2) + index * (catIcons.tileW + buttonGapSize)).roundToInt()
|
|
val iconPosY = 0
|
|
|
|
val iconIndex = catArrangement[index]
|
|
val iconIndexX = iconIndex % 1000
|
|
val iconIndexY = iconIndex / 1000
|
|
|
|
object : UIItemImageButton(
|
|
inventoryUI,
|
|
catIcons.get(iconIndexX, iconIndexY),
|
|
initialX = posX + iconPosX,
|
|
initialY = posY + iconPosY,
|
|
highlightable = true
|
|
) {
|
|
override val mouseUp: Boolean // true if mouse is on its occupying section on the bar, not just on the icon's bounding box
|
|
get() = getButtonIndexUnderMouseOnTray() == index && itemRelativeMouseY in -CATBAR_UNDERLINE_OFFSET until (catIcons.tileH + CATBAR_UNDERLINE_OFFSET)
|
|
}
|
|
}
|
|
|
|
|
|
if (showSideButtons) {
|
|
|
|
// side buttons
|
|
// NOTE: < > arrows must "highlightable = false"; "true" otherwise
|
|
// determine gaps: hacky way exploiting that we already know the catbar is always at the c of the ui
|
|
val relativeStartX = posX - (uiInternalWidth - width) / 2
|
|
val sideButtonsGap = (((uiInternalWidth - width) / 2) - 2f * catIcons.tileW) / 3f
|
|
val iconIndex = arrayOf(
|
|
catIcons.get(9, 1),
|
|
catIcons.get(16, 0),
|
|
catIcons.get(17, 0),
|
|
catIcons.get(13, 0)
|
|
)
|
|
|
|
|
|
//println("[UIItemInventoryCatBar] relativeStartX: $relativeStartX")
|
|
//println("[UIItemInventoryCatBar] posX: $posX")
|
|
|
|
sideButtons = Array(iconIndex.size) { index ->
|
|
val iconPosX = if (index < 2)
|
|
(relativeStartX + sideButtonsGap + (sideButtonsGap + catIcons.tileW) * index).roundToInt()
|
|
else
|
|
(relativeStartX + width + 2 * sideButtonsGap + (sideButtonsGap + catIcons.tileW) * index).roundToInt()
|
|
val iconPosY = 0
|
|
|
|
UIItemImageButton(
|
|
inventoryUI,
|
|
iconIndex[index],
|
|
initialX = iconPosX,
|
|
initialY = posY + iconPosY,
|
|
inactiveCol = if (index == 0 || index == 3) Color.WHITE else Color(0xffffff7f.toInt()),
|
|
activeCol = if (index == 0 || index == 3) Toolkit.Theme.COL_MOUSE_UP else Color(0xffffff7f.toInt()),
|
|
highlightable = (index == 0 || index == 3)
|
|
)
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
private val underlineIndTex: Texture
|
|
private val underlineColour = Color(0xeaeaea_40.toInt())
|
|
private val underlineHighlightColour = mainButtons[0].highlightCol
|
|
|
|
private var highlighterXPos = mainButtons[selectedIndex].posX
|
|
private var highlighterXStart = highlighterXPos
|
|
private var highlighterXEnd = highlighterXPos
|
|
|
|
private val highlighterYPos = catIcons.tileH + 4
|
|
private var highlighterMoving = false
|
|
private val highlighterMoveDuration: Second = 0.15f
|
|
private var highlighterMoveTimer: Second = 0f
|
|
|
|
private var transitionFired = false
|
|
|
|
/**
|
|
* 0: map, 1: inventory caticons, 2: menu
|
|
*/
|
|
var selectedPanel = 1; private set
|
|
|
|
|
|
fun setSelectedPanel(n: Int) {
|
|
if (n !in 0..2) throw IllegalArgumentException("$n")
|
|
selectedPanel = n
|
|
|
|
if (showSideButtons) sideButtons[0].highlighted = (n == 0)
|
|
mainButtons[selectedIndex].highlighted = (n == 1)
|
|
if (showSideButtons) sideButtons[3].highlighted = (n == 2)
|
|
}
|
|
|
|
|
|
// set up underlined indicator
|
|
init {
|
|
// procedurally generate texture
|
|
val pixmap = Pixmap(catIcons.tileW + buttonGapSize.floorToInt(), 1, Pixmap.Format.RGBA8888)
|
|
for (x in 0 until pixmap.width.plus(1).ushr(1)) { // eqv. of ceiling the half-int
|
|
val col = /*if (x == 0)*/ /*0xffffff_80.toInt()*/
|
|
/*else if (x == 1)*/ /*0xffffff_c0.toInt()*/
|
|
/*else */ 0xffffff_ff.toInt()
|
|
|
|
pixmap.drawPixel(x, 0, col)
|
|
pixmap.drawPixel(pixmap.width - (x + 1), 0, col)
|
|
}
|
|
underlineIndTex = Texture(pixmap)
|
|
underlineIndTex.setFilter(Texture.TextureFilter.Nearest, Texture.TextureFilter.Nearest)
|
|
pixmap.dispose()
|
|
|
|
|
|
mainButtons[selectedIndex].highlighted = true
|
|
}
|
|
|
|
|
|
/** (oldIndex: Int?, newIndex: Int) -> Unit
|
|
* Indices are raw index. That is, not re-arranged. */
|
|
var selectionChangeListener: ((Int?, Int) -> Unit)? = null
|
|
|
|
// returns the index of the button under mouse by checkig if cursur is on the "virtual rectangle" on the tray,
|
|
// rather than if the cursor is directly above the button
|
|
private fun getButtonIndexUnderMouseOnTray(): Int? {
|
|
return if (itemRelativeMouseX in 0 until width) {
|
|
(itemRelativeMouseX / (width.toFloat() / mainButtons.size)).toInt()
|
|
}
|
|
else null
|
|
}
|
|
|
|
override fun update(delta: Float) {
|
|
super.update(delta)
|
|
|
|
|
|
if (highlighterMoving) {
|
|
highlighterMoveTimer += delta
|
|
|
|
highlighterXPos = Movement.moveQuick(
|
|
highlighterXStart.toFloat(),
|
|
highlighterXEnd.toFloat(),
|
|
highlighterMoveTimer,
|
|
highlighterMoveDuration
|
|
).roundToInt()
|
|
|
|
if (highlighterMoveTimer > highlighterMoveDuration) {
|
|
highlighterMoveTimer = 0f
|
|
highlighterXStart = highlighterXEnd
|
|
highlighterXPos = highlighterXEnd
|
|
highlighterMoving = false
|
|
}
|
|
}
|
|
|
|
|
|
mainButtons.forEachIndexed { index, btn ->
|
|
btn.update(delta)
|
|
|
|
if (btn.mousePushed && selectedPanel != 1) {
|
|
transitionFired = true
|
|
selectedPanel = 1
|
|
}
|
|
|
|
// move selection highlighter
|
|
if (btn.mousePushed && index != selectedIndex) {
|
|
// normal stuffs
|
|
val oldIndex = selectedIndex
|
|
|
|
highlighterXStart = mainButtons[selectedIndex].posX // using old selectedIndex
|
|
selectedIndex = index
|
|
highlighterMoving = true
|
|
highlighterXEnd = mainButtons[selectedIndex].posX // using new selectedIndex
|
|
|
|
selectionChangeListener?.invoke(oldIndex, index)
|
|
}
|
|
|
|
if (selectedPanel == 1) {
|
|
btn.highlighted = (index == selectedIndex) // forcibly highlight if this.highlighted != null
|
|
|
|
if (showSideButtons) {
|
|
sideButtons[0].highlighted = false
|
|
sideButtons[3].highlighted = false
|
|
}
|
|
}
|
|
}
|
|
|
|
if (showSideButtons) {
|
|
sideButtons[0].update(delta)
|
|
sideButtons[3].update(delta)
|
|
|
|
// more transition stuffs
|
|
if (sideButtons[0].mousePushed) {
|
|
if (selectedPanel != 0) transitionFired = true
|
|
mainButtons.forEach { it.highlighted = false }
|
|
selectedPanel = 0
|
|
|
|
sideButtons[0].highlighted = true
|
|
sideButtons[3].highlighted = false
|
|
}
|
|
else if (sideButtons[3].mousePushed) {
|
|
if (selectedPanel != 2) transitionFired = true
|
|
mainButtons.forEach { it.highlighted = false }
|
|
selectedPanel = 2
|
|
transitionFired = true
|
|
|
|
sideButtons[0].highlighted = false
|
|
sideButtons[3].highlighted = true
|
|
}
|
|
|
|
|
|
if (transitionFired) {
|
|
transitionFired = false
|
|
panelTransitionReqFun(selectedPanel)
|
|
}
|
|
}
|
|
}
|
|
|
|
override fun render(frameDelta: Float, batch: SpriteBatch, camera: OrthographicCamera) {
|
|
super.render(frameDelta, batch, camera)
|
|
|
|
// button
|
|
// colour determined by UI items themselves
|
|
mainButtons.forEach { it.render(frameDelta, batch, camera) }
|
|
if (showSideButtons) sideButtons.forEach { it.render(frameDelta, batch, camera) }
|
|
|
|
|
|
blendNormalStraightAlpha(batch)
|
|
|
|
|
|
// underline
|
|
batch.color = underlineColour
|
|
Toolkit.drawStraightLine(batch, posX, posY + height - 1, posX + width, 1, false)
|
|
|
|
if (selectedPanel == 1) {
|
|
// indicator
|
|
batch.color = underlineHighlightColour
|
|
batch.draw(underlineIndTex, (highlighterXPos - buttonGapSize / 2), posY + highlighterYPos.toFloat())
|
|
|
|
// label
|
|
batch.color = labelCol
|
|
catIconsLabels[selectedIndex]().let {
|
|
App.fontGame.draw(batch, it, posX + ((width - App.fontGame.getWidth(it)) / 2), posY + highlighterYPos + 0)
|
|
}
|
|
}
|
|
else {
|
|
// generic label
|
|
batch.color = labelCol
|
|
superLabels[1]().let {
|
|
App.fontGame.draw(batch, it, posX + ((width - App.fontGame.getWidth(it)) / 2), posY + highlighterYPos + 0)
|
|
}
|
|
}
|
|
|
|
|
|
// label under sidebuttons
|
|
if (showSideButtons) {
|
|
batch.color = labelCol
|
|
|
|
superLabels[0]().let {
|
|
Toolkit.drawTextCentered(batch, App.fontGame, it, sideButtons[0].width, sideButtons[0].posX, posY + highlighterYPos + 0)
|
|
}
|
|
|
|
superLabels[2]().let {
|
|
Toolkit.drawTextCentered(batch, App.fontGame, it, sideButtons[3].width, sideButtons[3].posX, posY + highlighterYPos + 0)
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
private val labelCol = Color(0xe8e8e8ff.toInt())
|
|
|
|
|
|
|
|
override fun dispose() {
|
|
underlineIndTex.dispose()
|
|
//catIcons.dispose() // disposed of by the AppLoader
|
|
//mainButtons.forEach { it.dispose() } // disposed of by the AppLoader
|
|
//sideButtons.forEach { it.dispose() } // disposed of by the AppLoader
|
|
}
|
|
} |