icon_animation.c 2.3 KB

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