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 }