diff --git a/core/src/com/unciv/models/metadata/GameSettings.kt b/core/src/com/unciv/models/metadata/GameSettings.kt index f825a1e207..b1d43bf808 100644 --- a/core/src/com/unciv/models/metadata/GameSettings.kt +++ b/core/src/com/unciv/models/metadata/GameSettings.kt @@ -1,6 +1,6 @@ package com.unciv.models.metadata -import com.badlogic.gdx.Application +import com.badlogic.gdx.Application.ApplicationType import com.badlogic.gdx.Gdx import com.badlogic.gdx.utils.Base64Coder import com.unciv.Constants @@ -11,6 +11,7 @@ import com.unciv.ui.components.FontFamilyData import com.unciv.ui.components.Fonts import com.unciv.ui.components.KeyboardBindings import com.unciv.ui.screens.overviewscreen.EmpireOverviewCategories +import com.unciv.utils.Display import com.unciv.utils.ScreenOrientation import java.text.Collator import java.time.Duration @@ -110,17 +111,20 @@ class GameSettings { init { // 26 = Android Oreo. Versions below may display permanent icon in notification bar. - if (Gdx.app?.type == Application.ApplicationType.Android && Gdx.app.version < 26) { + if (Gdx.app?.type == ApplicationType.Android && Gdx.app.version < 26) { multiplayer.turnCheckerPersistentNotificationEnabled = false } } fun save() { - if (!isFreshlyCreated && Gdx.app?.type == Application.ApplicationType.Desktop) { - windowState = WindowState(Gdx.graphics.width, Gdx.graphics.height) - } + refreshWindowSize() UncivGame.Current.files.setGeneralSettings(this) } + fun refreshWindowSize() { + if (isFreshlyCreated || Gdx.app.type != ApplicationType.Desktop) return + if (!Display.hasUserSelectableSize(screenMode)) return + windowState = WindowState(Gdx.graphics.width, Gdx.graphics.height) + } fun addCompletedTutorialTask(tutorialTask: String): Boolean { if (!tutorialTasksCompleted.add(tutorialTask)) return false diff --git a/core/src/com/unciv/ui/popups/options/DisplayTab.kt b/core/src/com/unciv/ui/popups/options/DisplayTab.kt index 89773688ba..c1fbffb4cb 100644 --- a/core/src/com/unciv/ui/popups/options/DisplayTab.kt +++ b/core/src/com/unciv/ui/popups/options/DisplayTab.kt @@ -149,6 +149,7 @@ private fun addScreenModeSelectBox(table: Table, settings: GameSettings, selectB selectBox.items = Array(modes.values.toTypedArray()) selectBox.selected = current selectBox.onChange { + settings.refreshWindowSize() val mode = selectBox.selected settings.screenMode = mode.getId() Display.setScreenMode(mode.getId(), settings) diff --git a/core/src/com/unciv/utils/Display.kt b/core/src/com/unciv/utils/Display.kt index bc0ce46890..5e0daa4074 100644 --- a/core/src/com/unciv/utils/Display.kt +++ b/core/src/com/unciv/utils/Display.kt @@ -15,6 +15,7 @@ enum class ScreenOrientation(val description: String) { interface ScreenMode { fun getId(): Int + fun hasUserSelectableSize(): Boolean = false } interface PlatformDisplay { @@ -27,6 +28,8 @@ interface PlatformDisplay { fun hasOrientation(): Boolean { return false } fun setOrientation(orientation: ScreenOrientation) {} + + fun hasUserSelectableSize(id: Int): Boolean = false } object Display { @@ -42,4 +45,5 @@ object Display { fun getScreenModes(): Map { return platform.getScreenModes() } fun setScreenMode(id: Int, settings: GameSettings) { platform.setScreenMode(id, settings) } + fun hasUserSelectableSize(id: Int) = platform.hasUserSelectableSize(id) } diff --git a/desktop/src/com/unciv/app/desktop/DesktopDisplay.kt b/desktop/src/com/unciv/app/desktop/DesktopDisplay.kt index 06cd2720a5..451a33f5b4 100644 --- a/desktop/src/com/unciv/app/desktop/DesktopDisplay.kt +++ b/desktop/src/com/unciv/app/desktop/DesktopDisplay.kt @@ -1,75 +1,70 @@ package com.unciv.app.desktop import com.badlogic.gdx.Gdx +import com.badlogic.gdx.backends.lwjgl3.Lwjgl3Application +import com.badlogic.gdx.backends.lwjgl3.Lwjgl3ApplicationConfiguration import com.unciv.models.metadata.GameSettings import com.unciv.models.translations.tr import com.unciv.utils.PlatformDisplay import com.unciv.utils.ScreenMode -enum class ScreenWindowType { - Windowed, - Borderless, - Fullscreen -} -// TODO convert to Enum -class DesktopScreenMode( - private val modeId: Int, - val windowType: ScreenWindowType) : ScreenMode { +enum class DesktopScreenMode : ScreenMode { + // Order will be preserved in Options Popup + Windowed { + override fun activate(settings: GameSettings) { + Gdx.graphics.setUndecorated(false) + setWindowedMode(settings) + } - override fun getId(): Int { - return modeId + override fun hasUserSelectableSize() = true + }, + Fullscreen { + override fun activate(settings: GameSettings) { + Gdx.graphics.setFullscreenMode(Gdx.graphics.displayMode) + } + override fun hasUserSelectableSize() = false + }, + Borderless { + override fun activate(settings: GameSettings) { + Gdx.graphics.setUndecorated(true) + setWindowedMode(settings) + } + override fun hasUserSelectableSize() = true + }, + ; + + override fun getId() = ordinal + + override fun toString() = name.tr() + + abstract fun activate(settings: GameSettings) + + protected fun setWindowedMode(settings: GameSettings) { + val width = settings.windowState.width.coerceAtLeast(120) + val height = settings.windowState.height.coerceAtLeast(80) + // Kludge - see also DesktopLauncher - without, moving the window might revert to the size stored in config + (Lwjgl3Application::class.java).getDeclaredField("config").run { + isAccessible = true + get(Gdx.app) as Lwjgl3ApplicationConfiguration + }.setWindowedMode(width, height) + Gdx.graphics.setWindowedMode(width, height) } - override fun toString(): String { - return when (windowType) { - ScreenWindowType.Windowed -> "Windowed".tr() - ScreenWindowType.Borderless -> "Borderless".tr() - ScreenWindowType.Fullscreen -> "Fullscreen".tr() - } + companion object { + operator fun get(id: Int) = values()[id] } } class DesktopDisplay : PlatformDisplay { - private val modes = HashMap() - - init { - modes[0] = DesktopScreenMode(0, ScreenWindowType.Windowed) - modes[1] = DesktopScreenMode(1, ScreenWindowType.Fullscreen) - modes[2] = DesktopScreenMode(2, ScreenWindowType.Borderless) - } - - override fun getScreenModes(): Map { - return modes - } + override fun getScreenModes() = + DesktopScreenMode.values().associateBy { it.getId() } override fun setScreenMode(id: Int, settings: GameSettings) { - - val mode = modes[id] ?: return - - when (mode.windowType) { - - ScreenWindowType.Fullscreen -> { - Gdx.graphics.setFullscreenMode(Gdx.graphics.displayMode) - } - - ScreenWindowType.Windowed -> { - Gdx.graphics.setUndecorated(false) - Gdx.graphics.setWindowedMode( - settings.windowState.width.coerceAtLeast(120), - settings.windowState.height.coerceAtLeast(80) - ) - } - - ScreenWindowType.Borderless -> { - Gdx.graphics.setUndecorated(true) - Gdx.graphics.setWindowedMode( - settings.windowState.width.coerceAtLeast(120), - settings.windowState.height.coerceAtLeast(80) - ) - } - - } + DesktopScreenMode[id].activate(settings) } + + override fun hasUserSelectableSize(id: Int) = + DesktopScreenMode[id].hasUserSelectableSize() } diff --git a/desktop/src/com/unciv/app/desktop/DesktopLauncher.kt b/desktop/src/com/unciv/app/desktop/DesktopLauncher.kt index f2f2cb46f6..dbd8a9c5a4 100644 --- a/desktop/src/com/unciv/app/desktop/DesktopLauncher.kt +++ b/desktop/src/com/unciv/app/desktop/DesktopLauncher.kt @@ -47,7 +47,6 @@ internal object DesktopLauncher { config.setWindowIcon("ExtraImages/Icon.png") config.setTitle("Unciv") config.setHdpiMode(HdpiMode.Logical) - config.setMaximized(true) config.setWindowSizeLimits(120, 80, -1, -1) // We don't need the initial Audio created in Lwjgl3Application, HardenGdxAudio will replace it anyway. @@ -66,6 +65,10 @@ internal object DesktopLauncher { ) FileHandle(SETTINGS_FILE_NAME).writeString(json().toJson(settings), false) // so when we later open the game we get fullscreen } + // Kludge! This is a workaround - the matching call in DesktopDisplay doesn't "take" quite permanently, + // the window might revert to the "config" values when the user moves the window - worse if they + // minimize/restore. And the config default is 640x480 unless we set something here. + config.setWindowedMode(settings.windowState.width, settings.windowState.height) if (!isRunFromJAR) { UniqueDocsWriter().write()