grid layout finished,

minor fixes
This commit is contained in:
Elmārs Āboliņš 2021-06-15 23:55:49 +03:00
parent 5309f35dfc
commit 43e307295e
9 changed files with 266 additions and 33 deletions

View File

@ -1,5 +1,6 @@
local atlas = {}
atlas.__index = atlas
---@class atlases
local atlases ={}
atlases.__index = atlases
local BLOCK_SIZE = 5
@ -11,8 +12,8 @@ function atlases.create()
local self = {
atlases = {}
}
self.atlases[1] = atlas.new(sw, sh)
self.atlases[2] = atlas.new(sw, sh)
self.atlases[1] = atlas.new(sw*1.10, sh*1.10)
self.atlases[2] = atlas.new(sw*1.10, sh*1.10)
return setmetatable(self, atlases)
end
@ -80,7 +81,7 @@ function atlases:unassignAll()
self.atlases[2].taken_area = 0
end
function atlases:onscreenchange(newW, newH)
function atlases:onresize(newW, newH)
for i, e in ipairs(self.atlases[1].users) do
e:reassignCanvas()
end
@ -89,8 +90,8 @@ function atlases:onscreenchange(newW, newH)
e:reassignCanvas()
end
self.atlases[1] = atlas.new(newW, newH)
self.atlases[2] = atlas.new(newW, newH)
self.atlases[1] = atlas.new(newW*1.10, newH*1.10)
self.atlases[2] = atlas.new(newW*1.10, newH*1.10)
end
function atlas.new(w, h)
@ -246,9 +247,11 @@ end
function atlas:unassignElement(element)
local user = self.users[element]
if user then
self:unMarkTiles(user.x, user.y, user.w, user.h)
self.taken_area = self.taken_area - ((user.w*BLOCK_SIZE)*(user.h*BLOCK_SIZE))
self.users[element] = nil
end
end
return atlases

View File

@ -28,9 +28,10 @@ setmetatable(element, {
--Control functions
--The new function that should be used for element creation
function element:new(param, immediate, w, h)
function element:new(param, immediate, w, h, flags)
self.parameters = {}
self.baseParams = param
self.flags = flags or {}
--Internal state callbacks
self.callbacks = {}

View File

@ -80,6 +80,20 @@ function scene:draw()
end
function scene:resize(nw, nh)
if self.atlas then
self.atlas:onresize(nw, nh)
end
end
function scene:drawAtlases(x, y)
if self.atlas then
local aw = self.atlas.atlases[1].canvas:getWidth()
love.graphics.draw(self.atlas.atlases[1].canvas, x, y, 0, 0.5, 0.5)
love.graphics.draw(self.atlas.atlases[2].canvas, x+aw/2, y, 0, 0.5, 0.5)
end
end
---Updates this scene and it's elements
---@param dt number
function scene:update(dt)

View File

@ -36,8 +36,8 @@ setmetatable(helium, {__call = function(s, chunk)
draw = function (param, inputs, x, y, w, h)
end
},
{__call = function(s, param, w, h)
return helium.element(chunk, param, w, h)
{__call = function(s, param, w, h, flags)
return helium.element(chunk, param, w, h, flags)
end,})
end})

View File

@ -8,7 +8,7 @@ column.__index = column
function column.new()
local self = setmetatable({}, column)
return layout(self.draw)
return layout(self, self.draw)
end
function column:draw(x, y, width, height, children, hpad, vpad, alignX)

75
layout/container.lua Normal file
View File

@ -0,0 +1,75 @@
local path = string.sub(..., 1, string.len(...) - string.len(".container"))
local layout = require(path..'.init')
---@class Container
local container = {}
container.__index = container
---Positions an element within a container
---@param halign "'left'"|"'center'"|"'right'"|"'stretch'"
---@param valign "'top'"|"'center'"|"'bottom'"|"'stretch'"
---@return layout
function container.new(halign, valign)
local self = setmetatable({
halign = halign or 'left',
valign = valign or 'top',
}, container)
return layout(self, self.draw)
end
local function alignLeft(x, wroot, wchild)
return x
end
local function alignCenter(x, wroot, wchild)
return x+(wroot/2-wchild/2)
end
local function alignRight(x, wroot, wchild)
return x+(wroot-wchild)
end
local function alignHandlerX(mode, x, wr, wc)
if mode == 'center' then
return alignCenter(x, wr, wc)
elseif mode == 'right' then
return alignRight(x, wr, wc)
else
return alignLeft(x)
end
end
local function alignHandlerY(mode, y, hr, hc)
if mode == 'center' then
return alignCenter(y, hr, hc)
elseif mode == 'bottom' then
return alignRight(y, hr, hc)
else
return alignLeft(y)
end
end
function container:draw(x, y, width, height, children, hpad, vpad, alignX)
local w, h = children[1]:getSize()
local x, y
if self.halign =='stretch' then
w = width
x = x
else
x = alignHandlerX(self.halign, containerX, containerWidth, w)
end
if self.valign =='stretch' then
h = h
y = y
else
y = alignHandlerY(self.valign, containerY, containerHeight, h)
end
children[1]:draw(x, y, w, h)
end
return container

View File

@ -35,19 +35,18 @@ local layout = require(path..'.init')
---@type GridConfig
local preconfiguredGrid = {
colSpacing = 3,
rowSpacing = 3,
verticalStretchMode = 'normal',
horizontalStretchMode = 'normal',
colSpacing = 20,
rowSpacing = 20,
verticalStretchMode = 'stretch',
horizontalStretchMode = 'stretch',
verticalAlignMode = 'center',
horizontalAlignMode = 'center',
--rows = {1, 1, 1, 1},
columns = {1, 1, 1, 1},
--[[layout = {
{'header', 'header', 'header'},
{'sidebar','content','content'},
{'sidebar','content','content'},
}]]
rows = {5,5},
columns = {1,3,1},
layout = {
{'sidebar','content','sidebar2'},
{'sidebar','content','sidebar2'},
}
}
---@class grid
@ -99,7 +98,7 @@ local function alignHandlerY(mode, y, hr, hc)
end
end
function grid:draw(xRoot, yRoot, width, height, children, hpad, vpad)
function grid:draw(xRoot, yRoot, width, height, children)
-- Either of these means no named layout
local fullyAutoLayout = false
local autoCols = false
@ -110,7 +109,8 @@ function grid:draw(xRoot, yRoot, width, height, children, hpad, vpad)
local vertValueToPixels = 0
local horValueToPixels = 0
local finalLayout = {}
local XIndexes = {}
local YIndexes = {}
if self.gridLayout.columns then
if not self.gridLayout.rows then
@ -120,12 +120,23 @@ function grid:draw(xRoot, yRoot, width, height, children, hpad, vpad)
local total = 0
for i, col in ipairs(self.gridLayout.rows) do
YIndexes[i] = {}
YIndexes[i].start = total
total = total + col
YIndexes[i].finish = total
end
vertValueToPixels = (height-(self.gridLayout.rowSpacing*total))/total
vertValueToPixels = height/total
else
vertValueToPixels = (height-(self.gridLayout.rowSpacing*self.gridLayout.rows))/self.gridLayout.rows
vertValueToPixels = height/self.gridLayout.rows
for y = 1, self.gridLayout.rows do
YIndexes[y] = {}
YIndexes[y].start = y-1
YIndexes[y].finish = y
end
equalRows = true
end
end
@ -133,12 +144,23 @@ function grid:draw(xRoot, yRoot, width, height, children, hpad, vpad)
local total = 0
for i, col in ipairs(self.gridLayout.columns) do
XIndexes[i] = {}
XIndexes[i].start = total
total = total + col
XIndexes[i].finish = total
end
horValueToPixels = width/total
else
horValueToPixels = width/self.gridLayout.columns
for x = 1, self.gridLayout.columns do
XIndexes[x] = {}
XIndexes[x].start = x-1
XIndexes[x].finish = x
end
equalCols = true
end
else
@ -154,18 +176,131 @@ function grid:draw(xRoot, yRoot, width, height, children, hpad, vpad)
total = total + col
end
vertValueToPixels = (height-(self.gridLayout.rowSpacing*total))/total
vertValueToPixels = (height)/total
else
vertValueToPixels = (height-(self.gridLayout.rowSpacing*self.gridLayout.rows))/self.gridLayout.rows
vertValueToPixels = (height)/self.gridLayout.rows
equalRows = true
end
end
end
print(horValueToPixels, width)
if (not autoRows) and (not autoCols) then
if self.gridLayout.layout then
local layout = {}
--flip layout table
for x = 1, #self.gridLayout.layout[1] do
layout[x] = {}
end
for x = 1, #self.gridLayout.layout do
for y = 1, #self.gridLayout.layout[x] do
layout[y][x] = self.gridLayout.layout[x][y]
end
end
local layoutDepth, layoutWidth = #self.gridLayout.layout, #layout
if type(self.gridLayout.rows) == "table" then
if not #self.gridLayout.rows == layoutDepth then
error('Layout table doesnt match row number')
end
else
if not self.gridLayout.rows == layoutDepth then
error('Layout table doesnt match row number')
end
end
if type(self.gridLayout.columns) == "table" then
if not #self.gridLayout.columns == layoutWidth then
error('Layout table doesnt match column number')
end
else
if not self.gridLayout.columns == layoutWidth then
error('Layout table doesnt match column number')
end
end
-- {x, y, width, height}
local fields = {
}
for x = 1, #layout do
for y = 1, #layout[x] do
if not fields[layout[x][y]] then
local finishedRow = false
local finishedCol = false
local curField = layout[x][y]
fields[curField] = {}
fields[curField].x = XIndexes[x].start
fields[curField].y = YIndexes[y].start
fields[curField].finX = XIndexes[x].finish
fields[curField].finY = YIndexes[y].finish
local parseX, parseY = x+1, y+1
while not finishedRow do
if layout[x][parseY] and layout[x][parseY] == curField then
fields[curField].finY = YIndexes[parseY].finish
else
finishedRow = true
end
parseY = parseY + 1
end
while not finishedCol do
if layout[parseX] and layout[parseX][y] == curField then
fields[curField].finX = XIndexes[parseX].finish
else
finishedCol = true
end
parseX = parseX + 1
end
fields[curField].h = fields[curField].finY - fields[curField].y
fields[curField].w = fields[curField].finX - fields[curField].x
end
end
end
for i, field in pairs(fields) do
for y, elem in ipairs(children) do
if elem.flags[i] then
field.element = elem
end
end
end
for i, field in pairs(fields) do
if field.element then
local containerWidth = (field.w*horValueToPixels)-(self.gridLayout.colSpacing)
local containerHeight = (field.h*vertValueToPixels)-(self.gridLayout.rowSpacing)
local containerX = ((field.x)*horValueToPixels)+(self.gridLayout.colSpacing/2)
local containerY = ((field.y)*vertValueToPixels)+(self.gridLayout.rowSpacing/2)
local w, h = field.element:getSize()
local x, y
if self.gridLayout.horizontalStretchMode =='stretch' then
w = containerWidth
x = containerX
else
x = alignHandlerX(self.gridLayout.horizontalAlignMode, containerX, containerWidth, w)
end
if self.gridLayout.verticalStretchMode =='stretch' then
h = containerHeight
y = containerY
else
y = alignHandlerY(self.gridLayout.verticalAlignMode, containerY, containerHeight, h)
end
field.element:draw(x+xRoot, y+yRoot, w, h)
end
end
else
error('please provide a layout table')
end
elseif fullyAutoLayout then--one element per width, vertically down
local carriagePos = 0
if children then
@ -204,12 +339,14 @@ function grid:draw(xRoot, yRoot, width, height, children, hpad, vpad)
if self.gridLayout.horizontalStretchMode =='stretch' then
w = width
x = xRoot
else
x = alignHandlerX(self.gridLayout.horizontalAlignMode, xRoot, width, w)
end
if self.gridLayout.verticalStretchMode =='stretch' then
h = rowSize
y = carriagePos
else
y = alignHandlerY(self.gridLayout.verticalAlignMode, carriagePos, rowSize, h)
end
@ -254,6 +391,7 @@ function grid:draw(xRoot, yRoot, width, height, children, hpad, vpad)
if self.gridLayout.horizontalStretchMode =='stretch' then
w = colSize
x = colDrawStart
else
x = alignHandlerX(self.gridLayout.horizontalAlignMode, colDrawStart, colSize, w)
end

View File

@ -125,6 +125,7 @@ function layout:draw()
if self.vars.offTop and self.vars.offBot then
marginV = stack:normY(self.vars.offTop) + stack:normY(self.vars.offBot)
height = stack:normY(1) - marginV
y = self.vars.offTop
elseif self.vars.offTop then
y = stack:normY(self.vars.offTop)
height = math.min(stack:normY(self.vars.height), maxH-y)
@ -137,6 +138,7 @@ function layout:draw()
if self.vars.offLeft and self.vars.offRight then
marginH = stack:normX(self.vars.offLeft) + stack:normX(self.vars.offRight)
width = stack:normX(1) - marginH
x = self.vars.offLeft
elseif self.vars.offLeft then
x = stack:normX(self.vars.offLeft)
width = math.min(stack:normX(self.vars.width), maxW-x)
@ -150,5 +152,5 @@ function layout:draw()
end
setmetatable(layout, {__call = function(s, callback, binder) return layout.type(callback, binder) end })
setmetatable(layout, {__call = function(s, binder, callback) return layout.type(binder, callback) end })
return layout

View File

@ -9,7 +9,7 @@ row.__index = row
function row.new()
local self = setmetatable({}, row)
return layout(self.draw)
return layout(self, self.draw)
end
function row:draw(x, y, width, height, children, hpad, vpad, alignX)