1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-03-30 16:20:21 +00:00

Separate setting keys and names, support localization

This commit is contained in:
uramer 2022-04-09 19:58:32 +02:00
parent 1f5e3b78d4
commit a0c0c39a8c
4 changed files with 97 additions and 66 deletions

View File

@ -52,28 +52,28 @@ local function isGlobalScope(scope)
return scope == SCOPE.Global or scope == SCOPE.SaveGlobal return scope == SCOPE.Global or scope == SCOPE.SaveGlobal
end end
local function getSetting(groupName, settingName) local function getSetting(groupKey, settingKey)
local group = groups:get(groupName) local group = groups:get(groupKey)
if not group then if not group then
error('Unknown group') error('Unknown group')
end end
local setting = group[settingName] local setting = group[settingKey]
if not setting then if not setting then
error('Unknown setting') error('Unknown setting')
end end
return setting return setting
end end
local function getSettingValue(groupName, settingName) local function getSettingValue(groupKey, settingKey)
local setting = getSetting(groupName, settingName) local setting = getSetting(groupKey, settingKey)
local scopeSection = scopes[setting.scope] local scopeSection = scopes[setting.scope]
if not scopeSection then if not scopeSection then
error(('Setting %s is not available in this context'):format(setting.name)) error(('Setting %s is not available in this context'):format(setting.key))
end end
if not scopeSection:get(groupName) then if not scopeSection:get(groupKey) then
scopeSection:set(groupName, {}) scopeSection:set(groupKey, {})
end end
return scopeSection:get(groupName)[setting.name] or setting.default return scopeSection:get(groupKey)[setting.key] or setting.default
end end
local function notifySettingChange(scope, event) local function notifySettingChange(scope, event)
@ -89,11 +89,11 @@ local function notifySettingChange(scope, event)
end end
end end
local function setSettingValue(groupName, settingName, value) local function setSettingValue(groupKey, settingKey, value)
local setting = getSetting(groupName, settingName) local setting = getSetting(groupKey, settingKey)
local event = { local event = {
groupName = groupName, groupName = groupKey,
settingName = setting.name, settingName = setting.key,
value = value, value = value,
} }
if isPlayerScript and isGlobalScope(setting.scope) then if isPlayerScript and isGlobalScope(setting.scope) then
@ -102,43 +102,43 @@ local function setSettingValue(groupName, settingName, value)
end end
local scopeSection = scopes[setting.scope] local scopeSection = scopes[setting.scope]
if not scopeSection:get(groupName) then if not scopeSection:get(groupKey) then
scopeSection:set(groupName, {}) scopeSection:set(groupKey, {})
end end
local copy = scopeSection:getCopy(groupName) local copy = scopeSection:getCopy(groupKey)
copy[setting.name] = value copy[setting.key] = value
scopeSection:set(groupName, copy) scopeSection:set(groupKey, copy)
notifySettingChange(setting.scope, event) notifySettingChange(setting.scope, event)
end end
local groupMeta = { local groupMeta = {
__index = { __index = {
get = function(self, settingName) get = function(self, settingKey)
return getSettingValue(self.name, settingName) return getSettingValue(self.key, settingKey)
end, end,
set = function(self, settingName, value) set = function(self, settingKey, value)
setSettingValue(self.name, settingName, value) setSettingValue(self.key, settingKey, value)
end, end,
onChange = function(self, callback) onChange = function(self, callback)
table.insert(self.__callbacks, callback) table.insert(self.__callbacks, callback)
end, end,
__changed = function(self, settingName, value) __changed = function(self, settingKey, value)
for _, callback in ipairs(self.__callbacks) do for _, callback in ipairs(self.__callbacks) do
callback(settingName, value) callback(settingKey, value)
end end
end, end,
}, },
} }
local cachedGroups = {} local cachedGroups = {}
local function getGroup(groupName) local function getGroup(groupKey)
if not cachedGroups[groupName] then if not cachedGroups[groupKey] then
cachedGroups[groupName] = setmetatable({ cachedGroups[groupKey] = setmetatable({
name = groupName, key = groupKey,
__callbacks = {}, __callbacks = {},
}, groupMeta) }, groupMeta)
end end
return cachedGroups[groupName] return cachedGroups[groupKey]
end end
return { return {

View File

@ -8,6 +8,7 @@ return {
SCOPE = common.SCOPE, SCOPE = common.SCOPE,
getGroup = common.getGroup, getGroup = common.getGroup,
registerRenderer = render.registerRenderer, registerRenderer = render.registerRenderer,
localizeGroup = render.localizeGroup,
}, },
engineHandlers = { engineHandlers = {
onLoad = function(saved) onLoad = function(saved)

View File

@ -17,14 +17,8 @@ local function validScope(scope)
end end
local function validateSettingOptions(options) local function validateSettingOptions(options)
if type(options.name) ~= 'string' then if type(options.key) ~= 'string' then
error('Setting must have a name') error('Setting must have a key')
end
if options.default == nil then
error('Setting must have a default value')
end
if type(options.description) ~= 'string' then
error('Setting must have a description')
end end
if not validScope(options.scope) then if not validScope(options.scope) then
error(('Invalid setting scope %s'):format(options.scope)) error(('Invalid setting scope %s'):format(options.scope))
@ -36,14 +30,13 @@ end
local function addSetting(group, options) local function addSetting(group, options)
validateSettingOptions(options) validateSettingOptions(options)
if group[options.name] then if group[options.key] then
error(('Duplicate setting name %s'):format(options.name)) error(('Duplicate setting key %s'):format(options.key))
end end
group[options.name] = { group[options.key] = {
name = options.name, key = options.key,
scope = options.scope or SCOPE.Global, scope = options.scope or SCOPE.Global,
default = options.default, default = options.default,
description = options.description,
renderer = options.renderer, renderer = options.renderer,
} }
end end

View File

@ -9,51 +9,88 @@ local function registerRenderer(name, renderFunction)
end end
local groupOptions = {} local groupOptions = {}
local localization = {}
local function renderSetting(groupName, setting, value, index) local function renderSetting(groupKey, setting, value, index)
local renderFunction = renderers[setting.renderer] local renderFunction = renderers[setting.renderer]
if not renderFunction then if not renderFunction then
error(('Setting %s of %s has unknown renderer %s'):format(setting.name, groupName, setting.renderer)) error(('Setting %s of %s has unknown renderer %s'):format(setting.key, groupKey, setting.renderer))
end end
local layout = renderFunction(setting, value or setting.default, function(value) local loc = localization[groupKey] and localization[groupKey].settings[setting.key] or {
local group = common.getGroup(groupName) name = setting.key,
group:set(setting.name, value) description = '',
local element = groupOptions[groupName].element }
local settingLayout = renderSetting(groupName, setting, value, index) local layout = renderFunction(loc, value or setting.default, function(value)
settingLayout.name = setting.name local group = common.getGroup(groupKey)
element.layout.content[setting.name] = settingLayout group:set(setting.key, value)
local element = groupOptions[groupKey].element
local settingLayout = renderSetting(groupKey, setting, value, index)
settingLayout.name = setting.key
element.layout.content.settings.content[setting.key] = settingLayout
element:update() element:update()
end) end)
layout.name = setting.name layout.name = setting.key
return layout return layout
end end
local function onGroupRegistered(groupName) local function updateLocalization(groupKey)
local group = common.groups:get(groupName) local loc = localization[groupKey]
local layout = { local options = groupOptions[groupKey]
if not options or not loc then return end
local searchHints = { loc.name, loc.description }
options.name = loc.name
options.searchHints = table.concat(searchHints, ' ')
local layout = options.element.layout
layout.content.header.props.text = loc.description
end
local function onGroupRegistered(groupKey)
local group = common.groups:get(groupKey)
local settingsLayout = {
name = 'settings',
type = ui.TYPE.Flex, type = ui.TYPE.Flex,
content = ui.content{}, content = ui.content{},
} }
local searchHints = { groupName }
local count = 0 local count = 0
for _, setting in pairs(group) do for _, setting in pairs(group) do
count = count + 1 count = count + 1
local settingLayout = renderSetting(groupName, setting, setting.default, count) local settingLayout = renderSetting(groupKey, setting, setting.default, count)
settingLayout.name = setting.name settingLayout.key = setting.key
layout.content:add(settingLayout) settingsLayout.content:add(settingLayout)
table.insert(searchHints, setting.name)
end end
local options = { local layout = {
name = groupName, type = ui.TYPE.Flex,
element = ui.create(layout), content = ui.content {
searchHints = table.concat(searchHints, ' '), {
name = 'header',
type = ui.TYPE.Text,
props = {
text = '',
textSize = 30,
textColor = util.color.rgb(1, 1, 1),
},
},
settingsLayout,
},
} }
groupOptions[groupName] = options local options = {
print(('registering group %s'):format(groupName)) name = groupKey,
element = ui.create(layout),
searchHints = '',
}
groupOptions[groupKey] = options
updateLocalization(groupKey)
print(('registering group %s'):format(groupKey))
ui.registerSettingsPage(options) ui.registerSettingsPage(options)
end end
local function localizeGroup(groupKey, loc)
localization[groupKey] = loc
updateLocalization(groupKey)
end
return { return {
onGroupRegistered = onGroupRegistered, onGroupRegistered = onGroupRegistered,
registerRenderer = registerRenderer, registerRenderer = registerRenderer,
localizeGroup = localizeGroup,
} }