forked from your-land-mirror/minetest-flow
Add gui.Stack
This commit is contained in:
parent
8dd4d491a6
commit
a2fc646e77
20
README.md
20
README.md
@ -379,3 +379,23 @@ end)
|
||||
```
|
||||
|
||||

|
||||
|
||||
### `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"},
|
||||
}
|
||||
```
|
||||
|
||||

|
||||
|
44
init.lua
44
init.lua
@ -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]
|
||||
|
24
test.lua
24
test.lua
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user