Replace bookmark stubs with full add/remove/navigate implementation: - BookmarkStore: per-book binary persistence on SD card with v2 format supporting text snippets (backward-compatible with v1) - Visual bookmark ribbon indicator drawn on bookmarked pages via fillPolygon - Reader menu dynamically shows Add/Remove Bookmark based on current page state - Bookmark selection activity with chapter name, first sentence snippet, and page number display; long-press to delete with confirmation - Go to Bookmark falls back to Table of Contents when no bookmarks exist - Smart snippet extraction: skips partial sentences (lowercase first word) to capture the first full sentence on the page - Label truncation reserves space for page suffix so it's never cut off - Half refresh forced on menu exit to clear popup/menu artifacts Co-authored-by: Cursor <cursoragent@cursor.com>
61 lines
2.2 KiB
C++
61 lines
2.2 KiB
C++
#pragma once
|
|
#include <Epub.h>
|
|
#include <freertos/FreeRTOS.h>
|
|
#include <freertos/semphr.h>
|
|
#include <freertos/task.h>
|
|
|
|
#include <memory>
|
|
#include <vector>
|
|
|
|
#include "../ActivityWithSubactivity.h"
|
|
#include "util/BookmarkStore.h"
|
|
#include "util/ButtonNavigator.h"
|
|
|
|
class EpubReaderBookmarkSelectionActivity final : public ActivityWithSubactivity {
|
|
std::shared_ptr<Epub> epub;
|
|
std::vector<Bookmark> bookmarks;
|
|
std::string cachePath;
|
|
TaskHandle_t displayTaskHandle = nullptr;
|
|
SemaphoreHandle_t renderingMutex = nullptr;
|
|
ButtonNavigator buttonNavigator;
|
|
int selectorIndex = 0;
|
|
bool updateRequired = false;
|
|
bool deleteConfirmMode = false;
|
|
bool ignoreNextConfirmRelease = false;
|
|
int pendingDeleteIndex = 0;
|
|
const std::function<void()> onGoBack;
|
|
const std::function<void(int newSpineIndex, int newPage)> onSelectBookmark;
|
|
|
|
// Number of items that fit on a page, derived from logical screen height.
|
|
int getPageItems() const;
|
|
|
|
int getTotalItems() const;
|
|
|
|
// Build the prefix portion of a bookmark label (chapter + snippet, without page suffix)
|
|
std::string getBookmarkPrefix(const Bookmark& bookmark) const;
|
|
|
|
// Build the page suffix (e.g. " - Page 5")
|
|
static std::string getPageSuffix(const Bookmark& bookmark);
|
|
|
|
static void taskTrampoline(void* param);
|
|
[[noreturn]] void displayTaskLoop();
|
|
void renderScreen();
|
|
|
|
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)
|
|
: ActivityWithSubactivity("EpubReaderBookmarkSelection", renderer, mappedInput),
|
|
epub(epub),
|
|
bookmarks(std::move(bookmarks)),
|
|
cachePath(cachePath),
|
|
onGoBack(onGoBack),
|
|
onSelectBookmark(onSelectBookmark) {}
|
|
void onEnter() override;
|
|
void onExit() override;
|
|
void loop() override;
|
|
};
|