Expose override menu

This commit is contained in:
jpirnay
2026-05-23 10:24:12 +02:00
parent 39228b7631
commit a03f5faad5
12 changed files with 386 additions and 33 deletions
+2
View File
@@ -31,6 +31,8 @@ struct MenuResult {
uint8_t textDarkness = 1;
uint8_t bionicReadingOverride = 0;
int8_t paragraphAlignmentOverride = -1;
int8_t textAntiAliasingOverride = -1;
int8_t hyphenationOverride = -1;
};
struct ChapterResult {
+64 -13
View File
@@ -33,6 +33,7 @@
#include "KOReaderDocumentId.h"
#include "MappedInputManager.h"
#include "QrDisplayActivity.h"
#include "QuickOverridesActivity.h"
#include "ReaderActivity.h"
#include "ReaderUtils.h"
#include "ReadingSessionTracker.h"
@@ -333,6 +334,8 @@ void EpubReaderActivity::onEnter() {
? static_cast<bool>(currentBook.bionicReadingOverride)
: static_cast<bool>(SETTINGS.bionicReading);
bookParagraphAlignmentOverride = currentBook.paragraphAlignmentOverride;
bookTextAntiAliasingOverride = currentBook.textAntiAliasingOverride;
bookHyphenationOverride = currentBook.hyphenationOverride;
logReaderMemSnapshot("onEnter_after_recent_books");
// Start a reading-stats session. We use the cheap filename-based hash here:
@@ -1350,6 +1353,15 @@ void EpubReaderActivity::applyBookReaderOverrides(const int8_t embeddedStyleOver
const std::string& sdFontFamilyOverride,
const int8_t fontSizeOverride, const bool bionicReadingOverride,
const int8_t paragraphAlignmentOverride) {
applyBookReaderOverrides(embeddedStyleOverride, imageRenderingOverride, fontFamilyOverride, sdFontFamilyOverride,
fontSizeOverride, static_cast<int8_t>(bionicReadingOverride ? 1 : 0),
paragraphAlignmentOverride, bookTextAntiAliasingOverride, bookHyphenationOverride);
}
void EpubReaderActivity::applyBookReaderOverrides(
const int8_t embeddedStyleOverride, const int8_t imageRenderingOverride, const int8_t fontFamilyOverride,
const std::string& sdFontFamilyOverride, const int8_t fontSizeOverride, const int8_t bionicReadingOverride,
const int8_t paragraphAlignmentOverride, const int8_t textAntiAliasingOverride, const int8_t hyphenationOverride) {
if (!epub) {
return;
}
@@ -1363,11 +1375,12 @@ void EpubReaderActivity::applyBookReaderOverrides(const int8_t embeddedStyleOver
normalizedFontFamilyOverride = -1;
}
const bool bionicAsBool = bionicReadingOverride > 0;
if (bookEmbeddedStyleOverride == embeddedStyleOverride && bookImageRenderingOverride == imageRenderingOverride &&
bookFontFamilyOverride == normalizedFontFamilyOverride &&
bookSdFontFamilyOverride == normalizedSdFontFamilyOverride && bookFontSizeOverride == fontSizeOverride &&
bookBionicReadingOverride == bionicReadingOverride &&
bookParagraphAlignmentOverride == paragraphAlignmentOverride) {
bookBionicReadingOverride == bionicAsBool && bookParagraphAlignmentOverride == paragraphAlignmentOverride &&
bookTextAntiAliasingOverride == textAntiAliasingOverride && bookHyphenationOverride == hyphenationOverride) {
return;
}
@@ -1376,11 +1389,14 @@ void EpubReaderActivity::applyBookReaderOverrides(const int8_t embeddedStyleOver
bookFontFamilyOverride = normalizedFontFamilyOverride;
bookSdFontFamilyOverride = normalizedSdFontFamilyOverride;
bookFontSizeOverride = fontSizeOverride;
bookBionicReadingOverride = bionicReadingOverride;
bookBionicReadingOverride = bionicAsBool;
bookParagraphAlignmentOverride = paragraphAlignmentOverride;
bookTextAntiAliasingOverride = textAntiAliasingOverride;
bookHyphenationOverride = hyphenationOverride;
RECENT_BOOKS.setReaderOverrides(epub->getPath(), bookEmbeddedStyleOverride, bookImageRenderingOverride,
bookFontFamilyOverride, bookSdFontFamilyOverride, bookFontSizeOverride,
bookBionicReadingOverride, bookParagraphAlignmentOverride);
bookBionicReadingOverride, bookParagraphAlignmentOverride,
bookTextAntiAliasingOverride, bookHyphenationOverride);
RenderLock lock(*this);
if (section) {
@@ -1405,6 +1421,20 @@ uint8_t EpubReaderActivity::getEffectiveImageRendering() const {
return SETTINGS.imageRendering;
}
bool EpubReaderActivity::getEffectiveTextAntiAliasing() const {
if (bookTextAntiAliasingOverride >= 0) {
return bookTextAntiAliasingOverride != 0;
}
return SETTINGS.textAntiAliasing != 0;
}
bool EpubReaderActivity::getEffectiveHyphenation() const {
if (bookHyphenationOverride >= 0) {
return bookHyphenationOverride != 0;
}
return SETTINGS.hyphenationEnabled != 0;
}
uint8_t EpubReaderActivity::getEffectiveParagraphAlignment() const {
if (bookParagraphAlignmentOverride >= 0) {
return static_cast<uint8_t>(bookParagraphAlignmentOverride);
@@ -1690,7 +1720,7 @@ void EpubReaderActivity::render(RenderLock&& lock) {
lastRenderStats.embeddedStyle = getEffectiveEmbeddedStyle();
lastRenderStats.imageRendering = getEffectiveImageRendering();
lastRenderStats.effectiveFontId = getEffectiveReaderFontId();
lastRenderStats.textAntiAliasing = SETTINGS.textAntiAliasing;
lastRenderStats.textAntiAliasing = getEffectiveTextAntiAliasing();
lastRenderStats.freeHeapBefore = esp_get_free_heap_size();
lastRenderStats.largestFreeBlockBefore = heap_caps_get_largest_free_block(MALLOC_CAP_8BIT | MALLOC_CAP_DEFAULT);
showTruncatedSectionHintThisRender = false;
@@ -1775,7 +1805,7 @@ void EpubReaderActivity::render(RenderLock&& lock) {
if (!section->loadSectionFile(getEffectiveReaderFontId(), getEffectiveReaderLineCompression(),
SETTINGS.extraParagraphSpacing, getEffectiveParagraphAlignment(), viewportWidth,
viewportHeight, SETTINGS.hyphenationEnabled, embeddedStyle, bookBionicReadingOverride,
viewportHeight, getEffectiveHyphenation(), embeddedStyle, bookBionicReadingOverride,
imageRendering)) {
LOG_DBG("ERS", "Cache not found, building...");
lastRenderStats.cacheRebuilt = true;
@@ -1797,7 +1827,7 @@ void EpubReaderActivity::render(RenderLock&& lock) {
renderer.clearSdCardFontAccumulation();
if (!section->createSectionFile(getEffectiveReaderFontId(), getEffectiveReaderLineCompression(),
SETTINGS.extraParagraphSpacing, getEffectiveParagraphAlignment(), viewportWidth,
viewportHeight, SETTINGS.hyphenationEnabled, embeddedStyle,
viewportHeight, getEffectiveHyphenation(), embeddedStyle,
bookBionicReadingOverride, imageRendering, progressFn)) {
LOG_ERR("ERS", "Failed to persist page data to SD");
section.reset();
@@ -1819,12 +1849,12 @@ void EpubReaderActivity::render(RenderLock&& lock) {
renderer.clearSdCardFontAccumulation();
if (!section->createSectionFile(getEffectiveReaderFontId(), getEffectiveReaderLineCompression(),
SETTINGS.extraParagraphSpacing, getEffectiveParagraphAlignment(), viewportWidth,
viewportHeight, SETTINGS.hyphenationEnabled, embeddedStyle,
viewportHeight, getEffectiveHyphenation(), embeddedStyle,
bookBionicReadingOverride, imageRendering, progressFn)) {
LOG_ERR("ERS", "Failed to rebuild CSS section cache; keeping fallback");
section->loadSectionFile(getEffectiveReaderFontId(), getEffectiveReaderLineCompression(),
SETTINGS.extraParagraphSpacing, getEffectiveParagraphAlignment(), viewportWidth,
viewportHeight, SETTINGS.hyphenationEnabled, embeddedStyle, bookBionicReadingOverride,
viewportHeight, getEffectiveHyphenation(), embeddedStyle, bookBionicReadingOverride,
imageRendering);
}
} else {
@@ -1945,7 +1975,7 @@ void EpubReaderActivity::silentIndexNextChapterIfNeeded(const uint16_t viewportW
Section nextSection(epub, nextSpineIndex, renderer);
if (nextSection.loadSectionFile(getEffectiveReaderFontId(), getEffectiveReaderLineCompression(),
SETTINGS.extraParagraphSpacing, SETTINGS.paragraphAlignment, viewportWidth,
viewportHeight, SETTINGS.hyphenationEnabled, embeddedStyle, bookBionicReadingOverride,
viewportHeight, getEffectiveHyphenation(), embeddedStyle, bookBionicReadingOverride,
imageRendering)) {
return;
}
@@ -1955,7 +1985,7 @@ void EpubReaderActivity::silentIndexNextChapterIfNeeded(const uint16_t viewportW
renderer.clearSdCardFontAccumulation();
if (!nextSection.createSectionFile(getEffectiveReaderFontId(), getEffectiveReaderLineCompression(),
SETTINGS.extraParagraphSpacing, SETTINGS.paragraphAlignment, viewportWidth,
viewportHeight, SETTINGS.hyphenationEnabled, embeddedStyle,
viewportHeight, getEffectiveHyphenation(), embeddedStyle,
bookBionicReadingOverride, imageRendering)) {
LOG_ERR("ERS", "Failed silent indexing for chapter: %d", nextSpineIndex);
}
@@ -2010,7 +2040,7 @@ void EpubReaderActivity::renderContents(std::unique_ptr<Page> page, const int or
contigAfter, (int32_t)heapAfter - (int32_t)heapBefore);
logReaderMemSnapshot("prewarm_end");
const bool aaConfigured = SETTINGS.textAntiAliasing;
const bool aaConfigured = getEffectiveTextAntiAliasing();
bool aaEnabledForThisRender = aaConfigured;
if (aaConfigured && antiAliasingSuspendedLowMemory) {
const uint32_t freeHeapNow = esp_get_free_heap_size();
@@ -2288,7 +2318,7 @@ void EpubReaderActivity::displayPreRenderedPage(const Page& page, const int orie
// Grayscale AA pass. Prefer the tiled strip path (no BW snapshot needed);
// fall back to the legacy storeBwBufferRect path on controllers that don't
// support strip grayscale or when the strip scratch can't be allocated.
const bool aaConfigured = SETTINGS.textAntiAliasing && !antiAliasingSuspendedLowMemory;
const bool aaConfigured = getEffectiveTextAntiAliasing() && !antiAliasingSuspendedLowMemory;
if (aaConfigured) {
if (runTiledGrayscalePass(renderer, page, getEffectiveReaderFontId(), orientedMarginLeft, contentTop,
SETTINGS.fastAntiAliasing)) {
@@ -2575,6 +2605,22 @@ bool EpubReaderActivity::drawCurrentPageToBuffer(const std::string& filePath, Gf
return true;
}
void EpubReaderActivity::openQuickOverrides() {
ReaderUtils::enforceExitFullRefresh(renderer);
startActivityForResult(
std::make_unique<QuickOverridesActivity>(
renderer, mappedInput, bookEmbeddedStyleOverride, bookImageRenderingOverride, bookFontFamilyOverride,
bookSdFontFamilyOverride, bookFontSizeOverride, static_cast<int8_t>(bookBionicReadingOverride ? 1 : 0),
bookParagraphAlignmentOverride, bookTextAntiAliasingOverride, bookHyphenationOverride),
[this](const ActivityResult& result) {
const auto& menu = std::get<MenuResult>(result.data);
applyBookReaderOverrides(menu.embeddedStyleOverride, menu.imageRenderingOverride, menu.fontFamilyOverride,
menu.sdFontFamilyOverride, menu.fontSizeOverride,
static_cast<int8_t>(menu.bionicReadingOverride), menu.paragraphAlignmentOverride,
menu.textAntiAliasingOverride, menu.hyphenationOverride);
});
}
void EpubReaderActivity::openReaderMenu() {
const int currentPage = section ? section->currentPage + 1 : 0;
const int totalPages = section ? section->pageCount : 0;
@@ -2762,6 +2808,11 @@ void EpubReaderActivity::onButtonAction(const CrossPointSettings::BUTTON_ACTION
case BA::BTN_KOREADER_SYNC:
launchKOReaderSync(SyncLaunchMode::COMPARE);
break;
case BA::BTN_QUICK_OVERRIDES:
if (epub) {
openQuickOverrides();
}
break;
default:
break;
}
@@ -235,6 +235,8 @@ class EpubReaderActivity final : public Activity {
int8_t bookFontSizeOverride = -1;
bool bookBionicReadingOverride = false;
int8_t bookParagraphAlignmentOverride = -1;
int8_t bookTextAntiAliasingOverride = -1;
int8_t bookHyphenationOverride = -1;
// Bookmarks (starred pages)
BookmarkStore bookmarkStore;
@@ -299,10 +301,20 @@ class EpubReaderActivity final : public Activity {
void applyBookReaderOverrides(int8_t embeddedStyleOverride, int8_t imageRenderingOverride, int8_t fontFamilyOverride,
const std::string& sdFontFamilyOverride, int8_t fontSizeOverride,
bool bionicReadingOverride, int8_t paragraphAlignmentOverride);
// Wider variant that also covers AA and hyphenation. Used by QuickOverridesActivity;
// the narrower overload above funnels through here, preserving the AA/hyphenation
// values currently held on this activity.
void applyBookReaderOverrides(int8_t embeddedStyleOverride, int8_t imageRenderingOverride, int8_t fontFamilyOverride,
const std::string& sdFontFamilyOverride, int8_t fontSizeOverride,
int8_t bionicReadingOverride, int8_t paragraphAlignmentOverride,
int8_t textAntiAliasingOverride, int8_t hyphenationOverride);
void openReaderMenu();
void openQuickOverrides();
bool getEffectiveEmbeddedStyle() const;
uint8_t getEffectiveImageRendering() const;
uint8_t getEffectiveParagraphAlignment() const;
bool getEffectiveTextAntiAliasing() const;
bool getEffectiveHyphenation() const;
int getEffectiveReaderFontId() const;
float getEffectiveReaderLineCompression() const;
bool stepPageState(bool isForwardTurn);
@@ -0,0 +1,216 @@
#include "QuickOverridesActivity.h"
#include <GfxRenderer.h>
#include <HalDisplay.h>
#include <I18n.h>
#include "MappedInputManager.h"
#include "activities/ActivityResult.h"
#include "components/UITheme.h"
#include "fontIds.h"
QuickOverridesActivity::QuickOverridesActivity(
GfxRenderer& renderer, MappedInputManager& mappedInput, const int8_t initialEmbeddedStyleOverride,
const int8_t initialImageRenderingOverride, const int8_t initialFontFamilyOverride,
const std::string& initialSdFontFamilyOverride, const int8_t initialFontSizeOverride,
const int8_t initialBionicReadingOverride, const int8_t initialParagraphAlignmentOverride,
const int8_t initialTextAntiAliasingOverride, const int8_t initialHyphenationOverride)
: MenuListActivity("QuickOverrides", renderer, mappedInput),
pendingEmbeddedStyleOverride(initialEmbeddedStyleOverride),
pendingImageRenderingOverride(initialImageRenderingOverride),
pendingFontFamilyOverride(initialFontFamilyOverride),
pendingSdFontFamilyOverride(initialSdFontFamilyOverride),
pendingFontSizeOverride(initialFontSizeOverride),
pendingBionicReadingOverride(initialBionicReadingOverride),
pendingParagraphAlignmentOverride(initialParagraphAlignmentOverride),
pendingTextAntiAliasingOverride(initialTextAntiAliasingOverride),
pendingHyphenationOverride(initialHyphenationOverride) {
buildMenuItems();
}
namespace {
// Three-state cycle helper for overrides represented as int8_t with -1 = default.
// slot 0 -> -1 (default)
// slot 1 -> 1 (on)
// slot 2 -> 0 (off)
uint8_t threeStateSlotFromOverride(int8_t value) {
if (value < 0) return 0;
if (value > 0) return 1;
return 2;
}
int8_t threeStateOverrideFromSlot(uint8_t slot) {
if (slot == 0) return -1;
if (slot == 1) return 1;
return 0;
}
} // namespace
void QuickOverridesActivity::buildMenuItems() {
menuItems.reserve(8);
auto* self = this;
// Embedded style: default / on / off
menuItems.push_back(SettingInfo::DynamicEnumCtx(
StrId::STR_EMBEDDED_STYLE, {StrId::STR_DEFAULT_VALUE, StrId::STR_STATE_ON, StrId::STR_STATE_OFF}, self,
[](const void* ctx) -> uint8_t {
return threeStateSlotFromOverride(static_cast<const QuickOverridesActivity*>(ctx)->pendingEmbeddedStyleOverride);
},
[](void* ctx, uint8_t v) {
static_cast<QuickOverridesActivity*>(ctx)->pendingEmbeddedStyleOverride = threeStateOverrideFromSlot(v);
}));
// Image rendering: default(-1) / display(0) / placeholder(1) / suppress(2)
menuItems.push_back(SettingInfo::DynamicEnumCtx(
StrId::STR_IMAGES,
{StrId::STR_DEFAULT_VALUE, StrId::STR_IMAGES_DISPLAY, StrId::STR_IMAGES_PLACEHOLDER, StrId::STR_IMAGES_SUPPRESS},
self,
[](const void* ctx) -> uint8_t {
const auto* s = static_cast<const QuickOverridesActivity*>(ctx);
return (s->pendingImageRenderingOverride < 0) ? 0 : (s->pendingImageRenderingOverride + 1);
},
[](void* ctx, uint8_t v) {
auto* s = static_cast<QuickOverridesActivity*>(ctx);
s->pendingImageRenderingOverride = (v == 0) ? -1 : static_cast<int8_t>(v - 1);
}));
// Font family: built-in only — preserves any SD-family override unless the user
// explicitly picks a built-in (which clears it, matching the storage semantics).
menuItems.push_back(SettingInfo::DynamicEnumCtx(
StrId::STR_FONT_FAMILY, {StrId::STR_DEFAULT_VALUE, StrId::STR_BOOKERLY, StrId::STR_NOTO_SANS}, self,
[](const void* ctx) -> uint8_t {
const auto* s = static_cast<const QuickOverridesActivity*>(ctx);
return (s->pendingFontFamilyOverride < 0) ? 0 : static_cast<uint8_t>(s->pendingFontFamilyOverride + 1);
},
[](void* ctx, uint8_t v) {
auto* s = static_cast<QuickOverridesActivity*>(ctx);
if (v == 0) {
s->pendingFontFamilyOverride = -1;
} else {
s->pendingFontFamilyOverride = static_cast<int8_t>(v - 1);
s->pendingSdFontFamilyOverride.clear();
}
}));
// Font size: default(-1) -> Small(0) -> Medium(1) -> Large(2) -> X Large(3) -> Tiny(4)
menuItems.push_back(SettingInfo::DynamicEnumCtx(
StrId::STR_FONT_SIZE,
{StrId::STR_DEFAULT_VALUE, StrId::STR_SMALL, StrId::STR_MEDIUM, StrId::STR_LARGE, StrId::STR_X_LARGE,
StrId::STR_TINY},
self,
[](const void* ctx) -> uint8_t {
const auto* s = static_cast<const QuickOverridesActivity*>(ctx);
return (s->pendingFontSizeOverride < 0) ? 0 : static_cast<uint8_t>(s->pendingFontSizeOverride + 1);
},
[](void* ctx, uint8_t v) {
auto* s = static_cast<QuickOverridesActivity*>(ctx);
s->pendingFontSizeOverride = (v == 0) ? -1 : static_cast<int8_t>(v - 1);
}));
// Bionic: default / on / off
menuItems.push_back(SettingInfo::DynamicEnumCtx(
StrId::STR_BIONIC_READING, {StrId::STR_DEFAULT_VALUE, StrId::STR_STATE_ON, StrId::STR_STATE_OFF}, self,
[](const void* ctx) -> uint8_t {
return threeStateSlotFromOverride(static_cast<const QuickOverridesActivity*>(ctx)->pendingBionicReadingOverride);
},
[](void* ctx, uint8_t v) {
static_cast<QuickOverridesActivity*>(ctx)->pendingBionicReadingOverride = threeStateOverrideFromSlot(v);
}));
// Paragraph alignment: default(-1) + the 5 global options
menuItems.push_back(SettingInfo::DynamicEnumCtx(
StrId::STR_PARA_ALIGNMENT,
{StrId::STR_DEFAULT_VALUE, StrId::STR_JUSTIFY, StrId::STR_ALIGN_LEFT, StrId::STR_CENTER, StrId::STR_ALIGN_RIGHT,
StrId::STR_BOOK_S_STYLE},
self,
[](const void* ctx) -> uint8_t {
const auto* s = static_cast<const QuickOverridesActivity*>(ctx);
return (s->pendingParagraphAlignmentOverride < 0) ? 0
: static_cast<uint8_t>(s->pendingParagraphAlignmentOverride + 1);
},
[](void* ctx, uint8_t v) {
auto* s = static_cast<QuickOverridesActivity*>(ctx);
s->pendingParagraphAlignmentOverride = (v == 0) ? -1 : static_cast<int8_t>(v - 1);
}));
// Text anti-aliasing: default / on / off
menuItems.push_back(SettingInfo::DynamicEnumCtx(
StrId::STR_TEXT_AA, {StrId::STR_DEFAULT_VALUE, StrId::STR_STATE_ON, StrId::STR_STATE_OFF}, self,
[](const void* ctx) -> uint8_t {
return threeStateSlotFromOverride(
static_cast<const QuickOverridesActivity*>(ctx)->pendingTextAntiAliasingOverride);
},
[](void* ctx, uint8_t v) {
static_cast<QuickOverridesActivity*>(ctx)->pendingTextAntiAliasingOverride = threeStateOverrideFromSlot(v);
}));
// Hyphenation: default / on / off
menuItems.push_back(SettingInfo::DynamicEnumCtx(
StrId::STR_HYPHENATION, {StrId::STR_DEFAULT_VALUE, StrId::STR_STATE_ON, StrId::STR_STATE_OFF}, self,
[](const void* ctx) -> uint8_t {
return threeStateSlotFromOverride(static_cast<const QuickOverridesActivity*>(ctx)->pendingHyphenationOverride);
},
[](void* ctx, uint8_t v) {
static_cast<QuickOverridesActivity*>(ctx)->pendingHyphenationOverride = threeStateOverrideFromSlot(v);
}));
}
void QuickOverridesActivity::onEnter() {
MenuListActivity::onEnter();
// Fast refresh keeps the menu feeling responsive when cycling options. The
// parent reader is responsible for its own full refresh on resume if any
// override actually changed (applyBookReaderOverrides short-circuits if not).
renderer.setNextDisplayRefreshMode(HalDisplay::FAST_REFRESH);
}
void QuickOverridesActivity::onSettingToggled(int /*index*/) {
// No persistence on each toggle — overrides are committed on exit through
// the result handler in the parent reader activity.
renderer.setNextDisplayRefreshMode(HalDisplay::FAST_REFRESH);
}
void QuickOverridesActivity::onBackPressed() {
finishWithResult(/*cancelled=*/false);
}
void QuickOverridesActivity::finishWithResult(bool cancelled) {
ActivityResult result;
result.isCancelled = cancelled;
MenuResult payload;
payload.action = -1;
payload.nameId = -1;
payload.embeddedStyleOverride = pendingEmbeddedStyleOverride;
payload.imageRenderingOverride = pendingImageRenderingOverride;
payload.fontFamilyOverride = pendingFontFamilyOverride;
payload.sdFontFamilyOverride = pendingSdFontFamilyOverride;
payload.fontSizeOverride = pendingFontSizeOverride;
payload.bionicReadingOverride = (pendingBionicReadingOverride > 0) ? 1 : 0;
payload.paragraphAlignmentOverride = pendingParagraphAlignmentOverride;
payload.textAntiAliasingOverride = pendingTextAntiAliasingOverride;
payload.hyphenationOverride = pendingHyphenationOverride;
result.data = std::move(payload);
setResult(std::move(result));
finish();
}
void QuickOverridesActivity::render(RenderLock&&) {
renderer.clearScreen();
const Rect contentRect = UITheme::getContentRect(renderer, true, false);
const std::string title = tr(STR_QUICK_OVERRIDES);
const int titleX =
contentRect.x + (contentRect.width - renderer.getTextWidth(UI_12_FONT_ID, title.c_str(), EpdFontFamily::BOLD)) / 2;
renderer.drawText(UI_12_FONT_ID, titleX, 15 + contentRect.y, title.c_str(), true, EpdFontFamily::BOLD);
const int startY = 50 + contentRect.y;
const int listHeight = contentRect.height - (startY - contentRect.y);
drawMenuList(Rect{contentRect.x, startY, contentRect.width, listHeight});
const auto labels = mappedInput.mapLabels(tr(STR_BACK), tr(STR_SELECT), tr(STR_DIR_UP), tr(STR_DIR_DOWN));
GUI.drawButtonHints(renderer, labels.btn1, labels.btn2, labels.btn3, labels.btn4);
renderer.displayBuffer(HalDisplay::FAST_REFRESH);
}
@@ -0,0 +1,42 @@
#pragma once
#include <I18n.h>
#include <string>
#include "../MenuListActivity.h"
// Bottom-of-the-toolbox quick-overrides menu: shows only the per-book overrides
// (font family, size, embedded style, image rendering, bionic, paragraph
// alignment, anti-aliasing, hyphenation). Optimised for snappy in-book toggling:
// renders in FAST_REFRESH mode and reports back through MenuResult; the parent
// reader applies the result through its existing applyBookReaderOverrides()
// path, which itself short-circuits when nothing changed.
class QuickOverridesActivity final : public MenuListActivity {
public:
QuickOverridesActivity(GfxRenderer& renderer, MappedInputManager& mappedInput,
int8_t initialEmbeddedStyleOverride, int8_t initialImageRenderingOverride,
int8_t initialFontFamilyOverride, const std::string& initialSdFontFamilyOverride,
int8_t initialFontSizeOverride, int8_t initialBionicReadingOverride,
int8_t initialParagraphAlignmentOverride, int8_t initialTextAntiAliasingOverride,
int8_t initialHyphenationOverride);
void onEnter() override;
void render(RenderLock&&) override;
private:
void buildMenuItems();
void finishWithResult(bool cancelled);
void onBackPressed() override;
void onSettingToggled(int index) override;
int8_t pendingEmbeddedStyleOverride = -1;
int8_t pendingImageRenderingOverride = -1;
int8_t pendingFontFamilyOverride = -1;
std::string pendingSdFontFamilyOverride;
int8_t pendingFontSizeOverride = -1;
int8_t pendingBionicReadingOverride = -1;
int8_t pendingParagraphAlignmentOverride = -1;
int8_t pendingTextAntiAliasingOverride = -1;
int8_t pendingHyphenationOverride = -1;
};