Keyboard support for Next-button and Unit actions redone (#2372)
This commit is contained in:
parent
33da0e3a7f
commit
25a5559969
2 changed files with 85 additions and 34 deletions
|
@ -64,6 +64,9 @@ class WorldScreen(val viewingCiv:CivilizationInfo) : CameraStageBaseScreen() {
|
|||
|
||||
private var backButtonListener : InputListener
|
||||
|
||||
// An initialized val always turned out to illegally be null...
|
||||
lateinit var keyPressDispatcher: HashMap<Char,(() -> Unit)>
|
||||
|
||||
init {
|
||||
topBar.setPosition(0f, stage.height - topBar.height)
|
||||
topBar.width = stage.width
|
||||
|
@ -110,7 +113,7 @@ class WorldScreen(val viewingCiv:CivilizationInfo) : CameraStageBaseScreen() {
|
|||
|
||||
stage.addActor(unitActionsTable)
|
||||
|
||||
createNextTurnButton() // needs civ table to be positioned
|
||||
// still a zombie: createNextTurnButton() // needs civ table to be positioned
|
||||
|
||||
val tileToCenterOn: Vector2 =
|
||||
when {
|
||||
|
@ -142,6 +145,11 @@ class WorldScreen(val viewingCiv:CivilizationInfo) : CameraStageBaseScreen() {
|
|||
shouldUpdate = true
|
||||
}
|
||||
|
||||
private fun cleanupKeyDispatcher() {
|
||||
val delKeys = keyPressDispatcher.keys.filter { it!=' ' && it!='n' }
|
||||
delKeys.forEach { keyPressDispatcher.remove(it) }
|
||||
}
|
||||
|
||||
private fun addKeyboardListener() {
|
||||
stage.addListener(
|
||||
object : InputListener() {
|
||||
|
@ -187,6 +195,17 @@ class WorldScreen(val viewingCiv:CivilizationInfo) : CameraStageBaseScreen() {
|
|||
}
|
||||
return true
|
||||
}
|
||||
|
||||
override fun keyTyped(event: InputEvent?, character: Char): Boolean {
|
||||
if (character.toLowerCase() in keyPressDispatcher && !hasOpenPopups()) {
|
||||
//try-catch mainly for debugging. Breakpoints in the vicinity can make the event fire twice in rapid succession, second time the context can be invalid
|
||||
try {
|
||||
keyPressDispatcher[character.toLowerCase()]?.invoke()
|
||||
} catch (ex: Exception) {}
|
||||
return true
|
||||
}
|
||||
return super.keyTyped(event, character)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
@ -244,6 +263,7 @@ class WorldScreen(val viewingCiv:CivilizationInfo) : CameraStageBaseScreen() {
|
|||
}
|
||||
|
||||
minimapWrapper.update(viewingCiv)
|
||||
cleanupKeyDispatcher()
|
||||
unitActionsTable.update(bottomUnitTable.selectedUnit)
|
||||
unitActionsTable.y = bottomUnitTable.height
|
||||
|
||||
|
@ -398,7 +418,11 @@ class WorldScreen(val viewingCiv:CivilizationInfo) : CameraStageBaseScreen() {
|
|||
val nextTurnButton = TextButton("", skin) // text is set in update()
|
||||
nextTurnButton.label.setFontSize(30)
|
||||
nextTurnButton.labelCell.pad(10f)
|
||||
nextTurnButton.onClick { nextTurnAction() }
|
||||
val nextTurnActionWrapped = { nextTurnAction() }
|
||||
nextTurnButton.onClick (nextTurnActionWrapped)
|
||||
if (!::keyPressDispatcher.isInitialized) keyPressDispatcher = hashMapOf()
|
||||
keyPressDispatcher[' '] = nextTurnActionWrapped
|
||||
keyPressDispatcher['n'] = nextTurnActionWrapped
|
||||
|
||||
return nextTurnButton
|
||||
}
|
||||
|
|
|
@ -2,9 +2,12 @@ package com.unciv.ui.worldscreen.unit
|
|||
|
||||
import com.badlogic.gdx.graphics.Color
|
||||
import com.badlogic.gdx.scenes.scene2d.Actor
|
||||
import com.badlogic.gdx.scenes.scene2d.InputEvent
|
||||
import com.badlogic.gdx.scenes.scene2d.Touchable
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Button
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Label
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Table
|
||||
import com.badlogic.gdx.scenes.scene2d.utils.ClickListener
|
||||
import com.unciv.Constants
|
||||
import com.unciv.UncivGame
|
||||
import com.unciv.logic.map.MapUnit
|
||||
|
@ -12,48 +15,60 @@ import com.unciv.models.UnitAction
|
|||
import com.unciv.ui.utils.*
|
||||
import com.unciv.ui.worldscreen.WorldScreen
|
||||
|
||||
private data class UnitIconAndKey (val Icon: Actor, val key: Char = 0.toChar())
|
||||
class UnitActionButtonOnHoverListener(private val item: Actor, private val keyLabel: Label) : ClickListener() {
|
||||
override fun enter(event: InputEvent, x: Float, y: Float, pointer: Int, fromActor: Actor?) {
|
||||
super.enter(event, x, y, pointer, fromActor)
|
||||
keyLabel.isVisible = true
|
||||
}
|
||||
override fun exit(event: InputEvent, x: Float, y: Float, pointer: Int, toActor: Actor?) {
|
||||
super.exit(event, x, y, pointer, toActor)
|
||||
keyLabel.isVisible = false
|
||||
}
|
||||
}
|
||||
|
||||
class UnitActionsTable(val worldScreen: WorldScreen) : Table(){
|
||||
|
||||
init {
|
||||
touchable = Touchable.enabled
|
||||
}
|
||||
|
||||
private fun getIconForUnitAction(unitAction:String): Actor {
|
||||
private fun getIconAnKeyForUnitAction(unitAction:String): UnitIconAndKey {
|
||||
when {
|
||||
unitAction.startsWith("Upgrade to") -> {
|
||||
// Regexplaination: start with a [, take as many non-] chars as you can, until you reach a ].
|
||||
// What you find between the first [ and the first ] that comes after it, will be group no. 1
|
||||
val unitToUpgradeTo = Regex("""Upgrade to \[([^\]]*)\]""").find(unitAction)!!.groups[1]!!.value
|
||||
return ImageGetter.getUnitIcon(unitToUpgradeTo)
|
||||
return UnitIconAndKey(ImageGetter.getUnitIcon(unitToUpgradeTo), 'u')
|
||||
}
|
||||
unitAction.startsWith("Sleep") -> return ImageGetter.getImage("OtherIcons/Sleep")
|
||||
unitAction.startsWith("Fortify") -> return ImageGetter.getImage("OtherIcons/Shield").apply { color= Color.BLACK }
|
||||
unitAction.startsWith("Sleep") -> return UnitIconAndKey(ImageGetter.getImage("OtherIcons/Sleep"),'f')
|
||||
unitAction.startsWith("Fortify") -> return UnitIconAndKey(ImageGetter.getImage("OtherIcons/Shield").apply { color= Color.BLACK },'f')
|
||||
else -> when(unitAction){
|
||||
"Move unit" -> return ImageGetter.getStatIcon("Movement")
|
||||
"Stop movement"-> return ImageGetter.getStatIcon("Movement").apply { color= Color.RED }
|
||||
"Promote" -> return ImageGetter.getImage("OtherIcons/Star").apply { color= Color.GOLD }
|
||||
"Construct improvement" -> return ImageGetter.getUnitIcon(Constants.worker)
|
||||
"Automate" -> return ImageGetter.getUnitIcon("Great Engineer")
|
||||
"Stop automation" -> return ImageGetter.getImage("OtherIcons/Stop")
|
||||
"Found city" -> return ImageGetter.getUnitIcon(Constants.settler)
|
||||
"Hurry Research" -> return ImageGetter.getUnitIcon("Great Scientist")
|
||||
"Construct Academy" -> return ImageGetter.getImprovementIcon("Academy")
|
||||
"Start Golden Age" -> return ImageGetter.getUnitIcon("Great Artist")
|
||||
"Construct Landmark" -> return ImageGetter.getImprovementIcon("Landmark")
|
||||
"Construct Citadel" -> return ImageGetter.getImprovementIcon("Citadel")
|
||||
"Hurry Wonder" -> return ImageGetter.getUnitIcon("Great Engineer")
|
||||
"Construct Manufactory" -> return ImageGetter.getImprovementIcon("Manufactory")
|
||||
"Conduct Trade Mission" -> return ImageGetter.getUnitIcon("Great Merchant")
|
||||
"Construct Customs House" -> return ImageGetter.getImprovementIcon("Customs house")
|
||||
"Set up" -> return ImageGetter.getUnitIcon("Catapult")
|
||||
"Disband unit" -> return ImageGetter.getImage("OtherIcons/DisbandUnit")
|
||||
"Explore" -> return ImageGetter.getUnitIcon("Scout")
|
||||
"Stop exploration" -> return ImageGetter.getImage("OtherIcons/Stop")
|
||||
"Create Fishing Boats" -> return ImageGetter.getImprovementIcon("Fishing Boats")
|
||||
"Create Oil well" -> return ImageGetter.getImprovementIcon("Oil well")
|
||||
"Pillage" -> return ImageGetter.getImage("OtherIcons/Pillage")
|
||||
"Construct road" -> return ImageGetter.getImprovementIcon("Road")
|
||||
else -> return ImageGetter.getImage("OtherIcons/Star")
|
||||
"Move unit" -> return UnitIconAndKey(ImageGetter.getStatIcon("Movement"))
|
||||
"Stop movement"-> return UnitIconAndKey(ImageGetter.getStatIcon("Movement").apply { color= Color.RED }, '.')
|
||||
"Promote" -> return UnitIconAndKey(ImageGetter.getImage("OtherIcons/Star").apply { color= Color.GOLD }, 'o')
|
||||
"Construct improvement" -> return UnitIconAndKey(ImageGetter.getUnitIcon(Constants.worker),'i')
|
||||
"Automate" -> return UnitIconAndKey(ImageGetter.getUnitIcon("Great Engineer"), 'm')
|
||||
"Stop automation" -> return UnitIconAndKey(ImageGetter.getImage("OtherIcons/Stop"), 'm')
|
||||
"Found city" -> return UnitIconAndKey(ImageGetter.getUnitIcon(Constants.settler),'f')
|
||||
"Hurry Research" -> return UnitIconAndKey(ImageGetter.getUnitIcon("Great Scientist"), 'g')
|
||||
"Construct Academy" -> return UnitIconAndKey(ImageGetter.getImprovementIcon("Academy"), 'i')
|
||||
"Start Golden Age" -> return UnitIconAndKey(ImageGetter.getUnitIcon("Great Artist"), 'g')
|
||||
"Construct Landmark" -> return UnitIconAndKey(ImageGetter.getImprovementIcon("Landmark"), 'i')
|
||||
"Construct Citadel" -> return UnitIconAndKey(ImageGetter.getImprovementIcon("Citadel"), 'i')
|
||||
"Hurry Wonder" -> return UnitIconAndKey(ImageGetter.getUnitIcon("Great Engineer"), 'g')
|
||||
"Construct Manufactory" -> return UnitIconAndKey(ImageGetter.getImprovementIcon("Manufactory"), 'i')
|
||||
"Conduct Trade Mission" -> return UnitIconAndKey(ImageGetter.getUnitIcon("Great Merchant"), 'g')
|
||||
"Construct Customs House" -> return UnitIconAndKey(ImageGetter.getImprovementIcon("Customs house"), 'i')
|
||||
"Set up" -> return UnitIconAndKey(ImageGetter.getUnitIcon("Catapult"), 't')
|
||||
"Disband unit" -> return UnitIconAndKey(ImageGetter.getImage("OtherIcons/DisbandUnit"))
|
||||
"Explore" -> return UnitIconAndKey(ImageGetter.getUnitIcon("Scout"), 'x')
|
||||
"Stop exploration" -> return UnitIconAndKey(ImageGetter.getImage("OtherIcons/Stop"), 'x')
|
||||
"Create Fishing Boats" -> return UnitIconAndKey(ImageGetter.getImprovementIcon("Fishing Boats"),'i')
|
||||
"Create Oil well" -> return UnitIconAndKey(ImageGetter.getImprovementIcon("Oil well"),'i')
|
||||
"Pillage" -> return UnitIconAndKey(ImageGetter.getImage("OtherIcons/Pillage"),'p')
|
||||
"Construct road" -> return UnitIconAndKey(ImageGetter.getImprovementIcon("Road"),'r')
|
||||
else -> return UnitIconAndKey(ImageGetter.getImage("OtherIcons/Star"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -69,16 +84,28 @@ class UnitActionsTable(val worldScreen: WorldScreen) : Table(){
|
|||
|
||||
|
||||
private fun getUnitActionButton(unitAction: UnitAction): Button {
|
||||
val iconAndKey = getIconAnKeyForUnitAction(unitAction.title)
|
||||
val actionButton = Button(CameraStageBaseScreen.skin)
|
||||
actionButton.add(getIconForUnitAction(unitAction.title)).size(20f).pad(5f)
|
||||
actionButton.add(iconAndKey.Icon).size(20f).pad(5f)
|
||||
val fontColor = if(unitAction.isCurrentAction) Color.YELLOW else Color.WHITE
|
||||
actionButton.add(unitAction.title.toLabel(fontColor)).pad(5f)
|
||||
if (iconAndKey.key != 0.toChar()) {
|
||||
val keyLabel = "(${iconAndKey.key.toUpperCase()})".toLabel(Color.WHITE).apply { isVisible = false }
|
||||
actionButton.add(keyLabel)
|
||||
actionButton.addListener(UnitActionButtonOnHoverListener(actionButton, keyLabel))
|
||||
}
|
||||
actionButton.pack()
|
||||
actionButton.onClick(unitAction.uncivSound) {
|
||||
val action = {
|
||||
unitAction.action?.invoke()
|
||||
UncivGame.Current.worldScreen.shouldUpdate=true
|
||||
UncivGame.Current.worldScreen.shouldUpdate = true
|
||||
}
|
||||
if (unitAction.action == null) actionButton.disable()
|
||||
else {
|
||||
actionButton.onClick(unitAction.uncivSound,action)
|
||||
if (iconAndKey.key != 0.toChar())
|
||||
worldScreen.keyPressDispatcher[iconAndKey.key] = action
|
||||
}
|
||||
|
||||
return actionButton
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue