diff --git a/applications/main/archive/helpers/archive_browser.c b/applications/main/archive/helpers/archive_browser.c index 4b8c3d584d..c0325ff16e 100644 --- a/applications/main/archive/helpers/archive_browser.c +++ b/applications/main/archive/helpers/archive_browser.c @@ -70,12 +70,10 @@ static void archive_list_item_cb( if(!is_last) { archive_add_file_item(browser, is_folder, furi_string_get_cstr(item_path)); } else { - bool load_again = false; with_view_model( browser->view, ArchiveBrowserViewModel * model, { - model->list_loading = false; if(model->item_cnt <= BROWSER_SORT_THRESHOLD) { FuriString* selected = NULL; if(model->item_idx >= 0) { @@ -98,14 +96,9 @@ static void archive_list_item_cb( model->item_idx = 0; } } - if(archive_is_file_list_load_required(model)) { - load_again = true; - } + model->list_loading = false; }, true); - if(load_again) { - archive_file_array_load(browser, 0); - } archive_update_offset(browser); } } @@ -152,26 +145,6 @@ bool archive_is_item_in_array(ArchiveBrowserViewModel* model, uint32_t idx) { return true; } -bool archive_is_file_list_load_required(ArchiveBrowserViewModel* model) { - size_t array_size = files_array_size(model->files); - - if((model->list_loading) || (array_size >= model->item_cnt)) { - return false; - } - - if((model->array_offset > 0) && - (model->item_idx < (model->array_offset + FILE_LIST_BUF_LEN / 4))) { - return true; - } - - if(((model->array_offset + array_size) < model->item_cnt) && - (model->item_idx > (int32_t)(model->array_offset + array_size - FILE_LIST_BUF_LEN / 4))) { - return true; - } - - return false; -} - void archive_update_offset(ArchiveBrowserView* browser) { furi_assert(browser); diff --git a/applications/main/archive/helpers/archive_browser.h b/applications/main/archive/helpers/archive_browser.h index d9214bee16..8074d2532b 100644 --- a/applications/main/archive/helpers/archive_browser.h +++ b/applications/main/archive/helpers/archive_browser.h @@ -72,7 +72,6 @@ inline bool archive_is_known_app(ArchiveFileTypeEnum type) { } bool archive_is_item_in_array(ArchiveBrowserViewModel* model, uint32_t idx); -bool archive_is_file_list_load_required(ArchiveBrowserViewModel* model); void archive_update_offset(ArchiveBrowserView* browser); void archive_update_focus(ArchiveBrowserView* browser, const char* target); diff --git a/applications/main/archive/views/archive_browser_view.c b/applications/main/archive/views/archive_browser_view.c index 2f0bd3878e..559040877d 100644 --- a/applications/main/archive/views/archive_browser_view.c +++ b/applications/main/archive/views/archive_browser_view.c @@ -334,10 +334,24 @@ View* archive_browser_get_view(ArchiveBrowserView* browser) { return browser->view; } -static void file_list_rollover(ArchiveBrowserViewModel* model) { - if(!model->list_loading && files_array_size(model->files) < model->item_cnt) { - files_array_reset(model->files); +static bool is_file_list_load_required(ArchiveBrowserViewModel* model) { + size_t array_size = files_array_size(model->files); + + if((model->list_loading) || (array_size >= model->item_cnt)) { + return false; + } + + if((model->array_offset > 0) && + (model->item_idx < (model->array_offset + FILE_LIST_BUF_LEN / 4))) { + return true; } + + if(((model->array_offset + array_size) < model->item_cnt) && + (model->item_idx > (int32_t)(model->array_offset + array_size - FILE_LIST_BUF_LEN / 4))) { + return true; + } + + return false; } static bool archive_view_input(InputEvent* event, void* context) { @@ -423,19 +437,25 @@ static bool archive_view_input(InputEvent* event, void* context) { } else { scroll_speed = model->button_held_for_ticks > 9 ? 4 : 2; } + } else if(model->button_held_for_ticks < 0) { + scroll_speed = 0; } if(event->key == InputKeyUp) { if(model->item_idx < scroll_speed) { - model->button_held_for_ticks = 0; - model->item_idx = model->item_cnt - 1; - file_list_rollover(model); - } else { - model->item_idx = - ((model->item_idx - scroll_speed) + model->item_cnt) % - model->item_cnt; + scroll_speed = model->item_idx; + if(scroll_speed == 0) { + if(model->button_held_for_ticks > 0) { + model->button_held_for_ticks = -1; + } else { + scroll_speed = 1; + } + } } - if(archive_is_file_list_load_required(model)) { + + model->item_idx = + ((model->item_idx - scroll_speed) + model->item_cnt) % model->item_cnt; + if(is_file_list_load_required(model)) { model->list_loading = true; browser->callback(ArchiveBrowserEventLoadPrevItems, browser->context); } @@ -443,17 +463,26 @@ static bool archive_view_input(InputEvent* event, void* context) { browser->callback(ArchiveBrowserEventFavMoveUp, browser->context); } model->scroll_counter = 0; + + if(model->button_held_for_ticks < -1) { + model->button_held_for_ticks = 0; + } model->button_held_for_ticks += 1; } else if(event->key == InputKeyDown) { int32_t count = model->item_cnt; - if(model->item_idx + scroll_speed >= count) { - model->button_held_for_ticks = 0; - model->item_idx = 0; - file_list_rollover(model); - } else { - model->item_idx = (model->item_idx + scroll_speed) % model->item_cnt; + if(model->item_idx >= (count - scroll_speed)) { + scroll_speed = model->item_cnt - model->item_idx - 1; + if(scroll_speed == 0) { + if(model->button_held_for_ticks > 0) { + model->button_held_for_ticks = -1; + } else { + scroll_speed = 1; + } + } } - if(archive_is_file_list_load_required(model)) { + + model->item_idx = (model->item_idx + scroll_speed) % model->item_cnt; + if(is_file_list_load_required(model)) { model->list_loading = true; browser->callback(ArchiveBrowserEventLoadNextItems, browser->context); } @@ -461,6 +490,10 @@ static bool archive_view_input(InputEvent* event, void* context) { browser->callback(ArchiveBrowserEventFavMoveDown, browser->context); } model->scroll_counter = 0; + + if(model->button_held_for_ticks < -1) { + model->button_held_for_ticks = 0; + } model->button_held_for_ticks += 1; } }, diff --git a/applications/main/archive/views/archive_browser_view.h b/applications/main/archive/views/archive_browser_view.h index d06e27e8cb..f87d59a2b1 100644 --- a/applications/main/archive/views/archive_browser_view.h +++ b/applications/main/archive/views/archive_browser_view.h @@ -115,7 +115,7 @@ typedef struct { int32_t list_offset; size_t scroll_counter; - uint32_t button_held_for_ticks; + int32_t button_held_for_ticks; } ArchiveBrowserViewModel; void archive_browser_set_callback( diff --git a/applications/services/gui/modules/file_browser.c b/applications/services/gui/modules/file_browser.c index e260d6080a..d934cccc8f 100644 --- a/applications/services/gui/modules/file_browser.c +++ b/applications/services/gui/modules/file_browser.c @@ -144,7 +144,7 @@ typedef struct { bool hide_ext; size_t scroll_counter; - uint32_t button_held_for_ticks; + int32_t button_held_for_ticks; } FileBrowserModel; static const Icon* BrowserItemIcons[] = { @@ -332,12 +332,6 @@ static bool browser_is_list_load_required(FileBrowserModel* model) { return false; } -static void browser_list_rollover(FileBrowserModel* model) { - if(!model->list_loading && items_array_size(model->items) < model->item_cnt) { - items_array_reset(model->items); - } -} - static void browser_update_offset(FileBrowser* browser) { furi_assert(browser); @@ -420,7 +414,7 @@ static void browser_list_load_cb(void* context, uint32_t list_load_offset) { } } }, - false); + true); BrowserItem_t_clear(&back_item); } @@ -465,15 +459,14 @@ static void browser_list_item_cb( (browser->hide_ext) && (item.type == BrowserItemTypeFile)); } - // We shouldn't update screen on each item if custom callback is not set - // Otherwise it will cause screen flickering - bool instant_update = (browser->item_callback != NULL); with_view_model( browser->view, FileBrowserModel * model, - { items_array_push_back(model->items, item); }, - instant_update); - + { + items_array_push_back(model->items, item); + // TODO: calculate if element is visible + }, + false); furi_string_free(item.display_name); furi_string_free(item.path); if(item.custom_icon_data) { @@ -484,33 +477,25 @@ static void browser_list_item_cb( browser->view, FileBrowserModel * model, { - model->list_loading = false; - if(browser_is_list_load_required(model)) { - model->list_loading = true; - int32_t load_offset = CLAMP( - model->item_idx - ITEM_LIST_LEN_MAX / 2, (int32_t)model->item_cnt, 0); - file_browser_worker_load(browser->worker, load_offset, ITEM_LIST_LEN_MAX); - - if(model->item_cnt <= BROWSER_SORT_THRESHOLD) { - FuriString* selected = NULL; - if(model->item_idx > 0) { - selected = furi_string_alloc_set( - items_array_get(model->items, model->item_idx)->path); - } + if(model->item_cnt <= BROWSER_SORT_THRESHOLD) { + FuriString* selected = NULL; + if(model->item_idx > 0) { + selected = furi_string_alloc_set( + items_array_get(model->items, model->item_idx)->path); + } - items_array_sort(model->items); + items_array_sort(model->items); - if(selected != NULL) { - for(uint32_t i = 0; i < model->item_cnt; i++) { - if(!furi_string_cmp( - items_array_get(model->items, i)->path, selected)) { - model->item_idx = i; - break; - } + if(selected != NULL) { + for(uint32_t i = 0; i < model->item_cnt; i++) { + if(!furi_string_cmp(items_array_get(model->items, i)->path, selected)) { + model->item_idx = i; + break; } } } } + model->list_loading = false; }, false); browser_update_offset(browser); @@ -680,19 +665,24 @@ static bool file_browser_view_input_callback(InputEvent* event, void* context) { } else { scroll_speed = model->button_held_for_ticks > 9 ? 5 : 3; } + } else if(model->button_held_for_ticks < 0) { + scroll_speed = 0; } if(event->key == InputKeyUp) { if(model->item_idx < scroll_speed) { - model->button_held_for_ticks = 0; - model->item_idx = model->item_cnt - 1; - browser_list_rollover(model); - } else { - model->item_idx = - ((model->item_idx - scroll_speed) + model->item_cnt) % - model->item_cnt; + scroll_speed = model->item_idx; + if(scroll_speed == 0) { + if(model->button_held_for_ticks > 0) { + model->button_held_for_ticks = -1; + } else { + scroll_speed = 1; + } + } } + model->item_idx = + ((model->item_idx - scroll_speed) + model->item_cnt) % model->item_cnt; if(browser_is_list_load_required(model)) { model->list_loading = true; int32_t load_offset = CLAMP( @@ -704,16 +694,24 @@ static bool file_browser_view_input_callback(InputEvent* event, void* context) { } model->scroll_counter = 0; + if(model->button_held_for_ticks < -1) { + model->button_held_for_ticks = 0; + } model->button_held_for_ticks += 1; } else if(event->key == InputKeyDown) { - if(model->item_idx + scroll_speed >= (int32_t)model->item_cnt) { - model->button_held_for_ticks = 0; - model->item_idx = 0; - browser_list_rollover(model); - } else { - model->item_idx = (model->item_idx + scroll_speed) % model->item_cnt; + int32_t count = model->item_cnt; + if(model->item_idx + scroll_speed >= count) { + scroll_speed = count - model->item_idx - 1; + if(scroll_speed == 0) { + if(model->button_held_for_ticks > 0) { + model->button_held_for_ticks = -1; + } else { + scroll_speed = 1; + } + } } + model->item_idx = (model->item_idx + scroll_speed) % model->item_cnt; if(browser_is_list_load_required(model)) { model->list_loading = true; int32_t load_offset = CLAMP( @@ -725,6 +723,9 @@ static bool file_browser_view_input_callback(InputEvent* event, void* context) { } model->scroll_counter = 0; + if(model->button_held_for_ticks < -1) { + model->button_held_for_ticks = 0; + } model->button_held_for_ticks += 1; } },