|
@@ -0,0 +1,185 @@
|
|
|
|
+#include <rtgui/rtgui_object.h>
|
|
|
|
+#include <rtgui/rtgui_system.h>
|
|
|
|
+
|
|
|
|
+#include <rtgui/list.h>
|
|
|
|
+#include <rtgui/widgets/view.h>
|
|
|
|
+
|
|
|
|
+/* image for file and folder */
|
|
|
|
+rtgui_image_t *file_image, *folder_image;
|
|
|
|
+
|
|
|
|
+static void _filelist_view_constructor(filelist_view *view)
|
|
|
|
+{
|
|
|
|
+ /* default rect */
|
|
|
|
+ struct rtgui_rect rect = {0, 0, 200, 200};
|
|
|
|
+
|
|
|
|
+ /* set default widget rect and set event handler */
|
|
|
|
+ rtgui_widget_set_event_handler(RTGUI_WIDGET(view),filelist_view_event_handler);
|
|
|
|
+ rtgui_widget_set_rect(RTGUI_WIDGET(view), &rect);
|
|
|
|
+
|
|
|
|
+ RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(list)) = RTGUI_RGB(212, 208, 200);
|
|
|
|
+
|
|
|
|
+ view->count = 0;
|
|
|
|
+ view->current_directory = RT_NULL;
|
|
|
|
+ view->pattern = RT_NULL;
|
|
|
|
+ rtgui_list_init(&view->list);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+rtgui_type_t *filelist_view_type_get(void)
|
|
|
|
+{
|
|
|
|
+ static rtgui_type_t *filelist_view_type = RT_NULL;
|
|
|
|
+
|
|
|
|
+ if (!filelist_view_type)
|
|
|
|
+ {
|
|
|
|
+ filelist_view_type = rtgui_type_create("flview", RTGUI_VIEW_TYPE,
|
|
|
|
+ sizeof(filelist_view_t), RTGUI_CONSTRUCTOR(_filelist_view_constructor), RT_NULL);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return filelist_view_type;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+rt_bool_t filelist_view_event_handler(struct rtgui_widget* widget, struct rtgui_event* event)
|
|
|
|
+{
|
|
|
|
+ struct filelist_view* view = RT_NULL;
|
|
|
|
+
|
|
|
|
+ view = FILELIST_VIEW(widget);
|
|
|
|
+ switch (event.type)
|
|
|
|
+ {
|
|
|
|
+ case RTGUI_EVENT_PAINT:
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ case RTGUI_EVENT_RESIZE:
|
|
|
|
+ {
|
|
|
|
+ /* recalculate page items */
|
|
|
|
+ }
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ case RTGUI_EVENT_KBD:
|
|
|
|
+ {
|
|
|
|
+ struct rtgui_event_kbd* ekbd = (struct rtgui_event_kbd*)event;
|
|
|
|
+ if (ekbd->type == RTGUI_KEYDOWN)
|
|
|
|
+ {
|
|
|
|
+ switch (ekbd->key)
|
|
|
|
+ {
|
|
|
|
+ case RTGUIK_UP:
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ case RTGUIK_DOWN:
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ default:
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /* use view event handler */
|
|
|
|
+ return rtgui_view_event_handler(widget, event);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+filelist_view_t* filelist_view_create(const char* directory, const char* pattern)
|
|
|
|
+{
|
|
|
|
+ struct filelist_view* view = RT_NULL;
|
|
|
|
+
|
|
|
|
+ view = (struct filelist_view*) rtgui_widget_create(FILELIST_VIEW_TYPE);
|
|
|
|
+ if (view != RT_NULL)
|
|
|
|
+ {
|
|
|
|
+ view->pattern = rt_strdup(pattern);
|
|
|
|
+ filelist_view_set_directory(view, directory);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return list;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void filelist_view_destroy(filelist_view_t* view)
|
|
|
|
+{
|
|
|
|
+ /* delete all file items */
|
|
|
|
+ filelist_view_clear(view);
|
|
|
|
+
|
|
|
|
+ /* destroy view */
|
|
|
|
+ rtgui_widget_destroy(RTGUI_WIDGET(view));
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/* clear all file items */
|
|
|
|
+void filelist_view_clear(filelist_view_t* view)
|
|
|
|
+{
|
|
|
|
+ struct rtgui_list_node* node;
|
|
|
|
+ struct file_item* item;
|
|
|
|
+
|
|
|
|
+ while (view->list.next != RT_NULL)
|
|
|
|
+ {
|
|
|
|
+ node = view->list.next;
|
|
|
|
+ rtgui_list_remove(&view->list, node);
|
|
|
|
+
|
|
|
|
+ item = rtgui_list_entry(node, struct file_item, list);
|
|
|
|
+ rtgui_free(item->name);
|
|
|
|
+ rtgui_free(item);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void filelist_view_set_directory(filelist_view_t* view, const char* directory)
|
|
|
|
+{
|
|
|
|
+ rt_uint8_t fullpath[256];
|
|
|
|
+ struct file_item *item;
|
|
|
|
+
|
|
|
|
+ RT_ASSERT(view != RT_NULL);
|
|
|
|
+
|
|
|
|
+ /* clear file items firstly */
|
|
|
|
+ filelist_view_clear(view);
|
|
|
|
+ if (directory != RT_NULL)
|
|
|
|
+ {
|
|
|
|
+ DIR* dir;
|
|
|
|
+ dir = opendir(directory);
|
|
|
|
+ if (dir != RT_NULL)
|
|
|
|
+ {
|
|
|
|
+ struct dfs_dirent* dirent;
|
|
|
|
+ struct dfs_stat s;
|
|
|
|
+
|
|
|
|
+ do
|
|
|
|
+ {
|
|
|
|
+ dirent = readdir(dir);
|
|
|
|
+ if (dirent == RT_NULL) break;
|
|
|
|
+ if (fnmatch(dirent->d_name, view->pattern, FNM_FILE_NAME) != 0) continue;
|
|
|
|
+
|
|
|
|
+ item = (struct file_item*) rt_malloc (sizeof(struct file_item));
|
|
|
|
+ if (item == RT_NULL) break;
|
|
|
|
+
|
|
|
|
+ rt_memset(&s, 0, sizeof(struct dfs_stat));
|
|
|
|
+
|
|
|
|
+ /* build full path for the file */
|
|
|
|
+ rt_sprintf(fullpath, "%s/%s", directory, dirent->d_name);
|
|
|
|
+
|
|
|
|
+ item->name = strdup(direct->d_name);
|
|
|
|
+ rtgui_list_init(&item->list);
|
|
|
|
+ stat(fullpath, &s);
|
|
|
|
+ if ( s.st_mode & DFS_S_IFDIR )
|
|
|
|
+ {
|
|
|
|
+ item->type = FITEM_DIR;
|
|
|
|
+ item->size = 0;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ item->type = FITEM_FILE;
|
|
|
|
+ item->size = s.st_size;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ rtgui_list_append(&view->list, &item->list);
|
|
|
|
+ view->count ++;
|
|
|
|
+ } while (dirent != RT_NULL);
|
|
|
|
+
|
|
|
|
+ closedir(dir);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (view->count > 0)
|
|
|
|
+ {
|
|
|
|
+ /* select first one */
|
|
|
|
+ view->selected = rtgui_list_entry(view->list.next,
|
|
|
|
+ struct file_item, list);
|
|
|
|
+ }
|
|
|
|
+ else view->selected = RT_NULL;
|
|
|
|
+
|
|
|
|
+ /* update view */
|
|
|
|
+ rtgui_widget_update(RTGUI_WIDGET(view));
|
|
|
|
+}
|