281 lines
No EOL
11 KiB
Lua
281 lines
No EOL
11 KiB
Lua
|
|
dofile(core.get_builtin_path().."common/settings/settingtypes.lua")
|
|
|
|
-- Some categories, like Accessibility and Theme, do not appear
|
|
-- in the builtin settingtypes.txt, so they are added to the state table here.
|
|
local function inject_settings(state)
|
|
-- Theme
|
|
table.insert(state.categories, 1, "Theme")
|
|
state.settings.Theme = {
|
|
{
|
|
comment = "The background color of containers.",
|
|
context = "client",
|
|
default = "#fff",
|
|
name = "theme.container_bg_color",
|
|
readable_name = "Container background color",
|
|
requires = {},
|
|
type = "string",
|
|
value = imfs.state("#fff")
|
|
}
|
|
}
|
|
|
|
-- Accessibility
|
|
table.insert(state.categories, 2, "Accessibility")
|
|
state.settings.Accessibility = {
|
|
{
|
|
comment = "Smooths rotation of camera, also called look or mouse smoothing. 0 to disable.",
|
|
context = "client",
|
|
default = "0.0",
|
|
max = 0.99,
|
|
min = 0,
|
|
name = "camera_smoothing",
|
|
readable_name = "Camera smoothing",
|
|
requires = {},
|
|
type = "float",
|
|
value = imfs.state("0.0")
|
|
}
|
|
}
|
|
end
|
|
|
|
local function search_settings(state, search)
|
|
if state.search == "" then
|
|
return state.settings, state.categories
|
|
end
|
|
|
|
local words = search:lower():trim():split(" ")
|
|
|
|
local out = {}
|
|
for category, settings in pairs(state.settings) do
|
|
for i = 1, #settings do
|
|
for j = 1, #words do
|
|
local passed = true
|
|
if not (settings[i].readable_name:lower():find(words[j], 1, true)
|
|
or settings[i].name:find(words[j], 1, true)) then
|
|
passed = false
|
|
end
|
|
|
|
if passed then
|
|
if not out[category] then
|
|
out[category] = {settings[i]}
|
|
else
|
|
table.insert(out[category], settings[i])
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
local categories = {}
|
|
for i = 1, #state.categories do
|
|
local category = state.categories[i]
|
|
if category.name then
|
|
for j = 1, #state.categories do
|
|
if out[category[j]] then
|
|
if not categories[category.name] then
|
|
table.insert(categories, {name = category.name})
|
|
end
|
|
table.insert(categories[#categories], category[j])
|
|
break
|
|
end
|
|
end
|
|
else
|
|
if out[category] then
|
|
table.insert(categories, category)
|
|
break
|
|
end
|
|
end
|
|
end
|
|
|
|
return out, categories
|
|
end
|
|
|
|
return function(state)
|
|
imfs.begin(size.x, size.y)
|
|
:padding(0, 0)
|
|
:bgcolor(theme.styles.bg_color, true)
|
|
|
|
if not state.settings then
|
|
state.settings = {}
|
|
state.categories = {}
|
|
local category
|
|
local settings = settingtypes.parse_config_file(false, false)
|
|
for _, x in ipairs(settings) do
|
|
if x.type == "category" then
|
|
if x.level == 0 then
|
|
state.categories[#state.categories + 1] = {name = x.name}
|
|
elseif x.level == 1 then
|
|
local group = state.categories[#state.categories]
|
|
group[#group + 1] = x.name
|
|
state.settings[x.name] = {}
|
|
category = x.name
|
|
end
|
|
else
|
|
local s = state.settings[category]
|
|
x.value = imfs.state()
|
|
if x.type == "string" or x.type == "float" or x.type == "int" or x.type == "enum" then
|
|
x.value._val = minetest.settings:get(x.name) or x.default
|
|
elseif x.type == "bool" then
|
|
x.value._val = minetest.settings:get_bool(x.name, x.default)
|
|
end
|
|
s[#s +1] = x
|
|
end
|
|
end
|
|
|
|
inject_settings(state)
|
|
|
|
state.settings_shown._val = state.settings
|
|
state.categories_shown._val = state.categories
|
|
end
|
|
|
|
imfs.box(0, 0, "100%", 1, theme.styles.container.bg_color)
|
|
|
|
imfs.row(0.2, 0.125, "100% - 0.4", 0.75)
|
|
:gap(0.1)
|
|
theme.field(0, 0, "1x", "100%", state.search)
|
|
:onchange(function(value)
|
|
state.search = value
|
|
end)
|
|
:onenter(function()
|
|
local settings, categories = search_settings(state, state.search)
|
|
if categories[1] then
|
|
local first = categories[1].name and categories[1][1] or categories[1]
|
|
state.category(first)
|
|
end
|
|
state.categories_shown(categories)
|
|
state.settings_shown(settings)
|
|
end)
|
|
imfs.button(0, 0, 0.75, 0.75)
|
|
:image(theme.icon("search"))
|
|
:style({
|
|
bgimg = theme.get_background_image("button"),
|
|
bgimg_middle = theme.styles.button.border_width,
|
|
})
|
|
:tooltip("Search settings")
|
|
:onclick(function()
|
|
local settings, categories = search_settings(state, state.search)
|
|
if categories[1] then
|
|
local first = categories[1].name and categories[1][1] or categories[1]
|
|
state.category(first)
|
|
end
|
|
state.categories_shown(categories)
|
|
state.settings_shown(settings)
|
|
end)
|
|
|
|
imfs.button(0, 0, 0.75, 0.75)
|
|
:image(theme.icon("cancel"))
|
|
:style({
|
|
bgimg = theme.get_background_image("button"),
|
|
bgimg_middle = theme.styles.button.border_width,
|
|
})
|
|
:tooltip("Clear search")
|
|
:onclick(function()
|
|
state.search = ""
|
|
state.settings_shown(state.settings)
|
|
state.categories_shown(state.categories)
|
|
end)
|
|
imfs.button(0, 0, 2, "100%", "Back")
|
|
:onclick(function()
|
|
show_meta_menu()
|
|
end)
|
|
imfs.row_end()
|
|
|
|
imfs.box(0, 1, "20%", "100% - 1", theme.styles.container.bg_color)
|
|
imfs.box(0, 0.95, "100%", 0.1, theme.styles.container.border_color)
|
|
|
|
imfs.scroll_container(0.2, 1.05, "20% - 0.45", "100% - 1.05")
|
|
local categories = state.categories_shown()
|
|
if categories then
|
|
local y = 0.1
|
|
for i = 1, #categories do
|
|
local group = categories[i]
|
|
if not group then break end
|
|
-- Top-level categories.
|
|
if type(group) == "string" then
|
|
imfs.button(0, y, "100%", 0.5, group)
|
|
:onclick(function()
|
|
if state.category() ~= group then
|
|
state.category(group)
|
|
end
|
|
end)
|
|
y = y + 0.55
|
|
-- Grouped categories.
|
|
else
|
|
imfs.arealabel(0, y + 0.125, "100%", 0.375, group.name)
|
|
y = y + 0.425
|
|
local h = 0
|
|
for j = 1, #group do
|
|
local category = group[j]
|
|
imfs.box(0.12, y + 0.245, 0.25, 0.01, theme.styles.text_color)
|
|
imfs.button(0.25, y, "100% - 0.25", 0.5, category)
|
|
:onclick(function()
|
|
if state.category() ~= category then
|
|
state.category(category)
|
|
end
|
|
end)
|
|
h = h + 0.55
|
|
y = y + 0.55
|
|
end
|
|
imfs.box(0.12, y - h, 0.01, h - 0.3, theme.styles.text_color)
|
|
end
|
|
end
|
|
end
|
|
imfs.scroll_container_end()
|
|
|
|
imfs.box("20% - 0.05", 1, 0.1, "100% - 1", theme.styles.container.border_color)
|
|
|
|
imfs.scroll_container("20% + 0.25", 1.05, "80% - 0.45", "100% - 1.05")
|
|
imfs.column(0, 0, "100%", 1000)
|
|
:gap(0.1)
|
|
local settings = state.settings_shown()[state.category()]
|
|
if settings then
|
|
for i = 1, #settings do
|
|
local setting = settings[i]
|
|
if not setting then break end
|
|
if setting.type == "bool" then
|
|
local active = minetest.settings:get_bool(setting.name, setting.default)
|
|
theme.checkbox(0, 0, setting.readable_name, setting.value, setting.comment)
|
|
elseif setting.type == "float" or setting.type == "int" then
|
|
imfs.arealabel(0, 0, "100%", 0.325, setting.readable_name)
|
|
imfs.row(0, 0, "100%", 0.75)
|
|
:gap(0.1)
|
|
theme.number_field(0, 0, "1x", 0.75, setting.value)
|
|
:tooltip(setting.comment)
|
|
imfs.button(0, 0, 2, 0.75, "Set")
|
|
imfs.row_end()
|
|
elseif setting.type == "string" then
|
|
imfs.arealabel(0, 0, "100%", 0.325, setting.readable_name)
|
|
imfs.row(0, 0, "100%", 0.75)
|
|
:gap(0.1)
|
|
theme.field(0, 0, "1x", 0.75, setting.value)
|
|
:tooltip(setting.comment)
|
|
if setting.value._val ~= setting.default then
|
|
imfs.button(0, 0, 0.75, 0.75)
|
|
:image(theme.icon("refresh"))
|
|
:style({
|
|
bgimg = theme.get_background_image("button"),
|
|
bgimg_middle = theme.styles.button.border_width,
|
|
})
|
|
:tooltip("Reset to default")
|
|
end
|
|
imfs.button(0, 0, 2, 0.75, "Set")
|
|
imfs.row_end()
|
|
elseif setting.type == "enum" then
|
|
imfs.scope(setting.name)
|
|
imfs.arealabel(0, 0, "100%", 0.325, setting.readable_name)
|
|
imfs.row(0, 0, "100%", "fit")
|
|
:gap(0.1)
|
|
theme.dropdown(0, 0, "1x", 0.75, setting.values, setting.value)
|
|
:tooltip(setting.comment)
|
|
imfs.button(0, 0, 2, 0.75, "Set")
|
|
imfs.row_end()
|
|
imfs.scope_end()
|
|
else
|
|
print(dump(setting))
|
|
end
|
|
end
|
|
end
|
|
imfs.column_end()
|
|
imfs.scroll_container_end()
|
|
|
|
return imfs.end_()
|
|
end |