Skip to content

Commit a150f42

Browse files
committed
normal and cached SD card file pick
1 parent 533fd1d commit a150f42

File tree

3 files changed

+68
-14
lines changed

3 files changed

+68
-14
lines changed

examples/SDCard/SDCard/SDCard.ino

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ using namespace Menu;
2222
// and we also need to refer to `sdFolderMenu` inside the function
2323
result sdFolder(eventMask event, navNode& nav, prompt &item);
2424

25-
SDMenu sdFolderMenu("SD Card","/",sdFolder,enterEvent);
25+
// SDMenu sdFolderMenu("SD Card","/",sdFolder,enterEvent);
26+
CachedSDMenu<32> sdFolderMenu("SD Card","/",sdFolder,enterEvent);
2627

2728
//implementing the handler here after sdFolder is defined...
2829
result sdFolder(eventMask event, navNode& nav, prompt &item) {

library.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name=ArduinoMenu library
2-
version=4.17.2
2+
version=4.17.3
33
author=Rui Azevedo, [email protected]
44
maintainer=neu-rah, [email protected]
55
sentence=Generic menu/interactivity system

src/plugin/SDMenu.h

Lines changed: 65 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ class FSO {
3131
return dir;
3232
}
3333
//count entries on folder (files and dirs)
34-
idx_t count() {
34+
long count() {
3535
// Serial.print("count:");
3636
dir.rewindDirectory();
3737
int cnt=0;
@@ -49,7 +49,7 @@ class FSO {
4949
}
5050

5151
//get entry index by filename
52-
idx_t entryIdx(String name) {
52+
long entryIdx(String name) {
5353
dir.rewindDirectory();
5454
int cnt=0;
5555
while(true) {
@@ -69,7 +69,7 @@ class FSO {
6969
}
7070

7171
//get folder content entry by index
72-
String entry(idx_t idx) {
72+
String entry(long idx) {
7373
dir.rewindDirectory();
7474
idx_t cnt=0;
7575
while(true) {
@@ -90,6 +90,58 @@ class FSO {
9090

9191
};
9292

93+
template<typename SDC,idx_t maxSz>
94+
class CachedFSO:public FSO<SDC> {
95+
public:
96+
using Type=SDC;
97+
long cacheStart=0;
98+
String cache[maxSz];
99+
long size=0;//folder size (count of files and folders)
100+
CachedFSO(Type& sdc):FSO<SDC>(sdc) {}
101+
void refresh(long start=0) {
102+
if (start<0) start=0;
103+
// Serial.print("Refreshing from:");
104+
// Serial.println(start);
105+
cacheStart=start;
106+
FSO<SDC>::dir.rewindDirectory();
107+
size=0;
108+
while(true) {
109+
File file=FSO<SDC>::dir.openNextFile();
110+
if (!file) {
111+
file.close();
112+
break;
113+
}
114+
if (start<=size&&size<start+maxSz)
115+
cache[size-start]=String(file.name())+(file.isDirectory()?"/":"");
116+
file.close();
117+
size++;
118+
}
119+
}
120+
//open a folder
121+
bool goFolder(String folderName) {
122+
if (!FSO<SDC>::goFolder(folderName)) return false;
123+
refresh();
124+
return true;
125+
}
126+
long count() {return size;}
127+
128+
long entryIdx(String name) {
129+
idx_t sz=min(count(),(long)maxSz);
130+
for(int i=0;i<sz;i++)
131+
if (name==cache[i]) return i+cacheStart;
132+
long at=FSO<SDC>::entryIdx(name);
133+
//put cache around the missing item
134+
refresh(at-(maxSz>>1));
135+
return at;
136+
}
137+
String entry(long idx) {
138+
if (0>idx||idx>=size) return "";
139+
if (cacheStart<=idx&&idx<(cacheStart+maxSz)) return cache[idx-cacheStart];
140+
refresh(idx-(maxSz>>1));
141+
return entry(idx);
142+
}
143+
};
144+
93145
////////////////////////////////////////////////////////////////////////////
94146
#include <SD.h>
95147
// instead of allocating options for each file we will instead customize a menu
@@ -111,13 +163,7 @@ class SDMenuT:public menuNode,public FS {
111163
:menuNode(title,0,NULL,act,mask,
112164
wrapStyle,(systemStyles)(_menuData|_canNav))
113165
,FS(sd)
114-
// ,sdc(sd)
115-
// ,folderName(at)
116-
// ,dir(sdc.open(at))
117-
{
118-
// Serial.println("open dir, construction");
119-
// dir=sdc.open(at);
120-
}
166+
{}
121167

122168
void begin() {FS::goFolder(folderName);}
123169

@@ -180,13 +226,20 @@ class SDMenuT:public menuNode,public FS {
180226
return out.printRaw(folderName.c_str(),len);
181227
}
182228
//drawing options
183-
len-=out.printRaw(SDMenuT<FS>::entry(idx).c_str(),len);
229+
len-=out.printRaw(SDMenuT<FS>::entry(out.tops[root.level]+idx).c_str(),len);
184230
return len;
185231
}
186232
};
187233

188234
class SDMenu:public SDMenuT<FSO<decltype(SD)>> {
189235
public:
190236
SDMenu(constText* title,const char* at,Menu::action act=doNothing,Menu::eventMask mask=noEvent)
191-
:SDMenuT(SD,title,at,act,mask) {}
237+
:SDMenuT<FSO<decltype(SD)>>(SD,title,at,act,mask) {}
238+
};
239+
240+
template<idx_t cacheSize>
241+
class CachedSDMenu:public SDMenuT<CachedFSO<decltype(SD),cacheSize>> {
242+
public:
243+
CachedSDMenu(constText* title,const char* at,Menu::action act=doNothing,Menu::eventMask mask=noEvent)
244+
:SDMenuT<CachedFSO<decltype(SD),cacheSize>>(SD,title,at,act,mask) {}
192245
};

0 commit comments

Comments
 (0)