feat: Lyra screens (#732)

Implements Lyra theme for some more Crosspoint screens:

![IMG_7960
Medium](https://github.com/user-attachments/assets/5d97d91d-e5eb-4296-bbf4-917e142d9095)
![IMG_7961
Medium](https://github.com/user-attachments/assets/02d61964-2632-45ff-83c7-48b95882eb9c)
![IMG_7962
Medium](https://github.com/user-attachments/assets/cf42d20f-3a85-4669-b497-1cac4653fa5a)
![IMG_7963
Medium](https://github.com/user-attachments/assets/a8f59c37-db70-407c-a06d-3e40613a0f55)
![IMG_7964
Medium](https://github.com/user-attachments/assets/0fdaac72-077a-48f6-a8c5-1cd806a58937)
![IMG_7965
Medium](https://github.com/user-attachments/assets/5169f037-8ba8-4488-9a8a-06f5146ec1d9)

- A bit of refactoring for list scrolling logic

---

While CrossPoint doesn't have restrictions on AI tools in contributing,
please be transparent about their usage as it
helps set the right context for reviewers.

Did you use AI tools to help write this code? _**NO**_

---------

Co-authored-by: Dave Allie <dave@daveallie.com>
This commit is contained in:
CaptainFrito
2026-02-19 17:16:55 +07:00
committed by cottongin
parent 21b81bd177
commit 724c1969b9
35 changed files with 645 additions and 531 deletions

View File

@@ -325,7 +325,9 @@ void GfxRenderer::fillRoundedRect(const int x, const int y, const int width, con
return;
}
const int maxRadius = std::min({cornerRadius, width / 2, height / 2});
// Assume if we're not rounding all corners then we are only rounding one side
const int roundedSides = (!roundTopLeft || !roundTopRight || !roundBottomLeft || !roundBottomRight) ? 1 : 2;
const int maxRadius = std::min({cornerRadius, width / roundedSides, height / roundedSides});
if (maxRadius <= 0) {
fillRectDither(x, y, width, height, color);
return;
@@ -336,10 +338,16 @@ void GfxRenderer::fillRoundedRect(const int x, const int y, const int width, con
fillRectDither(x + maxRadius + 1, y, horizontalWidth - 2, height, color);
}
const int verticalHeight = height - 2 * maxRadius - 2;
if (verticalHeight > 0) {
fillRectDither(x, y + maxRadius + 1, maxRadius + 1, verticalHeight, color);
fillRectDither(x + width - maxRadius - 1, y + maxRadius + 1, maxRadius + 1, verticalHeight, color);
const int leftFillTop = y + (roundTopLeft ? (maxRadius + 1) : 0);
const int leftFillBottom = y + height - 1 - (roundBottomLeft ? (maxRadius + 1) : 0);
if (leftFillBottom >= leftFillTop) {
fillRectDither(x, leftFillTop, maxRadius + 1, leftFillBottom - leftFillTop + 1, color);
}
const int rightFillTop = y + (roundTopRight ? (maxRadius + 1) : 0);
const int rightFillBottom = y + height - 1 - (roundBottomRight ? (maxRadius + 1) : 0);
if (rightFillBottom >= rightFillTop) {
fillRectDither(x + width - maxRadius - 1, rightFillTop, maxRadius + 1, rightFillBottom - rightFillTop + 1, color);
}
auto fillArcTemplated = [this](int maxRadius, int cx, int cy, int xDir, int yDir, Color color) {
@@ -363,26 +371,18 @@ void GfxRenderer::fillRoundedRect(const int x, const int y, const int width, con
if (roundTopLeft) {
fillArcTemplated(maxRadius, x + maxRadius, y + maxRadius, -1, -1, color);
} else {
fillRectDither(x, y, maxRadius + 1, maxRadius + 1, color);
}
if (roundTopRight) {
fillArcTemplated(maxRadius, x + width - maxRadius - 1, y + maxRadius, 1, -1, color);
} else {
fillRectDither(x + width - maxRadius - 1, y, maxRadius + 1, maxRadius + 1, color);
}
if (roundBottomRight) {
fillArcTemplated(maxRadius, x + width - maxRadius - 1, y + height - maxRadius - 1, 1, 1, color);
} else {
fillRectDither(x + width - maxRadius - 1, y + height - maxRadius - 1, maxRadius + 1, maxRadius + 1, color);
}
if (roundBottomLeft) {
fillArcTemplated(maxRadius, x + maxRadius, y + height - maxRadius - 1, -1, 1, color);
} else {
fillRectDither(x, y + height - maxRadius - 1, maxRadius + 1, maxRadius + 1, color);
}
}