mirror of
https://github.com/yairm210/Unciv.git
synced 2025-07-29 14:20:17 +07:00
Translation refactoring - part 2 (Tutorials) (#2114)
* Make TranslationFileReader as object class * Generate strings from Tutorials.json * Simplified storage and loading of the tutorials * Transfer existing translations
This commit is contained in:
@ -81,7 +81,7 @@ class UncivGame(
|
||||
|
||||
if (rewriteTranslationFiles) { // Yes, also when running from the Jar. Sue me.
|
||||
translations.readAllLanguagesTranslation()
|
||||
TranslationFileReader().writeNewTranslationFiles(translations)
|
||||
TranslationFileReader.writeNewTranslationFiles(translations)
|
||||
} else {
|
||||
translations.tryReadTranslationForCurrentLanguage()
|
||||
}
|
||||
|
@ -5,11 +5,12 @@ import com.unciv.JsonParser
|
||||
import com.unciv.models.ruleset.Nation
|
||||
import java.nio.charset.Charset
|
||||
import kotlin.collections.set
|
||||
import com.badlogic.gdx.utils.Array
|
||||
|
||||
class TranslationFileReader{
|
||||
object TranslationFileReader {
|
||||
|
||||
private val percentagesFileLocation = "jsons/translations/completionPercentages.properties"
|
||||
val templateFileLocation = "jsons/translations/template.properties"
|
||||
private const val percentagesFileLocation = "jsons/translations/completionPercentages.properties"
|
||||
const val templateFileLocation = "jsons/translations/template.properties"
|
||||
private val charset = Charset.forName("UTF-8").name()
|
||||
|
||||
fun read(translationFile: String): LinkedHashMap<String, String> {
|
||||
@ -34,6 +35,8 @@ class TranslationFileReader{
|
||||
linesFromTemplates.addAll(templateFile.reader().readLines())
|
||||
linesFromTemplates.add("\n#################### Lines from Nations.json ####################\n")
|
||||
linesFromTemplates.addAll(generateNationsStrings())
|
||||
linesFromTemplates.add("\n#################### Lines from Tutorials.json ####################\n")
|
||||
linesFromTemplates.addAll(generateTutorialsStrings())
|
||||
|
||||
val stringBuilder = StringBuilder()
|
||||
for(line in linesFromTemplates){
|
||||
@ -113,4 +116,16 @@ class TranslationFileReader{
|
||||
return strings
|
||||
}
|
||||
|
||||
fun generateTutorialsStrings(): Collection<String> {
|
||||
|
||||
val tutorials = JsonParser().getFromJson(LinkedHashMap<String, Array<String>>().javaClass, "jsons/Tutorials.json")
|
||||
val strings = mutableSetOf<String>() // using set to avoid duplicates
|
||||
|
||||
for (tutorial in tutorials) {
|
||||
for (str in tutorial.value)
|
||||
if (str != "") strings.add("$str = ")
|
||||
}
|
||||
return strings
|
||||
}
|
||||
|
||||
}
|
@ -41,8 +41,7 @@ class Translations : LinkedHashMap<String, TranslationEntry>(){
|
||||
val languageTranslations:HashMap<String,String>
|
||||
try { // On some devices we get a weird UnsupportedEncodingException
|
||||
// which is super odd because everyone should support UTF-8
|
||||
languageTranslations = TranslationFileReader()
|
||||
.read(translationFileName)
|
||||
languageTranslations = TranslationFileReader.read(translationFileName)
|
||||
}catch (ex:Exception){
|
||||
return
|
||||
}
|
||||
@ -111,7 +110,7 @@ class Translations : LinkedHashMap<String, TranslationEntry>(){
|
||||
fun loadPercentageCompleteOfLanguages(){
|
||||
val startTime = System.currentTimeMillis()
|
||||
|
||||
percentCompleteOfLanguages = TranslationFileReader().readLanguagePercentages()
|
||||
percentCompleteOfLanguages = TranslationFileReader.readLanguagePercentages()
|
||||
|
||||
val translationFilesTime = System.currentTimeMillis() - startTime
|
||||
println("Loading percent complete of languages - "+translationFilesTime+"ms")
|
||||
@ -121,8 +120,9 @@ class Translations : LinkedHashMap<String, TranslationEntry>(){
|
||||
val percentComplete = HashMap<String,Int>()
|
||||
val translationStart = System.currentTimeMillis()
|
||||
|
||||
var allTranslations = TranslationFileReader().generateNationsStrings().size
|
||||
Gdx.files.internal(TranslationFileReader().templateFileLocation)
|
||||
var allTranslations = TranslationFileReader.generateNationsStrings().size
|
||||
allTranslations += TranslationFileReader.generateTutorialsStrings().size
|
||||
Gdx.files.internal(TranslationFileReader.templateFileLocation)
|
||||
.reader().forEachLine { if(it.contains(" = ")) allTranslations+=1 }
|
||||
|
||||
for(language in getLanguagesWithTranslationFile()){
|
||||
|
@ -2,11 +2,9 @@ package com.unciv.ui
|
||||
|
||||
import com.badlogic.gdx.scenes.scene2d.Actor
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.*
|
||||
import com.unciv.JsonParser
|
||||
import com.unciv.UncivGame
|
||||
import com.unciv.models.ruleset.Ruleset
|
||||
import com.unciv.models.translations.tr
|
||||
import com.unciv.ui.tutorials.TutorialMiner
|
||||
import com.unciv.ui.utils.*
|
||||
import java.util.*
|
||||
|
||||
@ -19,8 +17,6 @@ class CivilopediaScreen(ruleset: Ruleset) : CameraStageBaseScreen() {
|
||||
private val entrySelectTable = Table().apply { defaults().pad(5f) }
|
||||
val description = "".toLabel()
|
||||
|
||||
private val tutorialMiner = TutorialMiner(JsonParser())
|
||||
|
||||
fun select(category: String) {
|
||||
entrySelectTable.clear()
|
||||
for (entry in categoryToEntries[category]!!
|
||||
@ -87,8 +83,8 @@ class CivilopediaScreen(ruleset: Ruleset) : CameraStageBaseScreen() {
|
||||
.map { CivilopediaEntry(it.name,it.getDescription(ruleset.unitPromotions.values, true),
|
||||
Table().apply { add(ImageGetter.getPromotionIcon(it.name)) }) }
|
||||
|
||||
categoryToEntries["Tutorials"] = tutorialMiner.getCivilopediaTutorials(UncivGame.Current.settings.language)
|
||||
.map { CivilopediaEntry(it.key.value.replace("_"," "), it.value.joinToString("\n\n")) }
|
||||
categoryToEntries["Tutorials"] = tutorialController.getCivilopediaTutorials()
|
||||
.map { CivilopediaEntry(it.key.replace("_"," "), it.value.joinToString("\n\n") { line -> line.tr() }) }
|
||||
|
||||
for (category in categoryToEntries.keys) {
|
||||
val button = TextButton(category.tr(), skin)
|
||||
|
@ -1,16 +1,18 @@
|
||||
package com.unciv.ui.tutorials
|
||||
|
||||
import com.badlogic.gdx.utils.Array
|
||||
import com.unciv.JsonParser
|
||||
import com.unciv.UncivGame
|
||||
import com.unciv.models.Tutorial
|
||||
import com.unciv.ui.utils.CameraStageBaseScreen
|
||||
|
||||
class TutorialController(
|
||||
private val tutorialMiner: TutorialMiner,
|
||||
private val tutorialRender: TutorialRender
|
||||
) {
|
||||
class TutorialController(screen: CameraStageBaseScreen) {
|
||||
|
||||
private val tutorialQueue = mutableSetOf<Tutorial>()
|
||||
private var isTutorialShowing = false
|
||||
var allTutorialsShowedCallback: (() -> Unit)? = null
|
||||
private val tutorialRender = TutorialRender(screen)
|
||||
private val tutorials = JsonParser().getFromJson(LinkedHashMap<String, Array<String>>().javaClass, "jsons/Tutorials.json")
|
||||
|
||||
fun showTutorial(tutorial: Tutorial) {
|
||||
if (!UncivGame.Current.settings.showTutorials) return
|
||||
@ -26,7 +28,7 @@ class TutorialController(
|
||||
allTutorialsShowedCallback?.invoke()
|
||||
} else if (!isTutorialShowing) {
|
||||
isTutorialShowing = true
|
||||
val texts = tutorialMiner.getTutorial(tutorial, UncivGame.Current.settings.language)
|
||||
val texts = getTutorial(tutorial)
|
||||
tutorialRender.showTutorial(TutorialForRender(tutorial, texts)) {
|
||||
tutorialQueue.remove(tutorial)
|
||||
isTutorialShowing = false
|
||||
@ -40,4 +42,13 @@ class TutorialController(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun getCivilopediaTutorials(): Map<String, Array<String>> {
|
||||
return tutorials.filter { Tutorial.findByName(it.key)!!.isCivilopedia }
|
||||
}
|
||||
|
||||
private fun getTutorial(tutorial: Tutorial): Array<String> {
|
||||
|
||||
return tutorials[tutorial.value] ?: Array()
|
||||
}
|
||||
}
|
||||
|
@ -1,40 +0,0 @@
|
||||
package com.unciv.ui.tutorials
|
||||
|
||||
import com.badlogic.gdx.Gdx
|
||||
import com.badlogic.gdx.utils.Array
|
||||
import com.unciv.JsonParser
|
||||
import com.unciv.models.Tutorial
|
||||
|
||||
class TutorialMiner(private val jsonParser: JsonParser) {
|
||||
|
||||
companion object {
|
||||
private const val TUTORIALS_PATH = "jsons/Tutorials/Tutorials_%s.json"
|
||||
}
|
||||
|
||||
fun getCivilopediaTutorials(language: String): Map<Tutorial, List<String>> =
|
||||
getAllTutorials(language).filter { it.key.isCivilopedia }
|
||||
|
||||
fun getTutorial(tutorial: Tutorial, language: String): List<String> {
|
||||
val tutors = getAllTutorials(language)[tutorial]
|
||||
if (tutors != null) {
|
||||
return tutors
|
||||
} else {
|
||||
return emptyList()
|
||||
}
|
||||
}
|
||||
|
||||
private fun getAllTutorials(language: String): Map<Tutorial, List<String>> {
|
||||
val path = TUTORIALS_PATH.format(language)
|
||||
if (!Gdx.files.internal(path).exists()) return emptyMap()
|
||||
|
||||
// ...Yes. Disgusting. I wish I didn't have to do this.
|
||||
val x = LinkedHashMap<String, Array<Array<String>>>()
|
||||
val tutorials: LinkedHashMap<String, Array<Array<String>>> = jsonParser.getFromJson(x.javaClass, path)
|
||||
|
||||
val tutorialMap = mutableMapOf<Tutorial, List<String>>()
|
||||
for (tutorial in tutorials) {
|
||||
tutorialMap[Tutorial.findByName(tutorial.key)!!] = tutorial.value.map { it.joinToString("\n") }
|
||||
}
|
||||
return tutorialMap
|
||||
}
|
||||
}
|
@ -2,6 +2,7 @@ package com.unciv.ui.tutorials
|
||||
|
||||
import com.badlogic.gdx.Gdx
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.TextButton
|
||||
import com.badlogic.gdx.utils.Array
|
||||
import com.unciv.models.Tutorial
|
||||
import com.unciv.models.translations.tr
|
||||
import com.unciv.ui.utils.CameraStageBaseScreen
|
||||
@ -9,7 +10,7 @@ import com.unciv.ui.utils.ImageGetter
|
||||
import com.unciv.ui.utils.Popup
|
||||
import com.unciv.ui.utils.onClick
|
||||
|
||||
data class TutorialForRender(val tutorial: Tutorial, val texts: List<String>)
|
||||
data class TutorialForRender(val tutorial: Tutorial, val texts: Array<String>)
|
||||
|
||||
class TutorialRender(private val screen: CameraStageBaseScreen) {
|
||||
|
||||
@ -17,7 +18,7 @@ class TutorialRender(private val screen: CameraStageBaseScreen) {
|
||||
showDialog(tutorial.tutorial.name, tutorial.texts, closeAction)
|
||||
}
|
||||
|
||||
private fun showDialog(tutorialName: String, texts: List<String>, closeAction: () -> Unit) {
|
||||
private fun showDialog(tutorialName: String, texts: Array<String>, closeAction: () -> Unit) {
|
||||
val text = texts.firstOrNull()
|
||||
if (text == null) {
|
||||
closeAction()
|
||||
@ -33,7 +34,8 @@ class TutorialRender(private val screen: CameraStageBaseScreen) {
|
||||
val button = TextButton("Close".tr(), CameraStageBaseScreen.skin)
|
||||
button.onClick {
|
||||
tutorialPopup.remove()
|
||||
showDialog(tutorialName, texts - text, closeAction)
|
||||
texts.removeIndex(0)
|
||||
showDialog(tutorialName, texts, closeAction)
|
||||
}
|
||||
tutorialPopup.add(button).pad(10f)
|
||||
tutorialPopup.open()
|
||||
|
@ -11,14 +11,11 @@ import com.badlogic.gdx.scenes.scene2d.*
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.*
|
||||
import com.badlogic.gdx.scenes.scene2d.utils.ClickListener
|
||||
import com.badlogic.gdx.utils.viewport.ExtendViewport
|
||||
import com.unciv.JsonParser
|
||||
import com.unciv.UncivGame
|
||||
import com.unciv.models.Tutorial
|
||||
import com.unciv.models.UncivSound
|
||||
import com.unciv.models.translations.tr
|
||||
import com.unciv.ui.tutorials.TutorialController
|
||||
import com.unciv.ui.tutorials.TutorialMiner
|
||||
import com.unciv.ui.tutorials.TutorialRender
|
||||
import kotlin.concurrent.thread
|
||||
|
||||
open class CameraStageBaseScreen : Screen {
|
||||
@ -26,9 +23,7 @@ open class CameraStageBaseScreen : Screen {
|
||||
var game: UncivGame = UncivGame.Current
|
||||
var stage: Stage
|
||||
|
||||
val tutorialController by lazy {
|
||||
TutorialController(TutorialMiner(JsonParser()), TutorialRender(this))
|
||||
}
|
||||
protected val tutorialController by lazy { TutorialController(this) }
|
||||
|
||||
init {
|
||||
val width:Float
|
||||
@ -66,9 +61,7 @@ open class CameraStageBaseScreen : Screen {
|
||||
|
||||
override fun dispose() {}
|
||||
|
||||
fun displayTutorial(tutorial: Tutorial) {
|
||||
tutorialController.showTutorial(tutorial)
|
||||
}
|
||||
fun displayTutorial(tutorial: Tutorial) = tutorialController.showTutorial(tutorial)
|
||||
|
||||
companion object {
|
||||
var skin = Skin(Gdx.files.internal("skin/flat-earth-ui.json"))
|
||||
@ -90,7 +83,7 @@ open class CameraStageBaseScreen : Screen {
|
||||
|
||||
/** It returns the assigned [InputListener] */
|
||||
fun onBackButtonClicked(action:()->Unit): InputListener {
|
||||
var listener = object : InputListener(){
|
||||
val listener = object : InputListener(){
|
||||
override fun keyDown(event: InputEvent?, keycode: Int): Boolean {
|
||||
if(keycode == Input.Keys.BACK){
|
||||
action()
|
||||
|
@ -30,9 +30,6 @@ class Fonts {
|
||||
charSet.addAll(defaultText.asIterable())
|
||||
|
||||
if (language != "") {
|
||||
if (Gdx.files.internal("jsons/Tutorials/Tutorials_$language.json").exists())
|
||||
charSet.addAll(Gdx.files.internal("jsons/Tutorials/Tutorials_$language.json").readString().asIterable())
|
||||
|
||||
for (entry in UncivGame.Current.translations.entries) {
|
||||
for (lang in entry.value) {
|
||||
if (lang.key == language) charSet.addAll(lang.value.asIterable())
|
||||
|
@ -517,7 +517,7 @@ class WorldScreen(val viewingCiv:CivilizationInfo) : CameraStageBaseScreen() {
|
||||
// remove current listener for the "BACK" button to avoid showing the dialog twice
|
||||
stage.removeListener( backButtonListener )
|
||||
|
||||
var promptWindow = Popup(this)
|
||||
val promptWindow = Popup(this)
|
||||
promptWindow.addGoodSizedLabel("Do you want to exit the game?".tr())
|
||||
promptWindow.row()
|
||||
promptWindow.addButton("Yes"){game.exitEvent?.invoke()}
|
||||
|
Reference in New Issue
Block a user