local class = require('opus.class') local UI = require('opus.ui') UI.ProgressBar = class(UI.Window) UI.ProgressBar.defaults = { UIElement = 'ProgressBar', backgroundColor = 'gray', height = 1, progressColor = 'lime', progressChar = UI.extChars and '\153' or ' ', fillChar = ' ', fillColor = 'gray', textColor = 'green', value = 0, showText = false, -- display value text overlay centered on bar textOverlay = nil, -- custom overlay text (string or function(value) -> string) textOverlayColor = 'white', -- text overlay foreground color } function UI.ProgressBar:draw() local width = math.ceil(self.value / 100 * self.width) self:fillArea(width + 1, 1, self.width - width, self.height, self.fillChar, nil, self.fillColor) self:fillArea(1, 1, width, self.height, self.progressChar, self.progressColor) if self.showText then local text if self.textOverlay then text = type(self.textOverlay) == 'function' and self.textOverlay(self.value) or tostring(self.textOverlay) else text = math.floor(self.value) .. '%' end local midY = math.ceil(self.height / 2) local x = math.floor((self.width - #text) / 2) + 1 for i = 1, #text do local cx = x + i - 1 if cx >= 1 and cx <= self.width then local bg = cx <= width and self.progressColor or self.fillColor self:write(cx, midY, text:sub(i, i), bg, self.textOverlayColor) end end end end function UI.ProgressBar.example() return UI.ProgressBar { x = 2, ex = -2, y = 2, height = 2, focus = function() end, enable = function(self) require('opus.event').onInterval(.25, function() self.value = self.value == 100 and 0 or self.value + 5 self:draw() self:sync() end) return UI.ProgressBar.enable(self) end } end