CARPLAY版本整理
This commit is contained in:
420
MXC_A27-PCB4.5-270S/lib/LittlevGL/lvgl/src/lv_core/lv_disp.c
Normal file
420
MXC_A27-PCB4.5-270S/lib/LittlevGL/lvgl/src/lv_core/lv_disp.c
Normal file
@ -0,0 +1,420 @@
|
||||
/**
|
||||
* @file lv_disp.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_disp.h"
|
||||
#include "../lv_misc/lv_math.h"
|
||||
#include "../lv_core/lv_refr.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
#if LV_USE_ANIMATION
|
||||
static void scr_load_anim_start(lv_anim_t * a);
|
||||
static void opa_scale_anim(lv_obj_t * obj, lv_anim_value_t v);
|
||||
static void scr_anim_ready(lv_anim_t * a);
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Return with a pointer to the active screen
|
||||
* @param disp pointer to display which active screen should be get. (NULL to use the default
|
||||
* screen)
|
||||
* @return pointer to the active screen object (loaded by 'lv_scr_load()')
|
||||
*/
|
||||
lv_obj_t * lv_disp_get_scr_act(lv_disp_t * disp)
|
||||
{
|
||||
if(!disp) disp = lv_disp_get_default();
|
||||
if(!disp) {
|
||||
LV_LOG_WARN("no display registered to get its active screen");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return disp->act_scr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return with a pointer to the previous screen. Only used during screen transitions.
|
||||
* @param disp pointer to display which previous screen should be get. (NULL to use the default
|
||||
* screen)
|
||||
* @return pointer to the previous screen object or NULL if not used now
|
||||
*/
|
||||
lv_obj_t * lv_disp_get_scr_prev(lv_disp_t * disp)
|
||||
{
|
||||
if(!disp) disp = lv_disp_get_default();
|
||||
if(!disp) {
|
||||
LV_LOG_WARN("no display registered to get its previous screen");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return disp->prev_scr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a screen active
|
||||
* @param scr pointer to a screen
|
||||
*/
|
||||
void lv_disp_load_scr(lv_obj_t * scr)
|
||||
{
|
||||
lv_disp_t * d = lv_obj_get_disp(scr);
|
||||
if(!d) return; /*Shouldn't happen, just to be sure*/
|
||||
d->act_scr = scr;
|
||||
|
||||
lv_obj_invalidate(scr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return with the top layer. (Same on every screen and it is above the normal screen layer)
|
||||
* @param disp pointer to display which top layer should be get. (NULL to use the default screen)
|
||||
* @return pointer to the top layer object (transparent screen sized lv_obj)
|
||||
*/
|
||||
lv_obj_t * lv_disp_get_layer_top(lv_disp_t * disp)
|
||||
{
|
||||
if(!disp) disp = lv_disp_get_default();
|
||||
if(!disp) {
|
||||
LV_LOG_WARN("lv_layer_top: no display registered to get its top layer");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return disp->top_layer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return with the sys. layer. (Same on every screen and it is above the normal screen and the top
|
||||
* layer)
|
||||
* @param disp pointer to display which sys. layer should be get. (NULL to use the default screen)
|
||||
* @return pointer to the sys layer object (transparent screen sized lv_obj)
|
||||
*/
|
||||
lv_obj_t * lv_disp_get_layer_sys(lv_disp_t * disp)
|
||||
{
|
||||
if(!disp) disp = lv_disp_get_default();
|
||||
if(!disp) {
|
||||
LV_LOG_WARN("lv_layer_sys: no display registered to get its sys. layer");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return disp->sys_layer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign a screen to a display.
|
||||
* @param disp pointer to a display where to assign the screen
|
||||
* @param scr pointer to a screen object to assign
|
||||
*/
|
||||
void lv_disp_assign_screen(lv_disp_t * disp, lv_obj_t * scr)
|
||||
{
|
||||
if(lv_obj_get_parent(scr) != NULL) {
|
||||
LV_LOG_WARN("lv_disp_assign_screen: try to assign a non-screen object");
|
||||
return;
|
||||
}
|
||||
|
||||
lv_disp_t * old_disp = lv_obj_get_disp(scr);
|
||||
|
||||
if(old_disp == disp) return;
|
||||
|
||||
_lv_ll_chg_list(&old_disp->scr_ll, &disp->scr_ll, scr, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the background color of a display
|
||||
* @param disp pointer to a display
|
||||
* @param color color of the background
|
||||
*/
|
||||
void lv_disp_set_bg_color(lv_disp_t * disp, lv_color_t color)
|
||||
{
|
||||
if(!disp) disp = lv_disp_get_default();
|
||||
if(!disp) {
|
||||
LV_LOG_WARN("no display registered");
|
||||
return;
|
||||
}
|
||||
|
||||
disp->bg_color = color;
|
||||
|
||||
lv_area_t a;
|
||||
lv_area_set(&a, 0, 0, lv_disp_get_hor_res(disp) - 1, lv_disp_get_ver_res(disp) - 1);
|
||||
_lv_inv_area(disp, &a);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the background image of a display
|
||||
* @param disp pointer to a display
|
||||
* @param img_src path to file or pointer to an `lv_img_dsc_t` variable
|
||||
*/
|
||||
void lv_disp_set_bg_image(lv_disp_t * disp, const void * img_src)
|
||||
{
|
||||
if(!disp) disp = lv_disp_get_default();
|
||||
if(!disp) {
|
||||
LV_LOG_WARN("no display registered");
|
||||
return;
|
||||
}
|
||||
|
||||
disp->bg_img = img_src;
|
||||
|
||||
lv_area_t a;
|
||||
lv_area_set(&a, 0, 0, lv_disp_get_hor_res(disp) - 1, lv_disp_get_ver_res(disp) - 1);
|
||||
_lv_inv_area(disp, &a);
|
||||
}
|
||||
|
||||
/**
|
||||
* Opacity of the background
|
||||
* @param disp pointer to a display
|
||||
* @param opa opacity (0..255)
|
||||
*/
|
||||
void lv_disp_set_bg_opa(lv_disp_t * disp, lv_opa_t opa)
|
||||
{
|
||||
if(!disp) disp = lv_disp_get_default();
|
||||
if(!disp) {
|
||||
LV_LOG_WARN("no display registered");
|
||||
return;
|
||||
}
|
||||
|
||||
disp->bg_opa = opa;
|
||||
|
||||
lv_area_t a;
|
||||
lv_area_set(&a, 0, 0, lv_disp_get_hor_res(disp) - 1, lv_disp_get_ver_res(disp) - 1);
|
||||
_lv_inv_area(disp, &a);
|
||||
}
|
||||
|
||||
#if LV_USE_ANIMATION
|
||||
|
||||
/**
|
||||
* Switch screen with animation
|
||||
* @param scr pointer to the new screen to load
|
||||
* @param anim_type type of the animation from `lv_scr_load_anim_t`. E.g. `LV_SCR_LOAD_ANIM_MOVE_LEFT`
|
||||
* @param time time of the animation
|
||||
* @param delay delay before the transition
|
||||
* @param auto_del true: automatically delete the old screen
|
||||
*/
|
||||
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)
|
||||
{
|
||||
lv_disp_t * d = lv_obj_get_disp(new_scr);
|
||||
lv_obj_t * act_scr = lv_scr_act();
|
||||
|
||||
if(d->del_prev && act_scr != d->scr_to_load && d->scr_to_load) {
|
||||
lv_obj_del(act_scr);
|
||||
lv_disp_load_scr(d->scr_to_load);
|
||||
lv_anim_del(d->scr_to_load, NULL);
|
||||
lv_obj_set_pos(d->scr_to_load, 0, 0);
|
||||
lv_style_remove_prop(lv_obj_get_local_style(d->scr_to_load, LV_OBJ_PART_MAIN), LV_STYLE_OPA_SCALE);
|
||||
|
||||
act_scr = d->scr_to_load;
|
||||
}
|
||||
|
||||
d->scr_to_load = new_scr;
|
||||
|
||||
if(d->prev_scr && d->del_prev) {
|
||||
lv_obj_del(d->prev_scr);
|
||||
d->prev_scr = NULL;
|
||||
}
|
||||
|
||||
d->del_prev = auto_del;
|
||||
|
||||
/*Be sure there is no other animation on the screens*/
|
||||
lv_anim_del(new_scr, NULL);
|
||||
lv_anim_del(lv_scr_act(), NULL);
|
||||
|
||||
/*Be sure both screens are in a normal position*/
|
||||
lv_obj_set_pos(new_scr, 0, 0);
|
||||
lv_obj_set_pos(lv_scr_act(), 0, 0);
|
||||
lv_style_remove_prop(lv_obj_get_local_style(new_scr, LV_OBJ_PART_MAIN), LV_STYLE_OPA_SCALE);
|
||||
lv_style_remove_prop(lv_obj_get_local_style(lv_scr_act(), LV_OBJ_PART_MAIN), LV_STYLE_OPA_SCALE);
|
||||
|
||||
lv_anim_t a_new;
|
||||
lv_anim_init(&a_new);
|
||||
lv_anim_set_var(&a_new, new_scr);
|
||||
lv_anim_set_start_cb(&a_new, scr_load_anim_start);
|
||||
lv_anim_set_ready_cb(&a_new, scr_anim_ready);
|
||||
lv_anim_set_time(&a_new, time);
|
||||
lv_anim_set_delay(&a_new, delay);
|
||||
|
||||
lv_anim_t a_old;
|
||||
lv_anim_init(&a_old);
|
||||
lv_anim_set_var(&a_old, d->act_scr);
|
||||
lv_anim_set_time(&a_old, time);
|
||||
lv_anim_set_delay(&a_old, delay);
|
||||
|
||||
switch(anim_type) {
|
||||
case LV_SCR_LOAD_ANIM_NONE:
|
||||
/* Create a dummy animation to apply the delay*/
|
||||
lv_anim_set_exec_cb(&a_new, (lv_anim_exec_xcb_t) lv_obj_set_x);
|
||||
lv_anim_set_values(&a_new, 0, 0);
|
||||
break;
|
||||
case LV_SCR_LOAD_ANIM_OVER_LEFT:
|
||||
lv_anim_set_exec_cb(&a_new, (lv_anim_exec_xcb_t) lv_obj_set_x);
|
||||
lv_anim_set_values(&a_new, lv_disp_get_hor_res(d), 0);
|
||||
break;
|
||||
case LV_SCR_LOAD_ANIM_OVER_RIGHT:
|
||||
lv_anim_set_exec_cb(&a_new, (lv_anim_exec_xcb_t) lv_obj_set_x);
|
||||
lv_anim_set_values(&a_new, -lv_disp_get_hor_res(d), 0);
|
||||
break;
|
||||
case LV_SCR_LOAD_ANIM_OVER_TOP:
|
||||
lv_anim_set_exec_cb(&a_new, (lv_anim_exec_xcb_t) lv_obj_set_y);
|
||||
lv_anim_set_values(&a_new, lv_disp_get_ver_res(d), 0);
|
||||
break;
|
||||
case LV_SCR_LOAD_ANIM_OVER_BOTTOM:
|
||||
lv_anim_set_exec_cb(&a_new, (lv_anim_exec_xcb_t) lv_obj_set_y);
|
||||
lv_anim_set_values(&a_new, -lv_disp_get_ver_res(d), 0);
|
||||
break;
|
||||
case LV_SCR_LOAD_ANIM_MOVE_LEFT:
|
||||
lv_anim_set_exec_cb(&a_new, (lv_anim_exec_xcb_t) lv_obj_set_x);
|
||||
lv_anim_set_values(&a_new, lv_disp_get_hor_res(d), 0);
|
||||
|
||||
lv_anim_set_exec_cb(&a_old, (lv_anim_exec_xcb_t) lv_obj_set_x);
|
||||
lv_anim_set_values(&a_old, 0, -lv_disp_get_hor_res(d));
|
||||
break;
|
||||
case LV_SCR_LOAD_ANIM_MOVE_RIGHT:
|
||||
lv_anim_set_exec_cb(&a_new, (lv_anim_exec_xcb_t) lv_obj_set_x);
|
||||
lv_anim_set_values(&a_new, -lv_disp_get_hor_res(d), 0);
|
||||
|
||||
lv_anim_set_exec_cb(&a_old, (lv_anim_exec_xcb_t) lv_obj_set_x);
|
||||
lv_anim_set_values(&a_old, 0, lv_disp_get_hor_res(d));
|
||||
break;
|
||||
case LV_SCR_LOAD_ANIM_MOVE_TOP:
|
||||
lv_anim_set_exec_cb(&a_new, (lv_anim_exec_xcb_t) lv_obj_set_y);
|
||||
lv_anim_set_values(&a_new, lv_disp_get_ver_res(d), 0);
|
||||
|
||||
lv_anim_set_exec_cb(&a_old, (lv_anim_exec_xcb_t) lv_obj_set_y);
|
||||
lv_anim_set_values(&a_old, 0, -lv_disp_get_ver_res(d));
|
||||
break;
|
||||
case LV_SCR_LOAD_ANIM_MOVE_BOTTOM:
|
||||
lv_anim_set_exec_cb(&a_new, (lv_anim_exec_xcb_t) lv_obj_set_y);
|
||||
lv_anim_set_values(&a_new, -lv_disp_get_ver_res(d), 0);
|
||||
|
||||
lv_anim_set_exec_cb(&a_old, (lv_anim_exec_xcb_t) lv_obj_set_y);
|
||||
lv_anim_set_values(&a_old, 0, lv_disp_get_ver_res(d));
|
||||
break;
|
||||
|
||||
case LV_SCR_LOAD_ANIM_FADE_ON:
|
||||
lv_anim_set_exec_cb(&a_new, (lv_anim_exec_xcb_t) opa_scale_anim);
|
||||
lv_anim_set_values(&a_new, LV_OPA_TRANSP, LV_OPA_COVER);
|
||||
break;
|
||||
}
|
||||
|
||||
lv_anim_start(&a_new);
|
||||
lv_anim_start(&a_old);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Get elapsed time since last user activity on a display (e.g. click)
|
||||
* @param disp pointer to an display (NULL to get the overall smallest inactivity)
|
||||
* @return elapsed ticks (milliseconds) since the last activity
|
||||
*/
|
||||
uint32_t lv_disp_get_inactive_time(const lv_disp_t * disp)
|
||||
{
|
||||
if(disp) return lv_tick_elaps(disp->last_activity_time);
|
||||
|
||||
lv_disp_t * d;
|
||||
uint32_t t = UINT32_MAX;
|
||||
d = lv_disp_get_next(NULL);
|
||||
while(d) {
|
||||
uint32_t elaps = lv_tick_elaps(d->last_activity_time);
|
||||
t = LV_MATH_MIN(t, elaps);
|
||||
d = lv_disp_get_next(d);
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
/**
|
||||
* Manually trigger an activity on a display
|
||||
* @param disp pointer to an display (NULL to use the default display)
|
||||
*/
|
||||
void lv_disp_trig_activity(lv_disp_t * disp)
|
||||
{
|
||||
if(!disp) disp = lv_disp_get_default();
|
||||
if(!disp) {
|
||||
LV_LOG_WARN("lv_disp_trig_activity: no display registered");
|
||||
return;
|
||||
}
|
||||
|
||||
disp->last_activity_time = lv_tick_get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean any CPU cache that is related to the display.
|
||||
* @param disp pointer to an display (NULL to use the default display)
|
||||
*/
|
||||
void lv_disp_clean_dcache(lv_disp_t * disp)
|
||||
{
|
||||
if(!disp) disp = lv_disp_get_default();
|
||||
if(!disp) {
|
||||
LV_LOG_WARN("lv_disp_clean_dcache: no display registered");
|
||||
return;
|
||||
}
|
||||
|
||||
if(disp->driver.clean_dcache_cb)
|
||||
disp->driver.clean_dcache_cb(&disp->driver);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a pointer to the screen refresher task to
|
||||
* modify its parameters with `lv_task_...` functions.
|
||||
* @param disp pointer to a display
|
||||
* @return pointer to the display refresher task. (NULL on error)
|
||||
*/
|
||||
lv_task_t * _lv_disp_get_refr_task(lv_disp_t * disp)
|
||||
{
|
||||
if(!disp) disp = lv_disp_get_default();
|
||||
if(!disp) {
|
||||
LV_LOG_WARN("lv_disp_get_refr_task: no display registered");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return disp->refr_task;
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
#if LV_USE_ANIMATION
|
||||
static void scr_load_anim_start(lv_anim_t * a)
|
||||
{
|
||||
lv_disp_t * d = lv_obj_get_disp(a->var);
|
||||
d->prev_scr = lv_scr_act();
|
||||
|
||||
lv_disp_load_scr(a->var);
|
||||
}
|
||||
|
||||
static void opa_scale_anim(lv_obj_t * obj, lv_anim_value_t v)
|
||||
{
|
||||
lv_obj_set_style_local_opa_scale(obj, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, v);
|
||||
}
|
||||
|
||||
static void scr_anim_ready(lv_anim_t * a)
|
||||
{
|
||||
lv_disp_t * d = lv_obj_get_disp(a->var);
|
||||
|
||||
if(d->prev_scr && d->del_prev) lv_obj_del(d->prev_scr);
|
||||
d->prev_scr = NULL;
|
||||
d->scr_to_load = NULL;
|
||||
lv_style_remove_prop(lv_obj_get_local_style(a->var, LV_OBJ_PART_MAIN), LV_STYLE_OPA_SCALE);
|
||||
}
|
||||
#endif
|
226
MXC_A27-PCB4.5-270S/lib/LittlevGL/lvgl/src/lv_core/lv_disp.h
Normal file
226
MXC_A27-PCB4.5-270S/lib/LittlevGL/lvgl/src/lv_core/lv_disp.h
Normal file
@ -0,0 +1,226 @@
|
||||
/**
|
||||
* @file lv_disp.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_DISP_H
|
||||
#define LV_DISP_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "../lv_hal/lv_hal.h"
|
||||
#include "lv_obj.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
typedef enum {
|
||||
LV_SCR_LOAD_ANIM_NONE,
|
||||
LV_SCR_LOAD_ANIM_OVER_LEFT,
|
||||
LV_SCR_LOAD_ANIM_OVER_RIGHT,
|
||||
LV_SCR_LOAD_ANIM_OVER_TOP,
|
||||
LV_SCR_LOAD_ANIM_OVER_BOTTOM,
|
||||
LV_SCR_LOAD_ANIM_MOVE_LEFT,
|
||||
LV_SCR_LOAD_ANIM_MOVE_RIGHT,
|
||||
LV_SCR_LOAD_ANIM_MOVE_TOP,
|
||||
LV_SCR_LOAD_ANIM_MOVE_BOTTOM,
|
||||
LV_SCR_LOAD_ANIM_FADE_ON,
|
||||
} lv_scr_load_anim_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Return with a pointer to the active screen
|
||||
* @param disp pointer to display which active screen should be get. (NULL to use the default
|
||||
* screen)
|
||||
* @return pointer to the active screen object (loaded by 'lv_scr_load()')
|
||||
*/
|
||||
lv_obj_t * lv_disp_get_scr_act(lv_disp_t * disp);
|
||||
|
||||
/**
|
||||
* Return with a pointer to the previous screen. Only used during screen transitions.
|
||||
* @param disp pointer to display which previous screen should be get. (NULL to use the default
|
||||
* screen)
|
||||
* @return pointer to the previous screen object or NULL if not used now
|
||||
*/
|
||||
lv_obj_t * lv_disp_get_scr_prev(lv_disp_t * disp);
|
||||
|
||||
/**
|
||||
* Make a screen active
|
||||
* @param scr pointer to a screen
|
||||
*/
|
||||
void lv_disp_load_scr(lv_obj_t * scr);
|
||||
|
||||
/**
|
||||
* Return with the top layer. (Same on every screen and it is above the normal screen layer)
|
||||
* @param disp pointer to display which top layer should be get. (NULL to use the default screen)
|
||||
* @return pointer to the top layer object (transparent screen sized lv_obj)
|
||||
*/
|
||||
lv_obj_t * lv_disp_get_layer_top(lv_disp_t * disp);
|
||||
|
||||
/**
|
||||
* Return with the sys. layer. (Same on every screen and it is above the normal screen and the top
|
||||
* layer)
|
||||
* @param disp pointer to display which sys. layer should be get. (NULL to use the default screen)
|
||||
* @return pointer to the sys layer object (transparent screen sized lv_obj)
|
||||
*/
|
||||
lv_obj_t * lv_disp_get_layer_sys(lv_disp_t * disp);
|
||||
|
||||
/**
|
||||
* Assign a screen to a display.
|
||||
* @param disp pointer to a display where to assign the screen
|
||||
* @param scr pointer to a screen object to assign
|
||||
*/
|
||||
void lv_disp_assign_screen(lv_disp_t * disp, lv_obj_t * scr);
|
||||
|
||||
/**
|
||||
* Set the background color of a display
|
||||
* @param disp pointer to a display
|
||||
* @param color color of the background
|
||||
*/
|
||||
void lv_disp_set_bg_color(lv_disp_t * disp, lv_color_t color);
|
||||
|
||||
/**
|
||||
* Set the background image of a display
|
||||
* @param disp pointer to a display
|
||||
* @param img_src path to file or pointer to an `lv_img_dsc_t` variable
|
||||
*/
|
||||
void lv_disp_set_bg_image(lv_disp_t * disp, const void * img_src);
|
||||
|
||||
/**
|
||||
* Opacity of the background
|
||||
* @param disp pointer to a display
|
||||
* @param opa opacity (0..255)
|
||||
*/
|
||||
void lv_disp_set_bg_opa(lv_disp_t * disp, lv_opa_t opa);
|
||||
|
||||
#if LV_USE_ANIMATION
|
||||
|
||||
/**
|
||||
* Switch screen with animation
|
||||
* @param scr pointer to the new screen to load
|
||||
* @param anim_type type of the animation from `lv_scr_load_anim_t`. E.g. `LV_SCR_LOAD_ANIM_MOVE_LEFT`
|
||||
* @param time time of the animation
|
||||
* @param delay delay before the transition
|
||||
* @param auto_del true: automatically delete the old screen
|
||||
*/
|
||||
void lv_scr_load_anim(lv_obj_t * scr, lv_scr_load_anim_t anim_type, uint32_t time, uint32_t delay, bool auto_del);
|
||||
|
||||
#endif
|
||||
/**
|
||||
* Get elapsed time since last user activity on a display (e.g. click)
|
||||
* @param disp pointer to an display (NULL to get the overall smallest inactivity)
|
||||
* @return elapsed ticks (milliseconds) since the last activity
|
||||
*/
|
||||
uint32_t lv_disp_get_inactive_time(const lv_disp_t * disp);
|
||||
|
||||
/**
|
||||
* Manually trigger an activity on a display
|
||||
* @param disp pointer to an display (NULL to use the default display)
|
||||
*/
|
||||
void lv_disp_trig_activity(lv_disp_t * disp);
|
||||
|
||||
/**
|
||||
* Clean any CPU cache that is related to the display.
|
||||
* @param disp pointer to an display (NULL to use the default display)
|
||||
*/
|
||||
void lv_disp_clean_dcache(lv_disp_t * disp);
|
||||
|
||||
/**
|
||||
* Get a pointer to the screen refresher task to
|
||||
* modify its parameters with `lv_task_...` functions.
|
||||
* @param disp pointer to a display
|
||||
* @return pointer to the display refresher task. (NULL on error)
|
||||
*/
|
||||
lv_task_t * _lv_disp_get_refr_task(lv_disp_t * disp);
|
||||
|
||||
/*------------------------------------------------
|
||||
* To improve backward compatibility
|
||||
* Recommended only if you have one display
|
||||
*------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Get the active screen of the default display
|
||||
* @return pointer to the active screen
|
||||
*/
|
||||
static inline lv_obj_t * lv_scr_act(void)
|
||||
{
|
||||
return lv_disp_get_scr_act(lv_disp_get_default());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the top layer of the default display
|
||||
* @return pointer to the top layer
|
||||
*/
|
||||
static inline lv_obj_t * lv_layer_top(void)
|
||||
{
|
||||
return lv_disp_get_layer_top(lv_disp_get_default());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the active screen of the default display
|
||||
* @return pointer to the sys layer
|
||||
*/
|
||||
static inline lv_obj_t * lv_layer_sys(void)
|
||||
{
|
||||
return lv_disp_get_layer_sys(lv_disp_get_default());
|
||||
}
|
||||
|
||||
static inline void lv_scr_load(lv_obj_t * scr)
|
||||
{
|
||||
lv_disp_load_scr(scr);
|
||||
}
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/*------------------------------------------------
|
||||
* To improve backward compatibility
|
||||
* Recommended only if you have one display
|
||||
*------------------------------------------------*/
|
||||
|
||||
#ifndef LV_HOR_RES
|
||||
/**
|
||||
* The horizontal resolution of the currently active display.
|
||||
*/
|
||||
#define LV_HOR_RES lv_disp_get_hor_res(lv_disp_get_default())
|
||||
#endif
|
||||
|
||||
#ifndef LV_VER_RES
|
||||
/**
|
||||
* The vertical resolution of the currently active display.
|
||||
*/
|
||||
#define LV_VER_RES lv_disp_get_ver_res(lv_disp_get_default())
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Same as Android's DIP. (Different name is chosen to avoid mistype between LV_DPI and LV_DIP)
|
||||
* 1 dip is 1 px on a 160 DPI screen
|
||||
* 1 dip is 2 px on a 320 DPI screen
|
||||
* https://stackoverflow.com/questions/2025282/what-is-the-difference-between-px-dip-dp-and-sp
|
||||
*/
|
||||
#define LV_DPX(n) (n == 0 ? 0 :LV_MATH_MAX((( lv_disp_get_dpi(NULL) * (n) + 80) / 160), 1)) /*+80 for rounding*/
|
||||
|
||||
static inline lv_coord_t lv_dpx(lv_coord_t n)
|
||||
{
|
||||
return LV_DPX(n);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_DISP_H*/
|
531
MXC_A27-PCB4.5-270S/lib/LittlevGL/lvgl/src/lv_core/lv_group.c
Normal file
531
MXC_A27-PCB4.5-270S/lib/LittlevGL/lvgl/src/lv_core/lv_group.c
Normal file
@ -0,0 +1,531 @@
|
||||
/**
|
||||
* @file lv_group.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_group.h"
|
||||
#if LV_USE_GROUP != 0
|
||||
#include <stddef.h>
|
||||
#include "../lv_misc/lv_debug.h"
|
||||
#include "../lv_themes/lv_theme.h"
|
||||
#include "../lv_misc/lv_gc.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static void focus_next_core(lv_group_t * group, void * (*begin)(const lv_ll_t *),
|
||||
void * (*move)(const lv_ll_t *, const void *));
|
||||
static void lv_group_refocus(lv_group_t * g);
|
||||
static void obj_to_foreground(lv_obj_t * obj);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Init. the group module
|
||||
*/
|
||||
void _lv_group_init(void)
|
||||
{
|
||||
_lv_ll_init(&LV_GC_ROOT(_lv_group_ll), sizeof(lv_group_t));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new object group
|
||||
* @return pointer to the new object group
|
||||
*/
|
||||
lv_group_t * lv_group_create(void)
|
||||
{
|
||||
lv_group_t * group = _lv_ll_ins_head(&LV_GC_ROOT(_lv_group_ll));
|
||||
LV_ASSERT_MEM(group);
|
||||
if(group == NULL) return NULL;
|
||||
_lv_ll_init(&group->obj_ll, sizeof(lv_obj_t *));
|
||||
|
||||
group->obj_focus = NULL;
|
||||
group->frozen = 0;
|
||||
group->focus_cb = NULL;
|
||||
group->click_focus = 1;
|
||||
group->editing = 0;
|
||||
group->refocus_policy = LV_GROUP_REFOCUS_POLICY_PREV;
|
||||
group->wrap = 1;
|
||||
|
||||
#if LV_USE_USER_DATA
|
||||
_lv_memset_00(&group->user_data, sizeof(lv_group_user_data_t));
|
||||
#endif
|
||||
|
||||
return group;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a group object
|
||||
* @param group pointer to a group
|
||||
*/
|
||||
void lv_group_del(lv_group_t * group)
|
||||
{
|
||||
/*Defocus the currently focused object*/
|
||||
if(group->obj_focus != NULL) {
|
||||
(*group->obj_focus)->signal_cb(*group->obj_focus, LV_SIGNAL_DEFOCUS, NULL);
|
||||
lv_obj_invalidate(*group->obj_focus);
|
||||
}
|
||||
|
||||
/*Remove the objects from the group*/
|
||||
lv_obj_t ** obj;
|
||||
_LV_LL_READ(group->obj_ll, obj) {
|
||||
(*obj)->group_p = NULL;
|
||||
}
|
||||
|
||||
_lv_ll_clear(&(group->obj_ll));
|
||||
_lv_ll_remove(&LV_GC_ROOT(_lv_group_ll), group);
|
||||
lv_mem_free(group);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an object to a group
|
||||
* @param group pointer to a group
|
||||
* @param obj pointer to an object to add
|
||||
*/
|
||||
void lv_group_add_obj(lv_group_t * group, lv_obj_t * obj)
|
||||
{
|
||||
if(group == NULL) return;
|
||||
/*Do not add the object twice*/
|
||||
lv_obj_t ** obj_i;
|
||||
_LV_LL_READ(group->obj_ll, obj_i) {
|
||||
if((*obj_i) == obj) {
|
||||
LV_LOG_INFO("lv_group_add_obj: the object is already added to this group");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*If the object is already in a group and focused then defocus it*/
|
||||
if(obj->group_p) {
|
||||
if(lv_obj_is_focused(obj)) {
|
||||
lv_group_refocus(obj->group_p);
|
||||
|
||||
LV_LOG_INFO("lv_group_add_obj: assign object to an other group");
|
||||
}
|
||||
}
|
||||
|
||||
obj->group_p = group;
|
||||
lv_obj_t ** next = _lv_ll_ins_tail(&group->obj_ll);
|
||||
LV_ASSERT_MEM(next);
|
||||
if(next == NULL) return;
|
||||
*next = obj;
|
||||
|
||||
/* If the head and the tail is equal then there is only one object in the linked list.
|
||||
* In this case automatically activate it*/
|
||||
if(_lv_ll_get_head(&group->obj_ll) == next) {
|
||||
lv_group_refocus(group);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an object from its group
|
||||
* @param obj pointer to an object to remove
|
||||
*/
|
||||
void lv_group_remove_obj(lv_obj_t * obj)
|
||||
{
|
||||
lv_group_t * g = obj->group_p;
|
||||
if(g == NULL) return;
|
||||
|
||||
/*Focus on the next object*/
|
||||
if(*g->obj_focus == obj) {
|
||||
if(g->frozen) g->frozen = 0;
|
||||
|
||||
/*If this is the only object in the group then focus to nothing.*/
|
||||
if(_lv_ll_get_head(&g->obj_ll) == g->obj_focus && _lv_ll_get_tail(&g->obj_ll) == g->obj_focus) {
|
||||
(*g->obj_focus)->signal_cb(*g->obj_focus, LV_SIGNAL_DEFOCUS, NULL);
|
||||
}
|
||||
/*If there more objects in the group then focus to the next/prev object*/
|
||||
else {
|
||||
lv_group_refocus(g);
|
||||
}
|
||||
}
|
||||
|
||||
/* If the focuses object is still the same then it was the only object in the group but it will
|
||||
* be deleted. Set the `obj_focus` to NULL to get back to the initial state of the group with
|
||||
* zero objects*/
|
||||
if(*g->obj_focus == obj) {
|
||||
g->obj_focus = NULL;
|
||||
}
|
||||
|
||||
/*Search the object and remove it from its group */
|
||||
lv_obj_t ** i;
|
||||
_LV_LL_READ(g->obj_ll, i) {
|
||||
if(*i == obj) {
|
||||
_lv_ll_remove(&g->obj_ll, i);
|
||||
lv_mem_free(i);
|
||||
obj->group_p = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all objects from a group
|
||||
* @param group pointer to a group
|
||||
*/
|
||||
void lv_group_remove_all_objs(lv_group_t * group)
|
||||
{
|
||||
/*Defocus the currently focused object*/
|
||||
if(group->obj_focus != NULL) {
|
||||
(*group->obj_focus)->signal_cb(*group->obj_focus, LV_SIGNAL_DEFOCUS, NULL);
|
||||
lv_obj_invalidate(*group->obj_focus);
|
||||
group->obj_focus = NULL;
|
||||
}
|
||||
|
||||
/*Remove the objects from the group*/
|
||||
lv_obj_t ** obj;
|
||||
_LV_LL_READ(group->obj_ll, obj) {
|
||||
(*obj)->group_p = NULL;
|
||||
}
|
||||
|
||||
_lv_ll_clear(&(group->obj_ll));
|
||||
}
|
||||
|
||||
/**
|
||||
* Focus on an object (defocus the current)
|
||||
* @param obj pointer to an object to focus on
|
||||
*/
|
||||
void lv_group_focus_obj(lv_obj_t * obj)
|
||||
{
|
||||
if(obj == NULL) return;
|
||||
lv_group_t * g = obj->group_p;
|
||||
if(g == NULL) return;
|
||||
|
||||
if(g->frozen != 0) return;
|
||||
|
||||
if(g->obj_focus != NULL && obj == *g->obj_focus) return;
|
||||
|
||||
/*On defocus edit mode must be leaved*/
|
||||
lv_group_set_editing(g, false);
|
||||
|
||||
lv_obj_t ** i;
|
||||
_LV_LL_READ(g->obj_ll, i) {
|
||||
if(*i == obj) {
|
||||
if(g->obj_focus != NULL) {
|
||||
(*g->obj_focus)->signal_cb(*g->obj_focus, LV_SIGNAL_DEFOCUS, NULL);
|
||||
lv_res_t res = lv_event_send(*g->obj_focus, LV_EVENT_DEFOCUSED, NULL);
|
||||
if(res != LV_RES_OK) return;
|
||||
lv_obj_invalidate(*g->obj_focus);
|
||||
}
|
||||
|
||||
g->obj_focus = i;
|
||||
|
||||
if(g->obj_focus != NULL) {
|
||||
(*g->obj_focus)->signal_cb(*g->obj_focus, LV_SIGNAL_FOCUS, NULL);
|
||||
if(g->focus_cb) g->focus_cb(g);
|
||||
lv_res_t res = lv_event_send(*g->obj_focus, LV_EVENT_FOCUSED, NULL);
|
||||
if(res != LV_RES_OK) return;
|
||||
lv_obj_invalidate(*g->obj_focus);
|
||||
|
||||
/*If the object or its parent has `top == true` bring it to the foreground*/
|
||||
obj_to_foreground(*g->obj_focus);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Focus the next object in a group (defocus the current)
|
||||
* @param group pointer to a group
|
||||
*/
|
||||
void lv_group_focus_next(lv_group_t * group)
|
||||
{
|
||||
focus_next_core(group, _lv_ll_get_head, _lv_ll_get_next);
|
||||
}
|
||||
|
||||
/**
|
||||
* Focus the previous object in a group (defocus the current)
|
||||
* @param group pointer to a group
|
||||
*/
|
||||
void lv_group_focus_prev(lv_group_t * group)
|
||||
{
|
||||
focus_next_core(group, _lv_ll_get_tail, _lv_ll_get_prev);
|
||||
}
|
||||
|
||||
/**
|
||||
* Do not let to change the focus from the current object
|
||||
* @param group pointer to a group
|
||||
* @param en true: freeze, false: release freezing (normal mode)
|
||||
*/
|
||||
void lv_group_focus_freeze(lv_group_t * group, bool en)
|
||||
{
|
||||
if(en == false)
|
||||
group->frozen = 0;
|
||||
else
|
||||
group->frozen = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a control character to the focuses object of a group
|
||||
* @param group pointer to a group
|
||||
* @param c a character (use LV_KEY_.. to navigate)
|
||||
* @return result of focused object in group.
|
||||
*/
|
||||
lv_res_t lv_group_send_data(lv_group_t * group, uint32_t c)
|
||||
{
|
||||
lv_obj_t * act = lv_group_get_focused(group);
|
||||
if(act == NULL) return LV_RES_OK;
|
||||
|
||||
lv_res_t res;
|
||||
|
||||
res = act->signal_cb(act, LV_SIGNAL_CONTROL, &c);
|
||||
if(res != LV_RES_OK) return res;
|
||||
|
||||
res = lv_event_send(act, LV_EVENT_KEY, &c);
|
||||
if(res != LV_RES_OK) return res;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a function for a group which will be called when a new object is focused
|
||||
* @param group pointer to a group
|
||||
* @param focus_cb the call back function or NULL if unused
|
||||
*/
|
||||
void lv_group_set_focus_cb(lv_group_t * group, lv_group_focus_cb_t focus_cb)
|
||||
{
|
||||
group->focus_cb = focus_cb;
|
||||
}
|
||||
|
||||
/**
|
||||
* Manually set the current mode (edit or navigate).
|
||||
* @param group pointer to group
|
||||
* @param edit: true: edit mode; false: navigate mode
|
||||
*/
|
||||
void lv_group_set_editing(lv_group_t * group, bool edit)
|
||||
{
|
||||
if(group == NULL) return;
|
||||
uint8_t en_val = edit ? 1 : 0;
|
||||
|
||||
if(en_val == group->editing) return; /*Do not set the same mode again*/
|
||||
|
||||
group->editing = en_val;
|
||||
lv_obj_t * focused = lv_group_get_focused(group);
|
||||
|
||||
if(focused) {
|
||||
focused->signal_cb(focused, LV_SIGNAL_FOCUS, NULL); /*Focus again to properly leave/open edit/navigate mode*/
|
||||
lv_res_t res = lv_event_send(*group->obj_focus, LV_EVENT_FOCUSED, NULL);
|
||||
if(res != LV_RES_OK) return;
|
||||
|
||||
lv_obj_invalidate(focused);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the `click_focus` attribute. If enabled then the object will be focused then it is clicked.
|
||||
* @param group pointer to group
|
||||
* @param en: true: enable `click_focus`
|
||||
*/
|
||||
void lv_group_set_click_focus(lv_group_t * group, bool en)
|
||||
{
|
||||
group->click_focus = en ? 1 : 0;
|
||||
}
|
||||
|
||||
void lv_group_set_refocus_policy(lv_group_t * group, lv_group_refocus_policy_t policy)
|
||||
{
|
||||
group->refocus_policy = policy & 0x01;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether focus next/prev will allow wrapping from first->last or last->first.
|
||||
* @param group pointer to group
|
||||
* @param en: true: enable `wrap`
|
||||
*/
|
||||
void lv_group_set_wrap(lv_group_t * group, bool en)
|
||||
{
|
||||
group->wrap = en ? 1 : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the focused object or NULL if there isn't one
|
||||
* @param group pointer to a group
|
||||
* @return pointer to the focused object
|
||||
*/
|
||||
lv_obj_t * lv_group_get_focused(const lv_group_t * group)
|
||||
{
|
||||
if(!group) return NULL;
|
||||
if(group->obj_focus == NULL) return NULL;
|
||||
|
||||
return *group->obj_focus;
|
||||
}
|
||||
|
||||
#if LV_USE_USER_DATA
|
||||
/**
|
||||
* Get a pointer to the group's user data
|
||||
* @param group pointer to an group
|
||||
* @return pointer to the user data
|
||||
*/
|
||||
lv_group_user_data_t * lv_group_get_user_data(lv_group_t * group)
|
||||
{
|
||||
return &group->user_data;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Get the focus callback function of a group
|
||||
* @param group pointer to a group
|
||||
* @return the call back function or NULL if not set
|
||||
*/
|
||||
lv_group_focus_cb_t lv_group_get_focus_cb(const lv_group_t * group)
|
||||
{
|
||||
if(!group) return NULL;
|
||||
return group->focus_cb;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current mode (edit or navigate).
|
||||
* @param group pointer to group
|
||||
* @return true: edit mode; false: navigate mode
|
||||
*/
|
||||
bool lv_group_get_editing(const lv_group_t * group)
|
||||
{
|
||||
if(!group) return false;
|
||||
return group->editing ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the `click_focus` attribute.
|
||||
* @param group pointer to group
|
||||
* @return true: `click_focus` is enabled; false: disabled
|
||||
*/
|
||||
bool lv_group_get_click_focus(const lv_group_t * group)
|
||||
{
|
||||
if(!group) return false;
|
||||
return group->click_focus ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get whether focus next/prev will allow wrapping from first->last or last->first object.
|
||||
* @param group pointer to group
|
||||
* @param en: true: wrapping enabled; false: wrapping disabled
|
||||
*/
|
||||
bool lv_group_get_wrap(lv_group_t * group)
|
||||
{
|
||||
if(!group) return false;
|
||||
return group->wrap ? true : false;
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static void lv_group_refocus(lv_group_t * g)
|
||||
{
|
||||
/*Refocus must temporarily allow wrapping to work correctly*/
|
||||
uint8_t temp_wrap = g->wrap;
|
||||
g->wrap = 1;
|
||||
|
||||
if(g->refocus_policy == LV_GROUP_REFOCUS_POLICY_NEXT)
|
||||
lv_group_focus_next(g);
|
||||
else if(g->refocus_policy == LV_GROUP_REFOCUS_POLICY_PREV)
|
||||
lv_group_focus_prev(g);
|
||||
/*Restore wrap property*/
|
||||
g->wrap = temp_wrap;
|
||||
}
|
||||
|
||||
static void focus_next_core(lv_group_t * group, void * (*begin)(const lv_ll_t *),
|
||||
void * (*move)(const lv_ll_t *, const void *))
|
||||
{
|
||||
if(group->frozen) return;
|
||||
|
||||
lv_obj_t ** obj_next = group->obj_focus;
|
||||
lv_obj_t ** obj_sentinel = NULL;
|
||||
bool can_move = true;
|
||||
bool can_begin = true;
|
||||
|
||||
for(;;) {
|
||||
if(obj_next == NULL) {
|
||||
if(group->wrap || obj_sentinel == NULL) {
|
||||
if(!can_begin) return;
|
||||
obj_next = begin(&group->obj_ll);
|
||||
can_move = false;
|
||||
can_begin = false;
|
||||
}
|
||||
else {
|
||||
/*Currently focused object is the last/first in the group, keep it that way*/
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if(obj_sentinel == NULL) {
|
||||
obj_sentinel = obj_next;
|
||||
if(obj_sentinel == NULL) return; /*Group is empty*/
|
||||
}
|
||||
|
||||
if(can_move) {
|
||||
obj_next = move(&group->obj_ll, obj_next);
|
||||
|
||||
/*Give up if we walked the entire list and haven't found another visible object*/
|
||||
if(obj_next == obj_sentinel) return;
|
||||
}
|
||||
|
||||
can_move = true;
|
||||
|
||||
if(obj_next == NULL) continue;
|
||||
if(lv_obj_get_state(*obj_next, LV_OBJ_PART_MAIN) & LV_STATE_DISABLED) continue;
|
||||
|
||||
/*Hidden and disabled objects don't receive focus*/
|
||||
if(!lv_obj_get_hidden(*obj_next)) break;
|
||||
}
|
||||
|
||||
if(obj_next == group->obj_focus) return; /*There's only one visible object and it's already focused*/
|
||||
|
||||
if(group->obj_focus) {
|
||||
(*group->obj_focus)->signal_cb(*group->obj_focus, LV_SIGNAL_DEFOCUS, NULL);
|
||||
lv_res_t res = lv_event_send(*group->obj_focus, LV_EVENT_DEFOCUSED, NULL);
|
||||
if(res != LV_RES_OK) return;
|
||||
lv_obj_invalidate(*group->obj_focus);
|
||||
}
|
||||
|
||||
group->obj_focus = obj_next;
|
||||
|
||||
(*group->obj_focus)->signal_cb(*group->obj_focus, LV_SIGNAL_FOCUS, NULL);
|
||||
lv_res_t res = lv_event_send(*group->obj_focus, LV_EVENT_FOCUSED, NULL);
|
||||
if(res != LV_RES_OK) return;
|
||||
|
||||
/*If the object or its parent has `top == true` bring it to the foreground*/
|
||||
obj_to_foreground(*group->obj_focus);
|
||||
|
||||
lv_obj_invalidate(*group->obj_focus);
|
||||
|
||||
if(group->focus_cb) group->focus_cb(group);
|
||||
}
|
||||
|
||||
static void obj_to_foreground(lv_obj_t * obj)
|
||||
{
|
||||
/*Search for 'top' attribute*/
|
||||
lv_obj_t * i = obj;
|
||||
lv_obj_t * last_top = NULL;
|
||||
while(i != NULL) {
|
||||
if(i->top != 0) last_top = i;
|
||||
i = lv_obj_get_parent(i);
|
||||
}
|
||||
|
||||
if(last_top != NULL) {
|
||||
/*Move the last_top object to the foreground*/
|
||||
lv_obj_move_foreground(last_top);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /*LV_USE_GROUP != 0*/
|
241
MXC_A27-PCB4.5-270S/lib/LittlevGL/lvgl/src/lv_core/lv_group.h
Normal file
241
MXC_A27-PCB4.5-270S/lib/LittlevGL/lvgl/src/lv_core/lv_group.h
Normal file
@ -0,0 +1,241 @@
|
||||
/**
|
||||
* @file lv_group.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_GROUP_H
|
||||
#define LV_GROUP_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "lv_obj.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
/*Predefined keys to control the focused object via lv_group_send(group, c)*/
|
||||
/*For compatibility in signal function define the keys regardless to `LV_USE_GROUP`*/
|
||||
|
||||
enum {
|
||||
LV_KEY_UP = 17, /*0x11*/
|
||||
LV_KEY_DOWN = 18, /*0x12*/
|
||||
LV_KEY_RIGHT = 19, /*0x13*/
|
||||
LV_KEY_LEFT = 20, /*0x14*/
|
||||
LV_KEY_ESC = 27, /*0x1B*/
|
||||
LV_KEY_DEL = 127, /*0x7F*/
|
||||
LV_KEY_BACKSPACE = 8, /*0x08*/
|
||||
LV_KEY_ENTER = 10, /*0x0A, '\n'*/
|
||||
LV_KEY_NEXT = 9, /*0x09, '\t'*/
|
||||
LV_KEY_PREV = 11, /*0x0B, '*/
|
||||
LV_KEY_HOME = 2, /*0x02, STX*/
|
||||
LV_KEY_END = 3, /*0x03, ETX*/
|
||||
};
|
||||
typedef uint8_t lv_key_t;
|
||||
|
||||
#if LV_USE_GROUP != 0
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
struct _lv_group_t;
|
||||
|
||||
typedef void (*lv_group_style_mod_cb_t)(struct _lv_group_t *, lv_style_t *);
|
||||
typedef void (*lv_group_focus_cb_t)(struct _lv_group_t *);
|
||||
|
||||
/**
|
||||
* Groups can be used to logically hold objects so that they can be individually focused.
|
||||
* They are NOT for laying out objects on a screen (try `lv_cont` for that).
|
||||
*/
|
||||
typedef struct _lv_group_t {
|
||||
lv_ll_t obj_ll; /**< Linked list to store the objects in the group */
|
||||
lv_obj_t ** obj_focus; /**< The object in focus*/
|
||||
|
||||
lv_group_focus_cb_t focus_cb; /**< A function to call when a new object is focused (optional)*/
|
||||
#if LV_USE_USER_DATA
|
||||
lv_group_user_data_t user_data;
|
||||
#endif
|
||||
|
||||
uint8_t frozen : 1; /**< 1: can't focus to new object*/
|
||||
uint8_t editing : 1; /**< 1: Edit mode, 0: Navigate mode*/
|
||||
uint8_t click_focus : 1; /**< 1: If an object in a group is clicked by an indev then it will be
|
||||
focused */
|
||||
uint8_t refocus_policy : 1; /**< 1: Focus prev if focused on deletion. 0: Focus next if focused on
|
||||
deletion.*/
|
||||
uint8_t wrap : 1; /**< 1: Focus next/prev can wrap at end of list. 0: Focus next/prev stops at end
|
||||
of list.*/
|
||||
} lv_group_t;
|
||||
|
||||
enum { LV_GROUP_REFOCUS_POLICY_NEXT = 0, LV_GROUP_REFOCUS_POLICY_PREV = 1 };
|
||||
typedef uint8_t lv_group_refocus_policy_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Init. the group module
|
||||
* @remarks Internal function, do not call directly.
|
||||
*/
|
||||
void _lv_group_init(void);
|
||||
|
||||
/**
|
||||
* Create a new object group
|
||||
* @return pointer to the new object group
|
||||
*/
|
||||
lv_group_t * lv_group_create(void);
|
||||
|
||||
/**
|
||||
* Delete a group object
|
||||
* @param group pointer to a group
|
||||
*/
|
||||
void lv_group_del(lv_group_t * group);
|
||||
|
||||
/**
|
||||
* Add an object to a group
|
||||
* @param group pointer to a group
|
||||
* @param obj pointer to an object to add
|
||||
*/
|
||||
void lv_group_add_obj(lv_group_t * group, lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Remove an object from its group
|
||||
* @param obj pointer to an object to remove
|
||||
*/
|
||||
void lv_group_remove_obj(lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Remove all objects from a group
|
||||
* @param group pointer to a group
|
||||
*/
|
||||
void lv_group_remove_all_objs(lv_group_t * group);
|
||||
|
||||
/**
|
||||
* Focus on an object (defocus the current)
|
||||
* @param obj pointer to an object to focus on
|
||||
*/
|
||||
void lv_group_focus_obj(lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Focus the next object in a group (defocus the current)
|
||||
* @param group pointer to a group
|
||||
*/
|
||||
void lv_group_focus_next(lv_group_t * group);
|
||||
|
||||
/**
|
||||
* Focus the previous object in a group (defocus the current)
|
||||
* @param group pointer to a group
|
||||
*/
|
||||
void lv_group_focus_prev(lv_group_t * group);
|
||||
|
||||
/**
|
||||
* Do not let to change the focus from the current object
|
||||
* @param group pointer to a group
|
||||
* @param en true: freeze, false: release freezing (normal mode)
|
||||
*/
|
||||
void lv_group_focus_freeze(lv_group_t * group, bool en);
|
||||
|
||||
/**
|
||||
* Send a control character to the focuses object of a group
|
||||
* @param group pointer to a group
|
||||
* @param c a character (use LV_KEY_.. to navigate)
|
||||
* @return result of focused object in group.
|
||||
*/
|
||||
lv_res_t lv_group_send_data(lv_group_t * group, uint32_t c);
|
||||
|
||||
/**
|
||||
* Set a function for a group which will be called when a new object is focused
|
||||
* @param group pointer to a group
|
||||
* @param focus_cb the call back function or NULL if unused
|
||||
*/
|
||||
void lv_group_set_focus_cb(lv_group_t * group, lv_group_focus_cb_t focus_cb);
|
||||
|
||||
/**
|
||||
* Set whether the next or previous item in a group is focused if the currently focused obj is
|
||||
* deleted.
|
||||
* @param group pointer to a group
|
||||
* @param new refocus policy enum
|
||||
*/
|
||||
void lv_group_set_refocus_policy(lv_group_t * group, lv_group_refocus_policy_t policy);
|
||||
|
||||
/**
|
||||
* Manually set the current mode (edit or navigate).
|
||||
* @param group pointer to group
|
||||
* @param edit: true: edit mode; false: navigate mode
|
||||
*/
|
||||
void lv_group_set_editing(lv_group_t * group, bool edit);
|
||||
|
||||
/**
|
||||
* Set the `click_focus` attribute. If enabled then the object will be focused then it is clicked.
|
||||
* @param group pointer to group
|
||||
* @param en: true: enable `click_focus`
|
||||
*/
|
||||
void lv_group_set_click_focus(lv_group_t * group, bool en);
|
||||
|
||||
/**
|
||||
* Set whether focus next/prev will allow wrapping from first->last or last->first object.
|
||||
* @param group pointer to group
|
||||
* @param en: true: wrapping enabled; false: wrapping disabled
|
||||
*/
|
||||
void lv_group_set_wrap(lv_group_t * group, bool en);
|
||||
|
||||
/**
|
||||
* Get the focused object or NULL if there isn't one
|
||||
* @param group pointer to a group
|
||||
* @return pointer to the focused object
|
||||
*/
|
||||
lv_obj_t * lv_group_get_focused(const lv_group_t * group);
|
||||
|
||||
#if LV_USE_USER_DATA
|
||||
/**
|
||||
* Get a pointer to the group's user data
|
||||
* @param group pointer to an group
|
||||
* @return pointer to the user data
|
||||
*/
|
||||
lv_group_user_data_t * lv_group_get_user_data(lv_group_t * group);
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Get the focus callback function of a group
|
||||
* @param group pointer to a group
|
||||
* @return the call back function or NULL if not set
|
||||
*/
|
||||
lv_group_focus_cb_t lv_group_get_focus_cb(const lv_group_t * group);
|
||||
|
||||
/**
|
||||
* Get the current mode (edit or navigate).
|
||||
* @param group pointer to group
|
||||
* @return true: edit mode; false: navigate mode
|
||||
*/
|
||||
bool lv_group_get_editing(const lv_group_t * group);
|
||||
|
||||
/**
|
||||
* Get the `click_focus` attribute.
|
||||
* @param group pointer to group
|
||||
* @return true: `click_focus` is enabled; false: disabled
|
||||
*/
|
||||
bool lv_group_get_click_focus(const lv_group_t * group);
|
||||
|
||||
/**
|
||||
* Get whether focus next/prev will allow wrapping from first->last or last->first object.
|
||||
* @param group pointer to group
|
||||
* @param en: true: wrapping enabled; false: wrapping disabled
|
||||
*/
|
||||
bool lv_group_get_wrap(lv_group_t * group);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_GROUP != 0*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_GROUP_H*/
|
1583
MXC_A27-PCB4.5-270S/lib/LittlevGL/lvgl/src/lv_core/lv_indev.c
Normal file
1583
MXC_A27-PCB4.5-270S/lib/LittlevGL/lvgl/src/lv_core/lv_indev.c
Normal file
File diff suppressed because it is too large
Load Diff
183
MXC_A27-PCB4.5-270S/lib/LittlevGL/lvgl/src/lv_core/lv_indev.h
Normal file
183
MXC_A27-PCB4.5-270S/lib/LittlevGL/lvgl/src/lv_core/lv_indev.h
Normal file
@ -0,0 +1,183 @@
|
||||
/**
|
||||
* @file lv_indev.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_INDEV_H
|
||||
#define LV_INDEV_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_obj.h"
|
||||
#include "../lv_hal/lv_hal_indev.h"
|
||||
#include "../lv_core/lv_group.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Initialize the display input device subsystem
|
||||
*/
|
||||
void _lv_indev_init(void);
|
||||
|
||||
/**
|
||||
* Called periodically to read the input devices
|
||||
* @param task pointer to the task itself
|
||||
*/
|
||||
void _lv_indev_read_task(lv_task_t * task);
|
||||
|
||||
/**
|
||||
* Get the currently processed input device. Can be used in action functions too.
|
||||
* @return pointer to the currently processed input device or NULL if no input device processing
|
||||
* right now
|
||||
*/
|
||||
lv_indev_t * lv_indev_get_act(void);
|
||||
|
||||
/**
|
||||
* Get the type of an input device
|
||||
* @param indev pointer to an input device
|
||||
* @return the type of the input device from `lv_hal_indev_type_t` (`LV_INDEV_TYPE_...`)
|
||||
*/
|
||||
lv_indev_type_t lv_indev_get_type(const lv_indev_t * indev);
|
||||
|
||||
/**
|
||||
* Reset one or all input devices
|
||||
* @param indev pointer to an input device to reset or NULL to reset all of them
|
||||
* @param obj pointer to an object which triggers the reset.
|
||||
*/
|
||||
void lv_indev_reset(lv_indev_t * indev, lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Reset the long press state of an input device
|
||||
* @param indev_proc pointer to an input device
|
||||
*/
|
||||
void lv_indev_reset_long_press(lv_indev_t * indev);
|
||||
|
||||
/**
|
||||
* Enable or disable an input devices
|
||||
* @param indev pointer to an input device
|
||||
* @param en true: enable; false: disable
|
||||
*/
|
||||
void lv_indev_enable(lv_indev_t * indev, bool en);
|
||||
|
||||
/**
|
||||
* Set a cursor for a pointer input device (for LV_INPUT_TYPE_POINTER and LV_INPUT_TYPE_BUTTON)
|
||||
* @param indev pointer to an input device
|
||||
* @param cur_obj pointer to an object to be used as cursor
|
||||
*/
|
||||
void lv_indev_set_cursor(lv_indev_t * indev, lv_obj_t * cur_obj);
|
||||
|
||||
#if LV_USE_GROUP
|
||||
/**
|
||||
* Set a destination group for a keypad input device (for LV_INDEV_TYPE_KEYPAD)
|
||||
* @param indev pointer to an input device
|
||||
* @param group point to a group
|
||||
*/
|
||||
void lv_indev_set_group(lv_indev_t * indev, lv_group_t * group);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Set the an array of points for LV_INDEV_TYPE_BUTTON.
|
||||
* These points will be assigned to the buttons to press a specific point on the screen
|
||||
* @param indev pointer to an input device
|
||||
* @param group point to a group
|
||||
*/
|
||||
void lv_indev_set_button_points(lv_indev_t * indev, const lv_point_t points[]);
|
||||
|
||||
/**
|
||||
* Get the last point of an input device (for LV_INDEV_TYPE_POINTER and LV_INDEV_TYPE_BUTTON)
|
||||
* @param indev pointer to an input device
|
||||
* @param point pointer to a point to store the result
|
||||
*/
|
||||
void lv_indev_get_point(const lv_indev_t * indev, lv_point_t * point);
|
||||
|
||||
/**
|
||||
* Get the current gesture direct
|
||||
* @param indev pointer to an input device
|
||||
* @return current gesture direct
|
||||
*/
|
||||
lv_gesture_dir_t lv_indev_get_gesture_dir(const lv_indev_t * indev);
|
||||
|
||||
/**
|
||||
* Get the last pressed key of an input device (for LV_INDEV_TYPE_KEYPAD)
|
||||
* @param indev pointer to an input device
|
||||
* @return the last pressed key (0 on error)
|
||||
*/
|
||||
uint32_t lv_indev_get_key(const lv_indev_t * indev);
|
||||
|
||||
/**
|
||||
* Check if there is dragging with an input device or not (for LV_INDEV_TYPE_POINTER and
|
||||
* LV_INDEV_TYPE_BUTTON)
|
||||
* @param indev pointer to an input device
|
||||
* @return true: drag is in progress
|
||||
*/
|
||||
bool lv_indev_is_dragging(const lv_indev_t * indev);
|
||||
|
||||
/**
|
||||
* Get the vector of dragging of an input device (for LV_INDEV_TYPE_POINTER and
|
||||
* LV_INDEV_TYPE_BUTTON)
|
||||
* @param indev pointer to an input device
|
||||
* @param point pointer to a point to store the vector
|
||||
*/
|
||||
void lv_indev_get_vect(const lv_indev_t * indev, lv_point_t * point);
|
||||
|
||||
/**
|
||||
* Manually finish dragging.
|
||||
* `LV_SIGNAL_DRAG_END` and `LV_EVENT_DRAG_END` will be sent.
|
||||
* @param indev pointer to an input device
|
||||
* @return `LV_RES_INV` if the object being dragged was deleted. Else `LV_RES_OK`.
|
||||
*/
|
||||
lv_res_t lv_indev_finish_drag(lv_indev_t * indev);
|
||||
|
||||
/**
|
||||
* Do nothing until the next release
|
||||
* @param indev pointer to an input device
|
||||
*/
|
||||
void lv_indev_wait_release(lv_indev_t * indev);
|
||||
|
||||
/**
|
||||
* Gets a pointer to the currently active object in indev proc functions.
|
||||
* NULL if no object is currently being handled or if groups aren't used.
|
||||
* @return pointer to currently active object
|
||||
*/
|
||||
lv_obj_t * lv_indev_get_obj_act(void);
|
||||
|
||||
/**
|
||||
* Search the most top, clickable object by a point
|
||||
* @param obj pointer to a start object, typically the screen
|
||||
* @param point pointer to a point for searching the most top child
|
||||
* @return pointer to the found object or NULL if there was no suitable object
|
||||
*/
|
||||
lv_obj_t * lv_indev_search_obj(lv_obj_t * obj, lv_point_t * point);
|
||||
|
||||
/**
|
||||
* Get a pointer to the indev read task to
|
||||
* modify its parameters with `lv_task_...` functions.
|
||||
* @param indev pointer to an inout device
|
||||
* @return pointer to the indev read refresher task. (NULL on error)
|
||||
*/
|
||||
lv_task_t * lv_indev_get_read_task(lv_disp_t * indev);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_INDEV_H*/
|
4838
MXC_A27-PCB4.5-270S/lib/LittlevGL/lvgl/src/lv_core/lv_obj.c
Normal file
4838
MXC_A27-PCB4.5-270S/lib/LittlevGL/lvgl/src/lv_core/lv_obj.c
Normal file
File diff suppressed because it is too large
Load Diff
1528
MXC_A27-PCB4.5-270S/lib/LittlevGL/lvgl/src/lv_core/lv_obj.h
Normal file
1528
MXC_A27-PCB4.5-270S/lib/LittlevGL/lvgl/src/lv_core/lv_obj.h
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,270 @@
|
||||
|
||||
/**
|
||||
* @file lv_obj_style_dec.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_OBJ_STYLE_DEC_H
|
||||
#define LV_OBJ_STYLE_DEC_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**
|
||||
* Macro to declare the most important style set/get API functions.
|
||||
*
|
||||
* Get the value of a style property from an object in the object's current state
|
||||
* -----------------------------------------------------------------------------
|
||||
* - Get the value of a style property from an object in the object's current state.
|
||||
* - Transition animation is taken into account.
|
||||
* - If the property is not set in the object's styles check the parent(s) if the property can be inherited
|
||||
* - If still not found return a default value.
|
||||
* - For example:
|
||||
* `lv_style_int_t w = lv_obj_get_style_border_width(btn1, LV_BTN_PART_MAIN);`
|
||||
*
|
||||
* Set a local style property for an object in a given state
|
||||
* ---------------------------------------------------------
|
||||
* - For example:
|
||||
* `lv_obj_set_style_local_border_width(btn1, LV_BTN_PART_MAIN, LV_STATE_PRESSED, 2);`
|
||||
*
|
||||
* Get the value from a style in a given state
|
||||
* -------------------------------------------
|
||||
* - The same rules applies to the return value then for "lv_obj_get_style_local_...()" above
|
||||
* - For example
|
||||
* `int16_t weight = lv_style_get_border_width(&style1, LV_STATE_PRESSED, &result);`
|
||||
* `if(weight > 0) ...the property is found and loaded into result...`
|
||||
|
||||
* Set a value in a style in a given state
|
||||
* ---------------------------------------
|
||||
* - For example
|
||||
* `lv_style_set_border_width(&style1, LV_STATE_PRESSED, 2);`
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define _OBJ_GET_STYLE(prop_name, func_name, value_type, style_type) \
|
||||
static inline value_type lv_obj_get_style_##func_name(const lv_obj_t * obj, uint8_t part) \
|
||||
{ \
|
||||
return (value_type)_lv_obj_get_style##style_type(obj, part, LV_STYLE_##prop_name); \
|
||||
}
|
||||
#else
|
||||
#define _OBJ_GET_STYLE(prop_name, func_name, value_type, style_type) \
|
||||
static inline value_type lv_obj_get_style_##func_name(const lv_obj_t * obj, uint8_t part) \
|
||||
{ \
|
||||
return _lv_obj_get_style##style_type(obj, part, LV_STYLE_##prop_name); \
|
||||
}
|
||||
#endif
|
||||
|
||||
#define _OBJ_SET_STYLE_LOCAL(prop_name, func_name, value_type, style_type) \
|
||||
static inline void lv_obj_set_style_local_##func_name(lv_obj_t * obj, uint8_t part, lv_state_t state, value_type value) \
|
||||
{ \
|
||||
_lv_obj_set_style_local##style_type(obj, part, LV_STYLE_##prop_name | (state << LV_STYLE_STATE_POS), value); \
|
||||
}
|
||||
|
||||
#define _OBJ_SET_STYLE(prop_name, func_name, value_type, style_type) \
|
||||
static inline void lv_style_set_##func_name(lv_style_t * style, lv_state_t state, value_type value) \
|
||||
{ \
|
||||
_lv_style_set##style_type(style, LV_STYLE_##prop_name | (state << LV_STYLE_STATE_POS), value); \
|
||||
}
|
||||
|
||||
#define _LV_OBJ_STYLE_SET_GET_DECLARE(prop_name, func_name, value_type, style_type) \
|
||||
_OBJ_GET_STYLE(prop_name, func_name, value_type, style_type) \
|
||||
_OBJ_SET_STYLE_LOCAL(prop_name, func_name, value_type, style_type) \
|
||||
_OBJ_SET_STYLE(prop_name, func_name, value_type, style_type)
|
||||
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(RADIUS, radius, lv_style_int_t, _int)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(CLIP_CORNER, clip_corner, bool, _int)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(SIZE, size, lv_style_int_t, _int)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(TRANSFORM_WIDTH, transform_width, lv_style_int_t, _int)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(TRANSFORM_HEIGHT, transform_height, lv_style_int_t, _int)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(TRANSFORM_ANGLE, transform_angle, lv_style_int_t, _int)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(TRANSFORM_ZOOM, transform_zoom, lv_style_int_t, _int)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(OPA_SCALE, opa_scale, lv_opa_t, _opa)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(PAD_TOP, pad_top, lv_style_int_t, _int)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(PAD_BOTTOM, pad_bottom, lv_style_int_t, _int)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(PAD_LEFT, pad_left, lv_style_int_t, _int)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(PAD_RIGHT, pad_right, lv_style_int_t, _int)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(PAD_INNER, pad_inner, lv_style_int_t, _int)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(MARGIN_TOP, margin_top, lv_style_int_t, _int)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(MARGIN_BOTTOM, margin_bottom, lv_style_int_t, _int)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(MARGIN_LEFT, margin_left, lv_style_int_t, _int)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(MARGIN_RIGHT, margin_right, lv_style_int_t, _int)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(BG_BLEND_MODE, bg_blend_mode, lv_blend_mode_t, _int)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(BG_MAIN_STOP, bg_main_stop, lv_style_int_t, _int)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(BG_GRAD_STOP, bg_grad_stop, lv_style_int_t, _int)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(BG_GRAD_DIR, bg_grad_dir, lv_grad_dir_t, _int)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(BG_COLOR, bg_color, lv_color_t, _color)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(BG_GRAD_COLOR, bg_grad_color, lv_color_t, _color)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(BG_OPA, bg_opa, lv_opa_t, _opa)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(BORDER_WIDTH, border_width, lv_style_int_t, _int)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(BORDER_SIDE, border_side, lv_border_side_t, _int)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(BORDER_BLEND_MODE, border_blend_mode, lv_blend_mode_t, _int)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(BORDER_POST, border_post, bool, _int)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(BORDER_COLOR, border_color, lv_color_t, _color)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(BORDER_OPA, border_opa, lv_opa_t, _opa)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(OUTLINE_WIDTH, outline_width, lv_style_int_t, _int)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(OUTLINE_PAD, outline_pad, lv_style_int_t, _int)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(OUTLINE_BLEND_MODE, outline_blend_mode, lv_blend_mode_t, _int)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(OUTLINE_COLOR, outline_color, lv_color_t, _color)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(OUTLINE_OPA, outline_opa, lv_opa_t, _opa)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(SHADOW_WIDTH, shadow_width, lv_style_int_t, _int)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(SHADOW_OFS_X, shadow_ofs_x, lv_style_int_t, _int)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(SHADOW_OFS_Y, shadow_ofs_y, lv_style_int_t, _int)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(SHADOW_SPREAD, shadow_spread, lv_style_int_t, _int)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(SHADOW_BLEND_MODE, shadow_blend_mode, lv_blend_mode_t, _int)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(SHADOW_COLOR, shadow_color, lv_color_t, _color)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(SHADOW_OPA, shadow_opa, lv_opa_t, _opa)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(PATTERN_REPEAT, pattern_repeat, bool, _int)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(PATTERN_BLEND_MODE, pattern_blend_mode, lv_blend_mode_t, _int)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(PATTERN_RECOLOR, pattern_recolor, lv_color_t, _color)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(PATTERN_OPA, pattern_opa, lv_opa_t, _opa)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(PATTERN_RECOLOR_OPA, pattern_recolor_opa, lv_opa_t, _opa)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(PATTERN_IMAGE, pattern_image, const void *, _ptr)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(VALUE_LETTER_SPACE, value_letter_space, lv_style_int_t, _int)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(VALUE_LINE_SPACE, value_line_space, lv_style_int_t, _int)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(VALUE_BLEND_MODE, value_blend_mode, lv_blend_mode_t, _int)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(VALUE_OFS_X, value_ofs_x, lv_style_int_t, _int)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(VALUE_OFS_Y, value_ofs_y, lv_style_int_t, _int)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(VALUE_ALIGN, value_align, lv_align_t, _int)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(VALUE_COLOR, value_color, lv_color_t, _color)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(VALUE_OPA, value_opa, lv_opa_t, _opa)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(VALUE_FONT, value_font, const lv_font_t *, _ptr)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(VALUE_STR, value_str, const char *, _ptr)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(TEXT_LETTER_SPACE, text_letter_space, lv_style_int_t, _int)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(TEXT_LINE_SPACE, text_line_space, lv_style_int_t, _int)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(TEXT_DECOR, text_decor, lv_text_decor_t, _int)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(TEXT_BLEND_MODE, text_blend_mode, lv_blend_mode_t, _int)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(TEXT_COLOR, text_color, lv_color_t, _color)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(TEXT_SEL_COLOR, text_sel_color, lv_color_t, _color)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(TEXT_SEL_BG_COLOR, text_sel_bg_color, lv_color_t, _color)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(TEXT_OPA, text_opa, lv_opa_t, _opa)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(TEXT_FONT, text_font, const lv_font_t *, _ptr)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(LINE_WIDTH, line_width, lv_style_int_t, _int)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(LINE_BLEND_MODE, line_blend_mode, lv_blend_mode_t, _int)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(LINE_DASH_WIDTH, line_dash_width, lv_style_int_t, _int)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(LINE_DASH_GAP, line_dash_gap, lv_style_int_t, _int)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(LINE_ROUNDED, line_rounded, bool, _int)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(LINE_COLOR, line_color, lv_color_t, _color)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(LINE_OPA, line_opa, lv_opa_t, _opa)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(IMAGE_BLEND_MODE, image_blend_mode, lv_blend_mode_t, _int)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(IMAGE_RECOLOR, image_recolor, lv_color_t, _color)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(IMAGE_OPA, image_opa, lv_opa_t, _opa)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(IMAGE_RECOLOR_OPA, image_recolor_opa, lv_opa_t, _opa)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(TRANSITION_TIME, transition_time, lv_style_int_t, _int)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(TRANSITION_DELAY, transition_delay, lv_style_int_t, _int)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(TRANSITION_PROP_1, transition_prop_1, lv_style_int_t, _int)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(TRANSITION_PROP_2, transition_prop_2, lv_style_int_t, _int)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(TRANSITION_PROP_3, transition_prop_3, lv_style_int_t, _int)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(TRANSITION_PROP_4, transition_prop_4, lv_style_int_t, _int)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(TRANSITION_PROP_5, transition_prop_5, lv_style_int_t, _int)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(TRANSITION_PROP_6, transition_prop_6, lv_style_int_t, _int)
|
||||
#if LV_USE_ANIMATION
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(TRANSITION_PATH, transition_path, const lv_anim_path_t *, _ptr)
|
||||
#else
|
||||
/*For compatibility*/
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(TRANSITION_PATH, transition_path, const void *, _ptr)
|
||||
#endif
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(SCALE_WIDTH, scale_width, lv_style_int_t, _int)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(SCALE_BORDER_WIDTH, scale_border_width, lv_style_int_t, _int)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(SCALE_END_BORDER_WIDTH, scale_end_border_width, lv_style_int_t, _int)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(SCALE_END_LINE_WIDTH, scale_end_line_width, lv_style_int_t, _int)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(SCALE_GRAD_COLOR, scale_grad_color, lv_color_t, _color)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(SCALE_END_COLOR, scale_end_color, lv_color_t, _color)
|
||||
|
||||
#undef _LV_OBJ_STYLE_SET_GET_DECLARE
|
||||
#undef _OBJ_SET_STYLE_LOCAL
|
||||
#undef _OBJ_SET_STYLE
|
||||
#undef _OBJ_GET_STYLE
|
||||
|
||||
static inline void lv_obj_set_style_local_pad_all(lv_obj_t * obj, uint8_t part, lv_state_t state, lv_style_int_t value)
|
||||
{
|
||||
lv_obj_set_style_local_pad_top(obj, part, state, value);
|
||||
lv_obj_set_style_local_pad_bottom(obj, part, state, value);
|
||||
lv_obj_set_style_local_pad_left(obj, part, state, value);
|
||||
lv_obj_set_style_local_pad_right(obj, part, state, value);
|
||||
}
|
||||
|
||||
static inline void lv_style_set_pad_all(lv_style_t * style, lv_state_t state, lv_style_int_t value)
|
||||
{
|
||||
lv_style_set_pad_top(style, state, value);
|
||||
lv_style_set_pad_bottom(style, state, value);
|
||||
lv_style_set_pad_left(style, state, value);
|
||||
lv_style_set_pad_right(style, state, value);
|
||||
}
|
||||
|
||||
static inline void lv_obj_set_style_local_pad_hor(lv_obj_t * obj, uint8_t part, lv_state_t state, lv_style_int_t value)
|
||||
{
|
||||
lv_obj_set_style_local_pad_left(obj, part, state, value);
|
||||
lv_obj_set_style_local_pad_right(obj, part, state, value);
|
||||
}
|
||||
|
||||
static inline void lv_style_set_pad_hor(lv_style_t * style, lv_state_t state, lv_style_int_t value)
|
||||
{
|
||||
lv_style_set_pad_left(style, state, value);
|
||||
lv_style_set_pad_right(style, state, value);
|
||||
}
|
||||
|
||||
static inline void lv_obj_set_style_local_pad_ver(lv_obj_t * obj, uint8_t part, lv_state_t state, lv_style_int_t value)
|
||||
{
|
||||
lv_obj_set_style_local_pad_top(obj, part, state, value);
|
||||
lv_obj_set_style_local_pad_bottom(obj, part, state, value);
|
||||
}
|
||||
|
||||
static inline void lv_style_set_pad_ver(lv_style_t * style, lv_state_t state, lv_style_int_t value)
|
||||
{
|
||||
lv_style_set_pad_top(style, state, value);
|
||||
lv_style_set_pad_bottom(style, state, value);
|
||||
}
|
||||
|
||||
static inline void lv_obj_set_style_local_margin_all(lv_obj_t * obj, uint8_t part, lv_state_t state,
|
||||
lv_style_int_t value)
|
||||
{
|
||||
lv_obj_set_style_local_margin_top(obj, part, state, value);
|
||||
lv_obj_set_style_local_margin_bottom(obj, part, state, value);
|
||||
lv_obj_set_style_local_margin_left(obj, part, state, value);
|
||||
lv_obj_set_style_local_margin_right(obj, part, state, value);
|
||||
}
|
||||
|
||||
static inline void lv_style_set_margin_all(lv_style_t * style, lv_state_t state, lv_style_int_t value)
|
||||
{
|
||||
lv_style_set_margin_top(style, state, value);
|
||||
lv_style_set_margin_bottom(style, state, value);
|
||||
lv_style_set_margin_left(style, state, value);
|
||||
lv_style_set_margin_right(style, state, value);
|
||||
}
|
||||
|
||||
static inline void lv_obj_set_style_local_margin_hor(lv_obj_t * obj, uint8_t part, lv_state_t state,
|
||||
lv_style_int_t value)
|
||||
{
|
||||
lv_obj_set_style_local_margin_left(obj, part, state, value);
|
||||
lv_obj_set_style_local_margin_right(obj, part, state, value);
|
||||
}
|
||||
|
||||
static inline void lv_style_set_margin_hor(lv_style_t * style, lv_state_t state, lv_style_int_t value)
|
||||
{
|
||||
lv_style_set_margin_left(style, state, value);
|
||||
lv_style_set_margin_right(style, state, value);
|
||||
}
|
||||
|
||||
static inline void lv_obj_set_style_local_margin_ver(lv_obj_t * obj, uint8_t part, lv_state_t state,
|
||||
lv_style_int_t value)
|
||||
{
|
||||
lv_obj_set_style_local_margin_top(obj, part, state, value);
|
||||
lv_obj_set_style_local_margin_bottom(obj, part, state, value);
|
||||
}
|
||||
|
||||
static inline void lv_style_set_margin_ver(lv_style_t * style, lv_state_t state, lv_style_int_t value)
|
||||
{
|
||||
lv_style_set_margin_top(style, state, value);
|
||||
lv_style_set_margin_bottom(style, state, value);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_OBJ_STYLE_DEC_H*/
|
982
MXC_A27-PCB4.5-270S/lib/LittlevGL/lvgl/src/lv_core/lv_refr.c
Normal file
982
MXC_A27-PCB4.5-270S/lib/LittlevGL/lvgl/src/lv_core/lv_refr.c
Normal file
@ -0,0 +1,982 @@
|
||||
/**
|
||||
* @file lv_refr.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include <stddef.h>
|
||||
#include "lv_refr.h"
|
||||
#include "lv_disp.h"
|
||||
#include "../lv_hal/lv_hal_tick.h"
|
||||
#include "../lv_hal/lv_hal_disp.h"
|
||||
#include "../lv_misc/lv_task.h"
|
||||
#include "../lv_misc/lv_mem.h"
|
||||
#include "../lv_misc/lv_math.h"
|
||||
#include "../lv_misc/lv_gc.h"
|
||||
#include "../lv_draw/lv_draw.h"
|
||||
#include "../lv_font/lv_font_fmt_txt.h"
|
||||
#include "../lv_gpu/lv_gpu_stm32_dma2d.h"
|
||||
|
||||
#if LV_USE_PERF_MONITOR
|
||||
#include "../lv_widgets/lv_label.h"
|
||||
#endif
|
||||
|
||||
#include "vg_driver.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
/* Draw translucent random colored areas on the invalidated (redrawn) areas*/
|
||||
#define MASK_AREA_DEBUG 0
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static void lv_refr_join_area(void);
|
||||
static void lv_refr_areas(void);
|
||||
static void lv_refr_area(const lv_area_t * area_p);
|
||||
static void lv_refr_area_part(const lv_area_t * area_p);
|
||||
static lv_obj_t * lv_refr_get_top_obj(const lv_area_t * area_p, lv_obj_t * obj);
|
||||
static void lv_refr_obj_and_children(lv_obj_t * top_p, const lv_area_t * mask_p);
|
||||
static void lv_refr_obj(lv_obj_t * obj, const lv_area_t * mask_ori_p);
|
||||
static void lv_refr_vdb_flush(void);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
static uint32_t px_num;
|
||||
static lv_disp_t * disp_refr; /*Display being refreshed*/
|
||||
#if LV_USE_PERF_MONITOR
|
||||
static uint32_t fps_sum_cnt;
|
||||
static uint32_t fps_sum_all;
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Initialize the screen refresh subsystem
|
||||
*/
|
||||
void _lv_refr_init(void)
|
||||
{
|
||||
/*Nothing to do*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Redraw the invalidated areas now.
|
||||
* Normally the redrawing is periodically executed in `lv_task_handler` but a long blocking process
|
||||
* can prevent the call of `lv_task_handler`. In this case if the GUI is updated in the process
|
||||
* (e.g. progress bar) this function can be called when the screen should be updated.
|
||||
* @param disp pointer to display to refresh. NULL to refresh all displays.
|
||||
*/
|
||||
void lv_refr_now(lv_disp_t * disp)
|
||||
{
|
||||
#if LV_USE_ANIMATION
|
||||
lv_anim_refr_now();
|
||||
#endif
|
||||
|
||||
if(disp) {
|
||||
_lv_disp_refr_task(disp->refr_task);
|
||||
}
|
||||
else {
|
||||
lv_disp_t * d;
|
||||
d = lv_disp_get_next(NULL);
|
||||
while(d) {
|
||||
_lv_disp_refr_task(d->refr_task);
|
||||
d = lv_disp_get_next(d);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Invalidate an area on display to redraw it
|
||||
* @param area_p pointer to area which should be invalidated (NULL: delete the invalidated areas)
|
||||
* @param disp pointer to display where the area should be invalidated (NULL can be used if there is
|
||||
* only one display)
|
||||
*/
|
||||
void _lv_inv_area(lv_disp_t * disp, const lv_area_t * area_p)
|
||||
{
|
||||
if(!disp) disp = lv_disp_get_default();
|
||||
if(!disp) return;
|
||||
|
||||
/*Clear the invalidate buffer if the parameter is NULL*/
|
||||
if(area_p == NULL) {
|
||||
disp->inv_p = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
lv_area_t scr_area;
|
||||
scr_area.x1 = 0;
|
||||
scr_area.y1 = 0;
|
||||
scr_area.x2 = lv_disp_get_hor_res(disp) - 1;
|
||||
scr_area.y2 = lv_disp_get_ver_res(disp) - 1;
|
||||
|
||||
lv_area_t com_area;
|
||||
bool suc;
|
||||
|
||||
suc = _lv_area_intersect(&com_area, area_p, &scr_area);
|
||||
|
||||
/*The area is truncated to the screen*/
|
||||
if(suc != false) {
|
||||
if(disp->driver.rounder_cb) disp->driver.rounder_cb(&disp->driver, &com_area);
|
||||
|
||||
/*Save only if this area is not in one of the saved areas*/
|
||||
uint16_t i;
|
||||
for(i = 0; i < disp->inv_p; i++) {
|
||||
if(_lv_area_is_in(&com_area, &disp->inv_areas[i], 0) != false) return;
|
||||
}
|
||||
|
||||
/*Save the area*/
|
||||
if(disp->inv_p < LV_INV_BUF_SIZE) {
|
||||
lv_area_copy(&disp->inv_areas[disp->inv_p], &com_area);
|
||||
}
|
||||
else { /*If no place for the area add the screen*/
|
||||
disp->inv_p = 0;
|
||||
lv_area_copy(&disp->inv_areas[disp->inv_p], &scr_area);
|
||||
}
|
||||
disp->inv_p++;
|
||||
lv_task_set_prio(disp->refr_task, LV_REFR_TASK_PRIO);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the display which is being refreshed
|
||||
* @return the display being refreshed
|
||||
*/
|
||||
lv_disp_t * _lv_refr_get_disp_refreshing(void)
|
||||
{
|
||||
return disp_refr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the display which is being refreshed.
|
||||
* It shouldn't be used directly by the user.
|
||||
* It can be used to trick the drawing functions about there is an active display.
|
||||
* @param the display being refreshed
|
||||
*/
|
||||
void _lv_refr_set_disp_refreshing(lv_disp_t * disp)
|
||||
{
|
||||
disp_refr = disp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called periodically to handle the refreshing
|
||||
* @param task pointer to the task itself
|
||||
*/
|
||||
void _lv_disp_refr_task(lv_task_t * task)
|
||||
{
|
||||
LV_LOG_TRACE("lv_refr_task: started");
|
||||
|
||||
uint32_t start = lv_tick_get();
|
||||
uint32_t elaps = 0;
|
||||
|
||||
disp_refr = task->user_data;
|
||||
|
||||
#if LV_USE_PERF_MONITOR == 0
|
||||
/* Ensure the task does not run again automatically.
|
||||
* This is done before refreshing in case refreshing invalidates something else.
|
||||
*/
|
||||
lv_task_set_prio(task, LV_TASK_PRIO_OFF);
|
||||
#endif
|
||||
|
||||
/*Do nothing if there is no active screen*/
|
||||
if(disp_refr->act_scr == NULL) {
|
||||
disp_refr->inv_p = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
lv_refr_join_area();
|
||||
|
||||
lv_refr_areas();
|
||||
|
||||
/*If refresh happened ...*/
|
||||
if(disp_refr->inv_p != 0) {
|
||||
/* In true double buffered mode copy the refreshed areas to the new VDB to keep it up to date.
|
||||
* With set_px_cb we don't know anything about the buffer (even it's size) so skip copying.*/
|
||||
if(lv_disp_is_true_double_buf(disp_refr)) {
|
||||
if(disp_refr->driver.set_px_cb) {
|
||||
LV_LOG_WARN("Can't handle 2 screen sized buffers with set_px_cb. Display is not refreshed.");
|
||||
}
|
||||
else {
|
||||
lv_disp_buf_t * vdb = lv_disp_get_buf(disp_refr);
|
||||
|
||||
/*Flush the content of the VDB*/
|
||||
lv_refr_vdb_flush();
|
||||
|
||||
/* With true double buffering the flushing should be only the address change of the
|
||||
* current frame buffer. Wait until the address change is ready and copy the changed
|
||||
* content to the other frame buffer (new active VDB) to keep the buffers synchronized*/
|
||||
while(vdb->flushing);
|
||||
#if LCD_ROTATE_ANGLE == LCD_ROTATE_ANGLE_0
|
||||
lv_color_t * copy_buf = NULL;
|
||||
#if LV_USE_GPU_STM32_DMA2D
|
||||
LV_UNUSED(copy_buf);
|
||||
#else
|
||||
copy_buf = _lv_mem_buf_get(disp_refr->driver.hor_res * sizeof(lv_color_t));
|
||||
#endif
|
||||
|
||||
uint8_t * buf_act = (uint8_t *)vdb->buf_act;
|
||||
uint8_t * buf_ina = (uint8_t *)vdb->buf_act == vdb->buf1 ? vdb->buf2 : vdb->buf1;
|
||||
|
||||
lv_coord_t hres = lv_disp_get_hor_res(disp_refr);
|
||||
uint16_t a;
|
||||
for(a = 0; a < disp_refr->inv_p; a++) {
|
||||
#if defined(VG_DRIVER) && !defined(LVGL_VG_GPU) && !defined(REVERSE_TRACK)
|
||||
/* don't update the vg area */
|
||||
if (disp_refr->inv_areas[a].x1 == xm_vg_get_offset_x() &&
|
||||
disp_refr->inv_areas[a].y1 == xm_vg_get_offset_y() &&
|
||||
disp_refr->inv_areas[a].x2 == xm_vg_get_offset_x() + xm_vg_get_width() - 1 &&
|
||||
disp_refr->inv_areas[a].y2 == xm_vg_get_offset_y() + xm_vg_get_height() - 1) {
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
if(disp_refr->inv_area_joined[a] == 0) {
|
||||
uint32_t start_offs =
|
||||
(hres * disp_refr->inv_areas[a].y1 + disp_refr->inv_areas[a].x1) * sizeof(lv_color_t);
|
||||
#if LV_USE_GPU_STM32_DMA2D
|
||||
lv_gpu_stm32_dma2d_copy((lv_color_t *)(buf_act + start_offs), disp_refr->driver.hor_res,
|
||||
(lv_color_t *)(buf_ina + start_offs), disp_refr->driver.hor_res,
|
||||
lv_area_get_width(&disp_refr->inv_areas[a]),
|
||||
lv_area_get_height(&disp_refr->inv_areas[a]));
|
||||
#else
|
||||
|
||||
lv_coord_t y;
|
||||
uint32_t line_length = lv_area_get_width(&disp_refr->inv_areas[a]) * sizeof(lv_color_t);
|
||||
|
||||
for(y = disp_refr->inv_areas[a].y1; y <= disp_refr->inv_areas[a].y2; y++) {
|
||||
/* The frame buffer is probably in an external RAM where sequential access is much faster.
|
||||
* So first copy a line into a buffer and write it back the ext. RAM */
|
||||
_lv_memcpy(copy_buf, buf_ina + start_offs, line_length);
|
||||
_lv_memcpy(buf_act + start_offs, copy_buf, line_length);
|
||||
start_offs += hres * sizeof(lv_color_t);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if(copy_buf) _lv_mem_buf_release(copy_buf);
|
||||
#endif
|
||||
}
|
||||
} /*End of true double buffer handling*/
|
||||
|
||||
/*Clean up*/
|
||||
_lv_memset_00(disp_refr->inv_areas, sizeof(disp_refr->inv_areas));
|
||||
_lv_memset_00(disp_refr->inv_area_joined, sizeof(disp_refr->inv_area_joined));
|
||||
disp_refr->inv_p = 0;
|
||||
|
||||
elaps = lv_tick_elaps(start);
|
||||
/*Call monitor cb if present*/
|
||||
if(disp_refr->driver.monitor_cb) {
|
||||
disp_refr->driver.monitor_cb(&disp_refr->driver, elaps, px_num);
|
||||
}
|
||||
}
|
||||
|
||||
_lv_mem_buf_free_all();
|
||||
_lv_font_clean_up_fmt_txt();
|
||||
|
||||
#if LV_USE_PERF_MONITOR && LV_USE_LABEL
|
||||
static lv_obj_t * perf_label = NULL;
|
||||
if(perf_label == NULL) {
|
||||
perf_label = lv_label_create(lv_layer_sys(), NULL);
|
||||
lv_label_set_align(perf_label, LV_LABEL_ALIGN_RIGHT);
|
||||
lv_obj_set_style_local_bg_opa(perf_label, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_COVER);
|
||||
lv_obj_set_style_local_bg_color(perf_label, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_BLACK);
|
||||
lv_obj_set_style_local_text_color(perf_label, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_WHITE);
|
||||
lv_obj_set_style_local_pad_top(perf_label, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, 3);
|
||||
lv_obj_set_style_local_pad_bottom(perf_label, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, 3);
|
||||
lv_obj_set_style_local_pad_left(perf_label, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, 3);
|
||||
lv_obj_set_style_local_pad_right(perf_label, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, 3);
|
||||
lv_label_set_text(perf_label, "?");
|
||||
lv_obj_align(perf_label, NULL, LV_ALIGN_IN_BOTTOM_RIGHT, 0, 0);
|
||||
}
|
||||
|
||||
static uint32_t perf_last_time = 0;
|
||||
static uint32_t elaps_sum = 0;
|
||||
static uint32_t frame_cnt = 0;
|
||||
if(lv_tick_elaps(perf_last_time) < 300) {
|
||||
if(px_num > 5000) {
|
||||
elaps_sum += elaps;
|
||||
frame_cnt ++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
perf_last_time = lv_tick_get();
|
||||
uint32_t fps_limit = 1000 / disp_refr->refr_task->period;
|
||||
uint32_t fps;
|
||||
|
||||
if(elaps_sum == 0) elaps_sum = 1;
|
||||
if(frame_cnt == 0) fps = fps_limit;
|
||||
else fps = (1000 * frame_cnt) / elaps_sum;
|
||||
elaps_sum = 0;
|
||||
frame_cnt = 0;
|
||||
if(fps > fps_limit) fps = fps_limit;
|
||||
|
||||
fps_sum_all += fps;
|
||||
fps_sum_cnt ++;
|
||||
#if configGENERATE_RUN_TIME_STATS == 1
|
||||
uint32_t total_time = portGET_RUN_TIME_COUNTER_VALUE() / 100;
|
||||
uint32_t idle_time = ulTaskGetIdleRunTimeCounter();
|
||||
uint32_t cpu = 100 - idle_time / total_time;
|
||||
#else
|
||||
uint32_t cpu = 100 - lv_task_get_idle();
|
||||
#endif
|
||||
lv_label_set_text_fmt(perf_label, "%d FPS\n%d%% CPU", fps, cpu);
|
||||
lv_obj_align(perf_label, NULL, LV_ALIGN_IN_BOTTOM_RIGHT, 0, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
LV_LOG_TRACE("lv_refr_task: ready");
|
||||
}
|
||||
|
||||
#if LV_USE_PERF_MONITOR
|
||||
uint32_t lv_refr_get_fps_avg(void)
|
||||
{
|
||||
return fps_sum_all / fps_sum_cnt;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Join the areas which has got common parts
|
||||
*/
|
||||
static void lv_refr_join_area(void)
|
||||
{
|
||||
uint32_t join_from;
|
||||
uint32_t join_in;
|
||||
lv_area_t joined_area;
|
||||
for(join_in = 0; join_in < disp_refr->inv_p; join_in++) {
|
||||
if(disp_refr->inv_area_joined[join_in] != 0) continue;
|
||||
|
||||
/*Check all areas to join them in 'join_in'*/
|
||||
for(join_from = 0; join_from < disp_refr->inv_p; join_from++) {
|
||||
/*Handle only unjoined areas and ignore itself*/
|
||||
if(disp_refr->inv_area_joined[join_from] != 0 || join_in == join_from) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/*Check if the areas are on each other*/
|
||||
if(_lv_area_is_on(&disp_refr->inv_areas[join_in], &disp_refr->inv_areas[join_from]) == false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
_lv_area_join(&joined_area, &disp_refr->inv_areas[join_in], &disp_refr->inv_areas[join_from]);
|
||||
|
||||
/*Join two area only if the joined area size is smaller*/
|
||||
if(lv_area_get_size(&joined_area) < (lv_area_get_size(&disp_refr->inv_areas[join_in]) +
|
||||
lv_area_get_size(&disp_refr->inv_areas[join_from]))) {
|
||||
lv_area_copy(&disp_refr->inv_areas[join_in], &joined_area);
|
||||
|
||||
/*Mark 'join_form' is joined into 'join_in'*/
|
||||
disp_refr->inv_area_joined[join_from] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Refresh the joined areas
|
||||
*/
|
||||
static void lv_refr_areas(void)
|
||||
{
|
||||
px_num = 0;
|
||||
|
||||
if(disp_refr->inv_p == 0) return;
|
||||
|
||||
/*Find the last area which will be drawn*/
|
||||
int32_t i;
|
||||
int32_t last_i = 0;
|
||||
for(i = disp_refr->inv_p - 1; i >= 0; i--) {
|
||||
if(disp_refr->inv_area_joined[i] == 0) {
|
||||
last_i = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
disp_refr->driver.buffer->last_area = 0;
|
||||
disp_refr->driver.buffer->last_part = 0;
|
||||
|
||||
for(i = 0; i < disp_refr->inv_p; i++) {
|
||||
/*Refresh the unjoined areas*/
|
||||
if(disp_refr->inv_area_joined[i] == 0) {
|
||||
|
||||
if(i == last_i) disp_refr->driver.buffer->last_area = 1;
|
||||
disp_refr->driver.buffer->last_part = 0;
|
||||
lv_refr_area(&disp_refr->inv_areas[i]);
|
||||
|
||||
px_num += lv_area_get_size(&disp_refr->inv_areas[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Refresh an area if there is Virtual Display Buffer
|
||||
* @param area_p pointer to an area to refresh
|
||||
*/
|
||||
static void lv_refr_area(const lv_area_t * area_p)
|
||||
{
|
||||
/*True double buffering: there are two screen sized buffers. Just redraw directly into a
|
||||
* buffer*/
|
||||
if(lv_disp_is_true_double_buf(disp_refr)) {
|
||||
lv_disp_buf_t * vdb = lv_disp_get_buf(disp_refr);
|
||||
vdb->area.x1 = 0;
|
||||
vdb->area.x2 = lv_disp_get_hor_res(disp_refr) - 1;
|
||||
vdb->area.y1 = 0;
|
||||
vdb->area.y2 = lv_disp_get_ver_res(disp_refr) - 1;
|
||||
disp_refr->driver.buffer->last_part = 1;
|
||||
lv_refr_area_part(area_p);
|
||||
}
|
||||
/*The buffer is smaller: refresh the area in parts*/
|
||||
else {
|
||||
lv_disp_buf_t * vdb = lv_disp_get_buf(disp_refr);
|
||||
/*Calculate the max row num*/
|
||||
lv_coord_t w = lv_area_get_width(area_p);
|
||||
lv_coord_t h = lv_area_get_height(area_p);
|
||||
lv_coord_t y2 =
|
||||
area_p->y2 >= lv_disp_get_ver_res(disp_refr) ? lv_disp_get_ver_res(disp_refr) - 1 : area_p->y2;
|
||||
|
||||
int32_t max_row = (uint32_t)vdb->size / w;
|
||||
|
||||
if(max_row > h) max_row = h;
|
||||
|
||||
/*Round down the lines of VDB if rounding is added*/
|
||||
if(disp_refr->driver.rounder_cb) {
|
||||
lv_area_t tmp;
|
||||
tmp.x1 = 0;
|
||||
tmp.x2 = 0;
|
||||
tmp.y1 = 0;
|
||||
|
||||
lv_coord_t h_tmp = max_row;
|
||||
do {
|
||||
tmp.y2 = h_tmp - 1;
|
||||
disp_refr->driver.rounder_cb(&disp_refr->driver, &tmp);
|
||||
|
||||
/*If this height fits into `max_row` then fine*/
|
||||
if(lv_area_get_height(&tmp) <= max_row) break;
|
||||
|
||||
/*Decrement the height of the area until it fits into `max_row` after rounding*/
|
||||
h_tmp--;
|
||||
} while(h_tmp > 0);
|
||||
|
||||
if(h_tmp <= 0) {
|
||||
LV_LOG_WARN("Can't set VDB height using the round function. (Wrong round_cb or to "
|
||||
"small VDB)");
|
||||
return;
|
||||
}
|
||||
else {
|
||||
max_row = tmp.y2 + 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*Always use the full row*/
|
||||
lv_coord_t row;
|
||||
lv_coord_t row_last = 0;
|
||||
for(row = area_p->y1; row + max_row - 1 <= y2; row += max_row) {
|
||||
/*Calc. the next y coordinates of VDB*/
|
||||
vdb->area.x1 = area_p->x1;
|
||||
vdb->area.x2 = area_p->x2;
|
||||
vdb->area.y1 = row;
|
||||
vdb->area.y2 = row + max_row - 1;
|
||||
if(vdb->area.y2 > y2) vdb->area.y2 = y2;
|
||||
row_last = vdb->area.y2;
|
||||
if(y2 == row_last) disp_refr->driver.buffer->last_part = 1;
|
||||
lv_refr_area_part(area_p);
|
||||
}
|
||||
|
||||
/*If the last y coordinates are not handled yet ...*/
|
||||
if(y2 != row_last) {
|
||||
/*Calc. the next y coordinates of VDB*/
|
||||
vdb->area.x1 = area_p->x1;
|
||||
vdb->area.x2 = area_p->x2;
|
||||
vdb->area.y1 = row;
|
||||
vdb->area.y2 = y2;
|
||||
|
||||
disp_refr->driver.buffer->last_part = 1;
|
||||
lv_refr_area_part(area_p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Refresh a part of an area which is on the actual Virtual Display Buffer
|
||||
* @param area_p pointer to an area to refresh
|
||||
*/
|
||||
static void lv_refr_area_part(const lv_area_t * area_p)
|
||||
{
|
||||
lv_disp_buf_t * vdb = lv_disp_get_buf(disp_refr);
|
||||
|
||||
/*In non double buffered mode, before rendering the next part wait until the previous image is
|
||||
* flushed*/
|
||||
if(lv_disp_is_double_buf(disp_refr) == false) {
|
||||
while(vdb->flushing) {
|
||||
if(disp_refr->driver.wait_cb) disp_refr->driver.wait_cb(&disp_refr->driver);
|
||||
}
|
||||
}
|
||||
|
||||
lv_obj_t * top_act_scr = NULL;
|
||||
lv_obj_t * top_prev_scr = NULL;
|
||||
|
||||
/*Get the new mask from the original area and the act. VDB
|
||||
It will be a part of 'area_p'*/
|
||||
lv_area_t start_mask;
|
||||
_lv_area_intersect(&start_mask, area_p, &vdb->area);
|
||||
|
||||
/*Get the most top object which is not covered by others*/
|
||||
top_act_scr = lv_refr_get_top_obj(&start_mask, lv_disp_get_scr_act(disp_refr));
|
||||
if(disp_refr->prev_scr) {
|
||||
top_prev_scr = lv_refr_get_top_obj(&start_mask, disp_refr->prev_scr);
|
||||
}
|
||||
|
||||
/*Draw a display background if there is no top object*/
|
||||
if(top_act_scr == NULL && top_prev_scr == NULL) {
|
||||
if(disp_refr->bg_img) {
|
||||
lv_draw_img_dsc_t dsc;
|
||||
lv_draw_img_dsc_init(&dsc);
|
||||
dsc.opa = disp_refr->bg_opa;
|
||||
lv_img_header_t header;
|
||||
lv_res_t res;
|
||||
res = lv_img_decoder_get_info(disp_refr->bg_img, &header);
|
||||
if(res == LV_RES_OK) {
|
||||
lv_area_t a;
|
||||
lv_area_set(&a, 0, 0, header.w - 1, header.h - 1);
|
||||
lv_draw_img(&a, &start_mask, disp_refr->bg_img, &dsc);
|
||||
}
|
||||
else {
|
||||
LV_LOG_WARN("Can't draw the background image")
|
||||
}
|
||||
}
|
||||
else {
|
||||
lv_draw_rect_dsc_t dsc;
|
||||
lv_draw_rect_dsc_init(&dsc);
|
||||
dsc.bg_color = disp_refr->bg_color;
|
||||
dsc.bg_opa = disp_refr->bg_opa;
|
||||
lv_draw_rect(&start_mask, &start_mask, &dsc);
|
||||
|
||||
}
|
||||
}
|
||||
/*Refresh the previous screen if any*/
|
||||
if(disp_refr->prev_scr) {
|
||||
/*Get the most top object which is not covered by others*/
|
||||
if(top_prev_scr == NULL) {
|
||||
top_prev_scr = disp_refr->prev_scr;
|
||||
}
|
||||
/*Do the refreshing from the top object*/
|
||||
lv_refr_obj_and_children(top_prev_scr, &start_mask);
|
||||
|
||||
}
|
||||
|
||||
if(top_act_scr == NULL) {
|
||||
top_act_scr = disp_refr->act_scr;
|
||||
}
|
||||
/*Do the refreshing from the top object*/
|
||||
lv_refr_obj_and_children(top_act_scr, &start_mask);
|
||||
|
||||
/*Also refresh top and sys layer unconditionally*/
|
||||
lv_refr_obj_and_children(lv_disp_get_layer_top(disp_refr), &start_mask);
|
||||
lv_refr_obj_and_children(lv_disp_get_layer_sys(disp_refr), &start_mask);
|
||||
|
||||
/* In true double buffered mode flush only once when all areas were rendered.
|
||||
* In normal mode flush after every area */
|
||||
if(lv_disp_is_true_double_buf(disp_refr) == false) {
|
||||
lv_refr_vdb_flush();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Search the most top object which fully covers an area
|
||||
* @param area_p pointer to an area
|
||||
* @param obj the first object to start the searching (typically a screen)
|
||||
* @return
|
||||
*/
|
||||
static lv_obj_t * lv_refr_get_top_obj(const lv_area_t * area_p, lv_obj_t * obj)
|
||||
{
|
||||
lv_obj_t * found_p = NULL;
|
||||
|
||||
/*If this object is fully cover the draw area check the children too */
|
||||
if(_lv_area_is_in(area_p, &obj->coords, 0) && obj->hidden == 0) {
|
||||
lv_design_res_t design_res = obj->design_cb(obj, area_p, LV_DESIGN_COVER_CHK);
|
||||
if(design_res == LV_DESIGN_RES_MASKED) return NULL;
|
||||
|
||||
#if LV_USE_OPA_SCALE
|
||||
if(design_res == LV_DESIGN_RES_COVER && lv_obj_get_style_opa_scale(obj, LV_OBJ_PART_MAIN) != LV_OPA_COVER) {
|
||||
design_res = LV_DESIGN_RES_NOT_COVER;
|
||||
}
|
||||
#endif
|
||||
|
||||
lv_obj_t * i;
|
||||
_LV_LL_READ(obj->child_ll, i) {
|
||||
found_p = lv_refr_get_top_obj(area_p, i);
|
||||
|
||||
/*If a children is ok then break*/
|
||||
if(found_p != NULL) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*If no better children use this object*/
|
||||
if(found_p == NULL) {
|
||||
if(design_res == LV_DESIGN_RES_COVER) {
|
||||
found_p = obj;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return found_p;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make the refreshing from an object. Draw all its children and the youngers too.
|
||||
* @param top_p pointer to an objects. Start the drawing from it.
|
||||
* @param mask_p pointer to an area, the objects will be drawn only here
|
||||
*/
|
||||
static void lv_refr_obj_and_children(lv_obj_t * top_p, const lv_area_t * mask_p)
|
||||
{
|
||||
/* Normally always will be a top_obj (at least the screen)
|
||||
* but in special cases (e.g. if the screen has alpha) it won't.
|
||||
* In this case use the screen directly */
|
||||
if(top_p == NULL) top_p = lv_disp_get_scr_act(disp_refr);
|
||||
if(top_p == NULL) return; /*Shouldn't happen*/
|
||||
|
||||
/*Refresh the top object and its children*/
|
||||
lv_refr_obj(top_p, mask_p);
|
||||
|
||||
/*Draw the 'younger' sibling objects because they can be on top_obj */
|
||||
lv_obj_t * par;
|
||||
lv_obj_t * border_p = top_p;
|
||||
|
||||
par = lv_obj_get_parent(top_p);
|
||||
|
||||
/*Do until not reach the screen*/
|
||||
while(par != NULL) {
|
||||
/*object before border_p has to be redrawn*/
|
||||
lv_obj_t * i = _lv_ll_get_prev(&(par->child_ll), border_p);
|
||||
|
||||
while(i != NULL) {
|
||||
/*Refresh the objects*/
|
||||
lv_refr_obj(i, mask_p);
|
||||
i = _lv_ll_get_prev(&(par->child_ll), i);
|
||||
}
|
||||
|
||||
/*Call the post draw design function of the parents of the to object*/
|
||||
if(par->design_cb) par->design_cb(par, mask_p, LV_DESIGN_DRAW_POST);
|
||||
|
||||
/*The new border will be there last parents,
|
||||
*so the 'younger' brothers of parent will be refreshed*/
|
||||
border_p = par;
|
||||
/*Go a level deeper*/
|
||||
par = lv_obj_get_parent(par);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Refresh an object an all of its children. (Called recursively)
|
||||
* @param obj pointer to an object to refresh
|
||||
* @param mask_ori_p pointer to an area, the objects will be drawn only here
|
||||
*/
|
||||
static void lv_refr_obj(lv_obj_t * obj, const lv_area_t * mask_ori_p)
|
||||
{
|
||||
/*Do not refresh hidden objects*/
|
||||
if(obj->hidden != 0) return;
|
||||
|
||||
bool union_ok; /* Store the return value of area_union */
|
||||
/* Truncate the original mask to the coordinates of the parent
|
||||
* because the parent and its children are visible only here */
|
||||
lv_area_t obj_mask;
|
||||
lv_area_t obj_ext_mask;
|
||||
lv_area_t obj_area;
|
||||
lv_coord_t ext_size = obj->ext_draw_pad;
|
||||
lv_obj_get_coords(obj, &obj_area);
|
||||
obj_area.x1 -= ext_size;
|
||||
obj_area.y1 -= ext_size;
|
||||
obj_area.x2 += ext_size;
|
||||
obj_area.y2 += ext_size;
|
||||
union_ok = _lv_area_intersect(&obj_ext_mask, mask_ori_p, &obj_area);
|
||||
|
||||
/*Draw the parent and its children only if they ore on 'mask_parent'*/
|
||||
if(union_ok != false) {
|
||||
|
||||
/* Redraw the object */
|
||||
if(obj->design_cb) obj->design_cb(obj, &obj_ext_mask, LV_DESIGN_DRAW_MAIN);
|
||||
|
||||
#if MASK_AREA_DEBUG
|
||||
static lv_color_t debug_color = LV_COLOR_RED;
|
||||
lv_draw_rect_dsc_t draw_dsc;
|
||||
lv_draw_rect_dsc_init(&draw_dsc);
|
||||
draw_dsc.bg_color.full = debug_color.full;
|
||||
draw_dsc.bg_opa = LV_OPA_20;
|
||||
draw_dsc.border_width = 2;
|
||||
draw_dsc.border_opa = LV_OPA_50;
|
||||
draw_dsc.border_color.full = (debug_color.full + 0x13) * 9;
|
||||
|
||||
lv_draw_rect(&obj_ext_mask, &obj_ext_mask, &draw_dsc);
|
||||
debug_color.full *= 17;
|
||||
debug_color.full += 0xA1;
|
||||
#if LV_COLOR_DEPTH == 32
|
||||
debug_color.ch.alpha = 0xff;
|
||||
#endif
|
||||
#endif
|
||||
/*Create a new 'obj_mask' without 'ext_size' because the children can't be visible there*/
|
||||
lv_obj_get_coords(obj, &obj_area);
|
||||
union_ok = _lv_area_intersect(&obj_mask, mask_ori_p, &obj_area);
|
||||
if(union_ok != false) {
|
||||
lv_area_t mask_child; /*Mask from obj and its child*/
|
||||
lv_obj_t * child_p;
|
||||
lv_area_t child_area;
|
||||
_LV_LL_READ_BACK(obj->child_ll, child_p) {
|
||||
lv_obj_get_coords(child_p, &child_area);
|
||||
ext_size = child_p->ext_draw_pad;
|
||||
child_area.x1 -= ext_size;
|
||||
child_area.y1 -= ext_size;
|
||||
child_area.x2 += ext_size;
|
||||
child_area.y2 += ext_size;
|
||||
/* Get the union (common parts) of original mask (from obj)
|
||||
* and its child */
|
||||
union_ok = _lv_area_intersect(&mask_child, &obj_mask, &child_area);
|
||||
#if defined(VG_DRIVER) && !defined(LVGL_VG_GPU) && !defined(REVERSE_TRACK)
|
||||
/* when the refresh area is vg area, only draw the vg and it's childs */
|
||||
if (mask_ori_p->x1 == xm_vg_get_offset_x() && mask_ori_p->y1 == xm_vg_get_offset_y()
|
||||
&& mask_ori_p->x2 == xm_vg_get_offset_x() + xm_vg_get_width() - 1
|
||||
&& mask_ori_p->y2 == xm_vg_get_offset_y() + xm_vg_get_height() - 1) {
|
||||
if (child_area.x1 != mask_ori_p->x1 || child_area.y1 != mask_ori_p->y1
|
||||
|| child_area.x2 != mask_ori_p->x2 || child_area.y2 != mask_ori_p->y2)
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
/*If the parent and the child has common area then refresh the child */
|
||||
if(union_ok) {
|
||||
/*Refresh the next children*/
|
||||
lv_refr_obj(child_p, &mask_child);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* If all the children are redrawn make 'post draw' design */
|
||||
if(obj->design_cb) obj->design_cb(obj, &obj_ext_mask, LV_DESIGN_DRAW_POST);
|
||||
}
|
||||
}
|
||||
|
||||
static void lv_refr_vdb_rotate_180(lv_disp_drv_t * drv, lv_area_t * area, lv_color_t * color_p)
|
||||
{
|
||||
lv_coord_t area_w = lv_area_get_width(area);
|
||||
lv_coord_t area_h = lv_area_get_height(area);
|
||||
uint32_t total = area_w * area_h;
|
||||
/* Swap the beginning and end values */
|
||||
lv_color_t tmp;
|
||||
uint32_t i = total - 1, j = 0;
|
||||
while(i > j) {
|
||||
tmp = color_p[i];
|
||||
color_p[i] = color_p[j];
|
||||
color_p[j] = tmp;
|
||||
i--;
|
||||
j++;
|
||||
}
|
||||
lv_coord_t tmp_coord;
|
||||
tmp_coord = area->y2;
|
||||
area->y2 = drv->ver_res - area->y1 - 1;
|
||||
area->y1 = drv->ver_res - tmp_coord - 1;
|
||||
tmp_coord = area->x2;
|
||||
area->x2 = drv->hor_res - area->x1 - 1;
|
||||
area->x1 = drv->hor_res - tmp_coord - 1;
|
||||
}
|
||||
|
||||
static LV_ATTRIBUTE_FAST_MEM void lv_refr_vdb_rotate_90(bool invert_i, lv_coord_t area_w, lv_coord_t area_h,
|
||||
lv_color_t * orig_color_p, lv_color_t * rot_buf)
|
||||
{
|
||||
|
||||
uint32_t invert = (area_w * area_h) - 1;
|
||||
uint32_t initial_i = ((area_w - 1) * area_h);
|
||||
for(lv_coord_t y = 0; y < area_h; y++) {
|
||||
uint32_t i = initial_i + y;
|
||||
if(invert_i)
|
||||
i = invert - i;
|
||||
for(lv_coord_t x = 0; x < area_w; x++) {
|
||||
rot_buf[i] = *(orig_color_p++);
|
||||
if(invert_i)
|
||||
i += area_h;
|
||||
else
|
||||
i -= area_h;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function for lv_refr_vdb_rotate_90_sqr. Given a list of four numbers, rotate the entire list to the left.
|
||||
*/
|
||||
static inline void lv_vdb_rotate4(lv_color_t * a, lv_color_t * b, lv_color_t * c, lv_color_t * d)
|
||||
{
|
||||
lv_color_t tmp;
|
||||
tmp = *a;
|
||||
*a = *b;
|
||||
*b = *c;
|
||||
*c = *d;
|
||||
*d = tmp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rotate a square image 90/270 degrees in place.
|
||||
* @note inspired by https://stackoverflow.com/a/43694906
|
||||
*/
|
||||
static void lv_refr_vdb_rotate_90_sqr(bool is_270, lv_coord_t w, lv_color_t * color_p)
|
||||
{
|
||||
for(lv_coord_t i = 0; i < w / 2; i++) {
|
||||
for(lv_coord_t j = 0; j < (w + 1) / 2; j++) {
|
||||
lv_coord_t inv_i = (w - 1) - i;
|
||||
lv_coord_t inv_j = (w - 1) - j;
|
||||
if(is_270) {
|
||||
lv_vdb_rotate4(
|
||||
&color_p[i * w + j],
|
||||
&color_p[inv_j * w + i],
|
||||
&color_p[inv_i * w + inv_j],
|
||||
&color_p[j * w + inv_i]
|
||||
);
|
||||
}
|
||||
else {
|
||||
lv_vdb_rotate4(
|
||||
&color_p[i * w + j],
|
||||
&color_p[j * w + inv_i],
|
||||
&color_p[inv_i * w + inv_j],
|
||||
&color_p[inv_j * w + i]
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Rotate the VDB to the display's native orientation.
|
||||
*/
|
||||
static void lv_refr_vdb_rotate(lv_area_t * area, lv_color_t * color_p)
|
||||
{
|
||||
lv_disp_drv_t * drv = &disp_refr->driver;
|
||||
if(lv_disp_is_true_double_buf(disp_refr) && drv->sw_rotate) {
|
||||
LV_LOG_ERROR("cannot rotate a true double-buffered display!");
|
||||
return;
|
||||
}
|
||||
if(drv->rotated == LV_DISP_ROT_180) {
|
||||
lv_refr_vdb_rotate_180(drv, area, color_p);
|
||||
drv->flush_cb(drv, area, color_p);
|
||||
}
|
||||
else if(drv->rotated == LV_DISP_ROT_90 || drv->rotated == LV_DISP_ROT_270) {
|
||||
/*Allocate a temporary buffer to store rotated image */
|
||||
lv_color_t * rot_buf = NULL;
|
||||
lv_disp_buf_t * vdb = lv_disp_get_buf(disp_refr);
|
||||
lv_coord_t area_w = lv_area_get_width(area);
|
||||
lv_coord_t area_h = lv_area_get_height(area);
|
||||
/*Determine the maximum number of rows that can be rotated at a time*/
|
||||
lv_coord_t max_row = LV_MATH_MIN((lv_coord_t)((LV_DISP_ROT_MAX_BUF / sizeof(lv_color_t)) / area_w), area_h);
|
||||
lv_coord_t init_y_off;
|
||||
init_y_off = area->y1;
|
||||
if(drv->rotated == LV_DISP_ROT_90) {
|
||||
area->y2 = drv->ver_res - area->x1 - 1;
|
||||
area->y1 = area->y2 - area_w + 1;
|
||||
}
|
||||
else {
|
||||
area->y1 = area->x1;
|
||||
area->y2 = area->y1 + area_w - 1;
|
||||
}
|
||||
vdb->flushing = 0;
|
||||
/*Rotate the screen in chunks, flushing after each one*/
|
||||
lv_coord_t row = 0;
|
||||
while(row < area_h) {
|
||||
lv_coord_t height = LV_MATH_MIN(max_row, area_h - row);
|
||||
vdb->flushing = 1;
|
||||
if((row == 0) && (area_h >= area_w)) {
|
||||
/*Rotate the initial area as a square*/
|
||||
height = area_w;
|
||||
lv_refr_vdb_rotate_90_sqr(drv->rotated == LV_DISP_ROT_270, area_w, color_p);
|
||||
if(drv->rotated == LV_DISP_ROT_90) {
|
||||
area->x1 = init_y_off;
|
||||
area->x2 = init_y_off + area_w - 1;
|
||||
}
|
||||
else {
|
||||
area->x2 = drv->hor_res - 1 - init_y_off;
|
||||
area->x1 = area->x2 - area_w + 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/*Rotate other areas using a maximum buffer size*/
|
||||
if(rot_buf == NULL)
|
||||
rot_buf = _lv_mem_buf_get(LV_DISP_ROT_MAX_BUF);
|
||||
lv_refr_vdb_rotate_90(drv->rotated == LV_DISP_ROT_270, area_w, height, color_p, rot_buf);
|
||||
|
||||
if(drv->rotated == LV_DISP_ROT_90) {
|
||||
area->x1 = init_y_off + row;
|
||||
area->x2 = init_y_off + row + height - 1;
|
||||
}
|
||||
else {
|
||||
area->x2 = drv->hor_res - 1 - init_y_off - row;
|
||||
area->x1 = area->x2 - height + 1;
|
||||
}
|
||||
}
|
||||
/*Flush the completed area to the display*/
|
||||
drv->flush_cb(drv, area, rot_buf == NULL ? color_p : rot_buf);
|
||||
/*FIXME: Rotation forces legacy behavior where rendering and flushing are done serially*/
|
||||
while(vdb->flushing) {
|
||||
if(drv->wait_cb) drv->wait_cb(drv);
|
||||
}
|
||||
color_p += area_w * height;
|
||||
row += height;
|
||||
}
|
||||
/*Free the allocated buffer at the end if necessary*/
|
||||
if(rot_buf != NULL)
|
||||
_lv_mem_buf_release(rot_buf);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Flush the content of the VDB
|
||||
*/
|
||||
static void lv_refr_vdb_flush(void)
|
||||
{
|
||||
lv_disp_buf_t * vdb = lv_disp_get_buf(disp_refr);
|
||||
lv_color_t * color_p = vdb->buf_act;
|
||||
|
||||
/*In double buffered mode wait until the other buffer is flushed before flushing the current
|
||||
* one*/
|
||||
if(lv_disp_is_double_buf(disp_refr)) {
|
||||
while(vdb->flushing) {
|
||||
if(disp_refr->driver.wait_cb) disp_refr->driver.wait_cb(&disp_refr->driver);
|
||||
}
|
||||
}
|
||||
|
||||
vdb->flushing = 1;
|
||||
|
||||
if(disp_refr->driver.buffer->last_area && disp_refr->driver.buffer->last_part) vdb->flushing_last = 1;
|
||||
else vdb->flushing_last = 0;
|
||||
|
||||
/*Flush the rendered content to the display*/
|
||||
lv_disp_t * disp = _lv_refr_get_disp_refreshing();
|
||||
if(disp->driver.gpu_wait_cb) disp->driver.gpu_wait_cb(&disp->driver);
|
||||
|
||||
if(disp->driver.flush_cb) {
|
||||
/*Rotate the buffer to the display's native orientation if necessary*/
|
||||
if(disp->driver.rotated != LV_DISP_ROT_NONE && disp->driver.sw_rotate) {
|
||||
lv_refr_vdb_rotate(&vdb->area, vdb->buf_act);
|
||||
}
|
||||
else {
|
||||
disp->driver.flush_cb(&disp->driver, &vdb->area, color_p);
|
||||
}
|
||||
}
|
||||
if(vdb->buf1 && vdb->buf2) {
|
||||
if(vdb->buf_act == vdb->buf1)
|
||||
vdb->buf_act = vdb->buf2;
|
||||
else
|
||||
vdb->buf_act = vdb->buf1;
|
||||
}
|
||||
}
|
103
MXC_A27-PCB4.5-270S/lib/LittlevGL/lvgl/src/lv_core/lv_refr.h
Normal file
103
MXC_A27-PCB4.5-270S/lib/LittlevGL/lvgl/src/lv_core/lv_refr.h
Normal file
@ -0,0 +1,103 @@
|
||||
/**
|
||||
* @file lv_refr.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_REFR_H
|
||||
#define LV_REFR_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_obj.h"
|
||||
#include <stdbool.h>
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
#define LV_REFR_TASK_PRIO LV_TASK_PRIO_MID
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Initialize the screen refresh subsystem
|
||||
*/
|
||||
void _lv_refr_init(void);
|
||||
|
||||
/**
|
||||
* Redraw the invalidated areas now.
|
||||
* Normally the redrawing is periodically executed in `lv_task_handler` but a long blocking process
|
||||
* can prevent the call of `lv_task_handler`. In this case if the GUI is updated in the process
|
||||
* (e.g. progress bar) this function can be called when the screen should be updated.
|
||||
* @param disp pointer to display to refresh. NULL to refresh all displays.
|
||||
*/
|
||||
void lv_refr_now(lv_disp_t * disp);
|
||||
|
||||
/**
|
||||
* Invalidate an area on display to redraw it
|
||||
* @param area_p pointer to area which should be invalidated (NULL: delete the invalidated areas)
|
||||
* @param disp pointer to display where the area should be invalidated (NULL can be used if there is
|
||||
* only one display)
|
||||
*/
|
||||
void _lv_inv_area(lv_disp_t * disp, const lv_area_t * area_p);
|
||||
|
||||
/**
|
||||
* Get the display which is being refreshed
|
||||
* @return the display being refreshed
|
||||
*/
|
||||
lv_disp_t * _lv_refr_get_disp_refreshing(void);
|
||||
|
||||
/**
|
||||
* Set the display which is being refreshed.
|
||||
* It shouldn't be used directly by the user.
|
||||
* It can be used to trick the drawing functions about there is an active display.
|
||||
* @param the display being refreshed
|
||||
*/
|
||||
void _lv_refr_set_disp_refreshing(lv_disp_t * disp);
|
||||
|
||||
#if LV_USE_PERF_MONITOR
|
||||
/**
|
||||
* Get the average FPS since start up
|
||||
* @return the average FPS
|
||||
*/
|
||||
uint32_t lv_refr_get_fps_avg(void);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Called periodically to handle the refreshing
|
||||
* @param task pointer to the task itself
|
||||
*/
|
||||
void _lv_disp_refr_task(lv_task_t * task);
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_REFR_H*/
|
1134
MXC_A27-PCB4.5-270S/lib/LittlevGL/lvgl/src/lv_core/lv_style.c
Normal file
1134
MXC_A27-PCB4.5-270S/lib/LittlevGL/lvgl/src/lv_core/lv_style.c
Normal file
File diff suppressed because it is too large
Load Diff
632
MXC_A27-PCB4.5-270S/lib/LittlevGL/lvgl/src/lv_core/lv_style.h
Normal file
632
MXC_A27-PCB4.5-270S/lib/LittlevGL/lvgl/src/lv_core/lv_style.h
Normal file
@ -0,0 +1,632 @@
|
||||
/**
|
||||
* @file lv_style.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_STYLE_H
|
||||
#define LV_STYLE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include <stdbool.h>
|
||||
#include "../lv_font/lv_font.h"
|
||||
#include "../lv_misc/lv_color.h"
|
||||
#include "../lv_misc/lv_area.h"
|
||||
#include "../lv_misc/lv_anim.h"
|
||||
#include "../lv_misc/lv_types.h"
|
||||
#include "../lv_misc/lv_debug.h"
|
||||
#include "../lv_draw/lv_draw_blend.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
#define LV_RADIUS_CIRCLE (0x7FFF) /**< A very big radius to always draw as circle*/
|
||||
LV_EXPORT_CONST_INT(LV_RADIUS_CIRCLE);
|
||||
|
||||
#define LV_DEBUG_STYLE_SENTINEL_VALUE 0x2288AAEE
|
||||
#define LV_DEBUG_STYLE_LIST_SENTINEL_VALUE 0x9977CCBB
|
||||
|
||||
#define LV_STYLE_PROP_INIT(name, group, id, attr) name = (((group << 4) + id) | ((attr) << 8))
|
||||
|
||||
#define LV_STYLE_ID_MASK 0x00FF
|
||||
|
||||
#define LV_STYLE_ATTR_NONE 0
|
||||
#define LV_STYLE_ATTR_INHERIT (1 << 7)
|
||||
|
||||
#define _LV_STYLE_CLOSING_PROP 0xFF
|
||||
|
||||
#define LV_STYLE_TRANS_NUM_MAX 6
|
||||
|
||||
#define LV_STYLE_PROP_ALL 0xFF
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/*Border types (Use 'OR'ed values)*/
|
||||
enum {
|
||||
LV_BORDER_SIDE_NONE = 0x00,
|
||||
LV_BORDER_SIDE_BOTTOM = 0x01,
|
||||
LV_BORDER_SIDE_TOP = 0x02,
|
||||
LV_BORDER_SIDE_LEFT = 0x04,
|
||||
LV_BORDER_SIDE_RIGHT = 0x08,
|
||||
LV_BORDER_SIDE_FULL = 0x0F,
|
||||
LV_BORDER_SIDE_INTERNAL = 0x10, /**< FOR matrix-like objects (e.g. Button matrix)*/
|
||||
_LV_BORDER_SIDE_LAST
|
||||
};
|
||||
typedef uint8_t lv_border_side_t;
|
||||
|
||||
enum {
|
||||
LV_GRAD_DIR_NONE,
|
||||
LV_GRAD_DIR_VER,
|
||||
LV_GRAD_DIR_HOR,
|
||||
_LV_GRAD_DIR_LAST
|
||||
};
|
||||
|
||||
typedef uint8_t lv_grad_dir_t;
|
||||
|
||||
/*Text decorations (Use 'OR'ed values)*/
|
||||
enum {
|
||||
LV_TEXT_DECOR_NONE = 0x00,
|
||||
LV_TEXT_DECOR_UNDERLINE = 0x01,
|
||||
LV_TEXT_DECOR_STRIKETHROUGH = 0x02,
|
||||
_LV_TEXT_DECOR_LAST
|
||||
};
|
||||
|
||||
typedef uint8_t lv_text_decor_t;
|
||||
|
||||
typedef uint8_t lv_style_attr_t;
|
||||
|
||||
#define LV_STYLE_ATTR_GET_INHERIT(f) ((f)&0x80)
|
||||
#define LV_STYLE_ATTR_GET_STATE(f) ((f)&0x7F)
|
||||
|
||||
#define LV_STYLE_ID_VALUE 0x0 /*max 9 pcs*/
|
||||
#define LV_STYLE_ID_COLOR 0x9 /*max 3 pcs*/
|
||||
#define LV_STYLE_ID_OPA 0xC /*max 2 pcs*/
|
||||
#define LV_STYLE_ID_PTR 0xE /*max 2 pcs*/
|
||||
|
||||
enum {
|
||||
/*Skip 0th property*/
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_RADIUS, 0x0, LV_STYLE_ID_VALUE + 1, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_CLIP_CORNER, 0x0, LV_STYLE_ID_VALUE + 2, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_SIZE, 0x0, LV_STYLE_ID_VALUE + 3, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_TRANSFORM_WIDTH, 0x0, LV_STYLE_ID_VALUE + 4, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_TRANSFORM_HEIGHT, 0x0, LV_STYLE_ID_VALUE + 5, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_TRANSFORM_ANGLE, 0x0, LV_STYLE_ID_VALUE + 6, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_TRANSFORM_ZOOM, 0x0, LV_STYLE_ID_VALUE + 7, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_OPA_SCALE, 0x0, LV_STYLE_ID_OPA + 0, LV_STYLE_ATTR_INHERIT),
|
||||
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_PAD_TOP, 0x1, LV_STYLE_ID_VALUE + 0, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_PAD_BOTTOM, 0x1, LV_STYLE_ID_VALUE + 1, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_PAD_LEFT, 0x1, LV_STYLE_ID_VALUE + 2, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_PAD_RIGHT, 0x1, LV_STYLE_ID_VALUE + 3, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_PAD_INNER, 0x1, LV_STYLE_ID_VALUE + 4, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_MARGIN_TOP, 0x1, LV_STYLE_ID_VALUE + 5, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_MARGIN_BOTTOM, 0x1, LV_STYLE_ID_VALUE + 6, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_MARGIN_LEFT, 0x1, LV_STYLE_ID_VALUE + 7, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_MARGIN_RIGHT, 0x1, LV_STYLE_ID_VALUE + 8, LV_STYLE_ATTR_NONE),
|
||||
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_BG_BLEND_MODE, 0x2, LV_STYLE_ID_VALUE + 0, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_BG_MAIN_STOP, 0x2, LV_STYLE_ID_VALUE + 1, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_BG_GRAD_STOP, 0x2, LV_STYLE_ID_VALUE + 2, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_BG_GRAD_DIR, 0x2, LV_STYLE_ID_VALUE + 3, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_BG_COLOR, 0x2, LV_STYLE_ID_COLOR + 0, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_BG_GRAD_COLOR, 0x2, LV_STYLE_ID_COLOR + 1, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_BG_OPA, 0x2, LV_STYLE_ID_OPA + 0, LV_STYLE_ATTR_NONE),
|
||||
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_BORDER_WIDTH, 0x3, LV_STYLE_ID_VALUE + 0, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_BORDER_SIDE, 0x3, LV_STYLE_ID_VALUE + 1, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_BORDER_BLEND_MODE, 0x3, LV_STYLE_ID_VALUE + 2, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_BORDER_POST, 0x3, LV_STYLE_ID_VALUE + 3, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_BORDER_COLOR, 0x3, LV_STYLE_ID_COLOR + 0, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_BORDER_OPA, 0x3, LV_STYLE_ID_OPA + 0, LV_STYLE_ATTR_NONE),
|
||||
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_OUTLINE_WIDTH, 0x4, LV_STYLE_ID_VALUE + 0, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_OUTLINE_PAD, 0x4, LV_STYLE_ID_VALUE + 1, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_OUTLINE_BLEND_MODE, 0x4, LV_STYLE_ID_VALUE + 2, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_OUTLINE_COLOR, 0x4, LV_STYLE_ID_COLOR + 0, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_OUTLINE_OPA, 0x4, LV_STYLE_ID_OPA + 0, LV_STYLE_ATTR_NONE),
|
||||
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_SHADOW_WIDTH, 0x5, LV_STYLE_ID_VALUE + 0, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_SHADOW_OFS_X, 0x5, LV_STYLE_ID_VALUE + 1, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_SHADOW_OFS_Y, 0x5, LV_STYLE_ID_VALUE + 2, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_SHADOW_SPREAD, 0x5, LV_STYLE_ID_VALUE + 3, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_SHADOW_BLEND_MODE, 0x5, LV_STYLE_ID_VALUE + 4, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_SHADOW_COLOR, 0x5, LV_STYLE_ID_COLOR + 0, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_SHADOW_OPA, 0x5, LV_STYLE_ID_OPA + 0, LV_STYLE_ATTR_NONE),
|
||||
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_PATTERN_BLEND_MODE, 0x6, LV_STYLE_ID_VALUE + 0, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_PATTERN_REPEAT, 0x6, LV_STYLE_ID_VALUE + 1, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_PATTERN_RECOLOR, 0x6, LV_STYLE_ID_COLOR + 0, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_PATTERN_OPA, 0x6, LV_STYLE_ID_OPA + 0, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_PATTERN_RECOLOR_OPA, 0x6, LV_STYLE_ID_OPA + 1, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_PATTERN_IMAGE, 0x6, LV_STYLE_ID_PTR + 0, LV_STYLE_ATTR_NONE),
|
||||
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_VALUE_LETTER_SPACE, 0x7, LV_STYLE_ID_VALUE + 0, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_VALUE_LINE_SPACE, 0x7, LV_STYLE_ID_VALUE + 1, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_VALUE_BLEND_MODE, 0x7, LV_STYLE_ID_VALUE + 2, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_VALUE_OFS_X, 0x7, LV_STYLE_ID_VALUE + 3, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_VALUE_OFS_Y, 0x7, LV_STYLE_ID_VALUE + 4, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_VALUE_ALIGN, 0x7, LV_STYLE_ID_VALUE + 5, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_VALUE_COLOR, 0x7, LV_STYLE_ID_COLOR + 0, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_VALUE_OPA, 0x7, LV_STYLE_ID_OPA + 0, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_VALUE_FONT, 0x7, LV_STYLE_ID_PTR + 0, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_VALUE_STR, 0x7, LV_STYLE_ID_PTR + 1, LV_STYLE_ATTR_NONE),
|
||||
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_TEXT_LETTER_SPACE, 0x8, LV_STYLE_ID_VALUE + 0, LV_STYLE_ATTR_INHERIT),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_TEXT_LINE_SPACE, 0x8, LV_STYLE_ID_VALUE + 1, LV_STYLE_ATTR_INHERIT),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_TEXT_DECOR, 0x8, LV_STYLE_ID_VALUE + 2, LV_STYLE_ATTR_INHERIT),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_TEXT_BLEND_MODE, 0x8, LV_STYLE_ID_VALUE + 3, LV_STYLE_ATTR_INHERIT),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_TEXT_COLOR, 0x8, LV_STYLE_ID_COLOR + 0, LV_STYLE_ATTR_INHERIT),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_TEXT_SEL_COLOR, 0x8, LV_STYLE_ID_COLOR + 1, LV_STYLE_ATTR_INHERIT),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_TEXT_SEL_BG_COLOR, 0x8, LV_STYLE_ID_COLOR + 2, LV_STYLE_ATTR_INHERIT),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_TEXT_OPA, 0x8, LV_STYLE_ID_OPA + 0, LV_STYLE_ATTR_INHERIT),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_TEXT_FONT, 0x8, LV_STYLE_ID_PTR + 0, LV_STYLE_ATTR_INHERIT),
|
||||
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_LINE_WIDTH, 0x9, LV_STYLE_ID_VALUE + 0, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_LINE_BLEND_MODE, 0x9, LV_STYLE_ID_VALUE + 1, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_LINE_DASH_WIDTH, 0x9, LV_STYLE_ID_VALUE + 2, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_LINE_DASH_GAP, 0x9, LV_STYLE_ID_VALUE + 3, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_LINE_ROUNDED, 0x9, LV_STYLE_ID_VALUE + 4, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_LINE_COLOR, 0x9, LV_STYLE_ID_COLOR + 0, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_LINE_OPA, 0x9, LV_STYLE_ID_OPA + 0, LV_STYLE_ATTR_NONE),
|
||||
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_IMAGE_BLEND_MODE, 0xA, LV_STYLE_ID_VALUE + 0, LV_STYLE_ATTR_INHERIT),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_IMAGE_RECOLOR, 0xA, LV_STYLE_ID_COLOR + 0, LV_STYLE_ATTR_INHERIT),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_IMAGE_OPA, 0xA, LV_STYLE_ID_OPA + 0, LV_STYLE_ATTR_INHERIT),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_IMAGE_RECOLOR_OPA, 0xA, LV_STYLE_ID_OPA + 1, LV_STYLE_ATTR_INHERIT),
|
||||
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_TRANSITION_TIME, 0xB, LV_STYLE_ID_VALUE + 0, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_TRANSITION_DELAY, 0xB, LV_STYLE_ID_VALUE + 1, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_TRANSITION_PROP_1, 0xB, LV_STYLE_ID_VALUE + 2, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_TRANSITION_PROP_2, 0xB, LV_STYLE_ID_VALUE + 3, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_TRANSITION_PROP_3, 0xB, LV_STYLE_ID_VALUE + 4, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_TRANSITION_PROP_4, 0xB, LV_STYLE_ID_VALUE + 5, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_TRANSITION_PROP_5, 0xB, LV_STYLE_ID_VALUE + 6, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_TRANSITION_PROP_6, 0xB, LV_STYLE_ID_VALUE + 7, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_TRANSITION_PATH, 0xB, LV_STYLE_ID_PTR + 0, LV_STYLE_ATTR_NONE),
|
||||
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_SCALE_WIDTH, 0xC, LV_STYLE_ID_VALUE + 0, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_SCALE_BORDER_WIDTH, 0xC, LV_STYLE_ID_VALUE + 1, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_SCALE_END_BORDER_WIDTH, 0xC, LV_STYLE_ID_VALUE + 2, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_SCALE_END_LINE_WIDTH, 0xC, LV_STYLE_ID_VALUE + 3, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_SCALE_GRAD_COLOR, 0xC, LV_STYLE_ID_COLOR + 0, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_SCALE_END_COLOR, 0xC, LV_STYLE_ID_COLOR + 1, LV_STYLE_ATTR_NONE),
|
||||
};
|
||||
|
||||
typedef uint16_t lv_style_property_t;
|
||||
|
||||
#define LV_STYLE_STATE_POS 8
|
||||
#define LV_STYLE_STATE_MASK 0x7F00
|
||||
#define LV_STYLE_INHERIT_MASK 0x8000
|
||||
|
||||
typedef uint16_t lv_style_state_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t * map;
|
||||
#if LV_USE_ASSERT_STYLE
|
||||
uint32_t sentinel;
|
||||
#endif
|
||||
} lv_style_t;
|
||||
|
||||
typedef int16_t lv_style_int_t;
|
||||
|
||||
typedef struct {
|
||||
lv_style_t ** style_list;
|
||||
#if LV_USE_ASSERT_STYLE
|
||||
uint32_t sentinel;
|
||||
#endif
|
||||
uint32_t style_cnt : 6;
|
||||
uint32_t has_local : 1;
|
||||
uint32_t has_trans : 1;
|
||||
uint32_t skip_trans : 1; /*1: Temporally skip the transition style if any*/
|
||||
uint32_t ignore_trans : 1; /*1: Mark that this style list shouldn't receive transitions at all*/
|
||||
uint32_t valid_cache : 1; /*1: The cache is valid and can be used*/
|
||||
uint32_t ignore_cache : 1; /*1: Ignore cache while getting value of properties*/
|
||||
|
||||
uint32_t radius_zero : 1;
|
||||
uint32_t opa_scale_cover : 1;
|
||||
uint32_t clip_corner_off : 1;
|
||||
uint32_t transform_all_zero : 1;
|
||||
uint32_t pad_all_zero : 1;
|
||||
uint32_t margin_all_zero : 1;
|
||||
uint32_t blend_mode_all_normal : 1;
|
||||
uint32_t bg_opa_transp : 1;
|
||||
uint32_t bg_opa_cover : 1;
|
||||
|
||||
uint32_t border_width_zero : 1;
|
||||
uint32_t border_side_full : 1;
|
||||
uint32_t border_post_off : 1;
|
||||
|
||||
uint32_t outline_width_zero : 1;
|
||||
uint32_t pattern_img_null : 1;
|
||||
uint32_t shadow_width_zero : 1;
|
||||
uint32_t value_txt_str : 1;
|
||||
uint32_t img_recolor_opa_transp : 1;
|
||||
|
||||
uint32_t text_space_zero : 1;
|
||||
uint32_t text_decor_none : 1;
|
||||
uint32_t text_font_normal : 1;
|
||||
} lv_style_list_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Initialize a style
|
||||
* @param style pointer to a style to initialize
|
||||
*/
|
||||
void lv_style_init(lv_style_t * style);
|
||||
|
||||
/**
|
||||
* Copy a style with all its properties
|
||||
* @param style_dest pointer to the destination style. (Should be initialized with `lv_style_init()`)
|
||||
* @param style_src pointer to the source (to copy )style
|
||||
*/
|
||||
void lv_style_copy(lv_style_t * style_dest, const lv_style_t * style_src);
|
||||
|
||||
/**
|
||||
* Initialize a style list
|
||||
* @param list a style list to initialize
|
||||
*/
|
||||
void lv_style_list_init(lv_style_list_t * list);
|
||||
|
||||
/**
|
||||
* Copy a style list with all its styles and local style properties
|
||||
* @param list_dest pointer to the destination style list. (should be initialized with `lv_style_list_init()`)
|
||||
* @param list_src pointer to the source (to copy) style list.
|
||||
*/
|
||||
void lv_style_list_copy(lv_style_list_t * list_dest, const lv_style_list_t * list_src);
|
||||
|
||||
/**
|
||||
* Add a style to a style list.
|
||||
* Only the style pointer will be saved so the shouldn't be a local variable.
|
||||
* (It should be static, global or dynamically allocated)
|
||||
* @param list pointer to a style list
|
||||
* @param style pointer to a style to add
|
||||
*/
|
||||
void _lv_style_list_add_style(lv_style_list_t * list, lv_style_t * style);
|
||||
|
||||
/**
|
||||
* Remove a style from a style list
|
||||
* @param style_list pointer to a style list
|
||||
* @param style pointer to a style to remove
|
||||
*/
|
||||
void _lv_style_list_remove_style(lv_style_list_t * list, lv_style_t * style);
|
||||
|
||||
/**
|
||||
* Remove all styles added from style list, clear the local style, transition style and free all allocated memories.
|
||||
* Leave `ignore_trans` flag as it is.
|
||||
* @param list pointer to a style list.
|
||||
*/
|
||||
void _lv_style_list_reset(lv_style_list_t * style_list);
|
||||
|
||||
static inline lv_style_t * lv_style_list_get_style(lv_style_list_t * list, uint8_t id)
|
||||
{
|
||||
if(list->has_trans && list->skip_trans) id++;
|
||||
if(list->style_cnt == 0 || id >= list->style_cnt) return NULL;
|
||||
return list->style_list[id];
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all properties from a style and all allocated memories.
|
||||
* @param style pointer to a style
|
||||
*/
|
||||
void lv_style_reset(lv_style_t * style);
|
||||
|
||||
/**
|
||||
* Get the size of the properties in a style in bytes
|
||||
* @param style pointer to a style
|
||||
* @return size of the properties in bytes
|
||||
*/
|
||||
uint16_t _lv_style_get_mem_size(const lv_style_t * style);
|
||||
|
||||
/**
|
||||
* Copy a style to an other
|
||||
* @param dest pointer to the destination style
|
||||
* @param src pointer to the source style
|
||||
*/
|
||||
void lv_style_copy(lv_style_t * dest, const lv_style_t * src);
|
||||
|
||||
/**
|
||||
* Remove a property from a style
|
||||
* @param style pointer to a style
|
||||
* @param prop a style property ORed with a state.
|
||||
* E.g. `LV_STYLE_BORDER_WIDTH | (LV_STATE_PRESSED << LV_STYLE_STATE_POS)`
|
||||
* @return true: the property was found and removed; false: the property wasn't found
|
||||
*/
|
||||
bool lv_style_remove_prop(lv_style_t * style, lv_style_property_t prop);
|
||||
|
||||
/**
|
||||
* Set an integer typed property in a style.
|
||||
* @param style pointer to a style where the property should be set
|
||||
* @param prop a style property ORed with a state.
|
||||
* E.g. `LV_STYLE_BORDER_WIDTH | (LV_STATE_PRESSED << LV_STYLE_STATE_POS)`
|
||||
* @param value the value to set
|
||||
* @note shouldn't be used directly. Use the specific property set functions instead.
|
||||
* For example: `lv_style_set_border_width()`
|
||||
* @note for performance reasons it's not checked if the property really has integer type
|
||||
*/
|
||||
void _lv_style_set_int(lv_style_t * style, lv_style_property_t prop, lv_style_int_t value);
|
||||
|
||||
/**
|
||||
* Set a color typed property in a style.
|
||||
* @param style pointer to a style where the property should be set
|
||||
* @param prop a style property ORed with a state.
|
||||
* E.g. `LV_STYLE_BORDER_COLOR | (LV_STATE_PRESSED << LV_STYLE_STATE_POS)`
|
||||
* @param value the value to set
|
||||
* @note shouldn't be used directly. Use the specific property set functions instead.
|
||||
* For example: `lv_style_set_border_color()`
|
||||
* @note for performance reasons it's not checked if the property really has color type
|
||||
*/
|
||||
void _lv_style_set_color(lv_style_t * style, lv_style_property_t prop, lv_color_t color);
|
||||
|
||||
/**
|
||||
* Set an opacity typed property in a style.
|
||||
* @param style pointer to a style where the property should be set
|
||||
* @param prop a style property ORed with a state.
|
||||
* E.g. `LV_STYLE_BORDER_OPA | (LV_STATE_PRESSED << LV_STYLE_STATE_POS)`
|
||||
* @param value the value to set
|
||||
* @note shouldn't be used directly. Use the specific property set functions instead.
|
||||
* For example: `lv_style_set_border_opa()`
|
||||
* @note for performance reasons it's not checked if the property really has opacity type
|
||||
*/
|
||||
void _lv_style_set_opa(lv_style_t * style, lv_style_property_t prop, lv_opa_t opa);
|
||||
|
||||
/**
|
||||
* Set a pointer typed property in a style.
|
||||
* @param style pointer to a style where the property should be set
|
||||
* @param prop a style property ORed with a state.
|
||||
* E.g. `LV_STYLE_TEXT_POINTER | (LV_STATE_PRESSED << LV_STYLE_STATE_POS)`
|
||||
* @param value the value to set
|
||||
* @note shouldn't be used directly. Use the specific property set functions instead.
|
||||
* For example: `lv_style_set_border_width()`
|
||||
* @note for performance reasons it's not checked if the property really has pointer type
|
||||
*/
|
||||
void _lv_style_set_ptr(lv_style_t * style, lv_style_property_t prop, const void * p);
|
||||
|
||||
/**
|
||||
* Get an integer typed property from a style.
|
||||
* @param style pointer to a style from where the property should be get
|
||||
* @param prop a style property ORed with a state.
|
||||
* E.g. `LV_STYLE_BORDER_WIDTH | (LV_STATE_PRESSED << LV_STYLE_STATE_POS)`
|
||||
* @param res pointer to a buffer to store the result value
|
||||
* @return -1: the property wasn't found in the style.
|
||||
* The matching state bits of the desired state (in `prop`) and the best matching property's state
|
||||
* Higher value means match in higher precedence state.
|
||||
* @note shouldn't be used directly. Use the specific property get functions instead.
|
||||
* For example: `lv_style_get_border_width()`
|
||||
* @note for performance reasons it's not checked if the property really has integer type
|
||||
*/
|
||||
int16_t _lv_style_get_int(const lv_style_t * style, lv_style_property_t prop, lv_style_int_t * res);
|
||||
|
||||
/**
|
||||
* Get a color typed property from a style.
|
||||
* @param style pointer to a style from where the property should be get
|
||||
* @param prop a style property ORed with a state.
|
||||
* E.g. `LV_STYLE_BORDER_COLOR | (LV_STATE_PRESSED << LV_STYLE_STATE_POS)`
|
||||
* @param res pointer to a buffer to store the result value
|
||||
* @return -1: the property wasn't found in the style.
|
||||
* The matching state bits of the desired state (in `prop`) and the best matching property's state
|
||||
* Higher value means match in higher precedence state.
|
||||
* @note shouldn't be used directly. Use the specific property get functions instead.
|
||||
* For example: `lv_style_get_border_color()`
|
||||
* @note for performance reasons it's not checked if the property really has color type
|
||||
*/
|
||||
int16_t _lv_style_get_color(const lv_style_t * style, lv_style_property_t prop, lv_color_t * res);
|
||||
|
||||
/**
|
||||
* Get an opacity typed property from a style.
|
||||
* @param style pointer to a style from where the property should be get
|
||||
* @param prop a style property ORed with a state.
|
||||
* E.g. `LV_STYLE_BORDER_OPA | (LV_STATE_PRESSED << LV_STYLE_STATE_POS)`
|
||||
* @param res pointer to a buffer to store the result value
|
||||
* @return -1: the property wasn't found in the style.
|
||||
* The matching state bits of the desired state (in `prop`) and the best matching property's state
|
||||
* Higher value means match in higher precedence state.
|
||||
* @note shouldn't be used directly. Use the specific property get functions instead.
|
||||
* For example: `lv_style_get_border_opa()`
|
||||
* @note for performance reasons it's not checked if the property really has opacity type
|
||||
*/
|
||||
int16_t _lv_style_get_opa(const lv_style_t * style, lv_style_property_t prop, lv_opa_t * res);
|
||||
|
||||
/**
|
||||
* Get a pointer typed property from a style.
|
||||
* @param style pointer to a style from where the property should be get
|
||||
* @param prop a style property ORed with a state.
|
||||
* E.g. `LV_STYLE_TEXT_FONT | (LV_STATE_PRESSED << LV_STYLE_STATE_POS)`
|
||||
* @param res pointer to a buffer to store the result value
|
||||
* @return -1: the property wasn't found in the style.
|
||||
* The matching state bits of the desired state (in `prop`) and the best matching property's state
|
||||
* Higher value means match in higher precedence state.
|
||||
* @note shouldn't be used directly. Use the specific property get functions instead.
|
||||
* For example: `lv_style_get_text_font()`
|
||||
* @note for performance reasons it's not checked if the property really has pointer type
|
||||
*/
|
||||
int16_t _lv_style_get_ptr(const lv_style_t * style, lv_style_property_t prop, const void ** res);
|
||||
|
||||
/**
|
||||
* Get the local style of a style list
|
||||
* @param list pointer to a style list where the local property should be set
|
||||
* @return pointer to the local style if exists else `NULL`.
|
||||
*/
|
||||
lv_style_t * lv_style_list_get_local_style(lv_style_list_t * list);
|
||||
|
||||
/**
|
||||
* Get the transition style of a style list
|
||||
* @param list pointer to a style list where the transition property should be set
|
||||
* @return pointer to the transition style if exists else `NULL`.
|
||||
*/
|
||||
lv_style_t * _lv_style_list_get_transition_style(lv_style_list_t * list);
|
||||
|
||||
/**
|
||||
* Allocate the transition style in a style list. If already exists simply return it.
|
||||
* @param list pointer to a style list
|
||||
* @return the transition style of a style list
|
||||
*/
|
||||
lv_style_t * _lv_style_list_add_trans_style(lv_style_list_t * list);
|
||||
|
||||
/**
|
||||
* Set a local integer typed property in a style list.
|
||||
* @param list pointer to a style list where the local property should be set
|
||||
* @param prop a style property ORed with a state.
|
||||
* E.g. `LV_STYLE_BORDER_WIDTH | (LV_STATE_PRESSED << LV_STYLE_STATE_POS)`
|
||||
* @param value the value to set
|
||||
* @note for performance reasons it's not checked if the property really has integer type
|
||||
*/
|
||||
void _lv_style_list_set_local_int(lv_style_list_t * list, lv_style_property_t prop, lv_style_int_t value);
|
||||
|
||||
/**
|
||||
* Set a local color typed property in a style list.
|
||||
* @param list pointer to a style list where the local property should be set
|
||||
* @param prop a style property ORed with a state.
|
||||
* E.g. `LV_STYLE_BORDER_COLOR | (LV_STATE_PRESSED << LV_STYLE_STATE_POS)`
|
||||
* @param value the value to set
|
||||
* @note for performance reasons it's not checked if the property really has color type
|
||||
*/
|
||||
void _lv_style_list_set_local_color(lv_style_list_t * list, lv_style_property_t prop, lv_color_t value);
|
||||
|
||||
/**
|
||||
* Set a local opacity typed property in a style list.
|
||||
* @param list pointer to a style list where the local property should be set
|
||||
* @param prop a style property ORed with a state.
|
||||
* E.g. `LV_STYLE_BORDER_OPA | (LV_STATE_PRESSED << LV_STYLE_STATE_POS)`
|
||||
* @param value the value to set
|
||||
* @note for performance reasons it's not checked if the property really has opacity type
|
||||
*/
|
||||
void _lv_style_list_set_local_opa(lv_style_list_t * list, lv_style_property_t prop, lv_opa_t value);
|
||||
|
||||
/**
|
||||
* Set a local pointer typed property in a style list.
|
||||
* @param list pointer to a style list where the local property should be set
|
||||
* @param prop a style property ORed with a state.
|
||||
* E.g. `LV_STYLE_TEXT_FONT | (LV_STATE_PRESSED << LV_STYLE_STATE_POS)`
|
||||
* @param value the value to set
|
||||
* @note for performance reasons it's not checked if the property really has pointer type
|
||||
*/
|
||||
void _lv_style_list_set_local_ptr(lv_style_list_t * list, lv_style_property_t prop, const void * value);
|
||||
|
||||
/**
|
||||
* Get an integer typed property from a style list.
|
||||
* It will return the property which match best with given state.
|
||||
* @param list pointer to a style list from where the property should be get
|
||||
* @param prop a style property ORed with a state.
|
||||
* E.g. `LV_STYLE_BORDER_WIDTH | (LV_STATE_PRESSED << LV_STYLE_STATE_POS)`
|
||||
* @param res pointer to a buffer to store the result
|
||||
* @return LV_RES_OK: there was a matching property in the list
|
||||
* LV_RES_INV: there was NO matching property in the list
|
||||
* @note for performance reasons it's not checked if the property really has integer type
|
||||
*/
|
||||
lv_res_t _lv_style_list_get_int(lv_style_list_t * list, lv_style_property_t prop, lv_style_int_t * res);
|
||||
|
||||
/**
|
||||
* Get a color typed property from a style list.
|
||||
* It will return the property which match best with given state.
|
||||
* @param list pointer to a style list from where the property should be get
|
||||
* @param prop a style property ORed with a state.
|
||||
* E.g. `LV_STYLE_BORDER_COLOR | (LV_STATE_PRESSED << LV_STYLE_STATE_POS)`
|
||||
* @param res pointer to a buffer to store the result
|
||||
* @return LV_RES_OK: there was a matching property in the list
|
||||
* LV_RES_INV: there was NO matching property in the list
|
||||
* @note for performance reasons it's not checked if the property really has color type
|
||||
*/
|
||||
lv_res_t _lv_style_list_get_color(lv_style_list_t * list, lv_style_property_t prop, lv_color_t * res);
|
||||
|
||||
/**
|
||||
* Get an opacity typed property from a style list.
|
||||
* It will return the property which match best with given state.
|
||||
* @param list pointer to a style list from where the property should be get
|
||||
* @param prop a style property ORed with a state.
|
||||
* E.g. `LV_STYLE_BORDER_OPA | (LV_STATE_PRESSED << LV_STYLE_STATE_POS)`
|
||||
* @param res pointer to a buffer to store the result
|
||||
* @return LV_RES_OK: there was a matching property in the list
|
||||
* LV_RES_INV: there was NO matching property in the list
|
||||
* @note for performance reasons it's not checked if the property really has opacity type
|
||||
*/
|
||||
lv_res_t _lv_style_list_get_opa(lv_style_list_t * list, lv_style_property_t prop, lv_opa_t * res);
|
||||
|
||||
/**
|
||||
* Get a pointer typed property from a style list.
|
||||
* It will return the property which match best with given state.
|
||||
* @param list pointer to a style list from where the property should be get
|
||||
* @param prop a style property ORed with a state.
|
||||
* E.g. `LV_STYLE_TEXT_FONT | (LV_STATE_PRESSED << LV_STYLE_STATE_POS)`
|
||||
* @param res pointer to a buffer to store the result
|
||||
* @return LV_RES_OK: there was a matching property in the list
|
||||
* LV_RES_INV: there was NO matching property in the list
|
||||
* @note for performance reasons it's not checked if the property really has pointer type
|
||||
*/
|
||||
lv_res_t _lv_style_list_get_ptr(lv_style_list_t * list, lv_style_property_t prop, const void ** res);
|
||||
|
||||
/**
|
||||
* Check whether a style is valid (initialized correctly)
|
||||
* @param style pointer to a style
|
||||
* @return true: valid
|
||||
*/
|
||||
bool lv_debug_check_style(const lv_style_t * style);
|
||||
|
||||
/**
|
||||
* Check whether a style list is valid (initialized correctly)
|
||||
* @param list pointer to a style list
|
||||
* @return true: valid
|
||||
*/
|
||||
bool lv_debug_check_style_list(const lv_style_list_t * list);
|
||||
|
||||
/*************************
|
||||
* GLOBAL VARIABLES
|
||||
*************************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Create and initialize a `static` style
|
||||
* Example:
|
||||
* LV_STYLE_CREATE(my_style, &style_to_copy);
|
||||
* is equivalent to
|
||||
* static lv_style_t my_style;
|
||||
* lv_style_init(&my_style);
|
||||
* lv_style_copy(&my_style, &style_to_copy);
|
||||
*/
|
||||
#define LV_STYLE_CREATE(name, copy_p) static lv_style_t name; lv_style_init(&name); lv_style_copy(&name, copy_p)
|
||||
|
||||
#if LV_USE_DEBUG
|
||||
|
||||
# ifndef LV_DEBUG_IS_STYLE
|
||||
# define LV_DEBUG_IS_STYLE(style_p) (lv_debug_check_style(style_p))
|
||||
# endif
|
||||
|
||||
# ifndef LV_DEBUG_IS_STYLE_LIST
|
||||
# define LV_DEBUG_IS_STYLE_LIST(list_p) (lv_debug_check_style_list(list_p))
|
||||
# endif
|
||||
|
||||
# if LV_USE_ASSERT_STYLE
|
||||
# ifndef LV_ASSERT_STYLE
|
||||
# define LV_ASSERT_STYLE(style_p) LV_DEBUG_ASSERT(LV_DEBUG_IS_STYLE(style_p), "Invalid style", style_p);
|
||||
# endif
|
||||
# ifndef LV_ASSERT_STYLE_LIST
|
||||
# define LV_ASSERT_STYLE_LIST(list_p) LV_DEBUG_ASSERT(LV_DEBUG_IS_STYLE_LIST(list_p), "Invalid style list", list_p);
|
||||
# endif
|
||||
# else
|
||||
# define LV_ASSERT_STYLE(style_p)
|
||||
# define LV_ASSERT_STYLE_LIST(list_p)
|
||||
# endif
|
||||
|
||||
#else
|
||||
# define LV_ASSERT_STYLE(p)
|
||||
# define LV_ASSERT_STYLE_LIST(p)
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_STYLE_H*/
|
Reference in New Issue
Block a user