summaryrefslogtreecommitdiff
path: root/apps/tree.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/tree.c')
-rw-r--r--apps/tree.c311
1 files changed, 311 insertions, 0 deletions
diff --git a/apps/tree.c b/apps/tree.c
new file mode 100644
index 0000000000..6f1258392f
--- /dev/null
+++ b/apps/tree.c
@@ -0,0 +1,311 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 Daniel Stenberg
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19
20#include <string.h>
21#include <stdlib.h>
22#include <stdbool.h>
23
24#include "dir.h"
25#include "file.h"
26#include "lcd.h"
27#include "button.h"
28#include "kernel.h"
29#include "tree.h"
30//#include "play.h"
31
32#ifdef HAVE_LCD_BITMAP
33#include "icons.h"
34#endif
35
36#define TREE_MAX_FILENAMELEN 128
37#define MAX_DIR_LEVELS 10
38
39struct entry {
40 bool file; /* true if file, false if dir */
41 char name[TREE_MAX_FILENAMELEN];
42 int namelen;
43};
44
45void browse_root(void)
46{
47 dirbrowse("/");
48}
49
50
51#ifdef HAVE_LCD_BITMAP
52
53#define TREE_MAX_ON_SCREEN 7
54#define TREE_MAX_LEN_DISPLAY 16 /* max length that fits on screen */
55
56#define MARGIN_Y 8 /* Y pixel margin */
57#define MARGIN_X 12 /* X pixel margin */
58#define LINE_Y 0 /* Y position the entry-list starts at */
59#define LINE_X 2 /* X position the entry-list starts at */
60#define LINE_HEIGTH 8 /* pixels for each text line */
61
62extern unsigned char bitmap_icons_6x8[LastIcon][6];
63extern icons_6x8;
64
65#else /* HAVE_LCD_BITMAP */
66
67#define TREE_MAX_ON_SCREEN 2
68#define TREE_MAX_LEN_DISPLAY 11 /* max length that fits on screen */
69#define LINE_Y 0 /* Y position the entry-list starts at */
70#define LINE_X 1 /* X position the entry-list starts at */
71
72#endif /* HAVE_LCD_BITMAP */
73
74static int showdir(char *path, struct entry *buffer, int start,
75 int scrollpos, int* at_end)
76{
77#ifdef HAVE_LCD_BITMAP
78 int icon_type = 0;
79#endif
80 int i;
81 int j=0;
82 DIR *dir = opendir(path);
83 struct dirent *entry;
84
85 if(!dir)
86 return -1; /* not a directory */
87
88 i=start;
89 *at_end=0; /* Have we displayed the last directory entry? */
90 while((entry = readdir(dir))) {
91 int len;
92
93 if(entry->d_name[0] == '.')
94 /* skip names starting with a dot */
95 continue;
96
97 if(j++ < scrollpos)
98 continue ;
99
100 len = strlen(entry->d_name);
101 if(len < TREE_MAX_FILENAMELEN)
102 /* strncpy() is evil, we memcpy() instead, +1 includes the
103 trailing zero */
104 memcpy(buffer[i].name, entry->d_name, len+1);
105 else
106 memcpy(buffer[i].name, "too long", 9);
107
108 buffer[i].file = !(entry->attribute&ATTR_DIRECTORY);
109
110#ifdef HAVE_LCD_BITMAP
111 if ( buffer[i].file )
112 icon_type=File;
113 else
114 icon_type=Folder;
115 lcd_bitmap(bitmap_icons_6x8[icon_type], 6, MARGIN_Y+i*LINE_HEIGTH, 6,
116 8, true);
117#endif
118
119 if(len < TREE_MAX_LEN_DISPLAY)
120 lcd_puts(LINE_X, LINE_Y+i, buffer[i].name);
121 else {
122 char storage = buffer[i].name[TREE_MAX_LEN_DISPLAY];
123 buffer[i].name[TREE_MAX_LEN_DISPLAY]=0;
124 lcd_puts(LINE_X, LINE_Y+i, buffer[i].name);
125 buffer[i].name[TREE_MAX_LEN_DISPLAY]=storage;
126 }
127
128 if(++i >= TREE_MAX_ON_SCREEN)
129 break;
130 }
131
132 if (entry==0) {
133 *at_end=1;
134 } else {
135 *at_end=(readdir(dir)==0);
136 }
137 j = i ;
138 while (j++ < TREE_MAX_ON_SCREEN) {
139 lcd_puts(LINE_X, LINE_Y+j," ");
140 }
141 closedir(dir);
142
143 return i;
144}
145
146bool dirbrowse(char *root)
147{
148 struct entry buffer[TREE_MAX_ON_SCREEN];
149 int numentries;
150 char buf[255];
151 char currdir[255];
152 int dircursor=0;
153 int i;
154 int start=0;
155 int at_end=0;
156 int dirpos[MAX_DIR_LEVELS];
157 int dirlevel=0;
158
159 lcd_clear_display();
160
161#ifdef HAVE_LCD_BITMAP
162 lcd_putsxy(0,0, "[Browse]",0);
163 lcd_setmargins(0,MARGIN_Y);
164 lcd_setfont(0);
165#endif
166 memcpy(currdir,root,sizeof(currdir));
167
168 numentries = showdir(root, buffer, 0, start, &at_end);
169
170 if (numentries == -1)
171 return -1; /* root is not a directory */
172
173 lcd_puts(0, dircursor, "-");
174#ifdef HAVE_LCD_BITMAP
175 lcd_update();
176#endif
177
178 while(1) {
179 int key = button_get();
180
181 if(!key) {
182 sleep(1);
183 continue;
184 }
185 switch(key) {
186#ifdef HAVE_RECORDER_KEYPAD
187 case BUTTON_OFF:
188 return false;
189 break;
190#endif
191 case BUTTON_LEFT:
192 i=strlen(currdir);
193 if (i==1) {
194 return false;
195 }
196 else {
197 while (currdir[i-1]!='/')
198 i--;
199 strcpy(buf,&currdir[i]);
200 if (i==1)
201 currdir[i]=0;
202 else
203 currdir[i-1]=0;
204
205 lcd_clear_display();
206#ifdef HAVE_LCD_BITMAP
207 lcd_putsxy(0,0, "[Browse]",0);
208#endif
209 dirlevel--;
210 if ( dirlevel < MAX_DIR_LEVELS )
211 start = dirpos[dirlevel];
212 else
213 start = 0;
214 numentries = showdir(currdir, buffer, 0, start, &at_end);
215 dircursor=0;
216 while ( (dircursor < TREE_MAX_ON_SCREEN) &&
217 (strcmp(buffer[dircursor].name,buf)!=0))
218 dircursor++;
219 if (dircursor==TREE_MAX_ON_SCREEN)
220 dircursor=0;
221 lcd_puts(0, LINE_Y+dircursor, "-");
222#ifdef HAVE_LCD_BITMAP
223 lcd_update();
224#endif
225 }
226
227 break;
228
229 case BUTTON_RIGHT:
230#ifdef HAVE_RECORDER_KEYPAD
231 case BUTTON_PLAY:
232#endif
233 if ((currdir[0]=='/') && (currdir[1]==0)) {
234 sprintf(buf,"%s%s",currdir,buffer[dircursor].name);
235 } else {
236 sprintf(buf,"%s/%s",currdir,buffer[dircursor].name);
237 }
238
239 if (!buffer[dircursor].file) {
240 memcpy(currdir,buf,sizeof(currdir));
241 if ( dirlevel < MAX_DIR_LEVELS )
242 dirpos[dirlevel] = start+dircursor;
243 dirlevel++;
244 dircursor=0;
245 start=0;
246 } else {
247 playtune(currdir, buffer[dircursor].name);
248#ifdef HAVE_LCD_BITMAP
249 lcd_setmargins(0, MARGIN_Y);
250 lcd_setfont(0);
251#endif
252 }
253
254 lcd_clear_display();
255 numentries = showdir(currdir, buffer, 0, start, &at_end);
256 lcd_puts(0, LINE_Y+dircursor, "-");
257#ifdef HAVE_LCD_BITMAP
258 lcd_putsxy(0,0, "[Browse]",0);
259 lcd_update();
260#endif
261 break;
262
263 case BUTTON_UP:
264 if(dircursor) {
265 lcd_puts(0, LINE_Y+dircursor, " ");
266 dircursor--;
267 lcd_puts(0, LINE_Y+dircursor, "-");
268 lcd_update();
269 }
270 else {
271 if (start) {
272 lcd_clear_display();
273 start--;
274 numentries = showdir(currdir, buffer, 0,
275 start, &at_end);
276 lcd_puts(0, LINE_Y+dircursor, "-");
277#ifdef HAVE_LCD_BITMAP
278 lcd_putsxy(0,0, "[Browse]",0);
279 lcd_update();
280#endif
281 }
282 }
283 break;
284 case BUTTON_DOWN:
285 if(dircursor+1 < numentries) {
286 lcd_puts(0, LINE_Y+dircursor, " ");
287 dircursor++;
288 lcd_puts(0, LINE_Y+dircursor, "-");
289#ifdef HAVE_LCD_BITMAP
290 lcd_update();
291#endif
292 } else
293 {
294 if (!at_end) {
295 lcd_clear_display();
296 start++;
297 numentries = showdir(currdir, buffer, 0,
298 start, &at_end);
299 lcd_puts(0, LINE_Y+dircursor, "-");
300#ifdef HAVE_LCD_BITMAP
301 lcd_putsxy(0,0, "[Browse]",0);
302 lcd_update();
303#endif
304 }
305 }
306 break;
307 }
308 }
309
310 return false;
311}