blob: 62b4f25519eaa59089aa8fd3a86c73c1e3c55e05 [file] [log] [blame]
adamdunkelsf431abe2004-08-09 20:07:18 +00001/*
2 * Copyright (c) 2003, Adam Dunkels.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following
12 * disclaimer in the documentation and/or other materials provided
13 * with the distribution.
14 * 3. The name of the author may not be used to endorse or promote
15 * products derived from this software without specific prior
16 * written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
19 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
22 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
24 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 *
30 * This file is part of the Contiki desktop environment
31 *
oliverschmidta438e9d2006-05-24 19:34:39 +000032 * $Id: directory.c,v 1.3 2006/05/24 19:34:39 oliverschmidt Exp $
adamdunkelsf431abe2004-08-09 20:07:18 +000033 *
34 */
35
36#include <stdlib.h>
adamdunkelsf431abe2004-08-09 20:07:18 +000037#include <string.h>
38
39#include "ctk.h"
40#include "ctk-draw.h"
41#include "ek.h"
42#include "loader.h"
43
44#include "cfs.h"
45
46#include "program-handler.h"
47
48#define FILENAMELEN 24
49#define MAX_NUMFILES 40
50#define WIDTH 36
51#define HEIGHT 22
52
53static char (filenames[FILENAMELEN + 1])[MAX_NUMFILES];
54static struct dsc *dscs[MAX_NUMFILES];
55static unsigned char numfiles, morestart, filenameptr;
56
57static struct ctk_window window;
58
59static struct ctk_label description =
60 {CTK_LABEL(0, HEIGHT - 1, WIDTH, 1, "")};
61
62static char autoexit = 1;
63static struct ctk_button autoexitbutton =
64 {CTK_BUTTON(WIDTH/2 - 9, 20, 9, "Auto-exit")};
65static char autoexiton[] = "is On ";
66static char autoexitoff[] = "is Off";
67static struct ctk_label autoexitlabel =
68 {CTK_LABEL(WIDTH/2 - 9 + 12, 20, 6, 1, autoexiton)};
69
70static struct ctk_button morebutton =
71 {CTK_BUTTON(0, 20, 4, "More")};
72
73static struct ctk_button backbutton =
74 {CTK_BUTTON(0, 20, 4, "Back")};
75
76static struct ctk_button reloadbutton =
77 {CTK_BUTTON(30, 20, 6, "Reload")};
78
79EK_EVENTHANDLER(directory_eventhandler, ev, data);
80EK_PROCESS(p, "Directory browser", EK_PRIO_NORMAL,
81 directory_eventhandler, NULL, NULL);
82static ek_id_t id = EK_ID_NONE;
83
84static unsigned char width, height;
85
86#define LOADING_DIR 1
87#define LOADING_DSC 2
88static char loading = 0;
89static struct cfs_dir dir;
90/*-----------------------------------------------------------------------------------*/
91static void
92show_statustext(char *text)
93{
94 ctk_label_set_text(&description, text);
95 CTK_WIDGET_REDRAW(&description);
96}
97/*-----------------------------------------------------------------------------------*/
98static void
99startloading(void)
100{
101 if(cfs_opendir(&dir, "/") != 0) {
102 show_statustext("Cannot open directory");
103 loading = 0;
104 } else {
oliverschmidta438e9d2006-05-24 19:34:39 +0000105 loading = LOADING_DIR;
adamdunkelsf431abe2004-08-09 20:07:18 +0000106 ek_post(id, EK_EVENT_CONTINUE, NULL);
107 numfiles = 0;
108 }
109}
110/*-----------------------------------------------------------------------------------*/
111static void
112makewindow(unsigned char i)
113{
114 unsigned char x, y;
115
116 ctk_window_clear(&window);
117 CTK_WIDGET_SET_YPOS(&description, height - 3);
118 CTK_WIDGET_SET_WIDTH(&description, width);
119 CTK_WIDGET_ADD(&window, &description);
120
121 morestart = i;
122
123 x = 0; y = 1;
124 for(; dscs[i] != NULL; ++i) {
125
126 if(x + strlen(dscs[i]->icon->title) >= width) {
127 y += 5;
128 x = 0;
129 if(y >= height - 2 - 4) {
130 morestart = i;
131 break;
132 }
133 }
134 CTK_WIDGET_SET_XPOS(dscs[i]->icon, x);
135 CTK_WIDGET_SET_YPOS(dscs[i]->icon, y);
136 CTK_WIDGET_ADD(&window, dscs[i]->icon);
137
oliverschmidt5e7c4b62005-05-06 22:33:05 +0000138 x += strlen(dscs[i]->icon->title) + 2;
adamdunkelsf431abe2004-08-09 20:07:18 +0000139 }
140 CTK_WIDGET_SET_YPOS(&autoexitbutton, height - 2);
141 CTK_WIDGET_ADD(&window, &autoexitbutton);
142 CTK_WIDGET_SET_YPOS(&autoexitlabel, height - 2);
143 CTK_WIDGET_ADD(&window, &autoexitlabel);
oliverschmidt5e7c4b62005-05-06 22:33:05 +0000144 CTK_WIDGET_FOCUS(&window, &autoexitbutton);
adamdunkelsf431abe2004-08-09 20:07:18 +0000145
146 if(i != morestart) {
147 CTK_WIDGET_SET_YPOS(&backbutton, height - 1);
148 CTK_WIDGET_ADD(&window, &backbutton);
149 } else {
150 CTK_WIDGET_SET_YPOS(&morebutton, height - 1);
151 CTK_WIDGET_ADD(&window, &morebutton);
152 }
153 CTK_WIDGET_SET_XPOS(&reloadbutton, width - 8);
154 CTK_WIDGET_SET_YPOS(&reloadbutton, height - 1);
155 CTK_WIDGET_ADD(&window, &reloadbutton);
156}
157/*-----------------------------------------------------------------------------------*/
158LOADER_INIT_FUNC(directory_init, arg)
159{
160 arg_free(arg);
161
162 if(id == EK_ID_NONE) {
163 id = ek_start(&p);
164
oliverschmidt5e7c4b62005-05-06 22:33:05 +0000165 width = ctk_draw_width() - 2;
166 height = ctk_draw_height() - 3;
adamdunkelsf431abe2004-08-09 20:07:18 +0000167 }
168}
169/*-----------------------------------------------------------------------------------*/
170static void
171quit(void)
172{
173 unsigned char i;
174
oliverschmidta438e9d2006-05-24 19:34:39 +0000175 if(loading == LOADING_DIR) {
176 cfs_closedir(&dir);
177 }
adamdunkelsf431abe2004-08-09 20:07:18 +0000178 ctk_window_close(&window);
179 for(i = 0; dscs[i] != NULL; ++i) {
180 LOADER_UNLOAD_DSC(dscs[i]);
181 }
182 ek_exit();
183 id = EK_ID_NONE;
184 LOADER_UNLOAD();
185}
186/*-----------------------------------------------------------------------------------*/
187static void
188read_dirent(void)
189{
190 static struct cfs_dirent dirent;
191 static char message[40];
192
193 if(loading == LOADING_DIR) {
194 if(cfs_readdir(&dir, &dirent)) {
195 cfs_closedir(&dir);
196 loading = LOADING_DSC;
197 filenameptr = 0;
oliverschmidt5e7c4b62005-05-06 22:33:05 +0000198 } else if(strcasecmp(&dirent.name[strlen(dirent.name) - 4], ".dsc") == 0) {
adamdunkelsf431abe2004-08-09 20:07:18 +0000199 strncpy(filenames[numfiles], dirent.name, FILENAMELEN);
200 ++numfiles;
201 if(numfiles == MAX_NUMFILES) {
202 cfs_closedir(&dir);
203 loading = LOADING_DSC;
204 filenameptr = 0;
205 return;
206 }
207 strcpy(message, "Found \"");
208 strcpy(message + 7, dirent.name);
209 strcpy(message + 7 + strlen(dirent.name), "\"...");
210 show_statustext(message);
211 }
212 }
213}
214/*-----------------------------------------------------------------------------------*/
215static void
216load_dirent(void)
217{
218 static char message[40];
219 char *name;
220
221 if(loading == LOADING_DSC) {
222
223 name = filenames[filenameptr];
224 dscs[filenameptr] = LOADER_LOAD_DSC(name);
225 if(dscs[filenameptr] == NULL || filenameptr + 1 >= numfiles) {
226 loading = 0;
227 makewindow(0);
228 show_statustext("Directory loaded");
229 ctk_window_redraw(&window);
230 return;
231 }
232 ++filenameptr;
233 strcpy(message, "Loading \"");
234 strcpy(message + 9, name);
235 strcpy(message + 9 + strlen(name), "\"...");
236 show_statustext(message);
237 }
238}
239/*-----------------------------------------------------------------------------------*/
240EK_EVENTHANDLER(directory_eventhandler, ev, data)
241{
242 unsigned char i;
243 EK_EVENTHANDLER_ARGS(ev, data);
244
245 if(ev == EK_EVENT_INIT) {
246 ctk_window_new(&window, width, height, "Directory");
247
248 /* loaddirectory();*/
249 makewindow(0);
250 show_statustext("Loading directory...");
251 startloading();
252
253 ctk_window_open(&window);
254
255 } else if(ev == EK_EVENT_CONTINUE) {
256 read_dirent();
257 load_dirent();
258 if(loading != 0) {
259 ek_post(id, EK_EVENT_CONTINUE, NULL);
260 }
261 } else if(ev == ctk_signal_widget_activate) {
262 if(data == (ek_data_t)&reloadbutton) {
263 for(i = 0; dscs[i] != NULL; ++i) {
264 LOADER_UNLOAD_DSC(dscs[i]);
265 dscs[i] = NULL;
266 }
267 /* loaddirectory();*/
268 startloading();
269 makewindow(0);
270 ctk_window_open(&window);
271 } else if(data == (ek_data_t)&morebutton) {
272 makewindow(morestart);
273 ctk_window_open(&window);
274 } else if(data == (ek_data_t)&backbutton) {
275 makewindow(0);
276 ctk_window_open(&window);
277 } else if(data == (ek_data_t)&autoexitbutton) {
278 autoexit = 1 - autoexit;
279 if(autoexit == 1) {
280 ctk_label_set_text(&autoexitlabel, autoexiton);
281 } else {
282 ctk_label_set_text(&autoexitlabel, autoexitoff);
283 }
284 CTK_WIDGET_REDRAW(&autoexitlabel);
285 } else {
286 for(i = 0; dscs[i] != NULL; ++i) {
287 if(data == (ek_data_t)(dscs[i]->icon)) {
288 program_handler_load(dscs[i]->prgname, NULL);
289 if(autoexit) {
290 ctk_window_close(&window);
291 quit();
292 }
293 break;
294 }
295 }
296 }
297 } else if(ev == ctk_signal_widget_select) {
298 if(data == (ek_data_t)&reloadbutton) {
299 show_statustext("Reload directory");
300 } else if(data == (ek_data_t)&morebutton) {
301 show_statustext("Show more files");
302 } else if(data == (ek_data_t)&backbutton) {
303 show_statustext("Show first files");
304 } else if(data == (ek_data_t)&autoexitbutton) {
305 show_statustext("Exit when loading program");
306 } else {
307 for(i = 0; dscs[i] != NULL; ++i) {
308 if(data == (ek_data_t)(dscs[i]->icon)) {
309 show_statustext(dscs[i]->description);
310 break;
311 }
312 }
313 }
314 } else if(ev == ctk_signal_window_close &&
315 data == (ek_data_t)&window) {
316 quit();
317 } else if(ev == EK_EVENT_REQUEST_EXIT) {
318 ctk_window_close(&window);
319 quit();
320 }
321}
322/*-----------------------------------------------------------------------------------*/