From 8a327fa7be5a400736d6a9e8f7c0354303052b09 Mon Sep 17 00:00:00 2001 From: JackRainy Date: Sun, 12 Jan 2020 23:05:49 +0200 Subject: [PATCH] Fix for the "Back button can't end Unciv (#1513)" (#1661) * Callback to exit the game by 'Back' button * Prompt dialog for the game exit * Additional strings for translations are generated * Do not show exit prompt dialog twice --- .../translationsByLanguage/Czech.properties | 2 ++ .../translationsByLanguage/Dutch.properties | 2 ++ .../translationsByLanguage/English.properties | 2 ++ .../translationsByLanguage/French.properties | 2 ++ .../translationsByLanguage/German.properties | 2 ++ .../Indonesian.properties | 2 ++ .../translationsByLanguage/Italian.properties | 2 ++ .../translationsByLanguage/Korean.properties | 2 ++ .../translationsByLanguage/Malay.properties | 2 ++ .../translationsByLanguage/Polish.properties | 2 ++ .../Portuguese.properties | 2 ++ .../Romanian.properties | 2 ++ .../translationsByLanguage/Russian.properties | 1 + .../Simplified_Chinese.properties | 2 ++ .../translationsByLanguage/Spanish.properties | 2 ++ .../Traditional_Chinese.properties | 2 ++ .../Ukrainian.properties | 1 + .../template.properties | 1 + android/src/com/unciv/app/AndroidLauncher.kt | 4 ++- core/src/com/unciv/UncivGame.kt | 7 +++-- .../unciv/ui/utils/CameraStageBaseScreen.kt | 9 ++++--- .../com/unciv/ui/worldscreen/WorldScreen.kt | 26 +++++++++++++++++++ .../com/unciv/app/desktop/DesktopLauncher.kt | 4 +-- ios/src/com/unciv/app/IOSLauncher.java | 2 +- tests/src/com/unciv/testing/BasicTests.kt | 2 +- 25 files changed, 77 insertions(+), 10 deletions(-) diff --git a/android/assets/jsons/translationsByLanguage/Czech.properties b/android/assets/jsons/translationsByLanguage/Czech.properties index 5e36e22a42d4..5f02bf520566 100644 --- a/android/assets/jsons/translationsByLanguage/Czech.properties +++ b/android/assets/jsons/translationsByLanguage/Czech.properties @@ -790,6 +790,8 @@ Victory status = Cesta k vítězství Social policies = Sociální politika Community = Komunita Close = Zavřít + # Requires translation! +Do you want to exit the game? = # City screen diff --git a/android/assets/jsons/translationsByLanguage/Dutch.properties b/android/assets/jsons/translationsByLanguage/Dutch.properties index d859bb21609e..703577f88e6c 100644 --- a/android/assets/jsons/translationsByLanguage/Dutch.properties +++ b/android/assets/jsons/translationsByLanguage/Dutch.properties @@ -1222,6 +1222,8 @@ Social policies = Sociaal beleid # Requires translation! Community = Close = Sluiten + # Requires translation! +Do you want to exit the game? = # City screen diff --git a/android/assets/jsons/translationsByLanguage/English.properties b/android/assets/jsons/translationsByLanguage/English.properties index 47d5ed412ee2..ff8c48e44b11 100644 --- a/android/assets/jsons/translationsByLanguage/English.properties +++ b/android/assets/jsons/translationsByLanguage/English.properties @@ -1385,6 +1385,8 @@ Social policies = Community = # Requires translation! Close = + # Requires translation! +Do you want to exit the game? = # City screen diff --git a/android/assets/jsons/translationsByLanguage/French.properties b/android/assets/jsons/translationsByLanguage/French.properties index 7f60158a31b7..147023c271f3 100644 --- a/android/assets/jsons/translationsByLanguage/French.properties +++ b/android/assets/jsons/translationsByLanguage/French.properties @@ -775,6 +775,8 @@ Victory status = Conditions de victoire Social policies = Doctrines Community = Communauté Close = Fermer + # Requires translation! +Do you want to exit the game? = # City screen diff --git a/android/assets/jsons/translationsByLanguage/German.properties b/android/assets/jsons/translationsByLanguage/German.properties index 6eb3d6a40f02..c0f6ee11d605 100644 --- a/android/assets/jsons/translationsByLanguage/German.properties +++ b/android/assets/jsons/translationsByLanguage/German.properties @@ -793,6 +793,8 @@ Victory status = Siegesstatus Social policies = Sozialpolitiken Community = Gemeinschaft Close = Schließen + # Requires translation! +Do you want to exit the game? = # City screen diff --git a/android/assets/jsons/translationsByLanguage/Indonesian.properties b/android/assets/jsons/translationsByLanguage/Indonesian.properties index c33ebe42db05..4e8bbea2853b 100644 --- a/android/assets/jsons/translationsByLanguage/Indonesian.properties +++ b/android/assets/jsons/translationsByLanguage/Indonesian.properties @@ -791,6 +791,8 @@ Victory status = Status kemenangan Social policies = Kebijakan sosial Community = Komunitas Close = Tutup + # Requires translation! +Do you want to exit the game? = # City screen diff --git a/android/assets/jsons/translationsByLanguage/Italian.properties b/android/assets/jsons/translationsByLanguage/Italian.properties index 567badbd0ccc..4b6b8e736e08 100644 --- a/android/assets/jsons/translationsByLanguage/Italian.properties +++ b/android/assets/jsons/translationsByLanguage/Italian.properties @@ -762,6 +762,8 @@ Victory status = Condizioni di vittoria Social policies = Politiche sociali Community = Community Close = Chiudi + # Requires translation! +Do you want to exit the game? = # City screen diff --git a/android/assets/jsons/translationsByLanguage/Korean.properties b/android/assets/jsons/translationsByLanguage/Korean.properties index 399d33658302..86b72e8fee42 100644 --- a/android/assets/jsons/translationsByLanguage/Korean.properties +++ b/android/assets/jsons/translationsByLanguage/Korean.properties @@ -812,6 +812,8 @@ Victory status = 승리 조건 확인 Social policies = 사회 정책 Community = 커뮤니티 Close = 닫기 + # Requires translation! +Do you want to exit the game? = # City screen diff --git a/android/assets/jsons/translationsByLanguage/Malay.properties b/android/assets/jsons/translationsByLanguage/Malay.properties index 0c602fd7a6fa..9807c3df162e 100644 --- a/android/assets/jsons/translationsByLanguage/Malay.properties +++ b/android/assets/jsons/translationsByLanguage/Malay.properties @@ -1274,6 +1274,8 @@ Social policies = Community = # Requires translation! Close = + # Requires translation! +Do you want to exit the game? = # City screen diff --git a/android/assets/jsons/translationsByLanguage/Polish.properties b/android/assets/jsons/translationsByLanguage/Polish.properties index ab8a620734a0..7f06ed275429 100644 --- a/android/assets/jsons/translationsByLanguage/Polish.properties +++ b/android/assets/jsons/translationsByLanguage/Polish.properties @@ -775,6 +775,8 @@ Victory status = Status zwycięstwa Social policies = Ustroje społeczne Community = Społeczność Close = Zamknij + # Requires translation! +Do you want to exit the game? = # City screen diff --git a/android/assets/jsons/translationsByLanguage/Portuguese.properties b/android/assets/jsons/translationsByLanguage/Portuguese.properties index 7c5993c19174..9e51c635ae98 100644 --- a/android/assets/jsons/translationsByLanguage/Portuguese.properties +++ b/android/assets/jsons/translationsByLanguage/Portuguese.properties @@ -833,6 +833,8 @@ Victory status = Status da vitória Social policies = Políticas sociais Community = Comunidade Close = Fechar + # Requires translation! +Do you want to exit the game? = # City screen diff --git a/android/assets/jsons/translationsByLanguage/Romanian.properties b/android/assets/jsons/translationsByLanguage/Romanian.properties index 704d4f005317..26b9e95ab770 100644 --- a/android/assets/jsons/translationsByLanguage/Romanian.properties +++ b/android/assets/jsons/translationsByLanguage/Romanian.properties @@ -1104,6 +1104,8 @@ Social policies = Politici sociale # Requires translation! Community = Close = Închide + # Requires translation! +Do you want to exit the game? = # City screen diff --git a/android/assets/jsons/translationsByLanguage/Russian.properties b/android/assets/jsons/translationsByLanguage/Russian.properties index 80509700ee49..b7992b2b6736 100644 --- a/android/assets/jsons/translationsByLanguage/Russian.properties +++ b/android/assets/jsons/translationsByLanguage/Russian.properties @@ -775,6 +775,7 @@ Victory status = Статус победы Social policies = Общественные институты Community = Сообщество Close = Закрыть +Do you want to exit the game? = Вы хотите выйти из игры? # City screen diff --git a/android/assets/jsons/translationsByLanguage/Simplified_Chinese.properties b/android/assets/jsons/translationsByLanguage/Simplified_Chinese.properties index fb9737b4aae7..b6396ceb3824 100644 --- a/android/assets/jsons/translationsByLanguage/Simplified_Chinese.properties +++ b/android/assets/jsons/translationsByLanguage/Simplified_Chinese.properties @@ -791,6 +791,8 @@ Victory status = 胜利进度 Social policies = 社会政策 Community = 开发者社区 Close = 关闭 + # Requires translation! +Do you want to exit the game? = # City screen diff --git a/android/assets/jsons/translationsByLanguage/Spanish.properties b/android/assets/jsons/translationsByLanguage/Spanish.properties index 020bf07881c8..242aa221002b 100644 --- a/android/assets/jsons/translationsByLanguage/Spanish.properties +++ b/android/assets/jsons/translationsByLanguage/Spanish.properties @@ -779,6 +779,8 @@ Victory status = Estado de victoria Social policies = Políticas sociales Community = Comunidad Close = Cerrar + # Requires translation! +Do you want to exit the game? = # City screen diff --git a/android/assets/jsons/translationsByLanguage/Traditional_Chinese.properties b/android/assets/jsons/translationsByLanguage/Traditional_Chinese.properties index 6c4e1f168850..1b4ea5e5fe5f 100644 --- a/android/assets/jsons/translationsByLanguage/Traditional_Chinese.properties +++ b/android/assets/jsons/translationsByLanguage/Traditional_Chinese.properties @@ -791,6 +791,8 @@ Victory status = 勝利進度 Social policies = 社會政策 Community = 社群 Close = 關閉 + # Requires translation! +Do you want to exit the game? = # City screen diff --git a/android/assets/jsons/translationsByLanguage/Ukrainian.properties b/android/assets/jsons/translationsByLanguage/Ukrainian.properties index 349cfc7f6bf3..0ac85f3464ab 100644 --- a/android/assets/jsons/translationsByLanguage/Ukrainian.properties +++ b/android/assets/jsons/translationsByLanguage/Ukrainian.properties @@ -775,6 +775,7 @@ Victory status = Статус перемоги Social policies = Соціальні інститути Community = Громада Close = Закрити +Do you want to exit the game? = Ви бажаєте вийти з гри? # City screen diff --git a/android/assets/jsons/translationsByLanguage/template.properties b/android/assets/jsons/translationsByLanguage/template.properties index e77510eb6a8e..33cff0975ff1 100644 --- a/android/assets/jsons/translationsByLanguage/template.properties +++ b/android/assets/jsons/translationsByLanguage/template.properties @@ -762,6 +762,7 @@ Victory status = Social policies = Community = Close = +Do you want to exit the game? = # City screen diff --git a/android/src/com/unciv/app/AndroidLauncher.kt b/android/src/com/unciv/app/AndroidLauncher.kt index 8c01028a45fd..c796fa8eec70 100644 --- a/android/src/com/unciv/app/AndroidLauncher.kt +++ b/android/src/com/unciv/app/AndroidLauncher.kt @@ -9,7 +9,9 @@ class AndroidLauncher : AndroidApplication() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val config = AndroidApplicationConfiguration().apply { useImmersiveMode = true } - val game = UncivGame(BuildConfig.VERSION_NAME, CrashReportSenderAndroid(this)) + val game = UncivGame(BuildConfig.VERSION_NAME, + CrashReportSenderAndroid(this)) + {this.finish()} initialize(game, config) } } \ No newline at end of file diff --git a/core/src/com/unciv/UncivGame.kt b/core/src/com/unciv/UncivGame.kt index 32e11acca6f8..0bb48e555023 100644 --- a/core/src/com/unciv/UncivGame.kt +++ b/core/src/com/unciv/UncivGame.kt @@ -24,8 +24,12 @@ import kotlin.concurrent.thread class UncivGame( val version: String, - private val crashReportSender: CrashReportSender? = null + private val crashReportSender: CrashReportSender? = null, + val exitEvent: (()->Unit)? = null ) : Game() { + // we need this secondary constructor because Java code for iOS can't handle Kotlin lambda parameters + constructor(version: String) : this(version, null) + lateinit var gameInfo: GameInfo lateinit var settings : GameSettings lateinit var crashController: CrashController @@ -39,7 +43,6 @@ class UncivGame( var rewriteTranslationFiles = false - lateinit var worldScreen: WorldScreen var music : Music? =null diff --git a/core/src/com/unciv/ui/utils/CameraStageBaseScreen.kt b/core/src/com/unciv/ui/utils/CameraStageBaseScreen.kt index 03d02cbcdb7b..441cd2a6ebef 100644 --- a/core/src/com/unciv/ui/utils/CameraStageBaseScreen.kt +++ b/core/src/com/unciv/ui/utils/CameraStageBaseScreen.kt @@ -106,8 +106,9 @@ open class CameraStageBaseScreen : Screen { internal var batch: Batch = SpriteBatch() } - fun onBackButtonClicked(action:()->Unit){ - stage.addListener(object : InputListener(){ + /** It returns the assigned [InputListener] */ + fun onBackButtonClicked(action:()->Unit): InputListener { + var listener = object : InputListener(){ override fun keyDown(event: InputEvent?, keycode: Int): Boolean { if(keycode == Input.Keys.BACK){ action() @@ -115,7 +116,9 @@ open class CameraStageBaseScreen : Screen { } return false } - }) + } + stage.addListener( listener ) + return listener } } diff --git a/core/src/com/unciv/ui/worldscreen/WorldScreen.kt b/core/src/com/unciv/ui/worldscreen/WorldScreen.kt index 3e9e22161778..bbf3055b2090 100644 --- a/core/src/com/unciv/ui/worldscreen/WorldScreen.kt +++ b/core/src/com/unciv/ui/worldscreen/WorldScreen.kt @@ -3,6 +3,7 @@ package com.unciv.ui.worldscreen import com.badlogic.gdx.Gdx import com.badlogic.gdx.graphics.Color import com.badlogic.gdx.math.Vector2 +import com.badlogic.gdx.scenes.scene2d.InputListener import com.badlogic.gdx.scenes.scene2d.Touchable import com.badlogic.gdx.scenes.scene2d.actions.Actions import com.badlogic.gdx.scenes.scene2d.ui.Button @@ -58,6 +59,8 @@ class WorldScreen(val viewingCiv:CivilizationInfo) : CameraStageBaseScreen() { private val notificationsScroll: NotificationsScroll var shouldUpdate=false + private var backButtonListener : InputListener + init { topBar.setPosition(0f, stage.height - topBar.height) topBar.width = stage.width @@ -126,6 +129,8 @@ class WorldScreen(val viewingCiv:CivilizationInfo) : CameraStageBaseScreen() { shouldUpdate = true } + backButtonListener = onBackButtonClicked { exitGamePrompt() } + // don't run update() directly, because the UncivGame.worldScreen should be set so that the city buttons and tile groups // know what the viewing civ is. shouldUpdate = true @@ -502,5 +507,26 @@ class WorldScreen(val viewingCiv:CivilizationInfo) : CameraStageBaseScreen() { displayTutorial(Tutorial.Embarking) } + private fun exitGamePrompt() { + + // don't show a dialog, if it can't exit the game + if (game.exitEvent == null) + return + + // remove current listener for the "BACK" button to avoid showing the dialog twice + stage.removeListener( backButtonListener ) + + var promptWindow = PopupTable(this) + promptWindow.addGoodSizedLabel("Do you want to exit the game?".tr()) + promptWindow.row() + promptWindow.addButton("Yes"){game.exitEvent?.invoke()} + promptWindow.addButton("No") { + // restore the listener back + stage.addListener(backButtonListener) + promptWindow.close() + } + // show the dialog + promptWindow.open() + } } diff --git a/desktop/src/com/unciv/app/desktop/DesktopLauncher.kt b/desktop/src/com/unciv/app/desktop/DesktopLauncher.kt index 8bda0387c3e1..3a3452177289 100644 --- a/desktop/src/com/unciv/app/desktop/DesktopLauncher.kt +++ b/desktop/src/com/unciv/app/desktop/DesktopLauncher.kt @@ -12,6 +12,7 @@ import com.unciv.UncivGame import com.unciv.models.translations.tr import java.io.File import kotlin.concurrent.thread +import kotlin.system.exitProcess internal object DesktopLauncher { @@ -26,8 +27,7 @@ internal object DesktopLauncher { config.title = "Unciv" config.useHDPI = true - val game = UncivGame("Desktop") - + val game = UncivGame("Desktop", null){exitProcess(0)} if(!RaspberryPiDetector.isRaspberryPi()) // No discord RPC for Raspberry Pi, see https://github.com/yairm210/Unciv/issues/1624 tryActivateDiscord(game) diff --git a/ios/src/com/unciv/app/IOSLauncher.java b/ios/src/com/unciv/app/IOSLauncher.java index 6c9e80d43c45..de09d695e60a 100644 --- a/ios/src/com/unciv/app/IOSLauncher.java +++ b/ios/src/com/unciv/app/IOSLauncher.java @@ -10,7 +10,7 @@ class IOSLauncher extends IOSApplication.Delegate { @Override protected IOSApplication createApplication() { IOSApplicationConfiguration config = new IOSApplicationConfiguration(); - return new IOSApplication(new com.unciv.UncivGame("IOS", null), config); + return new IOSApplication(new com.unciv.UncivGame("IOS"), config); } public static void main(String[] argv) { diff --git a/tests/src/com/unciv/testing/BasicTests.kt b/tests/src/com/unciv/testing/BasicTests.kt index a5761c0a521a..1c54ab79c222 100644 --- a/tests/src/com/unciv/testing/BasicTests.kt +++ b/tests/src/com/unciv/testing/BasicTests.kt @@ -35,7 +35,7 @@ class BasicTests { @Test fun gameIsNotRunWithDebugModes() { - val game = UncivGame("", null) + val game = UncivGame("", null, null) Assert.assertTrue("This test will only pass if the game is not run with debug modes", !game.superchargedForDebug && !game.viewEntireMapForDebug