app_context.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. #include <gui/modules/menu.h>
  2. #include <gui/modules/popup.h>
  3. #include <gui/modules/submenu.h>
  4. #include <gui/modules/variable_item_list.h>
  5. #include "tone_gen.h"
  6. #include "app_context.h"
  7. /** custom event handler - passes the event to the scene manager */
  8. bool viewDispatcherCustomCallback(void* context, uint32_t custom_event) {
  9. furi_assert(context);
  10. struct AppContext_t* appContext = context;
  11. return scene_manager_handle_custom_event(appContext->scene_manager, custom_event);
  12. }
  13. /** navigation event handler - passes the event to the scene manager */
  14. bool viewDispatcherNavigationCallback(void* context) {
  15. furi_assert(context);
  16. struct AppContext_t* appContext = context;
  17. return scene_manager_handle_back_event(appContext->scene_manager);
  18. }
  19. AppContextStatus initializeAppContext(
  20. struct AppContext_t** context,
  21. int viewsCount,
  22. const SceneManagerHandlers* sceneManagerHandlers) {
  23. FURI_LOG_I(TAG, "Allocating memory for app context");
  24. *context = malloc(sizeof(struct AppContext_t));
  25. if(*context == NULL) {
  26. FURI_LOG_E(TAG, "Failed to allocate memory for app context");
  27. return APP_CONTEXT_CANT_ALLOCATE;
  28. }
  29. // Allocate our scene manager with the handlers provided
  30. FURI_LOG_I(TAG, "Setting up the scene manager");
  31. (*context)->scene_manager = scene_manager_alloc(sceneManagerHandlers, *context);
  32. // Now setup our view dispatchers
  33. FURI_LOG_I(TAG, "Setting up the view dispatcher");
  34. (*context)->view_dispatcher = view_dispatcher_alloc();
  35. FURI_LOG_I(TAG, "Setting view dispatcher callbacks");
  36. view_dispatcher_set_event_callback_context((*context)->view_dispatcher, (*context));
  37. FURI_LOG_I(TAG, "Setting view dispatcher custom event callbacks");
  38. view_dispatcher_set_custom_event_callback(
  39. (*context)->view_dispatcher, viewDispatcherCustomCallback);
  40. FURI_LOG_I(TAG, "Setting view dispatcher navigation event callbacks");
  41. view_dispatcher_set_navigation_event_callback(
  42. (*context)->view_dispatcher, viewDispatcherNavigationCallback);
  43. FURI_LOG_I(TAG, "Setting view dispatcher callbacks done");
  44. (*context)->activeViews = malloc(sizeof(struct View_t) * viewsCount);
  45. if((*context)->activeViews == NULL) {
  46. return APP_CONTEXT_CANT_ALLOCATE;
  47. }
  48. (*context)->activeViewsCount = viewsCount;
  49. return APP_CONTEXT_OK;
  50. }
  51. AppContextStatus addViewToAppContext(struct AppContext_t** context, struct View_t* view) {
  52. if(view->viewId > (*context)->activeViewsCount || view->viewId < 0) {
  53. FURI_LOG_I(TAG, "Not enough views!");
  54. return APP_CONTEXT_NOT_ENOUGH_VIEWS;
  55. }
  56. (*context)->activeViews[view->viewId] = view;
  57. switch(view->type) {
  58. case MENU:
  59. view_dispatcher_add_view(
  60. (*context)->view_dispatcher, view->viewId, menu_get_view(view->viewData));
  61. break;
  62. case SUBMENU:
  63. view_dispatcher_add_view(
  64. (*context)->view_dispatcher, view->viewId, submenu_get_view(view->viewData));
  65. break;
  66. case VIEW:
  67. view_dispatcher_add_view((*context)->view_dispatcher, view->viewId, view->viewData);
  68. break;
  69. case VARIABLE_ITEM_LIST:
  70. view_dispatcher_add_view(
  71. (*context)->view_dispatcher,
  72. view->viewId,
  73. variable_item_list_get_view(view->viewData));
  74. break;
  75. case POPUP:
  76. view_dispatcher_add_view(
  77. (*context)->view_dispatcher, view->viewId, popup_get_view(view->viewData));
  78. break;
  79. }
  80. return APP_CONTEXT_OK;
  81. }
  82. AppContextStatus freeAppContextViews(struct AppContext_t** context) {
  83. FURI_LOG_I(TAG, "Freeing views");
  84. for(int i = 0; i < (*context)->activeViewsCount; i++) {
  85. struct View_t* view = (*context)->activeViews[i];
  86. if(view != NULL) {
  87. view_dispatcher_remove_view((*context)->view_dispatcher, view->viewId);
  88. switch(view->type) {
  89. case MENU:
  90. menu_free(view->viewData);
  91. break;
  92. case SUBMENU:
  93. submenu_free(view->viewData);
  94. break;
  95. case VIEW:
  96. view_free(view->viewData);
  97. break;
  98. case VARIABLE_ITEM_LIST:
  99. variable_item_list_free(view->viewData);
  100. break;
  101. case POPUP:
  102. popup_free(view->viewData);
  103. break;
  104. }
  105. free(view);
  106. }
  107. }
  108. FURI_LOG_I(TAG, "Removing all views from list");
  109. free((*context)->activeViews);
  110. (*context)->activeViewsCount = 0;
  111. return APP_CONTEXT_OK;
  112. }
  113. AppContextStatus freeAppContext(struct AppContext_t** context) {
  114. FURI_LOG_I(TAG, "Ensuring views are free'd");
  115. AppContextStatus result = freeAppContextViews(context);
  116. if(result != APP_CONTEXT_OK) {
  117. return APP_CONTEXT_CANT_FREE_VIEWS;
  118. }
  119. FURI_LOG_I(TAG, "Freeing the scene");
  120. scene_manager_free((*context)->scene_manager);
  121. FURI_LOG_I(TAG, "Freeing the view dispatcher");
  122. view_dispatcher_free((*context)->view_dispatcher);
  123. FURI_LOG_I(TAG, "Freeing the app context");
  124. free((*context));
  125. return APP_CONTEXT_OK;
  126. }