Rework options UI (#2367)
* Bring Incas into the main game (also changes slinger withdraw ability to inheritable) * Update Nations.json * Reworked Options Menu: Clarity, No Scroll jump, less repaints * Reworked Options Menu: Minor cosmetic change * Reworked Options Menu: Removed test code
This commit is contained in:
parent
25a5559969
commit
323613ba02
1 changed files with 151 additions and 165 deletions
|
@ -24,133 +24,125 @@ class Language(val language:String, val percentComplete:Int){
|
|||
|
||||
class WorldScreenOptionsPopup(val worldScreen:WorldScreen) : Popup(worldScreen) {
|
||||
var selectedLanguage: String = "English"
|
||||
private val settings = UncivGame.Current.settings
|
||||
private val innerTable = Table(CameraStageBaseScreen.skin)
|
||||
|
||||
init {
|
||||
UncivGame.Current.settings.addCompletedTutorialTask("Open the options table")
|
||||
update()
|
||||
settings.addCompletedTutorialTask("Open the options table")
|
||||
|
||||
rebuildInnerTable()
|
||||
|
||||
val scrollPane = ScrollPane(innerTable, skin)
|
||||
scrollPane.setOverscroll(false, false)
|
||||
scrollPane.fadeScrollBars = false
|
||||
scrollPane.setScrollingDisabled(true, false)
|
||||
add(scrollPane).maxHeight(screen.stage.height * 0.6f).row()
|
||||
|
||||
addCloseButton()
|
||||
|
||||
pack() // Needed to show the background.
|
||||
center(UncivGame.Current.worldScreen.stage)
|
||||
}
|
||||
|
||||
private fun addHeader (text: String) {
|
||||
innerTable.add(text.toLabel(fontSize = 24)).colspan(2).padTop(if (innerTable.cells.isEmpty) 0f else 20f).row()
|
||||
}
|
||||
|
||||
fun update() {
|
||||
val settings = UncivGame.Current.settings
|
||||
private fun addYesNoRow (text: String, initialValue: Boolean, updateWorld: Boolean = false, action: ((Boolean) -> Unit)) {
|
||||
innerTable.add(text.toLabel())
|
||||
val button = YesNoButton(initialValue, skin) {
|
||||
action(it)
|
||||
settings.save()
|
||||
if (updateWorld)
|
||||
UncivGame.Current.worldScreen.shouldUpdate = true
|
||||
}
|
||||
innerTable.add(button).row()
|
||||
}
|
||||
|
||||
private fun reloadWorldAndOptions() {
|
||||
settings.save()
|
||||
clear()
|
||||
UncivGame.Current.worldScreen = WorldScreen(worldScreen.viewingCiv)
|
||||
UncivGame.Current.setWorldScreen()
|
||||
WorldScreenOptionsPopup(UncivGame.Current.worldScreen).open()
|
||||
}
|
||||
|
||||
val innerTable = Table(CameraStageBaseScreen.skin)
|
||||
private fun rebuildInnerTable() {
|
||||
settings.save()
|
||||
innerTable.clear()
|
||||
|
||||
innerTable.add("Display options".toLabel(fontSize = 24)).colspan(2).row()
|
||||
addHeader("Display options")
|
||||
|
||||
innerTable.add("Show worked tiles".toLabel())
|
||||
addButton(innerTable, if (settings.showWorkedTiles) "Yes" else "No") {
|
||||
settings.showWorkedTiles = !settings.showWorkedTiles
|
||||
update()
|
||||
addYesNoRow ("Show worked tiles", settings.showWorkedTiles, true) {
|
||||
settings.showWorkedTiles = it
|
||||
}
|
||||
addYesNoRow ("Show resources and improvements", settings.showResourcesAndImprovements, true) {
|
||||
settings.showResourcesAndImprovements = it
|
||||
}
|
||||
addYesNoRow ("Show tutorials", settings.showTutorials, true) {
|
||||
settings.showTutorials = it
|
||||
}
|
||||
addYesNoRow ("Show minimap", settings.showMinimap, true) {
|
||||
settings.showMinimap = it
|
||||
}
|
||||
addYesNoRow ("Show pixel units", settings.showPixelUnits, true) {
|
||||
settings.showPixelUnits = it
|
||||
}
|
||||
addYesNoRow ("Show pixel improvements", settings.showPixelImprovements, true) {
|
||||
settings.showPixelImprovements = it
|
||||
}
|
||||
|
||||
innerTable.add("Show resources and improvements".toLabel())
|
||||
addButton(innerTable, if (settings.showResourcesAndImprovements) "Yes" else "No") {
|
||||
settings.showResourcesAndImprovements = !settings.showResourcesAndImprovements
|
||||
update()
|
||||
addLanguageSelectBox()
|
||||
|
||||
addResolutionSelectBox()
|
||||
|
||||
addTileSetSelectBox()
|
||||
|
||||
addYesNoRow ("Continuous rendering", settings.continuousRendering) {
|
||||
settings.continuousRendering = it
|
||||
Gdx.graphics.isContinuousRendering = it
|
||||
}
|
||||
|
||||
addHeader("Gameplay options")
|
||||
|
||||
innerTable.add("Show tutorials".toLabel())
|
||||
addButton(innerTable, if (settings.showTutorials) "Yes" else "No") {
|
||||
settings.showTutorials = !settings.showTutorials
|
||||
update()
|
||||
addYesNoRow ("Check for idle units", settings.checkForDueUnits) {
|
||||
settings.checkForDueUnits = it
|
||||
}
|
||||
addYesNoRow ("Move units with a single tap", settings.singleTapMove) {
|
||||
settings.singleTapMove = it
|
||||
}
|
||||
addYesNoRow ("Auto-assign city production", settings.autoAssignCityProduction) {
|
||||
settings.autoAssignCityProduction = it
|
||||
}
|
||||
addYesNoRow ("Auto-build roads", settings.autoBuildingRoads) {
|
||||
settings.autoBuildingRoads = it
|
||||
}
|
||||
addYesNoRow ("Order trade offers by amount", settings.orderTradeOffersByAmount) {
|
||||
settings.orderTradeOffersByAmount = it
|
||||
}
|
||||
|
||||
innerTable.add("Show minimap".toLabel())
|
||||
addButton(innerTable, if (settings.showMinimap) "Yes" else "No") {
|
||||
settings.showMinimap = !settings.showMinimap
|
||||
update()
|
||||
}
|
||||
|
||||
innerTable.add("Show pixel units".toLabel())
|
||||
addButton(innerTable, if (settings.showPixelUnits) "Yes" else "No") {
|
||||
settings.showPixelUnits = !settings.showPixelUnits
|
||||
update()
|
||||
}
|
||||
|
||||
innerTable.add("Show pixel improvements".toLabel())
|
||||
addButton(innerTable, if (settings.showPixelImprovements) "Yes" else "No") {
|
||||
settings.showPixelImprovements = !settings.showPixelImprovements
|
||||
update()
|
||||
}
|
||||
|
||||
innerTable.add("Order trade offers by amount".toLabel())
|
||||
addButton(innerTable, if (settings.orderTradeOffersByAmount) "Yes" else "No") {
|
||||
settings.orderTradeOffersByAmount = !settings.orderTradeOffersByAmount
|
||||
update()
|
||||
}
|
||||
|
||||
addLanguageSelectBox(innerTable)
|
||||
|
||||
addResolutionSelectBox(innerTable)
|
||||
|
||||
addTileSetSelectBox(innerTable)
|
||||
|
||||
innerTable.add("Continuous rendering".toLabel())
|
||||
addButton(innerTable, if (settings.continuousRendering) "Yes" else "No") {
|
||||
settings.continuousRendering = !settings.continuousRendering
|
||||
Gdx.graphics.isContinuousRendering = settings.continuousRendering
|
||||
update()
|
||||
}
|
||||
|
||||
innerTable.add("Gameplay options".toLabel(fontSize = 24)).colspan(2).padTop(20f).row()
|
||||
|
||||
|
||||
innerTable.add("Check for idle units".toLabel())
|
||||
addButton(innerTable, if (settings.checkForDueUnits) "Yes" else "No") {
|
||||
settings.checkForDueUnits = !settings.checkForDueUnits
|
||||
update()
|
||||
}
|
||||
|
||||
innerTable.add("Move units with a single tap".toLabel())
|
||||
addButton(innerTable, if (settings.singleTapMove) "Yes" else "No") {
|
||||
settings.singleTapMove = !settings.singleTapMove
|
||||
update()
|
||||
}
|
||||
|
||||
innerTable.add("Auto-assign city production".toLabel())
|
||||
addButton(innerTable, if (settings.autoAssignCityProduction) "Yes" else "No") {
|
||||
settings.autoAssignCityProduction = !settings.autoAssignCityProduction
|
||||
update()
|
||||
}
|
||||
|
||||
innerTable.add("Auto-build roads".toLabel())
|
||||
addButton(innerTable, if (settings.autoBuildingRoads) "Yes" else "No") {
|
||||
settings.autoBuildingRoads = !settings.autoBuildingRoads
|
||||
update()
|
||||
}
|
||||
|
||||
addAutosaveTurnsSelectBox(innerTable)
|
||||
addAutosaveTurnsSelectBox()
|
||||
|
||||
// at the moment the notification service only exists on Android
|
||||
if (Gdx.app.type == Application.ApplicationType.Android) {
|
||||
innerTable.add("Multiplayer options".toLabel(fontSize = 24)).colspan(2).padTop(20f).row()
|
||||
addHeader("Multiplayer options")
|
||||
|
||||
innerTable.add("Enable out-of-game turn notifications".toLabel())
|
||||
addButton(innerTable, if (settings.multiplayerTurnCheckerEnabled) "Yes" else "No") {
|
||||
settings.multiplayerTurnCheckerEnabled = !settings.multiplayerTurnCheckerEnabled
|
||||
update()
|
||||
addYesNoRow ("Enable out-of-game turn notifications", settings.multiplayerTurnCheckerEnabled) {
|
||||
settings.multiplayerTurnCheckerEnabled = it
|
||||
}
|
||||
if (settings.multiplayerTurnCheckerEnabled) {
|
||||
addMultiplayerTurnCheckerDelayBox(innerTable)
|
||||
|
||||
innerTable.add("Show persistent notification for turn notifier service".toLabel())
|
||||
addButton(innerTable, if (settings.multiplayerTurnCheckerPersistentNotificationEnabled) "Yes" else "No") {
|
||||
settings.multiplayerTurnCheckerPersistentNotificationEnabled = !settings.multiplayerTurnCheckerPersistentNotificationEnabled
|
||||
update()
|
||||
if (settings.multiplayerTurnCheckerEnabled) {
|
||||
addMultiplayerTurnCheckerDelayBox()
|
||||
|
||||
addYesNoRow ("Show persistent notification for turn notifier service", settings.multiplayerTurnCheckerPersistentNotificationEnabled) {
|
||||
settings.multiplayerTurnCheckerPersistentNotificationEnabled = it
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
innerTable.add("Other options".toLabel(fontSize = 24)).colspan(2).padTop(20f).row()
|
||||
|
||||
|
||||
addSoundEffectsVolumeSlider(innerTable)
|
||||
addMusicVolumeSlider(innerTable)
|
||||
addHeader("Other options")
|
||||
|
||||
addSoundEffectsVolumeSlider()
|
||||
addMusicVolumeSlider()
|
||||
|
||||
if(Gdx.app.type==Application.ApplicationType.Desktop) {
|
||||
val generateTranslationsButton = TextButton("Generate translation files".tr(), CameraStageBaseScreen.skin)
|
||||
|
@ -167,51 +159,31 @@ class WorldScreenOptionsPopup(val worldScreen:WorldScreen) : Popup(worldScreen)
|
|||
|
||||
innerTable.add("Version".toLabel()).pad(10f)
|
||||
innerTable.add(UncivGame.Current.version.toLabel()).pad(10f).row()
|
||||
|
||||
|
||||
val scrollPane = ScrollPane(innerTable, skin)
|
||||
scrollPane.setOverscroll(false, false)
|
||||
scrollPane.fadeScrollBars = false
|
||||
scrollPane.setScrollingDisabled(true, false)
|
||||
add(scrollPane).maxHeight(screen.stage.height * 0.6f).row()
|
||||
|
||||
addCloseButton()
|
||||
|
||||
pack() // Needed to show the background.
|
||||
center(UncivGame.Current.worldScreen.stage)
|
||||
UncivGame.Current.worldScreen.shouldUpdate = true
|
||||
}
|
||||
|
||||
private fun addButton(table: Table, text: String, action: () -> Unit): Cell<TextButton> {
|
||||
val button = TextButton(text.tr(), skin).apply { color = ImageGetter.getBlue() }
|
||||
button.onClick(action)
|
||||
return table.add(button).apply { row() }
|
||||
}
|
||||
|
||||
|
||||
private fun addSoundEffectsVolumeSlider(innerTable: Table) {
|
||||
private fun addSoundEffectsVolumeSlider() {
|
||||
innerTable.add("Sound effects volume".tr())
|
||||
|
||||
val soundEffectsVolumeSlider = Slider(0f, 1.0f, 0.1f, false, skin)
|
||||
soundEffectsVolumeSlider.value = UncivGame.Current.settings.soundEffectsVolume
|
||||
soundEffectsVolumeSlider.value = settings.soundEffectsVolume
|
||||
soundEffectsVolumeSlider.onChange {
|
||||
UncivGame.Current.settings.soundEffectsVolume = soundEffectsVolumeSlider.value
|
||||
UncivGame.Current.settings.save()
|
||||
settings.soundEffectsVolume = soundEffectsVolumeSlider.value
|
||||
settings.save()
|
||||
Sounds.play(UncivSound.Click)
|
||||
}
|
||||
innerTable.add(soundEffectsVolumeSlider).pad(10f).row()
|
||||
}
|
||||
|
||||
private fun addMusicVolumeSlider(innerTable: Table) {
|
||||
private fun addMusicVolumeSlider() {
|
||||
val musicLocation = Gdx.files.local(UncivGame.Current.musicLocation)
|
||||
if (musicLocation.exists()) {
|
||||
innerTable.add("Music volume".tr())
|
||||
|
||||
val musicVolumeSlider = Slider(0f, 1.0f, 0.1f, false, skin)
|
||||
musicVolumeSlider.value = UncivGame.Current.settings.musicVolume
|
||||
musicVolumeSlider.value = settings.musicVolume
|
||||
musicVolumeSlider.onChange {
|
||||
UncivGame.Current.settings.musicVolume = musicVolumeSlider.value
|
||||
UncivGame.Current.settings.save()
|
||||
settings.musicVolume = musicVolumeSlider.value
|
||||
settings.save()
|
||||
|
||||
val music = UncivGame.Current.music
|
||||
if (music == null) // restart music, if it was off at the app start
|
||||
|
@ -235,7 +207,7 @@ class WorldScreenOptionsPopup(val worldScreen:WorldScreen) : Popup(worldScreen)
|
|||
errorTable.add("Downloading...".toLabel())
|
||||
val file = DropBox.downloadFile("/Music/thatched-villagers.mp3")
|
||||
musicLocation.write(file, false)
|
||||
update()
|
||||
rebuildInnerTable()
|
||||
UncivGame.Current.startMusic()
|
||||
} catch (ex: Exception) {
|
||||
errorTable.clear()
|
||||
|
@ -246,26 +218,23 @@ class WorldScreenOptionsPopup(val worldScreen:WorldScreen) : Popup(worldScreen)
|
|||
}
|
||||
}
|
||||
|
||||
private fun addResolutionSelectBox(innerTable: Table) {
|
||||
private fun addResolutionSelectBox() {
|
||||
innerTable.add("Resolution".toLabel())
|
||||
|
||||
val resolutionSelectBox = SelectBox<String>(skin)
|
||||
val resolutionArray = Array<String>()
|
||||
resolutionArray.addAll("750x500", "900x600", "1050x700", "1200x800", "1500x1000")
|
||||
resolutionSelectBox.items = resolutionArray
|
||||
resolutionSelectBox.selected = UncivGame.Current.settings.resolution
|
||||
resolutionSelectBox.selected = settings.resolution
|
||||
innerTable.add(resolutionSelectBox).minWidth(240f).pad(10f).row()
|
||||
|
||||
resolutionSelectBox.onChange {
|
||||
UncivGame.Current.settings.resolution = resolutionSelectBox.selected
|
||||
UncivGame.Current.settings.save()
|
||||
UncivGame.Current.worldScreen = WorldScreen(worldScreen.viewingCiv)
|
||||
UncivGame.Current.setWorldScreen()
|
||||
WorldScreenOptionsPopup(UncivGame.Current.worldScreen).open()
|
||||
settings.resolution = resolutionSelectBox.selected
|
||||
reloadWorldAndOptions()
|
||||
}
|
||||
}
|
||||
|
||||
private fun addTileSetSelectBox(innerTable: Table) {
|
||||
private fun addTileSetSelectBox() {
|
||||
innerTable.add("Tileset".toLabel())
|
||||
|
||||
val tileSetSelectBox = SelectBox<String>(skin)
|
||||
|
@ -274,55 +243,50 @@ class WorldScreenOptionsPopup(val worldScreen:WorldScreen) : Popup(worldScreen)
|
|||
.map { it.name.split("/")[1] }.distinct()
|
||||
for (tileset in tileSets) tileSetArray.add(tileset)
|
||||
tileSetSelectBox.items = tileSetArray
|
||||
tileSetSelectBox.selected = UncivGame.Current.settings.tileSet
|
||||
tileSetSelectBox.selected = settings.tileSet
|
||||
innerTable.add(tileSetSelectBox).minWidth(240f).pad(10f).row()
|
||||
|
||||
tileSetSelectBox.onChange {
|
||||
UncivGame.Current.settings.tileSet = tileSetSelectBox.selected
|
||||
UncivGame.Current.settings.save()
|
||||
UncivGame.Current.worldScreen = WorldScreen(worldScreen.viewingCiv)
|
||||
UncivGame.Current.setWorldScreen()
|
||||
WorldScreenOptionsPopup(UncivGame.Current.worldScreen).open()
|
||||
settings.tileSet = tileSetSelectBox.selected
|
||||
reloadWorldAndOptions()
|
||||
}
|
||||
}
|
||||
|
||||
private fun addAutosaveTurnsSelectBox(innerTable: Table) {
|
||||
private fun addAutosaveTurnsSelectBox() {
|
||||
innerTable.add("Turns between autosaves".toLabel())
|
||||
|
||||
val autosaveTurnsSelectBox = SelectBox<Int>(skin)
|
||||
val autosaveTurnsArray = Array<Int>()
|
||||
autosaveTurnsArray.addAll(1, 2, 5, 10)
|
||||
autosaveTurnsSelectBox.items = autosaveTurnsArray
|
||||
autosaveTurnsSelectBox.selected = UncivGame.Current.settings.turnsBetweenAutosaves
|
||||
autosaveTurnsSelectBox.selected = settings.turnsBetweenAutosaves
|
||||
|
||||
innerTable.add(autosaveTurnsSelectBox).pad(10f).row()
|
||||
|
||||
autosaveTurnsSelectBox.onChange {
|
||||
UncivGame.Current.settings.turnsBetweenAutosaves = autosaveTurnsSelectBox.selected
|
||||
UncivGame.Current.settings.save()
|
||||
update()
|
||||
settings.turnsBetweenAutosaves = autosaveTurnsSelectBox.selected
|
||||
settings.save()
|
||||
}
|
||||
}
|
||||
|
||||
private fun addMultiplayerTurnCheckerDelayBox(innerTable: Table) {
|
||||
private fun addMultiplayerTurnCheckerDelayBox() {
|
||||
innerTable.add("Time between turn checks out-of-game (in minutes)".toLabel())
|
||||
|
||||
val checkDelaySelectBox = SelectBox<Int>(skin)
|
||||
val possibleDelaysArray = Array<Int>()
|
||||
possibleDelaysArray.addAll(1, 2, 5, 15)
|
||||
checkDelaySelectBox.items = possibleDelaysArray
|
||||
checkDelaySelectBox.selected = UncivGame.Current.settings.multiplayerTurnCheckerDelayInMinutes
|
||||
checkDelaySelectBox.selected = settings.multiplayerTurnCheckerDelayInMinutes
|
||||
|
||||
innerTable.add(checkDelaySelectBox).pad(10f).row()
|
||||
|
||||
checkDelaySelectBox.onChange {
|
||||
UncivGame.Current.settings.multiplayerTurnCheckerDelayInMinutes = checkDelaySelectBox.selected
|
||||
UncivGame.Current.settings.save()
|
||||
update()
|
||||
settings.multiplayerTurnCheckerDelayInMinutes = checkDelaySelectBox.selected
|
||||
settings.save()
|
||||
}
|
||||
}
|
||||
|
||||
private fun addLanguageSelectBox(innerTable: Table) {
|
||||
private fun addLanguageSelectBox() {
|
||||
val languageSelectBox = SelectBox<Language>(skin)
|
||||
val languageArray = Array<Language>()
|
||||
UncivGame.Current.translations.percentCompleteOfLanguages
|
||||
|
@ -333,27 +297,49 @@ class WorldScreenOptionsPopup(val worldScreen:WorldScreen) : Popup(worldScreen)
|
|||
|
||||
innerTable.add("Language".toLabel())
|
||||
languageSelectBox.items = languageArray
|
||||
val matchingLanguage = languageArray.firstOrNull { it.language == UncivGame.Current.settings.language }
|
||||
val matchingLanguage = languageArray.firstOrNull { it.language == settings.language }
|
||||
languageSelectBox.selected = if (matchingLanguage != null) matchingLanguage else languageArray.first()
|
||||
innerTable.add(languageSelectBox).minWidth(240f).pad(10f).row()
|
||||
|
||||
languageSelectBox.onChange {
|
||||
// Sometimes the "changed" is triggered even when we didn't choose something that isn't the
|
||||
// Sometimes the "changed" is triggered even when we didn't choose something
|
||||
selectedLanguage = languageSelectBox.selected.language
|
||||
|
||||
if (selectedLanguage != UncivGame.Current.settings.language)
|
||||
if (selectedLanguage != settings.language)
|
||||
selectLanguage()
|
||||
}
|
||||
}
|
||||
|
||||
fun selectLanguage() {
|
||||
UncivGame.Current.settings.language = selectedLanguage
|
||||
UncivGame.Current.settings.save()
|
||||
|
||||
private fun selectLanguage() {
|
||||
settings.language = selectedLanguage
|
||||
UncivGame.Current.translations.tryReadTranslationForCurrentLanguage()
|
||||
CameraStageBaseScreen.resetFonts() // to load chinese characters if necessary
|
||||
UncivGame.Current.worldScreen = WorldScreen(worldScreen.viewingCiv)
|
||||
UncivGame.Current.setWorldScreen()
|
||||
WorldScreenOptionsPopup(UncivGame.Current.worldScreen).open()
|
||||
reloadWorldAndOptions()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
This TextButton subclass helps to keep looks and behaviour of our Yes/No
|
||||
in one place, but it also helps keeping context for those action lambdas.
|
||||
|
||||
Usage: YesNoButton(someSetting: Boolean, skin) { someSetting = it; sideEffects() }
|
||||
*/
|
||||
private fun Boolean.toYesNo(): String = (if (this) "Yes" else "No").tr()
|
||||
private class YesNoButton(initialValue: Boolean, skin: Skin, action: (Boolean) -> Unit)
|
||||
: TextButton (initialValue.toYesNo(), skin ) {
|
||||
|
||||
var value = initialValue
|
||||
private set(value) {
|
||||
field = value
|
||||
setText(value.toYesNo())
|
||||
}
|
||||
|
||||
init {
|
||||
color = ImageGetter.getBlue()
|
||||
onClick {
|
||||
value = !value
|
||||
action.invoke(value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue