From 7f4b586b131a927c084f3ddb054917c91e776456 Mon Sep 17 00:00:00 2001 From: Der Skythe Date: Thu, 15 Sep 2022 22:00:51 +0400 Subject: [PATCH 01/10] Init archive app with Rename, normal context menu and file info --- applications/main/archive/archive.c | 28 ++- applications/main/archive/archive_i.h | 7 + .../main/archive/helpers/archive_browser.c | 1 + .../main/archive/helpers/archive_files.c | 35 +++ .../main/archive/helpers/archive_files.h | 2 + .../main/archive/helpers/archive_menu.h | 52 +++++ .../archive/scenes/archive_scene_browser.c | 8 +- .../archive/scenes/archive_scene_config.h | 1 + .../archive/scenes/archive_scene_delete.c | 4 - .../main/archive/scenes/archive_scene_info.c | 78 +++++++ .../archive/scenes/archive_scene_rename.c | 68 ++++-- .../main/archive/views/archive_browser_view.c | 217 +++++++++++++----- .../main/archive/views/archive_browser_view.h | 15 +- 13 files changed, 424 insertions(+), 92 deletions(-) create mode 100644 applications/main/archive/helpers/archive_menu.h create mode 100644 applications/main/archive/scenes/archive_scene_info.c diff --git a/applications/main/archive/archive.c b/applications/main/archive/archive.c index bbe532c8c..93689a345 100644 --- a/applications/main/archive/archive.c +++ b/applications/main/archive/archive.c @@ -1,5 +1,4 @@ #include "archive_i.h" -#include "m-string.h" bool archive_custom_event_callback(void* context, uint32_t event) { furi_assert(context); @@ -17,6 +16,7 @@ ArchiveApp* archive_alloc() { ArchiveApp* archive = malloc(sizeof(ArchiveApp)); archive->gui = furi_record_open(RECORD_GUI); + archive->dialogs = furi_record_open(RECORD_DIALOGS); archive->text_input = text_input_alloc(); string_init(archive->fav_move_str); @@ -45,12 +45,21 @@ ArchiveApp* archive_alloc() { view_dispatcher_add_view( archive->view_dispatcher, ArchiveViewWidget, widget_get_view(archive->widget)); + // Loading + archive->loading = loading_alloc(); + view_dispatcher_add_view( + archive->view_dispatcher, ArchiveViewLoading, loading_get_view(archive->loading)); + return archive; } void archive_free(ArchiveApp* archive) { furi_assert(archive); + // Loading + view_dispatcher_remove_view(archive->view_dispatcher, ArchiveViewLoading); + loading_free(archive->loading); + view_dispatcher_remove_view(archive->view_dispatcher, ArchiveViewBrowser); view_dispatcher_remove_view(archive->view_dispatcher, ArchiveViewTextInput); view_dispatcher_remove_view(archive->view_dispatcher, ArchiveViewWidget); @@ -62,12 +71,29 @@ void archive_free(ArchiveApp* archive) { text_input_free(archive->text_input); + furi_record_close(RECORD_DIALOGS); + archive->dialogs = NULL; + furi_record_close(RECORD_GUI); archive->gui = NULL; free(archive); } +void archive_show_loading_popup(void* context, bool show) { + ArchiveApp* instance = context; + TaskHandle_t timer_task = xTaskGetHandle(configTIMER_SERVICE_TASK_NAME); + + if(show) { + // Raise timer priority so that animations can play + vTaskPrioritySet(timer_task, configMAX_PRIORITIES - 1); + view_dispatcher_switch_to_view(instance->view_dispatcher, ArchiveViewLoading); + } else { + // Restore default timer priority + vTaskPrioritySet(timer_task, configTIMER_TASK_PRIORITY); + } +} + int32_t archive_app(void* p) { UNUSED(p); ArchiveApp* archive = archive_alloc(); diff --git a/applications/main/archive/archive_i.h b/applications/main/archive/archive_i.h index 865e837dc..3020b1753 100644 --- a/applications/main/archive/archive_i.h +++ b/applications/main/archive/archive_i.h @@ -8,6 +8,8 @@ #include #include #include +#include +#include #include #include "views/archive_browser_view.h" @@ -18,6 +20,7 @@ typedef enum { ArchiveViewTextInput, ArchiveViewWidget, ArchiveViewTotal, + ArchiveViewLoading, } ArchiveViewEnum; struct ArchiveApp { @@ -27,8 +30,12 @@ struct ArchiveApp { ArchiveBrowserView* browser; TextInput* text_input; Widget* widget; + DialogsApp* dialogs; + Loading* loading; FuriPubSubSubscription* loader_stop_subscription; string_t fav_move_str; char text_store[MAX_NAME_LEN]; char file_extension[MAX_EXT_LEN + 1]; }; + +void archive_show_loading_popup(void* context, bool show); \ No newline at end of file diff --git a/applications/main/archive/helpers/archive_browser.c b/applications/main/archive/helpers/archive_browser.c index b08e58983..01a1c888c 100644 --- a/applications/main/archive/helpers/archive_browser.c +++ b/applications/main/archive/helpers/archive_browser.c @@ -377,6 +377,7 @@ void archive_show_file_menu(ArchiveBrowserView* browser, bool show) { if(archive_is_item_in_array(model, model->item_idx)) { model->menu = true; model->menu_idx = 0; + menu_array_reset(model->context_menu); ArchiveFile_t* selected = files_array_get(model->files, model->item_idx - model->array_offset); selected->fav = archive_is_favorite("%s", string_get_cstr(selected->path)); diff --git a/applications/main/archive/helpers/archive_files.c b/applications/main/archive/helpers/archive_files.c index 9f8b4ee1b..e67fbb74d 100644 --- a/applications/main/archive/helpers/archive_files.c +++ b/applications/main/archive/helpers/archive_files.c @@ -109,3 +109,38 @@ void archive_delete_file(void* context, const char* format, ...) { string_clear(filename); } + +FS_Error archive_rename_file_or_dir(void* context, const char* src_path, const char* dst_path) { + furi_assert(context); + + FURI_LOG_I(TAG, "Rename from %s to %s", src_path, dst_path); + + ArchiveBrowserView* browser = context; + Storage* fs_api = furi_record_open(RECORD_STORAGE); + + FileInfo fileinfo; + storage_common_stat(fs_api, src_path, &fileinfo); + + FS_Error error = FSE_OK; + + if(!path_contains_only_ascii(dst_path)) { + error = FSE_INVALID_NAME; + } else { + error = storage_common_rename(fs_api, src_path, dst_path); + } + furi_record_close(RECORD_STORAGE); + + if(archive_is_favorite("%s", src_path)) { + archive_favorites_rename(src_path, dst_path); + } + + if(error == FSE_OK) { + FURI_LOG_I(TAG, "Rename from %s to %s is DONE", src_path, dst_path); + archive_refresh_dir(browser); + } else { + const char* error_msg = filesystem_api_error_get_desc(error); + FURI_LOG_E(TAG, "Rename failed: %s, Code: %d", error_msg, error); + } + + return error; +} diff --git a/applications/main/archive/helpers/archive_files.h b/applications/main/archive/helpers/archive_files.h index 84b7e24a6..d4df327a9 100644 --- a/applications/main/archive/helpers/archive_files.h +++ b/applications/main/archive/helpers/archive_files.h @@ -3,6 +3,7 @@ #include #include #include +#include "toolbox/path.h" typedef enum { ArchiveFileTypeIButton, @@ -62,3 +63,4 @@ void archive_set_file_type(ArchiveFile_t* file, const char* path, bool is_folder bool archive_get_items(void* context, const char* path); void archive_file_append(const char* path, const char* format, ...); void archive_delete_file(void* context, const char* format, ...); +FS_Error archive_rename_file_or_dir(void* context, const char* src_path, const char* dst_path); diff --git a/applications/main/archive/helpers/archive_menu.h b/applications/main/archive/helpers/archive_menu.h new file mode 100644 index 000000000..5df6a1ca2 --- /dev/null +++ b/applications/main/archive/helpers/archive_menu.h @@ -0,0 +1,52 @@ +#pragma once + +#include +#include + +typedef struct { + string_t text; + uint32_t event; +} ArchiveContextMenuItem_t; + +static void ArchiveContextMenuItem_t_init(ArchiveContextMenuItem_t* obj) { + string_init(obj->text); + obj->event = 0; // ArchiveBrowserEventFileMenuNone +} + +static void ArchiveContextMenuItem_t_init_set( + ArchiveContextMenuItem_t* obj, + const ArchiveContextMenuItem_t* src) { + string_init_set(obj->text, src->text); + obj->event = src->event; +} + +static void ArchiveContextMenuItem_t_set( + ArchiveContextMenuItem_t* obj, + const ArchiveContextMenuItem_t* src) { + string_init_set(obj->text, src->text); + obj->event = src->event; +} + +static void ArchiveContextMenuItem_t_clear(ArchiveContextMenuItem_t* obj) { + string_clear(obj->text); +} + +ARRAY_DEF( + menu_array, + ArchiveContextMenuItem_t, + (INIT(API_2(ArchiveContextMenuItem_t_init)), + SET(API_6(ArchiveContextMenuItem_t_set)), + INIT_SET(API_6(ArchiveContextMenuItem_t_init_set)), + CLEAR(API_2(ArchiveContextMenuItem_t_clear)))) + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-function" +// Using in applications/archive/views/archive_browser_view.c +static void archive_menu_add_item( + ArchiveContextMenuItem_t* obj, + string_t text, + uint32_t event) { + string_init_move(obj->text, text); + obj->event = event; +} +#pragma GCC diagnostic pop \ No newline at end of file diff --git a/applications/main/archive/scenes/archive_scene_browser.c b/applications/main/archive/scenes/archive_scene_browser.c index e22ac792f..06e86941e 100644 --- a/applications/main/archive/scenes/archive_scene_browser.c +++ b/applications/main/archive/scenes/archive_scene_browser.c @@ -132,7 +132,9 @@ bool archive_scene_browser_on_event(void* context, SceneManagerEvent event) { case ArchiveBrowserEventFileMenuRename: if(favorites) { browser->callback(ArchiveBrowserEventEnterFavMove, browser->context); - } else if((archive_is_known_app(selected->type)) && (selected->is_app == false)) { + //} else if((archive_is_known_app(selected->type)) && (selected->is_app == false)) { + } else { + // Added ability to rename files and folders archive_show_file_menu(browser, false); scene_manager_set_scene_state( archive->scene_manager, ArchiveAppSceneBrowser, SCENE_STATE_NEED_REFRESH); @@ -140,6 +142,10 @@ bool archive_scene_browser_on_event(void* context, SceneManagerEvent event) { } consumed = true; break; + case ArchiveBrowserEventFileMenuInfo: + scene_manager_next_scene(archive->scene_manager, ArchiveAppSceneInfo); + consumed = true; + break; case ArchiveBrowserEventFileMenuDelete: if(archive_get_tab(browser) != ArchiveTabFavorites) { scene_manager_next_scene(archive->scene_manager, ArchiveAppSceneDelete); diff --git a/applications/main/archive/scenes/archive_scene_config.h b/applications/main/archive/scenes/archive_scene_config.h index 4145f43da..6dda7a20d 100644 --- a/applications/main/archive/scenes/archive_scene_config.h +++ b/applications/main/archive/scenes/archive_scene_config.h @@ -1,3 +1,4 @@ ADD_SCENE(archive, browser, Browser) ADD_SCENE(archive, rename, Rename) ADD_SCENE(archive, delete, Delete) +ADD_SCENE(archive, info, Info) diff --git a/applications/main/archive/scenes/archive_scene_delete.c b/applications/main/archive/scenes/archive_scene_delete.c index d882fd066..cca84fea3 100644 --- a/applications/main/archive/scenes/archive_scene_delete.c +++ b/applications/main/archive/scenes/archive_scene_delete.c @@ -1,10 +1,6 @@ #include "../archive_i.h" -#include "../helpers/archive_favorites.h" -#include "../helpers/archive_files.h" #include "../helpers/archive_apps.h" #include "../helpers/archive_browser.h" -#include "toolbox/path.h" -#include "m-string.h" #define SCENE_DELETE_CUSTOM_EVENT (0UL) #define MAX_TEXT_INPUT_LEN 22 diff --git a/applications/main/archive/scenes/archive_scene_info.c b/applications/main/archive/scenes/archive_scene_info.c new file mode 100644 index 000000000..a69274802 --- /dev/null +++ b/applications/main/archive/scenes/archive_scene_info.c @@ -0,0 +1,78 @@ +#include "../archive_i.h" +#include "../helpers/archive_browser.h" + +#define TAG "Archive" + +void archive_scene_info_widget_callback(GuiButtonType result, InputType type, void* context) { + furi_assert(context); + ArchiveApp* app = (ArchiveApp*)context; + if(type == InputTypeShort) { + view_dispatcher_send_custom_event(app->view_dispatcher, result); + } +} + +void archive_scene_info_on_enter(void* context) { + furi_assert(context); + ArchiveApp* app = (ArchiveApp*)context; + + widget_add_button_element( + app->widget, GuiButtonTypeLeft, "Back", archive_scene_info_widget_callback, app); + + string_t filename; + string_t dirname; + string_t str_size; + string_init(filename); + string_init(dirname); + string_init(str_size); + + ArchiveFile_t* current = archive_get_current_file(app->browser); + char file_info_message[128]; + Storage* fs_api = furi_record_open(RECORD_STORAGE); + + // Filename + path_extract_filename(current->path, filename, false); + snprintf(file_info_message, sizeof(file_info_message), "\e#%s\e#", string_get_cstr(filename)); + widget_add_text_box_element( + app->widget, 0, 0, 128, 20, AlignLeft, AlignCenter, file_info_message, false); + + // File size + FileInfo fileinfo; + storage_common_stat(fs_api, string_get_cstr(current->path), &fileinfo); + string_printf(str_size, "%d", fileinfo.size / 1024); + snprintf( + file_info_message, + sizeof(file_info_message), + "Size: \e#%s\e# Kb.", + string_get_cstr(str_size)); + widget_add_text_box_element( + app->widget, 0, 23, 128, 20, AlignLeft, AlignCenter, file_info_message, false); + + // Directory path + path_extract_dirname(string_get_cstr(current->path), dirname); + string_replace_str(dirname, STORAGE_ANY_PATH_PREFIX, ""); + widget_add_text_box_element( + app->widget, 0, 23, 128, 20, AlignLeft, AlignCenter, string_get_cstr(dirname), false); + + string_clear(filename); + string_clear(dirname); + string_clear(str_size); + + view_dispatcher_switch_to_view(app->view_dispatcher, ArchiveViewWidget); +} + +bool archive_scene_info_on_event(void* context, SceneManagerEvent event) { + furi_assert(context); + ArchiveApp* app = (ArchiveApp*)context; + + if(event.type == SceneManagerEventTypeCustom) { + return scene_manager_previous_scene(app->scene_manager); + } + return false; +} + +void archive_scene_info_on_exit(void* context) { + furi_assert(context); + ArchiveApp* app = (ArchiveApp*)context; + + widget_reset(app->widget); +} diff --git a/applications/main/archive/scenes/archive_scene_rename.c b/applications/main/archive/scenes/archive_scene_rename.c index 293fa89af..6e4a65ec4 100644 --- a/applications/main/archive/scenes/archive_scene_rename.c +++ b/applications/main/archive/scenes/archive_scene_rename.c @@ -4,6 +4,9 @@ #include "../helpers/archive_browser.h" #include "archive/views/archive_browser_view.h" #include "toolbox/path.h" +#include + +#define TAG "Archive" #define SCENE_RENAME_CUSTOM_EVENT (0UL) #define MAX_TEXT_INPUT_LEN 22 @@ -19,14 +22,24 @@ void archive_scene_rename_on_enter(void* context) { TextInput* text_input = archive->text_input; ArchiveFile_t* current = archive_get_current_file(archive->browser); - string_t filename; - string_init(filename); - path_extract_filename(current->path, filename, true); - strlcpy(archive->text_store, string_get_cstr(filename), MAX_NAME_LEN); + string_t path_name; + string_init(path_name); - path_extract_extension(current->path, archive->file_extension, MAX_EXT_LEN); + if(current->type == ArchiveFileTypeFolder) { + path_extract_basename(string_get_cstr(current->path), path_name); + strlcpy(archive->text_store, string_get_cstr(path_name), MAX_NAME_LEN); + text_input_set_header_text(text_input, "Rename directory:"); + } else /*if(current->type != ArchiveFileTypeUnknown) */ { + path_extract_filename(current->path, path_name, true); + strlcpy(archive->text_store, string_get_cstr(path_name), MAX_NAME_LEN); - text_input_set_header_text(text_input, "Rename:"); + path_extract_extension(current->path, archive->file_extension, MAX_EXT_LEN); + text_input_set_header_text(text_input, "Rename file:"); + } /*else { + path_extract_filename(current->path, path_name, false); + strlcpy(archive->text_store, string_get_cstr(path_name), MAX_NAME_LEN); + text_input_set_header_text(text_input, "Rename unknown file:"); + }*/ text_input_set_result_callback( text_input, @@ -36,11 +49,7 @@ void archive_scene_rename_on_enter(void* context) { MAX_TEXT_INPUT_LEN, false); - ValidatorIsFile* validator_is_file = validator_is_file_alloc_init( - string_get_cstr(archive->browser->path), archive->file_extension, ""); - text_input_set_validator(text_input, validator_is_file_callback, validator_is_file); - - string_clear(filename); + string_clear(path_name); view_dispatcher_switch_to_view(archive->view_dispatcher, ArchiveViewTextInput); } @@ -51,26 +60,43 @@ bool archive_scene_rename_on_event(void* context, SceneManagerEvent event) { if(event.type == SceneManagerEventTypeCustom) { if(event.event == SCENE_RENAME_CUSTOM_EVENT) { - Storage* fs_api = furi_record_open(RECORD_STORAGE); - const char* path_src = archive_get_name(archive->browser); ArchiveFile_t* file = archive_get_current_file(archive->browser); string_t path_dst; string_init(path_dst); - path_extract_dirname(path_src, path_dst); - string_cat_printf(path_dst, "/%s%s", archive->text_store, known_ext[file->type]); - storage_common_rename(fs_api, path_src, string_get_cstr(path_dst)); - furi_record_close(RECORD_STORAGE); - - if(file->fav) { - archive_favorites_rename(path_src, string_get_cstr(path_dst)); + if(file->type == ArchiveFileTypeFolder) { + // Rename folder/dir + path_extract_dirname(path_src, path_dst); + string_cat_printf(path_dst, "/%s", archive->text_store); + } else if(file->type != ArchiveFileTypeUnknown) { + // Rename known type + path_extract_dirname(path_src, path_dst); + string_cat_printf(path_dst, "/%s%s", archive->text_store, known_ext[file->type]); + } else { + // Rename unknown type + path_extract_dirname(path_src, path_dst); + string_cat_printf(path_dst, "/%s%s", archive->text_store, archive->file_extension); } + // Long time process if this is directory + archive_show_loading_popup(archive, true); + FS_Error error = + archive_rename_file_or_dir(archive->browser, path_src, string_get_cstr(path_dst)); + archive_show_loading_popup(archive, false); + archive_show_file_menu(archive->browser, false); string_clear(path_dst); - scene_manager_next_scene(archive->scene_manager, ArchiveAppSceneBrowser); + if(error != FSE_OK) { + string_t dialog_msg; + string_init(dialog_msg); + string_cat_printf(dialog_msg, "Cannot rename\nCode: %d", error); + dialog_message_show_storage_error(archive->dialogs, string_get_cstr(dialog_msg)); + string_clear(dialog_msg); + } else { + scene_manager_next_scene(archive->scene_manager, ArchiveAppSceneBrowser); + } consumed = true; } } diff --git a/applications/main/archive/views/archive_browser_view.c b/applications/main/archive/views/archive_browser_view.c index ddd6637db..d2720da12 100644 --- a/applications/main/archive/views/archive_browser_view.c +++ b/applications/main/archive/views/archive_browser_view.c @@ -5,6 +5,8 @@ #include "archive_browser_view.h" #include "../helpers/archive_browser.h" +#define TAG "Archive" + static const char* ArchiveTabNames[] = { [ArchiveTabFavorites] = "Favorites", [ArchiveTabIButton] = "iButton", @@ -42,43 +44,141 @@ void archive_browser_set_callback( } static void render_item_menu(Canvas* canvas, ArchiveBrowserViewModel* model) { - canvas_set_color(canvas, ColorWhite); - canvas_draw_box(canvas, 71, 17, 57, 46); - canvas_set_color(canvas, ColorBlack); - elements_slightly_rounded_frame(canvas, 70, 16, 58, 48); + if(menu_array_size(model->context_menu) == 0) { + // Context menu is empty, init array + string_t item_run; + string_t item_pin; + string_t item_info; + string_t item_rename; + string_t item_delete; - string_t menu[MENU_ITEMS]; + string_init_set_str(item_run, "Run In App"); + string_init_set_str(item_pin, "Pin"); + string_init_set_str(item_info, "Info"); + string_init_set_str(item_rename, "Rename"); + string_init_set_str(item_delete, "Delete"); - string_init_set_str(menu[0], "Run in app"); - string_init_set_str(menu[1], "Pin"); - string_init_set_str(menu[2], "Rename"); - string_init_set_str(menu[3], "Delete"); + // Need init context menu + ArchiveFile_t* selected = + files_array_get(model->files, model->item_idx - model->array_offset); - ArchiveFile_t* selected = files_array_get(model->files, model->item_idx - model->array_offset); - - if((selected->fav) || (model->tab_idx == ArchiveTabFavorites)) { - string_set_str(menu[1], "Unpin"); - } - - if(!archive_is_known_app(selected->type)) { - string_set_str(menu[0], "---"); - string_set_str(menu[1], "---"); - string_set_str(menu[2], "---"); - } else { - if(model->tab_idx == ArchiveTabFavorites) { - string_set_str(menu[2], "Move"); - string_set_str(menu[3], "---"); - } else if(selected->is_app) { - string_set_str(menu[2], "---"); + if((selected->fav) || (model->tab_idx == ArchiveTabFavorites)) { + string_set_str(item_pin, "Unpin"); } + + if (selected->type == ArchiveFileTypeFolder) { + FURI_LOG_D(TAG, "Directory type"); + archive_menu_add_item( + menu_array_push_raw(model->context_menu), + item_rename, + ArchiveBrowserEventFileMenuRename); + archive_menu_add_item( + menu_array_push_raw(model->context_menu), + item_delete, + ArchiveBrowserEventFileMenuDelete); + } else if(!archive_is_known_app(selected->type)) { + FURI_LOG_D(TAG, "Unknown type"); + + archive_menu_add_item( + menu_array_push_raw(model->context_menu), + item_info, + ArchiveBrowserEventFileMenuInfo); + archive_menu_add_item( + menu_array_push_raw(model->context_menu), + item_rename, + ArchiveBrowserEventFileMenuRename); + archive_menu_add_item( + menu_array_push_raw(model->context_menu), + item_delete, + ArchiveBrowserEventFileMenuDelete); + } else if(model->tab_idx == ArchiveTabFavorites) { + FURI_LOG_D(TAG, "ArchiveTabFavorites"); + + string_set_str(item_rename, "Move"); + + archive_menu_add_item( + menu_array_push_raw(model->context_menu), + item_run, + ArchiveBrowserEventFileMenuRun); + archive_menu_add_item( + menu_array_push_raw(model->context_menu), + item_pin, + ArchiveBrowserEventFileMenuPin); + archive_menu_add_item( + menu_array_push_raw(model->context_menu), + item_rename, + ArchiveBrowserEventFileMenuRename); + } else if(selected->is_app) { + FURI_LOG_D(TAG, "3 types"); + archive_menu_add_item( + menu_array_push_raw(model->context_menu), + item_run, + ArchiveBrowserEventFileMenuRun); + archive_menu_add_item( + menu_array_push_raw(model->context_menu), + item_info, + ArchiveBrowserEventFileMenuInfo); + archive_menu_add_item( + menu_array_push_raw(model->context_menu), + item_pin, + ArchiveBrowserEventFileMenuPin); + archive_menu_add_item( + menu_array_push_raw(model->context_menu), + item_delete, + ArchiveBrowserEventFileMenuDelete); + } else { + FURI_LOG_D(TAG, "All menu"); + archive_menu_add_item( + menu_array_push_raw(model->context_menu), + item_run, + ArchiveBrowserEventFileMenuRun); + archive_menu_add_item( + menu_array_push_raw(model->context_menu), + item_pin, + ArchiveBrowserEventFileMenuPin); + archive_menu_add_item( + menu_array_push_raw(model->context_menu), + item_rename, + ArchiveBrowserEventFileMenuRename); + archive_menu_add_item( + menu_array_push_raw(model->context_menu), + item_delete, + ArchiveBrowserEventFileMenuDelete); + } + + string_clear(item_run); + string_clear(item_pin); + string_clear(item_info); + string_clear(item_rename); + string_clear(item_delete); + } else { + FURI_LOG_D( + TAG, + "menu_array_size already set: %d", + menu_array_size(model->context_menu)); + } + size_t size_menu = menu_array_size(model->context_menu); + const uint8_t menu_height = 44; + const uint8_t line_height = 11; + + canvas_set_color(canvas, ColorWhite); + uint8_t calc_height = menu_height - ((MENU_ITEMS - size_menu) * line_height); + canvas_draw_box(canvas, 71, 17, 57, calc_height + 2); + canvas_set_color(canvas, ColorBlack); + elements_slightly_rounded_frame(canvas, 70, 16, 58, calc_height + 4); + + FURI_LOG_D( + TAG, + "size_menu: %d, calc_height: %d, menu_idx: %d", + size_menu, + calc_height, + model->menu_idx); + for(size_t i = 0; i < size_menu; i++) { + ArchiveContextMenuItem_t* current = menu_array_get(model->context_menu, i); + canvas_draw_str(canvas, 82, 27 + i * line_height, string_get_cstr(current->text)); } - for(size_t i = 0; i < MENU_ITEMS; i++) { - canvas_draw_str(canvas, 82, 27 + i * 11, string_get_cstr(menu[i])); - string_clear(menu[i]); - } - - canvas_draw_icon(canvas, 74, 20 + model->menu_idx * 11, &I_ButtonRight_4x7); + canvas_draw_icon(canvas, 74, 20 + model->menu_idx * line_height, &I_ButtonRight_4x7); } static void archive_draw_frame(Canvas* canvas, uint16_t idx, bool scrollbar, bool moving) { @@ -250,32 +350,33 @@ static bool archive_view_input(InputEvent* event, void* context) { }); if(in_menu) { - if(event->type == InputTypeShort) { - if(event->key == InputKeyUp || event->key == InputKeyDown) { - with_view_model( - browser->view, (ArchiveBrowserViewModel * model) { - if(event->key == InputKeyUp) { - model->menu_idx = ((model->menu_idx - 1) + MENU_ITEMS) % MENU_ITEMS; - } else if(event->key == InputKeyDown) { - model->menu_idx = (model->menu_idx + 1) % MENU_ITEMS; - } - return true; - }); - } - - if(event->key == InputKeyOk) { - uint8_t idx; - with_view_model( - browser->view, (ArchiveBrowserViewModel * model) { - idx = model->menu_idx; - return false; - }); - browser->callback(file_menu_actions[idx], browser->context); - } else if(event->key == InputKeyBack) { - browser->callback(ArchiveBrowserEventFileMenuClose, browser->context); - } + if(event->type != InputTypeShort) { + return true; // RETURN + } + if(event->key == InputKeyUp || event->key == InputKeyDown) { + with_view_model( + browser->view, (ArchiveBrowserViewModel * model) { + size_t size_menu = menu_array_size(model->context_menu); + if(event->key == InputKeyUp) { + model->menu_idx = ((model->menu_idx - 1) + size_menu) % size_menu; + } else if(event->key == InputKeyDown) { + model->menu_idx = (model->menu_idx + 1) % size_menu; + } + return true; + }); + } else if(event->key == InputKeyOk) { + uint32_t idx; + with_view_model( + browser->view, (ArchiveBrowserViewModel * model) { + ArchiveContextMenuItem_t* current = + menu_array_get(model->context_menu, model->menu_idx); + idx = current->event; + return false; + }); + browser->callback(idx, browser->context); + } else if(event->key == InputKeyBack) { + browser->callback(ArchiveBrowserEventFileMenuClose, browser->context); } - } else { if(event->type == InputTypeShort) { if(event->key == InputKeyLeft || event->key == InputKeyRight) { @@ -366,6 +467,7 @@ ArchiveBrowserView* browser_alloc() { with_view_model( browser->view, (ArchiveBrowserViewModel * model) { files_array_init(model->files); + menu_array_init(model->context_menu); model->tab_idx = TAB_DEFAULT; return true; }); @@ -383,6 +485,7 @@ void browser_free(ArchiveBrowserView* browser) { with_view_model( browser->view, (ArchiveBrowserViewModel * model) { files_array_clear(model->files); + menu_array_clear(model->context_menu); return false; }); @@ -390,4 +493,4 @@ void browser_free(ArchiveBrowserView* browser) { view_free(browser->view); free(browser); -} +} \ No newline at end of file diff --git a/applications/main/archive/views/archive_browser_view.h b/applications/main/archive/views/archive_browser_view.h index 5c649c389..838d2505d 100644 --- a/applications/main/archive/views/archive_browser_view.h +++ b/applications/main/archive/views/archive_browser_view.h @@ -7,6 +7,7 @@ #include #include #include "../helpers/archive_files.h" +#include "../helpers/archive_menu.h" #include "../helpers/archive_favorites.h" #include "gui/modules/file_browser_worker.h" @@ -31,12 +32,14 @@ typedef enum { } ArchiveTabEnum; typedef enum { + ArchiveBrowserEventFileMenuNone, ArchiveBrowserEventFileMenuOpen, - ArchiveBrowserEventFileMenuClose, ArchiveBrowserEventFileMenuRun, ArchiveBrowserEventFileMenuPin, ArchiveBrowserEventFileMenuRename, ArchiveBrowserEventFileMenuDelete, + ArchiveBrowserEventFileMenuInfo, + ArchiveBrowserEventFileMenuClose, ArchiveBrowserEventEnterDir, @@ -54,13 +57,6 @@ typedef enum { ArchiveBrowserEventExit, } ArchiveBrowserEvent; -static const uint8_t file_menu_actions[MENU_ITEMS] = { - [0] = ArchiveBrowserEventFileMenuRun, - [1] = ArchiveBrowserEventFileMenuPin, - [2] = ArchiveBrowserEventFileMenuRename, - [3] = ArchiveBrowserEventFileMenuDelete, -}; - typedef struct ArchiveBrowserView ArchiveBrowserView; typedef void (*ArchiveBrowserViewCallback)(ArchiveBrowserEvent event, void* context); @@ -88,6 +84,8 @@ typedef struct { uint8_t menu_idx; bool menu; + menu_array_t context_menu; + bool move_fav; bool list_loading; bool folder_loading; @@ -106,4 +104,5 @@ void archive_browser_set_callback( View* archive_browser_get_view(ArchiveBrowserView* browser); ArchiveBrowserView* browser_alloc(); + void browser_free(ArchiveBrowserView* browser); From 1fd92404815249ef5f0e694369302f3647db5fa8 Mon Sep 17 00:00:00 2001 From: Der Skythe Date: Thu, 15 Sep 2022 23:33:43 +0400 Subject: [PATCH 02/10] Add Info to all files, fix file info elements position --- .../archive/scenes/archive_scene_browser.c | 2 ++ .../main/archive/scenes/archive_scene_info.c | 23 ++++++++++--------- .../main/archive/views/archive_browser_view.c | 23 ++++++++++--------- .../main/archive/views/archive_browser_view.h | 2 +- 4 files changed, 27 insertions(+), 23 deletions(-) diff --git a/applications/main/archive/scenes/archive_scene_browser.c b/applications/main/archive/scenes/archive_scene_browser.c index 06e86941e..d77458c48 100644 --- a/applications/main/archive/scenes/archive_scene_browser.c +++ b/applications/main/archive/scenes/archive_scene_browser.c @@ -143,6 +143,8 @@ bool archive_scene_browser_on_event(void* context, SceneManagerEvent event) { consumed = true; break; case ArchiveBrowserEventFileMenuInfo: + scene_manager_set_scene_state( + archive->scene_manager, ArchiveAppSceneBrowser, SCENE_STATE_NEED_REFRESH); scene_manager_next_scene(archive->scene_manager, ArchiveAppSceneInfo); consumed = true; break; diff --git a/applications/main/archive/scenes/archive_scene_info.c b/applications/main/archive/scenes/archive_scene_info.c index a69274802..5af9acae5 100644 --- a/applications/main/archive/scenes/archive_scene_info.c +++ b/applications/main/archive/scenes/archive_scene_info.c @@ -33,7 +33,11 @@ void archive_scene_info_on_enter(void* context) { path_extract_filename(current->path, filename, false); snprintf(file_info_message, sizeof(file_info_message), "\e#%s\e#", string_get_cstr(filename)); widget_add_text_box_element( - app->widget, 0, 0, 128, 20, AlignLeft, AlignCenter, file_info_message, false); + app->widget, 0, 0, 128, 25, AlignLeft, AlignCenter, file_info_message, false); + + // Directory path + path_extract_dirname(string_get_cstr(current->path), dirname); + string_replace_str(dirname, STORAGE_ANY_PATH_PREFIX, ""); // File size FileInfo fileinfo; @@ -42,16 +46,12 @@ void archive_scene_info_on_enter(void* context) { snprintf( file_info_message, sizeof(file_info_message), - "Size: \e#%s\e# Kb.", - string_get_cstr(str_size)); + "Size: \e#%s\e# Kb.\n%s", + string_get_cstr(str_size), + string_get_cstr(dirname) + ); widget_add_text_box_element( - app->widget, 0, 23, 128, 20, AlignLeft, AlignCenter, file_info_message, false); - - // Directory path - path_extract_dirname(string_get_cstr(current->path), dirname); - string_replace_str(dirname, STORAGE_ANY_PATH_PREFIX, ""); - widget_add_text_box_element( - app->widget, 0, 23, 128, 20, AlignLeft, AlignCenter, string_get_cstr(dirname), false); + app->widget, 0, 25, 128, 25, AlignLeft, AlignCenter, file_info_message, false); string_clear(filename); string_clear(dirname); @@ -65,7 +65,8 @@ bool archive_scene_info_on_event(void* context, SceneManagerEvent event) { ArchiveApp* app = (ArchiveApp*)context; if(event.type == SceneManagerEventTypeCustom) { - return scene_manager_previous_scene(app->scene_manager); + scene_manager_next_scene(app->scene_manager, ArchiveAppSceneBrowser); + return true; } return false; } diff --git a/applications/main/archive/views/archive_browser_view.c b/applications/main/archive/views/archive_browser_view.c index d2720da12..4873b46cd 100644 --- a/applications/main/archive/views/archive_browser_view.c +++ b/applications/main/archive/views/archive_browser_view.c @@ -66,7 +66,7 @@ static void render_item_menu(Canvas* canvas, ArchiveBrowserViewModel* model) { string_set_str(item_pin, "Unpin"); } - if (selected->type == ArchiveFileTypeFolder) { + if(selected->type == ArchiveFileTypeFolder) { FURI_LOG_D(TAG, "Directory type"); archive_menu_add_item( menu_array_push_raw(model->context_menu), @@ -136,6 +136,10 @@ static void render_item_menu(Canvas* canvas, ArchiveBrowserViewModel* model) { menu_array_push_raw(model->context_menu), item_pin, ArchiveBrowserEventFileMenuPin); + archive_menu_add_item( + menu_array_push_raw(model->context_menu), + item_info, + ArchiveBrowserEventFileMenuInfo); archive_menu_add_item( menu_array_push_raw(model->context_menu), item_rename, @@ -152,20 +156,17 @@ static void render_item_menu(Canvas* canvas, ArchiveBrowserViewModel* model) { string_clear(item_rename); string_clear(item_delete); } else { - FURI_LOG_D( - TAG, - "menu_array_size already set: %d", - menu_array_size(model->context_menu)); + FURI_LOG_D(TAG, "menu_array_size already set: %d", menu_array_size(model->context_menu)); } size_t size_menu = menu_array_size(model->context_menu); - const uint8_t menu_height = 44; - const uint8_t line_height = 11; + const uint8_t menu_height = 48; + const uint8_t line_height = 10; canvas_set_color(canvas, ColorWhite); uint8_t calc_height = menu_height - ((MENU_ITEMS - size_menu) * line_height); - canvas_draw_box(canvas, 71, 17, 57, calc_height + 2); + canvas_draw_box(canvas, 71, 11, 57, calc_height + 4); canvas_set_color(canvas, ColorBlack); - elements_slightly_rounded_frame(canvas, 70, 16, 58, calc_height + 4); + elements_slightly_rounded_frame(canvas, 70, 12, 58, calc_height + 4); FURI_LOG_D( TAG, @@ -175,10 +176,10 @@ static void render_item_menu(Canvas* canvas, ArchiveBrowserViewModel* model) { model->menu_idx); for(size_t i = 0; i < size_menu; i++) { ArchiveContextMenuItem_t* current = menu_array_get(model->context_menu, i); - canvas_draw_str(canvas, 82, 27 + i * line_height, string_get_cstr(current->text)); + canvas_draw_str(canvas, 82, 21 + i * line_height, string_get_cstr(current->text)); } - canvas_draw_icon(canvas, 74, 20 + model->menu_idx * line_height, &I_ButtonRight_4x7); + canvas_draw_icon(canvas, 74, 14 + model->menu_idx * line_height, &I_ButtonRight_4x7); } static void archive_draw_frame(Canvas* canvas, uint16_t idx, bool scrollbar, bool moving) { diff --git a/applications/main/archive/views/archive_browser_view.h b/applications/main/archive/views/archive_browser_view.h index 838d2505d..e20bd62d3 100644 --- a/applications/main/archive/views/archive_browser_view.h +++ b/applications/main/archive/views/archive_browser_view.h @@ -15,7 +15,7 @@ #define MAX_NAME_LEN 255 #define MAX_EXT_LEN 6 #define FRAME_HEIGHT 12 -#define MENU_ITEMS 4u +#define MENU_ITEMS 5u #define MOVE_OFFSET 5u typedef enum { From 17a4e03656aab2c8a40f67232d417e10478e29df Mon Sep 17 00:00:00 2001 From: Der Skythe Date: Fri, 16 Sep 2022 02:21:10 +0400 Subject: [PATCH 03/10] Fix bugs with new model --- applications/main/archive/archive.c | 83 +++++++++++-------- applications/main/archive/archive_i.h | 6 +- .../main/archive/helpers/archive_files.c | 6 +- .../archive/scenes/archive_scene_browser.c | 3 +- .../main/archive/scenes/archive_scene_info.c | 41 +++++---- .../archive/scenes/archive_scene_rename.c | 21 ++--- 6 files changed, 94 insertions(+), 66 deletions(-) diff --git a/applications/main/archive/archive.c b/applications/main/archive/archive.c index 93689a345..2ac2bf0f6 100644 --- a/applications/main/archive/archive.c +++ b/applications/main/archive/archive.c @@ -1,76 +1,86 @@ #include "archive_i.h" -bool archive_custom_event_callback(void* context, uint32_t event) { +static bool archive_custom_event_callback(void* context, uint32_t event) { furi_assert(context); - ArchiveApp* archive = (ArchiveApp*)context; + ArchiveApp* archive = context; return scene_manager_handle_custom_event(archive->scene_manager, event); } -bool archive_back_event_callback(void* context) { +static bool archive_back_event_callback(void* context) { furi_assert(context); - ArchiveApp* archive = (ArchiveApp*)context; + ArchiveApp* archive = context; return scene_manager_handle_back_event(archive->scene_manager); } -ArchiveApp* archive_alloc() { +static void archive_tick_event_callback(void* context) { + furi_assert(context); + ArchiveApp* archive = context; + scene_manager_handle_tick_event(archive->scene_manager); +} + +static ArchiveApp* archive_alloc() { ArchiveApp* archive = malloc(sizeof(ArchiveApp)); - archive->gui = furi_record_open(RECORD_GUI); - archive->dialogs = furi_record_open(RECORD_DIALOGS); - archive->text_input = text_input_alloc(); string_init(archive->fav_move_str); - archive->view_dispatcher = view_dispatcher_alloc(); archive->scene_manager = scene_manager_alloc(&archive_scene_handlers, archive); + archive->view_dispatcher = view_dispatcher_alloc(); - view_dispatcher_enable_queue(archive->view_dispatcher); - view_dispatcher_attach_to_gui( - archive->view_dispatcher, archive->gui, ViewDispatcherTypeFullscreen); + archive->gui = furi_record_open(RECORD_GUI); - view_dispatcher_set_event_callback_context(archive->view_dispatcher, archive); - view_dispatcher_set_custom_event_callback( - archive->view_dispatcher, archive_custom_event_callback); - view_dispatcher_set_navigation_event_callback( - archive->view_dispatcher, archive_back_event_callback); + ViewDispatcher* view_dispatcher = archive->view_dispatcher; + view_dispatcher_enable_queue(view_dispatcher); + view_dispatcher_set_event_callback_context(view_dispatcher, archive); + view_dispatcher_set_custom_event_callback(view_dispatcher, archive_custom_event_callback); + view_dispatcher_set_navigation_event_callback(view_dispatcher, archive_back_event_callback); + view_dispatcher_set_tick_event_callback(view_dispatcher, archive_tick_event_callback, 100); - archive->browser = browser_alloc(); + archive->dialogs = furi_record_open(RECORD_DIALOGS); + archive->text_input = text_input_alloc(); view_dispatcher_add_view( - archive->view_dispatcher, ArchiveViewBrowser, archive_browser_get_view(archive->browser)); - - view_dispatcher_add_view( - archive->view_dispatcher, ArchiveViewTextInput, text_input_get_view(archive->text_input)); + view_dispatcher, ArchiveViewTextInput, text_input_get_view(archive->text_input)); archive->widget = widget_alloc(); view_dispatcher_add_view( archive->view_dispatcher, ArchiveViewWidget, widget_get_view(archive->widget)); + archive->view_stack = view_stack_alloc(); + view_dispatcher_add_view( + view_dispatcher, ArchiveViewStack, view_stack_get_view(archive->view_stack)); + + archive->browser = browser_alloc(); + view_dispatcher_add_view( + archive->view_dispatcher, ArchiveViewBrowser, archive_browser_get_view(archive->browser)); + // Loading archive->loading = loading_alloc(); - view_dispatcher_add_view( - archive->view_dispatcher, ArchiveViewLoading, loading_get_view(archive->loading)); return archive; } void archive_free(ArchiveApp* archive) { furi_assert(archive); + ViewDispatcher* view_dispatcher = archive->view_dispatcher; // Loading - view_dispatcher_remove_view(archive->view_dispatcher, ArchiveViewLoading); + view_dispatcher_remove_view(view_dispatcher, ArchiveViewLoading); loading_free(archive->loading); - view_dispatcher_remove_view(archive->view_dispatcher, ArchiveViewBrowser); - view_dispatcher_remove_view(archive->view_dispatcher, ArchiveViewTextInput); - view_dispatcher_remove_view(archive->view_dispatcher, ArchiveViewWidget); + view_dispatcher_remove_view(view_dispatcher, ArchiveViewTextInput); + text_input_free(archive->text_input); + + view_dispatcher_remove_view(view_dispatcher, ArchiveViewWidget); widget_free(archive->widget); + + view_dispatcher_remove_view(view_dispatcher, ArchiveViewBrowser); + view_dispatcher_free(archive->view_dispatcher); scene_manager_free(archive->scene_manager); + browser_free(archive->browser); string_clear(archive->fav_move_str); - text_input_free(archive->text_input); - furi_record_close(RECORD_DIALOGS); archive->dialogs = NULL; @@ -80,15 +90,17 @@ void archive_free(ArchiveApp* archive) { free(archive); } -void archive_show_loading_popup(void* context, bool show) { - ArchiveApp* instance = context; +void archive_show_loading_popup(ArchiveApp* context, bool show) { TaskHandle_t timer_task = xTaskGetHandle(configTIMER_SERVICE_TASK_NAME); + ViewStack* view_stack = context->view_stack; + Loading* loading = context->loading; if(show) { // Raise timer priority so that animations can play vTaskPrioritySet(timer_task, configMAX_PRIORITIES - 1); - view_dispatcher_switch_to_view(instance->view_dispatcher, ArchiveViewLoading); + view_stack_add_view(view_stack, loading_get_view(loading)); } else { + view_stack_remove_view(view_stack, loading_get_view(loading)); // Restore default timer priority vTaskPrioritySet(timer_task, configTIMER_TASK_PRIORITY); } @@ -96,10 +108,13 @@ void archive_show_loading_popup(void* context, bool show) { int32_t archive_app(void* p) { UNUSED(p); + ArchiveApp* archive = archive_alloc(); + view_dispatcher_attach_to_gui( + archive->view_dispatcher, archive->gui, ViewDispatcherTypeFullscreen); scene_manager_next_scene(archive->scene_manager, ArchiveAppSceneBrowser); view_dispatcher_run(archive->view_dispatcher); - archive_free(archive); + archive_free(archive); return 0; } diff --git a/applications/main/archive/archive_i.h b/applications/main/archive/archive_i.h index 3020b1753..0c5b337e6 100644 --- a/applications/main/archive/archive_i.h +++ b/applications/main/archive/archive_i.h @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -21,11 +22,13 @@ typedef enum { ArchiveViewWidget, ArchiveViewTotal, ArchiveViewLoading, + ArchiveViewStack, } ArchiveViewEnum; struct ArchiveApp { Gui* gui; ViewDispatcher* view_dispatcher; + ViewStack* view_stack; SceneManager* scene_manager; ArchiveBrowserView* browser; TextInput* text_input; @@ -33,9 +36,10 @@ struct ArchiveApp { DialogsApp* dialogs; Loading* loading; FuriPubSubSubscription* loader_stop_subscription; + string_t fav_move_str; char text_store[MAX_NAME_LEN]; char file_extension[MAX_EXT_LEN + 1]; }; -void archive_show_loading_popup(void* context, bool show); \ No newline at end of file +void archive_show_loading_popup(ArchiveApp* context, bool show); \ No newline at end of file diff --git a/applications/main/archive/helpers/archive_files.c b/applications/main/archive/helpers/archive_files.c index e67fbb74d..d53c74da4 100644 --- a/applications/main/archive/helpers/archive_files.c +++ b/applications/main/archive/helpers/archive_files.c @@ -134,12 +134,12 @@ FS_Error archive_rename_file_or_dir(void* context, const char* src_path, const c archive_favorites_rename(src_path, dst_path); } - if(error == FSE_OK) { + if(error == FSE_OK || error == FSE_EXIST) { FURI_LOG_I(TAG, "Rename from %s to %s is DONE", src_path, dst_path); archive_refresh_dir(browser); } else { - const char* error_msg = filesystem_api_error_get_desc(error); - FURI_LOG_E(TAG, "Rename failed: %s, Code: %d", error_msg, error); + FURI_LOG_E( + TAG, "Rename failed: %s, Code: %d", filesystem_api_error_get_desc(error), error); } return error; diff --git a/applications/main/archive/scenes/archive_scene_browser.c b/applications/main/archive/scenes/archive_scene_browser.c index d77458c48..3e7ac231d 100644 --- a/applications/main/archive/scenes/archive_scene_browser.c +++ b/applications/main/archive/scenes/archive_scene_browser.c @@ -143,8 +143,9 @@ bool archive_scene_browser_on_event(void* context, SceneManagerEvent event) { consumed = true; break; case ArchiveBrowserEventFileMenuInfo: + archive_show_file_menu(browser, false); scene_manager_set_scene_state( - archive->scene_manager, ArchiveAppSceneBrowser, SCENE_STATE_NEED_REFRESH); + archive->scene_manager, ArchiveAppSceneBrowser, SCENE_STATE_DEFAULT); scene_manager_next_scene(archive->scene_manager, ArchiveAppSceneInfo); consumed = true; break; diff --git a/applications/main/archive/scenes/archive_scene_info.c b/applications/main/archive/scenes/archive_scene_info.c index 5af9acae5..b6fae4bca 100644 --- a/applications/main/archive/scenes/archive_scene_info.c +++ b/applications/main/archive/scenes/archive_scene_info.c @@ -13,10 +13,10 @@ void archive_scene_info_widget_callback(GuiButtonType result, InputType type, vo void archive_scene_info_on_enter(void* context) { furi_assert(context); - ArchiveApp* app = (ArchiveApp*)context; + ArchiveApp* instance = context; widget_add_button_element( - app->widget, GuiButtonTypeLeft, "Back", archive_scene_info_widget_callback, app); + instance->widget, GuiButtonTypeLeft, "Back", archive_scene_info_widget_callback, instance); string_t filename; string_t dirname; @@ -25,7 +25,7 @@ void archive_scene_info_on_enter(void* context) { string_init(dirname); string_init(str_size); - ArchiveFile_t* current = archive_get_current_file(app->browser); + ArchiveFile_t* current = archive_get_current_file(instance->browser); char file_info_message[128]; Storage* fs_api = furi_record_open(RECORD_STORAGE); @@ -33,7 +33,7 @@ void archive_scene_info_on_enter(void* context) { path_extract_filename(current->path, filename, false); snprintf(file_info_message, sizeof(file_info_message), "\e#%s\e#", string_get_cstr(filename)); widget_add_text_box_element( - app->widget, 0, 0, 128, 25, AlignLeft, AlignCenter, file_info_message, false); + instance->widget, 0, 0, 128, 25, AlignLeft, AlignCenter, file_info_message, false); // Directory path path_extract_dirname(string_get_cstr(current->path), dirname); @@ -42,22 +42,35 @@ void archive_scene_info_on_enter(void* context) { // File size FileInfo fileinfo; storage_common_stat(fs_api, string_get_cstr(current->path), &fileinfo); - string_printf(str_size, "%d", fileinfo.size / 1024); - snprintf( - file_info_message, - sizeof(file_info_message), - "Size: \e#%s\e# Kb.\n%s", - string_get_cstr(str_size), - string_get_cstr(dirname) - ); + if(fileinfo.size <= 1024) { + string_printf(str_size, "%d", fileinfo.size); + snprintf( + file_info_message, + sizeof(file_info_message), + "Size: \e#%s\e# bytes\n%s", + string_get_cstr(str_size), + string_get_cstr(dirname)); + } else { + string_printf(str_size, "%d", fileinfo.size / 1024); + snprintf( + file_info_message, + sizeof(file_info_message), + "Size: \e#%s\e# Kb.\n%s", + string_get_cstr(str_size), + string_get_cstr(dirname)); + } widget_add_text_box_element( - app->widget, 0, 25, 128, 25, AlignLeft, AlignCenter, file_info_message, false); + instance->widget, 0, 25, 128, 25, AlignLeft, AlignCenter, file_info_message, false); + + // This one to return and cursor select this file + path_extract_filename_no_ext(string_get_cstr(current->path), filename); + strlcpy(instance->text_store, string_get_cstr(filename), MAX_NAME_LEN); string_clear(filename); string_clear(dirname); string_clear(str_size); - view_dispatcher_switch_to_view(app->view_dispatcher, ArchiveViewWidget); + view_dispatcher_switch_to_view(instance->view_dispatcher, ArchiveViewWidget); } bool archive_scene_info_on_event(void* context, SceneManagerEvent event) { diff --git a/applications/main/archive/scenes/archive_scene_rename.c b/applications/main/archive/scenes/archive_scene_rename.c index 6e4a65ec4..ca15ee88e 100644 --- a/applications/main/archive/scenes/archive_scene_rename.c +++ b/applications/main/archive/scenes/archive_scene_rename.c @@ -17,7 +17,7 @@ void archive_scene_rename_text_input_callback(void* context) { } void archive_scene_rename_on_enter(void* context) { - ArchiveApp* archive = (ArchiveApp*)context; + ArchiveApp* archive = context; TextInput* text_input = archive->text_input; ArchiveFile_t* current = archive_get_current_file(archive->browser); @@ -44,7 +44,7 @@ void archive_scene_rename_on_enter(void* context) { text_input_set_result_callback( text_input, archive_scene_rename_text_input_callback, - archive, + context, archive->text_store, MAX_TEXT_INPUT_LEN, false); @@ -55,7 +55,7 @@ void archive_scene_rename_on_enter(void* context) { } bool archive_scene_rename_on_event(void* context, SceneManagerEvent event) { - ArchiveApp* archive = (ArchiveApp*)context; + ArchiveApp* archive = context; bool consumed = false; if(event.type == SceneManagerEventTypeCustom) { @@ -80,6 +80,7 @@ bool archive_scene_rename_on_event(void* context, SceneManagerEvent event) { string_cat_printf(path_dst, "/%s%s", archive->text_store, archive->file_extension); } // Long time process if this is directory + view_dispatcher_switch_to_view(archive->view_dispatcher, ArchiveViewStack); archive_show_loading_popup(archive, true); FS_Error error = archive_rename_file_or_dir(archive->browser, path_src, string_get_cstr(path_dst)); @@ -88,14 +89,14 @@ bool archive_scene_rename_on_event(void* context, SceneManagerEvent event) { string_clear(path_dst); - if(error != FSE_OK) { + if(error == FSE_OK || error == FSE_EXIST) { + scene_manager_next_scene(archive->scene_manager, ArchiveAppSceneBrowser); + } else { string_t dialog_msg; string_init(dialog_msg); string_cat_printf(dialog_msg, "Cannot rename\nCode: %d", error); dialog_message_show_storage_error(archive->dialogs, string_get_cstr(dialog_msg)); string_clear(dialog_msg); - } else { - scene_manager_next_scene(archive->scene_manager, ArchiveAppSceneBrowser); } consumed = true; } @@ -104,12 +105,6 @@ bool archive_scene_rename_on_event(void* context, SceneManagerEvent event) { } void archive_scene_rename_on_exit(void* context) { - ArchiveApp* archive = (ArchiveApp*)context; - - // Clear view - void* validator_context = text_input_get_validator_callback_context(archive->text_input); - text_input_set_validator(archive->text_input, NULL, NULL); - validator_is_file_free(validator_context); - + ArchiveApp* archive = context; text_input_reset(archive->text_input); } From ec7676182aeee82f054c31cb94a5491cfb7f54b1 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Fri, 16 Sep 2022 02:15:58 +0300 Subject: [PATCH 04/10] fix null pointer dereference --- applications/main/archive/archive.c | 3 ++- applications/main/archive/archive_i.h | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/applications/main/archive/archive.c b/applications/main/archive/archive.c index 2ac2bf0f6..a2eee5937 100644 --- a/applications/main/archive/archive.c +++ b/applications/main/archive/archive.c @@ -64,7 +64,6 @@ void archive_free(ArchiveApp* archive) { ViewDispatcher* view_dispatcher = archive->view_dispatcher; // Loading - view_dispatcher_remove_view(view_dispatcher, ArchiveViewLoading); loading_free(archive->loading); view_dispatcher_remove_view(view_dispatcher, ArchiveViewTextInput); @@ -75,6 +74,8 @@ void archive_free(ArchiveApp* archive) { view_dispatcher_remove_view(view_dispatcher, ArchiveViewBrowser); + view_stack_free(archive->view_stack); + view_dispatcher_free(archive->view_dispatcher); scene_manager_free(archive->scene_manager); diff --git a/applications/main/archive/archive_i.h b/applications/main/archive/archive_i.h index 0c5b337e6..7f4ff5a7b 100644 --- a/applications/main/archive/archive_i.h +++ b/applications/main/archive/archive_i.h @@ -21,7 +21,6 @@ typedef enum { ArchiveViewTextInput, ArchiveViewWidget, ArchiveViewTotal, - ArchiveViewLoading, ArchiveViewStack, } ArchiveViewEnum; From 8915c0c66c7747967262f732793f57f2821e3aaa Mon Sep 17 00:00:00 2001 From: Der Skythe Date: Fri, 16 Sep 2022 03:16:46 +0400 Subject: [PATCH 05/10] Fix bugs with new model --- applications/main/archive/archive.c | 49 +++++++++++++++++++ applications/main/archive/archive_i.h | 6 +++ .../main/archive/scenes/archive_scene_info.c | 2 +- .../archive/scenes/archive_scene_rename.c | 4 +- 4 files changed, 58 insertions(+), 3 deletions(-) diff --git a/applications/main/archive/archive.c b/applications/main/archive/archive.c index 2ac2bf0f6..a74e28ca7 100644 --- a/applications/main/archive/archive.c +++ b/applications/main/archive/archive.c @@ -1,5 +1,29 @@ #include "archive_i.h" +static const NotificationSequence sequence_blink_set_yellow = { + &message_blink_set_color_yellow, + NULL, +}; + +static const NotificationSequence sequence_blink_set_magenta = { + &message_blink_set_color_magenta, + NULL, +}; + +static const NotificationSequence* archive_notification_sequences[] = { + &sequence_error, + &sequence_success, + &sequence_blink_start_cyan, + &sequence_blink_start_magenta, + &sequence_blink_set_yellow, + &sequence_blink_set_magenta, + &sequence_set_red_255, + &sequence_reset_red, + &sequence_set_green_255, + &sequence_reset_green, + &sequence_blink_stop, +}; + static bool archive_custom_event_callback(void* context, uint32_t event) { furi_assert(context); ArchiveApp* archive = context; @@ -27,6 +51,7 @@ static ArchiveApp* archive_alloc() { archive->view_dispatcher = view_dispatcher_alloc(); archive->gui = furi_record_open(RECORD_GUI); + archive->notifications = furi_record_open(RECORD_NOTIFICATION); ViewDispatcher* view_dispatcher = archive->view_dispatcher; view_dispatcher_enable_queue(view_dispatcher); @@ -73,6 +98,9 @@ void archive_free(ArchiveApp* archive) { view_dispatcher_remove_view(view_dispatcher, ArchiveViewWidget); widget_free(archive->widget); + view_dispatcher_remove_view(view_dispatcher, ArchiveViewStack); + view_stack_free(archive->view_stack); + view_dispatcher_remove_view(view_dispatcher, ArchiveViewBrowser); view_dispatcher_free(archive->view_dispatcher); @@ -81,6 +109,9 @@ void archive_free(ArchiveApp* archive) { browser_free(archive->browser); string_clear(archive->fav_move_str); + furi_record_close(RECORD_NOTIFICATION); + archive->notifications = NULL; + furi_record_close(RECORD_DIALOGS); archive->dialogs = NULL; @@ -106,6 +137,24 @@ void archive_show_loading_popup(ArchiveApp* context, bool show) { } } +void archive_text_store_set(ArchiveApp* context, const char* text, ...) { + va_list args; + va_start(args, text); + + vsnprintf(context->text_store, MAX_NAME_LEN, text, args); + + va_end(args); +} + +void archive_text_store_clear(ArchiveApp* context) { + memset(context->text_store, 0, MAX_NAME_LEN); +} + +void archive_notification_message(ArchiveApp* context, uint32_t message) { + furi_assert(message < sizeof(archive_notification_sequences) / sizeof(NotificationSequence*)); + notification_message(context->notifications, archive_notification_sequences[message]); +} + int32_t archive_app(void* p) { UNUSED(p); diff --git a/applications/main/archive/archive_i.h b/applications/main/archive/archive_i.h index 0c5b337e6..c72f746c4 100644 --- a/applications/main/archive/archive_i.h +++ b/applications/main/archive/archive_i.h @@ -23,6 +23,7 @@ typedef enum { ArchiveViewTotal, ArchiveViewLoading, ArchiveViewStack, + ArchiveViewDialogEx, } ArchiveViewEnum; struct ArchiveApp { @@ -35,6 +36,8 @@ struct ArchiveApp { Widget* widget; DialogsApp* dialogs; Loading* loading; + NotificationApp* notifications; + FuriPubSubSubscription* loader_stop_subscription; string_t fav_move_str; @@ -42,4 +45,7 @@ struct ArchiveApp { char file_extension[MAX_EXT_LEN + 1]; }; +void archive_text_store_set(iButton* ibutton, const char* text, ...); +void archive_text_store_clear(iButton* ibutton); +void archive_notification_message(iButton* ibutton, uint32_t message); void archive_show_loading_popup(ArchiveApp* context, bool show); \ No newline at end of file diff --git a/applications/main/archive/scenes/archive_scene_info.c b/applications/main/archive/scenes/archive_scene_info.c index b6fae4bca..705557377 100644 --- a/applications/main/archive/scenes/archive_scene_info.c +++ b/applications/main/archive/scenes/archive_scene_info.c @@ -64,7 +64,7 @@ void archive_scene_info_on_enter(void* context) { // This one to return and cursor select this file path_extract_filename_no_ext(string_get_cstr(current->path), filename); - strlcpy(instance->text_store, string_get_cstr(filename), MAX_NAME_LEN); + archive_text_store_set(instance, instance->text_store); string_clear(filename); string_clear(dirname); diff --git a/applications/main/archive/scenes/archive_scene_rename.c b/applications/main/archive/scenes/archive_scene_rename.c index ca15ee88e..4128cb7c0 100644 --- a/applications/main/archive/scenes/archive_scene_rename.c +++ b/applications/main/archive/scenes/archive_scene_rename.c @@ -27,11 +27,11 @@ void archive_scene_rename_on_enter(void* context) { if(current->type == ArchiveFileTypeFolder) { path_extract_basename(string_get_cstr(current->path), path_name); - strlcpy(archive->text_store, string_get_cstr(path_name), MAX_NAME_LEN); + archive_text_store_set(archive, string_get_cstr(path_name)); text_input_set_header_text(text_input, "Rename directory:"); } else /*if(current->type != ArchiveFileTypeUnknown) */ { path_extract_filename(current->path, path_name, true); - strlcpy(archive->text_store, string_get_cstr(path_name), MAX_NAME_LEN); + archive_text_store_set(archive, string_get_cstr(path_name)); path_extract_extension(current->path, archive->file_extension, MAX_EXT_LEN); text_input_set_header_text(text_input, "Rename file:"); From 286b4876cef229c14c643be620ed856dea3f992f Mon Sep 17 00:00:00 2001 From: Der Skythe Date: Fri, 16 Sep 2022 03:22:53 +0400 Subject: [PATCH 06/10] Fix bugs with new model --- applications/main/archive/archive_i.h | 1 - 1 file changed, 1 deletion(-) diff --git a/applications/main/archive/archive_i.h b/applications/main/archive/archive_i.h index 47ed728b7..bb4a23072 100644 --- a/applications/main/archive/archive_i.h +++ b/applications/main/archive/archive_i.h @@ -22,7 +22,6 @@ typedef enum { ArchiveViewWidget, ArchiveViewTotal, ArchiveViewStack, - ArchiveViewDialogEx, } ArchiveViewEnum; struct ArchiveApp { From c0e7c2a929c675d96acadd6eb9171395fdfaf82d Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Fri, 16 Sep 2022 02:27:08 +0300 Subject: [PATCH 07/10] remove merge bug --- applications/main/archive/archive.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/applications/main/archive/archive.c b/applications/main/archive/archive.c index 1e9226c1e..3842247bf 100644 --- a/applications/main/archive/archive.c +++ b/applications/main/archive/archive.c @@ -102,8 +102,6 @@ void archive_free(ArchiveApp* archive) { view_dispatcher_remove_view(view_dispatcher, ArchiveViewBrowser); - view_stack_free(archive->view_stack); - view_dispatcher_free(archive->view_dispatcher); scene_manager_free(archive->scene_manager); From 30aaae33be41f0141405e43894e6d8509a970822 Mon Sep 17 00:00:00 2001 From: Der Skythe Date: Fri, 16 Sep 2022 03:16:46 +0400 Subject: [PATCH 08/10] Revert "Fix bugs with new model" This reverts commit 8915c0c66c7747967262f732793f57f2821e3aaa. --- applications/main/archive/archive.c | 49 ------------------- applications/main/archive/archive_i.h | 5 -- .../main/archive/scenes/archive_scene_info.c | 2 +- .../archive/scenes/archive_scene_rename.c | 4 +- 4 files changed, 3 insertions(+), 57 deletions(-) diff --git a/applications/main/archive/archive.c b/applications/main/archive/archive.c index 3842247bf..350cd03ce 100644 --- a/applications/main/archive/archive.c +++ b/applications/main/archive/archive.c @@ -1,29 +1,5 @@ #include "archive_i.h" -static const NotificationSequence sequence_blink_set_yellow = { - &message_blink_set_color_yellow, - NULL, -}; - -static const NotificationSequence sequence_blink_set_magenta = { - &message_blink_set_color_magenta, - NULL, -}; - -static const NotificationSequence* archive_notification_sequences[] = { - &sequence_error, - &sequence_success, - &sequence_blink_start_cyan, - &sequence_blink_start_magenta, - &sequence_blink_set_yellow, - &sequence_blink_set_magenta, - &sequence_set_red_255, - &sequence_reset_red, - &sequence_set_green_255, - &sequence_reset_green, - &sequence_blink_stop, -}; - static bool archive_custom_event_callback(void* context, uint32_t event) { furi_assert(context); ArchiveApp* archive = context; @@ -51,7 +27,6 @@ static ArchiveApp* archive_alloc() { archive->view_dispatcher = view_dispatcher_alloc(); archive->gui = furi_record_open(RECORD_GUI); - archive->notifications = furi_record_open(RECORD_NOTIFICATION); ViewDispatcher* view_dispatcher = archive->view_dispatcher; view_dispatcher_enable_queue(view_dispatcher); @@ -97,9 +72,6 @@ void archive_free(ArchiveApp* archive) { view_dispatcher_remove_view(view_dispatcher, ArchiveViewWidget); widget_free(archive->widget); - view_dispatcher_remove_view(view_dispatcher, ArchiveViewStack); - view_stack_free(archive->view_stack); - view_dispatcher_remove_view(view_dispatcher, ArchiveViewBrowser); view_dispatcher_free(archive->view_dispatcher); @@ -108,9 +80,6 @@ void archive_free(ArchiveApp* archive) { browser_free(archive->browser); string_clear(archive->fav_move_str); - furi_record_close(RECORD_NOTIFICATION); - archive->notifications = NULL; - furi_record_close(RECORD_DIALOGS); archive->dialogs = NULL; @@ -136,24 +105,6 @@ void archive_show_loading_popup(ArchiveApp* context, bool show) { } } -void archive_text_store_set(ArchiveApp* context, const char* text, ...) { - va_list args; - va_start(args, text); - - vsnprintf(context->text_store, MAX_NAME_LEN, text, args); - - va_end(args); -} - -void archive_text_store_clear(ArchiveApp* context) { - memset(context->text_store, 0, MAX_NAME_LEN); -} - -void archive_notification_message(ArchiveApp* context, uint32_t message) { - furi_assert(message < sizeof(archive_notification_sequences) / sizeof(NotificationSequence*)); - notification_message(context->notifications, archive_notification_sequences[message]); -} - int32_t archive_app(void* p) { UNUSED(p); diff --git a/applications/main/archive/archive_i.h b/applications/main/archive/archive_i.h index bb4a23072..7f4ff5a7b 100644 --- a/applications/main/archive/archive_i.h +++ b/applications/main/archive/archive_i.h @@ -34,8 +34,6 @@ struct ArchiveApp { Widget* widget; DialogsApp* dialogs; Loading* loading; - NotificationApp* notifications; - FuriPubSubSubscription* loader_stop_subscription; string_t fav_move_str; @@ -43,7 +41,4 @@ struct ArchiveApp { char file_extension[MAX_EXT_LEN + 1]; }; -void archive_text_store_set(iButton* ibutton, const char* text, ...); -void archive_text_store_clear(iButton* ibutton); -void archive_notification_message(iButton* ibutton, uint32_t message); void archive_show_loading_popup(ArchiveApp* context, bool show); \ No newline at end of file diff --git a/applications/main/archive/scenes/archive_scene_info.c b/applications/main/archive/scenes/archive_scene_info.c index 705557377..b6fae4bca 100644 --- a/applications/main/archive/scenes/archive_scene_info.c +++ b/applications/main/archive/scenes/archive_scene_info.c @@ -64,7 +64,7 @@ void archive_scene_info_on_enter(void* context) { // This one to return and cursor select this file path_extract_filename_no_ext(string_get_cstr(current->path), filename); - archive_text_store_set(instance, instance->text_store); + strlcpy(instance->text_store, string_get_cstr(filename), MAX_NAME_LEN); string_clear(filename); string_clear(dirname); diff --git a/applications/main/archive/scenes/archive_scene_rename.c b/applications/main/archive/scenes/archive_scene_rename.c index 4128cb7c0..ca15ee88e 100644 --- a/applications/main/archive/scenes/archive_scene_rename.c +++ b/applications/main/archive/scenes/archive_scene_rename.c @@ -27,11 +27,11 @@ void archive_scene_rename_on_enter(void* context) { if(current->type == ArchiveFileTypeFolder) { path_extract_basename(string_get_cstr(current->path), path_name); - archive_text_store_set(archive, string_get_cstr(path_name)); + strlcpy(archive->text_store, string_get_cstr(path_name), MAX_NAME_LEN); text_input_set_header_text(text_input, "Rename directory:"); } else /*if(current->type != ArchiveFileTypeUnknown) */ { path_extract_filename(current->path, path_name, true); - archive_text_store_set(archive, string_get_cstr(path_name)); + strlcpy(archive->text_store, string_get_cstr(path_name), MAX_NAME_LEN); path_extract_extension(current->path, archive->file_extension, MAX_EXT_LEN); text_input_set_header_text(text_input, "Rename file:"); From 00585fa16aa55b4a8c61be26b5c445629cc9b05e Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Fri, 16 Sep 2022 02:32:03 +0300 Subject: [PATCH 09/10] add free back --- applications/main/archive/archive.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/applications/main/archive/archive.c b/applications/main/archive/archive.c index 350cd03ce..6eedc8ea0 100644 --- a/applications/main/archive/archive.c +++ b/applications/main/archive/archive.c @@ -72,6 +72,9 @@ void archive_free(ArchiveApp* archive) { view_dispatcher_remove_view(view_dispatcher, ArchiveViewWidget); widget_free(archive->widget); + view_dispatcher_remove_view(view_dispatcher, ArchiveViewStack); + view_stack_free(archive->view_stack); + view_dispatcher_remove_view(view_dispatcher, ArchiveViewBrowser); view_dispatcher_free(archive->view_dispatcher); From df87b04fa942a59f60b932661c333293fc6d2eba Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Fri, 16 Sep 2022 02:52:43 +0300 Subject: [PATCH 10/10] disable debug logs to make gui faster --- .../main/archive/views/archive_browser_view.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/applications/main/archive/views/archive_browser_view.c b/applications/main/archive/views/archive_browser_view.c index 4873b46cd..5fa21d150 100644 --- a/applications/main/archive/views/archive_browser_view.c +++ b/applications/main/archive/views/archive_browser_view.c @@ -67,7 +67,7 @@ static void render_item_menu(Canvas* canvas, ArchiveBrowserViewModel* model) { } if(selected->type == ArchiveFileTypeFolder) { - FURI_LOG_D(TAG, "Directory type"); + //FURI_LOG_D(TAG, "Directory type"); archive_menu_add_item( menu_array_push_raw(model->context_menu), item_rename, @@ -77,7 +77,7 @@ static void render_item_menu(Canvas* canvas, ArchiveBrowserViewModel* model) { item_delete, ArchiveBrowserEventFileMenuDelete); } else if(!archive_is_known_app(selected->type)) { - FURI_LOG_D(TAG, "Unknown type"); + //FURI_LOG_D(TAG, "Unknown type"); archive_menu_add_item( menu_array_push_raw(model->context_menu), @@ -92,7 +92,7 @@ static void render_item_menu(Canvas* canvas, ArchiveBrowserViewModel* model) { item_delete, ArchiveBrowserEventFileMenuDelete); } else if(model->tab_idx == ArchiveTabFavorites) { - FURI_LOG_D(TAG, "ArchiveTabFavorites"); + //FURI_LOG_D(TAG, "ArchiveTabFavorites"); string_set_str(item_rename, "Move"); @@ -109,7 +109,7 @@ static void render_item_menu(Canvas* canvas, ArchiveBrowserViewModel* model) { item_rename, ArchiveBrowserEventFileMenuRename); } else if(selected->is_app) { - FURI_LOG_D(TAG, "3 types"); + //FURI_LOG_D(TAG, "3 types"); archive_menu_add_item( menu_array_push_raw(model->context_menu), item_run, @@ -127,7 +127,7 @@ static void render_item_menu(Canvas* canvas, ArchiveBrowserViewModel* model) { item_delete, ArchiveBrowserEventFileMenuDelete); } else { - FURI_LOG_D(TAG, "All menu"); + //FURI_LOG_D(TAG, "All menu"); archive_menu_add_item( menu_array_push_raw(model->context_menu), item_run, @@ -155,9 +155,9 @@ static void render_item_menu(Canvas* canvas, ArchiveBrowserViewModel* model) { string_clear(item_info); string_clear(item_rename); string_clear(item_delete); - } else { + } /*else { FURI_LOG_D(TAG, "menu_array_size already set: %d", menu_array_size(model->context_menu)); - } + }*/ size_t size_menu = menu_array_size(model->context_menu); const uint8_t menu_height = 48; const uint8_t line_height = 10; @@ -168,12 +168,12 @@ static void render_item_menu(Canvas* canvas, ArchiveBrowserViewModel* model) { canvas_set_color(canvas, ColorBlack); elements_slightly_rounded_frame(canvas, 70, 12, 58, calc_height + 4); - FURI_LOG_D( + /*FURI_LOG_D( TAG, "size_menu: %d, calc_height: %d, menu_idx: %d", size_menu, calc_height, - model->menu_idx); + model->menu_idx);*/ for(size_t i = 0; i < size_menu; i++) { ArchiveContextMenuItem_t* current = menu_array_get(model->context_menu, i); canvas_draw_str(canvas, 82, 21 + i * line_height, string_get_cstr(current->text));