From da5cbfd0fce5d49d6c04807e0dda6bc8e8e2d11d Mon Sep 17 00:00:00 2001 From: luk3yx Date: Mon, 3 Mar 2025 14:35:18 +1300 Subject: [PATCH] Support font_size for labels etc --- doc/layout-elements.md | 4 ++++ doc/styling.md | 9 +++------ expand.lua | 4 ++-- init.lua | 4 ++-- layout.lua | 37 ++++++++++++++++++++++++++++--------- 5 files changed, 39 insertions(+), 19 deletions(-) diff --git a/doc/layout-elements.md b/doc/layout-elements.md index 1f635c0..673a5a7 100644 --- a/doc/layout-elements.md +++ b/doc/layout-elements.md @@ -6,6 +6,10 @@ All examples will assume that this line exists. These elements are used to lay out elements in the form. They don't have a direct equivalent in formspecs. +**Warning:** The below elements (except `gui.Spacer`) do not support `w` and +`h` properties and will break in weird ways if you try and use them. Use +`min_w` and `min_h` instead. + ## `gui.VBox` A vertical box, similar to a VBox in GTK. Elements inside a VBox are stacked diff --git a/doc/styling.md b/doc/styling.md index 04ae390..0de2350 100644 --- a/doc/styling.md +++ b/doc/styling.md @@ -45,9 +45,6 @@ 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:** 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 Alternatively, you can use the `gui.Style` and `gui.StyleType` elements if you @@ -71,6 +68,6 @@ 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. +**Warning:** `gui.Style` and `gui.StyleType` do not support styles that change +the element size, such as `font_size` for labels and `size` and `spacing` +lists. Use the inline syntax instead for these styles. diff --git a/expand.lua b/expand.lua index f735d27..ae38597 100644 --- a/expand.lua +++ b/expand.lua @@ -17,7 +17,7 @@ -- along with this program. If not, see . -- -local DEFAULT_SPACING, LABEL_OFFSET, get_and_fill_in_sizes, +local DEFAULT_SPACING, LABEL_HEIGHT, get_and_fill_in_sizes, invisible_elems = ... local align_types = {} @@ -75,7 +75,7 @@ function align_types.fill(node, x, w, extra_space) name = "_#", label = "", } - node.y = node.y - LABEL_OFFSET + node.y = node.y - (node._flow_font_height or LABEL_HEIGHT) / 2 node.label = nil node.style = nil node._label_hack = true diff --git a/init.lua b/init.lua index 674ae9b..5e53fa2 100644 --- a/init.lua +++ b/init.lua @@ -22,11 +22,11 @@ flow = {} local modpath = core.get_modpath("flow") local apply_padding, get_and_fill_in_sizes, set_current_lang, - DEFAULT_SPACING, LABEL_OFFSET, invisible_elems = + DEFAULT_SPACING, LABEL_HEIGHT, invisible_elems = dofile(modpath .. "/layout.lua") local expand = assert(loadfile(modpath .. "/expand.lua"))( - DEFAULT_SPACING, LABEL_OFFSET, get_and_fill_in_sizes, invisible_elems + DEFAULT_SPACING, LABEL_HEIGHT, get_and_fill_in_sizes, invisible_elems ) local parse_callbacks = dofile(modpath .. "/input.lua") diff --git a/layout.lua b/layout.lua index f3f9fc8..9fa2db9 100644 --- a/layout.lua +++ b/layout.lua @@ -68,7 +68,6 @@ local function naive_str_width(str) end local LABEL_HEIGHT = 0.4 -local LABEL_OFFSET = LABEL_HEIGHT / 2 local CHAR_WIDTH = 0.21 -- The "current_lang" variable isn't ideal but means that the language will be @@ -93,14 +92,29 @@ local function get_lines_size(lines) return w, LABEL_HEIGHT * #lines end -local function get_label_size(label) +local ASTERISK = ("*"):byte() +local function parse_font_size(str) + -- Only support *1.1 etc for now, I don't know if the other formats are + -- used + if str and type(str) == "string" and str:byte(1) == ASTERISK then + return tonumber(str:sub(2)) or 1 + end + return 1 +end + +local function get_label_size(label, style, line_spacing) label = label or "" if current_lang and current_lang ~= "" and current_lang ~= "en" then label = get_translated_string(current_lang, label) end local longest_line_width, line_count = naive_str_width(label) - return longest_line_width * CHAR_WIDTH, line_count * LABEL_HEIGHT + local font_size_frac = parse_font_size(style and style.font_size) + + local font_height = font_size_frac * LABEL_HEIGHT + return longest_line_width * CHAR_WIDTH * font_size_frac, + font_height + (line_count - 1) * (line_spacing or font_height), + font_height end local size_getters = {} @@ -160,13 +174,16 @@ end size_getters.scroll_container = size_getters.container function size_getters.label(node) - local w, h = get_label_size(node.label) - return w, LABEL_HEIGHT + (h - LABEL_HEIGHT) * 1.25 + -- Labels always have a distance of 0.5 between each line regardless of the + -- font size + local w, h, font_height = get_label_size(node.label, node.style, 0.5) + node._flow_font_height = font_height + return w, h end local MIN_BUTTON_HEIGHT = 0.8 function size_getters.button(node) - local x, y = get_label_size(node.label) + local x, y = get_label_size(node.label, node.style) return max(x, MIN_BUTTON_HEIGHT * 2), max(y, MIN_BUTTON_HEIGHT) end @@ -177,6 +194,7 @@ size_getters.item_image_button = size_getters.button size_getters.button_url = size_getters.button function size_getters.field(node) + -- Field labels ignore the "font_size" style local label_w, label_h = get_label_size(node.label) -- This is done in apply_padding as well but the label size has already @@ -185,7 +203,7 @@ function size_getters.field(node) node._padding_top = label_h end - local w, h = get_label_size(node.default) + local w, h = get_label_size(node.default, node.style) return max(w, label_w, 3), max(h, MIN_BUTTON_HEIGHT) end size_getters.pwdfield = size_getters.field @@ -205,6 +223,7 @@ function size_getters.dropdown(node) end function size_getters.checkbox(node) + -- Checkboxes don't support font_size local w, h = get_label_size(node.label) return w + 0.4, h end @@ -217,7 +236,7 @@ local function apply_padding(node, x, y) -- Labels are positioned from the centre of the first line and checkboxes -- are positioned from the centre. if node.type == "label" then - y = y + LABEL_OFFSET + y = y + (node._flow_font_height or LABEL_HEIGHT) / 2 elseif node.type == "checkbox" then y = y + h / 2 elseif field_elems[node.type] and not node._padding_top and node.label and @@ -323,4 +342,4 @@ local function set_current_lang(lang) end return apply_padding, get_and_fill_in_sizes, set_current_lang, - DEFAULT_SPACING, LABEL_OFFSET, invisible_elems + DEFAULT_SPACING, LABEL_HEIGHT, invisible_elems