Add gui.Stack

This commit is contained in:
luk3yx 2023-02-01 18:08:58 +13:00
parent 8dd4d491a6
commit a2fc646e77
3 changed files with 77 additions and 11 deletions

View File

@ -379,3 +379,23 @@ end)
```
![Screenshot](https://user-images.githubusercontent.com/3182651/212222545-baee3669-15cd-410d-a638-c63b65a8811b.png)
### `gui.Stack`
This container element places its children on top of each other. All child
elements are expanded in both directions.
Note that some elements (such as centred labels and `gui.Box`) won't pass
clicks through to the element below them.
Example:
```lua
gui.Stack{
min_w = 10,
gui.Button{label = "Hello world!"},
gui.Image{w = 1, h = 1, texture_name = "air.png", padding = 0.2, align_h = "left"},
}
```
![Screenshot](https://user-images.githubusercontent.com/3182651/215946217-3705dbd1-4ec8-4aed-a9eb-381fecb2d8f2.png)

View File

@ -195,6 +195,19 @@ function size_getters.hbox(hbox)
return x, height
end
function size_getters.stack(stack)
local width, height = 0, 0
for _, node in ipairs(stack) do
if not invisible_elems[node.type] then
local w, h = apply_padding(node, 0, 0)
width = max(width, w)
height = max(height, h)
end
end
return width, height
end
function size_getters.padding(node)
minetest.log("warning", "[flow] The gui.Padding element is deprecated")
assert(#node == 1, "Padding can only have one element inside.")
@ -210,7 +223,7 @@ local align_types = {}
function align_types.fill(node, x, w, extra_space)
-- Special cases
if node.type == "list" or node.type == "checkbox" then
if node.type == "list" or node.type == "checkbox" or node._label_hack then
return align_types.centre(node, x, w, extra_space)
elseif node.type == "label" then
if x == "y" then
@ -241,6 +254,7 @@ function align_types.fill(node, x, w, extra_space)
node.y = node.y - LABEL_OFFSET
node.label = nil
node._label_hack = true
assert(#node == 2)
end
node[w] = node[w] + extra_space
@ -286,24 +300,25 @@ function align_types.auto(node, x, w, extra_space, cross)
end
end
local expand_child_boxes
local function expand(box)
local x, w, align_h, y, h, align_v
if box.type == "hbox" then
local box_type = box.type
if box_type == "hbox" then
x, w, align_h, y, h, align_v = "x", "w", "align_h", "y", "h", "align_v"
elseif box.type == "vbox" then
elseif box_type == "vbox" then
x, w, align_h, y, h, align_v = "y", "h", "align_v", "x", "w", "align_h"
elseif box.type == "padding" then
elseif box_type == "stack" or
(box_type == "padding" and box[1].expand) then
box.type = "container"
local node = box[1]
if node.expand then
for _, node in ipairs(box) do
align_types[node.align_h or "auto"](node, "x", "w", box.w -
node.w - ((node.padding or 0) + (box.padding or 0)) * 2)
node.w - (node.padding or 0) * 2)
align_types[node.align_v or "auto"](node, "y", "h", box.h -
node.h - ((node.padding or 0) + (box.padding or 0)) * 2 -
(node._padding_top or 0) - (box._padding_top or 0))
node.h - (node.padding or 0) * 2 - (node._padding_top or 0))
end
return expand(node)
elseif box.type == "container" or box.type == "scroll_container" then
return expand_child_boxes(box)
elseif box_type == "container" or box_type == "scroll_container" then
for _, node in ipairs(box) do
if node.x == 0 and node.expand and box.w then
node.w = box.w
@ -311,6 +326,9 @@ local function expand(box)
expand(node)
end
return
elseif box_type == "padding" then
box.type = "container"
return expand_child_boxes(box)
else
return
end
@ -381,6 +399,10 @@ local function expand(box)
end
end
expand_child_boxes(box)
end
function expand_child_boxes(box)
-- Recursively expand and remove any invisible nodes
for i = #box, 1, -1 do
local node = box[i]

View File

@ -228,4 +228,28 @@ describe("Flow", function()
box[0.3,5.1;10,5.2;]
]])
end)
it("stacks elements", function()
test_render(gui.Stack{
gui.Button{w = 3, h = 1, label = "1", align_v = "top"},
gui.Image{w = 1, h = 1, align_h = "fill", align_v = "fill",
texture_name = "2"},
gui.Image{w = 1, h = 3, texture_name = "3", visible = false},
gui.Field{name = "4", label = "Test", align_v = "fill"},
gui.Field{name = "5", label = "", align_v = "fill"},
gui.Label{label = "Test", align_h = "centre"},
}, [[
size[3.6,3.6]
field_close_on_enter[4;false]
field_close_on_enter[5;false]
button[0.3,0.3;3,1;;1]
image[0.3,0.3;3,3;2]
field[0.3,0.7;3,2.6;4;Test;]
field[0.3,0.3;3,3;5;;]
image_button[0.3,1.6;3,0.4;blank.png;;Test;;false]
image_button[0.3,1.6;3,0.4;blank.png;;;;false]
]])
end)
end)