From c27bb5d74d857b9bea1d3ff0d229b4dc70eda563 Mon Sep 17 00:00:00 2001 From: Yair Morgenstern Date: Mon, 12 Jun 2023 22:54:37 +0300 Subject: [PATCH] Revert "Make ExpanderTab "expand" properly (#9522)" This reverts commit ae74dca0748f84db8e70b20fae8f914663f0a56f. --- .../com/unciv/ui/components/ExpanderTab.kt | 230 +++++------------- .../unciv/ui/popups/options/ModCheckTab.kt | 3 +- .../cityscreen/CitizenManagementTable.kt | 7 +- .../cityscreen/CityReligionInfoTable.kt | 7 +- .../ui/screens/cityscreen/CityStatsTable.kt | 11 +- .../cityscreen/SpecialistAllocationTable.kt | 7 +- .../diplomacyscreen/OffersListScroll.kt | 35 ++- .../mapeditorscreen/tabs/MapEditorViewTab.kt | 22 +- .../ui/screens/newgamescreen/NewGameScreen.kt | 15 +- .../pickerscreens/ModManagementScreen.kt | 13 +- .../mainmenu/WorldScreenMusicPopup.kt | 30 +-- 11 files changed, 136 insertions(+), 244 deletions(-) diff --git a/core/src/com/unciv/ui/components/ExpanderTab.kt b/core/src/com/unciv/ui/components/ExpanderTab.kt index cc542b7015..dfcee31ace 100644 --- a/core/src/com/unciv/ui/components/ExpanderTab.kt +++ b/core/src/com/unciv/ui/components/ExpanderTab.kt @@ -1,41 +1,31 @@ package com.unciv.ui.components import com.badlogic.gdx.graphics.Color +import com.badlogic.gdx.math.Interpolation import com.badlogic.gdx.scenes.scene2d.Actor import com.badlogic.gdx.scenes.scene2d.Touchable import com.badlogic.gdx.scenes.scene2d.actions.FloatAction -import com.badlogic.gdx.scenes.scene2d.ui.Cell -import com.badlogic.gdx.scenes.scene2d.ui.Container -import com.badlogic.gdx.scenes.scene2d.ui.Image import com.badlogic.gdx.scenes.scene2d.ui.Table -import com.badlogic.gdx.scenes.scene2d.ui.WidgetGroup -import com.badlogic.gdx.scenes.scene2d.utils.Layout import com.badlogic.gdx.utils.Align import com.unciv.Constants import com.unciv.UncivGame -import com.unciv.models.metadata.GameSettings -import com.unciv.ui.components.extensions.toLabel -import com.unciv.ui.components.input.onClick -import com.unciv.ui.images.IconCircleGroup import com.unciv.ui.images.ImageGetter +import com.unciv.ui.components.input.onClick +import com.unciv.ui.components.extensions.toLabel import com.unciv.ui.screens.basescreen.BaseScreen -import kotlin.math.abs /** * A widget with a header that when clicked shows/hides a sub-Table. * * @param title The header text, automatically translated. * @param fontSize Size applied to header text (only) - * @param icon Optional icon - please use [Image] or [IconCircleGroup] and make sure size is set - * @param startsOutOpened Default initial "open" state if no [persistenceID] set or no persistes state found + * @param icon Optional icon - please use [Image][com.badlogic.gdx.scenes.scene2d.ui.Image] or [IconCircleGroup] * @param defaultPad Padding between content and wrapper. * @param headerPad Default padding for the header Table. - * @param headerAlign How the header content aligns - use [Align] constants. - * @param expanderWidth If set initializes cell minWidth and wrapper width + * @param expanderWidth If set initializes header width * @param persistenceID If specified, the ExpanderTab will remember its open/closed state for the duration of one app run - * @param animated Controls whether opening/closing is animated, defaults to the [continuousRendering][GameSettings.continuousRendering] setting. - * @param content An [Actor] supporting [Layout] with the content to display in expanded state. Will be `pack()`ed! - * @param onChange If specified, this will be called on any visual change: repeatedly during animation if enabled, otherwise once after each change to [isOpen]. (e.g. to react to changed size) + * @param onChange If specified, this will be called after the visual change for a change in [isOpen] completes (e.g. to react to changed size) + * @param initContent Optional lambda with [innerTable] as parameter, to help initialize content. */ class ExpanderTab( title: String, @@ -44,64 +34,27 @@ class ExpanderTab( startsOutOpened: Boolean = true, defaultPad: Float = 10f, headerPad: Float = 10f, - headerAlign: Int = Align.center, - private val expanderWidth: Float = 0f, + expanderWidth: Float = 0f, private val persistenceID: String? = null, - animated: Boolean? = null, - private val content: WidgetGroup, - private val onChange: (() -> Unit)? = null -) : Table(BaseScreen.skin) { - /** Alternate builder-style constructor for an [ExpanderTab] - * - * @param initContent A lambda with the future [content] as parameter, to help initialize. Will be `pack()`ed when done! - */ - constructor( - title: String, - fontSize: Int = Constants.headingFontSize, - icon: Actor? = null, - startsOutOpened: Boolean = true, - defaultPad: Float = 10f, - headerPad: Float = 10f, - headerAlign: Int = Align.center, - expanderWidth: Float = 0f, - persistenceID: String? = null, - animated: Boolean? = null, - onChange: (() -> Unit)? = null, - initContent: ((Table) -> Unit) - ) : this ( - title, fontSize, icon, startsOutOpened, defaultPad, - headerPad, headerAlign, expanderWidth, persistenceID, animated, - Table(BaseScreen.skin).apply { - defaults().growX() - initContent(this) - }, - onChange - ) + private val onChange: (() -> Unit)? = null, + initContent: ((Table) -> Unit)? = null +): Table(BaseScreen.skin) { + private companion object { + const val arrowSize = 18f + const val arrowImage = "OtherIcons/BackArrow" + val arrowColor = Color(1f,0.96f,0.75f,1f) + const val animationDuration = 0.2f - companion object { - private const val arrowSize = 18f - private const val arrowImage = "OtherIcons/BackArrow" - private val arrowColor = Color(1f,0.96f,0.75f,1f) - private const val animationDurationForStageHeight = 0.5f // also serves as maximum - - private val persistedStates = HashMap() + val persistedStates = HashMap() } - // _Please_ don't make header, wrapper or content public. Makes tweaking this widget harder. - // If more control is needed and the parameter count gets too high, consider using a Style class - // or open class / protected fun createHeader() or dedicated setters instead. - private val header = Table(skin) // Header with label and icon, touchable to show/hide + val header = Table(skin) // Header with label and icon, touchable to show/hide private val headerLabel = title.toLabel(fontSize = fontSize) - private val arrowIcon = ImageGetter.getImage(arrowImage) - private val headerCell: Cell + private val headerIcon = ImageGetter.getImage(arrowImage) + private val contentWrapper = Table() // Wrapper for innerTable, this is what will be shown/hidden - private val wrapper: Container - private val wrapperCell: Cell> - private var wrapperWidth: Float = 0f - private var wrapperHeight: Float = 0f - - private var currentPercent = 0f - private val noAnimation = !(animated ?: UncivGame.Current.settings.continuousRendering) + /** 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 */ // This works because a HashMap _could_ store an entry for the null key but we cannot actually store one when declaring as HashMap @@ -113,14 +66,11 @@ class ExpanderTab( } init { - setLayoutEnabled(false) - - header.align(headerAlign) header.defaults().pad(headerPad) - arrowIcon.setSize(arrowSize, arrowSize) - arrowIcon.setOrigin(Align.center) - arrowIcon.rotation = 180f - arrowIcon.color = arrowColor + headerIcon.setSize(arrowSize, arrowSize) + headerIcon.setOrigin(Align.center) + headerIcon.rotation = 180f + headerIcon.color = arrowColor header.background( BaseScreen.skinStrings.getUiBackground( "General/ExpanderTab", @@ -129,78 +79,48 @@ class ExpanderTab( ) if (icon != null) header.add(icon) header.add(headerLabel) - header.add(arrowIcon).size(arrowSize).align(Align.center) + header.add(headerIcon).size(arrowSize).align(Align.center) header.touchable= Touchable.enabled header.onClick { toggle() } - - content.pack() - measureContent() - - wrapper = Container(content).apply { - setRound(false) - bottom() // controls what is seen first on opening! - setSize(wrapperWidth, 0f) - } - + if (expanderWidth != 0f) + defaults().minWidth(expanderWidth) defaults().growX() - headerCell = add(header).minWidth(wrapperWidth) - row() - wrapperCell = add(wrapper).size(wrapperWidth, 0f).pad(defaultPad) - - setLayoutEnabled(true) - update(fromInit = true) + contentWrapper.defaults().growX().pad(defaultPad) + innerTable.defaults().growX() + add(header).fillY().row() + add(contentWrapper) + contentWrapper.add(innerTable) // update will revert this + initContent?.invoke(innerTable) + if (expanderWidth == 0f) { + // Measure content width incl. pad, set header to same width + if (innerTable.needsLayout()) contentWrapper.pack() + getCell(header).minWidth(contentWrapper.width) + } + update(noAnimation = true) } - override fun getPrefHeight() = header.prefHeight + wrapperHeight * currentPercent - - override fun layout() { - // Critical magic here! Key to allow dynamic content. - // However, I can't explain why an invalidated header also needs to trigger it. Without, the - // WorldScreenMusicPopup's expanders, which are width-controlled by their outer cell's fillX/expandX, - // start aligned and same width, but will slightly misalign by some 10f on opening/closing some of them. - if (content.needsLayout() || header.needsLayout()) - contentHasChanged() - super.layout() - } - - private fun contentHasChanged() { - val oldWidth = wrapperWidth - val oldHeight = wrapperHeight - content.pack() - measureContent() - if (wrapperWidth == oldWidth && wrapperHeight == oldHeight) return - headerCell.minWidth(wrapperWidth) - currentPercent *= oldHeight / wrapperHeight // to animate smoothly to new height, >1f should work too - update() - } - - private fun measureContent() { - wrapperWidth = if (expanderWidth > 0f) expanderWidth else content.width - wrapperHeight = content.height - } - - private fun update(fromInit: Boolean = false) { + private fun update(noAnimation: Boolean = false) { if (persistenceID != null) persistedStates[persistenceID] = isOpen - - if (noAnimation || fromInit) { - updateContentVisibility(if (isOpen) 1f else 0f) - wrapper.isVisible = isOpen - if (!fromInit) onChange?.invoke() + if (noAnimation || !UncivGame.Current.settings.continuousRendering) { + contentWrapper.clear() + if (isOpen) contentWrapper.add(innerTable) + headerIcon.rotation = if (isOpen) 90f else 180f + if (!noAnimation) onChange?.invoke() return } - - clearActions() - addAction(ExpandAction()) - } - - private fun updateContentVisibility(percent: Float) { - currentPercent = percent - val height = percent * wrapperHeight - wrapperCell.size(wrapperWidth, height) // needed for layout - wrapper.setSize(wrapperWidth, height) // needed for clipping - arrowIcon.rotation = 90f * (2f - percent) - invalidateHierarchy() + 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) + onChange?.invoke() + } + } + }.apply { isReverse = isOpen } + addAction(action) } /** Toggle [isOpen], animated */ @@ -208,38 +128,8 @@ class ExpanderTab( isOpen = !isOpen } - /** Change header label text after initialization - **no** auto-translation! */ + /** Change header label text after initialization */ fun setText(text: String) { headerLabel.setText(text) } - - private inner class ExpandAction : FloatAction() { - init { - start = currentPercent // start from wherever we were if turned around midway - end = if (isOpen) 1f else 0f - // Duration: shorter if less content height... - val heightFactor = stage?.run { wrapperHeight.coerceAtMost(height) / height } ?: 0.5f - // ... and shorter if turned around midway - val distanceFactor = abs(end - currentPercent) - duration = (animationDurationForStageHeight * heightFactor) - .coerceAtLeast(0.15f) * distanceFactor - } - - override fun begin() { - super.begin() - wrapper.clip(true) - wrapper.isVisible = true - } - - override fun update(percent: Float) { - super.update(percent) - updateContentVisibility(value) - onChange?.invoke() - } - - override fun end() { - wrapper.clip(false) - wrapper.isVisible = isOpen // allows turning clip off in closed state - } - } } diff --git a/core/src/com/unciv/ui/popups/options/ModCheckTab.kt b/core/src/com/unciv/ui/popups/options/ModCheckTab.kt index a72a6719a3..a5b1786645 100644 --- a/core/src/com/unciv/ui/popups/options/ModCheckTab.kt +++ b/core/src/com/unciv/ui/popups/options/ModCheckTab.kt @@ -123,7 +123,7 @@ class ModCheckTab( .apply { color = Color.BLACK } .surroundWithCircle(30f, color = iconColor) - val expanderTab = ExpanderTab(mod.name, icon = icon, startsOutOpened = false, headerAlign = Align.left) { + val expanderTab = ExpanderTab(mod.name, icon = icon, startsOutOpened = false) { it.defaults().align(Align.left) if (!noProblem && mod.folderLocation != null) { val replaceableUniques = getDeprecatedReplaceableUniques(mod) @@ -143,6 +143,7 @@ class ModCheckTab( .joinToString("\n") { line -> line.text } }).row() } + expanderTab.header.left() val loadingLabel = modCheckResultTable.children.last() modCheckResultTable.removeActor(loadingLabel) diff --git a/core/src/com/unciv/ui/screens/cityscreen/CitizenManagementTable.kt b/core/src/com/unciv/ui/screens/cityscreen/CitizenManagementTable.kt index 55c2c87dd1..774c0479de 100644 --- a/core/src/com/unciv/ui/screens/cityscreen/CitizenManagementTable.kt +++ b/core/src/com/unciv/ui/screens/cityscreen/CitizenManagementTable.kt @@ -83,15 +83,16 @@ class CitizenManagementTable(val cityScreen: CityScreen) : Table(BaseScreen.skin } fun asExpander(onChange: (() -> Unit)?): ExpanderTab { - update() return ExpanderTab( title = "{Citizen Management}", fontSize = Constants.defaultFontSize, persistenceID = "CityStatsTable.CitizenManagement", startsOutOpened = false, - content = this, onChange = onChange - ) + ) { + it.add(this) + update() + } } } diff --git a/core/src/com/unciv/ui/screens/cityscreen/CityReligionInfoTable.kt b/core/src/com/unciv/ui/screens/cityscreen/CityReligionInfoTable.kt index 4b1397014b..7e3a295d21 100644 --- a/core/src/com/unciv/ui/screens/cityscreen/CityReligionInfoTable.kt +++ b/core/src/com/unciv/ui/screens/cityscreen/CityReligionInfoTable.kt @@ -96,7 +96,6 @@ class CityReligionInfoTable( fun asExpander(onChange: (()->Unit)?): ExpanderTab { val (icon, label) = getIconAndLabel(religionManager.getMajorityReligion()) - defaults().center().pad(5f) return ExpanderTab( title = "Majority Religion: [$label]", fontSize = Constants.defaultFontSize, @@ -104,8 +103,10 @@ class CityReligionInfoTable( defaultPad = 0f, persistenceID = "CityStatsTable.Religion", startsOutOpened = false, - content = this, onChange = onChange - ) + ) { + defaults().center().pad(5f) + it.add(this) + } } } diff --git a/core/src/com/unciv/ui/screens/cityscreen/CityStatsTable.kt b/core/src/com/unciv/ui/screens/cityscreen/CityStatsTable.kt index 7d1b8a2cb9..f50b31d064 100644 --- a/core/src/com/unciv/ui/screens/cityscreen/CityStatsTable.kt +++ b/core/src/com/unciv/ui/screens/cityscreen/CityStatsTable.kt @@ -232,6 +232,7 @@ class CityStatsTable(private val cityScreen: CityScreen): Table() { otherBuildings.sortBy { it.name } val totalTable = Table() + lowerTable.addCategory("Buildings", totalTable, false) if (specialistBuildings.isNotEmpty()) { val specialistBuildingsTable = Table() @@ -260,8 +261,6 @@ class CityStatsTable(private val cityScreen: CityScreen): Table() { for (building in otherBuildings) addBuildingButton(building, regularBuildingsTable) totalTable.add(regularBuildingsTable).growX().right().row() } - - lowerTable.addCategory("Buildings", totalTable, false) } private fun addBuildingButton(building: Building, destinationTable: Table) { @@ -313,15 +312,17 @@ class CityStatsTable(private val cityScreen: CityScreen): Table() { destinationTable.add(button).pad(1f).padBottom(2f).padTop(2f).expandX().right().row() } - private fun Table.addCategory(category: String, showHideTable: Table, startsOpened: Boolean = true) : ExpanderTab { + private fun Table.addCategory(category: String, showHideTable: Table, startsOpened: Boolean = true, innerPadding: Float = 10f) : ExpanderTab { val expanderTab = ExpanderTab( title = category, fontSize = Constants.defaultFontSize, persistenceID = "CityInfo.$category", startsOutOpened = startsOpened, - content = showHideTable, + defaultPad = innerPadding, onChange = { onContentResize() } - ) + ) { + it.add(showHideTable).fillX().right() + } add(expanderTab).growX().row() return expanderTab } diff --git a/core/src/com/unciv/ui/screens/cityscreen/SpecialistAllocationTable.kt b/core/src/com/unciv/ui/screens/cityscreen/SpecialistAllocationTable.kt index fe0bbc54e0..49eec80536 100644 --- a/core/src/com/unciv/ui/screens/cityscreen/SpecialistAllocationTable.kt +++ b/core/src/com/unciv/ui/screens/cityscreen/SpecialistAllocationTable.kt @@ -136,15 +136,16 @@ class SpecialistAllocationTable(private val cityScreen: CityScreen) : Table(Base fun asExpander(onChange: (() -> Unit)?): ExpanderTab { - update() return ExpanderTab( title = "{Specialists}:", fontSize = Constants.defaultFontSize, persistenceID = "CityStatsTable.Specialists", startsOutOpened = true, - content = this, onChange = onChange - ) + ) { + it.add(this) + update() + } } } diff --git a/core/src/com/unciv/ui/screens/diplomacyscreen/OffersListScroll.kt b/core/src/com/unciv/ui/screens/diplomacyscreen/OffersListScroll.kt index aa1a774801..866ce4174c 100644 --- a/core/src/com/unciv/ui/screens/diplomacyscreen/OffersListScroll.kt +++ b/core/src/com/unciv/ui/screens/diplomacyscreen/OffersListScroll.kt @@ -23,7 +23,6 @@ import com.unciv.models.ruleset.tile.ResourceSupplyList import com.unciv.models.translations.tr import com.unciv.ui.components.ExpanderTab import com.unciv.ui.components.extensions.disable -import com.unciv.ui.components.extensions.toLabel import com.unciv.ui.components.input.onClick import com.unciv.ui.images.IconTextButton import com.unciv.ui.images.ImageGetter @@ -42,11 +41,8 @@ class OffersListScroll( ) : ScrollPane(null) { val table = Table(BaseScreen.skin).apply { defaults().pad(5f) } - private data class ExpanderData( - val label: String, - val content: Table = Table().apply { defaults().pad(5f) } - ) - private val expanderContents = HashMap() + + private val expanderTabs = HashMap() /** * @param offersToDisplay The offers which should be displayed as buttons @@ -59,10 +55,10 @@ class OffersListScroll( untradableOffers: ResourceSupplyList = ResourceSupplyList.emptyList ) { table.clear() - expanderContents.clear() + expanderTabs.clear() for (offerType in values()) { - val labelName = when(offerType) { + val labelName = when(offerType){ Gold, Gold_Per_Turn, Treaty, Agreement, Introduction -> "" Luxury_Resource -> "Luxury resources" Strategic_Resource -> "Strategic resources" @@ -72,12 +68,11 @@ class OffersListScroll( } val offersOfType = offersToDisplay.filter { it.type == offerType } if (labelName.isNotEmpty() && offersOfType.any()) { - expanderContents[offerType] = ExpanderData(labelName) + expanderTabs[offerType] = ExpanderTab(labelName, persistenceID = "Trade.$persistenceID.$offerType") { + it.defaults().pad(5f) + } } } - val expanderWidth = (expanderContents.values.maxByOrNull { it.label.length } - ?.run { label.toLabel(fontSize = Constants.headingFontSize).prefWidth } - ?: 0f) + 50f // 50 for Expander header pad and arrow for (offerType in values()) { val offersOfType = offersToDisplay.filter { it.type == offerType } @@ -86,6 +81,11 @@ class OffersListScroll( { if (it.type==City) it.getOfferText() else it.name.tr() } )) + if (expanderTabs.containsKey(offerType)) { + expanderTabs[offerType]!!.innerTable.clear() + table.add(expanderTabs[offerType]!!).row() + } + for (offer in offersOfType) { val tradeLabel = offer.getOfferText(untradableOffers.sumBy(offer.name)) val tradeIcon = when (offer.type) { @@ -122,18 +122,11 @@ class OffersListScroll( else tradeButton.disable() // for instance we have negative gold - if (expanderContents.containsKey(offerType)) - expanderContents[offerType]!!.content.add(tradeButton).row() + if (expanderTabs.containsKey(offerType)) + expanderTabs[offerType]!!.innerTable.add(tradeButton).row() else table.add(tradeButton).row() } - - expanderContents[offerType]?.run { - table.add( - ExpanderTab(label, expanderWidth = expanderWidth, - persistenceID = "Trade.$persistenceID.$offerType", content = content) - ).row() - } } actor = table } diff --git a/core/src/com/unciv/ui/screens/mapeditorscreen/tabs/MapEditorViewTab.kt b/core/src/com/unciv/ui/screens/mapeditorscreen/tabs/MapEditorViewTab.kt index 5cd800a583..4a45a1d6bf 100644 --- a/core/src/com/unciv/ui/screens/mapeditorscreen/tabs/MapEditorViewTab.kt +++ b/core/src/com/unciv/ui/screens/mapeditorscreen/tabs/MapEditorViewTab.kt @@ -120,11 +120,12 @@ class MapEditorViewTab( "{Natural Wonders} (${naturalWonders.size})", fontSize = 21, startsOutOpened = false, - headerPad = 5f, - content = MarkupRenderer.render(lines, iconDisplay = IconDisplay.NoLink) { - scrollToWonder(it) - } - )).row() + headerPad = 5f + ) { + it.add(MarkupRenderer.render(lines, iconDisplay = IconDisplay.NoLink) { name-> + scrollToWonder(name) + }) + }).row() } // Starting locations not cached like natural wonders - storage is already compact @@ -135,11 +136,12 @@ class MapEditorViewTab( "{Starting locations} (${tileMap.startingLocationsByNation.size})", fontSize = 21, startsOutOpened = false, - headerPad = 5f, - content = MarkupRenderer.render(lines.asIterable(), iconDisplay = IconDisplay.NoLink) { - scrollToStartOfNation(it) - } - )).row() + headerPad = 5f + ) { + it.add(MarkupRenderer.render(lines.asIterable(), iconDisplay = IconDisplay.NoLink) { name -> + scrollToStartOfNation(name) + }) + }).row() } addSeparator() diff --git a/core/src/com/unciv/ui/screens/newgamescreen/NewGameScreen.kt b/core/src/com/unciv/ui/screens/newgamescreen/NewGameScreen.kt index a6c20d7d72..e87df08215 100644 --- a/core/src/com/unciv/ui/screens/newgamescreen/NewGameScreen.kt +++ b/core/src/com/unciv/ui/screens/newgamescreen/NewGameScreen.kt @@ -244,20 +244,23 @@ class NewGameScreen( private fun initPortrait() { scrollPane.setScrollingDisabled(false,false) - topTable.add(ExpanderTab("Game Options", content = newGameOptionsTable)) - .expandX().fillX().row() + topTable.add(ExpanderTab("Game Options") { + it.add(newGameOptionsTable).row() + }).expandX().fillX().row() topTable.addSeparator(Color.DARK_GRAY, height = 1f) topTable.add(newGameOptionsTable.modCheckboxes).expandX().fillX().row() topTable.addSeparator(Color.DARK_GRAY, height = 1f) - topTable.add(ExpanderTab("Map Options", content = mapOptionsTable)) - .expandX().fillX().row() + topTable.add(ExpanderTab("Map Options") { + it.add(mapOptionsTable).row() + }).expandX().fillX().row() topTable.addSeparator(Color.DARK_GRAY, height = 1f) (playerPickerTable.playerListTable.parent as ScrollPane).setScrollingDisabled(true,true) - topTable.add(ExpanderTab("Civilizations", content = playerPickerTable)) - .expandX().fillX().row() + topTable.add(ExpanderTab("Civilizations") { + it.add(playerPickerTable).row() + }).expandX().fillX().row() } private fun checkConnectionToMultiplayerServer(): Boolean { diff --git a/core/src/com/unciv/ui/screens/pickerscreens/ModManagementScreen.kt b/core/src/com/unciv/ui/screens/pickerscreens/ModManagementScreen.kt index b9d3b61ad4..f72306c478 100644 --- a/core/src/com/unciv/ui/screens/pickerscreens/ModManagementScreen.kt +++ b/core/src/com/unciv/ui/screens/pickerscreens/ModManagementScreen.kt @@ -158,16 +158,21 @@ class ModManagementScreen( topTable.add(optionsManager.expander).top().growX().row() - installedExpanderTab = ExpanderTab(optionsManager.getInstalledHeader(), expanderWidth = stage.width, content = scrollInstalledMods) + installedExpanderTab = ExpanderTab(optionsManager.getInstalledHeader(), expanderWidth = stage.width) { + it.add(scrollInstalledMods).growX() + } topTable.add(installedExpanderTab).top().growX().row() - onlineExpanderTab = ExpanderTab(optionsManager.getOnlineHeader(), expanderWidth = stage.width, content = scrollOnlineMods) + onlineExpanderTab = ExpanderTab(optionsManager.getOnlineHeader(), expanderWidth = stage.width) { + it.add(scrollOnlineMods).growX() + } topTable.add(onlineExpanderTab).top().padTop(10f).growX().row() topTable.add().expandY().row() // helps with top() being ignored - topTable.add(ExpanderTab("Mod info and options", expanderWidth = stage.width, content = modActionTable)) - .bottom().padTop(10f).growX().row() + topTable.add(ExpanderTab("Mod info and options", expanderWidth = stage.width) { + it.add(modActionTable).growX() + }).bottom().padTop(10f).growX().row() } private fun initLandscape() { diff --git a/core/src/com/unciv/ui/screens/worldscreen/mainmenu/WorldScreenMusicPopup.kt b/core/src/com/unciv/ui/screens/worldscreen/mainmenu/WorldScreenMusicPopup.kt index 65488a3bea..7b4208cdcf 100644 --- a/core/src/com/unciv/ui/screens/worldscreen/mainmenu/WorldScreenMusicPopup.kt +++ b/core/src/com/unciv/ui/screens/worldscreen/mainmenu/WorldScreenMusicPopup.kt @@ -34,7 +34,7 @@ class WorldScreenMusicPopup( private val musicController = UncivGame.Current.musicController private val trackStyle: TextButton.TextButtonStyle - private val historyTable = Table() + private val historyExpander: ExpanderTab private val visualMods = worldScreen.game.settings.visualMods private val mods = worldScreen.gameInfo.gameParameters.mods @@ -58,19 +58,13 @@ class WorldScreenMusicPopup( trackStyle.disabledFontColor = Color.LIGHT_GRAY addMusicMods(settings) - addHistory() + historyExpander = addHistory() addMusicControls(bottomTable, settings, musicController) - addCloseButton().padTop(10f).padBottom(0f).colspan(2) - - getScrollPane()?.run { - fadeScrollBars = false - if (bottomTable.prefWidth < prefWidth) - bottomTable.width = prefWidth - } + addCloseButton().colspan(2) musicController.onChange { - historyTable.clear() - historyTable.updateTrackList(musicController.getHistory()) + historyExpander.innerTable.clear() + historyExpander.innerTable.updateTrackList(musicController.getHistory()) } } @@ -94,24 +88,24 @@ class WorldScreenMusicPopup( } } - private fun addHistory() = addTrackList("—History—", musicController.getHistory(), historyTable) + private fun addHistory() = addTrackList("—History—", musicController.getHistory()) - private fun addTrackList(title: String, tracks: Sequence, table: Table? = null) { + private fun addTrackList(title: String, tracks: Sequence): ExpanderTab { // Note title is either a mod name or something that cannot be a mod name (thanks to the em-dashes) val icon = when (title) { in mods -> "OtherIcons/Mods" in visualMods -> "UnitPromotionIcons/Scouting" else -> null }?.let { ImageGetter.getImage(it).apply { setSize(18f) } } - val content = table ?: Table() - content.defaults().growX() - content.updateTrackList(tracks) val expander = ExpanderTab(title, Constants.defaultFontSize, icon, startsOutOpened = false, defaultPad = 0f, headerPad = 5f, persistenceID = "MusicPopup.$title", - content = content - ) + ) { + it.updateTrackList(tracks) + } add(expander).colspan(2).growX().row() + + return expander } private fun Table.updateTrackList(tracks: Sequence) {