mirror of
https://github.com/luanti-org/luanti.git
synced 2025-09-30 19:22:14 +00:00
Merge afceefc985
into 274d8a7c65
This commit is contained in:
commit
e5fd709dc5
19 changed files with 411 additions and 179 deletions
|
@ -432,34 +432,21 @@ end
|
|||
|
||||
function make.key(setting)
|
||||
local btn_bind = "bind_" .. setting.name
|
||||
local btn_clear = "unbind_" .. setting.name
|
||||
local btn_edit = "edit_" .. setting.name
|
||||
local function add_conflict_warnings(fs, height)
|
||||
local value = core.settings:get(setting.name)
|
||||
local value = core.settings:get(setting.name):split("|")
|
||||
if value == "" then
|
||||
return height
|
||||
end
|
||||
|
||||
local critical_keys = {
|
||||
keymap_drop = true,
|
||||
keymap_dig = true,
|
||||
keymap_place = true,
|
||||
}
|
||||
|
||||
for _, o in ipairs(core.full_settingtypes) do
|
||||
if o.type == "key" and o.name ~= setting.name and
|
||||
core.are_keycodes_equal(core.settings:get(o.name), value) then
|
||||
is_keybinding_critical(setting.name, o.name) and
|
||||
has_keybinding_conflict(core.settings:get(o.name):split("|"), value) then
|
||||
|
||||
local is_current_close_world = setting.name == "keymap_close_world"
|
||||
local is_other_close_world = o.name == "keymap_close_world"
|
||||
local is_current_critical = critical_keys[setting.name]
|
||||
local is_other_critical = critical_keys[o.name]
|
||||
|
||||
if (is_other_critical or is_current_critical) or
|
||||
(not is_current_close_world and not is_other_close_world) then
|
||||
table.insert(fs, ("label[0,%f;%s]"):format(height + 0.3,
|
||||
core.colorize(mt_color_orange, fgettext([[Conflicts with "$1"]], fgettext(o.readable_name)))))
|
||||
height = height + 0.6
|
||||
end
|
||||
table.insert(fs, ("label[0,%f;%s]"):format(height + 0.3,
|
||||
core.colorize(mt_color_orange, fgettext([[Conflicts with "$1"]], fgettext(o.readable_name)))))
|
||||
height = height + 0.6
|
||||
end
|
||||
end
|
||||
return height
|
||||
|
@ -471,30 +458,32 @@ function make.key(setting)
|
|||
|
||||
get_formspec = function(self, avail_w)
|
||||
self.resettable = core.settings:has(setting.name)
|
||||
local btn_bind_width = math.max(2.5, avail_w / 2)
|
||||
local value = core.settings:get(setting.name)
|
||||
local btn_width = math.max(2.5, avail_w / 2)
|
||||
local value = core.settings:get(setting.name):split("|")
|
||||
local fs = {
|
||||
("label[0,0.4;%s]"):format(get_label(setting)),
|
||||
("button_key[%f,0;%f,0.8;%s;%s]"):format(
|
||||
btn_bind_width, btn_bind_width - 0.8,
|
||||
btn_bind, core.formspec_escape(value)),
|
||||
("image_button[%f,0;0.8,0.8;%s;%s;]"):format(avail_w - 0.8,
|
||||
core.formspec_escape(defaulttexturedir .. "clear.png"),
|
||||
btn_clear),
|
||||
("tooltip[%s;%s]"):format(btn_clear, fgettext("Remove keybinding")),
|
||||
("tooltip[%s;%s]"):format(btn_edit, fgettext("Edit keybindings")),
|
||||
}
|
||||
if #value <= 1 then
|
||||
table.insert(fs, ("button_key[%f,0;%f,0.8;%s;%s]"):format(
|
||||
btn_width, btn_width-0.8, btn_bind, value[1] or ""))
|
||||
table.insert(fs, ("image_button[%f,0;0.8,0.8;%s;%s;]"):format(avail_w - 0.8,
|
||||
core.formspec_escape(defaulttexturedir.."overflow_btn.png"), btn_edit))
|
||||
else
|
||||
table.insert(fs, ("button[%f,0;%f,0.8;%s;%s]"):format(
|
||||
btn_width, btn_width, btn_edit, fgettext("Edit")))
|
||||
end
|
||||
local height = 0.8
|
||||
height = add_conflict_warnings(fs, height)
|
||||
return table.concat(fs), height
|
||||
end,
|
||||
|
||||
on_submit = function(self, fields)
|
||||
on_submit = function(self, fields, tabview)
|
||||
if fields[btn_bind] then
|
||||
core.settings:set(setting.name, fields[btn_bind])
|
||||
return true
|
||||
elseif fields[btn_clear] then
|
||||
core.settings:set(setting.name, "")
|
||||
return true
|
||||
elseif fields[btn_edit] then
|
||||
return show_change_keybinding_dlg(setting, tabview)
|
||||
end
|
||||
end,
|
||||
}
|
||||
|
|
173
builtin/common/settings/dlg_change_keybinding.lua
Normal file
173
builtin/common/settings/dlg_change_keybinding.lua
Normal file
|
@ -0,0 +1,173 @@
|
|||
-- Luanti
|
||||
-- SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
local function get_formspec(dialogdata)
|
||||
local name = dialogdata.setting.name
|
||||
local readable_name = name
|
||||
if dialogdata.setting.readable_name then
|
||||
readable_name = ("%s (%s)"):format(fgettext(dialogdata.setting.readable_name), name)
|
||||
end
|
||||
|
||||
local value = dialogdata.value
|
||||
local selection = dialogdata.selection
|
||||
|
||||
local fs = {
|
||||
"formspec_version[4]",
|
||||
"size[6,9]",
|
||||
("label[0.5,0.8;%s]"):format(readable_name),
|
||||
("button[0.5,5.7;5,0.8;btn_add;%s]"):format(fgettext("Add keybinding")),
|
||||
("button_key[0.5,6.7;4.2,0.8;btn_bind;%s]"):format(core.formspec_escape(value[selection] or "")),
|
||||
("image_button[4.7,6.7;0.8,0.8;%s;btn_clear;]"):format(
|
||||
core.formspec_escape(defaulttexturedir .. "clear.png")),
|
||||
("tooltip[btn_clear;%s]"):format(fgettext("Remove keybinding")),
|
||||
("button[3.1,7.7;2.4,0.8;btn_close;%s]"):format(fgettext("Cancel")),
|
||||
("button[0.5,7.7;2.4,0.8;btn_save;%s]"):format(fgettext("Save")),
|
||||
}
|
||||
|
||||
local warning = ""
|
||||
local cells = {}
|
||||
for idx, key in ipairs(value) do
|
||||
local prefix = ""
|
||||
for _, o in ipairs(core.full_settingtypes) do
|
||||
if o.type == "key" and o.name ~= name and
|
||||
is_keybinding_critical(name, o.name) and
|
||||
has_keybinding_conflict(core.settings:get(o.name):split("|"), key) then
|
||||
prefix = mt_color_orange
|
||||
if idx == selection then
|
||||
warning = core.colorize(mt_color_orange, fgettext([[Conflicts with "$1"]], fgettext_ne(o.readable_name)))
|
||||
end
|
||||
break
|
||||
end
|
||||
end
|
||||
table.insert(cells, core.formspec_escape(prefix .. core.get_keycode_name(key)))
|
||||
end
|
||||
table.insert(fs, ("textlist[0.5,1.3;5,3.8;keylist;%s;%d;false]"):format(table.concat(cells, ","), selection))
|
||||
table.insert(fs, ("label[0.5,5.4;%s]"):format(warning))
|
||||
|
||||
return table.concat(fs)
|
||||
end
|
||||
|
||||
local function buttonhandler(self, fields)
|
||||
local name = self.data.setting.name
|
||||
if fields.quit or fields.btn_close then
|
||||
self:delete()
|
||||
return true
|
||||
elseif fields.btn_save then
|
||||
local value = {}
|
||||
for _, v in ipairs(self.data.value) do
|
||||
if v ~= "" then -- filter out "empty" keybindings
|
||||
table.insert(value, v)
|
||||
end
|
||||
end
|
||||
core.settings:set(name, table.concat(value, "|"))
|
||||
self:delete()
|
||||
return true
|
||||
elseif fields.btn_clear then
|
||||
local selection = self.data.selection
|
||||
table.remove(self.data.value, selection)
|
||||
self.data.selection = math.max(1, math.min(selection, #self.data.value))
|
||||
return true
|
||||
elseif fields.btn_add then
|
||||
table.insert(self.data.value, "")
|
||||
self.data.selection = #self.data.value
|
||||
return true
|
||||
elseif fields.btn_bind then
|
||||
self.data.value[self.data.selection] = fields.btn_bind
|
||||
return true
|
||||
elseif fields.keylist then
|
||||
local event = core.explode_textlist_event(fields.keylist)
|
||||
if event.type == "CHG" or event.type == "DCL" then
|
||||
self.data.selection = event.index
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local formspec_handlers = {}
|
||||
if INIT == "pause_menu" then
|
||||
core.register_on_formspec_input(function(formname, fields)
|
||||
if formspec_handlers[formname] then
|
||||
formspec_handlers[formname](fields)
|
||||
return true
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
local is_mainmenu = INIT == "mainmenu"
|
||||
function show_change_keybinding_dlg(setting, tabview)
|
||||
local dlg
|
||||
if is_mainmenu then
|
||||
dlg = dialog_create("dlg_change_keybinding",
|
||||
get_formspec, buttonhandler)
|
||||
else
|
||||
local name = "__builtin:rebind_" .. setting.name
|
||||
dlg = {
|
||||
show = function()
|
||||
if dlg.removed then
|
||||
--core.open_settings("controls_keyboard_and_mouse")
|
||||
tabview:show()
|
||||
else
|
||||
core.show_formspec(name, get_formspec(dlg.data))
|
||||
end
|
||||
end,
|
||||
delete = function()
|
||||
core.show_formspec(name, "")
|
||||
formspec_handlers[name] = nil
|
||||
dlg.removed = true
|
||||
end,
|
||||
data = {},
|
||||
}
|
||||
formspec_handlers[name] = function(fields)
|
||||
if buttonhandler(dlg, fields) then
|
||||
dlg:show()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
dlg.data.setting = setting
|
||||
dlg.data.value = core.settings:get(setting.name):split("|")
|
||||
dlg.data.selection = 1
|
||||
|
||||
if is_mainmenu then
|
||||
dlg:set_parent(tabview)
|
||||
tabview:hide()
|
||||
end
|
||||
dlg:show()
|
||||
|
||||
return is_mainmenu
|
||||
end
|
||||
|
||||
function has_keybinding_conflict(t1, t2) -- not local as it is also used by the make.key component
|
||||
if type(t2) == "string" then
|
||||
if type(t1) == "string" then
|
||||
return core.are_keycodes_equal(t1, t2)
|
||||
else
|
||||
for _, v1 in pairs(t1) do
|
||||
if core.are_keycodes_equal(v1, t2) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
for _, v2 in pairs(t2) do
|
||||
if has_keybinding_conflict(t1, v2) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local critical_keys = {
|
||||
keymap_drop = true,
|
||||
keymap_dig = true,
|
||||
keymap_place = true,
|
||||
}
|
||||
function is_keybinding_critical(n1, n2)
|
||||
local is_current_close_world = n1 == "keymap_close_world"
|
||||
local is_other_close_world = n2 == "keymap_close_world"
|
||||
local is_current_critical = critical_keys[n1]
|
||||
local is_other_critical = critical_keys[n2]
|
||||
return (is_other_critical or is_current_critical) or
|
||||
(not is_current_close_world and not is_other_close_world)
|
||||
end
|
|
@ -814,7 +814,9 @@ else
|
|||
-- case it's a no-op
|
||||
core.show_formspec("__builtin:settings", "")
|
||||
end
|
||||
|
||||
core.show_formspec("__builtin:settings", get_formspec(dialog.data))
|
||||
dialog.show = function() -- Used by the keybinding form
|
||||
core.show_formspec("__builtin:settings", get_formspec(dialog.data))
|
||||
end
|
||||
dialog:show()
|
||||
end
|
||||
end
|
||||
|
|
|
@ -6,6 +6,7 @@ local path = core.get_builtin_path() .. "common" .. DIR_DELIM .. "settings" .. D
|
|||
|
||||
dofile(path .. "settingtypes.lua")
|
||||
dofile(path .. "dlg_change_mapgen_flags.lua")
|
||||
dofile(path .. "dlg_change_keybinding.lua")
|
||||
dofile(path .. "dlg_settings.lua")
|
||||
|
||||
-- Uncomment to generate 'minetest.conf.example' and 'settings_translation_file.cpp'.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue