rework checkbox

now it has no real parts, the bullet and text are drawn on the fly
This commit is contained in:
Gabor Kiss-Vamosi
2020-09-15 15:38:18 +02:00
parent fceb1177cd
commit 25691a4d94
15 changed files with 253 additions and 134 deletions

View File

@@ -143,8 +143,6 @@ void _lv_grid_full_refresh(lv_obj_t * cont);
void lv_grid_item_refr_pos(lv_obj_t * item);
bool _lv_obj_is_grid_item(lv_obj_t * obj);
/**********************
* GLOBAL VARIABLES

View File

@@ -848,7 +848,7 @@ static void indev_proc_press(lv_indev_proc_t * proc)
}
/*Do not use disabled objects*/
if(indev_obj_act && (lv_obj_get_state(indev_obj_act, LV_OBJ_PART_MAIN) & LV_STATE_DISABLED)) {
if(indev_obj_act && (lv_obj_get_state(indev_obj_act) & LV_STATE_DISABLED)) {
indev_obj_act = proc->types.pointer.act_obj;
}

View File

@@ -185,7 +185,7 @@ void lv_deinit(void)
* Pointer to an other base object to copy.
* @return pointer to the new object
*/
lv_obj_t * lv_obj_create(lv_obj_t * parent, 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;
@@ -775,10 +775,9 @@ void lv_obj_set_state(lv_obj_t * obj, lv_state_t new_state)
}
}
if(cmp_res == _LV_STYLE_STATE_CMP_DIFF) _lv_obj_refresh_style(obj, part, LV_STYLE_PROP_ALL);
}
if(cmp_res == _LV_STYLE_STATE_CMP_VISUAL_DIFF) lv_obj_invalidate(obj);
if(cmp_res == _LV_STYLE_STATE_CMP_DIFF) _lv_obj_refresh_style(obj, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL);
else if(cmp_res == _LV_STYLE_STATE_CMP_VISUAL_DIFF) lv_obj_invalidate(obj);
#endif
@@ -1292,7 +1291,7 @@ lv_bidi_dir_t lv_obj_get_base_dir(const lv_obj_t * obj)
#endif
}
lv_state_t lv_obj_get_state(const lv_obj_t * obj, uint8_t part)
lv_state_t lv_obj_get_state(const lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
@@ -1815,7 +1814,7 @@ static lv_res_t lv_obj_signal(lv_obj_t * obj, lv_signal_t sign, void * param)
/*Go the checked state if enabled*/
if(lv_indev_get_scroll_obj(param) == NULL && lv_obj_has_flag(obj, LV_OBJ_FLAG_CHECKABLE)) {
uint32_t toggled = 0;
if(!(lv_obj_get_state(obj, LV_OBJ_PART_MAIN) & LV_STATE_CHECKED)) {
if(!(lv_obj_get_state(obj) & LV_STATE_CHECKED)) {
lv_obj_add_state(obj, LV_STATE_CHECKED);
toggled = 0;
}
@@ -1880,8 +1879,8 @@ static lv_res_t lv_obj_signal(lv_obj_t * obj, lv_signal_t sign, void * param)
lv_obj_clear_state(obj, LV_STATE_FOCUSED | LV_STATE_EDITED);
}
else if(sign == LV_SIGNAL_COORD_CHG) {
if((lv_area_get_width(param) != lv_obj_get_width(obj) && _lv_grid_has_fr_col(obj)) ||
(lv_area_get_height(param) != lv_obj_get_height(obj) && _lv_grid_has_fr_row(obj)))
if(param && ((lv_area_get_width(param) != lv_obj_get_width(obj) && _lv_grid_has_fr_col(obj)) ||
(lv_area_get_height(param) != lv_obj_get_height(obj) && _lv_grid_has_fr_row(obj))))
{
_lv_grid_full_refresh(obj);
}

View File

@@ -130,6 +130,7 @@ enum {
LV_SIGNAL_REFR_EXT_DRAW_PAD, /**< Object's extra padding has changed */
LV_SIGNAL_GET_TYPE, /**< LVGL needs to retrieve the object's type */
LV_SIGNAL_GET_STYLE, /**< Get the style of an object*/
LV_SIGNAL_GET_SELF_SIZE, /**< If there are virtual content on the widget get it's size*/
/*Input device related*/
LV_SIGNAL_HIT_TEST, /**< Advanced hit-testing */
@@ -313,7 +314,7 @@ void lv_deinit(void);
* Pointer to an other base object to copy.
* @return pointer to the new object
*/
lv_obj_t * lv_obj_create(lv_obj_t * parent, 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
@@ -644,7 +645,7 @@ bool lv_obj_has_flag(const lv_obj_t * obj, lv_obj_flag_t f);
lv_bidi_dir_t lv_obj_get_base_dir(const lv_obj_t * obj);
lv_state_t lv_obj_get_state(const lv_obj_t * obj, uint8_t part);
lv_state_t lv_obj_get_state(const lv_obj_t * obj);
/**
* Get the signal function of an object

View File

@@ -402,16 +402,6 @@ void _lv_obj_draw_scrollbar(lv_obj_t * obj, const lv_area_t * clip_area)
return;
}
lv_coord_t st = lv_obj_get_scroll_top(obj);
lv_coord_t sb = lv_obj_get_scroll_bottom(obj);
lv_coord_t sl = lv_obj_get_scroll_left(obj);
lv_coord_t sr = lv_obj_get_scroll_right(obj);
/*Return if too small content to scroll*/
if(sm == LV_SCROLL_MODE_AUTO && st <= 0 && sb <= 0 && sl <= 0 && sr <= 0) {
return;
}
/*If there is no indev scrolling this object but the moe is active return*/
lv_indev_t * indev = lv_indev_get_next(NULL);
if(sm == LV_SCROLL_MODE_ACTIVE) {
@@ -428,6 +418,16 @@ void _lv_obj_draw_scrollbar(lv_obj_t * obj, const lv_area_t * clip_area)
}
}
lv_coord_t st = lv_obj_get_scroll_top(obj);
lv_coord_t sb = lv_obj_get_scroll_bottom(obj);
lv_coord_t sl = lv_obj_get_scroll_left(obj);
lv_coord_t sr = lv_obj_get_scroll_right(obj);
/*Return if too small content to scroll*/
if(sm == LV_SCROLL_MODE_AUTO && st <= 0 && sb <= 0 && sl <= 0 && sr <= 0) {
return;
}
lv_coord_t end_space = lv_obj_get_style_scrollbar_space_end(obj, LV_OBJ_PART_MAIN);
lv_coord_t side_space = lv_obj_get_style_scrollbar_space_side(obj, LV_OBJ_PART_MAIN);
lv_coord_t tickness = lv_obj_get_style_scrollbar_tickness(obj, LV_OBJ_PART_MAIN);

View File

@@ -441,7 +441,7 @@ lv_coord_t lv_obj_get_width_margin(lv_obj_t * obj)
}
/**
* Calculate the "auto size". It's `auto_size = max(gird_size, children_size)`
* Calculate the "auto size". It's `auto_size = max(gird_size, children_size, self_size)`
* @param obj pointer to an object
* @param w_out store the width here. NULL to not calculate width
* @param h_out store the height here. NULL to not calculate height
@@ -473,16 +473,17 @@ void _lv_obj_calc_auto_size(lv_obj_t * obj, lv_coord_t * w_out, lv_coord_t * h_o
if(w_out) {
lv_obj_scroll_to_x(obj, 0, LV_ANIM_OFF);
lv_coord_t scroll_right = lv_obj_get_scroll_right(obj);
children_w = lv_obj_get_width(obj) + scroll_right;
lv_coord_t scroll_left = lv_obj_get_scroll_left(obj);
children_w = lv_obj_get_width(obj) + scroll_right + scroll_left;
}
if(h_out) {
lv_obj_scroll_to_y(obj, 0, LV_ANIM_OFF);
lv_coord_t scroll_bottom = lv_obj_get_scroll_bottom(obj);
children_h = lv_obj_get_height(obj) + scroll_bottom;
lv_coord_t scroll_top = lv_obj_get_scroll_top(obj);
children_h = lv_obj_get_height(obj) + scroll_bottom + scroll_top ;
}
/*auto_size = max(gird_size, children_size)*/
if(w_out) *w_out = LV_MATH_MAX(children_w, grid_w);
if(h_out) *h_out = LV_MATH_MAX(children_h, grid_h);
@@ -585,6 +586,18 @@ bool _lv_obj_is_grid_item(lv_obj_t * obj)
return false;
}
/**
* Get the size of the virtual content on an object
* (E.g. some texts which are "just drawn" and there is not real object behind them)
* @param obj pointer to an object
* @param p store the result size here
*/
void _lv_obj_get_self_size(lv_obj_t * obj, lv_point_t * p)
{
p->x = 0;
p->y = 0;
lv_signal_send(obj, LV_SIGNAL_GET_SELF_SIZE, p);
}
/**********************
* STATIC FUNCTIONS
@@ -613,7 +626,8 @@ static bool refr_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
* Be sure the content is not scrolled in an invalid position on the new size*/
obj->coords.y2 = obj->coords.y1 + h - 1;
if(lv_obj_get_base_dir(obj) == LV_BIDI_DIR_RTL) {
obj->coords.x1 = obj->coords.x2 - w + 1;

View File

@@ -230,6 +230,15 @@ void _lv_obj_move_children_by(struct _lv_obj_t * obj, lv_coord_t x_diff, lv_coor
* @return true: grid item; false: not grid item
*/
bool _lv_obj_is_grid_item(struct _lv_obj_t * obj);
/**
* Get the size of the virtual content on an object
* (E.g. some texts which are "just drawn" and there is not real object behind them)
* @param obj pointer to an object
* @param p store the result size here
*/
void _lv_obj_get_self_size(lv_obj_t * obj, lv_point_t * p);
/**********************
* MACROS
**********************/

View File

@@ -183,17 +183,26 @@ lv_coord_t lv_obj_get_scroll_bottom(const lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
lv_coord_t y2 = LV_COORD_MIN;
lv_coord_t child_res = LV_COORD_MIN;
lv_obj_t * child = lv_obj_get_child(obj, NULL);
if(child == NULL) return 0;
if(child) {
lv_coord_t y2 = LV_COORD_MIN;
while(child) {
y2 = LV_MATH_MAX(y2, child->coords.y2 + lv_obj_get_style_margin_bottom(child, LV_OBJ_PART_MAIN));
child = lv_obj_get_child(obj, child);
}
return y2 - (obj->coords.y2 - lv_obj_get_style_pad_bottom(obj, LV_OBJ_PART_MAIN));
child_res = y2;
}
lv_point_t self_size;
_lv_obj_get_self_size(obj, &self_size);
self_size.y += obj->coords.y1 + lv_obj_get_style_pad_top(obj, LV_OBJ_PART_MAIN) + obj->scroll.y;
lv_coord_t y_max = LV_MATH_MAX(child_res, self_size.y) - obj->coords.y2;
return y_max + lv_obj_get_style_pad_bottom(obj, LV_OBJ_PART_MAIN);
}
/**
@@ -217,19 +226,30 @@ lv_coord_t lv_obj_get_scroll_left(const lv_obj_t * obj)
*/
lv_coord_t lv_obj_get_scroll_right(const lv_obj_t * obj)
{
static uint32_t cnt = 0;
printf("scrl right: %d\n", cnt);
cnt++;
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
lv_coord_t x2 = LV_COORD_MIN;
lv_coord_t child_res = LV_COORD_MIN;
lv_obj_t * child = lv_obj_get_child(obj, NULL);
if(child == NULL) return 0;
if(child) {
lv_coord_t x2 = LV_COORD_MIN;
while(child) {
x2 = LV_MATH_MAX(x2, child->coords.x2 + lv_obj_get_style_margin_right(child, LV_OBJ_PART_MAIN));
child = lv_obj_get_child(obj, child);
}
child_res = x2;
return x2 - (obj->coords.x2 - lv_obj_get_style_pad_right(obj, LV_OBJ_PART_MAIN));
}
lv_point_t self_size;
_lv_obj_get_self_size(obj, &self_size);
self_size.x += obj->coords.x1 + lv_obj_get_style_pad_left(obj, LV_OBJ_PART_MAIN) + obj->scroll.x;
lv_coord_t x_max = LV_MATH_MAX(child_res, self_size.x) - obj->coords.x2;
return x_max + lv_obj_get_style_pad_right(obj, LV_OBJ_PART_MAIN);
}
/**********************

View File

@@ -409,7 +409,7 @@ lv_style_int_t _lv_obj_get_style_int(const lv_obj_t * obj, uint8_t part, lv_styl
}
#endif
lv_state_t state = lv_obj_get_state(parent, part);
lv_state_t state = lv_obj_get_state(parent);
prop = (uint16_t)prop_ori + ((uint16_t)state << LV_STYLE_STATE_POS);
res = _lv_style_list_get_int(list, prop, &value_act);
@@ -474,7 +474,7 @@ lv_color_t _lv_obj_get_style_color(const lv_obj_t * obj, uint8_t part, lv_style_
while(parent) {
lv_style_list_t * list = _lv_obj_get_style_list(parent, part);
lv_state_t state = lv_obj_get_state(parent, part);
lv_state_t state = lv_obj_get_state(parent);
prop = (uint16_t)prop_ori + ((uint16_t)state << LV_STYLE_STATE_POS);
res = _lv_style_list_get_color(list, prop, &value_act);
@@ -552,7 +552,7 @@ lv_opa_t _lv_obj_get_style_opa(const lv_obj_t * obj, uint8_t part, lv_style_prop
}
#endif
lv_state_t state = lv_obj_get_state(parent, part);
lv_state_t state = lv_obj_get_state(parent);
prop = (uint16_t)prop_ori + ((uint16_t)state << LV_STYLE_STATE_POS);
res = _lv_style_list_get_opa(list, prop, &value_act);
@@ -629,7 +629,7 @@ const void * _lv_obj_get_style_ptr(const lv_obj_t * obj, uint8_t part, lv_style_
}
}
#endif
lv_state_t state = lv_obj_get_state(parent, part);
lv_state_t state = lv_obj_get_state(parent);
prop = (uint16_t)prop_ori + ((uint16_t)state << LV_STYLE_STATE_POS);
res = _lv_style_list_get_ptr(list, prop, &value_act);
@@ -1279,7 +1279,7 @@ static _lv_style_state_cmp_t style_snapshot_compare(style_snapshot_t * shot1, st
if(shot1->pad_inner != shot2->pad_inner) return _LV_STYLE_STATE_CMP_DIFF;
if(shot1->margin_top != shot2->margin_top) return _LV_STYLE_STATE_CMP_DIFF;
if(shot1->margin_bottom != shot2->margin_bottom) return _LV_STYLE_STATE_CMP_DIFF;
if(shot1->margin_left != shot2->margin_right) return _LV_STYLE_STATE_CMP_DIFF;
if(shot1->margin_left != shot2->margin_left) return _LV_STYLE_STATE_CMP_DIFF;
if(shot1->margin_right != shot2->margin_right) return _LV_STYLE_STATE_CMP_DIFF;
if(shot1->margin_top != shot2->margin_top) return _LV_STYLE_STATE_CMP_DIFF;
if(shot1->transform_width != shot2->transform_width) return _LV_STYLE_STATE_CMP_DIFF;

View File

@@ -306,7 +306,7 @@ static void clear_styles(lv_obj_t * obj, lv_theme_style_t name)
#if LV_USE_CHECKBOX
case LV_THEME_CHECKBOX:
_lv_obj_reset_style_list_no_refr(obj, LV_CHECKBOX_PART_BG);
_lv_obj_reset_style_list_no_refr(obj, LV_CHECKBOX_PART_MAIN);
_lv_obj_reset_style_list_no_refr(obj, LV_CHECKBOX_PART_BULLET);
break;
#endif

View File

@@ -645,6 +645,7 @@ static void checkbox_init(void)
lv_style_set_pad_right(&styles->cb_bullet, LV_STATE_DEFAULT, LV_DPX(3));
lv_style_set_pad_top(&styles->cb_bullet, LV_STATE_DEFAULT, LV_DPX(3));
lv_style_set_pad_bottom(&styles->cb_bullet, LV_STATE_DEFAULT, LV_DPX(3));
lv_style_set_margin_right(&styles->cb_bullet, LV_STATE_DEFAULT, LV_DPX(6));
#endif
}
@@ -1107,7 +1108,7 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj, lv_theme_style_t name)
#if LV_USE_CHECKBOX
case LV_THEME_CHECKBOX:
list = _lv_obj_get_style_list(obj, LV_CHECKBOX_PART_BG);
list = _lv_obj_get_style_list(obj, LV_CHECKBOX_PART_MAIN);
_lv_style_list_add_style(list, &styles->cb_bg);
list = _lv_obj_get_style_list(obj, LV_CHECKBOX_PART_BULLET);

View File

@@ -717,7 +717,7 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj, lv_theme_style_t name)
#if LV_USE_CHECKBOX
case LV_THEME_CHECKBOX:
list = _lv_obj_get_style_list(obj, LV_CHECKBOX_PART_BG);
list = _lv_obj_get_style_list(obj, LV_CHECKBOX_PART_MAIN);
_lv_style_list_add_style(list, &styles->pad_small);
list = _lv_obj_get_style_list(obj, LV_CHECKBOX_PART_BULLET);

View File

@@ -563,7 +563,7 @@ void theme_apply(lv_theme_t * th, lv_obj_t * obj, lv_theme_style_t name)
#if LV_USE_CHECKBOX
case LV_THEME_CHECKBOX:
list = _lv_obj_get_style_list(obj, LV_CHECKBOX_PART_BG);
list = _lv_obj_get_style_list(obj, LV_CHECKBOX_PART_MAIN);
list = _lv_obj_get_style_list(obj, LV_CHECKBOX_PART_BULLET);
_lv_style_list_add_style(list, &styles->bg);

View File

@@ -25,6 +25,7 @@
/**********************
* STATIC PROTOTYPES
**********************/
static lv_design_res_t lv_checkbox_design(lv_obj_t * cb, const lv_area_t * clip_area, lv_design_mode_t mode);
static lv_res_t lv_checkbox_signal(lv_obj_t * cb, lv_signal_t sign, void * param);
static lv_style_list_t * lv_checkbox_get_style(lv_obj_t * cb, uint8_t type);
@@ -32,6 +33,7 @@ static lv_style_list_t * lv_checkbox_get_style(lv_obj_t * cb, uint8_t type);
* STATIC VARIABLES
**********************/
static lv_signal_cb_t ancestor_signal;
static lv_design_cb_t ancestor_design;
/**********************
* MACROS
@@ -52,11 +54,12 @@ lv_obj_t * lv_checkbox_create(lv_obj_t * par, const lv_obj_t * copy)
LV_LOG_TRACE("check box create started");
/*Create the ancestor basic object*/
lv_obj_t * cb = lv_btn_create(par, copy);
lv_obj_t * cb = lv_obj_create(par, copy);
LV_ASSERT_MEM(cb);
if(cb == NULL) return NULL;
if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(cb);
if(ancestor_design == NULL) ancestor_design = lv_obj_get_design_cb(cb);
lv_checkbox_ext_t * ext = lv_obj_allocate_ext_attr(cb, sizeof(lv_checkbox_ext_t));
LV_ASSERT_MEM(ext);
@@ -65,34 +68,33 @@ lv_obj_t * lv_checkbox_create(lv_obj_t * par, const lv_obj_t * copy)
return NULL;
}
ext->bullet = NULL;
ext->label = NULL;
ext->static_txt = 1;
ext->text = "Check box";
lv_style_list_init(&ext->style_bullet);
lv_obj_set_signal_cb(cb, lv_checkbox_signal);
lv_obj_set_design_cb(cb, lv_checkbox_design);
/*Init the new checkbox object*/
if(copy == NULL) {
ext->bullet = lv_obj_create(cb, NULL);
lv_obj_set_click(ext->bullet, false);
ext->label = lv_label_create(cb, NULL);
lv_checkbox_set_text(cb, "Check box");
lv_btn_set_layout(cb, LV_LAYOUT_ROW_MID);
lv_btn_set_fit(cb, LV_FIT_TIGHT);
lv_btn_set_checkable(cb, true);
lv_obj_add_protect(cb, LV_PROTECT_PRESS_LOST);
lv_theme_apply(cb, LV_THEME_CHECKBOX);
lv_obj_add_flag(cb, LV_OBJ_FLAG_CLICKABLE);
lv_obj_set_size(cb, LV_SIZE_AUTO, LV_SIZE_AUTO);
}
else {
lv_checkbox_ext_t * copy_ext = lv_obj_get_ext_attr(copy);
ext->bullet = lv_obj_create(cb, copy_ext->bullet);
ext->label = lv_label_create(cb, copy_ext->label);
lv_checkbox_ext_t * copy_ext = lv_obj_get_ext_attr(copy);
lv_style_list_copy(&ext->style_bullet, &copy_ext->style_bullet);
ext->static_txt = copy_ext->static_txt;
if(copy_ext->static_txt) ext->text = copy_ext->text;
else {
ext->text = lv_mem_alloc(strlen(copy_ext->text) + 1);
strcpy(ext->text, copy_ext->text);
}
/*Refresh the style with new signal function*/
// lv_obj_refresh_style(cb);
_lv_obj_refresh_style(cb, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL);
}
LV_LOG_INFO("check box created");
@@ -115,7 +117,16 @@ void lv_checkbox_set_text(lv_obj_t * cb, const char * txt)
LV_ASSERT_OBJ(cb, LV_OBJX_NAME);
lv_checkbox_ext_t * ext = lv_obj_get_ext_attr(cb);
lv_label_set_text(ext->label, txt);
if(ext->static_txt) {
ext->static_txt = 0;
ext->text = NULL;
}
ext->text = lv_mem_realloc(ext->text, strlen(txt) + 1);
strcpy(ext->text, txt);
lv_signal_send(cb, LV_SIGNAL_CHILD_CHG, NULL);
}
/**
@@ -129,7 +140,13 @@ void lv_checkbox_set_text_static(lv_obj_t * cb, const char * txt)
LV_ASSERT_OBJ(cb, LV_OBJX_NAME);
lv_checkbox_ext_t * ext = lv_obj_get_ext_attr(cb);
lv_label_set_text_static(ext->label, txt);
if(ext->static_txt == 0) {
ext->static_txt = 1;
lv_mem_free(ext->text);
ext->text = NULL;
}
ext->text = txt;
}
/*=====================
@@ -146,13 +163,85 @@ const char * lv_checkbox_get_text(const lv_obj_t * cb)
LV_ASSERT_OBJ(cb, LV_OBJX_NAME);
lv_checkbox_ext_t * ext = lv_obj_get_ext_attr(cb);
return lv_label_get_text(ext->label);
return ext->text;
}
/**********************
* STATIC FUNCTIONS
**********************/
/**
* Handle the drawing related tasks of the check box
* @param cb pointer to a check box object
* @param clip_area the object will be drawn only in this area
* @param mode LV_DESIGN_COVER_CHK: only check if the object fully covers the 'mask_p' area
* (return 'true' if yes)
* LV_DESIGN_DRAW: draw the object (always return 'true')
* LV_DESIGN_DRAW_POST: drawing after every children are drawn
* @param return an element of `lv_design_res_t`
*/
static lv_design_res_t lv_checkbox_design(lv_obj_t * cb, const lv_area_t * clip_area, lv_design_mode_t mode)
{
/* A label never covers an area */
if(mode == LV_DESIGN_COVER_CHK)
return LV_DESIGN_RES_NOT_COVER;
else if(mode == LV_DESIGN_DRAW_MAIN) {
/*Draw the background*/
ancestor_design(cb, clip_area, mode);
lv_checkbox_ext_t * ext = lv_obj_get_ext_attr(cb);
const lv_font_t * font = lv_obj_get_style_text_font(cb, LV_CHECKBOX_PART_MAIN);
lv_style_int_t letter_sp = lv_obj_get_style_text_letter_space(cb, LV_CHECKBOX_PART_MAIN);
lv_style_int_t line_sp = lv_obj_get_style_text_line_space(cb, LV_CHECKBOX_PART_MAIN);
lv_coord_t line_height = lv_font_get_line_height(font);
lv_coord_t bg_leftp = lv_obj_get_style_pad_left(cb, LV_CHECKBOX_PART_MAIN);
lv_coord_t bg_rightp = lv_obj_get_style_pad_right(cb, LV_CHECKBOX_PART_MAIN);
lv_coord_t bg_topp = lv_obj_get_style_pad_top(cb, LV_CHECKBOX_PART_MAIN);
lv_coord_t bg_bottomp = lv_obj_get_style_pad_bottom(cb, LV_CHECKBOX_PART_MAIN);
lv_coord_t bullet_leftm = lv_obj_get_style_margin_left(cb, LV_CHECKBOX_PART_BULLET);
lv_coord_t bullet_rightm = lv_obj_get_style_margin_right(cb, LV_CHECKBOX_PART_BULLET);
lv_coord_t bullet_topm = lv_obj_get_style_margin_top(cb, LV_CHECKBOX_PART_BULLET);
lv_coord_t bullet_bottomm = lv_obj_get_style_margin_bottom(cb, LV_CHECKBOX_PART_BULLET);
lv_coord_t bullet_leftp = lv_obj_get_style_pad_left(cb, LV_CHECKBOX_PART_BULLET);
lv_coord_t bullet_rightp = lv_obj_get_style_pad_right(cb, LV_CHECKBOX_PART_BULLET);
lv_coord_t bullet_topp = lv_obj_get_style_pad_top(cb, LV_CHECKBOX_PART_BULLET);
lv_coord_t bullet_bottomp = lv_obj_get_style_pad_bottom(cb, LV_CHECKBOX_PART_BULLET);
lv_draw_rect_dsc_t bullet_dsc;
lv_draw_rect_dsc_init(&bullet_dsc);
lv_obj_init_draw_rect_dsc(cb, LV_CHECKBOX_PART_BULLET, &bullet_dsc);
lv_area_t bullet_area;
bullet_area.x1 = cb->coords.x1 + bg_leftp + bullet_leftm;
bullet_area.x2 = bullet_area.x1 + line_height + bullet_leftp + bullet_rightp;
bullet_area.y1 = cb->coords.y1 + bg_topp + bullet_topm;
bullet_area.y2 = bullet_area.y1 + line_height + bullet_topp + bullet_bottomp;
lv_draw_rect(&bullet_area, clip_area, &bullet_dsc);
lv_point_t text_size;
_lv_txt_get_size(&text_size, ext->text, font, letter_sp, line_sp, LV_COORD_MAX, LV_TXT_FLAG_RECOLOR);
lv_coord_t y_ofs = (lv_area_get_height(&bullet_area) - line_height) / 2; /*Align the text to the bullet's center line*/
lv_area_t text_area;
text_area.x1 = bullet_area.x2 + bullet_rightm;
text_area.x2 = text_area.x1 + text_size.x;
text_area.y1 = bullet_area.y1 + bg_topp + y_ofs;
text_area.y2 = text_area.y1 + text_size.y;
lv_draw_label_dsc_t label_dsc;
lv_draw_label_dsc_init(&label_dsc);
lv_obj_init_draw_label_dsc(cb, LV_CHECKBOX_PART_MAIN, &label_dsc);
lv_draw_label(&text_area, clip_area, &label_dsc, ext->text, NULL);
} else {
ancestor_design(cb, clip_area, mode);
}
return LV_DESIGN_RES_OK;
}
/**
* Signal function of the check box
* @param cb pointer to a check box object
@@ -162,44 +251,48 @@ const char * lv_checkbox_get_text(const lv_obj_t * cb)
*/
static lv_res_t lv_checkbox_signal(lv_obj_t * cb, lv_signal_t sign, void * param)
{
lv_checkbox_ext_t * ext = lv_obj_get_ext_attr(cb);
lv_res_t res;
/* Include the ancient signal function */
res = ancestor_signal(cb, sign, param);
if(res != LV_RES_OK) return res;
if(sign == LV_SIGNAL_GET_STYLE) {
lv_get_style_info_t * info = param;
info->result = lv_checkbox_get_style(cb, info->part);
if(info->result != NULL) return LV_RES_OK;
else return ancestor_signal(cb, sign, param);
}
else if (sign == LV_SIGNAL_GET_TYPE) {
return _lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
}
else if (sign == LV_SIGNAL_GET_SELF_SIZE) {
const lv_font_t * font = lv_obj_get_style_text_font(cb, LV_CHECKBOX_PART_MAIN);
lv_style_int_t letter_sp = lv_obj_get_style_text_letter_space(cb, LV_CHECKBOX_PART_MAIN);
lv_style_int_t line_sp = lv_obj_get_style_text_line_space(cb, LV_CHECKBOX_PART_MAIN);
lv_point_t text_size;
_lv_txt_get_size(&text_size, ext->text, font, letter_sp, line_sp, LV_COORD_MAX, LV_TXT_FLAG_RECOLOR);
/* Include the ancient signal function */
res = ancestor_signal(cb, sign, param);
if(res != LV_RES_OK) return res;
if(sign == LV_SIGNAL_GET_TYPE) return lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
lv_checkbox_ext_t * ext = lv_obj_get_ext_attr(cb);
if(sign == LV_SIGNAL_STYLE_CHG) {
const lv_font_t * font = lv_obj_get_style_text_font(ext->label, LV_LABEL_PART_MAIN);
lv_coord_t line_height = lv_font_get_line_height(font);
lv_coord_t leftp = lv_obj_get_style_pad_left(cb, LV_CHECKBOX_PART_BULLET);
lv_coord_t rightp = lv_obj_get_style_pad_right(cb, LV_CHECKBOX_PART_BULLET);
lv_coord_t topp = lv_obj_get_style_pad_top(cb, LV_CHECKBOX_PART_BULLET);
lv_coord_t bottomp = lv_obj_get_style_pad_bottom(cb, LV_CHECKBOX_PART_BULLET);
lv_obj_set_size(ext->bullet, line_height + leftp + rightp, line_height + topp + bottomp);
lv_obj_set_state(ext->bullet, lv_obj_get_state(cb, LV_CHECKBOX_PART_BG));
}
else if(sign == LV_SIGNAL_PRESSED || sign == LV_SIGNAL_RELEASED || sign == LV_SIGNAL_PRESS_LOST ||
sign == LV_SIGNAL_FOCUS || sign == LV_SIGNAL_DEFOCUS) {
lv_obj_set_state(ext->bullet, lv_obj_get_state(cb, LV_CHECKBOX_PART_BG));
}
else if(sign == LV_SIGNAL_CONTROL) {
#if LV_USE_GROUP
char c = *((char *)param);
if(c == LV_KEY_RIGHT || c == LV_KEY_DOWN || c == LV_KEY_LEFT || c == LV_KEY_UP) {
/*Follow the backgrounds state with the bullet*/
lv_obj_set_state(ext->bullet, lv_obj_get_state(cb, LV_CHECKBOX_PART_BG));
}
#endif
lv_coord_t bullet_leftm = lv_obj_get_style_margin_left(cb, LV_CHECKBOX_PART_BULLET);
lv_coord_t bullet_rightm = lv_obj_get_style_margin_right(cb, LV_CHECKBOX_PART_BULLET);
lv_coord_t bullet_topm = lv_obj_get_style_margin_top(cb, LV_CHECKBOX_PART_BULLET);
lv_coord_t bullet_bottomm = lv_obj_get_style_margin_bottom(cb, LV_CHECKBOX_PART_BULLET);
lv_coord_t bullet_leftp = lv_obj_get_style_pad_left(cb, LV_CHECKBOX_PART_BULLET);
lv_coord_t bullet_rightp = lv_obj_get_style_pad_right(cb, LV_CHECKBOX_PART_BULLET);
lv_coord_t bullet_topp = lv_obj_get_style_pad_top(cb, LV_CHECKBOX_PART_BULLET);
lv_coord_t bullet_bottomp = lv_obj_get_style_pad_bottom(cb, LV_CHECKBOX_PART_BULLET);
lv_point_t bullet_size;
bullet_size.x = line_height + bullet_leftm + bullet_rightm + bullet_leftp + bullet_rightp;
bullet_size.y = line_height + bullet_topm + bullet_bottomm + bullet_topp + bullet_bottomp;
lv_point_t * size_res = param;
size_res->x = bullet_size.x + text_size.x;
size_res->y = LV_MATH_MAX(bullet_size.y, text_size.y);
}
return res;
@@ -212,11 +305,11 @@ static lv_style_list_t * lv_checkbox_get_style(lv_obj_t * cb, uint8_t type)
lv_checkbox_ext_t * ext = lv_obj_get_ext_attr(cb);
switch(type) {
case LV_CHECKBOX_PART_BG:
case LV_CHECKBOX_PART_MAIN:
style_dsc_p = &cb->style_list;
break;
case LV_CHECKBOX_PART_BULLET:
style_dsc_p = lv_obj_get_style_list(ext->bullet, LV_BTN_PART_MAIN);
style_dsc_p = &ext->style_bullet;
break;
default:
style_dsc_p = NULL;

View File

@@ -27,8 +27,6 @@ extern "C" {
#endif
#include "../lv_core/lv_obj.h"
#include "lv_btn.h"
#include "lv_label.h"
/*********************
* DEFINES
@@ -43,13 +41,15 @@ typedef struct {
/*No inherited ext, derived from the base object */
/*New data for this widget */
lv_obj_t * text; /*Pointer to button*/
lv_obj_t * label; /*Pointer to label*/
lv_style_list_t style_bullet;
char * text; /*Pointer to button*/
uint32_t static_txt :1;
} lv_checkbox_ext_t;
/** Checkbox styles. */
enum {
LV_CHECKBOX_PART_MAIN = LV_OBJ_PART_MAIN, /**< Style of object background. */
LV_CHECKBOX_PART_BULLET, /**< Style of the bullet */
_LV_CHECKBOX_PART_VIRTUAL_LAST,
};
typedef uint8_t lv_checkbox_style_t;
@@ -74,7 +74,7 @@ lv_obj_t * lv_checkbox_create(lv_obj_t * par, const lv_obj_t * copy);
* Set the text of a check box. `txt` will be copied and may be deallocated
* after this function returns.
* @param cb pointer to a check box
* @param txt the text of the check box. NULL to refresh with the current text.
* @param txt the text of the check box.
*/
void lv_checkbox_set_text(lv_obj_t * cb, const char * txt);
@@ -82,7 +82,7 @@ void lv_checkbox_set_text(lv_obj_t * cb, const char * txt);
* Set the text of a check box. `txt` must not be deallocated during the life
* of this checkbox.
* @param cb pointer to a check box
* @param txt the text of the check box. NULL to refresh with the current text.
* @param txt the text of the check box.
*/
void lv_checkbox_set_text_static(lv_obj_t * cb, const char * txt);
@@ -93,27 +93,21 @@ void lv_checkbox_set_text_static(lv_obj_t * cb, const char * txt);
*/
static inline void lv_checkbox_set_checked(lv_obj_t * cb, bool checked)
{
lv_btn_set_state(cb, checked ? LV_BTN_STATE_CHECKED_RELEASED : LV_BTN_STATE_RELEASED);
if(checked) lv_obj_set_state(cb, LV_STATE_CHECKED);
else lv_obj_clear_state(cb, LV_STATE_CHECKED);
}
/**
* Make the check box inactive (disabled)
* @param cb pointer to a check box object
* @param dis true; make the checkbox disabled; false: make the chackbox active
*/
static inline void lv_checkbox_set_disabled(lv_obj_t * cb)
static inline void lv_checkbox_set_disabled(lv_obj_t * cb, bool dis)
{
lv_btn_set_state(cb, LV_BTN_STATE_DISABLED);
if(dis) lv_obj_set_state(cb, LV_STATE_DISABLED);
else lv_obj_clear_state(cb, LV_STATE_DISABLED);
}
/**
* Set the state of a check box
* @param cb pointer to a check box object
* @param state the new state of the check box (from lv_btn_state_t enum)
*/
static inline void lv_checkbox_set_state(lv_obj_t * cb, lv_btn_state_t state)
{
lv_btn_set_state(cb, state);
}
/*=====================
* Getter functions
*====================*/
@@ -132,7 +126,7 @@ const char * lv_checkbox_get_text(const lv_obj_t * cb);
*/
static inline bool lv_checkbox_is_checked(const lv_obj_t * cb)
{
return lv_btn_get_state(cb) == LV_BTN_STATE_RELEASED ? false : true;
return lv_obj_get_state(cb) & LV_STATE_CHECKED ? true : false;
}
/**
@@ -140,19 +134,9 @@ static inline bool lv_checkbox_is_checked(const lv_obj_t * cb)
* @param cb pointer to a check box object
* @return true: inactive; false: not inactive
*/
static inline bool lv_checkbox_is_inactive(const lv_obj_t * cb)
static inline bool lv_checkbox_is_disabled(const lv_obj_t * cb)
{
return lv_btn_get_state(cb) == LV_BTN_STATE_DISABLED ? true : false;
}
/**
* Get the current state of a check box
* @param cb pointer to a check box object
* @return the state of the check box (from lv_btn_state_t enum)
*/
static inline lv_btn_state_t lv_checkbox_get_state(const lv_obj_t * cb)
{
return lv_btn_get_state(cb);
return lv_obj_get_state(cb) & LV_STATE_DISABLED ? true : false;
}
/**********************