Settings menu improvements regarding default values (#13489)

The reset button now removes the setting from minetest.conf instead of setting it to its default value.
The reset button is now shown whenever a value is present in minetest.conf
Float settings now get a .0 suffix if they have no decimal places.
This commit is contained in:
Gregor Parzefall 2023-05-18 20:32:26 +02:00 committed by GitHub
parent 5ba70cf5ef
commit f393214fef
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 50 additions and 18 deletions

View File

@ -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

View File

@ -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

View File

@ -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",
})

View File

@ -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,...}`

View File

@ -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");

View File

@ -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<LuaSettings>(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}

View File

@ -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);