mag.c 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. #include "mag_i.h"
  2. static bool mag_debug_custom_event_callback(void* context, uint32_t event) {
  3. furi_assert(context);
  4. Mag* mag = context;
  5. return scene_manager_handle_custom_event(mag->scene_manager, event);
  6. }
  7. static bool mag_debug_back_event_callback(void* context) {
  8. furi_assert(context);
  9. Mag* mag = context;
  10. return scene_manager_handle_back_event(mag->scene_manager);
  11. }
  12. static Mag* mag_alloc() {
  13. Mag* mag = malloc(sizeof(Mag));
  14. mag->storage = furi_record_open(RECORD_STORAGE);
  15. mag->dialogs = furi_record_open(RECORD_DIALOGS);
  16. mag->file_name = furi_string_alloc();
  17. mag->file_path = furi_string_alloc_set(MAG_APP_FOLDER);
  18. mag->view_dispatcher = view_dispatcher_alloc();
  19. mag->scene_manager = scene_manager_alloc(&mag_scene_handlers, mag);
  20. view_dispatcher_enable_queue(mag->view_dispatcher);
  21. view_dispatcher_set_event_callback_context(mag->view_dispatcher, mag);
  22. view_dispatcher_set_custom_event_callback(
  23. mag->view_dispatcher, mag_debug_custom_event_callback);
  24. view_dispatcher_set_navigation_event_callback(
  25. mag->view_dispatcher, mag_debug_back_event_callback);
  26. // Open GUI record
  27. mag->gui = furi_record_open(RECORD_GUI);
  28. // Open Notification record
  29. mag->notifications = furi_record_open(RECORD_NOTIFICATION);
  30. // Submenu
  31. mag->submenu = submenu_alloc();
  32. view_dispatcher_add_view(mag->view_dispatcher, MagViewSubmenu, submenu_get_view(mag->submenu));
  33. // Dialog
  34. mag->dialog_ex = dialog_ex_alloc();
  35. view_dispatcher_add_view(
  36. mag->view_dispatcher, MagViewDialogEx, dialog_ex_get_view(mag->dialog_ex));
  37. // Popup
  38. mag->popup = popup_alloc();
  39. view_dispatcher_add_view(mag->view_dispatcher, MagViewPopup, popup_get_view(mag->popup));
  40. // Widget
  41. mag->widget = widget_alloc();
  42. view_dispatcher_add_view(mag->view_dispatcher, MagViewWidget, widget_get_view(mag->widget));
  43. // Text Input
  44. mag->text_input = text_input_alloc();
  45. view_dispatcher_add_view(
  46. mag->view_dispatcher, MagViewTextInput, text_input_get_view(mag->text_input));
  47. // Byte Input
  48. mag->byte_input = byte_input_alloc();
  49. view_dispatcher_add_view(
  50. mag->view_dispatcher, MagViewByteInput, byte_input_get_view(mag->byte_input));
  51. return mag;
  52. }
  53. static void mag_free(Mag* mag) {
  54. furi_assert(mag);
  55. furi_string_free(mag->file_name);
  56. furi_string_free(mag->file_path);
  57. // Submenu
  58. view_dispatcher_remove_view(mag->view_dispatcher, MagViewSubmenu);
  59. submenu_free(mag->submenu);
  60. // DialogEx
  61. view_dispatcher_remove_view(mag->view_dispatcher, MagViewDialogEx);
  62. dialog_ex_free(mag->dialog_ex);
  63. // Popup
  64. view_dispatcher_remove_view(mag->view_dispatcher, MagViewPopup);
  65. popup_free(mag->popup);
  66. // Widget
  67. view_dispatcher_remove_view(mag->view_dispatcher, MagViewWidget);
  68. widget_free(mag->widget);
  69. // TextInput
  70. view_dispatcher_remove_view(mag->view_dispatcher, MagViewTextInput);
  71. text_input_free(mag->text_input);
  72. // ByteInput
  73. view_dispatcher_remove_view(mag->view_dispatcher, MagViewByteInput);
  74. byte_input_free(mag->byte_input);
  75. // View Dispatcher
  76. view_dispatcher_free(mag->view_dispatcher);
  77. // Scene Manager
  78. scene_manager_free(mag->scene_manager);
  79. // GUI
  80. furi_record_close(RECORD_GUI);
  81. mag->gui = NULL;
  82. // Notifications
  83. furi_record_close(RECORD_NOTIFICATION);
  84. mag->notifications = NULL;
  85. furi_record_close(RECORD_STORAGE);
  86. furi_record_close(RECORD_DIALOGS);
  87. free(mag);
  88. }
  89. // entry point for app
  90. int32_t mag_app(void* p) {
  91. Mag* mag = mag_alloc();
  92. char* args = p;
  93. UNUSED(args);
  94. mag_make_app_folder(mag);
  95. view_dispatcher_attach_to_gui(mag->view_dispatcher, mag->gui, ViewDispatcherTypeFullscreen);
  96. scene_manager_next_scene(mag->scene_manager, MagSceneStart);
  97. view_dispatcher_run(mag->view_dispatcher);
  98. mag_free(mag);
  99. return 0;
  100. }
  101. bool mag_save_key(Mag* mag) {
  102. furi_assert(mag);
  103. bool result = false;
  104. mag_make_app_folder(mag);
  105. if(furi_string_end_with(mag->file_path, MAG_APP_EXTENSION)) {
  106. size_t filename_start = furi_string_search_rchar(mag->file_path, '/');
  107. furi_string_left(mag->file_path, filename_start);
  108. }
  109. furi_string_cat_printf(
  110. mag->file_path, "/%s%s", furi_string_get_cstr(mag->file_name), MAG_APP_EXTENSION);
  111. result = mag_save_key_data(mag, mag->file_path);
  112. return result;
  113. }
  114. bool mag_load_key_from_file_select(Mag* mag) {
  115. furi_assert(mag);
  116. DialogsFileBrowserOptions browser_options;
  117. // TODO: Fix icon reference / definition! Temporarily importing asset_icons.h in mag_i.h to let it compile. Remove when fixed!
  118. dialog_file_browser_set_basic_options(&browser_options, MAG_APP_EXTENSION, &I_125_10px);
  119. browser_options.base_path = MAG_APP_FOLDER;
  120. // Input events and views are managed by file_browser
  121. bool result =
  122. dialog_file_browser_show(mag->dialogs, mag->file_path, mag->file_path, &browser_options);
  123. if(result) {
  124. result = mag_load_key_data(mag, mag->file_path, true);
  125. }
  126. return result;
  127. }
  128. bool mag_delete_key(Mag* mag) {
  129. furi_assert(mag);
  130. return storage_simply_remove(mag->storage, furi_string_get_cstr(mag->file_path));
  131. }
  132. bool mag_load_key_data(Mag* mag, FuriString* path, bool show_dialog) {
  133. bool result = false;
  134. UNUSED(mag);
  135. UNUSED(path);
  136. UNUSED(show_dialog);
  137. // TODO: Needs reworking from LFRFID version, as that goes through some custom protocol by key type.
  138. return result;
  139. }
  140. bool mag_save_key_data(Mag* mag, FuriString* path) {
  141. bool result = false;
  142. UNUSED(path);
  143. //bool result = lfrfid_dict_file_save(app->dict, app->protocol_id, furi_string_get_cstr(path));
  144. // TODO: needs reworking from LFRFID version
  145. if(!result) {
  146. dialog_message_show_storage_error(mag->dialogs, "Cannot save\nkey file");
  147. }
  148. return result;
  149. }
  150. void mag_make_app_folder(Mag* mag) {
  151. furi_assert(mag);
  152. if(!storage_simply_mkdir(mag->storage, MAG_APP_FOLDER)) {
  153. dialog_message_show_storage_error(mag->dialogs, "Cannot create\napp folder");
  154. }
  155. }
  156. void mag_text_store_set(Mag* mag, const char* text, ...) {
  157. furi_assert(mag);
  158. va_list args;
  159. va_start(args, text);
  160. vsnprintf(mag->text_store, MAG_TEXT_STORE_SIZE, text, args);
  161. va_end(args);
  162. }
  163. void mag_text_store_clear(Mag* mag) {
  164. furi_assert(mag);
  165. memset(mag->text_store, 0, sizeof(mag->text_store));
  166. }
  167. void mag_popup_timeout_callback(void* context) {
  168. Mag* mag = context;
  169. view_dispatcher_send_custom_event(mag->view_dispatcher, MagEventPopupClosed);
  170. }
  171. void mag_widget_callback(GuiButtonType result, InputType type, void* context) {
  172. Mag* mag = context;
  173. if(type == InputTypeShort) {
  174. view_dispatcher_send_custom_event(mag->view_dispatcher, result);
  175. }
  176. }
  177. void mag_text_input_callback(void* context) {
  178. Mag* mag = context;
  179. view_dispatcher_send_custom_event(mag->view_dispatcher, MagEventNext);
  180. }