From 91c1eaf5a8c5e1c87d14755fb99a08e1cfdf72ac Mon Sep 17 00:00:00 2001 From: gornekich Date: Wed, 28 Jul 2021 17:52:00 +0300 Subject: [PATCH] [FL-1543] Scene manager search scene API (#611) * scene_manager: search -> search_and_switch_to previous_scene * scene_manager: add search and switch to another scene API * scene_manager: Navigation -> Back event --- applications/gui/scene_manager.c | 50 +++++++++++++++++-- applications/gui/scene_manager.h | 30 ++++++++--- applications/nfc/nfc.c | 7 ++- applications/nfc/scenes/nfc_scene_card_menu.c | 5 +- applications/nfc/scenes/nfc_scene_delete.c | 3 +- .../nfc/scenes/nfc_scene_delete_success.c | 3 +- .../nfc/scenes/nfc_scene_file_select.c | 2 +- .../nfc/scenes/nfc_scene_mifare_ul_menu.c | 5 +- .../scenes/nfc_scene_read_emv_data_success.c | 7 +-- applications/nfc/scenes/nfc_scene_save_name.c | 3 +- .../nfc/scenes/nfc_scene_save_success.c | 14 +++++- .../scenes/storage-settings-scene-ejected.c | 9 ++-- .../storage-settings-scene-formatting.c | 9 ++-- .../storage-settings/storage-settings.c | 6 +-- 14 files changed, 116 insertions(+), 37 deletions(-) mode change 100644 => 100755 applications/nfc/nfc.c mode change 100644 => 100755 applications/nfc/scenes/nfc_scene_delete.c mode change 100644 => 100755 applications/nfc/scenes/nfc_scene_delete_success.c mode change 100644 => 100755 applications/nfc/scenes/nfc_scene_mifare_ul_menu.c mode change 100644 => 100755 applications/storage-settings/scenes/storage-settings-scene-ejected.c mode change 100644 => 100755 applications/storage-settings/scenes/storage-settings-scene-formatting.c diff --git a/applications/gui/scene_manager.c b/applications/gui/scene_manager.c index 6a71ce5c..f4492a58 100755 --- a/applications/gui/scene_manager.c +++ b/applications/gui/scene_manager.c @@ -53,11 +53,11 @@ bool scene_manager_handle_custom_event(SceneManager* scene_manager, uint32_t cus scene_manager->context, event); } -bool scene_manager_handle_navigation_event(SceneManager* scene_manager) { +bool scene_manager_handle_back_event(SceneManager* scene_manager) { furi_assert(scene_manager); SceneManagerEvent event = { - .type = SceneManagerEventTypeNavigation, + .type = SceneManagerEventTypeBack, }; uint32_t scene_id = *SceneManagerIdStack_back(scene_manager->scene_id_stack); bool consumed = @@ -109,7 +109,9 @@ bool scene_manager_previous_scene(SceneManager* scene_manager) { return true; } -bool scene_manager_search_previous_scene(SceneManager* scene_manager, uint32_t scene_id) { +bool scene_manager_search_and_switch_to_previous_scene( + SceneManager* scene_manager, + uint32_t scene_id) { furi_assert(scene_manager); uint32_t prev_scene_id = 0; @@ -137,3 +139,45 @@ bool scene_manager_search_previous_scene(SceneManager* scene_manager, uint32_t s return true; } + +bool scene_manager_has_previous_scene(SceneManager* scene_manager, uint32_t scene_id) { + furi_assert(scene_manager); + bool scene_found = false; + uint32_t prev_scene_id; + SceneManagerIdStack_it_t scene_it; + SceneManagerIdStack_it_last(scene_it, scene_manager->scene_id_stack); + + // Perform search in scene stack + while(!scene_found) { + SceneManagerIdStack_previous(scene_it); + if(SceneManagerIdStack_end_p(scene_it)) { + break; + } + prev_scene_id = *SceneManagerIdStack_ref(scene_it); + if(prev_scene_id == scene_id) { + scene_found = true; + } + } + return scene_found; +} + +bool scene_manager_search_and_switch_to_another_scene( + SceneManager* scene_manager, + uint32_t scene_id) { + furi_assert(scene_manager); + furi_assert(scene_id < scene_manager->scene_handlers->scene_num); + + uint32_t cur_scene_id = *SceneManagerIdStack_back(scene_manager->scene_id_stack); + SceneManagerIdStack_it_t scene_it; + SceneManagerIdStack_it(scene_it, scene_manager->scene_id_stack); + SceneManagerIdStack_next(scene_it); + // Remove all scene id from navigation stack until first scene + SceneManagerIdStack_pop_until(scene_manager->scene_id_stack, scene_it); + // Add next scene + SceneManagerIdStack_push_back(scene_manager->scene_id_stack, scene_id); + + scene_manager->scene_handlers->on_exit_handlers[cur_scene_id](scene_manager->context); + scene_manager->scene_handlers->on_enter_handlers[scene_id](scene_manager->context); + + return true; +} diff --git a/applications/gui/scene_manager.h b/applications/gui/scene_manager.h index 3aeff288..0318b1cd 100755 --- a/applications/gui/scene_manager.h +++ b/applications/gui/scene_manager.h @@ -11,7 +11,7 @@ extern "C" { */ typedef enum { SceneManagerEventTypeCustom, - SceneManagerEventTypeNavigation, + SceneManagerEventTypeBack, SceneManagerEventTypeTick, } SceneManagerEventType; @@ -78,12 +78,12 @@ void scene_manager_free(SceneManager* scene_manager); */ bool scene_manager_handle_custom_event(SceneManager* scene_manager, uint32_t custom_event); -/** Navigation event handler - * Calls Scene event handler with Navigation event parameter +/** Back event handler + * Calls Scene event handler with Back event parameter * @param scene_manager SceneManager instance * @return true if event was consumed, false otherwise */ -bool scene_manager_handle_navigation_event(SceneManager* scene_manager); +bool scene_manager_handle_back_event(SceneManager* scene_manager); /** Tick event handler * Calls Scene event handler with Tick event parameter @@ -104,12 +104,30 @@ void scene_manager_next_scene(SceneManager* scene_manager, uint32_t next_scene_i */ bool scene_manager_previous_scene(SceneManager* scene_manager); -/** Search previous Scene by ID +/** Search previous Scene * @param scene_manager SceneManager instance * @param scene_id Scene ID * @return true if previous scene was found, false otherwise */ -bool scene_manager_search_previous_scene(SceneManager* scene_manager, uint32_t scene_id); +bool scene_manager_has_previous_scene(SceneManager* scene_manager, uint32_t scene_id); + +/** Search and switch to previous Scene + * @param scene_manager SceneManager instance + * @param scene_id Scene ID + * @return true if previous scene was found, false otherwise + */ +bool scene_manager_search_and_switch_to_previous_scene( + SceneManager* scene_manager, + uint32_t scene_id); + +/** Clear Scene stack and switch to another Scene + * @param scene_manager SceneManager instance + * @param scene_id Scene ID + * @return true if previous scene was found, false otherwise + */ +bool scene_manager_search_and_switch_to_another_scene( + SceneManager* scene_manager, + uint32_t scene_id); #ifdef __cplusplus } diff --git a/applications/nfc/nfc.c b/applications/nfc/nfc.c old mode 100644 new mode 100755 index 8815211c..734dade2 --- a/applications/nfc/nfc.c +++ b/applications/nfc/nfc.c @@ -7,10 +7,10 @@ bool nfc_custom_event_callback(void* context, uint32_t event) { return scene_manager_handle_custom_event(nfc->scene_manager, event); } -bool nfc_navigation_event_callback(void* context) { +bool nfc_back_event_callback(void* context) { furi_assert(context); Nfc* nfc = (Nfc*)context; - return scene_manager_handle_navigation_event(nfc->scene_manager); + return scene_manager_handle_back_event(nfc->scene_manager); } void nfc_tick_event_callback(void* context) { @@ -28,8 +28,7 @@ Nfc* nfc_alloc() { view_dispatcher_enable_queue(nfc->view_dispatcher); view_dispatcher_set_event_callback_context(nfc->view_dispatcher, nfc); view_dispatcher_set_custom_event_callback(nfc->view_dispatcher, nfc_custom_event_callback); - view_dispatcher_set_navigation_event_callback( - nfc->view_dispatcher, nfc_navigation_event_callback); + view_dispatcher_set_navigation_event_callback(nfc->view_dispatcher, nfc_back_event_callback); view_dispatcher_set_tick_event_callback(nfc->view_dispatcher, nfc_tick_event_callback, 100); // Open GUI record diff --git a/applications/nfc/scenes/nfc_scene_card_menu.c b/applications/nfc/scenes/nfc_scene_card_menu.c index f69e0838..f58c212e 100755 --- a/applications/nfc/scenes/nfc_scene_card_menu.c +++ b/applications/nfc/scenes/nfc_scene_card_menu.c @@ -70,8 +70,9 @@ const bool nfc_scene_card_menu_on_event(void* context, SceneManagerEvent event) scene_manager_next_scene(nfc->scene_manager, NfcSceneSaveName); return true; } - } else if(event.type == SceneManagerEventTypeNavigation) { - return scene_manager_search_previous_scene(nfc->scene_manager, NfcSceneStart); + } else if(event.type == SceneManagerEventTypeBack) { + return scene_manager_search_and_switch_to_previous_scene( + nfc->scene_manager, NfcSceneStart); } return false; diff --git a/applications/nfc/scenes/nfc_scene_delete.c b/applications/nfc/scenes/nfc_scene_delete.c old mode 100644 new mode 100755 index 84646e05..1e3dc292 --- a/applications/nfc/scenes/nfc_scene_delete.c +++ b/applications/nfc/scenes/nfc_scene_delete.c @@ -75,7 +75,8 @@ const bool nfc_scene_delete_on_event(void* context, SceneManagerEvent event) { if(nfc_device_delete(&nfc->dev)) { scene_manager_next_scene(nfc->scene_manager, NfcSceneDeleteSuccess); } else { - scene_manager_search_previous_scene(nfc->scene_manager, NfcSceneStart); + scene_manager_search_and_switch_to_previous_scene( + nfc->scene_manager, NfcSceneStart); } return true; } diff --git a/applications/nfc/scenes/nfc_scene_delete_success.c b/applications/nfc/scenes/nfc_scene_delete_success.c old mode 100644 new mode 100755 index 592a16c6..51328a0a --- a/applications/nfc/scenes/nfc_scene_delete_success.c +++ b/applications/nfc/scenes/nfc_scene_delete_success.c @@ -26,7 +26,8 @@ const bool nfc_scene_delete_success_on_event(void* context, SceneManagerEvent ev if(event.type == SceneManagerEventTypeCustom) { if(event.event == SCENE_SAVE_SUCCESS_CUSTOM_EVENT) { - return scene_manager_search_previous_scene(nfc->scene_manager, NfcSceneStart); + return scene_manager_search_and_switch_to_previous_scene( + nfc->scene_manager, NfcSceneStart); } } return false; diff --git a/applications/nfc/scenes/nfc_scene_file_select.c b/applications/nfc/scenes/nfc_scene_file_select.c index f8af371f..e75872a3 100755 --- a/applications/nfc/scenes/nfc_scene_file_select.c +++ b/applications/nfc/scenes/nfc_scene_file_select.c @@ -6,7 +6,7 @@ const void nfc_scene_file_select_on_enter(void* context) { if(nfc_file_select(&nfc->dev)) { scene_manager_next_scene(nfc->scene_manager, NfcSceneSavedMenu); } else { - scene_manager_search_previous_scene(nfc->scene_manager, NfcSceneStart); + scene_manager_search_and_switch_to_previous_scene(nfc->scene_manager, NfcSceneStart); } } diff --git a/applications/nfc/scenes/nfc_scene_mifare_ul_menu.c b/applications/nfc/scenes/nfc_scene_mifare_ul_menu.c old mode 100644 new mode 100755 index bc639db9..396c393b --- a/applications/nfc/scenes/nfc_scene_mifare_ul_menu.c +++ b/applications/nfc/scenes/nfc_scene_mifare_ul_menu.c @@ -41,8 +41,9 @@ const bool nfc_scene_mifare_ul_menu_on_event(void* context, SceneManagerEvent ev scene_manager_next_scene(nfc->scene_manager, NfcSceneNotImplemented); return true; } - } else if(event.type == SceneManagerEventTypeNavigation) { - return scene_manager_search_previous_scene(nfc->scene_manager, NfcSceneStart); + } else if(event.type == SceneManagerEventTypeBack) { + return scene_manager_search_and_switch_to_previous_scene( + nfc->scene_manager, NfcSceneStart); } return false; diff --git a/applications/nfc/scenes/nfc_scene_read_emv_data_success.c b/applications/nfc/scenes/nfc_scene_read_emv_data_success.c index fbfca822..74f15a22 100755 --- a/applications/nfc/scenes/nfc_scene_read_emv_data_success.c +++ b/applications/nfc/scenes/nfc_scene_read_emv_data_success.c @@ -68,15 +68,16 @@ const bool nfc_scene_read_emv_data_success_on_event(void* context, SceneManagerE if(event.type == SceneManagerEventTypeCustom) { if(event.event == GuiButtonTypeLeft) { - return scene_manager_search_previous_scene( + return scene_manager_search_and_switch_to_previous_scene( nfc->scene_manager, NfcSceneReadEmvAppSuccess); } else if(event.event == GuiButtonTypeRight) { nfc->dev.format = NfcDeviceSaveFormatBankCard; scene_manager_next_scene(nfc->scene_manager, NfcSceneSaveName); return true; } - } else if(event.type == SceneManagerEventTypeNavigation) { - return scene_manager_search_previous_scene(nfc->scene_manager, NfcSceneReadEmvAppSuccess); + } else if(event.type == SceneManagerEventTypeBack) { + return scene_manager_search_and_switch_to_previous_scene( + nfc->scene_manager, NfcSceneReadEmvAppSuccess); } return false; } diff --git a/applications/nfc/scenes/nfc_scene_save_name.c b/applications/nfc/scenes/nfc_scene_save_name.c index 9de2ac47..4a0041b2 100755 --- a/applications/nfc/scenes/nfc_scene_save_name.c +++ b/applications/nfc/scenes/nfc_scene_save_name.c @@ -45,7 +45,8 @@ const bool nfc_scene_save_name_on_event(void* context, SceneManagerEvent event) scene_manager_next_scene(nfc->scene_manager, NfcSceneSaveSuccess); return true; } else { - return scene_manager_search_previous_scene(nfc->scene_manager, NfcSceneStart); + return scene_manager_search_and_switch_to_previous_scene( + nfc->scene_manager, NfcSceneStart); } } } diff --git a/applications/nfc/scenes/nfc_scene_save_success.c b/applications/nfc/scenes/nfc_scene_save_success.c index cd36871a..058388b6 100755 --- a/applications/nfc/scenes/nfc_scene_save_success.c +++ b/applications/nfc/scenes/nfc_scene_save_success.c @@ -23,13 +23,23 @@ const void nfc_scene_save_success_on_enter(void* context) { const bool nfc_scene_save_success_on_event(void* context, SceneManagerEvent event) { Nfc* nfc = (Nfc*)context; + bool consumed = false; if(event.type == SceneManagerEventTypeCustom) { if(event.event == SCENE_SAVE_SUCCESS_CUSTOM_EVENT) { - return scene_manager_search_previous_scene(nfc->scene_manager, NfcSceneStart); + if(scene_manager_has_previous_scene(nfc->scene_manager, NfcSceneCardMenu)) { + consumed = scene_manager_search_and_switch_to_previous_scene( + nfc->scene_manager, NfcSceneCardMenu); + } else if(scene_manager_has_previous_scene(nfc->scene_manager, NfcSceneSetType)) { + consumed = scene_manager_search_and_switch_to_another_scene( + nfc->scene_manager, NfcSceneFileSelect); + } else { + consumed = scene_manager_search_and_switch_to_previous_scene( + nfc->scene_manager, NfcSceneStart); + } } } - return false; + return consumed; } const void nfc_scene_save_success_on_exit(void* context) { diff --git a/applications/storage-settings/scenes/storage-settings-scene-ejected.c b/applications/storage-settings/scenes/storage-settings-scene-ejected.c old mode 100644 new mode 100755 index 1ab2a6d9..8fb53570 --- a/applications/storage-settings/scenes/storage-settings-scene-ejected.c +++ b/applications/storage-settings/scenes/storage-settings-scene-ejected.c @@ -40,12 +40,13 @@ bool storage_settings_scene_unmounted_on_event(void* context, SceneManagerEvent if(event.type == SceneManagerEventTypeCustom) { switch(event.event) { case DialogExResultLeft: - consumed = - scene_manager_search_previous_scene(app->scene_manager, StorageSettingsStart); + consumed = scene_manager_search_and_switch_to_previous_scene( + app->scene_manager, StorageSettingsStart); break; } - } else if(event.type == SceneManagerEventTypeNavigation) { - consumed = scene_manager_search_previous_scene(app->scene_manager, StorageSettingsStart); + } else if(event.type == SceneManagerEventTypeBack) { + consumed = scene_manager_search_and_switch_to_previous_scene( + app->scene_manager, StorageSettingsStart); } return consumed; diff --git a/applications/storage-settings/scenes/storage-settings-scene-formatting.c b/applications/storage-settings/scenes/storage-settings-scene-formatting.c old mode 100644 new mode 100755 index 02a44947..9a82491d --- a/applications/storage-settings/scenes/storage-settings-scene-formatting.c +++ b/applications/storage-settings/scenes/storage-settings-scene-formatting.c @@ -60,12 +60,13 @@ bool storage_settings_scene_formatting_on_event(void* context, SceneManagerEvent if(event.type == SceneManagerEventTypeCustom) { switch(event.event) { case DialogExResultLeft: - consumed = - scene_manager_search_previous_scene(app->scene_manager, StorageSettingsStart); + consumed = scene_manager_search_and_switch_to_previous_scene( + app->scene_manager, StorageSettingsStart); break; } - } else if(event.type == SceneManagerEventTypeNavigation) { - consumed = scene_manager_search_previous_scene(app->scene_manager, StorageSettingsStart); + } else if(event.type == SceneManagerEventTypeBack) { + consumed = scene_manager_search_and_switch_to_previous_scene( + app->scene_manager, StorageSettingsStart); } return consumed; diff --git a/applications/storage-settings/storage-settings.c b/applications/storage-settings/storage-settings.c index 19213e19..49da39a2 100644 --- a/applications/storage-settings/storage-settings.c +++ b/applications/storage-settings/storage-settings.c @@ -6,10 +6,10 @@ static bool storage_settings_custom_event_callback(void* context, uint32_t event return scene_manager_handle_custom_event(app->scene_manager, event); } -static bool storage_settings_navigation_event_callback(void* context) { +static bool storage_settings_back_event_callback(void* context) { furi_assert(context); StorageSettings* app = context; - return scene_manager_handle_navigation_event(app->scene_manager); + return scene_manager_handle_back_event(app->scene_manager); } static StorageSettings* storage_settings_alloc() { @@ -29,7 +29,7 @@ static StorageSettings* storage_settings_alloc() { view_dispatcher_set_custom_event_callback( app->view_dispatcher, storage_settings_custom_event_callback); view_dispatcher_set_navigation_event_callback( - app->view_dispatcher, storage_settings_navigation_event_callback); + app->view_dispatcher, storage_settings_back_event_callback); view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen);