A fork of https://github.com/crosspoint-reader/crosspoint-reader
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Add directory picking to home screen

+44 -19
+41 -18
src/screens/FileSelectionScreen.cpp
··· 8 8 self->displayTaskLoop(); 9 9 } 10 10 11 - void FileSelectionScreen::onEnter() { 11 + void FileSelectionScreen::loadFiles() { 12 12 files.clear(); 13 - auto root = SD.open("/"); 14 - File file; 15 - while ((file = root.openNextFile())) { 16 - if (file.isDirectory()) { 17 - file.close(); 18 - continue; 19 - } 20 - 13 + selectorIndex = 0; 14 + auto root = SD.open(basepath.c_str()); 15 + for (File file = root.openNextFile(); file; file = root.openNextFile()) { 21 16 auto filename = std::string(file.name()); 22 - if (filename.substr(filename.length() - 5) != ".epub" || filename[0] == '.') { 17 + if (filename[0] == '.') { 23 18 file.close(); 24 19 continue; 25 20 } 26 21 27 - files.emplace_back(filename); 22 + if (file.isDirectory()) { 23 + files.emplace_back(filename + "/"); 24 + } else if (filename.substr(filename.length() - 5) == ".epub") { 25 + files.emplace_back(filename); 26 + } 28 27 file.close(); 29 28 } 30 29 root.close(); 30 + } 31 + 32 + void FileSelectionScreen::onEnter() { 33 + basepath = "/"; 34 + loadFiles(); 31 35 32 36 // Trigger first update 33 37 updateRequired = true; ··· 53 57 selectorIndex = (selectorIndex + files.size() - 1) % files.size(); 54 58 updateRequired = true; 55 59 } else if (input.button == CONFIRM) { 56 - Serial.printf("Selected file: %s\n", files[selectorIndex].c_str()); 57 - onSelect("/" + files[selectorIndex]); 60 + if (files.empty()) { 61 + return; 62 + } 63 + 64 + if (files[selectorIndex].back() == '/') { 65 + if (basepath.back() != '/') basepath += "/"; 66 + basepath += files[selectorIndex].substr(0, files[selectorIndex].length() - 1); 67 + loadFiles(); 68 + updateRequired = true; 69 + } else { 70 + onSelect(basepath + files[selectorIndex]); 71 + } 72 + } else if (input.button == BACK && basepath != "/") { 73 + basepath = basepath.substr(0, basepath.rfind('/')); 74 + if (basepath.empty()) basepath = "/"; 75 + loadFiles(); 76 + updateRequired = true; 58 77 } 59 78 } 60 79 ··· 75 94 const auto titleWidth = renderer->getTextWidth("CrossPoint Reader", true); 76 95 renderer->drawText((pageWidth - titleWidth) / 2, 0, "CrossPoint Reader", true); 77 96 78 - // Draw selection 79 - renderer->fillRect(0, 50 + selectorIndex * 20 + 2, pageWidth - 1, 20, 1); 97 + if (files.empty()) { 98 + renderer->drawSmallText(50, 50, "No EPUBs found"); 99 + } else { 100 + // Draw selection 101 + renderer->fillRect(0, 50 + selectorIndex * 20 + 2, pageWidth - 1, 20, 1); 80 102 81 - for (size_t i = 0; i < files.size(); i++) { 82 - const auto file = files[i]; 83 - renderer->drawSmallText(50, 50 + i * 20, file.c_str(), i == selectorIndex ? 0 : 1); 103 + for (size_t i = 0; i < files.size(); i++) { 104 + const auto file = files[i]; 105 + renderer->drawSmallText(50, 50 + i * 20, file.c_str(), i == selectorIndex ? 0 : 1); 106 + } 84 107 } 85 108 86 109 renderer->flushDisplay();
+3 -1
src/screens/FileSelectionScreen.h
··· 10 10 11 11 class FileSelectionScreen final : public Screen { 12 12 TaskHandle_t displayTaskHandle = nullptr; 13 + std::string basepath = "/"; 13 14 std::vector<std::string> files; 14 15 int selectorIndex = 0; 15 16 bool updateRequired = false; ··· 18 19 static void taskTrampoline(void* param); 19 20 [[noreturn]] void displayTaskLoop(); 20 21 void render() const; 22 + void loadFiles(); 21 23 22 - public: 24 + public: 23 25 explicit FileSelectionScreen(EpdRenderer* renderer, const std::function<void(const std::string&)>& onSelect) 24 26 : Screen(renderer), onSelect(onSelect) {} 25 27 void onEnter() override;