From 10956864b8ecf29cec45add61439fec5226a71b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elm=C4=81rs=20=C4=80boli=C5=86=C5=A1?= Date: Mon, 3 May 2021 22:38:34 +0300 Subject: [PATCH] Input modules fixes, slider hook added --- core/input.lua | 22 ++++---- hooks/README.md | 18 ------ hooks/callback.lua | 1 + {control => hooks}/context.lua | 0 {control => hooks}/position.lua | 0 {control => hooks}/size.lua | 0 {control => hooks}/state.lua | 2 +- shell/button.lua | 2 +- shell/checkbox.lua | 44 +++++++++++++++ shell/slider.lua | 97 +++++++++++++++++++++++++++++++++ 10 files changed, 155 insertions(+), 31 deletions(-) delete mode 100644 hooks/README.md create mode 100644 hooks/callback.lua rename {control => hooks}/context.lua (100%) rename {control => hooks}/position.lua (100%) rename {control => hooks}/size.lua (100%) rename {control => hooks}/state.lua (81%) diff --git a/core/input.lua b/core/input.lua index ce805c9..f2e5652 100644 --- a/core/input.lua +++ b/core/input.lua @@ -194,7 +194,7 @@ function input.eventHandlers.mousereleased(x, y, btn) sub.currentEvent = false captured = true if sub.cleanUp then - sub.cleanUp(x, y, btn) + sub.cleanUp(x-sub.x, y-sub.y, btn) end end end @@ -206,7 +206,7 @@ function input.eventHandlers.mousereleased(x, y, btn) sub.currentEvent = false captured = true if sub.cleanUp then - sub.cleanUp(x, y) + sub.cleanUp(x-sub.x, y-sub.y) end end end @@ -215,7 +215,7 @@ function input.eventHandlers.mousereleased(x, y, btn) 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) + sub:emit(x-sub.x, y-sub.y, btn) captured = true end @@ -225,7 +225,7 @@ function input.eventHandlers.mousereleased(x, y, btn) 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) + sub:emit(x-sub.x, y-sub.y, btn) captured = true end @@ -243,7 +243,7 @@ function input.eventHandlers.mousepressed(x, y, btn) local succ = sub:checkInside(x, y) if succ and sub.active then - sub.cleanUp = sub:emit(x, y, btn) or dummyfunc + sub.cleanUp = sub:emit(x-sub.x, y-sub.y, btn) or dummyfunc sub.currentEvent = true return true end @@ -264,7 +264,7 @@ function input.eventHandlers.mousepressed(x, y, btn) 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) + sub:emit(x-sub.x, y-sub.y, btn) return true end @@ -274,7 +274,7 @@ function input.eventHandlers.mousepressed(x, y, btn) 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) + sub:emit(x-sub.x, y-sub.y, btn) return true end @@ -320,13 +320,13 @@ function input.eventHandlers.mousemoved(x, y, dx, dy) local succ = sub:checkInside(x, y) 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-sub.x, y-sub.y, dx, dy) or dummyfunc sub.currentEvent = true return true elseif sub.currentEvent and not succ then sub.currentEvent = false if sub.cleanUp then - sub.cleanUp(x, y) + sub.cleanUp(x-sub.x, y-sub.y) end return true end @@ -338,9 +338,9 @@ function input.eventHandlers.mousemoved(x, y, dx, dy) for index, sub in ipairs(input.subscriptions.dragged) do if sub.active and sub.currentEvent then if not sub.cleanUp then - sub.cleanUp = sub:emit(x, y, dx, dy) or dummyfunc + sub.cleanUp = sub:emit(x-sub.x, y-sub.y, dx, dy) or dummyfunc else - sub:emit(x, y, dx, dy) + sub:emit(x-sub.x, y-sub.y, dx, dy) end return true diff --git a/hooks/README.md b/hooks/README.md deleted file mode 100644 index ee71b71..0000000 --- a/hooks/README.md +++ /dev/null @@ -1,18 +0,0 @@ -Hooks are additional functions to utilize the element lifecycle more granularly -e.g. - -```lua -local onDestroyHook = require("helium/hooks/onDestroy") - -return function (param) - - onDestroyHook(function() - doSomething() - end) - - return function() - love.graphics.print("Help") - end -end - -``` \ No newline at end of file diff --git a/hooks/callback.lua b/hooks/callback.lua new file mode 100644 index 0000000..c4eec28 --- /dev/null +++ b/hooks/callback.lua @@ -0,0 +1 @@ +--Allows to expose a function to outside the element simply \ No newline at end of file diff --git a/control/context.lua b/hooks/context.lua similarity index 100% rename from control/context.lua rename to hooks/context.lua diff --git a/control/position.lua b/hooks/position.lua similarity index 100% rename from control/position.lua rename to hooks/position.lua diff --git a/control/size.lua b/hooks/size.lua similarity index 100% rename from control/size.lua rename to hooks/size.lua diff --git a/control/state.lua b/hooks/state.lua similarity index 81% rename from control/state.lua rename to hooks/state.lua index 25e5426..877efc0 100644 --- a/control/state.lua +++ b/hooks/state.lua @@ -1,4 +1,4 @@ -local path = string.sub(..., 1, string.len(...) - string.len(".control.state")) +local path = string.sub(..., 1, string.len(...) - string.len(".hooks.state")) local context = require(path.. ".core.stack") return function (base) diff --git a/shell/button.lua b/shell/button.lua index 4aa1580..173282e 100644 --- a/shell/button.lua +++ b/shell/button.lua @@ -1,5 +1,5 @@ local path = string.sub(..., 1, string.len(...) - string.len(".shell.button")) -local state = require(path.. ".control.state") +local state = require(path.. ".hooks.state") local input = require(path.. ".core.input") return function(onClick, onRelease, onEnter, onExit, x, y, w, h) diff --git a/shell/checkbox.lua b/shell/checkbox.lua index e69de29..a5f5fa4 100644 --- a/shell/checkbox.lua +++ b/shell/checkbox.lua @@ -0,0 +1,44 @@ +local path = string.sub(..., 1, string.len(...) - string.len(".shell.button")) +local state = require(path.. ".hooks.state") +local input = require(path.. ".core.input") + +return function(onClick, onRelease, onEnter, onExit, startOn, x, y, w, h) + local checkbox = state { + down = false, + toggled = not not startOn, + over = false, + } + input('clicked', function(x, y, w, h) + if onClick then + onClick(x, y, w, h) + end + + checkbox.down = true + + return function(x, y, w, h) + if onRelease then + onRelease(x, y, w, h) + end + checkbox.toggled = not checkbox.toggled + checkbox.down = false + end + end) + + input('hover', function(x, y, w, h) + if onEnter then + onEnter(x, y, w, h) + end + + checkbox.over = true + + return function(x, y, w, h) + if onExit then + onExit(x, y, w, h) + end + + checkbox.over = false + end + end) + + return checkbox +end \ No newline at end of file diff --git a/shell/slider.lua b/shell/slider.lua index e69de29..c8f17f1 100644 --- a/shell/slider.lua +++ b/shell/slider.lua @@ -0,0 +1,97 @@ +local path = string.sub(..., 1, string.len(...) - string.len(".shell.button")) +local state = require(path.. ".hooks.state") +local input = require(path.. ".core.input") + +local function clamp(num, min, max) + local min, max = min or 0, max or 1 + return math.max(math.min(num, 1), 0) +end + +local function round(num) + return math.floor(num+0.5) +end + +local function calcPercent(min, val, max) + return clamp((val-min)/(max - min)) +end + +local function mapToValueRange(pct, minVal, maxVal, divider) + return (round(((maxVal-minVal)*pct) / divider) * divider)+minVal +end + +local function mapCoordToVal(minCoord, maxCoord, minVal, maxVal, divider, coord) + return mapToValueRange(calcPercent(minCoord, coord, maxCoord), minVal, maxVal, divider) +end + +return function(values, w, h, onChange, onFinish, onClick, onRelease, onEnter, onExit, x, y) + 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, + divisions = values.divider or 1, + min = values.min or 0, + max = values.max or values.start or 0, + } + local handle = state { + x = 0, + y = 0, + over = false, + down = false, + } + + if vertical then + handle.y = calcPercent(slider.min, slider.value, slider.max) * h + originy + else + handle.x = calcPercent(slider.min, slider.value, slider.max) * w + originx + end + + input('dragged', function(x, y, dx, dy) + if vertical then + slider.value = mapCoordToVal(originy, h, slider.min, slider.max, slider.divisions, y) + handle.y = calcPercent(slider.min, slider.value, slider.max) * h + originy + else + slider.value = mapCoordToVal(originx, w, slider.min, slider.max, slider.divisions, x) + handle.x = calcPercent(slider.min, slider.value, slider.max) * w + originx + end + + if onChange then + onChange(slider.value) + end + + handle.down = true + + return function(x, y) + handle.down = false + if vertical then + slider.value = mapCoordToVal(originy, h, slider.min, slider.max, slider.divisions, y) + handle.y = calcPercent(slider.min, slider.value, slider.max) * h + originy + else + slider.value = mapCoordToVal(originx, w, slider.min, slider.max, slider.divisions, x) + handle.x = calcPercent(slider.min, slider.value, slider.max) * w + originx + end + + if onFinish then + onFinish(slider.value) + end + end + end) + + + input('hover', function(x, y, w, h) + if onEnter then + onEnter(x, y, w, h) + end + + handle.over = true + + return function(x, y, w, h) + if onExit then + onExit(x, y, w, h) + end + + handle.over = false + end + end) + + return slider, handle +end \ No newline at end of file