fix: placeholder cover text, indexing timing, TOC long-press, cache deletion UI

- Fix fp4 fixed-point misuse in PlaceholderCoverGenerator (advanceX is 12.4
  fixed-point, not pixels) causing only first letter of each word to render
- Remove duplicate silentIndexNextChapterIfNeeded() call from loop() that
  blocked UI before render, preventing the indexing indicator from showing
- Fix indexing icon Y position to align within the status bar
- Add ignoreNextConfirmRelease to EpubReaderChapterSelectionActivity so
  long-press confirm release doesn't immediately select the first TOC item
- Reload recent books after cache deletion in HomeActivity and clear stale
  ignoreNextConfirmRelease flag to fix "no open books" and double-press bugs

Made-with: Cursor
This commit is contained in:
cottongin
2026-03-07 22:58:13 -05:00
parent a5ca15df4f
commit 022f5197d7
5 changed files with 17 additions and 9 deletions

View File

@@ -1,6 +1,7 @@
#include "PlaceholderCoverGenerator.h"
#include <EpdFont.h>
#include <EpdFontData.h>
#include <HalStorage.h>
#include <Logging.h>
#include <Utf8.h>
@@ -170,7 +171,7 @@ class PixelBuffer {
}
}
return glyph->advanceX * scale;
return fp4::toPixel(glyph->advanceX) * scale;
}
/// Render a UTF-8 string at (x, y) where y is the top of the text line, with integer scaling.
@@ -232,7 +233,7 @@ int getCharAdvance(const EpdFontData* font, uint32_t cp) {
const EpdFont fontObj(font);
const EpdGlyph* glyph = fontObj.getGlyph(cp);
if (!glyph) return 0;
return glyph->advanceX;
return fp4::toPixel(glyph->advanceX);
}
/// Split a string into words (splitting on whitespace: space, newline, tab, CR).

View File

@@ -307,6 +307,7 @@ void HomeActivity::openManageMenu(const std::string& bookPath) {
startActivityForResult(
std::make_unique<BookManageMenuActivity>(renderer, mappedInput, capturedPath, isArchived, true),
[this, capturedPath](const ActivityResult& result) {
ignoreNextConfirmRelease = false;
if (result.isCancelled) {
requestUpdate();
return;
@@ -339,13 +340,13 @@ void HomeActivity::openManageMenu(const std::string& bookPath) {
GUI.drawPopup(renderer, success ? tr(STR_DONE) : tr(STR_ACTION_FAILED));
}
requestUpdateAndWait();
recentBooks.clear();
recentsLoaded = false;
recentsLoading = false;
coverRendered = false;
freeCoverBuffer();
selectorIndex = 0;
firstRenderDone = false;
loadRecentBooks(UITheme::getInstance().getMetrics().homeRecentBooksCount);
requestUpdate();
});
}

View File

@@ -381,8 +381,6 @@ void EpubReaderActivity::loop() {
} else {
pageTurn(true);
}
silentIndexNextChapterIfNeeded();
}
// Translate an absolute percent into a spine index plus a normalized position
@@ -454,8 +452,10 @@ void EpubReaderActivity::onReaderMenuConfirm(EpubReaderMenuActivity::MenuAction
case EpubReaderMenuActivity::MenuAction::SELECT_CHAPTER: {
const int spineIdx = currentSpineIndex;
const std::string path = epub->getPath();
const bool consumeRelease = ignoreNextConfirmRelease;
startActivityForResult(
std::make_unique<EpubReaderChapterSelectionActivity>(renderer, mappedInput, epub, path, spineIdx),
std::make_unique<EpubReaderChapterSelectionActivity>(renderer, mappedInput, epub, path, spineIdx,
consumeRelease),
[this](const ActivityResult& result) {
if (!result.isCancelled && currentSpineIndex != std::get<ChapterResult>(result.data).spineIndex) {
RenderLock lock(*this);
@@ -1203,7 +1203,7 @@ void EpubReaderActivity::renderStatusBar() const {
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 + 2, kIndexingIconSize, kIndexingIconSize);
}
}
}

View File

@@ -48,6 +48,10 @@ void EpubReaderChapterSelectionActivity::loop() {
const int totalItems = getTotalItems();
if (mappedInput.wasReleased(MappedInputManager::Button::Confirm)) {
if (ignoreNextConfirmRelease) {
ignoreNextConfirmRelease = false;
return;
}
const auto newSpineIndex = epub->getSpineIndexForTocIndex(selectorIndex);
if (newSpineIndex == -1) {
ActivityResult result;

View File

@@ -12,6 +12,7 @@ class EpubReaderChapterSelectionActivity final : public Activity {
ButtonNavigator buttonNavigator;
int currentSpineIndex = 0;
int selectorIndex = 0;
bool ignoreNextConfirmRelease = false;
// Number of items that fit on a page, derived from logical screen height.
// This adapts automatically when switching between portrait and landscape.
@@ -23,11 +24,12 @@ class EpubReaderChapterSelectionActivity final : public Activity {
public:
explicit EpubReaderChapterSelectionActivity(GfxRenderer& renderer, MappedInputManager& mappedInput,
const std::shared_ptr<Epub>& epub, const std::string& epubPath,
const int currentSpineIndex)
const int currentSpineIndex, bool consumeFirstRelease = false)
: Activity("EpubReaderChapterSelection", renderer, mappedInput),
epub(epub),
epubPath(epubPath),
currentSpineIndex(currentSpineIndex) {}
currentSpineIndex(currentSpineIndex),
ignoreNextConfirmRelease(consumeFirstRelease) {}
void onEnter() override;
void onExit() override;
void loop() override;