diff --git a/sys/modules/opus/ui/components/Grid.lua b/sys/modules/opus/ui/components/Grid.lua index 80189f5..e84246c 100644 --- a/sys/modules/opus/ui/components/Grid.lua +++ b/sys/modules/opus/ui/components/Grid.lua @@ -26,6 +26,28 @@ function Writer:write(s, width, align, bg, fg) self.x = self.x + width end +function Writer:writeBar(width, ratio, barColor, emptyColor, text, textColor) + local filled = math.floor(ratio * width) + local empty = width - filled + if filled > 0 then + self.element:write(self.x, self.y, _rep(' ', filled), barColor) + end + if empty > 0 then + self.element:write(self.x + filled, self.y, _rep(' ', empty), emptyColor) + end + if text and #text > 0 and textColor then + local tx = self.x + math.floor((width - #text) / 2) + for i = 1, #text do + local cx = tx + i - 1 + if cx >= self.x and cx < self.x + width then + local bg = (cx - self.x) < filled and barColor or emptyColor + self.element:write(cx, self.y, text:sub(i, i), bg, textColor) + end + end + end + self.x = self.x + width +end + function Writer:finish(bg) if self.x <= self.element.width then self.element:write(self.x, self.y, _rep(' ', self.element.width - self.x + 1), bg) @@ -47,6 +69,7 @@ UI.Grid.defaults = { textSelectedColor = 'white', backgroundColor = 'black', backgroundSelectedColor = 'gray', + alternateRowColor = nil, headerBackgroundColor = 'primary', headerTextColor = 'white', headerSortColor = 'yellow', @@ -317,7 +340,7 @@ function UI.Grid:drawRows() local row = self:getDisplayValues(rawRow, key) local selected = index == self.index and not self.inactive - local bg = self:getRowBackgroundColor(rawRow, selected) + local bg = self:getRowBackgroundColor(rawRow, selected, index) local fg = self:getRowTextColor(rawRow, selected) local focused = self.focused and selected @@ -335,11 +358,25 @@ function UI.Grid:drawRow(sb, row, focused, bg, fg) local ind = focused and self.focusIndicator or ' ' for _,col in pairs(self.columns) do - sb:write(ind .. safeValue(row[col.key] or ''), - col.cw + 1, - col.align, - col.backgroundColor or bg, - col.textColor or fg) + if col.barColumn then + -- Bar column: render a colored fill bar + local ratio = tonumber(row[col.key]) or 0 + ratio = math.max(0, math.min(1, ratio)) + local barColor = col.barColor or colors.lime + local emptyColor = col.barEmptyColor or bg + if type(col.barColor) == 'function' then + barColor = col.barColor(row, ratio) + end + local barText = col.barText and (type(col.barText) == 'function' and col.barText(row, ratio) or col.barText) or nil + sb:write(ind, 1, nil, bg, fg) + sb:writeBar(col.cw, ratio, barColor, emptyColor, barText, col.barTextColor or colors.white) + else + sb:write(ind .. safeValue(row[col.key] or ''), + col.cw + 1, + col.align, + col.backgroundColor or bg, + col.textColor or fg) + end ind = ' ' end end @@ -354,13 +391,16 @@ function UI.Grid:getRowTextColor(row, selected) return self.textColor end -function UI.Grid:getRowBackgroundColor(row, selected) +function UI.Grid:getRowBackgroundColor(row, selected, index) if selected then if self.focused then return self.backgroundSelectedColor end return self.unfocusedBackgroundSelectedColor end + if self.alternateRowColor and index then + return index % 2 == 0 and self.alternateRowColor or self.backgroundColor + end return self.backgroundColor end