diff --git a/res/layouts/pages/languages.xml.lua b/res/layouts/pages/languages.xml.lua index be6c5905..aa0e6597 100644 --- a/res/layouts/pages/languages.xml.lua +++ b/res/layouts/pages/languages.xml.lua @@ -12,7 +12,7 @@ function on_open() for _,k in ipairs(names) do panel:add(string.format( "", - string.format("gui.set_locale(%q) menu:back()", invlocales[k]), k + string.format("core.set_setting('ui.language', %q) menu:back()", invlocales[k]), k )) end panel:add("") diff --git a/src/data/setting.cpp b/src/data/setting.cpp index d39f2c08..c1de4b6c 100644 --- a/src/data/setting.cpp +++ b/src/data/setting.cpp @@ -32,3 +32,7 @@ std::string FlagSetting::toString() const { return "invalid format"; } } + +std::string StringSetting::toString() const { + return value; +} diff --git a/src/data/setting.h b/src/data/setting.h index 2ecbd46c..8a84ce81 100644 --- a/src/data/setting.h +++ b/src/data/setting.h @@ -56,7 +56,7 @@ public: }); } - T get() const { + const T& get() const { return value; } @@ -160,8 +160,7 @@ public: FlagSetting( bool value, setting_format format=setting_format::simple - ) : ObservableSetting(value, format) - {} + ) : ObservableSetting(value, format) {} void toggle() { set(!get()); @@ -170,4 +169,14 @@ public: virtual std::string toString() const override; }; +class StringSetting : public ObservableSetting { +public: + StringSetting( + std::string value, + setting_format format=setting_format::simple + ) : ObservableSetting(value, format) {} + + virtual std::string toString() const override; +}; + #endif // DATA_SETTING_H_ diff --git a/src/engine.cpp b/src/engine.cpp index 306b4847..4f7c03ac 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -71,16 +71,18 @@ Engine::Engine(EngineSettings& settings, EnginePaths* paths) create_channel(this, "ui", settings.audio.volumeUI); gui = std::make_unique(); - if (settings.ui.language == "auto") { - settings.ui.language = langs::locale_by_envlocale( + if (settings.ui.language.get() == "auto") { + settings.ui.language.set(langs::locale_by_envlocale( platform::detect_locale(), paths->getResources() - ); + )); } if (ENGINE_VERSION_INDEV) { menus::create_version_label(this); } - setLanguage(settings.ui.language); + keepAlive(settings.ui.language.observe([=](auto lang) { + setLanguage(lang); + }, true)); addWorldGenerators(); scripting::initialize(this); @@ -275,7 +277,6 @@ void Engine::setScreen(std::shared_ptr screen) { } void Engine::setLanguage(std::string locale) { - settings.ui.language = locale; langs::setup(paths->getResources(), locale, contentPacks); menus::create_menus(this); } diff --git a/src/files/settings_io.cpp b/src/files/settings_io.cpp index ce8c7e38..66cf60d6 100644 --- a/src/files/settings_io.cpp +++ b/src/files/settings_io.cpp @@ -32,6 +32,8 @@ SettingsHandler::SettingsHandler(EngineSettings& settings) { map.emplace("graphics.fog-curve", &settings.graphics.fogCurve); map.emplace("graphics.backlight", &settings.graphics.backlight); map.emplace("graphics.gamma", &settings.graphics.gamma); + + map.emplace("ui.language", &settings.ui.language); } std::unique_ptr SettingsHandler::getValue(const std::string& name) const { @@ -46,6 +48,8 @@ std::unique_ptr SettingsHandler::getValue(const std::string& nam return dynamic::Value::of((integer_t)integer->get()); } else if (auto flag = dynamic_cast(setting)) { return dynamic::Value::boolean(flag->get()); + } else if (auto string = dynamic_cast(setting)) { + return dynamic::Value::of(string->get()); } else { throw std::runtime_error("type is not implemented for '"+name+"'"); } @@ -88,7 +92,7 @@ static void set_numeric_value(T* setting, const dynamic::Value& value) { void SettingsHandler::setValue(const std::string& name, const dynamic::Value& value) { auto found = map.find(name); if (found == map.end()) { - throw std::runtime_error("setting '"+name+"' does Pnot exist"); + throw std::runtime_error("setting '"+name+"' does not exist"); } auto setting = found->second; if (auto number = dynamic_cast(setting)) { @@ -97,6 +101,23 @@ void SettingsHandler::setValue(const std::string& name, const dynamic::Value& va set_numeric_value(integer, value); } else if (auto flag = dynamic_cast(setting)) { set_numeric_value(flag, value); + } else if (auto string = dynamic_cast(setting)) { + switch (value.type) { + case dynamic::valtype::string: + string->set(std::get(value.value)); + break; + case dynamic::valtype::integer: + string->set(std::to_string(std::get(value.value))); + break; + case dynamic::valtype::number: + string->set(std::to_string(std::get(value.value))); + break; + case dynamic::valtype::boolean: + string->set(std::to_string(std::get(value.value))); + break; + default: + throw std::runtime_error("not implemented for type"); + } } else { throw std::runtime_error("type is not implement - setting '"+name+"'"); } @@ -144,7 +165,7 @@ toml::Wrapper* create_wrapper(EngineSettings& settings) { debug.add("do-write-lights", &settings.debug.doWriteLights); toml::Section& ui = wrapper->add("ui"); - ui.add("language", &settings.ui.language); + ui.add("language", &*settings.ui.language); ui.add("world-preview-size", &*settings.ui.worldPreviewSize); return wrapper.release(); } diff --git a/src/logic/scripting/lua/libgui.cpp b/src/logic/scripting/lua/libgui.cpp index 56960a97..b1399443 100644 --- a/src/logic/scripting/lua/libgui.cpp +++ b/src/logic/scripting/lua/libgui.cpp @@ -385,13 +385,6 @@ static int l_gui_get_locale(lua_State* L) { return 1; } -/// @brief gui.set_locale(locale: string) -> nil -static int l_gui_set_locale(lua_State* L) { - auto locale = lua_tostring(L, 1); - scripting::engine->setLanguage(locale); - return 0; -} - const luaL_Reg guilib [] = { {"get_viewport", lua_wrap_errors}, {"getattr", lua_wrap_errors}, @@ -400,7 +393,6 @@ const luaL_Reg guilib [] = { {"str", lua_wrap_errors}, {"reindex", lua_wrap_errors}, {"get_locale", lua_wrap_errors}, - {"set_locale", lua_wrap_errors}, {"get_locales_info", lua_wrap_errors}, {NULL, NULL} }; diff --git a/src/settings.h b/src/settings.h index f952b09f..f066e79d 100644 --- a/src/settings.h +++ b/src/settings.h @@ -76,7 +76,7 @@ struct DebugSettings { }; struct UiSettings { - std::string language = "auto"; + StringSetting language {"auto"}; IntegerSetting worldPreviewSize {64, 1, 512}; };