Support font_size for labels etc

This commit is contained in:
luk3yx 2025-03-03 14:35:18 +13:00
parent bb4f0c9750
commit da5cbfd0fc
5 changed files with 39 additions and 19 deletions

View File

@ -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

View File

@ -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.

View File

@ -17,7 +17,7 @@
-- along with this program. If not, see <https://www.gnu.org/licenses/>.
--
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

View File

@ -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")

View File

@ -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