view_navigator.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. #include "view_navigator_i.h"
  2. ViewNavigator* view_navigator_alloc(void* context) {
  3. furi_assert(context);
  4. ViewNavigator* view_navigator = furi_alloc(sizeof(ViewNavigator));
  5. view_navigator->context = context;
  6. ViewNavSceneArray_init(view_navigator->scene_array);
  7. return view_navigator;
  8. }
  9. void view_navigator_free(ViewNavigator* view_navigator) {
  10. furi_assert(view_navigator);
  11. ViewNavSceneArray_clear(view_navigator->scene_array);
  12. free(view_navigator);
  13. }
  14. bool view_navigator_handle_custom_event(ViewNavigator* view_navigator, uint32_t event) {
  15. AppScene* scene = *ViewNavSceneArray_back(view_navigator->scene_array);
  16. return scene->on_event(view_navigator->context, event);
  17. }
  18. bool view_navigator_handle_navigation_event(ViewNavigator* view_navigator, uint32_t event) {
  19. if(event == ViewNavigatorEventNext) {
  20. return view_navigator_next_scene(view_navigator);
  21. } else if(event == ViewNavigatorEventBack) {
  22. AppScene* scene = *ViewNavSceneArray_back(view_navigator->scene_array);
  23. if(scene->on_event(view_navigator->context, ViewNavigatorEventBack)) {
  24. return true;
  25. } else {
  26. return view_navigator_previous_scene(view_navigator);
  27. }
  28. }
  29. return false;
  30. }
  31. bool view_navigator_handle_back_search_scene_event(ViewNavigator* view_navigator, uint32_t event) {
  32. return view_navigator_search_previous_scene(view_navigator, event);
  33. }
  34. void view_navigator_add_next_scene(ViewNavigator* view_navigator, AppScene* scene) {
  35. furi_assert(view_navigator);
  36. furi_assert(scene);
  37. ViewNavSceneArray_push_back(view_navigator->scene_array, scene);
  38. }
  39. void view_navigator_start(ViewNavigator* view_navigator) {
  40. furi_assert(view_navigator);
  41. AppScene* scene = *ViewNavSceneArray_front(view_navigator->scene_array);
  42. furi_assert(scene);
  43. scene->on_enter(view_navigator->context);
  44. }
  45. bool view_navigator_next_scene(ViewNavigator* view_navigator) {
  46. ViewNavSceneArray_it_t scene_it;
  47. ViewNavSceneArray_it_last(scene_it, view_navigator->scene_array);
  48. ViewNavSceneArray_previous(scene_it);
  49. AppScene* current_scene = *ViewNavSceneArray_ref(scene_it);
  50. AppScene* next_scene = *ViewNavSceneArray_back(view_navigator->scene_array);
  51. if(current_scene && next_scene) {
  52. current_scene->on_exit(view_navigator->context);
  53. next_scene->on_enter(view_navigator->context);
  54. return true;
  55. }
  56. return false;
  57. }
  58. bool view_navigator_previous_scene(ViewNavigator* view_navigator) {
  59. AppScene* current_scene = NULL;
  60. ViewNavSceneArray_pop_back(&current_scene, view_navigator->scene_array);
  61. if(ViewNavSceneArray_size(view_navigator->scene_array) == 0) {
  62. // Handle exit from start scene separately
  63. current_scene->on_exit(view_navigator->context);
  64. return false;
  65. }
  66. AppScene* previous_scene = *ViewNavSceneArray_back(view_navigator->scene_array);
  67. if(current_scene && previous_scene) {
  68. current_scene->on_exit(view_navigator->context);
  69. previous_scene->on_enter(view_navigator->context);
  70. return true;
  71. }
  72. return false;
  73. }
  74. bool view_navigator_search_previous_scene(ViewNavigator* view_navigator, uint32_t scene_id) {
  75. AppScene* previous_scene = NULL;
  76. AppScene* current_scene = *ViewNavSceneArray_back(view_navigator->scene_array);
  77. ViewNavSceneArray_it_t scene_it;
  78. ViewNavSceneArray_it_last(scene_it, view_navigator->scene_array);
  79. bool scene_found = false;
  80. while(!scene_found) {
  81. ViewNavSceneArray_previous(scene_it);
  82. previous_scene = *ViewNavSceneArray_ref(scene_it);
  83. if(previous_scene == NULL) {
  84. return false;
  85. }
  86. if(previous_scene->id == scene_id) {
  87. scene_found = true;
  88. }
  89. }
  90. ViewNavSceneArray_next(scene_it);
  91. ViewNavSceneArray_pop_until(view_navigator->scene_array, scene_it);
  92. current_scene->on_exit(view_navigator->context);
  93. previous_scene->on_enter(view_navigator->context);
  94. return true;
  95. }