view_display_test.c 5.9 KB

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