view.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. #include "view_i.h"
  2. View* view_alloc() {
  3. View* view = malloc(sizeof(View));
  4. view->orientation = ViewOrientationHorizontal;
  5. return view;
  6. }
  7. void view_free(View* view) {
  8. furi_assert(view);
  9. view_free_model(view);
  10. free(view);
  11. }
  12. void view_tie_icon_animation(View* view, IconAnimation* icon_animation) {
  13. furi_assert(view);
  14. icon_animation_set_update_callback(icon_animation, view_icon_animation_callback, view);
  15. }
  16. void view_set_draw_callback(View* view, ViewDrawCallback callback) {
  17. furi_assert(view);
  18. furi_assert(view->draw_callback == NULL);
  19. view->draw_callback = callback;
  20. }
  21. void view_set_input_callback(View* view, ViewInputCallback callback) {
  22. furi_assert(view);
  23. furi_assert(view->input_callback == NULL);
  24. view->input_callback = callback;
  25. }
  26. void view_set_custom_callback(View* view, ViewCustomCallback callback) {
  27. furi_assert(view);
  28. furi_assert(callback);
  29. view->custom_callback = callback;
  30. }
  31. void view_set_previous_callback(View* view, ViewNavigationCallback callback) {
  32. furi_assert(view);
  33. view->previous_callback = callback;
  34. }
  35. void view_set_enter_callback(View* view, ViewCallback callback) {
  36. furi_assert(view);
  37. view->enter_callback = callback;
  38. }
  39. void view_set_exit_callback(View* view, ViewCallback callback) {
  40. furi_assert(view);
  41. view->exit_callback = callback;
  42. }
  43. void view_set_update_callback(View* view, ViewUpdateCallback callback) {
  44. furi_assert(view);
  45. view->update_callback = callback;
  46. }
  47. void view_set_update_callback_context(View* view, void* context) {
  48. furi_assert(view);
  49. view->update_callback_context = context;
  50. }
  51. void view_set_context(View* view, void* context) {
  52. furi_assert(view);
  53. furi_assert(context);
  54. view->context = context;
  55. }
  56. void view_set_orientation(View* view, ViewOrientation orientation) {
  57. furi_assert(view);
  58. view->orientation = orientation;
  59. }
  60. void view_allocate_model(View* view, ViewModelType type, size_t size) {
  61. furi_assert(view);
  62. furi_assert(size > 0);
  63. furi_assert(view->model_type == ViewModelTypeNone);
  64. furi_assert(view->model == NULL);
  65. view->model_type = type;
  66. if(view->model_type == ViewModelTypeLockFree) {
  67. view->model = malloc(size);
  68. } else if(view->model_type == ViewModelTypeLocking) {
  69. ViewModelLocking* model = malloc(sizeof(ViewModelLocking));
  70. model->mutex = furi_mutex_alloc(FuriMutexTypeNormal);
  71. furi_check(model->mutex);
  72. model->data = malloc(size);
  73. view->model = model;
  74. } else {
  75. furi_assert(false);
  76. }
  77. }
  78. void view_free_model(View* view) {
  79. furi_assert(view);
  80. if(view->model_type == ViewModelTypeNone) {
  81. return;
  82. } else if(view->model_type == ViewModelTypeLockFree) {
  83. free(view->model);
  84. } else if(view->model_type == ViewModelTypeLocking) {
  85. ViewModelLocking* model = view->model;
  86. furi_mutex_free(model->mutex);
  87. free(model->data);
  88. free(model);
  89. view->model = NULL;
  90. } else {
  91. furi_assert(false);
  92. }
  93. }
  94. void* view_get_model(View* view) {
  95. furi_assert(view);
  96. if(view->model_type == ViewModelTypeLocking) {
  97. ViewModelLocking* model = (ViewModelLocking*)(view->model);
  98. furi_check(furi_mutex_acquire(model->mutex, FuriWaitForever) == FuriStatusOk);
  99. return model->data;
  100. }
  101. return view->model;
  102. }
  103. void view_commit_model(View* view, bool update) {
  104. furi_assert(view);
  105. view_unlock_model(view);
  106. if(update && view->update_callback) {
  107. view->update_callback(view, view->update_callback_context);
  108. }
  109. }
  110. void view_icon_animation_callback(IconAnimation* instance, void* context) {
  111. UNUSED(instance);
  112. furi_assert(context);
  113. View* view = context;
  114. if(view->update_callback) {
  115. view->update_callback(view, view->update_callback_context);
  116. }
  117. }
  118. void view_unlock_model(View* view) {
  119. furi_assert(view);
  120. if(view->model_type == ViewModelTypeLocking) {
  121. ViewModelLocking* model = (ViewModelLocking*)(view->model);
  122. furi_check(furi_mutex_release(model->mutex) == FuriStatusOk);
  123. }
  124. }
  125. void view_draw(View* view, Canvas* canvas) {
  126. furi_assert(view);
  127. if(view->draw_callback) {
  128. void* data = view_get_model(view);
  129. view->draw_callback(canvas, data);
  130. view_unlock_model(view);
  131. }
  132. }
  133. bool view_input(View* view, InputEvent* event) {
  134. furi_assert(view);
  135. if(view->input_callback) {
  136. return view->input_callback(event, view->context);
  137. } else {
  138. return false;
  139. }
  140. }
  141. bool view_custom(View* view, uint32_t event) {
  142. furi_assert(view);
  143. if(view->custom_callback) {
  144. return view->custom_callback(event, view->context);
  145. } else {
  146. return false;
  147. }
  148. }
  149. uint32_t view_previous(View* view) {
  150. furi_assert(view);
  151. if(view->previous_callback) {
  152. return view->previous_callback(view->context);
  153. } else {
  154. return VIEW_IGNORE;
  155. }
  156. }
  157. void view_enter(View* view) {
  158. furi_assert(view);
  159. if(view->enter_callback) view->enter_callback(view->context);
  160. }
  161. void view_exit(View* view) {
  162. furi_assert(view);
  163. if(view->exit_callback) view->exit_callback(view->context);
  164. }