Compare commits

..

1 Commits

Author SHA1 Message Date
CaptainFrito
cc483dc281
Merge 9443edfe14 into da4d3b5ea5 2026-01-29 06:54:39 +00:00
8 changed files with 39 additions and 67 deletions

View File

@ -233,7 +233,7 @@ void MyLibraryActivity::render() const {
UITheme::drawHeader(renderer, Rect{0, metrics.topPadding, pageWidth, metrics.headerHeight}, folderName);
UITheme::drawTabBar(renderer, Rect{0, metrics.topPadding + metrics.headerHeight, pageWidth, metrics.tabBarHeight},
{{"Recent", currentTab == Tab::Recent}, {"Files", currentTab == Tab::Files}}, false);
{{"Recent", currentTab == Tab::Recent}, {"Files", currentTab == Tab::Files}});
const int contentTop = metrics.topPadding + metrics.headerHeight + metrics.tabBarHeight + metrics.verticalSpacing;
const int contentHeight = pageHeight - contentTop - metrics.buttonHintsHeight - metrics.verticalSpacing * 2;

View File

@ -110,19 +110,12 @@ void SettingsActivity::loop() {
subActivity->loop();
return;
}
bool hasChangedCategory = false;
// Handle actions with early return
if (mappedInput.wasPressed(MappedInputManager::Button::Confirm)) {
if (selectedSettingIndex == 0) {
selectedCategoryIndex = (selectedCategoryIndex < categoryCount - 1) ? (selectedCategoryIndex + 1) : 0;
hasChangedCategory = true;
updateRequired = true;
} else {
toggleCurrentSetting();
updateRequired = true;
return;
}
toggleCurrentSetting();
updateRequired = true;
return;
}
if (mappedInput.wasPressed(MappedInputManager::Button::Back)) {
@ -131,13 +124,14 @@ void SettingsActivity::loop() {
return;
}
bool hasChangedCategory = false;
// Handle navigation
if (mappedInput.wasPressed(MappedInputManager::Button::Left)) {
selectedSettingIndex = (selectedSettingIndex > 0) ? (selectedSettingIndex - 1) : (settingsCount);
selectedSettingIndex = (selectedSettingIndex > 0) ? (selectedSettingIndex - 1) : (settingsCount - 1);
updateRequired = true;
} else if (mappedInput.wasPressed(MappedInputManager::Button::Right)) {
selectedSettingIndex = (selectedSettingIndex < settingsCount) ? (selectedSettingIndex + 1) : 0;
selectedSettingIndex = (selectedSettingIndex < settingsCount - 1) ? (selectedSettingIndex + 1) : 0;
updateRequired = true;
} else if (mappedInput.wasPressed(MappedInputManager::Button::Up)) {
hasChangedCategory = true;
@ -150,7 +144,7 @@ void SettingsActivity::loop() {
}
if (hasChangedCategory) {
selectedSettingIndex = (selectedSettingIndex == 0) ? 0 : 1;
selectedSettingIndex = 0;
switch (selectedCategoryIndex) {
case 0: // Display
settingsList = displaySettings;
@ -173,12 +167,11 @@ void SettingsActivity::loop() {
}
void SettingsActivity::toggleCurrentSetting() {
int selectedSetting = selectedSettingIndex - 1;
if (selectedSetting < 0 || selectedSetting >= settingsCount) {
if (selectedSettingIndex < 0 || selectedSettingIndex >= settingsCount) {
return;
}
const auto& setting = settingsList[selectedSetting];
const auto& setting = settingsList[selectedSettingIndex];
if (setting.type == SettingType::TOGGLE && setting.valuePtr != nullptr) {
// Toggle the boolean value using the member pointer
@ -263,14 +256,14 @@ void SettingsActivity::render() const {
tabs.push_back({categoryNames[i], selectedCategoryIndex == i});
}
UITheme::drawTabBar(renderer, Rect{0, metrics.topPadding + metrics.headerHeight, pageWidth, metrics.tabBarHeight},
tabs, selectedSettingIndex == 0);
tabs);
UITheme::drawList(
renderer,
Rect{0, metrics.topPadding + metrics.headerHeight + metrics.tabBarHeight + metrics.verticalSpacing, pageWidth,
pageHeight - (metrics.topPadding + metrics.headerHeight + metrics.tabBarHeight + metrics.buttonHintsHeight +
metrics.verticalSpacing * 2)},
settingsCount, selectedSettingIndex - 1, [this](int index) { return std::string(settingsList[index].name); }, false,
settingsCount, selectedSettingIndex, [this](int index) { return std::string(settingsList[index].name); }, false,
nullptr, true,
[this](int i) {
const auto& setting = settingsList[i];
@ -293,7 +286,7 @@ void SettingsActivity::render() const {
metrics.versionTextY, CROSSPOINT_VERSION);
// Draw help text
const auto labels = mappedInput.mapLabels("« Back", selectedSettingIndex == 0 ? "Tab >" : "Toggle", "Up", "Down");
const auto labels = mappedInput.mapLabels("« Back", "Select", "Up", "Down");
UITheme::drawButtonHints(renderer, labels.btn1, labels.btn2, labels.btn3, labels.btn4);
UITheme::drawSideButtonHints(renderer, "^", "v");

View File

@ -89,9 +89,9 @@ void UITheme::drawHeader(const GfxRenderer& renderer, Rect rect, const char* tit
}
}
void UITheme::drawTabBar(const GfxRenderer& renderer, const Rect rect, const std::vector<TabInfo>& tabs, bool selected) {
void UITheme::drawTabBar(const GfxRenderer& renderer, const Rect rect, const std::vector<TabInfo>& tabs) {
if (currentTheme != nullptr) {
currentTheme->drawTabBar(renderer, rect, tabs, selected);
currentTheme->drawTabBar(renderer, rect, tabs);
}
}

View File

@ -81,7 +81,7 @@ class UITheme {
const std::function<std::string(int index)>& rowIcon, bool hasValue,
const std::function<std::string(int index)>& rowValue);
static void drawHeader(const GfxRenderer& renderer, Rect rect, const char* title);
static void drawTabBar(const GfxRenderer& renderer, Rect rect, const std::vector<TabInfo>& tabs, bool selected);
static void drawTabBar(const GfxRenderer& renderer, Rect rect, const std::vector<TabInfo>& tabs);
static void drawRecentBookCover(GfxRenderer& renderer, Rect rect, const std::vector<RecentBookWithCover>& recentBooks,
const int selectorIndex, bool& coverRendered, bool& coverBufferStored,
bool& bufferRestored, std::function<bool()> storeCoverBuffer);

View File

@ -191,9 +191,7 @@ void BaseTheme::drawList(const GfxRenderer& renderer, Rect rect, int itemCount,
// Draw selection
int contentWidth = rect.width - BaseMetrics::values.sideButtonHintsWidth - 5;
if (selectedIndex >= 0) {
renderer.fillRect(0, rect.y + selectedIndex % pageItems * rowHeight - 2, contentWidth, rowHeight);
}
renderer.fillRect(0, rect.y + selectedIndex % pageItems * rowHeight - 2, contentWidth, rowHeight);
// Draw all items
const auto pageStartIndex = selectedIndex / pageItems * pageItems;
for (int i = pageStartIndex; i < itemCount && i < pageStartIndex + pageItems; i++) {
@ -234,7 +232,7 @@ void BaseTheme::drawHeader(const GfxRenderer& renderer, Rect rect, const char* t
}
}
void BaseTheme::drawTabBar(const GfxRenderer& renderer, const Rect rect, const std::vector<TabInfo>& tabs, bool selected) {
void BaseTheme::drawTabBar(const GfxRenderer& renderer, const Rect rect, const std::vector<TabInfo>& tabs) {
constexpr int underlineHeight = 2; // Height of selection underline
constexpr int underlineGap = 4; // Gap between text and underline
@ -246,19 +244,15 @@ void BaseTheme::drawTabBar(const GfxRenderer& renderer, const Rect rect, const s
const int textWidth =
renderer.getTextWidth(UI_12_FONT_ID, tab.label, tab.selected ? EpdFontFamily::BOLD : EpdFontFamily::REGULAR);
// Draw tab label
renderer.drawText(UI_12_FONT_ID, currentX, rect.y, tab.label, true,
tab.selected ? EpdFontFamily::BOLD : EpdFontFamily::REGULAR);
// Draw underline for selected tab
if (tab.selected) {
if (selected) {
renderer.fillRect(currentX - 3, rect.y, textWidth + 6, lineHeight + underlineGap);
} else {
renderer.fillRect(currentX, rect.y + lineHeight + underlineGap, textWidth, underlineHeight);
}
renderer.fillRect(currentX, rect.y + lineHeight + underlineGap, textWidth, underlineHeight);
}
// Draw tab label
renderer.drawText(UI_12_FONT_ID, currentX, rect.y, tab.label, !(tab.selected && selected),
tab.selected ? EpdFontFamily::BOLD : EpdFontFamily::REGULAR);
currentX += textWidth + BaseMetrics::values.tabSpacing;
}
}

View File

@ -53,7 +53,7 @@ class BaseTheme {
const std::function<std::string(int index)>& rowValue);
virtual void drawHeader(const GfxRenderer& renderer, Rect rect, const char* title);
virtual void drawTabBar(const GfxRenderer& renderer, Rect rect, const std::vector<TabInfo>& tabs, bool selected);
virtual void drawTabBar(const GfxRenderer& renderer, Rect rect, const std::vector<TabInfo>& tabs);
virtual void drawRecentBookCover(GfxRenderer& renderer, Rect rect,
const std::vector<RecentBookWithCover>& recentBooks, const int selectorIndex,
bool& coverRendered, bool& coverBufferStored, bool& bufferRestored,

View File

@ -78,30 +78,21 @@ void LyraTheme::drawHeader(const GfxRenderer& renderer, Rect rect, const char* t
}
}
void LyraTheme::drawTabBar(const GfxRenderer& renderer, Rect rect, const std::vector<TabInfo>& tabs, bool selected) {
void LyraTheme::drawTabBar(const GfxRenderer& renderer, Rect rect, const std::vector<TabInfo>& tabs) {
int currentX = rect.x + LyraMetrics::values.contentSidePadding;
if (selected) {
renderer.fillRectDither(rect.x, rect.y, rect.width, rect.height, COLOR_LIGHT_GRAY);
}
for (const auto& tab : tabs) {
const int textWidth = renderer.getTextWidth(UI_10_FONT_ID, tab.label, EpdFontFamily::REGULAR);
// Draw tab label
renderer.drawText(UI_10_FONT_ID, currentX, rect.y + 6, tab.label, true, EpdFontFamily::REGULAR);
// Draw underline for selected tab
if (tab.selected) {
if (selected) {
renderer.fillRoundedRect(currentX, rect.y + 1, textWidth + 2 * hPaddingInSelection, rect.height - 4,
cornerRadius, COLOR_BLACK);
} else {
renderer.fillRectDither(currentX, rect.y, textWidth + 2 * hPaddingInSelection, rect.height - 3, COLOR_LIGHT_GRAY);
renderer.drawLine(currentX, rect.y + rect.height - 3, currentX + textWidth + 2 * hPaddingInSelection, rect.y + rect.height - 3, 2, true);
}
renderer.drawLine(currentX, rect.y + rect.height - 2, currentX + textWidth, rect.y + rect.height - 2, true);
}
renderer.drawText(UI_10_FONT_ID, currentX + hPaddingInSelection, rect.y + 6, tab.label, !(tab.selected && selected), EpdFontFamily::REGULAR);
currentX += textWidth + LyraMetrics::values.tabSpacing + 2 * hPaddingInSelection;
currentX += textWidth + LyraMetrics::values.tabSpacing;
}
renderer.drawLine(rect.x, rect.y + rect.height - 1, rect.x + rect.width, rect.y + rect.height - 1, true);
@ -132,11 +123,9 @@ void LyraTheme::drawList(const GfxRenderer& renderer, Rect rect, int itemCount,
int contentWidth =
rect.width -
(totalPages > 1 ? (LyraMetrics::values.scrollBarWidth + LyraMetrics::values.scrollBarRightOffset) : 1);
if (selectedIndex >= 0) {
renderer.fillRoundedRect(LyraMetrics::values.contentSidePadding, rect.y + selectedIndex % pageItems * rowHeight,
renderer.fillRoundedRect(LyraMetrics::values.contentSidePadding, rect.y + selectedIndex % pageItems * rowHeight,
contentWidth - LyraMetrics::values.contentSidePadding * 2, rowHeight, cornerRadius,
COLOR_LIGHT_GRAY);
}
// Draw all items
const auto pageStartIndex = selectedIndex / pageItems * pageItems;
@ -180,26 +169,22 @@ void LyraTheme::drawButtonHints(const GfxRenderer& renderer, const char* btn1, c
const int pageHeight = renderer.getScreenHeight();
constexpr int buttonWidth = 80;
constexpr int smallButtonHeight = 15;
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};
constexpr int buttonPositions[] = {68, 156, 244, 332};
const char* labels[] = {btn1, btn2, btn3, btn4};
for (int i = 0; i < 4; i++) {
// Only draw if the label is non-empty
const int x = buttonPositions[i];
renderer.fillRect(x, pageHeight - buttonY, buttonWidth, buttonHeight, false);
if (labels[i] != nullptr && labels[i][0] != '\0') {
const int x = buttonPositions[i];
renderer.fillRect(x, pageHeight - buttonY, buttonWidth, buttonHeight, false);
renderer.drawRoundedRect(x, pageHeight - buttonY, buttonWidth, buttonHeight, 1, cornerRadius, true, true, false,
false, true);
const int textWidth = renderer.getTextWidth(SMALL_FONT_ID, labels[i]);
const int textX = x + (buttonWidth - 1 - textWidth) / 2;
renderer.drawText(SMALL_FONT_ID, textX, pageHeight - buttonY + textYOffset, labels[i]);
} else {
renderer.drawRoundedRect(x, pageHeight - smallButtonHeight, buttonWidth, smallButtonHeight, 1, cornerRadius, true, true, false,
false, true);
}
}
@ -209,7 +194,7 @@ void LyraTheme::drawButtonHints(const GfxRenderer& renderer, const char* btn1, c
void LyraTheme::drawSideButtonHints(const GfxRenderer& renderer, const char* topBtn, const char* bottomBtn) {
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)
constexpr int buttonHeight = 80; // Height on screen (width when rotated)
// Position for the button group - buttons share a border so they're adjacent
const char* labels[] = {topBtn, bottomBtn};

View File

@ -16,7 +16,7 @@ constexpr ThemeMetrics values = {.batteryWidth = 16,
.listRowHeight = 40,
.menuRowHeight = 64,
.menuSpacing = 8,
.tabSpacing = 8,
.tabSpacing = 20,
.tabBarHeight = 40,
.scrollBarWidth = 4,
.scrollBarRightOffset = 5,
@ -36,7 +36,7 @@ class LyraTheme : public BaseTheme {
// void drawProgressBar(const GfxRenderer& renderer, Rect rect, size_t current, size_t total) override;
void drawBattery(const GfxRenderer& renderer, Rect rect, bool showPercentage = true) override;
void drawHeader(const GfxRenderer& renderer, Rect rect, const char* title) override;
void drawTabBar(const GfxRenderer& renderer, Rect rect, const std::vector<TabInfo>& tabs, bool selected) override;
void drawTabBar(const GfxRenderer& renderer, Rect rect, const std::vector<TabInfo>& tabs) override;
void drawList(const GfxRenderer& renderer, Rect rect, int itemCount, int selectedIndex,
const std::function<std::string(int index)>& rowTitle, bool hasIcon,
const std::function<std::string(int index)>& rowIcon, bool hasValue,