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};
};