layout = {} uiState = {} local debugPrint = function(string) --print(string) end function layout.canvasAndColor(container, x, y, simulate) if simulate then return layout.handle(container[1], x, y, simulate) end color_push() love.graphics.setCanvas(container.canvas) x, y = layout.handle(container[1], x, y, simulate) love.graphics.setCanvas() color_pop() return x, y end function layout.rotate(container, x, y, simulate) assert_num("layout.rotate", 2, x, y) assert_num("layout.rotate (container)", container.rotation) local transform = love.math.newTransform(0, 0, container.rotation) local noTransform = love.math.newTransform(0, 0, 0) love.graphics.replaceTransform(transform) local x, y = layout.handle(container[1], x, y, simulate) love.graphics.replaceTransform(noTransform) return x, y end function layout.frame(container, x, y, simulate) assert_num("layout.frame", 2, x, y) x2, y2 = layout.handle(container[1], x +1, y +1, simulate) if not simulate then love.graphics.rectangle("line", x, y, x2 -x, y2 -y) end return x2+1, y2+1 end function layout.cursorSelect(container, x, y, simulate) x2, y2 = layout.handle(container[1], x, y, simulate) if not simulate then table.insert(uiState, { identifier = container.identifier, kind=container.kind, x=x, x2=x2, y=y, y2=y2 }) end return x2, y2 end function layout.linewidth(container, x, y, simulate) if simulate then return layout.handle(container[1], x, y, simulate) end assert(container.width, "layout.linewidth (container) no container.width provided!") local oldWidth = love.graphics.getLineWidth() love.graphics.setLineWidth(container.width) x, y = layout.handle(container[1], x, y, simulate) love.graphics.setLineWidth(oldWidth) return x, y end function layout.spacer(container, x, y, simulate) assert(container.width or container.height, "No arguments for layout.spacer!") assert(container.width == container.width, "Argument container.width to layout.spacer must not be NaN!") assert(container.height == container.height, "Argument container.height to layout.spacer must not be NaN!") local width = container.width or 0 local height = container.height or 0 if container[1] then return layout.handle(container[1], x + width, y + height, simulate) else return x + width, y + height end end function layout.drawTexture(container, x, y, simulate) local texture = container.texture local scale = container.scale or 1 if not simulate then love.graphics.draw(texture, x, y, 0, scale, scale) end return x + texture:getWidth()* scale, y + texture:getHeight() * scale end function layout.drawHash(container, x, y, simulate) local texture = gameloop.textures[container.hash] local scale = container.scale or 1 if not texture.image then texture.image = love.graphics.newImage(texture.data) end if not simulate then love.graphics.draw(texture.image, x, y, 0, scale, scale) end return x + texture.image:getWidth() * scale, y + texture.image:getHeight() * scale end function layout.colorPicker(container, x, y, simulate) assert(x and y) local startx, starty = x, y granularity = container.granularity or 0.2 local points = {} local myx, myy = x, y local endx = 0 local pointsize = 16 if not simulate then color_push() love.graphics.setPointSize(pointsize) for r=0, 1.0, granularity do for g=0, 1.0, granularity do for b=0, 1.0, granularity do love.graphics.setColor(r, g, b, 1) myx=myx+16 love.graphics.points(myx-4.5, myy+4.5) end end myy = myy + 16 if myx > endx then endx = myx end myx = x end color_pop() local iterationCount = (1.0 / granularity) + 1 maxx = x + pointsize * iterationCount * iterationCount table.insert(uiState, { granularity = granularity, pointsize = pointsize, kind=container.kind, x=x, x2=maxx, y=y, y2=myy }) else local iterationCount = (1.0 / granularity) + 1 maxx = x + pointsize * iterationCount * iterationCount maxy = y + pointsize * iterationCount end return maxx, myy end function layout.color(container, x, y, simulate) if simulate then return layout.handle(container[1], x, y, simulate) end assert(#container.color == 3 or #container.color == 4) color_push() love.graphics.setColor(container.color) x, y = layout.handle(container[1], x, y, simulate) color_pop() return x, y end function layout.rect(container, x, y, simulate) assert_num("layout.rect", 2, x, y) assert_num("layout.rect (container)", 2, container.width, container.height) if not simulate then if container.color then color_push() love.graphics.setColor(container.color.r, container.color.g, container.color.b, container.color.a or 1) love.graphics.rectangle(container.fill or "fill", x, y, container.width, container.height) color_pop() else love.graphics.rectangle(container.fill or "fill", x, y, container.width, container.height) end end return x + container.width, y + container.height end function layout.overlayRect(container, x, y, simulate) assert_num("layout.overlayRect", 2, x, y) winx, winy = layout.handle(container[1], x, y, simulate) width = winx -x height = winy -y if not simulate then love.graphics.rectangle(container.fill or "fill", x, y, width, height) end return x + width, y + height end function layout.label(container, x, y, simulate) if not container.font then container.font = ui.font end local text = love.graphics.newText( container.font, container.text ) if not text then text = "Unset text!!" end if not simulate then love.graphics.draw(text, x, y) end return x + text:getWidth(), y + text:getHeight() end function layout.layer(container, x, y, simulate) local ret1 = {} local ret2 = {} ret1.x, ret1.y = layout.handle(container[1], x, y, simulate) ret2.x, ret2.y = layout.handle(container[2], x, y, simulate) return math.max(ret1.x,ret2.x), math.max(ret1.y, ret2.y) end function layout.horizontal(container, x, y, simulate) local bigy = y if not simulate then assert(container[1], "horizontal called without arguments!") else if not container[1] then return x, y end end for i, v in ipairs(container) do local ret = {} ret.x, ret.y = layout.handle(v,x,y, simulate) if ret.y > bigy then bigy = ret.y end x = ret.x end return x,bigy end function layout.copySize(container, x, y, simulate) local bigx, bigy = layout.handle(container[2], x, y, true) container[1].width = bigx -x container[1].height = bigy -y assert(container[1]) assert(container[2]) layout.handle(container[1], x, y, simulate) layout.handle(container[2], x, y, simulate) return bigx, bigy end function layout.vertical(container, x, y, simulate) local bigx = x if not simulate then assert(container[1], "vertical called without arguments!") else if not container[1] then return x, y end end for i, v in ipairs(container) do local ret = {} ret.x, ret.y = layout.handle(v,x,y, simulate) if ret.x > bigx then bigx = ret.x end y = ret.y end return bigx,y end local depth = -1 function layout.handle(container, x, y, simulate) assert_num("layout.handle", 2, x, y) assert(container, "layout.handle called without container") local name = container["name"] assert(name, "layout.handle container without name") assert(layout[name], "Unknown layout function " .. name .. " called") depth = depth +1 local depthCursor = "" for i=0, depth do depthCursor = depthCursor .. ".." end if depth == 0 then if simulate then debugPrint("Starting simulation") else debugPrint("Starting rendering") end end debugPrint(depthCursor.. ">" .. container.name) x, y = layout[name](container, x, y, simulate) assert_num("layout.handle" .. container.name .. " is not returning properly!", 2, x, y) debugPrint(depthCursor.."<" .. container.name) depth = depth -1 if depth == -1 then if simulate then debugPrint("simulation ended\n") else debugPrint("rendering ended\n") end end return x, y end