[FL-2977] Gui: better navigation in file browser dialog (#2014)

* Gui: proper navigation in file browser dialog
* Trim file name from start path
* File list loading fix
* File list offset fix

Co-authored-by: nminaylov <nm29719@gmail.com>
Co-authored-by: Sergey Gavrilov <who.just.the.doctor@gmail.com>
This commit is contained in:
あく 2022-11-29 03:59:24 +09:00 committed by GitHub
parent 6b47bc1af4
commit 769c53b6da
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 41 additions and 6 deletions

View File

@ -265,8 +265,7 @@ void archive_file_array_load(ArchiveBrowserView* browser, int8_t dir) {
offset_new = model->item_idx - FILE_LIST_BUF_LEN / 4 * 1; offset_new = model->item_idx - FILE_LIST_BUF_LEN / 4 * 1;
} }
if(offset_new > 0) { if(offset_new > 0) {
offset_new = offset_new = CLAMP(offset_new, (int32_t)model->item_cnt, 0);
CLAMP(offset_new, (int32_t)model->item_cnt - FILE_LIST_BUF_LEN, 0);
} else { } else {
offset_new = 0; offset_new = 0;
} }

View File

@ -5,7 +5,7 @@
#define TAB_RIGHT InputKeyRight // Default tab switch direction #define TAB_RIGHT InputKeyRight // Default tab switch direction
#define TAB_DEFAULT ArchiveTabFavorites // Start tab #define TAB_DEFAULT ArchiveTabFavorites // Start tab
#define FILE_LIST_BUF_LEN 100 #define FILE_LIST_BUF_LEN 50
static const char* tab_default_paths[] = { static const char* tab_default_paths[] = {
[ArchiveTabFavorites] = "/app:favorites", [ArchiveTabFavorites] = "/app:favorites",

View File

@ -232,7 +232,10 @@ static bool browser_is_item_in_array(FileBrowserModel* model, uint32_t idx) {
static bool browser_is_list_load_required(FileBrowserModel* model) { static bool browser_is_list_load_required(FileBrowserModel* model) {
size_t array_size = items_array_size(model->items); size_t array_size = items_array_size(model->items);
uint32_t item_cnt = (model->is_root) ? model->item_cnt : model->item_cnt - 1; if((array_size > 0) && (!model->is_root) && (model->array_offset == 0)) {
array_size--;
}
uint32_t item_cnt = (model->is_root) ? (model->item_cnt) : (model->item_cnt - 1);
if((model->list_loading) || (array_size >= item_cnt)) { if((model->list_loading) || (array_size >= item_cnt)) {
return false; return false;
@ -524,7 +527,7 @@ static bool file_browser_view_input_callback(InputEvent* event, void* context) {
model->list_loading = true; model->list_loading = true;
int32_t load_offset = CLAMP( int32_t load_offset = CLAMP(
model->item_idx - ITEM_LIST_LEN_MAX / 4 * 3, model->item_idx - ITEM_LIST_LEN_MAX / 4 * 3,
(int32_t)model->item_cnt - ITEM_LIST_LEN_MAX, (int32_t)model->item_cnt,
0); 0);
file_browser_worker_load( file_browser_worker_load(
browser->worker, load_offset, ITEM_LIST_LEN_MAX); browser->worker, load_offset, ITEM_LIST_LEN_MAX);
@ -535,7 +538,7 @@ static bool file_browser_view_input_callback(InputEvent* event, void* context) {
model->list_loading = true; model->list_loading = true;
int32_t load_offset = CLAMP( int32_t load_offset = CLAMP(
model->item_idx - ITEM_LIST_LEN_MAX / 4 * 1, model->item_idx - ITEM_LIST_LEN_MAX / 4 * 1,
(int32_t)model->item_cnt - ITEM_LIST_LEN_MAX, (int32_t)model->item_cnt,
0); 0);
file_browser_worker_load( file_browser_worker_load(
browser->worker, load_offset, ITEM_LIST_LEN_MAX); browser->worker, load_offset, ITEM_LIST_LEN_MAX);
@ -590,6 +593,19 @@ static bool file_browser_view_input_callback(InputEvent* event, void* context) {
} }
consumed = true; consumed = true;
} }
} else if(event->key == InputKeyBack) {
if(event->type == InputTypeShort) {
bool is_root = false;
with_view_model(
browser->view, FileBrowserModel * model, { is_root = model->is_root; }, false);
if(!is_root && !file_browser_worker_is_in_start_folder(browser->worker)) {
consumed = true;
if(!is_root) {
file_browser_worker_folder_exit(browser->worker);
}
}
}
} }
return consumed; return consumed;

View File

@ -35,6 +35,8 @@ struct BrowserWorker {
FuriThread* thread; FuriThread* thread;
FuriString* filter_extension; FuriString* filter_extension;
FuriString* path_start;
FuriString* path_current;
FuriString* path_next; FuriString* path_next;
int32_t item_sel_idx; int32_t item_sel_idx;
uint32_t load_offset; uint32_t load_offset;
@ -289,6 +291,7 @@ static int32_t browser_worker(void* context) {
int32_t file_idx = 0; int32_t file_idx = 0;
browser_folder_init(browser, path, filename, &items_cnt, &file_idx); browser_folder_init(browser, path, filename, &items_cnt, &file_idx);
furi_string_set(browser->path_current, path);
FURI_LOG_D( FURI_LOG_D(
TAG, TAG,
"Enter folder: %s items: %lu idx: %ld", "Enter folder: %s items: %lu idx: %ld",
@ -311,6 +314,7 @@ static int32_t browser_worker(void* context) {
// Pop previous selected item index from history array // Pop previous selected item index from history array
idx_last_array_pop_back(&file_idx, browser->idx_last); idx_last_array_pop_back(&file_idx, browser->idx_last);
} }
furi_string_set(browser->path_current, path);
FURI_LOG_D( FURI_LOG_D(
TAG, TAG,
"Exit to: %s items: %lu idx: %ld", "Exit to: %s items: %lu idx: %ld",
@ -365,8 +369,14 @@ BrowserWorker*
browser->filter_extension = furi_string_alloc_set(filter_ext); browser->filter_extension = furi_string_alloc_set(filter_ext);
browser->skip_assets = skip_assets; browser->skip_assets = skip_assets;
browser->path_start = furi_string_alloc_set(path);
browser->path_current = furi_string_alloc_set(path);
browser->path_next = furi_string_alloc_set(path); browser->path_next = furi_string_alloc_set(path);
if(browser_path_is_file(browser->path_start)) {
browser_path_trim(browser->path_start);
}
browser->thread = furi_thread_alloc_ex("BrowserWorker", 2048, browser_worker, browser); browser->thread = furi_thread_alloc_ex("BrowserWorker", 2048, browser_worker, browser);
furi_thread_start(browser->thread); furi_thread_start(browser->thread);
@ -382,6 +392,8 @@ void file_browser_worker_free(BrowserWorker* browser) {
furi_string_free(browser->filter_extension); furi_string_free(browser->filter_extension);
furi_string_free(browser->path_next); furi_string_free(browser->path_next);
furi_string_free(browser->path_current);
furi_string_free(browser->path_start);
idx_last_array_clear(browser->idx_last); idx_last_array_clear(browser->idx_last);
@ -440,6 +452,11 @@ void file_browser_worker_folder_enter(BrowserWorker* browser, FuriString* path,
furi_thread_flags_set(furi_thread_get_id(browser->thread), WorkerEvtFolderEnter); furi_thread_flags_set(furi_thread_get_id(browser->thread), WorkerEvtFolderEnter);
} }
bool file_browser_worker_is_in_start_folder(BrowserWorker* browser) {
furi_assert(browser);
return (furi_string_cmp(browser->path_start, browser->path_current) == 0);
}
void file_browser_worker_folder_exit(BrowserWorker* browser) { void file_browser_worker_folder_exit(BrowserWorker* browser) {
furi_assert(browser); furi_assert(browser);
furi_thread_flags_set(furi_thread_get_id(browser->thread), WorkerEvtFolderExit); furi_thread_flags_set(furi_thread_get_id(browser->thread), WorkerEvtFolderExit);

View File

@ -52,6 +52,8 @@ void file_browser_worker_set_config(
void file_browser_worker_folder_enter(BrowserWorker* browser, FuriString* path, int32_t item_idx); void file_browser_worker_folder_enter(BrowserWorker* browser, FuriString* path, int32_t item_idx);
bool file_browser_worker_is_in_start_folder(BrowserWorker* browser);
void file_browser_worker_folder_exit(BrowserWorker* browser); void file_browser_worker_folder_exit(BrowserWorker* browser);
void file_browser_worker_folder_refresh(BrowserWorker* browser, int32_t item_idx); void file_browser_worker_folder_refresh(BrowserWorker* browser, int32_t item_idx);

View File

@ -817,6 +817,7 @@ Function,+,file_browser_worker_folder_enter,void,"BrowserWorker*, FuriString*, i
Function,+,file_browser_worker_folder_exit,void,BrowserWorker* Function,+,file_browser_worker_folder_exit,void,BrowserWorker*
Function,+,file_browser_worker_folder_refresh,void,"BrowserWorker*, int32_t" Function,+,file_browser_worker_folder_refresh,void,"BrowserWorker*, int32_t"
Function,+,file_browser_worker_free,void,BrowserWorker* Function,+,file_browser_worker_free,void,BrowserWorker*
Function,+,file_browser_worker_is_in_start_folder,_Bool,BrowserWorker*
Function,+,file_browser_worker_load,void,"BrowserWorker*, uint32_t, uint32_t" Function,+,file_browser_worker_load,void,"BrowserWorker*, uint32_t, uint32_t"
Function,+,file_browser_worker_set_callback_context,void,"BrowserWorker*, void*" Function,+,file_browser_worker_set_callback_context,void,"BrowserWorker*, void*"
Function,+,file_browser_worker_set_config,void,"BrowserWorker*, FuriString*, const char*, _Bool" Function,+,file_browser_worker_set_config,void,"BrowserWorker*, FuriString*, const char*, _Bool"

1 entry status name type params
817 Function + file_browser_worker_folder_exit void BrowserWorker*
818 Function + file_browser_worker_folder_refresh void BrowserWorker*, int32_t
819 Function + file_browser_worker_free void BrowserWorker*
820 Function + file_browser_worker_is_in_start_folder _Bool BrowserWorker*
821 Function + file_browser_worker_load void BrowserWorker*, uint32_t, uint32_t
822 Function + file_browser_worker_set_callback_context void BrowserWorker*, void*
823 Function + file_browser_worker_set_config void BrowserWorker*, FuriString*, const char*, _Bool