local path = string.sub(..., 1, string.len(...) - string.len(".core.input")) local stack = require(path .. ".core.stack") local helium = require(path .. ".dummy") local input = { eventHandlers = {}, subscriptions = setmetatable({}, {__index = function (t, index) return helium.scene.activeScene and helium.scene.activeScene.subscriptions[index] or nil end, __newindex = function(t, index, val) helium.scene.activeScene.subscriptions[index] = val end}), activeEvents = {} } input.__index = input --Middle man functions local orig = { mousepressed = love.handlers['mousepressed'], mousereleased = love.handlers['mousereleased'], textinput = love.handlers['textinput'], keypressed = love.handlers['keypressed'], keyreleased = love.handlers['keyreleased'], mousemoved = love.handlers['mousemoved'] } love.handlers['mousepressed'] = function(x, y, btn, d, e, f) if not input.eventHandlers.mousepressed(x, y, btn, d, e ,f) then orig.mousepressed(x, y, btn, d, e, f) end end love.handlers['mousereleased'] = function(x, y, btn, d, e, f) if not input.eventHandlers.mousereleased(x, y, btn, d, e ,f) then orig.mousereleased(x, y, btn, d, e, f) end end love.handlers['keypressed'] = function(key, b, c, d, e, f) if not input.eventHandlers.keypressed(key, b, c, d, e, f) then orig.keypressed(key, b, c, d, e, f) end end love.handlers['keyreleased'] = function(key, b, c, d, e, f) if not input.eventHandlers.keyreleased(key, b, c, d, e, f) then orig.keyreleased(key, b, c, d, e, f) end end love.handlers['textinput'] = function(text, b, c, d, e, f) if not input.eventHandlers.textinput(text, b, c, d, e, f) then orig.textinput(text, b, c, d, e, f) end end love.handlers['mousemoved'] = function(x, y, dx, dy, e, f) if not input.eventHandlers.mousemoved(x, y, dx, dy, e, f) then orig.mousemoved(x, y, dx, dy, e, f) end end local function sortFunc(t1, t2) if t1 == t2 then return false end return t1.stack.temporalZ.z > t2.stack.temporalZ.z end function input.sortZ() for i, subs in pairs(input.subscriptions) do table.sort(subs, sortFunc) end end local dummyfunc = function() end ---@class subscription local subscription = {} subscription.__index = subscription function input.unload() input.subscriptions = {} input.activeEvents = {} end --[[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 textinput, --same as love ###COMPLEX EVENTS### dragged, clicked, hover, ]] ---@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 stack = stack.getContext() local xn, yn = stack:normalizePos(x, y) local wn, hn = stack:normalizeSize(w, h) local sub = setmetatable({ x = xn, y = yn, w = wn, h = hn, origX = x, origY = y, origW = w, origH = h, eventType = eventType, active = true, stack = stack, callback = callback },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) end) if doff == false then sub:off() end if not input.subscriptions[eventType] then input.subscriptions[eventType] = {} end table.insert(input.subscriptions[eventType], 1, sub) input.sortZ() return sub end function subscription:off() self.active = false end function subscription:on() self.active = true end function subscription:remove() --input.subscriptions[self.eventType][self] = nil input.sortZ() end function subscription:emit(...) return self.callback(...) end function subscription:checkInside(x, y) return x>self.stack.absX and xself.stack.absY and yself.stack.absX and xself.stack.absY and y