mirror of https://github.com/OpenMW/openmw.git
MWUI interface (resolve https://gitlab.com/OpenMW/openmw/-/issues/6594)
parent
b4fca045c6
commit
03659bef86
@ -0,0 +1,6 @@
|
||||
Interface MWUI
|
||||
==============
|
||||
|
||||
.. raw:: html
|
||||
:file: generated_html/scripts_omw_mwui_init.html
|
||||
|
@ -0,0 +1,5 @@
|
||||
Package openmw_aux.ui
|
||||
=======================
|
||||
|
||||
.. raw:: html
|
||||
:file: generated_html/openmw_aux_ui.html
|
@ -0,0 +1,36 @@
|
||||
local ui = require('openmw.ui')
|
||||
|
||||
---
|
||||
-- `openmw_aux.ui` defines utility functions for UI.
|
||||
-- Implementation can be found in `resources/vfs/openmw_aux/ui.lua`.
|
||||
-- @module ui
|
||||
-- @usage local auxUi = require('openmw_aux.ui')
|
||||
local aux_ui = {}
|
||||
|
||||
local function deepContentCopy(content)
|
||||
local result = ui.content{}
|
||||
for _, v in ipairs(content) do
|
||||
result:add(aux_ui.deepLayoutCopy(v))
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
---
|
||||
-- @function [parent=#ui] templates
|
||||
-- @param #table layout
|
||||
-- @return #table copied layout
|
||||
function aux_ui.deepLayoutCopy(layout)
|
||||
local result = {}
|
||||
for k, v in pairs(layout) do
|
||||
if k == 'content' then
|
||||
result[k] = deepContentCopy(v)
|
||||
elseif type(v) == 'table' then
|
||||
result[k] = aux_ui.deepLayoutCopy(v)
|
||||
else
|
||||
result[k] = v
|
||||
end
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
return aux_ui
|
@ -0,0 +1,120 @@
|
||||
local ui = require('openmw.ui')
|
||||
local util = require('openmw.util')
|
||||
|
||||
local constants = require('scripts.omw.mwui.constants')
|
||||
|
||||
local v2 = util.vector2
|
||||
|
||||
local sideParts = {
|
||||
left = util.vector2(0, 0.5),
|
||||
right = util.vector2(1, 0.5),
|
||||
top = util.vector2(0.5, 0),
|
||||
bottom = util.vector2(0.5, 1),
|
||||
}
|
||||
local cornerParts = {
|
||||
top_left_corner = util.vector2(0, 0),
|
||||
top_right_corner = util.vector2(1, 0),
|
||||
bottom_left_corner = util.vector2(0, 1),
|
||||
bottom_right_corner = util.vector2(1, 1),
|
||||
}
|
||||
|
||||
local resources = {}
|
||||
do
|
||||
local boxBorderPattern = 'textures/menu_thin_border_%s.dds'
|
||||
for k, _ in pairs(sideParts) do
|
||||
resources[k] = ui.texture{ path = boxBorderPattern:format(k) }
|
||||
end
|
||||
for k, _ in pairs(cornerParts) do
|
||||
resources[k] = ui.texture{ path = boxBorderPattern:format(k) }
|
||||
end
|
||||
end
|
||||
|
||||
local borderPieces = {}
|
||||
for k, align in pairs(sideParts) do
|
||||
local resource = resources[k]
|
||||
local horizontal = align.x ~= 0.5
|
||||
borderPieces[#borderPieces + 1] = {
|
||||
type = ui.TYPE.Image,
|
||||
props = {
|
||||
resource = resource,
|
||||
relativePosition = align,
|
||||
anchor = align,
|
||||
relativeSize = horizontal and v2(0, 1) or v2(1, 0),
|
||||
size = (horizontal and v2(1, -2) or v2(-2, 1)) * constants.borderSize,
|
||||
tileH = not horizontal,
|
||||
tileV = horizontal,
|
||||
},
|
||||
}
|
||||
end
|
||||
|
||||
for k, align in pairs(cornerParts) do
|
||||
local resource = resources[k]
|
||||
borderPieces[#borderPieces + 1] = {
|
||||
type = ui.TYPE.Image,
|
||||
props = {
|
||||
resource = resource,
|
||||
relativePosition = align,
|
||||
anchor = align,
|
||||
size = v2(1, 1) * constants.borderSize,
|
||||
},
|
||||
}
|
||||
end
|
||||
|
||||
borderPieces[#borderPieces + 1] = {
|
||||
external = {
|
||||
slot = true,
|
||||
},
|
||||
props = {
|
||||
position = v2(1, 1) * (constants.borderSize + constants.padding),
|
||||
size = v2(-2, -2) * (constants.borderSize + constants.padding),
|
||||
relativeSize = v2(1, 1),
|
||||
},
|
||||
}
|
||||
|
||||
local borders = {
|
||||
content = ui.content(borderPieces)
|
||||
}
|
||||
borders.content:add({
|
||||
external = {
|
||||
slot = true,
|
||||
},
|
||||
props = {
|
||||
size = v2(-2, -2) * constants.borderSize,
|
||||
},
|
||||
})
|
||||
|
||||
local horizontalLine = {
|
||||
content = ui.content {
|
||||
{
|
||||
type = ui.TYPE.Image,
|
||||
props = {
|
||||
resource = resources.top,
|
||||
tileH = true,
|
||||
tileV = false,
|
||||
size = v2(0, constants.borderSize),
|
||||
relativeSize = v2(1, 0),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
local verticalLine = {
|
||||
content = ui.content {
|
||||
{
|
||||
type = ui.TYPE.Image,
|
||||
props = {
|
||||
resource = resources.left,
|
||||
tileH = false,
|
||||
tileV = true,
|
||||
size = v2(constants.borderSize, 0),
|
||||
relativeSize = v2(0, 1),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
return function(templates)
|
||||
templates.borders = borders
|
||||
templates.horizontalLine = horizontalLine
|
||||
templates.verticalLine = verticalLine
|
||||
end
|
@ -0,0 +1,45 @@
|
||||
local ui = require('openmw.ui')
|
||||
local util = require('openmw.util')
|
||||
|
||||
local whiteTexture = ui.texture{ path = 'white' }
|
||||
|
||||
local menuTransparency = ui._getMenuTransparency()
|
||||
|
||||
return function(templates)
|
||||
templates.backgroundTransparent = {
|
||||
props = {
|
||||
resource = whiteTexture,
|
||||
color = util.color.rgb(0, 0, 0),
|
||||
alpha = menuTransparency,
|
||||
},
|
||||
}
|
||||
templates.backgroundSolid = {
|
||||
props = {
|
||||
resource = whiteTexture,
|
||||
color = util.color.rgb(0, 0, 0),
|
||||
},
|
||||
}
|
||||
templates.box = {
|
||||
props = {
|
||||
inheritAlpha = false,
|
||||
},
|
||||
content = ui.content {
|
||||
{
|
||||
type = ui.TYPE.Image,
|
||||
template = templates.backgroundTransparent,
|
||||
props = {
|
||||
relativeSize = util.vector2(1, 1),
|
||||
},
|
||||
},
|
||||
{
|
||||
template = templates.borders,
|
||||
props = {
|
||||
relativeSize = util.vector2(1, 1),
|
||||
},
|
||||
external = {
|
||||
slot = true,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
end
|
@ -0,0 +1,8 @@
|
||||
local util = require('openmw.util')
|
||||
|
||||
return {
|
||||
textNormalSize = 16,
|
||||
sandColor = util.color.rgb(202 / 255, 165 / 255, 96 / 255),
|
||||
borderSize = 4,
|
||||
padding = 2,
|
||||
}
|
@ -0,0 +1,101 @@
|
||||
local util = require('openmw.util')
|
||||
|
||||
local function shallowLayoutCopy(source, target)
|
||||
for k in pairs(target) do
|
||||
target[k] = nil
|
||||
end
|
||||
for k, v in pairs(source) do
|
||||
target[k] = v
|
||||
end
|
||||
return target
|
||||
end
|
||||
|
||||
---
|
||||
-- @type Templates
|
||||
-- @usage
|
||||
-- local I = require('openmw.interfaces')
|
||||
-- local ui = require('openmw.ui')
|
||||
-- local auxUi = require('openmw_aux.ui')
|
||||
-- ui.create {
|
||||
-- template = I.MWUI.templates.textNormal,
|
||||
-- layer = 'Windows',
|
||||
-- type = ui.TYPE.Text,
|
||||
-- props = {
|
||||
-- text = 'Hello, world!',
|
||||
-- },
|
||||
-- }
|
||||
-- -- important to copy here
|
||||
-- local myText = auxUi.deepLayoutCopy(I.MWUI.templates.textNormal)
|
||||
-- myText.props.textSize = 20
|
||||
-- I.MWUI.templates.textNormal = myText
|
||||
-- ui.updateAll()
|
||||
|
||||
local templatesMeta = {
|
||||
__index = function(self, key)
|
||||
return self.__templates[key]
|
||||
end,
|
||||
__newindex = function(self, key, template)
|
||||
local target = self.__templates[key]
|
||||
if target == template then
|
||||
error("Overriding a template with itself")
|
||||
else
|
||||
shallowLayoutCopy(template, target)
|
||||
end
|
||||
end,
|
||||
}
|
||||
|
||||
---
|
||||
-- @module MWUI
|
||||
-- @usage require('openmw.interfaces').MWUI
|
||||
local function TemplateOverrides(templates)
|
||||
return setmetatable({
|
||||
__templates = util.makeReadOnly(templates),
|
||||
}, templatesMeta)
|
||||
end
|
||||
|
||||
---
|
||||
-- @field [parent=#MWUI] #Templates templates
|
||||
local templates = {}
|
||||
|
||||
---
|
||||
-- Standard rectangular border
|
||||
-- @field [parent=#Templates] openmw.ui#Layout border
|
||||
require('scripts.omw.mwui.borders')(templates)
|
||||
|
||||
---
|
||||
-- Border combined with a transparent background
|
||||
-- @field [parent=#Templates] openmw.ui#Layout box
|
||||
---
|
||||
-- A transparent background
|
||||
-- @field [parent=#Templates] openmw.ui#Layout backgroundTransparent
|
||||
---
|
||||
-- A solid, non-transparent background
|
||||
-- @field [parent=#Templates] openmw.ui#Layout backgroundSolid
|
||||
require('scripts.omw.mwui.box')(templates)
|
||||
|
||||
---
|
||||
-- Standard "sand" colored text
|
||||
-- @field [parent=#Templates] openmw.ui#Layout textNormal
|
||||
require('scripts.omw.mwui.text')(templates)
|
||||
|
||||
---
|
||||
-- Single line text input
|
||||
-- @field [parent=#Templates] openmw.ui#Layout textEditLine
|
||||
|
||||
---
|
||||
-- Multiline text input
|
||||
-- @field [parent=#Templates] openmw.ui#Layout textEditBox
|
||||
require('scripts.omw.mwui.textEdit')(templates)
|
||||
|
||||
---
|
||||
-- Interface version
|
||||
-- @field [parent=#MWUI] #number version
|
||||
local interface = {
|
||||
version = 0,
|
||||
templates = TemplateOverrides(templates),
|
||||
}
|
||||
|
||||
return {
|
||||
interfaceName = "MWUI",
|
||||
interface = interface,
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
local ui = require('openmw.ui')
|
||||
|
||||
local constants = require('scripts.omw.mwui.constants')
|
||||
|
||||
local textNormal = {
|
||||
type = ui.TYPE.Text,
|
||||
props = {
|
||||
textSize = constants.textNormalSize,
|
||||
textColor = constants.sandColor,
|
||||
},
|
||||
}
|
||||
|
||||
return function(templates)
|
||||
templates.textNormal = textNormal
|
||||
end
|
@ -0,0 +1,47 @@
|
||||
local util = require('openmw.util')
|
||||
local ui = require('openmw.ui')
|
||||
|
||||
local constants = require('scripts.omw.mwui.constants')
|
||||
|
||||
return function(templates)
|
||||
local borderContent = ui.content {
|
||||
{
|
||||
template = templates.borders,
|
||||
props = {
|
||||
relativeSize = util.vector2(1, 1),
|
||||
},
|
||||
content = ui.content {
|
||||
{
|
||||
external = {
|
||||
slot = true,
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
templates.textEditLine = {
|
||||
type = ui.TYPE.TextEdit,
|
||||
props = {
|
||||
textSize = constants.textNormalSize,
|
||||
textColor = constants.sandColor,
|
||||
textAlignH = ui.ALIGNMENT.Start,
|
||||
textAlignV = ui.ALIGNMENT.Center,
|
||||
multiline = false,
|
||||
},
|
||||
content = borderContent,
|
||||
}
|
||||
|
||||
templates.textEditBox = {
|
||||
type = ui.TYPE.TextEdit,
|
||||
props = {
|
||||
textSize = constants.textNormalSize,
|
||||
textColor = constants.sandColor,
|
||||
textAlignH = ui.ALIGNMENT.Start,
|
||||
textAlignV = ui.ALIGNMENT.Start,
|
||||
multiline = true,
|
||||
wordWrap = true,
|
||||
},
|
||||
content = borderContent,
|
||||
}
|
||||
end
|
Loading…
Reference in New Issue