gui.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  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_widget_status_bar_add(GUI* gui, Widget* widget) {
  21. assert(gui);
  22. assert(widget);
  23. gui_event_lock(gui->event);
  24. WidgetArray_push_back(gui->widgets_status_bar, widget);
  25. widget_gui_set(widget, gui);
  26. gui_event_unlock(gui->event);
  27. gui_update(gui);
  28. }
  29. void gui_widget_add(GUI* gui, Widget* widget) {
  30. assert(gui);
  31. assert(widget);
  32. gui_event_lock(gui->event);
  33. WidgetArray_push_back(gui->widgets, widget);
  34. widget_gui_set(widget, gui);
  35. gui_event_unlock(gui->event);
  36. gui_update(gui);
  37. }
  38. void gui_widget_fs_add(GUI* gui, Widget* widget) {
  39. assert(gui);
  40. assert(widget);
  41. gui_event_lock(gui->event);
  42. WidgetArray_push_back(gui->widgets_fs, widget);
  43. widget_gui_set(widget, gui);
  44. gui_event_unlock(gui->event);
  45. gui_update(gui);
  46. }
  47. void gui_widget_dialog_add(GUI* gui, Widget* widget) {
  48. assert(gui);
  49. assert(widget);
  50. gui_event_lock(gui->event);
  51. WidgetArray_push_back(gui->widgets_dialog, widget);
  52. widget_gui_set(widget, gui);
  53. gui_event_unlock(gui->event);
  54. gui_update(gui);
  55. }
  56. void gui_update(GUI* gui) {
  57. assert(gui);
  58. GUIMessage message;
  59. message.type = GUIMessageTypeRedraw;
  60. gui_event_messsage_send(gui->event, &message);
  61. }
  62. Widget* gui_widget_find_enabled(WidgetArray_t array) {
  63. size_t widgets_count = WidgetArray_size(array);
  64. for(size_t i = 0; i < widgets_count; i++) {
  65. Widget* widget = *WidgetArray_get(array, widgets_count - i - 1);
  66. if(widget_is_enabled(widget)) {
  67. return widget;
  68. }
  69. }
  70. return NULL;
  71. }
  72. bool gui_redraw_fs(GUI* gui) {
  73. canvas_frame_set(gui->canvas, 0, 0, 128, 64);
  74. Widget* widget = gui_widget_find_enabled(gui->widgets_fs);
  75. if(widget) {
  76. widget_draw(widget, gui->canvas);
  77. return true;
  78. } else {
  79. return false;
  80. }
  81. }
  82. void gui_redraw_status_bar(GUI* gui) {
  83. canvas_frame_set(gui->canvas, 0, 0, 128, 64);
  84. Widget* widget = gui_widget_find_enabled(gui->widgets_status_bar);
  85. if(widget) widget_draw(widget, gui->canvas);
  86. }
  87. void gui_redraw_normal(GUI* gui) {
  88. canvas_frame_set(gui->canvas, 0, 9, 128, 55);
  89. Widget* widget = gui_widget_find_enabled(gui->widgets);
  90. if(widget) widget_draw(widget, gui->canvas);
  91. }
  92. void gui_redraw_dialogs(GUI* gui) {
  93. canvas_frame_set(gui->canvas, 10, 20, 118, 44);
  94. Widget* widget = gui_widget_find_enabled(gui->widgets_dialog);
  95. if(widget) widget_draw(widget, gui->canvas);
  96. }
  97. void gui_redraw(GUI* gui) {
  98. assert(gui);
  99. if(!gui_redraw_fs(gui)) {
  100. gui_redraw_status_bar(gui);
  101. gui_redraw_normal(gui);
  102. }
  103. gui_redraw_dialogs(gui);
  104. canvas_commit(gui->canvas);
  105. }
  106. void gui_input(GUI* gui, InputEvent* input_event) {
  107. assert(gui);
  108. Widget* widget = gui_widget_find_enabled(gui->widgets_dialog);
  109. if(!widget) widget = gui_widget_find_enabled(gui->widgets_fs);
  110. if(!widget) widget = gui_widget_find_enabled(gui->widgets);
  111. if(widget) {
  112. widget_input(widget, input_event);
  113. }
  114. }
  115. GUI* gui_alloc() {
  116. GUI* gui = furi_alloc(sizeof(GUI));
  117. // Initialize widget arrays
  118. WidgetArray_init(gui->widgets_status_bar);
  119. WidgetArray_init(gui->widgets);
  120. WidgetArray_init(gui->widgets_fs);
  121. WidgetArray_init(gui->widgets_dialog);
  122. // Event dispatcher
  123. gui->event = gui_event_alloc();
  124. // Drawing canvas
  125. gui->canvas = canvas_alloc();
  126. return gui;
  127. }
  128. void gui_task(void* p) {
  129. GUI* gui = gui_alloc();
  130. // Create FURI record
  131. if(!furi_create_deprecated("gui", gui, sizeof(gui))) {
  132. printf("[gui_task] cannot create the gui record\n");
  133. furiac_exit(NULL);
  134. }
  135. furiac_ready();
  136. // Forever dispatch
  137. while(1) {
  138. GUIMessage message = gui_event_message_next(gui->event);
  139. if(message.type == GUIMessageTypeRedraw) {
  140. gui_redraw(gui);
  141. } else if(message.type == GUIMessageTypeInput) {
  142. gui_input(gui, &message.input);
  143. }
  144. }
  145. }