mirror of
https://github.com/lvgl/lvgl.git
synced 2025-01-28 07:03:00 +08:00
run clang format
This commit is contained in:
parent
80e2a1d5d5
commit
ba2160042a
@ -35,7 +35,8 @@
|
||||
|
||||
/**
|
||||
* 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)
|
||||
* @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)
|
||||
@ -79,7 +80,8 @@ 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)
|
||||
* 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)
|
||||
*/
|
||||
@ -147,7 +149,7 @@ uint32_t lv_disp_get_inactive_time(const lv_disp_t * disp)
|
||||
|
||||
lv_disp_t * d;
|
||||
uint32_t t = UINT32_MAX;
|
||||
d = lv_disp_get_next(NULL);
|
||||
d = lv_disp_get_next(NULL);
|
||||
while(d) {
|
||||
t = LV_MATH_MIN(t, lv_tick_elaps(d->last_activity_time));
|
||||
d = lv_disp_get_next(d);
|
||||
|
@ -30,7 +30,8 @@ extern "C" {
|
||||
|
||||
/**
|
||||
* 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)
|
||||
* @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);
|
||||
@ -49,7 +50,8 @@ void lv_disp_set_scr_act(lv_obj_t * scr);
|
||||
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)
|
||||
* 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)
|
||||
*/
|
||||
@ -68,7 +70,7 @@ void lv_disp_assign_screen(lv_disp_t * disp, lv_obj_t * scr);
|
||||
* @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) ;
|
||||
lv_task_t * lv_disp_get_refr_task(lv_disp_t * disp);
|
||||
|
||||
/**
|
||||
* Get elapsed time since last user activity on a display (e.g. click)
|
||||
@ -95,7 +97,6 @@ void lv_disp_trig_activity(lv_disp_t * disp);
|
||||
static inline lv_obj_t * lv_scr_act(void)
|
||||
{
|
||||
return lv_disp_get_scr_act(lv_disp_get_default());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -121,7 +122,6 @@ static inline void lv_scr_load(lv_obj_t * scr)
|
||||
lv_disp_set_scr_act(scr);
|
||||
}
|
||||
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
@ -13,7 +13,7 @@
|
||||
#include "../lv_misc/lv_gc.h"
|
||||
|
||||
#if defined(LV_GC_INCLUDE)
|
||||
# include LV_GC_INCLUDE
|
||||
#include LV_GC_INCLUDE
|
||||
#endif /* LV_ENABLE_GC */
|
||||
|
||||
/*********************
|
||||
@ -30,12 +30,11 @@
|
||||
static void style_mod_def(lv_group_t * group, lv_style_t * style);
|
||||
static void style_mod_edit_def(lv_group_t * group, lv_style_t * style);
|
||||
static void refresh_theme(lv_group_t * g, lv_theme_t * th);
|
||||
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 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
|
||||
**********************/
|
||||
@ -67,13 +66,13 @@ lv_group_t * lv_group_create(void)
|
||||
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->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;
|
||||
group->wrap = 1;
|
||||
|
||||
#if LV_USE_USER_DATA_SINGLE
|
||||
memset(&group->user_data, 0, sizeof(lv_group_user_data_t));
|
||||
@ -85,7 +84,6 @@ lv_group_t * lv_group_create(void)
|
||||
memset(&group->style_mod_edit_user_data, 0, sizeof(lv_group_user_data_t));
|
||||
#endif
|
||||
|
||||
|
||||
/*Initialize style modification callbacks from current theme*/
|
||||
refresh_theme(group, lv_theme_get_current());
|
||||
|
||||
@ -106,7 +104,8 @@ void lv_group_del(lv_group_t * group)
|
||||
|
||||
/*Remove the objects from the group*/
|
||||
lv_obj_t ** obj;
|
||||
LV_LL_READ(group->obj_ll, obj) {
|
||||
LV_LL_READ(group->obj_ll, obj)
|
||||
{
|
||||
(*obj)->group_p = NULL;
|
||||
}
|
||||
|
||||
@ -125,7 +124,8 @@ void lv_group_add_obj(lv_group_t * group, lv_obj_t * obj)
|
||||
|
||||
/*Do not add the object twice*/
|
||||
lv_obj_t ** obj_i;
|
||||
LV_LL_READ(group->obj_ll, 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;
|
||||
@ -141,7 +141,7 @@ void lv_group_add_obj(lv_group_t * group, lv_obj_t * obj)
|
||||
}
|
||||
}
|
||||
|
||||
obj->group_p = group;
|
||||
obj->group_p = group;
|
||||
lv_obj_t ** next = lv_ll_ins_tail(&group->obj_ll);
|
||||
lv_mem_assert(next);
|
||||
if(next == NULL) return;
|
||||
@ -162,12 +162,14 @@ void lv_group_remove_obj(lv_obj_t * obj)
|
||||
{
|
||||
lv_group_t * g = obj->group_p;
|
||||
if(g == NULL) return;
|
||||
if(g->obj_focus == NULL) return; /*Just to be sure (Not possible if there is at least one object in the group)*/
|
||||
if(g->obj_focus == NULL)
|
||||
return; /*Just to be sure (Not possible if there is at least one object in the group)*/
|
||||
|
||||
/*Focus on the next object*/
|
||||
if(*g->obj_focus == obj) {
|
||||
/*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) {
|
||||
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*/
|
||||
@ -176,15 +178,17 @@ void lv_group_remove_obj(lv_obj_t * obj)
|
||||
}
|
||||
}
|
||||
|
||||
/* 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 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) {
|
||||
LV_LL_READ(g->obj_ll, i)
|
||||
{
|
||||
if(*i == obj) {
|
||||
lv_ll_rem(&g->obj_ll, i);
|
||||
lv_mem_free(i);
|
||||
@ -210,9 +214,10 @@ void lv_group_focus_obj(lv_obj_t * obj)
|
||||
lv_group_set_editing(g, false);
|
||||
|
||||
lv_obj_t ** i;
|
||||
LV_LL_READ(g->obj_ll, i) {
|
||||
LV_LL_READ(g->obj_ll, i)
|
||||
{
|
||||
if(*i == obj) {
|
||||
if(g->obj_focus == i) return; /*Don't focus the already focused object again*/
|
||||
if(g->obj_focus == i) return; /*Don't focus the already focused object again*/
|
||||
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);
|
||||
@ -262,8 +267,10 @@ void lv_group_focus_prev(lv_group_t * group)
|
||||
*/
|
||||
void lv_group_focus_freeze(lv_group_t * group, bool en)
|
||||
{
|
||||
if(en == false) group->frozen = 0;
|
||||
else group->frozen = 1;
|
||||
if(en == false)
|
||||
group->frozen = 0;
|
||||
else
|
||||
group->frozen = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -321,13 +328,14 @@ void lv_group_set_editing(lv_group_t * group, bool edit)
|
||||
{
|
||||
uint8_t en_val = edit ? 1 : 0;
|
||||
|
||||
if(en_val == group->editing) return; /*Do not set the same mode again*/
|
||||
if(en_val == group->editing) return; /*Do not set the same mode again*/
|
||||
|
||||
group->editing = en_val;
|
||||
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*/
|
||||
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;
|
||||
}
|
||||
@ -345,7 +353,8 @@ 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) {
|
||||
void lv_group_set_refocus_policy(lv_group_t * group, lv_group_refocus_policy_t policy)
|
||||
{
|
||||
group->refocus_policy = policy & 0x01;
|
||||
}
|
||||
|
||||
@ -403,7 +412,6 @@ lv_group_user_data_t * lv_group_get_user_data(lv_group_t * group)
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* Get a the style modifier function of a group
|
||||
* @param group pointer to a group
|
||||
@ -412,7 +420,7 @@ lv_group_user_data_t * lv_group_get_user_data(lv_group_t * group)
|
||||
lv_group_style_mod_func_t lv_group_get_style_mod_cb(const lv_group_t * group)
|
||||
{
|
||||
if(!group) return false;
|
||||
return group->style_mod ;
|
||||
return group->style_mod;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -471,7 +479,8 @@ bool lv_group_get_wrap(lv_group_t * group)
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify the group that current theme changed and style modification callbacks need to be refreshed.
|
||||
* Notify the group that current theme changed and style modification callbacks need to be
|
||||
* refreshed.
|
||||
* @param group pointer to group. If NULL then all groups are notified.
|
||||
*/
|
||||
void lv_group_report_style_mod(lv_group_t * group)
|
||||
@ -484,7 +493,8 @@ void lv_group_report_style_mod(lv_group_t * group)
|
||||
}
|
||||
|
||||
lv_group_t * i;
|
||||
LV_LL_READ(LV_GC_ROOT(_lv_group_ll), i) {
|
||||
LV_LL_READ(LV_GC_ROOT(_lv_group_ll), i)
|
||||
{
|
||||
refresh_theme(i, th);
|
||||
}
|
||||
}
|
||||
@ -493,10 +503,11 @@ void lv_group_report_style_mod(lv_group_t * group)
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static void lv_group_refocus(lv_group_t *g) {
|
||||
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;
|
||||
g->wrap = 1;
|
||||
|
||||
if(g->refocus_policy == LV_GROUP_REFOCUS_POLICY_NEXT)
|
||||
lv_group_focus_next(g);
|
||||
@ -513,28 +524,28 @@ static void lv_group_refocus(lv_group_t *g) {
|
||||
*/
|
||||
static void style_mod_def(lv_group_t * group, lv_style_t * style)
|
||||
{
|
||||
(void)group; /*Unused*/
|
||||
(void)group; /*Unused*/
|
||||
#if LV_COLOR_DEPTH != 1
|
||||
|
||||
/*Make the style to be a little bit orange*/
|
||||
style->body.border.opa = LV_OPA_COVER;
|
||||
style->body.border.opa = LV_OPA_COVER;
|
||||
style->body.border.color = LV_COLOR_ORANGE;
|
||||
|
||||
/*If not empty or has border then emphasis the border*/
|
||||
if(style->body.opa != LV_OPA_TRANSP || style->body.border.width != 0) style->body.border.width = LV_DPI / 20;
|
||||
if(style->body.opa != LV_OPA_TRANSP || style->body.border.width != 0)
|
||||
style->body.border.width = LV_DPI / 20;
|
||||
|
||||
style->body.main_color = lv_color_mix(style->body.main_color, LV_COLOR_ORANGE, LV_OPA_70);
|
||||
style->body.grad_color = lv_color_mix(style->body.grad_color, LV_COLOR_ORANGE, LV_OPA_70);
|
||||
style->body.main_color = lv_color_mix(style->body.main_color, LV_COLOR_ORANGE, LV_OPA_70);
|
||||
style->body.grad_color = lv_color_mix(style->body.grad_color, LV_COLOR_ORANGE, LV_OPA_70);
|
||||
style->body.shadow.color = lv_color_mix(style->body.shadow.color, LV_COLOR_ORANGE, LV_OPA_60);
|
||||
|
||||
style->text.color = lv_color_mix(style->text.color, LV_COLOR_ORANGE, LV_OPA_70);
|
||||
#else
|
||||
style->body.border.opa = LV_OPA_COVER;
|
||||
style->body.border.opa = LV_OPA_COVER;
|
||||
style->body.border.color = LV_COLOR_BLACK;
|
||||
style->body.border.width = 2;
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -544,57 +555,56 @@ static void style_mod_def(lv_group_t * group, lv_style_t * style)
|
||||
*/
|
||||
static void style_mod_edit_def(lv_group_t * group, lv_style_t * style)
|
||||
{
|
||||
(void)group; /*Unused*/
|
||||
(void)group; /*Unused*/
|
||||
#if LV_COLOR_DEPTH != 1
|
||||
|
||||
/*Make the style to be a little bit orange*/
|
||||
style->body.border.opa = LV_OPA_COVER;
|
||||
style->body.border.opa = LV_OPA_COVER;
|
||||
style->body.border.color = LV_COLOR_GREEN;
|
||||
|
||||
/*If not empty or has border then emphasis the border*/
|
||||
if(style->body.opa != LV_OPA_TRANSP || style->body.border.width != 0) style->body.border.width = LV_DPI / 20;
|
||||
if(style->body.opa != LV_OPA_TRANSP || style->body.border.width != 0)
|
||||
style->body.border.width = LV_DPI / 20;
|
||||
|
||||
style->body.main_color = lv_color_mix(style->body.main_color, LV_COLOR_GREEN, LV_OPA_70);
|
||||
style->body.grad_color = lv_color_mix(style->body.grad_color, LV_COLOR_GREEN, LV_OPA_70);
|
||||
style->body.main_color = lv_color_mix(style->body.main_color, LV_COLOR_GREEN, LV_OPA_70);
|
||||
style->body.grad_color = lv_color_mix(style->body.grad_color, LV_COLOR_GREEN, LV_OPA_70);
|
||||
style->body.shadow.color = lv_color_mix(style->body.shadow.color, LV_COLOR_GREEN, LV_OPA_60);
|
||||
|
||||
style->text.color = lv_color_mix(style->text.color, LV_COLOR_GREEN, LV_OPA_70);
|
||||
#else
|
||||
style->body.border.opa = LV_OPA_COVER;
|
||||
style->body.border.opa = LV_OPA_COVER;
|
||||
style->body.border.color = LV_COLOR_BLACK;
|
||||
style->body.border.width = 3;
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
static void refresh_theme(lv_group_t * g, lv_theme_t * th)
|
||||
{
|
||||
g->style_mod = style_mod_def;
|
||||
g->style_mod = style_mod_def;
|
||||
g->style_mod_edit = style_mod_edit_def;
|
||||
if(th) {
|
||||
if(th->group.style_mod)
|
||||
g->style_mod = th->group.style_mod;
|
||||
if(th->group.style_mod_edit)
|
||||
g->style_mod_edit = th->group.style_mod_edit;
|
||||
if(th->group.style_mod) g->style_mod = th->group.style_mod;
|
||||
if(th->group.style_mod_edit) g->style_mod_edit = th->group.style_mod_edit;
|
||||
}
|
||||
}
|
||||
|
||||
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 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;
|
||||
if(group->frozen) return;
|
||||
|
||||
lv_obj_t ** obj_next = group->obj_focus;
|
||||
lv_obj_t ** obj_next = group->obj_focus;
|
||||
lv_obj_t ** obj_sentinel = NULL;
|
||||
bool can_move = true;
|
||||
bool can_begin = true;
|
||||
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;
|
||||
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*/
|
||||
@ -622,7 +632,8 @@ static void focus_next_core(lv_group_t * group, void * (*begin)(const lv_ll_t *)
|
||||
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(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);
|
||||
@ -648,7 +659,7 @@ static void focus_next_core(lv_group_t * group, void * (*begin)(const lv_ll_t *)
|
||||
static void obj_to_foreground(lv_obj_t * obj)
|
||||
{
|
||||
/*Search for 'top' attribute*/
|
||||
lv_obj_t * i = obj;
|
||||
lv_obj_t * i = obj;
|
||||
lv_obj_t * last_top = NULL;
|
||||
while(i != NULL) {
|
||||
if(i->top != 0) last_top = i;
|
||||
|
@ -26,20 +26,20 @@ extern "C" {
|
||||
*********************/
|
||||
/*Predefined keys to control the focused object via lv_group_send(group, c)*/
|
||||
/*For compatibility in signal function define the keys regardless to LV_GROUP*/
|
||||
#define LV_GROUP_KEY_UP 17 /*0x11*/
|
||||
#define LV_GROUP_KEY_DOWN 18 /*0x12*/
|
||||
#define LV_GROUP_KEY_RIGHT 19 /*0x13*/
|
||||
#define LV_GROUP_KEY_LEFT 20 /*0x14*/
|
||||
#define LV_GROUP_KEY_ESC 27 /*0x1B*/
|
||||
#define LV_GROUP_KEY_DEL 127 /*0x7F*/
|
||||
#define LV_GROUP_KEY_BACKSPACE 8 /*0x08*/
|
||||
#define LV_GROUP_KEY_ENTER 10 /*0x0A, '\n'*/
|
||||
#define LV_GROUP_KEY_NEXT 9 /*0x09, '\t'*/
|
||||
#define LV_GROUP_KEY_PREV 11 /*0x0B, '*/
|
||||
#define LV_GROUP_KEY_HOME 2 /*0x02, STX*/
|
||||
#define LV_GROUP_KEY_END 3 /*0x03, ETX*/
|
||||
#define LV_GROUP_KEY_UP 17 /*0x11*/
|
||||
#define LV_GROUP_KEY_DOWN 18 /*0x12*/
|
||||
#define LV_GROUP_KEY_RIGHT 19 /*0x13*/
|
||||
#define LV_GROUP_KEY_LEFT 20 /*0x14*/
|
||||
#define LV_GROUP_KEY_ESC 27 /*0x1B*/
|
||||
#define LV_GROUP_KEY_DEL 127 /*0x7F*/
|
||||
#define LV_GROUP_KEY_BACKSPACE 8 /*0x08*/
|
||||
#define LV_GROUP_KEY_ENTER 10 /*0x0A, '\n'*/
|
||||
#define LV_GROUP_KEY_NEXT 9 /*0x09, '\t'*/
|
||||
#define LV_GROUP_KEY_PREV 11 /*0x0B, '*/
|
||||
#define LV_GROUP_KEY_HOME 2 /*0x02, STX*/
|
||||
#define LV_GROUP_KEY_END 3 /*0x03, ETX*/
|
||||
|
||||
#if LV_USE_GROUP != 0
|
||||
#if LV_USE_GROUP != 0
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
@ -50,33 +50,35 @@ typedef void (*lv_group_focus_cb_t)(struct _lv_group_t *);
|
||||
|
||||
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_style_mod_func_t style_mod; /*A function which modifies the style of the focused object*/
|
||||
lv_group_style_mod_func_t style_mod_edit;/*A function which modifies the style of the focused object*/
|
||||
lv_group_focus_cb_t focus_cb; /*A function to call when a new object is focused (optional)*/
|
||||
lv_style_t style_tmp; /*Stores the modified style of the focused object */
|
||||
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_style_mod_func_t
|
||||
style_mod; /*A function which modifies the style of the focused object*/
|
||||
lv_group_style_mod_func_t
|
||||
style_mod_edit; /*A function which modifies the style of the focused object*/
|
||||
lv_group_focus_cb_t focus_cb; /*A function to call when a new object is focused (optional)*/
|
||||
lv_style_t style_tmp; /*Stores the modified style of the focused object */
|
||||
#if LV_USE_USER_DATA_SINGLE
|
||||
lv_group_user_data_t user_data;
|
||||
lv_group_user_data_t user_data;
|
||||
#endif
|
||||
|
||||
#if LV_USE_USER_DATA_MULTI
|
||||
lv_group_user_data_t focus_user_data;
|
||||
lv_group_user_data_t style_mod_user_data;
|
||||
lv_group_user_data_t style_mod_edit_user_data;
|
||||
lv_group_user_data_t focus_user_data;
|
||||
lv_group_user_data_t style_mod_user_data;
|
||||
lv_group_user_data_t style_mod_edit_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.*/
|
||||
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
|
||||
};
|
||||
enum { LV_GROUP_REFOCUS_POLICY_NEXT = 0, LV_GROUP_REFOCUS_POLICY_PREV = 1 };
|
||||
typedef uint8_t lv_group_refocus_policy_t;
|
||||
|
||||
/**********************
|
||||
@ -84,9 +86,9 @@ typedef uint8_t lv_group_refocus_policy_t;
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Init. the group module
|
||||
* @remarks Internal function, do not call directly.
|
||||
*/
|
||||
* Init. the group module
|
||||
* @remarks Internal function, do not call directly.
|
||||
*/
|
||||
void lv_group_init(void);
|
||||
|
||||
/**
|
||||
@ -169,7 +171,8 @@ void lv_group_set_style_mod_edit_cb(lv_group_t * group, lv_group_style_mod_func_
|
||||
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 focussed obj is deleted.
|
||||
* Set whether the next or previous item in a group is focused if the currently focussed obj is
|
||||
* deleted.
|
||||
* @param group pointer to a group
|
||||
* @param new refocus policy enum
|
||||
*/
|
||||
@ -264,7 +267,8 @@ bool lv_group_get_click_focus(const lv_group_t * group);
|
||||
bool lv_group_get_wrap(lv_group_t * group);
|
||||
|
||||
/**
|
||||
* Notify the group that current theme changed and style modification callbacks need to be refreshed.
|
||||
* Notify the group that current theme changed and style modification callbacks need to be
|
||||
* refreshed.
|
||||
* @param group pointer to group. If NULL then all groups are notified.
|
||||
*/
|
||||
void lv_group_report_style_mod(lv_group_t * group);
|
||||
|
@ -61,7 +61,7 @@ static lv_indev_t * indev_act;
|
||||
*/
|
||||
void lv_indev_init(void)
|
||||
{
|
||||
lv_indev_reset(NULL); /*Reset all input devices*/
|
||||
lv_indev_reset(NULL); /*Reset all input devices*/
|
||||
}
|
||||
|
||||
/**
|
||||
@ -77,7 +77,7 @@ void lv_indev_read_task(void * param)
|
||||
indev_act = param;
|
||||
|
||||
/*Read and process all indevs*/
|
||||
if(indev_act->driver.disp == NULL) return; /*Not assigned to any displays*/
|
||||
if(indev_act->driver.disp == NULL) return; /*Not assigned to any displays*/
|
||||
|
||||
/*Handle reset query before processing the point*/
|
||||
indev_proc_reset_query_handler(indev_act);
|
||||
@ -115,10 +115,10 @@ void lv_indev_read_task(void * param)
|
||||
LV_LOG_TRACE("indev read task finished");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @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)
|
||||
{
|
||||
@ -142,12 +142,13 @@ lv_indev_type_t lv_indev_get_type(const lv_indev_t * indev)
|
||||
*/
|
||||
void lv_indev_reset(lv_indev_t * indev)
|
||||
{
|
||||
if(indev) indev->proc.reset_query = 1;
|
||||
if(indev)
|
||||
indev->proc.reset_query = 1;
|
||||
else {
|
||||
lv_indev_t * i = lv_indev_get_next(NULL);
|
||||
while(i) {
|
||||
i->proc.reset_query = 1;
|
||||
i = lv_indev_get_next(i);
|
||||
i = lv_indev_get_next(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -158,9 +159,9 @@ void lv_indev_reset(lv_indev_t * indev)
|
||||
*/
|
||||
void lv_indev_reset_long_press(lv_indev_t * indev)
|
||||
{
|
||||
indev->proc.long_pr_sent = 0;
|
||||
indev->proc.long_pr_sent = 0;
|
||||
indev->proc.longpr_rep_timestamp = lv_tick_get();
|
||||
indev->proc.pr_timestamp = lv_tick_get();
|
||||
indev->proc.pr_timestamp = lv_tick_get();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -186,7 +187,8 @@ void lv_indev_set_cursor(lv_indev_t * indev, lv_obj_t * cur_obj)
|
||||
|
||||
indev->cursor = cur_obj;
|
||||
lv_obj_set_parent(indev->cursor, lv_disp_get_layer_sys(indev->driver.disp));
|
||||
lv_obj_set_pos(indev->cursor, indev->proc.types.pointer.act_point.x, indev->proc.types.pointer.act_point.y);
|
||||
lv_obj_set_pos(indev->cursor, indev->proc.types.pointer.act_point.x,
|
||||
indev->proc.types.pointer.act_point.y);
|
||||
}
|
||||
|
||||
#if LV_USE_GROUP
|
||||
@ -221,7 +223,7 @@ void lv_indev_set_button_points(lv_indev_t * indev, const lv_point_t * points)
|
||||
* @param indev pointer to an input device
|
||||
* @param feedback feedback callback
|
||||
*/
|
||||
void lv_indev_set_feedback(lv_indev_t *indev, lv_indev_feedback_t feedback)
|
||||
void lv_indev_set_feedback(lv_indev_t * indev, lv_indev_feedback_t feedback)
|
||||
{
|
||||
indev->feedback = feedback;
|
||||
}
|
||||
@ -249,24 +251,29 @@ void lv_indev_get_point(const lv_indev_t * indev, lv_point_t * point)
|
||||
*/
|
||||
uint32_t lv_indev_get_key(const lv_indev_t * indev)
|
||||
{
|
||||
if(indev->driver.type != LV_INDEV_TYPE_KEYPAD) return 0;
|
||||
else return indev->proc.types.keypad.last_key;
|
||||
if(indev->driver.type != LV_INDEV_TYPE_KEYPAD)
|
||||
return 0;
|
||||
else
|
||||
return indev->proc.types.keypad.last_key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if there is dragging with an input device or not (for LV_INDEV_TYPE_POINTER and LV_INDEV_TYPE_BUTTON)
|
||||
* 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)
|
||||
{
|
||||
if(indev == NULL) return false;
|
||||
if(indev->driver.type != LV_INDEV_TYPE_POINTER && indev->driver.type != LV_INDEV_TYPE_BUTTON) return false;
|
||||
if(indev->driver.type != LV_INDEV_TYPE_POINTER && indev->driver.type != LV_INDEV_TYPE_BUTTON)
|
||||
return false;
|
||||
return indev->proc.types.pointer.drag_in_prog == 0 ? false : true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the types.pointer.vector of dragging of an input device (for LV_INDEV_TYPE_POINTER and LV_INDEV_TYPE_BUTTON)
|
||||
* Get the types.pointer.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 types.pointer.vector
|
||||
*/
|
||||
@ -292,7 +299,7 @@ void lv_indev_get_vect(const lv_indev_t * indev, lv_point_t * point)
|
||||
* @param indev pointer to an input device
|
||||
* @return feedback callback
|
||||
*/
|
||||
lv_indev_feedback_t lv_indev_get_feedback(const lv_indev_t *indev)
|
||||
lv_indev_feedback_t lv_indev_get_feedback(const lv_indev_t * indev)
|
||||
{
|
||||
return indev->feedback;
|
||||
}
|
||||
@ -334,9 +341,8 @@ lv_task_t * lv_indev_get_read_task(lv_disp_t * indev)
|
||||
static void indev_pointer_proc(lv_indev_t * i, lv_indev_data_t * data)
|
||||
{
|
||||
/*Move the cursor if set and moved*/
|
||||
if(i->cursor != NULL &&
|
||||
(i->proc.types.pointer.last_point.x != data->point.x ||
|
||||
i->proc.types.pointer.last_point.y != data->point.y)) {
|
||||
if(i->cursor != NULL && (i->proc.types.pointer.last_point.x != data->point.x ||
|
||||
i->proc.types.pointer.last_point.y != data->point.y)) {
|
||||
lv_obj_set_pos(i->cursor, data->point.x, data->point.y);
|
||||
}
|
||||
|
||||
@ -364,10 +370,10 @@ static void indev_keypad_proc(lv_indev_t * i, lv_indev_data_t * data)
|
||||
if(data->state == LV_INDEV_STATE_PR && i->proc.wait_until_release) return;
|
||||
|
||||
if(i->proc.wait_until_release) {
|
||||
i->proc.wait_until_release = 0;
|
||||
i->proc.pr_timestamp = 0;
|
||||
i->proc.long_pr_sent = 0;
|
||||
i->proc.types.keypad.last_state = LV_INDEV_STATE_REL; /*To skip the processing of release*/
|
||||
i->proc.wait_until_release = 0;
|
||||
i->proc.pr_timestamp = 0;
|
||||
i->proc.long_pr_sent = 0;
|
||||
i->proc.types.keypad.last_state = LV_INDEV_STATE_REL; /*To skip the processing of release*/
|
||||
}
|
||||
|
||||
lv_group_t * g = i->group;
|
||||
@ -386,35 +392,36 @@ static void indev_keypad_proc(lv_indev_t * i, lv_indev_data_t * data)
|
||||
/* Save the previous state so we can detect state changes below and also set the last state now
|
||||
* so if any signal/event handler on the way returns `LV_RES_INV` the last state is remembered
|
||||
* for the next time*/
|
||||
uint32_t prev_state = i->proc.types.keypad.last_state;
|
||||
uint32_t prev_state = i->proc.types.keypad.last_state;
|
||||
i->proc.types.keypad.last_state = data->state;
|
||||
|
||||
/*Key press happened*/
|
||||
if(data->state == LV_INDEV_STATE_PR && prev_state == LV_INDEV_STATE_REL)
|
||||
{
|
||||
if(data->state == LV_INDEV_STATE_PR && prev_state == LV_INDEV_STATE_REL) {
|
||||
i->proc.pr_timestamp = lv_tick_get();
|
||||
|
||||
/*Simulate a press on the object if ENTER was pressed*/
|
||||
if(data->key == LV_GROUP_KEY_ENTER) {
|
||||
focused->signal_cb(focused, LV_SIGNAL_PRESSED, NULL);
|
||||
if(i->proc.reset_query) return; /*The object might be deleted*/
|
||||
if(i->proc.reset_query) return; /*The object might be deleted*/
|
||||
lv_event_send(focused, LV_EVENT_PRESSED, NULL);
|
||||
if(i->proc.reset_query) return; /*The object might be deleted*/
|
||||
if(i->proc.reset_query) return; /*The object might be deleted*/
|
||||
|
||||
/*Send the ENTER as a normal KEY*/
|
||||
lv_group_send_data(g, LV_GROUP_KEY_ENTER);
|
||||
}
|
||||
/*Move the focus on NEXT*/
|
||||
else if(data->key == LV_GROUP_KEY_NEXT) {
|
||||
lv_group_set_editing(g, false); /*Editing is not used by KEYPAD is be sure it is disabled*/
|
||||
lv_group_set_editing(g,
|
||||
false); /*Editing is not used by KEYPAD is be sure it is disabled*/
|
||||
lv_group_focus_next(g);
|
||||
if(i->proc.reset_query) return; /*The object might be deleted*/
|
||||
if(i->proc.reset_query) return; /*The object might be deleted*/
|
||||
}
|
||||
/*Move the focus on PREV*/
|
||||
else if(data->key == LV_GROUP_KEY_PREV) {
|
||||
lv_group_set_editing(g, false); /*Editing is not used by KEYPAD is be sure it is disabled*/
|
||||
lv_group_set_editing(g,
|
||||
false); /*Editing is not used by KEYPAD is be sure it is disabled*/
|
||||
lv_group_focus_prev(g);
|
||||
if(i->proc.reset_query) return; /*The object might be deleted*/
|
||||
if(i->proc.reset_query) return; /*The object might be deleted*/
|
||||
}
|
||||
/*Just send other keys to the object (e.g. 'A' or `LV_GORUP_KEY_RIGHT)*/
|
||||
else {
|
||||
@ -422,76 +429,78 @@ static void indev_keypad_proc(lv_indev_t * i, lv_indev_data_t * data)
|
||||
}
|
||||
}
|
||||
/*Pressing*/
|
||||
else if(data->state == LV_INDEV_STATE_PR && prev_state == LV_INDEV_STATE_PR)
|
||||
{
|
||||
else if(data->state == LV_INDEV_STATE_PR && prev_state == LV_INDEV_STATE_PR) {
|
||||
/*Long press time has elapsed?*/
|
||||
if(i->proc.long_pr_sent == 0 && lv_tick_elaps(i->proc.pr_timestamp) > i->driver.long_press_time) {
|
||||
if(i->proc.long_pr_sent == 0 &&
|
||||
lv_tick_elaps(i->proc.pr_timestamp) > i->driver.long_press_time) {
|
||||
i->proc.long_pr_sent = 1;
|
||||
if(data->key == LV_GROUP_KEY_ENTER) {
|
||||
i->proc.longpr_rep_timestamp = lv_tick_get();
|
||||
focused->signal_cb(focused, LV_SIGNAL_LONG_PRESS, NULL);
|
||||
if(i->proc.reset_query) return; /*The object might be deleted*/
|
||||
if(i->proc.reset_query) return; /*The object might be deleted*/
|
||||
lv_event_send(focused, LV_EVENT_LONG_PRESSED, NULL);
|
||||
if(i->proc.reset_query) return; /*The object might be deleted*/
|
||||
if(i->proc.reset_query) return; /*The object might be deleted*/
|
||||
}
|
||||
}
|
||||
/*Long press repeated time has elapsed?*/
|
||||
else if(i->proc.long_pr_sent != 0 && lv_tick_elaps(i->proc.longpr_rep_timestamp) > i->driver.long_press_rep_time) {
|
||||
else if(i->proc.long_pr_sent != 0 &&
|
||||
lv_tick_elaps(i->proc.longpr_rep_timestamp) > i->driver.long_press_rep_time) {
|
||||
|
||||
i->proc.longpr_rep_timestamp = lv_tick_get();
|
||||
|
||||
/*Send LONG_PRESS_REP on ENTER*/
|
||||
if(data->key == LV_GROUP_KEY_ENTER) {
|
||||
focused->signal_cb(focused, LV_SIGNAL_LONG_PRESS_REP, NULL);
|
||||
if(i->proc.reset_query) return; /*The object might be deleted*/
|
||||
if(i->proc.reset_query) return; /*The object might be deleted*/
|
||||
lv_event_send(focused, LV_EVENT_LONG_PRESSED_REPEAT, NULL);
|
||||
if(i->proc.reset_query) return; /*The object might be deleted*/
|
||||
if(i->proc.reset_query) return; /*The object might be deleted*/
|
||||
}
|
||||
/*Move the focus on NEXT again*/
|
||||
else if(data->key == LV_GROUP_KEY_NEXT) {
|
||||
lv_group_set_editing(g, false); /*Editing is not used by KEYPAD is be sure it is disabled*/
|
||||
lv_group_set_editing(
|
||||
g, false); /*Editing is not used by KEYPAD is be sure it is disabled*/
|
||||
lv_group_focus_next(g);
|
||||
if(i->proc.reset_query) return; /*The object might be deleted*/
|
||||
if(i->proc.reset_query) return; /*The object might be deleted*/
|
||||
}
|
||||
/*Move the focus on PREV again*/
|
||||
else if(data->key == LV_GROUP_KEY_PREV) {
|
||||
lv_group_set_editing(g, false); /*Editing is not used by KEYPAD is be sure it is disabled*/
|
||||
lv_group_set_editing(
|
||||
g, false); /*Editing is not used by KEYPAD is be sure it is disabled*/
|
||||
lv_group_focus_prev(g);
|
||||
if(i->proc.reset_query) return; /*The object might be deleted*/
|
||||
if(i->proc.reset_query) return; /*The object might be deleted*/
|
||||
}
|
||||
/*Just send other keys again to the object (e.g. 'A' or `LV_GORUP_KEY_RIGHT)*/
|
||||
else {
|
||||
lv_group_send_data(g, data->key);
|
||||
if(i->proc.reset_query) return; /*The object might be deleted*/
|
||||
if(i->proc.reset_query) return; /*The object might be deleted*/
|
||||
}
|
||||
}
|
||||
}
|
||||
/*Release happened*/
|
||||
else if(data->state == LV_INDEV_STATE_REL && prev_state == LV_INDEV_STATE_PR)
|
||||
{
|
||||
else if(data->state == LV_INDEV_STATE_REL && prev_state == LV_INDEV_STATE_PR) {
|
||||
/*The user might clear the key when it was released. Always release the pressed key*/
|
||||
data->key = prev_key;
|
||||
if(data->key == LV_GROUP_KEY_ENTER) {
|
||||
|
||||
focused->signal_cb(focused, LV_SIGNAL_RELEASED, NULL);
|
||||
if(i->proc.reset_query) return; /*The object might be deleted*/
|
||||
if(i->proc.reset_query) return; /*The object might be deleted*/
|
||||
|
||||
if(i->proc.long_pr_sent == 0) {
|
||||
lv_event_send(focused, LV_EVENT_SHORT_CLICKED, NULL);
|
||||
}
|
||||
|
||||
lv_event_send(focused, LV_EVENT_CLICKED, NULL);
|
||||
if(i->proc.reset_query) return; /*The object might be deleted*/
|
||||
if(i->proc.reset_query) return; /*The object might be deleted*/
|
||||
|
||||
lv_event_send(focused, LV_EVENT_RELEASED, NULL);
|
||||
if(i->proc.reset_query) return; /*The object might be deleted*/
|
||||
if(i->proc.reset_query) return; /*The object might be deleted*/
|
||||
}
|
||||
i->proc.pr_timestamp = 0;
|
||||
i->proc.long_pr_sent = 0;
|
||||
}
|
||||
#else
|
||||
(void)data; /*Unused*/
|
||||
(void)i; /*Unused*/
|
||||
(void)i; /*Unused*/
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -507,10 +516,10 @@ static void indev_encoder_proc(lv_indev_t * i, lv_indev_data_t * data)
|
||||
if(data->state == LV_INDEV_STATE_PR && i->proc.wait_until_release) return;
|
||||
|
||||
if(i->proc.wait_until_release) {
|
||||
i->proc.wait_until_release = 0;
|
||||
i->proc.pr_timestamp = 0;
|
||||
i->proc.long_pr_sent = 0;
|
||||
i->proc.types.keypad.last_state = LV_INDEV_STATE_REL; /*To skip the processing of release*/
|
||||
i->proc.wait_until_release = 0;
|
||||
i->proc.pr_timestamp = 0;
|
||||
i->proc.long_pr_sent = 0;
|
||||
i->proc.types.keypad.last_state = LV_INDEV_STATE_REL; /*To skip the processing of release*/
|
||||
}
|
||||
|
||||
lv_group_t * g = i->group;
|
||||
@ -546,26 +555,24 @@ static void indev_encoder_proc(lv_indev_t * i, lv_indev_data_t * data)
|
||||
if(focused == NULL) return;
|
||||
|
||||
/*Button press happened*/
|
||||
if(data->state == LV_INDEV_STATE_PR &&
|
||||
i->proc.types.keypad.last_state == LV_INDEV_STATE_REL)
|
||||
{
|
||||
if(data->state == LV_INDEV_STATE_PR && i->proc.types.keypad.last_state == LV_INDEV_STATE_REL) {
|
||||
bool editable = false;
|
||||
focused->signal_cb(focused, LV_SIGNAL_GET_EDITABLE, &editable);
|
||||
|
||||
i->proc.pr_timestamp = lv_tick_get();
|
||||
if(lv_group_get_editing(g) == true || editable == false) {
|
||||
focused->signal_cb(focused, LV_SIGNAL_PRESSED, NULL);
|
||||
if(i->proc.reset_query) return; /*The object might be deleted*/
|
||||
if(i->proc.reset_query) return; /*The object might be deleted*/
|
||||
|
||||
lv_event_send(focused, LV_EVENT_PRESSED, NULL);
|
||||
if(i->proc.reset_query) return; /*The object might be deleted*/
|
||||
if(i->proc.reset_query) return; /*The object might be deleted*/
|
||||
}
|
||||
}
|
||||
/*Pressing*/
|
||||
else if(data->state == LV_INDEV_STATE_PR && i->proc.types.keypad.last_state == LV_INDEV_STATE_PR) {
|
||||
else if(data->state == LV_INDEV_STATE_PR &&
|
||||
i->proc.types.keypad.last_state == LV_INDEV_STATE_PR) {
|
||||
if(i->proc.long_pr_sent == 0 &&
|
||||
lv_tick_elaps(i->proc.pr_timestamp) > i->driver.long_press_time)
|
||||
{
|
||||
lv_tick_elaps(i->proc.pr_timestamp) > i->driver.long_press_time) {
|
||||
bool editable = false;
|
||||
focused->signal_cb(focused, LV_SIGNAL_GET_EDITABLE, &editable);
|
||||
|
||||
@ -573,21 +580,24 @@ static void indev_encoder_proc(lv_indev_t * i, lv_indev_data_t * data)
|
||||
if(editable) {
|
||||
/*Don't leave edit mode if there is only one object (nowhere to navigate)*/
|
||||
if(lv_ll_is_empty(&g->obj_ll) == false) {
|
||||
lv_group_set_editing(g, lv_group_get_editing(g) ? false : true); /*Toggle edit mode on long press*/
|
||||
lv_group_set_editing(g, lv_group_get_editing(g)
|
||||
? false
|
||||
: true); /*Toggle edit mode on long press*/
|
||||
}
|
||||
}
|
||||
/*If not editable then just send a long press signal*/
|
||||
else {
|
||||
focused->signal_cb(focused, LV_SIGNAL_LONG_PRESS, NULL);
|
||||
if(i->proc.reset_query) return; /*The object might be deleted*/
|
||||
if(i->proc.reset_query) return; /*The object might be deleted*/
|
||||
lv_event_send(focused, LV_EVENT_LONG_PRESSED, NULL);
|
||||
if(i->proc.reset_query) return; /*The object might be deleted*/
|
||||
if(i->proc.reset_query) return; /*The object might be deleted*/
|
||||
}
|
||||
i->proc.long_pr_sent = 1;
|
||||
}
|
||||
}
|
||||
/*Release happened*/
|
||||
else if(data->state == LV_INDEV_STATE_REL && i->proc.types.keypad.last_state == LV_INDEV_STATE_PR) {
|
||||
else if(data->state == LV_INDEV_STATE_REL &&
|
||||
i->proc.types.keypad.last_state == LV_INDEV_STATE_PR) {
|
||||
|
||||
bool editable = false;
|
||||
focused->signal_cb(focused, LV_SIGNAL_GET_EDITABLE, &editable);
|
||||
@ -595,39 +605,40 @@ static void indev_encoder_proc(lv_indev_t * i, lv_indev_data_t * data)
|
||||
/*The button was released on a non-editable object. Just send enter*/
|
||||
if(editable == false) {
|
||||
focused->signal_cb(focused, LV_SIGNAL_RELEASED, NULL);
|
||||
if(i->proc.reset_query) return; /*The object might be deleted*/
|
||||
if(i->proc.reset_query) return; /*The object might be deleted*/
|
||||
|
||||
if(i->proc.long_pr_sent == 0) lv_event_send(focused, LV_EVENT_SHORT_CLICKED, NULL);
|
||||
if(i->proc.reset_query) return; /*The object might be deleted*/
|
||||
if(i->proc.reset_query) return; /*The object might be deleted*/
|
||||
|
||||
lv_event_send(focused, LV_EVENT_CLICKED, NULL);
|
||||
if(i->proc.reset_query) return; /*The object might be deleted*/
|
||||
if(i->proc.reset_query) return; /*The object might be deleted*/
|
||||
|
||||
lv_event_send(focused, LV_EVENT_RELEASED, NULL);
|
||||
if(i->proc.reset_query) return; /*The object might be deleted*/
|
||||
if(i->proc.reset_query) return; /*The object might be deleted*/
|
||||
}
|
||||
/*An object is being edited and the button is released. */
|
||||
else if(g->editing) {
|
||||
/*Ignore long pressed enter release because it comes from mode switch*/
|
||||
if(!i->proc.long_pr_sent || lv_ll_is_empty(&g->obj_ll)) {
|
||||
focused->signal_cb(focused, LV_SIGNAL_RELEASED, NULL);
|
||||
if(i->proc.reset_query) return; /*The object might be deleted*/
|
||||
if(i->proc.reset_query) return; /*The object might be deleted*/
|
||||
|
||||
lv_event_send(focused, LV_EVENT_SHORT_CLICKED, NULL);
|
||||
if(i->proc.reset_query) return; /*The object might be deleted*/
|
||||
if(i->proc.reset_query) return; /*The object might be deleted*/
|
||||
|
||||
lv_event_send(focused, LV_EVENT_CLICKED, NULL);
|
||||
if(i->proc.reset_query) return; /*The object might be deleted*/
|
||||
if(i->proc.reset_query) return; /*The object might be deleted*/
|
||||
|
||||
lv_event_send(focused, LV_EVENT_RELEASED, NULL);
|
||||
if(i->proc.reset_query) return; /*The object might be deleted*/
|
||||
if(i->proc.reset_query) return; /*The object might be deleted*/
|
||||
|
||||
lv_group_send_data(g, LV_GROUP_KEY_ENTER);
|
||||
}
|
||||
}
|
||||
/*If the focused object is editable and now in navigate mode then on enter switch edit mode*/
|
||||
/*If the focused object is editable and now in navigate mode then on enter switch edit
|
||||
mode*/
|
||||
else if(editable && !g->editing && !i->proc.long_pr_sent) {
|
||||
lv_group_set_editing(g, true); /*Set edit mode*/
|
||||
lv_group_set_editing(g, true); /*Set edit mode*/
|
||||
}
|
||||
|
||||
i->proc.pr_timestamp = 0;
|
||||
@ -635,10 +646,10 @@ static void indev_encoder_proc(lv_indev_t * i, lv_indev_data_t * data)
|
||||
}
|
||||
|
||||
i->proc.types.keypad.last_state = data->state;
|
||||
i->proc.types.keypad.last_key = data->key;
|
||||
i->proc.types.keypad.last_key = data->key;
|
||||
#else
|
||||
(void)data; /*Unused*/
|
||||
(void)i; /*Unused*/
|
||||
(void)i; /*Unused*/
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -655,9 +666,8 @@ static void indev_button_proc(lv_indev_t * i, lv_indev_data_t * data)
|
||||
|
||||
/*Still the same point is pressed*/
|
||||
if(i->proc.types.pointer.last_point.x == i->proc.types.pointer.act_point.x &&
|
||||
i->proc.types.pointer.last_point.y == i->proc.types.pointer.act_point.y &&
|
||||
data->state == LV_INDEV_STATE_PR)
|
||||
{
|
||||
i->proc.types.pointer.last_point.y == i->proc.types.pointer.act_point.y &&
|
||||
data->state == LV_INDEV_STATE_PR) {
|
||||
indev_proc_press(&i->proc);
|
||||
} else {
|
||||
/*If a new point comes always make a release*/
|
||||
@ -689,14 +699,14 @@ static void indev_proc_press(lv_indev_proc_t * proc)
|
||||
}
|
||||
/*If there is last object but it is not dragged and not protected also search*/
|
||||
else if(proc->types.pointer.drag_in_prog == 0 &&
|
||||
lv_obj_is_protected(proc->types.pointer.act_obj, LV_PROTECT_PRESS_LOST) == false) {/*Now types.pointer.act_obj != NULL*/
|
||||
lv_obj_is_protected(proc->types.pointer.act_obj, LV_PROTECT_PRESS_LOST) ==
|
||||
false) { /*Now types.pointer.act_obj != NULL*/
|
||||
pr_obj = indev_search_obj(proc, lv_disp_get_layer_sys(disp));
|
||||
if(pr_obj == NULL) pr_obj = indev_search_obj(proc, lv_disp_get_layer_top(disp));
|
||||
if(pr_obj == NULL) pr_obj = indev_search_obj(proc, lv_disp_get_scr_act(disp));
|
||||
}
|
||||
/*If a dragable or a protected object was the last then keep it*/
|
||||
else {
|
||||
|
||||
}
|
||||
|
||||
/*If a new object was found reset some variables and send a pressed signal*/
|
||||
@ -707,29 +717,31 @@ static void indev_proc_press(lv_indev_proc_t * proc)
|
||||
|
||||
/*If a new object found the previous was lost, so send a signal*/
|
||||
if(proc->types.pointer.act_obj != NULL) {
|
||||
proc->types.pointer.act_obj->signal_cb(proc->types.pointer.act_obj, LV_SIGNAL_PRESS_LOST, indev_act);
|
||||
if(proc->reset_query) return; /*The object might be deleted*/
|
||||
proc->types.pointer.act_obj->signal_cb(proc->types.pointer.act_obj,
|
||||
LV_SIGNAL_PRESS_LOST, indev_act);
|
||||
if(proc->reset_query) return; /*The object might be deleted*/
|
||||
lv_event_send(proc->types.pointer.act_obj, LV_EVENT_PRESS_LOST, NULL);
|
||||
if(proc->reset_query) return; /*The object might be deleted*/
|
||||
if(proc->reset_query) return; /*The object might be deleted*/
|
||||
}
|
||||
|
||||
proc->types.pointer.act_obj = pr_obj; /*Save the pressed object*/
|
||||
proc->types.pointer.last_obj = proc->types.pointer.act_obj; /*Refresh the types.pointer.last_obj*/
|
||||
proc->types.pointer.act_obj = pr_obj; /*Save the pressed object*/
|
||||
proc->types.pointer.last_obj =
|
||||
proc->types.pointer.act_obj; /*Refresh the types.pointer.last_obj*/
|
||||
|
||||
if(proc->types.pointer.act_obj != NULL) {
|
||||
/* Save the time when the obj pressed.
|
||||
* It is necessary to count the long press time.*/
|
||||
proc->pr_timestamp = lv_tick_get();
|
||||
proc->long_pr_sent = 0;
|
||||
proc->pr_timestamp = lv_tick_get();
|
||||
proc->long_pr_sent = 0;
|
||||
proc->types.pointer.drag_limit_out = 0;
|
||||
proc->types.pointer.drag_in_prog = 0;
|
||||
proc->types.pointer.drag_sum.x = 0;
|
||||
proc->types.pointer.drag_sum.y = 0;
|
||||
proc->types.pointer.vect.x = 0;
|
||||
proc->types.pointer.vect.y = 0;
|
||||
proc->types.pointer.drag_in_prog = 0;
|
||||
proc->types.pointer.drag_sum.x = 0;
|
||||
proc->types.pointer.drag_sum.y = 0;
|
||||
proc->types.pointer.vect.x = 0;
|
||||
proc->types.pointer.vect.y = 0;
|
||||
|
||||
/*Search for 'top' attribute*/
|
||||
lv_obj_t * i = proc->types.pointer.act_obj;
|
||||
lv_obj_t * i = proc->types.pointer.act_obj;
|
||||
lv_obj_t * last_top = NULL;
|
||||
while(i != NULL) {
|
||||
if(i->top != 0) last_top = i;
|
||||
@ -745,10 +757,11 @@ static void indev_proc_press(lv_indev_proc_t * proc)
|
||||
}
|
||||
|
||||
/*Send a signal about the press*/
|
||||
proc->types.pointer.act_obj->signal_cb(proc->types.pointer.act_obj, LV_SIGNAL_PRESSED, indev_act);
|
||||
if(proc->reset_query) return; /*The object might be deleted*/
|
||||
proc->types.pointer.act_obj->signal_cb(proc->types.pointer.act_obj, LV_SIGNAL_PRESSED,
|
||||
indev_act);
|
||||
if(proc->reset_query) return; /*The object might be deleted*/
|
||||
lv_event_send(proc->types.pointer.act_obj, LV_EVENT_PRESSED, NULL);
|
||||
if(proc->reset_query) return; /*The object might be deleted*/
|
||||
if(proc->reset_query) return; /*The object might be deleted*/
|
||||
}
|
||||
}
|
||||
|
||||
@ -759,21 +772,26 @@ static void indev_proc_press(lv_indev_proc_t * proc)
|
||||
proc->types.pointer.drag_throw_vect.x = (proc->types.pointer.drag_throw_vect.x * 5) >> 3;
|
||||
proc->types.pointer.drag_throw_vect.y = (proc->types.pointer.drag_throw_vect.y * 5) >> 3;
|
||||
|
||||
if(proc->types.pointer.drag_throw_vect.x < 0) proc->types.pointer.drag_throw_vect.x++;
|
||||
else if(proc->types.pointer.drag_throw_vect.x > 0) proc->types.pointer.drag_throw_vect.x--;
|
||||
if(proc->types.pointer.drag_throw_vect.x < 0)
|
||||
proc->types.pointer.drag_throw_vect.x++;
|
||||
else if(proc->types.pointer.drag_throw_vect.x > 0)
|
||||
proc->types.pointer.drag_throw_vect.x--;
|
||||
|
||||
if(proc->types.pointer.drag_throw_vect.y < 0) proc->types.pointer.drag_throw_vect.y++;
|
||||
else if(proc->types.pointer.drag_throw_vect.y > 0) proc->types.pointer.drag_throw_vect.y--;
|
||||
if(proc->types.pointer.drag_throw_vect.y < 0)
|
||||
proc->types.pointer.drag_throw_vect.y++;
|
||||
else if(proc->types.pointer.drag_throw_vect.y > 0)
|
||||
proc->types.pointer.drag_throw_vect.y--;
|
||||
|
||||
proc->types.pointer.drag_throw_vect.x += (proc->types.pointer.vect.x * 4) >> 3;
|
||||
proc->types.pointer.drag_throw_vect.y += (proc->types.pointer.vect.y * 4) >> 3;
|
||||
|
||||
/*If there is active object and it can be dragged run the drag*/
|
||||
if(proc->types.pointer.act_obj != NULL) {
|
||||
proc->types.pointer.act_obj->signal_cb(proc->types.pointer.act_obj, LV_SIGNAL_PRESSING, indev_act);
|
||||
if(proc->reset_query) return; /*The object might be deleted*/
|
||||
proc->types.pointer.act_obj->signal_cb(proc->types.pointer.act_obj, LV_SIGNAL_PRESSING,
|
||||
indev_act);
|
||||
if(proc->reset_query) return; /*The object might be deleted*/
|
||||
lv_event_send(proc->types.pointer.act_obj, LV_EVENT_PRESSING, NULL);
|
||||
if(proc->reset_query) return; /*The object might be deleted*/
|
||||
if(proc->reset_query) return; /*The object might be deleted*/
|
||||
|
||||
indev_drag(proc);
|
||||
if(proc->reset_query != 0) return;
|
||||
@ -783,9 +801,9 @@ static void indev_proc_press(lv_indev_proc_t * proc)
|
||||
/*Send a signal about the long press if enough time elapsed*/
|
||||
if(lv_tick_elaps(proc->pr_timestamp) > indev_act->driver.long_press_time) {
|
||||
pr_obj->signal_cb(pr_obj, LV_SIGNAL_LONG_PRESS, indev_act);
|
||||
if(proc->reset_query) return; /*The object might be deleted*/
|
||||
if(proc->reset_query) return; /*The object might be deleted*/
|
||||
lv_event_send(pr_obj, LV_EVENT_LONG_PRESSED, NULL);
|
||||
if(proc->reset_query) return; /*The object might be deleted*/
|
||||
if(proc->reset_query) return; /*The object might be deleted*/
|
||||
|
||||
/*Mark the signal sending to do not send it again*/
|
||||
proc->long_pr_sent = 1;
|
||||
@ -799,11 +817,10 @@ static void indev_proc_press(lv_indev_proc_t * proc)
|
||||
/*Send a signal about the long press repeate if enough time elapsed*/
|
||||
if(lv_tick_elaps(proc->longpr_rep_timestamp) > indev_act->driver.long_press_rep_time) {
|
||||
pr_obj->signal_cb(pr_obj, LV_SIGNAL_LONG_PRESS_REP, indev_act);
|
||||
if(proc->reset_query) return; /*The object might be deleted*/
|
||||
if(proc->reset_query) return; /*The object might be deleted*/
|
||||
lv_event_send(pr_obj, LV_EVENT_LONG_PRESSED_REPEAT, NULL);
|
||||
if(proc->reset_query) return; /*The object might be deleted*/
|
||||
if(proc->reset_query) return; /*The object might be deleted*/
|
||||
proc->longpr_rep_timestamp = lv_tick_get();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -816,67 +833,73 @@ static void indev_proc_press(lv_indev_proc_t * proc)
|
||||
static void indev_proc_release(lv_indev_proc_t * proc)
|
||||
{
|
||||
if(proc->wait_until_release != 0) {
|
||||
proc->types.pointer.act_obj = NULL;
|
||||
proc->types.pointer.act_obj = NULL;
|
||||
proc->types.pointer.last_obj = NULL;
|
||||
proc->pr_timestamp = 0;
|
||||
proc->longpr_rep_timestamp = 0;
|
||||
proc->wait_until_release = 0;
|
||||
proc->pr_timestamp = 0;
|
||||
proc->longpr_rep_timestamp = 0;
|
||||
proc->wait_until_release = 0;
|
||||
}
|
||||
|
||||
/*Forget the act obj and send a released signal */
|
||||
if(proc->types.pointer.act_obj) {
|
||||
/* If the object was protected against press lost then it possible that
|
||||
* the object is already not pressed but still it is the `act_obj`.
|
||||
* In this case send the `LV_SIGNAL_RELEASED/CLICKED` instead of `LV_SIGNAL_PRESS_LOST` if the indev is ON the `types.pointer.act_obj` */
|
||||
* In this case send the `LV_SIGNAL_RELEASED/CLICKED` instead of `LV_SIGNAL_PRESS_LOST` if
|
||||
* the indev is ON the `types.pointer.act_obj` */
|
||||
if(lv_obj_is_protected(proc->types.pointer.act_obj, LV_PROTECT_PRESS_LOST)) {
|
||||
proc->types.pointer.act_obj->signal_cb(proc->types.pointer.act_obj, LV_SIGNAL_RELEASED, indev_act);
|
||||
if(proc->reset_query) return; /*The object might be deleted*/
|
||||
proc->types.pointer.act_obj->signal_cb(proc->types.pointer.act_obj, LV_SIGNAL_RELEASED,
|
||||
indev_act);
|
||||
if(proc->reset_query) return; /*The object might be deleted*/
|
||||
|
||||
if(proc->long_pr_sent == 0 && proc->types.pointer.drag_in_prog == 0) {
|
||||
lv_event_send(proc->types.pointer.act_obj, LV_EVENT_SHORT_CLICKED, NULL);
|
||||
if(proc->reset_query) return; /*The object might be deleted*/
|
||||
if(proc->reset_query) return; /*The object might be deleted*/
|
||||
}
|
||||
|
||||
lv_event_send(proc->types.pointer.act_obj, LV_EVENT_CLICKED, NULL);
|
||||
if(proc->reset_query) return; /*The object might be deleted*/
|
||||
if(proc->reset_query) return; /*The object might be deleted*/
|
||||
|
||||
lv_event_send(proc->types.pointer.act_obj, LV_EVENT_RELEASED, NULL);
|
||||
if(proc->reset_query) return; /*The object might be deleted*/
|
||||
if(proc->reset_query) return; /*The object might be deleted*/
|
||||
}
|
||||
/* The simple case: `act_obj` was not protected against press lost.
|
||||
* If it is already not pressed then was `indev_proc_press` would set `act_obj = NULL`*/
|
||||
else {
|
||||
proc->types.pointer.act_obj->signal_cb(proc->types.pointer.act_obj, LV_SIGNAL_RELEASED, indev_act);
|
||||
if(proc->reset_query) return; /*The object might be deleted*/
|
||||
proc->types.pointer.act_obj->signal_cb(proc->types.pointer.act_obj, LV_SIGNAL_RELEASED,
|
||||
indev_act);
|
||||
if(proc->reset_query) return; /*The object might be deleted*/
|
||||
|
||||
if(proc->long_pr_sent == 0 && proc->types.pointer.drag_in_prog == 0) {
|
||||
lv_event_send(proc->types.pointer.act_obj, LV_EVENT_SHORT_CLICKED, NULL);
|
||||
if(proc->reset_query) return; /*The object might be deleted*/
|
||||
if(proc->reset_query) return; /*The object might be deleted*/
|
||||
}
|
||||
|
||||
lv_event_send(proc->types.pointer.act_obj, LV_EVENT_CLICKED, NULL);
|
||||
if(proc->reset_query) return; /*The object might be deleted*/
|
||||
if(proc->reset_query) return; /*The object might be deleted*/
|
||||
|
||||
lv_event_send(proc->types.pointer.act_obj, LV_EVENT_RELEASED, NULL);
|
||||
if(proc->reset_query) return; /*The object might be deleted*/
|
||||
if(proc->reset_query) return; /*The object might be deleted*/
|
||||
}
|
||||
|
||||
if(proc->reset_query != 0) return;
|
||||
|
||||
/*Handle click focus*/
|
||||
/*Handle click focus*/
|
||||
#if LV_USE_GROUP
|
||||
/*Edit mode is not used by POINTER devices. So leave edit mode if we are in it*/
|
||||
lv_group_t * g = lv_obj_get_group(proc->types.pointer.act_obj);
|
||||
if(lv_group_get_editing(g)) lv_group_set_editing(g, false);
|
||||
|
||||
/*Check, if the parent is in a group focus on it.*/
|
||||
if(lv_obj_is_protected(proc->types.pointer.act_obj, LV_PROTECT_CLICK_FOCUS) == false) { /*Respect the click focus protection*/
|
||||
if(lv_obj_is_protected(proc->types.pointer.act_obj, LV_PROTECT_CLICK_FOCUS) ==
|
||||
false) { /*Respect the click focus protection*/
|
||||
lv_obj_t * parent = proc->types.pointer.act_obj;
|
||||
|
||||
while(g == NULL) {
|
||||
parent = lv_obj_get_parent(parent);
|
||||
if(parent == NULL) break;
|
||||
if(lv_obj_is_protected(parent, LV_PROTECT_CLICK_FOCUS)) { /*Ignore is the protected against click focus*/
|
||||
if(lv_obj_is_protected(
|
||||
parent,
|
||||
LV_PROTECT_CLICK_FOCUS)) { /*Ignore is the protected against click focus*/
|
||||
parent = NULL;
|
||||
break;
|
||||
}
|
||||
@ -898,18 +921,19 @@ static void indev_proc_release(lv_indev_proc_t * proc)
|
||||
* a focus/defucus signal because of `click focus`*/
|
||||
if(proc->types.pointer.last_pressed != proc->types.pointer.act_obj) {
|
||||
lv_event_send(proc->types.pointer.last_pressed, LV_EVENT_DEFOCUSED, NULL);
|
||||
if(proc->reset_query) return; /*Not so strict as it's only the previous object and indev not uses it.*/
|
||||
if(proc->reset_query)
|
||||
return; /*Not so strict as it's only the previous object and indev not uses it.*/
|
||||
|
||||
lv_event_send(proc->types.pointer.act_obj, LV_EVENT_FOCUSED, NULL);
|
||||
if(proc->reset_query) return; /*The object might be deleted*/
|
||||
if(proc->reset_query) return; /*The object might be deleted*/
|
||||
|
||||
proc->types.pointer.last_pressed = proc->types.pointer.act_obj;
|
||||
}
|
||||
|
||||
if(proc->reset_query != 0) return;
|
||||
proc->types.pointer.act_obj = NULL;
|
||||
proc->pr_timestamp = 0;
|
||||
proc->longpr_rep_timestamp = 0;
|
||||
proc->pr_timestamp = 0;
|
||||
proc->longpr_rep_timestamp = 0;
|
||||
}
|
||||
|
||||
/*The reset can be set in the signal function.
|
||||
@ -930,19 +954,19 @@ static void indev_proc_release(lv_indev_proc_t * proc)
|
||||
static void indev_proc_reset_query_handler(lv_indev_t * indev)
|
||||
{
|
||||
if(indev->proc.reset_query) {
|
||||
indev->proc.types.pointer.act_obj = NULL;
|
||||
indev->proc.types.pointer.last_obj = NULL;
|
||||
indev->proc.types.pointer.last_pressed = NULL;
|
||||
indev->proc.types.pointer.drag_limit_out = 0;
|
||||
indev->proc.types.pointer.drag_in_prog = 0;
|
||||
indev->proc.long_pr_sent = 0;
|
||||
indev->proc.pr_timestamp = 0;
|
||||
indev->proc.longpr_rep_timestamp = 0;
|
||||
indev->proc.types.pointer.drag_sum.x = 0;
|
||||
indev->proc.types.pointer.drag_sum.y = 0;
|
||||
indev->proc.types.pointer.act_obj = NULL;
|
||||
indev->proc.types.pointer.last_obj = NULL;
|
||||
indev->proc.types.pointer.last_pressed = NULL;
|
||||
indev->proc.types.pointer.drag_limit_out = 0;
|
||||
indev->proc.types.pointer.drag_in_prog = 0;
|
||||
indev->proc.long_pr_sent = 0;
|
||||
indev->proc.pr_timestamp = 0;
|
||||
indev->proc.longpr_rep_timestamp = 0;
|
||||
indev->proc.types.pointer.drag_sum.x = 0;
|
||||
indev->proc.types.pointer.drag_sum.y = 0;
|
||||
indev->proc.types.pointer.drag_throw_vect.x = 0;
|
||||
indev->proc.types.pointer.drag_throw_vect.y = 0;
|
||||
indev->proc.reset_query = 0;
|
||||
indev->proc.reset_query = 0;
|
||||
}
|
||||
}
|
||||
/**
|
||||
@ -960,7 +984,8 @@ static lv_obj_t * indev_search_obj(const lv_indev_proc_t * proc, lv_obj_t * obj)
|
||||
if(lv_area_is_point_on(&obj->coords, &proc->types.pointer.act_point)) {
|
||||
lv_obj_t * i;
|
||||
|
||||
LV_LL_READ(obj->child_ll, i) {
|
||||
LV_LL_READ(obj->child_ll, i)
|
||||
{
|
||||
found_p = indev_search_obj(proc, i);
|
||||
|
||||
/*If a child was found then break*/
|
||||
@ -980,7 +1005,6 @@ static lv_obj_t * indev_search_obj(const lv_indev_proc_t * proc, lv_obj_t * obj)
|
||||
/*No parent found with hidden == true*/
|
||||
if(hidden_i == NULL) found_p = obj;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return found_p;
|
||||
@ -995,8 +1019,7 @@ static void indev_drag(lv_indev_proc_t * state)
|
||||
lv_obj_t * drag_obj = state->types.pointer.act_obj;
|
||||
|
||||
/*If drag parent is active check recursively the drag_parent attribute*/
|
||||
while(lv_obj_get_drag_parent(drag_obj) != false &&
|
||||
drag_obj != NULL) {
|
||||
while(lv_obj_get_drag_parent(drag_obj) != false && drag_obj != NULL) {
|
||||
drag_obj = lv_obj_get_parent(drag_obj);
|
||||
}
|
||||
|
||||
@ -1012,7 +1035,7 @@ static void indev_drag(lv_indev_proc_t * state)
|
||||
if(state->types.pointer.drag_limit_out == 0) {
|
||||
/*If a move is greater then LV_DRAG_LIMIT then begin the drag*/
|
||||
if(LV_MATH_ABS(state->types.pointer.drag_sum.x) >= indev_act->driver.drag_limit ||
|
||||
LV_MATH_ABS(state->types.pointer.drag_sum.y) >= indev_act->driver.drag_limit) {
|
||||
LV_MATH_ABS(state->types.pointer.drag_sum.y) >= indev_act->driver.drag_limit) {
|
||||
state->types.pointer.drag_limit_out = 1;
|
||||
}
|
||||
}
|
||||
@ -1020,26 +1043,27 @@ static void indev_drag(lv_indev_proc_t * state)
|
||||
/*If the drag limit is exceeded handle the dragging*/
|
||||
if(state->types.pointer.drag_limit_out != 0) {
|
||||
/*Set new position if the vector is not zero*/
|
||||
if(state->types.pointer.vect.x != 0 ||
|
||||
state->types.pointer.vect.y != 0)
|
||||
{
|
||||
if(state->types.pointer.vect.x != 0 || state->types.pointer.vect.y != 0) {
|
||||
|
||||
/*Get the coordinates of the object and modify them*/
|
||||
lv_coord_t act_x = lv_obj_get_x(drag_obj);
|
||||
lv_coord_t act_y = lv_obj_get_y(drag_obj);
|
||||
uint16_t inv_buf_size = lv_disp_get_inv_buf_size(indev_act->driver.disp); /*Get the number of currently invalidated areas*/
|
||||
lv_coord_t act_x = lv_obj_get_x(drag_obj);
|
||||
lv_coord_t act_y = lv_obj_get_y(drag_obj);
|
||||
uint16_t inv_buf_size = lv_disp_get_inv_buf_size(
|
||||
indev_act->driver.disp); /*Get the number of currently invalidated areas*/
|
||||
|
||||
lv_coord_t prev_x = drag_obj->coords.x1;
|
||||
lv_coord_t prev_y = drag_obj->coords.y1;
|
||||
lv_coord_t prev_x = drag_obj->coords.x1;
|
||||
lv_coord_t prev_y = drag_obj->coords.y1;
|
||||
lv_coord_t prev_par_w = lv_obj_get_width(lv_obj_get_parent(drag_obj));
|
||||
lv_coord_t prev_par_h = lv_obj_get_height(lv_obj_get_parent(drag_obj));
|
||||
|
||||
lv_obj_set_pos(drag_obj, act_x + state->types.pointer.vect.x, act_y + state->types.pointer.vect.y);
|
||||
lv_obj_set_pos(drag_obj, act_x + state->types.pointer.vect.x,
|
||||
act_y + state->types.pointer.vect.y);
|
||||
|
||||
/*Set the drag in progress flag if the object is really moved*/
|
||||
if(drag_obj->coords.x1 != prev_x || drag_obj->coords.y1 != prev_y) {
|
||||
if(state->types.pointer.drag_in_prog != 0) { /*Send the drag begin signal on first move*/
|
||||
drag_obj->signal_cb(drag_obj, LV_SIGNAL_DRAG_BEGIN, indev_act);
|
||||
if(state->types.pointer.drag_in_prog !=
|
||||
0) { /*Send the drag begin signal on first move*/
|
||||
drag_obj->signal_cb(drag_obj, LV_SIGNAL_DRAG_BEGIN, indev_act);
|
||||
if(state->reset_query != 0) return;
|
||||
}
|
||||
state->types.pointer.drag_in_prog = 1;
|
||||
@ -1053,7 +1077,8 @@ static void indev_drag(lv_indev_proc_t * state)
|
||||
lv_coord_t act_par_h = lv_obj_get_height(lv_obj_get_parent(drag_obj));
|
||||
if(act_par_w == prev_par_w && act_par_h == prev_par_h) {
|
||||
uint16_t new_inv_buf_size = lv_disp_get_inv_buf_size(indev_act->driver.disp);
|
||||
lv_disp_pop_from_inv_buf(indev_act->driver.disp, new_inv_buf_size - inv_buf_size);
|
||||
lv_disp_pop_from_inv_buf(indev_act->driver.disp,
|
||||
new_inv_buf_size - inv_buf_size);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1072,8 +1097,7 @@ static void indev_drag_throw(lv_indev_proc_t * proc)
|
||||
lv_obj_t * drag_obj = proc->types.pointer.last_obj;
|
||||
|
||||
/*If drag parent is active check recursively the drag_parent attribute*/
|
||||
while(lv_obj_get_drag_parent(drag_obj) != false &&
|
||||
drag_obj != NULL) {
|
||||
while(lv_obj_get_drag_parent(drag_obj) != false && drag_obj != NULL) {
|
||||
drag_obj = lv_obj_get_parent(drag_obj);
|
||||
}
|
||||
|
||||
@ -1089,11 +1113,12 @@ static void indev_drag_throw(lv_indev_proc_t * proc)
|
||||
}
|
||||
|
||||
/*Reduce the vectors*/
|
||||
proc->types.pointer.drag_throw_vect.x = proc->types.pointer.drag_throw_vect.x * (100 - indev_act->driver.drag_throw) / 100;
|
||||
proc->types.pointer.drag_throw_vect.y = proc->types.pointer.drag_throw_vect.y * (100 - indev_act->driver.drag_throw) / 100;
|
||||
proc->types.pointer.drag_throw_vect.x =
|
||||
proc->types.pointer.drag_throw_vect.x * (100 - indev_act->driver.drag_throw) / 100;
|
||||
proc->types.pointer.drag_throw_vect.y =
|
||||
proc->types.pointer.drag_throw_vect.y * (100 - indev_act->driver.drag_throw) / 100;
|
||||
|
||||
if(proc->types.pointer.drag_throw_vect.x != 0 ||
|
||||
proc->types.pointer.drag_throw_vect.y != 0) {
|
||||
if(proc->types.pointer.drag_throw_vect.x != 0 || proc->types.pointer.drag_throw_vect.y != 0) {
|
||||
/*Get the coordinates and modify them*/
|
||||
lv_area_t coords_ori;
|
||||
lv_obj_get_coords(drag_obj, &coords_ori);
|
||||
@ -1106,22 +1131,21 @@ static void indev_drag_throw(lv_indev_proc_t * proc)
|
||||
|
||||
/*If non of the coordinates are changed then do not continue throwing*/
|
||||
if((coords_ori.x1 == coord_new.x1 || proc->types.pointer.drag_throw_vect.x == 0) &&
|
||||
(coords_ori.y1 == coord_new.y1 || proc->types.pointer.drag_throw_vect.y == 0)) {
|
||||
proc->types.pointer.drag_in_prog = 0;
|
||||
proc->types.pointer.vect.x = 0;
|
||||
proc->types.pointer.vect.y = 0;
|
||||
(coords_ori.y1 == coord_new.y1 || proc->types.pointer.drag_throw_vect.y == 0)) {
|
||||
proc->types.pointer.drag_in_prog = 0;
|
||||
proc->types.pointer.vect.x = 0;
|
||||
proc->types.pointer.vect.y = 0;
|
||||
proc->types.pointer.drag_throw_vect.x = 0;
|
||||
proc->types.pointer.drag_throw_vect.y = 0;
|
||||
drag_obj->signal_cb(drag_obj, LV_SIGNAL_DRAG_END, indev_act);
|
||||
if(proc->reset_query) return; /*The object might be deleted*/
|
||||
|
||||
if(proc->reset_query) return; /*The object might be deleted*/
|
||||
}
|
||||
}
|
||||
/*If the types.pointer.vectors become 0 -> types.pointer.drag_in_prog = 0 and send a drag end signal*/
|
||||
/*If the types.pointer.vectors become 0 -> types.pointer.drag_in_prog = 0 and send a drag end
|
||||
signal*/
|
||||
else {
|
||||
proc->types.pointer.drag_in_prog = 0;
|
||||
drag_obj->signal_cb(drag_obj, LV_SIGNAL_DRAG_END, indev_act);
|
||||
if(proc->reset_query) return; /*The object might be deleted*/
|
||||
if(proc->reset_query) return; /*The object might be deleted*/
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -42,11 +42,11 @@ void lv_indev_read_task(void * param);
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @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
|
||||
@ -78,7 +78,7 @@ void lv_indev_enable(lv_indev_t * indev, bool en);
|
||||
* @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);
|
||||
void lv_indev_set_cursor(lv_indev_t * indev, lv_obj_t * cur_obj);
|
||||
|
||||
#if LV_USE_GROUP
|
||||
/**
|
||||
@ -86,7 +86,7 @@ void lv_indev_set_cursor(lv_indev_t *indev, lv_obj_t *cur_obj);
|
||||
* @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);
|
||||
void lv_indev_set_group(lv_indev_t * indev, lv_group_t * group);
|
||||
#endif
|
||||
|
||||
/**
|
||||
@ -95,14 +95,14 @@ void lv_indev_set_group(lv_indev_t *indev, lv_group_t *group);
|
||||
* @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);
|
||||
void lv_indev_set_button_points(lv_indev_t * indev, const lv_point_t * points);
|
||||
|
||||
/**
|
||||
* Set feedback callback for indev.
|
||||
* @param indev pointer to an input device
|
||||
* @param feedback feedback callback
|
||||
*/
|
||||
void lv_indev_set_feedback(lv_indev_t *indev, lv_indev_feedback_t feedback);
|
||||
void lv_indev_set_feedback(lv_indev_t * indev, lv_indev_feedback_t feedback);
|
||||
|
||||
/**
|
||||
* Get the last point of an input device (for LV_INDEV_TYPE_POINTER and LV_INDEV_TYPE_BUTTON)
|
||||
@ -119,14 +119,16 @@ void lv_indev_get_point(const lv_indev_t * indev, lv_point_t * point);
|
||||
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)
|
||||
* 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)
|
||||
* 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
|
||||
*/
|
||||
@ -137,7 +139,7 @@ void lv_indev_get_vect(const lv_indev_t * indev, lv_point_t * point);
|
||||
* @param indev pointer to an input device
|
||||
* @return feedback callback
|
||||
*/
|
||||
lv_indev_feedback_t lv_indev_get_feedback(const lv_indev_t *indev);
|
||||
lv_indev_feedback_t lv_indev_get_feedback(const lv_indev_t * indev);
|
||||
|
||||
/**
|
||||
* Do nothing until the next release
|
||||
@ -157,9 +159,8 @@ lv_task_t * lv_indev_get_read_task(lv_disp_t * indev);
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_INDEV_H*/
|
||||
#endif /*LV_INDEV_H*/
|
||||
|
@ -22,14 +22,14 @@
|
||||
#include "../lv_misc/lv_gc.h"
|
||||
|
||||
#if defined(LV_GC_INCLUDE)
|
||||
# include LV_GC_INCLUDE
|
||||
#include LV_GC_INCLUDE
|
||||
#endif /* LV_ENABLE_GC */
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define LV_OBJ_DEF_WIDTH (LV_DPI)
|
||||
#define LV_OBJ_DEF_HEIGHT (2 * LV_DPI / 3)
|
||||
#define LV_OBJ_DEF_WIDTH (LV_DPI)
|
||||
#define LV_OBJ_DEF_HEIGHT (2 * LV_DPI / 3)
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
@ -42,16 +42,16 @@ static void refresh_children_position(lv_obj_t * obj, lv_coord_t x_diff, lv_coor
|
||||
static void report_style_mod_core(void * style_p, lv_obj_t * obj);
|
||||
static void refresh_children_style(lv_obj_t * obj);
|
||||
static void delete_children(lv_obj_t * obj);
|
||||
static bool lv_obj_design(lv_obj_t * obj, const lv_area_t * mask_p, lv_design_mode_t mode);
|
||||
static bool lv_obj_design(lv_obj_t * obj, const lv_area_t * mask_p, lv_design_mode_t mode);
|
||||
static lv_res_t lv_obj_signal(lv_obj_t * obj, lv_signal_t sign, void * param);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
static bool lv_initialized = false;
|
||||
static lv_obj_t * event_act_obj; /*Stores the which event is currently being executed*/
|
||||
static bool event_act_obj_deleted; /*Shows that the object was deleted in the event function*/
|
||||
static const void * event_act_data; /*Stores the data passed to the event*/
|
||||
static lv_obj_t * event_act_obj; /*Stores the which event is currently being executed*/
|
||||
static bool event_act_obj_deleted; /*Shows that the object was deleted in the event function*/
|
||||
static const void * event_act_data; /*Stores the data passed to the event*/
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
@ -66,7 +66,7 @@ static const void * event_act_data; /*Stores the data passed to the ev
|
||||
void lv_init(void)
|
||||
{
|
||||
/* Do nothing if already initialized */
|
||||
if (lv_initialized) {
|
||||
if(lv_initialized) {
|
||||
LV_LOG_WARN("lv_init: already inited");
|
||||
return;
|
||||
}
|
||||
@ -99,7 +99,6 @@ void lv_init(void)
|
||||
lv_ll_init(&LV_GC_ROOT(_lv_disp_ll), sizeof(lv_disp_t));
|
||||
lv_ll_init(&LV_GC_ROOT(_lv_indev_ll), sizeof(lv_indev_t));
|
||||
|
||||
|
||||
#if LV_INDEV_READ_PERIOD != 0
|
||||
/*Init the input device handling*/
|
||||
lv_indev_init();
|
||||
@ -120,7 +119,7 @@ void lv_init(void)
|
||||
* @param copy pointer to a base object, if not NULL then the new object will be copied from it
|
||||
* @return pointer to the new object
|
||||
*/
|
||||
lv_obj_t * lv_obj_create(lv_obj_t * parent, const lv_obj_t * copy)
|
||||
lv_obj_t * lv_obj_create(lv_obj_t * parent, const lv_obj_t * copy)
|
||||
{
|
||||
|
||||
lv_obj_t * new_obj = NULL;
|
||||
@ -129,7 +128,8 @@ lv_obj_t * lv_obj_create(lv_obj_t * parent, const lv_obj_t * copy)
|
||||
LV_LOG_TRACE("Screen create started");
|
||||
lv_disp_t * disp = lv_disp_get_default();
|
||||
if(!disp) {
|
||||
LV_LOG_WARN("lv_obj_create: not display created to so far. No place to assign the new screen");
|
||||
LV_LOG_WARN(
|
||||
"lv_obj_create: not display created to so far. No place to assign the new screen");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -145,14 +145,14 @@ lv_obj_t * lv_obj_create(lv_obj_t * parent, const lv_obj_t * copy)
|
||||
new_obj->coords.y1 = 0;
|
||||
new_obj->coords.x2 = lv_disp_get_hor_res(NULL) - 1;
|
||||
new_obj->coords.y2 = lv_disp_get_ver_res(NULL) - 1;
|
||||
new_obj->ext_size = 0;
|
||||
new_obj->ext_size = 0;
|
||||
|
||||
/*Init realign*/
|
||||
#if LV_OBJ_REALIGN
|
||||
new_obj->realign.align = LV_ALIGN_CENTER;
|
||||
new_obj->realign.xofs = 0;
|
||||
new_obj->realign.yofs = 0;
|
||||
new_obj->realign.base = NULL;
|
||||
new_obj->realign.align = LV_ALIGN_CENTER;
|
||||
new_obj->realign.xofs = 0;
|
||||
new_obj->realign.yofs = 0;
|
||||
new_obj->realign.base = NULL;
|
||||
new_obj->realign.auto_realign = 0;
|
||||
#endif
|
||||
|
||||
@ -182,15 +182,15 @@ lv_obj_t * lv_obj_create(lv_obj_t * parent, const lv_obj_t * copy)
|
||||
new_obj->group_p = NULL;
|
||||
#endif
|
||||
/*Set attributes*/
|
||||
new_obj->click = 0;
|
||||
new_obj->drag = 0;
|
||||
new_obj->drag_throw = 0;
|
||||
new_obj->drag_parent = 0;
|
||||
new_obj->hidden = 0;
|
||||
new_obj->top = 0;
|
||||
new_obj->protect = LV_PROTECT_NONE;
|
||||
new_obj->click = 0;
|
||||
new_obj->drag = 0;
|
||||
new_obj->drag_throw = 0;
|
||||
new_obj->drag_parent = 0;
|
||||
new_obj->hidden = 0;
|
||||
new_obj->top = 0;
|
||||
new_obj->protect = LV_PROTECT_NONE;
|
||||
new_obj->opa_scale_en = 0;
|
||||
new_obj->opa_scale = LV_OPA_COVER;
|
||||
new_obj->opa_scale = LV_OPA_COVER;
|
||||
new_obj->parent_event = 0;
|
||||
|
||||
new_obj->ext_attr = NULL;
|
||||
@ -205,25 +205,22 @@ lv_obj_t * lv_obj_create(lv_obj_t * parent, const lv_obj_t * copy)
|
||||
lv_mem_assert(new_obj);
|
||||
if(new_obj == NULL) return NULL;
|
||||
|
||||
|
||||
new_obj->par = parent; /*Set the parent*/
|
||||
lv_ll_init(&(new_obj->child_ll), sizeof(lv_obj_t));
|
||||
|
||||
/*Set coordinates left top corner of parent*/
|
||||
new_obj->coords.x1 = parent->coords.x1;
|
||||
new_obj->coords.y1 = parent->coords.y1;
|
||||
new_obj->coords.x2 = parent->coords.x1 +
|
||||
LV_OBJ_DEF_WIDTH;
|
||||
new_obj->coords.y2 = parent->coords.y1 +
|
||||
LV_OBJ_DEF_HEIGHT;
|
||||
new_obj->ext_size = 0;
|
||||
new_obj->coords.x2 = parent->coords.x1 + LV_OBJ_DEF_WIDTH;
|
||||
new_obj->coords.y2 = parent->coords.y1 + LV_OBJ_DEF_HEIGHT;
|
||||
new_obj->ext_size = 0;
|
||||
|
||||
/*Init realign*/
|
||||
#if LV_OBJ_REALIGN
|
||||
new_obj->realign.align = LV_ALIGN_CENTER;
|
||||
new_obj->realign.xofs = 0;
|
||||
new_obj->realign.yofs = 0;
|
||||
new_obj->realign.base = NULL;
|
||||
new_obj->realign.align = LV_ALIGN_CENTER;
|
||||
new_obj->realign.xofs = 0;
|
||||
new_obj->realign.yofs = 0;
|
||||
new_obj->realign.base = NULL;
|
||||
new_obj->realign.auto_realign = 0;
|
||||
#endif
|
||||
/*Set appearance*/
|
||||
@ -254,14 +251,14 @@ lv_obj_t * lv_obj_create(lv_obj_t * parent, const lv_obj_t * copy)
|
||||
#endif
|
||||
|
||||
/*Set attributes*/
|
||||
new_obj->click = 1;
|
||||
new_obj->drag = 0;
|
||||
new_obj->drag_throw = 0;
|
||||
new_obj->drag_parent = 0;
|
||||
new_obj->hidden = 0;
|
||||
new_obj->top = 0;
|
||||
new_obj->protect = LV_PROTECT_NONE;
|
||||
new_obj->opa_scale = LV_OPA_COVER;
|
||||
new_obj->click = 1;
|
||||
new_obj->drag = 0;
|
||||
new_obj->drag_throw = 0;
|
||||
new_obj->drag_parent = 0;
|
||||
new_obj->hidden = 0;
|
||||
new_obj->top = 0;
|
||||
new_obj->protect = LV_PROTECT_NONE;
|
||||
new_obj->opa_scale = LV_OPA_COVER;
|
||||
new_obj->opa_scale_en = 0;
|
||||
new_obj->parent_event = 0;
|
||||
|
||||
@ -285,28 +282,29 @@ lv_obj_t * lv_obj_create(lv_obj_t * parent, const lv_obj_t * copy)
|
||||
|
||||
/*Copy realign*/
|
||||
#if LV_OBJ_REALIGN
|
||||
new_obj->realign.align = copy->realign.align;
|
||||
new_obj->realign.xofs = copy->realign.xofs;
|
||||
new_obj->realign.yofs = copy->realign.yofs;
|
||||
new_obj->realign.base = copy->realign.base;
|
||||
new_obj->realign.align = copy->realign.align;
|
||||
new_obj->realign.xofs = copy->realign.xofs;
|
||||
new_obj->realign.yofs = copy->realign.yofs;
|
||||
new_obj->realign.base = copy->realign.base;
|
||||
new_obj->realign.auto_realign = copy->realign.auto_realign;
|
||||
#endif
|
||||
|
||||
/*Only copy the `event_cb`. `signal_cb` and `design_cb` will be copied the the derived object type (e.g. `lv_btn`)*/
|
||||
new_obj-> event_cb = copy->event_cb;
|
||||
/*Only copy the `event_cb`. `signal_cb` and `design_cb` will be copied the the derived
|
||||
* object type (e.g. `lv_btn`)*/
|
||||
new_obj->event_cb = copy->event_cb;
|
||||
|
||||
/*Copy attributes*/
|
||||
new_obj->click = copy->click;
|
||||
new_obj->drag = copy->drag;
|
||||
new_obj->drag_throw = copy->drag_throw;
|
||||
new_obj->drag_parent = copy->drag_parent;
|
||||
new_obj->hidden = copy->hidden;
|
||||
new_obj->top = copy->top;
|
||||
new_obj->click = copy->click;
|
||||
new_obj->drag = copy->drag;
|
||||
new_obj->drag_throw = copy->drag_throw;
|
||||
new_obj->drag_parent = copy->drag_parent;
|
||||
new_obj->hidden = copy->hidden;
|
||||
new_obj->top = copy->top;
|
||||
new_obj->parent_event = copy->parent_event;
|
||||
|
||||
new_obj->opa_scale_en = copy->opa_scale_en;
|
||||
new_obj->protect = copy->protect;
|
||||
new_obj->opa_scale = copy->opa_scale;
|
||||
new_obj->protect = copy->protect;
|
||||
new_obj->opa_scale = copy->opa_scale;
|
||||
|
||||
new_obj->style_p = copy->style_p;
|
||||
|
||||
@ -322,7 +320,6 @@ lv_obj_t * lv_obj_create(lv_obj_t * parent, const lv_obj_t * copy)
|
||||
LV_LOG_INFO("Object create ready");
|
||||
}
|
||||
|
||||
|
||||
/*Send a signal to the parent to notify it about the new child*/
|
||||
if(parent != NULL) {
|
||||
parent->signal_cb(parent, LV_SIGNAL_CHILD_CHG, new_obj);
|
||||
@ -345,7 +342,7 @@ lv_res_t lv_obj_del(lv_obj_t * obj)
|
||||
|
||||
if(event_act_obj == obj && event_act_obj_deleted == false) event_act_obj_deleted = true;
|
||||
|
||||
/*Delete from the group*/
|
||||
/*Delete from the group*/
|
||||
#if LV_USE_GROUP
|
||||
bool was_focused = false;
|
||||
|
||||
@ -405,7 +402,7 @@ lv_res_t lv_obj_del(lv_obj_t * obj)
|
||||
obj->signal_cb(obj, LV_SIGNAL_CLEANUP, NULL);
|
||||
|
||||
/*Delete the base objects*/
|
||||
if(obj->ext_attr != NULL) lv_mem_free(obj->ext_attr);
|
||||
if(obj->ext_attr != NULL) lv_mem_free(obj->ext_attr);
|
||||
lv_mem_free(obj); /*Free the object itself*/
|
||||
|
||||
/*Send a signal to the parent to notify it about the child delete*/
|
||||
@ -443,14 +440,13 @@ void lv_obj_invalidate(const lv_obj_t * obj)
|
||||
|
||||
/*Invalidate the object only if it belongs to the 'LV_GC_ROOT(_lv_act_scr)'*/
|
||||
lv_obj_t * obj_scr = lv_obj_get_screen(obj);
|
||||
lv_disp_t * disp = lv_obj_get_disp(obj_scr);
|
||||
if(obj_scr == lv_disp_get_scr_act(disp) ||
|
||||
obj_scr == lv_disp_get_layer_top(disp)||
|
||||
obj_scr == lv_disp_get_layer_sys(disp)) {
|
||||
lv_disp_t * disp = lv_obj_get_disp(obj_scr);
|
||||
if(obj_scr == lv_disp_get_scr_act(disp) || obj_scr == lv_disp_get_layer_top(disp) ||
|
||||
obj_scr == lv_disp_get_layer_sys(disp)) {
|
||||
/*Truncate recursively to the parents*/
|
||||
lv_area_t area_trunc;
|
||||
lv_obj_t * par = lv_obj_get_parent(obj);
|
||||
bool union_ok = true;
|
||||
bool union_ok = true;
|
||||
/*Start with the original coordinates*/
|
||||
lv_coord_t ext_size = obj->ext_size;
|
||||
lv_area_copy(&area_trunc, &obj->coords);
|
||||
@ -462,8 +458,9 @@ void lv_obj_invalidate(const lv_obj_t * obj)
|
||||
/*Check through all parents*/
|
||||
while(par != NULL) {
|
||||
union_ok = lv_area_intersect(&area_trunc, &area_trunc, &par->coords);
|
||||
if(union_ok == false) break; /*If no common parts with parent break;*/
|
||||
if(lv_obj_get_hidden(par)) return; /*If the parent is hidden then the child is hidden and won't be drawn*/
|
||||
if(union_ok == false) break; /*If no common parts with parent break;*/
|
||||
if(lv_obj_get_hidden(par))
|
||||
return; /*If the parent is hidden then the child is hidden and won't be drawn*/
|
||||
|
||||
par = lv_obj_get_parent(par);
|
||||
}
|
||||
@ -472,7 +469,6 @@ void lv_obj_invalidate(const lv_obj_t * obj)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*=====================
|
||||
* Setter functions
|
||||
*====================*/
|
||||
@ -498,7 +494,6 @@ void lv_obj_set_parent(lv_obj_t * obj, lv_obj_t * parent)
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
lv_obj_invalidate(obj);
|
||||
|
||||
lv_point_t old_pos;
|
||||
@ -534,13 +529,13 @@ void lv_obj_set_pos(lv_obj_t * obj, lv_coord_t x, lv_coord_t y)
|
||||
{
|
||||
/*Convert x and y to absolute coordinates*/
|
||||
lv_obj_t * par = obj->par;
|
||||
x = x + par->coords.x1;
|
||||
y = y + par->coords.y1;
|
||||
x = x + par->coords.x1;
|
||||
y = y + par->coords.y1;
|
||||
|
||||
/*Calculate and set the movement*/
|
||||
lv_point_t diff;
|
||||
diff.x = x - obj->coords.x1;
|
||||
diff.y = y - obj->coords.y1;
|
||||
diff.x = x - obj->coords.x1;
|
||||
diff.y = y - obj->coords.y1;
|
||||
|
||||
/* Do nothing if the position is not changed */
|
||||
/* It is very important else recursive positioning can
|
||||
@ -571,7 +566,6 @@ void lv_obj_set_pos(lv_obj_t * obj, lv_coord_t x, lv_coord_t y)
|
||||
lv_obj_invalidate(obj);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the x coordinate of a object
|
||||
* @param obj pointer to an object
|
||||
@ -582,7 +576,6 @@ void lv_obj_set_x(lv_obj_t * obj, lv_coord_t x)
|
||||
lv_obj_set_pos(obj, x, lv_obj_get_y(obj));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the y coordinate of a object
|
||||
* @param obj pointer to an object
|
||||
@ -616,11 +609,10 @@ void lv_obj_set_size(lv_obj_t * obj, lv_coord_t w, lv_coord_t h)
|
||||
lv_area_t ori;
|
||||
lv_obj_get_coords(obj, &ori);
|
||||
|
||||
//Set the length and height
|
||||
// Set the length and height
|
||||
obj->coords.x2 = obj->coords.x1 + w - 1;
|
||||
obj->coords.y2 = obj->coords.y1 + h - 1;
|
||||
|
||||
|
||||
/*Send a signal to the object with its new coordinates*/
|
||||
obj->signal_cb(obj, LV_SIGNAL_CORD_CHG, &ori);
|
||||
|
||||
@ -630,8 +622,9 @@ void lv_obj_set_size(lv_obj_t * obj, lv_coord_t w, lv_coord_t h)
|
||||
|
||||
/*Tell the children the parent's size has changed*/
|
||||
lv_obj_t * i;
|
||||
LV_LL_READ(obj->child_ll, i) {
|
||||
i->signal_cb(i, LV_SIGNAL_PARENT_SIZE_CHG, NULL);
|
||||
LV_LL_READ(obj->child_ll, i)
|
||||
{
|
||||
i->signal_cb(i, LV_SIGNAL_PARENT_SIZE_CHG, NULL);
|
||||
}
|
||||
|
||||
/*Invalidate the new area*/
|
||||
@ -671,7 +664,8 @@ void lv_obj_set_height(lv_obj_t * obj, lv_coord_t h)
|
||||
* @param x_mod x coordinate shift after alignment
|
||||
* @param y_mod y coordinate shift after alignment
|
||||
*/
|
||||
void lv_obj_align(lv_obj_t * obj, const lv_obj_t * base, lv_align_t align, lv_coord_t x_mod, lv_coord_t y_mod)
|
||||
void lv_obj_align(lv_obj_t * obj, const lv_obj_t * base, lv_align_t align, lv_coord_t x_mod,
|
||||
lv_coord_t y_mod)
|
||||
{
|
||||
lv_coord_t new_x = lv_obj_get_x(obj);
|
||||
lv_coord_t new_y = lv_obj_get_y(obj);
|
||||
@ -731,12 +725,12 @@ void lv_obj_align(lv_obj_t * obj, const lv_obj_t * base, lv_align_t align, lv_co
|
||||
|
||||
case LV_ALIGN_OUT_TOP_MID:
|
||||
new_x = lv_obj_get_width(base) / 2 - lv_obj_get_width(obj) / 2;
|
||||
new_y = - lv_obj_get_height(obj);
|
||||
new_y = -lv_obj_get_height(obj);
|
||||
break;
|
||||
|
||||
case LV_ALIGN_OUT_TOP_RIGHT:
|
||||
new_x = lv_obj_get_width(base) - lv_obj_get_width(obj);
|
||||
new_y = - lv_obj_get_height(obj);
|
||||
new_y = -lv_obj_get_height(obj);
|
||||
break;
|
||||
|
||||
case LV_ALIGN_OUT_BOTTOM_LEFT:
|
||||
@ -755,17 +749,17 @@ void lv_obj_align(lv_obj_t * obj, const lv_obj_t * base, lv_align_t align, lv_co
|
||||
break;
|
||||
|
||||
case LV_ALIGN_OUT_LEFT_TOP:
|
||||
new_x = - lv_obj_get_width(obj);
|
||||
new_x = -lv_obj_get_width(obj);
|
||||
new_y = 0;
|
||||
break;
|
||||
|
||||
case LV_ALIGN_OUT_LEFT_MID:
|
||||
new_x = - lv_obj_get_width(obj);
|
||||
new_x = -lv_obj_get_width(obj);
|
||||
new_y = lv_obj_get_height(base) / 2 - lv_obj_get_height(obj) / 2;
|
||||
break;
|
||||
|
||||
case LV_ALIGN_OUT_LEFT_BOTTOM:
|
||||
new_x = - lv_obj_get_width(obj);
|
||||
new_x = -lv_obj_get_width(obj);
|
||||
new_y = lv_obj_get_height(base) - lv_obj_get_height(obj);
|
||||
break;
|
||||
|
||||
@ -786,11 +780,11 @@ void lv_obj_align(lv_obj_t * obj, const lv_obj_t * base, lv_align_t align, lv_co
|
||||
}
|
||||
|
||||
/*Bring together the coordination system of base and obj*/
|
||||
lv_obj_t * par = lv_obj_get_parent(obj);
|
||||
lv_obj_t * par = lv_obj_get_parent(obj);
|
||||
lv_coord_t base_abs_x = base->coords.x1;
|
||||
lv_coord_t base_abs_y = base->coords.y1;
|
||||
lv_coord_t par_abs_x = par->coords.x1;
|
||||
lv_coord_t par_abs_y = par->coords.y1;
|
||||
lv_coord_t par_abs_x = par->coords.x1;
|
||||
lv_coord_t par_abs_y = par->coords.y1;
|
||||
new_x += x_mod + base_abs_x;
|
||||
new_y += y_mod + base_abs_y;
|
||||
new_x -= par_abs_x;
|
||||
@ -800,10 +794,10 @@ void lv_obj_align(lv_obj_t * obj, const lv_obj_t * base, lv_align_t align, lv_co
|
||||
|
||||
#if LV_OBJ_REALIGN
|
||||
/*Save the last align parameters to use them in `lv_obj_realign`*/
|
||||
obj->realign.align = align;
|
||||
obj->realign.xofs = x_mod;
|
||||
obj->realign.yofs = y_mod;
|
||||
obj->realign.base = base;
|
||||
obj->realign.align = align;
|
||||
obj->realign.xofs = x_mod;
|
||||
obj->realign.yofs = y_mod;
|
||||
obj->realign.base = base;
|
||||
obj->realign.origo_align = 0;
|
||||
#endif
|
||||
}
|
||||
@ -816,12 +810,13 @@ void lv_obj_align(lv_obj_t * obj, const lv_obj_t * base, lv_align_t align, lv_co
|
||||
* @param x_mod x coordinate shift after alignment
|
||||
* @param y_mod y coordinate shift after alignment
|
||||
*/
|
||||
void lv_obj_align_origo(lv_obj_t * obj, const lv_obj_t * base, lv_align_t align, lv_coord_t x_mod, lv_coord_t y_mod)
|
||||
void lv_obj_align_origo(lv_obj_t * obj, const lv_obj_t * base, lv_align_t align, lv_coord_t x_mod,
|
||||
lv_coord_t y_mod)
|
||||
{
|
||||
lv_coord_t new_x = lv_obj_get_x(obj);
|
||||
lv_coord_t new_y = lv_obj_get_y(obj);
|
||||
|
||||
lv_coord_t obj_w_half = lv_obj_get_width(obj) / 2;
|
||||
lv_coord_t obj_w_half = lv_obj_get_width(obj) / 2;
|
||||
lv_coord_t obj_h_half = lv_obj_get_height(obj) / 2;
|
||||
|
||||
if(base == NULL) {
|
||||
@ -884,7 +879,7 @@ void lv_obj_align_origo(lv_obj_t * obj, const lv_obj_t * base, lv_align_t align,
|
||||
|
||||
case LV_ALIGN_OUT_TOP_RIGHT:
|
||||
new_x = lv_obj_get_width(base) - obj_w_half;
|
||||
new_y = - obj_h_half;
|
||||
new_y = -obj_h_half;
|
||||
break;
|
||||
|
||||
case LV_ALIGN_OUT_BOTTOM_LEFT:
|
||||
@ -903,17 +898,17 @@ void lv_obj_align_origo(lv_obj_t * obj, const lv_obj_t * base, lv_align_t align,
|
||||
break;
|
||||
|
||||
case LV_ALIGN_OUT_LEFT_TOP:
|
||||
new_x = - obj_w_half ;
|
||||
new_y = - obj_h_half;
|
||||
new_x = -obj_w_half;
|
||||
new_y = -obj_h_half;
|
||||
break;
|
||||
|
||||
case LV_ALIGN_OUT_LEFT_MID:
|
||||
new_x = - obj_w_half;
|
||||
new_x = -obj_w_half;
|
||||
new_y = lv_obj_get_height(base) / 2 - obj_h_half;
|
||||
break;
|
||||
|
||||
case LV_ALIGN_OUT_LEFT_BOTTOM:
|
||||
new_x = - obj_w_half;
|
||||
new_x = -obj_w_half;
|
||||
new_y = lv_obj_get_height(base) - obj_h_half;
|
||||
break;
|
||||
|
||||
@ -934,11 +929,11 @@ void lv_obj_align_origo(lv_obj_t * obj, const lv_obj_t * base, lv_align_t align,
|
||||
}
|
||||
|
||||
/*Bring together the coordination system of base and obj*/
|
||||
lv_obj_t * par = lv_obj_get_parent(obj);
|
||||
lv_obj_t * par = lv_obj_get_parent(obj);
|
||||
lv_coord_t base_abs_x = base->coords.x1;
|
||||
lv_coord_t base_abs_y = base->coords.y1;
|
||||
lv_coord_t par_abs_x = par->coords.x1;
|
||||
lv_coord_t par_abs_y = par->coords.y1;
|
||||
lv_coord_t par_abs_x = par->coords.x1;
|
||||
lv_coord_t par_abs_y = par->coords.y1;
|
||||
new_x += x_mod + base_abs_x;
|
||||
new_y += y_mod + base_abs_y;
|
||||
new_x -= par_abs_x;
|
||||
@ -948,10 +943,10 @@ void lv_obj_align_origo(lv_obj_t * obj, const lv_obj_t * base, lv_align_t align,
|
||||
|
||||
#if LV_OBJ_REALIGN
|
||||
/*Save the last align parameters to use them in `lv_obj_realign`*/
|
||||
obj->realign.align = align;
|
||||
obj->realign.xofs = x_mod;
|
||||
obj->realign.yofs = y_mod;
|
||||
obj->realign.base = base;
|
||||
obj->realign.align = align;
|
||||
obj->realign.xofs = x_mod;
|
||||
obj->realign.yofs = y_mod;
|
||||
obj->realign.base = base;
|
||||
obj->realign.origo_align = 1;
|
||||
#endif
|
||||
}
|
||||
@ -963,16 +958,21 @@ void lv_obj_align_origo(lv_obj_t * obj, const lv_obj_t * base, lv_align_t align,
|
||||
void lv_obj_realign(lv_obj_t * obj)
|
||||
{
|
||||
#if LV_OBJ_REALIGN
|
||||
if(obj->realign.origo_align) lv_obj_align_origo(obj, obj->realign.base, obj->realign.align, obj->realign.xofs, obj->realign.yofs);
|
||||
else lv_obj_align(obj, obj->realign.base, obj->realign.align, obj->realign.xofs, obj->realign.yofs);
|
||||
if(obj->realign.origo_align)
|
||||
lv_obj_align_origo(obj, obj->realign.base, obj->realign.align, obj->realign.xofs,
|
||||
obj->realign.yofs);
|
||||
else
|
||||
lv_obj_align(obj, obj->realign.base, obj->realign.align, obj->realign.xofs,
|
||||
obj->realign.yofs);
|
||||
#else
|
||||
(void) obj;
|
||||
(void)obj;
|
||||
LV_LOG_WARN("lv_obj_realaign: no effect because LV_OBJ_REALIGN = 0");
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable the automatic realign of the object when its size has changed based on the last `lv_obj_align` parameters.
|
||||
* Enable the automatic realign of the object when its size has changed based on the last
|
||||
* `lv_obj_align` parameters.
|
||||
* @param obj pointer to an object
|
||||
* @param en true: enable auto realign; false: disable auto realign
|
||||
*/
|
||||
@ -981,8 +981,8 @@ void lv_obj_set_auto_realign(lv_obj_t * obj, bool en)
|
||||
#if LV_OBJ_REALIGN
|
||||
obj->realign.auto_realign = en ? 1 : 0;
|
||||
#else
|
||||
(void) obj;
|
||||
(void) en;
|
||||
(void)obj;
|
||||
(void)en;
|
||||
LV_LOG_WARN("lv_obj_set_auto_realign: no effect because LV_OBJ_REALIGN = 0");
|
||||
#endif
|
||||
}
|
||||
@ -1016,7 +1016,6 @@ void lv_obj_refresh_style(lv_obj_t * obj)
|
||||
lv_obj_invalidate(obj);
|
||||
obj->signal_cb(obj, LV_SIGNAL_STYLE_CHG, NULL);
|
||||
lv_obj_invalidate(obj);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1030,7 +1029,8 @@ void lv_obj_report_style_mod(lv_style_t * style)
|
||||
|
||||
while(d) {
|
||||
lv_obj_t * i;
|
||||
LV_LL_READ(d->scr_ll, i) {
|
||||
LV_LL_READ(d->scr_ll, i)
|
||||
{
|
||||
if(i->style_p == style || style == NULL) {
|
||||
lv_obj_refresh_style(i);
|
||||
}
|
||||
@ -1052,15 +1052,16 @@ void lv_obj_report_style_mod(lv_style_t * style)
|
||||
*/
|
||||
void lv_obj_set_hidden(lv_obj_t * obj, bool en)
|
||||
{
|
||||
if(!obj->hidden) lv_obj_invalidate(obj); /*Invalidate when not hidden (hidden objects are ignored) */
|
||||
if(!obj->hidden)
|
||||
lv_obj_invalidate(obj); /*Invalidate when not hidden (hidden objects are ignored) */
|
||||
|
||||
obj->hidden = en == false ? 0 : 1;
|
||||
|
||||
if(!obj->hidden) lv_obj_invalidate(obj); /*Invalidate when not hidden (hidden objects are ignored) */
|
||||
if(!obj->hidden)
|
||||
lv_obj_invalidate(obj); /*Invalidate when not hidden (hidden objects are ignored) */
|
||||
|
||||
lv_obj_t * par = lv_obj_get_parent(obj);
|
||||
par->signal_cb(par, LV_SIGNAL_CHILD_CHG, obj);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1091,7 +1092,7 @@ void lv_obj_set_top(lv_obj_t * obj, bool en)
|
||||
*/
|
||||
void lv_obj_set_drag(lv_obj_t * obj, bool en)
|
||||
{
|
||||
if(en == true) lv_obj_set_click(obj, true); /*Drag is useless without enabled clicking*/
|
||||
if(en == true) lv_obj_set_click(obj, true); /*Drag is useless without enabled clicking*/
|
||||
obj->drag = (en == true ? 1 : 0);
|
||||
}
|
||||
|
||||
@ -1133,7 +1134,7 @@ void lv_obj_set_parent_event(lv_obj_t * obj, bool en)
|
||||
*/
|
||||
void lv_obj_set_opa_scale_enable(lv_obj_t * obj, bool en)
|
||||
{
|
||||
obj->opa_scale_en = en ? 1 : 0;
|
||||
obj->opa_scale_en = en ? 1 : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1191,22 +1192,22 @@ lv_res_t lv_event_send(lv_obj_t * obj, lv_event_t event, const void * data)
|
||||
if(obj == NULL) return LV_RES_OK;
|
||||
|
||||
/*If the event was send from an other event save the current states to restore it at the end*/
|
||||
lv_obj_t * prev_obj_act = event_act_obj;
|
||||
lv_obj_t * prev_obj_act = event_act_obj;
|
||||
bool prev_obj_act_deleted = event_act_obj_deleted;
|
||||
const void * prev_data = event_act_data;
|
||||
const void * prev_data = event_act_data;
|
||||
|
||||
event_act_obj = obj;
|
||||
event_act_obj = obj;
|
||||
event_act_obj_deleted = false;
|
||||
event_act_data = data;
|
||||
event_act_data = data;
|
||||
|
||||
if(obj->event_cb) obj->event_cb(obj, event);
|
||||
|
||||
bool deleted = event_act_obj_deleted;
|
||||
|
||||
/*Restore the previous states*/
|
||||
event_act_obj = prev_obj_act;
|
||||
event_act_obj = prev_obj_act;
|
||||
event_act_obj_deleted = prev_obj_act_deleted;
|
||||
event_act_data = prev_data;
|
||||
event_act_data = prev_data;
|
||||
|
||||
if(deleted) {
|
||||
return LV_RES_INV;
|
||||
@ -1298,71 +1299,71 @@ void lv_obj_refresh_ext_size(lv_obj_t * obj)
|
||||
* @param delay delay before the animation in milliseconds
|
||||
* @param cb a function to call when the animation is ready
|
||||
*/
|
||||
void lv_obj_animate(lv_obj_t * obj, lv_anim_builtin_t type, uint16_t time, uint16_t delay, void (*cb)(lv_obj_t *))
|
||||
void lv_obj_animate(lv_obj_t * obj, lv_anim_builtin_t type, uint16_t time, uint16_t delay,
|
||||
void (*cb)(lv_obj_t *))
|
||||
{
|
||||
lv_obj_t * par = lv_obj_get_parent(obj);
|
||||
|
||||
/*Get the direction*/
|
||||
bool out = (type & LV_ANIM_DIR_MASK) == LV_ANIM_IN ? false : true;
|
||||
type = type & (~LV_ANIM_DIR_MASK);
|
||||
type = type & (~LV_ANIM_DIR_MASK);
|
||||
|
||||
lv_anim_t a;
|
||||
a.var = obj;
|
||||
a.time = time;
|
||||
a.act_time = (int32_t) - delay;
|
||||
a.end_cb = (void(*)(void *))cb;
|
||||
a.path = lv_anim_path_linear;
|
||||
a.var = obj;
|
||||
a.time = time;
|
||||
a.act_time = (int32_t)-delay;
|
||||
a.end_cb = (void (*)(void *))cb;
|
||||
a.path = lv_anim_path_linear;
|
||||
a.playback_pause = 0;
|
||||
a.repeat_pause = 0;
|
||||
a.playback = 0;
|
||||
a.repeat = 0;
|
||||
a.repeat_pause = 0;
|
||||
a.playback = 0;
|
||||
a.repeat = 0;
|
||||
|
||||
/*Init to ANIM_IN*/
|
||||
switch(type) {
|
||||
case LV_ANIM_FLOAT_LEFT:
|
||||
a.fp = (void(*)(void *, int32_t))lv_obj_set_x;
|
||||
a.fp = (void (*)(void *, int32_t))lv_obj_set_x;
|
||||
a.start = -lv_obj_get_width(obj);
|
||||
a.end = lv_obj_get_x(obj);
|
||||
a.end = lv_obj_get_x(obj);
|
||||
break;
|
||||
case LV_ANIM_FLOAT_RIGHT:
|
||||
a.fp = (void(*)(void *, int32_t))lv_obj_set_x;
|
||||
a.fp = (void (*)(void *, int32_t))lv_obj_set_x;
|
||||
a.start = lv_obj_get_width(par);
|
||||
a.end = lv_obj_get_x(obj);
|
||||
a.end = lv_obj_get_x(obj);
|
||||
break;
|
||||
case LV_ANIM_FLOAT_TOP:
|
||||
a.fp = (void(*)(void *, int32_t))lv_obj_set_y;
|
||||
a.fp = (void (*)(void *, int32_t))lv_obj_set_y;
|
||||
a.start = -lv_obj_get_height(obj);
|
||||
a.end = lv_obj_get_y(obj);
|
||||
a.end = lv_obj_get_y(obj);
|
||||
break;
|
||||
case LV_ANIM_FLOAT_BOTTOM:
|
||||
a.fp = (void(*)(void *, int32_t))lv_obj_set_y;
|
||||
a.fp = (void (*)(void *, int32_t))lv_obj_set_y;
|
||||
a.start = lv_obj_get_height(par);
|
||||
a.end = lv_obj_get_y(obj);
|
||||
a.end = lv_obj_get_y(obj);
|
||||
break;
|
||||
case LV_ANIM_GROW_H:
|
||||
a.fp = (void(*)(void *, int32_t))lv_obj_set_width;
|
||||
a.fp = (void (*)(void *, int32_t))lv_obj_set_width;
|
||||
a.start = 0;
|
||||
a.end = lv_obj_get_width(obj);
|
||||
a.end = lv_obj_get_width(obj);
|
||||
break;
|
||||
case LV_ANIM_GROW_V:
|
||||
a.fp = (void(*)(void *, int32_t))lv_obj_set_height;
|
||||
a.fp = (void (*)(void *, int32_t))lv_obj_set_height;
|
||||
a.start = 0;
|
||||
a.end = lv_obj_get_height(obj);
|
||||
a.end = lv_obj_get_height(obj);
|
||||
break;
|
||||
case LV_ANIM_NONE:
|
||||
a.fp = NULL;
|
||||
a.fp = NULL;
|
||||
a.start = 0;
|
||||
a.end = 0;
|
||||
break;
|
||||
default:
|
||||
a.end = 0;
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
/*Swap start and end in case of ANIM OUT*/
|
||||
if(out != false) {
|
||||
int32_t tmp = a.start;
|
||||
a.start = a.end;
|
||||
a.end = tmp;
|
||||
a.start = a.end;
|
||||
a.end = tmp;
|
||||
}
|
||||
|
||||
lv_anim_create(&a);
|
||||
@ -1386,7 +1387,7 @@ lv_obj_t * lv_obj_get_screen(const lv_obj_t * obj)
|
||||
|
||||
do {
|
||||
act_p = par;
|
||||
par = lv_obj_get_parent(act_p);
|
||||
par = lv_obj_get_parent(act_p);
|
||||
} while(par != NULL);
|
||||
|
||||
return (lv_obj_t *)act_p;
|
||||
@ -1401,13 +1402,17 @@ lv_disp_t * lv_obj_get_disp(const lv_obj_t * obj)
|
||||
{
|
||||
const lv_obj_t * scr;
|
||||
|
||||
if(obj->par == NULL) scr = obj; /*`obj` is a screen*/
|
||||
else scr = lv_obj_get_screen(obj); /*get the screen of `obj`*/
|
||||
if(obj->par == NULL)
|
||||
scr = obj; /*`obj` is a screen*/
|
||||
else
|
||||
scr = lv_obj_get_screen(obj); /*get the screen of `obj`*/
|
||||
|
||||
lv_disp_t * d;
|
||||
LV_LL_READ(LV_GC_ROOT(_lv_disp_ll), d) {
|
||||
LV_LL_READ(LV_GC_ROOT(_lv_disp_ll), d)
|
||||
{
|
||||
lv_obj_t * s;
|
||||
LV_LL_READ(d->scr_ll, s) {
|
||||
LV_LL_READ(d->scr_ll, s)
|
||||
{
|
||||
if(s == scr) return d;
|
||||
}
|
||||
}
|
||||
@ -1499,7 +1504,6 @@ void lv_obj_get_coords(const lv_obj_t * obj, lv_area_t * cords_p)
|
||||
lv_area_copy(cords_p, &obj->coords);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the x coordinate of object
|
||||
* @param obj pointer to an object
|
||||
@ -1509,7 +1513,7 @@ lv_coord_t lv_obj_get_x(const lv_obj_t * obj)
|
||||
{
|
||||
lv_coord_t rel_x;
|
||||
lv_obj_t * parent = lv_obj_get_parent(obj);
|
||||
rel_x = obj->coords.x1 - parent->coords.x1;
|
||||
rel_x = obj->coords.x1 - parent->coords.x1;
|
||||
|
||||
return rel_x;
|
||||
}
|
||||
@ -1523,7 +1527,7 @@ lv_coord_t lv_obj_get_y(const lv_obj_t * obj)
|
||||
{
|
||||
lv_coord_t rel_y;
|
||||
lv_obj_t * parent = lv_obj_get_parent(obj);
|
||||
rel_y = obj->coords.y1 - parent->coords.y1;
|
||||
rel_y = obj->coords.y1 - parent->coords.y1;
|
||||
|
||||
return rel_y;
|
||||
}
|
||||
@ -1591,7 +1595,7 @@ bool lv_obj_get_auto_realign(lv_obj_t * obj)
|
||||
#if LV_OBJ_REALIGN
|
||||
return obj->realign.auto_realign ? true : false;
|
||||
#else
|
||||
(void) obj;
|
||||
(void)obj;
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
@ -1752,7 +1756,7 @@ lv_opa_t lv_obj_get_opa_scale(const lv_obj_t * obj)
|
||||
*/
|
||||
uint8_t lv_obj_get_protect(const lv_obj_t * obj)
|
||||
{
|
||||
return obj->protect ;
|
||||
return obj->protect;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1763,7 +1767,7 @@ uint8_t lv_obj_get_protect(const lv_obj_t * obj)
|
||||
*/
|
||||
bool lv_obj_is_protected(const lv_obj_t * obj, uint8_t prot)
|
||||
{
|
||||
return (obj->protect & prot) == 0 ? false : true ;
|
||||
return (obj->protect & prot) == 0 ? false : true;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1821,7 +1825,6 @@ void lv_obj_get_type(lv_obj_t * obj, lv_obj_type_t * buf)
|
||||
if(tmp.type[cnt] == NULL) break;
|
||||
}
|
||||
|
||||
|
||||
/*Swap the order. The real type comes first*/
|
||||
uint8_t i;
|
||||
for(i = 0; i < cnt; i++) {
|
||||
@ -1880,7 +1883,7 @@ bool lv_obj_is_focused(const lv_obj_t * obj)
|
||||
* LV_DESIGN_DRAW: draw the object (always return 'true')
|
||||
* @param return true/false, depends on 'mode'
|
||||
*/
|
||||
static bool lv_obj_design(lv_obj_t * obj, const lv_area_t * mask_p, lv_design_mode_t mode)
|
||||
static bool lv_obj_design(lv_obj_t * obj, const lv_area_t * mask_p, lv_design_mode_t mode)
|
||||
{
|
||||
if(mode == LV_DESIGN_COVER_CHK) {
|
||||
|
||||
@ -1934,11 +1937,10 @@ static lv_res_t lv_obj_signal(lv_obj_t * obj, lv_signal_t sign, void * param)
|
||||
|
||||
lv_style_t * style = lv_obj_get_style(obj);
|
||||
|
||||
lv_indev_t *indev_act = lv_indev_get_act();
|
||||
lv_indev_t * indev_act = lv_indev_get_act();
|
||||
|
||||
if(sign > _LV_SIGNAL_FEEDBACK_SECTION_START && sign < _LV_SIGNAL_FEEDBACK_SECTION_END) {
|
||||
if(indev_act != NULL && indev_act->feedback != NULL)
|
||||
indev_act->feedback(indev_act, sign);
|
||||
if(indev_act != NULL && indev_act->feedback != NULL) indev_act->feedback(indev_act, sign);
|
||||
}
|
||||
|
||||
if(sign == LV_SIGNAL_CHILD_CHG) {
|
||||
@ -1946,11 +1948,11 @@ static lv_res_t lv_obj_signal(lv_obj_t * obj, lv_signal_t sign, void * param)
|
||||
if(lv_obj_is_protected(obj, LV_PROTECT_CHILD_CHG) != false) res = LV_RES_INV;
|
||||
} else if(sign == LV_SIGNAL_REFR_EXT_SIZE) {
|
||||
if(style->body.shadow.width > obj->ext_size) obj->ext_size = style->body.shadow.width;
|
||||
} else if(sign == LV_SIGNAL_STYLE_CHG) {
|
||||
} else if(sign == LV_SIGNAL_STYLE_CHG) {
|
||||
lv_obj_refresh_ext_size(obj);
|
||||
} else if(sign == LV_SIGNAL_GET_TYPE) {
|
||||
} else if(sign == LV_SIGNAL_GET_TYPE) {
|
||||
lv_obj_type_t * buf = param;
|
||||
buf->type[0] = "lv_obj";
|
||||
buf->type[0] = "lv_obj";
|
||||
}
|
||||
|
||||
return res;
|
||||
@ -1965,7 +1967,8 @@ static lv_res_t lv_obj_signal(lv_obj_t * obj, lv_signal_t sign, void * param)
|
||||
static void refresh_children_position(lv_obj_t * obj, lv_coord_t x_diff, lv_coord_t y_diff)
|
||||
{
|
||||
lv_obj_t * i;
|
||||
LV_LL_READ(obj->child_ll, i) {
|
||||
LV_LL_READ(obj->child_ll, i)
|
||||
{
|
||||
i->coords.x1 += x_diff;
|
||||
i->coords.y1 += y_diff;
|
||||
i->coords.x2 += x_diff;
|
||||
@ -1983,7 +1986,8 @@ static void refresh_children_position(lv_obj_t * obj, lv_coord_t x_diff, lv_coor
|
||||
static void report_style_mod_core(void * style_p, lv_obj_t * obj)
|
||||
{
|
||||
lv_obj_t * i;
|
||||
LV_LL_READ(obj->child_ll, i) {
|
||||
LV_LL_READ(obj->child_ll, i)
|
||||
{
|
||||
if(i->style_p == style_p || style_p == NULL) {
|
||||
refresh_children_style(i);
|
||||
lv_obj_refresh_style(i);
|
||||
@ -2003,8 +2007,8 @@ static void refresh_children_style(lv_obj_t * obj)
|
||||
lv_obj_t * child = lv_obj_get_child(obj, NULL);
|
||||
while(child != NULL) {
|
||||
if(child->style_p == NULL) {
|
||||
refresh_children_style(child); /*Check children too*/
|
||||
lv_obj_refresh_style(child); /*Notify the child about the style change*/
|
||||
refresh_children_style(child); /*Check children too*/
|
||||
lv_obj_refresh_style(child); /*Notify the child about the style change*/
|
||||
} else if(child->style_p->glass) {
|
||||
/*Children with 'glass' parent might be effected if their style == NULL*/
|
||||
refresh_children_style(child);
|
||||
@ -2026,8 +2030,8 @@ static void delete_children(lv_obj_t * obj)
|
||||
lv_obj_t * i_next;
|
||||
i = lv_ll_get_head(&(obj->child_ll));
|
||||
|
||||
/*Remove from the group; remove before transversing children so that
|
||||
* the object still has access to all children during the
|
||||
/*Remove from the group; remove before transversing children so that
|
||||
* the object still has access to all children during the
|
||||
* LV_SIGNAL_DEFOCUS call*/
|
||||
#if LV_USE_GROUP
|
||||
bool was_focused = false;
|
||||
@ -2077,7 +2081,6 @@ static void delete_children(lv_obj_t * obj)
|
||||
obj->signal_cb(obj, LV_SIGNAL_CLEANUP, NULL);
|
||||
|
||||
/*Delete the base objects*/
|
||||
if(obj->ext_attr != NULL) lv_mem_free(obj->ext_attr);
|
||||
if(obj->ext_attr != NULL) lv_mem_free(obj->ext_attr);
|
||||
lv_mem_free(obj); /*Free the object itself*/
|
||||
|
||||
}
|
||||
|
@ -42,11 +42,11 @@ extern "C" {
|
||||
#error "LittlevGL: LV_ANTIALIAS can be only 0 or 1"
|
||||
#endif
|
||||
|
||||
#define LV_ANIM_IN 0x00 /*Animation to show an object. 'OR' it with lv_anim_builtin_t*/
|
||||
#define LV_ANIM_OUT 0x80 /*Animation to hide an object. 'OR' it with lv_anim_builtin_t*/
|
||||
#define LV_ANIM_DIR_MASK 0x80 /*ANIM_IN/ANIM_OUT mask*/
|
||||
#define LV_ANIM_IN 0x00 /*Animation to show an object. 'OR' it with lv_anim_builtin_t*/
|
||||
#define LV_ANIM_OUT 0x80 /*Animation to hide an object. 'OR' it with lv_anim_builtin_t*/
|
||||
#define LV_ANIM_DIR_MASK 0x80 /*ANIM_IN/ANIM_OUT mask*/
|
||||
|
||||
#define LV_MAX_ANCESTOR_NUM 8
|
||||
#define LV_MAX_ANCESTOR_NUM 8
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
@ -54,35 +54,35 @@ extern "C" {
|
||||
|
||||
struct _lv_obj_t;
|
||||
|
||||
enum
|
||||
{
|
||||
enum {
|
||||
LV_DESIGN_DRAW_MAIN,
|
||||
LV_DESIGN_DRAW_POST,
|
||||
LV_DESIGN_COVER_CHK,
|
||||
};
|
||||
typedef uint8_t lv_design_mode_t;
|
||||
|
||||
typedef bool (* lv_design_cb_t) (struct _lv_obj_t * obj, const lv_area_t * mask_p, lv_design_mode_t mode);
|
||||
typedef bool (*lv_design_cb_t)(struct _lv_obj_t * obj, const lv_area_t * mask_p,
|
||||
lv_design_mode_t mode);
|
||||
|
||||
enum
|
||||
{
|
||||
LV_RES_INV = 0, /*Typically indicates that the object is deleted (become invalid) in the action function or an operation was failed*/
|
||||
LV_RES_OK, /*The object is valid (no deleted) after the action*/
|
||||
enum {
|
||||
LV_RES_INV = 0, /*Typically indicates that the object is deleted (become invalid) in the action
|
||||
function or an operation was failed*/
|
||||
LV_RES_OK, /*The object is valid (no deleted) after the action*/
|
||||
};
|
||||
typedef uint8_t lv_res_t;
|
||||
|
||||
|
||||
enum {
|
||||
LV_EVENT_PRESSED, /*The object has been pressed*/
|
||||
LV_EVENT_PRESSING, /*The object is being pressed (called continuously while pressing)*/
|
||||
LV_EVENT_PRESS_LOST, /*Still pressing but slid from the objects*/
|
||||
LV_EVENT_SHORT_CLICKED, /*Released before long press time. Not called if dragged.*/
|
||||
LV_EVENT_LONG_PRESSED, /*Pressing for `LV_INDEV_LONG_PRESS_TIME` time. Not called if dragged.*/
|
||||
LV_EVENT_LONG_PRESSED_REPEAT, /*Called after `LV_INDEV_LONG_PRESS_TIME` in every `LV_INDEV_LONG_PRESS_REP_TIME` ms. Not called if dragged.*/
|
||||
LV_EVENT_CLICKED, /*Called on release if not dragged (regardless to long press)*/
|
||||
LV_EVENT_RELEASED, /*Called in every cases when the object has been released*/
|
||||
LV_EVENT_LONG_HOVER_IN, /*TODO*/
|
||||
LV_EVENT_LONG_HOVER_OUT, /*TODO*/
|
||||
LV_EVENT_PRESSED, /*The object has been pressed*/
|
||||
LV_EVENT_PRESSING, /*The object is being pressed (called continuously while pressing)*/
|
||||
LV_EVENT_PRESS_LOST, /*Still pressing but slid from the objects*/
|
||||
LV_EVENT_SHORT_CLICKED, /*Released before long press time. Not called if dragged.*/
|
||||
LV_EVENT_LONG_PRESSED, /*Pressing for `LV_INDEV_LONG_PRESS_TIME` time. Not called if dragged.*/
|
||||
LV_EVENT_LONG_PRESSED_REPEAT, /*Called after `LV_INDEV_LONG_PRESS_TIME` in every
|
||||
`LV_INDEV_LONG_PRESS_REP_TIME` ms. Not called if dragged.*/
|
||||
LV_EVENT_CLICKED, /*Called on release if not dragged (regardless to long press)*/
|
||||
LV_EVENT_RELEASED, /*Called in every cases when the object has been released*/
|
||||
LV_EVENT_LONG_HOVER_IN, /*TODO*/
|
||||
LV_EVENT_LONG_HOVER_OUT, /*TODO*/
|
||||
LV_EVENT_DRAG_BEGIN,
|
||||
LV_EVENT_DRAG_END,
|
||||
LV_EVENT_DRAG_THROW_BEGIN,
|
||||
@ -92,15 +92,14 @@ enum {
|
||||
LV_EVENT_INSERT,
|
||||
LV_EVENT_SELECTED,
|
||||
LV_EVENT_REFRESH,
|
||||
LV_EVENT_APPLY, /*"Ok", "Apply" or similar specific button has clicked*/
|
||||
LV_EVENT_CANCEL, /*"Close", "Cancel" or similar specific button has clicked*/
|
||||
LV_EVENT_APPLY, /*"Ok", "Apply" or similar specific button has clicked*/
|
||||
LV_EVENT_CANCEL, /*"Close", "Cancel" or similar specific button has clicked*/
|
||||
};
|
||||
typedef uint8_t lv_event_t;
|
||||
|
||||
typedef void (*lv_event_cb_t)(struct _lv_obj_t * obj, lv_event_t event);
|
||||
|
||||
enum
|
||||
{
|
||||
enum {
|
||||
/*General signals*/
|
||||
LV_SIGNAL_CLEANUP,
|
||||
LV_SIGNAL_CHILD_CHG,
|
||||
@ -110,7 +109,7 @@ enum
|
||||
LV_SIGNAL_REFR_EXT_SIZE,
|
||||
LV_SIGNAL_GET_TYPE,
|
||||
|
||||
_LV_SIGNAL_FEEDBACK_SECTION_START,
|
||||
_LV_SIGNAL_FEEDBACK_SECTION_START,
|
||||
/*Input device related*/
|
||||
LV_SIGNAL_PRESSED,
|
||||
LV_SIGNAL_PRESSING,
|
||||
@ -130,10 +129,9 @@ enum
|
||||
};
|
||||
typedef uint8_t lv_signal_t;
|
||||
|
||||
typedef lv_res_t (* lv_signal_cb_t) (struct _lv_obj_t * obj, lv_signal_t sign, void * param);
|
||||
typedef lv_res_t (*lv_signal_cb_t)(struct _lv_obj_t * obj, lv_signal_t sign, void * param);
|
||||
|
||||
enum
|
||||
{
|
||||
enum {
|
||||
LV_ALIGN_CENTER = 0,
|
||||
LV_ALIGN_IN_TOP_LEFT,
|
||||
LV_ALIGN_IN_TOP_MID,
|
||||
@ -159,47 +157,50 @@ enum
|
||||
typedef uint8_t lv_align_t;
|
||||
|
||||
#if LV_OBJ_REALIGN
|
||||
typedef struct {
|
||||
typedef struct
|
||||
{
|
||||
const struct _lv_obj_t * base;
|
||||
lv_coord_t xofs;
|
||||
lv_coord_t yofs;
|
||||
lv_align_t align;
|
||||
uint8_t auto_realign :1;
|
||||
uint8_t origo_align :1; /*1: the oigo (center of the object) was aligned with `lv_obj_align_origo`*/
|
||||
}lv_reailgn_t;
|
||||
uint8_t auto_realign : 1;
|
||||
uint8_t origo_align : 1; /*1: the oigo (center of the object) was aligned with
|
||||
`lv_obj_align_origo`*/
|
||||
} lv_reailgn_t;
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct _lv_obj_t
|
||||
{
|
||||
struct _lv_obj_t * par; /*Pointer to the parent object*/
|
||||
lv_ll_t child_ll; /*Linked list to store the children objects*/
|
||||
struct _lv_obj_t * par; /*Pointer to the parent object*/
|
||||
lv_ll_t child_ll; /*Linked list to store the children objects*/
|
||||
|
||||
lv_area_t coords; /*Coordinates of the object (x1, y1, x2, y2)*/
|
||||
lv_area_t coords; /*Coordinates of the object (x1, y1, x2, y2)*/
|
||||
|
||||
lv_event_cb_t event_cb;
|
||||
lv_signal_cb_t signal_cb; /*Object type specific signal function*/
|
||||
lv_design_cb_t design_cb; /*Object type specific design function*/
|
||||
lv_signal_cb_t signal_cb; /*Object type specific signal function*/
|
||||
lv_design_cb_t design_cb; /*Object type specific design function*/
|
||||
|
||||
void * ext_attr; /*Object type specific extended data*/
|
||||
lv_style_t * style_p; /*Pointer to the object's style*/
|
||||
void * ext_attr; /*Object type specific extended data*/
|
||||
lv_style_t * style_p; /*Pointer to the object's style*/
|
||||
|
||||
#if LV_USE_GROUP != 0
|
||||
void * group_p; /*Pointer to the group of the object*/
|
||||
void * group_p; /*Pointer to the group of the object*/
|
||||
#endif
|
||||
/*Attributes and states*/
|
||||
uint8_t click :1; /*1: Can be pressed by an input device*/
|
||||
uint8_t drag :1; /*1: Enable the dragging*/
|
||||
uint8_t drag_throw :1; /*1: Enable throwing with drag*/
|
||||
uint8_t drag_parent :1; /*1: Parent will be dragged instead*/
|
||||
uint8_t hidden :1; /*1: Object is hidden*/
|
||||
uint8_t top :1; /*1: If the object or its children is clicked it goes to the foreground*/
|
||||
uint8_t opa_scale_en :1; /*1: opa_scale is set*/
|
||||
uint8_t parent_event :1; /*1: Send the object's events to the parent too. */
|
||||
uint8_t protect; /*Automatically happening actions can be prevented. 'OR'ed values from `lv_protect_t`*/
|
||||
lv_opa_t opa_scale; /*Scale down the opacity by this factor. Effects all children as well*/
|
||||
uint8_t click : 1; /*1: Can be pressed by an input device*/
|
||||
uint8_t drag : 1; /*1: Enable the dragging*/
|
||||
uint8_t drag_throw : 1; /*1: Enable throwing with drag*/
|
||||
uint8_t drag_parent : 1; /*1: Parent will be dragged instead*/
|
||||
uint8_t hidden : 1; /*1: Object is hidden*/
|
||||
uint8_t top : 1; /*1: If the object or its children is clicked it goes to the foreground*/
|
||||
uint8_t opa_scale_en : 1; /*1: opa_scale is set*/
|
||||
uint8_t parent_event : 1; /*1: Send the object's events to the parent too. */
|
||||
uint8_t protect; /*Automatically happening actions can be prevented. 'OR'ed values from
|
||||
`lv_protect_t`*/
|
||||
lv_opa_t opa_scale; /*Scale down the opacity by this factor. Effects all children as well*/
|
||||
|
||||
lv_coord_t ext_size; /*EXTtend the size of the object in every direction. E.g. for shadow drawing*/
|
||||
lv_coord_t
|
||||
ext_size; /*EXTtend the size of the object in every direction. E.g. for shadow drawing*/
|
||||
#if LV_OBJ_REALIGN
|
||||
lv_reailgn_t realign;
|
||||
#endif
|
||||
@ -217,33 +218,34 @@ typedef struct _lv_obj_t
|
||||
} lv_obj_t;
|
||||
|
||||
/*Protect some attributes (max. 8 bit)*/
|
||||
enum
|
||||
{
|
||||
enum {
|
||||
LV_PROTECT_NONE = 0x00,
|
||||
LV_PROTECT_CHILD_CHG = 0x01, /*Disable the child change signal. Used by the library*/
|
||||
LV_PROTECT_PARENT = 0x02, /*Prevent automatic parent change (e.g. in lv_page)*/
|
||||
LV_PROTECT_POS = 0x04, /*Prevent automatic positioning (e.g. in lv_cont layout)*/
|
||||
LV_PROTECT_FOLLOW = 0x08, /*Prevent the object be followed in automatic ordering (e.g. in lv_cont PRETTY layout)*/
|
||||
LV_PROTECT_PRESS_LOST= 0x10, /*If the `indev` was pressing this object but swiped out while pressing do not search other object.*/
|
||||
LV_PROTECT_CLICK_FOCUS= 0x20,/*Prevent focusing the object by clicking on it*/
|
||||
LV_PROTECT_CHILD_CHG = 0x01, /*Disable the child change signal. Used by the library*/
|
||||
LV_PROTECT_PARENT = 0x02, /*Prevent automatic parent change (e.g. in lv_page)*/
|
||||
LV_PROTECT_POS = 0x04, /*Prevent automatic positioning (e.g. in lv_cont layout)*/
|
||||
LV_PROTECT_FOLLOW = 0x08, /*Prevent the object be followed in automatic ordering (e.g. in
|
||||
lv_cont PRETTY layout)*/
|
||||
LV_PROTECT_PRESS_LOST = 0x10, /*If the `indev` was pressing this object but swiped out while
|
||||
pressing do not search other object.*/
|
||||
LV_PROTECT_CLICK_FOCUS = 0x20, /*Prevent focusing the object by clicking on it*/
|
||||
};
|
||||
typedef uint8_t lv_protect_t;
|
||||
|
||||
|
||||
/*Used by `lv_obj_get_type()`. The object's and its ancestor types are stored here*/
|
||||
typedef struct {
|
||||
const char * type[LV_MAX_ANCESTOR_NUM]; /*[0]: the actual type, [1]: ancestor, [2] #1's ancestor ... [x]: "lv_obj" */
|
||||
typedef struct
|
||||
{
|
||||
const char * type[LV_MAX_ANCESTOR_NUM]; /*[0]: the actual type, [1]: ancestor, [2] #1's ancestor
|
||||
... [x]: "lv_obj" */
|
||||
} lv_obj_type_t;
|
||||
|
||||
enum
|
||||
{
|
||||
enum {
|
||||
LV_ANIM_NONE = 0,
|
||||
LV_ANIM_FLOAT_TOP, /*Float from/to the top*/
|
||||
LV_ANIM_FLOAT_LEFT, /*Float from/to the left*/
|
||||
LV_ANIM_FLOAT_BOTTOM, /*Float from/to the bottom*/
|
||||
LV_ANIM_FLOAT_RIGHT, /*Float from/to the right*/
|
||||
LV_ANIM_GROW_H, /*Grow/shrink horizontally*/
|
||||
LV_ANIM_GROW_V, /*Grow/shrink vertically*/
|
||||
LV_ANIM_FLOAT_TOP, /*Float from/to the top*/
|
||||
LV_ANIM_FLOAT_LEFT, /*Float from/to the left*/
|
||||
LV_ANIM_FLOAT_BOTTOM, /*Float from/to the bottom*/
|
||||
LV_ANIM_FLOAT_RIGHT, /*Float from/to the right*/
|
||||
LV_ANIM_GROW_H, /*Grow/shrink horizontally*/
|
||||
LV_ANIM_GROW_V, /*Grow/shrink vertically*/
|
||||
};
|
||||
typedef uint8_t lv_anim_builtin_t;
|
||||
|
||||
@ -267,7 +269,7 @@ void lv_init(void);
|
||||
* @param copy pointer to a base object, if not NULL then the new object will be copied from it
|
||||
* @return pointer to the new object
|
||||
*/
|
||||
lv_obj_t * lv_obj_create(lv_obj_t * parent,const lv_obj_t * copy);
|
||||
lv_obj_t * lv_obj_create(lv_obj_t * parent, const lv_obj_t * copy);
|
||||
|
||||
/**
|
||||
* Delete 'obj' and all of its children
|
||||
@ -280,7 +282,7 @@ lv_res_t lv_obj_del(lv_obj_t * obj);
|
||||
* Delete all children of an object
|
||||
* @param obj pointer to an object
|
||||
*/
|
||||
void lv_obj_clean(lv_obj_t *obj);
|
||||
void lv_obj_clean(lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Mark the object as invalid therefore its current position will be redrawn by 'lv_refr_task'
|
||||
@ -359,7 +361,8 @@ void lv_obj_set_height(lv_obj_t * obj, lv_coord_t h);
|
||||
* @param x_mod x coordinate shift after alignment
|
||||
* @param y_mod y coordinate shift after alignment
|
||||
*/
|
||||
void lv_obj_align(lv_obj_t * obj,const lv_obj_t * base, lv_align_t align, lv_coord_t x_mod, lv_coord_t y_mod);
|
||||
void lv_obj_align(lv_obj_t * obj, const lv_obj_t * base, lv_align_t align, lv_coord_t x_mod,
|
||||
lv_coord_t y_mod);
|
||||
|
||||
/**
|
||||
* Align an object to an other object.
|
||||
@ -369,7 +372,8 @@ void lv_obj_align(lv_obj_t * obj,const lv_obj_t * base, lv_align_t align, lv_coo
|
||||
* @param x_mod x coordinate shift after alignment
|
||||
* @param y_mod y coordinate shift after alignment
|
||||
*/
|
||||
void lv_obj_align_origo(lv_obj_t * obj, const lv_obj_t * base, lv_align_t align, lv_coord_t x_mod, lv_coord_t y_mod);
|
||||
void lv_obj_align_origo(lv_obj_t * obj, const lv_obj_t * base, lv_align_t align, lv_coord_t x_mod,
|
||||
lv_coord_t y_mod);
|
||||
|
||||
/**
|
||||
* Realign the object based on the last `lv_obj_align` parameters.
|
||||
@ -378,7 +382,8 @@ void lv_obj_align_origo(lv_obj_t * obj, const lv_obj_t * base, lv_align_t align,
|
||||
void lv_obj_realign(lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Enable the automatic realign of the object when its size has changed based on the last `lv_obj_align` parameters.
|
||||
* Enable the automatic realign of the object when its size has changed based on the last
|
||||
* `lv_obj_align` parameters.
|
||||
* @param obj pointer to an object
|
||||
* @param en true: enable auto realign; false: disable auto realign
|
||||
*/
|
||||
@ -563,7 +568,8 @@ void lv_obj_refresh_ext_size(lv_obj_t * obj);
|
||||
* @param delay delay before the animation in milliseconds
|
||||
* @param cb a function to call when the animation is ready
|
||||
*/
|
||||
void lv_obj_animate(lv_obj_t * obj, lv_anim_builtin_t type, uint16_t time, uint16_t delay, void (*cb) (lv_obj_t *));
|
||||
void lv_obj_animate(lv_obj_t * obj, lv_anim_builtin_t type, uint16_t time, uint16_t delay,
|
||||
void (*cb)(lv_obj_t *));
|
||||
#endif
|
||||
|
||||
/*=======================
|
||||
@ -814,7 +820,6 @@ void * lv_obj_get_ext_attr(const lv_obj_t * obj);
|
||||
*/
|
||||
void lv_obj_get_type(lv_obj_t * obj, lv_obj_type_t * buf);
|
||||
|
||||
|
||||
#if LV_USE_USER_DATA_SINGLE
|
||||
/**
|
||||
* Get a pointer to the object's user data
|
||||
@ -832,7 +837,6 @@ lv_obj_user_data_t * lv_obj_get_user_data(lv_obj_t * obj);
|
||||
*/
|
||||
void * lv_obj_get_group(const lv_obj_t * obj);
|
||||
|
||||
|
||||
/**
|
||||
* Tell whether the object is the focused object of a group or not.
|
||||
* @param obj pointer to an object
|
||||
@ -842,12 +846,10 @@ bool lv_obj_is_focused(const lv_obj_t * obj);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
@ -16,7 +16,7 @@
|
||||
#include "../lv_misc/lv_gc.h"
|
||||
|
||||
#if defined(LV_GC_INCLUDE)
|
||||
# include LV_GC_INCLUDE
|
||||
#include LV_GC_INCLUDE
|
||||
#endif /* LV_ENABLE_GC */
|
||||
|
||||
/*********************
|
||||
@ -43,7 +43,7 @@ static void lv_refr_vdb_flush(void);
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
static uint32_t px_num;
|
||||
static lv_disp_t * disp_refr; /*Display being refreshed*/
|
||||
static lv_disp_t * disp_refr; /*Display being refreshed*/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
@ -63,20 +63,20 @@ 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 the GUI is updated in the process (e.g. progress bar)
|
||||
* this function can be called when the screen should be updated.
|
||||
* 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 the GUI is updated in the process
|
||||
* (e.g. progress bar) this function can be called when the screen should be updated.
|
||||
*/
|
||||
void lv_refr_now(void)
|
||||
{
|
||||
lv_disp_refr_task(NULL);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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)
|
||||
* @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)
|
||||
{
|
||||
@ -113,11 +113,11 @@ void lv_inv_area(lv_disp_t * disp, const lv_area_t * area_p)
|
||||
/*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*/
|
||||
} 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 ++;
|
||||
disp->inv_p++;
|
||||
}
|
||||
}
|
||||
|
||||
@ -148,28 +148,33 @@ void lv_disp_refr_task(void * param)
|
||||
|
||||
/*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*/
|
||||
/*In true double buffered mode copy the refreshed areas to the new VDB to keep it up to
|
||||
* date*/
|
||||
if(lv_disp_is_true_double_buf(disp_refr)) {
|
||||
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);
|
||||
/* 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)
|
||||
;
|
||||
|
||||
uint8_t * buf_act = (uint8_t *) vdb->buf_act;
|
||||
uint8_t * buf_ina = (uint8_t *) vdb->buf_act == vdb->buf1 ? vdb->buf2 : vdb->buf1;
|
||||
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(disp_refr->inv_area_joined[a] == 0) {
|
||||
lv_coord_t y;
|
||||
uint32_t start_offs = (hres * disp_refr->inv_areas[a].y1 + disp_refr->inv_areas[a].x1) * sizeof(lv_color_t);
|
||||
uint32_t line_length = lv_area_get_width(&disp_refr->inv_areas[a]) * sizeof(lv_color_t);
|
||||
uint32_t start_offs =
|
||||
(hres * disp_refr->inv_areas[a].y1 + disp_refr->inv_areas[a].x1) *
|
||||
sizeof(lv_color_t);
|
||||
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++) {
|
||||
memcpy(buf_act + start_offs, buf_ina + start_offs, line_length);
|
||||
@ -177,7 +182,7 @@ void lv_disp_refr_task(void * param)
|
||||
}
|
||||
}
|
||||
}
|
||||
} /*End of true double buffer handling*/
|
||||
} /*End of true double buffer handling*/
|
||||
|
||||
/*Clean up*/
|
||||
memset(disp_refr->inv_areas, 0, sizeof(disp_refr->inv_areas));
|
||||
@ -216,8 +221,8 @@ static void lv_refr_join_area(void)
|
||||
}
|
||||
|
||||
/*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) {
|
||||
if(lv_area_is_on(&disp_refr->inv_areas[join_in], &disp_refr->inv_areas[join_from]) ==
|
||||
false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -226,7 +231,8 @@ static void lv_refr_join_area(void)
|
||||
|
||||
/*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_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'*/
|
||||
@ -261,24 +267,27 @@ static void lv_refr_areas(void)
|
||||
*/
|
||||
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*/
|
||||
/*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;
|
||||
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;
|
||||
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) ? y2 = lv_disp_get_ver_res(disp_refr) - 1 : area_p->y2;
|
||||
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)
|
||||
? y2 = lv_disp_get_ver_res(disp_refr) - 1
|
||||
: area_p->y2;
|
||||
|
||||
int32_t max_row = (uint32_t) vdb->size / w;
|
||||
int32_t max_row = (uint32_t)vdb->size / w;
|
||||
|
||||
if(max_row > h) max_row = h;
|
||||
|
||||
@ -298,11 +307,12 @@ static void lv_refr_area(const lv_area_t * area_p)
|
||||
if(lv_area_get_height(&tmp) <= max_row) break;
|
||||
|
||||
/*Decrement the height of the area until it fits into `max_row` after rounding*/
|
||||
y_tmp --;
|
||||
y_tmp--;
|
||||
} while(y_tmp != 0);
|
||||
|
||||
if(y_tmp == 0) {
|
||||
LV_LOG_WARN("Can't set VDB height using the round function. (Wrong round_cb or to small VDB)");
|
||||
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;
|
||||
@ -312,7 +322,7 @@ static void lv_refr_area(const lv_area_t * area_p)
|
||||
/*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) {
|
||||
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;
|
||||
@ -346,9 +356,11 @@ 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*/
|
||||
/*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);
|
||||
while(vdb->flushing)
|
||||
;
|
||||
}
|
||||
|
||||
lv_obj_t * top_p;
|
||||
@ -388,7 +400,8 @@ static lv_obj_t * lv_refr_get_top_obj(const lv_area_t * area_p, lv_obj_t * obj)
|
||||
|
||||
/*If this object is fully cover the draw area check the children too */
|
||||
if(lv_area_is_in(area_p, &obj->coords) && obj->hidden == 0) {
|
||||
LV_LL_READ(obj->child_ll, 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*/
|
||||
@ -401,8 +414,8 @@ static lv_obj_t * lv_refr_get_top_obj(const lv_area_t * area_p, lv_obj_t * obj)
|
||||
if(found_p == NULL) {
|
||||
lv_style_t * style = lv_obj_get_style(obj);
|
||||
if(style->body.opa == LV_OPA_COVER &&
|
||||
obj->design_cb(obj, area_p, LV_DESIGN_COVER_CHK) != false &&
|
||||
lv_obj_get_opa_scale(obj) == LV_OPA_COVER) {
|
||||
obj->design_cb(obj, area_p, LV_DESIGN_COVER_CHK) != false &&
|
||||
lv_obj_get_opa_scale(obj) == LV_OPA_COVER) {
|
||||
found_p = obj;
|
||||
}
|
||||
}
|
||||
@ -469,7 +482,7 @@ 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 */
|
||||
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;
|
||||
@ -488,8 +501,7 @@ static void lv_refr_obj(lv_obj_t * obj, const lv_area_t * mask_ori_p)
|
||||
|
||||
/* Redraw the object */
|
||||
obj->design_cb(obj, &obj_ext_mask, LV_DESIGN_DRAW_MAIN);
|
||||
//usleep(5 * 1000); /*DEBUG: Wait after every object draw to see the order of drawing*/
|
||||
|
||||
// usleep(5 * 1000); /*DEBUG: Wait after every object draw to see the order of drawing*/
|
||||
|
||||
/*Create a new 'obj_mask' without 'ext_size' because the children can't be visible there*/
|
||||
lv_obj_get_coords(obj, &obj_area);
|
||||
@ -498,7 +510,8 @@ static void lv_refr_obj(lv_obj_t * obj, const lv_area_t * mask_ori_p)
|
||||
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_LL_READ_BACK(obj->child_ll, child_p)
|
||||
{
|
||||
lv_obj_get_coords(child_p, &child_area);
|
||||
ext_size = child_p->ext_size;
|
||||
child_area.x1 -= ext_size;
|
||||
@ -519,7 +532,6 @@ static void lv_refr_obj(lv_obj_t * obj, const lv_area_t * mask_ori_p)
|
||||
|
||||
/* If all the children are redrawn make 'post draw' design */
|
||||
obj->design_cb(obj, &obj_ext_mask, LV_DESIGN_DRAW_POST);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -530,9 +542,11 @@ static void lv_refr_vdb_flush(void)
|
||||
{
|
||||
lv_disp_buf_t * vdb = lv_disp_get_buf(disp_refr);
|
||||
|
||||
/*In double buffered mode wait until the other buffer is flushed before flushing the current one*/
|
||||
/*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);
|
||||
while(vdb->flushing)
|
||||
;
|
||||
}
|
||||
|
||||
vdb->flushing = 1;
|
||||
@ -541,14 +555,15 @@ static void lv_refr_vdb_flush(void)
|
||||
lv_disp_t * disp = lv_refr_get_disp_refreshing();
|
||||
if(disp->driver.flush_cb) disp->driver.flush_cb(&disp->driver, &vdb->area, vdb->buf_act);
|
||||
|
||||
|
||||
if(vdb->buf1 && vdb->buf2) {
|
||||
if(vdb->buf_act == vdb->buf1) vdb->buf_act = vdb->buf2;
|
||||
else vdb->buf_act = vdb->buf1;
|
||||
if(vdb->buf_act == vdb->buf1)
|
||||
vdb->buf_act = vdb->buf2;
|
||||
else
|
||||
vdb->buf_act = vdb->buf1;
|
||||
|
||||
/*If the screen is transparent initialize it when the new VDB is selected*/
|
||||
# if LV_COLOR_SCREEN_TRANSP
|
||||
/*If the screen is transparent initialize it when the new VDB is selected*/
|
||||
#if LV_COLOR_SCREEN_TRANSP
|
||||
memset(vdb[vdb_active].buf, 0x00, LV_VDB_SIZE_IN_BYTES);
|
||||
# endif /*LV_COLOR_SCREEN_TRANSP*/
|
||||
#endif /*LV_COLOR_SCREEN_TRANSP*/
|
||||
}
|
||||
}
|
||||
|
@ -47,16 +47,17 @@ 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 the GUI is updated in the process (e.g. progress bar)
|
||||
* this function can be called when the screen should be updated.
|
||||
* 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 the GUI is updated in the process
|
||||
* (e.g. progress bar) this function can be called when the screen should be updated.
|
||||
*/
|
||||
void lv_refr_now(void);
|
||||
|
||||
/**
|
||||
* 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)
|
||||
* @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);
|
||||
|
||||
@ -76,7 +77,6 @@ void lv_disp_refr_task(void * param);
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
@ -12,19 +12,25 @@
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define STYLE_MIX_MAX 256
|
||||
#define STYLE_MIX_SHIFT 8 /*log2(STYLE_MIX_MAX)*/
|
||||
|
||||
#define VAL_PROP(v1, v2, r) v1 + (((v2-v1) * r) >> STYLE_MIX_SHIFT)
|
||||
#define STYLE_ATTR_MIX(attr, r) if(start->attr != end->attr) {res->attr = VAL_PROP(start->attr, end->attr, r);} else {res->attr = start->attr;}
|
||||
#define STYLE_MIX_MAX 256
|
||||
#define STYLE_MIX_SHIFT 8 /*log2(STYLE_MIX_MAX)*/
|
||||
|
||||
#define VAL_PROP(v1, v2, r) v1 + (((v2 - v1) * r) >> STYLE_MIX_SHIFT)
|
||||
#define STYLE_ATTR_MIX(attr, r) \
|
||||
if(start->attr != end->attr) { \
|
||||
res->attr = VAL_PROP(start->attr, end->attr, r); \
|
||||
} else { \
|
||||
res->attr = start->attr; \
|
||||
}
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
#if LV_USE_ANIMATION
|
||||
typedef struct {
|
||||
lv_style_t style_start; /*Save not only pointers because can be same as 'style_anim' then it will be modified too*/
|
||||
typedef struct
|
||||
{
|
||||
lv_style_t style_start; /*Save not only pointers because can be same as 'style_anim' then it
|
||||
will be modified too*/
|
||||
lv_style_t style_end;
|
||||
lv_style_t * style_anim;
|
||||
void (*end_cb)(void *);
|
||||
@ -73,89 +79,89 @@ void lv_style_init(void)
|
||||
* HUE = 210*/
|
||||
|
||||
/*Screen style*/
|
||||
lv_style_scr.glass = 0;
|
||||
lv_style_scr.body.opa = LV_OPA_COVER;
|
||||
lv_style_scr.body.main_color = LV_COLOR_WHITE;
|
||||
lv_style_scr.body.grad_color = LV_COLOR_WHITE;
|
||||
lv_style_scr.body.radius = 0;
|
||||
lv_style_scr.body.padding.left = 0;
|
||||
lv_style_scr.body.padding.right = 0;
|
||||
lv_style_scr.body.padding.top = 0;
|
||||
lv_style_scr.glass = 0;
|
||||
lv_style_scr.body.opa = LV_OPA_COVER;
|
||||
lv_style_scr.body.main_color = LV_COLOR_WHITE;
|
||||
lv_style_scr.body.grad_color = LV_COLOR_WHITE;
|
||||
lv_style_scr.body.radius = 0;
|
||||
lv_style_scr.body.padding.left = 0;
|
||||
lv_style_scr.body.padding.right = 0;
|
||||
lv_style_scr.body.padding.top = 0;
|
||||
lv_style_scr.body.padding.bottom = 0;
|
||||
lv_style_scr.body.padding.inner = LV_DPI / 12;
|
||||
lv_style_scr.body.padding.inner = LV_DPI / 12;
|
||||
|
||||
lv_style_scr.body.border.color = LV_COLOR_BLACK;
|
||||
lv_style_scr.body.border.opa = LV_OPA_COVER;
|
||||
lv_style_scr.body.border.opa = LV_OPA_COVER;
|
||||
lv_style_scr.body.border.width = 0;
|
||||
lv_style_scr.body.border.part = LV_BORDER_FULL;
|
||||
lv_style_scr.body.border.part = LV_BORDER_FULL;
|
||||
|
||||
lv_style_scr.body.shadow.color = LV_COLOR_GRAY;
|
||||
lv_style_scr.body.shadow.type = LV_SHADOW_FULL;
|
||||
lv_style_scr.body.shadow.type = LV_SHADOW_FULL;
|
||||
lv_style_scr.body.shadow.width = 0;
|
||||
|
||||
lv_style_scr.text.opa = LV_OPA_COVER;
|
||||
lv_style_scr.text.color = lv_color_make(0x30, 0x30, 0x30);
|
||||
lv_style_scr.text.sel_color = lv_color_make(0x55, 0x96, 0xd8);
|
||||
lv_style_scr.text.font = LV_FONT_DEFAULT;
|
||||
lv_style_scr.text.opa = LV_OPA_COVER;
|
||||
lv_style_scr.text.color = lv_color_make(0x30, 0x30, 0x30);
|
||||
lv_style_scr.text.sel_color = lv_color_make(0x55, 0x96, 0xd8);
|
||||
lv_style_scr.text.font = LV_FONT_DEFAULT;
|
||||
lv_style_scr.text.letter_space = 2;
|
||||
lv_style_scr.text.line_space = 2;
|
||||
lv_style_scr.text.line_space = 2;
|
||||
|
||||
lv_style_scr.image.opa = LV_OPA_COVER;
|
||||
lv_style_scr.image.color = lv_color_make(0x20, 0x20, 0x20);
|
||||
lv_style_scr.image.opa = LV_OPA_COVER;
|
||||
lv_style_scr.image.color = lv_color_make(0x20, 0x20, 0x20);
|
||||
lv_style_scr.image.intense = LV_OPA_TRANSP;
|
||||
|
||||
lv_style_scr.line.opa = LV_OPA_COVER;
|
||||
lv_style_scr.line.color = lv_color_make(0x20, 0x20, 0x20);
|
||||
lv_style_scr.line.width = 2;
|
||||
lv_style_scr.line.opa = LV_OPA_COVER;
|
||||
lv_style_scr.line.color = lv_color_make(0x20, 0x20, 0x20);
|
||||
lv_style_scr.line.width = 2;
|
||||
lv_style_scr.line.rounded = 0;
|
||||
|
||||
/*Plain style (by default near the same as the screen style)*/
|
||||
memcpy(&lv_style_plain, &lv_style_scr, sizeof(lv_style_t));
|
||||
lv_style_plain.body.padding.left = LV_DPI / 12;
|
||||
lv_style_plain.body.padding.right = LV_DPI / 12;
|
||||
lv_style_plain.body.padding.top = LV_DPI / 12;
|
||||
lv_style_plain.body.padding.left = LV_DPI / 12;
|
||||
lv_style_plain.body.padding.right = LV_DPI / 12;
|
||||
lv_style_plain.body.padding.top = LV_DPI / 12;
|
||||
lv_style_plain.body.padding.bottom = LV_DPI / 12;
|
||||
|
||||
/*Plain color style*/
|
||||
memcpy(&lv_style_plain_color, &lv_style_plain, sizeof(lv_style_t));
|
||||
lv_style_plain_color.text.color = lv_color_make(0xf0, 0xf0, 0xf0);
|
||||
lv_style_plain_color.image.color = lv_color_make(0xf0, 0xf0, 0xf0);
|
||||
lv_style_plain_color.line.color = lv_color_make(0xf0, 0xf0, 0xf0);
|
||||
lv_style_plain_color.text.color = lv_color_make(0xf0, 0xf0, 0xf0);
|
||||
lv_style_plain_color.image.color = lv_color_make(0xf0, 0xf0, 0xf0);
|
||||
lv_style_plain_color.line.color = lv_color_make(0xf0, 0xf0, 0xf0);
|
||||
lv_style_plain_color.body.main_color = lv_color_make(0x55, 0x96, 0xd8);
|
||||
lv_style_plain_color.body.grad_color = lv_style_plain_color.body.main_color;
|
||||
|
||||
/*Pretty style */
|
||||
memcpy(&lv_style_pretty, &lv_style_plain, sizeof(lv_style_t));
|
||||
lv_style_pretty.text.color = lv_color_make(0x20, 0x20, 0x20);
|
||||
lv_style_pretty.image.color = lv_color_make(0x20, 0x20, 0x20);
|
||||
lv_style_pretty.line.color = lv_color_make(0x20, 0x20, 0x20);
|
||||
lv_style_pretty.body.main_color = LV_COLOR_WHITE;
|
||||
lv_style_pretty.body.grad_color = LV_COLOR_SILVER;
|
||||
lv_style_pretty.body.radius = LV_DPI / 15;
|
||||
lv_style_pretty.text.color = lv_color_make(0x20, 0x20, 0x20);
|
||||
lv_style_pretty.image.color = lv_color_make(0x20, 0x20, 0x20);
|
||||
lv_style_pretty.line.color = lv_color_make(0x20, 0x20, 0x20);
|
||||
lv_style_pretty.body.main_color = LV_COLOR_WHITE;
|
||||
lv_style_pretty.body.grad_color = LV_COLOR_SILVER;
|
||||
lv_style_pretty.body.radius = LV_DPI / 15;
|
||||
lv_style_pretty.body.border.color = lv_color_make(0x40, 0x40, 0x40);
|
||||
lv_style_pretty.body.border.width = LV_DPI / 50 >= 1 ? LV_DPI / 50 : 1;
|
||||
lv_style_pretty.body.border.opa = LV_OPA_30;
|
||||
lv_style_pretty.body.border.width = LV_DPI / 50 >= 1 ? LV_DPI / 50 : 1;
|
||||
lv_style_pretty.body.border.opa = LV_OPA_30;
|
||||
|
||||
/*Pretty color style*/
|
||||
memcpy(&lv_style_pretty_color, &lv_style_pretty, sizeof(lv_style_t));
|
||||
lv_style_pretty_color.text.color = lv_color_make(0xe0, 0xe0, 0xe0);
|
||||
lv_style_pretty_color.image.color = lv_color_make(0xe0, 0xe0, 0xe0);
|
||||
lv_style_pretty_color.line.color = lv_color_make(0xc0, 0xc0, 0xc0);
|
||||
lv_style_pretty_color.body.main_color = lv_color_make(0x6b, 0x9a, 0xc7);
|
||||
lv_style_pretty_color.body.grad_color = lv_color_make(0x2b, 0x59, 0x8b);
|
||||
lv_style_pretty_color.text.color = lv_color_make(0xe0, 0xe0, 0xe0);
|
||||
lv_style_pretty_color.image.color = lv_color_make(0xe0, 0xe0, 0xe0);
|
||||
lv_style_pretty_color.line.color = lv_color_make(0xc0, 0xc0, 0xc0);
|
||||
lv_style_pretty_color.body.main_color = lv_color_make(0x6b, 0x9a, 0xc7);
|
||||
lv_style_pretty_color.body.grad_color = lv_color_make(0x2b, 0x59, 0x8b);
|
||||
lv_style_pretty_color.body.border.color = lv_color_make(0x15, 0x2c, 0x42);
|
||||
|
||||
/*Transparent style*/
|
||||
memcpy(&lv_style_transp, &lv_style_plain, sizeof(lv_style_t));
|
||||
lv_style_transp.glass = 1;
|
||||
lv_style_transp.glass = 1;
|
||||
lv_style_transp.body.border.width = 0;
|
||||
lv_style_transp.body.opa = LV_OPA_TRANSP;
|
||||
lv_style_transp.body.opa = LV_OPA_TRANSP;
|
||||
|
||||
/*Transparent fitting size*/
|
||||
memcpy(&lv_style_transp_fit, &lv_style_transp, sizeof(lv_style_t));
|
||||
lv_style_transp_fit.body.padding.left = 0;
|
||||
lv_style_transp_fit.body.padding.right = 0;
|
||||
lv_style_transp_fit.body.padding.top = 0;
|
||||
lv_style_transp_fit.body.padding.left = 0;
|
||||
lv_style_transp_fit.body.padding.right = 0;
|
||||
lv_style_transp_fit.body.padding.top = 0;
|
||||
lv_style_transp_fit.body.padding.bottom = 0;
|
||||
|
||||
/*Transparent tight style*/
|
||||
@ -164,58 +170,57 @@ void lv_style_init(void)
|
||||
|
||||
/*Button released style*/
|
||||
memcpy(&lv_style_btn_rel, &lv_style_plain, sizeof(lv_style_t));
|
||||
lv_style_btn_rel.body.main_color = lv_color_make(0x76, 0xa2, 0xd0);
|
||||
lv_style_btn_rel.body.grad_color = lv_color_make(0x19, 0x3a, 0x5d);
|
||||
lv_style_btn_rel.body.radius = LV_DPI / 15;
|
||||
lv_style_btn_rel.body.padding.left= LV_DPI / 4;
|
||||
lv_style_btn_rel.body.padding.right = LV_DPI / 4;
|
||||
lv_style_btn_rel.body.padding.top = LV_DPI / 6;
|
||||
lv_style_btn_rel.body.main_color = lv_color_make(0x76, 0xa2, 0xd0);
|
||||
lv_style_btn_rel.body.grad_color = lv_color_make(0x19, 0x3a, 0x5d);
|
||||
lv_style_btn_rel.body.radius = LV_DPI / 15;
|
||||
lv_style_btn_rel.body.padding.left = LV_DPI / 4;
|
||||
lv_style_btn_rel.body.padding.right = LV_DPI / 4;
|
||||
lv_style_btn_rel.body.padding.top = LV_DPI / 6;
|
||||
lv_style_btn_rel.body.padding.bottom = LV_DPI / 6;
|
||||
lv_style_btn_rel.body.padding.inner = LV_DPI / 10;
|
||||
lv_style_btn_rel.body.border.color = lv_color_make(0x0b, 0x19, 0x28);
|
||||
lv_style_btn_rel.body.border.width = LV_DPI / 50 >= 1 ? LV_DPI / 50 : 1;
|
||||
lv_style_btn_rel.body.border.opa = LV_OPA_70;
|
||||
lv_style_btn_rel.body.shadow.color = LV_COLOR_GRAY;
|
||||
lv_style_btn_rel.body.shadow.width = 0;
|
||||
lv_style_btn_rel.text.color = lv_color_make(0xff, 0xff, 0xff);
|
||||
lv_style_btn_rel.image.color = lv_color_make(0xff, 0xff, 0xff);
|
||||
lv_style_btn_rel.body.padding.inner = LV_DPI / 10;
|
||||
lv_style_btn_rel.body.border.color = lv_color_make(0x0b, 0x19, 0x28);
|
||||
lv_style_btn_rel.body.border.width = LV_DPI / 50 >= 1 ? LV_DPI / 50 : 1;
|
||||
lv_style_btn_rel.body.border.opa = LV_OPA_70;
|
||||
lv_style_btn_rel.body.shadow.color = LV_COLOR_GRAY;
|
||||
lv_style_btn_rel.body.shadow.width = 0;
|
||||
lv_style_btn_rel.text.color = lv_color_make(0xff, 0xff, 0xff);
|
||||
lv_style_btn_rel.image.color = lv_color_make(0xff, 0xff, 0xff);
|
||||
|
||||
/*Button pressed style*/
|
||||
memcpy(&lv_style_btn_pr, &lv_style_btn_rel, sizeof(lv_style_t));
|
||||
lv_style_btn_pr.body.main_color = lv_color_make(0x33, 0x62, 0x94);
|
||||
lv_style_btn_pr.body.grad_color = lv_color_make(0x10, 0x26, 0x3c);
|
||||
lv_style_btn_pr.text.color = lv_color_make(0xa4, 0xb5, 0xc6);
|
||||
lv_style_btn_pr.image.color = lv_color_make(0xa4, 0xb5, 0xc6);
|
||||
lv_style_btn_pr.line.color = lv_color_make(0xa4, 0xb5, 0xc6);
|
||||
lv_style_btn_pr.text.color = lv_color_make(0xa4, 0xb5, 0xc6);
|
||||
lv_style_btn_pr.image.color = lv_color_make(0xa4, 0xb5, 0xc6);
|
||||
lv_style_btn_pr.line.color = lv_color_make(0xa4, 0xb5, 0xc6);
|
||||
|
||||
/*Button toggle released style*/
|
||||
memcpy(&lv_style_btn_tgl_rel, &lv_style_btn_rel, sizeof(lv_style_t));
|
||||
lv_style_btn_tgl_rel.body.main_color = lv_color_make(0x0a, 0x11, 0x22);
|
||||
lv_style_btn_tgl_rel.body.grad_color = lv_color_make(0x37, 0x62, 0x90);
|
||||
lv_style_btn_tgl_rel.body.main_color = lv_color_make(0x0a, 0x11, 0x22);
|
||||
lv_style_btn_tgl_rel.body.grad_color = lv_color_make(0x37, 0x62, 0x90);
|
||||
lv_style_btn_tgl_rel.body.border.color = lv_color_make(0x01, 0x07, 0x0d);
|
||||
lv_style_btn_tgl_rel.text.color = lv_color_make(0xc8, 0xdd, 0xf4);
|
||||
lv_style_btn_tgl_rel.image.color = lv_color_make(0xc8, 0xdd, 0xf4);
|
||||
lv_style_btn_tgl_rel.line.color = lv_color_make(0xc8, 0xdd, 0xf4);
|
||||
lv_style_btn_tgl_rel.text.color = lv_color_make(0xc8, 0xdd, 0xf4);
|
||||
lv_style_btn_tgl_rel.image.color = lv_color_make(0xc8, 0xdd, 0xf4);
|
||||
lv_style_btn_tgl_rel.line.color = lv_color_make(0xc8, 0xdd, 0xf4);
|
||||
|
||||
/*Button toggle pressed style*/
|
||||
memcpy(&lv_style_btn_tgl_pr, &lv_style_btn_tgl_rel, sizeof(lv_style_t));
|
||||
lv_style_btn_tgl_pr.body.main_color = lv_color_make(0x02, 0x14, 0x27);
|
||||
lv_style_btn_tgl_pr.body.grad_color = lv_color_make(0x2b, 0x4c, 0x70);
|
||||
lv_style_btn_tgl_pr.text.color = lv_color_make(0xa4, 0xb5, 0xc6);
|
||||
lv_style_btn_tgl_pr.image.color = lv_color_make(0xa4, 0xb5, 0xc6);
|
||||
lv_style_btn_tgl_pr.line.color = lv_color_make(0xa4, 0xb5, 0xc6);
|
||||
lv_style_btn_tgl_pr.text.color = lv_color_make(0xa4, 0xb5, 0xc6);
|
||||
lv_style_btn_tgl_pr.image.color = lv_color_make(0xa4, 0xb5, 0xc6);
|
||||
lv_style_btn_tgl_pr.line.color = lv_color_make(0xa4, 0xb5, 0xc6);
|
||||
|
||||
/*Button inactive style*/
|
||||
memcpy(&lv_style_btn_ina, &lv_style_btn_rel, sizeof(lv_style_t));
|
||||
lv_style_btn_ina.body.main_color = lv_color_make(0xd8, 0xd8, 0xd8);
|
||||
lv_style_btn_ina.body.grad_color = lv_color_make(0xd8, 0xd8, 0xd8);
|
||||
lv_style_btn_ina.body.main_color = lv_color_make(0xd8, 0xd8, 0xd8);
|
||||
lv_style_btn_ina.body.grad_color = lv_color_make(0xd8, 0xd8, 0xd8);
|
||||
lv_style_btn_ina.body.border.color = lv_color_make(0x90, 0x90, 0x90);
|
||||
lv_style_btn_ina.text.color = lv_color_make(0x70, 0x70, 0x70);
|
||||
lv_style_btn_ina.image.color = lv_color_make(0x70, 0x70, 0x70);
|
||||
lv_style_btn_ina.line.color = lv_color_make(0x70, 0x70, 0x70);
|
||||
lv_style_btn_ina.text.color = lv_color_make(0x70, 0x70, 0x70);
|
||||
lv_style_btn_ina.image.color = lv_color_make(0x70, 0x70, 0x70);
|
||||
lv_style_btn_ina.line.color = lv_color_make(0x70, 0x70, 0x70);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Copy a style to an other
|
||||
* @param dest pointer to the destination style
|
||||
@ -226,7 +231,6 @@ void lv_style_copy(lv_style_t * dest, const lv_style_t * src)
|
||||
memcpy(dest, src, sizeof(lv_style_t));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Mix two styles according to a given ratio
|
||||
* @param start start style
|
||||
@ -234,7 +238,8 @@ void lv_style_copy(lv_style_t * dest, const lv_style_t * src)
|
||||
* @param res store the result style here
|
||||
* @param ratio the ratio of mix [0..256]; 0: `start` style; 256: `end` style
|
||||
*/
|
||||
void lv_style_mix(const lv_style_t * start, const lv_style_t * end, lv_style_t * res, uint16_t ratio)
|
||||
void lv_style_mix(const lv_style_t * start, const lv_style_t * end, lv_style_t * res,
|
||||
uint16_t ratio)
|
||||
{
|
||||
STYLE_ATTR_MIX(body.opa, ratio);
|
||||
STYLE_ATTR_MIX(body.radius, ratio);
|
||||
@ -256,26 +261,26 @@ void lv_style_mix(const lv_style_t * start, const lv_style_t * end, lv_style_t *
|
||||
|
||||
lv_opa_t opa = ratio == STYLE_MIX_MAX ? LV_OPA_COVER : ratio;
|
||||
|
||||
res->body.main_color = lv_color_mix(end->body.main_color, start->body.main_color, opa);
|
||||
res->body.grad_color = lv_color_mix(end->body.grad_color, start->body.grad_color, opa);
|
||||
res->body.main_color = lv_color_mix(end->body.main_color, start->body.main_color, opa);
|
||||
res->body.grad_color = lv_color_mix(end->body.grad_color, start->body.grad_color, opa);
|
||||
res->body.border.color = lv_color_mix(end->body.border.color, start->body.border.color, opa);
|
||||
res->body.shadow.color = lv_color_mix(end->body.shadow.color, start->body.shadow.color, opa);
|
||||
res->text.color = lv_color_mix(end->text.color, start->text.color, opa);
|
||||
res->image.color = lv_color_mix(end->image.color, start->image.color, opa);
|
||||
res->line.color = lv_color_mix(end->line.color, start->line.color, opa);
|
||||
res->text.color = lv_color_mix(end->text.color, start->text.color, opa);
|
||||
res->image.color = lv_color_mix(end->image.color, start->image.color, opa);
|
||||
res->line.color = lv_color_mix(end->line.color, start->line.color, opa);
|
||||
|
||||
if(ratio < (STYLE_MIX_MAX >> 1)) {
|
||||
res->body.border.part = start->body.border.part;
|
||||
res->glass = start->glass;
|
||||
res->text.font = start->text.font;
|
||||
res->glass = start->glass;
|
||||
res->text.font = start->text.font;
|
||||
res->body.shadow.type = start->body.shadow.type;
|
||||
res->line.rounded = start->line.rounded;
|
||||
res->line.rounded = start->line.rounded;
|
||||
} else {
|
||||
res->body.border.part = end->body.border.part;
|
||||
res->glass = end->glass;
|
||||
res->text.font = end->text.font;
|
||||
res->glass = end->glass;
|
||||
res->text.font = end->text.font;
|
||||
res->body.shadow.type = end->body.shadow.type;
|
||||
res->line.rounded = end->line.rounded;
|
||||
res->line.rounded = end->line.rounded;
|
||||
}
|
||||
}
|
||||
|
||||
@ -284,7 +289,8 @@ void lv_style_mix(const lv_style_t * start, const lv_style_t * end, lv_style_t *
|
||||
/**
|
||||
* Create an animation from a pre-configured 'lv_style_anim_t' variable
|
||||
* @param anim pointer to a pre-configured 'lv_style_anim_t' variable (will be copied)
|
||||
* @return pointer to a descriptor. Really this variable will be animated. (Can be used in `lv_anim_del(dsc, NULL)`)
|
||||
* @return pointer to a descriptor. Really this variable will be animated. (Can be used in
|
||||
* `lv_anim_del(dsc, NULL)`)
|
||||
*/
|
||||
void * lv_style_anim_create(lv_style_anim_t * anim)
|
||||
{
|
||||
@ -299,20 +305,19 @@ void * lv_style_anim_create(lv_style_anim_t * anim)
|
||||
memcpy(dsc->style_anim, anim->style_start, sizeof(lv_style_t));
|
||||
dsc->end_cb = anim->end_cb;
|
||||
|
||||
|
||||
lv_anim_t a;
|
||||
a.var = (void *)dsc;
|
||||
a.start = 0;
|
||||
a.end = STYLE_MIX_MAX;
|
||||
a.fp = (lv_anim_fp_t)style_animator;
|
||||
a.path = lv_anim_path_linear;
|
||||
a.end_cb = style_animation_common_end_cb;
|
||||
a.act_time = anim->act_time;
|
||||
a.time = anim->time;
|
||||
a.playback = anim->playback;
|
||||
a.var = (void *)dsc;
|
||||
a.start = 0;
|
||||
a.end = STYLE_MIX_MAX;
|
||||
a.fp = (lv_anim_fp_t)style_animator;
|
||||
a.path = lv_anim_path_linear;
|
||||
a.end_cb = style_animation_common_end_cb;
|
||||
a.act_time = anim->act_time;
|
||||
a.time = anim->time;
|
||||
a.playback = anim->playback;
|
||||
a.playback_pause = anim->playback_pause;
|
||||
a.repeat = anim->repeat;
|
||||
a.repeat_pause = anim->repeat_pause;
|
||||
a.repeat = anim->repeat;
|
||||
a.repeat_pause = anim->repeat_pause;
|
||||
|
||||
lv_anim_create(&a);
|
||||
|
||||
@ -332,8 +337,8 @@ void * lv_style_anim_create(lv_style_anim_t * anim)
|
||||
static void style_animator(lv_style_anim_dsc_t * dsc, int32_t val)
|
||||
{
|
||||
const lv_style_t * start = &dsc->style_start;
|
||||
const lv_style_t * end = &dsc->style_end;
|
||||
lv_style_t * act = dsc->style_anim;
|
||||
const lv_style_t * end = &dsc->style_end;
|
||||
lv_style_t * act = dsc->style_anim;
|
||||
|
||||
lv_style_mix(start, end, act, val);
|
||||
|
||||
@ -347,7 +352,7 @@ static void style_animator(lv_style_anim_dsc_t * dsc, int32_t val)
|
||||
*/
|
||||
static void style_animation_common_end_cb(void * ptr)
|
||||
{
|
||||
lv_style_anim_dsc_t * dsc = ptr; /*To avoid casting*/
|
||||
lv_style_anim_dsc_t * dsc = ptr; /*To avoid casting*/
|
||||
|
||||
if(dsc->end_cb) dsc->end_cb(dsc);
|
||||
|
||||
|
@ -22,28 +22,26 @@ extern "C" {
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define LV_RADIUS_CIRCLE (LV_COORD_MAX) /*A very big radius to always draw as circle*/
|
||||
#define LV_RADIUS_CIRCLE (LV_COORD_MAX) /*A very big radius to always draw as circle*/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/*Border types (Use 'OR'ed values)*/
|
||||
enum
|
||||
{
|
||||
LV_BORDER_NONE = 0x00,
|
||||
LV_BORDER_BOTTOM = 0x01,
|
||||
LV_BORDER_TOP = 0x02,
|
||||
LV_BORDER_LEFT = 0x04,
|
||||
LV_BORDER_RIGHT = 0x08,
|
||||
LV_BORDER_FULL = 0x0F,
|
||||
LV_BORDER_INTERNAL = 0x10, /*FOR matrix-like objects (e.g. Button matrix)*/
|
||||
enum {
|
||||
LV_BORDER_NONE = 0x00,
|
||||
LV_BORDER_BOTTOM = 0x01,
|
||||
LV_BORDER_TOP = 0x02,
|
||||
LV_BORDER_LEFT = 0x04,
|
||||
LV_BORDER_RIGHT = 0x08,
|
||||
LV_BORDER_FULL = 0x0F,
|
||||
LV_BORDER_INTERNAL = 0x10, /*FOR matrix-like objects (e.g. Button matrix)*/
|
||||
};
|
||||
typedef uint8_t lv_border_part_t;
|
||||
|
||||
/*Shadow types*/
|
||||
enum
|
||||
{
|
||||
enum {
|
||||
LV_SHADOW_BOTTOM = 0,
|
||||
LV_SHADOW_FULL,
|
||||
};
|
||||
@ -51,28 +49,32 @@ typedef uint8_t lv_shadow_type_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t glass :1; /*1: Do not inherit this style*/
|
||||
uint8_t glass : 1; /*1: Do not inherit this style*/
|
||||
|
||||
struct {
|
||||
struct
|
||||
{
|
||||
lv_color_t main_color;
|
||||
lv_color_t grad_color; /*`grad_color` will be removed in v6.0, use `aux_color` instead*/
|
||||
lv_color_t grad_color; /*`grad_color` will be removed in v6.0, use `aux_color` instead*/
|
||||
lv_coord_t radius;
|
||||
lv_opa_t opa;
|
||||
|
||||
struct {
|
||||
struct
|
||||
{
|
||||
lv_color_t color;
|
||||
lv_coord_t width;
|
||||
lv_border_part_t part;
|
||||
lv_opa_t opa;
|
||||
} border;
|
||||
|
||||
struct {
|
||||
struct
|
||||
{
|
||||
lv_color_t color;
|
||||
lv_coord_t width;
|
||||
lv_shadow_type_t type;
|
||||
} shadow;
|
||||
|
||||
struct {
|
||||
struct
|
||||
{
|
||||
lv_coord_t top;
|
||||
lv_coord_t bottom;
|
||||
lv_coord_t left;
|
||||
@ -81,8 +83,8 @@ typedef struct
|
||||
} padding;
|
||||
} body;
|
||||
|
||||
|
||||
struct {
|
||||
struct
|
||||
{
|
||||
lv_color_t color;
|
||||
lv_color_t sel_color;
|
||||
const lv_font_t * font;
|
||||
@ -91,22 +93,25 @@ typedef struct
|
||||
lv_opa_t opa;
|
||||
} text;
|
||||
|
||||
struct {
|
||||
struct
|
||||
{
|
||||
lv_color_t color;
|
||||
lv_opa_t intense;
|
||||
lv_opa_t opa;
|
||||
} image;
|
||||
|
||||
struct {
|
||||
struct
|
||||
{
|
||||
lv_color_t color;
|
||||
lv_coord_t width;
|
||||
lv_opa_t opa;
|
||||
uint8_t rounded :1; /*1: rounded line endings*/
|
||||
uint8_t rounded : 1; /*1: rounded line endings*/
|
||||
} line;
|
||||
} lv_style_t;
|
||||
|
||||
#if LV_USE_ANIMATION
|
||||
typedef struct {
|
||||
typedef struct
|
||||
{
|
||||
const lv_style_t * style_start; /*Pointer to the starting style*/
|
||||
const lv_style_t * style_end; /*Pointer to the destination style*/
|
||||
lv_style_t * style_anim; /*Pointer to a style to animate*/
|
||||
@ -115,8 +120,8 @@ typedef struct {
|
||||
int16_t act_time; /*Current time in animation. Set to negative to make delay.*/
|
||||
uint16_t playback_pause; /*Wait before play back*/
|
||||
uint16_t repeat_pause; /*Wait before repeat*/
|
||||
uint8_t playback :1; /*When the animation is ready play it back*/
|
||||
uint8_t repeat :1; /*Repeat the animation infinitely*/
|
||||
uint8_t playback : 1; /*When the animation is ready play it back*/
|
||||
uint8_t repeat : 1; /*Repeat the animation infinitely*/
|
||||
} lv_style_anim_t;
|
||||
|
||||
/* Example initialization
|
||||
@ -142,7 +147,7 @@ lv_style_anim_create(&a);
|
||||
/**
|
||||
* Init the basic styles
|
||||
*/
|
||||
void lv_style_init (void);
|
||||
void lv_style_init(void);
|
||||
|
||||
/**
|
||||
* Copy a style to an other
|
||||
@ -151,7 +156,6 @@ void lv_style_init (void);
|
||||
*/
|
||||
void lv_style_copy(lv_style_t * dest, const lv_style_t * src);
|
||||
|
||||
|
||||
/**
|
||||
* Mix two styles according to a given ratio
|
||||
* @param start start style
|
||||
@ -159,14 +163,16 @@ void lv_style_copy(lv_style_t * dest, const lv_style_t * src);
|
||||
* @param res store the result style here
|
||||
* @param ratio the ratio of mix [0..256]; 0: `start` style; 256: `end` style
|
||||
*/
|
||||
void lv_style_mix(const lv_style_t * start, const lv_style_t * end, lv_style_t * res, uint16_t ratio);
|
||||
void lv_style_mix(const lv_style_t * start, const lv_style_t * end, lv_style_t * res,
|
||||
uint16_t ratio);
|
||||
|
||||
#if LV_USE_ANIMATION
|
||||
|
||||
/**
|
||||
* Create an animation from a pre-configured 'lv_style_anim_t' variable
|
||||
* @param anim pointer to a pre-configured 'lv_style_anim_t' variable (will be copied)
|
||||
* @return pointer to a descriptor. Really this variable will be animated. (Can be used in `lv_anim_del(dsc, NULL)`)
|
||||
* @return pointer to a descriptor. Really this variable will be animated. (Can be used in
|
||||
* `lv_anim_del(dsc, NULL)`)
|
||||
*/
|
||||
void * lv_style_anim_create(lv_style_anim_t * anim);
|
||||
#endif
|
||||
@ -192,9 +198,8 @@ extern lv_style_t lv_style_btn_ina;
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_STYLE_H*/
|
||||
#endif /*LV_STYLE_H*/
|
||||
|
@ -58,36 +58,36 @@ lv_opa_t lv_draw_aa_get_opa(lv_coord_t seg, lv_coord_t px_id, lv_opa_t base_opa)
|
||||
* * * |
|
||||
*
|
||||
* Anti-aliased pixels come to the '*' characters
|
||||
* Calculate what percentage of the pixels should be covered if real line (not rasterized) would be drawn:
|
||||
* Calculate what percentage of the pixels should be covered if real line (not rasterized) would
|
||||
* be drawn:
|
||||
* 1. A real line should start on (0;0) and end on (2;1)
|
||||
* 2. So the line intersection coordinates on the first pixel: (0;0) (1;0.5) -> 25% covered pixel in average
|
||||
* 2. So the line intersection coordinates on the first pixel: (0;0) (1;0.5) -> 25% covered
|
||||
* pixel in average
|
||||
* 3. For the second pixel: (1;0.5) (2;1) -> 75% covered pixel in average
|
||||
* 4. The equation: (px_id * 2 + 1) / (segment_width * 2)
|
||||
* segment_width: the line segment which is being anti-aliased (was 2 in the example)
|
||||
* px_id: pixel ID from 0 to (segment_width - 1)
|
||||
* result: [0..1] coverage of the pixel
|
||||
* segment_width: the line segment which is being anti-aliased (was 2 in the
|
||||
* example) px_id: pixel ID from 0 to (segment_width - 1) result: [0..1] coverage of the pixel
|
||||
*/
|
||||
|
||||
/*Accelerate the common segment sizes to avoid division*/
|
||||
static const lv_opa_t seg1[1] = {128};
|
||||
static const lv_opa_t seg2[2] = {64, 192};
|
||||
static const lv_opa_t seg3[3] = {42, 128, 212};
|
||||
static const lv_opa_t seg4[4] = {32, 96, 159, 223};
|
||||
static const lv_opa_t seg5[5] = {26, 76, 128, 178, 230};
|
||||
static const lv_opa_t seg6[6] = {21, 64, 106, 148, 191, 234};
|
||||
static const lv_opa_t seg7[7] = {18, 55, 91, 128, 164, 200, 237};
|
||||
static const lv_opa_t seg8[8] = {16, 48, 80, 112, 143, 175, 207, 239};
|
||||
static const lv_opa_t seg1[1] = {128};
|
||||
static const lv_opa_t seg2[2] = {64, 192};
|
||||
static const lv_opa_t seg3[3] = {42, 128, 212};
|
||||
static const lv_opa_t seg4[4] = {32, 96, 159, 223};
|
||||
static const lv_opa_t seg5[5] = {26, 76, 128, 178, 230};
|
||||
static const lv_opa_t seg6[6] = {21, 64, 106, 148, 191, 234};
|
||||
static const lv_opa_t seg7[7] = {18, 55, 91, 128, 164, 200, 237};
|
||||
static const lv_opa_t seg8[8] = {16, 48, 80, 112, 143, 175, 207, 239};
|
||||
|
||||
static const lv_opa_t * seg_map[] = {seg1, seg2, seg3, seg4,
|
||||
seg5, seg6, seg7, seg8
|
||||
};
|
||||
static const lv_opa_t * seg_map[] = {seg1, seg2, seg3, seg4, seg5, seg6, seg7, seg8};
|
||||
|
||||
if(seg == 0) return LV_OPA_TRANSP;
|
||||
else if(seg < 8) return (uint32_t)((uint32_t)seg_map[seg - 1][px_id] * base_opa) >> 8;
|
||||
if(seg == 0)
|
||||
return LV_OPA_TRANSP;
|
||||
else if(seg < 8)
|
||||
return (uint32_t)((uint32_t)seg_map[seg - 1][px_id] * base_opa) >> 8;
|
||||
else {
|
||||
return ((px_id * 2 + 1) * base_opa) / (2 * seg);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -99,7 +99,8 @@ lv_opa_t lv_draw_aa_get_opa(lv_coord_t seg, lv_coord_t px_id, lv_opa_t base_opa)
|
||||
* @param color color of pixels
|
||||
* @param opa maximum opacity
|
||||
*/
|
||||
void lv_draw_aa_ver_seg(lv_coord_t x, lv_coord_t y, lv_coord_t length, const lv_area_t * mask, lv_color_t color, lv_opa_t opa)
|
||||
void lv_draw_aa_ver_seg(lv_coord_t x, lv_coord_t y, lv_coord_t length, const lv_area_t * mask,
|
||||
lv_color_t color, lv_opa_t opa)
|
||||
{
|
||||
bool aa_inv = false;
|
||||
if(length < 0) {
|
||||
@ -124,7 +125,8 @@ void lv_draw_aa_ver_seg(lv_coord_t x, lv_coord_t y, lv_coord_t length, const lv_
|
||||
* @param color color of pixels
|
||||
* @param opa maximum opacity
|
||||
*/
|
||||
void lv_draw_aa_hor_seg(lv_coord_t x, lv_coord_t y, lv_coord_t length, const lv_area_t * mask, lv_color_t color, lv_opa_t opa)
|
||||
void lv_draw_aa_hor_seg(lv_coord_t x, lv_coord_t y, lv_coord_t length, const lv_area_t * mask,
|
||||
lv_color_t color, lv_opa_t opa)
|
||||
{
|
||||
bool aa_inv = false;
|
||||
if(length < 0) {
|
||||
|
@ -27,11 +27,11 @@ extern "C" {
|
||||
*********************/
|
||||
/*If image pixels contains alpha we need to know how much byte is a pixel*/
|
||||
#if LV_COLOR_DEPTH == 1 || LV_COLOR_DEPTH == 8
|
||||
# define LV_IMG_PX_SIZE_ALPHA_BYTE 2
|
||||
#define LV_IMG_PX_SIZE_ALPHA_BYTE 2
|
||||
#elif LV_COLOR_DEPTH == 16
|
||||
# define LV_IMG_PX_SIZE_ALPHA_BYTE 3
|
||||
#define LV_IMG_PX_SIZE_ALPHA_BYTE 3
|
||||
#elif LV_COLOR_DEPTH == 32
|
||||
# define LV_IMG_PX_SIZE_ALPHA_BYTE 4
|
||||
#define LV_IMG_PX_SIZE_ALPHA_BYTE 4
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
@ -46,7 +46,6 @@ enum {
|
||||
};
|
||||
typedef uint8_t lv_img_src_t;
|
||||
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
@ -71,7 +70,8 @@ lv_opa_t lv_draw_aa_get_opa(lv_coord_t seg, lv_coord_t px_id, lv_opa_t base_opa)
|
||||
* @param color color of pixels
|
||||
* @param opa maximum opacity
|
||||
*/
|
||||
void lv_draw_aa_ver_seg(lv_coord_t x, lv_coord_t y, lv_coord_t length, const lv_area_t * mask, lv_color_t color, lv_opa_t opa);
|
||||
void lv_draw_aa_ver_seg(lv_coord_t x, lv_coord_t y, lv_coord_t length, const lv_area_t * mask,
|
||||
lv_color_t color, lv_opa_t opa);
|
||||
|
||||
/**
|
||||
* Add a horizontal anti-aliasing segment (pixels with decreasing opacity)
|
||||
@ -82,7 +82,8 @@ void lv_draw_aa_ver_seg(lv_coord_t x, lv_coord_t y, lv_coord_t length, const lv_
|
||||
* @param color color of pixels
|
||||
* @param opa maximum opacity
|
||||
*/
|
||||
void lv_draw_aa_hor_seg(lv_coord_t x, lv_coord_t y, lv_coord_t length, const lv_area_t * mask, lv_color_t color, lv_opa_t opa);
|
||||
void lv_draw_aa_hor_seg(lv_coord_t x, lv_coord_t y, lv_coord_t length, const lv_area_t * mask,
|
||||
lv_color_t color, lv_opa_t opa);
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
@ -107,4 +108,4 @@ void lv_draw_aa_hor_seg(lv_coord_t x, lv_coord_t y, lv_coord_t length, const lv_
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_DRAW_H*/
|
||||
#endif /*LV_DRAW_H*/
|
||||
|
@ -21,8 +21,10 @@
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static uint16_t fast_atan2(int x, int y);
|
||||
static void ver_line(lv_coord_t x, lv_coord_t y, const lv_area_t * mask, lv_coord_t len, lv_color_t color, lv_opa_t opa);
|
||||
static void hor_line(lv_coord_t x, lv_coord_t y, const lv_area_t * mask, lv_coord_t len, lv_color_t color, lv_opa_t opa);
|
||||
static void ver_line(lv_coord_t x, lv_coord_t y, const lv_area_t * mask, lv_coord_t len,
|
||||
lv_color_t color, lv_opa_t opa);
|
||||
static void hor_line(lv_coord_t x, lv_coord_t y, const lv_area_t * mask, lv_coord_t len,
|
||||
lv_color_t color, lv_opa_t opa);
|
||||
static bool deg_test_norm(uint16_t deg, uint16_t start, uint16_t end);
|
||||
static bool deg_test_inv(uint16_t deg, uint16_t start, uint16_t end);
|
||||
|
||||
@ -50,33 +52,41 @@ static bool deg_test_inv(uint16_t deg, uint16_t start, uint16_t end);
|
||||
* @param opa_scale scale down all opacities by the factor
|
||||
*/
|
||||
void lv_draw_arc(lv_coord_t center_x, lv_coord_t center_y, uint16_t radius, const lv_area_t * mask,
|
||||
uint16_t start_angle, uint16_t end_angle, const lv_style_t * style, lv_opa_t opa_scale)
|
||||
uint16_t start_angle, uint16_t end_angle, const lv_style_t * style,
|
||||
lv_opa_t opa_scale)
|
||||
{
|
||||
lv_coord_t thickness = style->line.width;
|
||||
if(thickness > radius) thickness = radius;
|
||||
|
||||
lv_coord_t r_out = radius;
|
||||
lv_coord_t r_in = r_out - thickness;
|
||||
lv_coord_t r_in = r_out - thickness;
|
||||
int16_t deg_base;
|
||||
int16_t deg;
|
||||
lv_coord_t x_start[4];
|
||||
lv_coord_t x_end[4];
|
||||
|
||||
lv_color_t color = style->line.color;
|
||||
lv_opa_t opa = opa_scale == LV_OPA_COVER ? style->body.opa : (uint16_t)((uint16_t) style->body.opa * opa_scale) >> 8;
|
||||
|
||||
lv_opa_t opa = opa_scale == LV_OPA_COVER
|
||||
? style->body.opa
|
||||
: (uint16_t)((uint16_t)style->body.opa * opa_scale) >> 8;
|
||||
|
||||
bool (*deg_test)(uint16_t, uint16_t, uint16_t);
|
||||
if(start_angle <= end_angle) deg_test = deg_test_norm;
|
||||
else deg_test = deg_test_inv;
|
||||
if(start_angle <= end_angle)
|
||||
deg_test = deg_test_norm;
|
||||
else
|
||||
deg_test = deg_test_inv;
|
||||
|
||||
if(deg_test(270, start_angle, end_angle)) hor_line(center_x - r_out + 1, center_y, mask, thickness - 1, color, opa); // Left Middle
|
||||
if(deg_test(90, start_angle, end_angle)) hor_line(center_x + r_in, center_y, mask, thickness - 1, color, opa); // Right Middle
|
||||
if(deg_test(180, start_angle, end_angle)) ver_line(center_x, center_y - r_out + 1, mask, thickness - 1, color, opa); // Top Middle
|
||||
if(deg_test(0, start_angle, end_angle)) ver_line(center_x, center_y + r_in, mask, thickness - 1, color, opa); // Bottom middle
|
||||
if(deg_test(270, start_angle, end_angle))
|
||||
hor_line(center_x - r_out + 1, center_y, mask, thickness - 1, color, opa); // Left Middle
|
||||
if(deg_test(90, start_angle, end_angle))
|
||||
hor_line(center_x + r_in, center_y, mask, thickness - 1, color, opa); // Right Middle
|
||||
if(deg_test(180, start_angle, end_angle))
|
||||
ver_line(center_x, center_y - r_out + 1, mask, thickness - 1, color, opa); // Top Middle
|
||||
if(deg_test(0, start_angle, end_angle))
|
||||
ver_line(center_x, center_y + r_in, mask, thickness - 1, color, opa); // Bottom middle
|
||||
|
||||
uint32_t r_out_sqr = r_out * r_out;
|
||||
uint32_t r_in_sqr = r_in * r_in;
|
||||
uint32_t r_in_sqr = r_in * r_in;
|
||||
int16_t xi;
|
||||
int16_t yi;
|
||||
for(yi = -r_out; yi < 0; yi++) {
|
||||
@ -84,16 +94,16 @@ void lv_draw_arc(lv_coord_t center_x, lv_coord_t center_y, uint16_t radius, cons
|
||||
x_start[1] = LV_COORD_MIN;
|
||||
x_start[2] = LV_COORD_MIN;
|
||||
x_start[3] = LV_COORD_MIN;
|
||||
x_end[0] = LV_COORD_MIN;
|
||||
x_end[1] = LV_COORD_MIN;
|
||||
x_end[2] = LV_COORD_MIN;
|
||||
x_end[3] = LV_COORD_MIN;
|
||||
x_end[0] = LV_COORD_MIN;
|
||||
x_end[1] = LV_COORD_MIN;
|
||||
x_end[2] = LV_COORD_MIN;
|
||||
x_end[3] = LV_COORD_MIN;
|
||||
for(xi = -r_out; xi < 0; xi++) {
|
||||
|
||||
uint32_t r_act_sqr = xi * xi + yi * yi;
|
||||
if(r_act_sqr > r_out_sqr) continue;
|
||||
|
||||
deg_base = fast_atan2(xi, yi) - 180;
|
||||
deg_base = fast_atan2(xi, yi) - 180;
|
||||
|
||||
deg = 180 + deg_base;
|
||||
if(deg_test(deg, start_angle, end_angle)) {
|
||||
@ -123,10 +133,11 @@ void lv_draw_arc(lv_coord_t center_x, lv_coord_t center_y, uint16_t radius, cons
|
||||
x_end[3] = xi - 1;
|
||||
}
|
||||
|
||||
if(r_act_sqr < r_in_sqr) break; /*No need to continue the iteration in x once we found the inner edge of the arc*/
|
||||
if(r_act_sqr < r_in_sqr)
|
||||
break; /*No need to continue the iteration in x once we found the inner edge of the
|
||||
arc*/
|
||||
}
|
||||
|
||||
|
||||
if(x_start[0] != LV_COORD_MIN) {
|
||||
if(x_end[0] == LV_COORD_MIN) x_end[0] = xi - 1;
|
||||
hor_line(center_x + x_start[0], center_y + yi, mask, x_end[0] - x_start[0], color, opa);
|
||||
@ -139,20 +150,20 @@ void lv_draw_arc(lv_coord_t center_x, lv_coord_t center_y, uint16_t radius, cons
|
||||
|
||||
if(x_start[2] != LV_COORD_MIN) {
|
||||
if(x_end[2] == LV_COORD_MIN) x_end[2] = xi - 1;
|
||||
hor_line(center_x - x_end[2], center_y + yi, mask, LV_MATH_ABS(x_end[2] - x_start[2]), color, opa);
|
||||
hor_line(center_x - x_end[2], center_y + yi, mask, LV_MATH_ABS(x_end[2] - x_start[2]),
|
||||
color, opa);
|
||||
}
|
||||
|
||||
if(x_start[3] != LV_COORD_MIN) {
|
||||
if(x_end[3] == LV_COORD_MIN) x_end[3] = xi - 1;
|
||||
hor_line(center_x - x_end[3], center_y - yi, mask, LV_MATH_ABS(x_end[3] - x_start[3]), color, opa);
|
||||
hor_line(center_x - x_end[3], center_y - yi, mask, LV_MATH_ABS(x_end[3] - x_start[3]),
|
||||
color, opa);
|
||||
}
|
||||
|
||||
|
||||
#if LV_ANTIALIAS
|
||||
/*TODO*/
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -171,61 +182,61 @@ static uint16_t fast_atan2(int x, int y)
|
||||
unsigned char negflag;
|
||||
unsigned char tempdegree;
|
||||
unsigned char comp;
|
||||
unsigned int degree; // this will hold the result
|
||||
//signed int x; // these hold the XY vector at the start
|
||||
//signed int y; // (and they will be destroyed)
|
||||
unsigned int degree; // this will hold the result
|
||||
// signed int x; // these hold the XY vector at the start
|
||||
// signed int y; // (and they will be destroyed)
|
||||
unsigned int ux;
|
||||
unsigned int uy;
|
||||
|
||||
// Save the sign flags then remove signs and get XY as unsigned ints
|
||||
negflag = 0;
|
||||
if(x < 0) {
|
||||
negflag += 0x01; // x flag bit
|
||||
x = (0 - x); // is now +
|
||||
negflag += 0x01; // x flag bit
|
||||
x = (0 - x); // is now +
|
||||
}
|
||||
ux = x; // copy to unsigned var before multiply
|
||||
ux = x; // copy to unsigned var before multiply
|
||||
if(y < 0) {
|
||||
negflag += 0x02; // y flag bit
|
||||
y = (0 - y); // is now +
|
||||
negflag += 0x02; // y flag bit
|
||||
y = (0 - y); // is now +
|
||||
}
|
||||
uy = y; // copy to unsigned var before multiply
|
||||
uy = y; // copy to unsigned var before multiply
|
||||
|
||||
// 1. Calc the scaled "degrees"
|
||||
if(ux > uy) {
|
||||
degree = (uy * 45) / ux; // degree result will be 0-45 range
|
||||
negflag += 0x10; // octant flag bit
|
||||
degree = (uy * 45) / ux; // degree result will be 0-45 range
|
||||
negflag += 0x10; // octant flag bit
|
||||
} else {
|
||||
degree = (ux * 45) / uy; // degree result will be 0-45 range
|
||||
degree = (ux * 45) / uy; // degree result will be 0-45 range
|
||||
}
|
||||
|
||||
// 2. Compensate for the 4 degree error curve
|
||||
comp = 0;
|
||||
tempdegree = degree; // use an unsigned char for speed!
|
||||
if(tempdegree > 22) { // if top half of range
|
||||
comp = 0;
|
||||
tempdegree = degree; // use an unsigned char for speed!
|
||||
if(tempdegree > 22) { // if top half of range
|
||||
if(tempdegree <= 44) comp++;
|
||||
if(tempdegree <= 41) comp++;
|
||||
if(tempdegree <= 37) comp++;
|
||||
if(tempdegree <= 32) comp++; // max is 4 degrees compensated
|
||||
} else { // else is lower half of range
|
||||
if(tempdegree <= 32) comp++; // max is 4 degrees compensated
|
||||
} else { // else is lower half of range
|
||||
if(tempdegree >= 2) comp++;
|
||||
if(tempdegree >= 6) comp++;
|
||||
if(tempdegree >= 10) comp++;
|
||||
if(tempdegree >= 15) comp++; // max is 4 degrees compensated
|
||||
if(tempdegree >= 15) comp++; // max is 4 degrees compensated
|
||||
}
|
||||
degree += comp; // degree is now accurate to +/- 1 degree!
|
||||
degree += comp; // degree is now accurate to +/- 1 degree!
|
||||
|
||||
// Invert degree if it was X>Y octant, makes 0-45 into 90-45
|
||||
if(negflag & 0x10) degree = (90 - degree);
|
||||
|
||||
// 3. Degree is now 0-90 range for this quadrant,
|
||||
// need to invert it for whichever quadrant it was in
|
||||
if(negflag & 0x02) { // if -Y
|
||||
if(negflag & 0x01) // if -Y -X
|
||||
if(negflag & 0x02) { // if -Y
|
||||
if(negflag & 0x01) // if -Y -X
|
||||
degree = (180 + degree);
|
||||
else // else is -Y +X
|
||||
else // else is -Y +X
|
||||
degree = (180 - degree);
|
||||
} else { // else is +Y
|
||||
if(negflag & 0x01) // if +Y -X
|
||||
} else { // else is +Y
|
||||
if(negflag & 0x01) // if +Y -X
|
||||
degree = (360 - degree);
|
||||
}
|
||||
return degree;
|
||||
@ -234,7 +245,8 @@ static uint16_t fast_atan2(int x, int y)
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
static void ver_line(lv_coord_t x, lv_coord_t y, const lv_area_t * mask, lv_coord_t len, lv_color_t color, lv_opa_t opa)
|
||||
static void ver_line(lv_coord_t x, lv_coord_t y, const lv_area_t * mask, lv_coord_t len,
|
||||
lv_color_t color, lv_opa_t opa)
|
||||
{
|
||||
lv_area_t area;
|
||||
lv_area_set(&area, x, y, x, y + len);
|
||||
@ -242,7 +254,8 @@ static void ver_line(lv_coord_t x, lv_coord_t y, const lv_area_t * mask, lv_coor
|
||||
lv_draw_fill(&area, mask, color, opa);
|
||||
}
|
||||
|
||||
static void hor_line(lv_coord_t x, lv_coord_t y, const lv_area_t * mask, lv_coord_t len, lv_color_t color, lv_opa_t opa)
|
||||
static void hor_line(lv_coord_t x, lv_coord_t y, const lv_area_t * mask, lv_coord_t len,
|
||||
lv_color_t color, lv_opa_t opa)
|
||||
{
|
||||
lv_area_t area;
|
||||
lv_area_set(&area, x, y, x + len, y);
|
||||
@ -252,13 +265,16 @@ static void hor_line(lv_coord_t x, lv_coord_t y, const lv_area_t * mask, lv_coor
|
||||
|
||||
static bool deg_test_norm(uint16_t deg, uint16_t start, uint16_t end)
|
||||
{
|
||||
if(deg >= start && deg <= end) return true;
|
||||
else return false;
|
||||
if(deg >= start && deg <= end)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool deg_test_inv(uint16_t deg, uint16_t start, uint16_t end)
|
||||
{
|
||||
if(deg >= start || deg <= end) {
|
||||
return true;
|
||||
} else return false;
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
@ -39,13 +39,13 @@ extern "C" {
|
||||
* @param opa_scale scale down all opacities by the factor
|
||||
*/
|
||||
void lv_draw_arc(lv_coord_t center_x, lv_coord_t center_y, uint16_t radius, const lv_area_t * mask,
|
||||
uint16_t start_angle, uint16_t end_angle, const lv_style_t * style, lv_opa_t opa_scale);
|
||||
uint16_t start_angle, uint16_t end_angle, const lv_style_t * style,
|
||||
lv_opa_t opa_scale);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
@ -26,7 +26,8 @@
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define VFILL_HW_ACC_SIZE_LIMIT 50 /*Always fill < 50 px with 'sw_color_fill' because of the hw. init overhead*/
|
||||
#define VFILL_HW_ACC_SIZE_LIMIT \
|
||||
50 /*Always fill < 50 px with 'sw_color_fill' because of the hw. init overhead*/
|
||||
|
||||
#ifndef LV_ATTRIBUTE_MEM_ALIGN
|
||||
#define LV_ATTRIBUTE_MEM_ALIGN
|
||||
@ -40,10 +41,12 @@
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static void sw_mem_blend(lv_color_t * dest, const lv_color_t * src, uint32_t length, lv_opa_t opa);
|
||||
static void sw_color_fill(lv_area_t * mem_area, lv_color_t * mem, const lv_area_t * fill_area, lv_color_t color, lv_opa_t opa);
|
||||
static void sw_color_fill(lv_area_t * mem_area, lv_color_t * mem, const lv_area_t * fill_area,
|
||||
lv_color_t color, lv_opa_t opa);
|
||||
|
||||
#if LV_COLOR_SCREEN_TRANSP
|
||||
static inline lv_color_t color_mix_2_alpha(lv_color_t bg_color, lv_opa_t bg_opa, lv_color_t fg_color, lv_opa_t fg_opa);
|
||||
static inline lv_color_t color_mix_2_alpha(lv_color_t bg_color, lv_opa_t bg_opa,
|
||||
lv_color_t fg_color, lv_opa_t fg_opa);
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
@ -66,21 +69,20 @@ static inline lv_color_t color_mix_2_alpha(lv_color_t bg_color, lv_opa_t bg_opa,
|
||||
* @param color pixel color
|
||||
* @param opa opacity of the area (0..255)
|
||||
*/
|
||||
void lv_draw_px(lv_coord_t x, lv_coord_t y, const lv_area_t * mask_p, lv_color_t color, lv_opa_t opa)
|
||||
void lv_draw_px(lv_coord_t x, lv_coord_t y, const lv_area_t * mask_p, lv_color_t color,
|
||||
lv_opa_t opa)
|
||||
{
|
||||
if(opa < LV_OPA_MIN) return;
|
||||
if(opa > LV_OPA_MAX) opa = LV_OPA_COVER;
|
||||
|
||||
|
||||
/*Pixel out of the mask*/
|
||||
if(x < mask_p->x1 || x > mask_p->x2 ||
|
||||
y < mask_p->y1 || y > mask_p->y2) {
|
||||
if(x < mask_p->x1 || x > mask_p->x2 || y < mask_p->y1 || y > mask_p->y2) {
|
||||
return;
|
||||
}
|
||||
|
||||
lv_disp_t * disp = lv_refr_get_disp_refreshing();
|
||||
lv_disp_t * disp = lv_refr_get_disp_refreshing();
|
||||
lv_disp_buf_t * vdb = lv_disp_get_buf(disp);
|
||||
uint32_t vdb_width = lv_area_get_width(&vdb->area);
|
||||
uint32_t vdb_width = lv_area_get_width(&vdb->area);
|
||||
|
||||
/*Make the coordinates relative to VDB*/
|
||||
x -= vdb->area.x1;
|
||||
@ -103,7 +105,6 @@ void lv_draw_px(lv_coord_t x, lv_coord_t y, const lv_area_t * mask_p, lv_color_t
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Fill an area in the Virtual Display Buffer
|
||||
* @param cords_p coordinates of the area to fill
|
||||
@ -111,8 +112,8 @@ void lv_draw_px(lv_coord_t x, lv_coord_t y, const lv_area_t * mask_p, lv_color_t
|
||||
* @param color fill color
|
||||
* @param opa opacity of the area (0..255)
|
||||
*/
|
||||
void lv_draw_fill(const lv_area_t * cords_p, const lv_area_t * mask_p,
|
||||
lv_color_t color, lv_opa_t opa)
|
||||
void lv_draw_fill(const lv_area_t * cords_p, const lv_area_t * mask_p, lv_color_t color,
|
||||
lv_opa_t opa)
|
||||
{
|
||||
if(opa < LV_OPA_MIN) return;
|
||||
if(opa > LV_OPA_MAX) opa = LV_OPA_COVER;
|
||||
@ -128,23 +129,23 @@ void lv_draw_fill(const lv_area_t * cords_p, const lv_area_t * mask_p,
|
||||
/*If there are common part of the three area then draw to the vdb*/
|
||||
if(union_ok == false) return;
|
||||
|
||||
lv_disp_t * disp = lv_refr_get_disp_refreshing();
|
||||
lv_disp_t * disp = lv_refr_get_disp_refreshing();
|
||||
lv_disp_buf_t * vdb = lv_disp_get_buf(disp);
|
||||
|
||||
lv_area_t vdb_rel_a; /*Stores relative coordinates on vdb*/
|
||||
lv_area_t vdb_rel_a; /*Stores relative coordinates on vdb*/
|
||||
vdb_rel_a.x1 = res_a.x1 - vdb->area.x1;
|
||||
vdb_rel_a.y1 = res_a.y1 - vdb->area.y1;
|
||||
vdb_rel_a.x2 = res_a.x2 - vdb->area.x1;
|
||||
vdb_rel_a.y2 = res_a.y2 - vdb->area.y1;
|
||||
|
||||
lv_color_t * vdb_buf_tmp = vdb->buf_act;
|
||||
uint32_t vdb_width = lv_area_get_width(&vdb->area);
|
||||
uint32_t vdb_width = lv_area_get_width(&vdb->area);
|
||||
/*Move the vdb_tmp to the first row*/
|
||||
vdb_buf_tmp += vdb_width * vdb_rel_a.y1;
|
||||
|
||||
|
||||
#if LV_USE_GPU
|
||||
static LV_ATTRIBUTE_MEM_ALIGN lv_color_t color_array_tmp[LV_HOR_RES_MAX]; /*Used by 'lv_disp_mem_blend'*/
|
||||
static LV_ATTRIBUTE_MEM_ALIGN lv_color_t
|
||||
color_array_tmp[LV_HOR_RES_MAX]; /*Used by 'lv_disp_mem_blend'*/
|
||||
static lv_coord_t last_width = -1;
|
||||
|
||||
lv_coord_t w = lv_area_get_width(&vdb_rel_a);
|
||||
@ -211,7 +212,6 @@ void lv_draw_fill(const lv_area_t * cords_p, const lv_area_t * mask_p,
|
||||
else {
|
||||
sw_color_fill(&vdb->area, vdb->buf_act, &vdb_rel_a, color, opa);
|
||||
}
|
||||
|
||||
}
|
||||
#else
|
||||
sw_color_fill(&vdb->area, vdb->buf_act, &vdb_rel_a, color, opa);
|
||||
@ -227,17 +227,14 @@ void lv_draw_fill(const lv_area_t * cords_p, const lv_area_t * mask_p,
|
||||
* @param color color of letter
|
||||
* @param opa opacity of letter (0..255)
|
||||
*/
|
||||
void lv_draw_letter(const lv_point_t * pos_p, const lv_area_t * mask_p,
|
||||
const lv_font_t * font_p, uint32_t letter,
|
||||
lv_color_t color, lv_opa_t opa)
|
||||
void lv_draw_letter(const lv_point_t * pos_p, const lv_area_t * mask_p, const lv_font_t * font_p,
|
||||
uint32_t letter, lv_color_t color, lv_opa_t opa)
|
||||
{
|
||||
const uint8_t bpp1_opa_table[2] = {0, 255}; /*Opacity mapping with bpp = 1 (Just for compatibility)*/
|
||||
const uint8_t bpp2_opa_table[4] = {0, 85, 170, 255}; /*Opacity mapping with bpp = 2*/
|
||||
const uint8_t bpp4_opa_table[16] = {0, 17, 34, 51, /*Opacity mapping with bpp = 4*/
|
||||
68, 85, 102, 119,
|
||||
136, 153, 170, 187,
|
||||
204, 221, 238, 255
|
||||
};
|
||||
const uint8_t bpp1_opa_table[2] = {
|
||||
0, 255}; /*Opacity mapping with bpp = 1 (Just for compatibility)*/
|
||||
const uint8_t bpp2_opa_table[4] = {0, 85, 170, 255}; /*Opacity mapping with bpp = 2*/
|
||||
const uint8_t bpp4_opa_table[16] = {0, 17, 34, 51, /*Opacity mapping with bpp = 4*/
|
||||
68, 85, 102, 119, 136, 153, 170, 187, 204, 221, 238, 255};
|
||||
if(opa < LV_OPA_MIN) return;
|
||||
if(opa > LV_OPA_MAX) opa = LV_OPA_COVER;
|
||||
|
||||
@ -250,7 +247,7 @@ void lv_draw_letter(const lv_point_t * pos_p, const lv_area_t * mask_p,
|
||||
lv_coord_t pos_y = pos_p->y;
|
||||
uint8_t letter_w = lv_font_get_real_width(font_p, letter);
|
||||
uint8_t letter_h = lv_font_get_height(font_p);
|
||||
uint8_t bpp = lv_font_get_bpp(font_p, letter); /*Bit per pixel (1,2, 4 or 8)*/
|
||||
uint8_t bpp = lv_font_get_bpp(font_p, letter); /*Bit per pixel (1,2, 4 or 8)*/
|
||||
const uint8_t * bpp_opa_table;
|
||||
uint8_t mask_init;
|
||||
uint8_t mask;
|
||||
@ -259,26 +256,24 @@ void lv_draw_letter(const lv_point_t * pos_p, const lv_area_t * mask_p,
|
||||
pos_x += (lv_font_get_width(font_p, letter) - letter_w) / 2;
|
||||
}
|
||||
|
||||
|
||||
switch(bpp) {
|
||||
case 1:
|
||||
bpp_opa_table = bpp1_opa_table;
|
||||
mask_init = 0x80;
|
||||
mask_init = 0x80;
|
||||
break;
|
||||
case 2:
|
||||
bpp_opa_table = bpp2_opa_table;
|
||||
mask_init = 0xC0;
|
||||
mask_init = 0xC0;
|
||||
break;
|
||||
case 4:
|
||||
bpp_opa_table = bpp4_opa_table;
|
||||
mask_init = 0xF0;
|
||||
mask_init = 0xF0;
|
||||
break;
|
||||
case 8:
|
||||
bpp_opa_table = NULL;
|
||||
mask_init = 0xFF;
|
||||
break; /*No opa table, pixel value will be used directly*/
|
||||
default:
|
||||
return; /*Invalid bpp. Can't render the letter*/
|
||||
mask_init = 0xFF;
|
||||
break; /*No opa table, pixel value will be used directly*/
|
||||
default: return; /*Invalid bpp. Can't render the letter*/
|
||||
}
|
||||
|
||||
const uint8_t * map_p = lv_font_get_bitmap(font_p, letter);
|
||||
@ -286,31 +281,32 @@ void lv_draw_letter(const lv_point_t * pos_p, const lv_area_t * mask_p,
|
||||
if(map_p == NULL) return;
|
||||
|
||||
/*If the letter is completely out of mask don't draw it */
|
||||
if(pos_x + letter_w < mask_p->x1 || pos_x > mask_p->x2 ||
|
||||
pos_y + letter_h < mask_p->y1 || pos_y > mask_p->y2) return;
|
||||
if(pos_x + letter_w < mask_p->x1 || pos_x > mask_p->x2 || pos_y + letter_h < mask_p->y1 ||
|
||||
pos_y > mask_p->y2)
|
||||
return;
|
||||
|
||||
lv_disp_t * disp = lv_refr_get_disp_refreshing();
|
||||
lv_disp_t * disp = lv_refr_get_disp_refreshing();
|
||||
lv_disp_buf_t * vdb = lv_disp_get_buf(disp);
|
||||
|
||||
lv_coord_t vdb_width = lv_area_get_width(&vdb->area);
|
||||
lv_coord_t vdb_width = lv_area_get_width(&vdb->area);
|
||||
lv_color_t * vdb_buf_tmp = vdb->buf_act;
|
||||
lv_coord_t col, row;
|
||||
uint8_t col_bit;
|
||||
uint8_t col_byte_cnt;
|
||||
uint8_t width_byte_scr = letter_w >> 3; /*Width in bytes (on the screen finally) (e.g. w = 11 -> 2 bytes wide)*/
|
||||
uint8_t width_byte_scr =
|
||||
letter_w >> 3; /*Width in bytes (on the screen finally) (e.g. w = 11 -> 2 bytes wide)*/
|
||||
if(letter_w & 0x7) width_byte_scr++;
|
||||
uint8_t width_byte_bpp = (letter_w * bpp) >> 3; /*Letter width in byte. Real width in the font*/
|
||||
uint8_t width_byte_bpp = (letter_w * bpp) >> 3; /*Letter width in byte. Real width in the font*/
|
||||
if((letter_w * bpp) & 0x7) width_byte_bpp++;
|
||||
|
||||
/* Calculate the col/row start/end on the map*/
|
||||
lv_coord_t col_start = pos_x >= mask_p->x1 ? 0 : mask_p->x1 - pos_x;
|
||||
lv_coord_t col_end = pos_x + letter_w <= mask_p->x2 ? letter_w : mask_p->x2 - pos_x + 1;
|
||||
lv_coord_t col_end = pos_x + letter_w <= mask_p->x2 ? letter_w : mask_p->x2 - pos_x + 1;
|
||||
lv_coord_t row_start = pos_y >= mask_p->y1 ? 0 : mask_p->y1 - pos_y;
|
||||
lv_coord_t row_end = pos_y + letter_h <= mask_p->y2 ? letter_h : mask_p->y2 - pos_y + 1;
|
||||
lv_coord_t row_end = pos_y + letter_h <= mask_p->y2 ? letter_h : mask_p->y2 - pos_y + 1;
|
||||
|
||||
/*Set a pointer on VDB to the first pixel of the letter*/
|
||||
vdb_buf_tmp += ((pos_y - vdb->area.y1) * vdb_width)
|
||||
+ pos_x - vdb->area.x1;
|
||||
vdb_buf_tmp += ((pos_y - vdb->area.y1) * vdb_width) + pos_x - vdb->area.x1;
|
||||
|
||||
/*If the letter is partially out of mask the move there on VDB*/
|
||||
vdb_buf_tmp += (row_start * vdb_width) + col_start;
|
||||
@ -320,30 +316,30 @@ void lv_draw_letter(const lv_point_t * pos_p, const lv_area_t * mask_p,
|
||||
|
||||
uint8_t letter_px;
|
||||
lv_opa_t px_opa;
|
||||
for(row = row_start; row < row_end; row ++) {
|
||||
for(row = row_start; row < row_end; row++) {
|
||||
col_byte_cnt = 0;
|
||||
col_bit = (col_start * bpp) % 8;
|
||||
mask = mask_init >> col_bit;
|
||||
for(col = col_start; col < col_end; col ++) {
|
||||
col_bit = (col_start * bpp) % 8;
|
||||
mask = mask_init >> col_bit;
|
||||
for(col = col_start; col < col_end; col++) {
|
||||
letter_px = (*map_p & mask) >> (8 - col_bit - bpp);
|
||||
if(letter_px != 0) {
|
||||
if(opa == LV_OPA_COVER) {
|
||||
px_opa = bpp == 8 ? letter_px : bpp_opa_table[letter_px];
|
||||
} else {
|
||||
px_opa = bpp == 8 ?
|
||||
(uint16_t)((uint16_t)letter_px * opa) >> 8 :
|
||||
(uint16_t)((uint16_t)bpp_opa_table[letter_px] * opa) >> 8;
|
||||
px_opa = bpp == 8 ? (uint16_t)((uint16_t)letter_px * opa) >> 8
|
||||
: (uint16_t)((uint16_t)bpp_opa_table[letter_px] * opa) >> 8;
|
||||
}
|
||||
|
||||
if(disp->driver.set_px_cb) {
|
||||
disp->driver.set_px_cb(&disp->driver, (uint8_t *)vdb->buf_act, vdb_width,
|
||||
(col + pos_x) - vdb->area.x1, (row + pos_y) - vdb->area.y1,
|
||||
color, px_opa);
|
||||
(col + pos_x) - vdb->area.x1,
|
||||
(row + pos_y) - vdb->area.y1, color, px_opa);
|
||||
} else {
|
||||
#if LV_COLOR_SCREEN_TRANSP == 0
|
||||
*vdb_buf_tmp = lv_color_mix(color, *vdb_buf_tmp, px_opa);
|
||||
#else
|
||||
*vdb_buf_tmp = color_mix_2_alpha(*vdb_buf_tmp, (*vdb_buf_tmp).alpha, color, px_opa);
|
||||
*vdb_buf_tmp =
|
||||
color_mix_2_alpha(*vdb_buf_tmp, (*vdb_buf_tmp).alpha, color, px_opa);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@ -355,14 +351,14 @@ void lv_draw_letter(const lv_point_t * pos_p, const lv_area_t * mask_p,
|
||||
mask = mask >> bpp;
|
||||
} else {
|
||||
col_bit = 0;
|
||||
col_byte_cnt ++;
|
||||
col_byte_cnt++;
|
||||
mask = mask_init;
|
||||
map_p ++;
|
||||
map_p++;
|
||||
}
|
||||
}
|
||||
|
||||
map_p += (width_byte_bpp) - col_byte_cnt;
|
||||
vdb_buf_tmp += vdb_width - (col_end - col_start); /*Next row in VDB*/
|
||||
map_p += (width_byte_bpp)-col_byte_cnt;
|
||||
vdb_buf_tmp += vdb_width - (col_end - col_start); /*Next row in VDB*/
|
||||
}
|
||||
}
|
||||
|
||||
@ -377,9 +373,9 @@ void lv_draw_letter(const lv_point_t * pos_p, const lv_area_t * mask_p,
|
||||
* @param recolor mix the pixels with this color
|
||||
* @param recolor_opa the intense of recoloring
|
||||
*/
|
||||
void lv_draw_map(const lv_area_t * cords_p, const lv_area_t * mask_p,
|
||||
const uint8_t * map_p, lv_opa_t opa, bool chroma_key, bool alpha_byte,
|
||||
lv_color_t recolor, lv_opa_t recolor_opa)
|
||||
void lv_draw_map(const lv_area_t * cords_p, const lv_area_t * mask_p, const uint8_t * map_p,
|
||||
lv_opa_t opa, bool chroma_key, bool alpha_byte, lv_color_t recolor,
|
||||
lv_opa_t recolor_opa)
|
||||
{
|
||||
|
||||
if(opa < LV_OPA_MIN) return;
|
||||
@ -390,11 +386,11 @@ void lv_draw_map(const lv_area_t * cords_p, const lv_area_t * mask_p,
|
||||
|
||||
/*Get the union of map size and mask*/
|
||||
/* The mask is already truncated to the vdb size
|
||||
* in 'lv_refr_area_with_vdb' function */
|
||||
* in 'lv_refr_area_with_vdb' function */
|
||||
union_ok = lv_area_intersect(&masked_a, cords_p, mask_p);
|
||||
|
||||
/*If there are common part of the three area then draw to the vdb*/
|
||||
if(union_ok == false) return;
|
||||
if(union_ok == false) return;
|
||||
|
||||
/*The pixel size in byte is different if an alpha byte is added too*/
|
||||
uint8_t px_size_byte = alpha_byte ? LV_IMG_PX_SIZE_ALPHA_BYTE : sizeof(lv_color_t);
|
||||
@ -402,13 +398,13 @@ void lv_draw_map(const lv_area_t * cords_p, const lv_area_t * mask_p,
|
||||
/*If the map starts OUT of the masked area then calc. the first pixel*/
|
||||
lv_coord_t map_width = lv_area_get_width(cords_p);
|
||||
if(cords_p->y1 < masked_a.y1) {
|
||||
map_p += (uint32_t) map_width * ((masked_a.y1 - cords_p->y1)) * px_size_byte;
|
||||
map_p += (uint32_t)map_width * ((masked_a.y1 - cords_p->y1)) * px_size_byte;
|
||||
}
|
||||
if(cords_p->x1 < masked_a.x1) {
|
||||
map_p += (masked_a.x1 - cords_p->x1) * px_size_byte;
|
||||
}
|
||||
|
||||
lv_disp_t * disp = lv_refr_get_disp_refreshing();
|
||||
lv_disp_t * disp = lv_refr_get_disp_refreshing();
|
||||
lv_disp_buf_t * vdb = lv_disp_get_buf(disp);
|
||||
|
||||
/*Stores coordinates relative to the current VDB*/
|
||||
@ -417,16 +413,17 @@ void lv_draw_map(const lv_area_t * cords_p, const lv_area_t * mask_p,
|
||||
masked_a.x2 = masked_a.x2 - vdb->area.x1;
|
||||
masked_a.y2 = masked_a.y2 - vdb->area.y1;
|
||||
|
||||
lv_coord_t vdb_width = lv_area_get_width(&vdb->area);
|
||||
lv_coord_t vdb_width = lv_area_get_width(&vdb->area);
|
||||
lv_color_t * vdb_buf_tmp = vdb->buf_act;
|
||||
vdb_buf_tmp += (uint32_t) vdb_width * masked_a.y1; /*Move to the first row*/
|
||||
vdb_buf_tmp += (uint32_t) masked_a.x1; /*Move to the first col*/
|
||||
vdb_buf_tmp += (uint32_t)vdb_width * masked_a.y1; /*Move to the first row*/
|
||||
vdb_buf_tmp += (uint32_t)masked_a.x1; /*Move to the first col*/
|
||||
|
||||
lv_coord_t row;
|
||||
lv_coord_t map_useful_w = lv_area_get_width(&masked_a);
|
||||
|
||||
/*The simplest case just copy the pixels into the VDB*/
|
||||
if(chroma_key == false && alpha_byte == false && opa == LV_OPA_COVER && recolor_opa == LV_OPA_TRANSP) {
|
||||
if(chroma_key == false && alpha_byte == false && opa == LV_OPA_COVER &&
|
||||
recolor_opa == LV_OPA_TRANSP) {
|
||||
|
||||
/*Use the custom VDB write function is exists*/
|
||||
if(disp->driver.set_px_cb) {
|
||||
@ -434,9 +431,10 @@ void lv_draw_map(const lv_area_t * cords_p, const lv_area_t * mask_p,
|
||||
for(row = masked_a.y1; row <= masked_a.y2; row++) {
|
||||
for(col = 0; col < map_useful_w; col++) {
|
||||
lv_color_t px_color = *((lv_color_t *)&map_p[(uint32_t)col * px_size_byte]);
|
||||
disp->driver.set_px_cb(&disp->driver, (uint8_t *)vdb->buf_act, vdb_width, col + masked_a.x1, row, px_color, opa);
|
||||
disp->driver.set_px_cb(&disp->driver, (uint8_t *)vdb->buf_act, vdb_width,
|
||||
col + masked_a.x1, row, px_color, opa);
|
||||
}
|
||||
map_p += map_width * px_size_byte; /*Next row on the map*/
|
||||
map_p += map_width * px_size_byte; /*Next row on the map*/
|
||||
}
|
||||
}
|
||||
/*Normal native VDB*/
|
||||
@ -451,8 +449,8 @@ void lv_draw_map(const lv_area_t * cords_p, const lv_area_t * mask_p,
|
||||
#else
|
||||
sw_mem_blend(vdb_buf_tmp, (lv_color_t *)map_p, map_useful_w, opa);
|
||||
#endif
|
||||
map_p += map_width * px_size_byte; /*Next row on the map*/
|
||||
vdb_buf_tmp += vdb_width; /*Next row on the VDB*/
|
||||
map_p += map_width * px_size_byte; /*Next row on the map*/
|
||||
vdb_buf_tmp += vdb_width; /*Next row on the VDB*/
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -461,12 +459,12 @@ void lv_draw_map(const lv_area_t * cords_p, const lv_area_t * mask_p,
|
||||
else {
|
||||
lv_color_t chroma_key_color = LV_COLOR_TRANSP;
|
||||
lv_coord_t col;
|
||||
lv_color_t last_img_px = LV_COLOR_BLACK;
|
||||
lv_color_t last_img_px = LV_COLOR_BLACK;
|
||||
lv_color_t recolored_px = lv_color_mix(recolor, last_img_px, recolor_opa);
|
||||
for(row = masked_a.y1; row <= masked_a.y2; row++) {
|
||||
for(col = 0; col < map_useful_w; col++) {
|
||||
lv_opa_t opa_result = opa;
|
||||
uint8_t * px_color_p = (uint8_t *) &map_p[(uint32_t)col * px_size_byte];
|
||||
lv_opa_t opa_result = opa;
|
||||
uint8_t * px_color_p = (uint8_t *)&map_p[(uint32_t)col * px_size_byte];
|
||||
lv_color_t px_color;
|
||||
|
||||
/*Calculate with the pixel level alpha*/
|
||||
@ -474,14 +472,17 @@ void lv_draw_map(const lv_area_t * cords_p, const lv_area_t * mask_p,
|
||||
#if LV_COLOR_DEPTH == 8 || LV_COLOR_DEPTH == 1
|
||||
px_color.full = px_color_p[0];
|
||||
#elif LV_COLOR_DEPTH == 16
|
||||
/*Because of Alpha byte 16 bit color can start on odd address which can cause crash*/
|
||||
/*Because of Alpha byte 16 bit color can start on odd address which can cause
|
||||
* crash*/
|
||||
px_color.full = px_color_p[0] + (px_color_p[1] << 8);
|
||||
#elif LV_COLOR_DEPTH == 32
|
||||
px_color = *((lv_color_t *)px_color_p);
|
||||
#endif
|
||||
lv_opa_t px_opa = *(px_color_p + LV_IMG_PX_SIZE_ALPHA_BYTE - 1);
|
||||
if(px_opa == LV_OPA_TRANSP) continue;
|
||||
else if(px_opa != LV_OPA_COVER) opa_result = (uint32_t)((uint32_t)px_opa * opa_result) >> 8;
|
||||
if(px_opa == LV_OPA_TRANSP)
|
||||
continue;
|
||||
else if(px_opa != LV_OPA_COVER)
|
||||
opa_result = (uint32_t)((uint32_t)px_opa * opa_result) >> 8;
|
||||
} else {
|
||||
px_color = *((lv_color_t *)px_color_p);
|
||||
}
|
||||
@ -491,40 +492,48 @@ void lv_draw_map(const lv_area_t * cords_p, const lv_area_t * mask_p,
|
||||
|
||||
/*Re-color the pixel if required*/
|
||||
if(recolor_opa != LV_OPA_TRANSP) {
|
||||
if(last_img_px.full != px_color.full) { /*Minor acceleration: calculate only for new colors (save the last)*/
|
||||
last_img_px = px_color;
|
||||
if(last_img_px.full != px_color.full) { /*Minor acceleration: calculate only for
|
||||
new colors (save the last)*/
|
||||
last_img_px = px_color;
|
||||
recolored_px = lv_color_mix(recolor, last_img_px, recolor_opa);
|
||||
}
|
||||
/*Handle custom VDB write is present*/
|
||||
if(disp->driver.set_px_cb) {
|
||||
disp->driver.set_px_cb(&disp->driver, (uint8_t *)vdb->buf_act, vdb_width, col + masked_a.x1, row, recolored_px, opa_result);
|
||||
disp->driver.set_px_cb(&disp->driver, (uint8_t *)vdb->buf_act, vdb_width,
|
||||
col + masked_a.x1, row, recolored_px, opa_result);
|
||||
}
|
||||
/*Normal native VDB write*/
|
||||
else {
|
||||
if(opa_result == LV_OPA_COVER) vdb_buf_tmp[col].full = recolored_px.full;
|
||||
else vdb_buf_tmp[col] = lv_color_mix(recolored_px, vdb_buf_tmp[col], opa_result);
|
||||
if(opa_result == LV_OPA_COVER)
|
||||
vdb_buf_tmp[col].full = recolored_px.full;
|
||||
else
|
||||
vdb_buf_tmp[col] =
|
||||
lv_color_mix(recolored_px, vdb_buf_tmp[col], opa_result);
|
||||
}
|
||||
} else {
|
||||
/*Handle custom VDB write is present*/
|
||||
if(disp->driver.set_px_cb) {
|
||||
disp->driver.set_px_cb(&disp->driver, (uint8_t *)vdb->buf_act, vdb_width, col + masked_a.x1, row, px_color, opa_result);
|
||||
disp->driver.set_px_cb(&disp->driver, (uint8_t *)vdb->buf_act, vdb_width,
|
||||
col + masked_a.x1, row, px_color, opa_result);
|
||||
}
|
||||
/*Normal native VDB write*/
|
||||
else {
|
||||
if(opa_result == LV_OPA_COVER) vdb_buf_tmp[col] = px_color;
|
||||
if(opa_result == LV_OPA_COVER)
|
||||
vdb_buf_tmp[col] = px_color;
|
||||
else {
|
||||
#if LV_COLOR_SCREEN_TRANSP == 0
|
||||
vdb_buf_tmp[col] = lv_color_mix(px_color, vdb_buf_tmp[col], opa_result);
|
||||
#else
|
||||
vdb_buf_tmp[col] = color_mix_2_alpha(vdb_buf_tmp[col], vdb_buf_tmp[col].alpha, px_color, opa_result);
|
||||
vdb_buf_tmp[col] = color_mix_2_alpha(
|
||||
vdb_buf_tmp[col], vdb_buf_tmp[col].alpha, px_color, opa_result);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
map_p += map_width * px_size_byte; /*Next row on the map*/
|
||||
vdb_buf_tmp += vdb_width; /*Next row on the VDB*/
|
||||
map_p += map_width * px_size_byte; /*Next row on the map*/
|
||||
vdb_buf_tmp += vdb_width; /*Next row on the VDB*/
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -560,7 +569,8 @@ static void sw_mem_blend(lv_color_t * dest, const lv_color_t * src, uint32_t len
|
||||
* @param color fill color
|
||||
* @param opa opacity (0, LV_OPA_TRANSP: transparent ... 255, LV_OPA_COVER, fully cover)
|
||||
*/
|
||||
static void sw_color_fill(lv_area_t * mem_area, lv_color_t * mem, const lv_area_t * fill_area, lv_color_t color, lv_opa_t opa)
|
||||
static void sw_color_fill(lv_area_t * mem_area, lv_color_t * mem, const lv_area_t * fill_area,
|
||||
lv_color_t color, lv_opa_t opa)
|
||||
{
|
||||
/*Set all row in vdb to the given color*/
|
||||
lv_coord_t row;
|
||||
@ -571,11 +581,12 @@ static void sw_color_fill(lv_area_t * mem_area, lv_color_t * mem, const lv_area_
|
||||
if(disp->driver.set_px_cb) {
|
||||
for(col = fill_area->x1; col <= fill_area->x2; col++) {
|
||||
for(row = fill_area->y1; row <= fill_area->y2; row++) {
|
||||
disp->driver.set_px_cb(&disp->driver, (uint8_t *)mem, mem_width, col, row, color, opa);
|
||||
disp->driver.set_px_cb(&disp->driver, (uint8_t *)mem, mem_width, col, row, color,
|
||||
opa);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
mem += fill_area->y1 * mem_width; /*Go to the first row*/
|
||||
mem += fill_area->y1 * mem_width; /*Go to the first row*/
|
||||
|
||||
/*Run simpler function without opacity*/
|
||||
if(opa == LV_OPA_COVER) {
|
||||
@ -587,7 +598,7 @@ static void sw_color_fill(lv_area_t * mem_area, lv_color_t * mem, const lv_area_
|
||||
|
||||
/*Copy the first row to all other rows*/
|
||||
lv_color_t * mem_first = &mem[fill_area->x1];
|
||||
lv_coord_t copy_size = (fill_area->x2 - fill_area->x1 + 1) * sizeof(lv_color_t);
|
||||
lv_coord_t copy_size = (fill_area->x2 - fill_area->x1 + 1) * sizeof(lv_color_t);
|
||||
mem += mem_width;
|
||||
|
||||
for(row = fill_area->y1 + 1; row <= fill_area->y2; row++) {
|
||||
@ -599,7 +610,7 @@ static void sw_color_fill(lv_area_t * mem_area, lv_color_t * mem, const lv_area_
|
||||
else {
|
||||
|
||||
#if LV_COLOR_SCREEN_TRANSP == 0
|
||||
lv_color_t bg_tmp = LV_COLOR_BLACK;
|
||||
lv_color_t bg_tmp = LV_COLOR_BLACK;
|
||||
lv_color_t opa_tmp = lv_color_mix(color, bg_tmp, opa);
|
||||
#endif
|
||||
for(row = fill_area->y1; row <= fill_area->y2; row++) {
|
||||
@ -607,7 +618,7 @@ static void sw_color_fill(lv_area_t * mem_area, lv_color_t * mem, const lv_area_
|
||||
#if LV_COLOR_SCREEN_TRANSP == 0
|
||||
/*If the bg color changed recalculate the result color*/
|
||||
if(mem[col].full != bg_tmp.full) {
|
||||
bg_tmp = mem[col];
|
||||
bg_tmp = mem[col];
|
||||
opa_tmp = lv_color_mix(color, bg_tmp, opa);
|
||||
}
|
||||
|
||||
@ -633,7 +644,8 @@ static void sw_color_fill(lv_area_t * mem_area, lv_color_t * mem, const lv_area_
|
||||
* @param fg_opa alpha of the foreground color
|
||||
* @return the mixed color. the alpha channel (color.alpha) contains the result alpha
|
||||
*/
|
||||
static inline lv_color_t color_mix_2_alpha(lv_color_t bg_color, lv_opa_t bg_opa, lv_color_t fg_color, lv_opa_t fg_opa)
|
||||
static inline lv_color_t color_mix_2_alpha(lv_color_t bg_color, lv_opa_t bg_opa,
|
||||
lv_color_t fg_color, lv_opa_t fg_opa)
|
||||
{
|
||||
/* Pick the foreground if it's fully opaque or the Background is fully transparent*/
|
||||
if(fg_opa == LV_OPA_COVER || bg_opa <= LV_OPA_MIN) {
|
||||
@ -651,32 +663,31 @@ static inline lv_color_t color_mix_2_alpha(lv_color_t bg_color, lv_opa_t bg_opa,
|
||||
/*Both colors have alpha. Expensive calculation need to be applied*/
|
||||
else {
|
||||
/*Save the parameters and the result. If they will be asked again don't compute again*/
|
||||
static lv_opa_t fg_opa_save = 0;
|
||||
static lv_opa_t bg_opa_save = 0;
|
||||
static lv_opa_t fg_opa_save = 0;
|
||||
static lv_opa_t bg_opa_save = 0;
|
||||
static lv_color_t fg_color_save = {{0}};
|
||||
static lv_color_t bg_color_save = {{0}};
|
||||
static lv_color_t c = {{0}};
|
||||
static lv_color_t c = {{0}};
|
||||
|
||||
if(fg_opa != fg_opa_save || bg_opa != bg_opa_save ||
|
||||
fg_color.full != fg_color_save.full || bg_color.full != bg_color_save.full)
|
||||
{
|
||||
fg_opa_save = fg_opa;
|
||||
bg_opa_save = bg_opa;
|
||||
if(fg_opa != fg_opa_save || bg_opa != bg_opa_save || fg_color.full != fg_color_save.full ||
|
||||
bg_color.full != bg_color_save.full) {
|
||||
fg_opa_save = fg_opa;
|
||||
bg_opa_save = bg_opa;
|
||||
fg_color.full = fg_color_save.full;
|
||||
bg_color.full = bg_color_save.full;
|
||||
/*Info: https://en.wikipedia.org/wiki/Alpha_compositing#Analytical_derivation_of_the_over_operator*/
|
||||
/*Info:
|
||||
* https://en.wikipedia.org/wiki/Alpha_compositing#Analytical_derivation_of_the_over_operator*/
|
||||
lv_opa_t alpha_res = 255 - ((uint16_t)((uint16_t)(255 - fg_opa) * (255 - bg_opa)) >> 8);
|
||||
if(alpha_res == 0) {
|
||||
while(1);
|
||||
while(1)
|
||||
;
|
||||
}
|
||||
lv_opa_t ratio = (uint16_t)((uint16_t) fg_opa * 255) / alpha_res;
|
||||
c = lv_color_mix(fg_color, bg_color, ratio);
|
||||
c.ch.alpha = alpha_res;
|
||||
lv_opa_t ratio = (uint16_t)((uint16_t)fg_opa * 255) / alpha_res;
|
||||
c = lv_color_mix(fg_color, bg_color, ratio);
|
||||
c.ch.alpha = alpha_res;
|
||||
}
|
||||
return c;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif /*LV_COLOR_SCREEN_TRANSP*/
|
||||
|
||||
|
@ -35,7 +35,8 @@ extern "C" {
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
void lv_draw_px(lv_coord_t x, lv_coord_t y, const lv_area_t * mask_p, lv_color_t color, lv_opa_t opa);
|
||||
void lv_draw_px(lv_coord_t x, lv_coord_t y, const lv_area_t * mask_p, lv_color_t color,
|
||||
lv_opa_t opa);
|
||||
/**
|
||||
* Fill an area in the Virtual Display Buffer
|
||||
* @param cords_p coordinates of the area to fill
|
||||
@ -43,8 +44,8 @@ void lv_draw_px(lv_coord_t x, lv_coord_t y, const lv_area_t * mask_p, lv_color_t
|
||||
* @param color fill color
|
||||
* @param opa opacity of the area (0..255)
|
||||
*/
|
||||
void lv_draw_fill(const lv_area_t * cords_p, const lv_area_t * mask_p,
|
||||
lv_color_t color, lv_opa_t opa);
|
||||
void lv_draw_fill(const lv_area_t * cords_p, const lv_area_t * mask_p, lv_color_t color,
|
||||
lv_opa_t opa);
|
||||
|
||||
/**
|
||||
* Draw a letter in the Virtual Display Buffer
|
||||
@ -55,9 +56,8 @@ void lv_draw_fill(const lv_area_t * cords_p, const lv_area_t * mask_p,
|
||||
* @param color color of letter
|
||||
* @param opa opacity of letter (0..255)
|
||||
*/
|
||||
void lv_draw_letter(const lv_point_t * pos_p, const lv_area_t * mask_p,
|
||||
const lv_font_t * font_p, uint32_t letter,
|
||||
lv_color_t color, lv_opa_t opa);
|
||||
void lv_draw_letter(const lv_point_t * pos_p, const lv_area_t * mask_p, const lv_font_t * font_p,
|
||||
uint32_t letter, lv_color_t color, lv_opa_t opa);
|
||||
|
||||
/**
|
||||
* Draw a color map to the display (image)
|
||||
@ -70,9 +70,9 @@ void lv_draw_letter(const lv_point_t * pos_p, const lv_area_t * mask_p,
|
||||
* @param recolor mix the pixels with this color
|
||||
* @param recolor_opa the intense of recoloring
|
||||
*/
|
||||
void lv_draw_map(const lv_area_t * cords_p, const lv_area_t * mask_p,
|
||||
const uint8_t * map_p, lv_opa_t opa, bool chroma_key, bool alpha_byte,
|
||||
lv_color_t recolor, lv_opa_t recolor_opa);
|
||||
void lv_draw_map(const lv_area_t * cords_p, const lv_area_t * mask_p, const uint8_t * map_p,
|
||||
lv_opa_t opa, bool chroma_key, bool alpha_byte, lv_color_t recolor,
|
||||
lv_opa_t recolor_opa);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
@ -82,4 +82,4 @@ void lv_draw_map(const lv_area_t * cords_p, const lv_area_t * mask_p,
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_DRAW_BASIC_H*/
|
||||
#endif /*LV_DRAW_BASIC_H*/
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -19,47 +19,52 @@ extern "C" {
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define LV_IMG_DECODER_OPEN_FAIL ((void*)(-1))
|
||||
#define LV_IMG_DECODER_OPEN_FAIL ((void *)(-1))
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
struct _lv_img_t;
|
||||
|
||||
typedef struct {
|
||||
typedef struct
|
||||
{
|
||||
|
||||
/* The first 8 bit is very important to distinguish the different source types.
|
||||
* For more info see `lv_img_get_src_type()` in lv_img.c */
|
||||
uint32_t cf :5; /* Color format: See `lv_img_color_format_t`*/
|
||||
uint32_t always_zero :3; /*It the upper bits of the first byte. Always zero to look like a non-printable character*/
|
||||
uint32_t cf : 5; /* Color format: See `lv_img_color_format_t`*/
|
||||
uint32_t always_zero : 3; /*It the upper bits of the first byte. Always zero to look like a
|
||||
non-printable character*/
|
||||
|
||||
uint32_t reserved :2; /*Reserved to be used later*/
|
||||
uint32_t reserved : 2; /*Reserved to be used later*/
|
||||
|
||||
uint32_t w:11; /*Width of the image map*/
|
||||
uint32_t h:11; /*Height of the image map*/
|
||||
uint32_t w : 11; /*Width of the image map*/
|
||||
uint32_t h : 11; /*Height of the image map*/
|
||||
} lv_img_header_t;
|
||||
|
||||
/*Image color format*/
|
||||
enum {
|
||||
LV_IMG_CF_UNKNOWN = 0,
|
||||
|
||||
LV_IMG_CF_RAW, /*Contains the file as it is. Needs custom decoder function*/
|
||||
LV_IMG_CF_RAW_ALPHA, /*Contains the file as it is. The image has alpha. Needs custom decoder function*/
|
||||
LV_IMG_CF_RAW_CHROMA_KEYED, /*Contains the file as it is. The image is chroma keyed. Needs custom decoder function*/
|
||||
LV_IMG_CF_RAW, /*Contains the file as it is. Needs custom decoder function*/
|
||||
LV_IMG_CF_RAW_ALPHA, /*Contains the file as it is. The image has alpha. Needs custom decoder
|
||||
function*/
|
||||
LV_IMG_CF_RAW_CHROMA_KEYED, /*Contains the file as it is. The image is chroma keyed. Needs
|
||||
custom decoder function*/
|
||||
|
||||
LV_IMG_CF_TRUE_COLOR, /*Color format and depth should match with LV_COLOR settings*/
|
||||
LV_IMG_CF_TRUE_COLOR_ALPHA, /*Same as `LV_IMG_CF_TRUE_COLOR` but every pixel has an alpha byte*/
|
||||
LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED, /*Same as `LV_IMG_CF_TRUE_COLOR` but LV_COLOR_TRANSP pixels will be transparent*/
|
||||
LV_IMG_CF_TRUE_COLOR, /*Color format and depth should match with LV_COLOR settings*/
|
||||
LV_IMG_CF_TRUE_COLOR_ALPHA, /*Same as `LV_IMG_CF_TRUE_COLOR` but every pixel has an alpha byte*/
|
||||
LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED, /*Same as `LV_IMG_CF_TRUE_COLOR` but LV_COLOR_TRANSP pixels
|
||||
will be transparent*/
|
||||
|
||||
LV_IMG_CF_INDEXED_1BIT, /*Can have 2 different colors in a palette (always chroma keyed)*/
|
||||
LV_IMG_CF_INDEXED_2BIT, /*Can have 4 different colors in a palette (always chroma keyed)*/
|
||||
LV_IMG_CF_INDEXED_4BIT, /*Can have 16 different colors in a palette (always chroma keyed)*/
|
||||
LV_IMG_CF_INDEXED_8BIT, /*Can have 256 different colors in a palette (always chroma keyed)*/
|
||||
LV_IMG_CF_INDEXED_1BIT, /*Can have 2 different colors in a palette (always chroma keyed)*/
|
||||
LV_IMG_CF_INDEXED_2BIT, /*Can have 4 different colors in a palette (always chroma keyed)*/
|
||||
LV_IMG_CF_INDEXED_4BIT, /*Can have 16 different colors in a palette (always chroma keyed)*/
|
||||
LV_IMG_CF_INDEXED_8BIT, /*Can have 256 different colors in a palette (always chroma keyed)*/
|
||||
|
||||
LV_IMG_CF_ALPHA_1BIT, /*Can have one color and it can be drawn or not*/
|
||||
LV_IMG_CF_ALPHA_2BIT, /*Can have one color but 4 different alpha value*/
|
||||
LV_IMG_CF_ALPHA_4BIT, /*Can have one color but 16 different alpha value*/
|
||||
LV_IMG_CF_ALPHA_8BIT, /*Can have one color but 256 different alpha value*/
|
||||
LV_IMG_CF_ALPHA_1BIT, /*Can have one color and it can be drawn or not*/
|
||||
LV_IMG_CF_ALPHA_2BIT, /*Can have one color but 4 different alpha value*/
|
||||
LV_IMG_CF_ALPHA_4BIT, /*Can have one color but 16 different alpha value*/
|
||||
LV_IMG_CF_ALPHA_8BIT, /*Can have one color but 256 different alpha value*/
|
||||
};
|
||||
typedef uint8_t lv_img_cf_t;
|
||||
|
||||
@ -74,10 +79,10 @@ typedef struct
|
||||
|
||||
/* Decoder function definitions */
|
||||
|
||||
|
||||
/**
|
||||
* Get info from an image and store in the `header`
|
||||
* @param src the image source. Can be a pointer to a C array or a file name (Use `lv_img_src_get_type` to determine the type)
|
||||
* @param src the image source. Can be a pointer to a C array or a file name (Use
|
||||
* `lv_img_src_get_type` to determine the type)
|
||||
* @param header store the info here
|
||||
* @return LV_RES_OK: info written correctly; LV_RES_INV: failed
|
||||
*/
|
||||
@ -85,12 +90,14 @@ typedef lv_res_t (*lv_img_decoder_info_f_t)(const void * src, lv_img_header_t *
|
||||
|
||||
/**
|
||||
* Open an image for decoding. Prepare it as it is required to read it later
|
||||
* @param src the image source. Can be a pointer to a C array or a file name (Use `lv_img_src_get_type` to determine the type)
|
||||
* @param src the image source. Can be a pointer to a C array or a file name (Use
|
||||
* `lv_img_src_get_type` to determine the type)
|
||||
* @param style the style of image (maybe it will be required to determine a color or something)
|
||||
* @return there are 3 possible return values:
|
||||
* 1) buffer with the decoded image
|
||||
* 2) if can decode the whole image NULL. decoder_read_line will be called to read the image line-by-line
|
||||
* 3) LV_IMG_DECODER_OPEN_FAIL if the image format is unknown to the decoder or an error occurred
|
||||
* 2) if can decode the whole image NULL. decoder_read_line will be called to read the image
|
||||
* line-by-line 3) LV_IMG_DECODER_OPEN_FAIL if the image format is unknown to the decoder or an
|
||||
* error occurred
|
||||
*/
|
||||
typedef const uint8_t * (*lv_img_decoder_open_f_t)(const void * src, const lv_style_t * style);
|
||||
|
||||
@ -103,7 +110,8 @@ typedef const uint8_t * (*lv_img_decoder_open_f_t)(const void * src, const lv_st
|
||||
* @param buf a buffer to store the decoded pixels
|
||||
* @return LV_RES_OK: ok; LV_RES_INV: failed
|
||||
*/
|
||||
typedef lv_res_t (*lv_img_decoder_read_line_f_t)(lv_coord_t x, lv_coord_t y, lv_coord_t len, uint8_t * buf);
|
||||
typedef lv_res_t (*lv_img_decoder_read_line_f_t)(lv_coord_t x, lv_coord_t y, lv_coord_t len,
|
||||
uint8_t * buf);
|
||||
|
||||
/**
|
||||
* Close the pending decoding. Free resources etc.
|
||||
@ -122,9 +130,8 @@ typedef void (*lv_img_decoder_close_f_t)(void);
|
||||
* @param style style of the image
|
||||
* @param opa_scale scale down all opacities by the factor
|
||||
*/
|
||||
void lv_draw_img(const lv_area_t * coords, const lv_area_t * mask,
|
||||
const void * src, const lv_style_t * style, lv_opa_t opa_scale);
|
||||
|
||||
void lv_draw_img(const lv_area_t * coords, const lv_area_t * mask, const void * src,
|
||||
const lv_style_t * style, lv_opa_t opa_scale);
|
||||
|
||||
/**
|
||||
* Initialize and `lv_img_dsc_t` variable with the image's info
|
||||
@ -145,25 +152,29 @@ lv_res_t lv_img_dsc_get_info(const char * src, lv_img_header_t * header);
|
||||
lv_img_src_t lv_img_src_get_type(const void * src);
|
||||
|
||||
/**
|
||||
* Set custom decoder functions. See the typdefs of the function typed above for more info about them
|
||||
* Set custom decoder functions. See the typdefs of the function typed above for more info about
|
||||
* them
|
||||
* @param info_fp info get function
|
||||
* @param open_fp open function
|
||||
* @param read_fp read line function
|
||||
* @param close_fp clode function
|
||||
*/
|
||||
void lv_img_decoder_set_custom(lv_img_decoder_info_f_t info_fp, lv_img_decoder_open_f_t open_fp,
|
||||
lv_img_decoder_read_line_f_t read_fp, lv_img_decoder_close_f_t close_fp);
|
||||
void lv_img_decoder_set_custom(lv_img_decoder_info_f_t info_fp, lv_img_decoder_open_f_t open_fp,
|
||||
lv_img_decoder_read_line_f_t read_fp,
|
||||
lv_img_decoder_close_f_t close_fp);
|
||||
|
||||
/**
|
||||
* Get the color of an image's pixel
|
||||
* @param dsc an image descriptor
|
||||
* @param x x coordinate of the point to get
|
||||
* @param y x coordinate of the point to get
|
||||
* @param style style of the image. In case of `LV_IMG_CF_ALPHA_1/2/4/8` `style->image.color` shows the color.
|
||||
* Can be `NULL` but for `ALPHA` images black will be returned. In other cases it is not used.
|
||||
* @param style style of the image. In case of `LV_IMG_CF_ALPHA_1/2/4/8` `style->image.color` shows
|
||||
* the color. Can be `NULL` but for `ALPHA` images black will be returned. In other cases it is not
|
||||
* used.
|
||||
* @return color of the point
|
||||
*/
|
||||
lv_color_t lv_img_buf_get_px_color(lv_img_dsc_t *dsc, lv_coord_t x, lv_coord_t y, lv_style_t * style);
|
||||
lv_color_t lv_img_buf_get_px_color(lv_img_dsc_t * dsc, lv_coord_t x, lv_coord_t y,
|
||||
lv_style_t * style);
|
||||
/**
|
||||
* Get the alpha value of an image's pixel
|
||||
* @param dsc pointer to an image descriptor
|
||||
@ -171,7 +182,7 @@ lv_color_t lv_img_buf_get_px_color(lv_img_dsc_t *dsc, lv_coord_t x, lv_coord_t y
|
||||
* @param y x coordinate of the point to set
|
||||
* @return alpha value of the point
|
||||
*/
|
||||
lv_opa_t lv_img_buf_get_px_alpha(lv_img_dsc_t *dsc, lv_coord_t x, lv_coord_t y);
|
||||
lv_opa_t lv_img_buf_get_px_alpha(lv_img_dsc_t * dsc, lv_coord_t x, lv_coord_t y);
|
||||
|
||||
/**
|
||||
* Set the color of a pixel of an image. The alpha channel won't be affected.
|
||||
@ -180,7 +191,7 @@ lv_opa_t lv_img_buf_get_px_alpha(lv_img_dsc_t *dsc, lv_coord_t x, lv_coord_t y);
|
||||
* @param y x coordinate of the point to set
|
||||
* @param c color of the point
|
||||
*/
|
||||
void lv_img_buf_set_px_color(lv_img_dsc_t *dsc, lv_coord_t x, lv_coord_t y, lv_color_t c);
|
||||
void lv_img_buf_set_px_color(lv_img_dsc_t * dsc, lv_coord_t x, lv_coord_t y, lv_color_t c);
|
||||
|
||||
/**
|
||||
* Set the alpha value of a pixel of an image. The color won't be affected
|
||||
@ -189,7 +200,7 @@ void lv_img_buf_set_px_color(lv_img_dsc_t *dsc, lv_coord_t x, lv_coord_t y, lv_c
|
||||
* @param y x coordinate of the point to set
|
||||
* @param opa the desired opacity
|
||||
*/
|
||||
void lv_img_buf_set_px_alpha(lv_img_dsc_t *dsc, lv_coord_t x, lv_coord_t y, lv_opa_t opa);
|
||||
void lv_img_buf_set_px_alpha(lv_img_dsc_t * dsc, lv_coord_t x, lv_coord_t y, lv_opa_t opa);
|
||||
|
||||
/**
|
||||
* Set the palette color of an indexed image. Valid only for `LV_IMG_CF_INDEXED1/2/4/8`
|
||||
@ -201,7 +212,7 @@ void lv_img_buf_set_px_alpha(lv_img_dsc_t *dsc, lv_coord_t x, lv_coord_t y, lv_o
|
||||
* - for `LV_IMG_CF_INDEXED8`: 0..255
|
||||
* @param color the color to set
|
||||
*/
|
||||
void lv_img_buf_set_palette(lv_img_dsc_t *dsc, int color_id, lv_color_t color);
|
||||
void lv_img_buf_set_palette(lv_img_dsc_t * dsc, int color_id, lv_color_t color);
|
||||
|
||||
/**
|
||||
* Get the pixel size of a color format in bits
|
||||
@ -228,7 +239,6 @@ bool lv_img_color_format_has_alpha(lv_img_cf_t cf);
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
@ -12,7 +12,7 @@
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define LABEL_RECOLOR_PAR_LENGTH 6
|
||||
#define LABEL_RECOLOR_PAR_LENGTH 6
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
@ -33,7 +33,6 @@ static uint8_t hex_char_to_num(char hex);
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
@ -54,8 +53,9 @@ static uint8_t hex_char_to_num(char hex);
|
||||
* @param sel_start start index of selected area (-1 if none)
|
||||
* @param sel_end end index of selected area (-1 if none)
|
||||
*/
|
||||
void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_style_t * style, lv_opa_t opa_scale,
|
||||
const char * txt, lv_txt_flag_t flag, lv_point_t * offset, int sel_start, int sel_end)
|
||||
void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_style_t * style,
|
||||
lv_opa_t opa_scale, const char * txt, lv_txt_flag_t flag, lv_point_t * offset,
|
||||
int sel_start, int sel_end)
|
||||
{
|
||||
const lv_font_t * font = style->text.font;
|
||||
lv_coord_t w;
|
||||
@ -65,13 +65,13 @@ void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_st
|
||||
} else {
|
||||
/*If EXAPND is enabled then not limit the text's width to the object's width*/
|
||||
lv_point_t p;
|
||||
lv_txt_get_size(&p, txt, style->text.font, style->text.letter_space, style->text.line_space, LV_COORD_MAX, flag);
|
||||
lv_txt_get_size(&p, txt, style->text.font, style->text.letter_space, style->text.line_space,
|
||||
LV_COORD_MAX, flag);
|
||||
w = p.x;
|
||||
}
|
||||
|
||||
lv_coord_t line_height = lv_font_get_height(font) + style->text.line_space;
|
||||
|
||||
|
||||
/*Init variables for the first line*/
|
||||
lv_coord_t line_width = 0;
|
||||
lv_point_t pos;
|
||||
@ -87,7 +87,7 @@ void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_st
|
||||
}
|
||||
|
||||
uint32_t line_start = 0;
|
||||
uint32_t line_end = lv_txt_get_next_line(txt, font, style->text.letter_space, w, flag);
|
||||
uint32_t line_end = lv_txt_get_next_line(txt, font, style->text.letter_space, w, flag);
|
||||
|
||||
/*Go the first visible line*/
|
||||
while(pos.y + line_height < mask->y1) {
|
||||
@ -101,21 +101,22 @@ void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_st
|
||||
|
||||
/*Align to middle*/
|
||||
if(flag & LV_TXT_FLAG_CENTER) {
|
||||
line_width = lv_txt_get_width(&txt[line_start], line_end - line_start,
|
||||
font, style->text.letter_space, flag);
|
||||
line_width = lv_txt_get_width(&txt[line_start], line_end - line_start, font,
|
||||
style->text.letter_space, flag);
|
||||
|
||||
pos.x += (lv_area_get_width(coords) - line_width) / 2;
|
||||
|
||||
}
|
||||
/*Align to the right*/
|
||||
else if(flag & LV_TXT_FLAG_RIGHT) {
|
||||
line_width = lv_txt_get_width(&txt[line_start], line_end - line_start,
|
||||
font, style->text.letter_space, flag);
|
||||
line_width = lv_txt_get_width(&txt[line_start], line_end - line_start, font,
|
||||
style->text.letter_space, flag);
|
||||
pos.x += lv_area_get_width(coords) - line_width;
|
||||
}
|
||||
|
||||
|
||||
lv_opa_t opa = opa_scale == LV_OPA_COVER ? style->text.opa : (uint16_t)((uint16_t) style->text.opa * opa_scale) >> 8;
|
||||
lv_opa_t opa = opa_scale == LV_OPA_COVER
|
||||
? style->text.opa
|
||||
: (uint16_t)((uint16_t)style->text.opa * opa_scale) >> 8;
|
||||
|
||||
cmd_state_t cmd_state = CMD_STATE_WAIT;
|
||||
uint32_t i;
|
||||
@ -133,7 +134,7 @@ void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_st
|
||||
}
|
||||
/*Write all letter of a line*/
|
||||
cmd_state = CMD_STATE_WAIT;
|
||||
i = line_start;
|
||||
i = line_start;
|
||||
uint32_t letter;
|
||||
while(i < line_end) {
|
||||
letter = lv_txt_encoded_next(txt, &i);
|
||||
@ -145,7 +146,8 @@ void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_st
|
||||
par_start = i;
|
||||
cmd_state = CMD_STATE_PAR;
|
||||
continue;
|
||||
} else if(cmd_state == CMD_STATE_PAR) { /*Other start char in parameter escaped cmd. char */
|
||||
} else if(cmd_state ==
|
||||
CMD_STATE_PAR) { /*Other start char in parameter escaped cmd. char */
|
||||
cmd_state = CMD_STATE_WAIT;
|
||||
} else if(cmd_state == CMD_STATE_IN) { /*Command end */
|
||||
cmd_state = CMD_STATE_WAIT;
|
||||
@ -162,9 +164,9 @@ void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_st
|
||||
memcpy(buf, &txt[par_start], LABEL_RECOLOR_PAR_LENGTH);
|
||||
buf[LABEL_RECOLOR_PAR_LENGTH] = '\0';
|
||||
int r, g, b;
|
||||
r = (hex_char_to_num(buf[0]) << 4) + hex_char_to_num(buf[1]);
|
||||
g = (hex_char_to_num(buf[2]) << 4) + hex_char_to_num(buf[3]);
|
||||
b = (hex_char_to_num(buf[4]) << 4) + hex_char_to_num(buf[5]);
|
||||
r = (hex_char_to_num(buf[0]) << 4) + hex_char_to_num(buf[1]);
|
||||
g = (hex_char_to_num(buf[2]) << 4) + hex_char_to_num(buf[3]);
|
||||
b = (hex_char_to_num(buf[4]) << 4) + hex_char_to_num(buf[5]);
|
||||
recolor = lv_color_make(r, g, b);
|
||||
} else {
|
||||
recolor.full = style->text.color.full;
|
||||
@ -182,21 +184,20 @@ void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_st
|
||||
letter_w = lv_font_get_width(font, letter);
|
||||
|
||||
if(sel_start != -1 && sel_end != -1) {
|
||||
int char_ind = lv_encoded_get_char_id(txt, i);
|
||||
/*Do not draw the rectangle on the character at `sel_start`.*/
|
||||
if(char_ind > sel_start && char_ind <= sel_end) {
|
||||
lv_area_t sel_coords;
|
||||
sel_coords.x1 = pos.x;
|
||||
sel_coords.y1 = pos.y;
|
||||
sel_coords.x2 = pos.x + letter_w + style->text.letter_space - 1;
|
||||
sel_coords.y2 = pos.y + line_height - 1;
|
||||
lv_draw_rect(&sel_coords, mask, &sel_style, opa);
|
||||
}
|
||||
int char_ind = lv_encoded_get_char_id(txt, i);
|
||||
/*Do not draw the rectangle on the character at `sel_start`.*/
|
||||
if(char_ind > sel_start && char_ind <= sel_end) {
|
||||
lv_area_t sel_coords;
|
||||
sel_coords.x1 = pos.x;
|
||||
sel_coords.y1 = pos.y;
|
||||
sel_coords.x2 = pos.x + letter_w + style->text.letter_space - 1;
|
||||
sel_coords.y2 = pos.y + line_height - 1;
|
||||
lv_draw_rect(&sel_coords, mask, &sel_style, opa);
|
||||
}
|
||||
}
|
||||
lv_draw_letter(&pos, mask, font, letter, color, opa);
|
||||
|
||||
|
||||
if(letter_w > 0){
|
||||
if(letter_w > 0) {
|
||||
pos.x += letter_w + style->text.letter_space;
|
||||
}
|
||||
}
|
||||
@ -207,16 +208,16 @@ void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_st
|
||||
pos.x = coords->x1;
|
||||
/*Align to middle*/
|
||||
if(flag & LV_TXT_FLAG_CENTER) {
|
||||
line_width = lv_txt_get_width(&txt[line_start], line_end - line_start,
|
||||
font, style->text.letter_space, flag);
|
||||
line_width = lv_txt_get_width(&txt[line_start], line_end - line_start, font,
|
||||
style->text.letter_space, flag);
|
||||
|
||||
pos.x += (lv_area_get_width(coords) - line_width) / 2;
|
||||
|
||||
}
|
||||
/*Align to the right*/
|
||||
else if(flag & LV_TXT_FLAG_RIGHT) {
|
||||
line_width = lv_txt_get_width(&txt[line_start], line_end - line_start,
|
||||
font, style->text.letter_space, flag);
|
||||
line_width = lv_txt_get_width(&txt[line_start], line_end - line_start, font,
|
||||
style->text.letter_space, flag);
|
||||
pos.x += lv_area_get_width(coords) - line_width;
|
||||
}
|
||||
|
||||
@ -242,32 +243,17 @@ static uint8_t hex_char_to_num(char hex)
|
||||
|
||||
if(hex >= '0' && hex <= '9') {
|
||||
result = hex - '0';
|
||||
}
|
||||
else {
|
||||
if(hex >= 'a') hex -= 'a' - 'A'; /*Convert to upper case*/
|
||||
} else {
|
||||
if(hex >= 'a') hex -= 'a' - 'A'; /*Convert to upper case*/
|
||||
|
||||
switch(hex) {
|
||||
case 'A':
|
||||
result = 10;
|
||||
break;
|
||||
case 'B':
|
||||
result = 11;
|
||||
break;
|
||||
case 'C':
|
||||
result = 12;
|
||||
break;
|
||||
case 'D':
|
||||
result = 13;
|
||||
break;
|
||||
case 'E':
|
||||
result = 14;
|
||||
break;
|
||||
case 'F':
|
||||
result = 15;
|
||||
break;
|
||||
default:
|
||||
result = 0;
|
||||
break;
|
||||
case 'A': result = 10; break;
|
||||
case 'B': result = 11; break;
|
||||
case 'C': result = 12; break;
|
||||
case 'D': result = 13; break;
|
||||
case 'E': result = 14; break;
|
||||
case 'F': result = 15; break;
|
||||
default: result = 0; break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -39,14 +39,14 @@ extern "C" {
|
||||
* @param sel_start start index of selected area (-1 if none)
|
||||
* @param sel_end end index of selected area (-1 if none)
|
||||
*/
|
||||
void lv_draw_label(const lv_area_t * coords,const lv_area_t * mask, const lv_style_t * style, lv_opa_t opa_scale,
|
||||
const char * txt, lv_txt_flag_t flag, lv_point_t * offset, int sel_start, int sel_end);
|
||||
void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_style_t * style,
|
||||
lv_opa_t opa_scale, const char * txt, lv_txt_flag_t flag, lv_point_t * offset,
|
||||
int sel_start, int sel_end);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
@ -16,27 +16,29 @@
|
||||
* DEFINES
|
||||
*********************/
|
||||
#if LV_COMPILER_VLA_SUPPORTED == 0
|
||||
#define LINE_MAX_WIDTH 64
|
||||
#define LINE_MAX_WIDTH 64
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
typedef struct {
|
||||
typedef struct
|
||||
{
|
||||
lv_point_t p1;
|
||||
lv_point_t p2;
|
||||
lv_point_t p_act;
|
||||
lv_coord_t dx;
|
||||
lv_coord_t sx; /*-1: x1 < x2; 1: x2 >= x1*/
|
||||
lv_coord_t sx; /*-1: x1 < x2; 1: x2 >= x1*/
|
||||
lv_coord_t dy;
|
||||
lv_coord_t sy; /*-1: y1 < y2; 1: y2 >= y1*/
|
||||
lv_coord_t sy; /*-1: y1 < y2; 1: y2 >= y1*/
|
||||
lv_coord_t err;
|
||||
lv_coord_t e2;
|
||||
bool hor; /*Rather horizontal or vertical*/
|
||||
bool hor; /*Rather horizontal or vertical*/
|
||||
} line_draw_t;
|
||||
|
||||
typedef struct {
|
||||
typedef struct
|
||||
{
|
||||
lv_coord_t width;
|
||||
lv_coord_t width_1;
|
||||
lv_coord_t width_half;
|
||||
@ -45,9 +47,12 @@ typedef struct {
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static void line_draw_hor(line_draw_t * main_line, const lv_area_t * mask, const lv_style_t * style, lv_opa_t opa_scale);
|
||||
static void line_draw_ver(line_draw_t * main_line, const lv_area_t * mask, const lv_style_t * style, lv_opa_t opa_scale);
|
||||
static void line_draw_skew(line_draw_t * main_line, bool dir_ori, const lv_area_t * mask, const lv_style_t * style, lv_opa_t opa_scale);
|
||||
static void line_draw_hor(line_draw_t * main_line, const lv_area_t * mask, const lv_style_t * style,
|
||||
lv_opa_t opa_scale);
|
||||
static void line_draw_ver(line_draw_t * main_line, const lv_area_t * mask, const lv_style_t * style,
|
||||
lv_opa_t opa_scale);
|
||||
static void line_draw_skew(line_draw_t * main_line, bool dir_ori, const lv_area_t * mask,
|
||||
const lv_style_t * style, lv_opa_t opa_scale);
|
||||
static void line_init(line_draw_t * line, const lv_point_t * p1, const lv_point_t * p2);
|
||||
static bool line_next(line_draw_t * line);
|
||||
static bool line_next_y(line_draw_t * line);
|
||||
@ -74,7 +79,7 @@ static bool line_next_x(line_draw_t * line);
|
||||
* @param opa_scale scale down all opacities by the factor
|
||||
*/
|
||||
void lv_draw_line(const lv_point_t * point1, const lv_point_t * point2, const lv_area_t * mask,
|
||||
const lv_style_t * style, lv_opa_t opa_scale)
|
||||
const lv_style_t * style, lv_opa_t opa_scale)
|
||||
{
|
||||
|
||||
if(style->line.width == 0) return;
|
||||
@ -117,7 +122,6 @@ void lv_draw_line(const lv_point_t * point1, const lv_point_t * point2, const lv
|
||||
|
||||
line_init(&main_line, &p1, &p2);
|
||||
|
||||
|
||||
/*Special case draw a horizontal line*/
|
||||
if(main_line.p1.y == main_line.p2.y) {
|
||||
line_draw_hor(&main_line, mask, style, opa_scale);
|
||||
@ -140,30 +144,31 @@ void lv_draw_line(const lv_point_t * point1, const lv_point_t * point2, const lv
|
||||
p_tmp.x = main_line.p2.x;
|
||||
p_tmp.y = main_line.p2.y - 1;
|
||||
line_init(&main_line, &p1, &p_tmp);
|
||||
main_line.sy = LV_MATH_ABS(main_line.sy); /*The sign can change if the line becomes horizontal*/
|
||||
}
|
||||
else if(main_line.p1.y > main_line.p2.y) {
|
||||
main_line.sy = LV_MATH_ABS(
|
||||
main_line.sy); /*The sign can change if the line becomes horizontal*/
|
||||
} else if(main_line.p1.y > main_line.p2.y) {
|
||||
dir_ori = false;
|
||||
p_tmp.x = main_line.p2.x;
|
||||
p_tmp.y = main_line.p2.y + 1;
|
||||
line_init(&main_line, &p1, &p_tmp);
|
||||
main_line.sy = -LV_MATH_ABS(main_line.sy); /*The sign can change if the line becomes horizontal*/
|
||||
main_line.sy = -LV_MATH_ABS(
|
||||
main_line.sy); /*The sign can change if the line becomes horizontal*/
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
if(main_line.p1.x < main_line.p2.x) {
|
||||
dir_ori = true;
|
||||
p_tmp.x = main_line.p2.x - 1;
|
||||
p_tmp.y = main_line.p2.y;
|
||||
line_init(&main_line, &p1, &p_tmp);
|
||||
main_line.sx = LV_MATH_ABS(main_line.sx); /*The sign can change if the line becomes vertical*/
|
||||
}
|
||||
else if(main_line.p1.x > main_line.p2.x) {
|
||||
main_line.sx = LV_MATH_ABS(
|
||||
main_line.sx); /*The sign can change if the line becomes vertical*/
|
||||
} else if(main_line.p1.x > main_line.p2.x) {
|
||||
dir_ori = false;
|
||||
p_tmp.x = main_line.p2.x + 1;
|
||||
p_tmp.y = main_line.p2.y;
|
||||
line_init(&main_line, &p1, &p_tmp);
|
||||
main_line.sx = -LV_MATH_ABS(main_line.sx); /*The sign can change if the line becomes vertical*/
|
||||
main_line.sx = -LV_MATH_ABS(
|
||||
main_line.sx); /*The sign can change if the line becomes vertical*/
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -172,24 +177,25 @@ void lv_draw_line(const lv_point_t * point1, const lv_point_t * point2, const lv
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
|
||||
static void line_draw_hor(line_draw_t * main_line, const lv_area_t * mask, const lv_style_t * style, lv_opa_t opa_scale)
|
||||
static void line_draw_hor(line_draw_t * main_line, const lv_area_t * mask, const lv_style_t * style,
|
||||
lv_opa_t opa_scale)
|
||||
{
|
||||
lv_coord_t width = style->line.width - 1;
|
||||
lv_coord_t width = style->line.width - 1;
|
||||
lv_coord_t width_half = width >> 1;
|
||||
lv_coord_t width_1 = width & 0x1;
|
||||
lv_opa_t opa = opa_scale == LV_OPA_COVER ? style->line.opa : (uint16_t)((uint16_t) style->line.opa * opa_scale) >> 8;
|
||||
lv_coord_t width_1 = width & 0x1;
|
||||
lv_opa_t opa = opa_scale == LV_OPA_COVER
|
||||
? style->line.opa
|
||||
: (uint16_t)((uint16_t)style->line.opa * opa_scale) >> 8;
|
||||
|
||||
lv_area_t act_area;
|
||||
act_area.x1 = main_line->p1.x;
|
||||
act_area.x2 = main_line->p2.x;
|
||||
act_area.y1 = main_line->p1.y - width_half - width_1;
|
||||
act_area.y2 = main_line->p2.y + width_half ;
|
||||
act_area.y2 = main_line->p2.y + width_half;
|
||||
|
||||
lv_area_t draw_area;
|
||||
draw_area.x1 = LV_MATH_MIN(act_area.x1, act_area.x2);
|
||||
@ -199,12 +205,15 @@ static void line_draw_hor(line_draw_t * main_line, const lv_area_t * mask, const
|
||||
lv_draw_fill(&draw_area, mask, style->line.color, opa);
|
||||
}
|
||||
|
||||
static void line_draw_ver(line_draw_t * main_line, const lv_area_t * mask, const lv_style_t * style, lv_opa_t opa_scale)
|
||||
static void line_draw_ver(line_draw_t * main_line, const lv_area_t * mask, const lv_style_t * style,
|
||||
lv_opa_t opa_scale)
|
||||
{
|
||||
lv_coord_t width = style->line.width - 1;
|
||||
lv_coord_t width = style->line.width - 1;
|
||||
lv_coord_t width_half = width >> 1;
|
||||
lv_coord_t width_1 = width & 0x1;
|
||||
lv_opa_t opa = opa_scale == LV_OPA_COVER ? style->line.opa : (uint16_t)((uint16_t) style->line.opa * opa_scale) >> 8;
|
||||
lv_coord_t width_1 = width & 0x1;
|
||||
lv_opa_t opa = opa_scale == LV_OPA_COVER
|
||||
? style->line.opa
|
||||
: (uint16_t)((uint16_t)style->line.opa * opa_scale) >> 8;
|
||||
|
||||
lv_area_t act_area;
|
||||
act_area.x1 = main_line->p1.x - width_half;
|
||||
@ -220,10 +229,13 @@ static void line_draw_ver(line_draw_t * main_line, const lv_area_t * mask, const
|
||||
lv_draw_fill(&draw_area, mask, style->line.color, opa);
|
||||
}
|
||||
|
||||
static void line_draw_skew(line_draw_t * main_line, bool dir_ori, const lv_area_t * mask, const lv_style_t * style, lv_opa_t opa_scale)
|
||||
static void line_draw_skew(line_draw_t * main_line, bool dir_ori, const lv_area_t * mask,
|
||||
const lv_style_t * style, lv_opa_t opa_scale)
|
||||
{
|
||||
|
||||
lv_opa_t opa = opa_scale == LV_OPA_COVER ? style->line.opa : (uint16_t)((uint16_t) style->line.opa * opa_scale) >> 8;
|
||||
lv_opa_t opa = opa_scale == LV_OPA_COVER
|
||||
? style->line.opa
|
||||
: (uint16_t)((uint16_t)style->line.opa * opa_scale) >> 8;
|
||||
bool aa = lv_disp_get_antialiasing(lv_refr_get_disp_refreshing());
|
||||
lv_point_t vect_main, vect_norm;
|
||||
vect_main.x = main_line->p2.x - main_line->p1.x;
|
||||
@ -231,7 +243,7 @@ static void line_draw_skew(line_draw_t * main_line, bool dir_ori, const lv_area_
|
||||
|
||||
if(main_line->hor) {
|
||||
if(main_line->p1.y < main_line->p2.y + dir_ori) {
|
||||
vect_norm.x = - vect_main.y;
|
||||
vect_norm.x = -vect_main.y;
|
||||
vect_norm.y = vect_main.x;
|
||||
} else {
|
||||
vect_norm.x = vect_main.y;
|
||||
@ -240,9 +252,9 @@ static void line_draw_skew(line_draw_t * main_line, bool dir_ori, const lv_area_
|
||||
} else {
|
||||
if(main_line->p1.x < main_line->p2.x + dir_ori) {
|
||||
vect_norm.x = vect_main.y;
|
||||
vect_norm.y = - vect_main.x;
|
||||
vect_norm.y = -vect_main.x;
|
||||
} else {
|
||||
vect_norm.x = - vect_main.y;
|
||||
vect_norm.x = -vect_main.y;
|
||||
vect_norm.y = vect_main.x;
|
||||
}
|
||||
}
|
||||
@ -272,12 +284,14 @@ static void line_draw_skew(line_draw_t * main_line, bool dir_ori, const lv_area_
|
||||
|
||||
uint32_t width_sqr = width * width;
|
||||
/* Run for a lot of times. Meanwhile the real width will be determined as well */
|
||||
for(i = 0; i < (lv_coord_t)sizeof(pattern); i ++) {
|
||||
for(i = 0; i < (lv_coord_t)sizeof(pattern); i++) {
|
||||
pattern[i].x = pattern_line.p_act.x;
|
||||
pattern[i].y = pattern_line.p_act.y;
|
||||
|
||||
/*Finish the pattern line if it's length equal to the desired width (Use Pythagoras theorem)*/
|
||||
uint32_t sqr = pattern_line.p_act.x * pattern_line.p_act.x + pattern_line.p_act.y * pattern_line.p_act.y;
|
||||
/*Finish the pattern line if it's length equal to the desired width (Use Pythagoras
|
||||
* theorem)*/
|
||||
uint32_t sqr = pattern_line.p_act.x * pattern_line.p_act.x +
|
||||
pattern_line.p_act.y * pattern_line.p_act.y;
|
||||
if(sqr >= width_sqr) {
|
||||
width = i;
|
||||
#if LV_ANTIALIAS
|
||||
@ -306,10 +320,9 @@ static void line_draw_skew(line_draw_t * main_line, bool dir_ori, const lv_area_
|
||||
if(width != 0) {
|
||||
x_center_ofs = pattern[width - 1].x / 2;
|
||||
y_center_ofs = pattern[width - 1].y / 2;
|
||||
}
|
||||
else {
|
||||
if(main_line->hor && main_line->p1.y >= main_line->p2.y + dir_ori) pattern[0].y --;
|
||||
if(!main_line->hor && main_line->p1.x >= main_line->p2.x + dir_ori) pattern[0].x --;
|
||||
} else {
|
||||
if(main_line->hor && main_line->p1.y >= main_line->p2.y + dir_ori) pattern[0].y--;
|
||||
if(!main_line->hor && main_line->p1.x >= main_line->p2.x + dir_ori) pattern[0].x--;
|
||||
}
|
||||
|
||||
/* Make the coordinates relative to the center */
|
||||
@ -323,17 +336,23 @@ static void line_draw_skew(line_draw_t * main_line, bool dir_ori, const lv_area_
|
||||
if(pattern[i - 1].x != pattern[i].x) {
|
||||
lv_coord_t seg_w = pattern[i].y - pattern[aa_last_corner].y;
|
||||
if(main_line->sy < 0) {
|
||||
lv_draw_aa_ver_seg(main_line->p1.x + pattern[aa_last_corner].x - 1, main_line->p1.y + pattern[aa_last_corner].y + seg_w + 1,
|
||||
seg_w, mask, style->line.color, opa);
|
||||
lv_draw_aa_ver_seg(main_line->p1.x + pattern[aa_last_corner].x - 1,
|
||||
main_line->p1.y + pattern[aa_last_corner].y + seg_w +
|
||||
1,
|
||||
seg_w, mask, style->line.color, opa);
|
||||
|
||||
lv_draw_aa_ver_seg(main_line->p2.x + pattern[aa_last_corner].x + 1, main_line->p2.y + pattern[aa_last_corner].y + seg_w + 1,
|
||||
-seg_w, mask, style->line.color, opa);
|
||||
lv_draw_aa_ver_seg(main_line->p2.x + pattern[aa_last_corner].x + 1,
|
||||
main_line->p2.y + pattern[aa_last_corner].y + seg_w +
|
||||
1,
|
||||
-seg_w, mask, style->line.color, opa);
|
||||
} else {
|
||||
lv_draw_aa_ver_seg(main_line->p1.x + pattern[aa_last_corner].x - 1, main_line->p1.y + pattern[aa_last_corner].y,
|
||||
seg_w, mask, style->line.color, opa);
|
||||
lv_draw_aa_ver_seg(main_line->p1.x + pattern[aa_last_corner].x - 1,
|
||||
main_line->p1.y + pattern[aa_last_corner].y, seg_w,
|
||||
mask, style->line.color, opa);
|
||||
|
||||
lv_draw_aa_ver_seg(main_line->p2.x + pattern[aa_last_corner].x + 1, main_line->p2.y + pattern[aa_last_corner].y,
|
||||
-seg_w, mask, style->line.color, opa);
|
||||
lv_draw_aa_ver_seg(main_line->p2.x + pattern[aa_last_corner].x + 1,
|
||||
main_line->p2.y + pattern[aa_last_corner].y, -seg_w,
|
||||
mask, style->line.color, opa);
|
||||
}
|
||||
aa_last_corner = i;
|
||||
}
|
||||
@ -341,22 +360,27 @@ static void line_draw_skew(line_draw_t * main_line, bool dir_ori, const lv_area_
|
||||
if(pattern[i - 1].y != pattern[i].y) {
|
||||
lv_coord_t seg_w = pattern[i].x - pattern[aa_last_corner].x;
|
||||
if(main_line->sx < 0) {
|
||||
lv_draw_aa_hor_seg(main_line->p1.x + pattern[aa_last_corner].x + seg_w + 1, main_line->p1.y + pattern[aa_last_corner].y - 1,
|
||||
seg_w, mask, style->line.color, opa);
|
||||
lv_draw_aa_hor_seg(main_line->p1.x + pattern[aa_last_corner].x + seg_w +
|
||||
1,
|
||||
main_line->p1.y + pattern[aa_last_corner].y - 1,
|
||||
seg_w, mask, style->line.color, opa);
|
||||
|
||||
lv_draw_aa_hor_seg(main_line->p2.x + pattern[aa_last_corner].x + seg_w + 1, main_line->p2.y + pattern[aa_last_corner].y + 1,
|
||||
-seg_w, mask, style->line.color, opa);
|
||||
lv_draw_aa_hor_seg(main_line->p2.x + pattern[aa_last_corner].x + seg_w +
|
||||
1,
|
||||
main_line->p2.y + pattern[aa_last_corner].y + 1,
|
||||
-seg_w, mask, style->line.color, opa);
|
||||
} else {
|
||||
lv_draw_aa_hor_seg(main_line->p1.x + pattern[aa_last_corner].x, main_line->p1.y + pattern[aa_last_corner].y - 1,
|
||||
seg_w, mask, style->line.color, opa);
|
||||
lv_draw_aa_hor_seg(main_line->p1.x + pattern[aa_last_corner].x,
|
||||
main_line->p1.y + pattern[aa_last_corner].y - 1,
|
||||
seg_w, mask, style->line.color, opa);
|
||||
|
||||
lv_draw_aa_hor_seg(main_line->p2.x + pattern[aa_last_corner].x, main_line->p2.y + pattern[aa_last_corner].y + 1,
|
||||
-seg_w, mask, style->line.color, opa);
|
||||
lv_draw_aa_hor_seg(main_line->p2.x + pattern[aa_last_corner].x,
|
||||
main_line->p2.y + pattern[aa_last_corner].y + 1,
|
||||
-seg_w, mask, style->line.color, opa);
|
||||
}
|
||||
aa_last_corner = i;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -364,40 +388,47 @@ static void line_draw_skew(line_draw_t * main_line, bool dir_ori, const lv_area_
|
||||
|
||||
#if LV_ANTIALIAS
|
||||
/*Add the last part of anti-aliasing for the perpendicular ending*/
|
||||
if(width != 0 && aa) { /*Due to rounding error with very thin lines it looks ugly*/
|
||||
if(width != 0 && aa) { /*Due to rounding error with very thin lines it looks ugly*/
|
||||
if(main_line->hor) {
|
||||
lv_coord_t seg_w = pattern[width_safe - 1].y - pattern[aa_last_corner].y;
|
||||
if(main_line->sy < 0) {
|
||||
lv_draw_aa_ver_seg(main_line->p1.x + pattern[aa_last_corner].x - 1, main_line->p1.y + pattern[aa_last_corner].y + seg_w,
|
||||
seg_w + main_line->sy, mask, style->line.color, opa);
|
||||
lv_draw_aa_ver_seg(main_line->p1.x + pattern[aa_last_corner].x - 1,
|
||||
main_line->p1.y + pattern[aa_last_corner].y + seg_w,
|
||||
seg_w + main_line->sy, mask, style->line.color, opa);
|
||||
|
||||
lv_draw_aa_ver_seg(main_line->p2.x + pattern[aa_last_corner].x + 1, main_line->p2.y + pattern[aa_last_corner].y + seg_w,
|
||||
-(seg_w + main_line->sy), mask, style->line.color, opa);
|
||||
lv_draw_aa_ver_seg(main_line->p2.x + pattern[aa_last_corner].x + 1,
|
||||
main_line->p2.y + pattern[aa_last_corner].y + seg_w,
|
||||
-(seg_w + main_line->sy), mask, style->line.color, opa);
|
||||
|
||||
} else {
|
||||
lv_draw_aa_ver_seg(main_line->p1.x + pattern[aa_last_corner].x - 1, main_line->p1.y + pattern[aa_last_corner].y,
|
||||
seg_w + main_line->sy, mask, style->line.color, opa);
|
||||
lv_draw_aa_ver_seg(main_line->p1.x + pattern[aa_last_corner].x - 1,
|
||||
main_line->p1.y + pattern[aa_last_corner].y,
|
||||
seg_w + main_line->sy, mask, style->line.color, opa);
|
||||
|
||||
lv_draw_aa_ver_seg(main_line->p2.x + pattern[aa_last_corner].x + 1, main_line->p2.y + pattern[aa_last_corner].y,
|
||||
-(seg_w + main_line->sy), mask, style->line.color, opa);
|
||||
lv_draw_aa_ver_seg(main_line->p2.x + pattern[aa_last_corner].x + 1,
|
||||
main_line->p2.y + pattern[aa_last_corner].y,
|
||||
-(seg_w + main_line->sy), mask, style->line.color, opa);
|
||||
}
|
||||
} else {
|
||||
lv_coord_t seg_w = pattern[width_safe - 1].x - pattern[aa_last_corner].x;
|
||||
if(main_line->sx < 0) {
|
||||
lv_draw_aa_hor_seg(main_line->p1.x + pattern[aa_last_corner].x + seg_w, main_line->p1.y + pattern[aa_last_corner].y - 1,
|
||||
seg_w + main_line->sx, mask, style->line.color, opa);
|
||||
lv_draw_aa_hor_seg(main_line->p1.x + pattern[aa_last_corner].x + seg_w,
|
||||
main_line->p1.y + pattern[aa_last_corner].y - 1,
|
||||
seg_w + main_line->sx, mask, style->line.color, opa);
|
||||
|
||||
lv_draw_aa_hor_seg(main_line->p2.x + pattern[aa_last_corner].x + seg_w, main_line->p2.y + pattern[aa_last_corner].y + 1,
|
||||
-(seg_w + main_line->sx), mask, style->line.color, opa);
|
||||
lv_draw_aa_hor_seg(main_line->p2.x + pattern[aa_last_corner].x + seg_w,
|
||||
main_line->p2.y + pattern[aa_last_corner].y + 1,
|
||||
-(seg_w + main_line->sx), mask, style->line.color, opa);
|
||||
|
||||
} else {
|
||||
lv_draw_aa_hor_seg(main_line->p1.x + pattern[aa_last_corner].x, main_line->p1.y + pattern[aa_last_corner].y - 1,
|
||||
seg_w + main_line->sx, mask, style->line.color, opa);
|
||||
lv_draw_aa_hor_seg(main_line->p1.x + pattern[aa_last_corner].x,
|
||||
main_line->p1.y + pattern[aa_last_corner].y - 1,
|
||||
seg_w + main_line->sx, mask, style->line.color, opa);
|
||||
|
||||
lv_draw_aa_hor_seg(main_line->p2.x + pattern[aa_last_corner].x, main_line->p2.y + pattern[aa_last_corner].y + 1,
|
||||
-(seg_w + main_line->sx), mask, style->line.color, opa);
|
||||
lv_draw_aa_hor_seg(main_line->p2.x + pattern[aa_last_corner].x,
|
||||
main_line->p2.y + pattern[aa_last_corner].y + 1,
|
||||
-(seg_w + main_line->sx), mask, style->line.color, opa);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -444,18 +475,21 @@ static void line_draw_skew(line_draw_t * main_line, bool dir_ori, const lv_area_
|
||||
lv_draw_fill(&draw_area, mask, style->line.color, opa);
|
||||
|
||||
/* Fill the gaps
|
||||
* When stepping in y one pixel remains empty on every corner (don't do this on the first segment ) */
|
||||
* When stepping in y one pixel remains empty on every corner (don't do this on the
|
||||
* first segment ) */
|
||||
if(i != 0 && pattern[i].x != pattern[i - 1].x && !first_run) {
|
||||
lv_draw_px(draw_area.x1, draw_area.y1 - main_line->sy, mask, style->line.color, opa);
|
||||
lv_draw_px(draw_area.x1, draw_area.y1 - main_line->sy, mask, style->line.color,
|
||||
opa);
|
||||
}
|
||||
}
|
||||
|
||||
#if LV_ANTIALIAS
|
||||
if(aa) {
|
||||
lv_draw_aa_hor_seg(prev_p.x + pattern[0].x, prev_p.y + pattern[0].y - aa_shift1,
|
||||
-(main_line->p_act.x - prev_p.x), mask, style->line.color, opa);
|
||||
lv_draw_aa_hor_seg(prev_p.x + pattern[width_safe - 1].x, prev_p.y + pattern[width_safe - 1].y + aa_shift2,
|
||||
main_line->p_act.x - prev_p.x, mask, style->line.color, opa);
|
||||
-(main_line->p_act.x - prev_p.x), mask, style->line.color, opa);
|
||||
lv_draw_aa_hor_seg(prev_p.x + pattern[width_safe - 1].x,
|
||||
prev_p.y + pattern[width_safe - 1].y + aa_shift2,
|
||||
main_line->p_act.x - prev_p.x, mask, style->line.color, opa);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -475,16 +509,18 @@ static void line_draw_skew(line_draw_t * main_line, bool dir_ori, const lv_area_
|
||||
/* Fill the gaps
|
||||
* When stepping in y one pixel remains empty on every corner */
|
||||
if(i != 0 && pattern[i].x != pattern[i - 1].x && !first_run) {
|
||||
lv_draw_px(draw_area.x1, draw_area.y1 - main_line->sy, mask, style->line.color, opa);
|
||||
lv_draw_px(draw_area.x1, draw_area.y1 - main_line->sy, mask, style->line.color,
|
||||
opa);
|
||||
}
|
||||
}
|
||||
|
||||
#if LV_ANTIALIAS
|
||||
if(aa) {
|
||||
lv_draw_aa_hor_seg(prev_p.x + pattern[0].x, prev_p.y + pattern[0].y - aa_shift1,
|
||||
-(main_line->p_act.x - prev_p.x + 1), mask, style->line.color, opa);
|
||||
lv_draw_aa_hor_seg(prev_p.x + pattern[width_safe - 1].x, prev_p.y + pattern[width_safe - 1].y + aa_shift2,
|
||||
main_line->p_act.x - prev_p.x + 1, mask, style->line.color, opa);
|
||||
-(main_line->p_act.x - prev_p.x + 1), mask, style->line.color, opa);
|
||||
lv_draw_aa_hor_seg(prev_p.x + pattern[width_safe - 1].x,
|
||||
prev_p.y + pattern[width_safe - 1].y + aa_shift2,
|
||||
main_line->p_act.x - prev_p.x + 1, mask, style->line.color, opa);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@ -501,19 +537,21 @@ static void line_draw_skew(line_draw_t * main_line, bool dir_ori, const lv_area_
|
||||
lv_draw_fill(&draw_area, mask, style->line.color, opa);
|
||||
|
||||
/* Fill the gaps
|
||||
* When stepping in x one pixel remains empty on every corner (don't do this on the first segment ) */
|
||||
* When stepping in x one pixel remains empty on every corner (don't do this on the
|
||||
* first segment ) */
|
||||
if(i != 0 && pattern[i].y != pattern[i - 1].y && !first_run) {
|
||||
lv_draw_px(draw_area.x1 - main_line->sx, draw_area.y1, mask, style->line.color, opa);
|
||||
lv_draw_px(draw_area.x1 - main_line->sx, draw_area.y1, mask, style->line.color,
|
||||
opa);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#if LV_ANTIALIAS
|
||||
if(aa) {
|
||||
lv_draw_aa_ver_seg(prev_p.x + pattern[0].x - aa_shift1, prev_p.y + pattern[0].y,
|
||||
-(main_line->p_act.y - prev_p.y), mask, style->line.color, opa);
|
||||
lv_draw_aa_ver_seg(prev_p.x + pattern[width_safe - 1].x + aa_shift2, prev_p.y + pattern[width_safe - 1].y,
|
||||
main_line->p_act.y - prev_p.y, mask, style->line.color, opa);
|
||||
-(main_line->p_act.y - prev_p.y), mask, style->line.color, opa);
|
||||
lv_draw_aa_ver_seg(prev_p.x + pattern[width_safe - 1].x + aa_shift2,
|
||||
prev_p.y + pattern[width_safe - 1].y,
|
||||
main_line->p_act.y - prev_p.y, mask, style->line.color, opa);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -535,22 +573,23 @@ static void line_draw_skew(line_draw_t * main_line, bool dir_ori, const lv_area_
|
||||
/* Fill the gaps
|
||||
* When stepping in x one pixel remains empty on every corner */
|
||||
if(i != 0 && pattern[i].y != pattern[i - 1].y && !first_run) {
|
||||
lv_draw_px(draw_area.x1 - main_line->sx, draw_area.y1, mask, style->line.color, opa);
|
||||
lv_draw_px(draw_area.x1 - main_line->sx, draw_area.y1, mask, style->line.color,
|
||||
opa);
|
||||
}
|
||||
}
|
||||
|
||||
#if LV_ANTIALIAS
|
||||
if(aa) {
|
||||
lv_draw_aa_ver_seg(prev_p.x + pattern[0].x - aa_shift1, prev_p.y + pattern[0].y,
|
||||
-(main_line->p_act.y - prev_p.y + 1), mask, style->line.color, opa);
|
||||
lv_draw_aa_ver_seg(prev_p.x + pattern[width_safe - 1].x + aa_shift2, prev_p.y + pattern[width_safe - 1].y,
|
||||
main_line->p_act.y - prev_p.y + 1, mask, style->line.color, opa);
|
||||
-(main_line->p_act.y - prev_p.y + 1), mask, style->line.color, opa);
|
||||
lv_draw_aa_ver_seg(prev_p.x + pattern[width_safe - 1].x + aa_shift2,
|
||||
prev_p.y + pattern[width_safe - 1].y,
|
||||
main_line->p_act.y - prev_p.y + 1, mask, style->line.color, opa);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void line_init(line_draw_t * line, const lv_point_t * p1, const lv_point_t * p2)
|
||||
{
|
||||
line->p1.x = p1->x;
|
||||
@ -558,12 +597,12 @@ static void line_init(line_draw_t * line, const lv_point_t * p1, const lv_point_
|
||||
line->p2.x = p2->x;
|
||||
line->p2.y = p2->y;
|
||||
|
||||
line->dx = LV_MATH_ABS(line->p2.x - line->p1.x);
|
||||
line->sx = line->p1.x < line->p2.x ? 1 : -1;
|
||||
line->dy = LV_MATH_ABS(line->p2.y - line->p1.y);
|
||||
line->sy = line->p1.y < line->p2.y ? 1 : -1;
|
||||
line->dx = LV_MATH_ABS(line->p2.x - line->p1.x);
|
||||
line->sx = line->p1.x < line->p2.x ? 1 : -1;
|
||||
line->dy = LV_MATH_ABS(line->p2.y - line->p1.y);
|
||||
line->sy = line->p1.y < line->p2.y ? 1 : -1;
|
||||
line->err = (line->dx > line->dy ? line->dx : -line->dy) / 2;
|
||||
line->e2 = 0;
|
||||
line->e2 = 0;
|
||||
line->hor = line->dx > line->dy ? true : false; /*Rather horizontal or vertical*/
|
||||
|
||||
line->p_act.x = line->p1.x;
|
||||
@ -599,7 +638,6 @@ static bool line_next_y(line_draw_t * line)
|
||||
} while(last_y == line->p_act.y);
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -616,6 +654,4 @@ static bool line_next_x(line_draw_t * line)
|
||||
} while(last_x == line->p_act.x);
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
|
@ -41,7 +41,6 @@ void lv_draw_line(const lv_point_t * point1, const lv_point_t * point2, const lv
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -34,13 +34,13 @@ extern "C" {
|
||||
* @param style pointer to a style
|
||||
* @param opa_scale scale down all opacities by the factor
|
||||
*/
|
||||
void lv_draw_rect(const lv_area_t * coords, const lv_area_t * mask, const lv_style_t * style, lv_opa_t opa_scale);
|
||||
void lv_draw_rect(const lv_area_t * coords, const lv_area_t * mask, const lv_style_t * style,
|
||||
lv_opa_t opa_scale);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
@ -41,7 +41,8 @@ static void point_swap(lv_point_t * p1, lv_point_t * p2);
|
||||
* @param style style for of the triangle
|
||||
* @param opa_scale scale down all opacities by the factor
|
||||
*/
|
||||
void lv_draw_triangle(const lv_point_t * points, const lv_area_t * mask, const lv_style_t * style, lv_opa_t opa_scale)
|
||||
void lv_draw_triangle(const lv_point_t * points, const lv_area_t * mask, const lv_style_t * style,
|
||||
lv_opa_t opa_scale)
|
||||
{
|
||||
lv_point_t tri[3];
|
||||
|
||||
@ -62,18 +63,18 @@ void lv_draw_triangle(const lv_point_t * points, const lv_area_t * mask, const l
|
||||
|
||||
/*Draw the triangle*/
|
||||
lv_point_t edge1;
|
||||
lv_coord_t dx1 = LV_MATH_ABS(tri[0].x - tri[1].x);
|
||||
lv_coord_t sx1 = tri[0].x < tri[1].x ? 1 : -1;
|
||||
lv_coord_t dy1 = LV_MATH_ABS(tri[0].y - tri[1].y);
|
||||
lv_coord_t sy1 = tri[0].y < tri[1].y ? 1 : -1;
|
||||
lv_coord_t dx1 = LV_MATH_ABS(tri[0].x - tri[1].x);
|
||||
lv_coord_t sx1 = tri[0].x < tri[1].x ? 1 : -1;
|
||||
lv_coord_t dy1 = LV_MATH_ABS(tri[0].y - tri[1].y);
|
||||
lv_coord_t sy1 = tri[0].y < tri[1].y ? 1 : -1;
|
||||
lv_coord_t err1 = (dx1 > dy1 ? dx1 : -dy1) / 2;
|
||||
lv_coord_t err_tmp1;
|
||||
|
||||
lv_point_t edge2;
|
||||
lv_coord_t dx2 = LV_MATH_ABS(tri[0].x - tri[2].x);
|
||||
lv_coord_t sx2 = tri[0].x < tri[2].x ? 1 : -1;
|
||||
lv_coord_t dy2 = LV_MATH_ABS(tri[0].y - tri[2].y);
|
||||
lv_coord_t sy2 = tri[0].y < tri[2].y ? 1 : -1;
|
||||
lv_coord_t dx2 = LV_MATH_ABS(tri[0].x - tri[2].x);
|
||||
lv_coord_t sx2 = tri[0].x < tri[2].x ? 1 : -1;
|
||||
lv_coord_t dy2 = LV_MATH_ABS(tri[0].y - tri[2].y);
|
||||
lv_coord_t sy2 = tri[0].y < tri[2].y ? 1 : -1;
|
||||
lv_coord_t err2 = (dx1 > dy2 ? dx2 : -dy2) / 2;
|
||||
lv_coord_t err_tmp2;
|
||||
|
||||
@ -87,21 +88,22 @@ void lv_draw_triangle(const lv_point_t * points, const lv_area_t * mask, const l
|
||||
lv_area_t act_area;
|
||||
lv_area_t draw_area;
|
||||
|
||||
|
||||
lv_opa_t opa = opa_scale == LV_OPA_COVER ? style->body.opa : (uint16_t)((uint16_t) style->body.opa * opa_scale) >> 8;
|
||||
lv_opa_t opa = opa_scale == LV_OPA_COVER
|
||||
? style->body.opa
|
||||
: (uint16_t)((uint16_t)style->body.opa * opa_scale) >> 8;
|
||||
|
||||
while(1) {
|
||||
act_area.x1 = edge1.x;
|
||||
act_area.x2 = edge2.x ;
|
||||
act_area.x2 = edge2.x;
|
||||
act_area.y1 = edge1.y;
|
||||
act_area.y2 = edge2.y ;
|
||||
|
||||
act_area.y2 = edge2.y;
|
||||
|
||||
draw_area.x1 = LV_MATH_MIN(act_area.x1, act_area.x2);
|
||||
draw_area.x2 = LV_MATH_MAX(act_area.x1, act_area.x2);
|
||||
draw_area.y1 = LV_MATH_MIN(act_area.y1, act_area.y2);
|
||||
draw_area.y2 = LV_MATH_MAX(act_area.y1, act_area.y2);
|
||||
draw_area.x2--; /*Do not draw most right pixel because it will be drawn by the adjacent triangle*/
|
||||
draw_area.x2--; /*Do not draw most right pixel because it will be drawn by the adjacent
|
||||
triangle*/
|
||||
lv_draw_fill(&draw_area, mask, style->body.main_color, opa);
|
||||
|
||||
/*Calc. the next point of edge1*/
|
||||
@ -109,12 +111,13 @@ void lv_draw_triangle(const lv_point_t * points, const lv_area_t * mask, const l
|
||||
do {
|
||||
if(edge1.x == tri[1].x && edge1.y == tri[1].y) {
|
||||
|
||||
dx1 = LV_MATH_ABS(tri[1].x - tri[2].x);
|
||||
sx1 = tri[1].x < tri[2].x ? 1 : -1;
|
||||
dy1 = LV_MATH_ABS(tri[1].y - tri[2].y);
|
||||
sy1 = tri[1].y < tri[2].y ? 1 : -1;
|
||||
dx1 = LV_MATH_ABS(tri[1].x - tri[2].x);
|
||||
sx1 = tri[1].x < tri[2].x ? 1 : -1;
|
||||
dy1 = LV_MATH_ABS(tri[1].y - tri[2].y);
|
||||
sy1 = tri[1].y < tri[2].y ? 1 : -1;
|
||||
err1 = (dx1 > dy1 ? dx1 : -dy1) / 2;
|
||||
} else if(edge1.x == tri[2].x && edge1.y == tri[2].y) return;
|
||||
} else if(edge1.x == tri[2].x && edge1.y == tri[2].y)
|
||||
return;
|
||||
err_tmp1 = err1;
|
||||
if(err_tmp1 > -dx1) {
|
||||
err1 -= dy1;
|
||||
@ -147,7 +150,6 @@ void lv_draw_triangle(const lv_point_t * points, const lv_area_t * mask, const l
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
|
||||
/**
|
||||
* Swap two points
|
||||
* p1 pointer to the first point
|
||||
@ -164,5 +166,4 @@ static void point_swap(lv_point_t * p1, lv_point_t * p2)
|
||||
|
||||
p2->x = tmp.x;
|
||||
p2->y = tmp.y;
|
||||
|
||||
}
|
||||
|
@ -34,13 +34,13 @@ extern "C" {
|
||||
* @param style style for of the triangle
|
||||
* @param opa_scale scale down all opacities by the factor
|
||||
*/
|
||||
void lv_draw_triangle(const lv_point_t * points, const lv_area_t * mask, const lv_style_t * style, lv_opa_t opa_scale);
|
||||
void lv_draw_triangle(const lv_point_t * points, const lv_area_t * mask, const lv_style_t * style,
|
||||
lv_opa_t opa_scale);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
@ -18,7 +18,7 @@
|
||||
#include "../lv_misc/lv_gc.h"
|
||||
|
||||
#if defined(LV_GC_INCLUDE)
|
||||
# include LV_GC_INCLUDE
|
||||
#include LV_GC_INCLUDE
|
||||
#endif /* LV_ENABLE_GC */
|
||||
|
||||
/*********************
|
||||
@ -57,10 +57,10 @@ void lv_disp_drv_init(lv_disp_drv_t * driver)
|
||||
memset(driver, 0, sizeof(lv_disp_drv_t));
|
||||
|
||||
driver->flush_cb = NULL;
|
||||
driver->hor_res = LV_HOR_RES_MAX;
|
||||
driver->ver_res = LV_VER_RES_MAX;
|
||||
driver->buffer = NULL;
|
||||
driver->rotated = 0;
|
||||
driver->hor_res = LV_HOR_RES_MAX;
|
||||
driver->ver_res = LV_VER_RES_MAX;
|
||||
driver->buffer = NULL;
|
||||
driver->rotated = 0;
|
||||
|
||||
#if LV_ANTIALIAS
|
||||
driver->antialiasing = true;
|
||||
@ -68,13 +68,12 @@ void lv_disp_drv_init(lv_disp_drv_t * driver)
|
||||
|
||||
#if LV_USE_GPU
|
||||
driver->mem_blend = NULL;
|
||||
driver->mem_fill = NULL;
|
||||
driver->mem_fill = NULL;
|
||||
#endif
|
||||
|
||||
driver->set_px_cb = NULL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initialize a display buffer
|
||||
* @param disp_buf pointer `lv_disp_buf_t` variable to initialize
|
||||
@ -86,21 +85,20 @@ void lv_disp_drv_init(lv_disp_drv_t * driver)
|
||||
* (sending to the display) parallel.
|
||||
* In the `disp_drv->flush` you should use DMA or similar hardware to send
|
||||
* the image to the display in the background.
|
||||
* It lets LittlevGL to render next frame into the other buffer while previous is being sent.
|
||||
* Set to `NULL` if unused.
|
||||
* It lets LittlevGL to render next frame into the other buffer while previous is being
|
||||
* sent. Set to `NULL` if unused.
|
||||
* @param size size of the `buf1` and `buf2` in pixel count.
|
||||
*/
|
||||
void lv_disp_buf_init(lv_disp_buf_t * disp_buf, void * buf1, void * buf2, uint32_t size)
|
||||
{
|
||||
memset(disp_buf, 0, sizeof(lv_disp_buf_t));
|
||||
|
||||
disp_buf->buf1 = buf1;
|
||||
disp_buf->buf2 = buf2;
|
||||
disp_buf->buf1 = buf1;
|
||||
disp_buf->buf2 = buf2;
|
||||
disp_buf->buf_act = disp_buf->buf1;
|
||||
disp_buf->size = size;
|
||||
disp_buf->size = size;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Register an initialized display driver.
|
||||
* Automatically set the first display as active.
|
||||
@ -122,12 +120,13 @@ lv_disp_t * lv_disp_drv_register(lv_disp_drv_t * driver)
|
||||
|
||||
if(disp_def == NULL) disp_def = disp;
|
||||
|
||||
lv_disp_t * disp_def_tmp = disp_def;
|
||||
disp_def = disp; /*Temporarily change the default screen to create the default screens on the new display*/
|
||||
lv_disp_t * disp_def_tmp = disp_def;
|
||||
disp_def = disp; /*Temporarily change the default screen to create the default screens on the
|
||||
new display*/
|
||||
|
||||
disp->act_scr = lv_obj_create(NULL, NULL); /*Create a default screen on the display*/
|
||||
disp->top_layer = lv_obj_create(NULL, NULL); /*Create top layer on the display*/
|
||||
disp->sys_layer = lv_obj_create(NULL, NULL); /*Create top layer on the display*/
|
||||
disp->act_scr = lv_obj_create(NULL, NULL); /*Create a default screen on the display*/
|
||||
disp->top_layer = lv_obj_create(NULL, NULL); /*Create top layer on the display*/
|
||||
disp->sys_layer = lv_obj_create(NULL, NULL); /*Create top layer on the display*/
|
||||
lv_obj_set_style(disp->top_layer, &lv_style_transp);
|
||||
lv_obj_set_style(disp->sys_layer, &lv_style_transp);
|
||||
|
||||
@ -135,14 +134,15 @@ lv_disp_t * lv_disp_drv_register(lv_disp_drv_t * driver)
|
||||
|
||||
lv_obj_invalidate(disp->act_scr);
|
||||
|
||||
disp_def = disp_def_tmp; /*Revert the default display*/
|
||||
disp_def = disp_def_tmp; /*Revert the default display*/
|
||||
|
||||
/*Create a refresh task*/
|
||||
disp->refr_task = lv_task_create(lv_disp_refr_task, LV_DISP_DEF_REFR_PERIOD, LV_TASK_PRIO_MID, disp);
|
||||
disp->refr_task =
|
||||
lv_task_create(lv_disp_refr_task, LV_DISP_DEF_REFR_PERIOD, LV_TASK_PRIO_MID, disp);
|
||||
lv_mem_assert(disp->refr_task);
|
||||
if(disp->refr_task == NULL) return NULL;
|
||||
|
||||
lv_task_ready(disp->refr_task); /*Be sure the screen will be refreshed immediately on start up*/
|
||||
lv_task_ready(disp->refr_task); /*Be sure the screen will be refreshed immediately on start up*/
|
||||
|
||||
return disp;
|
||||
}
|
||||
@ -157,7 +157,8 @@ void lv_disp_drv_update(lv_disp_t * disp, lv_disp_drv_t * new_drv)
|
||||
memcpy(&disp->driver, new_drv, sizeof(lv_disp_drv_t));
|
||||
|
||||
lv_obj_t * scr;
|
||||
LV_LL_READ(disp->scr_ll, scr) {
|
||||
LV_LL_READ(disp->scr_ll, scr)
|
||||
{
|
||||
lv_obj_set_size(scr, lv_disp_get_hor_res(disp), lv_disp_get_ver_res(disp));
|
||||
}
|
||||
}
|
||||
@ -187,7 +188,6 @@ void lv_disp_remove(lv_disp_t * disp)
|
||||
if(was_default) lv_disp_set_default(lv_ll_get_head(&LV_GC_ROOT(_lv_disp_ll)));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set a default screen. The new screens will be created on it by default.
|
||||
* @param disp pointer to a display
|
||||
@ -215,8 +215,10 @@ lv_coord_t lv_disp_get_hor_res(lv_disp_t * disp)
|
||||
{
|
||||
if(disp == NULL) disp = lv_disp_get_default();
|
||||
|
||||
if(disp == NULL) return disp->driver.rotated == 0 ? LV_HOR_RES_MAX : LV_VER_RES_MAX;
|
||||
else return disp->driver.rotated == 0 ? disp->driver.hor_res : disp->driver.ver_res;
|
||||
if(disp == NULL)
|
||||
return disp->driver.rotated == 0 ? LV_HOR_RES_MAX : LV_VER_RES_MAX;
|
||||
else
|
||||
return disp->driver.rotated == 0 ? disp->driver.hor_res : disp->driver.ver_res;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -228,8 +230,10 @@ lv_coord_t lv_disp_get_ver_res(lv_disp_t * disp)
|
||||
{
|
||||
if(disp == NULL) disp = lv_disp_get_default();
|
||||
|
||||
if(disp == NULL) return disp->driver.rotated == 0 ? LV_VER_RES_MAX : LV_HOR_RES_MAX;
|
||||
else return disp->driver.rotated == 0 ? disp->driver.ver_res : disp->driver.hor_res;
|
||||
if(disp == NULL)
|
||||
return disp->driver.rotated == 0 ? LV_VER_RES_MAX : LV_HOR_RES_MAX;
|
||||
else
|
||||
return disp->driver.rotated == 0 ? disp->driver.ver_res : disp->driver.hor_res;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -249,7 +253,6 @@ bool lv_disp_get_antialiasing(lv_disp_t * disp)
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Call in the display driver's `flush_cb` function when the flushing is finished
|
||||
* @param disp_drv pointer to display driver in `flush_cb` where this function is called
|
||||
@ -264,7 +267,6 @@ LV_ATTRIBUTE_FLUSH_READY void lv_disp_flush_ready(lv_disp_drv_t * disp_drv)
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the next display.
|
||||
* @param disp pointer to the current display. NULL to initialize.
|
||||
@ -272,8 +274,10 @@ LV_ATTRIBUTE_FLUSH_READY void lv_disp_flush_ready(lv_disp_drv_t * disp_drv)
|
||||
*/
|
||||
lv_disp_t * lv_disp_get_next(lv_disp_t * disp)
|
||||
{
|
||||
if(disp == NULL) return lv_ll_get_head(&LV_GC_ROOT(_lv_disp_ll));
|
||||
else return lv_ll_get_next(&LV_GC_ROOT(_lv_disp_ll), disp);
|
||||
if(disp == NULL)
|
||||
return lv_ll_get_head(&LV_GC_ROOT(_lv_disp_ll));
|
||||
else
|
||||
return lv_ll_get_next(&LV_GC_ROOT(_lv_disp_ll), disp);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -302,8 +306,10 @@ uint16_t lv_disp_get_inv_buf_size(lv_disp_t * disp)
|
||||
void lv_disp_pop_from_inv_buf(lv_disp_t * disp, uint16_t num)
|
||||
{
|
||||
|
||||
if(disp->inv_p < num) disp->inv_p = 0;
|
||||
else disp->inv_p -= num;
|
||||
if(disp->inv_p < num)
|
||||
disp->inv_p = 0;
|
||||
else
|
||||
disp->inv_p -= num;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -313,12 +319,15 @@ void lv_disp_pop_from_inv_buf(lv_disp_t * disp, uint16_t num)
|
||||
*/
|
||||
bool lv_disp_is_double_buf(lv_disp_t * disp)
|
||||
{
|
||||
if(disp->driver.buffer->buf1 && disp->driver.buffer->buf2) return true;
|
||||
else return false;
|
||||
if(disp->driver.buffer->buf1 && disp->driver.buffer->buf2)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the driver configuration if it's TRUE double buffered (both `buf1` and `buf2` are set and `size` is screen sized)
|
||||
* Check the driver configuration if it's TRUE double buffered (both `buf1` and `buf2` are set and
|
||||
* `size` is screen sized)
|
||||
* @param disp pointer to to display to check
|
||||
* @return true: double buffered; false: not double buffered
|
||||
*/
|
||||
@ -326,16 +335,13 @@ bool lv_disp_is_true_double_buf(lv_disp_t * disp)
|
||||
{
|
||||
uint32_t scr_size = disp->driver.hor_res * disp->driver.ver_res;
|
||||
|
||||
if(lv_disp_is_double_buf(disp) &&
|
||||
disp->driver.buffer->size == scr_size) {
|
||||
if(lv_disp_is_double_buf(disp) && disp->driver.buffer->size == scr_size) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
@ -27,11 +27,11 @@ extern "C" {
|
||||
* DEFINES
|
||||
*********************/
|
||||
#ifndef LV_INV_BUF_SIZE
|
||||
#define LV_INV_BUF_SIZE 32 /*Buffer size for invalid areas */
|
||||
#define LV_INV_BUF_SIZE 32 /*Buffer size for invalid areas */
|
||||
#endif
|
||||
|
||||
#ifndef LV_ATTRIBUTE_FLUSH_READY
|
||||
# define LV_ATTRIBUTE_FLUSH_READY
|
||||
#define LV_ATTRIBUTE_FLUSH_READY
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
@ -41,7 +41,6 @@ extern "C" {
|
||||
struct _disp_t;
|
||||
struct _disp_drv_t;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
void * buf1;
|
||||
@ -49,16 +48,16 @@ typedef struct
|
||||
|
||||
/*Used by the library*/
|
||||
void * buf_act;
|
||||
uint32_t size; /*In pixel count*/
|
||||
uint32_t size; /*In pixel count*/
|
||||
lv_area_t area;
|
||||
volatile uint32_t flushing :1;
|
||||
}lv_disp_buf_t;
|
||||
|
||||
volatile uint32_t flushing : 1;
|
||||
} lv_disp_buf_t;
|
||||
|
||||
/**
|
||||
* Display Driver structure to be registered by HAL
|
||||
*/
|
||||
typedef struct _disp_drv_t {
|
||||
typedef struct _disp_drv_t
|
||||
{
|
||||
|
||||
/*Horizontal and vertical resolution*/
|
||||
lv_coord_t hor_res;
|
||||
@ -69,11 +68,12 @@ typedef struct _disp_drv_t {
|
||||
lv_disp_buf_t * buffer;
|
||||
|
||||
#if LV_ANTIALIAS
|
||||
uint32_t antialiasing :1;
|
||||
uint32_t antialiasing : 1;
|
||||
#endif
|
||||
uint32_t rotated :1; /*1: turn the display by 90 degree.*/
|
||||
uint32_t rotated : 1; /*1: turn the display by 90 degree.*/
|
||||
|
||||
/* MANDATORY: Write the internal buffer (VDB) to the display. 'lv_disp_flush_ready()' has to be called when finished */
|
||||
/* MANDATORY: Write the internal buffer (VDB) to the display. 'lv_disp_flush_ready()' has to be
|
||||
* called when finished */
|
||||
void (*flush_cb)(struct _disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p);
|
||||
|
||||
/* OPTIONAL: Extend the invalidated areas to match with the display drivers requirements
|
||||
@ -83,12 +83,13 @@ typedef struct _disp_drv_t {
|
||||
/* OPTIONAL: Set a pixel in a buffer according to the special requirements of the display
|
||||
* Can be used for color format not supported in LittelvGL. E.g. 2 bit -> 4 gray scales
|
||||
* Note: Much slower then drawing with supported color formats. */
|
||||
void (*set_px_cb)(struct _disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y, lv_color_t color, lv_opa_t opa);
|
||||
void (*set_px_cb)(struct _disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w, lv_coord_t x,
|
||||
lv_coord_t y, lv_color_t color, lv_opa_t opa);
|
||||
|
||||
/* OPTIONAL: Called after every refresh cycle to tell the rendering and flushing time + the number of flushed pixels */
|
||||
/* OPTIONAL: Called after every refresh cycle to tell the rendering and flushing time + the
|
||||
* number of flushed pixels */
|
||||
void (*monitor_cb)(struct _disp_drv_t * disp_drv, uint32_t time, uint32_t px);
|
||||
|
||||
|
||||
#if LV_USE_USER_DATA_SINGLE
|
||||
lv_disp_drv_user_data_t user_data;
|
||||
#endif
|
||||
@ -112,7 +113,8 @@ typedef struct _disp_drv_t {
|
||||
|
||||
struct _lv_obj_t;
|
||||
|
||||
typedef struct _disp_t {
|
||||
typedef struct _disp_t
|
||||
{
|
||||
/*Driver to the display*/
|
||||
lv_disp_drv_t driver;
|
||||
|
||||
@ -128,7 +130,7 @@ typedef struct _disp_t {
|
||||
/*Invalidated (marked to redraw) areas*/
|
||||
lv_area_t inv_areas[LV_INV_BUF_SIZE];
|
||||
uint8_t inv_area_joined[LV_INV_BUF_SIZE];
|
||||
uint32_t inv_p :10;
|
||||
uint32_t inv_p : 10;
|
||||
|
||||
/*Miscellaneous data*/
|
||||
uint32_t last_activity_time;
|
||||
@ -146,7 +148,6 @@ typedef struct _disp_t {
|
||||
*/
|
||||
void lv_disp_drv_init(lv_disp_drv_t * driver);
|
||||
|
||||
|
||||
/**
|
||||
* Initialize a display buffer
|
||||
* @param disp_buf pointer `lv_disp_buf_t` variable to initialize
|
||||
@ -158,8 +159,8 @@ void lv_disp_drv_init(lv_disp_drv_t * driver);
|
||||
* (sending to the display) parallel.
|
||||
* In the `disp_drv->flush` you should use DMA or similar hardware to send
|
||||
* the image to the display in the background.
|
||||
* It lets LittlevGL to render next frame into the other buffer while previous is being sent.
|
||||
* Set to `NULL` if unused.
|
||||
* It lets LittlevGL to render next frame into the other buffer while previous is being
|
||||
* sent. Set to `NULL` if unused.
|
||||
* @param size size of the `buf1` and `buf2` in pixel count.
|
||||
*/
|
||||
void lv_disp_buf_init(lv_disp_buf_t * disp_buf, void * buf1, void * buf2, uint32_t size);
|
||||
@ -224,7 +225,6 @@ bool lv_disp_get_antialiasing(lv_disp_t * disp);
|
||||
*/
|
||||
LV_ATTRIBUTE_FLUSH_READY void lv_disp_flush_ready(lv_disp_drv_t * disp_drv);
|
||||
|
||||
|
||||
/**
|
||||
* Get the next display.
|
||||
* @param disp pointer to the current display. NULL to initialize.
|
||||
@ -259,7 +259,8 @@ void lv_disp_pop_from_inv_buf(lv_disp_t * disp, uint16_t num);
|
||||
bool lv_disp_is_double_buf(lv_disp_t * disp);
|
||||
|
||||
/**
|
||||
* Check the driver configuration if it's TRUE double buffered (both `buf1` and `buf2` are set and `size` is screen sized)
|
||||
* Check the driver configuration if it's TRUE double buffered (both `buf1` and `buf2` are set and
|
||||
* `size` is screen sized)
|
||||
* @param disp pointer to to display to check
|
||||
* @return true: double buffered; false: not double buffered
|
||||
*/
|
||||
|
@ -15,10 +15,9 @@
|
||||
#include "lv_hal_disp.h"
|
||||
|
||||
#if defined(LV_GC_INCLUDE)
|
||||
# include LV_GC_INCLUDE
|
||||
#include LV_GC_INCLUDE
|
||||
#endif /* LV_ENABLE_GC */
|
||||
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
@ -53,10 +52,10 @@ void lv_indev_drv_init(lv_indev_drv_t * driver)
|
||||
{
|
||||
memset(driver, 0, sizeof(lv_indev_drv_t));
|
||||
|
||||
driver->type = LV_INDEV_TYPE_NONE;
|
||||
driver->drag_limit = LV_INDEV_DEF_DRAG_LIMIT;
|
||||
driver->drag_throw = LV_INDEV_DEF_DRAG_THROW;
|
||||
driver->long_press_time = LV_INDEV_DEF_LONG_PRESS_TIME;
|
||||
driver->type = LV_INDEV_TYPE_NONE;
|
||||
driver->drag_limit = LV_INDEV_DEF_DRAG_LIMIT;
|
||||
driver->drag_throw = LV_INDEV_DEF_DRAG_THROW;
|
||||
driver->long_press_time = LV_INDEV_DEF_LONG_PRESS_TIME;
|
||||
driver->long_press_rep_time = LV_INDEV_DEF_LONG_PRESS_REP_TIME;
|
||||
}
|
||||
|
||||
@ -71,7 +70,8 @@ lv_indev_t * lv_indev_drv_register(lv_indev_drv_t * driver)
|
||||
if(driver->disp == NULL) driver->disp = lv_disp_get_default();
|
||||
|
||||
if(driver->disp == NULL) {
|
||||
LV_LOG_WARN("lv_indev_drv_register: no display registered hence can't attache the indev to a display");
|
||||
LV_LOG_WARN("lv_indev_drv_register: no display registered hence can't attache the indev to "
|
||||
"a display");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -85,11 +85,12 @@ lv_indev_t * lv_indev_drv_register(lv_indev_drv_t * driver)
|
||||
memcpy(&indev->driver, driver, sizeof(lv_indev_drv_t));
|
||||
|
||||
indev->proc.reset_query = 1;
|
||||
indev->cursor = NULL;
|
||||
indev->group = NULL;
|
||||
indev->btn_points = NULL;
|
||||
indev->cursor = NULL;
|
||||
indev->group = NULL;
|
||||
indev->btn_points = NULL;
|
||||
|
||||
indev->driver.read_task = lv_task_create(lv_indev_read_task, LV_INDEV_DEF_READ_PERIOD, LV_TASK_PRIO_MID, indev);
|
||||
indev->driver.read_task =
|
||||
lv_task_create(lv_indev_read_task, LV_INDEV_DEF_READ_PERIOD, LV_TASK_PRIO_MID, indev);
|
||||
|
||||
return indev;
|
||||
}
|
||||
@ -107,12 +108,15 @@ void lv_indev_drv_update(lv_indev_t * indev, lv_indev_drv_t * new_drv)
|
||||
/**
|
||||
* Get the next input device.
|
||||
* @param indev pointer to the current input device. NULL to initialize.
|
||||
* @return the next input devise or NULL if no more. Give the first input device when the parameter is NULL
|
||||
* @return the next input devise or NULL if no more. Give the first input device when the parameter
|
||||
* is NULL
|
||||
*/
|
||||
lv_indev_t * lv_indev_get_next(lv_indev_t * indev)
|
||||
{
|
||||
if(indev == NULL) return lv_ll_get_head(&LV_GC_ROOT(_lv_indev_ll));
|
||||
else return lv_ll_get_next(&LV_GC_ROOT(_lv_indev_ll), indev);
|
||||
if(indev == NULL)
|
||||
return lv_ll_get_head(&LV_GC_ROOT(_lv_indev_ll));
|
||||
else
|
||||
return lv_ll_get_next(&LV_GC_ROOT(_lv_indev_ll), indev);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -41,40 +41,41 @@ struct _lv_indev_drv_t;
|
||||
|
||||
/*Possible input device types*/
|
||||
enum {
|
||||
LV_INDEV_TYPE_NONE, /*Show uninitialized state*/
|
||||
LV_INDEV_TYPE_POINTER, /*Touch pad, mouse, external button*/
|
||||
LV_INDEV_TYPE_KEYPAD, /*Keypad or keyboard*/
|
||||
LV_INDEV_TYPE_BUTTON, /*External (hardware button) which is assinged to a specific point of the screen*/
|
||||
LV_INDEV_TYPE_ENCODER, /*Encoder with only Left, Right turn and a Button*/
|
||||
LV_INDEV_TYPE_NONE, /*Show uninitialized state*/
|
||||
LV_INDEV_TYPE_POINTER, /*Touch pad, mouse, external button*/
|
||||
LV_INDEV_TYPE_KEYPAD, /*Keypad or keyboard*/
|
||||
LV_INDEV_TYPE_BUTTON, /*External (hardware button) which is assinged to a specific point of the
|
||||
screen*/
|
||||
LV_INDEV_TYPE_ENCODER, /*Encoder with only Left, Right turn and a Button*/
|
||||
};
|
||||
typedef uint8_t lv_indev_type_t;
|
||||
|
||||
/*States for input devices*/
|
||||
enum {
|
||||
LV_INDEV_STATE_REL = 0,
|
||||
LV_INDEV_STATE_PR
|
||||
};
|
||||
enum { LV_INDEV_STATE_REL = 0, LV_INDEV_STATE_PR };
|
||||
typedef uint8_t lv_indev_state_t;
|
||||
|
||||
/*Data type when an input device is read */
|
||||
typedef struct {
|
||||
lv_point_t point; /*For LV_INDEV_TYPE_POINTER the currently pressed point*/
|
||||
uint32_t key; /*For LV_INDEV_TYPE_KEYPAD the currently pressed key*/
|
||||
uint32_t btn_id; /*For LV_INDEV_TYPE_BUTTON the currently pressed button*/
|
||||
int16_t enc_diff; /*For LV_INDEV_TYPE_ENCODER number of steps since the previous read*/
|
||||
typedef struct
|
||||
{
|
||||
lv_point_t point; /*For LV_INDEV_TYPE_POINTER the currently pressed point*/
|
||||
uint32_t key; /*For LV_INDEV_TYPE_KEYPAD the currently pressed key*/
|
||||
uint32_t btn_id; /*For LV_INDEV_TYPE_BUTTON the currently pressed button*/
|
||||
int16_t enc_diff; /*For LV_INDEV_TYPE_ENCODER number of steps since the previous read*/
|
||||
|
||||
lv_indev_state_t state; /*LV_INDEV_STATE_REL or LV_INDEV_STATE_PR*/
|
||||
lv_indev_state_t state; /*LV_INDEV_STATE_REL or LV_INDEV_STATE_PR*/
|
||||
|
||||
} lv_indev_data_t;
|
||||
|
||||
/*Initialized by the user and registered by 'lv_indev_add()'*/
|
||||
typedef struct _lv_indev_drv_t {
|
||||
typedef struct _lv_indev_drv_t
|
||||
{
|
||||
|
||||
/*Input device type*/
|
||||
lv_indev_type_t type;
|
||||
|
||||
/*Function pointer to read_cb data. Return 'true' if there is still data to be read_cb (buffered)*/
|
||||
bool (*read_cb)(struct _lv_indev_drv_t * indev_drv, lv_indev_data_t *data);
|
||||
/*Function pointer to read_cb data. Return 'true' if there is still data to be read_cb
|
||||
* (buffered)*/
|
||||
bool (*read_cb)(struct _lv_indev_drv_t * indev_drv, lv_indev_data_t * data);
|
||||
|
||||
#if LV_USE_USER_DATA_MULTI
|
||||
lv_indev_drv_user_data_t read_user_data;
|
||||
@ -103,39 +104,43 @@ typedef struct _lv_indev_drv_t {
|
||||
uint16_t long_press_rep_time;
|
||||
} lv_indev_drv_t;
|
||||
|
||||
|
||||
/*Run time data of input devices*/
|
||||
typedef struct _lv_indev_proc_t {
|
||||
typedef struct _lv_indev_proc_t
|
||||
{
|
||||
lv_indev_state_t state;
|
||||
union {
|
||||
struct { /*Pointer and button data*/
|
||||
union
|
||||
{
|
||||
struct
|
||||
{ /*Pointer and button data*/
|
||||
lv_point_t act_point;
|
||||
lv_point_t last_point;
|
||||
lv_point_t vect;
|
||||
lv_point_t drag_sum; /*Count the dragged pixels to check LV_INDEV_DEF_DRAG_LIMIT*/
|
||||
lv_point_t drag_sum; /*Count the dragged pixels to check LV_INDEV_DEF_DRAG_LIMIT*/
|
||||
lv_point_t drag_throw_vect;
|
||||
struct _lv_obj_t * act_obj; /*The object being pressed*/
|
||||
struct _lv_obj_t * last_obj; /*The last obejct which was pressed (used by dragthrow and other post-release event)*/
|
||||
struct _lv_obj_t * last_pressed; /*The lastly pressed object*/
|
||||
struct _lv_obj_t * act_obj; /*The object being pressed*/
|
||||
struct _lv_obj_t * last_obj; /*The last obejct which was pressed (used by dragthrow and
|
||||
other post-release event)*/
|
||||
struct _lv_obj_t * last_pressed; /*The lastly pressed object*/
|
||||
|
||||
/*Flags*/
|
||||
uint8_t drag_limit_out :1;
|
||||
uint8_t drag_in_prog :1;
|
||||
}pointer;
|
||||
struct { /*Keypad data*/
|
||||
uint8_t drag_limit_out : 1;
|
||||
uint8_t drag_in_prog : 1;
|
||||
} pointer;
|
||||
struct
|
||||
{ /*Keypad data*/
|
||||
lv_indev_state_t last_state;
|
||||
uint32_t last_key;
|
||||
}keypad;
|
||||
}types;
|
||||
} keypad;
|
||||
} types;
|
||||
|
||||
uint32_t pr_timestamp; /*Pressed time stamp*/
|
||||
uint32_t longpr_rep_timestamp; /*Long press repeat time stamp*/
|
||||
uint32_t pr_timestamp; /*Pressed time stamp*/
|
||||
uint32_t longpr_rep_timestamp; /*Long press repeat time stamp*/
|
||||
|
||||
/*Flags*/
|
||||
uint8_t long_pr_sent :1;
|
||||
uint8_t reset_query :1;
|
||||
uint8_t disabled :1;
|
||||
uint8_t wait_until_release :1;
|
||||
uint8_t long_pr_sent : 1;
|
||||
uint8_t reset_query : 1;
|
||||
uint8_t disabled : 1;
|
||||
uint8_t wait_until_release : 1;
|
||||
} lv_indev_proc_t;
|
||||
|
||||
typedef void (*lv_indev_feedback_t)(struct _lv_indev_t *, uint8_t);
|
||||
@ -143,14 +148,17 @@ typedef void (*lv_indev_feedback_t)(struct _lv_indev_t *, uint8_t);
|
||||
struct _lv_obj_t;
|
||||
struct _lv_group_t;
|
||||
|
||||
/*The main input device descriptor with driver, runtime data ('proc') and some additional information*/
|
||||
typedef struct _lv_indev_t {
|
||||
/*The main input device descriptor with driver, runtime data ('proc') and some additional
|
||||
* information*/
|
||||
typedef struct _lv_indev_t
|
||||
{
|
||||
lv_indev_drv_t driver;
|
||||
lv_indev_proc_t proc;
|
||||
lv_indev_feedback_t feedback;
|
||||
struct _lv_obj_t *cursor; /*Cursor for LV_INPUT_TYPE_POINTER*/
|
||||
struct _lv_group_t *group; /*Keypad destination group*/
|
||||
const lv_point_t * btn_points; /*Array points assigned to the button ()screen will be pressed here by the buttons*/
|
||||
struct _lv_obj_t * cursor; /*Cursor for LV_INPUT_TYPE_POINTER*/
|
||||
struct _lv_group_t * group; /*Keypad destination group*/
|
||||
const lv_point_t * btn_points; /*Array points assigned to the button ()screen will be pressed
|
||||
here by the buttons*/
|
||||
} lv_indev_t;
|
||||
|
||||
/**********************
|
||||
@ -163,14 +171,14 @@ typedef struct _lv_indev_t {
|
||||
* After it you can set the fields.
|
||||
* @param driver pointer to driver variable to initialize
|
||||
*/
|
||||
void lv_indev_drv_init(lv_indev_drv_t *driver);
|
||||
void lv_indev_drv_init(lv_indev_drv_t * driver);
|
||||
|
||||
/**
|
||||
* Register an initialized input device driver.
|
||||
* @param driver pointer to an initialized 'lv_indev_drv_t' variable (can be local variable)
|
||||
* @return pointer to the new input device or NULL on error
|
||||
*/
|
||||
lv_indev_t * lv_indev_drv_register(lv_indev_drv_t *driver);
|
||||
lv_indev_t * lv_indev_drv_register(lv_indev_drv_t * driver);
|
||||
|
||||
/**
|
||||
* Update the driver in run time.
|
||||
@ -182,7 +190,8 @@ void lv_indev_drv_update(lv_indev_t * indev, lv_indev_drv_t * new_drv);
|
||||
/**
|
||||
* Get the next input device.
|
||||
* @param indev pointer to the current input device. NULL to initialize.
|
||||
* @return the next input devise or NULL if no more. Give the first input device when the parameter is NULL
|
||||
* @return the next input devise or NULL if no more. Give the first input device when the parameter
|
||||
* is NULL
|
||||
*/
|
||||
lv_indev_t * lv_indev_get_next(lv_indev_t * indev);
|
||||
|
||||
@ -192,7 +201,7 @@ lv_indev_t * lv_indev_get_next(lv_indev_t * indev);
|
||||
* @param data input device will write its data here
|
||||
* @return false: no more data; true: there more data to read (buffered)
|
||||
*/
|
||||
bool lv_indev_read(lv_indev_t * indev, lv_indev_data_t *data);
|
||||
bool lv_indev_read(lv_indev_t * indev, lv_indev_data_t * data);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
|
@ -65,8 +65,9 @@ uint32_t lv_tick_get(void)
|
||||
uint32_t result;
|
||||
do {
|
||||
tick_irq_flag = 1;
|
||||
result = sys_time;
|
||||
} while(!tick_irq_flag); /*'lv_tick_inc()' clears this flag which can be in an interrupt. Continue until make a non interrupted cycle */
|
||||
result = sys_time;
|
||||
} while(!tick_irq_flag); /*'lv_tick_inc()' clears this flag which can be in an interrupt.
|
||||
Continue until make a non interrupted cycle */
|
||||
|
||||
return result;
|
||||
#else
|
||||
@ -97,4 +98,3 @@ uint32_t lv_tick_elaps(uint32_t prev_tick)
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
|
@ -63,4 +63,4 @@ uint32_t lv_tick_elaps(uint32_t prev_tick);
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_HAL_TICK_H*/
|
||||
#endif /*LV_HAL_TICK_H*/
|
||||
|
@ -17,15 +17,14 @@
|
||||
#include "lv_gc.h"
|
||||
|
||||
#if defined(LV_GC_INCLUDE)
|
||||
# include LV_GC_INCLUDE
|
||||
#include LV_GC_INCLUDE
|
||||
#endif /* LV_ENABLE_GC */
|
||||
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define LV_ANIM_RESOLUTION 1024
|
||||
#define LV_ANIM_RES_SHIFT 10
|
||||
#define LV_ANIM_RESOLUTION 1024
|
||||
#define LV_ANIM_RES_SHIFT 10
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
@ -69,7 +68,8 @@ void lv_anim_create(lv_anim_t * anim_p)
|
||||
{
|
||||
LV_LOG_TRACE("animation create started")
|
||||
/* Do not let two animations for the same 'var' with the same 'fp'*/
|
||||
if(anim_p->fp != NULL) lv_anim_del(anim_p->var, anim_p->fp); /*fp == NULL would delete all animations of var*/
|
||||
if(anim_p->fp != NULL)
|
||||
lv_anim_del(anim_p->var, anim_p->fp); /*fp == NULL would delete all animations of var*/
|
||||
|
||||
/*Add the new animation to the animation linked list*/
|
||||
lv_anim_t * new_anim = lv_ll_ins_head(&LV_GC_ROOT(_lv_anim_ll));
|
||||
@ -102,7 +102,7 @@ bool lv_anim_del(void * var, lv_anim_fp_t fp)
|
||||
lv_anim_t * a;
|
||||
lv_anim_t * a_next;
|
||||
bool del = false;
|
||||
a = lv_ll_get_head(&LV_GC_ROOT(_lv_anim_ll));
|
||||
a = lv_ll_get_head(&LV_GC_ROOT(_lv_anim_ll));
|
||||
while(a != NULL) {
|
||||
/*'a' might be deleted, so get the next object while 'a' is valid*/
|
||||
a_next = lv_ll_get_next(&LV_GC_ROOT(_lv_anim_ll), a);
|
||||
@ -110,7 +110,8 @@ bool lv_anim_del(void * var, lv_anim_fp_t fp)
|
||||
if(a->var == var && (a->fp == fp || fp == NULL)) {
|
||||
lv_ll_rem(&LV_GC_ROOT(_lv_anim_ll), a);
|
||||
lv_mem_free(a);
|
||||
anim_list_changed = true; /*Read by `anim_task`. It need to know if a delete occurred in the linked list*/
|
||||
anim_list_changed = true; /*Read by `anim_task`. It need to know if a delete occurred in
|
||||
the linked list*/
|
||||
del = true;
|
||||
}
|
||||
|
||||
@ -142,7 +143,7 @@ uint16_t lv_anim_count_running(void)
|
||||
*/
|
||||
uint16_t lv_anim_speed_to_time(uint16_t speed, int32_t start, int32_t end)
|
||||
{
|
||||
int32_t d = LV_MATH_ABS((int32_t) start - end);
|
||||
int32_t d = LV_MATH_ABS((int32_t)start - end);
|
||||
uint32_t time = (int32_t)((int32_t)(d * 1000) / speed);
|
||||
|
||||
if(time > UINT16_MAX) time = UINT16_MAX;
|
||||
@ -163,13 +164,15 @@ int32_t lv_anim_path_linear(const lv_anim_t * a)
|
||||
{
|
||||
/*Calculate the current step*/
|
||||
uint16_t step;
|
||||
if(a->time == a->act_time) step = LV_ANIM_RESOLUTION; /*Use the last value if the time fully elapsed*/
|
||||
else step = (a->act_time * LV_ANIM_RESOLUTION) / a->time;
|
||||
if(a->time == a->act_time)
|
||||
step = LV_ANIM_RESOLUTION; /*Use the last value if the time fully elapsed*/
|
||||
else
|
||||
step = (a->act_time * LV_ANIM_RESOLUTION) / a->time;
|
||||
|
||||
/* Get the new value which will be proportional to `step`
|
||||
* and the `start` and `end` values*/
|
||||
int32_t new_value;
|
||||
new_value = (int32_t) step * (a->end - a->start);
|
||||
new_value = (int32_t)step * (a->end - a->start);
|
||||
new_value = new_value >> LV_ANIM_RES_SHIFT;
|
||||
new_value += a->start;
|
||||
|
||||
@ -185,17 +188,18 @@ int32_t lv_anim_path_ease_in(const lv_anim_t * a)
|
||||
{
|
||||
/*Calculate the current step*/
|
||||
uint32_t t;
|
||||
if(a->time == a->act_time) t = 1024;
|
||||
else t = (uint32_t)((uint32_t)a->act_time * 1024) / a->time;
|
||||
if(a->time == a->act_time)
|
||||
t = 1024;
|
||||
else
|
||||
t = (uint32_t)((uint32_t)a->act_time * 1024) / a->time;
|
||||
|
||||
int32_t step = lv_bezier3(t, 0, 1, 1, 1024);
|
||||
|
||||
int32_t new_value;
|
||||
new_value = (int32_t) step * (a->end - a->start);
|
||||
new_value = (int32_t)step * (a->end - a->start);
|
||||
new_value = new_value >> 10;
|
||||
new_value += a->start;
|
||||
|
||||
|
||||
return new_value;
|
||||
}
|
||||
|
||||
@ -209,17 +213,18 @@ int32_t lv_anim_path_ease_out(const lv_anim_t * a)
|
||||
/*Calculate the current step*/
|
||||
|
||||
uint32_t t;
|
||||
if(a->time == a->act_time) t = 1024;
|
||||
else t = (uint32_t)((uint32_t)a->act_time * 1024) / a->time;
|
||||
if(a->time == a->act_time)
|
||||
t = 1024;
|
||||
else
|
||||
t = (uint32_t)((uint32_t)a->act_time * 1024) / a->time;
|
||||
|
||||
int32_t step = lv_bezier3(t, 0, 1023, 1023, 1024);
|
||||
|
||||
int32_t new_value;
|
||||
new_value = (int32_t) step * (a->end - a->start);
|
||||
new_value = (int32_t)step * (a->end - a->start);
|
||||
new_value = new_value >> 10;
|
||||
new_value += a->start;
|
||||
|
||||
|
||||
return new_value;
|
||||
}
|
||||
|
||||
@ -233,17 +238,18 @@ int32_t lv_anim_path_ease_in_out(const lv_anim_t * a)
|
||||
/*Calculate the current step*/
|
||||
|
||||
uint32_t t;
|
||||
if(a->time == a->act_time) t = 1024;
|
||||
else t = (uint32_t)((uint32_t)a->act_time * 1024) / a->time;
|
||||
if(a->time == a->act_time)
|
||||
t = 1024;
|
||||
else
|
||||
t = (uint32_t)((uint32_t)a->act_time * 1024) / a->time;
|
||||
|
||||
int32_t step = lv_bezier3(t, 0, 100, 924, 1024);
|
||||
|
||||
int32_t new_value;
|
||||
new_value = (int32_t) step * (a->end - a->start);
|
||||
new_value = (int32_t)step * (a->end - a->start);
|
||||
new_value = new_value >> 10;
|
||||
new_value += a->start;
|
||||
|
||||
|
||||
return new_value;
|
||||
}
|
||||
|
||||
@ -257,17 +263,18 @@ int32_t lv_anim_path_overshoot(const lv_anim_t * a)
|
||||
/*Calculate the current step*/
|
||||
|
||||
uint32_t t;
|
||||
if(a->time == a->act_time) t = 1024;
|
||||
else t = (uint32_t)((uint32_t)a->act_time * 1024) / a->time;
|
||||
if(a->time == a->act_time)
|
||||
t = 1024;
|
||||
else
|
||||
t = (uint32_t)((uint32_t)a->act_time * 1024) / a->time;
|
||||
|
||||
int32_t step = lv_bezier3(t, 0, 600, 1300, 1024);
|
||||
|
||||
int32_t new_value;
|
||||
new_value = (int32_t) step * (a->end - a->start);
|
||||
new_value = (int32_t)step * (a->end - a->start);
|
||||
new_value = new_value >> 10;
|
||||
new_value += a->start;
|
||||
|
||||
|
||||
return new_value;
|
||||
}
|
||||
|
||||
@ -280,41 +287,39 @@ int32_t lv_anim_path_bounce(const lv_anim_t * a)
|
||||
{
|
||||
/*Calculate the current step*/
|
||||
uint32_t t;
|
||||
if(a->time == a->act_time) t = 1024;
|
||||
else t = (uint32_t)((uint32_t)a->act_time * 1024) / a->time;
|
||||
if(a->time == a->act_time)
|
||||
t = 1024;
|
||||
else
|
||||
t = (uint32_t)((uint32_t)a->act_time * 1024) / a->time;
|
||||
|
||||
int32_t diff = (a->end - a->start);
|
||||
|
||||
/*3 bounces has 5 parts: 3 down and 2 up. One part is t / 5 long*/
|
||||
|
||||
if(t < 408){
|
||||
if(t < 408) {
|
||||
/*Go down*/
|
||||
t = (t * 2500) >> 10; /*[0..1024] range*/
|
||||
}
|
||||
else if(t >= 408 && t < 614) {
|
||||
t = (t * 2500) >> 10; /*[0..1024] range*/
|
||||
} else if(t >= 408 && t < 614) {
|
||||
/*First bounce back*/
|
||||
t -= 408;
|
||||
t = t * 5; /*to [0..1024] range*/
|
||||
t = 1024 - t;
|
||||
t = t * 5; /*to [0..1024] range*/
|
||||
t = 1024 - t;
|
||||
diff = diff / 6;
|
||||
}
|
||||
else if(t >= 614 && t < 819) {
|
||||
} else if(t >= 614 && t < 819) {
|
||||
/*Fall back*/
|
||||
t -= 614;
|
||||
t = t * 5; /*to [0..1024] range*/
|
||||
t = t * 5; /*to [0..1024] range*/
|
||||
diff = diff / 6;
|
||||
}
|
||||
else if(t >= 819 && t < 921) {
|
||||
} else if(t >= 819 && t < 921) {
|
||||
/*Second bounce back*/
|
||||
t -= 819;
|
||||
t = t * 10; /*to [0..1024] range*/
|
||||
t = 1024 - t;
|
||||
t = t * 10; /*to [0..1024] range*/
|
||||
t = 1024 - t;
|
||||
diff = diff / 16;
|
||||
}
|
||||
else if(t >= 921 && t <= 1024) {
|
||||
} else if(t >= 921 && t <= 1024) {
|
||||
/*Fall back*/
|
||||
t -= 921;
|
||||
t = t * 10; /*to [0..1024] range*/
|
||||
t = t * 10; /*to [0..1024] range*/
|
||||
diff = diff / 16;
|
||||
}
|
||||
|
||||
@ -324,11 +329,10 @@ int32_t lv_anim_path_bounce(const lv_anim_t * a)
|
||||
|
||||
int32_t new_value;
|
||||
|
||||
new_value = (int32_t) step * diff;
|
||||
new_value = (int32_t)step * diff;
|
||||
new_value = new_value >> 10;
|
||||
new_value = a->end - new_value;
|
||||
|
||||
|
||||
return new_value;
|
||||
}
|
||||
|
||||
@ -340,8 +344,10 @@ int32_t lv_anim_path_bounce(const lv_anim_t * a)
|
||||
*/
|
||||
int32_t lv_anim_path_step(const lv_anim_t * a)
|
||||
{
|
||||
if(a->act_time >= a->time) return a->end;
|
||||
else return a->start;
|
||||
if(a->act_time >= a->time)
|
||||
return a->end;
|
||||
else
|
||||
return a->start;
|
||||
}
|
||||
|
||||
/**********************
|
||||
@ -357,21 +363,24 @@ static void anim_task(void * param)
|
||||
(void)param;
|
||||
|
||||
lv_anim_t * a;
|
||||
LV_LL_READ(LV_GC_ROOT(_lv_anim_ll), a) {
|
||||
LV_LL_READ(LV_GC_ROOT(_lv_anim_ll), a)
|
||||
{
|
||||
a->has_run = 0;
|
||||
}
|
||||
|
||||
uint32_t elaps = lv_tick_elaps(last_task_run);
|
||||
a = lv_ll_get_head(&LV_GC_ROOT(_lv_anim_ll));
|
||||
a = lv_ll_get_head(&LV_GC_ROOT(_lv_anim_ll));
|
||||
|
||||
while(a != NULL) {
|
||||
/*It can be set by `lv_anim_del()` typically in `end_cb`. If set then an animation delete happened in `anim_ready_handler`
|
||||
* which could make this linked list reading corrupt because the list is changed meanwhile
|
||||
/*It can be set by `lv_anim_del()` typically in `end_cb`. If set then an animation delete
|
||||
* happened in `anim_ready_handler` which could make this linked list reading corrupt
|
||||
* because the list is changed meanwhile
|
||||
*/
|
||||
anim_list_changed = false;
|
||||
|
||||
if(!a->has_run) {
|
||||
a->has_run = 1; /*The list readying might be reseted so need to know which anim has run already*/
|
||||
a->has_run =
|
||||
1; /*The list readying might be reseted so need to know which anim has run already*/
|
||||
a->act_time += elaps;
|
||||
if(a->act_time >= 0) {
|
||||
if(a->act_time > a->time) a->act_time = a->time;
|
||||
@ -390,8 +399,10 @@ static void anim_task(void * param)
|
||||
|
||||
/* If the linked list changed due to anim. delete then it's not safe to continue
|
||||
* the reading of the list from here -> start from the head*/
|
||||
if(anim_list_changed) a = lv_ll_get_head(&LV_GC_ROOT(_lv_anim_ll));
|
||||
else a = lv_ll_get_next(&LV_GC_ROOT(_lv_anim_ll), a);
|
||||
if(anim_list_changed)
|
||||
a = lv_ll_get_head(&LV_GC_ROOT(_lv_anim_ll));
|
||||
else
|
||||
a = lv_ll_get_next(&LV_GC_ROOT(_lv_anim_ll), a);
|
||||
}
|
||||
|
||||
last_task_run = lv_tick_get();
|
||||
@ -410,9 +421,9 @@ static bool anim_ready_handler(lv_anim_t * a)
|
||||
* - no repeat and no play back (simple one shot animation)
|
||||
* - no repeat, play back is enabled and play back is ready */
|
||||
if((a->repeat == 0 && a->playback == 0) ||
|
||||
(a->repeat == 0 && a->playback == 1 && a->playback_now == 1)) {
|
||||
(a->repeat == 0 && a->playback == 1 && a->playback_now == 1)) {
|
||||
void (*cb)(void *) = a->end_cb;
|
||||
void * p = a->var;
|
||||
void * p = a->var;
|
||||
lv_ll_rem(&LV_GC_ROOT(_lv_anim_ll), a);
|
||||
lv_mem_free(a);
|
||||
anim_list_changed = true;
|
||||
@ -424,19 +435,19 @@ static bool anim_ready_handler(lv_anim_t * a)
|
||||
}
|
||||
/*If the animation is not deleted then restart it*/
|
||||
else {
|
||||
a->act_time = - a->repeat_pause; /*Restart the animation*/
|
||||
a->act_time = -a->repeat_pause; /*Restart the animation*/
|
||||
/*Swap the start and end values in play back mode*/
|
||||
if(a->playback != 0) {
|
||||
/*If now turning back use the 'playback_pause*/
|
||||
if(a->playback_now == 0) a->act_time = - a->playback_pause;
|
||||
if(a->playback_now == 0) a->act_time = -a->playback_pause;
|
||||
|
||||
/*Toggle the play back state*/
|
||||
a->playback_now = a->playback_now == 0 ? 1 : 0;
|
||||
/*Swap the start and end values*/
|
||||
int32_t tmp;
|
||||
tmp = a->start;
|
||||
tmp = a->start;
|
||||
a->start = a->end;
|
||||
a->end = tmp;
|
||||
a->end = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -10,7 +10,6 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
@ -35,28 +34,28 @@ extern "C" {
|
||||
|
||||
struct _lv_anim_t;
|
||||
|
||||
typedef int32_t(*lv_anim_path_t)(const struct _lv_anim_t*);
|
||||
typedef int32_t (*lv_anim_path_t)(const struct _lv_anim_t *);
|
||||
|
||||
typedef void (*lv_anim_fp_t)(void *, int32_t);
|
||||
typedef void (*lv_anim_cb_t)(void *);
|
||||
|
||||
typedef struct _lv_anim_t
|
||||
{
|
||||
void * var; /*Variable to animate*/
|
||||
lv_anim_fp_t fp; /*Animator function*/
|
||||
lv_anim_cb_t end_cb; /*Call it when the animation is ready*/
|
||||
lv_anim_path_t path; /*An array with the steps of animations*/
|
||||
int32_t start; /*Start value*/
|
||||
int32_t end; /*End value*/
|
||||
uint16_t time; /*Animation time in ms*/
|
||||
int16_t act_time; /*Current time in animation. Set to negative to make delay.*/
|
||||
uint16_t playback_pause; /*Wait before play back*/
|
||||
uint16_t repeat_pause; /*Wait before repeat*/
|
||||
uint8_t playback :1; /*When the animation is ready play it back*/
|
||||
uint8_t repeat :1; /*Repeat the animation infinitely*/
|
||||
void * var; /*Variable to animate*/
|
||||
lv_anim_fp_t fp; /*Animator function*/
|
||||
lv_anim_cb_t end_cb; /*Call it when the animation is ready*/
|
||||
lv_anim_path_t path; /*An array with the steps of animations*/
|
||||
int32_t start; /*Start value*/
|
||||
int32_t end; /*End value*/
|
||||
uint16_t time; /*Animation time in ms*/
|
||||
int16_t act_time; /*Current time in animation. Set to negative to make delay.*/
|
||||
uint16_t playback_pause; /*Wait before play back*/
|
||||
uint16_t repeat_pause; /*Wait before repeat*/
|
||||
uint8_t playback : 1; /*When the animation is ready play it back*/
|
||||
uint8_t repeat : 1; /*Repeat the animation infinitely*/
|
||||
/*Animation system use these - user shouldn't set*/
|
||||
uint8_t playback_now :1; /*Play back is in progress*/
|
||||
uint32_t has_run :1; /*Indicates the animation has run it this round*/
|
||||
uint8_t playback_now : 1; /*Play back is in progress*/
|
||||
uint32_t has_run : 1; /*Indicates the animation has run it this round*/
|
||||
} lv_anim_t;
|
||||
|
||||
/*Example initialization
|
||||
@ -119,7 +118,7 @@ uint16_t lv_anim_speed_to_time(uint16_t speed, int32_t start, int32_t end);
|
||||
* @param a pointer to an animation
|
||||
* @return the current value to set
|
||||
*/
|
||||
int32_t lv_anim_path_linear(const lv_anim_t *a);
|
||||
int32_t lv_anim_path_linear(const lv_anim_t * a);
|
||||
|
||||
/**
|
||||
* Calculate the current value of an animation slowing down the start phase
|
||||
@ -140,7 +139,7 @@ int32_t lv_anim_path_ease_out(const lv_anim_t * a);
|
||||
* @param a pointer to an animation
|
||||
* @return the current value to set
|
||||
*/
|
||||
int32_t lv_anim_path_ease_in_out(const lv_anim_t *a);
|
||||
int32_t lv_anim_path_ease_in_out(const lv_anim_t * a);
|
||||
|
||||
/**
|
||||
* Calculate the current value of an animation with overshoot at the end
|
||||
@ -162,7 +161,7 @@ int32_t lv_anim_path_bounce(const lv_anim_t * a);
|
||||
* @param a pointer to an animation
|
||||
* @return the current value to set
|
||||
*/
|
||||
int32_t lv_anim_path_step(const lv_anim_t *a);
|
||||
int32_t lv_anim_path_step(const lv_anim_t * a);
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
@ -174,4 +173,3 @@ int32_t lv_anim_path_step(const lv_anim_t *a);
|
||||
#endif
|
||||
|
||||
#endif /*LV_ANIM_H*/
|
||||
|
||||
|
@ -79,8 +79,8 @@ void lv_area_set_pos(lv_area_t * area_p, lv_coord_t x, lv_coord_t y)
|
||||
{
|
||||
lv_coord_t w = lv_area_get_width(area_p);
|
||||
lv_coord_t h = lv_area_get_height(area_p);
|
||||
area_p->x1 = x;
|
||||
area_p->y1 = y;
|
||||
area_p->x1 = x;
|
||||
area_p->y1 = y;
|
||||
lv_area_set_width(area_p, w);
|
||||
lv_area_set_height(area_p, h);
|
||||
}
|
||||
@ -94,8 +94,7 @@ uint32_t lv_area_get_size(const lv_area_t * area_p)
|
||||
{
|
||||
uint32_t size;
|
||||
|
||||
size = (uint32_t)(area_p->x2 - area_p->x1 + 1) *
|
||||
(area_p->y2 - area_p->y1 + 1);
|
||||
size = (uint32_t)(area_p->x2 - area_p->x1 + 1) * (area_p->y2 - area_p->y1 + 1);
|
||||
|
||||
return size;
|
||||
}
|
||||
@ -117,8 +116,7 @@ bool lv_area_intersect(lv_area_t * res_p, const lv_area_t * a1_p, const lv_area_
|
||||
|
||||
/*If x1 or y1 greater then x2 or y2 then the areas union is empty*/
|
||||
bool union_ok = true;
|
||||
if((res_p->x1 > res_p->x2) ||
|
||||
(res_p->y1 > res_p->y2)) {
|
||||
if((res_p->x1 > res_p->x2) || (res_p->y1 > res_p->y2)) {
|
||||
union_ok = false;
|
||||
}
|
||||
|
||||
@ -148,8 +146,7 @@ bool lv_area_is_point_on(const lv_area_t * a_p, const lv_point_t * p_p)
|
||||
{
|
||||
bool is_on = false;
|
||||
|
||||
if((p_p->x >= a_p->x1 && p_p->x <= a_p->x2) &&
|
||||
((p_p->y >= a_p->y1 && p_p->y <= a_p->y2))) {
|
||||
if((p_p->x >= a_p->x1 && p_p->x <= a_p->x2) && ((p_p->y >= a_p->y1 && p_p->y <= a_p->y2))) {
|
||||
is_on = true;
|
||||
}
|
||||
|
||||
@ -164,15 +161,12 @@ bool lv_area_is_point_on(const lv_area_t * a_p, const lv_point_t * p_p)
|
||||
*/
|
||||
bool lv_area_is_on(const lv_area_t * a1_p, const lv_area_t * a2_p)
|
||||
{
|
||||
if((a1_p->x1 <= a2_p->x2) &&
|
||||
(a1_p->x2 >= a2_p->x1) &&
|
||||
(a1_p->y1 <= a2_p->y2) &&
|
||||
(a1_p->y2 >= a2_p->y1)) {
|
||||
if((a1_p->x1 <= a2_p->x2) && (a1_p->x2 >= a2_p->x1) && (a1_p->y1 <= a2_p->y2) &&
|
||||
(a1_p->y2 >= a2_p->y1)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -185,10 +179,8 @@ bool lv_area_is_in(const lv_area_t * ain_p, const lv_area_t * aholder_p)
|
||||
{
|
||||
bool is_in = false;
|
||||
|
||||
if(ain_p->x1 >= aholder_p->x1 &&
|
||||
ain_p->y1 >= aholder_p->y1 &&
|
||||
ain_p->x2 <= aholder_p->x2 &&
|
||||
ain_p->y2 <= aholder_p->y2) {
|
||||
if(ain_p->x1 >= aholder_p->x1 && ain_p->y1 >= aholder_p->y1 && ain_p->x2 <= aholder_p->x2 &&
|
||||
ain_p->y2 <= aholder_p->y2) {
|
||||
is_in = true;
|
||||
}
|
||||
|
||||
|
@ -10,7 +10,6 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
@ -21,8 +20,8 @@ extern "C" {
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define LV_COORD_MAX (16383) /*To avoid overflow don't let the max [-32,32k] range */
|
||||
#define LV_COORD_MIN (-16384)
|
||||
#define LV_COORD_MAX (16383) /*To avoid overflow don't let the max [-32,32k] range */
|
||||
#define LV_COORD_MIN (-16384)
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
@ -165,5 +164,4 @@ bool lv_area_is_in(const lv_area_t * ain_p, const lv_area_t * aholder_p);
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -67,10 +67,10 @@ void lv_circ_next(lv_point_t * c, lv_coord_t * tmp)
|
||||
c->y++;
|
||||
|
||||
if(*tmp <= 0) {
|
||||
(*tmp) += 2 * c->y + 1; // Change in decision criterion for y -> y+1
|
||||
(*tmp) += 2 * c->y + 1; // Change in decision criterion for y -> y+1
|
||||
} else {
|
||||
c->x--;
|
||||
(*tmp) += 2 * (c->y - c->x) + 1; // Change for y -> y+1, x -> x-1
|
||||
(*tmp) += 2 * (c->y - c->x) + 1; // Change for y -> y+1, x -> x-1
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -10,7 +10,6 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
@ -75,5 +74,4 @@ void lv_circ_next(lv_point_t * c, lv_coord_t * tmp);
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -60,7 +60,7 @@ lv_color_t lv_color_hsv_to_rgb(uint16_t h, uint8_t s, uint8_t v)
|
||||
return lv_color_make(v, v, v);
|
||||
}
|
||||
|
||||
region = h / 43;
|
||||
region = h / 43;
|
||||
remainder = (h - (region * 43)) * 6;
|
||||
|
||||
p = (v * (255 - s)) >> 8;
|
||||
|
@ -32,58 +32,57 @@ extern "C" {
|
||||
#error "LV_COLOR_16_SWAP requires LV_COLOR_DEPTH == 16. Set it in lv_conf.h"
|
||||
#endif
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define LV_COLOR_WHITE LV_COLOR_MAKE(0xFF,0xFF,0xFF)
|
||||
#define LV_COLOR_SILVER LV_COLOR_MAKE(0xC0,0xC0,0xC0)
|
||||
#define LV_COLOR_GRAY LV_COLOR_MAKE(0x80,0x80,0x80)
|
||||
#define LV_COLOR_BLACK LV_COLOR_MAKE(0x00,0x00,0x00)
|
||||
#define LV_COLOR_RED LV_COLOR_MAKE(0xFF,0x00,0x00)
|
||||
#define LV_COLOR_MAROON LV_COLOR_MAKE(0x80,0x00,0x00)
|
||||
#define LV_COLOR_YELLOW LV_COLOR_MAKE(0xFF,0xFF,0x00)
|
||||
#define LV_COLOR_OLIVE LV_COLOR_MAKE(0x80,0x80,0x00)
|
||||
#define LV_COLOR_LIME LV_COLOR_MAKE(0x00,0xFF,0x00)
|
||||
#define LV_COLOR_GREEN LV_COLOR_MAKE(0x00,0x80,0x00)
|
||||
#define LV_COLOR_CYAN LV_COLOR_MAKE(0x00,0xFF,0xFF)
|
||||
#define LV_COLOR_AQUA LV_COLOR_CYAN
|
||||
#define LV_COLOR_TEAL LV_COLOR_MAKE(0x00,0x80,0x80)
|
||||
#define LV_COLOR_BLUE LV_COLOR_MAKE(0x00,0x00,0xFF)
|
||||
#define LV_COLOR_NAVY LV_COLOR_MAKE(0x00,0x00,0x80)
|
||||
#define LV_COLOR_MAGENTA LV_COLOR_MAKE(0xFF,0x00,0xFF)
|
||||
#define LV_COLOR_PURPLE LV_COLOR_MAKE(0x80,0x00,0x80)
|
||||
#define LV_COLOR_ORANGE LV_COLOR_MAKE(0xFF,0xA5,0x00)
|
||||
#define LV_COLOR_WHITE LV_COLOR_MAKE(0xFF, 0xFF, 0xFF)
|
||||
#define LV_COLOR_SILVER LV_COLOR_MAKE(0xC0, 0xC0, 0xC0)
|
||||
#define LV_COLOR_GRAY LV_COLOR_MAKE(0x80, 0x80, 0x80)
|
||||
#define LV_COLOR_BLACK LV_COLOR_MAKE(0x00, 0x00, 0x00)
|
||||
#define LV_COLOR_RED LV_COLOR_MAKE(0xFF, 0x00, 0x00)
|
||||
#define LV_COLOR_MAROON LV_COLOR_MAKE(0x80, 0x00, 0x00)
|
||||
#define LV_COLOR_YELLOW LV_COLOR_MAKE(0xFF, 0xFF, 0x00)
|
||||
#define LV_COLOR_OLIVE LV_COLOR_MAKE(0x80, 0x80, 0x00)
|
||||
#define LV_COLOR_LIME LV_COLOR_MAKE(0x00, 0xFF, 0x00)
|
||||
#define LV_COLOR_GREEN LV_COLOR_MAKE(0x00, 0x80, 0x00)
|
||||
#define LV_COLOR_CYAN LV_COLOR_MAKE(0x00, 0xFF, 0xFF)
|
||||
#define LV_COLOR_AQUA LV_COLOR_CYAN
|
||||
#define LV_COLOR_TEAL LV_COLOR_MAKE(0x00, 0x80, 0x80)
|
||||
#define LV_COLOR_BLUE LV_COLOR_MAKE(0x00, 0x00, 0xFF)
|
||||
#define LV_COLOR_NAVY LV_COLOR_MAKE(0x00, 0x00, 0x80)
|
||||
#define LV_COLOR_MAGENTA LV_COLOR_MAKE(0xFF, 0x00, 0xFF)
|
||||
#define LV_COLOR_PURPLE LV_COLOR_MAKE(0x80, 0x00, 0x80)
|
||||
#define LV_COLOR_ORANGE LV_COLOR_MAKE(0xFF, 0xA5, 0x00)
|
||||
|
||||
enum {
|
||||
LV_OPA_TRANSP = 0,
|
||||
LV_OPA_0 = 0,
|
||||
LV_OPA_10 = 25,
|
||||
LV_OPA_20 = 51,
|
||||
LV_OPA_30 = 76,
|
||||
LV_OPA_40 = 102,
|
||||
LV_OPA_50 = 127,
|
||||
LV_OPA_60 = 153,
|
||||
LV_OPA_70 = 178,
|
||||
LV_OPA_80 = 204,
|
||||
LV_OPA_90 = 229,
|
||||
LV_OPA_100 = 255,
|
||||
LV_OPA_COVER = 255,
|
||||
LV_OPA_TRANSP = 0,
|
||||
LV_OPA_0 = 0,
|
||||
LV_OPA_10 = 25,
|
||||
LV_OPA_20 = 51,
|
||||
LV_OPA_30 = 76,
|
||||
LV_OPA_40 = 102,
|
||||
LV_OPA_50 = 127,
|
||||
LV_OPA_60 = 153,
|
||||
LV_OPA_70 = 178,
|
||||
LV_OPA_80 = 204,
|
||||
LV_OPA_90 = 229,
|
||||
LV_OPA_100 = 255,
|
||||
LV_OPA_COVER = 255,
|
||||
};
|
||||
|
||||
#define LV_OPA_MIN 16 /*Opacities below this will be transparent*/
|
||||
#define LV_OPA_MAX 251 /*Opacities above this will fully cover*/
|
||||
#define LV_OPA_MIN 16 /*Opacities below this will be transparent*/
|
||||
#define LV_OPA_MAX 251 /*Opacities above this will fully cover*/
|
||||
|
||||
#if LV_COLOR_DEPTH == 1
|
||||
#define LV_COLOR_SIZE 8
|
||||
#define LV_COLOR_SIZE 8
|
||||
#elif LV_COLOR_DEPTH == 8
|
||||
#define LV_COLOR_SIZE 8
|
||||
#define LV_COLOR_SIZE 8
|
||||
#elif LV_COLOR_DEPTH == 16
|
||||
#define LV_COLOR_SIZE 16
|
||||
#define LV_COLOR_SIZE 16
|
||||
#elif LV_COLOR_DEPTH == 32
|
||||
#define LV_COLOR_SIZE 32
|
||||
#define LV_COLOR_SIZE 32
|
||||
#else
|
||||
#error "Invalid LV_COLOR_DEPTH in lv_conf.h! Set it to 1, 8, 16 or 32!"
|
||||
#endif
|
||||
@ -94,20 +93,20 @@ enum {
|
||||
|
||||
typedef union
|
||||
{
|
||||
uint8_t blue :1;
|
||||
uint8_t green :1;
|
||||
uint8_t red :1;
|
||||
uint8_t full :1;
|
||||
uint8_t blue : 1;
|
||||
uint8_t green : 1;
|
||||
uint8_t red : 1;
|
||||
uint8_t full : 1;
|
||||
} lv_color1_t;
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint8_t blue :2;
|
||||
uint8_t green :3;
|
||||
uint8_t red :3;
|
||||
}ch;
|
||||
uint8_t blue : 2;
|
||||
uint8_t green : 3;
|
||||
uint8_t red : 3;
|
||||
} ch;
|
||||
uint8_t full;
|
||||
} lv_color8_t;
|
||||
|
||||
@ -116,16 +115,16 @@ typedef union
|
||||
struct
|
||||
{
|
||||
#if LV_COLOR_16_SWAP == 0
|
||||
uint16_t blue :5;
|
||||
uint16_t green :6;
|
||||
uint16_t red :5;
|
||||
uint16_t blue : 5;
|
||||
uint16_t green : 6;
|
||||
uint16_t red : 5;
|
||||
#else
|
||||
uint16_t green_h :3;
|
||||
uint16_t red :5;
|
||||
uint16_t blue :5;
|
||||
uint16_t green_l :3;
|
||||
uint16_t green_h : 3;
|
||||
uint16_t red : 5;
|
||||
uint16_t blue : 5;
|
||||
uint16_t green_l : 3;
|
||||
#endif
|
||||
}ch;
|
||||
} ch;
|
||||
uint16_t full;
|
||||
} lv_color16_t;
|
||||
|
||||
@ -137,7 +136,7 @@ typedef union
|
||||
uint8_t green;
|
||||
uint8_t red;
|
||||
uint8_t alpha;
|
||||
}ch;
|
||||
} ch;
|
||||
uint32_t full;
|
||||
} lv_color32_t;
|
||||
|
||||
@ -189,32 +188,24 @@ static inline uint8_t lv_color_to1(lv_color_t color)
|
||||
#if LV_COLOR_DEPTH == 1
|
||||
return color.full;
|
||||
#elif LV_COLOR_DEPTH == 8
|
||||
if((color.ch.red & 0x4) ||
|
||||
(color.ch.green & 0x4) ||
|
||||
(color.ch.blue & 0x2)) {
|
||||
if((color.ch.red & 0x4) || (color.ch.green & 0x4) || (color.ch.blue & 0x2)) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
#elif LV_COLOR_DEPTH == 16
|
||||
# if LV_COLOR_16_SWAP == 0
|
||||
if((color.ch.red & 0x10) ||
|
||||
(color.ch.green & 0x20) ||
|
||||
(color.ch.blue & 0x10)) {
|
||||
#if LV_COLOR_16_SWAP == 0
|
||||
if((color.ch.red & 0x10) || (color.ch.green & 0x20) || (color.ch.blue & 0x10)) {
|
||||
return 1;
|
||||
# else
|
||||
if((color.ch.red & 0x10) ||
|
||||
(color.ch.green_h & 0x20) ||
|
||||
(color.ch.blue & 0x10)) {
|
||||
#else
|
||||
if((color.ch.red & 0x10) || (color.ch.green_h & 0x20) || (color.ch.blue & 0x10)) {
|
||||
return 1;
|
||||
# endif
|
||||
#endif
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
#elif LV_COLOR_DEPTH == 32
|
||||
if((color.ch.red & 0x80) ||
|
||||
(color.ch.green & 0x80) ||
|
||||
(color.ch.blue & 0x80)) {
|
||||
if((color.ch.red & 0x80) || (color.ch.green & 0x80) || (color.ch.blue & 0x80)) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
@ -225,30 +216,32 @@ static inline uint8_t lv_color_to1(lv_color_t color)
|
||||
static inline uint8_t lv_color_to8(lv_color_t color)
|
||||
{
|
||||
#if LV_COLOR_DEPTH == 1
|
||||
if(color.full == 0) return 0;
|
||||
else return 0xFF;
|
||||
if(color.full == 0)
|
||||
return 0;
|
||||
else
|
||||
return 0xFF;
|
||||
#elif LV_COLOR_DEPTH == 8
|
||||
return color.full;
|
||||
#elif LV_COLOR_DEPTH == 16
|
||||
|
||||
# if LV_COLOR_16_SWAP == 0
|
||||
#if LV_COLOR_16_SWAP == 0
|
||||
lv_color8_t ret;
|
||||
ret.ch.red = color.ch.red >> 2; /* 5 - 3 = 2*/
|
||||
ret.ch.green = color.ch.green >> 3; /* 6 - 3 = 3*/
|
||||
ret.ch.blue = color.ch.blue >> 3; /* 5 - 2 = 3*/
|
||||
ret.ch.red = color.ch.red >> 2; /* 5 - 3 = 2*/
|
||||
ret.ch.green = color.ch.green >> 3; /* 6 - 3 = 3*/
|
||||
ret.ch.blue = color.ch.blue >> 3; /* 5 - 2 = 3*/
|
||||
return ret.full;
|
||||
# else
|
||||
#else
|
||||
lv_color8_t ret;
|
||||
ret.ch.red = color.ch.red >> 2; /* 5 - 3 = 2*/
|
||||
ret.ch.green = color.ch.green_h; /* 6 - 3 = 3*/
|
||||
ret.ch.blue = color.ch.blue >> 3; /* 5 - 2 = 3*/
|
||||
ret.ch.red = color.ch.red >> 2; /* 5 - 3 = 2*/
|
||||
ret.ch.green = color.ch.green_h; /* 6 - 3 = 3*/
|
||||
ret.ch.blue = color.ch.blue >> 3; /* 5 - 2 = 3*/
|
||||
return ret.full;
|
||||
# endif
|
||||
#endif
|
||||
#elif LV_COLOR_DEPTH == 32
|
||||
lv_color8_t ret;
|
||||
ret.ch.red = color.ch.red >> 5; /* 8 - 3 = 5*/
|
||||
ret.ch.green = color.ch.green >> 5; /* 8 - 3 = 5*/
|
||||
ret.ch.blue = color.ch.blue >> 6; /* 8 - 2 = 6*/
|
||||
ret.ch.red = color.ch.red >> 5; /* 8 - 3 = 5*/
|
||||
ret.ch.green = color.ch.green >> 5; /* 8 - 3 = 5*/
|
||||
ret.ch.blue = color.ch.blue >> 6; /* 8 - 2 = 6*/
|
||||
return ret.full;
|
||||
#endif
|
||||
}
|
||||
@ -256,36 +249,38 @@ static inline uint8_t lv_color_to8(lv_color_t color)
|
||||
static inline uint16_t lv_color_to16(lv_color_t color)
|
||||
{
|
||||
#if LV_COLOR_DEPTH == 1
|
||||
if(color.full == 0) return 0;
|
||||
else return 0xFFFF;
|
||||
if(color.full == 0)
|
||||
return 0;
|
||||
else
|
||||
return 0xFFFF;
|
||||
#elif LV_COLOR_DEPTH == 8
|
||||
lv_color16_t ret;
|
||||
# if LV_COLOR_16_SWAP == 0
|
||||
ret.ch.red = color.ch.red * 4; /*(2^5 - 1)/(2^3 - 1) = 31/7 = 4*/
|
||||
ret.ch.green = color.ch.green * 9; /*(2^6 - 1)/(2^3 - 1) = 63/7 = 9*/
|
||||
ret.ch.blue = color.ch.blue * 10; /*(2^5 - 1)/(2^2 - 1) = 31/3 = 10*/
|
||||
# else
|
||||
ret.red = color.ch.red * 4;
|
||||
uint8_t g_tmp = color.ch.green * 9;
|
||||
#if LV_COLOR_16_SWAP == 0
|
||||
ret.ch.red = color.ch.red * 4; /*(2^5 - 1)/(2^3 - 1) = 31/7 = 4*/
|
||||
ret.ch.green = color.ch.green * 9; /*(2^6 - 1)/(2^3 - 1) = 63/7 = 9*/
|
||||
ret.ch.blue = color.ch.blue * 10; /*(2^5 - 1)/(2^2 - 1) = 31/3 = 10*/
|
||||
#else
|
||||
ret.red = color.ch.red * 4;
|
||||
uint8_t g_tmp = color.ch.green * 9;
|
||||
ret.ch.green_h = (g_tmp & 0x1F) >> 3;
|
||||
ret.ch.green_l = g_tmp & 0x07;
|
||||
ret.ch.blue = color.ch.blue * 10;
|
||||
# endif
|
||||
ret.ch.blue = color.ch.blue * 10;
|
||||
#endif
|
||||
return ret.full;
|
||||
#elif LV_COLOR_DEPTH == 16
|
||||
return color.full;
|
||||
#elif LV_COLOR_DEPTH == 32
|
||||
lv_color16_t ret;
|
||||
# if LV_COLOR_16_SWAP == 0
|
||||
ret.ch.red = color.ch.red >> 3; /* 8 - 5 = 3*/
|
||||
ret.ch.green = color.ch.green >> 2; /* 8 - 6 = 2*/
|
||||
ret.ch.blue = color.ch.blue >> 3; /* 8 - 5 = 3*/
|
||||
# else
|
||||
ret.ch.red = color.ch.red >> 3;
|
||||
#if LV_COLOR_16_SWAP == 0
|
||||
ret.ch.red = color.ch.red >> 3; /* 8 - 5 = 3*/
|
||||
ret.ch.green = color.ch.green >> 2; /* 8 - 6 = 2*/
|
||||
ret.ch.blue = color.ch.blue >> 3; /* 8 - 5 = 3*/
|
||||
#else
|
||||
ret.ch.red = color.ch.red >> 3;
|
||||
ret.ch.green_h = (color.ch.green & 0xE0) >> 5;
|
||||
ret.ch.green_l = (color.ch.green & 0x1C) >> 2;
|
||||
ret.ch.blue = color.ch.blue >> 3;
|
||||
# endif
|
||||
ret.ch.blue = color.ch.blue >> 3;
|
||||
#endif
|
||||
return ret.full;
|
||||
#endif
|
||||
}
|
||||
@ -293,31 +288,34 @@ static inline uint16_t lv_color_to16(lv_color_t color)
|
||||
static inline uint32_t lv_color_to32(lv_color_t color)
|
||||
{
|
||||
#if LV_COLOR_DEPTH == 1
|
||||
if(color.full == 0) return 0;
|
||||
else return 0xFFFFFFFF;
|
||||
if(color.full == 0)
|
||||
return 0;
|
||||
else
|
||||
return 0xFFFFFFFF;
|
||||
#elif LV_COLOR_DEPTH == 8
|
||||
lv_color32_t ret;
|
||||
ret.ch.red = color.ch.red * 36; /*(2^8 - 1)/(2^3 - 1) = 255/7 = 36*/
|
||||
ret.ch.green = color.ch.green * 36; /*(2^8 - 1)/(2^3 - 1) = 255/7 = 36*/
|
||||
ret.ch.blue = color.ch.blue * 85; /*(2^8 - 1)/(2^2 - 1) = 255/3 = 85*/
|
||||
ret.ch.red = color.ch.red * 36; /*(2^8 - 1)/(2^3 - 1) = 255/7 = 36*/
|
||||
ret.ch.green = color.ch.green * 36; /*(2^8 - 1)/(2^3 - 1) = 255/7 = 36*/
|
||||
ret.ch.blue = color.ch.blue * 85; /*(2^8 - 1)/(2^2 - 1) = 255/3 = 85*/
|
||||
ret.ch.alpha = 0xFF;
|
||||
return ret.full;
|
||||
#elif LV_COLOR_DEPTH == 16
|
||||
# if LV_COLOR_16_SWAP == 0
|
||||
#if LV_COLOR_16_SWAP == 0
|
||||
lv_color32_t ret;
|
||||
ret.ch.red = color.ch.red * 8; /*(2^8 - 1)/(2^5 - 1) = 255/31 = 8*/
|
||||
ret.ch.green = color.ch.green * 4; /*(2^8 - 1)/(2^6 - 1) = 255/63 = 4*/
|
||||
ret.ch.blue = color.ch.blue * 8; /*(2^8 - 1)/(2^5 - 1) = 255/31 = 8*/
|
||||
ret.ch.red = color.ch.red * 8; /*(2^8 - 1)/(2^5 - 1) = 255/31 = 8*/
|
||||
ret.ch.green = color.ch.green * 4; /*(2^8 - 1)/(2^6 - 1) = 255/63 = 4*/
|
||||
ret.ch.blue = color.ch.blue * 8; /*(2^8 - 1)/(2^5 - 1) = 255/31 = 8*/
|
||||
ret.ch.alpha = 0xFF;
|
||||
return ret.full;
|
||||
# else
|
||||
#else
|
||||
lv_color32_t ret;
|
||||
ret.ch.red = color.ch.red * 8; /*(2^8 - 1)/(2^5 - 1) = 255/31 = 8*/
|
||||
ret.ch.green = ((color.ch.green_h << 3) + color.ch.green_l) * 4; /*(2^8 - 1)/(2^6 - 1) = 255/63 = 4*/
|
||||
ret.ch.blue = color.ch.blue * 8; /*(2^8 - 1)/(2^5 - 1) = 255/31 = 8*/
|
||||
ret.ch.red = color.ch.red * 8; /*(2^8 - 1)/(2^5 - 1) = 255/31 = 8*/
|
||||
ret.ch.green =
|
||||
((color.ch.green_h << 3) + color.ch.green_l) * 4; /*(2^8 - 1)/(2^6 - 1) = 255/63 = 4*/
|
||||
ret.ch.blue = color.ch.blue * 8; /*(2^8 - 1)/(2^5 - 1) = 255/31 = 8*/
|
||||
ret.ch.alpha = 0xFF;
|
||||
return ret.full;
|
||||
# endif
|
||||
#endif
|
||||
#elif LV_COLOR_DEPTH == 32
|
||||
return color.full;
|
||||
#endif
|
||||
@ -328,21 +326,21 @@ static inline lv_color_t lv_color_mix(lv_color_t c1, lv_color_t c2, uint8_t mix)
|
||||
lv_color_t ret;
|
||||
#if LV_COLOR_DEPTH != 1
|
||||
/*LV_COLOR_DEPTH == 8, 16 or 32*/
|
||||
ret.ch.red = (uint16_t)((uint16_t) c1.ch.red * mix + (c2.ch.red * (255 - mix))) >> 8;
|
||||
# if LV_COLOR_DEPTH == 16 && LV_COLOR_16_SWAP
|
||||
ret.ch.red = (uint16_t)((uint16_t)c1.ch.red * mix + (c2.ch.red * (255 - mix))) >> 8;
|
||||
#if LV_COLOR_DEPTH == 16 && LV_COLOR_16_SWAP
|
||||
/*If swapped Green is in 2 parts*/
|
||||
uint16_t g_1 = (c1.ch.green_h << 3) + c1.ch.green_l;
|
||||
uint16_t g_2 = (c2.ch.green_h << 3) + c2.ch.green_l;
|
||||
uint16_t g_out = (uint16_t)((uint16_t) g_1 * mix + (g_2 * (255 - mix))) >> 8;
|
||||
uint16_t g_1 = (c1.ch.green_h << 3) + c1.ch.green_l;
|
||||
uint16_t g_2 = (c2.ch.green_h << 3) + c2.ch.green_l;
|
||||
uint16_t g_out = (uint16_t)((uint16_t)g_1 * mix + (g_2 * (255 - mix))) >> 8;
|
||||
ret.ch.green_h = g_out >> 3;
|
||||
ret.ch.green_l = g_out & 0x7;
|
||||
# else
|
||||
ret.ch.green = (uint16_t)((uint16_t) c1.ch.green * mix + (c2.ch.green * (255 - mix))) >> 8;
|
||||
# endif
|
||||
ret.ch.blue = (uint16_t)((uint16_t) c1.ch.blue * mix + (c2.ch.blue * (255 - mix))) >> 8;
|
||||
# if LV_COLOR_DEPTH == 32
|
||||
#else
|
||||
ret.ch.green = (uint16_t)((uint16_t)c1.ch.green * mix + (c2.ch.green * (255 - mix))) >> 8;
|
||||
#endif
|
||||
ret.ch.blue = (uint16_t)((uint16_t)c1.ch.blue * mix + (c2.ch.blue * (255 - mix))) >> 8;
|
||||
#if LV_COLOR_DEPTH == 32
|
||||
ret.ch.alpha = 0xFF;
|
||||
# endif
|
||||
#endif
|
||||
#else
|
||||
/*LV_COLOR_DEPTH == 1*/
|
||||
ret.full = mix > LV_OPA_50 ? c1.full : c2.full;
|
||||
@ -359,52 +357,57 @@ static inline lv_color_t lv_color_mix(lv_color_t c1, lv_color_t c2, uint8_t mix)
|
||||
static inline uint8_t lv_color_brightness(lv_color_t color)
|
||||
{
|
||||
lv_color32_t c32;
|
||||
c32.full = lv_color_to32(color);
|
||||
c32.full = lv_color_to32(color);
|
||||
uint16_t bright = 3 * c32.ch.red + c32.ch.blue + 4 * c32.ch.green;
|
||||
return (uint16_t) bright >> 3;
|
||||
return (uint16_t)bright >> 3;
|
||||
}
|
||||
|
||||
/* The most simple macro to create a color from R,G and B values */
|
||||
#if LV_COLOR_DEPTH == 1
|
||||
#define LV_COLOR_MAKE(r8, g8, b8) ((lv_color_t){(b8 >> 7 | g8 >> 7 | r8 >> 7)})
|
||||
static inline lv_color_t lv_color_make(int r8, int g8, int b8){
|
||||
static inline lv_color_t lv_color_make(int r8, int g8, int b8)
|
||||
{
|
||||
lv_color_t color;
|
||||
color.full = (b8 >> 7 | g8 >> 7 | r8 >> 7);
|
||||
return color;
|
||||
}
|
||||
#elif LV_COLOR_DEPTH == 8
|
||||
#define LV_COLOR_MAKE(r8, g8, b8) ((lv_color_t){{b8 >> 6, g8 >> 5, r8 >> 5}})
|
||||
static inline lv_color_t lv_color_make(uint8_t r8, int g8, int b8){
|
||||
static inline lv_color_t lv_color_make(uint8_t r8, int g8, int b8)
|
||||
{
|
||||
lv_color_t color;
|
||||
color.ch.blue = b8 >> 6;
|
||||
color.ch.blue = b8 >> 6;
|
||||
color.ch.green = g8 >> 5;
|
||||
color.ch.red = r8 >> 5;
|
||||
color.ch.red = r8 >> 5;
|
||||
return color;
|
||||
}
|
||||
#elif LV_COLOR_DEPTH == 16
|
||||
# if LV_COLOR_16_SWAP == 0
|
||||
# define LV_COLOR_MAKE(r8, g8, b8) ((lv_color_t){{b8 >> 3, g8 >> 2, r8 >> 3}})
|
||||
static inline lv_color_t lv_color_make(uint8_t r8, uint8_t g8, uint8_t b8){
|
||||
#if LV_COLOR_16_SWAP == 0
|
||||
#define LV_COLOR_MAKE(r8, g8, b8) ((lv_color_t){{b8 >> 3, g8 >> 2, r8 >> 3}})
|
||||
static inline lv_color_t lv_color_make(uint8_t r8, uint8_t g8, uint8_t b8)
|
||||
{
|
||||
lv_color_t color;
|
||||
color.ch.blue = (uint16_t)(b8 >> 3);
|
||||
color.ch.green = (uint16_t)(g8 >> 2);
|
||||
color.ch.red = (uint16_t)(r8 >> 3);
|
||||
return color;
|
||||
}
|
||||
# else
|
||||
# define LV_COLOR_MAKE(r8, g8, b8) ((lv_color_t){{g8 >> 5, r8 >> 3, b8 >> 3, (g8 >> 2) & 0x7}})
|
||||
static inline lv_color_t lv_color_make(uint8_t r8, uint8_t g8, uint8_t b8){
|
||||
#else
|
||||
#define LV_COLOR_MAKE(r8, g8, b8) ((lv_color_t){{g8 >> 5, r8 >> 3, b8 >> 3, (g8 >> 2) & 0x7}})
|
||||
static inline lv_color_t lv_color_make(uint8_t r8, uint8_t g8, uint8_t b8)
|
||||
{
|
||||
lv_color_t color;
|
||||
color.ch.green_h = (uint16_t)(g8 >> 5);
|
||||
color.ch.red = (uint16_t)(r8 >> 3);
|
||||
color.ch.blue = (uint16_t)(b8 >> 3);
|
||||
color.ch.green_l = (uint16_t)((g8 >> 2) & 0x7);
|
||||
color.ch.green_h = (uint16_t)(g8 >> 5);
|
||||
color.ch.red = (uint16_t)(r8 >> 3);
|
||||
color.ch.blue = (uint16_t)(b8 >> 3);
|
||||
color.ch.green_l = (uint16_t)((g8 >> 2) & 0x7);
|
||||
return color;
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
#elif LV_COLOR_DEPTH == 32
|
||||
#define LV_COLOR_MAKE(r8, g8, b8) ((lv_color_t){{b8, g8, r8, 0xff}}) /*Fix 0xff alpha*/
|
||||
static inline lv_color_t lv_color_make(uint8_t r8, uint8_t g8, uint8_t b8){
|
||||
#define LV_COLOR_MAKE(r8, g8, b8) ((lv_color_t){{b8, g8, r8, 0xff}}) /*Fix 0xff alpha*/
|
||||
static inline lv_color_t lv_color_make(uint8_t r8, uint8_t g8, uint8_t b8)
|
||||
{
|
||||
lv_color_t color;
|
||||
color.ch.blue = b8;
|
||||
color.ch.green = g8;
|
||||
@ -414,16 +417,17 @@ static inline lv_color_t lv_color_make(uint8_t r8, uint8_t g8, uint8_t b8){
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline lv_color_t lv_color_hex(uint32_t c) {
|
||||
return lv_color_make((uint8_t) ((c >> 16) & 0xFF),
|
||||
(uint8_t) ((c >> 8) & 0xFF),
|
||||
(uint8_t) (c & 0xFF));
|
||||
static inline lv_color_t lv_color_hex(uint32_t c)
|
||||
{
|
||||
return lv_color_make((uint8_t)((c >> 16) & 0xFF), (uint8_t)((c >> 8) & 0xFF),
|
||||
(uint8_t)(c & 0xFF));
|
||||
}
|
||||
|
||||
static inline lv_color_t lv_color_hex3(uint32_t c) {
|
||||
return lv_color_make((uint8_t) (((c >> 4) & 0xF0) | ((c >> 8) & 0xF)),
|
||||
(uint8_t) ((c & 0xF0) | ((c & 0xF0) >> 4)),
|
||||
(uint8_t) ((c & 0xF) | ((c & 0xF) << 4)));
|
||||
static inline lv_color_t lv_color_hex3(uint32_t c)
|
||||
{
|
||||
return lv_color_make((uint8_t)(((c >> 4) & 0xF0) | ((c >> 8) & 0xF)),
|
||||
(uint8_t)((c & 0xF0) | ((c & 0xF0) >> 4)),
|
||||
(uint8_t)((c & 0xF) | ((c & 0xF) << 4)));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -444,7 +448,6 @@ lv_color_t lv_color_hsv_to_rgb(uint16_t h, uint8_t s, uint8_t v);
|
||||
*/
|
||||
lv_color_hsv_t lv_color_rgb_to_hsv(uint8_t r, uint8_t g, uint8_t b);
|
||||
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
@ -23,7 +23,7 @@
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
static int32_t lv_font_codeCompare (const void* pRef, const void* pElement);
|
||||
static int32_t lv_font_codeCompare(const void * pRef, const void * pElement);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
@ -63,7 +63,6 @@ void lv_font_add(lv_font_t * child, lv_font_t * parent)
|
||||
}
|
||||
|
||||
parent->next_page = child;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -83,7 +82,6 @@ void lv_font_remove(lv_font_t * child, lv_font_t * parent)
|
||||
parent->next_page = child->next_page;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Tells if font which contains `letter` is monospace or not
|
||||
* @param font_p point to font
|
||||
@ -150,7 +148,6 @@ uint8_t lv_font_get_width(const lv_font_t * font_p, uint32_t letter)
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -190,11 +187,11 @@ uint8_t lv_font_get_bpp(const lv_font_t * font, uint32_t letter)
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic bitmap get function used in 'font->get_bitmap' when the font contains all characters in the range
|
||||
* Generic bitmap get function used in 'font->get_bitmap' when the font contains all characters in
|
||||
* the range
|
||||
* @param font pointer to font
|
||||
* @param unicode_letter an unicode letter which bitmap should be get
|
||||
* @return pointer to the bitmap or NULL if not found
|
||||
@ -209,7 +206,8 @@ const uint8_t * lv_font_get_bitmap_continuous(const lv_font_t * font, uint32_t u
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic bitmap get function used in 'font->get_bitmap' when the font NOT contains all characters in the range (sparse)
|
||||
* Generic bitmap get function used in 'font->get_bitmap' when the font NOT contains all characters
|
||||
* in the range (sparse)
|
||||
* @param font pointer to font
|
||||
* @param unicode_letter an unicode letter which bitmap should be get
|
||||
* @return pointer to the bitmap or NULL if not found
|
||||
@ -219,16 +217,13 @@ const uint8_t * lv_font_get_bitmap_sparse(const lv_font_t * font, uint32_t unico
|
||||
/*Check the range*/
|
||||
if(unicode_letter < font->unicode_first || unicode_letter > font->unicode_last) return NULL;
|
||||
|
||||
uint32_t* pUnicode;
|
||||
uint32_t * pUnicode;
|
||||
|
||||
pUnicode = lv_utils_bsearch(&unicode_letter,
|
||||
(uint32_t*) font->unicode_list,
|
||||
font->glyph_cnt,
|
||||
sizeof(uint32_t),
|
||||
lv_font_codeCompare);
|
||||
pUnicode = lv_utils_bsearch(&unicode_letter, (uint32_t *)font->unicode_list, font->glyph_cnt,
|
||||
sizeof(uint32_t), lv_font_codeCompare);
|
||||
|
||||
if (pUnicode != NULL) {
|
||||
uint32_t idx = (uint32_t) (pUnicode - font->unicode_list);
|
||||
if(pUnicode != NULL) {
|
||||
uint32_t idx = (uint32_t)(pUnicode - font->unicode_list);
|
||||
return &font->glyph_bitmap[font->glyph_dsc[idx].glyph_index];
|
||||
}
|
||||
|
||||
@ -236,7 +231,8 @@ const uint8_t * lv_font_get_bitmap_sparse(const lv_font_t * font, uint32_t unico
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic glyph width get function used in 'font->get_width' when the font contains all characters in the range
|
||||
* Generic glyph width get function used in 'font->get_width' when the font contains all characters
|
||||
* in the range
|
||||
* @param font pointer to font
|
||||
* @param unicode_letter an unicode letter which width should be get
|
||||
* @return width of the gylph or -1 if not found
|
||||
@ -253,7 +249,8 @@ int16_t lv_font_get_width_continuous(const lv_font_t * font, uint32_t unicode_le
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic glyph width get function used in 'font->get_bitmap' when the font NOT contains all characters in the range (sparse)
|
||||
* Generic glyph width get function used in 'font->get_bitmap' when the font NOT contains all
|
||||
* characters in the range (sparse)
|
||||
* @param font pointer to font
|
||||
* @param unicode_letter an unicode letter which width should be get
|
||||
* @return width of the glyph or -1 if not found
|
||||
@ -263,16 +260,13 @@ int16_t lv_font_get_width_sparse(const lv_font_t * font, uint32_t unicode_letter
|
||||
/*Check the range*/
|
||||
if(unicode_letter < font->unicode_first || unicode_letter > font->unicode_last) return -1;
|
||||
|
||||
uint32_t* pUnicode;
|
||||
uint32_t * pUnicode;
|
||||
|
||||
pUnicode = lv_utils_bsearch(&unicode_letter,
|
||||
(uint32_t*) font->unicode_list,
|
||||
font->glyph_cnt,
|
||||
sizeof(uint32_t),
|
||||
lv_font_codeCompare);
|
||||
pUnicode = lv_utils_bsearch(&unicode_letter, (uint32_t *)font->unicode_list, font->glyph_cnt,
|
||||
sizeof(uint32_t), lv_font_codeCompare);
|
||||
|
||||
if (pUnicode != NULL) {
|
||||
uint32_t idx = (uint32_t) (pUnicode - font->unicode_list);
|
||||
if(pUnicode != NULL) {
|
||||
uint32_t idx = (uint32_t)(pUnicode - font->unicode_list);
|
||||
return font->glyph_dsc[idx].w_px;
|
||||
}
|
||||
|
||||
@ -296,8 +290,7 @@ int16_t lv_font_get_width_sparse(const lv_font_t * font, uint32_t unicode_letter
|
||||
* @retval > 0 Reference is less than element.
|
||||
*
|
||||
*/
|
||||
static int32_t lv_font_codeCompare (const void* pRef,
|
||||
const void* pElement)
|
||||
static int32_t lv_font_codeCompare(const void * pRef, const void * pElement)
|
||||
{
|
||||
return (*(uint32_t*) pRef) - (*(uint32_t*) pElement);
|
||||
return (*(uint32_t *)pRef) - (*(uint32_t *)pElement);
|
||||
}
|
||||
|
@ -10,7 +10,6 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
@ -36,14 +35,14 @@ extern "C" {
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t w_px :8;
|
||||
uint32_t glyph_index :24;
|
||||
uint32_t w_px : 8;
|
||||
uint32_t glyph_index : 24;
|
||||
} lv_font_glyph_dsc_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t unicode :21;
|
||||
uint32_t glyph_dsc_index :11;
|
||||
uint32_t unicode : 21;
|
||||
uint32_t glyph_dsc_index : 11;
|
||||
} lv_font_unicode_map_t;
|
||||
|
||||
typedef struct _lv_font_struct
|
||||
@ -53,13 +52,15 @@ typedef struct _lv_font_struct
|
||||
const uint8_t * glyph_bitmap;
|
||||
const lv_font_glyph_dsc_t * glyph_dsc;
|
||||
const uint32_t * unicode_list;
|
||||
const uint8_t * (*get_bitmap)(const struct _lv_font_struct *,uint32_t); /*Get a glyph's bitmap from a font*/
|
||||
int16_t (*get_width)(const struct _lv_font_struct *,uint32_t); /*Get a glyph's with with a given font*/
|
||||
struct _lv_font_struct * next_page; /*Pointer to a font extension*/
|
||||
uint32_t h_px :8;
|
||||
uint32_t bpp :4; /*Bit per pixel: 1, 2 or 4*/
|
||||
uint32_t monospace :8; /*Fix width (0: normal width)*/
|
||||
uint16_t glyph_cnt; /*Number of glyphs (letters) in the font*/
|
||||
const uint8_t * (*get_bitmap)(const struct _lv_font_struct *,
|
||||
uint32_t); /*Get a glyph's bitmap from a font*/
|
||||
int16_t (*get_width)(const struct _lv_font_struct *,
|
||||
uint32_t); /*Get a glyph's with with a given font*/
|
||||
struct _lv_font_struct * next_page; /*Pointer to a font extension*/
|
||||
uint32_t h_px : 8;
|
||||
uint32_t bpp : 4; /*Bit per pixel: 1, 2 or 4*/
|
||||
uint32_t monospace : 8; /*Fix width (0: normal width)*/
|
||||
uint16_t glyph_cnt; /*Number of glyphs (letters) in the font*/
|
||||
} lv_font_t;
|
||||
|
||||
/**********************
|
||||
@ -76,7 +77,7 @@ void lv_font_init(void);
|
||||
* @param child the font to add
|
||||
* @param parent this font will be extended. Using it later will contain the characters from `child`
|
||||
*/
|
||||
void lv_font_add(lv_font_t *child, lv_font_t *parent);
|
||||
void lv_font_add(lv_font_t * child, lv_font_t * parent);
|
||||
|
||||
/**
|
||||
* Remove a font from a character set.
|
||||
@ -109,7 +110,6 @@ const uint8_t * lv_font_get_bitmap(const lv_font_t * font_p, uint32_t letter);
|
||||
*/
|
||||
uint8_t lv_font_get_width(const lv_font_t * font_p, uint32_t letter);
|
||||
|
||||
|
||||
/**
|
||||
* Get the width of the letter without overwriting it with the `monospace` attribute
|
||||
* @param font_p pointer to a font
|
||||
@ -137,7 +137,8 @@ static inline uint8_t lv_font_get_height(const lv_font_t * font_p)
|
||||
uint8_t lv_font_get_bpp(const lv_font_t * font, uint32_t letter);
|
||||
|
||||
/**
|
||||
* Generic bitmap get function used in 'font->get_bitmap' when the font contains all characters in the range
|
||||
* Generic bitmap get function used in 'font->get_bitmap' when the font contains all characters in
|
||||
* the range
|
||||
* @param font pointer to font
|
||||
* @param unicode_letter an unicode letter which bitmap should be get
|
||||
* @return pointer to the bitmap or NULL if not found
|
||||
@ -145,14 +146,16 @@ uint8_t lv_font_get_bpp(const lv_font_t * font, uint32_t letter);
|
||||
const uint8_t * lv_font_get_bitmap_continuous(const lv_font_t * font, uint32_t unicode_letter);
|
||||
|
||||
/**
|
||||
* Generic bitmap get function used in 'font->get_bitmap' when the font NOT contains all characters in the range (sparse)
|
||||
* Generic bitmap get function used in 'font->get_bitmap' when the font NOT contains all characters
|
||||
* in the range (sparse)
|
||||
* @param font pointer to font
|
||||
* @param unicode_letter an unicode letter which bitmap should be get
|
||||
* @return pointer to the bitmap or NULL if not found
|
||||
*/
|
||||
const uint8_t * lv_font_get_bitmap_sparse(const lv_font_t * font, uint32_t unicode_letter);
|
||||
/**
|
||||
* Generic glyph width get function used in 'font->get_width' when the font contains all characters in the range
|
||||
* Generic glyph width get function used in 'font->get_width' when the font contains all characters
|
||||
* in the range
|
||||
* @param font pointer to font
|
||||
* @param unicode_letter an unicode letter which width should be get
|
||||
* @return width of the gylph or -1 if not found
|
||||
@ -160,7 +163,8 @@ const uint8_t * lv_font_get_bitmap_sparse(const lv_font_t * font, uint32_t unico
|
||||
int16_t lv_font_get_width_continuous(const lv_font_t * font, uint32_t unicode_letter);
|
||||
|
||||
/**
|
||||
* Generic glyph width get function used in 'font->get_bitmap' when the font NOT contains all characters in the range (sparse)
|
||||
* Generic glyph width get function used in 'font->get_bitmap' when the font NOT contains all
|
||||
* characters in the range (sparse)
|
||||
* @param font pointer to font
|
||||
* @param unicode_letter an unicode letter which width should be get
|
||||
* @return width of the glyph or -1 if not found
|
||||
@ -173,7 +177,6 @@ int16_t lv_font_get_width_sparse(const lv_font_t * font, uint32_t unicode_letter
|
||||
|
||||
#define LV_FONT_DECLARE(font_name) extern lv_font_t font_name;
|
||||
|
||||
|
||||
/**********************
|
||||
* ADD BUILT IN FONTS
|
||||
**********************/
|
||||
@ -189,4 +192,3 @@ LV_FONT_CUSTOM_DECLARE
|
||||
#endif
|
||||
|
||||
#endif /*USE_FONT*/
|
||||
|
||||
|
@ -14,7 +14,7 @@
|
||||
#include "lv_gc.h"
|
||||
|
||||
#if defined(LV_GC_INCLUDE)
|
||||
# include LV_GC_INCLUDE
|
||||
#include LV_GC_INCLUDE
|
||||
#endif /* LV_ENABLE_GC */
|
||||
|
||||
/*********************
|
||||
@ -39,7 +39,6 @@
|
||||
static const char * lv_fs_get_real_path(const char * path);
|
||||
static lv_fs_drv_t * lv_fs_get_drv(char letter);
|
||||
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
@ -61,7 +60,8 @@ void lv_fs_init(void)
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if a drive is rady or not. If the `ready` function was not initialized `true` will be returned.
|
||||
* Test if a drive is rady or not. If the `ready` function was not initialized `true` will be
|
||||
* returned.
|
||||
* @param letter letter of the drive
|
||||
* @return true: drive is ready; false: drive is not ready
|
||||
*/
|
||||
@ -69,9 +69,9 @@ bool lv_fs_is_ready(char letter)
|
||||
{
|
||||
lv_fs_drv_t * drv = lv_fs_get_drv(letter);
|
||||
|
||||
if(drv == NULL) return false; /*An unknown driver in not ready*/
|
||||
if(drv == NULL) return false; /*An unknown driver in not ready*/
|
||||
|
||||
if(drv->ready == NULL) return true; /*Assume the driver is always ready if no handler provided*/
|
||||
if(drv->ready == NULL) return true; /*Assume the driver is always ready if no handler provided*/
|
||||
|
||||
return drv->ready();
|
||||
}
|
||||
@ -85,7 +85,7 @@ bool lv_fs_is_ready(char letter)
|
||||
*/
|
||||
lv_fs_res_t lv_fs_open(lv_fs_file_t * file_p, const char * path, lv_fs_mode_t mode)
|
||||
{
|
||||
file_p->drv = NULL;
|
||||
file_p->drv = NULL;
|
||||
file_p->file_d = NULL;
|
||||
|
||||
if(path == NULL) return LV_FS_RES_INV_PARAM;
|
||||
@ -101,7 +101,7 @@ lv_fs_res_t lv_fs_open(lv_fs_file_t * file_p, const char * path, lv_fs_mode_t mo
|
||||
|
||||
if(file_p->drv->ready != NULL) {
|
||||
if(file_p->drv->ready() == false) {
|
||||
file_p->drv = NULL;
|
||||
file_p->drv = NULL;
|
||||
file_p->file_d = NULL;
|
||||
return LV_FS_RES_HW_ERR;
|
||||
}
|
||||
@ -111,7 +111,7 @@ lv_fs_res_t lv_fs_open(lv_fs_file_t * file_p, const char * path, lv_fs_mode_t mo
|
||||
lv_mem_assert(file_p->file_d);
|
||||
if(file_p->file_d == NULL) {
|
||||
file_p->drv = NULL;
|
||||
return LV_FS_RES_OUT_OF_MEM; /* Out of memory */
|
||||
return LV_FS_RES_OUT_OF_MEM; /* Out of memory */
|
||||
}
|
||||
|
||||
if(file_p->drv->open == NULL) {
|
||||
@ -119,12 +119,12 @@ lv_fs_res_t lv_fs_open(lv_fs_file_t * file_p, const char * path, lv_fs_mode_t mo
|
||||
}
|
||||
|
||||
const char * real_path = lv_fs_get_real_path(path);
|
||||
lv_fs_res_t res = file_p->drv->open(file_p->file_d, real_path, mode);
|
||||
lv_fs_res_t res = file_p->drv->open(file_p->file_d, real_path, mode);
|
||||
|
||||
if(res != LV_FS_RES_OK) {
|
||||
lv_mem_free(file_p->file_d);
|
||||
file_p->file_d = NULL;
|
||||
file_p->drv = NULL;
|
||||
file_p->drv = NULL;
|
||||
}
|
||||
|
||||
return res;
|
||||
@ -147,9 +147,9 @@ lv_fs_res_t lv_fs_close(lv_fs_file_t * file_p)
|
||||
|
||||
lv_fs_res_t res = file_p->drv->close(file_p->file_d);
|
||||
|
||||
lv_mem_free(file_p->file_d); /*Clean up*/
|
||||
lv_mem_free(file_p->file_d); /*Clean up*/
|
||||
file_p->file_d = NULL;
|
||||
file_p->drv = NULL;
|
||||
file_p->drv = NULL;
|
||||
file_p->file_d = NULL;
|
||||
|
||||
return res;
|
||||
@ -176,7 +176,7 @@ lv_fs_res_t lv_fs_remove(const char * path)
|
||||
if(drv->remove == NULL) return LV_FS_RES_NOT_IMP;
|
||||
|
||||
const char * real_path = lv_fs_get_real_path(path);
|
||||
lv_fs_res_t res = drv->remove(real_path);
|
||||
lv_fs_res_t res = drv->remove(real_path);
|
||||
|
||||
return res;
|
||||
}
|
||||
@ -224,7 +224,7 @@ lv_fs_res_t lv_fs_write(lv_fs_file_t * file_p, const void * buf, uint32_t btw, u
|
||||
|
||||
uint32_t bw_tmp = 0;
|
||||
lv_fs_res_t res = file_p->drv->write(file_p->file_d, buf, btw, &bw_tmp);
|
||||
if(bw != NULL) *bw = bw_tmp;
|
||||
if(bw != NULL) *bw = bw_tmp;
|
||||
|
||||
return res;
|
||||
}
|
||||
@ -256,7 +256,7 @@ lv_fs_res_t lv_fs_seek(lv_fs_file_t * file_p, uint32_t pos)
|
||||
* @param pos_p pointer to store the position of the read write pointer
|
||||
* @return LV_FS_RES_OK or any error from 'fs_res_t'
|
||||
*/
|
||||
lv_fs_res_t lv_fs_tell(lv_fs_file_t * file_p, uint32_t * pos)
|
||||
lv_fs_res_t lv_fs_tell(lv_fs_file_t * file_p, uint32_t * pos)
|
||||
{
|
||||
if(file_p->drv == NULL) {
|
||||
pos = 0;
|
||||
@ -307,7 +307,6 @@ lv_fs_res_t lv_fs_size(lv_fs_file_t * file_p, uint32_t * size)
|
||||
|
||||
if(file_p->drv->size == NULL) return LV_FS_RES_NOT_IMP;
|
||||
|
||||
|
||||
if(size == NULL) return LV_FS_RES_INV_PARAM;
|
||||
|
||||
lv_fs_res_t res = file_p->drv->size(file_p->file_d, size);
|
||||
@ -343,12 +342,11 @@ lv_fs_res_t lv_fs_rename(const char * oldname, const char * newname)
|
||||
|
||||
const char * old_real = lv_fs_get_real_path(oldname);
|
||||
const char * new_real = lv_fs_get_real_path(newname);
|
||||
lv_fs_res_t res = drv->rename(old_real, new_real);
|
||||
lv_fs_res_t res = drv->rename(old_real, new_real);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initialize a 'fs_read_dir_t' variable for directory reading
|
||||
* @param rddir_p pointer to a 'fs_read_dir_t' variable
|
||||
@ -372,7 +370,7 @@ lv_fs_res_t lv_fs_dir_open(lv_fs_dir_t * rddir_p, const char * path)
|
||||
lv_mem_assert(rddir_p->dir_d);
|
||||
if(rddir_p->dir_d == NULL) {
|
||||
rddir_p->dir_d = NULL;
|
||||
return LV_FS_RES_OUT_OF_MEM; /* Out of memory */
|
||||
return LV_FS_RES_OUT_OF_MEM; /* Out of memory */
|
||||
}
|
||||
|
||||
if(rddir_p->drv->dir_open == NULL) {
|
||||
@ -380,7 +378,7 @@ lv_fs_res_t lv_fs_dir_open(lv_fs_dir_t * rddir_p, const char * path)
|
||||
}
|
||||
|
||||
const char * real_path = lv_fs_get_real_path(path);
|
||||
lv_fs_res_t res = rddir_p->drv->dir_open(rddir_p->dir_d, real_path);
|
||||
lv_fs_res_t res = rddir_p->drv->dir_open(rddir_p->dir_d, real_path);
|
||||
|
||||
return res;
|
||||
}
|
||||
@ -422,14 +420,14 @@ lv_fs_res_t lv_fs_dir_close(lv_fs_dir_t * rddir_p)
|
||||
lv_fs_res_t res;
|
||||
|
||||
if(rddir_p->drv->dir_close == NULL) {
|
||||
res = LV_FS_RES_NOT_IMP;
|
||||
res = LV_FS_RES_NOT_IMP;
|
||||
} else {
|
||||
res = rddir_p->drv->dir_close(rddir_p->dir_d);
|
||||
}
|
||||
|
||||
lv_mem_free(rddir_p->dir_d); /*Clean up*/
|
||||
lv_mem_free(rddir_p->dir_d); /*Clean up*/
|
||||
rddir_p->dir_d = NULL;
|
||||
rddir_p->drv = NULL;
|
||||
rddir_p->drv = NULL;
|
||||
rddir_p->dir_d = NULL;
|
||||
|
||||
return res;
|
||||
@ -453,11 +451,11 @@ lv_fs_res_t lv_fs_free_space(char letter, uint32_t * total_p, uint32_t * free_p)
|
||||
lv_fs_res_t res;
|
||||
|
||||
if(drv->free_space == NULL) {
|
||||
res = LV_FS_RES_NOT_IMP;
|
||||
res = LV_FS_RES_NOT_IMP;
|
||||
} else {
|
||||
uint32_t total_tmp = 0;
|
||||
uint32_t free_tmp = 0;
|
||||
res = drv->free_space(&total_tmp, &free_tmp);
|
||||
uint32_t free_tmp = 0;
|
||||
res = drv->free_space(&total_tmp, &free_tmp);
|
||||
|
||||
if(total_p != NULL) *total_p = total_tmp;
|
||||
if(free_p != NULL) *free_p = free_tmp;
|
||||
@ -475,7 +473,7 @@ void lv_fs_add_drv(lv_fs_drv_t * drv_p)
|
||||
{
|
||||
/*Save the new driver*/
|
||||
lv_fs_drv_t * new_drv;
|
||||
new_drv = lv_ll_ins_head(&LV_GC_ROOT(_lv_drv_ll));
|
||||
new_drv = lv_ll_ins_head(&LV_GC_ROOT(_lv_drv_ll));
|
||||
lv_mem_assert(new_drv);
|
||||
if(new_drv == NULL) return;
|
||||
|
||||
@ -487,12 +485,13 @@ void lv_fs_add_drv(lv_fs_drv_t * drv_p)
|
||||
* @param buf buffer to store the letters ('\0' added after the last letter)
|
||||
* @return the buffer
|
||||
*/
|
||||
char * lv_fs_get_letters(char * buf)
|
||||
char * lv_fs_get_letters(char * buf)
|
||||
{
|
||||
lv_fs_drv_t * drv;
|
||||
uint8_t i = 0;
|
||||
|
||||
LV_LL_READ(LV_GC_ROOT(_lv_drv_ll), drv) {
|
||||
LV_LL_READ(LV_GC_ROOT(_lv_drv_ll), drv)
|
||||
{
|
||||
buf[i] = drv->letter;
|
||||
i++;
|
||||
}
|
||||
@ -502,7 +501,6 @@ char * lv_fs_get_letters(char * buf)
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return with the extension of the filename
|
||||
* @param fn string with a filename
|
||||
@ -511,11 +509,11 @@ char * lv_fs_get_letters(char * buf)
|
||||
const char * lv_fs_get_ext(const char * fn)
|
||||
{
|
||||
uint16_t i;
|
||||
for(i = strlen(fn); i > 0; i --) {
|
||||
for(i = strlen(fn); i > 0; i--) {
|
||||
if(fn[i] == '.') {
|
||||
return &fn[i + 1];
|
||||
} else if(fn[i] == '/' || fn[i] == '\\') {
|
||||
return ""; /*No extension if a '\' or '/' found*/
|
||||
return ""; /*No extension if a '\' or '/' found*/
|
||||
}
|
||||
}
|
||||
|
||||
@ -532,17 +530,19 @@ char * lv_fs_up(char * path)
|
||||
uint16_t len = strlen(path);
|
||||
if(len == 0) return path;
|
||||
|
||||
len --; /*Go before the trailing '\0'*/
|
||||
len--; /*Go before the trailing '\0'*/
|
||||
|
||||
/*Ignore trailing '/' or '\'*/
|
||||
while(path[len] == '/' || path[len] == '\\') {
|
||||
path[len] = '\0';
|
||||
if(len > 0) len --;
|
||||
else return path;
|
||||
if(len > 0)
|
||||
len--;
|
||||
else
|
||||
return path;
|
||||
}
|
||||
|
||||
uint16_t i;
|
||||
for(i = len; i > 0; i --) {
|
||||
for(i = len; i > 0; i--) {
|
||||
if(path[i] == '/' || path[i] == '\\') break;
|
||||
}
|
||||
|
||||
@ -561,16 +561,18 @@ const char * lv_fs_get_last(const char * path)
|
||||
uint16_t len = strlen(path);
|
||||
if(len == 0) return path;
|
||||
|
||||
len --; /*Go before the trailing '\0'*/
|
||||
len--; /*Go before the trailing '\0'*/
|
||||
|
||||
/*Ignore trailing '/' or '\'*/
|
||||
while(path[len] == '/' || path[len] == '\\') {
|
||||
if(len > 0) len --;
|
||||
else return path;
|
||||
if(len > 0)
|
||||
len--;
|
||||
else
|
||||
return path;
|
||||
}
|
||||
|
||||
uint16_t i;
|
||||
for(i = len; i > 0; i --) {
|
||||
for(i = len; i > 0; i--) {
|
||||
if(path[i] == '/' || path[i] == '\\') break;
|
||||
}
|
||||
|
||||
@ -593,11 +595,11 @@ static const char * lv_fs_get_real_path(const char * path)
|
||||
/* Example path: "S:/folder/file.txt"
|
||||
* Leave the letter and the : / \ characters*/
|
||||
|
||||
path ++; /*Ignore the driver letter*/
|
||||
path++; /*Ignore the driver letter*/
|
||||
|
||||
while(*path != '\0') {
|
||||
if(*path == ':' || *path == '\\' || *path == '/') {
|
||||
path ++;
|
||||
path++;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
@ -615,7 +617,8 @@ static lv_fs_drv_t * lv_fs_get_drv(char letter)
|
||||
{
|
||||
lv_fs_drv_t * drv;
|
||||
|
||||
LV_LL_READ(LV_GC_ROOT(_lv_drv_ll), drv) {
|
||||
LV_LL_READ(LV_GC_ROOT(_lv_drv_ll), drv)
|
||||
{
|
||||
if(drv->letter == letter) {
|
||||
return drv;
|
||||
}
|
||||
|
@ -28,26 +28,25 @@ extern "C" {
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define LV_FS_MAX_FN_LENGTH 64
|
||||
#define LV_FS_MAX_FN_LENGTH 64
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
enum
|
||||
{
|
||||
enum {
|
||||
LV_FS_RES_OK = 0,
|
||||
LV_FS_RES_HW_ERR, /*Low level hardware error*/
|
||||
LV_FS_RES_FS_ERR, /*Error in the file system structure */
|
||||
LV_FS_RES_NOT_EX, /*Driver, file or directory is not exists*/
|
||||
LV_FS_RES_FULL, /*Disk full*/
|
||||
LV_FS_RES_LOCKED, /*The file is already opened*/
|
||||
LV_FS_RES_DENIED, /*Access denied. Check 'fs_open' modes and write protect*/
|
||||
LV_FS_RES_BUSY, /*The file system now can't handle it, try later*/
|
||||
LV_FS_RES_TOUT, /*Process time outed*/
|
||||
LV_FS_RES_NOT_IMP, /*Requested function is not implemented*/
|
||||
LV_FS_RES_OUT_OF_MEM, /*Not enough memory for an internal operation*/
|
||||
LV_FS_RES_INV_PARAM, /*Invalid parameter among arguments*/
|
||||
LV_FS_RES_UNKNOWN, /*Other unknown error*/
|
||||
LV_FS_RES_HW_ERR, /*Low level hardware error*/
|
||||
LV_FS_RES_FS_ERR, /*Error in the file system structure */
|
||||
LV_FS_RES_NOT_EX, /*Driver, file or directory is not exists*/
|
||||
LV_FS_RES_FULL, /*Disk full*/
|
||||
LV_FS_RES_LOCKED, /*The file is already opened*/
|
||||
LV_FS_RES_DENIED, /*Access denied. Check 'fs_open' modes and write protect*/
|
||||
LV_FS_RES_BUSY, /*The file system now can't handle it, try later*/
|
||||
LV_FS_RES_TOUT, /*Process time outed*/
|
||||
LV_FS_RES_NOT_IMP, /*Requested function is not implemented*/
|
||||
LV_FS_RES_OUT_OF_MEM, /*Not enough memory for an internal operation*/
|
||||
LV_FS_RES_INV_PARAM, /*Invalid parameter among arguments*/
|
||||
LV_FS_RES_UNKNOWN, /*Other unknown error*/
|
||||
};
|
||||
typedef uint8_t lv_fs_res_t;
|
||||
|
||||
@ -56,18 +55,16 @@ struct __lv_fs_drv_t;
|
||||
typedef struct
|
||||
{
|
||||
void * file_d;
|
||||
struct __lv_fs_drv_t* drv;
|
||||
struct __lv_fs_drv_t * drv;
|
||||
} lv_fs_file_t;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
void * dir_d;
|
||||
struct __lv_fs_drv_t * drv;
|
||||
} lv_fs_dir_t;
|
||||
|
||||
enum
|
||||
{
|
||||
enum {
|
||||
LV_FS_MODE_WR = 0x01,
|
||||
LV_FS_MODE_RD = 0x02,
|
||||
};
|
||||
@ -78,23 +75,23 @@ typedef struct __lv_fs_drv_t
|
||||
char letter;
|
||||
uint16_t file_size;
|
||||
uint16_t rddir_size;
|
||||
bool (*ready) (void);
|
||||
bool (*ready)(void);
|
||||
|
||||
lv_fs_res_t (*open) (void * file_p, const char * path, lv_fs_mode_t mode);
|
||||
lv_fs_res_t (*close) (void * file_p);
|
||||
lv_fs_res_t (*remove) (const char * fn);
|
||||
lv_fs_res_t (*read) (void * file_p, void * buf, uint32_t btr, uint32_t * br);
|
||||
lv_fs_res_t (*write) (void * file_p, const void * buf, uint32_t btw, uint32_t * bw);
|
||||
lv_fs_res_t (*seek) (void * file_p, uint32_t pos);
|
||||
lv_fs_res_t (*tell) (void * file_p, uint32_t * pos_p);
|
||||
lv_fs_res_t (*trunc) (void * file_p);
|
||||
lv_fs_res_t (*size) (void * file_p, uint32_t * size_p);
|
||||
lv_fs_res_t (*rename) (const char * oldname, const char * newname);
|
||||
lv_fs_res_t (*free_space) (uint32_t * total_p, uint32_t * free_p);
|
||||
lv_fs_res_t (*open)(void * file_p, const char * path, lv_fs_mode_t mode);
|
||||
lv_fs_res_t (*close)(void * file_p);
|
||||
lv_fs_res_t (*remove)(const char * fn);
|
||||
lv_fs_res_t (*read)(void * file_p, void * buf, uint32_t btr, uint32_t * br);
|
||||
lv_fs_res_t (*write)(void * file_p, const void * buf, uint32_t btw, uint32_t * bw);
|
||||
lv_fs_res_t (*seek)(void * file_p, uint32_t pos);
|
||||
lv_fs_res_t (*tell)(void * file_p, uint32_t * pos_p);
|
||||
lv_fs_res_t (*trunc)(void * file_p);
|
||||
lv_fs_res_t (*size)(void * file_p, uint32_t * size_p);
|
||||
lv_fs_res_t (*rename)(const char * oldname, const char * newname);
|
||||
lv_fs_res_t (*free_space)(uint32_t * total_p, uint32_t * free_p);
|
||||
|
||||
lv_fs_res_t (*dir_open) (void * rddir_p, const char * path);
|
||||
lv_fs_res_t (*dir_read) (void * rddir_p, char * fn);
|
||||
lv_fs_res_t (*dir_close) (void * rddir_p);
|
||||
lv_fs_res_t (*dir_open)(void * rddir_p, const char * path);
|
||||
lv_fs_res_t (*dir_read)(void * rddir_p, char * fn);
|
||||
lv_fs_res_t (*dir_close)(void * rddir_p);
|
||||
} lv_fs_drv_t;
|
||||
|
||||
/**********************
|
||||
@ -114,7 +111,8 @@ void lv_fs_init(void);
|
||||
void lv_fs_add_drv(lv_fs_drv_t * drv_p);
|
||||
|
||||
/**
|
||||
* Test if a drive is rady or not. If the `ready` function was not initialized `true` will be returned.
|
||||
* Test if a drive is rady or not. If the `ready` function was not initialized `true` will be
|
||||
* returned.
|
||||
* @param letter letter of the drive
|
||||
* @return true: drive is ready; false: drive is not ready
|
||||
*/
|
||||
@ -127,21 +125,21 @@ bool lv_fs_is_ready(char letter);
|
||||
* @param mode read: FS_MODE_RD, write: FS_MODE_WR, both: FS_MODE_RD | FS_MODE_WR
|
||||
* @return LV_FS_RES_OK or any error from lv_fs_res_t enum
|
||||
*/
|
||||
lv_fs_res_t lv_fs_open (lv_fs_file_t * file_p, const char * path, lv_fs_mode_t mode);
|
||||
lv_fs_res_t lv_fs_open(lv_fs_file_t * file_p, const char * path, lv_fs_mode_t mode);
|
||||
|
||||
/**
|
||||
* Close an already opened file
|
||||
* @param file_p pointer to a lv_fs_file_t variable
|
||||
* @return LV_FS_RES_OK or any error from lv_fs_res_t enum
|
||||
*/
|
||||
lv_fs_res_t lv_fs_close (lv_fs_file_t * file_p);
|
||||
lv_fs_res_t lv_fs_close(lv_fs_file_t * file_p);
|
||||
|
||||
/**
|
||||
* Delete a file
|
||||
* @param path path of the file to delete
|
||||
* @return LV_FS_RES_OK or any error from lv_fs_res_t enum
|
||||
*/
|
||||
lv_fs_res_t lv_fs_remove (const char * path);
|
||||
lv_fs_res_t lv_fs_remove(const char * path);
|
||||
|
||||
/**
|
||||
* Read from a file
|
||||
@ -151,7 +149,7 @@ lv_fs_res_t lv_fs_remove (const char * path);
|
||||
* @param br the number of real read bytes (Bytes Read). NULL if unused.
|
||||
* @return LV_FS_RES_OK or any error from lv_fs_res_t enum
|
||||
*/
|
||||
lv_fs_res_t lv_fs_read (lv_fs_file_t * file_p, void * buf, uint32_t btr, uint32_t * br);
|
||||
lv_fs_res_t lv_fs_read(lv_fs_file_t * file_p, void * buf, uint32_t btr, uint32_t * br);
|
||||
|
||||
/**
|
||||
* Write into a file
|
||||
@ -161,7 +159,7 @@ lv_fs_res_t lv_fs_read (lv_fs_file_t * file_p, void * buf, uint32_t btr, uint32_
|
||||
* @param br the number of real written bytes (Bytes Written). NULL if unused.
|
||||
* @return LV_FS_RES_OK or any error from lv_fs_res_t enum
|
||||
*/
|
||||
lv_fs_res_t lv_fs_write (lv_fs_file_t * file_p, const void * buf, uint32_t btw, uint32_t * bw);
|
||||
lv_fs_res_t lv_fs_write(lv_fs_file_t * file_p, const void * buf, uint32_t btw, uint32_t * bw);
|
||||
|
||||
/**
|
||||
* Set the position of the 'cursor' (read write pointer) in a file
|
||||
@ -169,7 +167,7 @@ lv_fs_res_t lv_fs_write (lv_fs_file_t * file_p, const void * buf, uint32_t btw,
|
||||
* @param pos the new position expressed in bytes index (0: start of file)
|
||||
* @return LV_FS_RES_OK or any error from lv_fs_res_t enum
|
||||
*/
|
||||
lv_fs_res_t lv_fs_seek (lv_fs_file_t * file_p, uint32_t pos);
|
||||
lv_fs_res_t lv_fs_seek(lv_fs_file_t * file_p, uint32_t pos);
|
||||
|
||||
/**
|
||||
* Give the position of the read write pointer
|
||||
@ -177,7 +175,7 @@ lv_fs_res_t lv_fs_seek (lv_fs_file_t * file_p, uint32_t pos);
|
||||
* @param pos_p pointer to store the position of the read write pointer
|
||||
* @return LV_FS_RES_OK or any error from 'fs_res_t'
|
||||
*/
|
||||
lv_fs_res_t lv_fs_tell (lv_fs_file_t * file_p, uint32_t * pos);
|
||||
lv_fs_res_t lv_fs_tell(lv_fs_file_t * file_p, uint32_t * pos);
|
||||
|
||||
/**
|
||||
* Truncate the file size to the current position of the read write pointer
|
||||
@ -185,7 +183,7 @@ lv_fs_res_t lv_fs_tell (lv_fs_file_t * file_p, uint32_t * pos);
|
||||
* @return LV_FS_RES_OK: no error, the file is read
|
||||
* any error from lv_fs_res_t enum
|
||||
*/
|
||||
lv_fs_res_t lv_fs_trunc (lv_fs_file_t * file_p);
|
||||
lv_fs_res_t lv_fs_trunc(lv_fs_file_t * file_p);
|
||||
|
||||
/**
|
||||
* Give the size of a file bytes
|
||||
@ -193,7 +191,7 @@ lv_fs_res_t lv_fs_trunc (lv_fs_file_t * file_p);
|
||||
* @param size pointer to a variable to store the size
|
||||
* @return LV_FS_RES_OK or any error from lv_fs_res_t enum
|
||||
*/
|
||||
lv_fs_res_t lv_fs_size (lv_fs_file_t * file_p, uint32_t * size);
|
||||
lv_fs_res_t lv_fs_size(lv_fs_file_t * file_p, uint32_t * size);
|
||||
|
||||
/**
|
||||
* Rename a file
|
||||
@ -201,7 +199,7 @@ lv_fs_res_t lv_fs_size (lv_fs_file_t * file_p, uint32_t * size);
|
||||
* @param newname path with the new name
|
||||
* @return LV_FS_RES_OK or any error from 'fs_res_t'
|
||||
*/
|
||||
lv_fs_res_t lv_fs_rename (const char * oldname, const char * newname);
|
||||
lv_fs_res_t lv_fs_rename(const char * oldname, const char * newname);
|
||||
|
||||
/**
|
||||
* Initialize a 'fs_dir_t' variable for directory reading
|
||||
@ -218,14 +216,14 @@ lv_fs_res_t lv_fs_dir_open(lv_fs_dir_t * rddir_p, const char * path);
|
||||
* @param fn pointer to a buffer to store the filename
|
||||
* @return LV_FS_RES_OK or any error from lv_fs_res_t enum
|
||||
*/
|
||||
lv_fs_res_t lv_fs_dir_read (lv_fs_dir_t * rddir_p, char * fn);
|
||||
lv_fs_res_t lv_fs_dir_read(lv_fs_dir_t * rddir_p, char * fn);
|
||||
|
||||
/**
|
||||
* Close the directory reading
|
||||
* @param rddir_p pointer to an initialized 'fs_dir_t' variable
|
||||
* @return LV_FS_RES_OK or any error from lv_fs_res_t enum
|
||||
*/
|
||||
lv_fs_res_t lv_fs_dir_close (lv_fs_dir_t * rddir_p);
|
||||
lv_fs_res_t lv_fs_dir_close(lv_fs_dir_t * rddir_p);
|
||||
|
||||
/**
|
||||
* Get the free and total size of a driver in kB
|
||||
@ -234,14 +232,14 @@ lv_fs_res_t lv_fs_dir_close (lv_fs_dir_t * rddir_p);
|
||||
* @param free_p pointer to store the free size [kB]
|
||||
* @return LV_FS_RES_OK or any error from lv_fs_res_t enum
|
||||
*/
|
||||
lv_fs_res_t lv_fs_free_space (char letter, uint32_t * total_p, uint32_t * free_p);
|
||||
lv_fs_res_t lv_fs_free_space(char letter, uint32_t * total_p, uint32_t * free_p);
|
||||
|
||||
/**
|
||||
* Fill a buffer with the letters of existing drivers
|
||||
* @param buf buffer to store the letters ('\0' added after the last letter)
|
||||
* @return the buffer
|
||||
*/
|
||||
char * lv_fs_get_letters(char * buf);
|
||||
char * lv_fs_get_letters(char * buf);
|
||||
|
||||
/**
|
||||
* Return with the extension of the filename
|
||||
|
@ -24,8 +24,8 @@
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
#if (!defined(LV_ENABLE_GC)) || LV_ENABLE_GC == 0
|
||||
LV_ROOTS
|
||||
#if(!defined(LV_ENABLE_GC)) || LV_ENABLE_GC == 0
|
||||
LV_ROOTS
|
||||
#endif /* LV_ENABLE_GC */
|
||||
/**********************
|
||||
* MACROS
|
||||
|
@ -29,30 +29,28 @@ extern "C" {
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
#define LV_GC_ROOTS(prefix) \
|
||||
prefix lv_ll_t _lv_task_ll; /*Linked list to store the lv_tasks*/ \
|
||||
prefix lv_ll_t _lv_disp_ll; /*Linked list of screens*/ \
|
||||
prefix lv_ll_t _lv_indev_ll; /*Linked list of screens*/ \
|
||||
prefix lv_ll_t _lv_drv_ll;\
|
||||
prefix lv_ll_t _lv_file_ll;\
|
||||
prefix lv_ll_t _lv_anim_ll;\
|
||||
prefix lv_ll_t _lv_group_ll;\
|
||||
prefix void * _lv_task_act;\
|
||||
|
||||
|
||||
#define LV_GC_ROOTS(prefix) \
|
||||
prefix lv_ll_t _lv_task_ll; /*Linked list to store the lv_tasks*/ \
|
||||
prefix lv_ll_t _lv_disp_ll; /*Linked list of screens*/ \
|
||||
prefix lv_ll_t _lv_indev_ll; /*Linked list of screens*/ \
|
||||
prefix lv_ll_t _lv_drv_ll; \
|
||||
prefix lv_ll_t _lv_file_ll; \
|
||||
prefix lv_ll_t _lv_anim_ll; \
|
||||
prefix lv_ll_t _lv_group_ll; \
|
||||
prefix void * _lv_task_act;
|
||||
|
||||
#define LV_NO_PREFIX
|
||||
#define LV_ROOTS LV_GC_ROOTS(LV_NO_PREFIX)
|
||||
|
||||
#if LV_ENABLE_GC == 1
|
||||
# if LV_MEM_CUSTOM != 1
|
||||
# error "GC requires CUSTOM_MEM"
|
||||
# endif /* LV_MEM_CUSTOM */
|
||||
#else /* LV_ENABLE_GC */
|
||||
# define LV_GC_ROOT(x) x
|
||||
LV_GC_ROOTS(extern)
|
||||
#if LV_MEM_CUSTOM != 1
|
||||
#error "GC requires CUSTOM_MEM"
|
||||
#endif /* LV_MEM_CUSTOM */
|
||||
#else /* LV_ENABLE_GC */
|
||||
#define LV_GC_ROOT(x) x
|
||||
LV_GC_ROOTS(extern)
|
||||
#endif /* LV_ENABLE_GC */
|
||||
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
@ -65,7 +63,6 @@ extern "C" {
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
@ -16,9 +16,9 @@
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define LL_NODE_META_SIZE (sizeof(lv_ll_node_t*) + sizeof(lv_ll_node_t*))
|
||||
#define LL_NODE_META_SIZE (sizeof(lv_ll_node_t *) + sizeof(lv_ll_node_t *))
|
||||
#define LL_PREV_P_OFFSET(ll_p) (ll_p->n_size)
|
||||
#define LL_NEXT_P_OFFSET(ll_p) (ll_p->n_size + sizeof(lv_ll_node_t*))
|
||||
#define LL_NEXT_P_OFFSET(ll_p) (ll_p->n_size + sizeof(lv_ll_node_t *))
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
@ -80,15 +80,15 @@ void * lv_ll_ins_head(lv_ll_t * ll_p)
|
||||
n_new = lv_mem_alloc(ll_p->n_size + LL_NODE_META_SIZE);
|
||||
|
||||
if(n_new != NULL) {
|
||||
node_set_prev(ll_p, n_new, NULL); /*No prev. before the new head*/
|
||||
node_set_next(ll_p, n_new, ll_p->head); /*After new comes the old head*/
|
||||
node_set_prev(ll_p, n_new, NULL); /*No prev. before the new head*/
|
||||
node_set_next(ll_p, n_new, ll_p->head); /*After new comes the old head*/
|
||||
|
||||
if(ll_p->head != NULL) { /*If there is old head then before it goes the new*/
|
||||
node_set_prev(ll_p, ll_p->head, n_new);
|
||||
}
|
||||
|
||||
ll_p->head = n_new; /*Set the new head in the dsc.*/
|
||||
if(ll_p->tail == NULL) {/*If there is no tail (1. node) set the tail too*/
|
||||
ll_p->head = n_new; /*Set the new head in the dsc.*/
|
||||
if(ll_p->tail == NULL) { /*If there is no tail (1. node) set the tail too*/
|
||||
ll_p->tail = n_new;
|
||||
}
|
||||
}
|
||||
@ -139,9 +139,9 @@ void * lv_ll_ins_tail(lv_ll_t * ll_p)
|
||||
if(n_new == NULL) return NULL;
|
||||
|
||||
if(n_new != NULL) {
|
||||
node_set_next(ll_p, n_new, NULL); /*No next after the new tail*/
|
||||
node_set_next(ll_p, n_new, NULL); /*No next after the new tail*/
|
||||
node_set_prev(ll_p, n_new, ll_p->tail); /*The prev. before new is tho old tail*/
|
||||
if(ll_p->tail != NULL) { /*If there is old tail then the new comes after it*/
|
||||
if(ll_p->tail != NULL) { /*If there is old tail then the new comes after it*/
|
||||
node_set_next(ll_p, ll_p->tail, n_new);
|
||||
}
|
||||
|
||||
@ -154,14 +154,13 @@ void * lv_ll_ins_tail(lv_ll_t * ll_p)
|
||||
return n_new;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Remove the node 'node_p' from 'll_p' linked list.
|
||||
* It does not free the the memory of node.
|
||||
* @param ll_p pointer to the linked list of 'node_p'
|
||||
* @param node_p pointer to node in 'll_p' linked list
|
||||
*/
|
||||
void lv_ll_rem(lv_ll_t * ll_p, void * node_p)
|
||||
void lv_ll_rem(lv_ll_t * ll_p, void * node_p)
|
||||
{
|
||||
if(lv_ll_get_head(ll_p) == node_p) {
|
||||
/*The new head will be the node after 'n_act'*/
|
||||
@ -197,7 +196,7 @@ void lv_ll_clear(lv_ll_t * ll_p)
|
||||
void * i;
|
||||
void * i_next;
|
||||
|
||||
i = lv_ll_get_head(ll_p);
|
||||
i = lv_ll_get_head(ll_p);
|
||||
i_next = NULL;
|
||||
|
||||
while(i != NULL) {
|
||||
@ -228,8 +227,8 @@ void lv_ll_chg_list(lv_ll_t * ll_ori_p, lv_ll_t * ll_new_p, void * node)
|
||||
node_set_prev(ll_new_p, ll_new_p->head, node);
|
||||
}
|
||||
|
||||
ll_new_p->head = node; /*Set the new head in the dsc.*/
|
||||
if(ll_new_p->tail == NULL) { /*If there is no tail (first node) set the tail too*/
|
||||
ll_new_p->head = node; /*Set the new head in the dsc.*/
|
||||
if(ll_new_p->tail == NULL) { /*If there is no tail (first node) set the tail too*/
|
||||
ll_new_p->tail = node;
|
||||
}
|
||||
}
|
||||
@ -243,7 +242,7 @@ void * lv_ll_get_head(const lv_ll_t * ll_p)
|
||||
{
|
||||
void * head = NULL;
|
||||
|
||||
if(ll_p != NULL) {
|
||||
if(ll_p != NULL) {
|
||||
head = ll_p->head;
|
||||
}
|
||||
|
||||
@ -259,7 +258,7 @@ void * lv_ll_get_tail(const lv_ll_t * ll_p)
|
||||
{
|
||||
void * tail = NULL;
|
||||
|
||||
if(ll_p != NULL) {
|
||||
if(ll_p != NULL) {
|
||||
tail = ll_p->tail;
|
||||
}
|
||||
|
||||
@ -272,11 +271,11 @@ void * lv_ll_get_tail(const lv_ll_t * ll_p)
|
||||
* @param n_act pointer a node
|
||||
* @return pointer to the next node
|
||||
*/
|
||||
void * lv_ll_get_next(const lv_ll_t * ll_p, const void * n_act)
|
||||
void * lv_ll_get_next(const lv_ll_t * ll_p, const void * n_act)
|
||||
{
|
||||
void * next = NULL;
|
||||
|
||||
if(ll_p != NULL) {
|
||||
if(ll_p != NULL) {
|
||||
const lv_ll_node_t * n_act_d = n_act;
|
||||
memcpy(&next, n_act_d + LL_NEXT_P_OFFSET(ll_p), sizeof(void *));
|
||||
}
|
||||
@ -290,7 +289,7 @@ void * lv_ll_get_next(const lv_ll_t * ll_p, const void * n_act)
|
||||
* @param n_act pointer a node
|
||||
* @return pointer to the previous node
|
||||
*/
|
||||
void * lv_ll_get_prev(const lv_ll_t * ll_p, const void * n_act)
|
||||
void * lv_ll_get_prev(const lv_ll_t * ll_p, const void * n_act)
|
||||
{
|
||||
void * prev = NULL;
|
||||
|
||||
@ -318,14 +317,15 @@ void lv_ll_swap(lv_ll_t * ll_p, void * n1_p, void * n2_p)
|
||||
*/
|
||||
void lv_ll_move_before(lv_ll_t * ll_p, void * n_act, void * n_after)
|
||||
{
|
||||
if(n_act == n_after) return; /*Can't move before itself*/
|
||||
|
||||
if(n_act == n_after) return; /*Can't move before itself*/
|
||||
|
||||
void * n_before;
|
||||
if(n_after != NULL) n_before = lv_ll_get_prev(ll_p, n_after);
|
||||
else n_before = lv_ll_get_tail(ll_p); /*if `n_after` is NULL `n_act` should be the new tail*/
|
||||
if(n_after != NULL)
|
||||
n_before = lv_ll_get_prev(ll_p, n_after);
|
||||
else
|
||||
n_before = lv_ll_get_tail(ll_p); /*if `n_after` is NULL `n_act` should be the new tail*/
|
||||
|
||||
if(n_act == n_before) return; /*Already before `n_after`*/
|
||||
if(n_act == n_before) return; /*Already before `n_after`*/
|
||||
|
||||
/*It's much easier to remove from the list and add again*/
|
||||
lv_ll_rem(ll_p, n_act);
|
||||
@ -354,7 +354,6 @@ bool lv_ll_is_empty(lv_ll_t * ll_p)
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
@ -367,11 +366,13 @@ bool lv_ll_is_empty(lv_ll_t * ll_p)
|
||||
*/
|
||||
static void node_set_prev(lv_ll_t * ll_p, lv_ll_node_t * act, lv_ll_node_t * prev)
|
||||
{
|
||||
if(act == NULL) return; /*Can't set the prev node of `NULL`*/
|
||||
if(act == NULL) return; /*Can't set the prev node of `NULL`*/
|
||||
|
||||
uint32_t node_p_size = sizeof(lv_ll_node_t *);
|
||||
if(prev) memcpy(act + LL_PREV_P_OFFSET(ll_p), &prev, node_p_size);
|
||||
else memset(act + LL_PREV_P_OFFSET(ll_p), 0, node_p_size);
|
||||
if(prev)
|
||||
memcpy(act + LL_PREV_P_OFFSET(ll_p), &prev, node_p_size);
|
||||
else
|
||||
memset(act + LL_PREV_P_OFFSET(ll_p), 0, node_p_size);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -382,10 +383,11 @@ static void node_set_prev(lv_ll_t * ll_p, lv_ll_node_t * act, lv_ll_node_t * pre
|
||||
*/
|
||||
static void node_set_next(lv_ll_t * ll_p, lv_ll_node_t * act, lv_ll_node_t * next)
|
||||
{
|
||||
if(act == NULL) return; /*Can't set the next node of `NULL`*/
|
||||
if(act == NULL) return; /*Can't set the next node of `NULL`*/
|
||||
|
||||
uint32_t node_p_size = sizeof(lv_ll_node_t *);
|
||||
if(next) memcpy(act + LL_NEXT_P_OFFSET(ll_p), &next, node_p_size);
|
||||
else memset(act + LL_NEXT_P_OFFSET(ll_p), 0, node_p_size);
|
||||
if(next)
|
||||
memcpy(act + LL_NEXT_P_OFFSET(ll_p), &next, node_p_size);
|
||||
else
|
||||
memset(act + LL_NEXT_P_OFFSET(ll_p), 0, node_p_size);
|
||||
}
|
||||
|
||||
|
@ -10,7 +10,6 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
@ -34,8 +33,8 @@ typedef uint8_t lv_ll_node_t;
|
||||
typedef struct
|
||||
{
|
||||
uint32_t n_size;
|
||||
lv_ll_node_t* head;
|
||||
lv_ll_node_t* tail;
|
||||
lv_ll_node_t * head;
|
||||
lv_ll_node_t * tail;
|
||||
} lv_ll_t;
|
||||
|
||||
/**********************
|
||||
@ -77,7 +76,7 @@ void * lv_ll_ins_tail(lv_ll_t * ll_p);
|
||||
* @param ll_p pointer to the linked list of 'node_p'
|
||||
* @param node_p pointer to node in 'll_p' linked list
|
||||
*/
|
||||
void lv_ll_rem(lv_ll_t * ll_p, void * node_p);
|
||||
void lv_ll_rem(lv_ll_t * ll_p, void * node_p);
|
||||
|
||||
/**
|
||||
* Remove and free all elements from a linked list. The list remain valid but become empty.
|
||||
@ -143,7 +142,8 @@ bool lv_ll_is_empty(lv_ll_t * ll_p);
|
||||
|
||||
#define LV_LL_READ(list, i) for(i = lv_ll_get_head(&list); i != NULL; i = lv_ll_get_next(&list, i))
|
||||
|
||||
#define LV_LL_READ_BACK(list, i) for(i = lv_ll_get_tail(&list); i != NULL; i = lv_ll_get_prev(&list, i))
|
||||
#define LV_LL_READ_BACK(list, i) \
|
||||
for(i = lv_ll_get_tail(&list); i != NULL; i = lv_ll_get_prev(&list, i))
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
@ -27,7 +27,7 @@
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
static void (*print_cb)(lv_log_level_t, const char *, uint32_t, const char *);
|
||||
static void (*print_cb)(lv_log_level_t, const char *, uint32_t, const char *);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
@ -40,9 +40,10 @@ static void (*print_cb)(lv_log_level_t, const char *, uint32_t, const char *);
|
||||
/**
|
||||
* Register custom print (or anything else) function to call when log is added
|
||||
* @param f a function pointer:
|
||||
* `void my_print (lv_log_level_t level, const char * file, uint32_t line, const char * dsc)`
|
||||
* `void my_print (lv_log_level_t level, const char * file, uint32_t line, const char *
|
||||
* dsc)`
|
||||
*/
|
||||
void lv_log_register_print(void f(lv_log_level_t, const char *, uint32_t, const char *))
|
||||
void lv_log_register_print(void f(lv_log_level_t, const char *, uint32_t, const char *))
|
||||
{
|
||||
print_cb = f;
|
||||
}
|
||||
@ -56,13 +57,13 @@ void lv_log_register_print(void f(lv_log_level_t, const char *, uint32_t, const
|
||||
*/
|
||||
void lv_log_add(lv_log_level_t level, const char * file, int line, const char * dsc)
|
||||
{
|
||||
if(level >= _LV_LOG_LEVEL_NUM) return; /*Invalid level*/
|
||||
if(level >= _LV_LOG_LEVEL_NUM) return; /*Invalid level*/
|
||||
|
||||
if(level >= LV_LOG_LEVEL) {
|
||||
|
||||
#if LV_LOG_PRINTF
|
||||
static const char * lvl_prefix[] = {"Trace", "Info", "Warn", "Error"};
|
||||
printf("%s: %s \t(%s #%d)\n", lvl_prefix[level], dsc, file, line);
|
||||
printf("%s: %s \t(%s #%d)\n", lvl_prefix[level], dsc, file, line);
|
||||
#else
|
||||
if(print_cb) print_cb(level, file, line, dsc);
|
||||
#endif
|
||||
|
@ -26,11 +26,11 @@ extern "C" {
|
||||
|
||||
/*Possible log level. For compatibility declare it independently from `LV_USE_LOG`*/
|
||||
|
||||
#define LV_LOG_LEVEL_TRACE 0 /*A lot of logs to give detailed information*/
|
||||
#define LV_LOG_LEVEL_INFO 1 /*Log important events*/
|
||||
#define LV_LOG_LEVEL_WARN 2 /*Log if something unwanted happened but didn't caused problem*/
|
||||
#define LV_LOG_LEVEL_ERROR 3 /*Only critical issue, when the system may fail*/
|
||||
#define _LV_LOG_LEVEL_NUM 4
|
||||
#define LV_LOG_LEVEL_TRACE 0 /*A lot of logs to give detailed information*/
|
||||
#define LV_LOG_LEVEL_INFO 1 /*Log important events*/
|
||||
#define LV_LOG_LEVEL_WARN 2 /*Log if something unwanted happened but didn't caused problem*/
|
||||
#define LV_LOG_LEVEL_ERROR 3 /*Only critical issue, when the system may fail*/
|
||||
#define _LV_LOG_LEVEL_NUM 4
|
||||
|
||||
typedef int8_t lv_log_level_t;
|
||||
|
||||
@ -39,7 +39,6 @@ typedef int8_t lv_log_level_t;
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
@ -47,9 +46,10 @@ typedef int8_t lv_log_level_t;
|
||||
/**
|
||||
* Register custom print (or anything else) function to call when log is added
|
||||
* @param f a function pointer:
|
||||
* `void my_print (lv_log_level_t level, const char * file, uint32_t line, const char * dsc)`
|
||||
* `void my_print (lv_log_level_t level, const char * file, uint32_t line, const char *
|
||||
* dsc)`
|
||||
*/
|
||||
void lv_log_register_print(void f(lv_log_level_t, const char *, uint32_t, const char *));
|
||||
void lv_log_register_print(void f(lv_log_level_t, const char *, uint32_t, const char *));
|
||||
|
||||
/**
|
||||
* Add a log
|
||||
@ -64,19 +64,34 @@ void lv_log_add(lv_log_level_t level, const char * file, int line, const char *
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#define LV_LOG_TRACE(dsc) lv_log_add(LV_LOG_LEVEL_TRACE, __FILE__, __LINE__, dsc);
|
||||
#define LV_LOG_INFO(dsc) lv_log_add(LV_LOG_LEVEL_INFO, __FILE__, __LINE__, dsc);
|
||||
#define LV_LOG_WARN(dsc) lv_log_add(LV_LOG_LEVEL_WARN, __FILE__, __LINE__, dsc);
|
||||
#define LV_LOG_ERROR(dsc) lv_log_add(LV_LOG_LEVEL_ERROR, __FILE__, __LINE__, dsc);
|
||||
#define LV_LOG_TRACE(dsc) lv_log_add(LV_LOG_LEVEL_TRACE, __FILE__, __LINE__, dsc);
|
||||
#define LV_LOG_INFO(dsc) lv_log_add(LV_LOG_LEVEL_INFO, __FILE__, __LINE__, dsc);
|
||||
#define LV_LOG_WARN(dsc) lv_log_add(LV_LOG_LEVEL_WARN, __FILE__, __LINE__, dsc);
|
||||
#define LV_LOG_ERROR(dsc) lv_log_add(LV_LOG_LEVEL_ERROR, __FILE__, __LINE__, dsc);
|
||||
|
||||
#else /*LV_USE_LOG*/
|
||||
|
||||
/*Do nothing if `LV_USE_LOG 0`*/
|
||||
#define lv_log_add(level, file, line, dsc) {;}
|
||||
#define LV_LOG_TRACE(dsc) {;}
|
||||
#define LV_LOG_INFO(dsc) {;}
|
||||
#define LV_LOG_WARN(dsc) {;}
|
||||
#define LV_LOG_ERROR(dsc) {;}
|
||||
#define lv_log_add(level, file, line, dsc) \
|
||||
{ \
|
||||
; \
|
||||
}
|
||||
#define LV_LOG_TRACE(dsc) \
|
||||
{ \
|
||||
; \
|
||||
}
|
||||
#define LV_LOG_INFO(dsc) \
|
||||
{ \
|
||||
; \
|
||||
}
|
||||
#define LV_LOG_WARN(dsc) \
|
||||
{ \
|
||||
; \
|
||||
}
|
||||
#define LV_LOG_ERROR(dsc) \
|
||||
{ \
|
||||
; \
|
||||
}
|
||||
#endif /*LV_USE_LOG*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -26,18 +26,13 @@
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
static int16_t sin0_90_table[] = {
|
||||
0, 572, 1144, 1715, 2286, 2856, 3425, 3993, 4560, 5126,
|
||||
5690, 6252, 6813, 7371, 7927, 8481, 9032, 9580, 10126, 10668,
|
||||
11207, 11743, 12275, 12803, 13328, 13848, 14364, 14876, 15383, 15886,
|
||||
16383, 16876, 17364, 17846, 18323, 18794, 19260, 19720, 20173, 20621,
|
||||
21062, 21497, 21925, 22347, 22762, 23170, 23571, 23964, 24351, 24730,
|
||||
25101, 25465, 25821, 26169, 26509, 26841, 27165, 27481, 27788, 28087,
|
||||
28377, 28659, 28932, 29196, 29451, 29697, 29934, 30162, 30381, 30591,
|
||||
30791, 30982, 31163, 31335, 31498, 31650, 31794, 31927, 32051, 32165,
|
||||
32269, 32364, 32448, 32523, 32587, 32642, 32687, 32722, 32747, 32762,
|
||||
32767
|
||||
};
|
||||
|
||||
0, 572, 1144, 1715, 2286, 2856, 3425, 3993, 4560, 5126, 5690, 6252, 6813,
|
||||
7371, 7927, 8481, 9032, 9580, 10126, 10668, 11207, 11743, 12275, 12803, 13328, 13848,
|
||||
14364, 14876, 15383, 15886, 16383, 16876, 17364, 17846, 18323, 18794, 19260, 19720, 20173,
|
||||
20621, 21062, 21497, 21925, 22347, 22762, 23170, 23571, 23964, 24351, 24730, 25101, 25465,
|
||||
25821, 26169, 26509, 26841, 27165, 27481, 27788, 28087, 28377, 28659, 28932, 29196, 29451,
|
||||
29697, 29934, 30162, 30381, 30591, 30791, 30982, 31163, 31335, 31498, 31650, 31794, 31927,
|
||||
32051, 32165, 32269, 32364, 32448, 32523, 32587, 32642, 32687, 32722, 32747, 32762, 32767};
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
@ -55,7 +50,7 @@ static int16_t sin0_90_table[] = {
|
||||
int16_t lv_trigo_sin(int16_t angle)
|
||||
{
|
||||
int16_t ret = 0;
|
||||
angle = angle % 360;
|
||||
angle = angle % 360;
|
||||
|
||||
if(angle < 0) angle = 360 + angle;
|
||||
|
||||
@ -63,13 +58,13 @@ int16_t lv_trigo_sin(int16_t angle)
|
||||
ret = sin0_90_table[angle];
|
||||
} else if(angle >= 90 && angle < 180) {
|
||||
angle = 180 - angle;
|
||||
ret = sin0_90_table[angle];
|
||||
ret = sin0_90_table[angle];
|
||||
} else if(angle >= 180 && angle < 270) {
|
||||
angle = angle - 180;
|
||||
ret = - sin0_90_table[angle];
|
||||
ret = -sin0_90_table[angle];
|
||||
} else { /*angle >=270*/
|
||||
angle = 360 - angle;
|
||||
ret = - sin0_90_table[angle];
|
||||
ret = -sin0_90_table[angle];
|
||||
}
|
||||
|
||||
return ret;
|
||||
@ -86,12 +81,11 @@ int16_t lv_trigo_sin(int16_t angle)
|
||||
*/
|
||||
int32_t lv_bezier3(uint32_t t, int32_t u0, int32_t u1, int32_t u2, int32_t u3)
|
||||
{
|
||||
uint32_t t_rem = 1024 - t;
|
||||
uint32_t t_rem = 1024 - t;
|
||||
uint32_t t_rem2 = (t_rem * t_rem) >> 10;
|
||||
uint32_t t_rem3 = (t_rem2 * t_rem) >> 10;
|
||||
uint32_t t2 = (t * t) >> 10;
|
||||
uint32_t t3 = (t2 * t) >> 10;
|
||||
|
||||
uint32_t t2 = (t * t) >> 10;
|
||||
uint32_t t3 = (t2 * t) >> 10;
|
||||
|
||||
uint32_t v1 = ((uint32_t)t_rem3 * u0) >> 10;
|
||||
uint32_t v2 = ((uint32_t)3 * t_rem2 * t * u1) >> 20;
|
||||
@ -99,11 +93,8 @@ int32_t lv_bezier3(uint32_t t, int32_t u0, int32_t u1, int32_t u2, int32_t u3)
|
||||
uint32_t v4 = ((uint32_t)t3 * u3) >> 10;
|
||||
|
||||
return v1 + v2 + v3 + v4;
|
||||
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
|
||||
|
@ -10,7 +10,6 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
@ -19,15 +18,15 @@ extern "C" {
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define LV_MATH_MIN(a,b) ((a) < (b) ? (a) : (b))
|
||||
#define LV_MATH_MAX(a,b) ((a) > (b) ? (a) : (b))
|
||||
#define LV_MATH_MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||
#define LV_MATH_MAX(a, b) ((a) > (b) ? (a) : (b))
|
||||
#define LV_MATH_ABS(x) ((x) > 0 ? (x) : (-(x)))
|
||||
|
||||
#define LV_TRIGO_SIN_MAX 32767
|
||||
#define LV_TRIGO_SHIFT 15 /* >> LV_TRIGO_SHIFT to normalize*/
|
||||
#define LV_TRIGO_SIN_MAX 32767
|
||||
#define LV_TRIGO_SHIFT 15 /* >> LV_TRIGO_SHIFT to normalize*/
|
||||
|
||||
#define LV_BEZIER_VAL_MAX 1024 /*Max time in Bezier functions (not [0..1] to use integers) */
|
||||
#define LV_BEZIER_VAL_SHIFT 10 /*log2(LV_BEZIER_VAL_MAX): used to normalize up scaled values*/
|
||||
#define LV_BEZIER_VAL_MAX 1024 /*Max time in Bezier functions (not [0..1] to use integers) */
|
||||
#define LV_BEZIER_VAL_SHIFT 10 /*log2(LV_BEZIER_VAL_MAX): used to normalize up scaled values*/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
|
@ -18,16 +18,15 @@
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define LV_MEM_ADD_JUNK 0 /*Add memory junk on alloc (0xaa) and free(0xbb) (just for testing purposes)*/
|
||||
|
||||
#define LV_MEM_ADD_JUNK \
|
||||
0 /*Add memory junk on alloc (0xaa) and free(0xbb) (just for testing purposes)*/
|
||||
|
||||
#ifdef LV_MEM_ENV64
|
||||
# define MEM_UNIT uint64_t
|
||||
#define MEM_UNIT uint64_t
|
||||
#else
|
||||
# define MEM_UNIT uint32_t
|
||||
#define MEM_UNIT uint32_t
|
||||
#endif
|
||||
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
@ -35,17 +34,20 @@
|
||||
#if LV_ENABLE_GC == 0 /*gc custom allocations must not include header*/
|
||||
|
||||
/*The size of this union must be 4 bytes (uint32_t)*/
|
||||
typedef union {
|
||||
struct {
|
||||
MEM_UNIT used: 1; //1: if the entry is used
|
||||
MEM_UNIT d_size: 31; //Size off the data (1 means 4 bytes)
|
||||
typedef union
|
||||
{
|
||||
struct
|
||||
{
|
||||
MEM_UNIT used : 1; // 1: if the entry is used
|
||||
MEM_UNIT d_size : 31; // Size off the data (1 means 4 bytes)
|
||||
} s;
|
||||
MEM_UNIT header; //The header (used + d_size)
|
||||
MEM_UNIT header; // The header (used + d_size)
|
||||
} lv_mem_header_t;
|
||||
|
||||
typedef struct {
|
||||
typedef struct
|
||||
{
|
||||
lv_mem_header_t header;
|
||||
uint8_t first_data; /*First data byte in the allocated data (Just for easily create a pointer)*/
|
||||
uint8_t first_data; /*First data byte in the allocated data (Just for easily create a pointer)*/
|
||||
} lv_mem_ent_t;
|
||||
|
||||
#endif /* LV_ENABLE_GC */
|
||||
@ -54,7 +56,7 @@ typedef struct {
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
#if LV_MEM_CUSTOM == 0
|
||||
static lv_mem_ent_t * ent_get_next(lv_mem_ent_t * act_e);
|
||||
static lv_mem_ent_t * ent_get_next(lv_mem_ent_t * act_e);
|
||||
static void * ent_alloc(lv_mem_ent_t * e, uint32_t size);
|
||||
static void ent_trunc(lv_mem_ent_t * e, uint32_t size);
|
||||
#endif
|
||||
@ -66,7 +68,7 @@ static void ent_trunc(lv_mem_ent_t * e, uint32_t size);
|
||||
static uint8_t * work_mem;
|
||||
#endif
|
||||
|
||||
static uint32_t zero_mem; /*Give the address of this variable if 0 byte should be allocated*/
|
||||
static uint32_t zero_mem; /*Give the address of this variable if 0 byte should be allocated*/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
@ -86,9 +88,9 @@ void lv_mem_init(void)
|
||||
#if LV_MEM_ADR == 0
|
||||
/*Allocate a large array to store the dynamically allocated data*/
|
||||
static LV_MEM_ATTR MEM_UNIT work_mem_int[LV_MEM_SIZE / sizeof(MEM_UNIT)];
|
||||
work_mem = (uint8_t *) work_mem_int;
|
||||
work_mem = (uint8_t *)work_mem_int;
|
||||
#else
|
||||
work_mem = (uint8_t *) LV_MEM_ADR;
|
||||
work_mem = (uint8_t *)LV_MEM_ADR;
|
||||
#endif
|
||||
|
||||
lv_mem_ent_t * full = (lv_mem_ent_t *)work_mem;
|
||||
@ -127,32 +129,31 @@ void * lv_mem_alloc(uint32_t size)
|
||||
#if LV_MEM_CUSTOM == 0 /*Use the allocation from dyn_mem*/
|
||||
lv_mem_ent_t * e = NULL;
|
||||
|
||||
//Search for a appropriate entry
|
||||
// Search for a appropriate entry
|
||||
do {
|
||||
//Get the next entry
|
||||
// Get the next entry
|
||||
e = ent_get_next(e);
|
||||
|
||||
/*If there is next entry then try to allocate there*/
|
||||
if(e != NULL) {
|
||||
alloc = ent_alloc(e, size);
|
||||
}
|
||||
//End if there is not next entry OR the alloc. is successful
|
||||
// End if there is not next entry OR the alloc. is successful
|
||||
} while(e != NULL && alloc == NULL);
|
||||
|
||||
|
||||
#else /*Use custom, user defined malloc function*/
|
||||
#else /*Use custom, user defined malloc function*/
|
||||
#if LV_ENABLE_GC == 1 /*gc must not include header*/
|
||||
alloc = LV_MEM_CUSTOM_ALLOC(size);
|
||||
#else /* LV_ENABLE_GC */
|
||||
#else /* LV_ENABLE_GC */
|
||||
/*Allocate a header too to store the size*/
|
||||
alloc = LV_MEM_CUSTOM_ALLOC(size + sizeof(lv_mem_header_t));
|
||||
if(alloc != NULL) {
|
||||
((lv_mem_ent_t *) alloc)->header.s.d_size = size;
|
||||
((lv_mem_ent_t *) alloc)->header.s.used = 1;
|
||||
alloc = &((lv_mem_ent_t *) alloc)->first_data;
|
||||
((lv_mem_ent_t *)alloc)->header.s.d_size = size;
|
||||
((lv_mem_ent_t *)alloc)->header.s.used = 1;
|
||||
alloc = &((lv_mem_ent_t *)alloc)->first_data;
|
||||
}
|
||||
#endif /* LV_ENABLE_GC */
|
||||
#endif /* LV_MEM_CUSTOM */
|
||||
#endif /* LV_ENABLE_GC */
|
||||
#endif /* LV_MEM_CUSTOM */
|
||||
|
||||
#if LV_MEM_ADD_JUNK
|
||||
if(alloc != NULL) memset(alloc, 0xaa, size);
|
||||
@ -172,14 +173,13 @@ void lv_mem_free(const void * data)
|
||||
if(data == &zero_mem) return;
|
||||
if(data == NULL) return;
|
||||
|
||||
|
||||
#if LV_MEM_ADD_JUNK
|
||||
memset((void *)data, 0xbb, lv_mem_get_size(data));
|
||||
#endif
|
||||
|
||||
#if LV_ENABLE_GC==0
|
||||
#if LV_ENABLE_GC == 0
|
||||
/*e points to the header*/
|
||||
lv_mem_ent_t * e = (lv_mem_ent_t *)((uint8_t *) data - sizeof(lv_mem_header_t));
|
||||
lv_mem_ent_t * e = (lv_mem_ent_t *)((uint8_t *)data - sizeof(lv_mem_header_t));
|
||||
e->header.s.used = 0;
|
||||
#endif
|
||||
|
||||
@ -199,10 +199,10 @@ void lv_mem_free(const void * data)
|
||||
}
|
||||
#endif
|
||||
#else /*Use custom, user defined free function*/
|
||||
#if LV_ENABLE_GC==0
|
||||
#if LV_ENABLE_GC == 0
|
||||
LV_MEM_CUSTOM_FREE(e);
|
||||
#else
|
||||
LV_MEM_CUSTOM_FREE((void*)data);
|
||||
LV_MEM_CUSTOM_FREE((void *)data);
|
||||
#endif /*LV_ENABLE_GC*/
|
||||
#endif
|
||||
}
|
||||
@ -215,26 +215,27 @@ void lv_mem_free(const void * data)
|
||||
* @return pointer to the new memory
|
||||
*/
|
||||
|
||||
#if LV_ENABLE_GC==0
|
||||
#if LV_ENABLE_GC == 0
|
||||
|
||||
void * lv_mem_realloc(void * data_p, uint32_t new_size)
|
||||
{
|
||||
/*data_p could be previously freed pointer (in this case it is invalid)*/
|
||||
if(data_p != NULL) {
|
||||
lv_mem_ent_t * e = (lv_mem_ent_t *)((uint8_t *) data_p - sizeof(lv_mem_header_t));
|
||||
lv_mem_ent_t * e = (lv_mem_ent_t *)((uint8_t *)data_p - sizeof(lv_mem_header_t));
|
||||
if(e->header.s.used == 0) {
|
||||
data_p = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t old_size = lv_mem_get_size(data_p);
|
||||
if(old_size == new_size) return data_p; /*Also avoid reallocating the same memory*/
|
||||
if(old_size == new_size) return data_p; /*Also avoid reallocating the same memory*/
|
||||
|
||||
#if LV_MEM_CUSTOM == 0
|
||||
/* Only truncate the memory is possible
|
||||
* If the 'old_size' was extended by a header size in 'ent_trunc' it avoids reallocating this same memory */
|
||||
* If the 'old_size' was extended by a header size in 'ent_trunc' it avoids reallocating this
|
||||
* same memory */
|
||||
if(new_size < old_size) {
|
||||
lv_mem_ent_t * e = (lv_mem_ent_t *)((uint8_t *) data_p - sizeof(lv_mem_header_t));
|
||||
lv_mem_ent_t * e = (lv_mem_ent_t *)((uint8_t *)data_p - sizeof(lv_mem_header_t));
|
||||
ent_trunc(e, new_size);
|
||||
return &e->first_data;
|
||||
}
|
||||
@ -251,7 +252,6 @@ void * lv_mem_realloc(void * data_p, uint32_t new_size)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(new_p == NULL) LV_LOG_WARN("Couldn't allocate memory");
|
||||
|
||||
return new_p;
|
||||
@ -325,7 +325,7 @@ void lv_mem_monitor(lv_mem_monitor_t * mon_p)
|
||||
|
||||
e = ent_get_next(e);
|
||||
|
||||
while(e != NULL) {
|
||||
while(e != NULL) {
|
||||
if(e->header.s.used == 0) {
|
||||
mon_p->free_cnt++;
|
||||
mon_p->free_size += e->header.s.d_size;
|
||||
@ -339,9 +339,9 @@ void lv_mem_monitor(lv_mem_monitor_t * mon_p)
|
||||
e = ent_get_next(e);
|
||||
}
|
||||
mon_p->total_size = LV_MEM_SIZE;
|
||||
mon_p->used_pct = 100 - (100U * mon_p->free_size) / mon_p->total_size;
|
||||
mon_p->frag_pct = (uint32_t)mon_p->free_biggest_size * 100U / mon_p->free_size;
|
||||
mon_p->frag_pct = 100 - mon_p->frag_pct;
|
||||
mon_p->used_pct = 100 - (100U * mon_p->free_size) / mon_p->total_size;
|
||||
mon_p->frag_pct = (uint32_t)mon_p->free_biggest_size * 100U / mon_p->free_size;
|
||||
mon_p->frag_pct = 100 - mon_p->frag_pct;
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -351,14 +351,14 @@ void lv_mem_monitor(lv_mem_monitor_t * mon_p)
|
||||
* @return the size of data memory in bytes
|
||||
*/
|
||||
|
||||
#if LV_ENABLE_GC==0
|
||||
#if LV_ENABLE_GC == 0
|
||||
|
||||
uint32_t lv_mem_get_size(const void * data)
|
||||
{
|
||||
if(data == NULL) return 0;
|
||||
if(data == &zero_mem) return 0;
|
||||
|
||||
lv_mem_ent_t * e = (lv_mem_ent_t *)((uint8_t *) data - sizeof(lv_mem_header_t));
|
||||
lv_mem_ent_t * e = (lv_mem_ent_t *)((uint8_t *)data - sizeof(lv_mem_header_t));
|
||||
|
||||
return e->header.s.d_size;
|
||||
}
|
||||
@ -387,10 +387,10 @@ static lv_mem_ent_t * ent_get_next(lv_mem_ent_t * act_e)
|
||||
lv_mem_ent_t * next_e = NULL;
|
||||
|
||||
if(act_e == NULL) { /*NULL means: get the first entry*/
|
||||
next_e = (lv_mem_ent_t *) work_mem;
|
||||
next_e = (lv_mem_ent_t *)work_mem;
|
||||
} else { /*Get the next entry */
|
||||
uint8_t * data = &act_e->first_data;
|
||||
next_e = (lv_mem_ent_t *)&data[act_e->header.s.d_size];
|
||||
next_e = (lv_mem_ent_t *)&data[act_e->header.s.d_size];
|
||||
|
||||
if(&next_e->first_data >= &work_mem[LV_MEM_SIZE]) next_e = NULL;
|
||||
}
|
||||
@ -398,7 +398,6 @@ static lv_mem_ent_t * ent_get_next(lv_mem_ent_t * act_e)
|
||||
return next_e;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Try to do the real allocation with a given size
|
||||
* @param e try to allocate to this entry
|
||||
@ -414,7 +413,7 @@ static void * ent_alloc(lv_mem_ent_t * e, uint32_t size)
|
||||
/*Truncate the entry to the desired size */
|
||||
ent_trunc(e, size),
|
||||
|
||||
e->header.s.used = 1;
|
||||
e->header.s.used = 1;
|
||||
|
||||
/*Save the allocated data*/
|
||||
alloc = &e->first_data;
|
||||
@ -451,9 +450,9 @@ static void ent_trunc(lv_mem_ent_t * e, uint32_t size)
|
||||
|
||||
/* Create the new entry after the current if there is space for it */
|
||||
if(e->header.s.d_size != size) {
|
||||
uint8_t * e_data = &e->first_data;
|
||||
lv_mem_ent_t * after_new_e = (lv_mem_ent_t *)&e_data[size];
|
||||
after_new_e->header.s.used = 0;
|
||||
uint8_t * e_data = &e->first_data;
|
||||
lv_mem_ent_t * after_new_e = (lv_mem_ent_t *)&e_data[size];
|
||||
after_new_e->header.s.used = 0;
|
||||
after_new_e->header.s.d_size = e->header.s.d_size - size - sizeof(lv_mem_header_t);
|
||||
}
|
||||
|
||||
|
@ -10,7 +10,6 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
@ -29,14 +28,14 @@ extern "C" {
|
||||
*********************/
|
||||
// Check windows
|
||||
#ifdef __WIN64
|
||||
# define LV_MEM_ENV64
|
||||
#define LV_MEM_ENV64
|
||||
#endif
|
||||
|
||||
// Check GCC
|
||||
#ifdef __GNUC__
|
||||
# if defined(__x86_64__) || defined(__ppc64__)
|
||||
# define LV_MEM_ENV64
|
||||
# endif
|
||||
#if defined(__x86_64__) || defined(__ppc64__)
|
||||
#define LV_MEM_ENV64
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
@ -58,7 +57,6 @@ typedef struct
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
|
||||
/**
|
||||
* Initiaize the dyn_mem module (work memory and other variables)
|
||||
*/
|
||||
@ -105,7 +103,6 @@ void lv_mem_monitor(lv_mem_monitor_t * mon_p);
|
||||
*/
|
||||
uint32_t lv_mem_get_size(const void * data);
|
||||
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
@ -115,13 +112,24 @@ uint32_t lv_mem_get_size(const void * data);
|
||||
* p pointer to a memory
|
||||
*/
|
||||
#if LV_USE_LOG == 0
|
||||
# define lv_mem_assert(p) {if(p == NULL) while(1); }
|
||||
#define lv_mem_assert(p) \
|
||||
{ \
|
||||
if(p == NULL) \
|
||||
while(1) \
|
||||
; \
|
||||
}
|
||||
#else
|
||||
# define lv_mem_assert(p) {if(p == NULL) {LV_LOG_ERROR("Out of memory!"); while(1); }}
|
||||
#define lv_mem_assert(p) \
|
||||
{ \
|
||||
if(p == NULL) { \
|
||||
LV_LOG_ERROR("Out of memory!"); \
|
||||
while(1) \
|
||||
; \
|
||||
} \
|
||||
}
|
||||
#endif
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_MEM_H*/
|
||||
|
||||
|
@ -20,65 +20,66 @@ extern "C" {
|
||||
* - Reserved: 0xE060..0xE07F
|
||||
*/
|
||||
|
||||
#define LV_SYMBOL_GLYPH_FIRST 0xF800
|
||||
#define LV_SYMBOL_AUDIO _LV_SYMBOL_VALUE3(EF,A0,80)
|
||||
#define LV_SYMBOL_VIDEO _LV_SYMBOL_VALUE3(EF,A0,81)
|
||||
#define LV_SYMBOL_LIST _LV_SYMBOL_VALUE3(EF,A0,82)
|
||||
#define LV_SYMBOL_OK _LV_SYMBOL_VALUE3(EF,A0,83)
|
||||
#define LV_SYMBOL_CLOSE _LV_SYMBOL_VALUE3(EF,A0,84)
|
||||
#define LV_SYMBOL_POWER _LV_SYMBOL_VALUE3(EF,A0,85)
|
||||
#define LV_SYMBOL_SETTINGS _LV_SYMBOL_VALUE3(EF,A0,86)
|
||||
#define LV_SYMBOL_TRASH _LV_SYMBOL_VALUE3(EF,A0,87)
|
||||
#define LV_SYMBOL_HOME _LV_SYMBOL_VALUE3(EF,A0,88)
|
||||
#define LV_SYMBOL_DOWNLOAD _LV_SYMBOL_VALUE3(EF,A0,89)
|
||||
#define LV_SYMBOL_DRIVE _LV_SYMBOL_VALUE3(EF,A0,8A)
|
||||
#define LV_SYMBOL_REFRESH _LV_SYMBOL_VALUE3(EF,A0,8B)
|
||||
#define LV_SYMBOL_MUTE _LV_SYMBOL_VALUE3(EF,A0,8C)
|
||||
#define LV_SYMBOL_VOLUME_MID _LV_SYMBOL_VALUE3(EF,A0,8D)
|
||||
#define LV_SYMBOL_VOLUME_MAX _LV_SYMBOL_VALUE3(EF,A0,8E)
|
||||
#define LV_SYMBOL_IMAGE _LV_SYMBOL_VALUE3(EF,A0,8F)
|
||||
#define LV_SYMBOL_EDIT _LV_SYMBOL_VALUE3(EF,A0,90)
|
||||
#define LV_SYMBOL_PREV _LV_SYMBOL_VALUE3(EF,A0,91)
|
||||
#define LV_SYMBOL_PLAY _LV_SYMBOL_VALUE3(EF,A0,92)
|
||||
#define LV_SYMBOL_PAUSE _LV_SYMBOL_VALUE3(EF,A0,93)
|
||||
#define LV_SYMBOL_STOP _LV_SYMBOL_VALUE3(EF,A0,94)
|
||||
#define LV_SYMBOL_NEXT _LV_SYMBOL_VALUE3(EF,A0,95)
|
||||
#define LV_SYMBOL_EJECT _LV_SYMBOL_VALUE3(EF,A0,96)
|
||||
#define LV_SYMBOL_LEFT _LV_SYMBOL_VALUE3(EF,A0,97)
|
||||
#define LV_SYMBOL_RIGHT _LV_SYMBOL_VALUE3(EF,A0,98)
|
||||
#define LV_SYMBOL_PLUS _LV_SYMBOL_VALUE3(EF,A0,99)
|
||||
#define LV_SYMBOL_MINUS _LV_SYMBOL_VALUE3(EF,A0,9A)
|
||||
#define LV_SYMBOL_WARNING _LV_SYMBOL_VALUE3(EF,A0,9B)
|
||||
#define LV_SYMBOL_SHUFFLE _LV_SYMBOL_VALUE3(EF,A0,9C)
|
||||
#define LV_SYMBOL_UP _LV_SYMBOL_VALUE3(EF,A0,9D)
|
||||
#define LV_SYMBOL_DOWN _LV_SYMBOL_VALUE3(EF,A0,9E)
|
||||
#define LV_SYMBOL_LOOP _LV_SYMBOL_VALUE3(EF,A0,9F)
|
||||
#define LV_SYMBOL_DIRECTORY _LV_SYMBOL_VALUE3(EF,A0,A0)
|
||||
#define LV_SYMBOL_UPLOAD _LV_SYMBOL_VALUE3(EF,A0,A1)
|
||||
#define LV_SYMBOL_CALL _LV_SYMBOL_VALUE3(EF,A0,A2)
|
||||
#define LV_SYMBOL_CUT _LV_SYMBOL_VALUE3(EF,A0,A3)
|
||||
#define LV_SYMBOL_COPY _LV_SYMBOL_VALUE3(EF,A0,A4)
|
||||
#define LV_SYMBOL_SAVE _LV_SYMBOL_VALUE3(EF,A0,A5)
|
||||
#define LV_SYMBOL_CHARGE _LV_SYMBOL_VALUE3(EF,A0,A6)
|
||||
#define LV_SYMBOL_BELL _LV_SYMBOL_VALUE3(EF,A0,A7)
|
||||
#define LV_SYMBOL_KEYBOARD _LV_SYMBOL_VALUE3(EF,A0,A8)
|
||||
#define LV_SYMBOL_GPS _LV_SYMBOL_VALUE3(EF,A0,A9)
|
||||
#define LV_SYMBOL_FILE _LV_SYMBOL_VALUE3(EF,A0,AA)
|
||||
#define LV_SYMBOL_WIFI _LV_SYMBOL_VALUE3(EF,A0,AB)
|
||||
#define LV_SYMBOL_BATTERY_FULL _LV_SYMBOL_VALUE3(EF,A0,AC)
|
||||
#define LV_SYMBOL_BATTERY_3 _LV_SYMBOL_VALUE3(EF,A0,AD)
|
||||
#define LV_SYMBOL_BATTERY_2 _LV_SYMBOL_VALUE3(EF,A0,AE)
|
||||
#define LV_SYMBOL_BATTERY_1 _LV_SYMBOL_VALUE3(EF,A0,AF)
|
||||
#define LV_SYMBOL_BATTERY_EMPTY _LV_SYMBOL_VALUE3(EF,A0,B0)
|
||||
#define LV_SYMBOL_BLUETOOTH _LV_SYMBOL_VALUE3(EF,A0,B1)
|
||||
#define LV_SYMBOL_GLYPH_LAST 0xF831
|
||||
#define LV_SYMBOL_DUMMY _LV_SYMBOL_VALUE3(EF,A3,BF) /*Invalid symbol at (U+F831). If written before a string then `lv_img` will show it as a label*/
|
||||
#define LV_SYMBOL_GLYPH_FIRST 0xF800
|
||||
#define LV_SYMBOL_AUDIO _LV_SYMBOL_VALUE3(EF, A0, 80)
|
||||
#define LV_SYMBOL_VIDEO _LV_SYMBOL_VALUE3(EF, A0, 81)
|
||||
#define LV_SYMBOL_LIST _LV_SYMBOL_VALUE3(EF, A0, 82)
|
||||
#define LV_SYMBOL_OK _LV_SYMBOL_VALUE3(EF, A0, 83)
|
||||
#define LV_SYMBOL_CLOSE _LV_SYMBOL_VALUE3(EF, A0, 84)
|
||||
#define LV_SYMBOL_POWER _LV_SYMBOL_VALUE3(EF, A0, 85)
|
||||
#define LV_SYMBOL_SETTINGS _LV_SYMBOL_VALUE3(EF, A0, 86)
|
||||
#define LV_SYMBOL_TRASH _LV_SYMBOL_VALUE3(EF, A0, 87)
|
||||
#define LV_SYMBOL_HOME _LV_SYMBOL_VALUE3(EF, A0, 88)
|
||||
#define LV_SYMBOL_DOWNLOAD _LV_SYMBOL_VALUE3(EF, A0, 89)
|
||||
#define LV_SYMBOL_DRIVE _LV_SYMBOL_VALUE3(EF, A0, 8A)
|
||||
#define LV_SYMBOL_REFRESH _LV_SYMBOL_VALUE3(EF, A0, 8B)
|
||||
#define LV_SYMBOL_MUTE _LV_SYMBOL_VALUE3(EF, A0, 8C)
|
||||
#define LV_SYMBOL_VOLUME_MID _LV_SYMBOL_VALUE3(EF, A0, 8D)
|
||||
#define LV_SYMBOL_VOLUME_MAX _LV_SYMBOL_VALUE3(EF, A0, 8E)
|
||||
#define LV_SYMBOL_IMAGE _LV_SYMBOL_VALUE3(EF, A0, 8F)
|
||||
#define LV_SYMBOL_EDIT _LV_SYMBOL_VALUE3(EF, A0, 90)
|
||||
#define LV_SYMBOL_PREV _LV_SYMBOL_VALUE3(EF, A0, 91)
|
||||
#define LV_SYMBOL_PLAY _LV_SYMBOL_VALUE3(EF, A0, 92)
|
||||
#define LV_SYMBOL_PAUSE _LV_SYMBOL_VALUE3(EF, A0, 93)
|
||||
#define LV_SYMBOL_STOP _LV_SYMBOL_VALUE3(EF, A0, 94)
|
||||
#define LV_SYMBOL_NEXT _LV_SYMBOL_VALUE3(EF, A0, 95)
|
||||
#define LV_SYMBOL_EJECT _LV_SYMBOL_VALUE3(EF, A0, 96)
|
||||
#define LV_SYMBOL_LEFT _LV_SYMBOL_VALUE3(EF, A0, 97)
|
||||
#define LV_SYMBOL_RIGHT _LV_SYMBOL_VALUE3(EF, A0, 98)
|
||||
#define LV_SYMBOL_PLUS _LV_SYMBOL_VALUE3(EF, A0, 99)
|
||||
#define LV_SYMBOL_MINUS _LV_SYMBOL_VALUE3(EF, A0, 9A)
|
||||
#define LV_SYMBOL_WARNING _LV_SYMBOL_VALUE3(EF, A0, 9B)
|
||||
#define LV_SYMBOL_SHUFFLE _LV_SYMBOL_VALUE3(EF, A0, 9C)
|
||||
#define LV_SYMBOL_UP _LV_SYMBOL_VALUE3(EF, A0, 9D)
|
||||
#define LV_SYMBOL_DOWN _LV_SYMBOL_VALUE3(EF, A0, 9E)
|
||||
#define LV_SYMBOL_LOOP _LV_SYMBOL_VALUE3(EF, A0, 9F)
|
||||
#define LV_SYMBOL_DIRECTORY _LV_SYMBOL_VALUE3(EF, A0, A0)
|
||||
#define LV_SYMBOL_UPLOAD _LV_SYMBOL_VALUE3(EF, A0, A1)
|
||||
#define LV_SYMBOL_CALL _LV_SYMBOL_VALUE3(EF, A0, A2)
|
||||
#define LV_SYMBOL_CUT _LV_SYMBOL_VALUE3(EF, A0, A3)
|
||||
#define LV_SYMBOL_COPY _LV_SYMBOL_VALUE3(EF, A0, A4)
|
||||
#define LV_SYMBOL_SAVE _LV_SYMBOL_VALUE3(EF, A0, A5)
|
||||
#define LV_SYMBOL_CHARGE _LV_SYMBOL_VALUE3(EF, A0, A6)
|
||||
#define LV_SYMBOL_BELL _LV_SYMBOL_VALUE3(EF, A0, A7)
|
||||
#define LV_SYMBOL_KEYBOARD _LV_SYMBOL_VALUE3(EF, A0, A8)
|
||||
#define LV_SYMBOL_GPS _LV_SYMBOL_VALUE3(EF, A0, A9)
|
||||
#define LV_SYMBOL_FILE _LV_SYMBOL_VALUE3(EF, A0, AA)
|
||||
#define LV_SYMBOL_WIFI _LV_SYMBOL_VALUE3(EF, A0, AB)
|
||||
#define LV_SYMBOL_BATTERY_FULL _LV_SYMBOL_VALUE3(EF, A0, AC)
|
||||
#define LV_SYMBOL_BATTERY_3 _LV_SYMBOL_VALUE3(EF, A0, AD)
|
||||
#define LV_SYMBOL_BATTERY_2 _LV_SYMBOL_VALUE3(EF, A0, AE)
|
||||
#define LV_SYMBOL_BATTERY_1 _LV_SYMBOL_VALUE3(EF, A0, AF)
|
||||
#define LV_SYMBOL_BATTERY_EMPTY _LV_SYMBOL_VALUE3(EF, A0, B0)
|
||||
#define LV_SYMBOL_BLUETOOTH _LV_SYMBOL_VALUE3(EF, A0, B1)
|
||||
#define LV_SYMBOL_GLYPH_LAST 0xF831
|
||||
#define LV_SYMBOL_DUMMY \
|
||||
_LV_SYMBOL_VALUE3(EF, A3, BF) /*Invalid symbol at (U+F831). If written before a string then \
|
||||
`lv_img` will show it as a label*/
|
||||
|
||||
#define _LV_SYMBOL_VALUE3(x, y, z) (0x ## z ## y ## x)
|
||||
#define _LV_SYMBOL_NUMSTR(sym) LV_ ## sym ## _NUMSTR = sym
|
||||
#define _LV_SYMBOL_VALUE3(x, y, z) (0x##z##y##x)
|
||||
#define _LV_SYMBOL_NUMSTR(sym) LV_##sym##_NUMSTR = sym
|
||||
|
||||
enum
|
||||
{
|
||||
enum {
|
||||
_LV_SYMBOL_NUMSTR(LV_SYMBOL_AUDIO),
|
||||
_LV_SYMBOL_NUMSTR(LV_SYMBOL_VIDEO),
|
||||
_LV_SYMBOL_NUMSTR(LV_SYMBOL_LIST),
|
||||
@ -136,13 +137,13 @@ enum
|
||||
|
||||
#define _LV_SYMBOL_STR_(x) #x
|
||||
#define _LV_SYMBOL_STR(x) _LV_SYMBOL_STR_(x)
|
||||
#define _LV_SYMBOL_CHAR(c) \x ## c
|
||||
#define _LV_SYMBOL_CHAR(c) \x##c
|
||||
#define _LV_SYMBOL_VALUE1(x) _LV_SYMBOL_STR(_LV_SYMBOL_CHAR(x))
|
||||
#define _LV_SYMBOL_VALUE3(x, y, z) _LV_SYMBOL_STR(_LV_SYMBOL_CHAR(x)_LV_SYMBOL_CHAR(y)_LV_SYMBOL_CHAR(z))
|
||||
#define _LV_SYMBOL_VALUE3(x, y, z) \
|
||||
_LV_SYMBOL_STR(_LV_SYMBOL_CHAR(x) _LV_SYMBOL_CHAR(y) _LV_SYMBOL_CHAR(z))
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
|
||||
#endif /*LV_LV_SYMBOL_DEF_H*/
|
||||
|
@ -13,13 +13,13 @@
|
||||
#include "lv_gc.h"
|
||||
|
||||
#if defined(LV_GC_INCLUDE)
|
||||
# include LV_GC_INCLUDE
|
||||
#include LV_GC_INCLUDE
|
||||
#endif /* LV_ENABLE_GC */
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define IDLE_MEAS_PERIOD 500 /*[ms]*/
|
||||
#define IDLE_MEAS_PERIOD 500 /*[ms]*/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
@ -33,7 +33,7 @@ static bool lv_task_exec(lv_task_t * lv_task_p);
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
static bool lv_task_run = false;
|
||||
static bool lv_task_run = false;
|
||||
static uint8_t idle_last = 0;
|
||||
static bool task_deleted;
|
||||
static bool task_created;
|
||||
@ -70,8 +70,8 @@ LV_ATTRIBUTE_TASK_HANDLER void lv_task_handler(void)
|
||||
task_handler_mutex = true;
|
||||
|
||||
static uint32_t idle_period_start = 0;
|
||||
static uint32_t handler_start = 0;
|
||||
static uint32_t busy_time = 0;
|
||||
static uint32_t handler_start = 0;
|
||||
static uint32_t busy_time = 0;
|
||||
|
||||
if(lv_task_run == false) return;
|
||||
|
||||
@ -84,9 +84,9 @@ LV_ATTRIBUTE_TASK_HANDLER void lv_task_handler(void)
|
||||
lv_task_t * next;
|
||||
bool end_flag;
|
||||
do {
|
||||
end_flag = true;
|
||||
task_deleted = false;
|
||||
task_created = false;
|
||||
end_flag = true;
|
||||
task_deleted = false;
|
||||
task_created = false;
|
||||
LV_GC_ROOT(_lv_task_act) = lv_ll_get_head(&LV_GC_ROOT(_lv_task_ll));
|
||||
while(LV_GC_ROOT(_lv_task_act)) {
|
||||
/* The task might be deleted if it runs only once ('once = 1')
|
||||
@ -100,9 +100,10 @@ LV_ATTRIBUTE_TASK_HANDLER void lv_task_handler(void)
|
||||
|
||||
/*Here is the interrupter task. Don't execute it again.*/
|
||||
if(LV_GC_ROOT(_lv_task_act) == task_interrupter) {
|
||||
task_interrupter = NULL; /*From this point only task after the interrupter comes, so the interrupter is not interesting anymore*/
|
||||
task_interrupter = NULL; /*From this point only task after the interrupter comes, so
|
||||
the interrupter is not interesting anymore*/
|
||||
LV_GC_ROOT(_lv_task_act) = next;
|
||||
continue; /*Load the next task*/
|
||||
continue; /*Load the next task*/
|
||||
}
|
||||
|
||||
/*Just try to run the tasks with highest priority.*/
|
||||
@ -113,7 +114,8 @@ LV_ATTRIBUTE_TASK_HANDLER void lv_task_handler(void)
|
||||
else if(task_interrupter) {
|
||||
if(((lv_task_t *)LV_GC_ROOT(_lv_task_act))->prio > task_interrupter->prio) {
|
||||
if(lv_task_exec(LV_GC_ROOT(_lv_task_act))) {
|
||||
task_interrupter = LV_GC_ROOT(_lv_task_act); /*Check all tasks again from the highest priority */
|
||||
task_interrupter = LV_GC_ROOT(
|
||||
_lv_task_act); /*Check all tasks again from the highest priority */
|
||||
end_flag = false;
|
||||
break;
|
||||
}
|
||||
@ -123,16 +125,19 @@ LV_ATTRIBUTE_TASK_HANDLER void lv_task_handler(void)
|
||||
* Just run the remaining tasks*/
|
||||
else {
|
||||
if(lv_task_exec(LV_GC_ROOT(_lv_task_act))) {
|
||||
task_interrupter = LV_GC_ROOT(_lv_task_act); /*Check all tasks again from the highest priority */
|
||||
task_interrupter = LV_GC_ROOT(
|
||||
_lv_task_act); /*Check all tasks again from the highest priority */
|
||||
end_flag = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(task_deleted) break; /*If a task was deleted then this or the next item might be corrupted*/
|
||||
if(task_created) break; /*If a task was deleted then this or the next item might be corrupted*/
|
||||
if(task_deleted)
|
||||
break; /*If a task was deleted then this or the next item might be corrupted*/
|
||||
if(task_created)
|
||||
break; /*If a task was deleted then this or the next item might be corrupted*/
|
||||
|
||||
LV_GC_ROOT(_lv_task_act) = next; /*Load the next task*/
|
||||
LV_GC_ROOT(_lv_task_act) = next; /*Load the next task*/
|
||||
}
|
||||
} while(!end_flag);
|
||||
|
||||
@ -140,15 +145,14 @@ LV_ATTRIBUTE_TASK_HANDLER void lv_task_handler(void)
|
||||
uint32_t idle_period_time = lv_tick_elaps(idle_period_start);
|
||||
if(idle_period_time >= IDLE_MEAS_PERIOD) {
|
||||
|
||||
idle_last = (uint32_t)((uint32_t)busy_time * 100) / IDLE_MEAS_PERIOD; /*Calculate the busy percentage*/
|
||||
idle_last = idle_last > 100 ? 0 : 100 - idle_last; /*But we need idle time*/
|
||||
busy_time = 0;
|
||||
idle_last = (uint32_t)((uint32_t)busy_time * 100) /
|
||||
IDLE_MEAS_PERIOD; /*Calculate the busy percentage*/
|
||||
idle_last = idle_last > 100 ? 0 : 100 - idle_last; /*But we need idle time*/
|
||||
busy_time = 0;
|
||||
idle_period_start = lv_tick_get();
|
||||
|
||||
|
||||
}
|
||||
|
||||
task_handler_mutex = false; /*Release the mutex*/
|
||||
task_handler_mutex = false; /*Release the mutex*/
|
||||
|
||||
LV_LOG_TRACE("lv_task_handler ready");
|
||||
}
|
||||
@ -168,7 +172,7 @@ lv_task_t * lv_task_create(void (*task)(void *), uint32_t period, lv_task_prio_t
|
||||
|
||||
/*Create task lists in order of priority from high to low*/
|
||||
tmp = lv_ll_get_head(&LV_GC_ROOT(_lv_task_ll));
|
||||
if(NULL == tmp) { /*First task*/
|
||||
if(NULL == tmp) { /*First task*/
|
||||
new_lv_task = lv_ll_ins_head(&LV_GC_ROOT(_lv_task_ll));
|
||||
lv_mem_assert(new_lv_task);
|
||||
if(new_lv_task == NULL) return NULL;
|
||||
@ -183,18 +187,18 @@ lv_task_t * lv_task_create(void (*task)(void *), uint32_t period, lv_task_prio_t
|
||||
tmp = lv_ll_get_next(&LV_GC_ROOT(_lv_task_ll), tmp);
|
||||
} while(tmp != NULL);
|
||||
|
||||
if(tmp == NULL) { /*Only too high priority tasks were found*/
|
||||
if(tmp == NULL) { /*Only too high priority tasks were found*/
|
||||
new_lv_task = lv_ll_ins_tail(&LV_GC_ROOT(_lv_task_ll));
|
||||
lv_mem_assert(new_lv_task);
|
||||
if(new_lv_task == NULL) return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
new_lv_task->period = period;
|
||||
new_lv_task->task = task;
|
||||
new_lv_task->prio = prio;
|
||||
new_lv_task->param = param;
|
||||
new_lv_task->once = 0;
|
||||
new_lv_task->period = period;
|
||||
new_lv_task->task = task;
|
||||
new_lv_task->prio = prio;
|
||||
new_lv_task->param = param;
|
||||
new_lv_task->once = 0;
|
||||
new_lv_task->last_run = lv_tick_get();
|
||||
|
||||
task_created = true;
|
||||
@ -212,7 +216,7 @@ void lv_task_del(lv_task_t * lv_task_p)
|
||||
|
||||
lv_mem_free(lv_task_p);
|
||||
|
||||
if(LV_GC_ROOT(_lv_task_act) == lv_task_p) task_deleted = true; /*The active task was deleted*/
|
||||
if(LV_GC_ROOT(_lv_task_act) == lv_task_p) task_deleted = true; /*The active task was deleted*/
|
||||
}
|
||||
|
||||
/**
|
||||
@ -224,7 +228,8 @@ void lv_task_set_prio(lv_task_t * lv_task_p, lv_task_prio_t prio)
|
||||
{
|
||||
/*Find the tasks with new priority*/
|
||||
lv_task_t * i;
|
||||
LV_LL_READ(LV_GC_ROOT(_lv_task_ll), i) {
|
||||
LV_LL_READ(LV_GC_ROOT(_lv_task_ll), i)
|
||||
{
|
||||
if(i->prio <= prio) {
|
||||
if(i != lv_task_p) lv_ll_move_before(&LV_GC_ROOT(_lv_task_ll), lv_task_p, i);
|
||||
break;
|
||||
@ -236,7 +241,6 @@ void lv_task_set_prio(lv_task_t * lv_task_p, lv_task_prio_t prio)
|
||||
lv_ll_move_before(&LV_GC_ROOT(_lv_task_ll), lv_task_p, NULL);
|
||||
}
|
||||
|
||||
|
||||
lv_task_p->prio = prio;
|
||||
}
|
||||
|
||||
@ -296,7 +300,6 @@ uint8_t lv_task_get_idle(void)
|
||||
return idle_last;
|
||||
}
|
||||
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
@ -314,19 +317,18 @@ static bool lv_task_exec(lv_task_t * lv_task_p)
|
||||
uint32_t elp = lv_tick_elaps(lv_task_p->last_run);
|
||||
if(elp >= lv_task_p->period) {
|
||||
lv_task_p->last_run = lv_tick_get();
|
||||
task_deleted = false;
|
||||
task_created = false;
|
||||
task_deleted = false;
|
||||
task_created = false;
|
||||
lv_task_p->task(lv_task_p->param);
|
||||
|
||||
/*Delete if it was a one shot lv_task*/
|
||||
if(task_deleted == false) { /*The task might be deleted by itself as well*/
|
||||
if(lv_task_p->once != 0) {
|
||||
lv_task_del(lv_task_p);
|
||||
}
|
||||
if(task_deleted == false) { /*The task might be deleted by itself as well*/
|
||||
if(lv_task_p->once != 0) {
|
||||
lv_task_del(lv_task_p);
|
||||
}
|
||||
}
|
||||
exec = true;
|
||||
}
|
||||
|
||||
return exec;
|
||||
}
|
||||
|
||||
|
@ -37,8 +37,7 @@ extern "C" {
|
||||
/**
|
||||
* Possible priorities for lv_tasks
|
||||
*/
|
||||
enum
|
||||
{
|
||||
enum {
|
||||
LV_TASK_PRIO_OFF = 0,
|
||||
LV_TASK_PRIO_LOWEST,
|
||||
LV_TASK_PRIO_LOW,
|
||||
@ -56,10 +55,10 @@ typedef struct
|
||||
{
|
||||
uint32_t period;
|
||||
uint32_t last_run;
|
||||
void (*task) (void*);
|
||||
void (*task)(void *);
|
||||
void * param;
|
||||
uint8_t prio:3;
|
||||
uint8_t once:1;
|
||||
uint8_t prio : 3;
|
||||
uint8_t once : 1;
|
||||
} lv_task_t;
|
||||
|
||||
/**********************
|
||||
@ -84,34 +83,34 @@ LV_ATTRIBUTE_TASK_HANDLER void lv_task_handler(void);
|
||||
* @param param free parameter
|
||||
* @return pointer to the new task
|
||||
*/
|
||||
lv_task_t* lv_task_create(void (*task) (void *), uint32_t period, lv_task_prio_t prio, void * param);
|
||||
lv_task_t * lv_task_create(void (*task)(void *), uint32_t period, lv_task_prio_t prio,
|
||||
void * param);
|
||||
|
||||
/**
|
||||
* Delete a lv_task
|
||||
* @param lv_task_p pointer to task created by lv_task_p
|
||||
*/
|
||||
void lv_task_del(lv_task_t* lv_task_p);
|
||||
void lv_task_del(lv_task_t * lv_task_p);
|
||||
|
||||
/**
|
||||
* Set new priority for a lv_task
|
||||
* @param lv_task_p pointer to a lv_task
|
||||
* @param prio the new priority
|
||||
*/
|
||||
void lv_task_set_prio(lv_task_t* lv_task_p, lv_task_prio_t prio);
|
||||
void lv_task_set_prio(lv_task_t * lv_task_p, lv_task_prio_t prio);
|
||||
|
||||
/**
|
||||
* Set new period for a lv_task
|
||||
* @param lv_task_p pointer to a lv_task
|
||||
* @param period the new period
|
||||
*/
|
||||
void lv_task_set_period(lv_task_t* lv_task_p, uint32_t period);
|
||||
void lv_task_set_period(lv_task_t * lv_task_p, uint32_t period);
|
||||
|
||||
/**
|
||||
* Make a lv_task ready. It will not wait its period.
|
||||
* @param lv_task_p pointer to a lv_task.
|
||||
*/
|
||||
void lv_task_ready(lv_task_t* lv_task_p);
|
||||
|
||||
void lv_task_ready(lv_task_t * lv_task_p);
|
||||
|
||||
/**
|
||||
* Delete the lv_task after one call
|
||||
@ -124,7 +123,7 @@ void lv_task_once(lv_task_t * lv_task_p);
|
||||
* It will be called the previously set period milliseconds later.
|
||||
* @param lv_task_p pointer to a lv_task.
|
||||
*/
|
||||
void lv_task_reset(lv_task_t* lv_task_p);
|
||||
void lv_task_reset(lv_task_t * lv_task_p);
|
||||
|
||||
/**
|
||||
* Enable or disable the whole lv_task handling
|
||||
|
@ -30,7 +30,6 @@ extern "C" {
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
@ -12,18 +12,21 @@
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define NO_BREAK_FOUND UINT32_MAX
|
||||
#define NO_BREAK_FOUND UINT32_MAX
|
||||
|
||||
#ifndef LV_TXT_LINE_BREAK_LONG_LEN
|
||||
#define LV_TXT_LINE_BREAK_LONG_LEN 12 /* If a character is at least this long, will break wherever "prettiest" */
|
||||
#define LV_TXT_LINE_BREAK_LONG_LEN \
|
||||
12 /* If a character is at least this long, will break wherever "prettiest" */
|
||||
#endif
|
||||
|
||||
#ifndef LV_TXT_LINE_BREAK_LONG_PRE_MIN_LEN
|
||||
#define LV_TXT_LINE_BREAK_LONG_PRE_MIN_LEN 3 /* Minimum number of characters of a word to put on a line before a break */
|
||||
#define LV_TXT_LINE_BREAK_LONG_PRE_MIN_LEN \
|
||||
3 /* Minimum number of characters of a word to put on a line before a break */
|
||||
#endif
|
||||
|
||||
#ifndef LV_TXT_LINE_BREAK_LONG_POST_MIN_LEN
|
||||
#define LV_TXT_LINE_BREAK_LONG_POST_MIN_LEN 1 /* Minimum number of characters of a word to put on a line after a break */
|
||||
#define LV_TXT_LINE_BREAK_LONG_POST_MIN_LEN \
|
||||
1 /* Minimum number of characters of a word to put on a line after a break */
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
@ -48,18 +51,17 @@ static uint32_t lv_txt_utf8_get_length(const char * txt);
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
|
||||
/**********************
|
||||
* GLOBAL VARIABLES
|
||||
**********************/
|
||||
uint8_t (*lv_txt_encoded_size)(const char *) = lv_txt_utf8_size;
|
||||
uint32_t (*lv_txt_unicode_to_encoded)(uint32_t) = lv_txt_unicode_to_utf8;
|
||||
uint32_t (*lv_txt_encoded_conv_wc)(uint32_t) = lv_txt_utf8_conv_wc;
|
||||
uint32_t (*lv_txt_encoded_next)(const char *, uint32_t *) = lv_txt_utf8_next;
|
||||
uint32_t (*lv_txt_encoded_prev)(const char *, uint32_t *) = lv_txt_utf8_prev;
|
||||
uint8_t (*lv_txt_encoded_size)(const char *) = lv_txt_utf8_size;
|
||||
uint32_t (*lv_txt_unicode_to_encoded)(uint32_t) = lv_txt_unicode_to_utf8;
|
||||
uint32_t (*lv_txt_encoded_conv_wc)(uint32_t) = lv_txt_utf8_conv_wc;
|
||||
uint32_t (*lv_txt_encoded_next)(const char *, uint32_t *) = lv_txt_utf8_next;
|
||||
uint32_t (*lv_txt_encoded_prev)(const char *, uint32_t *) = lv_txt_utf8_prev;
|
||||
uint32_t (*lv_txt_encoded_get_byte_id)(const char *, uint32_t) = lv_txt_utf8_get_byte_id;
|
||||
uint32_t (*lv_encoded_get_char_id)(const char *, uint32_t) = lv_txt_utf8_get_char_id;
|
||||
uint32_t (*lv_txt_get_encoded_length)(const char *) = lv_txt_utf8_get_length;
|
||||
uint32_t (*lv_encoded_get_char_id)(const char *, uint32_t) = lv_txt_utf8_get_char_id;
|
||||
uint32_t (*lv_txt_get_encoded_length)(const char *) = lv_txt_utf8_get_length;
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
@ -77,10 +79,12 @@ uint32_t (*lv_txt_get_encoded_length)(const char *) = lv_txt_utf8_get_l
|
||||
* @param letter_space letter space of the text
|
||||
* @param txt.line_space line space of the text
|
||||
* @param flags settings for the text from 'txt_flag_t' enum
|
||||
* @param max_width max with of the text (break the lines to fit this size) Set CORD_MAX to avoid line breaks
|
||||
* @param max_width max with of the text (break the lines to fit this size) Set CORD_MAX to avoid
|
||||
* line breaks
|
||||
*/
|
||||
void lv_txt_get_size(lv_point_t * size_res, const char * text, const lv_font_t * font,
|
||||
lv_coord_t letter_space, lv_coord_t line_space, lv_coord_t max_width, lv_txt_flag_t flag)
|
||||
lv_coord_t letter_space, lv_coord_t line_space, lv_coord_t max_width,
|
||||
lv_txt_flag_t flag)
|
||||
{
|
||||
size_res->x = 0;
|
||||
size_res->y = 0;
|
||||
@ -90,23 +94,24 @@ void lv_txt_get_size(lv_point_t * size_res, const char * text, const lv_font_t *
|
||||
|
||||
if(flag & LV_TXT_FLAG_EXPAND) max_width = LV_COORD_MAX;
|
||||
|
||||
uint32_t line_start = 0;
|
||||
uint32_t line_start = 0;
|
||||
uint32_t new_line_start = 0;
|
||||
lv_coord_t act_line_length;
|
||||
uint8_t letter_height = lv_font_get_height(font);
|
||||
|
||||
/*Calc. the height and longest line*/
|
||||
while(text[line_start] != '\0') {
|
||||
new_line_start += lv_txt_get_next_line(&text[line_start], font, letter_space, max_width, flag);
|
||||
size_res->y += letter_height ;
|
||||
new_line_start +=
|
||||
lv_txt_get_next_line(&text[line_start], font, letter_space, max_width, flag);
|
||||
size_res->y += letter_height;
|
||||
size_res->y += line_space;
|
||||
|
||||
/*Calculate the the longest line*/
|
||||
act_line_length = lv_txt_get_width(&text[line_start], new_line_start - line_start,
|
||||
font, letter_space, flag);
|
||||
act_line_length = lv_txt_get_width(&text[line_start], new_line_start - line_start, font,
|
||||
letter_space, flag);
|
||||
|
||||
size_res->x = LV_MATH_MAX(act_line_length, size_res->x);
|
||||
line_start = new_line_start;
|
||||
line_start = new_line_start;
|
||||
}
|
||||
|
||||
/*Ma ke the text one line taller if the last character is '\n' or '\r'*/
|
||||
@ -115,9 +120,10 @@ void lv_txt_get_size(lv_point_t * size_res, const char * text, const lv_font_t *
|
||||
}
|
||||
|
||||
/*Correction with the last line space or set the height manually if the text is empty*/
|
||||
if(size_res->y == 0) size_res->y = letter_height;
|
||||
else size_res->y -= line_space;
|
||||
|
||||
if(size_res->y == 0)
|
||||
size_res->y = letter_height;
|
||||
else
|
||||
size_res->y -= line_space;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -125,25 +131,27 @@ void lv_txt_get_size(lv_point_t * size_res, const char * text, const lv_font_t *
|
||||
* @param txt a '\0' terminated string
|
||||
* @param font pointer to a font
|
||||
* @param letter_space letter space
|
||||
* @param max_width max with of the text (break the lines to fit this size) Set CORD_MAX to avoid line breaks
|
||||
* @param max_width max with of the text (break the lines to fit this size) Set CORD_MAX to avoid
|
||||
* line breaks
|
||||
* @param flags settings for the text from 'txt_flag_type' enum
|
||||
* @return the index of the first char of the new line (in byte index not letter index. With UTF-8 they are different)
|
||||
* @return the index of the first char of the new line (in byte index not letter index. With UTF-8
|
||||
* they are different)
|
||||
*/
|
||||
uint16_t lv_txt_get_next_line(const char * txt, const lv_font_t * font,
|
||||
lv_coord_t letter_space, lv_coord_t max_width, lv_txt_flag_t flag)
|
||||
uint16_t lv_txt_get_next_line(const char * txt, const lv_font_t * font, lv_coord_t letter_space,
|
||||
lv_coord_t max_width, lv_txt_flag_t flag)
|
||||
{
|
||||
if(txt == NULL) return 0;
|
||||
if(font == NULL) return 0;
|
||||
|
||||
if(flag & LV_TXT_FLAG_EXPAND) max_width = LV_COORD_MAX;
|
||||
|
||||
uint32_t i = 0;
|
||||
lv_coord_t cur_w = 0;
|
||||
lv_coord_t w_at_last_break = 0;
|
||||
uint32_t i = 0;
|
||||
lv_coord_t cur_w = 0;
|
||||
lv_coord_t w_at_last_break = 0;
|
||||
uint32_t n_char_since_last_break = 0; /* Used count word length of long words */
|
||||
uint32_t last_break = NO_BREAK_FOUND;
|
||||
lv_txt_cmd_state_t cmd_state = LV_TXT_CMD_STATE_WAIT;
|
||||
uint32_t letter = 0;
|
||||
uint32_t last_break = NO_BREAK_FOUND;
|
||||
lv_txt_cmd_state_t cmd_state = LV_TXT_CMD_STATE_WAIT;
|
||||
uint32_t letter = 0;
|
||||
|
||||
while(txt[i] != '\0') {
|
||||
lv_coord_t letter_width;
|
||||
@ -152,36 +160,37 @@ uint16_t lv_txt_get_next_line(const char * txt, const lv_font_t * font,
|
||||
/*Handle the recolor command*/
|
||||
if((flag & LV_TXT_FLAG_RECOLOR) != 0) {
|
||||
if(lv_txt_is_cmd(&cmd_state, letter) != false) {
|
||||
continue; /*Skip the letter is it is part of a command*/
|
||||
continue; /*Skip the letter is it is part of a command*/
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*Check for new line chars*/
|
||||
if(letter == '\n' || letter == '\r') {
|
||||
uint32_t i_tmp = i;
|
||||
uint32_t i_tmp = i;
|
||||
uint32_t letter_next = lv_txt_encoded_next(txt, &i_tmp);
|
||||
if(letter == '\r' && letter_next == '\n') i = i_tmp;
|
||||
if(letter == '\r' && letter_next == '\n') i = i_tmp;
|
||||
|
||||
return i; /*Return with the first letter of the next line*/
|
||||
return i; /*Return with the first letter of the next line*/
|
||||
|
||||
} else { /*Check the actual length*/
|
||||
n_char_since_last_break++;
|
||||
letter_width = lv_font_get_width(font, letter);
|
||||
cur_w += letter_width;
|
||||
cur_w += letter_width;
|
||||
|
||||
/* Get the length of the current work and determine best place
|
||||
/* Get the length of the current work and determine best place
|
||||
* to break the line. */
|
||||
if(cur_w > max_width) {
|
||||
if( last_break != NO_BREAK_FOUND ) {
|
||||
/* Continue searching for next breakable character to see if the next word will fit */
|
||||
if(last_break != NO_BREAK_FOUND) {
|
||||
/* Continue searching for next breakable character to see if the next word will
|
||||
* fit */
|
||||
uint32_t n_char_fit = n_char_since_last_break - 1;
|
||||
if( n_char_since_last_break <= LV_TXT_LINE_BREAK_LONG_PRE_MIN_LEN ) {
|
||||
if(n_char_since_last_break <= LV_TXT_LINE_BREAK_LONG_PRE_MIN_LEN) {
|
||||
i = last_break;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
uint32_t i_tmp = i;
|
||||
cur_w -= w_at_last_break + letter_space; /*ignore the first letter_space after the break char */
|
||||
cur_w -=
|
||||
w_at_last_break +
|
||||
letter_space; /*ignore the first letter_space after the break char */
|
||||
bool other = true;
|
||||
while(txt[i_tmp] != '\0') {
|
||||
letter = lv_txt_encoded_next(txt, &i_tmp);
|
||||
@ -189,7 +198,7 @@ uint16_t lv_txt_get_next_line(const char * txt, const lv_font_t * font,
|
||||
/*Handle the recolor command*/
|
||||
if((flag & LV_TXT_FLAG_RECOLOR) != 0) {
|
||||
if(lv_txt_is_cmd(&cmd_state, letter) != false) {
|
||||
continue; /*Skip the letter is it is part of a command*/
|
||||
continue; /*Skip the letter is it is part of a command*/
|
||||
}
|
||||
}
|
||||
|
||||
@ -199,18 +208,17 @@ uint16_t lv_txt_get_next_line(const char * txt, const lv_font_t * font,
|
||||
/* Figure out the prettiest place to break */
|
||||
uint32_t char_remain;
|
||||
lv_txt_encoded_prev(txt, &i);
|
||||
for(char_remain=n_char_since_last_break - n_char_fit;
|
||||
char_remain < LV_TXT_LINE_BREAK_LONG_POST_MIN_LEN;
|
||||
char_remain++) {
|
||||
for(char_remain = n_char_since_last_break - n_char_fit;
|
||||
char_remain < LV_TXT_LINE_BREAK_LONG_POST_MIN_LEN;
|
||||
char_remain++) {
|
||||
lv_txt_encoded_prev(txt, &i);
|
||||
}
|
||||
}
|
||||
else{
|
||||
} else {
|
||||
i = last_break;
|
||||
}
|
||||
other = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
n_char_since_last_break++;
|
||||
lv_coord_t letter_width2 = lv_font_get_width(font, letter);
|
||||
cur_w += letter_width2;
|
||||
@ -220,29 +228,30 @@ uint16_t lv_txt_get_next_line(const char * txt, const lv_font_t * font,
|
||||
other = false;
|
||||
break;
|
||||
}
|
||||
if(letter_width2 > 0){
|
||||
if(letter_width2 > 0) {
|
||||
cur_w += letter_space;
|
||||
}
|
||||
}
|
||||
if( other ) {
|
||||
if(other) {
|
||||
if(n_char_since_last_break >= LV_TXT_LINE_BREAK_LONG_LEN) {
|
||||
/* Figure out the prettiest place to break */
|
||||
uint32_t char_remain;
|
||||
lv_txt_encoded_prev(txt, &i);
|
||||
for(char_remain=n_char_since_last_break - n_char_fit;
|
||||
char_remain < LV_TXT_LINE_BREAK_LONG_POST_MIN_LEN;
|
||||
char_remain++){
|
||||
for(char_remain = n_char_since_last_break - n_char_fit;
|
||||
char_remain < LV_TXT_LINE_BREAK_LONG_POST_MIN_LEN;
|
||||
char_remain++) {
|
||||
lv_txt_encoded_prev(txt, &i);
|
||||
}
|
||||
}
|
||||
else{
|
||||
} else {
|
||||
i = last_break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Now this character is out of the area so it will be first character of the next line*/
|
||||
/* But 'i' already points to the next character (because of lv_txt_utf8_next) step beck one*/
|
||||
/* Now this character is out of the area so it will be first character of the
|
||||
* next line*/
|
||||
/* But 'i' already points to the next character (because of lv_txt_utf8_next)
|
||||
* step beck one*/
|
||||
lv_txt_encoded_prev(txt, &i);
|
||||
}
|
||||
|
||||
@ -255,7 +264,7 @@ uint16_t lv_txt_get_next_line(const char * txt, const lv_font_t * font,
|
||||
/*If this char still can fit to this line then check if
|
||||
* txt can be broken here later */
|
||||
else if(is_break_char(letter)) {
|
||||
last_break = i; /*Save the first char index after break*/
|
||||
last_break = i; /*Save the first char index after break*/
|
||||
w_at_last_break = cur_w;
|
||||
if(letter_width > 0) {
|
||||
w_at_last_break += letter_space;
|
||||
@ -275,25 +284,26 @@ uint16_t lv_txt_get_next_line(const char * txt, const lv_font_t * font,
|
||||
/**
|
||||
* Give the length of a text with a given font
|
||||
* @param txt a '\0' terminate string
|
||||
* @param length length of 'txt' in byte count and not characters (Á is 1 character but 2 bytes in UTF-8)
|
||||
* @param length length of 'txt' in byte count and not characters (Á is 1 character but 2 bytes in
|
||||
* UTF-8)
|
||||
* @param font pointer to a font
|
||||
* @param letter_space letter space
|
||||
* @param flags settings for the text from 'txt_flag_t' enum
|
||||
* @return length of a char_num long text
|
||||
*/
|
||||
lv_coord_t lv_txt_get_width(const char * txt, uint16_t length,
|
||||
const lv_font_t * font, lv_coord_t letter_space, lv_txt_flag_t flag)
|
||||
lv_coord_t lv_txt_get_width(const char * txt, uint16_t length, const lv_font_t * font,
|
||||
lv_coord_t letter_space, lv_txt_flag_t flag)
|
||||
{
|
||||
if(txt == NULL) return 0;
|
||||
if(font == NULL) return 0;
|
||||
|
||||
uint32_t i = 0;
|
||||
lv_coord_t width = 0;
|
||||
uint32_t i = 0;
|
||||
lv_coord_t width = 0;
|
||||
lv_txt_cmd_state_t cmd_state = LV_TXT_CMD_STATE_WAIT;
|
||||
uint32_t letter;
|
||||
|
||||
if(length != 0) {
|
||||
while(i< length){
|
||||
while(i < length) {
|
||||
letter = lv_txt_encoded_next(txt, &i);
|
||||
if((flag & LV_TXT_FLAG_RECOLOR) != 0) {
|
||||
if(lv_txt_is_cmd(&cmd_state, letter) != false) {
|
||||
@ -302,14 +312,15 @@ lv_coord_t lv_txt_get_width(const char * txt, uint16_t length,
|
||||
}
|
||||
|
||||
lv_coord_t char_width = lv_font_get_width(font, letter);
|
||||
if(char_width > 0){
|
||||
if(char_width > 0) {
|
||||
width += lv_font_get_width(font, letter);
|
||||
width += letter_space;
|
||||
}
|
||||
}
|
||||
|
||||
if(width > 0) {
|
||||
width -= letter_space; /*Trim the last letter space. Important if the text is center aligned */
|
||||
width -= letter_space; /*Trim the last letter space. Important if the text is center
|
||||
aligned */
|
||||
}
|
||||
}
|
||||
|
||||
@ -318,8 +329,8 @@ lv_coord_t lv_txt_get_width(const char * txt, uint16_t length,
|
||||
|
||||
/**
|
||||
* Check next character in a string and decide if the character is part of the command or not
|
||||
* @param state pointer to a txt_cmd_state_t variable which stores the current state of command processing
|
||||
* (Initied. to TXT_CMD_STATE_WAIT )
|
||||
* @param state pointer to a txt_cmd_state_t variable which stores the current state of command
|
||||
* processing (Initied. to TXT_CMD_STATE_WAIT )
|
||||
* @param c the current character
|
||||
* @return true: the character is part of a command and should not be written,
|
||||
* false: the character should be written
|
||||
@ -331,12 +342,13 @@ bool lv_txt_is_cmd(lv_txt_cmd_state_t * state, uint32_t c)
|
||||
if(c == (uint32_t)LV_TXT_COLOR_CMD[0]) {
|
||||
if(*state == LV_TXT_CMD_STATE_WAIT) { /*Start char*/
|
||||
*state = LV_TXT_CMD_STATE_PAR;
|
||||
ret = true;
|
||||
} else if(*state == LV_TXT_CMD_STATE_PAR) { /*Other start char in parameter is escaped cmd. char */
|
||||
ret = true;
|
||||
} else if(*state ==
|
||||
LV_TXT_CMD_STATE_PAR) { /*Other start char in parameter is escaped cmd. char */
|
||||
*state = LV_TXT_CMD_STATE_WAIT;
|
||||
} else if(*state == LV_TXT_CMD_STATE_IN) { /*Command end */
|
||||
*state = LV_TXT_CMD_STATE_WAIT;
|
||||
ret = true;
|
||||
ret = true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -354,8 +366,8 @@ bool lv_txt_is_cmd(lv_txt_cmd_state_t * state, uint32_t c)
|
||||
/**
|
||||
* Insert a string into an other
|
||||
* @param txt_buf the original text (must be big enough for the result text)
|
||||
* @param pos position to insert. Expressed in character index and not byte index (Different in UTF-8)
|
||||
* 0: before the original text, 1: after the first char etc.
|
||||
* @param pos position to insert. Expressed in character index and not byte index (Different in
|
||||
* UTF-8) 0: before the original text, 1: after the first char etc.
|
||||
* @param ins_txt text to insert
|
||||
*/
|
||||
void lv_txt_ins(char * txt_buf, uint32_t pos, const char * ins_txt)
|
||||
@ -363,7 +375,8 @@ void lv_txt_ins(char * txt_buf, uint32_t pos, const char * ins_txt)
|
||||
uint32_t old_len = strlen(txt_buf);
|
||||
uint32_t ins_len = strlen(ins_txt);
|
||||
uint32_t new_len = ins_len + old_len;
|
||||
pos = lv_txt_encoded_get_byte_id(txt_buf, pos); /*Convert to byte index instead of letter index*/
|
||||
pos =
|
||||
lv_txt_encoded_get_byte_id(txt_buf, pos); /*Convert to byte index instead of letter index*/
|
||||
|
||||
/*Copy the second part into the end to make place to text to insert*/
|
||||
uint32_t i;
|
||||
@ -378,7 +391,8 @@ void lv_txt_ins(char * txt_buf, uint32_t pos, const char * ins_txt)
|
||||
/**
|
||||
* Delete a part of a string
|
||||
* @param txt string to modify
|
||||
* @param pos position where to start the deleting (0: before the first char, 1: after the first char etc.)
|
||||
* @param pos position where to start the deleting (0: before the first char, 1: after the first
|
||||
* char etc.)
|
||||
* @param len number of characters to delete
|
||||
*/
|
||||
void lv_txt_cut(char * txt, uint32_t pos, uint32_t len)
|
||||
@ -386,7 +400,7 @@ void lv_txt_cut(char * txt, uint32_t pos, uint32_t len)
|
||||
|
||||
uint32_t old_len = strlen(txt);
|
||||
|
||||
pos = lv_txt_encoded_get_byte_id(txt, pos); /*Convert to byte index instead of letter index*/
|
||||
pos = lv_txt_encoded_get_byte_id(txt, pos); /*Convert to byte index instead of letter index*/
|
||||
len = lv_txt_encoded_get_byte_id(&txt[pos], len);
|
||||
|
||||
/*Copy the second part into the end to make place to text to insert*/
|
||||
@ -396,7 +410,6 @@ void lv_txt_cut(char * txt, uint32_t pos, uint32_t len)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*******************************
|
||||
* UTF-8 ENCODER/DECOER
|
||||
******************************/
|
||||
@ -408,14 +421,17 @@ void lv_txt_cut(char * txt, uint32_t pos, uint32_t len)
|
||||
*/
|
||||
static uint8_t lv_txt_utf8_size(const char * str)
|
||||
{
|
||||
if((str[0] & 0x80) == 0) return 1;
|
||||
else if((str[0] & 0xE0) == 0xC0) return 2;
|
||||
else if((str[0] & 0xF0) == 0xE0) return 3;
|
||||
else if((str[0] & 0xF8) == 0xF0) return 4;
|
||||
return 1; /*If the char was invalid step tell it's 1 byte long*/
|
||||
if((str[0] & 0x80) == 0)
|
||||
return 1;
|
||||
else if((str[0] & 0xE0) == 0xC0)
|
||||
return 2;
|
||||
else if((str[0] & 0xF0) == 0xE0)
|
||||
return 3;
|
||||
else if((str[0] & 0xF8) == 0xF0)
|
||||
return 4;
|
||||
return 1; /*If the char was invalid step tell it's 1 byte long*/
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Convert an Unicode letter to UTF-8.
|
||||
* @param letter_uni an Unicode letter
|
||||
@ -427,20 +443,20 @@ static uint32_t lv_txt_unicode_to_utf8(uint32_t letter_uni)
|
||||
uint8_t bytes[4];
|
||||
|
||||
if(letter_uni < 0x0800) {
|
||||
bytes[0] = ((letter_uni >> 6) & 0x1F) | 0xC0;
|
||||
bytes[1] = ((letter_uni >> 0) & 0x3F) | 0x80;
|
||||
bytes[0] = ((letter_uni >> 6) & 0x1F) | 0xC0;
|
||||
bytes[1] = ((letter_uni >> 0) & 0x3F) | 0x80;
|
||||
bytes[2] = 0;
|
||||
bytes[3] = 0;
|
||||
} else if(letter_uni < 0x010000) {
|
||||
bytes[0] = ((letter_uni >> 12) & 0x0F) | 0xE0;
|
||||
bytes[1] = ((letter_uni >> 6) & 0x3F) | 0x80;
|
||||
bytes[2] = ((letter_uni >> 0) & 0x3F) | 0x80;
|
||||
bytes[1] = ((letter_uni >> 6) & 0x3F) | 0x80;
|
||||
bytes[2] = ((letter_uni >> 0) & 0x3F) | 0x80;
|
||||
bytes[3] = 0;
|
||||
} else if(letter_uni < 0x110000) {
|
||||
bytes[0] = ((letter_uni >> 18) & 0x07) | 0xF0;
|
||||
bytes[1] = ((letter_uni >> 12) & 0x3F) | 0x80;
|
||||
bytes[2] = ((letter_uni >> 6) & 0x3F) | 0x80;
|
||||
bytes[3] = ((letter_uni >> 0) & 0x3F) | 0x80;
|
||||
bytes[2] = ((letter_uni >> 6) & 0x3F) | 0x80;
|
||||
bytes[3] = ((letter_uni >> 0) & 0x3F) | 0x80;
|
||||
}
|
||||
|
||||
uint32_t * res_p = (uint32_t *)bytes;
|
||||
@ -462,7 +478,8 @@ static uint32_t lv_txt_utf8_conv_wc(uint32_t c)
|
||||
swapped = (c8[0] << 24) + (c8[1] << 16) + (c8[2] << 8) + (c8[3]);
|
||||
uint8_t i;
|
||||
for(i = 0; i < 4; i++) {
|
||||
if((swapped & 0xFF) == 0) swapped = (swapped >> 8); /*Ignore leading zeros (they were in the end originally)*/
|
||||
if((swapped & 0xFF) == 0)
|
||||
swapped = (swapped >> 8); /*Ignore leading zeros (they were in the end originally)*/
|
||||
}
|
||||
c = swapped;
|
||||
}
|
||||
@ -504,7 +521,7 @@ static uint32_t lv_txt_utf8_next(const char * txt, uint32_t * i)
|
||||
if((txt[*i] & 0xE0) == 0xC0) {
|
||||
result = (uint32_t)(txt[*i] & 0x1F) << 6;
|
||||
(*i)++;
|
||||
if((txt[*i] & 0xC0) != 0x80) return 0; /*Invalid UTF-8 code*/
|
||||
if((txt[*i] & 0xC0) != 0x80) return 0; /*Invalid UTF-8 code*/
|
||||
result += (txt[*i] & 0x3F);
|
||||
(*i)++;
|
||||
}
|
||||
@ -513,11 +530,11 @@ static uint32_t lv_txt_utf8_next(const char * txt, uint32_t * i)
|
||||
result = (uint32_t)(txt[*i] & 0x0F) << 12;
|
||||
(*i)++;
|
||||
|
||||
if((txt[*i] & 0xC0) != 0x80) return 0; /*Invalid UTF-8 code*/
|
||||
if((txt[*i] & 0xC0) != 0x80) return 0; /*Invalid UTF-8 code*/
|
||||
result += (uint32_t)(txt[*i] & 0x3F) << 6;
|
||||
(*i)++;
|
||||
|
||||
if((txt[*i] & 0xC0) != 0x80) return 0; /*Invalid UTF-8 code*/
|
||||
if((txt[*i] & 0xC0) != 0x80) return 0; /*Invalid UTF-8 code*/
|
||||
result += (txt[*i] & 0x3F);
|
||||
(*i)++;
|
||||
}
|
||||
@ -526,15 +543,15 @@ static uint32_t lv_txt_utf8_next(const char * txt, uint32_t * i)
|
||||
result = (uint32_t)(txt[*i] & 0x07) << 18;
|
||||
(*i)++;
|
||||
|
||||
if((txt[*i] & 0xC0) != 0x80) return 0; /*Invalid UTF-8 code*/
|
||||
if((txt[*i] & 0xC0) != 0x80) return 0; /*Invalid UTF-8 code*/
|
||||
result += (uint32_t)(txt[*i] & 0x3F) << 12;
|
||||
(*i)++;
|
||||
|
||||
if((txt[*i] & 0xC0) != 0x80) return 0; /*Invalid UTF-8 code*/
|
||||
if((txt[*i] & 0xC0) != 0x80) return 0; /*Invalid UTF-8 code*/
|
||||
result += (uint32_t)(txt[*i] & 0x3F) << 6;
|
||||
(*i)++;
|
||||
|
||||
if((txt[*i] & 0xC0) != 0x80) return 0; /*Invalid UTF-8 code*/
|
||||
if((txt[*i] & 0xC0) != 0x80) return 0; /*Invalid UTF-8 code*/
|
||||
result += txt[*i] & 0x3F;
|
||||
(*i)++;
|
||||
} else {
|
||||
@ -547,7 +564,8 @@ static uint32_t lv_txt_utf8_next(const char * txt, uint32_t * i)
|
||||
/**
|
||||
* Get previous UTF-8 character form a string.
|
||||
* @param txt pointer to '\0' terminated string
|
||||
* @param i start byte index in 'txt' where to start. After the call it will point to the previous UTF-8 char in 'txt'.
|
||||
* @param i start byte index in 'txt' where to start. After the call it will point to the previous
|
||||
* UTF-8 char in 'txt'.
|
||||
* @return the decoded Unicode character or 0 on invalid UTF-8 code
|
||||
*/
|
||||
static uint32_t lv_txt_utf8_prev(const char * txt, uint32_t * i)
|
||||
@ -558,21 +576,22 @@ static uint32_t lv_txt_utf8_prev(const char * txt, uint32_t * i)
|
||||
/*Try to find a !0 long UTF-8 char by stepping one character back*/
|
||||
(*i)--;
|
||||
do {
|
||||
if(cnt >= 4) return 0; /*No UTF-8 char found before the initial*/
|
||||
if(cnt >= 4) return 0; /*No UTF-8 char found before the initial*/
|
||||
|
||||
c_size = lv_txt_encoded_size(&txt[*i]);
|
||||
if(c_size == 0) {
|
||||
if(*i != 0)(*i)--;
|
||||
else return 0;
|
||||
if(*i != 0)
|
||||
(*i)--;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
cnt++;
|
||||
} while(c_size == 0);
|
||||
|
||||
uint32_t i_tmp = *i;
|
||||
uint32_t letter = lv_txt_encoded_next(txt, &i_tmp); /*Character found, get it*/
|
||||
uint32_t i_tmp = *i;
|
||||
uint32_t letter = lv_txt_encoded_next(txt, &i_tmp); /*Character found, get it*/
|
||||
|
||||
return letter;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -593,7 +612,6 @@ static uint32_t lv_txt_utf8_get_byte_id(const char * txt, uint32_t utf8_id)
|
||||
return byte_cnt;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Convert a byte index (in an UTF-8 text) to character index.
|
||||
* E.g. in "AÁRT" index of 'R' is 2th char but start at byte 3 because 'Á' is 2 bytes long
|
||||
@ -603,7 +621,7 @@ static uint32_t lv_txt_utf8_get_byte_id(const char * txt, uint32_t utf8_id)
|
||||
*/
|
||||
static uint32_t lv_txt_utf8_get_char_id(const char * txt, uint32_t byte_id)
|
||||
{
|
||||
uint32_t i = 0;
|
||||
uint32_t i = 0;
|
||||
uint32_t char_cnt = 0;
|
||||
|
||||
while(i < byte_id) {
|
||||
@ -623,7 +641,7 @@ static uint32_t lv_txt_utf8_get_char_id(const char * txt, uint32_t byte_id)
|
||||
static uint32_t lv_txt_utf8_get_length(const char * txt)
|
||||
{
|
||||
uint32_t len = 0;
|
||||
uint32_t i = 0;
|
||||
uint32_t i = 0;
|
||||
|
||||
while(txt[i] != '\0') {
|
||||
lv_txt_encoded_next(txt, &i);
|
||||
@ -657,4 +675,3 @@ static bool is_break_char(uint32_t letter)
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -27,26 +27,24 @@ extern "C" {
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define LV_TXT_COLOR_CMD "#"
|
||||
#define LV_TXT_COLOR_CMD "#"
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
enum
|
||||
{
|
||||
LV_TXT_FLAG_NONE = 0x00,
|
||||
LV_TXT_FLAG_RECOLOR = 0x01, /*Enable parsing of recolor command*/
|
||||
LV_TXT_FLAG_EXPAND = 0x02, /*Ignore width to avoid automatic word wrapping*/
|
||||
LV_TXT_FLAG_CENTER = 0x04, /*Align the text to the middle*/
|
||||
LV_TXT_FLAG_RIGHT = 0x08, /*Align the text to the right*/
|
||||
enum {
|
||||
LV_TXT_FLAG_NONE = 0x00,
|
||||
LV_TXT_FLAG_RECOLOR = 0x01, /*Enable parsing of recolor command*/
|
||||
LV_TXT_FLAG_EXPAND = 0x02, /*Ignore width to avoid automatic word wrapping*/
|
||||
LV_TXT_FLAG_CENTER = 0x04, /*Align the text to the middle*/
|
||||
LV_TXT_FLAG_RIGHT = 0x08, /*Align the text to the right*/
|
||||
};
|
||||
typedef uint8_t lv_txt_flag_t;
|
||||
|
||||
enum
|
||||
{
|
||||
LV_TXT_CMD_STATE_WAIT, /*Waiting for command*/
|
||||
LV_TXT_CMD_STATE_PAR, /*Processing the parameter*/
|
||||
LV_TXT_CMD_STATE_IN, /*Processing the command*/
|
||||
enum {
|
||||
LV_TXT_CMD_STATE_WAIT, /*Waiting for command*/
|
||||
LV_TXT_CMD_STATE_PAR, /*Processing the parameter*/
|
||||
LV_TXT_CMD_STATE_IN, /*Processing the command*/
|
||||
};
|
||||
typedef uint8_t lv_txt_cmd_state_t;
|
||||
|
||||
@ -62,39 +60,44 @@ typedef uint8_t lv_txt_cmd_state_t;
|
||||
* @param letter_space letter space of the text
|
||||
* @param line_space line space of the text
|
||||
* @param flags settings for the text from 'txt_flag_t' enum
|
||||
* @param max_width max with of the text (break the lines to fit this size) Set CORD_MAX to avoid line breaks
|
||||
* @param max_width max with of the text (break the lines to fit this size) Set CORD_MAX to avoid
|
||||
* line breaks
|
||||
*/
|
||||
void lv_txt_get_size(lv_point_t * size_res, const char * text, const lv_font_t * font,
|
||||
lv_coord_t letter_space, lv_coord_t line_space, lv_coord_t max_width, lv_txt_flag_t flag);
|
||||
lv_coord_t letter_space, lv_coord_t line_space, lv_coord_t max_width,
|
||||
lv_txt_flag_t flag);
|
||||
|
||||
/**
|
||||
* Get the next line of text. Check line length and break chars too.
|
||||
* @param txt a '\0' terminated string
|
||||
* @param font pointer to a font
|
||||
* @param letter_space letter space
|
||||
* @param max_width max with of the text (break the lines to fit this size) Set CORD_MAX to avoid line breaks
|
||||
* @param max_width max with of the text (break the lines to fit this size) Set CORD_MAX to avoid
|
||||
* line breaks
|
||||
* @param flags settings for the text from 'txt_flag_type' enum
|
||||
* @return the index of the first char of the new line (in byte index not letter index. With UTF-8 they are different)
|
||||
* @return the index of the first char of the new line (in byte index not letter index. With UTF-8
|
||||
* they are different)
|
||||
*/
|
||||
uint16_t lv_txt_get_next_line(const char * txt, const lv_font_t * font,
|
||||
lv_coord_t letter_space, lv_coord_t max_width, lv_txt_flag_t flag);
|
||||
uint16_t lv_txt_get_next_line(const char * txt, const lv_font_t * font, lv_coord_t letter_space,
|
||||
lv_coord_t max_width, lv_txt_flag_t flag);
|
||||
|
||||
/**
|
||||
* Give the length of a text with a given font
|
||||
* @param txt a '\0' terminate string
|
||||
* @param length length of 'txt' in byte count and not characters (Á is 1 character but 2 bytes in UTF-8)
|
||||
* @param length length of 'txt' in byte count and not characters (Á is 1 character but 2 bytes in
|
||||
* UTF-8)
|
||||
* @param font pointer to a font
|
||||
* @param letter_space letter space
|
||||
* @param flags settings for the text from 'txt_flag_t' enum
|
||||
* @return length of a char_num long text
|
||||
*/
|
||||
lv_coord_t lv_txt_get_width(const char * txt, uint16_t length,
|
||||
const lv_font_t * font, lv_coord_t letter_space, lv_txt_flag_t flag);
|
||||
|
||||
lv_coord_t lv_txt_get_width(const char * txt, uint16_t length, const lv_font_t * font,
|
||||
lv_coord_t letter_space, lv_txt_flag_t flag);
|
||||
|
||||
/**
|
||||
* Check next character in a string and decide if te character is part of the command or not
|
||||
* @param state pointer to a txt_cmd_state_t variable which stores the current state of command processing
|
||||
* @param state pointer to a txt_cmd_state_t variable which stores the current state of command
|
||||
* processing
|
||||
* @param c the current character
|
||||
* @return true: the character is part of a command and should not be written,
|
||||
* false: the character should be written
|
||||
@ -112,7 +115,8 @@ void lv_txt_ins(char * txt_buf, uint32_t pos, const char * ins_txt);
|
||||
/**
|
||||
* Delete a part of a string
|
||||
* @param txt string to modify
|
||||
* @param pos position where to start the deleting (0: before the first char, 1: after the first char etc.)
|
||||
* @param pos position where to start the deleting (0: before the first char, 1: after the first
|
||||
* char etc.)
|
||||
* @param len number of characters to delete
|
||||
*/
|
||||
void lv_txt_cut(char * txt, uint32_t pos, uint32_t len);
|
||||
@ -128,20 +132,19 @@ void lv_txt_cut(char * txt, uint32_t pos, uint32_t len);
|
||||
*/
|
||||
extern uint8_t (*lv_txt_encoded_size)(const char *);
|
||||
|
||||
|
||||
/**
|
||||
* Convert an Unicode letter to encoded
|
||||
* @param letter_uni an Unicode letter
|
||||
* @return Encoded character in Little Endian to be compatible with C chars (e.g. 'Á', 'Ü')
|
||||
*/
|
||||
extern uint32_t (*lv_txt_unicode_to_encoded)(uint32_t );
|
||||
extern uint32_t (*lv_txt_unicode_to_encoded)(uint32_t);
|
||||
|
||||
/**
|
||||
* Convert a wide character, e.g. 'Á' little endian to be compatible with the encoded format.
|
||||
* @param c a wide character
|
||||
* @return `c` in the encoded format
|
||||
*/
|
||||
extern uint32_t (*lv_txt_encoded_conv_wc) (uint32_t c);
|
||||
extern uint32_t (*lv_txt_encoded_conv_wc)(uint32_t c);
|
||||
|
||||
/**
|
||||
* Decode the next encoded character from a string.
|
||||
@ -151,12 +154,13 @@ extern uint32_t (*lv_txt_encoded_conv_wc) (uint32_t c);
|
||||
* NULL to use txt[0] as index
|
||||
* @return the decoded Unicode character or 0 on invalid data code
|
||||
*/
|
||||
extern uint32_t (*lv_txt_encoded_next)(const char *, uint32_t * );
|
||||
extern uint32_t (*lv_txt_encoded_next)(const char *, uint32_t *);
|
||||
|
||||
/**
|
||||
* Get the previous encoded character form a string.
|
||||
* @param txt pointer to '\0' terminated string
|
||||
* @param i_start index in 'txt' where to start. After the call it will point to the previous encoded char in 'txt'.
|
||||
* @param i_start index in 'txt' where to start. After the call it will point to the previous
|
||||
* encoded char in 'txt'.
|
||||
* @return the decoded Unicode character or 0 on invalid data
|
||||
*/
|
||||
extern uint32_t (*lv_txt_encoded_prev)(const char *, uint32_t *);
|
||||
|
@ -43,28 +43,28 @@
|
||||
*/
|
||||
char * lv_utils_num_to_str(int32_t num, char * buf)
|
||||
{
|
||||
if (num == 0) {
|
||||
if(num == 0) {
|
||||
buf[0] = '0';
|
||||
buf[1] = '\0';
|
||||
return buf;
|
||||
}
|
||||
int8_t digitCount = 0;
|
||||
int8_t i = 0;
|
||||
if (num < 0) {
|
||||
int8_t i = 0;
|
||||
if(num < 0) {
|
||||
buf[digitCount++] = '-';
|
||||
num = LV_MATH_ABS(num);
|
||||
num = LV_MATH_ABS(num);
|
||||
++i;
|
||||
}
|
||||
while (num) {
|
||||
char digit = num % 10;
|
||||
while(num) {
|
||||
char digit = num % 10;
|
||||
buf[digitCount++] = digit + 48;
|
||||
num /= 10;
|
||||
}
|
||||
buf[digitCount] = '\0';
|
||||
digitCount--;
|
||||
while (digitCount > i) {
|
||||
char temp = buf[i];
|
||||
buf[i] = buf[digitCount];
|
||||
while(digitCount > i) {
|
||||
char temp = buf[i];
|
||||
buf[i] = buf[digitCount];
|
||||
buf[digitCount] = temp;
|
||||
digitCount--;
|
||||
i++;
|
||||
@ -72,7 +72,6 @@ char * lv_utils_num_to_str(int32_t num, char * buf)
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
/** Searches base[0] to base[n - 1] for an item that matches *key.
|
||||
*
|
||||
* @note The function cmp must return negative if its first
|
||||
@ -85,25 +84,27 @@ char * lv_utils_num_to_str(int32_t num, char * buf)
|
||||
* @param base Pointer to first element to search
|
||||
* @param n Number of elements
|
||||
* @param size Size of each element
|
||||
* @param cmp Pointer to comparison function (see #lv_font_codeCompare as a comparison function example)
|
||||
* @param cmp Pointer to comparison function (see #lv_font_codeCompare as a comparison function
|
||||
* example)
|
||||
*
|
||||
* @return a pointer to a matching item, or NULL if none exists.
|
||||
*/
|
||||
void * lv_utils_bsearch(const void * key, const void * base, uint32_t n, uint32_t size, int32_t (* cmp)(const void * pRef, const void * pElement))
|
||||
void * lv_utils_bsearch(const void * key, const void * base, uint32_t n, uint32_t size,
|
||||
int32_t (*cmp)(const void * pRef, const void * pElement))
|
||||
{
|
||||
const char * middle;
|
||||
int32_t c;
|
||||
|
||||
for (middle = base; n != 0;) {
|
||||
middle += (n/2) * size;
|
||||
if ((c = (*cmp)(key, middle)) > 0) {
|
||||
n = (n/2) - ((n&1) == 0);
|
||||
for(middle = base; n != 0;) {
|
||||
middle += (n / 2) * size;
|
||||
if((c = (*cmp)(key, middle)) > 0) {
|
||||
n = (n / 2) - ((n & 1) == 0);
|
||||
base = (middle += size);
|
||||
} else if (c < 0) {
|
||||
} else if(c < 0) {
|
||||
n /= 2;
|
||||
middle = base;
|
||||
} else {
|
||||
return (char *) middle;
|
||||
return (char *)middle;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
@ -112,5 +113,3 @@ void * lv_utils_bsearch(const void * key, const void * base, uint32_t n, uint32_
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
|
||||
|
@ -10,7 +10,6 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
@ -48,11 +47,13 @@ char * lv_utils_num_to_str(int32_t num, char * buf);
|
||||
* @param base Pointer to first element to search
|
||||
* @param n Number of elements
|
||||
* @param size Size of each element
|
||||
* @param cmp Pointer to comparison function (see #lv_font_codeCompare as a comparison function example)
|
||||
* @param cmp Pointer to comparison function (see #lv_font_codeCompare as a comparison function
|
||||
* example)
|
||||
*
|
||||
* @return a pointer to a matching item, or NULL if none exists.
|
||||
*/
|
||||
void * lv_utils_bsearch(const void * key, const void * base, uint32_t n, uint32_t size, int32_t (* cmp)(const void * pRef, const void * pElement));
|
||||
void * lv_utils_bsearch(const void * key, const void * base, uint32_t n, uint32_t size,
|
||||
int32_t (*cmp)(const void * pRef, const void * pElement));
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
|
@ -3,7 +3,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
@ -14,7 +13,6 @@
|
||||
#include "../lv_draw/lv_draw_arc.h"
|
||||
#include "../lv_themes/lv_theme.h"
|
||||
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
@ -69,7 +67,7 @@ lv_obj_t * lv_arc_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
|
||||
/*Initialize the allocated 'ext' */
|
||||
ext->angle_start = 45;
|
||||
ext->angle_end = 315;
|
||||
ext->angle_end = 315;
|
||||
|
||||
/*The signal and design functions are not copied so set them here*/
|
||||
lv_obj_set_signal_cb(new_arc, lv_arc_signal);
|
||||
@ -89,8 +87,8 @@ lv_obj_t * lv_arc_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
/*Copy an existing arc*/
|
||||
else {
|
||||
lv_arc_ext_t * copy_ext = lv_obj_get_ext_attr(copy);
|
||||
ext->angle_start = copy_ext->angle_start;
|
||||
ext->angle_end = copy_ext->angle_end;
|
||||
ext->angle_start = copy_ext->angle_start;
|
||||
ext->angle_end = copy_ext->angle_end;
|
||||
|
||||
/*Refresh the style with new signal function*/
|
||||
lv_obj_refresh_style(new_arc);
|
||||
@ -109,7 +107,6 @@ lv_obj_t * lv_arc_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
* New object specific "add" or "remove" functions come here
|
||||
*/
|
||||
|
||||
|
||||
/*=====================
|
||||
* Setter functions
|
||||
*====================*/
|
||||
@ -128,7 +125,7 @@ void lv_arc_set_angles(lv_obj_t * arc, uint16_t start, uint16_t end)
|
||||
if(end > 360) end = 360;
|
||||
|
||||
ext->angle_start = start;
|
||||
ext->angle_end = end;
|
||||
ext->angle_end = end;
|
||||
|
||||
lv_obj_invalidate(arc);
|
||||
}
|
||||
@ -142,9 +139,7 @@ void lv_arc_set_angles(lv_obj_t * arc, uint16_t start, uint16_t end)
|
||||
void lv_arc_set_style(lv_obj_t * arc, lv_arc_style_t type, lv_style_t * style)
|
||||
{
|
||||
switch(type) {
|
||||
case LV_ARC_STYLE_MAIN:
|
||||
lv_obj_set_style(arc, style);
|
||||
break;
|
||||
case LV_ARC_STYLE_MAIN: lv_obj_set_style(arc, style); break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -187,12 +182,8 @@ lv_style_t * lv_arc_get_style(const lv_obj_t * arc, lv_arc_style_t type)
|
||||
lv_style_t * style = NULL;
|
||||
|
||||
switch(type) {
|
||||
case LV_ARC_STYLE_MAIN:
|
||||
style = lv_obj_get_style(arc);
|
||||
break;
|
||||
default:
|
||||
style = NULL;
|
||||
break;
|
||||
case LV_ARC_STYLE_MAIN: style = lv_obj_get_style(arc); break;
|
||||
default: style = NULL; break;
|
||||
}
|
||||
|
||||
return style;
|
||||
@ -231,24 +222,25 @@ static bool lv_arc_design(lv_obj_t * arc, const lv_area_t * mask, lv_design_mode
|
||||
lv_arc_ext_t * ext = lv_obj_get_ext_attr(arc);
|
||||
lv_style_t * style = lv_arc_get_style(arc, LV_ARC_STYLE_MAIN);
|
||||
|
||||
lv_coord_t r = (LV_MATH_MIN(lv_obj_get_width(arc), lv_obj_get_height(arc))) / 2;
|
||||
lv_coord_t x = arc->coords.x1 + lv_obj_get_width(arc) / 2;
|
||||
lv_coord_t y = arc->coords.y1 + lv_obj_get_height(arc) / 2;
|
||||
lv_coord_t r = (LV_MATH_MIN(lv_obj_get_width(arc), lv_obj_get_height(arc))) / 2;
|
||||
lv_coord_t x = arc->coords.x1 + lv_obj_get_width(arc) / 2;
|
||||
lv_coord_t y = arc->coords.y1 + lv_obj_get_height(arc) / 2;
|
||||
lv_opa_t opa_scale = lv_obj_get_opa_scale(arc);
|
||||
lv_draw_arc(x, y, r, mask, ext->angle_start, ext->angle_end, style, opa_scale);
|
||||
|
||||
|
||||
/*Draw circle on the ends if enabled */
|
||||
if(style->line.rounded) {
|
||||
lv_coord_t thick_half = style->line.width / 2;
|
||||
lv_coord_t cir_x = ((r - thick_half) * lv_trigo_sin(ext->angle_start) >> LV_TRIGO_SHIFT);
|
||||
lv_coord_t cir_y = ((r - thick_half) * lv_trigo_sin(ext->angle_start + 90) >> LV_TRIGO_SHIFT);
|
||||
lv_coord_t cir_x =
|
||||
((r - thick_half) * lv_trigo_sin(ext->angle_start) >> LV_TRIGO_SHIFT);
|
||||
lv_coord_t cir_y =
|
||||
((r - thick_half) * lv_trigo_sin(ext->angle_start + 90) >> LV_TRIGO_SHIFT);
|
||||
|
||||
lv_style_t cir_style;
|
||||
lv_style_copy(&cir_style, &lv_style_plain);
|
||||
cir_style.body.grad_color = style->line.color;
|
||||
cir_style.body.main_color = cir_style.body.grad_color;
|
||||
cir_style.body.radius = LV_RADIUS_CIRCLE;
|
||||
cir_style.body.radius = LV_RADIUS_CIRCLE;
|
||||
lv_area_t cir_area;
|
||||
cir_area.x1 = cir_x + x - thick_half;
|
||||
cir_area.y1 = cir_y + y - thick_half;
|
||||
@ -271,7 +263,6 @@ static bool lv_arc_design(lv_obj_t * arc, const lv_area_t * mask, lv_design_mode
|
||||
}
|
||||
/*Post draw when the children are drawn*/
|
||||
else if(mode == LV_DESIGN_DRAW_POST) {
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -292,13 +283,12 @@ static lv_res_t lv_arc_signal(lv_obj_t * arc, lv_signal_t sign, void * param)
|
||||
res = ancestor_signal(arc, sign, param);
|
||||
if(res != LV_RES_OK) return res;
|
||||
|
||||
|
||||
if(sign == LV_SIGNAL_CLEANUP) {
|
||||
/*Nothing to cleanup. (No dynamically allocated memory in 'ext')*/
|
||||
} else if(sign == LV_SIGNAL_GET_TYPE) {
|
||||
lv_obj_type_t * buf = param;
|
||||
uint8_t i;
|
||||
for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/
|
||||
for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/
|
||||
if(buf->type[i] == NULL) break;
|
||||
}
|
||||
buf->type[i] = "lv_arc";
|
||||
|
@ -3,7 +3,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef LV_ARC_H
|
||||
#define LV_ARC_H
|
||||
|
||||
@ -32,21 +31,19 @@ extern "C" {
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
/*Data of arc*/
|
||||
typedef struct {
|
||||
typedef struct
|
||||
{
|
||||
/*New data for this type */
|
||||
lv_coord_t angle_start;
|
||||
lv_coord_t angle_end;
|
||||
} lv_arc_ext_t;
|
||||
|
||||
|
||||
/*Styles*/
|
||||
enum {
|
||||
LV_ARC_STYLE_MAIN,
|
||||
};
|
||||
typedef uint8_t lv_arc_style_t;
|
||||
|
||||
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
@ -63,7 +60,6 @@ lv_obj_t * lv_arc_create(lv_obj_t * par, const lv_obj_t * copy);
|
||||
* Add/remove functions
|
||||
*=====================*/
|
||||
|
||||
|
||||
/*=====================
|
||||
* Setter functions
|
||||
*====================*/
|
||||
@ -82,7 +78,7 @@ void lv_arc_set_angles(lv_obj_t * arc, uint16_t start, uint16_t end);
|
||||
* @param type which style should be set
|
||||
* @param style pointer to a style
|
||||
* */
|
||||
void lv_arc_set_style(lv_obj_t * arc, lv_arc_style_t type, lv_style_t *style);
|
||||
void lv_arc_set_style(lv_obj_t * arc, lv_arc_style_t type, lv_style_t * style);
|
||||
|
||||
/*=====================
|
||||
* Getter functions
|
||||
@ -118,10 +114,10 @@ lv_style_t * lv_arc_get_style(const lv_obj_t * arc, lv_arc_style_t type);
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_ARC*/
|
||||
#endif /*LV_USE_ARC*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_ARC_H*/
|
||||
#endif /*LV_ARC_H*/
|
||||
|
@ -70,14 +70,14 @@ lv_obj_t * lv_bar_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
lv_mem_assert(ext);
|
||||
if(ext == NULL) return NULL;
|
||||
|
||||
ext->min_value = 0;
|
||||
ext->max_value = 100;
|
||||
ext->cur_value = 0;
|
||||
ext->anim_time = 200;
|
||||
ext->anim_start = 0;
|
||||
ext->anim_end = 0;
|
||||
ext->anim_state = LV_BAR_ANIM_STATE_INV;
|
||||
ext->sym = 0;
|
||||
ext->min_value = 0;
|
||||
ext->max_value = 100;
|
||||
ext->cur_value = 0;
|
||||
ext->anim_time = 200;
|
||||
ext->anim_start = 0;
|
||||
ext->anim_end = 0;
|
||||
ext->anim_state = LV_BAR_ANIM_STATE_INV;
|
||||
ext->sym = 0;
|
||||
ext->style_indic = &lv_style_pretty_color;
|
||||
|
||||
lv_obj_set_signal_cb(new_bar, lv_bar_signal);
|
||||
@ -98,11 +98,11 @@ lv_obj_t * lv_bar_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
}
|
||||
} else {
|
||||
lv_bar_ext_t * ext_copy = lv_obj_get_ext_attr(copy);
|
||||
ext->min_value = ext_copy->min_value;
|
||||
ext->max_value = ext_copy->max_value;
|
||||
ext->cur_value = ext_copy->cur_value;
|
||||
ext->style_indic = ext_copy->style_indic;
|
||||
ext->sym = ext_copy->sym;
|
||||
ext->min_value = ext_copy->min_value;
|
||||
ext->max_value = ext_copy->max_value;
|
||||
ext->cur_value = ext_copy->cur_value;
|
||||
ext->style_indic = ext_copy->style_indic;
|
||||
ext->sym = ext_copy->sym;
|
||||
/*Refresh the style with new signal function*/
|
||||
lv_obj_refresh_style(new_bar);
|
||||
|
||||
@ -146,34 +146,33 @@ void lv_bar_set_value(lv_obj_t * bar, int16_t value, bool anim)
|
||||
/*No animation in progress -> simply set the values*/
|
||||
if(ext->anim_state == LV_BAR_ANIM_STATE_INV) {
|
||||
ext->anim_start = ext->cur_value;
|
||||
ext->anim_end = new_value;
|
||||
ext->anim_end = new_value;
|
||||
}
|
||||
/*Animation in progress. Start from the animation end value*/
|
||||
else {
|
||||
ext->anim_start = ext->anim_end;
|
||||
ext->anim_end = new_value;
|
||||
ext->anim_end = new_value;
|
||||
}
|
||||
|
||||
lv_anim_t a;
|
||||
a.var = bar;
|
||||
a.start = LV_BAR_ANIM_STATE_START;
|
||||
a.end = LV_BAR_ANIM_STATE_END;
|
||||
a.fp = (lv_anim_fp_t)lv_bar_animate;
|
||||
a.path = lv_anim_path_linear;
|
||||
a.end_cb = lv_bar_anim_ready;
|
||||
a.act_time = 0;
|
||||
a.time = ext->anim_time;
|
||||
a.playback = 0;
|
||||
a.var = bar;
|
||||
a.start = LV_BAR_ANIM_STATE_START;
|
||||
a.end = LV_BAR_ANIM_STATE_END;
|
||||
a.fp = (lv_anim_fp_t)lv_bar_animate;
|
||||
a.path = lv_anim_path_linear;
|
||||
a.end_cb = lv_bar_anim_ready;
|
||||
a.act_time = 0;
|
||||
a.time = ext->anim_time;
|
||||
a.playback = 0;
|
||||
a.playback_pause = 0;
|
||||
a.repeat = 0;
|
||||
a.repeat_pause = 0;
|
||||
a.repeat = 0;
|
||||
a.repeat_pause = 0;
|
||||
|
||||
lv_anim_create(&a);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set minimum and the maximum values of a bar
|
||||
* @param bar pointer to the bar object
|
||||
@ -199,14 +198,15 @@ void lv_bar_set_range(lv_obj_t * bar, int16_t min, int16_t max)
|
||||
}
|
||||
|
||||
/**
|
||||
* Make the bar symmetric to zero. The indicator will grow from zero instead of the minimum position.
|
||||
* Make the bar symmetric to zero. The indicator will grow from zero instead of the minimum
|
||||
* position.
|
||||
* @param bar pointer to a bar object
|
||||
* @param en true: enable disable symmetric behavior; false: disable
|
||||
*/
|
||||
void lv_bar_set_sym(lv_obj_t * bar, bool en)
|
||||
{
|
||||
lv_bar_ext_t * ext = lv_obj_get_ext_attr(bar);
|
||||
ext->sym = en ? 1 : 0;
|
||||
ext->sym = en ? 1 : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -220,9 +220,7 @@ void lv_bar_set_style(lv_obj_t * bar, lv_bar_style_t type, lv_style_t * style)
|
||||
lv_bar_ext_t * ext = lv_obj_get_ext_attr(bar);
|
||||
|
||||
switch(type) {
|
||||
case LV_BAR_STYLE_BG:
|
||||
lv_obj_set_style(bar, style);
|
||||
break;
|
||||
case LV_BAR_STYLE_BG: lv_obj_set_style(bar, style); break;
|
||||
case LV_BAR_STYLE_INDIC:
|
||||
ext->style_indic = style;
|
||||
lv_obj_refresh_ext_size(bar);
|
||||
@ -245,7 +243,8 @@ int16_t lv_bar_get_value(const lv_obj_t * bar)
|
||||
/*If animated tell that it's already at the end value*/
|
||||
if(ext->anim_state != LV_BAR_ANIM_STATE_INV) return ext->anim_end;
|
||||
/*No animation, simple return the current value*/
|
||||
else return ext->cur_value;
|
||||
else
|
||||
return ext->cur_value;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -293,15 +292,9 @@ lv_style_t * lv_bar_get_style(const lv_obj_t * bar, lv_bar_style_t type)
|
||||
lv_bar_ext_t * ext = lv_obj_get_ext_attr(bar);
|
||||
|
||||
switch(type) {
|
||||
case LV_BAR_STYLE_BG:
|
||||
style = lv_obj_get_style(bar);
|
||||
break;
|
||||
case LV_BAR_STYLE_INDIC:
|
||||
style = ext->style_indic;
|
||||
break;
|
||||
default:
|
||||
style = NULL;
|
||||
break;
|
||||
case LV_BAR_STYLE_BG: style = lv_obj_get_style(bar); break;
|
||||
case LV_BAR_STYLE_INDIC: style = ext->style_indic; break;
|
||||
default: style = NULL; break;
|
||||
}
|
||||
|
||||
return style;
|
||||
@ -325,7 +318,7 @@ static bool lv_bar_design(lv_obj_t * bar, const lv_area_t * mask, lv_design_mode
|
||||
{
|
||||
if(mode == LV_DESIGN_COVER_CHK) {
|
||||
/*Return false if the object is not covers the mask area*/
|
||||
return ancestor_design_f(bar, mask, mode);
|
||||
return ancestor_design_f(bar, mask, mode);
|
||||
} else if(mode == LV_DESIGN_DRAW_MAIN) {
|
||||
lv_opa_t opa_scale = lv_obj_get_opa_scale(bar);
|
||||
|
||||
@ -333,7 +326,8 @@ static bool lv_bar_design(lv_obj_t * bar, const lv_area_t * mask, lv_design_mode
|
||||
ancestor_design_f(bar, mask, mode);
|
||||
#else
|
||||
/* Draw the borders later if the bar is focused.
|
||||
* At value = 100% the indicator can cover to whole background and the focused style won't be visible*/
|
||||
* At value = 100% the indicator can cover to whole background and the focused style won't
|
||||
* be visible*/
|
||||
if(lv_obj_is_focused(bar)) {
|
||||
lv_style_t * style_bg = lv_bar_get_style(bar, LV_BAR_STYLE_BG);
|
||||
lv_style_t style_tmp;
|
||||
@ -346,7 +340,8 @@ static bool lv_bar_design(lv_obj_t * bar, const lv_area_t * mask, lv_design_mode
|
||||
#endif
|
||||
lv_bar_ext_t * ext = lv_obj_get_ext_attr(bar);
|
||||
|
||||
if(ext->cur_value != ext->min_value || ext->sym || ext->anim_start != LV_BAR_ANIM_STATE_INV) {
|
||||
if(ext->cur_value != ext->min_value || ext->sym ||
|
||||
ext->anim_start != LV_BAR_ANIM_STATE_INV) {
|
||||
lv_style_t * style_indic = lv_bar_get_style(bar, LV_BAR_STYLE_INDIC);
|
||||
lv_area_t indic_area;
|
||||
lv_area_copy(&indic_area, &bar->coords);
|
||||
@ -362,21 +357,31 @@ static bool lv_bar_design(lv_obj_t * bar, const lv_area_t * mask, lv_design_mode
|
||||
/*Horizontal*/
|
||||
if(ext->anim_state != LV_BAR_ANIM_STATE_INV) {
|
||||
/*Calculate the coordinates of anim. start and end*/
|
||||
lv_coord_t anim_start_x = (int32_t)((int32_t)w * (ext->anim_start - ext->min_value)) / (ext->max_value - ext->min_value);
|
||||
lv_coord_t anim_end_x = (int32_t)((int32_t)w * (ext->anim_end - ext->min_value)) / (ext->max_value - ext->min_value);
|
||||
lv_coord_t anim_start_x =
|
||||
(int32_t)((int32_t)w * (ext->anim_start - ext->min_value)) /
|
||||
(ext->max_value - ext->min_value);
|
||||
lv_coord_t anim_end_x =
|
||||
(int32_t)((int32_t)w * (ext->anim_end - ext->min_value)) /
|
||||
(ext->max_value - ext->min_value);
|
||||
|
||||
/*Calculate the real position based on `anim_state` (between `anim_start` and `anim_end`)*/
|
||||
indic_area.x2 = anim_start_x + (((anim_end_x - anim_start_x) * ext->anim_state) >> LV_BAR_ANIM_STATE_NORM);
|
||||
/*Calculate the real position based on `anim_state` (between `anim_start` and
|
||||
* `anim_end`)*/
|
||||
indic_area.x2 =
|
||||
anim_start_x +
|
||||
(((anim_end_x - anim_start_x) * ext->anim_state) >> LV_BAR_ANIM_STATE_NORM);
|
||||
} else {
|
||||
indic_area.x2 = (int32_t)((int32_t)w * (ext->cur_value - ext->min_value)) / (ext->max_value - ext->min_value);
|
||||
indic_area.x2 = (int32_t)((int32_t)w * (ext->cur_value - ext->min_value)) /
|
||||
(ext->max_value - ext->min_value);
|
||||
}
|
||||
|
||||
indic_area.x2 = indic_area.x1 + indic_area.x2 - 1;
|
||||
if(ext->sym && ext->min_value < 0 && ext->max_value > 0) {
|
||||
/*Calculate the coordinate of the zero point*/
|
||||
lv_coord_t zero;
|
||||
zero = indic_area.x1 + (-ext->min_value * w) / (ext->max_value - ext->min_value);
|
||||
if(indic_area.x2 > zero) indic_area.x1 = zero;
|
||||
zero =
|
||||
indic_area.x1 + (-ext->min_value * w) / (ext->max_value - ext->min_value);
|
||||
if(indic_area.x2 > zero)
|
||||
indic_area.x1 = zero;
|
||||
else {
|
||||
indic_area.x1 = indic_area.x2;
|
||||
indic_area.x2 = zero;
|
||||
@ -385,13 +390,21 @@ static bool lv_bar_design(lv_obj_t * bar, const lv_area_t * mask, lv_design_mode
|
||||
} else {
|
||||
if(ext->anim_state != LV_BAR_ANIM_STATE_INV) {
|
||||
/*Calculate the coordinates of anim. start and end*/
|
||||
lv_coord_t anim_start_y = (int32_t)((int32_t)h * (ext->anim_start - ext->min_value)) / (ext->max_value - ext->min_value);
|
||||
lv_coord_t anim_end_y = (int32_t)((int32_t)h * (ext->anim_end - ext->min_value)) / (ext->max_value - ext->min_value);
|
||||
lv_coord_t anim_start_y =
|
||||
(int32_t)((int32_t)h * (ext->anim_start - ext->min_value)) /
|
||||
(ext->max_value - ext->min_value);
|
||||
lv_coord_t anim_end_y =
|
||||
(int32_t)((int32_t)h * (ext->anim_end - ext->min_value)) /
|
||||
(ext->max_value - ext->min_value);
|
||||
|
||||
/*Calculate the real position based on `anim_state` (between `anim_start` and `anim_end`)*/
|
||||
indic_area.y1 = anim_start_y + (((anim_end_y - anim_start_y) * ext->anim_state) >> LV_BAR_ANIM_STATE_NORM);
|
||||
/*Calculate the real position based on `anim_state` (between `anim_start` and
|
||||
* `anim_end`)*/
|
||||
indic_area.y1 =
|
||||
anim_start_y +
|
||||
(((anim_end_y - anim_start_y) * ext->anim_state) >> LV_BAR_ANIM_STATE_NORM);
|
||||
} else {
|
||||
indic_area.y1 = (int32_t)((int32_t)h * (ext->cur_value - ext->min_value)) / (ext->max_value - ext->min_value);
|
||||
indic_area.y1 = (int32_t)((int32_t)h * (ext->cur_value - ext->min_value)) /
|
||||
(ext->max_value - ext->min_value);
|
||||
}
|
||||
|
||||
indic_area.y1 = indic_area.y2 - indic_area.y1 + 1;
|
||||
@ -399,8 +412,10 @@ static bool lv_bar_design(lv_obj_t * bar, const lv_area_t * mask, lv_design_mode
|
||||
if(ext->sym && ext->min_value < 0 && ext->max_value > 0) {
|
||||
/*Calculate the coordinate of the zero point*/
|
||||
lv_coord_t zero;
|
||||
zero = indic_area.y2 - (-ext->min_value * h) / (ext->max_value - ext->min_value);
|
||||
if(indic_area.y1 < zero) indic_area.y2 = zero;
|
||||
zero =
|
||||
indic_area.y2 - (-ext->min_value * h) / (ext->max_value - ext->min_value);
|
||||
if(indic_area.y1 < zero)
|
||||
indic_area.y2 = zero;
|
||||
else {
|
||||
indic_area.y2 = indic_area.y1;
|
||||
indic_area.y1 = zero;
|
||||
@ -408,7 +423,6 @@ static bool lv_bar_design(lv_obj_t * bar, const lv_area_t * mask, lv_design_mode
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*Draw the indicator*/
|
||||
lv_draw_rect(&indic_area, mask, style_indic, opa_scale);
|
||||
}
|
||||
@ -416,16 +430,15 @@ static bool lv_bar_design(lv_obj_t * bar, const lv_area_t * mask, lv_design_mode
|
||||
#if LV_USE_GROUP
|
||||
/*Draw the border*/
|
||||
if(lv_obj_is_focused(bar)) {
|
||||
lv_opa_t opa_scale = lv_obj_get_opa_scale(bar);
|
||||
lv_opa_t opa_scale = lv_obj_get_opa_scale(bar);
|
||||
lv_style_t * style_bg = lv_bar_get_style(bar, LV_BAR_STYLE_BG);
|
||||
lv_style_t style_tmp;
|
||||
lv_style_copy(&style_tmp, style_bg);
|
||||
style_tmp.body.opa = LV_OPA_TRANSP;
|
||||
style_tmp.body.opa = LV_OPA_TRANSP;
|
||||
style_tmp.body.shadow.width = 0;
|
||||
lv_draw_rect(&bar->coords, mask, &style_tmp, opa_scale);
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -447,11 +460,12 @@ static lv_res_t lv_bar_signal(lv_obj_t * bar, lv_signal_t sign, void * param)
|
||||
|
||||
if(sign == LV_SIGNAL_REFR_EXT_SIZE) {
|
||||
lv_style_t * style_indic = lv_bar_get_style(bar, LV_BAR_STYLE_INDIC);
|
||||
if(style_indic->body.shadow.width > bar->ext_size) bar->ext_size = style_indic->body.shadow.width;
|
||||
if(style_indic->body.shadow.width > bar->ext_size)
|
||||
bar->ext_size = style_indic->body.shadow.width;
|
||||
} else if(sign == LV_SIGNAL_GET_TYPE) {
|
||||
lv_obj_type_t * buf = param;
|
||||
uint8_t i;
|
||||
for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/
|
||||
for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/
|
||||
if(buf->type[i] == NULL) break;
|
||||
}
|
||||
buf->type[i] = "lv_bar";
|
||||
@ -460,20 +474,18 @@ static lv_res_t lv_bar_signal(lv_obj_t * bar, lv_signal_t sign, void * param)
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
static void lv_bar_animate(void * bar, int32_t value)
|
||||
{
|
||||
lv_bar_ext_t * ext = lv_obj_get_ext_attr(bar);
|
||||
ext->anim_state = value;
|
||||
ext->anim_state = value;
|
||||
lv_obj_invalidate(bar);
|
||||
}
|
||||
|
||||
static void lv_bar_anim_ready(void * bar)
|
||||
{
|
||||
lv_bar_ext_t * ext = lv_obj_get_ext_attr(bar);
|
||||
ext->anim_state = LV_BAR_ANIM_STATE_INV;
|
||||
ext->anim_state = LV_BAR_ANIM_STATE_INV;
|
||||
lv_bar_set_value(bar, ext->anim_end, false);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -29,10 +29,10 @@ extern "C" {
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define LV_BAR_ANIM_STATE_START 0
|
||||
#define LV_BAR_ANIM_STATE_END 256
|
||||
#define LV_BAR_ANIM_STATE_INV -1
|
||||
#define LV_BAR_ANIM_STATE_NORM 8 /*log2(LV_BAR_ANIM_STATE_END) used to normalize data*/
|
||||
#define LV_BAR_ANIM_STATE_START 0
|
||||
#define LV_BAR_ANIM_STATE_END 256
|
||||
#define LV_BAR_ANIM_STATE_INV -1
|
||||
#define LV_BAR_ANIM_STATE_NORM 8 /*log2(LV_BAR_ANIM_STATE_END) used to normalize data*/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
@ -41,17 +41,17 @@ extern "C" {
|
||||
/*Data of bar*/
|
||||
typedef struct
|
||||
{
|
||||
/*No inherited ext*/ /*Ext. of ancestor*/
|
||||
/*No inherited ext*/ /*Ext. of ancestor*/
|
||||
/*New data for this type */
|
||||
int16_t cur_value; /*Current value of the bar*/
|
||||
int16_t min_value; /*Minimum value of the bar*/
|
||||
int16_t max_value; /*Maximum value of the bar*/
|
||||
int16_t cur_value; /*Current value of the bar*/
|
||||
int16_t min_value; /*Minimum value of the bar*/
|
||||
int16_t max_value; /*Maximum value of the bar*/
|
||||
int16_t anim_start;
|
||||
int16_t anim_end;
|
||||
int16_t anim_state;
|
||||
uint16_t anim_time;
|
||||
uint8_t sym :1; /*Symmetric: means the center is around zero value*/
|
||||
lv_style_t *style_indic; /*Style of the indicator*/
|
||||
uint8_t sym : 1; /*Symmetric: means the center is around zero value*/
|
||||
lv_style_t * style_indic; /*Style of the indicator*/
|
||||
} lv_bar_ext_t;
|
||||
|
||||
enum {
|
||||
@ -93,7 +93,8 @@ void lv_bar_set_value(lv_obj_t * bar, int16_t value, bool anim);
|
||||
void lv_bar_set_range(lv_obj_t * bar, int16_t min, int16_t max);
|
||||
|
||||
/**
|
||||
* Make the bar symmetric to zero. The indicator will grow from zero instead of the minimum position.
|
||||
* Make the bar symmetric to zero. The indicator will grow from zero instead of the minimum
|
||||
* position.
|
||||
* @param bar pointer to a bar object
|
||||
* @param en true: enable disable symmetric behavior; false: disable
|
||||
*/
|
||||
@ -105,7 +106,7 @@ void lv_bar_set_sym(lv_obj_t * bar, bool en);
|
||||
* @param type which style should be set
|
||||
* @param style pointer to a style
|
||||
*/
|
||||
void lv_bar_set_style(lv_obj_t *bar, lv_bar_style_t type, lv_style_t *style);
|
||||
void lv_bar_set_style(lv_obj_t * bar, lv_bar_style_t type, lv_style_t * style);
|
||||
|
||||
/*=====================
|
||||
* Getter functions
|
||||
@ -145,13 +146,13 @@ bool lv_bar_get_sym(lv_obj_t * bar);
|
||||
* @param type which style should be get
|
||||
* @return style pointer to a style
|
||||
*/
|
||||
lv_style_t * lv_bar_get_style(const lv_obj_t *bar, lv_bar_style_t type);
|
||||
lv_style_t * lv_bar_get_style(const lv_obj_t * bar, lv_bar_style_t type);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_BAR*/
|
||||
#endif /*LV_USE_BAR*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
@ -21,8 +21,8 @@
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define LV_BTN_INK_VALUE_MAX 256
|
||||
#define LV_BTN_INK_VALUE_MAX_SHIFT 8
|
||||
#define LV_BTN_INK_VALUE_MAX 256
|
||||
#define LV_BTN_INK_VALUE_MAX_SHIFT 8
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
@ -89,17 +89,17 @@ lv_obj_t * lv_btn_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
|
||||
ext->state = LV_BTN_STATE_REL;
|
||||
|
||||
ext->styles[LV_BTN_STATE_REL] = &lv_style_btn_rel;
|
||||
ext->styles[LV_BTN_STATE_PR] = &lv_style_btn_pr;
|
||||
ext->styles[LV_BTN_STATE_REL] = &lv_style_btn_rel;
|
||||
ext->styles[LV_BTN_STATE_PR] = &lv_style_btn_pr;
|
||||
ext->styles[LV_BTN_STATE_TGL_REL] = &lv_style_btn_tgl_rel;
|
||||
ext->styles[LV_BTN_STATE_TGL_PR] = &lv_style_btn_tgl_pr;
|
||||
ext->styles[LV_BTN_STATE_INA] = &lv_style_btn_ina;
|
||||
ext->styles[LV_BTN_STATE_TGL_PR] = &lv_style_btn_tgl_pr;
|
||||
ext->styles[LV_BTN_STATE_INA] = &lv_style_btn_ina;
|
||||
|
||||
ext->toggle = 0;
|
||||
#if LV_USE_ANIMATION && LV_BTN_INK_EFFECT
|
||||
ext->ink_in_time = 0;
|
||||
ext->ink_in_time = 0;
|
||||
ext->ink_wait_time = 0;
|
||||
ext->ink_out_time = 0;
|
||||
ext->ink_out_time = 0;
|
||||
#endif
|
||||
|
||||
lv_obj_set_signal_cb(new_btn, lv_btn_signal);
|
||||
@ -112,7 +112,7 @@ lv_obj_t * lv_btn_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
lv_btn_set_layout(new_btn, LV_LAYOUT_CENTER);
|
||||
}
|
||||
|
||||
lv_obj_set_click(new_btn, true); /*Be sure the button is clickable*/
|
||||
lv_obj_set_click(new_btn, true); /*Be sure the button is clickable*/
|
||||
|
||||
/*Set the default styles*/
|
||||
lv_theme_t * th = lv_theme_get_current();
|
||||
@ -129,12 +129,12 @@ lv_obj_t * lv_btn_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
/*Copy 'copy'*/
|
||||
else {
|
||||
lv_btn_ext_t * copy_ext = lv_obj_get_ext_attr(copy);
|
||||
ext->state = copy_ext->state;
|
||||
ext->toggle = copy_ext->toggle;
|
||||
ext->state = copy_ext->state;
|
||||
ext->toggle = copy_ext->toggle;
|
||||
#if LV_USE_ANIMATION && LV_BTN_INK_EFFECT
|
||||
ext->ink_in_time = copy_ext->ink_in_time;
|
||||
ext->ink_in_time = copy_ext->ink_in_time;
|
||||
ext->ink_wait_time = copy_ext->ink_wait_time;
|
||||
ext->ink_out_time = copy_ext->ink_out_time;
|
||||
ext->ink_out_time = copy_ext->ink_out_time;
|
||||
#endif
|
||||
memcpy(ext->styles, copy_ext->styles, sizeof(ext->styles));
|
||||
|
||||
@ -185,20 +185,11 @@ void lv_btn_toggle(lv_obj_t * btn)
|
||||
{
|
||||
lv_btn_ext_t * ext = lv_obj_get_ext_attr(btn);
|
||||
switch(ext->state) {
|
||||
case LV_BTN_STATE_REL:
|
||||
lv_btn_set_state(btn, LV_BTN_STATE_TGL_REL);
|
||||
break;
|
||||
case LV_BTN_STATE_PR:
|
||||
lv_btn_set_state(btn, LV_BTN_STATE_TGL_PR);
|
||||
break;
|
||||
case LV_BTN_STATE_TGL_REL:
|
||||
lv_btn_set_state(btn, LV_BTN_STATE_REL);
|
||||
break;
|
||||
case LV_BTN_STATE_TGL_PR:
|
||||
lv_btn_set_state(btn, LV_BTN_STATE_PR);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
case LV_BTN_STATE_REL: lv_btn_set_state(btn, LV_BTN_STATE_TGL_REL); break;
|
||||
case LV_BTN_STATE_PR: lv_btn_set_state(btn, LV_BTN_STATE_TGL_PR); break;
|
||||
case LV_BTN_STATE_TGL_REL: lv_btn_set_state(btn, LV_BTN_STATE_REL); break;
|
||||
case LV_BTN_STATE_TGL_PR: lv_btn_set_state(btn, LV_BTN_STATE_PR); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -211,11 +202,12 @@ void lv_btn_set_ink_in_time(lv_obj_t * btn, uint16_t time)
|
||||
{
|
||||
#if LV_USE_ANIMATION && LV_BTN_INK_EFFECT
|
||||
lv_btn_ext_t * ext = lv_obj_get_ext_attr(btn);
|
||||
ext->ink_in_time = time;
|
||||
ext->ink_in_time = time;
|
||||
#else
|
||||
(void)btn; /*Unused*/
|
||||
(void)btn; /*Unused*/
|
||||
(void)time; /*Unused*/
|
||||
LV_LOG_WARN("`lv_btn_set_ink_ink_time` has no effect if LV_BTN_INK_EFEFCT or LV_USE_ANIMATION is disabled")
|
||||
LV_LOG_WARN("`lv_btn_set_ink_ink_time` has no effect if LV_BTN_INK_EFEFCT or LV_USE_ANIMATION "
|
||||
"is disabled")
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -231,9 +223,10 @@ void lv_btn_set_ink_wait_time(lv_obj_t * btn, uint16_t time)
|
||||
lv_btn_ext_t * ext = lv_obj_get_ext_attr(btn);
|
||||
ext->ink_wait_time = time;
|
||||
#else
|
||||
(void)btn; /*Unused*/
|
||||
(void)btn; /*Unused*/
|
||||
(void)time; /*Unused*/
|
||||
LV_LOG_WARN("`lv_btn_set_ink_wait_time` has no effect if LV_BTN_INK_EFEFCT or LV_USE_ANIMATION is disabled")
|
||||
LV_LOG_WARN("`lv_btn_set_ink_wait_time` has no effect if LV_BTN_INK_EFEFCT or LV_USE_ANIMATION "
|
||||
"is disabled")
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -246,11 +239,12 @@ void lv_btn_set_ink_out_time(lv_obj_t * btn, uint16_t time)
|
||||
{
|
||||
#if LV_USE_ANIMATION && LV_BTN_INK_EFFECT
|
||||
lv_btn_ext_t * ext = lv_obj_get_ext_attr(btn);
|
||||
ext->ink_out_time = time;
|
||||
ext->ink_out_time = time;
|
||||
#else
|
||||
(void)btn; /*Unused*/
|
||||
(void)btn; /*Unused*/
|
||||
(void)time; /*Unused*/
|
||||
LV_LOG_WARN("`lv_btn_set_ink_out_time` has no effect if LV_BTN_INK_EFEFCT or LV_USE_ANIMATION is disabled")
|
||||
LV_LOG_WARN("`lv_btn_set_ink_out_time` has no effect if LV_BTN_INK_EFEFCT or LV_USE_ANIMATION "
|
||||
"is disabled")
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -265,28 +259,17 @@ void lv_btn_set_style(lv_obj_t * btn, lv_btn_style_t type, lv_style_t * style)
|
||||
lv_btn_ext_t * ext = lv_obj_get_ext_attr(btn);
|
||||
|
||||
switch(type) {
|
||||
case LV_BTN_STYLE_REL:
|
||||
ext->styles[LV_BTN_STATE_REL] = style;
|
||||
break;
|
||||
case LV_BTN_STYLE_PR:
|
||||
ext->styles[LV_BTN_STATE_PR] = style;
|
||||
break;
|
||||
case LV_BTN_STYLE_TGL_REL:
|
||||
ext->styles[LV_BTN_STATE_TGL_REL] = style;
|
||||
break;
|
||||
case LV_BTN_STYLE_TGL_PR:
|
||||
ext->styles[LV_BTN_STATE_TGL_PR] = style;
|
||||
break;
|
||||
case LV_BTN_STYLE_INA:
|
||||
ext->styles[LV_BTN_STATE_INA] = style;
|
||||
break;
|
||||
case LV_BTN_STYLE_REL: ext->styles[LV_BTN_STATE_REL] = style; break;
|
||||
case LV_BTN_STYLE_PR: ext->styles[LV_BTN_STATE_PR] = style; break;
|
||||
case LV_BTN_STYLE_TGL_REL: ext->styles[LV_BTN_STATE_TGL_REL] = style; break;
|
||||
case LV_BTN_STYLE_TGL_PR: ext->styles[LV_BTN_STATE_TGL_PR] = style; break;
|
||||
case LV_BTN_STYLE_INA: ext->styles[LV_BTN_STATE_INA] = style; break;
|
||||
}
|
||||
|
||||
/*Refresh the object with the new style*/
|
||||
lv_obj_set_style(btn, ext->styles[ext->state]);
|
||||
}
|
||||
|
||||
|
||||
/*=====================
|
||||
* Getter functions
|
||||
*====================*/
|
||||
@ -330,7 +313,6 @@ uint16_t lv_btn_get_ink_in_time(const lv_obj_t * btn)
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the wait time before the ink disappears
|
||||
* @param btn pointer to a button object
|
||||
@ -374,24 +356,12 @@ lv_style_t * lv_btn_get_style(const lv_obj_t * btn, lv_btn_style_t type)
|
||||
lv_btn_ext_t * ext = lv_obj_get_ext_attr(btn);
|
||||
|
||||
switch(type) {
|
||||
case LV_BTN_STYLE_REL:
|
||||
style = ext->styles[LV_BTN_STATE_REL];
|
||||
break;
|
||||
case LV_BTN_STYLE_PR:
|
||||
style = ext->styles[LV_BTN_STATE_PR];
|
||||
break;
|
||||
case LV_BTN_STYLE_TGL_REL:
|
||||
style = ext->styles[LV_BTN_STATE_TGL_REL];
|
||||
break;
|
||||
case LV_BTN_STYLE_TGL_PR:
|
||||
style = ext->styles[LV_BTN_STATE_TGL_PR];
|
||||
break;
|
||||
case LV_BTN_STYLE_INA:
|
||||
style = ext->styles[LV_BTN_STATE_INA];
|
||||
break;
|
||||
default:
|
||||
style = NULL;
|
||||
break;
|
||||
case LV_BTN_STYLE_REL: style = ext->styles[LV_BTN_STATE_REL]; break;
|
||||
case LV_BTN_STYLE_PR: style = ext->styles[LV_BTN_STATE_PR]; break;
|
||||
case LV_BTN_STYLE_TGL_REL: style = ext->styles[LV_BTN_STATE_TGL_REL]; break;
|
||||
case LV_BTN_STYLE_TGL_PR: style = ext->styles[LV_BTN_STATE_TGL_PR]; break;
|
||||
case LV_BTN_STYLE_INA: style = ext->styles[LV_BTN_STATE_INA]; break;
|
||||
default: style = NULL; break;
|
||||
}
|
||||
|
||||
return style;
|
||||
@ -401,7 +371,6 @@ lv_style_t * lv_btn_get_style(const lv_obj_t * btn, lv_btn_style_t type)
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
|
||||
/**
|
||||
* Handle the drawing related tasks of the drop down lists
|
||||
* @param btn pointer to an object
|
||||
@ -432,17 +401,19 @@ static bool lv_btn_design(lv_obj_t * btn, const lv_area_t * mask, lv_design_mode
|
||||
style_tmp.body.shadow.width = ext->styles[ink_top_state]->body.shadow.width;
|
||||
lv_draw_rect(&btn->coords, mask, &style_tmp, opa_scale);
|
||||
|
||||
lv_coord_t w = lv_obj_get_width(btn);
|
||||
lv_coord_t h = lv_obj_get_height(btn);
|
||||
lv_coord_t w = lv_obj_get_width(btn);
|
||||
lv_coord_t h = lv_obj_get_height(btn);
|
||||
lv_coord_t r_max = LV_MATH_MIN(w, h) / 2;
|
||||
|
||||
/*In the first part of the animation increase the size of the circle (ink effect) */
|
||||
lv_area_t cir_area;
|
||||
|
||||
lv_coord_t coord_state = ink_act_value < LV_BTN_INK_VALUE_MAX / 2 ? ink_act_value : LV_BTN_INK_VALUE_MAX / 2;
|
||||
lv_coord_t coord_state = ink_act_value < LV_BTN_INK_VALUE_MAX / 2
|
||||
? ink_act_value
|
||||
: LV_BTN_INK_VALUE_MAX / 2;
|
||||
lv_point_t p_act;
|
||||
p_act.x = ink_point.x;
|
||||
p_act.y = ink_point.y;
|
||||
p_act.x = ink_point.x;
|
||||
p_act.y = ink_point.y;
|
||||
lv_coord_t x_err = (btn->coords.x1 + w / 2) - p_act.x;
|
||||
lv_coord_t y_err = (btn->coords.y1 + h / 2) - p_act.y;
|
||||
|
||||
@ -450,18 +421,28 @@ static bool lv_btn_design(lv_obj_t * btn, const lv_area_t * mask, lv_design_mode
|
||||
p_act.y += (y_err * coord_state) >> (LV_BTN_INK_VALUE_MAX_SHIFT - 1);
|
||||
|
||||
lv_coord_t half_side = LV_MATH_MAX(w, h) / 2;
|
||||
cir_area.x1 = p_act.x - ((half_side * coord_state) >> (LV_BTN_INK_VALUE_MAX_SHIFT - 1));
|
||||
cir_area.y1 = p_act.y - ((half_side * coord_state) >> (LV_BTN_INK_VALUE_MAX_SHIFT - 1));
|
||||
cir_area.x2 = p_act.x + ((half_side * coord_state) >> (LV_BTN_INK_VALUE_MAX_SHIFT - 1));
|
||||
cir_area.y2 = p_act.y + ((half_side * coord_state) >> (LV_BTN_INK_VALUE_MAX_SHIFT - 1));
|
||||
cir_area.x1 =
|
||||
p_act.x - ((half_side * coord_state) >> (LV_BTN_INK_VALUE_MAX_SHIFT - 1));
|
||||
cir_area.y1 =
|
||||
p_act.y - ((half_side * coord_state) >> (LV_BTN_INK_VALUE_MAX_SHIFT - 1));
|
||||
cir_area.x2 =
|
||||
p_act.x + ((half_side * coord_state) >> (LV_BTN_INK_VALUE_MAX_SHIFT - 1));
|
||||
cir_area.y2 =
|
||||
p_act.y + ((half_side * coord_state) >> (LV_BTN_INK_VALUE_MAX_SHIFT - 1));
|
||||
|
||||
lv_area_intersect(&cir_area, &btn->coords, &cir_area); /*Limit the area. (It might be too big on the smaller side)*/
|
||||
lv_area_intersect(
|
||||
&cir_area, &btn->coords,
|
||||
&cir_area); /*Limit the area. (It might be too big on the smaller side)*/
|
||||
|
||||
/*In the second part animate the radius. Circle -> body.radius*/
|
||||
lv_coord_t r_state = ink_act_value > LV_BTN_INK_VALUE_MAX / 2 ? ink_act_value - LV_BTN_INK_VALUE_MAX / 2 : 0;
|
||||
lv_coord_t r_state = ink_act_value > LV_BTN_INK_VALUE_MAX / 2
|
||||
? ink_act_value - LV_BTN_INK_VALUE_MAX / 2
|
||||
: 0;
|
||||
|
||||
lv_style_copy(&style_tmp, ext->styles[ink_top_state]);
|
||||
style_tmp.body.radius = r_max + (((ext->styles[ink_bg_state]->body.radius - r_max) * r_state) >> (LV_BTN_INK_VALUE_MAX_SHIFT - 1));
|
||||
style_tmp.body.radius =
|
||||
r_max + (((ext->styles[ink_bg_state]->body.radius - r_max) * r_state) >>
|
||||
(LV_BTN_INK_VALUE_MAX_SHIFT - 1));
|
||||
style_tmp.body.border.width = 0;
|
||||
|
||||
/*Draw the circle*/
|
||||
@ -469,9 +450,9 @@ static bool lv_btn_design(lv_obj_t * btn, const lv_area_t * mask, lv_design_mode
|
||||
} else {
|
||||
lv_style_t res;
|
||||
lv_style_copy(&res, ext->styles[ink_bg_state]);
|
||||
lv_style_mix(ext->styles[ink_bg_state], ext->styles[ink_top_state], &res, ink_act_value);
|
||||
lv_style_mix(ext->styles[ink_bg_state], ext->styles[ink_top_state], &res,
|
||||
ink_act_value);
|
||||
lv_draw_rect(&btn->coords, mask, &res, opa_scale);
|
||||
|
||||
}
|
||||
}
|
||||
#else
|
||||
@ -500,20 +481,20 @@ static lv_res_t lv_btn_signal(lv_obj_t * btn, lv_signal_t sign, void * param)
|
||||
if(res != LV_RES_OK) return res;
|
||||
|
||||
lv_btn_ext_t * ext = lv_obj_get_ext_attr(btn);
|
||||
bool tgl = lv_btn_get_toggle(btn);
|
||||
bool tgl = lv_btn_get_toggle(btn);
|
||||
|
||||
if(sign == LV_SIGNAL_PRESSED) {
|
||||
/*Refresh the state*/
|
||||
if(ext->state == LV_BTN_STATE_REL) {
|
||||
lv_btn_set_state(btn, LV_BTN_STATE_PR);
|
||||
#if LV_USE_ANIMATION && LV_BTN_INK_EFFECT
|
||||
ink_bg_state = LV_BTN_STATE_REL;
|
||||
ink_bg_state = LV_BTN_STATE_REL;
|
||||
ink_top_state = LV_BTN_STATE_PR;
|
||||
#endif
|
||||
} else if(ext->state == LV_BTN_STATE_TGL_REL) {
|
||||
lv_btn_set_state(btn, LV_BTN_STATE_TGL_PR);
|
||||
#if LV_USE_ANIMATION && LV_BTN_INK_EFFECT
|
||||
ink_bg_state = LV_BTN_STATE_TGL_REL;
|
||||
ink_bg_state = LV_BTN_STATE_TGL_REL;
|
||||
ink_top_state = LV_BTN_STATE_TGL_PR;
|
||||
#endif
|
||||
}
|
||||
@ -527,36 +508,40 @@ static lv_res_t lv_btn_signal(lv_obj_t * btn, lv_signal_t sign, void * param)
|
||||
}
|
||||
/*Save the new data for inking and start it's animation if enabled*/
|
||||
if(ext->ink_in_time > 0) {
|
||||
ink_obj = btn;
|
||||
ink_obj = btn;
|
||||
ink_playback = false;
|
||||
ink_ready = false;
|
||||
ink_ready = false;
|
||||
lv_indev_get_point(lv_indev_get_act(), &ink_point);
|
||||
|
||||
lv_anim_t a;
|
||||
a.var = btn;
|
||||
a.start = 0;
|
||||
a.end = LV_BTN_INK_VALUE_MAX;
|
||||
a.fp = (lv_anim_fp_t)lv_btn_ink_effect_anim;
|
||||
a.path = lv_anim_path_linear;
|
||||
a.end_cb = lv_btn_ink_effect_anim_ready;
|
||||
a.act_time = 0;
|
||||
a.time = ext->ink_in_time;
|
||||
a.playback = 0;
|
||||
a.var = btn;
|
||||
a.start = 0;
|
||||
a.end = LV_BTN_INK_VALUE_MAX;
|
||||
a.fp = (lv_anim_fp_t)lv_btn_ink_effect_anim;
|
||||
a.path = lv_anim_path_linear;
|
||||
a.end_cb = lv_btn_ink_effect_anim_ready;
|
||||
a.act_time = 0;
|
||||
a.time = ext->ink_in_time;
|
||||
a.playback = 0;
|
||||
a.playback_pause = 0;
|
||||
a.repeat = 0;
|
||||
a.repeat_pause = 0;
|
||||
a.repeat = 0;
|
||||
a.repeat_pause = 0;
|
||||
lv_anim_create(&a);
|
||||
}
|
||||
#endif
|
||||
} else if(sign == LV_SIGNAL_PRESS_LOST) {
|
||||
/*Refresh the state*/
|
||||
if(ext->state == LV_BTN_STATE_PR) lv_btn_set_state(btn, LV_BTN_STATE_REL);
|
||||
else if(ext->state == LV_BTN_STATE_TGL_PR) lv_btn_set_state(btn, LV_BTN_STATE_TGL_REL);
|
||||
if(ext->state == LV_BTN_STATE_PR)
|
||||
lv_btn_set_state(btn, LV_BTN_STATE_REL);
|
||||
else if(ext->state == LV_BTN_STATE_TGL_PR)
|
||||
lv_btn_set_state(btn, LV_BTN_STATE_TGL_REL);
|
||||
} else if(sign == LV_SIGNAL_PRESSING) {
|
||||
/*When the button begins to drag revert pressed states to released*/
|
||||
if(lv_indev_is_dragging(param) != false) {
|
||||
if(ext->state == LV_BTN_STATE_PR) lv_btn_set_state(btn, LV_BTN_STATE_REL);
|
||||
else if(ext->state == LV_BTN_STATE_TGL_PR) lv_btn_set_state(btn, LV_BTN_STATE_TGL_REL);
|
||||
if(ext->state == LV_BTN_STATE_PR)
|
||||
lv_btn_set_state(btn, LV_BTN_STATE_REL);
|
||||
else if(ext->state == LV_BTN_STATE_TGL_PR)
|
||||
lv_btn_set_state(btn, LV_BTN_STATE_TGL_REL);
|
||||
}
|
||||
} else if(sign == LV_SIGNAL_RELEASED) {
|
||||
/*If not dragged and it was not long press action then
|
||||
@ -592,23 +577,24 @@ static lv_res_t lv_btn_signal(lv_obj_t * btn, lv_signal_t sign, void * param)
|
||||
}
|
||||
/*If not a toggle button and the "IN" inking is ready then start an "OUT" inking*/
|
||||
else if(ink_ready && ext->ink_out_time > 0) {
|
||||
ink_obj = btn;
|
||||
ink_playback = true; /*It is the playback. If not set `lv_btn_ink_effect_anim_ready` will start its own playback*/
|
||||
ink_obj = btn;
|
||||
ink_playback = true; /*It is the playback. If not set `lv_btn_ink_effect_anim_ready`
|
||||
will start its own playback*/
|
||||
lv_indev_get_point(lv_indev_get_act(), &ink_point);
|
||||
|
||||
lv_anim_t a;
|
||||
a.var = ink_obj;
|
||||
a.start = LV_BTN_INK_VALUE_MAX;
|
||||
a.end = 0;
|
||||
a.fp = (lv_anim_fp_t)lv_btn_ink_effect_anim;
|
||||
a.path = lv_anim_path_linear;
|
||||
a.end_cb = lv_btn_ink_effect_anim_ready;
|
||||
a.act_time = 0;
|
||||
a.time = ext->ink_out_time;
|
||||
a.playback = 0;
|
||||
a.var = ink_obj;
|
||||
a.start = LV_BTN_INK_VALUE_MAX;
|
||||
a.end = 0;
|
||||
a.fp = (lv_anim_fp_t)lv_btn_ink_effect_anim;
|
||||
a.path = lv_anim_path_linear;
|
||||
a.end_cb = lv_btn_ink_effect_anim_ready;
|
||||
a.act_time = 0;
|
||||
a.time = ext->ink_out_time;
|
||||
a.playback = 0;
|
||||
a.playback_pause = 0;
|
||||
a.repeat = 0;
|
||||
a.repeat_pause = 0;
|
||||
a.repeat = 0;
|
||||
a.repeat_pause = 0;
|
||||
lv_anim_create(&a);
|
||||
}
|
||||
#endif
|
||||
@ -620,17 +606,21 @@ static lv_res_t lv_btn_signal(lv_obj_t * btn, lv_signal_t sign, void * param)
|
||||
} else if(c == LV_GROUP_KEY_LEFT || c == LV_GROUP_KEY_DOWN) {
|
||||
if(lv_btn_get_toggle(btn)) lv_btn_set_state(btn, LV_BTN_STATE_REL);
|
||||
}
|
||||
// else if(c == LV_GROUP_KEY_ENTER) {
|
||||
// if(lv_btn_get_toggle(btn)) {
|
||||
// if(state == LV_BTN_STATE_REL || state == LV_BTN_STATE_PR) lv_btn_set_state(btn, LV_BTN_STATE_TGL_REL);
|
||||
// else if(state == LV_BTN_STATE_TGL_REL || state == LV_BTN_STATE_TGL_PR) lv_btn_set_state(btn, LV_BTN_STATE_REL);
|
||||
// } else {
|
||||
// if(state == LV_BTN_STATE_REL || state == LV_BTN_STATE_PR) lv_btn_set_state(btn, LV_BTN_STATE_REL);
|
||||
// else if(state == LV_BTN_STATE_TGL_REL || state == LV_BTN_STATE_TGL_PR) lv_btn_set_state(btn, LV_BTN_STATE_TGL_REL);
|
||||
// }
|
||||
// res = lv_obj_send_event(btn, LV_EVENT_VALUE_CHANGED);
|
||||
// if(res != LV_RES_OK) return res;
|
||||
// }
|
||||
// else if(c == LV_GROUP_KEY_ENTER) {
|
||||
// if(lv_btn_get_toggle(btn)) {
|
||||
// if(state == LV_BTN_STATE_REL || state == LV_BTN_STATE_PR)
|
||||
// lv_btn_set_state(btn, LV_BTN_STATE_TGL_REL); else if(state ==
|
||||
// LV_BTN_STATE_TGL_REL || state == LV_BTN_STATE_TGL_PR)
|
||||
// lv_btn_set_state(btn, LV_BTN_STATE_REL);
|
||||
// } else {
|
||||
// if(state == LV_BTN_STATE_REL || state == LV_BTN_STATE_PR)
|
||||
// lv_btn_set_state(btn, LV_BTN_STATE_REL); else if(state ==
|
||||
// LV_BTN_STATE_TGL_REL || state == LV_BTN_STATE_TGL_PR)
|
||||
// lv_btn_set_state(btn, LV_BTN_STATE_TGL_REL);
|
||||
// }
|
||||
// res = lv_obj_send_event(btn, LV_EVENT_VALUE_CHANGED);
|
||||
// if(res != LV_RES_OK) return res;
|
||||
// }
|
||||
} else if(sign == LV_SIGNAL_CLEANUP) {
|
||||
#if LV_USE_ANIMATION && LV_BTN_INK_EFFECT
|
||||
if(btn == ink_obj) {
|
||||
@ -641,7 +631,7 @@ static lv_res_t lv_btn_signal(lv_obj_t * btn, lv_signal_t sign, void * param)
|
||||
} else if(sign == LV_SIGNAL_GET_TYPE) {
|
||||
lv_obj_type_t * buf = param;
|
||||
uint8_t i;
|
||||
for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/
|
||||
for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/
|
||||
if(buf->type[i] == NULL) break;
|
||||
}
|
||||
buf->type[i] = "lv_btn";
|
||||
@ -671,28 +661,29 @@ static void lv_btn_ink_effect_anim(lv_obj_t * btn, int32_t val)
|
||||
*/
|
||||
static void lv_btn_ink_effect_anim_ready(void * p)
|
||||
{
|
||||
(void) p; /*Unused*/
|
||||
(void)p; /*Unused*/
|
||||
|
||||
lv_btn_ext_t * ext = lv_obj_get_ext_attr(ink_obj);
|
||||
lv_btn_ext_t * ext = lv_obj_get_ext_attr(ink_obj);
|
||||
lv_btn_state_t state = lv_btn_get_state(ink_obj);
|
||||
|
||||
lv_obj_invalidate(ink_obj);
|
||||
ink_ready = true;
|
||||
|
||||
if((state == LV_BTN_STATE_REL || state == LV_BTN_STATE_TGL_REL) && ext->toggle == 0 && ink_playback == false) {
|
||||
if((state == LV_BTN_STATE_REL || state == LV_BTN_STATE_TGL_REL) && ext->toggle == 0 &&
|
||||
ink_playback == false) {
|
||||
lv_anim_t a;
|
||||
a.var = ink_obj;
|
||||
a.start = LV_BTN_INK_VALUE_MAX;
|
||||
a.end = 0;
|
||||
a.fp = (lv_anim_fp_t)lv_btn_ink_effect_anim;
|
||||
a.path = lv_anim_path_linear;
|
||||
a.end_cb = lv_btn_ink_effect_anim_ready;
|
||||
a.act_time = -ext->ink_wait_time;
|
||||
a.time = ext->ink_out_time;
|
||||
a.playback = 0;
|
||||
a.var = ink_obj;
|
||||
a.start = LV_BTN_INK_VALUE_MAX;
|
||||
a.end = 0;
|
||||
a.fp = (lv_anim_fp_t)lv_btn_ink_effect_anim;
|
||||
a.path = lv_anim_path_linear;
|
||||
a.end_cb = lv_btn_ink_effect_anim_ready;
|
||||
a.act_time = -ext->ink_wait_time;
|
||||
a.time = ext->ink_out_time;
|
||||
a.playback = 0;
|
||||
a.playback_pause = 0;
|
||||
a.repeat = 0;
|
||||
a.repeat_pause = 0;
|
||||
a.repeat = 0;
|
||||
a.repeat_pause = 0;
|
||||
lv_anim_create(&a);
|
||||
|
||||
ink_playback = true;
|
||||
|
@ -39,8 +39,7 @@ extern "C" {
|
||||
|
||||
/* Button states
|
||||
* It can be used not only by buttons but other button-like objects too*/
|
||||
enum
|
||||
{
|
||||
enum {
|
||||
LV_BTN_STATE_REL,
|
||||
LV_BTN_STATE_PR,
|
||||
LV_BTN_STATE_TGL_REL,
|
||||
@ -55,14 +54,14 @@ typedef struct
|
||||
{
|
||||
lv_cont_ext_t cont; /*Ext. of ancestor*/
|
||||
/*New data for this type */
|
||||
lv_style_t * styles[LV_BTN_STATE_NUM]; /*Styles in each state*/
|
||||
lv_btn_state_t state; /*Current state of the button from 'lv_btn_state_t' enum*/
|
||||
lv_style_t * styles[LV_BTN_STATE_NUM]; /*Styles in each state*/
|
||||
lv_btn_state_t state; /*Current state of the button from 'lv_btn_state_t' enum*/
|
||||
#if LV_BTN_INK_EFFECT
|
||||
uint16_t ink_in_time; /*[ms] Time of ink fill effect (0: disable ink effect)*/
|
||||
uint16_t ink_wait_time; /*[ms] Wait before the ink disappears */
|
||||
uint16_t ink_out_time; /*[ms] Time of ink disappearing*/
|
||||
uint16_t ink_in_time; /*[ms] Time of ink fill effect (0: disable ink effect)*/
|
||||
uint16_t ink_wait_time; /*[ms] Wait before the ink disappears */
|
||||
uint16_t ink_out_time; /*[ms] Time of ink disappearing*/
|
||||
#endif
|
||||
uint8_t toggle :1; /*1: Toggle enabled*/
|
||||
uint8_t toggle : 1; /*1: Toggle enabled*/
|
||||
} lv_btn_ext_t;
|
||||
|
||||
/*Styles*/
|
||||
@ -130,7 +129,8 @@ static inline void lv_btn_set_layout(lv_obj_t * btn, lv_layout_t layout)
|
||||
* @param top bottom fit policy from `lv_fit_t`
|
||||
* @param bottom bottom fit policy from `lv_fit_t`
|
||||
*/
|
||||
static inline void lv_btn_set_fit4(lv_obj_t * btn, lv_fit_t left, lv_fit_t right, lv_fit_t top, lv_fit_t bottom)
|
||||
static inline void lv_btn_set_fit4(lv_obj_t * btn, lv_fit_t left, lv_fit_t right, lv_fit_t top,
|
||||
lv_fit_t bottom)
|
||||
{
|
||||
lv_cont_set_fit4(btn, left, right, top, bottom);
|
||||
}
|
||||
@ -185,7 +185,7 @@ void lv_btn_set_ink_out_time(lv_obj_t * btn, uint16_t time);
|
||||
* @param type which style should be set
|
||||
* @param style pointer to a style
|
||||
* */
|
||||
void lv_btn_set_style(lv_obj_t * btn, lv_btn_style_t type, lv_style_t *style);
|
||||
void lv_btn_set_style(lv_obj_t * btn, lv_btn_style_t type, lv_style_t * style);
|
||||
|
||||
/*=====================
|
||||
* Getter functions
|
||||
@ -255,7 +255,6 @@ static inline lv_fit_t lv_btn_get_fit_bottom(const lv_obj_t * btn)
|
||||
return lv_cont_get_fit_bottom(btn);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get time of the ink in effect (draw a circle on click to animate in the new state)
|
||||
* @param btn pointer to a button object
|
||||
@ -289,10 +288,10 @@ lv_style_t * lv_btn_get_style(const lv_obj_t * btn, lv_btn_style_t type);
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_BUTTON*/
|
||||
#endif /*LV_USE_BUTTON*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_BTN_H*/
|
||||
#endif /*LV_BTN_H*/
|
||||
|
@ -39,14 +39,12 @@ static uint16_t get_button_from_point(lv_obj_t * btnm, lv_point_t * p);
|
||||
static void allocate_btn_areas_and_controls(const lv_obj_t * btnm, const char ** map);
|
||||
static void invalidate_button_area(const lv_obj_t * btnm, uint16_t btn_idx);
|
||||
static bool maps_are_identical(const char ** map1, const char ** map2);
|
||||
static void make_one_button_toggled(lv_obj_t *btnm, uint16_t btn_idx);
|
||||
static void make_one_button_toggled(lv_obj_t * btnm, uint16_t btn_idx);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
static const char * lv_btnm_def_map[] = {"Btn1", "Btn2", "Btn3", "\n",
|
||||
"Btn4", "Btn5", ""
|
||||
};
|
||||
static const char * lv_btnm_def_map[] = {"Btn1", "Btn2", "Btn3", "\n", "Btn4", "Btn5", ""};
|
||||
|
||||
static lv_design_cb_t ancestor_design_f;
|
||||
static lv_signal_cb_t ancestor_signal;
|
||||
@ -62,7 +60,8 @@ static lv_signal_cb_t ancestor_signal;
|
||||
/**
|
||||
* Create a button matrix objects
|
||||
* @param par pointer to an object, it will be the parent of the new button matrix
|
||||
* @param copy pointer to a button matrix object, if not NULL then the new object will be copied from it
|
||||
* @param copy pointer to a button matrix object, if not NULL then the new object will be copied
|
||||
* from it
|
||||
* @return pointer to the created button matrix
|
||||
*/
|
||||
lv_obj_t * lv_btnm_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
@ -81,19 +80,19 @@ lv_obj_t * lv_btnm_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
lv_mem_assert(ext);
|
||||
if(ext == NULL) return NULL;
|
||||
|
||||
ext->btn_cnt = 0;
|
||||
ext->btn_id_pr = LV_BTNM_BTN_NONE;
|
||||
ext->btn_id_act = LV_BTNM_BTN_NONE;
|
||||
ext->button_areas = NULL;
|
||||
ext->ctrl_bits = NULL;
|
||||
ext->map_p = NULL;
|
||||
ext->recolor = 0;
|
||||
ext->one_toggle = 0;
|
||||
ext->styles_btn[LV_BTN_STATE_REL] = &lv_style_btn_rel;
|
||||
ext->styles_btn[LV_BTN_STATE_PR] = &lv_style_btn_pr;
|
||||
ext->btn_cnt = 0;
|
||||
ext->btn_id_pr = LV_BTNM_BTN_NONE;
|
||||
ext->btn_id_act = LV_BTNM_BTN_NONE;
|
||||
ext->button_areas = NULL;
|
||||
ext->ctrl_bits = NULL;
|
||||
ext->map_p = NULL;
|
||||
ext->recolor = 0;
|
||||
ext->one_toggle = 0;
|
||||
ext->styles_btn[LV_BTN_STATE_REL] = &lv_style_btn_rel;
|
||||
ext->styles_btn[LV_BTN_STATE_PR] = &lv_style_btn_pr;
|
||||
ext->styles_btn[LV_BTN_STATE_TGL_REL] = &lv_style_btn_tgl_rel;
|
||||
ext->styles_btn[LV_BTN_STATE_TGL_PR] = &lv_style_btn_tgl_pr;
|
||||
ext->styles_btn[LV_BTN_STATE_INA] = &lv_style_btn_ina;
|
||||
ext->styles_btn[LV_BTN_STATE_TGL_PR] = &lv_style_btn_tgl_pr;
|
||||
ext->styles_btn[LV_BTN_STATE_INA] = &lv_style_btn_ina;
|
||||
|
||||
if(ancestor_design_f == NULL) ancestor_design_f = lv_obj_get_design_func(new_btnm);
|
||||
|
||||
@ -157,7 +156,7 @@ void lv_btnm_set_map(const lv_obj_t * btnm, const char * map[])
|
||||
* set/allocation when map hasn't changed.
|
||||
*/
|
||||
lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm);
|
||||
if (!maps_are_identical(ext->map_p, map)) {
|
||||
if(!maps_are_identical(ext->map_p, map)) {
|
||||
|
||||
/*Analyze the map and create the required number of buttons*/
|
||||
allocate_btn_areas_and_controls(btnm, map);
|
||||
@ -166,43 +165,45 @@ void lv_btnm_set_map(const lv_obj_t * btnm, const char * map[])
|
||||
|
||||
/*Set size and positions of the buttons*/
|
||||
lv_style_t * style_bg = lv_btnm_get_style(btnm, LV_BTNM_STYLE_BG);
|
||||
lv_coord_t max_w = lv_obj_get_width(btnm) - style_bg->body.padding.left - style_bg->body.padding.right;
|
||||
lv_coord_t max_h = lv_obj_get_height(btnm) - style_bg->body.padding.top - style_bg->body.padding.bottom;
|
||||
lv_coord_t max_w =
|
||||
lv_obj_get_width(btnm) - style_bg->body.padding.left - style_bg->body.padding.right;
|
||||
lv_coord_t max_h =
|
||||
lv_obj_get_height(btnm) - style_bg->body.padding.top - style_bg->body.padding.bottom;
|
||||
lv_coord_t act_y = style_bg->body.padding.top;
|
||||
|
||||
/*Count the lines to calculate button height*/
|
||||
uint8_t line_cnt = 1;
|
||||
uint8_t li;
|
||||
for(li = 0; strlen(map[li]) != 0; li++) {
|
||||
if(strcmp(map[li], "\n") == 0) line_cnt ++;
|
||||
if(strcmp(map[li], "\n") == 0) line_cnt++;
|
||||
}
|
||||
|
||||
lv_coord_t btn_h = max_h - ((line_cnt - 1) * style_bg->body.padding.inner);
|
||||
btn_h = btn_h / line_cnt;
|
||||
btn_h --; /*-1 because e.g. height = 100 means 101 pixels (0..100)*/
|
||||
btn_h = btn_h / line_cnt;
|
||||
btn_h--; /*-1 because e.g. height = 100 means 101 pixels (0..100)*/
|
||||
|
||||
/* Count the units and the buttons in a line
|
||||
* (A button can be 1,2,3... unit wide)*/
|
||||
uint16_t unit_cnt; /*Number of units in a row*/
|
||||
uint16_t unit_act_cnt; /*Number of units currently put in a row*/
|
||||
uint16_t btn_cnt; /*Number of buttons in a row*/
|
||||
uint16_t i_tot = 0; /*Act. index in the str map*/
|
||||
uint16_t btn_i = 0; /*Act. index of button areas*/
|
||||
const char ** map_p_tmp = map;
|
||||
uint16_t unit_cnt; /*Number of units in a row*/
|
||||
uint16_t unit_act_cnt; /*Number of units currently put in a row*/
|
||||
uint16_t btn_cnt; /*Number of buttons in a row*/
|
||||
uint16_t i_tot = 0; /*Act. index in the str map*/
|
||||
uint16_t btn_i = 0; /*Act. index of button areas*/
|
||||
const char ** map_p_tmp = map;
|
||||
|
||||
/*Count the units and the buttons in a line*/
|
||||
while(1) {
|
||||
unit_cnt = 0;
|
||||
btn_cnt = 0;
|
||||
btn_cnt = 0;
|
||||
/*Count the buttons in a line*/
|
||||
while(strcmp(map_p_tmp[btn_cnt], "\n") != 0 &&
|
||||
strlen(map_p_tmp[btn_cnt]) != 0) { /*Check a line*/
|
||||
strlen(map_p_tmp[btn_cnt]) != 0) { /*Check a line*/
|
||||
unit_cnt += get_button_width(ext->ctrl_bits[btn_i + btn_cnt]);
|
||||
btn_cnt ++;
|
||||
btn_cnt++;
|
||||
}
|
||||
|
||||
/*Make sure the last row is at the bottom of 'btnm'*/
|
||||
if(map_p_tmp[btn_cnt][0] == '\0') { /*Last row?*/
|
||||
if(map_p_tmp[btn_cnt][0] == '\0') { /*Last row?*/
|
||||
btn_h = max_h - act_y + style_bg->body.padding.bottom - 1;
|
||||
}
|
||||
|
||||
@ -221,33 +222,34 @@ void lv_btnm_set_map(const lv_obj_t * btnm, const char * map[])
|
||||
* act_unit_w = one_unit_w * button_width
|
||||
* do this two operations but the multiply first to divide a greater number */
|
||||
act_unit_w = (all_unit_w * get_button_width(ext->ctrl_bits[btn_i])) / unit_cnt;
|
||||
act_unit_w --; /*-1 because e.g. width = 100 means 101 pixels (0..100)*/
|
||||
act_unit_w--; /*-1 because e.g. width = 100 means 101 pixels (0..100)*/
|
||||
|
||||
/*Always recalculate act_x because of rounding errors */
|
||||
act_x = (unit_act_cnt * all_unit_w) / unit_cnt + i * style_bg->body.padding.inner + style_bg->body.padding.left;
|
||||
act_x = (unit_act_cnt * all_unit_w) / unit_cnt + i * style_bg->body.padding.inner +
|
||||
style_bg->body.padding.left;
|
||||
|
||||
/* Set the button's area.
|
||||
* If inner padding is zero then use the prev. button x2 as x1 to avoid rounding errors*/
|
||||
* If inner padding is zero then use the prev. button x2 as x1 to avoid rounding
|
||||
* errors*/
|
||||
if(style_bg->body.padding.inner == 0 && act_x != style_bg->body.padding.left) {
|
||||
lv_area_set(&ext->button_areas[btn_i], ext->button_areas[btn_i - 1].x2, act_y,
|
||||
lv_area_set(&ext->button_areas[btn_i], ext->button_areas[btn_i - 1].x2, act_y,
|
||||
act_x + act_unit_w, act_y + btn_h);
|
||||
} else {
|
||||
lv_area_set(&ext->button_areas[btn_i], act_x, act_y,
|
||||
act_x + act_unit_w, act_y + btn_h);
|
||||
lv_area_set(&ext->button_areas[btn_i], act_x, act_y, act_x + act_unit_w,
|
||||
act_y + btn_h);
|
||||
}
|
||||
|
||||
unit_act_cnt += get_button_width(ext->ctrl_bits[btn_i]);
|
||||
|
||||
i_tot ++;
|
||||
btn_i ++;
|
||||
i_tot++;
|
||||
btn_i++;
|
||||
}
|
||||
}
|
||||
act_y += btn_h + style_bg->body.padding.inner;
|
||||
|
||||
|
||||
if(strlen(map_p_tmp[btn_cnt]) == 0) break; /*Break on end of map*/
|
||||
map_p_tmp = &map_p_tmp[btn_cnt + 1]; /*Set the map to the next line*/
|
||||
i_tot ++; /*Skip the '\n'*/
|
||||
map_p_tmp = &map_p_tmp[btn_cnt + 1]; /*Set the map to the next line*/
|
||||
i_tot++; /*Skip the '\n'*/
|
||||
}
|
||||
|
||||
lv_obj_invalidate(btnm);
|
||||
@ -287,17 +289,14 @@ void lv_btnm_set_pressed(const lv_obj_t * btnm, uint16_t id)
|
||||
{
|
||||
lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm);
|
||||
|
||||
if (id >= ext->btn_cnt && id != LV_BTNM_BTN_NONE)
|
||||
return;
|
||||
if(id >= ext->btn_cnt && id != LV_BTNM_BTN_NONE) return;
|
||||
|
||||
if (id == ext->btn_id_pr)
|
||||
return;
|
||||
if(id == ext->btn_id_pr) return;
|
||||
|
||||
ext->btn_id_pr = id;
|
||||
lv_obj_invalidate(btnm);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set a style of a button matrix
|
||||
* @param btnm pointer to a button matrix object
|
||||
@ -309,9 +308,7 @@ void lv_btnm_set_style(lv_obj_t * btnm, lv_btnm_style_t type, lv_style_t * style
|
||||
lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm);
|
||||
|
||||
switch(type) {
|
||||
case LV_BTNM_STYLE_BG:
|
||||
lv_obj_set_style(btnm, style);
|
||||
break;
|
||||
case LV_BTNM_STYLE_BG: lv_obj_set_style(btnm, style); break;
|
||||
case LV_BTNM_STYLE_BTN_REL:
|
||||
ext->styles_btn[LV_BTN_STATE_REL] = style;
|
||||
lv_obj_invalidate(btnm);
|
||||
@ -366,7 +363,6 @@ void lv_btnm_set_btn_ctrl(const lv_obj_t * btnm, uint16_t btn_id, lv_btnm_ctrl_t
|
||||
}
|
||||
|
||||
invalidate_button_area(btnm, btn_id);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -379,7 +375,7 @@ void lv_btnm_set_btn_ctrl_all(lv_obj_t * btnm, lv_btnm_ctrl_t ctrl, bool en)
|
||||
{
|
||||
lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm);
|
||||
uint16_t i;
|
||||
for(i= 0; i < ext->btn_cnt; i++) {
|
||||
for(i = 0; i < ext->btn_cnt; i++) {
|
||||
lv_btnm_set_btn_ctrl(btnm, i, ctrl, en);
|
||||
}
|
||||
}
|
||||
@ -396,7 +392,7 @@ void lv_btnm_set_btn_width(const lv_obj_t * btnm, uint16_t btn_id, uint8_t width
|
||||
{
|
||||
|
||||
lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm);
|
||||
if (btn_id >= ext->btn_cnt) return;
|
||||
if(btn_id >= ext->btn_cnt) return;
|
||||
ext->ctrl_bits[btn_id] &= (~LV_BTNM_WIDTH_MASK);
|
||||
ext->ctrl_bits[btn_id] |= (LV_BTNM_WIDTH_MASK & width);
|
||||
|
||||
@ -408,12 +404,13 @@ void lv_btnm_set_btn_width(const lv_obj_t * btnm, uint16_t btn_id, uint8_t width
|
||||
* @param btnm Button matrix object
|
||||
* @param one_toggle Whether "one toggle" mode is enabled
|
||||
*/
|
||||
void lv_btnm_set_one_toggle(lv_obj_t *btnm, bool one_toggle) {
|
||||
lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm);
|
||||
ext->one_toggle = one_toggle;
|
||||
void lv_btnm_set_one_toggle(lv_obj_t * btnm, bool one_toggle)
|
||||
{
|
||||
lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm);
|
||||
ext->one_toggle = one_toggle;
|
||||
|
||||
/*If more than one button is toggled only the first one should be*/
|
||||
make_one_button_toggled(btnm, 0);
|
||||
/*If more than one button is toggled only the first one should be*/
|
||||
make_one_button_toggled(btnm, 0);
|
||||
}
|
||||
|
||||
/*=====================
|
||||
@ -471,7 +468,6 @@ const char * lv_btnm_get_active_btn_text(const lv_obj_t * btnm)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the pressed button's index.
|
||||
* The button be really pressed by the user or manually set to pressed with `lv_btnm_set_pressed`
|
||||
@ -487,34 +483,36 @@ uint16_t lv_btnm_get_pressed_btn(const lv_obj_t * btnm)
|
||||
/**
|
||||
* Get the button's text
|
||||
* @param btnm pointer to button matrix object
|
||||
* @param btn_id the index a button not counting new line characters. (The return value of lv_btnm_get_pressed/released)
|
||||
* @param btn_id the index a button not counting new line characters. (The return value of
|
||||
* lv_btnm_get_pressed/released)
|
||||
* @return text of btn_index` button
|
||||
*/
|
||||
const char * lv_btnm_get_btn_text(const lv_obj_t * btnm, uint16_t btn_id)
|
||||
{
|
||||
lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm);
|
||||
if(btn_id > ext->btn_cnt) return NULL;
|
||||
if(btn_id > ext->btn_cnt) return NULL;
|
||||
|
||||
uint16_t txt_i = 0;
|
||||
uint16_t btn_i = 0;
|
||||
uint16_t txt_i = 0;
|
||||
uint16_t btn_i = 0;
|
||||
|
||||
/* Search the text of ext->btn_pr the buttons text in the map
|
||||
* Skip "\n"-s*/
|
||||
while(btn_i != btn_id) {
|
||||
btn_i ++;
|
||||
txt_i ++;
|
||||
if(strcmp(ext->map_p[txt_i], "\n") == 0) txt_i ++;
|
||||
}
|
||||
/* Search the text of ext->btn_pr the buttons text in the map
|
||||
* Skip "\n"-s*/
|
||||
while(btn_i != btn_id) {
|
||||
btn_i++;
|
||||
txt_i++;
|
||||
if(strcmp(ext->map_p[txt_i], "\n") == 0) txt_i++;
|
||||
}
|
||||
|
||||
if(btn_i == ext->btn_cnt) return NULL;
|
||||
if(btn_i == ext->btn_cnt) return NULL;
|
||||
|
||||
return ext->map_p[txt_i];
|
||||
return ext->map_p[txt_i];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the whether a control value is enabled or disabled for button of a button matrix
|
||||
* @param btnm pointer to a button matrix object
|
||||
* @param btn_id the index a button not counting new line characters. (E.g. the return value of lv_btnm_get_pressed/released)
|
||||
* @param btn_id the index a button not counting new line characters. (E.g. the return value of
|
||||
* lv_btnm_get_pressed/released)
|
||||
* @param ctrl control values to check (ORed value can be used)
|
||||
* @return true: long press repeat is disabled; false: long press repeat enabled
|
||||
*/
|
||||
@ -534,31 +532,17 @@ bool lv_btnm_get_btn_ctrl(lv_obj_t * btnm, uint16_t btn_id, lv_btnm_ctrl_t ctrl)
|
||||
*/
|
||||
lv_style_t * lv_btnm_get_style(const lv_obj_t * btnm, lv_btnm_style_t type)
|
||||
{
|
||||
lv_style_t * style = NULL;
|
||||
lv_style_t * style = NULL;
|
||||
lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm);
|
||||
|
||||
switch(type) {
|
||||
case LV_BTNM_STYLE_BG:
|
||||
style = lv_obj_get_style(btnm);
|
||||
break;
|
||||
case LV_BTNM_STYLE_BTN_REL:
|
||||
style = ext->styles_btn[LV_BTN_STATE_REL];
|
||||
break;
|
||||
case LV_BTNM_STYLE_BTN_PR:
|
||||
style = ext->styles_btn[LV_BTN_STATE_PR];
|
||||
break;
|
||||
case LV_BTNM_STYLE_BTN_TGL_REL:
|
||||
style = ext->styles_btn[LV_BTN_STATE_TGL_REL];
|
||||
break;
|
||||
case LV_BTNM_STYLE_BTN_TGL_PR:
|
||||
style = ext->styles_btn[LV_BTN_STATE_TGL_PR];
|
||||
break;
|
||||
case LV_BTNM_STYLE_BTN_INA:
|
||||
style = ext->styles_btn[LV_BTN_STATE_INA];
|
||||
break;
|
||||
default:
|
||||
style = NULL;
|
||||
break;
|
||||
case LV_BTNM_STYLE_BG: style = lv_obj_get_style(btnm); break;
|
||||
case LV_BTNM_STYLE_BTN_REL: style = ext->styles_btn[LV_BTN_STATE_REL]; break;
|
||||
case LV_BTNM_STYLE_BTN_PR: style = ext->styles_btn[LV_BTN_STATE_PR]; break;
|
||||
case LV_BTNM_STYLE_BTN_TGL_REL: style = ext->styles_btn[LV_BTN_STATE_TGL_REL]; break;
|
||||
case LV_BTNM_STYLE_BTN_TGL_PR: style = ext->styles_btn[LV_BTN_STATE_TGL_PR]; break;
|
||||
case LV_BTNM_STYLE_BTN_INA: style = ext->styles_btn[LV_BTN_STATE_INA]; break;
|
||||
default: style = NULL; break;
|
||||
}
|
||||
|
||||
return style;
|
||||
@ -569,10 +553,11 @@ lv_style_t * lv_btnm_get_style(const lv_obj_t * btnm, lv_btnm_style_t type)
|
||||
* @param btnm Button matrix object
|
||||
* @return whether "one toggle" mode is enabled
|
||||
*/
|
||||
bool lv_btnm_get_one_toggle(const lv_obj_t *btnm) {
|
||||
lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm);
|
||||
bool lv_btnm_get_one_toggle(const lv_obj_t * btnm)
|
||||
{
|
||||
lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm);
|
||||
|
||||
return ext->one_toggle;
|
||||
return ext->one_toggle;
|
||||
}
|
||||
|
||||
/**********************
|
||||
@ -600,7 +585,7 @@ static bool lv_btnm_design(lv_obj_t * btnm, const lv_area_t * mask, lv_design_mo
|
||||
|
||||
ancestor_design_f(btnm, mask, mode);
|
||||
|
||||
lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm);
|
||||
lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm);
|
||||
lv_style_t * bg_style = lv_obj_get_style(btnm);
|
||||
lv_style_t * btn_style;
|
||||
lv_opa_t opa_scale = lv_obj_get_opa_scale(btnm);
|
||||
@ -619,10 +604,10 @@ static bool lv_btnm_design(lv_obj_t * btnm, const lv_area_t * mask, lv_design_mo
|
||||
|
||||
if(ext->recolor) txt_flag = LV_TXT_FLAG_RECOLOR;
|
||||
|
||||
for(btn_i = 0; btn_i < ext->btn_cnt; btn_i ++, txt_i ++) {
|
||||
for(btn_i = 0; btn_i < ext->btn_cnt; btn_i++, txt_i++) {
|
||||
/*Search the next valid text in the map*/
|
||||
while(strcmp(ext->map_p[txt_i], "\n") == 0) {
|
||||
txt_i ++;
|
||||
txt_i++;
|
||||
}
|
||||
|
||||
/*Skip hidden buttons*/
|
||||
@ -639,12 +624,19 @@ static bool lv_btnm_design(lv_obj_t * btnm, const lv_area_t * mask, lv_design_mo
|
||||
|
||||
/*Load the style*/
|
||||
bool tgl_state = button_get_tgl_state(ext->ctrl_bits[btn_i]);
|
||||
if(button_is_inactive(ext->ctrl_bits[btn_i])) btn_style = lv_btnm_get_style(btnm, LV_BTNM_STYLE_BTN_INA);
|
||||
else if(btn_i != ext->btn_id_pr && tgl_state == false) btn_style = lv_btnm_get_style(btnm, LV_BTNM_STYLE_BTN_REL);
|
||||
else if(btn_i == ext->btn_id_pr && tgl_state == false) btn_style = lv_btnm_get_style(btnm, LV_BTNM_STYLE_BTN_PR);
|
||||
else if(btn_i != ext->btn_id_pr && tgl_state == true) btn_style = lv_btnm_get_style(btnm, LV_BTNM_STYLE_BTN_TGL_REL);
|
||||
else if(btn_i == ext->btn_id_pr && tgl_state == true) btn_style = lv_btnm_get_style(btnm, LV_BTNM_STYLE_BTN_TGL_PR);
|
||||
else btn_style = lv_btnm_get_style(btnm, LV_BTNM_STYLE_BTN_REL); /*Not possible option, just to be sure*/
|
||||
if(button_is_inactive(ext->ctrl_bits[btn_i]))
|
||||
btn_style = lv_btnm_get_style(btnm, LV_BTNM_STYLE_BTN_INA);
|
||||
else if(btn_i != ext->btn_id_pr && tgl_state == false)
|
||||
btn_style = lv_btnm_get_style(btnm, LV_BTNM_STYLE_BTN_REL);
|
||||
else if(btn_i == ext->btn_id_pr && tgl_state == false)
|
||||
btn_style = lv_btnm_get_style(btnm, LV_BTNM_STYLE_BTN_PR);
|
||||
else if(btn_i != ext->btn_id_pr && tgl_state == true)
|
||||
btn_style = lv_btnm_get_style(btnm, LV_BTNM_STYLE_BTN_TGL_REL);
|
||||
else if(btn_i == ext->btn_id_pr && tgl_state == true)
|
||||
btn_style = lv_btnm_get_style(btnm, LV_BTNM_STYLE_BTN_TGL_PR);
|
||||
else
|
||||
btn_style = lv_btnm_get_style(
|
||||
btnm, LV_BTNM_STYLE_BTN_REL); /*Not possible option, just to be sure*/
|
||||
|
||||
lv_style_copy(&style_tmp, btn_style);
|
||||
|
||||
@ -659,13 +651,12 @@ static bool lv_btnm_design(lv_obj_t * btnm, const lv_area_t * mask, lv_design_mo
|
||||
|
||||
if(txt_i == 0) {
|
||||
style_tmp.body.border.part &= ~LV_BORDER_LEFT;
|
||||
}
|
||||
else if(strcmp(ext->map_p[txt_i - 1],"\n") == 0) {
|
||||
} else if(strcmp(ext->map_p[txt_i - 1], "\n") == 0) {
|
||||
style_tmp.body.border.part &= ~LV_BORDER_LEFT;
|
||||
}
|
||||
|
||||
if(ext->map_p[txt_i + 1][0] == '\0' || strcmp(ext->map_p[txt_i + 1], "\n") == 0) {
|
||||
style_tmp.body.border.part &= ~LV_BORDER_RIGHT;
|
||||
style_tmp.body.border.part &= ~LV_BORDER_RIGHT;
|
||||
}
|
||||
}
|
||||
lv_draw_rect(&area_tmp, mask, &style_tmp, opa_scale);
|
||||
@ -674,16 +665,16 @@ static bool lv_btnm_design(lv_obj_t * btnm, const lv_area_t * mask, lv_design_mo
|
||||
if(btn_style->glass) btn_style = bg_style;
|
||||
const lv_font_t * font = btn_style->text.font;
|
||||
lv_point_t txt_size;
|
||||
lv_txt_get_size(&txt_size, ext->map_p[txt_i], font,
|
||||
btn_style->text.letter_space, btn_style->text.line_space,
|
||||
lv_area_get_width(&area_btnm), txt_flag);
|
||||
lv_txt_get_size(&txt_size, ext->map_p[txt_i], font, btn_style->text.letter_space,
|
||||
btn_style->text.line_space, lv_area_get_width(&area_btnm), txt_flag);
|
||||
|
||||
area_tmp.x1 += (btn_w - txt_size.x) / 2;
|
||||
area_tmp.y1 += (btn_h - txt_size.y) / 2;
|
||||
area_tmp.x2 = area_tmp.x1 + txt_size.x;
|
||||
area_tmp.y2 = area_tmp.y1 + txt_size.y;
|
||||
|
||||
lv_draw_label(&area_tmp, mask, btn_style, opa_scale, ext->map_p[txt_i], txt_flag, NULL, -1, -1);
|
||||
lv_draw_label(&area_tmp, mask, btn_style, opa_scale, ext->map_p[txt_i], txt_flag, NULL,
|
||||
-1, -1);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
@ -711,38 +702,36 @@ static lv_res_t lv_btnm_signal(lv_obj_t * btnm, lv_signal_t sign, void * param)
|
||||
lv_mem_free(ext->ctrl_bits);
|
||||
} else if(sign == LV_SIGNAL_STYLE_CHG || sign == LV_SIGNAL_CORD_CHG) {
|
||||
lv_btnm_set_map(btnm, ext->map_p);
|
||||
}
|
||||
else if(sign == LV_SIGNAL_PRESSED) {
|
||||
} else if(sign == LV_SIGNAL_PRESSED) {
|
||||
lv_indev_t * indev = lv_indev_get_act();
|
||||
if(lv_indev_get_type(indev) == LV_INDEV_TYPE_POINTER || lv_indev_get_type(indev) == LV_INDEV_TYPE_BUTTON) {
|
||||
if(lv_indev_get_type(indev) == LV_INDEV_TYPE_POINTER ||
|
||||
lv_indev_get_type(indev) == LV_INDEV_TYPE_BUTTON) {
|
||||
uint16_t btn_pr;
|
||||
/*Search the pressed area*/
|
||||
lv_indev_get_point(param, &p);
|
||||
btn_pr = get_button_from_point(btnm, &p);
|
||||
|
||||
invalidate_button_area(btnm, ext->btn_id_pr) /*Invalidate the old area*/;
|
||||
ext->btn_id_pr = btn_pr;
|
||||
invalidate_button_area(btnm, ext->btn_id_pr) /*Invalidate the old area*/;
|
||||
ext->btn_id_pr = btn_pr;
|
||||
ext->btn_id_act = btn_pr;
|
||||
invalidate_button_area(btnm, ext->btn_id_pr); /*Invalidate the new area*/
|
||||
invalidate_button_area(btnm, ext->btn_id_pr); /*Invalidate the new area*/
|
||||
}
|
||||
if(ext->btn_id_act != LV_BTNM_BTN_NONE) {
|
||||
if(button_is_click_trig(ext->ctrl_bits[ext->btn_id_act]) == false &&
|
||||
button_is_inactive(ext->ctrl_bits[ext->btn_id_act]) == false &&
|
||||
button_is_hidden(ext->ctrl_bits[ext->btn_id_act]) == false)
|
||||
{
|
||||
button_is_inactive(ext->ctrl_bits[ext->btn_id_act]) == false &&
|
||||
button_is_hidden(ext->ctrl_bits[ext->btn_id_act]) == false) {
|
||||
uint32_t b = ext->btn_id_act;
|
||||
lv_event_send(btnm, LV_EVENT_SELECTED, &b);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(sign == LV_SIGNAL_PRESSING) {
|
||||
} else if(sign == LV_SIGNAL_PRESSING) {
|
||||
uint16_t btn_pr;
|
||||
/*Search the pressed area*/
|
||||
lv_indev_get_point(param, &p);
|
||||
btn_pr = get_button_from_point(btnm, &p);
|
||||
/*Invalidate to old and the new areas*/;
|
||||
if(btn_pr != ext->btn_id_pr) {
|
||||
lv_indev_reset_long_press(param); /*Start the log press time again on the new button*/
|
||||
lv_indev_reset_long_press(param); /*Start the log press time again on the new button*/
|
||||
if(ext->btn_id_pr != LV_BTNM_BTN_NONE) {
|
||||
invalidate_button_area(btnm, ext->btn_id_pr);
|
||||
}
|
||||
@ -753,10 +742,9 @@ static lv_res_t lv_btnm_signal(lv_obj_t * btnm, lv_signal_t sign, void * param)
|
||||
}
|
||||
}
|
||||
|
||||
ext->btn_id_pr = btn_pr;
|
||||
ext->btn_id_pr = btn_pr;
|
||||
ext->btn_id_act = btn_pr;
|
||||
}
|
||||
else if(sign == LV_SIGNAL_RELEASED) {
|
||||
} else if(sign == LV_SIGNAL_RELEASED) {
|
||||
if(ext->btn_id_pr != LV_BTNM_BTN_NONE) {
|
||||
/*Toggle the button if enabled*/
|
||||
if(button_is_tgl_enabled(ext->ctrl_bits[ext->btn_id_pr])) {
|
||||
@ -765,8 +753,7 @@ static lv_res_t lv_btnm_signal(lv_obj_t * btnm, lv_signal_t sign, void * param)
|
||||
} else {
|
||||
ext->ctrl_bits[ext->btn_id_pr] |= LV_BTNM_CTRL_TGL_STATE;
|
||||
}
|
||||
if(ext->one_toggle)
|
||||
make_one_button_toggled(btnm, ext->btn_id_pr);
|
||||
if(ext->one_toggle) make_one_button_toggled(btnm, ext->btn_id_pr);
|
||||
}
|
||||
|
||||
/*Invalidate to old pressed area*/;
|
||||
@ -783,34 +770,28 @@ static lv_res_t lv_btnm_signal(lv_obj_t * btnm, lv_signal_t sign, void * param)
|
||||
#endif
|
||||
|
||||
if(button_is_click_trig(ext->ctrl_bits[ext->btn_id_act]) == true &&
|
||||
button_is_inactive(ext->ctrl_bits[ext->btn_id_act]) == false &&
|
||||
button_is_hidden(ext->ctrl_bits[ext->btn_id_act]) == false)
|
||||
{
|
||||
button_is_inactive(ext->ctrl_bits[ext->btn_id_act]) == false &&
|
||||
button_is_hidden(ext->ctrl_bits[ext->btn_id_act]) == false) {
|
||||
uint32_t b = ext->btn_id_act;
|
||||
lv_event_send(btnm, LV_EVENT_SELECTED, &b);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
else if(sign == LV_SIGNAL_LONG_PRESS_REP) {
|
||||
} else if(sign == LV_SIGNAL_LONG_PRESS_REP) {
|
||||
if(ext->btn_id_act != LV_BTNM_BTN_NONE) {
|
||||
if(button_is_repeat_disabled(ext->ctrl_bits[ext->btn_id_act]) == false &&
|
||||
button_is_inactive(ext->ctrl_bits[ext->btn_id_act]) == false &&
|
||||
button_is_hidden(ext->ctrl_bits[ext->btn_id_act]) == false)
|
||||
{
|
||||
button_is_inactive(ext->ctrl_bits[ext->btn_id_act]) == false &&
|
||||
button_is_hidden(ext->ctrl_bits[ext->btn_id_act]) == false) {
|
||||
uint32_t b = ext->btn_id_act;
|
||||
lv_event_send(btnm, LV_EVENT_SELECTED, &b);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(sign == LV_SIGNAL_PRESS_LOST || sign == LV_SIGNAL_DEFOCUS) {
|
||||
ext->btn_id_pr = LV_BTNM_BTN_NONE;
|
||||
} else if(sign == LV_SIGNAL_PRESS_LOST || sign == LV_SIGNAL_DEFOCUS) {
|
||||
ext->btn_id_pr = LV_BTNM_BTN_NONE;
|
||||
ext->btn_id_act = LV_BTNM_BTN_NONE;
|
||||
lv_obj_invalidate(btnm);
|
||||
}
|
||||
else if(sign == LV_SIGNAL_FOCUS) {
|
||||
} else if(sign == LV_SIGNAL_FOCUS) {
|
||||
#if LV_USE_GROUP
|
||||
lv_indev_t * indev = lv_indev_get_act();
|
||||
lv_indev_t * indev = lv_indev_get_act();
|
||||
lv_indev_type_t indev_type = lv_indev_get_type(indev);
|
||||
if(indev_type == LV_INDEV_TYPE_POINTER) {
|
||||
/*Select the clicked button*/
|
||||
@ -819,10 +800,12 @@ static lv_res_t lv_btnm_signal(lv_obj_t * btnm, lv_signal_t sign, void * param)
|
||||
uint16_t btn_i = get_button_from_point(btnm, &p1);
|
||||
ext->btn_id_pr = btn_i;
|
||||
|
||||
} else if(indev_type == LV_INDEV_TYPE_ENCODER) {
|
||||
} else if(indev_type == LV_INDEV_TYPE_ENCODER) {
|
||||
/*In navigation mode don't select any button but in edit mode select the fist*/
|
||||
if(lv_group_get_editing(lv_obj_get_group(btnm))) ext->btn_id_pr = 0;
|
||||
else ext->btn_id_pr = LV_BTNM_BTN_NONE;
|
||||
if(lv_group_get_editing(lv_obj_get_group(btnm)))
|
||||
ext->btn_id_pr = 0;
|
||||
else
|
||||
ext->btn_id_pr = LV_BTNM_BTN_NONE;
|
||||
} else {
|
||||
ext->btn_id_pr = 0;
|
||||
}
|
||||
@ -832,35 +815,35 @@ static lv_res_t lv_btnm_signal(lv_obj_t * btnm, lv_signal_t sign, void * param)
|
||||
|
||||
ext->btn_id_act = ext->btn_id_pr;
|
||||
lv_obj_invalidate(btnm);
|
||||
}
|
||||
else if(sign == LV_SIGNAL_CONTROL) {
|
||||
} else if(sign == LV_SIGNAL_CONTROL) {
|
||||
char c = *((char *)param);
|
||||
if(c == LV_GROUP_KEY_RIGHT) {
|
||||
if(ext->btn_id_pr == LV_BTNM_BTN_NONE) ext->btn_id_pr = 0;
|
||||
else ext->btn_id_pr++;
|
||||
if(ext->btn_id_pr == LV_BTNM_BTN_NONE)
|
||||
ext->btn_id_pr = 0;
|
||||
else
|
||||
ext->btn_id_pr++;
|
||||
if(ext->btn_id_pr >= ext->btn_cnt - 1) ext->btn_id_pr = ext->btn_cnt - 1;
|
||||
ext->btn_id_act = ext->btn_id_pr;
|
||||
lv_obj_invalidate(btnm);
|
||||
}
|
||||
else if(c == LV_GROUP_KEY_LEFT) {
|
||||
if(ext->btn_id_pr == LV_BTNM_BTN_NONE) ext->btn_id_pr = 0;
|
||||
} else if(c == LV_GROUP_KEY_LEFT) {
|
||||
if(ext->btn_id_pr == LV_BTNM_BTN_NONE) ext->btn_id_pr = 0;
|
||||
if(ext->btn_id_pr > 0) ext->btn_id_pr--;
|
||||
ext->btn_id_act = ext->btn_id_pr;
|
||||
lv_obj_invalidate(btnm);
|
||||
}
|
||||
else if(c == LV_GROUP_KEY_DOWN) {
|
||||
} else if(c == LV_GROUP_KEY_DOWN) {
|
||||
lv_style_t * style = lv_btnm_get_style(btnm, LV_BTNM_STYLE_BG);
|
||||
/*Find the area below the the current*/
|
||||
if(ext->btn_id_pr == LV_BTNM_BTN_NONE) {
|
||||
if(ext->btn_id_pr == LV_BTNM_BTN_NONE) {
|
||||
ext->btn_id_pr = 0;
|
||||
} else {
|
||||
uint16_t area_below;
|
||||
lv_coord_t pr_center = ext->button_areas[ext->btn_id_pr].x1 + (lv_area_get_width(&ext->button_areas[ext->btn_id_pr]) >> 1);
|
||||
lv_coord_t pr_center = ext->button_areas[ext->btn_id_pr].x1 +
|
||||
(lv_area_get_width(&ext->button_areas[ext->btn_id_pr]) >> 1);
|
||||
|
||||
for(area_below = ext->btn_id_pr; area_below < ext->btn_cnt; area_below ++) {
|
||||
if(ext->button_areas[area_below].y1 > ext->button_areas[ext->btn_id_pr].y1 &&
|
||||
pr_center >= ext->button_areas[area_below].x1 &&
|
||||
pr_center <= ext->button_areas[area_below].x2 + style->body.padding.left) {
|
||||
for(area_below = ext->btn_id_pr; area_below < ext->btn_cnt; area_below++) {
|
||||
if(ext->button_areas[area_below].y1 > ext->button_areas[ext->btn_id_pr].y1 &&
|
||||
pr_center >= ext->button_areas[area_below].x1 &&
|
||||
pr_center <= ext->button_areas[area_below].x2 + style->body.padding.left) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -869,44 +852,40 @@ static lv_res_t lv_btnm_signal(lv_obj_t * btnm, lv_signal_t sign, void * param)
|
||||
}
|
||||
ext->btn_id_act = ext->btn_id_pr;
|
||||
lv_obj_invalidate(btnm);
|
||||
}
|
||||
else if(c == LV_GROUP_KEY_UP) {
|
||||
} else if(c == LV_GROUP_KEY_UP) {
|
||||
lv_style_t * style = lv_btnm_get_style(btnm, LV_BTNM_STYLE_BG);
|
||||
/*Find the area below the the current*/
|
||||
if(ext->btn_id_pr == LV_BTNM_BTN_NONE) {
|
||||
if(ext->btn_id_pr == LV_BTNM_BTN_NONE) {
|
||||
ext->btn_id_pr = 0;
|
||||
} else {
|
||||
int16_t area_above;
|
||||
lv_coord_t pr_center = ext->button_areas[ext->btn_id_pr].x1 + (lv_area_get_width(&ext->button_areas[ext->btn_id_pr]) >> 1);
|
||||
lv_coord_t pr_center = ext->button_areas[ext->btn_id_pr].x1 +
|
||||
(lv_area_get_width(&ext->button_areas[ext->btn_id_pr]) >> 1);
|
||||
|
||||
for(area_above = ext->btn_id_pr; area_above >= 0; area_above --) {
|
||||
for(area_above = ext->btn_id_pr; area_above >= 0; area_above--) {
|
||||
if(ext->button_areas[area_above].y1 < ext->button_areas[ext->btn_id_pr].y1 &&
|
||||
pr_center >= ext->button_areas[area_above].x1 - style->body.padding.left &&
|
||||
pr_center <= ext->button_areas[area_above].x2) {
|
||||
pr_center >= ext->button_areas[area_above].x1 - style->body.padding.left &&
|
||||
pr_center <= ext->button_areas[area_above].x2) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(area_above >= 0) ext->btn_id_pr = area_above;
|
||||
|
||||
}
|
||||
ext->btn_id_act = ext->btn_id_pr;
|
||||
lv_obj_invalidate(btnm);
|
||||
}
|
||||
}
|
||||
else if(sign == LV_SIGNAL_GET_EDITABLE) {
|
||||
} else if(sign == LV_SIGNAL_GET_EDITABLE) {
|
||||
bool * editable = (bool *)param;
|
||||
*editable = true;
|
||||
}
|
||||
else if(sign == LV_SIGNAL_GET_TYPE) {
|
||||
*editable = true;
|
||||
} else if(sign == LV_SIGNAL_GET_TYPE) {
|
||||
lv_obj_type_t * buf = param;
|
||||
uint8_t i;
|
||||
for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/
|
||||
for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/
|
||||
if(buf->type[i] == NULL) break;
|
||||
}
|
||||
buf->type[i] = "lv_btnm";
|
||||
}
|
||||
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -919,10 +898,10 @@ static void allocate_btn_areas_and_controls(const lv_obj_t * btnm, const char **
|
||||
{
|
||||
/*Count the buttons in the map*/
|
||||
uint16_t btn_cnt = 0;
|
||||
uint16_t i = 0;
|
||||
uint16_t i = 0;
|
||||
while(strlen(map[i]) != 0) {
|
||||
if(strcmp(map[i], "\n") != 0) { /*Do not count line breaks*/
|
||||
btn_cnt ++;
|
||||
btn_cnt++;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
@ -957,7 +936,7 @@ static void allocate_btn_areas_and_controls(const lv_obj_t * btnm, const char **
|
||||
static uint8_t get_button_width(lv_btnm_ctrl_t ctrl_bits)
|
||||
{
|
||||
uint8_t w = ctrl_bits & LV_BTNM_WIDTH_MASK;
|
||||
return w != 0 ? w: 1;
|
||||
return w != 0 ? w : 1;
|
||||
}
|
||||
|
||||
static bool button_is_hidden(lv_btnm_ctrl_t ctrl_bits)
|
||||
@ -1048,15 +1027,12 @@ static void invalidate_button_area(const lv_obj_t * btnm, uint16_t btn_idx)
|
||||
*/
|
||||
static bool maps_are_identical(const char ** map1, const char ** map2)
|
||||
{
|
||||
if (map1 == map2)
|
||||
return true;
|
||||
if (map1 == NULL || map2 == NULL)
|
||||
return map1 == map2;
|
||||
if(map1 == map2) return true;
|
||||
if(map1 == NULL || map2 == NULL) return map1 == map2;
|
||||
|
||||
uint16_t i = 0;
|
||||
while (map1[i][0] != '\0' && map2[i][0] != '\0') {
|
||||
if (strcmp(map1[i], map2[i]) !=0 )
|
||||
return false;
|
||||
while(map1[i][0] != '\0' && map2[i][0] != '\0') {
|
||||
if(strcmp(map1[i], map2[i]) != 0) return false;
|
||||
i++;
|
||||
}
|
||||
return map1[i][0] == '\0' && map2[i][0] == '\0';
|
||||
@ -1068,15 +1044,14 @@ static bool maps_are_identical(const char ** map1, const char ** map2)
|
||||
* @param btnm Button matrix object
|
||||
* @param btn_idx Button that should remain toggled
|
||||
*/
|
||||
static void make_one_button_toggled(lv_obj_t *btnm, uint16_t btn_idx)
|
||||
static void make_one_button_toggled(lv_obj_t * btnm, uint16_t btn_idx)
|
||||
{
|
||||
/*Save whether the button was toggled*/
|
||||
bool was_toggled = lv_btnm_get_btn_ctrl(btnm, btn_idx, LV_BTNM_CTRL_TGL_STATE);
|
||||
/*Save whether the button was toggled*/
|
||||
bool was_toggled = lv_btnm_get_btn_ctrl(btnm, btn_idx, LV_BTNM_CTRL_TGL_STATE);
|
||||
|
||||
lv_btnm_set_btn_ctrl_all(btnm, LV_BTNM_CTRL_TGL_STATE, false);
|
||||
lv_btnm_set_btn_ctrl_all(btnm, LV_BTNM_CTRL_TGL_STATE, false);
|
||||
|
||||
if(was_toggled)
|
||||
lv_btnm_set_btn_ctrl(btnm, btn_idx, LV_BTNM_CTRL_TGL_STATE, true);
|
||||
if(was_toggled) lv_btnm_set_btn_ctrl(btnm, btn_idx, LV_BTNM_CTRL_TGL_STATE, true);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -3,7 +3,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef LV_BTNM_H
|
||||
#define LV_BTNM_H
|
||||
|
||||
@ -29,8 +28,8 @@ extern "C" {
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define LV_BTNM_WIDTH_MASK 0x0007
|
||||
#define LV_BTNM_BTN_NONE 0xFFFF
|
||||
#define LV_BTNM_WIDTH_MASK 0x0007
|
||||
#define LV_BTNM_BTN_NONE 0xFFFF
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
@ -38,12 +37,12 @@ extern "C" {
|
||||
|
||||
/* Type to store button control bits (disabled, hidden etc.) */
|
||||
enum {
|
||||
LV_BTNM_CTRL_HIDDEN = 0x0008,
|
||||
LV_BTNM_CTRL_NO_REPEAT = 0x0010,
|
||||
LV_BTNM_CTRL_INACTIVE = 0x0020,
|
||||
LV_BTNM_CTRL_TGL_ENABLE = 0x0040,
|
||||
LV_BTNM_CTRL_TGL_STATE = 0x0080,
|
||||
LV_BTNM_CTRL_CLICK_TRIG = 0x0100,
|
||||
LV_BTNM_CTRL_HIDDEN = 0x0008,
|
||||
LV_BTNM_CTRL_NO_REPEAT = 0x0010,
|
||||
LV_BTNM_CTRL_INACTIVE = 0x0020,
|
||||
LV_BTNM_CTRL_TGL_ENABLE = 0x0040,
|
||||
LV_BTNM_CTRL_TGL_STATE = 0x0080,
|
||||
LV_BTNM_CTRL_CLICK_TRIG = 0x0100,
|
||||
};
|
||||
typedef uint16_t lv_btnm_ctrl_t;
|
||||
|
||||
@ -52,15 +51,16 @@ typedef struct
|
||||
{
|
||||
/*No inherited ext.*/ /*Ext. of ancestor*/
|
||||
/*New data for this type */
|
||||
const char ** map_p; /*Pointer to the current map*/
|
||||
lv_area_t *button_areas; /*Array of areas of buttons*/
|
||||
lv_btnm_ctrl_t *ctrl_bits; /*Array of control bytes*/
|
||||
lv_style_t *styles_btn[LV_BTN_STATE_NUM]; /*Styles of buttons in each state*/
|
||||
uint16_t btn_cnt; /*Number of button in 'map_p'(Handled by the library)*/
|
||||
uint16_t btn_id_pr; /*Index of the currently pressed button or LV_BTNM_BTN_NONE*/
|
||||
uint16_t btn_id_act; /*Index of the active button (being pressed/released etc) or LV_BTNM_BTN_NONE */
|
||||
uint8_t recolor :1; /*Enable button recoloring*/
|
||||
uint8_t one_toggle :1; /*Single button toggled at once*/
|
||||
const char ** map_p; /*Pointer to the current map*/
|
||||
lv_area_t * button_areas; /*Array of areas of buttons*/
|
||||
lv_btnm_ctrl_t * ctrl_bits; /*Array of control bytes*/
|
||||
lv_style_t * styles_btn[LV_BTN_STATE_NUM]; /*Styles of buttons in each state*/
|
||||
uint16_t btn_cnt; /*Number of button in 'map_p'(Handled by the library)*/
|
||||
uint16_t btn_id_pr; /*Index of the currently pressed button or LV_BTNM_BTN_NONE*/
|
||||
uint16_t
|
||||
btn_id_act; /*Index of the active button (being pressed/released etc) or LV_BTNM_BTN_NONE */
|
||||
uint8_t recolor : 1; /*Enable button recoloring*/
|
||||
uint8_t one_toggle : 1; /*Single button toggled at once*/
|
||||
} lv_btnm_ext_t;
|
||||
|
||||
enum {
|
||||
@ -80,7 +80,8 @@ typedef uint8_t lv_btnm_style_t;
|
||||
/**
|
||||
* Create a button matrix objects
|
||||
* @param par pointer to an object, it will be the parent of the new button matrix
|
||||
* @param copy pointer to a button matrix object, if not NULL then the new object will be copied from it
|
||||
* @param copy pointer to a button matrix object, if not NULL then the new object will be copied
|
||||
* from it
|
||||
* @return pointer to the created button matrix
|
||||
*/
|
||||
lv_obj_t * lv_btnm_create(lv_obj_t * par, const lv_obj_t * copy);
|
||||
@ -172,7 +173,7 @@ void lv_btnm_set_btn_width(const lv_obj_t * btnm, uint16_t btn_id, uint8_t width
|
||||
* @param btnm Button matrix object
|
||||
* @param one_toggle Whether "one toggle" mode is enabled
|
||||
*/
|
||||
void lv_btnm_set_one_toggle(lv_obj_t *btnm, bool one_toggle);
|
||||
void lv_btnm_set_one_toggle(lv_obj_t * btnm, bool one_toggle);
|
||||
|
||||
/*=====================
|
||||
* Getter functions
|
||||
@ -219,7 +220,8 @@ uint16_t lv_btnm_get_pressed_btn(const lv_obj_t * btnm);
|
||||
/**
|
||||
* Get the button's text
|
||||
* @param btnm pointer to button matrix object
|
||||
* @param btn_id the index a button not counting new line characters. (The return value of lv_btnm_get_pressed/released)
|
||||
* @param btn_id the index a button not counting new line characters. (The return value of
|
||||
* lv_btnm_get_pressed/released)
|
||||
* @return text of btn_index` button
|
||||
*/
|
||||
const char * lv_btnm_get_btn_text(const lv_obj_t * btnm, uint16_t btn_id);
|
||||
@ -227,7 +229,8 @@ const char * lv_btnm_get_btn_text(const lv_obj_t * btnm, uint16_t btn_id);
|
||||
/**
|
||||
* Get the whether a control value is enabled or disabled for button of a button matrix
|
||||
* @param btnm pointer to a button matrix object
|
||||
* @param btn_id the index a button not counting new line characters. (E.g. the return value of lv_btnm_get_pressed/released)
|
||||
* @param btn_id the index a button not counting new line characters. (E.g. the return value of
|
||||
* lv_btnm_get_pressed/released)
|
||||
* @param ctrl control values to check (ORed value can be used)
|
||||
* @return true: long press repeat is disabled; false: long press repeat enabled
|
||||
*/
|
||||
@ -246,7 +249,7 @@ lv_style_t * lv_btnm_get_style(const lv_obj_t * btnm, lv_btnm_style_t type);
|
||||
* @param btnm Button matrix object
|
||||
* @return whether "one toggle" mode is enabled
|
||||
*/
|
||||
bool lv_btnm_get_one_toggle(const lv_obj_t *btnm);
|
||||
bool lv_btnm_get_one_toggle(const lv_obj_t * btnm);
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
@ -48,17 +48,15 @@ static const char * get_month_name(lv_obj_t * calendar, int32_t month);
|
||||
static uint8_t get_month_length(int32_t year, int32_t month);
|
||||
static uint8_t is_leap_year(uint32_t year);
|
||||
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
static lv_signal_cb_t ancestor_signal;
|
||||
static lv_design_cb_t ancestor_design;
|
||||
static const char * day_name[7] = {"Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"};
|
||||
static const char * month_name[12] = {"January", "February", "March", "April",
|
||||
"May", "June", "July", "August",
|
||||
"September", "October", "November", "December"
|
||||
};
|
||||
static const char * day_name[7] = {"Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"};
|
||||
static const char * month_name[12] = {"January", "February", "March", "April",
|
||||
"May", "June", "July", "August",
|
||||
"September", "October", "November", "December"};
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
@ -91,29 +89,29 @@ lv_obj_t * lv_calendar_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
if(ancestor_design == NULL) ancestor_design = lv_obj_get_design_func(new_calendar);
|
||||
|
||||
/*Initialize the allocated 'ext' */
|
||||
ext->today.year = 2018;
|
||||
ext->today.year = 2018;
|
||||
ext->today.month = 1;
|
||||
ext->today.day = 1;
|
||||
ext->today.day = 1;
|
||||
|
||||
ext->showed_date.year = 2018;
|
||||
ext->showed_date.year = 2018;
|
||||
ext->showed_date.month = 1;
|
||||
ext->showed_date.day = 1;
|
||||
ext->showed_date.day = 1;
|
||||
|
||||
ext->pressed_date.year = 0;
|
||||
ext->pressed_date.year = 0;
|
||||
ext->pressed_date.month = 0;
|
||||
ext->pressed_date.day = 0;
|
||||
ext->pressed_date.day = 0;
|
||||
|
||||
ext->highlighted_dates = NULL;
|
||||
ext->highlighted_dates_num = 0;
|
||||
ext->day_names = NULL;
|
||||
ext->month_names = NULL;
|
||||
ext->style_header = &lv_style_plain_color;
|
||||
ext->style_header_pr = &lv_style_pretty_color;
|
||||
ext->highlighted_dates = NULL;
|
||||
ext->highlighted_dates_num = 0;
|
||||
ext->day_names = NULL;
|
||||
ext->month_names = NULL;
|
||||
ext->style_header = &lv_style_plain_color;
|
||||
ext->style_header_pr = &lv_style_pretty_color;
|
||||
ext->style_highlighted_days = &lv_style_plain_color;
|
||||
ext->style_inactive_days = &lv_style_btn_ina;
|
||||
ext->style_week_box = &lv_style_plain_color;
|
||||
ext->style_today_box = &lv_style_pretty_color;
|
||||
ext->style_day_names = &lv_style_pretty;
|
||||
ext->style_inactive_days = &lv_style_btn_ina;
|
||||
ext->style_week_box = &lv_style_plain_color;
|
||||
ext->style_today_box = &lv_style_pretty_color;
|
||||
ext->style_day_names = &lv_style_pretty;
|
||||
|
||||
/*The signal and design functions are not copied so set them here*/
|
||||
lv_obj_set_signal_cb(new_calendar, lv_calendar_signal);
|
||||
@ -127,13 +125,20 @@ lv_obj_t * lv_calendar_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
lv_theme_t * th = lv_theme_get_current();
|
||||
if(th) {
|
||||
lv_calendar_set_style(new_calendar, LV_CALENDAR_STYLE_BG, th->style.calendar.bg);
|
||||
lv_calendar_set_style(new_calendar, LV_CALENDAR_STYLE_HEADER, th->style.calendar.header);
|
||||
lv_calendar_set_style(new_calendar, LV_CALENDAR_STYLE_HEADER_PR, th->style.calendar.header_pr);
|
||||
lv_calendar_set_style(new_calendar, LV_CALENDAR_STYLE_DAY_NAMES, th->style.calendar.day_names);
|
||||
lv_calendar_set_style(new_calendar, LV_CALENDAR_STYLE_WEEK_BOX, th->style.calendar.week_box);
|
||||
lv_calendar_set_style(new_calendar, LV_CALENDAR_STYLE_TODAY_BOX, th->style.calendar.today_box);
|
||||
lv_calendar_set_style(new_calendar, LV_CALENDAR_STYLE_HIGHLIGHTED_DAYS, th->style.calendar.highlighted_days);
|
||||
lv_calendar_set_style(new_calendar, LV_CALENDAR_STYLE_INACTIVE_DAYS, th->style.calendar.inactive_days);
|
||||
lv_calendar_set_style(new_calendar, LV_CALENDAR_STYLE_HEADER,
|
||||
th->style.calendar.header);
|
||||
lv_calendar_set_style(new_calendar, LV_CALENDAR_STYLE_HEADER_PR,
|
||||
th->style.calendar.header_pr);
|
||||
lv_calendar_set_style(new_calendar, LV_CALENDAR_STYLE_DAY_NAMES,
|
||||
th->style.calendar.day_names);
|
||||
lv_calendar_set_style(new_calendar, LV_CALENDAR_STYLE_WEEK_BOX,
|
||||
th->style.calendar.week_box);
|
||||
lv_calendar_set_style(new_calendar, LV_CALENDAR_STYLE_TODAY_BOX,
|
||||
th->style.calendar.today_box);
|
||||
lv_calendar_set_style(new_calendar, LV_CALENDAR_STYLE_HIGHLIGHTED_DAYS,
|
||||
th->style.calendar.highlighted_days);
|
||||
lv_calendar_set_style(new_calendar, LV_CALENDAR_STYLE_INACTIVE_DAYS,
|
||||
th->style.calendar.inactive_days);
|
||||
} else {
|
||||
lv_calendar_set_style(new_calendar, LV_CALENDAR_STYLE_BG, &lv_style_pretty);
|
||||
lv_calendar_set_style(new_calendar, LV_CALENDAR_STYLE_HEADER, ext->style_header);
|
||||
@ -141,33 +146,35 @@ lv_obj_t * lv_calendar_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
lv_calendar_set_style(new_calendar, LV_CALENDAR_STYLE_DAY_NAMES, ext->style_day_names);
|
||||
lv_calendar_set_style(new_calendar, LV_CALENDAR_STYLE_WEEK_BOX, ext->style_week_box);
|
||||
lv_calendar_set_style(new_calendar, LV_CALENDAR_STYLE_TODAY_BOX, ext->style_today_box);
|
||||
lv_calendar_set_style(new_calendar, LV_CALENDAR_STYLE_HIGHLIGHTED_DAYS, ext->style_highlighted_days);
|
||||
lv_calendar_set_style(new_calendar, LV_CALENDAR_STYLE_INACTIVE_DAYS, ext->style_inactive_days);
|
||||
lv_calendar_set_style(new_calendar, LV_CALENDAR_STYLE_HIGHLIGHTED_DAYS,
|
||||
ext->style_highlighted_days);
|
||||
lv_calendar_set_style(new_calendar, LV_CALENDAR_STYLE_INACTIVE_DAYS,
|
||||
ext->style_inactive_days);
|
||||
}
|
||||
}
|
||||
/*Copy an existing calendar*/
|
||||
else {
|
||||
lv_calendar_ext_t * copy_ext = lv_obj_get_ext_attr(copy);
|
||||
ext->today.year = copy_ext->today.year;
|
||||
ext->today.month = copy_ext->today.month;
|
||||
ext->today.day = copy_ext->today.day;
|
||||
ext->today.year = copy_ext->today.year;
|
||||
ext->today.month = copy_ext->today.month;
|
||||
ext->today.day = copy_ext->today.day;
|
||||
|
||||
ext->showed_date.year = copy_ext->showed_date.year;
|
||||
ext->showed_date.year = copy_ext->showed_date.year;
|
||||
ext->showed_date.month = copy_ext->showed_date.month;
|
||||
ext->showed_date.day = copy_ext->showed_date.day;
|
||||
ext->showed_date.day = copy_ext->showed_date.day;
|
||||
|
||||
ext->highlighted_dates = copy_ext->highlighted_dates;
|
||||
ext->highlighted_dates = copy_ext->highlighted_dates;
|
||||
ext->highlighted_dates_num = copy_ext->highlighted_dates_num;
|
||||
ext->day_names = copy_ext->day_names;
|
||||
ext->day_names = copy_ext->day_names;
|
||||
|
||||
ext->month_names = copy_ext->month_names;
|
||||
ext->style_header = copy_ext->style_header;
|
||||
ext->style_header_pr = copy_ext->style_header_pr;
|
||||
ext->month_names = copy_ext->month_names;
|
||||
ext->style_header = copy_ext->style_header;
|
||||
ext->style_header_pr = copy_ext->style_header_pr;
|
||||
ext->style_highlighted_days = copy_ext->style_highlighted_days;
|
||||
ext->style_inactive_days = copy_ext->style_inactive_days;
|
||||
ext->style_week_box = copy_ext->style_week_box;
|
||||
ext->style_today_box = copy_ext->style_today_box;
|
||||
ext->style_day_names = copy_ext->style_day_names;
|
||||
ext->style_inactive_days = copy_ext->style_inactive_days;
|
||||
ext->style_week_box = copy_ext->style_week_box;
|
||||
ext->style_today_box = copy_ext->style_today_box;
|
||||
ext->style_day_names = copy_ext->style_day_names;
|
||||
/*Refresh the style with new signal function*/
|
||||
lv_obj_refresh_style(new_calendar);
|
||||
}
|
||||
@ -185,7 +192,6 @@ lv_obj_t * lv_calendar_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
* New object specific "add" or "remove" functions come here
|
||||
*/
|
||||
|
||||
|
||||
/*=====================
|
||||
* Setter functions
|
||||
*====================*/
|
||||
@ -193,14 +199,15 @@ lv_obj_t * lv_calendar_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
/**
|
||||
* Set the today's date
|
||||
* @param calendar pointer to a calendar object
|
||||
* @param today pointer to an `lv_calendar_date_t` variable containing the date of today. The value will be saved it can be local variable too.
|
||||
* @param today pointer to an `lv_calendar_date_t` variable containing the date of today. The value
|
||||
* will be saved it can be local variable too.
|
||||
*/
|
||||
void lv_calendar_set_today_date(lv_obj_t * calendar, lv_calendar_date_t * today)
|
||||
{
|
||||
lv_calendar_ext_t * ext = lv_obj_get_ext_attr(calendar);
|
||||
ext->today.year = today->year;
|
||||
ext->today.month = today->month;
|
||||
ext->today.day = today->day;
|
||||
ext->today.year = today->year;
|
||||
ext->today.month = today->month;
|
||||
ext->today.day = today->day;
|
||||
|
||||
lv_obj_invalidate(calendar);
|
||||
}
|
||||
@ -208,14 +215,15 @@ void lv_calendar_set_today_date(lv_obj_t * calendar, lv_calendar_date_t * today)
|
||||
/**
|
||||
* Set the currently showed
|
||||
* @param calendar pointer to a calendar object
|
||||
* @param showed pointer to an `lv_calendar_date_t` variable containing the date to show. The value will be saved it can be local variable too.
|
||||
* @param showed pointer to an `lv_calendar_date_t` variable containing the date to show. The value
|
||||
* will be saved it can be local variable too.
|
||||
*/
|
||||
void lv_calendar_set_showed_date(lv_obj_t * calendar, lv_calendar_date_t * showed)
|
||||
{
|
||||
lv_calendar_ext_t * ext = lv_obj_get_ext_attr(calendar);
|
||||
ext->showed_date.year = showed->year;
|
||||
ext->showed_date.month = showed->month;
|
||||
ext->showed_date.day = showed->day;
|
||||
ext->showed_date.year = showed->year;
|
||||
ext->showed_date.month = showed->month;
|
||||
ext->showed_date.day = showed->day;
|
||||
|
||||
lv_obj_invalidate(calendar);
|
||||
}
|
||||
@ -223,42 +231,45 @@ void lv_calendar_set_showed_date(lv_obj_t * calendar, lv_calendar_date_t * showe
|
||||
/**
|
||||
* Set the the highlighted dates
|
||||
* @param calendar pointer to a calendar object
|
||||
* @param highlighted pointer to an `lv_calendar_date_t` array containing the dates. ONLY A POINTER WILL BE SAVED! CAN'T BE LOCAL ARRAY.
|
||||
* @param highlighted pointer to an `lv_calendar_date_t` array containing the dates. ONLY A POINTER
|
||||
* WILL BE SAVED! CAN'T BE LOCAL ARRAY.
|
||||
* @param date_num number of dates in the array
|
||||
*/
|
||||
void lv_calendar_set_highlighted_dates(lv_obj_t * calendar, lv_calendar_date_t * highlighted, uint16_t date_num)
|
||||
void lv_calendar_set_highlighted_dates(lv_obj_t * calendar, lv_calendar_date_t * highlighted,
|
||||
uint16_t date_num)
|
||||
{
|
||||
lv_calendar_ext_t * ext = lv_obj_get_ext_attr(calendar);
|
||||
ext->highlighted_dates = highlighted;
|
||||
lv_calendar_ext_t * ext = lv_obj_get_ext_attr(calendar);
|
||||
ext->highlighted_dates = highlighted;
|
||||
ext->highlighted_dates_num = date_num;
|
||||
|
||||
lv_obj_invalidate(calendar);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the name of the days
|
||||
* @param calendar pointer to a calendar object
|
||||
* @param day_names pointer to an array with the names. E.g. `const char * days[7] = {"Sun", "Mon", ...}`
|
||||
* Only the pointer will be saved so this variable can't be local which will be destroyed later.
|
||||
* @param day_names pointer to an array with the names. E.g. `const char * days[7] = {"Sun", "Mon",
|
||||
* ...}` Only the pointer will be saved so this variable can't be local which will be destroyed
|
||||
* later.
|
||||
*/
|
||||
void lv_calendar_set_day_names(lv_obj_t * calendar, const char ** day_names)
|
||||
{
|
||||
lv_calendar_ext_t * ext = lv_obj_get_ext_attr(calendar);
|
||||
ext->day_names = day_names;
|
||||
ext->day_names = day_names;
|
||||
lv_obj_invalidate(calendar);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the name of the month
|
||||
* @param calendar pointer to a calendar object
|
||||
* @param day_names pointer to an array with the names. E.g. `const char * days[12] = {"Jan", "Feb", ...}`
|
||||
* Only the pointer will be saved so this variable can't be local which will be destroyed later.
|
||||
* @param day_names pointer to an array with the names. E.g. `const char * days[12] = {"Jan", "Feb",
|
||||
* ...}` Only the pointer will be saved so this variable can't be local which will be destroyed
|
||||
* later.
|
||||
*/
|
||||
void lv_calendar_set_month_names(lv_obj_t * calendar, const char ** day_names)
|
||||
{
|
||||
lv_calendar_ext_t * ext = lv_obj_get_ext_attr(calendar);
|
||||
ext->month_names = day_names;
|
||||
ext->month_names = day_names;
|
||||
lv_obj_invalidate(calendar);
|
||||
}
|
||||
|
||||
@ -273,30 +284,14 @@ void lv_calendar_set_style(lv_obj_t * calendar, lv_calendar_style_t type, lv_sty
|
||||
lv_calendar_ext_t * ext = lv_obj_get_ext_attr(calendar);
|
||||
|
||||
switch(type) {
|
||||
case LV_CALENDAR_STYLE_BG:
|
||||
lv_obj_set_style(calendar, style);
|
||||
break;
|
||||
case LV_CALENDAR_STYLE_DAY_NAMES:
|
||||
ext->style_day_names = style;
|
||||
break;
|
||||
case LV_CALENDAR_STYLE_HEADER:
|
||||
ext->style_header = style;
|
||||
break;
|
||||
case LV_CALENDAR_STYLE_HEADER_PR:
|
||||
ext->style_header_pr = style;
|
||||
break;
|
||||
case LV_CALENDAR_STYLE_HIGHLIGHTED_DAYS:
|
||||
ext->style_highlighted_days = style;
|
||||
break;
|
||||
case LV_CALENDAR_STYLE_INACTIVE_DAYS:
|
||||
ext->style_inactive_days = style;
|
||||
break;
|
||||
case LV_CALENDAR_STYLE_TODAY_BOX:
|
||||
ext->style_today_box = style;
|
||||
break;
|
||||
case LV_CALENDAR_STYLE_WEEK_BOX:
|
||||
ext->style_week_box = style;
|
||||
break;
|
||||
case LV_CALENDAR_STYLE_BG: lv_obj_set_style(calendar, style); break;
|
||||
case LV_CALENDAR_STYLE_DAY_NAMES: ext->style_day_names = style; break;
|
||||
case LV_CALENDAR_STYLE_HEADER: ext->style_header = style; break;
|
||||
case LV_CALENDAR_STYLE_HEADER_PR: ext->style_header_pr = style; break;
|
||||
case LV_CALENDAR_STYLE_HIGHLIGHTED_DAYS: ext->style_highlighted_days = style; break;
|
||||
case LV_CALENDAR_STYLE_INACTIVE_DAYS: ext->style_inactive_days = style; break;
|
||||
case LV_CALENDAR_STYLE_TODAY_BOX: ext->style_today_box = style; break;
|
||||
case LV_CALENDAR_STYLE_WEEK_BOX: ext->style_week_box = style; break;
|
||||
}
|
||||
|
||||
lv_obj_invalidate(calendar);
|
||||
@ -391,37 +386,19 @@ const char ** lv_calendar_get_month_names(const lv_obj_t * calendar)
|
||||
* */
|
||||
lv_style_t * lv_calendar_get_style(const lv_obj_t * calendar, lv_calendar_style_t type)
|
||||
{
|
||||
lv_style_t * style = NULL;
|
||||
lv_style_t * style = NULL;
|
||||
lv_calendar_ext_t * ext = lv_obj_get_ext_attr(calendar);
|
||||
|
||||
switch(type) {
|
||||
case LV_CALENDAR_STYLE_BG:
|
||||
style = lv_obj_get_style(calendar);
|
||||
break;
|
||||
case LV_CALENDAR_STYLE_HEADER:
|
||||
style = ext->style_header;
|
||||
break;
|
||||
case LV_CALENDAR_STYLE_HEADER_PR:
|
||||
style = ext->style_header_pr;
|
||||
break;
|
||||
case LV_CALENDAR_STYLE_DAY_NAMES:
|
||||
style = ext->style_day_names;
|
||||
break;
|
||||
case LV_CALENDAR_STYLE_HIGHLIGHTED_DAYS:
|
||||
style = ext->style_highlighted_days;
|
||||
break;
|
||||
case LV_CALENDAR_STYLE_INACTIVE_DAYS:
|
||||
style = ext->style_inactive_days;
|
||||
break;
|
||||
case LV_CALENDAR_STYLE_WEEK_BOX:
|
||||
style = ext->style_week_box;
|
||||
break;
|
||||
case LV_CALENDAR_STYLE_TODAY_BOX:
|
||||
style = ext->style_today_box;
|
||||
break;
|
||||
default:
|
||||
style = NULL;
|
||||
break;
|
||||
case LV_CALENDAR_STYLE_BG: style = lv_obj_get_style(calendar); break;
|
||||
case LV_CALENDAR_STYLE_HEADER: style = ext->style_header; break;
|
||||
case LV_CALENDAR_STYLE_HEADER_PR: style = ext->style_header_pr; break;
|
||||
case LV_CALENDAR_STYLE_DAY_NAMES: style = ext->style_day_names; break;
|
||||
case LV_CALENDAR_STYLE_HIGHLIGHTED_DAYS: style = ext->style_highlighted_days; break;
|
||||
case LV_CALENDAR_STYLE_INACTIVE_DAYS: style = ext->style_inactive_days; break;
|
||||
case LV_CALENDAR_STYLE_WEEK_BOX: style = ext->style_week_box; break;
|
||||
case LV_CALENDAR_STYLE_TODAY_BOX: style = ext->style_today_box; break;
|
||||
default: style = NULL; break;
|
||||
}
|
||||
|
||||
return style;
|
||||
@ -458,7 +435,8 @@ static bool lv_calendar_design(lv_obj_t * calendar, const lv_area_t * mask, lv_d
|
||||
/*Draw the object*/
|
||||
else if(mode == LV_DESIGN_DRAW_MAIN) {
|
||||
lv_opa_t opa_scale = lv_obj_get_opa_scale(calendar);
|
||||
lv_draw_rect(&calendar->coords, mask, lv_calendar_get_style(calendar, LV_CALENDAR_STYLE_BG), opa_scale);
|
||||
lv_draw_rect(&calendar->coords, mask, lv_calendar_get_style(calendar, LV_CALENDAR_STYLE_BG),
|
||||
opa_scale);
|
||||
|
||||
draw_header(calendar, mask);
|
||||
draw_day_names(calendar, mask);
|
||||
@ -467,7 +445,6 @@ static bool lv_calendar_design(lv_obj_t * calendar, const lv_area_t * mask, lv_d
|
||||
}
|
||||
/*Post draw when the children are drawn*/
|
||||
else if(mode == LV_DESIGN_DRAW_POST) {
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -488,7 +465,6 @@ static lv_res_t lv_calendar_signal(lv_obj_t * calendar, lv_signal_t sign, void *
|
||||
res = ancestor_signal(calendar, sign, param);
|
||||
if(res != LV_RES_OK) return res;
|
||||
|
||||
|
||||
if(sign == LV_SIGNAL_CLEANUP) {
|
||||
/*Nothing to cleanup. (No dynamically allocated memory in 'ext')*/
|
||||
} else if(sign == LV_SIGNAL_PRESSING) {
|
||||
@ -516,13 +492,13 @@ static lv_res_t lv_calendar_signal(lv_obj_t * calendar, lv_signal_t sign, void *
|
||||
ext->btn_pressing = 0;
|
||||
} else {
|
||||
if(ext->btn_pressing != 0) lv_obj_invalidate(calendar);
|
||||
ext->btn_pressing = 0;
|
||||
ext->btn_pressing = 0;
|
||||
ext->pressed_date.year = 0;
|
||||
}
|
||||
} else if(sign == LV_SIGNAL_PRESS_LOST) {
|
||||
lv_calendar_ext_t * ext = lv_obj_get_ext_attr(calendar);
|
||||
ext->pressed_date.year = 0;
|
||||
ext->btn_pressing = 0;
|
||||
ext->pressed_date.year = 0;
|
||||
ext->btn_pressing = 0;
|
||||
lv_obj_invalidate(calendar);
|
||||
|
||||
} else if(sign == LV_SIGNAL_RELEASED) {
|
||||
@ -530,51 +506,49 @@ static lv_res_t lv_calendar_signal(lv_obj_t * calendar, lv_signal_t sign, void *
|
||||
if(ext->btn_pressing < 0) {
|
||||
if(ext->showed_date.month <= 1) {
|
||||
ext->showed_date.month = 12;
|
||||
ext->showed_date.year --;
|
||||
ext->showed_date.year--;
|
||||
} else {
|
||||
ext->showed_date.month --;
|
||||
ext->showed_date.month--;
|
||||
}
|
||||
} else if(ext->btn_pressing > 0) {
|
||||
} else if(ext->btn_pressing > 0) {
|
||||
if(ext->showed_date.month >= 12) {
|
||||
ext->showed_date.month = 1;
|
||||
ext->showed_date.year ++;
|
||||
ext->showed_date.year++;
|
||||
} else {
|
||||
ext->showed_date.month ++;
|
||||
ext->showed_date.month++;
|
||||
}
|
||||
}
|
||||
else if(ext->pressed_date.year != 0)
|
||||
{
|
||||
} else if(ext->pressed_date.year != 0) {
|
||||
res = lv_event_send(calendar, LV_EVENT_VALUE_CHANGED, NULL);
|
||||
if(res != LV_RES_OK) return res;
|
||||
}
|
||||
|
||||
ext->pressed_date.year = 0;
|
||||
ext->btn_pressing = 0;
|
||||
ext->btn_pressing = 0;
|
||||
lv_obj_invalidate(calendar);
|
||||
} else if(sign == LV_SIGNAL_CONTROL) {
|
||||
uint8_t c = *((uint8_t *) param);
|
||||
uint8_t c = *((uint8_t *)param);
|
||||
lv_calendar_ext_t * ext = lv_obj_get_ext_attr(calendar);
|
||||
if(c == LV_GROUP_KEY_RIGHT || c == LV_GROUP_KEY_UP) {
|
||||
if(ext->showed_date.month >= 12) {
|
||||
ext->showed_date.month = 1;
|
||||
ext->showed_date.year ++;
|
||||
ext->showed_date.year++;
|
||||
} else {
|
||||
ext->showed_date.month ++;
|
||||
ext->showed_date.month++;
|
||||
}
|
||||
lv_obj_invalidate(calendar);
|
||||
} else if(c == LV_GROUP_KEY_LEFT || c == LV_GROUP_KEY_DOWN) {
|
||||
if(ext->showed_date.month <= 1) {
|
||||
ext->showed_date.month = 12;
|
||||
ext->showed_date.year --;
|
||||
ext->showed_date.year--;
|
||||
} else {
|
||||
ext->showed_date.month --;
|
||||
ext->showed_date.month--;
|
||||
}
|
||||
lv_obj_invalidate(calendar);
|
||||
}
|
||||
} else if(sign == LV_SIGNAL_GET_TYPE) {
|
||||
lv_obj_type_t * buf = param;
|
||||
uint8_t i;
|
||||
for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set date*/
|
||||
for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set date*/
|
||||
if(buf->type[i] == NULL) break;
|
||||
}
|
||||
buf->type[i] = "lv_calendar";
|
||||
@ -598,41 +572,45 @@ static bool calculate_touched_day(lv_obj_t * calendar, const lv_point_t * touche
|
||||
lv_style_t * style_bg = lv_calendar_get_style(calendar, LV_CALENDAR_STYLE_BG);
|
||||
days_area.x1 += style_bg->body.padding.left;
|
||||
days_area.x2 -= style_bg->body.padding.right;
|
||||
days_area.y1 = calendar->coords.y1 + get_header_height(calendar) + get_day_names_height(calendar) - style_bg->body.padding.top;
|
||||
days_area.y1 = calendar->coords.y1 + get_header_height(calendar) +
|
||||
get_day_names_height(calendar) - style_bg->body.padding.top;
|
||||
|
||||
if(lv_area_is_point_on(&days_area, touched_point)) {
|
||||
lv_coord_t w = (days_area.x2 - days_area.x1 + 1) / 7;
|
||||
lv_coord_t h = (days_area.y2 - days_area.y1 + 1) / 6;
|
||||
lv_coord_t w = (days_area.x2 - days_area.x1 + 1) / 7;
|
||||
lv_coord_t h = (days_area.y2 - days_area.y1 + 1) / 6;
|
||||
uint8_t x_pos = 0;
|
||||
x_pos = (touched_point->x - days_area.x1) / w;
|
||||
x_pos = (touched_point->x - days_area.x1) / w;
|
||||
if(x_pos > 6) x_pos = 6;
|
||||
uint8_t y_pos = 0;
|
||||
y_pos = (touched_point->y - days_area.y1) / h;
|
||||
y_pos = (touched_point->y - days_area.y1) / h;
|
||||
if(y_pos > 5) y_pos = 5;
|
||||
|
||||
uint8_t i_pos = 0;
|
||||
i_pos = (y_pos * 7) + x_pos;
|
||||
uint8_t i_pos = 0;
|
||||
i_pos = (y_pos * 7) + x_pos;
|
||||
lv_calendar_ext_t * ext = lv_obj_get_ext_attr(calendar);
|
||||
if(i_pos < get_day_of_week(ext->showed_date.year, ext->showed_date.month, 1) ) {
|
||||
if(i_pos < get_day_of_week(ext->showed_date.year, ext->showed_date.month, 1)) {
|
||||
ext->pressed_date.year = ext->showed_date.year - (ext->showed_date.month == 1 ? 1 : 0);
|
||||
ext->pressed_date.month = ext->showed_date.month == 1 ? 12 : (ext->showed_date.month - 1);
|
||||
ext->pressed_date.day = get_month_length(ext->pressed_date.year, ext->pressed_date.month) -
|
||||
get_day_of_week(ext->showed_date.year, ext->showed_date.month, 1) + 1 + i_pos;
|
||||
}
|
||||
else if(i_pos < (get_day_of_week(ext->showed_date.year, ext->showed_date.month, 1) +
|
||||
get_month_length(ext->showed_date.year, ext->showed_date.month))) {
|
||||
ext->pressed_date.year = ext->showed_date.year;
|
||||
ext->pressed_date.month =
|
||||
ext->showed_date.month == 1 ? 12 : (ext->showed_date.month - 1);
|
||||
ext->pressed_date.day =
|
||||
get_month_length(ext->pressed_date.year, ext->pressed_date.month) -
|
||||
get_day_of_week(ext->showed_date.year, ext->showed_date.month, 1) + 1 + i_pos;
|
||||
} else if(i_pos < (get_day_of_week(ext->showed_date.year, ext->showed_date.month, 1) +
|
||||
get_month_length(ext->showed_date.year, ext->showed_date.month))) {
|
||||
ext->pressed_date.year = ext->showed_date.year;
|
||||
ext->pressed_date.month = ext->showed_date.month;
|
||||
ext->pressed_date.day = i_pos + 1 - get_day_of_week(ext->showed_date.year, ext->showed_date.month, 1);
|
||||
}
|
||||
else if(i_pos < 42) {
|
||||
ext->pressed_date.day =
|
||||
i_pos + 1 - get_day_of_week(ext->showed_date.year, ext->showed_date.month, 1);
|
||||
} else if(i_pos < 42) {
|
||||
ext->pressed_date.year = ext->showed_date.year + (ext->showed_date.month == 12 ? 1 : 0);
|
||||
ext->pressed_date.month = ext->showed_date.month == 12 ? 1 : (ext->showed_date.month + 1);
|
||||
ext->pressed_date.day = i_pos + 1 - get_day_of_week(ext->showed_date.year, ext->showed_date.month, 1)
|
||||
- get_month_length(ext->showed_date.year, ext->showed_date.month);
|
||||
ext->pressed_date.month =
|
||||
ext->showed_date.month == 12 ? 1 : (ext->showed_date.month + 1);
|
||||
ext->pressed_date.day =
|
||||
i_pos + 1 - get_day_of_week(ext->showed_date.year, ext->showed_date.month, 1) -
|
||||
get_month_length(ext->showed_date.year, ext->showed_date.month);
|
||||
}
|
||||
return true;
|
||||
}else {
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -646,7 +624,8 @@ static lv_coord_t get_header_height(lv_obj_t * calendar)
|
||||
{
|
||||
lv_calendar_ext_t * ext = lv_obj_get_ext_attr(calendar);
|
||||
|
||||
return lv_font_get_height(ext->style_header->text.font) + ext->style_header->body.padding.top + ext->style_header->body.padding.bottom ;
|
||||
return lv_font_get_height(ext->style_header->text.font) + ext->style_header->body.padding.top +
|
||||
ext->style_header->body.padding.bottom;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -658,7 +637,8 @@ static lv_coord_t get_day_names_height(lv_obj_t * calendar)
|
||||
{
|
||||
lv_calendar_ext_t * ext = lv_obj_get_ext_attr(calendar);
|
||||
|
||||
return lv_font_get_height(ext->style_day_names->text.font) + ext->style_day_names->body.padding.top + ext->style_day_names->body.padding.bottom;
|
||||
return lv_font_get_height(ext->style_day_names->text.font) +
|
||||
ext->style_day_names->body.padding.top + ext->style_day_names->body.padding.bottom;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -669,7 +649,7 @@ static lv_coord_t get_day_names_height(lv_obj_t * calendar)
|
||||
static void draw_header(lv_obj_t * calendar, const lv_area_t * mask)
|
||||
{
|
||||
lv_calendar_ext_t * ext = lv_obj_get_ext_attr(calendar);
|
||||
lv_opa_t opa_scale = lv_obj_get_opa_scale(calendar);
|
||||
lv_opa_t opa_scale = lv_obj_get_opa_scale(calendar);
|
||||
|
||||
lv_area_t header_area;
|
||||
header_area.x1 = calendar->coords.x1;
|
||||
@ -682,24 +662,27 @@ static void draw_header(lv_obj_t * calendar, const lv_area_t * mask)
|
||||
/*Add the year + month name*/
|
||||
char txt_buf[64];
|
||||
lv_utils_num_to_str(ext->showed_date.year, txt_buf);
|
||||
txt_buf[4] = ' ';
|
||||
txt_buf[5] = '\0';
|
||||
txt_buf[4] = ' ';
|
||||
txt_buf[5] = '\0';
|
||||
strcpy(&txt_buf[5], get_month_name(calendar, ext->showed_date.month));
|
||||
header_area.y1 += ext->style_header->body.padding.top;
|
||||
lv_draw_label(&header_area, mask, ext->style_header, opa_scale, txt_buf, LV_TXT_FLAG_CENTER, NULL, -1, -1);
|
||||
lv_draw_label(&header_area, mask, ext->style_header, opa_scale, txt_buf, LV_TXT_FLAG_CENTER,
|
||||
NULL, -1, -1);
|
||||
|
||||
/*Add the left arrow*/
|
||||
lv_style_t * arrow_style = ext->btn_pressing < 0 ? ext->style_header_pr : ext->style_header;
|
||||
header_area.x1 += ext->style_header->body.padding.left;
|
||||
lv_draw_label(&header_area, mask, arrow_style, opa_scale, LV_SYMBOL_LEFT, LV_TXT_FLAG_NONE, NULL, -1, -1);
|
||||
lv_draw_label(&header_area, mask, arrow_style, opa_scale, LV_SYMBOL_LEFT, LV_TXT_FLAG_NONE,
|
||||
NULL, -1, -1);
|
||||
|
||||
/*Add the right arrow*/
|
||||
arrow_style = ext->btn_pressing > 0 ? ext->style_header_pr : ext->style_header;
|
||||
header_area.x1 = header_area.x2 - ext->style_header->body.padding.right -
|
||||
lv_txt_get_width(LV_SYMBOL_RIGHT, strlen(LV_SYMBOL_RIGHT), arrow_style->text.font,
|
||||
arrow_style->text.line_space, LV_TXT_FLAG_NONE);
|
||||
lv_draw_label(&header_area, mask, arrow_style, opa_scale, LV_SYMBOL_RIGHT, LV_TXT_FLAG_NONE, NULL, -1, -1);
|
||||
|
||||
header_area.x1 =
|
||||
header_area.x2 - ext->style_header->body.padding.right -
|
||||
lv_txt_get_width(LV_SYMBOL_RIGHT, strlen(LV_SYMBOL_RIGHT), arrow_style->text.font,
|
||||
arrow_style->text.line_space, LV_TXT_FLAG_NONE);
|
||||
lv_draw_label(&header_area, mask, arrow_style, opa_scale, LV_SYMBOL_RIGHT, LV_TXT_FLAG_NONE,
|
||||
NULL, -1, -1);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -710,21 +693,23 @@ static void draw_header(lv_obj_t * calendar, const lv_area_t * mask)
|
||||
static void draw_day_names(lv_obj_t * calendar, const lv_area_t * mask)
|
||||
{
|
||||
lv_calendar_ext_t * ext = lv_obj_get_ext_attr(calendar);
|
||||
lv_opa_t opa_scale = lv_obj_get_opa_scale(calendar);
|
||||
lv_opa_t opa_scale = lv_obj_get_opa_scale(calendar);
|
||||
|
||||
lv_coord_t l_pad = ext->style_day_names->body.padding.left;
|
||||
lv_coord_t w = lv_obj_get_width(calendar) - ext->style_day_names->body.padding.left - ext->style_day_names->body.padding.right;
|
||||
lv_coord_t w = lv_obj_get_width(calendar) - ext->style_day_names->body.padding.left -
|
||||
ext->style_day_names->body.padding.right;
|
||||
lv_coord_t box_w = w / 7;
|
||||
lv_area_t label_area;
|
||||
label_area.y1 = calendar->coords.y1 + get_header_height(calendar) + ext->style_day_names->body.padding.top;
|
||||
label_area.y1 =
|
||||
calendar->coords.y1 + get_header_height(calendar) + ext->style_day_names->body.padding.top;
|
||||
label_area.y2 = label_area.y1 + lv_font_get_height(ext->style_day_names->text.font);
|
||||
uint32_t i;
|
||||
for(i = 0; i < 7; i++) {
|
||||
label_area.x1 = calendar->coords.x1 + (w * i) / 7 + l_pad;
|
||||
label_area.x2 = label_area.x1 + box_w;
|
||||
lv_draw_label(&label_area, mask, ext->style_day_names, opa_scale, get_day_name(calendar, i), LV_TXT_FLAG_CENTER, NULL, -1, -1);
|
||||
lv_draw_label(&label_area, mask, ext->style_day_names, opa_scale, get_day_name(calendar, i),
|
||||
LV_TXT_FLAG_CENTER, NULL, -1, -1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -735,41 +720,42 @@ static void draw_day_names(lv_obj_t * calendar, const lv_area_t * mask)
|
||||
static void draw_days(lv_obj_t * calendar, const lv_area_t * mask)
|
||||
{
|
||||
lv_calendar_ext_t * ext = lv_obj_get_ext_attr(calendar);
|
||||
lv_style_t * style_bg = lv_calendar_get_style(calendar, LV_CALENDAR_STYLE_BG);
|
||||
lv_style_t * style_bg = lv_calendar_get_style(calendar, LV_CALENDAR_STYLE_BG);
|
||||
lv_area_t label_area;
|
||||
lv_opa_t opa_scale = lv_obj_get_opa_scale(calendar);
|
||||
label_area.y1 = calendar->coords.y1 + get_header_height(calendar) +
|
||||
ext->style_day_names->body.padding.top + lv_font_get_height(ext->style_day_names->text.font) +
|
||||
ext->style_day_names->body.padding.bottom;
|
||||
label_area.y1 = calendar->coords.y1 + get_header_height(calendar) +
|
||||
ext->style_day_names->body.padding.top +
|
||||
lv_font_get_height(ext->style_day_names->text.font) +
|
||||
ext->style_day_names->body.padding.bottom;
|
||||
label_area.y2 = label_area.y1 + lv_font_get_height(style_bg->text.font);
|
||||
|
||||
lv_coord_t w = lv_obj_get_width(calendar) - style_bg->body.padding.left - style_bg->body.padding.right;
|
||||
lv_coord_t h = calendar->coords.y2 - label_area.y1 - style_bg->body.padding.bottom;
|
||||
lv_coord_t box_w = w / 7;
|
||||
lv_coord_t w =
|
||||
lv_obj_get_width(calendar) - style_bg->body.padding.left - style_bg->body.padding.right;
|
||||
lv_coord_t h = calendar->coords.y2 - label_area.y1 - style_bg->body.padding.bottom;
|
||||
lv_coord_t box_w = w / 7;
|
||||
lv_coord_t vert_space = (h - (6 * lv_font_get_height(style_bg->text.font))) / 5;
|
||||
|
||||
uint32_t week;
|
||||
uint8_t day_cnt;
|
||||
uint8_t month_start_day = get_day_of_week(ext->showed_date.year, ext->showed_date.month, 1);
|
||||
day_draw_state_t draw_state; /*true: Not the prev. or next month is drawn*/
|
||||
day_draw_state_t draw_state; /*true: Not the prev. or next month is drawn*/
|
||||
lv_style_t * act_style;
|
||||
|
||||
/*If starting with the first day of the week then the previous month is not visible*/
|
||||
if(month_start_day == 0) {
|
||||
day_cnt = 1;
|
||||
day_cnt = 1;
|
||||
draw_state = DAY_DRAW_ACT_MONTH;
|
||||
act_style = style_bg;
|
||||
act_style = style_bg;
|
||||
} else {
|
||||
draw_state = DAY_DRAW_PREV_MONTH;
|
||||
day_cnt = get_month_length(ext->showed_date.year, ext->showed_date.month - 1); /*Length of the previous month*/
|
||||
day_cnt -= month_start_day - 1; /*First visible number of the previous month*/
|
||||
day_cnt = get_month_length(ext->showed_date.year,
|
||||
ext->showed_date.month - 1); /*Length of the previous month*/
|
||||
day_cnt -= month_start_day - 1; /*First visible number of the previous month*/
|
||||
act_style = ext->style_inactive_days;
|
||||
}
|
||||
|
||||
|
||||
bool month_of_today_shown = false;
|
||||
if(ext->showed_date.year == ext->today.year &&
|
||||
ext->showed_date.month == ext->today.month) {
|
||||
if(ext->showed_date.year == ext->today.year && ext->showed_date.month == ext->today.month) {
|
||||
month_of_today_shown = true;
|
||||
}
|
||||
|
||||
@ -780,13 +766,16 @@ static void draw_days(lv_obj_t * calendar, const lv_area_t * mask)
|
||||
for(week = 0; week < 6; week++) {
|
||||
|
||||
/*Draw the "week box"*/
|
||||
if(month_of_today_shown &&
|
||||
((draw_state == DAY_DRAW_ACT_MONTH && ext->today.day >= day_cnt && ext->today.day < day_cnt + 7) ||
|
||||
(draw_state == DAY_DRAW_PREV_MONTH && ext->today.day <= 7 - month_start_day && week == 0))) {
|
||||
if(month_of_today_shown && ((draw_state == DAY_DRAW_ACT_MONTH &&
|
||||
ext->today.day >= day_cnt && ext->today.day < day_cnt + 7) ||
|
||||
(draw_state == DAY_DRAW_PREV_MONTH &&
|
||||
ext->today.day <= 7 - month_start_day && week == 0))) {
|
||||
lv_area_t week_box_area;
|
||||
lv_area_copy(&week_box_area, &label_area); /*'label_area' is already set for this row*/
|
||||
week_box_area.x1 = calendar->coords.x1 + style_bg->body.padding.left - ext->style_week_box->body.padding.left;
|
||||
week_box_area.x2 = calendar->coords.x2 - style_bg->body.padding.right + ext->style_week_box->body.padding.right;
|
||||
lv_area_copy(&week_box_area, &label_area); /*'label_area' is already set for this row*/
|
||||
week_box_area.x1 = calendar->coords.x1 + style_bg->body.padding.left -
|
||||
ext->style_week_box->body.padding.left;
|
||||
week_box_area.x2 = calendar->coords.x2 - style_bg->body.padding.right +
|
||||
ext->style_week_box->body.padding.right;
|
||||
|
||||
week_box_area.y1 -= ext->style_week_box->body.padding.top;
|
||||
week_box_area.y2 += ext->style_week_box->body.padding.bottom;
|
||||
@ -803,22 +792,24 @@ static void draw_days(lv_obj_t * calendar, const lv_area_t * mask)
|
||||
/*The previous month is over*/
|
||||
if(draw_state == DAY_DRAW_PREV_MONTH && day == month_start_day) {
|
||||
draw_state = DAY_DRAW_ACT_MONTH;
|
||||
day_cnt = 1;
|
||||
act_style = style_bg;
|
||||
day_cnt = 1;
|
||||
act_style = style_bg;
|
||||
}
|
||||
/*The current month is over*/
|
||||
if(draw_state == DAY_DRAW_ACT_MONTH &&
|
||||
day_cnt > get_month_length(ext->showed_date.year, ext->showed_date.month)) {
|
||||
day_cnt > get_month_length(ext->showed_date.year, ext->showed_date.month)) {
|
||||
draw_state = DAY_DRAW_NEXT_MONTH;
|
||||
day_cnt = 1;
|
||||
act_style = ext->style_inactive_days;
|
||||
day_cnt = 1;
|
||||
act_style = ext->style_inactive_days;
|
||||
}
|
||||
|
||||
label_area.x1 = calendar->coords.x1 + (w * day) / 7 + style_bg->body.padding.left + style_bg->body.padding.right;
|
||||
label_area.x1 = calendar->coords.x1 + (w * day) / 7 + style_bg->body.padding.left +
|
||||
style_bg->body.padding.right;
|
||||
label_area.x2 = label_area.x1 + box_w;
|
||||
|
||||
/*Draw the "today box"*/
|
||||
if(draw_state == DAY_DRAW_ACT_MONTH && month_of_today_shown && ext->today.day == day_cnt) {
|
||||
if(draw_state == DAY_DRAW_ACT_MONTH && month_of_today_shown &&
|
||||
ext->today.day == day_cnt) {
|
||||
lv_area_t today_box_area;
|
||||
lv_area_copy(&today_box_area, &label_area);
|
||||
today_box_area.x1 = label_area.x1;
|
||||
@ -832,31 +823,34 @@ static void draw_days(lv_obj_t * calendar, const lv_area_t * mask)
|
||||
/*Get the final style : highlighted/week box/today box/normal*/
|
||||
lv_style_t * final_style;
|
||||
if(draw_state == DAY_DRAW_PREV_MONTH &&
|
||||
is_highlighted(calendar, ext->showed_date.year - (ext->showed_date.month == 1 ? 1 : 0),
|
||||
ext->showed_date.month == 1 ? 12 : ext->showed_date.month - 1,
|
||||
day_cnt)) {
|
||||
is_highlighted(
|
||||
calendar, ext->showed_date.year - (ext->showed_date.month == 1 ? 1 : 0),
|
||||
ext->showed_date.month == 1 ? 12 : ext->showed_date.month - 1, day_cnt)) {
|
||||
final_style = ext->style_highlighted_days;
|
||||
} else if(draw_state == DAY_DRAW_ACT_MONTH &&
|
||||
is_highlighted(calendar, ext->showed_date.year,
|
||||
ext->showed_date.month,
|
||||
day_cnt)) {
|
||||
is_highlighted(calendar, ext->showed_date.year, ext->showed_date.month,
|
||||
day_cnt)) {
|
||||
final_style = ext->style_highlighted_days;
|
||||
} else if(draw_state == DAY_DRAW_NEXT_MONTH &&
|
||||
is_highlighted(calendar, ext->showed_date.year + (ext->showed_date.month == 12 ? 1 : 0),
|
||||
ext->showed_date.month == 12 ? 1 : ext->showed_date.month + 1,
|
||||
day_cnt)) {
|
||||
is_highlighted(
|
||||
calendar, ext->showed_date.year + (ext->showed_date.month == 12 ? 1 : 0),
|
||||
ext->showed_date.month == 12 ? 1 : ext->showed_date.month + 1, day_cnt)) {
|
||||
final_style = ext->style_highlighted_days;
|
||||
} else if(month_of_today_shown && day_cnt == ext->today.day && draw_state == DAY_DRAW_ACT_MONTH) final_style = ext->style_today_box;
|
||||
else if(in_week_box && draw_state == DAY_DRAW_ACT_MONTH) final_style = ext->style_week_box;
|
||||
else final_style = act_style;
|
||||
} else if(month_of_today_shown && day_cnt == ext->today.day &&
|
||||
draw_state == DAY_DRAW_ACT_MONTH)
|
||||
final_style = ext->style_today_box;
|
||||
else if(in_week_box && draw_state == DAY_DRAW_ACT_MONTH)
|
||||
final_style = ext->style_week_box;
|
||||
else
|
||||
final_style = act_style;
|
||||
|
||||
/*Write the day's number*/
|
||||
lv_utils_num_to_str(day_cnt, buf);
|
||||
lv_draw_label(&label_area, mask, final_style, opa_scale, buf, LV_TXT_FLAG_CENTER, NULL, -1, -1);
|
||||
lv_draw_label(&label_area, mask, final_style, opa_scale, buf, LV_TXT_FLAG_CENTER, NULL,
|
||||
-1, -1);
|
||||
|
||||
/*Go to the next day*/
|
||||
day_cnt ++;
|
||||
|
||||
day_cnt++;
|
||||
}
|
||||
|
||||
/*Got to the next weeks row*/
|
||||
@ -881,9 +875,8 @@ static bool is_highlighted(lv_obj_t * calendar, int32_t year, int32_t month, int
|
||||
|
||||
uint32_t i;
|
||||
for(i = 0; i < ext->highlighted_dates_num; i++) {
|
||||
if(ext->highlighted_dates[i].year == year &&
|
||||
ext->highlighted_dates[i].month == month &&
|
||||
ext->highlighted_dates[i].day == day) {
|
||||
if(ext->highlighted_dates[i].year == year && ext->highlighted_dates[i].month == month &&
|
||||
ext->highlighted_dates[i].day == day) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -901,48 +894,52 @@ static const char * get_day_name(lv_obj_t * calendar, uint8_t day)
|
||||
{
|
||||
|
||||
lv_calendar_ext_t * ext = lv_obj_get_ext_attr(calendar);
|
||||
if(ext->day_names) return ext->day_names[day];
|
||||
else return day_name[day];
|
||||
if(ext->day_names)
|
||||
return ext->day_names[day];
|
||||
else
|
||||
return day_name[day];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the month name
|
||||
* @param calendar pointer to a calendar object
|
||||
* @param month a month. The range is basically [1..12] but [-11..1] is also supported to handle previous year
|
||||
* @param month a month. The range is basically [1..12] but [-11..1] is also supported to handle
|
||||
* previous year
|
||||
* @return
|
||||
*/
|
||||
static const char * get_month_name(lv_obj_t * calendar, int32_t month)
|
||||
{
|
||||
month --; /*Range of months id [1..12] but range of indexes is [0..11]*/
|
||||
month--; /*Range of months id [1..12] but range of indexes is [0..11]*/
|
||||
if(month < 0) month = 12 + month;
|
||||
|
||||
lv_calendar_ext_t * ext = lv_obj_get_ext_attr(calendar);
|
||||
if(ext->month_names) return ext->month_names[month];
|
||||
else return month_name[month];
|
||||
if(ext->month_names)
|
||||
return ext->month_names[month];
|
||||
else
|
||||
return month_name[month];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of days in a month
|
||||
* @param year a year
|
||||
* @param month a month. The range is basically [1..12] but [-11..1] is also supported to handle previous year
|
||||
* @param month a month. The range is basically [1..12] but [-11..1] is also supported to handle
|
||||
* previous year
|
||||
* @return [28..31]
|
||||
*/
|
||||
static uint8_t get_month_length(int32_t year, int32_t month)
|
||||
{
|
||||
month --; /*Range of months id [1..12] but range of indexes is [0..11]*/
|
||||
month--; /*Range of months id [1..12] but range of indexes is [0..11]*/
|
||||
if(month < 0) {
|
||||
year--; /*Already in the previous year (won't be less then -12 to skip a whole year)*/
|
||||
year--; /*Already in the previous year (won't be less then -12 to skip a whole year)*/
|
||||
month = 12 + month; /*`month` is negative, the result will be < 12*/
|
||||
}
|
||||
if(month >= 12) {
|
||||
year ++;
|
||||
year++;
|
||||
month -= 12;
|
||||
}
|
||||
|
||||
/*month == 1 is february*/
|
||||
return (month == 1) ? (28 + is_leap_year(year)) : 31 - month % 7 % 2;
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -967,8 +964,8 @@ static uint8_t get_day_of_week(uint32_t year, uint32_t month, uint32_t day)
|
||||
uint32_t a = month < 3 ? 1 : 0;
|
||||
uint32_t b = year - a;
|
||||
|
||||
uint32_t day_of_week = (day + (31 * (month - 2 + 12 * a) / 12) +
|
||||
b + (b / 4) - (b / 100) + (b / 400)) % 7;
|
||||
uint32_t day_of_week =
|
||||
(day + (31 * (month - 2 + 12 * a) / 12) + b + (b / 4) - (b / 100) + (b / 400)) % 7;
|
||||
|
||||
return day_of_week;
|
||||
}
|
||||
|
@ -31,24 +31,29 @@ extern "C" {
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
typedef struct {
|
||||
typedef struct
|
||||
{
|
||||
uint16_t year;
|
||||
int8_t month;
|
||||
int8_t day;
|
||||
} lv_calendar_date_t;
|
||||
|
||||
/*Data of calendar*/
|
||||
typedef struct {
|
||||
typedef struct
|
||||
{
|
||||
/*None*/ /*Ext. of ancestor*/
|
||||
/*New data for this type */
|
||||
lv_calendar_date_t today; /*Date of today*/
|
||||
lv_calendar_date_t showed_date; /*Currently visible month (day is ignored)*/
|
||||
lv_calendar_date_t * highlighted_dates; /*Apply different style on these days (pointer to an array defined by the user)*/
|
||||
uint8_t highlighted_dates_num; /*Number of elements in `highlighted_days`*/
|
||||
int8_t btn_pressing; /*-1: prev month pressing, +1 next month pressing on the header*/
|
||||
lv_calendar_date_t today; /*Date of today*/
|
||||
lv_calendar_date_t showed_date; /*Currently visible month (day is ignored)*/
|
||||
lv_calendar_date_t * highlighted_dates; /*Apply different style on these days (pointer to an
|
||||
array defined by the user)*/
|
||||
uint8_t highlighted_dates_num; /*Number of elements in `highlighted_days`*/
|
||||
int8_t btn_pressing; /*-1: prev month pressing, +1 next month pressing on the header*/
|
||||
lv_calendar_date_t pressed_date;
|
||||
const char ** day_names; /*Pointer to an array with the name of the days (NULL: use default names)*/
|
||||
const char ** month_names; /*Pointer to an array with the name of the month (NULL. use default names)*/
|
||||
const char **
|
||||
day_names; /*Pointer to an array with the name of the days (NULL: use default names)*/
|
||||
const char **
|
||||
month_names; /*Pointer to an array with the name of the month (NULL. use default names)*/
|
||||
|
||||
/*Styles*/
|
||||
lv_style_t * style_header;
|
||||
@ -62,7 +67,7 @@ typedef struct {
|
||||
|
||||
/*Styles*/
|
||||
enum {
|
||||
LV_CALENDAR_STYLE_BG, /*Also the style of the "normal" date numbers*/
|
||||
LV_CALENDAR_STYLE_BG, /*Also the style of the "normal" date numbers*/
|
||||
LV_CALENDAR_STYLE_HEADER,
|
||||
LV_CALENDAR_STYLE_HEADER_PR,
|
||||
LV_CALENDAR_STYLE_DAY_NAMES,
|
||||
@ -73,9 +78,6 @@ enum {
|
||||
};
|
||||
typedef uint8_t lv_calendar_style_t;
|
||||
|
||||
|
||||
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
@ -92,7 +94,6 @@ lv_obj_t * lv_calendar_create(lv_obj_t * par, const lv_obj_t * copy);
|
||||
* Add/remove functions
|
||||
*=====================*/
|
||||
|
||||
|
||||
/*=====================
|
||||
* Setter functions
|
||||
*====================*/
|
||||
@ -100,39 +101,44 @@ lv_obj_t * lv_calendar_create(lv_obj_t * par, const lv_obj_t * copy);
|
||||
/**
|
||||
* Set the today's date
|
||||
* @param calendar pointer to a calendar object
|
||||
* @param today pointer to an `lv_calendar_date_t` variable containing the date of today. The value will be saved it can be local variable too.
|
||||
* @param today pointer to an `lv_calendar_date_t` variable containing the date of today. The value
|
||||
* will be saved it can be local variable too.
|
||||
*/
|
||||
void lv_calendar_set_today_date(lv_obj_t * calendar, lv_calendar_date_t * today);
|
||||
|
||||
/**
|
||||
* Set the currently showed
|
||||
* @param calendar pointer to a calendar object
|
||||
* @param showed pointer to an `lv_calendar_date_t` variable containing the date to show. The value will be saved it can be local variable too.
|
||||
* @param showed pointer to an `lv_calendar_date_t` variable containing the date to show. The value
|
||||
* will be saved it can be local variable too.
|
||||
*/
|
||||
void lv_calendar_set_showed_date(lv_obj_t * calendar, lv_calendar_date_t * showed);
|
||||
|
||||
/**
|
||||
* Set the the highlighted dates
|
||||
* @param calendar pointer to a calendar object
|
||||
* @param highlighted pointer to an `lv_calendar_date_t` array containing the dates. ONLY A POINTER WILL BE SAVED! CAN'T BE LOCAL ARRAY.
|
||||
* @param highlighted pointer to an `lv_calendar_date_t` array containing the dates. ONLY A POINTER
|
||||
* WILL BE SAVED! CAN'T BE LOCAL ARRAY.
|
||||
* @param date_num number of dates in the array
|
||||
*/
|
||||
void lv_calendar_set_highlighted_dates(lv_obj_t * calendar, lv_calendar_date_t * highlighted, uint16_t date_num);
|
||||
|
||||
void lv_calendar_set_highlighted_dates(lv_obj_t * calendar, lv_calendar_date_t * highlighted,
|
||||
uint16_t date_num);
|
||||
|
||||
/**
|
||||
* Set the name of the days
|
||||
* @param calendar pointer to a calendar object
|
||||
* @param day_names pointer to an array with the names. E.g. `const char * days[7] = {"Sun", "Mon", ...}`
|
||||
* Only the pointer will be saved so this variable can't be local which will be destroyed later.
|
||||
* @param day_names pointer to an array with the names. E.g. `const char * days[7] = {"Sun", "Mon",
|
||||
* ...}` Only the pointer will be saved so this variable can't be local which will be destroyed
|
||||
* later.
|
||||
*/
|
||||
void lv_calendar_set_day_names(lv_obj_t * calendar, const char ** day_names);
|
||||
|
||||
/**
|
||||
* Set the name of the month
|
||||
* @param calendar pointer to a calendar object
|
||||
* @param day_names pointer to an array with the names. E.g. `const char * days[12] = {"Jan", "Feb", ...}`
|
||||
* Only the pointer will be saved so this variable can't be local which will be destroyed later.
|
||||
* @param day_names pointer to an array with the names. E.g. `const char * days[12] = {"Jan", "Feb",
|
||||
* ...}` Only the pointer will be saved so this variable can't be local which will be destroyed
|
||||
* later.
|
||||
*/
|
||||
void lv_calendar_set_month_names(lv_obj_t * calendar, const char ** day_names);
|
||||
|
||||
@ -142,7 +148,7 @@ void lv_calendar_set_month_names(lv_obj_t * calendar, const char ** day_names);
|
||||
* @param type which style should be set
|
||||
* @param style pointer to a style
|
||||
* */
|
||||
void lv_calendar_set_style(lv_obj_t * calendar, lv_calendar_style_t type, lv_style_t *style);
|
||||
void lv_calendar_set_style(lv_obj_t * calendar, lv_calendar_style_t type, lv_style_t * style);
|
||||
|
||||
/*=====================
|
||||
* Getter functions
|
||||
@ -183,7 +189,6 @@ lv_calendar_date_t * lv_calendar_get_highlighted_dates(const lv_obj_t * calendar
|
||||
*/
|
||||
uint16_t lv_calendar_get_highlighted_dates_num(const lv_obj_t * calendar);
|
||||
|
||||
|
||||
/**
|
||||
* Get the name of the days
|
||||
* @param calendar pointer to a calendar object
|
||||
@ -214,10 +219,10 @@ lv_style_t * lv_calendar_get_style(const lv_obj_t * calendar, lv_calendar_style_
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_CALENDAR*/
|
||||
#endif /*LV_USE_CALENDAR*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_CALENDAR_H*/
|
||||
#endif /*LV_CALENDAR_H*/
|
||||
|
@ -8,7 +8,7 @@
|
||||
*********************/
|
||||
#include <stdlib.h>
|
||||
#include "lv_canvas.h"
|
||||
#include "../lv_misc/lv_math.h"
|
||||
#include "../lv_misc/lv_math.h"
|
||||
#include "../lv_draw/lv_draw_img.h"
|
||||
#if LV_USE_CANVAS != 0
|
||||
|
||||
@ -63,11 +63,11 @@ lv_obj_t * lv_canvas_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
|
||||
/*Initialize the allocated 'ext' */
|
||||
ext->dsc.header.always_zero = 0;
|
||||
ext->dsc.header.cf = LV_IMG_CF_TRUE_COLOR;
|
||||
ext->dsc.header.h = 0;
|
||||
ext->dsc.header.w = 0;
|
||||
ext->dsc.data_size = 0;
|
||||
ext->dsc.data = NULL;
|
||||
ext->dsc.header.cf = LV_IMG_CF_TRUE_COLOR;
|
||||
ext->dsc.header.h = 0;
|
||||
ext->dsc.header.w = 0;
|
||||
ext->dsc.data_size = 0;
|
||||
ext->dsc.data = NULL;
|
||||
|
||||
lv_img_set_src(new_canvas, &ext->dsc);
|
||||
|
||||
@ -112,9 +112,9 @@ void lv_canvas_set_buffer(lv_obj_t * canvas, void * buf, lv_coord_t w, lv_coord_
|
||||
lv_canvas_ext_t * ext = lv_obj_get_ext_attr(canvas);
|
||||
|
||||
ext->dsc.header.cf = cf;
|
||||
ext->dsc.header.w = w;
|
||||
ext->dsc.header.h = h;
|
||||
ext->dsc.data = buf;
|
||||
ext->dsc.header.w = w;
|
||||
ext->dsc.header.h = h;
|
||||
ext->dsc.data = buf;
|
||||
ext->dsc.data_size = (lv_img_color_format_get_px_size(cf) * w * h) / 8;
|
||||
|
||||
lv_img_set_src(canvas, &ext->dsc);
|
||||
@ -128,12 +128,11 @@ void lv_canvas_set_buffer(lv_obj_t * canvas, void * buf, lv_coord_t w, lv_coord_
|
||||
* @param c color of the point
|
||||
*/
|
||||
void lv_canvas_set_px(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y, lv_color_t c)
|
||||
{
|
||||
lv_canvas_ext_t * ext = lv_obj_get_ext_attr(canvas);
|
||||
{
|
||||
lv_canvas_ext_t * ext = lv_obj_get_ext_attr(canvas);
|
||||
|
||||
lv_img_buf_set_px_color(&ext->dsc, x, y, c);
|
||||
lv_obj_invalidate(canvas);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -145,9 +144,7 @@ void lv_canvas_set_px(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y, lv_color_t
|
||||
void lv_canvas_set_style(lv_obj_t * canvas, lv_canvas_style_t type, lv_style_t * style)
|
||||
{
|
||||
switch(type) {
|
||||
case LV_CANVAS_STYLE_MAIN:
|
||||
lv_img_set_style(canvas, style);
|
||||
break;
|
||||
case LV_CANVAS_STYLE_MAIN: lv_img_set_style(canvas, style); break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -165,8 +162,8 @@ void lv_canvas_set_style(lv_obj_t * canvas, lv_canvas_style_t type, lv_style_t *
|
||||
lv_color_t lv_canvas_get_px(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y)
|
||||
{
|
||||
lv_canvas_ext_t * ext = lv_obj_get_ext_attr(canvas);
|
||||
lv_style_t * style = lv_canvas_get_style(canvas, LV_CANVAS_STYLE_MAIN);
|
||||
|
||||
lv_style_t * style = lv_canvas_get_style(canvas, LV_CANVAS_STYLE_MAIN);
|
||||
|
||||
return lv_img_buf_get_px_color(&ext->dsc, x, y, style);
|
||||
}
|
||||
|
||||
@ -194,11 +191,8 @@ lv_style_t * lv_canvas_get_style(const lv_obj_t * canvas, lv_canvas_style_t type
|
||||
lv_style_t * style = NULL;
|
||||
|
||||
switch(type) {
|
||||
case LV_CANVAS_STYLE_MAIN:
|
||||
style = lv_img_get_style(canvas);
|
||||
break;
|
||||
default:
|
||||
style = NULL;
|
||||
case LV_CANVAS_STYLE_MAIN: style = lv_img_get_style(canvas); break;
|
||||
default: style = NULL;
|
||||
}
|
||||
|
||||
return style;
|
||||
@ -211,13 +205,15 @@ lv_style_t * lv_canvas_get_style(const lv_obj_t * canvas, lv_canvas_style_t type
|
||||
/**
|
||||
* Copy a buffer to the canvas
|
||||
* @param canvas pointer to a canvas object
|
||||
* @param to_copy buffer to copy. The color format has to match with the canvas's buffer color format
|
||||
* @param to_copy buffer to copy. The color format has to match with the canvas's buffer color
|
||||
* format
|
||||
* @param w width of the buffer to copy
|
||||
* @param h height of the buffer to copy
|
||||
* @param x left side of the destination position
|
||||
* @param y top side of the destination position
|
||||
*/
|
||||
void lv_canvas_copy_buf(lv_obj_t * canvas, const void * to_copy, lv_coord_t w, lv_coord_t h, lv_coord_t x, lv_coord_t y)
|
||||
void lv_canvas_copy_buf(lv_obj_t * canvas, const void * to_copy, lv_coord_t w, lv_coord_t h,
|
||||
lv_coord_t x, lv_coord_t y)
|
||||
{
|
||||
lv_canvas_ext_t * ext = lv_obj_get_ext_attr(canvas);
|
||||
if(x + w >= ext->dsc.header.w || y + h >= ext->dsc.header.h) {
|
||||
@ -225,12 +221,12 @@ void lv_canvas_copy_buf(lv_obj_t * canvas, const void * to_copy, lv_coord_t w, l
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t px_size = lv_img_color_format_get_px_size(ext->dsc.header.cf) >> 3;
|
||||
uint32_t px = ext->dsc.header.w * y * px_size + x * px_size;
|
||||
uint8_t * to_copy8 = (uint8_t *) to_copy;
|
||||
uint32_t px_size = lv_img_color_format_get_px_size(ext->dsc.header.cf) >> 3;
|
||||
uint32_t px = ext->dsc.header.w * y * px_size + x * px_size;
|
||||
uint8_t * to_copy8 = (uint8_t *)to_copy;
|
||||
lv_coord_t i;
|
||||
for(i = 0; i < h; i++) {
|
||||
memcpy((void*)&ext->dsc.data[px], to_copy8, w * px_size);
|
||||
memcpy((void *)&ext->dsc.data[px], to_copy8, w * px_size);
|
||||
px += ext->dsc.header.w * px_size;
|
||||
to_copy8 += w * px_size;
|
||||
}
|
||||
@ -245,7 +241,8 @@ void lv_canvas_copy_buf(lv_obj_t * canvas, const void * to_copy, lv_coord_t w, l
|
||||
* @param x left side of the destination position
|
||||
* @param y top side of the destination position
|
||||
*/
|
||||
void lv_canvas_mult_buf(lv_obj_t * canvas, void * to_copy, lv_coord_t w, lv_coord_t h, lv_coord_t x, lv_coord_t y)
|
||||
void lv_canvas_mult_buf(lv_obj_t * canvas, void * to_copy, lv_coord_t w, lv_coord_t h, lv_coord_t x,
|
||||
lv_coord_t y)
|
||||
{
|
||||
lv_canvas_ext_t * ext = lv_obj_get_ext_attr(canvas);
|
||||
if(x + w >= ext->dsc.header.w || y + h >= ext->dsc.header.h) {
|
||||
@ -258,35 +255,50 @@ void lv_canvas_mult_buf(lv_obj_t * canvas, void * to_copy, lv_coord_t w, lv_coor
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t px_size = lv_img_color_format_get_px_size(ext->dsc.header.cf) >> 3;
|
||||
uint32_t px = ext->dsc.header.w * y * px_size + x * px_size;
|
||||
lv_color_t * copy_buf_color = (lv_color_t *) to_copy;
|
||||
lv_color_t * canvas_buf_color = (lv_color_t *) &ext->dsc.data[px];
|
||||
uint32_t px_size = lv_img_color_format_get_px_size(ext->dsc.header.cf) >> 3;
|
||||
uint32_t px = ext->dsc.header.w * y * px_size + x * px_size;
|
||||
lv_color_t * copy_buf_color = (lv_color_t *)to_copy;
|
||||
lv_color_t * canvas_buf_color = (lv_color_t *)&ext->dsc.data[px];
|
||||
|
||||
lv_coord_t i;
|
||||
lv_coord_t j;
|
||||
for(i = 0; i < h; i++) {
|
||||
for(j = 0; j < w; j++) {
|
||||
#if LV_COLOR_DEPTH == 32
|
||||
canvas_buf_color[j].ch.red = (uint16_t) ((uint16_t) canvas_buf_color[j].ch.red * copy_buf_color[j].ch.red) >> 8;
|
||||
canvas_buf_color[j].ch.green = (uint16_t) ((uint16_t) canvas_buf_color[j].ch.green * copy_buf_color[j].ch.green) >> 8;
|
||||
canvas_buf_color[j].ch.blue = (uint16_t) ((uint16_t) canvas_buf_color[j].ch.blue * copy_buf_color[j].ch.blue) >> 8;
|
||||
canvas_buf_color[j].ch.red =
|
||||
(uint16_t)((uint16_t)canvas_buf_color[j].ch.red * copy_buf_color[j].ch.red) >> 8;
|
||||
canvas_buf_color[j].ch.green =
|
||||
(uint16_t)((uint16_t)canvas_buf_color[j].ch.green * copy_buf_color[j].ch.green) >>
|
||||
8;
|
||||
canvas_buf_color[j].ch.blue =
|
||||
(uint16_t)((uint16_t)canvas_buf_color[j].ch.blue * copy_buf_color[j].ch.blue) >> 8;
|
||||
#elif LV_COLOR_DEPTH == 16
|
||||
|
||||
canvas_buf_color[j].ch.red = (uint16_t) ((uint16_t) canvas_buf_color[j].ch.red * copy_buf_color[j].ch.red) >> 5;
|
||||
canvas_buf_color[j].ch.blue = (uint16_t) ((uint16_t) canvas_buf_color[j].ch.blue * copy_buf_color[j].ch.blue) >> 5;
|
||||
# if LV_COLOR_16_SWAP == 0
|
||||
canvas_buf_color[j].ch.green = (uint16_t) ((uint16_t) canvas_buf_color[j].ch.green * copy_buf_color[j].ch.green) >> 6;
|
||||
# else
|
||||
canvas_buf_color[j].ch.red = (uint16_t) ((uint16_t) canvas_buf_color[j].ch.red * copy_buf_color[j].ch.red) >> 6;
|
||||
canvas_buf_color[j].ch.blue = (uint16_t) ((uint16_t) canvas_buf_color[j].ch.blue * copy_buf_color[j].ch.blue) >> 6;
|
||||
canvas_buf_color[j].ch.red = (uint16_t) ((uint16_t) canvas_buf_color[j].ch.red * copy_buf_color[j].ch.red) >> 6;
|
||||
# endif /*LV_COLOR_16_SWAP*/
|
||||
canvas_buf_color[j].ch.red =
|
||||
(uint16_t)((uint16_t)canvas_buf_color[j].ch.red * copy_buf_color[j].ch.red) >> 5;
|
||||
canvas_buf_color[j].ch.blue =
|
||||
(uint16_t)((uint16_t)canvas_buf_color[j].ch.blue * copy_buf_color[j].ch.blue) >> 5;
|
||||
#if LV_COLOR_16_SWAP == 0
|
||||
canvas_buf_color[j].ch.green =
|
||||
(uint16_t)((uint16_t)canvas_buf_color[j].ch.green * copy_buf_color[j].ch.green) >>
|
||||
6;
|
||||
#else
|
||||
canvas_buf_color[j].ch.red =
|
||||
(uint16_t)((uint16_t)canvas_buf_color[j].ch.red * copy_buf_color[j].ch.red) >> 6;
|
||||
canvas_buf_color[j].ch.blue =
|
||||
(uint16_t)((uint16_t)canvas_buf_color[j].ch.blue * copy_buf_color[j].ch.blue) >> 6;
|
||||
canvas_buf_color[j].ch.red =
|
||||
(uint16_t)((uint16_t)canvas_buf_color[j].ch.red * copy_buf_color[j].ch.red) >> 6;
|
||||
#endif /*LV_COLOR_16_SWAP*/
|
||||
|
||||
#elif LV_COLOR_DEPTH == 8
|
||||
canvas_buf_color[j].ch.red = (uint16_t) ((uint16_t) canvas_buf_color[j].ch.red * copy_buf_color[j].ch.red) >> 3;
|
||||
canvas_buf_color[j].ch.green = (uint16_t) ((uint16_t) canvas_buf_color[j].ch.green * copy_buf_color[j].ch.green) >> 3;
|
||||
canvas_buf_color[j].ch.blue = (uint16_t) ((uint16_t) canvas_buf_color[j].ch.blue * copy_buf_color[j].ch.blue) >> 2;
|
||||
canvas_buf_color[j].ch.red =
|
||||
(uint16_t)((uint16_t)canvas_buf_color[j].ch.red * copy_buf_color[j].ch.red) >> 3;
|
||||
canvas_buf_color[j].ch.green =
|
||||
(uint16_t)((uint16_t)canvas_buf_color[j].ch.green * copy_buf_color[j].ch.green) >>
|
||||
3;
|
||||
canvas_buf_color[j].ch.blue =
|
||||
(uint16_t)((uint16_t)canvas_buf_color[j].ch.blue * copy_buf_color[j].ch.blue) >> 2;
|
||||
#endif
|
||||
}
|
||||
copy_buf_color += w;
|
||||
@ -307,22 +319,23 @@ void lv_canvas_mult_buf(lv_obj_t * canvas, void * to_copy, lv_coord_t w, lv_coor
|
||||
* @param pivot_y pivot Y of rotation. Relative to the source canvas
|
||||
* Set to `source height / 2` to rotate around the center
|
||||
*/
|
||||
void lv_canvas_rotate(lv_obj_t * canvas, lv_img_dsc_t * img, int16_t angle,lv_coord_t offset_x, lv_coord_t offset_y, int32_t pivot_x, int32_t pivot_y)
|
||||
void lv_canvas_rotate(lv_obj_t * canvas, lv_img_dsc_t * img, int16_t angle, lv_coord_t offset_x,
|
||||
lv_coord_t offset_y, int32_t pivot_x, int32_t pivot_y)
|
||||
{
|
||||
lv_canvas_ext_t * ext_dst = lv_obj_get_ext_attr(canvas);
|
||||
lv_style_t * style = lv_canvas_get_style(canvas, LV_CANVAS_STYLE_MAIN);
|
||||
int32_t sinma = lv_trigo_sin(-angle);
|
||||
int32_t cosma = lv_trigo_sin(-angle + 90); /* cos */
|
||||
lv_style_t * style = lv_canvas_get_style(canvas, LV_CANVAS_STYLE_MAIN);
|
||||
int32_t sinma = lv_trigo_sin(-angle);
|
||||
int32_t cosma = lv_trigo_sin(-angle + 90); /* cos */
|
||||
|
||||
int32_t img_width = img->header.w;
|
||||
int32_t img_height = img->header.h;
|
||||
int32_t dest_width = ext_dst->dsc.header.w;
|
||||
int32_t img_width = img->header.w;
|
||||
int32_t img_height = img->header.h;
|
||||
int32_t dest_width = ext_dst->dsc.header.w;
|
||||
int32_t dest_height = ext_dst->dsc.header.h;
|
||||
|
||||
int32_t x;
|
||||
int32_t y;
|
||||
for (x = -offset_x; x < dest_width - offset_x; x++) {
|
||||
for (y = -offset_y; y < dest_height - offset_y; y++) {
|
||||
for(x = -offset_x; x < dest_width - offset_x; x++) {
|
||||
for(y = -offset_y; y < dest_height - offset_y; y++) {
|
||||
/*Get the target point relative coordinates to the pivot*/
|
||||
int32_t xt = x - pivot_x;
|
||||
int32_t yt = y - pivot_y;
|
||||
@ -335,13 +348,15 @@ void lv_canvas_rotate(lv_obj_t * canvas, lv_img_dsc_t * img, int16_t angle,lv_co
|
||||
int xs_int = xs >> 8;
|
||||
int ys_int = ys >> 8;
|
||||
|
||||
if(xs_int >= img_width)
|
||||
continue;
|
||||
else if(xs_int < 0)
|
||||
continue;
|
||||
|
||||
if(xs_int >= img_width) continue;
|
||||
else if(xs_int < 0) continue;
|
||||
|
||||
|
||||
if(ys_int >= img_height) continue;
|
||||
else if(ys_int < 0) continue;
|
||||
if(ys_int >= img_height)
|
||||
continue;
|
||||
else if(ys_int < 0)
|
||||
continue;
|
||||
|
||||
/*Get the fractional part of the source pixel*/
|
||||
int xs_fract = xs & 0xff;
|
||||
@ -351,43 +366,43 @@ void lv_canvas_rotate(lv_obj_t * canvas, lv_img_dsc_t * img, int16_t angle,lv_co
|
||||
* If the fractional > 0x90 mix the source pixel with the right/bottom pixel
|
||||
* In the 0x70..0x90 range use the unchanged source pixel */
|
||||
|
||||
int xn; /*x neightboor*/
|
||||
lv_opa_t xr; /*x mix ratio*/
|
||||
int xn; /*x neightboor*/
|
||||
lv_opa_t xr; /*x mix ratio*/
|
||||
if(xs_fract < 0x70) {
|
||||
xn = xs_int - 1;
|
||||
xr = xs_fract * 2;
|
||||
}
|
||||
else if(xs_fract > 0x90) {
|
||||
} else if(xs_fract > 0x90) {
|
||||
xn = xs_int + 1;
|
||||
xr = (0xFF - xs_fract) * 2;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
xn = xs_int;
|
||||
xr = 0xFF;
|
||||
}
|
||||
|
||||
/*Handle under/overflow*/
|
||||
if(xn >= img_width) continue;
|
||||
else if(xn < 0) continue;
|
||||
if(xn >= img_width)
|
||||
continue;
|
||||
else if(xn < 0)
|
||||
continue;
|
||||
|
||||
int yn; /*y neightboor*/
|
||||
lv_opa_t yr; /*y mix ratio*/
|
||||
int yn; /*y neightboor*/
|
||||
lv_opa_t yr; /*y mix ratio*/
|
||||
if(ys_fract < 0x70) {
|
||||
yn = ys_int - 1;
|
||||
yr = ys_fract * 2;
|
||||
}
|
||||
else if(ys_fract > 0x90) {
|
||||
} else if(ys_fract > 0x90) {
|
||||
yn = ys_int + 1;
|
||||
yr = (0xFF - ys_fract) * 2;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
yn = ys_int;
|
||||
yr = 0xFF;
|
||||
}
|
||||
|
||||
/*Handle under/overflow*/
|
||||
if(yn >= img_height) continue;
|
||||
else if(yn < 0) continue;
|
||||
if(yn >= img_height)
|
||||
continue;
|
||||
else if(yn < 0)
|
||||
continue;
|
||||
|
||||
/*Get the mixture of the original source and the neightboor pixels in both directions*/
|
||||
lv_color_t c_dest_int = lv_img_buf_get_px_color(img, xs_int, ys_int, style);
|
||||
@ -399,58 +414,71 @@ void lv_canvas_rotate(lv_obj_t * canvas, lv_img_dsc_t * img, int16_t angle,lv_co
|
||||
|
||||
lv_color_t c_dest_xn = lv_img_buf_get_px_color(img, xn, ys_int, style);
|
||||
lv_color_t c_dest_yn = lv_img_buf_get_px_color(img, xs_int, yn, style);
|
||||
lv_color_t x_dest = lv_color_mix(c_dest_int, c_dest_xn, xr);
|
||||
lv_color_t y_dest = lv_color_mix(c_dest_int, c_dest_yn, yr);
|
||||
lv_color_t x_dest = lv_color_mix(c_dest_int, c_dest_xn, xr);
|
||||
lv_color_t y_dest = lv_color_mix(c_dest_int, c_dest_yn, yr);
|
||||
lv_color_t color_res = lv_color_mix(x_dest, y_dest, LV_OPA_50);
|
||||
|
||||
if (x + offset_x >= 0 && x + offset_x < dest_width && y + offset_y >= 0 && y + offset_y < dest_height)
|
||||
{
|
||||
if(x + offset_x >= 0 && x + offset_x < dest_width && y + offset_y >= 0 &&
|
||||
y + offset_y < dest_height) {
|
||||
/*If the image has no alpha channel just simple set the result color on the canvas*/
|
||||
if(lv_img_color_format_has_alpha(img->header.cf) == false) {
|
||||
lv_img_buf_set_px_color(&ext_dst->dsc, x + offset_x, y + offset_y, color_res);
|
||||
} else {
|
||||
/*Get result pixel opacity*/
|
||||
lv_opa_t opa_int = lv_img_buf_get_px_alpha(img, xs_int, ys_int);
|
||||
lv_opa_t opa_xn = lv_img_buf_get_px_alpha(img, xn, ys_int);
|
||||
lv_opa_t opa_yn = lv_img_buf_get_px_alpha(img, xs_int, yn);
|
||||
lv_opa_t opa_x = (opa_int * xr + (opa_xn * (255 - xr))) >> 8;
|
||||
lv_opa_t opa_y = (opa_int * yr + (opa_yn * (255 - yr))) >> 8;
|
||||
lv_opa_t opa_xn = lv_img_buf_get_px_alpha(img, xn, ys_int);
|
||||
lv_opa_t opa_yn = lv_img_buf_get_px_alpha(img, xs_int, yn);
|
||||
lv_opa_t opa_x = (opa_int * xr + (opa_xn * (255 - xr))) >> 8;
|
||||
lv_opa_t opa_y = (opa_int * yr + (opa_yn * (255 - yr))) >> 8;
|
||||
lv_opa_t opa_res = (opa_x + opa_y) / 2;
|
||||
if(opa_res <= LV_OPA_MIN) continue;
|
||||
|
||||
lv_color_t bg_color = lv_img_buf_get_px_color(&ext_dst->dsc, x + offset_x, y + offset_y, style);
|
||||
lv_color_t bg_color =
|
||||
lv_img_buf_get_px_color(&ext_dst->dsc, x + offset_x, y + offset_y, style);
|
||||
|
||||
/*If the canvas has no alpha but the image has mix the image's color with canvas*/
|
||||
/*If the canvas has no alpha but the image has mix the image's color with
|
||||
* canvas*/
|
||||
if(lv_img_color_format_has_alpha(ext_dst->dsc.header.cf) == false) {
|
||||
if(opa_res < LV_OPA_MAX) color_res = lv_color_mix(color_res, bg_color, opa_res);
|
||||
lv_img_buf_set_px_color(&ext_dst->dsc, x + offset_x, y + offset_y, color_res);
|
||||
if(opa_res < LV_OPA_MAX)
|
||||
color_res = lv_color_mix(color_res, bg_color, opa_res);
|
||||
lv_img_buf_set_px_color(&ext_dst->dsc, x + offset_x, y + offset_y,
|
||||
color_res);
|
||||
}
|
||||
/*Both the image and canvas has alpha channel. Some extra calculation is required*/
|
||||
/*Both the image and canvas has alpha channel. Some extra calculation is
|
||||
required*/
|
||||
else {
|
||||
lv_opa_t bg_opa = lv_img_buf_get_px_alpha(&ext_dst->dsc, x + offset_x, y + offset_y);
|
||||
/* Pick the foreground if it's fully opaque or the Background is fully transparent*/
|
||||
lv_opa_t bg_opa =
|
||||
lv_img_buf_get_px_alpha(&ext_dst->dsc, x + offset_x, y + offset_y);
|
||||
/* Pick the foreground if it's fully opaque or the Background is fully
|
||||
* transparent*/
|
||||
if(opa_res >= LV_OPA_MAX || bg_opa <= LV_OPA_MIN) {
|
||||
lv_img_buf_set_px_color(&ext_dst->dsc, x + offset_x, y + offset_y, color_res);
|
||||
lv_img_buf_set_px_alpha(&ext_dst->dsc, x + offset_x, y + offset_y, opa_res);
|
||||
lv_img_buf_set_px_color(&ext_dst->dsc, x + offset_x, y + offset_y,
|
||||
color_res);
|
||||
lv_img_buf_set_px_alpha(&ext_dst->dsc, x + offset_x, y + offset_y,
|
||||
opa_res);
|
||||
}
|
||||
/*Opaque background: use simple mix*/
|
||||
else if(bg_opa >= LV_OPA_MAX) {
|
||||
lv_img_buf_set_px_color(&ext_dst->dsc, x + offset_x, y + offset_y, lv_color_mix(color_res, bg_color, opa_res));
|
||||
lv_img_buf_set_px_color(&ext_dst->dsc, x + offset_x, y + offset_y,
|
||||
lv_color_mix(color_res, bg_color, opa_res));
|
||||
}
|
||||
/*Both colors have alpha. Expensive calculation need to be applied*/
|
||||
else {
|
||||
|
||||
/*Info: https://en.wikipedia.org/wiki/Alpha_compositing#Analytical_derivation_of_the_over_operator*/
|
||||
lv_opa_t opa_res_2 = 255 - ((uint16_t)((uint16_t)(255 - opa_res) * (255 - bg_opa)) >> 8);
|
||||
/*Info:
|
||||
* https://en.wikipedia.org/wiki/Alpha_compositing#Analytical_derivation_of_the_over_operator*/
|
||||
lv_opa_t opa_res_2 =
|
||||
255 - ((uint16_t)((uint16_t)(255 - opa_res) * (255 - bg_opa)) >> 8);
|
||||
if(opa_res_2 == 0) {
|
||||
opa_res_2 = 1; /*never happens, just to be sure*/
|
||||
opa_res_2 = 1; /*never happens, just to be sure*/
|
||||
}
|
||||
lv_opa_t ratio = (uint16_t)((uint16_t) opa_res * 255) / opa_res_2;
|
||||
lv_opa_t ratio = (uint16_t)((uint16_t)opa_res * 255) / opa_res_2;
|
||||
|
||||
lv_img_buf_set_px_color(&ext_dst->dsc, x + offset_x, y + offset_y, lv_color_mix(color_res, bg_color, ratio));
|
||||
lv_img_buf_set_px_alpha(&ext_dst->dsc, x + offset_x, y + offset_y, opa_res_2);
|
||||
lv_img_buf_set_px_color(&ext_dst->dsc, x + offset_x, y + offset_y,
|
||||
lv_color_mix(color_res, bg_color, ratio));
|
||||
lv_img_buf_set_px_alpha(&ext_dst->dsc, x + offset_x, y + offset_y,
|
||||
opa_res_2);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -458,7 +486,6 @@ void lv_canvas_rotate(lv_obj_t * canvas, lv_img_dsc_t * img, int16_t angle,lv_co
|
||||
}
|
||||
|
||||
lv_obj_invalidate(canvas);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -469,14 +496,14 @@ void lv_canvas_rotate(lv_obj_t * canvas, lv_img_dsc_t * img, int16_t angle,lv_co
|
||||
* @param radius radius of the circle
|
||||
* @param color border color of the circle
|
||||
*/
|
||||
void lv_canvas_draw_circle(lv_obj_t * canvas, lv_coord_t x0, lv_coord_t y0, lv_coord_t radius, lv_color_t color)
|
||||
void lv_canvas_draw_circle(lv_obj_t * canvas, lv_coord_t x0, lv_coord_t y0, lv_coord_t radius,
|
||||
lv_color_t color)
|
||||
{
|
||||
int x = radius;
|
||||
int y = 0;
|
||||
int x = radius;
|
||||
int y = 0;
|
||||
int err = 0;
|
||||
|
||||
while (x >= y)
|
||||
{
|
||||
while(x >= y) {
|
||||
lv_canvas_set_px(canvas, x0 + x, y0 + y, color);
|
||||
lv_canvas_set_px(canvas, x0 + y, y0 + x, color);
|
||||
lv_canvas_set_px(canvas, x0 - y, y0 + x, color);
|
||||
@ -486,16 +513,14 @@ void lv_canvas_draw_circle(lv_obj_t * canvas, lv_coord_t x0, lv_coord_t y0, lv_c
|
||||
lv_canvas_set_px(canvas, x0 + y, y0 - x, color);
|
||||
lv_canvas_set_px(canvas, x0 + x, y0 - y, color);
|
||||
|
||||
if (err <= 0)
|
||||
{
|
||||
if(err <= 0) {
|
||||
y += 1;
|
||||
err += 2*y + 1;
|
||||
err += 2 * y + 1;
|
||||
}
|
||||
|
||||
if (err > 0)
|
||||
{
|
||||
if(err > 0) {
|
||||
x -= 1;
|
||||
err -= 2*x + 1;
|
||||
err -= 2 * x + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -518,17 +543,23 @@ void lv_canvas_draw_line(lv_obj_t * canvas, lv_point_t point1, lv_point_t point2
|
||||
x1 = point2.x;
|
||||
y1 = point2.y;
|
||||
|
||||
int dx = abs(x1-x0), sx = x0<x1 ? 1 : -1;
|
||||
int dy = abs(y1-y0), sy = y0<y1 ? 1 : -1;
|
||||
int err = (dx>dy ? dx : -dy)/2, e2;
|
||||
int dx = abs(x1 - x0), sx = x0 < x1 ? 1 : -1;
|
||||
int dy = abs(y1 - y0), sy = y0 < y1 ? 1 : -1;
|
||||
int err = (dx > dy ? dx : -dy) / 2, e2;
|
||||
|
||||
for(;;){
|
||||
for(;;) {
|
||||
lv_canvas_set_px(canvas, x0, y0, color);
|
||||
|
||||
if (x0==x1 && y0==y1) break;
|
||||
if(x0 == x1 && y0 == y1) break;
|
||||
e2 = err;
|
||||
if (e2 >-dx) { err -= dy; x0 += sx; }
|
||||
if (e2 < dy) { err += dx; y0 += sy; }
|
||||
if(e2 > -dx) {
|
||||
err -= dy;
|
||||
x0 += sx;
|
||||
}
|
||||
if(e2 < dy) {
|
||||
err += dx;
|
||||
y0 += sy;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -565,7 +596,7 @@ void lv_canvas_draw_polygon(lv_obj_t * canvas, lv_point_t * points, size_t size,
|
||||
{
|
||||
uint8_t i;
|
||||
|
||||
for(i=0; i < (size - 1); i++) {
|
||||
for(i = 0; i < (size - 1); i++) {
|
||||
lv_canvas_draw_line(canvas, points[i], points[i + 1], color);
|
||||
}
|
||||
|
||||
@ -580,12 +611,13 @@ void lv_canvas_draw_polygon(lv_obj_t * canvas, lv_point_t * points, size_t size,
|
||||
* @param boundary_color line color of the polygon
|
||||
* @param fill_color fill color of the polygon
|
||||
*/
|
||||
void lv_canvas_fill_polygon(lv_obj_t * canvas, lv_point_t * points, size_t size, lv_color_t boundary_color, lv_color_t fill_color)
|
||||
void lv_canvas_fill_polygon(lv_obj_t * canvas, lv_point_t * points, size_t size,
|
||||
lv_color_t boundary_color, lv_color_t fill_color)
|
||||
{
|
||||
uint32_t x = 0, y = 0;
|
||||
uint8_t i;
|
||||
|
||||
for(i=0; i<size; i++) {
|
||||
for(i = 0; i < size; i++) {
|
||||
x += points[i].x;
|
||||
y += points[i].y;
|
||||
}
|
||||
@ -593,7 +625,7 @@ void lv_canvas_fill_polygon(lv_obj_t * canvas, lv_point_t * points, size_t size,
|
||||
x = x / size;
|
||||
y = y / size;
|
||||
|
||||
lv_canvas_boundary_fill4(canvas, (lv_coord_t) x, (lv_coord_t) y, boundary_color, fill_color);
|
||||
lv_canvas_boundary_fill4(canvas, (lv_coord_t)x, (lv_coord_t)y, boundary_color, fill_color);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -604,21 +636,20 @@ void lv_canvas_fill_polygon(lv_obj_t * canvas, lv_point_t * points, size_t size,
|
||||
* @param boundary_color edge/boundary color of the area
|
||||
* @param fill_color fill color of the area
|
||||
*/
|
||||
void lv_canvas_boundary_fill4(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y, lv_color_t boundary_color, lv_color_t fill_color)
|
||||
void lv_canvas_boundary_fill4(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y,
|
||||
lv_color_t boundary_color, lv_color_t fill_color)
|
||||
{
|
||||
lv_color_t c;
|
||||
|
||||
c = lv_canvas_get_px(canvas, x, y);
|
||||
|
||||
if(c.full != boundary_color.full &&
|
||||
c.full != fill_color.full)
|
||||
{
|
||||
if(c.full != boundary_color.full && c.full != fill_color.full) {
|
||||
lv_canvas_set_px(canvas, x, y, fill_color);
|
||||
|
||||
lv_canvas_boundary_fill4(canvas, x + 1, y, boundary_color, fill_color);
|
||||
lv_canvas_boundary_fill4(canvas, x, y + 1, boundary_color, fill_color);
|
||||
lv_canvas_boundary_fill4(canvas, x - 1, y, boundary_color, fill_color);
|
||||
lv_canvas_boundary_fill4(canvas, x, y - 1, boundary_color, fill_color);
|
||||
lv_canvas_boundary_fill4(canvas, x + 1, y, boundary_color, fill_color);
|
||||
lv_canvas_boundary_fill4(canvas, x, y + 1, boundary_color, fill_color);
|
||||
lv_canvas_boundary_fill4(canvas, x - 1, y, boundary_color, fill_color);
|
||||
lv_canvas_boundary_fill4(canvas, x, y - 1, boundary_color, fill_color);
|
||||
}
|
||||
}
|
||||
|
||||
@ -630,20 +661,20 @@ void lv_canvas_boundary_fill4(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y, lv_
|
||||
* @param fill_color fill color of the area
|
||||
* @param bg_color background color of the area
|
||||
*/
|
||||
void lv_canvas_flood_fill(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y, lv_color_t fill_color, lv_color_t bg_color)
|
||||
void lv_canvas_flood_fill(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y, lv_color_t fill_color,
|
||||
lv_color_t bg_color)
|
||||
{
|
||||
lv_color_t c;
|
||||
|
||||
c = lv_canvas_get_px(canvas, x, y);
|
||||
|
||||
if(c.full == bg_color.full)
|
||||
{
|
||||
if(c.full == bg_color.full) {
|
||||
lv_canvas_set_px(canvas, x, y, fill_color);
|
||||
|
||||
lv_canvas_flood_fill(canvas, x+1, y, fill_color, bg_color);
|
||||
lv_canvas_flood_fill(canvas, x, y+1, fill_color, bg_color);
|
||||
lv_canvas_flood_fill(canvas, x-1, y, fill_color, bg_color);
|
||||
lv_canvas_flood_fill(canvas, x, y-1, fill_color, bg_color);
|
||||
lv_canvas_flood_fill(canvas, x + 1, y, fill_color, bg_color);
|
||||
lv_canvas_flood_fill(canvas, x, y + 1, fill_color, bg_color);
|
||||
lv_canvas_flood_fill(canvas, x - 1, y, fill_color, bg_color);
|
||||
lv_canvas_flood_fill(canvas, x, y - 1, fill_color, bg_color);
|
||||
}
|
||||
}
|
||||
|
||||
@ -671,7 +702,7 @@ static lv_res_t lv_canvas_signal(lv_obj_t * canvas, lv_signal_t sign, void * par
|
||||
} else if(sign == LV_SIGNAL_GET_TYPE) {
|
||||
lv_obj_type_t * buf = param;
|
||||
uint8_t i;
|
||||
for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/
|
||||
for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/
|
||||
if(buf->type[i] == NULL) break;
|
||||
}
|
||||
buf->type[i] = "lv_canvas";
|
||||
|
@ -32,20 +32,19 @@ extern "C" {
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
/*Data of canvas*/
|
||||
typedef struct {
|
||||
typedef struct
|
||||
{
|
||||
lv_img_ext_t img; /*Ext. of ancestor*/
|
||||
/*New data for this type */
|
||||
lv_img_dsc_t dsc;
|
||||
} lv_canvas_ext_t;
|
||||
|
||||
|
||||
/*Styles*/
|
||||
enum {
|
||||
LV_CANVAS_STYLE_MAIN,
|
||||
};
|
||||
typedef uint8_t lv_canvas_style_t;
|
||||
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
@ -75,7 +74,8 @@ lv_obj_t * lv_canvas_create(lv_obj_t * par, const lv_obj_t * copy);
|
||||
* @param cf color format. The following formats are supported:
|
||||
* LV_IMG_CF_TRUE_COLOR, LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED, LV_IMG_CF_INDEXES_1/2/4/8BIT
|
||||
*/
|
||||
void lv_canvas_set_buffer(lv_obj_t * canvas, void * buf, lv_coord_t w, lv_coord_t h, lv_img_cf_t cf);
|
||||
void lv_canvas_set_buffer(lv_obj_t * canvas, void * buf, lv_coord_t w, lv_coord_t h,
|
||||
lv_img_cf_t cf);
|
||||
|
||||
/**
|
||||
* Set the color of a pixel on the canvas
|
||||
@ -129,13 +129,15 @@ lv_style_t * lv_canvas_get_style(const lv_obj_t * canvas, lv_canvas_style_t type
|
||||
/**
|
||||
* Copy a buffer to the canvas
|
||||
* @param canvas pointer to a canvas object
|
||||
* @param to_copy buffer to copy. The color format has to match with the canvas's buffer color format
|
||||
* @param to_copy buffer to copy. The color format has to match with the canvas's buffer color
|
||||
* format
|
||||
* @param w width of the buffer to copy
|
||||
* @param h height of the buffer to copy
|
||||
* @param x left side of the destination position
|
||||
* @param y top side of the destination position
|
||||
*/
|
||||
void lv_canvas_copy_buf(lv_obj_t * canvas, const void * to_copy, lv_coord_t w, lv_coord_t h, lv_coord_t x, lv_coord_t y);
|
||||
void lv_canvas_copy_buf(lv_obj_t * canvas, const void * to_copy, lv_coord_t w, lv_coord_t h,
|
||||
lv_coord_t x, lv_coord_t y);
|
||||
|
||||
/**
|
||||
* Multiply a buffer with the canvas
|
||||
@ -146,7 +148,8 @@ void lv_canvas_copy_buf(lv_obj_t * canvas, const void * to_copy, lv_coord_t w, l
|
||||
* @param x left side of the destination position
|
||||
* @param y top side of the destination position
|
||||
*/
|
||||
void lv_canvas_mult_buf(lv_obj_t * canvas, void * to_copy, lv_coord_t w, lv_coord_t h, lv_coord_t x, lv_coord_t y);
|
||||
void lv_canvas_mult_buf(lv_obj_t * canvas, void * to_copy, lv_coord_t w, lv_coord_t h, lv_coord_t x,
|
||||
lv_coord_t y);
|
||||
|
||||
/**
|
||||
* Rotate and image and store the result on a canvas.
|
||||
@ -161,7 +164,8 @@ void lv_canvas_mult_buf(lv_obj_t * canvas, void * to_copy, lv_coord_t w, lv_coor
|
||||
* @param pivot_y pivot Y of rotation. Relative to the source canvas
|
||||
* Set to `source height / 2` to rotate around the center
|
||||
*/
|
||||
void lv_canvas_rotate(lv_obj_t * canvas, lv_img_dsc_t * img, int16_t angle,lv_coord_t offset_x, lv_coord_t offset_y, int32_t pivot_x, int32_t pivot_y);
|
||||
void lv_canvas_rotate(lv_obj_t * canvas, lv_img_dsc_t * img, int16_t angle, lv_coord_t offset_x,
|
||||
lv_coord_t offset_y, int32_t pivot_x, int32_t pivot_y);
|
||||
|
||||
/**
|
||||
* Draw circle function of the canvas
|
||||
@ -171,7 +175,8 @@ void lv_canvas_rotate(lv_obj_t * canvas, lv_img_dsc_t * img, int16_t angle,lv_co
|
||||
* @param radius radius of the circle
|
||||
* @param color border color of the circle
|
||||
*/
|
||||
void lv_canvas_draw_circle(lv_obj_t * canvas, lv_coord_t x0, lv_coord_t y0, lv_coord_t radius, lv_color_t color);
|
||||
void lv_canvas_draw_circle(lv_obj_t * canvas, lv_coord_t x0, lv_coord_t y0, lv_coord_t radius,
|
||||
lv_color_t color);
|
||||
|
||||
/**
|
||||
* Draw line function of the canvas
|
||||
@ -217,16 +222,18 @@ void lv_canvas_draw_polygon(lv_obj_t * canvas, lv_point_t * points, size_t size,
|
||||
* @param boundary_color line color of the polygon
|
||||
* @param fill_color fill color of the polygon
|
||||
*/
|
||||
void lv_canvas_fill_polygon(lv_obj_t * canvas, lv_point_t * points, size_t size, lv_color_t boundary_color, lv_color_t fill_color);
|
||||
void lv_canvas_fill_polygon(lv_obj_t * canvas, lv_point_t * points, size_t size,
|
||||
lv_color_t boundary_color, lv_color_t fill_color);
|
||||
/**
|
||||
* Boundary fill function of the canvas
|
||||
* @param canvas pointer to a canvas object
|
||||
* @param x x coordinate of the start position (seed)
|
||||
* @param y y coordinate of the start position (seed)
|
||||
* @param boundary_color edge/boundary color of the area
|
||||
* @param fill_color fill color of the area
|
||||
* @param fill_color fill color of the area
|
||||
*/
|
||||
void lv_canvas_boundary_fill4(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y, lv_color_t boundary_color, lv_color_t fill_color);
|
||||
void lv_canvas_boundary_fill4(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y,
|
||||
lv_color_t boundary_color, lv_color_t fill_color);
|
||||
|
||||
/**
|
||||
* Flood fill function of the canvas
|
||||
@ -236,31 +243,42 @@ void lv_canvas_boundary_fill4(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y, lv_
|
||||
* @param fill_color fill color of the area
|
||||
* @param bg_color background color of the area
|
||||
*/
|
||||
void lv_canvas_flood_fill(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y, lv_color_t fill_color, lv_color_t bg_color);
|
||||
void lv_canvas_flood_fill(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y, lv_color_t fill_color,
|
||||
lv_color_t bg_color);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
#define LV_CANVAS_BUF_SIZE_TRUE_COLOR(w,h) ((LV_COLOR_SIZE / 8) * w * h)
|
||||
#define LV_CANVAS_BUF_SIZE_TRUE_COLOR_CHROMA_KEYED(w,h) ((LV_COLOR_SIZE / 8) * w * h)
|
||||
#define LV_CANVAS_BUF_SIZE_TRUE_COLOR_ALPHA(w,h) (LV_IMG_PX_SIZE_ALPHA_BYTE * w * h)
|
||||
#define LV_CANVAS_BUF_SIZE_TRUE_COLOR(w, h) ((LV_COLOR_SIZE / 8) * w * h)
|
||||
#define LV_CANVAS_BUF_SIZE_TRUE_COLOR_CHROMA_KEYED(w, h) ((LV_COLOR_SIZE / 8) * w * h)
|
||||
#define LV_CANVAS_BUF_SIZE_TRUE_COLOR_ALPHA(w, h) (LV_IMG_PX_SIZE_ALPHA_BYTE * w * h)
|
||||
|
||||
#define LV_CANVAS_BUF_SIZE_ALPHA_1BIT(w,h) ((((w / 8) + 1) * h)) /*(w / 8) + 1): to be sure no fractional row; LV_COLOR_SIZE / 8) * 2: palette*/
|
||||
#define LV_CANVAS_BUF_SIZE_INDEXED_1BIT(w,h) (LV_CANVAS_BUF_SIZE_ALPHA_1BIT(w,h) + 4 * 2) /*4 * 2: palette*/
|
||||
#define LV_CANVAS_BUF_SIZE_ALPHA_1BIT(w, h) \
|
||||
((((w / 8) + 1) * \
|
||||
h)) /*(w / 8) + 1): to be sure no fractional row; LV_COLOR_SIZE / 8) * 2: palette*/
|
||||
#define LV_CANVAS_BUF_SIZE_INDEXED_1BIT(w, h) \
|
||||
(LV_CANVAS_BUF_SIZE_ALPHA_1BIT(w, h) + 4 * 2) /*4 * 2: palette*/
|
||||
|
||||
#define LV_CANVAS_BUF_SIZE_ALPHA_2BIT(w,h) ((((w / 4) + 1) * h)) /*(w / 8) + 1): to be sure no fractional row; LV_COLOR_SIZE / 8) * 2: palette*/
|
||||
#define LV_CANVAS_BUF_SIZE_INDEXED_2BIT(w,h) (LV_CANVAS_BUF_SIZE_ALPHA_2BIT(w,h) + 4 * 4) /*4 * 4: palette*/
|
||||
#define LV_CANVAS_BUF_SIZE_ALPHA_2BIT(w, h) \
|
||||
((((w / 4) + 1) * \
|
||||
h)) /*(w / 8) + 1): to be sure no fractional row; LV_COLOR_SIZE / 8) * 2: palette*/
|
||||
#define LV_CANVAS_BUF_SIZE_INDEXED_2BIT(w, h) \
|
||||
(LV_CANVAS_BUF_SIZE_ALPHA_2BIT(w, h) + 4 * 4) /*4 * 4: palette*/
|
||||
|
||||
#define LV_CANVAS_BUF_SIZE_ALPHA_4BIT(w,h) ((((w / 2) + 1) * h)) /*(w / 8) + 1): to be sure no fractional row; LV_COLOR_SIZE / 8) * 2: palette*/
|
||||
#define LV_CANVAS_BUF_SIZE_INDEXED_4BIT(w,h) (LV_CANVAS_BUF_SIZE_ALPHA_4BIT(w,h) + 4 * 16) /*4 * 16: palette*/
|
||||
#define LV_CANVAS_BUF_SIZE_ALPHA_4BIT(w, h) \
|
||||
((((w / 2) + 1) * \
|
||||
h)) /*(w / 8) + 1): to be sure no fractional row; LV_COLOR_SIZE / 8) * 2: palette*/
|
||||
#define LV_CANVAS_BUF_SIZE_INDEXED_4BIT(w, h) \
|
||||
(LV_CANVAS_BUF_SIZE_ALPHA_4BIT(w, h) + 4 * 16) /*4 * 16: palette*/
|
||||
|
||||
#define LV_CANVAS_BUF_SIZE_ALPHA_8BIT(w,h) ((w * h))
|
||||
#define LV_CANVAS_BUF_SIZE_INDEXED_8BIT(w,h) (LV_CANVAS_BUF_SIZE_ALPHA_8BIT(w,h) + 4 * 256) /*4 * 256: palette*/
|
||||
#define LV_CANVAS_BUF_SIZE_ALPHA_8BIT(w, h) ((w * h))
|
||||
#define LV_CANVAS_BUF_SIZE_INDEXED_8BIT(w, h) \
|
||||
(LV_CANVAS_BUF_SIZE_ALPHA_8BIT(w, h) + 4 * 256) /*4 * 256: palette*/
|
||||
|
||||
#endif /*LV_USE_CANVAS*/
|
||||
#endif /*LV_USE_CANVAS*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_CANVAS_H*/
|
||||
#endif /*LV_CANVAS_H*/
|
||||
|
@ -66,7 +66,7 @@ lv_obj_t * lv_cb_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
if(ext == NULL) return NULL;
|
||||
|
||||
ext->bullet = NULL;
|
||||
ext->label = NULL;
|
||||
ext->label = NULL;
|
||||
|
||||
lv_obj_set_signal_cb(new_cb, lv_cb_signal);
|
||||
lv_obj_set_design_cb(new_cb, lv_cb_design);
|
||||
@ -74,7 +74,8 @@ lv_obj_t * lv_cb_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
/*Init the new checkbox object*/
|
||||
if(copy == NULL) {
|
||||
ext->bullet = lv_btn_create(new_cb, NULL);
|
||||
if(ancestor_bullet_design == NULL) ancestor_bullet_design = lv_obj_get_design_func(ext->bullet);
|
||||
if(ancestor_bullet_design == NULL)
|
||||
ancestor_bullet_design = lv_obj_get_design_func(ext->bullet);
|
||||
lv_obj_set_click(ext->bullet, false);
|
||||
|
||||
ext->label = lv_label_create(new_cb, NULL);
|
||||
@ -100,8 +101,8 @@ lv_obj_t * lv_cb_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
}
|
||||
} else {
|
||||
lv_cb_ext_t * copy_ext = lv_obj_get_ext_attr(copy);
|
||||
ext->bullet = lv_btn_create(new_cb, copy_ext->bullet);
|
||||
ext->label = lv_label_create(new_cb, copy_ext->label);
|
||||
ext->bullet = lv_btn_create(new_cb, copy_ext->bullet);
|
||||
ext->label = lv_label_create(new_cb, copy_ext->label);
|
||||
|
||||
/*Refresh the style with new signal function*/
|
||||
lv_obj_refresh_style(new_cb);
|
||||
@ -109,7 +110,6 @@ lv_obj_t * lv_cb_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
|
||||
lv_obj_set_design_cb(ext->bullet, lv_bullet_design);
|
||||
|
||||
|
||||
LV_LOG_INFO("check box created");
|
||||
|
||||
return new_cb;
|
||||
@ -137,7 +137,8 @@ void lv_cb_set_text(lv_obj_t * cb, const char * txt)
|
||||
* @param cb pointer to a check box
|
||||
* @param txt the text of the check box. NULL to refresh with the current text.
|
||||
*/
|
||||
void lv_cb_set_static_text(lv_obj_t * cb, const char * txt) {
|
||||
void lv_cb_set_static_text(lv_obj_t * cb, const char * txt)
|
||||
{
|
||||
lv_cb_ext_t * ext = lv_obj_get_ext_attr(cb);
|
||||
lv_label_set_static_text(ext->label, txt);
|
||||
}
|
||||
@ -160,26 +161,18 @@ void lv_cb_set_style(lv_obj_t * cb, lv_cb_style_t type, lv_style_t * style)
|
||||
lv_btn_set_style(cb, LV_BTN_STYLE_TGL_PR, style);
|
||||
lv_btn_set_style(cb, LV_BTN_STYLE_INA, style);
|
||||
break;
|
||||
case LV_CB_STYLE_BOX_REL:
|
||||
lv_btn_set_style(ext->bullet, LV_BTN_STYLE_REL, style);
|
||||
break;
|
||||
case LV_CB_STYLE_BOX_PR:
|
||||
lv_btn_set_style(ext->bullet, LV_BTN_STYLE_PR, style);
|
||||
break;
|
||||
case LV_CB_STYLE_BOX_REL: lv_btn_set_style(ext->bullet, LV_BTN_STYLE_REL, style); break;
|
||||
case LV_CB_STYLE_BOX_PR: lv_btn_set_style(ext->bullet, LV_BTN_STYLE_PR, style); break;
|
||||
case LV_CB_STYLE_BOX_TGL_REL:
|
||||
lv_btn_set_style(ext->bullet, LV_BTN_STYLE_TGL_REL, style);
|
||||
break;
|
||||
case LV_CB_STYLE_BOX_TGL_PR:
|
||||
lv_btn_set_style(ext->bullet, LV_BTN_STYLE_TGL_PR, style);
|
||||
break;
|
||||
case LV_CB_STYLE_BOX_INA:
|
||||
lv_btn_set_style(ext->bullet, LV_BTN_STYLE_INA, style);
|
||||
break;
|
||||
case LV_CB_STYLE_BOX_INA: lv_btn_set_style(ext->bullet, LV_BTN_STYLE_INA, style); break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*=====================
|
||||
* Getter functions
|
||||
*====================*/
|
||||
@ -195,7 +188,6 @@ const char * lv_cb_get_text(const lv_obj_t * cb)
|
||||
return lv_label_get_text(ext->label);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get a style of a button
|
||||
* @param cb pointer to check box object
|
||||
@ -205,27 +197,19 @@ const char * lv_cb_get_text(const lv_obj_t * cb)
|
||||
lv_style_t * lv_cb_get_style(const lv_obj_t * cb, lv_cb_style_t type)
|
||||
{
|
||||
lv_style_t * style = NULL;
|
||||
lv_cb_ext_t * ext = lv_obj_get_ext_attr(cb);
|
||||
lv_cb_ext_t * ext = lv_obj_get_ext_attr(cb);
|
||||
|
||||
switch(type) {
|
||||
case LV_CB_STYLE_BOX_REL:
|
||||
style = lv_btn_get_style(ext->bullet, LV_BTN_STYLE_REL);
|
||||
break;
|
||||
case LV_CB_STYLE_BOX_PR:
|
||||
style = lv_btn_get_style(ext->bullet, LV_BTN_STYLE_PR);
|
||||
break;
|
||||
case LV_CB_STYLE_BOX_REL: style = lv_btn_get_style(ext->bullet, LV_BTN_STYLE_REL); break;
|
||||
case LV_CB_STYLE_BOX_PR: style = lv_btn_get_style(ext->bullet, LV_BTN_STYLE_PR); break;
|
||||
case LV_CB_STYLE_BOX_TGL_REL:
|
||||
style = lv_btn_get_style(ext->bullet, LV_BTN_STYLE_TGL_REL);
|
||||
break;
|
||||
case LV_CB_STYLE_BOX_TGL_PR:
|
||||
style = lv_btn_get_style(ext->bullet, LV_BTN_STYLE_TGL_PR);
|
||||
break;
|
||||
case LV_CB_STYLE_BOX_INA:
|
||||
style = lv_btn_get_style(ext->bullet, LV_BTN_STYLE_INA);
|
||||
break;
|
||||
default:
|
||||
style = NULL;
|
||||
break;
|
||||
case LV_CB_STYLE_BOX_INA: style = lv_btn_get_style(ext->bullet, LV_BTN_STYLE_INA); break;
|
||||
default: style = NULL; break;
|
||||
}
|
||||
|
||||
return style;
|
||||
@ -253,7 +237,7 @@ static bool lv_cb_design(lv_obj_t * cb, const lv_area_t * mask, lv_design_mode_t
|
||||
/*Return false if the object is not covers the mask_p area*/
|
||||
result = ancestor_bg_design(cb, mask, mode);
|
||||
} else if(mode == LV_DESIGN_DRAW_MAIN || mode == LV_DESIGN_DRAW_POST) {
|
||||
lv_cb_ext_t * cb_ext = lv_obj_get_ext_attr(cb);
|
||||
lv_cb_ext_t * cb_ext = lv_obj_get_ext_attr(cb);
|
||||
lv_btn_ext_t * bullet_ext = lv_obj_get_ext_attr(cb_ext->bullet);
|
||||
|
||||
/*Be sure the state of the bullet is the same as the parent button*/
|
||||
@ -287,22 +271,22 @@ static bool lv_bullet_design(lv_obj_t * bullet, const lv_area_t * mask, lv_desig
|
||||
/* If the check box is the active in a group and
|
||||
* the background is not visible (transparent)
|
||||
* then activate the style of the bullet*/
|
||||
lv_style_t * style_ori = lv_obj_get_style(bullet);
|
||||
lv_obj_t * bg = lv_obj_get_parent(bullet);
|
||||
lv_style_t * style_ori = lv_obj_get_style(bullet);
|
||||
lv_obj_t * bg = lv_obj_get_parent(bullet);
|
||||
lv_style_t * style_page = lv_obj_get_style(bg);
|
||||
lv_group_t * g = lv_obj_get_group(bg);
|
||||
lv_group_t * g = lv_obj_get_group(bg);
|
||||
if(style_page->body.opa == LV_OPA_TRANSP) { /*Is the Background visible?*/
|
||||
if(lv_group_get_focused(g) == bg) {
|
||||
lv_style_t * style_mod;
|
||||
style_mod = lv_group_mod_style(g, style_ori);
|
||||
bullet->style_p = style_mod; /*Temporally change the style to the activated */
|
||||
style_mod = lv_group_mod_style(g, style_ori);
|
||||
bullet->style_p = style_mod; /*Temporally change the style to the activated */
|
||||
}
|
||||
}
|
||||
#endif
|
||||
ancestor_bullet_design(bullet, mask, mode);
|
||||
|
||||
#if LV_USE_GROUP
|
||||
bullet->style_p = style_ori; /*Revert the style*/
|
||||
bullet->style_p = style_ori; /*Revert the style*/
|
||||
#endif
|
||||
} else if(mode == LV_DESIGN_DRAW_POST) {
|
||||
ancestor_bullet_design(bullet, mask, mode);
|
||||
@ -311,7 +295,6 @@ static bool lv_bullet_design(lv_obj_t * bullet, const lv_area_t * mask, lv_desig
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Signal function of the check box
|
||||
* @param cb pointer to a check box object
|
||||
@ -331,22 +314,22 @@ static lv_res_t lv_cb_signal(lv_obj_t * cb, lv_signal_t sign, void * param)
|
||||
|
||||
if(sign == LV_SIGNAL_STYLE_CHG) {
|
||||
lv_style_t * label_style = lv_label_get_style(ext->label);
|
||||
lv_obj_set_size(ext->bullet, lv_font_get_height(label_style->text.font), lv_font_get_height(label_style->text.font));
|
||||
lv_obj_set_size(ext->bullet, lv_font_get_height(label_style->text.font),
|
||||
lv_font_get_height(label_style->text.font));
|
||||
lv_btn_set_state(ext->bullet, lv_btn_get_state(cb));
|
||||
} else if(sign == LV_SIGNAL_PRESSED ||
|
||||
sign == LV_SIGNAL_RELEASED ||
|
||||
} else if(sign == LV_SIGNAL_PRESSED || sign == LV_SIGNAL_RELEASED ||
|
||||
sign == LV_SIGNAL_PRESS_LOST) {
|
||||
lv_btn_set_state(ext->bullet, lv_btn_get_state(cb));
|
||||
} else if(sign == LV_SIGNAL_CONTROL) {
|
||||
char c = *((char *)param);
|
||||
if(c == LV_GROUP_KEY_RIGHT || c == LV_GROUP_KEY_DOWN ||
|
||||
c == LV_GROUP_KEY_LEFT || c == LV_GROUP_KEY_UP) {
|
||||
if(c == LV_GROUP_KEY_RIGHT || c == LV_GROUP_KEY_DOWN || c == LV_GROUP_KEY_LEFT ||
|
||||
c == LV_GROUP_KEY_UP) {
|
||||
lv_btn_set_state(ext->bullet, lv_btn_get_state(cb));
|
||||
}
|
||||
} else if(sign == LV_SIGNAL_GET_TYPE) {
|
||||
lv_obj_type_t * buf = param;
|
||||
uint8_t i;
|
||||
for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/
|
||||
for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/
|
||||
if(buf->type[i] == NULL) break;
|
||||
}
|
||||
buf->type[i] = "lv_cb";
|
||||
|
@ -47,8 +47,8 @@ typedef struct
|
||||
{
|
||||
lv_btn_ext_t bg_btn; /*Ext. of ancestor*/
|
||||
/*New data for this type */
|
||||
lv_obj_t * bullet; /*Pointer to button*/
|
||||
lv_obj_t * label; /*Pointer to label*/
|
||||
lv_obj_t * bullet; /*Pointer to button*/
|
||||
lv_obj_t * label; /*Pointer to label*/
|
||||
} lv_cb_ext_t;
|
||||
|
||||
enum {
|
||||
@ -118,7 +118,7 @@ static inline void lv_cb_set_inactive(lv_obj_t * cb)
|
||||
* @param type which style should be set
|
||||
* @param style pointer to a style
|
||||
* */
|
||||
void lv_cb_set_style(lv_obj_t * cb, lv_cb_style_t type, lv_style_t *style);
|
||||
void lv_cb_set_style(lv_obj_t * cb, lv_cb_style_t type, lv_style_t * style);
|
||||
|
||||
/*=====================
|
||||
* Getter functions
|
||||
@ -153,10 +153,10 @@ lv_style_t * lv_cb_get_style(const lv_obj_t * cb, lv_cb_style_t type);
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_CB*/
|
||||
#endif /*LV_USE_CB*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_CB_H*/
|
||||
#endif /*LV_CB_H*/
|
||||
|
@ -15,14 +15,14 @@
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define LV_CHART_YMIN_DEF 0
|
||||
#define LV_CHART_YMAX_DEF 100
|
||||
#define LV_CHART_HDIV_DEF 3
|
||||
#define LV_CHART_VDIV_DEF 5
|
||||
#define LV_CHART_PNUM_DEF 10
|
||||
#define LV_CHART_YMIN_DEF 0
|
||||
#define LV_CHART_YMAX_DEF 100
|
||||
#define LV_CHART_HDIV_DEF 3
|
||||
#define LV_CHART_VDIV_DEF 5
|
||||
#define LV_CHART_PNUM_DEF 10
|
||||
#define LV_CHART_AXIS_TO_LABEL_DISTANCE 4
|
||||
#define LV_CHART_AXIS_MAJOR_TICK_LEN_COE 1/15
|
||||
#define LV_CHART_AXIS_MINOR_TICK_LEN_COE 2/3
|
||||
#define LV_CHART_AXIS_MAJOR_TICK_LEN_COE 1 / 15
|
||||
#define LV_CHART_AXIS_MINOR_TICK_LEN_COE 2 / 3
|
||||
#define LV_CHART_AXIS_X_TICK_OFFSET_FIX 1
|
||||
#define LV_CHART_AXIS_Y_TICK_OFFSET_FIX 0
|
||||
|
||||
@ -60,7 +60,8 @@ static lv_signal_cb_t ancestor_signal;
|
||||
/**
|
||||
* Create a chart background objects
|
||||
* @param par pointer to an object, it will be the parent of the new chart background
|
||||
* @param copy pointer to a chart background object, if not NULL then the new object will be copied from it
|
||||
* @param copy pointer to a chart background object, if not NULL then the new object will be copied
|
||||
* from it
|
||||
* @return pointer to the created chart background
|
||||
*/
|
||||
lv_obj_t * lv_chart_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
@ -78,17 +79,17 @@ lv_obj_t * lv_chart_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
if(ext == NULL) return NULL;
|
||||
|
||||
lv_ll_init(&ext->series_ll, sizeof(lv_chart_series_t));
|
||||
ext->series.num = 0;
|
||||
ext->ymin = LV_CHART_YMIN_DEF;
|
||||
ext->ymax = LV_CHART_YMAX_DEF;
|
||||
ext->hdiv_cnt = LV_CHART_HDIV_DEF;
|
||||
ext->vdiv_cnt = LV_CHART_VDIV_DEF;
|
||||
ext->point_cnt = LV_CHART_PNUM_DEF;
|
||||
ext->type = LV_CHART_TYPE_LINE;
|
||||
ext->series.opa = LV_OPA_COVER;
|
||||
ext->series.dark = LV_OPA_50;
|
||||
ext->series.num = 0;
|
||||
ext->ymin = LV_CHART_YMIN_DEF;
|
||||
ext->ymax = LV_CHART_YMAX_DEF;
|
||||
ext->hdiv_cnt = LV_CHART_HDIV_DEF;
|
||||
ext->vdiv_cnt = LV_CHART_VDIV_DEF;
|
||||
ext->point_cnt = LV_CHART_PNUM_DEF;
|
||||
ext->type = LV_CHART_TYPE_LINE;
|
||||
ext->series.opa = LV_OPA_COVER;
|
||||
ext->series.dark = LV_OPA_50;
|
||||
ext->series.width = 2;
|
||||
ext->margin = 0;
|
||||
ext->margin = 0;
|
||||
memset(&ext->x_axis, 0, sizeof(ext->x_axis));
|
||||
memset(&ext->y_axis, 0, sizeof(ext->y_axis));
|
||||
|
||||
@ -112,14 +113,14 @@ lv_obj_t * lv_chart_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
|
||||
} else {
|
||||
lv_chart_ext_t * ext_copy = lv_obj_get_ext_attr(copy);
|
||||
ext->type = ext_copy->type;
|
||||
ext->ymin = ext_copy->ymin;
|
||||
ext->ymax = ext_copy->ymax;
|
||||
ext->hdiv_cnt = ext_copy->hdiv_cnt;
|
||||
ext->vdiv_cnt = ext_copy->vdiv_cnt;
|
||||
ext->point_cnt = ext_copy->point_cnt;
|
||||
ext->series.opa = ext_copy->series.opa;
|
||||
ext->margin = ext_copy->margin;
|
||||
ext->type = ext_copy->type;
|
||||
ext->ymin = ext_copy->ymin;
|
||||
ext->ymax = ext_copy->ymax;
|
||||
ext->hdiv_cnt = ext_copy->hdiv_cnt;
|
||||
ext->vdiv_cnt = ext_copy->vdiv_cnt;
|
||||
ext->point_cnt = ext_copy->point_cnt;
|
||||
ext->series.opa = ext_copy->series.opa;
|
||||
ext->margin = ext_copy->margin;
|
||||
memcpy(&ext->x_axis, &ext_copy->x_axis, sizeof(lv_chart_axis_cfg_t));
|
||||
memcpy(&ext->y_axis, &ext_copy->y_axis, sizeof(lv_chart_axis_cfg_t));
|
||||
|
||||
@ -129,7 +130,6 @@ lv_obj_t * lv_chart_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
|
||||
LV_LOG_INFO("chart created");
|
||||
|
||||
|
||||
return new_chart;
|
||||
}
|
||||
|
||||
@ -145,7 +145,7 @@ lv_obj_t * lv_chart_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
*/
|
||||
lv_chart_series_t * lv_chart_add_series(lv_obj_t * chart, lv_color_t color)
|
||||
{
|
||||
lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart);
|
||||
lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart);
|
||||
lv_chart_series_t * ser = lv_ll_ins_head(&ext->series_ll);
|
||||
lv_mem_assert(ser);
|
||||
if(ser == NULL) return NULL;
|
||||
@ -185,19 +185,16 @@ lv_chart_series_t * lv_chart_add_series(lv_obj_t * chart, lv_color_t color)
|
||||
*/
|
||||
void lv_chart_clear_serie(lv_obj_t * chart, lv_chart_series_t * serie)
|
||||
{
|
||||
if(chart == NULL || serie == NULL)
|
||||
return;
|
||||
if(chart == NULL || serie == NULL) return;
|
||||
lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart);
|
||||
if(ext == NULL) return;
|
||||
|
||||
uint32_t i;
|
||||
for(i = 0; i < ext->point_cnt; i++)
|
||||
{
|
||||
for(i = 0; i < ext->point_cnt; i++) {
|
||||
serie->points[i] = LV_CHART_POINT_DEF;
|
||||
}
|
||||
|
||||
serie->start_point = 0;
|
||||
|
||||
}
|
||||
|
||||
/*=====================
|
||||
@ -270,7 +267,8 @@ void lv_chart_set_point_count(lv_obj_t * chart, uint16_t point_cnt)
|
||||
|
||||
if(point_cnt < 1) point_cnt = 1;
|
||||
|
||||
LV_LL_READ_BACK(ext->series_ll, ser) {
|
||||
LV_LL_READ_BACK(ext->series_ll, ser)
|
||||
{
|
||||
if(ser->start_point != 0) {
|
||||
lv_coord_t * new_points = lv_mem_alloc(sizeof(lv_coord_t) * point_cnt);
|
||||
lv_mem_assert(new_points);
|
||||
@ -278,14 +276,16 @@ void lv_chart_set_point_count(lv_obj_t * chart, uint16_t point_cnt)
|
||||
|
||||
if(point_cnt >= point_cnt_old) {
|
||||
for(i = 0; i < point_cnt_old; i++) {
|
||||
new_points[i] = ser->points[(i + ser->start_point) % point_cnt_old]; /*Copy old contents to new array*/
|
||||
new_points[i] = ser->points[(i + ser->start_point) %
|
||||
point_cnt_old]; /*Copy old contents to new array*/
|
||||
}
|
||||
for(i = point_cnt_old; i < point_cnt; i++) {
|
||||
new_points[i] = def; /*Fill up the rest with default value*/
|
||||
new_points[i] = def; /*Fill up the rest with default value*/
|
||||
}
|
||||
} else {
|
||||
for(i = 0; i < point_cnt; i++) {
|
||||
new_points[i] = ser->points[(i + ser->start_point) % point_cnt_old]; /*Copy old contents to new array*/
|
||||
new_points[i] = ser->points[(i + ser->start_point) %
|
||||
point_cnt_old]; /*Copy old contents to new array*/
|
||||
}
|
||||
}
|
||||
|
||||
@ -394,7 +394,8 @@ void lv_chart_set_next(lv_obj_t * chart, lv_chart_series_t * ser, lv_coord_t y)
|
||||
{
|
||||
lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart);
|
||||
|
||||
ser->points[ser->start_point] = y; /*This was the place of the former left most value, after shifting it is the rightmost*/
|
||||
ser->points[ser->start_point] =
|
||||
y; /*This was the place of the former left most value, after shifting it is the rightmost*/
|
||||
ser->start_point = (ser->start_point + 1) % ext->point_cnt;
|
||||
|
||||
lv_chart_refresh(chart);
|
||||
@ -404,11 +405,11 @@ void lv_chart_set_next(lv_obj_t * chart, lv_chart_series_t * ser, lv_coord_t y)
|
||||
* Set the margin around the chart, used for axes value and labels
|
||||
* @param margin value of the margin
|
||||
*/
|
||||
void lv_chart_set_margin(lv_obj_t* chart, uint16_t margin)
|
||||
void lv_chart_set_margin(lv_obj_t * chart, uint16_t margin)
|
||||
{
|
||||
lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart);
|
||||
ext->margin = margin;
|
||||
lv_obj_refresh_ext_size(chart);
|
||||
lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart);
|
||||
ext->margin = margin;
|
||||
lv_obj_refresh_ext_size(chart);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -421,34 +422,28 @@ void lv_chart_set_margin(lv_obj_t* chart, uint16_t margin)
|
||||
* @param minor_tick_len the length of the minor tick, AUTO if 0
|
||||
* @param options extra options
|
||||
*/
|
||||
void lv_chart_set_x_ticks( lv_obj_t* chart,
|
||||
const char* list_of_values,
|
||||
uint8_t num_tick_marks,
|
||||
uint8_t major_tick_len,
|
||||
uint8_t minor_tick_len,
|
||||
lv_chart_axis_options_t options)
|
||||
void lv_chart_set_x_ticks(lv_obj_t * chart, const char * list_of_values, uint8_t num_tick_marks,
|
||||
uint8_t major_tick_len, uint8_t minor_tick_len,
|
||||
lv_chart_axis_options_t options)
|
||||
{
|
||||
lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart);
|
||||
lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart);
|
||||
ext->x_axis.num_tick_marks = num_tick_marks;
|
||||
ext->x_axis.list_of_values = list_of_values;
|
||||
ext->x_axis.major_tick_len = major_tick_len;
|
||||
ext->x_axis.minor_tick_len = minor_tick_len;
|
||||
ext->x_axis.options = options;
|
||||
ext->x_axis.options = options;
|
||||
}
|
||||
|
||||
void lv_chart_set_y_ticks( lv_obj_t* chart,
|
||||
const char* list_of_values,
|
||||
uint8_t num_tick_marks,
|
||||
uint8_t major_tick_len,
|
||||
uint8_t minor_tick_len,
|
||||
lv_chart_axis_options_t options)
|
||||
void lv_chart_set_y_ticks(lv_obj_t * chart, const char * list_of_values, uint8_t num_tick_marks,
|
||||
uint8_t major_tick_len, uint8_t minor_tick_len,
|
||||
lv_chart_axis_options_t options)
|
||||
{
|
||||
lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart);
|
||||
lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart);
|
||||
ext->y_axis.num_tick_marks = num_tick_marks;
|
||||
ext->y_axis.list_of_values = list_of_values;
|
||||
ext->y_axis.major_tick_len = major_tick_len;
|
||||
ext->y_axis.minor_tick_len = minor_tick_len;
|
||||
ext->y_axis.options = options;
|
||||
ext->y_axis.options = options;
|
||||
}
|
||||
|
||||
/*=====================
|
||||
@ -528,10 +523,10 @@ void lv_chart_refresh(lv_obj_t * chart)
|
||||
* @param chart pointer to an chart object
|
||||
* @param return value of the margin
|
||||
*/
|
||||
uint16_t lv_chart_get_margin(lv_obj_t* chart)
|
||||
uint16_t lv_chart_get_margin(lv_obj_t * chart)
|
||||
{
|
||||
lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart);
|
||||
return ext->margin;
|
||||
lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart);
|
||||
return ext->margin;
|
||||
}
|
||||
|
||||
/**********************
|
||||
@ -589,20 +584,21 @@ static lv_res_t lv_chart_signal(lv_obj_t * chart, lv_signal_t sign, void * param
|
||||
|
||||
if(sign == LV_SIGNAL_CLEANUP) {
|
||||
lv_coord_t ** datal;
|
||||
LV_LL_READ(ext->series_ll, datal) {
|
||||
LV_LL_READ(ext->series_ll, datal)
|
||||
{
|
||||
lv_mem_free(*datal);
|
||||
}
|
||||
lv_ll_clear(&ext->series_ll);
|
||||
} else if(sign == LV_SIGNAL_GET_TYPE) {
|
||||
lv_obj_type_t * buf = param;
|
||||
uint8_t i;
|
||||
for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/
|
||||
for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/
|
||||
if(buf->type[i] == NULL) break;
|
||||
}
|
||||
buf->type[i] = "lv_chart";
|
||||
} else if(sign == LV_SIGNAL_REFR_EXT_SIZE) {
|
||||
/*Provide extra px draw area around the chart*/
|
||||
chart->ext_size = ext->margin;
|
||||
/*Provide extra px draw area around the chart*/
|
||||
chart->ext_size = ext->margin;
|
||||
}
|
||||
|
||||
return res;
|
||||
@ -616,16 +612,16 @@ static lv_res_t lv_chart_signal(lv_obj_t * chart, lv_signal_t sign, void * param
|
||||
static void lv_chart_draw_div(lv_obj_t * chart, const lv_area_t * mask)
|
||||
{
|
||||
lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart);
|
||||
lv_style_t * style = lv_obj_get_style(chart);
|
||||
lv_opa_t opa_scale = lv_obj_get_opa_scale(chart);
|
||||
lv_style_t * style = lv_obj_get_style(chart);
|
||||
lv_opa_t opa_scale = lv_obj_get_opa_scale(chart);
|
||||
|
||||
uint8_t div_i;
|
||||
uint8_t div_i_end;
|
||||
uint8_t div_i_start;
|
||||
lv_point_t p1;
|
||||
lv_point_t p2;
|
||||
lv_coord_t w = lv_obj_get_width(chart) - 1;
|
||||
lv_coord_t h = lv_obj_get_height(chart) - 1;
|
||||
lv_coord_t w = lv_obj_get_width(chart) - 1;
|
||||
lv_coord_t h = lv_obj_get_height(chart) - 1;
|
||||
lv_coord_t x_ofs = chart->coords.x1;
|
||||
lv_coord_t y_ofs = chart->coords.y1;
|
||||
|
||||
@ -633,19 +629,21 @@ static void lv_chart_draw_div(lv_obj_t * chart, const lv_area_t * mask)
|
||||
/*Draw slide lines if no border*/
|
||||
if(style->body.border.width != 0) {
|
||||
div_i_start = 1;
|
||||
div_i_end = ext->hdiv_cnt;
|
||||
div_i_end = ext->hdiv_cnt;
|
||||
} else {
|
||||
div_i_start = 0;
|
||||
div_i_end = ext->hdiv_cnt + 1;
|
||||
div_i_end = ext->hdiv_cnt + 1;
|
||||
}
|
||||
|
||||
p1.x = 0 + x_ofs;
|
||||
p2.x = w + x_ofs;
|
||||
for(div_i = div_i_start; div_i <= div_i_end; div_i++) {
|
||||
p1.y = (int32_t)((int32_t)h * div_i) / (ext->hdiv_cnt + 1);
|
||||
p1.y += y_ofs;
|
||||
if(div_i == div_i_start) p1.y += (style->line.width >> 1) + 1; /*The first line might not be visible*/
|
||||
if(div_i == div_i_end) p1.y -= (style->line.width >> 1) + 1; /*The last line might not be visible*/
|
||||
p1.y += y_ofs;
|
||||
if(div_i == div_i_start)
|
||||
p1.y += (style->line.width >> 1) + 1; /*The first line might not be visible*/
|
||||
if(div_i == div_i_end)
|
||||
p1.y -= (style->line.width >> 1) + 1; /*The last line might not be visible*/
|
||||
|
||||
p2.y = p1.y;
|
||||
lv_draw_line(&p1, &p2, mask, style, opa_scale);
|
||||
@ -656,19 +654,21 @@ static void lv_chart_draw_div(lv_obj_t * chart, const lv_area_t * mask)
|
||||
/*Draw slide lines if no border*/
|
||||
if(style->body.border.width != 0) {
|
||||
div_i_start = 1;
|
||||
div_i_end = ext->vdiv_cnt;
|
||||
div_i_end = ext->vdiv_cnt;
|
||||
} else {
|
||||
div_i_start = 0;
|
||||
div_i_end = ext->vdiv_cnt + 1;
|
||||
div_i_end = ext->vdiv_cnt + 1;
|
||||
}
|
||||
|
||||
p1.y = 0 + y_ofs;
|
||||
p2.y = h + y_ofs;
|
||||
for(div_i = div_i_start; div_i <= div_i_end; div_i ++) {
|
||||
for(div_i = div_i_start; div_i <= div_i_end; div_i++) {
|
||||
p1.x = (int32_t)((int32_t)w * div_i) / (ext->vdiv_cnt + 1);
|
||||
p1.x += x_ofs;
|
||||
if(div_i == div_i_start) p1.x += (style->line.width >> 1) + 1; /*The first line might not be visible*/
|
||||
if(div_i == div_i_end) p1.x -= (style->line.width >> 1) + 1; /*The last line might not be visible*/
|
||||
p1.x += x_ofs;
|
||||
if(div_i == div_i_start)
|
||||
p1.x += (style->line.width >> 1) + 1; /*The first line might not be visible*/
|
||||
if(div_i == div_i_end)
|
||||
p1.x -= (style->line.width >> 1) + 1; /*The last line might not be visible*/
|
||||
p2.x = p1.x;
|
||||
lv_draw_line(&p1, &p2, mask, style, opa_scale);
|
||||
}
|
||||
@ -686,8 +686,8 @@ static void lv_chart_draw_lines(lv_obj_t * chart, const lv_area_t * mask)
|
||||
uint16_t i;
|
||||
lv_point_t p1;
|
||||
lv_point_t p2;
|
||||
lv_coord_t w = lv_obj_get_width(chart);
|
||||
lv_coord_t h = lv_obj_get_height(chart);
|
||||
lv_coord_t w = lv_obj_get_width(chart);
|
||||
lv_coord_t h = lv_obj_get_height(chart);
|
||||
lv_coord_t x_ofs = chart->coords.x1;
|
||||
lv_coord_t y_ofs = chart->coords.y1;
|
||||
int32_t y_tmp;
|
||||
@ -697,22 +697,23 @@ static void lv_chart_draw_lines(lv_obj_t * chart, const lv_area_t * mask)
|
||||
lv_opa_t opa_scale = lv_obj_get_opa_scale(chart);
|
||||
lv_style_t style;
|
||||
lv_style_copy(&style, &lv_style_plain);
|
||||
style.line.opa = ext->series.opa;
|
||||
style.line.opa = ext->series.opa;
|
||||
style.line.width = ext->series.width;
|
||||
|
||||
/*Go through all data lines*/
|
||||
LV_LL_READ_BACK(ext->series_ll, ser) {
|
||||
LV_LL_READ_BACK(ext->series_ll, ser)
|
||||
{
|
||||
style.line.color = ser->color;
|
||||
|
||||
p1.x = 0 + x_ofs;
|
||||
p2.x = 0 + x_ofs;
|
||||
|
||||
p_prev = ser->start_point;
|
||||
y_tmp = (int32_t)((int32_t) ser->points[p_prev] - ext->ymin) * h;
|
||||
y_tmp = y_tmp / (ext->ymax - ext->ymin);
|
||||
p2.y = h - y_tmp + y_ofs;
|
||||
y_tmp = (int32_t)((int32_t)ser->points[p_prev] - ext->ymin) * h;
|
||||
y_tmp = y_tmp / (ext->ymax - ext->ymin);
|
||||
p2.y = h - y_tmp + y_ofs;
|
||||
|
||||
for(i = 1; i < ext->point_cnt; i ++) {
|
||||
for(i = 1; i < ext->point_cnt; i++) {
|
||||
p1.x = p2.x;
|
||||
p1.y = p2.y;
|
||||
|
||||
@ -720,11 +721,12 @@ static void lv_chart_draw_lines(lv_obj_t * chart, const lv_area_t * mask)
|
||||
|
||||
p_act = (ser->start_point + i) % ext->point_cnt;
|
||||
|
||||
y_tmp = (int32_t)((int32_t) ser->points[p_act] - ext->ymin) * h;
|
||||
y_tmp = (int32_t)((int32_t)ser->points[p_act] - ext->ymin) * h;
|
||||
y_tmp = y_tmp / (ext->ymax - ext->ymin);
|
||||
p2.y = h - y_tmp + y_ofs;
|
||||
p2.y = h - y_tmp + y_ofs;
|
||||
|
||||
if(ser->points[p_prev] != LV_CHART_POINT_DEF && ser->points[p_act] != LV_CHART_POINT_DEF)
|
||||
if(ser->points[p_prev] != LV_CHART_POINT_DEF &&
|
||||
ser->points[p_act] != LV_CHART_POINT_DEF)
|
||||
lv_draw_line(&p1, &p2, mask, &style, opa_scale);
|
||||
|
||||
p_prev = p_act;
|
||||
@ -743,8 +745,8 @@ static void lv_chart_draw_points(lv_obj_t * chart, const lv_area_t * mask)
|
||||
|
||||
uint16_t i;
|
||||
lv_area_t cir_a;
|
||||
lv_coord_t w = lv_obj_get_width(chart);
|
||||
lv_coord_t h = lv_obj_get_height(chart);
|
||||
lv_coord_t w = lv_obj_get_width(chart);
|
||||
lv_coord_t h = lv_obj_get_height(chart);
|
||||
lv_coord_t x_ofs = chart->coords.x1;
|
||||
lv_coord_t y_ofs = chart->coords.y1;
|
||||
int32_t y_tmp;
|
||||
@ -755,22 +757,23 @@ static void lv_chart_draw_points(lv_obj_t * chart, const lv_area_t * mask)
|
||||
lv_style_copy(&style_point, &lv_style_plain);
|
||||
|
||||
style_point.body.border.width = 0;
|
||||
style_point.body.radius = LV_RADIUS_CIRCLE;
|
||||
style_point.body.opa = ext->series.opa;
|
||||
style_point.body.radius = ext->series.width;
|
||||
style_point.body.radius = LV_RADIUS_CIRCLE;
|
||||
style_point.body.opa = ext->series.opa;
|
||||
style_point.body.radius = ext->series.width;
|
||||
|
||||
/*Go through all data lines*/
|
||||
LV_LL_READ_BACK(ext->series_ll, ser) {
|
||||
LV_LL_READ_BACK(ext->series_ll, ser)
|
||||
{
|
||||
style_point.body.main_color = ser->color;
|
||||
style_point.body.grad_color = lv_color_mix(LV_COLOR_BLACK, ser->color, ext->series.dark);
|
||||
|
||||
for(i = 0; i < ext->point_cnt; i ++) {
|
||||
for(i = 0; i < ext->point_cnt; i++) {
|
||||
cir_a.x1 = ((w * i) / (ext->point_cnt - 1)) + x_ofs;
|
||||
cir_a.x2 = cir_a.x1 + style_point.body.radius;
|
||||
cir_a.x1 -= style_point.body.radius;
|
||||
p_act = (ser->start_point + i) % ext->point_cnt;
|
||||
y_tmp = (int32_t)((int32_t) ser->points[p_act] - ext->ymin) * h;
|
||||
y_tmp = y_tmp / (ext->ymax - ext->ymin);
|
||||
p_act = (ser->start_point + i) % ext->point_cnt;
|
||||
y_tmp = (int32_t)((int32_t)ser->points[p_act] - ext->ymin) * h;
|
||||
y_tmp = y_tmp / (ext->ymax - ext->ymin);
|
||||
cir_a.y1 = h - y_tmp + y_ofs;
|
||||
cir_a.y2 = cir_a.y1 + style_point.body.radius;
|
||||
cir_a.y1 -= style_point.body.radius;
|
||||
@ -800,35 +803,37 @@ static void lv_chart_draw_cols(lv_obj_t * chart, const lv_area_t * mask)
|
||||
int32_t y_tmp;
|
||||
lv_chart_series_t * ser;
|
||||
lv_style_t rects;
|
||||
lv_coord_t col_w = w / ((ext->series.num + 1) * ext->point_cnt); /* Suppose + 1 series as separator*/
|
||||
lv_coord_t x_ofs = col_w / 2; /*Shift with a half col.*/
|
||||
lv_coord_t col_w =
|
||||
w / ((ext->series.num + 1) * ext->point_cnt); /* Suppose + 1 series as separator*/
|
||||
lv_coord_t x_ofs = col_w / 2; /*Shift with a half col.*/
|
||||
|
||||
lv_style_copy(&rects, &lv_style_plain);
|
||||
rects.body.border.width = 0;
|
||||
rects.body.radius = 0;
|
||||
rects.body.opa = ext->series.opa;
|
||||
rects.body.radius = 0;
|
||||
rects.body.opa = ext->series.opa;
|
||||
|
||||
col_a.y2 = chart->coords.y2;
|
||||
|
||||
lv_coord_t x_act;
|
||||
|
||||
/*Go through all points*/
|
||||
for(i = 0; i < ext->point_cnt; i ++) {
|
||||
x_act = (int32_t)((int32_t) w * i) / ext->point_cnt;
|
||||
for(i = 0; i < ext->point_cnt; i++) {
|
||||
x_act = (int32_t)((int32_t)w * i) / ext->point_cnt;
|
||||
x_act += chart->coords.x1 + x_ofs;
|
||||
|
||||
/*Draw the current point of all data line*/
|
||||
LV_LL_READ_BACK(ext->series_ll, ser) {
|
||||
LV_LL_READ_BACK(ext->series_ll, ser)
|
||||
{
|
||||
rects.body.main_color = ser->color;
|
||||
rects.body.grad_color = lv_color_mix(LV_COLOR_BLACK, ser->color, ext->series.dark);
|
||||
col_a.x1 = x_act;
|
||||
col_a.x2 = col_a.x1 + col_w;
|
||||
col_a.x1 = x_act;
|
||||
col_a.x2 = col_a.x1 + col_w;
|
||||
x_act += col_w;
|
||||
|
||||
lv_coord_t p_act = (ser->start_point + i) % ext->point_cnt;
|
||||
y_tmp = (int32_t)((int32_t) ser->points[p_act] - ext->ymin) * h;
|
||||
y_tmp = y_tmp / (ext->ymax - ext->ymin);
|
||||
col_a.y1 = h - y_tmp + chart->coords.y1;
|
||||
y_tmp = (int32_t)((int32_t)ser->points[p_act] - ext->ymin) * h;
|
||||
y_tmp = y_tmp / (ext->ymax - ext->ymin);
|
||||
col_a.y1 = h - y_tmp + chart->coords.y1;
|
||||
|
||||
mask_ret = lv_area_intersect(&col_mask, mask, &col_a);
|
||||
if(mask_ret != false && ser->points[p_act] != LV_CHART_POINT_DEF) {
|
||||
@ -846,7 +851,7 @@ static void lv_chart_draw_vertical_lines(lv_obj_t * chart, const lv_area_t * mas
|
||||
{
|
||||
|
||||
lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart);
|
||||
lv_coord_t w = lv_obj_get_width(chart);
|
||||
lv_coord_t w = lv_obj_get_width(chart);
|
||||
/*Vertical lines works only if the width == point count. Else use the normal line type*/
|
||||
if(ext->point_cnt != w) {
|
||||
lv_chart_draw_lines(chart, mask);
|
||||
@ -856,7 +861,7 @@ static void lv_chart_draw_vertical_lines(lv_obj_t * chart, const lv_area_t * mas
|
||||
uint16_t i;
|
||||
lv_point_t p1;
|
||||
lv_point_t p2;
|
||||
lv_coord_t h = lv_obj_get_height(chart);
|
||||
lv_coord_t h = lv_obj_get_height(chart);
|
||||
lv_coord_t x_ofs = chart->coords.x1;
|
||||
lv_coord_t y_ofs = chart->coords.y1;
|
||||
int32_t y_tmp;
|
||||
@ -864,29 +869,28 @@ static void lv_chart_draw_vertical_lines(lv_obj_t * chart, const lv_area_t * mas
|
||||
lv_opa_t opa_scale = lv_obj_get_opa_scale(chart);
|
||||
lv_style_t style;
|
||||
lv_style_copy(&style, &lv_style_plain);
|
||||
style.line.opa = ext->series.opa;
|
||||
style.line.opa = ext->series.opa;
|
||||
style.line.width = ext->series.width;
|
||||
|
||||
/*Go through all data lines*/
|
||||
LV_LL_READ_BACK(ext->series_ll, ser) {
|
||||
LV_LL_READ_BACK(ext->series_ll, ser)
|
||||
{
|
||||
style.line.color = ser->color;
|
||||
|
||||
p1.x = 0 + x_ofs;
|
||||
p2.x = 0 + x_ofs;
|
||||
y_tmp = (int32_t)((int32_t) ser->points[0] - ext->ymin) * h;
|
||||
p1.x = 0 + x_ofs;
|
||||
p2.x = 0 + x_ofs;
|
||||
y_tmp = (int32_t)((int32_t)ser->points[0] - ext->ymin) * h;
|
||||
y_tmp = y_tmp / (ext->ymax - ext->ymin);
|
||||
p2.y = h - y_tmp + y_ofs;
|
||||
p1.y = p2.y;
|
||||
p2.y = h - y_tmp + y_ofs;
|
||||
p1.y = p2.y;
|
||||
|
||||
for(i = 0; i < ext->point_cnt; i++)
|
||||
{
|
||||
for(i = 0; i < ext->point_cnt; i++) {
|
||||
|
||||
y_tmp = (int32_t)((int32_t) ser->points[i] - ext->ymin) * h;
|
||||
y_tmp = (int32_t)((int32_t)ser->points[i] - ext->ymin) * h;
|
||||
y_tmp = y_tmp / (ext->ymax - ext->ymin);
|
||||
p2.y = h - y_tmp + y_ofs;
|
||||
p2.y = h - y_tmp + y_ofs;
|
||||
|
||||
if(p1.y == p2.y)
|
||||
{
|
||||
if(p1.y == p2.y) {
|
||||
p2.x++;
|
||||
}
|
||||
|
||||
@ -912,8 +916,8 @@ static void lv_chart_draw_areas(lv_obj_t * chart, const lv_area_t * mask)
|
||||
uint16_t i;
|
||||
lv_point_t p1;
|
||||
lv_point_t p2;
|
||||
lv_coord_t w = lv_obj_get_width(chart);
|
||||
lv_coord_t h = lv_obj_get_height(chart);
|
||||
lv_coord_t w = lv_obj_get_width(chart);
|
||||
lv_coord_t h = lv_obj_get_height(chart);
|
||||
lv_coord_t x_ofs = chart->coords.x1;
|
||||
lv_coord_t y_ofs = chart->coords.y1;
|
||||
int32_t y_tmp;
|
||||
@ -925,31 +929,33 @@ static void lv_chart_draw_areas(lv_obj_t * chart, const lv_area_t * mask)
|
||||
lv_style_copy(&style, &lv_style_plain);
|
||||
|
||||
/*Go through all data lines*/
|
||||
LV_LL_READ_BACK(ext->series_ll, ser) {
|
||||
LV_LL_READ_BACK(ext->series_ll, ser)
|
||||
{
|
||||
style.body.main_color = ser->color;
|
||||
|
||||
p1.x = 0 + x_ofs;
|
||||
p2.x = 0 + x_ofs;
|
||||
|
||||
p_prev = ser->start_point;
|
||||
y_tmp = (int32_t)((int32_t) ser->points[p_prev] - ext->ymin) * h;
|
||||
y_tmp = y_tmp / (ext->ymax - ext->ymin);
|
||||
p2.y = h - y_tmp + y_ofs;
|
||||
y_tmp = (int32_t)((int32_t)ser->points[p_prev] - ext->ymin) * h;
|
||||
y_tmp = y_tmp / (ext->ymax - ext->ymin);
|
||||
p2.y = h - y_tmp + y_ofs;
|
||||
|
||||
for(i = 1; i < ext->point_cnt; i ++) {
|
||||
for(i = 1; i < ext->point_cnt; i++) {
|
||||
p1.x = p2.x;
|
||||
p1.y = p2.y;
|
||||
|
||||
p2.x = ((w * i) / (ext->point_cnt - 1)) + x_ofs;
|
||||
p2.x = ((w * i) / (ext->point_cnt - 1)) + x_ofs;
|
||||
p_act = (ser->start_point + i) % ext->point_cnt;
|
||||
|
||||
y_tmp = (int32_t)((int32_t) ser->points[p_act] - ext->ymin) * h;
|
||||
y_tmp = (int32_t)((int32_t)ser->points[p_act] - ext->ymin) * h;
|
||||
y_tmp = y_tmp / (ext->ymax - ext->ymin);
|
||||
p2.y = h - y_tmp + y_ofs;
|
||||
p2.y = h - y_tmp + y_ofs;
|
||||
|
||||
if(ser->points[p_prev] != LV_CHART_POINT_DEF && ser->points[p_act] != LV_CHART_POINT_DEF) {
|
||||
if(ser->points[p_prev] != LV_CHART_POINT_DEF &&
|
||||
ser->points[p_act] != LV_CHART_POINT_DEF) {
|
||||
lv_point_t triangle_points[3];
|
||||
triangle_points[0] = p1;
|
||||
triangle_points[0] = p1;
|
||||
triangle_points[1].x = p2.x;
|
||||
triangle_points[1].y = y_ofs + h;
|
||||
triangle_points[2].x = p1.x;
|
||||
@ -970,9 +976,9 @@ static void lv_chart_draw_y_ticks(lv_obj_t * chart, const lv_area_t * mask)
|
||||
if(ext->y_axis.list_of_values != NULL || ext->y_axis.num_tick_marks != 0) {
|
||||
|
||||
const lv_style_t * style = lv_obj_get_style(chart);
|
||||
lv_opa_t opa_scale = lv_obj_get_opa_scale(chart);
|
||||
lv_opa_t opa_scale = lv_obj_get_opa_scale(chart);
|
||||
|
||||
uint8_t i,j;
|
||||
uint8_t i, j;
|
||||
uint8_t list_index;
|
||||
uint8_t num_of_labels;
|
||||
uint8_t num_scale_ticks;
|
||||
@ -981,96 +987,95 @@ static void lv_chart_draw_y_ticks(lv_obj_t * chart, const lv_area_t * mask)
|
||||
lv_point_t p2;
|
||||
lv_coord_t x_ofs = chart->coords.x1;
|
||||
lv_coord_t y_ofs = chart->coords.y1;
|
||||
lv_coord_t h = lv_obj_get_height(chart);
|
||||
lv_coord_t w = lv_obj_get_width(chart);
|
||||
char buf[LV_CHART_AXIS_TICK_LABEL_MAX_LEN+1]; /* up to N symbols per label + null terminator */
|
||||
lv_coord_t h = lv_obj_get_height(chart);
|
||||
lv_coord_t w = lv_obj_get_width(chart);
|
||||
char buf[LV_CHART_AXIS_TICK_LABEL_MAX_LEN +
|
||||
1]; /* up to N symbols per label + null terminator */
|
||||
|
||||
/* calculate the size of tick marks */
|
||||
if(ext->y_axis.major_tick_len == 0)
|
||||
major_tick_len = (int32_t)w * LV_CHART_AXIS_MAJOR_TICK_LEN_COE;
|
||||
major_tick_len = (int32_t)w * LV_CHART_AXIS_MAJOR_TICK_LEN_COE;
|
||||
else
|
||||
major_tick_len = ext->y_axis.major_tick_len;
|
||||
major_tick_len = ext->y_axis.major_tick_len;
|
||||
|
||||
if(ext->y_axis.minor_tick_len == 0)
|
||||
minor_tick_len = major_tick_len * LV_CHART_AXIS_MINOR_TICK_LEN_COE;
|
||||
minor_tick_len = major_tick_len * LV_CHART_AXIS_MINOR_TICK_LEN_COE;
|
||||
else
|
||||
minor_tick_len = ext->y_axis.minor_tick_len;
|
||||
minor_tick_len = ext->y_axis.minor_tick_len;
|
||||
|
||||
/* count the '\n'-s to determine the number of options */
|
||||
list_index = 0;
|
||||
list_index = 0;
|
||||
num_of_labels = 0;
|
||||
if(ext->y_axis.list_of_values != NULL)
|
||||
{
|
||||
for(j = 0; ext->y_axis.list_of_values[j] != '\0'; j++) {
|
||||
if(ext->y_axis.list_of_values[j] == '\n')
|
||||
num_of_labels++;
|
||||
}
|
||||
if(ext->y_axis.list_of_values != NULL) {
|
||||
for(j = 0; ext->y_axis.list_of_values[j] != '\0'; j++) {
|
||||
if(ext->y_axis.list_of_values[j] == '\n') num_of_labels++;
|
||||
}
|
||||
|
||||
num_of_labels++; /* last option in the at row*/
|
||||
num_of_labels++; /* last option in the at row*/
|
||||
}
|
||||
|
||||
/* we can't have string labels without ticks step, set to 1 if not specified */
|
||||
if(ext->y_axis.num_tick_marks == 0)
|
||||
ext->y_axis.num_tick_marks = 1;
|
||||
if(ext->y_axis.num_tick_marks == 0) ext->y_axis.num_tick_marks = 1;
|
||||
|
||||
/* calculate total number of ticks */
|
||||
if(num_of_labels < 2)
|
||||
num_scale_ticks = ext->y_axis.num_tick_marks;
|
||||
num_scale_ticks = ext->y_axis.num_tick_marks;
|
||||
else
|
||||
num_scale_ticks = (ext->y_axis.num_tick_marks * (num_of_labels - 1));
|
||||
num_scale_ticks = (ext->y_axis.num_tick_marks * (num_of_labels - 1));
|
||||
|
||||
for(i = 0; i < (num_scale_ticks + 1); i++ ) { /* one extra loop - it may not exist in the list, empty label */
|
||||
/* first point of the tick */
|
||||
for(i = 0; i < (num_scale_ticks + 1);
|
||||
i++) { /* one extra loop - it may not exist in the list, empty label */
|
||||
/* first point of the tick */
|
||||
p1.x = 0 + x_ofs;
|
||||
|
||||
/* second point of the tick */
|
||||
if( (num_of_labels != 0) && (i == 0 || i % ext->y_axis.num_tick_marks == 0) )
|
||||
p2.x = p1.x - major_tick_len; /* major tick */
|
||||
else
|
||||
p2.x = p1.x - minor_tick_len; /* minor tick */
|
||||
/* second point of the tick */
|
||||
if((num_of_labels != 0) && (i == 0 || i % ext->y_axis.num_tick_marks == 0))
|
||||
p2.x = p1.x - major_tick_len; /* major tick */
|
||||
else
|
||||
p2.x = p1.x - minor_tick_len; /* minor tick */
|
||||
|
||||
/* draw a line at moving y position */
|
||||
p2.y = p1.y = y_ofs + h - (int32_t)(((int32_t)h * i) / num_scale_ticks + 1) - LV_CHART_AXIS_Y_TICK_OFFSET_FIX;
|
||||
p2.y = p1.y = y_ofs + h - (int32_t)(((int32_t)h * i) / num_scale_ticks + 1) -
|
||||
LV_CHART_AXIS_Y_TICK_OFFSET_FIX;
|
||||
|
||||
if( i != num_scale_ticks )
|
||||
lv_draw_line(&p1, &p2, mask, style, opa_scale);
|
||||
else
|
||||
if( (ext->y_axis.options & LV_CHART_AXIS_DRAW_LAST_TICK) != 0 )
|
||||
lv_draw_line(&p1, &p2, mask, style, opa_scale);
|
||||
if(i != num_scale_ticks)
|
||||
lv_draw_line(&p1, &p2, mask, style, opa_scale);
|
||||
else if((ext->y_axis.options & LV_CHART_AXIS_DRAW_LAST_TICK) != 0)
|
||||
lv_draw_line(&p1, &p2, mask, style, opa_scale);
|
||||
|
||||
/* draw values if available */
|
||||
if (num_of_labels != 0)
|
||||
{
|
||||
/* add text only to major tick */
|
||||
if( i == 0 || i % ext->y_axis.num_tick_marks == 0 )
|
||||
{
|
||||
/* search for tick string */
|
||||
j = 0;
|
||||
while( ext->y_axis.list_of_values[list_index] != '\n' &&
|
||||
ext->y_axis.list_of_values[list_index] != '\0')
|
||||
{
|
||||
/* do not overflow the buffer, but move to the end of the current label */
|
||||
if(j < LV_CHART_AXIS_TICK_LABEL_MAX_LEN)
|
||||
buf[j++] = ext->y_axis.list_of_values[list_index++];
|
||||
else
|
||||
list_index++;
|
||||
}
|
||||
if(num_of_labels != 0) {
|
||||
/* add text only to major tick */
|
||||
if(i == 0 || i % ext->y_axis.num_tick_marks == 0) {
|
||||
/* search for tick string */
|
||||
j = 0;
|
||||
while(ext->y_axis.list_of_values[list_index] != '\n' &&
|
||||
ext->y_axis.list_of_values[list_index] != '\0') {
|
||||
/* do not overflow the buffer, but move to the end of the current label */
|
||||
if(j < LV_CHART_AXIS_TICK_LABEL_MAX_LEN)
|
||||
buf[j++] = ext->y_axis.list_of_values[list_index++];
|
||||
else
|
||||
list_index++;
|
||||
}
|
||||
|
||||
/* this was a string, but not end of the list, so jump to the next string */
|
||||
if(ext->y_axis.list_of_values[list_index] == '\n')
|
||||
list_index++;
|
||||
/* this was a string, but not end of the list, so jump to the next string */
|
||||
if(ext->y_axis.list_of_values[list_index] == '\n') list_index++;
|
||||
|
||||
/* terminate the string */
|
||||
buf[j] = '\0';
|
||||
/* terminate the string */
|
||||
buf[j] = '\0';
|
||||
|
||||
/* reserve appropriate area */
|
||||
lv_point_t size;
|
||||
lv_txt_get_size(&size, buf, style->text.font, style->text.letter_space, style->text.line_space, LV_COORD_MAX, LV_TXT_FLAG_CENTER);
|
||||
/* reserve appropriate area */
|
||||
lv_point_t size;
|
||||
lv_txt_get_size(&size, buf, style->text.font, style->text.letter_space,
|
||||
style->text.line_space, LV_COORD_MAX, LV_TXT_FLAG_CENTER);
|
||||
|
||||
/* set the area at some distance of the major tick len left of the tick */
|
||||
lv_area_t a = {(p2.x - size.x - LV_CHART_AXIS_TO_LABEL_DISTANCE) , (p2.y - size.y/2), (p2.x - LV_CHART_AXIS_TO_LABEL_DISTANCE), (p2.y + size.y/2) };
|
||||
lv_draw_label(&a, mask, style, opa_scale, buf, LV_TXT_FLAG_CENTER, NULL, -1, -1);
|
||||
}
|
||||
/* set the area at some distance of the major tick len left of the tick */
|
||||
lv_area_t a = {(p2.x - size.x - LV_CHART_AXIS_TO_LABEL_DISTANCE),
|
||||
(p2.y - size.y / 2), (p2.x - LV_CHART_AXIS_TO_LABEL_DISTANCE),
|
||||
(p2.y + size.y / 2)};
|
||||
lv_draw_label(&a, mask, style, opa_scale, buf, LV_TXT_FLAG_CENTER, NULL, -1,
|
||||
-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1084,9 +1089,9 @@ static void lv_chart_draw_x_ticks(lv_obj_t * chart, const lv_area_t * mask)
|
||||
if(ext->x_axis.list_of_values != NULL || ext->x_axis.num_tick_marks != 0) {
|
||||
|
||||
const lv_style_t * style = lv_obj_get_style(chart);
|
||||
lv_opa_t opa_scale = lv_obj_get_opa_scale(chart);
|
||||
lv_opa_t opa_scale = lv_obj_get_opa_scale(chart);
|
||||
|
||||
uint8_t i,j;
|
||||
uint8_t i, j;
|
||||
uint8_t list_index;
|
||||
uint8_t num_of_labels;
|
||||
uint8_t num_scale_ticks;
|
||||
@ -1095,96 +1100,95 @@ static void lv_chart_draw_x_ticks(lv_obj_t * chart, const lv_area_t * mask)
|
||||
lv_point_t p2;
|
||||
lv_coord_t x_ofs = chart->coords.x1;
|
||||
lv_coord_t y_ofs = chart->coords.y1;
|
||||
lv_coord_t h = lv_obj_get_height(chart);
|
||||
lv_coord_t w = lv_obj_get_width(chart);
|
||||
char buf[LV_CHART_AXIS_TICK_LABEL_MAX_LEN+1]; /* up to N symbols per label + null terminator */
|
||||
lv_coord_t h = lv_obj_get_height(chart);
|
||||
lv_coord_t w = lv_obj_get_width(chart);
|
||||
char buf[LV_CHART_AXIS_TICK_LABEL_MAX_LEN +
|
||||
1]; /* up to N symbols per label + null terminator */
|
||||
|
||||
/* calculate the size of tick marks */
|
||||
if(ext->x_axis.major_tick_len == 0)
|
||||
major_tick_len = (int32_t)w * LV_CHART_AXIS_MAJOR_TICK_LEN_COE;
|
||||
major_tick_len = (int32_t)w * LV_CHART_AXIS_MAJOR_TICK_LEN_COE;
|
||||
else
|
||||
major_tick_len = ext->x_axis.major_tick_len;
|
||||
major_tick_len = ext->x_axis.major_tick_len;
|
||||
|
||||
if(ext->x_axis.minor_tick_len == 0)
|
||||
minor_tick_len = major_tick_len * LV_CHART_AXIS_MINOR_TICK_LEN_COE;
|
||||
minor_tick_len = major_tick_len * LV_CHART_AXIS_MINOR_TICK_LEN_COE;
|
||||
else
|
||||
minor_tick_len = ext->x_axis.minor_tick_len;
|
||||
minor_tick_len = ext->x_axis.minor_tick_len;
|
||||
|
||||
/* count the '\n'-s to determine the number of options */
|
||||
list_index = 0;
|
||||
list_index = 0;
|
||||
num_of_labels = 0;
|
||||
if(ext->x_axis.list_of_values != NULL)
|
||||
{
|
||||
for(j = 0; ext->x_axis.list_of_values[j] != '\0'; j++) {
|
||||
if(ext->x_axis.list_of_values[j] == '\n')
|
||||
num_of_labels++;
|
||||
}
|
||||
if(ext->x_axis.list_of_values != NULL) {
|
||||
for(j = 0; ext->x_axis.list_of_values[j] != '\0'; j++) {
|
||||
if(ext->x_axis.list_of_values[j] == '\n') num_of_labels++;
|
||||
}
|
||||
|
||||
num_of_labels++; /* last option in the at row*/
|
||||
num_of_labels++; /* last option in the at row*/
|
||||
}
|
||||
|
||||
/* we can't have string labels without ticks step, set to 1 if not specified */
|
||||
if(ext->x_axis.num_tick_marks == 0)
|
||||
ext->x_axis.num_tick_marks = 1;
|
||||
if(ext->x_axis.num_tick_marks == 0) ext->x_axis.num_tick_marks = 1;
|
||||
|
||||
/* calculate total number of marks */
|
||||
if(num_of_labels < 2)
|
||||
num_scale_ticks = ext->x_axis.num_tick_marks;
|
||||
num_scale_ticks = ext->x_axis.num_tick_marks;
|
||||
else
|
||||
num_scale_ticks = (ext->x_axis.num_tick_marks * (num_of_labels - 1));
|
||||
num_scale_ticks = (ext->x_axis.num_tick_marks * (num_of_labels - 1));
|
||||
|
||||
for(i = 0; i < (num_scale_ticks + 1); i++ ) { /* one extra loop - it may not exist in the list, empty label */
|
||||
/* first point of the tick */
|
||||
for(i = 0; i < (num_scale_ticks + 1);
|
||||
i++) { /* one extra loop - it may not exist in the list, empty label */
|
||||
/* first point of the tick */
|
||||
p1.y = h + y_ofs;
|
||||
|
||||
/* second point of the tick */
|
||||
if( (num_of_labels != 0) && (i == 0 || i % ext->x_axis.num_tick_marks == 0) )
|
||||
p2.y = p1.y + major_tick_len; /* major tick */
|
||||
else
|
||||
p2.y = p1.y + minor_tick_len; /* minor tick */
|
||||
/* second point of the tick */
|
||||
if((num_of_labels != 0) && (i == 0 || i % ext->x_axis.num_tick_marks == 0))
|
||||
p2.y = p1.y + major_tick_len; /* major tick */
|
||||
else
|
||||
p2.y = p1.y + minor_tick_len; /* minor tick */
|
||||
|
||||
/* draw a line at moving x position */
|
||||
p2.x = p1.x = x_ofs + (int32_t)(((int32_t)w * i) / num_scale_ticks + 1) - LV_CHART_AXIS_X_TICK_OFFSET_FIX;
|
||||
p2.x = p1.x = x_ofs + (int32_t)(((int32_t)w * i) / num_scale_ticks + 1) -
|
||||
LV_CHART_AXIS_X_TICK_OFFSET_FIX;
|
||||
|
||||
if( i != num_scale_ticks )
|
||||
lv_draw_line(&p1, &p2, mask, style, opa_scale);
|
||||
else
|
||||
if( (ext->x_axis.options & LV_CHART_AXIS_DRAW_LAST_TICK) != 0 )
|
||||
lv_draw_line(&p1, &p2, mask, style, opa_scale);
|
||||
if(i != num_scale_ticks)
|
||||
lv_draw_line(&p1, &p2, mask, style, opa_scale);
|
||||
else if((ext->x_axis.options & LV_CHART_AXIS_DRAW_LAST_TICK) != 0)
|
||||
lv_draw_line(&p1, &p2, mask, style, opa_scale);
|
||||
|
||||
/* draw values if available */
|
||||
if (num_of_labels != 0)
|
||||
{
|
||||
/* add text only to major tick */
|
||||
if( i == 0 || i % ext->x_axis.num_tick_marks == 0 )
|
||||
{
|
||||
/* search for tick string */
|
||||
j = 0;
|
||||
while( ext->x_axis.list_of_values[list_index] != '\n' &&
|
||||
ext->x_axis.list_of_values[list_index] != '\0')
|
||||
{
|
||||
/* do not overflow the buffer, but move to the end of the current label */
|
||||
if(j < LV_CHART_AXIS_TICK_LABEL_MAX_LEN)
|
||||
buf[j++] = ext->x_axis.list_of_values[list_index++];
|
||||
else
|
||||
list_index++;
|
||||
}
|
||||
if(num_of_labels != 0) {
|
||||
/* add text only to major tick */
|
||||
if(i == 0 || i % ext->x_axis.num_tick_marks == 0) {
|
||||
/* search for tick string */
|
||||
j = 0;
|
||||
while(ext->x_axis.list_of_values[list_index] != '\n' &&
|
||||
ext->x_axis.list_of_values[list_index] != '\0') {
|
||||
/* do not overflow the buffer, but move to the end of the current label */
|
||||
if(j < LV_CHART_AXIS_TICK_LABEL_MAX_LEN)
|
||||
buf[j++] = ext->x_axis.list_of_values[list_index++];
|
||||
else
|
||||
list_index++;
|
||||
}
|
||||
|
||||
/* this was a string, but not end of the list, so jump to the next string */
|
||||
if(ext->x_axis.list_of_values[list_index] == '\n')
|
||||
list_index++;
|
||||
/* this was a string, but not end of the list, so jump to the next string */
|
||||
if(ext->x_axis.list_of_values[list_index] == '\n') list_index++;
|
||||
|
||||
/* terminate the string */
|
||||
buf[j] = '\0';
|
||||
/* terminate the string */
|
||||
buf[j] = '\0';
|
||||
|
||||
/* reserve appropriate area */
|
||||
lv_point_t size;
|
||||
lv_txt_get_size(&size, buf, style->text.font, style->text.letter_space, style->text.line_space, LV_COORD_MAX, LV_TXT_FLAG_CENTER);
|
||||
/* reserve appropriate area */
|
||||
lv_point_t size;
|
||||
lv_txt_get_size(&size, buf, style->text.font, style->text.letter_space,
|
||||
style->text.line_space, LV_COORD_MAX, LV_TXT_FLAG_CENTER);
|
||||
|
||||
/* set the area at some distance of the major tick len under of the tick */
|
||||
lv_area_t a = { (p2.x - size.x/2) , (p2.y + LV_CHART_AXIS_TO_LABEL_DISTANCE), (p2.x + size.x/2), (p2.y + size.y + LV_CHART_AXIS_TO_LABEL_DISTANCE) };
|
||||
lv_draw_label(&a, mask, style, opa_scale, buf, LV_TXT_FLAG_CENTER, NULL, -1, -1);
|
||||
}
|
||||
/* set the area at some distance of the major tick len under of the tick */
|
||||
lv_area_t a = {(p2.x - size.x / 2), (p2.y + LV_CHART_AXIS_TO_LABEL_DISTANCE),
|
||||
(p2.x + size.x / 2),
|
||||
(p2.y + size.y + LV_CHART_AXIS_TO_LABEL_DISTANCE)};
|
||||
lv_draw_label(&a, mask, style, opa_scale, buf, LV_TXT_FLAG_CENTER, NULL, -1,
|
||||
-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -27,20 +27,20 @@ extern "C" {
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define LV_CHART_POINT_DEF (LV_COORD_MIN)
|
||||
#define LV_CHART_POINT_DEF (LV_COORD_MIN)
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/*Chart types*/
|
||||
enum
|
||||
{
|
||||
LV_CHART_TYPE_LINE = 0x01, /*Connect the points with lines*/
|
||||
LV_CHART_TYPE_COLUMN = 0x02, /*Draw columns*/
|
||||
LV_CHART_TYPE_POINT = 0x04, /*Draw circles on the points*/
|
||||
LV_CHART_TYPE_VERTICAL_LINE = 0x08, /*Draw vertical lines on points (useful when chart width == point count)*/
|
||||
LV_CHART_TYPE_AREA = 0x10, /*Draw area chart*/
|
||||
enum {
|
||||
LV_CHART_TYPE_LINE = 0x01, /*Connect the points with lines*/
|
||||
LV_CHART_TYPE_COLUMN = 0x02, /*Draw columns*/
|
||||
LV_CHART_TYPE_POINT = 0x04, /*Draw circles on the points*/
|
||||
LV_CHART_TYPE_VERTICAL_LINE =
|
||||
0x08, /*Draw vertical lines on points (useful when chart width == point count)*/
|
||||
LV_CHART_TYPE_AREA = 0x10, /*Draw area chart*/
|
||||
};
|
||||
typedef uint8_t lv_chart_type_t;
|
||||
|
||||
@ -52,19 +52,18 @@ typedef struct
|
||||
} lv_chart_series_t;
|
||||
|
||||
/*Data of axis */
|
||||
enum
|
||||
{
|
||||
LV_CHART_AXIS_DRAW_LAST_TICK = 0x01 /* draw the last tick */
|
||||
enum {
|
||||
LV_CHART_AXIS_DRAW_LAST_TICK = 0x01 /* draw the last tick */
|
||||
};
|
||||
typedef uint8_t lv_chart_axis_options_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
const char* list_of_values;
|
||||
uint8_t num_tick_marks;
|
||||
lv_chart_axis_options_t options;
|
||||
uint8_t major_tick_len;
|
||||
uint8_t minor_tick_len;
|
||||
const char * list_of_values;
|
||||
uint8_t num_tick_marks;
|
||||
lv_chart_axis_options_t options;
|
||||
uint8_t major_tick_len;
|
||||
uint8_t minor_tick_len;
|
||||
} lv_chart_axis_cfg_t;
|
||||
|
||||
/*Data of chart */
|
||||
@ -72,26 +71,25 @@ typedef struct
|
||||
{
|
||||
/*No inherited ext*/ /*Ext. of ancestor*/
|
||||
/*New data for this type */
|
||||
lv_ll_t series_ll; /*Linked list for the data line pointers (stores lv_chart_dl_t)*/
|
||||
lv_coord_t ymin; /*y min value (used to scale the data)*/
|
||||
lv_coord_t ymax; /*y max value (used to scale the data)*/
|
||||
uint8_t hdiv_cnt; /*Number of horizontal division lines*/
|
||||
uint8_t vdiv_cnt; /*Number of vertical division lines*/
|
||||
uint16_t point_cnt; /*Point number in a data line*/
|
||||
lv_chart_type_t type; /*Line, column or point chart (from 'lv_chart_type_t')*/
|
||||
lv_ll_t series_ll; /*Linked list for the data line pointers (stores lv_chart_dl_t)*/
|
||||
lv_coord_t ymin; /*y min value (used to scale the data)*/
|
||||
lv_coord_t ymax; /*y max value (used to scale the data)*/
|
||||
uint8_t hdiv_cnt; /*Number of horizontal division lines*/
|
||||
uint8_t vdiv_cnt; /*Number of vertical division lines*/
|
||||
uint16_t point_cnt; /*Point number in a data line*/
|
||||
lv_chart_type_t type; /*Line, column or point chart (from 'lv_chart_type_t')*/
|
||||
lv_chart_axis_cfg_t y_axis;
|
||||
lv_chart_axis_cfg_t x_axis;
|
||||
uint16_t margin;
|
||||
struct {
|
||||
lv_coord_t width; /*Line width or point radius*/
|
||||
uint8_t num; /*Number of data lines in dl_ll*/
|
||||
lv_opa_t opa; /*Opacity of data lines*/
|
||||
lv_opa_t dark; /*Dark level of the point/column bottoms*/
|
||||
struct
|
||||
{
|
||||
lv_coord_t width; /*Line width or point radius*/
|
||||
uint8_t num; /*Number of data lines in dl_ll*/
|
||||
lv_opa_t opa; /*Opacity of data lines*/
|
||||
lv_opa_t dark; /*Dark level of the point/column bottoms*/
|
||||
} series;
|
||||
} lv_chart_ext_t;
|
||||
|
||||
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
@ -99,7 +97,8 @@ typedef struct
|
||||
/**
|
||||
* Create a chart background objects
|
||||
* @param par pointer to an object, it will be the parent of the new chart background
|
||||
* @param copy pointer to a chart background object, if not NULL then the new object will be copied from it
|
||||
* @param copy pointer to a chart background object, if not NULL then the new object will be copied
|
||||
* from it
|
||||
* @return pointer to the created chart background
|
||||
*/
|
||||
lv_obj_t * lv_chart_create(lv_obj_t * par, const lv_obj_t * copy);
|
||||
@ -207,7 +206,7 @@ void lv_chart_set_next(lv_obj_t * chart, lv_chart_series_t * ser, lv_coord_t y);
|
||||
* @param chart pointer to a chart object
|
||||
* @param style pointer to a style
|
||||
*/
|
||||
static inline void lv_chart_set_style(lv_obj_t *chart, lv_style_t *style)
|
||||
static inline void lv_chart_set_style(lv_obj_t * chart, lv_style_t * style)
|
||||
{
|
||||
lv_obj_set_style(chart, style);
|
||||
}
|
||||
@ -217,7 +216,7 @@ static inline void lv_chart_set_style(lv_obj_t *chart, lv_style_t *style)
|
||||
* @param chart pointer to an chart object
|
||||
* @param margin value of the margin
|
||||
*/
|
||||
void lv_chart_set_margin(lv_obj_t* chart, uint16_t margin);
|
||||
void lv_chart_set_margin(lv_obj_t * chart, uint16_t margin);
|
||||
|
||||
/**
|
||||
* Set the x/y-axis ticks of a chart
|
||||
@ -229,19 +228,13 @@ void lv_chart_set_margin(lv_obj_t* chart, uint16_t margin);
|
||||
* @param minor_tick_len the length of the minor tick, AUTO if 0
|
||||
* @param options extra options
|
||||
*/
|
||||
void lv_chart_set_x_ticks( lv_obj_t* chart,
|
||||
const char* list_of_values,
|
||||
uint8_t num_tick_marks,
|
||||
uint8_t major_tick_len,
|
||||
uint8_t minor_tick_len,
|
||||
lv_chart_axis_options_t options);
|
||||
void lv_chart_set_x_ticks(lv_obj_t * chart, const char * list_of_values, uint8_t num_tick_marks,
|
||||
uint8_t major_tick_len, uint8_t minor_tick_len,
|
||||
lv_chart_axis_options_t options);
|
||||
|
||||
void lv_chart_set_y_ticks( lv_obj_t* chart,
|
||||
const char* list_of_values,
|
||||
uint8_t num_tick_marks,
|
||||
uint8_t major_tick_len,
|
||||
uint8_t minor_tick_len,
|
||||
lv_chart_axis_options_t options);
|
||||
void lv_chart_set_y_ticks(lv_obj_t * chart, const char * list_of_values, uint8_t num_tick_marks,
|
||||
uint8_t major_tick_len, uint8_t minor_tick_len,
|
||||
lv_chart_axis_options_t options);
|
||||
|
||||
/*=====================
|
||||
* Getter functions
|
||||
@ -287,7 +280,7 @@ lv_opa_t lv_chart_get_series_darking(const lv_obj_t * chart);
|
||||
* @param chart pointer to an chart object
|
||||
* @return pointer to the chart's style
|
||||
*/
|
||||
static inline lv_style_t* lv_chart_get_style(const lv_obj_t *chart)
|
||||
static inline lv_style_t * lv_chart_get_style(const lv_obj_t * chart)
|
||||
{
|
||||
return lv_obj_get_style(chart);
|
||||
}
|
||||
@ -297,7 +290,7 @@ static inline lv_style_t* lv_chart_get_style(const lv_obj_t *chart)
|
||||
* @param chart pointer to an chart object
|
||||
* @param return value of the margin
|
||||
*/
|
||||
uint16_t lv_chart_get_margin(lv_obj_t* chart);
|
||||
uint16_t lv_chart_get_margin(lv_obj_t * chart);
|
||||
|
||||
/*=====================
|
||||
* Other functions
|
||||
@ -313,10 +306,10 @@ void lv_chart_refresh(lv_obj_t * chart);
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_CHART*/
|
||||
#endif /*LV_USE_CHART*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_CHART_H*/
|
||||
#endif /*LV_CHART_H*/
|
||||
|
@ -63,7 +63,6 @@ static lv_signal_cb_t ancestor_signal;
|
||||
lv_obj_t * lv_cont_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
{
|
||||
|
||||
|
||||
LV_LOG_TRACE("container create started");
|
||||
|
||||
/*Create a basic object*/
|
||||
@ -78,11 +77,11 @@ lv_obj_t * lv_cont_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
if(ext == NULL) return NULL;
|
||||
|
||||
lv_mem_assert(ext);
|
||||
ext->fit_left = LV_FIT_NONE;
|
||||
ext->fit_right = LV_FIT_NONE;
|
||||
ext->fit_top = LV_FIT_NONE;
|
||||
ext->fit_left = LV_FIT_NONE;
|
||||
ext->fit_right = LV_FIT_NONE;
|
||||
ext->fit_top = LV_FIT_NONE;
|
||||
ext->fit_bottom = LV_FIT_NONE;
|
||||
ext->layout = LV_LAYOUT_OFF;
|
||||
ext->layout = LV_LAYOUT_OFF;
|
||||
|
||||
lv_obj_set_signal_cb(new_cont, lv_cont_signal);
|
||||
|
||||
@ -99,11 +98,11 @@ lv_obj_t * lv_cont_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
/*Copy an existing object*/
|
||||
else {
|
||||
lv_cont_ext_t * copy_ext = lv_obj_get_ext_attr(copy);
|
||||
ext->fit_left = copy_ext->fit_left;
|
||||
ext->fit_right = copy_ext->fit_right;
|
||||
ext->fit_top = copy_ext->fit_top;
|
||||
ext->fit_bottom = copy_ext->fit_bottom;
|
||||
ext->layout = copy_ext->layout;
|
||||
ext->fit_left = copy_ext->fit_left;
|
||||
ext->fit_right = copy_ext->fit_right;
|
||||
ext->fit_top = copy_ext->fit_top;
|
||||
ext->fit_bottom = copy_ext->fit_bottom;
|
||||
ext->layout = copy_ext->layout;
|
||||
|
||||
/*Refresh the style with new signal function*/
|
||||
lv_obj_refresh_style(new_cont);
|
||||
@ -147,17 +146,14 @@ void lv_cont_set_fit4(lv_obj_t * cont, lv_fit_t left, lv_fit_t right, lv_fit_t t
|
||||
{
|
||||
lv_obj_invalidate(cont);
|
||||
lv_cont_ext_t * ext = lv_obj_get_ext_attr(cont);
|
||||
if(ext->fit_left == left &&
|
||||
ext->fit_right == right &&
|
||||
ext->fit_top == top &&
|
||||
ext->fit_bottom == bottom)
|
||||
{
|
||||
if(ext->fit_left == left && ext->fit_right == right && ext->fit_top == top &&
|
||||
ext->fit_bottom == bottom) {
|
||||
return;
|
||||
}
|
||||
|
||||
ext->fit_left = left;
|
||||
ext->fit_right = right;
|
||||
ext->fit_top = top;
|
||||
ext->fit_left = left;
|
||||
ext->fit_right = right;
|
||||
ext->fit_top = top;
|
||||
ext->fit_bottom = bottom;
|
||||
|
||||
/*Send a signal to refresh the layout*/
|
||||
@ -250,7 +246,7 @@ static lv_res_t lv_cont_signal(lv_obj_t * cont, lv_signal_t sign, void * param)
|
||||
lv_cont_refr_autofit(cont);
|
||||
} else if(sign == LV_SIGNAL_CORD_CHG) {
|
||||
if(lv_obj_get_width(cont) != lv_area_get_width(param) ||
|
||||
lv_obj_get_height(cont) != lv_area_get_height(param)) {
|
||||
lv_obj_get_height(cont) != lv_area_get_height(param)) {
|
||||
lv_cont_refr_layout(cont);
|
||||
lv_cont_refr_autofit(cont);
|
||||
}
|
||||
@ -261,7 +257,7 @@ static lv_res_t lv_cont_signal(lv_obj_t * cont, lv_signal_t sign, void * param)
|
||||
} else if(sign == LV_SIGNAL_GET_TYPE) {
|
||||
lv_obj_type_t * buf = param;
|
||||
uint8_t i;
|
||||
for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/
|
||||
for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/
|
||||
if(buf->type[i] == NULL) break;
|
||||
}
|
||||
buf->type[i] = "lv_cont";
|
||||
@ -270,7 +266,6 @@ static lv_res_t lv_cont_signal(lv_obj_t * cont, lv_signal_t sign, void * param)
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Refresh the layout of a container
|
||||
* @param cont pointer to an object which layout should be refreshed
|
||||
@ -292,7 +287,7 @@ static void lv_cont_refr_layout(lv_obj_t * cont)
|
||||
lv_cont_layout_row(cont);
|
||||
} else if(type == LV_LAYOUT_PRETTY) {
|
||||
lv_cont_layout_pretty(cont);
|
||||
} else if(type == LV_LAYOUT_GRID) {
|
||||
} else if(type == LV_LAYOUT_GRID) {
|
||||
lv_cont_layout_grid(cont);
|
||||
}
|
||||
}
|
||||
@ -314,19 +309,19 @@ static void lv_cont_layout_col(lv_obj_t * cont)
|
||||
switch(type) {
|
||||
case LV_LAYOUT_COL_L:
|
||||
hpad_corr = style->body.padding.left;
|
||||
align = LV_ALIGN_IN_TOP_LEFT;
|
||||
align = LV_ALIGN_IN_TOP_LEFT;
|
||||
break;
|
||||
case LV_LAYOUT_COL_M:
|
||||
hpad_corr = 0;
|
||||
align = LV_ALIGN_IN_TOP_MID;
|
||||
align = LV_ALIGN_IN_TOP_MID;
|
||||
break;
|
||||
case LV_LAYOUT_COL_R:
|
||||
hpad_corr = -style->body.padding.right;
|
||||
align = LV_ALIGN_IN_TOP_RIGHT;
|
||||
align = LV_ALIGN_IN_TOP_RIGHT;
|
||||
break;
|
||||
default:
|
||||
hpad_corr = 0;
|
||||
align = LV_ALIGN_IN_TOP_LEFT;
|
||||
align = LV_ALIGN_IN_TOP_LEFT;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -335,9 +330,10 @@ static void lv_cont_layout_col(lv_obj_t * cont)
|
||||
lv_obj_set_protect(cont, LV_PROTECT_CHILD_CHG);
|
||||
/* Align the children */
|
||||
lv_coord_t last_cord = style->body.padding.top;
|
||||
LV_LL_READ_BACK(cont->child_ll, child) {
|
||||
if(lv_obj_get_hidden(child) != false ||
|
||||
lv_obj_is_protected(child, LV_PROTECT_POS) != false) continue;
|
||||
LV_LL_READ_BACK(cont->child_ll, child)
|
||||
{
|
||||
if(lv_obj_get_hidden(child) != false || lv_obj_is_protected(child, LV_PROTECT_POS) != false)
|
||||
continue;
|
||||
|
||||
lv_obj_align(child, cont, align, hpad_corr, last_cord);
|
||||
last_cord += lv_obj_get_height(child) + style->body.padding.inner;
|
||||
@ -363,19 +359,19 @@ static void lv_cont_layout_row(lv_obj_t * cont)
|
||||
switch(type) {
|
||||
case LV_LAYOUT_ROW_T:
|
||||
vpad_corr = style->body.padding.top;
|
||||
align = LV_ALIGN_IN_TOP_LEFT;
|
||||
align = LV_ALIGN_IN_TOP_LEFT;
|
||||
break;
|
||||
case LV_LAYOUT_ROW_M:
|
||||
vpad_corr = 0;
|
||||
align = LV_ALIGN_IN_LEFT_MID;
|
||||
align = LV_ALIGN_IN_LEFT_MID;
|
||||
break;
|
||||
case LV_LAYOUT_ROW_B:
|
||||
vpad_corr = -style->body.padding.bottom;
|
||||
align = LV_ALIGN_IN_BOTTOM_LEFT;
|
||||
align = LV_ALIGN_IN_BOTTOM_LEFT;
|
||||
break;
|
||||
default:
|
||||
vpad_corr = 0;
|
||||
align = LV_ALIGN_IN_TOP_LEFT;
|
||||
align = LV_ALIGN_IN_TOP_LEFT;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -385,9 +381,10 @@ static void lv_cont_layout_row(lv_obj_t * cont)
|
||||
|
||||
/* Align the children */
|
||||
lv_coord_t last_cord = style->body.padding.left;
|
||||
LV_LL_READ_BACK(cont->child_ll, child) {
|
||||
if(lv_obj_get_hidden(child) != false ||
|
||||
lv_obj_is_protected(child, LV_PROTECT_POS) != false) continue;
|
||||
LV_LL_READ_BACK(cont->child_ll, child)
|
||||
{
|
||||
if(lv_obj_get_hidden(child) != false || lv_obj_is_protected(child, LV_PROTECT_POS) != false)
|
||||
continue;
|
||||
|
||||
lv_obj_align(child, cont, align, last_cord, vpad_corr);
|
||||
last_cord += lv_obj_get_width(child) + style->body.padding.inner;
|
||||
@ -404,14 +401,15 @@ static void lv_cont_layout_center(lv_obj_t * cont)
|
||||
{
|
||||
lv_obj_t * child;
|
||||
lv_style_t * style = lv_obj_get_style(cont);
|
||||
uint32_t obj_num = 0;
|
||||
lv_coord_t h_tot = 0;
|
||||
uint32_t obj_num = 0;
|
||||
lv_coord_t h_tot = 0;
|
||||
|
||||
LV_LL_READ(cont->child_ll, child) {
|
||||
if(lv_obj_get_hidden(child) != false ||
|
||||
lv_obj_is_protected(child, LV_PROTECT_POS) != false) continue;
|
||||
LV_LL_READ(cont->child_ll, child)
|
||||
{
|
||||
if(lv_obj_get_hidden(child) != false || lv_obj_is_protected(child, LV_PROTECT_POS) != false)
|
||||
continue;
|
||||
h_tot += lv_obj_get_height(child) + style->body.padding.inner;
|
||||
obj_num ++;
|
||||
obj_num++;
|
||||
}
|
||||
|
||||
if(obj_num == 0) return;
|
||||
@ -423,10 +421,11 @@ static void lv_cont_layout_center(lv_obj_t * cont)
|
||||
lv_obj_set_protect(cont, LV_PROTECT_CHILD_CHG);
|
||||
|
||||
/* Align the children */
|
||||
lv_coord_t last_cord = - (h_tot / 2);
|
||||
LV_LL_READ_BACK(cont->child_ll, child) {
|
||||
if(lv_obj_get_hidden(child) != false ||
|
||||
lv_obj_is_protected(child, LV_PROTECT_POS) != false) continue;
|
||||
lv_coord_t last_cord = -(h_tot / 2);
|
||||
LV_LL_READ_BACK(cont->child_ll, child)
|
||||
{
|
||||
if(lv_obj_get_hidden(child) != false || lv_obj_is_protected(child, LV_PROTECT_POS) != false)
|
||||
continue;
|
||||
|
||||
lv_obj_align(child, cont, LV_ALIGN_CENTER, 0, last_cord + lv_obj_get_height(child) / 2);
|
||||
last_cord += lv_obj_get_height(child) + style->body.padding.inner;
|
||||
@ -442,53 +441,60 @@ static void lv_cont_layout_center(lv_obj_t * cont)
|
||||
*/
|
||||
static void lv_cont_layout_pretty(lv_obj_t * cont)
|
||||
{
|
||||
lv_obj_t * child_rs; /* Row starter child */
|
||||
lv_obj_t * child_rc; /* Row closer child */
|
||||
lv_obj_t * child_tmp; /* Temporary child */
|
||||
lv_obj_t * child_rs; /* Row starter child */
|
||||
lv_obj_t * child_rc; /* Row closer child */
|
||||
lv_obj_t * child_tmp; /* Temporary child */
|
||||
lv_style_t * style = lv_obj_get_style(cont);
|
||||
lv_coord_t w_obj = lv_obj_get_width(cont);
|
||||
lv_coord_t act_y = style->body.padding.top;
|
||||
lv_coord_t w_obj = lv_obj_get_width(cont);
|
||||
lv_coord_t act_y = style->body.padding.top;
|
||||
/* Disable child change action because the children will be moved a lot
|
||||
* an unnecessary child change signals could be sent*/
|
||||
|
||||
child_rs = lv_ll_get_tail(&cont->child_ll); /*Set the row starter child*/
|
||||
if(child_rs == NULL) return; /*Return if no child*/
|
||||
if(child_rs == NULL) return; /*Return if no child*/
|
||||
|
||||
lv_obj_set_protect(cont, LV_PROTECT_CHILD_CHG);
|
||||
|
||||
child_rc = child_rs; /*Initially the the row starter and closer is the same*/
|
||||
while(child_rs != NULL) {
|
||||
lv_coord_t h_row = 0;
|
||||
lv_coord_t w_row = style->body.padding.left + style->body.padding.right; /*The width is at least the left+right hpad*/
|
||||
lv_coord_t w_row = style->body.padding.left +
|
||||
style->body.padding.right; /*The width is at least the left+right hpad*/
|
||||
uint32_t obj_num = 0;
|
||||
|
||||
/*Find the row closer object and collect some data*/
|
||||
do {
|
||||
if(lv_obj_get_hidden(child_rc) == false &&
|
||||
lv_obj_is_protected(child_rc, LV_PROTECT_POS) == false) {
|
||||
lv_obj_is_protected(child_rc, LV_PROTECT_POS) == false) {
|
||||
/*If this object is already not fit then break*/
|
||||
if(w_row + lv_obj_get_width(child_rc) > w_obj) {
|
||||
/*Step back one child because the last already not fit, so the previous is the closer*/
|
||||
if(child_rc != NULL && obj_num != 0) {
|
||||
/*Step back one child because the last already not fit, so the previous is the
|
||||
* closer*/
|
||||
if(child_rc != NULL && obj_num != 0) {
|
||||
child_rc = lv_ll_get_next(&cont->child_ll, child_rc);
|
||||
}
|
||||
break;
|
||||
}
|
||||
w_row += lv_obj_get_width(child_rc) + style->body.padding.inner; /*Add the object width + opad*/
|
||||
h_row = LV_MATH_MAX(h_row, lv_obj_get_height(child_rc)); /*Search the highest object*/
|
||||
obj_num ++;
|
||||
if(lv_obj_is_protected(child_rc, LV_PROTECT_FOLLOW)) break; /*If can not be followed by an other object then break here*/
|
||||
|
||||
w_row += lv_obj_get_width(child_rc) +
|
||||
style->body.padding.inner; /*Add the object width + opad*/
|
||||
h_row =
|
||||
LV_MATH_MAX(h_row, lv_obj_get_height(child_rc)); /*Search the highest object*/
|
||||
obj_num++;
|
||||
if(lv_obj_is_protected(child_rc, LV_PROTECT_FOLLOW))
|
||||
break; /*If can not be followed by an other object then break here*/
|
||||
}
|
||||
child_rc = lv_ll_get_prev(&cont->child_ll, child_rc); /*Load the next object*/
|
||||
if(obj_num == 0) child_rs = child_rc; /*If the first object was hidden (or too long) then set the next as first */
|
||||
if(obj_num == 0)
|
||||
child_rs = child_rc; /*If the first object was hidden (or too long) then set the
|
||||
next as first */
|
||||
} while(child_rc != NULL);
|
||||
|
||||
/*If the object is too long then align it to the middle*/
|
||||
if(obj_num == 0) {
|
||||
if(child_rc != NULL) {
|
||||
lv_obj_align(child_rc, cont, LV_ALIGN_IN_TOP_MID, 0, act_y);
|
||||
h_row = lv_obj_get_height(child_rc); /*Not set previously because of the early break*/
|
||||
h_row =
|
||||
lv_obj_get_height(child_rc); /*Not set previously because of the early break*/
|
||||
}
|
||||
}
|
||||
/*If there is only one object in the row then align it to the middle*/
|
||||
@ -499,31 +505,33 @@ static void lv_cont_layout_pretty(lv_obj_t * cont)
|
||||
else if(obj_num == 2) {
|
||||
lv_obj_t * obj1 = child_rs;
|
||||
lv_obj_t * obj2 = lv_ll_get_prev(&cont->child_ll, child_rs);
|
||||
w_row = lv_obj_get_width(obj1) + lv_obj_get_width(obj2);
|
||||
lv_coord_t pad = (w_obj - w_row) / 3;
|
||||
lv_obj_align(obj1, cont, LV_ALIGN_IN_TOP_LEFT, pad, act_y + (h_row - lv_obj_get_height(obj1)) / 2);
|
||||
lv_obj_align(obj2, cont, LV_ALIGN_IN_TOP_RIGHT, -pad, act_y + (h_row - lv_obj_get_height(obj2)) / 2);
|
||||
w_row = lv_obj_get_width(obj1) + lv_obj_get_width(obj2);
|
||||
lv_coord_t pad = (w_obj - w_row) / 3;
|
||||
lv_obj_align(obj1, cont, LV_ALIGN_IN_TOP_LEFT, pad,
|
||||
act_y + (h_row - lv_obj_get_height(obj1)) / 2);
|
||||
lv_obj_align(obj2, cont, LV_ALIGN_IN_TOP_RIGHT, -pad,
|
||||
act_y + (h_row - lv_obj_get_height(obj2)) / 2);
|
||||
}
|
||||
/* Align the children (from child_rs to child_rc)*/
|
||||
else {
|
||||
w_row -= style->body.padding.inner * obj_num;
|
||||
lv_coord_t new_opad = (w_obj - w_row) / (obj_num - 1);
|
||||
lv_coord_t act_x = style->body.padding.left; /*x init*/
|
||||
child_tmp = child_rs;
|
||||
lv_coord_t new_opad = (w_obj - w_row) / (obj_num - 1);
|
||||
lv_coord_t act_x = style->body.padding.left; /*x init*/
|
||||
child_tmp = child_rs;
|
||||
while(child_tmp != NULL) {
|
||||
if(lv_obj_get_hidden(child_tmp) == false &&
|
||||
lv_obj_is_protected(child_tmp, LV_PROTECT_POS) == false) {
|
||||
lv_obj_align(child_tmp, cont, LV_ALIGN_IN_TOP_LEFT, act_x, act_y + (h_row - lv_obj_get_height(child_tmp)) / 2);
|
||||
lv_obj_is_protected(child_tmp, LV_PROTECT_POS) == false) {
|
||||
lv_obj_align(child_tmp, cont, LV_ALIGN_IN_TOP_LEFT, act_x,
|
||||
act_y + (h_row - lv_obj_get_height(child_tmp)) / 2);
|
||||
act_x += lv_obj_get_width(child_tmp) + new_opad;
|
||||
}
|
||||
if(child_tmp == child_rc) break;
|
||||
child_tmp = lv_ll_get_prev(&cont->child_ll, child_tmp);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(child_rc == NULL) break;
|
||||
act_y += style->body.padding.inner + h_row; /*y increment*/
|
||||
act_y += style->body.padding.inner + h_row; /*y increment*/
|
||||
child_rs = lv_ll_get_prev(&cont->child_ll, child_rc); /*Go to the next object*/
|
||||
child_rc = child_rs;
|
||||
}
|
||||
@ -538,14 +546,16 @@ static void lv_cont_layout_grid(lv_obj_t * cont)
|
||||
{
|
||||
lv_obj_t * child;
|
||||
lv_style_t * style = lv_obj_get_style(cont);
|
||||
lv_coord_t w_tot = lv_obj_get_width(cont);
|
||||
lv_coord_t w_obj = lv_obj_get_width(lv_obj_get_child(cont, NULL));
|
||||
lv_coord_t h_obj = lv_obj_get_height(lv_obj_get_child(cont, NULL));
|
||||
uint16_t obj_row = (w_tot - style->body.padding.left - style->body.padding.right) /
|
||||
(w_obj + style->body.padding.inner); /*Obj. num. in a row*/
|
||||
lv_coord_t w_tot = lv_obj_get_width(cont);
|
||||
lv_coord_t w_obj = lv_obj_get_width(lv_obj_get_child(cont, NULL));
|
||||
lv_coord_t h_obj = lv_obj_get_height(lv_obj_get_child(cont, NULL));
|
||||
uint16_t obj_row = (w_tot - style->body.padding.left - style->body.padding.right) /
|
||||
(w_obj + style->body.padding.inner); /*Obj. num. in a row*/
|
||||
lv_coord_t x_ofs;
|
||||
if(obj_row > 1) {
|
||||
x_ofs = (w_obj + (w_tot - style->body.padding.left - style->body.padding.right) - (obj_row * w_obj)) / (obj_row - 1);
|
||||
x_ofs = (w_obj + (w_tot - style->body.padding.left - style->body.padding.right) -
|
||||
(obj_row * w_obj)) /
|
||||
(obj_row - 1);
|
||||
} else {
|
||||
x_ofs = w_tot / 2 - w_obj / 2;
|
||||
}
|
||||
@ -559,9 +569,10 @@ static void lv_cont_layout_grid(lv_obj_t * cont)
|
||||
lv_coord_t act_x = style->body.padding.left;
|
||||
lv_coord_t act_y = style->body.padding.top;
|
||||
uint16_t obj_cnt = 0;
|
||||
LV_LL_READ_BACK(cont->child_ll, child) {
|
||||
if(lv_obj_get_hidden(child) != false ||
|
||||
lv_obj_is_protected(child, LV_PROTECT_POS) != false) continue;
|
||||
LV_LL_READ_BACK(cont->child_ll, child)
|
||||
{
|
||||
if(lv_obj_get_hidden(child) != false || lv_obj_is_protected(child, LV_PROTECT_POS) != false)
|
||||
continue;
|
||||
|
||||
if(obj_row > 1) {
|
||||
lv_obj_set_pos(child, act_x, act_y);
|
||||
@ -569,11 +580,11 @@ static void lv_cont_layout_grid(lv_obj_t * cont)
|
||||
} else {
|
||||
lv_obj_set_pos(child, x_ofs, act_y);
|
||||
}
|
||||
obj_cnt ++;
|
||||
obj_cnt++;
|
||||
|
||||
if(obj_cnt >= obj_row) {
|
||||
obj_cnt = 0;
|
||||
act_x = style->body.padding.left;
|
||||
act_x = style->body.padding.left;
|
||||
act_y += y_ofs;
|
||||
}
|
||||
}
|
||||
@ -589,11 +600,8 @@ static void lv_cont_refr_autofit(lv_obj_t * cont)
|
||||
{
|
||||
lv_cont_ext_t * ext = lv_obj_get_ext_attr(cont);
|
||||
|
||||
if(ext->fit_left == LV_FIT_NONE &&
|
||||
ext->fit_right == LV_FIT_NONE &&
|
||||
ext->fit_top == LV_FIT_NONE &&
|
||||
ext->fit_bottom == LV_FIT_NONE)
|
||||
{
|
||||
if(ext->fit_left == LV_FIT_NONE && ext->fit_right == LV_FIT_NONE &&
|
||||
ext->fit_top == LV_FIT_NONE && ext->fit_bottom == LV_FIT_NONE) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -602,7 +610,7 @@ static void lv_cont_refr_autofit(lv_obj_t * cont)
|
||||
lv_style_t * style = lv_obj_get_style(cont);
|
||||
lv_obj_t * child_i;
|
||||
|
||||
lv_obj_t * par = lv_obj_get_parent(cont);
|
||||
lv_obj_t * par = lv_obj_get_parent(cont);
|
||||
lv_style_t * par_style = lv_obj_get_style(par);
|
||||
lv_area_t flood_area;
|
||||
lv_area_copy(&flood_area, &par->coords);
|
||||
@ -623,7 +631,8 @@ static void lv_cont_refr_autofit(lv_obj_t * cont)
|
||||
tight_area.x2 = LV_COORD_MIN;
|
||||
tight_area.y2 = LV_COORD_MIN;
|
||||
|
||||
LV_LL_READ(cont->child_ll, child_i) {
|
||||
LV_LL_READ(cont->child_ll, child_i)
|
||||
{
|
||||
if(lv_obj_get_hidden(child_i) != false) continue;
|
||||
tight_area.x1 = LV_MATH_MIN(tight_area.x1, child_i->coords.x1);
|
||||
tight_area.y1 = LV_MATH_MIN(tight_area.y1, child_i->coords.y1);
|
||||
@ -643,37 +652,42 @@ static void lv_cont_refr_autofit(lv_obj_t * cont)
|
||||
switch(ext->fit_left) {
|
||||
case LV_FIT_TIGHT: new_area.x1 = tight_area.x1; break;
|
||||
case LV_FIT_FLOOD: new_area.x1 = flood_area.x1; break;
|
||||
case LV_FIT_FILL: new_area.x1 = has_children ? LV_MATH_MIN(tight_area.x1, flood_area.x1) : flood_area.x1; break;
|
||||
case LV_FIT_FILL:
|
||||
new_area.x1 = has_children ? LV_MATH_MIN(tight_area.x1, flood_area.x1) : flood_area.x1;
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
switch(ext->fit_right) {
|
||||
case LV_FIT_TIGHT: new_area.x2 = tight_area.x2; break;
|
||||
case LV_FIT_FLOOD: new_area.x2 = flood_area.x2; break;
|
||||
case LV_FIT_FILL: new_area.x2 = has_children ? LV_MATH_MAX(tight_area.x2, flood_area.x2) : flood_area.x2; break;
|
||||
case LV_FIT_FILL:
|
||||
new_area.x2 = has_children ? LV_MATH_MAX(tight_area.x2, flood_area.x2) : flood_area.x2;
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
switch(ext->fit_top) {
|
||||
case LV_FIT_TIGHT: new_area.y1 = tight_area.y1; break;
|
||||
case LV_FIT_FLOOD: new_area.y1 = flood_area.y1; break;
|
||||
case LV_FIT_FILL: new_area.y1 = has_children ? LV_MATH_MIN(tight_area.y1, flood_area.y1) : flood_area.y1; break;
|
||||
case LV_FIT_FILL:
|
||||
new_area.y1 = has_children ? LV_MATH_MIN(tight_area.y1, flood_area.y1) : flood_area.y1;
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
switch(ext->fit_bottom) {
|
||||
case LV_FIT_TIGHT: new_area.y2 = tight_area.y2; break;
|
||||
case LV_FIT_FLOOD: new_area.y2 = flood_area.y2; break;
|
||||
case LV_FIT_FILL: new_area.y2 = has_children ? LV_MATH_MAX(tight_area.y2, flood_area.y2) : flood_area.y2; break;
|
||||
case LV_FIT_FILL:
|
||||
new_area.y2 = has_children ? LV_MATH_MAX(tight_area.y2, flood_area.y2) : flood_area.y2;
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
/*Do nothing if the coordinates are not changed*/
|
||||
if(cont->coords.x1 != new_area.x1 ||
|
||||
cont->coords.y1 != new_area.y1 ||
|
||||
cont->coords.x2 != new_area.x2 ||
|
||||
cont->coords.y2 != new_area.y2)
|
||||
{
|
||||
if(cont->coords.x1 != new_area.x1 || cont->coords.y1 != new_area.y1 ||
|
||||
cont->coords.x2 != new_area.x2 || cont->coords.y2 != new_area.y2) {
|
||||
|
||||
lv_obj_invalidate(cont);
|
||||
lv_area_copy(&cont->coords, &new_area);
|
||||
@ -686,11 +700,11 @@ static void lv_cont_refr_autofit(lv_obj_t * cont)
|
||||
par->signal_cb(par, LV_SIGNAL_CHILD_CHG, cont);
|
||||
|
||||
/*Tell the children the parent's size has changed*/
|
||||
LV_LL_READ(cont->child_ll, child_i) {
|
||||
child_i->signal_cb(child_i, LV_SIGNAL_PARENT_SIZE_CHG, NULL);
|
||||
LV_LL_READ(cont->child_ll, child_i)
|
||||
{
|
||||
child_i->signal_cb(child_i, LV_SIGNAL_PARENT_SIZE_CHG, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -32,27 +32,26 @@ extern "C" {
|
||||
**********************/
|
||||
|
||||
/*Layout options*/
|
||||
enum
|
||||
{
|
||||
enum {
|
||||
LV_LAYOUT_OFF = 0,
|
||||
LV_LAYOUT_CENTER,
|
||||
LV_LAYOUT_COL_L, /*Column left align*/
|
||||
LV_LAYOUT_COL_M, /*Column middle align*/
|
||||
LV_LAYOUT_COL_R, /*Column right align*/
|
||||
LV_LAYOUT_ROW_T, /*Row top align*/
|
||||
LV_LAYOUT_ROW_M, /*Row middle align*/
|
||||
LV_LAYOUT_ROW_B, /*Row bottom align*/
|
||||
LV_LAYOUT_PRETTY, /*Put as many object as possible in row and begin a new row*/
|
||||
LV_LAYOUT_GRID, /*Align same-sized object into a grid*/
|
||||
LV_LAYOUT_COL_L, /*Column left align*/
|
||||
LV_LAYOUT_COL_M, /*Column middle align*/
|
||||
LV_LAYOUT_COL_R, /*Column right align*/
|
||||
LV_LAYOUT_ROW_T, /*Row top align*/
|
||||
LV_LAYOUT_ROW_M, /*Row middle align*/
|
||||
LV_LAYOUT_ROW_B, /*Row bottom align*/
|
||||
LV_LAYOUT_PRETTY, /*Put as many object as possible in row and begin a new row*/
|
||||
LV_LAYOUT_GRID, /*Align same-sized object into a grid*/
|
||||
};
|
||||
typedef uint8_t lv_layout_t;
|
||||
|
||||
|
||||
enum {
|
||||
LV_FIT_NONE, /*Do not change the size automatically*/
|
||||
LV_FIT_TIGHT, /*Involve the children*/
|
||||
LV_FIT_FLOOD, /*Align the size to the parent's edge*/
|
||||
LV_FIT_FILL, /*Align the size to the parent's edge first but if there is an object out of it then involve it*/
|
||||
LV_FIT_NONE, /*Do not change the size automatically*/
|
||||
LV_FIT_TIGHT, /*Involve the children*/
|
||||
LV_FIT_FLOOD, /*Align the size to the parent's edge*/
|
||||
LV_FIT_FILL, /*Align the size to the parent's edge first but if there is an object out of it
|
||||
then involve it*/
|
||||
};
|
||||
typedef uint8_t lv_fit_t;
|
||||
|
||||
@ -60,14 +59,13 @@ typedef struct
|
||||
{
|
||||
/*Inherited from 'base_obj' so no inherited ext. */ /*Ext. of ancestor*/
|
||||
/*New data for this type */
|
||||
uint8_t layout :4; /*A layout from 'lv_layout_t' enum*/
|
||||
uint8_t fit_left :2; /*A fit type from `lv_fit_t` enum */
|
||||
uint8_t fit_right :2; /*A fit type from `lv_fit_t` enum */
|
||||
uint8_t fit_top :2; /*A fit type from `lv_fit_t` enum */
|
||||
uint8_t fit_bottom :2; /*A fit type from `lv_fit_t` enum */
|
||||
uint8_t layout : 4; /*A layout from 'lv_layout_t' enum*/
|
||||
uint8_t fit_left : 2; /*A fit type from `lv_fit_t` enum */
|
||||
uint8_t fit_right : 2; /*A fit type from `lv_fit_t` enum */
|
||||
uint8_t fit_top : 2; /*A fit type from `lv_fit_t` enum */
|
||||
uint8_t fit_bottom : 2; /*A fit type from `lv_fit_t` enum */
|
||||
} lv_cont_ext_t;
|
||||
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
@ -100,7 +98,8 @@ void lv_cont_set_layout(lv_obj_t * cont, lv_layout_t layout);
|
||||
* @param top bottom fit policy from `lv_fit_t`
|
||||
* @param bottom bottom fit policy from `lv_fit_t`
|
||||
*/
|
||||
void lv_cont_set_fit4(lv_obj_t * cont, lv_fit_t left, lv_fit_t right, lv_fit_t top, lv_fit_t bottom);
|
||||
void lv_cont_set_fit4(lv_obj_t * cont, lv_fit_t left, lv_fit_t right, lv_fit_t top,
|
||||
lv_fit_t bottom);
|
||||
|
||||
/**
|
||||
* Set the fit policy horizontally and vertically separately.
|
||||
@ -114,7 +113,6 @@ static inline void lv_cont_set_fit2(lv_obj_t * cont, lv_fit_t hor, lv_fit_t ver)
|
||||
lv_cont_set_fit4(cont, hor, hor, ver, ver);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the fit policyin all 4 direction at once.
|
||||
* It tell how to change the container's size automatically.
|
||||
@ -126,13 +124,12 @@ static inline void lv_cont_set_fit(lv_obj_t * cont, lv_fit_t fit)
|
||||
lv_cont_set_fit4(cont, fit, fit, fit, fit);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the style of a container
|
||||
* @param cont pointer to a container object
|
||||
* @param style pointer to the new style
|
||||
*/
|
||||
static inline void lv_cont_set_style(lv_obj_t *cont, lv_style_t * style)
|
||||
static inline void lv_cont_set_style(lv_obj_t * cont, lv_style_t * style)
|
||||
{
|
||||
lv_obj_set_style(cont, style);
|
||||
}
|
||||
@ -181,7 +178,7 @@ lv_fit_t lv_cont_get_fit_bottom(const lv_obj_t * cont);
|
||||
* @param cont pointer to a container object
|
||||
* @return pointer to the container's style
|
||||
*/
|
||||
static inline lv_style_t * lv_cont_get_style(const lv_obj_t *cont)
|
||||
static inline lv_style_t * lv_cont_get_style(const lv_obj_t * cont)
|
||||
{
|
||||
return lv_obj_get_style(cont);
|
||||
}
|
||||
@ -190,10 +187,10 @@ static inline lv_style_t * lv_cont_get_style(const lv_obj_t *cont)
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_CONT*/
|
||||
#endif /*LV_USE_CONT*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_CONT_H*/
|
||||
#endif /*LV_CONT_H*/
|
||||
|
@ -3,7 +3,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
@ -23,12 +22,12 @@
|
||||
* DEFINES
|
||||
*********************/
|
||||
#if LV_USE_ANIMATION
|
||||
# ifndef LV_DDLIST_ANIM_TIME
|
||||
# define LV_DDLIST_DEF_ANIM_TIME 200 /*ms*/
|
||||
# endif
|
||||
#ifndef LV_DDLIST_ANIM_TIME
|
||||
#define LV_DDLIST_DEF_ANIM_TIME 200 /*ms*/
|
||||
#endif
|
||||
#else
|
||||
# undef LV_DDLIST_DEF_ANIM_TIME
|
||||
# define LV_DDLIST_DEF_ANIM_TIME 0 /*No animation*/
|
||||
#undef LV_DDLIST_DEF_ANIM_TIME
|
||||
#define LV_DDLIST_DEF_ANIM_TIME 0 /*No animation*/
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
@ -50,9 +49,9 @@ static void lv_ddlist_adjust_height(lv_obj_t * ddlist, int32_t height);
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
static lv_signal_cb_t ancestor_signal;
|
||||
static lv_signal_cb_t ancestor_scrl_signal;
|
||||
static lv_design_cb_t ancestor_design;
|
||||
static lv_signal_cb_t ancestor_signal;
|
||||
static lv_signal_cb_t ancestor_scrl_signal;
|
||||
static lv_design_cb_t ancestor_design;
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
@ -65,7 +64,8 @@ static lv_design_cb_t ancestor_design;
|
||||
/**
|
||||
* Create a drop down list objects
|
||||
* @param par pointer to an object, it will be the parent of the new drop down list
|
||||
* @param copy pointer to a drop down list object, if not NULL then the new object will be copied from it
|
||||
* @param copy pointer to a drop down list object, if not NULL then the new object will be copied
|
||||
* from it
|
||||
* @return pointer to the created drop down list
|
||||
*/
|
||||
lv_obj_t * lv_ddlist_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
@ -78,7 +78,8 @@ lv_obj_t * lv_ddlist_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
if(new_ddlist == NULL) return NULL;
|
||||
|
||||
if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_func(new_ddlist);
|
||||
if(ancestor_scrl_signal == NULL) ancestor_scrl_signal = lv_obj_get_signal_func(lv_page_get_scrl(new_ddlist));
|
||||
if(ancestor_scrl_signal == NULL)
|
||||
ancestor_scrl_signal = lv_obj_get_signal_func(lv_page_get_scrl(new_ddlist));
|
||||
if(ancestor_design == NULL) ancestor_design = lv_obj_get_design_func(new_ddlist);
|
||||
|
||||
/*Allocate the drop down list type specific extended data*/
|
||||
@ -87,16 +88,16 @@ lv_obj_t * lv_ddlist_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
if(ext == NULL) return NULL;
|
||||
|
||||
/*Initialize the allocated 'ext' */
|
||||
ext->label = NULL;
|
||||
ext->opened = 0;
|
||||
ext->fix_height = 0;
|
||||
ext->sel_opt_id = 0;
|
||||
ext->label = NULL;
|
||||
ext->opened = 0;
|
||||
ext->fix_height = 0;
|
||||
ext->sel_opt_id = 0;
|
||||
ext->sel_opt_id_ori = 0;
|
||||
ext->option_cnt = 0;
|
||||
ext->anim_time = LV_DDLIST_DEF_ANIM_TIME;
|
||||
ext->sel_style = &lv_style_plain_color;
|
||||
ext->draw_arrow = 0; /*Do not draw arrow by default*/
|
||||
ext->stay_open = 0;
|
||||
ext->option_cnt = 0;
|
||||
ext->anim_time = LV_DDLIST_DEF_ANIM_TIME;
|
||||
ext->sel_style = &lv_style_plain_color;
|
||||
ext->draw_arrow = 0; /*Do not draw arrow by default*/
|
||||
ext->stay_open = 0;
|
||||
|
||||
/*The signal and design functions are not copied so set them here*/
|
||||
lv_obj_set_signal_cb(new_ddlist, lv_ddlist_signal);
|
||||
@ -131,16 +132,16 @@ lv_obj_t * lv_ddlist_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
/*Copy an existing drop down list*/
|
||||
else {
|
||||
lv_ddlist_ext_t * copy_ext = lv_obj_get_ext_attr(copy);
|
||||
ext->label = lv_label_create(new_ddlist, copy_ext->label);
|
||||
ext->label = lv_label_create(new_ddlist, copy_ext->label);
|
||||
lv_label_set_text(ext->label, lv_label_get_text(copy_ext->label));
|
||||
ext->sel_opt_id = copy_ext->sel_opt_id;
|
||||
ext->sel_opt_id = copy_ext->sel_opt_id;
|
||||
ext->sel_opt_id_ori = copy_ext->sel_opt_id;
|
||||
ext->fix_height = copy_ext->fix_height;
|
||||
ext->option_cnt = copy_ext->option_cnt;
|
||||
ext->sel_style = copy_ext->sel_style;
|
||||
ext->anim_time = copy_ext->anim_time;
|
||||
ext->draw_arrow = copy_ext->draw_arrow;
|
||||
ext->stay_open = copy_ext->stay_open;
|
||||
ext->fix_height = copy_ext->fix_height;
|
||||
ext->option_cnt = copy_ext->option_cnt;
|
||||
ext->sel_style = copy_ext->sel_style;
|
||||
ext->anim_time = copy_ext->anim_time;
|
||||
ext->draw_arrow = copy_ext->draw_arrow;
|
||||
ext->stay_open = copy_ext->stay_open;
|
||||
|
||||
/*Refresh the style with new signal function*/
|
||||
lv_obj_refresh_style(new_ddlist);
|
||||
@ -148,7 +149,6 @@ lv_obj_t * lv_ddlist_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
|
||||
LV_LOG_INFO("drop down list created");
|
||||
|
||||
|
||||
return new_ddlist;
|
||||
}
|
||||
|
||||
@ -171,8 +171,8 @@ void lv_ddlist_set_options(lv_obj_t * ddlist, const char * options)
|
||||
for(i = 0; options[i] != '\0'; i++) {
|
||||
if(options[i] == '\n') ext->option_cnt++;
|
||||
}
|
||||
ext->option_cnt++; /*Last option in the at row*/
|
||||
ext->sel_opt_id = 0;
|
||||
ext->option_cnt++; /*Last option in the at row*/
|
||||
ext->sel_opt_id = 0;
|
||||
ext->sel_opt_id_ori = 0;
|
||||
|
||||
lv_label_set_text(ext->label, options);
|
||||
@ -189,7 +189,7 @@ void lv_ddlist_set_selected(lv_obj_t * ddlist, uint16_t sel_opt)
|
||||
lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist);
|
||||
if(ext->sel_opt_id == sel_opt) return;
|
||||
|
||||
ext->sel_opt_id = sel_opt < ext->option_cnt ? sel_opt : ext->option_cnt - 1;
|
||||
ext->sel_opt_id = sel_opt < ext->option_cnt ? sel_opt : ext->option_cnt - 1;
|
||||
ext->sel_opt_id_ori = ext->sel_opt_id;
|
||||
/*Move the list to show the current option*/
|
||||
if(ext->opened == 0) {
|
||||
@ -228,7 +228,6 @@ void lv_ddlist_set_fit(lv_obj_t * ddlist, lv_fit_t fit)
|
||||
lv_page_set_scrl_fit2(ddlist, LV_FIT_FLOOD, LV_FIT_NONE);
|
||||
} else {
|
||||
lv_page_set_scrl_fit2(ddlist, LV_FIT_TIGHT, LV_FIT_NONE);
|
||||
|
||||
}
|
||||
|
||||
lv_ddlist_refr_size(ddlist, false);
|
||||
@ -260,7 +259,6 @@ void lv_ddlist_set_stay_open(lv_obj_t * ddlist, bool en)
|
||||
ext->stay_open = en ? 1 : 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the open/close animation time.
|
||||
* @param ddlist pointer to a drop down list
|
||||
@ -287,31 +285,26 @@ void lv_ddlist_set_style(lv_obj_t * ddlist, lv_ddlist_style_t type, lv_style_t *
|
||||
lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist);
|
||||
|
||||
switch(type) {
|
||||
case LV_DDLIST_STYLE_BG:
|
||||
lv_page_set_style(ddlist, LV_PAGE_STYLE_BG, style);
|
||||
break;
|
||||
case LV_DDLIST_STYLE_SB:
|
||||
lv_page_set_style(ddlist, LV_PAGE_STYLE_SB, style);
|
||||
break;
|
||||
case LV_DDLIST_STYLE_BG: lv_page_set_style(ddlist, LV_PAGE_STYLE_BG, style); break;
|
||||
case LV_DDLIST_STYLE_SB: lv_page_set_style(ddlist, LV_PAGE_STYLE_SB, style); break;
|
||||
case LV_DDLIST_STYLE_SEL:
|
||||
ext->sel_style = style;
|
||||
ext->sel_style = style;
|
||||
lv_obj_t * scrl = lv_page_get_scrl(ddlist);
|
||||
lv_obj_refresh_ext_size(scrl); /*Because of the wider selected rectangle*/
|
||||
lv_obj_refresh_ext_size(scrl); /*Because of the wider selected rectangle*/
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void lv_ddlist_set_align(lv_obj_t *ddlist, lv_label_align_t align)
|
||||
void lv_ddlist_set_align(lv_obj_t * ddlist, lv_label_align_t align)
|
||||
{
|
||||
lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist);
|
||||
lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist);
|
||||
|
||||
lv_label_set_align(ext->label, align);
|
||||
lv_label_set_align(ext->label, align);
|
||||
}
|
||||
/*=====================
|
||||
* Getter functions
|
||||
*====================*/
|
||||
|
||||
|
||||
/**
|
||||
* Get the options of a drop down list
|
||||
* @param ddlist pointer to drop down list object
|
||||
@ -346,13 +339,12 @@ void lv_ddlist_get_selected_str(const lv_obj_t * ddlist, char * buf, uint16_t bu
|
||||
lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist);
|
||||
|
||||
uint16_t i;
|
||||
uint16_t line = 0;
|
||||
uint16_t line = 0;
|
||||
const char * opt_txt = lv_label_get_text(ext->label);
|
||||
uint16_t txt_len = strlen(opt_txt);
|
||||
|
||||
uint16_t txt_len = strlen(opt_txt);
|
||||
|
||||
for(i = 0; i < txt_len && line != ext->sel_opt_id; i++) {
|
||||
if(opt_txt[i] == '\n') line ++;
|
||||
if(opt_txt[i] == '\n') line++;
|
||||
}
|
||||
|
||||
uint16_t c;
|
||||
@ -422,25 +414,21 @@ lv_style_t * lv_ddlist_get_style(const lv_obj_t * ddlist, lv_ddlist_style_t type
|
||||
lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist);
|
||||
|
||||
switch(type) {
|
||||
case LV_DDLIST_STYLE_BG:
|
||||
return lv_page_get_style(ddlist, LV_PAGE_STYLE_BG);
|
||||
case LV_DDLIST_STYLE_SB:
|
||||
return lv_page_get_style(ddlist, LV_PAGE_STYLE_SB);
|
||||
case LV_DDLIST_STYLE_SEL:
|
||||
return ext->sel_style;
|
||||
default:
|
||||
return NULL;
|
||||
case LV_DDLIST_STYLE_BG: return lv_page_get_style(ddlist, LV_PAGE_STYLE_BG);
|
||||
case LV_DDLIST_STYLE_SB: return lv_page_get_style(ddlist, LV_PAGE_STYLE_SB);
|
||||
case LV_DDLIST_STYLE_SEL: return ext->sel_style;
|
||||
default: return NULL;
|
||||
}
|
||||
|
||||
/*To avoid warning*/
|
||||
return NULL;
|
||||
}
|
||||
|
||||
lv_label_align_t lv_ddlist_get_align(const lv_obj_t *ddlist)
|
||||
lv_label_align_t lv_ddlist_get_align(const lv_obj_t * ddlist)
|
||||
{
|
||||
lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist);
|
||||
lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist);
|
||||
|
||||
return lv_label_get_align(ext->label);
|
||||
return lv_label_get_align(ext->label);
|
||||
}
|
||||
|
||||
/*=====================
|
||||
@ -458,7 +446,7 @@ void lv_ddlist_open(lv_obj_t * ddlist, bool anim_en)
|
||||
anim_en = false;
|
||||
#endif
|
||||
lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist);
|
||||
ext->opened = 1;
|
||||
ext->opened = 1;
|
||||
lv_obj_set_drag(lv_page_get_scrl(ddlist), true);
|
||||
lv_ddlist_refr_size(ddlist, anim_en);
|
||||
}
|
||||
@ -474,7 +462,7 @@ void lv_ddlist_close(lv_obj_t * ddlist, bool anim_en)
|
||||
anim_en = false;
|
||||
#endif
|
||||
lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist);
|
||||
ext->opened = 0;
|
||||
ext->opened = 0;
|
||||
lv_obj_set_drag(lv_page_get_scrl(ddlist), false);
|
||||
lv_ddlist_refr_size(ddlist, anim_en);
|
||||
}
|
||||
@ -488,25 +476,21 @@ void lv_ddlist_close(lv_obj_t * ddlist, bool anim_en)
|
||||
* @param ddlist drop down list
|
||||
* @return text alignment flag
|
||||
*/
|
||||
static lv_txt_flag_t lv_ddlist_get_txt_flag(const lv_obj_t *ddlist)
|
||||
static lv_txt_flag_t lv_ddlist_get_txt_flag(const lv_obj_t * ddlist)
|
||||
{
|
||||
lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist);
|
||||
lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist);
|
||||
|
||||
/*The label might be already deleted so just return with some value*/
|
||||
if(!ext->label) return LV_TXT_FLAG_CENTER;
|
||||
/*The label might be already deleted so just return with some value*/
|
||||
if(!ext->label) return LV_TXT_FLAG_CENTER;
|
||||
|
||||
lv_label_align_t align = lv_label_get_align(ext->label);
|
||||
lv_label_align_t align = lv_label_get_align(ext->label);
|
||||
|
||||
switch(align)
|
||||
{
|
||||
default:
|
||||
case LV_LABEL_ALIGN_LEFT:
|
||||
return LV_TXT_FLAG_NONE;
|
||||
case LV_LABEL_ALIGN_CENTER:
|
||||
return LV_TXT_FLAG_CENTER;
|
||||
case LV_LABEL_ALIGN_RIGHT:
|
||||
return LV_TXT_FLAG_RIGHT;
|
||||
}
|
||||
switch(align) {
|
||||
default:
|
||||
case LV_LABEL_ALIGN_LEFT: return LV_TXT_FLAG_NONE;
|
||||
case LV_LABEL_ALIGN_CENTER: return LV_TXT_FLAG_CENTER;
|
||||
case LV_LABEL_ALIGN_RIGHT: return LV_TXT_FLAG_RIGHT;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -530,12 +514,12 @@ static bool lv_ddlist_design(lv_obj_t * ddlist, const lv_area_t * mask, lv_desig
|
||||
ancestor_design(ddlist, mask, mode);
|
||||
|
||||
lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist);
|
||||
lv_opa_t opa_scale = lv_obj_get_opa_scale(ddlist);
|
||||
lv_opa_t opa_scale = lv_obj_get_opa_scale(ddlist);
|
||||
/*If the list is opened draw a rectangle under the selected item*/
|
||||
if(ext->opened != 0 || ext->force_sel) {
|
||||
lv_style_t * style = lv_ddlist_get_style(ddlist, LV_DDLIST_STYLE_BG);
|
||||
lv_style_t * style = lv_ddlist_get_style(ddlist, LV_DDLIST_STYLE_BG);
|
||||
const lv_font_t * font = style->text.font;
|
||||
lv_coord_t font_h = lv_font_get_height(font);
|
||||
lv_coord_t font_h = lv_font_get_height(font);
|
||||
|
||||
/*Draw the selected*/
|
||||
lv_area_t rect_area;
|
||||
@ -554,13 +538,13 @@ static bool lv_ddlist_design(lv_obj_t * ddlist, const lv_area_t * mask, lv_desig
|
||||
else if(mode == LV_DESIGN_DRAW_POST) {
|
||||
/*Redraw the text on the selected area with a different color*/
|
||||
lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist);
|
||||
lv_opa_t opa_scale = lv_obj_get_opa_scale(ddlist);
|
||||
lv_opa_t opa_scale = lv_obj_get_opa_scale(ddlist);
|
||||
|
||||
/*Redraw only in opened state*/
|
||||
if(ext->opened || ext->force_sel) {
|
||||
lv_style_t * style = lv_ddlist_get_style(ddlist, LV_DDLIST_STYLE_BG);
|
||||
lv_style_t * style = lv_ddlist_get_style(ddlist, LV_DDLIST_STYLE_BG);
|
||||
const lv_font_t * font = style->text.font;
|
||||
lv_coord_t font_h = lv_font_get_height(font);
|
||||
lv_coord_t font_h = lv_font_get_height(font);
|
||||
|
||||
lv_area_t area_sel;
|
||||
area_sel.y1 = ext->label->coords.y1;
|
||||
@ -578,45 +562,45 @@ static bool lv_ddlist_design(lv_obj_t * ddlist, const lv_area_t * mask, lv_desig
|
||||
lv_style_t new_style;
|
||||
lv_style_copy(&new_style, style);
|
||||
new_style.text.color = sel_style->text.color;
|
||||
new_style.text.opa = sel_style->text.opa;
|
||||
lv_txt_flag_t flag = lv_ddlist_get_txt_flag(ddlist);
|
||||
new_style.text.opa = sel_style->text.opa;
|
||||
lv_txt_flag_t flag = lv_ddlist_get_txt_flag(ddlist);
|
||||
lv_draw_label(&ext->label->coords, &mask_sel, &new_style, opa_scale,
|
||||
lv_label_get_text(ext->label), flag, NULL, -1, -1);
|
||||
}
|
||||
}
|
||||
|
||||
/*Add a down symbol in ddlist when closed*/
|
||||
else
|
||||
{
|
||||
/*Draw a arrow in ddlist if enabled*/
|
||||
if(ext->draw_arrow)
|
||||
{
|
||||
lv_style_t * style = lv_ddlist_get_style(ddlist, LV_DDLIST_STYLE_BG);
|
||||
const lv_font_t * font = style->text.font;
|
||||
lv_style_t * sel_style = lv_ddlist_get_style(ddlist, LV_DDLIST_STYLE_BG);
|
||||
lv_coord_t font_h = lv_font_get_height(font);
|
||||
lv_style_t new_style;
|
||||
lv_style_copy(&new_style, style);
|
||||
new_style.text.color = sel_style->text.color;
|
||||
new_style.text.opa = sel_style->text.opa;
|
||||
lv_area_t area_arrow;
|
||||
area_arrow.x2 = ddlist->coords.x2 - style->body.padding.right;
|
||||
area_arrow.x1 = area_arrow.x2 - lv_txt_get_width(LV_SYMBOL_DOWN, strlen(LV_SYMBOL_DOWN), sel_style->text.font, 0, 0);
|
||||
/*Add a down symbol in ddlist when closed*/
|
||||
else {
|
||||
/*Draw a arrow in ddlist if enabled*/
|
||||
if(ext->draw_arrow) {
|
||||
lv_style_t * style = lv_ddlist_get_style(ddlist, LV_DDLIST_STYLE_BG);
|
||||
const lv_font_t * font = style->text.font;
|
||||
lv_style_t * sel_style = lv_ddlist_get_style(ddlist, LV_DDLIST_STYLE_BG);
|
||||
lv_coord_t font_h = lv_font_get_height(font);
|
||||
lv_style_t new_style;
|
||||
lv_style_copy(&new_style, style);
|
||||
new_style.text.color = sel_style->text.color;
|
||||
new_style.text.opa = sel_style->text.opa;
|
||||
lv_area_t area_arrow;
|
||||
area_arrow.x2 = ddlist->coords.x2 - style->body.padding.right;
|
||||
area_arrow.x1 =
|
||||
area_arrow.x2 - lv_txt_get_width(LV_SYMBOL_DOWN, strlen(LV_SYMBOL_DOWN),
|
||||
sel_style->text.font, 0, 0);
|
||||
|
||||
area_arrow.y1 = ddlist->coords.y1 + style->text.line_space;
|
||||
area_arrow.y2 = area_arrow.y1 + font_h;
|
||||
area_arrow.y1 = ddlist->coords.y1 + style->text.line_space;
|
||||
area_arrow.y2 = area_arrow.y1 + font_h;
|
||||
|
||||
|
||||
lv_area_t mask_arrow;
|
||||
bool area_ok;
|
||||
area_ok = lv_area_intersect(&mask_arrow, mask, &area_arrow);
|
||||
if (area_ok)
|
||||
{
|
||||
lv_draw_label(&area_arrow, &mask_arrow, &new_style, opa_scale,
|
||||
LV_SYMBOL_DOWN, LV_TXT_FLAG_NONE, NULL, -1, -1); /*Use a down arrow in ddlist, you can replace it with your custom symbol*/
|
||||
}
|
||||
}
|
||||
}
|
||||
lv_area_t mask_arrow;
|
||||
bool area_ok;
|
||||
area_ok = lv_area_intersect(&mask_arrow, mask, &area_arrow);
|
||||
if(area_ok) {
|
||||
lv_draw_label(&area_arrow, &mask_arrow, &new_style, opa_scale, LV_SYMBOL_DOWN,
|
||||
LV_TXT_FLAG_NONE, NULL, -1,
|
||||
-1); /*Use a down arrow in ddlist, you can replace it with your
|
||||
custom symbol*/
|
||||
}
|
||||
}
|
||||
}
|
||||
/*Draw the scrollbar in the ancestor page design function*/
|
||||
ancestor_design(ddlist, mask, mode);
|
||||
}
|
||||
@ -646,41 +630,39 @@ static lv_res_t lv_ddlist_signal(lv_obj_t * ddlist, lv_signal_t sign, void * par
|
||||
ext->label = NULL;
|
||||
} else if(sign == LV_SIGNAL_FOCUS) {
|
||||
#if LV_USE_GROUP
|
||||
lv_group_t * g = lv_obj_get_group(ddlist);
|
||||
bool editing = lv_group_get_editing(g);
|
||||
lv_group_t * g = lv_obj_get_group(ddlist);
|
||||
bool editing = lv_group_get_editing(g);
|
||||
lv_indev_type_t indev_type = lv_indev_get_type(lv_indev_get_act());
|
||||
|
||||
/*Encoders need special handling*/
|
||||
if(indev_type == LV_INDEV_TYPE_ENCODER) {
|
||||
/*Open the list if editing*/
|
||||
if(editing) {
|
||||
ext->opened = true;
|
||||
ext->opened = true;
|
||||
ext->sel_opt_id_ori = ext->sel_opt_id;
|
||||
lv_ddlist_refr_size(ddlist, true);
|
||||
}
|
||||
/*Close the lift if navigating*/
|
||||
else {
|
||||
ext->opened = false;
|
||||
ext->opened = false;
|
||||
ext->sel_opt_id = ext->sel_opt_id_ori;
|
||||
lv_ddlist_refr_size(ddlist, true);
|
||||
|
||||
}
|
||||
} else {
|
||||
/*Open the list if closed*/
|
||||
if(!ext->opened) {
|
||||
ext->opened = true;
|
||||
ext->sel_opt_id_ori = ext->sel_opt_id; /*Save the current value. Used to revert this state if ENER wont't be pressed*/
|
||||
ext->opened = true;
|
||||
ext->sel_opt_id_ori = ext->sel_opt_id; /*Save the current value. Used to revert this
|
||||
state if ENER wont't be pressed*/
|
||||
lv_ddlist_refr_size(ddlist, true);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else if(sign == LV_SIGNAL_RELEASED) {
|
||||
} else if(sign == LV_SIGNAL_RELEASED) {
|
||||
release_handler(ddlist);
|
||||
}
|
||||
else if(sign == LV_SIGNAL_DEFOCUS) {
|
||||
} else if(sign == LV_SIGNAL_DEFOCUS) {
|
||||
if(ext->opened) {
|
||||
ext->opened = false;
|
||||
ext->opened = false;
|
||||
ext->sel_opt_id = ext->sel_opt_id_ori;
|
||||
lv_ddlist_refr_size(ddlist, true);
|
||||
}
|
||||
@ -693,7 +675,7 @@ static lv_res_t lv_ddlist_signal(lv_obj_t * ddlist, lv_signal_t sign, void * par
|
||||
}
|
||||
|
||||
if(ext->sel_opt_id + 1 < ext->option_cnt) {
|
||||
ext->sel_opt_id ++;
|
||||
ext->sel_opt_id++;
|
||||
lv_ddlist_pos_current_option(ddlist);
|
||||
lv_obj_invalidate(ddlist);
|
||||
}
|
||||
@ -703,24 +685,24 @@ static lv_res_t lv_ddlist_signal(lv_obj_t * ddlist, lv_signal_t sign, void * par
|
||||
lv_ddlist_refr_size(ddlist, true);
|
||||
}
|
||||
if(ext->sel_opt_id > 0) {
|
||||
ext->sel_opt_id --;
|
||||
ext->sel_opt_id--;
|
||||
lv_ddlist_pos_current_option(ddlist);
|
||||
lv_obj_invalidate(ddlist);
|
||||
}
|
||||
} else if(c == LV_GROUP_KEY_ESC) {
|
||||
if(ext->opened) {
|
||||
ext->opened = 0;
|
||||
ext->opened = 0;
|
||||
ext->sel_opt_id = ext->sel_opt_id_ori;
|
||||
lv_ddlist_refr_size(ddlist, true);
|
||||
}
|
||||
}
|
||||
} else if(sign == LV_SIGNAL_GET_EDITABLE) {
|
||||
bool * editable = (bool *)param;
|
||||
*editable = true;
|
||||
*editable = true;
|
||||
} else if(sign == LV_SIGNAL_GET_TYPE) {
|
||||
lv_obj_type_t * buf = param;
|
||||
uint8_t i;
|
||||
for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/
|
||||
for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/
|
||||
if(buf->type[i] == NULL) break;
|
||||
}
|
||||
buf->type[i] = "lv_ddlist";
|
||||
@ -751,17 +733,15 @@ static lv_res_t lv_ddlist_scrl_signal(lv_obj_t * scrl, lv_signal_t sign, void *
|
||||
/* Because of the wider selected rectangle ext. size
|
||||
* In this way by dragging the scrollable part the wider rectangle area can be redrawn too*/
|
||||
lv_style_t * style = lv_ddlist_get_style(ddlist, LV_DDLIST_STYLE_BG);
|
||||
lv_coord_t hpad = LV_MATH_MAX(style->body.padding.left, style->body.padding.right);
|
||||
lv_coord_t hpad = LV_MATH_MAX(style->body.padding.left, style->body.padding.right);
|
||||
if(scrl->ext_size < hpad) scrl->ext_size = hpad;
|
||||
}
|
||||
else if(sign == LV_SIGNAL_RELEASED) {
|
||||
} else if(sign == LV_SIGNAL_RELEASED) {
|
||||
if(lv_indev_is_dragging(lv_indev_get_act()) == false) {
|
||||
release_handler(ddlist);
|
||||
}
|
||||
}
|
||||
else if(sign == LV_SIGNAL_CLEANUP) {
|
||||
} else if(sign == LV_SIGNAL_CLEANUP) {
|
||||
lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist);
|
||||
ext->label = NULL; /*The label is already deleted*/
|
||||
ext->label = NULL; /*The label is already deleted*/
|
||||
}
|
||||
|
||||
return res;
|
||||
@ -792,7 +772,8 @@ static lv_res_t release_handler(lv_obj_t * ddlist)
|
||||
}
|
||||
|
||||
/*Search the clicked option (For KEYPAD and ENCODER the new value should be already set)*/
|
||||
if(lv_indev_get_type(indev) == LV_INDEV_TYPE_POINTER || lv_indev_get_type(indev) == LV_INDEV_TYPE_BUTTON) {
|
||||
if(lv_indev_get_type(indev) == LV_INDEV_TYPE_POINTER ||
|
||||
lv_indev_get_type(indev) == LV_INDEV_TYPE_BUTTON) {
|
||||
lv_point_t p;
|
||||
lv_indev_get_point(indev, &p);
|
||||
p.y -= ext->label->coords.y1;
|
||||
@ -800,15 +781,16 @@ static lv_res_t release_handler(lv_obj_t * ddlist)
|
||||
uint16_t letter_i;
|
||||
letter_i = lv_label_get_letter_on(ext->label, &p);
|
||||
|
||||
uint16_t new_opt = 0;
|
||||
const char * txt = lv_label_get_text(ext->label);
|
||||
uint32_t i = 0;
|
||||
uint16_t new_opt = 0;
|
||||
const char * txt = lv_label_get_text(ext->label);
|
||||
uint32_t i = 0;
|
||||
uint32_t line_cnt = 0;
|
||||
uint32_t letter;
|
||||
for(line_cnt = 0; line_cnt < letter_i; line_cnt++) {
|
||||
letter = lv_txt_encoded_next(txt, &i);
|
||||
/*Count he lines to reach the clicked letter. But ignore the last '\n' because it still belongs to the clicked line*/
|
||||
if(letter == '\n' && i != letter_i) new_opt ++;
|
||||
/*Count he lines to reach the clicked letter. But ignore the last '\n' because it
|
||||
* still belongs to the clicked line*/
|
||||
if(letter == '\n' && i != letter_i) new_opt++;
|
||||
}
|
||||
|
||||
ext->sel_opt_id = new_opt;
|
||||
@ -829,7 +811,6 @@ static lv_res_t release_handler(lv_obj_t * ddlist)
|
||||
}
|
||||
|
||||
return LV_RES_OK;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -843,18 +824,20 @@ static void lv_ddlist_refr_size(lv_obj_t * ddlist, bool anim_en)
|
||||
anim_en = false;
|
||||
#endif
|
||||
lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist);
|
||||
lv_style_t * style = lv_obj_get_style(ddlist);
|
||||
lv_style_t * style = lv_obj_get_style(ddlist);
|
||||
lv_coord_t new_height;
|
||||
if(ext->opened) { /*Open the list*/
|
||||
if(ext->fix_height == 0) new_height = lv_obj_get_height(lv_page_get_scrl(ddlist)) +
|
||||
style->body.padding.top + style->body.padding.bottom;
|
||||
else new_height = ext->fix_height;
|
||||
if(ext->fix_height == 0)
|
||||
new_height = lv_obj_get_height(lv_page_get_scrl(ddlist)) + style->body.padding.top +
|
||||
style->body.padding.bottom;
|
||||
else
|
||||
new_height = ext->fix_height;
|
||||
|
||||
} else { /*Close the list*/
|
||||
const lv_font_t * font = style->text.font;
|
||||
const lv_font_t * font = style->text.font;
|
||||
lv_style_t * label_style = lv_obj_get_style(ext->label);
|
||||
lv_coord_t font_h = lv_font_get_height(font);
|
||||
new_height = font_h + 2 * label_style->text.line_space;
|
||||
lv_coord_t font_h = lv_font_get_height(font);
|
||||
new_height = font_h + 2 * label_style->text.line_space;
|
||||
|
||||
lv_page_set_sb_mode(ddlist, LV_SB_MODE_HIDE);
|
||||
}
|
||||
@ -864,21 +847,22 @@ static void lv_ddlist_refr_size(lv_obj_t * ddlist, bool anim_en)
|
||||
lv_ddlist_pos_current_option(ddlist);
|
||||
if(ext->opened) lv_page_set_sb_mode(ddlist, LV_SB_MODE_UNHIDE);
|
||||
#if LV_USE_ANIMATION
|
||||
lv_anim_del(ddlist, (lv_anim_fp_t)lv_obj_set_height); /*If an animation is in progress then it will overwrite this changes*/
|
||||
lv_anim_del(ddlist, (lv_anim_fp_t)lv_obj_set_height); /*If an animation is in progress then
|
||||
it will overwrite this changes*/
|
||||
} else {
|
||||
lv_anim_t a;
|
||||
a.var = ddlist;
|
||||
a.start = lv_obj_get_height(ddlist);
|
||||
a.end = new_height;
|
||||
a.fp = (lv_anim_fp_t)lv_ddlist_adjust_height;
|
||||
a.path = lv_anim_path_linear;
|
||||
a.end_cb = (lv_anim_cb_t)lv_ddlist_anim_cb;
|
||||
a.act_time = 0;
|
||||
a.time = ext->anim_time;
|
||||
a.playback = 0;
|
||||
a.var = ddlist;
|
||||
a.start = lv_obj_get_height(ddlist);
|
||||
a.end = new_height;
|
||||
a.fp = (lv_anim_fp_t)lv_ddlist_adjust_height;
|
||||
a.path = lv_anim_path_linear;
|
||||
a.end_cb = (lv_anim_cb_t)lv_ddlist_anim_cb;
|
||||
a.act_time = 0;
|
||||
a.time = ext->anim_time;
|
||||
a.playback = 0;
|
||||
a.playback_pause = 0;
|
||||
a.repeat = 0;
|
||||
a.repeat_pause = 0;
|
||||
a.repeat = 0;
|
||||
a.repeat_pause = 0;
|
||||
|
||||
ext->force_sel = 1; /*Keep the list item selected*/
|
||||
lv_anim_create(&a);
|
||||
@ -891,12 +875,13 @@ static void lv_ddlist_refr_size(lv_obj_t * ddlist, bool anim_en)
|
||||
* Called at end of list animation.
|
||||
* @param ddlist pointer to a drop down list
|
||||
*/
|
||||
static void lv_ddlist_anim_cb(lv_obj_t * ddlist) {
|
||||
lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist);
|
||||
static void lv_ddlist_anim_cb(lv_obj_t * ddlist)
|
||||
{
|
||||
lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist);
|
||||
|
||||
lv_ddlist_pos_current_option(ddlist);
|
||||
lv_ddlist_pos_current_option(ddlist);
|
||||
|
||||
ext->force_sel = 0; /*Turn off drawing of selection*/
|
||||
ext->force_sel = 0; /*Turn off drawing of selection*/
|
||||
|
||||
if(ext->opened) lv_page_set_sb_mode(ddlist, LV_SB_MODE_UNHIDE);
|
||||
}
|
||||
@ -907,9 +892,10 @@ static void lv_ddlist_anim_cb(lv_obj_t * ddlist) {
|
||||
* @param ddlist Drop down list object
|
||||
* @param height New drop down list height
|
||||
*/
|
||||
static void lv_ddlist_adjust_height(lv_obj_t * ddlist, int32_t height) {
|
||||
lv_obj_set_height(ddlist, height);
|
||||
lv_ddlist_pos_current_option(ddlist);
|
||||
static void lv_ddlist_adjust_height(lv_obj_t * ddlist, int32_t height)
|
||||
{
|
||||
lv_obj_set_height(ddlist, height);
|
||||
lv_ddlist_pos_current_option(ddlist);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -918,18 +904,18 @@ static void lv_ddlist_adjust_height(lv_obj_t * ddlist, int32_t height) {
|
||||
*/
|
||||
static void lv_ddlist_pos_current_option(lv_obj_t * ddlist)
|
||||
{
|
||||
lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist);
|
||||
lv_style_t * style = lv_obj_get_style(ddlist);
|
||||
const lv_font_t * font = style->text.font;
|
||||
lv_coord_t font_h = lv_font_get_height(font);
|
||||
lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist);
|
||||
lv_style_t * style = lv_obj_get_style(ddlist);
|
||||
const lv_font_t * font = style->text.font;
|
||||
lv_coord_t font_h = lv_font_get_height(font);
|
||||
lv_style_t * label_style = lv_obj_get_style(ext->label);
|
||||
lv_obj_t * scrl = lv_page_get_scrl(ddlist);
|
||||
lv_obj_t * scrl = lv_page_get_scrl(ddlist);
|
||||
|
||||
lv_coord_t h = lv_obj_get_height(ddlist);
|
||||
lv_coord_t line_y1 = ext->sel_opt_id * (font_h + label_style->text.line_space) + ext->label->coords.y1 - scrl->coords.y1;
|
||||
|
||||
lv_obj_set_y(scrl, - line_y1 + (h - font_h) / 2);
|
||||
lv_coord_t h = lv_obj_get_height(ddlist);
|
||||
lv_coord_t line_y1 = ext->sel_opt_id * (font_h + label_style->text.line_space) +
|
||||
ext->label->coords.y1 - scrl->coords.y1;
|
||||
|
||||
lv_obj_set_y(scrl, -line_y1 + (h - font_h) / 2);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -46,17 +46,17 @@ typedef struct
|
||||
{
|
||||
lv_page_ext_t page; /*Ext. of ancestor*/
|
||||
/*New data for this type */
|
||||
lv_obj_t *label; /*Label for the options*/
|
||||
lv_style_t * sel_style; /*Style of the selected option*/
|
||||
uint16_t option_cnt; /*Number of options*/
|
||||
uint16_t sel_opt_id; /*Index of the current option*/
|
||||
uint16_t sel_opt_id_ori; /*Store the original index on focus*/
|
||||
uint16_t anim_time; /*Open/Close animation time [ms]*/
|
||||
uint8_t opened :1; /*1: The list is opened (handled by the library)*/
|
||||
uint8_t force_sel :1; /*1: Keep the selection highlight even if the list is closed*/
|
||||
uint8_t draw_arrow :1; /*1: Draw arrow*/
|
||||
uint8_t stay_open :1; /*1: Don't close the list when a new item is selected*/
|
||||
lv_coord_t fix_height; /*Height of the ddlist when opened. (0: auto-size)*/
|
||||
lv_obj_t * label; /*Label for the options*/
|
||||
lv_style_t * sel_style; /*Style of the selected option*/
|
||||
uint16_t option_cnt; /*Number of options*/
|
||||
uint16_t sel_opt_id; /*Index of the current option*/
|
||||
uint16_t sel_opt_id_ori; /*Store the original index on focus*/
|
||||
uint16_t anim_time; /*Open/Close animation time [ms]*/
|
||||
uint8_t opened : 1; /*1: The list is opened (handled by the library)*/
|
||||
uint8_t force_sel : 1; /*1: Keep the selection highlight even if the list is closed*/
|
||||
uint8_t draw_arrow : 1; /*1: Draw arrow*/
|
||||
uint8_t stay_open : 1; /*1: Don't close the list when a new item is selected*/
|
||||
lv_coord_t fix_height; /*Height of the ddlist when opened. (0: auto-size)*/
|
||||
} lv_ddlist_ext_t;
|
||||
|
||||
enum {
|
||||
@ -72,7 +72,8 @@ typedef uint8_t lv_ddlist_style_t;
|
||||
/**
|
||||
* Create a drop down list objects
|
||||
* @param par pointer to an object, it will be the parent of the new drop down list
|
||||
* @param copy pointer to a drop down list object, if not NULL then the new object will be copied from it
|
||||
* @param copy pointer to a drop down list object, if not NULL then the new object will be copied
|
||||
* from it
|
||||
* @return pointer to the created drop down list
|
||||
*/
|
||||
lv_obj_t * lv_ddlist_create(lv_obj_t * par, const lv_obj_t * copy);
|
||||
@ -103,7 +104,6 @@ void lv_ddlist_set_selected(lv_obj_t * ddlist, uint16_t sel_opt);
|
||||
*/
|
||||
void lv_ddlist_set_fix_height(lv_obj_t * ddlist, lv_coord_t h);
|
||||
|
||||
|
||||
/**
|
||||
* Enable or disable the horizontal fit to the content
|
||||
* @param ddlist pointer to a drop down list
|
||||
@ -142,27 +142,25 @@ static inline void lv_ddlist_set_sb_mode(lv_obj_t * ddlist, lv_sb_mode_t mode)
|
||||
*/
|
||||
void lv_ddlist_set_anim_time(lv_obj_t * ddlist, uint16_t anim_time);
|
||||
|
||||
|
||||
/**
|
||||
* Set a style of a drop down list
|
||||
* @param ddlist pointer to a drop down list object
|
||||
* @param type which style should be set
|
||||
* @param style pointer to a style
|
||||
* */
|
||||
void lv_ddlist_set_style(lv_obj_t *ddlist, lv_ddlist_style_t type, lv_style_t *style);
|
||||
void lv_ddlist_set_style(lv_obj_t * ddlist, lv_ddlist_style_t type, lv_style_t * style);
|
||||
|
||||
/**
|
||||
* Set the alignment of the labels in a drop down list
|
||||
* @param ddlist pointer to a drop down list object
|
||||
* @param align alignment of labels
|
||||
*/
|
||||
void lv_ddlist_set_align(lv_obj_t *ddlist, lv_label_align_t align);
|
||||
void lv_ddlist_set_align(lv_obj_t * ddlist, lv_label_align_t align);
|
||||
|
||||
/*=====================
|
||||
* Getter functions
|
||||
*====================*/
|
||||
|
||||
|
||||
/**
|
||||
* Get the options of a drop down list
|
||||
* @param ddlist pointer to drop down list object
|
||||
@ -227,14 +225,14 @@ uint16_t lv_ddlist_get_anim_time(const lv_obj_t * ddlist);
|
||||
* @param type which style should be get
|
||||
* @return style pointer to a style
|
||||
*/
|
||||
lv_style_t * lv_ddlist_get_style(const lv_obj_t *ddlist, lv_ddlist_style_t type);
|
||||
lv_style_t * lv_ddlist_get_style(const lv_obj_t * ddlist, lv_ddlist_style_t type);
|
||||
|
||||
/**
|
||||
* Get the alignment of the labels in a drop down list
|
||||
* @param ddlist pointer to a drop down list object
|
||||
* @return alignment of labels
|
||||
*/
|
||||
lv_label_align_t lv_ddlist_get_align(const lv_obj_t *ddlist);
|
||||
lv_label_align_t lv_ddlist_get_align(const lv_obj_t * ddlist);
|
||||
|
||||
/*=====================
|
||||
* Other functions
|
||||
@ -258,10 +256,10 @@ void lv_ddlist_close(lv_obj_t * ddlist, bool anim_en);
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_DDLIST*/
|
||||
#endif /*LV_USE_DDLIST*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_DDLIST_H*/
|
||||
#endif /*LV_DDLIST_H*/
|
||||
|
@ -3,7 +3,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
@ -21,12 +20,12 @@
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define LV_GAUGE_DEF_NEEDLE_COLOR LV_COLOR_RED
|
||||
#define LV_GAUGE_DEF_LABEL_COUNT 6
|
||||
#define LV_GAUGE_DEF_LINE_COUNT 21 /*Should be: ((label_cnt - 1) * internal_lines) + 1*/
|
||||
#define LV_GAUGE_DEF_ANGLE 220
|
||||
#define LV_GAUGE_INTERPOLATE_SHIFT 5 /*Interpolate the needle drawing between to degrees*/
|
||||
#define LV_GAUGE_INTERPOLATE_MASK 0x1F
|
||||
#define LV_GAUGE_DEF_NEEDLE_COLOR LV_COLOR_RED
|
||||
#define LV_GAUGE_DEF_LABEL_COUNT 6
|
||||
#define LV_GAUGE_DEF_LINE_COUNT 21 /*Should be: ((label_cnt - 1) * internal_lines) + 1*/
|
||||
#define LV_GAUGE_DEF_ANGLE 220
|
||||
#define LV_GAUGE_INTERPOLATE_SHIFT 5 /*Interpolate the needle drawing between to degrees*/
|
||||
#define LV_GAUGE_INTERPOLATE_MASK 0x1F
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
@ -75,10 +74,10 @@ lv_obj_t * lv_gauge_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
if(ext == NULL) return NULL;
|
||||
|
||||
/*Initialize the allocated 'ext' */
|
||||
ext->needle_count = 0;
|
||||
ext->values = NULL;
|
||||
ext->needle_count = 0;
|
||||
ext->values = NULL;
|
||||
ext->needle_colors = NULL;
|
||||
ext->label_count = LV_GAUGE_DEF_LABEL_COUNT;
|
||||
ext->label_count = LV_GAUGE_DEF_LABEL_COUNT;
|
||||
if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_func(new_gauge);
|
||||
if(ancestor_design == NULL) ancestor_design = lv_obj_get_design_func(new_gauge);
|
||||
|
||||
@ -88,7 +87,8 @@ lv_obj_t * lv_gauge_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
|
||||
/*Init the new gauge gauge*/
|
||||
if(copy == NULL) {
|
||||
lv_gauge_set_scale(new_gauge, LV_GAUGE_DEF_ANGLE, LV_GAUGE_DEF_LINE_COUNT, LV_GAUGE_DEF_LABEL_COUNT);
|
||||
lv_gauge_set_scale(new_gauge, LV_GAUGE_DEF_ANGLE, LV_GAUGE_DEF_LINE_COUNT,
|
||||
LV_GAUGE_DEF_LABEL_COUNT);
|
||||
lv_gauge_set_needle_count(new_gauge, 1, NULL);
|
||||
lv_gauge_set_critical_value(new_gauge, 80);
|
||||
lv_obj_set_size(new_gauge, 2 * LV_DPI, 2 * LV_DPI);
|
||||
@ -170,26 +170,26 @@ void lv_gauge_set_value(lv_obj_t * gauge, uint8_t needle_id, int16_t value)
|
||||
if(needle_id >= ext->needle_count) return;
|
||||
if(ext->values[needle_id] == value) return;
|
||||
|
||||
|
||||
int16_t min = lv_gauge_get_min_value(gauge);
|
||||
int16_t max = lv_gauge_get_max_value(gauge);
|
||||
|
||||
if(value > max) value = max;
|
||||
else if(value < min) value = min;
|
||||
if(value > max)
|
||||
value = max;
|
||||
else if(value < min)
|
||||
value = min;
|
||||
|
||||
ext->values[needle_id] = value;
|
||||
|
||||
|
||||
lv_obj_invalidate(gauge);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the scale settings of a gauge
|
||||
* @param gauge pointer to a gauge object
|
||||
* @param angle angle of the scale (0..360)
|
||||
* @param line_cnt count of scale lines.
|
||||
* The get a given "subdivision" lines between label, `line_cnt` = (sub_div + 1) * (label_cnt - 1) + 1
|
||||
* The get a given "subdivision" lines between label, `line_cnt` = (sub_div + 1) * (label_cnt - 1) +
|
||||
* 1
|
||||
* @param label_cnt count of scale labels.
|
||||
*/
|
||||
void lv_gauge_set_scale(lv_obj_t * gauge, uint16_t angle, uint8_t line_cnt, uint8_t label_cnt)
|
||||
@ -199,7 +199,7 @@ void lv_gauge_set_scale(lv_obj_t * gauge, uint16_t angle, uint8_t line_cnt, uint
|
||||
lv_lmeter_set_scale(gauge, angle, line_cnt);
|
||||
|
||||
lv_gauge_ext_t * ext = lv_obj_get_ext_attr(gauge);
|
||||
ext->label_count = label_cnt;
|
||||
ext->label_count = label_cnt;
|
||||
lv_obj_invalidate(gauge);
|
||||
}
|
||||
|
||||
@ -213,10 +213,10 @@ void lv_gauge_set_scale(lv_obj_t * gauge, uint16_t angle, uint8_t line_cnt, uint
|
||||
* @param needle the id of the needle
|
||||
* @return the value of the needle [min,max]
|
||||
*/
|
||||
int16_t lv_gauge_get_value(const lv_obj_t * gauge, uint8_t needle)
|
||||
int16_t lv_gauge_get_value(const lv_obj_t * gauge, uint8_t needle)
|
||||
{
|
||||
lv_gauge_ext_t * ext = lv_obj_get_ext_attr(gauge);
|
||||
int16_t min = lv_gauge_get_min_value(gauge);
|
||||
int16_t min = lv_gauge_get_min_value(gauge);
|
||||
|
||||
if(needle >= ext->needle_count) return min;
|
||||
|
||||
@ -273,28 +273,28 @@ static bool lv_gauge_design(lv_obj_t * gauge, const lv_area_t * mask, lv_design_
|
||||
* If the object is in focus 'lv_obj_get_style()' will give a pointer to tmp style
|
||||
* and to the real object style. It is important because of style change tricks below*/
|
||||
lv_style_t * style_ori_p = gauge->style_p;
|
||||
lv_style_t * style = lv_obj_get_style(gauge);
|
||||
lv_gauge_ext_t * ext = lv_obj_get_ext_attr(gauge);
|
||||
lv_style_t * style = lv_obj_get_style(gauge);
|
||||
lv_gauge_ext_t * ext = lv_obj_get_ext_attr(gauge);
|
||||
|
||||
lv_gauge_draw_scale(gauge, mask);
|
||||
|
||||
/*Draw the ancestor line meter with max value to show the rainbow like line colors*/
|
||||
uint16_t line_cnt_tmp = ext->lmeter.line_cnt;
|
||||
ancestor_design(gauge, mask, mode); /*To draw lines*/
|
||||
ancestor_design(gauge, mask, mode); /*To draw lines*/
|
||||
|
||||
/*Temporally modify the line meter to draw thicker and longer lines where labels are*/
|
||||
lv_style_t style_tmp;
|
||||
lv_style_copy(&style_tmp, style);
|
||||
ext->lmeter.line_cnt = ext->label_count; /*Only to labels*/
|
||||
style_tmp.line.width = style_tmp.line.width * 2; /*Ticker lines*/
|
||||
style_tmp.body.padding.left = style_tmp.body.padding.left * 2; /*Longer lines*/
|
||||
style_tmp.body.padding.right = style_tmp.body.padding.right * 2; /*Longer lines*/
|
||||
gauge->style_p = &style_tmp;
|
||||
ext->lmeter.line_cnt = ext->label_count; /*Only to labels*/
|
||||
style_tmp.line.width = style_tmp.line.width * 2; /*Ticker lines*/
|
||||
style_tmp.body.padding.left = style_tmp.body.padding.left * 2; /*Longer lines*/
|
||||
style_tmp.body.padding.right = style_tmp.body.padding.right * 2; /*Longer lines*/
|
||||
gauge->style_p = &style_tmp;
|
||||
|
||||
ancestor_design(gauge, mask, mode); /*To draw lines*/
|
||||
ancestor_design(gauge, mask, mode); /*To draw lines*/
|
||||
|
||||
ext->lmeter.line_cnt = line_cnt_tmp; /*Restore the parameters*/
|
||||
gauge->style_p = style_ori_p; /*Restore the ORIGINAL style pointer*/
|
||||
ext->lmeter.line_cnt = line_cnt_tmp; /*Restore the parameters*/
|
||||
gauge->style_p = style_ori_p; /*Restore the ORIGINAL style pointer*/
|
||||
|
||||
lv_gauge_draw_needle(gauge, mask);
|
||||
|
||||
@ -329,7 +329,7 @@ static lv_res_t lv_gauge_signal(lv_obj_t * gauge, lv_signal_t sign, void * param
|
||||
} else if(sign == LV_SIGNAL_GET_TYPE) {
|
||||
lv_obj_type_t * buf = param;
|
||||
uint8_t i;
|
||||
for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/
|
||||
for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/
|
||||
if(buf->type[i] == NULL) break;
|
||||
}
|
||||
buf->type[i] = "lv_gauge";
|
||||
@ -348,16 +348,17 @@ static void lv_gauge_draw_scale(lv_obj_t * gauge, const lv_area_t * mask)
|
||||
char scale_txt[16];
|
||||
|
||||
lv_gauge_ext_t * ext = lv_obj_get_ext_attr(gauge);
|
||||
lv_style_t * style = lv_obj_get_style(gauge);
|
||||
lv_opa_t opa_scale = lv_obj_get_opa_scale(gauge);
|
||||
lv_coord_t r = lv_obj_get_width(gauge) / 2 - (3 * style->body.padding.left) - style->body.padding.inner;
|
||||
lv_coord_t x_ofs = lv_obj_get_width(gauge) / 2 + gauge->coords.x1;
|
||||
lv_coord_t y_ofs = lv_obj_get_height(gauge) / 2 + gauge->coords.y1;
|
||||
lv_style_t * style = lv_obj_get_style(gauge);
|
||||
lv_opa_t opa_scale = lv_obj_get_opa_scale(gauge);
|
||||
lv_coord_t r =
|
||||
lv_obj_get_width(gauge) / 2 - (3 * style->body.padding.left) - style->body.padding.inner;
|
||||
lv_coord_t x_ofs = lv_obj_get_width(gauge) / 2 + gauge->coords.x1;
|
||||
lv_coord_t y_ofs = lv_obj_get_height(gauge) / 2 + gauge->coords.y1;
|
||||
int16_t scale_angle = lv_lmeter_get_scale_angle(gauge);
|
||||
uint16_t label_num = ext->label_count;
|
||||
int16_t angle_ofs = 90 + (360 - scale_angle) / 2;
|
||||
int16_t min = lv_gauge_get_min_value(gauge);
|
||||
int16_t max = lv_gauge_get_max_value(gauge);
|
||||
uint16_t label_num = ext->label_count;
|
||||
int16_t angle_ofs = 90 + (360 - scale_angle) / 2;
|
||||
int16_t min = lv_gauge_get_min_value(gauge);
|
||||
int16_t max = lv_gauge_get_max_value(gauge);
|
||||
|
||||
uint8_t i;
|
||||
for(i = 0; i < label_num; i++) {
|
||||
@ -376,8 +377,8 @@ static void lv_gauge_draw_scale(lv_obj_t * gauge, const lv_area_t * mask)
|
||||
|
||||
lv_area_t label_cord;
|
||||
lv_point_t label_size;
|
||||
lv_txt_get_size(&label_size, scale_txt, style->text.font,
|
||||
style->text.letter_space, style->text.line_space, LV_COORD_MAX, LV_TXT_FLAG_NONE);
|
||||
lv_txt_get_size(&label_size, scale_txt, style->text.font, style->text.letter_space,
|
||||
style->text.line_space, LV_COORD_MAX, LV_TXT_FLAG_NONE);
|
||||
|
||||
/*Draw the label*/
|
||||
label_cord.x1 = x - label_size.x / 2;
|
||||
@ -385,7 +386,8 @@ static void lv_gauge_draw_scale(lv_obj_t * gauge, const lv_area_t * mask)
|
||||
label_cord.x2 = label_cord.x1 + label_size.x;
|
||||
label_cord.y2 = label_cord.y1 + label_size.y;
|
||||
|
||||
lv_draw_label(&label_cord, mask, style, opa_scale, scale_txt, LV_TXT_FLAG_NONE, NULL, -1, -1);
|
||||
lv_draw_label(&label_cord, mask, style, opa_scale, scale_txt, LV_TXT_FLAG_NONE, NULL, -1,
|
||||
-1);
|
||||
}
|
||||
}
|
||||
/**
|
||||
@ -397,16 +399,16 @@ static void lv_gauge_draw_needle(lv_obj_t * gauge, const lv_area_t * mask)
|
||||
{
|
||||
lv_style_t style_needle;
|
||||
lv_gauge_ext_t * ext = lv_obj_get_ext_attr(gauge);
|
||||
lv_style_t * style = lv_gauge_get_style(gauge);
|
||||
lv_opa_t opa_scale = lv_obj_get_opa_scale(gauge);
|
||||
lv_style_t * style = lv_gauge_get_style(gauge);
|
||||
lv_opa_t opa_scale = lv_obj_get_opa_scale(gauge);
|
||||
|
||||
lv_coord_t r = lv_obj_get_width(gauge) / 2 - style->body.padding.left;
|
||||
lv_coord_t x_ofs = lv_obj_get_width(gauge) / 2 + gauge->coords.x1;
|
||||
lv_coord_t y_ofs = lv_obj_get_height(gauge) / 2 + gauge->coords.y1;
|
||||
uint16_t angle = lv_lmeter_get_scale_angle(gauge);
|
||||
lv_coord_t r = lv_obj_get_width(gauge) / 2 - style->body.padding.left;
|
||||
lv_coord_t x_ofs = lv_obj_get_width(gauge) / 2 + gauge->coords.x1;
|
||||
lv_coord_t y_ofs = lv_obj_get_height(gauge) / 2 + gauge->coords.y1;
|
||||
uint16_t angle = lv_lmeter_get_scale_angle(gauge);
|
||||
int16_t angle_ofs = 90 + (360 - angle) / 2;
|
||||
int16_t min = lv_gauge_get_min_value(gauge);
|
||||
int16_t max = lv_gauge_get_max_value(gauge);
|
||||
int16_t min = lv_gauge_get_min_value(gauge);
|
||||
int16_t max = lv_gauge_get_max_value(gauge);
|
||||
lv_point_t p_mid;
|
||||
lv_point_t p_end;
|
||||
lv_point_t p_end_low;
|
||||
@ -419,13 +421,12 @@ static void lv_gauge_draw_needle(lv_obj_t * gauge, const lv_area_t * mask)
|
||||
p_mid.y = y_ofs;
|
||||
for(i = 0; i < ext->needle_count; i++) {
|
||||
/*Calculate the end point of a needle*/
|
||||
int16_t needle_angle = (ext->values[i] - min) * angle * (1 << LV_GAUGE_INTERPOLATE_SHIFT) / (max - min); //+ angle_ofs;
|
||||
int16_t needle_angle = (ext->values[i] - min) * angle * (1 << LV_GAUGE_INTERPOLATE_SHIFT) /
|
||||
(max - min); //+ angle_ofs;
|
||||
|
||||
|
||||
int16_t needle_angle_low = (needle_angle >> LV_GAUGE_INTERPOLATE_SHIFT) + angle_ofs;
|
||||
int16_t needle_angle_low = (needle_angle >> LV_GAUGE_INTERPOLATE_SHIFT) + angle_ofs;
|
||||
int16_t needle_angle_high = needle_angle_low + 1;
|
||||
|
||||
|
||||
p_end_low.y = (lv_trigo_sin(needle_angle_low) * r) / LV_TRIGO_SIN_MAX + y_ofs;
|
||||
p_end_low.x = (lv_trigo_sin(needle_angle_low + 90) * r) / LV_TRIGO_SIN_MAX + x_ofs;
|
||||
|
||||
@ -433,8 +434,10 @@ static void lv_gauge_draw_needle(lv_obj_t * gauge, const lv_area_t * mask)
|
||||
p_end_high.x = (lv_trigo_sin(needle_angle_high + 90) * r) / LV_TRIGO_SIN_MAX + x_ofs;
|
||||
|
||||
uint16_t rem = needle_angle & ((1 << LV_GAUGE_INTERPOLATE_SHIFT) - 1);
|
||||
int16_t x_mod = ((LV_MATH_ABS(p_end_high.x - p_end_low.x)) * rem) >> LV_GAUGE_INTERPOLATE_SHIFT;
|
||||
int16_t y_mod = ((LV_MATH_ABS(p_end_high.y - p_end_low.y)) * rem) >> LV_GAUGE_INTERPOLATE_SHIFT;
|
||||
int16_t x_mod =
|
||||
((LV_MATH_ABS(p_end_high.x - p_end_low.x)) * rem) >> LV_GAUGE_INTERPOLATE_SHIFT;
|
||||
int16_t y_mod =
|
||||
((LV_MATH_ABS(p_end_high.y - p_end_low.y)) * rem) >> LV_GAUGE_INTERPOLATE_SHIFT;
|
||||
|
||||
if(p_end_high.x < p_end_low.x) x_mod = -x_mod;
|
||||
if(p_end_high.y < p_end_low.y) y_mod = -y_mod;
|
||||
@ -443,8 +446,10 @@ static void lv_gauge_draw_needle(lv_obj_t * gauge, const lv_area_t * mask)
|
||||
p_end.y = p_end_low.y + y_mod;
|
||||
|
||||
/*Draw the needle with the corresponding color*/
|
||||
if(ext->needle_colors == NULL) style_needle.line.color = LV_GAUGE_DEF_NEEDLE_COLOR;
|
||||
else style_needle.line.color = ext->needle_colors[i];
|
||||
if(ext->needle_colors == NULL)
|
||||
style_needle.line.color = LV_GAUGE_DEF_NEEDLE_COLOR;
|
||||
else
|
||||
style_needle.line.color = ext->needle_colors[i];
|
||||
|
||||
lv_draw_line(&p_mid, &p_end, mask, &style_needle, opa_scale);
|
||||
}
|
||||
@ -454,7 +459,7 @@ static void lv_gauge_draw_needle(lv_obj_t * gauge, const lv_area_t * mask)
|
||||
lv_style_copy(&style_neddle_mid, &lv_style_plain);
|
||||
style_neddle_mid.body.main_color = style->body.border.color;
|
||||
style_neddle_mid.body.grad_color = style->body.border.color;
|
||||
style_neddle_mid.body.radius = LV_RADIUS_CIRCLE;
|
||||
style_neddle_mid.body.radius = LV_RADIUS_CIRCLE;
|
||||
|
||||
lv_area_t nm_cord;
|
||||
nm_cord.x1 = x_ofs - style->body.padding.top;
|
||||
|
@ -42,10 +42,10 @@ extern "C" {
|
||||
/*Data of gauge*/
|
||||
typedef struct
|
||||
{
|
||||
lv_lmeter_ext_t lmeter; /*Ext. of ancestor*/
|
||||
lv_lmeter_ext_t lmeter; /*Ext. of ancestor*/
|
||||
/*New data for this type */
|
||||
int16_t * values; /*Array of the set values (for needles) */
|
||||
const lv_color_t * needle_colors; /*Color of the needles (lv_color_t my_colors[needle_num])*/
|
||||
int16_t * values; /*Array of the set values (for needles) */
|
||||
const lv_color_t * needle_colors; /*Color of the needles (lv_color_t my_colors[needle_num])*/
|
||||
uint8_t needle_count; /*Number of needles*/
|
||||
uint8_t label_count; /*Number of labels on the scale*/
|
||||
} lv_gauge_ext_t;
|
||||
@ -88,7 +88,7 @@ void lv_gauge_set_value(lv_obj_t * gauge, uint8_t needle_id, int16_t value);
|
||||
* @param min minimum value
|
||||
* @param max maximum value
|
||||
*/
|
||||
static inline void lv_gauge_set_range(lv_obj_t *gauge, int16_t min, int16_t max)
|
||||
static inline void lv_gauge_set_range(lv_obj_t * gauge, int16_t min, int16_t max)
|
||||
{
|
||||
lv_lmeter_set_range(gauge, min, max);
|
||||
}
|
||||
@ -108,7 +108,8 @@ static inline void lv_gauge_set_critical_value(lv_obj_t * gauge, int16_t value)
|
||||
* @param gauge pointer to a gauge object
|
||||
* @param angle angle of the scale (0..360)
|
||||
* @param line_cnt count of scale lines.
|
||||
* The get a given "subdivision" lines between label, `line_cnt` = (sub_div + 1) * (label_cnt - 1) + 1
|
||||
* The get a given "subdivision" lines between label, `line_cnt` = (sub_div + 1) * (label_cnt - 1) +
|
||||
* 1
|
||||
* @param label_cnt count of scale labels.
|
||||
*/
|
||||
void lv_gauge_set_scale(lv_obj_t * gauge, uint16_t angle, uint8_t line_cnt, uint8_t label_cnt);
|
||||
@ -118,7 +119,7 @@ void lv_gauge_set_scale(lv_obj_t * gauge, uint16_t angle, uint8_t line_cnt, uint
|
||||
* @param gauge pointer to a gauge object
|
||||
* @param bg set the style of the gauge
|
||||
* */
|
||||
static inline void lv_gauge_set_style(lv_obj_t *gauge, lv_style_t *bg)
|
||||
static inline void lv_gauge_set_style(lv_obj_t * gauge, lv_style_t * bg)
|
||||
{
|
||||
lv_obj_set_style(gauge, bg);
|
||||
}
|
||||
@ -133,7 +134,7 @@ static inline void lv_gauge_set_style(lv_obj_t *gauge, lv_style_t *bg)
|
||||
* @param needle the id of the needle
|
||||
* @return the value of the needle [min,max]
|
||||
*/
|
||||
int16_t lv_gauge_get_value(const lv_obj_t * gauge, uint8_t needle);
|
||||
int16_t lv_gauge_get_value(const lv_obj_t * gauge, uint8_t needle);
|
||||
|
||||
/**
|
||||
* Get the count of needles on a gauge
|
||||
@ -204,7 +205,7 @@ static inline uint16_t lv_gauge_get_scale_angle(const lv_obj_t * gauge)
|
||||
* @param gauge pointer to a gauge object
|
||||
* @return pointer to the gauge's style
|
||||
*/
|
||||
static inline lv_style_t * lv_gauge_get_style(const lv_obj_t *gauge)
|
||||
static inline lv_style_t * lv_gauge_get_style(const lv_obj_t * gauge)
|
||||
{
|
||||
return lv_obj_get_style(gauge);
|
||||
}
|
||||
@ -213,10 +214,10 @@ static inline lv_style_t * lv_gauge_get_style(const lv_obj_t *gauge)
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_GAUGE*/
|
||||
#endif /*LV_USE_GAUGE*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_GAUGE_H*/
|
||||
#endif /*LV_GAUGE_H*/
|
||||
|
@ -70,15 +70,14 @@ lv_obj_t * lv_img_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
lv_mem_assert(ext);
|
||||
if(ext == NULL) return NULL;
|
||||
|
||||
ext->src = NULL;
|
||||
ext->src_type = LV_IMG_SRC_UNKNOWN;
|
||||
ext->cf = LV_IMG_CF_UNKNOWN;
|
||||
ext->w = lv_obj_get_width(new_img);
|
||||
ext->h = lv_obj_get_height(new_img);
|
||||
ext->src = NULL;
|
||||
ext->src_type = LV_IMG_SRC_UNKNOWN;
|
||||
ext->cf = LV_IMG_CF_UNKNOWN;
|
||||
ext->w = lv_obj_get_width(new_img);
|
||||
ext->h = lv_obj_get_height(new_img);
|
||||
ext->auto_size = 1;
|
||||
ext->offset.x = 0;
|
||||
ext->offset.y = 0;
|
||||
|
||||
ext->offset.x = 0;
|
||||
ext->offset.y = 0;
|
||||
|
||||
/*Init the new object*/
|
||||
lv_obj_set_signal_cb(new_img, lv_img_signal);
|
||||
@ -91,32 +90,29 @@ lv_obj_t * lv_img_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
* and must be screen sized*/
|
||||
if(par != NULL) {
|
||||
ext->auto_size = 1;
|
||||
lv_obj_set_style(new_img, NULL); /*Inherit the style by default*/
|
||||
lv_obj_set_style(new_img, NULL); /*Inherit the style by default*/
|
||||
} else {
|
||||
ext->auto_size = 0;
|
||||
lv_obj_set_style(new_img, &lv_style_plain); /*Set a style for screens*/
|
||||
lv_obj_set_style(new_img, &lv_style_plain); /*Set a style for screens*/
|
||||
}
|
||||
} else {
|
||||
lv_img_ext_t * copy_ext = lv_obj_get_ext_attr(copy);
|
||||
ext->auto_size = copy_ext->auto_size;
|
||||
ext->auto_size = copy_ext->auto_size;
|
||||
lv_img_set_src(new_img, copy_ext->src);
|
||||
|
||||
/*Refresh the style with new signal function*/
|
||||
lv_obj_refresh_style(new_img);
|
||||
}
|
||||
|
||||
|
||||
LV_LOG_INFO("image created");
|
||||
|
||||
return new_img;
|
||||
}
|
||||
|
||||
|
||||
/*=====================
|
||||
* Setter functions
|
||||
*====================*/
|
||||
|
||||
|
||||
/**
|
||||
* Set the pixel map to display by the image
|
||||
* @param img pointer to an image object
|
||||
@ -125,21 +121,18 @@ lv_obj_t * lv_img_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
void lv_img_set_src(lv_obj_t * img, const void * src_img)
|
||||
{
|
||||
lv_img_src_t src_type = lv_img_src_get_type(src_img);
|
||||
lv_img_ext_t * ext = lv_obj_get_ext_attr(img);
|
||||
lv_img_ext_t * ext = lv_obj_get_ext_attr(img);
|
||||
|
||||
#if LV_USE_LOG && LV_LOG_LEVEL >= LV_LOG_LEVEL_INFO
|
||||
switch(src_type) {
|
||||
case LV_IMG_SRC_FILE:
|
||||
LV_LOG_TRACE("lv_img_set_src: `LV_IMG_SRC_FILE` type found");
|
||||
break;
|
||||
case LV_IMG_SRC_FILE: LV_LOG_TRACE("lv_img_set_src: `LV_IMG_SRC_FILE` type found"); break;
|
||||
case LV_IMG_SRC_VARIABLE:
|
||||
LV_LOG_TRACE("lv_img_set_src: `LV_IMG_SRC_VARIABLE` type found");
|
||||
break;
|
||||
case LV_IMG_SRC_SYMBOL:
|
||||
LV_LOG_TRACE("lv_img_set_src: `LV_IMG_SRC_SYMBOL` type found");
|
||||
break;
|
||||
default:
|
||||
LV_LOG_WARN("lv_img_set_src: unknown type");
|
||||
default: LV_LOG_WARN("lv_img_set_src: unknown type");
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -149,7 +142,7 @@ void lv_img_set_src(lv_obj_t * img, const void * src_img)
|
||||
if(ext->src_type == LV_IMG_SRC_SYMBOL || ext->src_type == LV_IMG_SRC_FILE) {
|
||||
lv_mem_free(ext->src);
|
||||
}
|
||||
ext->src = NULL;
|
||||
ext->src = NULL;
|
||||
ext->src_type = LV_IMG_SRC_UNKNOWN;
|
||||
return;
|
||||
}
|
||||
@ -157,8 +150,6 @@ void lv_img_set_src(lv_obj_t * img, const void * src_img)
|
||||
lv_img_header_t header;
|
||||
lv_img_dsc_get_info(src_img, &header);
|
||||
|
||||
|
||||
|
||||
/*Save the source*/
|
||||
if(src_type == LV_IMG_SRC_VARIABLE) {
|
||||
LV_LOG_INFO("lv_img_set_src: `LV_IMG_SRC_VARIABLE` type found");
|
||||
@ -171,11 +162,11 @@ void lv_img_set_src(lv_obj_t * img, const void * src_img)
|
||||
} else if(src_type == LV_IMG_SRC_FILE || src_type == LV_IMG_SRC_SYMBOL) {
|
||||
/* If the new and the old src are the same then it was only a refresh.*/
|
||||
if(ext->src != src_img) {
|
||||
/*If memory was allocated because of the previous `src_type` then free it*/
|
||||
/*If memory was allocated because of the previous `src_type` then free it*/
|
||||
if(ext->src_type == LV_IMG_SRC_FILE || ext->src_type == LV_IMG_SRC_SYMBOL) {
|
||||
lv_mem_free(ext->src);
|
||||
}
|
||||
char * new_str = lv_mem_alloc(strlen(src_img) + 1);
|
||||
char * new_str = lv_mem_alloc(strlen(src_img) + 1);
|
||||
lv_mem_assert(new_str);
|
||||
if(new_str == NULL) return;
|
||||
strcpy(new_str, src_img);
|
||||
@ -187,15 +178,16 @@ void lv_img_set_src(lv_obj_t * img, const void * src_img)
|
||||
/*`lv_img_dsc_get_info` couldn't set the with and height of a font so set it here*/
|
||||
lv_style_t * style = lv_img_get_style(img);
|
||||
lv_point_t size;
|
||||
lv_txt_get_size(&size, src_img, style->text.font, style->text.letter_space, style->text.line_space, LV_COORD_MAX, LV_TXT_FLAG_NONE);
|
||||
lv_txt_get_size(&size, src_img, style->text.font, style->text.letter_space,
|
||||
style->text.line_space, LV_COORD_MAX, LV_TXT_FLAG_NONE);
|
||||
header.w = size.x;
|
||||
header.h = size.y;
|
||||
}
|
||||
|
||||
ext->src_type = src_type;
|
||||
ext->w = header.w;
|
||||
ext->h = header.h;
|
||||
ext->cf = header.cf;
|
||||
ext->w = header.w;
|
||||
ext->h = header.h;
|
||||
ext->cf = header.cf;
|
||||
|
||||
if(lv_img_get_auto_size(img) != false) {
|
||||
lv_obj_set_size(img, ext->w, ext->h);
|
||||
@ -224,7 +216,7 @@ void lv_img_set_auto_size(lv_obj_t * img, bool en)
|
||||
* @param x: the new offset along x axis.
|
||||
* @param y: the new offset along y axis.
|
||||
*/
|
||||
void lv_img_set_offset(lv_obj_t *img, lv_coord_t x, lv_coord_t y)
|
||||
void lv_img_set_offset(lv_obj_t * img, lv_coord_t x, lv_coord_t y)
|
||||
{
|
||||
lv_img_ext_t * ext = lv_obj_get_ext_attr(img);
|
||||
|
||||
@ -241,7 +233,7 @@ void lv_img_set_offset(lv_obj_t *img, lv_coord_t x, lv_coord_t y)
|
||||
* @param img pointer to an image
|
||||
* @param x: the new offset along x axis.
|
||||
*/
|
||||
void lv_img_set_offset_x(lv_obj_t *img, lv_coord_t x)
|
||||
void lv_img_set_offset_x(lv_obj_t * img, lv_coord_t x)
|
||||
{
|
||||
lv_img_ext_t * ext = lv_obj_get_ext_attr(img);
|
||||
|
||||
@ -249,7 +241,6 @@ void lv_img_set_offset_x(lv_obj_t *img, lv_coord_t x)
|
||||
ext->offset.x = x;
|
||||
lv_obj_invalidate(img);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -258,7 +249,7 @@ void lv_img_set_offset_x(lv_obj_t *img, lv_coord_t x)
|
||||
* @param img pointer to an image
|
||||
* @param y: the new offset along y axis.
|
||||
*/
|
||||
void lv_img_set_offset_y(lv_obj_t *img, lv_coord_t y)
|
||||
void lv_img_set_offset_y(lv_obj_t * img, lv_coord_t y)
|
||||
{
|
||||
lv_img_ext_t * ext = lv_obj_get_ext_attr(img);
|
||||
|
||||
@ -272,7 +263,6 @@ void lv_img_set_offset_y(lv_obj_t *img, lv_coord_t y)
|
||||
* Getter functions
|
||||
*====================*/
|
||||
|
||||
|
||||
/**
|
||||
* Get the source of the image
|
||||
* @param img pointer to an image object
|
||||
@ -294,8 +284,10 @@ const char * lv_img_get_file_name(const lv_obj_t * img)
|
||||
{
|
||||
lv_img_ext_t * ext = lv_obj_get_ext_attr(img);
|
||||
|
||||
if(ext->src_type == LV_IMG_SRC_FILE) return ext->src;
|
||||
else return "";
|
||||
if(ext->src_type == LV_IMG_SRC_FILE)
|
||||
return ext->src;
|
||||
else
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
@ -315,7 +307,7 @@ bool lv_img_get_auto_size(const lv_obj_t * img)
|
||||
* @param img pointer to an image
|
||||
* @return offset.x value.
|
||||
*/
|
||||
lv_coord_t lv_img_get_offset_x(lv_obj_t *img)
|
||||
lv_coord_t lv_img_get_offset_x(lv_obj_t * img)
|
||||
{
|
||||
lv_img_ext_t * ext = lv_obj_get_ext_attr(img);
|
||||
|
||||
@ -327,7 +319,7 @@ lv_coord_t lv_img_get_offset_x(lv_obj_t *img)
|
||||
* @param img pointer to an image
|
||||
* @return offset.y value.
|
||||
*/
|
||||
lv_coord_t lv_img_get_offset_y(lv_obj_t *img)
|
||||
lv_coord_t lv_img_get_offset_y(lv_obj_t * img)
|
||||
{
|
||||
lv_img_ext_t * ext = lv_obj_get_ext_attr(img);
|
||||
|
||||
@ -357,7 +349,8 @@ static bool lv_img_design(lv_obj_t * img, const lv_area_t * mask, lv_design_mode
|
||||
bool cover = false;
|
||||
if(ext->src_type == LV_IMG_SRC_UNKNOWN || ext->src_type == LV_IMG_SRC_SYMBOL) return false;
|
||||
|
||||
if(ext->cf == LV_IMG_CF_TRUE_COLOR || ext->cf == LV_IMG_CF_RAW) cover = lv_area_is_in(mask, &img->coords);
|
||||
if(ext->cf == LV_IMG_CF_TRUE_COLOR || ext->cf == LV_IMG_CF_RAW)
|
||||
cover = lv_area_is_in(mask, &img->coords);
|
||||
|
||||
return cover;
|
||||
} else if(mode == LV_DESIGN_DRAW_MAIN) {
|
||||
@ -370,7 +363,7 @@ static bool lv_img_design(lv_obj_t * img, const lv_area_t * mask, lv_design_mode
|
||||
if(ext->src_type == LV_IMG_SRC_FILE || ext->src_type == LV_IMG_SRC_VARIABLE) {
|
||||
coords.x1 -= ext->offset.x;
|
||||
coords.y1 -= ext->offset.y;
|
||||
|
||||
|
||||
LV_LOG_TRACE("lv_img_design: start to draw image");
|
||||
lv_area_t cords_tmp;
|
||||
cords_tmp.y1 = coords.y1;
|
||||
@ -388,7 +381,8 @@ static bool lv_img_design(lv_obj_t * img, const lv_area_t * mask, lv_design_mode
|
||||
lv_style_t style_mod;
|
||||
lv_style_copy(&style_mod, style);
|
||||
style_mod.text.color = style->image.color;
|
||||
lv_draw_label(&coords, mask, &style_mod, opa_scale, ext->src, LV_TXT_FLAG_NONE, NULL, -1, -1);
|
||||
lv_draw_label(&coords, mask, &style_mod, opa_scale, ext->src, LV_TXT_FLAG_NONE, NULL,
|
||||
-1, -1);
|
||||
} else {
|
||||
/*Trigger the error handler of image drawer*/
|
||||
LV_LOG_WARN("lv_img_design: image source type is unknown");
|
||||
@ -399,7 +393,6 @@ static bool lv_img_design(lv_obj_t * img, const lv_area_t * mask, lv_design_mode
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Signal function of the image
|
||||
* @param img pointer to an image object
|
||||
@ -419,19 +412,18 @@ static lv_res_t lv_img_signal(lv_obj_t * img, lv_signal_t sign, void * param)
|
||||
if(sign == LV_SIGNAL_CLEANUP) {
|
||||
if(ext->src_type == LV_IMG_SRC_FILE || ext->src_type == LV_IMG_SRC_SYMBOL) {
|
||||
lv_mem_free(ext->src);
|
||||
ext->src = NULL;
|
||||
ext->src = NULL;
|
||||
ext->src_type = LV_IMG_SRC_UNKNOWN;
|
||||
}
|
||||
} else if(sign == LV_SIGNAL_STYLE_CHG) {
|
||||
/*Refresh the file name to refresh the symbol text size*/
|
||||
if(ext->src_type == LV_IMG_SRC_SYMBOL) {
|
||||
lv_img_set_src(img, ext->src);
|
||||
|
||||
}
|
||||
} else if(sign == LV_SIGNAL_GET_TYPE) {
|
||||
lv_obj_type_t * buf = param;
|
||||
uint8_t i;
|
||||
for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/
|
||||
for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/
|
||||
if(buf->type[i] == NULL) break;
|
||||
}
|
||||
buf->type[i] = "lv_img";
|
||||
|
@ -39,13 +39,13 @@ typedef struct
|
||||
{
|
||||
/*No inherited ext. because inherited from the base object*/ /*Ext. of ancestor*/
|
||||
/*New data for this type */
|
||||
const void * src; /*Image source: Pointer to an array or a file or a symbol*/
|
||||
const void * src; /*Image source: Pointer to an array or a file or a symbol*/
|
||||
lv_point_t offset;
|
||||
lv_coord_t w; /*Width of the image (Handled by the library)*/
|
||||
lv_coord_t h; /*Height of the image (Handled by the library)*/
|
||||
uint8_t src_type :2; /*See: lv_img_src_t*/
|
||||
uint8_t auto_size :1; /*1: automatically set the object size to the image size*/
|
||||
uint8_t cf :5; /*Color format from `lv_img_color_format_t`*/
|
||||
lv_coord_t w; /*Width of the image (Handled by the library)*/
|
||||
lv_coord_t h; /*Height of the image (Handled by the library)*/
|
||||
uint8_t src_type : 2; /*See: lv_img_src_t*/
|
||||
uint8_t auto_size : 1; /*1: automatically set the object size to the image size*/
|
||||
uint8_t cf : 5; /*Color format from `lv_img_color_format_t`*/
|
||||
} lv_img_ext_t;
|
||||
|
||||
/**********************
|
||||
@ -79,8 +79,8 @@ void lv_img_set_src(lv_obj_t * img, const void * src_img);
|
||||
*/
|
||||
static inline void lv_img_set_file(lv_obj_t * img, const char * fn)
|
||||
{
|
||||
(void) img;
|
||||
(void) fn;
|
||||
(void)img;
|
||||
(void)fn;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -98,7 +98,7 @@ void lv_img_set_auto_size(lv_obj_t * img, bool autosize_en);
|
||||
* @param x: the new offset along x axis.
|
||||
* @param y: the new offset along y axis.
|
||||
*/
|
||||
void lv_img_set_offset(lv_obj_t *img, lv_coord_t x, lv_coord_t y);
|
||||
void lv_img_set_offset(lv_obj_t * img, lv_coord_t x, lv_coord_t y);
|
||||
|
||||
/**
|
||||
* Set an offset for the source of an image.
|
||||
@ -106,7 +106,7 @@ void lv_img_set_offset(lv_obj_t *img, lv_coord_t x, lv_coord_t y);
|
||||
* @param img pointer to an image
|
||||
* @param x: the new offset along x axis.
|
||||
*/
|
||||
void lv_img_set_offset_x(lv_obj_t *img, lv_coord_t x);
|
||||
void lv_img_set_offset_x(lv_obj_t * img, lv_coord_t x);
|
||||
|
||||
/**
|
||||
* Set an offset for the source of an image.
|
||||
@ -114,14 +114,14 @@ void lv_img_set_offset_x(lv_obj_t *img, lv_coord_t x);
|
||||
* @param img pointer to an image
|
||||
* @param y: the new offset along y axis.
|
||||
*/
|
||||
void lv_img_set_offset_y(lv_obj_t *img, lv_coord_t y);
|
||||
|
||||
void lv_img_set_offset_y(lv_obj_t * img, lv_coord_t y);
|
||||
|
||||
/**
|
||||
* Set the style of an image
|
||||
* @param img pointer to an image object
|
||||
* @param style pointer to a style
|
||||
*/
|
||||
static inline void lv_img_set_style(lv_obj_t *img, lv_style_t *style)
|
||||
static inline void lv_img_set_style(lv_obj_t * img, lv_style_t * style)
|
||||
{
|
||||
lv_obj_set_style(img, style);
|
||||
}
|
||||
@ -133,8 +133,8 @@ static inline void lv_img_set_style(lv_obj_t *img, lv_style_t *style)
|
||||
*/
|
||||
static inline void lv_img_set_upscale(lv_obj_t * img, bool upcale)
|
||||
{
|
||||
(void) img;
|
||||
(void) upcale;
|
||||
(void)img;
|
||||
(void)upcale;
|
||||
}
|
||||
|
||||
/*=====================
|
||||
@ -167,21 +167,21 @@ bool lv_img_get_auto_size(const lv_obj_t * img);
|
||||
* @param img pointer to an image
|
||||
* @return offset.x value.
|
||||
*/
|
||||
lv_coord_t lv_img_get_offset_x(lv_obj_t *img);
|
||||
lv_coord_t lv_img_get_offset_x(lv_obj_t * img);
|
||||
|
||||
/**
|
||||
* Get the offset.y attribute of the img object.
|
||||
* @param img pointer to an image
|
||||
* @return offset.y value.
|
||||
*/
|
||||
lv_coord_t lv_img_get_offset_y(lv_obj_t *img);
|
||||
|
||||
lv_coord_t lv_img_get_offset_y(lv_obj_t * img);
|
||||
|
||||
/**
|
||||
* Get the style of an image object
|
||||
* @param img pointer to an image object
|
||||
* @return pointer to the image's style
|
||||
*/
|
||||
static inline lv_style_t* lv_img_get_style(const lv_obj_t *img)
|
||||
static inline lv_style_t * lv_img_get_style(const lv_obj_t * img)
|
||||
{
|
||||
return lv_obj_get_style(img);
|
||||
}
|
||||
@ -204,10 +204,10 @@ static inline bool lv_img_get_upscale(const lv_obj_t * img)
|
||||
/*Use this macro to declare an image in a c file*/
|
||||
#define LV_IMG_DECLARE(var_name) extern const lv_img_dsc_t var_name;
|
||||
|
||||
#endif /*LV_USE_IMG*/
|
||||
#endif /*LV_USE_IMG*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_IMG_H*/
|
||||
#endif /*LV_IMG_H*/
|
||||
|
@ -41,7 +41,8 @@ static lv_design_cb_t ancestor_design;
|
||||
/**
|
||||
* Create a image button object
|
||||
* @param par pointer to an object, it will be the parent of the new image button
|
||||
* @param copy pointer to a image button object, if not NULL then the new object will be copied from it
|
||||
* @param copy pointer to a image button object, if not NULL then the new object will be copied from
|
||||
* it
|
||||
* @return pointer to the created image button
|
||||
*/
|
||||
lv_obj_t * lv_imgbtn_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
@ -60,7 +61,7 @@ lv_obj_t * lv_imgbtn_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_func(new_imgbtn);
|
||||
if(ancestor_design == NULL) ancestor_design = lv_obj_get_design_func(new_imgbtn);
|
||||
|
||||
/*Initialize the allocated 'ext' */
|
||||
/*Initialize the allocated 'ext' */
|
||||
#if LV_IMGBTN_TILED == 0
|
||||
memset(ext->img_src, 0, sizeof(ext->img_src));
|
||||
#else
|
||||
@ -123,11 +124,15 @@ void lv_imgbtn_set_src(lv_obj_t * imgbtn, lv_btn_state_t state, const void * src
|
||||
* Set images for a state of the image button
|
||||
* @param imgbtn pointer to an image button object
|
||||
* @param state for which state set the new image (from `lv_btn_state_t`) `
|
||||
* @param src_left pointer to an image source for the left side of the button (a C array or path to a file)
|
||||
* @param src_mid pointer to an image source for the middle of the button (ideally 1px wide) (a C array or path to a file)
|
||||
* @param src_right pointer to an image source for the right side of the button (a C array or path to a file)
|
||||
* @param src_left pointer to an image source for the left side of the button (a C array or path to
|
||||
* a file)
|
||||
* @param src_mid pointer to an image source for the middle of the button (ideally 1px wide) (a C
|
||||
* array or path to a file)
|
||||
* @param src_right pointer to an image source for the right side of the button (a C array or path
|
||||
* to a file)
|
||||
*/
|
||||
void lv_imgbtn_set_src(lv_obj_t * imgbtn, lv_btn_state_t state, const void * src_left, const void * src_mid, const void * src_right)
|
||||
void lv_imgbtn_set_src(lv_obj_t * imgbtn, lv_btn_state_t state, const void * src_left,
|
||||
const void * src_mid, const void * src_right)
|
||||
{
|
||||
lv_imgbtn_ext_t * ext = lv_obj_get_ext_attr(imgbtn);
|
||||
|
||||
@ -249,7 +254,7 @@ static bool lv_imgbtn_design(lv_obj_t * imgbtn, const lv_area_t * mask, lv_desig
|
||||
/*Return false if the object is not covers the mask_p area*/
|
||||
if(mode == LV_DESIGN_COVER_CHK) {
|
||||
lv_imgbtn_ext_t * ext = lv_obj_get_ext_attr(imgbtn);
|
||||
bool cover = false;
|
||||
bool cover = false;
|
||||
if(ext->act_cf == LV_IMG_CF_TRUE_COLOR || ext->act_cf == LV_IMG_CF_RAW) {
|
||||
cover = lv_area_is_in(mask, &imgbtn->coords);
|
||||
}
|
||||
@ -260,9 +265,9 @@ static bool lv_imgbtn_design(lv_obj_t * imgbtn, const lv_area_t * mask, lv_desig
|
||||
else if(mode == LV_DESIGN_DRAW_MAIN) {
|
||||
/*Just draw an image*/
|
||||
lv_imgbtn_ext_t * ext = lv_obj_get_ext_attr(imgbtn);
|
||||
lv_btn_state_t state = lv_imgbtn_get_state(imgbtn);
|
||||
lv_style_t * style = lv_imgbtn_get_style(imgbtn, state);
|
||||
lv_opa_t opa_scale = lv_obj_get_opa_scale(imgbtn);
|
||||
lv_btn_state_t state = lv_imgbtn_get_state(imgbtn);
|
||||
lv_style_t * style = lv_imgbtn_get_style(imgbtn, state);
|
||||
lv_opa_t opa_scale = lv_obj_get_opa_scale(imgbtn);
|
||||
|
||||
#if LV_IMGBTN_TILED == 0
|
||||
const void * src = ext->img_src[state];
|
||||
@ -302,7 +307,7 @@ static bool lv_imgbtn_design(lv_obj_t * imgbtn, const lv_area_t * mask, lv_desig
|
||||
lv_coord_t i;
|
||||
lv_img_dsc_get_info(src, &header);
|
||||
|
||||
coords.x1 = imgbtn->coords.x1 + left_w ;
|
||||
coords.x1 = imgbtn->coords.x1 + left_w;
|
||||
coords.y1 = imgbtn->coords.y1;
|
||||
coords.x2 = coords.x1 + header.w - 1;
|
||||
coords.y2 = imgbtn->coords.y1 + header.h - 1;
|
||||
@ -314,13 +319,11 @@ static bool lv_imgbtn_design(lv_obj_t * imgbtn, const lv_area_t * mask, lv_desig
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
/*Post draw when the children are drawn*/
|
||||
else if(mode == LV_DESIGN_DRAW_POST) {
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -342,15 +345,15 @@ static lv_res_t lv_imgbtn_signal(lv_obj_t * imgbtn, lv_signal_t sign, void * par
|
||||
if(res != LV_RES_OK) return res;
|
||||
|
||||
if(sign == LV_SIGNAL_STYLE_CHG) {
|
||||
/* If the style changed then the button was clicked, released etc. so probably the state was changed as well
|
||||
* Set the new image for the new state.*/
|
||||
/* If the style changed then the button was clicked, released etc. so probably the state was
|
||||
* changed as well Set the new image for the new state.*/
|
||||
refr_img(imgbtn);
|
||||
} else if(sign == LV_SIGNAL_CLEANUP) {
|
||||
/*Nothing to cleanup. (No dynamically allocated memory in 'ext')*/
|
||||
} else if(sign == LV_SIGNAL_GET_TYPE) {
|
||||
lv_obj_type_t * buf = param;
|
||||
uint8_t i;
|
||||
for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/
|
||||
for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/
|
||||
if(buf->type[i] == NULL) break;
|
||||
}
|
||||
buf->type[i] = "lv_imgbtn";
|
||||
@ -359,11 +362,10 @@ static lv_res_t lv_imgbtn_signal(lv_obj_t * imgbtn, lv_signal_t sign, void * par
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
static void refr_img(lv_obj_t * imgbtn)
|
||||
{
|
||||
lv_imgbtn_ext_t * ext = lv_obj_get_ext_attr(imgbtn);
|
||||
lv_btn_state_t state = lv_imgbtn_get_state(imgbtn);
|
||||
lv_btn_state_t state = lv_imgbtn_get_state(imgbtn);
|
||||
lv_img_header_t header;
|
||||
|
||||
#if LV_IMGBTN_TILED == 0
|
||||
|
@ -38,20 +38,20 @@ extern "C" {
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
/*Data of image button*/
|
||||
typedef struct {
|
||||
typedef struct
|
||||
{
|
||||
lv_btn_ext_t btn; /*Ext. of ancestor*/
|
||||
/*New data for this type */
|
||||
#if LV_IMGBTN_TILED == 0
|
||||
const void * img_src[LV_BTN_STATE_NUM]; /*Store images to each state*/
|
||||
const void * img_src[LV_BTN_STATE_NUM]; /*Store images to each state*/
|
||||
#else
|
||||
const void * img_src_left[LV_BTN_STATE_NUM]; /*Store left side images to each state*/
|
||||
const void * img_src_mid[LV_BTN_STATE_NUM]; /*Store center images to each state*/
|
||||
const void * img_src_right[LV_BTN_STATE_NUM]; /*Store right side images to each state*/
|
||||
const void * img_src_left[LV_BTN_STATE_NUM]; /*Store left side images to each state*/
|
||||
const void * img_src_mid[LV_BTN_STATE_NUM]; /*Store center images to each state*/
|
||||
const void * img_src_right[LV_BTN_STATE_NUM]; /*Store right side images to each state*/
|
||||
#endif
|
||||
lv_img_cf_t act_cf; /*Color format of the currently active image*/
|
||||
lv_img_cf_t act_cf; /*Color format of the currently active image*/
|
||||
} lv_imgbtn_ext_t;
|
||||
|
||||
|
||||
/*Styles*/
|
||||
enum {
|
||||
LV_IMGBTN_STYLE_REL,
|
||||
@ -62,7 +62,6 @@ enum {
|
||||
};
|
||||
typedef uint8_t lv_imgbtn_style_t;
|
||||
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
@ -70,7 +69,8 @@ typedef uint8_t lv_imgbtn_style_t;
|
||||
/**
|
||||
* Create a image button objects
|
||||
* @param par pointer to an object, it will be the parent of the new image button
|
||||
* @param copy pointer to a image button object, if not NULL then the new object will be copied from it
|
||||
* @param copy pointer to a image button object, if not NULL then the new object will be copied from
|
||||
* it
|
||||
* @return pointer to the created image button
|
||||
*/
|
||||
lv_obj_t * lv_imgbtn_create(lv_obj_t * par, const lv_obj_t * copy);
|
||||
@ -79,7 +79,6 @@ lv_obj_t * lv_imgbtn_create(lv_obj_t * par, const lv_obj_t * copy);
|
||||
* Add/remove functions
|
||||
*=====================*/
|
||||
|
||||
|
||||
/*=====================
|
||||
* Setter functions
|
||||
*====================*/
|
||||
@ -97,11 +96,15 @@ void lv_imgbtn_set_src(lv_obj_t * imgbtn, lv_btn_state_t state, const void * src
|
||||
* Set images for a state of the image button
|
||||
* @param imgbtn pointer to an image button object
|
||||
* @param state for which state set the new image (from `lv_btn_state_t`) `
|
||||
* @param src_left pointer to an image source for the left side of the button (a C array or path to a file)
|
||||
* @param src_mid pointer to an image source for the middle of the button (ideally 1px wide) (a C array or path to a file)
|
||||
* @param src_right pointer to an image source for the right side of the button (a C array or path to a file)
|
||||
* @param src_left pointer to an image source for the left side of the button (a C array or path to
|
||||
* a file)
|
||||
* @param src_mid pointer to an image source for the middle of the button (ideally 1px wide) (a C
|
||||
* array or path to a file)
|
||||
* @param src_right pointer to an image source for the right side of the button (a C array or path
|
||||
* to a file)
|
||||
*/
|
||||
void lv_imgbtn_set_src(lv_obj_t * imgbtn, lv_btn_state_t state, const void * src_left, const void * src_mid, const void * src_right);
|
||||
void lv_imgbtn_set_src(lv_obj_t * imgbtn, lv_btn_state_t state, const void * src_left,
|
||||
const void * src_mid, const void * src_right);
|
||||
|
||||
#endif
|
||||
|
||||
@ -140,13 +143,12 @@ static inline void lv_imgbtn_toggle(lv_obj_t * imgbtn)
|
||||
* @param type which style should be set
|
||||
* @param style pointer to a style
|
||||
*/
|
||||
void lv_imgbtn_set_style(lv_obj_t * imgbtn, lv_imgbtn_style_t type, lv_style_t *style);
|
||||
void lv_imgbtn_set_style(lv_obj_t * imgbtn, lv_imgbtn_style_t type, lv_style_t * style);
|
||||
|
||||
/*=====================
|
||||
* Getter functions
|
||||
*====================*/
|
||||
|
||||
|
||||
#if LV_IMGBTN_TILED == 0
|
||||
/**
|
||||
* Get the images in a given state
|
||||
@ -219,10 +221,10 @@ lv_style_t * lv_imgbtn_get_style(const lv_obj_t * imgbtn, lv_imgbtn_style_t type
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_IMGBTN*/
|
||||
#endif /*LV_USE_IMGBTN*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_IMGBTN_H*/
|
||||
#endif /*LV_IMGBTN_H*/
|
||||
|
@ -31,61 +31,182 @@ static lv_res_t lv_kb_signal(lv_obj_t * kb, lv_signal_t sign, void * param);
|
||||
**********************/
|
||||
static lv_signal_cb_t ancestor_signal;
|
||||
|
||||
static const char * kb_map_lc[] = {
|
||||
"1#", "q", "w", "e", "r", "t", "y", "u", "i", "o", "p", "Bksp", "\n",
|
||||
"ABC", "a", "s", "d", "f", "g", "h", "j", "k", "l", "Enter", "\n",
|
||||
"_", "-", "z", "x", "c", "v", "b", "n", "m", ".", ",", ":", "\n",
|
||||
LV_SYMBOL_CLOSE, LV_SYMBOL_LEFT, " ", LV_SYMBOL_RIGHT, LV_SYMBOL_OK, ""
|
||||
};
|
||||
static const char * kb_map_lc[] = {"1#",
|
||||
"q",
|
||||
"w",
|
||||
"e",
|
||||
"r",
|
||||
"t",
|
||||
"y",
|
||||
"u",
|
||||
"i",
|
||||
"o",
|
||||
"p",
|
||||
"Bksp",
|
||||
"\n",
|
||||
"ABC",
|
||||
"a",
|
||||
"s",
|
||||
"d",
|
||||
"f",
|
||||
"g",
|
||||
"h",
|
||||
"j",
|
||||
"k",
|
||||
"l",
|
||||
"Enter",
|
||||
"\n",
|
||||
"_",
|
||||
"-",
|
||||
"z",
|
||||
"x",
|
||||
"c",
|
||||
"v",
|
||||
"b",
|
||||
"n",
|
||||
"m",
|
||||
".",
|
||||
",",
|
||||
":",
|
||||
"\n",
|
||||
LV_SYMBOL_CLOSE,
|
||||
LV_SYMBOL_LEFT,
|
||||
" ",
|
||||
LV_SYMBOL_RIGHT,
|
||||
LV_SYMBOL_OK,
|
||||
""};
|
||||
|
||||
static const lv_btnm_ctrl_t kb_ctrl_lc_map[] = {
|
||||
5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 7,
|
||||
(6 | LV_BTNM_CTRL_NO_REPEAT), 3, 3, 3, 3, 3, 3, 3, 3, 3, 7,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
2, 2, 6, 2, 2
|
||||
};
|
||||
5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 7, (6 | LV_BTNM_CTRL_NO_REPEAT),
|
||||
3, 3, 3, 3, 3, 3, 3, 3, 3, 7, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 6, 2,
|
||||
2};
|
||||
|
||||
static const char * kb_map_uc[] = {
|
||||
"1#", "Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P", "Bksp", "\n",
|
||||
"abc", "A", "S", "D", "F", "G", "H", "J", "K", "L", "Enter", "\n",
|
||||
"_", "-", "Z", "X", "C", "V", "B", "N", "M", ".", ",", ":", "\n",
|
||||
LV_SYMBOL_CLOSE, LV_SYMBOL_LEFT, " ", LV_SYMBOL_RIGHT, LV_SYMBOL_OK, ""
|
||||
};
|
||||
static const char * kb_map_uc[] = {"1#",
|
||||
"Q",
|
||||
"W",
|
||||
"E",
|
||||
"R",
|
||||
"T",
|
||||
"Y",
|
||||
"U",
|
||||
"I",
|
||||
"O",
|
||||
"P",
|
||||
"Bksp",
|
||||
"\n",
|
||||
"abc",
|
||||
"A",
|
||||
"S",
|
||||
"D",
|
||||
"F",
|
||||
"G",
|
||||
"H",
|
||||
"J",
|
||||
"K",
|
||||
"L",
|
||||
"Enter",
|
||||
"\n",
|
||||
"_",
|
||||
"-",
|
||||
"Z",
|
||||
"X",
|
||||
"C",
|
||||
"V",
|
||||
"B",
|
||||
"N",
|
||||
"M",
|
||||
".",
|
||||
",",
|
||||
":",
|
||||
"\n",
|
||||
LV_SYMBOL_CLOSE,
|
||||
LV_SYMBOL_LEFT,
|
||||
" ",
|
||||
LV_SYMBOL_RIGHT,
|
||||
LV_SYMBOL_OK,
|
||||
""};
|
||||
|
||||
static const lv_btnm_ctrl_t kb_ctrl_uc_map[] = {
|
||||
5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 7,
|
||||
(6 | LV_BTNM_CTRL_NO_REPEAT), 3, 3, 3, 3, 3, 3, 3, 3, 3, 7,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
2, 2, 6, 2, 2
|
||||
};
|
||||
5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 7, (6 | LV_BTNM_CTRL_NO_REPEAT),
|
||||
3, 3, 3, 3, 3, 3, 3, 3, 3, 7, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 6, 2,
|
||||
2};
|
||||
|
||||
static const char * kb_map_spec[] = {
|
||||
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "Bksp", "\n",
|
||||
"abc", "+", "-", "/", "*", "=", "%", "!", "?", "#", "<", ">", "\n",
|
||||
"\\", "@", "$", "(", ")", "{", "}", "[", "]", ";", "\"", "'", "\n",
|
||||
LV_SYMBOL_CLOSE, LV_SYMBOL_LEFT, " ", LV_SYMBOL_RIGHT, LV_SYMBOL_OK, ""
|
||||
};
|
||||
static const char * kb_map_spec[] = {"0",
|
||||
"1",
|
||||
"2",
|
||||
"3",
|
||||
"4",
|
||||
"5",
|
||||
"6",
|
||||
"7",
|
||||
"8",
|
||||
"9",
|
||||
"Bksp",
|
||||
"\n",
|
||||
"abc",
|
||||
"+",
|
||||
"-",
|
||||
"/",
|
||||
"*",
|
||||
"=",
|
||||
"%",
|
||||
"!",
|
||||
"?",
|
||||
"#",
|
||||
"<",
|
||||
">",
|
||||
"\n",
|
||||
"\\",
|
||||
"@",
|
||||
"$",
|
||||
"(",
|
||||
")",
|
||||
"{",
|
||||
"}",
|
||||
"[",
|
||||
"]",
|
||||
";",
|
||||
"\"",
|
||||
"'",
|
||||
"\n",
|
||||
LV_SYMBOL_CLOSE,
|
||||
LV_SYMBOL_LEFT,
|
||||
" ",
|
||||
LV_SYMBOL_RIGHT,
|
||||
LV_SYMBOL_OK,
|
||||
""};
|
||||
|
||||
static const lv_btnm_ctrl_t kb_ctrl_spec_map[] = {
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2,
|
||||
(2 | LV_BTNM_CTRL_NO_REPEAT), 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
2, 2, 6, 2, 2
|
||||
};
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, (2 | LV_BTNM_CTRL_NO_REPEAT),
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2,
|
||||
2, 6, 2, 2};
|
||||
|
||||
static const char * kb_map_num[] = {
|
||||
"1", "2", "3", "\202"LV_SYMBOL_CLOSE, "\n",
|
||||
"4", "5", "6", "\202"LV_SYMBOL_OK, "\n",
|
||||
"7", "8", "9", "\202Bksp", "\n",
|
||||
"+/-", "0", ".", LV_SYMBOL_LEFT, LV_SYMBOL_RIGHT, ""
|
||||
};
|
||||
static const char * kb_map_num[] = {"1",
|
||||
"2",
|
||||
"3",
|
||||
"\202" LV_SYMBOL_CLOSE,
|
||||
"\n",
|
||||
"4",
|
||||
"5",
|
||||
"6",
|
||||
"\202" LV_SYMBOL_OK,
|
||||
"\n",
|
||||
"7",
|
||||
"8",
|
||||
"9",
|
||||
"\202Bksp",
|
||||
"\n",
|
||||
"+/-",
|
||||
"0",
|
||||
".",
|
||||
LV_SYMBOL_LEFT,
|
||||
LV_SYMBOL_RIGHT,
|
||||
""};
|
||||
|
||||
static const lv_btnm_ctrl_t kb_ctrl_num_map[] = {
|
||||
1, 1, 1, 2,
|
||||
1, 1, 1, 2,
|
||||
1, 1, 1, 2,
|
||||
1, 1, 1, 1, 1
|
||||
};
|
||||
static const lv_btnm_ctrl_t kb_ctrl_num_map[] = {1, 1, 1, 2, 1, 1, 1, 2, 1, 1, 1, 2, 1, 1, 1, 1, 1};
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
@ -118,8 +239,8 @@ lv_obj_t * lv_kb_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
|
||||
/*Initialize the allocated 'ext' */
|
||||
|
||||
ext->ta = NULL;
|
||||
ext->mode = LV_KB_MODE_TEXT;
|
||||
ext->ta = NULL;
|
||||
ext->mode = LV_KB_MODE_TEXT;
|
||||
ext->cursor_mng = 0;
|
||||
|
||||
/*The signal and design functions are not copied so set them here*/
|
||||
@ -149,19 +270,17 @@ lv_obj_t * lv_kb_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
/*Copy an existing keyboard*/
|
||||
else {
|
||||
lv_kb_ext_t * copy_ext = lv_obj_get_ext_attr(copy);
|
||||
ext->ta = NULL;
|
||||
ext->ta = copy_ext->ta;
|
||||
ext->mode = copy_ext->mode;
|
||||
ext->cursor_mng = copy_ext->cursor_mng;
|
||||
ext->ta = NULL;
|
||||
ext->ta = copy_ext->ta;
|
||||
ext->mode = copy_ext->mode;
|
||||
ext->cursor_mng = copy_ext->cursor_mng;
|
||||
|
||||
/*Refresh the style with new signal function*/
|
||||
lv_obj_refresh_style(new_kb);
|
||||
}
|
||||
|
||||
|
||||
LV_LOG_INFO("keyboard created");
|
||||
|
||||
|
||||
return new_kb;
|
||||
}
|
||||
|
||||
@ -182,7 +301,7 @@ void lv_kb_set_ta(lv_obj_t * kb, lv_obj_t * ta)
|
||||
/*Hide the cursor of the old Text area if cursor management is enabled*/
|
||||
if(ext->ta && ext->cursor_mng) {
|
||||
cur_type = lv_ta_get_cursor_type(ext->ta);
|
||||
lv_ta_set_cursor_type(ext->ta, cur_type | LV_CURSOR_HIDDEN);
|
||||
lv_ta_set_cursor_type(ext->ta, cur_type | LV_CURSOR_HIDDEN);
|
||||
}
|
||||
|
||||
ext->ta = ta;
|
||||
@ -190,7 +309,7 @@ void lv_kb_set_ta(lv_obj_t * kb, lv_obj_t * ta)
|
||||
/*Show the cursor of the new Text area if cursor management is enabled*/
|
||||
if(ext->ta && ext->cursor_mng) {
|
||||
cur_type = lv_ta_get_cursor_type(ext->ta);
|
||||
lv_ta_set_cursor_type(ext->ta, cur_type & (~LV_CURSOR_HIDDEN));
|
||||
lv_ta_set_cursor_type(ext->ta, cur_type & (~LV_CURSOR_HIDDEN));
|
||||
}
|
||||
}
|
||||
|
||||
@ -208,14 +327,12 @@ void lv_kb_set_mode(lv_obj_t * kb, lv_kb_mode_t mode)
|
||||
if(mode == LV_KB_MODE_TEXT) {
|
||||
lv_btnm_set_map(kb, kb_map_lc);
|
||||
lv_btnm_set_ctrl_map(kb, kb_ctrl_lc_map);
|
||||
}
|
||||
else if(mode == LV_KB_MODE_NUM) {
|
||||
} else if(mode == LV_KB_MODE_NUM) {
|
||||
lv_btnm_set_map(kb, kb_map_num);
|
||||
lv_btnm_set_ctrl_map(kb, kb_ctrl_num_map);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Automatically hide or show the cursor of Text Area
|
||||
* @param kb pointer to a Keyboard object
|
||||
@ -233,9 +350,9 @@ void lv_kb_set_cursor_manage(lv_obj_t * kb, bool en)
|
||||
cur_type = lv_ta_get_cursor_type(ext->ta);
|
||||
|
||||
if(ext->cursor_mng) {
|
||||
lv_ta_set_cursor_type(ext->ta, cur_type & (~LV_CURSOR_HIDDEN));
|
||||
lv_ta_set_cursor_type(ext->ta, cur_type & (~LV_CURSOR_HIDDEN));
|
||||
} else {
|
||||
lv_ta_set_cursor_type(ext->ta, cur_type | LV_CURSOR_HIDDEN);
|
||||
lv_ta_set_cursor_type(ext->ta, cur_type | LV_CURSOR_HIDDEN);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -249,24 +366,14 @@ void lv_kb_set_cursor_manage(lv_obj_t * kb, bool en)
|
||||
void lv_kb_set_style(lv_obj_t * kb, lv_kb_style_t type, lv_style_t * style)
|
||||
{
|
||||
switch(type) {
|
||||
case LV_KB_STYLE_BG:
|
||||
lv_btnm_set_style(kb, LV_BTNM_STYLE_BG, style);
|
||||
break;
|
||||
case LV_KB_STYLE_BTN_REL:
|
||||
lv_btnm_set_style(kb, LV_BTNM_STYLE_BTN_REL, style);
|
||||
break;
|
||||
case LV_KB_STYLE_BTN_PR:
|
||||
lv_btnm_set_style(kb, LV_BTNM_STYLE_BTN_PR, style);
|
||||
break;
|
||||
case LV_KB_STYLE_BG: lv_btnm_set_style(kb, LV_BTNM_STYLE_BG, style); break;
|
||||
case LV_KB_STYLE_BTN_REL: lv_btnm_set_style(kb, LV_BTNM_STYLE_BTN_REL, style); break;
|
||||
case LV_KB_STYLE_BTN_PR: lv_btnm_set_style(kb, LV_BTNM_STYLE_BTN_PR, style); break;
|
||||
case LV_KB_STYLE_BTN_TGL_REL:
|
||||
lv_btnm_set_style(kb, LV_BTNM_STYLE_BTN_TGL_REL, style);
|
||||
break;
|
||||
case LV_KB_STYLE_BTN_TGL_PR:
|
||||
lv_btnm_set_style(kb, LV_BTNM_STYLE_BTN_TGL_PR, style);
|
||||
break;
|
||||
case LV_KB_STYLE_BTN_INA:
|
||||
lv_btnm_set_style(kb, LV_BTNM_STYLE_BTN_INA, style);
|
||||
break;
|
||||
case LV_KB_STYLE_BTN_TGL_PR: lv_btnm_set_style(kb, LV_BTNM_STYLE_BTN_TGL_PR, style); break;
|
||||
case LV_KB_STYLE_BTN_INA: lv_btnm_set_style(kb, LV_BTNM_STYLE_BTN_INA, style); break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -296,7 +403,6 @@ lv_kb_mode_t lv_kb_get_mode(const lv_obj_t * kb)
|
||||
return ext->mode;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the current cursor manage mode.
|
||||
* @param kb pointer to a Keyboard object
|
||||
@ -319,27 +425,15 @@ lv_style_t * lv_kb_get_style(const lv_obj_t * kb, lv_kb_style_t type)
|
||||
lv_style_t * style = NULL;
|
||||
|
||||
switch(type) {
|
||||
case LV_KB_STYLE_BG:
|
||||
style = lv_btnm_get_style(kb, LV_BTNM_STYLE_BG);
|
||||
break;
|
||||
case LV_KB_STYLE_BTN_REL:
|
||||
style = lv_btnm_get_style(kb, LV_BTNM_STYLE_BTN_REL);
|
||||
break;
|
||||
case LV_KB_STYLE_BTN_PR:
|
||||
style = lv_btnm_get_style(kb, LV_BTNM_STYLE_BTN_PR);
|
||||
break;
|
||||
case LV_KB_STYLE_BG: style = lv_btnm_get_style(kb, LV_BTNM_STYLE_BG); break;
|
||||
case LV_KB_STYLE_BTN_REL: style = lv_btnm_get_style(kb, LV_BTNM_STYLE_BTN_REL); break;
|
||||
case LV_KB_STYLE_BTN_PR: style = lv_btnm_get_style(kb, LV_BTNM_STYLE_BTN_PR); break;
|
||||
case LV_KB_STYLE_BTN_TGL_REL:
|
||||
style = lv_btnm_get_style(kb, LV_BTNM_STYLE_BTN_TGL_REL);
|
||||
break;
|
||||
case LV_KB_STYLE_BTN_TGL_PR:
|
||||
style = lv_btnm_get_style(kb, LV_BTNM_STYLE_BTN_TGL_PR);
|
||||
break;
|
||||
case LV_KB_STYLE_BTN_INA:
|
||||
style = lv_btnm_get_style(kb, LV_BTNM_STYLE_BTN_INA);
|
||||
break;
|
||||
default:
|
||||
style = NULL;
|
||||
break;
|
||||
case LV_KB_STYLE_BTN_TGL_PR: style = lv_btnm_get_style(kb, LV_BTNM_STYLE_BTN_TGL_PR); break;
|
||||
case LV_KB_STYLE_BTN_INA: style = lv_btnm_get_style(kb, LV_BTNM_STYLE_BTN_INA); break;
|
||||
default: style = NULL; break;
|
||||
}
|
||||
|
||||
return style;
|
||||
@ -351,7 +445,8 @@ lv_style_t * lv_kb_get_style(const lv_obj_t * kb, lv_kb_style_t type)
|
||||
|
||||
/**
|
||||
* Default keyboard event to add characters to the Text area and change the map.
|
||||
* If a custom `event_cb` is added to the keyboard this function be called from it to handle the button clicks
|
||||
* If a custom `event_cb` is added to the keyboard this function be called from it to handle the
|
||||
* button clicks
|
||||
* @param kb pointer to a keyboard
|
||||
* @param event the triggering event
|
||||
*/
|
||||
@ -360,10 +455,12 @@ void lv_kb_def_event_cb(lv_obj_t * kb, lv_event_t event)
|
||||
if(event != LV_EVENT_PRESSED && event != LV_EVENT_LONG_PRESSED_REPEAT) return;
|
||||
|
||||
lv_kb_ext_t * ext = lv_obj_get_ext_attr(kb);
|
||||
uint16_t btn_id = lv_btnm_get_active_btn(kb);
|
||||
uint16_t btn_id = lv_btnm_get_active_btn(kb);
|
||||
if(btn_id == LV_BTNM_BTN_NONE) return;
|
||||
if(lv_btnm_get_btn_ctrl(kb, btn_id, LV_BTNM_CTRL_HIDDEN | LV_BTNM_CTRL_INACTIVE)) return;
|
||||
if(lv_btnm_get_btn_ctrl(kb, btn_id, LV_BTNM_CTRL_NO_REPEAT) && event == LV_EVENT_LONG_PRESSED_REPEAT) return;
|
||||
if(lv_btnm_get_btn_ctrl(kb, btn_id, LV_BTNM_CTRL_NO_REPEAT) &&
|
||||
event == LV_EVENT_LONG_PRESSED_REPEAT)
|
||||
return;
|
||||
|
||||
const char * txt = lv_btnm_get_active_btn_text(kb);
|
||||
if(txt == NULL) return;
|
||||
@ -384,27 +481,32 @@ void lv_kb_def_event_cb(lv_obj_t * kb, lv_event_t event)
|
||||
} else if(strcmp(txt, LV_SYMBOL_CLOSE) == 0) {
|
||||
if(kb->event_cb) {
|
||||
lv_event_send(kb, LV_EVENT_CANCEL, NULL);
|
||||
}
|
||||
else {
|
||||
lv_kb_set_ta(kb, NULL); /*De-assign the text area to hide it cursor if needed*/
|
||||
} else {
|
||||
lv_kb_set_ta(kb, NULL); /*De-assign the text area to hide it cursor if needed*/
|
||||
lv_obj_del(kb);
|
||||
}
|
||||
return;
|
||||
} else if(strcmp(txt, LV_SYMBOL_OK) == 0) {
|
||||
if(kb->event_cb) lv_event_send(kb, LV_EVENT_APPLY, NULL);
|
||||
else lv_kb_set_ta(kb, NULL); /*De-assign the text area to hide it cursor if needed*/
|
||||
if(kb->event_cb)
|
||||
lv_event_send(kb, LV_EVENT_APPLY, NULL);
|
||||
else
|
||||
lv_kb_set_ta(kb, NULL); /*De-assign the text area to hide it cursor if needed*/
|
||||
return;
|
||||
}
|
||||
|
||||
/*Add the characters to the text area if set*/
|
||||
if(ext->ta == NULL) return;
|
||||
|
||||
if(strcmp(txt, "Enter") == 0)lv_ta_add_char(ext->ta, '\n');
|
||||
else if(strcmp(txt, LV_SYMBOL_LEFT) == 0) lv_ta_cursor_left(ext->ta);
|
||||
else if(strcmp(txt, LV_SYMBOL_RIGHT) == 0) lv_ta_cursor_right(ext->ta);
|
||||
else if(strcmp(txt, "Bksp") == 0) lv_ta_del_char(ext->ta);
|
||||
if(strcmp(txt, "Enter") == 0)
|
||||
lv_ta_add_char(ext->ta, '\n');
|
||||
else if(strcmp(txt, LV_SYMBOL_LEFT) == 0)
|
||||
lv_ta_cursor_left(ext->ta);
|
||||
else if(strcmp(txt, LV_SYMBOL_RIGHT) == 0)
|
||||
lv_ta_cursor_right(ext->ta);
|
||||
else if(strcmp(txt, "Bksp") == 0)
|
||||
lv_ta_del_char(ext->ta);
|
||||
else if(strcmp(txt, "+/-") == 0) {
|
||||
uint16_t cur = lv_ta_get_cursor_pos(ext->ta);
|
||||
uint16_t cur = lv_ta_get_cursor_pos(ext->ta);
|
||||
const char * ta_txt = lv_ta_get_text(ext->ta);
|
||||
if(ta_txt[0] == '-') {
|
||||
lv_ta_set_cursor_pos(ext->ta, 1);
|
||||
@ -447,27 +549,24 @@ static lv_res_t lv_kb_signal(lv_obj_t * kb, lv_signal_t sign, void * param)
|
||||
|
||||
if(sign == LV_SIGNAL_CLEANUP) {
|
||||
/*Nothing to cleanup. (No dynamically allocated memory in 'ext')*/
|
||||
}
|
||||
else if(sign == LV_SIGNAL_FOCUS) {
|
||||
} else if(sign == LV_SIGNAL_FOCUS) {
|
||||
lv_kb_ext_t * ext = lv_obj_get_ext_attr(kb);
|
||||
/*Show the cursor of the new Text area if cursor management is enabled*/
|
||||
if(ext->ta && ext->cursor_mng) {
|
||||
lv_cursor_type_t cur_type = lv_ta_get_cursor_type(ext->ta);
|
||||
lv_ta_set_cursor_type(ext->ta, cur_type & (~LV_CURSOR_HIDDEN));
|
||||
lv_ta_set_cursor_type(ext->ta, cur_type & (~LV_CURSOR_HIDDEN));
|
||||
}
|
||||
}
|
||||
else if(sign == LV_SIGNAL_DEFOCUS) {
|
||||
lv_kb_ext_t * ext = lv_obj_get_ext_attr(kb);
|
||||
/*Show the cursor of the new Text area if cursor management is enabled*/
|
||||
if(ext->ta && ext->cursor_mng) {
|
||||
lv_cursor_type_t cur_type = lv_ta_get_cursor_type(ext->ta);
|
||||
lv_ta_set_cursor_type(ext->ta, cur_type | LV_CURSOR_HIDDEN);
|
||||
}
|
||||
}
|
||||
else if(sign == LV_SIGNAL_GET_TYPE) {
|
||||
} else if(sign == LV_SIGNAL_DEFOCUS) {
|
||||
lv_kb_ext_t * ext = lv_obj_get_ext_attr(kb);
|
||||
/*Show the cursor of the new Text area if cursor management is enabled*/
|
||||
if(ext->ta && ext->cursor_mng) {
|
||||
lv_cursor_type_t cur_type = lv_ta_get_cursor_type(ext->ta);
|
||||
lv_ta_set_cursor_type(ext->ta, cur_type | LV_CURSOR_HIDDEN);
|
||||
}
|
||||
} else if(sign == LV_SIGNAL_GET_TYPE) {
|
||||
lv_obj_type_t * buf = param;
|
||||
uint8_t i;
|
||||
for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/
|
||||
for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/
|
||||
if(buf->type[i] == NULL) break;
|
||||
}
|
||||
buf->type[i] = "lv_kb";
|
||||
|
@ -48,12 +48,14 @@ enum {
|
||||
typedef uint8_t lv_kb_mode_t;
|
||||
|
||||
/*Data of keyboard*/
|
||||
typedef struct {
|
||||
lv_btnm_ext_t btnm; /*Ext. of ancestor*/
|
||||
typedef struct
|
||||
{
|
||||
lv_btnm_ext_t btnm; /*Ext. of ancestor*/
|
||||
/*New data for this type */
|
||||
lv_obj_t *ta; /*Pointer to the assigned text area*/
|
||||
lv_kb_mode_t mode; /*Key map type*/
|
||||
uint8_t cursor_mng :1; /*1: automatically show/hide cursor when a text area is assigned or left*/
|
||||
lv_obj_t * ta; /*Pointer to the assigned text area*/
|
||||
lv_kb_mode_t mode; /*Key map type*/
|
||||
uint8_t
|
||||
cursor_mng : 1; /*1: automatically show/hide cursor when a text area is assigned or left*/
|
||||
} lv_kb_ext_t;
|
||||
|
||||
enum {
|
||||
@ -66,7 +68,6 @@ enum {
|
||||
};
|
||||
typedef uint8_t lv_kb_style_t;
|
||||
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
@ -110,7 +111,7 @@ void lv_kb_set_cursor_manage(lv_obj_t * kb, bool en);
|
||||
* @param map pointer to a string array to describe the map.
|
||||
* See 'lv_btnm_set_map()' for more info.
|
||||
*/
|
||||
static inline void lv_kb_set_map(lv_obj_t *kb, const char * map[])
|
||||
static inline void lv_kb_set_map(lv_obj_t * kb, const char * map[])
|
||||
{
|
||||
lv_btnm_set_map(kb, map);
|
||||
}
|
||||
@ -123,7 +124,7 @@ static inline void lv_kb_set_map(lv_obj_t *kb, const char * map[])
|
||||
* @param ctrl_map pointer to an array of `lv_btn_ctrl_t` control bytes.
|
||||
* See: `lv_btnm_set_ctrl_map` for more details.
|
||||
*/
|
||||
static inline void lv_kb_set_ctrl_map(lv_obj_t *kb, const lv_btnm_ctrl_t * ctrl_map)
|
||||
static inline void lv_kb_set_ctrl_map(lv_obj_t * kb, const lv_btnm_ctrl_t * ctrl_map)
|
||||
{
|
||||
lv_btnm_set_ctrl_map(kb, ctrl_map);
|
||||
}
|
||||
@ -134,7 +135,7 @@ static inline void lv_kb_set_ctrl_map(lv_obj_t *kb, const lv_btnm_ctrl_t * ctrl_
|
||||
* @param type which style should be set
|
||||
* @param style pointer to a style
|
||||
*/
|
||||
void lv_kb_set_style(lv_obj_t *kb, lv_kb_style_t type, lv_style_t *style);
|
||||
void lv_kb_set_style(lv_obj_t * kb, lv_kb_style_t type, lv_style_t * style);
|
||||
|
||||
/*=====================
|
||||
* Getter functions
|
||||
@ -167,7 +168,7 @@ bool lv_kb_get_cursor_manage(const lv_obj_t * kb);
|
||||
* @param type which style should be get
|
||||
* @return style pointer to a style
|
||||
*/
|
||||
lv_style_t * lv_kb_get_style(const lv_obj_t *kb, lv_kb_style_t type);
|
||||
lv_style_t * lv_kb_get_style(const lv_obj_t * kb, lv_kb_style_t type);
|
||||
|
||||
/*=====================
|
||||
* Other functions
|
||||
@ -175,7 +176,8 @@ lv_style_t * lv_kb_get_style(const lv_obj_t *kb, lv_kb_style_t type);
|
||||
|
||||
/**
|
||||
* Default keyboard event to add characters to the Text area and change the map.
|
||||
* If a custom `event_cb` is added to the keyboard this function be called from it to handle the button clicks
|
||||
* If a custom `event_cb` is added to the keyboard this function be called from it to handle the
|
||||
* button clicks
|
||||
* @param kb pointer to a keyboard
|
||||
* @param event the triggering event
|
||||
*/
|
||||
@ -185,10 +187,10 @@ void lv_kb_def_event_cb(lv_obj_t * kb, lv_event_t event);
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_KB*/
|
||||
#endif /*LV_USE_KB*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_KB_H*/
|
||||
#endif /*LV_KB_H*/
|
||||
|
@ -20,7 +20,8 @@
|
||||
*********************/
|
||||
/*Test configurations*/
|
||||
#ifndef LV_LABEL_SCROLL_SPEED
|
||||
#define LV_LABEL_DEF_SCROLL_SPEED (25) /*Hor, or ver. scroll speed (px/sec) in 'LV_LABEL_LONG_SCROLL/ROLL' mode*/
|
||||
#define LV_LABEL_DEF_SCROLL_SPEED \
|
||||
(25) /*Hor, or ver. scroll speed (px/sec) in 'LV_LABEL_LONG_SCROLL/ROLL' mode*/
|
||||
#endif
|
||||
|
||||
#define ANIM_WAIT_CHAR_COUNT 3
|
||||
@ -80,18 +81,18 @@ lv_obj_t * lv_label_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
lv_mem_assert(ext);
|
||||
if(ext == NULL) return NULL;
|
||||
|
||||
ext->text = NULL;
|
||||
ext->static_txt = 0;
|
||||
ext->recolor = 0;
|
||||
ext->body_draw = 0;
|
||||
ext->align = LV_LABEL_ALIGN_LEFT;
|
||||
ext->dot_end = LV_LABEL_DOT_END_INV;
|
||||
ext->long_mode = LV_LABEL_LONG_EXPAND;
|
||||
ext->anim_speed = LV_LABEL_DEF_SCROLL_SPEED;
|
||||
ext->offset.x = 0;
|
||||
ext->offset.y = 0;
|
||||
ext->text = NULL;
|
||||
ext->static_txt = 0;
|
||||
ext->recolor = 0;
|
||||
ext->body_draw = 0;
|
||||
ext->align = LV_LABEL_ALIGN_LEFT;
|
||||
ext->dot_end = LV_LABEL_DOT_END_INV;
|
||||
ext->long_mode = LV_LABEL_LONG_EXPAND;
|
||||
ext->anim_speed = LV_LABEL_DEF_SCROLL_SPEED;
|
||||
ext->offset.x = 0;
|
||||
ext->offset.y = 0;
|
||||
ext->selection_start = -1;
|
||||
ext->selection_end = -1;
|
||||
ext->selection_end = -1;
|
||||
|
||||
lv_obj_set_design_cb(new_label, lv_label_design);
|
||||
lv_obj_set_signal_cb(new_label, lv_label_signal);
|
||||
@ -101,7 +102,7 @@ lv_obj_t * lv_label_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
lv_obj_set_click(new_label, false);
|
||||
lv_label_set_long_mode(new_label, LV_LABEL_LONG_EXPAND);
|
||||
lv_label_set_text(new_label, "Text");
|
||||
lv_label_set_style(new_label, NULL); /*Inherit parent's style*/
|
||||
lv_label_set_style(new_label, NULL); /*Inherit parent's style*/
|
||||
}
|
||||
/*Copy 'copy' if not NULL*/
|
||||
else {
|
||||
@ -110,8 +111,10 @@ lv_obj_t * lv_label_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
lv_label_set_recolor(new_label, lv_label_get_recolor(copy));
|
||||
lv_label_set_body_draw(new_label, lv_label_get_body_draw(copy));
|
||||
lv_label_set_align(new_label, lv_label_get_align(copy));
|
||||
if(copy_ext->static_txt == 0) lv_label_set_text(new_label, lv_label_get_text(copy));
|
||||
else lv_label_set_static_text(new_label, lv_label_get_text(copy));
|
||||
if(copy_ext->static_txt == 0)
|
||||
lv_label_set_text(new_label, lv_label_get_text(copy));
|
||||
else
|
||||
lv_label_set_static_text(new_label, lv_label_get_text(copy));
|
||||
|
||||
/*In DOT mode save the text byte-to-byte because a '\0' can be in the middle*/
|
||||
if(copy_ext->long_mode == LV_LABEL_LONG_DOT) {
|
||||
@ -128,7 +131,6 @@ lv_obj_t * lv_label_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
lv_obj_refresh_style(new_label);
|
||||
}
|
||||
|
||||
|
||||
LV_LOG_INFO("label created");
|
||||
|
||||
return new_label;
|
||||
@ -173,7 +175,7 @@ void lv_label_set_text(lv_obj_t * label, const char * text)
|
||||
if(ext->text == NULL) return;
|
||||
|
||||
strcpy(ext->text, text);
|
||||
ext->static_txt = 0; /*Now the text is dynamically allocated*/
|
||||
ext->static_txt = 0; /*Now the text is dynamically allocated*/
|
||||
}
|
||||
|
||||
lv_label_refr_text(label);
|
||||
@ -209,7 +211,7 @@ void lv_label_set_array_text(lv_obj_t * label, const char * array, uint16_t size
|
||||
|
||||
memcpy(ext->text, array, size);
|
||||
ext->text[size] = '\0';
|
||||
ext->static_txt = 0; /*Now the text is dynamically allocated*/
|
||||
ext->static_txt = 0; /*Now the text is dynamically allocated*/
|
||||
|
||||
lv_label_refr_text(label);
|
||||
}
|
||||
@ -230,7 +232,7 @@ void lv_label_set_static_text(lv_obj_t * label, const char * text)
|
||||
|
||||
if(text != NULL) {
|
||||
ext->static_txt = 1;
|
||||
ext->text = (char *) text;
|
||||
ext->text = (char *)text;
|
||||
}
|
||||
|
||||
lv_label_refr_text(label);
|
||||
@ -240,7 +242,8 @@ void lv_label_set_static_text(lv_obj_t * label, const char * text)
|
||||
* Set the behavior of the label with longer text then the object size
|
||||
* @param label pointer to a label object
|
||||
* @param long_mode the new mode from 'lv_label_long_mode' enum.
|
||||
* In LV_LONG_BREAK/LONG/ROLL the size of the label should be set AFTER this function
|
||||
* In LV_LONG_BREAK/LONG/ROLL the size of the label should be set AFTER this
|
||||
* function
|
||||
*/
|
||||
void lv_label_set_long_mode(lv_obj_t * label, lv_label_long_mode_t long_mode)
|
||||
{
|
||||
@ -248,16 +251,19 @@ void lv_label_set_long_mode(lv_obj_t * label, lv_label_long_mode_t long_mode)
|
||||
|
||||
#if LV_USE_ANIMATION
|
||||
/*Delete the old animation (if exists)*/
|
||||
lv_anim_del(label, (lv_anim_fp_t) lv_obj_set_x);
|
||||
lv_anim_del(label, (lv_anim_fp_t) lv_obj_set_y);
|
||||
lv_anim_del(label, (lv_anim_fp_t) lv_label_set_offset_x);
|
||||
lv_anim_del(label, (lv_anim_fp_t) lv_label_set_offset_y);
|
||||
lv_anim_del(label, (lv_anim_fp_t)lv_obj_set_x);
|
||||
lv_anim_del(label, (lv_anim_fp_t)lv_obj_set_y);
|
||||
lv_anim_del(label, (lv_anim_fp_t)lv_label_set_offset_x);
|
||||
lv_anim_del(label, (lv_anim_fp_t)lv_label_set_offset_y);
|
||||
#endif
|
||||
ext->offset.x = 0;
|
||||
ext->offset.y = 0;
|
||||
|
||||
if(long_mode == LV_LABEL_LONG_ROLL || long_mode == LV_LABEL_LONG_ROLL_CIRC || long_mode == LV_LABEL_LONG_CROP) ext->expand = 1;
|
||||
else ext->expand = 0;
|
||||
if(long_mode == LV_LABEL_LONG_ROLL || long_mode == LV_LABEL_LONG_ROLL_CIRC ||
|
||||
long_mode == LV_LABEL_LONG_CROP)
|
||||
ext->expand = 1;
|
||||
else
|
||||
ext->expand = 0;
|
||||
|
||||
/*Restore the character under the dots*/
|
||||
if(ext->long_mode == LV_LABEL_LONG_DOT && ext->dot_end != LV_LABEL_DOT_END_INV) {
|
||||
@ -280,7 +286,8 @@ void lv_label_set_align(lv_obj_t * label, lv_label_align_t align)
|
||||
|
||||
ext->align = align;
|
||||
|
||||
lv_obj_invalidate(label); /*Enough to invalidate because alignment is only drawing related (lv_refr_label_text() not required)*/
|
||||
lv_obj_invalidate(label); /*Enough to invalidate because alignment is only drawing related
|
||||
(lv_refr_label_text() not required)*/
|
||||
}
|
||||
|
||||
/**
|
||||
@ -295,7 +302,8 @@ void lv_label_set_recolor(lv_obj_t * label, bool en)
|
||||
|
||||
ext->recolor = en == false ? 0 : 1;
|
||||
|
||||
lv_label_refr_text(label); /*Refresh the text because the potential colo codes in text needs to be hided or revealed*/
|
||||
lv_label_refr_text(label); /*Refresh the text because the potential colo codes in text needs to
|
||||
be hided or revealed*/
|
||||
}
|
||||
|
||||
/**
|
||||
@ -406,21 +414,22 @@ uint16_t lv_label_get_anim_speed(const lv_obj_t * label)
|
||||
/**
|
||||
* Get the relative x and y coordinates of a letter
|
||||
* @param label pointer to a label object
|
||||
* @param index index of the letter [0 ... text length]. Expressed in character index, not byte index (different in UTF-8)
|
||||
* @param index index of the letter [0 ... text length]. Expressed in character index, not byte
|
||||
* index (different in UTF-8)
|
||||
* @param pos store the result here (E.g. index = 0 gives 0;0 coordinates)
|
||||
*/
|
||||
void lv_label_get_letter_pos(const lv_obj_t * label, uint16_t index, lv_point_t * pos)
|
||||
{
|
||||
const char * txt = lv_label_get_text(label);
|
||||
lv_label_ext_t * ext = lv_obj_get_ext_attr(label);
|
||||
uint32_t line_start = 0;
|
||||
const char * txt = lv_label_get_text(label);
|
||||
lv_label_ext_t * ext = lv_obj_get_ext_attr(label);
|
||||
uint32_t line_start = 0;
|
||||
uint32_t new_line_start = 0;
|
||||
lv_coord_t max_w = lv_obj_get_width(label);
|
||||
lv_style_t * style = lv_obj_get_style(label);
|
||||
const lv_font_t * font = style->text.font;
|
||||
uint8_t letter_height = lv_font_get_height(font);
|
||||
lv_coord_t y = 0;
|
||||
lv_txt_flag_t flag = LV_TXT_FLAG_NONE;
|
||||
lv_coord_t max_w = lv_obj_get_width(label);
|
||||
lv_style_t * style = lv_obj_get_style(label);
|
||||
const lv_font_t * font = style->text.font;
|
||||
uint8_t letter_height = lv_font_get_height(font);
|
||||
lv_coord_t y = 0;
|
||||
lv_txt_flag_t flag = LV_TXT_FLAG_NONE;
|
||||
|
||||
if(ext->recolor != 0) flag |= LV_TXT_FLAG_RECOLOR;
|
||||
if(ext->expand != 0) flag |= LV_TXT_FLAG_EXPAND;
|
||||
@ -435,8 +444,10 @@ void lv_label_get_letter_pos(const lv_obj_t * label, uint16_t index, lv_point_t
|
||||
|
||||
/*Search the line of the index letter */;
|
||||
while(txt[new_line_start] != '\0') {
|
||||
new_line_start += lv_txt_get_next_line(&txt[line_start], font, style->text.letter_space, max_w, flag);
|
||||
if(index < new_line_start || txt[new_line_start] == '\0') break; /*The line of 'index' letter begins at 'line_start'*/
|
||||
new_line_start +=
|
||||
lv_txt_get_next_line(&txt[line_start], font, style->text.letter_space, max_w, flag);
|
||||
if(index < new_line_start || txt[new_line_start] == '\0')
|
||||
break; /*The line of 'index' letter begins at 'line_start'*/
|
||||
|
||||
y += letter_height + style->text.line_space;
|
||||
line_start = new_line_start;
|
||||
@ -451,21 +462,21 @@ void lv_label_get_letter_pos(const lv_obj_t * label, uint16_t index, lv_point_t
|
||||
}
|
||||
|
||||
/*Calculate the x coordinate*/
|
||||
lv_coord_t x = lv_txt_get_width(&txt[line_start], index - line_start,
|
||||
font, style->text.letter_space, flag);
|
||||
lv_coord_t x = lv_txt_get_width(&txt[line_start], index - line_start, font,
|
||||
style->text.letter_space, flag);
|
||||
|
||||
if(index != line_start) x += style->text.letter_space;
|
||||
|
||||
if(ext->align == LV_LABEL_ALIGN_CENTER) {
|
||||
lv_coord_t line_w;
|
||||
line_w = lv_txt_get_width(&txt[line_start], new_line_start - line_start,
|
||||
font, style->text.letter_space, flag);
|
||||
line_w = lv_txt_get_width(&txt[line_start], new_line_start - line_start, font,
|
||||
style->text.letter_space, flag);
|
||||
x += lv_obj_get_width(label) / 2 - line_w / 2;
|
||||
|
||||
} else if(ext->align == LV_LABEL_ALIGN_RIGHT) {
|
||||
lv_coord_t line_w;
|
||||
line_w = lv_txt_get_width(&txt[line_start], new_line_start - line_start,
|
||||
font, style->text.letter_space, flag);
|
||||
line_w = lv_txt_get_width(&txt[line_start], new_line_start - line_start, font,
|
||||
style->text.letter_space, flag);
|
||||
|
||||
x += lv_obj_get_width(label) - line_w;
|
||||
}
|
||||
@ -482,16 +493,16 @@ void lv_label_get_letter_pos(const lv_obj_t * label, uint16_t index, lv_point_t
|
||||
*/
|
||||
uint16_t lv_label_get_letter_on(const lv_obj_t * label, lv_point_t * pos)
|
||||
{
|
||||
const char * txt = lv_label_get_text(label);
|
||||
lv_label_ext_t * ext = lv_obj_get_ext_attr(label);
|
||||
uint32_t line_start = 0;
|
||||
const char * txt = lv_label_get_text(label);
|
||||
lv_label_ext_t * ext = lv_obj_get_ext_attr(label);
|
||||
uint32_t line_start = 0;
|
||||
uint32_t new_line_start = 0;
|
||||
lv_coord_t max_w = lv_obj_get_width(label);
|
||||
lv_style_t * style = lv_obj_get_style(label);
|
||||
const lv_font_t * font = style->text.font;
|
||||
uint8_t letter_height = lv_font_get_height(font);
|
||||
lv_coord_t y = 0;
|
||||
lv_txt_flag_t flag = LV_TXT_FLAG_NONE;
|
||||
lv_coord_t max_w = lv_obj_get_width(label);
|
||||
lv_style_t * style = lv_obj_get_style(label);
|
||||
const lv_font_t * font = style->text.font;
|
||||
uint8_t letter_height = lv_font_get_height(font);
|
||||
lv_coord_t y = 0;
|
||||
lv_txt_flag_t flag = LV_TXT_FLAG_NONE;
|
||||
|
||||
if(ext->recolor != 0) flag |= LV_TXT_FLAG_RECOLOR;
|
||||
if(ext->expand != 0) flag |= LV_TXT_FLAG_EXPAND;
|
||||
@ -504,7 +515,8 @@ uint16_t lv_label_get_letter_on(const lv_obj_t * label, lv_point_t * pos)
|
||||
|
||||
/*Search the line of the index letter */;
|
||||
while(txt[line_start] != '\0') {
|
||||
new_line_start += lv_txt_get_next_line(&txt[line_start], font, style->text.letter_space, max_w, flag);
|
||||
new_line_start +=
|
||||
lv_txt_get_next_line(&txt[line_start], font, style->text.letter_space, max_w, flag);
|
||||
|
||||
if(pos->y <= y + letter_height) break; /*The line is found (stored in 'line_start')*/
|
||||
y += letter_height + style->text.line_space;
|
||||
@ -516,17 +528,18 @@ uint16_t lv_label_get_letter_on(const lv_obj_t * label, lv_point_t * pos)
|
||||
lv_coord_t x = 0;
|
||||
if(ext->align == LV_LABEL_ALIGN_CENTER) {
|
||||
lv_coord_t line_w;
|
||||
line_w = lv_txt_get_width(&txt[line_start], new_line_start - line_start,
|
||||
font, style->text.letter_space, flag);
|
||||
line_w = lv_txt_get_width(&txt[line_start], new_line_start - line_start, font,
|
||||
style->text.letter_space, flag);
|
||||
x += lv_obj_get_width(label) / 2 - line_w / 2;
|
||||
}
|
||||
|
||||
lv_txt_cmd_state_t cmd_state = LV_TXT_CMD_STATE_WAIT;
|
||||
uint32_t i = line_start;
|
||||
uint32_t i_current = i;
|
||||
uint32_t i = line_start;
|
||||
uint32_t i_current = i;
|
||||
uint32_t letter;
|
||||
while(i <= new_line_start - 1) {
|
||||
letter = lv_txt_encoded_next(txt, &i); /*Be careful 'i' already points to the next character*/
|
||||
letter =
|
||||
lv_txt_encoded_next(txt, &i); /*Be careful 'i' already points to the next character*/
|
||||
/*Handle the recolor command*/
|
||||
if((flag & LV_TXT_FLAG_RECOLOR) != 0) {
|
||||
if(lv_txt_is_cmd(&cmd_state, txt[i]) != false) {
|
||||
@ -552,74 +565,76 @@ uint16_t lv_label_get_letter_on(const lv_obj_t * label, lv_point_t * pos)
|
||||
* @param pos Point to check for characte under
|
||||
* @return whether a character is drawn under the point
|
||||
*/
|
||||
bool lv_label_is_char_under_pos(const lv_obj_t * label, lv_point_t * pos) {
|
||||
const char * txt = lv_label_get_text(label);
|
||||
lv_label_ext_t * ext = lv_obj_get_ext_attr(label);
|
||||
uint32_t line_start = 0;
|
||||
uint32_t new_line_start = 0;
|
||||
lv_coord_t max_w = lv_obj_get_width(label);
|
||||
lv_style_t * style = lv_obj_get_style(label);
|
||||
const lv_font_t * font = style->text.font;
|
||||
uint8_t letter_height = lv_font_get_height(font);
|
||||
lv_coord_t y = 0;
|
||||
lv_txt_flag_t flag = LV_TXT_FLAG_NONE;
|
||||
bool lv_label_is_char_under_pos(const lv_obj_t * label, lv_point_t * pos)
|
||||
{
|
||||
const char * txt = lv_label_get_text(label);
|
||||
lv_label_ext_t * ext = lv_obj_get_ext_attr(label);
|
||||
uint32_t line_start = 0;
|
||||
uint32_t new_line_start = 0;
|
||||
lv_coord_t max_w = lv_obj_get_width(label);
|
||||
lv_style_t * style = lv_obj_get_style(label);
|
||||
const lv_font_t * font = style->text.font;
|
||||
uint8_t letter_height = lv_font_get_height(font);
|
||||
lv_coord_t y = 0;
|
||||
lv_txt_flag_t flag = LV_TXT_FLAG_NONE;
|
||||
|
||||
if(ext->recolor != 0) flag |= LV_TXT_FLAG_RECOLOR;
|
||||
if(ext->expand != 0) flag |= LV_TXT_FLAG_EXPAND;
|
||||
if(ext->align == LV_LABEL_ALIGN_CENTER) flag |= LV_TXT_FLAG_CENTER;
|
||||
if(ext->recolor != 0) flag |= LV_TXT_FLAG_RECOLOR;
|
||||
if(ext->expand != 0) flag |= LV_TXT_FLAG_EXPAND;
|
||||
if(ext->align == LV_LABEL_ALIGN_CENTER) flag |= LV_TXT_FLAG_CENTER;
|
||||
|
||||
/*If the width will be expanded set the max length to very big */
|
||||
if(ext->long_mode == LV_LABEL_LONG_EXPAND) {
|
||||
max_w = LV_COORD_MAX;
|
||||
}
|
||||
/*If the width will be expanded set the max length to very big */
|
||||
if(ext->long_mode == LV_LABEL_LONG_EXPAND) {
|
||||
max_w = LV_COORD_MAX;
|
||||
}
|
||||
|
||||
/*Search the line of the index letter */;
|
||||
while(txt[line_start] != '\0') {
|
||||
new_line_start += lv_txt_get_next_line(&txt[line_start], font, style->text.letter_space, max_w, flag);
|
||||
/*Search the line of the index letter */;
|
||||
while(txt[line_start] != '\0') {
|
||||
new_line_start +=
|
||||
lv_txt_get_next_line(&txt[line_start], font, style->text.letter_space, max_w, flag);
|
||||
|
||||
if(pos->y <= y + letter_height) break; /*The line is found (stored in 'line_start')*/
|
||||
y += letter_height + style->text.line_space;
|
||||
if(pos->y <= y + letter_height) break; /*The line is found (stored in 'line_start')*/
|
||||
y += letter_height + style->text.line_space;
|
||||
|
||||
line_start = new_line_start;
|
||||
}
|
||||
line_start = new_line_start;
|
||||
}
|
||||
|
||||
/*Calculate the x coordinate*/
|
||||
lv_coord_t x = 0;
|
||||
lv_coord_t last_x = 0;
|
||||
if(ext->align == LV_LABEL_ALIGN_CENTER) {
|
||||
lv_coord_t line_w;
|
||||
line_w = lv_txt_get_width(&txt[line_start], new_line_start - line_start,
|
||||
font, style->text.letter_space, flag);
|
||||
x += lv_obj_get_width(label) / 2 - line_w / 2;
|
||||
}
|
||||
/*Calculate the x coordinate*/
|
||||
lv_coord_t x = 0;
|
||||
lv_coord_t last_x = 0;
|
||||
if(ext->align == LV_LABEL_ALIGN_CENTER) {
|
||||
lv_coord_t line_w;
|
||||
line_w = lv_txt_get_width(&txt[line_start], new_line_start - line_start, font,
|
||||
style->text.letter_space, flag);
|
||||
x += lv_obj_get_width(label) / 2 - line_w / 2;
|
||||
}
|
||||
|
||||
lv_txt_cmd_state_t cmd_state = LV_TXT_CMD_STATE_WAIT;
|
||||
uint32_t i = line_start;
|
||||
uint32_t i_current = i;
|
||||
uint32_t letter = 0;
|
||||
while(i <= new_line_start - 1) {
|
||||
letter = lv_txt_encoded_next(txt, &i); /*Be careful 'i' already points to the next character*/
|
||||
/*Handle the recolor command*/
|
||||
if((flag & LV_TXT_FLAG_RECOLOR) != 0) {
|
||||
if(lv_txt_is_cmd(&cmd_state, txt[i]) != false) {
|
||||
continue; /*Skip the letter is it is part of a command*/
|
||||
}
|
||||
}
|
||||
last_x = x;
|
||||
x += lv_font_get_width(font, letter);
|
||||
if(pos->x < x) {
|
||||
i = i_current;
|
||||
break;
|
||||
}
|
||||
x += style->text.letter_space;
|
||||
i_current = i;
|
||||
}
|
||||
lv_txt_cmd_state_t cmd_state = LV_TXT_CMD_STATE_WAIT;
|
||||
uint32_t i = line_start;
|
||||
uint32_t i_current = i;
|
||||
uint32_t letter = 0;
|
||||
while(i <= new_line_start - 1) {
|
||||
letter =
|
||||
lv_txt_encoded_next(txt, &i); /*Be careful 'i' already points to the next character*/
|
||||
/*Handle the recolor command*/
|
||||
if((flag & LV_TXT_FLAG_RECOLOR) != 0) {
|
||||
if(lv_txt_is_cmd(&cmd_state, txt[i]) != false) {
|
||||
continue; /*Skip the letter is it is part of a command*/
|
||||
}
|
||||
}
|
||||
last_x = x;
|
||||
x += lv_font_get_width(font, letter);
|
||||
if(pos->x < x) {
|
||||
i = i_current;
|
||||
break;
|
||||
}
|
||||
x += style->text.letter_space;
|
||||
i_current = i;
|
||||
}
|
||||
|
||||
int max_diff = lv_font_get_width(font, letter) + style->text.letter_space + 1;
|
||||
return (pos->x >= (last_x - style->text.letter_space) && pos->x <= (last_x + max_diff));
|
||||
int max_diff = lv_font_get_width(font, letter) + style->text.letter_space + 1;
|
||||
return (pos->x >= (last_x - style->text.letter_space) && pos->x <= (last_x + max_diff));
|
||||
}
|
||||
|
||||
|
||||
/*=====================
|
||||
* Other functions
|
||||
*====================*/
|
||||
@ -627,12 +642,11 @@ bool lv_label_is_char_under_pos(const lv_obj_t * label, lv_point_t * pos) {
|
||||
/**
|
||||
* Insert a text to the label. The label text can not be static.
|
||||
* @param label pointer to a label object
|
||||
* @param pos character index to insert. Expressed in character index and not byte index (Different in UTF-8)
|
||||
* 0: before first char.
|
||||
* LV_LABEL_POS_LAST: after last char.
|
||||
* @param pos character index to insert. Expressed in character index and not byte index (Different
|
||||
* in UTF-8) 0: before first char. LV_LABEL_POS_LAST: after last char.
|
||||
* @param txt pointer to the text to insert
|
||||
*/
|
||||
void lv_label_ins_text(lv_obj_t * label, uint32_t pos, const char * txt)
|
||||
void lv_label_ins_text(lv_obj_t * label, uint32_t pos, const char * txt)
|
||||
{
|
||||
lv_label_ext_t * ext = lv_obj_get_ext_attr(label);
|
||||
|
||||
@ -645,7 +659,7 @@ void lv_label_ins_text(lv_obj_t * label, uint32_t pos, const char * txt)
|
||||
uint32_t old_len = strlen(ext->text);
|
||||
uint32_t ins_len = strlen(txt);
|
||||
uint32_t new_len = ins_len + old_len;
|
||||
ext->text = lv_mem_realloc(ext->text, new_len + 1);
|
||||
ext->text = lv_mem_realloc(ext->text, new_len + 1);
|
||||
lv_mem_assert(ext->text);
|
||||
if(ext->text == NULL) return;
|
||||
|
||||
@ -661,11 +675,11 @@ void lv_label_ins_text(lv_obj_t * label, uint32_t pos, const char * txt)
|
||||
/**
|
||||
* Delete characters from a label. The label text can not be static.
|
||||
* @param label pointer to a label object
|
||||
* @param pos character index to insert. Expressed in character index and not byte index (Different in UTF-8)
|
||||
* 0: before first char.
|
||||
* @param pos character index to insert. Expressed in character index and not byte index (Different
|
||||
* in UTF-8) 0: before first char.
|
||||
* @param cnt number of characters to cut
|
||||
*/
|
||||
void lv_label_cut_text(lv_obj_t * label, uint32_t pos, uint32_t cnt)
|
||||
void lv_label_cut_text(lv_obj_t * label, uint32_t pos, uint32_t cnt)
|
||||
{
|
||||
lv_label_ext_t * ext = lv_obj_get_ext_attr(label);
|
||||
|
||||
@ -699,7 +713,8 @@ void lv_label_cut_text(lv_obj_t * label, uint32_t pos, uint32_t cnt)
|
||||
static bool lv_label_design(lv_obj_t * label, const lv_area_t * mask, lv_design_mode_t mode)
|
||||
{
|
||||
/* A label never covers an area */
|
||||
if(mode == LV_DESIGN_COVER_CHK) return false;
|
||||
if(mode == LV_DESIGN_COVER_CHK)
|
||||
return false;
|
||||
else if(mode == LV_DESIGN_DRAW_MAIN) {
|
||||
lv_area_t coords;
|
||||
lv_style_t * style = lv_obj_get_style(label);
|
||||
@ -727,7 +742,7 @@ static bool lv_label_design(lv_obj_t * label, const lv_area_t * mask, lv_design_
|
||||
}
|
||||
|
||||
/*TEST: draw a background for the label*/
|
||||
//lv_draw_rect(&label->coords, mask, &lv_style_plain_color, LV_OPA_COVER);
|
||||
// lv_draw_rect(&label->coords, mask, &lv_style_plain_color, LV_OPA_COVER);
|
||||
|
||||
lv_txt_flag_t flag = LV_TXT_FLAG_NONE;
|
||||
if(ext->recolor != 0) flag |= LV_TXT_FLAG_RECOLOR;
|
||||
@ -738,42 +753,46 @@ static bool lv_label_design(lv_obj_t * label, const lv_area_t * mask, lv_design_
|
||||
/* In ROLL mode the CENTER and RIGHT are pointless so remove them.
|
||||
* (In addition they will result mis-alignment is this case)*/
|
||||
if((ext->long_mode == LV_LABEL_LONG_ROLL || ext->long_mode == LV_LABEL_LONG_ROLL_CIRC) &&
|
||||
(ext->align == LV_LABEL_ALIGN_CENTER || ext->align == LV_LABEL_ALIGN_RIGHT)) {
|
||||
(ext->align == LV_LABEL_ALIGN_CENTER || ext->align == LV_LABEL_ALIGN_RIGHT)) {
|
||||
lv_point_t size;
|
||||
lv_txt_get_size(&size, ext->text, style->text.font, style->text.letter_space, style->text.line_space, LV_COORD_MAX, flag);
|
||||
lv_txt_get_size(&size, ext->text, style->text.font, style->text.letter_space,
|
||||
style->text.line_space, LV_COORD_MAX, flag);
|
||||
if(size.x > lv_obj_get_width(label)) {
|
||||
flag &= ~LV_TXT_FLAG_RIGHT;
|
||||
flag &= ~LV_TXT_FLAG_CENTER;
|
||||
}
|
||||
}
|
||||
|
||||
lv_draw_label(&coords, mask, style, opa_scale, ext->text, flag, &ext->offset, ext->selection_start, ext->selection_end);
|
||||
lv_draw_label(&coords, mask, style, opa_scale, ext->text, flag, &ext->offset,
|
||||
ext->selection_start, ext->selection_end);
|
||||
|
||||
if(ext->long_mode == LV_LABEL_LONG_ROLL_CIRC) {
|
||||
lv_point_t size;
|
||||
lv_txt_get_size(&size, ext->text, style->text.font, style->text.letter_space, style->text.line_space, LV_COORD_MAX, flag);
|
||||
lv_txt_get_size(&size, ext->text, style->text.font, style->text.letter_space,
|
||||
style->text.line_space, LV_COORD_MAX, flag);
|
||||
|
||||
lv_point_t ofs;
|
||||
/*Draw the text again next to the original to make an circular effect */
|
||||
if(size.x > lv_obj_get_width(label)) {
|
||||
ofs.x = ext->offset.x + size.x + lv_font_get_width(style->text.font, ' ') * ANIM_WAIT_CHAR_COUNT;
|
||||
ofs.x = ext->offset.x + size.x +
|
||||
lv_font_get_width(style->text.font, ' ') * ANIM_WAIT_CHAR_COUNT;
|
||||
ofs.y = ext->offset.y;
|
||||
lv_draw_label(&coords, mask, style, opa_scale, ext->text, flag, &ofs, ext->selection_start, ext->selection_end);
|
||||
lv_draw_label(&coords, mask, style, opa_scale, ext->text, flag, &ofs,
|
||||
ext->selection_start, ext->selection_end);
|
||||
}
|
||||
|
||||
/*Draw the text again below the original to make an circular effect */
|
||||
if(size.y > lv_obj_get_height(label)) {
|
||||
ofs.x = ext->offset.x;
|
||||
ofs.y = ext->offset.y + size.y + lv_font_get_height(style->text.font);
|
||||
lv_draw_label(&coords, mask, style, opa_scale, ext->text, flag, &ofs, ext->selection_start, ext->selection_end);
|
||||
lv_draw_label(&coords, mask, style, opa_scale, ext->text, flag, &ofs,
|
||||
ext->selection_start, ext->selection_end);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Signal function of the label
|
||||
* @param label pointer to a label object
|
||||
@ -790,7 +809,7 @@ static lv_res_t lv_label_signal(lv_obj_t * label, lv_signal_t sign, void * param
|
||||
if(res != LV_RES_OK) return res;
|
||||
|
||||
lv_label_ext_t * ext = lv_obj_get_ext_attr(label);
|
||||
if(sign == LV_SIGNAL_CLEANUP) {
|
||||
if(sign == LV_SIGNAL_CLEANUP) {
|
||||
if(ext->static_txt == 0) {
|
||||
lv_mem_free(ext->text);
|
||||
ext->text = NULL;
|
||||
@ -802,22 +821,22 @@ static lv_res_t lv_label_signal(lv_obj_t * label, lv_signal_t sign, void * param
|
||||
lv_label_refr_text(label);
|
||||
} else if(sign == LV_SIGNAL_CORD_CHG) {
|
||||
if(lv_area_get_width(&label->coords) != lv_area_get_width(param) ||
|
||||
lv_area_get_height(&label->coords) != lv_area_get_height(param)) {
|
||||
lv_area_get_height(&label->coords) != lv_area_get_height(param)) {
|
||||
lv_label_revert_dots(label);
|
||||
lv_label_refr_text(label);
|
||||
}
|
||||
} else if(sign == LV_SIGNAL_REFR_EXT_SIZE) {
|
||||
if(ext->body_draw) {
|
||||
lv_style_t * style = lv_label_get_style(label);
|
||||
label->ext_size = LV_MATH_MAX(label->ext_size, style->body.padding.left);
|
||||
label->ext_size = LV_MATH_MAX(label->ext_size, style->body.padding.right);
|
||||
label->ext_size = LV_MATH_MAX(label->ext_size, style->body.padding.top);
|
||||
label->ext_size = LV_MATH_MAX(label->ext_size, style->body.padding.bottom);
|
||||
label->ext_size = LV_MATH_MAX(label->ext_size, style->body.padding.left);
|
||||
label->ext_size = LV_MATH_MAX(label->ext_size, style->body.padding.right);
|
||||
label->ext_size = LV_MATH_MAX(label->ext_size, style->body.padding.top);
|
||||
label->ext_size = LV_MATH_MAX(label->ext_size, style->body.padding.bottom);
|
||||
}
|
||||
} else if(sign == LV_SIGNAL_GET_TYPE) {
|
||||
lv_obj_type_t * buf = param;
|
||||
uint8_t i;
|
||||
for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/
|
||||
for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/
|
||||
if(buf->type[i] == NULL) break;
|
||||
}
|
||||
buf->type[i] = "lv_label";
|
||||
@ -836,8 +855,8 @@ static void lv_label_refr_text(lv_obj_t * label)
|
||||
|
||||
if(ext->text == NULL) return;
|
||||
|
||||
lv_coord_t max_w = lv_obj_get_width(label);
|
||||
lv_style_t * style = lv_obj_get_style(label);
|
||||
lv_coord_t max_w = lv_obj_get_width(label);
|
||||
lv_style_t * style = lv_obj_get_style(label);
|
||||
const lv_font_t * font = style->text.font;
|
||||
|
||||
/*If the width will be expanded set the max length to very big */
|
||||
@ -850,7 +869,8 @@ static void lv_label_refr_text(lv_obj_t * label)
|
||||
lv_txt_flag_t flag = LV_TXT_FLAG_NONE;
|
||||
if(ext->recolor != 0) flag |= LV_TXT_FLAG_RECOLOR;
|
||||
if(ext->expand != 0) flag |= LV_TXT_FLAG_EXPAND;
|
||||
lv_txt_get_size(&size, ext->text, font, style->text.letter_space, style->text.line_space, max_w, flag);
|
||||
lv_txt_get_size(&size, ext->text, font, style->text.letter_space, style->text.line_space, max_w,
|
||||
flag);
|
||||
|
||||
/*Set the full size in expand mode*/
|
||||
if(ext->long_mode == LV_LABEL_LONG_EXPAND) {
|
||||
@ -860,105 +880,112 @@ static void lv_label_refr_text(lv_obj_t * label)
|
||||
else if(ext->long_mode == LV_LABEL_LONG_ROLL) {
|
||||
#if LV_USE_ANIMATION
|
||||
lv_anim_t anim;
|
||||
anim.var = label;
|
||||
anim.repeat = 1;
|
||||
anim.var = label;
|
||||
anim.repeat = 1;
|
||||
anim.playback = 1;
|
||||
anim.start = 0;
|
||||
anim.start = 0;
|
||||
anim.act_time = 0;
|
||||
anim.end_cb = NULL;
|
||||
anim.path = lv_anim_path_linear;
|
||||
anim.playback_pause = (((lv_font_get_width(style->text.font, ' ') + style->text.letter_space) * 1000) / ext->anim_speed) * ANIM_WAIT_CHAR_COUNT;;
|
||||
anim.repeat_pause = anim.playback_pause;
|
||||
anim.end_cb = NULL;
|
||||
anim.path = lv_anim_path_linear;
|
||||
anim.playback_pause =
|
||||
(((lv_font_get_width(style->text.font, ' ') + style->text.letter_space) * 1000) /
|
||||
ext->anim_speed) *
|
||||
ANIM_WAIT_CHAR_COUNT;
|
||||
;
|
||||
anim.repeat_pause = anim.playback_pause;
|
||||
|
||||
bool hor_anim = false;
|
||||
if(size.x > lv_obj_get_width(label)) {
|
||||
anim.end = lv_obj_get_width(label) - size.x;
|
||||
anim.fp = (lv_anim_fp_t) lv_label_set_offset_x;
|
||||
anim.end = lv_obj_get_width(label) - size.x;
|
||||
anim.fp = (lv_anim_fp_t)lv_label_set_offset_x;
|
||||
anim.time = lv_anim_speed_to_time(ext->anim_speed, anim.start, anim.end);
|
||||
lv_anim_create(&anim);
|
||||
hor_anim = true;
|
||||
} else {
|
||||
/*Delete the offset animation if not required*/
|
||||
lv_anim_del(label, (lv_anim_fp_t) lv_label_set_offset_x);
|
||||
lv_anim_del(label, (lv_anim_fp_t)lv_label_set_offset_x);
|
||||
ext->offset.x = 0;
|
||||
}
|
||||
|
||||
if(size.y > lv_obj_get_height(label) && hor_anim == false) {
|
||||
anim.end = lv_obj_get_height(label) - size.y - (lv_font_get_height(font));
|
||||
anim.fp = (lv_anim_fp_t)lv_label_set_offset_y;
|
||||
anim.end = lv_obj_get_height(label) - size.y - (lv_font_get_height(font));
|
||||
anim.fp = (lv_anim_fp_t)lv_label_set_offset_y;
|
||||
anim.time = lv_anim_speed_to_time(ext->anim_speed, anim.start, anim.end);
|
||||
lv_anim_create(&anim);
|
||||
} else {
|
||||
/*Delete the offset animation if not required*/
|
||||
lv_anim_del(label, (lv_anim_fp_t) lv_label_set_offset_y);
|
||||
lv_anim_del(label, (lv_anim_fp_t)lv_label_set_offset_y);
|
||||
ext->offset.y = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
/*In roll inf. mode keep the size but start offset animations*/
|
||||
else if(ext->long_mode == LV_LABEL_LONG_ROLL_CIRC) {
|
||||
#if LV_USE_ANIMATION
|
||||
lv_anim_t anim;
|
||||
anim.var = label;
|
||||
anim.repeat = 1;
|
||||
anim.playback = 0;
|
||||
anim.start = 0;
|
||||
anim.act_time = 0;
|
||||
anim.end_cb = NULL;
|
||||
anim.path = lv_anim_path_linear;
|
||||
anim.playback_pause = 0;
|
||||
anim.repeat_pause = 0;
|
||||
#if LV_USE_ANIMATION
|
||||
lv_anim_t anim;
|
||||
anim.var = label;
|
||||
anim.repeat = 1;
|
||||
anim.playback = 0;
|
||||
anim.start = 0;
|
||||
anim.act_time = 0;
|
||||
anim.end_cb = NULL;
|
||||
anim.path = lv_anim_path_linear;
|
||||
anim.playback_pause = 0;
|
||||
anim.repeat_pause = 0;
|
||||
|
||||
bool hor_anim = false;
|
||||
if(size.x > lv_obj_get_width(label)) {
|
||||
anim.end = - size.x - lv_font_get_width(font, ' ') * ANIM_WAIT_CHAR_COUNT;
|
||||
anim.fp = (lv_anim_fp_t) lv_label_set_offset_x;
|
||||
anim.time = lv_anim_speed_to_time(ext->anim_speed, anim.start, anim.end);
|
||||
lv_anim_create(&anim);
|
||||
hor_anim = true;
|
||||
} else {
|
||||
/*Delete the offset animation if not required*/
|
||||
lv_anim_del(label, (lv_anim_fp_t) lv_label_set_offset_x);
|
||||
ext->offset.x = 0;
|
||||
}
|
||||
bool hor_anim = false;
|
||||
if(size.x > lv_obj_get_width(label)) {
|
||||
anim.end = -size.x - lv_font_get_width(font, ' ') * ANIM_WAIT_CHAR_COUNT;
|
||||
anim.fp = (lv_anim_fp_t)lv_label_set_offset_x;
|
||||
anim.time = lv_anim_speed_to_time(ext->anim_speed, anim.start, anim.end);
|
||||
lv_anim_create(&anim);
|
||||
hor_anim = true;
|
||||
} else {
|
||||
/*Delete the offset animation if not required*/
|
||||
lv_anim_del(label, (lv_anim_fp_t)lv_label_set_offset_x);
|
||||
ext->offset.x = 0;
|
||||
}
|
||||
|
||||
if(size.y > lv_obj_get_height(label) && hor_anim == false) {
|
||||
anim.end = - size.y - (lv_font_get_height(font));
|
||||
anim.fp = (lv_anim_fp_t)lv_label_set_offset_y;
|
||||
anim.time = lv_anim_speed_to_time(ext->anim_speed, anim.start, anim.end);
|
||||
lv_anim_create(&anim);
|
||||
} else {
|
||||
/*Delete the offset animation if not required*/
|
||||
lv_anim_del(label, (lv_anim_fp_t) lv_label_set_offset_y);
|
||||
ext->offset.y = 0;
|
||||
}
|
||||
#endif
|
||||
if(size.y > lv_obj_get_height(label) && hor_anim == false) {
|
||||
anim.end = -size.y - (lv_font_get_height(font));
|
||||
anim.fp = (lv_anim_fp_t)lv_label_set_offset_y;
|
||||
anim.time = lv_anim_speed_to_time(ext->anim_speed, anim.start, anim.end);
|
||||
lv_anim_create(&anim);
|
||||
} else {
|
||||
/*Delete the offset animation if not required*/
|
||||
lv_anim_del(label, (lv_anim_fp_t)lv_label_set_offset_y);
|
||||
ext->offset.y = 0;
|
||||
}
|
||||
#endif
|
||||
} else if(ext->long_mode == LV_LABEL_LONG_DOT) {
|
||||
if(size.y <= lv_obj_get_height(label)) { /*No dots are required, the text is short enough*/
|
||||
if(size.y <= lv_obj_get_height(label)) { /*No dots are required, the text is short enough*/
|
||||
ext->dot_end = LV_LABEL_DOT_END_INV;
|
||||
} else if(lv_txt_get_encoded_length(ext->text) <= LV_LABEL_DOT_NUM) { /*Don't turn to dots all the characters*/
|
||||
} else if(lv_txt_get_encoded_length(ext->text) <=
|
||||
LV_LABEL_DOT_NUM) { /*Don't turn to dots all the characters*/
|
||||
ext->dot_end = LV_LABEL_DOT_END_INV;
|
||||
} else {
|
||||
lv_point_t p;
|
||||
p.x = lv_obj_get_width(label) - (lv_font_get_width(style->text.font, '.') + style->text.letter_space) * LV_LABEL_DOT_NUM; /*Shrink with dots*/
|
||||
p.x = lv_obj_get_width(label) -
|
||||
(lv_font_get_width(style->text.font, '.') + style->text.letter_space) *
|
||||
LV_LABEL_DOT_NUM; /*Shrink with dots*/
|
||||
p.y = lv_obj_get_height(label);
|
||||
p.y -= p.y % (lv_font_get_height(style->text.font) + style->text.line_space); /*Round down to the last line*/
|
||||
p.y -= style->text.line_space; /*Trim the last line space*/
|
||||
p.y -= p.y % (lv_font_get_height(style->text.font) +
|
||||
style->text.line_space); /*Round down to the last line*/
|
||||
p.y -= style->text.line_space; /*Trim the last line space*/
|
||||
uint32_t letter_id = lv_label_get_letter_on(label, &p);
|
||||
|
||||
|
||||
/*Save letters under the dots and replace them with dots*/
|
||||
uint32_t i;
|
||||
uint32_t byte_id = lv_txt_encoded_get_byte_id(ext->text, letter_id);
|
||||
uint32_t byte_id = lv_txt_encoded_get_byte_id(ext->text, letter_id);
|
||||
uint32_t byte_id_ori = byte_id;
|
||||
uint8_t len = 0;
|
||||
for(i = 0; i <= LV_LABEL_DOT_NUM; i++) {
|
||||
uint8_t len = 0;
|
||||
for(i = 0; i <= LV_LABEL_DOT_NUM; i++) {
|
||||
len += lv_txt_encoded_size(&ext->text[byte_id]);
|
||||
lv_txt_encoded_next(ext->text, &byte_id);
|
||||
}
|
||||
|
||||
memcpy(ext->dot_tmp, &ext->text[byte_id_ori], len);
|
||||
ext->dot_tmp[len] = '\0'; /*Close with a zero*/
|
||||
ext->dot_tmp[len] = '\0'; /*Close with a zero*/
|
||||
|
||||
for(i = 0; i < LV_LABEL_DOT_NUM; i++) {
|
||||
ext->text[byte_id_ori + i] = '.';
|
||||
@ -977,7 +1004,6 @@ static void lv_label_refr_text(lv_obj_t * label)
|
||||
/*Do nothing*/
|
||||
}
|
||||
|
||||
|
||||
lv_obj_invalidate(label);
|
||||
}
|
||||
|
||||
@ -987,7 +1013,7 @@ static void lv_label_revert_dots(lv_obj_t * label)
|
||||
if(ext->long_mode != LV_LABEL_LONG_DOT) return;
|
||||
if(ext->dot_end == LV_LABEL_DOT_END_INV) return;
|
||||
uint32_t letter_i = ext->dot_end - LV_LABEL_DOT_NUM;
|
||||
uint32_t byte_i = lv_txt_encoded_get_byte_id(ext->text, letter_i);
|
||||
uint32_t byte_i = lv_txt_encoded_get_byte_id(ext->text, letter_i);
|
||||
|
||||
/*Restore the characters*/
|
||||
uint8_t i = 0;
|
||||
@ -1003,14 +1029,14 @@ static void lv_label_revert_dots(lv_obj_t * label)
|
||||
static void lv_label_set_offset_x(lv_obj_t * label, lv_coord_t x)
|
||||
{
|
||||
lv_label_ext_t * ext = lv_obj_get_ext_attr(label);
|
||||
ext->offset.x = x;
|
||||
ext->offset.x = x;
|
||||
lv_obj_invalidate(label);
|
||||
}
|
||||
|
||||
static void lv_label_set_offset_y(lv_obj_t * label, lv_coord_t y)
|
||||
{
|
||||
lv_label_ext_t * ext = lv_obj_get_ext_attr(label);
|
||||
ext->offset.y = y;
|
||||
ext->offset.y = y;
|
||||
lv_obj_invalidate(label);
|
||||
}
|
||||
#endif
|
||||
|
@ -29,22 +29,22 @@ extern "C" {
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define LV_LABEL_DOT_NUM 3
|
||||
#define LV_LABEL_POS_LAST 0xFFFF
|
||||
#define LV_LABEL_DOT_NUM 3
|
||||
#define LV_LABEL_POS_LAST 0xFFFF
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/*Long mode behaviors. Used in 'lv_label_ext_t' */
|
||||
enum
|
||||
{
|
||||
LV_LABEL_LONG_EXPAND, /*Expand the object size to the text size*/
|
||||
LV_LABEL_LONG_BREAK, /*Keep the object width, break the too long lines and expand the object height*/
|
||||
LV_LABEL_LONG_DOT, /*Keep the size and write dots at the end if the text is too long*/
|
||||
LV_LABEL_LONG_ROLL, /*Keep the size and roll the text back and forth*/
|
||||
LV_LABEL_LONG_ROLL_CIRC,/*Keep the size and roll the text circularly*/
|
||||
LV_LABEL_LONG_CROP, /*Keep the size and crop the text out of it*/
|
||||
enum {
|
||||
LV_LABEL_LONG_EXPAND, /*Expand the object size to the text size*/
|
||||
LV_LABEL_LONG_BREAK, /*Keep the object width, break the too long lines and expand the object
|
||||
height*/
|
||||
LV_LABEL_LONG_DOT, /*Keep the size and write dots at the end if the text is too long*/
|
||||
LV_LABEL_LONG_ROLL, /*Keep the size and roll the text back and forth*/
|
||||
LV_LABEL_LONG_ROLL_CIRC, /*Keep the size and roll the text circularly*/
|
||||
LV_LABEL_LONG_CROP, /*Keep the size and crop the text out of it*/
|
||||
};
|
||||
typedef uint8_t lv_label_long_mode_t;
|
||||
|
||||
@ -59,29 +59,29 @@ typedef uint8_t lv_label_align_t;
|
||||
/*Data of label*/
|
||||
typedef struct
|
||||
{
|
||||
/*Inherited from 'base_obj' so no inherited ext.*/ /*Ext. of ancestor*/
|
||||
/*Inherited from 'base_obj' so no inherited ext.*/ /*Ext. of ancestor*/
|
||||
/*New data for this type */
|
||||
char * text; /*Text of the label*/
|
||||
lv_label_long_mode_t long_mode; /*Determinate what to do with the long texts*/
|
||||
char dot_tmp[LV_LABEL_DOT_NUM * 4 + 1]; /*Store the character which are replaced by dots (Handled by the library)*/
|
||||
char * text; /*Text of the label*/
|
||||
lv_label_long_mode_t long_mode; /*Determinate what to do with the long texts*/
|
||||
char dot_tmp[LV_LABEL_DOT_NUM * 4 +
|
||||
1]; /*Store the character which are replaced by dots (Handled by the library)*/
|
||||
|
||||
uint16_t dot_end; /*The text end position in dot mode (Handled by the library)*/
|
||||
uint16_t anim_speed; /*Speed of scroll and roll animation in px/sec unit*/
|
||||
lv_point_t offset; /*Text draw position offset*/
|
||||
uint8_t static_txt :1; /*Flag to indicate the text is static*/
|
||||
uint8_t align :2; /*Align type from 'lv_label_align_t'*/
|
||||
uint8_t recolor :1; /*Enable in-line letter re-coloring*/
|
||||
uint8_t expand :1; /*Ignore real width (used by the library with LV_LABEL_LONG_ROLL)*/
|
||||
uint8_t body_draw :1; /*Draw background body*/
|
||||
int selection_start; /*Left-most selection character*/
|
||||
int selection_end; /*Right-most selection character*/
|
||||
uint16_t dot_end; /*The text end position in dot mode (Handled by the library)*/
|
||||
uint16_t anim_speed; /*Speed of scroll and roll animation in px/sec unit*/
|
||||
lv_point_t offset; /*Text draw position offset*/
|
||||
uint8_t static_txt : 1; /*Flag to indicate the text is static*/
|
||||
uint8_t align : 2; /*Align type from 'lv_label_align_t'*/
|
||||
uint8_t recolor : 1; /*Enable in-line letter re-coloring*/
|
||||
uint8_t expand : 1; /*Ignore real width (used by the library with LV_LABEL_LONG_ROLL)*/
|
||||
uint8_t body_draw : 1; /*Draw background body*/
|
||||
int selection_start; /*Left-most selection character*/
|
||||
int selection_end; /*Right-most selection character*/
|
||||
} lv_label_ext_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
|
||||
/**
|
||||
* Create a label objects
|
||||
* @param par pointer to an object, it will be the parent of the new label
|
||||
@ -122,7 +122,8 @@ void lv_label_set_static_text(lv_obj_t * label, const char * text);
|
||||
* Set the behavior of the label with longer text then the object size
|
||||
* @param label pointer to a label object
|
||||
* @param long_mode the new mode from 'lv_label_long_mode' enum.
|
||||
* In LV_LONG_BREAK/LONG/ROLL the size of the label should be set AFTER this function
|
||||
* In LV_LONG_BREAK/LONG/ROLL the size of the label should be set AFTER this
|
||||
* function
|
||||
*/
|
||||
void lv_label_set_long_mode(lv_obj_t * label, lv_label_long_mode_t long_mode);
|
||||
|
||||
@ -131,7 +132,7 @@ void lv_label_set_long_mode(lv_obj_t * label, lv_label_long_mode_t long_mode);
|
||||
* @param label pointer to a label object
|
||||
* @param align 'LV_LABEL_ALIGN_LEFT' or 'LV_LABEL_ALIGN_LEFT'
|
||||
*/
|
||||
void lv_label_set_align(lv_obj_t *label, lv_label_align_t align);
|
||||
void lv_label_set_align(lv_obj_t * label, lv_label_align_t align);
|
||||
|
||||
/**
|
||||
* Enable the recoloring by in-line commands
|
||||
@ -145,21 +146,21 @@ void lv_label_set_recolor(lv_obj_t * label, bool en);
|
||||
* @param label pointer to a label object
|
||||
* @param en true: draw body; false: don't draw body
|
||||
*/
|
||||
void lv_label_set_body_draw(lv_obj_t *label, bool en);
|
||||
void lv_label_set_body_draw(lv_obj_t * label, bool en);
|
||||
|
||||
/**
|
||||
* Set the label's animation speed in LV_LABEL_LONG_ROLL and SCROLL modes
|
||||
* @param label pointer to a label object
|
||||
* @param anim_speed speed of animation in px/sec unit
|
||||
*/
|
||||
void lv_label_set_anim_speed(lv_obj_t *label, uint16_t anim_speed);
|
||||
void lv_label_set_anim_speed(lv_obj_t * label, uint16_t anim_speed);
|
||||
|
||||
/**
|
||||
* Set the style of an label
|
||||
* @param label pointer to an label object
|
||||
* @param style pointer to a style
|
||||
*/
|
||||
static inline void lv_label_set_style(lv_obj_t *label, lv_style_t *style)
|
||||
static inline void lv_label_set_style(lv_obj_t * label, lv_style_t * style)
|
||||
{
|
||||
lv_obj_set_style(label, style);
|
||||
}
|
||||
@ -200,19 +201,20 @@ bool lv_label_get_recolor(const lv_obj_t * label);
|
||||
* @param label pointer to a label object
|
||||
* @return true: draw body; false: don't draw body
|
||||
*/
|
||||
bool lv_label_get_body_draw(const lv_obj_t *label);
|
||||
bool lv_label_get_body_draw(const lv_obj_t * label);
|
||||
|
||||
/**
|
||||
* Get the label's animation speed in LV_LABEL_LONG_ROLL and SCROLL modes
|
||||
* @param label pointer to a label object
|
||||
* @return speed of animation in px/sec unit
|
||||
*/
|
||||
uint16_t lv_label_get_anim_speed(const lv_obj_t *label);
|
||||
uint16_t lv_label_get_anim_speed(const lv_obj_t * label);
|
||||
|
||||
/**
|
||||
* Get the relative x and y coordinates of a letter
|
||||
* @param label pointer to a label object
|
||||
* @param index index of the letter [0 ... text length]. Expressed in character index, not byte index (different in UTF-8)
|
||||
* @param index index of the letter [0 ... text length]. Expressed in character index, not byte
|
||||
* index (different in UTF-8)
|
||||
* @param pos store the result here (E.g. index = 0 gives 0;0 coordinates)
|
||||
*/
|
||||
void lv_label_get_letter_pos(const lv_obj_t * label, uint16_t index, lv_point_t * pos);
|
||||
@ -239,7 +241,7 @@ bool lv_label_is_char_under_pos(const lv_obj_t * label, lv_point_t * pos);
|
||||
* @param label pointer to an label object
|
||||
* @return pointer to the label's style
|
||||
*/
|
||||
static inline lv_style_t* lv_label_get_style(const lv_obj_t *label)
|
||||
static inline lv_style_t * lv_label_get_style(const lv_obj_t * label)
|
||||
{
|
||||
return lv_obj_get_style(label);
|
||||
}
|
||||
@ -251,30 +253,29 @@ static inline lv_style_t* lv_label_get_style(const lv_obj_t *label)
|
||||
/**
|
||||
* Insert a text to the label. The label text can not be static.
|
||||
* @param label pointer to a label object
|
||||
* @param pos character index to insert. Expressed in character index and not byte index (Different in UTF-8)
|
||||
* 0: before first char.
|
||||
* LV_LABEL_POS_LAST: after last char.
|
||||
* @param pos character index to insert. Expressed in character index and not byte index (Different
|
||||
* in UTF-8) 0: before first char. LV_LABEL_POS_LAST: after last char.
|
||||
* @param txt pointer to the text to insert
|
||||
*/
|
||||
void lv_label_ins_text(lv_obj_t * label, uint32_t pos, const char * txt);
|
||||
void lv_label_ins_text(lv_obj_t * label, uint32_t pos, const char * txt);
|
||||
|
||||
/**
|
||||
* Delete characters from a label. The label text can not be static.
|
||||
* @param label pointer to a label object
|
||||
* @param pos character index to insert. Expressed in character index and not byte index (Different in UTF-8)
|
||||
* 0: before first char.
|
||||
* @param pos character index to insert. Expressed in character index and not byte index (Different
|
||||
* in UTF-8) 0: before first char.
|
||||
* @param cnt number of characters to cut
|
||||
*/
|
||||
void lv_label_cut_text(lv_obj_t * label, uint32_t pos, uint32_t cnt);
|
||||
void lv_label_cut_text(lv_obj_t * label, uint32_t pos, uint32_t cnt);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_LABEL*/
|
||||
#endif /*LV_USE_LABEL*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_LABEL_H*/
|
||||
#endif /*LV_LABEL_H*/
|
||||
|
@ -15,10 +15,10 @@
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define LV_LED_WIDTH_DEF (LV_DPI / 3)
|
||||
#define LV_LED_HEIGHT_DEF (LV_DPI / 3)
|
||||
#define LV_LED_BRIGHT_OFF 100
|
||||
#define LV_LED_BRIGHT_ON 255
|
||||
#define LV_LED_WIDTH_DEF (LV_DPI / 3)
|
||||
#define LV_LED_HEIGHT_DEF (LV_DPI / 3)
|
||||
#define LV_LED_BRIGHT_OFF 100
|
||||
#define LV_LED_BRIGHT_ON 255
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
@ -87,13 +87,12 @@ lv_obj_t * lv_led_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
/*Copy an existing object*/
|
||||
else {
|
||||
lv_led_ext_t * copy_ext = lv_obj_get_ext_attr(copy);
|
||||
ext->bright = copy_ext->bright;
|
||||
ext->bright = copy_ext->bright;
|
||||
|
||||
/*Refresh the style with new signal function*/
|
||||
lv_obj_refresh_style(new_led);
|
||||
}
|
||||
|
||||
|
||||
LV_LOG_INFO("led created");
|
||||
|
||||
return new_led;
|
||||
@ -138,7 +137,6 @@ void lv_led_off(lv_obj_t * led)
|
||||
lv_led_set_bright(led, LV_LED_BRIGHT_OFF);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Toggle the state of a LED
|
||||
* @param led pointer to a LED object
|
||||
@ -146,8 +144,10 @@ void lv_led_off(lv_obj_t * led)
|
||||
void lv_led_toggle(lv_obj_t * led)
|
||||
{
|
||||
uint8_t bright = lv_led_get_bright(led);
|
||||
if(bright > (LV_LED_BRIGHT_OFF + LV_LED_BRIGHT_ON) >> 1) lv_led_off(led);
|
||||
else lv_led_on(led);
|
||||
if(bright > (LV_LED_BRIGHT_OFF + LV_LED_BRIGHT_ON) >> 1)
|
||||
lv_led_off(led);
|
||||
else
|
||||
lv_led_on(led);
|
||||
}
|
||||
|
||||
/*=====================
|
||||
@ -199,17 +199,22 @@ static bool lv_led_design(lv_obj_t * led, const lv_area_t * mask, lv_design_mode
|
||||
memcpy(&leds_tmp, style, sizeof(leds_tmp));
|
||||
|
||||
/*Mix. the color with black proportionally with brightness*/
|
||||
leds_tmp.body.main_color = lv_color_mix(leds_tmp.body.main_color, LV_COLOR_BLACK, ext->bright);
|
||||
leds_tmp.body.grad_color = lv_color_mix(leds_tmp.body.grad_color, LV_COLOR_BLACK, ext->bright);
|
||||
leds_tmp.body.border.color = lv_color_mix(leds_tmp.body.border.color, LV_COLOR_BLACK, ext->bright);
|
||||
leds_tmp.body.main_color =
|
||||
lv_color_mix(leds_tmp.body.main_color, LV_COLOR_BLACK, ext->bright);
|
||||
leds_tmp.body.grad_color =
|
||||
lv_color_mix(leds_tmp.body.grad_color, LV_COLOR_BLACK, ext->bright);
|
||||
leds_tmp.body.border.color =
|
||||
lv_color_mix(leds_tmp.body.border.color, LV_COLOR_BLACK, ext->bright);
|
||||
|
||||
/*Set the current swidth according to brightness proportionally between LV_LED_BRIGHT_OFF and LV_LED_BRIGHT_ON*/
|
||||
uint16_t bright_tmp = ext->bright;
|
||||
leds_tmp.body.shadow.width = ((bright_tmp - LV_LED_BRIGHT_OFF) * style->body.shadow.width) / (LV_LED_BRIGHT_ON - LV_LED_BRIGHT_OFF);
|
||||
/*Set the current swidth according to brightness proportionally between LV_LED_BRIGHT_OFF
|
||||
* and LV_LED_BRIGHT_ON*/
|
||||
uint16_t bright_tmp = ext->bright;
|
||||
leds_tmp.body.shadow.width = ((bright_tmp - LV_LED_BRIGHT_OFF) * style->body.shadow.width) /
|
||||
(LV_LED_BRIGHT_ON - LV_LED_BRIGHT_OFF);
|
||||
|
||||
led->style_p = &leds_tmp;
|
||||
ancestor_design_f(led, mask, mode);
|
||||
led->style_p = style_ori_p; /*Restore the ORIGINAL style pointer*/
|
||||
led->style_p = style_ori_p; /*Restore the ORIGINAL style pointer*/
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -229,11 +234,10 @@ static lv_res_t lv_led_signal(lv_obj_t * led, lv_signal_t sign, void * param)
|
||||
res = ancestor_signal(led, sign, param);
|
||||
if(res != LV_RES_OK) return res;
|
||||
|
||||
|
||||
if(sign == LV_SIGNAL_GET_TYPE) {
|
||||
lv_obj_type_t * buf = param;
|
||||
uint8_t i;
|
||||
for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/
|
||||
for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/
|
||||
if(buf->type[i] == NULL) break;
|
||||
}
|
||||
buf->type[i] = "lv_led";
|
||||
|
@ -36,7 +36,7 @@ typedef struct
|
||||
{
|
||||
/*No inherited ext.*/
|
||||
/*New data for this type */
|
||||
uint8_t bright; /*Current brightness of the LED (0..255)*/
|
||||
uint8_t bright; /*Current brightness of the LED (0..255)*/
|
||||
} lv_led_ext_t;
|
||||
|
||||
/**********************
|
||||
@ -81,7 +81,7 @@ void lv_led_toggle(lv_obj_t * led);
|
||||
* @param led pointer to a led object
|
||||
* @param style pointer to a style
|
||||
*/
|
||||
static inline void lv_led_set_style(lv_obj_t *led, lv_style_t *style)
|
||||
static inline void lv_led_set_style(lv_obj_t * led, lv_style_t * style)
|
||||
{
|
||||
lv_obj_set_style(led, style);
|
||||
}
|
||||
@ -98,7 +98,7 @@ uint8_t lv_led_get_bright(const lv_obj_t * led);
|
||||
* @param led pointer to an led object
|
||||
* @return pointer to the led's style
|
||||
*/
|
||||
static inline lv_style_t* lv_led_get_style(const lv_obj_t *led)
|
||||
static inline lv_style_t * lv_led_get_style(const lv_obj_t * led)
|
||||
{
|
||||
return lv_obj_get_style(led);
|
||||
}
|
||||
@ -107,10 +107,10 @@ static inline lv_style_t* lv_led_get_style(const lv_obj_t *led)
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_LED*/
|
||||
#endif /*LV_USE_LED*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_LED_H*/
|
||||
#endif /*LV_LED_H*/
|
||||
|
@ -15,7 +15,6 @@
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
@ -64,18 +63,20 @@ lv_obj_t * lv_line_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
lv_mem_assert(ext);
|
||||
if(ext == NULL) return NULL;
|
||||
|
||||
ext->point_num = 0;
|
||||
ext->point_num = 0;
|
||||
ext->point_array = NULL;
|
||||
ext->auto_size = 1;
|
||||
ext->y_inv = 0;
|
||||
ext->auto_size = 1;
|
||||
ext->y_inv = 0;
|
||||
|
||||
lv_obj_set_design_cb(new_line, lv_line_design);
|
||||
lv_obj_set_signal_cb(new_line, lv_line_signal);
|
||||
|
||||
/*Init the new line*/
|
||||
if(copy == NULL) {
|
||||
lv_obj_set_size(new_line, LV_DPI, LV_DPI); /*Auto size is enables, but set default size until no points are added*/
|
||||
lv_obj_set_style(new_line, NULL); /*Inherit parent's style*/
|
||||
lv_obj_set_size(
|
||||
new_line, LV_DPI,
|
||||
LV_DPI); /*Auto size is enables, but set default size until no points are added*/
|
||||
lv_obj_set_style(new_line, NULL); /*Inherit parent's style*/
|
||||
lv_obj_set_click(new_line, false);
|
||||
}
|
||||
/*Copy an existing object*/
|
||||
@ -89,7 +90,6 @@ lv_obj_t * lv_line_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
lv_obj_refresh_style(new_line);
|
||||
}
|
||||
|
||||
|
||||
LV_LOG_INFO("line created");
|
||||
|
||||
return new_line;
|
||||
@ -109,8 +109,8 @@ lv_obj_t * lv_line_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
void lv_line_set_points(lv_obj_t * line, const lv_point_t * point_a, uint16_t point_num)
|
||||
{
|
||||
lv_line_ext_t * ext = lv_obj_get_ext_attr(line);
|
||||
ext->point_array = point_a;
|
||||
ext->point_num = point_num;
|
||||
ext->point_array = point_a;
|
||||
ext->point_num = point_num;
|
||||
|
||||
if(point_num > 0 && ext->auto_size != 0) {
|
||||
uint16_t i;
|
||||
@ -207,7 +207,8 @@ bool lv_line_get_y_invert(const lv_obj_t * line)
|
||||
static bool lv_line_design(lv_obj_t * line, const lv_area_t * mask, lv_design_mode_t mode)
|
||||
{
|
||||
/*A line never covers an area*/
|
||||
if(mode == LV_DESIGN_COVER_CHK) return false;
|
||||
if(mode == LV_DESIGN_COVER_CHK)
|
||||
return false;
|
||||
else if(mode == LV_DESIGN_DRAW_MAIN) {
|
||||
lv_line_ext_t * ext = lv_obj_get_ext_attr(line);
|
||||
|
||||
@ -224,12 +225,12 @@ static bool lv_line_design(lv_obj_t * line, const lv_area_t * mask, lv_design_mo
|
||||
lv_coord_t h = lv_obj_get_height(line);
|
||||
uint16_t i;
|
||||
|
||||
lv_style_t circle_style; /*If rounded...*/
|
||||
lv_style_t circle_style; /*If rounded...*/
|
||||
lv_style_copy(&circle_style, style);
|
||||
circle_style.body.radius = LV_RADIUS_CIRCLE;
|
||||
circle_style.body.radius = LV_RADIUS_CIRCLE;
|
||||
circle_style.body.main_color = style->line.color;
|
||||
circle_style.body.grad_color = style->line.color;
|
||||
circle_style.body.opa = style->line.opa;
|
||||
circle_style.body.opa = style->line.opa;
|
||||
lv_area_t circle_area;
|
||||
|
||||
/*Read all points and draw the lines*/
|
||||
@ -242,15 +243,17 @@ static bool lv_line_design(lv_obj_t * line, const lv_area_t * mask, lv_design_mo
|
||||
p1.y = ext->point_array[i].y + y_ofs;
|
||||
p2.y = ext->point_array[i + 1].y + y_ofs;
|
||||
} else {
|
||||
p1.y = h - ext->point_array[i].y + y_ofs;
|
||||
p1.y = h - ext->point_array[i].y + y_ofs;
|
||||
p2.y = h - ext->point_array[i + 1].y + y_ofs;
|
||||
}
|
||||
lv_draw_line(&p1, &p2, mask, style, opa_scale);
|
||||
|
||||
/*Draw circle on the joints if enabled*/
|
||||
if(style->line.rounded) {
|
||||
circle_area.x1 = p1.x - ((style->line.width - 1) >> 1) - ((style->line.width - 1) & 0x1);
|
||||
circle_area.y1 = p1.y - ((style->line.width - 1) >> 1) - ((style->line.width - 1) & 0x1);
|
||||
circle_area.x1 =
|
||||
p1.x - ((style->line.width - 1) >> 1) - ((style->line.width - 1) & 0x1);
|
||||
circle_area.y1 =
|
||||
p1.y - ((style->line.width - 1) >> 1) - ((style->line.width - 1) & 0x1);
|
||||
circle_area.x2 = p1.x + ((style->line.width - 1) >> 1);
|
||||
circle_area.y2 = p1.y + ((style->line.width - 1) >> 1);
|
||||
lv_draw_rect(&circle_area, mask, &circle_style, opa_scale);
|
||||
@ -259,8 +262,10 @@ static bool lv_line_design(lv_obj_t * line, const lv_area_t * mask, lv_design_mo
|
||||
|
||||
/*Draw circle on the last point too if enabled*/
|
||||
if(style->line.rounded) {
|
||||
circle_area.x1 = p2.x - ((style->line.width - 1) >> 1) - ((style->line.width - 1) & 0x1);
|
||||
circle_area.y1 = p2.y - ((style->line.width - 1) >> 1) - ((style->line.width - 1) & 0x1);
|
||||
circle_area.x1 =
|
||||
p2.x - ((style->line.width - 1) >> 1) - ((style->line.width - 1) & 0x1);
|
||||
circle_area.y1 =
|
||||
p2.y - ((style->line.width - 1) >> 1) - ((style->line.width - 1) & 0x1);
|
||||
circle_area.x2 = p2.x + ((style->line.width - 1) >> 1);
|
||||
circle_area.y2 = p2.y + ((style->line.width - 1) >> 1);
|
||||
lv_draw_rect(&circle_area, mask, &circle_style, opa_scale);
|
||||
@ -283,11 +288,10 @@ static lv_res_t lv_line_signal(lv_obj_t * line, lv_signal_t sign, void * param)
|
||||
res = ancestor_signal(line, sign, param);
|
||||
if(res != LV_RES_OK) return res;
|
||||
|
||||
|
||||
if(sign == LV_SIGNAL_GET_TYPE) {
|
||||
lv_obj_type_t * buf = param;
|
||||
uint8_t i;
|
||||
for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/
|
||||
for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/
|
||||
if(buf->type[i] == NULL) break;
|
||||
}
|
||||
buf->type[i] = "lv_line";
|
||||
@ -296,7 +300,6 @@ static lv_res_t lv_line_signal(lv_obj_t * line, lv_signal_t sign, void * param)
|
||||
if(line->ext_size < style->line.width) line->ext_size = style->line.width;
|
||||
}
|
||||
|
||||
|
||||
return res;
|
||||
}
|
||||
#endif
|
||||
|
@ -34,18 +34,17 @@ extern "C" {
|
||||
/*Data of line*/
|
||||
typedef struct
|
||||
{
|
||||
/*Inherited from 'base_obj' so no inherited ext.*/ /*Ext. of ancestor*/
|
||||
const lv_point_t * point_array; /*Pointer to an array with the points of the line*/
|
||||
uint16_t point_num; /*Number of points in 'point_array' */
|
||||
uint8_t auto_size :1; /*1: set obj. width to x max and obj. height to y max */
|
||||
uint8_t y_inv :1; /*1: y == 0 will be on the bottom*/
|
||||
/*Inherited from 'base_obj' so no inherited ext.*/ /*Ext. of ancestor*/
|
||||
const lv_point_t * point_array; /*Pointer to an array with the points of the line*/
|
||||
uint16_t point_num; /*Number of points in 'point_array' */
|
||||
uint8_t auto_size : 1; /*1: set obj. width to x max and obj. height to y max */
|
||||
uint8_t y_inv : 1; /*1: y == 0 will be on the bottom*/
|
||||
} lv_line_ext_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
|
||||
/**
|
||||
* Create a line objects
|
||||
* @param par pointer to an object, it will be the parent of the new line
|
||||
@ -83,14 +82,16 @@ void lv_line_set_auto_size(lv_obj_t * line, bool en);
|
||||
*/
|
||||
void lv_line_set_y_invert(lv_obj_t * line, bool en);
|
||||
|
||||
#define lv_line_set_y_inv lv_line_set_y_invert /*The name was inconsistent. In v.6.0 only `lv_line_set_y_invert`will work */
|
||||
#define lv_line_set_y_inv \
|
||||
lv_line_set_y_invert /*The name was inconsistent. In v.6.0 only `lv_line_set_y_invert`will \
|
||||
work */
|
||||
|
||||
/**
|
||||
* Set the style of a line
|
||||
* @param line pointer to a line object
|
||||
* @param style pointer to a style
|
||||
*/
|
||||
static inline void lv_line_set_style(lv_obj_t *line, lv_style_t *style)
|
||||
static inline void lv_line_set_style(lv_obj_t * line, lv_style_t * style)
|
||||
{
|
||||
lv_obj_set_style(line, style);
|
||||
}
|
||||
@ -102,8 +103,8 @@ static inline void lv_line_set_style(lv_obj_t *line, lv_style_t *style)
|
||||
*/
|
||||
static inline void lv_line_set_upscale(lv_obj_t * line, bool upcale)
|
||||
{
|
||||
(void) line;
|
||||
(void) upcale;
|
||||
(void)line;
|
||||
(void)upcale;
|
||||
}
|
||||
/*=====================
|
||||
* Getter functions
|
||||
@ -128,7 +129,7 @@ bool lv_line_get_y_invert(const lv_obj_t * line);
|
||||
* @param line pointer to an line object
|
||||
* @return pointer to the line's style
|
||||
*/
|
||||
static inline lv_style_t* lv_line_get_style(const lv_obj_t *line)
|
||||
static inline lv_style_t * lv_line_get_style(const lv_obj_t * line)
|
||||
{
|
||||
return lv_obj_get_style(line);
|
||||
}
|
||||
@ -140,11 +141,10 @@ static inline lv_style_t* lv_line_get_style(const lv_obj_t *line)
|
||||
*/
|
||||
static inline bool lv_line_get_upscale(const lv_obj_t * line)
|
||||
{
|
||||
(void) line;
|
||||
(void)line;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
@ -155,4 +155,4 @@ static inline bool lv_line_get_upscale(const lv_obj_t * line)
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_LINE_H*/
|
||||
#endif /*LV_LINE_H*/
|
||||
|
@ -17,15 +17,16 @@
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define LV_LIST_LAYOUT_DEF LV_LAYOUT_COL_M
|
||||
#define LV_LIST_LAYOUT_DEF LV_LAYOUT_COL_M
|
||||
|
||||
#if LV_USE_ANIMATION
|
||||
# ifndef LV_LIST_FOCUS_TIME
|
||||
# define LV_LIST_DEF_ANIM_TIME 100 /*Animation time of focusing to the a list element [ms] (0: no animation) */
|
||||
# endif
|
||||
#ifndef LV_LIST_FOCUS_TIME
|
||||
#define LV_LIST_DEF_ANIM_TIME \
|
||||
100 /*Animation time of focusing to the a list element [ms] (0: no animation) */
|
||||
#endif
|
||||
#else
|
||||
# undef LV_LIST_DEF_ANIM_TIME
|
||||
# define LV_LIST_DEF_ANIM_TIME 0 /*No animations*/
|
||||
#undef LV_LIST_DEF_ANIM_TIME
|
||||
#define LV_LIST_DEF_ANIM_TIME 0 /*No animations*/
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
@ -37,7 +38,7 @@
|
||||
**********************/
|
||||
static lv_res_t lv_list_signal(lv_obj_t * list, lv_signal_t sign, void * param);
|
||||
static lv_res_t lv_list_btn_signal(lv_obj_t * btn, lv_signal_t sign, void * param);
|
||||
static void lv_list_btn_single_selected(lv_obj_t *btn);
|
||||
static void lv_list_btn_single_selected(lv_obj_t * btn);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
@ -49,7 +50,8 @@ static lv_signal_cb_t label_signal;
|
||||
static lv_signal_cb_t ancestor_page_signal;
|
||||
static lv_signal_cb_t ancestor_btn_signal;
|
||||
#if LV_USE_GROUP
|
||||
/*Used to make the last clicked button pressed (selected) when the list become focused and `click_focus == 1`*/
|
||||
/*Used to make the last clicked button pressed (selected) when the list become focused and
|
||||
* `click_focus == 1`*/
|
||||
static lv_obj_t * last_clicked_btn;
|
||||
#endif
|
||||
|
||||
@ -82,18 +84,18 @@ lv_obj_t * lv_list_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
lv_mem_assert(ext);
|
||||
if(ext == NULL) return NULL;
|
||||
|
||||
ext->style_img = NULL;
|
||||
ext->styles_btn[LV_BTN_STATE_REL] = &lv_style_btn_rel;
|
||||
ext->styles_btn[LV_BTN_STATE_PR] = &lv_style_btn_pr;
|
||||
ext->style_img = NULL;
|
||||
ext->styles_btn[LV_BTN_STATE_REL] = &lv_style_btn_rel;
|
||||
ext->styles_btn[LV_BTN_STATE_PR] = &lv_style_btn_pr;
|
||||
ext->styles_btn[LV_BTN_STATE_TGL_REL] = &lv_style_btn_tgl_rel;
|
||||
ext->styles_btn[LV_BTN_STATE_TGL_PR] = &lv_style_btn_tgl_pr;
|
||||
ext->styles_btn[LV_BTN_STATE_INA] = &lv_style_btn_ina;
|
||||
ext->anim_time = LV_LIST_DEF_ANIM_TIME;
|
||||
ext->single_mode = false;
|
||||
ext->size = 0;
|
||||
ext->styles_btn[LV_BTN_STATE_TGL_PR] = &lv_style_btn_tgl_pr;
|
||||
ext->styles_btn[LV_BTN_STATE_INA] = &lv_style_btn_ina;
|
||||
ext->anim_time = LV_LIST_DEF_ANIM_TIME;
|
||||
ext->single_mode = false;
|
||||
ext->size = 0;
|
||||
|
||||
#if LV_USE_GROUP
|
||||
ext->last_sel = NULL;
|
||||
ext->last_sel = NULL;
|
||||
ext->selected_btn = NULL;
|
||||
#endif
|
||||
|
||||
@ -137,18 +139,18 @@ lv_obj_t * lv_list_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
|
||||
lv_list_set_style(new_list, LV_LIST_STYLE_BTN_REL, copy_ext->styles_btn[LV_BTN_STATE_REL]);
|
||||
lv_list_set_style(new_list, LV_LIST_STYLE_BTN_PR, copy_ext->styles_btn[LV_BTN_STATE_PR]);
|
||||
lv_list_set_style(new_list, LV_LIST_STYLE_BTN_TGL_REL, copy_ext->styles_btn[LV_BTN_STATE_TGL_REL]);
|
||||
lv_list_set_style(new_list, LV_LIST_STYLE_BTN_TGL_PR, copy_ext->styles_btn[LV_BTN_STATE_TGL_REL]);
|
||||
lv_list_set_style(new_list, LV_LIST_STYLE_BTN_TGL_REL,
|
||||
copy_ext->styles_btn[LV_BTN_STATE_TGL_REL]);
|
||||
lv_list_set_style(new_list, LV_LIST_STYLE_BTN_TGL_PR,
|
||||
copy_ext->styles_btn[LV_BTN_STATE_TGL_REL]);
|
||||
lv_list_set_style(new_list, LV_LIST_STYLE_BTN_INA, copy_ext->styles_btn[LV_BTN_STATE_INA]);
|
||||
|
||||
/*Refresh the style with new signal function*/
|
||||
lv_obj_refresh_style(new_list);
|
||||
}
|
||||
|
||||
|
||||
LV_LOG_INFO("list created");
|
||||
|
||||
|
||||
return new_list;
|
||||
}
|
||||
|
||||
@ -161,7 +163,7 @@ void lv_list_clean(lv_obj_t * obj)
|
||||
lv_obj_t * scrl = lv_page_get_scrl(obj);
|
||||
lv_obj_clean(scrl);
|
||||
lv_list_ext_t * ext = lv_obj_get_ext_attr(obj);
|
||||
ext->size = 0;
|
||||
ext->size = 0;
|
||||
}
|
||||
|
||||
/*======================
|
||||
@ -176,10 +178,11 @@ void lv_list_clean(lv_obj_t * obj)
|
||||
* @param event_cb specify the an event handler function. NULL if unused
|
||||
* @return pointer to the new list element which can be customized (a button)
|
||||
*/
|
||||
lv_obj_t * lv_list_add(lv_obj_t * list, const void * img_src, const char * txt, lv_event_cb_t event_cb)
|
||||
lv_obj_t * lv_list_add(lv_obj_t * list, const void * img_src, const char * txt,
|
||||
lv_event_cb_t event_cb)
|
||||
{
|
||||
lv_list_ext_t * ext = lv_obj_get_ext_attr(list);
|
||||
ext->size ++;
|
||||
ext->size++;
|
||||
/*Create a list element with the image an the text*/
|
||||
lv_obj_t * liste;
|
||||
liste = lv_btn_create(list, NULL);
|
||||
@ -213,7 +216,7 @@ lv_obj_t * lv_list_add(lv_obj_t * list, const void * img_src, const char * txt,
|
||||
#endif
|
||||
if(txt != NULL) {
|
||||
lv_coord_t btn_hor_pad = ext->styles_btn[LV_BTN_STYLE_REL]->body.padding.left -
|
||||
ext->styles_btn[LV_BTN_STYLE_REL]->body.padding.right;
|
||||
ext->styles_btn[LV_BTN_STYLE_REL]->body.padding.right;
|
||||
lv_obj_t * label = lv_label_create(liste, NULL);
|
||||
lv_label_set_text(label, txt);
|
||||
lv_obj_set_click(label, false);
|
||||
@ -225,7 +228,7 @@ lv_obj_t * lv_list_add(lv_obj_t * list, const void * img_src, const char * txt,
|
||||
/* If this is the first item to be added to the list and the list is
|
||||
* focused, select it */
|
||||
{
|
||||
lv_group_t *g = lv_obj_get_group(list);
|
||||
lv_group_t * g = lv_obj_get_group(list);
|
||||
if(ext->size == 1 && lv_group_get_focused(g) == list) {
|
||||
lv_list_set_btn_selected(list, liste);
|
||||
}
|
||||
@ -238,7 +241,8 @@ lv_obj_t * lv_list_add(lv_obj_t * list, const void * img_src, const char * txt,
|
||||
/**
|
||||
* Remove the index of the button in the list
|
||||
* @param list pointer to a list object
|
||||
* @param index pointer to a the button's index in the list, index must be 0 <= index < lv_list_ext_t.size
|
||||
* @param index pointer to a the button's index in the list, index must be 0 <= index <
|
||||
* lv_list_ext_t.size
|
||||
* @return true: successfully deleted
|
||||
*/
|
||||
bool lv_list_remove(const lv_obj_t * list, uint32_t index)
|
||||
@ -246,15 +250,15 @@ bool lv_list_remove(const lv_obj_t * list, uint32_t index)
|
||||
lv_list_ext_t * ext = lv_obj_get_ext_attr(list);
|
||||
if(index >= ext->size) return false;
|
||||
uint32_t count = 0;
|
||||
lv_obj_t * e = lv_list_get_next_btn(list, NULL);
|
||||
lv_obj_t * e = lv_list_get_next_btn(list, NULL);
|
||||
while(e != NULL) {
|
||||
if(count == index) {
|
||||
lv_obj_del(e);
|
||||
ext->size --;
|
||||
ext->size--;
|
||||
return true;
|
||||
}
|
||||
e = lv_list_get_next_btn(list, e);
|
||||
count ++;
|
||||
count++;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -268,7 +272,7 @@ bool lv_list_remove(const lv_obj_t * list, uint32_t index)
|
||||
* @param list pointer to the currently pressed list object
|
||||
* @param mode, enable(true)/disable(false) single selected mode.
|
||||
*/
|
||||
void lv_list_set_single_mode(lv_obj_t *list, bool mode)
|
||||
void lv_list_set_single_mode(lv_obj_t * list, bool mode)
|
||||
{
|
||||
lv_list_ext_t * ext = lv_obj_get_ext_attr(list);
|
||||
|
||||
@ -288,19 +292,23 @@ void lv_list_set_btn_selected(lv_obj_t * list, lv_obj_t * btn)
|
||||
|
||||
if(ext->selected_btn) {
|
||||
lv_btn_state_t s = lv_btn_get_state(ext->selected_btn);
|
||||
if(s == LV_BTN_STATE_PR) lv_btn_set_state(ext->selected_btn, LV_BTN_STATE_REL);
|
||||
else if(s == LV_BTN_STATE_TGL_PR) lv_btn_set_state(ext->selected_btn, LV_BTN_STATE_TGL_REL);
|
||||
if(s == LV_BTN_STATE_PR)
|
||||
lv_btn_set_state(ext->selected_btn, LV_BTN_STATE_REL);
|
||||
else if(s == LV_BTN_STATE_TGL_PR)
|
||||
lv_btn_set_state(ext->selected_btn, LV_BTN_STATE_TGL_REL);
|
||||
}
|
||||
|
||||
ext->selected_btn = btn;
|
||||
if( btn != NULL ) {
|
||||
if(btn != NULL) {
|
||||
ext->last_sel = btn;
|
||||
}
|
||||
|
||||
if(ext->selected_btn) {
|
||||
lv_btn_state_t s = lv_btn_get_state(ext->selected_btn);
|
||||
if(s == LV_BTN_STATE_REL) lv_btn_set_state(ext->selected_btn, LV_BTN_STATE_PR);
|
||||
else if(s == LV_BTN_STATE_TGL_REL) lv_btn_set_state(ext->selected_btn, LV_BTN_STATE_TGL_PR);
|
||||
if(s == LV_BTN_STATE_REL)
|
||||
lv_btn_set_state(ext->selected_btn, LV_BTN_STATE_PR);
|
||||
else if(s == LV_BTN_STATE_TGL_REL)
|
||||
lv_btn_set_state(ext->selected_btn, LV_BTN_STATE_TGL_PR);
|
||||
|
||||
lv_page_focus(list, ext->selected_btn, ext->anim_time);
|
||||
}
|
||||
@ -332,51 +340,46 @@ void lv_list_set_anim_time(lv_obj_t * list, uint16_t anim_time)
|
||||
*/
|
||||
void lv_list_set_style(lv_obj_t * list, lv_list_style_t type, lv_style_t * style)
|
||||
{
|
||||
lv_list_ext_t * ext = lv_obj_get_ext_attr(list);
|
||||
lv_list_ext_t * ext = lv_obj_get_ext_attr(list);
|
||||
lv_btn_style_t btn_style_refr = LV_BTN_STYLE_REL;
|
||||
lv_obj_t * btn;
|
||||
|
||||
switch(type) {
|
||||
case LV_LIST_STYLE_BG:
|
||||
lv_page_set_style(list, LV_PAGE_STYLE_BG, style);
|
||||
/*style change signal will call 'refr_btn_width' */
|
||||
break;
|
||||
case LV_LIST_STYLE_SCRL:
|
||||
lv_page_set_style(list, LV_PAGE_STYLE_SCRL, style);
|
||||
break;
|
||||
case LV_LIST_STYLE_SB:
|
||||
lv_page_set_style(list, LV_PAGE_STYLE_SB, style);
|
||||
break;
|
||||
case LV_LIST_STYLE_EDGE_FLASH:
|
||||
lv_page_set_style(list, LV_PAGE_STYLE_EDGE_FLASH, style);
|
||||
break;
|
||||
case LV_LIST_STYLE_BTN_REL:
|
||||
ext->styles_btn[LV_BTN_STATE_REL] = style;
|
||||
btn_style_refr = LV_BTN_STYLE_REL;
|
||||
break;
|
||||
case LV_LIST_STYLE_BTN_PR:
|
||||
ext->styles_btn[LV_BTN_STATE_PR] = style;
|
||||
btn_style_refr = LV_BTN_STYLE_PR;
|
||||
break;
|
||||
case LV_LIST_STYLE_BTN_TGL_REL:
|
||||
ext->styles_btn[LV_BTN_STATE_TGL_REL] = style;
|
||||
btn_style_refr = LV_BTN_STYLE_TGL_REL;
|
||||
break;
|
||||
case LV_LIST_STYLE_BTN_TGL_PR:
|
||||
ext->styles_btn[LV_BTN_STATE_TGL_PR] = style;
|
||||
btn_style_refr = LV_BTN_STYLE_TGL_PR;
|
||||
break;
|
||||
case LV_LIST_STYLE_BTN_INA:
|
||||
ext->styles_btn[LV_BTN_STATE_INA] = style;
|
||||
btn_style_refr = LV_BTN_STYLE_INA;
|
||||
break;
|
||||
case LV_LIST_STYLE_BG:
|
||||
lv_page_set_style(list, LV_PAGE_STYLE_BG, style);
|
||||
/*style change signal will call 'refr_btn_width' */
|
||||
break;
|
||||
case LV_LIST_STYLE_SCRL: lv_page_set_style(list, LV_PAGE_STYLE_SCRL, style); break;
|
||||
case LV_LIST_STYLE_SB: lv_page_set_style(list, LV_PAGE_STYLE_SB, style); break;
|
||||
case LV_LIST_STYLE_EDGE_FLASH:
|
||||
lv_page_set_style(list, LV_PAGE_STYLE_EDGE_FLASH, style);
|
||||
break;
|
||||
case LV_LIST_STYLE_BTN_REL:
|
||||
ext->styles_btn[LV_BTN_STATE_REL] = style;
|
||||
btn_style_refr = LV_BTN_STYLE_REL;
|
||||
break;
|
||||
case LV_LIST_STYLE_BTN_PR:
|
||||
ext->styles_btn[LV_BTN_STATE_PR] = style;
|
||||
btn_style_refr = LV_BTN_STYLE_PR;
|
||||
break;
|
||||
case LV_LIST_STYLE_BTN_TGL_REL:
|
||||
ext->styles_btn[LV_BTN_STATE_TGL_REL] = style;
|
||||
btn_style_refr = LV_BTN_STYLE_TGL_REL;
|
||||
break;
|
||||
case LV_LIST_STYLE_BTN_TGL_PR:
|
||||
ext->styles_btn[LV_BTN_STATE_TGL_PR] = style;
|
||||
btn_style_refr = LV_BTN_STYLE_TGL_PR;
|
||||
break;
|
||||
case LV_LIST_STYLE_BTN_INA:
|
||||
ext->styles_btn[LV_BTN_STATE_INA] = style;
|
||||
btn_style_refr = LV_BTN_STYLE_INA;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
/*Refresh existing buttons' style*/
|
||||
if(type == LV_LIST_STYLE_BTN_PR || type == LV_LIST_STYLE_BTN_REL ||
|
||||
type == LV_LIST_STYLE_BTN_TGL_REL || type == LV_LIST_STYLE_BTN_TGL_PR ||
|
||||
type == LV_LIST_STYLE_BTN_INA) {
|
||||
type == LV_LIST_STYLE_BTN_TGL_REL || type == LV_LIST_STYLE_BTN_TGL_PR ||
|
||||
type == LV_LIST_STYLE_BTN_INA) {
|
||||
btn = lv_list_get_prev_btn(list, NULL);
|
||||
while(btn != NULL) {
|
||||
lv_btn_set_style(btn, btn_style_refr, ext->styles_btn[btn_style_refr]);
|
||||
@ -393,7 +396,7 @@ void lv_list_set_style(lv_obj_t * list, lv_list_style_t type, lv_style_t * style
|
||||
* Get single button selected mode.
|
||||
* @param list pointer to the currently pressed list object.
|
||||
*/
|
||||
bool lv_list_get_single_mode(lv_obj_t *list)
|
||||
bool lv_list_get_single_mode(lv_obj_t * list)
|
||||
{
|
||||
lv_list_ext_t * ext = lv_obj_get_ext_attr(list);
|
||||
|
||||
@ -463,7 +466,7 @@ lv_obj_t * lv_list_get_prev_btn(const lv_obj_t * list, lv_obj_t * prev_btn)
|
||||
/* Not a good practice but user can add/create objects to the lists manually.
|
||||
* When getting the next button try to be sure that it is at least a button */
|
||||
|
||||
lv_obj_t * btn ;
|
||||
lv_obj_t * btn;
|
||||
lv_obj_t * scrl = lv_page_get_scrl(list);
|
||||
|
||||
btn = lv_obj_get_child(scrl, prev_btn);
|
||||
@ -477,8 +480,6 @@ lv_obj_t * lv_list_get_prev_btn(const lv_obj_t * list, lv_obj_t * prev_btn)
|
||||
return btn;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get the next button from list. (Starts from the bottom button)
|
||||
* @param list pointer to a list object
|
||||
@ -490,7 +491,7 @@ lv_obj_t * lv_list_get_next_btn(const lv_obj_t * list, lv_obj_t * prev_btn)
|
||||
/* Not a good practice but user can add/create objects to the lists manually.
|
||||
* When getting the next button try to be sure that it is at least a button */
|
||||
|
||||
lv_obj_t * btn ;
|
||||
lv_obj_t * btn;
|
||||
lv_obj_t * scrl = lv_page_get_scrl(list);
|
||||
|
||||
btn = lv_obj_get_child_back(scrl, prev_btn);
|
||||
@ -513,7 +514,7 @@ lv_obj_t * lv_list_get_next_btn(const lv_obj_t * list, lv_obj_t * prev_btn)
|
||||
int32_t lv_list_get_btn_index(const lv_obj_t * list, const lv_obj_t * btn)
|
||||
{
|
||||
int index = 0;
|
||||
if( list == NULL ){
|
||||
if(list == NULL) {
|
||||
/* no list provided, assuming btn is part of a list */
|
||||
list = lv_obj_get_parent(lv_obj_get_parent(btn));
|
||||
}
|
||||
@ -522,7 +523,7 @@ int32_t lv_list_get_btn_index(const lv_obj_t * list, const lv_obj_t * btn)
|
||||
if(e == btn) {
|
||||
return index;
|
||||
}
|
||||
index ++;
|
||||
index++;
|
||||
e = lv_list_get_next_btn(list, e);
|
||||
}
|
||||
return -1;
|
||||
@ -572,40 +573,22 @@ uint16_t lv_list_get_anim_time(const lv_obj_t * list)
|
||||
* */
|
||||
lv_style_t * lv_list_get_style(const lv_obj_t * list, lv_list_style_t type)
|
||||
{
|
||||
lv_style_t * style = NULL;
|
||||
lv_style_t * style = NULL;
|
||||
lv_list_ext_t * ext = lv_obj_get_ext_attr(list);
|
||||
|
||||
switch(type) {
|
||||
case LV_LIST_STYLE_BG:
|
||||
style = lv_page_get_style(list, LV_PAGE_STYLE_BG);
|
||||
break;
|
||||
case LV_LIST_STYLE_SCRL:
|
||||
style = lv_page_get_style(list, LV_PAGE_STYLE_SB);
|
||||
break;
|
||||
case LV_LIST_STYLE_SB:
|
||||
style = lv_page_get_style(list, LV_PAGE_STYLE_SCRL);
|
||||
break;
|
||||
case LV_LIST_STYLE_EDGE_FLASH:
|
||||
style = lv_page_get_style(list, LV_PAGE_STYLE_EDGE_FLASH);
|
||||
break;
|
||||
case LV_LIST_STYLE_BTN_REL:
|
||||
style = ext->styles_btn[LV_BTN_STATE_REL];
|
||||
break;
|
||||
case LV_LIST_STYLE_BTN_PR:
|
||||
style = ext->styles_btn[LV_BTN_STATE_PR];
|
||||
break;
|
||||
case LV_LIST_STYLE_BTN_TGL_REL:
|
||||
style = ext->styles_btn[LV_BTN_STATE_TGL_REL];
|
||||
break;
|
||||
case LV_LIST_STYLE_BTN_TGL_PR:
|
||||
style = ext->styles_btn[LV_BTN_STATE_TGL_PR];
|
||||
break;
|
||||
case LV_LIST_STYLE_BTN_INA:
|
||||
style = ext->styles_btn[LV_BTN_STATE_INA];
|
||||
break;
|
||||
default:
|
||||
style = NULL;
|
||||
break;
|
||||
case LV_LIST_STYLE_BG: style = lv_page_get_style(list, LV_PAGE_STYLE_BG); break;
|
||||
case LV_LIST_STYLE_SCRL: style = lv_page_get_style(list, LV_PAGE_STYLE_SB); break;
|
||||
case LV_LIST_STYLE_SB: style = lv_page_get_style(list, LV_PAGE_STYLE_SCRL); break;
|
||||
case LV_LIST_STYLE_EDGE_FLASH:
|
||||
style = lv_page_get_style(list, LV_PAGE_STYLE_EDGE_FLASH);
|
||||
break;
|
||||
case LV_LIST_STYLE_BTN_REL: style = ext->styles_btn[LV_BTN_STATE_REL]; break;
|
||||
case LV_LIST_STYLE_BTN_PR: style = ext->styles_btn[LV_BTN_STATE_PR]; break;
|
||||
case LV_LIST_STYLE_BTN_TGL_REL: style = ext->styles_btn[LV_BTN_STATE_TGL_REL]; break;
|
||||
case LV_LIST_STYLE_BTN_TGL_PR: style = ext->styles_btn[LV_BTN_STATE_TGL_PR]; break;
|
||||
case LV_LIST_STYLE_BTN_INA: style = ext->styles_btn[LV_BTN_STATE_INA]; break;
|
||||
default: style = NULL; break;
|
||||
}
|
||||
|
||||
return style;
|
||||
@ -625,29 +608,30 @@ void lv_list_up(const lv_obj_t * list)
|
||||
lv_obj_t * scrl = lv_page_get_scrl(list);
|
||||
lv_obj_t * e;
|
||||
lv_obj_t * e_prev = NULL;
|
||||
e = lv_list_get_prev_btn(list, NULL);
|
||||
e = lv_list_get_prev_btn(list, NULL);
|
||||
while(e != NULL) {
|
||||
if(e->coords.y2 <= list->coords.y2) {
|
||||
if(e_prev != NULL) {
|
||||
lv_coord_t new_y = lv_obj_get_height(list) - (lv_obj_get_y(e_prev) + lv_obj_get_height(e_prev));
|
||||
lv_coord_t new_y =
|
||||
lv_obj_get_height(list) - (lv_obj_get_y(e_prev) + lv_obj_get_height(e_prev));
|
||||
lv_list_ext_t * ext = lv_obj_get_ext_attr(list);
|
||||
if(ext->anim_time == 0) {
|
||||
lv_obj_set_y(scrl, new_y);
|
||||
} else {
|
||||
#if LV_USE_ANIMATION
|
||||
lv_anim_t a;
|
||||
a.var = scrl;
|
||||
a.start = lv_obj_get_y(scrl);
|
||||
a.end = new_y;
|
||||
a.fp = (lv_anim_fp_t)lv_obj_set_y;
|
||||
a.path = lv_anim_path_linear;
|
||||
a.end_cb = NULL;
|
||||
a.act_time = 0;
|
||||
a.time = LV_LIST_DEF_ANIM_TIME;
|
||||
a.playback = 0;
|
||||
a.var = scrl;
|
||||
a.start = lv_obj_get_y(scrl);
|
||||
a.end = new_y;
|
||||
a.fp = (lv_anim_fp_t)lv_obj_set_y;
|
||||
a.path = lv_anim_path_linear;
|
||||
a.end_cb = NULL;
|
||||
a.act_time = 0;
|
||||
a.time = LV_LIST_DEF_ANIM_TIME;
|
||||
a.playback = 0;
|
||||
a.playback_pause = 0;
|
||||
a.repeat = 0;
|
||||
a.repeat_pause = 0;
|
||||
a.repeat = 0;
|
||||
a.repeat_pause = 0;
|
||||
lv_anim_create(&a);
|
||||
#endif
|
||||
}
|
||||
@ -655,7 +639,7 @@ void lv_list_up(const lv_obj_t * list)
|
||||
break;
|
||||
}
|
||||
e_prev = e;
|
||||
e = lv_list_get_prev_btn(list, e);
|
||||
e = lv_list_get_prev_btn(list, e);
|
||||
}
|
||||
}
|
||||
|
||||
@ -672,25 +656,25 @@ void lv_list_down(const lv_obj_t * list)
|
||||
e = lv_list_get_prev_btn(list, NULL);
|
||||
while(e != NULL) {
|
||||
if(e->coords.y1 < list->coords.y1) {
|
||||
lv_coord_t new_y = -lv_obj_get_y(e);
|
||||
lv_coord_t new_y = -lv_obj_get_y(e);
|
||||
lv_list_ext_t * ext = lv_obj_get_ext_attr(list);
|
||||
if(ext->anim_time == 0) {
|
||||
lv_obj_set_y(scrl, new_y);
|
||||
} else {
|
||||
#if LV_USE_ANIMATION
|
||||
lv_anim_t a;
|
||||
a.var = scrl;
|
||||
a.start = lv_obj_get_y(scrl);
|
||||
a.end = new_y;
|
||||
a.fp = (lv_anim_fp_t)lv_obj_set_y;
|
||||
a.path = lv_anim_path_linear;
|
||||
a.end_cb = NULL;
|
||||
a.act_time = 0;
|
||||
a.time = LV_LIST_DEF_ANIM_TIME;
|
||||
a.playback = 0;
|
||||
a.var = scrl;
|
||||
a.start = lv_obj_get_y(scrl);
|
||||
a.end = new_y;
|
||||
a.fp = (lv_anim_fp_t)lv_obj_set_y;
|
||||
a.path = lv_anim_path_linear;
|
||||
a.end_cb = NULL;
|
||||
a.act_time = 0;
|
||||
a.time = LV_LIST_DEF_ANIM_TIME;
|
||||
a.playback = 0;
|
||||
a.playback_pause = 0;
|
||||
a.repeat = 0;
|
||||
a.repeat_pause = 0;
|
||||
a.repeat = 0;
|
||||
a.repeat_pause = 0;
|
||||
lv_anim_create(&a);
|
||||
|
||||
#endif
|
||||
@ -737,21 +721,16 @@ static lv_res_t lv_list_signal(lv_obj_t * list, lv_signal_t sign, void * param)
|
||||
res = ancestor_page_signal(list, sign, param);
|
||||
if(res != LV_RES_OK) return res;
|
||||
|
||||
if(sign == LV_SIGNAL_RELEASED ||
|
||||
sign == LV_SIGNAL_PRESSED ||
|
||||
sign == LV_SIGNAL_PRESSING ||
|
||||
sign == LV_SIGNAL_LONG_PRESS ||
|
||||
sign == LV_SIGNAL_LONG_PRESS_REP)
|
||||
{
|
||||
if(sign == LV_SIGNAL_RELEASED || sign == LV_SIGNAL_PRESSED || sign == LV_SIGNAL_PRESSING ||
|
||||
sign == LV_SIGNAL_LONG_PRESS || sign == LV_SIGNAL_LONG_PRESS_REP) {
|
||||
/*If pressed/released etc by a KEYPAD or ENCODER delegate signal to the button*/
|
||||
lv_indev_t * indev = lv_indev_get_act();
|
||||
lv_indev_t * indev = lv_indev_get_act();
|
||||
lv_indev_type_t indev_type = lv_indev_get_type(indev);
|
||||
if(indev_type == LV_INDEV_TYPE_KEYPAD ||
|
||||
(indev_type == LV_INDEV_TYPE_ENCODER && lv_group_get_editing(lv_obj_get_group(list))))
|
||||
{
|
||||
(indev_type == LV_INDEV_TYPE_ENCODER && lv_group_get_editing(lv_obj_get_group(list)))) {
|
||||
/*Get the 'pressed' button*/
|
||||
lv_obj_t * btn = NULL;
|
||||
btn = lv_list_get_prev_btn(list, btn);
|
||||
btn = lv_list_get_prev_btn(list, btn);
|
||||
while(btn != NULL) {
|
||||
if(lv_btn_get_state(btn) == LV_BTN_STATE_PR) break;
|
||||
btn = lv_list_get_prev_btn(list, btn);
|
||||
@ -762,26 +741,23 @@ static lv_res_t lv_list_signal(lv_obj_t * list, lv_signal_t sign, void * param)
|
||||
bool drag = lv_indev_is_dragging(lv_indev_get_act());
|
||||
if(sign == LV_SIGNAL_PRESSED) {
|
||||
lv_event_send(btn, LV_EVENT_PRESSED, NULL);
|
||||
}
|
||||
else if(sign == LV_SIGNAL_PRESSING) {
|
||||
} else if(sign == LV_SIGNAL_PRESSING) {
|
||||
lv_event_send(btn, LV_EVENT_PRESSING, NULL);
|
||||
}
|
||||
else if(sign == LV_SIGNAL_LONG_PRESS && !drag) {
|
||||
} else if(sign == LV_SIGNAL_LONG_PRESS && !drag) {
|
||||
lv_event_send(btn, LV_EVENT_LONG_PRESSED, NULL);
|
||||
}
|
||||
else if(sign == LV_SIGNAL_LONG_PRESS_REP && !drag) {
|
||||
} else if(sign == LV_SIGNAL_LONG_PRESS_REP && !drag) {
|
||||
lv_event_send(btn, LV_EVENT_LONG_PRESSED_REPEAT, NULL);
|
||||
}
|
||||
else if(sign == LV_SIGNAL_RELEASED && !drag) {
|
||||
} else if(sign == LV_SIGNAL_RELEASED && !drag) {
|
||||
ext->last_sel = btn;
|
||||
if(indev->proc.long_pr_sent == 0) lv_event_send(btn, LV_EVENT_SHORT_CLICKED, NULL);
|
||||
if(lv_indev_is_dragging(indev) == false) lv_event_send(btn, LV_EVENT_CLICKED, NULL);
|
||||
if(indev->proc.long_pr_sent == 0)
|
||||
lv_event_send(btn, LV_EVENT_SHORT_CLICKED, NULL);
|
||||
if(lv_indev_is_dragging(indev) == false)
|
||||
lv_event_send(btn, LV_EVENT_CLICKED, NULL);
|
||||
lv_event_send(btn, LV_EVENT_RELEASED, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(sign == LV_SIGNAL_FOCUS) {
|
||||
} else if(sign == LV_SIGNAL_FOCUS) {
|
||||
|
||||
#if LV_USE_GROUP
|
||||
lv_indev_type_t indev_type = lv_indev_get_type(lv_indev_get_act());
|
||||
@ -793,8 +769,7 @@ static lv_res_t lv_list_signal(lv_obj_t * list, lv_signal_t sign, void * param)
|
||||
if(ext->last_sel) {
|
||||
/* Select the last used button */
|
||||
lv_list_set_btn_selected(list, ext->last_sel);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
/*Get the first button and mark it as selected*/
|
||||
lv_list_set_btn_selected(list, lv_list_get_next_btn(list, NULL));
|
||||
}
|
||||
@ -812,8 +787,7 @@ static lv_res_t lv_list_signal(lv_obj_t * list, lv_signal_t sign, void * param)
|
||||
if(ext->last_sel) {
|
||||
/* Select the last used button */
|
||||
lv_list_set_btn_selected(list, ext->last_sel);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
/*Get the first button and mark it as selected*/
|
||||
lv_list_set_btn_selected(list, lv_list_get_next_btn(list, NULL));
|
||||
}
|
||||
@ -825,13 +799,13 @@ static lv_res_t lv_list_signal(lv_obj_t * list, lv_signal_t sign, void * param)
|
||||
#if LV_USE_GROUP
|
||||
/*De-select the selected btn*/
|
||||
lv_list_set_btn_selected(list, NULL);
|
||||
last_clicked_btn = NULL; /*button click will be set if click happens before focus*/
|
||||
last_clicked_btn = NULL; /*button click will be set if click happens before focus*/
|
||||
lv_list_ext_t * ext = lv_obj_get_ext_attr(list);
|
||||
ext->selected_btn = NULL;
|
||||
ext->selected_btn = NULL;
|
||||
#endif
|
||||
} else if(sign == LV_SIGNAL_GET_EDITABLE) {
|
||||
bool * editable = (bool *)param;
|
||||
*editable = true;
|
||||
*editable = true;
|
||||
} else if(sign == LV_SIGNAL_CONTROL) {
|
||||
|
||||
#if LV_USE_GROUP
|
||||
@ -846,7 +820,10 @@ static lv_res_t lv_list_signal(lv_obj_t * list, lv_signal_t sign, void * param)
|
||||
/*If there is no selected button the make the first selected*/
|
||||
else {
|
||||
lv_obj_t * btn = lv_list_get_next_btn(list, NULL);
|
||||
if(btn) lv_list_set_btn_selected(list, btn); /*If there are no buttons on the list then there is no first button*/
|
||||
if(btn)
|
||||
lv_list_set_btn_selected(
|
||||
list,
|
||||
btn); /*If there are no buttons on the list then there is no first button*/
|
||||
}
|
||||
} else if(c == LV_GROUP_KEY_LEFT || c == LV_GROUP_KEY_UP) {
|
||||
lv_list_ext_t * ext = lv_obj_get_ext_attr(list);
|
||||
@ -865,7 +842,7 @@ static lv_res_t lv_list_signal(lv_obj_t * list, lv_signal_t sign, void * param)
|
||||
} else if(sign == LV_SIGNAL_GET_TYPE) {
|
||||
lv_obj_type_t * buf = param;
|
||||
uint8_t i;
|
||||
for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/
|
||||
for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/
|
||||
if(buf->type[i] == NULL) break;
|
||||
}
|
||||
buf->type[i] = "lv_list";
|
||||
@ -873,7 +850,6 @@ static lv_res_t lv_list_signal(lv_obj_t * list, lv_signal_t sign, void * param)
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Signal function of the list buttons
|
||||
* @param btn pointer to a button on the list
|
||||
@ -890,8 +866,8 @@ static lv_res_t lv_list_btn_signal(lv_obj_t * btn, lv_signal_t sign, void * para
|
||||
if(res != LV_RES_OK) return res;
|
||||
|
||||
if(sign == LV_SIGNAL_RELEASED) {
|
||||
lv_obj_t * list = lv_obj_get_parent(lv_obj_get_parent(btn));
|
||||
lv_list_ext_t * ext = lv_obj_get_ext_attr(list);
|
||||
lv_obj_t * list = lv_obj_get_parent(lv_obj_get_parent(btn));
|
||||
lv_list_ext_t * ext = lv_obj_get_ext_attr(list);
|
||||
ext->page.scroll_prop_ip = 0;
|
||||
|
||||
#if LV_USE_GROUP
|
||||
@ -902,8 +878,10 @@ static lv_res_t lv_list_btn_signal(lv_obj_t * btn, lv_signal_t sign, void * para
|
||||
lv_obj_t * btn_i = lv_list_get_prev_btn(list, NULL);
|
||||
while(btn_i) {
|
||||
lv_btn_state_t s = lv_btn_get_state(btn_i);
|
||||
if(s == LV_BTN_STATE_PR) lv_btn_set_state(btn_i, LV_BTN_STATE_REL);
|
||||
else if(s == LV_BTN_STATE_TGL_PR) lv_btn_set_state(btn_i, LV_BTN_STATE_TGL_REL);
|
||||
if(s == LV_BTN_STATE_PR)
|
||||
lv_btn_set_state(btn_i, LV_BTN_STATE_REL);
|
||||
else if(s == LV_BTN_STATE_TGL_PR)
|
||||
lv_btn_set_state(btn_i, LV_BTN_STATE_TGL_REL);
|
||||
btn_i = lv_list_get_prev_btn(list, btn_i);
|
||||
}
|
||||
|
||||
@ -915,50 +893,43 @@ static lv_res_t lv_list_btn_signal(lv_obj_t * btn, lv_signal_t sign, void * para
|
||||
* to mark it as selected (pressed state)*/
|
||||
last_clicked_btn = btn;
|
||||
#endif
|
||||
if(lv_indev_is_dragging(lv_indev_get_act()) == false && ext->single_mode)
|
||||
{
|
||||
if(lv_indev_is_dragging(lv_indev_get_act()) == false && ext->single_mode) {
|
||||
lv_list_btn_single_selected(btn);
|
||||
}
|
||||
}
|
||||
else if(sign == LV_SIGNAL_PRESS_LOST) {
|
||||
lv_obj_t * list = lv_obj_get_parent(lv_obj_get_parent(btn));
|
||||
lv_list_ext_t * ext = lv_obj_get_ext_attr(list);
|
||||
} else if(sign == LV_SIGNAL_PRESS_LOST) {
|
||||
lv_obj_t * list = lv_obj_get_parent(lv_obj_get_parent(btn));
|
||||
lv_list_ext_t * ext = lv_obj_get_ext_attr(list);
|
||||
ext->page.scroll_prop_ip = 0;
|
||||
}
|
||||
else if(sign == LV_SIGNAL_CLEANUP) {
|
||||
} else if(sign == LV_SIGNAL_CLEANUP) {
|
||||
|
||||
#if LV_USE_GROUP
|
||||
lv_obj_t * list = lv_obj_get_parent(lv_obj_get_parent(btn));
|
||||
lv_obj_t * sel = lv_list_get_btn_selected(list);
|
||||
lv_obj_t * sel = lv_list_get_btn_selected(list);
|
||||
if(sel == btn) lv_list_set_btn_selected(list, lv_list_get_next_btn(list, btn));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a single button selected in the list, deselect others, should be called in list btns call back.
|
||||
* Make a single button selected in the list, deselect others, should be called in list btns call
|
||||
* back.
|
||||
* @param btn pointer to the currently pressed list btn object
|
||||
*/
|
||||
static void lv_list_btn_single_selected(lv_obj_t *btn)
|
||||
static void lv_list_btn_single_selected(lv_obj_t * btn)
|
||||
{
|
||||
lv_obj_t *list = lv_obj_get_parent(lv_obj_get_parent(btn));
|
||||
lv_obj_t * list = lv_obj_get_parent(lv_obj_get_parent(btn));
|
||||
|
||||
lv_obj_t * e = lv_list_get_next_btn(list, NULL);
|
||||
do
|
||||
{
|
||||
if(e == btn)
|
||||
{
|
||||
do {
|
||||
if(e == btn) {
|
||||
lv_btn_set_state(e, LV_BTN_STATE_TGL_REL);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
lv_btn_set_state(e, LV_BTN_STATE_REL);
|
||||
}
|
||||
e = lv_list_get_next_btn(list, e);
|
||||
} while (e != NULL);
|
||||
} while(e != NULL);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -34,7 +34,6 @@ extern "C" {
|
||||
#error "lv_list: lv_label is required. Enable it in lv_conf.h (LV_USE_LABEL 1) "
|
||||
#endif
|
||||
|
||||
|
||||
#include "../lv_core/lv_obj.h"
|
||||
#include "lv_page.h"
|
||||
#include "lv_btn.h"
|
||||
@ -53,14 +52,15 @@ typedef struct
|
||||
{
|
||||
lv_page_ext_t page; /*Ext. of ancestor*/
|
||||
/*New data for this type */
|
||||
uint16_t anim_time; /*Scroll animation time*/
|
||||
lv_style_t *styles_btn[LV_BTN_STATE_NUM]; /*Styles of the list element buttons*/
|
||||
lv_style_t *style_img; /*Style of the list element images on buttons*/
|
||||
uint32_t size; /*the number of items(buttons) in the list*/
|
||||
bool single_mode; /* whether single selected mode is enabled */
|
||||
uint16_t anim_time; /*Scroll animation time*/
|
||||
lv_style_t * styles_btn[LV_BTN_STATE_NUM]; /*Styles of the list element buttons*/
|
||||
lv_style_t * style_img; /*Style of the list element images on buttons*/
|
||||
uint32_t size; /*the number of items(buttons) in the list*/
|
||||
bool single_mode; /* whether single selected mode is enabled */
|
||||
#if LV_USE_GROUP
|
||||
lv_obj_t * last_sel; /* The last selected button. It will be reverted when the list is focused again */
|
||||
lv_obj_t * selected_btn; /* The button is currently being selected*/
|
||||
lv_obj_t *
|
||||
last_sel; /* The last selected button. It will be reverted when the list is focused again */
|
||||
lv_obj_t * selected_btn; /* The button is currently being selected*/
|
||||
#endif
|
||||
} lv_list_ext_t;
|
||||
|
||||
@ -77,7 +77,6 @@ enum {
|
||||
};
|
||||
typedef uint8_t lv_list_style_t;
|
||||
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
@ -94,7 +93,7 @@ lv_obj_t * lv_list_create(lv_obj_t * par, const lv_obj_t * copy);
|
||||
* Delete all children of the scrl object, without deleting scrl child.
|
||||
* @param obj pointer to an object
|
||||
*/
|
||||
void lv_list_clean(lv_obj_t *obj);
|
||||
void lv_list_clean(lv_obj_t * obj);
|
||||
|
||||
/*======================
|
||||
* Add/remove functions
|
||||
@ -108,12 +107,14 @@ void lv_list_clean(lv_obj_t *obj);
|
||||
* @param event_cb specify the an event handler function. NULL if unused
|
||||
* @return pointer to the new list element which can be customized (a button)
|
||||
*/
|
||||
lv_obj_t * lv_list_add(lv_obj_t * list, const void * img_src, const char * txt, lv_event_cb_t event_cb);
|
||||
lv_obj_t * lv_list_add(lv_obj_t * list, const void * img_src, const char * txt,
|
||||
lv_event_cb_t event_cb);
|
||||
|
||||
/**
|
||||
* Remove the index of the button in the list
|
||||
* @param list pointer to a list object
|
||||
* @param index pointer to a the button's index in the list, index must be 0 <= index < lv_list_ext_t.size
|
||||
* @param index pointer to a the button's index in the list, index must be 0 <= index <
|
||||
* lv_list_ext_t.size
|
||||
* @return true: successfully deleted
|
||||
*/
|
||||
bool lv_list_remove(const lv_obj_t * list, uint32_t index);
|
||||
@ -121,14 +122,14 @@ bool lv_list_remove(const lv_obj_t * list, uint32_t index);
|
||||
/*=====================
|
||||
* Setter functions
|
||||
*====================*/
|
||||
|
||||
|
||||
/**
|
||||
* Set single button selected mode, only one button will be selected if enabled.
|
||||
* @param list pointer to the currently pressed list object
|
||||
* @param mode, enable(true)/disable(false) single selected mode.
|
||||
*/
|
||||
void lv_list_set_single_mode(lv_obj_t *list, bool mode);
|
||||
|
||||
void lv_list_set_single_mode(lv_obj_t * list, bool mode);
|
||||
|
||||
#if LV_USE_GROUP
|
||||
|
||||
/**
|
||||
@ -144,7 +145,7 @@ void lv_list_set_btn_selected(lv_obj_t * list, lv_obj_t * btn);
|
||||
* @param list pointer to a list object
|
||||
* @param anim_time duration of animation [ms]
|
||||
*/
|
||||
void lv_list_set_anim_time(lv_obj_t *list, uint16_t anim_time);
|
||||
void lv_list_set_anim_time(lv_obj_t * list, uint16_t anim_time);
|
||||
|
||||
/**
|
||||
* Set the scroll bar mode of a list
|
||||
@ -157,7 +158,8 @@ static inline void lv_list_set_sb_mode(lv_obj_t * list, lv_sb_mode_t mode)
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable the scroll propagation feature. If enabled then the List will move its parent if there is no more space to scroll.
|
||||
* Enable the scroll propagation feature. If enabled then the List will move its parent if there is
|
||||
* no more space to scroll.
|
||||
* @param list pointer to a List
|
||||
* @param en true or false to enable/disable scroll propagation
|
||||
*/
|
||||
@ -182,7 +184,7 @@ static inline void lv_list_set_edge_flash(lv_obj_t * list, bool en)
|
||||
* @param type which style should be set
|
||||
* @param style pointer to a style
|
||||
*/
|
||||
void lv_list_set_style(lv_obj_t *list, lv_list_style_t type, lv_style_t *style);
|
||||
void lv_list_set_style(lv_obj_t * list, lv_list_style_t type, lv_style_t * style);
|
||||
|
||||
/*=====================
|
||||
* Getter functions
|
||||
@ -192,8 +194,8 @@ void lv_list_set_style(lv_obj_t *list, lv_list_style_t type, lv_style_t *style);
|
||||
* Get single button selected mode.
|
||||
* @param list pointer to the currently pressed list object.
|
||||
*/
|
||||
bool lv_list_get_single_mode(lv_obj_t *list);
|
||||
|
||||
bool lv_list_get_single_mode(lv_obj_t * list);
|
||||
|
||||
/**
|
||||
* Get the text of a list element
|
||||
* @param btn pointer to list element
|
||||
@ -254,14 +256,12 @@ uint32_t lv_list_get_size(const lv_obj_t * list);
|
||||
lv_obj_t * lv_list_get_btn_selected(const lv_obj_t * list);
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* Get scroll animation duration
|
||||
* @param list pointer to a list object
|
||||
* @return duration of animation [ms]
|
||||
*/
|
||||
uint16_t lv_list_get_anim_time(const lv_obj_t *list);
|
||||
|
||||
uint16_t lv_list_get_anim_time(const lv_obj_t * list);
|
||||
|
||||
/**
|
||||
* Get the scroll bar mode of a list
|
||||
@ -299,7 +299,7 @@ static inline bool lv_list_get_edge_flash(lv_obj_t * list)
|
||||
* @param type which style should be get
|
||||
* @return style pointer to a style
|
||||
* */
|
||||
lv_style_t * lv_list_get_style(const lv_obj_t *list, lv_list_style_t type);
|
||||
lv_style_t * lv_list_get_style(const lv_obj_t * list, lv_list_style_t type);
|
||||
|
||||
/*=====================
|
||||
* Other functions
|
||||
@ -321,16 +321,16 @@ void lv_list_down(const lv_obj_t * list);
|
||||
* @param btn pointer to a list button to focus
|
||||
* @param anim_en true: scroll with animation, false: without animation
|
||||
*/
|
||||
void lv_list_focus(const lv_obj_t *btn, bool anim_en);
|
||||
void lv_list_focus(const lv_obj_t * btn, bool anim_en);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_LIST*/
|
||||
#endif /*LV_USE_LIST*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_LIST_H*/
|
||||
#endif /*LV_LIST_H*/
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user