big chungus commit
This commit is contained in:
parent
b6e29a3ed7
commit
a200960ad1
@ -29,14 +29,14 @@ function atlas.assign(element)
|
|||||||
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*4 then
|
if not canvas and createdAtlas.ideal_area < createdAtlas.taken_area*4 then
|
||||||
print('refragmenting ;3')
|
--print('refragmenting ;3')
|
||||||
createdAtlas:refragment()
|
createdAtlas:refragment()
|
||||||
canvas, quad = createdAtlas:assignElement(element)
|
canvas, quad = createdAtlas:assignElement(element)
|
||||||
if not canvas then
|
if not canvas then
|
||||||
print('ran out of space')
|
--print('ran out of space')
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
print('wont refragment', createdAtlas.ideal_area, createdAtlas.taken_area)
|
--print('wont refragment', createdAtlas.ideal_area, createdAtlas.taken_area)
|
||||||
end
|
end
|
||||||
return canvas, quad
|
return canvas, quad
|
||||||
end
|
end
|
||||||
@ -206,6 +206,7 @@ end
|
|||||||
function atlas:unassignElement(element)
|
function atlas:unassignElement(element)
|
||||||
local user = self.users[element]
|
local user = self.users[element]
|
||||||
self:unMarkTiles(user.x, user.y, user.w, user.h)
|
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
|
self.users[element] = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
137
core/element.lua
137
core/element.lua
@ -19,7 +19,7 @@ setmetatable(element, {
|
|||||||
self.parentFunc = func
|
self.parentFunc = func
|
||||||
|
|
||||||
self:new(param,nil, w, h)
|
self:new(param,nil, w, h)
|
||||||
self:createProxies(param)
|
self:createProxies()
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
@ -29,7 +29,6 @@ setmetatable(element, {
|
|||||||
--The new function that should be used for element creation
|
--The new function that should be used for element creation
|
||||||
function element:new(param, immediate, w, h)
|
function element:new(param, immediate, w, h)
|
||||||
self.parameters = {}
|
self.parameters = {}
|
||||||
|
|
||||||
self.baseParams = param
|
self.baseParams = param
|
||||||
|
|
||||||
--Internal settings
|
--Internal settings
|
||||||
@ -57,28 +56,48 @@ function element:new(param, immediate, w, h)
|
|||||||
self.renderBench = {
|
self.renderBench = {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self.baseView = {
|
self.baseView = {
|
||||||
x = 0,
|
x = 0,
|
||||||
y = 0,
|
y = 0,
|
||||||
w = w or 10,
|
w = w or 10,
|
||||||
h = h or 10,
|
h = h or 10,
|
||||||
minW = w or 10,
|
minW = w or 0,
|
||||||
minH = h or 10,
|
minH = h or 0,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.size = setmetatable({}, {__index = function(t, index)
|
||||||
|
return self.baseView[index]
|
||||||
|
end,})
|
||||||
|
|
||||||
self.view = self.baseView
|
self.view = self.baseView
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function element:sizeChange()
|
function element:sizeChange(i, v)
|
||||||
|
local increase = self.baseView[i] < v
|
||||||
|
|
||||||
|
if i == 'w' then
|
||||||
|
self.baseView.w = math.max(self.baseView.minW, v)
|
||||||
|
else
|
||||||
|
self.baseView.h = math.max(self.baseView.minH, v)
|
||||||
|
end
|
||||||
|
|
||||||
|
--defer resize
|
||||||
|
if self.deferResize then
|
||||||
|
if not self.deferResize.increased then
|
||||||
|
self.deferResize.increased = increase
|
||||||
|
end
|
||||||
|
else
|
||||||
|
self.deferResize = { increased = increase }
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function element:posChange()
|
function element:posChange(i, v)
|
||||||
|
self.baseView[i] = v
|
||||||
|
--defer resize
|
||||||
|
|
||||||
|
if not self.deferRepos then
|
||||||
|
self.deferRepos = true
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function element:onUpdate()
|
function element:onUpdate()
|
||||||
@ -104,14 +123,12 @@ function element:createProxies()
|
|||||||
end,
|
end,
|
||||||
__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
|
|
||||||
if index=='w' or index=='h' then
|
if index=='w' or index=='h' then
|
||||||
self:sizeChange()
|
self:sizeChange(index, val)
|
||||||
else
|
else
|
||||||
self:posChange()
|
self:posChange(index, val)
|
||||||
end
|
end
|
||||||
self.context:bubbleUpdate()
|
self.context:bubbleUpdate()
|
||||||
self:updateInputCtx()
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
})
|
})
|
||||||
@ -142,14 +159,22 @@ function element.setBench(time)
|
|||||||
selfRenderTime = time
|
selfRenderTime = time
|
||||||
end
|
end
|
||||||
|
|
||||||
function element:calculateCanvasCoeficient(selfTime)
|
function element:calculateCanvasCoeficient()
|
||||||
|
local avg, sum = 0, 0
|
||||||
|
|
||||||
|
for i, e in ipairs(self.renderBench) do
|
||||||
|
sum = sum + e
|
||||||
|
end
|
||||||
|
|
||||||
|
avg = sum/#self.renderBench
|
||||||
|
|
||||||
local sW, sH = love.graphics.getDimensions()
|
local sW, sH = love.graphics.getDimensions()
|
||||||
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 = (2-(helium.atlas.getRatio())) - (area/(areaBelow/(4+3*helium.atlas.getRatio())))
|
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 = avg/selfRenderTime
|
||||||
|
|
||||||
return (areaCoef+childCoef+sizeCoef)>coefficient
|
return (areaCoef+childCoef+sizeCoef)>coefficient
|
||||||
end
|
end
|
||||||
@ -163,6 +188,7 @@ function element:createCanvas()
|
|||||||
|
|
||||||
if not self.canvas then
|
if not self.canvas then
|
||||||
self.settings.failedCanvas = true
|
self.settings.failedCanvas = true
|
||||||
|
self.settings.hasCanvas = false
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
self.settings.hasCanvas = true
|
self.settings.hasCanvas = true
|
||||||
@ -180,27 +206,6 @@ function element:setCalculatedSize(w, h)
|
|||||||
self.view.h = math.max(self.view.minH, self.view.h)
|
self.view.h = math.max(self.view.minH, self.view.h)
|
||||||
end
|
end
|
||||||
|
|
||||||
function element:updateInputCtx()
|
|
||||||
self.context.inputContext:update()
|
|
||||||
--[[if self.settings.canvasW then
|
|
||||||
--If canvas too small make a bigger one
|
|
||||||
if self.settings.canvasW < self.view.w or self.settings.canvasH < self.view.h then
|
|
||||||
self.settings.canvasW = self.view.w*1.25
|
|
||||||
self.settings.canvasH = self.view.h*1.25
|
|
||||||
|
|
||||||
self.canvas = love.graphics.newCanvas(self.view.w*1.25, self.view.h*1.25)
|
|
||||||
--If canvas too big make a smaller one
|
|
||||||
elseif self.settings.canvasW > self.view.w*1.50 or self.settings.canvasH > self.view.h*1.50 then
|
|
||||||
self.settings.canvasW = self.view.w*1.25
|
|
||||||
self.settings.canvasH = self.view.h*1.25
|
|
||||||
|
|
||||||
self.canvas = love.graphics.newCanvas(self.view.w*1.25, self.view.h*1.25)
|
|
||||||
end
|
|
||||||
|
|
||||||
self.quad = love.graphics.newQuad(0, 0, self.view.w, self.view.h, self.settings.canvasW, self.settings.canvasH)
|
|
||||||
end]]
|
|
||||||
end
|
|
||||||
|
|
||||||
local dummy = function() end
|
local dummy = function() end
|
||||||
--Immediate mode code(don't call directly)
|
--Immediate mode code(don't call directly)
|
||||||
function element.immediate(param, func, x, y, w, h)
|
function element.immediate(param, func, x, y, w, h)
|
||||||
@ -209,7 +214,7 @@ function element.immediate(param, func, x, y, w, h)
|
|||||||
local ctx = context.getContext()
|
local ctx = context.getContext()
|
||||||
if ctx then
|
if ctx then
|
||||||
local self = setmetatable({}, element)
|
local self = setmetatable({}, element)
|
||||||
self = element:new(param, true)
|
self = self:new(param, true)
|
||||||
else
|
else
|
||||||
error("Can't render immediate outside of persistent")
|
error("Can't render immediate outside of persistent")
|
||||||
end
|
end
|
||||||
@ -218,7 +223,7 @@ end
|
|||||||
--Called once dimensions are validated
|
--Called once dimensions are validated
|
||||||
function element:setup()
|
function element:setup()
|
||||||
self.context:set()
|
self.context:set()
|
||||||
self.renderer = self.parentFunc(self.parameters, self.view.w, self.view.h)
|
self.renderer = self.parentFunc(self.parameters, self.size)
|
||||||
self.context:unset()
|
self.context:unset()
|
||||||
|
|
||||||
self.settings.isSetup = true
|
self.settings.isSetup = true
|
||||||
@ -302,20 +307,12 @@ function element:externalRender()
|
|||||||
end
|
end
|
||||||
|
|
||||||
function element:externalUpdate()
|
function element:externalUpdate()
|
||||||
|
self.context:zIndex()
|
||||||
if not self.settings.failedCanvas and self.settings.testRenderPasses == 0 and not self.settings.hasCanvas then
|
if not self.settings.failedCanvas and self.settings.testRenderPasses == 0 and not self.settings.hasCanvas then
|
||||||
local avg, sum = 0, 0
|
|
||||||
|
|
||||||
for i, e in ipairs(self.renderBench) do
|
if self:calculateCanvasCoeficient() then
|
||||||
sum = sum + e
|
|
||||||
end
|
|
||||||
|
|
||||||
avg = sum/#self.renderBench
|
|
||||||
|
|
||||||
if self:calculateCanvasCoeficient(avg) then
|
|
||||||
love.graphics.push()
|
|
||||||
love.graphics.origin()
|
|
||||||
self:createCanvas()
|
self:createCanvas()
|
||||||
love.graphics.pop()
|
|
||||||
self.settings.pendingUpdate = true
|
self.settings.pendingUpdate = true
|
||||||
else
|
else
|
||||||
self.settings.failedCanvas = true
|
self.settings.failedCanvas = true
|
||||||
@ -327,6 +324,27 @@ function element:externalUpdate()
|
|||||||
self.settings.pendingUpdate = false
|
self.settings.pendingUpdate = false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if self.deferResize then
|
||||||
|
self.context:sizeChanged()
|
||||||
|
if self.settings.hasCanvas then
|
||||||
|
helium.atlas.unassign(self)
|
||||||
|
|
||||||
|
if self:calculateCanvasCoeficient() then
|
||||||
|
self:createCanvas()
|
||||||
|
else
|
||||||
|
self.settings.hasCanvas = false
|
||||||
|
self.canvas = nil
|
||||||
|
self.quad = nil
|
||||||
|
self.deferResize = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if self.deferRepos then
|
||||||
|
self.context:posChanged()
|
||||||
|
self.deferRepos = false
|
||||||
|
end
|
||||||
|
|
||||||
return self.settings.remove
|
return self.settings.remove
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -337,21 +355,20 @@ local insert = table.insert
|
|||||||
---@param x number
|
---@param x number
|
||||||
---@param y number
|
---@param y number
|
||||||
function element:draw(x, y, w, h)
|
function element:draw(x, y, w, h)
|
||||||
if not self.view.lock then
|
|
||||||
if x then self.view.x = x end
|
if x then self.view.x = x end
|
||||||
if y then self.view.y = y end
|
if y then self.view.y = y end
|
||||||
if w then self.view.w = self.view.minW<=w and w or self.view.minW end
|
if w then self.view.w = w end
|
||||||
if h then self.view.h = self.view.minH<=h and h or self.view.minH end
|
if h then self.view.h = h end
|
||||||
end
|
|
||||||
|
|
||||||
if context.getContext() then
|
local cx = context.getContext()
|
||||||
if context.getContext().childRender(self) then
|
if cx then
|
||||||
|
if cx:childRender(self) then
|
||||||
self:externalUpdate()
|
self:externalUpdate()
|
||||||
self:externalRender()
|
self:externalRender()
|
||||||
end
|
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.elementInsertionQueue, self)
|
||||||
end
|
end
|
||||||
|
|
||||||
if self.settings.firstDraw then
|
if self.settings.firstDraw then
|
||||||
@ -360,6 +377,10 @@ function element:draw(x, y, w, h)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function element:getSize()
|
||||||
|
return self.view.w, self.view.h
|
||||||
|
end
|
||||||
|
|
||||||
function element:destroy()
|
function element:destroy()
|
||||||
self.settings.remove = true
|
self.settings.remove = true
|
||||||
self.settings.firstDraw = true
|
self.settings.firstDraw = true
|
||||||
|
|||||||
@ -9,45 +9,31 @@ function eventClass.new()
|
|||||||
return setmetatable(self, eventClass)
|
return setmetatable(self, eventClass)
|
||||||
end
|
end
|
||||||
|
|
||||||
function eventClass:sub(name, func)
|
function eventClass:newQueue(name)
|
||||||
local sub = { func = func }
|
self.eventSubs[name] = {}
|
||||||
|
|
||||||
self:provideQueue(name)
|
|
||||||
self.eventSubs[name][func] = func
|
|
||||||
|
|
||||||
return sub
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function eventClass:push(name, event)
|
--Data is the individualized table to pass to each subscriber (or middleware)
|
||||||
if self.eventSubs[name] then
|
function eventClass:sub(name, func, data)
|
||||||
table.insert(self.eventSubs[name].queue, event)
|
self.eventSubs[name][func] = {func = func, data = data}
|
||||||
|
|
||||||
|
return func
|
||||||
|
end
|
||||||
|
|
||||||
|
function eventClass:unsub(name, func)
|
||||||
|
self.eventSubs[name][func] = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
function eventClass:push(name, evntData)
|
||||||
|
local pushData = evntData
|
||||||
|
for i, e in pairs(self.eventSubs[name]) do
|
||||||
|
if self.eventSubs[name].beforeEach then
|
||||||
|
pushData = self.eventSubs[name].beforeEach(e.data, evntData) or evntData
|
||||||
|
end
|
||||||
|
|
||||||
|
e.func(pushData)
|
||||||
end
|
end
|
||||||
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
|
return eventClass
|
||||||
386
core/input.lua
386
core/input.lua
@ -1,47 +1,29 @@
|
|||||||
local path = string.sub(..., 1, string.len(...) - string.len(".core.input"))
|
local path = string.sub(..., 1, string.len(...) - string.len(".core.input"))
|
||||||
local helium = require(path .. ".dummy")
|
local stack = require(path .. ".core.stack")
|
||||||
|
|
||||||
local input={
|
local input = {
|
||||||
eventHandlers = {},
|
eventHandlers = {},
|
||||||
subscriptions = {},
|
subscriptions = {},
|
||||||
activeEvents = {}
|
activeEvents = {}
|
||||||
}
|
}
|
||||||
input.__index = input
|
input.__index = input
|
||||||
|
|
||||||
local windowMachine = {}
|
local function sortFunc(t1, t2)
|
||||||
windowMachine.__index = windowMachine
|
if t1.stack.temporalZ.z == t2.stack.temporalZ.z then
|
||||||
local windowCurrent = false
|
print('same Z ???',t1.stack.temporalZ.z, t2.stack.temporalZ.z)
|
||||||
|
|
||||||
--Go forward
|
|
||||||
windowMachine.push = function(window)
|
|
||||||
windowMachine[#windowMachine+1] = window
|
|
||||||
windowCurrent = #windowMachine
|
|
||||||
end
|
|
||||||
|
|
||||||
--Go a level back
|
|
||||||
windowMachine.pop = function()
|
|
||||||
windowMachine[#windowMachine] = nil
|
|
||||||
if windowCurrent>1 then
|
|
||||||
windowCurrent = windowCurrent-1
|
|
||||||
else
|
|
||||||
windowCurrent = false
|
|
||||||
end
|
end
|
||||||
end
|
if t1 == t2 then
|
||||||
|
print(tostring(t1), tostring(t2))
|
||||||
windowMachine.get = function()
|
return false
|
||||||
if windowCurrent then
|
|
||||||
return windowMachine[windowCurrent]
|
|
||||||
end
|
end
|
||||||
|
return t1.stack.temporalZ.z > t2.stack.temporalZ.z
|
||||||
end
|
end
|
||||||
|
|
||||||
local activeWindow
|
function input.sortZ()
|
||||||
local windowStack = {}
|
for i, subs in pairs(input.subscriptions) do
|
||||||
|
table.sort(subs, sortFunc)
|
||||||
function input.unload()
|
print(#subs)
|
||||||
windowStack = {}
|
end
|
||||||
activeWindow = nil
|
|
||||||
windowMachine = {}
|
|
||||||
input.subscriptions = {}
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local dummyfunc = function() end
|
local dummyfunc = function() end
|
||||||
@ -49,11 +31,10 @@ local dummyfunc = function() end
|
|||||||
local subscription = {}
|
local subscription = {}
|
||||||
subscription.__index = subscription
|
subscription.__index = subscription
|
||||||
|
|
||||||
---@class inputContext
|
function input.unload()
|
||||||
local context = {}
|
input.subscriptions = {}
|
||||||
context.__index = context
|
input.activeEvents = {}
|
||||||
|
end
|
||||||
local activeContext
|
|
||||||
|
|
||||||
--[[Event types
|
--[[Event types
|
||||||
###SIMPLE EVENTS###
|
###SIMPLE EVENTS###
|
||||||
@ -73,80 +54,6 @@ local activeContext
|
|||||||
|
|
||||||
|
|
||||||
]]
|
]]
|
||||||
function input.newContext(element)
|
|
||||||
local ctx = setmetatable({elem = element, subs = {}, childContexts={}}, context)
|
|
||||||
|
|
||||||
return ctx
|
|
||||||
end
|
|
||||||
|
|
||||||
function context:set()
|
|
||||||
self.activeWindow = windowMachine.get()
|
|
||||||
|
|
||||||
if activeContext and activeContext~=self then
|
|
||||||
if not self.parentCtx then
|
|
||||||
activeContext.childContexts[#activeContext.childContexts+1] = self
|
|
||||||
self.parentCtx = activeContext
|
|
||||||
end
|
|
||||||
self.absX = self.parentCtx.absX + self.elem.view.x
|
|
||||||
self.absY = self.parentCtx.absY + self.elem.view.y
|
|
||||||
activeContext = self
|
|
||||||
else
|
|
||||||
self.absX = self.elem.view.x
|
|
||||||
self.absY = self.elem.view.y
|
|
||||||
activeContext = self
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function context:update()
|
|
||||||
if self.parentCtx then
|
|
||||||
self.absX = self.parentCtx.absX + self.elem.view.x
|
|
||||||
self.absY = self.parentCtx.absY + self.elem.view.y
|
|
||||||
else
|
|
||||||
self.absX = self.elem.view.x
|
|
||||||
self.absY = self.elem.view.y
|
|
||||||
end
|
|
||||||
for i, e in ipairs(self.childContexts) do
|
|
||||||
e:update()
|
|
||||||
end
|
|
||||||
for i, sub in ipairs(self.subs) do
|
|
||||||
sub:contextUpdate(self.absX,self.absY,self)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function context:unset()
|
|
||||||
if self.parentCtx then
|
|
||||||
activeContext = self.parentCtx
|
|
||||||
else
|
|
||||||
activeContext = nil
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
function context:afterLoad()
|
|
||||||
--If i created window, pop it
|
|
||||||
if self.window then
|
|
||||||
windowMachine.pop()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function context:unsuspend()
|
|
||||||
for i, e in ipairs(self.subs) do
|
|
||||||
e:unsuspend()
|
|
||||||
end
|
|
||||||
for i, e in ipairs(self.childContexts) do
|
|
||||||
e:unsuspend()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function context:suspend()
|
|
||||||
for i, e in ipairs(self.subs) do
|
|
||||||
e:suspend()
|
|
||||||
end
|
|
||||||
for i, e in ipairs(self.childContexts) do
|
|
||||||
e:suspend()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
---@param x number
|
---@param x number
|
||||||
---@param y number
|
---@param y number
|
||||||
---@param w number
|
---@param w number
|
||||||
@ -156,70 +63,45 @@ end
|
|||||||
---@param doff boolean
|
---@param doff boolean
|
||||||
---@return subscription
|
---@return subscription
|
||||||
function subscription.create(x, y, w, h, eventType, callback, doff)
|
function subscription.create(x, y, w, h, eventType, callback, doff)
|
||||||
local sub
|
local stack = stack.getContext()
|
||||||
if activeContext then
|
local xn, yn = stack:normalizePos(x, y)
|
||||||
local wratio,hratio,xratio,yratio
|
local wn, hn = stack:normalizeSize(w, h)
|
||||||
if x<=1 and x~=0 then
|
|
||||||
xratio = x
|
|
||||||
x = activeContext.elem.view.w * x
|
|
||||||
end
|
|
||||||
|
|
||||||
if y<=1 and y~=0 then
|
local sub = setmetatable({
|
||||||
yratio = y
|
x = xn,
|
||||||
y = activeContext.elem.view.h * y
|
y = yn,
|
||||||
end
|
w = wn,
|
||||||
|
h = hn,
|
||||||
if w<=1 and w~=0 then
|
origX = x,
|
||||||
wratio = w
|
origY = y,
|
||||||
w = activeContext.elem.view.w * w
|
origW = w,
|
||||||
end
|
origH = h,
|
||||||
|
|
||||||
if h<=1 and h~=0 then
|
|
||||||
hratio = h
|
|
||||||
h = activeContext.elem.view.h * h
|
|
||||||
end
|
|
||||||
|
|
||||||
sub = setmetatable({
|
|
||||||
x = activeContext.absX + x,
|
|
||||||
y = activeContext.absY + y,
|
|
||||||
w = w,
|
|
||||||
h = h,
|
|
||||||
wratio = wratio,
|
|
||||||
hratio = hratio,
|
|
||||||
xratio = xratio,
|
|
||||||
yratio = yratio,
|
|
||||||
ix = x,
|
|
||||||
iy = y,
|
|
||||||
eventType = eventType,
|
eventType = eventType,
|
||||||
active = true,
|
active = true,
|
||||||
|
stack = stack,
|
||||||
callback = callback
|
callback = callback
|
||||||
},subscription)
|
},subscription)
|
||||||
|
|
||||||
|
sub.onSizeChange = stack:onSizeChange(function()
|
||||||
|
sub.w, sub.h = sub.stack:normalizeSize(sub.origW, sub.origH)
|
||||||
|
end)
|
||||||
|
|
||||||
|
sub.onPosChange = stack:onPosChange(function()
|
||||||
|
sub.x, sub.y = sub.stack:normalizePos(sub.origX, sub.origY)
|
||||||
|
print(sub.y, sub.stack.absY)
|
||||||
|
end)
|
||||||
|
|
||||||
if doff == false then
|
if doff == false then
|
||||||
sub:off()
|
sub:off()
|
||||||
end
|
end
|
||||||
|
|
||||||
if activeContext.window or activeContext.activeWindow then
|
|
||||||
sub.parentWindow = activeContext.window or activeContext.activeWindow
|
|
||||||
end
|
|
||||||
activeContext.subs[#activeContext.subs+1] = sub
|
|
||||||
else
|
|
||||||
sub = setmetatable({
|
|
||||||
x = x,
|
|
||||||
y = y,
|
|
||||||
w = w,
|
|
||||||
h = h,
|
|
||||||
eventType = eventType,
|
|
||||||
active = doff or true,
|
|
||||||
callback = callback
|
|
||||||
},subscription)
|
|
||||||
end
|
|
||||||
|
|
||||||
if not input.subscriptions[eventType] then
|
if not input.subscriptions[eventType] then
|
||||||
input.subscriptions[eventType] = {}
|
input.subscriptions[eventType] = {}
|
||||||
end
|
end
|
||||||
|
|
||||||
input.subscriptions[eventType][#input.subscriptions[eventType]+1] = sub
|
table.insert(input.subscriptions[eventType],1,sub)
|
||||||
|
|
||||||
|
input.sortZ()
|
||||||
|
|
||||||
return sub
|
return sub
|
||||||
end
|
end
|
||||||
@ -232,40 +114,9 @@ function subscription:on()
|
|||||||
self.active = true
|
self.active = true
|
||||||
end
|
end
|
||||||
|
|
||||||
function subscription:suspend()
|
function subscription:remove()
|
||||||
self.destroyStat = true
|
--input.subscriptions[self.eventType][self] = nil
|
||||||
self.preActive = self.active
|
input.sortZ()
|
||||||
self.active = false
|
|
||||||
end
|
|
||||||
|
|
||||||
function subscription:unsuspend()
|
|
||||||
self.active = self.preActive
|
|
||||||
end
|
|
||||||
|
|
||||||
function subscription:contextUpdate(absX, absY,activeContext)
|
|
||||||
if self.xratio then
|
|
||||||
self.x = absX + activeContext.elem.view.w * self.xratio
|
|
||||||
else
|
|
||||||
self.x = absX + self.ix
|
|
||||||
end
|
|
||||||
if self.yratio then
|
|
||||||
self.y = absY + activeContext.elem.view.h * self.yratio
|
|
||||||
else
|
|
||||||
self.y = absY + self.iy
|
|
||||||
end
|
|
||||||
if self.hratio then
|
|
||||||
self.h = activeContext.elem.view.h * self.hratio
|
|
||||||
end
|
|
||||||
if self.wratio then
|
|
||||||
self.w = activeContext.elem.view.w * self.wratio
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function subscription:update(x, y, w, h)
|
|
||||||
self.x = x or self.x
|
|
||||||
self.y = y or self.y
|
|
||||||
self.w = w or self.w
|
|
||||||
self.h = h or self.h
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function subscription:emit(...)
|
function subscription:emit(...)
|
||||||
@ -297,73 +148,11 @@ input.__call = function(self, eventType, callback, cbOff, x, y, w, h)
|
|||||||
return subscription.create(x,y,w,h,eventType,callback,cbOff)
|
return subscription.create(x,y,w,h,eventType,callback,cbOff)
|
||||||
end
|
end
|
||||||
|
|
||||||
--Will block ui clicks from going through it
|
|
||||||
input.window = function(x,y,w,h)
|
|
||||||
x = x or 0
|
|
||||||
y = y or 0
|
|
||||||
w = w or 1
|
|
||||||
h = h or 1
|
|
||||||
|
|
||||||
activeContext.window = subscription.create(x,y,w,h,'window',nil,false)
|
|
||||||
windowMachine.push(activeContext.window)
|
|
||||||
windowStack[#windowStack+1] = activeContext.window
|
|
||||||
return activeContext.window
|
|
||||||
end
|
|
||||||
|
|
||||||
--Run once per applicable event
|
|
||||||
--The windows should be basically pre sorted, so if something is a hit on a lower window
|
|
||||||
--And is on a higher one too, the lower one is discarded
|
|
||||||
local hits = {}
|
|
||||||
input.checkWindows = function(x,y)
|
|
||||||
local hit = false
|
|
||||||
for i = 1, #windowStack do
|
|
||||||
if windowStack[i]:checkInside(x,y) and windowStack[i].active then
|
|
||||||
hit = windowStack[i]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
--Returns latest hit
|
|
||||||
return hit
|
|
||||||
end
|
|
||||||
|
|
||||||
--Run per sub
|
|
||||||
function input.checkSub(sub,hit)
|
|
||||||
if sub.parentWindow and sub.parentWindow == hit then
|
|
||||||
return true
|
|
||||||
elseif not hit then
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
--Since the introduction of the relative subscriptions, there is more utility in ommiting coordinates by default
|
--Since the introduction of the relative subscriptions, there is more utility in ommiting coordinates by default
|
||||||
setmetatable(input, input)
|
setmetatable(input, input)
|
||||||
|
|
||||||
function input.eventHandlers.mousereleased(x, y, btn)
|
function input.eventHandlers.mousereleased(x, y, btn)
|
||||||
local captured = false
|
local captured = false
|
||||||
local hit = input.checkWindows(x, y)
|
|
||||||
if input.subscriptions.mousereleased then
|
|
||||||
for index, sub in ipairs(input.subscriptions.mousereleased) do
|
|
||||||
--local succ = sub:checkInside(x, y)
|
|
||||||
|
|
||||||
if sub.active and sub:checkInside(x, y) and input.checkSub(sub,hit) then -- succ and sub:check
|
|
||||||
sub:emit(x, y, btn)
|
|
||||||
captured = true
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if input.subscriptions.mousereleased_outside then
|
|
||||||
for index, sub in ipairs(input.subscriptions.mousereleased_outside) do
|
|
||||||
--local succ = sub:checkOutside(x, y)
|
|
||||||
|
|
||||||
if sub.active and sub:checkOutside(x, y) and input.checkSub(sub,hit) then -- succ and sub.active then
|
|
||||||
sub:emit(x, y, btn)
|
|
||||||
captured = true
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if input.subscriptions.clicked then
|
if input.subscriptions.clicked then
|
||||||
for index, sub in ipairs(input.subscriptions.clicked) do
|
for index, sub in ipairs(input.subscriptions.clicked) do
|
||||||
if sub.currentEvent then
|
if sub.currentEvent then
|
||||||
@ -388,44 +177,40 @@ function input.eventHandlers.mousereleased(x, y, btn)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if input.subscriptions.mousereleased then
|
||||||
|
for index, sub in ipairs(input.subscriptions.mousereleased) do
|
||||||
|
if sub.active and sub:checkInside(x, y) then
|
||||||
|
sub:emit(x, y, btn)
|
||||||
|
captured = true
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if input.subscriptions.mousereleased_outside then
|
||||||
|
for index, sub in ipairs(input.subscriptions.mousereleased_outside) do
|
||||||
|
if sub.active and sub:checkOutside(x, y) then
|
||||||
|
sub:emit(x, y, btn)
|
||||||
|
captured = true
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
return captured
|
return captured
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function input.eventHandlers.mousepressed(x, y, btn)
|
function input.eventHandlers.mousepressed(x, y, btn)
|
||||||
local captured = false
|
local captured = false
|
||||||
local hit = input.checkWindows(x, y)
|
|
||||||
if input.subscriptions.mousepressed then
|
|
||||||
for index, sub in ipairs(input.subscriptions.mousepressed) do
|
|
||||||
--local succ = sub:checkInside(x, y)
|
|
||||||
|
|
||||||
if sub.active and sub:checkInside(x, y) and input.checkSub(sub,hit) then -- succ and sub:check
|
|
||||||
sub:emit(x, y, btn)
|
|
||||||
captured = true
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if input.subscriptions.mousepressed_outside then
|
|
||||||
for index, sub in ipairs(input.subscriptions.mousepressed_outside) do
|
|
||||||
--local succ = sub:checkOutside(x, y)
|
|
||||||
|
|
||||||
if sub.active and sub:checkOutside(x, y) and input.checkSub(sub,hit) then -- succ and sub.active then
|
|
||||||
sub:emit(x, y, btn)
|
|
||||||
captured = true
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if input.subscriptions.clicked then
|
if input.subscriptions.clicked then
|
||||||
for index, sub in ipairs(input.subscriptions.clicked) do
|
for index, sub in ipairs(input.subscriptions.clicked) do
|
||||||
local succ = sub:checkInside(x, y)
|
local succ = sub:checkInside(x, y)
|
||||||
|
|
||||||
if succ and sub.active and input.checkSub(sub,hit) then
|
if succ and sub.active then
|
||||||
sub.cleanUp = sub:emit(x, y, btn) or dummyfunc
|
sub.cleanUp = sub:emit(x, y, btn) or dummyfunc
|
||||||
sub.currentEvent = true
|
sub.currentEvent = true
|
||||||
captured = true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
@ -433,16 +218,33 @@ function input.eventHandlers.mousepressed(x, y, btn)
|
|||||||
|
|
||||||
if input.subscriptions.dragged then
|
if input.subscriptions.dragged then
|
||||||
for index, sub in ipairs(input.subscriptions.dragged) do
|
for index, sub in ipairs(input.subscriptions.dragged) do
|
||||||
--local succ = sub:checkInside(x, y)
|
if sub.active and sub:checkInside(x, y) then
|
||||||
|
|
||||||
if sub.active and sub:checkInside(x, y) and input.checkSub(sub,hit) then -- succ and sub:check
|
|
||||||
sub.currentEvent = true
|
sub.currentEvent = true
|
||||||
captured = true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if input.subscriptions.mousepressed then
|
||||||
|
for index, sub in ipairs(input.subscriptions.mousepressed) do
|
||||||
|
if sub.active and sub:checkInside(x, y) then
|
||||||
|
sub:emit(x, y, btn)
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if input.subscriptions.mousepressed_outside then
|
||||||
|
for index, sub in ipairs(input.subscriptions.mousepressed_outside) do
|
||||||
|
if sub.active and sub:checkOutside(x, y) then
|
||||||
|
sub:emit(x, y, btn)
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
return captured
|
return captured
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -450,7 +252,7 @@ function input.eventHandlers.keypressed(btn)
|
|||||||
local captured = false
|
local captured = false
|
||||||
if input.subscriptions.keypressed then
|
if input.subscriptions.keypressed then
|
||||||
for index, sub in ipairs(input.subscriptions.keypressed) do
|
for index, sub in ipairs(input.subscriptions.keypressed) do
|
||||||
if sub.active then -- ==true then
|
if sub.active then
|
||||||
sub:emit( btn)
|
sub:emit( btn)
|
||||||
captured = true
|
captured = true
|
||||||
end
|
end
|
||||||
@ -485,13 +287,13 @@ function input.eventHandlers.mousemoved(x, y, dx, dy)
|
|||||||
if sub.active and not sub.currentEvent and succ then
|
if sub.active and not sub.currentEvent and succ then
|
||||||
sub.cleanUp = sub:emit(x, y, dx, dy) or dummyfunc
|
sub.cleanUp = sub:emit(x, y, dx, dy) or dummyfunc
|
||||||
sub.currentEvent = true
|
sub.currentEvent = true
|
||||||
captured = true
|
return true
|
||||||
elseif sub.currentEvent and not succ then
|
elseif sub.currentEvent and not succ then
|
||||||
sub.currentEvent = false
|
sub.currentEvent = false
|
||||||
captured = true
|
|
||||||
if sub.cleanUp then
|
if sub.cleanUp then
|
||||||
sub.cleanUp(x, y)
|
sub.cleanUp(x, y)
|
||||||
end
|
end
|
||||||
|
return true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -505,8 +307,8 @@ function input.eventHandlers.mousemoved(x, y, dx, dy)
|
|||||||
else
|
else
|
||||||
sub:emit(x, y, dx, dy)
|
sub:emit(x, y, dx, dy)
|
||||||
end
|
end
|
||||||
--sub.currentEvent = true -- checked in the condition so must be true
|
|
||||||
captured = true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
115
core/stack.lua
115
core/stack.lua
@ -2,12 +2,14 @@
|
|||||||
|
|
||||||
local path = string.sub(..., 1, string.len(...) - string.len(".core.stack"))
|
local path = string.sub(..., 1, string.len(...) - string.len(".core.stack"))
|
||||||
local helium = require(path .. ".dummy")
|
local helium = require(path .. ".dummy")
|
||||||
|
local event = require(path..'.core.events')
|
||||||
|
|
||||||
---@class context
|
---@class context
|
||||||
local context = {}
|
local context = {}
|
||||||
context.__index = context
|
context.__index = context
|
||||||
|
|
||||||
local activeContext
|
local activeContext
|
||||||
|
local currentTemporalZ = 0
|
||||||
|
|
||||||
---@param elem element
|
---@param elem element
|
||||||
function context.new(elem)
|
function context.new(elem)
|
||||||
@ -15,12 +17,16 @@ function context.new(elem)
|
|||||||
view = elem.view,
|
view = elem.view,
|
||||||
element = elem,
|
element = elem,
|
||||||
childrenContexts = {},
|
childrenContexts = {},
|
||||||
inputContext = helium.input.newContext(elem),
|
|
||||||
childRenderTime = 0,
|
childRenderTime = 0,
|
||||||
deferChildren = false,
|
deferChildren = false,
|
||||||
|
events = event.new(),
|
||||||
capturedChilds = {},
|
capturedChilds = {},
|
||||||
|
temporalZ = {z = nil},
|
||||||
}, context)
|
}, context)
|
||||||
|
|
||||||
|
ctx.events:newQueue('resize')
|
||||||
|
ctx.events:newQueue('poschange')
|
||||||
|
|
||||||
return ctx
|
return ctx
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -56,14 +62,9 @@ function context:set()
|
|||||||
|
|
||||||
activeContext = self
|
activeContext = self
|
||||||
end
|
end
|
||||||
|
|
||||||
self.inputContext:set()
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function context:unset()
|
function context:unset()
|
||||||
self.inputContext:unset()
|
|
||||||
self.inputContext:afterLoad()
|
|
||||||
|
|
||||||
if self.parentCtx then
|
if self.parentCtx then
|
||||||
activeContext = self.parentCtx
|
activeContext = self.parentCtx
|
||||||
else
|
else
|
||||||
@ -71,8 +72,9 @@ function context:unset()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function context:unsuspend()
|
function context:zIndex()
|
||||||
self.inputContext:unsuspend()
|
currentTemporalZ = currentTemporalZ+1
|
||||||
|
self.temporalZ.z = currentTemporalZ
|
||||||
end
|
end
|
||||||
|
|
||||||
function context:startSelfRender()
|
function context:startSelfRender()
|
||||||
@ -97,12 +99,6 @@ function context:destroy()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function context:suspend()
|
|
||||||
self.inputContext:set()
|
|
||||||
self.inputContext:suspend()
|
|
||||||
self.inputContext:unset()
|
|
||||||
end
|
|
||||||
|
|
||||||
function context:getChildrenCount()
|
function context:getChildrenCount()
|
||||||
return #self.childrenContexts
|
return #self.childrenContexts
|
||||||
end
|
end
|
||||||
@ -124,12 +120,103 @@ end
|
|||||||
|
|
||||||
function context:stopDeferingChildren()
|
function context:stopDeferingChildren()
|
||||||
self.deferChildren = false
|
self.deferChildren = false
|
||||||
|
|
||||||
return self.capturedChilds
|
return self.capturedChilds
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function context:normalizePos(x, y)
|
||||||
|
local xPX, yPX
|
||||||
|
|
||||||
|
if x<=1 and x~=0 then
|
||||||
|
xPX = self.element.view.w * x
|
||||||
|
end
|
||||||
|
|
||||||
|
if y<=1 and y~=0 then
|
||||||
|
yPX = self.element.view.h * y
|
||||||
|
end
|
||||||
|
|
||||||
|
return (xPX or x) + self.absX, (yPX or y) + self.absY
|
||||||
|
end
|
||||||
|
|
||||||
|
function context:normY(y)
|
||||||
|
local yPX
|
||||||
|
|
||||||
|
if y<=1 and y~=0 then
|
||||||
|
yPX = self.element.view.h * y
|
||||||
|
end
|
||||||
|
|
||||||
|
return (yPX or y)
|
||||||
|
end
|
||||||
|
|
||||||
|
function context:normX(x)
|
||||||
|
local xPX
|
||||||
|
|
||||||
|
if x<=1 and x~=0 then
|
||||||
|
xPX = self.element.view.w * x
|
||||||
|
end
|
||||||
|
|
||||||
|
return (xPX or x)
|
||||||
|
end
|
||||||
|
|
||||||
|
function context:normalizeSize(w, h)
|
||||||
|
local wPX, hPX
|
||||||
|
|
||||||
|
if w<=1 and w~=0 then
|
||||||
|
wPX = self.element.view.w * w
|
||||||
|
end
|
||||||
|
|
||||||
|
if h<=1 and h~=0 then
|
||||||
|
hPX = self.element.view.h * h
|
||||||
|
end
|
||||||
|
|
||||||
|
return wPX or w, hPX or h
|
||||||
|
end
|
||||||
|
|
||||||
|
--To be used by the element
|
||||||
|
function context:sizeChanged()
|
||||||
|
self.events:push('resize')
|
||||||
|
end
|
||||||
|
|
||||||
|
function context:posChanged()
|
||||||
|
if self.parentCtx then
|
||||||
|
self.absX = self.parentCtx.absX + self.view.x
|
||||||
|
self.absY = self.parentCtx.absY + self.view.y
|
||||||
|
else
|
||||||
|
self.absX = self.view.x
|
||||||
|
self.absY = self.view.y
|
||||||
|
end
|
||||||
|
|
||||||
|
self.events:push('poschange')
|
||||||
|
end
|
||||||
|
|
||||||
|
--Event subscriptions
|
||||||
|
function context:onSizeChange(callback)
|
||||||
|
return self.events:sub('resize', callback)
|
||||||
|
end
|
||||||
|
|
||||||
|
function context:onPosChange(callback)
|
||||||
|
return self.events:sub('poschange', callback)
|
||||||
|
end
|
||||||
|
|
||||||
|
function context:offSizeChange(callback)
|
||||||
|
self.events:unsub('resize', callback)
|
||||||
|
end
|
||||||
|
|
||||||
|
function context:offPosChange(callback)
|
||||||
|
self.events:unsub('poschange', callback)
|
||||||
|
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
|
||||||
|
|
||||||
|
function context.newFrame()
|
||||||
|
currentTemporalZ = 0
|
||||||
|
end
|
||||||
|
|
||||||
|
function context.unload()
|
||||||
|
activeContext = nil
|
||||||
|
end
|
||||||
|
|
||||||
return context
|
return context
|
||||||
20
init.lua
20
init.lua
@ -10,8 +10,10 @@ helium.utils = require(path..".utils")
|
|||||||
helium.element = require(path..".core.element")
|
helium.element = require(path..".core.element")
|
||||||
helium.input = require(path..".core.input")
|
helium.input = require(path..".core.input")
|
||||||
helium.loader = require(path..".loader")
|
helium.loader = require(path..".loader")
|
||||||
|
helium.stack = require(path..".core.stack")
|
||||||
helium.atlas = require(path..".core.atlas")
|
helium.atlas = require(path..".core.atlas")
|
||||||
helium.elementBuffer = {}
|
helium.elementBuffer = {}
|
||||||
|
helium.elementInsertionQueue = {}
|
||||||
helium.__index = helium
|
helium.__index = helium
|
||||||
|
|
||||||
setmetatable(helium, {__call = function(s, chunk)
|
setmetatable(helium, {__call = function(s, chunk)
|
||||||
@ -61,15 +63,17 @@ function helium.draw()
|
|||||||
for i, e in ipairs(helium.elementBuffer) do
|
for i, e in ipairs(helium.elementBuffer) do
|
||||||
e:externalRender()
|
e:externalRender()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
for i, e in ipairs(helium.elementInsertionQueue) do
|
||||||
|
table.insert(helium.elementBuffer, e)
|
||||||
|
end
|
||||||
|
helium.elementInsertionQueue = {}
|
||||||
end
|
end
|
||||||
|
|
||||||
function helium.update(dt)
|
function helium.update(dt)
|
||||||
if helium.conf.HOTSWAP then
|
|
||||||
helium.loader.update(dt)
|
|
||||||
end
|
|
||||||
|
|
||||||
for i = #helium.elementBuffer, 1, -1 do
|
for i = 1, #helium.elementBuffer do
|
||||||
if helium.elementBuffer[i]:externalUpdate() then
|
if helium.elementBuffer[i]:externalUpdate(i) then
|
||||||
table.remove(helium.elementBuffer,i)
|
table.remove(helium.elementBuffer,i)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -110,6 +114,7 @@ if helium.conf.AUTO_RUN then
|
|||||||
-- Main loop time.
|
-- Main loop time.
|
||||||
return function()
|
return function()
|
||||||
-- Process events.
|
-- Process events.
|
||||||
|
helium.stack.newFrame()
|
||||||
if love.event then
|
if love.event then
|
||||||
love.event.pump()
|
love.event.pump()
|
||||||
for name, a,b,c,d,e,f in love.event.poll() do
|
for name, a,b,c,d,e,f in love.event.poll() do
|
||||||
@ -139,12 +144,13 @@ if helium.conf.AUTO_RUN then
|
|||||||
love.graphics.origin()
|
love.graphics.origin()
|
||||||
love.graphics.clear(love.graphics.getBackgroundColor())
|
love.graphics.clear(love.graphics.getBackgroundColor())
|
||||||
|
|
||||||
if love.draw then love.draw() end
|
|
||||||
|
|
||||||
st = love.timer.getTime()
|
st = love.timer.getTime()
|
||||||
helium.draw()
|
helium.draw()
|
||||||
heliumTime=heliumTime+love.timer.getTime()-st
|
heliumTime=heliumTime+love.timer.getTime()-st
|
||||||
|
|
||||||
|
if love.draw then love.draw() end
|
||||||
|
|
||||||
|
|
||||||
love.graphics.present()
|
love.graphics.present()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
11
layout/column.lua
Normal file
11
layout/column.lua
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
return function(x, y, width, height, children, hpad, vpad, alignX)
|
||||||
|
local carriagePos = 0
|
||||||
|
if children then
|
||||||
|
for i, e in ipairs(children) do
|
||||||
|
local _, h = e:getSize()
|
||||||
|
e:draw(x, y+carriagePos+vpad)
|
||||||
|
carriagePos = carriagePos + h + vpad
|
||||||
|
end
|
||||||
|
end
|
||||||
|
print('finished layout')
|
||||||
|
end
|
||||||
0
layout/flow.lua
Normal file
0
layout/flow.lua
Normal file
128
layout/init.lua
128
layout/init.lua
@ -1,88 +1,144 @@
|
|||||||
local path = string.sub(..., 1, string.len(...) - string.len(".core.layout"))
|
local path = string.sub(..., 1, string.len(...) - string.len(".layout"))
|
||||||
|
|
||||||
local layout = {}
|
local layout = {}
|
||||||
|
local layouts = {}
|
||||||
|
layouts.column = require(path..'.layout.column')
|
||||||
layout.__index = layout
|
layout.__index = layout
|
||||||
local element = require(path..'core.element')
|
local element = require(path..'.core.element')
|
||||||
local stack = require(path..'core.stack')
|
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
|
--Start prep phase
|
||||||
function layout.type(type)
|
function layout.type(type)
|
||||||
|
local curStack = stack.getContext()
|
||||||
|
curStack:startDeferingChildren()
|
||||||
|
|
||||||
local self = {
|
local self = {
|
||||||
vars = {
|
vars = {
|
||||||
type = type or 'flow',
|
type = type or 'column',
|
||||||
offLeft = 0,
|
offLeft = 0,
|
||||||
offTop = 0,
|
offTop = 0,
|
||||||
width = 1,
|
width = 1,
|
||||||
|
hpad = 3,
|
||||||
|
vpad = 3,
|
||||||
height = 1,
|
height = 1,
|
||||||
alignX = 'left', --options: left, center, right
|
alignX = 'left', --options: left, center, right
|
||||||
alignY = 'top', --options: top, center, bottom
|
alignY = 'top', --options: top, center, bottom
|
||||||
flowDir = 'rtl' --options: rtl/ttb
|
--flowDir = 'rtl', --options: rtl/ttb
|
||||||
|
},
|
||||||
|
stack = curStack
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return setmetatable(self, layout)
|
return setmetatable(self, layout)
|
||||||
end
|
end
|
||||||
|
|
||||||
function layout:alignVert(pos)
|
function layout:alignVert(pos)
|
||||||
self.vars.alignY = pos
|
self.vars.alignY = pos
|
||||||
|
|
||||||
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
function layout:alignHoriz(pos)
|
function layout:alignHoriz(pos)
|
||||||
self.vars.alignX = pos
|
self.vars.alignX = pos
|
||||||
|
|
||||||
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--Sets up the box of the layout
|
||||||
function layout:width(w)
|
function layout:width(w)
|
||||||
self.vars.width = w
|
self.vars.width = w
|
||||||
|
|
||||||
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
function layout:height(h)
|
function layout:height(h)
|
||||||
self.vars.height = h
|
self.vars.height = h
|
||||||
|
|
||||||
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
function layout:left(x)
|
function layout:left(x)
|
||||||
self.vars.offTop = x
|
self.vars.offLeft = x
|
||||||
|
|
||||||
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
function layout:right(x)
|
function layout:right(x)
|
||||||
self.vars.offRight = x
|
self.vars.offRight = x
|
||||||
|
|
||||||
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
function layout:top(y)
|
function layout:top(y)
|
||||||
self.vars.offTop = y
|
self.vars.offTop = y
|
||||||
|
|
||||||
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
function layout:bottom(y)
|
function layout:bottom(y)
|
||||||
self.vars.offBot = y
|
self.vars.offBot = y
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
function layout:vPadding(px)
|
||||||
|
self.vars.vpad = px
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
function layout:hPadding(px)
|
||||||
|
self.vars.hpad = px
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--Schemes: left + right = width ignored
|
||||||
|
--top + bottom = height ignored
|
||||||
|
--top px + bottom relative works
|
||||||
|
--left relative + bottom px works
|
||||||
|
function layout:draw()
|
||||||
|
local stack = self.stack
|
||||||
|
local children = stack:stopDeferingChildren()
|
||||||
|
local height, width, x, y, _, marginV, marginH
|
||||||
|
local maxW, maxH = stack:normalizeSize(1,1)
|
||||||
|
|
||||||
|
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
|
||||||
|
elseif self.vars.offTop then
|
||||||
|
y = stack:normY(self.vars.offTop)
|
||||||
|
height = math.min(stack:normY(self.vars.height), maxH-y)
|
||||||
|
elseif self.vars.offBot then
|
||||||
|
y = stack:normY(self.vars.offBot)
|
||||||
|
height = math.min(stack:normY(self.vars.height), maxH-y)
|
||||||
|
y = 0
|
||||||
|
end
|
||||||
|
|
||||||
|
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
|
||||||
|
elseif self.vars.offLeft then
|
||||||
|
x = stack:normX(self.vars.offLeft)
|
||||||
|
width = math.min(stack:normX(self.vars.width), maxW-x)
|
||||||
|
elseif self.vars.offRight then
|
||||||
|
x = stack:normX(self.vars.offRight)
|
||||||
|
height = math.min(stack:normX(self.vars.width), maxW-x)
|
||||||
|
x = 0
|
||||||
|
end
|
||||||
|
|
||||||
|
layouts[self.vars.type](
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
children,
|
||||||
|
self.vars.hpad,
|
||||||
|
self.vars.vpad,
|
||||||
|
self.vars.alignX,
|
||||||
|
self.vars.alignY
|
||||||
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
setmetatable(layout, {__call = function(s, type) return layout.type(type) end })
|
||||||
setmetatable(layout, {__call = function(s, type) return layout.type(type) end }
|
|
||||||
return layout
|
return layout
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user