mirror of
https://github.com/yairm210/Unciv.git
synced 2025-09-24 03:53:12 -04:00
Move parsing of localized numbers to UncivTextField (#13550)
* Move parsing of localized numbers to UncivTextField * Docs!
This commit is contained in:
parent
0846b6d486
commit
02d3c110aa
@ -12,7 +12,6 @@ import com.unciv.ui.components.fonts.DiacriticSupport
|
||||
import com.unciv.ui.components.fonts.FontRulesetIcons
|
||||
import com.unciv.utils.Log
|
||||
import com.unciv.utils.debug
|
||||
import java.text.ParseException
|
||||
import java.util.Locale
|
||||
import org.jetbrains.annotations.VisibleForTesting
|
||||
|
||||
@ -544,44 +543,22 @@ fun String.removeConditionals(): String {
|
||||
.trim()
|
||||
}
|
||||
|
||||
// formats number according to current language
|
||||
/** Formats number according to current language
|
||||
*
|
||||
* Note: The inverse operation is UncivGame.Current.settings.getCurrentNumberFormat().parse(string), handled in the [UncivTextField.Numeric][com.unciv.ui.components.widgets.UncivTextField.Numeric] widget.
|
||||
*
|
||||
* @return locale-dependent String representation of receiver, may contain formatting like thousands separators
|
||||
*/
|
||||
fun Number.tr(): String {
|
||||
return UncivGame.Current.settings.getCurrentNumberFormat().format(this)
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the string as an integer using the current number format.
|
||||
/** Formats number according to a specific [language]
|
||||
*
|
||||
* Empty strings result in 0.
|
||||
* Note: The inverse operation is `LocaleCode.getNumberFormatFromLanguage(language).parse(string)`.
|
||||
*
|
||||
* @return The integer value, or null if parsing fails.
|
||||
* @return locale-dependent String representation of receiver, may contain formatting like thousands separators
|
||||
*/
|
||||
fun String.toIntOrNullTranslated(): Int? {
|
||||
if (isEmpty()) return 0
|
||||
return try {
|
||||
UncivGame.Current.settings.getCurrentNumberFormat().parse(this).toInt()
|
||||
} catch (_: ParseException) {
|
||||
this.toIntOrNull()
|
||||
}
|
||||
}
|
||||
|
||||
// formats number according to given language
|
||||
fun Number.tr(language: String): String {
|
||||
return LocaleCode.getNumberFormatFromLanguage(language).format(this)
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the string as an integer using the current number format.
|
||||
*
|
||||
* Empty strings result in 0.
|
||||
*
|
||||
* @return The integer value, or null if parsing fails.
|
||||
*/
|
||||
fun String.toIntOrNullTranslated(language: String): Int? {
|
||||
if (isEmpty()) return 0
|
||||
return try {
|
||||
LocaleCode.getNumberFormatFromLanguage(language).parse(this).toInt()
|
||||
} catch (_: ParseException) {
|
||||
this.toIntOrNull()
|
||||
}
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ import com.badlogic.gdx.scenes.scene2d.ui.ScrollPane
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.TextField
|
||||
import com.badlogic.gdx.scenes.scene2d.utils.FocusListener
|
||||
import com.unciv.Constants
|
||||
import com.unciv.UncivGame
|
||||
import com.unciv.logic.event.EventBus
|
||||
import com.unciv.models.translations.tr
|
||||
import com.unciv.ui.components.extensions.getAscendant
|
||||
@ -22,6 +23,7 @@ import com.unciv.ui.screens.basescreen.BaseScreen
|
||||
import com.unciv.ui.screens.basescreen.UncivStage
|
||||
import com.unciv.utils.Concurrency
|
||||
import com.unciv.utils.withGLContext
|
||||
import java.text.ParseException
|
||||
import kotlinx.coroutines.delay
|
||||
|
||||
/**
|
||||
@ -38,7 +40,7 @@ import kotlinx.coroutines.delay
|
||||
* @param onFocusChange a callback that will be notified when this TextField loses or gains the [keyboardFocus][com.badlogic.gdx.scenes.scene2d.Stage.keyboardFocus].
|
||||
* Receiver is the field, so you can simply use its elements. Parameter `it` is a Boolean indicating focus was received.
|
||||
*/
|
||||
class UncivTextField(
|
||||
open class UncivTextField(
|
||||
hint: String,
|
||||
preEnteredText: String = "",
|
||||
private val onFocusChange: (TextField.(Boolean) -> Unit)? = null
|
||||
@ -49,9 +51,9 @@ class UncivTextField(
|
||||
init {
|
||||
messageText = hint.tr()
|
||||
|
||||
addListener(UncivTextFieldFocusListener())
|
||||
this.addListener(UncivTextFieldFocusListener())
|
||||
|
||||
if (isAndroid) addListener(VisibleAreaChangedListener())
|
||||
if (isAndroid) this.addListener(VisibleAreaChangedListener())
|
||||
}
|
||||
|
||||
private inner class UncivTextFieldFocusListener : FocusListener() {
|
||||
@ -188,4 +190,66 @@ class UncivTextField(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Specialization of [UncivTextField] for numbers. See its documentation for improvements over [TextField].
|
||||
* - Note: It uses the generic [Number] class and thus supports both floating-point and integer as input.
|
||||
* You might need a conversion when retrieving the result.
|
||||
* - Note: [maxLength] is set to 26, but you can change it later.
|
||||
* - Limitation: Depending on Java's decisions for your locale, the displayed string will likely contain thousands separators.
|
||||
* These are ignored when parsing!
|
||||
* However, user input will not update them, fix misplaced ones, or add them to pasted numbers.
|
||||
*
|
||||
* @property value Gets/sets the [text], using localized formatting according to the language chosen in the settings, in both directions.
|
||||
* Note null is allowed and represents an empty text field.
|
||||
* @property setText Forbidden, use [value] instead.
|
||||
* @param hint See [UncivTextField].
|
||||
* @param initialValue Sets the initial [value] without triggering a `ChangeEvent.`
|
||||
* @param integerOnly Limits allowed characters and tells the parser to look for integers only.
|
||||
* @param onFocusChange See [UncivTextField].
|
||||
*/
|
||||
open class Numeric(
|
||||
hint: String,
|
||||
initialValue: Number?,
|
||||
integerOnly: Boolean = false,
|
||||
onFocusChange: (TextField.(Boolean) -> Unit)? = null
|
||||
) : UncivTextField(hint, initialValue?.tr() ?: "", onFocusChange) {
|
||||
private val formatter = UncivGame.Current.settings.getCurrentNumberFormat()
|
||||
private val symbols = formatter.format(if (integerOnly) -9999 else -9999.9).filter { !it.isDigit() }
|
||||
init {
|
||||
textFieldFilter = TextFieldFilter { _, c -> c.isDigit() || c in symbols }
|
||||
formatter.isParseIntegerOnly = integerOnly
|
||||
maxLength = 26 // enough for signed int64 including thousands separators - floating point shouldn't need more.
|
||||
}
|
||||
open var value: Number?
|
||||
get() = try {
|
||||
formatter.parse(text)
|
||||
} catch (_: ParseException) {
|
||||
null
|
||||
}
|
||||
set(value) { super.text = value?.tr() ?: "" }
|
||||
|
||||
// Enlist compiler to make sure no-one calls this *from our project*
|
||||
@Deprecated("Don't assign `text` on a numeric UncivTextField!", ReplaceWith("value"), DeprecationLevel.ERROR)
|
||||
// But: Gdx is leaking `this` and calls this override from its constructor, therefore don't throw.
|
||||
override fun setText(str: String?) = super.setText(str)
|
||||
}
|
||||
|
||||
/**
|
||||
* Specialization of [UncivTextField.Numeric] for 32-bit integers. Do read its Kdoc.
|
||||
* - maxLength is reduced to 14 accommodating the largest negative 32-bit integer with thousands separators.
|
||||
* @property intValue please prefer this over [value], it's easier!
|
||||
*/
|
||||
class Integer (
|
||||
hint: String,
|
||||
initialValue: Int?,
|
||||
onFocusChange: (TextField.(Boolean) -> Unit)? = null
|
||||
) : Numeric(hint, initialValue, integerOnly = true, onFocusChange) {
|
||||
init {
|
||||
maxLength = 14
|
||||
}
|
||||
var intValue: Int?
|
||||
get() = value?.toInt()
|
||||
set(value) { this.value = value }
|
||||
}
|
||||
}
|
||||
|
@ -3,9 +3,6 @@ package com.unciv.ui.popups
|
||||
import com.badlogic.gdx.graphics.Color
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Button
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Table
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.TextField
|
||||
import com.unciv.models.translations.toIntOrNullTranslated
|
||||
import com.unciv.models.translations.tr
|
||||
import com.unciv.ui.components.widgets.UncivTextField
|
||||
import com.unciv.ui.components.input.onChange
|
||||
import com.unciv.ui.components.input.onClick
|
||||
@ -32,71 +29,48 @@ class AskNumberPopup(
|
||||
screen: BaseScreen,
|
||||
label: String = "Please enter a number",
|
||||
icon: IconCircleGroup = ImageGetter.getImage("OtherIcons/Pencil").apply { this.color = ImageGetter.CHARCOAL }.surroundWithCircle(80f),
|
||||
defaultValue: String = "",
|
||||
defaultValue: Int? = null,
|
||||
amountButtons: List<Int> = listOf(),
|
||||
bounds: IntRange = IntRange(Int.MIN_VALUE, Int.MAX_VALUE),
|
||||
errorText: String = "Invalid input! Please enter a valid number.",
|
||||
validate: (input: Int) -> Boolean = { true },
|
||||
actionOnOk: (input: Int) -> Unit = { },
|
||||
): Popup(screen) {
|
||||
/** Note for future developers: Why this class only accepts positive digits and not negative.
|
||||
*
|
||||
* The problems is the minus sign. This might not seem like a large obstacle, but problems
|
||||
* arrive quickly. First is that our clean `DigitsOnlyFilter()` must be replaced with a check
|
||||
* that allows for adding a minus sign, but only when it is the first character. So far so good,
|
||||
* until a user starts typing numbers before an already placed - sign --> crash. Fix that
|
||||
* by disallowing any character being typed in front of a - sign. All is fixed right? Wrong!
|
||||
* Because you now also disallowed writing two minus signs at the same time, copying over a
|
||||
* new number after clamping now disallows overwriting the existing minus sign with a new minus
|
||||
* sign, as there is already a minus sign in the number. Well, no problem, you can just remove
|
||||
* the number before overwriting it with the clamped variant. But now you reset your cursor
|
||||
* position every time you type a character. You might start trying to cache the cursor position
|
||||
* as well, but at that point you're basically rewriting the setText() function, and when I
|
||||
* reached this point I decided to stop.
|
||||
*
|
||||
* P.S., if you do decide to go on this quest of adding minus signs, don't forget that
|
||||
* `"-".toInt()` also crashes, so you need to exclude that before checking to clamp.
|
||||
*/
|
||||
|
||||
init {
|
||||
val wrapper = Table()
|
||||
wrapper.add(icon).padRight(10f)
|
||||
wrapper.add(label.toLabel())
|
||||
add(wrapper).colspan(2).row()
|
||||
|
||||
val nameField = UncivTextField(label, defaultValue)
|
||||
nameField.textFieldFilter = TextField.TextFieldFilter { _, char -> char.isDigit() || char == '-' }
|
||||
val nameField = UncivTextField.Integer(label, defaultValue)
|
||||
|
||||
fun isValidInt(input: String): Boolean = input.toIntOrNullTranslated() != null
|
||||
fun getInt(input: String): Int? = input.toIntOrNullTranslated()
|
||||
fun clampInBounds(input: Int?): Int? {
|
||||
if (input == null) return null
|
||||
|
||||
fun clampInBounds(input: String): String {
|
||||
val int = getInt(input) ?: return input
|
||||
|
||||
if (bounds.first > int) {
|
||||
return bounds.first.tr()
|
||||
if (bounds.first > input) {
|
||||
return bounds.first
|
||||
}
|
||||
if (bounds.last < int)
|
||||
return bounds.last.tr()
|
||||
if (bounds.last < input)
|
||||
return bounds.last
|
||||
|
||||
return input
|
||||
}
|
||||
|
||||
nameField.onChange {
|
||||
nameField.text = clampInBounds(nameField.text)
|
||||
nameField.intValue = clampInBounds(nameField.intValue)
|
||||
}
|
||||
|
||||
val centerTable = Table(skin)
|
||||
|
||||
fun addValueButton(value: Int) {
|
||||
fun addValueButton(delta: Int) {
|
||||
centerTable.add(
|
||||
Button(
|
||||
value.toStringSigned().toLabel(),
|
||||
delta.toStringSigned().toLabel(),
|
||||
skin
|
||||
).apply {
|
||||
onClick {
|
||||
if (isValidInt(nameField.text))
|
||||
nameField.text = clampInBounds((getInt(nameField.text)!! + value).tr())
|
||||
val value = nameField.intValue ?: return@onClick
|
||||
nameField.intValue = value + delta
|
||||
}
|
||||
}
|
||||
).pad(5f)
|
||||
@ -120,12 +94,12 @@ class AskNumberPopup(
|
||||
addCloseButton()
|
||||
addOKButton(
|
||||
validate = {
|
||||
val errorFound = getInt(nameField.text)?.let { validate(it) } != true
|
||||
val errorFound = nameField.intValue?.let { validate(it) } != true
|
||||
if (errorFound) add(errorLabel).colspan(2).center()
|
||||
!errorFound
|
||||
}
|
||||
) {
|
||||
actionOnOk(getInt(nameField.text)!!)
|
||||
actionOnOk(nameField.intValue!!)
|
||||
}
|
||||
equalizeLastTwoButtonWidths()
|
||||
|
||||
|
@ -10,7 +10,6 @@ import com.unciv.logic.files.MapSaver
|
||||
import com.unciv.logic.files.UncivFiles
|
||||
import com.unciv.models.ruleset.RulesetCache
|
||||
import com.unciv.models.ruleset.tile.ResourceType
|
||||
import com.unciv.models.translations.tr
|
||||
import com.unciv.ui.components.widgets.UncivTextField
|
||||
import com.unciv.ui.components.extensions.addSeparator
|
||||
import com.unciv.ui.components.extensions.toCheckBox
|
||||
@ -32,10 +31,10 @@ fun debugTab(
|
||||
|
||||
if (GUI.isWorldLoaded()) {
|
||||
val simulateButton = "Simulate until turn:".toTextButton()
|
||||
val simulateTextField = UncivTextField("Turn", DebugUtils.SIMULATE_UNTIL_TURN.tr())
|
||||
val simulateTextField = UncivTextField.Numeric("Turn", DebugUtils.SIMULATE_UNTIL_TURN, integerOnly = true)
|
||||
val invalidInputLabel = "This is not a valid integer!".toLabel().also { it.isVisible = false }
|
||||
simulateButton.onClick {
|
||||
val simulateUntilTurns = simulateTextField.text.toIntOrNull()
|
||||
val simulateUntilTurns = simulateTextField.value?.toInt()
|
||||
if (simulateUntilTurns == null) {
|
||||
invalidInputLabel.isVisible = true
|
||||
return@onClick
|
||||
|
@ -120,7 +120,7 @@ class OfferColumnsTable(
|
||||
screen,
|
||||
label = "Enter the amount of gold",
|
||||
icon = ImageGetter.getStatIcon("Gold").surroundWithCircle(80f),
|
||||
defaultValue = offer.amount.tr(),
|
||||
defaultValue = offer.amount,
|
||||
amountButtons =
|
||||
if (offer.type == TradeOfferType.Gold) listOf(50, 500)
|
||||
else listOf(5, 15),
|
||||
|
@ -73,9 +73,9 @@ class MapEditorGenerateTab(
|
||||
Concurrency.runOnGLThread {
|
||||
ToastPopup( message, editorScreen, 4000 )
|
||||
newTab.mapParametersTable.run { mapParameters.mapSize.also {
|
||||
customMapSizeRadius.text = it.radius.tr()
|
||||
customMapWidth.text = it.width.tr()
|
||||
customMapHeight.text = it.height.tr()
|
||||
customMapSizeRadius.intValue = it.radius
|
||||
customMapWidth.intValue = it.width
|
||||
customMapHeight.intValue = it.height
|
||||
} }
|
||||
}
|
||||
return
|
||||
@ -196,7 +196,7 @@ class MapEditorGenerateTab(
|
||||
defaults().pad(2.5f)
|
||||
add("Generator steps".toLabel(fontSize = 24)).row()
|
||||
optionGroup.setMinCheckCount(0)
|
||||
for (option in MapGeneratorSteps.values()) {
|
||||
for (option in MapGeneratorSteps.entries) {
|
||||
if (option <= MapGeneratorSteps.All) continue
|
||||
val checkBox = option.label.toCheckBox {
|
||||
choice = option
|
||||
|
@ -3,8 +3,6 @@ package com.unciv.ui.screens.newgamescreen
|
||||
import com.badlogic.gdx.graphics.Color
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.CheckBox
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Table
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.TextField
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.TextField.TextFieldFilter.DigitsOnlyFilter
|
||||
import com.badlogic.gdx.utils.Align
|
||||
import com.unciv.UncivGame
|
||||
import com.unciv.logic.map.*
|
||||
@ -12,7 +10,6 @@ import com.unciv.logic.map.mapgenerator.MapGenerator
|
||||
import com.unciv.logic.map.mapgenerator.MapResourceSetting
|
||||
import com.unciv.models.metadata.GameParameters
|
||||
import com.unciv.models.ruleset.RulesetCache
|
||||
import com.unciv.models.translations.tr
|
||||
import com.unciv.ui.components.extensions.*
|
||||
import com.unciv.ui.components.input.onChange
|
||||
import com.unciv.ui.components.input.onClick
|
||||
@ -34,12 +31,12 @@ class MapParametersTable(
|
||||
private val forMapEditor: Boolean = false,
|
||||
private val sizeChangedCallback: (()->Unit)? = null
|
||||
) : Table() {
|
||||
// These are accessed fom outside the class to read _and_ write values,
|
||||
// These are accessed from outside the class to read _and_ write values,
|
||||
// namely from MapOptionsTable, NewMapScreen and NewGameScreen
|
||||
lateinit var mapTypeSelectBox: TranslatedSelectBox
|
||||
lateinit var customMapSizeRadius: TextField
|
||||
lateinit var customMapWidth: TextField
|
||||
lateinit var customMapHeight: TextField
|
||||
lateinit var customMapSizeRadius: UncivTextField.Integer
|
||||
lateinit var customMapWidth: UncivTextField.Integer
|
||||
lateinit var customMapHeight: UncivTextField.Integer
|
||||
|
||||
private lateinit var worldSizeSelectBox: TranslatedSelectBox
|
||||
private var customWorldSizeTable = Table()
|
||||
@ -51,13 +48,13 @@ class MapParametersTable(
|
||||
private lateinit var worldWrapCheckbox: CheckBox
|
||||
private lateinit var legendaryStartCheckbox: CheckBox
|
||||
private lateinit var strategicBalanceCheckbox: CheckBox
|
||||
private lateinit var seedTextField: TextField
|
||||
private lateinit var seedTextField: UncivTextField.Numeric
|
||||
|
||||
private lateinit var mapShapesOptionsValues: HashSet<String>
|
||||
private lateinit var mapTypesOptionsValues: HashSet<String>
|
||||
private lateinit var mapSizesOptionsValues: HashSet<String>
|
||||
private lateinit var mapResourcesOptionsValues: HashSet<String>
|
||||
|
||||
|
||||
private val maxMapSize = ((previousScreen as? NewGameScreen)?.getColumnWidth() ?: 200f) - 10f // There is 5px padding each side
|
||||
private val mapTypeExample = Table()
|
||||
|
||||
@ -98,7 +95,7 @@ class MapParametersTable(
|
||||
|
||||
fun reseed() {
|
||||
mapParameters.reseed()
|
||||
seedTextField.text = mapParameters.seed.tr()
|
||||
seedTextField.value = mapParameters.seed
|
||||
}
|
||||
|
||||
private fun addMapShapeSelectBox() {
|
||||
@ -131,7 +128,7 @@ class MapParametersTable(
|
||||
add(mapShapeSelectBox).fillX().row()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private fun generateExampleMap(){
|
||||
val ruleset = if (previousScreen is NewGameScreen) previousScreen.ruleset else RulesetCache.getVanillaRuleset()
|
||||
Concurrency.run("Generate example map") {
|
||||
@ -181,7 +178,7 @@ class MapParametersTable(
|
||||
add(optionsTable).colspan(2).grow().row()
|
||||
} else {
|
||||
mapTypeSelectBox = TranslatedSelectBox(mapTypes, mapParameters.type)
|
||||
|
||||
|
||||
|
||||
mapTypeSelectBox.onChange {
|
||||
mapParameters.type = mapTypeSelectBox.selected.value
|
||||
@ -189,7 +186,7 @@ class MapParametersTable(
|
||||
// If the map won't be generated, these options are irrelevant and are hidden
|
||||
noRuinsCheckbox.isVisible = mapParameters.type != MapType.empty
|
||||
noNaturalWondersCheckbox.isVisible = mapParameters.type != MapType.empty
|
||||
|
||||
|
||||
generateExampleMap()
|
||||
}
|
||||
|
||||
@ -228,12 +225,10 @@ class MapParametersTable(
|
||||
}
|
||||
|
||||
private fun addHexagonalSizeTable() {
|
||||
val defaultRadius = mapParameters.mapSize.radius.tr()
|
||||
customMapSizeRadius = UncivTextField("Radius", defaultRadius).apply {
|
||||
textFieldFilter = DigitsOnlyFilter()
|
||||
}
|
||||
val defaultRadius = mapParameters.mapSize.radius
|
||||
customMapSizeRadius = UncivTextField.Integer("Radius", defaultRadius)
|
||||
customMapSizeRadius.onChange {
|
||||
mapParameters.mapSize = MapSize(customMapSizeRadius.text.toIntOrNull() ?: 0 )
|
||||
mapParameters.mapSize = MapSize(customMapSizeRadius.intValue ?: 0 )
|
||||
}
|
||||
hexagonalSizeTable.add("{Radius}:".toLabel()).grow().left()
|
||||
hexagonalSizeTable.add(customMapSizeRadius).right().row()
|
||||
@ -242,21 +237,16 @@ class MapParametersTable(
|
||||
}
|
||||
|
||||
private fun addRectangularSizeTable() {
|
||||
val defaultWidth = mapParameters.mapSize.width.tr()
|
||||
customMapWidth = UncivTextField("Width", defaultWidth).apply {
|
||||
textFieldFilter = DigitsOnlyFilter()
|
||||
}
|
||||
|
||||
val defaultHeight = mapParameters.mapSize.height.tr()
|
||||
customMapHeight = UncivTextField("Height", defaultHeight).apply {
|
||||
textFieldFilter = DigitsOnlyFilter()
|
||||
}
|
||||
val defaultWidth = mapParameters.mapSize.width
|
||||
customMapWidth = UncivTextField.Integer("Width", defaultWidth)
|
||||
val defaultHeight = mapParameters.mapSize.height
|
||||
customMapHeight = UncivTextField.Integer("Height", defaultHeight)
|
||||
|
||||
customMapWidth.onChange {
|
||||
mapParameters.mapSize = MapSize(customMapWidth.text.toIntOrNull() ?: 0, customMapHeight.text.toIntOrNull() ?: 0)
|
||||
mapParameters.mapSize = MapSize(customMapWidth.intValue ?: 0, customMapHeight.intValue ?: 0)
|
||||
}
|
||||
customMapHeight.onChange {
|
||||
mapParameters.mapSize = MapSize(customMapWidth.text.toIntOrNull() ?: 0, customMapHeight.text.toIntOrNull() ?: 0)
|
||||
mapParameters.mapSize = MapSize(customMapWidth.intValue ?: 0, customMapHeight.intValue ?: 0)
|
||||
}
|
||||
|
||||
rectangularSizeTable.defaults().pad(5f)
|
||||
@ -384,16 +374,10 @@ class MapParametersTable(
|
||||
private fun addAdvancedControls(table: Table) {
|
||||
table.defaults().pad(2f).padTop(10f)
|
||||
|
||||
seedTextField = UncivTextField("RNG Seed", mapParameters.seed.tr())
|
||||
seedTextField.textFieldFilter = DigitsOnlyFilter()
|
||||
seedTextField = UncivTextField.Numeric("RNG Seed", mapParameters.seed, integerOnly = true)
|
||||
|
||||
// If the field is empty, fallback seed value to 0
|
||||
seedTextField.onChange {
|
||||
mapParameters.seed = try {
|
||||
seedTextField.text.toLong()
|
||||
} catch (_: Exception) {
|
||||
0L
|
||||
}
|
||||
mapParameters.seed = seedTextField.value?.toLong() ?: 0L
|
||||
}
|
||||
|
||||
table.add("RNG Seed".toLabel()).left()
|
||||
@ -464,7 +448,7 @@ class MapParametersTable(
|
||||
|
||||
addTextButton("Reset to defaults", true) {
|
||||
mapParameters.resetAdvancedSettings()
|
||||
seedTextField.text = mapParameters.seed.tr()
|
||||
seedTextField.value = mapParameters.seed
|
||||
for (entry in advancedSliders)
|
||||
entry.key.value = entry.value()
|
||||
}
|
||||
|
@ -193,9 +193,9 @@ class NewGameScreen(
|
||||
val message = mapSize.fixUndesiredSizes(gameSetupInfo.mapParameters.worldWrap)
|
||||
if (message != null) {
|
||||
with (mapOptionsTable.generatedMapOptionsTable) {
|
||||
customMapSizeRadius.text = mapSize.radius.tr()
|
||||
customMapWidth.text = mapSize.width.tr()
|
||||
customMapHeight.text = mapSize.height.tr()
|
||||
customMapSizeRadius.intValue = mapSize.radius
|
||||
customMapWidth.intValue = mapSize.width
|
||||
customMapHeight.intValue = mapSize.height
|
||||
}
|
||||
return message
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user