diff --git a/core/element.lua b/core/element.lua index e0943b8..e2e27a4 100644 --- a/core/element.lua +++ b/core/element.lua @@ -160,9 +160,7 @@ function element:createCanvas() self.canvas, self.quad = scene.activeScene.atlas:assign(self) - print('here') if not self.canvas then - print('failed') self.settings.failedCanvas = true self.settings.hasCanvas = false return diff --git a/core/input.lua b/core/input.lua index f2e5652..d28a4fe 100644 --- a/core/input.lua +++ b/core/input.lua @@ -18,6 +18,7 @@ input.__index = input 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'] @@ -43,6 +44,11 @@ love.handlers['keyreleased'] = function(key, b, c, d, e, f) 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) @@ -83,6 +89,8 @@ end keypressed,--key pressed keyreleased,--key released + textinput, --same as love + ###COMPLEX EVENTS### dragged, clicked, @@ -283,12 +291,12 @@ function input.eventHandlers.mousepressed(x, y, btn) return captured end -function input.eventHandlers.keypressed(btn) +function input.eventHandlers.keypressed(btn, btncode) local captured = false if input.subscriptions.keypressed then for index, sub in ipairs(input.subscriptions.keypressed) do if sub.active then - sub:emit( btn) + sub:emit(btn, btncode) captured = true end @@ -298,12 +306,26 @@ function input.eventHandlers.keypressed(btn) return captured end -function input.eventHandlers.keyreleased(btn) +function input.eventHandlers.keyreleased(btn, btncode) local captured = false if input.subscriptions.keyreleased then for index, sub in ipairs(input.subscriptions.keyreleased) do if sub.active then - sub:emit(btn) + sub:emit(btn, btncode) + captured = true + end + end + end + + return captured +end + +function input.eventHandlers.textinput(text) + local captured = false + if input.subscriptions.textinput then + for index, sub in ipairs(input.subscriptions.textinput) do + if sub.active then + sub:emit(text) captured = true end end diff --git a/core/stack.lua b/core/stack.lua index e4c8c34..57b2732 100644 --- a/core/stack.lua +++ b/core/stack.lua @@ -21,6 +21,7 @@ function context.new(elem) childRenderTime = 0, deferChildren = false, events = event.new(), + attachedState = {}, temporalZ = {z = nil}, }, context) @@ -187,6 +188,16 @@ function context:normalizeSize(w, h) return wPX or w, hPX or h end +function context:findAttachedState(name) + if self.attachedState and self.attachedState[name] then + return self.attachedState[name] + elseif self.parentCtx then + return self.parentCtx:findAttachedState(name) + else + return nil + end +end + --To be used by the element function context:sizeChanged() self.events:push('resize') diff --git a/hooks/context.lua b/hooks/context.lua index e69de29..b7c43e7 100644 --- a/hooks/context.lua +++ b/hooks/context.lua @@ -0,0 +1,48 @@ +local path = string.sub(..., 1, string.len(...) - string.len(".hooks.context")) +local context = require(path.. ".core.stack") + +local c = {} + +function c.use(name, base) + base = base or {} + local fakeBase = {} + local activeContext = context.getContext() + local indexMappings = {} + + local ctx = setmetatable({},{ + __index = function(t, index) + --Capturing contexts where this index is used + if not indexMappings[index] then + indexMappings[index] = {} + end + + local c = context.getContext() + indexMappings[index][c] = c + + return fakeBase[index] or base[index] + end, + __newindex = function(t, index, val) + if fakeBase[index] ~= val then + if indexMappings[index] then + for i, cctx in pairs(indexMappings[index]) do + cctx:bubbleUpdate() + end + end + fakeBase[index] = val + activeContext:bubbleUpdate() + end + end + }) + + activeContext.attachedState[name] = ctx + + return ctx +end + +function c.get(name) + local activeContext = context.getContext() + + return activeContext:findAttachedState(name) +end + +return c \ No newline at end of file diff --git a/shell/input.lua b/shell/input.lua index e69de29..f66dcf2 100644 --- a/shell/input.lua +++ b/shell/input.lua @@ -0,0 +1,75 @@ +local path = string.sub(..., 1, string.len(...) - string.len(".shell.input")) +local state = require(path.. ".hooks.state") +local input = require(path.. ".core.input") +local utf8 = require("utf8") + +return function(onChange, onFinish, startStr, onEnter, onExit, x, y, w, h) + local textState = state { + focused = false, + text = startStr or '', + over = false + } + local keyInput, textInput + + keyInput = input('keypressed', function(key) + if key == 'backspace' then + local byteoffset = utf8.offset(textState.text, -1) + + if byteoffset then + textState.text = string.sub(textState.text, 1, byteoffset - 1) + end + + if onChange then + onChange(textState.text) + end + end + if key == 'return' then + textState.focused = false + keyInput:off() + textInput:off() + if onFinish then + onFinish(textState.text) + end + end + end) + + textInput = input('textinput', function(text) + textState.text = textState.text .. text + if onChange then + onChange(textState.text) + end + end) + + input('mousepressed', function() + textState.focused = true + keyInput:on() + textInput:on() + end) + + input('mousepressed_outside', function() + textState.focused = false + keyInput:off() + textInput:off() + if onFinish then + onFinish(textState.text) + end + end) + + input('hover', function(x, y, w, h) + if onEnter then + onEnter(x, y, w, h) + end + + textState.over = true + + return function(x, y, w, h) + if onExit then + onExit(x, y, w, h) + end + + textState.over = false + end + end) + + return textState +end \ No newline at end of file diff --git a/shell/slider.lua b/shell/slider.lua index c8f17f1..fded8c6 100644 --- a/shell/slider.lua +++ b/shell/slider.lua @@ -27,7 +27,7 @@ return function(values, w, h, onChange, onFinish, onClick, onRelease, onEnter, o local vertical = h > w local originx, originy = x or 0, y or 0 local slider = state { - value = values.start or ((values.max - values.min)/2)+values.min or 0, + value = values.value or ((values.max - values.min)/2)+values.min or 0, divisions = values.divider or 1, min = values.min or 0, max = values.max or values.start or 0, @@ -74,7 +74,7 @@ return function(values, w, h, onChange, onFinish, onClick, onRelease, onEnter, o onFinish(slider.value) end end - end) + end, nil, originx, originy ) input('hover', function(x, y, w, h) @@ -91,7 +91,7 @@ return function(values, w, h, onChange, onFinish, onClick, onRelease, onEnter, o handle.over = false end - end) + end, nil, originx, originy ) return slider, handle end \ No newline at end of file