ExpanderTab revisited (#4357)

* ExpanderTab revisited

* ExpanderTab revisited - patch1
This commit is contained in:
SomeTroglodyte 2021-07-04 20:25:58 +02:00 committed by GitHub
parent b748f92bb5
commit 8fb55e77a3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 87 additions and 37 deletions

View File

@ -1,45 +1,94 @@
package com.unciv.ui.trade package com.unciv.ui.trade
import com.badlogic.gdx.graphics.Color
import com.badlogic.gdx.math.Interpolation
import com.badlogic.gdx.scenes.scene2d.Touchable import com.badlogic.gdx.scenes.scene2d.Touchable
import com.badlogic.gdx.scenes.scene2d.ui.Skin import com.badlogic.gdx.scenes.scene2d.actions.FloatAction
import com.badlogic.gdx.scenes.scene2d.ui.Table import com.badlogic.gdx.scenes.scene2d.ui.Table
import com.badlogic.gdx.utils.Align
import com.unciv.UncivGame
import com.unciv.ui.utils.CameraStageBaseScreen
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.toLabel import com.unciv.ui.utils.toLabel
class ExpanderTab(private val title:String,skin: Skin): Table(skin){ /**
private val toggle = Table(skin) // the show/hide toggler * A widget with a header that when clicked shows/hides a sub-Table.
private val tab = Table() // what holds the information to be shown/hidden *
val innerTable= Table() // the information itself * @param title The header text, automatically translated.
var isOpen=true * @param defaultPad Padding between content and wrapper. Header padding is currently not modifiable.
* @param initContent Optional lambda with [innerTable] as parameter, to help initialize content.
init{ */
toggle.defaults().pad(10f) class ExpanderTab(
toggle.touchable= Touchable.enabled title: String,
toggle.background(ImageGetter.getBackground(ImageGetter.getBlue())) startsOutOpened: Boolean = true,
toggle.add("+ $title".toLabel(fontSize = 24)) defaultPad: Float = 10f,
toggle.onClick { initContent: ((Table) -> Unit)? = null
if(isOpen) close() ): Table(CameraStageBaseScreen.skin) {
else open() private companion object {
} const val fontSize = 24
add(toggle).fill().row() const val arrowSize = 18f
tab.add(innerTable).pad(10f) const val arrowImage = "OtherIcons/BackArrow"
add(tab) val arrowColor = Color(1f,0.96f,0.75f,1f)
const val animationDuration = 0.2f
} }
fun close(){ private val header = Table(skin) // Header with label and icon, touchable to show/hide
if(!isOpen) return private val headerLabel = title.toLabel(fontSize = fontSize)
toggle.clearChildren() private val headerIcon = ImageGetter.getImage(arrowImage)
toggle.add("- $title".toLabel(fontSize = 24)) private val contentWrapper = Table() // Wrapper for innerTable, this is what will be shown/hidden
tab.clear()
isOpen=false /** The container where the client should add the content to toggle */
val innerTable = Table()
/** Indicates whether the contents are currently shown, changing this will animate the widget */
var isOpen = startsOutOpened
private set(value) {
if (value == field) return
field = value
update()
} }
fun open(){ init {
if(isOpen) return header.defaults().pad(10f)
toggle.clearChildren() headerIcon.setSize(arrowSize, arrowSize)
toggle.add("+ $title".toLabel(fontSize = 24)) headerIcon.setOrigin(Align.center)
tab.add(innerTable) headerIcon.rotation = 180f
isOpen=true headerIcon.color = arrowColor
header.background(ImageGetter.getBackground(ImageGetter.getBlue()))
header.add(headerLabel)
header.add(headerIcon).size(arrowSize).align(Align.center)
header.touchable= Touchable.enabled
header.onClick { toggle() }
add(header).expandX().fill().row()
contentWrapper.defaults().pad(defaultPad)
add(contentWrapper).expandX()
initContent?.invoke(innerTable)
update(noAnimation = true)
}
private fun update(noAnimation: Boolean = false) {
if (noAnimation || !UncivGame.Current.settings.continuousRendering) {
contentWrapper.clear()
if (isOpen) contentWrapper.add(innerTable)
headerIcon.rotation = if (isOpen) 90f else 180f
return
}
val action = object: FloatAction ( 90f, 180f, animationDuration, Interpolation.linear) {
override fun update(percent: Float) {
super.update(percent)
headerIcon.rotation = this.value
if (this.isComplete) {
contentWrapper.clear()
if (isOpen) contentWrapper.add(innerTable)
}
}
}.apply { isReverse = isOpen }
addAction(action)
}
/** Toggle [isOpen], animated */
fun toggle() {
isOpen = !isOpen
} }
} }

View File

@ -30,8 +30,8 @@ class OffersListScroll(val onOfferClicked: (TradeOffer) -> Unit) : ScrollPane(nu
table.clear() table.clear()
expanderTabs.clear() expanderTabs.clear()
for (offertype in values()) { for (offerType in values()) {
val labelName = when(offertype){ val labelName = when(offerType){
Gold, Gold_Per_Turn, Treaty,Agreement,Introduction -> "" Gold, Gold_Per_Turn, Treaty,Agreement,Introduction -> ""
Luxury_Resource -> "Luxury resources" Luxury_Resource -> "Luxury resources"
Strategic_Resource -> "Strategic resources" Strategic_Resource -> "Strategic resources"
@ -39,10 +39,11 @@ class OffersListScroll(val onOfferClicked: (TradeOffer) -> Unit) : ScrollPane(nu
WarDeclaration -> "Declarations of war" WarDeclaration -> "Declarations of war"
City -> "Cities" City -> "Cities"
} }
val offersOfType = offersToDisplay.filter { it.type == offertype } val offersOfType = offersToDisplay.filter { it.type == offerType }
if (labelName!="" && offersOfType.any()) { if (labelName.isNotEmpty() && offersOfType.any()) {
expanderTabs[offertype] = ExpanderTab(labelName.tr(), CameraStageBaseScreen.skin) expanderTabs[offerType] = ExpanderTab(labelName) {
expanderTabs[offertype]!!.innerTable.defaults().pad(5f) it.defaults().pad(5f)
}
} }
} }