110 lines
3.9 KiB
C
110 lines
3.9 KiB
C
|
#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;
|
||
|
}
|