flipp_pomodoro_timer_view.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. #include "flipp_pomodoro_timer_view.h"
  2. #include <furi.h>
  3. #include <gui/gui.h>
  4. #include <gui/elements.h>
  5. #include <gui/view.h>
  6. #include "../helpers/debug.h"
  7. #include "../flipp_pomodoro_app.h"
  8. #include "../modules/flipp_pomodoro.h"
  9. // Auto-compiled icons
  10. #include "flipp_pomodoro_icons.h"
  11. enum
  12. {
  13. ViewInputConsumed = true,
  14. ViewInputNotConusmed = false,
  15. };
  16. struct FlippPomodoroTimerView
  17. {
  18. View *view;
  19. FlippPomodoroTimerViewInputCb right_cb;
  20. void *right_cb_ctx;
  21. };
  22. typedef struct
  23. {
  24. FlippPomodoroState *state;
  25. } FlippPomodoroTimerViewModel;
  26. static const Icon *stage_background_image[] = {
  27. [Work] = &I_flipp_pomodoro_work_64,
  28. [Rest] = &I_flipp_pomodoro_rest_64,
  29. };
  30. static void flipp_pomodoro_view_timer_draw_countdown(Canvas *canvas, TimeDifference remaining_time)
  31. {
  32. canvas_set_font(canvas, FontBigNumbers);
  33. const uint8_t right_border_margin = 1;
  34. const uint8_t countdown_box_height = canvas_height(canvas) * 0.4;
  35. const uint8_t countdown_box_width = canvas_width(canvas) * 0.5;
  36. const uint8_t countdown_box_x = canvas_width(canvas) - countdown_box_width - right_border_margin;
  37. const uint8_t countdown_box_y = 0;
  38. elements_bold_rounded_frame(canvas,
  39. countdown_box_x,
  40. countdown_box_y,
  41. countdown_box_width,
  42. countdown_box_height);
  43. FuriString *timer_string = furi_string_alloc();
  44. furi_string_printf(timer_string, "%02u:%02u", remaining_time.minutes, remaining_time.seconds);
  45. const char *remaining_stage_time_string = furi_string_get_cstr(timer_string);
  46. canvas_draw_str_aligned(
  47. canvas,
  48. countdown_box_x + (countdown_box_width / 2),
  49. countdown_box_y + (countdown_box_height / 2),
  50. AlignCenter,
  51. AlignCenter,
  52. remaining_stage_time_string);
  53. furi_string_free(timer_string);
  54. };
  55. static void flipp_pomodoro_view_timer_draw_callback(Canvas *canvas, void *_model)
  56. {
  57. if (!_model)
  58. {
  59. return;
  60. };
  61. FlippPomodoroTimerViewModel *model = _model;
  62. canvas_clear(canvas);
  63. canvas_draw_icon(canvas, 0, 0, stage_background_image[model->state->stage]);
  64. flipp_pomodoro_view_timer_draw_countdown(
  65. canvas,
  66. flipp_pomodoro__stage_remaining_duration(model->state));
  67. canvas_set_font(canvas, FontSecondary);
  68. elements_button_right(canvas, flipp_pomodoro__next_stage_label(model->state));
  69. };
  70. bool flipp_pomodoro_view_timer_input_callback(InputEvent *event, void *ctx)
  71. {
  72. furi_assert(ctx);
  73. furi_assert(event);
  74. FlippPomodoroTimerView *timer = ctx;
  75. const bool should_trigger_right_event_cb = (event->type == InputTypePress) &&
  76. (event->key == InputKeyRight) &&
  77. (timer->right_cb != NULL);
  78. if (should_trigger_right_event_cb)
  79. {
  80. furi_assert(timer->right_cb);
  81. furi_assert(timer->right_cb_ctx);
  82. timer->right_cb(timer->right_cb_ctx);
  83. return ViewInputConsumed;
  84. };
  85. return ViewInputNotConusmed;
  86. };
  87. View *flipp_pomodoro_view_timer_get_view(FlippPomodoroTimerView *timer)
  88. {
  89. furi_assert(timer);
  90. return timer->view;
  91. };
  92. FlippPomodoroTimerView *flipp_pomodoro_view_timer_alloc()
  93. {
  94. FlippPomodoroTimerView *timer = malloc(sizeof(FlippPomodoroTimerView));
  95. timer->view = view_alloc();
  96. view_allocate_model(timer->view, ViewModelTypeLockFree, sizeof(FlippPomodoroTimerViewModel));
  97. view_set_context(flipp_pomodoro_view_timer_get_view(timer), timer);
  98. view_set_draw_callback(timer->view, flipp_pomodoro_view_timer_draw_callback);
  99. view_set_input_callback(timer->view, flipp_pomodoro_view_timer_input_callback);
  100. return timer;
  101. };
  102. void flipp_pomodoro_view_timer_set_on_right_cb(FlippPomodoroTimerView *timer, FlippPomodoroTimerViewInputCb right_cb, void *right_cb_ctx)
  103. {
  104. furi_assert(right_cb);
  105. furi_assert(right_cb_ctx);
  106. timer->right_cb = right_cb;
  107. timer->right_cb_ctx = right_cb_ctx;
  108. };
  109. void flipp_pomodoro_view_timer_set_state(View *view, FlippPomodoroState *state)
  110. {
  111. furi_assert(view);
  112. furi_assert(state);
  113. with_view_model(
  114. view,
  115. FlippPomodoroTimerViewModel * model,
  116. {
  117. model->state = state;
  118. },
  119. false);
  120. };
  121. void flipp_pomodoro_view_timer_free(FlippPomodoroTimerView *timer)
  122. {
  123. furi_assert(timer);
  124. view_free(timer->view);
  125. free(timer);
  126. };