acid-drop

- Hacking the planet from a LilyGo T-Deck using custom firmware
git clone git://git.acid.vegas/acid-drop.git
Log | Files | Refs | Archive | README | LICENSE

lv_anim_timeline.c (4752B)

      1 /**
      2  * @file lv_anim_timeline.c
      3  *
      4  */
      5 
      6 /*********************
      7  *      INCLUDES
      8  *********************/
      9 #include "lv_anim_timeline.h"
     10 #include "lv_mem.h"
     11 #include "lv_assert.h"
     12 
     13 /*********************
     14  *      DEFINES
     15  *********************/
     16 
     17 /**********************
     18  *      TYPEDEFS
     19  **********************/
     20 
     21 /*Data of anim_timeline_dsc*/
     22 typedef struct {
     23     lv_anim_t anim;
     24     uint32_t start_time;
     25 } lv_anim_timeline_dsc_t;
     26 
     27 /*Data of anim_timeline*/
     28 struct _lv_anim_timeline_t {
     29     lv_anim_timeline_dsc_t * anim_dsc;  /**< Dynamically allocated anim dsc array*/
     30     uint32_t anim_dsc_cnt;              /**< The length of anim dsc array*/
     31     bool reverse;                       /**< Reverse playback*/
     32 };
     33 
     34 /**********************
     35  *  STATIC PROTOTYPES
     36  **********************/
     37 static void lv_anim_timeline_virtual_exec_cb(void * var, int32_t v);
     38 
     39 /**********************
     40  *  STATIC VARIABLES
     41  **********************/
     42 
     43 /**********************
     44  *      MACROS
     45  **********************/
     46 
     47 /**********************
     48  *   GLOBAL FUNCTIONS
     49  **********************/
     50 
     51 lv_anim_timeline_t * lv_anim_timeline_create(void)
     52 {
     53     lv_anim_timeline_t * at = (lv_anim_timeline_t *)lv_mem_alloc(sizeof(lv_anim_timeline_t));
     54 
     55     LV_ASSERT_MALLOC(at);
     56 
     57     if(at) lv_memset_00(at, sizeof(lv_anim_timeline_t));
     58 
     59     return at;
     60 }
     61 
     62 void lv_anim_timeline_del(lv_anim_timeline_t * at)
     63 {
     64     LV_ASSERT_NULL(at);
     65 
     66     lv_anim_timeline_stop(at);
     67 
     68     lv_mem_free(at->anim_dsc);
     69     lv_mem_free(at);
     70 }
     71 
     72 void lv_anim_timeline_add(lv_anim_timeline_t * at, uint32_t start_time, lv_anim_t * a)
     73 {
     74     LV_ASSERT_NULL(at);
     75 
     76     at->anim_dsc_cnt++;
     77     at->anim_dsc = lv_mem_realloc(at->anim_dsc, at->anim_dsc_cnt * sizeof(lv_anim_timeline_dsc_t));
     78 
     79     LV_ASSERT_MALLOC(at->anim_dsc);
     80 
     81     at->anim_dsc[at->anim_dsc_cnt - 1].anim = *a;
     82     at->anim_dsc[at->anim_dsc_cnt - 1].start_time = start_time;
     83 
     84     /*Add default var and virtual exec_cb, used to delete animation.*/
     85     if(a->var == NULL && a->exec_cb == NULL) {
     86         at->anim_dsc[at->anim_dsc_cnt - 1].anim.var = at;
     87         at->anim_dsc[at->anim_dsc_cnt - 1].anim.exec_cb = lv_anim_timeline_virtual_exec_cb;
     88     }
     89 }
     90 
     91 uint32_t lv_anim_timeline_start(lv_anim_timeline_t * at)
     92 {
     93     LV_ASSERT_NULL(at);
     94 
     95     const uint32_t playtime = lv_anim_timeline_get_playtime(at);
     96     bool reverse = at->reverse;
     97 
     98     for(uint32_t i = 0; i < at->anim_dsc_cnt; i++) {
     99         lv_anim_t a = at->anim_dsc[i].anim;
    100         uint32_t start_time = at->anim_dsc[i].start_time;
    101 
    102         if(reverse) {
    103             int32_t temp = a.start_value;
    104             a.start_value = a.end_value;
    105             a.end_value = temp;
    106             lv_anim_set_delay(&a, playtime - (start_time + a.time));
    107         }
    108         else {
    109             lv_anim_set_delay(&a, start_time);
    110         }
    111 
    112         lv_anim_start(&a);
    113     }
    114 
    115     return playtime;
    116 }
    117 
    118 void lv_anim_timeline_stop(lv_anim_timeline_t * at)
    119 {
    120     LV_ASSERT_NULL(at);
    121 
    122     for(uint32_t i = 0; i < at->anim_dsc_cnt; i++) {
    123         lv_anim_t * a = &(at->anim_dsc[i].anim);
    124         lv_anim_del(a->var, a->exec_cb);
    125     }
    126 }
    127 
    128 void lv_anim_timeline_set_reverse(lv_anim_timeline_t * at, bool reverse)
    129 {
    130     LV_ASSERT_NULL(at);
    131     at->reverse = reverse;
    132 }
    133 
    134 void lv_anim_timeline_set_progress(lv_anim_timeline_t * at, uint16_t progress)
    135 {
    136     LV_ASSERT_NULL(at);
    137 
    138     const uint32_t playtime = lv_anim_timeline_get_playtime(at);
    139     const uint32_t act_time = progress * playtime / 0xFFFF;
    140 
    141     for(uint32_t i = 0; i < at->anim_dsc_cnt; i++) {
    142         lv_anim_t * a = &(at->anim_dsc[i].anim);
    143 
    144         if(a->exec_cb == NULL) {
    145             continue;
    146         }
    147 
    148         uint32_t start_time = at->anim_dsc[i].start_time;
    149         int32_t value = 0;
    150 
    151         if(act_time < start_time) {
    152             value = a->start_value;
    153         }
    154         else if(act_time < (start_time + a->time)) {
    155             a->act_time = act_time - start_time;
    156             value = a->path_cb(a);
    157         }
    158         else {
    159             value = a->end_value;
    160         }
    161 
    162         a->exec_cb(a->var, value);
    163     }
    164 }
    165 
    166 uint32_t lv_anim_timeline_get_playtime(lv_anim_timeline_t * at)
    167 {
    168     LV_ASSERT_NULL(at);
    169 
    170     uint32_t playtime = 0;
    171     for(uint32_t i = 0; i < at->anim_dsc_cnt; i++) {
    172         uint32_t end = lv_anim_get_playtime(&at->anim_dsc[i].anim);
    173         if(end == LV_ANIM_PLAYTIME_INFINITE)
    174             return end;
    175         end += at->anim_dsc[i].start_time;
    176         if(end > playtime) {
    177             playtime = end;
    178         }
    179     }
    180 
    181     return playtime;
    182 }
    183 
    184 bool lv_anim_timeline_get_reverse(lv_anim_timeline_t * at)
    185 {
    186     LV_ASSERT_NULL(at);
    187     return at->reverse;
    188 }
    189 
    190 /**********************
    191  *   STATIC FUNCTIONS
    192  **********************/
    193 
    194 static void lv_anim_timeline_virtual_exec_cb(void * var, int32_t v)
    195 {
    196     LV_UNUSED(var);
    197     LV_UNUSED(v);
    198 }