Add setting to enable status bar display options (#111)
Some checks are pending
CI / build (push) Waiting to run

Add setting toggle that allows status bar display options in EpubReader.

Supported options would be as follows: 

- FULL: display as is today
- PROGRESS: display progress bar only
- BATTERY: display battery only
- NONE: hide status bar

---------

Co-authored-by: Dave Allie <dave@daveallie.com>
This commit is contained in:
1991AcuraLegend 2025-12-27 17:48:27 -06:00 committed by GitHub
parent f96b6ab29c
commit 838246d147
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 85 additions and 60 deletions

View File

@ -10,7 +10,7 @@ CrossPointSettings CrossPointSettings::instance;
namespace { namespace {
constexpr uint8_t SETTINGS_FILE_VERSION = 1; 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"; constexpr char SETTINGS_FILE[] = "/.crosspoint/settings.bin";
} // namespace } // namespace
@ -28,6 +28,7 @@ bool CrossPointSettings::saveToFile() const {
serialization::writePod(outputFile, sleepScreen); serialization::writePod(outputFile, sleepScreen);
serialization::writePod(outputFile, extraParagraphSpacing); serialization::writePod(outputFile, extraParagraphSpacing);
serialization::writePod(outputFile, shortPwrBtn); serialization::writePod(outputFile, shortPwrBtn);
serialization::writePod(outputFile, statusBar);
outputFile.close(); outputFile.close();
Serial.printf("[%lu] [CPS] Settings saved to file\n", millis()); Serial.printf("[%lu] [CPS] Settings saved to file\n", millis());
@ -60,6 +61,8 @@ bool CrossPointSettings::loadFromFile() {
if (++settingsRead >= fileSettingsCount) break; if (++settingsRead >= fileSettingsCount) break;
serialization::readPod(inputFile, shortPwrBtn); serialization::readPod(inputFile, shortPwrBtn);
if (++settingsRead >= fileSettingsCount) break; if (++settingsRead >= fileSettingsCount) break;
serialization::readPod(inputFile, statusBar);
if (++settingsRead >= fileSettingsCount) break;
} while (false); } while (false);
inputFile.close(); inputFile.close();

View File

@ -18,8 +18,13 @@ class CrossPointSettings {
// Should match with SettingsActivity text // Should match with SettingsActivity text
enum SLEEP_SCREEN_MODE { DARK = 0, LIGHT = 1, CUSTOM = 2, COVER = 3 }; 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 // Sleep screen settings
uint8_t sleepScreen = DARK; uint8_t sleepScreen = DARK;
// Status bar settings
uint8_t statusBar = FULL;
// Text rendering settings // Text rendering settings
uint8_t extraParagraphSpacing = 1; uint8_t extraParagraphSpacing = 1;
// Duration of the power button press // Duration of the power button press

View File

@ -340,71 +340,87 @@ void EpubReaderActivity::renderContents(std::unique_ptr<Page> page) {
} }
void EpubReaderActivity::renderStatusBar() const { 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; constexpr auto textY = 776;
int percentageTextWidth = 0;
int progressTextWidth = 0;
// Calculate progress in book if (showProgress) {
const float sectionChapterProg = static_cast<float>(section->currentPage) / section->pageCount; // Calculate progress in book
const uint8_t bookProgress = epub->calculateProgress(currentSpineIndex, sectionChapterProg); const float sectionChapterProg = static_cast<float>(section->currentPage) / section->pageCount;
const uint8_t bookProgress = epub->calculateProgress(currentSpineIndex, sectionChapterProg);
// Right aligned text for progress counter // Right aligned text for progress counter
const std::string progress = std::to_string(section->currentPage + 1) + "/" + std::to_string(section->pageCount) + const std::string progress = std::to_string(section->currentPage + 1) + "/" + std::to_string(section->pageCount) +
" " + std::to_string(bookProgress) + "%"; " " + std::to_string(bookProgress) + "%";
const auto progressTextWidth = renderer.getTextWidth(SMALL_FONT_ID, progress.c_str()); progressTextWidth = renderer.getTextWidth(SMALL_FONT_ID, progress.c_str());
renderer.drawText(SMALL_FONT_ID, GfxRenderer::getScreenWidth() - marginRight - progressTextWidth, textY, renderer.drawText(SMALL_FONT_ID, GfxRenderer::getScreenWidth() - marginRight - progressTextWidth, textY,
progress.c_str()); 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
} }
renderer.fillRect(x + 1, y + 1, filledWidth, batteryHeight - 2);
// Centered chatper title text if (showBattery) {
// Page width minus existing content with 30px padding on each side // Left aligned battery icon and percentage
const int titleMarginLeft = 20 + percentageTextWidth + 30 + marginLeft; const uint16_t percentage = battery.readPercentage();
const int titleMarginRight = progressTextWidth + 30 + marginRight; const auto percentageText = std::to_string(percentage) + "%";
const int availableTextWidth = GfxRenderer::getScreenWidth() - titleMarginLeft - titleMarginRight; percentageTextWidth = renderer.getTextWidth(SMALL_FONT_ID, percentageText.c_str());
const int tocIndex = epub->getTocIndexForSpineIndex(currentSpineIndex); renderer.drawText(SMALL_FONT_ID, 20 + marginLeft, textY, percentageText.c_str());
std::string title; // 1 column on left, 2 columns on right, 5 columns of battery body
int titleWidth; constexpr int batteryWidth = 15;
if (tocIndex == -1) { constexpr int batteryHeight = 10;
title = "Unnamed"; constexpr int x = marginLeft;
titleWidth = renderer.getTextWidth(SMALL_FONT_ID, "Unnamed"); constexpr int y = 783;
} else {
const auto tocItem = epub->getTocItem(tocIndex); // Top line
title = tocItem.title; renderer.drawLine(x, y, x + batteryWidth - 4, y);
titleWidth = renderer.getTextWidth(SMALL_FONT_ID, title.c_str()); // Bottom line
while (titleWidth > availableTextWidth && title.length() > 11) { renderer.drawLine(x, y + batteryHeight - 1, x + batteryWidth - 4, y + batteryHeight - 1);
title.replace(title.length() - 8, 8, "..."); // Left line
titleWidth = renderer.getTextWidth(SMALL_FONT_ID, title.c_str()); 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());
}
} }

View File

@ -9,10 +9,11 @@
// Define the static settings list // Define the static settings list
namespace { namespace {
constexpr int settingsCount = 4; constexpr int settingsCount = 5;
const SettingInfo settingsList[settingsCount] = { const SettingInfo settingsList[settingsCount] = {
// Should match with SLEEP_SCREEN_MODE // Should match with SLEEP_SCREEN_MODE
{"Sleep Screen", SettingType::ENUM, &CrossPointSettings::sleepScreen, {"Dark", "Light", "Custom", "Cover"}}, {"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, {}}, {"Extra Paragraph Spacing", SettingType::TOGGLE, &CrossPointSettings::extraParagraphSpacing, {}},
{"Short Power Button Click", SettingType::TOGGLE, &CrossPointSettings::shortPwrBtn, {}}, {"Short Power Button Click", SettingType::TOGGLE, &CrossPointSettings::shortPwrBtn, {}},
{"Check for updates", SettingType::ACTION, nullptr, {}}, {"Check for updates", SettingType::ACTION, nullptr, {}},