layout start

This commit is contained in:
Elmārs Āboliņš 2020-09-03 01:21:36 +03:00
parent 1a13369dae
commit b6e29a3ed7
9 changed files with 225 additions and 82 deletions

View File

@ -1,61 +0,0 @@
local path = string.sub(..., 1, string.len(...) - string.len(".core.layout"))
local layout = {}
layout.__index = layout
local element = require(path..'core.element')
local function layout_new(type, x, y, w, h)
local ctx = element.getContext()
--The output will be in pixel numbers regardless of inputs
if x <= 1 or not x then
x = ctx.view.x * (x or 0)
end
if y <= 1 then
y = ctx.view.y * (y or 0)
end
if w <= 1 then
w = ctx.view.w * (w or 1)
end
if h <= 1 then
h = ctx.view.h * (h or 1)
end
return setmetatable({
x = x,
y = y,
w = w,
h = h
}, layout)
end
--Sets mode for the proceding operations
function layout.mode()
end
--Sets padding for the next operations
function layout.pad()
end
--Sets margins for the proceding operations
function layout.margin()
end
function layout.offset()
end
function layout:draw()
end
layout(0,0,1,1)
return layout

View File

@ -20,7 +20,7 @@ end
function atlas.init() function atlas.init()
local w, h = love.graphics.getDimensions() local w, h = love.graphics.getDimensions()
createdAtlas = atlas.new(w, h/2) createdAtlas = atlas.new(w*2, h)
atlas.createdAtlas = createdAtlas atlas.createdAtlas = createdAtlas
end end
@ -28,12 +28,15 @@ function atlas.assign(element)
local elW = element.view.w local elW = element.view.w
local elH = element.view.h local elH = element.view.h
local canvas, quad = createdAtlas:assignElement(element) local canvas, quad = createdAtlas:assignElement(element)
if not canvas and createdAtlas.ideal_area > createdAtlas.taken_area*1.25 then if not canvas and createdAtlas.ideal_area < createdAtlas.taken_area*4 then
print('refragmenting ;3') print('refragmenting ;3')
createdAtlas:refragment() createdAtlas:refragment()
local canvas, quad = createdAtlas:assignElement(element) canvas, quad = createdAtlas:assignElement(element)
if not canvas then
print('ran out of space')
end
else else
print('wont refragment') print('wont refragment', createdAtlas.ideal_area, createdAtlas.taken_area)
end end
return canvas, quad return canvas, quad
end end
@ -109,8 +112,7 @@ function atlas:assignElement(element)
} }
self:markTiles(x, y, tileSizeX, tileSizeY) self:markTiles(x, y, tileSizeX, tileSizeY)
self.taken_area = self.taken_area + ((tileSizeY*BLOCK_SIZE)*(tileSizeX*BLOCK_SIZE))
self.taken_area = self.taken_area + tileSizeY*BLOCK_SIZE + tileSizeX*BLOCK_SIZE
return self.canvas, self.users[element].quad return self.canvas, self.users[element].quad
else else
@ -170,7 +172,7 @@ end
function atlas:find(sizeY, sizeX) function atlas:find(sizeY, sizeX)
local maxX, maxY = #self.tiles[1], #self.tiles local maxX, maxY = #self.tiles[1], #self.tiles
for y = 1, #self.tiles-sizeY+1 do for y = 1, #self.tiles-(sizeY+1) do
local skipUntilX=0 local skipUntilX=0
if self.tiles[y].empty > sizeY then if self.tiles[y].empty > sizeY then
for x = 1, #self.tiles[1]-sizeX do for x = 1, #self.tiles[1]-sizeX do

View File

@ -14,6 +14,7 @@ setmetatable(element, {
local self local self
local func, param, w, h = ... local func, param, w, h = ...
--Make the object inherit class
self = setmetatable({}, element) self = setmetatable({}, element)
self.parentFunc = func self.parentFunc = func
@ -66,10 +67,36 @@ function element:new(param, immediate, w, h)
minH = h or 10, minH = h or 10,
} }
self.view = self.baseView self.view = self.baseView
end end
function element:sizeChange()
end
function element:posChange()
end
function element:onUpdate()
end
function element:onDraw()
end
function element:onLoad()
end
function element:onDestroy()
end
function element:createProxies() function element:createProxies()
self.view = setmetatable({}, { self.view = setmetatable({}, {
__index = function(t, index) __index = function(t, index)
@ -78,6 +105,11 @@ function element:createProxies()
__newindex = function(t, index, val) __newindex = function(t, index, val)
if self.baseView[index] ~= val then if self.baseView[index] ~= val then
self.baseView[index] = val self.baseView[index] = val
if index=='w' or index=='h' then
self:sizeChange()
else
self:posChange()
end
self.context:bubbleUpdate() self.context:bubbleUpdate()
self:updateInputCtx() self:updateInputCtx()
end end
@ -104,7 +136,7 @@ end
local childrenNum = 5 local childrenNum = 5
local selfRenderTime = false local selfRenderTime = false
local screenSize = 1/4 local screenSize = 1/4
local coefficient = 1.50 local coefficient = 1.5
function element.setBench(time) function element.setBench(time)
selfRenderTime = time selfRenderTime = time
@ -115,7 +147,7 @@ function element:calculateCanvasCoeficient(selfTime)
local areaBelow = helium.atlas.getFreeArea() local areaBelow = helium.atlas.getFreeArea()
local area = self.view.h * self.view.w local area = self.view.h * self.view.w
local areaCoef = (1-helium.atlas.getRatio()) - (area/areaBelow) local areaCoef = (2-(helium.atlas.getRatio())) - (area/(areaBelow/(4+3*helium.atlas.getRatio())))
local childCoef = self.context:getChildrenCount()/childrenNum local childCoef = self.context:getChildrenCount()/childrenNum
local sizeCoef = selfTime/selfRenderTime local sizeCoef = selfTime/selfRenderTime
@ -128,6 +160,12 @@ function element:createCanvas()
self.settings.canvasH = self.view.h self.settings.canvasH = self.view.h
self.canvas, self.quad = helium.atlas.assign(self) self.canvas, self.quad = helium.atlas.assign(self)
if not self.canvas then
self.settings.failedCanvas = true
return
end
self.settings.hasCanvas = true
end end
function element:setParam(p) function element:setParam(p)
@ -278,7 +316,6 @@ function element:externalUpdate()
love.graphics.origin() love.graphics.origin()
self:createCanvas() self:createCanvas()
love.graphics.pop() love.graphics.pop()
self.settings.hasCanvas = true
self.settings.pendingUpdate = true self.settings.pendingUpdate = true
else else
self.settings.failedCanvas = true self.settings.failedCanvas = true
@ -307,18 +344,20 @@ function element:draw(x, y, w, h)
if h then self.view.h = self.view.minH<=h and h or self.view.minH end if h then self.view.h = self.view.minH<=h and h or self.view.minH end
end end
if self.settings.firstDraw then
self.settings.remove = false
self.settings.firstDraw = false
end
if context.getContext() then if context.getContext() then
if context.getContext().childRender(self) then
self:externalUpdate() self:externalUpdate()
self:externalRender() self:externalRender()
end
elseif not self.settings.inserted then elseif not self.settings.inserted then
self.settings.inserted = true self.settings.inserted = true
insert(helium.elementBuffer, self) insert(helium.elementBuffer, self)
end end
if self.settings.firstDraw then
self.settings.remove = false
self.settings.firstDraw = false
end
end end
function element:destroy() function element:destroy()

53
core/events.lua Normal file
View File

@ -0,0 +1,53 @@
local eventClass = {}
eventClass.__index = eventClass
function eventClass.new()
local self = {
eventSubs = {}
}
return setmetatable(self, eventClass)
end
function eventClass:sub(name, func)
local sub = { func = func }
self:provideQueue(name)
self.eventSubs[name][func] = func
return sub
end
function eventClass:push(name, event)
if self.eventSubs[name] then
table.insert(self.eventSubs[name].queue, event)
end
end
function eventClass:flush(name)
end
function eventClass:flushAll()
for i, subs in pairs(self.eventSubs) do
local assembledEvent = {}
for i, e in ipairs(subs.queue) do
end
end
end
function eventClass:provideQueue(name)
if not self.eventSubs[name] then
self.eventSubs[name] = {
queue = {}
}
end
end
function eventClass:unsub(name, event)
self.eventSubs[name][event] = nil
end
return eventClass

View File

@ -16,7 +16,9 @@ function context.new(elem)
element = elem, element = elem,
childrenContexts = {}, childrenContexts = {},
inputContext = helium.input.newContext(elem), inputContext = helium.input.newContext(elem),
childRenderTime = 0 childRenderTime = 0,
deferChildren = false,
capturedChilds = {},
}, context) }, context)
return ctx return ctx
@ -105,11 +107,29 @@ function context:getChildrenCount()
return #self.childrenContexts return #self.childrenContexts
end end
function context:startDeferingChildren()
self.deferChildren = true
self.capturedChilds = {}
end
function context:childRender(el)
if self.deferChildren then
self.capturedChilds[#self.capturedChilds+1] = el
return false
else
return true
end
end
function context:stopDeferingChildren()
self.deferChildren = false
return self.capturedChilds
end
--Function meant for external context capture --Function meant for external context capture
function context.getContext() function context.getContext()
return activeContext return activeContext
end end
return context return context

0
hooks/onPosChange.lua Normal file
View File

0
hooks/onSizeChange.lua Normal file
View File

View File

@ -43,10 +43,12 @@ function helium.draw()
--love.graphics.setScissor(500, 500, 1, 1) --love.graphics.setScissor(500, 500, 1, 1)
local startTime = love.timer.getTime() local startTime = love.timer.getTime()
for i = 1, 20 do for i = 1, 20 do
love.graphics.print(i,-100,-100) love.graphics.print(i,-100,-100)
end end
helium.element.setBench((love.timer.getTime()-startTime)/9)
helium.element.setBench((love.timer.getTime()-startTime)/5)
first = false first = false
--love.graphics.setScissor() --love.graphics.setScissor()

88
layout/init.lua Normal file
View File

@ -0,0 +1,88 @@
local path = string.sub(..., 1, string.len(...) - string.len(".core.layout"))
local layout = {}
layout.__index = layout
local element = require(path..'core.element')
local stack = require(path..'core.stack')
local function layout_new(type, x, y, w, h)
local ctx = element.getContext()
--The output will be in pixel numbers regardless of inputs
if x <= 1 or not x then
x = ctx.view.x * (x or 0)
end
if y <= 1 then
y = ctx.view.y * (y or 0)
end
if w <= 1 then
w = ctx.view.w * (w or 1)
end
if h <= 1 then
h = ctx.view.h * (h or 1)
end
return
end
layout(0,0,1,1)
--Start prep phase
function layout.type(type)
local self = {
vars = {
type = type or 'flow',
offLeft = 0,
offTop = 0,
width = 1,
height = 1,
alignX = 'left', --options: left, center, right
alignY = 'top', --options: top, center, bottom
flowDir = 'rtl' --options: rtl/ttb
}
}
return setmetatable(self, layout)
end
function layout:alignVert(pos)
self.vars.alignY = pos
end
function layout:alignHoriz(pos)
self.vars.alignX = pos
end
function layout:width(w)
self.vars.width = w
end
function layout:height(h)
self.vars.height = h
end
function layout:left(x)
self.vars.offTop = x
end
function layout:right(x)
self.vars.offRight = x
end
function layout:top(y)
self.vars.offTop = y
end
function layout:bottom(y)
self.vars.offBot = y
end
setmetatable(layout, {__call = function(s, type) return layout.type(type) end }
return layout