a0e1e42f2d
* view: add custom event callback * nfc: rework nfc worker * gui: introduce view navigator * nfc_scences: introduce nfc scenes * nfc: add start scene * lib: add C application scene template * nfc: move nfc views to separate directory * view_dispatcher: add support for view_navigator * nfc views: rework nfc views * nfc scenes: add nfc application scenes * nfc: rework nfc main thread * view_dispatcher: add separate event for search back scene * nfc: set worker result address at worker start * nfc: update read nfc scenes * view_navigator: rework with M-LIB container * view_dispatcher: check that all views were freed * nfc: add debug menu with all functions * nfc read scene: add notification on success * api-hal-nfc: add API for UID emulation * nfc: add nfc emulation UID scene * assets: add NFC assets * nfc: update read and emulate scenes UI * nfc: fix memory leak * rfal: set custom analog configuration
110 lines
3.9 KiB
C
Executable File
110 lines
3.9 KiB
C
Executable File
#include "view_navigator_i.h"
|
|
|
|
ViewNavigator* view_navigator_alloc(void* context) {
|
|
furi_assert(context);
|
|
|
|
ViewNavigator* view_navigator = furi_alloc(sizeof(ViewNavigator));
|
|
view_navigator->context = context;
|
|
ViewNavSceneArray_init(view_navigator->scene_array);
|
|
|
|
return view_navigator;
|
|
}
|
|
|
|
void view_navigator_free(ViewNavigator* view_navigator) {
|
|
furi_assert(view_navigator);
|
|
ViewNavSceneArray_clear(view_navigator->scene_array);
|
|
|
|
free(view_navigator);
|
|
}
|
|
|
|
bool view_navigator_handle_custom_event(ViewNavigator* view_navigator, uint32_t event) {
|
|
AppScene* scene = *ViewNavSceneArray_back(view_navigator->scene_array);
|
|
return scene->on_event(view_navigator->context, event);
|
|
}
|
|
|
|
bool view_navigator_handle_navigation_event(ViewNavigator* view_navigator, uint32_t event) {
|
|
if(event == ViewNavigatorEventNext) {
|
|
return view_navigator_next_scene(view_navigator);
|
|
} else if(event == ViewNavigatorEventBack) {
|
|
AppScene* scene = *ViewNavSceneArray_back(view_navigator->scene_array);
|
|
if(scene->on_event(view_navigator->context, ViewNavigatorEventBack)) {
|
|
return true;
|
|
} else {
|
|
return view_navigator_previous_scene(view_navigator);
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool view_navigator_handle_back_search_scene_event(ViewNavigator* view_navigator, uint32_t event) {
|
|
return view_navigator_search_previous_scene(view_navigator, event);
|
|
}
|
|
|
|
void view_navigator_add_next_scene(ViewNavigator* view_navigator, AppScene* scene) {
|
|
furi_assert(view_navigator);
|
|
furi_assert(scene);
|
|
|
|
ViewNavSceneArray_push_back(view_navigator->scene_array, scene);
|
|
}
|
|
|
|
void view_navigator_start(ViewNavigator* view_navigator) {
|
|
furi_assert(view_navigator);
|
|
AppScene* scene = *ViewNavSceneArray_front(view_navigator->scene_array);
|
|
furi_assert(scene);
|
|
scene->on_enter(view_navigator->context);
|
|
}
|
|
|
|
bool view_navigator_next_scene(ViewNavigator* view_navigator) {
|
|
ViewNavSceneArray_it_t scene_it;
|
|
ViewNavSceneArray_it_last(scene_it, view_navigator->scene_array);
|
|
ViewNavSceneArray_previous(scene_it);
|
|
AppScene* current_scene = *ViewNavSceneArray_ref(scene_it);
|
|
AppScene* next_scene = *ViewNavSceneArray_back(view_navigator->scene_array);
|
|
if(current_scene && next_scene) {
|
|
current_scene->on_exit(view_navigator->context);
|
|
next_scene->on_enter(view_navigator->context);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool view_navigator_previous_scene(ViewNavigator* view_navigator) {
|
|
AppScene* current_scene = NULL;
|
|
ViewNavSceneArray_pop_back(¤t_scene, view_navigator->scene_array);
|
|
if(ViewNavSceneArray_size(view_navigator->scene_array) == 0) {
|
|
// Handle exit from start scene separately
|
|
current_scene->on_exit(view_navigator->context);
|
|
return false;
|
|
}
|
|
AppScene* previous_scene = *ViewNavSceneArray_back(view_navigator->scene_array);
|
|
if(current_scene && previous_scene) {
|
|
current_scene->on_exit(view_navigator->context);
|
|
previous_scene->on_enter(view_navigator->context);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool view_navigator_search_previous_scene(ViewNavigator* view_navigator, uint32_t scene_id) {
|
|
AppScene* previous_scene = NULL;
|
|
AppScene* current_scene = *ViewNavSceneArray_back(view_navigator->scene_array);
|
|
ViewNavSceneArray_it_t scene_it;
|
|
ViewNavSceneArray_it_last(scene_it, view_navigator->scene_array);
|
|
bool scene_found = false;
|
|
while(!scene_found) {
|
|
ViewNavSceneArray_previous(scene_it);
|
|
previous_scene = *ViewNavSceneArray_ref(scene_it);
|
|
if(previous_scene == NULL) {
|
|
return false;
|
|
}
|
|
if(previous_scene->id == scene_id) {
|
|
scene_found = true;
|
|
}
|
|
}
|
|
ViewNavSceneArray_next(scene_it);
|
|
ViewNavSceneArray_pop_until(view_navigator->scene_array, scene_it);
|
|
current_scene->on_exit(view_navigator->context);
|
|
previous_scene->on_enter(view_navigator->context);
|
|
return true;
|
|
}
|