Memory performance improvements!

- .tr() no longer tries to regex replace every entry in the dictionary - instead, we save the shortened version of each translation in its place!
 - when counting language completion percentage, we only count the numbers, not save them to a list!
 - label coloring and size now baked-in to .toLabel(). meaning we don't need to reassign styles and rebuild font caches!
This commit is contained in:
Yair Morgenstern 2019-10-31 12:01:23 +02:00
parent c39c1a4c15
commit de30382536
31 changed files with 161 additions and 138 deletions

View File

@ -4,19 +4,27 @@ import com.badlogic.gdx.utils.JsonReader
import com.unciv.UnCivGame import com.unciv.UnCivGame
import java.util.* import java.util.*
class Translations : HashMap<String, HashMap<String, String>>(){ class TranslationEntry(val entry:String) : HashMap<String, String>(){
/** For memory performance on .tr(), which was atrociously memory-expensive */
var entryWithShortenedSquareBrackets =""
}
class Translations : HashMap<String, TranslationEntry>(){
fun add(json:String){ fun add(json:String){
val jsonValue = JsonReader().parse(json)!! val jsonValue = JsonReader().parse(json)!!
var currentEntry = jsonValue.child var currentEntry = jsonValue.child
while(currentEntry!=null){ while(currentEntry!=null){
val entryMap = HashMap<String,String>() val currentEntryName = currentEntry.name!!
this[currentEntry.name!!]=entryMap val translationEntry = TranslationEntry(currentEntryName)
this[currentEntryName]=translationEntry
if(currentEntryName.contains('['))
translationEntry.entryWithShortenedSquareBrackets=currentEntryName.replace(squareBraceRegex,"[]")
var currentLanguage = currentEntry.child var currentLanguage = currentEntry.child
while(currentLanguage!=null){ while(currentLanguage!=null){
entryMap[currentLanguage.name!!]=currentLanguage.asString() translationEntry[currentLanguage.name!!]=currentLanguage.asString()
currentLanguage = currentLanguage.next currentLanguage = currentLanguage.next
} }
currentEntry = currentEntry.next currentEntry = currentEntry.next
@ -35,7 +43,7 @@ class Translations : HashMap<String, HashMap<String, String>>(){
fun getLanguages(): List<String> { fun getLanguages(): List<String> {
val toReturn = mutableListOf<String>() val toReturn = mutableListOf<String>()
toReturn.addAll(values.flatMap { it.keys }.distinct()) toReturn.addAll(values.flatMap { it.keys }.distinct())
toReturn.remove("Japanese") toReturn.remove("Japanese") // These were for tests but were never actually seriously translated
toReturn.remove("Thai") toReturn.remove("Thai")
return toReturn return toReturn
} }
@ -56,7 +64,12 @@ class Translations : HashMap<String, HashMap<String, String>>(){
} }
val squareBraceRegex = Regex("\\[(.*?)\\]") // we don't need to allocate different memory for this every time we .tr() val squareBraceRegex = Regex("\\[(.*?)\\]") // we don't need to allocate different memory for this every time we .tr()
val eitherSquareBraceRegex=Regex("\\[|\\]")
fun String.tr(): String { fun String.tr(): String {
// THIS IS INCREDIBLY INEFFICIENT and causes loads of memory problems!
if(contains("[")){ // Placeholders! if(contains("[")){ // Placeholders!
/** /**
* I'm SURE there's an easier way to do this but I can't think of it =\ * I'm SURE there's an easier way to do this but I can't think of it =\
@ -64,7 +77,7 @@ fun String.tr(): String {
* Well, not all languages are like English. So say I want to say "work on Library has completed in Akkad", * Well, not all languages are like English. So say I want to say "work on Library has completed in Akkad",
* but in a completely different language like Japanese or German, * but in a completely different language like Japanese or German,
* It could come out "Akkad hast die worken onner Library gerfinishen" or whatever, * It could come out "Akkad hast die worken onner Library gerfinishen" or whatever,
* basically, the order of the words in the sentance is not guaranteed. * basically, the order of the words in the sentence is not guaranteed.
* So to translate this, I give a sentence like "work on [building] has completed in [city]" * So to translate this, I give a sentence like "work on [building] has completed in [city]"
* and the german can put those placeholders where he wants, so "[city] hast die worken onner [building] gerfinishen" * and the german can put those placeholders where he wants, so "[city] hast die worken onner [building] gerfinishen"
* The string on which we call tr() will look like "work on [library] has completed in [Akkad]" * The string on which we call tr() will look like "work on [library] has completed in [Akkad]"
@ -72,32 +85,32 @@ fun String.tr(): String {
*/ */
val translationStringWithSquareBracketsOnly = replace(squareBraceRegex,"[]") val translationStringWithSquareBracketsOnly = replace(squareBraceRegex,"[]")
val translationStringUntilFirstSquareBracket = substringBefore('[')
val englishTranslationPlaceholder = GameBasics.Translations.keys val translationEntry = GameBasics.Translations.values
.firstOrNull { .firstOrNull { translationStringWithSquareBracketsOnly == it.entryWithShortenedSquareBrackets }
// this is to filter out obvious non-candidates, which is most of them, before we start using the "heavy lifting" of the regex replacement
it.startsWith(translationStringUntilFirstSquareBracket) if(translationEntry==null ||
&& it.replace(squareBraceRegex,"[]") == translationStringWithSquareBracketsOnly } !translationEntry.containsKey(UnCivGame.Current.settings.language)){
if(englishTranslationPlaceholder==null || // Translation placeholder doesn't exist for this language, default to English
!GameBasics.Translations[englishTranslationPlaceholder]!!.containsKey(UnCivGame.Current.settings.language)){ return this.replace(eitherSquareBraceRegex,"")
// Translation placeholder doesn't exist for this language
return this.replace("[","").replace("]","")
} }
val termsInMessage = squareBraceRegex.findAll(this).map { it.groups[1]!!.value }.toMutableList() val termsInMessage = squareBraceRegex.findAll(this).map { it.groups[1]!!.value }.toList()
val termsInTranslationPlaceholder = squareBraceRegex.findAll(englishTranslationPlaceholder).map { it.value }.toMutableList() val termsInTranslationPlaceholder = squareBraceRegex.findAll(translationEntry.entry).map { it.value }.toList()
if(termsInMessage.size!=termsInTranslationPlaceholder.size) if(termsInMessage.size!=termsInTranslationPlaceholder.size)
throw Exception("Message $this has a different number of terms than the placeholder $englishTranslationPlaceholder!") throw Exception("Message $this has a different number of terms than the placeholder $translationEntry!")
var languageSpecificPlaceholder = GameBasics.Translations[englishTranslationPlaceholder]!![UnCivGame.Current.settings.language]!! var languageSpecificPlaceholder = translationEntry[UnCivGame.Current.settings.language]!!
for(i in 0 until termsInMessage.size){ for(i in termsInMessage.indices){
languageSpecificPlaceholder = languageSpecificPlaceholder.replace(termsInTranslationPlaceholder[i], termsInMessage[i].tr()) languageSpecificPlaceholder = languageSpecificPlaceholder.replace(termsInTranslationPlaceholder[i], termsInMessage[i].tr())
} }
return languageSpecificPlaceholder.tr() return languageSpecificPlaceholder.tr()
} }
if(contains("{")){ // sentence if(contains("{")){ // sentence
return Regex("\\{(.*?)\\}").replace(this) { it.groups[1]!!.value.tr() } return Regex("\\{(.*?)\\}").replace(this) { it.groups[1]!!.value.tr() }
} }
val translation = GameBasics.Translations.get(this, UnCivGame.Current.settings.language) // single word val translation = GameBasics.Translations.get(this, UnCivGame.Current.settings.language) // single word
return translation return translation
} }

View File

@ -123,11 +123,11 @@ class EmpireOverviewScreen : CameraStageBaseScreen(){
val table = Table() val table = Table()
table.defaults().pad(10f) table.defaults().pad(10f)
table.background = ImageGetter.getBackground(civ.nation.getOuterColor()) table.background = ImageGetter.getBackground(civ.nation.getOuterColor())
table.add(civ.civName.toLabel().setFontColor(civ.nation.getInnerColor())).row() table.add(civ.civName.toLabel(civ.nation.getInnerColor())).row()
table.addSeparator() table.addSeparator()
for(offer in offersList){ for(offer in offersList){
val offerText = offer.getOfferText() val offerText = offer.getOfferText()
table.add(offerText.toLabel().setFontColor(civ.nation.getInnerColor())).row() table.add(offerText.toLabel(civ.nation.getInnerColor())).row()
} }
for(i in 1..numberOfOtherSidesOffers - offersList.size) for(i in 1..numberOfOtherSidesOffers - offersList.size)
table.add("".toLabel()).row() // we want both sides of the general table to have the same number of rows table.add("".toLabel()).row() // we want both sides of the general table to have the same number of rows
@ -138,7 +138,7 @@ class EmpireOverviewScreen : CameraStageBaseScreen(){
private fun getHappinessTable(): Table { private fun getHappinessTable(): Table {
val happinessTable = Table(skin) val happinessTable = Table(skin)
happinessTable.defaults().pad(5f) happinessTable.defaults().pad(5f)
happinessTable.add("Happiness".toLabel().setFontSize(24)).colspan(2).row() happinessTable.add("Happiness".toLabel(fontSize = 24)).colspan(2).row()
happinessTable.addSeparator() happinessTable.addSeparator()
val happinessBreakdown = currentPlayerCivInfo.stats().getHappinessBreakdown() val happinessBreakdown = currentPlayerCivInfo.stats().getHappinessBreakdown()
@ -156,7 +156,7 @@ class EmpireOverviewScreen : CameraStageBaseScreen(){
private fun getGoldTable(): Table { private fun getGoldTable(): Table {
val goldTable = Table(skin) val goldTable = Table(skin)
goldTable.defaults().pad(5f) goldTable.defaults().pad(5f)
goldTable.add("Gold".toLabel().setFontSize(24)).colspan(2).row() goldTable.add("Gold".toLabel(fontSize = 24)).colspan(2).row()
goldTable.addSeparator() goldTable.addSeparator()
var total=0f var total=0f
for (entry in currentPlayerCivInfo.stats().getStatMapForNextTurn()) { for (entry in currentPlayerCivInfo.stats().getStatMapForNextTurn()) {
@ -175,7 +175,7 @@ class EmpireOverviewScreen : CameraStageBaseScreen(){
private fun getScienceTable(): Table { private fun getScienceTable(): Table {
val scienceTable = Table(skin) val scienceTable = Table(skin)
scienceTable.defaults().pad(5f) scienceTable.defaults().pad(5f)
scienceTable.add("Science".toLabel().setFontSize(24)).colspan(2).row() scienceTable.add("Science".toLabel(fontSize = 24)).colspan(2).row()
scienceTable.addSeparator() scienceTable.addSeparator()
val scienceStats = currentPlayerCivInfo.stats().getStatMapForNextTurn() val scienceStats = currentPlayerCivInfo.stats().getStatMapForNextTurn()
.filter { it.value.science!=0f } .filter { it.value.science!=0f }
@ -198,7 +198,7 @@ class EmpireOverviewScreen : CameraStageBaseScreen(){
val pointsToGreatPerson = currentPlayerCivInfo.greatPeople.pointsForNextGreatPerson val pointsToGreatPerson = currentPlayerCivInfo.greatPeople.pointsForNextGreatPerson
greatPeopleTable.defaults().pad(5f) greatPeopleTable.defaults().pad(5f)
greatPeopleTable.add("Great person points".toLabel().setFontSize(24)).colspan(3).row() greatPeopleTable.add("Great person points".toLabel(fontSize = 24)).colspan(3).row()
greatPeopleTable.addSeparator() greatPeopleTable.addSeparator()
greatPeopleTable.add() greatPeopleTable.add()
greatPeopleTable.add("Current points".tr()) greatPeopleTable.add("Current points".tr())
@ -227,7 +227,7 @@ class EmpireOverviewScreen : CameraStageBaseScreen(){
val cityInfoTableIcons = Table(skin) val cityInfoTableIcons = Table(skin)
cityInfoTableIcons.defaults().pad(padding).align(Align.center) cityInfoTableIcons.defaults().pad(padding).align(Align.center)
cityInfoTableIcons.add("Cities".toLabel().setFontSize(24)).colspan(8).align(Align.center).row() cityInfoTableIcons.add("Cities".toLabel(fontSize = 24)).colspan(8).align(Align.center).row()
cityInfoTableIcons.add() cityInfoTableIcons.add()
cityInfoTableIcons.add(ImageGetter.getStatIcon("Population")).size(iconSize) cityInfoTableIcons.add(ImageGetter.getStatIcon("Population")).size(iconSize)
cityInfoTableIcons.add(ImageGetter.getStatIcon("Food")).size(iconSize) cityInfoTableIcons.add(ImageGetter.getStatIcon("Food")).size(iconSize)
@ -406,23 +406,25 @@ class EmpireOverviewScreen : CameraStageBaseScreen(){
val civGroup = Table() val civGroup = Table()
val civGroupBackground = ImageGetter.getDrawable("OtherIcons/civTableBackground") val civGroupBackground = ImageGetter.getDrawable("OtherIcons/civTableBackground")
val civNameText = civ.civName.tr()+afterCivNameText var labelText = civ.civName.tr()+afterCivNameText
val label = civNameText.toLabel() var labelColor=Color.WHITE
label.setAlignment(Align.center)
if (civ.isDefeated()) { if (civ.isDefeated()) {
civGroup.add(ImageGetter.getImage("OtherIcons/DisbandUnit")).size(30f) civGroup.add(ImageGetter.getImage("OtherIcons/DisbandUnit")).size(30f)
civGroup.background = civGroupBackground.tint(Color.LIGHT_GRAY) civGroup.background = civGroupBackground.tint(Color.LIGHT_GRAY)
label.setFontColor(Color.BLACK) labelColor = Color.BLACK
} else if (currentPlayer==civ || UnCivGame.Current.viewEntireMapForDebug || currentPlayer.knows(civ)) { } else if (currentPlayer==civ || UnCivGame.Current.viewEntireMapForDebug || currentPlayer.knows(civ)) {
civGroup.add(ImageGetter.getNationIndicator(civ.nation, 30f)) civGroup.add(ImageGetter.getNationIndicator(civ.nation, 30f))
civGroup.background = civGroupBackground.tint(civ.nation.getOuterColor()) civGroup.background = civGroupBackground.tint(civ.nation.getOuterColor())
label.setFontColor(civ.nation.getInnerColor()) labelColor = civ.nation.getInnerColor()
} else { } else {
civGroup.background = civGroupBackground.tint(Color.DARK_GRAY) civGroup.background = civGroupBackground.tint(Color.DARK_GRAY)
label.setText("???") labelText = "???"
} }
val label = labelText.toLabel(labelColor)
label.setAlignment(Align.center)
civGroup.add(label).pad(10f) civGroup.add(label).pad(10f)
civGroup.pack() civGroup.pack()
return civGroup return civGroup

View File

@ -43,7 +43,7 @@ class CityInfoTable(private val cityScreen: CityScreen) : Table(CameraStageBaseS
val width = cityScreen.stage.width/4 - 2*pad val width = cityScreen.stage.width/4 - 2*pad
val showHideTableWrapper = Table() val showHideTableWrapper = Table()
showHideTableWrapper.add(showHideTable).width(width) showHideTableWrapper.add(showHideTable).width(width)
titleTable.add(str.toLabel().setFontSize(24)) titleTable.add(str.toLabel(fontSize = 24))
titleTable.onClick { titleTable.onClick {
if(showHideTableWrapper.hasChildren()) showHideTableWrapper.clear() if(showHideTableWrapper.hasChildren()) showHideTableWrapper.clear()
else showHideTableWrapper.add(showHideTable).width(width) else showHideTableWrapper.add(showHideTable).width(width)
@ -147,7 +147,7 @@ class CityInfoTable(private val cityScreen: CityScreen) : Table(CameraStageBaseS
val statValuesTable = Table().apply { defaults().pad(2f) } val statValuesTable = Table().apply { defaults().pad(2f) }
addCategory(stat.name, statValuesTable) addCategory(stat.name, statValuesTable)
statValuesTable.add("Base values".toLabel().setFontSize(24)).colspan(2).row() statValuesTable.add("Base values".toLabel(fontSize= 24)).colspan(2).row()
var sumOfAllBaseValues = 0f var sumOfAllBaseValues = 0f
for(entry in relevantBaseStats) { for(entry in relevantBaseStats) {
val specificStatValue = entry.value.get(stat) val specificStatValue = entry.value.get(stat)
@ -161,7 +161,7 @@ class CityInfoTable(private val cityScreen: CityScreen) : Table(CameraStageBaseS
val relevantBonuses = cityStats.statPercentBonusList.filter { it.value.get(stat)!=0f } val relevantBonuses = cityStats.statPercentBonusList.filter { it.value.get(stat)!=0f }
if(relevantBonuses.isNotEmpty()) { if(relevantBonuses.isNotEmpty()) {
statValuesTable.add("Bonuses".toLabel().setFontSize(24)).colspan(2).padTop(20f).row() statValuesTable.add("Bonuses".toLabel(fontSize = 24)).colspan(2).padTop(20f).row()
var sumOfBonuses = 0f var sumOfBonuses = 0f
for (entry in relevantBonuses) { for (entry in relevantBonuses) {
val specificStatValue = entry.value.get(stat) val specificStatValue = entry.value.get(stat)
@ -179,7 +179,7 @@ class CityInfoTable(private val cityScreen: CityScreen) : Table(CameraStageBaseS
} }
statValuesTable.add("Final".toLabel().setFontSize(24)).colspan(2).padTop(20f).row() statValuesTable.add("Final".toLabel(fontSize = 24)).colspan(2).padTop(20f).row()
var finalTotal = 0f var finalTotal = 0f
for (entry in cityStats.finalStatList) { for (entry in cityStats.finalStatList) {
val specificStatValue = entry.value.get(stat) val specificStatValue = entry.value.get(stat)

View File

@ -4,10 +4,7 @@ import com.badlogic.gdx.graphics.Color
import com.badlogic.gdx.scenes.scene2d.ui.* import com.badlogic.gdx.scenes.scene2d.ui.*
import com.badlogic.gdx.utils.Align import com.badlogic.gdx.utils.Align
import com.unciv.models.gamebasics.tr import com.unciv.models.gamebasics.tr
import com.unciv.ui.utils.CameraStageBaseScreen import com.unciv.ui.utils.*
import com.unciv.ui.utils.ImageGetter
import com.unciv.ui.utils.onClick
import com.unciv.ui.utils.setFontSize
import com.unciv.ui.worldscreen.optionstable.PopupTable import com.unciv.ui.worldscreen.optionstable.PopupTable
class CityScreenCityPickerTable(val cityScreen: CityScreen) : Table(){ class CityScreenCityPickerTable(val cityScreen: CityScreen) : Table(){
@ -49,8 +46,7 @@ class CityScreenCityPickerTable(val cityScreen: CityScreen) : Table(){
cityNameTable.add(resistanceImage).size(20f).padRight(5f) cityNameTable.add(resistanceImage).size(20f).padRight(5f)
} }
val currentCityLabel = Label(city.name, CameraStageBaseScreen.skin) val currentCityLabel = city.name.toLabel(fontSize = 30)
currentCityLabel.setFontSize(30)
currentCityLabel.onClick { currentCityLabel.onClick {
val editCityNamePopup = PopupTable(cityScreen) val editCityNamePopup = PopupTable(cityScreen)
val textArea = TextField(city.name, CameraStageBaseScreen.skin) val textArea = TextField(city.name, CameraStageBaseScreen.skin)

View File

@ -46,7 +46,7 @@ class ConstructionsTable(val cityScreen: CityScreen) : Table(CameraStageBaseScre
pickProductionButton.background = ImageGetter.getBackground(Color.BLACK) pickProductionButton.background = ImageGetter.getBackground(Color.BLACK)
pickProductionButton.add(ImageGetter.getConstructionImage(construction).surroundWithCircle(40f)).padRight(10f) pickProductionButton.add(ImageGetter.getConstructionImage(construction).surroundWithCircle(40f)).padRight(10f)
pickProductionButton.add(buttonText.toLabel().setFontColor(Color.WHITE)) pickProductionButton.add(buttonText.toLabel())
if(rejectionReason=="" && UnCivGame.Current.worldScreen.isPlayersTurn) { // no rejection reason means we can build it! if(rejectionReason=="" && UnCivGame.Current.worldScreen.isPlayersTurn) { // no rejection reason means we can build it!
pickProductionButton.onClick { pickProductionButton.onClick {
@ -63,7 +63,7 @@ class ConstructionsTable(val cityScreen: CityScreen) : Table(CameraStageBaseScre
else { else {
pickProductionButton.color = Color.GRAY pickProductionButton.color = Color.GRAY
pickProductionButton.row() pickProductionButton.row()
pickProductionButton.add(rejectionReason.toLabel().setFontColor(Color.RED)).colspan(pickProductionButton.columns) pickProductionButton.add(rejectionReason.toLabel(Color.RED)).colspan(pickProductionButton.columns)
} }
if(construction==cityScreen.city.cityConstructions.currentConstruction) if(construction==cityScreen.city.cityConstructions.currentConstruction)
@ -75,7 +75,7 @@ class ConstructionsTable(val cityScreen: CityScreen) : Table(CameraStageBaseScre
if(list.isEmpty()) return if(list.isEmpty()) return
val titleTable = Table() val titleTable = Table()
titleTable.background = ImageGetter.getBackground(ImageGetter.getBlue()) titleTable.background = ImageGetter.getBackground(ImageGetter.getBlue())
titleTable.add(title.toLabel().setFontSize(24)) titleTable.add(title.toLabel(fontSize = 24))
addSeparator() addSeparator()
add(titleTable).fill().row() add(titleTable).fill().row()
@ -185,7 +185,7 @@ class ConstructionsTable(val cityScreen: CityScreen) : Table(CameraStageBaseScre
.pad(5f) .pad(5f)
val buildingText = city.cityConstructions.getCityProductionTextForCityButton() val buildingText = city.cityConstructions.getCityProductionTextForCityButton()
currentConstructionTable.add(buildingText.toLabel().setFontColor(Color.WHITE)).row() currentConstructionTable.add(buildingText.toLabel()).row()
} }
else{ else{
currentConstructionTable.add() // no icon currentConstructionTable.add() // no icon

View File

@ -5,7 +5,7 @@ import com.badlogic.gdx.scenes.scene2d.ui.Skin
import com.badlogic.gdx.scenes.scene2d.ui.Table import com.badlogic.gdx.scenes.scene2d.ui.Table
import com.unciv.ui.utils.ImageGetter import com.unciv.ui.utils.ImageGetter
import com.unciv.ui.utils.onClick import com.unciv.ui.utils.onClick
import com.unciv.ui.utils.setFontSize import com.unciv.ui.utils.toLabel
class ExpanderTab(private val title:String,skin: Skin): Table(skin){ class ExpanderTab(private val title:String,skin: Skin): Table(skin){
private val toggle = Table(skin) // the show/hide toggler private val toggle = Table(skin) // the show/hide toggler
@ -17,7 +17,7 @@ class ExpanderTab(private val title:String,skin: Skin): Table(skin){
toggle.defaults().pad(10f) toggle.defaults().pad(10f)
toggle.touchable= Touchable.enabled toggle.touchable= Touchable.enabled
toggle.background(ImageGetter.getBackground(ImageGetter.getBlue())) toggle.background(ImageGetter.getBackground(ImageGetter.getBlue()))
toggle.add("+ $title").apply { actor.setFontSize(24) } toggle.add("+ $title".toLabel(fontSize = 24))
toggle.onClick { toggle.onClick {
if(isOpen) close() if(isOpen) close()
else open() else open()
@ -30,7 +30,7 @@ class ExpanderTab(private val title:String,skin: Skin): Table(skin){
fun close(){ fun close(){
if(!isOpen) return if(!isOpen) return
toggle.clearChildren() toggle.clearChildren()
toggle.add("- $title").apply { actor.setFontSize(24) } toggle.add("- $title".toLabel(fontSize = 24))
tab.clear() tab.clear()
isOpen=false isOpen=false
} }
@ -38,7 +38,7 @@ class ExpanderTab(private val title:String,skin: Skin): Table(skin){
fun open(){ fun open(){
if(isOpen) return if(isOpen) return
toggle.clearChildren() toggle.clearChildren()
toggle.add("+ $title").apply { actor.setFontSize(24) } toggle.add("+ $title".toLabel(fontSize = 24))
tab.add(innerTable) tab.add(innerTable)
isOpen=true isOpen=true
} }

View File

@ -7,7 +7,10 @@ import com.unciv.models.gamebasics.GameBasics
import com.unciv.models.gamebasics.Nation import com.unciv.models.gamebasics.Nation
import com.unciv.models.gamebasics.Translations import com.unciv.models.gamebasics.Translations
import com.unciv.models.gamebasics.tr import com.unciv.models.gamebasics.tr
import com.unciv.ui.utils.* import com.unciv.ui.utils.CameraStageBaseScreen
import com.unciv.ui.utils.ImageGetter
import com.unciv.ui.utils.onClick
import com.unciv.ui.utils.toLabel
class NationTable(val nation: Nation, width:Float, onClick:()->Unit) class NationTable(val nation: Nation, width:Float, onClick:()->Unit)
: Table(CameraStageBaseScreen.skin) { : Table(CameraStageBaseScreen.skin) {
@ -20,13 +23,10 @@ class NationTable(val nation: Nation, width:Float, onClick:()->Unit)
val titleTable = Table() val titleTable = Table()
titleTable.add(ImageGetter.getNationIndicator(nation, 50f)).pad(10f) titleTable.add(ImageGetter.getNationIndicator(nation, 50f)).pad(10f)
titleTable.add(nation.getLeaderDisplayName().toLabel() titleTable.add(nation.getLeaderDisplayName().toLabel(nation.getInnerColor(),24))
.apply { setFontColor(nation.getInnerColor()); setFontSize(24) })
innerTable.add(titleTable).row() innerTable.add(titleTable).row()
innerTable.add(getUniqueLabel(nation) innerTable.add(getUniqueLabel(nation).apply { setWrap(true) }).width(width)
.apply { setWrap(true);setFontColor(nation.getInnerColor()) })
.width(width)
onClick { onClick() } onClick { onClick() }
touchable = Touchable.enabled touchable = Touchable.enabled
add(innerTable) add(innerTable)
@ -44,7 +44,7 @@ class NationTable(val nation: Nation, width:Float, onClick:()->Unit)
addUniqueUnitsText(nation, textList) addUniqueUnitsText(nation, textList)
addUniqueImprovementsText(nation, textList) addUniqueImprovementsText(nation, textList)
return textList.joinToString("\n").tr().trim().toLabel() return textList.joinToString("\n").tr().trim().toLabel(nation.getInnerColor())
} }
private fun addUniqueBuildingsText(nation: Nation, textList: ArrayList<String>) { private fun addUniqueBuildingsText(nation: Nation, textList: ArrayList<String>) {

View File

@ -33,8 +33,8 @@ class PlayerPickerTable(val newGameScreen: NewGameScreen, val newGameParameters:
for (player in newGameParameters.players) for (player in newGameParameters.players)
playerListTable.add(getPlayerTable(player)).pad(10f).row() playerListTable.add(getPlayerTable(player)).pad(10f).row()
if(newGameParameters.players.count() < GameBasics.Nations.values.count { it.isMajorCiv() }) { if(newGameParameters.players.count() < GameBasics.Nations.values.count { it.isMajorCiv() }) {
playerListTable.add("+".toLabel().setFontSize(30).apply { this.setAlignment(Align.center) } playerListTable.add("+".toLabel(Color.BLACK,30).apply { this.setAlignment(Align.center) }
.setFontColor(Color.BLACK).surroundWithCircle(50f).onClick { newGameParameters.players.add(Player()); update() }) .surroundWithCircle(50f).onClick { newGameParameters.players.add(Player()); update() })
} }
} }
@ -62,7 +62,7 @@ class PlayerPickerTable(val newGameScreen: NewGameScreen, val newGameParameters:
val playerIdTextfield = TextField(player.playerId, CameraStageBaseScreen.skin) val playerIdTextfield = TextField(player.playerId, CameraStageBaseScreen.skin)
playerIdTable.add(playerIdTextfield).colspan(2) playerIdTable.add(playerIdTextfield).colspan(2)
val errorLabel = "Not a valid user id!".toLabel().setFontColor(Color.RED) val errorLabel = "Not a valid user id!".toLabel(Color.RED)
errorLabel.isVisible=false errorLabel.isVisible=false
playerIdTable.add(errorLabel) playerIdTable.add(errorLabel)
@ -103,9 +103,9 @@ class PlayerPickerTable(val newGameScreen: NewGameScreen, val newGameParameters:
private fun getNationTable(player: Player): Table { private fun getNationTable(player: Player): Table {
val nationTable = Table() val nationTable = Table()
val nationImage = if (player.chosenCiv == "Random") "?".toLabel() val nationImage = if (player.chosenCiv == "Random") "?".toLabel(Color.BLACK,30)
.apply { this.setAlignment(Align.center) }.setFontSize(30) .apply { this.setAlignment(Align.center) }
.setFontColor(Color.BLACK).surroundWithCircle(50f) .surroundWithCircle(50f)
else ImageGetter.getNationIndicator(GameBasics.Nations[player.chosenCiv]!!, 50f) else ImageGetter.getNationIndicator(GameBasics.Nations[player.chosenCiv]!!, 50f)
nationTable.add(nationImage) nationTable.add(nationImage)
nationTable.add(player.chosenCiv.toLabel()).pad(20f) nationTable.add(player.chosenCiv.toLabel()).pad(20f)

View File

@ -1,6 +1,5 @@
package com.unciv.ui.pickerscreens package com.unciv.ui.pickerscreens
import com.badlogic.gdx.graphics.Color
import com.badlogic.gdx.scenes.scene2d.ui.Button import com.badlogic.gdx.scenes.scene2d.ui.Button
import com.unciv.UnCivGame import com.unciv.UnCivGame
import com.unciv.logic.civilization.GreatPersonManager import com.unciv.logic.civilization.GreatPersonManager
@ -9,7 +8,6 @@ import com.unciv.models.gamebasics.tr
import com.unciv.models.gamebasics.unit.BaseUnit import com.unciv.models.gamebasics.unit.BaseUnit
import com.unciv.ui.utils.ImageGetter import com.unciv.ui.utils.ImageGetter
import com.unciv.ui.utils.onClick import com.unciv.ui.utils.onClick
import com.unciv.ui.utils.setFontColor
import com.unciv.ui.utils.toLabel import com.unciv.ui.utils.toLabel
class GreatPersonPickerScreen : PickerScreen() { class GreatPersonPickerScreen : PickerScreen() {
@ -24,11 +22,11 @@ class GreatPersonPickerScreen : PickerScreen() {
val button = Button(skin) val button = Button(skin)
button.add(ImageGetter.getUnitIcon(unit.name)).size(30f).pad(10f) button.add(ImageGetter.getUnitIcon(unit.name)).size(30f).pad(10f)
button.add(unit.name.toLabel().setFontColor(Color.WHITE)).pad(10f) button.add(unit.name.toLabel()).pad(10f)
button.pack() button.pack()
button.onClick { button.onClick {
theChosenOne = unit theChosenOne = unit
var unitDescription=HashSet<String>() val unitDescription=HashSet<String>()
unit.uniques.forEach { unitDescription.add(it.tr()) } unit.uniques.forEach { unitDescription.add(it.tr()) }
pick("Get ".tr() +unit.name.tr()) pick("Get ".tr() +unit.name.tr())
descriptionLabel.setText(unitDescription.joinToString()) descriptionLabel.setText(unitDescription.joinToString())

View File

@ -58,7 +58,7 @@ class ImprovementPickerScreen(tileInfo: TileInfo, onAccept: ()->Unit) : PickerSc
&& improvement.name!=RoadStatus.Railroad.name && !improvement.name.startsWith("Remove")) && improvement.name!=RoadStatus.Railroad.name && !improvement.name.startsWith("Remove"))
labelText += "\n" + "Replaces [${tileInfo.improvement}]".tr() labelText += "\n" + "Replaces [${tileInfo.improvement}]".tr()
group.add(labelText.toLabel().setFontColor(Color.WHITE)).pad(10f) group.add(labelText.toLabel()).pad(10f)
group.touchable = Touchable.enabled group.touchable = Touchable.enabled
group.onClick { group.onClick {

View File

@ -51,8 +51,7 @@ class PromotionPickerScreen(val mapUnit: MapUnit) : PickerScreen() {
val group = Table() val group = Table()
group.add(ImageGetter.getPromotionIcon(promotion.name)).size(30f).pad(10f) group.add(ImageGetter.getPromotionIcon(promotion.name)).size(30f).pad(10f)
group.add(promotion.name.toLabel() group.add(promotion.name.toLabel()).pad(10f).padRight(20f)
.setFontColor(Color.WHITE)).pad(10f).padRight(20f)
group.touchable = Touchable.enabled group.touchable = Touchable.enabled
group.onClick { group.onClick {

View File

@ -2,18 +2,17 @@ package com.unciv.ui.pickerscreens
import com.badlogic.gdx.graphics.Color import com.badlogic.gdx.graphics.Color
import com.badlogic.gdx.scenes.scene2d.Touchable import com.badlogic.gdx.scenes.scene2d.Touchable
import com.badlogic.gdx.scenes.scene2d.ui.Label
import com.badlogic.gdx.scenes.scene2d.ui.Table import com.badlogic.gdx.scenes.scene2d.ui.Table
import com.badlogic.gdx.utils.Align import com.badlogic.gdx.utils.Align
import com.unciv.logic.civilization.TechManager import com.unciv.logic.civilization.TechManager
import com.unciv.models.gamebasics.GameBasics import com.unciv.models.gamebasics.GameBasics
import com.unciv.ui.utils.CameraStageBaseScreen import com.unciv.ui.utils.CameraStageBaseScreen
import com.unciv.ui.utils.ImageGetter import com.unciv.ui.utils.ImageGetter
import com.unciv.ui.utils.setFontColor
import com.unciv.ui.utils.surroundWithCircle import com.unciv.ui.utils.surroundWithCircle
import com.unciv.ui.utils.toLabel
class TechButton(techName:String, val techManager: TechManager, isWorldScreen: Boolean = true) : Table(CameraStageBaseScreen.skin) { class TechButton(techName:String, val techManager: TechManager, isWorldScreen: Boolean = true) : Table(CameraStageBaseScreen.skin) {
val text= Label("", skin).setFontColor(Color.WHITE).apply { setAlignment(Align.center) } val text= "".toLabel().apply { setAlignment(Align.center) }
init { init {
touchable = Touchable.enabled touchable = Touchable.enabled

View File

@ -55,8 +55,8 @@ class TechPickerScreen(internal val civInfo: CivilizationInfo, switchfromWorldSc
val erasName = arrayOf("Ancient","Classical","Medieval","Renaissance","Industrial","Modern","Information","Future") val erasName = arrayOf("Ancient","Classical","Medieval","Renaissance","Industrial","Modern","Information","Future")
for (i in 0..7) { for (i in 0..7) {
val j = if (erasName[i]!="Ancient" && erasName[i]!="Future") 2 else 3 val j = if (erasName[i]!="Ancient" && erasName[i]!="Future") 2 else 3
if (i%2==0) topTable.add((erasName[i]+" era").toLabel().setFontColor(Color.WHITE).addBorder(2f, Color.BLUE)).fill().colspan(j) if (i%2==0) topTable.add((erasName[i]+" era").toLabel().addBorder(2f, Color.BLUE)).fill().colspan(j)
else topTable.add((erasName[i]+" era").toLabel().setFontColor(Color.WHITE).addBorder(2f, Color.FIREBRICK)).fill().colspan(j) else topTable.add((erasName[i]+" era").toLabel().addBorder(2f, Color.FIREBRICK)).fill().colspan(j)
} }
// Create tech table (row by row) // Create tech table (row by row)

View File

@ -12,7 +12,10 @@ import com.unciv.UnCivGame
import com.unciv.logic.GameSaver import com.unciv.logic.GameSaver
import com.unciv.models.gamebasics.tr import com.unciv.models.gamebasics.tr
import com.unciv.ui.pickerscreens.PickerScreen import com.unciv.ui.pickerscreens.PickerScreen
import com.unciv.ui.utils.* import com.unciv.ui.utils.disable
import com.unciv.ui.utils.enable
import com.unciv.ui.utils.onClick
import com.unciv.ui.utils.toLabel
import com.unciv.ui.worldscreen.optionstable.PopupTable import com.unciv.ui.worldscreen.optionstable.PopupTable
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.* import java.util.*
@ -54,7 +57,7 @@ class LoadGameScreen : PickerScreen() {
private fun getRightSideTable(): Table { private fun getRightSideTable(): Table {
val rightSideTable = Table() val rightSideTable = Table()
val errorLabel = "".toLabel().setFontColor(Color.RED) val errorLabel = "".toLabel(Color.RED)
val loadFromClipboardButton = TextButton("Load copied data".tr(), skin) val loadFromClipboardButton = TextButton("Load copied data".tr(), skin)
loadFromClipboardButton.onClick { loadFromClipboardButton.onClick {
try { try {

View File

@ -40,7 +40,7 @@ class LoadMapScreen(previousMap: TileMap) : PickerScreen(){
val rightSideTable = Table().apply { defaults().pad(10f) } val rightSideTable = Table().apply { defaults().pad(10f) }
val loadFromClipboardButton = TextButton("Load copied data".tr(), skin) val loadFromClipboardButton = TextButton("Load copied data".tr(), skin)
val couldNotLoadMapLabel = "Could not load map!".toLabel().setFontColor(Color.RED).apply { isVisible=false } val couldNotLoadMapLabel = "Could not load map!".toLabel(Color.RED).apply { isVisible=false }
loadFromClipboardButton.onClick { loadFromClipboardButton.onClick {
try { try {
val clipboardContentsString = Gdx.app.clipboard.contents.trim() val clipboardContentsString = Gdx.app.clipboard.contents.trim()

View File

@ -44,7 +44,7 @@ class CityButton(val city: CityInfo, internal val tileGroup: WorldTileGroup, ski
} }
private fun addAirUnitTable() { private fun addAirUnitTable() {
if (!tileGroup.tileInfo.airUnits.isNotEmpty()) return if (tileGroup.tileInfo.airUnits.isEmpty()) return
val secondarycolor = city.civInfo.nation.getInnerColor() val secondarycolor = city.civInfo.nation.getInnerColor()
val airUnitTable = Table().apply { defaults().pad(5f) } val airUnitTable = Table().apply { defaults().pad(5f) }
airUnitTable.background = ImageGetter.getDrawable("OtherIcons/civTableBackground") airUnitTable.background = ImageGetter.getDrawable("OtherIcons/civTableBackground")
@ -52,8 +52,7 @@ class CityButton(val city: CityInfo, internal val tileGroup: WorldTileGroup, ski
val aircraftImage = ImageGetter.getImage("OtherIcons/Aircraft") val aircraftImage = ImageGetter.getImage("OtherIcons/Aircraft")
aircraftImage.color = secondarycolor aircraftImage.color = secondarycolor
airUnitTable.add(aircraftImage).size(15f) airUnitTable.add(aircraftImage).size(15f)
airUnitTable.add(tileGroup.tileInfo.airUnits.size.toString().toLabel() airUnitTable.add(tileGroup.tileInfo.airUnits.size.toString().toLabel(secondarycolor,14))
.setFontColor(secondarycolor).setFontSize(14))
add(airUnitTable).row() add(airUnitTable).row()
} }
@ -128,8 +127,7 @@ class CityButton(val city: CityInfo, internal val tileGroup: WorldTileGroup, ski
} }
val cityButtonText = city.population.population.toString() + " | " + city.name val cityButtonText = city.population.population.toString() + " | " + city.name
val label = cityButtonText.toLabel() val label = cityButtonText.toLabel(secondaryColor)
label.setFontColor(secondaryColor)
iconTable.add(label).pad(10f) // sufficient horizontal padding iconTable.add(label).pad(10f) // sufficient horizontal padding
.fillY() // provide full-height clicking area .fillY() // provide full-height clicking area
@ -182,9 +180,7 @@ class CityButton(val city: CityInfo, internal val tileGroup: WorldTileGroup, ski
val cityCurrentConstruction = cityConstructions.getCurrentConstruction() val cityCurrentConstruction = cityConstructions.getCurrentConstruction()
if(cityCurrentConstruction !is SpecialConstruction) { if(cityCurrentConstruction !is SpecialConstruction) {
val turnsToConstruction = cityConstructions.turnsToConstruction(cityCurrentConstruction.name) val turnsToConstruction = cityConstructions.turnsToConstruction(cityCurrentConstruction.name)
val label = turnsToConstruction.toString().toLabel() val label = turnsToConstruction.toString().toLabel(secondaryColor,14)
label.setFontColor(secondaryColor)
label.setFontSize(14)
label.pack() label.pack()
group.addActor(label) group.addActor(label)

View File

@ -93,7 +93,7 @@ class DiplomacyScreen(val viewingCiv:CivilizationInfo):CameraStageBaseScreen() {
val diplomacyTable = Table() val diplomacyTable = Table()
diplomacyTable.defaults().pad(10f) diplomacyTable.defaults().pad(10f)
diplomacyTable.add(otherCiv.getLeaderDisplayName().toLabel().setFontSize(24)).row() diplomacyTable.add(otherCiv.getLeaderDisplayName().toLabel(fontSize = 24)).row()
diplomacyTable.add(("Type: ".tr() + otherCiv.getCityStateType().toString().tr()).toLabel()).row() diplomacyTable.add(("Type: ".tr() + otherCiv.getCityStateType().toString().tr()).toLabel()).row()
diplomacyTable.add(("Influence: ".tr() + otherCivDiplomacyManager.influence.toInt() + "/30").toLabel()).row() diplomacyTable.add(("Influence: ".tr() + otherCivDiplomacyManager.influence.toInt() + "/30").toLabel()).row()
@ -106,14 +106,16 @@ class DiplomacyScreen(val viewingCiv:CivilizationInfo):CameraStageBaseScreen() {
CityStateType.Militaristic -> "Provides land units every 20 turns at [30] Influence".tr() CityStateType.Militaristic -> "Provides land units every 20 turns at [30] Influence".tr()
} }
val friendBonusLabel = friendBonusText.toLabel() val friendBonusLabelColor:Color
diplomacyTable.add(friendBonusLabel).row()
if (otherCivDiplomacyManager.relationshipLevel() >= RelationshipLevel.Friend) { if (otherCivDiplomacyManager.relationshipLevel() >= RelationshipLevel.Friend) {
friendBonusLabel.setFontColor(Color.GREEN) friendBonusLabelColor = Color.GREEN
val turnsToRelationshipChange = otherCivDiplomacyManager.influence.toInt() - 30 + 1 val turnsToRelationshipChange = otherCivDiplomacyManager.influence.toInt() - 30 + 1
diplomacyTable.add("Relationship changes in another [$turnsToRelationshipChange] turns".toLabel()).row() diplomacyTable.add("Relationship changes in another [$turnsToRelationshipChange] turns".toLabel()).row()
} else } else
friendBonusLabel.setFontColor(Color.GRAY) friendBonusLabelColor = Color.GRAY
val friendBonusLabel = friendBonusText.toLabel(friendBonusLabelColor)
diplomacyTable.add(friendBonusLabel).row()
diplomacyTable.addSeparator() diplomacyTable.addSeparator()
@ -158,7 +160,7 @@ class DiplomacyScreen(val viewingCiv:CivilizationInfo):CameraStageBaseScreen() {
val diplomacyTable = Table() val diplomacyTable = Table()
diplomacyTable.defaults().pad(10f) diplomacyTable.defaults().pad(10f)
diplomacyTable.add(otherCiv.getLeaderDisplayName().toLabel().setFontSize(24)).row() diplomacyTable.add(otherCiv.getLeaderDisplayName().toLabel(fontSize = 24)).row()
val translatedNation = otherCiv.getTranslatedNation() val translatedNation = otherCiv.getTranslatedNation()
if(otherCivDiplomacyManager.relationshipLevel()<=RelationshipLevel.Enemy) if(otherCivDiplomacyManager.relationshipLevel()<=RelationshipLevel.Enemy)
diplomacyTable.add(translatedNation.hateHello.toLabel()).row() diplomacyTable.add(translatedNation.hateHello.toLabel()).row()
@ -262,7 +264,7 @@ class DiplomacyScreen(val viewingCiv:CivilizationInfo):CameraStageBaseScreen() {
if (modifier.value > 0) text += "+" if (modifier.value > 0) text += "+"
text += modifier.value.roundToInt() text += modifier.value.roundToInt()
val color = if (modifier.value < 0) Color.RED else Color.GREEN val color = if (modifier.value < 0) Color.RED else Color.GREEN
diplomacyModifiersTable.add(text.toLabel().setFontColor(color)).row() diplomacyModifiersTable.add(text.toLabel(color)).row()
} }
return diplomacyModifiersTable return diplomacyModifiersTable
} }
@ -300,7 +302,7 @@ class DiplomacyScreen(val viewingCiv:CivilizationInfo):CameraStageBaseScreen() {
else -> Color.RED else -> Color.RED
} }
relationshipTable.add(relationshipText.toLabel().setFontColor(relationshipColor)) relationshipTable.add(relationshipText.toLabel(relationshipColor))
return relationshipTable return relationshipTable
} }

View File

@ -113,15 +113,6 @@ fun Actor.centerX(parent:Stage){ x = parent.width/2 - width/2 }
fun Actor.centerY(parent:Stage){ y = parent.height/2- height/2} fun Actor.centerY(parent:Stage){ y = parent.height/2- height/2}
fun Actor.center(parent:Stage){ centerX(parent); centerY(parent)} fun Actor.center(parent:Stage){ centerX(parent); centerY(parent)}
fun Label.setFontColor(color:Color): Label {style=Label.LabelStyle(style).apply { fontColor=color }; return this}
fun Label.setFontSize(size:Int): Label {
style = Label.LabelStyle(style)
style.font = Fonts().getFont(size)
style = style // because we need it to call the SetStyle function. Yuk, I know.
return this // for chaining
}
/** same as [onClick], but sends the [InputEvent] and coordinates along */ /** same as [onClick], but sends the [InputEvent] and coordinates along */
fun Actor.onClickEvent(sound: String = "click", function: (event: InputEvent?, x: Float, y: Float) -> Unit) { fun Actor.onClickEvent(sound: String = "click", function: (event: InputEvent?, x: Float, y: Float) -> Unit) {
@ -209,3 +200,25 @@ fun <T> HashSet<T>.withoutItem(item:T): HashSet<T> {
/** also translates */ /** also translates */
fun String.toLabel() = Label(this.tr(),CameraStageBaseScreen.skin) fun String.toLabel() = Label(this.tr(),CameraStageBaseScreen.skin)
// We don't want to use setFontSize and setFontColor because they set the font,
// which means we need to rebuild the font cache which means more memory allocation.
fun String.toLabel(fontColor:Color= Color.WHITE, fontSize:Int=18): Label {
var labelStyle = CameraStageBaseScreen.skin.get(Label.LabelStyle::class.java)
if(fontColor!= Color.WHITE || fontSize!=18) { // if we want the default we don't need to create another style
labelStyle = Label.LabelStyle(labelStyle) // clone this to another
labelStyle.fontColor = fontColor
if (fontSize != 18) labelStyle.font = Fonts().getFont(fontSize)
}
return Label(this.tr(),labelStyle)
}
fun Label.setFontColor(color:Color): Label {style=Label.LabelStyle(style).apply { fontColor=color }; return this}
fun Label.setFontSize(size:Int): Label {
style = Label.LabelStyle(style)
style.font = Fonts().getFont(size)
style = style // because we need it to call the SetStyle function. Yuk, I know.
return this // for chaining
}

View File

@ -60,8 +60,8 @@ class AlertPopup(val worldScreen: WorldScreen, val popupAlert: PopupAlert): Popu
} }
AlertType.CityConquered -> { AlertType.CityConquered -> {
val city = worldScreen.gameInfo.civilizations.flatMap { it.cities }.first { it.name == popupAlert.value} val city = worldScreen.gameInfo.civilizations.flatMap { it.cities }.first { it.name == popupAlert.value}
addGoodSizedLabel("What would you like to do with the city?") addGoodSizedLabel("What would you like to do with the city?",24)
.apply { this.actor.setFontSize(24) }.padBottom(20f).row() .padBottom(20f).row()
val conqueringCiv = worldScreen.gameInfo.currentPlayerCiv val conqueringCiv = worldScreen.gameInfo.currentPlayerCiv
if (city.foundingCiv != "" if (city.foundingCiv != ""

View File

@ -5,7 +5,9 @@ import com.badlogic.gdx.scenes.scene2d.Touchable
import com.badlogic.gdx.scenes.scene2d.ui.ScrollPane import com.badlogic.gdx.scenes.scene2d.ui.ScrollPane
import com.badlogic.gdx.scenes.scene2d.ui.Table import com.badlogic.gdx.scenes.scene2d.ui.Table
import com.unciv.logic.civilization.Notification import com.unciv.logic.civilization.Notification
import com.unciv.ui.utils.* import com.unciv.ui.utils.ImageGetter
import com.unciv.ui.utils.onClick
import com.unciv.ui.utils.toLabel
import kotlin.math.min import kotlin.math.min
class NotificationsScroll(internal val worldScreen: WorldScreen) : ScrollPane(null) { class NotificationsScroll(internal val worldScreen: WorldScreen) : ScrollPane(null) {
@ -28,7 +30,7 @@ class NotificationsScroll(internal val worldScreen: WorldScreen) : ScrollPane(nu
notificationsTable.clearChildren() notificationsTable.clearChildren()
for (notification in notifications.toList()) { // toList to avoid concurrency problems for (notification in notifications.toList()) { // toList to avoid concurrency problems
val label = notification.text.toLabel().setFontColor(Color.BLACK).setFontSize(14) val label = notification.text.toLabel(Color.BLACK,14)
val listItem = Table() val listItem = Table()
listItem.add(ImageGetter.getCircle() listItem.add(ImageGetter.getCircle()

View File

@ -4,7 +4,10 @@ import com.badlogic.gdx.scenes.scene2d.Touchable
import com.badlogic.gdx.scenes.scene2d.ui.Table import com.badlogic.gdx.scenes.scene2d.ui.Table
import com.unciv.UnCivGame import com.unciv.UnCivGame
import com.unciv.logic.civilization.CivilizationInfo import com.unciv.logic.civilization.CivilizationInfo
import com.unciv.ui.utils.* import com.unciv.ui.utils.CameraStageBaseScreen
import com.unciv.ui.utils.ImageGetter
import com.unciv.ui.utils.onClick
import com.unciv.ui.utils.toLabel
class PlayerReadyScreen(currentPlayerCiv: CivilizationInfo) : CameraStageBaseScreen(){ class PlayerReadyScreen(currentPlayerCiv: CivilizationInfo) : CameraStageBaseScreen(){
init { init {
@ -12,8 +15,7 @@ class PlayerReadyScreen(currentPlayerCiv: CivilizationInfo) : CameraStageBaseScr
table.touchable= Touchable.enabled table.touchable= Touchable.enabled
table.background= ImageGetter.getBackground(currentPlayerCiv.nation.getOuterColor()) table.background= ImageGetter.getBackground(currentPlayerCiv.nation.getOuterColor())
table.add("[$currentPlayerCiv] ready?".toLabel().setFontSize(24) table.add("[$currentPlayerCiv] ready?".toLabel(currentPlayerCiv.nation.getInnerColor(),24))
.setFontColor(currentPlayerCiv.nation.getInnerColor()))
table.onClick { table.onClick {
UnCivGame.Current.worldScreen = WorldScreen(currentPlayerCiv) UnCivGame.Current.worldScreen = WorldScreen(currentPlayerCiv)

View File

@ -34,6 +34,7 @@ class TileGroupMap<T: TileGroup>(val tileGroups:Collection<T>, padding:Float): G
val cityButtonLayers = ArrayList<Group>() val cityButtonLayers = ArrayList<Group>()
val circleCrosshairFogLayers = ArrayList<Group>() val circleCrosshairFogLayers = ArrayList<Group>()
// Apparently the sortedByDescending is kinda memory-intensive because it needs to sort ALL the tiles
for(group in tileGroups.sortedByDescending { it.tileInfo.position.x + it.tileInfo.position.y }){ for(group in tileGroups.sortedByDescending { it.tileInfo.position.x + it.tileInfo.position.y }){
// now, we steal the subgroups from all the tilegroups, that's how we form layers! // now, we steal the subgroups from all the tilegroups, that's how we form layers!
baseLayers.add(group.baseLayerGroup.apply { setPosition(group.x,group.y) }) baseLayers.add(group.baseLayerGroup.apply { setPosition(group.x,group.y) })

View File

@ -189,8 +189,7 @@ class TileMapHolder(internal val worldScreen: WorldScreen, internal val tileMap:
val numberCircle = ImageGetter.getCircle().apply { width = size / 2; height = size / 2;color = Color.BLUE } val numberCircle = ImageGetter.getCircle().apply { width = size / 2; height = size / 2;color = Color.BLUE }
moveHereButton.addActor(numberCircle) moveHereButton.addActor(numberCircle)
moveHereButton.addActor(dto.turnsToGetThere.toString().toLabel() moveHereButton.addActor(dto.turnsToGetThere.toString().toLabel().apply { center(numberCircle) })
.apply { center(numberCircle); setFontColor(Color.WHITE) })
val unitIcon = UnitGroup(dto.unit, size / 2) val unitIcon = UnitGroup(dto.unit, size / 2)
unitIcon.y = size - unitIcon.height unitIcon.y = size - unitIcon.height

View File

@ -263,7 +263,7 @@ class WorldScreen(val viewingCiv:CivilizationInfo) : CameraStageBaseScreen() {
buttonPic.background = ImageGetter.getDrawable("OtherIcons/civTableBackground") buttonPic.background = ImageGetter.getDrawable("OtherIcons/civTableBackground")
.tint(colorFromRGB(7, 46, 43)) .tint(colorFromRGB(7, 46, 43))
buttonPic.defaults().pad(20f) buttonPic.defaults().pad(20f)
buttonPic.add("{Pick a tech}!".toLabel().setFontColor(Color.WHITE).setFontSize(30)) buttonPic.add("{Pick a tech}!".toLabel(Color.WHITE,30))
techButtonHolder.add(buttonPic) techButtonHolder.add(buttonPic)
} }
else { else {

View File

@ -22,11 +22,11 @@ import kotlin.math.roundToInt
class WorldScreenTopBar(val screen: WorldScreen) : Table() { class WorldScreenTopBar(val screen: WorldScreen) : Table() {
private val turnsLabel = "Turns: 0/400".toLabel().setFontColor(Color.WHITE) private val turnsLabel = "Turns: 0/400".toLabel()
private val goldLabel = "Gold:".toLabel().setFontColor(colorFromRGB(225, 217, 71) ) private val goldLabel = "Gold:".toLabel(colorFromRGB(225, 217, 71) )
private val scienceLabel = "Science:".toLabel().setFontColor(colorFromRGB(78, 140, 151) ) private val scienceLabel = "Science:".toLabel(colorFromRGB(78, 140, 151) )
private val happinessLabel = "Happiness:".toLabel() private val happinessLabel = "Happiness:".toLabel()
private val cultureLabel = "Culture:".toLabel().setFontColor(colorFromRGB(210, 94, 210) ) private val cultureLabel = "Culture:".toLabel(colorFromRGB(210, 94, 210) )
private val resourceLabels = HashMap<String, Label>() private val resourceLabels = HashMap<String, Label>()
private val resourceImages = HashMap<String, Actor>() private val resourceImages = HashMap<String, Actor>()
private val happinessImage = Group() private val happinessImage = Group()

View File

@ -110,8 +110,8 @@ class BattleTable(val worldScreen: WorldScreen): Table() {
else listOf() else listOf()
for(i in 0..max(attackerModifiers.size,defenderModifiers.size)){ for(i in 0..max(attackerModifiers.size,defenderModifiers.size)){
if (attackerModifiers.size > i) add(attackerModifiers[i]).actor.setFontSize(14) else add() if (attackerModifiers.size > i) add(attackerModifiers[i].toLabel(fontSize = 14)) else add()
if (defenderModifiers.size > i) add(defenderModifiers[i]).actor.setFontSize(14) else add() if (defenderModifiers.size > i) add(defenderModifiers[i].toLabel(fontSize = 14)) else add()
row().pad(2f) row().pad(2f)
} }

View File

@ -29,8 +29,8 @@ open class PopupTable(val screen: CameraStageBaseScreen): Table(CameraStageBaseS
remove() remove()
} }
fun addGoodSizedLabel(text: String): Cell<Label> { fun addGoodSizedLabel(text: String, size:Int=18): Cell<Label> {
val label = text.toLabel() val label = text.toLabel(fontSize = size)
label.setWrap(true) label.setWrap(true)
label.setAlignment(Align.center) label.setAlignment(Align.center)
return add(label).width(screen.stage.width / 2) return add(label).width(screen.stage.width / 2)

View File

@ -13,7 +13,6 @@ import com.unciv.ui.saves.LoadGameScreen
import com.unciv.ui.saves.SaveGameScreen import com.unciv.ui.saves.SaveGameScreen
import com.unciv.ui.utils.addSeparator import com.unciv.ui.utils.addSeparator
import com.unciv.ui.utils.disable import com.unciv.ui.utils.disable
import com.unciv.ui.utils.setFontColor
import com.unciv.ui.utils.toLabel import com.unciv.ui.utils.toLabel
import com.unciv.ui.worldscreen.WorldScreen import com.unciv.ui.worldscreen.WorldScreen
import java.util.* import java.util.*
@ -108,7 +107,7 @@ class WorldScreenMenuTable(val worldScreen: WorldScreen) : PopupTable(worldScree
copyGameIdButton.actor.disable() copyGameIdButton.actor.disable()
multiplayerPopup.addGoodSizedLabel("Players can enter your game by copying the game ID to the clipboard, and clicking on the Join Game button").row() multiplayerPopup.addGoodSizedLabel("Players can enter your game by copying the game ID to the clipboard, and clicking on the Join Game button").row()
val badGameIdLabel = "".toLabel().setFontColor(Color.RED) val badGameIdLabel = "".toLabel(Color.RED)
badGameIdLabel.isVisible = false badGameIdLabel.isVisible = false
multiplayerPopup.addButton("Join Game") { multiplayerPopup.addButton("Join Game") {
val gameId = Gdx.app.clipboard.contents val gameId = Gdx.app.clipboard.contents

View File

@ -16,9 +16,9 @@ import kotlin.concurrent.thread
class Language(val language:String){ class Language(val language:String){
val percentComplete:Int val percentComplete:Int
init{ init{
val availableTranslations = GameBasics.Translations.filter { it.value.containsKey(language) } val availableTranslations = GameBasics.Translations.count() { it.value.containsKey(language) }
if(language=="English") percentComplete = 100 if(language=="English") percentComplete = 100
else percentComplete = (availableTranslations.size*100 / GameBasics.Translations.size) else percentComplete = (availableTranslations*100 / GameBasics.Translations.size)
} }
override fun toString(): String { override fun toString(): String {
val spaceSplitLang = language.replace("_"," ") val spaceSplitLang = language.replace("_"," ")
@ -183,7 +183,7 @@ class WorldScreenOptionsTable(val worldScreen:WorldScreen) : PopupTable(worldScr
UnCivGame.Current.startMusic() UnCivGame.Current.startMusic()
} catch (ex: Exception) { } catch (ex: Exception) {
errorTable.clear() errorTable.clear()
errorTable.add("Could not download music!".toLabel().setFontColor(Color.RED)) errorTable.add("Could not download music!".toLabel(Color.RED))
} }
} }
} }
@ -267,7 +267,10 @@ class WorldScreenOptionsTable(val worldScreen:WorldScreen) : PopupTable(worldScr
languageSelectBox.addListener(object : ChangeListener() { languageSelectBox.addListener(object : ChangeListener() {
override fun changed(event: ChangeEvent?, actor: Actor?) { override fun changed(event: ChangeEvent?, actor: Actor?) {
// Sometimes the "changed" is triggered even when we didn't choose something that isn't the
selectedLanguage = languageSelectBox.selected.language selectedLanguage = languageSelectBox.selected.language
if(selectedLanguage!=UnCivGame.Current.settings.language )
selectLanguage() selectLanguage()
} }
}) })

View File

@ -4,12 +4,10 @@ import com.badlogic.gdx.graphics.Color
import com.badlogic.gdx.scenes.scene2d.Actor import com.badlogic.gdx.scenes.scene2d.Actor
import com.badlogic.gdx.scenes.scene2d.Touchable import com.badlogic.gdx.scenes.scene2d.Touchable
import com.badlogic.gdx.scenes.scene2d.ui.Button import com.badlogic.gdx.scenes.scene2d.ui.Button
import com.badlogic.gdx.scenes.scene2d.ui.Label
import com.badlogic.gdx.scenes.scene2d.ui.Table import com.badlogic.gdx.scenes.scene2d.ui.Table
import com.unciv.Constants import com.unciv.Constants
import com.unciv.UnCivGame import com.unciv.UnCivGame
import com.unciv.logic.map.MapUnit import com.unciv.logic.map.MapUnit
import com.unciv.models.gamebasics.tr
import com.unciv.ui.utils.* import com.unciv.ui.utils.*
import com.unciv.ui.worldscreen.WorldScreen import com.unciv.ui.worldscreen.WorldScreen
@ -69,10 +67,8 @@ class UnitActionsTable(val worldScreen: WorldScreen) : Table(){
private fun getUnitActionButton(unitAction: UnitAction): Button { private fun getUnitActionButton(unitAction: UnitAction): Button {
val actionButton = Button(CameraStageBaseScreen.skin) val actionButton = Button(CameraStageBaseScreen.skin)
actionButton.add(getIconForUnitAction(unitAction.name)).size(20f).pad(5f) actionButton.add(getIconForUnitAction(unitAction.name)).size(20f).pad(5f)
actionButton.add( val fontColor = if(unitAction.currentAction) Color.YELLOW else Color.WHITE
Label(unitAction.title.tr(),CameraStageBaseScreen.skin) actionButton.add(unitAction.title.toLabel(fontColor)).pad(5f)
.setFontColor(if(unitAction.currentAction) Color.YELLOW else Color.WHITE))
.pad(5f)
actionButton.pack() actionButton.pack()
actionButton.onClick(unitAction.sound) { unitAction.action(); UnCivGame.Current.worldScreen.shouldUpdate=true } actionButton.onClick(unitAction.sound) { unitAction.action(); UnCivGame.Current.worldScreen.shouldUpdate=true }
if (!unitAction.canAct) actionButton.disable() if (!unitAction.canAct) actionButton.disable()

View File

@ -41,13 +41,13 @@ class UnitTable(val worldScreen: WorldScreen) : Table(){
add(VerticalGroup().apply { add(VerticalGroup().apply {
pad(5f) pad(5f)
deselectUnitButton.add(Label("X",CameraStageBaseScreen.skin).setFontColor(Color.WHITE)).pad(10f) deselectUnitButton.add(Label("X",CameraStageBaseScreen.skin)).pad(10f)
deselectUnitButton.pack() deselectUnitButton.pack()
deselectUnitButton.touchable = Touchable.enabled deselectUnitButton.touchable = Touchable.enabled
deselectUnitButton.onClick { selectedUnit=null; selectedCity=null; worldScreen.shouldUpdate=true;this@UnitTable.isVisible=false } deselectUnitButton.onClick { selectedUnit=null; selectedCity=null; worldScreen.shouldUpdate=true;this@UnitTable.isVisible=false }
addActor(deselectUnitButton) addActor(deselectUnitButton)
helpUnitButton.add(Label("?",CameraStageBaseScreen.skin).setFontColor(Color.WHITE)).pad(10f) helpUnitButton.add(Label("?",CameraStageBaseScreen.skin)).pad(10f)
helpUnitButton.pack() helpUnitButton.pack()
helpUnitButton.touchable = Touchable.enabled helpUnitButton.touchable = Touchable.enabled
helpUnitButton.onClick { helpUnitButton.onClick {