From bd157e8909d7ebb509defdbd234140bd0f397b3d Mon Sep 17 00:00:00 2001 From: lixianjing Date: Thu, 4 Jun 2020 07:15:24 +0800 Subject: [PATCH] improve file chooser --- demos/demo_file_browser.c | 5 +-- docs/changes.md | 6 ++++ src/ext_widgets/file_browser/file_browser.c | 4 +++ .../file_browser/file_browser_view.c | 26 +++++++++++++-- .../file_browser/file_browser_view.h | 32 +++++++++++++++++++ src/ext_widgets/file_browser/file_chooser.c | 14 ++++++++ src/ext_widgets/file_browser/file_chooser.h | 3 +- 7 files changed, 84 insertions(+), 6 deletions(-) diff --git a/demos/demo_file_browser.c b/demos/demo_file_browser.c index 765a8cef5..750a8a8ad 100644 --- a/demos/demo_file_browser.c +++ b/demos/demo_file_browser.c @@ -52,7 +52,7 @@ static ret_t on_file_save(void* ctx, event_t* e) { file_chooser_t* chooser = file_chooser_create(); emitter_on(EMITTER(chooser), EVT_DONE, tk_on_choose_file_result, ctx); - file_chooser_set_init_dir(chooser, "./"); + file_chooser_set_init_dir(chooser, "../"); return file_chooser_choose_file_for_save(chooser); } @@ -61,7 +61,8 @@ static ret_t on_file_open(void* ctx, event_t* e) { file_chooser_t* chooser = file_chooser_create(); emitter_on(EMITTER(chooser), EVT_DONE, tk_on_choose_file_result, ctx); - file_chooser_set_init_dir(chooser, "./"); + file_chooser_set_init_dir(chooser, "src"); + file_chooser_set_filter(chooser, ".c.h.cpp.inc"); return file_chooser_choose_file_for_open(chooser); } diff --git a/docs/changes.md b/docs/changes.md index c1116d649..091611ebf 100644 --- a/docs/changes.md +++ b/docs/changes.md @@ -1,4 +1,10 @@ # 最新动态 +* 2020/06/04 + * 完善 file_chooser 支持初始目录和过滤规则。 + +* 2020/06/03 + * 完善 path_normalize 函数。 + * 2020/06/02 * 完善文档 * 完善 label diff --git a/src/ext_widgets/file_browser/file_browser.c b/src/ext_widgets/file_browser/file_browser.c index 7dc0bcd00..0049992d4 100644 --- a/src/ext_widgets/file_browser/file_browser.c +++ b/src/ext_widgets/file_browser/file_browser.c @@ -514,6 +514,10 @@ bool_t fb_filter_by_ext_names(void* ctx, const void* data) { const char* ext_names = (const char*)ctx; const char* p = strrchr(item->name, '.'); + if (item->is_dir) { + return TRUE; + } + if (ext_names == NULL) { return TRUE; } diff --git a/src/ext_widgets/file_browser/file_browser_view.c b/src/ext_widgets/file_browser/file_browser_view.c index e3aa9152f..8a6078ca0 100644 --- a/src/ext_widgets/file_browser/file_browser_view.c +++ b/src/ext_widgets/file_browser/file_browser_view.c @@ -33,7 +33,7 @@ #define FB_DATE_TIME_FORMAT "YY-MM-DD hh:mm:ss" #endif /*FB_DATE_TIME_FORMAT*/ -static ret_t file_browser_view_reload(widget_t* widget); +ret_t file_browser_view_reload(widget_t* widget); ret_t file_browser_view_set_init_dir(widget_t* widget, const char* init_dir) { file_browser_view_t* file_browser_view = FILE_BROWSER_VIEW(widget); @@ -45,6 +45,26 @@ ret_t file_browser_view_set_init_dir(widget_t* widget, const char* init_dir) { return RET_OK; } +ret_t file_browser_view_set_filter(widget_t* widget, const char* filter) { + file_browser_view_t* file_browser_view = FILE_BROWSER_VIEW(widget); + return_value_if_fail(file_browser_view != NULL && filter != NULL, RET_BAD_PARAMS); + + file_browser_view->filter = tk_str_copy(file_browser_view->filter, filter); + + if (tk_str_eq(filter, STR_FILTER_FILES_ONLY)) { + file_browser_set_filter(file_browser_view->fb, fb_filter_files_only, NULL); + } else if (tk_str_eq(filter, STR_FILTER_DIR_ONLY)) { + file_browser_set_filter(file_browser_view->fb, fb_filter_directories_only, NULL); + } else if(filter != NULL) { + file_browser_set_filter(file_browser_view->fb, fb_filter_by_ext_names, + file_browser_view->filter); + } else { + file_browser_set_filter(file_browser_view->fb, NULL, NULL); + } + + return RET_OK; +} + static ret_t file_browser_view_sync_sort(widget_t* widget) { file_browser_view_t* file_browser_view = FILE_BROWSER_VIEW(widget); const char* sort_by = file_browser_view->sort_by; @@ -267,7 +287,7 @@ static widget_t* file_browser_view_create_folder_item(widget_t* widget) { return item; } -static ret_t file_browser_view_reload(widget_t* widget) { +ret_t file_browser_view_reload(widget_t* widget) { uint32_t i = 0; uint32_t nr = 0; widget_t* item = NULL; @@ -369,7 +389,7 @@ static ret_t file_browser_view_init_ui(widget_t* widget) { widget_on(template, EVT_CLICK, file_browser_view_on_item_clicked, widget); file_browser_view->inited = TRUE; - return file_browser_view_reload(widget); + return RET_OK; } static ret_t file_browser_view_on_event(widget_t* widget, event_t* e) { diff --git a/src/ext_widgets/file_browser/file_browser_view.h b/src/ext_widgets/file_browser/file_browser_view.h index 5eeaeec00..c91f4df75 100644 --- a/src/ext_widgets/file_browser/file_browser_view.h +++ b/src/ext_widgets/file_browser/file_browser_view.h @@ -76,6 +76,13 @@ typedef struct _file_browser_view_t { * 初始文件夹。 */ char* init_dir; + + /** + * @property {char*} filter + * @annotation ["set_prop","get_prop","readable","persitent","design","scriptable"] + * 过滤规则。 + */ + char* filter; /** * @property {bool_t} ignore_hidden_files @@ -157,6 +164,28 @@ widget_t* file_browser_view_cast(widget_t* widget); */ ret_t file_browser_view_set_init_dir(widget_t* widget, const char* init_dir); +/** + * @method file_browser_view_set_filter + * 设置 过滤规则。 + * @annotation ["scriptable"] + * @param {widget_t*} widget widget对象。 + * @param {const char*} filter 过滤规则。 + *> files_only 表示只列出文件,dir_only 表示只列出目录,其它表示只列出满足扩展名文件集合(如:.jpg.png.gif)。 + * + * @return {ret_t} 返回RET_OK表示成功,否则表示失败。 + */ +ret_t file_browser_view_set_filter(widget_t* widget, const char* filter); + +/** + * @method file_browser_view_reload + * 重新加载。 + * @annotation ["scriptable"] + * @param {widget_t*} widget widget对象。 + * + * @return {ret_t} 返回RET_OK表示成功,否则表示失败。 + */ +ret_t file_browser_view_reload(widget_t* widget); + /** * @method file_browser_view_set_ignore_hidden_files * 设置 忽略隐藏文件。 @@ -289,6 +318,9 @@ ret_t file_browser_view_register(void); /*容器控件,通常是scrollview*/ #define FILE_BROWSER_VIEW_CONTAINER "container" +#define STR_FILTER_FILES_ONLY "files_only" +#define STR_FILTER_DIR_ONLY "dir_only" + /*public for subclass and runtime type check*/ TK_EXTERN_VTABLE(file_browser_view); diff --git a/src/ext_widgets/file_browser/file_chooser.c b/src/ext_widgets/file_browser/file_chooser.c index fa3bdeec8..4d9a94808 100644 --- a/src/ext_widgets/file_browser/file_chooser.c +++ b/src/ext_widgets/file_browser/file_chooser.c @@ -102,9 +102,22 @@ static ret_t file_choose_on_ok(void* ctx, event_t* e) { ret_t file_chooser_choose(file_chooser_t* chooser) { widget_t* win = window_open(chooser->ui); + widget_t* file_browser_view = widget_lookup_by_type(win, WIDGET_TYPE_FILE_BROWSER_VIEW, TRUE); + widget_child_on(win, FILE_CHOOSER_OK, EVT_CLICK, file_choose_on_ok, chooser); widget_child_on(win, FILE_CHOOSER_CANCEL, EVT_CLICK, file_choose_on_click_to_close, chooser); + if (chooser->init_dir != NULL || chooser->filter != NULL) { + if (chooser->filter != NULL) { + file_browser_view_set_filter(file_browser_view, chooser->filter); + } + + if (chooser->init_dir != NULL) { + file_browser_view_set_init_dir(file_browser_view, chooser->init_dir); + } + } + file_browser_view_reload(file_browser_view); + if (widget_is_dialog(win)) { dialog_modal(win); } @@ -131,6 +144,7 @@ ret_t file_chooser_choose_folder(file_chooser_t* chooser) { return_value_if_fail(chooser != NULL, RET_BAD_PARAMS); chooser->ui = FILE_CHOOSER_UI_CHOOSE_FOLDER; + file_chooser_set_filter(chooser, STR_FILTER_DIR_ONLY); return file_chooser_choose(chooser); } diff --git a/src/ext_widgets/file_browser/file_chooser.h b/src/ext_widgets/file_browser/file_chooser.h index 94610a1b5..02eb03d4e 100644 --- a/src/ext_widgets/file_browser/file_chooser.h +++ b/src/ext_widgets/file_browser/file_chooser.h @@ -106,7 +106,8 @@ ret_t file_chooser_set_init_dir(file_chooser_t* chooser, const char* init_dir); * 设置过滤规则。 * @annotation ["scriptable"] * @param {file_chooser_t*} chooser file_chooser对象。 - * @param {const char*} filter 过滤规则(如".jpg.png.gif")。 + * @param {const char*} filter 过滤规则。 + *> files_only 表示只列出文件,dir_only 表示只列出目录,其它表示只列出满足扩展名文件集合(如:.jpg.png.gif)。 * * @return {ret_t} 返回RET_OK表示成功,否则表示失败。 */