diff --git a/core/src/com/unciv/ui/cityscreen/CitizenManagementTable.kt b/core/src/com/unciv/ui/cityscreen/CitizenManagementTable.kt index 3f1fb396bc..5c20a5c80e 100644 --- a/core/src/com/unciv/ui/cityscreen/CitizenManagementTable.kt +++ b/core/src/com/unciv/ui/cityscreen/CitizenManagementTable.kt @@ -3,62 +3,77 @@ package com.unciv.ui.cityscreen import com.badlogic.gdx.graphics.Color import com.badlogic.gdx.scenes.scene2d.Touchable import com.badlogic.gdx.scenes.scene2d.ui.Table +import com.unciv.Constants import com.unciv.logic.city.CityFocus import com.unciv.ui.images.ImageGetter import com.unciv.ui.utils.* -class CitizenManagementTable(val cityScreen: CityScreen) : Table() { - private val innerTable = Table() +class CitizenManagementTable(val cityScreen: CityScreen) : Table(BaseScreen.skin) { val city = cityScreen.city - init { - innerTable.background = ImageGetter.getBackground(ImageGetter.getBlue().darken(0.5f)) - add(innerTable).pad(2f).fill() - background = ImageGetter.getBackground(Color.WHITE) - } - - fun update(visible: Boolean = false) { - innerTable.clear() - - if (!visible) { - isVisible = false - return - } - isVisible = true + fun update() { + clear() val colorSelected = BaseScreen.skin.get("selection", Color::class.java) val colorButton = BaseScreen.skin.get("color", Color::class.java) // effectively a button, but didn't want to rewrite TextButton style // and much more compact and can control backgrounds easily based on settings + val resetLabel = "Reset Citizens".toLabel() + val resetCell = Table() + resetCell.add(resetLabel).pad(5f) + if (cityScreen.canChangeState) { + resetCell.touchable = Touchable.enabled + resetCell.onClick { city.reassignPopulation(true); cityScreen.update() } + } + resetCell.background = ImageGetter.getBackground(colorButton) + add(resetCell).colspan(2).growX().pad(3f) + row() + val avoidLabel = "Avoid Growth".toLabel() val avoidCell = Table() - avoidCell.touchable = Touchable.enabled avoidCell.add(avoidLabel).pad(5f) - if (cityScreen.canChangeState) + if (cityScreen.canChangeState) { + avoidCell.touchable = Touchable.enabled avoidCell.onClick { city.avoidGrowth = !city.avoidGrowth; city.reassignPopulation(); cityScreen.update() } - + } avoidCell.background = ImageGetter.getBackground(if (city.avoidGrowth) colorSelected else colorButton) - innerTable.add(avoidCell).colspan(2).growX().pad(3f) - innerTable.row() + add(avoidCell).colspan(2).growX().pad(3f) + row() + var newRow = false for (focus in CityFocus.values()) { if (!focus.tableEnabled) continue if (focus == CityFocus.FaithFocus && !city.civInfo.gameInfo.isReligionEnabled()) continue val label = focus.label.toLabel() val cell = Table() - cell.touchable = Touchable.enabled cell.add(label).pad(5f) - if (cityScreen.canChangeState) - cell.onClick { city.cityAIFocus = focus; city.reassignPopulation(); cityScreen.update() } - + if (cityScreen.canChangeState) { + cell.touchable = Touchable.enabled + cell.onClick { + city.cityAIFocus = focus; city.reassignPopulation(); cityScreen.update() + } + } cell.background = ImageGetter.getBackground(if (city.cityAIFocus == focus) colorSelected else colorButton) - innerTable.add(cell).growX().pad(3f) - if (focus.stat != null) - innerTable.add(ImageGetter.getStatIcon(focus.stat.name)).size(20f).padRight(5f) - innerTable.row() + add(cell).growX().pad(3f) + if (newRow) // every 2 make new row + row() + newRow = !newRow } pack() } + fun asExpander(onChange: (() -> Unit)?): ExpanderTab { + return ExpanderTab( + title = "{Citizen Management}", + fontSize = Constants.defaultFontSize, + persistenceID = "CityStatsTable.CitizenManagement", + startsOutOpened = false, + onChange = onChange + ) { + it.add(this) + update() + } + } + } diff --git a/core/src/com/unciv/ui/cityscreen/CityScreen.kt b/core/src/com/unciv/ui/cityscreen/CityScreen.kt index 1518c49390..23ba201a50 100644 --- a/core/src/com/unciv/ui/cityscreen/CityScreen.kt +++ b/core/src/com/unciv/ui/cityscreen/CityScreen.kt @@ -55,12 +55,6 @@ class CityScreen( /** Displays raze city button - sits on TOP CENTER */ private var razeCityButtonHolder = Table() - /** Displays reset locks button - sits on BOT RIGHT */ - private var resetCitizensButtonHolder = Table() - - /** Displays reset locks button - sits on BOT RIGHT */ - private var citizenManagementButtonHolder = Table() - /** Displays city stats info */ private var cityStatsTable = CityStatsTable(this) @@ -70,10 +64,6 @@ class CityScreen( /** Displays selected construction info, alternate with tileTable - sits on BOTTOM RIGHT */ private var selectedConstructionTable = ConstructionInfoTable(this) - /** Displays selected construction info, alternate with tileTable - sits on BOTTOM RIGHT */ - private var citizenManagementTable = CitizenManagementTable(this) - var citizenManagementVisible = false - /** Displays city name, allows switching between cities - sits on BOTTOM CENTER */ private var cityPickerTable = CityScreenCityPickerTable(this) @@ -118,29 +108,10 @@ class CityScreen( //stage.setDebugTableUnderMouse(true) stage.addActor(cityStatsTable) - val resetCitizensButton = "Reset Citizens".toTextButton() - resetCitizensButton.labelCell.pad(5f) - resetCitizensButton.onClick { city.reassignPopulation(resetLocked = true); update() } - resetCitizensButtonHolder.add(resetCitizensButton) - resetCitizensButtonHolder.pack() - if (!canChangeState) resetCitizensButton.disable() - stage.addActor(resetCitizensButtonHolder) - val citizenManagementButton = "Citizen Management".toTextButton() - citizenManagementButton.labelCell.pad(5f) - citizenManagementButton.onClick { - clearSelection() - citizenManagementVisible = true - update() - } - if (!canChangeState) citizenManagementButton.disable() - citizenManagementButtonHolder.add(citizenManagementButton) - citizenManagementButtonHolder.pack() - stage.addActor(citizenManagementButtonHolder) constructionsTable.addActorsToStage() stage.addActor(cityInfoTable) stage.addActor(selectedConstructionTable) stage.addActor(tileTable) - stage.addActor(citizenManagementTable) stage.addActor(cityPickerTable) // add late so it's top in Z-order and doesn't get covered in cramped portrait stage.addActor(exitCityButton) update() @@ -178,23 +149,6 @@ class CityScreen( tileTable.setPosition(stage.width - posFromEdge, posFromEdge, Align.bottomRight) selectedConstructionTable.update(selectedConstruction) selectedConstructionTable.setPosition(stage.width - posFromEdge, posFromEdge, Align.bottomRight) - citizenManagementTable.update(citizenManagementVisible) - citizenManagementTable.setPosition(stage.width - posFromEdge, posFromEdge, Align.bottomRight) - if (selectedTile == null && selectedConstruction == null && !citizenManagementVisible) - resetCitizensButtonHolder.setPosition(stage.width - posFromEdge, - posFromEdge, Align.bottomRight) - else if (selectedConstruction != null) - resetCitizensButtonHolder.setPosition(stage.width - posFromEdge, - posFromEdge + selectedConstructionTable.height + 10f, Align.bottomRight) - else if (selectedTile != null) - resetCitizensButtonHolder.setPosition(stage.width - posFromEdge, - posFromEdge + tileTable.height + 10f, Align.bottomRight) - else - resetCitizensButtonHolder.setPosition(stage.width - posFromEdge, - posFromEdge + citizenManagementTable.height + 10f, Align.bottomRight) - citizenManagementButtonHolder.isVisible = !citizenManagementVisible - citizenManagementButtonHolder.setPosition(stage.width - posFromEdge, - posFromEdge + resetCitizensButtonHolder.y + resetCitizensButtonHolder.height + 10f, Align.bottomRight) // In portrait mode only: calculate already occupied horizontal space val rightMargin = when { @@ -413,13 +367,11 @@ class CityScreen( pickTileData = null } selectedTile = null - citizenManagementVisible = false } private fun selectTile(newTile: TileInfo?) { selectedConstruction = null selectedQueueEntryTargetTile = null pickTileData = null - citizenManagementVisible = false selectedTile = newTile } fun clearSelection() = selectTile(null) diff --git a/core/src/com/unciv/ui/cityscreen/CityStatsTable.kt b/core/src/com/unciv/ui/cityscreen/CityStatsTable.kt index 6609ad0a8a..c28d7fe8d1 100644 --- a/core/src/com/unciv/ui/cityscreen/CityStatsTable.kt +++ b/core/src/com/unciv/ui/cityscreen/CityStatsTable.kt @@ -16,9 +16,11 @@ import com.unciv.ui.images.ImageGetter import com.unciv.ui.utils.* import kotlin.math.ceil import kotlin.math.round +import com.unciv.ui.utils.AutoScrollPane as ScrollPane class CityStatsTable(val cityScreen: CityScreen): Table() { private val innerTable = Table() + private val outerPane: ScrollPane private val cityInfo = cityScreen.city init { @@ -29,7 +31,10 @@ class CityStatsTable(val cityScreen: CityScreen): Table() { innerTable.defaults().pad(2f) innerTable.background = ImageGetter.getBackground(Color.BLACK.cpy().apply { a = 0.8f }) - add(innerTable).fill() + outerPane = ScrollPane(innerTable) + outerPane.setOverscroll(false, false) + outerPane.setScrollingDisabled(true, false) + add(outerPane).maxHeight(cityScreen.stage.height / 2) } fun update() { @@ -42,18 +47,20 @@ class CityStatsTable(val cityScreen: CityScreen): Table() { val icon = Table() if (cityInfo.cityAIFocus.stat == stat) { icon.add(ImageGetter.getStatIcon(stat.name).surroundWithCircle(27f, false, color = selected)) - if (cityScreen.canChangeState) + if (cityScreen.canChangeState) { icon.onClick { cityInfo.cityAIFocus = CityFocus.NoFocus cityInfo.reassignPopulation(); cityScreen.update() } + } } else { icon.add(ImageGetter.getStatIcon(stat.name).surroundWithCircle(27f, false, color = Color.CLEAR)) - if (cityScreen.canChangeState) + if (cityScreen.canChangeState) { icon.onClick { cityInfo.cityAIFocus = cityInfo.cityAIFocus.safeValueOf(stat) cityInfo.reassignPopulation(); cityScreen.update() } + } } miniStatsTable.add(icon).size(27f).padRight(5f) val valueToDisplay = if (stat == Stat.Happiness) cityInfo.cityStats.happinessList.values.sum() else amount @@ -63,12 +70,16 @@ class CityStatsTable(val cityScreen: CityScreen): Table() { innerTable.addSeparator() addText() + addCitizenManagement() if (!cityInfo.population.getMaxSpecialists().isEmpty()) { addSpecialistInfo() } if (cityInfo.religion.getNumberOfFollowers().isNotEmpty() && cityInfo.civInfo.gameInfo.isReligionEnabled()) addReligionInfo() + innerTable.pack() + outerPane.layout() + outerPane.updateVisualScroll() pack() } @@ -132,6 +143,18 @@ class CityStatsTable(val cityScreen: CityScreen): Table() { innerTable.add(tableWithIcons).row() } + private fun addCitizenManagement() { + val expanderTab = CitizenManagementTable(cityScreen).asExpander { + pack() + setPosition( + stage.width - CityScreen.posFromEdge, + stage.height - CityScreen.posFromEdge, + Align.topRight + ) + } + innerTable.add(expanderTab).growX().row() + } + private fun addSpecialistInfo() { val expanderTab = SpecialistAllocationTable(cityScreen).asExpander { pack() diff --git a/core/src/com/unciv/ui/cityscreen/SpecialistAllocationTable.kt b/core/src/com/unciv/ui/cityscreen/SpecialistAllocationTable.kt index 9572d46eb6..878becbb35 100644 --- a/core/src/com/unciv/ui/cityscreen/SpecialistAllocationTable.kt +++ b/core/src/com/unciv/ui/cityscreen/SpecialistAllocationTable.kt @@ -18,7 +18,7 @@ class SpecialistAllocationTable(val cityScreen: CityScreen) : Table(BaseScreen.s // Auto/Manual Specialists Toggle // Color of "color" coming from Skin.json that's loaded into BaseScreen // 5 columns: unassignButton, AllocationTable, assignButton, SeparatorVertical, SpecialistsStatsTabe - if (cityScreen.canChangeState) + if (cityScreen.canChangeState) { if (cityInfo.manualSpecialists) { val manualSpecialists = "Manual Specialists".toLabel() .addBorder(5f, BaseScreen.skin.get("color", Color::class.java)) @@ -33,6 +33,7 @@ class SpecialistAllocationTable(val cityScreen: CityScreen) : Table(BaseScreen.s autoSpecialists.onClick { cityInfo.manualSpecialists = true; update() } add(autoSpecialists).colspan(5).row() } + } for ((specialistName, maxSpecialists) in cityInfo.population.getMaxSpecialists()) { if (!cityInfo.getRuleset().specialists.containsKey(specialistName)) // specialist doesn't exist in this ruleset, probably a mod continue