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
This commit is contained in:
JackRainy 2020-01-12 23:05:49 +02:00 committed by Yair Morgenstern
parent ca59dc4e1f
commit 8a327fa7be
25 changed files with 77 additions and 10 deletions

View File

@ -790,6 +790,8 @@ Victory status = Cesta k vítězství
Social policies = Sociální politika Social policies = Sociální politika
Community = Komunita Community = Komunita
Close = Zavřít Close = Zavřít
# Requires translation!
Do you want to exit the game? =
# City screen # City screen

View File

@ -1222,6 +1222,8 @@ Social policies = Sociaal beleid
# Requires translation! # Requires translation!
Community = Community =
Close = Sluiten Close = Sluiten
# Requires translation!
Do you want to exit the game? =
# City screen # City screen

View File

@ -1385,6 +1385,8 @@ Social policies =
Community = Community =
# Requires translation! # Requires translation!
Close = Close =
# Requires translation!
Do you want to exit the game? =
# City screen # City screen

View File

@ -775,6 +775,8 @@ Victory status = Conditions de victoire
Social policies = Doctrines Social policies = Doctrines
Community = Communauté Community = Communauté
Close = Fermer Close = Fermer
# Requires translation!
Do you want to exit the game? =
# City screen # City screen

View File

@ -793,6 +793,8 @@ Victory status = Siegesstatus
Social policies = Sozialpolitiken Social policies = Sozialpolitiken
Community = Gemeinschaft Community = Gemeinschaft
Close = Schließen Close = Schließen
# Requires translation!
Do you want to exit the game? =
# City screen # City screen

View File

@ -791,6 +791,8 @@ Victory status = Status kemenangan
Social policies = Kebijakan sosial Social policies = Kebijakan sosial
Community = Komunitas Community = Komunitas
Close = Tutup Close = Tutup
# Requires translation!
Do you want to exit the game? =
# City screen # City screen

View File

@ -762,6 +762,8 @@ Victory status = Condizioni di vittoria
Social policies = Politiche sociali Social policies = Politiche sociali
Community = Community Community = Community
Close = Chiudi Close = Chiudi
# Requires translation!
Do you want to exit the game? =
# City screen # City screen

View File

@ -812,6 +812,8 @@ Victory status = 승리 조건 확인
Social policies = 사회 정책 Social policies = 사회 정책
Community = 커뮤니티 Community = 커뮤니티
Close = 닫기 Close = 닫기
# Requires translation!
Do you want to exit the game? =
# City screen # City screen

View File

@ -1274,6 +1274,8 @@ Social policies =
Community = Community =
# Requires translation! # Requires translation!
Close = Close =
# Requires translation!
Do you want to exit the game? =
# City screen # City screen

View File

@ -775,6 +775,8 @@ Victory status = Status zwycięstwa
Social policies = Ustroje społeczne Social policies = Ustroje społeczne
Community = Społeczność Community = Społeczność
Close = Zamknij Close = Zamknij
# Requires translation!
Do you want to exit the game? =
# City screen # City screen

View File

@ -833,6 +833,8 @@ Victory status = Status da vitória
Social policies = Políticas sociais Social policies = Políticas sociais
Community = Comunidade Community = Comunidade
Close = Fechar Close = Fechar
# Requires translation!
Do you want to exit the game? =
# City screen # City screen

View File

@ -1104,6 +1104,8 @@ Social policies = Politici sociale
# Requires translation! # Requires translation!
Community = Community =
Close = Închide Close = Închide
# Requires translation!
Do you want to exit the game? =
# City screen # City screen

View File

@ -775,6 +775,7 @@ Victory status = Статус победы
Social policies = Общественные институты Social policies = Общественные институты
Community = Сообщество Community = Сообщество
Close = Закрыть Close = Закрыть
Do you want to exit the game? = Вы хотите выйти из игры?
# City screen # City screen

View File

@ -791,6 +791,8 @@ Victory status = 胜利进度
Social policies = 社会政策 Social policies = 社会政策
Community = 开发者社区 Community = 开发者社区
Close = 关闭 Close = 关闭
# Requires translation!
Do you want to exit the game? =
# City screen # City screen

View File

@ -779,6 +779,8 @@ Victory status = Estado de victoria
Social policies = Políticas sociales Social policies = Políticas sociales
Community = Comunidad Community = Comunidad
Close = Cerrar Close = Cerrar
# Requires translation!
Do you want to exit the game? =
# City screen # City screen

View File

@ -791,6 +791,8 @@ Victory status = 勝利進度
Social policies = 社會政策 Social policies = 社會政策
Community = 社群 Community = 社群
Close = 關閉 Close = 關閉
# Requires translation!
Do you want to exit the game? =
# City screen # City screen

View File

@ -775,6 +775,7 @@ Victory status = Статус перемоги
Social policies = Соціальні інститути Social policies = Соціальні інститути
Community = Громада Community = Громада
Close = Закрити Close = Закрити
Do you want to exit the game? = Ви бажаєте вийти з гри?
# City screen # City screen

View File

@ -762,6 +762,7 @@ Victory status =
Social policies = Social policies =
Community = Community =
Close = Close =
Do you want to exit the game? =
# City screen # City screen

View File

@ -9,7 +9,9 @@ class AndroidLauncher : AndroidApplication() {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
val config = AndroidApplicationConfiguration().apply { useImmersiveMode = true } 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) initialize(game, config)
} }
} }

View File

@ -24,8 +24,12 @@ import kotlin.concurrent.thread
class UncivGame( class UncivGame(
val version: String, val version: String,
private val crashReportSender: CrashReportSender? = null private val crashReportSender: CrashReportSender? = null,
val exitEvent: (()->Unit)? = null
) : Game() { ) : 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 gameInfo: GameInfo
lateinit var settings : GameSettings lateinit var settings : GameSettings
lateinit var crashController: CrashController lateinit var crashController: CrashController
@ -39,7 +43,6 @@ class UncivGame(
var rewriteTranslationFiles = false var rewriteTranslationFiles = false
lateinit var worldScreen: WorldScreen lateinit var worldScreen: WorldScreen
var music : Music? =null var music : Music? =null

View File

@ -106,8 +106,9 @@ open class CameraStageBaseScreen : Screen {
internal var batch: Batch = SpriteBatch() internal var batch: Batch = SpriteBatch()
} }
fun onBackButtonClicked(action:()->Unit){ /** It returns the assigned [InputListener] */
stage.addListener(object : InputListener(){ fun onBackButtonClicked(action:()->Unit): InputListener {
var listener = object : InputListener(){
override fun keyDown(event: InputEvent?, keycode: Int): Boolean { override fun keyDown(event: InputEvent?, keycode: Int): Boolean {
if(keycode == Input.Keys.BACK){ if(keycode == Input.Keys.BACK){
action() action()
@ -115,7 +116,9 @@ open class CameraStageBaseScreen : Screen {
} }
return false return false
} }
}) }
stage.addListener( listener )
return listener
} }
} }

View File

@ -3,6 +3,7 @@ package com.unciv.ui.worldscreen
import com.badlogic.gdx.Gdx import com.badlogic.gdx.Gdx
import com.badlogic.gdx.graphics.Color import com.badlogic.gdx.graphics.Color
import com.badlogic.gdx.math.Vector2 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.Touchable
import com.badlogic.gdx.scenes.scene2d.actions.Actions import com.badlogic.gdx.scenes.scene2d.actions.Actions
import com.badlogic.gdx.scenes.scene2d.ui.Button import com.badlogic.gdx.scenes.scene2d.ui.Button
@ -58,6 +59,8 @@ class WorldScreen(val viewingCiv:CivilizationInfo) : CameraStageBaseScreen() {
private val notificationsScroll: NotificationsScroll private val notificationsScroll: NotificationsScroll
var shouldUpdate=false var shouldUpdate=false
private var backButtonListener : InputListener
init { init {
topBar.setPosition(0f, stage.height - topBar.height) topBar.setPosition(0f, stage.height - topBar.height)
topBar.width = stage.width topBar.width = stage.width
@ -126,6 +129,8 @@ class WorldScreen(val viewingCiv:CivilizationInfo) : CameraStageBaseScreen() {
shouldUpdate = true 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 // 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. // know what the viewing civ is.
shouldUpdate = true shouldUpdate = true
@ -502,5 +507,26 @@ class WorldScreen(val viewingCiv:CivilizationInfo) : CameraStageBaseScreen() {
displayTutorial(Tutorial.Embarking) 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()
}
} }

View File

@ -12,6 +12,7 @@ import com.unciv.UncivGame
import com.unciv.models.translations.tr import com.unciv.models.translations.tr
import java.io.File import java.io.File
import kotlin.concurrent.thread import kotlin.concurrent.thread
import kotlin.system.exitProcess
internal object DesktopLauncher { internal object DesktopLauncher {
@ -26,8 +27,7 @@ internal object DesktopLauncher {
config.title = "Unciv" config.title = "Unciv"
config.useHDPI = true 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 if(!RaspberryPiDetector.isRaspberryPi()) // No discord RPC for Raspberry Pi, see https://github.com/yairm210/Unciv/issues/1624
tryActivateDiscord(game) tryActivateDiscord(game)

View File

@ -10,7 +10,7 @@ class IOSLauncher extends IOSApplication.Delegate {
@Override @Override
protected IOSApplication createApplication() { protected IOSApplication createApplication() {
IOSApplicationConfiguration config = new IOSApplicationConfiguration(); 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) { public static void main(String[] argv) {

View File

@ -35,7 +35,7 @@ class BasicTests {
@Test @Test
fun gameIsNotRunWithDebugModes() { 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", Assert.assertTrue("This test will only pass if the game is not run with debug modes",
!game.superchargedForDebug !game.superchargedForDebug
&& !game.viewEntireMapForDebug && !game.viewEntireMapForDebug