local path = string.sub(..., 1, string.len(...) - string.len(".core.input")) local helium = require(path .. ".dummy") local input={ eventHandlers = {}, subscriptions = {}, activeEvents = {} } local dummyfunc = function() end ---@class subscription local subscription = {} subscription.__index = subscription ---@class inputContext local context = {} context.__index = context local activeContext --[[Event types ###SIMPLE EVENTS### mousepressed,--press started mousereleased,--press released after an event inside started mousepressed_outside --mousepressed outside of the subscription mousereleased_outside --mousereleased outside of the subscription keypressed,--key pressed keyreleased,--key released ###COMPLEX EVENTS### dragged, clicked, hover, ]] function input.newContext(element) local ctx = setmetatable({elem = element, subs = {}, childContexts={}}, context) return ctx end function context:set() if activeContext 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 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:destroy() for i, e in ipairs(self.subs) do e:destroy() end for i, e in ipairs(self.childContexts) do e:destroy() end end ---@param x number ---@param y number ---@param w number ---@param h number ---@param eventType string ---@param callback function ---@param doff boolean ---@return subscription function subscription.create(x, y, w, h, eventType, callback, doff) local sub if activeContext then local wratio,hratio,xratio,yratio if x<=1 and x~=0 then xratio = x x = activeContext.elem.view.w * x end if y<=1 and y~=0 then yratio = y y = activeContext.elem.view.h * y end if w<=1 and w~=0 then wratio = w w = activeContext.elem.view.w * w end 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, active = doff or true, callback = callback },subscription) 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 input.subscriptions[eventType] = {} end table.insert(input.subscriptions[eventType],sub) return sub end function subscription:off() self.active = false end function subscription:on() self.active = true end function subscription:destroy() self.destroyStat = true self.active = false 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 function subscription:emit(...) return self.callback(...) end function subscription:checkInside(x, y) return x>self.x and xself.y and yself.x and xself.y and y