From 877c5c812236337756bd8dba8694ac0ccf53da66 Mon Sep 17 00:00:00 2001 From: Nikolay Minaylov Date: Sun, 17 Jul 2022 10:41:16 +0300 Subject: [PATCH] [FL-1962, FL-2464, FL-2465, FL-2466, FL-2560, FL-2637, FL-2595] Ibutton, Infrared, LfRFID GUI fixes (#1392) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Ibutton, Infrared, LfRFID GUI fixes * Loading screens update Co-authored-by: あく --- .../archive/views/archive_browser_view.c | 13 ++--- applications/gui/modules/file_browser.c | 13 ++--- applications/gui/modules/loading.c | 15 +++--- .../ibutton/scenes/ibutton_scene_add_type.c | 4 +- .../scenes/ibutton_scene_exit_confirm.c | 4 +- .../scenes/ibutton_scene_read_crc_error.c | 5 +- .../scenes/ibutton_scene_read_key_menu.c | 6 ++- .../scenes/ibutton_scene_read_not_key_error.c | 5 +- .../scenes/ibutton_scene_saved_key_menu.c | 5 +- .../ibutton/scenes/ibutton_scene_start.c | 5 +- .../scenes/infrared_scene_ask_retry.c | 48 ++++++++++++++++++ .../infrared/scenes/infrared_scene_config.h | 1 + .../scenes/infrared_scene_learn_success.c | 3 +- .../scenes/infrared_scene_remote_list.c | 3 +- .../infrared/scenes/infrared_scene_start.c | 1 + .../scene/lfrfid_app_scene_exit_confirm.cpp | 2 +- .../lfrfid/scene/lfrfid_app_scene_read.cpp | 4 +- applications/nfc/nfc.c | 24 +++++++++ applications/nfc/nfc_device.c | 15 ++++++ applications/nfc/nfc_device.h | 7 +++ applications/nfc/nfc_i.h | 5 ++ .../nfc/scenes/nfc_scene_file_select.c | 3 ++ assets/icons/Archive/loading_10px.png | Bin 173 -> 4349 bytes assets/icons/Common/Loading_24/frame_01.png | Bin 194 -> 3650 bytes assets/icons/Common/Loading_24/frame_02.png | Bin 194 -> 3649 bytes assets/icons/Common/Loading_24/frame_03.png | Bin 192 -> 3649 bytes assets/icons/Common/Loading_24/frame_04.png | Bin 190 -> 3645 bytes assets/icons/Common/Loading_24/frame_05.png | Bin 203 -> 3654 bytes assets/icons/Common/Loading_24/frame_06.png | Bin 184 -> 3650 bytes assets/icons/Common/Loading_24/frame_07.png | Bin 203 -> 3655 bytes 30 files changed, 147 insertions(+), 44 deletions(-) create mode 100644 applications/infrared/scenes/infrared_scene_ask_retry.c diff --git a/applications/archive/views/archive_browser_view.c b/applications/archive/views/archive_browser_view.c index 34b875b8c..810d5c8f7 100644 --- a/applications/archive/views/archive_browser_view.c +++ b/applications/archive/views/archive_browser_view.c @@ -105,17 +105,10 @@ static void archive_draw_frame(Canvas* canvas, uint16_t idx, bool scrollbar, boo static void archive_draw_loading(Canvas* canvas, ArchiveBrowserViewModel* model) { furi_assert(model); - uint8_t width = 49; - uint8_t height = 47; - uint8_t x = 128 / 2 - width / 2; - uint8_t y = 64 / 2 - height / 2 + 6; + uint8_t x = 128 / 2 - 24 / 2; + uint8_t y = 64 / 2 - 24 / 2; - elements_bold_rounded_frame(canvas, x, y, width, height); - - canvas_set_font(canvas, FontSecondary); - elements_multiline_text(canvas, x + 7, y + 13, "Loading..."); - - canvas_draw_icon(canvas, x + 13, y + 19, &A_Loading_24); + canvas_draw_icon(canvas, x, y, &A_Loading_24); } static void draw_list(Canvas* canvas, ArchiveBrowserViewModel* model) { diff --git a/applications/gui/modules/file_browser.c b/applications/gui/modules/file_browser.c index 1cef1d079..4dc0ee547 100644 --- a/applications/gui/modules/file_browser.c +++ b/applications/gui/modules/file_browser.c @@ -354,19 +354,12 @@ static void browser_draw_frame(Canvas* canvas, uint16_t idx, bool scrollbar) { } static void browser_draw_loading(Canvas* canvas, FileBrowserModel* model) { - uint8_t width = 49; - uint8_t height = 47; - uint8_t x = 128 / 2 - width / 2; - uint8_t y = 64 / 2 - height / 2; - UNUSED(model); - elements_bold_rounded_frame(canvas, x, y, width, height); + uint8_t x = 128 / 2 - 24 / 2; + uint8_t y = 64 / 2 - 24 / 2; - canvas_set_font(canvas, FontSecondary); - elements_multiline_text(canvas, x + 7, y + 13, "Loading..."); - - canvas_draw_icon(canvas, x + 13, y + 19, &A_Loading_24); + canvas_draw_icon(canvas, x, y, &A_Loading_24); } static void browser_draw_list(Canvas* canvas, FileBrowserModel* model) { diff --git a/applications/gui/modules/loading.c b/applications/gui/modules/loading.c index 575126972..0fa2c1286 100644 --- a/applications/gui/modules/loading.c +++ b/applications/gui/modules/loading.c @@ -20,17 +20,16 @@ typedef struct { static void loading_draw_callback(Canvas* canvas, void* _model) { LoadingModel* model = (LoadingModel*)_model; - uint8_t width = 49; - uint8_t height = 47; - uint8_t x = (canvas_width(canvas) - width) / 2; - uint8_t y = (canvas_height(canvas) - height) / 2; + canvas_set_color(canvas, ColorWhite); + canvas_draw_box(canvas, 0, 0, canvas_width(canvas), canvas_height(canvas)); + canvas_set_color(canvas, ColorBlack); - elements_bold_rounded_frame(canvas, x, y, width, height); + uint8_t x = canvas_width(canvas) / 2 - 24 / 2; + uint8_t y = canvas_height(canvas) / 2 - 24 / 2; - canvas_set_font(canvas, FontSecondary); - elements_multiline_text(canvas, x + 7, y + 13, "Loading..."); + canvas_draw_icon(canvas, x, y, &A_Loading_24); - canvas_draw_icon_animation(canvas, x + 13, y + 19, model->icon); + canvas_draw_icon_animation(canvas, x, y, model->icon); } static bool loading_input_callback(InputEvent* event, void* context) { diff --git a/applications/ibutton/scenes/ibutton_scene_add_type.c b/applications/ibutton/scenes/ibutton_scene_add_type.c index 273330e71..9a0583a58 100644 --- a/applications/ibutton/scenes/ibutton_scene_add_type.c +++ b/applications/ibutton/scenes/ibutton_scene_add_type.c @@ -23,7 +23,8 @@ void ibutton_scene_add_type_on_enter(void* context) { submenu_add_item( submenu, "Metakom", SubmenuIndexMetakom, ibutton_scene_add_type_submenu_callback, ibutton); - submenu_set_selected_item(submenu, SubmenuIndexCyfral); + submenu_set_selected_item( + submenu, scene_manager_get_scene_state(ibutton->scene_manager, iButtonSceneAddType)); view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewSubmenu); } @@ -34,6 +35,7 @@ bool ibutton_scene_add_type_on_event(void* context, SceneManagerEvent event) { bool consumed = false; if(event.type == SceneManagerEventTypeCustom) { + scene_manager_set_scene_state(ibutton->scene_manager, iButtonSceneAddType, event.event); consumed = true; if(event.event == SubmenuIndexCyfral) { ibutton_key_set_type(key, iButtonKeyCyfral); diff --git a/applications/ibutton/scenes/ibutton_scene_exit_confirm.c b/applications/ibutton/scenes/ibutton_scene_exit_confirm.c index abd171f6a..c4e90892e 100644 --- a/applications/ibutton/scenes/ibutton_scene_exit_confirm.c +++ b/applications/ibutton/scenes/ibutton_scene_exit_confirm.c @@ -19,9 +19,9 @@ void ibutton_scene_exit_confirm_on_enter(void* context) { widget_add_button_element( widget, GuiButtonTypeRight, "Stay", ibutton_scene_exit_confirm_widget_callback, ibutton); widget_add_string_element( - widget, 64, 19, AlignCenter, AlignBottom, FontPrimary, "Exit to iButton menu"); + widget, 64, 19, AlignCenter, AlignBottom, FontPrimary, "Exit to iButton menu?"); widget_add_string_element( - widget, 64, 29, AlignCenter, AlignBottom, FontSecondary, "All unsaved data will be lost"); + widget, 64, 31, AlignCenter, AlignBottom, FontSecondary, "All unsaved data will be lost."); view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewWidget); } diff --git a/applications/ibutton/scenes/ibutton_scene_read_crc_error.c b/applications/ibutton/scenes/ibutton_scene_read_crc_error.c index 28d59d2d0..f822ff6a2 100644 --- a/applications/ibutton/scenes/ibutton_scene_read_crc_error.c +++ b/applications/ibutton/scenes/ibutton_scene_read_crc_error.c @@ -43,7 +43,10 @@ bool ibutton_scene_read_crc_error_on_event(void* context, SceneManagerEvent even SceneManager* scene_manager = ibutton->scene_manager; bool consumed = false; - if(event.type == SceneManagerEventTypeCustom) { + if(event.type == SceneManagerEventTypeBack) { + consumed = true; + scene_manager_next_scene(scene_manager, iButtonSceneExitConfirm); + } else if(event.type == SceneManagerEventTypeCustom) { consumed = true; if(event.event == DialogExResultRight) { scene_manager_next_scene(scene_manager, iButtonSceneReadKeyMenu); diff --git a/applications/ibutton/scenes/ibutton_scene_read_key_menu.c b/applications/ibutton/scenes/ibutton_scene_read_key_menu.c index 7d479a463..921b24fc1 100644 --- a/applications/ibutton/scenes/ibutton_scene_read_key_menu.c +++ b/applications/ibutton/scenes/ibutton_scene_read_key_menu.c @@ -31,8 +31,8 @@ void ibutton_scene_read_key_menu_on_enter(void* context) { ibutton_scene_read_key_menu_submenu_callback, ibutton); } - - submenu_set_selected_item(submenu, SubmenuIndexSave); + submenu_set_selected_item( + submenu, scene_manager_get_scene_state(ibutton->scene_manager, iButtonSceneReadKeyMenu)); view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewSubmenu); } @@ -42,6 +42,8 @@ bool ibutton_scene_read_key_menu_on_event(void* context, SceneManagerEvent event bool consumed = false; if(event.type == SceneManagerEventTypeCustom) { + scene_manager_set_scene_state( + ibutton->scene_manager, iButtonSceneReadKeyMenu, event.event); consumed = true; if(event.event == SubmenuIndexSave) { scene_manager_next_scene(ibutton->scene_manager, iButtonSceneSaveName); diff --git a/applications/ibutton/scenes/ibutton_scene_read_not_key_error.c b/applications/ibutton/scenes/ibutton_scene_read_not_key_error.c index 45fbefe8b..8a7528031 100644 --- a/applications/ibutton/scenes/ibutton_scene_read_not_key_error.c +++ b/applications/ibutton/scenes/ibutton_scene_read_not_key_error.c @@ -44,7 +44,10 @@ bool ibutton_scene_read_not_key_error_on_event(void* context, SceneManagerEvent SceneManager* scene_manager = ibutton->scene_manager; bool consumed = false; - if(event.type == SceneManagerEventTypeCustom) { + if(event.type == SceneManagerEventTypeBack) { + consumed = true; + scene_manager_next_scene(scene_manager, iButtonSceneExitConfirm); + } else if(event.type == SceneManagerEventTypeCustom) { consumed = true; if(event.event == DialogExResultRight) { scene_manager_next_scene(scene_manager, iButtonSceneReadKeyMenu); diff --git a/applications/ibutton/scenes/ibutton_scene_saved_key_menu.c b/applications/ibutton/scenes/ibutton_scene_saved_key_menu.c index 365297721..3d588dd02 100644 --- a/applications/ibutton/scenes/ibutton_scene_saved_key_menu.c +++ b/applications/ibutton/scenes/ibutton_scene_saved_key_menu.c @@ -42,7 +42,8 @@ void ibutton_scene_saved_key_menu_on_enter(void* context) { submenu_add_item( submenu, "Info", SubmenuIndexInfo, ibutton_scene_saved_key_menu_submenu_callback, ibutton); - submenu_set_selected_item(submenu, SubmenuIndexEmulate); + submenu_set_selected_item( + submenu, scene_manager_get_scene_state(ibutton->scene_manager, iButtonSceneSavedKeyMenu)); view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewSubmenu); } @@ -52,6 +53,8 @@ bool ibutton_scene_saved_key_menu_on_event(void* context, SceneManagerEvent even bool consumed = false; if(event.type == SceneManagerEventTypeCustom) { + scene_manager_set_scene_state( + ibutton->scene_manager, iButtonSceneSavedKeyMenu, event.event); consumed = true; if(event.event == SubmenuIndexEmulate) { scene_manager_next_scene(ibutton->scene_manager, iButtonSceneEmulate); diff --git a/applications/ibutton/scenes/ibutton_scene_start.c b/applications/ibutton/scenes/ibutton_scene_start.c index cc8af9839..c2844cde9 100644 --- a/applications/ibutton/scenes/ibutton_scene_start.c +++ b/applications/ibutton/scenes/ibutton_scene_start.c @@ -1,4 +1,5 @@ #include "../ibutton_i.h" +#include "ibutton/scenes/ibutton_scene.h" enum SubmenuIndex { SubmenuIndexRead, @@ -22,7 +23,8 @@ void ibutton_scene_start_on_enter(void* context) { submenu_add_item( submenu, "Add Manually", SubmenuIndexAdd, ibutton_scene_start_submenu_callback, ibutton); - submenu_set_selected_item(submenu, SubmenuIndexRead); + submenu_set_selected_item( + submenu, scene_manager_get_scene_state(ibutton->scene_manager, iButtonSceneStart)); view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewSubmenu); } @@ -32,6 +34,7 @@ bool ibutton_scene_start_on_event(void* context, SceneManagerEvent event) { bool consumed = false; if(event.type == SceneManagerEventTypeCustom) { + scene_manager_set_scene_state(ibutton->scene_manager, iButtonSceneStart, event.event); consumed = true; if(event.event == SubmenuIndexRead) { scene_manager_next_scene(ibutton->scene_manager, iButtonSceneRead); diff --git a/applications/infrared/scenes/infrared_scene_ask_retry.c b/applications/infrared/scenes/infrared_scene_ask_retry.c new file mode 100644 index 000000000..48a5cfcde --- /dev/null +++ b/applications/infrared/scenes/infrared_scene_ask_retry.c @@ -0,0 +1,48 @@ +#include "../infrared_i.h" + +static void infrared_scene_dialog_result_callback(DialogExResult result, void* context) { + Infrared* infrared = context; + view_dispatcher_send_custom_event(infrared->view_dispatcher, result); +} + +void infrared_scene_ask_retry_on_enter(void* context) { + Infrared* infrared = context; + DialogEx* dialog_ex = infrared->dialog_ex; + + dialog_ex_set_header(dialog_ex, "Return to reading?", 64, 0, AlignCenter, AlignTop); + dialog_ex_set_text( + dialog_ex, "All unsaved data\nwill be lost", 64, 31, AlignCenter, AlignCenter); + dialog_ex_set_icon(dialog_ex, 0, 0, NULL); + dialog_ex_set_left_button_text(dialog_ex, "Exit"); + dialog_ex_set_center_button_text(dialog_ex, NULL); + dialog_ex_set_right_button_text(dialog_ex, "Stay"); + dialog_ex_set_result_callback(dialog_ex, infrared_scene_dialog_result_callback); + dialog_ex_set_context(dialog_ex, context); + + view_dispatcher_switch_to_view(infrared->view_dispatcher, InfraredViewDialogEx); +} + +bool infrared_scene_ask_retry_on_event(void* context, SceneManagerEvent event) { + Infrared* infrared = context; + SceneManager* scene_manager = infrared->scene_manager; + bool consumed = false; + + if(event.type == SceneManagerEventTypeBack) { + consumed = true; + } else if(event.type == SceneManagerEventTypeCustom) { + if(event.event == DialogExResultLeft) { + scene_manager_search_and_switch_to_previous_scene(scene_manager, InfraredSceneLearn); + consumed = true; + } else if(event.event == DialogExResultRight) { + scene_manager_previous_scene(scene_manager); + consumed = true; + } + } + + return consumed; +} + +void infrared_scene_ask_retry_on_exit(void* context) { + Infrared* infrared = context; + dialog_ex_reset(infrared->dialog_ex); +} diff --git a/applications/infrared/scenes/infrared_scene_config.h b/applications/infrared/scenes/infrared_scene_config.h index 8ff3b167b..26a92056d 100644 --- a/applications/infrared/scenes/infrared_scene_config.h +++ b/applications/infrared/scenes/infrared_scene_config.h @@ -1,5 +1,6 @@ ADD_SCENE(infrared, start, Start) ADD_SCENE(infrared, ask_back, AskBack) +ADD_SCENE(infrared, ask_retry, AskRetry) ADD_SCENE(infrared, edit, Edit) ADD_SCENE(infrared, edit_delete, EditDelete) ADD_SCENE(infrared, edit_delete_done, EditDeleteDone) diff --git a/applications/infrared/scenes/infrared_scene_learn_success.c b/applications/infrared/scenes/infrared_scene_learn_success.c index ec950ca71..1297ebcf9 100644 --- a/applications/infrared/scenes/infrared_scene_learn_success.c +++ b/applications/infrared/scenes/infrared_scene_learn_success.c @@ -89,8 +89,7 @@ bool infrared_scene_learn_success_on_event(void* context, SceneManagerEvent even } else if(event.type == SceneManagerEventTypeCustom) { if(event.event == DialogExResultLeft) { if(scene_state == InfraredSceneLearnSuccessStateIdle) { - scene_manager_search_and_switch_to_previous_scene( - scene_manager, InfraredSceneLearn); + scene_manager_next_scene(scene_manager, InfraredSceneAskRetry); } consumed = true; } else if(event.event == DialogExResultRight) { diff --git a/applications/infrared/scenes/infrared_scene_remote_list.c b/applications/infrared/scenes/infrared_scene_remote_list.c index 25b37759c..b0038c1a3 100644 --- a/applications/infrared/scenes/infrared_scene_remote_list.c +++ b/applications/infrared/scenes/infrared_scene_remote_list.c @@ -5,7 +5,6 @@ void infrared_scene_remote_list_on_enter(void* context) { SceneManager* scene_manager = infrared->scene_manager; ViewDispatcher* view_dispatcher = infrared->view_dispatcher; - string_set_str(infrared->file_path, INFRARED_APP_FOLDER); bool success = dialog_file_browser_show( infrared->dialogs, infrared->file_path, @@ -16,7 +15,7 @@ void infrared_scene_remote_list_on_enter(void* context) { true); if(success) { - view_set_orientation(view_stack_get_view(infrared->view_stack), ViewOrientationHorizontal); + view_set_orientation(view_stack_get_view(infrared->view_stack), ViewOrientationVertical); view_dispatcher_switch_to_view(view_dispatcher, InfraredViewStack); infrared_show_loading_popup(infrared, true); diff --git a/applications/infrared/scenes/infrared_scene_start.c b/applications/infrared/scenes/infrared_scene_start.c index 6b874a3ad..d188a6c36 100644 --- a/applications/infrared/scenes/infrared_scene_start.c +++ b/applications/infrared/scenes/infrared_scene_start.c @@ -66,6 +66,7 @@ bool infrared_scene_start_on_event(void* context, SceneManagerEvent event) { scene_manager_next_scene(scene_manager, InfraredSceneLearn); consumed = true; } else if(submenu_index == SubmenuIndexSavedRemotes) { + string_set_str(infrared->file_path, INFRARED_APP_FOLDER); scene_manager_next_scene(scene_manager, InfraredSceneRemoteList); consumed = true; } else if(submenu_index == SubmenuIndexDebug) { diff --git a/applications/lfrfid/scene/lfrfid_app_scene_exit_confirm.cpp b/applications/lfrfid/scene/lfrfid_app_scene_exit_confirm.cpp index d423cec9b..bac0247d9 100644 --- a/applications/lfrfid/scene/lfrfid_app_scene_exit_confirm.cpp +++ b/applications/lfrfid/scene/lfrfid_app_scene_exit_confirm.cpp @@ -19,7 +19,7 @@ void LfRfidAppSceneExitConfirm::on_enter(LfRfidApp* app, bool /* need_restore */ line_1->set_text("Exit to RFID menu?", 64, 19, 128 - 2, AlignCenter, AlignBottom, FontPrimary); line_2->set_text( - "All unsaved data will be lost", 64, 29, 0, AlignCenter, AlignBottom, FontSecondary); + "All unsaved data will be lost.", 64, 31, 0, AlignCenter, AlignBottom, FontSecondary); app->view_controller.switch_to(); } diff --git a/applications/lfrfid/scene/lfrfid_app_scene_read.cpp b/applications/lfrfid/scene/lfrfid_app_scene_read.cpp index f87aa200a..67279a163 100644 --- a/applications/lfrfid/scene/lfrfid_app_scene_read.cpp +++ b/applications/lfrfid/scene/lfrfid_app_scene_read.cpp @@ -22,9 +22,9 @@ bool LfRfidAppSceneRead::on_event(LfRfidApp* app, LfRfidApp::Event* event) { app->scene_controller.switch_to_next_scene(LfRfidApp::SceneType::ReadSuccess); } else { if(app->worker.any_read()) { - notification_message(app->notification, &sequence_blink_green_10); + notification_message(app->notification, &sequence_blink_yellow_10); } else if(app->worker.detect()) { - notification_message(app->notification, &sequence_blink_cyan_10); + notification_message(app->notification, &sequence_blink_yellow_10); } else { notification_message(app->notification, &sequence_blink_cyan_10); } diff --git a/applications/nfc/nfc.c b/applications/nfc/nfc.c index e98b5d9a5..0dc4b3ae1 100644 --- a/applications/nfc/nfc.c +++ b/applications/nfc/nfc.c @@ -125,6 +125,10 @@ Nfc* nfc_alloc() { nfc->popup = popup_alloc(); view_dispatcher_add_view(nfc->view_dispatcher, NfcViewPopup, popup_get_view(nfc->popup)); + // Loading + nfc->loading = loading_alloc(); + view_dispatcher_add_view(nfc->view_dispatcher, NfcViewLoading, loading_get_view(nfc->loading)); + // Text Input nfc->text_input = text_input_alloc(); view_dispatcher_add_view( @@ -179,6 +183,10 @@ void nfc_free(Nfc* nfc) { view_dispatcher_remove_view(nfc->view_dispatcher, NfcViewPopup); popup_free(nfc->popup); + // Loading + view_dispatcher_remove_view(nfc->view_dispatcher, NfcViewLoading); + loading_free(nfc->loading); + // TextInput view_dispatcher_remove_view(nfc->view_dispatcher, NfcViewTextInput); text_input_free(nfc->text_input); @@ -258,12 +266,27 @@ void nfc_blink_stop(Nfc* nfc) { notification_message(nfc->notifications, &sequence_blink_stop); } +void nfc_show_loading_popup(void* context, bool show) { + Nfc* nfc = 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(nfc->view_dispatcher, NfcViewLoading); + } else { + // Restore default timer priority + vTaskPrioritySet(timer_task, configTIMER_TASK_PRIORITY); + } +} + int32_t nfc_app(void* p) { Nfc* nfc = nfc_alloc(); char* args = p; // Check argument and run corresponding scene if((*args != '\0')) { + nfc_device_set_loading_callback(nfc->dev, nfc_show_loading_popup, nfc); uint32_t rpc_ctx = 0; if(sscanf(p, "RPC %lX", &rpc_ctx) == 1) { nfc->rpc_ctx = (void*)rpc_ctx; @@ -281,6 +304,7 @@ int32_t nfc_app(void* p) { // Exit app view_dispatcher_stop(nfc->view_dispatcher); } + nfc_device_set_loading_callback(nfc->dev, NULL, nfc); } else { scene_manager_next_scene(nfc->scene_manager, NfcSceneStart); } diff --git a/applications/nfc/nfc_device.c b/applications/nfc/nfc_device.c index 155cc3f84..e4f9ac565 100644 --- a/applications/nfc/nfc_device.c +++ b/applications/nfc/nfc_device.c @@ -846,6 +846,10 @@ static bool nfc_device_load_data(NfcDevice* dev, string_t path, bool show_dialog string_init(temp_str); bool deprecated_version = false; + if(dev->loading_cb) { + dev->loading_cb(dev->loading_cb_ctx, true); + } + do { // Check existance of shadow file nfc_device_get_shadow_path(path, temp_str); @@ -887,6 +891,10 @@ static bool nfc_device_load_data(NfcDevice* dev, string_t path, bool show_dialog parsed = true; } while(false); + if(dev->loading_cb) { + dev->loading_cb(dev->loading_cb_ctx, false); + } + if((!parsed) && (show_dialog)) { if(deprecated_version) { dialog_message_show_storage_error(dev->dialogs, "File format deprecated"); @@ -1024,3 +1032,10 @@ bool nfc_device_restore(NfcDevice* dev, bool use_load_path) { string_clear(path); return restored; } + +void nfc_device_set_loading_callback(NfcDevice* dev, NfcLoadingCallback callback, void* context) { + furi_assert(dev); + + dev->loading_cb = callback; + dev->loading_cb_ctx = context; +} diff --git a/applications/nfc/nfc_device.h b/applications/nfc/nfc_device.h index 3b2875c09..fee9b07e1 100644 --- a/applications/nfc/nfc_device.h +++ b/applications/nfc/nfc_device.h @@ -18,6 +18,8 @@ #define NFC_APP_EXTENSION ".nfc" #define NFC_APP_SHADOW_EXTENSION ".shd" +typedef void (*NfcLoadingCallback)(void* context, bool state); + typedef enum { NfcDeviceProtocolUnknown, NfcDeviceProtocolEMV, @@ -59,6 +61,9 @@ typedef struct { string_t load_path; NfcDeviceSaveFormat format; bool shadow_file_exist; + + NfcLoadingCallback loading_cb; + void* loading_cb_ctx; } NfcDevice; NfcDevice* nfc_device_alloc(); @@ -82,3 +87,5 @@ void nfc_device_clear(NfcDevice* dev); bool nfc_device_delete(NfcDevice* dev, bool use_load_path); bool nfc_device_restore(NfcDevice* dev, bool use_load_path); + +void nfc_device_set_loading_callback(NfcDevice* dev, NfcLoadingCallback callback, void* context); diff --git a/applications/nfc/nfc_i.h b/applications/nfc/nfc_i.h index c42ddced2..4b806d408 100755 --- a/applications/nfc/nfc_i.h +++ b/applications/nfc/nfc_i.h @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -63,6 +64,7 @@ struct Nfc { Submenu* submenu; DialogEx* dialog_ex; Popup* popup; + Loading* loading; TextInput* text_input; ByteInput* byte_input; TextBox* text_box; @@ -77,6 +79,7 @@ typedef enum { NfcViewMenu, NfcViewDialogEx, NfcViewPopup, + NfcViewLoading, NfcViewTextInput, NfcViewByteInput, NfcViewTextBox, @@ -97,4 +100,6 @@ void nfc_blink_start(Nfc* nfc); void nfc_blink_stop(Nfc* nfc); +void nfc_show_loading_popup(void* context, bool show); + void nfc_rpc_exit_callback(Nfc* nfc); diff --git a/applications/nfc/scenes/nfc_scene_file_select.c b/applications/nfc/scenes/nfc_scene_file_select.c index 36614bb8f..0278c3b9c 100755 --- a/applications/nfc/scenes/nfc_scene_file_select.c +++ b/applications/nfc/scenes/nfc_scene_file_select.c @@ -1,13 +1,16 @@ #include "../nfc_i.h" +#include "nfc/nfc_device.h" void nfc_scene_file_select_on_enter(void* context) { Nfc* nfc = context; // Process file_select return + nfc_device_set_loading_callback(nfc->dev, nfc_show_loading_popup, nfc); if(nfc_file_select(nfc->dev)) { scene_manager_next_scene(nfc->scene_manager, NfcSceneSavedMenu); } else { scene_manager_search_and_switch_to_previous_scene(nfc->scene_manager, NfcSceneStart); } + nfc_device_set_loading_callback(nfc->dev, NULL, nfc); } bool nfc_scene_file_select_on_event(void* context, SceneManagerEvent event) { diff --git a/assets/icons/Archive/loading_10px.png b/assets/icons/Archive/loading_10px.png index 9cc33b7fdb0af039d777f83421c3035d59ca4ace..4f626b3d58c1800c375ebbfd358db6c72374dbcf 100644 GIT binary patch delta 4341 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 ja-)vR)4GM delta 146 zcmeyXxR!B(ayFdh=jFp#HRM+RD&H|v2kEe@c zh{WaE{y@G11{_ZDzUSX4?%DEtMd6m%W8xeVs?Gi>6AtDql!!~Yr`&t%(&6k?G7|cq yFR%W_@3VSu&F0(DZEA0J#H_yk>9_L(#*Y`|=Ra0)6J_8An(XQ7=d#Wzp$P!)?>CeH diff --git a/assets/icons/Common/Loading_24/frame_01.png b/assets/icons/Common/Loading_24/frame_01.png index d1f35692590a934aa850a77b71c7923fc1b1b360..9c49dcad1cb6060c4057ad5c44d67f440c2a91b1 100644 GIT binary patch literal 3650 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 W-YVa~mCZmC89ZJ6T-G@yGywn-uQd|@ diff --git a/assets/icons/Common/Loading_24/frame_02.png b/assets/icons/Common/Loading_24/frame_02.png index b1617692131bd61a713453f0a025810acb8e446b..93a59fe681d26795d0db342a0c55ba42fc2c7529 100644 GIT binary patch literal 3649 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 LTALIbyM_M?u*zuP delta 178 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 UGJ6**0L^3YboFyt=akR{07E7*?*IS* diff --git a/assets/icons/Common/Loading_24/frame_04.png b/assets/icons/Common/Loading_24/frame_04.png index 7f55b0df457223e99a1eefbb4fbc5d1ad75dd431..adefde921e591dfbc18a438e6f350d27b314ae15 100644 GIT binary patch literal 3645 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 JmfHB7`5%CoVEzCA delta 174 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 diff --git a/assets/icons/Common/Loading_24/frame_06.png b/assets/icons/Common/Loading_24/frame_06.png index 3354ecda423dfc60a6836f8541f78b8f0bdde6bf..b768a7875f6fd1e259b30d9212e21df882a9da52 100644 GIT binary patch literal 3650 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 W0n(a=Iq%{Q0Jc^RmZcV+k^ckPJzkpt delta 168 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 Qb0?0anT=_&v0M260R4Sy)&Kwi delta 187 zcmX>ubDD92L_H%j0|UdYo$Gf4DaPU;cPEB*=VV?2IV|apzK#qG8~eHcB(eheYymzY zuK)l42QotsU9JOCoCO|{#S9GG!XV7ZFl&wkP|(lQ#W6(Uvh10SybT6CE*JfmoDiGZ zn$X@eah8^HDhJzwWZnKljvv3Qw$^CyoEczZ{e#zV$-%ONg{#iTpFW@~$)_1V`^_dV h-n$w5UbIa)$9+|pODR`h`8UvL22WQ%mvv4FO#s@bK