[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:
parent
6b47bc1af4
commit
769c53b6da
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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",
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
@ -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"
|
||||||
|
|
Loading…
Reference in New Issue
Block a user