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.
*/
class ExpanderTab(
title: String,
startsOutOpened: Boolean = true,
defaultPad: Float = 10f,
initContent: ((Table) -> Unit)? = null
): Table(CameraStageBaseScreen.skin) {
private companion object {
const val fontSize = 24
const val arrowSize = 18f
const val arrowImage = "OtherIcons/BackArrow"
val arrowColor = Color(1f,0.96f,0.75f,1f)
const val animationDuration = 0.2f
}
init{ private val header = Table(skin) // Header with label and icon, touchable to show/hide
toggle.defaults().pad(10f) private val headerLabel = title.toLabel(fontSize = fontSize)
toggle.touchable= Touchable.enabled private val headerIcon = ImageGetter.getImage(arrowImage)
toggle.background(ImageGetter.getBackground(ImageGetter.getBlue())) private val contentWrapper = Table() // Wrapper for innerTable, this is what will be shown/hidden
toggle.add("+ $title".toLabel(fontSize = 24))
toggle.onClick { /** The container where the client should add the content to toggle */
if(isOpen) close() val innerTable = Table()
else open()
/** 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()
} }
add(toggle).fill().row()
tab.add(innerTable).pad(10f) init {
add(tab) header.defaults().pad(10f)
headerIcon.setSize(arrowSize, arrowSize)
headerIcon.setOrigin(Align.center)
headerIcon.rotation = 180f
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)
} }
fun close(){ private fun update(noAnimation: Boolean = false) {
if(!isOpen) return if (noAnimation || !UncivGame.Current.settings.continuousRendering) {
toggle.clearChildren() contentWrapper.clear()
toggle.add("- $title".toLabel(fontSize = 24)) if (isOpen) contentWrapper.add(innerTable)
tab.clear() headerIcon.rotation = if (isOpen) 90f else 180f
isOpen=false 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)
} }
fun open(){ /** Toggle [isOpen], animated */
if(isOpen) return fun toggle() {
toggle.clearChildren() isOpen = !isOpen
toggle.add("+ $title".toLabel(fontSize = 24))
tab.add(innerTable)
isOpen=true
} }
} }

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)
}
} }
} }
@ -85,4 +86,4 @@ class OffersListScroll(val onOfferClicked: (TradeOffer) -> Unit) : ScrollPane(nu
} }
actor = table actor = table
} }
} }