mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-11-04 07:56:40 +00:00 
			
		
		
		
	l10n name is taken not from the ActionInfo/TriggerInfo's 'key' param, but from the 'l10n' param when making the inputBinding setting renderer
		
			
				
	
	
		
			191 lines
		
	
	
	
		
			5.5 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
			
		
		
	
	
			191 lines
		
	
	
	
		
			5.5 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
local core = require('openmw.core')
 | 
						|
local input = require('openmw.input')
 | 
						|
local storage = require('openmw.storage')
 | 
						|
local ui = require('openmw.ui')
 | 
						|
local util = require('openmw.util')
 | 
						|
local async = require('openmw.async')
 | 
						|
local I = require('openmw.interfaces')
 | 
						|
 | 
						|
local settingsGroup = 'SettingsOMWControls'
 | 
						|
 | 
						|
local function boolSetting(key, default)
 | 
						|
    return {
 | 
						|
        key = key,
 | 
						|
        renderer = 'checkbox',
 | 
						|
        name = key,
 | 
						|
        description = key .. 'Description',
 | 
						|
        default = default,
 | 
						|
    }
 | 
						|
end
 | 
						|
 | 
						|
I.Settings.registerPage({
 | 
						|
    key = 'OMWControls',
 | 
						|
    l10n = 'OMWControls',
 | 
						|
    name = 'ControlsPage',
 | 
						|
    description = 'ControlsPageDescription',
 | 
						|
})
 | 
						|
 | 
						|
I.Settings.registerGroup({
 | 
						|
    key = settingsGroup,
 | 
						|
    page = 'OMWControls',
 | 
						|
    l10n = 'OMWControls',
 | 
						|
    name = 'MovementSettings',
 | 
						|
    permanentStorage = true,
 | 
						|
    settings = {
 | 
						|
        boolSetting('alwaysRun', false),
 | 
						|
        boolSetting('toggleSneak', false), -- TODO: consider removing this setting when we have the advanced binding UI
 | 
						|
        boolSetting('smoothControllerMovement', true),
 | 
						|
    },
 | 
						|
})
 | 
						|
 | 
						|
local interfaceL10n = core.l10n('interface')
 | 
						|
 | 
						|
local bindingSection = storage.playerSection('OMWInputBindings')
 | 
						|
 | 
						|
local recording = nil
 | 
						|
 | 
						|
local mouseButtonNames = {
 | 
						|
    [1] = 'Left',
 | 
						|
    [2] = 'Middle',
 | 
						|
    [3] = 'Right',
 | 
						|
    [4] = '4',
 | 
						|
    [5] = '5',
 | 
						|
}
 | 
						|
 | 
						|
-- TODO: support different controllers, use icons to render controller buttons
 | 
						|
local controllerButtonNames = {
 | 
						|
    [-1] = 'Invalid',
 | 
						|
    [input.CONTROLLER_BUTTON.A] = "A",
 | 
						|
    [input.CONTROLLER_BUTTON.B] = "B",
 | 
						|
    [input.CONTROLLER_BUTTON.X] = "X",
 | 
						|
    [input.CONTROLLER_BUTTON.Y] = "Y",
 | 
						|
    [input.CONTROLLER_BUTTON.Back] = "Back",
 | 
						|
    [input.CONTROLLER_BUTTON.Guide] = "Guide",
 | 
						|
    [input.CONTROLLER_BUTTON.Start] = "Start",
 | 
						|
    [input.CONTROLLER_BUTTON.LeftStick] = "Left Stick",
 | 
						|
    [input.CONTROLLER_BUTTON.RightStick] = "Right Stick",
 | 
						|
    [input.CONTROLLER_BUTTON.LeftShoulder] = "LB",
 | 
						|
    [input.CONTROLLER_BUTTON.RightShoulder] = "RB",
 | 
						|
    [input.CONTROLLER_BUTTON.DPadUp] = "D-pad Up",
 | 
						|
    [input.CONTROLLER_BUTTON.DPadDown] = "D-pad Down",
 | 
						|
    [input.CONTROLLER_BUTTON.DPadLeft] = "D-pad Left",
 | 
						|
    [input.CONTROLLER_BUTTON.DPadRight] = "D-pad Right",
 | 
						|
}
 | 
						|
 | 
						|
local function bindingLabel(recording, binding)
 | 
						|
    if recording then
 | 
						|
        return interfaceL10n('N/A')
 | 
						|
    elseif not binding or not binding.button then
 | 
						|
        return interfaceL10n('None')
 | 
						|
    elseif binding.device == 'keyboard' then
 | 
						|
        return input.getKeyName(binding.button)
 | 
						|
    elseif binding.device == 'mouse' then
 | 
						|
        return string.format('Mouse %s', mouseButtonNames[binding.button] or 'Unknown')
 | 
						|
    elseif binding.device == 'controller' then
 | 
						|
        return string.format('Controller %s', controllerButtonNames[binding.button] or 'Unknown')
 | 
						|
    else
 | 
						|
        return 'Unknown'
 | 
						|
    end
 | 
						|
end
 | 
						|
 | 
						|
local inputTypes = {
 | 
						|
    action = input.actions,
 | 
						|
    trigger = input.triggers,
 | 
						|
}
 | 
						|
 | 
						|
I.Settings.registerRenderer('inputBinding', function(id, set, arg)
 | 
						|
    if type(id) ~= 'string' then error('inputBinding: must have a string default value') end
 | 
						|
    if not arg then error('inputBinding: argument with "key" and "type" is required') end
 | 
						|
    if not arg.type then error('inputBinding: type argument is required') end
 | 
						|
    if not inputTypes[arg.type] then error('inputBinding: type must be "action" or "trigger"') end
 | 
						|
    if not arg.key then error('inputBinding: key argument is required') end
 | 
						|
    local info = inputTypes[arg.type][arg.key]
 | 
						|
    if not info then print(string.format('inputBinding: %s %s not found', arg.type, arg.key)) return end
 | 
						|
 | 
						|
    local l10n = core.l10n(info.l10n)
 | 
						|
 | 
						|
    local name = {
 | 
						|
        template = I.MWUI.templates.textNormal,
 | 
						|
        props = {
 | 
						|
            text = l10n(info.name),
 | 
						|
        },
 | 
						|
    }
 | 
						|
 | 
						|
    local description = {
 | 
						|
        template = I.MWUI.templates.textNormal,
 | 
						|
        props = {
 | 
						|
            text = l10n(info.description),
 | 
						|
        },
 | 
						|
    }
 | 
						|
 | 
						|
    local binding = bindingSection:get(id)
 | 
						|
    local label = bindingLabel(recording and recording.id == id, binding)
 | 
						|
 | 
						|
    local recorder = {
 | 
						|
        template = I.MWUI.templates.textNormal,
 | 
						|
        props = {
 | 
						|
            text = label,
 | 
						|
        },
 | 
						|
        events = {
 | 
						|
            mouseClick = async:callback(function()
 | 
						|
                if recording ~= nil then return end
 | 
						|
                if binding ~= nil then bindingSection:set(id, nil) end
 | 
						|
                recording = {
 | 
						|
                    id = id,
 | 
						|
                    arg = arg,
 | 
						|
                    refresh = function() set(id) end,
 | 
						|
                }
 | 
						|
                recording.refresh()
 | 
						|
            end),
 | 
						|
        },
 | 
						|
    }
 | 
						|
 | 
						|
    local row = {
 | 
						|
        type = ui.TYPE.Flex,
 | 
						|
        props = {
 | 
						|
            horizontal = true,
 | 
						|
        },
 | 
						|
        content = ui.content {
 | 
						|
            name,
 | 
						|
            { props = { size = util.vector2(10, 0) } },
 | 
						|
            recorder,
 | 
						|
        },
 | 
						|
    }
 | 
						|
    local column = {
 | 
						|
        type = ui.TYPE.Flex,
 | 
						|
        content = ui.content {
 | 
						|
            row,
 | 
						|
            description,
 | 
						|
        },
 | 
						|
    }
 | 
						|
 | 
						|
    return column
 | 
						|
end)
 | 
						|
 | 
						|
local function bindButton(device, button)
 | 
						|
    if recording == nil then return end
 | 
						|
    local binding = {
 | 
						|
        device = device,
 | 
						|
        button = button,
 | 
						|
        type = recording.arg.type,
 | 
						|
        key = recording.arg.key,
 | 
						|
    }
 | 
						|
    bindingSection:set(recording.id, binding)
 | 
						|
    local refresh = recording.refresh
 | 
						|
    recording = nil
 | 
						|
    refresh()
 | 
						|
end
 | 
						|
 | 
						|
return {
 | 
						|
    engineHandlers = {
 | 
						|
        onKeyPress = function(key)
 | 
						|
            bindButton(key.code ~= input.KEY.Escape and 'keyboard' or nil, key.code)
 | 
						|
        end,
 | 
						|
        onMouseButtonPress = function(button)
 | 
						|
            bindButton('mouse', button)
 | 
						|
        end,
 | 
						|
        onControllerButtonPress = function(id)
 | 
						|
            bindButton('controller', id)
 | 
						|
        end,
 | 
						|
    }
 | 
						|
}
 |