From 7e143b91d96e8727ea2024e839cf547fd5f4a680 Mon Sep 17 00:00:00 2001 From: zysftd Date: Sun, 12 Jul 2026 13:24:04 +0800 Subject: [PATCH 01/15] feat: add i18n translation infrastructure - Add TranslationService singleton with JSON-based translation loading - Add _(key) macro for wrapping UI strings - Add nlohmann-json to vcpkg.json - Register TranslationService in Gui CMakeLists.txt - Create translations/en.json and zh.json (to be populated) --- source/Gui/CMakeLists.txt | 2 + source/Gui/TranslationService.cpp | 75 +++++++++++++++++++++++++++++++ source/Gui/TranslationService.h | 26 +++++++++++ source/Gui/translations/en.json | 1 + source/Gui/translations/zh.json | 1 + vcpkg.json | 4 ++ 6 files changed, 109 insertions(+) create mode 100644 source/Gui/TranslationService.cpp create mode 100644 source/Gui/TranslationService.h create mode 100644 source/Gui/translations/en.json create mode 100644 source/Gui/translations/zh.json diff --git a/source/Gui/CMakeLists.txt b/source/Gui/CMakeLists.txt index bfb5def80..56bc15050 100644 --- a/source/Gui/CMakeLists.txt +++ b/source/Gui/CMakeLists.txt @@ -2,6 +2,8 @@ target_sources(alien PUBLIC AboutDialog.cpp AboutDialog.h + TranslationService.cpp + TranslationService.h ActivateUserDialog.cpp ActivateUserDialog.h AlienDialog.cpp diff --git a/source/Gui/TranslationService.cpp b/source/Gui/TranslationService.cpp new file mode 100644 index 000000000..8b90679ab --- /dev/null +++ b/source/Gui/TranslationService.cpp @@ -0,0 +1,75 @@ +#include "TranslationService.h" + +#include +#include + +namespace fs = std::filesystem; + +TranslationService& TranslationService::get() +{ + static TranslationService instance; + return instance; +} + +bool TranslationService::load(std::string const& language) +{ + std::vector candidates = { + "translations/" + language + ".json", + "../source/Gui/translations/" + language + ".json", + fs::path(fs::absolute(fs::path(__FILE__)).parent_path().generic_string()) / "translations" / (language + ".json"), + }; + + for (auto const& path : candidates) { + if (!fs::exists(path)) { + continue; + } + std::ifstream file(path); + if (!file.is_open()) { + continue; + } + try { + _translations = nlohmann::json::parse(file); + _currentLanguage = language; + return true; + } catch (...) { + continue; + } + } + return false; +} + +char const* TranslationService::tr(char const* key) const +{ + if (_currentLanguage == "en") { + return key; + } + auto it = _translations.find(key); + if (it != _translations.end() && it->is_string()) { + return it->get_ref().c_str(); + } + return key; +} + +std::string const& TranslationService::currentLanguage() const +{ + return _currentLanguage; +} + +std::vector TranslationService::availableLanguages() const +{ + std::vector languages{"en"}; + for (auto const& dir : {"translations", "../source/Gui/translations"}) { + if (!fs::exists(dir)) { + continue; + } + for (auto const& entry : fs::directory_iterator(dir)) { + if (entry.path().extension() == ".json") { + auto lang = entry.path().stem().string(); + if (lang != "en" && std::find(languages.begin(), languages.end(), lang) == languages.end()) { + languages.push_back(lang); + } + } + } + } + return languages; +} diff --git a/source/Gui/TranslationService.h b/source/Gui/TranslationService.h new file mode 100644 index 000000000..e8fd09326 --- /dev/null +++ b/source/Gui/TranslationService.h @@ -0,0 +1,26 @@ +#pragma once + +#include +#include +#include + +#include + +class TranslationService +{ +public: + static TranslationService& get(); + + bool load(std::string const& language); + char const* tr(char const* key) const; + std::string const& currentLanguage() const; + std::vector availableLanguages() const; + +private: + TranslationService() = default; + + nlohmann::json _translations = nlohmann::json::object(); + std::string _currentLanguage = "en"; +}; + +#define _(key) TranslationService::get().tr(key) diff --git a/source/Gui/translations/en.json b/source/Gui/translations/en.json new file mode 100644 index 000000000..9e26dfeeb --- /dev/null +++ b/source/Gui/translations/en.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/source/Gui/translations/zh.json b/source/Gui/translations/zh.json new file mode 100644 index 000000000..9e26dfeeb --- /dev/null +++ b/source/Gui/translations/zh.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/vcpkg.json b/vcpkg.json index 5e952c8ad..ce09ff8e2 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -75,6 +75,10 @@ { "name": "implot", "version>=": "0.16" + }, + { + "name": "nlohmann-json", + "version>=": "3.11.2" } ], "builtin-baseline": "af752f21c9d79ba3df9cb0250ce2233933f58486" From 18bfc0dff10a30117f16f3f1ae121d5405a1dfe4 Mon Sep 17 00:00:00 2001 From: zysftd Date: Sun, 12 Jul 2026 20:22:28 +0800 Subject: [PATCH 02/15] feat: add Chinese translation data and i18n infrastructure --- source/Gui/Definitions.h | 1 + source/Gui/Main.cpp | 4 + source/Gui/StyleRepository.cpp | 58 ++ source/Gui/translations/en.json | 1091 +++++++++++++++++++++++++++- source/Gui/translations/zh.json | 1199 ++++++++++++++++++++++++++++++- 5 files changed, 2351 insertions(+), 2 deletions(-) diff --git a/source/Gui/Definitions.h b/source/Gui/Definitions.h index f0e5deac9..ccabd4f8d 100644 --- a/source/Gui/Definitions.h +++ b/source/Gui/Definitions.h @@ -1,6 +1,7 @@ #pragma once #include +#include "TranslationService.h" class _MainWindow; using MainWindow = std::shared_ptr<_MainWindow>; diff --git a/source/Gui/Main.cpp b/source/Gui/Main.cpp index d99a100f9..82b69bf08 100644 --- a/source/Gui/Main.cpp +++ b/source/Gui/Main.cpp @@ -16,6 +16,7 @@ #include "HelpStrings.h" #include "MainWindow.h" +#include "TranslationService.h" namespace @@ -38,6 +39,9 @@ int main(int argc, char** argv) GlobalSettings::get().setDebugMode(inDebugMode); GlobalSettings::get().setInterop(useInterop); + auto language = GlobalSettings::get().getValue("settings.language", std::string("en")); + TranslationService::get().load(language); + FileLogger fileLogger = std::make_shared<_FileLogger>(); MainWindow mainWindow; diff --git a/source/Gui/StyleRepository.cpp b/source/Gui/StyleRepository.cpp index 324f56db6..2ba3a2296 100644 --- a/source/Gui/StyleRepository.cpp +++ b/source/Gui/StyleRepository.cpp @@ -17,8 +17,29 @@ #include #include +#include + #include "WindowController.h" +namespace +{ + std::string findCjkFont() + { + std::vector candidates = { + std::string(getenv("HOME")) + "/.local/share/fonts/NotoSansCJK-Regular.ttc", + "/usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttc", + "/usr/share/fonts/noto-cjk/NotoSansCJK-Regular.ttc", + "/usr/share/fonts/truetype/noto/NotoSansCJK-Regular.ttc", + }; + for (auto const& path : candidates) { + if (std::filesystem::exists(path)) { + return path; + } + } + return {}; + } +} + void StyleRepository::setup() { auto scaleFactor = WindowController::get().getContentScaleFactor(); @@ -35,6 +56,16 @@ void StyleRepository::setup() configMerge.MergeMode = true; configMerge.FontBuilderFlags = ImGuiFreeTypeBuilderFlags_LightHinting; + auto cjkFontPath = findCjkFont(); + auto cjkFontAvailable = !cjkFontPath.empty(); + + ImFontConfig configCJK; + if (cjkFontAvailable) { + configCJK.MergeMode = true; + configCJK.FontBuilderFlags = ImGuiFreeTypeBuilderFlags_LightHinting; + configCJK.FontNo = 2; + } + ImGuiIO& io = ImGui::GetIO(); //default font (small with icons) @@ -44,18 +75,33 @@ void StyleRepository::setup() io.Fonts->AddFontFromMemoryCompressedTTF( FontAwesomeSolid_compressed_data, FontAwesomeSolid_compressed_size, 16.0f * scaleFactor, &configMerge, rangesIcons); } + if (cjkFontAvailable) { + io.Fonts->AddFontFromFileTTF(cjkFontPath.c_str(), 16.0f * scaleFactor, &configCJK, io.Fonts->GetGlyphRangesChineseFull()); + } //small bold font _smallBoldFont = io.Fonts->AddFontFromMemoryCompressedTTF(DroidSansBold_compressed_data, DroidSansBold_compressed_size, 16.0f * scaleFactor); + if (cjkFontAvailable) { + io.Fonts->AddFontFromFileTTF(cjkFontPath.c_str(), 16.0f * scaleFactor, &configCJK, io.Fonts->GetGlyphRangesChineseFull()); + } //medium bold font _mediumBoldFont = io.Fonts->AddFontFromMemoryCompressedTTF(DroidSansBold_compressed_data, DroidSansBold_compressed_size, 24.0f * scaleFactor); + if (cjkFontAvailable) { + io.Fonts->AddFontFromFileTTF(cjkFontPath.c_str(), 24.0f * scaleFactor, &configCJK, io.Fonts->GetGlyphRangesChineseFull()); + } //medium font _mediumFont = io.Fonts->AddFontFromMemoryCompressedTTF(DroidSans_compressed_data, DroidSans_compressed_size, 24.0f * scaleFactor); + if (cjkFontAvailable) { + io.Fonts->AddFontFromFileTTF(cjkFontPath.c_str(), 24.0f * scaleFactor, &configCJK, io.Fonts->GetGlyphRangesChineseFull()); + } //large font _largeFont = io.Fonts->AddFontFromMemoryCompressedTTF(DroidSans_compressed_data, DroidSans_compressed_size, 48.0f * scaleFactor); + if (cjkFontAvailable) { + io.Fonts->AddFontFromFileTTF(cjkFontPath.c_str(), 48.0f * scaleFactor, &configCJK, io.Fonts->GetGlyphRangesChineseFull()); + } //icon font _iconFont = io.Fonts->AddFontFromMemoryCompressedTTF(AlienIconFont_compressed_data, AlienIconFont_compressed_size, 24.0f * scaleFactor); @@ -68,12 +114,24 @@ void StyleRepository::setup() //monospace medium font _monospaceMediumFont = io.Fonts->AddFontFromMemoryCompressedTTF(Cousine_Regular_compressed_data, Cousine_Regular_compressed_size, 14.0f * scaleFactor); + if (cjkFontAvailable) { + io.Fonts->AddFontFromFileTTF(cjkFontPath.c_str(), 14.0f * scaleFactor, &configCJK, io.Fonts->GetGlyphRangesChineseSimplifiedCommon()); + } //monospace large font _monospaceLargeFont = io.Fonts->AddFontFromMemoryCompressedTTF(Cousine_Regular_compressed_data, Cousine_Regular_compressed_size, 128.0f * scaleFactor); + if (cjkFontAvailable) { + io.Fonts->AddFontFromFileTTF(cjkFontPath.c_str(), 128.0f * scaleFactor, &configCJK, io.Fonts->GetGlyphRangesChineseSimplifiedCommon()); + } _reefMediumFont = io.Fonts->AddFontFromMemoryCompressedTTF(Reef_compressed_data, Reef_compressed_size, 24.0f * scaleFactor); + if (cjkFontAvailable) { + io.Fonts->AddFontFromFileTTF(cjkFontPath.c_str(), 24.0f * scaleFactor, &configCJK, io.Fonts->GetGlyphRangesChineseFull()); + } _reefLargeFont = io.Fonts->AddFontFromMemoryCompressedTTF(Reef_compressed_data, Reef_compressed_size, 64.0f * scaleFactor); + if (cjkFontAvailable) { + io.Fonts->AddFontFromFileTTF(cjkFontPath.c_str(), 64.0f * scaleFactor, &configCJK, io.Fonts->GetGlyphRangesChineseFull()); + } } ImFont* StyleRepository::getIconFont() const diff --git a/source/Gui/translations/en.json b/source/Gui/translations/en.json index 9e26dfeeb..61ee423d4 100644 --- a/source/Gui/translations/en.json +++ b/source/Gui/translations/en.json @@ -1 +1,1090 @@ -{} \ No newline at end of file +{ + " 0: This value is used for handcrafted cells. This refers to cells that have been ": " 0: This value is used for handcrafted cells. This refers to cells that have been ", + " 1: This value is used for free cells. Free cells are cells that have not been created by a ": " 1: This value is used for free cells. Free cells are cells that have not been created by a ", + " Abs(x) := x if x >= 0 and -x if x < 0\n\n": " Abs(x) := x if x >= 0 and -x if x < 0\n\n", + " Activated: The countdown is decreased until 0 each time the detonator is executed. If the countdown is 0, the detonator will explode.\n\n": " Activated: The countdown is decreased until 0 each time the detonator is executed. If the countdown is 0, the detonator will explode.\n\n", + " All Cells: In this mode there are no restrictions, e.g. any other constructor or injector cell can be infected. ": " All Cells: In this mode there are no restrictions, e.g. any other constructor or injector cell can be infected. ", + " All cell functions: The cells are colored according to their cell function.": " All cell functions: The cells are colored according to their cell function.", + " Anti-attacker: reduces the attack strength of an enemy attacker cell\n\n": " Anti-attacker: reduces the attack strength of an enemy attacker cell\n\n", + " Attacker: 1 if a cell is attacked by an other attacker cell": " Attacker: 1 if a cell is attacked by an other attacker cell", + " Attacker: a value which is proportional to the gained ": " Attacker: a value which is proportional to the gained ", + " Attacker: abs(value) > threshold activates attacker\n\n": " Attacker: abs(value) > threshold activates attacker\n\n", + " Automatic: The construction process is automatically triggered at regular intervals. ": " Automatic: The construction process is automatically triggered at regular intervals. ", + " Bending: Increases (or decreases) the angle between the muscle ": " Bending: Increases (or decreases) the angle between the muscle ", + " Binary step(x) := 1 if x >= 0 and 0 if x < 0\n\n": " Binary step(x) := 1 if x >= 0 and 0 if x < 0\n\n", + " Cell states: blue = ready, green = under construction, white = activating, pink = detached, pale blue = reviving, red = dying\n\n": " Cell states: blue = ready, green = under construction, white = activating, pink = detached, pale blue = reviving, red = dying\n\n", + " Connected cells: ": " Connected cells: ", + " Connected cells: In this case the energy will be distributed evenly across all ": " Connected cells: In this case the energy will be distributed evenly across all ", + " Constructor: 0 (could not ": " Constructor: 0 (could not ", + " Constructor: abs(value) > ": " Constructor: abs(value) > ", + " Detonator: abs(value) > threshold activates detonator": " Detonator: abs(value) > threshold activates detonator", + " Energy: The more energy a cell has, the brighter it is displayed. A grayscale is used.\n\n": " Energy: The more energy a cell has, the brighter it is displayed. A grayscale is used.\n\n", + " Expansion and contraction: Causes an elongation (or contraction) of the ": " Expansion and contraction: Causes an elongation (or contraction) of the ", + " Exploded: The detonator is already exploded.": " Exploded: The detonator is already exploded.", + " Free cells: Cells that were not created by reproduction but by the conversion of energy particles (they could serve as free food).\n\n": " Free cells: Cells that were not created by reproduction but by the conversion of energy particles (they could serve as free food).\n\n", + " Gaussian(x) := exp(-2 * x * x)": " Gaussian(x) := exp(-2 * x * x)", + " Genome complexities: This property can be utilized by attacker cells when the parameter 'Complex creature protection' is ": " Genome complexities: This property can be utilized by attacker cells when the parameter 'Complex creature protection' is ", + " Handcrafted constructs: Cells that were created in the editor (e.g. walls).\n\n": " Handcrafted constructs: Cells that were created in the editor (e.g. walls).\n\n", + " Identity(x) := x\n\n": " Identity(x) := x\n\n", + " Injector: 0 (no cells found) or 1 (injection in process or completed)\n\n": " Injector: 0 (no cells found) or 1 (injection in process or completed)\n\n", + " Injector: abs(value) > threshold ": " Injector: abs(value) > threshold ", + " Input channel ": " Input channel ", + " Input channel #0: abs(value) > threshold activates ": " Input channel #0: abs(value) > threshold activates ", + " Input channel #0: abs(value) > threshold activates constructor (only necessary in ": " Input channel #0: abs(value) > threshold activates constructor (only necessary in ", + " Input channel #0: abs(value) > threshold activates injector\n\n": " Input channel #0: abs(value) > threshold activates injector\n\n", + " Input channel #0: abs(value) > threshold activates sensor\n\n": " Input channel #0: abs(value) > threshold activates sensor\n\n", + " Input channel #0: value > threshold triggers creation of a bond to a cell in the vicinity, value < -threshold triggers destruction of a bond\n\n": " Input channel #0: value > threshold triggers creation of a bond to a cell in the vicinity, value < -threshold triggers destruction of a bond\n\n", + " Input channel #1: This channel is solely utilized for acceleration due to bending. If the sign of channel #1 ": " Input channel #1: This channel is solely utilized for acceleration due to bending. If the sign of channel #1 ", + " Input channel #3: This channel is used for muscles in movement mode. It encodes the relative angle for the movement with respect to a ": " Input channel #3: This channel is used for muscles in movement mode. It encodes the relative angle for the movement with respect to a ", + " Less complex mutants: Cells that have a less complex genome. The complexity calculation can be customized in the simulation parameters under the 'Genome complexity measurement' expert settings. By default, it is the number of encoded cells in the genome.\n\n": " Less complex mutants: Cells that have a less complex genome. The complexity calculation can be customized in the simulation parameters under the 'Genome complexity measurement' expert settings. By default, it is the number of encoded cells in the genome.\n\n", + " Manual: The construction process is only triggered when ": " Manual: The construction process is only triggered when ", + " More complex mutants: Cells that have a more complex genome.\n\n": " More complex mutants: Cells that have a more complex genome.\n\n", + " Movement to sensor target: A movement can be performed if the input signal has its origin in a sensor cell which has previously detected a ": " Movement to sensor target: A movement can be performed if the input signal has its origin in a sensor cell which has previously detected a ", + " Muscle: The strength of the movement, bending or expansion/contraction. A negative sign corresponds to ": " Muscle: The strength of the movement, bending or expansion/contraction. A negative sign corresponds to ", + " Muscle: This channel is ": " Muscle: This channel is ", + " Muscle: This channel is used for muscles in movement mode. It encodes the relative angle for the movement with respect to a previously ": " Muscle: This channel is used for muscles in movement mode. It encodes the relative angle for the movement with respect to a previously ", + " Mutants and cell functions: Combination of mutants and cell function coloring.\n\n": " Mutants and cell functions: Combination of mutants and cell function coloring.\n\n", + " Mutants: Different mutants are represented by different colors (only larger structural mutations such as translations or duplications are taken into ": " Mutants: Different mutants are represented by different colors (only larger structural mutations such as translations or duplications are taken into ", + " Neuron": " Neuron", + " Neuron\n\n": " Neuron\n\n", + " None: No further restriction.\n\n": " None: No further restriction.\n\n", + " Only empty cells: Only cells which possess an empty genome can be infected. This mode is useful when an organism wants to ": " Only empty cells: Only cells which possess an empty genome can be infected. This mode is useful when an organism wants to ", + " Other mutants: Cells that have a significantly different genome.\n\n": " Other mutants: Cells that have a significantly different genome.\n\n", + " Output channel #0: ": " Output channel #0: ", + " Output channel #0: 0 (could not constructor next cell, e.g. no energy, required ": " Output channel #0: 0 (could not constructor next cell, e.g. no energy, required ", + " Output channel #0: 0 (no cells found) or 1 (injection in process or completed)": " Output channel #0: 0 (no cells found) or 1 (injection in process or completed)", + " Output channel #0: 0 (no connection created/removed) or 1 (connection created/removed)": " Output channel #0: 0 (no connection created/removed) or 1 (connection created/removed)", + " Output channel #0: a value which is proportional to the gained energy": " Output channel #0: a value which is proportional to the gained energy", + " Output channel #1: density of the last match\n\n": " Output channel #1: density of the last match\n\n", + " Output channel #2: distance ": " Output channel #2: distance ", + " Output channel #3: angle of the last match": " Output channel #3: angle of the last match", + " Private: Each user account has its own private space. The simulations and genomes are only visible to ": " Private: Each user account has its own private space. The simulations and genomes are only visible to ", + " Public: All logged-in users can share their simulations and genomes with the public. The files stored here are ": " Public: All logged-in users can share their simulations and genomes with the public. The files stored here are ", + " Ready: The detonator cell waits for input on channel #0. If abs(value) > threshold, the detonator will be activated.\n\n": " Ready: The detonator cell waits for input on channel #0. If abs(value) > threshold, the detonator will be activated.\n\n", + " Reconnector: 0 (no connection created/removed) or 1 (connection created/removed)": " Reconnector: 0 (no connection created/removed) or 1 (connection created/removed)", + " Reconnector: value > threshold triggers creation of a bond to a cell in the vicinity, value < -threshold triggers destruction of a bond\n\n": " Reconnector: value > threshold triggers creation of a bond to a cell in the vicinity, value < -threshold triggers destruction of a bond\n\n", + " Same mutants: Cells that have a related genome.\n\n": " Same mutants: Cells that have a related genome.\n\n", + " Scan specific direction: In this mode, the scanning process is restricted to a particular direction. The ": " Scan specific direction: In this mode, the scanning process is restricted to a particular direction. The ", + " Scan vicinity: In this mode, the entire nearby area is scanned (typically ": " Scan vicinity: In this mode, the entire nearby area is scanned (typically ", + " Sensor: 0 (no match) or 1 (match)\n\n": " Sensor: 0 (no match) or 1 (match)\n\n", + " Sensor: abs(value) > threshold activates ": " Sensor: abs(value) > threshold activates ", + " Sensor: angle of the last match": " Sensor: angle of the last match", + " Sensor: density of the last match": " Sensor: density of the last match", + " Sensor: distance of the last match (0 = far away, 1 = close)": " Sensor: distance of the last match (0 = far away, 1 = close)", + " Sigmoid(x) := 2 / (1 + exp(x)) - 1\n\n": " Sigmoid(x) := 2 / (1 + exp(x)) - 1\n\n", + " Single cell function: A specific type of cell function can be highlighted, which is selected in the next parameter.\n\n": " Single cell function: A specific type of cell function can be highlighted, which is selected in the next parameter.\n\n", + " Standard cell colors: Each cell is assigned one of 7 default colors, which is displayed with this option. \n\n": " Standard cell colors: Each cell is assigned one of 7 default colors, which is displayed with this option. \n\n", + " Transmitters and constructors: ": " Transmitters and constructors: ", + " Transmitters and constructors: Here, the energy will be transferred to spatially nearby constructors or other transmitter cells ": " Transmitters and constructors: Here, the energy will be transferred to spatially nearby constructors or other transmitter cells ", + " alien-project: This ": " alien-project: This ", + " considering the weights and bias in order to calculate the neuron's output, i.e., output_j = sigma(sum_i (input_i * weight_ji) + bias_j), where sigma": " considering the weights and bias in order to calculate the neuron's output, i.e., output_j = sigma(sum_i (input_i * weight_ji) + bias_j), where sigma", + " denotes the activation function. The following choices for sigma are available:\n\n": " denotes the activation function. The following choices for sigma are available:\n\n", + " file, name and description are stored on the server. It cannot be guaranteed that the data will not be deleted.": " file, name and description are stored on the server. It cannot be guaranteed that the data will not be deleted.", + " name": " name", + " save points": " save points", + " to the server and made visible in the browser. You can choose whether you want to share it with other users or whether it should only be visible in your private workspace.\nIf you have already selected a folder, your ": " to the server and made visible in the browser. You can choose whether you want to share it with other users or whether it should only be visible in your private workspace.\nIf you have already selected a folder, your ", + " will be uploaded there.": " will be uploaded there.", + " will be visible to all users. If false, the ": " will be visible to all users. If false, the ", + " will only be visible in the private workspace. This property can also be changed later if desired.": " will only be visible in the private workspace. This property can also be changed later if desired.", + " with the one that is currently open. The name, description and reactions will be preserved.": " with the one that is currently open. The name, description and reactions will be preserved.", + " your user name or email address is already in use,\n": " your user name or email address is already in use,\n", + "#0: The strength of the movement, bending or expansion/contraction. A negative sign corresponds to the opposite ": "#0: The strength of the movement, bending or expansion/contraction. A negative sign corresponds to the opposite ", + "' has been deleted.\nYou are logged out.": "' has been deleted.\nYou are logged out.", + "' will be deleted on the server side.\nThese include the likes, the simulations and the account data.": "' will be deleted on the server side.\nThese include the likes, the simulations and the account data.", + "'HKEY_CURRENT_USER\\SOFTWARE\\alien' or, in the case of other OS, in 'settings.json' on your local machine. It ": "'HKEY_CURRENT_USER\\SOFTWARE\\alien' or, in the case of other OS, in 'settings.json' on your local machine. It ", + "'Manual' mode)\n\n": "'Manual' mode)\n\n", + "'Options,' and choose 'High performance'.\n\nIf these conditions are not met, ALIEN may crash unexpectedly.\n\n": "'Options,' and choose 'High performance'.\n\nIf these conditions are not met, ALIEN may crash unexpectedly.\n\n", + "'s private workspace": "'s private workspace", + "'self-copy' mode. In this case, the constructor's sub-genome refers to its superordinate genome.": "'self-copy' mode. In this case, the constructor's sub-genome refers to its superordinate genome.", + "'stick together' with other cell networks after collision.": "'stick together' with other cell networks after collision.", + "(if the parameter 'Movement toward target' is deactivated). In the first case, the object must have been targeted by a sensor cell from which the ": "(if the parameter 'Movement toward target' is deactivated). In the first case, the object must have been targeted by a sensor cell from which the ", + "0 (no match) or 1 (match)\n\n": "0 (no match) or 1 (match)\n\n", + "120 deg": "120 deg", + "180 deg": "180 deg", + "60 deg": "60 deg", + "72 deg": "72 deg", + "90 deg": "90 deg", + "A constructor cell builds a cell network according to a contained genome. The construction process takes place cell by ": "A constructor cell builds a cell network according to a contained genome. The construction process takes place cell by ", + "A defender cell does not need to be activated. Its presence reduces the strength of an enemy attack involving attacker ": "A defender cell does not need to be activated. Its presence reduces the strength of an enemy attack involving attacker ", + "A detonator cell will be activated if it receives an input on channel #0 with abs(value) > threshold. Then its counter ": "A detonator cell will be activated if it receives an input on channel #0 with abs(value) > threshold. Then its counter ", + "A functioning organism requires cells to collaborate. This can involve sensor cells that perceive the environment, neuron cells that ": "A functioning organism requires cells to collaborate. This can involve sensor cells that perceive the environment, neuron cells that ", + "A genome describes a network of connected cells. On the one hand, there is the option to select a pre-defined geometry (e.g. ": "A genome describes a network of connected cells. On the one hand, there is the option to select a pre-defined geometry (e.g. ", + "A high frame rate leads to a greater GPU workload for rendering and thus lowers the simulation speed (time steps per second).": "A high frame rate leads to a greater GPU workload for rendering and thus lowers the simulation speed (time steps per second).", + "A high value protects new mutants with equal or greater genome complexity from being attacked.": "A high value protects new mutants with equal or greater genome complexity from being attacked.", + "A pattern is a set of cell networks and energy particles.": "A pattern is a set of cell networks and energy particles.", + "A reconnector cell can make or break a cell connection to an other cell (with a different creature id) with a specified color. \n\n": "A reconnector cell can make or break a cell connection to an other cell (with a different creature id) with a specified color. \n\n", + "ALIEN is an artificial life and physics simulation tool based on a CUDA-powered 2D particle engine for soft bodies and fluids.": "ALIEN is an artificial life and physics simulation tool based on a CUDA-powered 2D particle engine for soft bodies and fluids.", + "About": "About", + "Absolute value": "Absolute value", + "Absorption factor": "Absorption factor", + "Accumulate values for all colors": "Accumulate values for all colors", + "Activate": "Activate", + "Activating this toggle, the cell's output will be discarded. This prevents any other cell from utilizing it as input.": "Activating this toggle, the cell's output will be discarded. This prevents any other cell from utilizing it as input.", + "Activation function": "Activation function", + "Adaptive space grid": "Adaptive space grid", + "Add a reaction": "Add a reaction", + "Add parameter zone": "Add parameter zone", + "Add radiation source": "Add radiation source", + "Additionally, other cells such as constructor cells provide an output signal as soon as they are triggered (automatically).": "Additionally, other cells such as constructor cells provide an output signal as soon as they are triggered (automatically).", + "Adopt": "Adopt", + "Adopt simulation parameters": "Adopt simulation parameters", + "Advanced absorption control": "Advanced absorption control", + "Advanced attacker control": "Advanced attacker control", + "Affected activation functions": "Affected activation functions", + "Affected biases": "Affected biases", + "Affected weights": "Affected weights", + "Age": "Age", + "All cell functions": "All cell functions", + "Amount of energy lost by a muscle action of a cell in form of emitted energy particles.": "Amount of energy lost by a muscle action of a cell in form of emitted energy particles.", + "Amount of energy lost by an attempted attack of a cell in form of emitted energy particles.": "Amount of energy lost by an attempted attack of a cell in form of emitted energy particles.", + "An ALIEN world is two-dimensional rectangular domain with periodic boundary conditions. The space is modeled as a continuum.": "An ALIEN world is two-dimensional rectangular domain with periodic boundary conditions. The space is modeled as a continuum.", + "An attacker cell attacks surrounding cells from other cell networks (with different creature id) by stealing energy from ": "An attacker cell attacks surrounding cells from other cell networks (with different creature id) by stealing energy from ", + "An error occurred on the server.": "An error occurred on the server.", + "An error occurred on the server. This could be related to the fact that\n": "An error occurred on the server. This could be related to the fact that\n", + "An error occurred on the server. Your entered code may be incorrect.\nPlease try to reset the password again.": "An error occurred on the server. Your entered code may be incorrect.\nPlease try to reset the password again.", + "Analysis result": "Analysis result", + "Angle": "Angle", + "Angle increment": "Angle increment", + "Angular velocity": "Angular velocity", + "Angular velocity increment": "Angular velocity increment", + "Anti-attacker strength": "Anti-attacker strength", + "Anti-injector strength": "Anti-injector strength", + "Anti-injector: increases the injection duration of an enemy injector cell": "Anti-injector: increases the injection duration of an enemy injector cell", + "Artificial Life Environment": "Artificial Life Environment", + "Artificial Life Environment, version %s\n\nis an open source project initiated and maintained by\nChristian Heinemann.": "Artificial Life Environment, version %s\n\nis an open source project initiated and maintained by\nChristian Heinemann.", + "As a result, you will be able to see the GPU information of other registered users who have shared it.": "As a result, you will be able to see the GPU information of other registered users who have shared it.", + "Attack radius": "Attack radius", + "Attack strength": "Attack strength", + "Attack visualization": "Attack visualization", + "Attacker": "Attacker", + "Attacker cells can distribute the acquired energy through two different methods. The energy distribution is analogous to ": "Attacker cells can distribute the acquired energy through two different methods. The energy distribution is analogous to ", + "Attacker: It attacks surrounding cells from other cell networks by stealing energy from them.": "Attacker: It attacks surrounding cells from other cell networks by stealing energy from them.", + "Attacks": "Attacks", + "Autosave": "Autosave", + "Autosave interval (min)": "Autosave interval (min)", + "Autotracking on selection": "Autotracking on selection", + "Backflow": "Backflow", + "Backflow limit": "Backflow limit", + "Background color": "Background color", + "Base": "Base", + "Base parameters": "Base parameters", + "Basic notion": "Basic notion", + "Bending acceleration": "Bending acceleration", + "Bending angle": "Bending angle", + "Bias": "Bias", + "Binary step": "Binary step", + "Binding creation velocity": "Binding creation velocity", + "Blast radius": "Blast radius", + "Blocks": "Blocks", + "Borderless rendering": "Borderless rendering", + "Break down by color": "Break down by color", + "Brightness": "Brightness", + "Browser": "Browser", + "Build": "Build", + "By default, a nerve cell forwards signals from connected cells (and summing it up if ": "By default, a nerve cell forwards signals from connected cells (and summing it up if ", + "By default, cells in the genome sequence are automatically connected to all neighboring cells belonging to the same genome when they ": "By default, cells in the genome sequence are automatically connected to all neighboring cells belonging to the same genome when they ", + "By default, the generated pulses consist of a positive value in channel #0. When 'Alternating pulses' is enabled, the ": "By default, the generated pulses consist of a positive value in channel #0. When 'Alternating pulses' is enabled, the ", + "By default, when the constructor cell initiates a new construction, the new cell is created in the area with the most available ": "By default, when the constructor cell initiates a new construction, the new cell is created in the area with the most available ", + "CTRL + click on a slider to type in a precise value": "CTRL + click on a slider to type in a precise value", + "CUDA settings": "CUDA settings", + "Cancel": "Cancel", + "Catch peaks": "Catch peaks", + "Cell": "Cell", + "Cell #": "Cell #", + "Cell Energies": "Cell Energies", + "Cell age limiter": "Cell age limiter", + "Cell ages": "Cell ages", + "Cell color": "Cell color", + "Cell color transition rules": "Cell color transition rules", + "Cell colors": "Cell colors", + "Cell connection": "Cell connection", + "Cell count": "Cell count", + "Cell death consequences": "Cell death consequences", + "Cell deletion": "Cell deletion", + "Cell distance": "Cell distance", + "Cell function": "Cell function", + "Cell function type": "Cell function type", + "Cell function: Attacker": "Cell function: Attacker", + "Cell function: Constructor": "Cell function: Constructor", + "Cell function: Defender": "Cell function: Defender", + "Cell function: Detonator": "Cell function: Detonator", + "Cell function: Injector": "Cell function: Injector", + "Cell function: Muscle": "Cell function: Muscle", + "Cell function: Reconnector": "Cell function: Reconnector", + "Cell function: Sensor": "Cell function: Sensor", + "Cell function: Transmitter": "Cell function: Transmitter", + "Cell glow": "Cell glow", + "Cell info overlay": "Cell info overlay", + "Cell insertion": "Cell insertion", + "Cell life cycle": "Cell life cycle", + "Cell network": "Cell network", + "Cell properties": "Cell properties", + "Cell radius": "Cell radius", + "Cell specific parameters": "Cell specific parameters", + "Cell states": "Cell states", + "Cells": "Cells", + "Cells can exist in various states. When a cell network of the organism is being constructed, its cells are in the 'Under construction' state. Once the cell network ": "Cells can exist in various states. When a cell network of the organism is being constructed, its cells are in the 'Under construction' state. Once the cell network ", + "Cells can possess a specific function that enables them to, for example, perceive their environment, process information, or ": "Cells can possess a specific function that enables them to, for example, perceive their environment, process information, or ", + "Center": "Center", + "Center position": "Center position", + "Center position and velocity": "Center position and velocity", + "Center rotation": "Center rotation", + "Central": "Central", + "Chain explosion probability": "Chain explosion probability", + "Change color": "Change color", + "Change folder name": "Change folder name", + "Change name or description": "Change name or description", + "Choose a reaction": "Choose a reaction", + "Circular": "Circular", + "Cleaning up save points ...": "Cleaning up save points ...", + "Clear": "Clear", + "Clockwise": "Clockwise", + "Clone selected zone/radiation source": "Clone selected zone/radiation source", + "Close inspections": "Close inspections", + "Code (case sensitive)": "Code (case sensitive)", + "Collapse all folders": "Collapse all folders", + "Collision-based": "Collision-based", + "Color": "Color", + "Color #0": "Color #0", + "Color #1": "Color #1", + "Color #2": "Color #2", + "Color #3": "Color #3", + "Color #4": "Color #4", + "Color #5": "Color #5", + "Color #6": "Color #6", + "Color inhomogeneity factor": "Color inhomogeneity factor", + "Color transition rule": "Color transition rule", + "Color transitions": "Color transitions", + "Coloring": "Coloring", + "Completed injections": "Completed injections", + "Completeness check": "Completeness check", + "Complex creature protection": "Complex creature protection", + "Conditional inflow": "Conditional inflow", + "Connected cells": "Connected cells", + "Connection distance": "Connection distance", + "Connections mismatch penalty": "Connections mismatch penalty", + "Constructor": "Constructor", + "Contained energy": "Contained energy", + "Contraction and expansion delta": "Contraction and expansion delta", + "Contrast": "Contrast", + "Convert to destructible cell": "Convert to destructible cell", + "Convert to indestructible wall": "Convert to indestructible wall", + "Copy": "Copy", + "Copy pattern": "Copy pattern", + "Copy simulation parameters to clipboard": "Copy simulation parameters to clipboard", + "Core radius": "Core radius", + "Counter clockwise": "Counter clockwise", + "Create a disc-shaped cell network": "Create a disc-shaped cell network", + "Create a hexagonal cell network": "Create a hexagonal cell network", + "Create a rectangular cell network": "Create a rectangular cell network", + "Create a single cell": "Create a single cell", + "Create a single energy particle": "Create a single energy particle", + "Create save point": "Create save point", + "Create user": "Create user", + "Created cells": "Created cells", + "Created cells / sec": "Created cells / sec", + "Created self-replicators / sec": "Created self-replicators / sec", + "Creating flashback ...": "Creating flashback ...", + "Creating in-memory flashback: It saves the content of the current world to the memory.": "Creating in-memory flashback: It saves the content of the current world to the memory.", + "Creating save point ...": "Creating save point ...", + "Creator": "Creator", + "Current": "Current", + "Custom geometry": "Custom geometry", + "Customize deletion mutations": "Customize deletion mutations", + "Customize neuron mutations": "Customize neuron mutations", + "DEBUG": "DEBUG", + "Damping factor": "Damping factor", + "Data privacy policy": "Data privacy policy", + "Decay rate of dying cells": "Decay rate of dying cells", + "Defender": "Defender", + "Defender activities": "Defender activities", + "Defender: It reduces the attack strength when another cell in the vicinity performs an attack.": "Defender: It reduces the attack strength when another cell in the vicinity performs an attack.", + "Define matrix": "Define matrix", + "Defines the maximum age of a cell. If a cell exceeds this age it will be transformed to an energy particle.": "Defines the maximum age of a cell. If a cell exceeds this age it will be transformed to an energy particle.", + "Delete": "Delete", + "Delete Pattern": "Delete Pattern", + "Delete all save points": "Delete all save points", + "Delete save point": "Delete save point", + "Delete selected ": "Delete selected ", + "Delete selected zone/radiation source": "Delete selected zone/radiation source", + "Delete user": "Delete user", + "Deleting save point ...": "Deleting save point ...", + "Deletion": "Deletion", + "Depth level": "Depth level", + "Description": "Description", + "Description (optional)": "Description (optional)", + "Desktop": "Desktop", + "Destroy cells": "Destroy cells", + "Detached creature parts die": "Detached creature parts die", + "Detonation countdown": "Detonation countdown", + "Detonations": "Detonations", + "Detonator": "Detonator", + "Detonator: A cell which can explode by a signal. It generates a large amount of kinetic energy for the objects in its surroundings.": "Detonator: A cell which can explode by a signal. It generates a large amount of kinetic energy for the objects in its surroundings.", + "Directory": "Directory", + "Disable radiation sources": "Disable radiation sources", + "Display settings": "Display settings", + "Distance": "Distance", + "Diversity": "Diversity", + "Do you really want to delete all savepoints?": "Do you really want to delete all savepoints?", + "Do you really want to terminate the program?": "Do you really want to terminate the program?", + "Download": "Download", + "Downloads": "Downloads", + "Drag and drop": "Drag and drop", + "Draw freehand cell network": "Draw freehand cell network", + "Draws a suitable grid in the background depending on the zoom level.": "Draws a suitable grid in the background depending on the zoom level.", + "Draws borders along the world before it repeats itself.": "Draws borders along the world before it repeats itself.", + "Draws red crosses in the center of radiation sources.": "Draws red crosses in the center of radiation sources.", + "Drift angle": "Drift angle", + "Duplication": "Duplication", + "Each generated cell has an 'execution order number' that is one greater than the previous generated cell.": "Each generated cell has an 'execution order number' that is one greater than the previous generated cell.", + "Each neuron has 8 input channels and produces an output by the formula output_j = sigma((sum_i (input_i * weight_ji) + ": "Each neuron has 8 input channels and produces an output by the formula output_j = sigma((sum_i (input_i * weight_ji) + ", + "Editors": "Editors", + "Email": "Email", + "End drawing": "End drawing", + "Energy": "Energy", + "Energy cost": "Energy cost", + "Energy distribution Value": "Energy distribution Value", + "Energy distribution radius": "Energy distribution radius", + "Energy particle": "Energy particle", + "Energy particle #": "Energy particle #", + "Energy particles": "Energy particles", + "Energy to cell transformation": "Energy to cell transformation", + "Entire creature dies": "Entire creature dies", + "Entire history plots": "Entire history plots", + "Error": "Error", + "Error: Savepoint files could not be read or created in the specified directory.": "Error: Savepoint files could not be read or created in the specified directory.", + "Evolution simulations": "Evolution simulations", + "Examples": "Examples", + "Exit": "Exit", + "Expand all folders": "Expand all folders", + "Expert settings": "Expert settings", + "Expert settings: Advanced attacker control": "Expert settings: Advanced attacker control", + "Expert settings: Advanced energy absorption control": "Expert settings: Advanced energy absorption control", + "Expert settings: Cell age limiter": "Expert settings: Cell age limiter", + "Expert settings: Cell color transition rules": "Expert settings: Cell color transition rules", + "Expert settings: Cell glow": "Expert settings: Cell glow", + "Expert settings: Customize deletion mutations": "Expert settings: Customize deletion mutations", + "Expert settings: Customize neuron mutations": "Expert settings: Customize neuron mutations", + "Expert settings: External energy control": "Expert settings: External energy control", + "Expert settings: Genome complexity measurement": "Expert settings: Genome complexity measurement", + "Expert settings: Legacy behavior": "Expert settings: Legacy behavior", + "External energy amount": "External energy amount", + "External energy control": "External energy control", + "Fade-out radius": "Fade-out radius", + "Fetch angle from adjacent sensor": "Fetch angle from adjacent sensor", + "Field type": "Field type", + "File size": "File size", + "Filter (case insensitive)": "Filter (case insensitive)", + "First steps": "First steps", + "Fluid dynamics": "Fluid dynamics", + "Fluids, walls and soft bodies": "Fluids, walls and soft bodies", + "Folder name": "Folder name", + "Food chain color matrix": "Food chain color matrix", + "For how long should I run a simulation to see evolutionary changes?": "For how long should I run a simulation to see evolutionary changes?", + "Force field": "Force field", + "Forgot your password?": "Forgot your password?", + "Frames per second": "Frames per second", + "Free cells": "Free cells", + "Frequently asked questions": "Frequently asked questions", + "Friction": "Friction", + "Full screen": "Full screen", + "Furthermore, these networks can be fed by sensors and, in turn, control muscle and attacker cells.": "Furthermore, these networks can be fed by sensors and, in turn, control muscle and attacker cells.", + "Fusion velocity": "Fusion velocity", + "GPU (visible if logged in)": "GPU (visible if logged in)", + "GPU model": "GPU model", + "Gaussian": "Gaussian", + "GeForce 10 series).\n\n2) You have the latest NVIDIA graphics driver installed.\n\n3) The name of the ": "GeForce 10 series).\n\n2) You have the latest NVIDIA graphics driver installed.\n\n3) The name of the ", + "General": "General", + "Generate ascending execution order numbers": "Generate ascending execution order numbers", + "Genome": "Genome", + "Genome color": "Genome color", + "Genome colors": "Genome colors", + "Genome complexities": "Genome complexities", + "Genome complexity\naverage": "Genome complexity\naverage", + "Genome complexity\nmaximum": "Genome complexity\nmaximum", + "Genome complexity\nvariance": "Genome complexity\nvariance", + "Genome complexity measurement": "Genome complexity measurement", + "Genome complexity variance": "Genome complexity variance", + "Genome copy mutations": "Genome copy mutations", + "Genome editor": "Genome editor", + "Genomes": "Genomes", + "Geometry": "Geometry", + "Geometry penalty": "Geometry penalty", + "Getting started": "Getting started", + "Grid multiplier": "Grid multiplier", + "Height": "Height", + "Here, one can configure whether the encoded cell network in the genome should be detached from the constructor cell once it has been ": "Here, one can configure whether the encoded cell network in the genome should be detached from the constructor cell once it has been ", + "Here, one can set how the cells are to be colored during rendering. \n\n": "Here, one can set how the cells are to be colored during rendering. \n\n", + "Here, the energy will be transferred to spatially nearby constructors or other transmitter cells within the same cell ": "Here, the energy will be transferred to spatially nearby constructors or other transmitter cells within the same cell ", + "High velocity penalty": "High velocity penalty", + "Highlighted cell function": "Highlighted cell function", + "Histograms": "Histograms", + "Horizontal cells": "Horizontal cells", + "How can I add energy to a simulation?": "How can I add energy to a simulation?", + "How can I create a cell signal in the first place?": "How can I create a cell signal in the first place?", + "How can neural networks be incorporated?": "How can neural networks be incorporated?", + "How does a simple self-replicating organism work?": "How does a simple self-replicating organism work?", + "How to create a new user?": "How to create a new user?", + "How to use or create folders?": "How to use or create folders?", + "Identity": "Identity", + "If a constructor or injector cell is encoded in a genome, that cell can itself contain another genome. This sub-genome can ": "If a constructor or injector cell is encoded in a genome, that cell can itself contain another genome. This sub-genome can ", + "If activated, all radiation sources within this zone are deactivated.": "If activated, all radiation sources within this zone are deactivated.", + "If activated, an energy particle will transform into a cell if the energy of the particle exceeds the normal energy value.": "If activated, an energy particle will transform into a cell if the energy of the particle exceeds the normal energy value.", + "If activated, successful attacks of attacker cells are visualized.": "If activated, successful attacks of attacker cells are visualized.", + "If activated, the attacker cell is able to destroy other cells. If deactivated, it only damages them.": "If activated, the attacker cell is able to destroy other cells. If deactivated, it only damages them.", + "If activated, the direction in which muscle cells are moving are visualized.": "If activated, the direction in which muscle cells are moving are visualized.", + "If activated, the sensor detects only objects with a distance equal or greater than the specified value.": "If activated, the sensor detects only objects with a distance equal or greater than the specified value.", + "If activated, the sensor detects only objects with a distance equal or less than the specified value.": "If activated, the sensor detects only objects with a distance equal or less than the specified value.", + "If activated, the simulation is rendered periodically in the view port.": "If activated, the simulation is rendered periodically in the view port.", + "If activated, the transmitter cells can only transfer energy to nearby cells belonging to the same creature.": "If activated, the transmitter cells can only transfer energy to nearby cells belonging to the same creature.", + "If an attacked cell is connected to defender cells or itself a defender cell the attack strength is reduced by this factor.": "If an attacked cell is connected to defender cells or itself a defender cell the attack strength is reduced by this factor.", + "If enabled, a signal in channel #0 will be generated at regular time intervals.": "If enabled, a signal in channel #0 will be generated at regular time intervals.", + "If the Sticky property is selected, the created cells can usually form further connections. That is, they can ": "If the Sticky property is selected, the created cells can usually form further connections. That is, they can ", + "If the attacked cell is connected to cells with different colors, this factor affects the energy of the captured energy.": "If the attacked cell is connected to cells with different colors, this factor affects the energy of the captured energy.", + "If the conditions are met and the error still occurs, please start ALIEN with the command line parameter '-d', try to reproduce the error and ": "If the conditions are met and the error still occurs, please start ALIEN with the command line parameter '-d', try to reproduce the error and ", + "If the toggle 'Remember' is activated, the password will be stored in the Windows registry under the path ": "If the toggle 'Remember' is activated, the password will be stored in the Windows registry under the path ", + "If this option is enabled, other users will be able to see in the browser window that you have the following graphics card: ": "If this option is enabled, other users will be able to see in the browser window that you have the following graphics card: ", + "If true, the ": "If true, the ", + "If you want to upload the ": "If you want to upload the ", + "Image converter": "Image converter", + "Important": "Important", + "In case that the parameter 'Cell death consequences' is set to 'Detached creature parts die': A cell is in 'Detached' state when it is separated from ": "In case that the parameter 'Cell death consequences' is set to 'Detached creature parts die': A cell is in 'Detached' state when it is separated from ", + "In general, the following types of parameters can be set.": "In general, the following types of parameters can be set.", + "In order to share and upvote simulations you need to log in.": "In order to share and upvote simulations you need to log in.", + "In progress": "In progress", + "In queue": "In queue", + "In this case the energy will be distributed evenly across all connected and connected-connected cells.\n\n": "In this case the energy will be distributed evenly across all connected and connected-connected cells.\n\n", + "Include sub-genomes": "Include sub-genomes", + "Indestructible wall": "Indestructible wall", + "Indicates how energetic the emitted particles of aged cells are.": "Indicates how energetic the emitted particles of aged cells are.", + "Indicates how energetic the emitted particles of high energy cells are.": "Indicates how energetic the emitted particles of high energy cells are.", + "Individual cell color": "Individual cell color", + "Inflow": "Inflow", + "Inflow only for non-replicators": "Inflow only for non-replicators", + "Information": "Information", + "Injection activities": "Injection activities", + "Injection radius": "Injection radius", + "Injection time": "Injection time", + "Injector": "Injector", + "Injector cells can override the genome of other constructor or injector cells by their own. To do this, they need to be activated, remain in ": "Injector cells can override the genome of other constructor or injector cells by their own. To do this, they need to be activated, remain in ", + "Injector: It can infect other constructor cells to inject its own built-in genome.": "Injector: It can infect other constructor cells to inject its own built-in genome.", + "Inner radius": "Inner radius", + "Input #": "Input #", + "Insertion": "Insertion", + "Inspect Objects": "Inspect Objects", + "Inspect objects": "Inspect objects", + "Inspect principal genome": "Inspect principal genome", + "Internal energy (may be interpreted as its temperature)": "Internal energy (may be interpreted as its temperature)", + "Introduction": "Introduction", + "It contains features for compatibility with older versions.": "It contains features for compatibility with older versions.", + "It contains further settings that influence how much energy can be obtained from an attack by attacker cells.": "It contains further settings that influence how much energy can be obtained from an attack by attacker cells.", + "It enables additional possibilities to control the maximal cell age.": "It enables additional possibilities to control the maximal cell age.", + "It enables an additional rendering step that makes the cells glow.": "It enables an additional rendering step that makes the cells glow.", + "It enables further settings for deletion mutations. If disabled, defaults are used (displayed in the tooltip of the specific parameters).": "It enables further settings for deletion mutations. If disabled, defaults are used (displayed in the tooltip of the specific parameters).", + "It enables further settings for neuron mutations. If disabled, defaults are used (displayed in the tooltip of the specific parameters).": "It enables further settings for neuron mutations. If disabled, defaults are used (displayed in the tooltip of the specific parameters).", + "Layers": "Layers", + "Legacy behavior": "Legacy behavior", + "Limited save files": "Limited save files", + "Linear": "Linear", + "Living state": "Living state", + "Load previous time step": "Load previous time step", + "Load save point": "Load save point", + "Loading flashback ...": "Loading flashback ...", + "Loading previous time step ...": "Loading previous time step ...", + "Location": "Location", + "Log": "Log", + "Logarithmic": "Logarithmic", + "Login": "Login", + "Login or register": "Login or register", + "Logout": "Logout", + "Low connection penalty": "Low connection penalty", + "Low genome complexity penalty": "Low genome complexity penalty", + "Low velocity penalty": "Low velocity penalty", + "Make public": "Make public", + "Make sticky": "Make sticky", + "Make uniform velocities": "Make uniform velocities", + "Make unsticky": "Make unsticky", + "Mark reference domain": "Mark reference domain", + "Mass operations": "Mass operations", + "Max angle": "Max angle", + "Max angular velocity": "Max angular velocity", + "Max connections": "Max connections", + "Max velocity X": "Max velocity X", + "Max velocity Y": "Max velocity Y", + "Maximum age": "Maximum age", + "Maximum age balancing": "Maximum age balancing", + "Maximum collision distance": "Maximum collision distance", + "Maximum distance": "Maximum distance", + "Maximum distance up to which a collision of two cells is possible.": "Maximum distance up to which a collision of two cells is possible.", + "Maximum distance up to which a connection of two cells is possible.": "Maximum distance up to which a connection of two cells is possible.", + "Maximum emergent cell age": "Maximum emergent cell age", + "Maximum energy": "Maximum energy", + "Maximum force": "Maximum force", + "Maximum force that can be applied to a cell without causing it to disintegrate.": "Maximum force that can be applied to a cell without causing it to disintegrate.", + "Maximum inactive cell age": "Maximum inactive cell age", + "Maximum value": "Maximum value", + "Maximum velocity": "Maximum velocity", + "Maximum velocity that a cell can reach.": "Maximum velocity that a cell can reach.", + "Message overlay": "Message overlay", + "Min angle": "Min angle", + "Min angular velocity": "Min angular velocity", + "Min velocity X": "Min velocity X", + "Min velocity Y": "Min velocity Y", + "Minimum age": "Minimum age", + "Minimum distance": "Minimum distance", + "Minimum distance between two cells.": "Minimum distance between two cells.", + "Minimum energy": "Minimum energy", + "Minimum energy a cell needs to exist.": "Minimum energy a cell needs to exist.", + "Minimum relative velocity of two colliding cells so that a connection can be established.": "Minimum relative velocity of two colliding cells so that a connection can be established.", + "Minimum size": "Minimum size", + "Minimum split energy": "Minimum split energy", + "Minimum value": "Minimum value", + "Mode": "Mode", + "More": "More", + "Motion blur": "Motion blur", + "Motion type": "Motion type", + "Move selected zone/radiation source downward": "Move selected zone/radiation source downward", + "Move selected zone/radiation source upward": "Move selected zone/radiation source upward", + "Movement acceleration": "Movement acceleration", + "Movement toward target": "Movement toward target", + "Multiplier": "Multiplier", + "Muscle": "Muscle", + "Muscle activities": "Muscle activities", + "Muscle cells can perform different movements and deformations based on input and configuration.\n\n": "Muscle cells can perform different movements and deformations based on input and configuration.\n\n", + "Muscle movement visualization": "Muscle movement visualization", + "Muscle: When a muscle cell is activated, it can produce either a movement, a bending or a change in length of the cell connection.": "Muscle: When a muscle cell is activated, it can produce either a movement, a bending or a change in length of the cell connection.", + "Mutants": "Mutants", + "Mutants and cell functions": "Mutants and cell functions", + "Name": "Name", + "Nerve": "Nerve", + "Nerve pulses": "Nerve pulses", + "Network settings": "Network settings", + "Neural activities": "Neural activities", + "Neural net": "Neural net", + "Neuron": "Neuron", + "Neuron factor": "Neuron factor", + "Neuron weights and biases": "Neuron weights and biases", + "New": "New", + "New complex mutant protection": "New complex mutant protection", + "New password": "New password", + "New simulation": "New simulation", + "Next autosave in ": "Next autosave in ", + "No autosave scheduled": "No autosave scheduled", + "No valid directory": "No valid directory", + "Non-overlapping copies could not be created.": "Non-overlapping copies could not be created.", + "None": "None", + "Normal energy": "Normal energy", + "Num genotype\ncells average": "Num genotype\ncells average", + "Number of copies": "Number of copies", + "Number of files": "Number of files", + "Numerics": "Numerics", + "OK": "OK", + "Object inspection": "Object inspection", + "Objects": "Objects", + "Offset": "Offset", + "Open": "Open", + "Open ALIEN Discord server": "Open ALIEN Discord server", + "Open image": "Open image", + "Open parameters for selected zone/radiation source in a new window": "Open parameters for selected zone/radiation source in a new window", + "Open pattern": "Open pattern", + "Open simulation parameters": "Open simulation parameters", + "Open simulation parameters from file": "Open simulation parameters from file", + "Options": "Options", + "Orientation": "Orientation", + "Outer radius": "Outer radius", + "Output #": "Output #", + "Overlapping check": "Overlapping check", + "Overview": "Overview", + "Palette": "Palette", + "Parameters": "Parameters", + "Parameters (filtered)": "Parameters (filtered)", + "Password": "Password", + "Paste": "Paste", + "Paste pattern": "Paste pattern", + "Paste simulation parameters from clipboard": "Paste simulation parameters from clipboard", + "Pattern": "Pattern", + "Pattern analysis": "Pattern analysis", + "Pattern editor": "Pattern editor", + "Pause": "Pause", + "Peak value": "Peak value", + "Pencil radius": "Pencil radius", + "Physics": "Physics", + "Physics: Binding": "Physics: Binding", + "Physics: Motion": "Physics: Motion", + "Physics: Radiation": "Physics: Radiation", + "Physics: Thresholds": "Physics: Thresholds", + "Plant-herbivore ecosystems": "Plant-herbivore ecosystems", + "Please choose a color": "Please choose a color", + "Please enter a new password and the confirmation code\nsent to your email address.": "Please enter a new password and the confirmation code\nsent to your email address.", + "Please enter the desired user name and password and proceed by clicking the 'Create user' button.": "Please enter the desired user name and password and proceed by clicking the 'Create user' button.", + "Please enter the user name and proceed by clicking the 'Reset password' button.": "Please enter the user name and proceed by clicking the 'Reset password' button.", + "Please enter your email address to receive the\nconfirmation code for the new user.": "Please enter your email address to receive the\nconfirmation code for the new user.", + "Please enter your email address to receive the\nconfirmation code to reset the password.": "Please enter your email address to receive the\nconfirmation code to reset the password.", + "Please make sure that:\n\n1) You have an NVIDIA graphics card with compute capability 6.0 or higher (for example ": "Please make sure that:\n\n1) You have an NVIDIA graphics card with compute capability 6.0 or higher (for example ", + "Plot height": "Plot height", + "Plot type": "Plot type", + "Position": "Position", + "Position (x,y)": "Position (x,y)", + "Position X": "Position X", + "Position Y": "Position Y", + "Position in space": "Position in space", + "Preserve self-replication": "Preserve self-replication", + "Pressure": "Pressure", + "Prevent genome depth increase": "Prevent genome depth increase", + "Previous": "Previous", + "Primary cell coloring": "Primary cell coloring", + "Private workspace (need to login)": "Private workspace (need to login)", + "Process single time step": "Process single time step", + "Processes per time step and active cell": "Processes per time step and active cell", + "Project name": "Project name", + "Properties": "Properties", + "Public workspace": "Public workspace", + "Radial": "Radial", + "Radiation": "Radiation", + "Radiation angle": "Radiation angle", + "Radiation sources": "Radiation sources", + "Radiation type 1: Strength": "Radiation type 1: Strength", + "Radiation type I: Minimum age": "Radiation type I: Minimum age", + "Radiation type I: Strength": "Radiation type I: Strength", + "Radiation type II: Energy threshold": "Radiation type II: Energy threshold", + "Radiation type II: Strength": "Radiation type II: Strength", + "Radius": "Radius", + "Ramification factor": "Ramification factor", + "Random multiplication": "Random multiplication", + "Random multiplier": "Random multiplier", + "Randomize": "Randomize", + "Randomize mutation ids": "Randomize mutation ids", + "Re-enter password": "Re-enter password", + "Reactions": "Reactions", + "Reactions given": "Reactions given", + "Reactions received": "Reactions received", + "Real-time": "Real-time", + "Real-time plots": "Real-time plots", + "Reconnector": "Reconnector", + "Reconnector creations": "Reconnector creations", + "Reconnector deletions": "Reconnector deletions", + "Reconnector: Has the ability to dynamically create or destroy connections to other cells with a specified color.": "Reconnector: Has the ability to dynamically create or destroy connections to other cells with a specified color.", + "Rectangular": "Rectangular", + "Reference simulation parameters replaced": "Reference simulation parameters replaced", + "Refresh": "Refresh", + "Reinforcement factor": "Reinforcement factor", + "Relative strength": "Relative strength", + "Relative time: %s\nValue: %s": "Relative time: %s\nValue: %s", + "Release stresses": "Release stresses", + "Remember": "Remember", + "Render UI": "Render UI", + "Render simulation": "Render simulation", + "Rendering": "Rendering", + "Replace the selected ": "Replace the selected ", + "Repulsion strength": "Repulsion strength", + "Reset age after construction": "Reset age after construction", + "Reset password": "Reset password", + "Resize": "Resize", + "Resize world": "Resize world", + "Resolution": "Resolution", + "Restrict to selected cell networks": "Restrict to selected cell networks", + "Restricts the sensor so that it only scans cells with a certain color.": "Restricts the sensor so that it only scans cells with a certain color.", + "Revert changes": "Revert changes", + "Rigidity": "Rigidity", + "Roll out changes to cell networks": "Roll out changes to cell networks", + "Run": "Run", + "Same creature energy distribution": "Same creature energy distribution", + "Same mutant protection": "Same mutant protection", + "Save": "Save", + "Save on exit": "Save on exit", + "Save pattern": "Save pattern", + "Save pattern analysis result": "Save pattern analysis result", + "Save simulation parameters": "Save simulation parameters", + "Save simulation parameters to file": "Save simulation parameters to file", + "Saving on exit ...": "Saving on exit ...", + "Scale": "Scale", + "Scale content": "Scale content", + "Security information": "Security information", + "Select a position in the simulation view": "Select a position in the simulation view", + "Select a position with the mouse": "Select a position with the mouse", + "Select directory": "Select directory", + "Selection": "Selection", + "Self-replicators": "Self-replicators", + "Sensor": "Sensor", + "Sensor activities": "Sensor activities", + "Sensor cells scan their environment for concentrations of cells of a certain color and provide distance and angle to the ": "Sensor cells scan their environment for concentrations of cells of a certain color and provide distance and angle to the ", + "Sensor detection factor": "Sensor detection factor", + "Sensor matches": "Sensor matches", + "Sensor: If activated, it performs a long-range scan for the concentration of cells with a certain color.": "Sensor: If activated, it performs a long-range scan for the concentration of cells with a certain color.", + "Sensors can operate in 2 modes:\n\n": "Sensors can operate in 2 modes:\n\n", + "Server address": "Server address", + "Set execution order": "Set execution order", + "Settings": "Settings", + "Shader parameters": "Shader parameters", + "Shape": "Shape", + "Share GPU model info": "Share GPU model info", + "Show after startup": "Show after startup", + "Show radiation sources": "Show radiation sources", + "Sigmoid": "Sigmoid", + "Signal in channel #0 is not necessary.\n\n In both cases, if there is not enough energy available for the cell being ": "Signal in channel #0 is not necessary.\n\n In both cases, if there is not enough energy available for the cell being ", + "Signals": "Signals", + "Signals can also be generated within a neuron cell using bias values.": "Signals can also be generated within a neuron cell using bias values.", + "Simulation": "Simulation", + "Simulation parameters": "Simulation parameters", + "Simulation parameters copied": "Simulation parameters copied", + "Simulation parameters for '": "Simulation parameters for '", + "Simulation parameters for 'Base'": "Simulation parameters for 'Base'", + "Simulation parameters pasted": "Simulation parameters pasted", + "Simulations": "Simulations", + "Simulators": "Simulators", + "Single cell function": "Single cell function", + "Size (x,y)": "Size (x,y)", + "Size factor": "Size factor", + "Slow down": "Slow down", + "Smoothing length": "Smoothing length", + "Space": "Space", + "Spatial control": "Spatial control", + "Specifies how many branches the constructor can use to build the cell networks. Each branch is connected to ": "Specifies how many branches the constructor can use to build the cell networks. Each branch is connected to ", + "Specifies the color of the cells where connections are to be established or destroyed.": "Specifies the color of the cells where connections are to be established or destroyed.", + "Specifies the radius of the drawn cells in unit length.": "Specifies the radius of the drawn cells in unit length.", + "Standard cell colors": "Standard cell colors", + "Start drawing": "Start drawing", + "Statistics": "Statistics", + "Sticky": "Sticky", + "Stiffness": "Stiffness", + "Strength": "Strength", + "Sub-genome color": "Sub-genome color", + "Swarming": "Swarming", + "Sync with rendering": "Sync with rendering", + "Target color and duration": "Target color and duration", + "Temporal control": "Temporal control", + "The ": "The ", + "The activation function is a mapping which will be applied to the accumulated value from all inputs channels": "The activation function is a mapping which will be applied to the accumulated value from all inputs channels", + "The age of the cell in time steps.": "The age of the cell in time steps.", + "The amount of energy which a attacker cell can transfer to nearby transmitter or constructor cells or to connected cells.": "The amount of energy which a attacker cell can transfer to nearby transmitter or constructor cells or to connected cells.", + "The amount of energy which a transmitter cell can transfer to nearby transmitter or constructor cells or to connected cells.": "The amount of energy which a transmitter cell can transfer to nearby transmitter or constructor cells or to connected cells.", + "The amount of internal energy of the cell. The cell undergoes decay when its energy falls below a critical ": "The amount of internal energy of the cell. The cell undergoes decay when its energy falls below a critical ", + "The analysis result could not be saved to the specified file.": "The analysis result could not be saved to the specified file.", + "The angle between the predecessor and successor cell can be specified here. Please note that the shown angle here is shifted ": "The angle between the predecessor and successor cell can be specified here. Please note that the shown angle here is shifted ", + "The angle in which direction the scanning process should take place can be determined here. An angle of 0 means that the ": "The angle in which direction the scanning process should take place can be determined here. An angle of 0 means that the ", + "The average number of encoded cells in the genomes is displayed.": "The average number of encoded cells in the genomes is displayed.", + "The cell network encoded in the genome can be repeatedly built by specifying a number of ": "The cell network encoded in the genome can be repeatedly built by specifying a number of ", + "The constructor can automatically connect constructed cells to other cells in the vicinity within this distance.": "The constructor can automatically connect constructed cells to other cells in the vicinity within this distance.", + "The countdown specifies the cycles (in 6 time steps) until the detonator will explode.": "The countdown specifies the cycles (in 6 time steps) until the detonator will explode.", + "The data transfer to the server is encrypted via https. On the server side, the password is not stored in cleartext, but as a salted SHA-256 hash ": "The data transfer to the server is encrypted via https. On the server side, the password is not stored in cleartext, but as a salted SHA-256 hash ", + "The default simulation file could not be read.\nAn empty simulation will be created.": "The default simulation file could not be read.\nAn empty simulation will be created.", + "The distance between two connected cells.": "The distance between two connected cells.", + "The duration of the injection process depends on the simulation parameter 'Injection time'.": "The duration of the injection process depends on the simulation parameter 'Injection time'.", + "The energy that the cell should receive after its creation. The larger this value is, the more energy the constructor cell must expend ": "The energy that the cell should receive after its creation. The larger this value is, the more energy the constructor cell must expend ", + "The following cell functions obtain their input from channel #0:\n\n": "The following cell functions obtain their input from channel #0:\n\n", + "The following cell functions obtain their input from channel #1:\n\n": "The following cell functions obtain their input from channel #1:\n\n", + "The following cell functions obtain their input from channel #2:\n\n": "The following cell functions obtain their input from channel #2:\n\n", + "The following cell functions obtain their input from channel #3:\n\n": "The following cell functions obtain their input from channel #3:\n\n", + "The following cell functions obtain their input from channel #4:\n\n": "The following cell functions obtain their input from channel #4:\n\n", + "The following cell functions obtain their input from channel #5:\n\n": "The following cell functions obtain their input from channel #5:\n\n", + "The following cell functions obtain their input from channel #6:\n\n": "The following cell functions obtain their input from channel #6:\n\n", + "The following cell functions obtain their input from channel #7:\n\n": "The following cell functions obtain their input from channel #7:\n\n", + "The following cell functions write their output to channel #0:\n\n": "The following cell functions write their output to channel #0:\n\n", + "The following cell functions write their output to channel #1:\n\n": "The following cell functions write their output to channel #1:\n\n", + "The following cell functions write their output to channel #2:\n\n": "The following cell functions write their output to channel #2:\n\n", + "The following cell functions write their output to channel #3:\n\n": "The following cell functions write their output to channel #3:\n\n", + "The following cell functions write their output to channel #4:\n\n": "The following cell functions write their output to channel #4:\n\n", + "The following cell functions write their output to channel #5:\n\n": "The following cell functions write their output to channel #5:\n\n", + "The following cell functions write their output to channel #6:\n\n": "The following cell functions write their output to channel #6:\n\n", + "The following cell functions write their output to channel #7:\n\n": "The following cell functions write their output to channel #7:\n\n", + "The following folder has been selected in the browser\nand will used for the upload:\n\n": "The following folder has been selected in the browser\nand will used for the upload:\n\n", + "The following options can be used to only bind to cells with certain properties:\n\n": "The following options can be used to only bind to cells with certain properties:\n\n", + "The following options can be used to only detect cells with certain properties:\n\n": "The following options can be used to only detect cells with certain properties:\n\n", + "The fraction of energy that a cell can absorb from an incoming energy particle can be specified here.": "The fraction of energy that a cell can absorb from an incoming energy particle can be specified here.", + "The functions of cells can be executed in a specific sequence determined by this number. The values are limited between 0 and 5 and ": "The functions of cells can be executed in a specific sequence determined by this number. The values are limited between 0 and 5 and ", + "The height of the rectangle in cells.": "The height of the rectangle in cells.", + "The id of the cell is a unique 64 bit number which identifies the cell in the entire world and cannot be changed. The ": "The id of the cell is a unique 64 bit number which identifies the cell in the entire world and cannot be changed. The ", + "The id of the last creature that has been scanned.": "The id of the last creature that has been scanned.", + "The inner radius of the disc in cells.": "The inner radius of the disc in cells.", + "The intervals between two pulses can be set here. It is specified in cycles, which corresponds to 6 time steps each.": "The intervals between two pulses can be set here. It is specified in cycles, which corresponds to 6 time steps each.", + "The larger this parameter is, the less energy can be gained by attacking creatures with more complex genomes.": "The larger this parameter is, the less energy can be gained by attacking creatures with more complex genomes.", + "The larger this parameter is, the less energy can be gained by attacking creatures with the same mutation id.": "The larger this parameter is, the less energy can be gained by attacking creatures with the same mutation id.", + "The larger this parameter is, the more difficult it is to attack cells that contain more connections.": "The larger this parameter is, the more difficult it is to attack cells that contain more connections.", + "The length of the genome in bytes.": "The length of the genome in bytes.", + "The maximal age of cells that arise from energy particles can be set here.": "The maximal age of cells that arise from energy particles can be set here.", + "The maximum distance over which a transmitter cell transfers its additional energy to nearby transmitter or constructor cells.": "The maximum distance over which a transmitter cell transfers its additional energy to nearby transmitter or constructor cells.", + "The maximum distance over which an attacker cell can attack another cell.": "The maximum distance over which an attacker cell can attack another cell.", + "The maximum distance over which an injector cell can infect another cell.": "The maximum distance over which an injector cell can infect another cell.", + "The maximum number of bonds a cell can form with other cells.": "The maximum number of bonds a cell can form with other cells.", + "The maximum number of radiation sources has been reached.": "The maximum number of radiation sources has been reached.", + "The maximum number of zones has been reached.": "The maximum number of zones has been reached.", + "The maximum radius in which a reconnector cell can establish or destroy connections to other cells.": "The maximum radius in which a reconnector cell can establish or destroy connections to other cells.", + "The maximum radius in which a sensor cell can detect mass concentrations.": "The maximum radius in which a sensor cell can detect mass concentrations.", + "The minimum age of a cell can be defined here, from which it emits energy particles.": "The minimum age of a cell can be defined here, from which it emits energy particles.", + "The minimum density to search for a cell concentration of a specific color. This value ranges between 0 and 1. It controls the ": "The minimum density to search for a cell concentration of a specific color. This value ranges between 0 and 1. It controls the ", + "The minimum energy of a cell can be defined here, from which it emits energy particles.": "The minimum energy of a cell can be defined here, from which it emits energy particles.", + "The mutation id is a value to distinguish mutants. After most mutations (except neural network and cell properties) the mutation id changes. A few ": "The mutation id is a value to distinguish mutants. After most mutations (except neural network and cell properties) the mutation id changes. A few ", + "The number of all encoded cells in the genome including its sub-genomes, repetitions and number of branches.": "The number of all encoded cells in the genome including its sub-genomes, repetitions and number of branches.", + "The number of colonies is displayed. A colony is a set of at least 20 same mutants.": "The number of colonies is displayed. A colony is a set of at least 20 same mutants.", + "The number of layers in cells starting from the center.": "The number of layers in cells starting from the center.", + "The number of the encoded cells per repetition in the genome. Cells of sub-genomes are not counted here.": "The number of the encoded cells per repetition in the genome. Cells of sub-genomes are not counted here.", + "The number of zones and radiation sources of the current simulation parameters must match with those from the clipboard.": "The number of zones and radiation sources of the current simulation parameters must match with those from the clipboard.", + "The outer radius of the disc in cells.": "The outer radius of the disc in cells.", + "The password does not match.": "The password does not match.", + "The password has been successfully set.\nYou are logged in.": "The password has been successfully set.\nYou are logged in.", + "The probability that the explosion of one detonator will trigger the explosion of other detonators within the blast radius.": "The probability that the explosion of one detonator will trigger the explosion of other detonators within the blast radius.", + "The proportion of activation functions in the neuronal network of a cell that are changed within a neuron mutation. The default is 0.05.": "The proportion of activation functions in the neuronal network of a cell that are changed within a neuron mutation. The default is 0.05.", + "The proportion of biases in the neuronal network of a cell that are changed within a neuron mutation. The default is 0.2.": "The proportion of biases in the neuronal network of a cell that are changed within a neuron mutation. The default is 0.2.", + "The proportion of weights in the neuronal network of a cell that are changed within a neuron mutation. The default is 0.2.": "The proportion of weights in the neuronal network of a cell that are changed within a neuron mutation. The default is 0.2.", + "The radius of the detonation.": "The radius of the detonation.", + "The radius of the glow. Please note that a large radius affects the performance.": "The radius of the glow. Please note that a large radius affects the performance.", + "The radius of the pencil in number of cells.": "The radius of the pencil in number of cells.", + "The reference angle defines an angle between two cell connections. If the actual angle is larger, tangential forces act on the connected cells, ": "The reference angle defines an angle between two cell connections. If the actual angle is larger, tangential forces act on the connected cells, ", + "The reference distance defines the distance at which no forces act between two connected cells. If the actual distance is greater than the reference ": "The reference distance defines the distance at which no forces act between two connected cells. If the actual distance is greater than the reference ", + "The selected file could not be opened.": "The selected file could not be opened.", + "The selected file could not be saved.": "The selected file could not be saved.", + "The selected pattern could not be saved to the specified file.": "The selected pattern could not be saved to the specified file.", + "The sequence number of the cell in the genome that will be constructed next.": "The sequence number of the cell in the genome that will be constructed next.", + "The spatial distance between each cell and its predecessor cell in the genome sequence is determined here.": "The spatial distance between each cell and its predecessor cell in the genome sequence is determined here.", + "The spatial structure of the cells encoded in the genome is displayed here. This is only a rough ": "The spatial structure of the cells encoded in the genome is displayed here. This is only a rough ", + "The specific cell function type to be highlighted can be selected here.": "The specific cell function type to be highlighted can be selected here.", + "The stiffness determines the amount of force generated after a displacement to push the cell (network) to its reference configuration.": "The stiffness determines the amount of force generated after a displacement to push the cell (network) to its reference configuration.", + "The strength of the glow.": "The strength of the glow.", + "The strength of the repulsive forces, between two cells that are not connected.": "The strength of the repulsive forces, between two cells that are not connected.", + "The user '": "The user '", + "The width of the rectangle in cells.": "The width of the rectangle in cells.", + "The zoom level from which the neuronal activities become visible.": "The zoom level from which the neuronal activities become visible.", + "There are 2 modes available for controlling constructor cells:\n\n": "There are 2 modes available for controlling constructor cells:\n\n", + "There are three different workspaces where you can find and possibly upload simulations and genomes:\n\n": "There are three different workspaces where you can find and possibly upload simulations and genomes:\n\n", + "There are two ways to control the energy distribution, which is set ": "There are two ways to control the energy distribution, which is set ", + "These settings offer extended possibilities for controlling the absorption of energy particles by cells.": "These settings offer extended possibilities for controlling the absorption of energy particles by cells.", + "This can be done using the 'Copy genome' button in the toolbar. This action copies the entire genome from the current tab to ": "This can be done using the 'Copy genome' button in the toolbar. This action copies the entire genome from the current tab to ", + "This can be used to define color transitions for cells depending on their age.": "This can be used to define color transitions for cells depending on their age.", + "This function equips the cell with a small network of 8 neurons with 8x8 configurable weights, 8 bias values and activation functions. It processes ": "This function equips the cell with a small network of 8 neurons with 8x8 configurable weights, 8 bias values and activation functions. It processes ", + "This number specifies the current branch on which the construction process takes place. Each branch is ": "This number specifies the current branch on which the construction process takes place. Each branch is ", + "This parameter allows to control the strength of the pressure.": "This parameter allows to control the strength of the pressure.", + "This parameter be used to control the strength of the viscosity. Larger values lead to a smoother movement.": "This parameter be used to control the strength of the viscosity. Larger values lead to a smoother movement.", + "This parameter controls how the number of encoded cells in the genome influences the calculation of its complexity.": "This parameter controls how the number of encoded cells in the genome influences the calculation of its complexity.", + "This parameter takes into account the number of encoded neurons in the genome for the complexity value.": "This parameter takes into account the number of encoded neurons in the genome for the complexity value.", + "This property defines the color of the cell. It is not just a visual marker. On the one hand, the cell color can be used to define own types of cells ": "This property defines the color of the cell. It is not just a visual marker. On the one hand, the cell color can be used to define own types of cells ", + "This specifies the fraction of the velocity that is slowed down per time step.": "This specifies the fraction of the velocity that is slowed down per time step.", + "This type of mutation alters the color of all cell descriptions in a genome by using the specified color transitions.": "This type of mutation alters the color of all cell descriptions in a genome by using the specified color transitions.", + "This type of mutation alters the color of all cell descriptions in a sub-genome by using the specified color transitions.": "This type of mutation alters the color of all cell descriptions in a sub-genome by using the specified color transitions.", + "This type of mutation copies a block of cell descriptions from the genome at a random position to a new random position.": "This type of mutation copies a block of cell descriptions from the genome at a random position to a new random position.", + "This type of mutation moves a block of cell descriptions from the genome at a random position to a new random position.": "This type of mutation moves a block of cell descriptions from the genome at a random position to a new random position.", + "This value denotes the complexity of the creature's genome. The calculation can be customized in the simulation parameters under the 'Genome ": "This value denotes the complexity of the creature's genome. The calculation can be customized in the simulation parameters under the 'Genome ", + "This value describes the angle between two concatenated cell networks viewed from the first cell of the subsequent cell network.": "This value describes the angle between two concatenated cell networks viewed from the first cell of the subsequent cell network.", + "This value describes the angle between two concatenated cell networks viewed from the last cell of the previous cell network.": "This value describes the angle between two concatenated cell networks viewed from the last cell of the previous cell network.", + "This value determines the angle from the last constructed cell to the second-last constructed cell and the constructor cell. The ": "This value determines the angle from the last constructed cell to the second-last constructed cell and the constructor cell. The ", + "This value indicates the number of pulses until the sign will be changed in channel #0.": "This value indicates the number of pulses until the sign will be changed in channel #0.", + "This value indicates the number of times this genome has been inherited by offspring.": "This value indicates the number of times this genome has been inherited by offspring.", + "This value loosely identifies a specific creature. While not guaranteed, it is very likely that two creatures will have different creature ids.": "This value loosely identifies a specific creature. While not guaranteed, it is very likely that two creatures will have different creature ids.", + "This value sets the stiffness for the entire encoded cell network. The stiffness determines the amount of ": "This value sets the stiffness for the entire encoded cell network. The stiffness determines the amount of ", + "This value specifies how many times the cell network described in the genome should be concatenated for each construction. For a value greater ": "This value specifies how many times the cell network described in the genome should be concatenated for each construction. For a value greater ", + "This value specifies the time interval for automatic triggering of the constructor cell. It is given in multiples ": "This value specifies the time interval for automatic triggering of the constructor cell. It is given in multiples ", + "This values specifies the number of CUDA thread blocks. If you are using a high-end graphics card, you can try to increase the number of blocks.": "This values specifies the number of CUDA thread blocks. If you are using a high-end graphics card, you can try to increase the number of blocks.", + "Throughput": "Throughput", + "Time horizon": "Time horizon", + "Time spent": "Time spent", + "Time step": "Time step", + "Time step data": "Time step data", + "Time step size": "Time step size", + "Time step: %s\nTimestamp: %s\nValue: %s": "Time step: %s\nTimestamp: %s\nValue: %s", + "Time steps per second": "Time steps per second", + "Timelines": "Timelines", + "Timestamp": "Timestamp", + "To translate a genome into an actual structure, there are two options:": "To translate a genome into an actual structure, there are two options:", + "Tools": "Tools", + "Total time steps": "Total time steps", + "Translation": "Translation", + "Transmitter": "Transmitter", + "Transmitter activities": "Transmitter activities", + "Transmitter cells are designed to transport energy. This is important, for example, to supply constructor cells with energy or to ": "Transmitter cells are designed to transport energy. This is important, for example, to supply constructor cells with energy or to ", + "Triples of connected cells within a network have specific spatial angles relative to each other. These angles ": "Triples of connected cells within a network have specific spatial angles relative to each other. These angles ", + "Type": "Type", + "Undo": "Undo", + "Unlimited save files": "Unlimited save files", + "Upload ": "Upload ", + "Upload genome": "Upload genome", + "Upload simulation": "Upload simulation", + "Upload your current ": "Upload your current ", + "Upper limit of connections": "Upper limit of connections", + "User name": "User name", + "Velocity": "Velocity", + "Velocity (x,y)": "Velocity (x,y)", + "Velocity X": "Velocity X", + "Velocity X increment": "Velocity X increment", + "Velocity Y": "Velocity Y", + "Velocity Y increment": "Velocity Y increment", + "Verbose": "Verbose", + "Version": "Version", + "Vertical cells": "Vertical cells", + "Viruses": "Viruses", + "Viscosity": "Viscosity", + "Visible in the public workspace": "Visible in the public workspace", + "Visualization": "Visualization", + "Warning: All the data of the user '": "Warning: All the data of the user '", + "Weight": "Weight", + "What is ": "What is ", + "When a cell is set as indestructible wall, it becomes immortal, resistant to external forces, but still capable of linear movement. Furthermore, unconnected ": "When a cell is set as indestructible wall, it becomes immortal, resistant to external forces, but still capable of linear movement. Furthermore, unconnected ", + "When a genome injection is initiated, the counter increments after each consecutive successful activation of the injector. Once the counter reaches a ": "When a genome injection is initiated, the counter increments after each consecutive successful activation of the injector. Once the counter reaches a ", + "When a new cell network has been fully constructed by a constructor cell, one can define the time steps until activation. Before activation, the cell ": "When a new cell network has been fully constructed by a constructor cell, one can define the time steps until activation. Before activation, the cell ", + "When this parameter is increased, cells with fewer genome complexity will absorb less energy from an incoming energy particle.": "When this parameter is increased, cells with fewer genome complexity will absorb less energy from an incoming energy particle.", + "When this parameter is increased, fast moving cells will absorb less energy from an incoming energy particle.": "When this parameter is increased, fast moving cells will absorb less energy from an incoming energy particle.", + "When this parameter is increased, slowly moving cells will absorb less energy from an incoming energy particle.": "When this parameter is increased, slowly moving cells will absorb less energy from an incoming energy particle.", + "Why does the radiation source generates no energy particles?": "Why does the radiation source generates no energy particles?", + "Width": "Width", + "Windows user that contains no non-English characters. If this is not the case, a new Windows user could be created to solve this problem.\n\n4) ALIEN needs ": "Windows user that contains no non-English characters. If this is not the case, a new Windows user could be created to solve this problem.\n\n4) ALIEN needs ", + "World": "World", + "World size": "World size", + "Your input contains not allowed characters.": "Your input contains not allowed characters.", + "Zone": "Zone", + "Zoom factor": "Zoom factor", + "Zoom in": "Zoom in", + "Zoom level for cell activity": "Zoom level for cell activity", + "Zoom out": "Zoom out", + "Zoom sensitivity": "Zoom sensitivity", + "[cell color]": "[cell color]", + "[target cell color]": "[target cell color]", + "account).\n\n": "account).\n\n", + "action.\n\n": "action.\n\n", + "activated (see tooltip there). The coloring is as follows: blue = creature with low bonus (usually small or simple genome structure), red = large ": "activated (see tooltip there). The coloring is as follows: blue = creature with low bonus (usually small or simple genome structure), red = large ", + "activates injector\n\n": "activates injector\n\n", + "aiming to reduce the angle. Conversely, if the actual angle is smaller, the tangential forces tend to enlarge this angle. With this type of force ": "aiming to reduce the angle. Conversely, if the actual angle is smaller, the tangential forces tend to enlarge this angle. With this type of force ", + "alien": "alien", + "alien-project's workspace": "alien-project's workspace", + "appropriately. On the other hand, it is also possible to define custom geometries by setting an angle between predecessor and ": "appropriately. On the other hand, it is also possible to define custom geometries by setting an angle between predecessor and ", + "are created. However, this can pose a challenge because the constructed cells need time to fold into their desired positions. If the ": "are created. However, this can pose a challenge because the constructed cells need time to fold into their desired positions. If the ", + "are guided by the reference angles encoded in the cells. With this setting, it is optionally possible to specify that the reference angles must only ": "are guided by the reference angles encoded in the cells. With this setting, it is optionally possible to specify that the reference angles must only ", + "artificially created by the user.\n\n": "artificially created by the user.\n\n", + "attacker\n\n": "attacker\n\n", + "attacker cells, etc.": "attacker cells, etc.", + "attacking its creator.": "attacking its creator.", + "be multiples of certain values. This allows for greater stability of the created networks, as the angles would otherwise be more susceptible to ": "be multiples of certain values. This allows for greater stability of the created networks, as the angles would otherwise be more susceptible to ", + "bending in muscle cells.": "bending in muscle cells.", + "bias_j), where sigma denotes the activation function.": "bias_j), where sigma denotes the activation function.", + "bonus\n\n": "bonus\n\n", + "by 180 degrees for convenience. In other words, a value of 0 actually corresponds to an angle of 180 degrees, i.e. a straight ": "by 180 degrees for convenience. In other words, a value of 0 actually corresponds to an angle of 180 degrees, i.e. a straight ", + "cell function is executed, an input signal will firstly be calculated. This involves reading the signals of all connected cells ": "cell function is executed, an input signal will firstly be calculated. This involves reading the signals of all connected cells ", + "cell id is displayed here in hexadecimal notation.": "cell id is displayed here in hexadecimal notation.", + "cell network.\n\n": "cell network.\n\n", + "cell networks can fold back into a desired shape after deformation.": "cell networks can fold back into a desired shape after deformation.", + "cell, input cell, and the nearest connected cell clockwise from the muscle cell.": "cell, input cell, and the nearest connected cell clockwise from the muscle cell.", + "cell, where energy is required for each new cell. Once a new cell is generated, it is connected to the already constructed ": "cell, where energy is required for each new cell. Once a new cell is generated, it is connected to the already constructed ", + "cells is collected and transferred to other cells in the vicinity. A cell has excess energy when it exceeds a defined normal value (see ": "cells is collected and transferred to other cells in the vicinity. A cell has excess energy when it exceeds a defined normal value (see ", + "cells or extends the injection duration for injector cells.": "cells or extends the injection duration for injector cells.", + "close proximity to the target cell for a certain minimum duration, and, in the case of a target constructor cell, its construction process ": "close proximity to the target cell for a certain minimum duration, and, in the case of a target constructor cell, its construction process ", + "closest match.\n\n": "closest match.\n\n", + "complexity measurement' expert settings. By default, it is the number of encoded cells in the genome.": "complexity measurement' expert settings. By default, it is the number of encoded cells in the genome.", + "concatenation). A value of infinity is also possible, but should not be used for an activated completeness check (see simulation parameters).": "concatenation). A value of infinity is also possible, but should not be used for an activated completeness check (see simulation parameters).", + "configured to use your high-performance graphics card. On Windows you need to access the 'Graphics settings,' add 'alien.exe' to the list, click ": "configured to use your high-performance graphics card. On Windows you need to access the 'Graphics settings,' add 'alien.exe' to the list, click ", + "connected and connected-connected cells.\n\n": "connected and connected-connected cells.\n\n", + "connected to the CUDA-powered card. ALIEN uses the same graphics card for computation as well as rendering and chooses the one ": "connected to the CUDA-powered card. ALIEN uses the same graphics card for computation as well as rendering and chooses the one ", + "connected to the constructor cell and consists of repetitions of the encoded cell network.": "connected to the constructor cell and consists of repetitions of the encoded cell network.", + "connection check failed, completeness check failed), 1 (next cell construction successful)": "connection check failed, completeness check failed), 1 (next cell construction successful)", + "connections' = 2 means that the cell to be ": "connections' = 2 means that the cell to be ", + "constructed will only be created when there are at least 2 already constructed cells (excluding the predecessor cell) available for ": "constructed will only be created when there are at least 2 already constructed cells (excluding the predecessor cell) available for ", + "constructor next cell, e.g. no energy, required connection check failed, completeness check failed), 1 (next cell construction ": "constructor next cell, e.g. no energy, required connection check failed, completeness check failed), 1 (next cell construction ", + "created, the construction process will pause until the next triggering.": "created, the construction process will pause until the next triggering.", + "current spatial location of the constructor cell is unfavorable, the newly formed cell might not be connected to the desired cells, ": "current spatial location of the constructor cell is unfavorable, the newly formed cell might not be connected to the desired cells, ", + "define that green cells are particularly good at absorbing energy particles, while other cell colors are better at attacking foreign cells.\nOn the ": "define that green cells are particularly good at absorbing energy particles, while other cell colors are better at attacking foreign cells.\nOn the ", + "describe additional body parts or branching of the creature, for instance. Furthermore, sub-genomes can in turn possess further ": "describe additional body parts or branching of the creature, for instance. Furthermore, sub-genomes can in turn possess further ", + "detected object (if the parameter 'Movement toward target' is activated) or to the direction of the adjacent cell where the input signal comes from ": "detected object (if the parameter 'Movement toward target' is activated) or to the direction of the adjacent cell where the input signal comes from ", + "detected target by a sensor cell (if the parameter 'Movement toward target' is activated) or to the direction of the adjacent cell where the input ": "detected target by a sensor cell (if the parameter 'Movement toward target' is activated) or to the direction of the adjacent cell where the input ", + "differs from the sign of channel #0, no acceleration will be obtained during the bending process.\n\n ": "differs from the sign of channel #0, no acceleration will be obtained during the bending process.\n\n ", + "direction is specified as an angle.": "direction is specified as an angle.", + "directory. This should normally be the case.\n\n5) If you have multiple graphics cards, please check that your primary monitor is ": "directory. This should normally be the case.\n\n5) If you have multiple graphics cards, please check that your primary monitor is ", + "distance, the cells attract each other. If it is smaller, they repel.": "distance, the cells attract each other. If it is smaller, they repel.", + "during the bending process.": "during the bending process.", + "effects can be best observed in the preview of the genome editor.": "effects can be best observed in the preview of the genome editor.", + "energy\n\n": "energy\n\n", + "every 6 time steps.": "every 6 time steps.", + "execution number of the current cell. For this purpose, each channel from #0 to #7 of those cells is summed and the result is written ": "execution number of the current cell. For this purpose, each channel from #0 to #7 of those cells is summed and the result is written ", + "external influences. Choosing 60 degrees is recommended here, as it allows for the accurate representation of most geometries.": "external influences. Choosing 60 degrees is recommended here, as it allows for the accurate representation of most geometries.", + "features.\n\n": "features.\n\n", + "follow a modulo 6 logic. For example, a cell with an execution number of 0 will be executed at time points 0, 6, 12, 18, etc. A cell ": "follow a modulo 6 logic. For example, a cell with an execution number of 0 will be executed at time points 0, 6, 12, 18, etc. A cell ", + "for example, from attacker cells to constructor cells.": "for example, from attacker cells to constructor cells.", + "for instance, due to being too far away. An better approach would involve delaying the construction process until a desired number of ": "for instance, due to being too far away. An better approach would involve delaying the construction process until a desired number of ", + "force generated to push the cell network to its reference configuration.": "force generated to push the cell network to its reference configuration.", + "fully constructed. Disabling this property is useful for encoding growing structures (such as plant-like species) or creature body ": "fully constructed. Disabling this property is useful for encoding growing structures (such as plant-like species) or creature body ", + "genome": "genome", + "genomes": "genomes", + "here:\n\n": "here:\n\n", + "infinity": "infinity", + "inject its genome into another own constructor cell (e.g. to build a spore). In this mode the injection process does not take any ": "inject its genome into another own constructor cell (e.g. to build a spore). In this mode the injection process does not take any ", + "input signal originates (it does not have to be an adjacent cell). A value of -0.5 correspond to -180 deg and +0.5 to +180 deg.": "input signal originates (it does not have to be an adjacent cell). A value of -0.5 correspond to -180 deg and +0.5 to +180 deg.", + "installation directory (including the parent directories) should not contain non-English characters. If this is not fulfilled, ": "installation directory (including the parent directories) should not contain non-English characters. If this is not fulfilled, ", + "is completed, the cells briefly enter the 'Activating' state before transitioning to the 'Ready' state shortly after. If a cell ": "is completed, the cells briefly enter the 'Activating' state before transitioning to the 'Ready' state shortly after. If a cell ", + "is decreasing after each executing until it reaches 0. After that the detonator cell will explode and the surrounding cells are highly accelerated.": "is decreasing after each executing until it reaches 0. After that the detonator cell will explode and the surrounding cells are highly accelerated.", + "is recommended not to choose a password that is used elsewhere.": "is recommended not to choose a password that is used elsewhere.", + "its organism where the constructor cell for self-replication is located. However, if a non-dying cell for self-replication is still present, a detached cell will ": "its organism where the constructor cell for self-replication is located. However, if a non-dying cell for self-replication is still present, a detached cell will ", + "must not have started yet.\n\n": "must not have started yet.\n\n", + "neighboring cells from the same genome are in the direct vicinity. This number of cells can be optionally set here.\n For example, 'required ": "neighboring cells from the same genome are in the direct vicinity. This number of cells can be optionally set here.\n For example, 'required ", + "network is in a dormant state. This is especially useful when the offspring should not become active immediately, for example, to prevent it from ": "network is in a dormant state. This is especially useful when the offspring should not become active immediately, for example, to prevent it from ", + "network is in the process of dying, its cells are in the 'Dying' state.\n\n": "network is in the process of dying, its cells are in the 'Dying' state.\n\n", + "network. If multiple such transmitter cells are present at certain distances, energy can be transmitted over greater distances, ": "network. If multiple such transmitter cells are present at certain distances, energy can be transmitted over greater distances, ", + "none is set, the cell can receive no input signals.": "none is set, the cell can receive no input signals.", + "normal cells and energy particles bounce off from indestructible ones.": "normal cells and energy particles bounce off from indestructible ones.", + "of 6 (which is a complete execution cycle). This means that a value of 1 indicates that the constructor cell will be activated ": "of 6 (which is a complete execution cycle). This means that a value of 1 indicates that the constructor cell will be activated ", + "of cell functions. A muscle cell, for instance, requiring input from a neuron cell, should then be executed some time steps later.": "of cell functions. A muscle cell, for instance, requiring input from a neuron cell, should then be executed some time steps later.", + "of the last match (0 = far away, 1 = close)\n\n": "of the last match (0 = far away, 1 = close)\n\n", + "or, in the case of other OS, in 'settings.json' on your local machine.": "or, in the case of other OS, in 'settings.json' on your local machine.", + "other hand, cell color also plays a role in perception. Sensor cells are dedicated to a specific color and can only detect the corresponding cells.": "other hand, cell color also plays a role in perception. Sensor cells are dedicated to a specific color and can only detect the corresponding cells.", + "output signals. The process for updating a cell signal is performed in two steps:\n\n1) When a ": "output signals. The process for updating a cell signal is performed in two steps:\n\n1) When a ", + "over greater distances, for example, from attacker cells to constructor cells.": "over greater distances, for example, from attacker cells to constructor cells.", + "parts.": "parts.", + "please re-install ALIEN to a suitable directory. Do not move the files manually. If you use Windows, make also sure that you install ALIEN with a ": "please re-install ALIEN to a suitable directory. Do not move the files manually. If you use Windows, make also sure that you install ALIEN with a ", + "potential connections. If the condition is not met, the construction process is postponed.": "potential connections. If the condition is not met, the construction process is postponed.", + "prediction without using the physics engine.": "prediction without using the physics engine.", + "process information, muscle cells that perform movements, and so on. These various cell functions often require input signals and produce ": "process information, muscle cells that perform movements, and so on. These various cell functions often require input signals and produce ", + "reference distance to the input cell.\n\n": "reference distance to the input cell.\n\n", + "repetitions. This value indicates the index of the current repetition.": "repetitions. This value indicates the index of the current repetition.", + "scan will be performed in the direction derived from the input cell (the cell from which the input signal originates) ": "scan will be performed in the direction derived from the input cell (the cell from which the input signal originates) ", + "segment.": "segment.", + "self-replication process, but by transformation from an energy particle.": "self-replication process, but by transformation from an energy particle.", + "sensitivity of the sensor. Typically, very few cells of the corresponding color are already detected with a value of 0.1.": "sensitivity of the sensor. Typically, very few cells of the corresponding color are already detected with a value of 0.1.", + "sensor\n\n": "sensor\n\n", + "settings).\n\n": "settings).\n\n", + "sigma(sum_i (input_i * weight_ji) + bias_j),\nwhere sigma stands for the activation function (different choices are available).": "sigma(sum_i (input_i * weight_ji) + bias_j),\nwhere sigma stands for the activation function (different choices are available).", + "sign of this value alternates at specific time intervals. This can be used, for example, to easily create signals for back-and-forth movements or ": "sign of this value alternates at specific time intervals. This can be used, for example, to easily create signals for back-and-forth movements or ", + "signal comes from (if the parameter 'Movement toward target' is deactivated). A value of -0.5 correspond to -180 deg and +0.5 to +180 deg.": "signal comes from (if the parameter 'Movement toward target' is deactivated). A value of -0.5 correspond to -180 deg and +0.5 to +180 deg.", + "signals received from their input.": "signals received from their input.", + "sim": "sim", + "sims": "sims", + "simulation": "simulation", + "simulation parameter 'Normal energy' in 'Cell life cycle'). Transmitter cells do not need an activation but they can transport ": "simulation parameter 'Normal energy' in 'Cell life cycle'). Transmitter cells do not need an activation but they can transport ", + "solely utilized for acceleration due to bending. If the sign of channel #1 differs from the sign of channel #0, no acceleration will be obtained ": "solely utilized for acceleration due to bending. If the sign of channel #1 differs from the sign of channel #0, no acceleration will be obtained ", + "space. This angle specifies the deviation from that rule.": "space. This angle specifies the deviation from that rule.", + "specific threshold (refer to the 'Injection time' simulation parameter), the injection process is completed.": "specific threshold (refer to the 'Injection time' simulation parameter), the injection process is completed.", + "sub-sub-genomes, etc. To insert a sub-genome here by clicking on 'Paste', one must have previously copied one to the clipboard. ": "sub-sub-genomes, etc. To insert a sub-genome here by clicking on 'Paste', one must have previously copied one to the clipboard. ", + "successful)\n\n": "successful)\n\n", + "successor cells for each cell (except for the first and last in the sequence).": "successor cells for each cell (except for the first and last in the sequence).", + "support attacked cells. The energy transport works as follows: A part of the excess energy of the own cell and the directly connected ": "support attacked cells. The energy transport works as follows: A part of the excess energy of the own cell and the directly connected ", + "take action. All cell functions have in common that they obtain the input from connected cells whose execution number matches the input ": "take action. All cell functions have in common that they obtain the input from connected cells whose execution number matches the input ", + "target. The direction of movement is specified relative to the target.\n\n": "target. The direction of movement is specified relative to the target.\n\n", + "than 1, the cell network geometry has to fulfill certain requirements (e.g. rectangle, hexagon, loop and lolli geometries are not suitable for ": "than 1, the cell network geometry has to fulfill certain requirements (e.g. rectangle, hexagon, loop and lolli geometries are not suitable for ", + "that are subject to different rules. For this purpose, the simulation parameters can be specified depending on the color. For example, one could ": "that are subject to different rules. For this purpose, the simulation parameters can be specified depending on the color. For example, one could ", + "that it also generates a signal in channel #0 at regular intervals. This can be used to trigger other sensor cells, ": "that it also generates a signal in channel #0 at regular intervals. This can be used to trigger other sensor cells, ", + "the calculated signal as input. The cell then provides an output in form of an output signal.\n\nSetting an 'input execution number' is optional. If ": "the calculated signal as input. The cell then provides an output in form of an output signal.\n\nSetting an 'input execution number' is optional. If ", + "the clipboard. If you want to create self-replication, you must not insert a sub-genome; instead, you switch it to the ": "the clipboard. If you want to create self-replication, you must not insert a sub-genome; instead, you switch it to the ", + "the constructor cell and consists of repetitions of the encoded cell network.": "the constructor cell and consists of repetitions of the encoded cell network.", + "the execution of a cell function, some channels will be then overriden by the output of the corresponding cell function.\n\nIMPORTANT: If ": "the execution of a cell function, some channels will be then overriden by the output of the corresponding cell function.\n\nIMPORTANT: If ", + "the input from channel #0 to #7 and provides the output to those channels. More precisely, the output of each neuron calculates as\noutput_j := ": "the input from channel #0 to #7 and provides the output to those channels. More precisely, the output of each neuron calculates as\noutput_j := ", + "the logged-in user.": "the logged-in user.", + "the opposite action.\n\n": "the opposite action.\n\n", + "them. The gained energy is then distributed in the own cell network.\n\n": "them. The gained energy is then distributed in the own cell network.\n\n", + "then create a GitHub issue on https://github.com/chrxh/alien/issues where the log.txt is attached.": "then create a GitHub issue on https://github.com/chrxh/alien/issues where the log.txt is attached.", + "there are multiple such cells) and thus directly providing it as input to other cells. Independently of this, one can specify ": "there are multiple such cells) and thus directly providing it as input to other cells. Independently of this, one can specify ", + "there is signal in channel #0.\n\n": "there is signal in channel #0.\n\n", + "threshold (refer to the 'Minimum energy' simulation parameter).": "threshold (refer to the 'Minimum energy' simulation parameter).", + "threshold activates constructor (only necessary in 'Manual' mode)\n\n": "threshold activates constructor (only necessary in 'Manual' mode)\n\n", + "time.\n\n": "time.\n\n", + "to create it.": "to create it.", + "to the channel from #0 to #7 of the current cell. In particular, if there is only one input cell, its signal is simply forwarded. After ": "to the channel from #0 to #7 of the current cell. In particular, if there is only one input cell, its signal is simply forwarded. After ", + "towards the sensor cell.": "towards the sensor cell.", + "transition into the 'Reviving' state and then into 'Ready' state shortly after.": "transition into the 'Reviving' state and then into 'Ready' state shortly after.", + "transmitter cells. \n\n": "transmitter cells. \n\n", + "triangle or hexagon). Then, the cells encoded in the genome are generated along this geometry and connected together ": "triangle or hexagon). Then, the cells encoded in the genome are generated along this geometry and connected together ", + "value in the database. If the toggle 'Remember' is activated, the password will be stored in the Windows registry under the path 'HKEY_CURRENT_USER\\SOFTWARE\\alien' ": "value in the database. If the toggle 'Remember' is activated, the password will be stored in the Windows registry under the path 'HKEY_CURRENT_USER\\SOFTWARE\\alien' ", + "values have a special meaning:\n\n": "values have a special meaning:\n\n", + "vironment ?": "vironment ?", + "visible to all users.\n\n": "visible to all users.\n\n", + "whose 'execution number' matches the specified 'input execution number' and summing their values up.\n\n2) The cell function is executed and can use ": "whose 'execution number' matches the specified 'input execution number' and summing their values up.\n\n2) The cell function is executed and can use ", + "with an execution number of 1 will be shifted by one, i.e. executed at 1, 7, 13, 19, etc. This time offset enables the orchestration ": "with an execution number of 1 will be shifted by one, i.e. executed at 1, 7, 13, 19, etc. This time offset enables the orchestration ", + "with the highest compute capability.\n\n6) If you possess both integrated and dedicated graphics cards, please ensure that the alien-executable is ": "with the highest compute capability.\n\n6) If you possess both integrated and dedicated graphics cards, please ensure that the alien-executable is ", + "within a radius of several 100 units). The scan radius can be adjusted via a simulation parameter (see 'Range' in the sensor ": "within a radius of several 100 units). The scan radius can be adjusted via a simulation parameter (see 'Range' in the sensor ", + "within the same cell network. If multiple such transmitter cells are present at certain distances, energy can be transmitted ": "within the same cell network. If multiple such transmitter cells are present at certain distances, energy can be transmitted ", + "workspace contains simulations that come along with the released versions. They cover a wide range and exploit different ": "workspace contains simulations that come along with the released versions. They cover a wide range and exploit different ", + "write access to its own ": "write access to its own ", + "you choose a cell function, this tooltip will be updated to provide more specific information. ": "you choose a cell function, this tooltip will be updated to provide more specific information. " +} \ No newline at end of file diff --git a/source/Gui/translations/zh.json b/source/Gui/translations/zh.json index 9e26dfeeb..31d7b9830 100644 --- a/source/Gui/translations/zh.json +++ b/source/Gui/translations/zh.json @@ -1 +1,1198 @@ -{} \ No newline at end of file +{ + " Activated: The countdown is decreased until 0 each time the detonator is executed. If the countdown is 0, the detonator will explode.\n\n": "在此可配置基因组中编码的细胞网络在完全构建后是否应与构建细胞分离。", + " All Cells: In this mode there are no restrictions, e.g. any other constructor or injector cell can be infected. ": "要在此处通过点击'Paste'插入子基因组,必须事先将一个基因组复制到剪贴板。", + " Anti-attacker: reduces the attack strength of an enemy attacker cell\n\n": "此值设置整个编码细胞网络的刚度。刚度决定了将细胞网络推送到其参考配置时产生的力的大小。", + " Attacker: 1 if a cell is attacked by an other attacker cell": "以下细胞功能从通道 #0 获取其输入:\n\n", + " Attacker: a value which is proportional to the gained ": "能量成比例的值\n\n", + " Attacker: abs(value) > threshold activates attacker\n\n": "激活注射细胞\n\n", + " Automatic: The construction process is automatically triggered at regular intervals. ": "此处可确定扫描过程应在哪个方向进行。角度为 0 表示", + " Bending: Increases (or decreases) the angle between the muscle ": "另一方面,也可以通过为每个细胞(序列中的第一个和最后一个除外)设置前驱细胞和后继细胞之间的角度来定义自定义几何形状。", + " Connected cells: ": "默认情况下,当构建细胞开始新的构建时,新细胞会在可用空间最大的区域中创建。", + " Connected cells: In this case the energy will be distributed evenly across all ": " 复杂度较低的突变体:具有较低复杂度基因组的细胞。复杂度计算可以在模拟参数的'Genome complexity measurement'专家设置中自定义。默认情况下,它是基因组中编码的细胞数量。\n\n", + " Constructor: 0 (could not ": " 构建细胞:0(无法", + " Constructor: abs(value) > ": "阈值激活构建器(仅在'手动'模式下需要)\n\n", + " Detonator: abs(value) > threshold activates detonator": " 肌肉细胞:该通道仅用于", + " Expansion and contraction: Causes an elongation (or contraction) of the ": "基因组描述了一个连接细胞网络。一方面,可以选择预定义的几何形状(例如", + " Exploded: The detonator is already exploded.": "禁用此属性对于编码生长结构(如植物类物种)或生物身体部位很有用。", + " Free cells: Cells that were not created by reproduction but by the conversion of energy particles (they could serve as free food).\n\n": "(例如,构建孢子)。在此模式下,注射过程不需要任何时间。\n\n", + " Handcrafted constructs: Cells that were created in the editor (e.g. walls).\n\n": " 所有细胞:在此模式下没有限制,例如任何其他构建细胞或注射细胞都可以被感染。", + " Injector: 0 (no cells found) or 1 (injection in process or completed)\n\n": " 重连细胞:0(未创建/移除连接)或 1(已创建/移除连接)", + " Injector: abs(value) > threshold ": " 肌肉细胞:运动、弯曲或扩张/收缩的强度。负号对应相反的动作。\n\n", + " Input channel ": " 输入通道 #3:该通道用于运动模式下的肌肉。它编码相对于检测到的物体(如果参数 'Movement toward target' 被激活)", + " Input channel #0: abs(value) > threshold activates ": "与目标细胞保持足够近的距离达到一定最短时间,并且对于目标构建细胞,其构建过程", + " Input channel #0: abs(value) > threshold activates constructor (only necessary in ": "传感器细胞扫描其环境以寻找特定颜色细胞的浓度,并返回最近匹配细胞的距离和角度。", + " Input channel #0: abs(value) > threshold activates injector\n\n": "#0:运动、弯曲或扩张/收缩的强度。负号表示相反的动作。\n\n", + " Input channel #0: abs(value) > threshold activates sensor\n\n": " 输出通道 #2:最近匹配", + " Input channel #0: value > threshold triggers creation of a bond to a cell in the vicinity, value < -threshold triggers destruction of a bond\n\n": "为此,这些细胞的每个通道 #0 到 #7 的值被求和,结果写入当前细胞的通道 #0 到 #7。", + " Input channel #1: This channel is solely utilized for acceleration due to bending. If the sign of channel #1 ": "防御细胞不需要激活。它的存在可以降低涉及攻击细胞的敌方攻击强度,", + " Input channel #3: This channel is used for muscles in movement mode. It encodes the relative angle for the movement with respect to a ": "重连细胞可以创建或断开与指定颜色的其他细胞(具有不同生物 ID)的连接。\n\n", + " Less complex mutants: Cells that have a less complex genome. The complexity calculation can be customized in the simulation parameters under the 'Genome complexity measurement' expert settings. By default, it is the number of encoded cells in the genome.\n\n": "注射过程的持续时间取决于模拟参数'Injection time'。", + " More complex mutants: Cells that have a more complex genome.\n\n": " 向传感器目标移动:如果输入信号源自之前检测到目标的传感器细胞,则可以执行移动。", + " Movement to sensor target: A movement can be performed if the input signal has its origin in a sensor cell which has previously detected a ": "剪贴板。如果您想创建自我复制,则不得插入子基因组;相反,应将其切换到", + " Muscle: The strength of the movement, bending or expansion/contraction. A negative sign corresponds to ": " 引爆细胞:abs(值) > 阈值激活引爆细胞", + " Muscle: This channel is ": " 神经元", + " Muscle: This channel is used for muscles in movement mode. It encodes the relative angle for the movement with respect to a previously ": " 神经元", + " Neuron": "以下细胞功能将其输出写入通道 #5:\n\n", + " Neuron\n\n": " 神经元\n\n", + " None: No further restriction.\n\n": "如果在特定距离上存在多个这样的传递细胞,能量可以传输到更远的距离,", + " Only empty cells: Only cells which possess an empty genome can be infected. This mode is useful when an organism wants to ": "倒计时指定引爆细胞爆炸前的周期数(以 6 个时间步为单位)。", + " Other mutants: Cells that have a significantly different genome.\n\n": " 仅空细胞:只有拥有空基因组的细胞可以被感染。此模式在生物想要将其基因组注入自己的另一个构建细胞时很有用", + " Output channel #0: ": "的距离(0 = 远,1 = 近)\n\n", + " Output channel #0: 0 (could not constructor next cell, e.g. no energy, required ": " 输入通道 #0:abs(值) > 阈值激活传感器\n\n", + " Output channel #0: 0 (no cells found) or 1 (injection in process or completed)": " 输入通道 #1:该通道仅用于弯曲引起的加速度。如果通道 #1 ", + " Output channel #0: 0 (no connection created/removed) or 1 (connection created/removed)": "特别地,如果只有一个输入细胞,其信号将被简单地转发。", + " Output channel #0: a value which is proportional to the gained energy": " 输入通道 #0:abs(值) > 阈值激活注射细胞\n\n", + " Output channel #1: density of the last match\n\n": "默认情况下,神经细胞将来自连接细胞的信号转发(如果有多个此类信号则求和),", + " Output channel #2: distance ": "从而直接将其作为输入提供给其他细胞。除此之外,可以指定", + " Output channel #3: angle of the last match": "攻击细胞等。", + " Ready: The detonator cell waits for input on channel #0. If abs(value) > threshold, the detonator will be activated.\n\n": "此值描述两个串联细胞网络之间从前一个网络的最后一个细胞观察时的角度。", + " Reconnector: 0 (no connection created/removed) or 1 (connection created/removed)": "以下细胞功能将其输出写入通道 #1:\n\n", + " Reconnector: value > threshold triggers creation of a bond to a cell in the vicinity, value < -threshold triggers destruction of a bond\n\n": " 神经元\n\n", + " Same mutants: Cells that have a related genome.\n\n": "例如,从攻击细胞到构建细胞。", + " Scan specific direction: In this mode, the scanning process is restricted to a particular direction. The ": "默认情况下,生成的脉冲由通道 #0 中的正值组成。当启用'交替脉冲'时,", + " Scan vicinity: In this mode, the entire nearby area is scanned (typically ": "激活后,传感器仅检测距离小于或等于指定值的对象。", + " Sensor: 0 (no match) or 1 (match)\n\n": " 攻击细胞:与获得", + " Sensor: abs(value) > threshold activates ": " 攻击细胞:abs(值) > 阈值激活攻击细胞\n\n", + " Sensor: angle of the last match": "以下细胞功能将其输出写入通道 #4:\n\n", + " Sensor: density of the last match": "以下细胞功能将其输出写入通道 #2:\n\n", + " Sensor: distance of the last match (0 = far away, 1 = close)": "以下细胞功能将其输出写入通道 #3:\n\n", + " Transmitters and constructors: ": "此值决定从最后一个构建的细胞到倒数第二个构建的细胞和构建细胞之间的角度。", + " Transmitters and constructors: Here, the energy will be transferred to spatially nearby constructors or other transmitter cells ": " 就绪:引爆细胞等待通道 #0 上的输入。如果 abs(值) > 阈值,引爆细胞将被激活。\n\n", + " alien-project: This ": "当此参数增加时,基因组复杂度较低的细胞将从传入的能量粒子中吸收更少的能量。", + " considering the weights and bias in order to calculate the neuron's output, i.e., output_j = sigma(sum_i (input_i * weight_ji) + bias_j), where sigma": " 自动:构建过程按固定时间间隔自动触发。不需要通道 #0 中的信号。\n\n 在这两种情况下,如果被创建的细胞没有足够的可用能量,", + " denotes the activation function. The following choices for sigma are available:\n\n": "构建过程将暂停,直到下一次触发。", + " file, name and description are stored on the server. It cannot be guaranteed that the data will not be deleted.": "文件、名称和描述存储在服务器上。无法保证数据不会被删除。", + " name": "名称", + " save points": " 个存档点", + " will be uploaded there.": "将上传到该文件夹。", + " will be visible to all users. If false, the ": "将对所有用户可见。如果禁用,该", + " will only be visible in the private workspace. This property can also be changed later if desired.": "将仅在私有工作区可见。此属性以后也可以更改。", + " with the one that is currently open. The name, description and reactions will be preserved.": "。名称、描述和反应将被保留。", + " your user name or email address is already in use,\n": " 您的用户名或电子邮件地址已被使用,\n", + "#0: The strength of the movement, bending or expansion/contraction. A negative sign corresponds to the opposite ": "或相对于输入信号来源的相邻细胞方向(如果参数 'Movement toward target' 未激活)的运动相对角度。", + "' has been deleted.\nYou are logged out.": "' 已被删除。\n您已退出登录。", + "' will be deleted on the server side.\nThese include the likes, the simulations and the account data.": "' 的所有数据将在服务器端被删除。\n这包括点赞、模拟和账户数据。", + "'HKEY_CURRENT_USER\\SOFTWARE\\alien' or, in the case of other OS, in 'settings.json' on your local machine. It ": "Sigmoid函数", + "'Options,' and choose 'High performance'.\n\nIf these conditions are not met, ALIEN may crash unexpectedly.\n\n": "该功能为细胞配备了一个由 8 个神经元组成的小型网络,具有 8x8 个可配置权重、8 个偏置值和激活函数。它处理", + "'s private workspace": " 的私人工作区", + "'self-copy' mode. In this case, the constructor's sub-genome refers to its superordinate genome.": "参考角度定义了两个细胞连接之间的角度。如果实际角度更大,则切向力作用于连接的细胞上,旨在减小角度。", + "'stick together' with other cell networks after collision.": "或者在其它操作系统上存储在本地机器的 'settings.json' 中。", + "(if the parameter 'Movement toward target' is deactivated). In the first case, the object must have been targeted by a sensor cell from which the ": " 输出通道 #0:0(未创建/移除连接)或 1(已创建/移除连接)", + "0 (no match) or 1 (match)\n\n": " 输出通道 #3:最近匹配的角度", + "120 deg": "120度", + "180 deg": "180度", + "60 deg": "60度", + "72 deg": "72度", + "90 deg": "90度", + "A constructor cell builds a cell network according to a contained genome. The construction process takes place cell by ": "'手动'模式下需要)\n\n", + "A defender cell does not need to be activated. Its presence reduces the strength of an enemy attack involving attacker ": "在每次执行后递减,直到达到 0。之后引爆细胞会爆炸,周围的细胞会被高度加速。", + "A detonator cell will be activated if it receives an input on channel #0 with abs(value) > threshold. Then its counter ": "在执行细胞功能后,一些通道将被相应细胞功能的输出覆盖。\n\n重要提示:如果您选择了一个细胞功能,", + "A functioning organism requires cells to collaborate. This can involve sensor cells that perceive the environment, neuron cells that ": "可以选择在此处设置此细胞数量。\n 例如,'required connections' = 2 意味着要构建的细胞", + "A genome describes a network of connected cells. On the one hand, there is the option to select a pre-defined geometry (e.g. ": "相反,如果实际角度更小,则切向力倾向于增大此角度。通过这种力,细胞网络在变形后可以折叠回期望的形状。", + "A high frame rate leads to a greater GPU workload for rendering and thus lowers the simulation speed (time steps per second).": "高帧率会增加 GPU 渲染负载,从而降低仿真速度(每秒时间步数)。", + "A high value protects new mutants with equal or greater genome complexity from being attacked.": "较高值保护具有相同或更高基因组复杂度的新突变体免受攻击。", + "A pattern is a set of cell networks and energy particles.": "细胞特定参数", + "A reconnector cell can make or break a cell connection to an other cell (with a different creature id) with a specified color. \n\n": "它们从执行序号与当前细胞输入执行序号匹配的连接细胞处获取输入。", + "ALIEN is an artificial life and physics simulation tool based on a CUDA-powered 2D particle engine for soft bodies and fluids.": "ALIEN 是一款基于 CUDA 加速的二维粒子引擎的人工生命与物理模拟工具,专为软体和流体设计。", + "About": "关于", + "Absolute value": "工作区包含随发布版本附带的模拟。它们覆盖了广泛的范围并利用了不同的功能。\n\n", + "Absorption factor": "吸收因子", + "Accumulate values for all colors": "累计所有颜色值", + "Activate": "激活编辑", + "Activating this toggle, the cell's output will be discarded. This prevents any other cell from utilizing it as input.": "其中 sigma 表示激活函数。", + "Activation function": "激活函数", + "Adaptive space grid": "自适应空间网格", + "Add a reaction": "添加反应", + "Add parameter zone": "添加参数区", + "Add radiation source": "添加辐射源", + "Adopt": "取消", + "Adopt simulation parameters": "采用仿真参数", + "Advanced absorption control": "高级吸收控制", + "Advanced attacker control": "高级攻击控制", + "Affected activation functions": "受影响的激活函数", + "Affected biases": "受影响的偏置", + "Affected weights": "受影响的权重", + "Age": "年龄", + "All cell functions": "所有细胞功能", + "Amount of energy lost by an attempted attack of a cell in form of emitted energy particles.": "细胞尝试攻击时以发射能量粒子形式损失的能量。", + "An ALIEN world is two-dimensional rectangular domain with periodic boundary conditions. The space is modeled as a continuum.": "神经元:为细胞配备了一个由8个神经元组成的小型网络。它处理从连接细胞信号中获得的输入,并为其连接细胞提供输出信号。", + "An attacker cell attacks surrounding cells from other cell networks (with different creature id) by stealing energy from ": " 输出通道 #0:与获得能量成比例的值", + "An error occurred on the server.": "服务器发生错误。", + "An error occurred on the server. This could be related to the fact that\n": "服务器发生错误。这可能是因为\n", + "Analysis result": "分析结果", + "Angle": "角度", + "Angular velocity": "角速度", + "Anti-attacker strength": "反攻击强度", + "Anti-injector strength": "反注射强度", + "Anti-injector: increases the injection duration of an enemy injector cell": "网络中连接细胞的三元组彼此之间具有特定的空间角度。这些角度由细胞中编码的参考角度引导。", + "As a result, you will be able to see the GPU information of other registered users who have shared it.": "绝对值函数", + "Attack radius": "能量消耗", + "Attack strength": "攻击细胞可以攻击其他细胞的最大距离。", + "Attack visualization": "攻击可视化", + "Attacker": "攻击器", + "Attacker cells can distribute the acquired energy through two different methods. The energy distribution is analogous to ": " 自由细胞:不是通过繁殖产生,而是通过能量粒子转化产生的细胞(它们可以作为免费食物)。\n\n", + "Attacker: It attacks surrounding cells from other cell networks by stealing energy from them.": "ALIEN 中的基因组可以描述多个细胞网络,这些网络按层次结构组织,并在构建时可能相互连接。", + "Attacks": "攻击", + "Autosave": "自动保存", + "Autosave interval (min)": "自动保存间隔(分钟)", + "Autotracking on selection": "选中时自动跟踪", + "Background color": "背景颜色", + "Base": "基础", + "Base parameters": "基础参数", + "Basic notion": "基本概念", + "Bending angle": "弯曲加速度", + "Bias": "偏置", + "Binary step": "有三个不同的工作区,您可以在其中找到并可选择上传模拟和基因组:\n\n", + "Binding creation velocity": "连接创建速度", + "Blast radius": "爆炸半径", + "Blocks": "块数量", + "Borderless rendering": "无边界渲染", + "Break down by color": "按颜色分解", + "Brightness": "亮度", + "Browser": "浏览器", + "Build": "构建", + "By default, a nerve cell forwards signals from connected cells (and summing it up if ": "攻击细胞通过窃取能量来攻击来自其他细胞网络(具有不同生物 ID)的周围细胞。", + "By default, cells in the genome sequence are automatically connected to all neighboring cells belonging to the same genome when they ": "有两种方式控制在此设置的能量分配:\n\n", + "By default, the generated pulses consist of a positive value in channel #0. When 'Alternating pulses' is enabled, the ": "以下选项可用于仅绑定到具有特定属性的细胞:\n\n", + "By default, when the constructor cell initiates a new construction, the new cell is created in the area with the most available ": " 复杂度较低的突变体:具有较低复杂度基因组的细胞。复杂度计算可以在模拟参数的'Genome complexity measurement'专家设置中自定义。默认情况下,它是基因组中编码的细胞数量。\n\n", + "CTRL + click on a slider to type in a precise value": "CTRL + 点击滑块可输入精确数值", + "CUDA settings": "CUDA 设置", + "Cancel": "取消", + "Catch peaks": "捕获峰值", + "Cell": "细胞", + "Cell #": "细胞 #", + "Cell Energies": "细胞能量", + "Cell age limiter": "细胞年龄限制器", + "Cell ages": "细胞年龄", + "Cell color": "细胞颜色", + "Cell color transition rules": "细胞颜色过渡规则", + "Cell colors": "细胞颜色", + "Cell connection": "细胞连接", + "Cell count": "细胞数", + "Cell death consequences": "无", + "Cell deletion": "细胞删除", + "Cell distance": "细胞间距", + "Cell function": "细胞功能", + "Cell function type": "细胞功能类型", + "Cell function: Attacker": "细胞功能:攻击器", + "Cell function: Constructor": "细胞功能:构建器", + "Cell function: Defender": "细胞功能:防御器", + "Cell function: Detonator": "细胞功能:引爆器", + "Cell function: Injector": "细胞功能:注射器", + "Cell function: Muscle": "细胞功能:肌肉", + "Cell function: Reconnector": "细胞功能:重连器", + "Cell function: Sensor": "细胞功能:传感器", + "Cell function: Transmitter": "细胞功能:发射器", + "Cell glow": "细胞辉光", + "Cell info overlay": "细胞信息叠加层", + "Cell insertion": "细胞插入", + "Cell life cycle": "细胞生命周期", + "Cell network": "细胞网络", + "Cell properties": "细胞属性", + "Cell radius": "细胞半径", + "Cell specific parameters": "细胞特定参数", + "Cell states": "细胞状态", + "Cells": "细胞", + "Cells can possess a specific function that enables them to, for example, perceive their environment, process information, or ": "此属性定义细胞的颜色。它不仅仅是一个视觉标记。一方面,细胞颜色可用于定义遵循不同规则的自身细胞类型。", + "Center": "居中", + "Center position": "中心位置", + "Center position and velocity": "中心位置与速度", + "Center rotation": "中心旋转", + "Central": "中心", + "Chain explosion probability": "连锁爆炸概率", + "Change color": "更改颜色", + "Change folder name": "更改文件夹名称", + "Change name or description": "修改名称或描述", + "Choose a reaction": "选择反应", + "Circular": "圆形", + "Cleaning up save points ...": "正在清理存档点...", + "Clear": "清除", + "Clockwise": "顺时针", + "Clone selected zone/radiation source": "克隆选中的区/辐射源", + "Close inspections": "关闭检查", + "Collapse all folders": "折叠所有文件夹", + "Collision-based": "基于碰撞", + "Color": "颜色", + "Color #0": "颜色 #0", + "Color #1": "颜色 #1", + "Color #2": "颜色 #2", + "Color #3": "颜色 #3", + "Color #4": "颜色 #4", + "Color #5": "颜色 #5", + "Color #6": "颜色 #6", + "Color inhomogeneity factor": "能量分配值", + "Color transition rule": "颜色转换规则", + "Color transitions": "颜色转换", + "Coloring": "着色", + "Completed injections": "完成注射", + "Completeness check": "完整性检查", + "Complex creature protection": "复杂生物保护", + "Conditional inflow": "\n\n例如,值为 0.6 表示构建器细胞从外部能源获得构建新细胞所需能量的 60%,", + "Connected cells": "已连接的细胞", + "Connection distance": "连接距离", + "Connections mismatch penalty": "能量分配半径", + "Constructor": "构建器", + "Contained energy": "含能量", + "Contraction and expansion delta": "肌肉细胞可缩短或伸长细胞连接的最大长度。此参数仅适用于收缩/伸展模式的肌肉细胞。", + "Contrast": "对比度", + "Convert to destructible cell": "转换为可摧毁细胞", + "Convert to indestructible wall": "转换为不可摧毁墙", + "Copy": "复制", + "Copy pattern": "复制图案", + "Copy simulation parameters to clipboard": "复制仿真参数到剪贴板", + "Core radius": "核心半径", + "Counter clockwise": "逆时针", + "Create a disc-shaped cell network": "创建圆形细胞网络", + "Create a hexagonal cell network": "创建六边形细胞网络", + "Create a rectangular cell network": "创建矩形细胞网络", + "Create a single cell": "创建单个细胞", + "Create a single energy particle": "创建单个能量粒子", + "Create save point": "创建存档点", + "Create user": "创建用户", + "Created cells": "创建细胞", + "Created cells / sec": "创建细胞/秒", + "Created self-replicators / sec": "创建自复制体/秒", + "Creating flashback ...": "正在创建快照...", + "Creating in-memory flashback: It saves the content of the current world to the memory.": "创建内存快照:将当前世界保存到内存中。", + "Creating save point ...": "正在创建存档点...", + "Creator": "创建器", + "Current": "当前", + "Custom geometry": "自定义几何", + "Customize deletion mutations": "自定义删除突变", + "Customize neuron mutations": "自定义神经元突变", + "Damping factor": "若神经网络权重或偏置被突变调整,可被强化、减弱或偏移。此处定义减弱使用的因子。默认为 1.05。", + "Data privacy policy": "数据隐私政策", + "Decay rate of dying cells": "垂死细胞衰变率", + "Defender": "防御器", + "Defender activities": "防御器活动", + "Defender: It reduces the attack strength when another cell in the vicinity performs an attack.": "更准确地说,这意味着存在一个描述特定网络的顶级蓝图。如果此网络中存在更多的构建细胞,", + "Define matrix": "定义矩阵", + "Defines the maximum age of a cell. If a cell exceeds this age it will be transformed to an energy particle.": "定义细胞的最大年龄。超过此年龄后细胞将转化为能量粒子。", + "Delete": "删除", + "Delete Pattern": "删除图案", + "Delete all save points": "删除所有存档点", + "Delete save point": "删除存档点", + "Delete selected ": "删除所选", + "Delete selected zone/radiation source": "删除选中的区/辐射源", + "Delete user": "删除用户", + "Deleting save point ...": "正在删除存档点...", + "Depth level": "神经元因子", + "Description": "描述", + "Description (optional)": "描述(可选)", + "Desktop": "桌面", + "Destroy cells": "摧毁细胞", + "Detached creature parts die": "定义当一个细胞处于「垂死」状态时生物体发生的变化。\n\n", + "Detonation countdown": "引爆倒计时", + "Detonations": "引爆", + "Detonator": "引爆器", + "Detonator: A cell which can explode by a signal. It generates a large amount of kinetic energy for the objects in its surroundings.": "能量粒子由细胞作为辐射或在衰变过程中产生,反之也可以被吸收。", + "Directory": "可以在此处选择存储存档点的目录。这样可以为一次仿真运行在单独的目录中创建存档点。存档点使用当前时间步命名。", + "Disable radiation sources": "禁用辐射源", + "Display settings": "显示设置", + "Diversity": "多样性", + "Do you really want to delete all savepoints?": "确定要删除所有存档点吗?", + "Do you really want to terminate the program?": "确定要退出程序吗?", + "Download": "下载", + "Downloads": "下载", + "Drag and drop": "拖放", + "Draw freehand cell network": "手绘细胞网络", + "Draws a suitable grid in the background depending on the zoom level.": "根据缩放级别在背景中绘制合适的网格。", + "Draws borders along the world before it repeats itself.": "在世界重复自身之前沿边界绘制边框。", + "Draws red crosses in the center of radiation sources.": "在辐射源中心绘制红色十字标记。", + "Drift angle": "漂移角", + "Duplication": "复制", + "Each generated cell has an 'execution order number' that is one greater than the previous generated cell.": "圆盘的外半径(以细胞计)。", + "Each neuron has 8 input channels and produces an output by the formula output_j = sigma((sum_i (input_i * weight_ji) + ": "此值指定构建细胞自动触发的时间间隔。它以 6 的倍数给出(6 为一个完整的执行周期)。", + "Editors": "编辑器", + "Email": "邮箱", + "End drawing": "结束绘制", + "Energy": "能量", + "Energy cost": "能量消耗", + "Energy distribution Value": "能量分配值", + "Energy distribution radius": "能量分配半径", + "Energy particle": "能量粒子", + "Energy particle #": "能量粒子 #", + "Energy particles": "能量粒子", + "Energy to cell transformation": "若激活,当能量粒子的能量超过正常能量值时,它将转化为细胞。", + "Entire creature dies": "分离的生物部分死亡", + "Entire history plots": "全部历史图", + "Error": "错误", + "Error: Savepoint files could not be read or created in the specified directory.": "错误:无法在指定目录读取或创建存档点文件。", + "Evolution simulations": "进化模拟", + "Examples": "示例", + "Exit": "退出", + "Expand all folders": "展开所有文件夹", + "Expert settings": "专家设置", + "Expert settings: Advanced attacker control": "专家设置:高级攻击控制", + "Expert settings: Advanced energy absorption control": "专家设置:高级能量吸收控制", + "Expert settings: Cell age limiter": "专家设置:细胞年龄限制器", + "Expert settings: Cell color transition rules": "专家设置:细胞颜色过渡规则", + "Expert settings: Cell glow": "专家设置:细胞辉光", + "Expert settings: Customize deletion mutations": "专家设置:自定义删除突变", + "Expert settings: Customize neuron mutations": "专家设置:自定义神经元突变", + "Expert settings: External energy control": "专家设置:外部能量控制", + "Expert settings: Genome complexity measurement": "专家设置:基因组复杂度测量", + "Expert settings: Legacy behavior": "专家设置:旧版行为", + "External energy amount": "外部能量量", + "External energy control": "外部能量控制", + "Fade-out radius": "淡出半径", + "Fetch angle from adjacent sensor": "从相邻传感器获取角度", + "Field type": "场类型", + "File size": "文件大小", + "Filter (case insensitive)": "过滤(不区分大小写)", + "First steps": "第一步", + "Fluid dynamics": "流体动力学", + "Fluids, walls and soft bodies": "流体、墙壁和软体", + "Folder name": "文件夹名称", + "Food chain color matrix": "食物链颜色矩阵", + "Force field": "力场", + "Forgot your password?": "忘记密码?", + "Frames per second": "每秒帧数", + "Free cells": "自由细胞", + "Frequently asked questions": "常见问题", + "Friction": "刚性", + "Full screen": "全屏", + "Fusion velocity": "融合速度", + "GPU (visible if logged in)": "GPU(登录后可见)", + "GPU model": "GPU 型号", + "Gaussian": " 公共:所有登录用户都可以与公众分享他们的模拟和基因组。此处存储的文件对所有用户可见。\n\n", + "GeForce 10 series).\n\n2) You have the latest NVIDIA graphics driver installed.\n\n3) The name of the ": "请重新将 ALIEN 安装到合适的目录。不要手动移动文件。如果您使用 Windows,也请确保您安装 ALIEN 的 ", + "General": "通用", + "Generate ascending execution order numbers": "生成升序执行顺序编号", + "Genome": "基因组", + "Genome color": "基因组颜色", + "Genome colors": "基因组颜色", + "Genome complexities": "基因组复杂度", + "Genome complexity\naverage": "基因组复杂度\n平均值", + "Genome complexity\nmaximum": "基因组复杂度\n最大值", + "Genome complexity\nvariance": "基因组复杂度\n方差", + "Genome complexity measurement": "基因组复杂度测量", + "Genome complexity variance": "基因组复杂度方差", + "Genome copy mutations": "基因组复制突变", + "Genome editor": "基因组编辑器", + "Genomes": "基因组", + "Geometry": "几何", + "Geometry penalty": "此参数越大,攻击包含更多连接的细胞就越困难。", + "Getting started": "快速上手", + "Grid multiplier": "网格倍增器", + "Height": "高度", + "Here, one can configure whether the encoded cell network in the genome should be detached from the constructor cell once it has been ": " 标准细胞颜色:每个细胞被分配 7 种默认颜色之一,通过此选项显示。\n\n", + "Here, the energy will be transferred to spatially nearby constructors or other transmitter cells within the same cell ": "其效果可以在基因组编辑器的预览中得到最佳观察。", + "Highlighted cell function": "高亮的细胞功能", + "Histograms": "直方图", + "Horizontal cells": "水平细胞数", + "How does a simple self-replicating organism work?": "简单的自我复制生物是如何工作的?", + "How to create a new user?": "如何创建新用户?", + "How to use or create folders?": "如何使用或创建文件夹?", + "Identity": "恒等", + "If a constructor or injector cell is encoded in a genome, that cell can itself contain another genome. This sub-genome can ": "(请参考'Minimum energy'模拟参数)。", + "If activated, all radiation sources within this zone are deactivated.": "若激活,此区域内的所有辐射源将被禁用。", + "If activated, successful attacks of attacker cells are visualized.": "若激活,攻击细胞的成功攻击将被可视化。", + "If activated, the attacker cell is able to destroy other cells. If deactivated, it only damages them.": "若激活,攻击细胞可以摧毁其他细胞。若禁用,仅对其造成伤害。", + "If activated, the direction in which muscle cells are moving are visualized.": "若激活,肌肉细胞的运动方向将被可视化。", + "If activated, the sensor detects only objects with a distance equal or greater than the specified value.": " 弯曲:增加(或减少)肌肉细胞、输入细胞和从肌肉细胞顺时针方向最近的连接细胞之间的角度。", + "If activated, the sensor detects only objects with a distance equal or less than the specified value.": " 反攻击:降低敌方攻击细胞的攻击强度\n\n", + "If activated, the simulation is rendered periodically in the view port.": "若激活,仿真画面将在视口中周期性渲染。", + "If activated, the transmitter cells can only transfer energy to nearby cells belonging to the same creature.": "若激活,发射器细胞只能将能量传输给属于同一生物的附近细胞。", + "If an attacked cell is connected to defender cells or itself a defender cell the attack strength is reduced by this factor.": "若被攻击细胞连接到防御细胞或自身为防御细胞,攻击强度将按此因子降低。", + "If enabled, a signal in channel #0 will be generated at regular time intervals.": " 反注射:增加敌方注射细胞的注射持续时间", + "If the Sticky property is selected, the created cells can usually form further connections. That is, they can ": "如果激活'记住'开关,密码将存储在 Windows 注册表的 'HKEY_CURRENT_USER\\SOFTWARE\\alien' 路径下,", + "If the attacked cell is connected to cells with different colors, this factor affects the energy of the captured energy.": "攻击细胞可传输到附近发射器、构建器细胞或已连接细胞的能量量。", + "If the conditions are met and the error still occurs, please start ALIEN with the command line parameter '-d', try to reproduce the error and ": "来自通道 #0 到 #7 的输入,并将输出提供给这些通道。更准确地说,每个神经元的输出计算公式为\noutput_j := ", + "If the toggle 'Remember' is activated, the password will be stored in the Windows registry under the path ": "这样,您将能够看到其他已分享的注册用户的 GPU 信息。", + "If this option is enabled, other users will be able to see in the browser window that you have the following graphics card: ": "恒等函数", + "If true, the ": "如果启用,该", + "If you want to upload the ": "如果要上传", + "Image converter": "图像转换器", + "Important": "通过根据细胞颜色进行定制,可以指定不同类型的生物。有许多示例以两个类别为特色:植物和食草动物。", + "In general, the following types of parameters can be set.": "通常,可以设置以下类型的参数。", + "In order to share and upvote simulations you need to log in.": "您需要登录才能分享和点赞仿真。", + "In progress": "进行中", + "In queue": "排队中", + "In this case the energy will be distributed evenly across all connected and connected-connected cells.\n\n": "此角度指定了与该规则的偏差。", + "Include sub-genomes": "包含子基因组", + "Indestructible wall": "不可摧毁墙", + "Indicates how energetic the emitted particles of aged cells are.": "指示老化细胞发射粒子的能量强度。", + "Indicates how energetic the emitted particles of high energy cells are.": "指示高能细胞发射粒子的能量强度。", + "Individual cell color": "单个细胞颜色", + "Inflow only for non-replicators": "能量从仿真回流到外部能量池的比例。每次细胞失去能量或死亡时,其部分能量将被提取。", + "Information": "信息", + "Injection activities": "注射活动", + "Injection radius": "注射半径", + "Injection time": "注射时间", + "Injector": "注射器", + "Injector cells can override the genome of other constructor or injector cells by their own. To do this, they need to be activated, remain in ": " 输出通道 #0:0(未找到细胞)或 1(注射进行中或已完成)", + "Injector: It can infect other constructor cells to inject its own built-in genome.": "基因组", + "Inner radius": "内半径", + "Input #": "输入 #", + "Inspect Objects": "检查对象", + "Inspect objects": "检查对象", + "Inspect principal genome": "检查主基因组", + "Internal energy (may be interpreted as its temperature)": "内部能量(可理解为温度)", + "Introduction": "简介", + "It contains further settings that influence how much energy can be obtained from an attack by attacker cells.": "包含影响攻击细胞攻击所得能量的进一步设置。", + "It enables additional possibilities to control the maximal cell age.": "提供控制最大细胞年龄的额外选项。", + "It enables an additional rendering step that makes the cells glow.": "启用额外的渲染步骤,使细胞发光。", + "It enables further settings for deletion mutations. If disabled, defaults are used (displayed in the tooltip of the specific parameters).": "启用删除突变的进一步设置。若禁用,使用默认值。", + "It enables further settings for neuron mutations. If disabled, defaults are used (displayed in the tooltip of the specific parameters).": "启用神经元突变的进一步设置。若禁用,使用默认值。", + "Layers": "层数", + "Limited save files": "文件数量", + "Linear": "线性", + "Living state": "存活状态", + "Load previous time step": "加载上一个时间步", + "Load save point": "加载存档点", + "Loading previous time step ...": "正在加载上一个时间步...", + "Location": "位置", + "Log": "日志", + "Logarithmic": "对数", + "Login": "登录", + "Login or register": "登录或注册", + "Logout": "退出登录", + "Low connection penalty": "低连接惩罚", + "Low genome complexity penalty": "低基因组复杂度惩罚", + "Low velocity penalty": "低速惩罚", + "Make public": "设为公开", + "Make sticky": "设为粘性", + "Make uniform velocities": "使速度均匀", + "Make unsticky": "取消粘性", + "Mark reference domain": "标记参考域", + "Mass operations": "批量操作", + "Max angle": "最大角度", + "Max angular velocity": "最大角速度", + "Max connections": "最大连接数", + "Max velocity X": "最大速度 X", + "Max velocity Y": "最大速度 Y", + "Maximum age": "最大年龄", + "Maximum collision distance": "摩擦", + "Maximum distance": "最大距离", + "Maximum distance up to which a collision of two cells is possible.": "每次时间步速度被减小的比例。", + "Maximum distance up to which a connection of two cells is possible.": "两个细胞可以建立连接的最大距离。", + "Maximum energy": "最大能量", + "Maximum force": "最大力", + "Maximum force that can be applied to a cell without causing it to disintegrate.": "施加到细胞而不使其崩解的最大力。", + "Maximum inactive cell age": "最大非活动细胞年龄", + "Maximum value": "最大值", + "Maximum velocity": "最大速度", + "Maximum velocity that a cell can reach.": "细胞可以达到的最大速度。", + "Message overlay": "消息叠加层", + "Min angle": "最小角度", + "Min angular velocity": "最小角速度", + "Min velocity X": "最小速度 X", + "Min velocity Y": "最小速度 Y", + "Minimum age": "最小年龄", + "Minimum distance": "最小距离", + "Minimum distance between two cells.": "两个细胞之间的最小距离。", + "Minimum energy": "最小能量", + "Minimum energy a cell needs to exist.": "细胞存活所需的最低能量。", + "Minimum relative velocity of two colliding cells so that a connection can be established.": "两个碰撞细胞建立连接所需的最小相对速度。", + "Minimum size": "最小尺寸", + "Minimum split energy": "最小分裂能量", + "Minimum value": "最小值", + "Mode": "无限存档文件", + "More": "更多", + "Motion blur": "动态模糊", + "Motion type": "运动类型", + "Move selected zone/radiation source downward": "下移选中的区/辐射源", + "Move selected zone/radiation source upward": "上移选中的区/辐射源", + "Movement acceleration": "运动加速度", + "Movement toward target": "朝向目标运动", + "Multiplier": "倍增器", + "Muscle": "肌肉", + "Muscle activities": "肌肉活动", + "Muscle cells can perform different movements and deformations based on input and configuration.\n\n": "的符号与通道 #0 的符号不同,则在弯曲过程中不会获得加速度。\n\n ", + "Muscle movement visualization": "肌肉运动可视化", + "Muscle: When a muscle cell is activated, it can produce either a movement, a bending or a change in length of the cell connection.": "它们也可以包含更多的基因组,这些基因组又描述其他的细胞网络,以此类推。", + "Mutants": "突变体", + "Mutants and cell functions": "突变体和细胞功能", + "Name": "名称", + "Nerve": "神经", + "Nerve pulses": "神经脉冲", + "Network settings": "网络设置", + "Neural activities": "神经元活动", + "Neural net": "神经网络", + "Neuron": "神经元", + "Neuron weights and biases": "神经元权重和偏置", + "New": "新建", + "New complex mutant protection": "新复杂突变体保护", + "New simulation": "新建仿真", + "Next autosave in ": "下次自动保存于 ", + "No autosave scheduled": "没有计划的自动保存", + "No valid directory": "无有效目录", + "Non-overlapping copies could not be created.": "无法创建不重叠的副本。", + "None": "无", + "Normal energy": "正常能量", + "Num genotype\ncells average": "基因型细胞数\n平均值", + "Number of copies": "复制数量", + "Numerics": "数值计算", + "OK": "确定", + "Object inspection": "对象检查", + "Objects": "对象", + "Open": "打开", + "Open ALIEN Discord server": "打开 ALIEN Discord 服务器", + "Open image": "打开图像", + "Open parameters for selected zone/radiation source in a new window": "在新窗口中打开选中区/辐射源的参数", + "Open pattern": "打开图案", + "Open simulation parameters": "打开仿真参数", + "Open simulation parameters from file": "从文件打开仿真参数", + "Options": "选项", + "Orientation": "方向", + "Outer radius": "外半径", + "Output #": "输出 #", + "Overlapping check": "重叠检查", + "Overview": "概览", + "Palette": "调色板", + "Parameters": "参数", + "Parameters (filtered)": "参数(已过滤)", + "Password": "密码", + "Paste": "粘贴", + "Paste pattern": "粘贴图案", + "Paste simulation parameters from clipboard": "从剪贴板粘贴仿真参数", + "Pattern": "模式", + "Pattern analysis": "图案分析", + "Pattern editor": "模式编辑器", + "Pause": "暂停", + "Peak value": "峰值", + "Pencil radius": "铅笔半径", + "Physics": "物理", + "Physics: Binding": "物理:连接", + "Physics: Motion": "物理:运动", + "Physics: Radiation": "物理:辐射", + "Physics: Thresholds": "物理:阈值", + "Plant-herbivore ecosystems": "植物与食草动物生态系统", + "Please choose a color": "请选择颜色", + "Please enter the desired user name and password and proceed by clicking the 'Create user' button.": "如果激活'记住'开关,密码将存储在 Windows 注册表的 ", + "Please enter the user name and proceed by clicking the 'Reset password' button.": "'HKEY_CURRENT_USER\\SOFTWARE\\alien' 路径下,", + "Please enter your email address to receive the\nconfirmation code for the new user.": "请输入您的电子邮件地址以接收\n新用户的确认码。", + "Please enter your email address to receive the\nconfirmation code to reset the password.": "请输入您的电子邮件地址以接收\n重置密码的确认码。", + "Please make sure that:\n\n1) You have an NVIDIA graphics card with compute capability 6.0 or higher (for example ": "请确保以下条件:\n\n1) 您拥有计算能力 6.0 或更高的 NVIDIA 显卡(例如 GeForce 10 系列)。\n\n2) 您已安装最新的 NVIDIA 显卡驱动。\n\n3) 安装目录的名称(包括父目录)不应包含非英文字符。如果不满足,", + "Plot height": "绘图高度", + "Plot type": "绘图类型", + "Position": "位置", + "Position (x,y)": "位置 (x,y)", + "Position X": "位置 X", + "Position Y": "位置 Y", + "Position in space": "空间中的位置", + "Pressure": "粘度", + "Prevent genome depth increase": "基因组具有树状结构(可包含子基因组)。若此标志激活,突变不会增加基因组结构的深度。", + "Previous": "上一个", + "Primary cell coloring": "主要细胞着色", + "Private workspace (need to login)": "私人工作区(需登录)", + "Process single time step": "执行单个时间步", + "Processes per time step and active cell": "每时间步每活跃细胞进程", + "Project name": "项目名称", + "Properties": "属性", + "Public workspace": "公共工作区", + "Radial": "径向", + "Radiation": "辐射", + "Radiation angle": "辐射角度", + "Radiation sources": "辐射源", + "Radiation type 1: Strength": "辐射类型 1:强度", + "Radiation type I: Minimum age": "辐射类型 I:最低年龄", + "Radiation type I: Strength": "辐射类型 I:强度", + "Radiation type II: Energy threshold": "辐射类型 II:能量阈值", + "Radiation type II: Strength": "辐射类型 II:强度", + "Radius": "半径", + "Ramification factor": "分支因子", + "Random multiplication": "随机倍增", + "Random multiplier": "随机倍增器", + "Randomize": "随机化", + "Randomize mutation ids": "随机化突变ID", + "Re-enter password": "重新输入密码", + "Reactions": "反应", + "Reactions given": "给出的反应", + "Reactions received": "收到的反应", + "Real-time": "实时", + "Real-time plots": "实时图", + "Reconnector": "重连器", + "Reconnector creations": "连接器创建", + "Reconnector deletions": "连接器删除", + "Reconnector: Has the ability to dynamically create or destroy connections to other cells with a specified color.": "能量粒子是一种只具有能量值、位置和速度的粒子。与细胞不同,它们不能形成网络或执行任何额外功能。", + "Rectangular": "矩形", + "Reference simulation parameters replaced": "错误", + "Refresh": "刷新", + "Reinforcement factor": "强化因子", + "Relative strength": "相对强度", + "Relative time: %s\nValue: %s": "相对时间: %s\n值: %s", + "Release stresses": "释放应力", + "Remember": "记住密码", + "Render UI": "渲染 UI", + "Render simulation": "渲染仿真画面", + "Rendering": "渲染", + "Replace the selected ": "用当前打开的替换所选", + "Repulsion strength": "最大碰撞距离", + "Reset age after construction": "构建后重置年龄", + "Reset password": "重置密码", + "Resize": "调整大小", + "Resize world": "调整世界大小", + "Resolution": "分辨率", + "Restrict to selected cell networks": "限制到选中的细胞网络", + "Restricts the sensor so that it only scans cells with a certain color.": " 连接的细胞:在这种情况下,能量将在所有直接连接和连接之连接的细胞之间均匀分配。\n\n", + "Revert changes": "恢复更改", + "Rigidity": "刚性", + "Roll out changes to cell networks": "展开变更到细胞网络", + "Run": "运行", + "Same creature energy distribution": "同生物能量分配", + "Same mutant protection": "同突变体保护", + "Save": "保存", + "Save on exit": "退出时保存", + "Save pattern": "保存图案", + "Save pattern analysis result": "保存图案分析结果", + "Save simulation parameters": "保存仿真参数", + "Save simulation parameters to file": "将仿真参数保存到文件", + "Saving on exit ...": "正在退出保存…", + "Scale": "缩放", + "Scale content": "缩放内容", + "Security information": "安全信息", + "Select a position in the simulation view": "在模拟视图中选择一个位置", + "Select a position with the mouse": "用鼠标选择一个位置", + "Select directory": "选择目录", + "Selection": "选择", + "Self-replicators": "自复制体", + "Sensor": "传感器", + "Sensor activities": "传感器活动", + "Sensor cells scan their environment for concentrations of cells of a certain color and provide distance and angle to the ": "0(无匹配)或 1(匹配)\n\n", + "Sensor detection factor": "传感器检测因子", + "Sensor matches": "传感器匹配", + "Sensor: If activated, it performs a long-range scan for the concentration of cells with a certain color.": "能量粒子", + "Sensors can operate in 2 modes:\n\n": "激活后,传感器仅检测距离大于或等于指定值的对象。", + "Server address": "服务器地址", + "Set execution order": "设置执行顺序", + "Settings": "设置", + "Shader parameters": "着色器参数", + "Shape": "形状", + "Share GPU model info": "分享 GPU 型号信息", + "Show after startup": "启动时显示", + "Show radiation sources": "显示辐射源", + "Sigmoid": "高斯函数", + "Signal in channel #0 is not necessary.\n\n In both cases, if there is not enough energy available for the cell being ": "扫描将沿着从输入细胞(输入信号来源的细胞)指向传感器细胞的方向进行。", + "Signals": "信号", + "Simulation": "仿真", + "Simulation parameters": "仿真参数", + "Simulation parameters copied": "仿真参数已复制", + "Simulation parameters for '": "仿真参数 - '", + "Simulation parameters for 'Base'": "仿真参数 - '基础'", + "Simulation parameters pasted": "仿真参数已粘贴", + "Simulations": "仿真", + "Simulators": "仿真用户", + "Single cell function": "单一细胞功能", + "Size (x,y)": "尺寸 (x,y)", + "Size factor": "尺寸因子", + "Slow down": "减速", + "Smoothing length": "平滑长度", + "Space": "空格", + "Spatial control": "空间控制", + "Specifies how many branches the constructor can use to build the cell networks. Each branch is connected to ": "完成,细胞会短暂进入'激活中'状态,然后很快过渡到'就绪'状态。如果细胞网络正在死亡过程中,", + "Specifies the color of the cells where connections are to be established or destroyed.": "通过此设置,可以选择性地指定参考角度只能是特定值的倍数。", + "Specifies the radius of the drawn cells in unit length.": "指定绘制细胞的半径(单位长度)。", + "Standard cell colors": "标准细胞颜色", + "Start drawing": "开始绘制", + "Statistics": "统计", + "Sticky": "粘性", + "Stiffness": "刚度", + "Strength": "辉光强度", + "Sub-genome color": "子基因组颜色", + "Swarming": "群体行为", + "Sync with rendering": "同步渲染", + "Target color and duration": "目标颜色和持续时间", + "Temporal control": "时间控制", + "The ": "该", + "The activation function is a mapping which will be applied to the accumulated value from all inputs channels": " 手动:仅当通道 #0 中有信号时才触发构建过程。\n\n", + "The amount of energy which a transmitter cell can transfer to nearby transmitter or constructor cells or to connected cells.": "发射器细胞可传输到附近发射器、构建器细胞或已连接细胞的能量量。", + "The amount of internal energy of the cell. The cell undergoes decay when its energy falls below a critical ": " 细胞状态:蓝色 = 就绪,绿色 = 构建中,白色 = 激活中,粉色 = 分离,浅蓝 = 恢复中,红色 = 死亡中\n\n", + "The analysis result could not be saved to the specified file.": "分析结果无法保存到指定文件。", + "The angle between the predecessor and successor cell can be specified here. Please note that the shown angle here is shifted ": "执行运动的肌肉细胞等等。这些不同的细胞功能通常需要输入信号并产生输出信号。更新细胞信号的过程分为两步:\n\n1) 当", + "The angle in which direction the scanning process should take place can be determined here. An angle of 0 means that the ": "此值指示在通道 #0 中更改符号之前的脉冲数。", + "The average number of encoded cells in the genomes is displayed.": "显示基因组中编码细胞数的平均值。", + "The cell network encoded in the genome can be repeatedly built by specifying a number of ": "基因组中编码的细胞网络可以通过指定重复次数来重复构建。", + "The constructor can automatically connect constructed cells to other cells in the vicinity within this distance.": "构建器可在此距离内自动将构建的细胞连接到附近其他细胞。", + "The countdown specifies the cycles (in 6 time steps) until the detonator will explode.": "细胞的内部能量值。当能量低于临界阈值时,细胞会衰变", + "The data transfer to the server is encrypted via https. On the server side, the password is not stored in cleartext, but as a salted SHA-256 hash ": "或者在其它操作系统上存储在本地机器的 'settings.json' 中。", + "The default simulation file could not be read.\nAn empty simulation will be created.": "默认仿真文件无法读取。\n将创建一个空白仿真。", + "The distance between two connected cells.": "到服务器的数据传输通过 https 加密。在服务器端,密码不以明文形式存储,而是作为加盐的 SHA-256 哈希值存储在数据库中。", + "The duration of the injection process depends on the simulation parameter 'Injection time'.": "这可以使用工具栏中的'Copy genome'按钮完成。此操作将当前标签中的整个基因组复制到", + "The energy that the cell should receive after its creation. The larger this value is, the more energy the constructor cell must expend ": "未设置,细胞将无法接收输入信号。", + "The following cell functions obtain their input from channel #0:\n\n": " 神经元\n\n", + "The following cell functions obtain their input from channel #1:\n\n": "弯曲引起的加速度。如果通道 #1 的符号与通道 #0 的符号不同,在弯曲过程中不会获得加速度。", + "The following cell functions obtain their input from channel #2:\n\n": " 肌肉细胞:该通道用于运动模式下的肌肉。它编码相对于先前由传感器细胞检测到的目标(如果参数'Movement toward target'已激活)", + "The following cell functions obtain their input from channel #3:\n\n": "-0.5 对应 -180 度,+0.5 对应 +180 度。", + "The following cell functions obtain their input from channel #4:\n\n": "以下细胞功能从通道 #6 获取其输入:\n\n", + "The following cell functions obtain their input from channel #5:\n\n": "以下细胞功能从通道 #7 获取其输入:\n\n", + "The following cell functions obtain their input from channel #6:\n\n": "铅笔的半径(以细胞数量计)。", + "The following cell functions obtain their input from channel #7:\n\n": "矩形的宽度(以细胞计)。", + "The following cell functions write their output to channel #0:\n\n": "以下细胞功能将其输出写入通道 #0:\n\n", + "The following cell functions write their output to channel #1:\n\n": " 神经元\n\n", + "The following cell functions write their output to channel #2:\n\n": " 神经元\n\n", + "The following cell functions write their output to channel #3:\n\n": " 神经元\n\n", + "The following cell functions write their output to channel #4:\n\n": " 神经元", + "The following cell functions write their output to channel #5:\n\n": " 神经元", + "The following cell functions write their output to channel #6:\n\n": " 神经元", + "The following cell functions write their output to channel #7:\n\n": " 神经元\n\n", + "The following folder has been selected in the browser\nand will used for the upload:\n\n": "已在浏览器中选择以下文件夹\n并将用于上传:\n\n", + "The following options can be used to only bind to cells with certain properties:\n\n": "这使得创建的网络具有更高的稳定性,否则角度更容易受到外部影响。", + "The following options can be used to only detect cells with certain properties:\n\n": " 传递细胞和构建细胞:在这里,能量将传输到同一细胞网络中空间附近的构建细胞或其他传递细胞。", + "The fraction of energy that a cell can absorb from an incoming energy particle can be specified here.": "细胞从入射能量粒子中吸收能量的比例。", + "The functions of cells can be executed in a specific sequence determined by this number. The values are limited between 0 and 5 and ": "默认情况下,基因组序列中的细胞在创建时会自动连接到所有属于同一基因组的相邻细胞。", + "The height of the rectangle in cells.": "两个连接细胞之间的距离。", + "The id of the last creature that has been scanned.": "最后扫描的生物的 ID。", + "The inner radius of the disc in cells.": "请输入用户名,然后点击'重置密码'按钮。", + "The intervals between two pulses can be set here. It is specified in cycles, which corresponds to 6 time steps each.": "指定要建立或断开连接的细胞颜色。", + "The larger this parameter is, the less energy can be gained by attacking creatures with the same mutation id.": "此参数越大,攻击具有相同突变 ID 的生物所能获得的能量越少。", + "The larger this parameter is, the more difficult it is to attack cells that contain more connections.": "攻击细胞将在攻击中捕获的能量传输到附近发射器或构建器细胞的最大距离。", + "The length of the genome in bytes.": "基因组的字节长度。", + "The maximal age of cells that arise from energy particles can be set here.": "此处可设置从能量粒子中产生的细胞的最大年龄。", + "The maximum distance over which a transmitter cell transfers its additional energy to nearby transmitter or constructor cells.": "发射器细胞将额外能量传输到附近发射器或构建器细胞的最大距离。", + "The maximum distance over which an injector cell can infect another cell.": "注射器细胞可以感染其他细胞的最大距离。", + "The maximum number of bonds a cell can form with other cells.": " 单一细胞功能:可以高亮特定类型的细胞功能,在下一个参数中选择。\n\n", + "The maximum number of radiation sources has been reached.": "已达到最大辐射源数量。", + "The maximum number of zones has been reached.": "已达到最大区域数量。", + "The maximum radius in which a reconnector cell can establish or destroy connections to other cells.": "重连器细胞可建立或破坏与其他细胞连接的最大半径。", + "The maximum radius in which a sensor cell can detect mass concentrations.": "传感器细胞可检测质量浓度的最大半径。", + "The minimum age of a cell can be defined here, from which it emits energy particles.": "定义细胞开始发射能量粒子的最低年龄。", + "The minimum density to search for a cell concentration of a specific color. This value ranges between 0 and 1. It controls the ": "移动方向相对于目标指定。\n\n", + "The minimum energy of a cell can be defined here, from which it emits energy particles.": "定义细胞开始发射能量粒子的最低能量。", + "The number of all encoded cells in the genome including its sub-genomes, repetitions and number of branches.": "基因组中所有编码细胞的数量,包括其子基因组、重复数和分支数。", + "The number of colonies is displayed. A colony is a set of at least 20 same mutants.": "显示菌落数。一个菌落是一组至少20个相同的突变体。", + "The number of layers in cells starting from the center.": "如果选择'粘性'属性,创建的细胞通常可以形成更多连接。也就是说,它们可以在碰撞后与其他细胞网络'粘在一起'。", + "The number of the encoded cells per repetition in the genome. Cells of sub-genomes are not counted here.": "基因组中每次重复编码的细胞数量。子基因组的细胞不计算在内。", + "The outer radius of the disc in cells.": "请输入所需的用户名和密码,然后点击'创建用户'按钮。", + "The password does not match.": "密码不匹配。", + "The probability that the explosion of one detonator will trigger the explosion of other detonators within the blast radius.": "一个引爆器的爆炸触发爆炸半径内其他引爆器爆炸的概率。", + "The proportion of activation functions in the neuronal network of a cell that are changed within a neuron mutation. The default is 0.05.": "神经元突变中改变细胞神经网络激活函数的比例。默认为 0.05。", + "The proportion of biases in the neuronal network of a cell that are changed within a neuron mutation. The default is 0.2.": "神经元突变中改变细胞神经网络偏置的比例。默认为 0.2。", + "The proportion of weights in the neuronal network of a cell that are changed within a neuron mutation. The default is 0.2.": "神经元突变中改变细胞神经网络权重的比例。默认为 0.2。", + "The radius of the detonation.": "爆炸的半径。", + "The radius of the glow. Please note that a large radius affects the performance.": "辉光半径。注意:较大的半径会影响性能。", + "The radius of the pencil in number of cells.": "从中心开始的细胞层数。", + "The selected file could not be opened.": "无法打开所选文件。", + "The selected file could not be saved.": "无法保存所选文件。", + "The selected pattern could not be saved to the specified file.": "无法将所选图案保存到指定文件。", + "The sequence number of the cell in the genome that will be constructed next.": "下一个将构建的细胞在基因组中的序号。", + "The spatial distance between each cell and its predecessor cell in the genome sequence is determined here.": "此值大致标识一个特定的生物。虽然不能保证,但两个生物具有不同生物 ID 的可能性很高。", + "The spatial structure of the cells encoded in the genome is displayed here. This is only a rough ": "此处显示基因组中编码的细胞的空间结构。这只是一个粗略的", + "The specific cell function type to be highlighted can be selected here.": "可选择要高亮的特定细胞功能类型。", + "The stiffness determines the amount of force generated after a displacement to push the cell (network) to its reference configuration.": "(参见那里的工具提示)。着色方式如下:蓝色 = 低加成生物(通常小或简单的基因组结构),红色 = 高加成\n\n", + "The strength of the glow.": "辉光的强度。", + "The strength of the repulsive forces, between two cells that are not connected.": "两个细胞之间可以发生碰撞的最大距离。", + "The user '": "用户 '", + "The width of the rectangle in cells.": "圆盘的内半径(以细胞计)。", + "The zoom level from which the neuronal activities become visible.": "神经元活动变得可见的缩放级别。", + "There are 2 modes available for controlling constructor cells:\n\n": "在几百单位半径内)。扫描半径可通过模拟参数调整(参见传感器设置中的 'Range')。", + "There are three different workspaces where you can find and possibly upload simulations and genomes:\n\n": " 私有:每个用户帐户都有自己的私有空间。模拟和基因组仅对登录用户可见。", + "There are two ways to control the energy distribution, which is set ": "当构建细胞完全构建了一个新的细胞网络后,可以定义直到激活的时间步数。激活前,细胞网络处于休眠状态。", + "These settings offer extended possibilities for controlling the absorption of energy particles by cells.": "提供控制细胞吸收能量粒子的扩展功能。", + "This can be done using the 'Copy genome' button in the toolbar. This action copies the entire genome from the current tab to ": "当细胞被设置为不可摧毁的墙壁时,它变得不朽,抵抗外力,但仍能进行线性运动。此外,未连接的普通细胞和能量粒子会从不可摧毁的细胞上弹开。", + "This can be used to define color transitions for cells depending on their age.": "可用于根据细胞年龄定义颜色过渡。", + "This function equips the cell with a small network of 8 neurons with 8x8 configurable weights, 8 bias values and activation functions. It processes ": "支持被攻击的细胞。能量传输的工作原理如下:收集自身细胞和直接连接的细胞的部分过剩能量,", + "This number specifies the current branch on which the construction process takes place. Each branch is ": "此数字指定当前构建过程所在的分支。每个分支都连接到构建细胞,", + "This parameter allows to control the strength of the pressure.": "控制粘度的强度。较大值使运动更平滑。", + "This parameter be used to control the strength of the viscosity. Larger values lead to a smoother movement.": "两个未连接细胞之间的排斥力强度。", + "This parameter controls how the number of encoded cells in the genome influences the calculation of its complexity.": "此参数控制基因组中编码细胞数对其复杂度计算的影响。", + "This property defines the color of the cell. It is not just a visual marker. On the one hand, the cell color can be used to define own types of cells ": "细胞功能可以按照由该编号确定的特定顺序执行。值限制在 0 到 5 之间,遵循模 6 的逻辑。", + "This specifies the fraction of the velocity that is slowed down per time step.": "控制连接细胞的刚性。\n较高值会使连接细胞更像刚体一样一致运动。", + "This type of mutation alters the color of all cell descriptions in a genome by using the specified color transitions.": "此类突变使用指定的颜色转换改变基因组中所有细胞描述的颜色。", + "This type of mutation alters the color of all cell descriptions in a sub-genome by using the specified color transitions.": "此类突变使用指定的颜色转换改变子基因组中所有细胞描述的颜色。", + "This type of mutation copies a block of cell descriptions from the genome at a random position to a new random position.": "此类突变将基因组中一块细胞描述从随机位置复制到新的随机位置。", + "This type of mutation moves a block of cell descriptions from the genome at a random position to a new random position.": "此类突变将基因组中一块细胞描述从随机位置移动到新的随机位置。", + "This value describes the angle between two concatenated cell networks viewed from the first cell of the subsequent cell network.": "此处可设置渲染时细胞的着色方式。\n\n", + "This value describes the angle between two concatenated cell networks viewed from the last cell of the previous cell network.": " 能量:细胞能量越多,显示越亮。使用灰度表示。\n\n", + "This value determines the angle from the last constructed cell to the second-last constructed cell and the constructor cell. The ": "搜索特定颜色细胞浓度的最小密度。该值介于 0 和 1 之间。它控制传感器的灵敏度。", + "This value indicates the number of pulses until the sign will be changed in channel #0.": " 其他突变体:具有显著不同基因组的细胞。\n\n", + "This value indicates the number of times this genome has been inherited by offspring.": "此值表示此基因组已被后代继承的次数。", + "This value sets the stiffness for the entire encoded cell network. The stiffness determines the amount of ": "突变 ID 是用于区分突变体的值。大多数突变(神经网络和细胞属性除外)后,突变 ID 会发生变化。少数值具有特殊含义:\n\n", + "This value specifies how many times the cell network described in the genome should be concatenated for each construction. For a value greater ": "如果参数'Cell death consequences'设置为'Detached creature parts die':当细胞与位于自我复制构建细胞的生物体分离时,", + "This value specifies the time interval for automatic triggering of the constructor cell. It is given in multiples ": "以下选项可用于仅检测具有特定属性的细胞:\n\n", + "Throughput": "吞吐量", + "Time horizon": "时间范围", + "Time spent": "在线时长", + "Time step": "时间步", + "Time step data": "时间步数据", + "Time step size": "时间步长", + "Time step: %s\nTimestamp: %s\nValue: %s": "时间步: %s\n时间戳: %s\n值: %s", + "Time steps per second": "每秒时间步数", + "Timelines": "时间线", + "Timestamp": "时间戳", + "To translate a genome into an actual structure, there are two options:": "要将基因组转化为实际结构,有两种选择:", + "Tools": "工具", + "Total time steps": "总时间步数", + "Translation": "移位", + "Transmitter": "发射器", + "Transmitter activities": "发射器活动", + "Transmitter cells are designed to transport energy. This is important, for example, to supply constructor cells with energy or to ": "从其输入接收到的信号。", + "Triples of connected cells within a network have specific spatial angles relative to each other. These angles ": " 1:此值用于自由细胞。自由细胞不是通过自我复制过程创建的,而是通过能量粒子转化而来。", + "Type": "类型", + "Undo": "撤销", + "Upload ": "上传", + "Upload genome": "上传基因组", + "Upload simulation": "上传仿真", + "Upload your current ": "将当前", + "Upper limit of connections": "连接数上限", + "User name": "用户名", + "Velocity": "速度", + "Velocity (x,y)": "速度 (x,y)", + "Velocity X": "速度 X", + "Velocity Y": "速度 Y", + "Verbose": "详细", + "Version": "版本", + "Vertical cells": "垂直细胞数", + "Viruses": "病毒", + "Viscosity": "排斥强度", + "Visible in the public workspace": "在公共工作区可见", + "Visualization": "可视化", + "Warning: All the data of the user '": "警告:用户 '", + "Weight": "权重", + "What is ": "什么是 ", + "When a cell is set as indestructible wall, it becomes immortal, resistant to external forces, but still capable of linear movement. Furthermore, unconnected ": " 所有细胞功能:细胞根据其细胞功能着色。", + "When a genome injection is initiated, the counter increments after each consecutive successful activation of the injector. Once the counter reaches a ": "当基因组注射启动时,每次注射细胞连续成功激活后计数器递增。一旦计数器达到", + "When a new cell network has been fully constructed by a constructor cell, one can define the time steps until activation. Before activation, the cell ": " 其他突变体:具有显著不同基因组的细胞。\n\n", + "When this parameter is increased, fast moving cells will absorb less energy from an incoming energy particle.": "此参数增大时,快速移动的细胞从入射能量粒子中吸收的能量将减少。", + "When this parameter is increased, slowly moving cells will absorb less energy from an incoming energy particle.": "此参数增大时,慢速移动的细胞从入射能量粒子中吸收的能量将减少。", + "Width": "宽度", + "Windows user that contains no non-English characters. If this is not the case, a new Windows user could be created to solve this problem.\n\n4) ALIEN needs ": "连接到 CUDA 显卡。ALIEN 使用同一张显卡进行计算和渲染,并选择计算能力最高的那张。\n\n6) 如果您同时拥有集成显卡和独立显卡,请确保 ALIEN 可执行文件", + "World": "世界", + "World size": "世界大小", + "Your input contains not allowed characters.": "传递细胞设计用于传输能量。这很重要,例如,为构建细胞提供能量或", + "Zone": "区域", + "Zoom factor": "缩放因子", + "Zoom in": "放大", + "Zoom level for cell activity": "神经元活动可见缩放级别", + "Zoom out": "缩小", + "Zoom sensitivity": "缩放灵敏度", + "[cell color]": "[细胞颜色]", + "[target cell color]": "[目标细胞颜色]", + "action.\n\n": "在第一种情况下,物体必须已被传感器细胞(信号来源)定位(不一定是相邻细胞)。-0.5 对应 -180 度,+0.5 对应 +180 度。", + "activates injector\n\n": " 重连细胞:值 > 阈值触发与附近细胞建立连接,值 < -阈值触发断开连接\n\n", + "alien": "异星", + "alien-project's workspace": "alien-project 的工作区", + "appropriately. On the other hand, it is also possible to define custom geometries by setting an angle between predecessor and ": "细胞的 ID 是一个唯一的 64 位数字,在整个世界中标识该细胞且无法更改。", + "are created. However, this can pose a challenge because the constructed cells need time to fold into their desired positions. If the ": " 连接的细胞:", + "are guided by the reference angles encoded in the cells. With this setting, it is optionally possible to specify that the reference angles must only ": "此值表示生物基因组的复杂度。计算可以在模拟参数的'Genome complexity measurement'专家设置中自定义。", + "attacker\n\n": "必须尚未开始。\n\n", + "attacker cells, etc.": "攻击细胞\n\n", + "attacking its creator.": " 手工构建体:在编辑器中创建的细胞(例如墙壁)。\n\n", + "be multiples of certain values. This allows for greater stability of the created networks, as the angles would otherwise be more susceptible to ": "默认情况下,它是基因组中编码的细胞数量。", + "bending in muscle cells.": " 相同突变体:具有相关基因组的细胞。\n\n", + "bias_j), where sigma denotes the activation function.": "这意味着值为 1 表示构建细胞将每 6 个时间步被激活一次。", + "by 180 degrees for convenience. In other words, a value of 0 actually corresponds to an angle of 180 degrees, i.e. a straight ": "执行细胞功能时,首先会计算输入信号。这涉及读取所有连接的、其'执行序号'与指定的'输入执行序号'匹配的细胞的信号,", + "cell function is executed, an input signal will firstly be calculated. This involves reading the signals of all connected cells ": "激活函数是一种映射,它将应用于来自所有输入通道的累积值,并考虑权重和偏置,", + "cell network.\n\n": "连接检查失败、完整性检查失败),1(下一个细胞构建成功)", + "cell, input cell, and the nearest connected cell clockwise from the muscle cell.": "此处确定基因组序列中每个细胞与其前驱细胞之间的空间距离。", + "cell, where energy is required for each new cell. Once a new cell is generated, it is connected to the already constructed ": " 输出通道 #0:0(无法构建下一个细胞,例如无能量、所需", + "cells is collected and transferred to other cells in the vicinity. A cell has excess energy when it exceeds a defined normal value (see ": "每个新细胞都需要能量。一旦新细胞生成,它就会连接到已构建的", + "cells or extends the injection duration for injector cells.": "细胞可以拥有特定的功能,使其能够感知环境、处理信息或采取行动。所有细胞功能的共同点是,", + "close proximity to the target cell for a certain minimum duration, and, in the case of a target constructor cell, its construction process ": "肌肉细胞可以根据输入和配置执行不同的运动和变形。\n\n", + "closest match.\n\n": " 输出通道 #1:最近匹配的密度\n\n", + "concatenation). A value of infinity is also possible, but should not be used for an activated completeness check (see simulation parameters).": "然后很快进入'就绪'状态。", + "configured to use your high-performance graphics card. On Windows you need to access the 'Graphics settings,' add 'alien.exe' to the list, click ": "您的输入包含不允许的字符。", + "connected and connected-connected cells.\n\n": " 复杂度较高的突变体:具有更高复杂度基因组的细胞。\n\n", + "connected to the CUDA-powered card. ALIEN uses the same graphics card for computation as well as rendering and chooses the one ": "如果条件满足但错误仍然发生,请使用命令行参数 '-d' 启动 ALIEN,尝试重现错误,", + "connected to the constructor cell and consists of repetitions of the encoded cell network.": "并由编码的细胞网络的重复组成。", + "connection check failed, completeness check failed), 1 (next cell construction successful)": " 输出通道 #0:", + "connections' = 2 means that the cell to be ": "如果在特定距离上存在多个这样的传递细胞,能量可以传输到更远的距离,", + "constructed will only be created when there are at least 2 already constructed cells (excluding the predecessor cell) available for ": "例如,从攻击细胞到构建细胞。", + "constructor next cell, e.g. no energy, required connection check failed, completeness check failed), 1 (next cell construction ": "构建下一个细胞,例如无能量、所需连接检查失败、完整性检查失败),1(下一个细胞构建成功)\n\n", + "created, the construction process will pause until the next triggering.": "限制传感器仅扫描具有特定颜色的细胞。", + "current spatial location of the constructor cell is unfavorable, the newly formed cell might not be connected to the desired cells, ": "在这种情况下,能量将在所有直接连接和连接之连接的细胞之间均匀分配。\n\n", + "define that green cells are particularly good at absorbing energy particles, while other cell colors are better at attacking foreign cells.\nOn the ": "这种时间偏移使得细胞功能的编排成为可能。例如,需要来自神经元细胞输入的肌肉细胞应在稍后的时间步执行。", + "describe additional body parts or branching of the creature, for instance. Furthermore, sub-genomes can in turn possess further ": "刚度决定了位移后产生将细胞(网络)推回其参考配置的力的大小。", + "detected object (if the parameter 'Movement toward target' is activated) or to the direction of the adjacent cell where the input signal comes from ": " 输入通道 #0:值 > 阈值触发与附近细胞建立连接,值 < -阈值触发断开连接\n\n", + "detected target by a sensor cell (if the parameter 'Movement toward target' is activated) or to the direction of the adjacent cell where the input ": "以下细胞功能从通道 #5 获取其输入:\n\n", + "differs from the sign of channel #0, no acceleration will be obtained during the bending process.\n\n ": "或延长注射细胞的注射持续时间。", + "direction is specified as an angle.": "该值的符号会在特定时间间隔交替变化。例如,这可用于轻松创建用于肌肉细胞前后运动或弯曲的信号。", + "directory. This should normally be the case.\n\n5) If you have multiple graphics cards, please check that your primary monitor is ": "'选项',然后选择'高性能'。\n\n如果不满足这些条件,ALIEN 可能会意外崩溃。\n\n", + "during the bending process.": " 神经元\n\n", + "effects can be best observed in the preview of the genome editor.": "通常,使用 0.1 的值就可以检测到非常少数量的相应颜色细胞。", + "energy\n\n": " 注射细胞:0(未找到细胞)或 1(注射进行中或已完成)\n\n", + "every 6 time steps.": " 相同突变体:具有相关基因组的细胞。\n\n", + "execution number of the current cell. For this purpose, each channel from #0 to #7 of those cells is summed and the result is written ": "一方面,细胞颜色也在感知中发挥作用。传感器细胞专门针对特定颜色,只能检测到相应的细胞。", + "external influences. Choosing 60 degrees is recommended here, as it allows for the accurate representation of most geometries.": "细胞可存在于多种状态。当生物体的细胞网络正在构建时,其细胞处于'构建中'状态。一旦细胞网络", + "follow a modulo 6 logic. For example, a cell with an execution number of 0 will be executed at time points 0, 6, 12, 18, etc. A cell ": "然而,这可能带来挑战,因为构建的细胞需要时间折叠到期望的位置。如果", + "for example, from attacker cells to constructor cells.": " 扫描附近:在此模式下,扫描整个附近区域(通常", + "for instance, due to being too far away. An better approach would involve delaying the construction process until a desired number of ": " 传递细胞和构建细胞:", + "force generated to push the cell network to its reference configuration.": " 0:此值用于手工细胞。这指的是由用户人工创建的细胞。\n\n", + "fully constructed. Disabling this property is useful for encoding growing structures (such as plant-like species) or creature body ": " 突变体:不同突变体由不同颜色表示(仅考虑较大的结构突变,如易位或重复)。\n\n", + "genome": "基因组", + "genomes": "个基因组", + "here:\n\n": "这在希望后代不要立即变得活跃时特别有用,例如,防止其攻击创造者。", + "infinity": "无穷", + "inject its genome into another own constructor cell (e.g. to build a spore). In this mode the injection process does not take any ": "如果在基因组中编码了构建细胞或注射细胞,则该细胞本身可以包含另一个基因组。这个子基因组可以", + "input signal originates (it does not have to be an adjacent cell). A value of -0.5 correspond to -180 deg and +0.5 to +180 deg.": "引爆细胞在通道 #0 上接收 abs(值) > 阈值的输入时被激活。然后其计数器", + "installation directory (including the parent directories) should not contain non-English characters. If this is not fulfilled, ": "Windows 用户名不包含非英文字符。如果不符合,可以创建一个新的 Windows 用户来解决此问题。\n\n4) ALIEN 需要", + "is decreasing after each executing until it reaches 0. After that the detonator cell will explode and the surrounding cells are highly accelerated.": "本工具提示将更新以提供更具体的信息。", + "is recommended not to choose a password that is used elsewhere.": "二元阶梯函数", + "must not have started yet.\n\n": " 输入通道 ", + "neighboring cells from the same genome are in the direct vicinity. This number of cells can be optionally set here.\n For example, 'required ": "在这里,能量将传输到同一细胞网络中空间附近的构建细胞或其他传递细胞。", + "network is in a dormant state. This is especially useful when the offspring should not become active immediately, for example, to prevent it from ": " 自由细胞:不是通过繁殖产生,而是通过能量粒子转化产生的细胞(它们可以作为免费食物)。\n\n", + "network. If multiple such transmitter cells are present at certain distances, energy can be transmitted over greater distances, ": "传感器可在 2 种模式下运行:\n\n", + "none is set, the cell can receive no input signals.": "每个神经元有 8 个输入通道,并通过公式 output_j = sigma(sum_i (input_i * weight_ji) + bias_j) 产生输出,", + "of 6 (which is a complete execution cycle). This means that a value of 1 indicates that the constructor cell will be activated ": " 无:无进一步限制。\n\n", + "of cell functions. A muscle cell, for instance, requiring input from a neuron cell, should then be executed some time steps later.": "更好的方法是延迟构建过程,直到同一基因组的期望数量的相邻细胞位于直接附近。", + "of the last match (0 = far away, 1 = close)\n\n": "它还在固定时间间隔内在通道 #0 中生成信号。这可用于触发其他传感器细胞、", + "or, in the case of other OS, in 'settings.json' on your local machine.": "如果启用此选项,其他用户将能够在浏览器窗口中看到您拥有以下显卡:", + "other hand, cell color also plays a role in perception. Sensor cells are dedicated to a specific color and can only detect the corresponding cells.": "一个正常运作的生物需要细胞之间的协作。这可能涉及感知环境的传感器细胞、处理信息的神经元细胞、", + "output signals. The process for updating a cell signal is performed in two steps:\n\n1) When a ": "如果不满足条件,构建过程将被推迟。", + "over greater distances, for example, from attacker cells to constructor cells.": " 已爆炸:引爆细胞已经爆炸。", + "parts.": " 突变体和细胞功能:突变体和细胞功能着色的组合。\n\n", + "please re-install ALIEN to a suitable directory. Do not move the files manually. If you use Windows, make also sure that you install ALIEN with a ": "对其自身目录的写入权限。这通常应该是满足的。\n\n5) 如果您有多个显卡,请检查您的主显示器是否", + "potential connections. If the condition is not met, the construction process is postponed.": "有 2 种模式可用于控制构建细胞:\n\n", + "prediction without using the physics engine.": "预测,未使用物理引擎。", + "process information, muscle cells that perform movements, and so on. These various cell functions often require input signals and produce ": "只有在至少有 2 个已构建的细胞(不包括前驱细胞)可用于潜在连接时才会被创建。", + "reference distance to the input cell.\n\n": "三角形或六边形)。然后,基因组中编码的细胞将沿着该几何形状生成并适当地连接在一起。", + "repetitions. This value indicates the index of the current repetition.": "此值指示当前重复的索引。", + "scan will be performed in the direction derived from the input cell (the cell from which the input signal originates) ": "攻击细胞可通过两种不同的方法分配获取的能量。能量分配类似于传递细胞。", + "segment.": "并将它们的值求和。\n\n2) 执行细胞功能,并可以使用计算出的信号作为输入。然后,细胞以输出信号的形式提供输出。\n\n设置'输入执行序号'是可选的。如果", + "sensitivity of the sensor. Typically, very few cells of the corresponding color are already detected with a value of 0.1.": " 扩张和收缩:导致到输入细胞的参考距离的伸长(或收缩)。\n\n", + "sensor\n\n": " 注射细胞:abs(值) > 阈值", + "settings).\n\n": "此处可设置两个脉冲之间的间隔。它以周期为单位指定,每个周期对应 6 个时间步。", + "sigma(sum_i (input_i * weight_ji) + bias_j),\nwhere sigma stands for the activation function (different choices are available).": "模拟参数 'Cell life cycle' 中的 'Normal energy')。传递细胞不需要激活,但可以传输", + "sign of this value alternates at specific time intervals. This can be used, for example, to easily create signals for back-and-forth movements or ": " 无:无进一步限制。\n\n", + "signal comes from (if the parameter 'Movement toward target' is deactivated). A value of -0.5 correspond to -180 deg and +0.5 to +180 deg.": " 神经元", + "signals received from their input.": " 输入通道 #0:abs(值) > 阈值激活构建器(仅在", + "sim": "个仿真", + "sims": "个仿真", + "simulation": "仿真", + "simulation parameter 'Normal energy' in 'Cell life cycle'). Transmitter cells do not need an activation but they can transport ": "细胞网络。\n\n", + "solely utilized for acceleration due to bending. If the sign of channel #1 differs from the sign of channel #0, no acceleration will be obtained ": "以下细胞功能从通道 #3 获取其输入:\n\n", + "space. This angle specifies the deviation from that rule.": " 复杂度较高的突变体:具有更高复杂度基因组的细胞。\n\n", + "specific threshold (refer to the 'Injection time' simulation parameter), the injection process is completed.": "特定阈值(请参考'Injection time'模拟参数),注射过程即完成。", + "sub-sub-genomes, etc. To insert a sub-genome here by clicking on 'Paste', one must have previously copied one to the clipboard. ": "细胞与其他细胞能形成的最大连接数。", + "successful)\n\n": " 传感器:0(无匹配)或 1(匹配)\n\n", + "successor cells for each cell (except for the first and last in the sequence).": "此处以十六进制表示显示细胞 ID。", + "support attacked cells. The energy transport works as follows: A part of the excess energy of the own cell and the directly connected ": "构建细胞根据其包含的基因组构建细胞网络。构建过程逐个细胞进行,", + "take action. All cell functions have in common that they obtain the input from connected cells whose execution number matches the input ": "为此,可以指定依赖于颜色的模拟参数。例如,可以定义绿色细胞特别擅长吸收能量粒子,而其他颜色的细胞更擅长攻击外来细胞。\n另", + "target. The direction of movement is specified relative to the target.\n\n": "'self-copy'模式。在这种情况下,构建器的子基因组引用其上级基因组。", + "than 1, the cell network geometry has to fulfill certain requirements (e.g. rectangle, hexagon, loop and lolli geometries are not suitable for ": "它处于'分离'状态。但是,如果仍存在一个未死亡的自我复制细胞,分离的细胞将过渡到'恢复中'状态,", + "that are subject to different rules. For this purpose, the simulation parameters can be specified depending on the color. For example, one could ": "例如,执行序号为 0 的细胞将在时间点 0、6、12、18 等处执行。执行序号为 1 的细胞将偏移一个,即在 1、7、13、19 等处执行。", + "that it also generates a signal in channel #0 at regular intervals. This can be used to trigger other sensor cells, ": " 输入通道 #0:abs(值) > 阈值激活", + "the calculated signal as input. The cell then provides an output in form of an output signal.\n\nSetting an 'input execution number' is optional. If ": "以下 sigma 选项可用:\n\n", + "the clipboard. If you want to create self-replication, you must not insert a sub-genome; instead, you switch it to the ": "参考距离定义了两个连接细胞之间没有力作用时的距离。如果实际距离大于参考距离,细胞相互吸引。如果更小,则相互排斥。", + "the constructor cell and consists of repetitions of the encoded cell network.": "其细胞处于'死亡中'状态。\n\n", + "the execution of a cell function, some channels will be then overriden by the output of the corresponding cell function.\n\nIMPORTANT: If ": "180 度。换句话说,值为 0 实际上对应 180 度,即直线段。", + "the input from channel #0 to #7 and provides the output to those channels. More precisely, the output of each neuron calculates as\noutput_j := ": "并将其转移到附近的其它细胞。当细胞超过定义的正常值时,即为拥有过剩能量(参见", + "the opposite action.\n\n": "以下细胞功能从通道 #1 获取其输入:\n\n", + "them. The gained energy is then distributed in the own cell network.\n\n": "注射细胞可以用自己的基因组覆盖其他构建细胞或注射细胞的基因组。为此,它们需要被激活,", + "then create a GitHub issue on https://github.com/chrxh/alien/issues where the log.txt is attached.": "sigma(sum_i (input_i * weight_ji) + bias_j),\n其中 sigma 表示激活函数(提供不同的选择)。", + "there are multiple such cells) and thus directly providing it as input to other cells. Independently of this, one can specify ": "获得的能量随后分配在自己的细胞网络中。\n\n", + "there is signal in channel #0.\n\n": " 扫描特定方向:在此模式下,扫描过程仅限于特定方向。方向指定为角度。", + "threshold (refer to the 'Minimum energy' simulation parameter).": " 基因组复杂度:当参数'Complex creature protection'激活时,攻击细胞可以利用此属性", + "threshold activates constructor (only necessary in 'Manual' mode)\n\n": " 传感器:abs(值) > 阈值激活传感器\n\n", + "time.\n\n": "描述生物体的额外身体部位或分支等。此外,子基因组又可以拥有进一步的子子基因组等。", + "to create it.": "激活此开关后,细胞的输出将被丢弃。这将阻止任何其他细胞将其作为输入使用。", + "to the channel from #0 to #7 of the current cell. In particular, if there is only one input cell, its signal is simply forwarded. After ": "此处可以指定前驱细胞和后继细胞之间的角度。请注意,为方便起见,此处显示的角度已偏移了", + "transmitter cells. \n\n": " 手工构建体:在编辑器中创建的细胞(例如墙壁)。\n\n", + "triangle or hexagon). Then, the cells encoded in the genome are generated along this geometry and connected together ": "细胞以时间步为单位的年龄。", + "value in the database. If the toggle 'Remember' is activated, the password will be stored in the Windows registry under the path 'HKEY_CURRENT_USER\\SOFTWARE\\alien' ": "建议不要选择在其他地方使用过的密码。", + "whose 'execution number' matches the specified 'input execution number' and summing their values up.\n\n2) The cell function is executed and can use ": "以计算神经元的输出,即 output_j = sigma(sum_i (input_i * weight_ji) + bias_j),其中 sigma 表示激活函数。", + "with an execution number of 1 will be shifted by one, i.e. executed at 1, 7, 13, 19, etc. This time offset enables the orchestration ": "构建细胞的当前空间位置不利,新形成的细胞可能无法连接到期望的细胞,例如由于距离太远。", + "with the highest compute capability.\n\n6) If you possess both integrated and dedicated graphics cards, please ensure that the alien-executable is ": "然后在 https://github.com/chrxh/alien/issues 上创建一个 GitHub 问题,并附上 log.txt 文件。", + "within a radius of several 100 units). The scan radius can be adjusted via a simulation parameter (see 'Range' in the sensor ": "启用后,将按固定时间间隔在通道 #0 中生成信号。", + "within the same cell network. If multiple such transmitter cells are present at certain distances, energy can be transmitted ": " 已激活:每次引爆细胞执行时,倒计时递减直到 0。如果倒计时为 0,引爆细胞将爆炸。\n\n", + "write access to its own ": "已配置为使用您的高性能显卡。在 Windows 上,您需要进入'图形设置',将 'alien.exe' 添加到列表中,点击", + "you choose a cell function, this tooltip will be updated to provide more specific information. ": "细胞在创建后应接收的能量。该值越大,构建细胞必须消耗的能量就越多才能创建它。", + " 0: This value is used for handcrafted cells. This refers to cells that have been ": " 0:此值用于手工细胞。这指的是由用户人工创建的细胞。", + " 1: This value is used for free cells. Free cells are cells that have not been created by a ": " 1:此值用于自由细胞。自由细胞不是通过自我复制过程创建的,而是通过能量粒子转化而来。", + " Abs(x) := x if x >= 0 and -x if x < 0\n\n": " Abs(x) := 当 x >= 0 时等于 x,当 x < 0 时等于 -x\n\n", + " All cell functions: The cells are colored according to their cell function.": " 所有细胞功能:细胞根据其细胞功能着色。", + " Binary step(x) := 1 if x >= 0 and 0 if x < 0\n\n": " Binary step(x) := 当 x >= 0 时等于 1,当 x < 0 时等于 0\n\n", + " Cell states: blue = ready, green = under construction, white = activating, pink = detached, pale blue = reviving, red = dying\n\n": " 细胞状态:蓝色 = 就绪,绿色 = 构建中,白色 = 激活中,粉色 = 分离,浅蓝 = 恢复中,红色 = 死亡中\n\n", + " Energy: The more energy a cell has, the brighter it is displayed. A grayscale is used.\n\n": " 能量:细胞能量越多,显示越亮。使用灰度表示。\n\n", + " Gaussian(x) := exp(-2 * x * x)": " Gaussian(x) := exp(-2 * x * x)", + " Genome complexities: This property can be utilized by attacker cells when the parameter 'Complex creature protection' is ": " 基因组复杂度:当参数'Complex creature protection'激活时,攻击细胞可以利用此属性", + " Identity(x) := x\n\n": " Identity(x) := x\n\n", + " Manual: The construction process is only triggered when ": " 手动:仅当通道 #0 中有信号时才触发构建过程。\n\n", + " Mutants and cell functions: Combination of mutants and cell function coloring.\n\n": " 突变体和细胞功能:突变体和细胞功能着色的组合。\n\n", + " Mutants: Different mutants are represented by different colors (only larger structural mutations such as translations or duplications are taken into ": " 突变体:不同突变体由不同颜色表示(仅考虑较大的结构突变,如易位或重复)。\n\n", + " Private: Each user account has its own private space. The simulations and genomes are only visible to ": " 私有:每个用户帐户都有自己的私有空间。模拟和基因组仅对", + " Public: All logged-in users can share their simulations and genomes with the public. The files stored here are ": " 公共:所有登录用户都可以与公众分享他们的模拟和基因组。此处存储的文件", + " Sigmoid(x) := 2 / (1 + exp(x)) - 1\n\n": " Sigmoid(x) := 2 / (1 + exp(x)) - 1\n\n", + " Single cell function: A specific type of cell function can be highlighted, which is selected in the next parameter.\n\n": " 单一细胞功能:可以高亮特定类型的细胞功能,在下一个参数中选择。\n\n", + " Standard cell colors: Each cell is assigned one of 7 default colors, which is displayed with this option. \n\n": " 标准细胞颜色:每个细胞被分配 7 种默认颜色之一,通过此选项显示。\n\n", + " to the server and made visible in the browser. You can choose whether you want to share it with other users or whether it should only be visible in your private workspace.\nIf you have already selected a folder, your ": " 上传到服务器并在浏览器中可见。您可以选择是否与其他用户共享,还是仅在您的私人工作区可见。\n如果您已选择文件夹,您的", + "'Manual' mode)\n\n": "'手动'模式)\n\n", + "Additionally, other cells such as constructor cells provide an output signal as soon as they are triggered (automatically).": "此外,其他细胞(如构建细胞)在被触发时会自动提供输出信号。", + "Amount of energy lost by a muscle action of a cell in form of emitted energy particles.": "细胞肌肉动作以发射能量粒子形式损失的能量。", + "An error occurred on the server. Your entered code may be incorrect.\nPlease try to reset the password again.": "服务器发生错误。您输入的验证码可能不正确。\n请尝试再次重置密码。", + "Angle increment": "角度增量", + "Angular velocity increment": "角速度增量", + "Artificial Life Environment": "人工生命环境", + "Artificial Life Environment, version %s\n\nis an open source project initiated and maintained by\nChristian Heinemann.": "人工生命环境,版本 %s\n\n是一个由 Christian Heinemann 发起并维护的开源项目。", + "Backflow": "回流", + "Backflow limit": "回流限制", + "Bending acceleration": "弯曲加速度", + "Cells can exist in various states. When a cell network of the organism is being constructed, its cells are in the 'Under construction' state. Once the cell network ": "细胞可存在于多种状态。当生物体的细胞网络正在构建时,其细胞处于'构建中'状态。一旦细胞网络", + "Code (case sensitive)": "验证码(区分大小写)", + "DEBUG": "调试", + "Deletion": "删除", + "Distance": "距离", + "For how long should I run a simulation to see evolutionary changes?": "我应该运行仿真多长时间才能看到进化变化?", + "Furthermore, these networks can be fed by sensors and, in turn, control muscle and attacker cells.": "此外,这些网络可以由传感器提供输入,进而控制肌肉和攻击细胞。", + "Here, one can set how the cells are to be colored during rendering. \n\n": "此处可设置渲染时细胞的着色方式。\n\n", + "High velocity penalty": "高速惩罚", + "How can I add energy to a simulation?": "如何向仿真中添加能量?", + "How can I create a cell signal in the first place?": "如何首先创建细胞信号?", + "How can neural networks be incorporated?": "如何集成神经网络?", + "If activated, an energy particle will transform into a cell if the energy of the particle exceeds the normal energy value.": "若激活,当能量粒子的能量超过正常能量值时,它将转化为细胞。", + "In case that the parameter 'Cell death consequences' is set to 'Detached creature parts die': A cell is in 'Detached' state when it is separated from ": "如果参数'Cell death consequences'设置为'Detached creature parts die':当细胞与位于自我复制构建细胞的生物体分离时,", + "Inflow": "流入", + "Insertion": "插入", + "It contains features for compatibility with older versions.": "包含与旧版本兼容的功能。", + "Legacy behavior": "旧版行为", + "Loading flashback ...": "正在加载快照…", + "Maximum age balancing": "最大年龄平衡", + "Maximum emergent cell age": "最大新生细胞年龄", + "Neuron factor": "神经元因子", + "New password": "新密码", + "Number of files": "文件数量", + "Offset": "偏移", + "Please enter a new password and the confirmation code\nsent to your email address.": "请输入新密码以及发送到您邮箱的确认码。", + "Preserve self-replication": "保留自我复制", + "Signals can also be generated within a neuron cell using bias values.": "信号也可以在神经元细胞内使用偏置值生成。", + "The age of the cell in time steps.": "细胞以时间步为单位的年龄。", + "The amount of energy which a attacker cell can transfer to nearby transmitter or constructor cells or to connected cells.": "攻击细胞可传输到附近发射器、构建器细胞或已连接细胞的能量量。", + "The id of the cell is a unique 64 bit number which identifies the cell in the entire world and cannot be changed. The ": "细胞的 ID 是一个唯一的 64 位数字,在整个世界中标识该细胞且无法更改。", + "The larger this parameter is, the less energy can be gained by attacking creatures with more complex genomes.": "此参数越大,攻击具有更复杂基因组的生物所能获得的能量越少。", + "The maximum distance over which an attacker cell can attack another cell.": "攻击细胞可以攻击其他细胞的最大距离。", + "The mutation id is a value to distinguish mutants. After most mutations (except neural network and cell properties) the mutation id changes. A few ": "突变 ID 是用于区分突变体的值。大多数突变(神经网络和细胞属性除外)后,突变 ID 会发生变化。少数", + "The number of zones and radiation sources of the current simulation parameters must match with those from the clipboard.": "当前仿真参数的区域和辐射源数量必须与剪贴板中的相匹配。", + "The password has been successfully set.\nYou are logged in.": "密码已成功设置。\n您已登录。", + "The reference angle defines an angle between two cell connections. If the actual angle is larger, tangential forces act on the connected cells, ": "参考角度定义了两个细胞连接之间的角度。如果实际角度更大,则切向力作用于连接的细胞上,", + "The reference distance defines the distance at which no forces act between two connected cells. If the actual distance is greater than the reference ": "参考距离定义了两个连接细胞之间没有力作用时的距离。如果实际距离大于参考距离,", + "This parameter takes into account the number of encoded neurons in the genome for the complexity value.": "此参数将基因组中编码的神经元数量纳入复杂度值的计算。", + "This value denotes the complexity of the creature's genome. The calculation can be customized in the simulation parameters under the 'Genome ": "此值表示生物基因组的复杂度。计算可以在模拟参数的'Genome", + "This value loosely identifies a specific creature. While not guaranteed, it is very likely that two creatures will have different creature ids.": "此值大致标识一个特定的生物。虽然不能保证,但两个生物具有不同生物 ID 的可能性很高。", + "This values specifies the number of CUDA thread blocks. If you are using a high-end graphics card, you can try to increase the number of blocks.": "此值指定 CUDA 线程块的数量。如果您使用高端显卡,可以尝试增加块的数量。", + "Unlimited save files": "无限存档文件", + "Velocity X increment": "速度 X 增量", + "Velocity Y increment": "速度 Y 增量", + "When this parameter is increased, cells with fewer genome complexity will absorb less energy from an incoming energy particle.": "当此参数增大时,基因组复杂度较低的细胞将从入射能量粒子中吸收更少的能量。", + "Why does the radiation source generates no energy particles?": "为什么辐射源不产生能量粒子?", + "account).\n\n": "账户)。\n\n", + "activated (see tooltip there). The coloring is as follows: blue = creature with low bonus (usually small or simple genome structure), red = large ": "(参见那里的工具提示)。着色方式如下:蓝色 = 低加成生物(通常小或简单的基因组结构),红色 = 高加成", + "aiming to reduce the angle. Conversely, if the actual angle is smaller, the tangential forces tend to enlarge this angle. With this type of force ": "旨在减小角度。相反,如果实际角度更小,切向力倾向于增大此角度。通过这种力,", + "artificially created by the user.\n\n": "由用户人工创建的。\n\n", + "bonus\n\n": "加成\n\n", + "cell id is displayed here in hexadecimal notation.": "此处以十六进制表示显示细胞 ID。", + "cell networks can fold back into a desired shape after deformation.": "细胞网络在变形后可以折叠回期望的形状。", + "complexity measurement' expert settings. By default, it is the number of encoded cells in the genome.": "complexity measurement'专家设置中自定义。默认情况下,它是基因组中编码的细胞数量。", + "distance, the cells attract each other. If it is smaller, they repel.": "时,细胞相互吸引。如果更小,则相互排斥。", + "features.\n\n": "功能。\n\n", + "is completed, the cells briefly enter the 'Activating' state before transitioning to the 'Ready' state shortly after. If a cell ": "完成,细胞会短暂进入'激活中'状态,然后很快过渡到'就绪'状态。如果细胞", + "its organism where the constructor cell for self-replication is located. However, if a non-dying cell for self-replication is still present, a detached cell will ": "它的生物体。但是,如果仍存在一个未死亡的自我复制细胞,分离的细胞将", + "network is in the process of dying, its cells are in the 'Dying' state.\n\n": "正在死亡过程中,其细胞处于'死亡中'状态。\n\n", + "normal cells and energy particles bounce off from indestructible ones.": "普通细胞和能量粒子会从不可摧毁的细胞上弹开。", + "self-replication process, but by transformation from an energy particle.": "自我复制过程,而是通过能量粒子转化而来。", + "the logged-in user.": "登录用户可见。", + "towards the sensor cell.": "指向传感器细胞的方向。", + "transition into the 'Reviving' state and then into 'Ready' state shortly after.": "过渡到'恢复中'状态,然后很快进入'就绪'状态。", + "values have a special meaning:\n\n": "值具有特殊含义:\n\n", + "vironment ?": "vironment ?", + "visible to all users.\n\n": "对所有用户可见。\n\n", + "workspace contains simulations that come along with the released versions. They cover a wide range and exploit different ": "工作区包含随发布版本附带的模拟。它们覆盖了广泛的范围并利用了不同的", + "Please enter the confirmation code sent to your email address.": "请输入发送到您邮箱的确认码。", + "Resend": "重新发送", + "Resend to other email address": "发送到其他邮箱", + "Regardless of this, many parameters can also be set depending on the cell color. For this purpose click the '+' button beside the parameter. This customization is useful when you want to define different classes of species.": "此外,许多参数也可以根据细胞颜色进行设置。为此,请点击参数旁边的'+'按钮。当您想要定义不同物种类别时,这种自定义非常有用。", + "To perform movements, an organism requires muscle cells. These are also controlled by signals. Muscle cells can work in various modes: they can bend, contract/expand, or generate an impulse.": "生物需要肌肉细胞来执行运动。这些肌肉细胞也由信号控制。它们可以在多种模式下工作:弯曲、收缩/扩张或产生脉冲。", + "Neural networks are available as cell functions. If a cell is assigned the function 'Neuron', it possesses a small neural network consisting of 8 neurons. However, these networks can be interconnected to form arbitrarily large networks, as each cell receives input from the output of certain connected cells.": "神经网络可作为细胞功能使用。如果细胞被赋予'神经元'功能,它将拥有一个由 8 个神经元组成的小型神经网络。然而,这些网络可以相互连接形成任意大的网络,因为每个细胞都从某些连接细胞的输出接收输入。", + "The existence of matter in the form of cells is a prerequisite for the radiation source to emit particles. Furthermore, the simulation parameters should be adjusted in a way that guarantees a gradual loss of energy from cells over time.": "以细胞形式存在的物质是辐射源发射粒子的先决条件。此外,应调整仿真参数以确保细胞随时间逐渐失去能量。", + "The spatial control window combines zoom information and settings on the one hand, and scaling functions on the other hand. A quite useful feature in the dialog for scaling/resizing is the option 'Scale content'. If activated, periodic spatial copies of the original world can be made.": "空间控制窗口一方面集成了缩放信息和设置,另一方面提供了缩放功能。在缩放/调整大小对话框中,一个非常有用的功能是'缩放内容'选项。若激活,可以创建原始世界的周期性空间副本。", + "Each particle can be equipped with higher-level functions including sensors, muscles, neurons, constructors, etc. that allow to mimic certain functionalities of biological cells or of robotic components. Multi-cellular organisms are simulated as networks of particles that exchange energy and information over their bonds. The engine encompasses a genetic system capable of encoding the blueprints of organisms in genomes which are stored in individual cells. The simulator is capable to simulate entire ecosystems inhabited by different populations where every object is composed of interacting particles with specific functions (regardless of whether it models a plant, herbivore, carnivore, virus, environmental structure, etc.).": "每个粒子都可以配备高级功能,包括传感器、肌肉、神经元、构建器等,从而模拟生物细胞或机器人组件的某些功能。多细胞生物被模拟为粒子网络,通过连接交换能量和信息。引擎包含一个遗传系统,能够将有机体的蓝图编码在基因组中,并存储在单个细胞内。该模拟器能够模拟由不同种群栖息的整个生态系统,其中每个对象都由具有特定功能的相互作用粒子组成(无论它模拟的是植物、食草动物、食肉动物、病毒还是环境结构等)。", + "Cells can produce signals comprising of 8 values, primarily utilized for controlling cell functions and sometimes referred to as channel #0 to channel #7. The states are refreshed periodically, specifically when the cell functions are executed. To be more precise, each cell function is executed at regular time intervals (every 6 time steps). The 'execution order number' specifies the exact time offset within those intervals.": "细胞可以产生由 8 个值组成的信号,主要用于控制细胞功能,有时称为通道 #0 到通道 #7。这些状态会定期刷新,具体来说是在执行细胞功能时。更准确地说,每个细胞功能以固定的时间间隔(每 6 个时间步)执行。'执行序号'指定了这些间隔内的确切时间偏移。", + "In the edit mode, it is possible to push bodies around in a running simulation by holding and moving the right mouse button. With the left mouse button you can drag and drop objects. Please try this out. It can make a lot of fun! The editing mode also allows you to activate lot of editing windows (Pattern editor, Creator, Multiplier, Genome editor, etc.) whose possibilities can be explored over time. Practically all properties of each single particle can be manipulated. In addition, there are mass editing functions available.": "在编辑模式下,您可以在运行仿真时按住并移动鼠标右键来推动物体。使用鼠标左键可以拖放对象。请尝试一下,它会带来很多乐趣!编辑模式还允许您激活许多编辑窗口(图案编辑器、创建器、倍增器、基因组编辑器等),其功能可以随着时间探索。几乎每个粒子的所有属性都可以被操作。此外,还有批量编辑功能可用。", + "In addition to the background color, you can determine the coloring of the cells here. Each cell is assigned a specific color, which can be used for customization and which is also used by default for rendering. However, in evolution simulations, it can be very useful to color mutants differently. This allows for better visual evaluation of diversities, mutation rates, and successful mutants, etc. For this purpose, you can switch the cell coloring to the mutation id.": "除了背景颜色,您还可以在此处确定细胞的着色方式。每个细胞被分配一种特定颜色,可用于自定义,默认情况下也用于渲染。然而,在进化仿真中,为不同突变体赋予不同颜色非常有用。这可以更好地直观评估多样性、突变率和成功突变体等。为此,您可以将细胞着色切换为基于突变 ID。", + "LI": "LI", + "A cell network is a connected graph consisting of cells and cell connections. Two cells in a network are therefore connected to each other directly or via other cells. A cell network physically represents a particular body.": "细胞网络是一个由细胞和细胞连接组成的连通图。网络中的两个细胞因此可以直接或通过其他细胞相互连接。细胞网络在物理上代表一个特定的物体。", + "In the temporal control window, a simulation can be started or paused. The execution speed may be regulated if necessary. In addition, it is possible to calculate and revert single time steps as well as to make snapshots of a simulation to which one can return at any time without having to reload the simulation from a file.": "在时间控制窗口中,可以启动或暂停仿真。必要时可以调节执行速度。此外,还可以计算和回退单个时间步,以及创建仿真快照,用户可以随时返回到这些快照,而无需从文件重新加载仿真。", + "This depends on many factors: On the size of the simulated world, on the mutation rates, on various selection pressures that can be influenced by the simulation parameters and on the self-replication duration. Usually one should wait for several dozen generations, which may correspond to hundreds of thousands or million time steps.In small worlds with smaller organisms and high mutation rates, evolutionary changes can sometimes be observed every minute depending on the hardware. With more complex simulations, you should rather expect a few hours.": "这取决于许多因素:仿真世界的大小、突变率、受仿真参数影响的各种选择压力以及自我复制持续时间。通常需要等待几十代,这可能对应数十万或数百万个时间步。在具有较小生物和高突变率的小世界中,根据硬件不同,有时每分钟都能观察到进化变化。对于更复杂的仿真,您可能需要等待几个小时。", + "In the 'Genome editor', genomes describing cell networks can be created and modified. Each tab shows the principal part of the genome. It is a sequence of cells that are supposed to be constructed in that order. If one of these cells is a constructor cell, it contains an additional genome that can be edited in a separate tab, if desired.": "在'基因组编辑器'中,可以创建和修改描述细胞网络的基因组。每个标签页显示基因组的主体部分。它是一个按照构建顺序排列的细胞序列。如果其中一个细胞是构建细胞,它包含一个额外的基因组,如果需要,可以在单独的标签页中编辑。", + "By customizing the cells according to their color, it is possible to specify different types of organisms. There are many examples that feature two classes: plants and herbivores. Plants are able to consume radiation particles, while herbivores can consume plants. This simple relationship already provides interesting dynamics, as the following examples show.": "通过根据颜色自定义细胞,可以指定不同类型的生物。有许多以两个类别为特色的示例:植物和食草动物。植物能够消耗辐射粒子,而食草动物可以消耗植物。如下面的示例所示,这种简单的关系已经提供了有趣的动态效果。", + "In addition, simulations can be scaled up by increasing the size of the world and filling the resulting empty space with copies of the original world. This functionality is available via the resize dialog in the 'Spatial control' window, if you set a new size there and activate 'Scale content'.": "此外,可以通过增大世界大小并用原始世界的副本填充产生的空白空间来扩展仿真。此功能可通过'空间控制'窗口中的调整大小对话框实现,您可以在其中设置新尺寸并激活'缩放内容'。", + "The easiest way to get to know the ALIEN simulator is to download and run an existing simulation file. You can then try out different function and modify the simulation according to your wishes.": "了解 ALIEN 模拟器的最简单方法是下载并运行现有的仿真文件。然后您可以尝试不同的功能并根据自己的意愿修改仿真。", + "The process for updating the values of a signal is as follows: Firstly, the values of all input signals (i.e. signals from connected cells which matches with the input execution number) are summed up. The resulted sum is then employed as input for the cell function, which may potentially alter the values. Subsequently, the outcome is used to generate an output signal.": "更新信号值的过程如下:首先,对所有输入信号(即来自连接细胞的与输入执行序号匹配的信号)的值求和。然后将结果和用作细胞功能的输入,该功能可能会改变这些值。随后,结果用于生成输出信号。", + "There are powerful sensors available as cell functions for detecting concentrations of specific colors in the surroundings. Organisms equipped with these sensors can perceive their environment, nourish their neural networks, and respond accordingly.": "细胞功能中提供了强大的传感器,用于检测周围环境中特定颜色的浓度。配备这些传感器的生物可以感知其环境,滋养其神经网络,并做出相应的响应。", + "The mutation rates influence the probability of modifying a genome for the underlying cells. When adjusting these rates, it should be noted that different types of mutations also have different impacts. For instance, a 'Duplication' mutation affects the genome much more invasively than a 'Neural net' mutation, which only adjusts weights and biases. Furthermore, it should be considered that for evolutionary simulations, where individuals require a long time for self-replication, high mutation rates should be avoided. The correct values are best determined through experimentation.": "突变率影响修改底层细胞基因组的概率。调整这些比率时,应注意不同类型的突变也有不同的影响。例如,'复制'突变对基因组的影响比仅调整权重和偏置的'神经网络'突变更具侵入性。此外,应考虑到,对于个体需要长时间进行自我复制的进化仿真,应避免高突变率。正确的值最好通过实验确定。", + "If you want to create individual cells, cell networks, or energy particles, you can open the 'Creator' window. In this window you also find a mode for creating cell structures by freehand drawing on the simulation area. The created cells are equipped with default values and can be modified later if desired.": "如果您想创建单个细胞、细胞网络或能量粒子,可以打开'创建器'窗口。在此窗口中,您还可以找到通过在仿真区域上手绘创建细胞结构的模式。创建的细胞具有默认值,如果需要,可以稍后修改。", + "The navigation mode is enabled by default and allows you to zoom in (holding the left mouse button) and out (holding the right mouse button) continuously. Alternatively, you can also use the mouse wheel. By holding the middle mouse button and moving the mouse, you can pan the visualized section of the world.": "导航模式默认启用,允许您连续放大(按住鼠标左键)和缩小(按住鼠标右键)。或者,您也可以使用鼠标滚轮。通过按住鼠标中键并移动鼠标,您可以平移世界的可视化部分。", + "Sometimes it is difficult to set precise values in a slider. In this case, you can click on the slider while holding the CTRL key. This allows you to enter the exact value in an input field and confirm it by pressing ENTER.": "有时很难在滑块中设置精确值。在这种情况下,您可以按住 CTRL 键点击滑块。这将允许您在输入字段中输入确切值,然后按 ENTER 确认。", + "Optionally, you can define radiation sources by opening the corresponding editor. Typically, all cells lose energy over time by emitting particles. These energy particles travel through space and can be absorbed by other cells under certain conditions. When no radiation source is defined, energy particles are emitted at the cell's position, resulting in a more or less uniform distribution of energy particles throughout space over time. For certain simulations, especially in modeling plant species, it is beneficial to specify explicit sources where energy particles should be generated. This can be achieved in the 'Radiation sources' window. Even when a source is defined, cells continue to lose the same amount of energy as before. The difference is that particles are now spawned at the specified source. The energy conservation principle remains intact.": "您可以选择通过打开相应的编辑器来定义辐射源。通常,所有细胞都会随时间通过发射粒子而损失能量。这些能量粒子在空间中移动,在特定条件下可以被其他细胞吸收。当没有定义辐射源时,能量粒子在细胞位置发射,随着时间的推移导致能量粒子在空间中或多或少均匀分布。对于某些仿真,特别是在模拟植物物种时,指定明确的能量粒子生成源是有益的。这可以在'辐射源'窗口中实现。即使定义了源,细胞仍会像以前一样损失相同数量的能量。区别在于粒子现在在指定源处生成。能量守恒原理依然保持。", + "Adding energy to a simulation can increase the available resources and thus the population. There is a convenient way to directly feed all constructor cells with additional energy. This can be achieved by enabling the 'External energy control' expert settings in the simulation parameter window. Next, set the amount of energy to be added (for instance, 1M could sustain 10K cells if each cell has 100 energy units). The external energy is not added instantly but at a rate that can be specified under 'inflow'.": "向仿真中添加能量可以增加可用资源,从而增加种群数量。有一种方便的方法可以直接为所有构建细胞提供额外能量。这可以通过在仿真参数窗口中启用'外部能量控制'专家设置来实现。接下来,设置要添加的能量量(例如,如果每个细胞有 100 能量单位,则 1M 可以维持 10K 个细胞)。外部能量不是立即添加的,而是以可以在'流入'下指定的速率添加。", + "ALIEN comes with a lot of simulation files that can be found in the browser window. They are good for experimenting with certain aspects of the program. We pick some examples to give a short overview:": "ALIEN 附带了许多仿真文件,可以在浏览器窗口中找到。它们非常适合对程序的某些方面进行实验。我们挑选一些示例来做一个简短的概述:", + "All parameters relevant to the simulation can be adjusted here. By default, the parameters are set uniformly for the entire world. However, it is also possible to allow certain parameters to vary locally in special zones. To do this, you can create a new tab in the simulation parameter window by clicking on the '+' button. It adds a spatially (fuzzy) delimited area where the global parameters can be overwritten. This zone is also visible by a different color.": "所有与仿真相关的参数都可以在此调整。默认情况下,参数对整个世界是统一设置的。然而,也可以允许某些参数在特殊区域内局部变化。为此,您可以通过点击'+'按钮在仿真参数窗口中创建一个新标签页。它会添加一个空间(模糊)界定的区域,全局参数可以在该区域被覆盖。该区域也通过不同的颜色可见。", + "rtificial ": "rtificial ", + "Nerve: On the one hand, it transfers signals from connected input cells and on the other hand, it can optionally generate signals at specific intervals.": "神经:一方面,它传递来自连接的输入细胞的信号;另一方面,它可以选择性地在特定时间间隔生成信号。", + "The principle of energy conservation holds true in a simulation, which means that energy particles cannot spontaneously come into existence out of nothingness. This principle plays a vital role in ensuring the stability of long-term simulations. If a radiation source is defined, it will emit a particle only when a cell somewhere loses energy. Conversely, in the absence of a radiation source, any emitted energy particle would originate directly in the spatial vicinity of the corresponding cell.": "能量守恒原理在仿真中成立,这意味着能量粒子不能凭空自发产生。这一原理在确保长期仿真的稳定性方面发挥着至关重要的作用。如果定义了辐射源,只有当某个地方的细胞失去能量时,它才会发射粒子。相反,在没有辐射源的情况下,任何发射的能量粒子将直接源自相应细胞的空间附近。", + "fe ": "fe ", + "To be able to experiment with existing simulations, it is important to know and change the simulation parameters. This can be accomplished in the window 'Simulation parameters'. For example, the radiation intensity can be increased or the friction can be adjusted. Explanations to the individual parameters can be found in the tooltip next to them.": "为了能够对现有仿真进行实验,了解并更改仿真参数非常重要。这可以在'仿真参数'窗口中完成。例如,可以增加辐射强度或调整摩擦系数。各个参数的说明可在其旁边的工具提示中找到。", + "An energy particle is a particle which has only an energy value, position and velocity. Unlike cells, they cannot form networks or perform any additional functions. Energy particles are produced by cells as radiation or during decay and can, in turn, also be absorbed.": "能量粒子是一种只具有能量值、位置和速度的粒子。与细胞不同,它们不能形成网络或执行任何额外功能。能量粒子由细胞作为辐射或在衰变过程中产生,反过来也可以被吸收。", + "There are several pure physics simulations demonstrating the engines' capability. They are suitable for testing the influence of simulation parameters such as 'Smoothing length', 'Pressure', 'Viscosity', etc.": "有几个纯物理仿真演示了引擎的能力。它们适用于测试仿真参数的影响,例如'平滑长度'、'压力'、'粘度'等。", + "Constructor: A constructor can build a cell network based on a built-in genome. The construction is done cell by cell and requires energy. A constructor can either be controlled via signals or become active automatically (default).": "构建器:构建器可以根据内置基因组构建细胞网络。构建过程逐个细胞进行,需要能量。构建器可以通过信号控制,也可以自动激活(默认)。", + "A simple creature first needs a constructor cell that contains its genome and is responsible for self-replication. The constructor cell is automatically triggered and generates (as soon as enough energy is available) the cell network of the offspring built cell by cell as described in its genome. The genome for the offspring is also copied and placed into the constructor cell of the offspring.": "一个简单的生物首先需要一个包含其基因组并负责自我复制的构建细胞。构建细胞被自动触发,并(一旦有足够的能量)按照其基因组描述逐个细胞生成后代的细胞网络。后代的基因组也会被复制并放入后代的构建细胞中。", + "If you want to design your own worlds, sceneries or organisms, there are many different editors available, which partially require deeper knowledge. To open the editors, you have to switch to the edit mode (e.g. a click on the icon at the bottom left). A short overview of the possibilities are given below.": "如果您想设计自己的世界、场景或生物,有许多不同的编辑器可用,其中一些需要更深入的知识。要打开编辑器,您需要切换到编辑模式(例如,点击左下角的图标)。以下简要概述了各种可能性。", + "The blueprints for entire cell networks can be stored in genomes. These genomes are translated into real cell networks by constructor cells and, if necessary, copied to their offspring. Furthermore, injector cells are able to inject their own genome into other constructor cells, which allows to model virus behaviors.": "整个细胞网络的蓝图可以存储在基因组中。这些基因组由构建细胞转化为实际的细胞网络,并在必要时复制给后代。此外,注射细胞能够将自己的基因组注入其他构建细胞,从而模拟病毒行为。", + "In addition to cell functions, a color can be used to perform additional user-defined customization of cells. For this purpose, most simulation parameters can be adjusted separately for each color, if desired. As a result, cells of different colors may have individual properties.": "除了细胞功能之外,颜色还可以用于对细胞进行额外的用户自定义。为此,如果需要,大多数仿真参数可以针对每种颜色单独调整。因此,不同颜色的细胞可能具有各自的属性。", + "Transmitter: It distributes energy to other constructors, transmitters or surrounding cells. In particular, it can be used to power active constructors. No signal is required for triggering.": "发射器:它将能量分配给其他构建器、发射器或周围细胞。特别地,它可以用于为活跃的构建器提供能量。不需要信号触发。", + "It is possible to assign a special function to a cell, which will be executed at regular time intervals. The following functions are implemented:": "可以为细胞分配一个特殊功能,该功能将以固定时间间隔执行。实现了以下功能:", + "Neuron: It equips the cell with a small network of 8 neurons. It processes input gained from the signals of connected cells and provides an output signal to other connected cells.": "神经元:它为细胞配备了一个由 8 个神经元组成的小型网络。它处理从连接细胞信号中获得的输入,并为其连接细胞提供输出信号。", + "By attaching higher-level functions to particle networks, complex multi-cellular organisms can be modeled. They can evolve over time as they are subject to mutations. The following examples consist of homogeneous as well as changing worlds populated by self-reproducing agents. Different selection pressures control evolution.": "通过将高级功能附加到粒子网络,可以建模复杂的多细胞生物。它们会随时间进化,因为会受到突变的影响。以下示例包括由自我复制代理栖息的同质和变化的世界。不同的选择压力控制着进化。", + "A": "A", + "EN": "EN", + "For the perception of the environment, sensor cells are available. When such a cell is triggered by a signal, it provide information about the relative position of cell concentrations with respect to a specific color, which can be further processed by e.g. cell with neural network.": "为了感知环境,可以使用传感器细胞。当此类细胞被信号触发时,它提供关于特定颜色细胞浓度的相对位置信息,这些信息可以进一步由具有神经网络的细胞等处理。", + "A cell connection is a bond between two cells. It stores the reference distance and on each side a reference angle to a possibly further cell connection. The reference distance and angles are calculated when the connection is established. As soon as the actual distance deviates from the reference distance, a pulling/pushing force is applied at both ends. Furthermore, tangential forces are applied at both ends in the case of an angle mismatch.": "细胞连接是两个细胞之间的纽带。它存储参考距离以及每侧到可能的下一个细胞连接的参考角度。参考距离和角度在连接建立时计算。一旦实际距离偏离参考距离,两端就会受到拉力或推力。此外,在角度不匹配的情况下,两端会受到切向力。", + "The easiest way is to select and move objects with the mouse. You can simply drag and drop cell networks in the simulation view. This also works during running simulations. When the simulation is paused, you can select a rectangular area to be highlighted by holding down the right mouse button. The selection is visually highlighted and can be moved via drag and drop. By holding down the SHIFT button duringa mouse action, only the selected cells and not the associated cell networks are shifted. This can lead to the destruction or formation of cell connections which are not selected.": "最简单的方法是使用鼠标选择并移动对象。您可以在仿真视图中直接拖放细胞网络。这在仿真运行期间也有效。当仿真暂停时,您可以通过按住鼠标右键选择一个矩形区域进行高亮。选中的区域会视觉高亮显示,并可以通过拖放移动。在鼠标操作期间按住 SHIFT 键,只会移动选中的细胞,而不会移动相关的细胞网络。这可能导致未选中的细胞连接被破坏或形成。", + "Cells are the basic building blocks that make up everything. They can be connected to each others, possibly attached to the background (to model barriers), possess special functions and transport signals. Additionally, cells have various physical properties, including": "细胞是构成万物的基本构建块。它们可以相互连接,也可以附着到背景上(用于模拟屏障),拥有特殊功能并传输信号。此外,细胞还具有各种物理属性,包括", + "Another option is to inject the genome into an existing organism. To do this, you must select the organism and click on 'Inspect principal genome' in the editor menu. A window will open where you see the existing genome of that creature. Then you can inject your own genome by invoking the 'Inject from editor' button.": "另一种选择是将基因组注入现有的生物中。为此,您必须选择该生物,然后点击编辑器菜单中的'检查主基因组'。将打开一个窗口,显示该生物的现有基因组。然后您可以通过调用'从编辑器注入'按钮来注入您自己的基因组。", + "In general, an organism in ALIEN consists of a network of cells where the cells work together by communicating with each other through signals.": "通常,ALIEN 中的生物由一个细胞网络组成,其中细胞通过信号相互通信来协同工作。", + "The most direct approach involves using a nerve cell that generates an signal at regular time intervals. The advantage here is that you can precisely configure the length of the time intervals.": "最直接的方法是使用神经细胞,它以固定时间间隔生成信号。其优点在于您可以精确配置时间间隔的长度。", + "Nearly every property of each particle can be viewed and edited. For this purpose, special editing windows can be attached to a particle. To do this, you have to select one or more particles (not too many) and invoke 'Inspect objects' from the editor menu. Each selected particle is now connected to a window. It is even possible to view these editing windows during a running simulation. In this way, you can monitor in real-time how properties of individual particles change over time.": "几乎每个粒子的每个属性都可以查看和编辑。为此,可以将特殊的编辑窗口附加到粒子上。操作方法是:选择一个或多个粒子(不要太多),然后从编辑器菜单中调用'检查对象'。每个选中的粒子现在都连接到一个窗口。甚至可以在运行仿真期间查看这些编辑窗口。这样,您可以实时监控各个粒子的属性如何随时间变化。", + "Self-replication requires energy, which must be obtained in some way. On the one hand, energy can be acquired by the absorption of energy particles flying around. This can be the main source of energy for plant-like species. On the other hand, there is the possibility to utilize attacker cells. They can attack cells from other organisms by stealing energy from them. If an attacker cell is part of the creature, it must be explicitly triggered by a signal. This signal may come, for example, from another cell equipped with a neural network. The energy obtained by an attacker cell is distributed to nearby constructor or transmitter cells.": "自我复制需要能量,必须通过某种方式获取。一方面,能量可以通过吸收周围飞行的能量粒子获得。这可以是类植物物种的主要能量来源。另一方面,也可以利用攻击细胞。它们可以通过窃取能量来攻击其他生物的细胞。如果攻击细胞是生物的一部分,它必须由信号明确触发。该信号可能来自例如配备了神经网络的另一个细胞。攻击细胞获得的能量分配给附近的构建细胞或发射器细胞。", + "To activate most cell functions, an input from a connected cell in the form of a signal is required. The simplest methods to generate a signal are as follows:": "要激活大多数细胞功能,需要来自连接细胞的信号输入。生成信号的最简单方法如下:", + "Generally, in an ALIEN simulation, all objects as well as thermal radiation are modeled by different types of particles moving through an empty space. The following terms are frequently used:": "通常,在 ALIEN 仿真中,所有物体以及热辐射都由不同类型在空间中运动的粒子来建模。以下术语经常使用:", + "Physical properties of already selected cells and energy particles, such as center velocities, positions, colors, etc., can be conveniently changed in the 'Pattern editor'. In addition, selections can be saved, loaded, copied and pasted.": "已选中的细胞和能量粒子的物理属性,如中心速度、位置、颜色等,可以在'图案编辑器'中方便地更改。此外,选中的内容可以保存、加载、复制和粘贴。", + "On older graphics cards or when using a high resolution (e.g. 4K), it is recommended to reduce the rendered frames per second, as this significantly increases the simulation speed (time steps per second). This adjustment can be made in the display settings.": "在较旧的显卡上或使用高分辨率(例如 4K)时,建议减少渲染的每秒帧数,因为这可以显著提高仿真速度(每秒时间步数)。此调整可以在显示设置中进行。", + "For the beginning, however, you can use the example already loaded. Initially, it is advisable to become acquainted with the windows for temporal and spatial controls. The handling should be intuitive and requires no deeper knowledge.": "不过,刚开始时,您可以使用已加载的示例。建议先熟悉时间和空间控制窗口。操作方式直观,不需要更深入的知识。", + "A genome in ALIEN may describe several cell networks, which are hierarchically structured und possibly connected when constructed. More precisely, it means that there is a top-level blueprint describing a certain network. If there are further constructor cells within this network, they can also contain further genomes, which in turn describe other cell networks and so on.": "ALIEN 中的基因组可以描述多个细胞网络,这些网络按层次结构组织,并在构建时可能相互连接。更准确地说,这意味着存在一个描述特定网络的顶级蓝图。如果此网络中存在更多的构建细胞,它们也可以包含更多的基因组,这些基因组又描述其他的细胞网络,以此类推。", + "Basic physical properties can be modified in these settings. This includes adjusting the radiation intensity, various thresholds, and the motion algorithm. Changes can have significant effects on performance and, in the worst case, may lead to program crashes.": "在这些设置中可以修改基本的物理属性。包括调整辐射强度、各种阈值和运动算法。更改可能对性能产生重大影响,在最坏的情况下可能导致程序崩溃。", + "Various mass editing functions are available. On the one hand, the pattern editor allows to change different physical properties of an entire selection. On the other hand, through the 'Tools' menu, the 'Mass operations' dialog can be opened. Here, colors of cells and genomes, energy values, and other properties can be globally modified. The new values will be randomly chosen from a specified range. Cells within a cell networks will be assigned the same value.": "各种批量编辑功能可用。一方面,图案编辑器允许更改整个选区的不同物理属性。另一方面,通过'工具'菜单可以打开'批量操作'对话框。在这里,细胞和基因组的颜色、能量值和其他属性可以进行全局修改。新值将从指定范围内随机选择。细胞网络内的细胞将被赋予相同的值。", + "You can generate a spore using the corresponding toolbar button. A spore is a single constructor cell containing the specific genome and possessing enough energy to create the main structure described within.": "您可以使用相应的工具栏按钮生成孢子。孢子是一个包含特定基因组并具有足够能量来创建其中描述的主要结构的单个构建细胞。", + "These parameter types are particularly important when simulating (self-replicating) agents composed of cell networks, going beyond pure physical simulations. Many of the different cell functions depend on specific parameters, which can be adjusted here. Particularly important are the parameters for mutation rates and the attack functions.With the latter, the food chain between cells of different colors can be configured. For example, in the 'Food chain color matrix' one could specify that cells with a certain color can only consume cells with a certain other color but not themselves.": "这些参数类型在模拟由细胞网络组成的(自我复制)代理时特别重要,超越了纯物理模拟。许多不同的细胞功能依赖于特定参数,这些参数可以在此调整。特别重要的是突变率和攻击功能的参数。通过后者,可以配置不同颜色细胞之间的食物链。例如,在'食物链颜色矩阵'中,可以指定某种颜色的细胞只能消耗另一种特定颜色的细胞,而不能消耗自身。", + "ALIEN offers the possibility for users to customize the basic entities through a color system with 7 different colors. More precisely, each cell is assigned a specific color, allowing the application of different simulation parameter values based on the cell's color. This enables the creation of specific conditions for populations coexisting in a shared world. For example, plant-like organisms may have a higher absorption rate for radiation particles, so they can get their energy from that.": "ALIEN 为用户提供了通过包含 7 种不同颜色的颜色系统自定义基本实体的可能性。更准确地说,每个细胞被分配一种特定颜色,允许根据细胞颜色应用不同的仿真参数值。这使得为共存于同一世界中的种群创建特定条件成为可能。例如,类植物生物可能对辐射粒子具有更高的吸收率,从而从中获取能量。", + "Network": "网络", + "Windows": "窗口", + "Editor": "编辑器", + "View": "视图", + "Help": "帮助", + "Various examples can be found in the in-game simulation browser demonstrating capabilities of the engine ranging from pure physics examples, self-deploying structures, self-replicators to evolving ecosystems. If not already open, please invoke Network  Browser in the menu bar. Simulations can be conveniently downloaded and uploaded from/to the connected server (alien-project.org by default). In order to upload own simulations to the server or rate other simulations, you need to register a new user, which can be accomplished in the login dialog.": "各种示例可以在游戏内的模拟浏览器中找到,展示了引擎的能力,范围从纯物理示例、自展开结构、自复制体到进化生态系统。如果尚未打开,请在菜单栏中调用'网络 -> 浏览器'。仿真可以方便地从连接的服务器下载或上传(默认为 alien-project.org)。要将自己的仿真上传到服务器或评价其他仿真,您需要注册一个新用户,这可以在登录对话框中完成。", + "There are basically two modes of how the user can operate in the view where the simulation is shown: a navigation mode and an edit mode. You can switch between these two modes by invoking the edit button at the bottom left of the screen or in the menu via Editor  Activate.": "用户可以在显示仿真的视图中操作,基本上有两种模式:导航模式和编辑模式。您可以通过点击屏幕左下角的编辑按钮或通过菜单中的'编辑器 -> 激活编辑'在这两种模式之间切换。", + "Fluids/Pump with Soft-Bodies": "流体/带软体的泵", + "Demos/Perpetual Motion Machine": "演示/永动机", + "Demos/Stormy Night": "演示/暴风雨之夜", + "Deep Down Below/Selected Results": "深海之下/精选结果", + "Primordial Ocean/Selected Results": "原始海洋/精选结果", + "v4.8-Evolution/Gradient/Selected Results": "v4.8-进化/梯度/精选结果", + "Evolution Sandbox/Example": "进化沙盒/示例", + "Complex Evolution Testbed/Example": "复杂进化试验台/示例", + "Twin Worlds/Example": "双子世界/示例", + "Bugs and Flowers/Example": "昆虫与花朵/示例", + "Self-replicating Fluid/Initial Setting": "自我复制流体/初始设置", + "Swarms/Space Invaders": "群体/太空入侵者", + "Evolving Swarms/Example": "进化群体/示例", + "...": "...", + "Change visibility: public  private and private  public": "修改可见性:公开  私有、私有  公开", + " simulations found": " 个仿真", + " genomes found": " 个基因组", + " simulators found": " 个仿真器", + "Logged in as ": "已登录为 ", + " @": " @", + "Not logged in to ": "未登录到 ", + "NEW": "新", + " K": " K", + " KB": " KB", + " Bytes": " Bytes", + "Text to filter search results": "筛选搜索结果的文本", + "Change visibility: public ": "修改可见性:公开 ", + " public": " 公开", + "more...": "更多...", + "public": "公开", + "private": "私有", + "alien-project": "alien-project", + "simulations": "仿真" +} \ No newline at end of file From cb4ff1b0b3393a58874ef08b41358464a118d54f Mon Sep 17 00:00:00 2001 From: zysftd Date: Sun, 12 Jul 2026 20:28:48 +0800 Subject: [PATCH 03/15] feat: add Chinese localization infrastructure and CJK font support --- external/vcpkg | 2 +- source/Gui/CMakeLists.txt | 6 +- source/Gui/InspectorWindow.h | 59 +++++++ source/Gui/LocationHelper.cpp | 154 ++++++++++++++++++ source/Gui/LocationHelper.h | 26 +++ source/Gui/LocationWidgets.h | 14 ++ source/Gui/PatternAnalysisDialog.h | 101 ++++++++++++ source/Gui/ShaderWindow.h | 16 ++ source/Gui/SimulationParametersBaseWidgets.h | 23 +++ .../Gui/SimulationParametersSourceWidgets.h | 23 +++ source/Gui/SimulationParametersZoneWidgets.h | 28 ++++ source/Gui/SimulationScrollbar.cpp | 110 +++++++++++++ source/Gui/SimulationScrollbar.h | 30 ++++ source/Gui/ZoneColorPalette.cpp | 23 +++ source/Gui/ZoneColorPalette.h | 17 ++ 15 files changed, 628 insertions(+), 4 deletions(-) create mode 100644 source/Gui/InspectorWindow.h create mode 100644 source/Gui/LocationHelper.cpp create mode 100644 source/Gui/LocationHelper.h create mode 100644 source/Gui/LocationWidgets.h create mode 100644 source/Gui/PatternAnalysisDialog.h create mode 100644 source/Gui/ShaderWindow.h create mode 100644 source/Gui/SimulationParametersBaseWidgets.h create mode 100644 source/Gui/SimulationParametersSourceWidgets.h create mode 100644 source/Gui/SimulationParametersZoneWidgets.h create mode 100644 source/Gui/SimulationScrollbar.cpp create mode 100644 source/Gui/SimulationScrollbar.h create mode 100644 source/Gui/ZoneColorPalette.cpp create mode 100644 source/Gui/ZoneColorPalette.h diff --git a/external/vcpkg b/external/vcpkg index af752f21c..f87344cac 160000 --- a/external/vcpkg +++ b/external/vcpkg @@ -1 +1 @@ -Subproject commit af752f21c9d79ba3df9cb0250ce2233933f58486 +Subproject commit f87344cac03158cbf1467264565f1fd36b382a24 diff --git a/source/Gui/CMakeLists.txt b/source/Gui/CMakeLists.txt index 56bc15050..107f17b93 100644 --- a/source/Gui/CMakeLists.txt +++ b/source/Gui/CMakeLists.txt @@ -2,8 +2,6 @@ target_sources(alien PUBLIC AboutDialog.cpp AboutDialog.h - TranslationService.cpp - TranslationService.h ActivateUserDialog.cpp ActivateUserDialog.h AlienDialog.cpp @@ -176,7 +174,9 @@ PUBLIC Viewport.cpp Viewport.h WindowController.cpp - WindowController.h) + WindowController.h + TranslationService.cpp + TranslationService.h) target_link_libraries(alien Base) target_link_libraries(alien EngineKernels) diff --git a/source/Gui/InspectorWindow.h b/source/Gui/InspectorWindow.h new file mode 100644 index 000000000..ad893a27d --- /dev/null +++ b/source/Gui/InspectorWindow.h @@ -0,0 +1,59 @@ +#pragma once + +#include "EngineInterface/Definitions.h" +#include "EngineInterface/Descriptions.h" +#include "Definitions.h" + +struct MemoryEditor; +struct CompilationResult; + +class _InspectorWindow +{ +public: + _InspectorWindow(SimulationFacade const& simulationFacade, uint64_t entityId, RealVector2D const& initialPos, bool selectGenomeTab); + ~_InspectorWindow(); + + void process(); + + bool isClosed() const; + uint64_t getId() const; + +private: + bool isCell() const; + std::string generateTitle() const; + + void processCell(CellDescription cell); + void processCellBaseTab(CellDescription& cell); + void processCellFunctionTab(CellDescription& cell); + void processCellFunctionPropertiesTab(CellDescription& cell); + template + void processCellGenomeTab(Description& desc); + void processCellMetadataTab(CellDescription& cell); + + void processNerveContent(NerveDescription& nerve); + void processNeuronContent(NeuronDescription& neuron); + void processConstructorContent(ConstructorDescription& constructor); + void processInjectorContent(InjectorDescription& injector); + void processAttackerContent(AttackerDescription& attacker); + void processDefenderContent(DefenderDescription& defender); + void processTransmitterContent(TransmitterDescription& transmitter); + void processMuscleContent(MuscleDescription& muscle); + void processSensorContent(SensorDescription& sensor); + void processReconnectorContent(ReconnectorDescription& reconnector); + void processDetonatorContent(DetonatorDescription& detonator); + + void processParticle(ParticleDescription particle); + + float calcWindowWidth() const; + + void validateAndCorrect(CellDescription& cell) const; + + SimulationFacade _simulationFacade; + + RealVector2D _initialPos; + + bool _on = true; + uint64_t _entityId = 0; + float _genomeZoom = 20.0f; + bool _selectGenomeTab = false; +}; diff --git a/source/Gui/LocationHelper.cpp b/source/Gui/LocationHelper.cpp new file mode 100644 index 000000000..9e97ee731 --- /dev/null +++ b/source/Gui/LocationHelper.cpp @@ -0,0 +1,154 @@ +#include "LocationHelper.h" + +#include "Base/Definitions.h" + +std::variant LocationHelper::findLocation(SimulationParameters& parameters, int locationIndex) +{ + for (int i = 0; i < parameters.numZones; ++i) { + if (parameters.zone[i].locationIndex == locationIndex) { + return ¶meters.zone[i]; + } + } + for (int i = 0; i < parameters.numRadiationSources; ++i) { + if (parameters.radiationSource[i].locationIndex == locationIndex) { + return ¶meters.radiationSource[i]; + } + } + THROW_NOT_IMPLEMENTED(); +} + +int LocationHelper::findLocationArrayIndex(SimulationParameters const& parameters, int locationIndex) +{ + for (int i = 0; i < parameters.numZones; ++i) { + if (parameters.zone[i].locationIndex == locationIndex) { + return i; + } + } + for (int i = 0; i < parameters.numRadiationSources; ++i) { + if (parameters.radiationSource[i].locationIndex == locationIndex) { + return i; + } + } + THROW_NOT_IMPLEMENTED(); +} + +std::map LocationHelper::onDecreaseLocationIndex(SimulationParameters& parameters, int locationIndex) +{ + std::variant zoneOrSource1 = findLocation(parameters, locationIndex); + std::variant zoneOrSource2 = findLocation(parameters, locationIndex - 1); + if (std::holds_alternative(zoneOrSource1)) { + std::get(zoneOrSource1)->locationIndex -= 1; + } else { + std::get(zoneOrSource1)->locationIndex -= 1; + } + if (std::holds_alternative(zoneOrSource2)) { + std::get(zoneOrSource2)->locationIndex += 1; + } else { + std::get(zoneOrSource2)->locationIndex += 1; + } + + std::map result; + for (int i = 0; i < parameters.numZones + parameters.numRadiationSources + 1; ++i) { + if (i == locationIndex) { + result.emplace(i, i - 1); + } else if (i == locationIndex - 1) { + result.emplace(i, i + 1); + } else { + result.emplace(i, i); + } + } + return result; +} + +std::map LocationHelper::onIncreaseLocationIndex(SimulationParameters& parameters, int locationIndex) +{ + std::variant zoneOrSource1 = findLocation(parameters, locationIndex); + std::variant zoneOrSource2 = findLocation(parameters, locationIndex + 1); + if (std::holds_alternative(zoneOrSource1)) { + std::get(zoneOrSource1)->locationIndex += 1; + } else { + std::get(zoneOrSource1)->locationIndex += 1; + } + if (std::holds_alternative(zoneOrSource2)) { + std::get(zoneOrSource2)->locationIndex -= 1; + } else { + std::get(zoneOrSource2)->locationIndex -= 1; + } + + std::map result; + for (int i = 0; i < parameters.numZones + parameters.numRadiationSources + 1; ++i) { + if (i == locationIndex) { + result.emplace(i, i + 1); + } else if (i == locationIndex + 1) { + result.emplace(i, i - 1); + } else { + result.emplace(i, i); + } + } + return result; +} + +std::map LocationHelper::adaptLocationIndex(SimulationParameters& parameters, int fromLocationIndex, int offset) +{ + std::map result; + result.emplace(0, 0); + for (int i = 0; i < parameters.numZones; ++i) { + auto& zone = parameters.zone[i]; + if (zone.locationIndex >= fromLocationIndex) { + result.emplace(zone.locationIndex, zone.locationIndex + offset); + zone.locationIndex += offset; + } else { + result.emplace(zone.locationIndex, zone.locationIndex); + } + } + for (int i = 0; i < parameters.numRadiationSources; ++i) { + auto& source = parameters.radiationSource[i]; + if (source.locationIndex >= fromLocationIndex) { + result.emplace(source.locationIndex, source.locationIndex + offset); + source.locationIndex += offset; + } else { + result.emplace(source.locationIndex, source.locationIndex); + } + } + return result; +} + +std::string LocationHelper::generateZoneName(SimulationParameters& parameters) +{ + int counter = 0; + bool alreadyUsed; + std::string result; + do { + alreadyUsed = false; + result = "Zone " + std::to_string(++counter); + for (int i = 0; i < parameters.numZones; ++i) { + auto name = std::string(parameters.zone[i].name); + if (result == name) { + alreadyUsed = true; + break; + } + } + } while (alreadyUsed); + + return result; +} + +std::string LocationHelper::generateSourceName(SimulationParameters& parameters) +{ + int counter = 0; + bool alreadyUsed; + std::string result; + do { + alreadyUsed = false; + result = "Radiation " + std::to_string(++counter); + for (int i = 0; i < parameters.numRadiationSources; ++i) { + auto name = std::string(parameters.radiationSource[i].name); + if (result == name) { + alreadyUsed = true; + break; + } + } + } while (alreadyUsed); + + return result; +} diff --git a/source/Gui/LocationHelper.h b/source/Gui/LocationHelper.h new file mode 100644 index 000000000..c5477e224 --- /dev/null +++ b/source/Gui/LocationHelper.h @@ -0,0 +1,26 @@ +#pragma once + +#include +#include +#include + +#include "EngineInterface/SimulationParameters.h" + +class LocationHelper +{ +public: + static std::variant findLocation(SimulationParameters& parameters, int locationIndex); + static int findLocationArrayIndex(SimulationParameters const& parameters, int locationIndex); + + // returns new by old location index + static std::map onDecreaseLocationIndex(SimulationParameters& parameters, int locationIndex); + + // returns new by old location index + static std::map onIncreaseLocationIndex(SimulationParameters& parameters, int locationIndex); + + // returns new by old location index + static std::map adaptLocationIndex(SimulationParameters& parameters, int fromLocationIndex, int offset); + + static std::string generateZoneName(SimulationParameters& parameters); + static std::string generateSourceName(SimulationParameters& parameters); +}; diff --git a/source/Gui/LocationWidgets.h b/source/Gui/LocationWidgets.h new file mode 100644 index 000000000..654ff33d8 --- /dev/null +++ b/source/Gui/LocationWidgets.h @@ -0,0 +1,14 @@ +#pragma once + +#include "Definitions.h" + +class _LocationWidgets +{ +public: + virtual ~_LocationWidgets() = default; + + virtual void process() = 0; + virtual std::string getLocationName() = 0; + virtual int getLocationIndex() const = 0; + virtual void setLocationIndex(int locationIndex) = 0; +}; \ No newline at end of file diff --git a/source/Gui/PatternAnalysisDialog.h b/source/Gui/PatternAnalysisDialog.h new file mode 100644 index 000000000..0415f5356 --- /dev/null +++ b/source/Gui/PatternAnalysisDialog.h @@ -0,0 +1,101 @@ +#pragma once + +#include "Base/Singleton.h" +#include "EngineInterface/Descriptions.h" +#include "EngineInterface/SimulationFacade.h" + +#include "Definitions.h" +#include "MainLoopEntity.h" + +class PatternAnalysisDialog : public MainLoopEntity +{ + MAKE_SINGLETON(PatternAnalysisDialog); + +public: + void show(); + +private: + void init(SimulationFacade simulationFacade) override; + void process() override; + void shutdown() override; + void saveRepetitiveActiveClustersToFiles(std::string const& filename); + + struct CellAnalysisDescription + { + int maxConnections; + int numConnections; + bool constructionState; + std::optional inputExecutionOrderNumber; + bool outputBlocked; + int executionOrderNumber; + int color; + int cellFunction; + + bool operator==(CellAnalysisDescription const& other) const + { + return maxConnections == other.maxConnections && numConnections == other.numConnections && constructionState == other.constructionState + && inputExecutionOrderNumber == other.inputExecutionOrderNumber && outputBlocked == other.outputBlocked && executionOrderNumber == other.executionOrderNumber + && cellFunction == other.cellFunction + && color == other.color; + } + + bool operator!=(CellAnalysisDescription const& other) const { return !operator==(other); } + + bool operator<(CellAnalysisDescription const& other) const + { + if (maxConnections != other.maxConnections) { + return maxConnections < other.maxConnections; + } + if (numConnections != other.numConnections) { + return numConnections < other.numConnections; + } + if (constructionState != other.constructionState) { + return constructionState < other.constructionState; + } + if (inputExecutionOrderNumber != other.inputExecutionOrderNumber) { + return inputExecutionOrderNumber < other.inputExecutionOrderNumber; + } + if (outputBlocked != other.outputBlocked) { + return outputBlocked < other.outputBlocked; + } + if (executionOrderNumber != other.executionOrderNumber) { + return executionOrderNumber < other.executionOrderNumber; + } + if (cellFunction != other.cellFunction) { + return cellFunction < other.cellFunction; + } + if (color != other.color) { + return color < other.color; + } + return false; + } + }; + struct ClusterAnalysisDescription + { + std::set> connectedCells; + + bool operator<(ClusterAnalysisDescription const& other) const + { + if (connectedCells != other.connectedCells) { + return connectedCells < other.connectedCells; + } + return false; + } + }; + struct PartitionClassData + { + int numberOfElements = 0; + ClusterDescription representant; + + bool operator<(PartitionClassData const& other) const { return numberOfElements < other.numberOfElements; }; + }; + + std::map calcPartitionData() const; + + ClusterAnalysisDescription getAnalysisDescription(ClusterDescription const& cluster) const; + +private: + SimulationFacade _simulationFacade; + + std::string _startingPath; +}; diff --git a/source/Gui/ShaderWindow.h b/source/Gui/ShaderWindow.h new file mode 100644 index 000000000..c91b9be5c --- /dev/null +++ b/source/Gui/ShaderWindow.h @@ -0,0 +1,16 @@ +#pragma once + +#include "Base/Singleton.h" + +#include "AlienWindow.h" +#include "Definitions.h" + +class ShaderWindow : public AlienWindow<> +{ + MAKE_SINGLETON_NO_DEFAULT_CONSTRUCTION(ShaderWindow); + +private: + ShaderWindow(); + + void processIntern() override; +}; \ No newline at end of file diff --git a/source/Gui/SimulationParametersBaseWidgets.h b/source/Gui/SimulationParametersBaseWidgets.h new file mode 100644 index 000000000..4d89b082c --- /dev/null +++ b/source/Gui/SimulationParametersBaseWidgets.h @@ -0,0 +1,23 @@ +#pragma once + +#include "EngineInterface/Definitions.h" + +#include "LocationWidgets.h" +#include "ZoneColorPalette.h" + +class _SimulationParametersBaseWidgets : public _LocationWidgets +{ +public: + void init(SimulationFacade const& simulationFacade); + void process() override; + std::string getLocationName() override; + int getLocationIndex() const override; + void setLocationIndex(int locationIndex) override; + +private: + SimulationFacade _simulationFacade; + + ZoneColorPalette _zoneColorPalette; + uint32_t _backupColor = 0; + std::vector _cellFunctionStrings; +}; diff --git a/source/Gui/SimulationParametersSourceWidgets.h b/source/Gui/SimulationParametersSourceWidgets.h new file mode 100644 index 000000000..1df3bee66 --- /dev/null +++ b/source/Gui/SimulationParametersSourceWidgets.h @@ -0,0 +1,23 @@ +#pragma once + +#include + +#include "EngineInterface/Definitions.h" +#include "LocationWidgets.h" +#include "ZoneColorPalette.h" + +class _SimulationParametersSourceWidgets : public _LocationWidgets +{ +public: + void init(SimulationFacade const& simulationFacade, int locationIndex); + void process() override; + std::string getLocationName() override; + int getLocationIndex() const override; + void setLocationIndex(int locationIndex) override; + +private: + SimulationFacade _simulationFacade; + + int _locationIndex = 0; + std::string _sourceName; +}; diff --git a/source/Gui/SimulationParametersZoneWidgets.h b/source/Gui/SimulationParametersZoneWidgets.h new file mode 100644 index 000000000..82c550486 --- /dev/null +++ b/source/Gui/SimulationParametersZoneWidgets.h @@ -0,0 +1,28 @@ +#pragma once + +#include "EngineInterface/SimulationParametersZone.h" +#include "EngineInterface/Definitions.h" + +#include "LocationWidgets.h" +#include "ZoneColorPalette.h" + +class _SimulationParametersZoneWidgets : public _LocationWidgets +{ +public: + void init(SimulationFacade const& simulationFacade, int locationIndex); + void process() override; + std::string getLocationName() override; + int getLocationIndex() const override; + void setLocationIndex(int locationIndex) override; + +private: + void setDefaultSpotData(SimulationParametersZone& spot) const; + + SimulationFacade _simulationFacade; + + int _locationIndex = 0; + ZoneColorPalette _zoneColorPalette; + uint32_t _backupColor = 0; + std::vector _cellFunctionStrings; + std::string _zoneName; +}; diff --git a/source/Gui/SimulationScrollbar.cpp b/source/Gui/SimulationScrollbar.cpp new file mode 100644 index 000000000..5e86713e8 --- /dev/null +++ b/source/Gui/SimulationScrollbar.cpp @@ -0,0 +1,110 @@ +#include "SimulationScrollbar.h" + +#include + +#include + +#include "EngineInterface/SimulationFacade.h" +#include "Viewport.h" +#include "StyleRepository.h" + +_SimulationScrollbar::_SimulationScrollbar( + std::string const& id, + Orientation orientation, + SimulationFacade const& simulationFacade) + : _id(id) + , _orientation(orientation) + , _simulationFacade(simulationFacade) +{} + +void _SimulationScrollbar::process(RealRect const& rect) +{ + processEvents(rect); + + auto size = rect.bottomRight - rect.topLeft; + auto sliderbarRect = calcSliderbarRect(rect); + ImGuiWindowFlags windowFlags = + ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoDecoration; + + ImGui::SetNextWindowPos(ImVec2(rect.topLeft.x, rect.topLeft.y)); + ImGui::SetNextWindowSize(ImVec2(size.x, size.y)); + ImGui::SetNextWindowBgAlpha(Const::WindowAlpha * ImGui::GetStyle().Alpha); + ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0); + ImGui::Begin(_id.c_str(), NULL, windowFlags); + + ImColor sliderColor = doesMouseCursorIntersectSliderBar(rect) ? ImColor(Const::SimulationSliderColor_Active) + : ImColor(Const::SimulationSliderColor_Base); + sliderColor.Value.w *= ImGui::GetStyle().Alpha; + ImGui::GetWindowDrawList()->AddRectFilled( + ImVec2(rect.topLeft.x + sliderbarRect.topLeft.x, rect.topLeft.y + sliderbarRect.topLeft.y), + ImVec2(rect.topLeft.x + sliderbarRect.bottomRight.x, rect.topLeft.y + sliderbarRect.bottomRight.y), + sliderColor, + 5.0f); + + ImGui::End(); + ImGui::PopStyleVar(); +} + +void _SimulationScrollbar::processEvents(RealRect const& rect) +{ + if (ImGui::IsMouseClicked(ImGuiMouseButton_Left)) { + if (doesMouseCursorIntersectSliderBar(rect)) { + _worldCenterForDragging = Viewport::get().getCenterInWorldPos(); + } + } + if (ImGui::IsMouseDragging(ImGuiMouseButton_Left) && _worldCenterForDragging) { + auto dragViewDelta = ImGui::GetMouseDragDelta(); + auto scrollbarSize = rect.bottomRight - rect.topLeft; + auto worldSize = _simulationFacade->getWorldSize(); + auto dragWorldDelta = RealVector2D{ + dragViewDelta.x / scrollbarSize.x * worldSize.x, dragViewDelta.y / scrollbarSize.y * worldSize.y}; + auto centerInWorldPos = Viewport::get().getCenterInWorldPos(); + if (Orientation::Horizontal == _orientation) { + centerInWorldPos.x = _worldCenterForDragging->x + dragWorldDelta.x; + } else { + centerInWorldPos.y = _worldCenterForDragging->y + dragWorldDelta.y; + } + Viewport::get().setCenterInWorldPos(centerInWorldPos); + } + if (ImGui::IsMouseReleased(ImGuiMouseButton_Left)) { + _worldCenterForDragging = std::nullopt; + } +} + +RealRect _SimulationScrollbar::calcSliderbarRect(RealRect const& scrollbarRect) const +{ + auto size2d = scrollbarRect.bottomRight - scrollbarRect.topLeft; + auto worldSize = + Orientation::Horizontal == _orientation ? _simulationFacade->getWorldSize().x : _simulationFacade->getWorldSize().y; + auto size = Orientation::Horizontal == _orientation ? size2d.x : size2d.y; + + auto worldRect = Viewport::get().getVisibleWorldRect(); + auto startWorldPos = Orientation::Horizontal == _orientation ? worldRect.topLeft.x : worldRect.topLeft.y; + auto endWorldPos = Orientation::Horizontal == _orientation ? worldRect.bottomRight.x : worldRect.bottomRight.y; + + auto sliderBarStartPos = std::min(std::max(startWorldPos / worldSize * size, 0.0f), size); + auto sliderBarEndPos = std::min(std::max(endWorldPos / worldSize * size, 0.0f), size); + if (sliderBarEndPos < sliderBarStartPos) { + sliderBarEndPos = sliderBarStartPos; + } + auto sliderBarPos = + Orientation::Horizontal == _orientation ? ImVec2{4 + sliderBarStartPos, 4} : ImVec2{4, 4 + sliderBarStartPos}; + auto sliderBarSize = Orientation::Horizontal == _orientation ? ImVec2{sliderBarEndPos - sliderBarStartPos - 8, 10} + : ImVec2{10, sliderBarEndPos - sliderBarStartPos - 8}; + + sliderBarSize = {std::max(10.0f, sliderBarSize.x), std::max(10.0f, sliderBarSize.y)}; + + return { + {sliderBarPos.x, sliderBarPos.y}, {sliderBarPos.x + sliderBarSize.x - 1, sliderBarPos.y + sliderBarSize.y - 1}}; +} + +bool _SimulationScrollbar::doesMouseCursorIntersectSliderBar(RealRect const& rect) const +{ + auto sliderbarRect = calcSliderbarRect(rect); + + ImVec2 mousePositionAbsolute = ImGui::GetMousePos(); + return mousePositionAbsolute.x >= rect.topLeft.x + sliderbarRect.topLeft.x - 3 + && mousePositionAbsolute.x <= rect.topLeft.x + sliderbarRect.bottomRight.x + 3 + && mousePositionAbsolute.y >= rect.topLeft.y + sliderbarRect.topLeft.y - 3 + && mousePositionAbsolute.y <= rect.topLeft.y + sliderbarRect.bottomRight.y + 3; +} diff --git a/source/Gui/SimulationScrollbar.h b/source/Gui/SimulationScrollbar.h new file mode 100644 index 000000000..7349f5c7b --- /dev/null +++ b/source/Gui/SimulationScrollbar.h @@ -0,0 +1,30 @@ +#pragma once + +#include "Base/Definitions.h" +#include "EngineInterface/Definitions.h" + +#include "Definitions.h" + +class _SimulationScrollbar +{ +public: + enum class Orientation + { + Horizontal, + Vertical + }; + _SimulationScrollbar(std::string const& id, Orientation orientation, SimulationFacade const& simulationFacade); + + void process(RealRect const& rect); + +private: + void processEvents(RealRect const& rect); + RealRect calcSliderbarRect(RealRect const& scrollbarRect) const; + bool doesMouseCursorIntersectSliderBar(RealRect const& rect) const; + + std::string _id; + Orientation _orientation = Orientation::Horizontal; + SimulationFacade _simulationFacade; + + std::optional _worldCenterForDragging; +}; \ No newline at end of file diff --git a/source/Gui/ZoneColorPalette.cpp b/source/Gui/ZoneColorPalette.cpp new file mode 100644 index 000000000..047727f80 --- /dev/null +++ b/source/Gui/ZoneColorPalette.cpp @@ -0,0 +1,23 @@ +#include "ZoneColorPalette.h" + +#include + +ZoneColorPalette::ZoneColorPalette() +{ + for (int n = 0; n < IM_ARRAYSIZE(_palette); n++) { + ImVec4 color; + ImGui::ColorConvertHSVtoRGB(n / 31.0f, 0.8f, 0.2f, color.x, color.y, color.z); + color.w = 1.0f; + _palette[n] = ImColor(color); + } +} + +uint32_t ZoneColorPalette::getColor(int index) const +{ + return _palette[index % IM_ARRAYSIZE(_palette)]; +} + +auto ZoneColorPalette::getReference()-> Palette& +{ + return _palette; +} diff --git a/source/Gui/ZoneColorPalette.h b/source/Gui/ZoneColorPalette.h new file mode 100644 index 000000000..e8cbabe96 --- /dev/null +++ b/source/Gui/ZoneColorPalette.h @@ -0,0 +1,17 @@ +#pragma once + +#include + +class ZoneColorPalette +{ +public: + ZoneColorPalette(); + + uint32_t getColor(int index) const; + + using Palette = uint32_t[32]; + Palette& getReference(); + +private: + uint32_t _palette[32] = {}; +}; From 32011b375b5895d1e9aa1d73d7699ecfc513cf56 Mon Sep 17 00:00:00 2001 From: zysftd Date: Sun, 12 Jul 2026 20:38:17 +0800 Subject: [PATCH 04/15] feat: add _() wrappers for all GUI strings and language selection --- source/Gui/AboutDialog.cpp | 6 +- source/Gui/ActivateUserDialog.cpp | 22 +- source/Gui/AutosaveWindow.cpp | 56 ++--- source/Gui/BrowserWindow.cpp | 92 +++---- source/Gui/ChangeColorDialog.cpp | 12 +- source/Gui/CreateUserDialog.cpp | 26 +- source/Gui/CreatorWindow.cpp | 44 ++-- source/Gui/DeleteUserDialog.cpp | 14 +- source/Gui/DisplaySettingsDialog.cpp | 40 ++- source/Gui/DisplaySettingsDialog.h | 2 + source/Gui/EditSimulationDialog.cpp | 20 +- source/Gui/EditorController.cpp | 6 +- source/Gui/ExitDialog.cpp | 8 +- source/Gui/FileTransferController.cpp | 6 +- source/Gui/GenericMessageDialog.cpp | 8 +- source/Gui/GenomeEditorWindow.cpp | 2 +- source/Gui/GettingStartedWindow.cpp | 22 +- source/Gui/GpuSettingsDialog.cpp | 12 +- source/Gui/InspectionWindow.cpp | 232 +++++++++--------- source/Gui/LogWindow.cpp | 4 +- source/Gui/LoginDialog.cpp | 24 +- source/Gui/MainLoopController.cpp | 90 +++---- source/Gui/MassOperationsDialog.cpp | 26 +- source/Gui/MultiplierWindow.cpp | 26 +- source/Gui/NetworkSettingsDialog.cpp | 8 +- source/Gui/NetworkTransferController.cpp | 12 +- source/Gui/NewPasswordDialog.cpp | 14 +- source/Gui/NewSimulationDialog.cpp | 14 +- source/Gui/PatternEditorWindow.cpp | 44 ++-- source/Gui/PreviewSettingsDialog.cpp | 8 +- source/Gui/ResetPasswordDialog.cpp | 14 +- source/Gui/ResizeWorldDialog.cpp | 12 +- source/Gui/SelectionWindow.cpp | 10 +- source/Gui/SignalsBufferDialog.cpp | 8 +- source/Gui/SimulationParametersMainWindow.cpp | 54 ++-- source/Gui/SpatialControlWindow.cpp | 20 +- source/Gui/StatisticsWindow.cpp | 88 +++---- source/Gui/TemporalControlWindow.cpp | 28 +-- source/Gui/UploadSimulationDialog.cpp | 14 +- 39 files changed, 587 insertions(+), 561 deletions(-) diff --git a/source/Gui/AboutDialog.cpp b/source/Gui/AboutDialog.cpp index c372b90ba..bd991fcd4 100644 --- a/source/Gui/AboutDialog.cpp +++ b/source/Gui/AboutDialog.cpp @@ -8,19 +8,19 @@ #include "StyleRepository.h" AboutDialog::AboutDialog() - : AlienDialog("About") + : AlienDialog(_("About")) {} void AboutDialog::processIntern() { ImGui::Text( - "Artificial Life Environment, version %s\n\nis an open source project initiated and maintained by\nChristian Heinemann.", + _("Artificial Life Environment, version %s\n\nis an open source project initiated and maintained by\nChristian Heinemann."), Const::ProgramVersion.c_str()); ImGui::Dummy({0, ImGui::GetContentRegionAvail().y - scale(50.0f)}); AlienGui::Separator(); - if (AlienGui::Button("OK")) { + if (AlienGui::Button(_("OK"))) { close(); } ImGui::SetItemDefaultFocus(); diff --git a/source/Gui/ActivateUserDialog.cpp b/source/Gui/ActivateUserDialog.cpp index 13f982de5..2b0c93c97 100644 --- a/source/Gui/ActivateUserDialog.cpp +++ b/source/Gui/ActivateUserDialog.cpp @@ -26,22 +26,22 @@ void ActivateUserDialog::open(std::string const& userName, std::string const& pa } ActivateUserDialog::ActivateUserDialog() - : AlienDialog("Activate user") + : AlienDialog(_("Activate user")) {} void ActivateUserDialog::processIntern() { - AlienGui::Text("Please enter the confirmation code sent to your email address."); + AlienGui::Text(_("Please enter the confirmation code sent to your email address.")); AlienGui::HelpMarker( - "Please check your spam folder if you did not find an email. If you did not receive an email there, try signing up with possibly another " - "email address. If this still does not work, please contact info@alien-project.org."); + _("Please check your spam folder if you did not find an email. If you did not receive an email there, try signing up with possibly another " + "email address. If this still does not work, please contact info@alien-project.org.")); AlienGui::Separator(); - AlienGui::InputText(AlienGui::InputTextParameters().hint("Code (case sensitive)").textWidth(0), _confirmationCode); + AlienGui::InputText(AlienGui::InputTextParameters().hint(_("Code (case sensitive)")).textWidth(0), _confirmationCode); AlienGui::Separator(); ImGui::BeginDisabled(_confirmationCode.empty()); - if (AlienGui::Button("OK")) { + if (AlienGui::Button(_("OK"))) { close(); onActivateUser(); } @@ -52,12 +52,12 @@ void ActivateUserDialog::processIntern() AlienGui::VerticalSeparator(); ImGui::SameLine(); - if (AlienGui::Button("Resend")) { + if (AlienGui::Button(_("Resend"))) { CreateUserDialog::get().onCreateUser(); } ImGui::SameLine(); - if (AlienGui::Button("Resend to other email address")) { + if (AlienGui::Button(_("Resend to other email address"))) { close(); CreateUserDialog::get().open(_userName, _password, _userInfo); } @@ -66,7 +66,7 @@ void ActivateUserDialog::processIntern() AlienGui::VerticalSeparator(); ImGui::SameLine(); - if (AlienGui::Button("Cancel")) { + if (AlienGui::Button(_("Cancel"))) { close(); } } @@ -79,10 +79,10 @@ void ActivateUserDialog::onActivateUser() result |= NetworkService::get().login(errorCode, _userName, _password, _userInfo); } if (!result) { - GenericMessageDialog::get().information("Error", "An error occurred on the server. Your entered code may be incorrect.\nPlease try to register again."); + GenericMessageDialog::get().information(_("Error"), _("An error occurred on the server. Your entered code may be incorrect.\nPlease try to register again.")); } else { GenericMessageDialog::get().information( - "Information", + _("Information"), "The user '" + _userName + "' has been successfully created.\nYou are logged in and are now able to upload your own simulations\nor upvote others by likes."); BrowserWindow::get().onRefresh(); diff --git a/source/Gui/AutosaveWindow.cpp b/source/Gui/AutosaveWindow.cpp index 1f609c913..7bc0bf6ba 100644 --- a/source/Gui/AutosaveWindow.cpp +++ b/source/Gui/AutosaveWindow.cpp @@ -29,7 +29,7 @@ namespace } AutosaveWindow::AutosaveWindow() - : AlienWindow("Autosave", "windows.autosave", false, true) + : AlienWindow(_("Autosave"), "windows.autosave", false, true) {} void AutosaveWindow::initIntern() @@ -95,7 +95,7 @@ void AutosaveWindow::processIntern() validateAndCorrect(); } catch (std::runtime_error const& error) { - GenericMessageDialog::get().information("Error", error.what()); + GenericMessageDialog::get().information(_("Error"), error.what()); } } @@ -116,22 +116,22 @@ void AutosaveWindow::processToolbar() onCreateSavepoint(false); } ImGui::EndDisabled(); - AlienGui::Tooltip("Create save point"); + AlienGui::Tooltip(_("Create save point")); ImGui::SameLine(); ImGui::BeginDisabled(!static_cast(_selectedEntry)); if (AlienGui::ToolbarButton(AlienGui::ToolbarButtonParameters().text(ICON_FA_MINUS))) { onDeleteSavepoint(_selectedEntry); } - AlienGui::Tooltip("Delete save point"); + AlienGui::Tooltip(_("Delete save point")); ImGui::EndDisabled(); ImGui::SameLine(); ImGui::BeginDisabled(!_savepointTable.has_value() || _savepointTable->isEmpty()); if (AlienGui::ToolbarButton(AlienGui::ToolbarButtonParameters().text(ICON_FA_BROOM))) { - GenericMessageDialog::get().yesNo("Delete", "Do you really want to delete all savepoints?", [&]() { scheduleCleanup(); }); + GenericMessageDialog::get().yesNo(_("Delete"), _("Do you really want to delete all savepoints?"), [&]() { scheduleCleanup(); }); } - AlienGui::Tooltip("Delete all save points"); + AlienGui::Tooltip(_("Delete all save points")); ImGui::EndDisabled(); AlienGui::Separator(); @@ -142,16 +142,16 @@ void AutosaveWindow::processHeader() {} void AutosaveWindow::processTable() { if (!_savepointTable.has_value()) { - AlienGui::Text("Error: Savepoint files could not be read or created in the specified directory."); + AlienGui::Text(_("Error: Savepoint files could not be read or created in the specified directory.")); return; } static ImGuiTableFlags flags = ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable | ImGuiTableFlags_RowBg | ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersV | ImGuiTableFlags_ScrollY | ImGuiTableFlags_ScrollX; if (ImGui::BeginTable("Save files", 3, flags, ImVec2(-1, -1), 0.0f)) { - ImGui::TableSetupColumn("Simulation", ImGuiTableColumnFlags_NoSort | ImGuiTableColumnFlags_WidthFixed, scale(140.0f)); - ImGui::TableSetupColumn("Timestamp", ImGuiTableColumnFlags_NoSort | ImGuiTableColumnFlags_WidthFixed, scale(140.0f)); - ImGui::TableSetupColumn("Time step", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, scale(100.0f)); + ImGui::TableSetupColumn(_("Simulation"), ImGuiTableColumnFlags_NoSort | ImGuiTableColumnFlags_WidthFixed, scale(140.0f)); + ImGui::TableSetupColumn(_("Timestamp"), ImGuiTableColumnFlags_NoSort | ImGuiTableColumnFlags_WidthFixed, scale(140.0f)); + ImGui::TableSetupColumn(_("Time step"), ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, scale(100.0f)); //ImGui::TableSetupColumn("Peak value", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, scale(200.0f)); ImGui::TableSetupScrollFreeze(0, 1); ImGui::TableHeadersRow(); @@ -170,15 +170,15 @@ void AutosaveWindow::processTable() ImGui::TableNextColumn(); if (entry->state == SavepointState_InQueue) { ImGui::PushStyleColor(ImGuiCol_Text, Const::TextDecentColor.Value); - AlienGui::Text("In queue"); + AlienGui::Text(_("In queue")); ImGui::PopStyleColor(); } else if (entry->state == SavepointState_InProgress) { ImGui::PushStyleColor(ImGuiCol_Text, Const::TextDecentColor.Value); - AlienGui::Text("In progress"); + AlienGui::Text(_("In progress")); ImGui::PopStyleColor(); } else if (entry->state == SavepointState_Persisted) { auto triggerLoadSavepoint = AlienGui::ActionButton(AlienGui::ActionButtonParameters().buttonText(ICON_FA_DOWNLOAD)); - AlienGui::Tooltip("Load save point", false); + AlienGui::Tooltip(_("Load save point"), false); if (triggerLoadSavepoint) { onLoadSavepoint(entry); } @@ -186,7 +186,7 @@ void AutosaveWindow::processTable() ImGui::SameLine(); AlienGui::Text(entry->name); } else if (entry->state == SavepointState_Error) { - AlienGui::Text("Error"); + AlienGui::Text(_("Error")); } ImGui::SameLine(); ImGui::Dummy({0, scale(22.0f)}); @@ -237,11 +237,11 @@ void AutosaveWindow::processSettings() AlienGui::MovableHorizontalSeparator(AlienGui::MovableHorizontalSeparatorParameters().additive(false), _settingsHeight); } - _settingsOpen = AlienGui::BeginTreeNode(AlienGui::TreeNodeParameters().name("Settings").rank(AlienGui::TreeNodeRank::High).defaultOpen(_settingsOpen)); + _settingsOpen = AlienGui::BeginTreeNode(AlienGui::TreeNodeParameters().name(_("Settings")).rank(AlienGui::TreeNodeRank::High).defaultOpen(_settingsOpen)); if (_settingsOpen) { if (ImGui::BeginChild("##autosaveSettings", {scale(0), 0})) { if (AlienGui::InputInt( - AlienGui::InputIntParameters().name("Autosave interval (min)").textWidth(RightColumnWidth).defaultValue(_origAutosaveInterval), + AlienGui::InputIntParameters().name(_("Autosave interval (min)")).textWidth(RightColumnWidth).defaultValue(_origAutosaveInterval), _autosaveInterval, &_autosaveEnabled)) { if (_autosaveEnabled) { @@ -266,25 +266,25 @@ void AutosaveWindow::processSettings() if (AlienGui::InputText( AlienGui::InputTextParameters() - .name("Directory") + .name(_("Directory")) .textWidth(RightColumnWidth) .defaultValue(_origDirectory) .folderButton(true) - .tooltip("The directory where the savepoints are stored can be chosen here. This allows the savepoints to be created in a separate " - "directory for a simulation run. The savepoints are named using the current time step."), + .tooltip(_("The directory where the savepoints are stored can be chosen here. This allows the savepoints to be created in a separate " + "directory for a simulation run. The savepoints are named using the current time step.")), _directory)) { updateSavepointTableFromFile(); } AlienGui::Switcher( AlienGui::SwitcherParameters() - .name("Mode") - .values({"Limited save files", "Unlimited save files"}) + .name(_("Mode")) + .values({_("Limited save files"), _("Unlimited save files")}) .textWidth(RightColumnWidth) .defaultValue(_origSaveMode), &_saveMode); if (_saveMode == SaveMode_Circular) { AlienGui::InputInt( - AlienGui::InputIntParameters().name("Number of files").textWidth(RightColumnWidth).defaultValue(_origNumberOfFiles), _numberOfFiles); + AlienGui::InputIntParameters().name(_("Number of files")).textWidth(RightColumnWidth).defaultValue(_origNumberOfFiles), _numberOfFiles); } } ImGui::EndChild(); @@ -296,9 +296,9 @@ void AutosaveWindow::processStatusBar() { std::vector statusItems; if (!_savepointTable.has_value()) { - statusItems.emplace_back("No valid directory"); + statusItems.emplace_back(_("No valid directory")); } else if (!_autosaveEnabled) { - statusItems.emplace_back("No autosave scheduled"); + statusItems.emplace_back(_("No autosave scheduled")); } else { auto secondsSinceLastAutosave = std::chrono::duration_cast(std::chrono::steady_clock::now() - _lastAutosaveTimepoint); statusItems.emplace_back("Next autosave in " + StringHelper::format(std::chrono::seconds(_autosaveInterval * 60) - secondsSinceLastAutosave)); @@ -312,7 +312,7 @@ void AutosaveWindow::processStatusBar() void AutosaveWindow::onCreateSavepoint(bool usePeakSimulation) { - printOverlayMessage("Creating save point ..."); + printOverlayMessage(_("Creating save point ...")); if (_saveMode == SaveMode_Circular) { auto nonPersistentEntries = SavepointTableService::get().truncate(_savepointTable.value(), _numberOfFiles - 1); @@ -342,7 +342,7 @@ void AutosaveWindow::onCreateSavepoint(bool usePeakSimulation) void AutosaveWindow::onDeleteSavepoint(SavepointEntry const& entry) { - printOverlayMessage("Deleting save point ..."); + printOverlayMessage(_("Deleting save point ...")); SavepointTableService::get().deleteEntry(_savepointTable.value(), entry); @@ -370,7 +370,7 @@ void AutosaveWindow::processStateUpdates() void AutosaveWindow::processCleanup() { if (_scheduleCleanup) { - printOverlayMessage("Cleaning up save points ..."); + printOverlayMessage(_("Cleaning up save points ...")); auto nonPersistentEntries = SavepointTableService::get().truncate(_savepointTable.value(), 0); scheduleDeleteNonPersistentSavepoint(nonPersistentEntries); @@ -410,7 +410,7 @@ void AutosaveWindow::processAutomaticSavepoints() .center = Viewport::get().getCenterInWorldPos()}); }, [&](auto const& requestId) {}, - [](auto const& errors) { GenericMessageDialog::get().information("Error", errors); }); + [](auto const& errors) { GenericMessageDialog::get().information(_("Error"), errors); }); _lastPeakTimepoint = std::chrono::steady_clock::now(); } } diff --git a/source/Gui/BrowserWindow.cpp b/source/Gui/BrowserWindow.cpp index 77e89f21a..fba49ccc4 100644 --- a/source/Gui/BrowserWindow.cpp +++ b/source/Gui/BrowserWindow.cpp @@ -61,7 +61,7 @@ namespace } BrowserWindow::BrowserWindow() - : AlienWindow("Browser", "windows.browser", true, true) + : AlienWindow(_("Browser"), "windows.browser", true, true) {} namespace @@ -235,7 +235,7 @@ void BrowserWindow::processToolbar() onRefresh(); } ImGui::EndDisabled(); - AlienGui::Tooltip("Refresh"); + AlienGui::Tooltip(_("Refresh")); //login button ImGui::SameLine(); @@ -244,7 +244,7 @@ void BrowserWindow::processToolbar() LoginDialog::get().open(); } ImGui::EndDisabled(); - AlienGui::Tooltip("Login or register"); + AlienGui::Tooltip(_("Login or register")); //logout button ImGui::SameLine(); @@ -254,7 +254,7 @@ void BrowserWindow::processToolbar() onRefresh(); } ImGui::EndDisabled(); - AlienGui::Tooltip("Logout"); + AlienGui::Tooltip(_("Logout")); //separator ImGui::SameLine(); @@ -284,7 +284,7 @@ void BrowserWindow::processToolbar() onEditResource(_selectedTreeTO); } ImGui::EndDisabled(); - AlienGui::Tooltip("Change name or description"); + AlienGui::Tooltip(_("Change name or description")); //replace button ImGui::SameLine(); @@ -323,14 +323,14 @@ void BrowserWindow::processToolbar() if (AlienGui::ToolbarButton(AlienGui::ToolbarButtonParameters().text(ICON_FA_EXPAND_ARROWS_ALT))) { onExpandFolders(); } - AlienGui::Tooltip("Expand all folders"); + AlienGui::Tooltip(_("Expand all folders")); //collapse button ImGui::SameLine(); if (AlienGui::ToolbarButton(AlienGui::ToolbarButtonParameters().text(ICON_FA_COMPRESS_ARROWS_ALT))) { onCollapseFolders(); } - AlienGui::Tooltip("Collapse all folders"); + AlienGui::Tooltip(_("Collapse all folders")); #ifdef _WIN32 //separator @@ -342,7 +342,7 @@ void BrowserWindow::processToolbar() if (AlienGui::ToolbarButton(AlienGui::ToolbarButtonParameters().text(ICON_FA_COMMENTS))) { openWeblink(Const::DiscordURL); } - AlienGui::Tooltip("Open ALIEN Discord server"); + AlienGui::Tooltip(_("Open ALIEN Discord server")); #endif AlienGui::Separator(); @@ -357,7 +357,7 @@ void BrowserWindow::processWorkspace() false, ImGuiWindowFlags_HorizontalScrollbar)) { if (ImGui::BeginTabBar("##Type", ImGuiTabBarFlags_FittingPolicyResizeDown)) { - if (ImGui::BeginTabItem("Simulations", nullptr, ImGuiTabItemFlags_None)) { + if (ImGui::BeginTabItem(_("Simulations"), nullptr, ImGuiTabItemFlags_None)) { if (_currentWorkspace.resourceType != NetworkResourceType_Simulation) { _currentWorkspace.resourceType = NetworkResourceType_Simulation; _selectedTreeTO = nullptr; @@ -365,7 +365,7 @@ void BrowserWindow::processWorkspace() processSimulationList(); ImGui::EndTabItem(); } - if (ImGui::BeginTabItem("Genomes", nullptr, ImGuiTabItemFlags_None)) { + if (ImGui::BeginTabItem(_("Genomes"), nullptr, ImGuiTabItemFlags_None)) { if (_currentWorkspace.resourceType != NetworkResourceType_Genome) { _currentWorkspace.resourceType = NetworkResourceType_Genome; _selectedTreeTO = nullptr; @@ -396,7 +396,7 @@ void BrowserWindow::processWorkspaceSelectionAndFilter() AlienGui::SwitcherParameters() .textWidth(48.0f) .tooltip(Const::BrowserWorkspaceTooltip) - .values({privateWorkspaceString, std::string("alien-project's workspace"), std::string("Public workspace")}), + .values({privateWorkspaceString, _("alien-project's workspace"), _("Public workspace")}), &workspaceType_reordered)) { _selectedTreeTO = nullptr; } @@ -440,22 +440,22 @@ void BrowserWindow::processUserList() | ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersV | ImGuiTableFlags_ScrollY | ImGuiTableFlags_ScrollX; if (ImGui::BeginTabBar("##Simulators", ImGuiTabBarFlags_FittingPolicyResizeDown)) { - if (ImGui::BeginTabItem("Simulators", nullptr, ImGuiTabItemFlags_None)) { + if (ImGui::BeginTabItem(_("Simulators"), nullptr, ImGuiTabItemFlags_None)) { if (ImGui::BeginTable("Browser", 5, flags, ImVec2(-1, -1), 0.0f)) { - ImGui::TableSetupColumn("Name", ImGuiTableColumnFlags_PreferSortDescending | ImGuiTableColumnFlags_WidthFixed, scale(90.0f)); + ImGui::TableSetupColumn(_("Name"), ImGuiTableColumnFlags_PreferSortDescending | ImGuiTableColumnFlags_WidthFixed, scale(90.0f)); auto isLoggedIn = NetworkService::get().getLoggedInUserName().has_value(); ImGui::TableSetupColumn( - isLoggedIn ? "GPU model" : "GPU (visible if logged in)", + isLoggedIn ? _("GPU model") : _("GPU (visible if logged in)"), ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, styleRepository.scale(200.0f)); - ImGui::TableSetupColumn("Time spent", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, styleRepository.scale(80.0f)); + ImGui::TableSetupColumn(_("Time spent"), ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, styleRepository.scale(80.0f)); ImGui::TableSetupColumn( - "Reactions received", + _("Reactions received"), ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_PreferSortDescending, scale(120.0f)); ImGui::TableSetupColumn( - "Reactions given", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, styleRepository.scale(100.0f)); + _("Reactions given"), ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, styleRepository.scale(100.0f)); ImGui::TableSetupScrollFreeze(0, 1); ImGui::TableHeadersRow(); ImGui::TableSetBgColor(ImGuiTableBgTarget_RowBg0, Const::TableHeaderColor); @@ -551,7 +551,7 @@ void BrowserWindow::processStatusBar() statusItems.emplace_back("Server: " + NetworkService::get().getServerAddress()); if (!NetworkService::get().getLoggedInUserName()) { - statusItems.emplace_back("In order to share and upvote simulations you need to log in."); + statusItems.emplace_back(_("In order to share and upvote simulations you need to log in.")); } AlienGui::StatusBar(statusItems); @@ -565,21 +565,21 @@ void BrowserWindow::processSimulationList() | ImGuiTableFlags_ScrollX; if (ImGui::BeginTable("Browser", 11, flags, ImVec2(-1, -scale(WorkspaceBottomSpace)), 0.0f)) { - ImGui::TableSetupColumn("Simulation", ImGuiTableColumnFlags_WidthFixed, scale(210.0f), NetworkResourceColumnId_SimulationName); - ImGui::TableSetupColumn("Description", ImGuiTableColumnFlags_WidthFixed, scale(200.0f), NetworkResourceColumnId_Desc); - ImGui::TableSetupColumn("Reactions", ImGuiTableColumnFlags_WidthFixed, scale(140.0f), NetworkResourceColumnId_Likes); + ImGui::TableSetupColumn(_("Simulation"), ImGuiTableColumnFlags_WidthFixed, scale(210.0f), NetworkResourceColumnId_SimulationName); + ImGui::TableSetupColumn(_("Description"), ImGuiTableColumnFlags_WidthFixed, scale(200.0f), NetworkResourceColumnId_Desc); + ImGui::TableSetupColumn(_("Reactions"), ImGuiTableColumnFlags_WidthFixed, scale(140.0f), NetworkResourceColumnId_Likes); ImGui::TableSetupColumn( - "Timestamp", + _("Timestamp"), ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_PreferSortDescending, scale(135.0f), NetworkResourceColumnId_Timestamp); - ImGui::TableSetupColumn("User name", ImGuiTableColumnFlags_WidthFixed, scale(120.0f), NetworkResourceColumnId_UserName); - ImGui::TableSetupColumn("Downloads", ImGuiTableColumnFlags_WidthFixed, 0.0f, NetworkResourceColumnId_NumDownloads); - ImGui::TableSetupColumn("Width", ImGuiTableColumnFlags_WidthFixed, 0.0f, NetworkResourceColumnId_Width); - ImGui::TableSetupColumn("Height", ImGuiTableColumnFlags_WidthFixed, 0.0f, NetworkResourceColumnId_Height); - ImGui::TableSetupColumn("Objects", ImGuiTableColumnFlags_WidthFixed, 0.0f, NetworkResourceColumnId_Particles); - ImGui::TableSetupColumn("File size", ImGuiTableColumnFlags_WidthFixed, 0.0f, NetworkResourceColumnId_FileSize); - ImGui::TableSetupColumn("Version", ImGuiTableColumnFlags_WidthFixed, 0.0f, NetworkResourceColumnId_Version); + ImGui::TableSetupColumn(_("User name"), ImGuiTableColumnFlags_WidthFixed, scale(120.0f), NetworkResourceColumnId_UserName); + ImGui::TableSetupColumn(_("Downloads"), ImGuiTableColumnFlags_WidthFixed, 0.0f, NetworkResourceColumnId_NumDownloads); + ImGui::TableSetupColumn(_("Width"), ImGuiTableColumnFlags_WidthFixed, 0.0f, NetworkResourceColumnId_Width); + ImGui::TableSetupColumn(_("Height"), ImGuiTableColumnFlags_WidthFixed, 0.0f, NetworkResourceColumnId_Height); + ImGui::TableSetupColumn(_("Objects"), ImGuiTableColumnFlags_WidthFixed, 0.0f, NetworkResourceColumnId_Particles); + ImGui::TableSetupColumn(_("File size"), ImGuiTableColumnFlags_WidthFixed, 0.0f, NetworkResourceColumnId_FileSize); + ImGui::TableSetupColumn(_("Version"), ImGuiTableColumnFlags_WidthFixed, 0.0f, NetworkResourceColumnId_Version); ImGui::TableSetupScrollFreeze(0, 1); ImGui::TableHeadersRow(); ImGui::TableSetBgColor(ImGuiTableBgTarget_RowBg0, Const::TableHeaderColor); @@ -673,19 +673,19 @@ void BrowserWindow::processGenomeList() | ImGuiTableFlags_ScrollY | ImGuiTableFlags_ScrollX; if (ImGui::BeginTable("Browser", 9, flags, ImVec2(0, -scale(WorkspaceBottomSpace)), 0.0f)) { - ImGui::TableSetupColumn("Genome", ImGuiTableColumnFlags_WidthFixed, scale(210.0f), NetworkResourceColumnId_SimulationName); - ImGui::TableSetupColumn("Description", ImGuiTableColumnFlags_WidthFixed, scale(200.0f), NetworkResourceColumnId_Desc); - ImGui::TableSetupColumn("Reactions", ImGuiTableColumnFlags_WidthFixed, scale(140.0f), NetworkResourceColumnId_Likes); + ImGui::TableSetupColumn(_("Genome"), ImGuiTableColumnFlags_WidthFixed, scale(210.0f), NetworkResourceColumnId_SimulationName); + ImGui::TableSetupColumn(_("Description"), ImGuiTableColumnFlags_WidthFixed, scale(200.0f), NetworkResourceColumnId_Desc); + ImGui::TableSetupColumn(_("Reactions"), ImGuiTableColumnFlags_WidthFixed, scale(140.0f), NetworkResourceColumnId_Likes); ImGui::TableSetupColumn( - "Timestamp", + _("Timestamp"), ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_PreferSortDescending, scale(135.0f), NetworkResourceColumnId_Timestamp); - ImGui::TableSetupColumn("User name", ImGuiTableColumnFlags_WidthFixed, scale(120.0f), NetworkResourceColumnId_UserName); - ImGui::TableSetupColumn("Downloads", ImGuiTableColumnFlags_WidthFixed, 0.0f, NetworkResourceColumnId_NumDownloads); - ImGui::TableSetupColumn("Cells", ImGuiTableColumnFlags_WidthFixed, 0.0f, NetworkResourceColumnId_Particles); - ImGui::TableSetupColumn("File size", ImGuiTableColumnFlags_WidthFixed, 0.0f, NetworkResourceColumnId_FileSize); - ImGui::TableSetupColumn("Version", ImGuiTableColumnFlags_WidthFixed, 0.0f, NetworkResourceColumnId_Version); + ImGui::TableSetupColumn(_("User name"), ImGuiTableColumnFlags_WidthFixed, scale(120.0f), NetworkResourceColumnId_UserName); + ImGui::TableSetupColumn(_("Downloads"), ImGuiTableColumnFlags_WidthFixed, 0.0f, NetworkResourceColumnId_NumDownloads); + ImGui::TableSetupColumn(_("Cells"), ImGuiTableColumnFlags_WidthFixed, 0.0f, NetworkResourceColumnId_Particles); + ImGui::TableSetupColumn(_("File size"), ImGuiTableColumnFlags_WidthFixed, 0.0f, NetworkResourceColumnId_FileSize); + ImGui::TableSetupColumn(_("Version"), ImGuiTableColumnFlags_WidthFixed, 0.0f, NetworkResourceColumnId_Version); ImGui::TableSetupScrollFreeze(0, 1); ImGui::TableHeadersRow(); ImGui::TableSetBgColor(ImGuiTableBgTarget_RowBg0, Const::TableHeaderColor); @@ -779,7 +779,7 @@ bool BrowserWindow::processResourceNameField(NetworkResourceTreeTO const& treeTO ImGui::SameLine(); if (_currentWorkspace.workspaceType == WorkspaceType_Private && leaf.rawTO->workspaceType == WorkspaceType_Public) { AlienGui::Text(ICON_FA_SHARE_ALT); - AlienGui::Tooltip("Visible in the public workspace"); + AlienGui::Tooltip(_("Visible in the public workspace")); } ImGui::SameLine(); @@ -789,7 +789,7 @@ bool BrowserWindow::processResourceNameField(NetworkResourceTreeTO const& treeTO font->Scale *= 0.65f; ImGui::PushFont(font); ImGui::PushStyleColor(ImGuiCol_Text, Const::BrowserResourceNewTextColor.Value); - AlienGui::Text("NEW"); + AlienGui::Text(_("NEW")); ImGui::PopStyleColor(); font->Scale = origSize; ImGui::PopFont(); @@ -807,9 +807,9 @@ bool BrowserWindow::processResourceNameField(NetworkResourceTreeTO const& treeTO ImGui::PushStyleColor(ImGuiCol_Text, (ImU32)Const::TextDecentColor); std::string resourceTypeString = [&] { if (treeTO->type == NetworkResourceType_Simulation) { - return folder.numLeafs == 1 ? "sim" : "sims"; + return folder.numLeafs == 1 ? _("sim") : _("sims"); } else { - return folder.numLeafs == 1 ? "genome" : "genomes"; + return folder.numLeafs == 1 ? _("genome") : _("genomes"); } }(); AlienGui::Text("(" + std::to_string(folder.numLeafs) + " " + resourceTypeString + ")"); @@ -832,7 +832,7 @@ void BrowserWindow::processReactionList(NetworkResourceTreeTO const& treeTO) auto& leaf = treeTO->getLeaf(); auto isAddReaction = AlienGui::ActionButton(AlienGui::ActionButtonParameters().buttonText(ICON_FA_PLUS)); - AlienGui::Tooltip("Add a reaction", false); + AlienGui::Tooltip(_("Add a reaction"), false); if (isAddReaction) { _activateEmojiPopup = true; _emojiPopupTO = treeTO; @@ -1062,7 +1062,7 @@ void BrowserWindow::processEmojiWindow() _activateEmojiPopup = false; } if (ImGui::BeginPopup("emoji")) { - ImGui::Text("Choose a reaction"); + ImGui::Text("%s", _("Choose a reaction")); ImGui::Spacing(); ImGui::Spacing(); if (_showAllEmojis) { @@ -1090,7 +1090,7 @@ void BrowserWindow::processEmojiWindow() } ImGui::SetCursorPosY(ImGui::GetCursorPosY() + scale(8.0f)); - if (AlienGui::Button("More", ImGui::GetContentRegionAvail().x)) { + if (AlienGui::Button(_("More"), ImGui::GetContentRegionAvail().x)) { _showAllEmojis = true; } } @@ -1134,7 +1134,7 @@ void BrowserWindow::processEmojiButton(int emojiType) void BrowserWindow::processDownloadButton(BrowserLeaf const& leaf) { auto isDownload = AlienGui::ActionButton(AlienGui::ActionButtonParameters().buttonText(ICON_FA_DOWNLOAD)); - AlienGui::Tooltip("Download", false); + AlienGui::Tooltip(_("Download"), false); if (isDownload) { onDownloadResource(leaf); } diff --git a/source/Gui/ChangeColorDialog.cpp b/source/Gui/ChangeColorDialog.cpp index 9b70ae62b..ef37be62a 100644 --- a/source/Gui/ChangeColorDialog.cpp +++ b/source/Gui/ChangeColorDialog.cpp @@ -17,17 +17,17 @@ void ChangeColorDialog::open(GenomeTabEditData const& editData) } ChangeColorDialog::ChangeColorDialog() - : AlienDialog("Change color") + : AlienDialog(_("Change color")) {} void ChangeColorDialog::processIntern() { - AlienGui::Group(AlienGui::GroupParameters().text("Filter")); + AlienGui::Group(AlienGui::GroupParameters().text(_("Filter"))); ImGui::Checkbox("##restrictToSelectedGene", &_restrictToSelectedGene); ImGui::SameLine(0, ImGui::GetStyle().FramePadding.x * 4); - AlienGui::Text("Restrict to selected gene"); + AlienGui::Text(_("Restrict to selected gene")); - AlienGui::Group(AlienGui::GroupParameters().text("Color transition rule")); + AlienGui::Group(AlienGui::GroupParameters().text(_("Color transition rule"))); if (ImGui::BeginTable("##", 3, ImGuiTableFlags_SizingStretchProp)) { ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthStretch, 0); ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthFixed, scale(20)); @@ -63,13 +63,13 @@ void ChangeColorDialog::processIntern() ImGui::Dummy({0, ImGui::GetContentRegionAvail().y - scale(50.0f)}); AlienGui::Separator(); - if (AlienGui::Button("OK")) { + if (AlienGui::Button(_("OK"))) { onChangeColor(); close(); } ImGui::SetItemDefaultFocus(); ImGui::SameLine(); - if (AlienGui::Button("Cancel")) { + if (AlienGui::Button(_("Cancel"))) { close(); } } diff --git a/source/Gui/CreateUserDialog.cpp b/source/Gui/CreateUserDialog.cpp index c33fa9587..ed9093bb7 100644 --- a/source/Gui/CreateUserDialog.cpp +++ b/source/Gui/CreateUserDialog.cpp @@ -11,7 +11,7 @@ #include "GenericMessageDialog.h" CreateUserDialog::CreateUserDialog() - : AlienDialog("Create user") + : AlienDialog(_("Create user")) {} void CreateUserDialog::open(std::string const& userName, std::string const& password, UserInfo const& userInfo) @@ -25,22 +25,22 @@ void CreateUserDialog::open(std::string const& userName, std::string const& pass void CreateUserDialog::processIntern() { - AlienGui::Text("Security information"); - AlienGui::HelpMarker("The data transfer to the server is encrypted via https. On the server side, the email address is not stored in cleartext, but " - "as a SHA-256 hash value in the database."); - AlienGui::Text("Data privacy policy"); - AlienGui::HelpMarker("The entered e-mail address will not be passed on to third parties and is used only for the following two reasons: 1) To send " - "the confirmation code. " - "2) A SHA-256 hash value of the email address is stored on the server to verify that it is not yet in use."); + AlienGui::Text(_("Security information")); + AlienGui::HelpMarker(_("The data transfer to the server is encrypted via https. On the server side, the email address is not stored in cleartext, but " + "as a SHA-256 hash value in the database.")); + AlienGui::Text(_("Data privacy policy")); + AlienGui::HelpMarker(_("The entered e-mail address will not be passed on to third parties and is used only for the following two reasons: 1) To send " + "the confirmation code. " + "2) A SHA-256 hash value of the email address is stored on the server to verify that it is not yet in use.")); AlienGui::Separator(); - AlienGui::Text("Please enter your email address to receive the\nconfirmation code for the new user."); + AlienGui::Text(_("Please enter your email address to receive the\nconfirmation code for the new user.")); AlienGui::Separator(); - AlienGui::InputText(AlienGui::InputTextParameters().hint("Email").textWidth(0), _email); + AlienGui::InputText(AlienGui::InputTextParameters().hint(_("Email")).textWidth(0), _email); AlienGui::Separator(); ImGui::BeginDisabled(_email.empty()); - if (AlienGui::Button("Create user")) { + if (AlienGui::Button(_("Create user"))) { close(); onCreateUser(); @@ -49,7 +49,7 @@ void CreateUserDialog::processIntern() ImGui::SetItemDefaultFocus(); ImGui::SameLine(); - if (AlienGui::Button("Cancel")) { + if (AlienGui::Button(_("Cancel"))) { close(); } } @@ -60,7 +60,7 @@ void CreateUserDialog::onCreateUser() ActivateUserDialog::get().open(_userName, _password, _userInfo); } else { GenericMessageDialog::get().information( - "Error", + _("Error"), "An error occurred on the server. This could be related to the fact that\n" ICON_FA_CARET_RIGHT " your user name or email address is already in use,\n" ICON_FA_CARET_RIGHT " or your user " "name contains white spaces."); diff --git a/source/Gui/CreatorWindow.cpp b/source/Gui/CreatorWindow.cpp index 5e258c327..2a4b14a54 100644 --- a/source/Gui/CreatorWindow.cpp +++ b/source/Gui/CreatorWindow.cpp @@ -28,11 +28,11 @@ namespace { auto const ModeText = std::unordered_map{ - {CreationMode_CreateObject, "Create a single object"}, - {CreationMode_CreateRectangle, "Create a rectangular object network"}, - {CreationMode_CreateHexagon, "Create a hexagonal object network"}, - {CreationMode_CreateDisc, "Create a disc-shaped object network"}, - {CreationMode_Drawing, "Draw freehand"}, + {CreationMode_CreateObject, _("Create a single object")}, + {CreationMode_CreateRectangle, _("Create a rectangular object network")}, + {CreationMode_CreateHexagon, _("Create a hexagonal object network")}, + {CreationMode_CreateDisc, _("Create a disc-shaped object network")}, + {CreationMode_Drawing, _("Draw freehand")}, }; auto const RightColumnWidth = 160.0f; @@ -101,7 +101,7 @@ void CreatorWindow::processIntern() AlienGui::ComboColor( AlienGui::ComboColorParameters() .customizationColors(_SimulationFacade::get()->getSimulationParameters().customizationColors.value) - .name("Color") + .name(_("Color")) .textWidth(RightColumnWidth) .tooltip(Const::GenomeColorTooltip), color); @@ -110,7 +110,7 @@ void CreatorWindow::processIntern() auto pencilWidth = EditorModel::get().getPencilWidth(); AlienGui::SliderFloat( AlienGui::SliderFloatParameters() - .name("Pencil radius") + .name(_("Pencil radius")) .min(1.0f) .max(8.0f) .textWidth(RightColumnWidth) @@ -121,45 +121,45 @@ void CreatorWindow::processIntern() } AlienGui::Switcher( AlienGui::SwitcherParameters() - .name("Material") + .name(_("Material")) .textWidth(RightColumnWidth) - .values({"Solid", "Fluid", "Free cells", "Energy particles"}) + .values({_("Solid"), _("Fluid"), _("Free cells"), _("Energy particles")}) .tooltip(Const::CreatorDrawingTypeTooltip), &_material); AlienGui::InputFloat( - AlienGui::InputFloatParameters().name("Energy").format("%.2f").textWidth(RightColumnWidth).tooltip(Const::CellEnergyTooltip), _energy); + AlienGui::InputFloatParameters().name(_("Energy")).format("%.2f").textWidth(RightColumnWidth).tooltip(Const::CellEnergyTooltip), _energy); if (_material == CreationMaterial_Fluid) { - AlienGui::SliderFloat(AlienGui::SliderFloatParameters().name("Glow").min(0).max(1.0f).format("%.2f").textWidth(RightColumnWidth), &_glow); + AlienGui::SliderFloat(AlienGui::SliderFloatParameters().name(_("Glow")).min(0).max(1.0f).format("%.2f").textWidth(RightColumnWidth), &_glow); } if (!isEnergyMaterial() && _material != CreationMaterial_Fluid) { AlienGui::SliderFloat( - AlienGui::SliderFloatParameters().name("Stiffness").max(1.0f).min(0.0f).textWidth(RightColumnWidth).tooltip(Const::CellStiffnessTooltip), + AlienGui::SliderFloatParameters().name(_("Stiffness")).max(1.0f).min(0.0f).textWidth(RightColumnWidth).tooltip(Const::CellStiffnessTooltip), &_stiffness); } if (_mode == CreationMode_CreateRectangle) { AlienGui::InputInt( - AlienGui::InputIntParameters().name("Horizontal objects").textWidth(RightColumnWidth).tooltip(Const::CreatorRectangleWidthTooltip), + AlienGui::InputIntParameters().name(_("Horizontal objects")).textWidth(RightColumnWidth).tooltip(Const::CreatorRectangleWidthTooltip), _rectHorizontalObjects); AlienGui::InputInt( - AlienGui::InputIntParameters().name("Vertical objects").textWidth(RightColumnWidth).tooltip(Const::CreatorRectangleHeightTooltip), + AlienGui::InputIntParameters().name(_("Vertical objects")).textWidth(RightColumnWidth).tooltip(Const::CreatorRectangleHeightTooltip), _rectVerticalObjects); } if (_mode == CreationMode_CreateHexagon) { - AlienGui::InputInt(AlienGui::InputIntParameters().name("Layers").textWidth(RightColumnWidth).tooltip(Const::CreatorHexagonLayersTooltip), _layers); + AlienGui::InputInt(AlienGui::InputIntParameters().name(_("Layers")).textWidth(RightColumnWidth).tooltip(Const::CreatorHexagonLayersTooltip), _layers); } if (_mode == CreationMode_CreateDisc) { AlienGui::InputFloat( - AlienGui::InputFloatParameters().name("Outer radius").textWidth(RightColumnWidth).format("%.0f").tooltip(Const::CreatorDiscOuterRadiusTooltip), + AlienGui::InputFloatParameters().name(_("Outer radius")).textWidth(RightColumnWidth).format("%.0f").tooltip(Const::CreatorDiscOuterRadiusTooltip), _outerRadius); AlienGui::InputFloat( - AlienGui::InputFloatParameters().name("Inner radius").textWidth(RightColumnWidth).format("%.0f").tooltip(Const::CreatorDiscInnerRadiusTooltip), + AlienGui::InputFloatParameters().name(_("Inner radius")).textWidth(RightColumnWidth).format("%.0f").tooltip(Const::CreatorDiscInnerRadiusTooltip), _innerRadius); } if (_mode == CreationMode_CreateRectangle || _mode == CreationMode_CreateHexagon || _mode == CreationMode_CreateDisc) { AlienGui::InputFloat( AlienGui::InputFloatParameters() - .name("Object distance") + .name(_("Object distance")) .format("%.2f") .step(0.1) .textWidth(RightColumnWidth) @@ -167,10 +167,10 @@ void CreatorWindow::processIntern() _objectDistance); } if (_mode != CreationMode_CreateObject) { - AlienGui::Checkbox(AlienGui::CheckboxParameters().name("Sticky").textWidth(RightColumnWidth).tooltip(Const::CreatorStickyTooltip), _makeSticky); + AlienGui::Checkbox(AlienGui::CheckboxParameters().name(_("Sticky")).textWidth(RightColumnWidth).tooltip(Const::CreatorStickyTooltip), _makeSticky); } if (!isEnergyMaterial()) { - AlienGui::Checkbox(AlienGui::CheckboxParameters().name("Static").textWidth(RightColumnWidth).tooltip(Const::CellStaticTooltip), _static); + AlienGui::Checkbox(AlienGui::CheckboxParameters().name(_("Static")).textWidth(RightColumnWidth).tooltip(Const::CellStaticTooltip), _static); } } ImGui::EndChild(); @@ -181,7 +181,7 @@ void CreatorWindow::processIntern() } else { AlienGui::Separator(); simInteractionController.setDrawMode(false); - if (AlienGui::Button("Build")) { + if (AlienGui::Button(_("Build"))) { if (_mode == CreationMode_CreateObject) { createEntity(); } @@ -277,7 +277,7 @@ void CreatorWindow::finishDrawing() } CreatorWindow::CreatorWindow() - : AlienWindow("Creator", "editors.creator", false) + : AlienWindow(_("Creator"), "editors.creator", false) {} void CreatorWindow::createEntity() diff --git a/source/Gui/DeleteUserDialog.cpp b/source/Gui/DeleteUserDialog.cpp index f906780c6..b200c525b 100644 --- a/source/Gui/DeleteUserDialog.cpp +++ b/source/Gui/DeleteUserDialog.cpp @@ -10,7 +10,7 @@ #include "GenericMessageDialog.h" DeleteUserDialog::DeleteUserDialog() - : AlienDialog("Delete user") + : AlienDialog(_("Delete user")) {} void DeleteUserDialog::processIntern() @@ -20,16 +20,16 @@ void DeleteUserDialog::processIntern() + "' will be deleted on the server side.\nThese include the likes, the simulations and the account data."); AlienGui::Separator(); - AlienGui::InputText(AlienGui::InputTextParameters().hint("Re-enter password").password(true).textWidth(0), _reenteredPassword); + AlienGui::InputText(AlienGui::InputTextParameters().hint(_("Re-enter password")).password(true).textWidth(0), _reenteredPassword); AlienGui::Separator(); ImGui::BeginDisabled(_reenteredPassword.empty()); - if (AlienGui::Button("Delete")) { + if (AlienGui::Button(_("Delete"))) { close(); if (_reenteredPassword == *NetworkService::get().getPassword()) { onDelete(); } else { - GenericMessageDialog::get().information("Error", "The password does not match."); + GenericMessageDialog::get().information(_("Error"), _("The password does not match.")); } _reenteredPassword.clear(); } @@ -37,7 +37,7 @@ void DeleteUserDialog::processIntern() ImGui::SetItemDefaultFocus(); ImGui::SameLine(); - if (AlienGui::Button("Cancel")) { + if (AlienGui::Button(_("Cancel"))) { close(); _reenteredPassword.clear(); } @@ -48,8 +48,8 @@ void DeleteUserDialog::onDelete() auto userName = *NetworkService::get().getLoggedInUserName(); if (NetworkService::get().deleteUser()) { BrowserWindow::get().onRefresh(); - GenericMessageDialog::get().information("Information", "The user '" + userName + "' has been deleted.\nYou are logged out."); + GenericMessageDialog::get().information(_("Information"), "The user '" + userName + "' has been deleted.\nYou are logged out."); } else { - GenericMessageDialog::get().information("Error", "An error occurred on the server."); + GenericMessageDialog::get().information(_("Error"), _("An error occurred on the server.")); } } diff --git a/source/Gui/DisplaySettingsDialog.cpp b/source/Gui/DisplaySettingsDialog.cpp index b157eb8d0..3bdb57c26 100644 --- a/source/Gui/DisplaySettingsDialog.cpp +++ b/source/Gui/DisplaySettingsDialog.cpp @@ -4,10 +4,12 @@ #include +#include #include #include "AlienGui.h" #include "StyleRepository.h" +#include "TranslationService.h" #include "WindowController.h" #include @@ -15,6 +17,8 @@ namespace { auto const RightColumnWidth = 185.0f; + std::vector const LanguageNames = {"English", "中文"}; + std::vector const LanguageCodes = {"en", "zh"}; } void DisplaySettingsDialog::initIntern() @@ -25,39 +29,46 @@ void DisplaySettingsDialog::initIntern() } DisplaySettingsDialog::DisplaySettingsDialog() - : AlienDialog("Display settings") + : AlienDialog(_("Display settings")) {} void DisplaySettingsDialog::processIntern() { auto isFullscreen = _pendingIsFullscreen; - if (AlienGui::ToggleButton(AlienGui::ToggleButtonParameters().name("Full screen"), isFullscreen)) { + if (AlienGui::ToggleButton(AlienGui::ToggleButtonParameters().name(_("Full screen")), isFullscreen)) { _pendingIsFullscreen = isFullscreen; } ImGui::BeginDisabled(!_pendingIsFullscreen); AlienGui::Combo( - AlienGui::ComboParameters().name("Resolution").textWidth(RightColumnWidth).defaultValue(_origSelectionIndex).values(_videoModeStrings), + AlienGui::ComboParameters().name(_("Resolution")).textWidth(RightColumnWidth).defaultValue(_origSelectionIndex).values(_videoModeStrings), _pendingSelectionIndex); ImGui::EndDisabled(); + if (AlienGui::Combo( + AlienGui::ComboParameters().name(_("Language")).textWidth(RightColumnWidth).values(LanguageNames), + _languageIndex)) { + GlobalSettings::get().setValue("settings.language", LanguageCodes[_languageIndex]); + TranslationService::get().load(LanguageCodes[_languageIndex]); + } + AlienGui::SliderInt( AlienGui::SliderIntParameters() - .name("Frames per second") + .name(_("Frames per second")) .textWidth(RightColumnWidth) .defaultValue(&_origFps) .min(20) .max(100) - .tooltip("A high frame rate leads to a greater GPU workload for rendering and thus lowers the simulation speed (time steps per second)."), + .tooltip(_("A high frame rate leads to a greater GPU workload for rendering and thus lowers the simulation speed (time steps per second).")), &_pendingFps); ImGui::Dummy({0, ImGui::GetContentRegionAvail().y - scale(50.0f)}); AlienGui::Separator(); - if (AlienGui::Button("Adopt")) { + if (AlienGui::Button(_("Adopt"))) { close(); if (_pendingIsFullscreen) { setFullscreen(_pendingSelectionIndex); @@ -66,12 +77,15 @@ void DisplaySettingsDialog::processIntern() } WindowController::get().setFps(_pendingFps); _selectionIndex = _pendingSelectionIndex; + GlobalSettings::get().setValue("settings.language", LanguageCodes[_languageIndex]); } ImGui::SetItemDefaultFocus(); ImGui::SameLine(); - if (AlienGui::Button("Cancel")) { + ImGui::SameLine(); + if (AlienGui::Button(_("Cancel"))) { close(); + TranslationService::get().load(LanguageCodes[_origLanguageIndex]); } } @@ -83,6 +97,16 @@ void DisplaySettingsDialog::openIntern() _pendingIsFullscreen = !WindowController::get().isWindowedMode(); _pendingSelectionIndex = _selectionIndex; _pendingFps = _origFps; + + auto language = GlobalSettings::get().getValue("settings.language", std::string("en")); + _languageIndex = 0; + for (size_t i = 0; i < LanguageCodes.size(); ++i) { + if (LanguageCodes[i] == language) { + _languageIndex = static_cast(i); + break; + } + } + _origLanguageIndex = _languageIndex; } void DisplaySettingsDialog::setFullscreen(int selectionIndex) @@ -130,7 +154,7 @@ namespace std::vector DisplaySettingsDialog::createVideoModeStrings() const { std::vector result; - result.emplace_back("Desktop"); + result.emplace_back(_("Desktop")); for (int i = 0; i < _videoModesCount; ++i) { result.emplace_back(createVideoModeString(_videoModes[i])); } diff --git a/source/Gui/DisplaySettingsDialog.h b/source/Gui/DisplaySettingsDialog.h index 7718d3110..dffc1d1b9 100644 --- a/source/Gui/DisplaySettingsDialog.h +++ b/source/Gui/DisplaySettingsDialog.h @@ -25,6 +25,8 @@ class DisplaySettingsDialog : public AlienDialog int _origSelectionIndex = 0; int _selectionIndex = 0; int _origFps = 33; + int _languageIndex = 0; + int _origLanguageIndex = 0; bool _pendingIsFullscreen = false; int _pendingSelectionIndex = 0; diff --git a/source/Gui/EditSimulationDialog.cpp b/source/Gui/EditSimulationDialog.cpp index e2e66bd36..c7f4498a5 100644 --- a/source/Gui/EditSimulationDialog.cpp +++ b/source/Gui/EditSimulationDialog.cpp @@ -17,7 +17,7 @@ void EditSimulationDialog::openForLeaf(NetworkResourceTreeTO const& treeTO) { - changeTitle("Change name or description"); + changeTitle(_("Change name or description")); AlienDialog::open(); _treeTO = treeTO; @@ -28,7 +28,7 @@ void EditSimulationDialog::openForLeaf(NetworkResourceTreeTO const& treeTO) void EditSimulationDialog::openForFolder(NetworkResourceTreeTO const& treeTO, std::vector const& rawTOs) { - changeTitle("Change folder name"); + changeTitle(_("Change folder name")); AlienDialog::open(); _treeTO = treeTO; _rawTOs = rawTOs; @@ -55,20 +55,20 @@ void EditSimulationDialog::processForLeaf() auto& rawTO = _treeTO->getLeaf().rawTO; std::string resourceTypeString = rawTO->resourceType == NetworkResourceType_Simulation ? "simulation" : "genome"; - AlienGui::InputText(AlienGui::InputTextParameters().textWidth(0).hint("Name"), _newName); + AlienGui::InputText(AlienGui::InputTextParameters().textWidth(0).hint(_("Name")), _newName); AlienGui::Separator(); ImGui::PushID("description"); AlienGui::InputTextMultiline( - AlienGui::InputTextMultilineParameters().hint("Desc (optional)").textWidth(0).height(ImGui::GetContentRegionAvail().y - scale(50.0f)), + AlienGui::InputTextMultilineParameters().hint(_("Desc (optional)")).textWidth(0).height(ImGui::GetContentRegionAvail().y - scale(50.0f)), _newDescription); ImGui::PopID(); AlienGui::Separator(); ImGui::BeginDisabled(_newName.empty()); - if (AlienGui::Button("OK")) { + if (AlienGui::Button(_("OK"))) { if (NetworkValidationService::get().isStringValidForDatabase(_newName) && NetworkValidationService::get().isStringValidForDatabase(_newDescription)) { EditNetworkResourceRequestData::Entry entry{.resourceId = rawTO->id, .newName = _newName, .newDescription = _newDescription}; NetworkTransferController::get().onEdit(EditNetworkResourceRequestData{.entries = std::vector{entry}}); @@ -81,7 +81,7 @@ void EditSimulationDialog::processForLeaf() ImGui::SetItemDefaultFocus(); ImGui::SameLine(); - if (AlienGui::Button("Cancel")) { + if (AlienGui::Button(_("Cancel"))) { close(); } } @@ -89,14 +89,14 @@ void EditSimulationDialog::processForLeaf() void EditSimulationDialog::processForFolder() { if (ImGui::BeginChild("##Folder", {0, -scale(50.0f)})) { - AlienGui::InputText(AlienGui::InputTextParameters().textWidth(0).hint("Folder name"), _newName); + AlienGui::InputText(AlienGui::InputTextParameters().textWidth(0).hint(_("Folder name")), _newName); } ImGui::EndChild(); AlienGui::Separator(); ImGui::BeginDisabled(_newName.empty()); - if (AlienGui::Button("OK")) { + if (AlienGui::Button(_("OK"))) { if (NetworkValidationService::get().isStringValidForDatabase(_newName)) { EditNetworkResourceRequestData requestData; @@ -108,14 +108,14 @@ void EditSimulationDialog::processForFolder() NetworkTransferController::get().onEdit(requestData); close(); } else { - showMessage("Error", Const::NotAllowedCharacters); + showMessage(_("Error"), Const::NotAllowedCharacters); } } ImGui::EndDisabled(); ImGui::SetItemDefaultFocus(); ImGui::SameLine(); - if (AlienGui::Button("Cancel")) { + if (AlienGui::Button(_("Cancel"))) { close(); } } diff --git a/source/Gui/EditorController.cpp b/source/Gui/EditorController.cpp index 7e6946af0..4e9d8532b 100644 --- a/source/Gui/EditorController.cpp +++ b/source/Gui/EditorController.cpp @@ -256,7 +256,7 @@ bool EditorController::isCopyingPossible() const void EditorController::onCopy() { PatternEditorWindow::get().onCopy(); - printOverlayMessage("Selection copied"); + printOverlayMessage(_("Selection copied")); } bool EditorController::isPastingPossible() const @@ -267,7 +267,7 @@ bool EditorController::isPastingPossible() const void EditorController::onPaste() { PatternEditorWindow::get().onPaste(); - printOverlayMessage("Selection pasted"); + printOverlayMessage(_("Selection pasted")); } bool EditorController::isDeletingPossible() const @@ -278,7 +278,7 @@ bool EditorController::isDeletingPossible() const void EditorController::onDelete() { PatternEditorWindow::get().onDelete(); - printOverlayMessage("Selection deleted"); + printOverlayMessage(_("Selection deleted")); } void EditorController::processInspectorWindows() diff --git a/source/Gui/ExitDialog.cpp b/source/Gui/ExitDialog.cpp index 777d5dc3a..fddc9b438 100644 --- a/source/Gui/ExitDialog.cpp +++ b/source/Gui/ExitDialog.cpp @@ -6,22 +6,22 @@ #include "MainLoopController.h" ExitDialog::ExitDialog() - : AlienDialog("Exit") + : AlienDialog(_("Exit")) {} void ExitDialog::processIntern() { - ImGui::TextWrapped("%s", "Do you really want to terminate the program?"); + ImGui::TextWrapped("%s", _("Do you really want to terminate the program?")); ImGui::Dummy({0, ImGui::GetContentRegionAvail().y - scale(50.0f)}); AlienGui::Separator(); - if (AlienGui::Button("OK")) { + if (AlienGui::Button(_("OK"))) { MainLoopController::get().scheduleClosing(); close(); } ImGui::SameLine(); - if (AlienGui::Button("Cancel")) { + if (AlienGui::Button(_("Cancel"))) { close(); } ImGui::SetItemDefaultFocus(); diff --git a/source/Gui/FileTransferController.cpp b/source/Gui/FileTransferController.cpp index 28fb67bc1..aabeff316 100644 --- a/source/Gui/FileTransferController.cpp +++ b/source/Gui/FileTransferController.cpp @@ -28,7 +28,7 @@ void FileTransferController::onOpenSimulationDialog() void FileTransferController::onOpenSimulation(std::filesystem::path const& filename) { - printOverlayMessage("Loading ..."); + printOverlayMessage(_("Loading ...")); _openSimulationProcessor->executeTask( [&](auto const& senderId) { @@ -54,7 +54,7 @@ void FileTransferController::onOpenSimulation(std::filesystem::path const& filen } catch (AlienException const& exception) { errorMessage = exception.what(); } catch (...) { - errorMessage = "Failed to load simulation."; + errorMessage = _("Failed to load simulation."); } if (errorMessage) { @@ -81,7 +81,7 @@ void FileTransferController::onSaveSimulationDialog() auto firstFilename = ifd::FileDialog::Instance().GetResult(); auto firstFilenameCopy = firstFilename; _referencePath = firstFilenameCopy.remove_filename().string(); - printOverlayMessage("Saving ..."); + printOverlayMessage(_("Saving ...")); _saveSimulationProcessor->executeTask( [&, firstFilename = firstFilename](auto const& senderId) { auto senderInfo = SenderInfo{.senderId = senderId, .wishResultData = false, .wishErrorInfo = true}; diff --git a/source/Gui/GenericMessageDialog.cpp b/source/Gui/GenericMessageDialog.cpp index a78a3e46f..611d9f561 100644 --- a/source/Gui/GenericMessageDialog.cpp +++ b/source/Gui/GenericMessageDialog.cpp @@ -56,7 +56,7 @@ void GenericMessageDialog::yesNo(std::string const& title, std::string const& me } GenericMessageDialog::GenericMessageDialog() - : AlienDialog("Message") + : AlienDialog(_("Message")) {} void GenericMessageDialog::processInformation() @@ -71,7 +71,7 @@ void GenericMessageDialog::processInformation() processMessageText(); AlienGui::Separator(); - if (AlienGui::Button("OK")) { + if (AlienGui::Button(_("OK"))) { close(); } } @@ -88,12 +88,12 @@ void GenericMessageDialog::processYesNo() processMessageText(); AlienGui::Separator(); - if (AlienGui::Button("Yes")) { + if (AlienGui::Button(_("Yes"))) { close(); _execFunction(); } ImGui::SameLine(); - if (AlienGui::Button("No")) { + if (AlienGui::Button(_("No"))) { close(); } } diff --git a/source/Gui/GenomeEditorWindow.cpp b/source/Gui/GenomeEditorWindow.cpp index 90df13423..575e2b3b8 100644 --- a/source/Gui/GenomeEditorWindow.cpp +++ b/source/Gui/GenomeEditorWindow.cpp @@ -61,7 +61,7 @@ GenomeDesc GenomeEditorWindow::getCurrentGenome() const } GenomeEditorWindow::GenomeEditorWindow() - : AlienWindow("Genome editor", "windows.genome editor", false, true, {500.0f, 300.0f}) + : AlienWindow(_("Genome editor"), "windows.genome editor", false, true, {500.0f, 300.0f}) {} void GenomeEditorWindow::initIntern() diff --git a/source/Gui/GettingStartedWindow.cpp b/source/Gui/GettingStartedWindow.cpp index e9733eca0..682d5bb51 100644 --- a/source/Gui/GettingStartedWindow.cpp +++ b/source/Gui/GettingStartedWindow.cpp @@ -18,7 +18,7 @@ void GettingStartedWindow::initIntern() GettingStartedWindow::GettingStartedWindow() - : AlienWindow("Getting started", "windows.getting started", true) + : AlienWindow(_("Getting started"), "windows.getting started", true) {} void GettingStartedWindow::shutdownIntern() @@ -38,7 +38,7 @@ void GettingStartedWindow::processIntern() */ drawHeading1("Introduction"); - ImGui::Text("ALIEN is an artificial life and physics simulation tool based on a CUDA-powered 2D particle engine for soft bodies and fluids."); + ImGui::Text("%s", _("ALIEN is an artificial life and physics simulation tool based on a CUDA-powered 2D particle engine for soft bodies and fluids.")); ImGui::Text( "Each particle can be equipped with higher-level functions including sensors, muscles, neurons, constructors, etc. that allow to " "mimic certain functionalities of biological cells or of robotic components. Multi-cellular organisms are simulated as networks of " @@ -150,7 +150,7 @@ void GettingStartedWindow::processIntern() ImGui::Spacing(); drawHeading2("World"); - ImGui::Text("An ALIEN world is two-dimensional rectangular domain with periodic boundary conditions. The space is modeled as a continuum."); + ImGui::Text("%s", _("An ALIEN world is two-dimensional rectangular domain with periodic boundary conditions. The space is modeled as a continuum.")); ImGui::Spacing(); drawHeading2("Cell"); @@ -408,7 +408,7 @@ void GettingStartedWindow::processIntern() ImGui::EndChild(); AlienGui::Separator(); - AlienGui::ToggleButton(AlienGui::ToggleButtonParameters().name("Show after startup"), _showAfterStartup); + AlienGui::ToggleButton(AlienGui::ToggleButtonParameters().name(_("Show after startup")), _showAfterStartup); } void GettingStartedWindow::drawTitle() @@ -416,46 +416,46 @@ void GettingStartedWindow::drawTitle() ImGui::PushStyleColor(ImGuiCol_Text, (ImU32)Const::HeadlineColor); ImGui::PushFont(StyleRepository::get().getMediumFont()); - ImGui::Text("What is "); + ImGui::Text("%s", _("What is ")); ImGui::PopFont(); ImGui::SameLine(); AlienGui::MoveTickLeft(); ImGui::PushFont(StyleRepository::get().getMediumBoldFont()); - ImGui::Text("A"); + ImGui::Text("%s", _("A")); ImGui::PopFont(); ImGui::SameLine(); AlienGui::MoveTickLeft(); AlienGui::MoveTickLeft(); ImGui::PushFont(StyleRepository::get().getMediumFont()); - ImGui::Text("rtificial "); + ImGui::Text("%s", _("rtificial ")); ImGui::PopFont(); ImGui::SameLine(); AlienGui::MoveTickLeft(); ImGui::PushFont(StyleRepository::get().getMediumBoldFont()); - ImGui::Text("LI"); + ImGui::Text("%s", _("LI")); ImGui::PopFont(); ImGui::SameLine(); AlienGui::MoveTickLeft(); AlienGui::MoveTickLeft(); ImGui::PushFont(StyleRepository::get().getMediumFont()); - ImGui::Text("fe "); + ImGui::Text("%s", _("fe ")); ImGui::PopFont(); ImGui::SameLine(); AlienGui::MoveTickLeft(); ImGui::PushFont(StyleRepository::get().getMediumBoldFont()); - ImGui::Text("EN"); + ImGui::Text("%s", _("EN")); ImGui::PopFont(); ImGui::SameLine(); AlienGui::MoveTickLeft(); AlienGui::MoveTickLeft(); ImGui::PushFont(StyleRepository::get().getMediumFont()); - ImGui::Text("vironment ?"); + ImGui::Text("%s", _("vironment ?")); ImGui::PopFont(); ImGui::PopStyleColor(); diff --git a/source/Gui/GpuSettingsDialog.cpp b/source/Gui/GpuSettingsDialog.cpp index b41d611f3..972f60fbb 100644 --- a/source/Gui/GpuSettingsDialog.cpp +++ b/source/Gui/GpuSettingsDialog.cpp @@ -32,7 +32,7 @@ void GpuSettingsDialog::shutdownIntern() } GpuSettingsDialog::GpuSettingsDialog() - : AlienDialog("CUDA settings") + : AlienDialog(_("CUDA settings")) {} void GpuSettingsDialog::processIntern() @@ -41,11 +41,11 @@ void GpuSettingsDialog::processIntern() AlienGui::InputInt( AlienGui::InputIntParameters() - .name("Blocks") + .name(_("Blocks")) .textWidth(RightColumnWidth) .defaultValue(origGpuSettings.numBlocks) - .tooltip("This values specifies the number of CUDA thread blocks. If you are using a high-end graphics card, you can try to increase the number of " - "blocks."), + .tooltip(_("This values specifies the number of CUDA thread blocks. If you are using a high-end graphics card, you can try to increase the number of " + "blocks.")), _pendingGpuSettings.numBlocks); validateAndCorrect(_pendingGpuSettings); @@ -53,14 +53,14 @@ void GpuSettingsDialog::processIntern() ImGui::Dummy({0, ImGui::GetContentRegionAvail().y - scale(50.0f)}); AlienGui::Separator(); - if (AlienGui::Button("Adopt")) { + if (AlienGui::Button(_("Adopt"))) { close(); _SimulationFacade::get()->setGpuSettings_async(_pendingGpuSettings); } ImGui::SetItemDefaultFocus(); ImGui::SameLine(); - if (AlienGui::Button("Cancel")) { + if (AlienGui::Button(_("Cancel"))) { close(); } } diff --git a/source/Gui/InspectionWindow.cpp b/source/Gui/InspectionWindow.cpp index 6e9466ed6..9d6836e68 100644 --- a/source/Gui/InspectionWindow.cpp +++ b/source/Gui/InspectionWindow.cpp @@ -386,16 +386,16 @@ void _InspectionWindow::processParticle(EnergyDesc particle) auto origParticle = particle; AlienGui::DynamicTableLayout table(TableColumnWidth); if (table.begin()) { - if (AlienGui::BeginTreeNode(AlienGui::TreeNodeParameters().name("Energy particle").rank(AlienGui::TreeNodeRank::High))) { + if (AlienGui::BeginTreeNode(AlienGui::TreeNodeParameters().name(_("Energy particle")).rank(AlienGui::TreeNodeRank::High))) { processPropertiesSubNode("Energy particle", [&] { inspectorHexId("Particle id", particle._id); - AlienGui::InputFloat2(AlienGui::InputFloat2Parameters().name("Position").format("%.3f").textWidth(TextWidth), particle._pos.x, particle._pos.y); - AlienGui::InputFloat2(AlienGui::InputFloat2Parameters().name("Velocity").format("%.3f").textWidth(TextWidth), particle._vel.x, particle._vel.y); - AlienGui::InputFloat(AlienGui::InputFloatParameters().name("Energy").format("%.2f").textWidth(TextWidth), particle._energy); + AlienGui::InputFloat2(AlienGui::InputFloat2Parameters().name(_("Position")).format("%.3f").textWidth(TextWidth), particle._pos.x, particle._pos.y); + AlienGui::InputFloat2(AlienGui::InputFloat2Parameters().name(_("Velocity")).format("%.3f").textWidth(TextWidth), particle._vel.x, particle._vel.y); + AlienGui::InputFloat(AlienGui::InputFloatParameters().name(_("Energy")).format("%.2f").textWidth(TextWidth), particle._energy); AlienGui::ComboColor( AlienGui::ComboColorParameters() .customizationColors(_SimulationFacade::get()->getSimulationParameters().customizationColors.value) - .name("Color") + .name(_("Color")) .textWidth(TextWidth), particle._color); }); @@ -411,31 +411,31 @@ void _InspectionWindow::processParticle(EnergyDesc particle) void _InspectionWindow::processObjectNode(ObjectDesc& object) { - if (AlienGui::BeginTreeNode(AlienGui::TreeNodeParameters().name("Object").rank(AlienGui::TreeNodeRank::High))) { + if (AlienGui::BeginTreeNode(AlienGui::TreeNodeParameters().name(_("Object")).rank(AlienGui::TreeNodeRank::High))) { processPropertiesSubNode("Object", [&] { inspectorHexId("Object id", object._id); - AlienGui::InputFloat2(AlienGui::InputFloat2Parameters().name("Position").format("%.2f").textWidth(TextWidth), object._pos.x, object._pos.y); - AlienGui::InputFloat2(AlienGui::InputFloat2Parameters().name("Velocity").format("%.2f").textWidth(TextWidth), object._vel.x, object._vel.y); - AlienGui::InputFloat(AlienGui::InputFloatParameters().name("Stiffness").format("%.2f").step(0.05f).textWidth(TextWidth), object._stiffness); + AlienGui::InputFloat2(AlienGui::InputFloat2Parameters().name(_("Position")).format("%.2f").textWidth(TextWidth), object._pos.x, object._pos.y); + AlienGui::InputFloat2(AlienGui::InputFloat2Parameters().name(_("Velocity")).format("%.2f").textWidth(TextWidth), object._vel.x, object._vel.y); + AlienGui::InputFloat(AlienGui::InputFloatParameters().name(_("Stiffness")).format("%.2f").step(0.05f).textWidth(TextWidth), object._stiffness); AlienGui::ComboColor( AlienGui::ComboColorParameters() .customizationColors(_SimulationFacade::get()->getSimulationParameters().customizationColors.value) - .name("Color") + .name(_("Color")) .textWidth(TextWidth), object._color); - AlienGui::Checkbox(AlienGui::CheckboxParameters().name("Static").textWidth(TextWidth), object._isStatic); - AlienGui::Checkbox(AlienGui::CheckboxParameters().name("Sticky").textWidth(TextWidth), object._sticky); + AlienGui::Checkbox(AlienGui::CheckboxParameters().name(_("Static")).textWidth(TextWidth), object._isStatic); + AlienGui::Checkbox(AlienGui::CheckboxParameters().name(_("Sticky")).textWidth(TextWidth), object._sticky); auto objectType = object.getObjectType(); AlienGui::ComboParameters typeParams; - typeParams.name("Object type").textWidth(TextWidth).values(Const::ObjectTypeStrings); + typeParams.name(_("Object type")).textWidth(TextWidth).values(Const::ObjectTypeStrings); if (AlienGui::Combo(typeParams, objectType)) { object._type = createObjectTypeDesc(objectType); } }); if (!object._connections.empty()) { - if (AlienGui::BeginTreeNode(AlienGui::TreeNodeParameters().name("Connections").rank(AlienGui::TreeNodeRank::Default))) { + if (AlienGui::BeginTreeNode(AlienGui::TreeNodeParameters().name(_("Connections")).rank(AlienGui::TreeNodeRank::Default))) { for (size_t i = 0; i < object._connections.size(); ++i) { auto& conn = object._connections.at(i); auto const connectionNumber = i + 1; @@ -443,9 +443,9 @@ void _InspectionWindow::processObjectNode(ObjectDesc& object) AlienGui::TreeNodeParameters().name("Connection #" + std::to_string(connectionNumber)).rank(AlienGui::TreeNodeRank::Low))) { inspectorHexId("Connected id", conn._objectId); AlienGui::InputFloat( - AlienGui::InputFloatParameters().name("Distance").format("%.2f").textWidth(TextWidth).readOnly(true), conn._distance); + AlienGui::InputFloatParameters().name(_("Distance")).format("%.2f").textWidth(TextWidth).readOnly(true), conn._distance); AlienGui::InputFloat( - AlienGui::InputFloatParameters().name("Ref angle").format("%.2f").textWidth(TextWidth).readOnly(true), conn._angleFromPrevious); + AlienGui::InputFloatParameters().name(_("Ref angle")).format("%.2f").textWidth(TextWidth).readOnly(true), conn._angleFromPrevious); } AlienGui::EndTreeNode(); } @@ -458,10 +458,10 @@ void _InspectionWindow::processObjectNode(ObjectDesc& object) void _InspectionWindow::processSolidNode(ObjectDesc& object) { - if (AlienGui::BeginTreeNode(AlienGui::TreeNodeParameters().name("Solid").rank(AlienGui::TreeNodeRank::High).defaultOpen(false))) { + if (AlienGui::BeginTreeNode(AlienGui::TreeNodeParameters().name(_("Solid")).rank(AlienGui::TreeNodeRank::High).defaultOpen(false))) { processPropertiesSubNode("Solid", [&] { auto& solid = object.getSolidRef(); - AlienGui::InputFloat(AlienGui::InputFloatParameters().name("Energy").format("%.2f").textWidth(TextWidth), solid._energy); + AlienGui::InputFloat(AlienGui::InputFloatParameters().name(_("Energy")).format("%.2f").textWidth(TextWidth), solid._energy); }); } AlienGui::EndTreeNode(); @@ -469,11 +469,11 @@ void _InspectionWindow::processSolidNode(ObjectDesc& object) void _InspectionWindow::processFluidNode(ObjectDesc& object) { - if (AlienGui::BeginTreeNode(AlienGui::TreeNodeParameters().name("Fluid").rank(AlienGui::TreeNodeRank::High).defaultOpen(false))) { + if (AlienGui::BeginTreeNode(AlienGui::TreeNodeParameters().name(_("Fluid")).rank(AlienGui::TreeNodeRank::High).defaultOpen(false))) { processPropertiesSubNode("Fluid", [&] { auto& fluid = object.getFluidRef(); - AlienGui::InputFloat(AlienGui::InputFloatParameters().name("Energy").format("%.2f").textWidth(TextWidth), fluid._energy); - AlienGui::SliderFloat(AlienGui::SliderFloatParameters().name("Glow").min(0.0f).max(1.0f).format("%.2f").textWidth(TextWidth), &fluid._glow); + AlienGui::InputFloat(AlienGui::InputFloatParameters().name(_("Energy")).format("%.2f").textWidth(TextWidth), fluid._energy); + AlienGui::SliderFloat(AlienGui::SliderFloatParameters().name(_("Glow")).min(0.0f).max(1.0f).format("%.2f").textWidth(TextWidth), &fluid._glow); }); } AlienGui::EndTreeNode(); @@ -481,11 +481,11 @@ void _InspectionWindow::processFluidNode(ObjectDesc& object) void _InspectionWindow::processFreeCellNode(ObjectDesc& object) { - if (AlienGui::BeginTreeNode(AlienGui::TreeNodeParameters().name("Free cell").rank(AlienGui::TreeNodeRank::High).defaultOpen(false))) { + if (AlienGui::BeginTreeNode(AlienGui::TreeNodeParameters().name(_("Free cell")).rank(AlienGui::TreeNodeRank::High).defaultOpen(false))) { processPropertiesSubNode("Free cell", [&] { auto& freeCell = object.getFreeCellRef(); - AlienGui::InputFloat(AlienGui::InputFloatParameters().name("Energy").format("%.2f").textWidth(TextWidth), freeCell._energy); - AlienGui::InputInt(AlienGui::InputIntParameters().name("Age").textWidth(TextWidth), freeCell._age); + AlienGui::InputFloat(AlienGui::InputFloatParameters().name(_("Energy")).format("%.2f").textWidth(TextWidth), freeCell._energy); + AlienGui::InputInt(AlienGui::InputIntParameters().name(_("Age")).textWidth(TextWidth), freeCell._age); }); } AlienGui::EndTreeNode(); @@ -493,28 +493,28 @@ void _InspectionWindow::processFreeCellNode(ObjectDesc& object) void _InspectionWindow::processCellNode(ObjectDesc& object) { - if (AlienGui::BeginTreeNode(AlienGui::TreeNodeParameters().name("Cell").rank(AlienGui::TreeNodeRank::High).defaultOpen(false))) { + if (AlienGui::BeginTreeNode(AlienGui::TreeNodeParameters().name(_("Cell")).rank(AlienGui::TreeNodeRank::High).defaultOpen(false))) { auto& cell = object.getCellRef(); processPropertiesSubNode("Cell", [&] { - AlienGui::InputFloat(AlienGui::InputFloatParameters().name("Usable energy").format("%.2f").textWidth(TextWidth), cell._usableEnergy); - AlienGui::InputFloat(AlienGui::InputFloatParameters().name("Raw energy").format("%.2f").textWidth(TextWidth), cell._rawEnergy); - AlienGui::InputOptionalFloat(AlienGui::InputFloatParameters().name("Front angle").format("%.2f").textWidth(TextWidth), cell._frontAngle); - AlienGui::InputInt(AlienGui::InputIntParameters().name("Age").textWidth(TextWidth), cell._age); + AlienGui::InputFloat(AlienGui::InputFloatParameters().name(_("Usable energy")).format("%.2f").textWidth(TextWidth), cell._usableEnergy); + AlienGui::InputFloat(AlienGui::InputFloatParameters().name(_("Raw energy")).format("%.2f").textWidth(TextWidth), cell._rawEnergy); + AlienGui::InputOptionalFloat(AlienGui::InputFloatParameters().name(_("Front angle")).format("%.2f").textWidth(TextWidth), cell._frontAngle); + AlienGui::InputInt(AlienGui::InputIntParameters().name(_("Age")).textWidth(TextWidth), cell._age); static std::vector const cellStateStrings = {"Ready", "Constructing", "Activating", "Dying", "Instant dying"}; AlienGui::ComboParameters stateParams; - stateParams.name("Cell state").textWidth(TextWidth).values(cellStateStrings); + stateParams.name(_("Cell state")).textWidth(TextWidth).values(cellStateStrings); AlienGui::Combo(stateParams, cell._cellState); - AlienGui::InputInt(AlienGui::InputIntParameters().name("Node index").textWidth(TextWidth), cell._nodeIndex); - AlienGui::InputInt(AlienGui::InputIntParameters().name("Parent node index").textWidth(TextWidth), cell._parentNodeIndex); - AlienGui::InputInt(AlienGui::InputIntParameters().name("Gene index").textWidth(TextWidth), cell._geneIndex); - AlienGui::InputInt(AlienGui::InputIntParameters().name("Concatenation index").textWidth(TextWidth), cell._concatenationIndex); - AlienGui::InputInt(AlienGui::InputIntParameters().name("Branch index").textWidth(TextWidth), cell._branchIndex); - AlienGui::InputInt(AlienGui::InputIntParameters().name("Activation time").textWidth(TextWidth), cell._activationTime); - AlienGui::Checkbox(AlienGui::CheckboxParameters().name("Head cell").textWidth(TextWidth), cell._headCell); + AlienGui::InputInt(AlienGui::InputIntParameters().name(_("Node index")).textWidth(TextWidth), cell._nodeIndex); + AlienGui::InputInt(AlienGui::InputIntParameters().name(_("Parent node index")).textWidth(TextWidth), cell._parentNodeIndex); + AlienGui::InputInt(AlienGui::InputIntParameters().name(_("Gene index")).textWidth(TextWidth), cell._geneIndex); + AlienGui::InputInt(AlienGui::InputIntParameters().name(_("Concatenation index")).textWidth(TextWidth), cell._concatenationIndex); + AlienGui::InputInt(AlienGui::InputIntParameters().name(_("Branch index")).textWidth(TextWidth), cell._branchIndex); + AlienGui::InputInt(AlienGui::InputIntParameters().name(_("Activation time")).textWidth(TextWidth), cell._activationTime); + AlienGui::Checkbox(AlienGui::CheckboxParameters().name(_("Head cell")).textWidth(TextWidth), cell._headCell); auto cellType = cell.getCellType(); AlienGui::ComboParameters cellTypeParams; - cellTypeParams.name("Cell type").textWidth(TextWidth).values(Const::CellTypeStrings); + cellTypeParams.name(_("Cell type")).textWidth(TextWidth).values(Const::CellTypeStrings); if (AlienGui::Combo(cellTypeParams, cellType)) { cell._cellType = createCellTypeDesc(cellType); if (cellType == CellType_Void) { @@ -525,7 +525,7 @@ void _InspectionWindow::processCellNode(ObjectDesc& object) // Void cells cannot have a constructor if (cellType != CellType_Void) { bool hasConstructor = cell._constructor.has_value(); - AlienGui::Checkbox(AlienGui::CheckboxParameters().name("Has constructor").textWidth(TextWidth), hasConstructor); + AlienGui::Checkbox(AlienGui::CheckboxParameters().name(_("Has constructor")).textWidth(TextWidth), hasConstructor); if (hasConstructor && !cell._constructor.has_value()) { cell._constructor = ConstructorDesc(); } else if (!hasConstructor && cell._constructor.has_value()) { @@ -548,27 +548,27 @@ void _InspectionWindow::processCellNode(ObjectDesc& object) void _InspectionWindow::processConstructorNode(ConstructorDesc& constructor) { - if (AlienGui::BeginTreeNode(AlienGui::TreeNodeParameters().name("Constructor").rank(AlienGui::TreeNodeRank::Default).defaultOpen(false))) { - AlienGui::InputOptionalInt(AlienGui::InputIntParameters().name("Auto trigger interval").textWidth(TextWidth), constructor._autoTriggerInterval); - AlienGui::InputInt(AlienGui::InputIntParameters().name("Activation time").textWidth(TextWidth), constructor._constructionActivationTime); - AlienGui::InputFloat(AlienGui::InputFloatParameters().name("Construction angle").format("%.2f").textWidth(TextWidth), constructor._constructionAngle); + if (AlienGui::BeginTreeNode(AlienGui::TreeNodeParameters().name(_("Constructor")).rank(AlienGui::TreeNodeRank::Default).defaultOpen(false))) { + AlienGui::InputOptionalInt(AlienGui::InputIntParameters().name(_("Auto trigger interval")).textWidth(TextWidth), constructor._autoTriggerInterval); + AlienGui::InputInt(AlienGui::InputIntParameters().name(_("Activation time")).textWidth(TextWidth), constructor._constructionActivationTime); + AlienGui::InputFloat(AlienGui::InputFloatParameters().name(_("Construction angle")).format("%.2f").textWidth(TextWidth), constructor._constructionAngle); int providedEnergy = constructor._provideEnergy; - if (AlienGui::Combo(AlienGui::ComboParameters().name("Provide energy").textWidth(TextWidth).values(Const::ProvideEnergyStrings), providedEnergy)) { + if (AlienGui::Combo(AlienGui::ComboParameters().name(_("Provide energy")).textWidth(TextWidth).values(Const::ProvideEnergyStrings), providedEnergy)) { constructor._provideEnergy = static_cast(providedEnergy); } - AlienGui::InputFloat(AlienGui::InputFloatParameters().name("Reserved energy").format("%.2f").textWidth(TextWidth), constructor._reservedEnergy); - AlienGui::Checkbox(AlienGui::CheckboxParameters().name("Separation").textWidth(TextWidth), constructor._separation); + AlienGui::InputFloat(AlienGui::InputFloatParameters().name(_("Reserved energy")).format("%.2f").textWidth(TextWidth), constructor._reservedEnergy); + AlienGui::Checkbox(AlienGui::CheckboxParameters().name(_("Separation")).textWidth(TextWidth), constructor._separation); auto numBranches = constructor._numBranches - 1; if (constructor._separation) { ImGui::BeginDisabled(); } - AlienGui::Switcher(AlienGui::SwitcherParameters().name("Number of branches").values({"1", "2", "3", "4", "5", "6"}).textWidth(TextWidth), &numBranches); + AlienGui::Switcher(AlienGui::SwitcherParameters().name(_("Number of branches")).values({_("1"), _("2"), _("3"), _("4"), _("5"), _("6")}).textWidth(TextWidth), &numBranches); if (constructor._separation) { ImGui::EndDisabled(); } constructor._numBranches = numBranches + 1; - AlienGui::InputInt(AlienGui::InputIntParameters().name("Concatenations").infinity(true).textWidth(TextWidth), constructor._numConcatenations); - AlienGui::InputInt(AlienGui::InputIntParameters().name("Gene index").textWidth(TextWidth), constructor._geneIndex); + AlienGui::InputInt(AlienGui::InputIntParameters().name(_("Concatenations")).infinity(true).textWidth(TextWidth), constructor._numConcatenations); + AlienGui::InputInt(AlienGui::InputIntParameters().name(_("Gene index")).textWidth(TextWidth), constructor._geneIndex); } AlienGui::EndTreeNode(); } @@ -580,20 +580,20 @@ void _InspectionWindow::processCreatureProperties(ExtendedObjectDesc& extendedOb inspectorHexId("Creature id", creature._id); inspectorText("Generation", std::to_string(creature._generation)); inspectorText("Num cells", std::to_string(creature._numCells)); - AlienGui::InputInt(AlienGui::InputIntParameters().name("Lineage id").textWidth(TextWidth), creature._lineageId); - AlienGui::InputFloat(AlienGui::InputFloatParameters().name("Accumulated mutations").format("%.5f").textWidth(TextWidth), creature._accumulatedMutations); + AlienGui::InputInt(AlienGui::InputIntParameters().name(_("Lineage id")).textWidth(TextWidth), creature._lineageId); + AlienGui::InputFloat(AlienGui::InputFloatParameters().name(_("Accumulated mutations")).format("%.5f").textWidth(TextWidth), creature._accumulatedMutations); auto& genome = extendedObject.genome.value(); inspectorText("Genome name", genome._name); inspectorText("Resistance to injection", genome._resistanceToInjection ? "Yes" : "No"); inspectorText("Apply meta-mutations", genome._applyMetaMutations ? "Yes" : "No"); - if (AlienGui::Button(AlienGui::ButtonParameters().buttonText("Edit").name("Edit genome").textWidth(TextWidth))) { + if (AlienGui::Button(AlienGui::ButtonParameters().buttonText("Edit").name(_("Edit genome")).textWidth(TextWidth))) { GenomeEditorWindow::get().openTab(genome, false); } } void _InspectionWindow::processCreatureNode(ExtendedObjectDesc& extendedObject) { - if (AlienGui::BeginTreeNode(AlienGui::TreeNodeParameters().name("Creature").rank(AlienGui::TreeNodeRank::High).defaultOpen(false))) { + if (AlienGui::BeginTreeNode(AlienGui::TreeNodeParameters().name(_("Creature")).rank(AlienGui::TreeNodeRank::High).defaultOpen(false))) { processPropertiesSubNode("Creature", [&] { processCreatureProperties(extendedObject); }); } AlienGui::EndTreeNode(); @@ -601,7 +601,7 @@ void _InspectionWindow::processCreatureNode(ExtendedObjectDesc& extendedObject) void _InspectionWindow::processSignalsNode(CellDesc& cell) { - if (AlienGui::BeginTreeNode(AlienGui::TreeNodeParameters().name("Signals").rank(AlienGui::TreeNodeRank::Default).defaultOpen(false))) { + if (AlienGui::BeginTreeNode(AlienGui::TreeNodeParameters().name(_("Signals")).rank(AlienGui::TreeNodeRank::Default).defaultOpen(false))) { auto& channels = cell._signal._channels; if (static_cast(channels.size()) < NEURONS_PER_CELL) { channels.resize(NEURONS_PER_CELL, 0.0f); @@ -616,7 +616,7 @@ void _InspectionWindow::processSignalsNode(CellDesc& cell) void _InspectionWindow::processNeuralNetNode(CellDesc& cell) { - if (AlienGui::BeginTreeNode(AlienGui::TreeNodeParameters().name("Neural network").rank(AlienGui::TreeNodeRank::Default).defaultOpen(false))) { + if (AlienGui::BeginTreeNode(AlienGui::TreeNodeParameters().name(_("Neural network")).rank(AlienGui::TreeNodeRank::Default).defaultOpen(false))) { _neuralNetWidget->process( cell._neuralNetwork._weights, cell._neuralNetwork._biases, cell._neuralNetwork._activationFunctions, cell._neuralNetwork._connectionWeights); } @@ -631,12 +631,12 @@ namespace for (int i = 0; i < NEURONS_PER_CELL; ++i) { bits[i] = (bitMask & (1 << i)) != 0; } - AlienGui::MultiCheckboxes(AlienGui::MultiCheckboxesParameters().name("Channel mask bit 0-3").textWidth(TextWidth), bits[0], bits[1], bits[2], bits[3]); - AlienGui::MultiCheckboxes(AlienGui::MultiCheckboxesParameters().name("Channel mask bit 4-7").textWidth(TextWidth), bits[4], bits[5], bits[6], bits[7]); + AlienGui::MultiCheckboxes(AlienGui::MultiCheckboxesParameters().name(_("Channel mask bit 0-3")).textWidth(TextWidth), bits[0], bits[1], bits[2], bits[3]); + AlienGui::MultiCheckboxes(AlienGui::MultiCheckboxesParameters().name(_("Channel mask bit 4-7")).textWidth(TextWidth), bits[4], bits[5], bits[6], bits[7]); AlienGui::MultiCheckboxes( - AlienGui::MultiCheckboxesParameters().name("Channel mask bit 8-11").textWidth(TextWidth), bits[8], bits[9], bits[10], bits[11]); + AlienGui::MultiCheckboxesParameters().name(_("Channel mask bit 8-11")).textWidth(TextWidth), bits[8], bits[9], bits[10], bits[11]); AlienGui::MultiCheckboxes( - AlienGui::MultiCheckboxesParameters().name("Channel mask bit 12-15").textWidth(TextWidth), bits[12], bits[13], bits[14], bits[15]); + AlienGui::MultiCheckboxesParameters().name(_("Channel mask bit 12-15")).textWidth(TextWidth), bits[12], bits[13], bits[14], bits[15]); bitMask = 0; for (int i = 0; i < NEURONS_PER_CELL; ++i) { if (bits[i]) { @@ -655,130 +655,130 @@ void _InspectionWindow::processCellTypeNode(CellDesc& cell) if (cellType == CellType_Depot) { auto& depot = std::get(cell._cellType); - AlienGui::InputFloat(AlienGui::InputFloatParameters().name("Storage limit").format("%.2f").textWidth(TextWidth), depot._storageLimit); - AlienGui::InputFloat(AlienGui::InputFloatParameters().name("Stored usable energy").format("%.2f").textWidth(TextWidth), depot._storedUsableEnergy); + AlienGui::InputFloat(AlienGui::InputFloatParameters().name(_("Storage limit")).format("%.2f").textWidth(TextWidth), depot._storageLimit); + AlienGui::InputFloat(AlienGui::InputFloatParameters().name(_("Stored usable energy")).format("%.2f").textWidth(TextWidth), depot._storedUsableEnergy); } else if (cellType == CellType_Sensor) { auto& sensor = std::get(cell._cellType); - AlienGui::Checkbox(AlienGui::CheckboxParameters().name("Auto trigger").textWidth(TextWidth), sensor._autoTrigger); - AlienGui::Checkbox(AlienGui::CheckboxParameters().name("Tag for attackers").textWidth(TextWidth), sensor._tagForAttackers); + AlienGui::Checkbox(AlienGui::CheckboxParameters().name(_("Auto trigger")).textWidth(TextWidth), sensor._autoTrigger); + AlienGui::Checkbox(AlienGui::CheckboxParameters().name(_("Tag for attackers")).textWidth(TextWidth), sensor._tagForAttackers); auto mode = sensor.getMode(); AlienGui::ComboParameters modeParams; - modeParams.name("Mode").textWidth(TextWidth).values(Const::SensorModeStrings); + modeParams.name(_("Mode")).textWidth(TextWidth).values(Const::SensorModeStrings); if (AlienGui::Combo(modeParams, mode)) { sensor._mode = createSensorModeDesc(mode); } if (mode == SensorMode_DetectEnergy) { auto& m = std::get(sensor._mode); - AlienGui::InputFloat(AlienGui::InputFloatParameters().name("Min density").step(0.05f).format("%.2f").textWidth(TextWidth), m._minDensity); + AlienGui::InputFloat(AlienGui::InputFloatParameters().name(_("Min density")).step(0.05f).format("%.2f").textWidth(TextWidth), m._minDensity); } else if (mode == SensorMode_DetectFreeCell) { auto& m = std::get(sensor._mode); - AlienGui::InputFloat(AlienGui::InputFloatParameters().name("Min density").step(0.05f).format("%.2f").textWidth(TextWidth), m._minDensity); + AlienGui::InputFloat(AlienGui::InputFloatParameters().name(_("Min density")).step(0.05f).format("%.2f").textWidth(TextWidth), m._minDensity); AlienGui::ColorCheckboxes( - AlienGui::ColorCheckboxesParameters().customizationColors(customizationColors).name("Restrict to colors").textWidth(TextWidth), + AlienGui::ColorCheckboxesParameters().customizationColors(customizationColors).name(_("Restrict to colors")).textWidth(TextWidth), m._restrictToColors); } else if (mode == SensorMode_DetectCreature) { auto& m = std::get(sensor._mode); - AlienGui::InputOptionalInt(AlienGui::InputIntParameters().name("Min num cells").textWidth(TextWidth), m._minNumCells); - AlienGui::InputOptionalInt(AlienGui::InputIntParameters().name("Max num cells").textWidth(TextWidth), m._maxNumCells); + AlienGui::InputOptionalInt(AlienGui::InputIntParameters().name(_("Min num cells")).textWidth(TextWidth), m._minNumCells); + AlienGui::InputOptionalInt(AlienGui::InputIntParameters().name(_("Max num cells")).textWidth(TextWidth), m._maxNumCells); AlienGui::ColorCheckboxes( - AlienGui::ColorCheckboxesParameters().customizationColors(customizationColors).name("Restrict to colors").textWidth(TextWidth), + AlienGui::ColorCheckboxesParameters().customizationColors(customizationColors).name(_("Restrict to colors")).textWidth(TextWidth), m._restrictToColors); AlienGui::ComboParameters lineageParams; - lineageParams.name("Restrict to lineage").textWidth(TextWidth).values({"No", "Same lineage", "Other lineage"}); + lineageParams.name(_("Restrict to lineage")).textWidth(TextWidth).values({_("No"), _("Same lineage"), _("Other lineage")}); AlienGui::Combo(lineageParams, m._restrictToLineage); } - AlienGui::SliderInt(AlienGui::SliderIntParameters().name("Min range").min(0).max(255).textWidth(TextWidth), &sensor._minRange); - AlienGui::SliderInt(AlienGui::SliderIntParameters().name("Max range").min(0).max(255).textWidth(TextWidth), &sensor._maxRange); + AlienGui::SliderInt(AlienGui::SliderIntParameters().name(_("Min range")).min(0).max(255).textWidth(TextWidth), &sensor._minRange); + AlienGui::SliderInt(AlienGui::SliderIntParameters().name(_("Max range")).min(0).max(255).textWidth(TextWidth), &sensor._maxRange); } else if (cellType == CellType_Generator) { auto& generator = std::get(cell._cellType); - AlienGui::Checkbox(AlienGui::CheckboxParameters().name("Additive").textWidth(TextWidth), generator._additive); - AlienGui::InputFloat(AlienGui::InputFloatParameters().name("Min value").step(0.05f).format("%.2f").textWidth(TextWidth), generator._minValue); - AlienGui::InputFloat(AlienGui::InputFloatParameters().name("Max value").step(0.05f).format("%.2f").textWidth(TextWidth), generator._maxValue); - AlienGui::InputInt(AlienGui::InputIntParameters().name("Time offset").textWidth(TextWidth), generator._timeOffset); + AlienGui::Checkbox(AlienGui::CheckboxParameters().name(_("Additive")).textWidth(TextWidth), generator._additive); + AlienGui::InputFloat(AlienGui::InputFloatParameters().name(_("Min value")).step(0.05f).format("%.2f").textWidth(TextWidth), generator._minValue); + AlienGui::InputFloat(AlienGui::InputFloatParameters().name(_("Max value")).step(0.05f).format("%.2f").textWidth(TextWidth), generator._maxValue); + AlienGui::InputInt(AlienGui::InputIntParameters().name(_("Time offset")).textWidth(TextWidth), generator._timeOffset); auto mode = generator.getMode(); AlienGui::ComboParameters modeParams; - modeParams.name("Mode").textWidth(TextWidth).values(Const::GeneratorModeStrings); + modeParams.name(_("Mode")).textWidth(TextWidth).values(Const::GeneratorModeStrings); if (AlienGui::Combo(modeParams, mode)) { generator._mode = createGeneratorModeDesc(mode); } if (mode == GeneratorMode_SquareSignal) { auto& m = std::get(generator._mode); - AlienGui::InputInt(AlienGui::InputIntParameters().name("Period").textWidth(TextWidth), m._period); + AlienGui::InputInt(AlienGui::InputIntParameters().name(_("Period")).textWidth(TextWidth), m._period); } else if (mode == GeneratorMode_SawtoothSignal) { auto& m = std::get(generator._mode); - AlienGui::InputInt(AlienGui::InputIntParameters().name("Period").textWidth(TextWidth), m._period); + AlienGui::InputInt(AlienGui::InputIntParameters().name(_("Period")).textWidth(TextWidth), m._period); } } else if (cellType == CellType_Attacker) { auto& attacker = std::get(cell._cellType); auto mode = attacker.getMode(); AlienGui::ComboParameters modeParams; - modeParams.name("Mode").textWidth(TextWidth).values(Const::AttackerModeStrings); + modeParams.name(_("Mode")).textWidth(TextWidth).values(Const::AttackerModeStrings); if (AlienGui::Combo(modeParams, mode)) { attacker._mode = createAttackerModeDesc(mode); } if (mode == AttackerMode_FreeCell) { auto& m = std::get(attacker._mode); AlienGui::ColorCheckboxes( - AlienGui::ColorCheckboxesParameters().customizationColors(customizationColors).name("Restrict to colors").textWidth(TextWidth), + AlienGui::ColorCheckboxesParameters().customizationColors(customizationColors).name(_("Restrict to colors")).textWidth(TextWidth), m._restrictToColors); } } else if (cellType == CellType_Injector) { auto& injector = std::get(cell._cellType); - AlienGui::InputInt(AlienGui::InputIntParameters().name("Gene index").textWidth(TextWidth), injector._geneIndex); + AlienGui::InputInt(AlienGui::InputIntParameters().name(_("Gene index")).textWidth(TextWidth), injector._geneIndex); } else if (cellType == CellType_Muscle) { auto& muscle = std::get(cell._cellType); auto mode = muscle.getMode(); AlienGui::ComboParameters modeParams; - modeParams.name("Mode").textWidth(TextWidth).values(Const::MuscleModeStrings); + modeParams.name(_("Mode")).textWidth(TextWidth).values(Const::MuscleModeStrings); if (AlienGui::Combo(modeParams, mode)) { muscle._mode = createMuscleModeDesc(mode); } if (mode == MuscleMode_AutoBending) { auto& m = std::get(muscle._mode); AlienGui::SliderFloat( - AlienGui::SliderFloatParameters().name("Max angle deviation").min(0.0f).max(1.0f).format("%.2f").textWidth(TextWidth), + AlienGui::SliderFloatParameters().name(_("Max angle deviation")).min(0.0f).max(1.0f).format("%.2f").textWidth(TextWidth), &m._maxAngleDeviation); AlienGui::SliderFloat( - AlienGui::SliderFloatParameters().name("Forward backward ratio").min(0.0f).max(1.0f).format("%.2f").textWidth(TextWidth), + AlienGui::SliderFloatParameters().name(_("Forward backward ratio")).min(0.0f).max(1.0f).format("%.2f").textWidth(TextWidth), &m._forwardBackwardRatio); } else if (mode == MuscleMode_ManualBending) { auto& m = std::get(muscle._mode); AlienGui::SliderFloat( - AlienGui::SliderFloatParameters().name("Max angle deviation").min(0.0f).max(1.0f).format("%.2f").textWidth(TextWidth), + AlienGui::SliderFloatParameters().name(_("Max angle deviation")).min(0.0f).max(1.0f).format("%.2f").textWidth(TextWidth), &m._maxAngleDeviation); AlienGui::SliderFloat( - AlienGui::SliderFloatParameters().name("Forward backward ratio").min(0.0f).max(1.0f).format("%.2f").textWidth(TextWidth), + AlienGui::SliderFloatParameters().name(_("Forward backward ratio")).min(0.0f).max(1.0f).format("%.2f").textWidth(TextWidth), &m._forwardBackwardRatio); } else if (mode == MuscleMode_AngleBending) { auto& m = std::get(muscle._mode); AlienGui::SliderFloat( - AlienGui::SliderFloatParameters().name("Max angle deviation").min(0.0f).max(1.0f).format("%.2f").textWidth(TextWidth), + AlienGui::SliderFloatParameters().name(_("Max angle deviation")).min(0.0f).max(1.0f).format("%.2f").textWidth(TextWidth), &m._maxAngleDeviation); AlienGui::InputFloat( - AlienGui::InputFloatParameters().name("Attraction repulsion ratio").step(0.05f).format("%.2f").textWidth(TextWidth), + AlienGui::InputFloatParameters().name(_("Attraction repulsion ratio")).step(0.05f).format("%.2f").textWidth(TextWidth), m._attractionRepulsionRatio); } else if (mode == MuscleMode_AutoCrawling) { auto& m = std::get(muscle._mode); AlienGui::SliderFloat( - AlienGui::SliderFloatParameters().name("Max distance deviation").min(0.0f).max(1.0f).format("%.2f").textWidth(TextWidth), + AlienGui::SliderFloatParameters().name(_("Max distance deviation")).min(0.0f).max(1.0f).format("%.2f").textWidth(TextWidth), &m._maxDistanceDeviation); AlienGui::SliderFloat( - AlienGui::SliderFloatParameters().name("Forward backward ratio").min(0.0f).max(1.0f).format("%.2f").textWidth(TextWidth), + AlienGui::SliderFloatParameters().name(_("Forward backward ratio")).min(0.0f).max(1.0f).format("%.2f").textWidth(TextWidth), &m._forwardBackwardRatio); } else if (mode == MuscleMode_ManualCrawling) { auto& m = std::get(muscle._mode); AlienGui::SliderFloat( - AlienGui::SliderFloatParameters().name("Max distance deviation").min(0.0f).max(1.0f).format("%.2f").textWidth(TextWidth), + AlienGui::SliderFloatParameters().name(_("Max distance deviation")).min(0.0f).max(1.0f).format("%.2f").textWidth(TextWidth), &m._maxDistanceDeviation); AlienGui::SliderFloat( - AlienGui::SliderFloatParameters().name("Forward backward ratio").min(0.0f).max(1.0f).format("%.2f").textWidth(TextWidth), + AlienGui::SliderFloatParameters().name(_("Forward backward ratio")).min(0.0f).max(1.0f).format("%.2f").textWidth(TextWidth), &m._forwardBackwardRatio); } } else if (cellType == CellType_Defender) { auto& defender = std::get(cell._cellType); int defMode = defender._mode; AlienGui::ComboParameters modeParams; - modeParams.name("Mode").textWidth(TextWidth).values(Const::DefenderModeStrings); + modeParams.name(_("Mode")).textWidth(TextWidth).values(Const::DefenderModeStrings); if (AlienGui::Combo(modeParams, defMode)) { defender._mode = static_cast(defMode); } @@ -786,24 +786,24 @@ void _InspectionWindow::processCellTypeNode(CellDesc& cell) auto& reconnector = std::get(cell._cellType); auto mode = reconnector.getMode(); AlienGui::ComboParameters modeParams; - modeParams.name("Mode").textWidth(TextWidth).values(Const::ReconnectorModeStrings); + modeParams.name(_("Mode")).textWidth(TextWidth).values(Const::ReconnectorModeStrings); if (AlienGui::Combo(modeParams, mode)) { reconnector._mode = createReconnectorModeDesc(mode); } if (mode == ReconnectorMode_FreeCell) { auto& m = std::get(reconnector._mode); AlienGui::ColorCheckboxes( - AlienGui::ColorCheckboxesParameters().customizationColors(customizationColors).name("Restrict to colors").textWidth(TextWidth), + AlienGui::ColorCheckboxesParameters().customizationColors(customizationColors).name(_("Restrict to colors")).textWidth(TextWidth), m._restrictToColors); } else if (mode == ReconnectorMode_Creature) { auto& m = std::get(reconnector._mode); - AlienGui::InputOptionalInt(AlienGui::InputIntParameters().name("Min num cells").textWidth(TextWidth), m._minNumCells); - AlienGui::InputOptionalInt(AlienGui::InputIntParameters().name("Max num cells").textWidth(TextWidth), m._maxNumCells); + AlienGui::InputOptionalInt(AlienGui::InputIntParameters().name(_("Min num cells")).textWidth(TextWidth), m._minNumCells); + AlienGui::InputOptionalInt(AlienGui::InputIntParameters().name(_("Max num cells")).textWidth(TextWidth), m._maxNumCells); AlienGui::ColorCheckboxes( - AlienGui::ColorCheckboxesParameters().customizationColors(customizationColors).name("Restrict to colors").textWidth(TextWidth), + AlienGui::ColorCheckboxesParameters().customizationColors(customizationColors).name(_("Restrict to colors")).textWidth(TextWidth), m._restrictToColors); AlienGui::ComboParameters lineageParams; - lineageParams.name("Restrict to lineage").textWidth(TextWidth).values({"No", "Same lineage", "Other lineage"}); + lineageParams.name(_("Restrict to lineage")).textWidth(TextWidth).values({_("No"), _("Same lineage"), _("Other lineage")}); AlienGui::Combo(lineageParams, m._restrictToLineage); } } else if (cellType == CellType_Detonator) { @@ -811,24 +811,24 @@ void _InspectionWindow::processCellTypeNode(CellDesc& cell) static std::vector const detonatorStateStrings = {"Ready", "Activated", "Exploded"}; int state = detonator._state; AlienGui::ComboParameters stateParams; - stateParams.name("State").textWidth(TextWidth).values(detonatorStateStrings); + stateParams.name(_("State")).textWidth(TextWidth).values(detonatorStateStrings); if (AlienGui::Combo(stateParams, state)) { detonator._state = static_cast(state); } - AlienGui::InputInt(AlienGui::InputIntParameters().name("Countdown").textWidth(TextWidth), detonator._countdown); + AlienGui::InputInt(AlienGui::InputIntParameters().name(_("Countdown")).textWidth(TextWidth), detonator._countdown); } else if (cellType == CellType_Digestor) { auto& digestor = std::get(cell._cellType); AlienGui::SliderFloat( - AlienGui::SliderFloatParameters().name("Raw energy conductivity").max(1.0f).format("%.2f").textWidth(TextWidth), + AlienGui::SliderFloatParameters().name(_("Raw energy conductivity")).max(1.0f).format("%.2f").textWidth(TextWidth), &digestor._rawEnergyConductivity); auto conversion = digestor.getRawEnergyConversionRate(); - AlienGui::SliderFloat(AlienGui::SliderFloatParameters().name("Energy conversion").max(1.0f).format("%.2f").textWidth(TextWidth), &conversion); + AlienGui::SliderFloat(AlienGui::SliderFloatParameters().name(_("Energy conversion")).max(1.0f).format("%.2f").textWidth(TextWidth), &conversion); digestor.setRawEnergyConversionRate(conversion); } else if (cellType == CellType_Memory) { auto& memory = std::get(cell._cellType); auto mode = memory.getMode(); AlienGui::ComboParameters modeParams; - modeParams.name("Mode").textWidth(TextWidth).values(Const::MemoryModeStrings); + modeParams.name(_("Mode")).textWidth(TextWidth).values(Const::MemoryModeStrings); if (AlienGui::Combo(modeParams, mode)) { memory._mode = createMemoryModeDesc(mode); if (mode == MemoryMode_SignalRecorder || mode == MemoryMode_SignalStorage) { @@ -837,20 +837,20 @@ void _InspectionWindow::processCellTypeNode(CellDesc& cell) } if (mode == MemoryMode_SignalDelay) { auto& m = std::get(memory._mode); - AlienGui::InputInt(AlienGui::InputIntParameters().name("Delay").textWidth(TextWidth), m._delay); + AlienGui::InputInt(AlienGui::InputIntParameters().name(_("Delay")).textWidth(TextWidth), m._delay); } else if (mode == MemoryMode_SignalRecorder) { auto& m = std::get(memory._mode); - AlienGui::Checkbox(AlienGui::CheckboxParameters().name("Read only").textWidth(TextWidth), m._readOnly); + AlienGui::Checkbox(AlienGui::CheckboxParameters().name(_("Read only")).textWidth(TextWidth), m._readOnly); } else if (mode == MemoryMode_SignalStorage) { auto& m = std::get(memory._mode); - AlienGui::Checkbox(AlienGui::CheckboxParameters().name("Read only").textWidth(TextWidth), m._readOnly); + AlienGui::Checkbox(AlienGui::CheckboxParameters().name(_("Read only")).textWidth(TextWidth), m._readOnly); } else if (mode == MemoryMode_SignalIntegrator) { auto& m = std::get(memory._mode); AlienGui::SliderFloat( - AlienGui::SliderFloatParameters().name("New signal weight").max(1.0f).format("%.2f").textWidth(TextWidth), &m._newSignalWeight); + AlienGui::SliderFloatParameters().name(_("New signal weight")).max(1.0f).format("%.2f").textWidth(TextWidth), &m._newSignalWeight); } processMemoryChannelBits(memory._channelBitMask); - if (AlienGui::Button(AlienGui::ButtonParameters().buttonText("Edit").name("Signal buffer").textWidth(TextWidth))) { + if (AlienGui::Button(AlienGui::ButtonParameters().buttonText("Edit").name(_("Signal buffer")).textWidth(TextWidth))) { SignalsBufferDialog::get().open( memory._signalEntries, [this](std::vector const& entries) { _pendingSignalEntries = entries; }); } @@ -858,21 +858,21 @@ void _InspectionWindow::processCellTypeNode(CellDesc& cell) auto& communicator = std::get(cell._cellType); auto mode = communicator.getMode(); AlienGui::ComboParameters modeParams; - modeParams.name("Mode").textWidth(TextWidth).values(Const::CommunicatorModeStrings); + modeParams.name(_("Mode")).textWidth(TextWidth).values(Const::CommunicatorModeStrings); if (AlienGui::Combo(modeParams, mode)) { communicator._mode = createCommunicatorModeDesc(mode); } if (mode == CommunicatorMode_Sender) { auto& m = std::get(communicator._mode); - AlienGui::SliderInt(AlienGui::SliderIntParameters().name("Range").min(0).max(20).textWidth(TextWidth), &m._range); - AlienGui::Checkbox(AlienGui::CheckboxParameters().name("One-way").textWidth(TextWidth), m._oneway); + AlienGui::SliderInt(AlienGui::SliderIntParameters().name(_("Range")).min(0).max(20).textWidth(TextWidth), &m._range); + AlienGui::Checkbox(AlienGui::CheckboxParameters().name(_("One-way")).textWidth(TextWidth), m._oneway); } else if (mode == CommunicatorMode_Receiver) { auto& m = std::get(communicator._mode); AlienGui::ColorCheckboxes( - AlienGui::ColorCheckboxesParameters().customizationColors(customizationColors).name("Restrict to colors").textWidth(TextWidth), + AlienGui::ColorCheckboxesParameters().customizationColors(customizationColors).name(_("Restrict to colors")).textWidth(TextWidth), m._restrictToColors); AlienGui::ComboParameters lineageParams; - lineageParams.name("Restrict to lineage").textWidth(TextWidth).values({"No", "Same lineage", "Other lineage"}); + lineageParams.name(_("Restrict to lineage")).textWidth(TextWidth).values({_("No"), _("Same lineage"), _("Other lineage")}); AlienGui::Combo(lineageParams, m._restrictToLineage); } } diff --git a/source/Gui/LogWindow.cpp b/source/Gui/LogWindow.cpp index 26c744915..82b5f5963 100644 --- a/source/Gui/LogWindow.cpp +++ b/source/Gui/LogWindow.cpp @@ -17,7 +17,7 @@ void LogWindow::initIntern() } LogWindow::LogWindow() - : AlienWindow("Log", "windows.log", false) + : AlienWindow(_("Log"), "windows.log", false) {} void LogWindow::shutdownIntern() @@ -42,5 +42,5 @@ void LogWindow::processIntern() ImGui::Spacing(); ImGui::Spacing(); - AlienGui::ToggleButton(AlienGui::ToggleButtonParameters().name("Verbose"), _verbose); + AlienGui::ToggleButton(AlienGui::ToggleButtonParameters().name(_("Verbose")), _verbose); } diff --git a/source/Gui/LoginDialog.cpp b/source/Gui/LoginDialog.cpp index fe79acb44..41a14f381 100644 --- a/source/Gui/LoginDialog.cpp +++ b/source/Gui/LoginDialog.cpp @@ -25,42 +25,42 @@ void LoginDialog::initIntern() } LoginDialog::LoginDialog() - : AlienDialog("Login") + : AlienDialog(_("Login")) {} void LoginDialog::processIntern() { - AlienGui::Text("How to create a new user?"); + AlienGui::Text(_("How to create a new user?")); AlienGui::HelpMarker(Const::LoginHowToCreateNewUseTooltip); - AlienGui::Text("Forgot your password?"); + AlienGui::Text(_("Forgot your password?")); AlienGui::HelpMarker(Const::LoginForgotYourPasswordTooltip); - AlienGui::Text("Security information"); + AlienGui::Text(_("Security information")); AlienGui::HelpMarker(Const::LoginSecurityInformationTooltip); AlienGui::Separator(); auto& loginController = LoginController::get(); auto userName = loginController.getUserName(); - AlienGui::InputText(AlienGui::InputTextParameters().hint("User name").textWidth(0), userName); + AlienGui::InputText(AlienGui::InputTextParameters().hint(_("User name")).textWidth(0), userName); loginController.setUserName(userName); auto password = loginController.getPassword(); - AlienGui::InputText(AlienGui::InputTextParameters().hint("Password").password(true).textWidth(0), password); + AlienGui::InputText(AlienGui::InputTextParameters().hint(_("Password")).password(true).textWidth(0), password); loginController.setPassword(password); AlienGui::Separator(); ImGui::Spacing(); auto remember = loginController.isRemember(); - AlienGui::ToggleButton(AlienGui::ToggleButtonParameters().name("Remember").tooltip(Const::LoginRememberTooltip), remember); + AlienGui::ToggleButton(AlienGui::ToggleButtonParameters().name(_("Remember")).tooltip(Const::LoginRememberTooltip), remember); loginController.setRemember(remember); auto shareGpuInfo = loginController.shareGpuInfo(); AlienGui::ToggleButton( AlienGui::ToggleButtonParameters() - .name("Share GPU model info") + .name(_("Share GPU model info")) .tooltip(Const::LoginShareGpuInfoTooltip1 + _SimulationFacade::get()->getGpuName() + "\n" + Const::LoginShareGpuInfoTooltip2), shareGpuInfo); loginController.setShareGpuInfo(shareGpuInfo); @@ -69,7 +69,7 @@ void LoginDialog::processIntern() AlienGui::Separator(); ImGui::BeginDisabled(userName.empty() || password.empty()); - if (AlienGui::Button("Login")) { + if (AlienGui::Button(_("Login"))) { close(); loginController.onLogin(); } @@ -81,7 +81,7 @@ void LoginDialog::processIntern() ImGui::SameLine(); ImGui::BeginDisabled(userName.empty() || password.empty()); - if (AlienGui::Button("Create user")) { + if (AlienGui::Button(_("Create user"))) { close(); CreateUserDialog::get().open(userName, password, LoginController::get().getUserInfo()); } @@ -89,7 +89,7 @@ void LoginDialog::processIntern() ImGui::SameLine(); ImGui::BeginDisabled(userName.empty()); - if (AlienGui::Button("Reset password")) { + if (AlienGui::Button(_("Reset password"))) { close(); ResetPasswordDialog::get().open(userName, LoginController::get().getUserInfo()); } @@ -99,7 +99,7 @@ void LoginDialog::processIntern() AlienGui::VerticalSeparator(); ImGui::SameLine(); - if (AlienGui::Button("Cancel")) { + if (AlienGui::Button(_("Cancel"))) { close(); } } diff --git a/source/Gui/MainLoopController.cpp b/source/Gui/MainLoopController.cpp index f89b730f2..b2bd94987 100644 --- a/source/Gui/MainLoopController.cpp +++ b/source/Gui/MainLoopController.cpp @@ -249,7 +249,7 @@ void MainLoopController::processOperatingMode() void MainLoopController::processScheduleExit() { if (_saveOnExit) { - printOverlayMessage("Saving on exit ..."); + printOverlayMessage(_("Saving on exit ...")); auto senderInfo = SenderInfo{.senderId = SenderId{StartupSenderId}, .wishResultData = true, .wishErrorInfo = true}; auto saveData = SaveSimulationRequestData{Const::AutosaveFile, Viewport::get().getZoomFactor(), Viewport::get().getCenterInWorldPos()}; @@ -348,45 +348,45 @@ void MainLoopController::processMenubar() ImGui::Dummy(ImVec2(scale(10.0f), 0.0f)); AlienGui::BeginMenu(" " ICON_FA_GAMEPAD " Simulation ", _simulationMenuOpened); - AlienGui::MenuItem(AlienGui::MenuItemParameters().name("New").keyCtrl(true).key(ImGuiKey_N), [&] { NewSimulationDialog::get().open(); }); + AlienGui::MenuItem(AlienGui::MenuItemParameters().name(_("New")).keyCtrl(true).key(ImGuiKey_N), [&] { NewSimulationDialog::get().open(); }); AlienGui::MenuItem( - AlienGui::MenuItemParameters().name("Open").keyCtrl(true).key(ImGuiKey_O), [&] { FileTransferController::get().onOpenSimulationDialog(); }); + AlienGui::MenuItemParameters().name(_("Open")).keyCtrl(true).key(ImGuiKey_O), [&] { FileTransferController::get().onOpenSimulationDialog(); }); AlienGui::MenuItem( - AlienGui::MenuItemParameters().name("Save").keyCtrl(true).key(ImGuiKey_S), [&] { FileTransferController::get().onSaveSimulationDialog(); }); + AlienGui::MenuItemParameters().name(_("Save")).keyCtrl(true).key(ImGuiKey_S), [&] { FileTransferController::get().onSaveSimulationDialog(); }); AlienGui::MenuSeparator(); auto running = _SimulationFacade::get()->isSimulationRunning(); - AlienGui::MenuItem(AlienGui::MenuItemParameters().name("Run").key(ImGuiKey_Space).disabled(running).closeMenuWhenItemClicked(false), [&] { + AlienGui::MenuItem(AlienGui::MenuItemParameters().name(_("Run")).key(ImGuiKey_Space).disabled(running).closeMenuWhenItemClicked(false), [&] { _SimulationFacade::get()->runSimulation(); - printOverlayMessage("Run"); + printOverlayMessage(_("Run")); }); - AlienGui::MenuItem(AlienGui::MenuItemParameters().name("Pause").key(ImGuiKey_Space).disabled(!running).closeMenuWhenItemClicked(false), [&] { + AlienGui::MenuItem(AlienGui::MenuItemParameters().name(_("Pause")).key(ImGuiKey_Space).disabled(!running).closeMenuWhenItemClicked(false), [&] { _SimulationFacade::get()->pauseSimulation(); - printOverlayMessage("Pause"); + printOverlayMessage(_("Pause")); }); AlienGui::EndMenu(); AlienGui::BeginMenu(" " ICON_FA_GLOBE " Network ", _networkMenuOpened); AlienGui::MenuItem( - AlienGui::MenuItemParameters().name("Browser").keyAlt(true).key(ImGuiKey_W).closeMenuWhenItemClicked(false).selected(BrowserWindow::get().isOn()), + AlienGui::MenuItemParameters().name(_("Browser")).keyAlt(true).key(ImGuiKey_W).closeMenuWhenItemClicked(false).selected(BrowserWindow::get().isOn()), [&] { BrowserWindow::get().setOn(!BrowserWindow::get().isOn()); }); AlienGui::MenuSeparator(); - AlienGui::MenuItem(AlienGui::MenuItemParameters().name("Login").keyAlt(true).key(ImGuiKey_L).disabled(NetworkService::get().isLoggedIn()), [&] { + AlienGui::MenuItem(AlienGui::MenuItemParameters().name(_("Login")).keyAlt(true).key(ImGuiKey_L).disabled(NetworkService::get().isLoggedIn()), [&] { LoginDialog::get().open(); }); AlienGui::MenuItem( - AlienGui::MenuItemParameters().name("Logout").keyAlt(true).key(ImGuiKey_T).closeMenuWhenItemClicked(false).disabled(!NetworkService::get().isLoggedIn()), + AlienGui::MenuItemParameters().name(_("Logout")).keyAlt(true).key(ImGuiKey_T).closeMenuWhenItemClicked(false).disabled(!NetworkService::get().isLoggedIn()), [&] { NetworkService::get().logout(); BrowserWindow::get().onRefresh(); }); AlienGui::MenuItem( - AlienGui::MenuItemParameters().name("Upload simulation").keyAlt(true).key(ImGuiKey_D).disabled(!NetworkService::get().isLoggedIn()), + AlienGui::MenuItemParameters().name(_("Upload simulation")).keyAlt(true).key(ImGuiKey_D).disabled(!NetworkService::get().isLoggedIn()), [&] { UploadSimulationDialog::get().open(NetworkResourceType_Simulation); }); - AlienGui::MenuItem(AlienGui::MenuItemParameters().name("Upload genome").keyAlt(true).key(ImGuiKey_Q).disabled(!NetworkService::get().isLoggedIn()), [&] { + AlienGui::MenuItem(AlienGui::MenuItemParameters().name(_("Upload genome")).keyAlt(true).key(ImGuiKey_Q).disabled(!NetworkService::get().isLoggedIn()), [&] { UploadSimulationDialog::get().open(NetworkResourceType_Genome); }); AlienGui::MenuSeparator(); - AlienGui::MenuItem(AlienGui::MenuItemParameters().name("Delete user").keyAlt(true).key(ImGuiKey_J).disabled(!NetworkService::get().isLoggedIn()), [&] { + AlienGui::MenuItem(AlienGui::MenuItemParameters().name(_("Delete user")).keyAlt(true).key(ImGuiKey_J).disabled(!NetworkService::get().isLoggedIn()), [&] { DeleteUserDialog::get().open(); }); AlienGui::EndMenu(); @@ -394,7 +394,7 @@ void MainLoopController::processMenubar() AlienGui::BeginMenu(" " ICON_FA_WINDOW_RESTORE " Windows ", _windowMenuOpened); AlienGui::MenuItem( AlienGui::MenuItemParameters() - .name("Temporal control") + .name(_("Temporal control")) .keyAlt(true) .key(ImGuiKey_1) .selected(TemporalControlWindow::get().isOn()) @@ -402,35 +402,35 @@ void MainLoopController::processMenubar() [&] { TemporalControlWindow::get().setOn(!TemporalControlWindow::get().isOn()); }); AlienGui::MenuItem( AlienGui::MenuItemParameters() - .name("Spatial control") + .name(_("Spatial control")) .keyAlt(true) .key(ImGuiKey_2) .selected(SpatialControlWindow::get().isOn()) .closeMenuWhenItemClicked(false), [&] { SpatialControlWindow::get().setOn(!SpatialControlWindow::get().isOn()); }); AlienGui::MenuItem( - AlienGui::MenuItemParameters().name("Statistics").keyAlt(true).key(ImGuiKey_3).selected(StatisticsWindow::get().isOn()).closeMenuWhenItemClicked(false), + AlienGui::MenuItemParameters().name(_("Statistics")).keyAlt(true).key(ImGuiKey_3).selected(StatisticsWindow::get().isOn()).closeMenuWhenItemClicked(false), [&] { StatisticsWindow::get().setOn(!StatisticsWindow::get().isOn()); }); AlienGui::MenuItem( AlienGui::MenuItemParameters() - .name("Simulation parameters") + .name(_("Simulation parameters")) .keyAlt(true) .key(ImGuiKey_4) .selected(SimulationParametersMainWindow::get().isOn()) .closeMenuWhenItemClicked(false), [&] { SimulationParametersMainWindow::get().setOn(!SimulationParametersMainWindow::get().isOn()); }); AlienGui::MenuItem( - AlienGui::MenuItemParameters().name("Autosave").keyAlt(true).key(ImGuiKey_5).selected(AutosaveWindow::get().isOn()).closeMenuWhenItemClicked(false), + AlienGui::MenuItemParameters().name(_("Autosave")).keyAlt(true).key(ImGuiKey_5).selected(AutosaveWindow::get().isOn()).closeMenuWhenItemClicked(false), [&] { AutosaveWindow::get().setOn(!AutosaveWindow::get().isOn()); }); AlienGui::MenuItem( - AlienGui::MenuItemParameters().name("Log").keyAlt(true).key(ImGuiKey_6).selected(LogWindow::get().isOn()).closeMenuWhenItemClicked(false), + AlienGui::MenuItemParameters().name(_("Log")).keyAlt(true).key(ImGuiKey_6).selected(LogWindow::get().isOn()).closeMenuWhenItemClicked(false), [&] { LogWindow::get().setOn(!LogWindow::get().isOn()); }); AlienGui::EndMenu(); AlienGui::BeginMenu(" " ICON_FA_PEN_ALT " Editor ", _editorMenuOpened); AlienGui::MenuItem( AlienGui::MenuItemParameters() - .name("Genome editor") + .name(_("Genome editor")) .keyAlt(true) .key(ImGuiKey_B) .selected(GenomeEditorWindow::get().isOn()) @@ -439,7 +439,7 @@ void MainLoopController::processMenubar() AlienGui::MenuSeparator(); AlienGui::MenuItem( AlienGui::MenuItemParameters() - .name("Allow object editing") + .name(_("Allow object editing")) .keyAlt(true) .key(ImGuiKey_E) .selected(SimulationInteractionController::get().isEditMode()) @@ -447,7 +447,7 @@ void MainLoopController::processMenubar() [&] { SimulationInteractionController::get().setEditMode(!SimulationInteractionController::get().isEditMode()); }); AlienGui::MenuItem( AlienGui::MenuItemParameters() - .name("Selection") + .name(_("Selection")) .keyAlt(true) .key(ImGuiKey_S) .selected(SelectionWindow::get().isOn()) @@ -456,7 +456,7 @@ void MainLoopController::processMenubar() [&] { SelectionWindow::get().setOn(!SelectionWindow::get().isOn()); }); AlienGui::MenuItem( AlienGui::MenuItemParameters() - .name("Creator") + .name(_("Creator")) .keyAlt(true) .key(ImGuiKey_G) .selected(CreatorWindow::get().isOn()) @@ -465,7 +465,7 @@ void MainLoopController::processMenubar() [&] { CreatorWindow::get().setOn(!CreatorWindow::get().isOn()); }); AlienGui::MenuItem( AlienGui::MenuItemParameters() - .name("Pattern editor") + .name(_("Pattern editor")) .keyAlt(true) .key(ImGuiKey_M) .selected(PatternEditorWindow::get().isOn()) @@ -474,7 +474,7 @@ void MainLoopController::processMenubar() [&] { PatternEditorWindow::get().setOn(!PatternEditorWindow::get().isOn()); }); AlienGui::MenuItem( AlienGui::MenuItemParameters() - .name("Multiplier") + .name(_("Multiplier")) .keyAlt(true) .key(ImGuiKey_A) .selected(MultiplierWindow::get().isOn()) @@ -484,49 +484,49 @@ void MainLoopController::processMenubar() AlienGui::MenuSeparator(); AlienGui::MenuItem( AlienGui::MenuItemParameters() - .name("Inspect objects") + .name(_("Inspect objects")) .keyAlt(true) .key(ImGuiKey_N) .disabled(!SimulationInteractionController::get().isEditMode() || !PatternEditorWindow::get().isObjectInspectionPossible()), [&] { EditorController::get().onInspectSelectedObjects(); }); AlienGui::MenuItem( AlienGui::MenuItemParameters() - .name("Inspect genomes") + .name(_("Inspect genomes")) .keyAlt(true) .key(ImGuiKey_F) .disabled(!SimulationInteractionController::get().isEditMode() || !PatternEditorWindow::get().isGenomeInspectionPossible()), [&] { EditorController::get().onInspectSelectedGenomes(); }); AlienGui::MenuItem( AlienGui::MenuItemParameters() - .name("Inspect creatures") + .name(_("Inspect creatures")) .keyAlt(true) .key(ImGuiKey_P) .disabled(!SimulationInteractionController::get().isEditMode() || !PatternEditorWindow::get().isCreatureInspectionPossible()), [&] { EditorController::get().onInspectSelectedCreatures(); }); AlienGui::MenuItem( AlienGui::MenuItemParameters() - .name("Close inspections") + .name(_("Close inspections")) .key(ImGuiKey_Escape) .disabled(!SimulationInteractionController::get().isEditMode() || !EditorController::get().areInspectionWindowsActive()), [&] { EditorController::get().onCloseAllInspectorWindows(); }); AlienGui::MenuSeparator(); AlienGui::MenuItem( AlienGui::MenuItemParameters() - .name("Copy") + .name(_("Copy")) .keyCtrl(true) .key(ImGuiKey_C) .disabled(!SimulationInteractionController::get().isEditMode() || !EditorController::get().isCopyingPossible()), [&] { EditorController::get().onCopy(); }); AlienGui::MenuItem( AlienGui::MenuItemParameters() - .name("Paste") + .name(_("Paste")) .keyCtrl(true) .key(ImGuiKey_V) .disabled(!SimulationInteractionController::get().isEditMode() || !EditorController::get().isPastingPossible()), [&] { EditorController::get().onPaste(); }); AlienGui::MenuItem( AlienGui::MenuItemParameters() - .name("Delete") + .name(_("Delete")) .key(ImGuiKey_Delete) .disabled(!SimulationInteractionController::get().isEditMode() || !EditorController::get().isCopyingPossible()), [&] { EditorController::get().onDelete(); }); @@ -535,7 +535,7 @@ void MainLoopController::processMenubar() AlienGui::BeginMenu(" " ICON_FA_EYE " View ", _viewMenuOpened); AlienGui::MenuItem( AlienGui::MenuItemParameters() - .name("Cell info overlay") + .name(_("Cell info overlay")) .keyAlt(true) .key(ImGuiKey_O) .selected(SimulationView::get().isOverlayActive()) @@ -543,18 +543,18 @@ void MainLoopController::processMenubar() [&] { SimulationView::get().setOverlayActive(!SimulationView::get().isOverlayActive()); }); AlienGui::MenuItem( AlienGui::MenuItemParameters() - .name("Message overlay") + .name(_("Message overlay")) .keyAlt(true) .key(ImGuiKey_X) .selected(OverlayController::get().isOn()) .closeMenuWhenItemClicked(false), [&] { OverlayController::get().setOn(!OverlayController::get().isOn()); }); AlienGui::MenuItem( - AlienGui::MenuItemParameters().name("Render UI").keyAlt(true).key(ImGuiKey_U).selected(UiController::get().isOn()).closeMenuWhenItemClicked(false), + AlienGui::MenuItemParameters().name(_("Render UI")).keyAlt(true).key(ImGuiKey_U).selected(UiController::get().isOn()).closeMenuWhenItemClicked(false), [&] { UiController::get().setOn(!UiController::get().isOn()); }); AlienGui::MenuItem( AlienGui::MenuItemParameters() - .name("Render simulation") + .name(_("Render simulation")) .keyAlt(true) .key(ImGuiKey_I) .selected(SimulationView::get().isRenderSimulation()) @@ -563,22 +563,22 @@ void MainLoopController::processMenubar() AlienGui::EndMenu(); AlienGui::BeginMenu(" " ICON_FA_TOOLS " Tools ", _toolsMenuOpened); - AlienGui::MenuItem(AlienGui::MenuItemParameters().name("Mass operations").keyAlt(true).key(ImGuiKey_H), [&] { MassOperationsDialog::get().open(); }); - AlienGui::MenuItem(AlienGui::MenuItemParameters().name("Image converter").keyAlt(true).key(ImGuiKey_C), [&] { ImageToPatternDialog::get().show(); }); + AlienGui::MenuItem(AlienGui::MenuItemParameters().name(_("Mass operations")).keyAlt(true).key(ImGuiKey_H), [&] { MassOperationsDialog::get().open(); }); + AlienGui::MenuItem(AlienGui::MenuItemParameters().name(_("Image converter")).keyAlt(true).key(ImGuiKey_C), [&] { ImageToPatternDialog::get().show(); }); AlienGui::EndMenu(); AlienGui::BeginMenu(" " ICON_FA_COG " Settings ", _settingsMenuOpened, false); AlienGui::MenuItem( - AlienGui::MenuItemParameters().name("Save on exit").selected(_saveOnExit).closeMenuWhenItemClicked(false), [&] { _saveOnExit = !_saveOnExit; }); - AlienGui::MenuItem(AlienGui::MenuItemParameters().name("CUDA settings"), [&] { GpuSettingsDialog::get().open(); }); - AlienGui::MenuItem(AlienGui::MenuItemParameters().name("Display settings").keyAlt(true).key(ImGuiKey_V), [&] { DisplaySettingsDialog::get().open(); }); - AlienGui::MenuItem(AlienGui::MenuItemParameters().name("Network settings").keyAlt(true).key(ImGuiKey_K), [&] { NetworkSettingsDialog::get().open(); }); + AlienGui::MenuItemParameters().name(_("Save on exit")).selected(_saveOnExit).closeMenuWhenItemClicked(false), [&] { _saveOnExit = !_saveOnExit; }); + AlienGui::MenuItem(AlienGui::MenuItemParameters().name(_("CUDA settings")), [&] { GpuSettingsDialog::get().open(); }); + AlienGui::MenuItem(AlienGui::MenuItemParameters().name(_("Display settings")).keyAlt(true).key(ImGuiKey_V), [&] { DisplaySettingsDialog::get().open(); }); + AlienGui::MenuItem(AlienGui::MenuItemParameters().name(_("Network settings")).keyAlt(true).key(ImGuiKey_K), [&] { NetworkSettingsDialog::get().open(); }); AlienGui::EndMenu(); AlienGui::BeginMenu(" " ICON_FA_LIFE_RING " Help ", _helpMenuOpened); - AlienGui::MenuItem(AlienGui::MenuItemParameters().name("About"), [&] { AboutDialog::get().open(); }); + AlienGui::MenuItem(AlienGui::MenuItemParameters().name(_("About")), [&] { AboutDialog::get().open(); }); AlienGui::MenuItem( - AlienGui::MenuItemParameters().name("Getting started").selected(GettingStartedWindow::get().isOn()).closeMenuWhenItemClicked(false), + AlienGui::MenuItemParameters().name(_("Getting started")).selected(GettingStartedWindow::get().isOn()).closeMenuWhenItemClicked(false), [&] { GettingStartedWindow::get().setOn(!GettingStartedWindow::get().isOn()); }); AlienGui::EndMenu(); AlienGui::EndMenuBar(); diff --git a/source/Gui/MassOperationsDialog.cpp b/source/Gui/MassOperationsDialog.cpp index 6caeff94f..fcb5cb6f0 100644 --- a/source/Gui/MassOperationsDialog.cpp +++ b/source/Gui/MassOperationsDialog.cpp @@ -109,7 +109,7 @@ void MassOperationsDialog::processIntern() AlienGui::Group(AlienGui::GroupParameters().text("Filter").highlighted(true)); ImGui::Checkbox("##restrictToSelection", &_restrictToSelectedCreatures); ImGui::SameLine(0, ImGui::GetStyle().FramePadding.x * 4); - AlienGui::Text("Restrict to selection"); + AlienGui::Text(_("Restrict to selection")); AlienGui::Group(AlienGui::GroupParameters().text("Operations").highlighted(true)); @@ -156,9 +156,9 @@ void MassOperationsDialog::processIntern() ImGui::SameLine(0, ImGui::GetStyle().FramePadding.x * 4); auto posX = ImGui::GetCursorPos().x; ImGui::BeginDisabled(!_randomizeEnergies); - AlienGui::InputFloat(AlienGui::InputFloatParameters().format("%.1f").name("Minimum energy").textWidth(RightColumnWidth), _minEnergy); + AlienGui::InputFloat(AlienGui::InputFloatParameters().format("%.1f").name(_("Minimum energy")).textWidth(RightColumnWidth), _minEnergy); ImGui::SetCursorPosX(posX); - AlienGui::InputFloat(AlienGui::InputFloatParameters().format("%.1f").name("Maximum energy").textWidth(RightColumnWidth), _maxEnergy); + AlienGui::InputFloat(AlienGui::InputFloatParameters().format("%.1f").name(_("Maximum energy")).textWidth(RightColumnWidth), _maxEnergy); ImGui::EndDisabled(); table.next(); @@ -168,9 +168,9 @@ void MassOperationsDialog::processIntern() ImGui::SameLine(0, ImGui::GetStyle().FramePadding.x * 4); posX = ImGui::GetCursorPos().x; ImGui::BeginDisabled(!_randomizeAges); - AlienGui::InputInt(AlienGui::InputIntParameters().name("Minimum age").textWidth(RightColumnWidth), _minAge); + AlienGui::InputInt(AlienGui::InputIntParameters().name(_("Minimum age")).textWidth(RightColumnWidth), _minAge); ImGui::SetCursorPosX(posX); - AlienGui::InputInt(AlienGui::InputIntParameters().name("Maximum age").textWidth(RightColumnWidth), _maxAge); + AlienGui::InputInt(AlienGui::InputIntParameters().name(_("Maximum age")).textWidth(RightColumnWidth), _maxAge); ImGui::EndDisabled(); table.next(); @@ -180,9 +180,9 @@ void MassOperationsDialog::processIntern() ImGui::SameLine(0, ImGui::GetStyle().FramePadding.x * 4); posX = ImGui::GetCursorPos().x; ImGui::BeginDisabled(!_randomizeCountdowns); - AlienGui::InputInt(AlienGui::InputIntParameters().name("Minimum value").textWidth(RightColumnWidth), _minCountdown); + AlienGui::InputInt(AlienGui::InputIntParameters().name(_("Minimum value")).textWidth(RightColumnWidth), _minCountdown); ImGui::SetCursorPosX(posX); - AlienGui::InputInt(AlienGui::InputIntParameters().name("Maximum value").textWidth(RightColumnWidth), _maxCountdown); + AlienGui::InputInt(AlienGui::InputIntParameters().name(_("Maximum value")).textWidth(RightColumnWidth), _maxCountdown); ImGui::EndDisabled(); table.next(); @@ -190,7 +190,7 @@ void MassOperationsDialog::processIntern() AlienGui::Group(AlienGui::GroupParameters().text("Randomize mutants")); ImGui::Checkbox("##lineageId", &_randomizeLineageId); ImGui::SameLine(0, ImGui::GetStyle().FramePadding.x * 4); - AlienGui::Text("Randomize lineage ids"); + AlienGui::Text(_("Randomize lineage ids")); table.next(); @@ -199,9 +199,9 @@ void MassOperationsDialog::processIntern() ImGui::SameLine(0, ImGui::GetStyle().FramePadding.x * 4); posX = ImGui::GetCursorPos().x; ImGui::BeginDisabled(!_randomizeGlow); - AlienGui::SliderFloat(AlienGui::SliderFloatParameters().format("%.2f").name("Minimum glow").min(0).max(1).textWidth(RightColumnWidth), &_minGlow); + AlienGui::SliderFloat(AlienGui::SliderFloatParameters().format("%.2f").name(_("Minimum glow")).min(0).max(1).textWidth(RightColumnWidth), &_minGlow); ImGui::SetCursorPosX(posX); - AlienGui::SliderFloat(AlienGui::SliderFloatParameters().format("%.2f").name("Maximum glow").min(0).max(1).textWidth(RightColumnWidth), &_maxGlow); + AlienGui::SliderFloat(AlienGui::SliderFloatParameters().format("%.2f").name(_("Maximum glow")).min(0).max(1).textWidth(RightColumnWidth), &_maxGlow); ImGui::EndDisabled(); table.next(); @@ -223,7 +223,7 @@ void MassOperationsDialog::processIntern() AlienGui::Separator(); ImGui::BeginDisabled(!isOkEnabled()); - if (AlienGui::Button("OK")) { + if (AlienGui::Button(_("OK"))) { onExecute(); close(); } @@ -231,7 +231,7 @@ void MassOperationsDialog::processIntern() ImGui::SameLine(); ImGui::SetItemDefaultFocus(); - if (AlienGui::Button("Cancel")) { + if (AlienGui::Button(_("Cancel"))) { close(); } @@ -240,7 +240,7 @@ void MassOperationsDialog::processIntern() } MassOperationsDialog::MassOperationsDialog() - : AlienDialog("Mass operations") + : AlienDialog(_("Mass operations")) {} void MassOperationsDialog::colorCheckbox(std::string id, uint32_t cellColor, bool& check) diff --git a/source/Gui/MultiplierWindow.cpp b/source/Gui/MultiplierWindow.cpp index 7118c2991..f4602b73d 100644 --- a/source/Gui/MultiplierWindow.cpp +++ b/source/Gui/MultiplierWindow.cpp @@ -90,7 +90,7 @@ void MultiplierWindow::shutdownIntern() } MultiplierWindow::MultiplierWindow() - : AlienWindow("Multiplier", "editors.multiplier", false) + : AlienWindow(_("Multiplier"), "editors.multiplier", false) {} void MultiplierWindow::processIntern() @@ -119,7 +119,7 @@ void MultiplierWindow::processIntern() ImGui::BeginDisabled( EditorModel::get().isSelectionEmpty() || (_selectionDataAfterMultiplication && _selectionDataAfterMultiplication->compareSizes(EditorModel::get().getSelectionShallowData()))); - if (AlienGui::Button("Build")) { + if (AlienGui::Button(_("Build"))) { onBuild(); } ImGui::EndDisabled(); @@ -128,7 +128,7 @@ void MultiplierWindow::processIntern() ImGui::BeginDisabled( EditorModel::get().isSelectionEmpty() || !_selectionDataAfterMultiplication || !_selectionDataAfterMultiplication->compareSizes(EditorModel::get().getSelectionShallowData())); - if (AlienGui::Button("Undo")) { + if (AlienGui::Button(_("Undo"))) { onUndo(); } ImGui::EndDisabled(); @@ -180,22 +180,22 @@ void MultiplierWindow::processGridPanel() void MultiplierWindow::processRandomPanel() { - AlienGui::InputInt(AlienGui::InputIntParameters().name("Number of copies").textWidth(RightColumnWidth), _randomParameters._number); - AlienGui::InputFloat(AlienGui::InputFloatParameters().name("Min angle").textWidth(RightColumnWidth).format("%.1f"), _randomParameters._minAngle); - AlienGui::InputFloat(AlienGui::InputFloatParameters().name("Max angle").textWidth(RightColumnWidth).format("%.1f"), _randomParameters._maxAngle); + AlienGui::InputInt(AlienGui::InputIntParameters().name(_("Number of copies")).textWidth(RightColumnWidth), _randomParameters._number); + AlienGui::InputFloat(AlienGui::InputFloatParameters().name(_("Min angle")).textWidth(RightColumnWidth).format("%.1f"), _randomParameters._minAngle); + AlienGui::InputFloat(AlienGui::InputFloatParameters().name(_("Max angle")).textWidth(RightColumnWidth).format("%.1f"), _randomParameters._maxAngle); AlienGui::InputFloat( - AlienGui::InputFloatParameters().name("Min velocity X").textWidth(RightColumnWidth).format("%.2f").step(0.05f), _randomParameters._minVelX); + AlienGui::InputFloatParameters().name(_("Min velocity X")).textWidth(RightColumnWidth).format("%.2f").step(0.05f), _randomParameters._minVelX); AlienGui::InputFloat( - AlienGui::InputFloatParameters().name("Max velocity X").textWidth(RightColumnWidth).format("%.2f").step(0.05f), _randomParameters._maxVelX); + AlienGui::InputFloatParameters().name(_("Max velocity X")).textWidth(RightColumnWidth).format("%.2f").step(0.05f), _randomParameters._maxVelX); AlienGui::InputFloat( - AlienGui::InputFloatParameters().name("Min velocity Y").textWidth(RightColumnWidth).format("%.2f").step(0.05f), _randomParameters._minVelY); + AlienGui::InputFloatParameters().name(_("Min velocity Y")).textWidth(RightColumnWidth).format("%.2f").step(0.05f), _randomParameters._minVelY); AlienGui::InputFloat( - AlienGui::InputFloatParameters().name("Max velocity Y").textWidth(RightColumnWidth).format("%.2f").step(0.05f), _randomParameters._maxVelY); + AlienGui::InputFloatParameters().name(_("Max velocity Y")).textWidth(RightColumnWidth).format("%.2f").step(0.05f), _randomParameters._maxVelY); AlienGui::InputFloat( - AlienGui::InputFloatParameters().name("Min angular velocity").textWidth(RightColumnWidth).format("%.1f").step(0.1f), _randomParameters._minAngularVel); + AlienGui::InputFloatParameters().name(_("Min angular velocity")).textWidth(RightColumnWidth).format("%.1f").step(0.1f), _randomParameters._minAngularVel); AlienGui::InputFloat( - AlienGui::InputFloatParameters().name("Max angular velocity").textWidth(RightColumnWidth).format("%.1f").step(0.1f), _randomParameters._maxAngularVel); - AlienGui::Checkbox(AlienGui::CheckboxParameters().name("Overlapping check").textWidth(RightColumnWidth), _randomParameters._overlappingCheck); + AlienGui::InputFloatParameters().name(_("Max angular velocity")).textWidth(RightColumnWidth).format("%.1f").step(0.1f), _randomParameters._maxAngularVel); + AlienGui::Checkbox(AlienGui::CheckboxParameters().name(_("Overlapping check")).textWidth(RightColumnWidth), _randomParameters._overlappingCheck); } void MultiplierWindow::validateAndCorrect() diff --git a/source/Gui/NetworkSettingsDialog.cpp b/source/Gui/NetworkSettingsDialog.cpp index 751acf630..b2cb0116e 100644 --- a/source/Gui/NetworkSettingsDialog.cpp +++ b/source/Gui/NetworkSettingsDialog.cpp @@ -14,25 +14,25 @@ namespace } NetworkSettingsDialog::NetworkSettingsDialog() - : AlienDialog("Network settings") + : AlienDialog(_("Network settings")) {} void NetworkSettingsDialog::processIntern() { AlienGui::InputText( - AlienGui::InputTextParameters().name("Blocks").defaultValue(_origServerAddress).name("Server address").textWidth(RightColumnWidth), _serverAddress); + AlienGui::InputTextParameters().name(_("Blocks")).defaultValue(_origServerAddress).name(_("Server address")).textWidth(RightColumnWidth), _serverAddress); ImGui::Dummy({0, ImGui::GetContentRegionAvail().y - scale(50.0f)}); AlienGui::Separator(); - if (AlienGui::Button("Adopt")) { + if (AlienGui::Button(_("Adopt"))) { close(); onChangeSettings(); } ImGui::SetItemDefaultFocus(); ImGui::SameLine(); - if (AlienGui::Button("Cancel")) { + if (AlienGui::Button(_("Cancel"))) { close(); } } diff --git a/source/Gui/NetworkTransferController.cpp b/source/Gui/NetworkTransferController.cpp index 5e869bbad..4267a08cc 100644 --- a/source/Gui/NetworkTransferController.cpp +++ b/source/Gui/NetworkTransferController.cpp @@ -29,7 +29,7 @@ void NetworkTransferController::init() void NetworkTransferController::onDownload(DownloadNetworkResourceRequestData const& requestData) { - printOverlayMessage("Downloading ..."); + printOverlayMessage(_("Downloading ...")); _downloadProcessor->executeTask( [&](auto const& senderId) { @@ -93,7 +93,7 @@ void NetworkTransferController::onDownload(DownloadNetworkResourceRequestData co void NetworkTransferController::onUpload(UploadNetworkResourceRequestData const& requestData) { - printOverlayMessage("Uploading ..."); + printOverlayMessage(_("Uploading ...")); _uploadProcessor->executeTask( [&](auto const& senderId) { @@ -109,7 +109,7 @@ void NetworkTransferController::onUpload(UploadNetworkResourceRequestData const& void NetworkTransferController::onReplace(ReplaceNetworkResourceRequestData const& requestData) { - printOverlayMessage("Replacing ..."); + printOverlayMessage(_("Replacing ...")); _replaceProcessor->executeTask( [&](auto const& senderId) { @@ -125,7 +125,7 @@ void NetworkTransferController::onReplace(ReplaceNetworkResourceRequestData cons void NetworkTransferController::onDelete(DeleteNetworkResourceRequestData const& requestData) { - printOverlayMessage("Deleting ..."); + printOverlayMessage(_("Deleting ...")); _deleteProcessor->executeTask( [&](auto const& senderId) { @@ -141,7 +141,7 @@ void NetworkTransferController::onDelete(DeleteNetworkResourceRequestData const& void NetworkTransferController::onEdit(EditNetworkResourceRequestData const& requestData) { - printOverlayMessage("Applying changes ..."); + printOverlayMessage(_("Applying changes ...")); _editProcessor->executeTask( [&](auto const& senderId) { @@ -156,7 +156,7 @@ void NetworkTransferController::onEdit(EditNetworkResourceRequestData const& req void NetworkTransferController::onMove(MoveNetworkResourceRequestData const& requestData) { - printOverlayMessage("Changing visibility ..."); + printOverlayMessage(_("Changing visibility ...")); _moveProcessor->executeTask( [&](auto const& senderId) { diff --git a/source/Gui/NewPasswordDialog.cpp b/source/Gui/NewPasswordDialog.cpp index be900842e..37a577a96 100644 --- a/source/Gui/NewPasswordDialog.cpp +++ b/source/Gui/NewPasswordDialog.cpp @@ -25,27 +25,27 @@ void NewPasswordDialog::open(std::string const& userName, UserInfo const& userIn } NewPasswordDialog::NewPasswordDialog() - : AlienDialog("New password") + : AlienDialog(_("New password")) {} void NewPasswordDialog::processIntern() { - AlienGui::Text("Security information"); + AlienGui::Text(_("Security information")); AlienGui::HelpMarker( "The data transfer to the server is encrypted via https. On the server side, the password is not stored in cleartext, but as a salted SHA-256 hash " "value in the database."); AlienGui::Separator(); - AlienGui::Text("Please enter a new password and the confirmation code\nsent to your email address."); + AlienGui::Text(_("Please enter a new password and the confirmation code\nsent to your email address.")); AlienGui::Separator(); - AlienGui::InputText(AlienGui::InputTextParameters().hint("New password").password(true).textWidth(0), _newPassword); - AlienGui::InputText(AlienGui::InputTextParameters().hint("Code (case sensitive)").textWidth(0), _confirmationCode); + AlienGui::InputText(AlienGui::InputTextParameters().hint(_("New password")).password(true).textWidth(0), _newPassword); + AlienGui::InputText(AlienGui::InputTextParameters().hint(_("Code (case sensitive)")).textWidth(0), _confirmationCode); AlienGui::Separator(); ImGui::BeginDisabled(_confirmationCode.empty()); - if (AlienGui::Button("OK")) { + if (AlienGui::Button(_("OK"))) { close(); onNewPassword(); } @@ -53,7 +53,7 @@ void NewPasswordDialog::processIntern() ImGui::SetItemDefaultFocus(); ImGui::SameLine(); - if (AlienGui::Button("Cancel")) { + if (AlienGui::Button(_("Cancel"))) { close(); } } diff --git a/source/Gui/NewSimulationDialog.cpp b/source/Gui/NewSimulationDialog.cpp index 11ce774da..9b3e169fd 100644 --- a/source/Gui/NewSimulationDialog.cpp +++ b/source/Gui/NewSimulationDialog.cpp @@ -30,19 +30,19 @@ void NewSimulationDialog::shutdownIntern() } NewSimulationDialog::NewSimulationDialog() - : AlienDialog("New simulation") + : AlienDialog(_("New simulation")) {} void NewSimulationDialog::processIntern() { - AlienGui::InputText(AlienGui::InputTextParameters().name("Project name").textWidth(ContentTextInputWidth), _projectName, ProjectNameSize); - AlienGui::InputInt(AlienGui::InputIntParameters().name("Width").textWidth(ContentTextInputWidth), _width); - AlienGui::InputInt(AlienGui::InputIntParameters().name("Height").textWidth(ContentTextInputWidth), _height); - AlienGui::Checkbox(AlienGui::CheckboxParameters().name("Adopt parameters").textWidth(ContentTextInputWidth), _adoptSimulationParameters); + AlienGui::InputText(AlienGui::InputTextParameters().name(_("Project name")).textWidth(ContentTextInputWidth), _projectName, ProjectNameSize); + AlienGui::InputInt(AlienGui::InputIntParameters().name(_("Width")).textWidth(ContentTextInputWidth), _width); + AlienGui::InputInt(AlienGui::InputIntParameters().name(_("Height")).textWidth(ContentTextInputWidth), _height); + AlienGui::Checkbox(AlienGui::CheckboxParameters().name(_("Adopt parameters")).textWidth(ContentTextInputWidth), _adoptSimulationParameters); ImGui::Dummy({0, ImGui::GetContentRegionAvail().y - scale(50.0f)}); AlienGui::Separator(); - if (AlienGui::Button("OK")) { + if (AlienGui::Button(_("OK"))) { ImGui::CloseCurrentPopup(); onNewSimulation(); close(); @@ -50,7 +50,7 @@ void NewSimulationDialog::processIntern() ImGui::SetItemDefaultFocus(); ImGui::SameLine(); - if (AlienGui::Button("Cancel")) { + if (AlienGui::Button(_("Cancel"))) { ImGui::CloseCurrentPopup(); close(); } diff --git a/source/Gui/PatternEditorWindow.cpp b/source/Gui/PatternEditorWindow.cpp index 16b968de9..452dcaef8 100644 --- a/source/Gui/PatternEditorWindow.cpp +++ b/source/Gui/PatternEditorWindow.cpp @@ -53,7 +53,7 @@ void PatternEditorWindow::processIntern() if (AlienGui::ToolbarButton(AlienGui::ToolbarButtonParameters().text(ICON_FA_FOLDER_OPEN))) { onOpenPattern(); } - AlienGui::Tooltip("Open pattern"); + AlienGui::Tooltip(_("Open pattern")); //save button ImGui::BeginDisabled(EditorModel::get().isSelectionEmpty()); @@ -62,7 +62,7 @@ void PatternEditorWindow::processIntern() onSavePattern(); } ImGui::EndDisabled(); - AlienGui::Tooltip("Save pattern"); + AlienGui::Tooltip(_("Save pattern")); ImGui::SameLine(); AlienGui::ToolbarSeparator(); @@ -74,7 +74,7 @@ void PatternEditorWindow::processIntern() onCopy(); } ImGui::EndDisabled(); - AlienGui::Tooltip("Copy pattern"); + AlienGui::Tooltip(_("Copy pattern")); //paste button ImGui::SameLine(); @@ -83,7 +83,7 @@ void PatternEditorWindow::processIntern() onPaste(); } ImGui::EndDisabled(); - AlienGui::Tooltip("Paste pattern"); + AlienGui::Tooltip(_("Paste pattern")); //delete button ImGui::SameLine(); @@ -92,7 +92,7 @@ void PatternEditorWindow::processIntern() onDelete(); } ImGui::EndDisabled(); - AlienGui::Tooltip("Delete Pattern"); + AlienGui::Tooltip(_("Delete Pattern")); ImGui::SameLine(); AlienGui::ToolbarSeparator(); @@ -104,7 +104,7 @@ void PatternEditorWindow::processIntern() EditorController::get().onInspectSelectedObjects(); } ImGui::EndDisabled(); - AlienGui::Tooltip("Inspect Objects"); + AlienGui::Tooltip(_("Inspect Objects")); //inspect genomes button ImGui::SameLine(); @@ -113,7 +113,7 @@ void PatternEditorWindow::processIntern() EditorController::get().onInspectSelectedGenomes(); } ImGui::EndDisabled(); - AlienGui::Tooltip("Inspect genomes"); + AlienGui::Tooltip(_("Inspect genomes")); //inspect creatures button ImGui::SameLine(); @@ -122,7 +122,7 @@ void PatternEditorWindow::processIntern() EditorController::get().onInspectSelectedCreatures(); } ImGui::EndDisabled(); - AlienGui::Tooltip("Inspect creatures"); + AlienGui::Tooltip(_("Inspect creatures")); if (ImGui::BeginChild("##", ImVec2(0, ImGui::GetContentRegionAvail().y - scale(50.0f)), false, ImGuiWindowFlags_HorizontalScrollbar)) { @@ -133,25 +133,25 @@ void PatternEditorWindow::processIntern() auto centerPosX = EditorModel::get().isRolloutToClusters() ? selectionData.clusterCenterPosX : selectionData.centerPosX; auto origCenterPosX = centerPosX; - AlienGui::InputFloat(AlienGui::InputFloatParameters().name("Position X").textWidth(RightColumnWidth).format("%.3f"), centerPosX); + AlienGui::InputFloat(AlienGui::InputFloatParameters().name(_("Position X")).textWidth(RightColumnWidth).format("%.3f"), centerPosX); auto centerPosY = EditorModel::get().isRolloutToClusters() ? selectionData.clusterCenterPosY : selectionData.centerPosY; auto origCenterPosY = centerPosY; - AlienGui::InputFloat(AlienGui::InputFloatParameters().name("Position Y").textWidth(RightColumnWidth).format("%.3f"), centerPosY); + AlienGui::InputFloat(AlienGui::InputFloatParameters().name(_("Position Y")).textWidth(RightColumnWidth).format("%.3f"), centerPosY); auto centerVelX = EditorModel::get().isRolloutToClusters() ? selectionData.clusterCenterVelX : selectionData.centerVelX; auto origCenterVelX = centerVelX; - AlienGui::InputFloat(AlienGui::InputFloatParameters().name("Velocity X").textWidth(RightColumnWidth).step(0.1f).format("%.3f"), centerVelX); + AlienGui::InputFloat(AlienGui::InputFloatParameters().name(_("Velocity X")).textWidth(RightColumnWidth).step(0.1f).format("%.3f"), centerVelX); auto centerVelY = EditorModel::get().isRolloutToClusters() ? selectionData.clusterCenterVelY : selectionData.centerVelY; auto origCenterVelY = centerVelY; - AlienGui::InputFloat(AlienGui::InputFloatParameters().name("Velocity Y").textWidth(RightColumnWidth).step(0.1f).format("%.3f"), centerVelY); + AlienGui::InputFloat(AlienGui::InputFloatParameters().name(_("Velocity Y")).textWidth(RightColumnWidth).step(0.1f).format("%.3f"), centerVelY); AlienGui::Group(AlienGui::GroupParameters().text("Center rotation")); auto origAngle = _angle; AlienGui::SliderInputFloat( AlienGui::SliderInputFloatParameters() - .name("Angle") + .name(_("Angle")) .textWidth(RightColumnWidth) .inputWidth(StyleRepository::get().scale(50.0f)) .min(-180.0f) @@ -160,7 +160,7 @@ void PatternEditorWindow::processIntern() _angle); auto origAngularVel = _angularVel; - AlienGui::InputFloat(AlienGui::InputFloatParameters().name("Angular velocity").textWidth(RightColumnWidth).step(0.01f).format("%.2f"), _angularVel); + AlienGui::InputFloat(AlienGui::InputFloatParameters().name(_("Angular velocity")).textWidth(RightColumnWidth).step(0.01f).format("%.2f"), _angularVel); if (centerPosX != origCenterPosX || centerPosY != origCenterPosY) { ShallowUpdateSelectionData updateData; @@ -215,38 +215,38 @@ void PatternEditorWindow::processIntern() _SimulationFacade::get()->uniformVelocitiesForSelectedObjects(EditorModel::get().isRolloutToClusters()); } ImGui::EndDisabled(); - AlienGui::Tooltip("Make uniform velocities"); + AlienGui::Tooltip(_("Make uniform velocities")); ImGui::SameLine(); ImGui::BeginDisabled(EditorModel::get().isCellSelectionEmpty()); if (ImGui::Button(ICON_FA_BALANCE_SCALE)) { _SimulationFacade::get()->relaxSelectedObjects(EditorModel::get().isRolloutToClusters()); } - AlienGui::Tooltip("Release stresses"); + AlienGui::Tooltip(_("Release stresses")); ImGui::SameLine(); if (ImGui::Button(ICON_FA_TINT)) { onMakeSticky(); } - AlienGui::Tooltip("Make sticky"); + AlienGui::Tooltip(_("Make sticky")); ImGui::SameLine(); if (ImGui::Button(ICON_FA_TINT_SLASH)) { onRemoveStickiness(); } - AlienGui::Tooltip("Make unsticky"); + AlienGui::Tooltip(_("Make unsticky")); ImGui::SameLine(); if (ImGui::Button(ICON_FA_LINK)) { onSetBarrier(true); } - AlienGui::Tooltip("Fix"); + AlienGui::Tooltip(_("Fix")); ImGui::SameLine(); if (ImGui::Button(ICON_FA_UNLINK)) { onSetBarrier(false); } - AlienGui::Tooltip("Unfix"); + AlienGui::Tooltip(_("Unfix")); ImGui::EndDisabled(); _lastSelection = selection; @@ -255,7 +255,7 @@ void PatternEditorWindow::processIntern() AlienGui::Separator(); auto rolloutToClusters = EditorModel::get().isRolloutToClusters(); - if (AlienGui::ToggleButton(AlienGui::ToggleButtonParameters().name("Roll out changes to cell networks"), rolloutToClusters)) { + if (AlienGui::ToggleButton(AlienGui::ToggleButtonParameters().name(_("Roll out changes to cell networks")), rolloutToClusters)) { EditorModel::get().setRolloutToClusters(rolloutToClusters); _angle = 0; _angularVel = 0; @@ -355,7 +355,7 @@ void PatternEditorWindow::onDelete() } PatternEditorWindow::PatternEditorWindow() - : AlienWindow("Pattern editor", "editors.pattern editor", true) + : AlienWindow(_("Pattern editor"), "editors.pattern editor", true) {} void PatternEditorWindow::shutdownIntern() diff --git a/source/Gui/PreviewSettingsDialog.cpp b/source/Gui/PreviewSettingsDialog.cpp index f5f4d4db8..6023c05e4 100644 --- a/source/Gui/PreviewSettingsDialog.cpp +++ b/source/Gui/PreviewSettingsDialog.cpp @@ -6,7 +6,7 @@ #include "GenomeWindowEditData.h" PreviewSettingsDialog::PreviewSettingsDialog() - : AlienDialog("Preview settings") + : AlienDialog(_("Preview settings")) {} void PreviewSettingsDialog::setEditData(GenomeWindowEditData const& editData) @@ -19,7 +19,7 @@ void PreviewSettingsDialog::processIntern() // Convert boolean to switcher index: 0 = Node index, 1 = Cell type int displayMode = _showNodeIndex ? 0 : 1; - AlienGui::Switcher(AlienGui::SwitcherParameters().name("Display mode").textWidth(scale(120.0f)).values({"Node index", "Cell type"}), &displayMode); + AlienGui::Switcher(AlienGui::SwitcherParameters().name(_("Display mode")).textWidth(scale(120.0f)).values({_("Node index"), _("Cell type")}), &displayMode); // Convert switcher index back to boolean _showNodeIndex = (displayMode == 0); @@ -27,14 +27,14 @@ void PreviewSettingsDialog::processIntern() ImGui::Dummy({0, ImGui::GetContentRegionAvail().y - scale(50.0f)}); AlienGui::Separator(); - if (AlienGui::Button("Adopt")) { + if (AlienGui::Button(_("Adopt"))) { close(); _editData->showNodeIndex = _showNodeIndex; } ImGui::SetItemDefaultFocus(); ImGui::SameLine(); - if (AlienGui::Button("Cancel")) { + if (AlienGui::Button(_("Cancel"))) { close(); } } diff --git a/source/Gui/ResetPasswordDialog.cpp b/source/Gui/ResetPasswordDialog.cpp index 25fd66fa2..8367db8d6 100644 --- a/source/Gui/ResetPasswordDialog.cpp +++ b/source/Gui/ResetPasswordDialog.cpp @@ -7,7 +7,7 @@ #include "NewPasswordDialog.h" ResetPasswordDialog::ResetPasswordDialog() - : AlienDialog("Reset password") + : AlienDialog(_("Reset password")) {} void ResetPasswordDialog::open(std::string const& userName, UserInfo const& userInfo) @@ -20,22 +20,22 @@ void ResetPasswordDialog::open(std::string const& userName, UserInfo const& user void ResetPasswordDialog::processIntern() { - AlienGui::Text("Security information"); + AlienGui::Text(_("Security information")); AlienGui::HelpMarker("The data transfer to the server is encrypted via https. On the server side, the email address is not stored in cleartext, but " "as a SHA-256 hash value in the database."); - AlienGui::Text("Data privacy policy"); + AlienGui::Text(_("Data privacy policy")); AlienGui::HelpMarker( "The entered e-mail address will not be passed on to third parties and is used only for the following two reasons: 1) To send the confirmation code. " "2) A SHA-256 hash value of the email address is stored on the server to verify that it is not yet in use."); AlienGui::Separator(); - AlienGui::Text("Please enter your email address to receive the\nconfirmation code to reset the password."); + AlienGui::Text(_("Please enter your email address to receive the\nconfirmation code to reset the password.")); AlienGui::Separator(); - AlienGui::InputText(AlienGui::InputTextParameters().hint("Email").textWidth(0), _email); + AlienGui::InputText(AlienGui::InputTextParameters().hint(_("Email")).textWidth(0), _email); AlienGui::Separator(); ImGui::BeginDisabled(_email.empty()); - if (AlienGui::Button("OK")) { + if (AlienGui::Button(_("OK"))) { close(); onResetPassword(); @@ -44,7 +44,7 @@ void ResetPasswordDialog::processIntern() ImGui::SetItemDefaultFocus(); ImGui::SameLine(); - if (AlienGui::Button("Cancel")) { + if (AlienGui::Button(_("Cancel"))) { close(); } } diff --git a/source/Gui/ResizeWorldDialog.cpp b/source/Gui/ResizeWorldDialog.cpp index ea5b27f89..99728c5e5 100644 --- a/source/Gui/ResizeWorldDialog.cpp +++ b/source/Gui/ResizeWorldDialog.cpp @@ -25,7 +25,7 @@ void ResizeWorldDialog::open() } ResizeWorldDialog::ResizeWorldDialog() - : AlienDialog("Resize world") + : AlienDialog(_("Resize world")) {} void ResizeWorldDialog::processIntern() @@ -41,7 +41,7 @@ void ResizeWorldDialog::processIntern() ImGui::PopItemWidth(); ImGui::TableSetColumnIndex(1); - ImGui::Text("Width"); + ImGui::Text("%s", _("Width")); //height ImGui::TableNextRow(); @@ -51,22 +51,22 @@ void ResizeWorldDialog::processIntern() ImGui::PopItemWidth(); ImGui::TableSetColumnIndex(1); - ImGui::Text("Height"); + ImGui::Text("%s", _("Height")); ImGui::EndTable(); } - AlienGui::ToggleButton(AlienGui::ToggleButtonParameters().name("Scale content"), _scaleContent); + AlienGui::ToggleButton(AlienGui::ToggleButtonParameters().name(_("Scale content")), _scaleContent); AlienGui::Separator(); - if (AlienGui::Button("OK")) { + if (AlienGui::Button(_("OK"))) { onResizing(); close(); } ImGui::SetItemDefaultFocus(); ImGui::SameLine(); - if (AlienGui::Button("Cancel")) { + if (AlienGui::Button(_("Cancel"))) { close(); } diff --git a/source/Gui/SelectionWindow.cpp b/source/Gui/SelectionWindow.cpp index 769456762..0cd887142 100644 --- a/source/Gui/SelectionWindow.cpp +++ b/source/Gui/SelectionWindow.cpp @@ -15,7 +15,7 @@ namespace } SelectionWindow::SelectionWindow() - : AlienWindow("Selection", "windows.selection", true, false, {scale(100), scale(100.0f)}) + : AlienWindow(_("Selection"), "windows.selection", true, false, {scale(100), scale(100.0f)}) {} void SelectionWindow::processIntern() @@ -24,7 +24,7 @@ void SelectionWindow::processIntern() if (table.begin()) { auto selection = EditorModel::get().getSelectionShallowData(); - ImGui::Text("Cells"); + ImGui::Text("%s", _("Cells")); ImGui::PushFont(StyleRepository::get().getLargeFont()); ImGui::PushStyleColor(ImGuiCol_Text, Const::TextDecentColor.Value); ImGui::TextUnformatted(StringHelper::format(selection.numObjects).c_str()); @@ -32,7 +32,7 @@ void SelectionWindow::processIntern() ImGui::PopFont(); table.next(); - ImGui::Text("Connected cells"); + ImGui::Text("%s", _("Connected cells")); ImGui::PushFont(StyleRepository::get().getLargeFont()); ImGui::PushStyleColor(ImGuiCol_Text, Const::TextDecentColor.Value); ImGui::TextUnformatted(StringHelper::format(selection.numClusterCells).c_str()); @@ -40,7 +40,7 @@ void SelectionWindow::processIntern() ImGui::PopFont(); table.next(); - ImGui::Text("Creatures"); + ImGui::Text("%s", _("Creatures")); ImGui::PushFont(StyleRepository::get().getLargeFont()); ImGui::PushStyleColor(ImGuiCol_Text, Const::TextDecentColor.Value); ImGui::TextUnformatted(StringHelper::format(selection.numCreatures).c_str()); @@ -48,7 +48,7 @@ void SelectionWindow::processIntern() ImGui::PopFont(); table.next(); - ImGui::Text("Energy particles"); + ImGui::Text("%s", _("Energy particles")); ImGui::PushFont(StyleRepository::get().getLargeFont()); ImGui::PushStyleColor(ImGuiCol_Text, Const::TextDecentColor.Value); ImGui::TextUnformatted(StringHelper::format(selection.numEnergyParticles).c_str()); diff --git a/source/Gui/SignalsBufferDialog.cpp b/source/Gui/SignalsBufferDialog.cpp index aa633dd87..c29703baa 100644 --- a/source/Gui/SignalsBufferDialog.cpp +++ b/source/Gui/SignalsBufferDialog.cpp @@ -56,7 +56,7 @@ void SignalsBufferDialog::processIntern() auto buttonAreaHeight = scale(50.0f); if (ImGui::BeginChild("SignalsBufferContent", ImVec2(0, -buttonAreaHeight), false)) { int numEntries = static_cast(_channelsBuffer.size()); - if (AlienGui::InputInt(AlienGui::InputIntParameters().name("Number of signals").textWidth(DialogTextWidth), numEntries)) { + if (AlienGui::InputInt(AlienGui::InputIntParameters().name(_("Number of signals")).textWidth(DialogTextWidth), numEntries)) { numEntries = std::clamp(numEntries, 0, MAX_CELL_MEMORY_ENTRIES); _channelsBuffer.resize(numEntries, std::vector(NEURONS_PER_CELL, 0.0f)); } @@ -67,7 +67,7 @@ void SignalsBufferDialog::processIntern() } _selectedEntry = std::clamp(_selectedEntry, 0, numEntries - 1); - AlienGui::Switcher(AlienGui::SwitcherParameters().name("Edit signal").values(entryTexts).textWidth(DialogTextWidth), &_selectedEntry); + AlienGui::Switcher(AlienGui::SwitcherParameters().name(_("Edit signal")).values(entryTexts).textWidth(DialogTextWidth), &_selectedEntry); _selectedEntry = std::clamp(_selectedEntry, 0, numEntries - 1); auto& channels = _channelsBuffer.at(_selectedEntry); @@ -85,7 +85,7 @@ void SignalsBufferDialog::processIntern() AlienGui::Separator(); - if (AlienGui::Button("Adopt")) { + if (AlienGui::Button(_("Adopt"))) { ImGui::CloseCurrentPopup(); onAdopt(); close(); @@ -93,7 +93,7 @@ void SignalsBufferDialog::processIntern() ImGui::SetItemDefaultFocus(); ImGui::SameLine(); - if (AlienGui::Button("Cancel")) { + if (AlienGui::Button(_("Cancel"))) { ImGui::CloseCurrentPopup(); close(); } diff --git a/source/Gui/SimulationParametersMainWindow.cpp b/source/Gui/SimulationParametersMainWindow.cpp index 288ab7b6a..30434a4f7 100644 --- a/source/Gui/SimulationParametersMainWindow.cpp +++ b/source/Gui/SimulationParametersMainWindow.cpp @@ -36,7 +36,7 @@ namespace } SimulationParametersMainWindow::SimulationParametersMainWindow() - : AlienWindow("Simulation parameters", "windows.simulation parameters", false, true) + : AlienWindow(_("Simulation parameters"), "windows.simulation parameters", false, true) {} void SimulationParametersMainWindow::initIntern() @@ -101,12 +101,12 @@ void SimulationParametersMainWindow::shutdownIntern() void SimulationParametersMainWindow::processToolbar() { - if (AlienGui::ToolbarButton(AlienGui::ToolbarButtonParameters().text(ICON_FA_FOLDER_OPEN).tooltip("Open simulation parameters from file"))) { + if (AlienGui::ToolbarButton(AlienGui::ToolbarButtonParameters().text(ICON_FA_FOLDER_OPEN).tooltip(_("Open simulation parameters from file")))) { onOpenParameters(); } ImGui::SameLine(); - if (AlienGui::ToolbarButton(AlienGui::ToolbarButtonParameters().text(ICON_FA_SAVE).tooltip("Save simulation parameters to file"))) { + if (AlienGui::ToolbarButton(AlienGui::ToolbarButtonParameters().text(ICON_FA_SAVE).tooltip(_("Save simulation parameters to file")))) { onSaveParameters(); } @@ -114,17 +114,17 @@ void SimulationParametersMainWindow::processToolbar() AlienGui::ToolbarSeparator(); ImGui::SameLine(); - if (AlienGui::ToolbarButton(AlienGui::ToolbarButtonParameters().text(ICON_FA_COPY).tooltip("Copy simulation parameters to clipboard"))) { + if (AlienGui::ToolbarButton(AlienGui::ToolbarButtonParameters().text(ICON_FA_COPY).tooltip(_("Copy simulation parameters to clipboard")))) { _copiedParameters = _SimulationFacade::get()->getSimulationParameters(); - printOverlayMessage("Simulation parameters copied"); + printOverlayMessage(_("Simulation parameters copied")); } ImGui::SameLine(); if (AlienGui::ToolbarButton( - AlienGui::ToolbarButtonParameters().text(ICON_FA_PASTE).tooltip("Paste simulation parameters from clipboard").disabled(!_copiedParameters))) { + AlienGui::ToolbarButtonParameters().text(ICON_FA_PASTE).tooltip(_("Paste simulation parameters from clipboard")).disabled(!_copiedParameters))) { _SimulationFacade::get()->setSimulationParameters(*_copiedParameters); _SimulationFacade::get()->setOriginalSimulationParameters(*_copiedParameters); - printOverlayMessage("Simulation parameters pasted"); + printOverlayMessage(_("Simulation parameters pasted")); } ImGui::SameLine(); @@ -139,7 +139,7 @@ void SimulationParametersMainWindow::processToolbar() auto parameters = _SimulationFacade::get()->getSimulationParameters(); if (_copiedParameters->numLayers == parameters.numLayers && _copiedParameters->numSources == parameters.numSources) { _SimulationFacade::get()->setOriginalSimulationParameters(*_copiedParameters); - printOverlayMessage("Reference simulation parameters replaced"); + printOverlayMessage(_("Reference simulation parameters replaced")); } else { GenericMessageDialog::get().information( "Error", "The number of layers and radiation sources of the current simulation parameters must match with those from the clipboard."); @@ -150,12 +150,12 @@ void SimulationParametersMainWindow::processToolbar() AlienGui::ToolbarSeparator(); ImGui::SameLine(); - if (AlienGui::ToolbarButton(AlienGui::ToolbarButtonParameters().text(ICON_FA_PLUS).secondText(ICON_FA_LAYER_GROUP).tooltip("Add parameter layer"))) { + if (AlienGui::ToolbarButton(AlienGui::ToolbarButtonParameters().text(ICON_FA_PLUS).secondText(ICON_FA_LAYER_GROUP).tooltip(_("Add parameter layer")))) { onInsertDefaultLayer(); } ImGui::SameLine(); - if (AlienGui::ToolbarButton(AlienGui::ToolbarButtonParameters().text(ICON_FA_PLUS).secondText(ICON_FA_SUN).tooltip("Add radiation source"))) { + if (AlienGui::ToolbarButton(AlienGui::ToolbarButtonParameters().text(ICON_FA_PLUS).secondText(ICON_FA_SUN).tooltip(_("Add radiation source")))) { onInsertDefaultSource(); } @@ -164,13 +164,13 @@ void SimulationParametersMainWindow::processToolbar() .text(ICON_FA_PLUS) .secondText(ICON_FA_CLONE) .disabled(_selectedOrderNumber == 0) - .tooltip("Clone selected layer/radiation source"))) { + .tooltip(_("Clone selected layer/radiation source")))) { onCloneLocation(); } ImGui::SameLine(); if (AlienGui::ToolbarButton( - AlienGui::ToolbarButtonParameters().text(ICON_FA_MINUS).disabled(_selectedOrderNumber == 0).tooltip("Delete selected layer/radiation source"))) { + AlienGui::ToolbarButtonParameters().text(ICON_FA_MINUS).disabled(_selectedOrderNumber == 0).tooltip(_("Delete selected layer/radiation source")))) { onDeleteLocation(); } @@ -181,14 +181,14 @@ void SimulationParametersMainWindow::processToolbar() if (AlienGui::ToolbarButton(AlienGui::ToolbarButtonParameters() .text(ICON_FA_CHEVRON_UP) .disabled(_selectedOrderNumber <= 1) - .tooltip("Move selected layer/radiation source upward"))) { + .tooltip(_("Move selected layer/radiation source upward")))) { onDecreaseOrderNumber(); } ImGui::SameLine(); if (AlienGui::ToolbarButton(AlienGui::ToolbarButtonParameters() .text(ICON_FA_CHEVRON_DOWN) - .tooltip("Move selected layer/radiation source downward") + .tooltip(_("Move selected layer/radiation source downward")) .disabled(_selectedOrderNumber >= _locations.size() - 1 || _selectedOrderNumber == 0))) { onIncreaseOrderNumber(); } @@ -199,7 +199,7 @@ void SimulationParametersMainWindow::processToolbar() ImGui::SameLine(); if (AlienGui::ToolbarButton(AlienGui::ToolbarButtonParameters() .text(ICON_FA_EXTERNAL_LINK_SQUARE_ALT) - .tooltip("Open parameters for selected layer/radiation source in a new window"))) { + .tooltip(_("Open parameters for selected layer/radiation source in a new window")))) { onOpenInLocationWindow(); } @@ -211,7 +211,7 @@ void SimulationParametersMainWindow::processMasterWidget() if (ImGui::BeginChild("##master", {0, getMasterWidgetHeight()})) { if (_masterWidgetOpen = - AlienGui::BeginTreeNode(AlienGui::TreeNodeParameters().name("Overview").rank(AlienGui::TreeNodeRank::High).defaultOpen(_masterWidgetOpen))) { + AlienGui::BeginTreeNode(AlienGui::TreeNodeParameters().name(_("Overview")).rank(AlienGui::TreeNodeRank::High).defaultOpen(_masterWidgetOpen))) { ImGui::Spacing(); if (ImGui::BeginChild("##master2", {0, -ImGui::GetStyle().FramePadding.y})) { processLocationTable(); @@ -305,7 +305,7 @@ void SimulationParametersMainWindow::processExpertWidget() { if (ImGui::BeginChild("##expert", {0, 0})) { if (_expertWidgetOpen = AlienGui::BeginTreeNode( - AlienGui::TreeNodeParameters().name("Expert settings").rank(AlienGui::TreeNodeRank::High).defaultOpen(_expertWidgetOpen))) { + AlienGui::TreeNodeParameters().name(_("Expert settings")).rank(AlienGui::TreeNodeRank::High).defaultOpen(_expertWidgetOpen))) { if (ImGui::BeginChild("##expert2", {0, 0}, ImGuiChildFlags_Border, ImGuiWindowFlags_HorizontalScrollbar)) { processExpertSettings(); } @@ -331,11 +331,11 @@ void SimulationParametersMainWindow::processLocationTable() if (ImGui::BeginTable("Locations", 5, flags, ImVec2(-1, -1), 0)) { - ImGui::TableSetupColumn("Name", ImGuiTableColumnFlags_NoSort | ImGuiTableColumnFlags_WidthFixed, scale(140.0f)); - ImGui::TableSetupColumn("Type", ImGuiTableColumnFlags_NoSort | ImGuiTableColumnFlags_WidthFixed, scale(140.0f)); - ImGui::TableSetupColumn("Position", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, scale(115.0f)); - ImGui::TableSetupColumn("Strength", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, scale(90.0f)); - ImGui::TableSetupColumn("Opacity", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, scale(90.0f)); + ImGui::TableSetupColumn(_("Name"), ImGuiTableColumnFlags_NoSort | ImGuiTableColumnFlags_WidthFixed, scale(140.0f)); + ImGui::TableSetupColumn(_("Type"), ImGuiTableColumnFlags_NoSort | ImGuiTableColumnFlags_WidthFixed, scale(140.0f)); + ImGui::TableSetupColumn(_("Position"), ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, scale(115.0f)); + ImGui::TableSetupColumn(_("Strength"), ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, scale(90.0f)); + ImGui::TableSetupColumn(_("Opacity"), ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, scale(90.0f)); ImGui::TableSetupScrollFreeze(0, 1); ImGui::TableHeadersRow(); ImGui::TableSetBgColor(ImGuiTableBgTarget_RowBg0, Const::TableHeaderColor); @@ -374,11 +374,11 @@ void SimulationParametersMainWindow::processLocationTable() // Column: Type ImGui::TableNextColumn(); if (entry.type == LocationType::Base) { - AlienGui::Text("Base parameters"); + AlienGui::Text(_("Base parameters")); } else if (entry.type == LocationType::Layer) { - AlienGui::Text("Layer"); + AlienGui::Text(_("Layer")); } else if (entry.type == LocationType::Source) { - AlienGui::Text("Radiation"); + AlienGui::Text(_("Radiation")); } // Column: Position @@ -397,7 +397,7 @@ void SimulationParametersMainWindow::processLocationTable() if (entry.type == LocationType::Base || entry.type == LocationType::Source) { AlienGui::Text(entry.strength); } else { - AlienGui::Text("-"); + AlienGui::Text(_("-")); } // Column: Opacity @@ -405,7 +405,7 @@ void SimulationParametersMainWindow::processLocationTable() if (entry.type == LocationType::Layer) { AlienGui::Text(entry.strength); } else { - AlienGui::Text("-"); + AlienGui::Text(_("-")); } ImGui::PopID(); diff --git a/source/Gui/SpatialControlWindow.cpp b/source/Gui/SpatialControlWindow.cpp index 31a9997cb..8a495625e 100644 --- a/source/Gui/SpatialControlWindow.cpp +++ b/source/Gui/SpatialControlWindow.cpp @@ -25,7 +25,7 @@ void SpatialControlWindow::initIntern() } SpatialControlWindow::SpatialControlWindow() - : AlienWindow("Spatial control", "windows.spatial control", true) + : AlienWindow(_("Spatial control"), "windows.spatial control", true) {} void SpatialControlWindow::shutdownIntern() @@ -54,7 +54,7 @@ void SpatialControlWindow::processIntern() if (ImGui::BeginChild("##", ImVec2(0, 0), false, ImGuiWindowFlags_HorizontalScrollbar)) { - ImGui::Text("World size"); + ImGui::Text("%s", _("World size")); ImGui::PushFont(StyleRepository::get().getLargeFont()); ImGui::PushStyleColor(ImGuiCol_Text, Const::TextDecentColor.Value); auto worldSize = _SimulationFacade::get()->getWorldSize(); @@ -62,14 +62,14 @@ void SpatialControlWindow::processIntern() ImGui::PopStyleColor(); ImGui::PopFont(); - ImGui::Text("Zoom factor"); + ImGui::Text("%s", _("Zoom factor")); ImGui::PushFont(StyleRepository::get().getLargeFont()); ImGui::PushStyleColor(ImGuiCol_Text, Const::TextDecentColor.Value); ImGui::TextUnformatted(StringHelper::format(Viewport::get().getZoomFactor(), 2).c_str()); ImGui::PopStyleColor(); ImGui::PopFont(); - ImGui::Text("Center position"); + ImGui::Text("%s", _("Center position")); ImGui::PushFont(StyleRepository::get().getLargeFont()); ImGui::PushStyleColor(ImGuiCol_Text, Const::TextDecentColor.Value); auto centerPos = Viewport::get().getCenterInWorldPos(); @@ -78,11 +78,11 @@ void SpatialControlWindow::processIntern() ImGui::PopFont(); AlienGui::Separator(); - AlienGui::ToggleButton(AlienGui::ToggleButtonParameters().name("Autotracking on selection"), _centerSelection); + AlienGui::ToggleButton(AlienGui::ToggleButtonParameters().name(_("Autotracking on selection")), _centerSelection); ImGui::Spacing(); ImGui::Spacing(); float sensitivity = Viewport::get().getZoomSensitivity(); - if (AlienGui::SliderFloat(AlienGui::SliderFloatParameters().name("Zoom sensitivity").min(1.0f).max(1.1f).textWidth(130).format(""), &sensitivity)) { + if (AlienGui::SliderFloat(AlienGui::SliderFloatParameters().name(_("Zoom sensitivity")).min(1.0f).max(1.1f).textWidth(130).format(""), &sensitivity)) { Viewport::get().setZoomSensitivity(sensitivity); } } @@ -99,7 +99,7 @@ void SpatialControlWindow::processZoomInButton() if (AlienGui::ToolbarButton(AlienGui::ToolbarButtonParameters().text(ICON_FA_SEARCH_PLUS))) { Viewport::get().setZoomFactor(Viewport::get().getZoomFactor() * 2); } - AlienGui::Tooltip("Zoom in"); + AlienGui::Tooltip(_("Zoom in")); } void SpatialControlWindow::processZoomOutButton() @@ -107,7 +107,7 @@ void SpatialControlWindow::processZoomOutButton() if (AlienGui::ToolbarButton(AlienGui::ToolbarButtonParameters().text(ICON_FA_SEARCH_MINUS))) { Viewport::get().setZoomFactor(Viewport::get().getZoomFactor() / 2); } - AlienGui::Tooltip("Zoom out"); + AlienGui::Tooltip(_("Zoom out")); } void SpatialControlWindow::processCenterButton() @@ -117,7 +117,7 @@ void SpatialControlWindow::processCenterButton() auto worldSize = toRealVector2D(_SimulationFacade::get()->getWorldSize()); Viewport::get().setCenterInWorldPos({worldSize.x / 2, worldSize.y / 2}); } - AlienGui::Tooltip("Center"); + AlienGui::Tooltip(_("Center")); } void SpatialControlWindow::processResizeButton() @@ -125,7 +125,7 @@ void SpatialControlWindow::processResizeButton() if (AlienGui::ToolbarButton(AlienGui::ToolbarButtonParameters().text(ICON_FA_CROP_ALT))) { ResizeWorldDialog::get().open(); } - AlienGui::Tooltip("Resize"); + AlienGui::Tooltip(_("Resize")); } void SpatialControlWindow::processCenterOnSelection() diff --git a/source/Gui/StatisticsWindow.cpp b/source/Gui/StatisticsWindow.cpp index d0bb8423b..84549deed 100644 --- a/source/Gui/StatisticsWindow.cpp +++ b/source/Gui/StatisticsWindow.cpp @@ -73,7 +73,7 @@ void StatisticsWindow::initIntern() } StatisticsWindow::StatisticsWindow() - : AlienWindow("Statistics", "windows.statistics", false) + : AlienWindow(_("Statistics"), "windows.statistics", false) {} void StatisticsWindow::shutdownIntern() @@ -100,7 +100,7 @@ void StatisticsWindow::processIntern() if (ImGui::BeginChild("##statistics", {0, _settingsOpen ? -_settingsHeight : -scale(40.0f)})) { if (ImGui::BeginTabBar("##Statistics", ImGuiTabBarFlags_AutoSelectNewTabs | ImGuiTabBarFlags_FittingPolicyResizeDown)) { - if (ImGui::BeginTabItem("Timelines")) { + if (ImGui::BeginTabItem(_("Timelines"))) { if (ImGui::BeginChild("##timelines", ImVec2(0, 0), 0)) { processTimelinesTab(); } @@ -108,7 +108,7 @@ void StatisticsWindow::processIntern() ImGui::EndTabItem(); } - if (ImGui::BeginTabItem("Histograms")) { + if (ImGui::BeginTabItem(_("Histograms"))) { if (ImGui::BeginChild("##histograms", ImVec2(0, 0), 0)) { processHistogramsTab(); } @@ -116,7 +116,7 @@ void StatisticsWindow::processIntern() ImGui::EndTabItem(); } - if (ImGui::BeginTabItem("Throughput")) { + if (ImGui::BeginTabItem(_("Throughput"))) { if (ImGui::BeginChild("##throughput", ImVec2(0, 0), 0)) { processTablesTab(); } @@ -135,9 +135,9 @@ void StatisticsWindow::processTimelinesTab() { ImGui::Spacing(); - AlienGui::Switcher(AlienGui::SwitcherParameters().name("Mode").textWidth(RightColumnWidth).values({"Real-time plots", "Entire history plots"}), &_plotMode); + AlienGui::Switcher(AlienGui::SwitcherParameters().name(_("Mode")).textWidth(RightColumnWidth).values({_("Real-time plots"), _("Entire history plots")}), &_plotMode); - AlienGui::Switcher(AlienGui::SwitcherParameters().name("Plot type").textWidth(RightColumnWidth).values(createPlotTypeStrings()), &_plotType); + AlienGui::Switcher(AlienGui::SwitcherParameters().name(_("Plot type")).textWidth(RightColumnWidth).values(createPlotTypeStrings()), &_plotType); if (ImGui::BeginChild("##plots", ImVec2(0, 0), false)) { processTimelineStatistics(); @@ -233,22 +233,22 @@ void StatisticsWindow::processTablesTab() ImGuiTableFlags_BordersInnerH | ImGuiTableFlags_BordersInnerV | ImGuiTableFlags_BordersOuterH | ImGuiTableFlags_BordersOuterV, ImVec2(-1, 0))) { - ImGui::TableSetupColumn("##"); - ImGui::TableSetupColumn("##", ImGuiTableColumnFlags_WidthFixed, scale(RightColumnWidthTable)); + ImGui::TableSetupColumn(_("##")); + ImGui::TableSetupColumn(_("##"), ImGuiTableColumnFlags_WidthFixed, scale(RightColumnWidthTable)); ImGui::TableNextRow(); ImGui::TableSetColumnIndex(0); AlienGui::Text(StringHelper::format(_tableLiveStatistics.getCreatedCellsPerSecond())); ImGui::TableSetColumnIndex(1); - AlienGui::Text("Created cells / sec"); + AlienGui::Text(_("Created cells / sec")); ImGui::TableNextRow(); ImGui::TableSetColumnIndex(0); AlienGui::Text(StringHelper::format(_tableLiveStatistics.getCreatedReplicatorsPerSecond())); ImGui::TableSetColumnIndex(1); - AlienGui::Text("Created self-replicators / sec"); + AlienGui::Text(_("Created self-replicators / sec")); ImGui::EndTable(); } @@ -263,14 +263,14 @@ void StatisticsWindow::processSettings() AlienGui::MovableHorizontalSeparator(AlienGui::MovableHorizontalSeparatorParameters().additive(false), _settingsHeight); } - _settingsOpen = AlienGui::BeginTreeNode(AlienGui::TreeNodeParameters().name("Settings").rank(AlienGui::TreeNodeRank::High).defaultOpen(_settingsOpen)); + _settingsOpen = AlienGui::BeginTreeNode(AlienGui::TreeNodeParameters().name(_("Settings")).rank(AlienGui::TreeNodeRank::High).defaultOpen(_settingsOpen)); if (_settingsOpen) { if (ImGui::BeginChild("##addons", {scale(0), 0})) { ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x - scale(RightColumnWidth)); if (_plotMode == 0) { AlienGui::SliderFloat( AlienGui::SliderFloatParameters() - .name("Time horizon") + .name(_("Time horizon")) .min(1.0f) .max(TimelineLiveStatistics::MaxLiveHistory) .format("%.1f s") @@ -279,13 +279,13 @@ void StatisticsWindow::processSettings() } if (_plotMode == 1) { AlienGui::SliderFloat( - AlienGui::SliderFloatParameters().name("Time horizon").min(1.0f).max(100.0f).format("%.0f percent").textWidth(RightColumnWidth), + AlienGui::SliderFloatParameters().name(_("Time horizon")).min(1.0f).max(100.0f).format("%.0f percent").textWidth(RightColumnWidth), &_timeHorizonForLongtermStatistics); } AlienGui::SliderFloat( - AlienGui::SliderFloatParameters().name("Plot height").min(MinPlotHeight).max(1000.0f).format("%.0f").textWidth(RightColumnWidth), &_plotHeight); - AlienGui::Switcher(AlienGui::SwitcherParameters().name("Scale").textWidth(RightColumnWidth).values({"Linear", "Logarithmic"}), &_plotScale); + AlienGui::SliderFloatParameters().name(_("Plot height")).min(MinPlotHeight).max(1000.0f).format("%.0f").textWidth(RightColumnWidth), &_plotHeight); + AlienGui::Switcher(AlienGui::SwitcherParameters().name(_("Scale")).textWidth(RightColumnWidth).values({_("Linear"), _("Logarithmic")}), &_plotScale); } ImGui::EndChild(); } @@ -299,8 +299,8 @@ void StatisticsWindow::processTimelineStatistics() ImGui::PushID(1); int row = 0; if (ImGui::BeginTable("##", 2, ImGuiTableFlags_BordersInnerH, ImVec2(-1, 0))) { - ImGui::TableSetupColumn("##"); - ImGui::TableSetupColumn("##", ImGuiTableColumnFlags_WidthFixed, scale(RightColumnWidthTimeline)); + ImGui::TableSetupColumn(_("##")); + ImGui::TableSetupColumn(_("##"), ImGuiTableColumnFlags_WidthFixed, scale(RightColumnWidthTimeline)); ImPlot::PushColormap(ImPlotColormap_Cool); @@ -308,31 +308,31 @@ void StatisticsWindow::processTimelineStatistics() ImGui::TableSetColumnIndex(0); processPlot(row++, &DataPointCollection::numObjects); ImGui::TableSetColumnIndex(1); - AlienGui::Text("Objects"); + AlienGui::Text(_("Objects")); ImGui::TableNextRow(); ImGui::TableSetColumnIndex(0); processPlot(row++, &DataPointCollection::numEnergyParticles); ImGui::TableSetColumnIndex(1); - AlienGui::Text("Energy particles"); + AlienGui::Text(_("Energy particles")); ImGui::TableNextRow(); ImGui::TableSetColumnIndex(0); processPlot(row++, &DataPointCollection::totalEnergy); ImGui::TableSetColumnIndex(1); - AlienGui::Text("Contained energy"); + AlienGui::Text(_("Contained energy")); ImGui::TableNextRow(); ImGui::TableSetColumnIndex(0); processPlot(row++, &DataPointCollection::numSelfReplicators); ImGui::TableSetColumnIndex(1); - AlienGui::Text("Self-replicators"); + AlienGui::Text(_("Self-replicators")); ImGui::TableNextRow(); ImGui::TableSetColumnIndex(0); processPlot(row++, &DataPointCollection::numColonies); ImGui::TableSetColumnIndex(1); - AlienGui::Text("Diversity"); + AlienGui::Text(_("Diversity")); ImGui::SameLine(); AlienGui::HelpMarker("The number of colonies is displayed. A colony is a set of at least 20 same mutants."); @@ -340,7 +340,7 @@ void StatisticsWindow::processTimelineStatistics() ImGui::TableSetColumnIndex(0); processPlot(row++, &DataPointCollection::averageGenomeCells, 2); ImGui::TableSetColumnIndex(1); - AlienGui::Text("Num genotype\ncells average"); + AlienGui::Text(_("Num genotype\ncells average")); ImGui::SameLine(); AlienGui::HelpMarker("The average number of encoded cells in the genomes is displayed."); @@ -348,31 +348,31 @@ void StatisticsWindow::processTimelineStatistics() ImGui::TableSetColumnIndex(0); processPlot(row++, &DataPointCollection::averageNumCells, 2); ImGui::TableSetColumnIndex(1); - AlienGui::Text("Genome complexity\naverage"); + AlienGui::Text(_("Genome complexity\naverage")); ImGui::TableNextRow(); ImGui::TableSetColumnIndex(0); processPlot(row++, &DataPointCollection::varianceNumCells, 2); ImGui::TableSetColumnIndex(1); - AlienGui::Text("Genome complexity\nvariance"); + AlienGui::Text(_("Genome complexity\nvariance")); ImGui::TableNextRow(); ImGui::TableSetColumnIndex(0); processPlot(row++, &DataPointCollection::maxNumCellsOfColonies, 2); ImGui::TableSetColumnIndex(1); - AlienGui::Text("Genome complexity\nmaximum"); + AlienGui::Text(_("Genome complexity\nmaximum")); ImGui::TableNextRow(); ImGui::TableSetColumnIndex(0); processPlot(row++, &DataPointCollection::numViruses); ImGui::TableSetColumnIndex(1); - AlienGui::Text("Viruses"); + AlienGui::Text(_("Viruses")); ImGui::TableNextRow(); ImGui::TableSetColumnIndex(0); processPlot(row++, &DataPointCollection::numFreeCells); ImGui::TableSetColumnIndex(1); - AlienGui::Text("Free cells"); + AlienGui::Text(_("Free cells")); ImPlot::PopColormap(); @@ -384,93 +384,93 @@ void StatisticsWindow::processTimelineStatistics() AlienGui::Group(AlienGui::GroupParameters().text("Processes per time step and active cell")); ImGui::PushID(2); if (ImGui::BeginTable("##", 2, ImGuiTableFlags_BordersInnerH, ImVec2(-1, 0))) { - ImGui::TableSetupColumn("##"); - ImGui::TableSetupColumn("##", ImGuiTableColumnFlags_WidthFixed, scale(RightColumnWidthTimeline)); + ImGui::TableSetupColumn(_("##")); + ImGui::TableSetupColumn(_("##"), ImGuiTableColumnFlags_WidthFixed, scale(RightColumnWidthTimeline)); ImPlot::PushColormap(ImPlotColormap_Cool); ImGui::TableNextRow(); ImGui::TableSetColumnIndex(0); processPlot(row++, &DataPointCollection::numCreatedCells, 6); ImGui::TableSetColumnIndex(1); - AlienGui::Text("Created cells"); + AlienGui::Text(_("Created cells")); ImGui::TableNextRow(); ImGui::TableSetColumnIndex(0); processPlot(row++, &DataPointCollection::numAttacks, 6); ImGui::TableSetColumnIndex(1); - AlienGui::Text("Attacks"); + AlienGui::Text(_("Attacks")); ImGui::TableNextRow(); ImGui::TableSetColumnIndex(0); processPlot(row++, &DataPointCollection::numMuscleActivities, 6); ImGui::TableSetColumnIndex(1); - AlienGui::Text("Muscle activities"); + AlienGui::Text(_("Muscle activities")); ImGui::TableNextRow(); ImGui::TableSetColumnIndex(0); processPlot(row++, &DataPointCollection::numDepotActivities, 6); ImGui::TableSetColumnIndex(1); - AlienGui::Text("Transmitter activities"); + AlienGui::Text(_("Transmitter activities")); ImGui::TableNextRow(); ImGui::TableSetColumnIndex(0); processPlot(row++, &DataPointCollection::numDefenderActivities, 6); ImGui::TableSetColumnIndex(1); - AlienGui::Text("Defender activities"); + AlienGui::Text(_("Defender activities")); ImGui::TableNextRow(); ImGui::TableSetColumnIndex(0); processPlot(row++, &DataPointCollection::numGeneratorPulses, 6); ImGui::TableSetColumnIndex(1); - AlienGui::Text("Generator pulses"); + AlienGui::Text(_("Generator pulses")); ImGui::TableNextRow(); ImGui::TableSetColumnIndex(0); processPlot(row++, &DataPointCollection::numNeuronActivities, 6); ImGui::TableSetColumnIndex(1); - AlienGui::Text("Neural activities"); + AlienGui::Text(_("Neural activities")); ImGui::TableNextRow(); ImGui::TableSetColumnIndex(0); processPlot(row++, &DataPointCollection::numSensorActivities, 6); ImGui::TableSetColumnIndex(1); - AlienGui::Text("Sensor activities"); + AlienGui::Text(_("Sensor activities")); ImGui::TableNextRow(); ImGui::TableSetColumnIndex(0); processPlot(row++, &DataPointCollection::numSensorMatches, 6); ImGui::TableSetColumnIndex(1); - AlienGui::Text("Sensor matches"); + AlienGui::Text(_("Sensor matches")); ImGui::TableNextRow(); ImGui::TableSetColumnIndex(0); processPlot(row++, &DataPointCollection::numInjectionActivities, 6); ImGui::TableSetColumnIndex(1); - AlienGui::Text("Injection activities"); + AlienGui::Text(_("Injection activities")); ImGui::TableNextRow(); ImGui::TableSetColumnIndex(0); processPlot(row++, &DataPointCollection::numCompletedInjections, 6); ImGui::TableSetColumnIndex(1); - AlienGui::Text("Completed injections"); + AlienGui::Text(_("Completed injections")); ImGui::TableNextRow(); ImGui::TableSetColumnIndex(0); processPlot(row++, &DataPointCollection::numReconnectorCreated, 6); ImGui::TableSetColumnIndex(1); - AlienGui::Text("Reconnector creations"); + AlienGui::Text(_("Reconnector creations")); ImGui::TableNextRow(); ImGui::TableSetColumnIndex(0); processPlot(row++, &DataPointCollection::numReconnectorRemoved, 6); ImGui::TableSetColumnIndex(1); - AlienGui::Text("Reconnector deletions"); + AlienGui::Text(_("Reconnector deletions")); ImGui::TableNextRow(); ImGui::TableSetColumnIndex(0); processPlot(row++, &DataPointCollection::numDetonations, 8); ImGui::TableSetColumnIndex(1); - AlienGui::Text("Detonations"); + AlienGui::Text(_("Detonations")); ImPlot::PopColormap(); ImGui::EndTable(); diff --git a/source/Gui/TemporalControlWindow.cpp b/source/Gui/TemporalControlWindow.cpp index 5845cfbea..386711ba3 100644 --- a/source/Gui/TemporalControlWindow.cpp +++ b/source/Gui/TemporalControlWindow.cpp @@ -33,7 +33,7 @@ void TemporalControlWindow::onSnapshot() } TemporalControlWindow::TemporalControlWindow() - : AlienWindow("Temporal control", "windows.temporal control", true) + : AlienWindow(_("Temporal control"), "windows.temporal control", true) {} void TemporalControlWindow::processIntern() @@ -74,7 +74,7 @@ void TemporalControlWindow::processIntern() void TemporalControlWindow::processTpsInfo() { - ImGui::Text("Time steps per second"); + ImGui::Text("%s", _("Time steps per second")); ImGui::PushFont(StyleRepository::get().getLargeFont()); ImGui::PushStyleColor(ImGuiCol_Text, Const::TextDecentColor.Value /*0xffa07050*/); @@ -85,7 +85,7 @@ void TemporalControlWindow::processTpsInfo() void TemporalControlWindow::processTotalTimestepsInfo() { - ImGui::Text("Total time steps"); + ImGui::Text("%s", _("Total time steps")); ImGui::PushFont(StyleRepository::get().getLargeFont()); ImGui::PushStyleColor(ImGuiCol_Text, Const::TextDecentColor.Value); @@ -96,7 +96,7 @@ void TemporalControlWindow::processTotalTimestepsInfo() void TemporalControlWindow::processRealTimeInfo() { - ImGui::Text("Real-time"); + ImGui::Text("%s", _("Real-time")); ImGui::PushFont(StyleRepository::get().getLargeFont()); ImGui::PushStyleColor(ImGuiCol_Text, Const::TextDecentColor.Value); @@ -107,7 +107,7 @@ void TemporalControlWindow::processRealTimeInfo() void TemporalControlWindow::processTpsRestriction() { - AlienGui::ToggleButton(AlienGui::ToggleButtonParameters().name("Slow down"), _slowDown); + AlienGui::ToggleButton(AlienGui::ToggleButtonParameters().name(_("Slow down")), _slowDown); ImGui::SameLine(scale(LeftColumnWidth) - (ImGui::GetWindowWidth() - ImGui::GetContentRegionAvail().x)); ImGui::BeginDisabled(!_slowDown); ImGui::PushItemWidth(ImGui::GetContentRegionAvail().x); @@ -121,7 +121,7 @@ void TemporalControlWindow::processTpsRestriction() ImGui::EndDisabled(); auto syncSimulationWithRendering = _SimulationFacade::get()->isSyncSimulationWithRendering(); - if (AlienGui::ToggleButton(AlienGui::ToggleButtonParameters().name("Sync with rendering"), syncSimulationWithRendering)) { + if (AlienGui::ToggleButton(AlienGui::ToggleButtonParameters().name(_("Sync with rendering")), syncSimulationWithRendering)) { _SimulationFacade::get()->setSyncSimulationWithRendering(syncSimulationWithRendering); } @@ -139,11 +139,11 @@ void TemporalControlWindow::processRunButton() { ImGui::BeginDisabled(_SimulationFacade::get()->isSimulationRunning()); auto result = AlienGui::ToolbarButton(AlienGui::ToolbarButtonParameters().text(ICON_FA_PLAY)); - AlienGui::Tooltip("Run"); + AlienGui::Tooltip(_("Run")); if (result) { _history.clear(); _SimulationFacade::get()->runSimulation(); - printOverlayMessage("Run"); + printOverlayMessage(_("Run")); } ImGui::EndDisabled(); } @@ -152,10 +152,10 @@ void TemporalControlWindow::processPauseButton() { ImGui::BeginDisabled(!_SimulationFacade::get()->isSimulationRunning()); auto result = AlienGui::ToolbarButton(AlienGui::ToolbarButtonParameters().text(ICON_FA_PAUSE)); - AlienGui::Tooltip("Pause"); + AlienGui::Tooltip(_("Pause")); if (result) { _SimulationFacade::get()->pauseSimulation(); - printOverlayMessage("Pause"); + printOverlayMessage(_("Pause")); } ImGui::EndDisabled(); } @@ -164,11 +164,11 @@ void TemporalControlWindow::processStepBackwardButton() { ImGui::BeginDisabled(_history.empty() || _SimulationFacade::get()->isSimulationRunning()); auto result = AlienGui::ToolbarButton(AlienGui::ToolbarButtonParameters().text(ICON_FA_CHEVRON_LEFT)); - AlienGui::Tooltip("Load previous time step"); + AlienGui::Tooltip(_("Load previous time step")); if (result) { auto const& snapshot = _history.back(); delayedExecution([this, snapshot] { applySnapshot(snapshot); }); - printOverlayMessage("Loading previous time step ..."); + printOverlayMessage(_("Loading previous time step ...")); _history.pop_back(); } @@ -179,7 +179,7 @@ void TemporalControlWindow::processStepForwardButton() { ImGui::BeginDisabled(_SimulationFacade::get()->isSimulationRunning()); auto result = AlienGui::ToolbarButton(AlienGui::ToolbarButtonParameters().text(ICON_FA_CHEVRON_RIGHT)); - AlienGui::Tooltip("Process single time step"); + AlienGui::Tooltip(_("Process single time step")); if (result) { _history.emplace_back(createSnapshot()); _SimulationFacade::get()->calcTimesteps(1); @@ -190,7 +190,7 @@ void TemporalControlWindow::processStepForwardButton() void TemporalControlWindow::processCreateFlashbackButton() { auto result = AlienGui::ToolbarButton(AlienGui::ToolbarButtonParameters().text(ICON_FA_CAMERA)); - AlienGui::Tooltip("Creating in-memory flashback: It saves the content of the current world to the memory."); + AlienGui::Tooltip(_("Creating in-memory flashback: It saves the content of the current world to the memory.")); if (result) { delayedExecution([this] { onSnapshot(); }); diff --git a/source/Gui/UploadSimulationDialog.cpp b/source/Gui/UploadSimulationDialog.cpp index c2564f361..f576bed0a 100644 --- a/source/Gui/UploadSimulationDialog.cpp +++ b/source/Gui/UploadSimulationDialog.cpp @@ -68,11 +68,11 @@ void UploadSimulationDialog::processIntern() { auto resourceTypeString = BrowserDataTypeToLowerString.at(_resourceType); if (ImGui::BeginChild("##header", ImVec2(0, scale(52.0f)), true, ImGuiWindowFlags_HorizontalScrollbar)) { - AlienGui::Text("Data privacy policy"); + AlienGui::Text(_("Data privacy policy")); AlienGui::HelpMarker( "The " + resourceTypeString + " file, name and description are stored on the server. It cannot be guaranteed that the data will not be deleted."); - AlienGui::Text("How to use or create folders?"); + AlienGui::Text(_("How to use or create folders?")); AlienGui::HelpMarker( "If you want to upload the " + resourceTypeString + " to a folder, you can use the `/`-notation. The folder will be created automatically if it does not exist.\nFor instance, naming a simulation " @@ -83,7 +83,7 @@ void UploadSimulationDialog::processIntern() if (!_folder.empty()) { if (ImGui::BeginChild("##folder info", ImVec2(0, scale(85.0f)), true, ImGuiWindowFlags_HorizontalScrollbar)) { - AlienGui::Text("The following folder has been selected in the browser\nand will used for the upload:\n\n"); + AlienGui::Text(_("The following folder has been selected in the browser\nand will used for the upload:\n\n")); AlienGui::Text(AlienGui::TextParameters().text(_folder).style(AlienGui::TextStyle::Bold)); } ImGui::EndChild(); @@ -98,7 +98,7 @@ void UploadSimulationDialog::processIntern() ImGui::PushID("description"); AlienGui::InputTextMultiline( AlienGui::InputTextMultilineParameters() - .hint("Desc (optional)") + .hint(_("Desc (optional)")) .textWidth(0) .height(ImGui::GetContentRegionAvail().y - StyleRepository::get().scale(70.0f)), _resourceDescription); @@ -106,7 +106,7 @@ void UploadSimulationDialog::processIntern() AlienGui::ToggleButton( AlienGui::ToggleButtonParameters() - .name("Make public") + .name(_("Make public")) .tooltip( "If true, the " + resourceTypeString + " will be visible to all users. If false, the " + resourceTypeString + " will only be visible in the private workspace. This property can also be changed later if desired."), @@ -115,7 +115,7 @@ void UploadSimulationDialog::processIntern() AlienGui::Separator(); ImGui::BeginDisabled(_resourceName.empty()); - if (AlienGui::Button("OK")) { + if (AlienGui::Button(_("OK"))) { if (NetworkValidationService::get().isStringValidForDatabase(_resourceName) && NetworkValidationService::get().isStringValidForDatabase(_resourceDescription)) { close(); @@ -130,7 +130,7 @@ void UploadSimulationDialog::processIntern() ImGui::SetItemDefaultFocus(); ImGui::SameLine(); - if (AlienGui::Button("Cancel")) { + if (AlienGui::Button(_("Cancel"))) { close(); } } From cd65b077b36f2013891cf1bd210f596c130f4b5f Mon Sep 17 00:00:00 2001 From: zysftd Date: Sun, 12 Jul 2026 20:43:28 +0800 Subject: [PATCH 05/15] fix: wrap main menu headers with _() and fix duplicate Cancel button --- source/Gui/DisplaySettingsDialog.cpp | 1 - source/Gui/MainLoopController.cpp | 16 ++++++++-------- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/source/Gui/DisplaySettingsDialog.cpp b/source/Gui/DisplaySettingsDialog.cpp index 3bdb57c26..94274a636 100644 --- a/source/Gui/DisplaySettingsDialog.cpp +++ b/source/Gui/DisplaySettingsDialog.cpp @@ -81,7 +81,6 @@ void DisplaySettingsDialog::processIntern() } ImGui::SetItemDefaultFocus(); - ImGui::SameLine(); ImGui::SameLine(); if (AlienGui::Button(_("Cancel"))) { close(); diff --git a/source/Gui/MainLoopController.cpp b/source/Gui/MainLoopController.cpp index b2bd94987..5f7d49413 100644 --- a/source/Gui/MainLoopController.cpp +++ b/source/Gui/MainLoopController.cpp @@ -347,7 +347,7 @@ void MainLoopController::processMenubar() AlienGui::MenuShutdownButton([&] { ExitDialog::get().open(); }); ImGui::Dummy(ImVec2(scale(10.0f), 0.0f)); - AlienGui::BeginMenu(" " ICON_FA_GAMEPAD " Simulation ", _simulationMenuOpened); + AlienGui::BeginMenu(std::string(" " ICON_FA_GAMEPAD " ") + _("Simulation"), _simulationMenuOpened); AlienGui::MenuItem(AlienGui::MenuItemParameters().name(_("New")).keyCtrl(true).key(ImGuiKey_N), [&] { NewSimulationDialog::get().open(); }); AlienGui::MenuItem( AlienGui::MenuItemParameters().name(_("Open")).keyCtrl(true).key(ImGuiKey_O), [&] { FileTransferController::get().onOpenSimulationDialog(); }); @@ -365,7 +365,7 @@ void MainLoopController::processMenubar() }); AlienGui::EndMenu(); - AlienGui::BeginMenu(" " ICON_FA_GLOBE " Network ", _networkMenuOpened); + AlienGui::BeginMenu(std::string(" " ICON_FA_GLOBE " ") + _("Network"), _networkMenuOpened); AlienGui::MenuItem( AlienGui::MenuItemParameters().name(_("Browser")).keyAlt(true).key(ImGuiKey_W).closeMenuWhenItemClicked(false).selected(BrowserWindow::get().isOn()), [&] { BrowserWindow::get().setOn(!BrowserWindow::get().isOn()); }); @@ -391,7 +391,7 @@ void MainLoopController::processMenubar() }); AlienGui::EndMenu(); - AlienGui::BeginMenu(" " ICON_FA_WINDOW_RESTORE " Windows ", _windowMenuOpened); + AlienGui::BeginMenu(std::string(" " ICON_FA_WINDOW_RESTORE " ") + _("Windows"), _windowMenuOpened); AlienGui::MenuItem( AlienGui::MenuItemParameters() .name(_("Temporal control")) @@ -427,7 +427,7 @@ void MainLoopController::processMenubar() [&] { LogWindow::get().setOn(!LogWindow::get().isOn()); }); AlienGui::EndMenu(); - AlienGui::BeginMenu(" " ICON_FA_PEN_ALT " Editor ", _editorMenuOpened); + AlienGui::BeginMenu(std::string(" " ICON_FA_PEN_ALT " ") + _("Editor"), _editorMenuOpened); AlienGui::MenuItem( AlienGui::MenuItemParameters() .name(_("Genome editor")) @@ -532,7 +532,7 @@ void MainLoopController::processMenubar() [&] { EditorController::get().onDelete(); }); AlienGui::EndMenu(); - AlienGui::BeginMenu(" " ICON_FA_EYE " View ", _viewMenuOpened); + AlienGui::BeginMenu(std::string(" " ICON_FA_EYE " ") + _("View"), _viewMenuOpened); AlienGui::MenuItem( AlienGui::MenuItemParameters() .name(_("Cell info overlay")) @@ -562,12 +562,12 @@ void MainLoopController::processMenubar() [&] { SimulationView::get().setRenderSimulation(!SimulationView::get().isRenderSimulation()); }); AlienGui::EndMenu(); - AlienGui::BeginMenu(" " ICON_FA_TOOLS " Tools ", _toolsMenuOpened); + AlienGui::BeginMenu(std::string(" " ICON_FA_TOOLS " ") + _("Tools"), _toolsMenuOpened); AlienGui::MenuItem(AlienGui::MenuItemParameters().name(_("Mass operations")).keyAlt(true).key(ImGuiKey_H), [&] { MassOperationsDialog::get().open(); }); AlienGui::MenuItem(AlienGui::MenuItemParameters().name(_("Image converter")).keyAlt(true).key(ImGuiKey_C), [&] { ImageToPatternDialog::get().show(); }); AlienGui::EndMenu(); - AlienGui::BeginMenu(" " ICON_FA_COG " Settings ", _settingsMenuOpened, false); + AlienGui::BeginMenu(std::string(" " ICON_FA_COG " ") + _("Settings"), _settingsMenuOpened, false); AlienGui::MenuItem( AlienGui::MenuItemParameters().name(_("Save on exit")).selected(_saveOnExit).closeMenuWhenItemClicked(false), [&] { _saveOnExit = !_saveOnExit; }); AlienGui::MenuItem(AlienGui::MenuItemParameters().name(_("CUDA settings")), [&] { GpuSettingsDialog::get().open(); }); @@ -575,7 +575,7 @@ void MainLoopController::processMenubar() AlienGui::MenuItem(AlienGui::MenuItemParameters().name(_("Network settings")).keyAlt(true).key(ImGuiKey_K), [&] { NetworkSettingsDialog::get().open(); }); AlienGui::EndMenu(); - AlienGui::BeginMenu(" " ICON_FA_LIFE_RING " Help ", _helpMenuOpened); + AlienGui::BeginMenu(std::string(" " ICON_FA_LIFE_RING " ") + _("Help"), _helpMenuOpened); AlienGui::MenuItem(AlienGui::MenuItemParameters().name(_("About")), [&] { AboutDialog::get().open(); }); AlienGui::MenuItem( AlienGui::MenuItemParameters().name(_("Getting started")).selected(GettingStartedWindow::get().isOn()).closeMenuWhenItemClicked(false), From e3a925060bf81c3111418175a916a154d7eaaef6 Mon Sep 17 00:00:00 2001 From: zysftd Date: Sun, 12 Jul 2026 20:48:28 +0800 Subject: [PATCH 06/15] fix: restore GettingStartedWindow _() wrappers and startup animation title --- source/Gui/GettingStartedWindow.cpp | 464 ++++++++++++++-------------- source/Gui/MainLoopController.cpp | 4 +- 2 files changed, 227 insertions(+), 241 deletions(-) diff --git a/source/Gui/GettingStartedWindow.cpp b/source/Gui/GettingStartedWindow.cpp index 682d5bb51..b7e12a806 100644 --- a/source/Gui/GettingStartedWindow.cpp +++ b/source/Gui/GettingStartedWindow.cpp @@ -1,11 +1,10 @@ #include "GettingStartedWindow.h" #include - #include -#include "AlienGui.h" #include "StyleRepository.h" +#include "AlienGui.h" #ifdef _WIN32 #include @@ -36,355 +35,350 @@ void GettingStartedWindow::processIntern() /** * INTRO */ - drawHeading1("Introduction"); + drawHeading1(_("Introduction")); ImGui::Text("%s", _("ALIEN is an artificial life and physics simulation tool based on a CUDA-powered 2D particle engine for soft bodies and fluids.")); - ImGui::Text( + ImGui::Text("%s", _( "Each particle can be equipped with higher-level functions including sensors, muscles, neurons, constructors, etc. that allow to " "mimic certain functionalities of biological cells or of robotic components. Multi-cellular organisms are simulated as networks of " "particles that exchange energy and information over their bonds. The engine encompasses a genetic system capable of encoding the " "blueprints of organisms in genomes which are stored in individual cells. The simulator is capable to simulate entire ecosystems inhabited " "by different populations where every object is composed of interacting particles with specific functions (regardless of whether it models a " - "plant, herbivore, carnivore, virus, environmental structure, etc.)."); + "plant, herbivore, carnivore, virus, environmental structure, etc.).")); /** * FIRST STEPS */ - drawHeading1("First steps"); + drawHeading1(_("First steps")); - ImGui::Text("The easiest way to get to know the ALIEN simulator is to download and run an existing simulation file. You can then try out different " - "function and modify the simulation according to your wishes."); - ImGui::Text( + ImGui::Text("%s", _("The easiest way to get to know the ALIEN simulator is to download and run an existing simulation file. You can then try out different " + "function and modify the simulation according to your wishes.")); + ImGui::Text("%s", _( "Various examples can be found in the in-game simulation browser demonstrating capabilities of the " "engine ranging from pure physics examples, self-deploying structures, self-replicators to evolving ecosystems. If not already open, please " "invoke Network " ICON_FA_LONG_ARROW_ALT_RIGHT " Browser in the menu bar. " "Simulations can be conveniently downloaded and uploaded from/to the connected server (alien-project.org by default). " "In order to upload own simulations to the server or rate other simulations, you need to register a new user, which can be accomplished in " - "the login dialog."); - - ImGui::Text("For the beginning, however, you can use the example already loaded. Initially, it is advisable to become acquainted with the " - "windows for temporal and spatial controls. The handling should be intuitive and requires no deeper knowledge."); - drawItemText("In the temporal control window, a simulation can be started or paused. The execution speed " + "the login dialog.")); + + ImGui::Text("%s", _("For the beginning, however, you can use the example already loaded. Initially, it is advisable to become acquainted with the " + "windows for temporal and spatial controls. The handling should be intuitive and requires no deeper knowledge.")); + drawItemText(_("In the temporal control window, a simulation can be started or paused. The execution speed " "may be regulated if necessary. In addition, it is possible to calculate and revert single time steps as " "well as to make snapshots of a simulation to which one can return at any time without having " - "to reload the simulation from a file."); - drawItemText("The spatial control window combines zoom information and settings on the one hand, and " + "to reload the simulation from a file.")); + drawItemText(_("The spatial control window combines zoom information and settings on the one hand, and " "scaling functions on the other hand. A quite useful feature in the dialog for " "scaling/resizing is the option 'Scale content'. If activated, periodic spatial copies of " - "the original world can be made."); - ImGui::Text("There are basically two modes of how the user can operate in the view where the simulation is " - "shown: a navigation mode and an edit mode. You can switch between these two modes by invoking " - "the edit button at the bottom left of the screen or in the menu via Editor " ICON_FA_LONG_ARROW_ALT_RIGHT " Activate."); - drawItemText( + "the original world can be made.")); + ImGui::Text("%s", _("There are basically two modes of how the user can operate in the view where the simulation is " + "shown: a navigation mode and an edit mode. You can switch between these two modes by invoking " + "the edit button at the bottom left of the screen or in the menu via Editor " ICON_FA_LONG_ARROW_ALT_RIGHT " Activate.")); + drawItemText(_( "The navigation mode is enabled by default and allows you to zoom in (holding the left mouse " "button) and out (holding the right mouse button) continuously. Alternatively, you can also use the mouse wheel. By holding the middle mouse " - "button and moving the mouse, you can pan the visualized section of the world."); - drawItemText( + "button and moving the mouse, you can pan the visualized section of the world.")); + drawItemText(_( "In the edit mode, it is possible to push bodies around in a running simulation by holding and moving the right mouse button. " "With the left mouse button you can drag and drop objects. Please try this out. It can make a lot of fun! The editing mode also allows you " "to activate lot of editing windows (Pattern editor, Creator, Multiplier, Genome editor, etc.) whose possibilities can be explored over time. " - "Practically all properties of each single particle can be manipulated. In addition, there are mass editing functions available."); + "Practically all properties of each single particle can be manipulated. In addition, there are mass editing functions available.")); - ImGui::Text("To be able to experiment with existing simulations, it is important to know and change the " + ImGui::Text("%s", _("To be able to experiment with existing simulations, it is important to know and change the " "simulation parameters. This can be accomplished in the window 'Simulation parameters'. For example, " "the radiation intensity can be increased or the friction can be adjusted. Explanations to the " - "individual parameters can be found in the tooltip next to them."); + "individual parameters can be found in the tooltip next to them.")); - ImGui::Text( + ImGui::Text("%s", _( "ALIEN offers the possibility for users to customize the basic entities through a color system with 7 different colors. More precisely, each " "cell is assigned a specific color, allowing the application of different simulation parameter values based on the cell's color. This " "enables the creation of specific conditions for populations coexisting in a shared world. For example, " - "plant-like organisms may have a higher absorption rate for radiation particles, so they can get their energy from that."); + "plant-like organisms may have a higher absorption rate for radiation particles, so they can get their energy from that.")); - drawHeading2("Important"); - ImGui::Text("On older graphics cards or when using a high resolution (e.g. 4K), it is recommended to reduce the rendered frames per second, " - "as this significantly increases the simulation speed (time steps per second). This adjustment can be made in the display settings."); + drawHeading2(_("Important")); + ImGui::Text("%s", _( + "On older graphics cards or when using a high resolution (e.g. 4K), it is recommended to reduce the rendered frames per second, " + "as this significantly increases the simulation speed (time steps per second). This adjustment can be made in the display settings.")); /** * EXAMPLES */ - drawHeading1("Examples"); - drawParagraph( + drawHeading1(_("Examples")); + drawParagraph(_( "ALIEN comes with a lot of simulation files that can be found in the browser window. They are good for experimenting with certain aspects of the " - "program. We pick some examples to give a short overview:"); - - drawHeading2("Fluids, walls and soft bodies"); - drawParagraph("There are several pure physics simulations demonstrating the engines' capability. They are suitable for testing the influence of " - "simulation parameters such as 'Smoothing length', 'Pressure', 'Viscosity', etc."); - drawItemText("Fluids/Pump with Soft-Bodies"); - drawItemText("Demos/Perpetual Motion Machine"); - drawItemText("Demos/Stormy Night"); - - drawHeading2("Evolution simulations"); - drawParagraph("By attaching higher-level functions to particle networks, complex multi-cellular organisms can be modeled. They can evolve over time as " - "they are subject to mutations. The following examples consist of homogeneous as well as changing worlds populated by self-reproducing " - "agents. Different " - "selection pressures control evolution."); - drawItemText("Deep Down Below/Selected Results"); - drawItemText("Primordial Ocean/Selected Results"); - drawItemText("v4.8-Evolution/Gradient/Selected Results"); - drawItemText("Evolution Sandbox/Example"); - drawItemText("Complex Evolution Testbed/Example"); - - drawHeading2("Plant-herbivore ecosystems"); - drawParagraph("By customizing the cells according to their color, it is possible to specify different types of organisms. There are many examples that " - "feature two classes: plants and herbivores. Plants are able to consume radiation particles, while herbivores can consume plants. This " - "simple relationship already provides interesting dynamics, as the following examples show."); - drawItemText("Twin Worlds/Example"); - drawItemText("Bugs and Flowers/Example"); - drawItemText("Self-replicating Fluid/Initial Setting"); - - drawHeading2("Swarming"); - drawParagraph("There are powerful sensors available as cell functions for detecting concentrations of specific colors in the surroundings. " - "Organisms equipped with these sensors can perceive their environment, nourish their neural networks, and respond accordingly."); - drawItemText("Swarms/Space Invaders"); - drawItemText("Evolving Swarms/Example"); + "program. We pick some examples to give a short overview:")); + + drawHeading2(_("Fluids, walls and soft bodies")); + drawParagraph(_("There are several pure physics simulations demonstrating the engines' capability. They are suitable for testing the influence of " + "simulation parameters such as 'Smoothing length', 'Pressure', 'Viscosity', etc.")); + drawItemText(_("Fluids/Pump with Soft-Bodies")); + drawItemText(_("Demos/Perpetual Motion Machine")); + drawItemText(_("Demos/Stormy Night")); + + drawHeading2(_("Evolution simulations")); + drawParagraph(_("By attaching higher-level functions to particle networks, complex multi-cellular organisms can be modeled. They can evolve over time as " + "they are subject to mutations. The following examples consist of homogeneous as well as changing worlds populated by self-reproducing agents. Different " + "selection pressures control evolution.")); + drawItemText(_("Deep Down Below/Selected Results")); + drawItemText(_("Primordial Ocean/Selected Results")); + drawItemText(_("v4.8-Evolution/Gradient/Selected Results")); + drawItemText(_("Evolution Sandbox/Example")); + drawItemText(_("Complex Evolution Testbed/Example")); + + drawHeading2(_("Plant-herbivore ecosystems")); + drawParagraph(_("By customizing the cells according to their color, it is possible to specify different types of organisms. There are many examples that " + "feature two classes: plants and herbivores. Plants are able to consume radiation particles, while herbivores can consume plants. This " + "simple relationship already provides interesting dynamics, as the following examples show.")); + drawItemText(_("Twin Worlds/Example")); + drawItemText(_("Bugs and Flowers/Example")); + drawItemText(_("Self-replicating Fluid/Initial Setting")); + + drawHeading2(_("Swarming")); + drawParagraph(_("There are powerful sensors available as cell functions for detecting concentrations of specific colors in the surroundings. " + "Organisms equipped with these sensors can perceive their environment, nourish their neural networks, and respond accordingly.")); + drawItemText(_("Swarms/Space Invaders")); + drawItemText(_("Evolving Swarms/Example")); /** * BASIC NOTION */ - drawHeading1("Basic notion"); + drawHeading1(_("Basic notion")); - ImGui::Text("Generally, in an ALIEN simulation, all objects as well as thermal radiation are modeled by different types of particles moving through an " - "empty space. The following terms are frequently used:"); + ImGui::Text("%s", _("Generally, in an ALIEN simulation, all objects as well as thermal radiation are modeled by different types of particles moving through an " + "empty space. The following terms are frequently used:")); ImGui::Spacing(); - drawHeading2("World"); + drawHeading2(_("World")); ImGui::Text("%s", _("An ALIEN world is two-dimensional rectangular domain with periodic boundary conditions. The space is modeled as a continuum.")); ImGui::Spacing(); - drawHeading2("Cell"); - ImGui::Text("Cells are the basic building blocks that make up everything. They can be connected to each others, possibly attached to the background " - "(to model barriers), possess special functions and transport signals. Additionally, cells have various physical properties, including"); - drawItemText("Position in space"); - drawItemText("Velocity"); - drawItemText("Internal energy (may be interpreted as its temperature)"); - drawItemText("Upper limit of connections"); - drawItemText("Living state"); + drawHeading2(_("Cell")); + ImGui::Text("%s", _( + "Cells are the basic building blocks that make up everything. They can be connected to each others, possibly attached to the background " + "(to model barriers), possess special functions and transport signals. Additionally, cells have various physical properties, including")); + drawItemText(_("Position in space")); + drawItemText(_("Velocity")); + drawItemText(_("Internal energy (may be interpreted as its temperature)")); + drawItemText(_("Upper limit of connections")); + drawItemText(_("Living state")); ImGui::Spacing(); - drawHeading2("Cell connection"); - ImGui::Text( + drawHeading2(_("Cell connection")); + ImGui::Text("%s", _( "A cell connection is a bond between two cells. It stores the reference distance and on each side a reference angle to a possibly further cell " "connection. The reference distance and angles are calculated when the connection is established. As soon as the actual distance deviates from " "the reference distance, a pulling/pushing force is applied at both ends. Furthermore, tangential forces are applied at both ends in the " - "case of an angle mismatch."); + "case of an angle mismatch.")); ImGui::Spacing(); - drawHeading2("Cell function"); - ImGui::Text("It is possible to assign a special function to a object, which will be executed at regular time intervals. The following functions are " - "implemented:"); - drawItemText( - "Neuron: It equips the cell with a small network of 8 neurons. It processes input gained from the signals of connected cells and provides an " - "output signal to other connected cells."); - drawItemText( + drawHeading2(_("Cell function")); + ImGui::Text("%s", _("It is possible to assign a special function to a cell, which will be executed at regular time intervals. The following functions are " + "implemented:")); + drawItemText(_("Neuron: It equips the cell with a small network of 8 neurons. It processes input gained from the signals of connected cells and provides an " + "output signal to other connected cells.")); + drawItemText(_( "Transmitter: It distributes energy to other constructors, transmitters or surrounding cells. In particular, it can be used to power active " - "constructors. No signal is required for triggering."); - drawItemText("Constructor: A constructor can build a cell network based on a built-in genome. The construction is done cell by cell and requires " - "energy. A constructor can either be controlled via signals or become active automatically (default)."); - drawItemText("Injector: It can infect other constructor cells to inject its own built-in genome."); - drawItemText("Generator: On the one hand, it transfers signals from connected input cells and on the other hand, it can optionally generate " - "signals at specific intervals."); - drawItemText("Attacker: It attacks surrounding cells from other cell networks by stealing energy from them."); - drawItemText("Defender: It reduces the attack strength when another cell in the vicinity performs an attack."); - drawItemText("Muscle: When a muscle cell is activated, it can produce either a movement, a bending or a change in length of the cell connection."); - drawItemText("Sensor: If activated, it performs a long-range scan for the concentration of cells with a certain color."); - drawItemText("Reconnector: Has the ability to dynamically create or destroy connections to other cells with a specified color."); - drawItemText("Detonator: A cell which can explode by a signal. It generates a large amount of kinetic energy for the objects in its surroundings."); + "constructors. No signal is required for triggering.")); + drawItemText(_("Constructor: A constructor can build a cell network based on a built-in genome. The construction is done cell by cell and requires " + "energy. A constructor can either be controlled via signals or become active automatically (default).")); + drawItemText(_("Injector: It can infect other constructor cells to inject its own built-in genome.")); + drawItemText(_("Nerve: On the one hand, it transfers signals from connected input cells and on the other hand, it can optionally generate " + "signals at specific intervals.")); + drawItemText(_("Attacker: It attacks surrounding cells from other cell networks by stealing energy from them.")); + drawItemText(_("Defender: It reduces the attack strength when another cell in the vicinity performs an attack.")); + drawItemText(_("Muscle: When a muscle cell is activated, it can produce either a movement, a bending or a change in length of the cell connection.")); + drawItemText(_("Sensor: If activated, it performs a long-range scan for the concentration of cells with a certain color.")); + drawItemText(_("Reconnector: Has the ability to dynamically create or destroy connections to other cells with a specified color.")); + drawItemText(_( + "Detonator: A cell which can explode by a signal. It generates a large amount of kinetic energy for the objects in its surroundings.")); ImGui::Spacing(); - drawHeading2("Signals"); - drawParagraph( + drawHeading2(_("Signals")); + drawParagraph(_( "Cells can produce signals comprising of 8 values, primarily utilized for controlling cell functions and sometimes referred to as channel #0 " "to channel #7. The states are refreshed periodically, specifically when the cell functions are executed. To be more precise, each cell function " - "is executed at regular time intervals (every 6 time steps). The 'execution order number' specifies the exact time offset within those intervals."); - drawParagraph( - "The process for updating the values of a signal is as follows: Firstly, the values of all input signals (i.e. " - "signals from connected cells which matches with the input execution number) are summed up. The resulted sum is then employed as input for " - "the cell function, which may potentially alter the values. Subsequently, the outcome is used to generate an output signal."); + "is executed at regular time intervals (every 6 time steps). The 'execution order number' specifies the exact time offset within those intervals.")); + drawParagraph(_("The process for updating the values of a signal is as follows: Firstly, the values of all input signals (i.e. " + "signals from connected cells which matches with the input execution number) are summed up. The resulted sum is then employed as input for " + "the cell function, which may potentially alter the values. Subsequently, the outcome is used to generate an output signal.")); ImGui::Spacing(); - drawHeading2("Cell color"); - drawParagraph("In addition to cell functions, a color can be used to perform additional user-defined customization of cells. For this purpose, most " - "simulation parameters can be adjusted separately for each color, if desired. As a result, cells of different colors may have individual " - "properties."); + drawHeading2(_("Cell color")); + drawParagraph(_("In addition to cell functions, a color can be used to perform additional user-defined customization of cells. For this purpose, most " + "simulation parameters can be adjusted separately for each color, if desired. As a result, cells of different colors may have individual " + "properties.")); ImGui::Spacing(); - drawHeading2("Cell network"); - drawParagraph("A cell network is a connected graph consisting of cells and cell connections. Two cells in a network are therefore " - "connected to each other directly or via other cells. A cell network physically represents a particular body."); + drawHeading2(_("Cell network")); + drawParagraph(_("A cell network is a connected graph consisting of cells and cell connections. Two cells in a network are therefore " + "connected to each other directly or via other cells. A cell network physically represents a particular body.")); ImGui::Spacing(); - drawHeading2("Genome"); - drawParagraph("The blueprints for entire cell networks can be stored in genomes. These genomes are translated into real cell networks by constructor " - "cells and, if necessary, copied to their offspring. Furthermore, injector cells are able to inject their own genome into other " - "constructor cells, which allows to model virus behaviors."); - drawParagraph("A genome in ALIEN may describe several cell networks, which are hierarchically structured und possibly connected when constructed. More " + drawHeading2(_("Genome")); + drawParagraph(_("The blueprints for entire cell networks can be stored in genomes. These genomes are translated into real cell networks by constructor " + "cells and, if necessary, copied to their offspring. Furthermore, injector cells are able to inject their own genome into other " + "constructor cells, which allows to model virus behaviors.")); + drawParagraph(_("A genome in ALIEN may describe several cell networks, which are hierarchically structured und possibly connected when constructed. More " "precisely, it means that there is a top-level blueprint describing a certain network. If there are further constructor cells " - "within this network, they can also contain further genomes, which in turn describe other cell networks and so on."); + "within this network, they can also contain further genomes, which in turn describe other cell networks and so on.")); ImGui::Spacing(); - drawHeading2("Energy particle"); - drawParagraph( + drawHeading2(_("Energy particle")); + drawParagraph(_( "An energy particle is a particle which has only an energy value, position and velocity. Unlike cells, they cannot form networks or perform any " - "additional functions. Energy particles are produced by cells as radiation or during decay and can, in turn, also be absorbed."); + "additional functions. Energy particles are produced by cells as radiation or during decay and can, in turn, also be absorbed.")); ImGui::Spacing(); - drawHeading2("Pattern"); - drawParagraph("A pattern is a set of cell networks and energy particles."); + drawHeading2(_("Pattern")); + drawParagraph(_("A pattern is a set of cell networks and energy particles.")); /** * SIMULATION PARAMETERS */ - drawHeading1("Simulation parameters"); - drawParagraph( + drawHeading1(_("Simulation parameters")); + drawParagraph(_( "All parameters relevant to the simulation can be adjusted here. By default, the parameters are set uniformly for the entire world. However, it is " - "also possible to allow certain parameters to vary locally in special layers. To do this, you can create a new tab in the simulation parameter " - "window by clicking on " - "the '+' button. It adds a spatially (fuzzy) delimited area where the global parameters can be overwritten. This layer is also visible by a " - "different color."); - drawParagraph("Regardless of this, many parameters can also be set depending on the cell color. For this purpose click the '+' button beside the " - "parameter. This customization is useful when you want to define different classes of species."); - drawParagraph("Sometimes it is difficult to set precise values in a slider. In this case, you can click on the slider while holding the CTRL key. This " - "allows you to enter the exact value in an input field and confirm it by pressing ENTER."); - drawParagraph("In general, the following types of parameters can be set."); - drawHeading2("Rendering"); - drawParagraph( + "also possible to allow certain parameters to vary locally in special zones. To do this, you can create a new tab in the simulation parameter window by clicking on " + "the '+' button. It adds a spatially (fuzzy) delimited area where the global parameters can be overwritten. This zone is also visible by a " + "different color.")); + drawParagraph(_("Regardless of this, many parameters can also be set depending on the cell color. For this purpose click the '+' button beside the " + "parameter. This customization is useful when you want to define different classes of species.")); + drawParagraph(_("Sometimes it is difficult to set precise values in a slider. In this case, you can click on the slider while holding the CTRL key. This " + "allows you to enter the exact value in an input field and confirm it by pressing ENTER.")); + drawParagraph(_("In general, the following types of parameters can be set.")); + drawHeading2(_("Rendering")); + drawParagraph(_( "In addition to the background color, you can determine the coloring of the cells here. Each cell is assigned a specific color, which can be used " "for customization and which is also used by default for rendering. However, in evolution simulations, it can be very useful to color mutants " "differently. This allows for better visual evaluation of diversities, mutation rates, and successful mutants, etc. For this purpose, you can " - "switch the object coloring to the mutation id."); - drawHeading2("Physics"); - drawParagraph("Basic physical properties can be modified in these settings. This includes adjusting the radiation intensity, various thresholds, and " - "the motion algorithm. Changes can have significant effects on performance and, in the worst case, may lead to program crashes."); - drawHeading2("Radiation sources"); - drawParagraph("Optionally, you can define radiation sources by opening the corresponding editor. Typically, all cells lose energy over time by " + "switch the cell coloring to the mutation id.")); + drawHeading2(_("Physics")); + drawParagraph(_("Basic physical properties can be modified in these settings. This includes adjusting the radiation intensity, various thresholds, and " + "the motion algorithm. Changes can have significant effects on performance and, in the worst case, may lead to program crashes.")); + drawHeading2(_("Radiation sources")); + drawParagraph(_("Optionally, you can define radiation sources by opening the corresponding editor. Typically, all cells lose energy over time by " "emitting particles. These energy particles travel through space and can be absorbed by other cells under certain conditions. When no " "radiation source is defined, energy particles are emitted at the cell's position, resulting in a more or less uniform distribution of " "energy particles throughout space over time. For certain simulations, especially in modeling plant species, it is beneficial to specify " "explicit sources where energy particles should be generated. This can be achieved in the 'Radiation sources' window. Even when a source " "is defined, cells continue to lose the same amount of energy as before. The difference is that particles are now spawned at the " - "specified source. The energy conservation principle remains intact."); - drawHeading2("Cell specific parameters"); - drawParagraph("These parameter types are particularly important when simulating (self-replicating) agents composed of cell networks, going beyond pure " + "specified source. The energy conservation principle remains intact.")); + drawHeading2(_("Cell specific parameters")); + drawParagraph(_("These parameter types are particularly important when simulating (self-replicating) agents composed of cell networks, going beyond pure " "physical simulations. Many of the different cell functions depend on specific parameters, which can be adjusted here. Particularly " "important are the parameters for mutation rates and the attack functions.With the latter, the food chain between cells of different " "colors can be configured. For example, in the 'Food chain color matrix' one could specify that cells with a certain color can only " - "consume cells with a certain other color but not themselves."); - drawParagraph("The mutation rates influence the probability of modifying a genome for the underlying cells. When adjusting these rates, it should " + "consume cells with a certain other color but not themselves.")); + drawParagraph(_("The mutation rates influence the probability of modifying a genome for the underlying cells. When adjusting these rates, it should " "be noted that different types of mutations also have different impacts. For instance, a 'Duplication' mutation affects the genome much " "more invasively than a 'Neural net' mutation, which only adjusts weights and biases. Furthermore, it should be considered that for " "evolutionary simulations, where individuals require a long time for self-replication, high mutation rates should be " - "avoided. The correct values are best determined through experimentation."); + "avoided. The correct values are best determined through experimentation.")); /** * EDITORS */ - drawHeading1("Editors"); - drawParagraph( + drawHeading1(_("Editors")); + drawParagraph(_( "If you want to design your own worlds, sceneries or organisms, there are many different editors available, which partially require deeper " "knowledge. To open the editors, you have to switch to the edit mode (e.g. a click on the icon at the bottom left). A short overview of the " - "possibilities are given below."); - drawHeading2("Drag and drop"); - drawParagraph( + "possibilities are given below.")); + drawHeading2(_("Drag and drop")); + drawParagraph(_( "The easiest way is to select and move objects with the mouse. You can simply drag and drop cell networks in the simulation view. This " "also works during running simulations. When the simulation is paused, you can select a rectangular area to be highlighted by holding " "down the right mouse button. The selection is visually highlighted and can be moved via drag and drop. By holding down the SHIFT button during" "a mouse action, only the selected cells and not the associated cell networks are shifted. This can lead to the destruction or formation of cell " - "connections which are not selected."); - drawHeading2("Creator"); - drawParagraph("If you want to create individual cells, cell networks, or energy particles, you can open the 'Creator' window. In this window you also " + "connections which are not selected.")); + drawHeading2(_("Creator")); + drawParagraph(_("If you want to create individual cells, cell networks, or energy particles, you can open the 'Creator' window. In this window you also " "find a mode for creating cell structures by freehand drawing on the simulation area. The created cells are equipped with default values " - "and can be modified later if desired."); - drawHeading2("Pattern editor"); - drawParagraph("Physical properties of already selected cells and energy particles, such as center velocities, positions, colors, etc., can be " - "conveniently changed in the 'Pattern editor'. In addition, selections can be saved, loaded, copied and pasted."); - drawHeading2("Genome editor"); - drawParagraph("In the 'Genome editor', genomes describing cell networks can be created and modified. Each tab shows the principal part of the genome. " - "It is a sequence of cells that are supposed to be constructed in that order. If one of these cells is a constructor object, it contains " - "an additional genome that can be edited in a separate tab, if desired."); - drawParagraph("To translate a genome into an actual structure, there are two options:"); - drawItemText("You can generate a spore using the corresponding toolbar button. A spore is a single constructor cell containing the specific genome and " - "possessing enough energy to create the main structure described within."); - drawItemText( + "and can be modified later if desired.")); + drawHeading2(_("Pattern editor")); + drawParagraph(_("Physical properties of already selected cells and energy particles, such as center velocities, positions, colors, etc., can be " + "conveniently changed in the 'Pattern editor'. In addition, selections can be saved, loaded, copied and pasted.")); + drawHeading2(_("Genome editor")); + drawParagraph(_("In the 'Genome editor', genomes describing cell networks can be created and modified. Each tab shows the principal part of the genome. " + "It is a sequence of cells that are supposed to be constructed in that order. If one of these cells is a constructor cell, it contains " + "an additional genome that can be edited in a separate tab, if desired.")); + drawParagraph(_("To translate a genome into an actual structure, there are two options:")); + drawItemText(_("You can generate a spore using the corresponding toolbar button. A spore is a single constructor cell containing the specific genome and " + "possessing enough energy to create the main structure described within.")); + drawItemText(_( "Another option is to inject the genome into an existing organism. To do this, you must select the organism and click on 'Inspect principal " "genome' in the editor menu. A window will open where you see the existing genome of that creature. Then you can inject your own genome by " - "invoking the 'Inject from editor' button."); - drawHeading2("Object inspection"); - drawParagraph("Nearly every property of each particle can be viewed and edited. For this purpose, special editing windows can be attached to a " - "energyParticle. To do this, you have to select one or more particles (not too many) and invoke 'Inspect objects' from the editor menu. Each " + "invoking the 'Inject from editor' button.")); + drawHeading2(_("Object inspection")); + drawParagraph(_("Nearly every property of each particle can be viewed and edited. For this purpose, special editing windows can be attached to a " + "particle. To do this, you have to select one or more particles (not too many) and invoke 'Inspect objects' from the editor menu. Each " "selected particle is now connected to a window. It is even possible to view these editing windows during a running simulation. In this " - "way, you can monitor in real-time how properties of individual particles change over time."); - drawHeading2("Mass operations"); - drawParagraph("Various mass editing functions are available. On the one hand, the pattern editor allows to change different physical properties of an " + "way, you can monitor in real-time how properties of individual particles change over time.")); + drawHeading2(_("Mass operations")); + drawParagraph(_("Various mass editing functions are available. On the one hand, the pattern editor allows to change different physical properties of an " "entire selection. On the other hand, through the 'Tools' menu, the 'Mass operations' dialog can be opened. Here, colors of cells and " "genomes, energy values, and other properties can be globally modified. The new values will be randomly chosen from a specified range. " - "Cells within a cell networks will be assigned the same value."); - drawParagraph("In addition, simulations can be scaled up by increasing the size of the world and filling the resulting empty space with copies of the " + "Cells within a cell networks will be assigned the same value.")); + drawParagraph(_("In addition, simulations can be scaled up by increasing the size of the world and filling the resulting empty space with copies of the " "original world. This functionality is available via the resize dialog in the 'Spatial control' window, if you set a new size there and " - "activate 'Scale content'."); + "activate 'Scale content'.")); /** * FREQUENTLY ASK QUESTIONS */ - drawHeading1("Frequently asked questions"); - - drawHeading2("How does a simple self-replicating organism work?"); - drawParagraph("In general, an organism in ALIEN consists of a network of cells where the cells work together by communicating with each other through " - "signals."); - drawParagraph("A simple creature first needs a constructor cell that contains its genome and is responsible for self-replication. The constructor cell " - "is automatically triggered and generates (as soon as enough energy is available) the cell network of the offspring built cell by cell " - "as described in " - "its genome. The genome for the offspring is also copied and placed into the constructor cell of the offspring."); - drawParagraph( + drawHeading1(_("Frequently asked questions")); + + drawHeading2(_("How does a simple self-replicating organism work?")); + drawParagraph(_("In general, an organism in ALIEN consists of a network of cells where the cells work together by communicating with each other through " + "signals.")); + drawParagraph(_( + "A simple creature first needs a constructor cell that contains its genome and is responsible for self-replication. The constructor cell " + "is automatically triggered and generates (as soon as enough energy is available) the cell network of the offspring built cell by cell as described in " + "its genome. The genome for the offspring is also copied and placed into the constructor cell of the offspring.")); + drawParagraph(_( "Self-replication requires energy, which must be obtained in some way. On the one hand, energy can be acquired by the absorption of " - "energy particles flying around. This can be the main source of energy for plant-like species. On the other hand, there is the possibility to " - "utilize " + "energy particles flying around. This can be the main source of energy for plant-like species. On the other hand, there is the possibility to utilize " "attacker cells. They can attack cells from other organisms by stealing energy from them. If an attacker cell is part of the creature, it must be " "explicitly triggered by a signal. This signal may come, for example, from another cell equipped with a neural network. The energy " - "obtained by an attacker cell is distributed to nearby constructor or transmitter cells."); - drawParagraph("To perform movements, an organism requires muscle cells. These are also controlled by signals. Muscle cells can work in " - "various modes: they can bend, contract/expand, or generate an impulse."); - drawParagraph("For the perception of the environment, sensor cells are available. When such a cell is triggered by a signal, it provide " + "obtained by an attacker cell is distributed to nearby constructor or transmitter cells.")); + drawParagraph(_("To perform movements, an organism requires muscle cells. These are also controlled by signals. Muscle cells can work in " + "various modes: they can bend, contract/expand, or generate an impulse.")); + drawParagraph(_("For the perception of the environment, sensor cells are available. When such a cell is triggered by a signal, it provide " "information about the relative position of cell concentrations with respect to a specific color, which can be further processed by e.g. " - "cell with neural network."); + "cell with neural network.")); - drawHeading2("Why does the radiation source generates no energy particles?"); - drawParagraph("The principle of energy conservation holds true in a simulation, which means that energy particles cannot spontaneously come into " + drawHeading2(_("Why does the radiation source generates no energy particles?")); + drawParagraph(_("The principle of energy conservation holds true in a simulation, which means that energy particles cannot spontaneously come into " "existence out of nothingness. This principle plays a vital role in ensuring the stability of long-term simulations. If a radiation " "source is defined, it will emit a particle only when a cell somewhere loses energy. Conversely, in the absence of a radiation source, " - "any emitted energy particle would originate directly in the spatial vicinity of the corresponding object."); - drawParagraph("The existence of matter in the form of cells is a prerequisite for the radiation source to emit particles. Furthermore, the simulation " - "parameters should be adjusted in a way that guarantees a gradual loss of energy from cells over time."); + "any emitted energy particle would originate directly in the spatial vicinity of the corresponding cell.")); + drawParagraph(_("The existence of matter in the form of cells is a prerequisite for the radiation source to emit particles. Furthermore, the simulation " + "parameters should be adjusted in a way that guarantees a gradual loss of energy from cells over time.")); - drawHeading2("How can neural networks be incorporated?"); - drawParagraph("Neural networks are available as cell functions. If a cell is assigned the function 'Neuron', it possesses a small neural network " + drawHeading2(_("How can neural networks be incorporated?")); + drawParagraph(_("Neural networks are available as cell functions. If a cell is assigned the function 'Neuron', it possesses a small neural network " "consisting of 8 neurons. However, these networks can be interconnected to form arbitrarily large networks, as each cell receives input " - "from the output of certain connected cells."); - drawParagraph("Furthermore, these networks can be fed by sensors and, in turn, control muscle and attacker cells."); + "from the output of certain connected cells.")); + drawParagraph(_("Furthermore, these networks can be fed by sensors and, in turn, control muscle and attacker cells.")); - drawHeading2("For how long should I run a simulation to see evolutionary changes?"); - drawParagraph( + drawHeading2(_("For how long should I run a simulation to see evolutionary changes?")); + drawParagraph(_( "This depends on many factors: On the size of the simulated world, on the mutation rates, on various selection pressures that can be influenced " - "by the simulation parameters and on the self-replication duration. Usually one should wait for several dozen generations, which may correspond to " - "hundreds of thousands or million time steps." - "In small worlds with smaller organisms and high mutation rates, evolutionary changes can sometimes be observed every minute depending on the " - "hardware. With more complex " - "simulations, you should rather expect a few hours."); - - drawHeading2("How can I add energy to a simulation?"); - drawParagraph( - "Adding energy to a simulation can increase the available resources and thus the population. There is a convenient way to directly feed " - "all constructor cells with additional energy. This can be achieved by enabling the 'External energy control' expert settings in the simulation " - "parameter window. Next, set the amount of energy to be added (for instance, 1M could sustain 10K cells if each cell has 100 energy " - "units). The external energy is not added instantly but at a rate that can be specified under 'inflow'."); - - drawHeading2("How can I create a cell signal in the first place?"); - drawParagraph("To activate most cell functions, an input from a connected cell in the form of a signal is required. The simplest methods " - "to generate a signal are as follows:"); - drawItemText("The most direct approach involves using a generator cell that generates an signal at regular time intervals. The advantage here is that " - "you can precisely configure the length of the time intervals."); - drawItemText("Signals can also be generated within a neuron cell using bias values."); - drawParagraph("Additionally, other cells such as constructor cells provide an output signal as soon as they are triggered (automatically)."); + "by the simulation parameters and on the self-replication duration. Usually one should wait for several dozen generations, which may correspond to hundreds of thousands or million time steps." + "In small worlds with smaller organisms and high mutation rates, evolutionary changes can sometimes be observed every minute depending on the hardware. With more complex " + "simulations, you should rather expect a few hours.")); + + drawHeading2(_("How can I add energy to a simulation?")); + drawParagraph(_("Adding energy to a simulation can increase the available resources and thus the population. There is a convenient way to directly feed " + "all constructor cells with additional energy. This can be achieved by enabling the 'External energy control' expert settings in the simulation " + "parameter window. Next, set the amount of energy to be added (for instance, 1M could sustain 10K cells if each cell has 100 energy " + "units). The external energy is not added instantly but at a rate that can be specified under 'inflow'.")); + + drawHeading2(_("How can I create a cell signal in the first place?")); + drawParagraph(_("To activate most cell functions, an input from a connected cell in the form of a signal is required. The simplest methods " + "to generate a signal are as follows:")); + drawItemText(_("The most direct approach involves using a nerve cell that generates an signal at regular time intervals. The advantage here is that " + "you can precisely configure the length of the time intervals.")); + drawItemText(_("Signals can also be generated within a neuron cell using bias values.")); + drawParagraph(_("Additionally, other cells such as constructor cells provide an output signal as soon as they are triggered (automatically).")); //ImGui::Text("There is a lot to explore. ALIEN features an extensive graph and particle editor in order to build custom worlds with desired " // "environmental structures and machines. A documentation with tutorial-like introductions to various topics can be found at"); @@ -420,40 +414,31 @@ void GettingStartedWindow::drawTitle() ImGui::PopFont(); ImGui::SameLine(); - AlienGui::MoveTickLeft(); ImGui::PushFont(StyleRepository::get().getMediumBoldFont()); ImGui::Text("%s", _("A")); ImGui::PopFont(); ImGui::SameLine(); - AlienGui::MoveTickLeft(); - AlienGui::MoveTickLeft(); ImGui::PushFont(StyleRepository::get().getMediumFont()); ImGui::Text("%s", _("rtificial ")); ImGui::PopFont(); ImGui::SameLine(); - AlienGui::MoveTickLeft(); ImGui::PushFont(StyleRepository::get().getMediumBoldFont()); ImGui::Text("%s", _("LI")); ImGui::PopFont(); ImGui::SameLine(); - AlienGui::MoveTickLeft(); - AlienGui::MoveTickLeft(); ImGui::PushFont(StyleRepository::get().getMediumFont()); ImGui::Text("%s", _("fe ")); ImGui::PopFont(); ImGui::SameLine(); - AlienGui::MoveTickLeft(); ImGui::PushFont(StyleRepository::get().getMediumBoldFont()); ImGui::Text("%s", _("EN")); ImGui::PopFont(); ImGui::SameLine(); - AlienGui::MoveTickLeft(); - AlienGui::MoveTickLeft(); ImGui::PushFont(StyleRepository::get().getMediumFont()); ImGui::Text("%s", _("vironment ?")); ImGui::PopFont(); @@ -466,7 +451,7 @@ void GettingStartedWindow::drawHeading1(std::string const& text) { AlienGui::Separator(); ImGui::PushStyleColor(ImGuiCol_Text, (ImU32)Const::HeadlineColor); - AlienGui::Text(AlienGui::TextParameters().text(text).style(AlienGui::TextStyle::Bold)); + AlienGui::Text(text); ImGui::PopStyleColor(); AlienGui::Separator(); } @@ -474,7 +459,7 @@ void GettingStartedWindow::drawHeading1(std::string const& text) void GettingStartedWindow::drawHeading2(std::string const& text) { ImGui::Spacing(); - AlienGui::Text(AlienGui::TextParameters().text(text).style(AlienGui::TextStyle::Bold)); + AlienGui::Text(text); } void GettingStartedWindow::drawItemText(std::string const& text) @@ -488,3 +473,4 @@ void GettingStartedWindow::drawParagraph(std::string const& text) { AlienGui::Text(text); } + \ No newline at end of file diff --git a/source/Gui/MainLoopController.cpp b/source/Gui/MainLoopController.cpp index 5f7d49413..089bf052f 100644 --- a/source/Gui/MainLoopController.cpp +++ b/source/Gui/MainLoopController.cpp @@ -306,9 +306,9 @@ void MainLoopController::drawLoadingScreen() ImColor textColor = Const::ProgramVersionTextColor; textColor.Value.w *= ImGui::GetStyle().Alpha; - drawList->AddText(styleRep.getReefLargeFont(), scale(48.0f), {center.x - scale(175), bottom - scale(200)}, textColor, "Artificial Life Environment"); + drawList->AddText(styleRep.getReefLargeFont(), scale(48.0f), {center.x - scale(175), bottom - scale(200)}, textColor, _("Artificial Life Environment")); - auto versionString = "Version " + Const::ProgramVersion; + auto versionString = std::string(_("Version ")) + Const::ProgramVersion; drawList->AddText( styleRep.getReefMediumFont(), scale(24.0f), From 6ad221ac2dc19102d98ddcb191f3dc07148b7315 Mon Sep 17 00:00:00 2001 From: zysftd Date: Sun, 12 Jul 2026 20:50:22 +0800 Subject: [PATCH 07/15] fix: resolve duplicate translations causing ImGui ID conflicts --- source/Gui/translations/zh.json | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/source/Gui/translations/zh.json b/source/Gui/translations/zh.json index 31d7b9830..3d94affa3 100644 --- a/source/Gui/translations/zh.json +++ b/source/Gui/translations/zh.json @@ -91,7 +91,7 @@ "A genome describes a network of connected cells. On the one hand, there is the option to select a pre-defined geometry (e.g. ": "相反,如果实际角度更小,则切向力倾向于增大此角度。通过这种力,细胞网络在变形后可以折叠回期望的形状。", "A high frame rate leads to a greater GPU workload for rendering and thus lowers the simulation speed (time steps per second).": "高帧率会增加 GPU 渲染负载,从而降低仿真速度(每秒时间步数)。", "A high value protects new mutants with equal or greater genome complexity from being attacked.": "较高值保护具有相同或更高基因组复杂度的新突变体免受攻击。", - "A pattern is a set of cell networks and energy particles.": "细胞特定参数", + "A pattern is a set of cell networks and energy particles.": "模式是一组细胞网络和能量粒子。", "A reconnector cell can make or break a cell connection to an other cell (with a different creature id) with a specified color. \n\n": "它们从执行序号与当前细胞输入执行序号匹配的连接细胞处获取输入。", "ALIEN is an artificial life and physics simulation tool based on a CUDA-powered 2D particle engine for soft bodies and fluids.": "ALIEN 是一款基于 CUDA 加速的二维粒子引擎的人工生命与物理模拟工具,专为软体和流体设计。", "About": "关于", @@ -105,7 +105,7 @@ "Add a reaction": "添加反应", "Add parameter zone": "添加参数区", "Add radiation source": "添加辐射源", - "Adopt": "取消", + "Adopt": "采纳", "Adopt simulation parameters": "采用仿真参数", "Advanced absorption control": "高级吸收控制", "Advanced attacker control": "高级攻击控制", @@ -126,7 +126,7 @@ "Anti-injector strength": "反注射强度", "Anti-injector: increases the injection duration of an enemy injector cell": "网络中连接细胞的三元组彼此之间具有特定的空间角度。这些角度由细胞中编码的参考角度引导。", "As a result, you will be able to see the GPU information of other registered users who have shared it.": "绝对值函数", - "Attack radius": "能量消耗", + "Attack radius": "攻击半径", "Attack strength": "攻击细胞可以攻击其他细胞的最大距离。", "Attack visualization": "攻击可视化", "Attacker": "攻击器", @@ -140,7 +140,7 @@ "Base": "基础", "Base parameters": "基础参数", "Basic notion": "基本概念", - "Bending angle": "弯曲加速度", + "Bending angle": "弯曲角度", "Bias": "偏置", "Binary step": "有三个不同的工作区,您可以在其中找到并可选择上传模拟和基因组:\n\n", "Binding creation velocity": "连接创建速度", @@ -169,7 +169,7 @@ "Cell colors": "细胞颜色", "Cell connection": "细胞连接", "Cell count": "细胞数", - "Cell death consequences": "无", + "Cell death consequences": "细胞死亡后果", "Cell deletion": "细胞删除", "Cell distance": "细胞间距", "Cell function": "细胞功能", @@ -220,7 +220,7 @@ "Color #4": "颜色 #4", "Color #5": "颜色 #5", "Color #6": "颜色 #6", - "Color inhomogeneity factor": "能量分配值", + "Color inhomogeneity factor": "颜色不均匀因子", "Color transition rule": "颜色转换规则", "Color transitions": "颜色转换", "Coloring": "着色", @@ -230,7 +230,7 @@ "Conditional inflow": "\n\n例如,值为 0.6 表示构建器细胞从外部能源获得构建新细胞所需能量的 60%,", "Connected cells": "已连接的细胞", "Connection distance": "连接距离", - "Connections mismatch penalty": "能量分配半径", + "Connections mismatch penalty": "连接不匹配惩罚", "Constructor": "构建器", "Contained energy": "含能量", "Contraction and expansion delta": "肌肉细胞可缩短或伸长细胞连接的最大长度。此参数仅适用于收缩/伸展模式的肌肉细胞。", @@ -276,7 +276,7 @@ "Delete selected zone/radiation source": "删除选中的区/辐射源", "Delete user": "删除用户", "Deleting save point ...": "正在删除存档点...", - "Depth level": "神经元因子", + "Depth level": "深度层", "Description": "描述", "Description (optional)": "描述(可选)", "Desktop": "桌面", @@ -300,7 +300,7 @@ "Draws borders along the world before it repeats itself.": "在世界重复自身之前沿边界绘制边框。", "Draws red crosses in the center of radiation sources.": "在辐射源中心绘制红色十字标记。", "Drift angle": "漂移角", - "Duplication": "复制", + "Duplication": "重复", "Each generated cell has an 'execution order number' that is one greater than the previous generated cell.": "圆盘的外半径(以细胞计)。", "Each neuron has 8 input channels and produces an output by the formula output_j = sigma((sum_i (input_i * weight_ji) + ": "此值指定构建细胞自动触发的时间间隔。它以 6 的倍数给出(6 为一个完整的执行周期)。", "Editors": "编辑器", @@ -350,7 +350,7 @@ "Frames per second": "每秒帧数", "Free cells": "自由细胞", "Frequently asked questions": "常见问题", - "Friction": "刚性", + "Friction": "摩擦", "Full screen": "全屏", "Fusion velocity": "融合速度", "GPU (visible if logged in)": "GPU(登录后可见)", @@ -436,7 +436,7 @@ "It enables further settings for deletion mutations. If disabled, defaults are used (displayed in the tooltip of the specific parameters).": "启用删除突变的进一步设置。若禁用,使用默认值。", "It enables further settings for neuron mutations. If disabled, defaults are used (displayed in the tooltip of the specific parameters).": "启用神经元突变的进一步设置。若禁用,使用默认值。", "Layers": "层数", - "Limited save files": "文件数量", + "Limited save files": "限制存档文件数", "Linear": "线性", "Living state": "存活状态", "Load previous time step": "加载上一个时间步", @@ -488,7 +488,7 @@ "Minimum size": "最小尺寸", "Minimum split energy": "最小分裂能量", "Minimum value": "最小值", - "Mode": "无限存档文件", + "Mode": "模式", "More": "更多", "Motion blur": "动态模糊", "Motion type": "运动类型", @@ -1021,7 +1021,7 @@ "Cells can exist in various states. When a cell network of the organism is being constructed, its cells are in the 'Under construction' state. Once the cell network ": "细胞可存在于多种状态。当生物体的细胞网络正在构建时,其细胞处于'构建中'状态。一旦细胞网络", "Code (case sensitive)": "验证码(区分大小写)", "DEBUG": "调试", - "Deletion": "删除", + "Deletion": "缺失", "Distance": "距离", "For how long should I run a simulation to see evolutionary changes?": "我应该运行仿真多长时间才能看到进化变化?", "Furthermore, these networks can be fed by sensors and, in turn, control muscle and attacker cells.": "此外,这些网络可以由传感器提供输入,进而控制肌肉和攻击细胞。", From 833df1556fc8262426d630261729e14772dd5a75 Mon Sep 17 00:00:00 2001 From: zysftd Date: Sun, 12 Jul 2026 20:52:13 +0800 Subject: [PATCH 08/15] fix: title spacing and Adopt translation --- source/Gui/GettingStartedWindow.cpp | 12 ++++++------ source/Gui/translations/zh.json | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/source/Gui/GettingStartedWindow.cpp b/source/Gui/GettingStartedWindow.cpp index b7e12a806..d9cb5b110 100644 --- a/source/Gui/GettingStartedWindow.cpp +++ b/source/Gui/GettingStartedWindow.cpp @@ -413,32 +413,32 @@ void GettingStartedWindow::drawTitle() ImGui::Text("%s", _("What is ")); ImGui::PopFont(); - ImGui::SameLine(); + ImGui::SameLine(0, 0); ImGui::PushFont(StyleRepository::get().getMediumBoldFont()); ImGui::Text("%s", _("A")); ImGui::PopFont(); - ImGui::SameLine(); + ImGui::SameLine(0, 0); ImGui::PushFont(StyleRepository::get().getMediumFont()); ImGui::Text("%s", _("rtificial ")); ImGui::PopFont(); - ImGui::SameLine(); + ImGui::SameLine(0, 0); ImGui::PushFont(StyleRepository::get().getMediumBoldFont()); ImGui::Text("%s", _("LI")); ImGui::PopFont(); - ImGui::SameLine(); + ImGui::SameLine(0, 0); ImGui::PushFont(StyleRepository::get().getMediumFont()); ImGui::Text("%s", _("fe ")); ImGui::PopFont(); - ImGui::SameLine(); + ImGui::SameLine(0, 0); ImGui::PushFont(StyleRepository::get().getMediumBoldFont()); ImGui::Text("%s", _("EN")); ImGui::PopFont(); - ImGui::SameLine(); + ImGui::SameLine(0, 0); ImGui::PushFont(StyleRepository::get().getMediumFont()); ImGui::Text("%s", _("vironment ?")); ImGui::PopFont(); diff --git a/source/Gui/translations/zh.json b/source/Gui/translations/zh.json index 3d94affa3..1b03896b7 100644 --- a/source/Gui/translations/zh.json +++ b/source/Gui/translations/zh.json @@ -105,7 +105,7 @@ "Add a reaction": "添加反应", "Add parameter zone": "添加参数区", "Add radiation source": "添加辐射源", - "Adopt": "采纳", + "Adopt": "应用", "Adopt simulation parameters": "采用仿真参数", "Advanced absorption control": "高级吸收控制", "Advanced attacker control": "高级攻击控制", From 2e45a49baf05b118b1f18ec5bbc4a2b4949ea0eb Mon Sep 17 00:00:00 2001 From: zysftd Date: Sun, 12 Jul 2026 20:54:42 +0800 Subject: [PATCH 09/15] fix: translate browser status bar strings --- source/Gui/BrowserWindow.cpp | 12 ++++++------ source/Gui/translations/zh.json | 3 ++- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/source/Gui/BrowserWindow.cpp b/source/Gui/BrowserWindow.cpp index fba49ccc4..fcc5eaa7a 100644 --- a/source/Gui/BrowserWindow.cpp +++ b/source/Gui/BrowserWindow.cpp @@ -538,17 +538,17 @@ void BrowserWindow::processStatusBar() auto numSimulations = toInt(simulations.size()); auto numGenomes = toInt(genomes.size()); - statusItems.emplace_back(std::to_string(numSimulations) + " simulations found"); - statusItems.emplace_back(std::to_string(numGenomes) + " genomes found"); - statusItems.emplace_back(std::to_string(_userTOs.size()) + " simulators found"); + statusItems.emplace_back(std::to_string(numSimulations) + _(" simulations found")); + statusItems.emplace_back(std::to_string(numGenomes) + _(" genomes found")); + statusItems.emplace_back(std::to_string(_userTOs.size()) + _(" simulators found")); if (auto userName = NetworkService::get().getLoggedInUserName()) { - statusItems.emplace_back("Logged in as " + *userName); + statusItems.emplace_back(std::string(_("Logged in as ")) + *userName); } else { - statusItems.emplace_back("Not logged in to " + NetworkService::get().getServerAddress()); + statusItems.emplace_back(std::string(_("Not logged in to ")) + NetworkService::get().getServerAddress()); } - statusItems.emplace_back("Server: " + NetworkService::get().getServerAddress()); + statusItems.emplace_back(std::string(_("Server: ")) + NetworkService::get().getServerAddress()); if (!NetworkService::get().getLoggedInUserName()) { statusItems.emplace_back(_("In order to share and upvote simulations you need to log in.")); diff --git a/source/Gui/translations/zh.json b/source/Gui/translations/zh.json index 1b03896b7..9f6b540f4 100644 --- a/source/Gui/translations/zh.json +++ b/source/Gui/translations/zh.json @@ -1194,5 +1194,6 @@ "public": "公开", "private": "私有", "alien-project": "alien-project", - "simulations": "仿真" + "simulations": "仿真", + "Server: ": "服务器:" } \ No newline at end of file From 092ff6c9d04313b6adbce53fee8cfbff6fe564f2 Mon Sep 17 00:00:00 2001 From: zysftd Date: Sun, 12 Jul 2026 20:57:21 +0800 Subject: [PATCH 10/15] fix: translate New Simulation dialog strings --- source/Gui/NewSimulationDialog.cpp | 2 ++ source/Gui/translations/zh.json | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/source/Gui/NewSimulationDialog.cpp b/source/Gui/NewSimulationDialog.cpp index 9b3e169fd..a3ada6374 100644 --- a/source/Gui/NewSimulationDialog.cpp +++ b/source/Gui/NewSimulationDialog.cpp @@ -61,6 +61,8 @@ void NewSimulationDialog::processIntern() void NewSimulationDialog::openIntern() { + strncpy(_projectName, _(""), sizeof(_projectName) - 1); + _projectName[sizeof(_projectName) - 1] = '\0'; auto worldSize = _SimulationFacade::get()->getWorldSize(); _width = worldSize.x; _height = worldSize.y; diff --git a/source/Gui/translations/zh.json b/source/Gui/translations/zh.json index 9f6b540f4..31607caa4 100644 --- a/source/Gui/translations/zh.json +++ b/source/Gui/translations/zh.json @@ -1195,5 +1195,7 @@ "private": "私有", "alien-project": "alien-project", "simulations": "仿真", - "Server: ": "服务器:" + "Server: ": "服务器:", + "Adopt parameters": "应用参数", + "": "<未命名仿真>" } \ No newline at end of file From 9364ba193028a3d0ae5d7f39c736b9460428041e Mon Sep 17 00:00:00 2001 From: zysftd Date: Sun, 12 Jul 2026 21:00:02 +0800 Subject: [PATCH 11/15] fix: translate file dialog strings --- source/Gui/FileTransferController.cpp | 16 ++++++++-------- source/Gui/SimulationParametersMainWindow.cpp | 14 +++++++------- source/Gui/translations/zh.json | 7 ++++++- 3 files changed, 21 insertions(+), 16 deletions(-) diff --git a/source/Gui/FileTransferController.cpp b/source/Gui/FileTransferController.cpp index aabeff316..944ced7d3 100644 --- a/source/Gui/FileTransferController.cpp +++ b/source/Gui/FileTransferController.cpp @@ -19,7 +19,7 @@ void FileTransferController::onOpenSimulationDialog() { GenericFileDialog::get().showOpenFileDialog( - "Open simulation", "Simulation file (*.sim){.sim},.*", _referencePath, [&](std::filesystem::path const& filename) { + _("Open simulation"), "Simulation file (*.sim){.sim},.*", _referencePath, [&](std::filesystem::path const& filename) { auto filenameCopy = filename; _referencePath = filenameCopy.remove_filename().string(); onOpenSimulation(filename); @@ -58,7 +58,7 @@ void FileTransferController::onOpenSimulation(std::filesystem::path const& filen } if (errorMessage) { - showMessage("Error", *errorMessage); + showMessage(_("Error"), *errorMessage); _SimulationFacade::get()->closeSimulation(); _SimulationFacade::get()->newSimulation( data.deserializedSimulation.auxiliaryData.timestep, @@ -77,7 +77,7 @@ void FileTransferController::onOpenSimulation(std::filesystem::path const& filen void FileTransferController::onSaveSimulationDialog() { - GenericFileDialog::get().showSaveFileDialog("Save simulation", "Simulation file (*.sim){.sim},.*", _referencePath, [&](std::filesystem::path const& path) { + GenericFileDialog::get().showSaveFileDialog(_("Save simulation"), "Simulation file (*.sim){.sim},.*", _referencePath, [&](std::filesystem::path const& path) { auto firstFilename = ifd::FileDialog::Instance().GetResult(); auto firstFilenameCopy = firstFilename; _referencePath = firstFilenameCopy.remove_filename().string(); @@ -89,14 +89,14 @@ void FileTransferController::onSaveSimulationDialog() return _PersisterFacade::get()->scheduleSaveSimulation(senderInfo, readData); }, [](auto const&) {}, - [](auto const& criticalErrors) { GenericMessageDialog::get().information("Error", criticalErrors); }); + [](auto const& criticalErrors) { GenericMessageDialog::get().information(_("Error"), criticalErrors); }); }); } void FileTransferController::onOpenGenomeDialog(std::function const& openFunc) { GenericFileDialog::get().showOpenFileDialog( - "Open genome", + _("Open genome"), "Genome (*.genome){.genome},.*", _referencePath, [&, openFunc = openFunc](std::filesystem::path const& path) { @@ -105,7 +105,7 @@ void FileTransferController::onOpenGenomeDialog(std::function const& afterSaveFunc) { GenericFileDialog::get().showSaveFileDialog( - "Save genome", "Genome (*.genome){.genome},.*", _referencePath, [&, genome = genome, afterSaveFunc = afterSaveFunc](std::filesystem::path const& path) { + _("Save genome"), "Genome (*.genome){.genome},.*", _referencePath, [&, genome = genome, afterSaveFunc = afterSaveFunc](std::filesystem::path const& path) { auto firstFilename = ifd::FileDialog::Instance().GetResult(); auto firstFilenameCopy = firstFilename; _referencePath = firstFilenameCopy.remove_filename().string(); if (!SerializerService::get().serializeGenomeToFile(firstFilename.string(), genome)) { - GenericMessageDialog::get().information("Save genome", "The selected file could not be saved."); + GenericMessageDialog::get().information(_("Save genome"), _("The selected file could not be saved.")); } else if (afterSaveFunc) { afterSaveFunc(); } diff --git a/source/Gui/SimulationParametersMainWindow.cpp b/source/Gui/SimulationParametersMainWindow.cpp index 30434a4f7..bcb09358a 100644 --- a/source/Gui/SimulationParametersMainWindow.cpp +++ b/source/Gui/SimulationParametersMainWindow.cpp @@ -142,7 +142,7 @@ void SimulationParametersMainWindow::processToolbar() printOverlayMessage(_("Reference simulation parameters replaced")); } else { GenericMessageDialog::get().information( - "Error", "The number of layers and radiation sources of the current simulation parameters must match with those from the clipboard."); + _("Error"), _("The number of layers and radiation sources of the current simulation parameters must match with those from the clipboard.")); } } @@ -431,14 +431,14 @@ void SimulationParametersMainWindow::processExpertSettings() void SimulationParametersMainWindow::onOpenParameters() { GenericFileDialog::get().showOpenFileDialog( - "Open simulation parameters", "Simulation parameters (*.parameters){.parameters},.*", _fileDialogPath, [&](std::filesystem::path const& path) { + _("Open simulation parameters"), "Simulation parameters (*.parameters){.parameters},.*", _fileDialogPath, [&](std::filesystem::path const& path) { auto firstFilename = ifd::FileDialog::Instance().GetResult(); auto firstFilenameCopy = firstFilename; _fileDialogPath = firstFilenameCopy.remove_filename().string(); SimulationParameters parameters; if (!SerializerService::get().deserializeSimulationParametersFromFile(parameters, firstFilename.string())) { - GenericMessageDialog::get().information("Open simulation parameters", "The selected file could not be opened."); + GenericMessageDialog::get().information(_("Open simulation parameters"), _("The selected file could not be opened.")); } else { _SimulationFacade::get()->setSimulationParameters(parameters); _SimulationFacade::get()->setOriginalSimulationParameters(parameters); @@ -449,14 +449,14 @@ void SimulationParametersMainWindow::onOpenParameters() void SimulationParametersMainWindow::onSaveParameters() { GenericFileDialog::get().showSaveFileDialog( - "Save simulation parameters", "Simulation parameters (*.parameters){.parameters},.*", _fileDialogPath, [&](std::filesystem::path const& path) { + _("Save simulation parameters"), "Simulation parameters (*.parameters){.parameters},.*", _fileDialogPath, [&](std::filesystem::path const& path) { auto firstFilename = ifd::FileDialog::Instance().GetResult(); auto firstFilenameCopy = firstFilename; _fileDialogPath = firstFilenameCopy.remove_filename().string(); auto parameters = _SimulationFacade::get()->getSimulationParameters(); if (!SerializerService::get().serializeSimulationParametersToFile(firstFilename.string(), parameters)) { - GenericMessageDialog::get().information("Save simulation parameters", "The selected file could not be saved."); + GenericMessageDialog::get().information(_("Save simulation parameters"), _("The selected file could not be saved.")); } }); } @@ -706,7 +706,7 @@ void SimulationParametersMainWindow::correctLayout(float origMasterHeight, float bool SimulationParametersMainWindow::checkNumLayers(SimulationParameters const& parameters) { if (parameters.numLayers == MAX_LAYERS) { - showMessage("Error", "The maximum number of layers has been reached."); + showMessage(_("Error"), _("The maximum number of layers has been reached.")); return false; } return true; @@ -715,7 +715,7 @@ bool SimulationParametersMainWindow::checkNumLayers(SimulationParameters const& bool SimulationParametersMainWindow::checkNumSources(SimulationParameters const& parameters) { if (parameters.numSources == MAX_SOURCES) { - showMessage("Error", "The maximum number of radiation sources has been reached."); + showMessage(_("Error"), _("The maximum number of radiation sources has been reached.")); return false; } return true; diff --git a/source/Gui/translations/zh.json b/source/Gui/translations/zh.json index 31607caa4..18b014b30 100644 --- a/source/Gui/translations/zh.json +++ b/source/Gui/translations/zh.json @@ -1197,5 +1197,10 @@ "simulations": "仿真", "Server: ": "服务器:", "Adopt parameters": "应用参数", - "": "<未命名仿真>" + "": "<未命名仿真>", + "Open simulation": "Open simulation", + "Save simulation": "Save simulation", + "Open genome": "Open genome", + "Save genome": "Save genome", + "Failed to load simulation.": "Failed to load simulation." } \ No newline at end of file From e465b09381596e03a260db64283ab0d99cb40720 Mon Sep 17 00:00:00 2001 From: zysftd Date: Sun, 12 Jul 2026 21:07:24 +0800 Subject: [PATCH 12/15] fix: translate remaining file dialog and tooltip strings --- source/Gui/GenomeEditorWindow.cpp | 4 ++-- source/Gui/ImageToPatternDialog.cpp | 2 +- source/Gui/PatternEditorWindow.cpp | 4 ++-- source/Gui/translations/zh.json | 12 +++++++----- 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/source/Gui/GenomeEditorWindow.cpp b/source/Gui/GenomeEditorWindow.cpp index 575e2b3b8..e0eada952 100644 --- a/source/Gui/GenomeEditorWindow.cpp +++ b/source/Gui/GenomeEditorWindow.cpp @@ -94,12 +94,12 @@ bool GenomeEditorWindow::isShown() void GenomeEditorWindow::processToolbar() { - if (AlienGui::ToolbarButton(AlienGui::ToolbarButtonParameters().text(ICON_FA_FOLDER_OPEN).tooltip("Open genome from file"))) { + if (AlienGui::ToolbarButton(AlienGui::ToolbarButtonParameters().text(ICON_FA_FOLDER_OPEN).tooltip(_("Open genome from file")))) { onOpenGenome(); } ImGui::SameLine(); - if (AlienGui::ToolbarButton(AlienGui::ToolbarButtonParameters().text(ICON_FA_SAVE).tooltip("Save genome to file"))) { + if (AlienGui::ToolbarButton(AlienGui::ToolbarButtonParameters().text(ICON_FA_SAVE).tooltip(_("Save genome to file")))) { onSaveGenome(); } diff --git a/source/Gui/ImageToPatternDialog.cpp b/source/Gui/ImageToPatternDialog.cpp index 4bacf6c34..bbc73cef3 100644 --- a/source/Gui/ImageToPatternDialog.cpp +++ b/source/Gui/ImageToPatternDialog.cpp @@ -76,7 +76,7 @@ namespace void ImageToPatternDialog::show() { - GenericFileDialog::get().showOpenFileDialog("Open image", "Image (*.png){.png},.*", _startingPath, [&](std::filesystem::path const& path) { + GenericFileDialog::get().showOpenFileDialog(_("Open image"), "Image (*.png){.png},.*", _startingPath, [&](std::filesystem::path const& path) { auto const& customizationColors = _SimulationFacade::get()->getSimulationParameters().customizationColors.value; auto firstFilename = ifd::FileDialog::Instance().GetResult(); auto firstFilenameCopy = firstFilename; diff --git a/source/Gui/PatternEditorWindow.cpp b/source/Gui/PatternEditorWindow.cpp index 452dcaef8..6461f2a4b 100644 --- a/source/Gui/PatternEditorWindow.cpp +++ b/source/Gui/PatternEditorWindow.cpp @@ -274,7 +274,7 @@ bool PatternEditorWindow::isShown() void PatternEditorWindow::onOpenPattern() { - GenericFileDialog::get().showOpenFileDialog("Open pattern", "Pattern file (*.sim){.sim},.*", _startingPath, [&](std::filesystem::path const& path) { + GenericFileDialog::get().showOpenFileDialog(_("Open pattern"), "Pattern file (*.sim){.sim},.*", _startingPath, [&](std::filesystem::path const& path) { auto firstFilename = ifd::FileDialog::Instance().GetResult(); auto firstFilenameCopy = firstFilename; _startingPath = firstFilenameCopy.remove_filename().string(); @@ -285,7 +285,7 @@ void PatternEditorWindow::onOpenPattern() _SimulationFacade::get()->addAndSelectSimulationData(Desc(content)); EditorModel::get().update(); } else { - GenericMessageDialog::get().information("Open pattern", "The selected file could not be opened."); + GenericMessageDialog::get().information(_("Open pattern"), _("The selected file could not be opened.")); } }); } diff --git a/source/Gui/translations/zh.json b/source/Gui/translations/zh.json index 18b014b30..9be20644c 100644 --- a/source/Gui/translations/zh.json +++ b/source/Gui/translations/zh.json @@ -1198,9 +1198,11 @@ "Server: ": "服务器:", "Adopt parameters": "应用参数", "": "<未命名仿真>", - "Open simulation": "Open simulation", - "Save simulation": "Save simulation", - "Open genome": "Open genome", - "Save genome": "Save genome", - "Failed to load simulation.": "Failed to load simulation." + "Open simulation": "打开仿真", + "Save simulation": "保存仿真", + "Open genome": "打开基因组", + "Save genome": "保存基因组", + "Failed to load simulation.": "Failed to load simulation.", + "Open genome from file": "从文件打开基因组", + "Save genome to file": "将基因组保存到文件" } \ No newline at end of file From ca32be3019b03aece1df3e72ed39f9b646e842e9 Mon Sep 17 00:00:00 2001 From: zysftd Date: Sun, 12 Jul 2026 21:10:51 +0800 Subject: [PATCH 13/15] fix: localize ImFileDialog buttons (Save/Open/Cancel/OK) --- external/ImFileDialog/ImFileDialog.cpp | 16 +++++++++------- source/Gui/translations/zh.json | 3 ++- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/external/ImFileDialog/ImFileDialog.cpp b/external/ImFileDialog/ImFileDialog.cpp index ab605afa9..f411ddd2b 100644 --- a/external/ImFileDialog/ImFileDialog.cpp +++ b/external/ImFileDialog/ImFileDialog.cpp @@ -12,6 +12,8 @@ #include #include +#include "../../source/Gui/TranslationService.h" + #define STB_IMAGE_IMPLEMENTATION #include "stb_image.h" @@ -1252,18 +1254,18 @@ namespace ifd { ImGui::CloseCurrentPopup(); } ImGui::SameLine(); - if (ImGui::Button("Cancel")) { + if (ImGui::Button(_("Cancel"))) { m_newEntryBuffer[0] = 0; ImGui::CloseCurrentPopup(); } ImGui::EndPopup(); } - if (ImGui::BeginPopupModal("Enter directory name##newdir")) { + if (ImGui::BeginPopupModal((std::string(_("Enter directory name")) + "##newdir").c_str())) { ImGui::PushItemWidth(250.0f); - ImGui::InputText("##newfilename", m_newEntryBuffer, 1024); // TODO: remove hardcoded literals + ImGui::InputText("##newfilename", m_newEntryBuffer, 1024); ImGui::PopItemWidth(); - if (ImGui::Button("OK")) { + if (ImGui::Button(_("OK"))) { std::error_code ec; std::filesystem::create_directory(m_currentDirectory / std::string(m_newEntryBuffer), ec); m_setDirectory(m_currentDirectory, false); // refresh @@ -1271,7 +1273,7 @@ namespace ifd { ImGui::CloseCurrentPopup(); } ImGui::SameLine(); - if (ImGui::Button("Cancel")) { + if (ImGui::Button(_("Cancel"))) { ImGui::CloseCurrentPopup(); m_newEntryBuffer[0] = 0; } @@ -1385,7 +1387,7 @@ namespace ifd { // buttons ImGui::SetCursorPosX(ImGui::GetWindowWidth() - 250); - if (ImGui::Button(m_type == IFD_DIALOG_SAVE ? "Save" : "Open", ImVec2(250 / 2 - ImGui::GetStyle().ItemSpacing.x, 0.0f))) { + if (ImGui::Button(m_type == IFD_DIALOG_SAVE ? _("Save") : _("Open"), ImVec2(250 / 2 - ImGui::GetStyle().ItemSpacing.x, 0.0f))) { std::u8string filename(m_inputTextbox); bool success = false; if (!filename.empty() || m_type == IFD_DIALOG_DIRECTORY) @@ -1396,7 +1398,7 @@ namespace ifd { #endif } ImGui::SameLine(); - if (ImGui::Button("Cancel", ImVec2(-FLT_MIN, 0.0f))) + if (ImGui::Button(_("Cancel"), ImVec2(-FLT_MIN, 0.0f))) m_finalize(); } } diff --git a/source/Gui/translations/zh.json b/source/Gui/translations/zh.json index 9be20644c..6277b950e 100644 --- a/source/Gui/translations/zh.json +++ b/source/Gui/translations/zh.json @@ -1204,5 +1204,6 @@ "Save genome": "保存基因组", "Failed to load simulation.": "Failed to load simulation.", "Open genome from file": "从文件打开基因组", - "Save genome to file": "将基因组保存到文件" + "Save genome to file": "将基因组保存到文件", + "Enter directory name": "输入目录名称" } \ No newline at end of file From 85583140d845874386d519e95d83781259cd3185 Mon Sep 17 00:00:00 2001 From: zysftd Date: Sun, 12 Jul 2026 21:28:13 +0800 Subject: [PATCH 14/15] fix: localize ImFileDialog file name, search, and column labels --- external/ImFileDialog/ImFileDialog.cpp | 12 ++++++------ source/Gui/translations/zh.json | 6 +++++- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/external/ImFileDialog/ImFileDialog.cpp b/external/ImFileDialog/ImFileDialog.cpp index f411ddd2b..0612f7a33 100644 --- a/external/ImFileDialog/ImFileDialog.cpp +++ b/external/ImFileDialog/ImFileDialog.cpp @@ -1099,7 +1099,7 @@ namespace ifd { if (m_zoom == 1.0f) { if (ImGui::BeginTable("##contentTable", 3, /*ImGuiTableFlags_Resizable |*/ ImGuiTableFlags_Sortable, ImVec2(0, -FLT_MIN))) { // header - ImGui::TableSetupColumn("Name##filename", ImGuiTableColumnFlags_WidthStretch, 0.0f -1.0f, 0); + ImGui::TableSetupColumn((std::string(_("Name")) + "##filename").c_str(), ImGuiTableColumnFlags_WidthStretch, 0.0f -1.0f, 0); ImGui::TableSetupColumn("Date modified##filedate", ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_NoResize, 0.0f, 1); ImGui::TableSetupColumn("Size##filesize", ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_NoResize, 0.0f, 2); ImGui::TableSetupScrollFreeze(0, 1); @@ -1217,7 +1217,7 @@ namespace ifd { if (openAreYouSureDlg) ImGui::OpenPopup("Are you sure?##delete"); if (openNewFileDlg) - ImGui::OpenPopup("Enter file name##newfile"); + ImGui::OpenPopup((std::string(_("Enter file name")) + "##newfile").c_str()); if (openNewDirectoryDlg) ImGui::OpenPopup("Enter directory name##newdir"); if (ImGui::BeginPopupModal("Are you sure?##delete")) { @@ -1238,7 +1238,7 @@ namespace ifd { } ImGui::EndPopup(); } - if (ImGui::BeginPopupModal("Enter file name##newfile")) { + if (ImGui::BeginPopupModal((std::string(_("Enter file name")) + "##newfile").c_str())) { ImGui::PushItemWidth(250.0f); ImGui::InputText("##newfilename", m_newEntryBuffer, 1024); // TODO: remove hardcoded literals ImGui::PopItemWidth(); @@ -1327,7 +1327,7 @@ namespace ifd { ImGui::SameLine(); ImGui::PopStyleColor(); - if (ImGui::InputTextEx("##searchTB", "Search", m_searchBuffer, 128, ImVec2(-FLT_MIN, GUI_ELEMENT_SIZE), 0)) // TODO: no hardcoded literals + if (ImGui::InputTextEx("##searchTB", _("Search"), m_searchBuffer, 128, ImVec2(-FLT_MIN, GUI_ELEMENT_SIZE), 0)) // TODO: no hardcoded literals m_setDirectory(m_currentDirectory, false); // refresh @@ -1369,9 +1369,9 @@ namespace ifd { /***** BOTTOM BAR *****/ if (m_type != IFD_DIALOG_DIRECTORY) { - ImGui::Text("File name:"); + ImGui::Text("%s", _("File name:")); ImGui::SameLine(); - if (ImGui::InputTextEx("##file_input", "Filename", reinterpret_cast(m_inputTextbox), 1024, ImVec2((m_type != IFD_DIALOG_DIRECTORY) ? -250.0f : -FLT_MIN, 0), ImGuiInputTextFlags_EnterReturnsTrue)) { + if (ImGui::InputTextEx("##file_input", _("Filename"), reinterpret_cast(m_inputTextbox), 1024, ImVec2((m_type != IFD_DIALOG_DIRECTORY) ? -250.0f : -FLT_MIN, 0), ImGuiInputTextFlags_EnterReturnsTrue)) { bool success = m_finalize(std::u8string(m_inputTextbox)); #ifdef _WIN32 if (!success) diff --git a/source/Gui/translations/zh.json b/source/Gui/translations/zh.json index 6277b950e..0b6ef6669 100644 --- a/source/Gui/translations/zh.json +++ b/source/Gui/translations/zh.json @@ -1205,5 +1205,9 @@ "Failed to load simulation.": "Failed to load simulation.", "Open genome from file": "从文件打开基因组", "Save genome to file": "将基因组保存到文件", - "Enter directory name": "输入目录名称" + "Enter directory name": "输入目录名称", + "Enter file name": "输入文件名", + "File name:": "文件名:", + "Filename": "文件名", + "Search": "搜索" } \ No newline at end of file From f876c36feff6575b963420294199c4ed35e6785b Mon Sep 17 00:00:00 2001 From: zysftd Date: Mon, 13 Jul 2026 11:50:38 +0800 Subject: [PATCH 15/15] i18n: localize genome editor, neural net editor, inspection window and mutation rates dialogs --- source/Gui/GeneEditorWidget.cpp | 34 ++-- source/Gui/GenomeEditorWidget.cpp | 46 ++--- source/Gui/GenomeEditorWindow.cpp | 28 +-- source/Gui/InspectionWindow.cpp | 36 ++-- source/Gui/MutationRatesDialog.cpp | 122 ++++++------ source/Gui/MutationRatesWidget.cpp | 34 ++-- source/Gui/NeuralNetEditorWidget.cpp | 14 +- source/Gui/NodeEditorWidget.cpp | 172 ++++++++-------- source/Gui/PreviewWidget.cpp | 8 +- source/Gui/translations/en.json | 281 ++++++++++++++++++++++++++- source/Gui/translations/zh.json | 158 ++++++++++++++- 11 files changed, 682 insertions(+), 251 deletions(-) diff --git a/source/Gui/GeneEditorWidget.cpp b/source/Gui/GeneEditorWidget.cpp index 955487b96..aaf48ae73 100644 --- a/source/Gui/GeneEditorWidget.cpp +++ b/source/Gui/GeneEditorWidget.cpp @@ -54,12 +54,12 @@ _GeneEditorWidget::_GeneEditorWidget(GenomeTabEditData const& editData, GenomeTa void _GeneEditorWidget::processNoSelection() { - AlienGui::Group(AlienGui::GroupParameters().text("Selected gene")); + AlienGui::Group(AlienGui::GroupParameters().text(_("Selected gene"))); if (ImGui::BeginChild("overlay", ImVec2(0, 0), 0)) { auto startPos = ImGui::GetCursorScreenPos(); auto size = ImGui::GetContentRegionAvail(); AlienGui::DisabledField(); - auto text = "No gene is selected"; + auto text = _("No gene is selected"); auto textSize = ImGui::CalcTextSize(text); ImVec2 textPos(startPos.x + size.x / 2 - textSize.x / 2, startPos.y + size.y / 2 - textSize.y / 2); ImGui::GetWindowDrawList()->AddText(textPos, ImGui::GetColorU32(ImGuiCol_Text), text); @@ -69,7 +69,7 @@ void _GeneEditorWidget::processNoSelection() void _GeneEditorWidget::processHeaderData() { - AlienGui::Group(AlienGui::GroupParameters().text("Selected gene").highlighted(true)); + AlienGui::Group(AlienGui::GroupParameters().text(_("Selected gene")).highlighted(true)); if (ImGui::BeginChild("GeneHeader", ImVec2(0, -_layoutData->nodeListHeight), 0, 0)) { auto& gene = _editData->getSelectedGeneRef(); @@ -81,14 +81,14 @@ void _GeneEditorWidget::processHeaderData() auto rightColumnWidth = std::max(HeaderMinRightColumnWidth, scaleInverse(ImGui::GetContentRegionAvail().x - scale(HeaderMaxLeftColumnWidth))); - AlienGui::Group(AlienGui::GroupParameters().text("Base properties")); + AlienGui::Group(AlienGui::GroupParameters().text(_("Base properties"))); // Gene name - AlienGui::InputText(AlienGui::InputTextParameters().name("Gene name").textWidth(rightColumnWidth), gene._name); + AlienGui::InputText(AlienGui::InputTextParameters().name(_("Gene name")).textWidth(rightColumnWidth), gene._name); // Shape if (AlienGui::Combo( - AlienGui::ComboParameters().name("Shape generator").values(Const::ConstructorShapeStrings).textWidth(rightColumnWidth), + AlienGui::ComboParameters().name(_("Shape generator")).values(Const::ConstructorShapeStrings).textWidth(rightColumnWidth), gene._shape)) { { ShapeGenerator shapeGenerator; @@ -100,17 +100,17 @@ void _GeneEditorWidget::processHeaderData() // Connection distance AlienGui::InputFloat( - AlienGui::InputFloatParameters().name("Connection distance").format("%.2f").step(0.05f).textWidth(rightColumnWidth), gene._connectionDistance); + AlienGui::InputFloatParameters().name(_("Connection distance")).format("%.2f").step(0.05f).textWidth(rightColumnWidth), gene._connectionDistance); // Stiffness - AlienGui::InputFloat(AlienGui::InputFloatParameters().name("Stiffness").format("%.2f").step(0.05f).textWidth(rightColumnWidth), gene._stiffness); + AlienGui::InputFloat(AlienGui::InputFloatParameters().name(_("Stiffness")).format("%.2f").step(0.05f).textWidth(rightColumnWidth), gene._stiffness); // Homogeneous cell type AlienGui::Checkbox( AlienGui::CheckboxParameters() - .name("Homogeneous cell type") + .name(_("Homogeneous cell type")) .textWidth(rightColumnWidth) - .tooltip("If enabled, every constructed cell of this gene uses the cell type and its properties of the first node."), + .tooltip(_("If enabled, every constructed cell of this gene uses the cell type and its properties of the first node.")), gene._homogeneousCellType); table.next(); @@ -138,11 +138,11 @@ void _GeneEditorWidget::processNodeList() | ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersV | ImGuiTableFlags_ScrollY | ImGuiTableFlags_ScrollX; if (ImGui::BeginTable("Node list", 5, flags, ImVec2(-1, -1), 0.0f)) { - ImGui::TableSetupColumn("Node index", ImGuiTableColumnFlags_NoSort | ImGuiTableColumnFlags_WidthFixed, scale(80.0f)); - ImGui::TableSetupColumn("Type", ImGuiTableColumnFlags_NoSort | ImGuiTableColumnFlags_WidthFixed, scale(135.0f)); - ImGui::TableSetupColumn("Construction", ImGuiTableColumnFlags_NoSort | ImGuiTableColumnFlags_WidthFixed, scale(135.0f)); - ImGui::TableSetupColumn("Angle", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, scale(40.0f)); - ImGui::TableSetupColumn("Color", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, scale(40.0f)); + ImGui::TableSetupColumn(_("Node index"), ImGuiTableColumnFlags_NoSort | ImGuiTableColumnFlags_WidthFixed, scale(80.0f)); + ImGui::TableSetupColumn(_("Type"), ImGuiTableColumnFlags_NoSort | ImGuiTableColumnFlags_WidthFixed, scale(135.0f)); + ImGui::TableSetupColumn(_("Construction"), ImGuiTableColumnFlags_NoSort | ImGuiTableColumnFlags_WidthFixed, scale(135.0f)); + ImGui::TableSetupColumn(_("Angle"), ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, scale(40.0f)); + ImGui::TableSetupColumn(_("Color"), ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, scale(40.0f)); ImGui::TableSetupScrollFreeze(0, 1); ImGui::TableHeadersRow(); ImGui::TableSetBgColor(ImGuiTableBgTarget_RowBg0, Const::TableHeaderColor); @@ -318,7 +318,7 @@ void _GeneEditorWidget::onMoveNodeUpward() auto& gene = _editData->getSelectedGeneRef(); if (indexToMove == 1 && gene._nodes.at(indexToMove).getCellType() == CellType_Void) { - showMessage("Error", "The first node cannot be void."); + showMessage(_("Error"), _("The first node cannot be void.")); return; } @@ -334,7 +334,7 @@ void _GeneEditorWidget::onMoveNodeDownward() auto& gene = _editData->getSelectedGeneRef(); if (indexToMove == gene._nodes.size() - 2 && gene._nodes.at(indexToMove).getCellType() == CellType_Void) { - showMessage("Error", "The last node cannot be void."); + showMessage(_("Error"), _("The last node cannot be void.")); return; } diff --git a/source/Gui/GenomeEditorWidget.cpp b/source/Gui/GenomeEditorWidget.cpp index 375a589d2..06384a542 100644 --- a/source/Gui/GenomeEditorWidget.cpp +++ b/source/Gui/GenomeEditorWidget.cpp @@ -65,7 +65,7 @@ _GenomeEditorWidget::_GenomeEditorWidget(GenomeTabEditData const& editData, Geno void _GenomeEditorWidget::processHeaderData() { - AlienGui::Group(AlienGui::GroupParameters().text("Genome").highlighted(true)); + AlienGui::Group(AlienGui::GroupParameters().text(_("Genome")).highlighted(true)); if (ImGui::BeginChild("GenomeHeader", ImVec2(0, -_layoutData->geneListHeight), 0)) { @@ -73,29 +73,29 @@ void _GenomeEditorWidget::processHeaderData() if (table.begin()) { auto rightColumnWidth = std::max(HeaderMinRightColumnWidth, scaleInverse(ImGui::GetContentRegionAvail().x - scale(HeaderMaxLeftColumnWidth))); - AlienGui::Group(AlienGui::GroupParameters().text("Base properties and info")); - AlienGui::InputText(AlienGui::InputTextParameters().name("Genome name").textWidth(rightColumnWidth), _editData->genome._name); + AlienGui::Group(AlienGui::GroupParameters().text(_("Base properties and info"))); + AlienGui::InputText(AlienGui::InputTextParameters().name(_("Genome name")).textWidth(rightColumnWidth), _editData->genome._name); auto numNodesString = std::to_string(GenomeDescInfoService::get().getNumberOfNodes(_editData->genome)); - AlienGui::InputText(AlienGui::InputTextParameters().name("Node count").readOnly(true).textWidth(rightColumnWidth), numNodesString); + AlienGui::InputText(AlienGui::InputTextParameters().name(_("Node count")).readOnly(true).textWidth(rightColumnWidth), numNodesString); AlienGui::SliderFloat( - AlienGui::SliderFloatParameters().name("Front angle").format("%.1f").min(-180.0f).max(180.0f).textWidth(rightColumnWidth), + AlienGui::SliderFloatParameters().name(_("Front angle")).format("%.1f").min(-180.0f).max(180.0f).textWidth(rightColumnWidth), &_editData->genome._frontAngle); AlienGui::Checkbox( AlienGui::CheckboxParameters() - .name("Resistance to injection") + .name(_("Resistance to injection")) .textWidth(rightColumnWidth), _editData->genome._resistanceToInjection); table.next(); - AlienGui::Group(AlienGui::GroupParameters().text("Mutation rates")); + AlienGui::Group(AlienGui::GroupParameters().text(_("Mutation rates"))); MutationRatesWidget::process(_editData->genome._mutationRates, rightColumnWidth); - AlienGui::Checkbox(AlienGui::CheckboxParameters().name("Apply meta-mutations").textWidth(rightColumnWidth), _editData->genome._applyMetaMutations); + AlienGui::Checkbox(AlienGui::CheckboxParameters().name(_("Apply meta-mutations")).textWidth(rightColumnWidth), _editData->genome._applyMetaMutations); table.next(); @@ -123,12 +123,12 @@ void _GenomeEditorWidget::processGeneList() | ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersV | ImGuiTableFlags_ScrollY | ImGuiTableFlags_ScrollX; if (ImGui::BeginTable("Gene list", 6, flags, ImVec2(-1, -1), 0.0f)) { - ImGui::TableSetupColumn("Gene index", ImGuiTableColumnFlags_NoSort | ImGuiTableColumnFlags_WidthFixed, scale(80.0f)); - ImGui::TableSetupColumn("Name", ImGuiTableColumnFlags_NoSort | ImGuiTableColumnFlags_WidthFixed, scale(120.0f)); - ImGui::TableSetupColumn("References", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, scale(80.0f)); - ImGui::TableSetupColumn("Referenced by", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, scale(95.0f)); - ImGui::TableSetupColumn("Shape", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, scale(60.0f)); - ImGui::TableSetupColumn("Nodes", ImGuiTableColumnFlags_NoSort | ImGuiTableColumnFlags_WidthFixed, scale(70.0f)); + ImGui::TableSetupColumn(_("Gene index"), ImGuiTableColumnFlags_NoSort | ImGuiTableColumnFlags_WidthFixed, scale(80.0f)); + ImGui::TableSetupColumn(_("Name"), ImGuiTableColumnFlags_NoSort | ImGuiTableColumnFlags_WidthFixed, scale(120.0f)); + ImGui::TableSetupColumn(_("References"), ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, scale(80.0f)); + ImGui::TableSetupColumn(_("Referenced by"), ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, scale(95.0f)); + ImGui::TableSetupColumn(_("Shape"), ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, scale(60.0f)); + ImGui::TableSetupColumn(_("Nodes"), ImGuiTableColumnFlags_NoSort | ImGuiTableColumnFlags_WidthFixed, scale(70.0f)); ImGui::TableSetupScrollFreeze(0, 1); ImGui::TableHeadersRow(); ImGui::TableSetBgColor(ImGuiTableBgTarget_RowBg0, Const::TableHeaderColor); @@ -160,7 +160,7 @@ void _GenomeEditorWidget::processGeneList() AlienGui::Text(std::to_string(row)); if (row == 0) { ImGui::SameLine(); - AlienGui::Text(AlienGui::TextParameters().text(" (root)").style(AlienGui::TextStyle::Decent)); + AlienGui::Text(AlienGui::TextParameters().text(_(" (root)")).style(AlienGui::TextStyle::Decent)); } ImGui::SameLine(); auto selected = _editData->selectedGeneIndex.has_value() ? _editData->selectedGeneIndex.value() == row : false; @@ -180,7 +180,7 @@ void _GenomeEditorWidget::processGeneList() if (!gene._name.empty()) { AlienGui::Text(gene._name); } else { - AlienGui::Text(AlienGui::TextParameters().text("(unnamed)").style(AlienGui::TextStyle::Decent)); + AlienGui::Text(AlienGui::TextParameters().text(_("(unnamed)")).style(AlienGui::TextStyle::Decent)); } // Column 2: References @@ -310,15 +310,15 @@ void _GenomeEditorWidget::onRemoveGene() if (!referencedBy.empty()) { auto referencedByStrings = referencedBy | std::views::transform([](auto const& geneIndex) { return std::to_string(geneIndex); }); auto referencedByString = boost::algorithm::join(std::vector(referencedByStrings.begin(), referencedByStrings.end()), ", "); - auto text = referencedBy.size() == 1 ? "This gene could not be removed since it is still used by gene " - : "This gene could not be removed since it is still used by genes "; - GenericMessageDialog::get().information("Error", text + referencedByString + "."); + auto text = referencedBy.size() == 1 ? _("This gene could not be removed since it is still used by gene ") + : _("This gene could not be removed since it is still used by genes "); + GenericMessageDialog::get().information(_("Error"), text + referencedByString + "."); return; } if (_editData->selectedGeneIndex.value() == 0) { GenericMessageDialog::get().yesNo( - "Delete root gene", - "Do you really want to delete the root gene? If you decide to do so, the following gene will become the new root gene.", + _("Delete root gene"), + _("Do you really want to delete the root gene? If you decide to do so, the following gene will become the new root gene."), [this] { this->removeGeneIntern(); }); return; } @@ -328,7 +328,7 @@ void _GenomeEditorWidget::onRemoveGene() void _GenomeEditorWidget::onMoveGeneUpward() { if (_editData->selectedGeneIndex.value() == 1) { - GenericMessageDialog::get().yesNo("Swap root gene", "Do you really want to swap the root gene?", [this] { this->moveGeneUpwardIntern(); }); + GenericMessageDialog::get().yesNo(_("Swap root gene"), _("Do you really want to swap the root gene?"), [this] { this->moveGeneUpwardIntern(); }); return; } moveGeneUpwardIntern(); @@ -337,7 +337,7 @@ void _GenomeEditorWidget::onMoveGeneUpward() void _GenomeEditorWidget::onMoveGeneDownward() { if (_editData->selectedGeneIndex.value() == 0) { - GenericMessageDialog::get().yesNo("Swap root gene", "Do you really want to swap the root gene?", [this] { this->moveGeneDownwardIntern(); }); + GenericMessageDialog::get().yesNo(_("Swap root gene"), _("Do you really want to swap the root gene?"), [this] { this->moveGeneDownwardIntern(); }); return; } moveGeneDownwardIntern(); diff --git a/source/Gui/GenomeEditorWindow.cpp b/source/Gui/GenomeEditorWindow.cpp index e0eada952..adfe0a6a0 100644 --- a/source/Gui/GenomeEditorWindow.cpp +++ b/source/Gui/GenomeEditorWindow.cpp @@ -107,31 +107,31 @@ void GenomeEditorWindow::processToolbar() if (AlienGui::ToolbarButton( AlienGui::ToolbarButtonParameters() .text(ICON_FA_UPLOAD) - .tooltip("Share your genome with other users:\nYour current genome will be uploaded to the server and made visible in the browser."))) { + .tooltip(_("Share your genome with other users:\nYour current genome will be uploaded to the server and made visible in the browser.")))) { } ImGui::SameLine(); AlienGui::ToolbarSeparator(); ImGui::SameLine(); - if (AlienGui::ToolbarButton(AlienGui::ToolbarButtonParameters().text(ICON_FA_CLONE).tooltip("Clone genome"))) { + if (AlienGui::ToolbarButton(AlienGui::ToolbarButtonParameters().text(ICON_FA_CLONE).tooltip(_("Clone genome")))) { onCloneGenome(); } ImGui::SameLine(); - if (AlienGui::ToolbarButton(AlienGui::ToolbarButtonParameters().text(ICON_FA_COPY).tooltip("Copy genome to clipboard"))) { + if (AlienGui::ToolbarButton(AlienGui::ToolbarButtonParameters().text(ICON_FA_COPY).tooltip(_("Copy genome to clipboard")))) { onCopyGenome(); } ImGui::SameLine(); if (AlienGui::ToolbarButton( - AlienGui::ToolbarButtonParameters().text(ICON_FA_PASTE).tooltip("Paste genome from clipboard").disabled(!_copiedGenome.has_value()))) { + AlienGui::ToolbarButtonParameters().text(ICON_FA_PASTE).tooltip(_("Paste genome from clipboard")).disabled(!_copiedGenome.has_value()))) { onPasteGenome(); } ImGui::SameLine(); if (AlienGui::ToolbarButton( - AlienGui::ToolbarButtonParameters().text(ICON_FA_WINDOW_CLOSE).tooltip("Close all tabs except the current one").disabled(_tabs.size() <= 1))) { + AlienGui::ToolbarButtonParameters().text(ICON_FA_WINDOW_CLOSE).tooltip(_("Close all tabs except the current one")).disabled(_tabs.size() <= 1))) { onCloseOtherTabs(); } @@ -141,12 +141,12 @@ void GenomeEditorWindow::processToolbar() ImGui::SameLine(); auto hasGenomeChanged = _tabs.at(_selectedTabIndex)->hasGenomeChanged(); if (AlienGui::ToolbarButton( - AlienGui::ToolbarButtonParameters().text(ICON_FA_CAMERA).tooltip("Create save point in this tab").disabled(!hasGenomeChanged))) { + AlienGui::ToolbarButtonParameters().text(ICON_FA_CAMERA).tooltip(_("Create save point in this tab")).disabled(!hasGenomeChanged))) { onSavepointGenome(); } ImGui::SameLine(); - if (AlienGui::ToolbarButton(AlienGui::ToolbarButtonParameters().text(ICON_FA_UNDO).tooltip("Revert genome to save point").disabled(!hasGenomeChanged))) { + if (AlienGui::ToolbarButton(AlienGui::ToolbarButtonParameters().text(ICON_FA_UNDO).tooltip(_("Revert genome to save point")).disabled(!hasGenomeChanged))) { _tabs.at(_selectedTabIndex)->revertChanges(); } @@ -154,7 +154,7 @@ void GenomeEditorWindow::processToolbar() AlienGui::ToolbarSeparator(); ImGui::SameLine(); - if (AlienGui::ToolbarButton(AlienGui::ToolbarButtonParameters().text(ICON_FA_PALETTE).tooltip("Change the color of all nodes with a certain color"))) { + if (AlienGui::ToolbarButton(AlienGui::ToolbarButtonParameters().text(ICON_FA_PALETTE).tooltip(_("Change the color of all nodes with a certain color")))) { ChangeColorDialog::get().open(_tabs.at(_selectedTabIndex)->getEditData()); } @@ -165,14 +165,14 @@ void GenomeEditorWindow::processToolbar() auto creaturesSelected = EditorModel::get().getSelectionShallowData().numCreatures > 0; if (AlienGui::ToolbarButton(AlienGui::ToolbarButtonParameters() .text(ICON_FA_SYRINGE) - .tooltip("Inject the current genome to the selected creatures in the simulation") + .tooltip(_("Inject the current genome to the selected creatures in the simulation")) .disabled(!creaturesSelected))) { onInjectGenome(); } ImGui::SameLine(); if (AlienGui::ToolbarButton( - AlienGui::ToolbarButtonParameters().text(ICON_FA_SEEDLING).tooltip("Create a seed with current genome without free energy supply"))) { + AlienGui::ToolbarButtonParameters().text(ICON_FA_SEEDLING).tooltip(_("Create a seed with current genome without free energy supply")))) { onCreateSeed(false); } ImGui::SameLine(); @@ -180,7 +180,7 @@ void GenomeEditorWindow::processToolbar() .text(ICON_FA_SEEDLING) .secondText(ICON_FA_BOLT) .secondTextOffset({30.0f, 25.0f}) - .tooltip("Create a seed with current genome with free energy supply"))) { + .tooltip(_("Create a seed with current genome with free energy supply")))) { onCreateSeed(true); } @@ -197,7 +197,7 @@ void GenomeEditorWindow::processTabWidget() if (ImGui::TabItemButton("+", ImGuiTabItemFlags_Trailing | ImGuiTabItemFlags_NoTooltip)) { onScheduleAddTab(getDefaultGenome()); } - AlienGui::Tooltip("New genome"); + AlienGui::Tooltip(_("New genome")); std::optional tabIndexToSelect = _tabIndexToSelect; std::optional tabToDelete; @@ -295,7 +295,7 @@ void GenomeEditorWindow::onInjectGenome() { auto const& selectedTab = _tabs.at(_selectedTabIndex); auto numCreatures = _SimulationFacade::get()->injectGenomeToSelectedCreatures(selectedTab->getGenomeDesc()); - printOverlayMessage("Genome injected to " + std::to_string(numCreatures) + (numCreatures == 1 ? " creature" : " creatures")); + printOverlayMessage(_("Genome injected to ") + std::to_string(numCreatures) + (numCreatures == 1 ? _(" creature") : _(" creatures"))); selectedTab->resetOriginal(); } @@ -326,7 +326,7 @@ void GenomeEditorWindow::onCreateSeed(bool provideEnergy) _SimulationFacade::get()->addAndSelectSimulationData(std::move(seed)); EditorModel::get().update(); - printOverlayMessage("Seed created"); + printOverlayMessage(_("Seed created")); } void GenomeEditorWindow::onScheduleAddTab(GenomeDesc const& genome) diff --git a/source/Gui/InspectionWindow.cpp b/source/Gui/InspectionWindow.cpp index 9d6836e68..b5afffc6d 100644 --- a/source/Gui/InspectionWindow.cpp +++ b/source/Gui/InspectionWindow.cpp @@ -54,7 +54,7 @@ namespace template void processPropertiesSubNode(std::string const& idSuffix, Func&& processWidgets) { - if (AlienGui::BeginTreeNode(AlienGui::TreeNodeParameters().name("Properties##" + idSuffix).rank(AlienGui::TreeNodeRank::Default).defaultOpen(true))) { + if (AlienGui::BeginTreeNode(AlienGui::TreeNodeParameters().name(std::string(_("Properties")) + "##" + idSuffix).rank(AlienGui::TreeNodeRank::Default).defaultOpen(true))) { processWidgets(); } AlienGui::EndTreeNode(); @@ -299,11 +299,11 @@ std::string _InspectionWindow::generateTitle() const if (_creatureMode) { auto entity = EditorModel::get().getInspectedEntity(_entityId); auto const& creature = std::get(entity).creature; - ss << "Creature with id 0x" << std::hex << std::uppercase << (creature.has_value() ? creature->_id : _entityId); + ss << _("Creature with id 0x") << std::hex << std::uppercase << (creature.has_value() ? creature->_id : _entityId); } else if (isExtendedObject()) { - ss << "Cell with id 0x" << std::hex << std::uppercase << _entityId; + ss << _("Cell with id 0x") << std::hex << std::uppercase << _entityId; } else { - ss << "Energy particle with id 0x" << std::hex << std::uppercase << _entityId; + ss << _("Energy particle with id 0x") << std::hex << std::uppercase << _entityId; } return ss.str(); } @@ -413,7 +413,7 @@ void _InspectionWindow::processObjectNode(ObjectDesc& object) { if (AlienGui::BeginTreeNode(AlienGui::TreeNodeParameters().name(_("Object")).rank(AlienGui::TreeNodeRank::High))) { processPropertiesSubNode("Object", [&] { - inspectorHexId("Object id", object._id); + inspectorHexId(_("Object id"), object._id); AlienGui::InputFloat2(AlienGui::InputFloat2Parameters().name(_("Position")).format("%.2f").textWidth(TextWidth), object._pos.x, object._pos.y); AlienGui::InputFloat2(AlienGui::InputFloat2Parameters().name(_("Velocity")).format("%.2f").textWidth(TextWidth), object._vel.x, object._vel.y); AlienGui::InputFloat(AlienGui::InputFloatParameters().name(_("Stiffness")).format("%.2f").step(0.05f).textWidth(TextWidth), object._stiffness); @@ -440,8 +440,8 @@ void _InspectionWindow::processObjectNode(ObjectDesc& object) auto& conn = object._connections.at(i); auto const connectionNumber = i + 1; if (AlienGui::BeginTreeNode( - AlienGui::TreeNodeParameters().name("Connection #" + std::to_string(connectionNumber)).rank(AlienGui::TreeNodeRank::Low))) { - inspectorHexId("Connected id", conn._objectId); + AlienGui::TreeNodeParameters().name(_("Connection #") + std::to_string(connectionNumber)).rank(AlienGui::TreeNodeRank::Low))) { + inspectorHexId(_("Connected id"), conn._objectId); AlienGui::InputFloat( AlienGui::InputFloatParameters().name(_("Distance")).format("%.2f").textWidth(TextWidth).readOnly(true), conn._distance); AlienGui::InputFloat( @@ -500,7 +500,7 @@ void _InspectionWindow::processCellNode(ObjectDesc& object) AlienGui::InputFloat(AlienGui::InputFloatParameters().name(_("Raw energy")).format("%.2f").textWidth(TextWidth), cell._rawEnergy); AlienGui::InputOptionalFloat(AlienGui::InputFloatParameters().name(_("Front angle")).format("%.2f").textWidth(TextWidth), cell._frontAngle); AlienGui::InputInt(AlienGui::InputIntParameters().name(_("Age")).textWidth(TextWidth), cell._age); - static std::vector const cellStateStrings = {"Ready", "Constructing", "Activating", "Dying", "Instant dying"}; + static std::vector const cellStateStrings = {_("Ready"), _("Constructing"), _("Activating"), _("Dying"), _("Instant dying")}; AlienGui::ComboParameters stateParams; stateParams.name(_("Cell state")).textWidth(TextWidth).values(cellStateStrings); AlienGui::Combo(stateParams, cell._cellState); @@ -577,16 +577,16 @@ void _InspectionWindow::processConstructorNode(ConstructorDesc& constructor) void _InspectionWindow::processCreatureProperties(ExtendedObjectDesc& extendedObject) { auto& creature = extendedObject.creature.value(); - inspectorHexId("Creature id", creature._id); - inspectorText("Generation", std::to_string(creature._generation)); - inspectorText("Num cells", std::to_string(creature._numCells)); + inspectorHexId(_("Creature id"), creature._id); + inspectorText(_("Generation"), std::to_string(creature._generation)); + inspectorText(_("Num cells"), std::to_string(creature._numCells)); AlienGui::InputInt(AlienGui::InputIntParameters().name(_("Lineage id")).textWidth(TextWidth), creature._lineageId); AlienGui::InputFloat(AlienGui::InputFloatParameters().name(_("Accumulated mutations")).format("%.5f").textWidth(TextWidth), creature._accumulatedMutations); auto& genome = extendedObject.genome.value(); - inspectorText("Genome name", genome._name); - inspectorText("Resistance to injection", genome._resistanceToInjection ? "Yes" : "No"); - inspectorText("Apply meta-mutations", genome._applyMetaMutations ? "Yes" : "No"); - if (AlienGui::Button(AlienGui::ButtonParameters().buttonText("Edit").name(_("Edit genome")).textWidth(TextWidth))) { + inspectorText(_("Genome name"), genome._name); + inspectorText(_("Resistance to injection"), genome._resistanceToInjection ? _("Yes") : _("No")); + inspectorText(_("Apply meta-mutations"), genome._applyMetaMutations ? _("Yes") : _("No")); + if (AlienGui::Button(AlienGui::ButtonParameters().buttonText(_("Edit")).name(_("Edit genome")).textWidth(TextWidth))) { GenomeEditorWindow::get().openTab(genome, false); } } @@ -649,7 +649,7 @@ namespace void _InspectionWindow::processCellTypeNode(CellDesc& cell) { auto cellType = cell.getCellType(); - auto cellTypeName = Const::CellTypeStrings.at(cellType) + " properties"; + auto cellTypeName = Const::CellTypeStrings.at(cellType) + " " + _("properties"); if (AlienGui::BeginTreeNode(AlienGui::TreeNodeParameters().name(cellTypeName + "##Cell node").rank(AlienGui::TreeNodeRank::Default).defaultOpen(false))) { auto const& customizationColors = _SimulationFacade::get()->getSimulationParameters().customizationColors.value; @@ -808,7 +808,7 @@ void _InspectionWindow::processCellTypeNode(CellDesc& cell) } } else if (cellType == CellType_Detonator) { auto& detonator = std::get(cell._cellType); - static std::vector const detonatorStateStrings = {"Ready", "Activated", "Exploded"}; + static std::vector const detonatorStateStrings = {_("Ready"), _("Activated"), _("Exploded")}; int state = detonator._state; AlienGui::ComboParameters stateParams; stateParams.name(_("State")).textWidth(TextWidth).values(detonatorStateStrings); @@ -850,7 +850,7 @@ void _InspectionWindow::processCellTypeNode(CellDesc& cell) AlienGui::SliderFloatParameters().name(_("New signal weight")).max(1.0f).format("%.2f").textWidth(TextWidth), &m._newSignalWeight); } processMemoryChannelBits(memory._channelBitMask); - if (AlienGui::Button(AlienGui::ButtonParameters().buttonText("Edit").name(_("Signal buffer")).textWidth(TextWidth))) { + if (AlienGui::Button(AlienGui::ButtonParameters().buttonText(_("Edit")).name(_("Signal buffer")).textWidth(TextWidth))) { SignalsBufferDialog::get().open( memory._signalEntries, [this](std::vector const& entries) { _pendingSignalEntries = entries; }); } diff --git a/source/Gui/MutationRatesDialog.cpp b/source/Gui/MutationRatesDialog.cpp index 5ec5958a4..86ef1f5eb 100644 --- a/source/Gui/MutationRatesDialog.cpp +++ b/source/Gui/MutationRatesDialog.cpp @@ -18,7 +18,7 @@ namespace if (AlienGui::BeginTreeNode(AlienGui::TreeNodeParameters().name(name).rank(AlienGui::TreeNodeRank::Default))) { AlienGui::SliderFloat( AlienGui::SliderFloatParameters() - .name("Node probability") + .name(_("Node probability")) .id(id) .min(0.0f) .max(1.0f) @@ -27,7 +27,7 @@ namespace .textWidth(rightColumnWidth), &mutation._nodeProbability); AlienGui::SliderFloat( - AlienGui::SliderFloatParameters().name("Value change sigma").id(id).min(0.0f).max(1.0f).logarithmic(true).format("%.3f").textWidth(rightColumnWidth), + AlienGui::SliderFloatParameters().name(_("Value change sigma")).id(id).min(0.0f).max(1.0f).logarithmic(true).format("%.3f").textWidth(rightColumnWidth), &mutation._valueChangeSigma); } AlienGui::EndTreeNode(); @@ -38,7 +38,7 @@ namespace if (AlienGui::BeginTreeNode(AlienGui::TreeNodeParameters().name(name).rank(AlienGui::TreeNodeRank::Default))) { AlienGui::SliderFloat( AlienGui::SliderFloatParameters() - .name("Node probability") + .name(_("Node probability")) .id(id) .min(0.0f) .max(1.0f) @@ -47,14 +47,14 @@ namespace .textWidth(rightColumnWidth), &mutation._nodeProbability); AlienGui::SliderFloat( - AlienGui::SliderFloatParameters().name("Weight change sigma").id(id).min(0.0f).max(2.0f).logarithmic(true).format("%.2f").textWidth(rightColumnWidth), + AlienGui::SliderFloatParameters().name(_("Weight change sigma")).id(id).min(0.0f).max(2.0f).logarithmic(true).format("%.2f").textWidth(rightColumnWidth), &mutation._weightChangeSigma); AlienGui::SliderFloat( - AlienGui::SliderFloatParameters().name("Bias change sigma").id(id).min(0.0f).max(2.0f).logarithmic(true).format("%.3f").textWidth(rightColumnWidth), + AlienGui::SliderFloatParameters().name(_("Bias change sigma")).id(id).min(0.0f).max(2.0f).logarithmic(true).format("%.3f").textWidth(rightColumnWidth), &mutation._biasChangeSigma); AlienGui::SliderFloat( AlienGui::SliderFloatParameters() - .name("ActFn change probability") + .name(_("ActFn change probability")) .id(id) .min(0.0f) .max(1.0f) @@ -71,7 +71,7 @@ namespace if (AlienGui::BeginTreeNode(AlienGui::TreeNodeParameters().name(name).rank(AlienGui::TreeNodeRank::Default))) { AlienGui::SliderFloat( AlienGui::SliderFloatParameters() - .name("Node probability") + .name(_("Node probability")) .id(id) .min(0.0f) .max(1.0f) @@ -80,11 +80,11 @@ namespace .textWidth(rightColumnWidth), &mutation._nodeProbability); AlienGui::SliderFloat( - AlienGui::SliderFloatParameters().name("Value change sigma").id(id).min(0.0f).max(1.0f).logarithmic(true).format("%.3f").textWidth(rightColumnWidth), + AlienGui::SliderFloatParameters().name(_("Value change sigma")).id(id).min(0.0f).max(1.0f).logarithmic(true).format("%.3f").textWidth(rightColumnWidth), &mutation._valueChangeSigma); AlienGui::SliderFloat( AlienGui::SliderFloatParameters() - .name("Enum change probability") + .name(_("Enum change probability")) .id(id) .min(0.0f) .max(1.0f) @@ -101,7 +101,7 @@ namespace if (AlienGui::BeginTreeNode(AlienGui::TreeNodeParameters().name(name).rank(AlienGui::TreeNodeRank::Default))) { AlienGui::SliderFloat( AlienGui::SliderFloatParameters() - .name("Gene probability") + .name(_("Gene probability")) .id(id) .min(0.0f) .max(1.0f) @@ -110,11 +110,11 @@ namespace .textWidth(rightColumnWidth), &mutation._geneProbability); AlienGui::SliderFloat( - AlienGui::SliderFloatParameters().name("Value change sigma").id(id).min(0.0f).max(1.0f).logarithmic(true).format("%.3f").textWidth(rightColumnWidth), + AlienGui::SliderFloatParameters().name(_("Value change sigma")).id(id).min(0.0f).max(1.0f).logarithmic(true).format("%.3f").textWidth(rightColumnWidth), &mutation._valueChangeSigma); AlienGui::SliderFloat( AlienGui::SliderFloatParameters() - .name("Enum change probability") + .name(_("Enum change probability")) .id(id) .min(0.0f) .max(1.0f) @@ -131,7 +131,7 @@ namespace if (AlienGui::BeginTreeNode(AlienGui::TreeNodeParameters().name(name).rank(AlienGui::TreeNodeRank::Default))) { AlienGui::SliderFloat( AlienGui::SliderFloatParameters() - .name("Node probability") + .name(_("Node probability")) .id(id) .min(0.0f) .max(1.0f) @@ -148,7 +148,7 @@ namespace if (AlienGui::BeginTreeNode(AlienGui::TreeNodeParameters().name(name).rank(AlienGui::TreeNodeRank::Default))) { AlienGui::SliderFloat( AlienGui::SliderFloatParameters() - .name("Node probability") + .name(_("Node probability")) .id(id) .min(0.0f) .max(1.0f) @@ -165,7 +165,7 @@ namespace if (AlienGui::BeginTreeNode(AlienGui::TreeNodeParameters().name(name).rank(AlienGui::TreeNodeRank::Default))) { AlienGui::SliderFloat( AlienGui::SliderFloatParameters() - .name("Node probability") + .name(_("Node probability")) .id(id) .min(0.0f) .max(1.0f) @@ -183,7 +183,7 @@ namespace if (AlienGui::BeginTreeNode(AlienGui::TreeNodeParameters().name(name).rank(AlienGui::TreeNodeRank::Default))) { AlienGui::SliderFloat( AlienGui::SliderFloatParameters() - .name("Gene probability") + .name(_("Gene probability")) .id(id) .min(0.0f) .max(1.0f) @@ -201,7 +201,7 @@ namespace if (AlienGui::BeginTreeNode(AlienGui::TreeNodeParameters().name(name).rank(AlienGui::TreeNodeRank::Default))) { AlienGui::SliderFloat( AlienGui::SliderFloatParameters() - .name("Node probability") + .name(_("Node probability")) .id(id) .min(0.0f) .max(1.0f) @@ -218,7 +218,7 @@ namespace if (AlienGui::BeginTreeNode(AlienGui::TreeNodeParameters().name(name).rank(AlienGui::TreeNodeRank::Default))) { AlienGui::SliderFloat( AlienGui::SliderFloatParameters() - .name("Node probability") + .name(_("Node probability")) .id(id) .min(0.0f) .max(1.0f) @@ -227,11 +227,11 @@ namespace .textWidth(rightColumnWidth), &mutation._nodeProbability); AlienGui::SliderFloat( - AlienGui::SliderFloatParameters().name("Value change sigma").id(id).min(0.0f).max(1.0f).logarithmic(true).format("%.3f").textWidth(rightColumnWidth), + AlienGui::SliderFloatParameters().name(_("Value change sigma")).id(id).min(0.0f).max(1.0f).logarithmic(true).format("%.3f").textWidth(rightColumnWidth), &mutation._valueChangeSigma); AlienGui::SliderFloat( AlienGui::SliderFloatParameters() - .name("Enum change probability") + .name(_("Enum change probability")) .id(id) .min(0.0f) .max(1.0f) @@ -241,7 +241,7 @@ namespace &mutation._enumChangeProbability); AlienGui::SliderFloat( AlienGui::SliderFloatParameters() - .name("Constructor toggle probability") + .name(_("Constructor toggle probability")) .id(id) .min(0.0f) .max(1.0f) @@ -265,7 +265,7 @@ namespace } MutationRatesDialog::MutationRatesDialog() - : AlienDialog("Mutation rates", {800.0f, 400.0f}, true) + : AlienDialog(_("Mutation rates"), {800.0f, 400.0f}, true) {} void MutationRatesDialog::initIntern() {} @@ -423,154 +423,154 @@ void MutationRatesDialog::processIntern() if (ImGui::BeginChild("MutationRateContent", ImVec2(0, -buttonAreaHeight), false)) { AlienGui::DynamicTableLayout sectionTable(MinSectionWidth); if (sectionTable.begin()) { - if (AlienGui::BeginTreeNode(AlienGui::TreeNodeParameters().name("Connection weight mutations").rank(AlienGui::TreeNodeRank::High))) { + if (AlienGui::BeginTreeNode(AlienGui::TreeNodeParameters().name(_("Connection weight mutations")).rank(AlienGui::TreeNodeRank::High))) { processConcreteMutationRates(2, [&](AlienGui::DynamicTableLayout& table) { - processConnectionMutationRate("Mutation rate 1", "CMR1", _mutation._connectionMutations[0], RightColumnWidth); + processConnectionMutationRate(_("Mutation rate 1"), "CMR1", _mutation._connectionMutations[0], RightColumnWidth); table.next(); - processConnectionMutationRate("Mutation rate 2", "CMR2", _mutation._connectionMutations[1], RightColumnWidth); + processConnectionMutationRate(_("Mutation rate 2"), "CMR2", _mutation._connectionMutations[1], RightColumnWidth); table.next(); }); } AlienGui::EndTreeNode(); sectionTable.next(); - if (AlienGui::BeginTreeNode(AlienGui::TreeNodeParameters().name("Neuron mutations").rank(AlienGui::TreeNodeRank::High))) { + if (AlienGui::BeginTreeNode(AlienGui::TreeNodeParameters().name(_("Neuron mutations")).rank(AlienGui::TreeNodeRank::High))) { processConcreteMutationRates(2, [&](AlienGui::DynamicTableLayout& table) { - processNeuronMutationRate("Mutation rate 1", "NMR1", _mutation._neuronMutations[0], RightColumnWidth); + processNeuronMutationRate(_("Mutation rate 1"), "NMR1", _mutation._neuronMutations[0], RightColumnWidth); table.next(); - processNeuronMutationRate("Mutation rate 2", "NMR2", _mutation._neuronMutations[1], RightColumnWidth); + processNeuronMutationRate(_("Mutation rate 2"), "NMR2", _mutation._neuronMutations[1], RightColumnWidth); table.next(); }); } AlienGui::EndTreeNode(); sectionTable.next(); - if (AlienGui::BeginTreeNode(AlienGui::TreeNodeParameters().name("Cell type property mutations").rank(AlienGui::TreeNodeRank::High))) { + if (AlienGui::BeginTreeNode(AlienGui::TreeNodeParameters().name(_("Cell type property mutations")).rank(AlienGui::TreeNodeRank::High))) { processConcreteMutationRates(2, [&](AlienGui::DynamicTableLayout& table) { - processCellTypePropertiesMutationRate("Mutation rate 1", "CTPM1", _mutation._cellTypePropertiesMutations[0], RightColumnWidth); + processCellTypePropertiesMutationRate(_("Mutation rate 1"), "CTPM1", _mutation._cellTypePropertiesMutations[0], RightColumnWidth); table.next(); - processCellTypePropertiesMutationRate("Mutation rate 2", "CTPM2", _mutation._cellTypePropertiesMutations[1], RightColumnWidth); + processCellTypePropertiesMutationRate(_("Mutation rate 2"), "CTPM2", _mutation._cellTypePropertiesMutations[1], RightColumnWidth); table.next(); }); } AlienGui::EndTreeNode(); sectionTable.next(); - if (AlienGui::BeginTreeNode(AlienGui::TreeNodeParameters().name("Geometry mutations").rank(AlienGui::TreeNodeRank::High))) { + if (AlienGui::BeginTreeNode(AlienGui::TreeNodeParameters().name(_("Geometry mutations")).rank(AlienGui::TreeNodeRank::High))) { processConcreteMutationRates(2, [&](AlienGui::DynamicTableLayout& table) { - processGeometryMutationRate("Mutation rate 1", "GEOM1", _mutation._geometryMutations[0], RightColumnWidth); + processGeometryMutationRate(_("Mutation rate 1"), "GEOM1", _mutation._geometryMutations[0], RightColumnWidth); table.next(); - processGeometryMutationRate("Mutation rate 2", "GEOM2", _mutation._geometryMutations[1], RightColumnWidth); + processGeometryMutationRate(_("Mutation rate 2"), "GEOM2", _mutation._geometryMutations[1], RightColumnWidth); table.next(); }); } AlienGui::EndTreeNode(); sectionTable.next(); - if (AlienGui::BeginTreeNode(AlienGui::TreeNodeParameters().name("Cell type mode mutations").rank(AlienGui::TreeNodeRank::High))) { + if (AlienGui::BeginTreeNode(AlienGui::TreeNodeParameters().name(_("Cell type mode mutations")).rank(AlienGui::TreeNodeRank::High))) { processConcreteMutationRates(1, [&](AlienGui::DynamicTableLayout& table) { - processCellTypeModeMutationRate("Mutation rate", "CTMM", _mutation._cellTypeModeMutation, RightColumnWidth); + processCellTypeModeMutationRate(_("Mutation rate"), "CTMM", _mutation._cellTypeModeMutation, RightColumnWidth); table.next(); }); } AlienGui::EndTreeNode(); sectionTable.next(); - if (AlienGui::BeginTreeNode(AlienGui::TreeNodeParameters().name("Cell type mutations").rank(AlienGui::TreeNodeRank::High))) { + if (AlienGui::BeginTreeNode(AlienGui::TreeNodeParameters().name(_("Cell type mutations")).rank(AlienGui::TreeNodeRank::High))) { processConcreteMutationRates(1, [&](AlienGui::DynamicTableLayout& table) { - processCellTypeMutationRate("Mutation rate", "CTM", _mutation._cellTypeMutation, RightColumnWidth); + processCellTypeMutationRate(_("Mutation rate"), "CTM", _mutation._cellTypeMutation, RightColumnWidth); table.next(); }); } AlienGui::EndTreeNode(); sectionTable.next(); - if (AlienGui::BeginTreeNode(AlienGui::TreeNodeParameters().name("Void mutations").rank(AlienGui::TreeNodeRank::High))) { + if (AlienGui::BeginTreeNode(AlienGui::TreeNodeParameters().name(_("Void mutations")).rank(AlienGui::TreeNodeRank::High))) { processConcreteMutationRates(1, [&](AlienGui::DynamicTableLayout& table) { - processVoidMutationRate("Mutation rate", "VM", _mutation._voidMutation, RightColumnWidth); + processVoidMutationRate(_("Mutation rate"), "VM", _mutation._voidMutation, RightColumnWidth); table.next(); }); } AlienGui::EndTreeNode(); sectionTable.next(); - if (AlienGui::BeginTreeNode(AlienGui::TreeNodeParameters().name("Extend gene mutations").rank(AlienGui::TreeNodeRank::High))) { + if (AlienGui::BeginTreeNode(AlienGui::TreeNodeParameters().name(_("Extend gene mutations")).rank(AlienGui::TreeNodeRank::High))) { processConcreteMutationRates(1, [&](AlienGui::DynamicTableLayout& table) { - processGeneProbabilityMutationRate("Mutation rate", "EXGM", _mutation._extendGeneMutation, RightColumnWidth); + processGeneProbabilityMutationRate(_("Mutation rate"), "EXGM", _mutation._extendGeneMutation, RightColumnWidth); table.next(); }); } AlienGui::EndTreeNode(); sectionTable.next(); - if (AlienGui::BeginTreeNode(AlienGui::TreeNodeParameters().name("Add node mutations").rank(AlienGui::TreeNodeRank::High))) { + if (AlienGui::BeginTreeNode(AlienGui::TreeNodeParameters().name(_("Add node mutations")).rank(AlienGui::TreeNodeRank::High))) { processConcreteMutationRates(1, [&](AlienGui::DynamicTableLayout& table) { - processNodeProbabilityMutationRate("Mutation rate", "ADNM", _mutation._addNodeMutation, RightColumnWidth); + processNodeProbabilityMutationRate(_("Mutation rate"), "ADNM", _mutation._addNodeMutation, RightColumnWidth); table.next(); }); } AlienGui::EndTreeNode(); sectionTable.next(); - if (AlienGui::BeginTreeNode(AlienGui::TreeNodeParameters().name("Trim gene mutations").rank(AlienGui::TreeNodeRank::High))) { + if (AlienGui::BeginTreeNode(AlienGui::TreeNodeParameters().name(_("Trim gene mutations")).rank(AlienGui::TreeNodeRank::High))) { processConcreteMutationRates(1, [&](AlienGui::DynamicTableLayout& table) { - processGeneProbabilityMutationRate("Mutation rate", "TRGM", _mutation._trimGeneMutation, RightColumnWidth); + processGeneProbabilityMutationRate(_("Mutation rate"), "TRGM", _mutation._trimGeneMutation, RightColumnWidth); table.next(); }); } AlienGui::EndTreeNode(); sectionTable.next(); - if (AlienGui::BeginTreeNode(AlienGui::TreeNodeParameters().name("Delete node mutations").rank(AlienGui::TreeNodeRank::High))) { + if (AlienGui::BeginTreeNode(AlienGui::TreeNodeParameters().name(_("Delete node mutations")).rank(AlienGui::TreeNodeRank::High))) { processConcreteMutationRates(1, [&](AlienGui::DynamicTableLayout& table) { - processNodeProbabilityMutationRate("Mutation rate", "DLNM", _mutation._deleteNodeMutation, RightColumnWidth); + processNodeProbabilityMutationRate(_("Mutation rate"), "DLNM", _mutation._deleteNodeMutation, RightColumnWidth); table.next(); }); } AlienGui::EndTreeNode(); sectionTable.next(); - if (AlienGui::BeginTreeNode(AlienGui::TreeNodeParameters().name("Duplicate gene mutations").rank(AlienGui::TreeNodeRank::High))) { + if (AlienGui::BeginTreeNode(AlienGui::TreeNodeParameters().name(_("Duplicate gene mutations")).rank(AlienGui::TreeNodeRank::High))) { processConcreteMutationRates(1, [&](AlienGui::DynamicTableLayout& table) { - processGeneProbabilityMutationRate("Mutation rate", "DPGM", _mutation._duplicateGeneMutation, RightColumnWidth); + processGeneProbabilityMutationRate(_("Mutation rate"), "DPGM", _mutation._duplicateGeneMutation, RightColumnWidth); table.next(); }); } AlienGui::EndTreeNode(); sectionTable.next(); - if (AlienGui::BeginTreeNode(AlienGui::TreeNodeParameters().name("Delete gene mutations").rank(AlienGui::TreeNodeRank::High))) { + if (AlienGui::BeginTreeNode(AlienGui::TreeNodeParameters().name(_("Delete gene mutations")).rank(AlienGui::TreeNodeRank::High))) { processConcreteMutationRates(1, [&](AlienGui::DynamicTableLayout& table) { - processGeneProbabilityMutationRate("Mutation rate", "DLGM", _mutation._deleteGeneMutation, RightColumnWidth); + processGeneProbabilityMutationRate(_("Mutation rate"), "DLGM", _mutation._deleteGeneMutation, RightColumnWidth); table.next(); }); } AlienGui::EndTreeNode(); sectionTable.next(); - if (AlienGui::BeginTreeNode(AlienGui::TreeNodeParameters().name("Copy node section mutations").rank(AlienGui::TreeNodeRank::High))) { + if (AlienGui::BeginTreeNode(AlienGui::TreeNodeParameters().name(_("Copy node section mutations")).rank(AlienGui::TreeNodeRank::High))) { processConcreteMutationRates(1, [&](AlienGui::DynamicTableLayout& table) { - processGeneProbabilityMutationRate("Mutation rate", "CNSM", _mutation._copyNodeSectionMutation, RightColumnWidth); + processGeneProbabilityMutationRate(_("Mutation rate"), "CNSM", _mutation._copyNodeSectionMutation, RightColumnWidth); table.next(); }); } AlienGui::EndTreeNode(); sectionTable.next(); - if (AlienGui::BeginTreeNode(AlienGui::TreeNodeParameters().name("Move node section mutations").rank(AlienGui::TreeNodeRank::High))) { + if (AlienGui::BeginTreeNode(AlienGui::TreeNodeParameters().name(_("Move node section mutations")).rank(AlienGui::TreeNodeRank::High))) { processConcreteMutationRates(1, [&](AlienGui::DynamicTableLayout& table) { - processGeneProbabilityMutationRate("Mutation rate", "MNSM", _mutation._moveNodeSectionMutation, RightColumnWidth); + processGeneProbabilityMutationRate(_("Mutation rate"), "MNSM", _mutation._moveNodeSectionMutation, RightColumnWidth); table.next(); }); } AlienGui::EndTreeNode(); sectionTable.next(); - if (AlienGui::BeginTreeNode(AlienGui::TreeNodeParameters().name("Constructor mutations").rank(AlienGui::TreeNodeRank::High))) { + if (AlienGui::BeginTreeNode(AlienGui::TreeNodeParameters().name(_("Constructor mutations")).rank(AlienGui::TreeNodeRank::High))) { processConcreteMutationRates(2, [&](AlienGui::DynamicTableLayout& table) { - processConstructorMutationRate("Mutation rate 1", "COM1", _mutation._constructorMutations[0], RightColumnWidth); + processConstructorMutationRate(_("Mutation rate 1"), "COM1", _mutation._constructorMutations[0], RightColumnWidth); table.next(); - processConstructorMutationRate("Mutation rate 2", "COM2", _mutation._constructorMutations[1], RightColumnWidth); + processConstructorMutationRate(_("Mutation rate 2"), "COM2", _mutation._constructorMutations[1], RightColumnWidth); table.next(); }); } @@ -584,7 +584,7 @@ void MutationRatesDialog::processIntern() AlienGui::Separator(); - if (AlienGui::Button("Adopt")) { + if (AlienGui::Button(_("Adopt"))) { ImGui::CloseCurrentPopup(); onAdopt(); close(); @@ -592,7 +592,7 @@ void MutationRatesDialog::processIntern() ImGui::SetItemDefaultFocus(); ImGui::SameLine(); - if (AlienGui::Button("Cancel")) { + if (AlienGui::Button(_("Cancel"))) { ImGui::CloseCurrentPopup(); close(); } diff --git a/source/Gui/MutationRatesWidget.cpp b/source/Gui/MutationRatesWidget.cpp index 381933f87..a687bed50 100644 --- a/source/Gui/MutationRatesWidget.cpp +++ b/source/Gui/MutationRatesWidget.cpp @@ -37,28 +37,28 @@ namespace { std::vector> activeMutations; addActiveMutationType( - activeMutations, "Connection mutations", {mutationRates._connectionMutations[0]._nodeProbability, mutationRates._connectionMutations[1]._nodeProbability}); + activeMutations, _("Connection mutations"), {mutationRates._connectionMutations[0]._nodeProbability, mutationRates._connectionMutations[1]._nodeProbability}); addActiveMutationType( - activeMutations, "Neuron mutations", {mutationRates._neuronMutations[0]._nodeProbability, mutationRates._neuronMutations[1]._nodeProbability}); + activeMutations, _("Neuron mutations"), {mutationRates._neuronMutations[0]._nodeProbability, mutationRates._neuronMutations[1]._nodeProbability}); addActiveMutationType( activeMutations, - "Cell type property mut.", + _("Cell type property mut."), {mutationRates._cellTypePropertiesMutations[0]._nodeProbability, mutationRates._cellTypePropertiesMutations[1]._nodeProbability}); addActiveMutationType( - activeMutations, "Geometry mutations", {mutationRates._geometryMutations[0]._geneProbability, mutationRates._geometryMutations[1]._geneProbability}); - addActiveMutationType(activeMutations, "Cell type mode mut.", {mutationRates._cellTypeModeMutation._nodeProbability}); - addActiveMutationType(activeMutations, "Cell type mutations", {mutationRates._cellTypeMutation._nodeProbability}); - addActiveMutationType(activeMutations, "Void mutations", {mutationRates._voidMutation._nodeProbability}); - addActiveMutationType(activeMutations, "Extend gene mutations", {mutationRates._extendGeneMutation._geneProbability}); - addActiveMutationType(activeMutations, "Add node mutations", {mutationRates._addNodeMutation._nodeProbability}); - addActiveMutationType(activeMutations, "Trim gene mutations", {mutationRates._trimGeneMutation._geneProbability}); - addActiveMutationType(activeMutations, "Delete node mutations", {mutationRates._deleteNodeMutation._nodeProbability}); - addActiveMutationType(activeMutations, "Duplicate gene mutations", {mutationRates._duplicateGeneMutation._geneProbability}); - addActiveMutationType(activeMutations, "Delete gene mutations", {mutationRates._deleteGeneMutation._geneProbability}); - addActiveMutationType(activeMutations, "Copy node section mutations", {mutationRates._copyNodeSectionMutation._geneProbability}); - addActiveMutationType(activeMutations, "Move node section mutations", {mutationRates._moveNodeSectionMutation._geneProbability}); + activeMutations, _("Geometry mutations"), {mutationRates._geometryMutations[0]._geneProbability, mutationRates._geometryMutations[1]._geneProbability}); + addActiveMutationType(activeMutations, _("Cell type mode mut."), {mutationRates._cellTypeModeMutation._nodeProbability}); + addActiveMutationType(activeMutations, _("Cell type mutations"), {mutationRates._cellTypeMutation._nodeProbability}); + addActiveMutationType(activeMutations, _("Void mutations"), {mutationRates._voidMutation._nodeProbability}); + addActiveMutationType(activeMutations, _("Extend gene mutations"), {mutationRates._extendGeneMutation._geneProbability}); + addActiveMutationType(activeMutations, _("Add node mutations"), {mutationRates._addNodeMutation._nodeProbability}); + addActiveMutationType(activeMutations, _("Trim gene mutations"), {mutationRates._trimGeneMutation._geneProbability}); + addActiveMutationType(activeMutations, _("Delete node mutations"), {mutationRates._deleteNodeMutation._nodeProbability}); + addActiveMutationType(activeMutations, _("Duplicate gene mutations"), {mutationRates._duplicateGeneMutation._geneProbability}); + addActiveMutationType(activeMutations, _("Delete gene mutations"), {mutationRates._deleteGeneMutation._geneProbability}); + addActiveMutationType(activeMutations, _("Copy node section mutations"), {mutationRates._copyNodeSectionMutation._geneProbability}); + addActiveMutationType(activeMutations, _("Move node section mutations"), {mutationRates._moveNodeSectionMutation._geneProbability}); addActiveMutationType( - activeMutations, "Constructor", {mutationRates._constructorMutations[0]._nodeProbability, mutationRates._constructorMutations[1]._nodeProbability}); + activeMutations, _("Constructor"), {mutationRates._constructorMutations[0]._nodeProbability, mutationRates._constructorMutations[1]._nodeProbability}); return activeMutations; } } @@ -67,7 +67,7 @@ void MutationRatesWidget::process(MutationRatesDesc& mutationRates, float rightC { ImGui::BeginGroup(); - if (AlienGui::Button(AlienGui::ButtonParameters().buttonText("Edit").name("Click to edit").textWidth(rightColumnWidth))) { + if (AlienGui::Button(AlienGui::ButtonParameters().buttonText(_("Edit")).name(_("Click to edit")).textWidth(rightColumnWidth))) { auto onAdopt = [&mutationRates](MutationRatesDesc const& adoptedRates) { mutationRates = adoptedRates; }; if (nested) { MutationRatesDialog::get().openNested(mutationRates, onAdopt); diff --git a/source/Gui/NeuralNetEditorWidget.cpp b/source/Gui/NeuralNetEditorWidget.cpp index 313ca17f1..cb789f532 100644 --- a/source/Gui/NeuralNetEditorWidget.cpp +++ b/source/Gui/NeuralNetEditorWidget.cpp @@ -62,7 +62,7 @@ void _NeuralNetEditorWidget::process( void _NeuralNetEditorWidget::processConnectionWeightSliders(std::vector& connectionWeights, LayoutData& layout) { pushDefaultColors(); - ImGui::Button("Connection weights", {layout.width - 2 * ImGui::GetStyle().FramePadding.x, 0}); + ImGui::Button(_("Connection weights"), {layout.width - 2 * ImGui::GetStyle().FramePadding.x, 0}); popColors(); auto resetButtonWidth = ImGui::CalcTextSize("x").x /* + 2 * ImGui::GetStyle().FramePadding.x*/; @@ -98,7 +98,7 @@ void _NeuralNetEditorWidget::processConnectionWeightSliders(std::vector& void _NeuralNetEditorWidget::processChannelWeightSliders(std::vector& weights, SelectionData& selectionData, LayoutData& layout) { pushDefaultColors(); - ImGui::Button("Neuron weights", {layout.width - 2 * ImGui::GetStyle().FramePadding.x, 0}); + ImGui::Button(_("Neuron weights"), {layout.width - 2 * ImGui::GetStyle().FramePadding.x, 0}); popColors(); ImGui::PushID("ChannelWeightSliders"); @@ -297,7 +297,7 @@ void _NeuralNetEditorWidget::processActionButtons( std::vector& activationFunctions) { if (ImGui::BeginChild("ActionButtons", ImVec2(0, scale(50.0f)))) { - if (AlienGui::Button("Clear")) { + if (AlienGui::Button(_("Clear"))) { for (int i = 0; i < NEURONS_PER_CELL; ++i) { for (int j = 0; j < NEURONS_PER_CELL; ++j) { weights[i * NEURONS_PER_CELL + j] = NeuralNetWeight(0); @@ -307,7 +307,7 @@ void _NeuralNetEditorWidget::processActionButtons( } } ImGui::SameLine(); - if (AlienGui::Button("Identity")) { + if (AlienGui::Button(_("Identity"))) { for (int i = 0; i < NEURONS_PER_CELL; ++i) { for (int j = 0; j < NEURONS_PER_CELL; ++j) { weights[i * NEURONS_PER_CELL + j] = (i == j) ? NeuralNetWeight(1.0f) : NeuralNetWeight(0); @@ -317,7 +317,7 @@ void _NeuralNetEditorWidget::processActionButtons( } } ImGui::SameLine(); - if (AlienGui::Button("Randomize")) { + if (AlienGui::Button(_("Randomize"))) { for (int i = 0; i < NEURONS_PER_CELL; ++i) { for (int j = 0; j < NEURONS_PER_CELL; ++j) { weights[i * NEURONS_PER_CELL + j] = NeuralNetWeight(NumberGenerator::get().getRandomFloat(-2.0f, 2.0f)); @@ -327,13 +327,13 @@ void _NeuralNetEditorWidget::processActionButtons( } } ImGui::SameLine(); - if (AlienGui::Button("Copy")) { + if (AlienGui::Button(_("Copy"))) { NetData copiedNet{weights, biases, activationFunctions}; _copiedNet = copiedNet; } ImGui::SameLine(); ImGui::BeginDisabled(!_copiedNet.has_value()); - if (AlienGui::Button("Paste")) { + if (AlienGui::Button(_("Paste"))) { weights = _copiedNet->weights; biases = _copiedNet->biases; activationFunctions = _copiedNet->activationFunctions; diff --git a/source/Gui/NodeEditorWidget.cpp b/source/Gui/NodeEditorWidget.cpp index 8bfca4a2e..c6f573c47 100644 --- a/source/Gui/NodeEditorWidget.cpp +++ b/source/Gui/NodeEditorWidget.cpp @@ -200,7 +200,7 @@ namespace void _NodeEditorWidget::processNodeAttributes() { - AlienGui::Group(AlienGui::GroupParameters().text("Selected node").highlighted(true)); + AlienGui::Group(AlienGui::GroupParameters().text(_("Selected node")).highlighted(true)); if (ImGui::BeginChild("NodeData", ImVec2(0, -_layoutData->neuralNetEditorHeight), 0, 0)) { auto& gene = _editData->getSelectedGeneRef(); @@ -217,31 +217,31 @@ void _NodeEditorWidget::processNodeAttributes() auto rightColumnWidth = std::max(MinTextWidth, scaleInverse(ImGui::GetContentRegionAvail().x - scale(MaxWidgetWidth))); // Angle - AlienGui::Group(AlienGui::GroupParameters().text("Base properties")); + AlienGui::Group(AlienGui::GroupParameters().text(_("Base properties"))); auto nodeIndex = _editData->getSelectedNodeIndex(); auto isInnerNode = nodeIndex.value() != 0 && nodeIndex != gene._nodes.size() - 1; //if (!isInnerNode) { AlienGui::InputFloat( AlienGui::InputFloatParameters() - .name("Angle") + .name(_("Angle")) .textWidth(rightColumnWidth) .readOnly(isInnerNode) - .infoLabel(isInnerNode ? std::make_optional(std::string("Deduced")) : std::nullopt) + .infoLabel(isInnerNode ? std::make_optional(std::string(_("Deduced"))) : std::nullopt) .format("%.1f"), node._referenceAngle); //} - AlienGui::ComboColor( - AlienGui::ComboColorParameters().customizationColors(customizationColors).name("Color").textWidth(rightColumnWidth), node._color); + AlienGui::ComboColor( + AlienGui::ComboColorParameters().customizationColors(customizationColors).name(_("Color")).textWidth(rightColumnWidth), node._color); // Type auto nodeType = cellTypeNode.getCellType(); - if (AlienGui::Combo(AlienGui::ComboParameters().name("Type").values(Const::CellTypeStrings).textWidth(rightColumnWidth), nodeType)) { + if (AlienGui::Combo(AlienGui::ComboParameters().name(_("Type")).values(Const::CellTypeStrings).textWidth(rightColumnWidth), nodeType)) { if (nodeType == CellType_Void && (gene._homogeneousCellType || nodeIndex.value() == 0)) { - showMessage("Error", "The first node cannot be void."); + showMessage(_("Error"), _("The first node cannot be void.")); } else if (nodeType == CellType_Void && nodeIndex.value() == gene._nodes.size() - 1) { - showMessage("Error", "The last node cannot be void."); + showMessage(_("Error"), _("The last node cannot be void.")); } else { cellTypeNode._cellType = createCellTypeGenomeDesc(nodeType); if (nodeType == CellType_Void) { @@ -255,16 +255,16 @@ void _NodeEditorWidget::processNodeAttributes() // Construction gene combo std::vector genes; - genes.emplace_back("None"); + genes.emplace_back(_("None")); for (auto const& [index, gene] : _editData->genome._genes | boost::adaptors::indexed(0)) { auto text = std::to_string(index) + ": " + gene._name; if (index == 0) { - text += " (root)"; + text += _(" (root)"); } genes.emplace_back(text); } int constructionGeneIndex = node._constructor.has_value() ? node._constructor.value()._geneIndex + 1 : 0; - if (AlienGui::Combo(AlienGui::ComboParameters().name("Construction").values(genes).textWidth(rightColumnWidth), constructionGeneIndex)) { + if (AlienGui::Combo(AlienGui::ComboParameters().name(_("Construction")).values(genes).textWidth(rightColumnWidth), constructionGeneIndex)) { if (constructionGeneIndex == 0) { node._constructor = std::nullopt; } else { @@ -275,7 +275,7 @@ void _NodeEditorWidget::processNodeAttributes() } } - AlienGui::Group(AlienGui::GroupParameters().text("Construction properties")); + AlienGui::Group(AlienGui::GroupParameters().text(_("Construction properties"))); if (node._constructor.has_value()) { ImGui::PushID("Constructor"); @@ -284,29 +284,29 @@ void _NodeEditorWidget::processNodeAttributes() // Auto activation interval AlienGui::InputOptionalInt( - AlienGui::InputIntParameters().name("Auto trigger interval").textWidth(rightColumnWidth), constructor._autoTriggerInterval); + AlienGui::InputIntParameters().name(_("Auto trigger interval")).textWidth(rightColumnWidth), constructor._autoTriggerInterval); // Construction activation time AlienGui::InputInt( - AlienGui::InputIntParameters().name("Offspring trigger time").textWidth(rightColumnWidth), constructor._constructionActivationTime); + AlienGui::InputIntParameters().name(_("Offspring trigger time")).textWidth(rightColumnWidth), constructor._constructionActivationTime); // Construction angle AlienGui::InputFloat( - AlienGui::InputFloatParameters().name("Construction angle").textWidth(rightColumnWidth).format("%.1f"), constructor._constructionAngle); + AlienGui::InputFloatParameters().name(_("Construction angle")).textWidth(rightColumnWidth).format("%.1f"), constructor._constructionAngle); // Reserved energy AlienGui::InputFloat( - AlienGui::InputFloatParameters().name("Reserved energy").textWidth(rightColumnWidth).format("%.1f"), constructor._reservedEnergy); + AlienGui::InputFloatParameters().name(_("Reserved energy")).textWidth(rightColumnWidth).format("%.1f"), constructor._reservedEnergy); // Separation - AlienGui::Checkbox(AlienGui::CheckboxParameters().name("Separation").textWidth(rightColumnWidth), constructor._separation); + AlienGui::Checkbox(AlienGui::CheckboxParameters().name(_("Separation")).textWidth(rightColumnWidth), constructor._separation); // Number of branches AlienGui::BeginIndent(); if (!constructor._separation) { auto numBranches = constructor._numBranches - 1; - AlienGui::Switcher( - AlienGui::SwitcherParameters().name("Number of branches").values({"1", "2", "3", "4", "5", "6"}).textWidth(rightColumnWidth), + AlienGui::Switcher( + AlienGui::SwitcherParameters().name(_("Number of branches")).values({"1", "2", "3", "4", "5", "6"}).textWidth(rightColumnWidth), &numBranches); constructor._numBranches = numBranches + 1; } @@ -314,7 +314,7 @@ void _NodeEditorWidget::processNodeAttributes() // Concatenations AlienGui::InputInt( - AlienGui::InputIntParameters().name("Concatenations").infinity(true).textWidth(rightColumnWidth), constructor._numConcatenations); + AlienGui::InputIntParameters().name(_("Concatenations")).infinity(true).textWidth(rightColumnWidth), constructor._numConcatenations); AlienGui::EndIndent(); ImGui::PopID(); @@ -323,15 +323,15 @@ void _NodeEditorWidget::processNodeAttributes() table.next(); - AlienGui::Group(AlienGui::GroupParameters().text("Type-specific properties")); + AlienGui::Group(AlienGui::GroupParameters().text(_("Type-specific properties"))); if (nodeType == CellType_Base) { } else if (nodeType == CellType_Depot) { auto& depot = std::get(cellTypeNode._cellType); AlienGui::InputFloat( - AlienGui::InputFloatParameters().name("Max energy for storage").format("%.1f").textWidth(rightColumnWidth), depot._storageLimit); + AlienGui::InputFloatParameters().name(_("Max energy for storage")).format("%.1f").textWidth(rightColumnWidth), depot._storageLimit); AlienGui::InputFloat( - AlienGui::InputFloatParameters().name("Initial stored energy").textWidth(rightColumnWidth).format("%.1f"), + AlienGui::InputFloatParameters().name(_("Initial stored energy")).textWidth(rightColumnWidth).format("%.1f"), depot._initialStoredUsableEnergy); } else if (nodeType == CellType_Sensor) { @@ -339,12 +339,12 @@ void _NodeEditorWidget::processNodeAttributes() // Auto activation interval auto& sensor = std::get(cellTypeNode._cellType); - AlienGui::Checkbox(AlienGui::CheckboxParameters().name("Auto trigger").textWidth(rightColumnWidth), sensor._autoTrigger); - AlienGui::Checkbox(AlienGui::CheckboxParameters().name("Tag for attackers").textWidth(rightColumnWidth), sensor._tagForAttackers); + AlienGui::Checkbox(AlienGui::CheckboxParameters().name(_("Auto trigger")).textWidth(rightColumnWidth), sensor._autoTrigger); + AlienGui::Checkbox(AlienGui::CheckboxParameters().name(_("Tag for attackers")).textWidth(rightColumnWidth), sensor._tagForAttackers); // Mode selection auto mode = sensor.getMode(); - if (AlienGui::Combo(AlienGui::ComboParameters().name("Mode").values(Const::SensorModeStrings).textWidth(rightColumnWidth), mode)) { + if (AlienGui::Combo(AlienGui::ComboParameters().name(_("Mode")).values(Const::SensorModeStrings).textWidth(rightColumnWidth), mode)) { sensor._mode = createSensorModeGenomeDesc(mode); } @@ -355,7 +355,7 @@ void _NodeEditorWidget::processNodeAttributes() AlienGui::BeginIndent(); auto& detectEnergy = std::get(sensor._mode); AlienGui::InputFloat( - AlienGui::InputFloatParameters().name("Min density").step(0.05f).format("%.2f").textWidth(rightColumnWidth), detectEnergy._minDensity); + AlienGui::InputFloatParameters().name(_("Min density")).step(0.05f).format("%.2f").textWidth(rightColumnWidth), detectEnergy._minDensity); AlienGui::EndIndent(); } else if (mode == SensorMode_DetectSolid) { // No parameters @@ -363,33 +363,33 @@ void _NodeEditorWidget::processNodeAttributes() AlienGui::BeginIndent(); auto& detectFreeCell = std::get(sensor._mode); AlienGui::InputFloat( - AlienGui::InputFloatParameters().name("Min density").step(0.05f).format("%.2f").textWidth(rightColumnWidth), + AlienGui::InputFloatParameters().name(_("Min density")).step(0.05f).format("%.2f").textWidth(rightColumnWidth), detectFreeCell._minDensity); AlienGui::ColorCheckboxes( - AlienGui::ColorCheckboxesParameters().customizationColors(customizationColors).name("Restrict to colors").textWidth(rightColumnWidth), + AlienGui::ColorCheckboxesParameters().customizationColors(customizationColors).name(_("Restrict to colors")).textWidth(rightColumnWidth), detectFreeCell._restrictToColors); AlienGui::EndIndent(); } else if (mode == SensorMode_DetectCreature) { AlienGui::BeginIndent(); auto& detectCreature = std::get(sensor._mode); AlienGui::InputOptionalInt( - AlienGui::InputIntParameters().name("Min creature cells").textWidth(rightColumnWidth), detectCreature._minNumCells); + AlienGui::InputIntParameters().name(_("Min creature cells")).textWidth(rightColumnWidth), detectCreature._minNumCells); AlienGui::InputOptionalInt( - AlienGui::InputIntParameters().name("Max creature cells").textWidth(rightColumnWidth), detectCreature._maxNumCells); + AlienGui::InputIntParameters().name(_("Max creature cells")).textWidth(rightColumnWidth), detectCreature._maxNumCells); AlienGui::ColorCheckboxes( - AlienGui::ColorCheckboxesParameters().customizationColors(customizationColors).name("Restrict to colors").textWidth(rightColumnWidth), + AlienGui::ColorCheckboxesParameters().customizationColors(customizationColors).name(_("Restrict to colors")).textWidth(rightColumnWidth), detectCreature._restrictToColors); AlienGui::Combo( - AlienGui::ComboParameters().name("Restrict to lineage").values({"No", "Same lineage", "Other lineage"}).textWidth(rightColumnWidth), + AlienGui::ComboParameters().name(_("Restrict to lineage")).values({_("No"), _("Same lineage"), _("Other lineage")}).textWidth(rightColumnWidth), detectCreature._restrictToLineage); AlienGui::EndIndent(); } // Minimum range - AlienGui::SliderInt(AlienGui::SliderIntParameters().name("Min range").min(0).max(512).textWidth(rightColumnWidth), &sensor._minRange); + AlienGui::SliderInt(AlienGui::SliderIntParameters().name(_("Min range")).min(0).max(512).textWidth(rightColumnWidth), &sensor._minRange); // Maximum range - AlienGui::SliderInt(AlienGui::SliderIntParameters().name("Max range").min(0).max(512).textWidth(rightColumnWidth), &sensor._maxRange); + AlienGui::SliderInt(AlienGui::SliderIntParameters().name(_("Max range")).min(0).max(512).textWidth(rightColumnWidth), &sensor._maxRange); ImGui::PopID(); @@ -398,20 +398,20 @@ void _NodeEditorWidget::processNodeAttributes() auto& generator = std::get(cellTypeNode._cellType); // Additive - AlienGui::Checkbox(AlienGui::CheckboxParameters().name("Additive").textWidth(rightColumnWidth), generator._additive); + AlienGui::Checkbox(AlienGui::CheckboxParameters().name(_("Additive")).textWidth(rightColumnWidth), generator._additive); // Value range AlienGui::InputFloat( - AlienGui::InputFloatParameters().name("Min value").format("%.2f").step(0.05f).textWidth(rightColumnWidth), generator._minValue); + AlienGui::InputFloatParameters().name(_("Min value")).format("%.2f").step(0.05f).textWidth(rightColumnWidth), generator._minValue); AlienGui::InputFloat( - AlienGui::InputFloatParameters().name("Max value").format("%.2f").step(0.05f).textWidth(rightColumnWidth), generator._maxValue); + AlienGui::InputFloatParameters().name(_("Max value")).format("%.2f").step(0.05f).textWidth(rightColumnWidth), generator._maxValue); // Time offset - AlienGui::InputInt(AlienGui::InputIntParameters().name("Time offset").textWidth(rightColumnWidth), generator._timeOffset); + AlienGui::InputInt(AlienGui::InputIntParameters().name(_("Time offset")).textWidth(rightColumnWidth), generator._timeOffset); // Mode auto mode = generator.getMode(); - if (AlienGui::Combo(AlienGui::ComboParameters().name("Mode").values(Const::GeneratorModeStrings).textWidth(rightColumnWidth), mode)) { + if (AlienGui::Combo(AlienGui::ComboParameters().name(_("Mode")).values(Const::GeneratorModeStrings).textWidth(rightColumnWidth), mode)) { generator._mode = createGeneratorModeGenomeDesc(mode); } @@ -419,14 +419,14 @@ void _NodeEditorWidget::processNodeAttributes() AlienGui::BeginIndent(); auto& squareSignal = std::get(generator._mode); - AlienGui::InputInt(AlienGui::InputIntParameters().name("Period").textWidth(rightColumnWidth), squareSignal._period); + AlienGui::InputInt(AlienGui::InputIntParameters().name(_("Period")).textWidth(rightColumnWidth), squareSignal._period); AlienGui::EndIndent(); } else if (mode == GeneratorMode_SawtoothSignal) { AlienGui::BeginIndent(); auto& sawtoothSignal = std::get(generator._mode); - AlienGui::InputInt(AlienGui::InputIntParameters().name("Period").textWidth(rightColumnWidth), sawtoothSignal._period); + AlienGui::InputInt(AlienGui::InputIntParameters().name(_("Period")).textWidth(rightColumnWidth), sawtoothSignal._period); AlienGui::EndIndent(); } @@ -435,7 +435,7 @@ void _NodeEditorWidget::processNodeAttributes() auto& attacker = std::get(cellTypeNode._cellType); auto mode = attacker.getMode(); - if (AlienGui::Combo(AlienGui::ComboParameters().name("Mode").values(Const::AttackerModeStrings).textWidth(rightColumnWidth), mode)) { + if (AlienGui::Combo(AlienGui::ComboParameters().name(_("Mode")).values(Const::AttackerModeStrings).textWidth(rightColumnWidth), mode)) { attacker._mode = createAttackerModeGenomeDesc(mode); } @@ -444,7 +444,7 @@ void _NodeEditorWidget::processNodeAttributes() auto& attackFreeCell = std::get(attacker._mode); AlienGui::ColorCheckboxes( - AlienGui::ColorCheckboxesParameters().customizationColors(customizationColors).name("Restrict to colors").textWidth(rightColumnWidth), + AlienGui::ColorCheckboxesParameters().customizationColors(customizationColors).name(_("Restrict to colors")).textWidth(rightColumnWidth), attackFreeCell._restrictToColors); AlienGui::EndIndent(); @@ -453,14 +453,14 @@ void _NodeEditorWidget::processNodeAttributes() // Gene index auto& injector = std::get(cellTypeNode._cellType); - AlienGui::InputInt(AlienGui::InputIntParameters().name("Gene index").textWidth(rightColumnWidth), injector._geneIndex); + AlienGui::InputInt(AlienGui::InputIntParameters().name(_("Gene index")).textWidth(rightColumnWidth), injector._geneIndex); } else if (nodeType == CellType_Muscle) { // Mode auto& muscle = std::get(cellTypeNode._cellType); auto mode = muscle.getMode(); - if (AlienGui::Combo(AlienGui::ComboParameters().name("Mode").values(Const::MuscleModeStrings).textWidth(rightColumnWidth), mode)) { + if (AlienGui::Combo(AlienGui::ComboParameters().name(_("Mode")).values(Const::MuscleModeStrings).textWidth(rightColumnWidth), mode)) { muscle._mode = createMuscleModeGenomeDesc(mode); } @@ -470,12 +470,12 @@ void _NodeEditorWidget::processNodeAttributes() // Max angle deviation auto& autoBending = std::get(muscle._mode); AlienGui::SliderFloat( - AlienGui::SliderFloatParameters().name("Max angle deviation").min(0.0f).max(1.0f).format("%.2f").textWidth(rightColumnWidth), + AlienGui::SliderFloatParameters().name(_("Max angle deviation")).min(0.0f).max(1.0f).format("%.2f").textWidth(rightColumnWidth), &autoBending._maxAngleDeviation); // Front back ratio AlienGui::SliderFloat( - AlienGui::SliderFloatParameters().name("Forward backward ratio").min(0.0f).max(1.0f).format("%.2f").textWidth(rightColumnWidth), + AlienGui::SliderFloatParameters().name(_("Forward backward ratio")).min(0.0f).max(1.0f).format("%.2f").textWidth(rightColumnWidth), &autoBending._forwardBackwardRatio); AlienGui::EndIndent(); @@ -486,12 +486,12 @@ void _NodeEditorWidget::processNodeAttributes() // Max angle deviation auto& manualBending = std::get(muscle._mode); AlienGui::SliderFloat( - AlienGui::SliderFloatParameters().name("Max angle deviation").min(0.0f).max(1.0f).format("%.2f").textWidth(rightColumnWidth), + AlienGui::SliderFloatParameters().name(_("Max angle deviation")).min(0.0f).max(1.0f).format("%.2f").textWidth(rightColumnWidth), &manualBending._maxAngleDeviation); // Front back ratio AlienGui::SliderFloat( - AlienGui::SliderFloatParameters().name("Forward backward ratio").min(0.0f).max(1.0f).format("%.2f").textWidth(rightColumnWidth), + AlienGui::SliderFloatParameters().name(_("Forward backward ratio")).min(0.0f).max(1.0f).format("%.2f").textWidth(rightColumnWidth), &manualBending._forwardBackwardRatio); AlienGui::EndIndent(); @@ -502,12 +502,12 @@ void _NodeEditorWidget::processNodeAttributes() // Max angle deviation auto& angleBending = std::get(muscle._mode); AlienGui::SliderFloat( - AlienGui::SliderFloatParameters().name("Max angle deviation").min(0.0f).max(1.0f).format("%.2f").textWidth(rightColumnWidth), + AlienGui::SliderFloatParameters().name(_("Max angle deviation")).min(0.0f).max(1.0f).format("%.2f").textWidth(rightColumnWidth), &angleBending._maxAngleDeviation); // Front back ratio AlienGui::InputFloat( - AlienGui::InputFloatParameters().name("Attraction repulsion ratio").format("%.2f").step(0.05f).textWidth(rightColumnWidth), + AlienGui::InputFloatParameters().name(_("Attraction repulsion ratio")).format("%.2f").step(0.05f).textWidth(rightColumnWidth), angleBending._attractionRepulsionRatio); AlienGui::EndIndent(); @@ -518,12 +518,12 @@ void _NodeEditorWidget::processNodeAttributes() // Max angle deviation auto& autoCrawling = std::get(muscle._mode); AlienGui::SliderFloat( - AlienGui::SliderFloatParameters().name("Max distance deviation").min(0.0f).max(1.0f).format("%.2f").textWidth(rightColumnWidth), + AlienGui::SliderFloatParameters().name(_("Max distance deviation")).min(0.0f).max(1.0f).format("%.2f").textWidth(rightColumnWidth), &autoCrawling._maxDistanceDeviation); // Front back ratio AlienGui::SliderFloat( - AlienGui::SliderFloatParameters().name("Forward backward ratio").min(0.0f).max(1.0f).format("%.2f").textWidth(rightColumnWidth), + AlienGui::SliderFloatParameters().name(_("Forward backward ratio")).min(0.0f).max(1.0f).format("%.2f").textWidth(rightColumnWidth), &autoCrawling._forwardBackwardRatio); AlienGui::EndIndent(); @@ -534,12 +534,12 @@ void _NodeEditorWidget::processNodeAttributes() // Max angle deviation auto& manualCrawling = std::get(muscle._mode); AlienGui::SliderFloat( - AlienGui::SliderFloatParameters().name("Max distance deviation").min(0.0f).max(1.0f).format("%.2f").textWidth(rightColumnWidth), + AlienGui::SliderFloatParameters().name(_("Max distance deviation")).min(0.0f).max(1.0f).format("%.2f").textWidth(rightColumnWidth), &manualCrawling._maxDistanceDeviation); // Front back ratio AlienGui::SliderFloat( - AlienGui::SliderFloatParameters().name("Forward backward ratio").min(0.0f).max(1.0f).format("%.2f").textWidth(rightColumnWidth), + AlienGui::SliderFloatParameters().name(_("Forward backward ratio")).min(0.0f).max(1.0f).format("%.2f").textWidth(rightColumnWidth), &manualCrawling._forwardBackwardRatio); AlienGui::EndIndent(); @@ -551,14 +551,14 @@ void _NodeEditorWidget::processNodeAttributes() // Defender mode auto& defender = std::get(cellTypeNode._cellType); - AlienGui::Combo(AlienGui::ComboParameters().name("Mode").values(Const::DefenderModeStrings).textWidth(rightColumnWidth), defender._mode); + AlienGui::Combo(AlienGui::ComboParameters().name(_("Mode")).values(Const::DefenderModeStrings).textWidth(rightColumnWidth), defender._mode); } else if (nodeType == CellType_Reconnector) { // Mode selection auto& reconnector = std::get(cellTypeNode._cellType); auto mode = reconnector.getMode(); - if (AlienGui::Combo(AlienGui::ComboParameters().name("Mode").values(Const::ReconnectorModeStrings).textWidth(rightColumnWidth), mode)) { + if (AlienGui::Combo(AlienGui::ComboParameters().name(_("Mode")).values(Const::ReconnectorModeStrings).textWidth(rightColumnWidth), mode)) { reconnector._mode = createReconnectorModeGenomeDesc(mode); } @@ -569,19 +569,19 @@ void _NodeEditorWidget::processNodeAttributes() AlienGui::BeginIndent(); auto& freeCell = std::get(reconnector._mode); AlienGui::ColorCheckboxes( - AlienGui::ColorCheckboxesParameters().customizationColors(customizationColors).name("Restrict to colors").textWidth(rightColumnWidth), + AlienGui::ColorCheckboxesParameters().customizationColors(customizationColors).name(_("Restrict to colors")).textWidth(rightColumnWidth), freeCell._restrictToColors); AlienGui::EndIndent(); } else if (mode == ReconnectorMode_Creature) { AlienGui::BeginIndent(); auto& creature = std::get(reconnector._mode); - AlienGui::InputOptionalInt(AlienGui::InputIntParameters().name("Min creature cells").textWidth(rightColumnWidth), creature._minNumCells); - AlienGui::InputOptionalInt(AlienGui::InputIntParameters().name("Max creature cells").textWidth(rightColumnWidth), creature._maxNumCells); + AlienGui::InputOptionalInt(AlienGui::InputIntParameters().name(_("Min creature cells")).textWidth(rightColumnWidth), creature._minNumCells); + AlienGui::InputOptionalInt(AlienGui::InputIntParameters().name(_("Max creature cells")).textWidth(rightColumnWidth), creature._maxNumCells); AlienGui::ColorCheckboxes( - AlienGui::ColorCheckboxesParameters().customizationColors(customizationColors).name("Restrict to colors").textWidth(rightColumnWidth), + AlienGui::ColorCheckboxesParameters().customizationColors(customizationColors).name(_("Restrict to colors")).textWidth(rightColumnWidth), creature._restrictToColors); AlienGui::Combo( - AlienGui::ComboParameters().name("Restrict to lineage").values({"No", "Same lineage", "Other lineage"}).textWidth(rightColumnWidth), + AlienGui::ComboParameters().name(_("Restrict to lineage")).values({_("No"), _("Same lineage"), _("Other lineage")}).textWidth(rightColumnWidth), creature._restrictToLineage); AlienGui::EndIndent(); } @@ -590,23 +590,23 @@ void _NodeEditorWidget::processNodeAttributes() // Countdown auto& detonator = std::get(cellTypeNode._cellType); - AlienGui::InputInt(AlienGui::InputIntParameters().name("Countdown").textWidth(rightColumnWidth), detonator._countdown); + AlienGui::InputInt(AlienGui::InputIntParameters().name(_("Countdown")).textWidth(rightColumnWidth), detonator._countdown); } else if (nodeType == CellType_Digestor) { auto& digestor = std::get(cellTypeNode._cellType); AlienGui::SliderFloat( - AlienGui::SliderFloatParameters().name("Energy conductivity").max(1.0f).format("%.2f").textWidth(rightColumnWidth), + AlienGui::SliderFloatParameters().name(_("Energy conductivity")).max(1.0f).format("%.2f").textWidth(rightColumnWidth), &digestor._rawEnergyConductivity); auto rawEnergyConversionRate = digestor.getRawEnergyConversionRate(); AlienGui::SliderFloat( - AlienGui::SliderFloatParameters().name("Energy conversion").max(1.0f).format("%.2f").textWidth(rightColumnWidth), &rawEnergyConversionRate); + AlienGui::SliderFloatParameters().name(_("Energy conversion")).max(1.0f).format("%.2f").textWidth(rightColumnWidth), &rawEnergyConversionRate); digestor.setRawEnergyConversionRate(rawEnergyConversionRate); } else if (nodeType == CellType_Memory) { // Mode selection auto& memory = std::get(cellTypeNode._cellType); auto mode = memory.getMode(); - if (AlienGui::Combo(AlienGui::ComboParameters().name("Mode").values(Const::MemoryModeStrings).textWidth(rightColumnWidth), mode)) { + if (AlienGui::Combo(AlienGui::ComboParameters().name(_("Mode")).values(Const::MemoryModeStrings).textWidth(rightColumnWidth), mode)) { memory._mode = createMemoryModeGenomeDesc(mode); if (mode == MemoryMode_SignalRecorder || mode == MemoryMode_SignalStorage) { memory._signalEntries.resize(8, SignalEntryGenomeDesc()); @@ -617,13 +617,13 @@ void _NodeEditorWidget::processNodeAttributes() if (mode == MemoryMode_SignalDelay) { AlienGui::BeginIndent(); auto& signalDelay = std::get(memory._mode); - AlienGui::InputInt(AlienGui::InputIntParameters().name("Delay").textWidth(rightColumnWidth), signalDelay._delay); + AlienGui::InputInt(AlienGui::InputIntParameters().name(_("Delay")).textWidth(rightColumnWidth), signalDelay._delay); AlienGui::EndIndent(); } else if (mode == MemoryMode_SignalRecorder) { AlienGui::BeginIndent(); auto& signalRecorder = std::get(memory._mode); - AlienGui::Checkbox(AlienGui::CheckboxParameters().name("Read only").textWidth(rightColumnWidth), signalRecorder._readOnly); - if (AlienGui::Button(AlienGui::ButtonParameters().buttonText("Edit").name("Signal buffer").textWidth(rightColumnWidth))) { + AlienGui::Checkbox(AlienGui::CheckboxParameters().name(_("Read only")).textWidth(rightColumnWidth), signalRecorder._readOnly); + if (AlienGui::Button(AlienGui::ButtonParameters().buttonText(_("Edit")).name(_("Signal buffer")).textWidth(rightColumnWidth))) { SignalsBufferDialog::get().open( memory._signalEntries, [&memory](std::vector const& entries) { memory._signalEntries = entries; }); } @@ -631,8 +631,8 @@ void _NodeEditorWidget::processNodeAttributes() } else if (mode == MemoryMode_SignalStorage) { AlienGui::BeginIndent(); auto& signalStorage = std::get(memory._mode); - AlienGui::Checkbox(AlienGui::CheckboxParameters().name("Read only").textWidth(rightColumnWidth), signalStorage._readOnly); - if (AlienGui::Button(AlienGui::ButtonParameters().buttonText("Edit").name("Signal buffer").textWidth(rightColumnWidth))) { + AlienGui::Checkbox(AlienGui::CheckboxParameters().name(_("Read only")).textWidth(rightColumnWidth), signalStorage._readOnly); + if (AlienGui::Button(AlienGui::ButtonParameters().buttonText(_("Edit")).name(_("Signal buffer")).textWidth(rightColumnWidth))) { SignalsBufferDialog::get().open( memory._signalEntries, [&memory](std::vector const& entries) { memory._signalEntries = entries; }); } @@ -641,7 +641,7 @@ void _NodeEditorWidget::processNodeAttributes() AlienGui::BeginIndent(); auto& signalIntegrator = std::get(memory._mode); AlienGui::SliderFloat( - AlienGui::SliderFloatParameters().name("New signal weight").max(1.0f).format("%.2f").textWidth(rightColumnWidth), + AlienGui::SliderFloatParameters().name(_("New signal weight")).max(1.0f).format("%.2f").textWidth(rightColumnWidth), &signalIntegrator._newSignalWeight); AlienGui::EndIndent(); } @@ -651,13 +651,13 @@ void _NodeEditorWidget::processNodeAttributes() bit[i] = (memory._channelBitMask & (1 << i)) != 0; } AlienGui::MultiCheckboxes( - AlienGui::MultiCheckboxesParameters().name("Channel mask bit 0-3").textWidth(rightColumnWidth), bit[0], bit[1], bit[2], bit[3]); + AlienGui::MultiCheckboxesParameters().name(_("Channel mask bit 0-3")).textWidth(rightColumnWidth), bit[0], bit[1], bit[2], bit[3]); AlienGui::MultiCheckboxes( - AlienGui::MultiCheckboxesParameters().name("Channel mask bit 4-7").textWidth(rightColumnWidth), bit[4], bit[5], bit[6], bit[7]); + AlienGui::MultiCheckboxesParameters().name(_("Channel mask bit 4-7")).textWidth(rightColumnWidth), bit[4], bit[5], bit[6], bit[7]); AlienGui::MultiCheckboxes( - AlienGui::MultiCheckboxesParameters().name("Channel mask bit 8-11").textWidth(rightColumnWidth), bit[8], bit[9], bit[10], bit[11]); + AlienGui::MultiCheckboxesParameters().name(_("Channel mask bit 8-11")).textWidth(rightColumnWidth), bit[8], bit[9], bit[10], bit[11]); AlienGui::MultiCheckboxes( - AlienGui::MultiCheckboxesParameters().name("Channel mask bit 12-15").textWidth(rightColumnWidth), bit[12], bit[13], bit[14], bit[15]); + AlienGui::MultiCheckboxesParameters().name(_("Channel mask bit 12-15")).textWidth(rightColumnWidth), bit[12], bit[13], bit[14], bit[15]); memory._channelBitMask = 0; for (int i = 0; i < NEURONS_PER_CELL; ++i) { if (bit[i]) { @@ -670,7 +670,7 @@ void _NodeEditorWidget::processNodeAttributes() // Mode selection auto& communicator = std::get(cellTypeNode._cellType); auto mode = communicator.getMode(); - if (AlienGui::Combo(AlienGui::ComboParameters().name("Mode").values(Const::CommunicatorModeStrings).textWidth(rightColumnWidth), mode)) { + if (AlienGui::Combo(AlienGui::ComboParameters().name(_("Mode")).values(Const::CommunicatorModeStrings).textWidth(rightColumnWidth), mode)) { communicator._mode = createCommunicatorModeGenomeDesc(mode); } @@ -678,17 +678,17 @@ void _NodeEditorWidget::processNodeAttributes() if (mode == CommunicatorMode_Sender) { AlienGui::BeginIndent(); auto& sender = std::get(communicator._mode); - AlienGui::SliderInt(AlienGui::SliderIntParameters().name("Range").min(0).max(20).textWidth(rightColumnWidth), &sender._range); - AlienGui::Checkbox(AlienGui::CheckboxParameters().name("One-way").textWidth(rightColumnWidth), sender._oneway); + AlienGui::SliderInt(AlienGui::SliderIntParameters().name(_("Range")).min(0).max(20).textWidth(rightColumnWidth), &sender._range); + AlienGui::Checkbox(AlienGui::CheckboxParameters().name(_("One-way")).textWidth(rightColumnWidth), sender._oneway); AlienGui::EndIndent(); } else if (mode == CommunicatorMode_Receiver) { AlienGui::BeginIndent(); auto& receiver = std::get(communicator._mode); AlienGui::ColorCheckboxes( - AlienGui::ColorCheckboxesParameters().customizationColors(customizationColors).name("Restrict to colors").textWidth(rightColumnWidth), + AlienGui::ColorCheckboxesParameters().customizationColors(customizationColors).name(_("Restrict to colors")).textWidth(rightColumnWidth), receiver._restrictToColors); AlienGui::Combo( - AlienGui::ComboParameters().name("Restrict to lineage").values({"No", "Same lineage", "Other lineage"}).textWidth(rightColumnWidth), + AlienGui::ComboParameters().name(_("Restrict to lineage")).values({_("No"), _("Same lineage"), _("Other lineage")}).textWidth(rightColumnWidth), receiver._restrictToLineage); AlienGui::EndIndent(); @@ -704,12 +704,12 @@ void _NodeEditorWidget::processNodeAttributes() void _NodeEditorWidget::processNoSelection() { - AlienGui::Group(AlienGui::GroupParameters().text("Selected node")); + AlienGui::Group(AlienGui::GroupParameters().text(_("Selected node"))); if (ImGui::BeginChild("overlay", ImVec2(0, 0), 0)) { auto startPos = ImGui::GetCursorScreenPos(); auto size = ImGui::GetContentRegionAvail(); AlienGui::DisabledField(); - auto text = "No node is selected"; + auto text = _("No node is selected"); auto textSize = ImGui::CalcTextSize(text); ImVec2 textPos(startPos.x + size.x / 2 - textSize.x / 2, startPos.y + size.y / 2 - textSize.y / 2); ImGui::GetWindowDrawList()->AddText(textPos, ImGui::GetColorU32(ImGuiCol_Text), text); @@ -721,7 +721,7 @@ void _NodeEditorWidget::processNeuralNetEditor() { AlienGui::MoveTickUp(); AlienGui::MoveTickUp(); - AlienGui::Group(AlienGui::GroupParameters().text("Neural network")); + AlienGui::Group(AlienGui::GroupParameters().text(_("Neural network"))); auto& node = _editData->getSelectedNodeRef(); _neuralNetWidget->process( diff --git a/source/Gui/PreviewWidget.cpp b/source/Gui/PreviewWidget.cpp index c6b8380ed..004355bc0 100644 --- a/source/Gui/PreviewWidget.cpp +++ b/source/Gui/PreviewWidget.cpp @@ -133,7 +133,7 @@ namespace void _PreviewWidget::processCreaturePreviews() { - AlienGui::Group(AlienGui::GroupParameters().text("Preview").highlighted(true)); + AlienGui::Group(AlienGui::GroupParameters().text(_("Preview")).highlighted(true)); auto previewRawData = _SimulationFacade::get()->getPreviewData(); @@ -178,7 +178,7 @@ void _PreviewWidget::processActionBar() AlienGui::Separator(); // Alternatives: ICON_FA_GEM, ICON_FA_FIRE, ICON_FA_CUDA if (AlienGui::SelectableButton( - AlienGui::SelectableButtonParameters().name(ICON_FA_DICE_D20).tooltip("Activates a more detail simulation including signals and muscles"), + AlienGui::SelectableButtonParameters().name(ICON_FA_DICE_D20).tooltip(_("Activates a more detail simulation including signals and muscles")), _editData->detailSimulation)) { onRestart(); } @@ -188,7 +188,7 @@ void _PreviewWidget::processActionBar() PreviewSettingsDialog::get().setEditData(_genomeEditData); PreviewSettingsDialog::get().open(); } - AlienGui::Tooltip("Preview settings"); + AlienGui::Tooltip(_("Preview settings")); ImGui::SameLine(); AlienGui::VerticalSeparator(20.0f); @@ -234,7 +234,7 @@ void _PreviewWidget::processActionBar() ImGui::SameLine(); ImGui::SetNextItemWidth(scale(90.0f)); - ImGui::SliderInt("##TPSRestriction", &_editData->simulationSpeed, 1, 100, "%d%% speed", ImGuiSliderFlags_None); + ImGui::SliderInt("##TPSRestriction", &_editData->simulationSpeed, 1, 100, _("%d%% speed"), ImGuiSliderFlags_None); _editData->simulationSpeed = std::clamp(_editData->simulationSpeed, 1, 100); ImGui::SameLine(); diff --git a/source/Gui/translations/en.json b/source/Gui/translations/en.json index 61ee423d4..3ee5da40c 100644 --- a/source/Gui/translations/en.json +++ b/source/Gui/translations/en.json @@ -1086,5 +1086,282 @@ "within the same cell network. If multiple such transmitter cells are present at certain distances, energy can be transmitted ": "within the same cell network. If multiple such transmitter cells are present at certain distances, energy can be transmitted ", "workspace contains simulations that come along with the released versions. They cover a wide range and exploit different ": "workspace contains simulations that come along with the released versions. They cover a wide range and exploit different ", "write access to its own ": "write access to its own ", - "you choose a cell function, this tooltip will be updated to provide more specific information. ": "you choose a cell function, this tooltip will be updated to provide more specific information. " -} \ No newline at end of file + "you choose a cell function, this tooltip will be updated to provide more specific information. ": "you choose a cell function, this tooltip will be updated to provide more specific information. ", + " (root)": " (root)", + " @": " @", + " Bytes": " Bytes", + " K": " K", + " KB": " KB", + " creature": " creature", + " creatures": " creatures", + " genomes found": " genomes found", + " public": " public", + " simulations found": " simulations found", + " simulators found": " simulators found", + "%d%% speed": "%d%% speed", + "(unnamed)": "(unnamed)", + "...": "...", + "": "", + "A": "A", + "A cell connection is a bond between two cells. It stores the reference distance and on each side a reference angle to a possibly further cell connection. The reference distance and angles are calculated when the connection is established. As soon as the actual distance deviates from the reference distance, a pulling/pushing force is applied at both ends. Furthermore, tangential forces are applied at both ends in the case of an angle mismatch.": "A cell connection is a bond between two cells. It stores the reference distance and on each side a reference angle to a possibly further cell connection. The reference distance and angles are calculated when the connection is established. As soon as the actual distance deviates from the reference distance, a pulling/pushing force is applied at both ends. Furthermore, tangential forces are applied at both ends in the case of an angle mismatch.", + "A cell network is a connected graph consisting of cells and cell connections. Two cells in a network are therefore connected to each other directly or via other cells. A cell network physically represents a particular body.": "A cell network is a connected graph consisting of cells and cell connections. Two cells in a network are therefore connected to each other directly or via other cells. A cell network physically represents a particular body.", + "A genome in ALIEN may describe several cell networks, which are hierarchically structured und possibly connected when constructed. More precisely, it means that there is a top-level blueprint describing a certain network. If there are further constructor cells within this network, they can also contain further genomes, which in turn describe other cell networks and so on.": "A genome in ALIEN may describe several cell networks, which are hierarchically structured und possibly connected when constructed. More precisely, it means that there is a top-level blueprint describing a certain network. If there are further constructor cells within this network, they can also contain further genomes, which in turn describe other cell networks and so on.", + "A simple creature first needs a constructor cell that contains its genome and is responsible for self-replication. The constructor cell is automatically triggered and generates (as soon as enough energy is available) the cell network of the offspring built cell by cell as described in its genome. The genome for the offspring is also copied and placed into the constructor cell of the offspring.": "A simple creature first needs a constructor cell that contains its genome and is responsible for self-replication. The constructor cell is automatically triggered and generates (as soon as enough energy is available) the cell network of the offspring built cell by cell as described in its genome. The genome for the offspring is also copied and placed into the constructor cell of the offspring.", + "ALIEN comes with a lot of simulation files that can be found in the browser window. They are good for experimenting with certain aspects of the program. We pick some examples to give a short overview:": "ALIEN comes with a lot of simulation files that can be found in the browser window. They are good for experimenting with certain aspects of the program. We pick some examples to give a short overview:", + "ALIEN offers the possibility for users to customize the basic entities through a color system with 7 different colors. More precisely, each cell is assigned a specific color, allowing the application of different simulation parameter values based on the cell's color. This enables the creation of specific conditions for populations coexisting in a shared world. For example, plant-like organisms may have a higher absorption rate for radiation particles, so they can get their energy from that.": "ALIEN offers the possibility for users to customize the basic entities through a color system with 7 different colors. More precisely, each cell is assigned a specific color, allowing the application of different simulation parameter values based on the cell's color. This enables the creation of specific conditions for populations coexisting in a shared world. For example, plant-like organisms may have a higher absorption rate for radiation particles, so they can get their energy from that.", + "ActFn change probability": "ActFn change probability", + "Activates a more detail simulation including signals and muscles": "Activates a more detail simulation including signals and muscles", + "Add node mutations": "Add node mutations", + "Adding energy to a simulation can increase the available resources and thus the population. There is a convenient way to directly feed all constructor cells with additional energy. This can be achieved by enabling the 'External energy control' expert settings in the simulation parameter window. Next, set the amount of energy to be added (for instance, 1M could sustain 10K cells if each cell has 100 energy units). The external energy is not added instantly but at a rate that can be specified under 'inflow'.": "Adding energy to a simulation can increase the available resources and thus the population. There is a convenient way to directly feed all constructor cells with additional energy. This can be achieved by enabling the 'External energy control' expert settings in the simulation parameter window. Next, set the amount of energy to be added (for instance, 1M could sustain 10K cells if each cell has 100 energy units). The external energy is not added instantly but at a rate that can be specified under 'inflow'.", + "Additive": "Additive", + "Adopt parameters": "Adopt parameters", + "All parameters relevant to the simulation can be adjusted here. By default, the parameters are set uniformly for the entire world. However, it is also possible to allow certain parameters to vary locally in special zones. To do this, you can create a new tab in the simulation parameter window by clicking on the '+' button. It adds a spatially (fuzzy) delimited area where the global parameters can be overwritten. This zone is also visible by a different color.": "All parameters relevant to the simulation can be adjusted here. By default, the parameters are set uniformly for the entire world. However, it is also possible to allow certain parameters to vary locally in special zones. To do this, you can create a new tab in the simulation parameter window by clicking on the '+' button. It adds a spatially (fuzzy) delimited area where the global parameters can be overwritten. This zone is also visible by a different color.", + "An energy particle is a particle which has only an energy value, position and velocity. Unlike cells, they cannot form networks or perform any additional functions. Energy particles are produced by cells as radiation or during decay and can, in turn, also be absorbed.": "An energy particle is a particle which has only an energy value, position and velocity. Unlike cells, they cannot form networks or perform any additional functions. Energy particles are produced by cells as radiation or during decay and can, in turn, also be absorbed.", + "Another option is to inject the genome into an existing organism. To do this, you must select the organism and click on 'Inspect principal genome' in the editor menu. A window will open where you see the existing genome of that creature. Then you can inject your own genome by invoking the 'Inject from editor' button.": "Another option is to inject the genome into an existing organism. To do this, you must select the organism and click on 'Inspect principal genome' in the editor menu. A window will open where you see the existing genome of that creature. Then you can inject your own genome by invoking the 'Inject from editor' button.", + "Apply meta-mutations": "Apply meta-mutations", + "Attraction repulsion ratio": "Attraction repulsion ratio", + "Auto trigger interval": "Auto trigger interval", + "Base properties": "Base properties", + "Base properties and info": "Base properties and info", + "Basic physical properties can be modified in these settings. This includes adjusting the radiation intensity, various thresholds, and the motion algorithm. Changes can have significant effects on performance and, in the worst case, may lead to program crashes.": "Basic physical properties can be modified in these settings. This includes adjusting the radiation intensity, various thresholds, and the motion algorithm. Changes can have significant effects on performance and, in the worst case, may lead to program crashes.", + "Bias change sigma": "Bias change sigma", + "Bugs and Flowers/Example": "Bugs and Flowers/Example", + "By attaching higher-level functions to particle networks, complex multi-cellular organisms can be modeled. They can evolve over time as they are subject to mutations. The following examples consist of homogeneous as well as changing worlds populated by self-reproducing agents. Different selection pressures control evolution.": "By attaching higher-level functions to particle networks, complex multi-cellular organisms can be modeled. They can evolve over time as they are subject to mutations. The following examples consist of homogeneous as well as changing worlds populated by self-reproducing agents. Different selection pressures control evolution.", + "By customizing the cells according to their color, it is possible to specify different types of organisms. There are many examples that feature two classes: plants and herbivores. Plants are able to consume radiation particles, while herbivores can consume plants. This simple relationship already provides interesting dynamics, as the following examples show.": "By customizing the cells according to their color, it is possible to specify different types of organisms. There are many examples that feature two classes: plants and herbivores. Plants are able to consume radiation particles, while herbivores can consume plants. This simple relationship already provides interesting dynamics, as the following examples show.", + "Cell type mode mut.": "Cell type mode mut.", + "Cell type mode mutations": "Cell type mode mutations", + "Cell type mutations": "Cell type mutations", + "Cell type property mut.": "Cell type property mut.", + "Cell type property mutations": "Cell type property mutations", + "Cells are the basic building blocks that make up everything. They can be connected to each others, possibly attached to the background (to model barriers), possess special functions and transport signals. Additionally, cells have various physical properties, including": "Cells are the basic building blocks that make up everything. They can be connected to each others, possibly attached to the background (to model barriers), possess special functions and transport signals. Additionally, cells have various physical properties, including", + "Cells can produce signals comprising of 8 values, primarily utilized for controlling cell functions and sometimes referred to as channel #0 to channel #7. The states are refreshed periodically, specifically when the cell functions are executed. To be more precise, each cell function is executed at regular time intervals (every 6 time steps). The 'execution order number' specifies the exact time offset within those intervals.": "Cells can produce signals comprising of 8 values, primarily utilized for controlling cell functions and sometimes referred to as channel #0 to channel #7. The states are refreshed periodically, specifically when the cell functions are executed. To be more precise, each cell function is executed at regular time intervals (every 6 time steps). The 'execution order number' specifies the exact time offset within those intervals.", + "Change the color of all nodes with a certain color": "Change the color of all nodes with a certain color", + "Change visibility: public ": "Change visibility: public ", + "Change visibility: public  private and private  public": "Change visibility: public  private and private  public", + "Channel mask bit 0-3": "Channel mask bit 0-3", + "Channel mask bit 12-15": "Channel mask bit 12-15", + "Channel mask bit 4-7": "Channel mask bit 4-7", + "Channel mask bit 8-11": "Channel mask bit 8-11", + "Click to edit": "Click to edit", + "Clone genome": "Clone genome", + "Close all tabs except the current one": "Close all tabs except the current one", + "Complex Evolution Testbed/Example": "Complex Evolution Testbed/Example", + "Concatenations": "Concatenations", + "Connection mutations": "Connection mutations", + "Connection weight mutations": "Connection weight mutations", + "Connection weights": "Connection weights", + "Construction": "Construction", + "Construction angle": "Construction angle", + "Construction properties": "Construction properties", + "Constructor mutations": "Constructor mutations", + "Constructor toggle probability": "Constructor toggle probability", + "Constructor: A constructor can build a cell network based on a built-in genome. The construction is done cell by cell and requires energy. A constructor can either be controlled via signals or become active automatically (default).": "Constructor: A constructor can build a cell network based on a built-in genome. The construction is done cell by cell and requires energy. A constructor can either be controlled via signals or become active automatically (default).", + "Copy genome to clipboard": "Copy genome to clipboard", + "Copy node section mutations": "Copy node section mutations", + "Countdown": "Countdown", + "Create a seed with current genome with free energy supply": "Create a seed with current genome with free energy supply", + "Create a seed with current genome without free energy supply": "Create a seed with current genome without free energy supply", + "Create save point in this tab": "Create save point in this tab", + "Deduced": "Deduced", + "Deep Down Below/Selected Results": "Deep Down Below/Selected Results", + "Delay": "Delay", + "Delete gene mutations": "Delete gene mutations", + "Delete node mutations": "Delete node mutations", + "Delete root gene": "Delete root gene", + "Demos/Perpetual Motion Machine": "Demos/Perpetual Motion Machine", + "Demos/Stormy Night": "Demos/Stormy Night", + "Do you really want to delete the root gene? If you decide to do so, the following gene will become the new root gene.": "Do you really want to delete the root gene? If you decide to do so, the following gene will become the new root gene.", + "Do you really want to swap the root gene?": "Do you really want to swap the root gene?", + "Duplicate gene mutations": "Duplicate gene mutations", + "EN": "EN", + "Each particle can be equipped with higher-level functions including sensors, muscles, neurons, constructors, etc. that allow to mimic certain functionalities of biological cells or of robotic components. Multi-cellular organisms are simulated as networks of particles that exchange energy and information over their bonds. The engine encompasses a genetic system capable of encoding the blueprints of organisms in genomes which are stored in individual cells. The simulator is capable to simulate entire ecosystems inhabited by different populations where every object is composed of interacting particles with specific functions (regardless of whether it models a plant, herbivore, carnivore, virus, environmental structure, etc.).": "Each particle can be equipped with higher-level functions including sensors, muscles, neurons, constructors, etc. that allow to mimic certain functionalities of biological cells or of robotic components. Multi-cellular organisms are simulated as networks of particles that exchange energy and information over their bonds. The engine encompasses a genetic system capable of encoding the blueprints of organisms in genomes which are stored in individual cells. The simulator is capable to simulate entire ecosystems inhabited by different populations where every object is composed of interacting particles with specific functions (regardless of whether it models a plant, herbivore, carnivore, virus, environmental structure, etc.).", + "Edit": "Edit", + "Editor": "Editor", + "Energy conductivity": "Energy conductivity", + "Energy conversion": "Energy conversion", + "Enter directory name": "Enter directory name", + "Enter file name": "Enter file name", + "Enum change probability": "Enum change probability", + "Evolution Sandbox/Example": "Evolution Sandbox/Example", + "Evolving Swarms/Example": "Evolving Swarms/Example", + "Extend gene mutations": "Extend gene mutations", + "Failed to load simulation.": "Failed to load simulation.", + "File name:": "File name:", + "Filename": "Filename", + "Fluids/Pump with Soft-Bodies": "Fluids/Pump with Soft-Bodies", + "For the beginning, however, you can use the example already loaded. Initially, it is advisable to become acquainted with the windows for temporal and spatial controls. The handling should be intuitive and requires no deeper knowledge.": "For the beginning, however, you can use the example already loaded. Initially, it is advisable to become acquainted with the windows for temporal and spatial controls. The handling should be intuitive and requires no deeper knowledge.", + "For the perception of the environment, sensor cells are available. When such a cell is triggered by a signal, it provide information about the relative position of cell concentrations with respect to a specific color, which can be further processed by e.g. cell with neural network.": "For the perception of the environment, sensor cells are available. When such a cell is triggered by a signal, it provide information about the relative position of cell concentrations with respect to a specific color, which can be further processed by e.g. cell with neural network.", + "Forward backward ratio": "Forward backward ratio", + "Front angle": "Front angle", + "Gene index": "Gene index", + "Gene name": "Gene name", + "Gene probability": "Gene probability", + "Generally, in an ALIEN simulation, all objects as well as thermal radiation are modeled by different types of particles moving through an empty space. The following terms are frequently used:": "Generally, in an ALIEN simulation, all objects as well as thermal radiation are modeled by different types of particles moving through an empty space. The following terms are frequently used:", + "Genome injected to ": "Genome injected to ", + "Genome name": "Genome name", + "Geometry mutations": "Geometry mutations", + "Help": "Help", + "Homogeneous cell type": "Homogeneous cell type", + "If enabled, every constructed cell of this gene uses the cell type and its properties of the first node.": "If enabled, every constructed cell of this gene uses the cell type and its properties of the first node.", + "If you want to create individual cells, cell networks, or energy particles, you can open the 'Creator' window. In this window you also find a mode for creating cell structures by freehand drawing on the simulation area. The created cells are equipped with default values and can be modified later if desired.": "If you want to create individual cells, cell networks, or energy particles, you can open the 'Creator' window. In this window you also find a mode for creating cell structures by freehand drawing on the simulation area. The created cells are equipped with default values and can be modified later if desired.", + "If you want to design your own worlds, sceneries or organisms, there are many different editors available, which partially require deeper knowledge. To open the editors, you have to switch to the edit mode (e.g. a click on the icon at the bottom left). A short overview of the possibilities are given below.": "If you want to design your own worlds, sceneries or organisms, there are many different editors available, which partially require deeper knowledge. To open the editors, you have to switch to the edit mode (e.g. a click on the icon at the bottom left). A short overview of the possibilities are given below.", + "In addition to cell functions, a color can be used to perform additional user-defined customization of cells. For this purpose, most simulation parameters can be adjusted separately for each color, if desired. As a result, cells of different colors may have individual properties.": "In addition to cell functions, a color can be used to perform additional user-defined customization of cells. For this purpose, most simulation parameters can be adjusted separately for each color, if desired. As a result, cells of different colors may have individual properties.", + "In addition to the background color, you can determine the coloring of the cells here. Each cell is assigned a specific color, which can be used for customization and which is also used by default for rendering. However, in evolution simulations, it can be very useful to color mutants differently. This allows for better visual evaluation of diversities, mutation rates, and successful mutants, etc. For this purpose, you can switch the cell coloring to the mutation id.": "In addition to the background color, you can determine the coloring of the cells here. Each cell is assigned a specific color, which can be used for customization and which is also used by default for rendering. However, in evolution simulations, it can be very useful to color mutants differently. This allows for better visual evaluation of diversities, mutation rates, and successful mutants, etc. For this purpose, you can switch the cell coloring to the mutation id.", + "In addition, simulations can be scaled up by increasing the size of the world and filling the resulting empty space with copies of the original world. This functionality is available via the resize dialog in the 'Spatial control' window, if you set a new size there and activate 'Scale content'.": "In addition, simulations can be scaled up by increasing the size of the world and filling the resulting empty space with copies of the original world. This functionality is available via the resize dialog in the 'Spatial control' window, if you set a new size there and activate 'Scale content'.", + "In general, an organism in ALIEN consists of a network of cells where the cells work together by communicating with each other through signals.": "In general, an organism in ALIEN consists of a network of cells where the cells work together by communicating with each other through signals.", + "In the 'Genome editor', genomes describing cell networks can be created and modified. Each tab shows the principal part of the genome. It is a sequence of cells that are supposed to be constructed in that order. If one of these cells is a constructor cell, it contains an additional genome that can be edited in a separate tab, if desired.": "In the 'Genome editor', genomes describing cell networks can be created and modified. Each tab shows the principal part of the genome. It is a sequence of cells that are supposed to be constructed in that order. If one of these cells is a constructor cell, it contains an additional genome that can be edited in a separate tab, if desired.", + "In the edit mode, it is possible to push bodies around in a running simulation by holding and moving the right mouse button. With the left mouse button you can drag and drop objects. Please try this out. It can make a lot of fun! The editing mode also allows you to activate lot of editing windows (Pattern editor, Creator, Multiplier, Genome editor, etc.) whose possibilities can be explored over time. Practically all properties of each single particle can be manipulated. In addition, there are mass editing functions available.": "In the edit mode, it is possible to push bodies around in a running simulation by holding and moving the right mouse button. With the left mouse button you can drag and drop objects. Please try this out. It can make a lot of fun! The editing mode also allows you to activate lot of editing windows (Pattern editor, Creator, Multiplier, Genome editor, etc.) whose possibilities can be explored over time. Practically all properties of each single particle can be manipulated. In addition, there are mass editing functions available.", + "In the temporal control window, a simulation can be started or paused. The execution speed may be regulated if necessary. In addition, it is possible to calculate and revert single time steps as well as to make snapshots of a simulation to which one can return at any time without having to reload the simulation from a file.": "In the temporal control window, a simulation can be started or paused. The execution speed may be regulated if necessary. In addition, it is possible to calculate and revert single time steps as well as to make snapshots of a simulation to which one can return at any time without having to reload the simulation from a file.", + "Initial stored energy": "Initial stored energy", + "Inject the current genome to the selected creatures in the simulation": "Inject the current genome to the selected creatures in the simulation", + "It is possible to assign a special function to a cell, which will be executed at regular time intervals. The following functions are implemented:": "It is possible to assign a special function to a cell, which will be executed at regular time intervals. The following functions are implemented:", + "LI": "LI", + "Logged in as ": "Logged in as ", + "Max angle deviation": "Max angle deviation", + "Max creature cells": "Max creature cells", + "Max distance deviation": "Max distance deviation", + "Max energy for storage": "Max energy for storage", + "Max range": "Max range", + "Max value": "Max value", + "Min creature cells": "Min creature cells", + "Min density": "Min density", + "Min range": "Min range", + "Min value": "Min value", + "Move node section mutations": "Move node section mutations", + "Mutation rate": "Mutation rate", + "Mutation rate 1": "Mutation rate 1", + "Mutation rate 2": "Mutation rate 2", + "Mutation rates": "Mutation rates", + "NEW": "NEW", + "Nearly every property of each particle can be viewed and edited. For this purpose, special editing windows can be attached to a particle. To do this, you have to select one or more particles (not too many) and invoke 'Inspect objects' from the editor menu. Each selected particle is now connected to a window. It is even possible to view these editing windows during a running simulation. In this way, you can monitor in real-time how properties of individual particles change over time.": "Nearly every property of each particle can be viewed and edited. For this purpose, special editing windows can be attached to a particle. To do this, you have to select one or more particles (not too many) and invoke 'Inspect objects' from the editor menu. Each selected particle is now connected to a window. It is even possible to view these editing windows during a running simulation. In this way, you can monitor in real-time how properties of individual particles change over time.", + "Nerve: On the one hand, it transfers signals from connected input cells and on the other hand, it can optionally generate signals at specific intervals.": "Nerve: On the one hand, it transfers signals from connected input cells and on the other hand, it can optionally generate signals at specific intervals.", + "Network": "Network", + "Neural network": "Neural network", + "Neural networks are available as cell functions. If a cell is assigned the function 'Neuron', it possesses a small neural network consisting of 8 neurons. However, these networks can be interconnected to form arbitrarily large networks, as each cell receives input from the output of certain connected cells.": "Neural networks are available as cell functions. If a cell is assigned the function 'Neuron', it possesses a small neural network consisting of 8 neurons. However, these networks can be interconnected to form arbitrarily large networks, as each cell receives input from the output of certain connected cells.", + "Neuron mutations": "Neuron mutations", + "Neuron weights": "Neuron weights", + "Neuron: It equips the cell with a small network of 8 neurons. It processes input gained from the signals of connected cells and provides an output signal to other connected cells.": "Neuron: It equips the cell with a small network of 8 neurons. It processes input gained from the signals of connected cells and provides an output signal to other connected cells.", + "New genome": "New genome", + "New signal weight": "New signal weight", + "No": "No", + "No gene is selected": "No gene is selected", + "No node is selected": "No node is selected", + "Node count": "Node count", + "Node index": "Node index", + "Node probability": "Node probability", + "Nodes": "Nodes", + "Not logged in to ": "Not logged in to ", + "Number of branches": "Number of branches", + "Offspring trigger time": "Offspring trigger time", + "On older graphics cards or when using a high resolution (e.g. 4K), it is recommended to reduce the rendered frames per second, as this significantly increases the simulation speed (time steps per second). This adjustment can be made in the display settings.": "On older graphics cards or when using a high resolution (e.g. 4K), it is recommended to reduce the rendered frames per second, as this significantly increases the simulation speed (time steps per second). This adjustment can be made in the display settings.", + "One-way": "One-way", + "Open genome": "Open genome", + "Open genome from file": "Open genome from file", + "Open simulation": "Open simulation", + "Optionally, you can define radiation sources by opening the corresponding editor. Typically, all cells lose energy over time by emitting particles. These energy particles travel through space and can be absorbed by other cells under certain conditions. When no radiation source is defined, energy particles are emitted at the cell's position, resulting in a more or less uniform distribution of energy particles throughout space over time. For certain simulations, especially in modeling plant species, it is beneficial to specify explicit sources where energy particles should be generated. This can be achieved in the 'Radiation sources' window. Even when a source is defined, cells continue to lose the same amount of energy as before. The difference is that particles are now spawned at the specified source. The energy conservation principle remains intact.": "Optionally, you can define radiation sources by opening the corresponding editor. Typically, all cells lose energy over time by emitting particles. These energy particles travel through space and can be absorbed by other cells under certain conditions. When no radiation source is defined, energy particles are emitted at the cell's position, resulting in a more or less uniform distribution of energy particles throughout space over time. For certain simulations, especially in modeling plant species, it is beneficial to specify explicit sources where energy particles should be generated. This can be achieved in the 'Radiation sources' window. Even when a source is defined, cells continue to lose the same amount of energy as before. The difference is that particles are now spawned at the specified source. The energy conservation principle remains intact.", + "Other lineage": "Other lineage", + "Paste genome from clipboard": "Paste genome from clipboard", + "Period": "Period", + "Physical properties of already selected cells and energy particles, such as center velocities, positions, colors, etc., can be conveniently changed in the 'Pattern editor'. In addition, selections can be saved, loaded, copied and pasted.": "Physical properties of already selected cells and energy particles, such as center velocities, positions, colors, etc., can be conveniently changed in the 'Pattern editor'. In addition, selections can be saved, loaded, copied and pasted.", + "Please enter the confirmation code sent to your email address.": "Please enter the confirmation code sent to your email address.", + "Preview": "Preview", + "Preview settings": "Preview settings", + "Primordial Ocean/Selected Results": "Primordial Ocean/Selected Results", + "Range": "Range", + "Read only": "Read only", + "Referenced by": "Referenced by", + "References": "References", + "Regardless of this, many parameters can also be set depending on the cell color. For this purpose click the '+' button beside the parameter. This customization is useful when you want to define different classes of species.": "Regardless of this, many parameters can also be set depending on the cell color. For this purpose click the '+' button beside the parameter. This customization is useful when you want to define different classes of species.", + "Resend": "Resend", + "Resend to other email address": "Resend to other email address", + "Reserved energy": "Reserved energy", + "Resistance to injection": "Resistance to injection", + "Restrict to colors": "Restrict to colors", + "Restrict to lineage": "Restrict to lineage", + "Revert genome to save point": "Revert genome to save point", + "Same lineage": "Same lineage", + "Save genome": "Save genome", + "Save genome to file": "Save genome to file", + "Save simulation": "Save simulation", + "Search": "Search", + "Seed created": "Seed created", + "Selected gene": "Selected gene", + "Selected node": "Selected node", + "Self-replicating Fluid/Initial Setting": "Self-replicating Fluid/Initial Setting", + "Self-replication requires energy, which must be obtained in some way. On the one hand, energy can be acquired by the absorption of energy particles flying around. This can be the main source of energy for plant-like species. On the other hand, there is the possibility to utilize attacker cells. They can attack cells from other organisms by stealing energy from them. If an attacker cell is part of the creature, it must be explicitly triggered by a signal. This signal may come, for example, from another cell equipped with a neural network. The energy obtained by an attacker cell is distributed to nearby constructor or transmitter cells.": "Self-replication requires energy, which must be obtained in some way. On the one hand, energy can be acquired by the absorption of energy particles flying around. This can be the main source of energy for plant-like species. On the other hand, there is the possibility to utilize attacker cells. They can attack cells from other organisms by stealing energy from them. If an attacker cell is part of the creature, it must be explicitly triggered by a signal. This signal may come, for example, from another cell equipped with a neural network. The energy obtained by an attacker cell is distributed to nearby constructor or transmitter cells.", + "Separation": "Separation", + "Server: ": "Server: ", + "Shape generator": "Shape generator", + "Share your genome with other users:\nYour current genome will be uploaded to the server and made visible in the browser.": "Share your genome with other users:\nYour current genome will be uploaded to the server and made visible in the browser.", + "Signal buffer": "Signal buffer", + "Sometimes it is difficult to set precise values in a slider. In this case, you can click on the slider while holding the CTRL key. This allows you to enter the exact value in an input field and confirm it by pressing ENTER.": "Sometimes it is difficult to set precise values in a slider. In this case, you can click on the slider while holding the CTRL key. This allows you to enter the exact value in an input field and confirm it by pressing ENTER.", + "Swap root gene": "Swap root gene", + "Swarms/Space Invaders": "Swarms/Space Invaders", + "Tag for attackers": "Tag for attackers", + "Text to filter search results": "Text to filter search results", + "The blueprints for entire cell networks can be stored in genomes. These genomes are translated into real cell networks by constructor cells and, if necessary, copied to their offspring. Furthermore, injector cells are able to inject their own genome into other constructor cells, which allows to model virus behaviors.": "The blueprints for entire cell networks can be stored in genomes. These genomes are translated into real cell networks by constructor cells and, if necessary, copied to their offspring. Furthermore, injector cells are able to inject their own genome into other constructor cells, which allows to model virus behaviors.", + "The easiest way is to select and move objects with the mouse. You can simply drag and drop cell networks in the simulation view. This also works during running simulations. When the simulation is paused, you can select a rectangular area to be highlighted by holding down the right mouse button. The selection is visually highlighted and can be moved via drag and drop. By holding down the SHIFT button duringa mouse action, only the selected cells and not the associated cell networks are shifted. This can lead to the destruction or formation of cell connections which are not selected.": "The easiest way is to select and move objects with the mouse. You can simply drag and drop cell networks in the simulation view. This also works during running simulations. When the simulation is paused, you can select a rectangular area to be highlighted by holding down the right mouse button. The selection is visually highlighted and can be moved via drag and drop. By holding down the SHIFT button duringa mouse action, only the selected cells and not the associated cell networks are shifted. This can lead to the destruction or formation of cell connections which are not selected.", + "The easiest way to get to know the ALIEN simulator is to download and run an existing simulation file. You can then try out different function and modify the simulation according to your wishes.": "The easiest way to get to know the ALIEN simulator is to download and run an existing simulation file. You can then try out different function and modify the simulation according to your wishes.", + "The existence of matter in the form of cells is a prerequisite for the radiation source to emit particles. Furthermore, the simulation parameters should be adjusted in a way that guarantees a gradual loss of energy from cells over time.": "The existence of matter in the form of cells is a prerequisite for the radiation source to emit particles. Furthermore, the simulation parameters should be adjusted in a way that guarantees a gradual loss of energy from cells over time.", + "The first node cannot be void.": "The first node cannot be void.", + "The last node cannot be void.": "The last node cannot be void.", + "The most direct approach involves using a nerve cell that generates an signal at regular time intervals. The advantage here is that you can precisely configure the length of the time intervals.": "The most direct approach involves using a nerve cell that generates an signal at regular time intervals. The advantage here is that you can precisely configure the length of the time intervals.", + "The mutation rates influence the probability of modifying a genome for the underlying cells. When adjusting these rates, it should be noted that different types of mutations also have different impacts. For instance, a 'Duplication' mutation affects the genome much more invasively than a 'Neural net' mutation, which only adjusts weights and biases. Furthermore, it should be considered that for evolutionary simulations, where individuals require a long time for self-replication, high mutation rates should be avoided. The correct values are best determined through experimentation.": "The mutation rates influence the probability of modifying a genome for the underlying cells. When adjusting these rates, it should be noted that different types of mutations also have different impacts. For instance, a 'Duplication' mutation affects the genome much more invasively than a 'Neural net' mutation, which only adjusts weights and biases. Furthermore, it should be considered that for evolutionary simulations, where individuals require a long time for self-replication, high mutation rates should be avoided. The correct values are best determined through experimentation.", + "The navigation mode is enabled by default and allows you to zoom in (holding the left mouse button) and out (holding the right mouse button) continuously. Alternatively, you can also use the mouse wheel. By holding the middle mouse button and moving the mouse, you can pan the visualized section of the world.": "The navigation mode is enabled by default and allows you to zoom in (holding the left mouse button) and out (holding the right mouse button) continuously. Alternatively, you can also use the mouse wheel. By holding the middle mouse button and moving the mouse, you can pan the visualized section of the world.", + "The principle of energy conservation holds true in a simulation, which means that energy particles cannot spontaneously come into existence out of nothingness. This principle plays a vital role in ensuring the stability of long-term simulations. If a radiation source is defined, it will emit a particle only when a cell somewhere loses energy. Conversely, in the absence of a radiation source, any emitted energy particle would originate directly in the spatial vicinity of the corresponding cell.": "The principle of energy conservation holds true in a simulation, which means that energy particles cannot spontaneously come into existence out of nothingness. This principle plays a vital role in ensuring the stability of long-term simulations. If a radiation source is defined, it will emit a particle only when a cell somewhere loses energy. Conversely, in the absence of a radiation source, any emitted energy particle would originate directly in the spatial vicinity of the corresponding cell.", + "The process for updating the values of a signal is as follows: Firstly, the values of all input signals (i.e. signals from connected cells which matches with the input execution number) are summed up. The resulted sum is then employed as input for the cell function, which may potentially alter the values. Subsequently, the outcome is used to generate an output signal.": "The process for updating the values of a signal is as follows: Firstly, the values of all input signals (i.e. signals from connected cells which matches with the input execution number) are summed up. The resulted sum is then employed as input for the cell function, which may potentially alter the values. Subsequently, the outcome is used to generate an output signal.", + "The spatial control window combines zoom information and settings on the one hand, and scaling functions on the other hand. A quite useful feature in the dialog for scaling/resizing is the option 'Scale content'. If activated, periodic spatial copies of the original world can be made.": "The spatial control window combines zoom information and settings on the one hand, and scaling functions on the other hand. A quite useful feature in the dialog for scaling/resizing is the option 'Scale content'. If activated, periodic spatial copies of the original world can be made.", + "There are basically two modes of how the user can operate in the view where the simulation is shown: a navigation mode and an edit mode. You can switch between these two modes by invoking the edit button at the bottom left of the screen or in the menu via Editor  Activate.": "There are basically two modes of how the user can operate in the view where the simulation is shown: a navigation mode and an edit mode. You can switch between these two modes by invoking the edit button at the bottom left of the screen or in the menu via Editor  Activate.", + "There are powerful sensors available as cell functions for detecting concentrations of specific colors in the surroundings. Organisms equipped with these sensors can perceive their environment, nourish their neural networks, and respond accordingly.": "There are powerful sensors available as cell functions for detecting concentrations of specific colors in the surroundings. Organisms equipped with these sensors can perceive their environment, nourish their neural networks, and respond accordingly.", + "There are several pure physics simulations demonstrating the engines' capability. They are suitable for testing the influence of simulation parameters such as 'Smoothing length', 'Pressure', 'Viscosity', etc.": "There are several pure physics simulations demonstrating the engines' capability. They are suitable for testing the influence of simulation parameters such as 'Smoothing length', 'Pressure', 'Viscosity', etc.", + "These parameter types are particularly important when simulating (self-replicating) agents composed of cell networks, going beyond pure physical simulations. Many of the different cell functions depend on specific parameters, which can be adjusted here. Particularly important are the parameters for mutation rates and the attack functions.With the latter, the food chain between cells of different colors can be configured. For example, in the 'Food chain color matrix' one could specify that cells with a certain color can only consume cells with a certain other color but not themselves.": "These parameter types are particularly important when simulating (self-replicating) agents composed of cell networks, going beyond pure physical simulations. Many of the different cell functions depend on specific parameters, which can be adjusted here. Particularly important are the parameters for mutation rates and the attack functions.With the latter, the food chain between cells of different colors can be configured. For example, in the 'Food chain color matrix' one could specify that cells with a certain color can only consume cells with a certain other color but not themselves.", + "This depends on many factors: On the size of the simulated world, on the mutation rates, on various selection pressures that can be influenced by the simulation parameters and on the self-replication duration. Usually one should wait for several dozen generations, which may correspond to hundreds of thousands or million time steps.In small worlds with smaller organisms and high mutation rates, evolutionary changes can sometimes be observed every minute depending on the hardware. With more complex simulations, you should rather expect a few hours.": "This depends on many factors: On the size of the simulated world, on the mutation rates, on various selection pressures that can be influenced by the simulation parameters and on the self-replication duration. Usually one should wait for several dozen generations, which may correspond to hundreds of thousands or million time steps.In small worlds with smaller organisms and high mutation rates, evolutionary changes can sometimes be observed every minute depending on the hardware. With more complex simulations, you should rather expect a few hours.", + "This gene could not be removed since it is still used by gene ": "This gene could not be removed since it is still used by gene ", + "This gene could not be removed since it is still used by genes ": "This gene could not be removed since it is still used by genes ", + "Time offset": "Time offset", + "To activate most cell functions, an input from a connected cell in the form of a signal is required. The simplest methods to generate a signal are as follows:": "To activate most cell functions, an input from a connected cell in the form of a signal is required. The simplest methods to generate a signal are as follows:", + "To be able to experiment with existing simulations, it is important to know and change the simulation parameters. This can be accomplished in the window 'Simulation parameters'. For example, the radiation intensity can be increased or the friction can be adjusted. Explanations to the individual parameters can be found in the tooltip next to them.": "To be able to experiment with existing simulations, it is important to know and change the simulation parameters. This can be accomplished in the window 'Simulation parameters'. For example, the radiation intensity can be increased or the friction can be adjusted. Explanations to the individual parameters can be found in the tooltip next to them.", + "To perform movements, an organism requires muscle cells. These are also controlled by signals. Muscle cells can work in various modes: they can bend, contract/expand, or generate an impulse.": "To perform movements, an organism requires muscle cells. These are also controlled by signals. Muscle cells can work in various modes: they can bend, contract/expand, or generate an impulse.", + "Transmitter: It distributes energy to other constructors, transmitters or surrounding cells. In particular, it can be used to power active constructors. No signal is required for triggering.": "Transmitter: It distributes energy to other constructors, transmitters or surrounding cells. In particular, it can be used to power active constructors. No signal is required for triggering.", + "Trim gene mutations": "Trim gene mutations", + "Twin Worlds/Example": "Twin Worlds/Example", + "Type-specific properties": "Type-specific properties", + "Value change sigma": "Value change sigma", + "Various examples can be found in the in-game simulation browser demonstrating capabilities of the engine ranging from pure physics examples, self-deploying structures, self-replicators to evolving ecosystems. If not already open, please invoke Network  Browser in the menu bar. Simulations can be conveniently downloaded and uploaded from/to the connected server (alien-project.org by default). In order to upload own simulations to the server or rate other simulations, you need to register a new user, which can be accomplished in the login dialog.": "Various examples can be found in the in-game simulation browser demonstrating capabilities of the engine ranging from pure physics examples, self-deploying structures, self-replicators to evolving ecosystems. If not already open, please invoke Network  Browser in the menu bar. Simulations can be conveniently downloaded and uploaded from/to the connected server (alien-project.org by default). In order to upload own simulations to the server or rate other simulations, you need to register a new user, which can be accomplished in the login dialog.", + "Various mass editing functions are available. On the one hand, the pattern editor allows to change different physical properties of an entire selection. On the other hand, through the 'Tools' menu, the 'Mass operations' dialog can be opened. Here, colors of cells and genomes, energy values, and other properties can be globally modified. The new values will be randomly chosen from a specified range. Cells within a cell networks will be assigned the same value.": "Various mass editing functions are available. On the one hand, the pattern editor allows to change different physical properties of an entire selection. On the other hand, through the 'Tools' menu, the 'Mass operations' dialog can be opened. Here, colors of cells and genomes, energy values, and other properties can be globally modified. The new values will be randomly chosen from a specified range. Cells within a cell networks will be assigned the same value.", + "View": "View", + "Void mutations": "Void mutations", + "Weight change sigma": "Weight change sigma", + "Windows": "Windows", + "You can generate a spore using the corresponding toolbar button. A spore is a single constructor cell containing the specific genome and possessing enough energy to create the main structure described within.": "You can generate a spore using the corresponding toolbar button. A spore is a single constructor cell containing the specific genome and possessing enough energy to create the main structure described within.", + "alien-project": "alien-project", + "fe ": "fe ", + "more...": "more...", + "private": "private", + "public": "public", + "rtificial ": "rtificial ", + "simulations": "simulations", + "v4.8-Evolution/Gradient/Selected Results": "v4.8-Evolution/Gradient/Selected Results", + "Creature with id 0x": "Creature with id 0x", + "Cell with id 0x": "Cell with id 0x", + "Energy particle with id 0x": "Energy particle with id 0x", + "Object id": "Object id", + "Connection #": "Connection #", + "Connected id": "Connected id", + "Creature id": "Creature id", + "Generation": "Generation", + "Num cells": "Num cells", + "Yes": "Yes", + "Ready": "Ready", + "Constructing": "Constructing", + "Activating": "Activating", + "Dying": "Dying", + "Instant dying": "Instant dying", + "Activated": "Activated", + "Exploded": "Exploded", + "properties": "properties", + "State": "State", + "Allow object editing": "Allow object editing", + "Inspect genomes": "Inspect genomes", + "Inspect creatures": "Inspect creatures" +} diff --git a/source/Gui/translations/zh.json b/source/Gui/translations/zh.json index 0b6ef6669..502082178 100644 --- a/source/Gui/translations/zh.json +++ b/source/Gui/translations/zh.json @@ -1209,5 +1209,159 @@ "Enter file name": "输入文件名", "File name:": "文件名:", "Filename": "文件名", - "Search": "搜索" -} \ No newline at end of file + "Search": "搜索", + "Share your genome with other users:\nYour current genome will be uploaded to the server and made visible in the browser.": "与其他用户分享您的基因组:\n当前基因组将被上传到服务器并在浏览器中可见。", + "Clone genome": "克隆基因组", + "Copy genome to clipboard": "复制基因组到剪贴板", + "Paste genome from clipboard": "从剪贴板粘贴基因组", + "Close all tabs except the current one": "关闭除当前标签外的所有标签", + "Create save point in this tab": "在此标签创建保存点", + "Revert genome to save point": "恢复到保存点", + "Change the color of all nodes with a certain color": "更改所有具有指定颜色的节点的颜色", + "Inject the current genome to the selected creatures in the simulation": "将当前基因组注入到模拟中选中的生物", + "Create a seed with current genome without free energy supply": "使用当前基因组创建种子(不提供免费能量)", + "Create a seed with current genome with free energy supply": "使用当前基因组创建种子(提供免费能量)", + "New genome": "新建基因组", + "Genome injected to ": "基因组已注入 ", + " creature": " 个生物", + " creatures": " 个生物", + "Seed created": "种子已创建", + "Connection weights": "连接权重", + "Neuron weights": "神经元权重", + "Base properties and info": "基本属性与信息", + "Mutation rates": "突变率", + "Genome name": "基因组名称", + "Node count": "节点数", + "Front angle": "前向角度", + "Resistance to injection": "注射抗性", + "Apply meta-mutations": "应用元突变", + "Gene index": "基因索引", + "References": "引用", + "Referenced by": "被引用", + "Nodes": "节点", + " (root)": "(根)", + "(unnamed)": "(未命名)", + "Delete root gene": "删除根基因", + "Do you really want to delete the root gene? If you decide to do so, the following gene will become the new root gene.": "您确定要删除根基因吗?如果删除,下一个基因将成为新的根基因。", + "Swap root gene": "交换根基因", + "Do you really want to swap the root gene?": "您确定要交换根基因吗?", + "This gene could not be removed since it is still used by gene ": "无法删除此基因,因为它仍被基因 ", + "This gene could not be removed since it is still used by genes ": "无法删除此基因,因为它仍被基因 ", + "Selected gene": "选中的基因", + "No gene is selected": "未选中基因", + "Base properties": "基本属性", + "Gene name": "基因名称", + "Shape generator": "形状生成器", + "Homogeneous cell type": "同质细胞类型", + "If enabled, every constructed cell of this gene uses the cell type and its properties of the first node.": "启用后,此基因构建的每个细胞均使用第一个节点的细胞类型及其属性。", + "Node index": "节点索引", + "Construction": "构建", + "The first node cannot be void.": "第一个节点不能为空。", + "The last node cannot be void.": "最后一个节点不能为空。", + "Selected node": "选中的节点", + "No node is selected": "未选中节点", + "Deduced": "推导", + "Construction properties": "构建属性", + "Auto trigger interval": "自动触发间隔", + "Offspring trigger time": "子代触发时间", + "Construction angle": "构建角度", + "Reserved energy": "预留能量", + "Separation": "分离", + "Number of branches": "分支数", + "Concatenations": "串联数", + "Type-specific properties": "类型特定属性", + "Max energy for storage": "最大储存能量", + "Initial stored energy": "初始储存能量", + "Tag for attackers": "攻击者标记", + "Min density": "最小密度", + "Restrict to colors": "限制颜色", + "Min creature cells": "最小生物细胞数", + "Max creature cells": "最大生物细胞数", + "Restrict to lineage": "限制谱系", + "Min range": "最小范围", + "Max range": "最大范围", + "Additive": "累加", + "Min value": "最小值", + "Max value": "最大值", + "Time offset": "时间偏移", + "Period": "周期", + "Max angle deviation": "最大角度偏差", + "Forward backward ratio": "前后比", + "Attraction repulsion ratio": "吸引排斥比", + "Max distance deviation": "最大距离偏差", + "Countdown": "倒计时", + "Energy conductivity": "能量传导率", + "Energy conversion": "能量转化率", + "Delay": "延迟", + "Read only": "只读", + "Signal buffer": "信号缓冲区", + "New signal weight": "新信号权重", + "Channel mask bit 0-3": "通道掩码位 0-3", + "Channel mask bit 4-7": "通道掩码位 4-7", + "Channel mask bit 8-11": "通道掩码位 8-11", + "Channel mask bit 12-15": "通道掩码位 12-15", + "Range": "范围", + "One-way": "单向", + "Neural network": "神经网络", + "No": "否", + "Same lineage": "同谱系", + "Other lineage": "其他谱系", + "Connection weight mutations": "连接权重突变", + "Neuron mutations": "神经元突变", + "Cell type property mutations": "细胞类型属性突变", + "Geometry mutations": "几何突变", + "Cell type mode mutations": "细胞类型模式突变", + "Cell type mutations": "细胞类型突变", + "Void mutations": "空突变", + "Extend gene mutations": "扩展基因突变", + "Add node mutations": "添加节点突变", + "Trim gene mutations": "修剪基因突变", + "Delete node mutations": "删除节点突变", + "Duplicate gene mutations": "复制基因突变", + "Delete gene mutations": "删除基因突变", + "Copy node section mutations": "复制节点段突变", + "Move node section mutations": "移动节点段突变", + "Constructor mutations": "构建细胞突变", + "Mutation rate 1": "突变率 1", + "Mutation rate 2": "突变率 2", + "Mutation rate": "突变率", + "Node probability": "节点概率", + "Value change sigma": "值变化 sigma", + "Weight change sigma": "权重变化 sigma", + "Bias change sigma": "偏置变化 sigma", + "ActFn change probability": "激活函数变化概率", + "Gene probability": "基因概率", + "Enum change probability": "枚举变化概率", + "Constructor toggle probability": "构建细胞切换概率", + "Connection mutations": "连接突变", + "Cell type property mut.": "细胞类型属性突变", + "Cell type mode mut.": "细胞类型模式突变", + "Edit": "编辑", + "Click to edit": "点击编辑", + "Preview": "预览", + "Activates a more detail simulation including signals and muscles": "激活更详细的模拟,包括信号和肌肉", + "Preview settings": "预览设置", + "%d%% speed": "%d%% 速度", + "Creature with id 0x": "生物 ID 0x", + "Cell with id 0x": "细胞 ID 0x", + "Energy particle with id 0x": "能量粒子 ID 0x", + "Object id": "对象 ID", + "Connection #": "连接 #", + "Connected id": "连接 ID", + "Creature id": "生物 ID", + "Generation": "世代", + "Num cells": "细胞数", + "Yes": "是", + "Ready": "就绪", + "Constructing": "构建中", + "Activating": "激活中", + "Dying": "死亡中", + "Instant dying": "立即死亡", + "Activated": "已激活", + "Exploded": "已爆炸", + "properties": "属性", + "State": "状态", + "Allow object editing": "允许编辑对象", + "Inspect genomes": "检查基因组", + "Inspect creatures": "检查生物" +}