icon_animation.c 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  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_assert(instance->icon->frame_rate);
  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. }