rework checkbox and add LV_SIGNAL_SELF_SIZE

This commit is contained in:
Gabor Kiss-Vamosi
2020-09-29 14:26:35 +02:00
parent c474d6d3a6
commit 132e79fa42
8 changed files with 226 additions and 77 deletions

View File

@@ -444,6 +444,43 @@ lv_coord_t lv_obj_get_width_margin(lv_obj_t * obj)
return lv_obj_get_width(obj) + mleft + mright;
}
/**
* Get the width of the virtual content of an object
* @param obj pointer to an objects
* @return the width of the virtually drawn content
*/
lv_coord_t _lv_obj_get_self_width(lv_obj_t * obj)
{
lv_point_t p = {0, LV_COORD_MIN};
lv_signal_send((lv_obj_t * )obj, LV_SIGNAL_GET_SELF_SIZE, &p);
return p.x;
}
/**
* Get the height of the virtual content of an object
* @param obj pointer to an objects
* @return the width of the virtually drawn content
*/
lv_coord_t _lv_obj_get_self_height(lv_obj_t * obj)
{
lv_point_t p = {LV_COORD_MIN, 0};
lv_signal_send((lv_obj_t * )obj, LV_SIGNAL_GET_SELF_SIZE, &p);
return p.y;
}
/**
* Handle if the size of the internal (virtual) content of an object has changed.
* @param obj pointer to an object
* @return false: nothing happened; true: refresh happened
*/
bool _lv_obj_handle_self_size_chg(lv_obj_t * obj)
{
if(obj->w_set != LV_SIZE_AUTO && obj->h_set == LV_SIZE_AUTO) return false;
lv_obj_set_size(obj, obj->w_set, obj->h_set);
return true;
}
/**
* Calculate the "auto size". It's `auto_size = max(gird_size, children_size, self_size)`
* @param obj pointer to an object

View File

@@ -198,6 +198,27 @@ lv_coord_t lv_obj_get_height_margin(struct _lv_obj_t * obj);
*/
lv_coord_t lv_obj_get_width_margin(struct _lv_obj_t * obj);
/**
* Get the width of the virtual content of an object
* @param obj pointer to an objects
* @return the width of the virtually drawn content
*/
lv_coord_t _lv_obj_get_self_width(lv_obj_t * obj);
/**
* Get the height of the virtual content of an object
* @param obj pointer to an objects
* @return the width of the virtually drawn content
*/
lv_coord_t _lv_obj_get_self_height(lv_obj_t * obj);
/**
* Handle if the size of the internal (virtual) content of an object has changed.
* @param obj pointer to an object
* @return false: nothing happened; true: refresh happened
*/
bool _lv_obj_handle_self_size_chg(lv_obj_t * obj);
/**
* Calculate the "auto size". It's `auto_size = max(gird_size, children_size)`
* @param obj pointer to an object

View File

@@ -179,7 +179,7 @@ lv_coord_t lv_obj_get_scroll_top(const lv_obj_t * obj)
* @param obj
* @return
*/
lv_coord_t lv_obj_get_scroll_bottom(const lv_obj_t * obj)
lv_coord_t lv_obj_get_scroll_bottom(lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
@@ -196,6 +196,18 @@ lv_coord_t lv_obj_get_scroll_bottom(const lv_obj_t * obj)
child_res = y2;
}
lv_coord_t pad_top = lv_obj_get_style_pad_top(obj, LV_OBJ_PART_MAIN);
lv_coord_t pad_bottom = lv_obj_get_style_pad_bottom(obj, LV_OBJ_PART_MAIN);
child_res -= (obj->coords.y2 - pad_bottom);
lv_coord_t self_h = _lv_obj_get_self_height(obj);
self_h = self_h - (lv_obj_get_height(obj) - pad_top - pad_bottom);
self_h += obj->scroll.y;
return LV_MATH_MAX(child_res, self_h);
return child_res - obj->coords.y2 + lv_obj_get_style_pad_bottom(obj, LV_OBJ_PART_MAIN);
}
@@ -218,7 +230,7 @@ lv_coord_t lv_obj_get_scroll_left(const lv_obj_t * obj)
* @param obj
* @return
*/
lv_coord_t lv_obj_get_scroll_right(const lv_obj_t * obj)
lv_coord_t lv_obj_get_scroll_right(lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
@@ -239,11 +251,11 @@ lv_coord_t lv_obj_get_scroll_right(const lv_obj_t * obj)
child_res -= (obj->coords.x2 - pad_right);
lv_point_t p = {0, 0};
lv_signal_send(obj, LV_SIGNAL_GET_SELF_SIZE, &p);
p.x = p.x - (lv_obj_get_width(obj) - pad_right - pad_left);
p.x += obj->scroll.x;
return LV_MATH_MAX(child_res, p.x);
lv_coord_t self_w = _lv_obj_get_self_width(obj);
self_w = self_w - (lv_obj_get_width(obj) - pad_right - pad_left);
self_w += obj->scroll.x;
return LV_MATH_MAX(child_res, self_w);
}
/**********************

View File

@@ -119,7 +119,7 @@ lv_coord_t lv_obj_get_scroll_top(const struct _lv_obj_t * obj);
* @param obj
* @return
*/
lv_coord_t lv_obj_get_scroll_bottom(const struct _lv_obj_t * obj);
lv_coord_t lv_obj_get_scroll_bottom(struct _lv_obj_t * obj);
/**
@@ -138,7 +138,7 @@ lv_coord_t lv_obj_get_scroll_left(const struct _lv_obj_t * obj);
* @param obj
* @return
*/
lv_coord_t lv_obj_get_scroll_right(const struct _lv_obj_t * obj);
lv_coord_t lv_obj_get_scroll_right(struct _lv_obj_t * obj);
/**********************

View File

@@ -626,9 +626,6 @@ static void checkbox_init(void)
#if LV_USE_CHECKBOX != 0
style_init_reset(&styles->cb_bg);
lv_style_set_radius(&styles->cb_bg, LV_STATE_DEFAULT, LV_DPX(4));
lv_style_set_pad_left(&styles->cb_bg, LV_STATE_DEFAULT, LV_DPX(30));
lv_style_set_pad_top(&styles->cb_bg, LV_STATE_DEFAULT, LV_DPX(3));
lv_style_set_pad_bottom(&styles->cb_bg, LV_STATE_DEFAULT, LV_DPX(3));
lv_style_set_outline_color(&styles->cb_bg, LV_STATE_DEFAULT, theme.color_primary);
lv_style_set_outline_opa(&styles->cb_bg, LV_STATE_DEFAULT, LV_OPA_TRANSP);
lv_style_set_outline_opa(&styles->cb_bg, LV_STATE_FOCUSED, LV_OPA_50);

View File

@@ -1108,9 +1108,10 @@ static lv_res_t lv_canvas_signal(lv_obj_t * canvas, lv_signal_t sign, void * par
/* Include the ancient signal function */
res = ancestor_signal(canvas, 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);
if(sign == LV_SIGNAL_CLEANUP) {
if(sign == LV_SIGNAL_GET_TYPE) {
return _lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
}
else if(sign == LV_SIGNAL_CLEANUP) {
/*Nothing to cleanup. (No dynamically allocated memory in 'ext')*/
}

View File

@@ -12,6 +12,7 @@
#include "../lv_misc/lv_debug.h"
#include "../lv_core/lv_group.h"
#include "../lv_themes/lv_theme.h"
#include "lv_label.h"
/*********************
* DEFINES
@@ -54,7 +55,7 @@ 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_label_create(par, copy);
lv_obj_t * cb = lv_obj_create(par, copy);
LV_ASSERT_MEM(cb);
if(cb == NULL) return NULL;
@@ -75,11 +76,12 @@ lv_obj_t * lv_checkbox_create(lv_obj_t * par, const lv_obj_t * copy)
/*Init the new checkbox object*/
if(copy == NULL) {
lv_label_set_text_static(cb, "Check box");
ext->txt = "Check box";
ext->static_txt = 1;
lv_theme_apply(cb, LV_THEME_CHECKBOX);
lv_obj_add_flag(cb, LV_OBJ_FLAG_CLICKABLE);
lv_obj_add_flag(cb, LV_OBJ_FLAG_CHECKABLE);
lv_obj_set_size(cb, LV_SIZE_AUTO, LV_SIZE_AUTO);
}
else {
@@ -99,10 +101,87 @@ lv_obj_t * lv_checkbox_create(lv_obj_t * par, const lv_obj_t * copy)
* Setter functions
*====================*/
/**
* 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.
*/
void lv_checkbox_set_text(lv_obj_t * cb, const char * txt)
{
lv_checkbox_ext_t * ext = lv_obj_get_ext_attr(cb);
size_t len = strlen(txt);
if(!ext->static_txt) ext->txt = lv_mem_realloc(ext->txt, len + 1);
else ext->txt = lv_mem_alloc(len + 1);
strcpy(ext->txt, txt);
ext->static_txt = 0;
if(cb->w_set == LV_SIZE_AUTO || cb->h_set == LV_SIZE_AUTO) {
lv_obj_set_size(cb, cb->w_set, cb->h_set);
}
}
/**
* 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.
*/
void lv_checkbox_set_text_static(lv_obj_t * cb, const char * txt)
{
lv_checkbox_ext_t * ext = lv_obj_get_ext_attr(cb);
if(!ext->static_txt) lv_mem_free(ext->txt);
ext->txt = txt;
ext->static_txt = 1;
if(cb->w_set == LV_SIZE_AUTO || cb->h_set == LV_SIZE_AUTO) {
lv_obj_set_size(cb, cb->w_set, cb->h_set);
}
}
/**
* Set the state of the check box
* @param cb pointer to a check box object
* @param checked true: make the check box checked; false: make it unchecked
*/
void lv_checkbox_set_checked(lv_obj_t * cb, bool checked)
{
if(checked) lv_obj_set_state(cb, LV_STATE_CHECKED);
else lv_obj_clear_state(cb, LV_STATE_CHECKED);
_lv_obj_remove_style_trans(cb);
}
/**
* 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
*/
void lv_checkbox_set_disabled(lv_obj_t * cb, bool dis)
{
if(dis) lv_obj_set_state(cb, LV_STATE_DISABLED);
else lv_obj_clear_state(cb, LV_STATE_DISABLED);
_lv_obj_remove_style_trans(cb);
}
/*=====================
* Getter functions
*====================*/
/**
* Get the text of a check box
* @param cb pointer to check box object
* @return pointer to the text of the check box
*/
const char * lv_checkbox_get_text(const lv_obj_t * cb)
{
lv_checkbox_ext_t * ext = lv_obj_get_ext_attr(cb);
return ext->txt;
}
/**********************
* STATIC FUNCTIONS
**********************/
@@ -129,12 +208,14 @@ static lv_design_res_t lv_checkbox_design(lv_obj_t * cb, const lv_area_t * clip_
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_coord_t line_height = lv_font_get_line_height(font);
lv_coord_t font_h = lv_font_get_line_height(font);
lv_coord_t bg_topp = lv_obj_get_style_pad_top(cb, LV_CHECKBOX_PART_MAIN);
lv_coord_t bg_leftp = lv_obj_get_style_pad_left(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_topm = lv_obj_get_style_margin_top(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_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);
@@ -145,12 +226,32 @@ static lv_design_res_t lv_checkbox_design(lv_obj_t * cb, const lv_area_t * clip_
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 + bullet_leftm;
bullet_area.x2 = bullet_area.x1 + line_height + bullet_leftp + bullet_rightp - 1;
bullet_area.y1 = cb->coords.y1 + bg_topp - bullet_topp + bullet_topm;
bullet_area.y2 = bullet_area.y1 + line_height + bullet_topp + bullet_bottomp - 1;
bullet_area.x1 = cb->coords.x1 + bg_leftp + bullet_leftm;
bullet_area.x2 = bullet_area.x1 + font_h + bullet_leftp + bullet_rightp - 1;
bullet_area.y1 = cb->coords.y1 + bg_topp + bullet_topm;
bullet_area.y2 = bullet_area.y1 + font_h + bullet_topp + bullet_bottomp - 1;
lv_draw_rect(&bullet_area, clip_area, &bullet_dsc);
lv_coord_t line_space = lv_obj_get_style_text_line_space(cb, LV_CHECKBOX_PART_MAIN);
lv_coord_t letter_space = lv_obj_get_style_text_letter_space(cb, LV_CHECKBOX_PART_MAIN);
lv_point_t txt_size;
_lv_txt_get_size(&txt_size, ext->txt, font, letter_space, line_space, LV_COORD_MAX, LV_TXT_FLAG_NONE);
lv_draw_label_dsc_t txt_dsc;
lv_draw_label_dsc_init(&txt_dsc);
lv_obj_init_draw_label_dsc(cb, LV_CHECKBOX_PART_MAIN, &txt_dsc);
lv_coord_t y_ofs = (lv_area_get_height(&bullet_area) - font_h) / 2;
lv_area_t txt_area;
txt_area.x1 = bullet_area.x2 + bullet_rightm;
txt_area.x2 = txt_area.x1 + txt_size.x;
txt_area.y1 = cb->coords.y1 + bg_topp + y_ofs;
txt_area.y2 = txt_area.y1 + txt_size.y;
lv_draw_label(&txt_area, clip_area, &txt_dsc, ext->txt, NULL);
} else {
ancestor_design(cb, clip_area, mode);
}
@@ -166,8 +267,6 @@ static lv_design_res_t lv_checkbox_design(lv_obj_t * cb, const lv_area_t * clip_
*/
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);
@@ -182,6 +281,34 @@ static lv_res_t lv_checkbox_signal(lv_obj_t * cb, lv_signal_t sign, void * 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) {
lv_point_t * p = param;
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_coord_t font_h = lv_font_get_line_height(font);
lv_coord_t line_space = lv_obj_get_style_text_line_space(cb, LV_CHECKBOX_PART_MAIN);
lv_coord_t letter_space = lv_obj_get_style_text_letter_space(cb, LV_CHECKBOX_PART_MAIN);
lv_point_t txt_size;
_lv_txt_get_size(&txt_size, ext->txt, font, letter_space, line_space, LV_COORD_MAX, LV_TXT_FLAG_NONE);
lv_coord_t bullet_leftm = lv_obj_get_style_margin_left(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_rightm = lv_obj_get_style_margin_right(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 = font_h + bullet_leftm + bullet_rightm + bullet_leftp + bullet_rightp;
bullet_size.y = font_h + bullet_topm + bullet_bottomm + bullet_topp + bullet_bottomp;
p->x = bullet_size.x + txt_size.x;
p->y = LV_MATH_MAX(bullet_size.y, txt_size.y);
}
return res;
}

View File

@@ -14,20 +14,15 @@ extern "C" {
* INCLUDES
*********************/
#include "../lv_conf_internal.h"
#include "../lv_core/lv_obj.h"
#if LV_USE_CHECKBOX != 0
/*Testing of dependencies*/
#if LV_USE_BTN == 0
#error "lv_cb: lv_btn is required. Enable it in lv_conf.h (LV_USE_BTN 1) "
#endif
#if LV_USE_LABEL == 0
#error "lv_cb: lv_label is required. Enable it in lv_conf.h (LV_USE_LABEL 1) "
#endif
#include "lv_label.h"
/*********************
* DEFINES
*********************/
@@ -38,10 +33,10 @@ extern "C" {
/*Data of check box*/
typedef struct {
lv_label_ext_t label_ext;
/*New data for this widget */
lv_style_list_t style_bullet;
char * txt;
uint32_t static_txt :1;
} lv_checkbox_ext_t;
/** Checkbox styles. */
@@ -68,65 +63,24 @@ lv_obj_t * lv_checkbox_create(lv_obj_t * par, const lv_obj_t * copy);
* Setter functions
*====================*/
/**
* 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.
*/
static inline void lv_checkbox_set_text(lv_obj_t * cb, const char * txt)
{
lv_label_set_text(cb, 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.
*/
static inline void lv_checkbox_set_text_static(lv_obj_t * cb, const char * txt)
{
lv_label_set_text_static(cb, txt);
}
/**
* Set the state of the check box
* @param cb pointer to a check box object
* @param checked true: make the check box checked; false: make it unchecked
*/
static inline void lv_checkbox_set_checked(lv_obj_t * cb, bool checked)
{
if(checked) lv_obj_set_state(cb, LV_STATE_CHECKED);
else lv_obj_clear_state(cb, LV_STATE_CHECKED);
}
void lv_checkbox_set_checked(lv_obj_t * cb, bool 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
* @param dis true; make the checkbox disabled; false: make the checkbox active
*/
static inline void lv_checkbox_set_disabled(lv_obj_t * cb, bool dis)
{
if(dis) lv_obj_set_state(cb, LV_STATE_DISABLED);
else lv_obj_clear_state(cb, LV_STATE_DISABLED);
}
void lv_checkbox_set_disabled(lv_obj_t * cb, bool dis);
/*=====================
* Getter functions
*====================*/
/**
* Get the text of a check box
* @param cb pointer to check box object
* @return pointer to the text of the check box
*/
static inline const char * lv_checkbox_get_text(const lv_obj_t * cb)
{
return lv_label_get_text(cb);
}
/**
* Get the current state of the check box
* @param cb pointer to a check box object