chore: post-sync cleanup and clang-format
- Remove stale Lyra3CoversTheme.h (functionality merged into LyraTheme) - Fix UITheme.cpp to use LyraTheme for LYRA_3_COVERS theme variant - Update open-x4-sdk submodule to 91e7e2b (drawImageTransparent support) - Run clang-format on all source files Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -15,10 +15,10 @@
|
||||
|
||||
#include "CrossPointSettings.h"
|
||||
#include "CrossPointState.h"
|
||||
#include "util/BookSettings.h"
|
||||
#include "components/UITheme.h"
|
||||
#include "fontIds.h"
|
||||
#include "images/Logo120.h"
|
||||
#include "util/BookSettings.h"
|
||||
#include "util/StringUtils.h"
|
||||
|
||||
namespace {
|
||||
@@ -80,9 +80,7 @@ uint8_t quantizeBayerDither(int gray, int x, int y) {
|
||||
// creating a high-frequency checkerboard that causes e-ink display crosstalk
|
||||
// and washes out adjacent content during HALF_REFRESH.
|
||||
// Gray values 171-254 produce a level-2/level-3 mix via Bayer dithering.
|
||||
bool bayerCrossesBwBoundary(uint8_t gray) {
|
||||
return gray > 170 && gray < 255;
|
||||
}
|
||||
bool bayerCrossesBwBoundary(uint8_t gray) { return gray > 170 && gray < 255; }
|
||||
|
||||
// Hash-based block dithering for BW-boundary gray values (171-254).
|
||||
// Each blockSize×blockSize pixel block gets a single uniform level (2 or 3),
|
||||
@@ -301,9 +299,12 @@ void drawLetterboxFill(GfxRenderer& renderer, const LetterboxFillData& data, uin
|
||||
for (int y = 0; y < data.letterboxA; y++)
|
||||
for (int x = 0; x < renderer.getScreenWidth(); x++) {
|
||||
uint8_t lv;
|
||||
if (isSolid) lv = levelA;
|
||||
else if (hashA) lv = hashBlockDither(data.avgA, x, y);
|
||||
else lv = quantizeBayerDither(data.avgA, x, y);
|
||||
if (isSolid)
|
||||
lv = levelA;
|
||||
else if (hashA)
|
||||
lv = hashBlockDither(data.avgA, x, y);
|
||||
else
|
||||
lv = quantizeBayerDither(data.avgA, x, y);
|
||||
renderer.drawPixelGray(x, y, lv);
|
||||
}
|
||||
}
|
||||
@@ -312,9 +313,12 @@ void drawLetterboxFill(GfxRenderer& renderer, const LetterboxFillData& data, uin
|
||||
for (int y = start; y < renderer.getScreenHeight(); y++)
|
||||
for (int x = 0; x < renderer.getScreenWidth(); x++) {
|
||||
uint8_t lv;
|
||||
if (isSolid) lv = levelB;
|
||||
else if (hashB) lv = hashBlockDither(data.avgB, x, y);
|
||||
else lv = quantizeBayerDither(data.avgB, x, y);
|
||||
if (isSolid)
|
||||
lv = levelB;
|
||||
else if (hashB)
|
||||
lv = hashBlockDither(data.avgB, x, y);
|
||||
else
|
||||
lv = quantizeBayerDither(data.avgB, x, y);
|
||||
renderer.drawPixelGray(x, y, lv);
|
||||
}
|
||||
}
|
||||
@@ -323,9 +327,12 @@ void drawLetterboxFill(GfxRenderer& renderer, const LetterboxFillData& data, uin
|
||||
for (int x = 0; x < data.letterboxA; x++)
|
||||
for (int y = 0; y < renderer.getScreenHeight(); y++) {
|
||||
uint8_t lv;
|
||||
if (isSolid) lv = levelA;
|
||||
else if (hashA) lv = hashBlockDither(data.avgA, x, y);
|
||||
else lv = quantizeBayerDither(data.avgA, x, y);
|
||||
if (isSolid)
|
||||
lv = levelA;
|
||||
else if (hashA)
|
||||
lv = hashBlockDither(data.avgA, x, y);
|
||||
else
|
||||
lv = quantizeBayerDither(data.avgA, x, y);
|
||||
renderer.drawPixelGray(x, y, lv);
|
||||
}
|
||||
}
|
||||
@@ -334,9 +341,12 @@ void drawLetterboxFill(GfxRenderer& renderer, const LetterboxFillData& data, uin
|
||||
for (int x = start; x < renderer.getScreenWidth(); x++)
|
||||
for (int y = 0; y < renderer.getScreenHeight(); y++) {
|
||||
uint8_t lv;
|
||||
if (isSolid) lv = levelB;
|
||||
else if (hashB) lv = hashBlockDither(data.avgB, x, y);
|
||||
else lv = quantizeBayerDither(data.avgB, x, y);
|
||||
if (isSolid)
|
||||
lv = levelB;
|
||||
else if (hashB)
|
||||
lv = hashBlockDither(data.avgB, x, y);
|
||||
else
|
||||
lv = quantizeBayerDither(data.avgB, x, y);
|
||||
renderer.drawPixelGray(x, y, lv);
|
||||
}
|
||||
}
|
||||
@@ -523,9 +533,8 @@ void SleepActivity::renderBitmapSleepScreen(const Bitmap& bitmap, const std::str
|
||||
}
|
||||
}
|
||||
if (fillData.valid) {
|
||||
LOG_DBG("SLP", "Letterbox fill: %s, horizontal=%d, avgA=%d, avgB=%d, letterboxA=%d, letterboxB=%d",
|
||||
fillModeName, fillData.horizontal, fillData.avgA, fillData.avgB, fillData.letterboxA,
|
||||
fillData.letterboxB);
|
||||
LOG_DBG("SLP", "Letterbox fill: %s, horizontal=%d, avgA=%d, avgB=%d, letterboxA=%d, letterboxB=%d", fillModeName,
|
||||
fillData.horizontal, fillData.avgA, fillData.avgB, fillData.letterboxA, fillData.letterboxB);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
#include <GfxRenderer.h>
|
||||
#include <HalStorage.h>
|
||||
#include <I18n.h>
|
||||
#include <Utf8.h>
|
||||
#include <PlaceholderCoverGenerator.h>
|
||||
#include <Utf8.h>
|
||||
#include <Xtc.h>
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
@@ -17,9 +17,7 @@ void DictionaryDefinitionActivity::onEnter() {
|
||||
requestUpdate();
|
||||
}
|
||||
|
||||
void DictionaryDefinitionActivity::onExit() {
|
||||
Activity::onExit();
|
||||
}
|
||||
void DictionaryDefinitionActivity::onExit() { Activity::onExit(); }
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Check if a Unicode codepoint is likely renderable by the e-ink bitmap font.
|
||||
@@ -27,12 +25,12 @@ void DictionaryDefinitionActivity::onExit() {
|
||||
// Skips IPA extensions, Greek, Cyrillic, Arabic, CJK, and other non-Latin scripts.
|
||||
// ---------------------------------------------------------------------------
|
||||
bool DictionaryDefinitionActivity::isRenderableCodepoint(uint32_t cp) {
|
||||
if (cp <= 0x024F) return true; // Basic Latin + Latin Extended-A/B
|
||||
if (cp >= 0x0300 && cp <= 0x036F) return true; // Combining Diacritical Marks
|
||||
if (cp >= 0x2000 && cp <= 0x206F) return true; // General Punctuation
|
||||
if (cp >= 0x20A0 && cp <= 0x20CF) return true; // Currency Symbols
|
||||
if (cp >= 0x2100 && cp <= 0x214F) return true; // Letterlike Symbols
|
||||
if (cp >= 0x2190 && cp <= 0x21FF) return true; // Arrows
|
||||
if (cp <= 0x024F) return true; // Basic Latin + Latin Extended-A/B
|
||||
if (cp >= 0x0300 && cp <= 0x036F) return true; // Combining Diacritical Marks
|
||||
if (cp >= 0x2000 && cp <= 0x206F) return true; // General Punctuation
|
||||
if (cp >= 0x20A0 && cp <= 0x20CF) return true; // Currency Symbols
|
||||
if (cp >= 0x2100 && cp <= 0x214F) return true; // Letterlike Symbols
|
||||
if (cp >= 0x2190 && cp <= 0x21FF) return true; // Arrows
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -48,7 +46,7 @@ std::string DictionaryDefinitionActivity::decodeEntity(const std::string& entity
|
||||
if (entity == "apos") return "'";
|
||||
if (entity == "nbsp" || entity == "thinsp" || entity == "ensp" || entity == "emsp") return " ";
|
||||
if (entity == "ndash") return "\xE2\x80\x93"; // U+2013
|
||||
if (entity == "mdash") return "\xE2\x80\x94"; // U+2014
|
||||
if (entity == "mdash") return "\xE2\x80\x94"; // U+2014
|
||||
if (entity == "lsquo") return "\xE2\x80\x98";
|
||||
if (entity == "rsquo") return "\xE2\x80\x99";
|
||||
if (entity == "ldquo") return "\xE2\x80\x9C";
|
||||
@@ -502,11 +500,11 @@ void DictionaryDefinitionActivity::render(Activity::RenderLock&&) {
|
||||
const int tw = renderer.getTextWidth(SMALL_FONT_ID, truncated.c_str());
|
||||
|
||||
if (useCCW) {
|
||||
renderer.drawTextRotated90CCW(SMALL_FONT_ID, sideX,
|
||||
sideButtonY[i] + (sideButtonHeight - tw) / 2, truncated.c_str());
|
||||
renderer.drawTextRotated90CCW(SMALL_FONT_ID, sideX, sideButtonY[i] + (sideButtonHeight - tw) / 2,
|
||||
truncated.c_str());
|
||||
} else {
|
||||
renderer.drawTextRotated90CW(SMALL_FONT_ID, sideX,
|
||||
sideButtonY[i] + (sideButtonHeight + tw) / 2, truncated.c_str());
|
||||
renderer.drawTextRotated90CW(SMALL_FONT_ID, sideX, sideButtonY[i] + (sideButtonHeight + tw) / 2,
|
||||
truncated.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -13,9 +13,7 @@ void DictionarySuggestionsActivity::onEnter() {
|
||||
requestUpdate();
|
||||
}
|
||||
|
||||
void DictionarySuggestionsActivity::onExit() {
|
||||
ActivityWithSubactivity::onExit();
|
||||
}
|
||||
void DictionarySuggestionsActivity::onExit() { ActivityWithSubactivity::onExit(); }
|
||||
|
||||
void DictionarySuggestionsActivity::loop() {
|
||||
if (subActivity) {
|
||||
@@ -66,8 +64,8 @@ void DictionarySuggestionsActivity::loop() {
|
||||
}
|
||||
|
||||
enterNewActivity(new DictionaryDefinitionActivity(
|
||||
renderer, mappedInput, selected, definition, readerFontId, orientation,
|
||||
[this]() { pendingBackFromDef = true; }, [this]() { pendingExitToReader = true; }));
|
||||
renderer, mappedInput, selected, definition, readerFontId, orientation, [this]() { pendingBackFromDef = true; },
|
||||
[this]() { pendingExitToReader = true; }));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -25,9 +25,7 @@ void DictionaryWordSelectActivity::onEnter() {
|
||||
requestUpdate();
|
||||
}
|
||||
|
||||
void DictionaryWordSelectActivity::onExit() {
|
||||
ActivityWithSubactivity::onExit();
|
||||
}
|
||||
void DictionaryWordSelectActivity::onExit() { ActivityWithSubactivity::onExit(); }
|
||||
|
||||
bool DictionaryWordSelectActivity::isLandscape() const {
|
||||
return orientation == CrossPointSettings::ORIENTATION::LANDSCAPE_CW ||
|
||||
@@ -368,8 +366,8 @@ void DictionaryWordSelectActivity::loop() {
|
||||
|
||||
if (!definition.empty()) {
|
||||
enterNewActivity(new DictionaryDefinitionActivity(
|
||||
renderer, mappedInput, cleaned, definition, fontId, orientation,
|
||||
[this]() { pendingBackFromDef = true; }, [this]() { pendingExitToReader = true; }));
|
||||
renderer, mappedInput, cleaned, definition, fontId, orientation, [this]() { pendingBackFromDef = true; },
|
||||
[this]() { pendingExitToReader = true; }));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -379,8 +377,8 @@ void DictionaryWordSelectActivity::loop() {
|
||||
std::string stemDef = Dictionary::lookup(stem);
|
||||
if (!stemDef.empty()) {
|
||||
enterNewActivity(new DictionaryDefinitionActivity(
|
||||
renderer, mappedInput, stem, stemDef, fontId, orientation,
|
||||
[this]() { pendingBackFromDef = true; }, [this]() { pendingExitToReader = true; }));
|
||||
renderer, mappedInput, stem, stemDef, fontId, orientation, [this]() { pendingBackFromDef = true; },
|
||||
[this]() { pendingExitToReader = true; }));
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -459,7 +457,7 @@ void DictionaryWordSelectActivity::drawHints() {
|
||||
renderer.setOrientation(origOrientation);
|
||||
|
||||
// Bottom button constants (match LyraTheme::drawButtonHints)
|
||||
constexpr int buttonHeight = 40; // LyraMetrics::values.buttonHintsHeight
|
||||
constexpr int buttonHeight = 40; // LyraMetrics::values.buttonHintsHeight
|
||||
constexpr int buttonWidth = 80;
|
||||
constexpr int cornerRadius = 6;
|
||||
constexpr int textYOffset = 7;
|
||||
@@ -467,35 +465,43 @@ void DictionaryWordSelectActivity::drawHints() {
|
||||
constexpr int buttonPositions[] = {58, 146, 254, 342};
|
||||
|
||||
// Side button constants (match LyraTheme::drawSideButtonHints)
|
||||
constexpr int sideButtonWidth = 30; // LyraMetrics::values.sideButtonHintsWidth
|
||||
constexpr int sideButtonWidth = 30; // LyraMetrics::values.sideButtonHintsWidth
|
||||
constexpr int sideButtonHeight = 78;
|
||||
constexpr int sideButtonGap = 5;
|
||||
constexpr int sideTopY = 345; // topHintButtonY
|
||||
constexpr int sideTopY = 345; // topHintButtonY
|
||||
const int sideX = portW - sideButtonWidth;
|
||||
const int sideButtonY[2] = {sideTopY, sideTopY + sideButtonHeight + sideButtonGap};
|
||||
|
||||
// Labels for face and side buttons depend on orientation,
|
||||
// because the physical-to-logical mapping rotates with the screen.
|
||||
const char* facePrev; // label for physical Left face button
|
||||
const char* faceNext; // label for physical Right face button
|
||||
const char* sideTop; // label for physical top side button (PageBack)
|
||||
const char* sideBottom; // label for physical bottom side button (PageForward)
|
||||
const char* facePrev; // label for physical Left face button
|
||||
const char* faceNext; // label for physical Right face button
|
||||
const char* sideTop; // label for physical top side button (PageBack)
|
||||
const char* sideBottom; // label for physical bottom side button (PageForward)
|
||||
|
||||
const bool landscape = isLandscape();
|
||||
const bool inverted = isInverted();
|
||||
|
||||
if (landscape && orientation == CrossPointSettings::ORIENTATION::LANDSCAPE_CW) {
|
||||
facePrev = "Line Up"; faceNext = "Line Dn";
|
||||
sideTop = "Word \xC2\xBB"; sideBottom = "\xC2\xAB Word";
|
||||
facePrev = "Line Up";
|
||||
faceNext = "Line Dn";
|
||||
sideTop = "Word \xC2\xBB";
|
||||
sideBottom = "\xC2\xAB Word";
|
||||
} else if (landscape) { // LANDSCAPE_CCW
|
||||
facePrev = "Line Dn"; faceNext = "Line Up";
|
||||
sideTop = "\xC2\xAB Word"; sideBottom = "Word \xC2\xBB";
|
||||
facePrev = "Line Dn";
|
||||
faceNext = "Line Up";
|
||||
sideTop = "\xC2\xAB Word";
|
||||
sideBottom = "Word \xC2\xBB";
|
||||
} else if (inverted) {
|
||||
facePrev = "Word \xC2\xBB"; faceNext = "\xC2\xAB Word";
|
||||
sideTop = "Line Dn"; sideBottom = "Line Up";
|
||||
facePrev = "Word \xC2\xBB";
|
||||
faceNext = "\xC2\xAB Word";
|
||||
sideTop = "Line Dn";
|
||||
sideBottom = "Line Up";
|
||||
} else { // Portrait (default)
|
||||
facePrev = "\xC2\xAB Word"; faceNext = "Word \xC2\xBB";
|
||||
sideTop = "Line Up"; sideBottom = "Line Dn";
|
||||
facePrev = "\xC2\xAB Word";
|
||||
faceNext = "Word \xC2\xBB";
|
||||
sideTop = "Line Up";
|
||||
sideBottom = "Line Dn";
|
||||
}
|
||||
|
||||
const auto labels = mappedInput.mapLabels("\xC2\xAB Back", "Select", facePrev, faceNext);
|
||||
@@ -622,12 +628,12 @@ void DictionaryWordSelectActivity::drawHints() {
|
||||
|
||||
if (useCCW) {
|
||||
// Text reads top-to-bottom (90° CCW rotation): y starts near top of button
|
||||
renderer.drawTextRotated90CCW(SMALL_FONT_ID, sideX,
|
||||
sideButtonY[i] + (sideButtonHeight - tw) / 2, truncated.c_str());
|
||||
renderer.drawTextRotated90CCW(SMALL_FONT_ID, sideX, sideButtonY[i] + (sideButtonHeight - tw) / 2,
|
||||
truncated.c_str());
|
||||
} else {
|
||||
// Text reads bottom-to-top (90° CW rotation): y starts near bottom of button
|
||||
renderer.drawTextRotated90CW(SMALL_FONT_ID, sideX,
|
||||
sideButtonY[i] + (sideButtonHeight + tw) / 2, truncated.c_str());
|
||||
renderer.drawTextRotated90CW(SMALL_FONT_ID, sideX, sideButtonY[i] + (sideButtonHeight + tw) / 2,
|
||||
truncated.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -13,8 +13,7 @@ class DictionaryWordSelectActivity final : public ActivityWithSubactivity {
|
||||
explicit DictionaryWordSelectActivity(GfxRenderer& renderer, MappedInputManager& mappedInput,
|
||||
std::unique_ptr<Page> page, int fontId, int marginLeft, int marginTop,
|
||||
const std::string& cachePath, uint8_t orientation,
|
||||
const std::function<void()>& onBack,
|
||||
const std::string& nextPageFirstWord = "")
|
||||
const std::function<void()>& onBack, const std::string& nextPageFirstWord = "")
|
||||
: ActivityWithSubactivity("DictionaryWordSelect", renderer, mappedInput),
|
||||
page(std::move(page)),
|
||||
fontId(fontId),
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
#include <HalStorage.h>
|
||||
#include <I18n.h>
|
||||
#include <Logging.h>
|
||||
|
||||
#include <PlaceholderCoverGenerator.h>
|
||||
|
||||
#include "CrossPointSettings.h"
|
||||
@@ -242,8 +241,7 @@ void EpubReaderActivity::loop() {
|
||||
}
|
||||
|
||||
// Long press CONFIRM opens Table of Contents directly (skip menu)
|
||||
if (mappedInput.isPressed(MappedInputManager::Button::Confirm) &&
|
||||
mappedInput.getHeldTime() >= longPressConfirmMs) {
|
||||
if (mappedInput.isPressed(MappedInputManager::Button::Confirm) && mappedInput.getHeldTime() >= longPressConfirmMs) {
|
||||
ignoreNextConfirmRelease = true;
|
||||
if (epub && epub->getTocItemsCount() > 0) {
|
||||
openChapterSelection(true); // skip the stale release from this long-press
|
||||
@@ -266,8 +264,8 @@ void EpubReaderActivity::loop() {
|
||||
}
|
||||
const int bookProgressPercent = clampPercent(static_cast<int>(bookProgress + 0.5f));
|
||||
const bool hasDictionary = Dictionary::exists();
|
||||
const bool isBookmarked = BookmarkStore::hasBookmark(
|
||||
epub->getCachePath(), currentSpineIndex, section ? section->currentPage : 0);
|
||||
const bool isBookmarked =
|
||||
BookmarkStore::hasBookmark(epub->getCachePath(), currentSpineIndex, section ? section->currentPage : 0);
|
||||
exitActivity();
|
||||
enterNewActivity(new EpubReaderMenuActivity(
|
||||
this->renderer, this->mappedInput, epub->getTitle(), currentPage, totalPages, bookProgressPercent,
|
||||
@@ -935,13 +933,11 @@ void EpubReaderActivity::render(Activity::RenderLock&& lock) {
|
||||
|
||||
silentIndexingActive = false;
|
||||
const bool textOnlyPage = !p->hasImages();
|
||||
if (textOnlyPage &&
|
||||
SETTINGS.indexingDisplay != CrossPointSettings::INDEXING_DISPLAY::INDEXING_POPUP &&
|
||||
if (textOnlyPage && SETTINGS.indexingDisplay != CrossPointSettings::INDEXING_DISPLAY::INDEXING_POPUP &&
|
||||
section->pageCount >= 1 &&
|
||||
((section->pageCount == 1 && section->currentPage == 0) ||
|
||||
(section->pageCount >= 2 && section->currentPage == section->pageCount - 2)) &&
|
||||
currentSpineIndex + 1 < epub->getSpineItemsCount() &&
|
||||
preIndexedNextSpine != currentSpineIndex + 1) {
|
||||
currentSpineIndex + 1 < epub->getSpineItemsCount() && preIndexedNextSpine != currentSpineIndex + 1) {
|
||||
Section probe(epub, currentSpineIndex + 1, renderer);
|
||||
if (probe.loadSectionFile(SETTINGS.getReaderFontId(), SETTINGS.getReaderLineCompression(),
|
||||
SETTINGS.extraParagraphSpacing, SETTINGS.paragraphAlignment, viewportWidth,
|
||||
@@ -971,9 +967,8 @@ bool EpubReaderActivity::silentIndexNextChapterIfNeeded(const uint16_t viewportW
|
||||
return false;
|
||||
}
|
||||
|
||||
const bool shouldPreIndex =
|
||||
(section->pageCount == 1 && section->currentPage == 0) ||
|
||||
(section->pageCount >= 2 && section->currentPage == section->pageCount - 2);
|
||||
const bool shouldPreIndex = (section->pageCount == 1 && section->currentPage == 0) ||
|
||||
(section->pageCount >= 2 && section->currentPage == section->pageCount - 2);
|
||||
if (!epub || !section || !shouldPreIndex) {
|
||||
silentIndexingActive = false;
|
||||
return false;
|
||||
@@ -1065,8 +1060,8 @@ void EpubReaderActivity::renderContents(std::unique_ptr<Page> page, const int or
|
||||
if (page->getImageBoundingBox(imgX, imgY, imgW, imgH)) {
|
||||
int screenX = imgX + orientedMarginLeft;
|
||||
int screenY = imgY + orientedMarginTop;
|
||||
LOG_DBG("ERS", "Image page: fast double-refresh (page bbox: %d,%d %dx%d, screen: %d,%d %dx%d)",
|
||||
imgX, imgY, imgW, imgH, screenX, screenY, imgW, imgH);
|
||||
LOG_DBG("ERS", "Image page: fast double-refresh (page bbox: %d,%d %dx%d, screen: %d,%d %dx%d)", imgX, imgY, imgW,
|
||||
imgH, screenX, screenY, imgW, imgH);
|
||||
|
||||
#if USE_IMAGE_DOUBLE_FAST_REFRESH == 0
|
||||
// Method A: Fill blank area + two FAST_REFRESH operations
|
||||
@@ -1233,8 +1228,7 @@ void EpubReaderActivity::renderStatusBar(const int orientedMarginRight, const in
|
||||
if (SETTINGS.indexingDisplay == CrossPointSettings::INDEXING_DISPLAY::INDEXING_STATUS_TEXT) {
|
||||
renderer.drawText(SMALL_FONT_ID, indicatorX, textY, tr(STR_INDEXING));
|
||||
} else if (SETTINGS.indexingDisplay == CrossPointSettings::INDEXING_DISPLAY::INDEXING_STATUS_ICON) {
|
||||
renderer.drawIcon(kIndexingIcon, indicatorX, textY - kIndexingIconSize + 2, kIndexingIconSize,
|
||||
kIndexingIconSize);
|
||||
renderer.drawIcon(kIndexingIcon, indicatorX, textY - kIndexingIconSize + 2, kIndexingIconSize, kIndexingIconSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,13 +20,13 @@ class EpubReaderActivity final : public ActivityWithSubactivity {
|
||||
bool pendingPercentJump = false;
|
||||
// Normalized 0.0-1.0 progress within the target spine item, computed from book percentage.
|
||||
float pendingSpineProgress = 0.0f;
|
||||
bool pendingSubactivityExit = false; // Defer subactivity exit to avoid use-after-free
|
||||
bool pendingGoHome = false; // Defer go home to avoid race condition with display task
|
||||
bool skipNextButtonCheck = false; // Skip button processing for one frame after subactivity exit
|
||||
bool ignoreNextConfirmRelease = false; // Suppress short-press after long-press Confirm
|
||||
volatile bool loadingSection = false; // True during the entire !section block (read from main loop)
|
||||
bool silentIndexingActive = false; // True while silently pre-indexing the next chapter
|
||||
int preIndexedNextSpine = -1; // Spine index already pre-indexed (prevents re-render loop)
|
||||
bool pendingSubactivityExit = false; // Defer subactivity exit to avoid use-after-free
|
||||
bool pendingGoHome = false; // Defer go home to avoid race condition with display task
|
||||
bool skipNextButtonCheck = false; // Skip button processing for one frame after subactivity exit
|
||||
bool ignoreNextConfirmRelease = false; // Suppress short-press after long-press Confirm
|
||||
volatile bool loadingSection = false; // True during the entire !section block (read from main loop)
|
||||
bool silentIndexingActive = false; // True while silently pre-indexing the next chapter
|
||||
int preIndexedNextSpine = -1; // Spine index already pre-indexed (prevents re-render loop)
|
||||
const std::function<void()> onGoBack;
|
||||
const std::function<void()> onGoHome;
|
||||
|
||||
|
||||
@@ -47,9 +47,7 @@ void EpubReaderBookmarkSelectionActivity::onEnter() {
|
||||
requestUpdate();
|
||||
}
|
||||
|
||||
void EpubReaderBookmarkSelectionActivity::onExit() {
|
||||
ActivityWithSubactivity::onExit();
|
||||
}
|
||||
void EpubReaderBookmarkSelectionActivity::onExit() { ActivityWithSubactivity::onExit(); }
|
||||
|
||||
void EpubReaderBookmarkSelectionActivity::loop() {
|
||||
if (subActivity) {
|
||||
@@ -207,8 +205,8 @@ void EpubReaderBookmarkSelectionActivity::render(Activity::RenderLock&&) {
|
||||
if (!bookmarks.empty()) {
|
||||
const char* deleteHint = "Hold select to delete";
|
||||
const int hintWidth = renderer.getTextWidth(SMALL_FONT_ID, deleteHint);
|
||||
renderer.drawText(SMALL_FONT_ID, (renderer.getScreenWidth() - hintWidth) / 2,
|
||||
renderer.getScreenHeight() - 70, deleteHint);
|
||||
renderer.drawText(SMALL_FONT_ID, (renderer.getScreenWidth() - hintWidth) / 2, renderer.getScreenHeight() - 70,
|
||||
deleteHint);
|
||||
}
|
||||
|
||||
const auto labels = mappedInput.mapLabels("\xC2\xAB Back", "Select", "Up", "Down");
|
||||
|
||||
@@ -26,12 +26,10 @@ class EpubReaderBookmarkSelectionActivity final : public ActivityWithSubactivity
|
||||
static std::string getPageSuffix(const Bookmark& bookmark);
|
||||
|
||||
public:
|
||||
explicit EpubReaderBookmarkSelectionActivity(GfxRenderer& renderer, MappedInputManager& mappedInput,
|
||||
const std::shared_ptr<Epub>& epub,
|
||||
std::vector<Bookmark> bookmarks,
|
||||
const std::string& cachePath,
|
||||
const std::function<void()>& onGoBack,
|
||||
const std::function<void(int newSpineIndex, int newPage)>& onSelectBookmark)
|
||||
explicit EpubReaderBookmarkSelectionActivity(
|
||||
GfxRenderer& renderer, MappedInputManager& mappedInput, const std::shared_ptr<Epub>& epub,
|
||||
std::vector<Bookmark> bookmarks, const std::string& cachePath, const std::function<void()>& onGoBack,
|
||||
const std::function<void(int newSpineIndex, int newPage)>& onSelectBookmark)
|
||||
: ActivityWithSubactivity("EpubReaderBookmarkSelection", renderer, mappedInput),
|
||||
epub(epub),
|
||||
bookmarks(std::move(bookmarks)),
|
||||
|
||||
@@ -40,13 +40,13 @@ void EpubReaderMenuActivity::loop() {
|
||||
return;
|
||||
}
|
||||
buttonNavigator.onNext([this] {
|
||||
orientationSelectIndex = ButtonNavigator::nextIndex(orientationSelectIndex,
|
||||
static_cast<int>(orientationLabels.size()));
|
||||
orientationSelectIndex =
|
||||
ButtonNavigator::nextIndex(orientationSelectIndex, static_cast<int>(orientationLabels.size()));
|
||||
requestUpdate();
|
||||
});
|
||||
buttonNavigator.onPrevious([this] {
|
||||
orientationSelectIndex = ButtonNavigator::previousIndex(orientationSelectIndex,
|
||||
static_cast<int>(orientationLabels.size()));
|
||||
orientationSelectIndex =
|
||||
ButtonNavigator::previousIndex(orientationSelectIndex, static_cast<int>(orientationLabels.size()));
|
||||
requestUpdate();
|
||||
});
|
||||
return;
|
||||
@@ -92,8 +92,8 @@ void EpubReaderMenuActivity::loop() {
|
||||
// Toggle between the two preferred orientations.
|
||||
// If currently in a portrait-category orientation (Portrait/Inverted), switch to preferredLandscape.
|
||||
// If currently in a landscape-category orientation (CW/CCW), switch to preferredPortrait.
|
||||
const bool isCurrentlyPortrait = (pendingOrientation == CrossPointSettings::PORTRAIT ||
|
||||
pendingOrientation == CrossPointSettings::INVERTED);
|
||||
const bool isCurrentlyPortrait =
|
||||
(pendingOrientation == CrossPointSettings::PORTRAIT || pendingOrientation == CrossPointSettings::INVERTED);
|
||||
if (isCurrentlyPortrait) {
|
||||
pendingOrientation = SETTINGS.preferredLandscape;
|
||||
} else {
|
||||
|
||||
@@ -33,8 +33,7 @@ class EpubReaderMenuActivity final : public ActivityWithSubactivity {
|
||||
explicit EpubReaderMenuActivity(GfxRenderer& renderer, MappedInputManager& mappedInput, const std::string& title,
|
||||
const int currentPage, const int totalPages, const int bookProgressPercent,
|
||||
const uint8_t currentOrientation, const uint8_t currentFontSize,
|
||||
const bool hasDictionary, const bool isBookmarked,
|
||||
const std::string& bookCachePath,
|
||||
const bool hasDictionary, const bool isBookmarked, const std::string& bookCachePath,
|
||||
const std::function<void(uint8_t, uint8_t)>& onBack,
|
||||
const std::function<void(MenuAction)>& onAction)
|
||||
: ActivityWithSubactivity("EpubReaderMenu", renderer, mappedInput),
|
||||
@@ -74,14 +73,13 @@ class EpubReaderMenuActivity final : public ActivityWithSubactivity {
|
||||
uint8_t pendingFontSize = 0;
|
||||
const std::vector<StrId> orientationLabels = {StrId::STR_PORTRAIT, StrId::STR_LANDSCAPE_CW, StrId::STR_INVERTED,
|
||||
StrId::STR_LANDSCAPE_CCW};
|
||||
const std::vector<StrId> fontSizeLabels = {StrId::STR_SMALL, StrId::STR_MEDIUM, StrId::STR_LARGE,
|
||||
StrId::STR_X_LARGE};
|
||||
const std::vector<StrId> fontSizeLabels = {StrId::STR_SMALL, StrId::STR_MEDIUM, StrId::STR_LARGE, StrId::STR_X_LARGE};
|
||||
std::string bookCachePath;
|
||||
// Letterbox fill override: 0xFF = Default (use global), 0 = Dithered, 1 = Solid, 2 = None
|
||||
uint8_t pendingLetterboxFill = BookSettings::USE_GLOBAL;
|
||||
static constexpr int LETTERBOX_FILL_OPTION_COUNT = 4; // Default + 3 modes
|
||||
const std::vector<StrId> letterboxFillLabels = {StrId::STR_DEFAULT_OPTION, StrId::STR_DITHERED, StrId::STR_SOLID,
|
||||
StrId::STR_NONE_OPT};
|
||||
StrId::STR_NONE_OPT};
|
||||
int currentPage = 0;
|
||||
int totalPages = 0;
|
||||
int bookProgressPercent = 0;
|
||||
@@ -100,7 +98,7 @@ class EpubReaderMenuActivity final : public ActivityWithSubactivity {
|
||||
// Map the internal override value to an index into letterboxFillLabels.
|
||||
int letterboxFillToIndex() const {
|
||||
if (pendingLetterboxFill == BookSettings::USE_GLOBAL) return 0; // "Default"
|
||||
return pendingLetterboxFill + 1; // 0->1 (Dithered), 1->2 (Solid), 2->3 (None)
|
||||
return pendingLetterboxFill + 1; // 0->1 (Dithered), 1->2 (Solid), 2->3 (None)
|
||||
}
|
||||
|
||||
// Map an index from letterboxFillLabels back to an override value.
|
||||
@@ -137,5 +135,4 @@ class EpubReaderMenuActivity final : public ActivityWithSubactivity {
|
||||
items.push_back({MenuAction::DELETE_CACHE, StrId::STR_DELETE_CACHE});
|
||||
return items;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
@@ -23,9 +23,7 @@ void LookedUpWordsActivity::onEnter() {
|
||||
requestUpdate();
|
||||
}
|
||||
|
||||
void LookedUpWordsActivity::onExit() {
|
||||
ActivityWithSubactivity::onExit();
|
||||
}
|
||||
void LookedUpWordsActivity::onExit() { ActivityWithSubactivity::onExit(); }
|
||||
|
||||
void LookedUpWordsActivity::loop() {
|
||||
if (subActivity) {
|
||||
@@ -83,8 +81,8 @@ void LookedUpWordsActivity::loop() {
|
||||
|
||||
// Detect long press on Confirm to trigger delete (only for real word entries, not sentinel)
|
||||
constexpr unsigned long DELETE_HOLD_MS = 700;
|
||||
if (selectedIndex != deleteDictCacheIndex &&
|
||||
mappedInput.isPressed(MappedInputManager::Button::Confirm) && mappedInput.getHeldTime() >= DELETE_HOLD_MS) {
|
||||
if (selectedIndex != deleteDictCacheIndex && mappedInput.isPressed(MappedInputManager::Button::Confirm) &&
|
||||
mappedInput.getHeldTime() >= DELETE_HOLD_MS) {
|
||||
deleteConfirmMode = true;
|
||||
ignoreNextConfirmRelease = true;
|
||||
pendingDeleteIndex = selectedIndex;
|
||||
@@ -150,11 +148,10 @@ void LookedUpWordsActivity::loop() {
|
||||
Activity::RenderLock lock(*this);
|
||||
popupLayout = GUI.drawPopup(renderer, "Looking up...");
|
||||
}
|
||||
std::string definition = Dictionary::lookup(
|
||||
headword, [this, &popupLayout](int percent) {
|
||||
Activity::RenderLock lock(*this);
|
||||
GUI.fillPopupProgress(renderer, popupLayout, percent);
|
||||
});
|
||||
std::string definition = Dictionary::lookup(headword, [this, &popupLayout](int percent) {
|
||||
Activity::RenderLock lock(*this);
|
||||
GUI.fillPopupProgress(renderer, popupLayout, percent);
|
||||
});
|
||||
|
||||
if (!definition.empty()) {
|
||||
enterNewActivity(new DictionaryDefinitionActivity(
|
||||
@@ -169,8 +166,8 @@ void LookedUpWordsActivity::loop() {
|
||||
std::string stemDef = Dictionary::lookup(stem);
|
||||
if (!stemDef.empty()) {
|
||||
enterNewActivity(new DictionaryDefinitionActivity(
|
||||
renderer, mappedInput, stem, stemDef, readerFontId, orientation,
|
||||
[this]() { pendingBackFromDef = true; }, [this]() { pendingExitToReader = true; }));
|
||||
renderer, mappedInput, stem, stemDef, readerFontId, orientation, [this]() { pendingBackFromDef = true; },
|
||||
[this]() { pendingExitToReader = true; }));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,11 +3,10 @@
|
||||
#include <GfxRenderer.h>
|
||||
#include <HalStorage.h>
|
||||
#include <I18n.h>
|
||||
#include <PlaceholderCoverGenerator.h>
|
||||
#include <Serialization.h>
|
||||
#include <Utf8.h>
|
||||
|
||||
#include <PlaceholderCoverGenerator.h>
|
||||
|
||||
#include "CrossPointSettings.h"
|
||||
#include "CrossPointState.h"
|
||||
#include "MappedInputManager.h"
|
||||
@@ -85,7 +84,7 @@ void TxtReaderActivity::onEnter() {
|
||||
const int thumbHeight = PRERENDER_THUMB_HEIGHTS[i];
|
||||
const int thumbWidth = static_cast<int>(thumbHeight * 0.6);
|
||||
PlaceholderCoverGenerator::generate(txt->getThumbBmpPath(thumbHeight), txt->getTitle(), "", thumbWidth,
|
||||
thumbHeight);
|
||||
thumbHeight);
|
||||
updateProgress();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
#include <GfxRenderer.h>
|
||||
#include <HalStorage.h>
|
||||
#include <I18n.h>
|
||||
|
||||
#include <PlaceholderCoverGenerator.h>
|
||||
|
||||
#include "CrossPointSettings.h"
|
||||
@@ -73,7 +72,7 @@ void XtcReaderActivity::onEnter() {
|
||||
const int thumbHeight = PRERENDER_THUMB_HEIGHTS[i];
|
||||
const int thumbWidth = static_cast<int>(thumbHeight * 0.6);
|
||||
PlaceholderCoverGenerator::generate(xtc->getThumbBmpPath(thumbHeight), xtc->getTitle(), xtc->getAuthor(),
|
||||
thumbWidth, thumbHeight);
|
||||
thumbWidth, thumbHeight);
|
||||
}
|
||||
updateProgress();
|
||||
}
|
||||
|
||||
@@ -142,7 +142,6 @@ void CalibreSettingsActivity::render(Activity::RenderLock&&) {
|
||||
},
|
||||
true);
|
||||
|
||||
|
||||
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);
|
||||
|
||||
|
||||
@@ -168,7 +168,6 @@ void KOReaderSettingsActivity::render(Activity::RenderLock&&) {
|
||||
},
|
||||
true);
|
||||
|
||||
|
||||
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);
|
||||
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
|
||||
#include <GfxRenderer.h>
|
||||
#include <I18n.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <cstdio>
|
||||
#include <ctime>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include "CrossPointSettings.h"
|
||||
#include "MappedInputManager.h"
|
||||
@@ -106,8 +106,8 @@ void SetTimeActivity::render(Activity::RenderLock&&) {
|
||||
renderer.fillRoundedRect(startX - highlightPad, timeY - 4, digitWidth + highlightPad * 2, lineHeight12 + 8, 6,
|
||||
Color::LightGray);
|
||||
} else {
|
||||
renderer.fillRoundedRect(startX + digitWidth + colonWidth - highlightPad, timeY - 4,
|
||||
digitWidth + highlightPad * 2, lineHeight12 + 8, 6, Color::LightGray);
|
||||
renderer.fillRoundedRect(startX + digitWidth + colonWidth - highlightPad, timeY - 4, digitWidth + highlightPad * 2,
|
||||
lineHeight12 + 8, 6, Color::LightGray);
|
||||
}
|
||||
|
||||
// Draw the time digits and colon
|
||||
|
||||
@@ -6,8 +6,7 @@
|
||||
|
||||
class SetTimeActivity final : public Activity {
|
||||
public:
|
||||
explicit SetTimeActivity(GfxRenderer& renderer, MappedInputManager& mappedInput,
|
||||
const std::function<void()>& onBack)
|
||||
explicit SetTimeActivity(GfxRenderer& renderer, MappedInputManager& mappedInput, const std::function<void()>& onBack)
|
||||
: Activity("SetTime", renderer, mappedInput), onBack(onBack) {}
|
||||
|
||||
void onEnter() override;
|
||||
|
||||
Reference in New Issue
Block a user