diff --git a/lib/Epub/Epub/Section.cpp b/lib/Epub/Epub/Section.cpp index 581a364..31a99af 100644 --- a/lib/Epub/Epub/Section.cpp +++ b/lib/Epub/Epub/Section.cpp @@ -123,9 +123,7 @@ bool Section::clearCache() const { bool Section::createSectionFile(const int fontId, const float lineCompression, const bool extraParagraphSpacing, const uint8_t paragraphAlignment, const uint16_t viewportWidth, const uint16_t viewportHeight, const bool hyphenationEnabled, - const std::function& progressSetupFn, const std::function& progressFn) { - constexpr uint32_t MIN_SIZE_FOR_PROGRESS = 50 * 1024; // 50KB const auto localPath = epub->getSpineItem(spineIndex).href; const auto tmpHtmlPath = epub->getCachePath() + "/.tmp_" + std::to_string(spineIndex) + ".html"; @@ -171,11 +169,6 @@ bool Section::createSectionFile(const int fontId, const float lineCompression, c Serial.printf("[%lu] [SCT] Streamed temp HTML to %s (%d bytes)\n", millis(), tmpHtmlPath.c_str(), fileSize); - // Only show progress bar for larger chapters where rendering overhead is worth it - if (progressSetupFn && fileSize >= MIN_SIZE_FOR_PROGRESS) { - progressSetupFn(); - } - if (!SdMan.openFileForWrite("SCT", filePath, file)) { return false; } diff --git a/lib/Epub/Epub/Section.h b/lib/Epub/Epub/Section.h index 5b72614..cfa01fe 100644 --- a/lib/Epub/Epub/Section.h +++ b/lib/Epub/Epub/Section.h @@ -33,7 +33,6 @@ class Section { bool clearCache() const; bool createSectionFile(int fontId, float lineCompression, bool extraParagraphSpacing, uint8_t paragraphAlignment, uint16_t viewportWidth, uint16_t viewportHeight, bool hyphenationEnabled, - const std::function& progressSetupFn = nullptr, const std::function& progressFn = nullptr); std::unique_ptr loadPageFromSectionFile(); }; diff --git a/lib/GfxRenderer/GfxRenderer.h b/lib/GfxRenderer/GfxRenderer.h index b1fea69..009309e 100644 --- a/lib/GfxRenderer/GfxRenderer.h +++ b/lib/GfxRenderer/GfxRenderer.h @@ -55,8 +55,6 @@ class GfxRenderer { int getScreenWidth() const; int getScreenHeight() const; void displayBuffer(EInkDisplay::RefreshMode refreshMode = EInkDisplay::FAST_REFRESH) const; - // EXPERIMENTAL: Windowed update - display only a rectangular region - void displayWindow(int x, int y, int width, int height) const; void invertScreen() const; void clearScreen(uint8_t color = 0xFF) const; diff --git a/src/ScreenComponents.cpp b/src/ScreenComponents.cpp index 2e8d9e7..083b77e 100644 --- a/src/ScreenComponents.cpp +++ b/src/ScreenComponents.cpp @@ -42,6 +42,43 @@ void ScreenComponents::drawBattery(const GfxRenderer& renderer, const int left, renderer.fillRect(x + 2, y + 2, filledWidth, batteryHeight - 4); } +ScreenComponents::PopupLayout ScreenComponents::drawPopup(const GfxRenderer& renderer, const char* message, const int y, + const int minWidth, const int minHeight) { + const int textWidth = renderer.getTextWidth(UI_12_FONT_ID, message, EpdFontFamily::BOLD); + constexpr int margin = 16; + const int contentWidth = textWidth > minWidth ? textWidth : minWidth; + const int x = (renderer.getScreenWidth() - contentWidth - margin * 2) / 2; + const int w = contentWidth + margin * 2; + const int contentHeight = renderer.getLineHeight(UI_12_FONT_ID) + margin * 2; + const int h = contentHeight >= minHeight ? contentHeight : minHeight; + renderer.fillRect(x - 2, y - 2, w + 4, h + 4, true); + renderer.fillRect(x + 2, y + 2, w - 4, h - 4, false); + + const int textX = x + margin + (contentWidth - textWidth) / 2; + renderer.drawText(UI_12_FONT_ID, textX, y + margin, message, true, EpdFontFamily::BOLD); + renderer.displayBuffer(); + return {x, y, w, h}; +} + +void ScreenComponents::fillPopupProgress(const GfxRenderer& renderer, const PopupLayout& layout, const int progress) { + const int barWidth = POPUP_DEFAULT_MIN_WIDTH; + const int barHeight = POPUP_DEFAULT_BAR_HEIGHT; + const int barX = layout.x + (layout.width - barWidth) / 2; + const int barY = layout.y + layout.height - 16; // 16 pixels above bottom of popup + + int fillWidth = barWidth * progress / 100; + if (fillWidth < 0) { + fillWidth = 0; + } else if (fillWidth > barWidth) { + fillWidth = barWidth; + } + + if (fillWidth > 2) { + renderer.fillRect(barX + 1, barY + 1, fillWidth - 2, barHeight - 2, true); + } + renderer.displayBuffer(EInkDisplay::FAST_REFRESH); +} + 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 48c40f4..89299f5 100644 --- a/src/ScreenComponents.h +++ b/src/ScreenComponents.h @@ -13,8 +13,24 @@ struct TabInfo { class ScreenComponents { public: + static constexpr int POPUP_DEFAULT_MIN_HEIGHT = 72; + static constexpr int POPUP_DEFAULT_BAR_HEIGHT = 6; + static constexpr int POPUP_DEFAULT_MIN_WIDTH = 200; + + struct PopupLayout { + int x; + int y; + int width; + int height; + }; + static void drawBattery(const GfxRenderer& renderer, int left, int top, bool showPercentage = true); + static PopupLayout drawPopup(const GfxRenderer& renderer, const char* message, int y = 117, + int minWidth = POPUP_DEFAULT_MIN_WIDTH, int minHeight = POPUP_DEFAULT_MIN_HEIGHT); + + static void fillPopupProgress(const GfxRenderer& renderer, const PopupLayout& layout, int progress); + // Draw a horizontal tab bar with underline indicator for selected tab // Returns the height of the tab bar (for positioning content below) static int drawTabBar(const GfxRenderer& renderer, int y, const std::vector& tabs); diff --git a/src/activities/boot_sleep/SleepActivity.cpp b/src/activities/boot_sleep/SleepActivity.cpp index c0d6844..69de73f 100644 --- a/src/activities/boot_sleep/SleepActivity.cpp +++ b/src/activities/boot_sleep/SleepActivity.cpp @@ -14,7 +14,6 @@ void SleepActivity::onEnter() { Activity::onEnter(); - renderPopup("Entering Sleep..."); if (SETTINGS.sleepScreen == CrossPointSettings::SLEEP_SCREEN_MODE::BLANK) { return renderBlankSleepScreen(); @@ -31,20 +30,6 @@ void SleepActivity::onEnter() { renderDefaultSleepScreen(); } -void SleepActivity::renderPopup(const char* message) const { - const int textWidth = renderer.getTextWidth(UI_12_FONT_ID, message, EpdFontFamily::BOLD); - constexpr int margin = 20; - const int x = (renderer.getScreenWidth() - textWidth - margin * 2) / 2; - constexpr int y = 117; - const int w = textWidth + margin * 2; - const int h = renderer.getLineHeight(UI_12_FONT_ID) + margin * 2; - // renderer.clearScreen(); - renderer.fillRect(x - 5, y - 5, w + 10, h + 10, true); - renderer.fillRect(x + 5, y + 5, w - 10, h - 10, false); - renderer.drawText(UI_12_FONT_ID, x + margin, y + margin, message, true, EpdFontFamily::BOLD); - renderer.displayBuffer(); -} - void SleepActivity::renderCustomSleepScreen() const { // Check if we have a /sleep directory auto dir = SdMan.open("/sleep"); diff --git a/src/activities/boot_sleep/SleepActivity.h b/src/activities/boot_sleep/SleepActivity.h index 283220c..87df8ba 100644 --- a/src/activities/boot_sleep/SleepActivity.h +++ b/src/activities/boot_sleep/SleepActivity.h @@ -10,7 +10,6 @@ class SleepActivity final : public Activity { void onEnter() override; private: - void renderPopup(const char* message) const; void renderDefaultSleepScreen() const; void renderCustomSleepScreen() const; void renderCoverSleepScreen() const; diff --git a/src/activities/reader/EpubReaderActivity.cpp b/src/activities/reader/EpubReaderActivity.cpp index 6ff39c5..e77e559 100644 --- a/src/activities/reader/EpubReaderActivity.cpp +++ b/src/activities/reader/EpubReaderActivity.cpp @@ -285,49 +285,15 @@ void EpubReaderActivity::renderScreen() { viewportHeight, SETTINGS.hyphenationEnabled)) { Serial.printf("[%lu] [ERS] Cache not found, building...\n", millis()); - // Progress bar dimensions - constexpr int barWidth = 200; - constexpr int barHeight = 10; - constexpr int boxMargin = 20; - const int textWidth = renderer.getTextWidth(UI_12_FONT_ID, "Indexing..."); - const int boxWidthWithBar = (barWidth > textWidth ? barWidth : textWidth) + boxMargin * 2; - const int boxWidthNoBar = textWidth + boxMargin * 2; - const int boxHeightWithBar = renderer.getLineHeight(UI_12_FONT_ID) + barHeight + boxMargin * 3; - const int boxHeightNoBar = renderer.getLineHeight(UI_12_FONT_ID) + boxMargin * 2; - const int boxXWithBar = (renderer.getScreenWidth() - boxWidthWithBar) / 2; - const int boxXNoBar = (renderer.getScreenWidth() - boxWidthNoBar) / 2; - constexpr int boxY = 50; - const int barX = boxXWithBar + (boxWidthWithBar - barWidth) / 2; - const int barY = boxY + renderer.getLineHeight(UI_12_FONT_ID) + boxMargin * 2; - - // Always show "Indexing..." text first - { - renderer.fillRect(boxXNoBar, boxY, boxWidthNoBar, boxHeightNoBar, false); - renderer.drawText(UI_12_FONT_ID, boxXNoBar + boxMargin, boxY + boxMargin, "Indexing..."); - renderer.drawRect(boxXNoBar + 5, boxY + 5, boxWidthNoBar - 10, boxHeightNoBar - 10); - renderer.displayBuffer(); - pagesUntilFullRefresh = 0; - } - - // Setup callback - only called for chapters >= 50KB, redraws with progress bar - auto progressSetup = [this, boxXWithBar, boxWidthWithBar, boxHeightWithBar, barX, barY] { - renderer.fillRect(boxXWithBar, boxY, boxWidthWithBar, boxHeightWithBar, false); - renderer.drawText(UI_12_FONT_ID, boxXWithBar + boxMargin, boxY + boxMargin, "Indexing..."); - renderer.drawRect(boxXWithBar + 5, boxY + 5, boxWidthWithBar - 10, boxHeightWithBar - 10); - renderer.drawRect(barX, barY, barWidth, barHeight); - renderer.displayBuffer(); - }; - - // Progress callback to update progress bar - auto progressCallback = [this, barX, barY, barWidth, barHeight](int progress) { - const int fillWidth = (barWidth - 2) * progress / 100; - renderer.fillRect(barX + 1, barY + 1, fillWidth, barHeight - 2, true); - renderer.displayBuffer(EInkDisplay::FAST_REFRESH); + pagesUntilFullRefresh = 0; + const auto popupLayout = ScreenComponents::drawPopup(renderer, "Indexing..."); + const auto progressCallback = [this, popupLayout](int progress) { + ScreenComponents::fillPopupProgress(renderer, popupLayout, progress); }; if (!section->createSectionFile(SETTINGS.getReaderFontId(), SETTINGS.getReaderLineCompression(), SETTINGS.extraParagraphSpacing, SETTINGS.paragraphAlignment, viewportWidth, - viewportHeight, SETTINGS.hyphenationEnabled, progressSetup, progressCallback)) { + viewportHeight, SETTINGS.hyphenationEnabled, progressCallback)) { Serial.printf("[%lu] [ERS] Failed to persist page data to SD\n", millis()); section.reset(); return; diff --git a/src/activities/reader/TxtReaderActivity.cpp b/src/activities/reader/TxtReaderActivity.cpp index db72532..60cafa7 100644 --- a/src/activities/reader/TxtReaderActivity.cpp +++ b/src/activities/reader/TxtReaderActivity.cpp @@ -192,24 +192,7 @@ void TxtReaderActivity::buildPageIndex() { Serial.printf("[%lu] [TRS] Building page index for %zu bytes...\n", millis(), fileSize); - // Progress bar dimensions (matching EpubReaderActivity style) - constexpr int barWidth = 200; - constexpr int barHeight = 10; - constexpr int boxMargin = 20; - const int textWidth = renderer.getTextWidth(UI_12_FONT_ID, "Indexing..."); - const int boxWidth = (barWidth > textWidth ? barWidth : textWidth) + boxMargin * 2; - const int boxHeight = renderer.getLineHeight(UI_12_FONT_ID) + barHeight + boxMargin * 3; - const int boxX = (renderer.getScreenWidth() - boxWidth) / 2; - constexpr int boxY = 50; - const int barX = boxX + (boxWidth - barWidth) / 2; - const int barY = boxY + renderer.getLineHeight(UI_12_FONT_ID) + boxMargin * 2; - - // Draw initial progress box - renderer.fillRect(boxX, boxY, boxWidth, boxHeight, false); - renderer.drawText(UI_12_FONT_ID, boxX + boxMargin, boxY + boxMargin, "Indexing..."); - renderer.drawRect(boxX + 5, boxY + 5, boxWidth - 10, boxHeight - 10); - renderer.drawRect(barX, barY, barWidth, barHeight); - renderer.displayBuffer(); + const auto popupLayout = ScreenComponents::drawPopup(renderer, "Indexing..."); while (offset < fileSize) { std::vector tempLines; @@ -235,9 +218,7 @@ void TxtReaderActivity::buildPageIndex() { lastProgressPercent = progressPercent; // Fill progress bar - const int fillWidth = (barWidth - 2) * progressPercent / 100; - renderer.fillRect(barX + 1, barY + 1, fillWidth, barHeight - 2, true); - renderer.displayBuffer(EInkDisplay::FAST_REFRESH); + ScreenComponents::fillPopupProgress(renderer, popupLayout, progressPercent); } // Yield to other tasks periodically @@ -383,9 +364,6 @@ void TxtReaderActivity::renderScreen() { // Initialize reader if not done if (!initialized) { - renderer.clearScreen(); - renderer.drawCenteredText(UI_12_FONT_ID, 300, "Indexing...", true, EpdFontFamily::BOLD); - renderer.displayBuffer(); initializeReader(); } diff --git a/src/main.cpp b/src/main.cpp index c0222e0..3ccd943 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -332,9 +332,6 @@ void setup() { setupDisplayAndFonts(); - exitActivity(); - enterNewActivity(new BootActivity(renderer, mappedInputManager)); - APP_STATE.loadFromFile(); RECENT_BOOKS.loadFromFile();