mirror of
https://github.com/yairm210/Unciv.git
synced 2025-09-25 04:43:05 -04:00
Tabbed pager architecture update (#6460)
* Change TabbedPager mechanism to communicate page activation * Change TabbedPager mechanism for fixed content * OptionsPopup better use of TabbedPager * TabbedPager arrow keys * After-merge patch Co-authored-by: Yair Morgenstern <yairm210@hotmail.com>
This commit is contained in:
parent
5876047bda
commit
8385f814a6
@ -61,9 +61,7 @@ class DiplomacyOverviewTab (
|
||||
update()
|
||||
}
|
||||
|
||||
override fun getFixedContent(): WidgetGroup {
|
||||
return fixedContent
|
||||
}
|
||||
override fun getFixedContent() = fixedContent
|
||||
|
||||
// Refresh content and determine landscape/portrait layout
|
||||
private fun update() {
|
||||
|
@ -52,10 +52,8 @@ class EmpireOverviewScreen(
|
||||
keyPressDispatcher = keyPressDispatcher,
|
||||
capacity = EmpireOverviewCategories.values().size)
|
||||
|
||||
tabbedPager.addPage(Constants.close) {
|
||||
_, _ -> game.setWorldScreen()
|
||||
}
|
||||
tabbedPager.getPageButton(0).setColor(0.75f, 0.1f, 0.1f, 1f)
|
||||
tabbedPager.bindArrowKeys()
|
||||
tabbedPager.addClosePage { game.setWorldScreen() }
|
||||
|
||||
for (category in EmpireOverviewCategories.values()) {
|
||||
val tabState = category.stateTester(viewingPlayer)
|
||||
@ -70,17 +68,8 @@ class EmpireOverviewScreen(
|
||||
icon, iconSize,
|
||||
disabled = tabState != EmpireOverviewTabState.Normal,
|
||||
shortcutKey = category.shortcutKey,
|
||||
scrollAlign = category.scrollAlign,
|
||||
fixedContent = pageObject.getFixedContent(),
|
||||
onDeactivation = { _, _, scrollY -> pageObject.deactivated(scrollY) }
|
||||
) {
|
||||
index, name ->
|
||||
val scrollY = pageObject.activated()
|
||||
if (scrollY != null) tabbedPager.setPageScrollY(index, scrollY)
|
||||
if (name == "Stats")
|
||||
game.settings.addCompletedTutorialTask("See your stats breakdown")
|
||||
game.settings.lastOverviewPage = name
|
||||
}
|
||||
scrollAlign = category.scrollAlign
|
||||
)
|
||||
if (category.name == page)
|
||||
tabbedPager.selectPage(index)
|
||||
}
|
||||
@ -99,6 +88,6 @@ class EmpireOverviewScreen(
|
||||
|
||||
fun resizePage(tab: EmpireOverviewTab) {
|
||||
val category = (pageObjects.entries.find { it.value == tab } ?: return).key
|
||||
tabbedPager.replacePage(category.name, tab, tab.getFixedContent())
|
||||
tabbedPager.replacePage(category.name, tab)
|
||||
}
|
||||
}
|
||||
|
@ -2,10 +2,10 @@ package com.unciv.ui.overviewscreen
|
||||
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Label
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Table
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.WidgetGroup
|
||||
import com.badlogic.gdx.utils.Align
|
||||
import com.unciv.logic.civilization.CivilizationInfo
|
||||
import com.unciv.ui.utils.BaseScreen
|
||||
import com.unciv.ui.utils.TabbedPager
|
||||
import com.unciv.ui.utils.packIfNeeded
|
||||
import com.unciv.ui.utils.toLabel
|
||||
|
||||
@ -13,17 +13,18 @@ abstract class EmpireOverviewTab (
|
||||
val viewingPlayer: CivilizationInfo,
|
||||
val overviewScreen: EmpireOverviewScreen,
|
||||
persistedData: EmpireOverviewTabPersistableData? = null
|
||||
) : Table(BaseScreen.skin) {
|
||||
) : Table(BaseScreen.skin), TabbedPager.IPageExtensions {
|
||||
open class EmpireOverviewTabPersistableData {
|
||||
open fun isEmpty() = true
|
||||
}
|
||||
open val persistableData = persistedData ?: EmpireOverviewTabPersistableData()
|
||||
/** Override if your Tab needs to do stuff on activation. @return non-null to scroll the Tab vertically within the TabbedPager. */
|
||||
open fun activated(): Float? = null
|
||||
/** Override if your Tab needs to do housekeeping when it loses focus. [scrollY] is the Tab's current vertical scroll position. */
|
||||
open fun deactivated(scrollY: Float) {}
|
||||
/** Override to supply content not participating in scrolling */
|
||||
open fun getFixedContent(): WidgetGroup? = null
|
||||
|
||||
override fun activated(index: Int, caption: String, pager: TabbedPager) {
|
||||
val settings = overviewScreen.game.settings
|
||||
if (caption == "Stats")
|
||||
settings.addCompletedTutorialTask("See your stats breakdown")
|
||||
settings.lastOverviewPage = caption
|
||||
}
|
||||
|
||||
val gameInfo = viewingPlayer.gameInfo
|
||||
|
||||
|
@ -37,8 +37,7 @@ class ReligionOverviewTab(
|
||||
private val statsTable = Table()
|
||||
private val beliefsTable = Table()
|
||||
|
||||
override fun getFixedContent(): WidgetGroup? {
|
||||
return Table().apply {
|
||||
override fun getFixedContent() = Table().apply {
|
||||
defaults().pad(5f)
|
||||
align(Align.top)
|
||||
|
||||
@ -49,7 +48,6 @@ class ReligionOverviewTab(
|
||||
add(religionButtonLabel)
|
||||
addSeparator()
|
||||
}
|
||||
}
|
||||
|
||||
init {
|
||||
defaults().pad(5f)
|
||||
|
@ -3,7 +3,6 @@ package com.unciv.ui.overviewscreen
|
||||
import com.badlogic.gdx.graphics.Color
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Label
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Table
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.WidgetGroup
|
||||
import com.badlogic.gdx.utils.Align
|
||||
import com.unciv.UncivGame
|
||||
import com.unciv.logic.civilization.CivilizationInfo
|
||||
|
@ -4,7 +4,6 @@ import com.badlogic.gdx.graphics.Color
|
||||
import com.badlogic.gdx.math.Vector2
|
||||
import com.badlogic.gdx.scenes.scene2d.Group
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Table
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.WidgetGroup
|
||||
import com.badlogic.gdx.utils.Align
|
||||
import com.unciv.Constants
|
||||
import com.unciv.logic.civilization.CivilizationInfo
|
||||
@ -30,9 +29,13 @@ class UnitOverviewTab(
|
||||
}
|
||||
override val persistableData = (persistedData as? UnitTabPersistableData) ?: UnitTabPersistableData()
|
||||
|
||||
override fun activated() = persistableData.scrollY
|
||||
override fun deactivated(scrollY: Float) {
|
||||
persistableData.scrollY = scrollY
|
||||
override fun activated(index: Int, caption: String, pager: TabbedPager) {
|
||||
if (persistableData.scrollY != null)
|
||||
pager.setPageScrollY(index, persistableData.scrollY!!)
|
||||
super.activated(index, caption, pager)
|
||||
}
|
||||
override fun deactivated(index: Int, caption: String, pager: TabbedPager) {
|
||||
persistableData.scrollY = pager.getPageScrollY(index)
|
||||
}
|
||||
|
||||
private val supplyTableWidth = (overviewScreen.stage.width * 0.25f).coerceAtLeast(240f)
|
||||
@ -40,9 +43,7 @@ class UnitOverviewTab(
|
||||
private val unitHeaderTable = Table()
|
||||
private val fixedContent = Table()
|
||||
|
||||
override fun getFixedContent(): WidgetGroup {
|
||||
return fixedContent
|
||||
}
|
||||
override fun getFixedContent() = fixedContent
|
||||
|
||||
init {
|
||||
fixedContent.add(getUnitSupplyTable()).align(Align.top).padBottom(10f).row()
|
||||
|
@ -81,9 +81,7 @@ class WonderOverviewTab(
|
||||
private val wonders: Array<WonderInfo> = collectInfo()
|
||||
|
||||
private val fixedContent = Table()
|
||||
override fun getFixedContent(): WidgetGroup {
|
||||
return fixedContent
|
||||
}
|
||||
override fun getFixedContent() = fixedContent
|
||||
|
||||
init {
|
||||
fixedContent.apply {
|
||||
|
@ -1,5 +1,6 @@
|
||||
package com.unciv.ui.utils
|
||||
|
||||
import com.badlogic.gdx.Input
|
||||
import com.badlogic.gdx.graphics.Color
|
||||
import com.badlogic.gdx.scenes.scene2d.*
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.*
|
||||
@ -9,11 +10,8 @@ import com.unciv.Constants
|
||||
import com.unciv.UncivGame
|
||||
import com.unciv.ui.utils.UncivTooltip.Companion.addTooltip
|
||||
|
||||
|
||||
/*
|
||||
Unimplemented ideas:
|
||||
Use fixedContent for OptionsPopup mod check tab
|
||||
*/
|
||||
//TODO If keys are assigned, the widget is in a popup not filling stage width, and a button is
|
||||
// partially visible on the right end, the key tooltip will show outside the parent.
|
||||
|
||||
/**
|
||||
* Implements a 'Tabs' widget where different pages can be switched by selecting a header button.
|
||||
@ -72,10 +70,27 @@ class TabbedPager(
|
||||
private val fixedContentScroll = LinkedScrollPane(horizontalOnly = true)
|
||||
private val fixedContentScrollCell: Cell<ScrollPane>
|
||||
private val contentScroll = LinkedScrollPane(horizontalOnly = false, linkTo = fixedContentScroll)
|
||||
private var savedScrollListener: EventListener? = null
|
||||
|
||||
private val deferredSecretPages = ArrayDeque<PageState>(0)
|
||||
private var askPasswordLock = false
|
||||
|
||||
//endregion
|
||||
//region Public Interfaces
|
||||
|
||||
/** Pages added via [addPage] can optionally implement this to get notified when they are
|
||||
* [activated] or [deactivated], or to provide [fixed content][getFixedContent] */
|
||||
interface IPageExtensions {
|
||||
/** Called by [TabbedPager] after a page is shown, whether by user click or programmatically. */
|
||||
fun activated(index: Int, caption: String, pager: TabbedPager)
|
||||
|
||||
/** Called by [TabbedPager] before a page is hidden, whether by user click or programmatically. */
|
||||
fun deactivated(index: Int, caption: String, pager: TabbedPager) {}
|
||||
|
||||
/** @return Optional second content [Actor], will be placed outside the tab's main [ScrollPane] between header and `content`. Scrolls horizontally only. */
|
||||
fun getFixedContent(): Actor? = null
|
||||
}
|
||||
|
||||
//endregion
|
||||
//region Private Classes
|
||||
|
||||
@ -84,8 +99,6 @@ class TabbedPager(
|
||||
var content: Actor,
|
||||
var fixedContent: Actor?,
|
||||
var disabled: Boolean,
|
||||
val onActivation: ((Int, String) -> Unit)?,
|
||||
val onDeactivation: ((Int, String, Float) -> Unit)?,
|
||||
icon: Actor?,
|
||||
iconSize: Float,
|
||||
val shortcutKey: KeyCharAndCode,
|
||||
@ -247,6 +260,12 @@ class TabbedPager(
|
||||
}
|
||||
}
|
||||
|
||||
private class EmptyClosePage(private val action: ()->Unit) : Actor(), IPageExtensions {
|
||||
override fun activated(index: Int, caption: String, pager: TabbedPager) {
|
||||
action()
|
||||
}
|
||||
}
|
||||
|
||||
//endregion
|
||||
//region Initialization
|
||||
|
||||
@ -312,7 +331,7 @@ class TabbedPager(
|
||||
|
||||
if (activePage != -1) {
|
||||
val page = pages[activePage]
|
||||
page.onDeactivation?.invoke(activePage, page.caption, contentScroll.scrollY)
|
||||
(page.content as? IPageExtensions)?.deactivated(activePage, page.caption, this)
|
||||
page.button.color = Color.WHITE
|
||||
fixedContentScroll.actor = null
|
||||
page.scrollX = contentScroll.scrollX
|
||||
@ -359,7 +378,8 @@ class TabbedPager(
|
||||
else
|
||||
// when coming from a tap/click, can we at least ensure no part of it is outside the visible area
|
||||
headerScroll.run { scrollX = scrollX.coerceIn((page.buttonX + page.buttonW - scrollWidth)..page.buttonX) }
|
||||
page.onActivation?.invoke(index, page.caption)
|
||||
|
||||
(page.content as? IPageExtensions)?.activated(index, page.caption, this)
|
||||
}
|
||||
return true
|
||||
}
|
||||
@ -393,6 +413,12 @@ class TabbedPager(
|
||||
/** Access a page's header button e.g. for unusual formatting */
|
||||
fun getPageButton(index: Int) = pages[index].button
|
||||
|
||||
/** Query the vertical scroll position af a page's contents */
|
||||
fun getPageScrollY(index: Int): Float {
|
||||
if (index == activePage) return contentScroll.scrollY
|
||||
if (index !in 0 until pages.size) return 0f
|
||||
return pages[index].scrollY
|
||||
}
|
||||
/** Change the vertical scroll position af a page's contents */
|
||||
fun setPageScrollY(index: Int, scrollY: Float, animation: Boolean = false) {
|
||||
if (index !in 0 until pages.size) return
|
||||
@ -403,6 +429,32 @@ class TabbedPager(
|
||||
if (!animation) contentScroll.updateVisualScroll()
|
||||
}
|
||||
|
||||
/** Disable/Enable built-in ScrollPane for content pages, including focus stealing prevention */
|
||||
fun setScrollDisabled(disabled: Boolean) {
|
||||
if (disabled == contentScroll.isScrollingDisabledY) return
|
||||
contentScroll.setScrollingDisabled(disabled, disabled)
|
||||
if (disabled) {
|
||||
savedScrollListener = contentScroll.captureListeners.first()
|
||||
contentScroll.captureListeners.clear()
|
||||
} else {
|
||||
if (savedScrollListener != null)
|
||||
contentScroll.addCaptureListener(savedScrollListener)
|
||||
}
|
||||
}
|
||||
|
||||
/** Bind arrow keys to navigate pages left/right.
|
||||
* Needs [keyPressDispatcher] to be set on instantiation.
|
||||
* Caller is responsible for cleanup if necessary. */
|
||||
fun bindArrowKeys() {
|
||||
if (keyPressDispatcher == null) return
|
||||
fun cyclePage(direction: Int) {
|
||||
if (activePage == -1) return
|
||||
selectPage((activePage + direction).coerceIn(0 until pages.size))
|
||||
}
|
||||
keyPressDispatcher[KeyCharAndCode(Input.Keys.LEFT)] = { cyclePage(-1) }
|
||||
keyPressDispatcher[KeyCharAndCode(Input.Keys.RIGHT)] = { cyclePage(1) }
|
||||
}
|
||||
|
||||
/** Remove a page by its index.
|
||||
* @return `true` if page successfully removed */
|
||||
fun removePage(index: Int): Boolean {
|
||||
@ -425,18 +477,7 @@ class TabbedPager(
|
||||
if (isActive) selectPage(-1)
|
||||
pages[index].let {
|
||||
it.content = content
|
||||
measureContent(it)
|
||||
}
|
||||
if (isActive) selectPage(index)
|
||||
}
|
||||
/** Replace a page's [content] and [fixedContent] by its [index]. */
|
||||
fun replacePage(index: Int, content: Actor, fixedContent: Actor?) {
|
||||
if (index !in 0 until pages.size) return
|
||||
val isActive = index == activePage
|
||||
if (isActive) selectPage(-1)
|
||||
pages[index].let {
|
||||
it.content = content
|
||||
it.fixedContent = fixedContent
|
||||
it.fixedContent = (content as? IPageExtensions)?.getFixedContent()
|
||||
measureContent(it)
|
||||
}
|
||||
if (isActive) selectPage(index)
|
||||
@ -444,22 +485,17 @@ class TabbedPager(
|
||||
|
||||
/** Replace a page's [content] by its [caption]. */
|
||||
fun replacePage(caption: String, content: Actor) = replacePage(getPageIndex(caption), content)
|
||||
/** Replace a page's [content] and [fixedContent] by its [caption]. */
|
||||
fun replacePage(caption: String, content: Actor, fixedContent: Actor?) = replacePage(getPageIndex(caption), content, fixedContent)
|
||||
|
||||
/** Add a page!
|
||||
* @param caption Text to be shown on the header button (automatically translated), can later be used to reference the page in other calls.
|
||||
* @param content [Actor] to show in the lower area when this page is selected.
|
||||
* @param content [Actor] to show in the lower area when this page is selected. Can optionally implement [IPageExtensions] to be notified of activation or deactivation.
|
||||
* @param icon Actor, typically an [Image], to show before the caption on the header button.
|
||||
* @param iconSize Size for [icon] - if not zero, the icon is wrapped to allow a [setSize] even on [Image] which ignores size.
|
||||
* @param insertBefore -1 to add at the end, or index of existing page to insert this before it.
|
||||
* @param secret Marks page as 'secret'. A password is asked once per [TabbedPager] and if it does not match the has passed in the constructor the page and all subsequent secret pages are dropped.
|
||||
* @param disabled Initial disabled state. Disabled pages cannot be selected even with [selectPage], their button is dimmed.
|
||||
* @param shortcutKey Optional keyboard key to associate - goes to the [KeyPressDispatcher] passed in the constructor.
|
||||
* @param syncScroll If on, the ScrollPanes for [content] and [fixedContent] will synchronize horizontally.
|
||||
* @param fixedContent Optional second content [Actor], will be placed outside the tab's main [ScrollPane] between header and [content]. Scrolls horizontally only.
|
||||
* @param onDeactivation _Optional_ callback called when this page is hidden. Lambda arguments are page index and caption, and scrollY of the tab's [ScrollPane].
|
||||
* @param onActivation _Optional_ callback called when this page is shown (per actual change to this page, not per header click). Lambda arguments are page index and caption.
|
||||
* @param syncScroll If on, the ScrollPanes for [content] and [fixed content][IPageExtensions.getFixedContent] will synchronize horizontally.
|
||||
* @return The new page's index or -1 if it could not be immediately added (secret).
|
||||
*/
|
||||
fun addPage(
|
||||
@ -472,19 +508,14 @@ class TabbedPager(
|
||||
disabled: Boolean = false,
|
||||
shortcutKey: KeyCharAndCode = KeyCharAndCode.UNKNOWN,
|
||||
scrollAlign: Int = Align.top,
|
||||
syncScroll: Boolean = true,
|
||||
fixedContent: Actor? = null,
|
||||
onDeactivation: ((Int, String, Float) -> Unit)? = null,
|
||||
onActivation: ((Int, String) -> Unit)? = null
|
||||
syncScroll: Boolean = true
|
||||
): Int {
|
||||
// Build page descriptor and header button
|
||||
val page = PageState(
|
||||
caption = caption,
|
||||
content = content ?: Group(),
|
||||
fixedContent = fixedContent,
|
||||
fixedContent = (content as? IPageExtensions)?.getFixedContent(),
|
||||
disabled = disabled,
|
||||
onActivation = onActivation,
|
||||
onDeactivation = onDeactivation,
|
||||
icon = icon,
|
||||
iconSize = iconSize,
|
||||
shortcutKey = shortcutKey,
|
||||
@ -514,6 +545,18 @@ class TabbedPager(
|
||||
return addAndShowPage(page, insertBefore)
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a "Close" button tho the Tab headers, with empty content which will invoke [action] when clicked
|
||||
*/
|
||||
fun addClosePage(
|
||||
insertBefore: Int = -1,
|
||||
color: Color = Color(0.75f, 0.1f, 0.1f, 1f),
|
||||
action: ()->Unit
|
||||
) {
|
||||
val index = addPage(Constants.close, EmptyClosePage(action), insertBefore = insertBefore)
|
||||
pages[index].button.color = color
|
||||
}
|
||||
|
||||
/**
|
||||
* Activate any [secret][addPage] pages by asking for the password.
|
||||
*
|
||||
|
@ -16,6 +16,7 @@ import com.unciv.UncivGame
|
||||
import com.unciv.logic.MapSaver
|
||||
import com.unciv.logic.civilization.PlayerType
|
||||
import com.unciv.models.UncivSound
|
||||
import com.unciv.models.metadata.BaseRuleset
|
||||
import com.unciv.models.ruleset.Ruleset
|
||||
import com.unciv.models.ruleset.Ruleset.RulesetError
|
||||
import com.unciv.models.ruleset.Ruleset.RulesetErrorSeverity
|
||||
@ -59,7 +60,6 @@ class OptionsPopup(val previousScreen: BaseScreen) : Popup(previousScreen) {
|
||||
private var modCheckBaseSelect: TranslatedSelectBox? = null
|
||||
private val modCheckResultTable = Table()
|
||||
private val selectBoxMinWidth: Float
|
||||
private val previousMaxWorldZoom = settings.maxWorldZoomOut
|
||||
|
||||
//endregion
|
||||
|
||||
@ -81,7 +81,7 @@ class OptionsPopup(val previousScreen: BaseScreen) : Popup(previousScreen) {
|
||||
tabMaxHeight = (if (isPortrait()) 0.7f else 0.8f) * stage.height
|
||||
}
|
||||
tabs = TabbedPager(tabMinWidth, tabMaxWidth, 0f, tabMaxHeight,
|
||||
headerFontSize = 21, backgroundColor = Color.CLEAR, capacity = 8)
|
||||
headerFontSize = 21, backgroundColor = Color.CLEAR, keyPressDispatcher = this.keyPressDispatcher, capacity = 8)
|
||||
add(tabs).pad(0f).grow().row()
|
||||
|
||||
tabs.addPage("About", getAboutTab(), ImageGetter.getExternalImage("Icon.png"), 24f)
|
||||
@ -91,14 +91,17 @@ class OptionsPopup(val previousScreen: BaseScreen) : Popup(previousScreen) {
|
||||
tabs.addPage("Sound", getSoundTab(), ImageGetter.getImage("OtherIcons/Speaker"), 24f)
|
||||
tabs.addPage("Multiplayer", getMultiplayerTab(), ImageGetter.getImage("OtherIcons/Multiplayer"), 24f)
|
||||
tabs.addPage("Advanced", getAdvancedTab(), ImageGetter.getImage("OtherIcons/Settings"), 24f)
|
||||
if (RulesetCache.size > 1) {
|
||||
tabs.addPage("Locate mod errors", getModCheckTab(), ImageGetter.getImage("OtherIcons/Mods"), 24f) { _, _ ->
|
||||
if (RulesetCache.size > BaseRuleset.values().size) {
|
||||
val content = ModCheckTab(this) {
|
||||
if (modCheckFirstRun) runModChecker()
|
||||
else runModChecker(modCheckBaseSelect!!.selected.value)
|
||||
}
|
||||
tabs.addPage("Locate mod errors", content, ImageGetter.getImage("OtherIcons/Mods"), 24f)
|
||||
}
|
||||
if (Gdx.input.isKeyPressed(Input.Keys.SHIFT_RIGHT) && (Gdx.input.isKeyPressed(Input.Keys.CONTROL_RIGHT) || Gdx.input.isKeyPressed(Input.Keys.ALT_RIGHT))) {
|
||||
tabs.addPage("Debug", getDebugTab(), ImageGetter.getImage("OtherIcons/SecretOptions"), 24f, secret = true)
|
||||
}
|
||||
tabs.bindArrowKeys() // If we're sharing WorldScreen's dispatcher that's OK since it does revertToCheckPoint on update
|
||||
|
||||
addCloseButton {
|
||||
previousScreen.game.musicController.onChange(null)
|
||||
@ -274,27 +277,22 @@ class OptionsPopup(val previousScreen: BaseScreen) : Popup(previousScreen) {
|
||||
settings.save()
|
||||
connectionToServerButton.isEnabled = multiplayerServerTextField.text != Constants.dropboxMultiplayerServer
|
||||
}
|
||||
serverIpTable.add(multiplayerServerTextField).width(screen.stage.width / 2)
|
||||
add(serverIpTable).row()
|
||||
serverIpTable.add(multiplayerServerTextField).minWidth(screen.stage.width / 2).growX()
|
||||
add(serverIpTable).fillX().row()
|
||||
|
||||
add("Reset to Dropbox".toTextButton().onClick {
|
||||
multiplayerServerTextField.text = Constants.dropboxMultiplayerServer
|
||||
}).row()
|
||||
|
||||
add(connectionToServerButton.onClick {
|
||||
val popup = Popup(screen).apply {
|
||||
val popup = Popup(screen).apply {
|
||||
addGoodSizedLabel("Awaiting response...").row()
|
||||
}
|
||||
popup.open(true)
|
||||
|
||||
successfullyConnectedToServer { success: Boolean, result: String ->
|
||||
if (success) {
|
||||
popup.addGoodSizedLabel("Success!").row()
|
||||
popup.addCloseButton()
|
||||
} else {
|
||||
popup.addGoodSizedLabel("Failed!").row()
|
||||
popup.addCloseButton()
|
||||
}
|
||||
successfullyConnectedToServer { success: Boolean, _: String ->
|
||||
popup.addGoodSizedLabel(if (success) "Success!" else "Failed!").row()
|
||||
popup.addCloseButton()
|
||||
}
|
||||
}).row()
|
||||
}
|
||||
@ -373,27 +371,38 @@ class OptionsPopup(val previousScreen: BaseScreen) : Popup(previousScreen) {
|
||||
addSetUserId()
|
||||
}
|
||||
|
||||
private fun getModCheckTab() = Table(BaseScreen.skin).apply {
|
||||
defaults().pad(10f).align(Align.top)
|
||||
val reloadModsButton = "Reload mods".toTextButton().onClick {
|
||||
runModChecker(modCheckBaseSelect!!.selected.value)
|
||||
}
|
||||
add(reloadModsButton).row()
|
||||
private class ModCheckTab(
|
||||
options: OptionsPopup,
|
||||
private val runAction: ()->Unit
|
||||
) : Table(), TabbedPager.IPageExtensions {
|
||||
private val fixedContent = Table()
|
||||
|
||||
val labeledBaseSelect = Table(BaseScreen.skin).apply {
|
||||
add("Check extension mods based on:".toLabel()).padRight(10f)
|
||||
val baseMods = listOf(modCheckWithoutBase) + RulesetCache.getSortedBaseRulesets()
|
||||
modCheckBaseSelect = TranslatedSelectBox(baseMods, modCheckWithoutBase, BaseScreen.skin).apply {
|
||||
selectedIndex = 0
|
||||
onChange {
|
||||
runModChecker(modCheckBaseSelect!!.selected.value)
|
||||
init {
|
||||
defaults().pad(10f).align(Align.top)
|
||||
|
||||
fixedContent.defaults().pad(10f).align(Align.top)
|
||||
val reloadModsButton = "Reload mods".toTextButton().onClick(runAction)
|
||||
fixedContent.add(reloadModsButton).row()
|
||||
|
||||
val labeledBaseSelect = Table().apply {
|
||||
add("Check extension mods based on:".toLabel()).padRight(10f)
|
||||
val baseMods = listOf(modCheckWithoutBase) + RulesetCache.getSortedBaseRulesets()
|
||||
options.modCheckBaseSelect = TranslatedSelectBox(baseMods, modCheckWithoutBase, BaseScreen.skin).apply {
|
||||
selectedIndex = 0
|
||||
onChange { runAction() }
|
||||
}
|
||||
add(options.modCheckBaseSelect)
|
||||
}
|
||||
add(modCheckBaseSelect)
|
||||
}
|
||||
add(labeledBaseSelect).row()
|
||||
fixedContent.add(labeledBaseSelect).row()
|
||||
|
||||
add(modCheckResultTable)
|
||||
add(options.modCheckResultTable)
|
||||
}
|
||||
|
||||
override fun getFixedContent() = fixedContent
|
||||
|
||||
override fun activated(index: Int, caption: String, pager: TabbedPager) {
|
||||
runAction()
|
||||
}
|
||||
}
|
||||
|
||||
private fun runModChecker(base: String = modCheckWithoutBase) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user