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. FuriTimer* 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,
  96. ViewDisplayTestModel * model,
  97. {
  98. if(event->key == InputKeyLeft && model->test > 0) {
  99. model->test--;
  100. consumed = true;
  101. } else if(
  102. event->key == InputKeyRight &&
  103. model->test < (COUNT_OF(view_display_test_tests) - 1)) {
  104. model->test++;
  105. consumed = true;
  106. } else if(event->key == InputKeyDown && model->size > 0) {
  107. model->size--;
  108. consumed = true;
  109. } else if(event->key == InputKeyUp && model->size < 24) {
  110. model->size++;
  111. consumed = true;
  112. } else if(event->key == InputKeyOk) {
  113. model->flip_flop = !model->flip_flop;
  114. consumed = true;
  115. }
  116. },
  117. consumed);
  118. }
  119. return consumed;
  120. }
  121. static void view_display_test_enter(void* context) {
  122. ViewDisplayTest* instance = context;
  123. furi_timer_start(instance->timer, furi_kernel_get_tick_frequency() / 32);
  124. }
  125. static void view_display_test_exit(void* context) {
  126. ViewDisplayTest* instance = context;
  127. furi_timer_stop(instance->timer);
  128. }
  129. static void view_display_test_timer_callback(void* context) {
  130. ViewDisplayTest* instance = context;
  131. with_view_model(
  132. instance->view, ViewDisplayTestModel * model, { model->counter++; }, true);
  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. furi_timer_alloc(view_display_test_timer_callback, FuriTimerTypePeriodic, instance);
  145. return instance;
  146. }
  147. void view_display_test_free(ViewDisplayTest* instance) {
  148. furi_assert(instance);
  149. furi_timer_free(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. }