slabOS/lib/basalt/objects/Scrollbar.lua
2025-06-02 10:23:40 +03:00

218 lines
6.7 KiB
Lua

local tHex = require("tHex")
return function(name, basalt)
local base = basalt.getObject("VisualObject")(name, basalt)
local objectType = "Scrollbar"
base:setZIndex(2)
base:setSize(1, 8)
base:setBackground(colors.lightGray, "\127", colors.gray)
local barType = "vertical"
local symbol = " "
local symbolBG = colors.black
local symbolFG = colors.black
local scrollAmount = 3
local index = 1
local symbolSize = 1
local symbolAutoSize = true
local function updateSymbolSize()
local w,h = base:getSize()
if(symbolAutoSize)then
symbolSize = math.max((barType == "vertical" and h or w-(#symbol)) - (scrollAmount-1), 1)
end
end
updateSymbolSize()
local function mouseEvent(self, button, x, y)
local obx, oby = self:getAbsolutePosition()
local w,h = self:getSize()
updateSymbolSize()
local size = barType == "vertical" and h or w
for i = 0, size do
if ((barType == "vertical" and oby + i == y) or (barType == "horizontal" and obx + i == x)) and (obx <= x) and (obx + w > x) and (oby <= y) and (oby + h > y) then
index = math.min(i + 1, size - (#symbol + symbolSize - 2))
self:scrollbarMoveHandler()
self:updateDraw()
end
end
end
local object = {
getType = function(self)
return objectType
end,
load = function(self)
base.load(self)
local parent = self:getParent()
self:listenEvent("mouse_click")
self:listenEvent("mouse_up")
self:listenEvent("mouse_scroll")
self:listenEvent("mouse_drag")
end,
setSymbol = function(self, _symbol, bg, fg)
symbol = _symbol:sub(1,1)
symbolBG = bg or symbolBG
symbolFG = fg or symbolFG
updateSymbolSize()
self:updateDraw()
return self
end,
setSymbolBG = function(self, bg)
return self:setSymbol(symbol, bg, nil)
end,
setSymbolFG = function(self, fg)
return self:setSymbol(symbol, nil, fg)
end,
getSymbol = function(self)
return symbol
end,
getSymbolBG = function(self)
return symbolBG
end,
getSymbolFG = function(self)
return symbolFG
end,
setIndex = function(self, _index)
index = _index
if (index < 1) then
index = 1
end
local w,h = self:getSize()
--index = math.min(index, (barType == "vertical" and h or w) - (symbolSize - 1))
updateSymbolSize()
self:updateDraw()
return self
end,
setScrollAmount = function(self, amount)
scrollAmount = amount
updateSymbolSize()
self:updateDraw()
return self
end,
getScrollAmount = function(self)
return scrollAmount
end,
getIndex = function(self)
local w,h = self:getSize()
return scrollAmount > (barType=="vertical" and h or w) and math.floor(scrollAmount/(barType=="vertical" and h or w) * index) or index
end,
setSymbolSize = function(self, size)
symbolSize = tonumber(size) or 1
symbolAutoSize = size~=false and false or true
updateSymbolSize()
self:updateDraw()
return self
end,
getSymbolSize = function(self)
return symbolSize
end,
setBarType = function(self, _typ)
barType = _typ:lower()
updateSymbolSize()
self:updateDraw()
return self
end,
getBarType = function(self)
return barType
end,
mouseHandler = function(self, button, x, y, ...)
if (base.mouseHandler(self, button, x, y, ...)) then
mouseEvent(self, button, x, y)
return true
end
return false
end,
dragHandler = function(self, button, x, y)
if (base.dragHandler(self, button, x, y)) then
mouseEvent(self, button, x, y)
return true
end
return false
end,
setSize = function(self, ...)
base.setSize(self, ...)
updateSymbolSize()
return self
end,
scrollHandler = function(self, dir, x, y)
if(base.scrollHandler(self, dir, x, y))then
local w,h = self:getSize()
updateSymbolSize()
index = index + dir
if (index < 1) then
index = 1
end
index = math.min(index, (barType == "vertical" and h or w) - (barType == "vertical" and symbolSize - 1 or #symbol+symbolSize-2))
self:scrollbarMoveHandler()
self:updateDraw()
end
end,
onChange = function(self, ...)
for _,v in pairs(table.pack(...))do
if(type(v)=="function")then
self:registerEvent("scrollbar_moved", v)
end
end
return self
end,
scrollbarMoveHandler = function(self)
self:sendEvent("scrollbar_moved", self:getIndex())
end,
customEventHandler = function(self, event, ...)
base.customEventHandler(self, event, ...)
if(event=="basalt_FrameResize")then
updateSymbolSize()
end
end,
draw = function(self)
base.draw(self)
self:addDraw("scrollbar", function()
local parent = self:getParent()
local w,h = self:getSize()
local bgCol,fgCol = self:getBackground(), self:getForeground()
if (barType == "horizontal") then
for n = 0, h - 1 do
self:addBlit(index, 1 + n, symbol:rep(symbolSize), tHex[symbolFG]:rep(#symbol*symbolSize), tHex[symbolBG]:rep(#symbol*symbolSize))
end
elseif (barType == "vertical") then
for n = 0, h - 1 do
if (index == n + 1) then
for curIndexOffset = 0, math.min(symbolSize - 1, h) do
self:addBlit(1, index + curIndexOffset, symbol:rep(math.max(#symbol, w)), tHex[symbolFG]:rep(math.max(#symbol, w)), tHex[symbolBG]:rep(math.max(#symbol, w)))
end
end
end
end
end)
end,
}
object.__index = object
return setmetatable(object, base)
end