Add gui.Spacer

This commit is contained in:
luk3yx 2022-07-18 11:35:31 +12:00
parent fa003ade20
commit 49567b7055
2 changed files with 95 additions and 25 deletions

View File

@ -152,6 +152,64 @@ gui.ScrollableVBox{
} }
``` ```
#### `gui.Spacer`
A "flexible space" element that expands by default. Example usage:
```lua
gui.HBox{
-- These buttons will be on the left-hand side of the screen
gui.Button{label = "Cancel"},
gui.Button{label = "< Back"},
gui.Spacer{},
-- These buttons will be on the right-hand side of the screen
gui.Button{label = "Next >"},
gui.Button{label = "Confirm"},
}
```
I advise against using spacers when `expand = true` and `align = ...` would
work just as well since spacers are implemented hackily and won't account for
some special cases.
You can replicate the above example without spacers, however it doesn't look as
clean:
```lua
gui.HBox{
-- These buttons will be on the left-hand side of the screen
gui.Button{label = "Cancel"},
gui.Button{label = "< Back", expand = true, align_h = "left"},
-- These buttons will be on the right-hand side of the screen
gui.Button{label = "Next >"},
gui.Button{label = "Confirm"},
}
```
You should not do this as it creates unnecessary boxes, and the label may be
slightly off-centre (because label widths depend on screen size, DPI, etc
and this code doesn't trigger the centering hack):
```lua
gui.HBox{
gui.Spacer{},
gui.Label{label="I am not properly centered!"},
gui.Spacer{},
}
```
You should do this instead:
```lua
gui.Label{label="I am centered!", align_h = "centre"},
```
This applies to other elements as well, because using HBox and Spacer to centre
elements creates unnecessary containers.
### Minetest formspec elements ### Minetest formspec elements
There is an auto-generated `elements.md` file which contains a list of elements There is an auto-generated `elements.md` file which contains a list of elements

View File

@ -330,7 +330,7 @@ local function expand(box)
local expand_count = 0 local expand_count = 0
for i, node in ipairs(box) do for i, node in ipairs(box) do
local width, height = node[w] or 0, node[h] or 0 local width, height = node[w] or 0, node[h] or 0
if width > 0 and height > 0 then if not invisible_elems[node.type] then
if i > 1 then if i > 1 then
free_space = free_space - (box.spacing or DEFAULT_SPACING) free_space = free_space - (box.spacing or DEFAULT_SPACING)
end end
@ -347,7 +347,7 @@ local function expand(box)
-- Nodes are expanded in the other direction no matter what their -- Nodes are expanded in the other direction no matter what their
-- expand setting is -- expand setting is
if box_h > height and height > 0 then if box_h > height then
align_types[node[align_v] or "auto"](node, y, h, align_types[node[align_v] or "auto"](node, y, h,
box_h - height - (node.padding or 0) * 2 - box_h - height - (node.padding or 0) * 2 -
(y == "y" and node._padding_top or 0), true) (y == "y" and node._padding_top or 0), true)
@ -561,18 +561,7 @@ local function parse_callbacks(tree, ctx_form)
return callbacks, saved_fields return callbacks, saved_fields
end end
local gui = setmetatable({ local gui_mt = {
embed = function(fs, w, h)
if type(fs) ~= "table" then
fs = formspec_ast.parse(fs)
end
fs.type = "container"
fs.w = w
fs.h = h
return fs
end,
formspec_version = 0,
}, {
__index = function(gui, k) __index = function(gui, k)
local elem_type = k local elem_type = k
if elem_type ~= "ScrollbarOptions" and elem_type ~= "TableOptions" and if elem_type ~= "ScrollbarOptions" and elem_type ~= "TableOptions" and
@ -589,10 +578,19 @@ local gui = setmetatable({
rawset(gui, k, f) rawset(gui, k, f)
return f return f
end, end,
__newindex = function() }
error("Cannot modifiy gui table") local gui = setmetatable({
end embed = function(fs, w, h)
}) if type(fs) ~= "table" then
fs = formspec_ast.parse(fs)
end
fs.type = "container"
fs.w = w
fs.h = h
return fs
end,
formspec_version = 0,
}, gui_mt)
flow.widgets = gui flow.widgets = gui
local current_ctx local current_ctx
@ -780,8 +778,8 @@ end
-- Extra GUI elements -- Extra GUI elements
-- Please don't use rawset(gui, ...) in your own code -- Please don't modify the gui table in your own code
rawset(gui, "PaginatedVBox", function(def) function gui.PaginatedVBox(def)
local w, h = def.w, def.h local w, h = def.w, def.h
def.w, def.h = nil, nil def.w, def.h = nil, nil
local paginator_name = "_paginator-" .. assert(def.name) local paginator_name = "_paginator-" .. assert(def.name)
@ -844,9 +842,9 @@ rawset(gui, "PaginatedVBox", function(def)
}, },
} }
} }
end) end
rawset(gui, "ScrollableVBox", function(def) function gui.ScrollableVBox(def)
-- On older clients fall back to a paginated vbox -- On older clients fall back to a paginated vbox
if gui.formspec_version < 4 then if gui.formspec_version < 4 then
return gui.PaginatedVBox(def) return gui.PaginatedVBox(def)
@ -882,9 +880,9 @@ rawset(gui, "ScrollableVBox", function(def)
name = scrollbar_name, name = scrollbar_name,
} }
} }
end) end
rawset(gui, "Flow", function(def) function gui.Flow(def)
local vbox = { local vbox = {
type = "vbox", type = "vbox",
bgcolor = def.bgcolor, bgcolor = def.bgcolor,
@ -908,7 +906,21 @@ rawset(gui, "Flow", function(def)
end end
vbox[#vbox + 1] = gui.HBox(line) vbox[#vbox + 1] = gui.HBox(line)
return vbox return vbox
end) end
function gui.Spacer(def)
def.type = "container"
if def.expand == nil then
def.expand = true
end
assert(#def == 0)
return def
end
-- Prevent any further modifications to the gui table
function gui_mt.__newindex()
error("Cannot modifiy gui table")
end
local modpath = minetest.get_modpath("flow") local modpath = minetest.get_modpath("flow")
local example_form local example_form