From a2fc646e77ae29054e3004cf045f335faa2f61d8 Mon Sep 17 00:00:00 2001 From: luk3yx Date: Wed, 1 Feb 2023 18:08:58 +1300 Subject: [PATCH] Add gui.Stack --- README.md | 20 ++++++++++++++++++++ init.lua | 44 +++++++++++++++++++++++++++++++++----------- test.lua | 24 ++++++++++++++++++++++++ 3 files changed, 77 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 7389a21..882d6ba 100644 --- a/README.md +++ b/README.md @@ -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) diff --git a/init.lua b/init.lua index 9509c29..5e702d8 100644 --- a/init.lua +++ b/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] diff --git a/test.lua b/test.lua index fe11b78..8ad80ea 100644 --- a/test.lua +++ b/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)