Merge branch 'x3-support'

# Conflicts:
#	lib/GfxRenderer/GfxRenderer.h
#	open-x4-sdk
This commit is contained in:
jpirnay
2026-04-04 10:05:14 +02:00
16 changed files with 564 additions and 132 deletions
+39 -23
View File
@@ -347,7 +347,10 @@ void LyraTheme::drawButtonHints(GfxRenderer& renderer, const char* btn1, const c
constexpr int buttonHeight = LyraMetrics::values.buttonHintsHeight;
constexpr int buttonY = LyraMetrics::values.buttonHintsHeight; // Distance from bottom
constexpr int textYOffset = 7; // Distance from top of button to text baseline
constexpr int buttonPositions[] = {58, 146, 254, 342};
// X3 has wider screen in portrait (528 vs 480), use more spacing
constexpr int x4ButtonPositions[] = {58, 146, 254, 342};
constexpr int x3ButtonPositions[] = {65, 157, 291, 383};
const int* buttonPositions = gpio.deviceIsX3() ? x3ButtonPositions : x4ButtonPositions;
const char* labels[] = {btn1, btn2, btn3, btn4};
for (int i = 0; i < 4; i++) {
@@ -376,34 +379,47 @@ void LyraTheme::drawSideButtonHints(const GfxRenderer& renderer, const char* top
const int screenWidth = renderer.getScreenWidth();
constexpr int buttonWidth = LyraMetrics::values.sideButtonHintsWidth; // Width on screen (height when rotated)
constexpr int buttonHeight = 78; // Height on screen (width when rotated)
// Position for the button group - buttons share a border so they're adjacent
constexpr int buttonMargin = 0;
const char* labels[] = {topBtn, bottomBtn};
if (gpio.deviceIsX3()) {
// X3 layout: Up on left side, Down on right side, positioned higher
constexpr int x3ButtonY = 155;
// Draw the shared border for both buttons as one unit
const int x = screenWidth - buttonWidth;
if (topBtn != nullptr && topBtn[0] != '\0') {
renderer.drawRoundedRect(buttonMargin, x3ButtonY, buttonWidth, buttonHeight, 1, cornerRadius, false, true, false,
true, true);
const int textWidth = renderer.getTextWidth(SMALL_FONT_ID, topBtn);
renderer.drawTextRotated90CW(SMALL_FONT_ID, buttonMargin, x3ButtonY + (buttonHeight + textWidth) / 2, topBtn);
}
// Draw top button outline
if (topBtn != nullptr && topBtn[0] != '\0') {
renderer.drawRoundedRect(x, topHintButtonY, buttonWidth, buttonHeight, 1, cornerRadius, true, false, true, false,
true);
}
if (bottomBtn != nullptr && bottomBtn[0] != '\0') {
const int rightX = screenWidth - buttonWidth;
renderer.drawRoundedRect(rightX, x3ButtonY, buttonWidth, buttonHeight, 1, cornerRadius, true, false, true, false,
true);
const int textWidth = renderer.getTextWidth(SMALL_FONT_ID, bottomBtn);
renderer.drawTextRotated90CW(SMALL_FONT_ID, rightX, x3ButtonY + (buttonHeight + textWidth) / 2, bottomBtn);
}
} else {
// X4 layout: Both buttons stacked on right side
const char* labels[] = {topBtn, bottomBtn};
const int x = screenWidth - buttonWidth;
// Draw bottom button outline
if (bottomBtn != nullptr && bottomBtn[0] != '\0') {
renderer.drawRoundedRect(x, topHintButtonY + buttonHeight + 5, buttonWidth, buttonHeight, 1, cornerRadius, true,
false, true, false, true);
}
if (topBtn != nullptr && topBtn[0] != '\0') {
renderer.drawRoundedRect(x, topHintButtonY, buttonWidth, buttonHeight, 1, cornerRadius, true, false, true, false,
true);
}
// Draw text for each button
for (int i = 0; i < 2; i++) {
if (labels[i] != nullptr && labels[i][0] != '\0') {
const int y = topHintButtonY + (i * buttonHeight + 5);
if (bottomBtn != nullptr && bottomBtn[0] != '\0') {
renderer.drawRoundedRect(x, topHintButtonY + buttonHeight + 5, buttonWidth, buttonHeight, 1, cornerRadius, true,
false, true, false, true);
}
// Draw rotated text centered in the button
const int textWidth = renderer.getTextWidth(SMALL_FONT_ID, labels[i]);
renderer.drawTextRotated90CW(SMALL_FONT_ID, x, y + (buttonHeight + textWidth) / 2, labels[i]);
for (int i = 0; i < 2; i++) {
if (labels[i] != nullptr && labels[i][0] != '\0') {
const int y = topHintButtonY + (i * buttonHeight) + 5;
const int textWidth = renderer.getTextWidth(SMALL_FONT_ID, labels[i]);
renderer.drawTextRotated90CW(SMALL_FONT_ID, x, y + (buttonHeight + textWidth) / 2, labels[i]);
}
}
}
}