Browse Source

Update GUI Translation demo for 4.0 (#930)

- Add PO support in addition to CSV.

Co-authored-by: SkyJJ <[email protected]>
Hugo Locurcio 1 year ago
parent
commit
5bda007763
59 changed files with 812 additions and 323 deletions
  1. 27 5
      gui/translation/README.md
  2. 0 0
      gui/translation/audio/hello_en.wav
  3. 24 0
      gui/translation/audio/hello_en.wav.import
  4. 0 0
      gui/translation/audio/hello_es.wav
  5. 24 0
      gui/translation/audio/hello_es.wav.import
  6. 0 0
      gui/translation/audio/hello_jp.wav
  7. 24 0
      gui/translation/audio/hello_jp.wav.import
  8. BIN
      gui/translation/audio/hello_ru.wav
  9. 24 0
      gui/translation/audio/hello_ru.wav.import
  10. BIN
      gui/translation/flag_japan.png
  11. BIN
      gui/translation/flag_spain.png
  12. BIN
      gui/translation/flag_uk.png
  13. 0 12
      gui/translation/font/droid_sans.tres
  14. 0 0
      gui/translation/fonts/DroidSans.ttf
  15. 5 4
      gui/translation/fonts/DroidSans.ttf.import
  16. 0 0
      gui/translation/fonts/DroidSansArabic.ttf
  17. 5 4
      gui/translation/fonts/DroidSansArabic.ttf.import
  18. 0 0
      gui/translation/fonts/DroidSansFallback.ttf
  19. 5 4
      gui/translation/fonts/DroidSansFallback.ttf.import
  20. 0 0
      gui/translation/fonts/DroidSansHebrew.ttf
  21. 5 4
      gui/translation/fonts/DroidSansHebrew.ttf.import
  22. 0 0
      gui/translation/fonts/DroidSansJapanese.ttf
  23. 5 4
      gui/translation/fonts/DroidSansJapanese.ttf.import
  24. 0 0
      gui/translation/fonts/DroidSansThai.ttf
  25. 5 4
      gui/translation/fonts/DroidSansThai.ttf.import
  26. 1 1
      gui/translation/fonts/LICENSE.DroidSans.txt
  27. 33 0
      gui/translation/fonts/droid_sans.tres
  28. 0 24
      gui/translation/hello_en.wav.import
  29. 0 24
      gui/translation/hello_es.wav.import
  30. 0 24
      gui/translation/hello_jp.wav.import
  31. BIN
      gui/translation/icon.webp
  32. 1 1
      gui/translation/icon.webp.import
  33. BIN
      gui/translation/images/flag_japan.webp
  34. 4 4
      gui/translation/images/flag_japan.webp.import
  35. BIN
      gui/translation/images/flag_russia.webp
  36. 34 0
      gui/translation/images/flag_russia.webp.import
  37. BIN
      gui/translation/images/flag_spain.webp
  38. 4 4
      gui/translation/images/flag_spain.webp.import
  39. BIN
      gui/translation/images/flag_uk.webp
  40. 4 4
      gui/translation/images/flag_uk.webp.import
  41. BIN
      gui/translation/images/speaker.webp
  42. 4 4
      gui/translation/images/speaker.webp.import
  43. 9 8
      gui/translation/project.godot
  44. BIN
      gui/translation/screenshots/translation.png
  45. BIN
      gui/translation/screenshots/translation.webp
  46. BIN
      gui/translation/speaker.png
  47. 0 4
      gui/translation/text.csv
  48. 0 17
      gui/translation/text.csv.import
  49. 47 0
      gui/translation/translation_csv.gd
  50. 0 32
      gui/translation/translation_demo.gd
  51. 0 131
      gui/translation/translation_demo.tscn
  52. 144 0
      gui/translation/translation_demo_csv.tscn
  53. 130 0
      gui/translation/translation_demo_po.tscn
  54. 44 0
      gui/translation/translation_po.gd
  55. 4 0
      gui/translation/translations/csv/text.csv
  56. 17 0
      gui/translation/translations/csv/text.csv.import
  57. 56 0
      gui/translation/translations/po/translation_demo.pot
  58. 62 0
      gui/translation/translations/po/translation_demo_es.po
  59. 61 0
      gui/translation/translations/po/translation_demo_ja.po

+ 27 - 5
gui/translation/README.md

@@ -1,14 +1,36 @@
 # GUI Translation Demo
 # GUI Translation Demo
 
 
-A demo showing how Godot seamlessly enables
-the use of localized resources and texts.
+This is a demo of how a project can be internationalized. Translations are
+created in a CSV file and then imported into Godot.
+
+For correct display, the font used must contain the glyphs required by the
+target language. See the `fonts` folder for some fonts that you can use in your
+project. Godot can load system fonts as a fallback, but this is not supported on
+all platforms and the different visual design of system fonts can create
+inconsistencies.
+
+Godot allows internationalized text to change automatically when the locale is
+modified. Resources can also be set to internationalized alternatives and replaced
+automatically on locale change. This process is known as *remapping*.
+
+Both CSV and gettext (PO/POT) approaches are showcased. Use the button in the
+bottom-right corner to switch between the two approaches.
+
+The resouce remapping process with PO is the same with CSV. The in-game text translation
+process is also the same – use keys to fetch the appropriate translation.
+
+The main difference between PO files and CSV files is the way both of them store
+the translated data in their files.  Have a look at the `translations/po`
+and `translations/csv` folders to see the files involved.
+
+See [Internationalizing games](https://docs.godotengine.org/en/latest/tutorials/i18n/internationalizing_games.html)
+and [Localization using gettext](https://docs.godotengine.org/en/latest/tutorials/i18n/localization_using_gettext.html)
+for more information.
 
 
 Language: GDScript
 Language: GDScript
 
 
 Renderer: Compatibility
 Renderer: Compatibility
 
 
-Check out this demo on the asset library: https://godotengine.org/asset-library/asset/134
-
 ## Screenshots
 ## Screenshots
 
 
-![Screenshot](screenshots/translation.png)
+![Screenshot](screenshots/translation.webp)

+ 0 - 0
gui/translation/hello_en.wav → gui/translation/audio/hello_en.wav


+ 24 - 0
gui/translation/audio/hello_en.wav.import

@@ -0,0 +1,24 @@
+[remap]
+
+importer="wav"
+type="AudioStreamWAV"
+uid="uid://ciept8j0x21to"
+path="res://.godot/imported/hello_en.wav-2eea592f221b07e3c37c5477c1da8173.sample"
+
+[deps]
+
+source_file="res://audio/hello_en.wav"
+dest_files=["res://.godot/imported/hello_en.wav-2eea592f221b07e3c37c5477c1da8173.sample"]
+
+[params]
+
+force/8_bit=false
+force/mono=false
+force/max_rate=false
+force/max_rate_hz=44100
+edit/trim=false
+edit/normalize=false
+edit/loop_mode=0
+edit/loop_begin=0
+edit/loop_end=-1
+compress/mode=0

+ 0 - 0
gui/translation/hello_es.wav → gui/translation/audio/hello_es.wav


+ 24 - 0
gui/translation/audio/hello_es.wav.import

@@ -0,0 +1,24 @@
+[remap]
+
+importer="wav"
+type="AudioStreamWAV"
+uid="uid://dd4xk00uh27hj"
+path="res://.godot/imported/hello_es.wav-0b3ee7fc19ef7ac4822f3f3dc177c570.sample"
+
+[deps]
+
+source_file="res://audio/hello_es.wav"
+dest_files=["res://.godot/imported/hello_es.wav-0b3ee7fc19ef7ac4822f3f3dc177c570.sample"]
+
+[params]
+
+force/8_bit=false
+force/mono=false
+force/max_rate=false
+force/max_rate_hz=44100
+edit/trim=false
+edit/normalize=false
+edit/loop_mode=0
+edit/loop_begin=0
+edit/loop_end=-1
+compress/mode=0

+ 0 - 0
gui/translation/hello_jp.wav → gui/translation/audio/hello_jp.wav


+ 24 - 0
gui/translation/audio/hello_jp.wav.import

@@ -0,0 +1,24 @@
+[remap]
+
+importer="wav"
+type="AudioStreamWAV"
+uid="uid://3tnymbrsqo0w"
+path="res://.godot/imported/hello_jp.wav-c7c916ef924fa85620d3858f227d094f.sample"
+
+[deps]
+
+source_file="res://audio/hello_jp.wav"
+dest_files=["res://.godot/imported/hello_jp.wav-c7c916ef924fa85620d3858f227d094f.sample"]
+
+[params]
+
+force/8_bit=false
+force/mono=false
+force/max_rate=false
+force/max_rate_hz=44100
+edit/trim=false
+edit/normalize=false
+edit/loop_mode=0
+edit/loop_begin=0
+edit/loop_end=-1
+compress/mode=0

BIN
gui/translation/audio/hello_ru.wav


+ 24 - 0
gui/translation/audio/hello_ru.wav.import

@@ -0,0 +1,24 @@
+[remap]
+
+importer="wav"
+type="AudioStreamWAV"
+uid="uid://dkuqg8u4fid5m"
+path="res://.godot/imported/hello_ru.wav-490e2b267af12af16807f2bf3de6d995.sample"
+
+[deps]
+
+source_file="res://audio/hello_ru.wav"
+dest_files=["res://.godot/imported/hello_ru.wav-490e2b267af12af16807f2bf3de6d995.sample"]
+
+[params]
+
+force/8_bit=false
+force/mono=false
+force/max_rate=false
+force/max_rate_hz=44100
+edit/trim=false
+edit/normalize=false
+edit/loop_mode=0
+edit/loop_begin=0
+edit/loop_end=-1
+compress/mode=0

BIN
gui/translation/flag_japan.png


BIN
gui/translation/flag_spain.png


BIN
gui/translation/flag_uk.png


+ 0 - 12
gui/translation/font/droid_sans.tres

@@ -1,12 +0,0 @@
-[gd_resource type="FontVariation" load_steps=7 format=3 uid="uid://duo4ycm3e6mrb"]
-
-[ext_resource type="FontFile" uid="uid://c7ujio1oqntre" path="res://font/DroidSansArabic.ttf" id="1"]
-[ext_resource type="FontFile" uid="uid://xesv5idkrqcd" path="res://font/DroidSansFallback.ttf" id="2"]
-[ext_resource type="FontFile" uid="uid://cft2167j0ba27" path="res://font/DroidSansHebrew.ttf" id="3"]
-[ext_resource type="FontFile" uid="uid://rdmplfeo1mfc" path="res://font/DroidSansJapanese.ttf" id="4"]
-[ext_resource type="FontFile" uid="uid://ctmwkt7kh6cst" path="res://font/DroidSansThai.ttf" id="5"]
-[ext_resource type="FontFile" uid="uid://33p1pmbcp0bh" path="res://font/DroidSans.ttf" id="6"]
-
-[resource]
-fallbacks = Array[Font]([ExtResource("4"), ExtResource("5"), ExtResource("3"), ExtResource("1"), ExtResource("2")])
-base_font = ExtResource("6")

+ 0 - 0
gui/translation/font/DroidSans.ttf → gui/translation/fonts/DroidSans.ttf


+ 5 - 4
gui/translation/font/DroidSans.ttf.import → gui/translation/fonts/DroidSans.ttf.import

@@ -2,19 +2,20 @@
 
 
 importer="font_data_dynamic"
 importer="font_data_dynamic"
 type="FontFile"
 type="FontFile"
-uid="uid://33p1pmbcp0bh"
-path="res://.godot/imported/DroidSans.ttf-ba789e8a8b60473207799201d8a90bb4.fontdata"
+uid="uid://qaejxgrojp2d"
+path="res://.godot/imported/DroidSans.ttf-f4f3e617929333a8a3b131725141d728.fontdata"
 
 
 [deps]
 [deps]
 
 
-source_file="res://font/DroidSans.ttf"
-dest_files=["res://.godot/imported/DroidSans.ttf-ba789e8a8b60473207799201d8a90bb4.fontdata"]
+source_file="res://fonts/DroidSans.ttf"
+dest_files=["res://.godot/imported/DroidSans.ttf-f4f3e617929333a8a3b131725141d728.fontdata"]
 
 
 [params]
 [params]
 
 
 Rendering=null
 Rendering=null
 antialiasing=1
 antialiasing=1
 generate_mipmaps=false
 generate_mipmaps=false
+disable_embedded_bitmaps=true
 multichannel_signed_distance_field=false
 multichannel_signed_distance_field=false
 msdf_pixel_range=8
 msdf_pixel_range=8
 msdf_size=48
 msdf_size=48

+ 0 - 0
gui/translation/font/DroidSansArabic.ttf → gui/translation/fonts/DroidSansArabic.ttf


+ 5 - 4
gui/translation/font/DroidSansArabic.ttf.import → gui/translation/fonts/DroidSansArabic.ttf.import

@@ -2,19 +2,20 @@
 
 
 importer="font_data_dynamic"
 importer="font_data_dynamic"
 type="FontFile"
 type="FontFile"
-uid="uid://c7ujio1oqntre"
-path="res://.godot/imported/DroidSansArabic.ttf-da8dabd885d494269ba77c8d78d8ed5b.fontdata"
+uid="uid://b6jt1itr5jreh"
+path="res://.godot/imported/DroidSansArabic.ttf-e3dcbe0c4bc0f3f609a01ac9b0b2d1d4.fontdata"
 
 
 [deps]
 [deps]
 
 
-source_file="res://font/DroidSansArabic.ttf"
-dest_files=["res://.godot/imported/DroidSansArabic.ttf-da8dabd885d494269ba77c8d78d8ed5b.fontdata"]
+source_file="res://fonts/DroidSansArabic.ttf"
+dest_files=["res://.godot/imported/DroidSansArabic.ttf-e3dcbe0c4bc0f3f609a01ac9b0b2d1d4.fontdata"]
 
 
 [params]
 [params]
 
 
 Rendering=null
 Rendering=null
 antialiasing=1
 antialiasing=1
 generate_mipmaps=false
 generate_mipmaps=false
+disable_embedded_bitmaps=true
 multichannel_signed_distance_field=false
 multichannel_signed_distance_field=false
 msdf_pixel_range=8
 msdf_pixel_range=8
 msdf_size=48
 msdf_size=48

+ 0 - 0
gui/translation/font/DroidSansFallback.ttf → gui/translation/fonts/DroidSansFallback.ttf


+ 5 - 4
gui/translation/font/DroidSansFallback.ttf.import → gui/translation/fonts/DroidSansFallback.ttf.import

@@ -2,19 +2,20 @@
 
 
 importer="font_data_dynamic"
 importer="font_data_dynamic"
 type="FontFile"
 type="FontFile"
-uid="uid://xesv5idkrqcd"
-path="res://.godot/imported/DroidSansFallback.ttf-9bc560676e9de93a3474250e8f345fde.fontdata"
+uid="uid://cdrxhlo8nqckh"
+path="res://.godot/imported/DroidSansFallback.ttf-fefd6276707493f1293e2a65efe0de0d.fontdata"
 
 
 [deps]
 [deps]
 
 
-source_file="res://font/DroidSansFallback.ttf"
-dest_files=["res://.godot/imported/DroidSansFallback.ttf-9bc560676e9de93a3474250e8f345fde.fontdata"]
+source_file="res://fonts/DroidSansFallback.ttf"
+dest_files=["res://.godot/imported/DroidSansFallback.ttf-fefd6276707493f1293e2a65efe0de0d.fontdata"]
 
 
 [params]
 [params]
 
 
 Rendering=null
 Rendering=null
 antialiasing=1
 antialiasing=1
 generate_mipmaps=false
 generate_mipmaps=false
+disable_embedded_bitmaps=true
 multichannel_signed_distance_field=false
 multichannel_signed_distance_field=false
 msdf_pixel_range=8
 msdf_pixel_range=8
 msdf_size=48
 msdf_size=48

+ 0 - 0
gui/translation/font/DroidSansHebrew.ttf → gui/translation/fonts/DroidSansHebrew.ttf


+ 5 - 4
gui/translation/font/DroidSansHebrew.ttf.import → gui/translation/fonts/DroidSansHebrew.ttf.import

@@ -2,19 +2,20 @@
 
 
 importer="font_data_dynamic"
 importer="font_data_dynamic"
 type="FontFile"
 type="FontFile"
-uid="uid://cft2167j0ba27"
-path="res://.godot/imported/DroidSansHebrew.ttf-2fc88dbe58ef638a09561323f2a293d1.fontdata"
+uid="uid://7bhkit5l8dka"
+path="res://.godot/imported/DroidSansHebrew.ttf-12677dba89ba8356d90dbb4569825058.fontdata"
 
 
 [deps]
 [deps]
 
 
-source_file="res://font/DroidSansHebrew.ttf"
-dest_files=["res://.godot/imported/DroidSansHebrew.ttf-2fc88dbe58ef638a09561323f2a293d1.fontdata"]
+source_file="res://fonts/DroidSansHebrew.ttf"
+dest_files=["res://.godot/imported/DroidSansHebrew.ttf-12677dba89ba8356d90dbb4569825058.fontdata"]
 
 
 [params]
 [params]
 
 
 Rendering=null
 Rendering=null
 antialiasing=1
 antialiasing=1
 generate_mipmaps=false
 generate_mipmaps=false
+disable_embedded_bitmaps=true
 multichannel_signed_distance_field=false
 multichannel_signed_distance_field=false
 msdf_pixel_range=8
 msdf_pixel_range=8
 msdf_size=48
 msdf_size=48

+ 0 - 0
gui/translation/font/DroidSansJapanese.ttf → gui/translation/fonts/DroidSansJapanese.ttf


+ 5 - 4
gui/translation/font/DroidSansJapanese.ttf.import → gui/translation/fonts/DroidSansJapanese.ttf.import

@@ -2,19 +2,20 @@
 
 
 importer="font_data_dynamic"
 importer="font_data_dynamic"
 type="FontFile"
 type="FontFile"
-uid="uid://rdmplfeo1mfc"
-path="res://.godot/imported/DroidSansJapanese.ttf-de3fc871b57fb078f93cf2bf5d96545a.fontdata"
+uid="uid://b74c6j1be4nyv"
+path="res://.godot/imported/DroidSansJapanese.ttf-70e19a56601aacaaf5d6d308c2567f75.fontdata"
 
 
 [deps]
 [deps]
 
 
-source_file="res://font/DroidSansJapanese.ttf"
-dest_files=["res://.godot/imported/DroidSansJapanese.ttf-de3fc871b57fb078f93cf2bf5d96545a.fontdata"]
+source_file="res://fonts/DroidSansJapanese.ttf"
+dest_files=["res://.godot/imported/DroidSansJapanese.ttf-70e19a56601aacaaf5d6d308c2567f75.fontdata"]
 
 
 [params]
 [params]
 
 
 Rendering=null
 Rendering=null
 antialiasing=1
 antialiasing=1
 generate_mipmaps=false
 generate_mipmaps=false
+disable_embedded_bitmaps=true
 multichannel_signed_distance_field=false
 multichannel_signed_distance_field=false
 msdf_pixel_range=8
 msdf_pixel_range=8
 msdf_size=48
 msdf_size=48

+ 0 - 0
gui/translation/font/DroidSansThai.ttf → gui/translation/fonts/DroidSansThai.ttf


+ 5 - 4
gui/translation/font/DroidSansThai.ttf.import → gui/translation/fonts/DroidSansThai.ttf.import

@@ -2,19 +2,20 @@
 
 
 importer="font_data_dynamic"
 importer="font_data_dynamic"
 type="FontFile"
 type="FontFile"
-uid="uid://ctmwkt7kh6cst"
-path="res://.godot/imported/DroidSansThai.ttf-91e10bcf58a298496a7fd92e1d4cd8c4.fontdata"
+uid="uid://t73gcvmo33on"
+path="res://.godot/imported/DroidSansThai.ttf-136cea21d69e1da7eb0a603f8d91fa3a.fontdata"
 
 
 [deps]
 [deps]
 
 
-source_file="res://font/DroidSansThai.ttf"
-dest_files=["res://.godot/imported/DroidSansThai.ttf-91e10bcf58a298496a7fd92e1d4cd8c4.fontdata"]
+source_file="res://fonts/DroidSansThai.ttf"
+dest_files=["res://.godot/imported/DroidSansThai.ttf-136cea21d69e1da7eb0a603f8d91fa3a.fontdata"]
 
 
 [params]
 [params]
 
 
 Rendering=null
 Rendering=null
 antialiasing=1
 antialiasing=1
 generate_mipmaps=false
 generate_mipmaps=false
+disable_embedded_bitmaps=true
 multichannel_signed_distance_field=false
 multichannel_signed_distance_field=false
 msdf_pixel_range=8
 msdf_pixel_range=8
 msdf_size=48
 msdf_size=48

+ 1 - 1
gui/translation/LICENSE.DroidSans.txt → gui/translation/fonts/LICENSE.DroidSans.txt

@@ -4,7 +4,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at
 You may obtain a copy of the License at
 
 
-     http://www.apache.org/licenses/LICENSE-2.0
+	 http://www.apache.org/licenses/LICENSE-2.0
 
 
 Unless required by applicable law or agreed to in writing, software
 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 distributed under the License is distributed on an "AS IS" BASIS,

+ 33 - 0
gui/translation/fonts/droid_sans.tres

@@ -0,0 +1,33 @@
+[gd_resource type="FontFile" load_steps=7 format=3 uid="uid://b0887xnwnkgju"]
+
+[ext_resource type="FontFile" uid="uid://b6jt1itr5jreh" path="res://fonts/DroidSansArabic.ttf" id="1"]
+[ext_resource type="FontFile" uid="uid://cdrxhlo8nqckh" path="res://fonts/DroidSansFallback.ttf" id="2"]
+[ext_resource type="FontFile" uid="uid://7bhkit5l8dka" path="res://fonts/DroidSansHebrew.ttf" id="3"]
+[ext_resource type="FontFile" uid="uid://b74c6j1be4nyv" path="res://fonts/DroidSansJapanese.ttf" id="4"]
+[ext_resource type="FontFile" uid="uid://t73gcvmo33on" path="res://fonts/DroidSansThai.ttf" id="5"]
+[ext_resource type="FontFile" uid="uid://qaejxgrojp2d" path="res://fonts/DroidSans.ttf" id="6"]
+
+[resource]
+fallbacks = Array[Font]([ExtResource("6"), ExtResource("1"), ExtResource("2"), ExtResource("3"), ExtResource("4"), ExtResource("5")])
+face_index = null
+embolden = null
+transform = null
+cache/0/16/0/ascent = 0.0
+cache/0/16/0/descent = 0.0
+cache/0/16/0/underline_position = 0.0
+cache/0/16/0/underline_thickness = 0.0
+cache/0/16/0/scale = 1.0
+cache/0/16/0/glyphs/0/advance = Vector2(0, 0)
+cache/0/16/0/glyphs/0/offset = Vector2(0, 0)
+cache/0/16/0/glyphs/0/size = Vector2(0, 0)
+cache/0/16/0/glyphs/0/uv_rect = Rect2(0, 0, 0, 0)
+cache/0/16/0/glyphs/0/texture_idx = -1
+cache/0/16/0/kerning_overrides/16/0 = Vector2(0, 0)
+cache/0/16/0/kerning_overrides/50/0 = Vector2(0, 0)
+cache/0/50/0/ascent = 0.0
+cache/0/50/0/descent = 0.0
+cache/0/50/0/underline_position = 0.0
+cache/0/50/0/underline_thickness = 0.0
+cache/0/50/0/scale = 1.0
+cache/0/50/0/kerning_overrides/16/0 = Vector2(0, 0)
+cache/0/50/0/kerning_overrides/50/0 = Vector2(0, 0)

+ 0 - 24
gui/translation/hello_en.wav.import

@@ -1,24 +0,0 @@
-[remap]
-
-importer="wav"
-type="AudioStreamWAV"
-uid="uid://d3e12qtu6rlb6"
-path="res://.godot/imported/hello_en.wav-27ed59f2d75c1ba813ab0abd069b6758.sample"
-
-[deps]
-
-source_file="res://hello_en.wav"
-dest_files=["res://.godot/imported/hello_en.wav-27ed59f2d75c1ba813ab0abd069b6758.sample"]
-
-[params]
-
-force/8_bit=false
-force/mono=false
-force/max_rate=false
-force/max_rate_hz=44100
-edit/trim=true
-edit/normalize=true
-edit/loop_mode=0
-edit/loop_begin=0
-edit/loop_end=-1
-compress/mode=0

+ 0 - 24
gui/translation/hello_es.wav.import

@@ -1,24 +0,0 @@
-[remap]
-
-importer="wav"
-type="AudioStreamWAV"
-uid="uid://s18obcimx61r"
-path="res://.godot/imported/hello_es.wav-64fe245556f8642a1881ae257bd123f2.sample"
-
-[deps]
-
-source_file="res://hello_es.wav"
-dest_files=["res://.godot/imported/hello_es.wav-64fe245556f8642a1881ae257bd123f2.sample"]
-
-[params]
-
-force/8_bit=false
-force/mono=false
-force/max_rate=false
-force/max_rate_hz=44100
-edit/trim=true
-edit/normalize=true
-edit/loop_mode=0
-edit/loop_begin=0
-edit/loop_end=-1
-compress/mode=0

+ 0 - 24
gui/translation/hello_jp.wav.import

@@ -1,24 +0,0 @@
-[remap]
-
-importer="wav"
-type="AudioStreamWAV"
-uid="uid://7fh3dentieog"
-path="res://.godot/imported/hello_jp.wav-c31fbd7870b4b969789cb01f208809ac.sample"
-
-[deps]
-
-source_file="res://hello_jp.wav"
-dest_files=["res://.godot/imported/hello_jp.wav-c31fbd7870b4b969789cb01f208809ac.sample"]
-
-[params]
-
-force/8_bit=false
-force/mono=false
-force/max_rate=false
-force/max_rate_hz=44100
-edit/trim=true
-edit/normalize=true
-edit/loop_mode=0
-edit/loop_begin=0
-edit/loop_end=-1
-compress/mode=0

BIN
gui/translation/icon.webp


+ 1 - 1
gui/translation/icon.webp.import

@@ -2,7 +2,7 @@
 
 
 importer="texture"
 importer="texture"
 type="CompressedTexture2D"
 type="CompressedTexture2D"
-uid="uid://brwp8bimc75uu"
+uid="uid://csnnfel8tal41"
 path="res://.godot/imported/icon.webp-e94f9a68b0f625a567a797079e4d325f.ctex"
 path="res://.godot/imported/icon.webp-e94f9a68b0f625a567a797079e4d325f.ctex"
 metadata={
 metadata={
 "vram_texture": false
 "vram_texture": false

BIN
gui/translation/images/flag_japan.webp


+ 4 - 4
gui/translation/speaker.png.import → gui/translation/images/flag_japan.webp.import

@@ -2,16 +2,16 @@
 
 
 importer="texture"
 importer="texture"
 type="CompressedTexture2D"
 type="CompressedTexture2D"
-uid="uid://bbdxdamxifokx"
-path="res://.godot/imported/speaker.png-045bf6684b83b55b088824f14e175d16.ctex"
+uid="uid://b5mub20y1npox"
+path="res://.godot/imported/flag_japan.webp-45f78f2bd7470509154ff093f6e7ec81.ctex"
 metadata={
 metadata={
 "vram_texture": false
 "vram_texture": false
 }
 }
 
 
 [deps]
 [deps]
 
 
-source_file="res://speaker.png"
-dest_files=["res://.godot/imported/speaker.png-045bf6684b83b55b088824f14e175d16.ctex"]
+source_file="res://images/flag_japan.webp"
+dest_files=["res://.godot/imported/flag_japan.webp-45f78f2bd7470509154ff093f6e7ec81.ctex"]
 
 
 [params]
 [params]
 
 

BIN
gui/translation/images/flag_russia.webp


+ 34 - 0
gui/translation/images/flag_russia.webp.import

@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://leegvlwf2hrn"
+path="res://.godot/imported/flag_russia.webp-db8c7f4fab536218d1b7b7c4b6c2d411.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://images/flag_russia.webp"
+dest_files=["res://.godot/imported/flag_russia.webp-db8c7f4fab536218d1b7b7c4b6c2d411.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1

BIN
gui/translation/images/flag_spain.webp


+ 4 - 4
gui/translation/flag_spain.png.import → gui/translation/images/flag_spain.webp.import

@@ -2,16 +2,16 @@
 
 
 importer="texture"
 importer="texture"
 type="CompressedTexture2D"
 type="CompressedTexture2D"
-uid="uid://dsh7m5tl07jml"
-path="res://.godot/imported/flag_spain.png-fd2012b4e19487cfc4923df0c268553f.ctex"
+uid="uid://c0wh2enemiaay"
+path="res://.godot/imported/flag_spain.webp-f240dac0b8ec15b0721be1d39e3a9520.ctex"
 metadata={
 metadata={
 "vram_texture": false
 "vram_texture": false
 }
 }
 
 
 [deps]
 [deps]
 
 
-source_file="res://flag_spain.png"
-dest_files=["res://.godot/imported/flag_spain.png-fd2012b4e19487cfc4923df0c268553f.ctex"]
+source_file="res://images/flag_spain.webp"
+dest_files=["res://.godot/imported/flag_spain.webp-f240dac0b8ec15b0721be1d39e3a9520.ctex"]
 
 
 [params]
 [params]
 
 

BIN
gui/translation/images/flag_uk.webp


+ 4 - 4
gui/translation/flag_uk.png.import → gui/translation/images/flag_uk.webp.import

@@ -2,16 +2,16 @@
 
 
 importer="texture"
 importer="texture"
 type="CompressedTexture2D"
 type="CompressedTexture2D"
-uid="uid://cxbco5txqcf40"
-path="res://.godot/imported/flag_uk.png-eb8a2b26ac36f4d0cf0d7345e577ec2c.ctex"
+uid="uid://cy06u7558clgu"
+path="res://.godot/imported/flag_uk.webp-bb99f24470917ddd226648d0bc13ea65.ctex"
 metadata={
 metadata={
 "vram_texture": false
 "vram_texture": false
 }
 }
 
 
 [deps]
 [deps]
 
 
-source_file="res://flag_uk.png"
-dest_files=["res://.godot/imported/flag_uk.png-eb8a2b26ac36f4d0cf0d7345e577ec2c.ctex"]
+source_file="res://images/flag_uk.webp"
+dest_files=["res://.godot/imported/flag_uk.webp-bb99f24470917ddd226648d0bc13ea65.ctex"]
 
 
 [params]
 [params]
 
 

BIN
gui/translation/images/speaker.webp


+ 4 - 4
gui/translation/flag_japan.png.import → gui/translation/images/speaker.webp.import

@@ -2,16 +2,16 @@
 
 
 importer="texture"
 importer="texture"
 type="CompressedTexture2D"
 type="CompressedTexture2D"
-uid="uid://nokaqfa1grg5"
-path="res://.godot/imported/flag_japan.png-e7284e6af3de26ab9c66cac9c4062038.ctex"
+uid="uid://bk44e7bkr4w4l"
+path="res://.godot/imported/speaker.webp-61e01feddc14193cb3c662b9561152bf.ctex"
 metadata={
 metadata={
 "vram_texture": false
 "vram_texture": false
 }
 }
 
 
 [deps]
 [deps]
 
 
-source_file="res://flag_japan.png"
-dest_files=["res://.godot/imported/flag_japan.png-e7284e6af3de26ab9c66cac9c4062038.ctex"]
+source_file="res://images/speaker.webp"
+dest_files=["res://.godot/imported/speaker.webp-61e01feddc14193cb3c662b9561152bf.ctex"]
 
 
 [params]
 [params]
 
 

+ 9 - 8
gui/translation/project.godot

@@ -14,7 +14,7 @@ config/name="Translation Demo"
 config/description="A demo showing how Godot seamlessly enables
 config/description="A demo showing how Godot seamlessly enables
 the use of localized resources and texts."
 the use of localized resources and texts."
 config/tags=PackedStringArray("demo", "internationalization", "official")
 config/tags=PackedStringArray("demo", "internationalization", "official")
-run/main_scene="res://translation_demo.tscn"
+run/main_scene="res://translation_demo_csv.tscn"
 config/features=PackedStringArray("4.2")
 config/features=PackedStringArray("4.2")
 config/icon="res://icon.webp"
 config/icon="res://icon.webp"
 
 
@@ -26,21 +26,22 @@ window/stretch/aspect="expand"
 [internationalization]
 [internationalization]
 
 
 locale/translation_remaps={
 locale/translation_remaps={
-"res://flag_uk.png": PackedStringArray("res://flag_spain.png:es", "res://flag_japan.png:ja"),
-"res://hello_en.wav": PackedStringArray("res://hello_es.wav:es", "res://hello_jp.wav:ja")
+"res://audio/hello_en.wav": PackedStringArray("res://audio/hello_es.wav:es", "res://audio/hello_jp.wav:ja", "res://audio/hello_ru.wav:ru"),
+"res://images/flag_uk.webp": PackedStringArray("res://images/flag_japan.webp:ja", "res://images/flag_russia.webp:ru", "res://images/flag_spain.webp:es")
 }
 }
-locale/translations=PackedStringArray("res://text.en.translation", "res://text.es.translation", "res://text.ja.translation")
+locale/translations=PackedStringArray("res://translations/csv/text.en.translation", "res://translations/csv/text.es.translation", "res://translations/csv/text.ja.translation", "res://translations/csv/text.ru.translation", "res://translations/po/translation_demo_es.po", "res://translations/po/translation_demo_ja.po")
+locale/translations_pot_files=PackedStringArray("res://translation_demo_po.tscn")
 locale/locale_filter_mode=0
 locale/locale_filter_mode=0
 
 
 [locale]
 [locale]
 
 
+translations=PackedStringArray("res://TranslationFiles/CSV/text.en.translation", "res://TranslationFiles/CSV/text.es.translation", "res://TranslationFiles/CSV/text.ja.translation", "res://TranslationFiles/CSV/text.ru.translation", "res://TranslationFiles/PO/translation_demo_es.po", "res://TranslationFiles/PO/translation_demo_ja.po")
 translation_remaps={
 translation_remaps={
-"res://flag_uk.png": ["res://flag_spain.png:es", "res://flag_japan.png:ja"],
-"res://hello_en.wav": PackedStringArray("res://hello_es.wav:es", "res://hello_jp.wav:ja")
+"res://Audio/hello_en.wav": PackedStringArray("res://Audio/hello_es.wav:es", "res://Audio/hello_jp.wav:ja", "res://Audio/hello_ru.wav:ru"),
+"res://Images/flag_uk.png": PackedStringArray("res://Images/flag_spain.png:es", "res://Images/flag_japan.png:ja", "res://Images/flag_russia.png:ru")
 }
 }
-translations=PackedStringArray("res://text.en.translation", "res://text.es.translation", "res://text.ja.translation")
+translations_pot_files=PackedStringArray("res://translation_po.gd", "res://translation_demo_po.tscn")
 
 
 [rendering]
 [rendering]
 
 
 renderer/rendering_method="gl_compatibility"
 renderer/rendering_method="gl_compatibility"
-renderer/rendering_method.mobile="gl_compatibility"

BIN
gui/translation/screenshots/translation.png


BIN
gui/translation/screenshots/translation.webp


BIN
gui/translation/speaker.png


+ 0 - 4
gui/translation/text.csv

@@ -1,4 +0,0 @@
-KEYS,en,es,ja
-KEY_HELLO,Hello!,Hola!,こんにちは
-KEY_PUSH,Push Me!,Aprétame!,押す
-KEY_TEXT,This is translated!,¡Esto está traducido!,これが翻訳されていました!

+ 0 - 17
gui/translation/text.csv.import

@@ -1,17 +0,0 @@
-[remap]
-
-importer="csv_translation"
-type="Translation"
-uid="uid://dyudr7sc6obqu"
-
-[deps]
-
-files=["res://text.en.translation", "res://text.es.translation", "res://text.ja.translation"]
-
-source_file="res://text.csv"
-dest_files=["res://text.en.translation", "res://text.es.translation", "res://text.ja.translation"]
-
-[params]
-
-compress=true
-delimiter=0

+ 47 - 0
gui/translation/translation_csv.gd

@@ -0,0 +1,47 @@
+# For more information on localization,
+# search Godot's online documentation "Internationalization", or visit
+# https://docs.godotengine.org/en/latest/tutorials/i18n/index.html
+
+extends Panel
+
+func _ready() -> void:
+	_print_intro()
+
+
+func _on_english_pressed() -> void:
+	TranslationServer.set_locale("en")
+	_print_intro()
+
+
+func _on_spanish_pressed() -> void:
+	TranslationServer.set_locale("es")
+	_print_intro()
+
+
+func _on_japanese_pressed() -> void:
+	TranslationServer.set_locale("ja")
+	_print_intro()
+
+
+func _on_russian_pressed() -> void:
+	TranslationServer.set_locale("ru")
+	_print_intro()
+
+
+func _on_play_audio_pressed() -> void:
+	$Audio.play()
+
+
+func _print_intro() -> void:
+	print_rich("\n[b]Language:[/b] %s (%s)" % [TranslationServer.get_locale_name(TranslationServer.get_locale()), TranslationServer.get_locale()])
+
+	# In CSV translation, use the appropriate key in the Object.tr() function to fetch
+	# the corresponding translation.
+	# This is the same for scene nodes containing user-facing texts to be translated.
+	print(tr("KEY_INTRO"))
+
+	# CSV does not support plural translations. If you need pluralization, you must use PO instead.
+
+
+func _on_go_to_po_translation_demo_pressed() -> void:
+	get_tree().change_scene_to_packed(load("res://translation_demo_po.tscn"))

+ 0 - 32
gui/translation/translation_demo.gd

@@ -1,32 +0,0 @@
-extends Control
-
-func _ready() -> void:
-	_set_text_in_label()
-
-
-func _on_english_pressed():
-	TranslationServer.set_locale("en")
-
-
-func _on_spanish_pressed():
-	TranslationServer.set_locale("es")
-
-
-func _on_japanese_pressed():
-	TranslationServer.set_locale("ja")
-
-
-func _on_play_pressed():
-	$Audio.play()
-
-
-func _set_text_in_label():
-	# Use tr(translation_key) to get the desired string in the correct language.
-	var message := "This text is being translated through script: \n"
-	message += tr("KEY_TEXT")
-	$TextLabel.text = message
-
-
-func _notification(what):
-	if what == NOTIFICATION_TRANSLATION_CHANGED:
-		_set_text_in_label()

+ 0 - 131
gui/translation/translation_demo.tscn

@@ -1,131 +0,0 @@
-[gd_scene load_steps=7 format=3 uid="uid://7bhrbgdbrped"]
-
-[ext_resource type="Script" path="res://translation_demo.gd" id="1"]
-[ext_resource type="FontVariation" uid="uid://duo4ycm3e6mrb" path="res://font/droid_sans.tres" id="2_fnagj"]
-[ext_resource type="Texture2D" uid="uid://bbdxdamxifokx" path="res://speaker.png" id="3"]
-[ext_resource type="Texture2D" uid="uid://cxbco5txqcf40" path="res://flag_uk.png" id="4"]
-[ext_resource type="AudioStream" uid="uid://d3e12qtu6rlb6" path="res://hello_en.wav" id="5"]
-
-[sub_resource type="Theme" id="Theme_2nqf7"]
-default_font = ExtResource("2_fnagj")
-default_font_size = 0
-
-[node name="TranslationDemo" type="Control"]
-layout_mode = 3
-anchors_preset = 8
-anchor_left = 0.5
-anchor_top = 0.5
-anchor_right = 0.5
-anchor_bottom = 0.5
-offset_left = -512.0
-offset_top = -300.0
-offset_right = 512.0
-offset_bottom = 300.0
-size_flags_horizontal = 2
-size_flags_vertical = 2
-theme = SubResource("Theme_2nqf7")
-script = ExtResource("1")
-
-[node name="English" type="Button" parent="."]
-layout_mode = 0
-offset_left = 32.0
-offset_top = 64.0
-offset_right = 192.0
-offset_bottom = 88.0
-size_flags_horizontal = 2
-size_flags_vertical = 2
-text = "Use English"
-
-[node name="Spanish" type="Button" parent="."]
-layout_mode = 0
-offset_left = 32.0
-offset_top = 112.0
-offset_right = 192.0
-offset_bottom = 136.0
-size_flags_horizontal = 2
-size_flags_vertical = 2
-text = "Use Spanish"
-
-[node name="Japanese" type="Button" parent="."]
-layout_mode = 0
-offset_left = 32.0
-offset_top = 160.0
-offset_right = 192.0
-offset_bottom = 184.0
-size_flags_horizontal = 2
-size_flags_vertical = 2
-text = "Use Japanese"
-
-[node name="Description" type="Label" parent="."]
-layout_mode = 0
-offset_left = 243.0
-offset_top = 42.0
-offset_right = 804.0
-offset_bottom = 312.0
-size_flags_horizontal = 2
-size_flags_vertical = 0
-text = "This is a demo of how a game can be internationalized.
-Translations are created in a CSV file and then imported into Godot.
-
-Using a TTF/OTF font with CJK is required for this demo to run. One is provided
-in the font/ folder that you can use for your games.
-
-Godot allows internationalized text to change automatically when the locale is
-modified. Resources can also be set internationalized alternatives and replaced
-automatically on locale change."
-
-[node name="HSeparator" type="HSeparator" parent="."]
-layout_mode = 0
-offset_left = 33.0
-offset_top = 330.0
-offset_right = 1001.0
-offset_bottom = 370.0
-
-[node name="HelloText" type="Label" parent="."]
-layout_mode = 0
-offset_left = 246.0
-offset_top = 381.0
-offset_right = 324.0
-offset_bottom = 400.0
-size_flags_vertical = 0
-text = "KEY_HELLO"
-
-[node name="PlayAudio" type="Button" parent="."]
-layout_mode = 0
-offset_left = 243.0
-offset_top = 442.0
-offset_right = 475.0
-offset_bottom = 467.0
-text = "KEY_PUSH"
-icon = ExtResource("3")
-
-[node name="Flag" type="TextureRect" parent="."]
-layout_mode = 0
-offset_left = 85.0
-offset_top = 382.0
-offset_right = 213.0
-offset_bottom = 467.0
-texture = ExtResource("4")
-
-[node name="Audio" type="AudioStreamPlayer" parent="."]
-stream = ExtResource("5")
-
-[node name="TextLabel" type="Label" parent="."]
-layout_mode = 0
-anchor_left = 0.5
-anchor_top = 0.5
-anchor_right = 0.5
-anchor_bottom = 0.5
-offset_left = 21.0
-offset_top = 80.0
-offset_right = 487.0
-offset_bottom = 255.0
-grow_horizontal = 2
-grow_vertical = 2
-text = "This text is being translated through script:
-"
-
-[connection signal="pressed" from="English" to="." method="_on_english_pressed"]
-[connection signal="pressed" from="Spanish" to="." method="_on_spanish_pressed"]
-[connection signal="pressed" from="Japanese" to="." method="_on_japanese_pressed"]
-[connection signal="pressed" from="PlayAudio" to="." method="_on_play_pressed"]

+ 144 - 0
gui/translation/translation_demo_csv.tscn

@@ -0,0 +1,144 @@
+[gd_scene load_steps=6 format=3 uid="uid://du3apufm66p3x"]
+
+[ext_resource type="Script" path="res://translation_csv.gd" id="1_o1a7r"]
+[ext_resource type="Texture2D" uid="uid://bk44e7bkr4w4l" path="res://images/speaker.webp" id="3_d0i3f"]
+[ext_resource type="FontFile" uid="uid://b0887xnwnkgju" path="res://fonts/droid_sans.tres" id="3_wf1ar"]
+[ext_resource type="Texture2D" uid="uid://cy06u7558clgu" path="res://images/flag_uk.webp" id="4_xn1dg"]
+[ext_resource type="AudioStream" uid="uid://ciept8j0x21to" path="res://audio/hello_en.wav" id="6_a303u"]
+
+[node name="TranslationDemoCSV" type="Panel"]
+anchors_preset = 8
+anchor_left = 0.5
+anchor_top = 0.5
+anchor_right = 0.5
+anchor_bottom = 0.5
+offset_left = -512.0
+offset_top = -300.0
+offset_right = 512.0
+offset_bottom = 300.0
+size_flags_horizontal = 2
+size_flags_vertical = 2
+script = ExtResource("1_o1a7r")
+
+[node name="Title" type="Label" parent="."]
+layout_mode = 0
+offset_left = 422.0
+offset_top = 12.0
+offset_right = 602.0
+offset_bottom = 49.0
+theme_override_colors/font_color = Color(0.682353, 1, 0.65098, 1)
+theme_override_font_sizes/font_size = 24
+text = "CSV Example"
+
+[node name="English" type="Button" parent="."]
+layout_mode = 0
+offset_left = 32.0
+offset_top = 81.9594
+offset_right = 192.0
+offset_bottom = 105.959
+size_flags_horizontal = 2
+size_flags_vertical = 2
+text = "Use English"
+
+[node name="Spanish" type="Button" parent="."]
+layout_mode = 0
+offset_left = 32.0
+offset_top = 129.959
+offset_right = 192.0
+offset_bottom = 153.959
+size_flags_horizontal = 2
+size_flags_vertical = 2
+text = "Use Spanish"
+
+[node name="Japanese" type="Button" parent="."]
+layout_mode = 0
+offset_left = 32.0
+offset_top = 177.959
+offset_right = 192.0
+offset_bottom = 201.959
+size_flags_horizontal = 2
+size_flags_vertical = 2
+text = "Use Japanese"
+
+[node name="Russian" type="Button" parent="."]
+layout_mode = 0
+offset_left = 32.0
+offset_top = 225.959
+offset_right = 192.0
+offset_bottom = 249.959
+size_flags_horizontal = 2
+size_flags_vertical = 2
+text = "Use Russian"
+
+[node name="Description" type="Label" parent="."]
+layout_mode = 0
+offset_left = 243.0
+offset_top = 59.9594
+offset_right = 804.0
+offset_bottom = 329.959
+size_flags_horizontal = 2
+size_flags_vertical = 0
+text = "This is a demo of how a project can be internationalized.
+Translations are created in a CSV file and then imported into Godot.
+
+For correct display, the font used must contain the glyphs required by the target language.
+See the \"fonts\" folder for some fonts that you can use in your project.
+Godot can load system fonts as a fallback, but this is not supported on all platforms
+and the different visual design of system fonts can create inconsistencies.
+
+Godot allows internationalized text to change automatically when the locale is
+modified. Resources can also be set to internationalized alternatives and replaced
+automatically on locale change. This process is known as remapping."
+
+[node name="HSeparator" type="HSeparator" parent="."]
+layout_mode = 0
+offset_left = 33.0
+offset_top = 354.0
+offset_right = 1001.0
+offset_bottom = 394.0
+
+[node name="HelloText" type="Label" parent="."]
+layout_mode = 0
+offset_left = 246.0
+offset_top = 405.0
+offset_right = 326.0
+offset_bottom = 429.0
+size_flags_vertical = 0
+theme_override_fonts/font = ExtResource("3_wf1ar")
+text = "KEY_HELLO"
+
+[node name="PlayAudio" type="Button" parent="."]
+layout_mode = 0
+offset_left = 243.0
+offset_top = 466.0
+offset_right = 475.0
+offset_bottom = 498.0
+theme_override_fonts/font = ExtResource("3_wf1ar")
+text = "KEY_PUSH"
+icon = ExtResource("3_d0i3f")
+
+[node name="Flag" type="TextureRect" parent="."]
+layout_mode = 0
+offset_left = 85.0
+offset_top = 406.0
+offset_right = 213.0
+offset_bottom = 491.0
+texture = ExtResource("4_xn1dg")
+
+[node name="Audio" type="AudioStreamPlayer2D" parent="."]
+stream = ExtResource("6_a303u")
+
+[node name="GoToPOTranslationDemo" type="Button" parent="."]
+layout_mode = 0
+offset_left = 761.0
+offset_top = 545.0
+offset_right = 1000.0
+offset_bottom = 576.0
+text = "Go to PO Translation Demo"
+
+[connection signal="pressed" from="English" to="." method="_on_english_pressed"]
+[connection signal="pressed" from="Spanish" to="." method="_on_spanish_pressed"]
+[connection signal="pressed" from="Japanese" to="." method="_on_japanese_pressed"]
+[connection signal="pressed" from="Russian" to="." method="_on_russian_pressed"]
+[connection signal="pressed" from="PlayAudio" to="." method="_on_play_audio_pressed"]
+[connection signal="pressed" from="GoToPOTranslationDemo" to="." method="_on_go_to_po_translation_demo_pressed"]

+ 130 - 0
gui/translation/translation_demo_po.tscn

@@ -0,0 +1,130 @@
+[gd_scene load_steps=6 format=3 uid="uid://u6cnwv1b1mhl"]
+
+[ext_resource type="Script" path="res://translation_po.gd" id="1_u1syg"]
+[ext_resource type="FontFile" uid="uid://b0887xnwnkgju" path="res://fonts/droid_sans.tres" id="3_0g48e"]
+[ext_resource type="Texture2D" uid="uid://bk44e7bkr4w4l" path="res://images/speaker.webp" id="3_x3031"]
+[ext_resource type="Texture2D" uid="uid://cy06u7558clgu" path="res://images/flag_uk.webp" id="4_2she1"]
+[ext_resource type="AudioStream" uid="uid://ciept8j0x21to" path="res://audio/hello_en.wav" id="6_v8u3c"]
+
+[node name="TranslationDemoPO" type="Panel"]
+anchors_preset = 8
+anchor_left = 0.5
+anchor_top = 0.5
+anchor_right = 0.5
+anchor_bottom = 0.5
+offset_left = -512.0
+offset_top = -300.0
+offset_right = 512.0
+offset_bottom = 300.0
+size_flags_horizontal = 2
+size_flags_vertical = 2
+script = ExtResource("1_u1syg")
+
+[node name="Title" type="Label" parent="."]
+layout_mode = 0
+offset_left = 422.0
+offset_top = 12.0
+offset_right = 602.0
+offset_bottom = 50.0
+theme_override_colors/font_color = Color(0.788235, 0.54902, 0.933333, 1)
+theme_override_font_sizes/font_size = 24
+text = "PO Example"
+
+[node name="English" type="Button" parent="."]
+layout_mode = 0
+offset_left = 32.0
+offset_top = 81.592
+offset_right = 192.0
+offset_bottom = 112.592
+size_flags_horizontal = 2
+size_flags_vertical = 2
+text = "Use English"
+
+[node name="Spanish" type="Button" parent="."]
+layout_mode = 0
+offset_left = 32.0
+offset_top = 129.592
+offset_right = 192.0
+offset_bottom = 160.592
+size_flags_horizontal = 2
+size_flags_vertical = 2
+text = "Use Spanish"
+
+[node name="Japanese" type="Button" parent="."]
+layout_mode = 0
+offset_left = 32.0
+offset_top = 177.592
+offset_right = 192.0
+offset_bottom = 208.592
+size_flags_horizontal = 2
+size_flags_vertical = 2
+text = "Use Japanese"
+
+[node name="Description" type="Label" parent="."]
+layout_mode = 0
+offset_left = 243.0
+offset_top = 64.592
+offset_right = 929.0
+offset_bottom = 334.592
+size_flags_horizontal = 2
+size_flags_vertical = 0
+text = "This second demo showcases localization using gettext (PO/POT) files.
+
+The resouce remapping process is the same with CSV. The in-game text translation
+process is also the same – use keys to fetch the appropriate translation.
+
+The main difference between PO files and CSV files is the way both of them store
+the translated data in their files.  Have a look at the \"translations/po\"
+and \"translations/csv\" folders to see the files involved."
+
+[node name="HSeparator" type="HSeparator" parent="."]
+layout_mode = 0
+offset_left = 33.0
+offset_top = 354.0
+offset_right = 1001.0
+offset_bottom = 394.0
+
+[node name="HelloText" type="Label" parent="."]
+layout_mode = 0
+offset_left = 246.0
+offset_top = 405.0
+offset_right = 325.0
+offset_bottom = 429.0
+size_flags_vertical = 0
+theme_override_fonts/font = ExtResource("3_0g48e")
+text = "Hello!"
+
+[node name="PlayAudio" type="Button" parent="."]
+layout_mode = 0
+offset_left = 243.0
+offset_top = 466.0
+offset_right = 475.0
+offset_bottom = 498.0
+theme_override_fonts/font = ExtResource("3_0g48e")
+text = "Push Me!"
+icon = ExtResource("3_x3031")
+
+[node name="Flag" type="TextureRect" parent="."]
+layout_mode = 0
+offset_left = 85.0
+offset_top = 406.0
+offset_right = 213.0
+offset_bottom = 491.0
+texture = ExtResource("4_2she1")
+
+[node name="Audio" type="AudioStreamPlayer2D" parent="."]
+stream = ExtResource("6_v8u3c")
+
+[node name="GoToCSVTranslationDemo" type="Button" parent="."]
+layout_mode = 0
+offset_left = 761.0
+offset_top = 545.0
+offset_right = 1000.0
+offset_bottom = 576.0
+text = "Go to CSV Translation Demo"
+
+[connection signal="pressed" from="English" to="." method="_on_english_pressed"]
+[connection signal="pressed" from="Spanish" to="." method="_on_spanish_pressed"]
+[connection signal="pressed" from="Japanese" to="." method="_on_japanese_pressed"]
+[connection signal="pressed" from="PlayAudio" to="." method="_on_play_audio_pressed"]
+[connection signal="pressed" from="GoToCSVTranslationDemo" to="." method="_on_go_to_csv_translation_demo_pressed"]

+ 44 - 0
gui/translation/translation_po.gd

@@ -0,0 +1,44 @@
+# For more information on translation using PO files,
+# search Godot's online documentation "Localization using gettext", or visit
+# https://docs.godotengine.org/en/latest/tutorials/i18n/localization_using_gettext.html
+
+extends Panel
+
+func _ready() -> void:
+	_print_intro()
+
+func _on_english_pressed() -> void:
+	TranslationServer.set_locale("en")
+	_print_intro()
+
+
+func _on_spanish_pressed() -> void:
+	TranslationServer.set_locale("es")
+	_print_intro()
+
+
+func _on_japanese_pressed() -> void:
+	TranslationServer.set_locale("ja")
+	_print_intro()
+
+
+func _on_play_audio_pressed() -> void:
+	$Audio.play()
+
+
+func _print_intro() -> void:
+	print_rich("\n[b]Language:[/b] %s (%s)" % [TranslationServer.get_locale_name(TranslationServer.get_locale()), TranslationServer.get_locale()])
+
+	# In PO translation, you would use source string as the 'key' for the Object.tr() function.
+	# This is the same for scene nodes containing user-facing texts to be translated.
+	print(tr("Hello, this is a translation demo project."))
+
+	# PO plural translation example.
+	# The difference with CSV is that you must add the "plural_message" argument, because PO files
+	# expect the data (else undefine behaviour might occur).
+	var days_passed := randi_range(1, 3)
+	print(tr_n("One day ago.", "{days} days ago.", days_passed).format({ days = days_passed }))
+
+
+func _on_go_to_csv_translation_demo_pressed() -> void:
+	get_tree().change_scene_to_packed(load("res://translation_demo_csv.tscn"))

+ 4 - 0
gui/translation/translations/csv/text.csv

@@ -0,0 +1,4 @@
+,en,es,ja,ru
+KEY_HELLO,Hello!,Hola!,こんにちは!,Привет!
+KEY_PUSH,Push Me!,Aprétame!,押す!,Толкни меня!
+KEY_INTRO,"Hello, this is a translation demo project.","Hola, este es un proyecto de demostración de traducción.","こんにちは、これは翻訳デモプロジェクトです.","Здравствуйте, это демонстрационный проект перевода."

+ 17 - 0
gui/translation/translations/csv/text.csv.import

@@ -0,0 +1,17 @@
+[remap]
+
+importer="csv_translation"
+type="Translation"
+uid="uid://ftws6mo13r10"
+
+[deps]
+
+files=["res://translations/csv/text.en.translation", "res://translations/csv/text.es.translation", "res://translations/csv/text.ja.translation", "res://translations/csv/text.ru.translation"]
+
+source_file="res://translations/csv/text.csv"
+dest_files=["res://translations/csv/text.en.translation", "res://translations/csv/text.es.translation", "res://translations/csv/text.ja.translation", "res://translations/csv/text.ru.translation"]
+
+[params]
+
+compress=true
+delimiter=0

+ 56 - 0
gui/translation/translations/po/translation_demo.pot

@@ -0,0 +1,56 @@
+# LANGUAGE translation for Translation Demo for the following files:
+# res://translation_po.gd
+# res://translation_demo_po.tscn
+#
+#
+# FIRST AUTHOR < EMAIL @ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: Translation Demo\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8-bit\n"
+
+#: translation_demo_po.tscn
+msgid "Hello, this is a translation demo project."
+msgstr ""
+
+#: translation_demo_po.tscn
+msgid "One day ago."
+msgid_plural "{days} days ago."
+msgstr[0] ""
+msgstr[1] ""
+
+#: translation_demo_po.tscn
+msgid "Use English"
+msgstr ""
+
+#: translation_demo_po.tscn
+msgid "Use Spanish"
+msgstr ""
+
+#: translation_demo_po.tscn
+msgid "Use Japanese"
+msgstr ""
+
+#: translation_demo_po.tscn
+msgid "This second demo shows translation using PO files. "
+""
+"The resouce remapping process is the same with CSV. The in-game text translation "
+"process is also the same - use keys to fetch the appropriate translation."
+""
+"The main difference between PO files and CSV files is the way both of them store "
+"the translated data in their files.  Have a look at "TranslationFiles/PO" folder "
+"and "TranslationFiles/CSV" folder to see the files involved in translation."
+""
+"To find out more about PO files, search Godot's online documentation "Localization using gettext""
+msgstr ""
+
+#: translation_demo_po.tscn
+msgid "Hello!"
+msgstr ""
+
+#: translation_demo_po.tscn
+msgid "Push Me!"
+msgstr ""

+ 62 - 0
gui/translation/translations/po/translation_demo_es.po

@@ -0,0 +1,62 @@
+# LANGUAGE translation for Translation Demo for the following files:
+# res://translation_po.gd
+# res://translation_demo_po.tscn
+#
+#
+# FIRST AUTHOR < EMAIL @ADDRESS>, YEAR.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Translation Demo\n"
+"POT-Creation-Date: \n"
+"PO-Revision-Date: \n"
+"Last-Translator: \n"
+"Language-Team: \n"
+"Language: es\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: Poedit 2.3.1\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: translation_demo_po.tscn
+msgid "Hello, this is a translation demo project."
+msgstr "Hola, este es un proyecto de demostración de traducción."
+
+#: translation_demo_po.tscn
+msgid "One day ago."
+msgid_plural "{days} days ago."
+msgstr[0] "Hace un dia."
+msgstr[1] "Hach {days} dias."
+
+#: translation_demo_po.tscn
+msgid "Use English"
+msgstr ""
+
+#: translation_demo_po.tscn
+msgid "Use Spanish"
+msgstr ""
+
+#: translation_demo_po.tscn
+msgid "Use Japanese"
+msgstr ""
+
+#: translation_demo_po.tscn
+msgid ""
+"This second demo shows translation using PO files. The resouce remapping "
+"process is the same with CSV. The in-game text translation process is also "
+"the same - use keys to fetch the appropriate translation.The main difference "
+"between PO files and CSV files is the way both of them store the translated "
+"data in their files.  Have a look at \"TranslationFiles/PO\" folder and "
+"\"TranslationFiles/CSV\" folder to see the files involved in translation.To "
+"find out more about PO files, search Godot's online documentation "
+"\"Localization using gettext\""
+msgstr ""
+
+#: translation_demo_po.tscn
+msgid "Hello!"
+msgstr "Hola!"
+
+#: translation_demo_po.tscn
+msgid "Push Me!"
+msgstr "Aprétame!"

+ 61 - 0
gui/translation/translations/po/translation_demo_ja.po

@@ -0,0 +1,61 @@
+# LANGUAGE translation for Translation Demo for the following files:
+# res://translation_po.gd
+# res://translation_demo_po.tscn
+#
+#
+# FIRST AUTHOR < EMAIL @ADDRESS>, YEAR.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Translation Demo\n"
+"POT-Creation-Date: \n"
+"PO-Revision-Date: \n"
+"Last-Translator: \n"
+"Language-Team: \n"
+"Language: ja\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: Poedit 2.3.1\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+
+#: translation_demo_po.tscn
+msgid "Hello, this is a translation demo project."
+msgstr "こんにちは、これは翻訳デモプロジェクトです."
+
+#: translation_demo_po.tscn
+msgid "One day ago."
+msgid_plural "{days} days ago."
+msgstr[0] "{days}日前."
+
+#: translation_demo_po.tscn
+msgid "Use English"
+msgstr ""
+
+#: translation_demo_po.tscn
+msgid "Use Spanish"
+msgstr ""
+
+#: translation_demo_po.tscn
+msgid "Use Japanese"
+msgstr ""
+
+#: translation_demo_po.tscn
+msgid ""
+"This second demo shows translation using PO files. The resouce remapping "
+"process is the same with CSV. The in-game text translation process is also "
+"the same - use keys to fetch the appropriate translation.The main difference "
+"between PO files and CSV files is the way both of them store the translated "
+"data in their files.  Have a look at \"TranslationFiles/PO\" folder and "
+"\"TranslationFiles/CSV\" folder to see the files involved in translation.To "
+"find out more about PO files, search Godot's online documentation "
+"\"Localization using gettext\""
+msgstr ""
+
+#: translation_demo_po.tscn
+msgid "Hello!"
+msgstr "こんにちは!"
+
+#: translation_demo_po.tscn
+msgid "Push Me!"
+msgstr "押す!"