1
0
Fork 0
mirror of https://github.com/luanti-org/luanti.git synced 2025-06-27 16:36:03 +00:00
luanti/builtin/common/settings/dlg_change_keybinding.lua

159 lines
4.3 KiB
Lua
Raw Normal View History

2025-05-24 23:16:14 +02:00
-- 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
2025-05-25 00:33:52 +02:00
local value = dialogdata.value
local selection = dialogdata.selection
2025-05-24 23:16:14 +02:00
local fs = {
"formspec_version[4]",
2025-05-25 00:33:52 +02:00
"size[6,9]",
2025-05-24 23:16:14 +02:00
("label[0.5,0.8;%s]"):format(readable_name),
2025-05-25 00:33:52 +02:00
("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.6,6.7;0.8,0.8;%s;btn_clear;]"):format(
core.formspec_escape(defaulttexturedir .. "clear.png")),
("tooltip[btn_clear;%s]"):format(fgettext("Remove keybinding")),
2025-05-25 00:33:52 +02:00
("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")),
2025-05-24 23:16:14 +02:00
}
2025-05-25 00:57:36 +02:00
local warning = ""
2025-05-25 00:33:52 +02:00
local cells = {}
2025-05-25 00:57:36 +02:00
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 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)))
2025-05-25 00:57:36 +02:00
end
break
end
end
table.insert(cells, core.formspec_escape(prefix .. core.get_keycode_name(key)))
2025-05-25 00:33:52 +02:00
end
2025-05-25 00:57:36 +02:00
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))
2025-05-25 00:33:52 +02:00
2025-05-24 23:16:14 +02:00
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
2025-05-25 00:33:52 +02:00
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
2025-05-24 23:16:14 +02:00
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
2025-05-25 00:33:52 +02:00
dlg.data.value = core.settings:get(setting.name):split("|")
dlg.data.selection = 1
2025-05-24 23:16:14 +02:00
if is_mainmenu then
dlg:set_parent(tabview)
tabview:hide()
end
dlg:show()
return is_mainmenu
end
2025-05-25 00:57:36 +02:00
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