diff --git a/lib/Epub/Epub.cpp b/lib/Epub/Epub.cpp index a59b32f..8b4bb9a 100644 --- a/lib/Epub/Epub.cpp +++ b/lib/Epub/Epub.cpp @@ -70,16 +70,18 @@ bool Epub::parseContentOpf(const std::string& contentOpfFilePath) { // Grab data from opfParser into epub title = opfParser.title; if (!opfParser.coverItemId.empty() && opfParser.items.count(opfParser.coverItemId) > 0) { - coverImageItem = opfParser.items.at(opfParser.coverItemId).href; + coverImageItem = opfParser.items.at(opfParser.coverItemId); } - if (!opfParser.tocNcxPath.empty()) { - tocNcxItem = opfParser.tocNcxPath; + if (opfParser.items.count("ncx")) { + tocNcxItem = opfParser.items.at("ncx"); + } else if (opfParser.items.count("ncxtoc")) { + tocNcxItem = opfParser.items.at("ncxtoc"); } for (auto& spineRef : opfParser.spineRefs) { if (opfParser.items.count(spineRef)) { - spine.emplace_back(spineRef, opfParser.items.at(spineRef).href); + spine.emplace_back(spineRef, opfParser.items.at(spineRef)); } } diff --git a/lib/Epub/Epub/parsers/ContentOpfParser.cpp b/lib/Epub/Epub/parsers/ContentOpfParser.cpp index d760bb8..667f679 100644 --- a/lib/Epub/Epub/parsers/ContentOpfParser.cpp +++ b/lib/Epub/Epub/parsers/ContentOpfParser.cpp @@ -110,24 +110,17 @@ void XMLCALL ContentOpfParser::startElement(void* userData, const XML_Char* name if (self->state == IN_MANIFEST && (strcmp(name, "item") == 0 || strcmp(name, "opf:item") == 0)) { std::string itemId; - ManifestItem item; + std::string href; for (int i = 0; atts[i]; i += 2) { if (strcmp(atts[i], "id") == 0) { itemId = atts[i + 1]; } else if (strcmp(atts[i], "href") == 0) { - item.href = self->baseContentPath + atts[i + 1]; - } else if (strcmp(atts[i], "media-type") == 0) { - item.mediaType = atts[i + 1]; + href = self->baseContentPath + atts[i + 1]; } } - if (!itemId.empty()) { - self->items[itemId] = item; - if (item.mediaType == "application/x-dtbncx+xml" && self->tocNcxPath.empty()) { - self->tocNcxPath = item.href; - } - } + self->items[itemId] = href; return; } diff --git a/lib/Epub/Epub/parsers/ContentOpfParser.h b/lib/Epub/Epub/parsers/ContentOpfParser.h index cb887ab..cba4551 100644 --- a/lib/Epub/Epub/parsers/ContentOpfParser.h +++ b/lib/Epub/Epub/parsers/ContentOpfParser.h @@ -2,8 +2,6 @@ #include #include -#include -#include #include "Epub.h" #include "expat.h" @@ -28,15 +26,10 @@ class ContentOpfParser final : public Print { static void endElement(void* userData, const XML_Char* name); public: - struct ManifestItem { - std::string href; - std::string mediaType; - }; - std::string title; std::string tocNcxPath; std::string coverItemId; - std::map items; + std::map items; std::vector spineRefs; explicit ContentOpfParser(const std::string& baseContentPath, const size_t xmlSize) diff --git a/src/screens/EpubReaderChapterSelectionScreen.cpp b/src/screens/EpubReaderChapterSelectionScreen.cpp index 99bff76..26688a4 100644 --- a/src/screens/EpubReaderChapterSelectionScreen.cpp +++ b/src/screens/EpubReaderChapterSelectionScreen.cpp @@ -13,41 +13,13 @@ void EpubReaderChapterSelectionScreen::taskTrampoline(void* param) { self->displayTaskLoop(); } -void EpubReaderChapterSelectionScreen::rebuildVisibleSpineIndices() { - visibleSpineIndices.clear(); - if (!epub) { - return; - } - - const int spineCount = epub->getSpineItemsCount(); - visibleSpineIndices.reserve(spineCount); - for (int i = 0; i < spineCount; i++) { - if (epub->getTocIndexForSpineIndex(i) != -1) { - visibleSpineIndices.push_back(i); - } - } -} - void EpubReaderChapterSelectionScreen::onEnter() { if (!epub) { return; } renderingMutex = xSemaphoreCreateMutex(); - rebuildVisibleSpineIndices(); - - selectorIndex = 0; - if (!visibleSpineIndices.empty()) { - for (size_t i = 0; i < visibleSpineIndices.size(); i++) { - if (visibleSpineIndices[i] == currentSpineIndex) { - selectorIndex = static_cast(i); - break; - } - } - if (selectorIndex >= static_cast(visibleSpineIndices.size())) { - selectorIndex = static_cast(visibleSpineIndices.size()) - 1; - } - } + selectorIndex = currentSpineIndex; // Trigger first update updateRequired = true; @@ -68,7 +40,6 @@ void EpubReaderChapterSelectionScreen::onExit() { } vSemaphoreDelete(renderingMutex); renderingMutex = nullptr; - visibleSpineIndices.clear(); } void EpubReaderChapterSelectionScreen::handleInput() { @@ -80,53 +51,22 @@ void EpubReaderChapterSelectionScreen::handleInput() { const bool skipPage = inputManager.getHeldTime() > SKIP_PAGE_MS; if (inputManager.wasPressed(InputManager::BTN_CONFIRM)) { - if (!visibleSpineIndices.empty()) { - if (selectorIndex >= static_cast(visibleSpineIndices.size())) { - selectorIndex = static_cast(visibleSpineIndices.size()) - 1; - } - onSelectSpineIndex(visibleSpineIndices[selectorIndex]); - } - return; - } - - if (inputManager.wasPressed(InputManager::BTN_BACK)) { + onSelectSpineIndex(selectorIndex); + } else if (inputManager.wasPressed(InputManager::BTN_BACK)) { onGoBack(); - return; - } - - const int chapterCount = static_cast(visibleSpineIndices.size()); - if (chapterCount == 0) { - return; - } - - if (selectorIndex >= chapterCount) { - selectorIndex = chapterCount - 1; - } - - if (prevReleased) { + } else if (prevReleased) { if (skipPage) { - const int totalPages = (chapterCount + PAGE_ITEMS - 1) / PAGE_ITEMS; - int currentPage = selectorIndex / PAGE_ITEMS; - currentPage = (currentPage + totalPages - 1) % totalPages; - selectorIndex = currentPage * PAGE_ITEMS; - if (selectorIndex >= chapterCount) { - selectorIndex = chapterCount - 1; - } + selectorIndex = + ((selectorIndex / PAGE_ITEMS - 1) * PAGE_ITEMS + epub->getSpineItemsCount()) % epub->getSpineItemsCount(); } else { - selectorIndex = (selectorIndex + chapterCount - 1) % chapterCount; + selectorIndex = (selectorIndex + epub->getSpineItemsCount() - 1) % epub->getSpineItemsCount(); } updateRequired = true; } else if (nextReleased) { if (skipPage) { - const int totalPages = (chapterCount + PAGE_ITEMS - 1) / PAGE_ITEMS; - int currentPage = selectorIndex / PAGE_ITEMS; - currentPage = (currentPage + 1) % totalPages; - selectorIndex = currentPage * PAGE_ITEMS; - if (selectorIndex >= chapterCount) { - selectorIndex = chapterCount - 1; - } + selectorIndex = ((selectorIndex / PAGE_ITEMS + 1) * PAGE_ITEMS) % epub->getSpineItemsCount(); } else { - selectorIndex = (selectorIndex + 1) % chapterCount; + selectorIndex = (selectorIndex + 1) % epub->getSpineItemsCount(); } updateRequired = true; } @@ -150,28 +90,17 @@ void EpubReaderChapterSelectionScreen::renderScreen() { const auto pageWidth = renderer.getScreenWidth(); renderer.drawCenteredText(READER_FONT_ID, 10, "Select Chapter", true, BOLD); - const int chapterCount = static_cast(visibleSpineIndices.size()); - if (chapterCount == 0) { - renderer.drawText(UI_FONT_ID, 20, 60, "No chapters available"); - renderer.displayBuffer(); - return; - } - - if (selectorIndex >= chapterCount) { - selectorIndex = chapterCount - 1; - } - const auto pageStartIndex = selectorIndex / PAGE_ITEMS * PAGE_ITEMS; renderer.fillRect(0, 60 + (selectorIndex % PAGE_ITEMS) * 30 + 2, pageWidth - 1, 30); - for (int i = pageStartIndex; i < chapterCount && i < pageStartIndex + PAGE_ITEMS; i++) { - const int spineIndex = visibleSpineIndices[i]; - const int tocIndex = epub->getTocIndexForSpineIndex(spineIndex); + for (int i = pageStartIndex; i < epub->getSpineItemsCount() && i < pageStartIndex + PAGE_ITEMS; i++) { + const int tocIndex = epub->getTocIndexForSpineIndex(i); if (tocIndex == -1) { - continue; // Filtered chapters should not reach here, but skip defensively. + renderer.drawText(UI_FONT_ID, 20, 60 + (i % PAGE_ITEMS) * 30, "Unnamed", i != selectorIndex); + } else { + auto item = epub->getTocItem(tocIndex); + renderer.drawText(UI_FONT_ID, 20 + (item.level - 1) * 15, 60 + (i % PAGE_ITEMS) * 30, item.title.c_str(), + i != selectorIndex); } - auto item = epub->getTocItem(tocIndex); - renderer.drawText(UI_FONT_ID, 20 + (item.level - 1) * 15, 60 + (i % PAGE_ITEMS) * 30, item.title.c_str(), - i != selectorIndex); } renderer.displayBuffer(); diff --git a/src/screens/EpubReaderChapterSelectionScreen.h b/src/screens/EpubReaderChapterSelectionScreen.h index 0ba41f0..8cac4cb 100644 --- a/src/screens/EpubReaderChapterSelectionScreen.h +++ b/src/screens/EpubReaderChapterSelectionScreen.h @@ -5,7 +5,6 @@ #include #include -#include #include "Screen.h" @@ -16,13 +15,11 @@ class EpubReaderChapterSelectionScreen final : public Screen { int currentSpineIndex = 0; int selectorIndex = 0; bool updateRequired = false; - std::vector visibleSpineIndices; const std::function onGoBack; const std::function onSelectSpineIndex; static void taskTrampoline(void* param); [[noreturn]] void displayTaskLoop(); - void rebuildVisibleSpineIndices(); void renderScreen(); public: