gui.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. #include "gui.h"
  2. #include "gui_i.h"
  3. #include <flipper.h>
  4. #include <stdio.h>
  5. #include <m-array.h>
  6. #include "gui_event.h"
  7. #include "canvas.h"
  8. #include "canvas_i.h"
  9. #include "widget.h"
  10. #include "widget_i.h"
  11. ARRAY_DEF(WidgetArray, Widget*, M_PTR_OPLIST);
  12. struct GUI {
  13. GUIEvent* event;
  14. Canvas* canvas;
  15. WidgetArray_t widgets_status_bar;
  16. WidgetArray_t widgets;
  17. WidgetArray_t widgets_fs;
  18. WidgetArray_t widgets_dialog;
  19. };
  20. void gui_add_widget(GUI* gui, Widget* widget, WidgetLayer layer) {
  21. WidgetArray_t* widget_array = NULL;
  22. switch(layer) {
  23. case WidgetLayerStatusBar:
  24. widget_array = &gui->widgets_status_bar;
  25. break;
  26. case WidgetLayerMain:
  27. widget_array = &gui->widgets;
  28. break;
  29. case WidgetLayerFullscreen:
  30. widget_array = &gui->widgets_fs;
  31. break;
  32. case WidgetLayerDialog:
  33. widget_array = &gui->widgets_dialog;
  34. break;
  35. default:
  36. }
  37. assert(gui);
  38. assert(widget);
  39. assert(widget_array);
  40. gui_event_lock(gui->event);
  41. WidgetArray_push_back(widget_array, widget);
  42. widget_gui_set(widget, gui);
  43. gui_event_unlock(gui->event);
  44. gui_update(gui);
  45. }
  46. void gui_update(GUI* gui) {
  47. assert(gui);
  48. GUIMessage message;
  49. message.type = GUIMessageTypeRedraw;
  50. gui_event_messsage_send(gui->event, &message);
  51. }
  52. Widget* gui_widget_find_enabled(WidgetArray_t array) {
  53. size_t widgets_count = WidgetArray_size(array);
  54. for(size_t i = 0; i < widgets_count; i++) {
  55. Widget* widget = *WidgetArray_get(array, widgets_count - i - 1);
  56. if(widget_is_enabled(widget)) {
  57. return widget;
  58. }
  59. }
  60. return NULL;
  61. }
  62. bool gui_redraw_fs(GUI* gui) {
  63. canvas_frame_set(gui->canvas, 0, 0, 128, 64);
  64. Widget* widget = gui_widget_find_enabled(gui->widgets_fs);
  65. if(widget) {
  66. widget_draw(widget, gui->canvas);
  67. return true;
  68. } else {
  69. return false;
  70. }
  71. }
  72. void gui_redraw_status_bar(GUI* gui) {
  73. canvas_frame_set(gui->canvas, 0, 0, 128, 64);
  74. Widget* widget = gui_widget_find_enabled(gui->widgets_status_bar);
  75. if(widget) widget_draw(widget, gui->canvas);
  76. }
  77. void gui_redraw_normal(GUI* gui) {
  78. canvas_frame_set(gui->canvas, 0, 9, 128, 55);
  79. Widget* widget = gui_widget_find_enabled(gui->widgets);
  80. if(widget) widget_draw(widget, gui->canvas);
  81. }
  82. void gui_redraw_dialogs(GUI* gui) {
  83. canvas_frame_set(gui->canvas, 10, 20, 118, 44);
  84. Widget* widget = gui_widget_find_enabled(gui->widgets_dialog);
  85. if(widget) widget_draw(widget, gui->canvas);
  86. }
  87. void gui_redraw(GUI* gui) {
  88. assert(gui);
  89. if(!gui_redraw_fs(gui)) {
  90. gui_redraw_status_bar(gui);
  91. gui_redraw_normal(gui);
  92. }
  93. gui_redraw_dialogs(gui);
  94. canvas_commit(gui->canvas);
  95. }
  96. void gui_input(GUI* gui, InputEvent* input_event) {
  97. assert(gui);
  98. Widget* widget = gui_widget_find_enabled(gui->widgets_dialog);
  99. if(!widget) widget = gui_widget_find_enabled(gui->widgets_fs);
  100. if(!widget) widget = gui_widget_find_enabled(gui->widgets);
  101. if(widget) {
  102. widget_input(widget, input_event);
  103. }
  104. }
  105. GUI* gui_alloc() {
  106. GUI* gui = furi_alloc(sizeof(GUI));
  107. // Initialize widget arrays
  108. WidgetArray_init(gui->widgets_status_bar);
  109. WidgetArray_init(gui->widgets);
  110. WidgetArray_init(gui->widgets_fs);
  111. WidgetArray_init(gui->widgets_dialog);
  112. // Event dispatcher
  113. gui->event = gui_event_alloc();
  114. // Drawing canvas
  115. gui->canvas = canvas_alloc();
  116. return gui;
  117. }
  118. void gui_task(void* p) {
  119. GUI* gui = gui_alloc();
  120. GuiApi gui_api = {
  121. .add_widget = gui_add_widget,
  122. .gui = gui,
  123. };
  124. // Create FURI record
  125. if(!furi_create("gui", &gui_api)) {
  126. printf("[gui_task] cannot create the gui record\n");
  127. furiac_exit(NULL);
  128. }
  129. furiac_ready();
  130. // Forever dispatch
  131. while(1) {
  132. GUIMessage message = gui_event_message_next(gui->event);
  133. if(message.type == GUIMessageTypeRedraw) {
  134. gui_redraw(gui);
  135. } else if(message.type == GUIMessageTypeInput) {
  136. gui_input(gui, &message.input);
  137. }
  138. }
  139. }