diff --git a/builtin/mainmenu/settings/components.lua b/builtin/mainmenu/settings/components.lua index c50bb53e3..3ff38c943 100644 --- a/builtin/mainmenu/settings/components.lua +++ b/builtin/mainmenu/settings/components.lua @@ -30,7 +30,7 @@ local make = {} -- * `info_text`: (Optional) string, informational text shown in an info icon. -- * `setting`: (Optional) the setting. -- * `max_w`: (Optional) maximum width, `avail_w` will never exceed this. --- * `changed`: (Optional) true if the setting has changed from its default value. +-- * `resettable`: (Optional) if this is true, a reset button is shown. -- * `get_formspec = function(self, avail_w)`: -- * `avail_w` is the available width for the component. -- * Returns `fs, used_height`. @@ -69,9 +69,10 @@ end --- Used for string and numeric style fields --- ---- @param converter Function to coerce values +--- @param converter Function to coerce values from strings. --- @param validator Validator function, optional. Returns true when valid. -local function make_field(converter, validator) +--- @param stringifier Function to convert values to strings, optional. +local function make_field(converter, validator, stringifier) return function(setting) return { info_text = setting.comment, @@ -79,7 +80,7 @@ local function make_field(converter, validator) get_formspec = function(self, avail_w) local value = core.settings:get(setting.name) or setting.default - self.changed = converter(value) ~= converter(setting.default) + self.resettable = core.settings:has(setting.name) local fs = ("field[0,0.3;%f,0.8;%s;%s;%s]"):format( avail_w - 1.5, setting.name, get_label(setting), core.formspec_escape(value)) @@ -101,7 +102,7 @@ local function make_field(converter, validator) if setting.max then value = math.min(value, setting.max) end - core.settings:set(setting.name, tostring(value)) + core.settings:set(setting.name, (stringifier or tostring)(value)) return true end end, @@ -110,7 +111,13 @@ local function make_field(converter, validator) end -make.float = make_field(tonumber, is_valid_number) +make.float = make_field(tonumber, is_valid_number, function(x) + local str = tostring(x) + if str:match("^%d+$") then + str = str .. ".0" + end + return str +end) make.int = make_field(function(x) local value = tonumber(x) return value and math.floor(value) @@ -125,7 +132,7 @@ function make.bool(setting) get_formspec = function(self, avail_w) local value = core.settings:get_bool(setting.name, core.is_yes(setting.default)) - self.changed = tostring(value) ~= setting.default + self.resettable = core.settings:has(setting.name) local fs = ("checkbox[0,0.25;%s;%s;%s]"):format( setting.name, get_label(setting), tostring(value)) @@ -152,7 +159,7 @@ function make.enum(setting) get_formspec = function(self, avail_w) local value = core.settings:get(setting.name) or setting.default - self.changed = value ~= setting.default + self.resettable = core.settings:has(setting.name) local items = {} for i, option in ipairs(setting.values) do @@ -189,7 +196,7 @@ function make.path(setting) get_formspec = function(self, avail_w) local value = core.settings:get(setting.name) or setting.default - self.changed = value ~= setting.default + self.resettable = core.settings:has(setting.name) local fs = ("field[0,0.3;%f,0.8;%s;%s;%s]"):format( avail_w - 3, setting.name, get_label(setting), value) @@ -233,7 +240,7 @@ function make.v3f(setting) get_formspec = function(self, avail_w) local value = vector.from_string(core.settings:get(setting.name) or setting.default) - self.changed = value ~= vector.from_string(setting.default) + self.resettable = core.settings:has(setting.name) -- Allocate space for "Set" button avail_w = avail_w - 1 @@ -287,7 +294,7 @@ function make.flags(setting) } local value = core.settings:get(setting.name) or setting.default - self.changed = value:gsub(" ", "") ~= setting.default:gsub(" ", "") + self.resettable = core.settings:has(setting.name) checkboxes = {} for _, name in ipairs(value:split(",")) do diff --git a/builtin/mainmenu/settings/dlg_settings.lua b/builtin/mainmenu/settings/dlg_settings.lua index fdf324452..751db87e6 100644 --- a/builtin/mainmenu/settings/dlg_settings.lua +++ b/builtin/mainmenu/settings/dlg_settings.lua @@ -414,7 +414,7 @@ local function get_formspec(dialogdata) fs[#fs + 1] = "style_type[image_button;border=false;padding=]" - local show_reset = comp.changed and comp.setting and comp.setting.default + local show_reset = comp.resettable and comp.setting local show_info = comp.info_text and comp.info_text ~= "" if show_reset or show_info then -- ensure there's enough space for reset/info @@ -423,10 +423,13 @@ local function get_formspec(dialogdata) local info_reset_y = used_h / 2 - 0.25 if show_reset then + local default = comp.setting.default + local reset_tooltip = default and + fgettext("Reset setting to default ($1)", tostring(default)) or + fgettext("Reset setting to default") fs[#fs + 1] = ("image_button[%f,%f;0.5,0.5;%s;%s;]"):format( right_pane_width - 1.4, info_reset_y, reset_icon_path, "reset_" .. i) - fs[#fs + 1] = ("tooltip[%s;%s]"):format( - "reset_" .. i, fgettext("Reset setting to default ($1)", tostring(comp.setting.default))) + fs[#fs + 1] = ("tooltip[%s;%s]"):format("reset_" .. i, reset_tooltip) end if show_info then @@ -506,7 +509,7 @@ local function buttonhandler(this, fields) return true end if comp.setting and fields["reset_" .. i] then - core.settings:set(comp.setting.name, comp.setting.default) + core.settings:remove(comp.setting.name) return true end end diff --git a/builtin/mainmenu/settings/settingtypes.lua b/builtin/mainmenu/settings/settingtypes.lua index d350761be..06389b085 100644 --- a/builtin/mainmenu/settings/settingtypes.lua +++ b/builtin/mainmenu/settings/settingtypes.lua @@ -411,7 +411,7 @@ function settingtypes.parse_config_file(read_all, parse_mods) table.insert(settings, { name = mod.path, - readable_name = mod.title, + readable_name = mod.title or mod.name, level = 1, type = "category", }) @@ -442,7 +442,7 @@ function settingtypes.parse_config_file(read_all, parse_mods) table.insert(settings, { name = mod.path, - readable_name = mod.title, + readable_name = mod.title or mod.name, level = 1, type = "category", }) diff --git a/doc/lua_api.md b/doc/lua_api.md index ba19c1e9c..c596da2ab 100644 --- a/doc/lua_api.md +++ b/doc/lua_api.md @@ -7898,6 +7898,12 @@ It can be created via `Settings(filename)`. * Also, see documentation for set() above. * `remove(key)`: returns a boolean (`true` for success) * `get_names()`: returns `{key1,...}` +* `has(key)`: + * Returns a boolean indicating whether `key` exists. + * Note that for the main settings object (`minetest.settings`), `get(key)` + might return a value even if `has(key)` returns `false`. That's because + `get` can fall back to the so-called parent of the `Settings` object, i.e. + the default values. * `write()`: returns a boolean (`true` for success) * Writes changes to file. * `to_table()`: returns `{[key1]=value1,...}` diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp index 6df5ed090..c19ceba72 100644 --- a/src/defaultsettings.cpp +++ b/src/defaultsettings.cpp @@ -207,7 +207,7 @@ void set_default_settings() settings->setDefault("shader_path", ""); settings->setDefault("video_driver", ""); settings->setDefault("cinematic", "false"); - settings->setDefault("camera_smoothing", "0"); + settings->setDefault("camera_smoothing", "0.0"); settings->setDefault("cinematic_camera_smoothing", "0.7"); settings->setDefault("enable_clouds", "true"); settings->setDefault("view_bobbing_amount", "1.0"); diff --git a/src/script/lua_api/l_settings.cpp b/src/script/lua_api/l_settings.cpp index e4d523070..cd79124f6 100644 --- a/src/script/lua_api/l_settings.cpp +++ b/src/script/lua_api/l_settings.cpp @@ -275,6 +275,18 @@ int LuaSettings::l_get_names(lua_State* L) return 1; } +// has(self, key) -> boolean +int LuaSettings::l_has(lua_State* L) +{ + NO_MAP_LOCK_REQUIRED; + LuaSettings* o = checkObject(L, 1); + + std::string key = std::string(luaL_checkstring(L, 2)); + lua_pushboolean(L, o->m_settings->existsLocal(key)); + + return 1; +} + // write(self) -> success int LuaSettings::l_write(lua_State* L) { @@ -364,6 +376,7 @@ const luaL_Reg LuaSettings::methods[] = { luamethod(LuaSettings, set_np_group), luamethod(LuaSettings, remove), luamethod(LuaSettings, get_names), + luamethod(LuaSettings, has), luamethod(LuaSettings, write), luamethod(LuaSettings, to_table), {0,0} diff --git a/src/script/lua_api/l_settings.h b/src/script/lua_api/l_settings.h index 7eead16e6..96f56bb3b 100644 --- a/src/script/lua_api/l_settings.h +++ b/src/script/lua_api/l_settings.h @@ -59,6 +59,9 @@ private: // get_names(self) -> {key1, ...} static int l_get_names(lua_State *L); + // has(self, key) -> boolean + static int l_has(lua_State *L); + // write(self) -> success static int l_write(lua_State *L);