diff --git a/applications/main/archive/helpers/archive_browser.c b/applications/main/archive/helpers/archive_browser.c index 01ba4a994..4155c0afb 100644 --- a/applications/main/archive/helpers/archive_browser.c +++ b/applications/main/archive/helpers/archive_browser.c @@ -64,7 +64,13 @@ static void archive_add_file_item(browser, is_folder, furi_string_get_cstr(item_path)); } else { with_view_model( - browser->view, ArchiveBrowserViewModel * model, { model->list_loading = false; }, true); + browser->view, + ArchiveBrowserViewModel * model, + { + files_array_sort(model->files); + model->list_loading = false; + }, + true); } } diff --git a/applications/main/archive/helpers/archive_files.h b/applications/main/archive/helpers/archive_files.h index d2cd93a66..db624f5b5 100644 --- a/applications/main/archive/helpers/archive_files.h +++ b/applications/main/archive/helpers/archive_files.h @@ -2,6 +2,8 @@ #include #include +#include +#include #include #include "toolbox/path.h" @@ -81,13 +83,26 @@ static void ArchiveFile_t_clear(ArchiveFile_t* obj) { furi_string_free(obj->custom_name); } -ARRAY_DEF( - files_array, - ArchiveFile_t, - (INIT(API_2(ArchiveFile_t_init)), - SET(API_6(ArchiveFile_t_set)), - INIT_SET(API_6(ArchiveFile_t_init_set)), - CLEAR(API_2(ArchiveFile_t_clear)))) +static int ArchiveFile_t_cmp(const ArchiveFile_t* a, const ArchiveFile_t* b) { + if(a->type == ArchiveFileTypeFolder && b->type != ArchiveFileTypeFolder) { + return -1; + } + + return furi_string_cmp(a->path, b->path); +} + +#define M_OPL_ArchiveFile_t() \ + (INIT(API_2(ArchiveFile_t_init)), \ + SET(API_6(ArchiveFile_t_set)), \ + INIT_SET(API_6(ArchiveFile_t_init_set)), \ + CLEAR(API_2(ArchiveFile_t_clear)), \ + CMP(API_6(ArchiveFile_t_cmp)), \ + SWAP(M_SWAP_DEFAULT), \ + EQUAL(API_6(M_EQUAL_DEFAULT))) + +ARRAY_DEF(files_array, ArchiveFile_t) + +ALGO_DEF(files_array, ARRAY_OPLIST(files_array, M_OPL_ArchiveFile_t())) void archive_set_file_type(ArchiveFile_t* file, const char* path, bool is_folder, bool is_app); bool archive_get_items(void* context, const char* path); diff --git a/applications/services/gui/modules/file_browser.c b/applications/services/gui/modules/file_browser.c index 60e78b01c..fa119f128 100644 --- a/applications/services/gui/modules/file_browser.c +++ b/applications/services/gui/modules/file_browser.c @@ -5,6 +5,8 @@ #include #include #include "furi_hal_resources.h" +#include "m-string.h" +#include "m-algo.h" #include #include #include @@ -71,13 +73,29 @@ static void BrowserItem_t_clear(BrowserItem_t* obj) { } } -ARRAY_DEF( - items_array, - BrowserItem_t, - (INIT(API_2(BrowserItem_t_init)), - SET(API_6(BrowserItem_t_set)), - INIT_SET(API_6(BrowserItem_t_init_set)), - CLEAR(API_2(BrowserItem_t_clear)))) +static int BrowserItem_t_cmp(const BrowserItem_t* a, const BrowserItem_t* b) { + // Back indicator comes before everything, then folders, then all other files. + if((a->type == BrowserItemTypeBack) || + (a->type == BrowserItemTypeFolder && b->type != BrowserItemTypeFolder && + b->type != BrowserItemTypeBack)) { + return -1; + } + + return furi_string_cmp(a->path, b->path); +} + +#define M_OPL_BrowserItem_t() \ + (INIT(API_2(BrowserItem_t_init)), \ + SET(API_6(BrowserItem_t_set)), \ + INIT_SET(API_6(BrowserItem_t_init_set)), \ + CLEAR(API_2(BrowserItem_t_clear)), \ + CMP(API_6(BrowserItem_t_cmp)), \ + SWAP(M_SWAP_DEFAULT), \ + EQUAL(API_6(M_EQUAL_DEFAULT))) + +ARRAY_DEF(items_array, BrowserItem_t) + +ALGO_DEF(items_array, ARRAY_OPLIST(items_array, M_OPL_BrowserItem_t())) struct FileBrowser { View* view; @@ -388,7 +406,13 @@ static void } } else { with_view_model( - browser->view, FileBrowserModel * model, { model->list_loading = false; }, true); + browser->view, + FileBrowserModel * model, + { + items_array_sort(model->items); + model->list_loading = false; + }, + true); } }