icon_animation.c 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. #include "icon_animation_i.h"
  2. #include "icon_i.h"
  3. #include <furi.h>
  4. IconAnimation* icon_animation_alloc(const Icon* icon) {
  5. furi_assert(icon);
  6. IconAnimation* instance = furi_alloc(sizeof(IconAnimation));
  7. instance->icon = icon;
  8. instance->timer = osTimerNew(icon_animation_timer_callback, osTimerPeriodic, instance, NULL);
  9. return instance;
  10. }
  11. void icon_animation_free(IconAnimation* instance) {
  12. furi_assert(instance);
  13. furi_check(osTimerDelete(instance->timer) == osOK);
  14. free(instance);
  15. }
  16. void icon_animation_set_update_callback(
  17. IconAnimation* instance,
  18. IconAnimationCallback callback,
  19. void* context) {
  20. furi_assert(instance);
  21. instance->callback = callback;
  22. instance->callback_context = context;
  23. }
  24. const uint8_t* icon_animation_get_data(IconAnimation* instance) {
  25. return instance->icon->frames[instance->frame];
  26. }
  27. void icon_animation_next_frame(IconAnimation* instance) {
  28. furi_assert(instance);
  29. instance->frame = (instance->frame + 1) % instance->icon->frame_count;
  30. }
  31. void icon_animation_timer_callback(void* context) {
  32. furi_assert(context);
  33. IconAnimation* instance = context;
  34. if(!instance->animating) return;
  35. icon_animation_next_frame(instance);
  36. if(instance->callback) {
  37. instance->callback(instance, instance->callback_context);
  38. }
  39. }
  40. uint8_t icon_animation_get_width(IconAnimation* instance) {
  41. furi_assert(instance);
  42. return instance->icon->width;
  43. }
  44. uint8_t icon_animation_get_height(IconAnimation* instance) {
  45. furi_assert(instance);
  46. return instance->icon->height;
  47. }
  48. void icon_animation_start(IconAnimation* instance) {
  49. furi_assert(instance);
  50. if(!instance->animating) {
  51. instance->animating = true;
  52. furi_check(
  53. xTimerChangePeriod(
  54. instance->timer, (osKernelGetTickFreq() / instance->icon->frame_rate), 0) ==
  55. pdPASS);
  56. }
  57. }
  58. void icon_animation_stop(IconAnimation* instance) {
  59. furi_assert(instance);
  60. if(instance->animating) {
  61. instance->animating = false;
  62. furi_check(xTimerStop(instance->timer, 0) == pdPASS);
  63. instance->frame = 0;
  64. }
  65. }
  66. bool icon_animation_is_last_frame(IconAnimation* instance) {
  67. furi_assert(instance);
  68. return instance->icon->frame_count - instance->frame <= 1;
  69. }