From 30b56eb977d0c84447c9d8831b9423192e9156a8 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 31 Jan 2026 20:39:38 +0000 Subject: [PATCH] Add Chapter Progress Bar status bar option Co-authored-by: lukestein <44452336+lukestein@users.noreply.github.com> --- src/CrossPointSettings.h | 1 + src/ScreenComponents.cpp | 11 +++++++++++ src/ScreenComponents.h | 1 + src/activities/reader/EpubReaderActivity.cpp | 20 +++++++++++++++++--- src/activities/reader/TxtReaderActivity.cpp | 17 ++++++++++++++--- src/activities/settings/SettingsActivity.cpp | 3 ++- 6 files changed, 46 insertions(+), 7 deletions(-) diff --git a/src/CrossPointSettings.h b/src/CrossPointSettings.h index c450d348..fed2401e 100644 --- a/src/CrossPointSettings.h +++ b/src/CrossPointSettings.h @@ -31,6 +31,7 @@ class CrossPointSettings { FULL = 2, FULL_WITH_PROGRESS_BAR = 3, ONLY_PROGRESS_BAR = 4, + CHAPTER_PROGRESS_BAR = 5, STATUS_BAR_MODE_COUNT }; diff --git a/src/ScreenComponents.cpp b/src/ScreenComponents.cpp index 72f7faf0..8db98822 100644 --- a/src/ScreenComponents.cpp +++ b/src/ScreenComponents.cpp @@ -85,6 +85,17 @@ void ScreenComponents::drawBookProgressBar(const GfxRenderer& renderer, const si renderer.fillRect(vieweableMarginLeft, progressBarY, barWidth, BOOK_PROGRESS_BAR_HEIGHT, true); } +void ScreenComponents::drawChapterProgressBar(const GfxRenderer& renderer, const size_t chapterProgress) { + int vieweableMarginTop, vieweableMarginRight, vieweableMarginBottom, vieweableMarginLeft; + renderer.getOrientedViewableTRBL(&vieweableMarginTop, &vieweableMarginRight, &vieweableMarginBottom, + &vieweableMarginLeft); + + const int progressBarMaxWidth = renderer.getScreenWidth() - vieweableMarginLeft - vieweableMarginRight; + const int progressBarY = renderer.getScreenHeight() - vieweableMarginBottom - BOOK_PROGRESS_BAR_HEIGHT; + const int barWidth = progressBarMaxWidth * chapterProgress / 100; + renderer.fillRect(vieweableMarginLeft, progressBarY, barWidth, BOOK_PROGRESS_BAR_HEIGHT, true); +} + int ScreenComponents::drawTabBar(const GfxRenderer& renderer, const int y, const std::vector& tabs) { constexpr int tabPadding = 20; // Horizontal padding between tabs constexpr int leftMargin = 20; // Left margin for first tab diff --git a/src/ScreenComponents.h b/src/ScreenComponents.h index 78ed5920..d3bdcbeb 100644 --- a/src/ScreenComponents.h +++ b/src/ScreenComponents.h @@ -24,6 +24,7 @@ class ScreenComponents { static void drawBattery(const GfxRenderer& renderer, int left, int top, bool showPercentage = true); static void drawBookProgressBar(const GfxRenderer& renderer, size_t bookProgress); + static void drawChapterProgressBar(const GfxRenderer& renderer, size_t chapterProgress); static PopupLayout drawPopup(const GfxRenderer& renderer, const char* message); diff --git a/src/activities/reader/EpubReaderActivity.cpp b/src/activities/reader/EpubReaderActivity.cpp index 5ccfb4fe..2b4b9211 100644 --- a/src/activities/reader/EpubReaderActivity.cpp +++ b/src/activities/reader/EpubReaderActivity.cpp @@ -495,14 +495,18 @@ void EpubReaderActivity::renderStatusBar(const int orientedMarginRight, const in const bool showProgressPercentage = SETTINGS.statusBar == CrossPointSettings::STATUS_BAR_MODE::FULL; const bool showProgressBar = SETTINGS.statusBar == CrossPointSettings::STATUS_BAR_MODE::FULL_WITH_PROGRESS_BAR || SETTINGS.statusBar == CrossPointSettings::STATUS_BAR_MODE::ONLY_PROGRESS_BAR; + const bool showChapterProgressBar = SETTINGS.statusBar == CrossPointSettings::STATUS_BAR_MODE::CHAPTER_PROGRESS_BAR; const bool showProgressText = SETTINGS.statusBar == CrossPointSettings::STATUS_BAR_MODE::FULL || SETTINGS.statusBar == CrossPointSettings::STATUS_BAR_MODE::FULL_WITH_PROGRESS_BAR; + const bool showBookPercentage = SETTINGS.statusBar == CrossPointSettings::STATUS_BAR_MODE::CHAPTER_PROGRESS_BAR; const bool showBattery = SETTINGS.statusBar == CrossPointSettings::STATUS_BAR_MODE::NO_PROGRESS || SETTINGS.statusBar == CrossPointSettings::STATUS_BAR_MODE::FULL || - SETTINGS.statusBar == CrossPointSettings::STATUS_BAR_MODE::FULL_WITH_PROGRESS_BAR; + SETTINGS.statusBar == CrossPointSettings::STATUS_BAR_MODE::FULL_WITH_PROGRESS_BAR || + SETTINGS.statusBar == CrossPointSettings::STATUS_BAR_MODE::CHAPTER_PROGRESS_BAR; const bool showChapterTitle = SETTINGS.statusBar == CrossPointSettings::STATUS_BAR_MODE::NO_PROGRESS || SETTINGS.statusBar == CrossPointSettings::STATUS_BAR_MODE::FULL || - SETTINGS.statusBar == CrossPointSettings::STATUS_BAR_MODE::FULL_WITH_PROGRESS_BAR; + SETTINGS.statusBar == CrossPointSettings::STATUS_BAR_MODE::FULL_WITH_PROGRESS_BAR || + SETTINGS.statusBar == CrossPointSettings::STATUS_BAR_MODE::CHAPTER_PROGRESS_BAR; const bool showBatteryPercentage = SETTINGS.hideBatteryPercentage == CrossPointSettings::HIDE_BATTERY_PERCENTAGE::HIDE_NEVER; @@ -515,7 +519,7 @@ void EpubReaderActivity::renderStatusBar(const int orientedMarginRight, const in const float sectionChapterProg = static_cast(section->currentPage) / section->pageCount; const float bookProgress = epub->calculateProgress(currentSpineIndex, sectionChapterProg) * 100; - if (showProgressText || showProgressPercentage) { + if (showProgressText || showProgressPercentage || showBookPercentage) { // Right aligned text for progress counter char progressStr[32]; @@ -523,6 +527,8 @@ void EpubReaderActivity::renderStatusBar(const int orientedMarginRight, const in if (showProgressPercentage) { snprintf(progressStr, sizeof(progressStr), "%d/%d %.0f%%", section->currentPage + 1, section->pageCount, bookProgress); + } else if (showBookPercentage) { + snprintf(progressStr, sizeof(progressStr), "%.0f%%", bookProgress); } else { snprintf(progressStr, sizeof(progressStr), "%d/%d", section->currentPage + 1, section->pageCount); } @@ -537,6 +543,14 @@ void EpubReaderActivity::renderStatusBar(const int orientedMarginRight, const in ScreenComponents::drawBookProgressBar(renderer, static_cast(bookProgress)); } + if (showChapterProgressBar) { + // Draw chapter progress bar at the very bottom of the screen, from edge to edge of viewable area + const float chapterProgress = (section->pageCount > 0) + ? (static_cast(section->currentPage + 1) / section->pageCount) * 100 + : 0; + ScreenComponents::drawChapterProgressBar(renderer, static_cast(chapterProgress)); + } + if (showBattery) { ScreenComponents::drawBattery(renderer, orientedMarginLeft + 1, textY, showBatteryPercentage); } diff --git a/src/activities/reader/TxtReaderActivity.cpp b/src/activities/reader/TxtReaderActivity.cpp index eb1a9eef..f851dca8 100644 --- a/src/activities/reader/TxtReaderActivity.cpp +++ b/src/activities/reader/TxtReaderActivity.cpp @@ -487,14 +487,18 @@ void TxtReaderActivity::renderStatusBar(const int orientedMarginRight, const int const bool showProgressPercentage = SETTINGS.statusBar == CrossPointSettings::STATUS_BAR_MODE::FULL; const bool showProgressBar = SETTINGS.statusBar == CrossPointSettings::STATUS_BAR_MODE::FULL_WITH_PROGRESS_BAR || SETTINGS.statusBar == CrossPointSettings::STATUS_BAR_MODE::ONLY_PROGRESS_BAR; + const bool showChapterProgressBar = SETTINGS.statusBar == CrossPointSettings::STATUS_BAR_MODE::CHAPTER_PROGRESS_BAR; const bool showProgressText = SETTINGS.statusBar == CrossPointSettings::STATUS_BAR_MODE::FULL || SETTINGS.statusBar == CrossPointSettings::STATUS_BAR_MODE::FULL_WITH_PROGRESS_BAR; + const bool showBookPercentage = SETTINGS.statusBar == CrossPointSettings::STATUS_BAR_MODE::CHAPTER_PROGRESS_BAR; const bool showBattery = SETTINGS.statusBar == CrossPointSettings::STATUS_BAR_MODE::NO_PROGRESS || SETTINGS.statusBar == CrossPointSettings::STATUS_BAR_MODE::FULL || - SETTINGS.statusBar == CrossPointSettings::STATUS_BAR_MODE::FULL_WITH_PROGRESS_BAR; + SETTINGS.statusBar == CrossPointSettings::STATUS_BAR_MODE::FULL_WITH_PROGRESS_BAR || + SETTINGS.statusBar == CrossPointSettings::STATUS_BAR_MODE::CHAPTER_PROGRESS_BAR; const bool showTitle = SETTINGS.statusBar == CrossPointSettings::STATUS_BAR_MODE::NO_PROGRESS || SETTINGS.statusBar == CrossPointSettings::STATUS_BAR_MODE::FULL || - SETTINGS.statusBar == CrossPointSettings::STATUS_BAR_MODE::FULL_WITH_PROGRESS_BAR; + SETTINGS.statusBar == CrossPointSettings::STATUS_BAR_MODE::FULL_WITH_PROGRESS_BAR || + SETTINGS.statusBar == CrossPointSettings::STATUS_BAR_MODE::CHAPTER_PROGRESS_BAR; const bool showBatteryPercentage = SETTINGS.hideBatteryPercentage == CrossPointSettings::HIDE_BATTERY_PERCENTAGE::HIDE_NEVER; @@ -504,10 +508,12 @@ void TxtReaderActivity::renderStatusBar(const int orientedMarginRight, const int const float progress = totalPages > 0 ? (currentPage + 1) * 100.0f / totalPages : 0; - if (showProgressText || showProgressPercentage) { + if (showProgressText || showProgressPercentage || showBookPercentage) { char progressStr[32]; if (showProgressPercentage) { snprintf(progressStr, sizeof(progressStr), "%d/%d %.0f%%", currentPage + 1, totalPages, progress); + } else if (showBookPercentage) { + snprintf(progressStr, sizeof(progressStr), "%.0f%%", progress); } else { snprintf(progressStr, sizeof(progressStr), "%d/%d", currentPage + 1, totalPages); } @@ -522,6 +528,11 @@ void TxtReaderActivity::renderStatusBar(const int orientedMarginRight, const int ScreenComponents::drawBookProgressBar(renderer, static_cast(progress)); } + if (showChapterProgressBar) { + // For text mode, treat the entire book as one chapter, so chapter progress == book progress + ScreenComponents::drawChapterProgressBar(renderer, static_cast(progress)); + } + if (showBattery) { ScreenComponents::drawBattery(renderer, orientedMarginLeft, textY, showBatteryPercentage); } diff --git a/src/activities/settings/SettingsActivity.cpp b/src/activities/settings/SettingsActivity.cpp index 7316db05..55688baa 100644 --- a/src/activities/settings/SettingsActivity.cpp +++ b/src/activities/settings/SettingsActivity.cpp @@ -19,7 +19,8 @@ const SettingInfo displaySettings[displaySettingsCount] = { SettingInfo::Enum("Sleep Screen Cover Filter", &CrossPointSettings::sleepScreenCoverFilter, {"None", "Contrast", "Inverted"}), SettingInfo::Enum("Status Bar", &CrossPointSettings::statusBar, - {"None", "No Progress", "Full w/ Percentage", "Full w/ Progress Bar", "Progress Bar"}), + {"None", "No Progress", "Full w/ Percentage", "Full w/ Progress Bar", "Progress Bar", + "Chapter Progress Bar"}), SettingInfo::Enum("Hide Battery %", &CrossPointSettings::hideBatteryPercentage, {"Never", "In Reader", "Always"}), SettingInfo::Enum("Refresh Frequency", &CrossPointSettings::refreshFrequency, {"1 page", "5 pages", "10 pages", "15 pages", "30 pages"})};