mirror of
https://github.com/yairm210/Unciv.git
synced 2025-09-25 04:43:05 -04:00
City Info Table Expanders - fix persistence and resizing, close/open all button (#6441)
* Fix CityInfoTable expander persistence and resizing issues * CityInfoTable button to close/open all expanders
This commit is contained in:
parent
c8a88bfc49
commit
477ac78856
@ -1,7 +1,9 @@
|
||||
package com.unciv.ui.cityscreen
|
||||
|
||||
import com.badlogic.gdx.graphics.Color
|
||||
import com.badlogic.gdx.scenes.scene2d.Group
|
||||
import com.badlogic.gdx.scenes.scene2d.Touchable
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Cell
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Table
|
||||
import com.badlogic.gdx.utils.Align
|
||||
import com.unciv.Constants
|
||||
@ -24,6 +26,10 @@ class CityInfoTable(private val cityScreen: CityScreen) : Table(BaseScreen.skin)
|
||||
private val scrollPane: ScrollPane
|
||||
private val innerTable = Table(skin)
|
||||
|
||||
private val allExpanders = mutableListOf<ExpanderTab>()
|
||||
private val hideShowAllCell: Cell<Group>
|
||||
private var hideShowAllShouldClose = false
|
||||
|
||||
init {
|
||||
align(Align.topLeft)
|
||||
|
||||
@ -37,13 +43,17 @@ class CityInfoTable(private val cityScreen: CityScreen) : Table(BaseScreen.skin)
|
||||
scrollPane = ScrollPane(innerTable.addBorder(2f, Color.WHITE))
|
||||
scrollPane.setOverscroll(false, false)
|
||||
|
||||
add(showConstructionsTableButton).left().padLeft(pad).padBottom(pad).row()
|
||||
add(scrollPane).left().row()
|
||||
val hideShowAllButton = Group()
|
||||
add(showConstructionsTableButton).left().padLeft(pad).padBottom(pad)
|
||||
hideShowAllCell = add(hideShowAllButton).size(30f) // size as the cell won't be resized when the actor is replaced
|
||||
hideShowAllCell.left().padLeft(pad).padBottom(pad).expandX().row()
|
||||
add(scrollPane).colspan(2).left().row()
|
||||
}
|
||||
|
||||
internal fun update() {
|
||||
val cityInfo = cityScreen.city
|
||||
|
||||
allExpanders.clear()
|
||||
innerTable.clear()
|
||||
|
||||
innerTable.apply {
|
||||
@ -52,24 +62,56 @@ class CityInfoTable(private val cityScreen: CityScreen) : Table(BaseScreen.skin)
|
||||
addGreatPersonPointInfo(cityInfo)
|
||||
}
|
||||
|
||||
updateHideShowAllButton()
|
||||
|
||||
getCell(scrollPane).maxHeight(stage.height - showConstructionsTableButton.height - pad - 10f)
|
||||
onContentResize()
|
||||
}
|
||||
|
||||
private fun updateHideShowAllButton() {
|
||||
val anyExpanderOpen = allExpanders.map { it.isOpen }.maxOrNull() ?: false
|
||||
if (anyExpanderOpen == hideShowAllShouldClose) return
|
||||
hideShowAllShouldClose = anyExpanderOpen
|
||||
val hideShowAllButton = getToggleButton(hideShowAllShouldClose)
|
||||
hideShowAllButton.touchable = Touchable.enabled
|
||||
hideShowAllButton.onClick {
|
||||
for (expander in allExpanders) {
|
||||
if (expander.isOpen == hideShowAllShouldClose) expander.toggle()
|
||||
}
|
||||
updateHideShowAllButton()
|
||||
}
|
||||
hideShowAllCell.setActor(hideShowAllButton)
|
||||
}
|
||||
|
||||
private fun onContentResize() {
|
||||
pack()
|
||||
setPosition(CityScreen.posFromEdge, stage.height - CityScreen.posFromEdge, Align.topLeft)
|
||||
}
|
||||
|
||||
private fun Table.addCategory(category: String, showHideTable: Table) {
|
||||
val categoryWidth = cityScreen.stage.width / 4
|
||||
val expander = ExpanderTab(category, persistenceID = "CityInfo") {
|
||||
val expander = ExpanderTab(category, persistenceID = "CityInfo.$category"
|
||||
, onChange = {
|
||||
onContentResize()
|
||||
updateHideShowAllButton()
|
||||
}
|
||||
) {
|
||||
it.add(showHideTable).minWidth(categoryWidth)
|
||||
}
|
||||
addSeparator()
|
||||
add(expander).minWidth(categoryWidth).expandX().fillX().row()
|
||||
allExpanders += expander
|
||||
}
|
||||
|
||||
private fun addBuildingInfo(building: Building, destinationTable: Table) {
|
||||
val icon = ImageGetter.getConstructionImage(building.name).surroundWithCircle(30f)
|
||||
val isFree = building.name in cityScreen.city.civInfo.civConstructions.getFreeBuildings(cityScreen.city.id)
|
||||
val displayName = if (isFree) "{${building.name}} ({Free})" else building.name
|
||||
val buildingNameAndIconTable = ExpanderTab(displayName, Constants.defaultFontSize, icon, false, 5f) {
|
||||
val buildingNameAndIconTable = ExpanderTab(
|
||||
displayName, Constants.defaultFontSize, icon,
|
||||
startsOutOpened = false, defaultPad = 5f,
|
||||
onChange = { onContentResize() }
|
||||
) {
|
||||
val detailsString = building.getDescription(cityScreen.city, false)
|
||||
it.add(detailsString.toLabel().apply { wrap = true })
|
||||
.width(cityScreen.stage.width / 4 - 2 * pad).row() // when you set wrap, then you need to manually set the size of the label
|
||||
@ -146,8 +188,13 @@ class CityInfoTable(private val cityScreen: CityScreen) : Table(BaseScreen.skin)
|
||||
}
|
||||
}
|
||||
|
||||
private fun addStatsToHashmap(statTreeNode: StatTreeNode, hashMap: HashMap<String, Float>, stat:Stat,
|
||||
showDetails:Boolean, indentation:Int=0) {
|
||||
private fun addStatsToHashmap(
|
||||
statTreeNode: StatTreeNode,
|
||||
hashMap: HashMap<String, Float>,
|
||||
stat: Stat,
|
||||
showDetails: Boolean,
|
||||
indentation: Int = 0
|
||||
) {
|
||||
for ((name, child) in statTreeNode.children) {
|
||||
val statAmount = child.totalStats[stat]
|
||||
if (statAmount == 0f) continue
|
||||
@ -185,6 +232,7 @@ class CityInfoTable(private val cityScreen: CityScreen) : Table(BaseScreen.skin)
|
||||
statValuesTable,
|
||||
!showDetails
|
||||
)
|
||||
onContentResize()
|
||||
}
|
||||
|
||||
val relevantBaseStats = LinkedHashMap<String, Float>()
|
||||
@ -245,10 +293,7 @@ class CityInfoTable(private val cityScreen: CityScreen) : Table(BaseScreen.skin)
|
||||
statValuesTable.pack()
|
||||
|
||||
if (stat != Stat.Happiness) {
|
||||
val toggleButtonChar = if (showDetails) "-" else "+"
|
||||
val toggleButton = toggleButtonChar.toLabel().apply { setAlignment(Align.center) }
|
||||
.surroundWithCircle(25f, color = ImageGetter.getBlue())
|
||||
.surroundWithCircle(27f, false)
|
||||
val toggleButton = getToggleButton(showDetails)
|
||||
statValuesTable.addActor(toggleButton)
|
||||
toggleButton.setPosition(0f, statValuesTable.height, Align.topLeft)
|
||||
}
|
||||
@ -256,6 +301,14 @@ class CityInfoTable(private val cityScreen: CityScreen) : Table(BaseScreen.skin)
|
||||
statValuesTable.padBottom(4f)
|
||||
}
|
||||
|
||||
private fun getToggleButton(showDetails: Boolean): IconCircleGroup {
|
||||
val label = (if (showDetails) "-" else "+").toLabel()
|
||||
label.setAlignment(Align.center)
|
||||
return label
|
||||
.surroundWithCircle(25f, color = ImageGetter.getBlue())
|
||||
.surroundWithCircle(27f, false)
|
||||
}
|
||||
|
||||
private fun Table.addGreatPersonPointInfo(cityInfo: CityInfo) {
|
||||
val greatPersonPoints = cityInfo.getGreatPersonPointsForNextTurn()
|
||||
val allGreatPersonNames = greatPersonPoints.asSequence().flatMap { it.value.keys }.distinct()
|
||||
@ -274,7 +327,7 @@ class CityInfoTable(private val cityScreen: CityScreen) : Table(BaseScreen.skin)
|
||||
|
||||
companion object {
|
||||
private const val FONT_SIZE_STAT_INFO_HEADER = 22
|
||||
|
||||
|
||||
private fun Float.toPercentLabel() =
|
||||
"${if (this>0f) "+" else ""}${DecimalFormat("0.#").format(this)}%".toLabel()
|
||||
private fun Float.toOneDecimalLabel() =
|
||||
|
@ -113,7 +113,7 @@ class CityScreen(
|
||||
constructionsTable.isVisible = false
|
||||
cityInfoTable.isVisible = true
|
||||
cityInfoTable.update()
|
||||
cityInfoTable.setPosition(posFromEdge, stage.height - posFromEdge, Align.topLeft)
|
||||
// CityInfoTable sets its relative position itself
|
||||
}
|
||||
|
||||
// Bottom right: Tile or selected construction info
|
||||
|
Loading…
x
Reference in New Issue
Block a user