Typescript definitions

This commit is contained in:
qfx 2020-02-19 20:43:58 +02:00
parent 8eab7d3d35
commit 69a0e74619
4 changed files with 170 additions and 14 deletions

View File

@ -27,7 +27,7 @@ end
function context:set() function context:set()
if activeContext then if activeContext then
if not self.parentCtx then if not self.parentCtx and activeContext~=self then
self.parentCtx = activeContext self.parentCtx = activeContext
activeContext.childrenContexts[#activeContext.childrenContexts] = self activeContext.childrenContexts[#activeContext.childrenContexts] = self
end end
@ -169,6 +169,7 @@ function element:new(w, h, param)
end end
self:setup() self:setup()
self.settings.isSetup = true
end end
function element:updateInputCtx() function element:updateInputCtx()
@ -244,6 +245,7 @@ function element:setup()
self.inputContext:set() self.inputContext:set()
self.renderer = self.parentFunc(self.parameters,self.state,self.view) self.renderer = self.parentFunc(self.parameters,self.state,self.view)
self.inputContext:unset() self.inputContext:unset()
self.inputContext:afterLoad()
self.context:unset() self.context:unset()
self.settings.isSetup = true self.settings.isSetup = true
@ -333,6 +335,10 @@ function element:draw(x, y)
if y then self.view.y = y end if y then self.view.y = y end
end end
if not self.settings.isSetup then
self.inputContext:unsuspend()
self.settings.isSetup = true
end
if activeContext then if activeContext then
self:externalRender() self:externalRender()
@ -346,7 +352,8 @@ function element:undraw()
self.settings.remove = true self.settings.remove = true
self.settings.isSetup = false self.settings.isSetup = false
self.inputContext:set() self.inputContext:set()
self.inputContext:destroy() self.inputContext:suspend()
self.inputContext:unset()
end end
return element return element

15
core/input.d.ts vendored Normal file
View File

@ -0,0 +1,15 @@
interface Subscription{
on():void;
off():void;
}
export enum inputType{
clicked = "clicked",
keypressed = "keypressed",
hover = "hover",
mousepressed = "mousepressed",
mousereleased = "mousereleased",
dragged = "dragged"
}
export function input(it:inputType,cb:(x?:number,y?:number)=>void,doff?:boolean,x?:number,y?:number,w?:number,h?:number): Subscription;

View File

@ -8,6 +8,35 @@ local input={
} }
input.__index = input input.__index = input
local windowMachine = {}
windowMachine.__index = windowMachine
local windowCurrent = false
--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
windowMachine.get = function()
if windowCurrent then
return windowMachine[windowCurrent]
end
end
local activeWindow
local windowStack = {}
local dummyfunc = function() end local dummyfunc = function() end
---@class subscription ---@class subscription
local subscription = {} local subscription = {}
@ -44,7 +73,9 @@ function input.newContext(element)
end end
function context:set() function context:set()
if activeContext then self.activeWindow = windowMachine.get()
if activeContext and activeContext~=self then
if not self.parentCtx then if not self.parentCtx then
activeContext.childContexts[#activeContext.childContexts+1] = self activeContext.childContexts[#activeContext.childContexts+1] = self
self.parentCtx = activeContext self.parentCtx = activeContext
@ -78,14 +109,31 @@ function context:unset()
else else
activeContext = nil activeContext = nil
end end
end end
function context:destroy() 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 for i, e in ipairs(self.subs) do
e:destroy() e:unsuspend()
end end
for i, e in ipairs(self.childContexts) do for i, e in ipairs(self.childContexts) do
e:destroy() 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
end end
@ -133,9 +181,17 @@ function subscription.create(x, y, w, h, eventType, callback, doff)
ix = x, ix = x,
iy = y, iy = y,
eventType = eventType, eventType = eventType,
active = doff or true, active = true,
callback = callback callback = callback
},subscription) },subscription)
if doff == false then
sub:off()
end
if activeContext.window or activeContext.activeWindow then
sub.parentWindow = activeContext.window or activeContext.activeWindow
end
activeContext.subs[#activeContext.subs+1] = sub activeContext.subs[#activeContext.subs+1] = sub
else else
sub = setmetatable({ sub = setmetatable({
@ -166,11 +222,16 @@ function subscription:on()
self.active = true self.active = true
end end
function subscription:destroy() function subscription:suspend()
self.destroyStat = true self.destroyStat = true
self.preActive = self.active
self.active = false self.active = false
end end
function subscription:unsuspend()
self.active = self.preActive
end
function subscription:contextUpdate(absX, absY,activeContext) function subscription:contextUpdate(absX, absY,activeContext)
if self.xratio then if self.xratio then
self.x = absX + activeContext.elem.view.w * self.xratio self.x = absX + activeContext.elem.view.w * self.xratio
@ -226,16 +287,56 @@ 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
print(sub.parentWindow)
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 if input.subscriptions.mousereleased then
for index, sub in ipairs(input.subscriptions.mousereleased) do for index, sub in ipairs(input.subscriptions.mousereleased) do
--local succ = sub:checkInside(x, y) --local succ = sub:checkInside(x, y)
if sub.active and sub:checkInside(x, y) then -- succ and sub:check if sub.active and sub:checkInside(x, y) and input.checkSub(sub,hit) then -- succ and sub:check
sub:emit(x, y, btn) sub:emit(x, y, btn)
captured = true captured = true
end end
@ -246,7 +347,7 @@ function input.eventHandlers.mousereleased(x, y, btn)
for index, sub in ipairs(input.subscriptions.mousereleased_outside) do for index, sub in ipairs(input.subscriptions.mousereleased_outside) do
--local succ = sub:checkOutside(x, y) --local succ = sub:checkOutside(x, y)
if sub.active and sub:checkOutside(x, y) then -- succ and sub.active then if sub.active and sub:checkOutside(x, y) and input.checkSub(sub,hit) then -- succ and sub.active then
sub:emit(x, y, btn) sub:emit(x, y, btn)
captured = true captured = true
end end
@ -285,11 +386,12 @@ 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 if input.subscriptions.mousepressed then
for index, sub in ipairs(input.subscriptions.mousepressed) do for index, sub in ipairs(input.subscriptions.mousepressed) do
--local succ = sub:checkInside(x, y) --local succ = sub:checkInside(x, y)
if sub.active and sub:checkInside(x, y) then -- succ and sub:check if sub.active and sub:checkInside(x, y) and input.checkSub(sub,hit) then -- succ and sub:check
sub:emit(x, y, btn) sub:emit(x, y, btn)
captured = true captured = true
end end
@ -300,7 +402,7 @@ function input.eventHandlers.mousepressed(x, y, btn)
for index, sub in ipairs(input.subscriptions.mousepressed_outside) do for index, sub in ipairs(input.subscriptions.mousepressed_outside) do
--local succ = sub:checkOutside(x, y) --local succ = sub:checkOutside(x, y)
if sub.active and sub:checkOutside(x, y) then -- succ and sub.active then if sub.active and sub:checkOutside(x, y) and input.checkSub(sub,hit) then -- succ and sub.active then
sub:emit(x, y, btn) sub:emit(x, y, btn)
captured = true captured = true
end end
@ -311,7 +413,7 @@ function input.eventHandlers.mousepressed(x, y, btn)
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 then if succ and sub.active and input.checkSub(sub,hit) 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 captured = true
@ -324,7 +426,7 @@ function input.eventHandlers.mousepressed(x, y, btn)
for index, sub in ipairs(input.subscriptions.dragged) do for index, sub in ipairs(input.subscriptions.dragged) do
--local succ = sub:checkInside(x, y) --local succ = sub:checkInside(x, y)
if sub.active and sub:checkInside(x, y) then -- succ and sub:check 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 captured = true
end end

32
helium.d.ts vendored Normal file
View File

@ -0,0 +1,32 @@
export interface parameters{
[index: string]: any;
[index: number]: any;
}
export interface view{
x: number;
y: number;
w: number;
h: number;
lock?: boolean;
onChange?(): null;
}
export interface state{
[index: string]: any;
[index: number]: any;
}
interface HeliumElement{
view: view;
state: state;
parameters: parameters;
draw(x:number,y:number): null;
undraw(): null;
}
export module helium{
export let input: typeof import("./core/input") ;
}
export function helium<T>(chunk:(params:T,state:state,view:view)=>()=>void):(params:T, w:number, h:number)=>HeliumElement;