Progress bars can show the percentage on top

The percentage (rounded down, in the element's font) is centred inside the
bar and its dots invert the bar, so it reads on the filled and the empty
part. It uses the bar's unused format and font fields, so the page format
stays the same. The Bad page shows it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
mangavalkandClaude Opus 5.5 committed 2026-10-18 16:27:56 +02:00
1 parent 9959c1aa74
commit 948087077d
9 files changed
+187 -9

No files matched your search

+34
View File
@@ -90,6 +90,38 @@ static void drawImage(const PageElement &e, PageResources &resources, uint8_t *b
}
}
// Bar with BAR_PERCENT: the percentage in the middle of the area inside the frame, its
// dots flip what is below them (so it shows on the filled and the empty part). Centred on
// the dots the text really has (fonts have empty rows); left out when it doesn't fit.
static void drawBarPercent(const PageElement &e, PageResources &resources, uint8_t *bitmap, int x, int y, int w,
int h)
{
char text[8];
barPercent(e, resources.haValue(e), text, sizeof(text));
Font font = usableFont(resources, e.font);
uint8_t dots[BITMAP_BYTES];
memset(dots, 0, BITMAP_BYTES);
drawText(dots, font, 0, 0, text, DrawMode::Set);
int left = BITMAP_WIDTH, right = -1, top = BITMAP_HEIGHT, bottom = -1;
for (int yy = 0; yy < BITMAP_HEIGHT; yy++)
for (int xx = 0; xx < BITMAP_WIDTH; xx++)
if (bitmapPixel(dots, xx, yy))
{
left = xx < left ? xx : left;
right = xx > right ? xx : right;
top = yy < top ? yy : top;
bottom = yy > bottom ? yy : bottom;
}
int tw = right - left + 1, th = bottom - top + 1;
if (right < 0 || tw > w || th > h)
return;
int ox = x + (w - tw) / 2 - left, oy = y + (h - th) / 2 - top;
for (int yy = top; yy <= bottom; yy++)
for (int xx = left; xx <= right; xx++)
if (bitmapPixel(dots, xx, yy))
setBitmapPixel(bitmap, ox + xx, oy + yy, !bitmapPixel(bitmap, ox + xx, oy + yy));
}
// Bar: a frame (optional) filled from the left by the Home Assistant value
static void drawBar(const PageElement &e, PageResources &resources, uint8_t *bitmap, ElementBox &box)
{
@@ -120,6 +152,8 @@ static void drawBar(const PageElement &e, PageResources &resources, uint8_t *bit
int bx = left + x, by = e.y + y;
setBitmapPixel(bitmap, bx, by, e.overlay == Overlay::Invert ? !bitmapPixel(bitmap, bx, by) : true);
}
if (e.format == BAR_PERCENT)
drawBarPercent(e, resources, bitmap, left + inner, e.y + inner, w - 2 * inner, h - 2 * inner);
}
// A text element; returns the ms until it scrolls on (0: it doesn't scroll)