123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831 |
- /*
- * File : filelist_view.c
- * This file is part of RTGUI in RT-Thread RTOS
- * COPYRIGHT (C) 2010, RT-Thread Development Team
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rt-thread.org/license/LICENSE
- *
- * Change Logs:
- * Date Author Notes
- * 2010-01-06 Bernard first version
- */
- #include <rtgui/rtgui_object.h>
- #include <rtgui/rtgui_system.h>
- #include <rtgui/rtgui_theme.h>
- #include <rtgui/rtgui_app.h>
- #include <rtgui/list.h>
- #include <rtgui/image.h>
- #include <rtgui/widgets/container.h>
- #include <rtgui/widgets/filelist_view.h>
- #include <rtgui/widgets/listbox.h>
- #include <rtgui/widgets/window.h>
- #if defined(RTGUI_USING_DFS_FILERW) || defined(RTGUI_USING_STDIO_FILERW)
- #ifdef _WIN32
- #include <io.h>
- #include <dirent.h>
- #include <sys/stat.h>
- #define PATH_SEPARATOR '\\'
- #else
- #include <dfs_posix.h>
- #define PATH_SEPARATOR '/'
- #endif
- #include <string.h>
- #define RTGUI_FILELIST_MARGIN 5
- const static char * file_xpm[] = {
- "16 16 21 1",
- " c None",
- ". c #999999",
- "+ c #818181",
- "@ c #FFFFFF",
- "# c #ECECEC",
- "$ c #EAEAEA",
- "% c #EBEBEB",
- "& c #EDEDED",
- "* c #F0F0F0",
- "= c #C4C4C4",
- "- c #C5C5C5",
- "; c #C6C6C6",
- "> c #C7C7C7",
- ", c #EEEEEE",
- "' c #EDEDE5",
- ") c #EDEDE6",
- "! c #EFEFEF",
- "~ c #C8C8C8",
- "{ c #F1F1F1",
- "] c #F2F2F2",
- "^ c #959595",
- ".++++++++++++ ",
- "+@@@@@@@@@@@@+ ",
- "+@#$$%%%##&*@+ ",
- "+@$=--;;;;>*@+ ",
- "+@$%%###&&,*@+ ",
- "+@%-;;;;;;>*@+ ",
- "+@%%##&&'#,*@+ ",
- "+@%;;;;,,),*@+ ",
- "+@##&&,,!!!*@+ ",
- "+@#;;;>>~~~*@+ ",
- "+@#&,,!!*{{{@+ ",
- "+@&;>>~~~{{]@+ ",
- "+@&&,!!**{]]@+ ",
- "+@@@@@@@@@@@@+ ",
- "^++++++++++++^ ",
- " "};
- const static char * folder_xpm[] = {
- "16 16 121 2",
- " c None",
- ". c #D9B434",
- "+ c #E1C25E",
- "@ c #E2C360",
- "# c #E2C35F",
- "$ c #DBB63C",
- "% c #DAB336",
- "& c #FEFEFD",
- "* c #FFFFFE",
- "= c #FFFEFE",
- "- c #FFFEFD",
- "; c #FBF7EA",
- "> c #E4C76B",
- ", c #E3C76B",
- "' c #E6CD79",
- ") c #E5CA74",
- "! c #DAAF35",
- "~ c #FEFCF7",
- "{ c #F8E48E",
- "] c #F5DE91",
- "^ c #F5E09F",
- "/ c #F6E1AC",
- "( c #FEFBEF",
- "_ c #FEFDF4",
- ": c #FEFCF3",
- "< c #FEFCF1",
- "[ c #FEFBEE",
- "} c #FFFDFA",
- "| c #DAAF36",
- "1 c #DAAA36",
- "2 c #FDFAF1",
- "3 c #F5DE94",
- "4 c #F4DC93",
- "5 c #F2D581",
- "6 c #EDCA6A",
- "7 c #EACB6C",
- "8 c #EFD385",
- "9 c #EFD280",
- "0 c #EFD07A",
- "a c #EECF76",
- "b c #EECF72",
- "c c #FBF7E9",
- "d c #DAAE34",
- "e c #DAAB35",
- "f c #FBF6E8",
- "g c #EFD494",
- "h c #EECE88",
- "i c #E9C173",
- "j c #F6E9C9",
- "k c #FEFCF2",
- "l c #FEFCF0",
- "m c #DAAB36",
- "n c #DAA637",
- "o c #FFFDF8",
- "p c #FFFDF6",
- "q c #FFFCF5",
- "r c #FCF6D8",
- "s c #F8E694",
- "t c #F7E385",
- "u c #F6DF76",
- "v c #F5DB68",
- "w c #F4D85C",
- "x c #FCF4D7",
- "y c #DAA435",
- "z c #DAA136",
- "A c #FEFCF6",
- "B c #FCF2C8",
- "C c #FBEFB9",
- "D c #FAECAC",
- "E c #F9E89C",
- "F c #F7E38B",
- "G c #F6E07C",
- "H c #F6DC6C",
- "I c #F5D95D",
- "J c #F4D64F",
- "K c #F3D344",
- "L c #FCF3D0",
- "M c #DA9F35",
- "N c #DA9A36",
- "O c #FDFAF2",
- "P c #FAEDB3",
- "Q c #F9E9A4",
- "R c #F8E695",
- "S c #F7E285",
- "T c #F6DE76",
- "U c #F5DB65",
- "V c #F4D757",
- "W c #F3D449",
- "X c #F2D13B",
- "Y c #F1CE30",
- "Z c #FBF2CC",
- "` c #DA9835",
- " . c #DA9435",
- ".. c #FEFAEF",
- "+. c #F9E9A1",
- "@. c #F8E591",
- "#. c #F7E181",
- "$. c #F6DE72",
- "%. c #F5DA63",
- "&. c #F4D754",
- "*. c #F3D347",
- "=. c #F2D039",
- "-. c #F1CD2E",
- ";. c #F0CB26",
- ">. c #FBF2CA",
- ",. c #D98E33",
- "'. c #FAF0DC",
- "). c #F4DDA7",
- "!. c #F4DB9E",
- "~. c #F3DA96",
- "{. c #F3D88E",
- "]. c #F3D786",
- "^. c #F2D47F",
- "/. c #F2D379",
- "(. c #F1D272",
- "_. c #F1D06C",
- ":. c #F1CF69",
- "<. c #F8EAC2",
- "[. c #D8882D",
- "}. c #D8872D",
- "|. c #D8862C",
- " ",
- " ",
- " ",
- " . + @ @ @ # $ ",
- " % & * = - * ; > , , , ' ) ",
- " ! ~ { ] ^ / ( _ : < ( [ } | ",
- " 1 2 3 4 5 6 7 8 9 0 a b c d ",
- " e f g h i j k : k l ( [ * m ",
- " n * o p q : r s t u v w x y ",
- " z A B C D E F G H I J K L M ",
- " N O P Q R S T U V W X Y Z ` ",
- " ...+.@.#.$.%.&.*.=.-.;.>. . ",
- " ,.'.).!.~.{.].^./.(._.:.<.,. ",
- " [.}.[.[.[.[.[.[.[.[.}.[.|. ",
- " ",
- " "};
- /* image for file and folder */
- static rtgui_image_t *file_image, *folder_image;
- static struct rtgui_listbox_item items[] =
- {
- #ifdef RTGUI_USING_FONTHZ
- {"şţôË�`Á§�Ë", RT_NULL},
- {"íĄŚv�`Á§�Ë", RT_NULL},
- {"ŘXµĚ", RT_NULL}
- #else
- {"Open folder", RT_NULL},
- {"Select folder", RT_NULL},
- {"Cancel", RT_NULL}
- #endif
- };
- static void rtgui_filelist_view_clear(rtgui_filelist_view_t* view);
- static rt_bool_t rtgui_filelist_view_on_folder_item(rtgui_object_t* object, struct rtgui_event* event)
- {
- rtgui_win_t *menu;
- rtgui_listbox_t *listbox;
- rtgui_filelist_view_t *view;
- listbox = RTGUI_LISTBOX(object);
- menu = RTGUI_WIN(rtgui_widget_get_toplevel(RTGUI_WIDGET(object)));
- view = RTGUI_FILELIST_VIEW(menu->user_data);
- /* hide window */
- rtgui_win_hiden(menu);
- switch (listbox->current_item)
- {
- case 0:
- {
- char* dir_ptr;
- /* destroy menu window */
- rtgui_win_destroy(menu);
- dir_ptr = (char*) rtgui_malloc (256);
- rtgui_filelist_view_get_fullpath(view, dir_ptr, 256);
- rtgui_filelist_view_set_directory(view, dir_ptr);
- rt_free(dir_ptr);
- }
- break;
- case 1:
- /* destroy menu window */
- rtgui_win_destroy(menu);
- break;
- default:
- /* destroy menu window */
- rtgui_win_destroy(menu);
- break;
- }
- return RT_TRUE;
- }
- static rt_bool_t rtgui_filelist_view_on_menu_deactivate(rtgui_object_t* object, struct rtgui_event* event)
- {
- rtgui_win_t *menu;
- menu = RTGUI_WIN(rtgui_widget_get_toplevel(RTGUI_WIDGET(object)));
- /* destroy menu window */
- rtgui_win_destroy(menu);
- return RT_TRUE;
- }
- static void rtgui_filelist_view_menu_pop(rtgui_widget_t *parent)
- {
- rtgui_win_t *menu;
- rtgui_listbox_t *listbox;
- rtgui_rect_t screen, rect = {0, 0, 140, 85};
- rtgui_graphic_driver_get_rect(rtgui_graphic_driver_get_default(), &screen);
- rtgui_rect_moveto_align(&screen, &rect, RTGUI_ALIGN_CENTER_HORIZONTAL | RTGUI_ALIGN_CENTER_VERTICAL);
- menu = rtgui_win_create(RTGUI_WIN(rtgui_widget_get_toplevel(parent)),
- "Folder Menu", &rect, RTGUI_WIN_STYLE_DEFAULT);
- if (menu != RT_NULL)
- {
- /* set user data on menu window */
- menu->user_data = (rt_uint32_t)parent;
- rtgui_win_set_ondeactivate(menu, rtgui_filelist_view_on_menu_deactivate);
- listbox = rtgui_listbox_create(items, sizeof(items)/sizeof(items[0]), &rect);
- rtgui_listbox_set_onitem(listbox, rtgui_filelist_view_on_folder_item);
- rtgui_container_add_child(RTGUI_CONTAINER(menu), RTGUI_WIDGET(listbox));
- rtgui_win_show(menu, RT_FALSE);
- rtgui_widget_focus(RTGUI_WIDGET(listbox));
- rtgui_listbox_set_current_item(listbox, 0);
- }
- }
- static void _rtgui_filelist_view_constructor(struct rtgui_filelist_view *view)
- {
- /* default rect */
- struct rtgui_rect rect = {0, 0, 200, 200};
- /* set default widget rect and set event handler */
- rtgui_object_set_event_handler(RTGUI_OBJECT(view), rtgui_filelist_view_event_handler);
- rtgui_widget_set_rect(RTGUI_WIDGET(view), &rect);
- RTGUI_WIDGET(view)->flag |= RTGUI_WIDGET_FLAG_FOCUSABLE;
- view->current_item = 0;
- view->items_count = 0;
- view->page_items = 0;
- view->current_directory = RT_NULL;
- view->pattern = RT_NULL;
- RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(view)) = white;
- RTGUI_WIDGET_TEXTALIGN(RTGUI_WIDGET(view)) = RTGUI_ALIGN_CENTER_VERTICAL;
- file_image = rtgui_image_create_from_mem("xpm",
- (rt_uint8_t*)file_xpm, sizeof(file_xpm), RT_TRUE);
- folder_image = rtgui_image_create_from_mem("xpm",
- (rt_uint8_t*)folder_xpm, sizeof(folder_xpm), RT_TRUE);
- }
- static void _rtgui_filelist_view_destructor(struct rtgui_filelist_view *view)
- {
- /* delete all file items */
- rtgui_filelist_view_clear(view);
- /* delete current directory and pattern */
- rtgui_free(view->current_directory); view->current_directory = RT_NULL;
- rtgui_free(view->pattern); view->pattern = RT_NULL;
- /* delete image */
- rtgui_image_destroy(file_image);
- rtgui_image_destroy(folder_image);
- }
- DEFINE_CLASS_TYPE(filelist, "filelist",
- RTGUI_CONTAINER_TYPE,
- _rtgui_filelist_view_constructor,
- _rtgui_filelist_view_destructor,
- sizeof(struct rtgui_filelist_view));
- void rtgui_filelist_view_ondraw(struct rtgui_filelist_view* view)
- {
- struct rtgui_dc* dc;
- rt_uint16_t page_index, index;
- struct rtgui_file_item* item;
- struct rtgui_rect rect, item_rect, image_rect;
- dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(view));
- if (dc == RT_NULL) return;
- rtgui_widget_get_rect(RTGUI_WIDGET(view), &rect);
- rtgui_dc_fill_rect(dc, &rect);
- /* get item base rect */
- item_rect = rect;
- item_rect.y1 += 1;
- item_rect.y2 = item_rect.y1 + (1 + rtgui_theme_get_selected_height());
- /* get image base rect */
- image_rect.x1 = RTGUI_FILELIST_MARGIN; image_rect.y1 = 0;
- image_rect.x2 = RTGUI_FILELIST_MARGIN + file_image->w; image_rect.y2 = file_image->h;
- rtgui_rect_moveto_align(&item_rect, &image_rect, RTGUI_ALIGN_CENTER_VERTICAL);
- /* get current page */
- page_index = (view->current_item / view->page_items) * view->page_items;
- for (index = 0; index < view->page_items; index ++)
- {
- if (page_index + index >= view->items_count) break;
- item = &(view->items[page_index + index]);
- if (page_index + index == view->current_item)
- {
- rtgui_theme_draw_selected(dc, &item_rect);
- }
- else
- {
- /* draw background */
- rtgui_dc_fill_rect(dc, &item_rect);
- }
- /* draw item */
- if (item->type == RTGUI_FITEM_FILE)
- rtgui_image_blit(file_image, dc, &image_rect);
- else
- rtgui_image_blit(folder_image, dc, &image_rect);
- /* draw text */
- item_rect.x1 += RTGUI_FILELIST_MARGIN + file_image->w + 2;
- rtgui_dc_draw_text(dc, item->name, &item_rect);
- item_rect.x1 -= RTGUI_FILELIST_MARGIN + file_image->w + 2;
- /* move to next item position */
- item_rect.y1 += (rtgui_theme_get_selected_height() + 1);
- item_rect.y2 += (rtgui_theme_get_selected_height() + 1);
- image_rect.y1 += (rtgui_theme_get_selected_height() + 1);
- image_rect.y2 += (rtgui_theme_get_selected_height() + 1);
- }
- rtgui_dc_end_drawing(dc);
- }
- void rtgui_filelist_view_update_current(struct rtgui_filelist_view* view, rt_uint16_t old_item)
- {
- struct rtgui_dc* dc;
- struct rtgui_file_item* item;
- rtgui_rect_t rect, item_rect, image_rect;
- if (old_item/view->page_items != view->current_item/view->page_items)
- {
- /* it's not a same page, update all */
- rtgui_widget_update(RTGUI_WIDGET(view));
- return;
- }
- dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(view));
- if (dc == RT_NULL) return;
- rtgui_widget_get_rect(RTGUI_WIDGET(view), &rect);
- /* get old item rect */
- item_rect = rect;
- item_rect.y1 += 1;
- item_rect.y1 += (old_item % view->page_items) * (1 + rtgui_theme_get_selected_height());
- item_rect.y2 = item_rect.y1 + (1 + rtgui_theme_get_selected_height());
- /* get image rect */
- image_rect.x1 = RTGUI_FILELIST_MARGIN; image_rect.y1 = 0;
- image_rect.x2 = RTGUI_FILELIST_MARGIN + file_image->w; image_rect.y2 = file_image->h;
- rtgui_rect_moveto_align(&item_rect, &image_rect, RTGUI_ALIGN_CENTER_VERTICAL);
- /* draw old item */
- rtgui_dc_fill_rect(dc, &item_rect);
- item = &(view->items[old_item]);
- if (item->type == RTGUI_FITEM_FILE) /* draw item image */
- rtgui_image_blit(file_image, dc, &image_rect);
- else
- rtgui_image_blit(folder_image, dc, &image_rect);
- item_rect.x1 += RTGUI_FILELIST_MARGIN + file_image->w + 2;
- rtgui_dc_draw_text(dc, item->name, &item_rect);
- /* draw current item */
- item_rect = rect;
- item_rect.y1 += 1;
- item_rect.y1 += (view->current_item % view->page_items) * (1 + rtgui_theme_get_selected_height());
- item_rect.y2 = item_rect.y1 + (1 + rtgui_theme_get_selected_height());
- rtgui_theme_draw_selected(dc, &item_rect);
- /* get image base rect */
- image_rect.x1 = RTGUI_FILELIST_MARGIN; image_rect.y1 = 0;
- image_rect.x2 = RTGUI_FILELIST_MARGIN + file_image->w; image_rect.y2 = file_image->h;
- rtgui_rect_moveto_align(&item_rect, &image_rect, RTGUI_ALIGN_CENTER_VERTICAL);
- item = &(view->items[view->current_item]);
- if (item->type == RTGUI_FITEM_FILE) /* draw item image */
- rtgui_image_blit(file_image, dc, &image_rect);
- else
- rtgui_image_blit(folder_image, dc, &image_rect);
- item_rect.x1 += RTGUI_FILELIST_MARGIN + file_image->w + 2;
- rtgui_dc_draw_text(dc, item->name, &item_rect);
- rtgui_dc_end_drawing(dc);
- }
- static void rtgui_filelist_view_onenturn(struct rtgui_filelist_view* view)
- {
- if (view->items[view->current_item].type == RTGUI_FITEM_DIR)
- {
- char new_path[64];
- if (strcmp(view->items[view->current_item].name, ".") == 0) return ;
- if (strcmp(view->items[view->current_item].name, "..") == 0)
- {
- char *ptr;
- ptr = strrchr(view->current_directory, PATH_SEPARATOR);
- if (ptr == RT_NULL) return ;
- if (ptr == &(view->current_directory[0]))
- {
- /* it's root directory */
- new_path[0] = PATH_SEPARATOR;
- new_path[1] = '\0';
- }
- else
- {
- strncpy(new_path, view->current_directory, ptr - view->current_directory + 1);
- new_path[ptr - view->current_directory] = '\0';
- }
- }
- else if (view->current_item == 0 &&
- #ifdef _WIN32
- (view->current_directory[1] == ':') && (view->current_directory[2] == '\\')
- #else
- (view->current_directory[0] == '/') && (view->current_directory[1] == '\0')
- #endif
- )
- {
- rtgui_filelist_view_destroy(view);
- return ;
- }
- else
- {
- rtgui_filelist_view_menu_pop(RTGUI_WIDGET(view));
- return ;
- }
- rtgui_filelist_view_set_directory(view, new_path);
- }
- }
- rt_bool_t rtgui_filelist_view_event_handler(struct rtgui_object* object, struct rtgui_event* event)
- {
- struct rtgui_widget *widget;
- struct rtgui_filelist_view* view = RT_NULL;
- widget = RTGUI_WIDGET(object);
- view = RTGUI_FILELIST_VIEW(widget);
- switch (event->type)
- {
- case RTGUI_EVENT_PAINT:
- rtgui_filelist_view_ondraw(view);
- return RT_FALSE;
- case RTGUI_EVENT_RESIZE:
- {
- struct rtgui_event_resize* resize;
- resize = (struct rtgui_event_resize*)event;
- /* recalculate page items */
- if (file_image != RT_NULL)
- view->page_items = resize->h / (1 + rtgui_theme_get_selected_height());
- else
- view->page_items = resize->h / (2 + 14);
- }
- break;
- case RTGUI_EVENT_MOUSE_BUTTON:
- {
- rtgui_rect_t rect;
- struct rtgui_event_mouse* emouse;
- emouse = (struct rtgui_event_mouse*)event;
- /* calculate selected item */
- /* get physical extent information */
- rtgui_widget_get_rect(widget, &rect);
- rtgui_widget_rect_to_device(widget, &rect);
- if (rtgui_rect_contains_point(&rect, emouse->x, emouse->y) == RT_EOK)
- {
- rt_uint16_t index;
- rt_uint16_t current_page;
- rt_uint16_t old_item;
- index = (emouse->y - rect.y1) / (2 + rtgui_theme_get_selected_height());
- /* get current page */
- current_page = view->current_item/view->page_items;
- old_item = view->current_item;
- if (index + current_page * view->page_items < view->items_count)
- {
- /* set selected item */
- view->current_item = index + current_page * view->page_items;
- if (emouse->button & RTGUI_MOUSE_BUTTON_DOWN)
- {
- rtgui_filelist_view_update_current(view, old_item);
- }
- else
- {
- /* up event */
- rtgui_filelist_view_onenturn(view);
- }
- }
- return RT_TRUE;
- }
- }
- break;
- case RTGUI_EVENT_KBD:
- {
- struct rtgui_event_kbd* ekbd = (struct rtgui_event_kbd*)event;
- if (ekbd->type == RTGUI_KEYDOWN)
- {
- rt_uint16_t old_item;
- old_item = view->current_item;
- switch (ekbd->key)
- {
- case RTGUIK_UP:
- if (view->current_item > 0)
- view->current_item --;
- rtgui_filelist_view_update_current(view, old_item);
- return RT_TRUE;
- case RTGUIK_DOWN:
- if (view->current_item < view->items_count - 1)
- view->current_item ++;
- rtgui_filelist_view_update_current(view, old_item);
- return RT_TRUE;
- case RTGUIK_LEFT:
- if (view->current_item - view->page_items >= 0)
- view->current_item -= view->page_items;
- rtgui_filelist_view_update_current(view, old_item);
- return RT_TRUE;
- case RTGUIK_RIGHT:
- if (view->current_item + view->page_items < view->items_count - 1)
- view->current_item += view->page_items;
- rtgui_filelist_view_update_current(view, old_item);
- return RT_TRUE;
- case RTGUIK_RETURN:
- rtgui_filelist_view_onenturn(view);
- return RT_TRUE;
- default:
- break;
- }
- }
- }
- return RT_FALSE;
- }
- /* use view event handler */
- return rtgui_container_event_handler(object, event);
- }
- rtgui_filelist_view_t* rtgui_filelist_view_create(const char* directory,
- const char* pattern,
- const rtgui_rect_t* rect)
- {
- struct rtgui_filelist_view* view = RT_NULL;
- /* create a new view */
- view = (struct rtgui_filelist_view*) rtgui_widget_create(RTGUI_FILELIST_VIEW_TYPE);
- if (view != RT_NULL)
- {
- view->items = RT_NULL;
- view->pattern = rt_strdup(pattern);
- view->page_items = rtgui_rect_height(*rect) / (1 + rtgui_theme_get_selected_height());
- rtgui_filelist_view_set_directory(view, directory);
- }
- return view;
- }
- void rtgui_filelist_view_destroy(rtgui_filelist_view_t* view)
- {
- /* destroy view */
- rtgui_widget_destroy(RTGUI_WIDGET(view));
- }
- /* clear all file items */
- static void rtgui_filelist_view_clear(rtgui_filelist_view_t* view)
- {
- rt_uint32_t index;
- struct rtgui_file_item* item;
- for (index = 0; index < view->items_count; index ++)
- {
- item = &(view->items[index]);
- /* release item name */
- rt_free(item->name);
- item->name = RT_NULL;
- }
- /* release items */
- rtgui_free(view->items);
- view->items = RT_NULL;
- view->items_count = 0;
- view->current_item = 0;
- }
- void rtgui_filelist_view_set_directory(rtgui_filelist_view_t* view, const char* directory)
- {
- struct rtgui_file_item *item;
- RT_ASSERT(view != RT_NULL);
- /* clear file items firstly */
- rtgui_filelist_view_clear(view);
- if (directory != RT_NULL)
- {
- DIR* dir;
- struct stat s;
- char* fullpath;
- rt_uint32_t index;
- struct dirent* dirent;
- view->items_count = 0;
- dir = opendir(directory);
- if (dir == RT_NULL) goto __return;
- /* current directory exists, set it */
- if (view->current_directory != RT_NULL) rt_free(view->current_directory);
- view->current_directory = rt_strdup(directory);
- do
- {
- dirent = readdir(dir);
- if (dirent == RT_NULL) break;
- if (strcmp(dirent->d_name, ".") == 0) continue;
- if (strcmp(dirent->d_name, "..") == 0) continue;
- view->items_count ++;
- } while (dirent != RT_NULL);
- closedir(dir);
- view->items_count ++; /* root directory for [x] exit, others for .. */
- view->items = (struct rtgui_file_item*) rtgui_malloc(sizeof(struct rtgui_file_item) * view->items_count);
- if (view->items == RT_NULL) return; /* no memory */
- index = 0;
- if (directory[0] == '/' && directory[1] != '\0')
- {
- item = &(view->items[0]);
- /* add .. directory */
- item->name = rt_strdup("..");
- item->type = RTGUI_FITEM_DIR;
- item->size = 0;
- index ++;
- }
- else
- {
- item = &(view->items[0]);
- /* add .. directory */
- item->name = rt_strdup("ŘXµĚ�`Á§ăš”M");
- item->type = RTGUI_FITEM_DIR;
- item->size = 0;
- index ++;
- }
- /* reopen directory */
- dir = opendir(directory);
- fullpath = rtgui_malloc(256);
- while (index < view->items_count)
- {
- dirent = readdir(dir);
- if (dirent == RT_NULL) break;
- if (strcmp(dirent->d_name, ".") == 0) continue;
- if (strcmp(dirent->d_name, "..") == 0) continue;
- item = &(view->items[index]);
- item->name = rt_strdup(dirent->d_name);
- rt_memset(&s, 0, sizeof(struct stat));
- /* build full path for the file */
- if (directory[strlen(directory) - 1] != PATH_SEPARATOR)
- rt_snprintf(fullpath, 256, "%s%c%s", directory, PATH_SEPARATOR, dirent->d_name);
- else
- rt_snprintf(fullpath, 256, "%s%s", directory, dirent->d_name);
- stat(fullpath, &s);
- if ( s.st_mode & S_IFDIR )
- {
- item->type = RTGUI_FITEM_DIR;
- item->size = 0;
- }
- else
- {
- item->type = RTGUI_FITEM_FILE;
- item->size = s.st_size;
- }
- index ++;
- }
- rtgui_free(fullpath);
- closedir(dir);
- }
- view->current_item = 0;
- __return:
- /* update view */
- rtgui_widget_update(RTGUI_WIDGET(view));
- }
- void rtgui_filelist_view_get_fullpath(rtgui_filelist_view_t* view, char* path, rt_size_t len)
- {
- RT_ASSERT(view != RT_NULL);
- if (view->current_directory[strlen(view->current_directory) - 1] != PATH_SEPARATOR)
- rt_snprintf(path, len, "%s%c%s",view->current_directory, PATH_SEPARATOR,
- view->items[view->current_item].name);
- else
- rt_snprintf(path, len, "%s%s",view->current_directory,
- view->items[view->current_item].name);
- }
- #endif
|