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