view_display_test.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. #include "view_display_test.h"
  2. typedef struct {
  3. uint32_t test;
  4. uint32_t size;
  5. uint32_t counter;
  6. bool flip_flop;
  7. } ViewDisplayTestModel;
  8. struct ViewDisplayTest {
  9. View* view;
  10. osTimerId_t timer;
  11. };
  12. static void view_display_test_draw_callback_intro(Canvas* canvas, void* _model) {
  13. UNUSED(_model);
  14. canvas_draw_str(canvas, 12, 24, "Use < and > to switch tests");
  15. canvas_draw_str(canvas, 12, 36, "Use ^ and v to switch size");
  16. canvas_draw_str(canvas, 32, 48, "Use (o) to flip");
  17. }
  18. static void view_display_test_draw_callback_fill(Canvas* canvas, void* _model) {
  19. ViewDisplayTestModel* model = _model;
  20. if(model->flip_flop) {
  21. uint8_t width = canvas_width(canvas);
  22. uint8_t height = canvas_height(canvas);
  23. canvas_draw_box(canvas, 0, 0, width, height);
  24. }
  25. }
  26. static void view_display_test_draw_callback_hstripe(Canvas* canvas, void* _model) {
  27. ViewDisplayTestModel* model = _model;
  28. uint8_t block = 1 + model->size;
  29. uint8_t width = canvas_width(canvas);
  30. uint8_t height = canvas_height(canvas);
  31. for(uint8_t y = model->flip_flop * block; y < height; y += 2 * block) {
  32. canvas_draw_box(canvas, 0, y, width, block);
  33. }
  34. }
  35. static void view_display_test_draw_callback_vstripe(Canvas* canvas, void* _model) {
  36. ViewDisplayTestModel* model = _model;
  37. uint8_t block = 1 + model->size;
  38. uint8_t width = canvas_width(canvas);
  39. uint8_t height = canvas_height(canvas);
  40. for(uint8_t x = model->flip_flop * block; x < width; x += 2 * block) {
  41. canvas_draw_box(canvas, x, 0, block, height);
  42. }
  43. }
  44. static void view_display_test_draw_callback_check(Canvas* canvas, void* _model) {
  45. ViewDisplayTestModel* model = _model;
  46. uint8_t block = 1 + model->size;
  47. uint8_t width = canvas_width(canvas);
  48. uint8_t height = canvas_height(canvas);
  49. bool flip_flop = model->flip_flop;
  50. for(uint8_t x = 0; x < width; x += block) {
  51. bool last_flip_flop = flip_flop;
  52. for(uint8_t y = 0; y < height; y += block) {
  53. if(flip_flop) {
  54. canvas_draw_box(canvas, x, y, block, block);
  55. }
  56. flip_flop = !flip_flop;
  57. }
  58. if(last_flip_flop == flip_flop) {
  59. flip_flop = !flip_flop;
  60. }
  61. }
  62. }
  63. static void view_display_test_draw_callback_move(Canvas* canvas, void* _model) {
  64. ViewDisplayTestModel* model = _model;
  65. uint8_t block = 1 + model->size;
  66. uint8_t width = canvas_width(canvas) - block;
  67. uint8_t height = canvas_height(canvas) - block;
  68. uint8_t x = model->counter % width;
  69. if((model->counter / width) % 2) {
  70. x = width - x;
  71. }
  72. uint8_t y = model->counter % height;
  73. if((model->counter / height) % 2) {
  74. y = height - y;
  75. }
  76. canvas_draw_box(canvas, x, y, block, block);
  77. }
  78. const ViewDrawCallback view_display_test_tests[] = {
  79. view_display_test_draw_callback_intro,
  80. view_display_test_draw_callback_fill,
  81. view_display_test_draw_callback_hstripe,
  82. view_display_test_draw_callback_vstripe,
  83. view_display_test_draw_callback_check,
  84. view_display_test_draw_callback_move,
  85. };
  86. static void view_display_test_draw_callback(Canvas* canvas, void* _model) {
  87. ViewDisplayTestModel* model = _model;
  88. view_display_test_tests[model->test](canvas, _model);
  89. }
  90. static bool view_display_test_input_callback(InputEvent* event, void* context) {
  91. ViewDisplayTest* instance = context;
  92. bool consumed = false;
  93. if(event->type == InputTypeShort || event->type == InputTypeRepeat) {
  94. with_view_model(
  95. instance->view, (ViewDisplayTestModel * model) {
  96. if(event->key == InputKeyLeft && model->test > 0) {
  97. model->test--;
  98. consumed = true;
  99. } else if(
  100. event->key == InputKeyRight &&
  101. model->test < (COUNT_OF(view_display_test_tests) - 1)) {
  102. model->test++;
  103. consumed = true;
  104. } else if(event->key == InputKeyDown && model->size > 0) {
  105. model->size--;
  106. consumed = true;
  107. } else if(event->key == InputKeyUp && model->size < 24) {
  108. model->size++;
  109. consumed = true;
  110. } else if(event->key == InputKeyOk) {
  111. model->flip_flop = !model->flip_flop;
  112. consumed = true;
  113. }
  114. return consumed;
  115. });
  116. }
  117. return consumed;
  118. }
  119. static void view_display_test_enter(void* context) {
  120. ViewDisplayTest* instance = context;
  121. osTimerStart(instance->timer, osKernelGetTickFreq() / 32);
  122. }
  123. static void view_display_test_exit(void* context) {
  124. ViewDisplayTest* instance = context;
  125. osTimerStop(instance->timer);
  126. }
  127. static void view_display_test_timer_callback(void* context) {
  128. ViewDisplayTest* instance = context;
  129. with_view_model(
  130. instance->view, (ViewDisplayTestModel * model) {
  131. model->counter++;
  132. return true;
  133. });
  134. }
  135. ViewDisplayTest* view_display_test_alloc() {
  136. ViewDisplayTest* instance = malloc(sizeof(ViewDisplayTest));
  137. instance->view = view_alloc();
  138. view_set_context(instance->view, instance);
  139. view_allocate_model(instance->view, ViewModelTypeLockFree, sizeof(ViewDisplayTestModel));
  140. view_set_draw_callback(instance->view, view_display_test_draw_callback);
  141. view_set_input_callback(instance->view, view_display_test_input_callback);
  142. view_set_enter_callback(instance->view, view_display_test_enter);
  143. view_set_exit_callback(instance->view, view_display_test_exit);
  144. instance->timer =
  145. osTimerNew(view_display_test_timer_callback, osTimerPeriodic, instance, NULL);
  146. return instance;
  147. }
  148. void view_display_test_free(ViewDisplayTest* instance) {
  149. furi_assert(instance);
  150. osTimerDelete(instance->timer);
  151. view_free(instance->view);
  152. free(instance);
  153. }
  154. View* view_display_test_get_view(ViewDisplayTest* instance) {
  155. furi_assert(instance);
  156. return instance->view;
  157. }