129 lines
3.6 KiB
Lua
129 lines
3.6 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
|
|
|
|
---@class SliderValuesTable
|
|
---@field value number @Starting value of the slider
|
|
---@field divider number @The divider (rounding) for your slider
|
|
---@field min number @The minimum slider number
|
|
---@field max number @The maximum slider number
|
|
|
|
---@class SliderStateTable
|
|
---@field value number @Current value of the slider
|
|
---@field divisions number @Current divisions of the slider
|
|
---@field min number @Min value of the slider
|
|
---@field max number @Max value of the slider
|
|
|
|
---@class HandleStateTable
|
|
---@field down boolean @Whether the mouse is pressing the handle
|
|
---@field over boolean @Whether the mouse is over the handle
|
|
---@field x number @X position of the handle
|
|
---@field y number @Y position of the handle
|
|
|
|
---Sets up a slider for your element
|
|
---@param values SliderValuesTable
|
|
---@param w number
|
|
---@param h number
|
|
---@param onChange fun(sliderValue:number)
|
|
---@param onFinish fun(sliderValue:number)
|
|
---@param onClick fun()
|
|
---@param onRelease fun()
|
|
---@param onEnter fun()
|
|
---@param onExit fun()
|
|
---@param x any
|
|
---@param y any
|
|
---@return SliderStateTable
|
|
---@return HandleStateTable
|
|
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.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.value 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, nil, originx, originy )
|
|
|
|
|
|
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, nil, originx, originy )
|
|
|
|
return slider, handle
|
|
end |