compute_layout = function(node, x,y, nodes_to_render, font) --[[ --debug prints when modifying the DOM if node.type == 'rows' or node.type == 'cols' then print(node.type, node.button, #node.data) else print(node.type, node.button) end --]] -- append to nodes_to_render flattened instructions to render a hierarchy of nodes -- return x,y rendered until (surface coordinates) if node.type == 'text' then -- leaf node containing raw text node.x = x node.y = y -- render background if necessary local pending_nodes = {} if node.bg then local n = {type='rectangle', drawmode='fill', r=node.bg.r, g=node.bg.g, b=node.bg.b, x=node.x-5, y=node.y-5, rx=node.rx, ry=node.ry} table.insert(pending_nodes, n) table.insert(nodes_to_render, n) end -- render border if necessary if node.border then local n = {type='rectangle', drawmode='line', r=node.border.r, g=node.border.g, b=node.border.b, x=node.x-5, y=node.y-5, rx=node.rx, ry=node.ry} table.insert(pending_nodes, n) table.insert(nodes_to_render, n) end -- render contents if node.width then node.w = node.width else node.w = 0 for i,line in ipairs(node.data) do local width = love.graphics.getFont():getWidth(line.data)/Viewport.zoom if node.w < width then node.w = width end end end if node.editor == nil then initialize_editor(node) else update_editor_box(node, font) end node.h = box_height(node) table.insert(nodes_to_render, node) for _,n in ipairs(pending_nodes) do n.w = node.w+10 n.h = node.h+10 end elseif node.type == 'rows' then node.x = x node.y = y local node_to_render if node.bg then node_to_render = {type='rectangle', r=node.bg.r, g=node.bg.g, b=node.bg.b, x=node.x, y=node.y} table.insert(nodes_to_render, node_to_render) end -- lay out children top to bottom local subx,suby = x,y local w,h = 0,0 local subnodes for _,child in ipairs(node.data) do if child.margin then suby = suby+child.margin h = h+child.margin end if not child.width then child.width = node.width -- HACK: should we set child.w or child.width? Neither is quite satisfactory. end subx,suby = compute_layout(child, x,suby, nodes_to_render, font) if w < child.w then w = child.w end h = h+child.h end node.w = w node.h = h if node_to_render then node_to_render.w = w node_to_render.h = h end elseif node.type == 'cols' then node.x = x node.y = y -- lay out children left to right local node_to_render if node.bg then node_to_render = {type='rectangle', r=node.bg.r, g=node.bg.g, b=node.bg.b, x=node.x, y=node.y} table.insert(nodes_to_render, node_to_render) end local subx,suby = x,y local w,h = 0,0 for _,child in ipairs(node.data) do if child.margin then subx = subx+child.margin w = w+child.margin end subx,suby = compute_layout(child, subx,y, nodes_to_render, font) w = w + child.w if h < child.h then h = child.h end end node.w = w node.h = h if node_to_render then node_to_render.w = w node_to_render.h = h end end return x+node.w,y+node.h end