helium/shell/slider.lua
2021-05-03 22:38:34 +03:00

97 lines
2.5 KiB
Lua

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