diff --git a/gui/translation/README.md b/gui/translation/README.md index 78af273ebd..3de786a962 100644 --- a/gui/translation/README.md +++ b/gui/translation/README.md @@ -1,14 +1,36 @@ # 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 Renderer: Compatibility -Check out this demo on the asset library: https://godotengine.org/asset-library/asset/134 - ## Screenshots -![Screenshot](screenshots/translation.png) +![Screenshot](screenshots/translation.webp) diff --git a/gui/translation/hello_en.wav b/gui/translation/audio/hello_en.wav similarity index 100% rename from gui/translation/hello_en.wav rename to gui/translation/audio/hello_en.wav diff --git a/gui/translation/audio/hello_en.wav.import b/gui/translation/audio/hello_en.wav.import new file mode 100644 index 0000000000..532d396d59 --- /dev/null +++ b/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 diff --git a/gui/translation/hello_es.wav b/gui/translation/audio/hello_es.wav similarity index 100% rename from gui/translation/hello_es.wav rename to gui/translation/audio/hello_es.wav diff --git a/gui/translation/audio/hello_es.wav.import b/gui/translation/audio/hello_es.wav.import new file mode 100644 index 0000000000..cf7ce7869e --- /dev/null +++ b/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 diff --git a/gui/translation/hello_jp.wav b/gui/translation/audio/hello_jp.wav similarity index 100% rename from gui/translation/hello_jp.wav rename to gui/translation/audio/hello_jp.wav diff --git a/gui/translation/audio/hello_jp.wav.import b/gui/translation/audio/hello_jp.wav.import new file mode 100644 index 0000000000..4f18b6cbcc --- /dev/null +++ b/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 diff --git a/gui/translation/audio/hello_ru.wav b/gui/translation/audio/hello_ru.wav new file mode 100644 index 0000000000..26a9839d86 Binary files /dev/null and b/gui/translation/audio/hello_ru.wav differ diff --git a/gui/translation/audio/hello_ru.wav.import b/gui/translation/audio/hello_ru.wav.import new file mode 100644 index 0000000000..f8a0eb3464 --- /dev/null +++ b/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 diff --git a/gui/translation/flag_japan.png b/gui/translation/flag_japan.png deleted file mode 100644 index 920a44ca41..0000000000 Binary files a/gui/translation/flag_japan.png and /dev/null differ diff --git a/gui/translation/flag_spain.png b/gui/translation/flag_spain.png deleted file mode 100644 index 447acc8823..0000000000 Binary files a/gui/translation/flag_spain.png and /dev/null differ diff --git a/gui/translation/flag_uk.png b/gui/translation/flag_uk.png deleted file mode 100644 index cb96806b8d..0000000000 Binary files a/gui/translation/flag_uk.png and /dev/null differ diff --git a/gui/translation/font/droid_sans.tres b/gui/translation/font/droid_sans.tres deleted file mode 100644 index 37e067b4b6..0000000000 --- a/gui/translation/font/droid_sans.tres +++ /dev/null @@ -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") diff --git a/gui/translation/font/DroidSans.ttf b/gui/translation/fonts/DroidSans.ttf similarity index 100% rename from gui/translation/font/DroidSans.ttf rename to gui/translation/fonts/DroidSans.ttf diff --git a/gui/translation/font/DroidSans.ttf.import b/gui/translation/fonts/DroidSans.ttf.import similarity index 60% rename from gui/translation/font/DroidSans.ttf.import rename to gui/translation/fonts/DroidSans.ttf.import index 667a49e306..1b45a53a9d 100644 --- a/gui/translation/font/DroidSans.ttf.import +++ b/gui/translation/fonts/DroidSans.ttf.import @@ -2,19 +2,20 @@ importer="font_data_dynamic" 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] -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] Rendering=null antialiasing=1 generate_mipmaps=false +disable_embedded_bitmaps=true multichannel_signed_distance_field=false msdf_pixel_range=8 msdf_size=48 diff --git a/gui/translation/font/DroidSansArabic.ttf b/gui/translation/fonts/DroidSansArabic.ttf similarity index 100% rename from gui/translation/font/DroidSansArabic.ttf rename to gui/translation/fonts/DroidSansArabic.ttf diff --git a/gui/translation/font/DroidSansArabic.ttf.import b/gui/translation/fonts/DroidSansArabic.ttf.import similarity index 59% rename from gui/translation/font/DroidSansArabic.ttf.import rename to gui/translation/fonts/DroidSansArabic.ttf.import index fdc1a3c5c7..f3d4ff1fbe 100644 --- a/gui/translation/font/DroidSansArabic.ttf.import +++ b/gui/translation/fonts/DroidSansArabic.ttf.import @@ -2,19 +2,20 @@ importer="font_data_dynamic" 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] -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] Rendering=null antialiasing=1 generate_mipmaps=false +disable_embedded_bitmaps=true multichannel_signed_distance_field=false msdf_pixel_range=8 msdf_size=48 diff --git a/gui/translation/font/DroidSansFallback.ttf b/gui/translation/fonts/DroidSansFallback.ttf similarity index 100% rename from gui/translation/font/DroidSansFallback.ttf rename to gui/translation/fonts/DroidSansFallback.ttf diff --git a/gui/translation/font/DroidSansFallback.ttf.import b/gui/translation/fonts/DroidSansFallback.ttf.import similarity index 58% rename from gui/translation/font/DroidSansFallback.ttf.import rename to gui/translation/fonts/DroidSansFallback.ttf.import index 72aa382faf..3796ff52b0 100644 --- a/gui/translation/font/DroidSansFallback.ttf.import +++ b/gui/translation/fonts/DroidSansFallback.ttf.import @@ -2,19 +2,20 @@ importer="font_data_dynamic" 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] -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] Rendering=null antialiasing=1 generate_mipmaps=false +disable_embedded_bitmaps=true multichannel_signed_distance_field=false msdf_pixel_range=8 msdf_size=48 diff --git a/gui/translation/font/DroidSansHebrew.ttf b/gui/translation/fonts/DroidSansHebrew.ttf similarity index 100% rename from gui/translation/font/DroidSansHebrew.ttf rename to gui/translation/fonts/DroidSansHebrew.ttf diff --git a/gui/translation/font/DroidSansHebrew.ttf.import b/gui/translation/fonts/DroidSansHebrew.ttf.import similarity index 59% rename from gui/translation/font/DroidSansHebrew.ttf.import rename to gui/translation/fonts/DroidSansHebrew.ttf.import index 8ee558094e..28349ccb7c 100644 --- a/gui/translation/font/DroidSansHebrew.ttf.import +++ b/gui/translation/fonts/DroidSansHebrew.ttf.import @@ -2,19 +2,20 @@ importer="font_data_dynamic" 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] -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] Rendering=null antialiasing=1 generate_mipmaps=false +disable_embedded_bitmaps=true multichannel_signed_distance_field=false msdf_pixel_range=8 msdf_size=48 diff --git a/gui/translation/font/DroidSansJapanese.ttf b/gui/translation/fonts/DroidSansJapanese.ttf similarity index 100% rename from gui/translation/font/DroidSansJapanese.ttf rename to gui/translation/fonts/DroidSansJapanese.ttf diff --git a/gui/translation/font/DroidSansJapanese.ttf.import b/gui/translation/fonts/DroidSansJapanese.ttf.import similarity index 58% rename from gui/translation/font/DroidSansJapanese.ttf.import rename to gui/translation/fonts/DroidSansJapanese.ttf.import index 03dde240ab..92417ea966 100644 --- a/gui/translation/font/DroidSansJapanese.ttf.import +++ b/gui/translation/fonts/DroidSansJapanese.ttf.import @@ -2,19 +2,20 @@ importer="font_data_dynamic" 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] -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] Rendering=null antialiasing=1 generate_mipmaps=false +disable_embedded_bitmaps=true multichannel_signed_distance_field=false msdf_pixel_range=8 msdf_size=48 diff --git a/gui/translation/font/DroidSansThai.ttf b/gui/translation/fonts/DroidSansThai.ttf similarity index 100% rename from gui/translation/font/DroidSansThai.ttf rename to gui/translation/fonts/DroidSansThai.ttf diff --git a/gui/translation/font/DroidSansThai.ttf.import b/gui/translation/fonts/DroidSansThai.ttf.import similarity index 59% rename from gui/translation/font/DroidSansThai.ttf.import rename to gui/translation/fonts/DroidSansThai.ttf.import index f074d1a0ac..adc3edefdd 100644 --- a/gui/translation/font/DroidSansThai.ttf.import +++ b/gui/translation/fonts/DroidSansThai.ttf.import @@ -2,19 +2,20 @@ importer="font_data_dynamic" 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] -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] Rendering=null antialiasing=1 generate_mipmaps=false +disable_embedded_bitmaps=true multichannel_signed_distance_field=false msdf_pixel_range=8 msdf_size=48 diff --git a/gui/translation/LICENSE.DroidSans.txt b/gui/translation/fonts/LICENSE.DroidSans.txt similarity index 91% rename from gui/translation/LICENSE.DroidSans.txt rename to gui/translation/fonts/LICENSE.DroidSans.txt index d3a2eaa8c3..5f4d5f9ecd 100644 --- a/gui/translation/LICENSE.DroidSans.txt +++ b/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 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 distributed under the License is distributed on an "AS IS" BASIS, diff --git a/gui/translation/fonts/droid_sans.tres b/gui/translation/fonts/droid_sans.tres new file mode 100644 index 0000000000..20ed3e5a45 --- /dev/null +++ b/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) diff --git a/gui/translation/hello_en.wav.import b/gui/translation/hello_en.wav.import deleted file mode 100644 index 2c9616a2f4..0000000000 --- a/gui/translation/hello_en.wav.import +++ /dev/null @@ -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 diff --git a/gui/translation/hello_es.wav.import b/gui/translation/hello_es.wav.import deleted file mode 100644 index 5405645fcc..0000000000 --- a/gui/translation/hello_es.wav.import +++ /dev/null @@ -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 diff --git a/gui/translation/hello_jp.wav.import b/gui/translation/hello_jp.wav.import deleted file mode 100644 index c18d59cafd..0000000000 --- a/gui/translation/hello_jp.wav.import +++ /dev/null @@ -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 diff --git a/gui/translation/icon.webp b/gui/translation/icon.webp index 873e84c40e..cb75f80492 100644 Binary files a/gui/translation/icon.webp and b/gui/translation/icon.webp differ diff --git a/gui/translation/icon.webp.import b/gui/translation/icon.webp.import index cc29159c5b..7ea556100d 100644 --- a/gui/translation/icon.webp.import +++ b/gui/translation/icon.webp.import @@ -2,7 +2,7 @@ importer="texture" type="CompressedTexture2D" -uid="uid://brwp8bimc75uu" +uid="uid://csnnfel8tal41" path="res://.godot/imported/icon.webp-e94f9a68b0f625a567a797079e4d325f.ctex" metadata={ "vram_texture": false diff --git a/gui/translation/images/flag_japan.webp b/gui/translation/images/flag_japan.webp new file mode 100644 index 0000000000..3db899c0fc Binary files /dev/null and b/gui/translation/images/flag_japan.webp differ diff --git a/gui/translation/speaker.png.import b/gui/translation/images/flag_japan.webp.import similarity index 68% rename from gui/translation/speaker.png.import rename to gui/translation/images/flag_japan.webp.import index 373efebb80..b7d5085946 100644 --- a/gui/translation/speaker.png.import +++ b/gui/translation/images/flag_japan.webp.import @@ -2,16 +2,16 @@ importer="texture" 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={ "vram_texture": false } [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] diff --git a/gui/translation/images/flag_russia.webp b/gui/translation/images/flag_russia.webp new file mode 100644 index 0000000000..abe5bea972 Binary files /dev/null and b/gui/translation/images/flag_russia.webp differ diff --git a/gui/translation/images/flag_russia.webp.import b/gui/translation/images/flag_russia.webp.import new file mode 100644 index 0000000000..0aec0b9596 --- /dev/null +++ b/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 diff --git a/gui/translation/images/flag_spain.webp b/gui/translation/images/flag_spain.webp new file mode 100644 index 0000000000..ba931e7d5a Binary files /dev/null and b/gui/translation/images/flag_spain.webp differ diff --git a/gui/translation/flag_spain.png.import b/gui/translation/images/flag_spain.webp.import similarity index 68% rename from gui/translation/flag_spain.png.import rename to gui/translation/images/flag_spain.webp.import index f0d711deec..32c94a2929 100644 --- a/gui/translation/flag_spain.png.import +++ b/gui/translation/images/flag_spain.webp.import @@ -2,16 +2,16 @@ importer="texture" 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={ "vram_texture": false } [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] diff --git a/gui/translation/images/flag_uk.webp b/gui/translation/images/flag_uk.webp new file mode 100644 index 0000000000..7b6f5c9f1e Binary files /dev/null and b/gui/translation/images/flag_uk.webp differ diff --git a/gui/translation/flag_uk.png.import b/gui/translation/images/flag_uk.webp.import similarity index 69% rename from gui/translation/flag_uk.png.import rename to gui/translation/images/flag_uk.webp.import index 8369281779..8f0c62fa54 100644 --- a/gui/translation/flag_uk.png.import +++ b/gui/translation/images/flag_uk.webp.import @@ -2,16 +2,16 @@ importer="texture" 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={ "vram_texture": false } [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] diff --git a/gui/translation/images/speaker.webp b/gui/translation/images/speaker.webp new file mode 100644 index 0000000000..7f13974b25 Binary files /dev/null and b/gui/translation/images/speaker.webp differ diff --git a/gui/translation/flag_japan.png.import b/gui/translation/images/speaker.webp.import similarity index 69% rename from gui/translation/flag_japan.png.import rename to gui/translation/images/speaker.webp.import index 26026c4338..12bf44bf5c 100644 --- a/gui/translation/flag_japan.png.import +++ b/gui/translation/images/speaker.webp.import @@ -2,16 +2,16 @@ importer="texture" 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={ "vram_texture": false } [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] diff --git a/gui/translation/project.godot b/gui/translation/project.godot index 80846bdddd..475f4c124e 100644 --- a/gui/translation/project.godot +++ b/gui/translation/project.godot @@ -14,7 +14,7 @@ config/name="Translation Demo" config/description="A demo showing how Godot seamlessly enables the use of localized resources and texts." 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/icon="res://icon.webp" @@ -26,21 +26,22 @@ window/stretch/aspect="expand" [internationalization] 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] +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={ -"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] renderer/rendering_method="gl_compatibility" -renderer/rendering_method.mobile="gl_compatibility" diff --git a/gui/translation/screenshots/translation.png b/gui/translation/screenshots/translation.png deleted file mode 100644 index 5f27d9e7d9..0000000000 Binary files a/gui/translation/screenshots/translation.png and /dev/null differ diff --git a/gui/translation/screenshots/translation.webp b/gui/translation/screenshots/translation.webp new file mode 100644 index 0000000000..1b84b9e3aa Binary files /dev/null and b/gui/translation/screenshots/translation.webp differ diff --git a/gui/translation/speaker.png b/gui/translation/speaker.png deleted file mode 100644 index 02bd0a876e..0000000000 Binary files a/gui/translation/speaker.png and /dev/null differ diff --git a/gui/translation/text.csv b/gui/translation/text.csv deleted file mode 100644 index 0da91e35d5..0000000000 --- a/gui/translation/text.csv +++ /dev/null @@ -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!,これが翻訳されていました! diff --git a/gui/translation/text.csv.import b/gui/translation/text.csv.import deleted file mode 100644 index 4b3b681cc6..0000000000 --- a/gui/translation/text.csv.import +++ /dev/null @@ -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 diff --git a/gui/translation/translation_csv.gd b/gui/translation/translation_csv.gd new file mode 100644 index 0000000000..e182af93e6 --- /dev/null +++ b/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")) diff --git a/gui/translation/translation_demo.gd b/gui/translation/translation_demo.gd deleted file mode 100644 index af3d17bf47..0000000000 --- a/gui/translation/translation_demo.gd +++ /dev/null @@ -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() diff --git a/gui/translation/translation_demo.tscn b/gui/translation/translation_demo.tscn deleted file mode 100644 index 74585e20d3..0000000000 --- a/gui/translation/translation_demo.tscn +++ /dev/null @@ -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"] diff --git a/gui/translation/translation_demo_csv.tscn b/gui/translation/translation_demo_csv.tscn new file mode 100644 index 0000000000..d440a4d96b --- /dev/null +++ b/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"] diff --git a/gui/translation/translation_demo_po.tscn b/gui/translation/translation_demo_po.tscn new file mode 100644 index 0000000000..f3aa9812b0 --- /dev/null +++ b/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"] diff --git a/gui/translation/translation_po.gd b/gui/translation/translation_po.gd new file mode 100644 index 0000000000..5625483203 --- /dev/null +++ b/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")) diff --git a/gui/translation/translations/csv/text.csv b/gui/translation/translations/csv/text.csv new file mode 100644 index 0000000000..c002e96e41 --- /dev/null +++ b/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.","こんにちは、これは翻訳デモプロジェクトです.","Здравствуйте, это демонстрационный проект перевода." diff --git a/gui/translation/translations/csv/text.csv.import b/gui/translation/translations/csv/text.csv.import new file mode 100644 index 0000000000..68d46a7ed5 --- /dev/null +++ b/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 diff --git a/gui/translation/translations/po/translation_demo.pot b/gui/translation/translations/po/translation_demo.pot new file mode 100644 index 0000000000..90a73065eb --- /dev/null +++ b/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 "" diff --git a/gui/translation/translations/po/translation_demo_es.po b/gui/translation/translations/po/translation_demo_es.po new file mode 100644 index 0000000000..f7fba50c65 --- /dev/null +++ b/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!" diff --git a/gui/translation/translations/po/translation_demo_ja.po b/gui/translation/translations/po/translation_demo_ja.po new file mode 100644 index 0000000000..e91bc9f91a --- /dev/null +++ b/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 "押す!"