diff --git a/core/src/com/unciv/logic/files/FileChooser.kt b/core/src/com/unciv/logic/files/FileChooser.kt index cd44b7ac0a..c2144c040f 100644 --- a/core/src/com/unciv/logic/files/FileChooser.kt +++ b/core/src/com/unciv/logic/files/FileChooser.kt @@ -19,7 +19,7 @@ import com.badlogic.gdx.utils.Align import com.unciv.Constants import com.unciv.models.UncivSound import com.unciv.models.translations.tr -import com.unciv.ui.components.UncivTextField +import com.unciv.ui.components.widgets.UncivTextField import com.unciv.ui.components.extensions.addSeparator import com.unciv.ui.components.extensions.isEnabled import com.unciv.ui.components.extensions.toLabel @@ -65,7 +65,7 @@ open class FileChooser( } // components - private val fileNameInput = UncivTextField.create("Please enter a file name") + private val fileNameInput = UncivTextField("Please enter a file name") private val fileNameLabel = "File name:".toLabel() private val fileNameWrapper = Table().apply { defaults().space(10f) diff --git a/core/src/com/unciv/ui/components/UncivTextField.kt b/core/src/com/unciv/ui/components/UncivTextField.kt deleted file mode 100644 index 19cb115d95..0000000000 --- a/core/src/com/unciv/ui/components/UncivTextField.kt +++ /dev/null @@ -1,240 +0,0 @@ -package com.unciv.ui.components - -import com.badlogic.gdx.Application -import com.badlogic.gdx.Gdx -import com.badlogic.gdx.graphics.g2d.Batch -import com.badlogic.gdx.graphics.g2d.BitmapFont -import com.badlogic.gdx.math.Vector2 -import com.badlogic.gdx.scenes.scene2d.Actor -import com.badlogic.gdx.scenes.scene2d.InputEvent -import com.badlogic.gdx.scenes.scene2d.InputListener -import com.badlogic.gdx.scenes.scene2d.ui.ScrollPane -import com.badlogic.gdx.scenes.scene2d.ui.TextField -import com.badlogic.gdx.scenes.scene2d.utils.FocusListener -import com.unciv.Constants -import com.unciv.logic.event.EventBus -import com.unciv.models.translations.tr -import com.unciv.ui.components.extensions.getAscendant -import com.unciv.ui.components.extensions.getOverlap -import com.unciv.ui.components.extensions.right -import com.unciv.ui.components.extensions.stageBoundingBox -import com.unciv.ui.components.extensions.top -import com.unciv.ui.components.input.KeyCharAndCode -import com.unciv.ui.components.input.keyShortcuts -import com.unciv.ui.popups.Popup -import com.unciv.ui.screens.basescreen.BaseScreen -import com.unciv.ui.screens.basescreen.UncivStage -import com.unciv.utils.Concurrency -import com.unciv.utils.withGLContext -import kotlinx.coroutines.delay - -object UncivTextField { - /** - * Creates a text field that has nicer platform-specific input added compared to the default Gdx [TextField]. - * - * - On Android, manages on-screen keyboard visibility and reacts to how the on-screen keyboard reduces screen space. - * - Tries to scroll the field into view when receiving focus using an ascendant ScrollPane. - * - If view of the field is still obscured, show am "emergency" Popup instead (can help when on Android the on-screen keyboard is large and the screen small). - * - If this TextField handles the Tab key (see [keyShortcuts]), its [focus navigation feature][TextField.next] is disabled (otherwise it would search for another TextField in the same parent to give focus to, and remove the on-screen keyboard if it finds none). - * - All parameters are supported on all platforms. - * - * @param hint The text that should be displayed in the text field when no text is entered and it does not have focus, will automatically be translated. Also shown as Label in the "emergency" Popup. - * @param preEnteredText the text initially entered within this text field. - * @param onFocusChange a callback that will be notified when this TextField loses or gains the [keyboardFocus][com.badlogic.gdx.scenes.scene2d.Stage.keyboardFocus]. - * Receiver is the field, so you can simply use its elements. Parameter `it` is a Boolean indicating focus was received. - */ - fun create(hint: String, preEnteredText: String = "", onFocusChange: (TextField.(Boolean) -> Unit)? = null): TextField { - @Suppress("UNCIV_RAW_TEXTFIELD") - val textField = object : TextField(preEnteredText, BaseScreen.skin) { - override fun next(up: Boolean) { - if (KeyCharAndCode.TAB in keyShortcuts) return - super.next(up) - } - - // Note - this way to force TextField to display `[]` characters normally is an incomplete hack. - // The complete way would either require overriding `updateDisplayText` which is private, or all methods calling it, - // which are many including the keyboard listener, or keep a separate font without markup enabled around and put that - // into the default style, including its own NativeBitmapFontData instance and texture - involves quite some redesign. - // That said, observing the deficiency is hard - the internal `glyphPositions` could theoretically get out of sync, affecting selection and caret display. - override fun layout() { - val oldEnable = style.font.data.markupEnabled - style.font.data.markupEnabled = false - super.layout() - style.font.data.markupEnabled = oldEnable - } - override fun drawText(batch: Batch, font: BitmapFont, x: Float, y: Float) { - val oldEnable = font.data.markupEnabled - font.data.markupEnabled = false - super.drawText(batch, font, x, y) - font.data.markupEnabled = oldEnable - } - } - val translatedHint = hint.tr() - textField.messageText = translatedHint - textField.addListener(object : FocusListener() { - override fun keyboardFocusChanged(event: FocusEvent, actor: Actor, focused: Boolean) { - if (focused) { - textField.scrollAscendantToTextField() - } - onFocusChange?.invoke(textField, focused) - } - }) - - if (Gdx.app.type == Application.ApplicationType.Android) - TextfieldImprovements.add(textField) - return textField - } -} - -/** - * Tries to scroll a [ScrollPane] ascendant of the text field so that this text field is in the middle of the visible area. - * - * @return true if the text field is visible after this operation - */ -fun TextField.scrollAscendantToTextField(): Boolean { - val stage = this.stage - if (stage !is UncivStage) return false - - val scrollPane = this.getAscendant { it is ScrollPane } as ScrollPane? - val visibleArea = stage.lastKnownVisibleArea - val textFieldStageBoundingBox = this.stageBoundingBox - if (scrollPane == null) return visibleArea.contains(textFieldStageBoundingBox) - - val scrollPaneBounds = scrollPane.stageBoundingBox - val visibleScrollPaneArea = scrollPaneBounds.getOverlap(visibleArea) - if (visibleScrollPaneArea == null) { - return false - } else if (visibleScrollPaneArea.contains(textFieldStageBoundingBox)) { - return true - } - - val scrollContent = scrollPane.actor - val textFieldScrollContentCoords = localToAscendantCoordinates(scrollContent, Vector2(0f, 0f)) - - // It's possible that our textField can't be (fully) scrolled to be within the visible scrollPane area - val pixelsNotVisibleOnLeftSide = (visibleScrollPaneArea.x - scrollPaneBounds.x).coerceAtLeast(0f) - val textFieldDistanceFromLeftSide = textFieldScrollContentCoords.x - val pixelsNotVisibleOnRightSide = (scrollPaneBounds.right - visibleScrollPaneArea.right).coerceAtLeast(0f) - val textFieldDistanceFromRightSide = scrollContent.width - (textFieldScrollContentCoords.x + this.width) - val pixelsNotVisibleOnTop = (scrollPaneBounds.top - visibleScrollPaneArea.top).coerceAtLeast(0f) - val textFieldDistanceFromTop = scrollContent.height - (textFieldScrollContentCoords.y + this.height) - val pixelsNotVisibleOnBottom = (visibleScrollPaneArea.y - scrollPaneBounds.y).coerceAtLeast(0f) - val textFieldDistanceFromBottom = textFieldScrollContentCoords.y - // If the visible scroll pane area is smaller than our text field, it will always be partly obscured - if (visibleScrollPaneArea.width < this.width || visibleScrollPaneArea.height < this.height - // If the amount of pixels obscured near a scrollContent edge is larger than the distance of the text field to that edge, it will always be (partly) obscured - || pixelsNotVisibleOnLeftSide > textFieldDistanceFromLeftSide - || pixelsNotVisibleOnRightSide > textFieldDistanceFromRightSide - || pixelsNotVisibleOnTop > textFieldDistanceFromTop - || pixelsNotVisibleOnBottom > textFieldDistanceFromBottom) { - return false - } - - // We want to put the text field in the middle of the visible area - val scrollXMiddle = textFieldScrollContentCoords.x - this.width / 2 + visibleScrollPaneArea.width / 2 - // If the visible area is to the right of the left edge of the scroll pane, we need to scroll that much farther to get to the real visible middle - scrollPane.scrollX = pixelsNotVisibleOnLeftSide + scrollXMiddle - - // ScrollPane.scrollY has the origin at the top instead of at the bottom, so + for height / 2 instead of - - // We want to put the text field in the middle of the visible area - val scrollYMiddleGdxOrigin = textFieldScrollContentCoords.y + this.height / 2 + visibleScrollPaneArea.height / 2 - // If the visible area is below the top edge of the scroll pane, we need to scroll that much farther to get to the real visible middle - // Also, convert to scroll pane origin (0 is on top instead of bottom) - scrollPane.scrollY = pixelsNotVisibleOnTop + scrollContent.height - scrollYMiddleGdxOrigin - - return true -} - -object TextfieldImprovements { - private val hideKeyboard = { Gdx.input.setOnscreenKeyboardVisible(false) } - fun add(textField: TextField): TextField { - textField.addListener(object : InputListener() { - private val events = EventBus.EventReceiver() - init { - events.receive(UncivStage.VisibleAreaChanged::class) { - if (textField.stage == null || !textField.hasKeyboardFocus()) return@receive - Concurrency.run { - // If anything resizes, it also does so with this event. So we need to wait for that to finish to update the scroll position. - delay(100) - withGLContext { - if (textField.stage == null) return@withGLContext - - if (textField.scrollAscendantToTextField()) { - val scrollPane = textField.getAscendant { it is ScrollPane } as ScrollPane? - // when screen dimensions change, we don't want an animation for scrolling, just show, just show the textfield immediately - scrollPane?.updateVisualScroll() - } else { - // We can't scroll the text field into view, so we need to show a popup - TextfieldPopup(textField).open() - } - } - } - } - } - override fun touchDown(event: InputEvent, x: Float, y: Float, pointer: Int, button: Int): Boolean { - addPopupCloseListener(textField) - return false - } - }) - textField.addListener(object : FocusListener() { - override fun keyboardFocusChanged(event: FocusEvent?, actor: Actor?, focused: Boolean) { - if (focused) { - addPopupCloseListener(textField) - Gdx.input.setOnscreenKeyboardVisible(true) - } - } - }) - - return textField - } - - private fun addPopupCloseListener(textField: TextField) { - val popup = textField.getAscendant { it is Popup } as Popup? - if (popup != null && !popup.closeListeners.contains(hideKeyboard)) { - popup.closeListeners.add(hideKeyboard) - } - } -} - -class TextfieldPopup( - textField: TextField -) : Popup(textField.stage) { - val popupTextfield = clone(textField) - init { - addGoodSizedLabel(popupTextfield.messageText) - .colspan(2) - .row() - - add(popupTextfield) - .width(stageToShowOn.width / 2) - .colspan(2) - .row() - - addCloseButton(Constants.cancel) - .left() - addOKButton { textField.text = popupTextfield.text } - .right() - .row() - - showListeners.add { - stageToShowOn.keyboardFocus = popupTextfield - } - closeListeners.add { - stageToShowOn.keyboardFocus = null - Gdx.input.setOnscreenKeyboardVisible(false) - } - } - - private fun clone(textField: TextField): TextField { - @Suppress("UNCIV_RAW_TEXTFIELD") // we are copying the existing text field - val copy = TextField(textField.text, textField.style) - copy.textFieldFilter = textField.textFieldFilter - copy.messageText = textField.messageText - copy.setSelection(textField.selectionStart, textField.selection.length) - copy.cursorPosition = textField.cursorPosition - copy.alignment = textField.alignment - copy.isPasswordMode = textField.isPasswordMode - copy.onscreenKeyboard = textField.onscreenKeyboard - return copy - } -} diff --git a/core/src/com/unciv/ui/components/widgets/TabbedPager.kt b/core/src/com/unciv/ui/components/widgets/TabbedPager.kt index ac3d9d4366..cafcd9bf80 100644 --- a/core/src/com/unciv/ui/components/widgets/TabbedPager.kt +++ b/core/src/com/unciv/ui/components/widgets/TabbedPager.kt @@ -17,7 +17,6 @@ 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.ui.components.UncivTextField import com.unciv.ui.components.UncivTooltip.Companion.addTooltip import com.unciv.ui.components.extensions.addSeparator import com.unciv.ui.components.extensions.darken @@ -593,7 +592,7 @@ open class TabbedPager( */ fun askForPassword(secretHashCode: Int = 0) { class PassPopup(screen: BaseScreen, unlockAction: ()->Unit, lockAction: ()->Unit) : Popup(screen) { - val passEntry = UncivTextField.create("Password") + val passEntry = UncivTextField("Password") init { passEntry.isPasswordMode = true add(passEntry).row() diff --git a/core/src/com/unciv/ui/components/widgets/TextFieldWithFixes.kt b/core/src/com/unciv/ui/components/widgets/TextFieldWithFixes.kt new file mode 100644 index 0000000000..6e461846a9 --- /dev/null +++ b/core/src/com/unciv/ui/components/widgets/TextFieldWithFixes.kt @@ -0,0 +1,59 @@ +package com.unciv.ui.components.widgets + +import com.badlogic.gdx.graphics.g2d.Batch +import com.badlogic.gdx.graphics.g2d.BitmapFont +import com.badlogic.gdx.scenes.scene2d.ui.Skin +import com.badlogic.gdx.scenes.scene2d.ui.TextField +import com.unciv.ui.components.input.KeyCharAndCode +import com.unciv.ui.components.input.keyShortcuts + +/** + * Creates a text field with two deviations from the default Gdx [TextField]: + * - Turns off Gdx color markup support while drawing, so [] in the text display properly + * - If this TextField handles the Tab key (see [keyShortcuts]), its [focus navigation feature][TextField.next] is disabled (otherwise it would search for another TextField in the same parent to give focus to, and remove the on-screen keyboard if it finds none). + * - constructors same as standard TextField, plus a cloning constructor. + */ +open class TextFieldWithFixes private constructor(text: String, style: TextFieldStyle) : TextField(text, style) { + internal constructor(text: String, skin: Skin) : this(text, skin.get(TextFieldStyle::class.java)) + internal constructor(textField: TextFieldWithFixes) : this(textField.text, textField.style) { + textFieldFilter = textField.textFieldFilter + messageText = textField.messageText + hasSelection = textField.hasSelection + cursor = textField.cursor + selectionStart = textField.selectionStart + alignment = textField.alignment + isPasswordMode = textField.isPasswordMode + onscreenKeyboard = textField.onscreenKeyboard + } + + // Without this, the DeveloperConsole can't catch the Tab key for Autocomplete reliably + override fun next(up: Boolean) { + if (KeyCharAndCode.TAB in keyShortcuts) return + super.next(up) + } + + // Note - this way to force TextField to display `[]` characters normally is an incomplete hack. + // The complete way would either require overriding `updateDisplayText` which is private, or all methods calling it, + // which are many including the keyboard listener, or keep a separate font without markup enabled around and put that + // into the default style, including its own NativeBitmapFontData instance and texture - involves quite some redesign. + // That said, observing the deficiency is hard - the internal `glyphPositions` could theoretically get out of sync, affecting selection and caret display. + override fun layout() { + val oldEnable = style.font.data.markupEnabled + style.font.data.markupEnabled = false + super.layout() + style.font.data.markupEnabled = oldEnable + } + override fun drawText(batch: Batch, font: BitmapFont, x: Float, y: Float) { + val oldEnable = font.data.markupEnabled + font.data.markupEnabled = false + super.drawText(batch, font, x, y) + font.data.markupEnabled = oldEnable + } + + fun copyTextAndSelection(textField: TextFieldWithFixes) { + text = textField.text + hasSelection = textField.hasSelection + cursor = textField.cursor + selectionStart = textField.selectionStart + } +} diff --git a/core/src/com/unciv/ui/components/widgets/UncivTextField.kt b/core/src/com/unciv/ui/components/widgets/UncivTextField.kt new file mode 100644 index 0000000000..956d44aeb8 --- /dev/null +++ b/core/src/com/unciv/ui/components/widgets/UncivTextField.kt @@ -0,0 +1,192 @@ +package com.unciv.ui.components.widgets + +import com.badlogic.gdx.Application +import com.badlogic.gdx.Gdx +import com.badlogic.gdx.math.Vector2 +import com.badlogic.gdx.scenes.scene2d.Actor +import com.badlogic.gdx.scenes.scene2d.InputEvent +import com.badlogic.gdx.scenes.scene2d.InputListener +import com.badlogic.gdx.scenes.scene2d.ui.ScrollPane +import com.badlogic.gdx.scenes.scene2d.ui.TextField +import com.badlogic.gdx.scenes.scene2d.utils.FocusListener +import com.unciv.Constants +import com.unciv.logic.event.EventBus +import com.unciv.models.translations.tr +import com.unciv.ui.components.extensions.getAscendant +import com.unciv.ui.components.extensions.getOverlap +import com.unciv.ui.components.extensions.right +import com.unciv.ui.components.extensions.stageBoundingBox +import com.unciv.ui.components.extensions.top +import com.unciv.ui.components.input.keyShortcuts +import com.unciv.ui.popups.Popup +import com.unciv.ui.screens.basescreen.BaseScreen +import com.unciv.ui.screens.basescreen.UncivStage +import com.unciv.utils.Concurrency +import com.unciv.utils.withGLContext +import kotlinx.coroutines.delay + +/** + * Creates a text field that has nicer platform-specific input added compared to the default Gdx [TextField]. + * + * - On Android, manages on-screen keyboard visibility and reacts to how the on-screen keyboard reduces screen space. + * - Tries to scroll the field into view when receiving focus using an ascendant ScrollPane. + * - If view of the field is still obscured, show am "emergency" Popup instead (can help when on Android the on-screen keyboard is large and the screen small). + * - If this TextField handles the Tab key (see [keyShortcuts]), its [focus navigation feature][TextField.next] is disabled (otherwise it would search for another TextField in the same parent to give focus to, and remove the on-screen keyboard if it finds none). + * - All parameters are supported on all platforms. + * + * @param hint The text that should be displayed in the text field when no text is entered and it does not have focus, will automatically be translated. Also shown as Label in the "emergency" Popup. + * @param preEnteredText the text initially entered within this text field. + * @param onFocusChange a callback that will be notified when this TextField loses or gains the [keyboardFocus][com.badlogic.gdx.scenes.scene2d.Stage.keyboardFocus]. + * Receiver is the field, so you can simply use its elements. Parameter `it` is a Boolean indicating focus was received. + */ +class UncivTextField( + hint: String, + preEnteredText: String = "", + private val onFocusChange: (TextField.(Boolean) -> Unit)? = null +) : TextFieldWithFixes(preEnteredText, BaseScreen.skin) { + private val isAndroid = Gdx.app.type == Application.ApplicationType.Android + private val hideKeyboard = { Gdx.input.setOnscreenKeyboardVisible(false) } + + init { + messageText = hint.tr() + + addListener(UncivTextFieldFocusListener()) + + if (isAndroid) addListener(VisibleAreaChangedListener()) + } + + private inner class UncivTextFieldFocusListener : FocusListener() { + override fun keyboardFocusChanged(event: FocusEvent, actor: Actor, focused: Boolean) { + if (focused) { + scrollAscendantToTextField() + if (isAndroid) { + addPopupCloseListener() + Gdx.input.setOnscreenKeyboardVisible(true) + } + } + onFocusChange?.invoke(this@UncivTextField, focused) + } + } + + private inner class VisibleAreaChangedListener : InputListener() { + private val events = EventBus.EventReceiver() + init { + events.receive(UncivStage.VisibleAreaChanged::class) { + if (stage == null || !hasKeyboardFocus()) return@receive + Concurrency.run { + // If anything resizes, it also does so with this event. So we need to wait for that to finish to update the scroll position. + delay(100) + withGLContext { + if (stage == null) return@withGLContext + + if (scrollAscendantToTextField()) { + val scrollPane = getAscendant() + // when screen dimensions change, we don't want an animation for scrolling, just show the textfield immediately + scrollPane?.updateVisualScroll() + } else { + // We can't scroll the text field into view, so we need to show a popup + TextfieldPopup().open() + } + } + } + } + } + override fun touchDown(event: InputEvent, x: Float, y: Float, pointer: Int, button: Int): Boolean { + addPopupCloseListener() + return false + } + } + + private fun addPopupCloseListener() { + val popup = getAscendant() + if (popup != null && !popup.closeListeners.contains(hideKeyboard)) { + popup.closeListeners.add(hideKeyboard) + } + } + + /** + * Tries to scroll a [ScrollPane] ascendant of the text field so that this text field is in the middle of the visible area. + * + * @return true if the text field is visible after this operation + */ + private fun scrollAscendantToTextField(): Boolean { + val stage = this.stage as? UncivStage ?: return false + + val scrollPane = this.getAscendant() + val visibleArea = stage.lastKnownVisibleArea + val textFieldStageBoundingBox = this.stageBoundingBox + if (scrollPane == null) return visibleArea.contains(textFieldStageBoundingBox) + + val scrollPaneBounds = scrollPane.stageBoundingBox + val visibleScrollPaneArea = scrollPaneBounds.getOverlap(visibleArea) + if (visibleScrollPaneArea == null) { + return false + } else if (visibleScrollPaneArea.contains(textFieldStageBoundingBox)) { + return true + } + + val scrollContent = scrollPane.actor + val textFieldScrollContentCoords = localToAscendantCoordinates(scrollContent, Vector2(0f, 0f)) + + // It's possible that our textField can't be (fully) scrolled to be within the visible scrollPane area + val pixelsNotVisibleOnLeftSide = (visibleScrollPaneArea.x - scrollPaneBounds.x).coerceAtLeast(0f) + val textFieldDistanceFromLeftSide = textFieldScrollContentCoords.x + val pixelsNotVisibleOnRightSide = (scrollPaneBounds.right - visibleScrollPaneArea.right).coerceAtLeast(0f) + val textFieldDistanceFromRightSide = scrollContent.width - (textFieldScrollContentCoords.x + this.width) + val pixelsNotVisibleOnTop = (scrollPaneBounds.top - visibleScrollPaneArea.top).coerceAtLeast(0f) + val textFieldDistanceFromTop = scrollContent.height - (textFieldScrollContentCoords.y + this.height) + val pixelsNotVisibleOnBottom = (visibleScrollPaneArea.y - scrollPaneBounds.y).coerceAtLeast(0f) + val textFieldDistanceFromBottom = textFieldScrollContentCoords.y + // If the visible scroll pane area is smaller than our text field, it will always be partly obscured + if (visibleScrollPaneArea.width < this.width || visibleScrollPaneArea.height < this.height + // If the amount of pixels obscured near a scrollContent edge is larger than the distance of the text field to that edge, it will always be (partly) obscured + || pixelsNotVisibleOnLeftSide > textFieldDistanceFromLeftSide + || pixelsNotVisibleOnRightSide > textFieldDistanceFromRightSide + || pixelsNotVisibleOnTop > textFieldDistanceFromTop + || pixelsNotVisibleOnBottom > textFieldDistanceFromBottom) { + return false + } + + // We want to put the text field in the middle of the visible area + val scrollXMiddle = textFieldScrollContentCoords.x - this.width / 2 + visibleScrollPaneArea.width / 2 + // If the visible area is to the right of the left edge of the scroll pane, we need to scroll that much farther to get to the real visible middle + scrollPane.scrollX = pixelsNotVisibleOnLeftSide + scrollXMiddle + + // ScrollPane.scrollY has the origin at the top instead of at the bottom, so + for height / 2 instead of - + // We want to put the text field in the middle of the visible area + val scrollYMiddleGdxOrigin = textFieldScrollContentCoords.y + this.height / 2 + visibleScrollPaneArea.height / 2 + // If the visible area is below the top edge of the scroll pane, we need to scroll that much farther to get to the real visible middle + // Also, convert to scroll pane origin (0 is on top instead of bottom) + scrollPane.scrollY = pixelsNotVisibleOnTop + scrollContent.height - scrollYMiddleGdxOrigin + + return true + } + + private inner class TextfieldPopup : Popup(stage) { + val popupTextfield = TextFieldWithFixes(this@UncivTextField) + init { + addGoodSizedLabel(popupTextfield.messageText) + .colspan(2) + .row() + + add(popupTextfield) + .width(stageToShowOn.width / 2) + .colspan(2) + .row() + + addCloseButton(Constants.cancel) + .left() + addOKButton { this@UncivTextField.copyTextAndSelection(popupTextfield) } + .right() + .row() + + showListeners.add { + stageToShowOn.keyboardFocus = popupTextfield + } + closeListeners.add { + stageToShowOn.keyboardFocus = null + Gdx.input.setOnscreenKeyboardVisible(false) + } + } + } +} diff --git a/core/src/com/unciv/ui/popups/AskNumberPopup.kt b/core/src/com/unciv/ui/popups/AskNumberPopup.kt index b47913b7c3..31895d452d 100644 --- a/core/src/com/unciv/ui/popups/AskNumberPopup.kt +++ b/core/src/com/unciv/ui/popups/AskNumberPopup.kt @@ -4,7 +4,7 @@ import com.badlogic.gdx.graphics.Color import com.badlogic.gdx.scenes.scene2d.ui.Button import com.badlogic.gdx.scenes.scene2d.ui.Table import com.badlogic.gdx.scenes.scene2d.ui.TextField -import com.unciv.ui.components.UncivTextField +import com.unciv.ui.components.widgets.UncivTextField import com.unciv.ui.components.input.onChange import com.unciv.ui.components.input.onClick import com.unciv.ui.components.extensions.surroundWithCircle @@ -62,7 +62,7 @@ class AskNumberPopup( wrapper.add(label.toLabel()) add(wrapper).colspan(2).row() - val nameField = UncivTextField.create(label, defaultValue) + val nameField = UncivTextField(label, defaultValue) nameField.textFieldFilter = TextField.TextFieldFilter { _, char -> char.isDigit() || char == '-' } fun isValidInt(input: String): Boolean { diff --git a/core/src/com/unciv/ui/popups/AskTextPopup.kt b/core/src/com/unciv/ui/popups/AskTextPopup.kt index 023cfd499c..4a6ce30160 100644 --- a/core/src/com/unciv/ui/popups/AskTextPopup.kt +++ b/core/src/com/unciv/ui/popups/AskTextPopup.kt @@ -6,7 +6,7 @@ import com.badlogic.gdx.scenes.scene2d.ui.Table import com.badlogic.gdx.scenes.scene2d.ui.TextField import com.unciv.ui.images.ImageGetter import com.unciv.ui.screens.basescreen.BaseScreen -import com.unciv.ui.components.UncivTextField +import com.unciv.ui.components.widgets.UncivTextField import com.unciv.ui.components.extensions.surroundWithCircle import com.unciv.ui.components.extensions.toLabel @@ -40,7 +40,7 @@ class AskTextPopup( wrapper.add(label.toLabel()) add(wrapper).colspan(2).row() - val nameField = UncivTextField.create(label, defaultText) + val nameField = UncivTextField(label, defaultText) nameField.textFieldFilter = TextField.TextFieldFilter { _, char -> char !in illegalChars} nameField.maxLength = maxLength diff --git a/core/src/com/unciv/ui/popups/AuthPopup.kt b/core/src/com/unciv/ui/popups/AuthPopup.kt index abfca36af7..7b332917c9 100644 --- a/core/src/com/unciv/ui/popups/AuthPopup.kt +++ b/core/src/com/unciv/ui/popups/AuthPopup.kt @@ -3,7 +3,7 @@ package com.unciv.ui.popups import com.badlogic.gdx.scenes.scene2d.Stage import com.badlogic.gdx.scenes.scene2d.ui.TextButton import com.unciv.UncivGame -import com.unciv.ui.components.UncivTextField +import com.unciv.ui.components.widgets.UncivTextField import com.unciv.ui.components.input.onClick import com.unciv.ui.components.extensions.toTextButton import com.unciv.ui.screens.basescreen.BaseScreen @@ -14,7 +14,7 @@ class AuthPopup(stage: Stage, authSuccessful: ((Boolean) -> Unit)? = null) constructor(screen: BaseScreen, authSuccessful: ((Boolean) -> Unit)? = null) : this(screen.stage, authSuccessful) init { - val passwordField = UncivTextField.create("Password") + val passwordField = UncivTextField("Password") val button = "Authenticate".toTextButton() val negativeButtonStyle = BaseScreen.skin.get("negative", TextButton.TextButtonStyle::class.java) diff --git a/core/src/com/unciv/ui/popups/options/DebugTab.kt b/core/src/com/unciv/ui/popups/options/DebugTab.kt index 283a1f0ab0..f769038c03 100644 --- a/core/src/com/unciv/ui/popups/options/DebugTab.kt +++ b/core/src/com/unciv/ui/popups/options/DebugTab.kt @@ -10,7 +10,7 @@ import com.unciv.logic.files.MapSaver import com.unciv.logic.files.UncivFiles import com.unciv.models.ruleset.RulesetCache import com.unciv.models.ruleset.tile.ResourceType -import com.unciv.ui.components.UncivTextField +import com.unciv.ui.components.widgets.UncivTextField import com.unciv.ui.components.extensions.addSeparator import com.unciv.ui.components.extensions.toCheckBox import com.unciv.ui.components.extensions.toLabel @@ -31,7 +31,7 @@ fun debugTab( if (GUI.isWorldLoaded()) { val simulateButton = "Simulate until turn:".toTextButton() - val simulateTextField = UncivTextField.create("Turn", DebugUtils.SIMULATE_UNTIL_TURN.toString()) + val simulateTextField = UncivTextField("Turn", DebugUtils.SIMULATE_UNTIL_TURN.toString()) val invalidInputLabel = "This is not a valid integer!".toLabel().also { it.isVisible = false } simulateButton.onClick { val simulateUntilTurns = simulateTextField.text.toIntOrNull() diff --git a/core/src/com/unciv/ui/popups/options/MultiplayerTab.kt b/core/src/com/unciv/ui/popups/options/MultiplayerTab.kt index 14fc4c6521..e4776a83e6 100644 --- a/core/src/com/unciv/ui/popups/options/MultiplayerTab.kt +++ b/core/src/com/unciv/ui/popups/options/MultiplayerTab.kt @@ -9,11 +9,9 @@ import com.unciv.logic.files.IMediaFinder import com.unciv.logic.multiplayer.OnlineMultiplayer import com.unciv.logic.multiplayer.storage.FileStorageRateLimitReached import com.unciv.logic.multiplayer.storage.MultiplayerAuthException -import com.unciv.models.UncivSound import com.unciv.models.metadata.GameSettings import com.unciv.models.metadata.GameSettings.GameSetting -import com.unciv.models.ruleset.RulesetCache -import com.unciv.ui.components.UncivTextField +import com.unciv.ui.components.widgets.UncivTextField import com.unciv.ui.components.extensions.addSeparator import com.unciv.ui.components.extensions.brighten import com.unciv.ui.components.extensions.format @@ -113,7 +111,7 @@ private fun addMultiplayerServerOptions( } else { "https://" } - val multiplayerServerTextField = UncivTextField.create("Server address", textToShowForMultiplayerAddress) + val multiplayerServerTextField = UncivTextField("Server address", textToShowForMultiplayerAddress) multiplayerServerTextField.setTextFieldFilter { _, c -> c !in " \r\n\t\\" } multiplayerServerTextField.programmaticChangeEvents = true val serverIpTable = Table() @@ -160,7 +158,7 @@ private fun addMultiplayerServerOptions( }).row() if (UncivGame.Current.onlineMultiplayer.multiplayerServer.featureSet.authVersion > 0) { - val passwordTextField = UncivTextField.create( + val passwordTextField = UncivTextField( settings.multiplayer.passwords[settings.multiplayer.server] ?: "Password" ) val setPasswordButton = "Set password".toTextButton() diff --git a/core/src/com/unciv/ui/screens/civilopediascreen/CivilopediaSearchPopup.kt b/core/src/com/unciv/ui/screens/civilopediascreen/CivilopediaSearchPopup.kt index 671c9a4a00..4c07bdbf07 100644 --- a/core/src/com/unciv/ui/screens/civilopediascreen/CivilopediaSearchPopup.kt +++ b/core/src/com/unciv/ui/screens/civilopediascreen/CivilopediaSearchPopup.kt @@ -10,7 +10,7 @@ import com.unciv.models.ruleset.Ruleset import com.unciv.models.ruleset.RulesetCache import com.unciv.models.stats.INamed import com.unciv.models.translations.tr -import com.unciv.ui.components.UncivTextField +import com.unciv.ui.components.widgets.UncivTextField import com.unciv.ui.components.extensions.disable import com.unciv.ui.components.extensions.enable import com.unciv.ui.components.extensions.toLabel @@ -34,7 +34,7 @@ class CivilopediaSearchPopup( private val linkAction: (String) -> Unit ) : Popup(pediaScreen) { private var ruleset = pediaScreen.ruleset - private val searchText = UncivTextField.create("") // Always focused, "hint" never seen + private val searchText = UncivTextField("") // Always focused, "hint" never seen private val modSelect = ModSelectBox() private lateinit var resultExpander: ExpanderTab private val resultCell: Cell diff --git a/core/src/com/unciv/ui/screens/devconsole/DevConsolePopup.kt b/core/src/com/unciv/ui/screens/devconsole/DevConsolePopup.kt index 5a09cd0b9b..1c8d59fde3 100644 --- a/core/src/com/unciv/ui/screens/devconsole/DevConsolePopup.kt +++ b/core/src/com/unciv/ui/screens/devconsole/DevConsolePopup.kt @@ -11,7 +11,7 @@ import com.unciv.Constants import com.unciv.GUI import com.unciv.logic.civilization.Civilization import com.unciv.logic.map.mapunit.MapUnit -import com.unciv.ui.components.UncivTextField +import com.unciv.ui.components.widgets.UncivTextField import com.unciv.ui.components.extensions.surroundWithCircle import com.unciv.ui.components.extensions.toCheckBox import com.unciv.ui.components.extensions.toLabel @@ -34,7 +34,7 @@ class DevConsolePopup(val screen: WorldScreen) : Popup(screen) { private var currentHistoryEntry = history.size - private val textField = UncivTextField.create("", "") // always has focus, so a hint won't show + private val textField = UncivTextField("") // always has focus, so a hint won't show private val responseLabel = "".toLabel(Color.RED).apply { wrap = true } private val inputWrapper = Table() diff --git a/core/src/com/unciv/ui/screens/mapeditorscreen/MapEditorScreen.kt b/core/src/com/unciv/ui/screens/mapeditorscreen/MapEditorScreen.kt index bcb71b3a6a..33877d573b 100644 --- a/core/src/com/unciv/ui/screens/mapeditorscreen/MapEditorScreen.kt +++ b/core/src/com/unciv/ui/screens/mapeditorscreen/MapEditorScreen.kt @@ -21,7 +21,7 @@ import com.unciv.models.metadata.GameParameters import com.unciv.models.metadata.GameSetupInfo import com.unciv.models.ruleset.Ruleset import com.unciv.models.ruleset.RulesetCache -import com.unciv.ui.components.UncivTextField +import com.unciv.ui.components.widgets.UncivTextField import com.unciv.ui.components.input.KeyCharAndCode import com.unciv.ui.components.input.KeyShortcutDispatcherVeto import com.unciv.ui.components.input.KeyboardPanningListener @@ -85,7 +85,7 @@ class MapEditorScreen(map: TileMap? = null) : BaseScreen(), RecreateOnResize { val tabs: MapEditorMainTabs var tileClickHandler: ((tile: Tile)->Unit)? = null private var zoomController: ZoomButtonPair? = null - val descriptionTextField = UncivTextField.create("Enter a description for the users of this map") + val descriptionTextField = UncivTextField("Enter a description for the users of this map") private val highlightedTileGroups = mutableListOf() diff --git a/core/src/com/unciv/ui/screens/mapeditorscreen/tabs/MapEditorSaveTab.kt b/core/src/com/unciv/ui/screens/mapeditorscreen/tabs/MapEditorSaveTab.kt index ce03cf3730..14b65ad865 100644 --- a/core/src/com/unciv/ui/screens/mapeditorscreen/tabs/MapEditorSaveTab.kt +++ b/core/src/com/unciv/ui/screens/mapeditorscreen/tabs/MapEditorSaveTab.kt @@ -9,7 +9,7 @@ import com.unciv.logic.files.MapSaver import com.unciv.logic.map.MapGeneratedMainType import com.unciv.logic.map.TileMap import com.unciv.models.translations.tr -import com.unciv.ui.components.UncivTextField +import com.unciv.ui.components.widgets.UncivTextField import com.unciv.ui.components.extensions.isEnabled import com.unciv.ui.components.extensions.toTextButton import com.unciv.ui.components.input.KeyCharAndCode @@ -45,7 +45,7 @@ class MapEditorSaveTab( private val deleteButton = "Delete map".toTextButton() private val quitButton = "Exit map editor".toTextButton() - private val mapNameTextField = UncivTextField.create("Map Name") + private val mapNameTextField = UncivTextField("Map Name") private var chosenMap: FileHandle? = null diff --git a/core/src/com/unciv/ui/screens/modmanager/ModManagementOptions.kt b/core/src/com/unciv/ui/screens/modmanager/ModManagementOptions.kt index dd652896bf..2753e22def 100644 --- a/core/src/com/unciv/ui/screens/modmanager/ModManagementOptions.kt +++ b/core/src/com/unciv/ui/screens/modmanager/ModManagementOptions.kt @@ -7,7 +7,7 @@ import com.unciv.Constants import com.unciv.models.metadata.ModCategories import com.unciv.models.translations.tr import com.unciv.ui.components.widgets.ExpanderTab -import com.unciv.ui.components.UncivTextField +import com.unciv.ui.components.widgets.UncivTextField import com.unciv.ui.components.UncivTooltip.Companion.addTooltip import com.unciv.ui.components.extensions.surroundWithCircle import com.unciv.ui.components.extensions.toLabel @@ -78,7 +78,7 @@ internal class ModManagementOptions(private val modManagementScreen: ModManageme return Filter(textField.text, category.topic) } - private val textField = UncivTextField.create("Enter search text") + private val textField = UncivTextField("Enter search text") var category = ModCategories.default() diff --git a/core/src/com/unciv/ui/screens/modmanager/ModManagementScreen.kt b/core/src/com/unciv/ui/screens/modmanager/ModManagementScreen.kt index ca1f2041e1..9a31b79f6b 100644 --- a/core/src/com/unciv/ui/screens/modmanager/ModManagementScreen.kt +++ b/core/src/com/unciv/ui/screens/modmanager/ModManagementScreen.kt @@ -12,8 +12,6 @@ import com.badlogic.gdx.scenes.scene2d.ui.TextButton import com.badlogic.gdx.utils.Align import com.badlogic.gdx.utils.SerializationException import com.unciv.UncivGame -import com.unciv.json.fromJsonFile -import com.unciv.json.json import com.unciv.logic.UncivShowableException import com.unciv.logic.github.Github import com.unciv.logic.github.Github.repoNameToFolderName @@ -22,7 +20,7 @@ import com.unciv.models.ruleset.Ruleset import com.unciv.models.ruleset.RulesetCache import com.unciv.models.tilesets.TileSetCache import com.unciv.models.translations.tr -import com.unciv.ui.components.UncivTextField +import com.unciv.ui.components.widgets.UncivTextField import com.unciv.ui.components.extensions.addSeparator import com.unciv.ui.components.extensions.disable import com.unciv.ui.components.extensions.enable @@ -409,7 +407,7 @@ class ModManagementScreen private constructor( downloadButton.onClick { val popup = Popup(this) popup.addGoodSizedLabel("Please enter the mod repository -or- archive zip -or- branch -or- release url:").row() - val textField = UncivTextField.create("").apply { maxLength = 666 } + val textField = UncivTextField("").apply { maxLength = 666 } popup.add(textField).width(stage.width / 2).row() val pasteLinkButton = "Paste from clipboard".toTextButton() pasteLinkButton.onClick { diff --git a/core/src/com/unciv/ui/screens/multiplayerscreens/AddFriendScreen.kt b/core/src/com/unciv/ui/screens/multiplayerscreens/AddFriendScreen.kt index 6fd1f0bac8..59d8c6b46d 100644 --- a/core/src/com/unciv/ui/screens/multiplayerscreens/AddFriendScreen.kt +++ b/core/src/com/unciv/ui/screens/multiplayerscreens/AddFriendScreen.kt @@ -8,7 +8,7 @@ import com.unciv.logic.multiplayer.FriendList import com.unciv.models.translations.tr import com.unciv.ui.screens.pickerscreens.PickerScreen import com.unciv.ui.popups.ToastPopup -import com.unciv.ui.components.UncivTextField +import com.unciv.ui.components.widgets.UncivTextField import com.unciv.ui.components.extensions.enable import com.unciv.ui.components.input.onClick import com.unciv.ui.components.extensions.toLabel @@ -17,9 +17,9 @@ import java.util.UUID class AddFriendScreen : PickerScreen() { init { - val friendNameTextField = UncivTextField.create("Please input a name for your friend!") + val friendNameTextField = UncivTextField("Please input a name for your friend!") val pastePlayerIDButton = "Paste player ID from clipboard".toTextButton() - val playerIDTextField = UncivTextField.create("Please input a player ID for your friend!") + val playerIDTextField = UncivTextField("Please input a player ID for your friend!") val friendlist = FriendList() topTable.add("Friend name".toLabel()).row() diff --git a/core/src/com/unciv/ui/screens/multiplayerscreens/AddMultiplayerGameScreen.kt b/core/src/com/unciv/ui/screens/multiplayerscreens/AddMultiplayerGameScreen.kt index caea5befd0..fcf461c40e 100644 --- a/core/src/com/unciv/ui/screens/multiplayerscreens/AddMultiplayerGameScreen.kt +++ b/core/src/com/unciv/ui/screens/multiplayerscreens/AddMultiplayerGameScreen.kt @@ -5,7 +5,7 @@ import com.badlogic.gdx.scenes.scene2d.ui.Table import com.unciv.Constants import com.unciv.logic.IdChecker import com.unciv.models.translations.tr -import com.unciv.ui.components.UncivTextField +import com.unciv.ui.components.widgets.UncivTextField import com.unciv.ui.components.extensions.enable import com.unciv.ui.components.extensions.toLabel import com.unciv.ui.components.extensions.toTextButton @@ -23,8 +23,8 @@ import java.util.UUID class AddMultiplayerGameScreen(multiplayerScreen: MultiplayerScreen) : PickerScreen() { init { - val gameNameTextField = UncivTextField.create("Game name") - val gameIDTextField = UncivTextField.create("GameID") + val gameNameTextField = UncivTextField("Game name") + val gameIDTextField = UncivTextField("GameID") val pasteGameIDButton = "Paste gameID from clipboard".toTextButton() pasteGameIDButton.onClick { gameIDTextField.text = Gdx.app.clipboard.contents diff --git a/core/src/com/unciv/ui/screens/multiplayerscreens/EditFriendScreen.kt b/core/src/com/unciv/ui/screens/multiplayerscreens/EditFriendScreen.kt index 43603d104f..2710ac7f05 100644 --- a/core/src/com/unciv/ui/screens/multiplayerscreens/EditFriendScreen.kt +++ b/core/src/com/unciv/ui/screens/multiplayerscreens/EditFriendScreen.kt @@ -10,7 +10,7 @@ import com.unciv.models.translations.tr import com.unciv.ui.screens.pickerscreens.PickerScreen import com.unciv.ui.popups.ConfirmPopup import com.unciv.ui.popups.ToastPopup -import com.unciv.ui.components.UncivTextField +import com.unciv.ui.components.widgets.UncivTextField import com.unciv.ui.components.extensions.enable import com.unciv.ui.components.input.onClick import com.unciv.ui.components.extensions.toLabel @@ -19,9 +19,9 @@ import java.util.UUID class EditFriendScreen(selectedFriend: FriendList.Friend) : PickerScreen() { init { - val friendNameTextField = UncivTextField.create("Please input a name for your friend!", selectedFriend.name) + val friendNameTextField = UncivTextField("Please input a name for your friend!", selectedFriend.name) val pastePlayerIDButton = "Player ID from clipboard".toTextButton() - val playerIDTextField = UncivTextField.create("Please input a player ID for your friend!", selectedFriend.playerID) + val playerIDTextField = UncivTextField("Please input a player ID for your friend!", selectedFriend.playerID) val deleteFriendButton = "Delete".toTextButton() val friendlist = FriendList() diff --git a/core/src/com/unciv/ui/screens/multiplayerscreens/MultiplayerScreen.kt b/core/src/com/unciv/ui/screens/multiplayerscreens/MultiplayerScreen.kt index f1c9785185..f90b6f66bc 100644 --- a/core/src/com/unciv/ui/screens/multiplayerscreens/MultiplayerScreen.kt +++ b/core/src/com/unciv/ui/screens/multiplayerscreens/MultiplayerScreen.kt @@ -7,7 +7,7 @@ import com.unciv.Constants import com.unciv.logic.multiplayer.OnlineMultiplayerGame import com.unciv.logic.multiplayer.storage.MultiplayerAuthException import com.unciv.models.translations.tr -import com.unciv.ui.components.UncivTextField +import com.unciv.ui.components.widgets.UncivTextField import com.unciv.ui.components.extensions.disable import com.unciv.ui.components.extensions.enable import com.unciv.ui.components.extensions.toTextButton @@ -190,7 +190,7 @@ class MultiplayerScreen : PickerScreen() { val btn = "Rename".toTextButton().apply { disable() } btn.onClick { Popup(this).apply { - val textField = UncivTextField.create("Game name", selectedGame!!.name) + val textField = UncivTextField("Game name", selectedGame!!.name) add(textField).width(stageToShowOn.width / 2).row() val saveButton = "Save".toTextButton() diff --git a/core/src/com/unciv/ui/screens/newgamescreen/MapParametersTable.kt b/core/src/com/unciv/ui/screens/newgamescreen/MapParametersTable.kt index 9b45bc1699..50d195d927 100644 --- a/core/src/com/unciv/ui/screens/newgamescreen/MapParametersTable.kt +++ b/core/src/com/unciv/ui/screens/newgamescreen/MapParametersTable.kt @@ -13,7 +13,7 @@ import com.unciv.logic.map.mapgenerator.MapResourceSetting import com.unciv.logic.map.MapShape import com.unciv.logic.map.MapSize import com.unciv.logic.map.MapType -import com.unciv.ui.components.UncivTextField +import com.unciv.ui.components.widgets.UncivTextField import com.unciv.ui.components.extensions.pad import com.unciv.ui.components.extensions.toCheckBox import com.unciv.ui.components.extensions.toLabel @@ -205,7 +205,7 @@ class MapParametersTable( private fun addHexagonalSizeTable() { val defaultRadius = mapParameters.mapSize.radius.toString() - customMapSizeRadius = UncivTextField.create("Radius", defaultRadius).apply { + customMapSizeRadius = UncivTextField("Radius", defaultRadius).apply { textFieldFilter = DigitsOnlyFilter() } customMapSizeRadius.onChange { @@ -219,12 +219,12 @@ class MapParametersTable( private fun addRectangularSizeTable() { val defaultWidth = mapParameters.mapSize.width.toString() - customMapWidth = UncivTextField.create("Width", defaultWidth).apply { + customMapWidth = UncivTextField("Width", defaultWidth).apply { textFieldFilter = DigitsOnlyFilter() } val defaultHeight = mapParameters.mapSize.height.toString() - customMapHeight = UncivTextField.create("Height", defaultHeight).apply { + customMapHeight = UncivTextField("Height", defaultHeight).apply { textFieldFilter = DigitsOnlyFilter() } @@ -360,7 +360,7 @@ class MapParametersTable( private fun addAdvancedControls(table: Table) { table.defaults().pad(5f) - seedTextField = UncivTextField.create("RNG Seed", mapParameters.seed.toString()) + seedTextField = UncivTextField("RNG Seed", mapParameters.seed.toString()) seedTextField.textFieldFilter = DigitsOnlyFilter() // If the field is empty, fallback seed value to 0 diff --git a/core/src/com/unciv/ui/screens/newgamescreen/PlayerPickerTable.kt b/core/src/com/unciv/ui/screens/newgamescreen/PlayerPickerTable.kt index d63beab3fb..3be859590a 100644 --- a/core/src/com/unciv/ui/screens/newgamescreen/PlayerPickerTable.kt +++ b/core/src/com/unciv/ui/screens/newgamescreen/PlayerPickerTable.kt @@ -17,7 +17,7 @@ import com.unciv.models.ruleset.Ruleset import com.unciv.models.ruleset.nation.Nation import com.unciv.models.translations.tr import com.unciv.ui.components.input.KeyCharAndCode -import com.unciv.ui.components.UncivTextField +import com.unciv.ui.components.widgets.UncivTextField import com.unciv.ui.components.widgets.WrappableLabel import com.unciv.ui.components.extensions.darken import com.unciv.ui.components.extensions.isEnabled @@ -229,7 +229,7 @@ class PlayerPickerTable( private fun Table.addPlayerTableMultiplayerControls(player: Player) { row() - val playerIdTextField = UncivTextField.create("Please input Player ID!", player.playerId) + val playerIdTextField = UncivTextField("Please input Player ID!", player.playerId) add(playerIdTextField).colspan(2).fillX().pad(5f) val errorLabel = "✘".toLabel(Color.RED) add(errorLabel).pad(5f).row() diff --git a/core/src/com/unciv/ui/screens/savescreens/SaveGameScreen.kt b/core/src/com/unciv/ui/screens/savescreens/SaveGameScreen.kt index 4e18824a4d..7275690b05 100644 --- a/core/src/com/unciv/ui/screens/savescreens/SaveGameScreen.kt +++ b/core/src/com/unciv/ui/screens/savescreens/SaveGameScreen.kt @@ -9,7 +9,7 @@ import com.unciv.logic.GameInfo import com.unciv.logic.files.PlatformSaverLoader import com.unciv.logic.files.UncivFiles import com.unciv.models.translations.tr -import com.unciv.ui.components.UncivTextField +import com.unciv.ui.components.widgets.UncivTextField import com.unciv.ui.components.UncivTooltip.Companion.addTooltip import com.unciv.ui.components.extensions.disable import com.unciv.ui.components.extensions.enable @@ -32,7 +32,7 @@ class SaveGameScreen(val gameInfo: GameInfo) : LoadOrSaveScreen("Current saves") const val saveToCustomText = "Save to custom location" } - private val gameNameTextField = UncivTextField.create(nameFieldLabelText) + private val gameNameTextField = UncivTextField(nameFieldLabelText) init { setDefaultCloseAction()