Refactor: Extract PickerPane from PickerScreen (#6870)

Refactor: Extract PickerPane from PickerScreen
This commit is contained in:
Timo T 2022-05-20 21:23:25 +02:00 committed by GitHub
parent a2bc1a1a29
commit 5d835c762a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 122 additions and 80 deletions

View File

@ -19,7 +19,7 @@ class DiplomaticVotePickerScreen(private val votingCiv: CivilizationInfo) : Pick
val choosableCivs = votingCiv.gameInfo.civilizations.filter { it.isMajorCiv() && it != votingCiv && !it.isDefeated() }
for (civ in choosableCivs)
{
val button = getPickerOptionButton(ImageGetter.getNationIndicator(civ.nation, pickerOptionIconSize), civ.civName)
val button = PickerPane.getPickerOptionButton(ImageGetter.getNationIndicator(civ.nation, PickerPane.pickerOptionIconSize), civ.civName)
button.pack()
button.onClick {
chosenCiv = civ.civName

View File

@ -19,7 +19,7 @@ class GreatPersonPickerScreen(val civInfo:CivilizationInfo) : PickerScreen() {
val useMayaLongCount = civInfo.greatPeople.mayaLimitedFreeGP > 0
for (unit in greatPersonUnits) {
val button = getPickerOptionButton(ImageGetter.getUnitIcon(unit.name), unit.name)
val button = PickerPane.getPickerOptionButton(ImageGetter.getUnitIcon(unit.name), unit.name)
button.pack()
button.isEnabled = !useMayaLongCount || unit.name in civInfo.greatPeople.longCountGPPool
if (button.isEnabled) button.onClick {

View File

@ -131,7 +131,7 @@ class ImprovementPickerScreen(
regularImprovements.add(statIcons).align(Align.right)
val improvementButton = getPickerOptionButton(image, labelText)
val improvementButton = PickerPane.getPickerOptionButton(image, labelText)
improvementButton.onClick {
selectedImprovement = improvement
pick(improvement.name.tr())

View File

@ -375,7 +375,7 @@ class ModManagementScreen(
private fun onlineButtonAction(repo: Github.Repo, button: Button) {
syncOnlineSelected(repo.name, button)
showModDescription(repo.name)
removeRightSideClickListeners()
rightSideButton.clearListeners()
rightSideButton.enable()
val label = if (installedModInfo[repo.name]?.state?.hasUpdate == true)
"Update [${repo.name}]"
@ -519,7 +519,7 @@ class ModManagementScreen(
// Don't let the player think he can delete Vanilla and G&K rulesets
rightSideButton.isEnabled = mod.ruleset.folderLocation!=null
showModDescription(mod.name)
removeRightSideClickListeners()
rightSideButton.clearListeners()
rightSideButton.onClick {
rightSideButton.isEnabled = false
YesNoPopup(

View File

@ -0,0 +1,85 @@
package com.unciv.ui.pickerscreens
import com.badlogic.gdx.scenes.scene2d.Actor
import com.badlogic.gdx.scenes.scene2d.ui.Button
import com.badlogic.gdx.scenes.scene2d.ui.SplitPane
import com.badlogic.gdx.scenes.scene2d.ui.Table
import com.badlogic.gdx.scenes.scene2d.ui.VerticalGroup
import com.unciv.Constants
import com.unciv.UncivGame
import com.unciv.ui.images.IconTextButton
import com.unciv.ui.utils.*
class PickerPane(
disableScroll: Boolean = false,
) : Table() {
/** The close button on the lower left of [bottomTable], see [setDefaultCloseAction] */
val closeButton = Constants.close.toTextButton()
/** A scrollable wrapped Label you can use to show descriptions in the [bottomTable], starts empty */
val descriptionLabel = "".toLabel()
/** A wrapper containing [rightSideButton]. You can add buttons, they will be arranged vertically */
val rightSideGroup = VerticalGroup()
/** A button on the lower right of [bottomTable] you can use for a "OK"-type action, starts disabled */
val rightSideButton = "".toTextButton()
private val screenSplit = 0.85f
private val maxBottomTableHeight = 150f // about 7 lines of normal text
/**
* The table displaying the choices from which to pick (usually).
* Also the element which most of the screen real estate is devoted to displaying.
*/
val topTable = Table()
/** Holds the [Close button][closeButton], a [description label][descriptionLabel] and an [action button][rightSideButton] */
val bottomTable = Table()
/** A ScrollPane scrolling [topTable], disabled by the disableScroll parameter */
val scrollPane = AutoScrollPane(topTable)
/** A fixed SplitPane holds [scrollPane] and [bottomTable] */
val splitPane = SplitPane(scrollPane, bottomTable, true, BaseScreen.skin)
init {
bottomTable.add(closeButton).pad(10f)
descriptionLabel.wrap = true
val labelScroll = AutoScrollPane(descriptionLabel, BaseScreen.skin)
bottomTable.add(labelScroll).pad(5f).fill().expand()
rightSideButton.disable()
rightSideGroup.addActor(rightSideButton)
bottomTable.add(rightSideGroup).pad(10f).right()
scrollPane.setScrollingDisabled(disableScroll, disableScroll) // lock scrollPane
if (disableScroll) scrollPane.clearListeners() // remove focus capture of AutoScrollPane too
add(splitPane).expand().fill()
}
override fun layout() {
super.layout()
bottomTable.height = bottomTable.height.coerceAtMost(maxBottomTableHeight)
splitPane.splitAmount = (scrollPane.height / (scrollPane.height + bottomTable.height)).coerceAtLeast(screenSplit)
}
/** Enables the [rightSideButton]. See [pick] for a way to set the text. */
fun setRightSideButtonEnabled(enabled: Boolean) {
rightSideButton.isEnabled = enabled
}
/** Sets the text of the [rightSideButton] and enables it if it's the player's turn */
fun pick(rightButtonText: String) {
if (UncivGame.Current.worldScreen.isPlayersTurn) rightSideButton.enable()
rightSideButton.setText(rightButtonText)
}
companion object {
/** Icon size used in [getPickerOptionButton]. */
const val pickerOptionIconSize = 30f
/** Return a button for picker screens that display a list of big buttons with icons and labels. */
fun getPickerOptionButton(icon: Actor, label: String): Button {
return IconTextButton(label, icon).apply {
iconCell!!.size(pickerOptionIconSize).pad(10f)
labelCell.pad(10f)
}
}
}
}

View File

@ -1,64 +1,38 @@
package com.unciv.ui.pickerscreens
import com.badlogic.gdx.scenes.scene2d.Actor
import com.badlogic.gdx.scenes.scene2d.ui.*
import com.unciv.Constants
import com.unciv.UncivGame
import com.unciv.ui.images.IconTextButton
import com.unciv.ui.utils.*
import com.unciv.ui.utils.AutoScrollPane as ScrollPane
import com.unciv.ui.utils.BaseScreen
import com.unciv.ui.utils.onClick
open class PickerScreen(disableScroll: Boolean = false) : BaseScreen() {
/** The close button on the lower left of [bottomTable], see [setDefaultCloseAction] */
protected var closeButton: TextButton = Constants.close.toTextButton()
/** A scrollable wrapped Label you can use to show descriptions in the [bottomTable], starts empty */
protected var descriptionLabel: Label
/** A wrapper containing [rightSideButton]. You can add buttons, they will be arranged vertically */
protected var rightSideGroup = VerticalGroup()
/** A button on the lower right of [bottomTable] you can use for a "OK"-type action, starts disabled */
protected var rightSideButton: TextButton
private val screenSplit = 0.85f
private val maxBottomTableHeight = 150f // about 7 lines of normal text
val pickerPane = PickerPane(disableScroll = disableScroll)
/**
* The table displaying the choices from which to pick (usually).
* Also the element which most of the screen real estate is devoted to displaying.
*/
protected var topTable: Table
/** Holds the [Close button][closeButton], a [description label][descriptionLabel] and an [action button][rightSideButton] */
protected var bottomTable:Table = Table()
/** A fixed SplitPane holds [scrollPane] and [bottomTable] */
protected var splitPane: SplitPane
/** A ScrollPane scrolling [topTable], disabled by the disableScroll parameter */
protected var scrollPane: ScrollPane
/** @see PickerPane.closeButton */
val closeButton by pickerPane::closeButton
/** @see PickerPane.descriptionLabel */
val descriptionLabel by pickerPane::descriptionLabel
/** @see PickerPane.rightSideGroup */
val rightSideGroup by pickerPane::rightSideGroup
/** @see PickerPane.rightSideButton */
val rightSideButton by pickerPane::rightSideButton
/** @see PickerPane.topTable */
val topTable by pickerPane::topTable
/** @see PickerPane.scrollPane */
val scrollPane by pickerPane::scrollPane
/** @see PickerPane.splitPane */
val splitPane by pickerPane::splitPane
init {
bottomTable.add(closeButton).pad(10f)
pickerPane.setFillParent(true)
stage.addActor(pickerPane)
ensureLayout()
}
descriptionLabel = "".toLabel()
descriptionLabel.wrap = true
val labelScroll = ScrollPane(descriptionLabel, skin)
bottomTable.add(labelScroll).pad(5f).fill().expand()
rightSideButton = "".toTextButton()
rightSideButton.disable()
rightSideGroup.addActor(rightSideButton)
bottomTable.add(rightSideGroup).pad(10f).right()
bottomTable.height = (stage.height * (1 - screenSplit)).coerceAtMost(maxBottomTableHeight)
topTable = Table()
scrollPane = ScrollPane(topTable)
scrollPane.setScrollingDisabled(disableScroll, disableScroll) // lock scrollPane
if (disableScroll) scrollPane.clearListeners() // remove focus capture of AutoScrollPane too
scrollPane.setSize(stage.width, stage.height - bottomTable.height)
splitPane = SplitPane(scrollPane, bottomTable, true, skin)
splitPane.splitAmount = scrollPane.height / stage.height
splitPane.setFillParent(true)
stage.addActor(splitPane)
/** Make sure that anyone relying on sizes of the tables within this class during construction gets correct size readings.
* (see [com.unciv.ui.pickerscreens.PolicyPickerScreen]) */
private fun ensureLayout() {
pickerPane.validate()
}
/**
@ -71,35 +45,17 @@ open class PickerScreen(disableScroll: Boolean = false) : BaseScreen() {
else game.setWorldScreen()
dispose()
}
closeButton.onClick(closeAction)
pickerPane.closeButton.onClick(closeAction)
onBackButtonClicked(closeAction)
}
/** Enables the [rightSideButton]. See [pick] for a way to set the text. */
fun setRightSideButtonEnabled(enabled: Boolean) {
rightSideButton.isEnabled = enabled
pickerPane.setRightSideButtonEnabled(enabled)
}
/** Sets the text of the [rightSideButton] and enables it if it's the player's turn */
protected fun pick(rightButtonText: String) {
if (UncivGame.Current.worldScreen.isPlayersTurn) rightSideButton.enable()
rightSideButton.setText(rightButtonText)
}
/** Remove listeners from [rightSideButton] to prepare giving it a new onClick */
fun removeRightSideClickListeners() {
rightSideButton.clearListeners()
}
companion object {
/** Icon size used in [getPickerOptionButton]. */
const val pickerOptionIconSize = 30f
/** Return a button for picker screens that display a list of big buttons with icons and labels. */
fun getPickerOptionButton(icon: Actor, label: String): Button {
return IconTextButton(label, icon).apply {
iconCell!!.size(pickerOptionIconSize).pad(10f)
labelCell.pad(10f)
}
}
fun pick(rightButtonText: String) {
pickerPane.pick(rightButtonText)
}
}

View File

@ -73,6 +73,7 @@ class PolicyPickerScreen(val worldScreen: WorldScreen, civInfo: CivilizationInfo
var rowChangeWidth = Float.MAX_VALUE
// estimate how many branch boxes fit using average size (including pad)
// TODO If we'd want to use scene2d correctly, this is supposed to happen inside an overridden layout() method
val numBranchesX = scrollPane.width / 242f
val numBranchesY = scrollPane.height / 305f
// plan a nice geometry

View File

@ -77,7 +77,7 @@ class PromotionPickerScreen(val unit: MapUnit) : PickerScreen() {
val isPromotionAvailable = promotion in unitAvailablePromotions
val unitHasPromotion = unit.promotions.promotions.contains(promotion.name)
val selectPromotionButton = getPickerOptionButton(ImageGetter.getPromotionIcon(promotion.name), promotion.name)
val selectPromotionButton = PickerPane.getPickerOptionButton(ImageGetter.getPromotionIcon(promotion.name), promotion.name)
selectPromotionButton.isEnabled = true
selectPromotionButton.onClick {
val enable = canBePromoted && isPromotionAvailable && !unitHasPromotion && canChangeState