Untinted embedded symbols - Notifications and Citystate diplomacy (#9051)

This commit is contained in:
SomeTroglodyte 2023-03-30 15:32:43 +02:00 committed by GitHub
parent 3d56c1ba5d
commit aea988a6bb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 130 additions and 3 deletions

View File

@ -0,0 +1,107 @@
@file:Suppress("unused")
package com.unciv.ui.components
import com.badlogic.gdx.graphics.Color
import com.badlogic.gdx.scenes.scene2d.ui.Label
import com.unciv.Constants
import com.unciv.models.translations.tr
import com.unciv.ui.screens.basescreen.BaseScreen
/** A Label allowing Gdx markup
*
* See also [Color Markup Language](https://libgdx.com/wiki/graphics/2d/fonts/color-markup-language)
*/
class ColorMarkupLabel private constructor(
fontSize: Int, // inverted order so it can be differentiated from the translating constructor
text: String,
) : Label(text, BaseScreen.skin) {
/** A Label allowing Gdx markup, auto-translated.
*
* Since Gdx markup markers are interpreted and removed by translation, use «» instead.
*/
constructor(text: String, fontSize: Int = Constants.defaultFontSize)
: this(fontSize, mapMarkup(text))
/** A Label automatically applying Gdx markup colors to symbols and rest of text separately
* - _after_ translating [text].
*/
constructor(text: String,
textColor: Color,
symbolColor: Color = Color.WHITE,
fontSize: Int = Constants.defaultFontSize)
: this (fontSize, prepareText(text, textColor, symbolColor))
private val originalMarkupEnabled: Boolean
init {
if (fontSize != Constants.defaultFontSize) {
val labelStyle = LabelStyle(style) // clone otherwise all default-styled Labels affected
style = labelStyle
style.font = Fonts.font
setFontScale(fontSize / Fonts.ORIGINAL_FONT_SIZE)
}
originalMarkupEnabled = style.font.data.markupEnabled
}
override fun layout() {
style.font.data.markupEnabled = true
super.layout()
style.font.data.markupEnabled = originalMarkupEnabled
}
companion object {
private fun mapMarkup(text: String): String {
val translated = text.tr()
if ('«' !in translated) return translated
return translated.replace('«', '[').replace('»', ']')
}
private fun Color.toMarkup() = when {
this == Color.CLEAR -> "CLEAR"
this == Color.BLACK -> "BLACK"
this == Color.BLUE -> "BLUE"
this == Color.CYAN -> "CYAN"
this == Color.GOLD -> "GOLD"
this == Color.GRAY -> "GRAY"
this == Color.GREEN -> "GREEN"
this == Color.LIME -> "LIME"
this == Color.NAVY -> "NAVY"
this == Color.PINK -> "PINK"
this == Color.RED -> "RED"
this == Color.SKY -> "SKY"
this == Color.TAN -> "TAN"
this == Color.TEAL -> "TEAL"
this == Color.WHITE -> "WHITE"
a < 1f -> "#" + toString()
else -> "#" + toString().substring(0,6)
}
private fun prepareText(text: String, textColor: Color, symbolColor: Color): String {
val translated = text.tr()
if (textColor == Color.WHITE && symbolColor == Color.WHITE || translated.isBlank())
return translated
val tc = textColor.toMarkup()
if (textColor == symbolColor)
return "[$tc]$translated[]"
val sc = symbolColor.toMarkup()
val sb = StringBuilder(translated.length + 42)
var currentColor = ' '
for (char in translated) {
val newColor = if (char in Fonts.allSymbols) 'S' else 'T'
if (newColor != currentColor) {
if (currentColor != ' ') sb.append("[]")
sb.append('[')
sb.append((if (newColor == 'S') sc else tc).toString())
sb.append(']')
currentColor = newColor
}
sb.append(char)
}
if (currentColor != ' ') sb.append("[]")
return sb.toString()
}
}
}

View File

@ -249,4 +249,13 @@ object Fonts {
const val greatMerchant = '⚖' // U+2696 'scale'
const val greatScientist = '⚛' // U+269B 'atom'
const val death = '☠' // U+2620 'skull and crossbones'
val allSymbols = arrayOf<Char>(
turn,
strength, rangedStrength, range, movement,
production, gold, food, science, culture, happiness, faith,
greatArtist, greatEngineer, greatGeneral, greatMerchant, greatScientist,
death,
*MayaCalendar.allSymbols
)
}

View File

@ -30,6 +30,15 @@ object MayaCalendar {
val digits = zero..nineteen
fun digitIcon(ch: Char) = iconFolder + (ch.toCode() - zero.toCode()).toString()
val allSymbols = sequence {
yield(tun)
yield(katun)
yield(baktun)
yieldAll(digits)
}.iterator().run {
Array<Char>(23) { next() }
}
// Calculation
private const val daysOn30000101BCE = 36000 + 5040 + 240 + 11

View File

@ -29,6 +29,7 @@ import com.unciv.models.ruleset.unique.UniqueType
import com.unciv.models.translations.tr
import com.unciv.ui.audio.MusicMood
import com.unciv.ui.audio.MusicTrackChooserFlags
import com.unciv.ui.components.ColorMarkupLabel
import com.unciv.ui.components.Fonts
import com.unciv.ui.components.KeyCharAndCode
import com.unciv.ui.components.UncivTooltip.Companion.addTooltip
@ -266,12 +267,12 @@ class DiplomacyScreen(
}
val friendBonusLabelColor = if (relationLevel == RelationshipLevel.Friend) Color.GREEN else Color.GRAY
val friendBonusLabel = friendBonusText.toLabel(friendBonusLabelColor)
val friendBonusLabel = ColorMarkupLabel(friendBonusText, friendBonusLabelColor)
.apply { setAlignment(Align.center) }
diplomacyTable.add(friendBonusLabel).row()
val allyBonusLabelColor = if (relationLevel == RelationshipLevel.Ally) Color.GREEN else Color.GRAY
val allyBonusLabel = allyBonusText.toLabel(allyBonusLabelColor)
val allyBonusLabel = ColorMarkupLabel(allyBonusText, allyBonusLabelColor)
.apply { setAlignment(Align.center) }
diplomacyTable.add(allyBonusLabel).row()

View File

@ -7,6 +7,7 @@ import com.badlogic.gdx.scenes.scene2d.ui.Table
import com.badlogic.gdx.utils.Align
import com.unciv.logic.civilization.Notification
import com.unciv.logic.civilization.NotificationCategory
import com.unciv.ui.components.ColorMarkupLabel
import com.unciv.ui.images.ImageGetter
import com.unciv.ui.screens.basescreen.BaseScreen
import com.unciv.ui.components.WrappableLabel
@ -81,7 +82,7 @@ class NotificationsScroll(
add(ImageGetter.getWhiteDot()).minHeight(2f).width(worldScreen.stage.width/8)
add(Table().apply {
background = backgroundDrawable
add(category.name.toLabel(fontSize = 30, fontColor = Color.BLACK))
add(ColorMarkupLabel(category.name, Color.BLACK, fontSize = 30))
}).pad(3f)
add(ImageGetter.getWhiteDot()).minHeight(2f).width(worldScreen.stage.width/8)
}).row()