Settings menu improvements regarding default values ()

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
7 changed files with 50 additions and 18 deletions

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

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

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

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

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

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

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