From bea549ec31b024d05c25a38742df651e39fd3f87 Mon Sep 17 00:00:00 2001 From: luk3yx Date: Mon, 3 Mar 2025 13:51:25 +1300 Subject: [PATCH] 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. --- doc/styling.md | 8 ++++++-- expand.lua | 12 +++++++----- init.lua | 2 +- layout.lua | 25 ++++++++++++++++++++++++- 4 files changed, 38 insertions(+), 9 deletions(-) diff --git a/doc/styling.md b/doc/styling.md index 608cd10..04ae390 100644 --- a/doc/styling.md +++ b/doc/styling.md @@ -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. diff --git a/expand.lua b/expand.lua index 7bf165d..f735d27 100644 --- a/expand.lua +++ b/expand.lua @@ -17,7 +17,8 @@ -- along with this program. If not, see . -- -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) diff --git a/init.lua b/init.lua index e6c07a5..674ae9b 100644 --- a/init.lua +++ b/init.lua @@ -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") diff --git a/layout.lua b/layout.lua index 6bd42ed..3db9240 100644 --- a/layout.lua +++ b/layout.lua @@ -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