Unit rename UI (#4804)

* Rework Yes/No and OK/Close

* Apply Yes/No and OK/Close constants

* Clean up and decorate RenameUnitPopup
This commit is contained in:
SomeTroglodyte 2021-08-09 12:59:30 +02:00 committed by GitHub
parent 6d04bf424b
commit e59db3ada3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 74 additions and 35 deletions

View File

@ -67,9 +67,12 @@ object Constants {
const val cancelImprovementOrder = "Cancel improvement order"
const val tutorialPopupNamePrefix = "Tutorial: "
const val OK = "OK"
const val close = "Close"
const val disabled = "disabled"
const val yes = "Yes"
const val no = "No"
const val enabled = "enabled"
const val disabled = "disabled"
const val barbarians = "Barbarians"
const val spectator = "Spectator"

View File

@ -185,7 +185,7 @@ class MainMenuScreen: CameraStageBaseScreen() {
add(loadMapButton).row()
keyPressDispatcher['l'] = loadMapAction
add(screen.getMenuButton("Close", "OtherIcons/Close") { close() }
add(screen.getMenuButton(Constants.close, "OtherIcons/Close") { close() }
.apply { background=tableBackground })
keyPressDispatcher[KeyCharAndCode.BACK] = { close() }

View File

@ -1,5 +1,6 @@
package com.unciv.ui.mapeditor
import com.unciv.Constants
import com.unciv.UncivGame
import com.unciv.models.ruleset.RulesetCache
import com.unciv.models.translations.tr
@ -30,7 +31,7 @@ class GameParametersScreen(var mapEditorScreen: MapEditorScreen): IPreviousScree
.maxHeight(topTable.parent.height).width(stage.width / 2).padTop(20f).top()
topTable.addSeparatorVertical()
topTable.add(playerPickerTable).maxHeight(topTable.parent.height).width(stage.width / 2).padTop(20f).top()
rightSideButton.setText("OK".tr())
rightSideButton.setText(Constants.OK.tr())
rightSideButton.onClick {
mapEditorScreen.gameSetupInfo = gameSetupInfo
mapEditorScreen.ruleset.clear()

View File

@ -3,6 +3,7 @@ package com.unciv.ui.mapeditor
import com.badlogic.gdx.Gdx
import com.badlogic.gdx.scenes.scene2d.ui.ScrollPane
import com.badlogic.gdx.scenes.scene2d.ui.Table
import com.unciv.Constants
import com.unciv.MainMenuScreen
import com.unciv.UncivGame
import com.unciv.models.ruleset.RulesetCache
@ -64,13 +65,14 @@ class MapEditorMenuPopup(var mapEditorScreen: MapEditorScreen): Popup(mapEditorS
add(ScrollPane(incompatibilityTable)).colspan(2)
.maxHeight(screen.stage.height * 0.8f).row()
add("Change map to fit selected ruleset?".toLabel()).colspan(2).row()
addButtonInRow("Yes", 'y') {
addButtonInRow(Constants.yes, 'y') {
for (tile in mapEditorScreen.tileMap.values)
tile.normalizeToRuleset(ruleset)
mapEditorScreen.tileMap.mapParameters.mods = mods
mapEditorScreen.game.setScreen(MapEditorScreen(mapEditorScreen.tileMap))
}
addButtonInRow("No", 'n') { close() }
addButtonInRow(Constants.no, 'n') { close() }
equalizeLastTwoButtonWidths()
}.open(true)
}

View File

@ -1,33 +1,32 @@
package com.unciv.ui.pickerscreens
import com.badlogic.gdx.scenes.scene2d.ui.Table
import com.badlogic.gdx.scenes.scene2d.ui.TextField
import com.unciv.logic.map.MapUnit
import com.unciv.ui.utils.CameraStageBaseScreen
import com.unciv.ui.utils.Popup
import com.unciv.ui.utils.onClick
import com.unciv.ui.utils.toTextButton
import com.unciv.ui.utils.*
class RenameUnitPopup(unit: MapUnit, screen: CameraStageBaseScreen): Popup(screen) {
init {
addGoodSizedLabel("Choose name for [${unit.baseUnit.name}]").row()
val wrapper = Table()
wrapper.add(ImageGetter.getUnitIcon(unit.name).surroundWithCircle(80f)).padRight(10f)
wrapper.add("Choose name for [${unit.baseUnit.name}]".toLabel())
add(wrapper).colspan(2).row()
val nameField = TextField("", skin)
// Disallowed special characters determined with US keyboard and a certain binary
// copyrighted by Firaxis Games
val illegal_chars = "%*[]\"\\|<>/?"
nameField.textFieldFilter = TextField.TextFieldFilter { _, char -> !(char in illegal_chars)}
// Max name length decided arbitrarily
nameField.maxLength = 10
add(nameField)
row()
add("OK".toTextButton().onClick {
if (nameField.text != "") {
// Disallowed special characters - used by tr() or simply precaution
val illegalChars = "[]{}\"\\<>"
nameField.textFieldFilter = TextField.TextFieldFilter { _, char -> char !in illegalChars}
nameField.maxLength = unit.civInfo.gameInfo.ruleSet.units.values.maxOf { it.name.length }
add(nameField).growX().colspan(2).row()
addOKButton {
if (nameField.text != "" && nameField.text != unit.name) {
unit.instanceName = nameField.text
}
screen.game.setScreen(PromotionPickerScreen(unit))
})
add("Close".toTextButton().onClick { close() })
}
addCloseButton()
equalizeLastTwoButtonWidths()
keyboardFocus = nameField
}
}

View File

@ -51,9 +51,13 @@ data class KeyCharAndCode(val char: Char, val code: Int) {
companion object {
// Convenience shortcuts for frequently used constants
/** Android back, assigns ESC automatically as well */
val BACK = KeyCharAndCode(Input.Keys.BACK)
/** Automatically assigned for [BACK] */
val ESC = KeyCharAndCode(Input.Keys.ESCAPE)
/** Assigns [NUMPAD_ENTER] automatically as well */
val RETURN = KeyCharAndCode(Input.Keys.ENTER)
/** Automatically assigned for [RETURN] */
val NUMPAD_ENTER = KeyCharAndCode(Input.Keys.NUMPAD_ENTER)
val SPACE = KeyCharAndCode(Input.Keys.SPACE)
val BACKSPACE= KeyCharAndCode(Input.Keys.BACKSPACE)

View File

@ -78,7 +78,7 @@ open class Popup(val screen: CameraStageBaseScreen): Table(CameraStageBaseScreen
/**
* Adds a [caption][text] label: A label with word wrap enabled over half the stage width.
* Will be larger than normal text if the [size] parameter is set to >18f.
* Will be larger than normal text if the [size] parameter is set to >18.
* @param text The caption text.
* @param size The font size for the label.
*/
@ -97,7 +97,7 @@ open class Popup(val screen: CameraStageBaseScreen): Table(CameraStageBaseScreen
* @return The new [Cell]
*/
fun addButtonInRow(text: String, key: KeyCharAndCode? = null, action: () -> Unit): Cell<TextButton> {
val button = text.toTextButton().apply { color = ImageGetter.getBlue() }
val button = text.toTextButton()
button.onClick(action)
if (key != null) {
keyPressDispatcher[key] = action
@ -125,11 +125,11 @@ open class Popup(val screen: CameraStageBaseScreen): Table(CameraStageBaseScreen
= addButtonInRow(text, key, action).apply { row() }
/**
* Adds a [TextButton] that closes the popup.
* Adds a [TextButton] that closes the popup, with [BACK][KeyCharAndCode.BACK] already mapped.
* @param text The button's caption, defaults to "Close".
* @param additionalKey An additional key that should close the popup, Back and ESC are assigned by default.
* @param additionalKey An additional key that should act like a click.
* @param action A lambda to be executed after closing the popup when the button is clicked.
* @return The new [Cell]
* @return The new [Cell], marked as end of row.
*/
fun addCloseButton(
text: String = Constants.close,
@ -141,6 +141,37 @@ open class Popup(val screen: CameraStageBaseScreen): Table(CameraStageBaseScreen
return addButton(text, additionalKey, closeAction)
}
/**
* Adds a [TextButton] that closes the popup, with [RETURN][KeyCharAndCode.RETURN] already mapped.
* @param text The button's caption, defaults to "OK".
* @param additionalKey An additional key that should act like a click.
* @param action A lambda to be executed after closing the popup when the button is clicked.
* @return The new [Cell], NOT marked as end of row.
*/
fun addOKButton(
text: String = Constants.OK,
additionalKey: KeyCharAndCode? = null,
action: (()->Unit)
): Cell<TextButton> {
val okAction = { close(); action() }
keyPressDispatcher[KeyCharAndCode.RETURN] = okAction
return addButtonInRow(text, additionalKey, okAction)
}
/**
* The last two additions ***must*** be buttons.
* Make their width equal by setting minWidth of one cell to actor width of the other.
*/
fun equalizeLastTwoButtonWidths() {
val n = innerTable.cells.size
if (n < 2) throw UnsupportedOperationException()
val cell1 = innerTable.cells[n-2]
val cell2 = innerTable.cells[n-1]
if (cell1.actor !is Button || cell2.actor !is Button) throw UnsupportedOperationException()
cell1.minWidth(cell2.actor.width)
cell2.minWidth(cell1.actor.width)
}
/**
* Sets or retrieves the [Actor] that currently has keyboard focus.
*

View File

@ -1,6 +1,7 @@
package com.unciv.ui.utils
import com.badlogic.gdx.Gdx
import com.unciv.Constants
import com.unciv.UncivGame
/** Variant of [Popup] pre-populated with one label, plus yes and no buttons
@ -15,15 +16,12 @@ open class YesNoPopup (
screen: CameraStageBaseScreen = UncivGame.Current.worldScreen,
restoreDefault:()->Unit = {}
) : Popup(screen) {
private val yes = { close(); action() }
private val no = { close(); restoreDefault() }
init {
add(question.toLabel()).colspan(2).row()
addButtonInRow("Yes", 'y', yes)
addButtonInRow("No", 'n', no)
keyPressDispatcher[KeyCharAndCode.RETURN] = yes
keyPressDispatcher[KeyCharAndCode.BACK] = no
addOKButton(Constants.yes, KeyCharAndCode('y'), action)
addCloseButton(Constants.no, KeyCharAndCode('n'), restoreDefault)
equalizeLastTwoButtonWidths()
}
}

View File

@ -5,6 +5,7 @@ import com.badlogic.gdx.Gdx
import com.badlogic.gdx.Input
import com.badlogic.gdx.graphics.Color
import com.badlogic.gdx.scenes.scene2d.ui.*
import com.unciv.Constants
import com.unciv.MainMenuScreen
import com.unciv.logic.civilization.PlayerType
import com.unciv.models.UncivSound
@ -455,7 +456,7 @@ class OptionsPopup(val previousScreen:CameraStageBaseScreen) : Popup(previousScr
Usage: YesNoButton(someSetting: Boolean, skin) { someSetting = it; sideEffects() }
*/
private fun Boolean.toYesNo(): String = (if (this) "Yes" else "No").tr()
private fun Boolean.toYesNo(): String = (if (this) Constants.yes else Constants.no).tr()
private class YesNoButton(initialValue: Boolean, skin: Skin, action: (Boolean) -> Unit)
: TextButton (initialValue.toYesNo(), skin ) {