Nation picker portraits (#5250)

* New game nation picker spruce-up

* New game nation picker spruce-up - Ctext icon control
This commit is contained in:
SomeTroglodyte
2021-09-18 22:31:03 +02:00
committed by GitHub
parent 01bfd17594
commit ec0801ccef
5 changed files with 79 additions and 44 deletions

View File

@ -9,6 +9,7 @@ import com.unciv.models.stats.Stat
import com.unciv.models.stats.Stats
import com.unciv.models.translations.tr
import com.unciv.ui.civilopedia.CivilopediaScreen
import com.unciv.ui.civilopedia.FormattedLine.IconDisplay
import com.unciv.ui.civilopedia.MarkupRenderer
import com.unciv.ui.utils.*
import com.unciv.ui.utils.UncivTooltip.Companion.addTooltip
@ -36,7 +37,7 @@ class CityScreenTileTable(private val cityScreen: CityScreen): Table() {
val stats = selectedTile.getTileStats(city, city.civInfo)
innerTable.pad(5f)
innerTable.add( MarkupRenderer.render(selectedTile.toMarkup(city.civInfo), noLinkImages = true) {
innerTable.add( MarkupRenderer.render(selectedTile.toMarkup(city.civInfo), iconDisplay = IconDisplay.None) {
// Sorry, this will leave the city screen
UncivGame.Current.setScreen(CivilopediaScreen(city.getRuleset(), link = it))
} )

View File

@ -27,7 +27,6 @@ import kotlin.math.max
*/
// Kdoc not using the @property syntax because Android Studio 4.2.2 renders those _twice_
/** Represents a decorated text line with optional linking capability.
* A line can have [text] with optional [size], [color], [indent] or as [header];
* and up to three icons: [link], [object][icon], [star][starred] in that order.
@ -222,13 +221,16 @@ class FormattedLine (
}
return defaultColor
}
/** Used only as parameter to [FormattedLine.render] and [MarkupRenderer.render] */
enum class IconDisplay { All, NoLink, None }
/**
* Renders the formatted line as a scene2d [Actor] (currently always a [Table])
* @param labelWidth Total width to render into, needed to support wrap on Labels.
* @param noLinkImages Omit visual indicator that a line is linked.
* @param iconDisplay Flag to omit link or all images.
*/
fun render(labelWidth: Float, noLinkImages: Boolean = false): Actor {
fun render(labelWidth: Float, iconDisplay: IconDisplay = IconDisplay.All): Actor {
if (extraImage.isNotEmpty()) {
val table = Table(CameraStageBaseScreen.skin)
try {
@ -260,11 +262,11 @@ class FormattedLine (
val table = Table(CameraStageBaseScreen.skin)
var iconCount = 0
val iconSize = max(minIconSize, fontSize * 1.5f)
if (linkType != LinkType.None && !noLinkImages) {
if (linkType != LinkType.None && iconDisplay == IconDisplay.All) {
table.add(ImageGetter.getImage(linkImage)).size(iconSize).padRight(iconPad)
iconCount++
}
if (!noLinkImages)
if (iconDisplay != IconDisplay.None)
iconCount += renderIcon(table, iconToDisplay, iconSize)
if (starred) {
val image = ImageGetter.getImage(starImage)
@ -278,7 +280,7 @@ class FormattedLine (
centered -> -usedWidth
indent == 0 && iconCount == 0 -> 0f
indent == 0 -> iconPad
noLinkImages -> indent * indentPad - usedWidth
iconCount == 0 -> indent * indentPad - usedWidth
else -> (indent-1) * indentPad +
indentOneAtNumIcons * (minIconSize + iconPad) + iconPad - usedWidth
}
@ -354,14 +356,14 @@ object MarkupRenderer {
*
* @param labelWidth Available width needed for wrapping labels and [centered][FormattedLine.centered] attribute.
* @param padding Default cell padding (default 2.5f) to control line spacing
* @param noLinkImages Flag to omit link images (but not linking itself)
* @param iconDisplay Flag to omit link or all images (but not linking itself if linkAction is supplied)
* @param linkAction Delegate to call for internal links. Leave null to suppress linking.
*/
fun render(
lines: Collection<FormattedLine>,
labelWidth: Float = 0f,
padding: Float = defaultPadding,
noLinkImages: Boolean = false,
iconDisplay: FormattedLine.IconDisplay = FormattedLine.IconDisplay.All,
linkAction: ((id: String) -> Unit)? = null
): Table {
val skin = CameraStageBaseScreen.skin
@ -376,7 +378,7 @@ object MarkupRenderer {
.pad(separatorTopPadding, 0f, separatorBottomPadding, 0f)
continue
}
val actor = line.render(labelWidth, noLinkImages)
val actor = line.render(labelWidth, iconDisplay)
if (line.linkType == FormattedLine.LinkType.Internal && linkAction != null)
actor.onClick {
linkAction(line.link)

View File

@ -8,10 +8,9 @@ import com.badlogic.gdx.utils.Align
import com.unciv.Constants
import com.unciv.models.ruleset.Nation
import com.unciv.models.ruleset.Ruleset
import com.unciv.ui.utils.CameraStageBaseScreen
import com.unciv.ui.utils.ImageGetter
import com.unciv.ui.utils.surroundWithCircle
import com.unciv.ui.utils.toLabel
import com.unciv.ui.civilopedia.FormattedLine.IconDisplay
import com.unciv.ui.civilopedia.MarkupRenderer
import com.unciv.ui.utils.*
// The ruleset also acts as a secondary parameter to determine if this is the right or self side of the player picker
class NationTable(val nation: Nation, width: Float, minHeight: Float, ruleset: Ruleset? = null)
@ -19,42 +18,76 @@ class NationTable(val nation: Nation, width: Float, minHeight: Float, ruleset: R
val innerTable = Table()
init {
background = ImageGetter.getBackground(nation.getInnerColor())
if (ruleset != null) pad(5f)
innerTable.pad(5f)
val totalPadding = 20f // pad*2 + innerTable.pad*2
innerTable.background = ImageGetter.getBackground(nation.getOuterColor())
val innerColor = nation.getInnerColor()
val outerColor = nation.getOuterColor()
val textBackgroundColor = Color(0x002042ff) // getBlue().lerp(Black,0.5).apply { a = 1 }
val borderWidth = 5f
val totalPadding = 10f + 4 * borderWidth // pad*2 + innerTable.pad*2 + borderTable.pad*2
val internalWidth = width - totalPadding
val titleTable = Table()
titleTable.background = ImageGetter.getBackground(outerColor)
val nationIndicator: Actor =
if (nation.name == Constants.random) ImageGetter.getRandomNationIndicator(50f)
else ImageGetter.getNationIndicator(nation, 50f)
titleTable.add(nationIndicator).pad(10f).padLeft(0f) // left 0 for centering _with_ label
val nationIndicator: Actor
if(nation.name=="Random") nationIndicator = "?".toLabel(Color.WHITE, 30)
.apply { this.setAlignment(Align.center) }
.surroundWithCircle(45f).apply { circle.color = Color.BLACK }
.surroundWithCircle(50f, false).apply { circle.color = Color.WHITE }
else nationIndicator = ImageGetter.getNationIndicator(nation, 50f)
titleTable.add(nationIndicator).pad(10f)
val titleText = if (ruleset == null || nation.name== Constants.random || nation.name==Constants.spectator)
val titleText = if (ruleset == null || nation.name == Constants.random || nation.name == Constants.spectator)
nation.name else nation.getLeaderDisplayName()
val leaderDisplayLabel = titleText.toLabel(nation.getInnerColor(), 24)
val leaderDisplayNameMaxWidth = internalWidth - 90f // 70 for the nation indicator + 20 extra
if (leaderDisplayLabel.width > leaderDisplayNameMaxWidth) { // for instance Polish has really long [x] of [y] translations
val leaderDisplayNameMaxWidth = internalWidth - 70f // for the nation indicator with padding
val leaderDisplayLabel = WrappableLabel(titleText, leaderDisplayNameMaxWidth, innerColor, 24)
if (leaderDisplayLabel.prefWidth > leaderDisplayNameMaxWidth - 2f) {
leaderDisplayLabel.wrap = true
titleTable.add(leaderDisplayLabel).width(leaderDisplayNameMaxWidth)
} else titleTable.add(leaderDisplayLabel)
innerTable.add(titleTable).row()
} else {
titleTable.add(leaderDisplayLabel).align(Align.center).pad(10f,0f)
}
innerTable.add(titleTable).growX().fillY().row()
if (ruleset != null) {
val nationUniqueLabel = nation.getUniqueString(ruleset).toLabel(nation.getInnerColor())
nationUniqueLabel.wrap = true
innerTable.add(nationUniqueLabel).width(internalWidth)
titleTable.padBottom(borderWidth) // visual centering including upper border
innerTable.background = ImageGetter.getBackground(textBackgroundColor)
val lines = nation.getCivilopediaTextLines(ruleset)
.filter { it.header != 3 }
innerTable.add(MarkupRenderer.render(lines, internalWidth, iconDisplay = IconDisplay.NoLink)).pad(10f)
val borderTable = Table()
borderTable.background = ImageGetter.getBackground(outerColor)
borderTable.add(innerTable).pad(borderWidth).grow()
add(borderTable).pad(borderWidth).width(width).minHeight(minHeight - totalPadding)
} else {
innerTable.background = ImageGetter.getBackground(outerColor)
add(innerTable).width(width).minHeight(minHeight - totalPadding)
}
touchable = Touchable.enabled
add(innerTable).width(width).minHeight(minHeight - totalPadding)
background = ImageGetter.getBackground(innerColor)
}
}
}
/*
Layout if ruleset != null:
*Widgets*
Text colour Background Colour
Align Padding
+----- *NationTable* ----------------------------------------+
| getInnerColor |
| +---- *borderTable* -------------------------------------+ |
| | getOuterColor | |
| | +--- *innerTable* -----------------------------------+ | |
| | | +-- *titleTable* --------------------------------+ | | |
| | | | getInnerColor getOuterColor | | | |
| | | | *nationIndicator* *leaderDisplayLabel* | | | |
| | | | center or left/wrap 0: all sides | | | |
| | | +------------------------------------------------+ | | |
| | | White Dark-blue | | |
| | | MarkupRenderer.render(getCivilopediaTextLines) | | |
| | | left/wrap 10: all sides | | |
| | | | | |
| | +----------------------------------------------------+ | |
| +--------------------------------------------------------+ |
+------------------------------------------------------------+
*/

View File

@ -316,8 +316,6 @@ private class NationPickerPopup(
private fun setNationDetails(nation: Nation) {
nationDetailsTable.clear()
// val nationUniqueLabel = nation.getUniqueString(ruleset).toLabel(nation.getInnerColor())
// nationUniqueLabel.wrap = true
nationDetailsTable.add(NationTable(nation, civBlocksWidth, partHeight, ruleset))
nationDetailsTable.onClick {
if (previousScreen is GameParametersScreen)

View File

@ -7,6 +7,7 @@ import com.unciv.UncivGame
import com.unciv.logic.civilization.CivilizationInfo
import com.unciv.logic.map.TileInfo
import com.unciv.ui.civilopedia.CivilopediaScreen
import com.unciv.ui.civilopedia.FormattedLine.IconDisplay
import com.unciv.ui.civilopedia.MarkupRenderer
import com.unciv.ui.utils.CameraStageBaseScreen
import com.unciv.ui.utils.ImageGetter
@ -22,7 +23,7 @@ class TileInfoTable(private val viewingCiv :CivilizationInfo) : Table(CameraStag
if (tile != null && (UncivGame.Current.viewEntireMapForDebug || viewingCiv.exploredTiles.contains(tile.position)) ) {
add(getStatsTable(tile))
add( MarkupRenderer.render(tile.toMarkup(viewingCiv), padding = 0f, noLinkImages = true) {
add( MarkupRenderer.render(tile.toMarkup(viewingCiv), padding = 0f, iconDisplay = IconDisplay.None) {
UncivGame.Current.setScreen(CivilopediaScreen(viewingCiv.gameInfo.ruleSet, link = it))
} ).pad(5f).row()
if (UncivGame.Current.viewEntireMapForDebug)