Add directory picking to home screen

This commit is contained in:
Dave Allie 2025-12-05 22:12:28 +11:00
parent 72aa7ba3f6
commit 2631613b8d
No known key found for this signature in database
GPG Key ID: F2FDDB3AD8D0276F
2 changed files with 44 additions and 19 deletions

View File

@ -8,26 +8,30 @@ void FileSelectionScreen::taskTrampoline(void* param) {
self->displayTaskLoop();
}
void FileSelectionScreen::onEnter() {
void FileSelectionScreen::loadFiles() {
files.clear();
auto root = SD.open("/");
File file;
while ((file = root.openNextFile())) {
if (file.isDirectory()) {
file.close();
continue;
}
selectorIndex = 0;
auto root = SD.open(basepath.c_str());
for (File file = root.openNextFile(); file; file = root.openNextFile()) {
auto filename = std::string(file.name());
if (filename.substr(filename.length() - 5) != ".epub" || filename[0] == '.') {
if (filename[0] == '.') {
file.close();
continue;
}
if (file.isDirectory()) {
files.emplace_back(filename + "/");
} else if (filename.substr(filename.length() - 5) == ".epub") {
files.emplace_back(filename);
}
file.close();
}
root.close();
}
void FileSelectionScreen::onEnter() {
basepath = "/";
loadFiles();
// Trigger first update
updateRequired = true;
@ -53,8 +57,23 @@ void FileSelectionScreen::handleInput(const Input input) {
selectorIndex = (selectorIndex + files.size() - 1) % files.size();
updateRequired = true;
} else if (input.button == CONFIRM) {
Serial.printf("Selected file: %s\n", files[selectorIndex].c_str());
onSelect("/" + files[selectorIndex]);
if (files.empty()) {
return;
}
if (files[selectorIndex].back() == '/') {
if (basepath.back() != '/') basepath += "/";
basepath += files[selectorIndex].substr(0, files[selectorIndex].length() - 1);
loadFiles();
updateRequired = true;
} else {
onSelect(basepath + files[selectorIndex]);
}
} else if (input.button == BACK && basepath != "/") {
basepath = basepath.substr(0, basepath.rfind('/'));
if (basepath.empty()) basepath = "/";
loadFiles();
updateRequired = true;
}
}
@ -75,6 +94,9 @@ void FileSelectionScreen::render() const {
const auto titleWidth = renderer->getTextWidth("CrossPoint Reader", true);
renderer->drawText((pageWidth - titleWidth) / 2, 0, "CrossPoint Reader", true);
if (files.empty()) {
renderer->drawSmallText(50, 50, "No EPUBs found");
} else {
// Draw selection
renderer->fillRect(0, 50 + selectorIndex * 20 + 2, pageWidth - 1, 20, 1);
@ -82,6 +104,7 @@ void FileSelectionScreen::render() const {
const auto file = files[i];
renderer->drawSmallText(50, 50 + i * 20, file.c_str(), i == selectorIndex ? 0 : 1);
}
}
renderer->flushDisplay();
}

View File

@ -10,6 +10,7 @@
class FileSelectionScreen final : public Screen {
TaskHandle_t displayTaskHandle = nullptr;
std::string basepath = "/";
std::vector<std::string> files;
int selectorIndex = 0;
bool updateRequired = false;
@ -18,8 +19,9 @@ class FileSelectionScreen final : public Screen {
static void taskTrampoline(void* param);
[[noreturn]] void displayTaskLoop();
void render() const;
void loadFiles();
public:
public:
explicit FileSelectionScreen(EpdRenderer* renderer, const std::function<void(const std::string&)>& onSelect)
: Screen(renderer), onSelect(onSelect) {}
void onEnter() override;