Add UI support for darkness levels
This commit is contained in:
@@ -138,6 +138,15 @@ class CrossPointSettings {
|
||||
|
||||
// Image rendering in EPUB reader
|
||||
enum IMAGE_RENDERING { IMAGES_DISPLAY = 0, IMAGES_PLACEHOLDER = 1, IMAGES_SUPPRESS = 2, IMAGE_RENDERING_COUNT };
|
||||
|
||||
// Text darkness for AA glyph rendering (forwarded to GfxRenderer::setTextDarkness)
|
||||
enum TEXT_DARKNESS {
|
||||
DARKNESS_NORMAL = 0, // true 4-level AA
|
||||
DARKNESS_DARK = 1, // historical default — bolder dark-gray AA
|
||||
DARKNESS_EXTRA_DARK = 2, // both AA shades pushed to darkest gray state
|
||||
DARKNESS_MAXIMUM = 3, // skip grayscale passes — AA pixels stay solid black from BW pass
|
||||
TEXT_DARKNESS_COUNT
|
||||
};
|
||||
#ifdef ENABLE_IMAGE_DITHERING_EXTENSION
|
||||
enum IMAGE_DITHERING {
|
||||
IMAGE_DITHER_BAYER = 0,
|
||||
@@ -191,6 +200,9 @@ class CrossPointSettings {
|
||||
// Text rendering settings
|
||||
uint8_t extraParagraphSpacing = 1;
|
||||
uint8_t textAntiAliasing = 1;
|
||||
// Text darkness (0 = normal, 1 = dark, 2 = extra dark). Default 1 preserves
|
||||
// historical AA rendering (both grayscale shades drawn in the MSB pass).
|
||||
uint8_t textDarkness = DARKNESS_DARK;
|
||||
// Short power button click behaviour
|
||||
uint8_t shortPwrBtn = IGNORE;
|
||||
// EPUB reading orientation settings
|
||||
|
||||
@@ -68,6 +68,9 @@ inline const std::vector<SettingInfo>& getSettingsList() {
|
||||
StrId::STR_CAT_READER),
|
||||
SettingInfo::Toggle(StrId::STR_TEXT_AA, &CrossPointSettings::textAntiAliasing, "textAntiAliasing",
|
||||
StrId::STR_CAT_READER),
|
||||
SettingInfo::Enum(StrId::STR_TEXT_DARKNESS, &CrossPointSettings::textDarkness,
|
||||
{StrId::STR_NORMAL, StrId::STR_DARK, StrId::STR_EXTRA_DARK, StrId::STR_MAX_DARK},
|
||||
"textDarkness", StrId::STR_CAT_READER),
|
||||
SettingInfo::Enum(StrId::STR_IMAGES, &CrossPointSettings::imageRendering,
|
||||
{StrId::STR_IMAGES_DISPLAY, StrId::STR_IMAGES_PLACEHOLDER, StrId::STR_IMAGES_SUPPRESS},
|
||||
"imageRendering", StrId::STR_CAT_READER),
|
||||
|
||||
@@ -24,6 +24,7 @@ struct MenuResult {
|
||||
uint8_t pageTurnOption = 0;
|
||||
int8_t embeddedStyleOverride = -1;
|
||||
int8_t imageRenderingOverride = -1;
|
||||
uint8_t textDarkness = 1;
|
||||
};
|
||||
|
||||
struct ChapterResult {
|
||||
|
||||
@@ -173,20 +173,21 @@ void EpubReaderActivity::loop() {
|
||||
bookProgress = epub->calculateProgress(currentSpineIndex, chapterProgress) * 100.0f;
|
||||
}
|
||||
const int bookProgressPercent = clampPercent(static_cast<int>(bookProgress + 0.5f));
|
||||
startActivityForResult(
|
||||
std::make_unique<EpubReaderMenuActivity>(
|
||||
renderer, mappedInput, epub->getTitle(), currentPage, totalPages, bookProgressPercent, SETTINGS.orientation,
|
||||
!currentPageFootnotes.empty(), bookEmbeddedStyleOverride, bookImageRenderingOverride),
|
||||
[this](const ActivityResult& result) {
|
||||
// Always apply orientation change even if the menu was cancelled
|
||||
const auto& menu = std::get<MenuResult>(result.data);
|
||||
applyOrientation(menu.orientation);
|
||||
toggleAutoPageTurn(menu.pageTurnOption);
|
||||
applyBookReaderOverrides(menu.embeddedStyleOverride, menu.imageRenderingOverride);
|
||||
if (!result.isCancelled) {
|
||||
onReaderMenuConfirm(static_cast<EpubReaderMenuActivity::MenuAction>(menu.action));
|
||||
}
|
||||
});
|
||||
startActivityForResult(std::make_unique<EpubReaderMenuActivity>(
|
||||
renderer, mappedInput, epub->getTitle(), currentPage, totalPages, bookProgressPercent,
|
||||
SETTINGS.orientation, !currentPageFootnotes.empty(), bookEmbeddedStyleOverride,
|
||||
bookImageRenderingOverride, SETTINGS.textDarkness),
|
||||
[this](const ActivityResult& result) {
|
||||
// Always apply orientation/darkness change even if the menu was cancelled
|
||||
const auto& menu = std::get<MenuResult>(result.data);
|
||||
applyOrientation(menu.orientation);
|
||||
applyTextDarkness(menu.textDarkness);
|
||||
toggleAutoPageTurn(menu.pageTurnOption);
|
||||
applyBookReaderOverrides(menu.embeddedStyleOverride, menu.imageRenderingOverride);
|
||||
if (!result.isCancelled) {
|
||||
onReaderMenuConfirm(static_cast<EpubReaderMenuActivity::MenuAction>(menu.action));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Long press BACK (1s+) goes to home screen
|
||||
@@ -587,6 +588,17 @@ void EpubReaderActivity::applyOrientation(const uint8_t orientation) {
|
||||
}
|
||||
}
|
||||
|
||||
void EpubReaderActivity::applyTextDarkness(const uint8_t textDarkness) {
|
||||
if (SETTINGS.textDarkness == textDarkness) {
|
||||
return;
|
||||
}
|
||||
SETTINGS.textDarkness = textDarkness;
|
||||
SETTINGS.saveToFile();
|
||||
renderer.setTextDarkness(textDarkness);
|
||||
// Force a re-render so the new darkness is visible immediately.
|
||||
requestUpdate();
|
||||
}
|
||||
|
||||
void EpubReaderActivity::toggleAutoPageTurn(const uint8_t selectedPageTurnOption) {
|
||||
if (selectedPageTurnOption == 0 || selectedPageTurnOption >= PAGE_TURN_LABELS.size()) {
|
||||
automaticPageTurnActive = false;
|
||||
|
||||
@@ -74,6 +74,7 @@ class EpubReaderActivity final : public Activity {
|
||||
void launchKOReaderSync(SyncLaunchMode mode = SyncLaunchMode::COMPARE);
|
||||
void handleSyncResult(const ActivityResult& result);
|
||||
void applyOrientation(uint8_t orientation);
|
||||
void applyTextDarkness(uint8_t textDarkness);
|
||||
void toggleAutoPageTurn(uint8_t selectedPageTurnOption);
|
||||
void applyBookReaderOverrides(int8_t embeddedStyleOverride, int8_t imageRenderingOverride);
|
||||
bool getEffectiveEmbeddedStyle() const;
|
||||
|
||||
@@ -12,26 +12,29 @@ EpubReaderMenuActivity::EpubReaderMenuActivity(GfxRenderer& renderer, MappedInpu
|
||||
const std::string& title, const int currentPage, const int totalPages,
|
||||
const int bookProgressPercent, const uint8_t currentOrientation,
|
||||
const bool hasFootnotes, const int8_t initialEmbeddedStyleOverride,
|
||||
const int8_t initialImageRenderingOverride)
|
||||
const int8_t initialImageRenderingOverride,
|
||||
const uint8_t initialTextDarkness)
|
||||
: Activity("EpubReaderMenu", renderer, mappedInput),
|
||||
menuItems(buildMenuItems(hasFootnotes)),
|
||||
title(title),
|
||||
pendingOrientation(currentOrientation),
|
||||
pendingEmbeddedStyleOverride(initialEmbeddedStyleOverride),
|
||||
pendingImageRenderingOverride(initialImageRenderingOverride),
|
||||
pendingTextDarkness(initialTextDarkness),
|
||||
currentPage(currentPage),
|
||||
totalPages(totalPages),
|
||||
bookProgressPercent(bookProgressPercent) {}
|
||||
|
||||
std::vector<EpubReaderMenuActivity::MenuItem> EpubReaderMenuActivity::buildMenuItems(bool hasFootnotes) {
|
||||
std::vector<MenuItem> items;
|
||||
items.reserve(12);
|
||||
items.reserve(13);
|
||||
items.push_back({MenuAction::SELECT_CHAPTER, StrId::STR_SELECT_CHAPTER});
|
||||
if (hasFootnotes) {
|
||||
items.push_back({MenuAction::FOOTNOTES, StrId::STR_FOOTNOTES});
|
||||
}
|
||||
items.push_back({MenuAction::EMBEDDED_STYLE, StrId::STR_EMBEDDED_STYLE});
|
||||
items.push_back({MenuAction::IMAGE_RENDERING, StrId::STR_IMAGES});
|
||||
items.push_back({MenuAction::TEXT_DARKNESS, StrId::STR_TEXT_DARKNESS});
|
||||
items.push_back({MenuAction::ROTATE_SCREEN, StrId::STR_ORIENTATION});
|
||||
items.push_back({MenuAction::AUTO_PAGE_TURN, StrId::STR_AUTO_TURN_PAGES_PER_MIN});
|
||||
items.push_back({MenuAction::GO_TO_PERCENT, StrId::STR_GO_TO_PERCENT});
|
||||
@@ -106,15 +109,25 @@ void EpubReaderMenuActivity::loop() {
|
||||
return;
|
||||
}
|
||||
|
||||
if (selectedAction == MenuAction::TEXT_DARKNESS) {
|
||||
pendingTextDarkness = (pendingTextDarkness + 1) % textDarknessLabels.size();
|
||||
requestUpdate();
|
||||
return;
|
||||
}
|
||||
|
||||
setResult(MenuResult{static_cast<int>(selectedAction), pendingOrientation, selectedPageTurnOption,
|
||||
pendingEmbeddedStyleOverride, pendingImageRenderingOverride});
|
||||
pendingEmbeddedStyleOverride, pendingImageRenderingOverride, pendingTextDarkness});
|
||||
finish();
|
||||
return;
|
||||
} else if (mappedInput.wasReleased(MappedInputManager::Button::Back)) {
|
||||
ActivityResult result;
|
||||
result.isCancelled = true;
|
||||
result.data = MenuResult{-1, pendingOrientation, selectedPageTurnOption, pendingEmbeddedStyleOverride,
|
||||
pendingImageRenderingOverride};
|
||||
result.data = MenuResult{-1,
|
||||
pendingOrientation,
|
||||
selectedPageTurnOption,
|
||||
pendingEmbeddedStyleOverride,
|
||||
pendingImageRenderingOverride,
|
||||
pendingTextDarkness};
|
||||
setResult(std::move(result));
|
||||
finish();
|
||||
return;
|
||||
@@ -191,6 +204,13 @@ void EpubReaderMenuActivity::render(RenderLock&&) {
|
||||
const auto width = renderer.getTextWidth(UI_10_FONT_ID, value);
|
||||
renderer.drawText(UI_10_FONT_ID, contentRect.x + contentRect.width - 20 - width, displayY, value, !isSelected);
|
||||
}
|
||||
|
||||
if (menuItems[i].action == MenuAction::TEXT_DARKNESS) {
|
||||
const uint8_t idx = (pendingTextDarkness < textDarknessLabels.size()) ? pendingTextDarkness : 0;
|
||||
const char* value = I18N.get(textDarknessLabels[idx]);
|
||||
const auto width = renderer.getTextWidth(UI_10_FONT_ID, value);
|
||||
renderer.drawText(UI_10_FONT_ID, contentRect.x + contentRect.width - 20 - width, displayY, value, !isSelected);
|
||||
}
|
||||
}
|
||||
|
||||
// Footer / Hints
|
||||
|
||||
@@ -16,6 +16,7 @@ class EpubReaderMenuActivity final : public Activity {
|
||||
FOOTNOTES,
|
||||
EMBEDDED_STYLE,
|
||||
IMAGE_RENDERING,
|
||||
TEXT_DARKNESS,
|
||||
GO_TO_PERCENT,
|
||||
AUTO_PAGE_TURN,
|
||||
ROTATE_SCREEN,
|
||||
@@ -30,8 +31,8 @@ class EpubReaderMenuActivity final : public Activity {
|
||||
explicit EpubReaderMenuActivity(GfxRenderer& renderer, MappedInputManager& mappedInput, const std::string& title,
|
||||
const int currentPage, const int totalPages, const int bookProgressPercent,
|
||||
const uint8_t currentOrientation, const bool hasFootnotes,
|
||||
const int8_t initialEmbeddedStyleOverride,
|
||||
const int8_t initialImageRenderingOverride);
|
||||
const int8_t initialEmbeddedStyleOverride, const int8_t initialImageRenderingOverride,
|
||||
const uint8_t initialTextDarkness);
|
||||
|
||||
void onEnter() override;
|
||||
void onExit() override;
|
||||
@@ -57,8 +58,11 @@ class EpubReaderMenuActivity final : public Activity {
|
||||
uint8_t selectedPageTurnOption = 0;
|
||||
int8_t pendingEmbeddedStyleOverride = -1;
|
||||
int8_t pendingImageRenderingOverride = -1;
|
||||
uint8_t pendingTextDarkness = 1;
|
||||
const std::vector<StrId> orientationLabels = {StrId::STR_PORTRAIT, StrId::STR_LANDSCAPE_CW, StrId::STR_INVERTED,
|
||||
StrId::STR_LANDSCAPE_CCW};
|
||||
const std::vector<StrId> textDarknessLabels = {StrId::STR_NORMAL, StrId::STR_DARK, StrId::STR_EXTRA_DARK,
|
||||
StrId::STR_MAX_DARK};
|
||||
const std::vector<StrId> imageRenderingLabels = {StrId::STR_IMAGES_DISPLAY, StrId::STR_IMAGES_PLACEHOLDER,
|
||||
StrId::STR_IMAGES_SUPPRESS};
|
||||
const std::vector<const char*> pageTurnLabels = {I18N.get(StrId::STR_STATE_OFF), "1", "3", "6", "12"};
|
||||
|
||||
@@ -271,6 +271,7 @@ void loop() {
|
||||
HalClock::updatePeriodic();
|
||||
|
||||
renderer.setFadingFix(SETTINGS.fadingFix);
|
||||
renderer.setTextDarkness(SETTINGS.textDarkness);
|
||||
|
||||
if (Serial && millis() - lastMemPrint >= 10000) {
|
||||
LOG_INF("MEM", "Free: %d bytes, Total: %d bytes, Min Free: %d bytes, MaxAlloc: %d bytes", ESP.getFreeHeap(),
|
||||
|
||||
Reference in New Issue
Block a user