diff --git a/src/CrossPointSettings.h b/src/CrossPointSettings.h index 8ce32a2..ed86b9f 100644 --- a/src/CrossPointSettings.h +++ b/src/CrossPointSettings.h @@ -20,7 +20,7 @@ class CrossPointSettings { enum SLEEP_SCREEN_COVER_MODE { FIT = 0, CROP = 1 }; // Status bar display type enum - enum STATUS_BAR_MODE { NONE = 0, NO_PROGRESS = 1, FULL = 2 }; + enum STATUS_BAR_MODE { NONE = 0, NO_PROGRESS = 1, FULL = 2, FULL_WITH_PROGRESS_BAR = 3 }; enum ORIENTATION { PORTRAIT = 0, // 480x800 logical coordinates (current default) diff --git a/src/activities/reader/EpubReaderActivity.cpp b/src/activities/reader/EpubReaderActivity.cpp index d70a15c..b981761 100644 --- a/src/activities/reader/EpubReaderActivity.cpp +++ b/src/activities/reader/EpubReaderActivity.cpp @@ -17,6 +17,9 @@ namespace { constexpr unsigned long skipChapterMs = 700; constexpr unsigned long goHomeMs = 1000; constexpr int statusBarMargin = 19; +constexpr int progressBarHeight = 4; +constexpr int progressBarMarginTop = 1; + } // namespace void EpubReaderActivity::taskTrampoline(void* param) { @@ -261,6 +264,9 @@ void EpubReaderActivity::renderScreen() { return; } + // Add additional margin for status bar if progress bar is shown + const bool showProgressBar = SETTINGS.statusBar == CrossPointSettings::FULL_WITH_PROGRESS_BAR; + // Apply screen viewable areas and additional padding int orientedMarginTop, orientedMarginRight, orientedMarginBottom, orientedMarginLeft; renderer.getOrientedViewableTRBL(&orientedMarginTop, &orientedMarginRight, &orientedMarginBottom, @@ -268,7 +274,7 @@ void EpubReaderActivity::renderScreen() { orientedMarginTop += SETTINGS.screenMargin; orientedMarginLeft += SETTINGS.screenMargin; orientedMarginRight += SETTINGS.screenMargin; - orientedMarginBottom += statusBarMargin; + orientedMarginBottom += statusBarMargin + (showProgressBar ? (progressBarHeight + progressBarMarginTop) : 0); if (!section) { const auto filepath = epub->getSpineItem(currentSpineIndex).href; @@ -426,11 +432,14 @@ void EpubReaderActivity::renderContents(std::unique_ptr page, const int or void EpubReaderActivity::renderStatusBar(const int orientedMarginRight, const int orientedMarginBottom, const int orientedMarginLeft) const { // determine visible status bar elements - const bool showProgress = SETTINGS.statusBar == CrossPointSettings::STATUS_BAR_MODE::FULL; + const bool showProgressPercentage = SETTINGS.statusBar == CrossPointSettings::STATUS_BAR_MODE::FULL; + const bool showProgressBar = SETTINGS.statusBar == CrossPointSettings::STATUS_BAR_MODE::FULL_WITH_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 || + SETTINGS.statusBar == CrossPointSettings::STATUS_BAR_MODE::FULL_WITH_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 || + SETTINGS.statusBar == CrossPointSettings::STATUS_BAR_MODE::FULL_WITH_PROGRESS_BAR; const bool showBatteryPercentage = SETTINGS.hideBatteryPercentage == CrossPointSettings::HIDE_BATTERY_PERCENTAGE::HIDE_NEVER; @@ -439,19 +448,37 @@ void EpubReaderActivity::renderStatusBar(const int orientedMarginRight, const in const auto textY = screenHeight - orientedMarginBottom - 4; int progressTextWidth = 0; - if (showProgress) { + if (showProgressPercentage || showProgressBar) { // Calculate progress in book const float sectionChapterProg = static_cast(section->currentPage) / section->pageCount; const float bookProgress = epub->calculateProgress(currentSpineIndex, sectionChapterProg) * 100; // Right aligned text for progress counter char progressStr[32]; - snprintf(progressStr, sizeof(progressStr), "%d/%d %.1f%%", section->currentPage + 1, section->pageCount, - bookProgress); - const std::string progress = progressStr; - progressTextWidth = renderer.getTextWidth(SMALL_FONT_ID, progress.c_str()); + + // Hide percentage when progress bar is shown to reduce clutter + if(showProgressPercentage) { + snprintf(progressStr, sizeof(progressStr), "%d/%d %.1f%%", section->currentPage + 1, section->pageCount, + bookProgress); + } else { + snprintf(progressStr, sizeof(progressStr), "%d/%d", section->currentPage + 1, section->pageCount); + } + + progressTextWidth = renderer.getTextWidth(SMALL_FONT_ID, progressStr); renderer.drawText(SMALL_FONT_ID, renderer.getScreenWidth() - orientedMarginRight - progressTextWidth, textY, - progress.c_str()); + progressStr); + + if (showProgressBar) { + // Draw progress bar at the very bottom of the screen, from edge to edge of viewable area + int vieweableMarginTop, vieweableMarginRight, vieweableMarginBottom, vieweableMarginLeft; + renderer.getOrientedViewableTRBL(&vieweableMarginTop, &vieweableMarginRight, &vieweableMarginBottom, + &vieweableMarginLeft); + + const int progressBarMaxWidth = renderer.getScreenWidth() - vieweableMarginLeft - vieweableMarginRight; + const int progressBarY = renderer.getScreenHeight() - vieweableMarginBottom - progressBarHeight; + const int barWidth = progressBarMaxWidth * bookProgress / 100; + renderer.fillRect(vieweableMarginLeft, progressBarY, barWidth, progressBarHeight, true); + } } if (showBattery) { diff --git a/src/activities/reader/TxtReaderActivity.cpp b/src/activities/reader/TxtReaderActivity.cpp index db72532..9874422 100644 --- a/src/activities/reader/TxtReaderActivity.cpp +++ b/src/activities/reader/TxtReaderActivity.cpp @@ -14,6 +14,8 @@ namespace { constexpr unsigned long goHomeMs = 1000; constexpr int statusBarMargin = 25; +constexpr int progressBarHeight = 4; +constexpr int progressBarMarginTop = 1; constexpr size_t CHUNK_SIZE = 8 * 1024; // 8KB chunk for reading // Cache file magic and version @@ -149,6 +151,9 @@ void TxtReaderActivity::initializeReader() { cachedScreenMargin = SETTINGS.screenMargin; cachedParagraphAlignment = SETTINGS.paragraphAlignment; + // Add additional margin for status bar if progress bar is shown + const bool showProgressBar = SETTINGS.statusBar == CrossPointSettings::FULL_WITH_PROGRESS_BAR; + // Calculate viewport dimensions int orientedMarginTop, orientedMarginRight, orientedMarginBottom, orientedMarginLeft; renderer.getOrientedViewableTRBL(&orientedMarginTop, &orientedMarginRight, &orientedMarginBottom, @@ -156,7 +161,7 @@ void TxtReaderActivity::initializeReader() { orientedMarginTop += cachedScreenMargin; orientedMarginLeft += cachedScreenMargin; orientedMarginRight += cachedScreenMargin; - orientedMarginBottom += statusBarMargin; + orientedMarginBottom += statusBarMargin + (showProgressBar ? (progressBarHeight + progressBarMarginTop) : 0); viewportWidth = renderer.getScreenWidth() - orientedMarginLeft - orientedMarginRight; const int viewportHeight = renderer.getScreenHeight() - orientedMarginTop - orientedMarginBottom; @@ -497,23 +502,44 @@ void TxtReaderActivity::renderPage() { void TxtReaderActivity::renderStatusBar(const int orientedMarginRight, const int orientedMarginBottom, const int orientedMarginLeft) const { - const bool showProgress = SETTINGS.statusBar == CrossPointSettings::STATUS_BAR_MODE::FULL; + const bool showProgressPercentage = SETTINGS.statusBar == CrossPointSettings::STATUS_BAR_MODE::FULL; + const bool showProgressBar = SETTINGS.statusBar == CrossPointSettings::STATUS_BAR_MODE::FULL_WITH_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 || + SETTINGS.statusBar == CrossPointSettings::STATUS_BAR_MODE::FULL_WITH_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 || + SETTINGS.statusBar == CrossPointSettings::STATUS_BAR_MODE::FULL_WITH_PROGRESS_BAR; const auto screenHeight = renderer.getScreenHeight(); const auto textY = screenHeight - orientedMarginBottom - 4; int progressTextWidth = 0; - if (showProgress) { - const int progress = totalPages > 0 ? (currentPage + 1) * 100 / totalPages : 0; - const std::string progressStr = - std::to_string(currentPage + 1) + "/" + std::to_string(totalPages) + " " + std::to_string(progress) + "%"; - progressTextWidth = renderer.getTextWidth(SMALL_FONT_ID, progressStr.c_str()); + if (showProgressPercentage || showProgressBar) { + const float progress = totalPages > 0 ? (currentPage + 1) * 100.0f / totalPages : 0; + + char progressStr[32]; + if (showProgressPercentage) { + snprintf(progressStr, sizeof(progressStr), "%d/%d %.1f%%", currentPage + 1, totalPages, progress); + } else { + snprintf(progressStr, sizeof(progressStr), "%d/%d", currentPage + 1, totalPages); + } + + progressTextWidth = renderer.getTextWidth(SMALL_FONT_ID, progressStr); renderer.drawText(SMALL_FONT_ID, renderer.getScreenWidth() - orientedMarginRight - progressTextWidth, textY, - progressStr.c_str()); + progressStr); + + if (showProgressBar) { + // Draw progress bar at the very bottom of the screen, from edge to edge of viewable area + int vieweableMarginTop, vieweableMarginRight, vieweableMarginBottom, vieweableMarginLeft; + renderer.getOrientedViewableTRBL(&vieweableMarginTop, &vieweableMarginRight, &vieweableMarginBottom, + &vieweableMarginLeft); + + const int progressBarMaxWidth = renderer.getScreenWidth() - vieweableMarginLeft - vieweableMarginRight; + const int progressBarY = renderer.getScreenHeight() - vieweableMarginBottom - progressBarHeight; + const int barWidth = progressBarMaxWidth * progress / 100; + renderer.fillRect(vieweableMarginLeft, progressBarY, barWidth, progressBarHeight, true); + } } if (showBattery) { diff --git a/src/activities/settings/SettingsActivity.cpp b/src/activities/settings/SettingsActivity.cpp index 7907e50..b69db88 100644 --- a/src/activities/settings/SettingsActivity.cpp +++ b/src/activities/settings/SettingsActivity.cpp @@ -19,7 +19,8 @@ const SettingInfo settingsList[settingsCount] = { // Should match with SLEEP_SCREEN_MODE SettingInfo::Enum("Sleep Screen", &CrossPointSettings::sleepScreen, {"Dark", "Light", "Custom", "Cover", "None"}), SettingInfo::Enum("Sleep Screen Cover Mode", &CrossPointSettings::sleepScreenCoverMode, {"Fit", "Crop"}), - SettingInfo::Enum("Status Bar", &CrossPointSettings::statusBar, {"None", "No Progress", "Full"}), + SettingInfo::Enum("Status Bar", &CrossPointSettings::statusBar, {"None", "No Progress", "Full w/ Percentage", + "Full w/ Progress Bar"}), SettingInfo::Enum("Hide Battery %", &CrossPointSettings::hideBatteryPercentage, {"Never", "In Reader", "Always"}), SettingInfo::Toggle("Extra Paragraph Spacing", &CrossPointSettings::extraParagraphSpacing), SettingInfo::Toggle("Text Anti-Aliasing", &CrossPointSettings::textAntiAliasing),