cc-utilities/gfx/progress.lua
2024-10-14 16:36:19 +02:00

116 lines
2.7 KiB
Lua

local Element = require("gfx.element")
local Prop = require("gfx.prop")
local Orientation = require("gfx.prop.orientation")
local BlankElement = Element:new()
function BlankElement:draw()
local dirty = Element.draw(self)
if dirty then
self:_getWindow().clear()
end
end
local function round(value, biasDown)
local decimal = value % 1
return (((not biasDown) and decimal < 0.5) or ((not not biasDown) and decimal <= 0.5)) and math.floor(value) or math.ceil(value)
end
local Progress = Element:new{
progress = 0.0,
active = nil,
inactive = nil
}
function Progress:new(o)
local template = o or {}
template.fgColor = template.fgColor or colors.red
template.bgColor = template.bgColor or colors.gray
local obj = Element.new(self, template)
obj.active = BlankElement:new()
obj.inactive = BlankElement:new()
obj:_refreshColors()
return obj
end
function Progress:setFgColor(color)
self.active:setBgColor(color)
end
function Progress:setBgColor(color)
self.inactive:setBgColor(color)
end
function Progress:_updateProgress()
local width, height = self:getWidth(), self:getHeight()
if self:isVertical() then
self.active:resize{
width = width,
height = round(self:getProgress() * height)
}
self.inactive:resize{
width = width,
height = round((1 - self:getProgress()) * height, true)
}
self.inactive:setY(self.active:getY() + self.active:getHeight())
else
self.active:resize{
width = round(self:getProgress() * width),
height = height
}
self.inactive:resize{
width = round((1 - self:getProgress()) * width, true),
height = height
}
self.inactive:setX(self.active:getX() + self.active:getWidth())
end
self:_refreshColors()
end
function Progress:_refreshColors()
self:setFgColor(self:getFgColor())
self:setBgColor(self:getBgColor())
end
function Progress:setProgress(progress)
self:setDirty()
self.progress = math.min(1, math.max(0, progress))
self:_updateProgress()
end
function Progress:getProgress()
return self.progress
end
function Progress:draw()
local dirty = Element.draw(self)
if dirty then
self.inactive:draw()
self.active:draw()
end
return dirty
end
function Progress:_isDirty()
return Element._isDirty(self) or self.active:_isDirty() or self.inactive:_isDirty()
end
function Progress:setDirty(fullInvalidate)
Element.setDirty(self, fullInvalidate)
self.active:setDirty(self, fullInvalidate)
self.inactive:setDirty(self, fullInvalidate)
end
function Progress:_reload()
Element._reload(self)
-- Reload child windows
local win = self:_getWindow()
self.active:setParent(win)
self.inactive:setParent(win)
self:_updateProgress()
end
return Prop.attach(Progress, Orientation, Orientation.HORIZONTAL)