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_disp.c (14368B)
1 /** 2 * @file lv_disp.c 3 * 4 */ 5 6 /********************* 7 * INCLUDES 8 *********************/ 9 #include "lv_disp.h" 10 #include "../misc/lv_math.h" 11 #include "../core/lv_refr.h" 12 13 /********************* 14 * DEFINES 15 *********************/ 16 17 /********************** 18 * TYPEDEFS 19 **********************/ 20 21 /********************** 22 * STATIC PROTOTYPES 23 **********************/ 24 25 static void scr_load_anim_start(lv_anim_t * a); 26 static void opa_scale_anim(void * obj, int32_t v); 27 static void set_x_anim(void * obj, int32_t v); 28 static void set_y_anim(void * obj, int32_t v); 29 static void scr_anim_ready(lv_anim_t * a); 30 static bool is_out_anim(lv_scr_load_anim_t a); 31 32 /********************** 33 * STATIC VARIABLES 34 **********************/ 35 36 /********************** 37 * MACROS 38 **********************/ 39 40 /********************** 41 * GLOBAL FUNCTIONS 42 **********************/ 43 44 /** 45 * Return with a pointer to the active screen 46 * @param disp pointer to display which active screen should be get. (NULL to use the default 47 * screen) 48 * @return pointer to the active screen object (loaded by 'lv_scr_load()') 49 */ 50 lv_obj_t * lv_disp_get_scr_act(lv_disp_t * disp) 51 { 52 if(!disp) disp = lv_disp_get_default(); 53 if(!disp) { 54 LV_LOG_WARN("no display registered to get its active screen"); 55 return NULL; 56 } 57 58 return disp->act_scr; 59 } 60 61 /** 62 * Return with a pointer to the previous screen. Only used during screen transitions. 63 * @param disp pointer to display which previous screen should be get. (NULL to use the default 64 * screen) 65 * @return pointer to the previous screen object or NULL if not used now 66 */ 67 lv_obj_t * lv_disp_get_scr_prev(lv_disp_t * disp) 68 { 69 if(!disp) disp = lv_disp_get_default(); 70 if(!disp) { 71 LV_LOG_WARN("no display registered to get its previous screen"); 72 return NULL; 73 } 74 75 return disp->prev_scr; 76 } 77 78 /** 79 * Make a screen active 80 * @param scr pointer to a screen 81 */ 82 void lv_disp_load_scr(lv_obj_t * scr) 83 { 84 lv_disp_t * d = lv_obj_get_disp(scr); 85 if(!d) return; /*Shouldn't happen, just to be sure*/ 86 87 lv_obj_t * old_scr = d->act_scr; 88 89 if(d->act_scr) lv_event_send(old_scr, LV_EVENT_SCREEN_UNLOAD_START, NULL); 90 if(d->act_scr) lv_event_send(scr, LV_EVENT_SCREEN_LOAD_START, NULL); 91 92 d->act_scr = scr; 93 94 if(d->act_scr) lv_event_send(scr, LV_EVENT_SCREEN_LOADED, NULL); 95 if(d->act_scr) lv_event_send(old_scr, LV_EVENT_SCREEN_UNLOADED, NULL); 96 97 lv_obj_invalidate(scr); 98 } 99 100 /** 101 * Return with the top layer. (Same on every screen and it is above the normal screen layer) 102 * @param disp pointer to display which top layer should be get. (NULL to use the default screen) 103 * @return pointer to the top layer object (transparent screen sized lv_obj) 104 */ 105 lv_obj_t * lv_disp_get_layer_top(lv_disp_t * disp) 106 { 107 if(!disp) disp = lv_disp_get_default(); 108 if(!disp) { 109 LV_LOG_WARN("lv_layer_top: no display registered to get its top layer"); 110 return NULL; 111 } 112 113 return disp->top_layer; 114 } 115 116 /** 117 * Return with the sys. layer. (Same on every screen and it is above the normal screen and the top 118 * layer) 119 * @param disp pointer to display which sys. layer should be retrieved. (NULL to use the default screen) 120 * @return pointer to the sys layer object (transparent screen sized lv_obj) 121 */ 122 lv_obj_t * lv_disp_get_layer_sys(lv_disp_t * disp) 123 { 124 if(!disp) disp = lv_disp_get_default(); 125 if(!disp) { 126 LV_LOG_WARN("lv_layer_sys: no display registered to get its sys. layer"); 127 return NULL; 128 } 129 130 return disp->sys_layer; 131 } 132 133 /** 134 * Set the theme of a display 135 * @param disp pointer to a display 136 */ 137 void lv_disp_set_theme(lv_disp_t * disp, lv_theme_t * th) 138 { 139 if(!disp) disp = lv_disp_get_default(); 140 if(!disp) { 141 LV_LOG_WARN("no display registered"); 142 return; 143 } 144 145 disp->theme = th; 146 147 if(disp->screen_cnt == 3 && 148 lv_obj_get_child_cnt(disp->screens[0]) == 0 && 149 lv_obj_get_child_cnt(disp->screens[1]) == 0 && 150 lv_obj_get_child_cnt(disp->screens[2]) == 0) { 151 lv_theme_apply(disp->screens[0]); 152 } 153 } 154 /** 155 * Get the theme of a display 156 * @param disp pointer to a display 157 * @return the display's theme (can be NULL) 158 */ 159 lv_theme_t * lv_disp_get_theme(lv_disp_t * disp) 160 { 161 if(disp == NULL) disp = lv_disp_get_default(); 162 return disp->theme; 163 } 164 165 /** 166 * Set the background color of a display 167 * @param disp pointer to a display 168 * @param color color of the background 169 */ 170 void lv_disp_set_bg_color(lv_disp_t * disp, lv_color_t color) 171 { 172 if(!disp) disp = lv_disp_get_default(); 173 if(!disp) { 174 LV_LOG_WARN("no display registered"); 175 return; 176 } 177 178 disp->bg_color = color; 179 180 lv_area_t a; 181 lv_area_set(&a, 0, 0, lv_disp_get_hor_res(disp) - 1, lv_disp_get_ver_res(disp) - 1); 182 _lv_inv_area(disp, &a); 183 184 } 185 186 /** 187 * Set the background image of a display 188 * @param disp pointer to a display 189 * @param img_src path to file or pointer to an `lv_img_dsc_t` variable 190 */ 191 void lv_disp_set_bg_image(lv_disp_t * disp, const void * img_src) 192 { 193 if(!disp) disp = lv_disp_get_default(); 194 if(!disp) { 195 LV_LOG_WARN("no display registered"); 196 return; 197 } 198 199 disp->bg_img = img_src; 200 201 lv_area_t a; 202 lv_area_set(&a, 0, 0, lv_disp_get_hor_res(disp) - 1, lv_disp_get_ver_res(disp) - 1); 203 _lv_inv_area(disp, &a); 204 } 205 206 /** 207 * Set opacity of the background 208 * @param disp pointer to a display 209 * @param opa opacity (0..255) 210 */ 211 void lv_disp_set_bg_opa(lv_disp_t * disp, lv_opa_t opa) 212 { 213 if(!disp) disp = lv_disp_get_default(); 214 if(!disp) { 215 LV_LOG_WARN("no display registered"); 216 return; 217 } 218 219 disp->bg_opa = opa; 220 221 lv_area_t a; 222 lv_area_set(&a, 0, 0, lv_disp_get_hor_res(disp) - 1, lv_disp_get_ver_res(disp) - 1); 223 _lv_inv_area(disp, &a); 224 } 225 226 /** 227 * Switch screen with animation 228 * @param scr pointer to the new screen to load 229 * @param anim_type type of the animation from `lv_scr_load_anim_t`, e.g. `LV_SCR_LOAD_ANIM_MOVE_LEFT` 230 * @param time time of the animation 231 * @param delay delay before the transition 232 * @param auto_del true: automatically delete the old screen 233 */ 234 void lv_scr_load_anim(lv_obj_t * new_scr, lv_scr_load_anim_t anim_type, uint32_t time, uint32_t delay, bool auto_del) 235 { 236 237 lv_disp_t * d = lv_obj_get_disp(new_scr); 238 lv_obj_t * act_scr = lv_scr_act(); 239 240 /*If an other screen load animation is in progress 241 *make target screen loaded immediately. */ 242 if(d->scr_to_load && act_scr != d->scr_to_load) { 243 lv_disp_load_scr(d->scr_to_load); 244 lv_anim_del(d->scr_to_load, NULL); 245 lv_obj_set_pos(d->scr_to_load, 0, 0); 246 lv_obj_remove_local_style_prop(d->scr_to_load, LV_STYLE_OPA, 0); 247 248 if(d->del_prev) { 249 lv_obj_del(act_scr); 250 } 251 act_scr = d->scr_to_load; 252 } 253 254 d->scr_to_load = new_scr; 255 256 if(d->prev_scr && d->del_prev) { 257 lv_obj_del(d->prev_scr); 258 d->prev_scr = NULL; 259 } 260 261 d->draw_prev_over_act = is_out_anim(anim_type); 262 d->del_prev = auto_del; 263 264 /*Be sure there is no other animation on the screens*/ 265 lv_anim_del(new_scr, NULL); 266 lv_anim_del(lv_scr_act(), NULL); 267 268 /*Be sure both screens are in a normal position*/ 269 lv_obj_set_pos(new_scr, 0, 0); 270 lv_obj_set_pos(lv_scr_act(), 0, 0); 271 lv_obj_remove_local_style_prop(new_scr, LV_STYLE_OPA, 0); 272 lv_obj_remove_local_style_prop(lv_scr_act(), LV_STYLE_OPA, 0); 273 274 lv_anim_t a_new; 275 lv_anim_init(&a_new); 276 lv_anim_set_var(&a_new, new_scr); 277 lv_anim_set_start_cb(&a_new, scr_load_anim_start); 278 lv_anim_set_ready_cb(&a_new, scr_anim_ready); 279 lv_anim_set_time(&a_new, time); 280 lv_anim_set_delay(&a_new, delay); 281 282 lv_anim_t a_old; 283 lv_anim_init(&a_old); 284 lv_anim_set_var(&a_old, d->act_scr); 285 lv_anim_set_time(&a_old, time); 286 lv_anim_set_delay(&a_old, delay); 287 288 switch(anim_type) { 289 case LV_SCR_LOAD_ANIM_NONE: 290 /*Create a dummy animation to apply the delay*/ 291 lv_anim_set_exec_cb(&a_new, set_x_anim); 292 lv_anim_set_values(&a_new, 0, 0); 293 break; 294 case LV_SCR_LOAD_ANIM_OVER_LEFT: 295 lv_anim_set_exec_cb(&a_new, set_x_anim); 296 lv_anim_set_values(&a_new, lv_disp_get_hor_res(d), 0); 297 break; 298 case LV_SCR_LOAD_ANIM_OVER_RIGHT: 299 lv_anim_set_exec_cb(&a_new, set_x_anim); 300 lv_anim_set_values(&a_new, -lv_disp_get_hor_res(d), 0); 301 break; 302 case LV_SCR_LOAD_ANIM_OVER_TOP: 303 lv_anim_set_exec_cb(&a_new, set_y_anim); 304 lv_anim_set_values(&a_new, lv_disp_get_ver_res(d), 0); 305 break; 306 case LV_SCR_LOAD_ANIM_OVER_BOTTOM: 307 lv_anim_set_exec_cb(&a_new, set_y_anim); 308 lv_anim_set_values(&a_new, -lv_disp_get_ver_res(d), 0); 309 break; 310 case LV_SCR_LOAD_ANIM_MOVE_LEFT: 311 lv_anim_set_exec_cb(&a_new, set_x_anim); 312 lv_anim_set_values(&a_new, lv_disp_get_hor_res(d), 0); 313 314 lv_anim_set_exec_cb(&a_old, set_x_anim); 315 lv_anim_set_values(&a_old, 0, -lv_disp_get_hor_res(d)); 316 break; 317 case LV_SCR_LOAD_ANIM_MOVE_RIGHT: 318 lv_anim_set_exec_cb(&a_new, set_x_anim); 319 lv_anim_set_values(&a_new, -lv_disp_get_hor_res(d), 0); 320 321 lv_anim_set_exec_cb(&a_old, set_x_anim); 322 lv_anim_set_values(&a_old, 0, lv_disp_get_hor_res(d)); 323 break; 324 case LV_SCR_LOAD_ANIM_MOVE_TOP: 325 lv_anim_set_exec_cb(&a_new, set_y_anim); 326 lv_anim_set_values(&a_new, lv_disp_get_ver_res(d), 0); 327 328 lv_anim_set_exec_cb(&a_old, set_y_anim); 329 lv_anim_set_values(&a_old, 0, -lv_disp_get_ver_res(d)); 330 break; 331 case LV_SCR_LOAD_ANIM_MOVE_BOTTOM: 332 lv_anim_set_exec_cb(&a_new, set_y_anim); 333 lv_anim_set_values(&a_new, -lv_disp_get_ver_res(d), 0); 334 335 lv_anim_set_exec_cb(&a_old, set_y_anim); 336 lv_anim_set_values(&a_old, 0, lv_disp_get_ver_res(d)); 337 break; 338 case LV_SCR_LOAD_ANIM_FADE_IN: 339 lv_anim_set_exec_cb(&a_new, opa_scale_anim); 340 lv_anim_set_values(&a_new, LV_OPA_TRANSP, LV_OPA_COVER); 341 break; 342 case LV_SCR_LOAD_ANIM_FADE_OUT: 343 lv_anim_set_exec_cb(&a_old, opa_scale_anim); 344 lv_anim_set_values(&a_old, LV_OPA_COVER, LV_OPA_TRANSP); 345 break; 346 case LV_SCR_LOAD_ANIM_OUT_LEFT: 347 lv_anim_set_exec_cb(&a_old, set_x_anim); 348 lv_anim_set_values(&a_old, 0, -lv_disp_get_hor_res(d)); 349 break; 350 case LV_SCR_LOAD_ANIM_OUT_RIGHT: 351 lv_anim_set_exec_cb(&a_old, set_x_anim); 352 lv_anim_set_values(&a_old, 0, lv_disp_get_hor_res(d)); 353 break; 354 case LV_SCR_LOAD_ANIM_OUT_TOP: 355 lv_anim_set_exec_cb(&a_old, set_y_anim); 356 lv_anim_set_values(&a_old, 0, -lv_disp_get_ver_res(d)); 357 break; 358 case LV_SCR_LOAD_ANIM_OUT_BOTTOM: 359 lv_anim_set_exec_cb(&a_old, set_y_anim); 360 lv_anim_set_values(&a_old, 0, lv_disp_get_ver_res(d)); 361 break; 362 } 363 364 lv_event_send(act_scr, LV_EVENT_SCREEN_UNLOAD_START, NULL); 365 366 lv_anim_start(&a_new); 367 lv_anim_start(&a_old); 368 369 } 370 371 /** 372 * Get elapsed time since last user activity on a display (e.g. click) 373 * @param disp pointer to a display (NULL to get the overall smallest inactivity) 374 * @return elapsed ticks (milliseconds) since the last activity 375 */ 376 uint32_t lv_disp_get_inactive_time(const lv_disp_t * disp) 377 { 378 if(disp) return lv_tick_elaps(disp->last_activity_time); 379 380 lv_disp_t * d; 381 uint32_t t = UINT32_MAX; 382 d = lv_disp_get_next(NULL); 383 while(d) { 384 uint32_t elaps = lv_tick_elaps(d->last_activity_time); 385 t = LV_MIN(t, elaps); 386 d = lv_disp_get_next(d); 387 } 388 389 return t; 390 } 391 392 /** 393 * Manually trigger an activity on a display 394 * @param disp pointer to a display (NULL to use the default display) 395 */ 396 void lv_disp_trig_activity(lv_disp_t * disp) 397 { 398 if(!disp) disp = lv_disp_get_default(); 399 if(!disp) { 400 LV_LOG_WARN("lv_disp_trig_activity: no display registered"); 401 return; 402 } 403 404 disp->last_activity_time = lv_tick_get(); 405 } 406 407 /** 408 * Clean any CPU cache that is related to the display. 409 * @param disp pointer to a display (NULL to use the default display) 410 */ 411 void lv_disp_clean_dcache(lv_disp_t * disp) 412 { 413 if(!disp) disp = lv_disp_get_default(); 414 if(!disp) { 415 LV_LOG_WARN("lv_disp_clean_dcache: no display registered"); 416 return; 417 } 418 419 if(disp->driver->clean_dcache_cb) 420 disp->driver->clean_dcache_cb(disp->driver); 421 } 422 423 /** 424 * Get a pointer to the screen refresher timer to 425 * modify its parameters with `lv_timer_...` functions. 426 * @param disp pointer to a display 427 * @return pointer to the display refresher timer. (NULL on error) 428 */ 429 lv_timer_t * _lv_disp_get_refr_timer(lv_disp_t * disp) 430 { 431 if(!disp) disp = lv_disp_get_default(); 432 if(!disp) { 433 LV_LOG_WARN("lv_disp_get_refr_timer: no display registered"); 434 return NULL; 435 } 436 437 return disp->refr_timer; 438 } 439 440 /********************** 441 * STATIC FUNCTIONS 442 **********************/ 443 444 static void scr_load_anim_start(lv_anim_t * a) 445 { 446 lv_disp_t * d = lv_obj_get_disp(a->var); 447 448 d->prev_scr = lv_scr_act(); 449 d->act_scr = a->var; 450 451 lv_event_send(d->act_scr, LV_EVENT_SCREEN_LOAD_START, NULL); 452 } 453 454 static void opa_scale_anim(void * obj, int32_t v) 455 { 456 lv_obj_set_style_opa(obj, v, 0); 457 } 458 459 static void set_x_anim(void * obj, int32_t v) 460 { 461 lv_obj_set_x(obj, v); 462 } 463 464 static void set_y_anim(void * obj, int32_t v) 465 { 466 lv_obj_set_y(obj, v); 467 } 468 469 static void scr_anim_ready(lv_anim_t * a) 470 { 471 lv_disp_t * d = lv_obj_get_disp(a->var); 472 473 lv_event_send(d->act_scr, LV_EVENT_SCREEN_LOADED, NULL); 474 lv_event_send(d->prev_scr, LV_EVENT_SCREEN_UNLOADED, NULL); 475 476 if(d->prev_scr && d->del_prev) lv_obj_del(d->prev_scr); 477 d->prev_scr = NULL; 478 d->draw_prev_over_act = false; 479 d->scr_to_load = NULL; 480 lv_obj_remove_local_style_prop(a->var, LV_STYLE_OPA, 0); 481 } 482 483 static bool is_out_anim(lv_scr_load_anim_t anim_type) 484 { 485 return anim_type == LV_SCR_LOAD_ANIM_FADE_OUT || 486 anim_type == LV_SCR_LOAD_ANIM_OUT_LEFT || 487 anim_type == LV_SCR_LOAD_ANIM_OUT_RIGHT || 488 anim_type == LV_SCR_LOAD_ANIM_OUT_TOP || 489 anim_type == LV_SCR_LOAD_ANIM_OUT_BOTTOM; 490 }