Support "size" and "spacing" list styles

These are only supported in inline styles so that flow can calculate the
size of the elements without having to look through the rest of the
tree.
This commit is contained in:
luk3yx 2025-03-03 13:51:25 +13:00
parent 8c96383cc4
commit bea549ec31
4 changed files with 38 additions and 9 deletions

View File

@ -45,8 +45,8 @@ See [the Luanti documentation](https://api.luanti.org/formspec/#styling-formspec
for a list of valid property names and values. Flow accepts numbers and
booleans as property values where applicable.
**Warning:** Flow does not currently support styles that change the element
size, like `font_size` for labels and `size` for lists.
**Warning:** Styles that change the size of the element are currently only
supported on `gui.List` (notably `font_size` on labels won't work properly)
## Separate style elements
@ -70,3 +70,7 @@ gui.Button{
```
The `Style` and `StyleType` elements are invisible and won't affect padding.
**Warning:** `gui.Style` and `gui.StyleType` do not support *any* styles that
change the element size, such as `font_size` for labels and `size` and `spacing`
lists.

View File

@ -17,7 +17,8 @@
-- along with this program. If not, see <https://www.gnu.org/licenses/>.
--
local DEFAULT_SPACING, LABEL_OFFSET, invisible_elems = ...
local DEFAULT_SPACING, LABEL_OFFSET, get_and_fill_in_sizes,
invisible_elems = ...
local align_types = {}
function align_types.fill(node, x, w, extra_space)
@ -147,8 +148,7 @@ local function expand(box)
if not invisible_elems[node.type] then
local width, height = node.w or 0, node.h or 0
if node.type == "list" then
width = width * 1.25 - 0.25
height = height * 1.25 - 0.25
width, height = get_and_fill_in_sizes(node)
end
local padding_x2 = (node.padding or 0) * 2
align_types[node.align_h or "auto"](node, "x", "w", box.w -
@ -191,8 +191,10 @@ local function expand(box)
end
if node.type == "list" then
width = width * 1.25 - 0.25
height = height * 1.25 - 0.25
width, height = get_and_fill_in_sizes(node)
if y == "x" then
width, height = height, width
end
end
free_space = free_space - width - (node.padding or 0) * 2 -
(y == "x" and node._padding_top or 0)

View File

@ -26,7 +26,7 @@ local apply_padding, get_and_fill_in_sizes, set_current_lang,
dofile(modpath .. "/layout.lua")
local expand = assert(loadfile(modpath .. "/expand.lua"))(
DEFAULT_SPACING, LABEL_OFFSET, invisible_elems
DEFAULT_SPACING, LABEL_OFFSET, get_and_fill_in_sizes, invisible_elems
)
local parse_callbacks = dofile(modpath .. "/input.lua")

View File

@ -105,9 +105,32 @@ end
local size_getters = {}
local function parse_v2f(str, default_x, default_y)
if str and type(str) == "string" then
local x, y = str:match("^%s-(%d+)%s-,%s-(%d+)%s-$")
return tonumber(x) or default_x, tonumber(y) or default_y
end
return default_x, default_y
end
local function get_and_fill_in_sizes(node)
if node.type == "list" then
return node.w * 1.25 - 0.25, node.h * 1.25 - 0.25
if node._flow_w and node._flow_h then
return node._flow_w, node._flow_h
end
local style = node.style
local slot_w, slot_h = parse_v2f(style and style.size, 1, 1)
local spacing_w, spacing_h = parse_v2f(style and style.spacing, 0.25, 0.25)
local w = node.w * (slot_w + spacing_w) - spacing_w
local h = node.h * (slot_h + spacing_h) - spacing_h
-- Cache calculated size so we don't have to parse the list style again
node._flow_w, node._flow_h = w, h
return w, h
end
if node.w and node.h then