gui.c 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. #include "gui.h"
  2. #include "gui_i.h"
  3. #include <furi.h>
  4. #include <m-array.h>
  5. #include <stdio.h>
  6. #include "gui_event.h"
  7. #include "canvas.h"
  8. #include "canvas_i.h"
  9. #include "view_port.h"
  10. #include "view_port_i.h"
  11. ARRAY_DEF(ViewPortArray, ViewPort*, M_PTR_OPLIST);
  12. struct Gui {
  13. GuiEvent* event;
  14. Canvas* canvas;
  15. ViewPortArray_t layers[GuiLayerMAX];
  16. osMutexId_t mutex;
  17. };
  18. ViewPort* gui_view_port_find_enabled(ViewPortArray_t array) {
  19. size_t view_ports_count = ViewPortArray_size(array);
  20. for(size_t i = 0; i < view_ports_count; i++) {
  21. ViewPort* view_port = *ViewPortArray_get(array, view_ports_count - i - 1);
  22. if(view_port_is_enabled(view_port)) {
  23. return view_port;
  24. }
  25. }
  26. return NULL;
  27. }
  28. void gui_update(Gui* gui) {
  29. furi_assert(gui);
  30. GuiMessage message;
  31. message.type = GuiMessageTypeRedraw;
  32. gui_event_messsage_send(gui->event, &message);
  33. }
  34. bool gui_redraw_fs(Gui* gui) {
  35. canvas_frame_set(gui->canvas, 0, 0, GUI_DISPLAY_WIDTH, GUI_DISPLAY_HEIGHT);
  36. ViewPort* view_port = gui_view_port_find_enabled(gui->layers[GuiLayerFullscreen]);
  37. if(view_port) {
  38. view_port_draw(view_port, gui->canvas);
  39. return true;
  40. } else {
  41. return false;
  42. }
  43. }
  44. void gui_redraw_status_bar(Gui* gui) {
  45. ViewPortArray_it_t it;
  46. uint8_t x;
  47. uint8_t x_used = 0;
  48. uint8_t width;
  49. ViewPort* view_port;
  50. // Right side
  51. x = 128;
  52. ViewPortArray_it(it, gui->layers[GuiLayerStatusBarRight]);
  53. while(!ViewPortArray_end_p(it) && x_used < GUI_STATUS_BAR_WIDTH) {
  54. // Render view_port;
  55. view_port = *ViewPortArray_ref(it);
  56. if(view_port_is_enabled(view_port)) {
  57. width = view_port_get_width(view_port);
  58. if(!width) width = 8;
  59. x_used += width;
  60. x -= (width + 2);
  61. canvas_frame_set(gui->canvas, x, GUI_STATUS_BAR_Y, width, GUI_STATUS_BAR_HEIGHT);
  62. view_port_draw(view_port, gui->canvas);
  63. }
  64. ViewPortArray_next(it);
  65. }
  66. // Left side
  67. x = 0;
  68. ViewPortArray_it(it, gui->layers[GuiLayerStatusBarLeft]);
  69. while(!ViewPortArray_end_p(it) && x_used < GUI_STATUS_BAR_WIDTH) {
  70. // Render view_port;
  71. view_port = *ViewPortArray_ref(it);
  72. if(view_port_is_enabled(view_port)) {
  73. width = view_port_get_width(view_port);
  74. if(!width) width = 8;
  75. x_used += width;
  76. canvas_frame_set(gui->canvas, x, GUI_STATUS_BAR_Y, width, GUI_STATUS_BAR_HEIGHT);
  77. view_port_draw(view_port, gui->canvas);
  78. x += (width + 2);
  79. }
  80. ViewPortArray_next(it);
  81. }
  82. }
  83. bool gui_redraw_normal(Gui* gui) {
  84. canvas_frame_set(gui->canvas, GUI_MAIN_X, GUI_MAIN_Y, GUI_MAIN_WIDTH, GUI_MAIN_HEIGHT);
  85. ViewPort* view_port = gui_view_port_find_enabled(gui->layers[GuiLayerMain]);
  86. if(view_port) {
  87. view_port_draw(view_port, gui->canvas);
  88. return true;
  89. }
  90. return false;
  91. }
  92. bool gui_redraw_none(Gui* gui) {
  93. canvas_frame_set(gui->canvas, GUI_MAIN_X, GUI_MAIN_Y, GUI_MAIN_WIDTH, GUI_MAIN_HEIGHT);
  94. ViewPort* view_port = gui_view_port_find_enabled(gui->layers[GuiLayerNone]);
  95. if(view_port) {
  96. view_port_draw(view_port, gui->canvas);
  97. return true;
  98. }
  99. return false;
  100. }
  101. void gui_redraw(Gui* gui) {
  102. furi_assert(gui);
  103. gui_lock(gui);
  104. canvas_reset(gui->canvas);
  105. if(!gui_redraw_fs(gui)) {
  106. if(!gui_redraw_normal(gui)) {
  107. gui_redraw_none(gui);
  108. }
  109. gui_redraw_status_bar(gui);
  110. }
  111. canvas_commit(gui->canvas);
  112. gui_unlock(gui);
  113. }
  114. void gui_input(Gui* gui, InputEvent* input_event) {
  115. furi_assert(gui);
  116. furi_assert(input_event);
  117. gui_lock(gui);
  118. ViewPort* view_port = gui_view_port_find_enabled(gui->layers[GuiLayerFullscreen]);
  119. if(!view_port) view_port = gui_view_port_find_enabled(gui->layers[GuiLayerMain]);
  120. if(!view_port) view_port = gui_view_port_find_enabled(gui->layers[GuiLayerNone]);
  121. if(view_port) {
  122. view_port_input(view_port, input_event);
  123. }
  124. gui_unlock(gui);
  125. }
  126. void gui_lock(Gui* gui) {
  127. furi_assert(gui);
  128. furi_check(osMutexAcquire(gui->mutex, osWaitForever) == osOK);
  129. }
  130. void gui_unlock(Gui* gui) {
  131. furi_assert(gui);
  132. furi_check(osMutexRelease(gui->mutex) == osOK);
  133. }
  134. void gui_add_view_port(Gui* gui, ViewPort* view_port, GuiLayer layer) {
  135. furi_assert(gui);
  136. furi_assert(view_port);
  137. furi_check(layer < GuiLayerMAX);
  138. gui_lock(gui);
  139. ViewPortArray_push_back(gui->layers[layer], view_port);
  140. view_port_gui_set(view_port, gui);
  141. gui_unlock(gui);
  142. gui_update(gui);
  143. }
  144. void gui_remove_view_port(Gui* gui, ViewPort* view_port) {
  145. furi_assert(gui);
  146. furi_assert(view_port);
  147. gui_lock(gui);
  148. view_port_gui_set(view_port, NULL);
  149. ViewPortArray_it_t it;
  150. for(size_t i = 0; i < GuiLayerMAX; i++) {
  151. ViewPortArray_it(it, gui->layers[i]);
  152. while(!ViewPortArray_end_p(it)) {
  153. if(*ViewPortArray_ref(it) == view_port) {
  154. ViewPortArray_remove(gui->layers[i], it);
  155. }
  156. ViewPortArray_next(it);
  157. }
  158. }
  159. gui_unlock(gui);
  160. }
  161. Gui* gui_alloc() {
  162. Gui* gui = furi_alloc(sizeof(Gui));
  163. // Allocate mutex
  164. gui->mutex = osMutexNew(NULL);
  165. furi_check(gui->mutex);
  166. // Event dispatcher
  167. gui->event = gui_event_alloc();
  168. // Drawing canvas
  169. gui->canvas = canvas_init();
  170. // Compose Layers
  171. for(size_t i = 0; i < GuiLayerMAX; i++) {
  172. ViewPortArray_init(gui->layers[i]);
  173. }
  174. return gui;
  175. }
  176. void gui_task(void* p) {
  177. Gui* gui = gui_alloc();
  178. // Create FURI record
  179. furi_record_create("gui", gui);
  180. // Forever dispatch
  181. while(1) {
  182. GuiMessage message = gui_event_message_next(gui->event);
  183. if(message.type == GuiMessageTypeRedraw) {
  184. gui_redraw(gui);
  185. } else if(message.type == GuiMessageTypeInput) {
  186. gui_input(gui, &message.input);
  187. }
  188. }
  189. }