Add support for padding[] (MT 5.7.0+)

This commit is contained in:
luk3yx 2023-03-15 18:08:13 +13:00
parent 68dd6d4137
commit 412a4676a7
2 changed files with 51 additions and 17 deletions

View File

@ -32,6 +32,10 @@ The following elements are supported:
- **You need to use these to set the position of the HUD!**
- See [the Minetest API documentation](https://minetest.gitlab.io/minetest/formspec/#positionxy) for more info.
- You probably want `anchor` to have the same value as `position`.
- `padding`
- When set, hud_fs attempts to calculate the form size in the same way that
the client does.
- Use `padding[0.05,0.05]` to make the HUD use roughly the same scaling as formspecs.
- `container`
- `label`
- Because of HUD limitations, `minetest.colorize()` only works at the start
@ -79,6 +83,8 @@ hud_fs.show_hud(player, "waypoints", {
default (64, subject to change).
- The scale is the amount of pixels per co-ordinate. For example, a 1x1
image will have a size of 10x10 pixels if the scale is set to 10.
- This is ignored on MT 5.7.0+ clients if a `padding[]` element exists in
the formspec.
- `hud_fs.set_z_index(formname, z_index)`: Sets the base Z-Index of the HUD.
- All future HUDs shown with `formname` will use this z-index instead of
the default (0).
@ -108,12 +114,11 @@ rejected in https://github.com/minetest/minetest/issues/10135.
#### But I hate formspecs and don't want to touch them
Then don't use this mod. There are plenty of other HUD library mods around such
The API provided by this mod accepts a list of HUD elements in place of a
formspec. Alternatively, there are other HUD library mods around such
as [hudlib](https://github.com/octacian/hudlib) and
[panel_lib](https://gitlab.com/zughy-friends-minetest/panel_lib).
Alternatively, the API provided by this mod accepts a list of HUD elements in
place of a formspec.
## Performance

View File

@ -12,7 +12,8 @@ local DEBUG = false
local DEFAULT_SCALE = 64
local DEFAULT_Z_INDEX = 0
local floor, type, pairs, max = math.floor, type, pairs, math.max
local floor, type, pairs = math.floor, type, pairs
local max, min = math.max, math.min
-- Attempt to use modlib's parser
local colorstring_to_number
@ -73,9 +74,10 @@ function nodes.label(node, scale)
return elem
end
function nodes.image(node, scale, _, possibly_using_gles)
local w = floor(node.w * scale)
local h = floor(node.h * scale)
function nodes.image(node, scale, _, possibly_using_gles, client_hud_scale)
-- The provided texture could be any size so this has to scale it first
local w = floor(node.w * scale * client_hud_scale)
local h = floor(node.h * scale * client_hud_scale)
local texture = node.texture_name
if w > 0 and h > 0 and texture ~= "" then
@ -104,12 +106,12 @@ function nodes.image(node, scale, _, possibly_using_gles)
hud_elem_type = "image",
text = texture,
alignment = {x = 1, y = 1},
scale = {x = 1, y = 1},
scale = {x = 1 / client_hud_scale, y = 1 / client_hud_scale},
}
end
-- Hack box[] into image[]
function nodes.box(node, scale, add_node, possibly_using_gles)
function nodes.box(node, scale)
local col = node.color
-- Add default transparency
if col:byte(1) == 35 then
@ -119,8 +121,14 @@ function nodes.box(node, scale, add_node, possibly_using_gles)
col = col .. "8C"
end
end
node.texture_name = 'hud_fs_box.png^[colorize:' .. col
return nodes.image(node, scale, add_node, possibly_using_gles)
-- Since hud_fs_box.png is guaranteed to be 1x1, scale can be used directly
return {
hud_elem_type = "image",
text = 'hud_fs_box.png^[colorize:' .. col,
alignment = {x = 1, y = 1},
scale = {x = node.w * scale, y = node.h * scale},
}
end
function nodes.textarea(node, scale, add_node)
@ -168,7 +176,7 @@ local function get_tile_image(tiles, preferred_texture)
return tile
end
function nodes.item_image(node, scale, add_node, possibly_using_gles)
function nodes.item_image(node, ...)
local def = minetest.registered_items[node.item_name]
if not def then
node.texture_name = "unknown_item.png"
@ -185,7 +193,7 @@ function nodes.item_image(node, scale, add_node, possibly_using_gles)
else
node.texture_name = "unknown_node.png"
end
return nodes.image(node, scale, add_node, possibly_using_gles)
return nodes.image(node, ...)
end
function nodes.button(node, _, add_node)
@ -224,7 +232,7 @@ local function render_error(err)
return {}
end
local function render(tree, possibly_using_gles, scale, z_index)
local function render(tree, possibly_using_gles, scale, z_index, window)
if type(tree) == "string" then
local err
tree, err = formspec_ast.parse(tree)
@ -245,16 +253,17 @@ local function render(tree, possibly_using_gles, scale, z_index)
scale = scale or DEFAULT_SCALE
z_index = z_index or DEFAULT_Z_INDEX
local client_hud_scale = window and window.real_hud_scaling or 1
local function add_node(node_type, node)
local elem = nodes[node_type](node, scale, add_node,
possibly_using_gles)
possibly_using_gles, client_hud_scale)
elem.position = pos
elem.name = node_type
elem.z_index = z_index
elem.offset = {
x = (node.x + offset_x) * scale,
y = (node.y + offset_y) * scale
}
if node_type == "box" then print(dump(elem)) end
hud_elems[#hud_elems + 1] = elem
z_index = z_index + 1
end
@ -272,6 +281,24 @@ local function render(tree, possibly_using_gles, scale, z_index)
end
offset_x = -node.x * size_w
offset_y = -node.y * size_h
elseif node_type == "padding" and window then
if size_w == 0 or size_h == 0 then
return render_error("padding[] without size[]")
elseif #hud_elems > 0 then
return render_error("padding[] after other elements")
end
-- If padding[] is present, override the specified scale on new
-- clients
scale = min(
-- The client's size
window.size.x / (window.max_formspec_size.x * 1.1),
window.size.y / (window.max_formspec_size.y * 1.1),
-- Maximum size based on the padding
window.size.x * (1 - node.x * 2) / size_w,
window.size.y * (1 - node.y * 2) / size_h
) / client_hud_scale
elseif nodes[node_type] then
add_node(node_type, node)
elseif node_type == nil and node.hud_elem_type then
@ -367,8 +394,10 @@ function hud_fs.show_hud(player, formname, formspec)
info.platform == "iOS")
local ids, elems = data[1], data[2]
local window = minetest.get_player_window_information and
minetest.get_player_window_information(name)
local new_elems = render(formspec, possibly_using_gles, scales[formname],
z_indexes[formname])
z_indexes[formname], window)
-- Z-index was added to MT 5.2.0 (protocol version 39) and is ignored by
-- older clients. Because of the way HUDs work, sometimes it's safest to