2026-01-14 19:36:40 +09:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
|
|
#include <Txt.h>
|
|
|
|
|
#include <freertos/FreeRTOS.h>
|
|
|
|
|
#include <freertos/semphr.h>
|
|
|
|
|
#include <freertos/task.h>
|
|
|
|
|
|
|
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
|
|
#include "CrossPointSettings.h"
|
|
|
|
|
#include "activities/ActivityWithSubactivity.h"
|
|
|
|
|
|
|
|
|
|
class TxtReaderActivity final : public ActivityWithSubactivity {
|
|
|
|
|
std::unique_ptr<Txt> txt;
|
|
|
|
|
TaskHandle_t displayTaskHandle = nullptr;
|
|
|
|
|
SemaphoreHandle_t renderingMutex = nullptr;
|
|
|
|
|
int currentPage = 0;
|
|
|
|
|
int totalPages = 1;
|
|
|
|
|
int pagesUntilFullRefresh = 0;
|
|
|
|
|
bool updateRequired = false;
|
|
|
|
|
const std::function<void()> onGoBack;
|
|
|
|
|
const std::function<void()> onGoHome;
|
|
|
|
|
|
2026-01-22 15:45:07 -05:00
|
|
|
// End-of-book prompt state
|
|
|
|
|
bool showingEndOfBookPrompt = false;
|
|
|
|
|
int endOfBookSelection = 2; // 0=Archive, 1=Delete, 2=Keep
|
|
|
|
|
|
2026-01-14 19:36:40 +09:00
|
|
|
// Streaming text reader - stores file offsets for each page
|
|
|
|
|
std::vector<size_t> pageOffsets; // File offset for start of each page
|
|
|
|
|
std::vector<std::string> currentPageLines;
|
|
|
|
|
int linesPerPage = 0;
|
|
|
|
|
int viewportWidth = 0;
|
|
|
|
|
bool initialized = false;
|
|
|
|
|
|
|
|
|
|
// Cached settings for cache validation (different fonts/margins require re-indexing)
|
|
|
|
|
int cachedFontId = 0;
|
|
|
|
|
int cachedScreenMargin = 0;
|
|
|
|
|
uint8_t cachedParagraphAlignment = CrossPointSettings::LEFT_ALIGN;
|
|
|
|
|
|
|
|
|
|
static void taskTrampoline(void* param);
|
|
|
|
|
[[noreturn]] void displayTaskLoop();
|
|
|
|
|
void renderScreen();
|
|
|
|
|
void renderPage();
|
|
|
|
|
void renderStatusBar(int orientedMarginRight, int orientedMarginBottom, int orientedMarginLeft) const;
|
2026-01-22 15:45:07 -05:00
|
|
|
void renderEndOfBookPrompt();
|
|
|
|
|
void handleEndOfBookAction();
|
2026-01-14 19:36:40 +09:00
|
|
|
|
|
|
|
|
void initializeReader();
|
|
|
|
|
bool loadPageAtOffset(size_t offset, std::vector<std::string>& outLines, size_t& nextOffset);
|
|
|
|
|
void buildPageIndex();
|
|
|
|
|
bool loadPageIndexCache();
|
|
|
|
|
void savePageIndexCache() const;
|
|
|
|
|
void saveProgress() const;
|
|
|
|
|
void loadProgress();
|
2026-01-25 00:24:54 -05:00
|
|
|
int findPageForOffset(size_t targetOffset) const;
|
2026-01-14 19:36:40 +09:00
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
explicit TxtReaderActivity(GfxRenderer& renderer, MappedInputManager& mappedInput, std::unique_ptr<Txt> txt,
|
|
|
|
|
const std::function<void()>& onGoBack, const std::function<void()>& onGoHome)
|
|
|
|
|
: ActivityWithSubactivity("TxtReader", renderer, mappedInput),
|
|
|
|
|
txt(std::move(txt)),
|
|
|
|
|
onGoBack(onGoBack),
|
|
|
|
|
onGoHome(onGoHome) {}
|
|
|
|
|
void onEnter() override;
|
|
|
|
|
void onExit() override;
|
|
|
|
|
void loop() override;
|
|
|
|
|
};
|