[FL-1962, FL-2464, FL-2465, FL-2466, FL-2560, FL-2637, FL-2595] Ibutton, Infrared, LfRFID GUI fixes (#1392)
* Ibutton, Infrared, LfRFID GUI fixes * Loading screens update Co-authored-by: あく <alleteam@gmail.com>
| @ -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) { | static void archive_draw_loading(Canvas* canvas, ArchiveBrowserViewModel* model) { | ||||||
|     furi_assert(model); |     furi_assert(model); | ||||||
| 
 | 
 | ||||||
|     uint8_t width = 49; |     uint8_t x = 128 / 2 - 24 / 2; | ||||||
|     uint8_t height = 47; |     uint8_t y = 64 / 2 - 24 / 2; | ||||||
|     uint8_t x = 128 / 2 - width / 2; |  | ||||||
|     uint8_t y = 64 / 2 - height / 2 + 6; |  | ||||||
| 
 | 
 | ||||||
|     elements_bold_rounded_frame(canvas, x, y, width, height); |     canvas_draw_icon(canvas, x, y, &A_Loading_24); | ||||||
| 
 |  | ||||||
|     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); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void draw_list(Canvas* canvas, ArchiveBrowserViewModel* model) { | static void draw_list(Canvas* canvas, ArchiveBrowserViewModel* model) { | ||||||
|  | |||||||
| @ -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) { | 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); |     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); |     canvas_draw_icon(canvas, x, y, &A_Loading_24); | ||||||
|     elements_multiline_text(canvas, x + 7, y + 13, "Loading..."); |  | ||||||
| 
 |  | ||||||
|     canvas_draw_icon(canvas, x + 13, y + 19, &A_Loading_24); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void browser_draw_list(Canvas* canvas, FileBrowserModel* model) { | static void browser_draw_list(Canvas* canvas, FileBrowserModel* model) { | ||||||
|  | |||||||
| @ -20,17 +20,16 @@ typedef struct { | |||||||
| static void loading_draw_callback(Canvas* canvas, void* _model) { | static void loading_draw_callback(Canvas* canvas, void* _model) { | ||||||
|     LoadingModel* model = (LoadingModel*)_model; |     LoadingModel* model = (LoadingModel*)_model; | ||||||
| 
 | 
 | ||||||
|     uint8_t width = 49; |     canvas_set_color(canvas, ColorWhite); | ||||||
|     uint8_t height = 47; |     canvas_draw_box(canvas, 0, 0, canvas_width(canvas), canvas_height(canvas)); | ||||||
|     uint8_t x = (canvas_width(canvas) - width) / 2; |     canvas_set_color(canvas, ColorBlack); | ||||||
|     uint8_t y = (canvas_height(canvas) - height) / 2; |  | ||||||
| 
 | 
 | ||||||
|     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); |     canvas_draw_icon(canvas, x, y, &A_Loading_24); | ||||||
|     elements_multiline_text(canvas, x + 7, y + 13, "Loading..."); |  | ||||||
| 
 | 
 | ||||||
|     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) { | static bool loading_input_callback(InputEvent* event, void* context) { | ||||||
|  | |||||||
| @ -23,7 +23,8 @@ void ibutton_scene_add_type_on_enter(void* context) { | |||||||
|     submenu_add_item( |     submenu_add_item( | ||||||
|         submenu, "Metakom", SubmenuIndexMetakom, ibutton_scene_add_type_submenu_callback, ibutton); |         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); |     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; |     bool consumed = false; | ||||||
| 
 | 
 | ||||||
|     if(event.type == SceneManagerEventTypeCustom) { |     if(event.type == SceneManagerEventTypeCustom) { | ||||||
|  |         scene_manager_set_scene_state(ibutton->scene_manager, iButtonSceneAddType, event.event); | ||||||
|         consumed = true; |         consumed = true; | ||||||
|         if(event.event == SubmenuIndexCyfral) { |         if(event.event == SubmenuIndexCyfral) { | ||||||
|             ibutton_key_set_type(key, iButtonKeyCyfral); |             ibutton_key_set_type(key, iButtonKeyCyfral); | ||||||
|  | |||||||
| @ -19,9 +19,9 @@ void ibutton_scene_exit_confirm_on_enter(void* context) { | |||||||
|     widget_add_button_element( |     widget_add_button_element( | ||||||
|         widget, GuiButtonTypeRight, "Stay", ibutton_scene_exit_confirm_widget_callback, ibutton); |         widget, GuiButtonTypeRight, "Stay", ibutton_scene_exit_confirm_widget_callback, ibutton); | ||||||
|     widget_add_string_element( |     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_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); |     view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewWidget); | ||||||
| } | } | ||||||
|  | |||||||
| @ -43,7 +43,10 @@ bool ibutton_scene_read_crc_error_on_event(void* context, SceneManagerEvent even | |||||||
|     SceneManager* scene_manager = ibutton->scene_manager; |     SceneManager* scene_manager = ibutton->scene_manager; | ||||||
|     bool consumed = false; |     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; |         consumed = true; | ||||||
|         if(event.event == DialogExResultRight) { |         if(event.event == DialogExResultRight) { | ||||||
|             scene_manager_next_scene(scene_manager, iButtonSceneReadKeyMenu); |             scene_manager_next_scene(scene_manager, iButtonSceneReadKeyMenu); | ||||||
|  | |||||||
| @ -31,8 +31,8 @@ void ibutton_scene_read_key_menu_on_enter(void* context) { | |||||||
|             ibutton_scene_read_key_menu_submenu_callback, |             ibutton_scene_read_key_menu_submenu_callback, | ||||||
|             ibutton); |             ibutton); | ||||||
|     } |     } | ||||||
| 
 |     submenu_set_selected_item( | ||||||
|     submenu_set_selected_item(submenu, SubmenuIndexSave); |         submenu, scene_manager_get_scene_state(ibutton->scene_manager, iButtonSceneReadKeyMenu)); | ||||||
| 
 | 
 | ||||||
|     view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewSubmenu); |     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; |     bool consumed = false; | ||||||
| 
 | 
 | ||||||
|     if(event.type == SceneManagerEventTypeCustom) { |     if(event.type == SceneManagerEventTypeCustom) { | ||||||
|  |         scene_manager_set_scene_state( | ||||||
|  |             ibutton->scene_manager, iButtonSceneReadKeyMenu, event.event); | ||||||
|         consumed = true; |         consumed = true; | ||||||
|         if(event.event == SubmenuIndexSave) { |         if(event.event == SubmenuIndexSave) { | ||||||
|             scene_manager_next_scene(ibutton->scene_manager, iButtonSceneSaveName); |             scene_manager_next_scene(ibutton->scene_manager, iButtonSceneSaveName); | ||||||
|  | |||||||
| @ -44,7 +44,10 @@ bool ibutton_scene_read_not_key_error_on_event(void* context, SceneManagerEvent | |||||||
|     SceneManager* scene_manager = ibutton->scene_manager; |     SceneManager* scene_manager = ibutton->scene_manager; | ||||||
|     bool consumed = false; |     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; |         consumed = true; | ||||||
|         if(event.event == DialogExResultRight) { |         if(event.event == DialogExResultRight) { | ||||||
|             scene_manager_next_scene(scene_manager, iButtonSceneReadKeyMenu); |             scene_manager_next_scene(scene_manager, iButtonSceneReadKeyMenu); | ||||||
|  | |||||||
| @ -42,7 +42,8 @@ void ibutton_scene_saved_key_menu_on_enter(void* context) { | |||||||
|     submenu_add_item( |     submenu_add_item( | ||||||
|         submenu, "Info", SubmenuIndexInfo, ibutton_scene_saved_key_menu_submenu_callback, ibutton); |         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); |     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; |     bool consumed = false; | ||||||
| 
 | 
 | ||||||
|     if(event.type == SceneManagerEventTypeCustom) { |     if(event.type == SceneManagerEventTypeCustom) { | ||||||
|  |         scene_manager_set_scene_state( | ||||||
|  |             ibutton->scene_manager, iButtonSceneSavedKeyMenu, event.event); | ||||||
|         consumed = true; |         consumed = true; | ||||||
|         if(event.event == SubmenuIndexEmulate) { |         if(event.event == SubmenuIndexEmulate) { | ||||||
|             scene_manager_next_scene(ibutton->scene_manager, iButtonSceneEmulate); |             scene_manager_next_scene(ibutton->scene_manager, iButtonSceneEmulate); | ||||||
|  | |||||||
| @ -1,4 +1,5 @@ | |||||||
| #include "../ibutton_i.h" | #include "../ibutton_i.h" | ||||||
|  | #include "ibutton/scenes/ibutton_scene.h" | ||||||
| 
 | 
 | ||||||
| enum SubmenuIndex { | enum SubmenuIndex { | ||||||
|     SubmenuIndexRead, |     SubmenuIndexRead, | ||||||
| @ -22,7 +23,8 @@ void ibutton_scene_start_on_enter(void* context) { | |||||||
|     submenu_add_item( |     submenu_add_item( | ||||||
|         submenu, "Add Manually", SubmenuIndexAdd, ibutton_scene_start_submenu_callback, ibutton); |         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); |     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; |     bool consumed = false; | ||||||
| 
 | 
 | ||||||
|     if(event.type == SceneManagerEventTypeCustom) { |     if(event.type == SceneManagerEventTypeCustom) { | ||||||
|  |         scene_manager_set_scene_state(ibutton->scene_manager, iButtonSceneStart, event.event); | ||||||
|         consumed = true; |         consumed = true; | ||||||
|         if(event.event == SubmenuIndexRead) { |         if(event.event == SubmenuIndexRead) { | ||||||
|             scene_manager_next_scene(ibutton->scene_manager, iButtonSceneRead); |             scene_manager_next_scene(ibutton->scene_manager, iButtonSceneRead); | ||||||
|  | |||||||
							
								
								
									
										48
									
								
								applications/infrared/scenes/infrared_scene_ask_retry.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -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); | ||||||
|  | } | ||||||
| @ -1,5 +1,6 @@ | |||||||
| ADD_SCENE(infrared, start, Start) | ADD_SCENE(infrared, start, Start) | ||||||
| ADD_SCENE(infrared, ask_back, AskBack) | ADD_SCENE(infrared, ask_back, AskBack) | ||||||
|  | ADD_SCENE(infrared, ask_retry, AskRetry) | ||||||
| ADD_SCENE(infrared, edit, Edit) | ADD_SCENE(infrared, edit, Edit) | ||||||
| ADD_SCENE(infrared, edit_delete, EditDelete) | ADD_SCENE(infrared, edit_delete, EditDelete) | ||||||
| ADD_SCENE(infrared, edit_delete_done, EditDeleteDone) | ADD_SCENE(infrared, edit_delete_done, EditDeleteDone) | ||||||
|  | |||||||
| @ -89,8 +89,7 @@ bool infrared_scene_learn_success_on_event(void* context, SceneManagerEvent even | |||||||
|     } else if(event.type == SceneManagerEventTypeCustom) { |     } else if(event.type == SceneManagerEventTypeCustom) { | ||||||
|         if(event.event == DialogExResultLeft) { |         if(event.event == DialogExResultLeft) { | ||||||
|             if(scene_state == InfraredSceneLearnSuccessStateIdle) { |             if(scene_state == InfraredSceneLearnSuccessStateIdle) { | ||||||
|                 scene_manager_search_and_switch_to_previous_scene( |                 scene_manager_next_scene(scene_manager, InfraredSceneAskRetry); | ||||||
|                     scene_manager, InfraredSceneLearn); |  | ||||||
|             } |             } | ||||||
|             consumed = true; |             consumed = true; | ||||||
|         } else if(event.event == DialogExResultRight) { |         } else if(event.event == DialogExResultRight) { | ||||||
|  | |||||||
| @ -5,7 +5,6 @@ void infrared_scene_remote_list_on_enter(void* context) { | |||||||
|     SceneManager* scene_manager = infrared->scene_manager; |     SceneManager* scene_manager = infrared->scene_manager; | ||||||
|     ViewDispatcher* view_dispatcher = infrared->view_dispatcher; |     ViewDispatcher* view_dispatcher = infrared->view_dispatcher; | ||||||
| 
 | 
 | ||||||
|     string_set_str(infrared->file_path, INFRARED_APP_FOLDER); |  | ||||||
|     bool success = dialog_file_browser_show( |     bool success = dialog_file_browser_show( | ||||||
|         infrared->dialogs, |         infrared->dialogs, | ||||||
|         infrared->file_path, |         infrared->file_path, | ||||||
| @ -16,7 +15,7 @@ void infrared_scene_remote_list_on_enter(void* context) { | |||||||
|         true); |         true); | ||||||
| 
 | 
 | ||||||
|     if(success) { |     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); |         view_dispatcher_switch_to_view(view_dispatcher, InfraredViewStack); | ||||||
| 
 | 
 | ||||||
|         infrared_show_loading_popup(infrared, true); |         infrared_show_loading_popup(infrared, true); | ||||||
|  | |||||||
| @ -66,6 +66,7 @@ bool infrared_scene_start_on_event(void* context, SceneManagerEvent event) { | |||||||
|             scene_manager_next_scene(scene_manager, InfraredSceneLearn); |             scene_manager_next_scene(scene_manager, InfraredSceneLearn); | ||||||
|             consumed = true; |             consumed = true; | ||||||
|         } else if(submenu_index == SubmenuIndexSavedRemotes) { |         } else if(submenu_index == SubmenuIndexSavedRemotes) { | ||||||
|  |             string_set_str(infrared->file_path, INFRARED_APP_FOLDER); | ||||||
|             scene_manager_next_scene(scene_manager, InfraredSceneRemoteList); |             scene_manager_next_scene(scene_manager, InfraredSceneRemoteList); | ||||||
|             consumed = true; |             consumed = true; | ||||||
|         } else if(submenu_index == SubmenuIndexDebug) { |         } else if(submenu_index == SubmenuIndexDebug) { | ||||||
|  | |||||||
| @ -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_1->set_text("Exit to RFID menu?", 64, 19, 128 - 2, AlignCenter, AlignBottom, FontPrimary); | ||||||
|     line_2->set_text( |     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<ContainerVM>(); |     app->view_controller.switch_to<ContainerVM>(); | ||||||
| } | } | ||||||
|  | |||||||
| @ -22,9 +22,9 @@ bool LfRfidAppSceneRead::on_event(LfRfidApp* app, LfRfidApp::Event* event) { | |||||||
|             app->scene_controller.switch_to_next_scene(LfRfidApp::SceneType::ReadSuccess); |             app->scene_controller.switch_to_next_scene(LfRfidApp::SceneType::ReadSuccess); | ||||||
|         } else { |         } else { | ||||||
|             if(app->worker.any_read()) { |             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()) { |             } else if(app->worker.detect()) { | ||||||
|                 notification_message(app->notification, &sequence_blink_cyan_10); |                 notification_message(app->notification, &sequence_blink_yellow_10); | ||||||
|             } else { |             } else { | ||||||
|                 notification_message(app->notification, &sequence_blink_cyan_10); |                 notification_message(app->notification, &sequence_blink_cyan_10); | ||||||
|             } |             } | ||||||
|  | |||||||
| @ -125,6 +125,10 @@ Nfc* nfc_alloc() { | |||||||
|     nfc->popup = popup_alloc(); |     nfc->popup = popup_alloc(); | ||||||
|     view_dispatcher_add_view(nfc->view_dispatcher, NfcViewPopup, popup_get_view(nfc->popup)); |     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
 |     // Text Input
 | ||||||
|     nfc->text_input = text_input_alloc(); |     nfc->text_input = text_input_alloc(); | ||||||
|     view_dispatcher_add_view( |     view_dispatcher_add_view( | ||||||
| @ -179,6 +183,10 @@ void nfc_free(Nfc* nfc) { | |||||||
|     view_dispatcher_remove_view(nfc->view_dispatcher, NfcViewPopup); |     view_dispatcher_remove_view(nfc->view_dispatcher, NfcViewPopup); | ||||||
|     popup_free(nfc->popup); |     popup_free(nfc->popup); | ||||||
| 
 | 
 | ||||||
|  |     // Loading
 | ||||||
|  |     view_dispatcher_remove_view(nfc->view_dispatcher, NfcViewLoading); | ||||||
|  |     loading_free(nfc->loading); | ||||||
|  | 
 | ||||||
|     // TextInput
 |     // TextInput
 | ||||||
|     view_dispatcher_remove_view(nfc->view_dispatcher, NfcViewTextInput); |     view_dispatcher_remove_view(nfc->view_dispatcher, NfcViewTextInput); | ||||||
|     text_input_free(nfc->text_input); |     text_input_free(nfc->text_input); | ||||||
| @ -258,12 +266,27 @@ void nfc_blink_stop(Nfc* nfc) { | |||||||
|     notification_message(nfc->notifications, &sequence_blink_stop); |     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) { | int32_t nfc_app(void* p) { | ||||||
|     Nfc* nfc = nfc_alloc(); |     Nfc* nfc = nfc_alloc(); | ||||||
|     char* args = p; |     char* args = p; | ||||||
| 
 | 
 | ||||||
|     // Check argument and run corresponding scene
 |     // Check argument and run corresponding scene
 | ||||||
|     if((*args != '\0')) { |     if((*args != '\0')) { | ||||||
|  |         nfc_device_set_loading_callback(nfc->dev, nfc_show_loading_popup, nfc); | ||||||
|         uint32_t rpc_ctx = 0; |         uint32_t rpc_ctx = 0; | ||||||
|         if(sscanf(p, "RPC %lX", &rpc_ctx) == 1) { |         if(sscanf(p, "RPC %lX", &rpc_ctx) == 1) { | ||||||
|             nfc->rpc_ctx = (void*)rpc_ctx; |             nfc->rpc_ctx = (void*)rpc_ctx; | ||||||
| @ -281,6 +304,7 @@ int32_t nfc_app(void* p) { | |||||||
|             // Exit app
 |             // Exit app
 | ||||||
|             view_dispatcher_stop(nfc->view_dispatcher); |             view_dispatcher_stop(nfc->view_dispatcher); | ||||||
|         } |         } | ||||||
|  |         nfc_device_set_loading_callback(nfc->dev, NULL, nfc); | ||||||
|     } else { |     } else { | ||||||
|         scene_manager_next_scene(nfc->scene_manager, NfcSceneStart); |         scene_manager_next_scene(nfc->scene_manager, NfcSceneStart); | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -846,6 +846,10 @@ static bool nfc_device_load_data(NfcDevice* dev, string_t path, bool show_dialog | |||||||
|     string_init(temp_str); |     string_init(temp_str); | ||||||
|     bool deprecated_version = false; |     bool deprecated_version = false; | ||||||
| 
 | 
 | ||||||
|  |     if(dev->loading_cb) { | ||||||
|  |         dev->loading_cb(dev->loading_cb_ctx, true); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     do { |     do { | ||||||
|         // Check existance of shadow file
 |         // Check existance of shadow file
 | ||||||
|         nfc_device_get_shadow_path(path, temp_str); |         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; |         parsed = true; | ||||||
|     } while(false); |     } while(false); | ||||||
| 
 | 
 | ||||||
|  |     if(dev->loading_cb) { | ||||||
|  |         dev->loading_cb(dev->loading_cb_ctx, false); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     if((!parsed) && (show_dialog)) { |     if((!parsed) && (show_dialog)) { | ||||||
|         if(deprecated_version) { |         if(deprecated_version) { | ||||||
|             dialog_message_show_storage_error(dev->dialogs, "File format deprecated"); |             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); |     string_clear(path); | ||||||
|     return restored; |     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; | ||||||
|  | } | ||||||
|  | |||||||
| @ -18,6 +18,8 @@ | |||||||
| #define NFC_APP_EXTENSION ".nfc" | #define NFC_APP_EXTENSION ".nfc" | ||||||
| #define NFC_APP_SHADOW_EXTENSION ".shd" | #define NFC_APP_SHADOW_EXTENSION ".shd" | ||||||
| 
 | 
 | ||||||
|  | typedef void (*NfcLoadingCallback)(void* context, bool state); | ||||||
|  | 
 | ||||||
| typedef enum { | typedef enum { | ||||||
|     NfcDeviceProtocolUnknown, |     NfcDeviceProtocolUnknown, | ||||||
|     NfcDeviceProtocolEMV, |     NfcDeviceProtocolEMV, | ||||||
| @ -59,6 +61,9 @@ typedef struct { | |||||||
|     string_t load_path; |     string_t load_path; | ||||||
|     NfcDeviceSaveFormat format; |     NfcDeviceSaveFormat format; | ||||||
|     bool shadow_file_exist; |     bool shadow_file_exist; | ||||||
|  | 
 | ||||||
|  |     NfcLoadingCallback loading_cb; | ||||||
|  |     void* loading_cb_ctx; | ||||||
| } NfcDevice; | } NfcDevice; | ||||||
| 
 | 
 | ||||||
| NfcDevice* nfc_device_alloc(); | 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_delete(NfcDevice* dev, bool use_load_path); | ||||||
| 
 | 
 | ||||||
| bool nfc_device_restore(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); | ||||||
|  | |||||||
| @ -18,6 +18,7 @@ | |||||||
| #include <gui/modules/submenu.h> | #include <gui/modules/submenu.h> | ||||||
| #include <gui/modules/dialog_ex.h> | #include <gui/modules/dialog_ex.h> | ||||||
| #include <gui/modules/popup.h> | #include <gui/modules/popup.h> | ||||||
|  | #include <gui/modules/loading.h> | ||||||
| #include <gui/modules/text_input.h> | #include <gui/modules/text_input.h> | ||||||
| #include <gui/modules/byte_input.h> | #include <gui/modules/byte_input.h> | ||||||
| #include <gui/modules/text_box.h> | #include <gui/modules/text_box.h> | ||||||
| @ -63,6 +64,7 @@ struct Nfc { | |||||||
|     Submenu* submenu; |     Submenu* submenu; | ||||||
|     DialogEx* dialog_ex; |     DialogEx* dialog_ex; | ||||||
|     Popup* popup; |     Popup* popup; | ||||||
|  |     Loading* loading; | ||||||
|     TextInput* text_input; |     TextInput* text_input; | ||||||
|     ByteInput* byte_input; |     ByteInput* byte_input; | ||||||
|     TextBox* text_box; |     TextBox* text_box; | ||||||
| @ -77,6 +79,7 @@ typedef enum { | |||||||
|     NfcViewMenu, |     NfcViewMenu, | ||||||
|     NfcViewDialogEx, |     NfcViewDialogEx, | ||||||
|     NfcViewPopup, |     NfcViewPopup, | ||||||
|  |     NfcViewLoading, | ||||||
|     NfcViewTextInput, |     NfcViewTextInput, | ||||||
|     NfcViewByteInput, |     NfcViewByteInput, | ||||||
|     NfcViewTextBox, |     NfcViewTextBox, | ||||||
| @ -97,4 +100,6 @@ void nfc_blink_start(Nfc* nfc); | |||||||
| 
 | 
 | ||||||
| void nfc_blink_stop(Nfc* nfc); | void nfc_blink_stop(Nfc* nfc); | ||||||
| 
 | 
 | ||||||
|  | void nfc_show_loading_popup(void* context, bool show); | ||||||
|  | 
 | ||||||
| void nfc_rpc_exit_callback(Nfc* nfc); | void nfc_rpc_exit_callback(Nfc* nfc); | ||||||
|  | |||||||
| @ -1,13 +1,16 @@ | |||||||
| #include "../nfc_i.h" | #include "../nfc_i.h" | ||||||
|  | #include "nfc/nfc_device.h" | ||||||
| 
 | 
 | ||||||
| void nfc_scene_file_select_on_enter(void* context) { | void nfc_scene_file_select_on_enter(void* context) { | ||||||
|     Nfc* nfc = context; |     Nfc* nfc = context; | ||||||
|     // Process file_select return
 |     // Process file_select return
 | ||||||
|  |     nfc_device_set_loading_callback(nfc->dev, nfc_show_loading_popup, nfc); | ||||||
|     if(nfc_file_select(nfc->dev)) { |     if(nfc_file_select(nfc->dev)) { | ||||||
|         scene_manager_next_scene(nfc->scene_manager, NfcSceneSavedMenu); |         scene_manager_next_scene(nfc->scene_manager, NfcSceneSavedMenu); | ||||||
|     } else { |     } else { | ||||||
|         scene_manager_search_and_switch_to_previous_scene(nfc->scene_manager, NfcSceneStart); |         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) { | bool nfc_scene_file_select_on_event(void* context, SceneManagerEvent event) { | ||||||
|  | |||||||
| Before Width: | Height: | Size: 173 B After Width: | Height: | Size: 4.2 KiB | 
| Before Width: | Height: | Size: 194 B After Width: | Height: | Size: 3.6 KiB | 
| Before Width: | Height: | Size: 194 B After Width: | Height: | Size: 3.6 KiB | 
| Before Width: | Height: | Size: 192 B After Width: | Height: | Size: 3.6 KiB | 
| Before Width: | Height: | Size: 190 B After Width: | Height: | Size: 3.6 KiB | 
| Before Width: | Height: | Size: 203 B After Width: | Height: | Size: 3.6 KiB | 
| Before Width: | Height: | Size: 184 B After Width: | Height: | Size: 3.6 KiB | 
| Before Width: | Height: | Size: 203 B After Width: | Height: | Size: 3.6 KiB | 
 Nikolay Minaylov
						Nikolay Minaylov