Movable status bar and dual-edge progress bars
This commit is contained in:
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
[submodule "open-x4-sdk"]
|
[submodule "open-x4-sdk"]
|
||||||
path = open-x4-sdk
|
path = open-x4-sdk
|
||||||
url = https://github.com/jpirnay/community-sdk.git
|
url = https://github.com/jpirnay/community-sdk.git
|
||||||
branch = main
|
branch = fear-sdcard-capacity
|
||||||
|
|||||||
@@ -301,6 +301,11 @@ STR_CHAPTER_PAGE_COUNT: "Chapter Page Count"
|
|||||||
STR_BOOK_PROGRESS_PERCENTAGE: "Book Progress Percentage"
|
STR_BOOK_PROGRESS_PERCENTAGE: "Book Progress Percentage"
|
||||||
STR_PROGRESS_BAR: "Progress Bar"
|
STR_PROGRESS_BAR: "Progress Bar"
|
||||||
STR_PROGRESS_BAR_THICKNESS: "Progress Bar Thickness"
|
STR_PROGRESS_BAR_THICKNESS: "Progress Bar Thickness"
|
||||||
|
STR_UPPER_PROGRESS_BAR: "Upper Progress Bar"
|
||||||
|
STR_UPPER_PROGRESS_BAR_THICKNESS: "Upper Progress Bar Thickness"
|
||||||
|
STR_LOWER_PROGRESS_BAR: "Lower Progress Bar"
|
||||||
|
STR_LOWER_PROGRESS_BAR_THICKNESS: "Lower Progress Bar Thickness"
|
||||||
|
STR_STATUS_ITEMS_POSITION: "Status Items Position"
|
||||||
STR_PROGRESS_BAR_THIN: "Thin"
|
STR_PROGRESS_BAR_THIN: "Thin"
|
||||||
STR_PROGRESS_BAR_MEDIUM: "Medium"
|
STR_PROGRESS_BAR_MEDIUM: "Medium"
|
||||||
STR_PROGRESS_BAR_THICK: "Thick"
|
STR_PROGRESS_BAR_THICK: "Thick"
|
||||||
@@ -311,6 +316,8 @@ STR_EXAMPLE_BOOK: "Book Title"
|
|||||||
STR_PREVIEW: "Preview"
|
STR_PREVIEW: "Preview"
|
||||||
STR_TITLE: "Title"
|
STR_TITLE: "Title"
|
||||||
STR_BATTERY: "Battery"
|
STR_BATTERY: "Battery"
|
||||||
|
STR_TOP: "Top"
|
||||||
|
STR_BOTTOM: "Bottom"
|
||||||
STR_UI_THEME: "UI Theme"
|
STR_UI_THEME: "UI Theme"
|
||||||
STR_THEME_CLASSIC: "Classic"
|
STR_THEME_CLASSIC: "Classic"
|
||||||
STR_THEME_LYRA: "Lyra"
|
STR_THEME_LYRA: "Lyra"
|
||||||
|
|||||||
@@ -59,6 +59,11 @@ class CrossPointSettings {
|
|||||||
STATUS_BAR_PROGRESS_BAR_THICKNESS_COUNT
|
STATUS_BAR_PROGRESS_BAR_THICKNESS_COUNT
|
||||||
};
|
};
|
||||||
enum STATUS_BAR_TITLE { BOOK_TITLE = 0, CHAPTER_TITLE = 1, HIDE_TITLE = 2, STATUS_BAR_TITLE_COUNT };
|
enum STATUS_BAR_TITLE { BOOK_TITLE = 0, CHAPTER_TITLE = 1, HIDE_TITLE = 2, STATUS_BAR_TITLE_COUNT };
|
||||||
|
enum STATUS_BAR_ITEMS_POSITION {
|
||||||
|
STATUS_BAR_ITEMS_TOP = 0,
|
||||||
|
STATUS_BAR_ITEMS_BOTTOM = 1,
|
||||||
|
STATUS_BAR_ITEMS_POSITION_COUNT
|
||||||
|
};
|
||||||
|
|
||||||
enum ORIENTATION {
|
enum ORIENTATION {
|
||||||
PORTRAIT = 0, // 480x800 logical coordinates (current default)
|
PORTRAIT = 0, // 480x800 logical coordinates (current default)
|
||||||
@@ -185,12 +190,17 @@ class CrossPointSettings {
|
|||||||
uint8_t sleepCoverOverlay = 0;
|
uint8_t sleepCoverOverlay = 0;
|
||||||
// Sleep image pick mode (random vs sequential walk-through)
|
// Sleep image pick mode (random vs sequential walk-through)
|
||||||
uint8_t sleepImagePickMode = PICK_RANDOM;
|
uint8_t sleepImagePickMode = PICK_RANDOM;
|
||||||
// Status bar settings (statusBar retained for migration only)
|
// Status bar settings (statusBar, statusBarProgressBar, statusBarProgressBarThickness retained for migration only)
|
||||||
uint8_t statusBar = FULL;
|
uint8_t statusBar = FULL;
|
||||||
uint8_t statusBarChapterPageCount = 1;
|
uint8_t statusBarChapterPageCount = 1;
|
||||||
uint8_t statusBarBookProgressPercentage = 1;
|
uint8_t statusBarBookProgressPercentage = 1;
|
||||||
uint8_t statusBarProgressBar = HIDE_PROGRESS;
|
uint8_t statusBarProgressBar = HIDE_PROGRESS;
|
||||||
uint8_t statusBarProgressBarThickness = PROGRESS_BAR_NORMAL;
|
uint8_t statusBarProgressBarThickness = PROGRESS_BAR_NORMAL;
|
||||||
|
uint8_t statusBarUpperProgressBar = HIDE_PROGRESS;
|
||||||
|
uint8_t statusBarUpperProgressBarThickness = PROGRESS_BAR_NORMAL;
|
||||||
|
uint8_t statusBarLowerProgressBar = HIDE_PROGRESS;
|
||||||
|
uint8_t statusBarLowerProgressBarThickness = PROGRESS_BAR_NORMAL;
|
||||||
|
uint8_t statusBarItemsPosition = STATUS_BAR_ITEMS_BOTTOM;
|
||||||
uint8_t statusBarTitle = CHAPTER_TITLE;
|
uint8_t statusBarTitle = CHAPTER_TITLE;
|
||||||
uint8_t statusBarBattery = 1;
|
uint8_t statusBarBattery = 1;
|
||||||
// Text rendering settings
|
// Text rendering settings
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ void applyLegacyStatusBarSettings(CrossPointSettings& settings) {
|
|||||||
settings.statusBarChapterPageCount = 0;
|
settings.statusBarChapterPageCount = 0;
|
||||||
settings.statusBarBookProgressPercentage = 0;
|
settings.statusBarBookProgressPercentage = 0;
|
||||||
settings.statusBarProgressBar = CrossPointSettings::HIDE_PROGRESS;
|
settings.statusBarProgressBar = CrossPointSettings::HIDE_PROGRESS;
|
||||||
|
settings.statusBarLowerProgressBar = CrossPointSettings::HIDE_PROGRESS;
|
||||||
settings.statusBarTitle = CrossPointSettings::HIDE_TITLE;
|
settings.statusBarTitle = CrossPointSettings::HIDE_TITLE;
|
||||||
settings.statusBarBattery = 0;
|
settings.statusBarBattery = 0;
|
||||||
break;
|
break;
|
||||||
@@ -31,6 +32,7 @@ void applyLegacyStatusBarSettings(CrossPointSettings& settings) {
|
|||||||
settings.statusBarChapterPageCount = 0;
|
settings.statusBarChapterPageCount = 0;
|
||||||
settings.statusBarBookProgressPercentage = 0;
|
settings.statusBarBookProgressPercentage = 0;
|
||||||
settings.statusBarProgressBar = CrossPointSettings::HIDE_PROGRESS;
|
settings.statusBarProgressBar = CrossPointSettings::HIDE_PROGRESS;
|
||||||
|
settings.statusBarLowerProgressBar = CrossPointSettings::HIDE_PROGRESS;
|
||||||
settings.statusBarTitle = CrossPointSettings::CHAPTER_TITLE;
|
settings.statusBarTitle = CrossPointSettings::CHAPTER_TITLE;
|
||||||
settings.statusBarBattery = 1;
|
settings.statusBarBattery = 1;
|
||||||
break;
|
break;
|
||||||
@@ -38,6 +40,7 @@ void applyLegacyStatusBarSettings(CrossPointSettings& settings) {
|
|||||||
settings.statusBarChapterPageCount = 1;
|
settings.statusBarChapterPageCount = 1;
|
||||||
settings.statusBarBookProgressPercentage = 0;
|
settings.statusBarBookProgressPercentage = 0;
|
||||||
settings.statusBarProgressBar = CrossPointSettings::BOOK_PROGRESS;
|
settings.statusBarProgressBar = CrossPointSettings::BOOK_PROGRESS;
|
||||||
|
settings.statusBarLowerProgressBar = CrossPointSettings::BOOK_PROGRESS;
|
||||||
settings.statusBarTitle = CrossPointSettings::CHAPTER_TITLE;
|
settings.statusBarTitle = CrossPointSettings::CHAPTER_TITLE;
|
||||||
settings.statusBarBattery = 1;
|
settings.statusBarBattery = 1;
|
||||||
break;
|
break;
|
||||||
@@ -45,6 +48,7 @@ void applyLegacyStatusBarSettings(CrossPointSettings& settings) {
|
|||||||
settings.statusBarChapterPageCount = 1;
|
settings.statusBarChapterPageCount = 1;
|
||||||
settings.statusBarBookProgressPercentage = 0;
|
settings.statusBarBookProgressPercentage = 0;
|
||||||
settings.statusBarProgressBar = CrossPointSettings::BOOK_PROGRESS;
|
settings.statusBarProgressBar = CrossPointSettings::BOOK_PROGRESS;
|
||||||
|
settings.statusBarLowerProgressBar = CrossPointSettings::BOOK_PROGRESS;
|
||||||
settings.statusBarTitle = CrossPointSettings::HIDE_TITLE;
|
settings.statusBarTitle = CrossPointSettings::HIDE_TITLE;
|
||||||
settings.statusBarBattery = 0;
|
settings.statusBarBattery = 0;
|
||||||
break;
|
break;
|
||||||
@@ -52,6 +56,7 @@ void applyLegacyStatusBarSettings(CrossPointSettings& settings) {
|
|||||||
settings.statusBarChapterPageCount = 0;
|
settings.statusBarChapterPageCount = 0;
|
||||||
settings.statusBarBookProgressPercentage = 1;
|
settings.statusBarBookProgressPercentage = 1;
|
||||||
settings.statusBarProgressBar = CrossPointSettings::CHAPTER_PROGRESS;
|
settings.statusBarProgressBar = CrossPointSettings::CHAPTER_PROGRESS;
|
||||||
|
settings.statusBarLowerProgressBar = CrossPointSettings::CHAPTER_PROGRESS;
|
||||||
settings.statusBarTitle = CrossPointSettings::CHAPTER_TITLE;
|
settings.statusBarTitle = CrossPointSettings::CHAPTER_TITLE;
|
||||||
settings.statusBarBattery = 1;
|
settings.statusBarBattery = 1;
|
||||||
break;
|
break;
|
||||||
@@ -60,10 +65,16 @@ void applyLegacyStatusBarSettings(CrossPointSettings& settings) {
|
|||||||
settings.statusBarChapterPageCount = 1;
|
settings.statusBarChapterPageCount = 1;
|
||||||
settings.statusBarBookProgressPercentage = 1;
|
settings.statusBarBookProgressPercentage = 1;
|
||||||
settings.statusBarProgressBar = CrossPointSettings::HIDE_PROGRESS;
|
settings.statusBarProgressBar = CrossPointSettings::HIDE_PROGRESS;
|
||||||
|
settings.statusBarLowerProgressBar = CrossPointSettings::HIDE_PROGRESS;
|
||||||
settings.statusBarTitle = CrossPointSettings::CHAPTER_TITLE;
|
settings.statusBarTitle = CrossPointSettings::CHAPTER_TITLE;
|
||||||
settings.statusBarBattery = 1;
|
settings.statusBarBattery = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
settings.statusBarUpperProgressBar = CrossPointSettings::HIDE_PROGRESS;
|
||||||
|
settings.statusBarUpperProgressBarThickness = CrossPointSettings::PROGRESS_BAR_NORMAL;
|
||||||
|
settings.statusBarLowerProgressBarThickness = settings.statusBarProgressBarThickness;
|
||||||
|
settings.statusBarItemsPosition = CrossPointSettings::STATUS_BAR_ITEMS_BOTTOM;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---- CrossPointState ----
|
// ---- CrossPointState ----
|
||||||
@@ -215,9 +226,35 @@ bool JsonSettingsIO::loadSettings(CrossPointSettings& s, const char* json, bool*
|
|||||||
// Legacy migration: if statusBarChapterPageCount is absent this is a pre-refactor settings file.
|
// Legacy migration: if statusBarChapterPageCount is absent this is a pre-refactor settings file.
|
||||||
// Populate s with migrated values now so the generic loop below picks them up as defaults and clamps them.
|
// Populate s with migrated values now so the generic loop below picks them up as defaults and clamps them.
|
||||||
if (doc["statusBarChapterPageCount"].isNull()) {
|
if (doc["statusBarChapterPageCount"].isNull()) {
|
||||||
|
s.statusBar = clamp(doc["statusBar"] | s.statusBar, CrossPointSettings::STATUS_BAR_MODE_COUNT, s.statusBar);
|
||||||
applyLegacyStatusBarSettings(s);
|
applyLegacyStatusBarSettings(s);
|
||||||
|
if (needsResave) *needsResave = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto migrateMissingStatusSetting = [&doc, &needsResave, &clamp](const char* newKey, uint8_t& value,
|
||||||
|
const char* legacyKey, uint8_t defaultValue,
|
||||||
|
uint8_t count) {
|
||||||
|
if (!doc[newKey].isNull()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
value = clamp(doc[legacyKey] | defaultValue, count, defaultValue);
|
||||||
|
if (needsResave) *needsResave = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
migrateMissingStatusSetting("statusBarUpperProgressBar", s.statusBarUpperProgressBar, "statusBarUpperProgressBar",
|
||||||
|
CrossPointSettings::HIDE_PROGRESS, CrossPointSettings::STATUS_BAR_PROGRESS_BAR_COUNT);
|
||||||
|
migrateMissingStatusSetting("statusBarUpperProgressBarThickness", s.statusBarUpperProgressBarThickness,
|
||||||
|
"statusBarUpperProgressBarThickness", CrossPointSettings::PROGRESS_BAR_NORMAL,
|
||||||
|
CrossPointSettings::STATUS_BAR_PROGRESS_BAR_THICKNESS_COUNT);
|
||||||
|
migrateMissingStatusSetting("statusBarLowerProgressBar", s.statusBarLowerProgressBar, "statusBarProgressBar",
|
||||||
|
s.statusBarProgressBar, CrossPointSettings::STATUS_BAR_PROGRESS_BAR_COUNT);
|
||||||
|
migrateMissingStatusSetting("statusBarLowerProgressBarThickness", s.statusBarLowerProgressBarThickness,
|
||||||
|
"statusBarProgressBarThickness", s.statusBarProgressBarThickness,
|
||||||
|
CrossPointSettings::STATUS_BAR_PROGRESS_BAR_THICKNESS_COUNT);
|
||||||
|
migrateMissingStatusSetting("statusBarItemsPosition", s.statusBarItemsPosition, "statusBarItemsPosition",
|
||||||
|
CrossPointSettings::STATUS_BAR_ITEMS_BOTTOM,
|
||||||
|
CrossPointSettings::STATUS_BAR_ITEMS_POSITION_COUNT);
|
||||||
|
|
||||||
for (const auto& info : getSettingsList()) {
|
for (const auto& info : getSettingsList()) {
|
||||||
if (!info.key) continue;
|
if (!info.key) continue;
|
||||||
// Dynamic entries (KOReader etc.) are stored in their own files — skip.
|
// Dynamic entries (KOReader etc.) are stored in their own files — skip.
|
||||||
|
|||||||
+14
-6
@@ -278,16 +278,18 @@ inline const std::vector<SettingInfo> list = {
|
|||||||
StrId::STR_KOREADER_SYNC),
|
StrId::STR_KOREADER_SYNC),
|
||||||
|
|
||||||
// --- Status Bar Settings (web-only, uses StatusBarSettingsActivity) ---
|
// --- Status Bar Settings (web-only, uses StatusBarSettingsActivity) ---
|
||||||
|
SettingInfo::Enum(StrId::STR_UPPER_PROGRESS_BAR, &CrossPointSettings::statusBarUpperProgressBar,
|
||||||
|
{StrId::STR_BOOK, StrId::STR_CHAPTER, StrId::STR_HIDE}, "statusBarUpperProgressBar",
|
||||||
|
StrId::STR_CUSTOMISE_STATUS_BAR),
|
||||||
|
SettingInfo::Enum(StrId::STR_UPPER_PROGRESS_BAR_THICKNESS, &CrossPointSettings::statusBarUpperProgressBarThickness,
|
||||||
|
{StrId::STR_PROGRESS_BAR_THIN, StrId::STR_PROGRESS_BAR_MEDIUM, StrId::STR_PROGRESS_BAR_THICK},
|
||||||
|
"statusBarUpperProgressBarThickness", StrId::STR_CUSTOMISE_STATUS_BAR),
|
||||||
|
SettingInfo::Enum(StrId::STR_STATUS_ITEMS_POSITION, &CrossPointSettings::statusBarItemsPosition,
|
||||||
|
{StrId::STR_TOP, StrId::STR_BOTTOM}, "statusBarItemsPosition", StrId::STR_CUSTOMISE_STATUS_BAR),
|
||||||
SettingInfo::Toggle(StrId::STR_CHAPTER_PAGE_COUNT, &CrossPointSettings::statusBarChapterPageCount,
|
SettingInfo::Toggle(StrId::STR_CHAPTER_PAGE_COUNT, &CrossPointSettings::statusBarChapterPageCount,
|
||||||
"statusBarChapterPageCount", StrId::STR_CUSTOMISE_STATUS_BAR),
|
"statusBarChapterPageCount", StrId::STR_CUSTOMISE_STATUS_BAR),
|
||||||
SettingInfo::Toggle(StrId::STR_BOOK_PROGRESS_PERCENTAGE, &CrossPointSettings::statusBarBookProgressPercentage,
|
SettingInfo::Toggle(StrId::STR_BOOK_PROGRESS_PERCENTAGE, &CrossPointSettings::statusBarBookProgressPercentage,
|
||||||
"statusBarBookProgressPercentage", StrId::STR_CUSTOMISE_STATUS_BAR),
|
"statusBarBookProgressPercentage", StrId::STR_CUSTOMISE_STATUS_BAR),
|
||||||
SettingInfo::Enum(StrId::STR_PROGRESS_BAR, &CrossPointSettings::statusBarProgressBar,
|
|
||||||
{StrId::STR_BOOK, StrId::STR_CHAPTER, StrId::STR_HIDE}, "statusBarProgressBar",
|
|
||||||
StrId::STR_CUSTOMISE_STATUS_BAR),
|
|
||||||
SettingInfo::Enum(StrId::STR_PROGRESS_BAR_THICKNESS, &CrossPointSettings::statusBarProgressBarThickness,
|
|
||||||
{StrId::STR_PROGRESS_BAR_THIN, StrId::STR_PROGRESS_BAR_MEDIUM, StrId::STR_PROGRESS_BAR_THICK},
|
|
||||||
"statusBarProgressBarThickness", StrId::STR_CUSTOMISE_STATUS_BAR),
|
|
||||||
SettingInfo::Enum(StrId::STR_TITLE, &CrossPointSettings::statusBarTitle,
|
SettingInfo::Enum(StrId::STR_TITLE, &CrossPointSettings::statusBarTitle,
|
||||||
{StrId::STR_BOOK, StrId::STR_CHAPTER, StrId::STR_HIDE}, "statusBarTitle",
|
{StrId::STR_BOOK, StrId::STR_CHAPTER, StrId::STR_HIDE}, "statusBarTitle",
|
||||||
StrId::STR_CUSTOMISE_STATUS_BAR),
|
StrId::STR_CUSTOMISE_STATUS_BAR),
|
||||||
@@ -295,6 +297,12 @@ inline const std::vector<SettingInfo> list = {
|
|||||||
StrId::STR_CUSTOMISE_STATUS_BAR),
|
StrId::STR_CUSTOMISE_STATUS_BAR),
|
||||||
SettingInfo::Toggle(StrId::STR_CLOCK, &CrossPointSettings::statusBarClock, "statusBarClock",
|
SettingInfo::Toggle(StrId::STR_CLOCK, &CrossPointSettings::statusBarClock, "statusBarClock",
|
||||||
StrId::STR_CUSTOMISE_STATUS_BAR),
|
StrId::STR_CUSTOMISE_STATUS_BAR),
|
||||||
|
SettingInfo::Enum(StrId::STR_LOWER_PROGRESS_BAR, &CrossPointSettings::statusBarLowerProgressBar,
|
||||||
|
{StrId::STR_BOOK, StrId::STR_CHAPTER, StrId::STR_HIDE}, "statusBarLowerProgressBar",
|
||||||
|
StrId::STR_CUSTOMISE_STATUS_BAR),
|
||||||
|
SettingInfo::Enum(StrId::STR_LOWER_PROGRESS_BAR_THICKNESS, &CrossPointSettings::statusBarLowerProgressBarThickness,
|
||||||
|
{StrId::STR_PROGRESS_BAR_THIN, StrId::STR_PROGRESS_BAR_MEDIUM, StrId::STR_PROGRESS_BAR_THICK},
|
||||||
|
"statusBarLowerProgressBarThickness", StrId::STR_CUSTOMISE_STATUS_BAR),
|
||||||
};
|
};
|
||||||
} // namespace SettingsListDetail
|
} // namespace SettingsListDetail
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
#include <esp_heap_caps.h>
|
#include <esp_heap_caps.h>
|
||||||
#include <esp_system.h>
|
#include <esp_system.h>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include "CrossPointSettings.h"
|
#include "CrossPointSettings.h"
|
||||||
@@ -111,6 +112,27 @@ const char* orientationToString(const GfxRenderer::Orientation orientation) {
|
|||||||
return "Unknown";
|
return "Unknown";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int getImageOnlyPageYOffset(const Page& page, const int viewportHeight) {
|
||||||
|
if (viewportHeight <= 0 || page.elements.empty()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const bool imageOnlyPage = std::all_of(
|
||||||
|
page.elements.begin(), page.elements.end(),
|
||||||
|
[](const std::shared_ptr<PageElement>& element) { return element && element->getTag() == TAG_PageImage; });
|
||||||
|
if (!imageOnlyPage) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16_t imgX, imgY, imgW, imgH;
|
||||||
|
if (!page.getImageBoundingBox(imgX, imgY, imgW, imgH) || imgH >= viewportHeight) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int centeredTop = (viewportHeight - imgH) / 2;
|
||||||
|
return std::max(0, centeredTop - static_cast<int>(imgY));
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
void EpubReaderActivity::onEnter() {
|
void EpubReaderActivity::onEnter() {
|
||||||
@@ -241,7 +263,7 @@ void EpubReaderActivity::loop() {
|
|||||||
if (mappedInput.wasReleased(MappedInputManager::Button::Confirm) ||
|
if (mappedInput.wasReleased(MappedInputManager::Button::Confirm) ||
|
||||||
mappedInput.wasReleased(MappedInputManager::Button::Back)) {
|
mappedInput.wasReleased(MappedInputManager::Button::Back)) {
|
||||||
buttonEvents.drain();
|
buttonEvents.drain();
|
||||||
automaticPageTurnActive = false;
|
stopAutomaticPageTurn();
|
||||||
// updates chapter title space to indicate page turn disabled
|
// updates chapter title space to indicate page turn disabled
|
||||||
requestUpdate();
|
requestUpdate();
|
||||||
return;
|
return;
|
||||||
@@ -1009,9 +1031,30 @@ void EpubReaderActivity::applyTextDarkness(const uint8_t textDarkness) {
|
|||||||
requestUpdate();
|
requestUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EpubReaderActivity::stopAutomaticPageTurn() {
|
||||||
|
if (!automaticPageTurnActive) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
automaticPageTurnActive = false;
|
||||||
|
|
||||||
|
if (UITheme::getStatusBarHeight(true) == UITheme::getStatusBarHeight()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Preserve current reading position so we can restore after reflow.
|
||||||
|
RenderLock lock(*this);
|
||||||
|
if (section) {
|
||||||
|
cachedSpineIndex = currentSpineIndex;
|
||||||
|
cachedChapterTotalPageCount = section->pageCount;
|
||||||
|
nextPageNumber = section->currentPage;
|
||||||
|
}
|
||||||
|
section.reset();
|
||||||
|
}
|
||||||
|
|
||||||
void EpubReaderActivity::toggleAutoPageTurn(const uint8_t selectedPageTurnOption) {
|
void EpubReaderActivity::toggleAutoPageTurn(const uint8_t selectedPageTurnOption) {
|
||||||
if (selectedPageTurnOption == 0 || selectedPageTurnOption >= std::size(PAGE_TURN_LABELS)) {
|
if (selectedPageTurnOption == 0 || selectedPageTurnOption >= std::size(PAGE_TURN_LABELS)) {
|
||||||
automaticPageTurnActive = false;
|
stopAutomaticPageTurn();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1020,9 +1063,8 @@ void EpubReaderActivity::toggleAutoPageTurn(const uint8_t selectedPageTurnOption
|
|||||||
pageTurnDuration = (1UL * 60 * 1000) / PAGE_TURN_LABELS[selectedPageTurnOption];
|
pageTurnDuration = (1UL * 60 * 1000) / PAGE_TURN_LABELS[selectedPageTurnOption];
|
||||||
automaticPageTurnActive = true;
|
automaticPageTurnActive = true;
|
||||||
|
|
||||||
const uint8_t statusBarHeight = UITheme::getInstance().getStatusBarHeight();
|
// Reset cached section when automatic page turn adds a forced status item band.
|
||||||
// resets cached section so that space is reserved for auto page turn indicator when None or progress bar only
|
if (UITheme::getStatusBarHeight(true) != UITheme::getStatusBarHeight()) {
|
||||||
if (statusBarHeight == 0 || statusBarHeight == UITheme::getInstance().getProgressBarHeight()) {
|
|
||||||
// Preserve current reading position so we can restore after reflow.
|
// Preserve current reading position so we can restore after reflow.
|
||||||
RenderLock lock(*this);
|
RenderLock lock(*this);
|
||||||
if (section) {
|
if (section) {
|
||||||
@@ -1223,21 +1265,13 @@ void EpubReaderActivity::render(RenderLock&& lock) {
|
|||||||
int orientedMarginTop, orientedMarginRight, orientedMarginBottom, orientedMarginLeft;
|
int orientedMarginTop, orientedMarginRight, orientedMarginBottom, orientedMarginLeft;
|
||||||
renderer.getOrientedViewableTRBL(&orientedMarginTop, &orientedMarginRight, &orientedMarginBottom,
|
renderer.getOrientedViewableTRBL(&orientedMarginTop, &orientedMarginRight, &orientedMarginBottom,
|
||||||
&orientedMarginLeft);
|
&orientedMarginLeft);
|
||||||
orientedMarginTop += SETTINGS.screenMargin;
|
const int statusBarTopHeight = UITheme::getStatusBarTopHeight(automaticPageTurnActive);
|
||||||
|
const int statusBarBottomHeight = UITheme::getStatusBarBottomHeight(automaticPageTurnActive);
|
||||||
|
|
||||||
|
orientedMarginTop += std::max(static_cast<int>(SETTINGS.screenMargin), statusBarTopHeight);
|
||||||
orientedMarginLeft += SETTINGS.screenMargin;
|
orientedMarginLeft += SETTINGS.screenMargin;
|
||||||
orientedMarginRight += SETTINGS.screenMargin;
|
orientedMarginRight += SETTINGS.screenMargin;
|
||||||
|
orientedMarginBottom += std::max(static_cast<int>(SETTINGS.screenMargin), statusBarBottomHeight);
|
||||||
const uint8_t statusBarHeight = UITheme::getInstance().getStatusBarHeight();
|
|
||||||
|
|
||||||
// reserves space for automatic page turn indicator when no status bar or progress bar only
|
|
||||||
if (automaticPageTurnActive &&
|
|
||||||
(statusBarHeight == 0 || statusBarHeight == UITheme::getInstance().getProgressBarHeight())) {
|
|
||||||
orientedMarginBottom +=
|
|
||||||
std::max(SETTINGS.screenMargin,
|
|
||||||
static_cast<uint8_t>(statusBarHeight + UITheme::getInstance().getMetrics().statusBarVerticalMargin));
|
|
||||||
} else {
|
|
||||||
orientedMarginBottom += std::max(SETTINGS.screenMargin, statusBarHeight);
|
|
||||||
}
|
|
||||||
|
|
||||||
const uint16_t viewportWidth = renderer.getScreenWidth() - orientedMarginLeft - orientedMarginRight;
|
const uint16_t viewportWidth = renderer.getScreenWidth() - orientedMarginLeft - orientedMarginRight;
|
||||||
const uint16_t viewportHeight = renderer.getScreenHeight() - orientedMarginTop - orientedMarginBottom;
|
const uint16_t viewportHeight = renderer.getScreenHeight() - orientedMarginTop - orientedMarginBottom;
|
||||||
@@ -1485,10 +1519,13 @@ void EpubReaderActivity::renderContents(std::unique_ptr<Page> page, const int or
|
|||||||
fcm->resetStats();
|
fcm->resetStats();
|
||||||
logReaderMemSnapshot("prewarm_begin");
|
logReaderMemSnapshot("prewarm_begin");
|
||||||
|
|
||||||
|
const int viewportHeight = std::max(0, renderer.getScreenHeight() - orientedMarginTop - orientedMarginBottom);
|
||||||
|
const int contentTop = orientedMarginTop + getImageOnlyPageYOffset(*page, viewportHeight);
|
||||||
|
|
||||||
// Font prewarm: scan pass accumulates text, then prewarm, then real render
|
// Font prewarm: scan pass accumulates text, then prewarm, then real render
|
||||||
const uint32_t heapBefore = esp_get_free_heap_size();
|
const uint32_t heapBefore = esp_get_free_heap_size();
|
||||||
auto scope = fcm->createPrewarmScope();
|
auto scope = fcm->createPrewarmScope();
|
||||||
page->render(renderer, getEffectiveReaderFontId(), orientedMarginLeft, orientedMarginTop); // scan pass
|
page->render(renderer, getEffectiveReaderFontId(), orientedMarginLeft, contentTop); // scan pass
|
||||||
scope.endScanAndPrewarm();
|
scope.endScanAndPrewarm();
|
||||||
const uint32_t heapAfter = esp_get_free_heap_size();
|
const uint32_t heapAfter = esp_get_free_heap_size();
|
||||||
fcm->logStats("prewarm");
|
fcm->logStats("prewarm");
|
||||||
@@ -1506,7 +1543,7 @@ void EpubReaderActivity::renderContents(std::unique_ptr<Page> page, const int or
|
|||||||
lastRenderStats.forcedHalfRefresh = forceHalfRefreshThisPage;
|
lastRenderStats.forcedHalfRefresh = forceHalfRefreshThisPage;
|
||||||
|
|
||||||
logReaderMemSnapshot("before_bw_render");
|
logReaderMemSnapshot("before_bw_render");
|
||||||
page->render(renderer, getEffectiveReaderFontId(), orientedMarginLeft, orientedMarginTop);
|
page->render(renderer, getEffectiveReaderFontId(), orientedMarginLeft, contentTop);
|
||||||
renderStatusBar();
|
renderStatusBar();
|
||||||
fcm->logStats("bw_render");
|
fcm->logStats("bw_render");
|
||||||
const auto tBwRender = millis();
|
const auto tBwRender = millis();
|
||||||
@@ -1520,12 +1557,12 @@ void EpubReaderActivity::renderContents(std::unique_ptr<Page> page, const int or
|
|||||||
// Step 2: Re-render with images and display again (images appear clean)
|
// Step 2: Re-render with images and display again (images appear clean)
|
||||||
int16_t imgX, imgY, imgW, imgH;
|
int16_t imgX, imgY, imgW, imgH;
|
||||||
if (page->getImageBoundingBox(imgX, imgY, imgW, imgH)) {
|
if (page->getImageBoundingBox(imgX, imgY, imgW, imgH)) {
|
||||||
renderer.fillRect(imgX + orientedMarginLeft, imgY + orientedMarginTop, imgW, imgH, false);
|
renderer.fillRect(imgX + orientedMarginLeft, imgY + contentTop, imgW, imgH, false);
|
||||||
renderer.displayBuffer(HalDisplay::FAST_REFRESH);
|
renderer.displayBuffer(HalDisplay::FAST_REFRESH);
|
||||||
|
|
||||||
// Re-render page content to restore images into the blanked area
|
// Re-render page content to restore images into the blanked area
|
||||||
// Status bar is not re-rendered here to avoid reading stale dynamic values (e.g. battery %)
|
// Status bar is not re-rendered here to avoid reading stale dynamic values (e.g. battery %)
|
||||||
page->render(renderer, getEffectiveReaderFontId(), orientedMarginLeft, orientedMarginTop);
|
page->render(renderer, getEffectiveReaderFontId(), orientedMarginLeft, contentTop);
|
||||||
renderer.displayBuffer(HalDisplay::FAST_REFRESH);
|
renderer.displayBuffer(HalDisplay::FAST_REFRESH);
|
||||||
} else {
|
} else {
|
||||||
renderer.displayBuffer(HalDisplay::HALF_REFRESH);
|
renderer.displayBuffer(HalDisplay::HALF_REFRESH);
|
||||||
@@ -1558,7 +1595,7 @@ void EpubReaderActivity::renderContents(std::unique_ptr<Page> page, const int or
|
|||||||
logReaderMemSnapshot("gray_lsb_begin");
|
logReaderMemSnapshot("gray_lsb_begin");
|
||||||
renderer.clearScreen(0x00);
|
renderer.clearScreen(0x00);
|
||||||
renderer.setRenderMode(GfxRenderer::GRAYSCALE_LSB);
|
renderer.setRenderMode(GfxRenderer::GRAYSCALE_LSB);
|
||||||
page->render(renderer, getEffectiveReaderFontId(), orientedMarginLeft, orientedMarginTop);
|
page->render(renderer, getEffectiveReaderFontId(), orientedMarginLeft, contentTop);
|
||||||
renderer.copyGrayscaleLsbBuffers();
|
renderer.copyGrayscaleLsbBuffers();
|
||||||
const auto tGrayLsb = millis();
|
const auto tGrayLsb = millis();
|
||||||
logReaderMemSnapshot("gray_lsb_end");
|
logReaderMemSnapshot("gray_lsb_end");
|
||||||
@@ -1567,7 +1604,7 @@ void EpubReaderActivity::renderContents(std::unique_ptr<Page> page, const int or
|
|||||||
logReaderMemSnapshot("gray_msb_begin");
|
logReaderMemSnapshot("gray_msb_begin");
|
||||||
renderer.clearScreen(0x00);
|
renderer.clearScreen(0x00);
|
||||||
renderer.setRenderMode(GfxRenderer::GRAYSCALE_MSB);
|
renderer.setRenderMode(GfxRenderer::GRAYSCALE_MSB);
|
||||||
page->render(renderer, getEffectiveReaderFontId(), orientedMarginLeft, orientedMarginTop);
|
page->render(renderer, getEffectiveReaderFontId(), orientedMarginLeft, contentTop);
|
||||||
renderer.copyGrayscaleMsbBuffers();
|
renderer.copyGrayscaleMsbBuffers();
|
||||||
const auto tGrayMsb = millis();
|
const auto tGrayMsb = millis();
|
||||||
logReaderMemSnapshot("gray_msb_end");
|
logReaderMemSnapshot("gray_msb_end");
|
||||||
@@ -1638,16 +1675,9 @@ void EpubReaderActivity::renderStatusBar() const {
|
|||||||
const float bookProgress = epub->calculateProgress(currentSpineIndex, sectionChapterProg) * 100;
|
const float bookProgress = epub->calculateProgress(currentSpineIndex, sectionChapterProg) * 100;
|
||||||
|
|
||||||
std::string title;
|
std::string title;
|
||||||
int textYOffset = 0;
|
|
||||||
|
|
||||||
if (automaticPageTurnActive) {
|
if (automaticPageTurnActive) {
|
||||||
title = tr(STR_AUTO_TURN_ENABLED) + std::to_string(60 * 1000 / pageTurnDuration);
|
title = tr(STR_AUTO_TURN_ENABLED) + std::to_string(60 * 1000 / pageTurnDuration);
|
||||||
|
|
||||||
const uint8_t statusBarHeight = UITheme::getInstance().getStatusBarHeight();
|
|
||||||
if (statusBarHeight == 0 || statusBarHeight == UITheme::getInstance().getProgressBarHeight()) {
|
|
||||||
textYOffset += UITheme::getInstance().getMetrics().statusBarVerticalMargin;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if (SETTINGS.statusBarTitle == CrossPointSettings::STATUS_BAR_TITLE::CHAPTER_TITLE) {
|
} else if (SETTINGS.statusBarTitle == CrossPointSettings::STATUS_BAR_TITLE::CHAPTER_TITLE) {
|
||||||
const int tocIndex =
|
const int tocIndex =
|
||||||
section ? section->getTocIndexForPage(section->currentPage) : epub->getTocIndexForSpineIndex(currentSpineIndex);
|
section ? section->getTocIndexForPage(section->currentPage) : epub->getTocIndexForSpineIndex(currentSpineIndex);
|
||||||
@@ -1663,7 +1693,7 @@ void EpubReaderActivity::renderStatusBar() const {
|
|||||||
|
|
||||||
const bool isStarred = section && bookmarkStore.has(static_cast<uint16_t>(currentSpineIndex),
|
const bool isStarred = section && bookmarkStore.has(static_cast<uint16_t>(currentSpineIndex),
|
||||||
static_cast<uint16_t>(section->currentPage));
|
static_cast<uint16_t>(section->currentPage));
|
||||||
GUI.drawStatusBar(renderer, bookProgress, currentPage, pageCount, title, 0, textYOffset, isStarred);
|
GUI.drawStatusBar(renderer, bookProgress, currentPage, pageCount, title, 0, isStarred);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EpubReaderActivity::navigateToHref(const std::string& hrefStr, const bool savePosition) {
|
void EpubReaderActivity::navigateToHref(const std::string& hrefStr, const bool savePosition) {
|
||||||
@@ -1754,11 +1784,10 @@ bool EpubReaderActivity::drawCurrentPageToBuffer(const std::string& filePath, Gf
|
|||||||
// Compute margins exactly as render() does
|
// Compute margins exactly as render() does
|
||||||
int marginTop, marginRight, marginBottom, marginLeft;
|
int marginTop, marginRight, marginBottom, marginLeft;
|
||||||
renderer.getOrientedViewableTRBL(&marginTop, &marginRight, &marginBottom, &marginLeft);
|
renderer.getOrientedViewableTRBL(&marginTop, &marginRight, &marginBottom, &marginLeft);
|
||||||
marginTop += SETTINGS.screenMargin;
|
marginTop += std::max(static_cast<int>(SETTINGS.screenMargin), UITheme::getStatusBarTopHeight());
|
||||||
marginLeft += SETTINGS.screenMargin;
|
marginLeft += SETTINGS.screenMargin;
|
||||||
marginRight += SETTINGS.screenMargin;
|
marginRight += SETTINGS.screenMargin;
|
||||||
const uint8_t statusBarHeight = UITheme::getInstance().getStatusBarHeight();
|
marginBottom += std::max(static_cast<int>(SETTINGS.screenMargin), UITheme::getStatusBarBottomHeight());
|
||||||
marginBottom += std::max(SETTINGS.screenMargin, statusBarHeight);
|
|
||||||
|
|
||||||
const uint16_t viewportWidth = renderer.getScreenWidth() - marginLeft - marginRight;
|
const uint16_t viewportWidth = renderer.getScreenWidth() - marginLeft - marginRight;
|
||||||
const uint16_t viewportHeight = renderer.getScreenHeight() - marginTop - marginBottom;
|
const uint16_t viewportHeight = renderer.getScreenHeight() - marginTop - marginBottom;
|
||||||
|
|||||||
@@ -177,6 +177,7 @@ class EpubReaderActivity final : public Activity {
|
|||||||
void applyOrientation(uint8_t orientation);
|
void applyOrientation(uint8_t orientation);
|
||||||
void applyTextDarkness(uint8_t textDarkness);
|
void applyTextDarkness(uint8_t textDarkness);
|
||||||
void toggleAutoPageTurn(uint8_t selectedPageTurnOption);
|
void toggleAutoPageTurn(uint8_t selectedPageTurnOption);
|
||||||
|
void stopAutomaticPageTurn();
|
||||||
void applyBookReaderOverrides(int8_t embeddedStyleOverride, int8_t imageRenderingOverride, int8_t fontFamilyOverride,
|
void applyBookReaderOverrides(int8_t embeddedStyleOverride, int8_t imageRenderingOverride, int8_t fontFamilyOverride,
|
||||||
const std::string& sdFontFamilyOverride, int8_t fontSizeOverride,
|
const std::string& sdFontFamilyOverride, int8_t fontSizeOverride,
|
||||||
bool bionicReadingOverride);
|
bool bionicReadingOverride);
|
||||||
|
|||||||
@@ -292,11 +292,10 @@ void MdReaderActivity::initializeReader() {
|
|||||||
|
|
||||||
renderer.getOrientedViewableTRBL(&cachedOrientedMarginTop, &cachedOrientedMarginRight, &cachedOrientedMarginBottom,
|
renderer.getOrientedViewableTRBL(&cachedOrientedMarginTop, &cachedOrientedMarginRight, &cachedOrientedMarginBottom,
|
||||||
&cachedOrientedMarginLeft);
|
&cachedOrientedMarginLeft);
|
||||||
cachedOrientedMarginTop += cachedScreenMargin;
|
cachedOrientedMarginTop += std::max(static_cast<int>(cachedScreenMargin), UITheme::getStatusBarTopHeight());
|
||||||
cachedOrientedMarginLeft += cachedScreenMargin;
|
cachedOrientedMarginLeft += cachedScreenMargin;
|
||||||
cachedOrientedMarginRight += cachedScreenMargin;
|
cachedOrientedMarginRight += cachedScreenMargin;
|
||||||
cachedOrientedMarginBottom +=
|
cachedOrientedMarginBottom += std::max(static_cast<int>(cachedScreenMargin), UITheme::getStatusBarBottomHeight());
|
||||||
std::max(cachedScreenMargin, static_cast<uint8_t>(UITheme::getInstance().getStatusBarHeight()));
|
|
||||||
|
|
||||||
viewportWidth = renderer.getScreenWidth() - cachedOrientedMarginLeft - cachedOrientedMarginRight;
|
viewportWidth = renderer.getScreenWidth() - cachedOrientedMarginLeft - cachedOrientedMarginRight;
|
||||||
const int viewportHeight = renderer.getScreenHeight() - cachedOrientedMarginTop - cachedOrientedMarginBottom;
|
const int viewportHeight = renderer.getScreenHeight() - cachedOrientedMarginTop - cachedOrientedMarginBottom;
|
||||||
|
|||||||
@@ -7,6 +7,8 @@
|
|||||||
#include <Serialization.h>
|
#include <Serialization.h>
|
||||||
#include <Utf8.h>
|
#include <Utf8.h>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
#include "CrossPointSettings.h"
|
#include "CrossPointSettings.h"
|
||||||
#include "CrossPointState.h"
|
#include "CrossPointState.h"
|
||||||
#include "GlobalBookmarkIndex.h"
|
#include "GlobalBookmarkIndex.h"
|
||||||
@@ -207,11 +209,10 @@ void TxtReaderActivity::initializeReader() {
|
|||||||
// Calculate viewport dimensions
|
// Calculate viewport dimensions
|
||||||
renderer.getOrientedViewableTRBL(&cachedOrientedMarginTop, &cachedOrientedMarginRight, &cachedOrientedMarginBottom,
|
renderer.getOrientedViewableTRBL(&cachedOrientedMarginTop, &cachedOrientedMarginRight, &cachedOrientedMarginBottom,
|
||||||
&cachedOrientedMarginLeft);
|
&cachedOrientedMarginLeft);
|
||||||
cachedOrientedMarginTop += cachedScreenMargin;
|
cachedOrientedMarginTop += std::max(static_cast<int>(cachedScreenMargin), UITheme::getStatusBarTopHeight());
|
||||||
cachedOrientedMarginLeft += cachedScreenMargin;
|
cachedOrientedMarginLeft += cachedScreenMargin;
|
||||||
cachedOrientedMarginRight += cachedScreenMargin;
|
cachedOrientedMarginRight += cachedScreenMargin;
|
||||||
cachedOrientedMarginBottom +=
|
cachedOrientedMarginBottom += std::max(static_cast<int>(cachedScreenMargin), UITheme::getStatusBarBottomHeight());
|
||||||
std::max(cachedScreenMargin, static_cast<uint8_t>(UITheme::getInstance().getStatusBarHeight()));
|
|
||||||
|
|
||||||
viewportWidth = renderer.getScreenWidth() - cachedOrientedMarginLeft - cachedOrientedMarginRight;
|
viewportWidth = renderer.getScreenWidth() - cachedOrientedMarginLeft - cachedOrientedMarginRight;
|
||||||
const int viewportHeight = renderer.getScreenHeight() - cachedOrientedMarginTop - cachedOrientedMarginBottom;
|
const int viewportHeight = renderer.getScreenHeight() - cachedOrientedMarginTop - cachedOrientedMarginBottom;
|
||||||
@@ -407,7 +408,7 @@ void TxtReaderActivity::renderStatusBar() const {
|
|||||||
title = txt->getTitle();
|
title = txt->getTitle();
|
||||||
}
|
}
|
||||||
const bool isStarred = bookmarkStore.has(0, static_cast<uint16_t>(currentPage));
|
const bool isStarred = bookmarkStore.has(0, static_cast<uint16_t>(currentPage));
|
||||||
GUI.drawStatusBar(renderer, progress, currentPage + 1, totalPages, title, 0, 0, isStarred);
|
GUI.drawStatusBar(renderer, progress, currentPage + 1, totalPages, title, 0, isStarred);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TxtReaderActivity::saveProgress() const {
|
void TxtReaderActivity::saveProgress() const {
|
||||||
@@ -644,10 +645,10 @@ bool TxtReaderActivity::drawCurrentPageToBuffer(const std::string& filePath, Gfx
|
|||||||
|
|
||||||
int marginTop, marginRight, marginBottom, marginLeft;
|
int marginTop, marginRight, marginBottom, marginLeft;
|
||||||
renderer.getOrientedViewableTRBL(&marginTop, &marginRight, &marginBottom, &marginLeft);
|
renderer.getOrientedViewableTRBL(&marginTop, &marginRight, &marginBottom, &marginLeft);
|
||||||
marginTop += screenMargin;
|
marginTop += std::max(static_cast<int>(screenMargin), UITheme::getStatusBarTopHeight());
|
||||||
marginLeft += screenMargin;
|
marginLeft += screenMargin;
|
||||||
marginRight += screenMargin;
|
marginRight += screenMargin;
|
||||||
marginBottom += std::max(screenMargin, static_cast<uint8_t>(UITheme::getInstance().getStatusBarHeight()));
|
marginBottom += std::max(static_cast<int>(screenMargin), UITheme::getStatusBarBottomHeight());
|
||||||
|
|
||||||
const int vw = renderer.getScreenWidth() - marginLeft - marginRight;
|
const int vw = renderer.getScreenWidth() - marginLeft - marginRight;
|
||||||
const int vh = renderer.getScreenHeight() - marginTop - marginBottom;
|
const int vh = renderer.getScreenHeight() - marginTop - marginBottom;
|
||||||
|
|||||||
@@ -3,7 +3,10 @@
|
|||||||
#include <GfxRenderer.h>
|
#include <GfxRenderer.h>
|
||||||
#include <I18n.h>
|
#include <I18n.h>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <cstdio>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "CrossPointSettings.h"
|
#include "CrossPointSettings.h"
|
||||||
#include "MappedInputManager.h"
|
#include "MappedInputManager.h"
|
||||||
@@ -11,14 +14,19 @@
|
|||||||
#include "fontIds.h"
|
#include "fontIds.h"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
constexpr int MENU_ITEMS = 7;
|
// Base menu items (without clock). Clock is appended conditionally at index 5.
|
||||||
const StrId menuNames[MENU_ITEMS] = {StrId::STR_CHAPTER_PAGE_COUNT,
|
constexpr int MENU_ITEMS_NO_CLOCK = 9;
|
||||||
StrId::STR_BOOK_PROGRESS_PERCENTAGE,
|
constexpr int MENU_ITEMS_WITH_CLOCK = 10;
|
||||||
StrId::STR_PROGRESS_BAR,
|
const StrId menuNames[MENU_ITEMS_WITH_CLOCK] = {StrId::STR_STATUS_ITEMS_POSITION,
|
||||||
StrId::STR_PROGRESS_BAR_THICKNESS,
|
StrId::STR_CHAPTER_PAGE_COUNT,
|
||||||
StrId::STR_TITLE,
|
StrId::STR_BOOK_PROGRESS_PERCENTAGE,
|
||||||
StrId::STR_BATTERY,
|
StrId::STR_TITLE,
|
||||||
StrId::STR_CLOCK};
|
StrId::STR_BATTERY,
|
||||||
|
StrId::STR_CLOCK,
|
||||||
|
StrId::STR_UPPER_PROGRESS_BAR,
|
||||||
|
StrId::STR_UPPER_PROGRESS_BAR_THICKNESS,
|
||||||
|
StrId::STR_LOWER_PROGRESS_BAR,
|
||||||
|
StrId::STR_LOWER_PROGRESS_BAR_THICKNESS};
|
||||||
constexpr int PROGRESS_BAR_ITEMS = 3;
|
constexpr int PROGRESS_BAR_ITEMS = 3;
|
||||||
const StrId progressBarNames[PROGRESS_BAR_ITEMS] = {StrId::STR_BOOK, StrId::STR_CHAPTER, StrId::STR_HIDE};
|
const StrId progressBarNames[PROGRESS_BAR_ITEMS] = {StrId::STR_BOOK, StrId::STR_CHAPTER, StrId::STR_HIDE};
|
||||||
|
|
||||||
@@ -29,26 +37,130 @@ const StrId progressBarThicknessNames[PROGRESS_BAR_THICKNESS_ITEMS] = {
|
|||||||
constexpr int TITLE_ITEMS = 3;
|
constexpr int TITLE_ITEMS = 3;
|
||||||
const StrId titleNames[TITLE_ITEMS] = {StrId::STR_BOOK, StrId::STR_CHAPTER, StrId::STR_HIDE};
|
const StrId titleNames[TITLE_ITEMS] = {StrId::STR_BOOK, StrId::STR_CHAPTER, StrId::STR_HIDE};
|
||||||
|
|
||||||
const int widthMargin = 10;
|
constexpr int STATUS_ITEMS_POSITION_ITEMS = 2;
|
||||||
const int verticalPreviewPadding = 50;
|
const StrId statusItemsPositionNames[STATUS_ITEMS_POSITION_ITEMS] = {StrId::STR_TOP, StrId::STR_BOTTOM};
|
||||||
const int verticalPreviewTextPadding = 40;
|
|
||||||
|
constexpr int previewHorizontalInset = 10;
|
||||||
|
constexpr int previewHeight = 78;
|
||||||
|
constexpr int previewInnerMargin = 4;
|
||||||
|
|
||||||
|
void drawPreviewProgressBar(const GfxRenderer& renderer, const Rect& rect, const uint8_t progressBar,
|
||||||
|
const uint8_t thickness, const bool topEdge) {
|
||||||
|
if (progressBar == CrossPointSettings::STATUS_BAR_PROGRESS_BAR::HIDE_PROGRESS) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int percent = progressBar == CrossPointSettings::STATUS_BAR_PROGRESS_BAR::BOOK_PROGRESS ? 75 : 25;
|
||||||
|
const int barHeight = (thickness + 1) * 2;
|
||||||
|
const int y = topEdge ? rect.y + previewInnerMargin : rect.y + rect.height - previewInnerMargin - barHeight;
|
||||||
|
const int barWidth = (rect.width - previewInnerMargin * 2) * percent / 100;
|
||||||
|
renderer.fillRect(rect.x + previewInnerMargin, y, barWidth, barHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
void drawPreviewStatusItems(const GfxRenderer& renderer, const Rect& rect, const ThemeMetrics& metrics) {
|
||||||
|
const bool hasProgressText = SETTINGS.statusBarChapterPageCount || SETTINGS.statusBarBookProgressPercentage;
|
||||||
|
const bool hasTitle = SETTINGS.statusBarTitle != CrossPointSettings::STATUS_BAR_TITLE::HIDE_TITLE;
|
||||||
|
const bool hasStatusItems =
|
||||||
|
hasProgressText || hasTitle || SETTINGS.statusBarBattery || (SETTINGS.useClock && SETTINGS.statusBarClock);
|
||||||
|
if (!hasStatusItems) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const bool statusItemsAtTop =
|
||||||
|
SETTINGS.statusBarItemsPosition == CrossPointSettings::STATUS_BAR_ITEMS_POSITION::STATUS_BAR_ITEMS_TOP;
|
||||||
|
const int adjacentProgressHeight = statusItemsAtTop
|
||||||
|
? UITheme::getProgressBarHeight(SETTINGS.statusBarUpperProgressBar,
|
||||||
|
SETTINGS.statusBarUpperProgressBarThickness)
|
||||||
|
: UITheme::getProgressBarHeight(SETTINGS.statusBarLowerProgressBar,
|
||||||
|
SETTINGS.statusBarLowerProgressBarThickness);
|
||||||
|
const int statusItemsHeight = UITheme::getStatusBarItemsHeight();
|
||||||
|
const int textY = statusItemsAtTop
|
||||||
|
? rect.y + previewInnerMargin + adjacentProgressHeight + 4
|
||||||
|
: rect.y + rect.height - previewInnerMargin - adjacentProgressHeight - statusItemsHeight + 4;
|
||||||
|
|
||||||
|
const bool showBatteryPercentage =
|
||||||
|
SETTINGS.statusBarBattery &&
|
||||||
|
SETTINGS.hideBatteryPercentage == CrossPointSettings::HIDE_BATTERY_PERCENTAGE::HIDE_NEVER;
|
||||||
|
if (SETTINGS.statusBarBattery) {
|
||||||
|
GUI.drawBatteryLeft(renderer,
|
||||||
|
Rect{rect.x + previewInnerMargin + 2, textY, metrics.batteryWidth, metrics.batteryHeight},
|
||||||
|
showBatteryPercentage);
|
||||||
|
}
|
||||||
|
|
||||||
|
int progressTextWidth = 0;
|
||||||
|
if (hasProgressText) {
|
||||||
|
char progressStr[32] = "";
|
||||||
|
if (SETTINGS.statusBarChapterPageCount && SETTINGS.statusBarBookProgressPercentage) {
|
||||||
|
snprintf(progressStr, sizeof(progressStr), "%d/%d %d%%", 8, 32, 75);
|
||||||
|
} else if (SETTINGS.statusBarBookProgressPercentage) {
|
||||||
|
snprintf(progressStr, sizeof(progressStr), "%d%%", 75);
|
||||||
|
} else {
|
||||||
|
snprintf(progressStr, sizeof(progressStr), "%d/%d", 8, 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
progressTextWidth = renderer.getTextWidth(SMALL_FONT_ID, progressStr);
|
||||||
|
renderer.drawText(SMALL_FONT_ID, rect.x + rect.width - previewInnerMargin - 2 - progressTextWidth, textY,
|
||||||
|
progressStr);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hasTitle) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* title = SETTINGS.statusBarTitle == CrossPointSettings::STATUS_BAR_TITLE::BOOK_TITLE
|
||||||
|
? tr(STR_EXAMPLE_BOOK)
|
||||||
|
: tr(STR_EXAMPLE_CHAPTER);
|
||||||
|
int leftReserve = 6;
|
||||||
|
if (SETTINGS.statusBarBattery) {
|
||||||
|
leftReserve = metrics.batteryWidth + 28;
|
||||||
|
if (showBatteryPercentage) {
|
||||||
|
const int percentReserve = 2 + metrics.batteryWidth + BaseTheme::batteryPercentSpacing +
|
||||||
|
renderer.getTextWidth(SMALL_FONT_ID, "100%") + 8;
|
||||||
|
leftReserve = std::max(leftReserve, percentReserve);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const int rightReserve = progressTextWidth > 0 ? progressTextWidth + 18 : 6;
|
||||||
|
const int titleAreaWidth = rect.width - previewInnerMargin * 2 - leftReserve - rightReserve;
|
||||||
|
if (titleAreaWidth <= 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string previewTitle = renderer.truncatedText(SMALL_FONT_ID, title, titleAreaWidth);
|
||||||
|
const int titleWidth = renderer.getTextWidth(SMALL_FONT_ID, previewTitle.c_str());
|
||||||
|
renderer.drawText(SMALL_FONT_ID, rect.x + previewInnerMargin + leftReserve + (titleAreaWidth - titleWidth) / 2, textY,
|
||||||
|
previewTitle.c_str());
|
||||||
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
void StatusBarSettingsActivity::onEnter() {
|
void StatusBarSettingsActivity::onEnter() {
|
||||||
Activity::onEnter();
|
Activity::onEnter();
|
||||||
|
|
||||||
const int menuCount = SETTINGS.useClock ? MENU_ITEMS : MENU_ITEMS - 1;
|
const int menuCount = SETTINGS.useClock ? MENU_ITEMS_WITH_CLOCK : MENU_ITEMS_NO_CLOCK;
|
||||||
if (selectedIndex >= menuCount) {
|
if (selectedIndex >= menuCount) {
|
||||||
selectedIndex = 0;
|
selectedIndex = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clamp statusBarProgressBar and statusBarTitle in case of corrupt/migrated data
|
// Clamp status bar settings in case of corrupt/migrated data.
|
||||||
if (SETTINGS.statusBarProgressBar >= PROGRESS_BAR_ITEMS) {
|
if (SETTINGS.statusBarUpperProgressBar >= PROGRESS_BAR_ITEMS) {
|
||||||
SETTINGS.statusBarProgressBar = CrossPointSettings::STATUS_BAR_PROGRESS_BAR::HIDE_PROGRESS;
|
SETTINGS.statusBarUpperProgressBar = CrossPointSettings::STATUS_BAR_PROGRESS_BAR::HIDE_PROGRESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SETTINGS.statusBarTitle >= PROGRESS_BAR_THICKNESS_ITEMS) {
|
if (SETTINGS.statusBarLowerProgressBar >= PROGRESS_BAR_ITEMS) {
|
||||||
SETTINGS.statusBarTitle = CrossPointSettings::STATUS_BAR_PROGRESS_BAR_THICKNESS::PROGRESS_BAR_NORMAL;
|
SETTINGS.statusBarLowerProgressBar = CrossPointSettings::STATUS_BAR_PROGRESS_BAR::HIDE_PROGRESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SETTINGS.statusBarUpperProgressBarThickness >= PROGRESS_BAR_THICKNESS_ITEMS) {
|
||||||
|
SETTINGS.statusBarUpperProgressBarThickness =
|
||||||
|
CrossPointSettings::STATUS_BAR_PROGRESS_BAR_THICKNESS::PROGRESS_BAR_NORMAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SETTINGS.statusBarLowerProgressBarThickness >= PROGRESS_BAR_THICKNESS_ITEMS) {
|
||||||
|
SETTINGS.statusBarLowerProgressBarThickness =
|
||||||
|
CrossPointSettings::STATUS_BAR_PROGRESS_BAR_THICKNESS::PROGRESS_BAR_NORMAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SETTINGS.statusBarItemsPosition >= STATUS_ITEMS_POSITION_ITEMS) {
|
||||||
|
SETTINGS.statusBarItemsPosition = CrossPointSettings::STATUS_BAR_ITEMS_POSITION::STATUS_BAR_ITEMS_BOTTOM;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SETTINGS.statusBarTitle >= TITLE_ITEMS) {
|
if (SETTINGS.statusBarTitle >= TITLE_ITEMS) {
|
||||||
@@ -74,53 +186,67 @@ void StatusBarSettingsActivity::loop() {
|
|||||||
|
|
||||||
// Handle navigation
|
// Handle navigation
|
||||||
buttonNavigator.onNextRelease([this] {
|
buttonNavigator.onNextRelease([this] {
|
||||||
const int menuCount = SETTINGS.useClock ? MENU_ITEMS : MENU_ITEMS - 1;
|
const int menuCount = SETTINGS.useClock ? MENU_ITEMS_WITH_CLOCK : MENU_ITEMS_NO_CLOCK;
|
||||||
selectedIndex = ButtonNavigator::nextIndex(selectedIndex, menuCount);
|
selectedIndex = ButtonNavigator::nextIndex(selectedIndex, menuCount);
|
||||||
requestUpdate();
|
requestUpdate();
|
||||||
});
|
});
|
||||||
|
|
||||||
buttonNavigator.onPreviousRelease([this] {
|
buttonNavigator.onPreviousRelease([this] {
|
||||||
const int menuCount = SETTINGS.useClock ? MENU_ITEMS : MENU_ITEMS - 1;
|
const int menuCount = SETTINGS.useClock ? MENU_ITEMS_WITH_CLOCK : MENU_ITEMS_NO_CLOCK;
|
||||||
selectedIndex = ButtonNavigator::previousIndex(selectedIndex, menuCount);
|
selectedIndex = ButtonNavigator::previousIndex(selectedIndex, menuCount);
|
||||||
requestUpdate();
|
requestUpdate();
|
||||||
});
|
});
|
||||||
|
|
||||||
buttonNavigator.onNextContinuous([this] {
|
buttonNavigator.onNextContinuous([this] {
|
||||||
const int menuCount = SETTINGS.useClock ? MENU_ITEMS : MENU_ITEMS - 1;
|
const int menuCount = SETTINGS.useClock ? MENU_ITEMS_WITH_CLOCK : MENU_ITEMS_NO_CLOCK;
|
||||||
selectedIndex = ButtonNavigator::nextIndex(selectedIndex, menuCount);
|
selectedIndex = ButtonNavigator::nextIndex(selectedIndex, menuCount);
|
||||||
requestUpdate();
|
requestUpdate();
|
||||||
});
|
});
|
||||||
|
|
||||||
buttonNavigator.onPreviousContinuous([this] {
|
buttonNavigator.onPreviousContinuous([this] {
|
||||||
const int menuCount = SETTINGS.useClock ? MENU_ITEMS : MENU_ITEMS - 1;
|
const int menuCount = SETTINGS.useClock ? MENU_ITEMS_WITH_CLOCK : MENU_ITEMS_NO_CLOCK;
|
||||||
selectedIndex = ButtonNavigator::previousIndex(selectedIndex, menuCount);
|
selectedIndex = ButtonNavigator::previousIndex(selectedIndex, menuCount);
|
||||||
requestUpdate();
|
requestUpdate();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void StatusBarSettingsActivity::handleSelection() {
|
void StatusBarSettingsActivity::handleSelection() {
|
||||||
if (selectedIndex == 0) {
|
// When clock is hidden, indices 6+ shift down by 1 (clock slot at index 5 is absent).
|
||||||
|
// We remap the logical index to match the menuNames array which always includes clock at slot 5.
|
||||||
|
const int logicalIndex = (!SETTINGS.useClock && selectedIndex >= 5) ? selectedIndex + 1 : selectedIndex;
|
||||||
|
|
||||||
|
if (logicalIndex == 0) {
|
||||||
|
// Status Items Position
|
||||||
|
SETTINGS.statusBarItemsPosition = (SETTINGS.statusBarItemsPosition + 1) % STATUS_ITEMS_POSITION_ITEMS;
|
||||||
|
} else if (logicalIndex == 1) {
|
||||||
// Chapter Page Count
|
// Chapter Page Count
|
||||||
SETTINGS.statusBarChapterPageCount = (SETTINGS.statusBarChapterPageCount + 1) % 2;
|
SETTINGS.statusBarChapterPageCount = (SETTINGS.statusBarChapterPageCount + 1) % 2;
|
||||||
} else if (selectedIndex == 1) {
|
} else if (logicalIndex == 2) {
|
||||||
// Book Progress %
|
// Book Progress %
|
||||||
SETTINGS.statusBarBookProgressPercentage = (SETTINGS.statusBarBookProgressPercentage + 1) % 2;
|
SETTINGS.statusBarBookProgressPercentage = (SETTINGS.statusBarBookProgressPercentage + 1) % 2;
|
||||||
} else if (selectedIndex == 2) {
|
} else if (logicalIndex == 3) {
|
||||||
// Progress Bar
|
// Title
|
||||||
SETTINGS.statusBarProgressBar = (SETTINGS.statusBarProgressBar + 1) % PROGRESS_BAR_ITEMS;
|
|
||||||
} else if (selectedIndex == 3) {
|
|
||||||
// Progress Bar Thickness
|
|
||||||
SETTINGS.statusBarProgressBarThickness =
|
|
||||||
(SETTINGS.statusBarProgressBarThickness + 1) % PROGRESS_BAR_THICKNESS_ITEMS;
|
|
||||||
} else if (selectedIndex == 4) {
|
|
||||||
// Chapter Title
|
|
||||||
SETTINGS.statusBarTitle = (SETTINGS.statusBarTitle + 1) % TITLE_ITEMS;
|
SETTINGS.statusBarTitle = (SETTINGS.statusBarTitle + 1) % TITLE_ITEMS;
|
||||||
} else if (selectedIndex == 5) {
|
} else if (logicalIndex == 4) {
|
||||||
// Show Battery
|
// Battery
|
||||||
SETTINGS.statusBarBattery = (SETTINGS.statusBarBattery + 1) % 2;
|
SETTINGS.statusBarBattery = (SETTINGS.statusBarBattery + 1) % 2;
|
||||||
} else if (selectedIndex == 6 && SETTINGS.useClock) {
|
} else if (logicalIndex == 5 && SETTINGS.useClock) {
|
||||||
// Show Clock
|
// Clock
|
||||||
SETTINGS.statusBarClock = (SETTINGS.statusBarClock + 1) % 2;
|
SETTINGS.statusBarClock = (SETTINGS.statusBarClock + 1) % 2;
|
||||||
|
} else if (logicalIndex == 6) {
|
||||||
|
// Upper Progress Bar
|
||||||
|
SETTINGS.statusBarUpperProgressBar = (SETTINGS.statusBarUpperProgressBar + 1) % PROGRESS_BAR_ITEMS;
|
||||||
|
} else if (logicalIndex == 7) {
|
||||||
|
// Upper Progress Bar Thickness
|
||||||
|
SETTINGS.statusBarUpperProgressBarThickness =
|
||||||
|
(SETTINGS.statusBarUpperProgressBarThickness + 1) % PROGRESS_BAR_THICKNESS_ITEMS;
|
||||||
|
} else if (logicalIndex == 8) {
|
||||||
|
// Lower Progress Bar
|
||||||
|
SETTINGS.statusBarLowerProgressBar = (SETTINGS.statusBarLowerProgressBar + 1) % PROGRESS_BAR_ITEMS;
|
||||||
|
} else if (logicalIndex == 9) {
|
||||||
|
// Lower Progress Bar Thickness
|
||||||
|
SETTINGS.statusBarLowerProgressBarThickness =
|
||||||
|
(SETTINGS.statusBarLowerProgressBarThickness + 1) % PROGRESS_BAR_THICKNESS_ITEMS;
|
||||||
}
|
}
|
||||||
SETTINGS.saveToFile();
|
SETTINGS.saveToFile();
|
||||||
}
|
}
|
||||||
@@ -137,28 +263,44 @@ void StatusBarSettingsActivity::render(RenderLock&&) {
|
|||||||
tr(STR_CUSTOMISE_STATUS_BAR));
|
tr(STR_CUSTOMISE_STATUS_BAR));
|
||||||
|
|
||||||
const int contentTop = metrics.topPadding + metrics.headerHeight + metrics.verticalSpacing;
|
const int contentTop = metrics.topPadding + metrics.headerHeight + metrics.verticalSpacing;
|
||||||
const int contentHeight = pageHeight - contentTop - metrics.buttonHintsHeight - metrics.verticalSpacing * 2;
|
const int previewLabelHeight = renderer.getLineHeight(UI_10_FONT_ID);
|
||||||
const int menuCount = SETTINGS.useClock ? MENU_ITEMS : MENU_ITEMS - 1;
|
const int previewAreaHeight = previewLabelHeight + previewHeight + metrics.verticalSpacing * 2;
|
||||||
|
const int contentHeight =
|
||||||
|
pageHeight - contentTop - metrics.buttonHintsHeight - previewAreaHeight - metrics.verticalSpacing * 2;
|
||||||
|
const int menuCount = SETTINGS.useClock ? MENU_ITEMS_WITH_CLOCK : MENU_ITEMS_NO_CLOCK;
|
||||||
GUI.drawList(
|
GUI.drawList(
|
||||||
renderer, Rect{0, contentTop, pageWidth, contentHeight}, static_cast<int>(menuCount),
|
renderer, Rect{0, contentTop, pageWidth, contentHeight}, static_cast<int>(menuCount),
|
||||||
static_cast<int>(selectedIndex), [](int index) { return std::string(I18N.get(menuNames[index])); }, nullptr,
|
static_cast<int>(selectedIndex),
|
||||||
nullptr,
|
[](int index) {
|
||||||
|
const int logicalIndex = (!SETTINGS.useClock && index >= 5) ? index + 1 : index;
|
||||||
|
return std::string(I18N.get(menuNames[logicalIndex]));
|
||||||
|
},
|
||||||
|
nullptr, nullptr,
|
||||||
[this](int index) {
|
[this](int index) {
|
||||||
// Draw status for each setting
|
// When clock is hidden, indices 6+ shift down by 1 in the display list but we still
|
||||||
if (index == 0) {
|
// index into menuNames which has clock at slot 5. Remap for value display.
|
||||||
|
const int logicalIndex = (!SETTINGS.useClock && index >= 5) ? index + 1 : index;
|
||||||
|
|
||||||
|
if (logicalIndex == 0) {
|
||||||
|
return I18N.get(statusItemsPositionNames[SETTINGS.statusBarItemsPosition]);
|
||||||
|
} else if (logicalIndex == 1) {
|
||||||
return SETTINGS.statusBarChapterPageCount ? tr(STR_SHOW) : tr(STR_HIDE);
|
return SETTINGS.statusBarChapterPageCount ? tr(STR_SHOW) : tr(STR_HIDE);
|
||||||
} else if (index == 1) {
|
} else if (logicalIndex == 2) {
|
||||||
return SETTINGS.statusBarBookProgressPercentage ? tr(STR_SHOW) : tr(STR_HIDE);
|
return SETTINGS.statusBarBookProgressPercentage ? tr(STR_SHOW) : tr(STR_HIDE);
|
||||||
} else if (index == 2) {
|
} else if (logicalIndex == 3) {
|
||||||
return I18N.get(progressBarNames[SETTINGS.statusBarProgressBar]);
|
|
||||||
} else if (index == 3) {
|
|
||||||
return I18N.get(progressBarThicknessNames[SETTINGS.statusBarProgressBarThickness]);
|
|
||||||
} else if (index == 4) {
|
|
||||||
return I18N.get(titleNames[SETTINGS.statusBarTitle]);
|
return I18N.get(titleNames[SETTINGS.statusBarTitle]);
|
||||||
} else if (index == 5) {
|
} else if (logicalIndex == 4) {
|
||||||
return SETTINGS.statusBarBattery ? tr(STR_SHOW) : tr(STR_HIDE);
|
return SETTINGS.statusBarBattery ? tr(STR_SHOW) : tr(STR_HIDE);
|
||||||
} else if (index == 6) {
|
} else if (logicalIndex == 5) {
|
||||||
return SETTINGS.statusBarClock ? tr(STR_SHOW) : tr(STR_HIDE);
|
return SETTINGS.statusBarClock ? tr(STR_SHOW) : tr(STR_HIDE);
|
||||||
|
} else if (logicalIndex == 6) {
|
||||||
|
return I18N.get(progressBarNames[SETTINGS.statusBarUpperProgressBar]);
|
||||||
|
} else if (logicalIndex == 7) {
|
||||||
|
return I18N.get(progressBarThicknessNames[SETTINGS.statusBarUpperProgressBarThickness]);
|
||||||
|
} else if (logicalIndex == 8) {
|
||||||
|
return I18N.get(progressBarNames[SETTINGS.statusBarLowerProgressBar]);
|
||||||
|
} else if (logicalIndex == 9) {
|
||||||
|
return I18N.get(progressBarThicknessNames[SETTINGS.statusBarLowerProgressBarThickness]);
|
||||||
} else {
|
} else {
|
||||||
return tr(STR_HIDE);
|
return tr(STR_HIDE);
|
||||||
}
|
}
|
||||||
@@ -169,19 +311,16 @@ void StatusBarSettingsActivity::render(RenderLock&&) {
|
|||||||
const auto labels = mappedInput.mapLabels(tr(STR_BACK), tr(STR_TOGGLE), tr(STR_DIR_UP), tr(STR_DIR_DOWN));
|
const auto labels = mappedInput.mapLabels(tr(STR_BACK), tr(STR_TOGGLE), tr(STR_DIR_UP), tr(STR_DIR_DOWN));
|
||||||
GUI.drawButtonHints(renderer, labels.btn1, labels.btn2, labels.btn3, labels.btn4);
|
GUI.drawButtonHints(renderer, labels.btn1, labels.btn2, labels.btn3, labels.btn4);
|
||||||
|
|
||||||
std::string title;
|
const int previewLabelY = contentTop + contentHeight + metrics.verticalSpacing;
|
||||||
if (SETTINGS.statusBarTitle == CrossPointSettings::STATUS_BAR_TITLE::BOOK_TITLE) {
|
renderer.drawText(UI_10_FONT_ID, metrics.contentSidePadding, previewLabelY, tr(STR_PREVIEW));
|
||||||
title = tr(STR_EXAMPLE_BOOK);
|
const Rect previewRect{previewHorizontalInset, previewLabelY + previewLabelHeight + metrics.verticalSpacing / 2,
|
||||||
} else if (SETTINGS.statusBarTitle == CrossPointSettings::STATUS_BAR_TITLE::CHAPTER_TITLE) {
|
pageWidth - previewHorizontalInset * 2, previewHeight};
|
||||||
title = tr(STR_EXAMPLE_CHAPTER);
|
renderer.drawRect(previewRect.x, previewRect.y, previewRect.width, previewRect.height);
|
||||||
}
|
drawPreviewProgressBar(renderer, previewRect, SETTINGS.statusBarUpperProgressBar,
|
||||||
|
SETTINGS.statusBarUpperProgressBarThickness, true);
|
||||||
GUI.drawStatusBar(renderer, 75, 8, 32, title, verticalPreviewPadding);
|
drawPreviewProgressBar(renderer, previewRect, SETTINGS.statusBarLowerProgressBar,
|
||||||
|
SETTINGS.statusBarLowerProgressBarThickness, false);
|
||||||
renderer.drawText(UI_10_FONT_ID, metrics.contentSidePadding,
|
drawPreviewStatusItems(renderer, previewRect, metrics);
|
||||||
renderer.getScreenHeight() - UITheme::getInstance().getStatusBarHeight() - verticalPreviewPadding -
|
|
||||||
verticalPreviewTextPadding,
|
|
||||||
tr(STR_PREVIEW));
|
|
||||||
|
|
||||||
renderer.displayBuffer();
|
renderer.displayBuffer();
|
||||||
}
|
}
|
||||||
|
|||||||
+59
-14
@@ -6,6 +6,7 @@
|
|||||||
#include <I18n.h>
|
#include <I18n.h>
|
||||||
#include <Logging.h>
|
#include <Logging.h>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include "MappedInputManager.h"
|
#include "MappedInputManager.h"
|
||||||
@@ -16,6 +17,24 @@
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
constexpr int SKIP_PAGE_MS = 700;
|
constexpr int SKIP_PAGE_MS = 700;
|
||||||
|
constexpr int STATUS_BAR_ITEM_PADDING = 4;
|
||||||
|
constexpr int STATUS_BAR_DESCENDER_CLEARANCE = 4;
|
||||||
|
|
||||||
|
uint8_t normalizeProgressBar(const uint8_t progressBar) {
|
||||||
|
return progressBar < CrossPointSettings::STATUS_BAR_PROGRESS_BAR_COUNT ? progressBar
|
||||||
|
: CrossPointSettings::HIDE_PROGRESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t normalizeProgressBarThickness(const uint8_t thickness) {
|
||||||
|
return thickness < CrossPointSettings::STATUS_BAR_PROGRESS_BAR_THICKNESS_COUNT
|
||||||
|
? thickness
|
||||||
|
: CrossPointSettings::PROGRESS_BAR_NORMAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t normalizeStatusBarItemsPosition(const uint8_t position) {
|
||||||
|
return position < CrossPointSettings::STATUS_BAR_ITEMS_POSITION_COUNT ? position
|
||||||
|
: CrossPointSettings::STATUS_BAR_ITEMS_BOTTOM;
|
||||||
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
UITheme UITheme::instance;
|
UITheme UITheme::instance;
|
||||||
@@ -159,22 +178,48 @@ UIIcon UITheme::getFileIcon(const std::string& filename) {
|
|||||||
return File;
|
return File;
|
||||||
}
|
}
|
||||||
|
|
||||||
int UITheme::getStatusBarHeight() {
|
int UITheme::getProgressBarHeight(const uint8_t progressBar, const uint8_t thickness) {
|
||||||
const ThemeMetrics& metrics = UITheme::getInstance().getMetrics();
|
const ThemeMetrics& metrics = UITheme::getInstance().getMetrics();
|
||||||
|
const uint8_t normalizedProgressBar = normalizeProgressBar(progressBar);
|
||||||
// Add status bar margin
|
if (normalizedProgressBar == CrossPointSettings::STATUS_BAR_PROGRESS_BAR::HIDE_PROGRESS) {
|
||||||
const bool showStatusBar = SETTINGS.statusBarChapterPageCount || SETTINGS.statusBarBookProgressPercentage ||
|
return 0;
|
||||||
SETTINGS.statusBarTitle != CrossPointSettings::STATUS_BAR_TITLE::HIDE_TITLE ||
|
}
|
||||||
SETTINGS.statusBarBattery || (SETTINGS.useClock && SETTINGS.statusBarClock);
|
const uint8_t normalizedThickness = normalizeProgressBarThickness(thickness);
|
||||||
const bool showProgressBar =
|
return ((normalizedThickness + 1) * 2) + metrics.progressBarMarginTop;
|
||||||
SETTINGS.statusBarProgressBar != CrossPointSettings::STATUS_BAR_PROGRESS_BAR::HIDE_PROGRESS;
|
|
||||||
return (showStatusBar ? (metrics.statusBarVerticalMargin) : 0) +
|
|
||||||
(showProgressBar ? (((SETTINGS.statusBarProgressBarThickness + 1) * 2) + metrics.progressBarMarginTop) : 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int UITheme::getProgressBarHeight() {
|
int UITheme::getStatusBarItemsHeight() {
|
||||||
const ThemeMetrics& metrics = UITheme::getInstance().getMetrics();
|
const ThemeMetrics& metrics = UITheme::getInstance().getMetrics();
|
||||||
const bool showProgressBar =
|
return std::max(metrics.statusBarVerticalMargin + (STATUS_BAR_ITEM_PADDING * 2) + STATUS_BAR_DESCENDER_CLEARANCE,
|
||||||
SETTINGS.statusBarProgressBar != CrossPointSettings::STATUS_BAR_PROGRESS_BAR::HIDE_PROGRESS;
|
metrics.batteryHeight + (STATUS_BAR_ITEM_PADDING * 2) + STATUS_BAR_DESCENDER_CLEARANCE);
|
||||||
return (showProgressBar ? (((SETTINGS.statusBarProgressBarThickness + 1) * 2) + metrics.progressBarMarginTop) : 0);
|
}
|
||||||
|
|
||||||
|
int UITheme::getStatusBarTopHeight(const bool forceStatusItems) {
|
||||||
|
const bool showStatusItems = forceStatusItems || SETTINGS.statusBarChapterPageCount ||
|
||||||
|
SETTINGS.statusBarBookProgressPercentage ||
|
||||||
|
SETTINGS.statusBarTitle != CrossPointSettings::STATUS_BAR_TITLE::HIDE_TITLE ||
|
||||||
|
SETTINGS.statusBarBattery || (SETTINGS.useClock && SETTINGS.statusBarClock);
|
||||||
|
const uint8_t statusBarItemsPosition = normalizeStatusBarItemsPosition(SETTINGS.statusBarItemsPosition);
|
||||||
|
const bool statusItemsAtTop =
|
||||||
|
statusBarItemsPosition == CrossPointSettings::STATUS_BAR_ITEMS_POSITION::STATUS_BAR_ITEMS_TOP;
|
||||||
|
const int statusItemsHeight = showStatusItems && statusItemsAtTop ? getStatusBarItemsHeight() : 0;
|
||||||
|
return getProgressBarHeight(SETTINGS.statusBarUpperProgressBar, SETTINGS.statusBarUpperProgressBarThickness) +
|
||||||
|
statusItemsHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
int UITheme::getStatusBarBottomHeight(const bool forceStatusItems) {
|
||||||
|
const bool showStatusItems = forceStatusItems || SETTINGS.statusBarChapterPageCount ||
|
||||||
|
SETTINGS.statusBarBookProgressPercentage ||
|
||||||
|
SETTINGS.statusBarTitle != CrossPointSettings::STATUS_BAR_TITLE::HIDE_TITLE ||
|
||||||
|
SETTINGS.statusBarBattery || (SETTINGS.useClock && SETTINGS.statusBarClock);
|
||||||
|
const uint8_t statusBarItemsPosition = normalizeStatusBarItemsPosition(SETTINGS.statusBarItemsPosition);
|
||||||
|
const bool statusItemsAtBottom =
|
||||||
|
statusBarItemsPosition == CrossPointSettings::STATUS_BAR_ITEMS_POSITION::STATUS_BAR_ITEMS_BOTTOM;
|
||||||
|
const int statusItemsHeight = showStatusItems && statusItemsAtBottom ? getStatusBarItemsHeight() : 0;
|
||||||
|
return getProgressBarHeight(SETTINGS.statusBarLowerProgressBar, SETTINGS.statusBarLowerProgressBarThickness) +
|
||||||
|
statusItemsHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
int UITheme::getStatusBarHeight(const bool forceStatusItems) {
|
||||||
|
return getStatusBarTopHeight(forceStatusItems) + getStatusBarBottomHeight(forceStatusItems);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,8 +61,11 @@ class UITheme {
|
|||||||
static Rect getContentRect(const GfxRenderer& renderer, bool hasBottomHints, bool hasSideHints);
|
static Rect getContentRect(const GfxRenderer& renderer, bool hasBottomHints, bool hasSideHints);
|
||||||
static std::string getCoverThumbPath(std::string coverBmpPath, int coverHeight);
|
static std::string getCoverThumbPath(std::string coverBmpPath, int coverHeight);
|
||||||
static UIIcon getFileIcon(const std::string& filename);
|
static UIIcon getFileIcon(const std::string& filename);
|
||||||
static int getStatusBarHeight();
|
static int getStatusBarTopHeight(bool forceStatusItems = false);
|
||||||
static int getProgressBarHeight();
|
static int getStatusBarBottomHeight(bool forceStatusItems = false);
|
||||||
|
static int getStatusBarHeight(bool forceStatusItems = false);
|
||||||
|
static int getStatusBarItemsHeight();
|
||||||
|
static int getProgressBarHeight(uint8_t progressBar, uint8_t thickness);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const ThemeMetrics* currentMetrics;
|
const ThemeMetrics* currentMetrics;
|
||||||
|
|||||||
@@ -52,6 +52,21 @@ void drawBatteryIcon(const GfxRenderer& renderer, int x, int y, int battWidth, i
|
|||||||
BaseTheme::drawBatteryLightningBolt(renderer, x + 4, y + 2);
|
BaseTheme::drawBatteryLightningBolt(renderer, x + 4, y + 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int progressBarPixelHeight(const uint8_t progressBar, const uint8_t thickness, const ThemeMetrics& metrics) {
|
||||||
|
const int reservedHeight = UITheme::getProgressBarHeight(progressBar, thickness);
|
||||||
|
return std::max(0, reservedHeight - metrics.progressBarMarginTop);
|
||||||
|
}
|
||||||
|
|
||||||
|
int statusBarProgressPercent(const uint8_t progressBar, const float bookProgress, const int currentPage,
|
||||||
|
const int pageCount) {
|
||||||
|
if (progressBar == CrossPointSettings::STATUS_BAR_PROGRESS_BAR::BOOK_PROGRESS) {
|
||||||
|
return std::clamp(static_cast<int>(bookProgress), 0, 100);
|
||||||
|
}
|
||||||
|
const int chapterProgress =
|
||||||
|
(pageCount > 0) ? static_cast<int>((static_cast<float>(currentPage) / pageCount) * 100) : 0;
|
||||||
|
return std::clamp(chapterProgress, 0, 100);
|
||||||
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
void BaseTheme::drawBatteryOutline(const GfxRenderer& renderer, int x, int y, int battWidth, int rectHeight) {
|
void BaseTheme::drawBatteryOutline(const GfxRenderer& renderer, int x, int y, int battWidth, int rectHeight) {
|
||||||
@@ -748,19 +763,56 @@ void BaseTheme::fillPopupProgress(const GfxRenderer& renderer, const Rect& layou
|
|||||||
}
|
}
|
||||||
|
|
||||||
void BaseTheme::drawStatusBar(GfxRenderer& renderer, const float bookProgress, const int currentPage,
|
void BaseTheme::drawStatusBar(GfxRenderer& renderer, const float bookProgress, const int currentPage,
|
||||||
const int pageCount, std::string title, const int paddingBottom, const int textYOffset,
|
const int pageCount, std::string title, const int paddingBottom,
|
||||||
const bool isStarred) const {
|
const bool isStarred) const {
|
||||||
auto metrics = UITheme::getInstance().getMetrics();
|
auto metrics = UITheme::getInstance().getMetrics();
|
||||||
int orientedMarginTop, orientedMarginRight, orientedMarginBottom, orientedMarginLeft;
|
int orientedMarginTop, orientedMarginRight, orientedMarginBottom, orientedMarginLeft;
|
||||||
renderer.getOrientedViewableTRBL(&orientedMarginTop, &orientedMarginRight, &orientedMarginBottom,
|
renderer.getOrientedViewableTRBL(&orientedMarginTop, &orientedMarginRight, &orientedMarginBottom,
|
||||||
&orientedMarginLeft);
|
&orientedMarginLeft);
|
||||||
|
|
||||||
// Draw Progress Text
|
|
||||||
const auto screenHeight = renderer.getScreenHeight();
|
const auto screenHeight = renderer.getScreenHeight();
|
||||||
auto textY = screenHeight - UITheme::getInstance().getStatusBarHeight() - orientedMarginBottom - paddingBottom - 4;
|
const auto screenWidth = renderer.getScreenWidth();
|
||||||
|
const int progressBarMaxWidth = screenWidth - orientedMarginLeft - orientedMarginRight;
|
||||||
|
|
||||||
|
auto drawEdgeProgressBar = [&](const uint8_t progressBar, const uint8_t thickness, const bool topEdge) {
|
||||||
|
const int barHeight = progressBarPixelHeight(progressBar, thickness, metrics);
|
||||||
|
if (barHeight <= 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const int progress = statusBarProgressPercent(progressBar, bookProgress, currentPage, pageCount);
|
||||||
|
const int barWidth = progressBarMaxWidth * progress / 100;
|
||||||
|
const int y =
|
||||||
|
topEdge ? orientedMarginTop + paddingBottom : screenHeight - orientedMarginBottom - paddingBottom - barHeight;
|
||||||
|
renderer.fillRect(orientedMarginLeft, y, barWidth, barHeight, true);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Draw progress bars first; status items are then placed inside the reserved band for their selected edge.
|
||||||
|
drawEdgeProgressBar(SETTINGS.statusBarUpperProgressBar, SETTINGS.statusBarUpperProgressBarThickness, true);
|
||||||
|
drawEdgeProgressBar(SETTINGS.statusBarLowerProgressBar, SETTINGS.statusBarLowerProgressBarThickness, false);
|
||||||
|
|
||||||
|
const bool hasProgressText = SETTINGS.statusBarBookProgressPercentage || SETTINGS.statusBarChapterPageCount;
|
||||||
|
const bool hasStatusItems = hasProgressText || SETTINGS.statusBarBattery || !title.empty() ||
|
||||||
|
SETTINGS.statusBarTitle != CrossPointSettings::STATUS_BAR_TITLE::HIDE_TITLE ||
|
||||||
|
(SETTINGS.useClock && SETTINGS.statusBarClock);
|
||||||
|
if (!hasStatusItems) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const bool statusItemsAtTop =
|
||||||
|
SETTINGS.statusBarItemsPosition == CrossPointSettings::STATUS_BAR_ITEMS_POSITION::STATUS_BAR_ITEMS_TOP;
|
||||||
|
const int adjacentProgressHeight = statusItemsAtTop
|
||||||
|
? UITheme::getProgressBarHeight(SETTINGS.statusBarUpperProgressBar,
|
||||||
|
SETTINGS.statusBarUpperProgressBarThickness)
|
||||||
|
: UITheme::getProgressBarHeight(SETTINGS.statusBarLowerProgressBar,
|
||||||
|
SETTINGS.statusBarLowerProgressBarThickness);
|
||||||
|
const int statusItemsHeight = UITheme::getStatusBarItemsHeight();
|
||||||
|
|
||||||
|
const int textY = statusItemsAtTop ? orientedMarginTop + paddingBottom + adjacentProgressHeight + 4
|
||||||
|
: screenHeight - orientedMarginBottom - paddingBottom - adjacentProgressHeight -
|
||||||
|
statusItemsHeight + 4;
|
||||||
int progressTextWidth = 0;
|
int progressTextWidth = 0;
|
||||||
|
|
||||||
if (SETTINGS.statusBarBookProgressPercentage || SETTINGS.statusBarChapterPageCount) {
|
if (hasProgressText) {
|
||||||
// Right aligned text for progress counter
|
// Right aligned text for progress counter
|
||||||
char progressStr[32];
|
char progressStr[32];
|
||||||
|
|
||||||
@@ -773,27 +825,9 @@ void BaseTheme::drawStatusBar(GfxRenderer& renderer, const float bookProgress, c
|
|||||||
}
|
}
|
||||||
|
|
||||||
progressTextWidth = renderer.getTextWidth(SMALL_FONT_ID, progressStr);
|
progressTextWidth = renderer.getTextWidth(SMALL_FONT_ID, progressStr);
|
||||||
renderer.drawText(
|
renderer.drawText(SMALL_FONT_ID,
|
||||||
SMALL_FONT_ID,
|
screenWidth - metrics.statusBarHorizontalMargin - orientedMarginRight - progressTextWidth, textY,
|
||||||
renderer.getScreenWidth() - metrics.statusBarHorizontalMargin - orientedMarginRight - progressTextWidth, textY,
|
progressStr);
|
||||||
progressStr);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw Progress Bar
|
|
||||||
if (SETTINGS.statusBarProgressBar != CrossPointSettings::STATUS_BAR_PROGRESS_BAR::HIDE_PROGRESS) {
|
|
||||||
const int progressBarMaxWidth = renderer.getScreenWidth() - orientedMarginLeft - orientedMarginRight;
|
|
||||||
const int progressBarY = renderer.getScreenHeight() - orientedMarginBottom -
|
|
||||||
((SETTINGS.statusBarProgressBarThickness + 1) * 2) - paddingBottom;
|
|
||||||
size_t progress;
|
|
||||||
if (SETTINGS.statusBarProgressBar == CrossPointSettings::STATUS_BAR_PROGRESS_BAR::BOOK_PROGRESS) {
|
|
||||||
progress = static_cast<size_t>(bookProgress);
|
|
||||||
} else {
|
|
||||||
// Chapter progress
|
|
||||||
progress = (pageCount > 0) ? (static_cast<float>(currentPage) / pageCount) * 100 : 0;
|
|
||||||
}
|
|
||||||
const int barWidth = progressBarMaxWidth * progress / 100;
|
|
||||||
renderer.fillRect(orientedMarginLeft, progressBarY, barWidth, ((SETTINGS.statusBarProgressBarThickness + 1) * 2),
|
|
||||||
true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw Battery
|
// Draw Battery
|
||||||
@@ -819,11 +853,8 @@ void BaseTheme::drawStatusBar(GfxRenderer& renderer, const float bookProgress, c
|
|||||||
|
|
||||||
// Draw Title
|
// Draw Title
|
||||||
if (!title.empty()) {
|
if (!title.empty()) {
|
||||||
textY -= textYOffset;
|
|
||||||
// Centered chapter title text
|
|
||||||
// Page width minus existing content with 30px padding on each side
|
|
||||||
const int rendererableScreenWidth =
|
const int rendererableScreenWidth =
|
||||||
renderer.getScreenWidth() - (metrics.statusBarHorizontalMargin * 2) - orientedMarginLeft - orientedMarginRight;
|
screenWidth - (metrics.statusBarHorizontalMargin * 2) - orientedMarginLeft - orientedMarginRight;
|
||||||
|
|
||||||
const int batterySize = SETTINGS.statusBarBattery ? (showBatteryPercentage ? 50 : 20) : 0;
|
const int batterySize = SETTINGS.statusBarBattery ? (showBatteryPercentage ? 50 : 20) : 0;
|
||||||
const int starReserve = isStarred ? (renderer.getTextWidth(SMALL_FONT_ID, "*") + 6) : 0;
|
const int starReserve = isStarred ? (renderer.getTextWidth(SMALL_FONT_ID, "*") + 6) : 0;
|
||||||
@@ -836,8 +867,7 @@ void BaseTheme::drawStatusBar(GfxRenderer& renderer, const float bookProgress, c
|
|||||||
int titleMarginLeftAdjusted = std::max(titleMarginLeft, titleMarginRight);
|
int titleMarginLeftAdjusted = std::max(titleMarginLeft, titleMarginRight);
|
||||||
int availableTitleSpace = rendererableScreenWidth - 2 * titleMarginLeftAdjusted;
|
int availableTitleSpace = rendererableScreenWidth - 2 * titleMarginLeftAdjusted;
|
||||||
|
|
||||||
int titleWidth;
|
int titleWidth = renderer.getTextWidth(SMALL_FONT_ID, title.c_str());
|
||||||
titleWidth = renderer.getTextWidth(SMALL_FONT_ID, title.c_str());
|
|
||||||
if (titleWidth > availableTitleSpace) {
|
if (titleWidth > availableTitleSpace) {
|
||||||
// Not enough space to center on the screen, center it within the remaining space instead
|
// Not enough space to center on the screen, center it within the remaining space instead
|
||||||
availableTitleSpace = rendererableScreenWidth - titleMarginLeft - titleMarginRight;
|
availableTitleSpace = rendererableScreenWidth - titleMarginLeft - titleMarginRight;
|
||||||
@@ -860,14 +890,12 @@ void BaseTheme::drawStatusBar(GfxRenderer& renderer, const float bookProgress, c
|
|||||||
int starX;
|
int starX;
|
||||||
if (progressTextWidth > 0) {
|
if (progressTextWidth > 0) {
|
||||||
// Place star just left of the progress text with a small gap
|
// Place star just left of the progress text with a small gap
|
||||||
starX = renderer.getScreenWidth() - metrics.statusBarHorizontalMargin - orientedMarginRight - progressTextWidth -
|
starX = screenWidth - metrics.statusBarHorizontalMargin - orientedMarginRight - progressTextWidth - starWidth - 6;
|
||||||
starWidth - 6;
|
|
||||||
} else {
|
} else {
|
||||||
// No progress text, place star at right edge
|
// No progress text, place star at right edge
|
||||||
starX = renderer.getScreenWidth() - metrics.statusBarHorizontalMargin - orientedMarginRight - starWidth;
|
starX = screenWidth - metrics.statusBarHorizontalMargin - orientedMarginRight - starWidth;
|
||||||
}
|
}
|
||||||
const int starY = title.empty() ? textY : (textY + textYOffset);
|
renderer.drawText(SMALL_FONT_ID, starX, textY, "*");
|
||||||
renderer.drawText(SMALL_FONT_ID, starX, starY, "*");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -151,7 +151,7 @@ class BaseTheme {
|
|||||||
virtual void fillPopupProgress(const GfxRenderer& renderer, const Rect& layout, const int progress) const;
|
virtual void fillPopupProgress(const GfxRenderer& renderer, const Rect& layout, const int progress) const;
|
||||||
virtual void drawStatusBar(GfxRenderer& renderer, const float bookProgress, const int currentPage,
|
virtual void drawStatusBar(GfxRenderer& renderer, const float bookProgress, const int currentPage,
|
||||||
const int pageCount, std::string title, const int paddingBottom = 0,
|
const int pageCount, std::string title, const int paddingBottom = 0,
|
||||||
const int textYOffset = 0, const bool isStarred = false) const;
|
const bool isStarred = false) const;
|
||||||
virtual void drawHelpText(const GfxRenderer& renderer, Rect rect, const char* label) const;
|
virtual void drawHelpText(const GfxRenderer& renderer, Rect rect, const char* label) const;
|
||||||
virtual void drawTextField(const GfxRenderer& renderer, Rect rect, const int textWidth, bool cursorMode = false,
|
virtual void drawTextField(const GfxRenderer& renderer, Rect rect, const int textWidth, bool cursorMode = false,
|
||||||
int contentStartX = 0, int contentWidth = 0) const;
|
int contentStartX = 0, int contentWidth = 0) const;
|
||||||
|
|||||||
Reference in New Issue
Block a user