Redesign EmpireOverviewScreen as TabbedPager (#6364)

This commit is contained in:
SomeTroglodyte
2022-03-17 21:23:09 +01:00
committed by GitHub
parent c80db524b2
commit 89e73ad7c5
13 changed files with 480 additions and 313 deletions

View File

@ -18,7 +18,18 @@ import com.unciv.ui.utils.UncivTooltip.Companion.addTooltip
import kotlin.math.max
import kotlin.math.roundToInt
class CityOverviewTable(private val viewingPlayer: CivilizationInfo, private val overviewScreen: EmpireOverviewScreen): Table() {
class CityOverviewTab(
viewingPlayer: CivilizationInfo,
overviewScreen: EmpireOverviewScreen,
persistedData: EmpireOverviewTabPersistableData? = null
) : EmpireOverviewTab(viewingPlayer, overviewScreen) {
class CityTabPersistableData(
var sortedBy: String = "City"
) : EmpireOverviewTabPersistableData() {
override fun isEmpty() = sortedBy == "City"
}
override val persistableData = (persistedData as? CityTabPersistableData) ?: CityTabPersistableData()
companion object {
const val iconSize = 50f //if you set this too low, there is a chance that the tables will be misaligned
@ -31,20 +42,19 @@ class CityOverviewTable(private val viewingPlayer: CivilizationInfo, private val
init {
val numHeaderCells = columnsNames.size + 2 // +1 City +1 Filler
var sortedBy = "City"
val cityInfoTableIcons = Table(skin)
val cityInfoTableDetails = Table(skin)
val cityInfoTableTotal = Table(skin)
fun sortOnClick(iconName: String) {
val descending = sortedBy == iconName
sortedBy = iconName
val descending = persistableData.sortedBy == iconName
persistableData.sortedBy = iconName
// sort the table: clear and fill with sorted data
cityInfoTableDetails.clear()
fillCitiesTable(cityInfoTableDetails, iconName, descending)
// reset to return back for ascending next time
if (descending) sortedBy = ""
if (descending) persistableData.sortedBy = ""
}
fun addSortIcon(iconName: String, iconParam: Actor? = null) {
@ -77,7 +87,7 @@ class CityOverviewTable(private val viewingPlayer: CivilizationInfo, private val
.minWidth(iconSize) //we need the min width so we can align the different tables
.align(Align.left)
fillCitiesTable(cityInfoTableDetails, sortedBy, false)
fillCitiesTable(cityInfoTableDetails, persistableData.sortedBy, false)
val cityInfoScrollPane = AutoScrollPane(cityInfoTableDetails)
cityInfoScrollPane.pack()

View File

@ -12,12 +12,17 @@ import com.unciv.logic.civilization.diplomacy.DiplomaticStatus
import com.unciv.ui.trade.DiplomacyScreen
import com.unciv.ui.utils.*
class DiplomacyOverviewTable (
private val viewingPlayer: CivilizationInfo,
private val overviewScreen: EmpireOverviewScreen
): Table() {
private var includeCityStates = false
class DiplomacyOverviewTab (
viewingPlayer: CivilizationInfo,
overviewScreen: EmpireOverviewScreen,
persistedData: EmpireOverviewTabPersistableData? = null
) : EmpireOverviewTab(viewingPlayer, overviewScreen) {
class DiplomacyTabPersistableData(
var includeCityStates: Boolean = false
) : EmpireOverviewTabPersistableData() {
override fun isEmpty() = !includeCityStates
}
override val persistableData = (persistedData as? DiplomacyTabPersistableData) ?: DiplomacyTabPersistableData()
init {
update()
@ -25,9 +30,9 @@ class DiplomacyOverviewTable (
fun update() {
clear()
val relevantCivs = viewingPlayer.gameInfo.civilizations
.filter { !it.isBarbarian() && !it.isSpectator() && (includeCityStates || !it.isCityState()) }
val diplomacyGroup = DiplomacyGroup(viewingPlayer, overviewScreen.centerAreaHeight, includeCityStates)
val relevantCivs = gameInfo.civilizations
.filter { !it.isBarbarian() && !it.isSpectator() && (persistableData.includeCityStates || !it.isCityState()) }
val diplomacyGroup = DiplomacyGroup(viewingPlayer, overviewScreen.centerAreaHeight, persistableData.includeCityStates)
val playerKnowsAndUndefeatedCivs = relevantCivs.filter { diplomacyGroup.playerKnows(it) && !it.isDefeated() }
val playerKnowsAndDefeatedCivs = relevantCivs.filter { diplomacyGroup.playerKnows(it) && it.isDefeated() }
if (playerKnowsAndUndefeatedCivs.size > 1)
@ -39,12 +44,14 @@ class DiplomacyOverviewTable (
titleTable.add(viewingPlayer.civName.toLabel()).left().padRight(10f)
titleTable.add(viewingPlayer.calculateScoreBreakdown().values.sum().toInt().toLabel()).row()
val civTableScrollPane = getCivTableScroll(relevantCivs, titleTable, playerKnowsAndUndefeatedCivs, playerKnowsAndDefeatedCivs)
val toggleCityStatesButton = "City-States".toTextButton()
toggleCityStatesButton.color = if(includeCityStates) Color.RED else Color.GREEN
toggleCityStatesButton.onClick { includeCityStates = !includeCityStates; update() }
toggleCityStatesButton.color = if (persistableData.includeCityStates) Color.RED else Color.GREEN
toggleCityStatesButton.onClick {
persistableData.includeCityStates = !persistableData.includeCityStates
update()
}
val floatingTable = Table()
floatingTable.add(toggleCityStatesButton).row()

View File

@ -0,0 +1,65 @@
package com.unciv.ui.overviewscreen
import com.unciv.logic.civilization.CivilizationInfo
import com.unciv.ui.utils.KeyCharAndCode
import com.unciv.ui.overviewscreen.EmpireOverviewTab.EmpireOverviewTabPersistableData
private typealias FactoryType = (CivilizationInfo, EmpireOverviewScreen, EmpireOverviewTabPersistableData?) -> EmpireOverviewTab
enum class EmpireOverviewTabState { Normal, Disabled, Hidden }
private typealias StateTesterType = (CivilizationInfo) -> EmpireOverviewTabState
private fun Boolean.toState(): EmpireOverviewTabState = if (this) EmpireOverviewTabState.Disabled else EmpireOverviewTabState.Normal
/** This controls which Tabs for the [EmpireOverviewScreen] exist and their order.
*
* To add a Tab, build a new [EmpireOverviewTab] subclass and fill out a new entry here, that's all.
* Note the enum value's name is used as Tab caption, so if you ever need a non-alphanumeric caption please redesign to include a property for the caption.
*/
enum class EmpireOverviewCategories(
val iconName: String,
val shortcutKey: KeyCharAndCode,
val factory: FactoryType,
val stateTester: StateTesterType
) {
Cities("OtherIcons/Cities", 'C',
fun (viewingPlayer: CivilizationInfo, overviewScreen: EmpireOverviewScreen, persistedData: EmpireOverviewTabPersistableData?)
= CityOverviewTab(viewingPlayer, overviewScreen, persistedData),
fun (viewingPlayer: CivilizationInfo) = viewingPlayer.cities.isEmpty().toState()),
Stats("StatIcons/Gold", 'S',
fun (viewingPlayer: CivilizationInfo, overviewScreen: EmpireOverviewScreen, _: EmpireOverviewTabPersistableData?)
= StatsOverviewTab(viewingPlayer, overviewScreen),
fun (_: CivilizationInfo) = EmpireOverviewTabState.Normal),
Trades("StatIcons/Acquire", 'T',
fun (viewingPlayer: CivilizationInfo, overviewScreen: EmpireOverviewScreen, _: EmpireOverviewTabPersistableData?)
= TradesOverviewTab(viewingPlayer, overviewScreen),
fun (viewingPlayer: CivilizationInfo) = viewingPlayer.diplomacy.values.all { it.trades.isEmpty() }.toState()),
Units("OtherIcons/Shield", 'U',
fun (viewingPlayer: CivilizationInfo, overviewScreen: EmpireOverviewScreen, _: EmpireOverviewTabPersistableData?)
= UnitOverviewTab(viewingPlayer, overviewScreen),
fun (viewingPlayer: CivilizationInfo) = viewingPlayer.getCivUnits().none().toState()),
Diplomacy("OtherIcons/DiplomacyW", 'D',
fun (viewingPlayer: CivilizationInfo, overviewScreen: EmpireOverviewScreen, persistedData: EmpireOverviewTabPersistableData?)
= DiplomacyOverviewTab(viewingPlayer, overviewScreen, persistedData),
fun (viewingPlayer: CivilizationInfo) = viewingPlayer.diplomacy.isEmpty().toState()),
Resources("StatIcons/Happiness", 'R',
fun (viewingPlayer: CivilizationInfo, overviewScreen: EmpireOverviewScreen, _: EmpireOverviewTabPersistableData?)
= ResourcesOverviewTab(viewingPlayer, overviewScreen),
fun (viewingPlayer: CivilizationInfo) = viewingPlayer.detailedCivResources.isEmpty().toState()),
Religion("StatIcons/Faith", 'F',
fun (viewingPlayer: CivilizationInfo, overviewScreen: EmpireOverviewScreen, persistedData: EmpireOverviewTabPersistableData?)
= ReligionOverviewTab(viewingPlayer, overviewScreen, persistedData),
fun (viewingPlayer: CivilizationInfo) = when {
!viewingPlayer.gameInfo.isReligionEnabled() -> EmpireOverviewTabState.Hidden
viewingPlayer.gameInfo.religions.isEmpty() -> EmpireOverviewTabState.Disabled
else -> EmpireOverviewTabState.Normal
}),
Wonders("OtherIcons/Wonders", 'W',
fun (viewingPlayer: CivilizationInfo, overviewScreen: EmpireOverviewScreen, _: EmpireOverviewTabPersistableData?)
= WonderOverviewTab(viewingPlayer, overviewScreen),
fun (viewingPlayer: CivilizationInfo) = (viewingPlayer.naturalWonders.isEmpty() && viewingPlayer.cities.isEmpty()).toState()),
;
constructor(iconName: String, shortcutChar: Char, factory: FactoryType, stateTester: StateTesterType = { _ -> EmpireOverviewTabState.Normal })
: this(iconName, KeyCharAndCode(shortcutChar), factory, stateTester)
}

View File

@ -1,73 +1,37 @@
package com.unciv.ui.overviewscreen
import com.badlogic.gdx.graphics.Color
import com.badlogic.gdx.scenes.scene2d.Touchable
import com.badlogic.gdx.scenes.scene2d.ui.Button
import com.badlogic.gdx.scenes.scene2d.ui.Table
import com.badlogic.gdx.utils.Align
import com.unciv.Constants
import com.unciv.logic.civilization.CivilizationInfo
import com.unciv.models.translations.tr
import com.unciv.ui.utils.*
import com.unciv.ui.utils.KeyPressDispatcher.Companion.keyboardAvailable
import com.unciv.ui.utils.UncivTooltip.Companion.addTooltip
import com.unciv.ui.utils.AutoScrollPane as ScrollPane
import com.unciv.ui.overviewscreen.EmpireOverviewTab.EmpireOverviewTabPersistableData
import com.unciv.ui.utils.BaseScreen
import com.unciv.ui.utils.ImageGetter
import com.unciv.ui.utils.TabbedPager
class EmpireOverviewScreen(
private var viewingPlayer: CivilizationInfo,
defaultPage: String = ""
) : BaseScreen() {
private val topTable = Table().apply { defaults().pad(10f) }
private val centerTable = Table().apply { defaults().pad(5f) }
internal val setCategoryActions = HashMap<String, () -> Unit>()
private val categoryButtons = HashMap<String, Button>()
// 50 normal button height + 2*10 topTable padding + 2 Separator + 2*5 centerTable padding
// Since a resize recreates this screen this should be fine as a val
internal val centerAreaHeight = stage.height - 82f
private object ButtonDecorations {
data class IconAndKey (val icon: String, val key: Char = Char.MIN_VALUE)
val keyIconMap: HashMap<String,IconAndKey> = hashMapOf(
Pair("Cities", IconAndKey("OtherIcons/Cities", 'C')),
Pair("Stats", IconAndKey("StatIcons/Gold", 'S')),
Pair("Trades", IconAndKey("StatIcons/Acquire", 'T')),
Pair("Units", IconAndKey("OtherIcons/Shield", 'U')),
Pair("Diplomacy", IconAndKey("OtherIcons/DiplomacyW", 'D')),
Pair("Resources", IconAndKey("StatIcons/Happiness", 'R')),
Pair("Religion", IconAndKey("StatIcons/Faith", 'F')),
Pair("Wonders", IconAndKey("OtherIcons/Wonders", 'W'))
)
private val tabbedPager: TabbedPager
private val pageObjects = HashMap<EmpireOverviewCategories, EmpireOverviewTab>()
companion object {
// This is what keeps per-tab states between overview invocations
var persistState: Map<EmpireOverviewCategories, EmpireOverviewTabPersistableData>? = null
private fun updatePersistState(pageObjects: HashMap<EmpireOverviewCategories, EmpireOverviewTab>) {
persistState = pageObjects.mapValues { it.value.persistableData }.filterNot { it.value.isEmpty() }
}
}
private fun addCategory(name: String, table: Table, disabled: Boolean = false) {
// Buttons now hold their old label plus optionally an indicator for the shortcut key.
// Implement this templated on UnitActionsTable.getUnitActionButton()
val iconAndKey = ButtonDecorations.keyIconMap[name] ?: return // category without decoration entry disappears
val setCategoryAction = {
centerTable.clear()
centerTable.add(ScrollPane(table).apply { setOverscroll(false, false) })
.height(centerAreaHeight)
.width(stage.width)
centerTable.pack()
for ((key, categoryButton) in categoryButtons.filterNot { it.value.touchable == Touchable.disabled })
categoryButton.color = if (key == name) Color.BLUE else Color.WHITE
if (name == "Stats")
game.settings.addCompletedTutorialTask("See your stats breakdown")
game.settings.lastOverviewPage = name
}
val icon = if (iconAndKey.icon != "") ImageGetter.getImage(iconAndKey.icon) else null
val button = IconTextButton(name, icon)
if (!disabled && keyboardAvailable && iconAndKey.key != Char.MIN_VALUE) {
button.addTooltip(iconAndKey.key)
keyPressDispatcher[iconAndKey.key] = setCategoryAction
}
setCategoryActions[name] = setCategoryAction
categoryButtons[name] = button
button.onClick(setCategoryAction)
if (disabled) button.disable()
topTable.add(button)
override fun dispose() {
tabbedPager.selectPage(-1)
updatePersistState(pageObjects)
super.dispose()
}
init {
@ -77,76 +41,59 @@ class EmpireOverviewScreen(
defaultPage
}
else game.settings.lastOverviewPage
val iconSize = Constants.defaultFontSize.toFloat()
onBackButtonClicked { game.setWorldScreen() }
addCategory("Cities", CityOverviewTable(viewingPlayer, this), viewingPlayer.cities.isEmpty())
addCategory("Stats", StatsOverviewTable(viewingPlayer, this))
addCategory("Trades", TradesOverviewTable(viewingPlayer, this), viewingPlayer.diplomacy.values.all { it.trades.isEmpty() })
addCategory("Units", UnitOverviewTable(viewingPlayer, this), viewingPlayer.getCivUnits().none())
addCategory("Diplomacy", DiplomacyOverviewTable(viewingPlayer, this), viewingPlayer.diplomacy.isEmpty())
addCategory("Resources", ResourcesOverviewTable(viewingPlayer, this), viewingPlayer.detailedCivResources.isEmpty())
if (viewingPlayer.gameInfo.isReligionEnabled())
addCategory("Religion", ReligionOverviewTable(viewingPlayer, this), viewingPlayer.gameInfo.religions.isEmpty())
addCategory("Wonders", WonderOverviewTable(viewingPlayer, this), viewingPlayer.naturalWonders.isEmpty() && viewingPlayer.cities.isEmpty())
tabbedPager = TabbedPager(
stage.width, stage.width,
centerAreaHeight, centerAreaHeight,
separatorColor = Color.WHITE,
keyPressDispatcher = keyPressDispatcher,
capacity = EmpireOverviewCategories.values().size)
val closeButton = Constants.close.toTextButton().apply {
setColor(0.75f, 0.1f, 0.1f, 1f)
tabbedPager.addPage(Constants.close) {
_, _ -> game.setWorldScreen()
}
closeButton.onClick { game.setWorldScreen() }
closeButton.y = stage.height - closeButton.height - 5
topTable.add(closeButton)
tabbedPager.getPageButton(0).setColor(0.75f, 0.1f, 0.1f, 1f)
topTable.pack()
val topScroll = ScrollPane(topTable).apply { setScrollingDisabled(false, true) }
for (category in EmpireOverviewCategories.values()) {
val tabState = category.stateTester(viewingPlayer)
if (tabState == EmpireOverviewTabState.Hidden) continue
val icon = if (category.iconName.isEmpty()) null else ImageGetter.getImage(category.iconName)
val pageObject = category.factory(viewingPlayer, this, persistState?.get(category))
pageObject.pad(10f, 0f, 10f, 0f)
pageObjects[category] = pageObject
val index = tabbedPager.addPage(
caption = category.name,
content = pageObject,
icon, iconSize,
disabled = tabState != EmpireOverviewTabState.Normal,
shortcutKey = category.shortcutKey,
fixedContent = pageObject.getFixedContent(),
onDeactivation = { _, _, scrollY -> pageObject.deactivated(scrollY) }
) {
index, name ->
val scrollY = pageObject.activated()
if (scrollY != null) tabbedPager.setPageScrollY(index, scrollY)
if (name == "Stats")
game.settings.addCompletedTutorialTask("See your stats breakdown")
game.settings.lastOverviewPage = name
}
if (category.name == page)
tabbedPager.selectPage(index)
}
setCategoryActions[page]?.invoke()
val table = Table()
table.add(topScroll).row()
table.addSeparator()
table.add(centerTable).height(stage.height - topTable.height).expand().row()
table.setFillParent(true)
stage.addActor(table)
}
tabbedPager.setFillParent(true)
stage.addActor(tabbedPager)
}
override fun resize(width: Int, height: Int) {
if (stage.viewport.screenWidth != width || stage.viewport.screenHeight != height) {
updatePersistState(pageObjects)
game.setScreen(EmpireOverviewScreen(viewingPlayer, game.settings.lastOverviewPage))
dispose()
}
}
//todo this belongs in VictoryScreen as it's only ever used there
companion object {
fun getCivGroup(civ: CivilizationInfo, afterCivNameText:String, currentPlayer:CivilizationInfo): Table {
val civGroup = Table()
var labelText = civ.civName.tr()+afterCivNameText
var labelColor = Color.WHITE
val backgroundColor: Color
if (civ.isDefeated()) {
civGroup.add(ImageGetter.getImage("OtherIcons/DisbandUnit")).size(30f)
backgroundColor = Color.LIGHT_GRAY
labelColor = Color.BLACK
} else if (currentPlayer == civ // || game.viewEntireMapForDebug
|| currentPlayer.knows(civ) || currentPlayer.isDefeated() || currentPlayer.victoryManager.hasWon()) {
civGroup.add(ImageGetter.getNationIndicator(civ.nation, 30f))
backgroundColor = civ.nation.getOuterColor()
labelColor = civ.nation.getInnerColor()
} else {
civGroup.add(ImageGetter.getRandomNationIndicator(30f))
backgroundColor = Color.DARK_GRAY
labelText = Constants.unknownNationName
}
civGroup.background = ImageGetter.getRoundedEdgeRectangle(backgroundColor)
val label = labelText.toLabel(labelColor)
label.setAlignment(Align.center)
civGroup.add(label).padLeft(10f)
civGroup.pack()
return civGroup
}
}
}

View File

@ -0,0 +1,40 @@
package com.unciv.ui.overviewscreen
import com.badlogic.gdx.scenes.scene2d.ui.Table
import com.badlogic.gdx.scenes.scene2d.ui.WidgetGroup
import com.unciv.logic.civilization.CivilizationInfo
import com.unciv.ui.utils.BaseScreen
abstract class EmpireOverviewTab (
val viewingPlayer: CivilizationInfo,
val overviewScreen: EmpireOverviewScreen,
persistedData: EmpireOverviewTabPersistableData? = null
) : Table(BaseScreen.skin) {
open class EmpireOverviewTabPersistableData {
open fun isEmpty() = true
}
open val persistableData = persistedData ?: EmpireOverviewTabPersistableData()
/** Override if your Tab needs to do stuff on activation. @return non-null to scroll the Tab vertically within the TabbedPager. */
open fun activated(): Float? = null
/** Override if your Tab needs to do housekeeping when it loses focus. [scrollY] is the Tab's current vertical scroll position. */
open fun deactivated(scrollY: Float) {}
/** Override to supply content not participating in scrolling */
open fun getFixedContent(): WidgetGroup? = null
val gameInfo = viewingPlayer.gameInfo
protected fun equalizeColumns(vararg tables: Table) {
val columns = tables.first().columns
val widths = (0 until columns)
.mapTo(ArrayList(columns)) { column ->
tables.maxOf { it.getColumnWidth(column) }
}
for (table in tables) {
for (column in 0 until columns)
table.cells[column].run {
minWidth(widths[column] - padLeft - padRight)
}
table.invalidate()
}
}
}

View File

@ -17,20 +17,23 @@ import com.unciv.ui.civilopedia.MarkupRenderer
import com.unciv.ui.utils.*
import kotlin.math.max
class ReligionOverviewTable(
private val viewingPlayer: CivilizationInfo,
private val overviewScreen: EmpireOverviewScreen
): Table() {
class ReligionOverviewTab(
viewingPlayer: CivilizationInfo,
overviewScreen: EmpireOverviewScreen,
persistedData: EmpireOverviewTabPersistableData? = null
) : EmpireOverviewTab(viewingPlayer, overviewScreen) {
class ReligionTabPersistableData(
var selectedReligion: String? = null
) : EmpireOverviewTabPersistableData() {
override fun isEmpty() = selectedReligion == null
}
override val persistableData = (persistedData as? ReligionTabPersistableData) ?: ReligionTabPersistableData()
val gameInfo = viewingPlayer.gameInfo
private val civStatsTable = Table(BaseScreen.skin)
private val religionButtons = Table(BaseScreen.skin)
private val civStatsTable = Table()
private val religionButtons = Table()
private val religionButtonLabel = "Click an icon to see the stats of this religion".toLabel()
private val statsTable = Table(BaseScreen.skin)
private val beliefsTable = Table(BaseScreen.skin)
private var selectedReligion: String? = null
private val statsTable = Table()
private val beliefsTable = Table()
init {
defaults().pad(5f)
@ -38,14 +41,15 @@ class ReligionOverviewTable(
loadReligionButtons()
civStatsTable.defaults().left().pad(5f)
statsTable.defaults().left().pad(5f)
beliefsTable.defaults().padBottom(20f)
civStatsTable.addCivSpecificStats()
add(civStatsTable).row()
add(religionButtons).row()
add(religionButtonLabel)
addSeparator()
statsTable.defaults().left().pad(5f)
loadReligion(persistableData.selectedReligion)
add(statsTable).row()
beliefsTable.defaults().padBottom(20f)
add(beliefsTable).pad(20f)
}
@ -85,18 +89,23 @@ class ReligionOverviewTable(
val button = Button(image, BaseScreen.skin)
button.onClick {
selectedReligion = religion.name
persistableData.selectedReligion = religion.name
loadReligionButtons()
loadReligion(religion)
}
if (selectedReligion == religion.name)
if (persistableData.selectedReligion == religion.name)
button.disable()
religionButtons.add(button).pad(5f)
}
}
private fun loadReligion(religionName: String?) {
if (religionName == null) return
val religion = gameInfo.religions[religionName] ?: return
loadReligion(religion)
}
private fun loadReligion(religion: Religion) {
statsTable.clear()
beliefsTable.clear()

View File

@ -11,11 +11,10 @@ import com.unciv.ui.utils.addSeparator
import com.unciv.ui.utils.onClick
import com.unciv.ui.utils.toLabel
@Suppress("UNUSED_PARAMETER") // Keep all OverviewScreen Pages compatible
class ResourcesOverviewTable (
class ResourcesOverviewTab(
viewingPlayer: CivilizationInfo,
overviewScreen: EmpireOverviewScreen
) : Table() {
) : EmpireOverviewTab(viewingPlayer, overviewScreen) {
init {
defaults().pad(10f)

View File

@ -6,145 +6,150 @@ import com.unciv.Constants
import com.unciv.UncivGame
import com.unciv.logic.civilization.CivilizationInfo
import com.unciv.models.ruleset.ModOptionsConstants
import com.unciv.models.stats.Stat
import com.unciv.models.stats.StatMap
import com.unciv.ui.utils.*
import kotlin.math.roundToInt
class StatsOverviewTable (
private val viewingPlayer: CivilizationInfo,
private val overviewScreen: EmpireOverviewScreen
) : Table() {
class StatsOverviewTab(
viewingPlayer: CivilizationInfo,
overviewScreen: EmpireOverviewScreen
) : EmpireOverviewTab(viewingPlayer, overviewScreen) {
private val happinessTable = Table()
private val goldAndSliderTable = Table()
private val goldTable = Table()
private val scienceTable = Table()
private val greatPeopleTable = Table()
private val scoreTable = Table()
init {
defaults().pad(40f)
add(getHappinessTable()).top()
add(getGoldTable()).top()
add(getScienceTable()).top()
add(getGreatPeopleTable()).top()
add(getScoreTable()).top()
}
val tablePadding = 30f // Padding around each of the stat tables
defaults().pad(tablePadding).top()
private fun getHappinessTable(): Table {
val happinessTable = Table(BaseScreen.skin)
happinessTable.defaults().pad(5f)
happinessTable.add("Happiness".toLabel(fontSize = Constants.headingFontSize)).colspan(2).row()
happinessTable.addSeparator()
val happinessBreakdown = viewingPlayer.stats().getHappinessBreakdown()
for (entry in happinessBreakdown.filterNot { it.value.roundToInt()==0 }) {
happinessTable.add(entry.key.toLabel())
happinessTable.add(entry.value.roundToInt().toString()).right().row()
}
happinessTable.add("Total".toLabel())
happinessTable.add(happinessBreakdown.values.sum().roundToInt().toString()).right()
happinessTable.pack()
return happinessTable
}
private fun getGoldTable(): Table {
val goldTable = Table(BaseScreen.skin)
goldTable.defaults().pad(5f)
goldTable.add("Gold".toLabel(fontSize = Constants.headingFontSize)).colspan(2).row()
goldTable.addSeparator()
var total = 0f
for (entry in viewingPlayer.stats().getStatMapForNextTurn()) {
if (entry.value.gold == 0f) continue
goldTable.add(entry.key.toLabel())
goldTable.add(entry.value.gold.roundToInt().toString()).right().row()
total += entry.value.gold
}
goldTable.add("Total".toLabel())
goldTable.add(total.roundToInt().toString()).right()
if (viewingPlayer.gameInfo.ruleSet.modOptions.uniques.contains(ModOptionsConstants.convertGoldToScience)) {
goldTable.addSeparator()
val sliderTable = Table()
sliderTable.add("Convert gold to science".toLabel()).row()
val slider = UncivSlider(0f, 1f, 0.1f,
initial = viewingPlayer.tech.goldPercentConvertedToScience,
getTipText = UncivSlider::formatPercent
) {
viewingPlayer.tech.goldPercentConvertedToScience = it
for (city in viewingPlayer.cities) { city.cityStats.update() }
overviewScreen.setCategoryActions["Stats"]!!() // ? will probably steal focus and so prevent dragging the slider
}
slider.isDisabled = !UncivGame.Current.worldScreen.canChangeState
sliderTable.add(slider).padTop(15f)
goldTable.add(sliderTable).colspan(2)
}
goldTable.pack()
return goldTable
}
private fun getScienceTable(): Table {
val scienceTable = Table(BaseScreen.skin)
scienceTable.defaults().pad(5f)
scienceTable.add("Science".toLabel(fontSize = Constants.headingFontSize)).colspan(2).row()
scienceTable.addSeparator()
val scienceStats = viewingPlayer.stats().getStatMapForNextTurn()
.filter { it.value.science != 0f }
for (entry in scienceStats) {
scienceTable.add(entry.key.toLabel())
scienceTable.add(entry.value.science.roundToInt().toString()).right().row()
}
scienceTable.add("Total".toLabel())
scienceTable.add(scienceStats.map { it.value.science }.sum().roundToInt().toString()).right()
scienceTable.pack()
return scienceTable
greatPeopleTable.defaults().pad(5f)
scoreTable.defaults().pad(5f)
goldAndSliderTable.add(goldTable).row()
if (gameInfo.ruleSet.modOptions.uniques.contains(ModOptionsConstants.convertGoldToScience))
goldAndSliderTable.addGoldSlider()
update()
add(happinessTable)
add(goldAndSliderTable)
add(scienceTable)
add(greatPeopleTable)
add(scoreTable)
}
private fun getGreatPeopleTable(): Table {
val greatPeopleTable = Table(BaseScreen.skin)
fun update() {
val statMap = viewingPlayer.stats().getStatMapForNextTurn()
updateHappinessTable()
goldTable.updateStatTable(Stat.Gold, statMap)
scienceTable.updateStatTable(Stat.Science, statMap)
updateGreatPeopleTable()
updateScoreTable()
}
greatPeopleTable.defaults().pad(5f)
val greatPeopleHeader = Table(BaseScreen.skin)
private fun Table.addHeading(label: String) {
clear()
add(label.toLabel(fontSize = Constants.headingFontSize)).colspan(2).row()
addSeparator()
}
private fun Table.addLabeledValue(label: String, value: Float) {
val roundedValue = value.roundToInt()
if (roundedValue == 0) return
add(label.toLabel()).left()
add(roundedValue.toLabel()).right().row()
}
private fun Table.addTotal(value: Float) {
add("Total".toLabel()).left()
add(value.roundToInt().toLabel()).right()
pack()
}
private fun updateHappinessTable() = happinessTable.apply {
addHeading("Happiness")
val happinessBreakdown = viewingPlayer.stats().getHappinessBreakdown()
for ((key, value) in happinessBreakdown)
addLabeledValue(key, value)
addTotal(happinessBreakdown.values.sum())
}
private fun Table.updateStatTable(stat: Stat, statMap: StatMap) {
addHeading(stat.name)
var total = 0f
for ((source, stats) in statMap) {
addLabeledValue(source, stats[stat])
total += stats[stat]
}
addTotal(total)
}
private fun Table.addGoldSlider() {
addSeparator()
val sliderTable = Table()
sliderTable.add("Convert gold to science".toLabel()).row()
val slider = UncivSlider(0f, 1f, 0.1f,
initial = viewingPlayer.tech.goldPercentConvertedToScience,
getTipText = UncivSlider::formatPercent
) {
viewingPlayer.tech.goldPercentConvertedToScience = it
for (city in viewingPlayer.cities) { city.cityStats.update() }
update()
}
slider.isDisabled = !UncivGame.Current.worldScreen.canChangeState
sliderTable.add(slider).padTop(15f)
add(sliderTable).colspan(2)
}
private fun updateGreatPeopleTable() = greatPeopleTable.apply {
clear()
val greatPeopleHeader = Table()
val greatPeopleIcon = ImageGetter.getStatIcon("Specialist")
greatPeopleIcon.color = Color.ROYAL
greatPeopleHeader.add(greatPeopleIcon).padRight(12f).size(30f)
greatPeopleHeader.add("Great person points".toLabel(fontSize = Constants.headingFontSize)).padTop(5f)
greatPeopleTable.add(greatPeopleHeader).colspan(3).row()
greatPeopleTable.addSeparator()
greatPeopleTable.add()
greatPeopleTable.add("Current points".toLabel())
greatPeopleTable.add("Points per turn".toLabel()).row()
greatPeopleHeader.add(greatPeopleIcon).padRight(1f).size(Constants.headingFontSize.toFloat())
greatPeopleHeader.add("Great person points".toLabel(fontSize = Constants.headingFontSize))
add(greatPeopleHeader).colspan(3).row()
addSeparator()
add()
add("Current points".toLabel())
add("Points per turn".toLabel()).row()
val greatPersonPoints = viewingPlayer.greatPeople.greatPersonPointsCounter
val greatPersonPointsPerTurn = viewingPlayer.getGreatPersonPointsForNextTurn()
val pointsToGreatPerson = viewingPlayer.greatPeople.pointsForNextGreatPerson
for((greatPerson, points) in greatPersonPoints) {
greatPeopleTable.add(greatPerson.toLabel())
greatPeopleTable.add("$points/$pointsToGreatPerson")
greatPeopleTable.add(greatPersonPointsPerTurn[greatPerson].toString()).row()
for ((greatPerson, points) in greatPersonPoints) {
add(greatPerson.toLabel()).left()
add("$points/$pointsToGreatPerson".toLabel())
add(greatPersonPointsPerTurn[greatPerson]!!.toLabel()).right().row()
}
val pointsForGreatGeneral = viewingPlayer.greatPeople.greatGeneralPoints
val pointsForNextGreatGeneral = viewingPlayer.greatPeople.pointsForNextGreatGeneral
greatPeopleTable.add("Great General".toLabel())
greatPeopleTable.add("$pointsForGreatGeneral/$pointsForNextGreatGeneral").row()
greatPeopleTable.pack()
return greatPeopleTable
add("Great General".toLabel()).left()
add("$pointsForGreatGeneral/$pointsForNextGreatGeneral".toLabel())
pack()
}
private fun getScoreTable(): Table {
val scoreTableHeader = Table(BaseScreen.skin)
scoreTableHeader.add("Score".toLabel(fontSize = Constants.headingFontSize)).padBottom(6f)
val scoreTable = Table(BaseScreen.skin)
scoreTable.defaults().pad(5f)
scoreTable.add(scoreTableHeader).colspan(2).row()
scoreTable.addSeparator()
val scoreBreakdown = viewingPlayer.calculateScoreBreakdown().filter { it.value != 0.0 }
for ((label, value) in scoreBreakdown) {
scoreTable.add(label.toLabel())
scoreTable.add(value.toInt().toLabel()).row()
}
scoreTable.add("Total".toLabel())
scoreTable.add(scoreBreakdown.values.sum().toInt().toLabel())
return scoreTable
private fun updateScoreTable() = scoreTable.apply {
clear()
val scoreHeader = Table()
val scoreIcon = ImageGetter.getImage("OtherIcons/Cultured")
scoreIcon.color = Color.FIREBRICK
scoreHeader.add(scoreIcon).padRight(1f).size(Constants.headingFontSize.toFloat())
scoreHeader.add("Score".toLabel(fontSize = Constants.headingFontSize))
add(scoreHeader).colspan(2).row()
addSeparator()
val scoreBreakdown = viewingPlayer.calculateScoreBreakdown()
for ((label, value) in scoreBreakdown)
addLabeledValue(label, value.toFloat())
addTotal(scoreBreakdown.values.sum().toFloat())
}
}

View File

@ -4,15 +4,14 @@ import com.badlogic.gdx.scenes.scene2d.ui.Table
import com.unciv.logic.civilization.CivilizationInfo
import com.unciv.logic.trade.Trade
import com.unciv.logic.trade.TradeOffersList
import com.unciv.ui.utils.BaseScreen
import com.unciv.ui.utils.ImageGetter
import com.unciv.ui.utils.addSeparator
import com.unciv.ui.utils.toLabel
class TradesOverviewTable (
private val viewingPlayer: CivilizationInfo,
private val overviewScreen: EmpireOverviewScreen
) : Table() {
class TradesOverviewTab(
viewingPlayer: CivilizationInfo,
overviewScreen: EmpireOverviewScreen
) : EmpireOverviewTab(viewingPlayer, overviewScreen) {
init {
defaults().pad(10f)
@ -28,14 +27,14 @@ class TradesOverviewTable (
else -> -1
}
}
for(diplomacy in diplomacies) {
for (diplomacy in diplomacies) {
for (trade in diplomacy.trades)
add(createTradeTable(trade, diplomacy.otherCiv())).row()
}
}
private fun createTradeTable(trade: Trade, otherCiv: CivilizationInfo): Table {
val generalTable = Table(BaseScreen.skin)
val generalTable = Table()
generalTable.add(createOffersTable(viewingPlayer, trade.ourOffers, trade.theirOffers.size)).minWidth(overviewScreen.stage.width/4).fillY()
generalTable.add(createOffersTable(otherCiv, trade.theirOffers, trade.ourOffers.size)).minWidth(overviewScreen.stage.width/4).fillY()
return generalTable
@ -47,12 +46,12 @@ class TradesOverviewTable (
table.background = ImageGetter.getBackground(civ.nation.getOuterColor())
table.add(civ.civName.toLabel(civ.nation.getInnerColor())).row()
table.addSeparator()
for(offer in offersList){
for (offer in offersList) {
var offerText = offer.getOfferText()
if(!offerText.contains("\n")) offerText+="\n"
if (!offerText.contains("\n")) offerText += "\n"
table.add(offerText.toLabel(civ.nation.getInnerColor())).row()
}
for(i in 1..numberOfOtherSidesOffers - offersList.size)
for (i in 1..numberOfOtherSidesOffers - offersList.size)
table.add("\n".toLabel()).row() // we want both sides of the general table to have the same number of rows
return table
}

View File

@ -13,10 +13,10 @@ import kotlin.math.abs
/**
* Supplies the Unit sub-table for the Empire Overview
*/
class UnitOverviewTable(
private val viewingPlayer: CivilizationInfo,
private val overviewScreen: EmpireOverviewScreen
) : Table(BaseScreen.skin) {
class UnitOverviewTab(
viewingPlayer: CivilizationInfo,
overviewScreen: EmpireOverviewScreen
) : EmpireOverviewTab(viewingPlayer, overviewScreen) {
init {
add(getUnitSupplyTable()).top().padRight(25f)

View File

@ -20,11 +20,10 @@ import com.unciv.ui.utils.ImageGetter
import com.unciv.ui.utils.onClick
import com.unciv.ui.utils.toLabel
class WonderOverviewTable(
private val viewingPlayer: CivilizationInfo,
@Suppress("unused") private val overviewScreen: EmpireOverviewScreen
): Table() {
val gameInfo = viewingPlayer.gameInfo
class WonderOverviewTab(
viewingPlayer: CivilizationInfo,
overviewScreen: EmpireOverviewScreen
) : EmpireOverviewTab(viewingPlayer, overviewScreen) {
val ruleSet = gameInfo.ruleSet
private val hideReligionItems = !gameInfo.isReligionEnabled()

View File

@ -1,17 +1,18 @@
package com.unciv.ui.utils
import com.badlogic.gdx.graphics.Color
import com.badlogic.gdx.graphics.g3d.model.Animation
import com.badlogic.gdx.scenes.scene2d.Actor
import com.badlogic.gdx.scenes.scene2d.Group
import com.badlogic.gdx.scenes.scene2d.ui.*
import com.unciv.Constants
import com.unciv.UncivGame
import com.unciv.ui.utils.UncivTooltip.Companion.addTooltip
import kotlin.math.min
/*
Unimplemented ideas:
Allow "fixed header" content that does not participate in scrolling
(OptionsPopup mod check tab)
Use fixedContent for OptionsPopup mod check tab
`scrollAlign: Align` property controls initial content scroll position (currently it's Align.top)
*/
@ -30,6 +31,8 @@ import kotlin.math.min
* area of added pages and set the reported pref-W/H to their maximum within these bounds. But, if a
* maximum is not specified, that coordinate will grow with content unlimited, and layout max-W/H will
* always report the same as pref-W/H.
*
* [keyPressDispatcher] is optional and works with the `shortcutKey` parameter of [addPage] to support key bindings with tooltips.
*/
//region Fields and initialization
@Suppress("MemberVisibilityCanBePrivate", "unused") // All member are part of our API
@ -43,19 +46,23 @@ class TabbedPager(
private val highlightColor: Color = Color.BLUE,
backgroundColor: Color = ImageGetter.getBlue().darken(0.5f),
private val headerPadding: Float = 10f,
separatorColor: Color = Color.CLEAR,
private val keyPressDispatcher: KeyPressDispatcher? = null,
capacity: Int = 4
) : Table() {
private class PageState(
caption: String,
var content: Actor,
var fixedContent: WidgetGroup? = null,
var disabled: Boolean = false,
val onActivation: ((Int, String)->Unit)? = null,
val onActivation: ((Int, String) -> Unit)? = null,
val onDeactivation: ((Int, String, Float) -> Unit)? = null,
icon: Actor? = null,
iconSize: Float = 0f,
val shortcutKey: KeyCharAndCode = KeyCharAndCode.UNKNOWN,
pager: TabbedPager
) {
var scrollX = 0f
var scrollY = 0f
@ -90,6 +97,7 @@ class TabbedPager(
private var headerHeight = 0f
private val contentScroll = AutoScrollPane(null)
private val fixedContentWrapper = Container<WidgetGroup>()
private val deferredSecretPages = ArrayDeque<PageState>(0)
private var askPasswordLock = false
@ -102,6 +110,9 @@ class TabbedPager(
// Measure header height, most likely its final value
removePage(addPage("Dummy"))
add(headerScroll).growX().minHeight(headerHeight).row()
if (separatorColor != Color.CLEAR)
addSeparator(separatorColor)
add(fixedContentWrapper).growX().row()
add(contentScroll).grow().row()
}
@ -145,7 +156,9 @@ class TabbedPager(
if (index >= 0 && pages[index].disabled) return false
if (activePage != -1) {
pages[activePage].apply {
onDeactivation?.invoke(activePage, button.name, contentScroll.scrollY)
button.color = Color.WHITE
fixedContentWrapper.actor = null
scrollX = contentScroll.scrollX
scrollY = contentScroll.scrollY
contentScroll.removeActor(content)
@ -155,6 +168,7 @@ class TabbedPager(
if (index != -1) {
pages[index].apply {
button.color = highlightColor
fixedContentWrapper.actor = fixedContent
contentScroll.actor = content
contentScroll.layout()
if (scrollX < 0f) // was marked to center on first show
@ -196,6 +210,19 @@ class TabbedPager(
*/
fun setPageDisabled(caption: String, disabled: Boolean) = setPageDisabled(getPageIndex(caption), disabled)
/** Access a page's header button e.g. for unusual formatting */
fun getPageButton(index: Int) = pages[index].button
/** Change the vertical scroll position af a page's contents */
fun setPageScrollY(index: Int, scrollY: Float, animation: Boolean = false) {
if (index !in 0 until pages.size) return
val page = pages[index]
page.scrollY = scrollY
if (index != activePage) return
contentScroll.scrollY = scrollY
if (!animation) contentScroll.updateVisualScroll()
}
/** Remove a page by its index.
* @return `true` if page successfully removed */
fun removePage(index: Int): Boolean {
@ -211,7 +238,7 @@ class TabbedPager(
* @return `true` if page successfully removed */
fun removePage(caption: String) = removePage(getPageIndex(caption))
/** Replace a page's content by its index. */
/** Replace a page's [content] by its [index]. */
fun replacePage(index: Int, content: Actor) {
if (index !in 0 until pages.size) return
val isActive = index == activePage
@ -219,9 +246,20 @@ class TabbedPager(
pages[index].content = content
if (isActive) selectPage(index)
}
/** Replace a page's [content] and [fixedContent] by its [index]. */
fun replacePage(index: Int, content: Actor, fixedContent: WidgetGroup?) {
if (index !in 0 until pages.size) return
val isActive = index == activePage
if (isActive) selectPage(-1)
pages[index].content = content
pages[index].fixedContent = fixedContent
if (isActive) selectPage(index)
}
/** Replace a page's content by its caption. */
/** Replace a page's [content] by its [caption]. */
fun replacePage(caption: String, content: Actor) = replacePage(getPageIndex(caption), content)
/** Replace a page's [content] and [fixedContent] by its [caption]. */
fun replacePage(caption: String, content: Actor, fixedContent: WidgetGroup?) = replacePage(getPageIndex(caption), content, fixedContent)
/** Add a page!
* @param caption Text to be shown on the header button (automatically translated), can later be used to reference the page in other calls.
@ -231,6 +269,9 @@ class TabbedPager(
* @param insertBefore -1 to add at the end or index of existing page to insert this before
* @param secret Marks page as 'secret'. A password is asked once per [TabbedPager] and if it does not match the has passed in the constructor the page and all subsequent secret pages are dropped.
* @param disabled Initial disabled state. Disabled pages cannot be selected even with [selectPage], their button is dimmed.
* @param shortcutKey Optional keyboard key to associate - goes to the [KeyPressDispatcher] passed in the constructor.
* @param fixedContent Optional second content [WidgetGroup], will be placed outside the tab's [ScrollPane] between header and [content].
* @param onDeactivation _Optional_ callback called when this page is hidden. Lambda arguments are page index and caption, and scrollY of the tab's [ScrollPane].
* @param onActivation _Optional_ callback called when this page is shown (per actual change to this page, not per header click). Lambda arguments are page index and caption.
* @return The new page's index or -1 if it could not be immediately added (secret).
*/
@ -242,16 +283,22 @@ class TabbedPager(
insertBefore: Int = -1,
secret: Boolean = false,
disabled: Boolean = false,
onActivation: ((Int, String)->Unit)? = null
shortcutKey: KeyCharAndCode = KeyCharAndCode.UNKNOWN,
fixedContent: WidgetGroup? = null,
onDeactivation: ((Int, String, Float) -> Unit)? = null,
onActivation: ((Int, String) -> Unit)? = null
): Int {
// Build page descriptor and header button
val page = PageState(
caption = caption,
content = content ?: Group(),
fixedContent = fixedContent,
disabled = disabled,
onActivation = onActivation,
onDeactivation = onDeactivation,
icon = icon,
iconSize = iconSize,
shortcutKey = shortcutKey,
pager = this
)
page.button.apply {
@ -260,6 +307,7 @@ class TabbedPager(
onClick {
selectPage(page)
}
addTooltip(shortcutKey, if (iconSize > 0f) iconSize else 18f)
pack()
if (height + 2 * headerPadding > headerHeight) {
headerHeight = height + 2 * headerPadding
@ -310,6 +358,22 @@ class TabbedPager(
private fun getPageIndex(page: PageState) = pages.indexOf(page)
private fun measureContent(group: WidgetGroup) {
group.packIfNeeded()
var needLayout = false
val contentWidth = min(group.width, limitWidth)
if (contentWidth > preferredWidth) {
preferredWidth = contentWidth
needLayout = true
}
val contentHeight = min(group.height, limitHeight)
if (contentHeight > preferredHeight) {
preferredHeight = contentHeight
needLayout = true
}
if (needLayout && activePage >= 0) invalidateHierarchy()
}
private fun addAndShowPage(page: PageState, insertBefore: Int): Int {
// Update pages array and header table
val newIndex: Int
@ -330,23 +394,16 @@ class TabbedPager(
pages[i].buttonX += page.buttonW
// Content Sizing
if (page.content is WidgetGroup) {
(page.content as WidgetGroup).packIfNeeded()
val contentWidth = min(page.content.width, limitWidth)
if (contentWidth > preferredWidth) {
preferredWidth = contentWidth
if (activePage >= 0) invalidateHierarchy()
}
val contentHeight = min(page.content.height, limitHeight)
if (contentHeight > preferredHeight) {
preferredHeight = contentHeight
if (activePage >= 0) invalidateHierarchy()
}
if (page.fixedContent != null) measureContent(page.fixedContent!!)
(page.content as? WidgetGroup)?.let {
measureContent(it)
page.scrollX = -1f // mark to center later when all pages are measured
}
if (growMaxWidth) maximumWidth = minimumWidth
if (growMaxHeight) maximumHeight = minimumHeight
keyPressDispatcher?.set(page.shortcutKey) { selectPage(newIndex) }
return newIndex
}

View File

@ -13,13 +13,12 @@ import com.unciv.models.translations.tr
import com.unciv.models.metadata.GameSetupInfo
import com.unciv.models.ruleset.unique.UniqueType
import com.unciv.ui.newgamescreen.NewGameScreen
import com.unciv.ui.overviewscreen.EmpireOverviewScreen
import com.unciv.ui.pickerscreens.PickerScreen
import com.unciv.ui.utils.*
import com.unciv.ui.worldscreen.WorldScreen
class VictoryScreen(val worldScreen: WorldScreen) : PickerScreen() {
val gameInfo = worldScreen.gameInfo
private val playerCivInfo = worldScreen.viewingCiv
val victoryTypes = gameInfo.gameParameters.victoryTypes
@ -27,7 +26,6 @@ class VictoryScreen(val worldScreen: WorldScreen) : PickerScreen() {
private val culturalVictoryEnabled = victoryTypes.contains(VictoryType.Cultural)
private val dominationVictoryEnabled = victoryTypes.contains(VictoryType.Domination)
private val contentsTable = Table()
init {
@ -193,10 +191,10 @@ class VictoryScreen(val worldScreen: WorldScreen) : PickerScreen() {
dominationVictoryColumn.addSeparator()
for (civ in majorCivs.filter { !it.isDefeated() })
dominationVictoryColumn.add(EmpireOverviewScreen.getCivGroup(civ, "", playerCivInfo)).fillX().row()
dominationVictoryColumn.add(getCivGroup(civ, "", playerCivInfo)).fillX().row()
for (civ in majorCivs.filter { it.isDefeated() })
dominationVictoryColumn.add(EmpireOverviewScreen.getCivGroup(civ, "", playerCivInfo)).fillX().row()
dominationVictoryColumn.add(getCivGroup(civ, "", playerCivInfo)).fillX().row()
return dominationVictoryColumn
}
@ -213,7 +211,7 @@ class VictoryScreen(val worldScreen: WorldScreen) : PickerScreen() {
}.sortedByDescending { it.branchesCompleted }
for (entry in civsToBranchesCompleted) {
val civToBranchesHaveCompleted = EmpireOverviewScreen.getCivGroup(entry.civ, " - " + entry.branchesCompleted, playerCivInfo)
val civToBranchesHaveCompleted = getCivGroup(entry.civ, " - " + entry.branchesCompleted, playerCivInfo)
policyVictoryColumn.add(civToBranchesHaveCompleted).fillX().row()
}
return policyVictoryColumn
@ -232,7 +230,7 @@ class VictoryScreen(val worldScreen: WorldScreen) : PickerScreen() {
}
for (entry in civsToPartsRemaining) {
val civToPartsBeRemaining = (EmpireOverviewScreen.getCivGroup(entry.civ, " - " + entry.partsRemaining, playerCivInfo))
val civToPartsBeRemaining = (getCivGroup(entry.civ, " - " + entry.partsRemaining, playerCivInfo))
scientificVictoryColumn.add(civToPartsBeRemaining).fillX().row()
}
return scientificVictoryColumn
@ -248,7 +246,7 @@ class VictoryScreen(val worldScreen: WorldScreen) : PickerScreen() {
column.addSeparator()
for (civ in majorCivs.sortedByDescending { it.getStatForRanking(category) }) {
column.add(EmpireOverviewScreen.getCivGroup(civ, ": " + civ.getStatForRanking(category).toString(), playerCivInfo)).fillX().row()
column.add(getCivGroup(civ, ": " + civ.getStatForRanking(category).toString(), playerCivInfo)).fillX().row()
}
civRankingsTable.add(column)
@ -258,4 +256,36 @@ class VictoryScreen(val worldScreen: WorldScreen) : PickerScreen() {
contentsTable.add(civRankingsTable)
}
companion object {
fun getCivGroup(civ: CivilizationInfo, afterCivNameText:String, currentPlayer:CivilizationInfo): Table {
val civGroup = Table()
var labelText = civ.civName.tr()+afterCivNameText
var labelColor = Color.WHITE
val backgroundColor: Color
if (civ.isDefeated()) {
civGroup.add(ImageGetter.getImage("OtherIcons/DisbandUnit")).size(30f)
backgroundColor = Color.LIGHT_GRAY
labelColor = Color.BLACK
} else if (currentPlayer == civ // || game.viewEntireMapForDebug
|| currentPlayer.knows(civ) || currentPlayer.isDefeated() || currentPlayer.victoryManager.hasWon()) {
civGroup.add(ImageGetter.getNationIndicator(civ.nation, 30f))
backgroundColor = civ.nation.getOuterColor()
labelColor = civ.nation.getInnerColor()
} else {
civGroup.add(ImageGetter.getRandomNationIndicator(30f))
backgroundColor = Color.DARK_GRAY
labelText = Constants.unknownNationName
}
civGroup.background = ImageGetter.getRoundedEdgeRectangle(backgroundColor)
val label = labelText.toLabel(labelColor)
label.setAlignment(Align.center)
civGroup.add(label).padLeft(10f)
civGroup.pack()
return civGroup
}
}
}