diff --git a/src/CrossPointSettings.cpp b/src/CrossPointSettings.cpp index 467ee9ca..83ba59d1 100644 --- a/src/CrossPointSettings.cpp +++ b/src/CrossPointSettings.cpp @@ -10,7 +10,7 @@ CrossPointSettings CrossPointSettings::instance; namespace { constexpr uint8_t SETTINGS_FILE_VERSION = 1; -constexpr uint8_t SETTINGS_COUNT = 3; +constexpr uint8_t SETTINGS_COUNT = 4; constexpr char SETTINGS_FILE[] = "/.crosspoint/settings.bin"; } // namespace @@ -28,6 +28,7 @@ bool CrossPointSettings::saveToFile() const { serialization::writePod(outputFile, sleepScreen); serialization::writePod(outputFile, extraParagraphSpacing); serialization::writePod(outputFile, shortPwrBtn); + serialization::writePod(outputFile, statusBar); outputFile.close(); Serial.printf("[%lu] [CPS] Settings saved to file\n", millis()); @@ -60,6 +61,8 @@ bool CrossPointSettings::loadFromFile() { if (++settingsRead >= fileSettingsCount) break; serialization::readPod(inputFile, shortPwrBtn); if (++settingsRead >= fileSettingsCount) break; + serialization::readPod(inputFile, statusBar); + if (++settingsRead >= fileSettingsCount) break; } while (false); inputFile.close(); diff --git a/src/CrossPointSettings.h b/src/CrossPointSettings.h index 14c33322..ab591bef 100644 --- a/src/CrossPointSettings.h +++ b/src/CrossPointSettings.h @@ -18,8 +18,13 @@ class CrossPointSettings { // Should match with SettingsActivity text enum SLEEP_SCREEN_MODE { DARK = 0, LIGHT = 1, CUSTOM = 2, COVER = 3 }; + // Status bar display type enum + enum STATUS_BAR_MODE { NONE = 0, NO_PROGRESS = 1, FULL = 2 }; + // Sleep screen settings uint8_t sleepScreen = DARK; + // Status bar settings + uint8_t statusBar = FULL; // Text rendering settings uint8_t extraParagraphSpacing = 1; // Duration of the power button press diff --git a/src/activities/reader/EpubReaderActivity.cpp b/src/activities/reader/EpubReaderActivity.cpp index f4905d60..b2242376 100644 --- a/src/activities/reader/EpubReaderActivity.cpp +++ b/src/activities/reader/EpubReaderActivity.cpp @@ -340,71 +340,87 @@ void EpubReaderActivity::renderContents(std::unique_ptr page) { } void EpubReaderActivity::renderStatusBar() const { + // determine visible status bar elements + const bool showProgress = SETTINGS.statusBar == CrossPointSettings::STATUS_BAR_MODE::FULL; + const bool showBattery = SETTINGS.statusBar == CrossPointSettings::STATUS_BAR_MODE::NO_PROGRESS || + SETTINGS.statusBar == CrossPointSettings::STATUS_BAR_MODE::FULL; + const bool showChapterTitle = SETTINGS.statusBar == CrossPointSettings::STATUS_BAR_MODE::NO_PROGRESS || + SETTINGS.statusBar == CrossPointSettings::STATUS_BAR_MODE::FULL; + + // height variable shared by all elements constexpr auto textY = 776; + int percentageTextWidth = 0; + int progressTextWidth = 0; - // Calculate progress in book - const float sectionChapterProg = static_cast(section->currentPage) / section->pageCount; - const uint8_t bookProgress = epub->calculateProgress(currentSpineIndex, sectionChapterProg); + if (showProgress) { + // Calculate progress in book + const float sectionChapterProg = static_cast(section->currentPage) / section->pageCount; + const uint8_t bookProgress = epub->calculateProgress(currentSpineIndex, sectionChapterProg); - // Right aligned text for progress counter - const std::string progress = std::to_string(section->currentPage + 1) + "/" + std::to_string(section->pageCount) + - " " + std::to_string(bookProgress) + "%"; - const auto progressTextWidth = renderer.getTextWidth(SMALL_FONT_ID, progress.c_str()); - renderer.drawText(SMALL_FONT_ID, GfxRenderer::getScreenWidth() - marginRight - progressTextWidth, textY, - progress.c_str()); - - // Left aligned battery icon and percentage - const uint16_t percentage = battery.readPercentage(); - const auto percentageText = std::to_string(percentage) + "%"; - const auto percentageTextWidth = renderer.getTextWidth(SMALL_FONT_ID, percentageText.c_str()); - renderer.drawText(SMALL_FONT_ID, 20 + marginLeft, textY, percentageText.c_str()); - - // 1 column on left, 2 columns on right, 5 columns of battery body - constexpr int batteryWidth = 15; - constexpr int batteryHeight = 10; - constexpr int x = marginLeft; - constexpr int y = 783; - - // Top line - renderer.drawLine(x, y, x + batteryWidth - 4, y); - // Bottom line - renderer.drawLine(x, y + batteryHeight - 1, x + batteryWidth - 4, y + batteryHeight - 1); - // Left line - renderer.drawLine(x, y, x, y + batteryHeight - 1); - // Battery end - renderer.drawLine(x + batteryWidth - 4, y, x + batteryWidth - 4, y + batteryHeight - 1); - renderer.drawLine(x + batteryWidth - 3, y + 2, x + batteryWidth - 1, y + 2); - renderer.drawLine(x + batteryWidth - 3, y + batteryHeight - 3, x + batteryWidth - 1, y + batteryHeight - 3); - renderer.drawLine(x + batteryWidth - 1, y + 2, x + batteryWidth - 1, y + batteryHeight - 3); - - // The +1 is to round up, so that we always fill at least one pixel - int filledWidth = percentage * (batteryWidth - 5) / 100 + 1; - if (filledWidth > batteryWidth - 5) { - filledWidth = batteryWidth - 5; // Ensure we don't overflow + // Right aligned text for progress counter + const std::string progress = std::to_string(section->currentPage + 1) + "/" + std::to_string(section->pageCount) + + " " + std::to_string(bookProgress) + "%"; + progressTextWidth = renderer.getTextWidth(SMALL_FONT_ID, progress.c_str()); + renderer.drawText(SMALL_FONT_ID, GfxRenderer::getScreenWidth() - marginRight - progressTextWidth, textY, + progress.c_str()); } - renderer.fillRect(x + 1, y + 1, filledWidth, batteryHeight - 2); - // Centered chatper title text - // Page width minus existing content with 30px padding on each side - const int titleMarginLeft = 20 + percentageTextWidth + 30 + marginLeft; - const int titleMarginRight = progressTextWidth + 30 + marginRight; - const int availableTextWidth = GfxRenderer::getScreenWidth() - titleMarginLeft - titleMarginRight; - const int tocIndex = epub->getTocIndexForSpineIndex(currentSpineIndex); + if (showBattery) { + // Left aligned battery icon and percentage + const uint16_t percentage = battery.readPercentage(); + const auto percentageText = std::to_string(percentage) + "%"; + percentageTextWidth = renderer.getTextWidth(SMALL_FONT_ID, percentageText.c_str()); + renderer.drawText(SMALL_FONT_ID, 20 + marginLeft, textY, percentageText.c_str()); - std::string title; - int titleWidth; - if (tocIndex == -1) { - title = "Unnamed"; - titleWidth = renderer.getTextWidth(SMALL_FONT_ID, "Unnamed"); - } else { - const auto tocItem = epub->getTocItem(tocIndex); - title = tocItem.title; - titleWidth = renderer.getTextWidth(SMALL_FONT_ID, title.c_str()); - while (titleWidth > availableTextWidth && title.length() > 11) { - title.replace(title.length() - 8, 8, "..."); - titleWidth = renderer.getTextWidth(SMALL_FONT_ID, title.c_str()); + // 1 column on left, 2 columns on right, 5 columns of battery body + constexpr int batteryWidth = 15; + constexpr int batteryHeight = 10; + constexpr int x = marginLeft; + constexpr int y = 783; + + // Top line + renderer.drawLine(x, y, x + batteryWidth - 4, y); + // Bottom line + renderer.drawLine(x, y + batteryHeight - 1, x + batteryWidth - 4, y + batteryHeight - 1); + // Left line + renderer.drawLine(x, y, x, y + batteryHeight - 1); + // Battery end + renderer.drawLine(x + batteryWidth - 4, y, x + batteryWidth - 4, y + batteryHeight - 1); + renderer.drawLine(x + batteryWidth - 3, y + 2, x + batteryWidth - 1, y + 2); + renderer.drawLine(x + batteryWidth - 3, y + batteryHeight - 3, x + batteryWidth - 1, y + batteryHeight - 3); + renderer.drawLine(x + batteryWidth - 1, y + 2, x + batteryWidth - 1, y + batteryHeight - 3); + + // The +1 is to round up, so that we always fill at least one pixel + int filledWidth = percentage * (batteryWidth - 5) / 100 + 1; + if (filledWidth > batteryWidth - 5) { + filledWidth = batteryWidth - 5; // Ensure we don't overflow } + renderer.fillRect(x + 1, y + 1, filledWidth, batteryHeight - 2); } - renderer.drawText(SMALL_FONT_ID, titleMarginLeft + (availableTextWidth - titleWidth) / 2, textY, title.c_str()); + if (showChapterTitle) { + // Centered chatper title text + // Page width minus existing content with 30px padding on each side + const int titleMarginLeft = 20 + percentageTextWidth + 30 + marginLeft; + const int titleMarginRight = progressTextWidth + 30 + marginRight; + const int availableTextWidth = GfxRenderer::getScreenWidth() - titleMarginLeft - titleMarginRight; + const int tocIndex = epub->getTocIndexForSpineIndex(currentSpineIndex); + + std::string title; + int titleWidth; + if (tocIndex == -1) { + title = "Unnamed"; + titleWidth = renderer.getTextWidth(SMALL_FONT_ID, "Unnamed"); + } else { + const auto tocItem = epub->getTocItem(tocIndex); + title = tocItem.title; + titleWidth = renderer.getTextWidth(SMALL_FONT_ID, title.c_str()); + while (titleWidth > availableTextWidth && title.length() > 11) { + title.replace(title.length() - 8, 8, "..."); + titleWidth = renderer.getTextWidth(SMALL_FONT_ID, title.c_str()); + } + } + + renderer.drawText(SMALL_FONT_ID, titleMarginLeft + (availableTextWidth - titleWidth) / 2, textY, title.c_str()); + } } diff --git a/src/activities/settings/SettingsActivity.cpp b/src/activities/settings/SettingsActivity.cpp index f7af052e..b71a877c 100644 --- a/src/activities/settings/SettingsActivity.cpp +++ b/src/activities/settings/SettingsActivity.cpp @@ -9,10 +9,11 @@ // Define the static settings list namespace { -constexpr int settingsCount = 4; +constexpr int settingsCount = 5; const SettingInfo settingsList[settingsCount] = { // Should match with SLEEP_SCREEN_MODE {"Sleep Screen", SettingType::ENUM, &CrossPointSettings::sleepScreen, {"Dark", "Light", "Custom", "Cover"}}, + {"Status Bar", SettingType::ENUM, &CrossPointSettings::statusBar, {"None", "No Progress", "Full"}}, {"Extra Paragraph Spacing", SettingType::TOGGLE, &CrossPointSettings::extraParagraphSpacing, {}}, {"Short Power Button Click", SettingType::TOGGLE, &CrossPointSettings::shortPwrBtn, {}}, {"Check for updates", SettingType::ACTION, nullptr, {}},