diff --git a/application.fam b/application.fam index dd3a8c6eeca..4d669c4e29a 100644 --- a/application.fam +++ b/application.fam @@ -13,7 +13,7 @@ App( provides=[], stack_size=2 * 1024, order=20, - fap_icon="mag_10px.png", + fap_icon="icons/mag_10px.png", fap_category="Tools", fap_icon_assets="icons", -) \ No newline at end of file +) diff --git a/mag.c b/mag.c index 3f2fd4fa476..713b91dd3f3 100644 --- a/mag.c +++ b/mag.c @@ -1,5 +1,7 @@ #include "mag_i.h" +#define TAG "Mag" + static bool mag_debug_custom_event_callback(void* context, uint32_t event) { furi_assert(context); Mag* mag = context; @@ -30,6 +32,8 @@ static Mag* mag_alloc() { view_dispatcher_set_navigation_event_callback( mag->view_dispatcher, mag_debug_back_event_callback); + mag->mag_dev = mag_device_alloc(); + // Open GUI record mag->gui = furi_record_open(RECORD_GUI); @@ -49,6 +53,10 @@ static Mag* mag_alloc() { mag->popup = popup_alloc(); view_dispatcher_add_view(mag->view_dispatcher, MagViewPopup, popup_get_view(mag->popup)); + // Loading + mag->loading = loading_alloc(); + view_dispatcher_add_view(mag->view_dispatcher, MagViewLoading, loading_get_view(mag->loading)); + // Widget mag->widget = widget_alloc(); view_dispatcher_add_view(mag->view_dispatcher, MagViewWidget, widget_get_view(mag->widget)); @@ -58,11 +66,6 @@ static Mag* mag_alloc() { view_dispatcher_add_view( mag->view_dispatcher, MagViewTextInput, text_input_get_view(mag->text_input)); - // Byte Input - mag->byte_input = byte_input_alloc(); - view_dispatcher_add_view( - mag->view_dispatcher, MagViewByteInput, byte_input_get_view(mag->byte_input)); - return mag; } @@ -72,6 +75,10 @@ static void mag_free(Mag* mag) { furi_string_free(mag->file_name); furi_string_free(mag->file_path); + // Mag device + mag_device_free(mag->mag_dev); + mag->mag_dev = NULL; + // Submenu view_dispatcher_remove_view(mag->view_dispatcher, MagViewSubmenu); submenu_free(mag->submenu); @@ -84,6 +91,10 @@ static void mag_free(Mag* mag) { view_dispatcher_remove_view(mag->view_dispatcher, MagViewPopup); popup_free(mag->popup); + // Loading + view_dispatcher_remove_view(mag->view_dispatcher, MagViewLoading); + loading_free(mag->loading); + // Widget view_dispatcher_remove_view(mag->view_dispatcher, MagViewWidget); widget_free(mag->widget); @@ -92,10 +103,6 @@ static void mag_free(Mag* mag) { view_dispatcher_remove_view(mag->view_dispatcher, MagViewTextInput); text_input_free(mag->text_input); - // ByteInput - view_dispatcher_remove_view(mag->view_dispatcher, MagViewByteInput); - byte_input_free(mag->byte_input); - // View Dispatcher view_dispatcher_free(mag->view_dispatcher); @@ -118,18 +125,24 @@ static void mag_free(Mag* mag) { // entry point for app int32_t mag_app(void* p) { + FURI_LOG_D(TAG, "Start"); Mag* mag = mag_alloc(); - char* args = p; - UNUSED(args); + FURI_LOG_D(TAG, "Mag alloc-ed"); + UNUSED(p); mag_make_app_folder(mag); + FURI_LOG_D(TAG, "mag_make_app_folder done"); view_dispatcher_attach_to_gui(mag->view_dispatcher, mag->gui, ViewDispatcherTypeFullscreen); + FURI_LOG_D(TAG, "view_dispatcher_attach... done"); scene_manager_next_scene(mag->scene_manager, MagSceneStart); + FURI_LOG_D(TAG, "scene manager next scene done"); view_dispatcher_run(mag->view_dispatcher); + FURI_LOG_D(TAG, "view dispatcher run done"); mag_free(mag); + FURI_LOG_D(TAG, "mag free done"); return 0; } @@ -157,8 +170,7 @@ bool mag_load_key_from_file_select(Mag* mag) { furi_assert(mag); DialogsFileBrowserOptions browser_options; - // TODO: Fix icon reference / definition! Temporarily importing asset_icons.h in mag_i.h to let it compile. Remove when fixed! - dialog_file_browser_set_basic_options(&browser_options, MAG_APP_EXTENSION, &I_125_10px); + dialog_file_browser_set_basic_options(&browser_options, MAG_APP_EXTENSION, &I_mag_10px); browser_options.base_path = MAG_APP_FOLDER; // Input events and views are managed by file_browser @@ -241,3 +253,17 @@ void mag_text_input_callback(void* context) { Mag* mag = context; view_dispatcher_send_custom_event(mag->view_dispatcher, MagEventNext); } + +void mag_show_loading_popup(void* context, bool show) { + Mag* mag = 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(mag->view_dispatcher, MagViewLoading); + } else { + // Restore default timer priority + vTaskPrioritySet(timer_task, configTIMER_TASK_PRIORITY); + } +} diff --git a/mag_10px.png b/mag_10px.png deleted file mode 100644 index cb3a2e688de..00000000000 Binary files a/mag_10px.png and /dev/null differ diff --git a/mag_device.c b/mag_device.c index e326fadaf4c..bd3fcaa4a87 100644 --- a/mag_device.c +++ b/mag_device.c @@ -3,5 +3,219 @@ #include #include -//static const char* mag_file_header = "Flipper Mag device"; -//static const uint32_t mag_file_version = 1; \ No newline at end of file +#define TAG "MagDevice" + +static const char* mag_file_header = "Flipper Mag device"; +static const uint32_t mag_file_version = 0; + +MagDevice* mag_device_alloc() { + MagDevice* mag_dev = malloc(sizeof(MagDevice)); + mag_dev->dev_data = furi_string_alloc(); + mag_dev->storage = furi_record_open(RECORD_STORAGE); + mag_dev->dialogs = furi_record_open(RECORD_DIALOGS); + mag_dev->load_path = furi_string_alloc(); + return mag_dev; +} + +void mag_device_data_clear(FuriString* dev_data) { + furi_string_reset(dev_data); +} + +void mag_device_clear(MagDevice* mag_dev) { + furi_assert(mag_dev); + + mag_device_data_clear(mag_dev->dev_data); + memset(&mag_dev->dev_data, 0, sizeof(mag_dev->dev_data)); + furi_string_reset(mag_dev->load_path); +} + +void mag_device_free(MagDevice* mag_dev) { + furi_assert(mag_dev); + + mag_device_clear(mag_dev); + furi_record_close(RECORD_STORAGE); + furi_record_close(RECORD_DIALOGS); + furi_string_free(mag_dev->load_path); + free(mag_dev); +} + +void mag_device_set_name(MagDevice* mag_dev, const char* name) { + furi_assert(mag_dev); + + strlcpy(mag_dev->dev_name, name, MAG_DEV_NAME_MAX_LEN); +} + +static bool mag_device_save_file( + MagDevice* mag_dev, + const char* dev_name, + const char* folder, + const char* extension, + bool use_load_path) { + furi_assert(mag_dev); + + bool saved = false; + FlipperFormat* file = flipper_format_file_alloc(mag_dev->storage); + FuriString* temp_str; + temp_str = furi_string_alloc(); + + do { + if(use_load_path && !furi_string_empty(mag_dev->load_path)) { + // Get dir name + path_extract_dirname(furi_string_get_cstr(mag_dev->load_path), temp_str); + // Create mag directory if necessary + if(!storage_simply_mkdir((mag_dev->storage), furi_string_get_cstr(temp_str))) break; + // Make path to file to be saved + furi_string_cat_printf(temp_str, "/%s%s", dev_name, extension); + } else { + // Create mag directory if necessary + if(!storage_simply_mkdir((mag_dev->storage), MAG_APP_FOLDER)) break; + // First remove mag device file if it was saved + furi_string_printf(temp_str, "%s/%s%s", folder, dev_name, extension); + } + // Open file + if(!flipper_format_file_open_always(file, furi_string_get_cstr(temp_str))) break; + + // Write header + if(!flipper_format_write_header_cstr(file, mag_file_header, mag_file_version)) break; + + // Write comment + if(!flipper_format_write_comment_cstr(file, "Mag device track data")) break; + + // Write data + if(!flipper_format_write_string_cstr(file, "Data", furi_string_get_cstr(mag_dev->dev_data))) + break; + + saved = true; + } while(0); + + if(!saved) { + dialog_message_show_storage_error(mag_dev->dialogs, "Cannot save\nfile"); + } + + furi_string_free(temp_str); + flipper_format_free(file); + + // TODO. Extrapolating from the picopass app + return saved; +} + +bool mag_device_save(MagDevice* mag_dev, const char* dev_name) { + // wrapping function in the event we have multiple formats + return mag_device_save_file(mag_dev, dev_name, MAG_APP_FOLDER, MAG_APP_EXTENSION, true); +} + +static bool mag_device_load_data(MagDevice* mag_dev, FuriString* path, bool show_dialog) { + bool parsed = false; + + FlipperFormat* file = flipper_format_file_alloc(mag_dev->storage); + FuriString* temp_str; + temp_str = furi_string_alloc(); + bool deprecated_version = false; + bool data_read = true; + + if(mag_dev->loading_cb) { + mag_dev->loading_cb(mag_dev->loading_cb_ctx, true); + } + + do { + if(!flipper_format_file_open_existing(file, furi_string_get_cstr(path))) break; + + // Read and verify header, check file version + uint32_t version; + if(!flipper_format_read_header(file, temp_str, &version)) break; + if(furi_string_cmp_str(temp_str, mag_file_header) || (version != mag_file_version)) { + deprecated_version = true; + break; + } + + // Parse data + if(!flipper_format_read_string(file, "Data", mag_dev->dev_data)) { + data_read = false; + break; + } + + parsed = true; + } while(false); + + if((!parsed) && (show_dialog)) { + if(deprecated_version) { + dialog_message_show_storage_error(mag_dev->dialogs, "File format\ndeprecated"); + } else if(!data_read) { + dialog_message_show_storage_error(mag_dev->dialogs, "Cannot read\ndata"); + } else { + dialog_message_show_storage_error(mag_dev->dialogs, "Cannot parse\nfile"); + } + } + + furi_string_free(temp_str); + flipper_format_free(file); + + return parsed; +} + +bool mag_file_select(MagDevice* mag_dev) { + furi_assert(mag_dev); + + // Input events and views are managed by file_browser + FuriString* mag_app_folder; + mag_app_folder = furi_string_alloc_set(MAG_APP_FOLDER); + + DialogsFileBrowserOptions browser_options; + dialog_file_browser_set_basic_options(&browser_options, MAG_APP_EXTENSION, &I_mag_10px); + browser_options.base_path = MAG_APP_FOLDER; + + bool res = dialog_file_browser_show( + mag_dev->dialogs, mag_dev->load_path, mag_app_folder, &browser_options); + + furi_string_free(mag_app_folder); + if(res) { + FuriString* filename; + filename = furi_string_alloc(); + path_extract_filename(mag_dev->load_path, filename, true); + strncpy(mag_dev->dev_name, furi_string_get_cstr(filename), MAG_DEV_NAME_MAX_LEN); + res = mag_device_load_data(mag_dev, mag_dev->load_path, true); + if(res) { + mag_device_set_name(mag_dev, mag_dev->dev_name); + } + furi_string_free(filename); + } + + return res; +} + +bool mag_device_delete(MagDevice* mag_dev, bool use_load_path) { + furi_assert(mag_dev); + + bool deleted = false; + FuriString* file_path; + file_path = furi_string_alloc(); + + do { + // Delete original file + if(use_load_path && !furi_string_empty(mag_dev->load_path)) { + furi_string_set(file_path, mag_dev->load_path); + } else { + furi_string_printf( + file_path, "%s/%s%s", MAG_APP_FOLDER, mag_dev->dev_name, MAG_APP_EXTENSION); + } + if(!storage_simply_remove(mag_dev->storage, furi_string_get_cstr(file_path))) break; + deleted = true; + } while(false); + + if(!deleted) { + dialog_message_show_storage_error(mag_dev->dialogs, "Cannot remove\nfile"); + } + + furi_string_free(file_path); + return deleted; +} + +void mag_device_set_loading_callback( + MagDevice* mag_dev, + MagLoadingCallback callback, + void* context) { + furi_assert(mag_dev); + + mag_dev->loading_cb = callback; + mag_dev->loading_cb_ctx = context; +} diff --git a/mag_device.h b/mag_device.h index 5c4dccd105c..c2896fb1915 100644 --- a/mag_device.h +++ b/mag_device.h @@ -6,3 +6,43 @@ #include #include "mag_icons.h" + +#define MAG_DEV_NAME_MAX_LEN 22 + +#define MAG_APP_FOLDER ANY_PATH("mag") +#define MAG_APP_EXTENSION ".mag" + +typedef void (*MagLoadingCallback)(void* context, bool state); + +typedef struct MagDevice MagDevice; + +struct MagDevice { + Storage* storage; + DialogsApp* dialogs; + FuriString* dev_data; + char dev_name[MAG_DEV_NAME_MAX_LEN + 1]; + FuriString* load_path; + MagLoadingCallback loading_cb; + void* loading_cb_ctx; +}; + +MagDevice* mag_device_alloc(); + +void mag_device_free(MagDevice* mag_dev); + +void mag_device_set_name(MagDevice* mag_dev, const char* name); + +bool mag_device_save(MagDevice* mag_dev, const char* dev_name); + +bool mag_file_select(MagDevice* mag_dev); + +void mag_device_data_clear(FuriString* dev_data); + +void mag_device_clear(MagDevice* mag_dev); + +bool mag_device_delete(MagDevice* mag_dev, bool use_load_path); + +void mag_device_set_loading_callback( + MagDevice* mag_dev, + MagLoadingCallback callback, + void* context); diff --git a/mag_i.h b/mag_i.h index 3d2d602478b..f5543c2bdd3 100644 --- a/mag_i.h +++ b/mag_i.h @@ -1,11 +1,12 @@ #pragma once +#include "mag_device.h" + #include #include #include #include -#include #include #include #include @@ -13,8 +14,8 @@ #include #include #include +#include #include -#include #include #include @@ -26,13 +27,7 @@ #include "scenes/mag_scene.h" -#define MAG_KEY_NAME_SIZE 22 -#define MAG_TEXT_STORE_SIZE 40 - -#define MAG_APP_FOLDER ANY_PATH("mag") -#define MAG_SD_FOLDER EXT_PATH("mag") -#define MAG_APP_EXTENSION ".mag" -#define MAG_APP_SHADOW_EXTENSION ".shd" +#define MAG_TEXT_STORE_SIZE 128 enum MagCustomEvent { MagEventNext = 100, @@ -49,7 +44,7 @@ struct Mag { SceneManager* scene_manager; Storage* storage; DialogsApp* dialogs; - Widget* widget; + MagDevice* mag_dev; char text_store[MAG_TEXT_STORE_SIZE + 1]; FuriString* file_path; @@ -59,8 +54,9 @@ struct Mag { Submenu* submenu; DialogEx* dialog_ex; Popup* popup; + Loading* loading; TextInput* text_input; - ByteInput* byte_input; + Widget* widget; // Custom views? }; @@ -69,11 +65,19 @@ typedef enum { MagViewSubmenu, MagViewDialogEx, MagViewPopup, + MagViewLoading, MagViewWidget, MagViewTextInput, - MagViewByteInput, } MagView; +void mag_text_store_set(Mag* mag, const char* text, ...); + +void mag_text_store_clear(Mag* mag); + +void mag_show_loading_popup(void* context, bool show); + +// all below this comment are destined for deprecation (now handled by mag_device) + bool mag_save_key(Mag* mag); bool mag_load_key_from_file_select(Mag* mag); @@ -86,10 +90,6 @@ bool mag_save_key_data(Mag* mag, FuriString* path); void mag_make_app_folder(Mag* mag); -void mag_text_store_set(Mag* mag, const char* text, ...); - -void mag_text_store_clear(Mag* mag); - void mag_popup_timeout_callback(void* context); void mag_widget_callback(GuiButtonType result, InputType type, void* context); diff --git a/scenes/mag_scene_config.h b/scenes/mag_scene_config.h index d5f75167144..14168bb81c3 100644 --- a/scenes/mag_scene_config.h +++ b/scenes/mag_scene_config.h @@ -1,7 +1,7 @@ ADD_SCENE(mag, start, Start) ADD_SCENE(mag, emulate_test, EmulateTest) -ADD_SCENE(mag, select_key, SelectKey) -ADD_SCENE(mag, saved_key_menu, SavedKeyMenu) +ADD_SCENE(mag, file_select, FileSelect) +ADD_SCENE(mag, saved_menu, SavedMenu) ADD_SCENE(mag, saved_info, SavedInfo) ADD_SCENE(mag, save_data, SaveData) ADD_SCENE(mag, save_name, SaveName) @@ -9,3 +9,4 @@ ADD_SCENE(mag, save_success, SaveSuccess) ADD_SCENE(mag, delete_success, DeleteSuccess) ADD_SCENE(mag, delete_confirm, DeleteConfirm) ADD_SCENE(mag, exit_confirm, ExitConfirm) +ADD_SCENE(mag, under_construction, UnderConstruction) diff --git a/scenes/mag_scene_emulate_test.c b/scenes/mag_scene_emulate_test.c index 70f582cd196..c184ce9c31b 100644 --- a/scenes/mag_scene_emulate_test.c +++ b/scenes/mag_scene_emulate_test.c @@ -186,7 +186,7 @@ bool mag_scene_emulate_test_on_event(void *context, SceneManagerEvent event) { furi_string_set_str(v, test_str); // blink led while spoofing - notification_message(mag->notifications, &sequence_blink_start_magenta); + notification_message(mag->notifications, &sequence_blink_start_blue); mag_spoof(v, TEST_TRACK); notification_message(mag->notifications, &sequence_blink_stop); diff --git a/scenes/mag_scene_file_select.c b/scenes/mag_scene_file_select.c new file mode 100644 index 00000000000..b759c4d18fa --- /dev/null +++ b/scenes/mag_scene_file_select.c @@ -0,0 +1,24 @@ +#include "../mag_i.h" +#include "../mag_device.h" + +void mag_scene_file_select_on_enter(void* context) { + Mag* mag = context; + //UNUSED(mag); + mag_device_set_loading_callback(mag->mag_dev, mag_show_loading_popup, mag); + if(mag_file_select(mag->mag_dev)) { + scene_manager_next_scene(mag->scene_manager, MagSceneSavedMenu); + } else { + scene_manager_search_and_switch_to_previous_scene(mag->scene_manager, MagSceneStart); + } + mag_device_set_loading_callback(mag->mag_dev, NULL, mag); +} + +bool mag_scene_file_select_on_event(void* context, SceneManagerEvent event) { + UNUSED(context); + UNUSED(event); + return false; +} + +void mag_scene_file_select_on_exit(void* context) { + UNUSED(context); +} \ No newline at end of file diff --git a/scenes/mag_scene_save_name.c b/scenes/mag_scene_save_name.c index 36f6c79cd7e..d2c2ae1f3fc 100644 --- a/scenes/mag_scene_save_name.c +++ b/scenes/mag_scene_save_name.c @@ -24,7 +24,7 @@ void mag_scene_save_name_on_enter(void* context) { mag_text_input_callback, mag, mag->text_store, - MAG_KEY_NAME_SIZE, + MAG_DEV_NAME_MAX_LEN, key_name_is_empty); FURI_LOG_I("", "%s %s", furi_string_get_cstr(folder_path), mag->text_store); @@ -56,7 +56,7 @@ bool mag_scene_save_name_on_event(void* context, SceneManagerEvent event) { if(mag_save_key(mag)) { scene_manager_next_scene(scene_manager, MagSceneSaveSuccess); - if(scene_manager_has_previous_scene(scene_manager, MagSceneSavedKeyMenu)) { + if(scene_manager_has_previous_scene(scene_manager, MagSceneSavedMenu)) { // Nothing, do not count editing as saving //} else if(scene_manager_has_previous_scene(scene_manager, MagSceneSaveType)) { //DOLPHIN_DEED(DolphinDeedRfidAdd); diff --git a/scenes/mag_scene_saved_info.c b/scenes/mag_scene_saved_info.c index 7c2874d5c09..84baf9245e2 100644 --- a/scenes/mag_scene_saved_info.c +++ b/scenes/mag_scene_saved_info.c @@ -2,19 +2,39 @@ void mag_scene_saved_info_on_enter(void* context) { Mag* mag = context; - UNUSED(mag); + Widget* widget = mag->widget; + + widget_add_string_element( + widget, + 64, + 12, + AlignCenter, + AlignCenter, + FontSecondary, + furi_string_get_cstr(mag->mag_dev->dev_data)); + + widget_add_button_element(widget, GuiButtonTypeLeft, "Back", mag_widget_callback, mag); + + view_dispatcher_switch_to_view(mag->view_dispatcher, MagViewWidget); } bool mag_scene_saved_info_on_event(void* context, SceneManagerEvent event) { Mag* mag = context; - UNUSED(mag); - UNUSED(event); + SceneManager* scene_manager = mag->scene_manager; bool consumed = false; + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == GuiButtonTypeLeft) { + consumed = true; + + scene_manager_previous_scene(scene_manager); + } + } + return consumed; } void mag_scene_saved_info_on_exit(void* context) { Mag* mag = context; - UNUSED(mag); + widget_reset(mag->widget); } \ No newline at end of file diff --git a/scenes/mag_scene_saved_key_menu.c b/scenes/mag_scene_saved_key_menu.c deleted file mode 100644 index 97627ca7843..00000000000 --- a/scenes/mag_scene_saved_key_menu.c +++ /dev/null @@ -1,20 +0,0 @@ -#include "../mag_i.h" - -void mag_scene_saved_key_menu_on_enter(void* context) { - Mag* mag = context; - UNUSED(mag); -} - -bool mag_scene_saved_key_menu_on_event(void* context, SceneManagerEvent event) { - Mag* mag = context; - UNUSED(mag); - UNUSED(event); - bool consumed = false; - - return consumed; -} - -void mag_scene_saved_key_menu_on_exit(void* context) { - Mag* mag = context; - UNUSED(mag); -} \ No newline at end of file diff --git a/scenes/mag_scene_saved_menu.c b/scenes/mag_scene_saved_menu.c new file mode 100644 index 00000000000..9794b0dc8a7 --- /dev/null +++ b/scenes/mag_scene_saved_menu.c @@ -0,0 +1,65 @@ +#include "../mag_i.h" + +enum SubmenuIndex { + SubmenuIndexEmulate, + SubmenuIndexEdit, + SubmenuIndexDelete, + SubmenuIndexInfo, +}; + +void mag_scene_saved_menu_submenu_callback(void* context, uint32_t index) { + Mag* mag = context; + + view_dispatcher_send_custom_event(mag->view_dispatcher, index); +} + +void mag_scene_saved_menu_on_enter(void* context) { + Mag* mag = context; + Submenu* submenu = mag->submenu; + + submenu_add_item( + submenu, "Emulate", SubmenuIndexEmulate, mag_scene_saved_menu_submenu_callback, mag); + submenu_add_item( + submenu, "Edit", SubmenuIndexEdit, mag_scene_saved_menu_submenu_callback, mag); + submenu_add_item( + submenu, "Delete", SubmenuIndexDelete, mag_scene_saved_menu_submenu_callback, mag); + submenu_add_item( + submenu, "Info", SubmenuIndexInfo, mag_scene_saved_menu_submenu_callback, mag); + + submenu_set_selected_item( + mag->submenu, scene_manager_get_scene_state(mag->scene_manager, MagSceneSavedMenu)); + + view_dispatcher_switch_to_view(mag->view_dispatcher, MagViewSubmenu); +} + +bool mag_scene_saved_menu_on_event(void* context, SceneManagerEvent event) { + Mag* mag = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + scene_manager_set_scene_state(mag->scene_manager, MagSceneSavedMenu, event.event); + + // TODO: replace with actual next scenes once built + if(event.event == SubmenuIndexEmulate) { + scene_manager_next_scene(mag->scene_manager, MagSceneUnderConstruction); + consumed = true; + } else if(event.event == SubmenuIndexEdit) { + scene_manager_next_scene(mag->scene_manager, MagSceneUnderConstruction); + consumed = true; + } else if(event.event == SubmenuIndexDelete) { + scene_manager_next_scene(mag->scene_manager, MagSceneUnderConstruction); + consumed = true; + } else if(event.event == SubmenuIndexInfo) { + scene_manager_next_scene(mag->scene_manager, MagSceneSavedInfo); + consumed = true; + } + } + + return consumed; +} + +void mag_scene_saved_menu_on_exit(void* context) { + Mag* mag = context; + + submenu_reset(mag->submenu); +} \ No newline at end of file diff --git a/scenes/mag_scene_select_key.c b/scenes/mag_scene_select_key.c deleted file mode 100644 index ee3af7ba423..00000000000 --- a/scenes/mag_scene_select_key.c +++ /dev/null @@ -1,20 +0,0 @@ -#include "../mag_i.h" - -void mag_scene_select_key_on_enter(void* context) { - Mag* mag = context; - UNUSED(mag); -} - -bool mag_scene_select_key_on_event(void* context, SceneManagerEvent event) { - Mag* mag = context; - UNUSED(mag); - UNUSED(event); - bool consumed = false; - - return consumed; -} - -void mag_scene_select_key_on_exit(void* context) { - Mag* mag = context; - UNUSED(mag); -} \ No newline at end of file diff --git a/scenes/mag_scene_start.c b/scenes/mag_scene_start.c index 332683694d0..998e4805d0b 100644 --- a/scenes/mag_scene_start.c +++ b/scenes/mag_scene_start.c @@ -45,10 +45,10 @@ bool mag_scene_start_on_event(void* context, SceneManagerEvent event) { consumed = true; } else if(event.event == SubmenuIndexSaved) { furi_string_set(mag->file_path, MAG_APP_FOLDER); - scene_manager_next_scene(mag->scene_manager, MagSceneSelectKey); + scene_manager_next_scene(mag->scene_manager, MagSceneFileSelect); consumed = true; } else if(event.event == SubmenuIndexAddManually) { - scene_manager_next_scene(mag->scene_manager, MagSceneSaveData); + scene_manager_next_scene(mag->scene_manager, MagSceneUnderConstruction); consumed = true; } scene_manager_set_scene_state(mag->scene_manager, MagSceneStart, event.event); diff --git a/scenes/mag_scene_under_construction.c b/scenes/mag_scene_under_construction.c new file mode 100644 index 00000000000..520f0a79254 --- /dev/null +++ b/scenes/mag_scene_under_construction.c @@ -0,0 +1,40 @@ +#include "../mag_i.h" + +void mag_scene_under_construction_on_enter(void* context) { + Mag* mag = context; + Widget* widget = mag->widget; + + FuriString* tmp_str; + tmp_str = furi_string_alloc(); + + widget_add_button_element(widget, GuiButtonTypeLeft, "Back", mag_widget_callback, mag); + + furi_string_printf(tmp_str, "Under construction!"); + widget_add_string_element( + widget, 64, 4, AlignCenter, AlignTop, FontPrimary, furi_string_get_cstr(tmp_str)); + furi_string_reset(tmp_str); + + view_dispatcher_switch_to_view(mag->view_dispatcher, MagViewWidget); + furi_string_free(tmp_str); +} + +bool mag_scene_under_construction_on_event(void* context, SceneManagerEvent event) { + Mag* mag = context; + SceneManager* scene_manager = mag->scene_manager; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == GuiButtonTypeLeft) { + consumed = true; + + scene_manager_previous_scene(scene_manager); + } + } + + return consumed; +} + +void mag_scene_under_construction_on_exit(void* context) { + Mag* mag = context; + widget_reset(mag->widget); +} \ No newline at end of file