mirror of
https://github.com/OpenMW/openmw.git
synced 2025-03-27 04:40:26 +00:00
Renderers
This commit is contained in:
parent
7edd28c1a4
commit
e591f856fb
7 changed files with 326 additions and 4 deletions
|
@ -8,6 +8,7 @@ Lua API reference
|
||||||
engine_handlers
|
engine_handlers
|
||||||
user_interface
|
user_interface
|
||||||
aipackages
|
aipackages
|
||||||
|
setting_renderers
|
||||||
events
|
events
|
||||||
openmw_util
|
openmw_util
|
||||||
openmw_storage
|
openmw_storage
|
||||||
|
|
126
docs/source/reference/lua-scripting/setting_renderers.rst
Normal file
126
docs/source/reference/lua-scripting/setting_renderers.rst
Normal file
|
@ -0,0 +1,126 @@
|
||||||
|
Built-in Setting Renderers
|
||||||
|
==========================
|
||||||
|
|
||||||
|
textLine
|
||||||
|
--------
|
||||||
|
|
||||||
|
Single line text input
|
||||||
|
|
||||||
|
**Argument**
|
||||||
|
|
||||||
|
Table with the following optional fields:
|
||||||
|
|
||||||
|
.. list-table::
|
||||||
|
:header-rows: 1
|
||||||
|
:widths: 20 20 60
|
||||||
|
|
||||||
|
* - name
|
||||||
|
- type (default)
|
||||||
|
- description
|
||||||
|
* - disabled
|
||||||
|
- bool (false)
|
||||||
|
- Disables changing the setting from the UI
|
||||||
|
|
||||||
|
checkbox
|
||||||
|
--------
|
||||||
|
|
||||||
|
True / false (yes/no) toggle
|
||||||
|
|
||||||
|
**Argument**
|
||||||
|
|
||||||
|
Table with the following optional fields:
|
||||||
|
|
||||||
|
.. list-table::
|
||||||
|
:header-rows: 1
|
||||||
|
:widths: 20 20 60
|
||||||
|
|
||||||
|
* - name
|
||||||
|
- type (default)
|
||||||
|
- description
|
||||||
|
* - disabled
|
||||||
|
- bool (false)
|
||||||
|
- Disables changing the setting from the UI
|
||||||
|
* - l10n
|
||||||
|
- string ('Interface')
|
||||||
|
- Localization context with display values for the true/false values
|
||||||
|
* - trueLabel
|
||||||
|
- string ('Yes')
|
||||||
|
- Localization key to display for the true value
|
||||||
|
* - falseLabel
|
||||||
|
- string ('No')
|
||||||
|
- Localization key to display for the false value
|
||||||
|
|
||||||
|
number
|
||||||
|
------
|
||||||
|
|
||||||
|
Numeric input
|
||||||
|
|
||||||
|
**Argument**
|
||||||
|
|
||||||
|
Table with the following optional fields:
|
||||||
|
|
||||||
|
.. list-table::
|
||||||
|
:header-rows: 1
|
||||||
|
:widths: 20 20 60
|
||||||
|
|
||||||
|
* - name
|
||||||
|
- type (default)
|
||||||
|
- description
|
||||||
|
* - disabled
|
||||||
|
- bool (false)
|
||||||
|
- Disables changing the setting from the UI
|
||||||
|
* - integer
|
||||||
|
- bool (false)
|
||||||
|
- Only allow integer values
|
||||||
|
* - min
|
||||||
|
- number (nil)
|
||||||
|
- If set, restricts setting values to numbers larger than min
|
||||||
|
* - max
|
||||||
|
- number (nil)
|
||||||
|
- If set, restricts setting values to numbers smaller than max
|
||||||
|
|
||||||
|
select
|
||||||
|
------
|
||||||
|
|
||||||
|
A small selection box with two next / previous arrows on the sides
|
||||||
|
|
||||||
|
**Argument**
|
||||||
|
|
||||||
|
Table with the following optional fields:
|
||||||
|
|
||||||
|
.. list-table::
|
||||||
|
:header-rows: 1
|
||||||
|
:widths: 20 20 60
|
||||||
|
|
||||||
|
* - name
|
||||||
|
- type (default)
|
||||||
|
- description
|
||||||
|
* - disabled
|
||||||
|
- bool (false)
|
||||||
|
- Disables changing the setting from the UI
|
||||||
|
* - l10n
|
||||||
|
- string (required)
|
||||||
|
- Localization context with display values for items
|
||||||
|
* - items
|
||||||
|
- #list<string> ({})
|
||||||
|
- List of options to choose from, all the viable values of the setting
|
||||||
|
|
||||||
|
color
|
||||||
|
-----
|
||||||
|
|
||||||
|
Hex-code color input with a preview
|
||||||
|
|
||||||
|
**Argument**
|
||||||
|
|
||||||
|
Table with the following optional fields:
|
||||||
|
|
||||||
|
.. list-table::
|
||||||
|
:header-rows: 1
|
||||||
|
:widths: 20 20 60
|
||||||
|
|
||||||
|
* - name
|
||||||
|
- type (default)
|
||||||
|
- description
|
||||||
|
* - disabled
|
||||||
|
- bool (false)
|
||||||
|
- Disables changing the setting from the UI
|
|
@ -24,6 +24,7 @@ set(LUA_BUILTIN_FILES
|
||||||
scripts/omw/settings/renderers.lua
|
scripts/omw/settings/renderers.lua
|
||||||
|
|
||||||
l10n/Calendar/en.yaml
|
l10n/Calendar/en.yaml
|
||||||
|
l10n/Interface/en.yaml
|
||||||
|
|
||||||
scripts/omw/mwui/constants.lua
|
scripts/omw/mwui/constants.lua
|
||||||
scripts/omw/mwui/borders.lua
|
scripts/omw/mwui/borders.lua
|
||||||
|
|
3
files/builtin_scripts/l10n/Interface/en.yaml
Normal file
3
files/builtin_scripts/l10n/Interface/en.yaml
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
Yes: "Yes"
|
||||||
|
No: "No"
|
||||||
|
Reset: "Reset"
|
|
@ -28,7 +28,7 @@ require('scripts.omw.settings.renderers')(render.registerRenderer)
|
||||||
-- @field #string name A key from the localization context
|
-- @field #string name A key from the localization context
|
||||||
-- @field #string description A key from the localization context (optional, can be `nil`)
|
-- @field #string description A key from the localization context (optional, can be `nil`)
|
||||||
-- @field default A default value
|
-- @field default A default value
|
||||||
-- @field #string renderer A renderer key
|
-- @field #string renderer A renderer key (see the "Built-in Setting Renderers" page)
|
||||||
-- @field argument An argument for the renderer
|
-- @field argument An argument for the renderer
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -12,6 +12,8 @@ local function registerRenderer(name, renderFunction)
|
||||||
renderers[name] = renderFunction
|
renderers[name] = renderFunction
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local interfaceL10n = core.l10n('Interface')
|
||||||
|
|
||||||
local pages = {}
|
local pages = {}
|
||||||
local groups = {}
|
local groups = {}
|
||||||
local pageOptions = {}
|
local pageOptions = {}
|
||||||
|
@ -156,7 +158,7 @@ local function renderGroup(group, global)
|
||||||
{
|
{
|
||||||
template = I.MWUI.templates.textNormal,
|
template = I.MWUI.templates.textNormal,
|
||||||
props = {
|
props = {
|
||||||
text = 'Reset',
|
text = interfaceL10n('Reset')
|
||||||
},
|
},
|
||||||
events = {
|
events = {
|
||||||
mouseClick = async:callback(function()
|
mouseClick = async:callback(function()
|
||||||
|
@ -368,7 +370,11 @@ local function onGroupRegistered(global, key)
|
||||||
|
|
||||||
if not pages[group.page] then return end
|
if not pages[group.page] then return end
|
||||||
local options = renderPage(pages[group.page])
|
local options = renderPage(pages[group.page])
|
||||||
|
if pageOptions[group.page] then
|
||||||
pageOptions[group.page].element:destroy()
|
pageOptions[group.page].element:destroy()
|
||||||
|
else
|
||||||
|
pageOptions[group.page] = {}
|
||||||
|
end
|
||||||
for k, v in pairs(options) do
|
for k, v in pairs(options) do
|
||||||
pageOptions[group.page][k] = v
|
pageOptions[group.page][k] = v
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
|
local core = require('openmw.core')
|
||||||
local ui = require('openmw.ui')
|
local ui = require('openmw.ui')
|
||||||
local async = require('openmw.async')
|
local async = require('openmw.async')
|
||||||
|
local util = require('openmw.util')
|
||||||
local I = require('openmw.interfaces')
|
local I = require('openmw.interfaces')
|
||||||
|
|
||||||
local function applyDefaults(argument, defaults)
|
local function applyDefaults(argument, defaults)
|
||||||
|
@ -52,11 +54,13 @@ return function(registerRenderer)
|
||||||
do
|
do
|
||||||
local defaultArgument = {
|
local defaultArgument = {
|
||||||
disabled = false,
|
disabled = false,
|
||||||
|
l10n = 'Interface',
|
||||||
trueLabel = 'Yes',
|
trueLabel = 'Yes',
|
||||||
falseLabel = 'No',
|
falseLabel = 'No',
|
||||||
}
|
}
|
||||||
registerRenderer('checkbox', function(value, set, argument)
|
registerRenderer('checkbox', function(value, set, argument)
|
||||||
argument = applyDefaults(argument, defaultArgument)
|
argument = applyDefaults(argument, defaultArgument)
|
||||||
|
local l10n = core.l10n(argument.l10n)
|
||||||
return disable(argument.disabled, {
|
return disable(argument.disabled, {
|
||||||
template = I.MWUI.templates.box,
|
template = I.MWUI.templates.box,
|
||||||
content = ui.content {
|
content = ui.content {
|
||||||
|
@ -66,7 +70,7 @@ return function(registerRenderer)
|
||||||
{
|
{
|
||||||
template = I.MWUI.templates.textNormal,
|
template = I.MWUI.templates.textNormal,
|
||||||
props = {
|
props = {
|
||||||
text = value and argument.trueLabel or argument.falseLabel
|
text = l10n(value and argument.trueLabel or argument.falseLabel)
|
||||||
},
|
},
|
||||||
events = {
|
events = {
|
||||||
mouseClick = async:callback(function() set(not value) end),
|
mouseClick = async:callback(function() set(not value) end),
|
||||||
|
@ -78,4 +82,185 @@ return function(registerRenderer)
|
||||||
})
|
})
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local function validateNumber(text, argument)
|
||||||
|
local number = tonumber(text)
|
||||||
|
if not number then return end
|
||||||
|
if argument.min and number < argument.min then return end
|
||||||
|
if argument.max and number > argument.max then return end
|
||||||
|
if argument.integer and math.floor(number) ~= number then return end
|
||||||
|
return number
|
||||||
|
end
|
||||||
|
local defaultArgument = {
|
||||||
|
disabled = false,
|
||||||
|
integer = false,
|
||||||
|
min = nil,
|
||||||
|
max = nil,
|
||||||
|
}
|
||||||
|
registerRenderer('number', function(value, set, argument)
|
||||||
|
argument = applyDefaults(argument, defaultArgument)
|
||||||
|
local lastInput = nil
|
||||||
|
return disable(argument.disabled, {
|
||||||
|
template = I.MWUI.templates.textEditLine,
|
||||||
|
props = {
|
||||||
|
text = tostring(value),
|
||||||
|
},
|
||||||
|
events = {
|
||||||
|
textChanged = async:callback(function(text)
|
||||||
|
lastInput = text
|
||||||
|
end),
|
||||||
|
focusLoss = async:callback(function()
|
||||||
|
if not lastInput then return end
|
||||||
|
local number = validateNumber(lastInput, argument)
|
||||||
|
if not number then
|
||||||
|
set(value)
|
||||||
|
end
|
||||||
|
if number and number ~= value then
|
||||||
|
set(number)
|
||||||
|
end
|
||||||
|
end),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local defaultArgument = {
|
||||||
|
disabled = false,
|
||||||
|
l10n = nil,
|
||||||
|
items = {},
|
||||||
|
}
|
||||||
|
local leftArrow = ui.texture {
|
||||||
|
path = 'textures/omw_menu_scroll_left.dds',
|
||||||
|
}
|
||||||
|
local rightArrow = ui.texture {
|
||||||
|
path = 'textures/omw_menu_scroll_right.dds',
|
||||||
|
}
|
||||||
|
registerRenderer('select', function(value, set, argument)
|
||||||
|
argument = applyDefaults(argument, defaultArgument)
|
||||||
|
if not argument.l10n then
|
||||||
|
error('"select" renderer requires a "l10n" argument')
|
||||||
|
end
|
||||||
|
local l10n = core.l10n(argument.l10n)
|
||||||
|
local index = nil
|
||||||
|
local itemCount = 0
|
||||||
|
for i, item in ipairs(argument.items) do
|
||||||
|
itemCount = itemCount + 1
|
||||||
|
if item == value then
|
||||||
|
index = i
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if not index then return {} end
|
||||||
|
local label = l10n(value)
|
||||||
|
local body = {
|
||||||
|
type = ui.TYPE.Flex,
|
||||||
|
props = {
|
||||||
|
horizontal = true,
|
||||||
|
arrange = ui.ALIGNMENT.Center,
|
||||||
|
},
|
||||||
|
content = ui.content {
|
||||||
|
{
|
||||||
|
type = ui.TYPE.Image,
|
||||||
|
props = {
|
||||||
|
resource = leftArrow,
|
||||||
|
size = util.vector2(1, 1) * 12,
|
||||||
|
},
|
||||||
|
events = {
|
||||||
|
mouseClick = async:callback(function()
|
||||||
|
index = (index - 2) % itemCount + 1
|
||||||
|
set(argument.items[index])
|
||||||
|
end),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
template = I.MWUI.templates.textNormal,
|
||||||
|
props = {
|
||||||
|
text = label,
|
||||||
|
},
|
||||||
|
external = {
|
||||||
|
grow = 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type = ui.TYPE.Image,
|
||||||
|
props = {
|
||||||
|
resource = rightArrow,
|
||||||
|
size = util.vector2(1, 1) * 12,
|
||||||
|
},
|
||||||
|
events = {
|
||||||
|
mouseClick = async:callback(function()
|
||||||
|
index = (index) % itemCount + 1
|
||||||
|
set(argument.items[index])
|
||||||
|
end),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return disable(argument.disabled, {
|
||||||
|
template = I.MWUI.templates.box,
|
||||||
|
content = ui.content {
|
||||||
|
{
|
||||||
|
template = I.MWUI.templates.padding,
|
||||||
|
content = ui.content {
|
||||||
|
body,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local whiteTexture = ui.texture { path = 'white' }
|
||||||
|
local defaultArgument = {
|
||||||
|
disabled = false,
|
||||||
|
}
|
||||||
|
registerRenderer('color', function(value, set, argument)
|
||||||
|
argument = applyDefaults(argument, defaultArgument)
|
||||||
|
local colorDisplay = {
|
||||||
|
template = I.MWUI.templates.box,
|
||||||
|
content = ui.content {
|
||||||
|
{
|
||||||
|
type = ui.TYPE.Image,
|
||||||
|
props = {
|
||||||
|
resource = whiteTexture,
|
||||||
|
color = value,
|
||||||
|
-- TODO: remove hardcoded size when possible
|
||||||
|
size = util.vector2(1, 1) * 20,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
local lastInput = nil
|
||||||
|
local hexInput = {
|
||||||
|
template = I.MWUI.templates.textEditLine,
|
||||||
|
props = {
|
||||||
|
text = value:asHex(),
|
||||||
|
},
|
||||||
|
events = {
|
||||||
|
textChanged = async:callback(function(text)
|
||||||
|
lastInput = text
|
||||||
|
end),
|
||||||
|
focusLoss = async:callback(function()
|
||||||
|
if not lastInput then return end
|
||||||
|
if not pcall(function() set(util.color.hex(lastInput)) end)
|
||||||
|
then set(value) end
|
||||||
|
end),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return disable(argument.disabled, {
|
||||||
|
type = ui.TYPE.Flex,
|
||||||
|
props = {
|
||||||
|
horizontal = true,
|
||||||
|
arrange = ui.ALIGNMENT.Center,
|
||||||
|
},
|
||||||
|
content = ui.content {
|
||||||
|
colorDisplay,
|
||||||
|
{ template = I.MWUI.templates.interval },
|
||||||
|
hexInput,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
end)
|
||||||
|
end
|
||||||
end
|
end
|
Loading…
Reference in a new issue