diff --git a/lv_draw/lv_draw.c b/lv_draw/lv_draw.c index 7dddd46e3..4d474a652 100644 --- a/lv_draw/lv_draw.c +++ b/lv_draw/lv_draw.c @@ -245,13 +245,13 @@ void lv_draw_label(const area_t * coords,const area_t * mask, const lv_style_t * w = area_get_width(coords); } else { point_t p; - txt_get_size(&p, txt, style->text.font, style->text.space_letter, style->text.space_line, CORD_MAX, flag); + txt_get_size(&p, txt, style->text.font, style->text.letter_space, style->text.line_space, CORD_MAX, flag); w = p.x; } /*Init variables for the first line*/ cord_t line_length = 0; uint32_t line_start = 0; - uint32_t line_end = txt_get_next_line(txt, font, style->text.space_letter, w, flag); + uint32_t line_end = txt_get_next_line(txt, font, style->text.letter_space, w, flag); point_t pos; pos.x = coords->x1; @@ -260,7 +260,7 @@ void lv_draw_label(const area_t * coords,const area_t * mask, const lv_style_t * /*Align the line to middle if enabled*/ if(flag & TXT_FLAG_CENTER) { line_length = txt_get_width(&txt[line_start], line_end - line_start, - font, style->text.space_letter, flag); + font, style->text.letter_space, flag); pos.x += (w - line_length) / 2; } @@ -322,25 +322,25 @@ void lv_draw_label(const area_t * coords,const area_t * mask, const lv_style_t * color_t color = style->text.color; if(cmd_state == CMD_STATE_IN) color = recolor; - letter_fp(&pos, mask, font, letter, color, style->body.opa); + letter_fp(&pos, mask, font, letter, color, style->text.opa); - pos.x += (font_get_width(font, letter) >> FONT_ANTIALIAS) + style->text.space_letter; + pos.x += (font_get_width(font, letter) >> FONT_ANTIALIAS) + style->text.letter_space; } /*Go to next line*/ line_start = line_end; - line_end += txt_get_next_line(&txt[line_start], font, style->text.space_letter, w, flag); + line_end += txt_get_next_line(&txt[line_start], font, style->text.letter_space, w, flag); pos.x = coords->x1; /*Align to middle*/ if(flag & TXT_FLAG_CENTER) { line_length = txt_get_width(&txt[line_start], line_end - line_start, - font, style->text.space_letter, flag); + font, style->text.letter_space, flag); pos.x += (w - line_length) / 2; } /*Go the next line position*/ pos.y += font_get_height(font) >> FONT_ANTIALIAS; - pos.y += style->text.space_line; + pos.y += style->text.line_space; } } @@ -395,7 +395,7 @@ void lv_draw_img(const area_t * coords, const area_t * mask, const_data = true; uint8_t * f_data = ((ufs_file_t*)file.file_d)->ent->data_d; f_data += sizeof(lv_img_raw_header_t); - map_fp(coords, &mask_com, (void*)f_data , style->body.opa, header.transp, upscale, style->image.color, style->image.intense); + map_fp(coords, &mask_com, (void*)f_data , style->image.opa, header.transp, upscale, style->image.color, style->image.intense); } #endif @@ -429,7 +429,7 @@ void lv_draw_img(const area_t * coords, const area_t * mask, for(row = mask_com.y1; row <= mask_com.y2; row += us_val) { res = fs_read(&file, buf, useful_data, &br); - map_fp(&line, &mask_com, buf, style->body.opa, header.transp, upscale, + map_fp(&line, &mask_com, buf, style->image.opa, header.transp, upscale, style->image.color, style->image.intense); fs_tell(&file, &act_pos); @@ -515,7 +515,7 @@ void lv_draw_line(const point_t * p1, const point_t * p2, const area_t * mask, draw_area.x2 = MATH_MAX(act_area.x1, act_area.x2); draw_area.y1 = MATH_MIN(act_area.y1, act_area.y2); draw_area.y2 = MATH_MAX(act_area.y1, act_area.y2); - fill_fp(&draw_area, mask, style->line.color, style->body.opa); + fill_fp(&draw_area, mask, style->line.color, style->line.opa); } if (hor == false && last_x != act_point.x) { area_t act_area; @@ -531,7 +531,7 @@ void lv_draw_line(const point_t * p1, const point_t * p2, const area_t * mask, draw_area.x2 = MATH_MAX(act_area.x1, act_area.x2); draw_area.y1 = MATH_MIN(act_area.y1, act_area.y2); draw_area.y2 = MATH_MAX(act_area.y1, act_area.y2); - fill_fp(&draw_area, mask, style->line.color, style->body.opa); + fill_fp(&draw_area, mask, style->line.color, style->line.opa); } /*Calc. the next point of the line*/ @@ -559,7 +559,7 @@ void lv_draw_line(const point_t * p1, const point_t * p2, const area_t * mask, draw_area.x2 = MATH_MAX(act_area.x1, act_area.x2); draw_area.y1 = MATH_MIN(act_area.y1, act_area.y2); draw_area.y2 = MATH_MAX(act_area.y1, act_area.y2); - fill_fp(&draw_area, mask, style->line.color, style->body.opa); + fill_fp(&draw_area, mask, style->line.color, style->line.opa); } if (hor == false) { area_t act_area; @@ -573,7 +573,7 @@ void lv_draw_line(const point_t * p1, const point_t * p2, const area_t * mask, draw_area.x2 = MATH_MAX(act_area.x1, act_area.x2); draw_area.y1 = MATH_MIN(act_area.y1, act_area.y2); draw_area.y2 = MATH_MAX(act_area.y1, act_area.y2); - fill_fp(&draw_area, mask, style->line.color, style->body.opa); + fill_fp(&draw_area, mask, style->line.color, style->line.opa); } } diff --git a/lv_obj/lv_indev.c b/lv_obj/lv_indev.c index dd9f0176b..86a01cdea 100644 --- a/lv_obj/lv_indev.c +++ b/lv_obj/lv_indev.c @@ -144,6 +144,7 @@ void lv_indev_get_point(lv_indev_t * indev, point_t * point) */ bool lv_indev_is_dragging(lv_indev_t * indev) { + if(indev == NULL) return false; return indev->state.drag_in_prog == 0 ? false : true; } diff --git a/lv_obj/lv_indev.h b/lv_obj/lv_indev.h index 1db54d18f..91c575146 100644 --- a/lv_obj/lv_indev.h +++ b/lv_obj/lv_indev.h @@ -24,14 +24,6 @@ extern "C" { * TYPEDEFS **********************/ -typedef enum -{ - LV_RES_INV = 0, /*Typically indicates that the object is deleted (become invalid) in the action function*/ - LV_RES_OK, /*The object is valid (no deleted) after the action*/ -}lv_res_t; - -typedef lv_res_t (*lv_action_t) (struct __LV_OBJ_T * obj); - /********************** * GLOBAL PROTOTYPES **********************/ diff --git a/lv_obj/lv_obj.h b/lv_obj/lv_obj.h index 8fb92ff78..84cda6601 100644 --- a/lv_obj/lv_obj.h +++ b/lv_obj/lv_obj.h @@ -134,6 +134,14 @@ typedef struct __LV_OBJ_T #endif }lv_obj_t; +typedef enum +{ + LV_RES_INV = 0, /*Typically indicates that the object is deleted (become invalid) in the action function*/ + LV_RES_OK, /*The object is valid (no deleted) after the action*/ +}lv_res_t; + +typedef lv_res_t (*lv_action_t) (struct __LV_OBJ_T * obj); + /*Protect some attributes (max. 8 bit)*/ typedef enum { diff --git a/lv_obj/lv_style.c b/lv_obj/lv_style.c index 649c84c06..a00cced88 100644 --- a/lv_obj/lv_style.c +++ b/lv_obj/lv_style.c @@ -86,14 +86,17 @@ void lv_style_init (void) lv_style_scr.body.shadow.type = LV_SHADOW_FULL; lv_style_scr.body.shadow.width = 0; + lv_style_scr.text.opa = OPA_COVER; lv_style_scr.text.color = COLOR_MAKE(0x20, 0x20, 0x20); lv_style_scr.text.font = FONT_DEFAULT; - lv_style_scr.text.space_letter = 1 << LV_ANTIALIAS; - lv_style_scr.text.space_line = 2 << LV_ANTIALIAS; + lv_style_scr.text.letter_space = 1 << LV_ANTIALIAS; + lv_style_scr.text.line_space = 2 << LV_ANTIALIAS; + lv_style_scr.image.opa = OPA_COVER; lv_style_scr.image.color = COLOR_MAKE(0x20, 0x20, 0x20); lv_style_scr.image.intense = OPA_TRANSP; + lv_style_scr.line.opa = OPA_COVER; lv_style_scr.line.color = COLOR_MAKE(0x20, 0x20, 0x20); lv_style_scr.line.width = 1 << LV_ANTIALIAS; @@ -256,8 +259,8 @@ static void lv_style_aimator(lv_style_anim_dsc_t * dsc, int32_t val) STYLE_ATTR_ANIM(body.padding.hor, val); STYLE_ATTR_ANIM(body.padding.ver, val); STYLE_ATTR_ANIM(body.padding.inner, val); - STYLE_ATTR_ANIM(text.space_line, val); - STYLE_ATTR_ANIM(text.space_letter, val); + STYLE_ATTR_ANIM(text.line_space, val); + STYLE_ATTR_ANIM(text.letter_space, val); STYLE_ATTR_ANIM(line.width, val); STYLE_ATTR_ANIM(image.intense, val); diff --git a/lv_obj/lv_style.h b/lv_obj/lv_style.h index 582a4b81f..608df88c5 100644 --- a/lv_obj/lv_style.h +++ b/lv_obj/lv_style.h @@ -70,18 +70,21 @@ typedef struct struct { color_t color; const font_t * font; - cord_t space_letter; - cord_t space_line; + cord_t letter_space; + cord_t line_space; + opa_t opa; }text; struct { color_t color; opa_t intense; + opa_t opa; }image; struct { color_t color; cord_t width; + opa_t opa; }line; }lv_style_t; diff --git a/lv_objx/lv_bar.c b/lv_objx/lv_bar.c index d0adb576d..cc0e0f81e 100644 --- a/lv_objx/lv_bar.c +++ b/lv_objx/lv_bar.c @@ -63,7 +63,7 @@ lv_obj_t * lv_bar_create(lv_obj_t * par, lv_obj_t * copy) dm_assert(ext); ext->min_value = 0; ext->max_value = 100; - ext->act_value = 0; + ext->cur_value = 0; ext->style_inicator = &lv_style_pretty_color; /* Save the ancient design function. @@ -78,17 +78,17 @@ lv_obj_t * lv_bar_create(lv_obj_t * par, lv_obj_t * copy) lv_obj_set_click(new_bar, false); lv_obj_set_size(new_bar, LV_DPI * 2, LV_DPI / 3); lv_obj_set_style(new_bar, &lv_style_pretty); - lv_bar_set_value(new_bar, ext->act_value); + lv_bar_set_value(new_bar, ext->cur_value); } 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->act_value = ext_copy->act_value; + ext->cur_value = ext_copy->cur_value; ext->style_inicator = ext_copy->style_inicator; /*Refresh the style with new signal function*/ lv_obj_refresh_style(new_bar); - lv_bar_set_value(new_bar, ext->act_value); + lv_bar_set_value(new_bar, ext->cur_value); } return new_bar; } @@ -131,8 +131,8 @@ bool lv_bar_signal(lv_obj_t * bar, lv_signal_t sign, void * param) void lv_bar_set_value(lv_obj_t * bar, int16_t value) { lv_bar_ext_t * ext = lv_obj_get_ext_attr(bar); - ext->act_value = value > ext->max_value ? ext->max_value : value; - ext->act_value = ext->act_value < ext->min_value ? ext->min_value : ext->act_value; + ext->cur_value = value > ext->max_value ? ext->max_value : value; + ext->cur_value = ext->cur_value < ext->min_value ? ext->min_value : ext->cur_value; lv_obj_invalidate(bar); } @@ -152,7 +152,7 @@ void lv_bar_set_value_anim(lv_obj_t * bar, int16_t value, uint16_t anim_time) anim_t a; a.var = bar; - a.start = ext->act_value; + a.start = ext->cur_value; a.end = new_value; a.fp = (anim_fp_t)lv_bar_set_value; a.path = anim_get_path(ANIM_PATH_LIN); @@ -180,13 +180,13 @@ void lv_bar_set_range(lv_obj_t * bar, int16_t min, int16_t max) lv_bar_ext_t * ext = lv_obj_get_ext_attr(bar); ext->max_value = max; ext->min_value = min; - if(ext->act_value > max) { - ext->act_value = max; - lv_bar_set_value(bar, ext->act_value); + if(ext->cur_value > max) { + ext->cur_value = max; + lv_bar_set_value(bar, ext->cur_value); } - if(ext->act_value < min) { - ext->act_value = min; - lv_bar_set_value(bar, ext->act_value); + if(ext->cur_value < min) { + ext->cur_value = min; + lv_bar_set_value(bar, ext->cur_value); } lv_obj_invalidate(bar); } @@ -197,7 +197,7 @@ void lv_bar_set_range(lv_obj_t * bar, int16_t min, int16_t max) * @param bg pointer to the background's style (NULL to leave unchanged) * @param indic pointer to the indicator's style (NULL to leave unchanged) */ -void lv_bar_set_styles(lv_obj_t * bar, lv_style_t * bg, lv_style_t * indic) +void lv_bar_set_style(lv_obj_t * bar, lv_style_t * bg, lv_style_t * indic) { lv_bar_ext_t * ext = lv_obj_get_ext_attr(bar); @@ -223,7 +223,7 @@ void lv_bar_set_styles(lv_obj_t * bar, lv_style_t * bg, lv_style_t * indic) int16_t lv_bar_get_value(lv_obj_t * bar) { lv_bar_ext_t * ext = lv_obj_get_ext_attr(bar); - return ext->act_value; + return ext->cur_value; } /** @@ -298,10 +298,10 @@ static bool lv_bar_design(lv_obj_t * bar, const area_t * mask, lv_design_mode_t cord_t h = area_get_height(&indic_area); if(w >= h) { - indic_area.x2 = (int32_t) ((int32_t)w * (ext->act_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; } else { - indic_area.y1 = (int32_t) ((int32_t)h * (ext->act_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; } diff --git a/lv_objx/lv_bar.h b/lv_objx/lv_bar.h index 48e2b3aeb..a7fc1ebca 100644 --- a/lv_objx/lv_bar.h +++ b/lv_objx/lv_bar.h @@ -34,7 +34,7 @@ typedef struct { /*No inherited ext*/ /*Ext. of ancestor*/ /*New data for this type */ - int16_t act_value; /*Current 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*/ lv_style_t *style_inicator; /*Style of the indicator*/ @@ -90,7 +90,7 @@ void lv_bar_set_range(lv_obj_t * bar, int16_t min, int16_t max); * @param bg pointer to the background's style * @param indic pointer to the indicator's style */ -void lv_bar_set_styles(lv_obj_t * bar, lv_style_t * bg, lv_style_t * indic); +void lv_bar_set_style(lv_obj_t * bar, lv_style_t * bg, lv_style_t * indic); /** * Get the value of a bar diff --git a/lv_objx/lv_btn.c b/lv_objx/lv_btn.c index 976dfed5d..027a6a47b 100644 --- a/lv_objx/lv_btn.c +++ b/lv_objx/lv_btn.c @@ -28,13 +28,12 @@ /********************** * STATIC PROTOTYPES **********************/ -#if 0 -static bool lv_btn_design(lv_obj_t * btn, const area_t * mask, lv_design_mode_t mode); -#endif +static lv_signal_func_t ancestor_signal; /********************** * STATIC VARIABLES **********************/ +static lv_res_t lv_btn_signal(lv_obj_t * btn, lv_signal_t sign, void * param); /********************** * MACROS @@ -56,6 +55,8 @@ lv_obj_t * lv_btn_create(lv_obj_t * par, lv_obj_t * copy) new_btn = lv_cont_create(par, copy); dm_assert(new_btn); + if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_func(new_btn); + /*Allocate the extended data*/ lv_btn_ext_t * ext = lv_obj_allocate_ext_attr(new_btn, sizeof(lv_btn_ext_t)); dm_assert(ext); @@ -79,7 +80,7 @@ lv_obj_t * lv_btn_create(lv_obj_t * par, lv_obj_t * copy) /*If no copy do the basic initialization*/ if(copy == NULL) { - lv_cont_set_layout(new_btn, LV_CONT_LAYOUT_CENTER); + lv_btn_set_layout(new_btn, LV_CONT_LAYOUT_CENTER); lv_obj_set_style(new_btn, ext->styles[LV_BTN_STATE_RELEASED]); } /*Copy 'copy'*/ @@ -97,118 +98,6 @@ lv_obj_t * lv_btn_create(lv_obj_t * par, lv_obj_t * copy) return new_btn; } -/** - * Signal function of the button - * @param btn pointer to a button object - * @param sign a signal type from lv_signal_t enum - * @param param pointer to a signal specific variable - */ -bool lv_btn_signal(lv_obj_t * btn, lv_signal_t sign, void * param) -{ - bool valid; - - /* Include the ancient signal function */ - valid = lv_cont_signal(btn, sign, param); - - /* The object can be deleted so check its validity and then - * make the object specific signal handling */ - if(valid != false) { - lv_btn_ext_t * ext = lv_obj_get_ext_attr(btn); - lv_btn_state_t state = lv_btn_get_state(btn); - bool tgl = lv_btn_get_toggle(btn); - - if(sign == LV_SIGNAL_PRESSED) { - /*Refresh the state*/ - if(ext->state == LV_BTN_STATE_RELEASED) { - lv_btn_set_state(btn, LV_BTN_STATE_PRESSED); - } else if(ext->state == LV_BTN_STATE_TGL_RELEASED) { - lv_btn_set_state(btn, LV_BTN_STATE_TGL_PRESSED); - } - - ext->long_press_action_executed = 0; - /*Call the press action, 'param' is the caller indev_proc*/ - if(ext->actions[LV_BTN_ACTION_PRESS] && state != LV_BTN_STATE_INACTIVE) { - valid = ext->actions[LV_BTN_ACTION_PRESS](btn); - } - } - else if(sign == LV_SIGNAL_PRESS_LOST) { - /*Refresh the state*/ - if(ext->state == LV_BTN_STATE_PRESSED) lv_btn_set_state(btn, LV_BTN_STATE_RELEASED); - else if(ext->state == LV_BTN_STATE_TGL_PRESSED) lv_btn_set_state(btn, LV_BTN_STATE_TGL_RELEASED); - } - 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_PRESSED) lv_btn_set_state(btn, LV_BTN_STATE_RELEASED); - else if(ext->state == LV_BTN_STATE_TGL_PRESSED) lv_btn_set_state(btn, LV_BTN_STATE_TGL_RELEASED); - } - } - else if(sign == LV_SIGNAL_RELEASED) { - /*If not dragged and it was not long press action then - *change state and run the action*/ - if(lv_indev_is_dragging(param) == false && ext->long_press_action_executed == 0) { - if(ext->state == LV_BTN_STATE_PRESSED && tgl == false) { - lv_btn_set_state(btn, LV_BTN_STATE_RELEASED); - } else if(ext->state == LV_BTN_STATE_TGL_PRESSED && tgl == false) { - lv_btn_set_state(btn, LV_BTN_STATE_TGL_RELEASED); - } else if(ext->state == LV_BTN_STATE_PRESSED && tgl == true) { - lv_btn_set_state(btn, LV_BTN_STATE_TGL_RELEASED); - } else if(ext->state == LV_BTN_STATE_TGL_PRESSED && tgl == true) { - lv_btn_set_state(btn, LV_BTN_STATE_RELEASED); - } - - if(ext->actions[LV_BTN_ACTION_RELEASE] && state != LV_BTN_STATE_INACTIVE) { - valid = ext->actions[LV_BTN_ACTION_RELEASE](btn); - } - } else { /*If dragged change back the state*/ - if(ext->state == LV_BTN_STATE_PRESSED) { - lv_btn_set_state(btn, LV_BTN_STATE_RELEASED); - } else if(ext->state == LV_BTN_STATE_TGL_PRESSED) { - lv_btn_set_state(btn, LV_BTN_STATE_TGL_RELEASED); - } - } - } - else if(sign == LV_SIGNAL_LONG_PRESS) { - if(ext->actions[LV_BTN_ACTION_LONG_PRESS] && state != LV_BTN_STATE_INACTIVE) { - ext->long_press_action_executed = 1; - valid = ext->actions[LV_BTN_ACTION_LONG_PRESS](btn); - } - } - else if(sign == LV_SIGNAL_LONG_PRESS_REP) { - if(ext->actions[LV_BTN_ACTION_LONG_PRESS_REPEATE] && state != LV_BTN_STATE_INACTIVE) { - valid = ext->actions[LV_BTN_ACTION_LONG_PRESS_REPEATE](btn); - } - } - else if(sign == LV_SIGNAL_CONTROLL) { - char c = *((char*)param); - if(c == LV_GROUP_KEY_RIGHT || c == LV_GROUP_KEY_UP) { - if(lv_btn_get_toggle(btn) != false) lv_btn_set_state(btn, LV_BTN_STATE_TGL_RELEASED); - if(ext->actions[LV_BTN_ACTION_RELEASE] && lv_btn_get_state(btn) != LV_BTN_STATE_INACTIVE) { - valid = ext->actions[LV_BTN_ACTION_RELEASE]; - } - } else if(c == LV_GROUP_KEY_LEFT || c == LV_GROUP_KEY_DOWN) { - if(lv_btn_get_toggle(btn) != false) lv_btn_set_state(btn, LV_BTN_STATE_RELEASED); - if(ext->actions[LV_BTN_ACTION_RELEASE] && lv_btn_get_state(btn) != LV_BTN_STATE_INACTIVE) { - valid = ext->actions[LV_BTN_ACTION_RELEASE](btn); - } - } else if(c == LV_GROUP_KEY_ENTER) { - if(lv_btn_get_toggle(btn) != false) { - lv_btn_state_t state = lv_btn_get_state(btn); - if(state == LV_BTN_STATE_RELEASED) lv_btn_set_state(btn, LV_BTN_STATE_TGL_RELEASED); - else if(state == LV_BTN_STATE_PRESSED) lv_btn_set_state(btn, LV_BTN_STATE_TGL_PRESSED); - else if(state == LV_BTN_STATE_TGL_RELEASED) lv_btn_set_state(btn, LV_BTN_STATE_RELEASED); - else if(state == LV_BTN_STATE_TGL_PRESSED) lv_btn_set_state(btn, LV_BTN_STATE_PRESSED); - } - if(ext->actions[LV_BTN_ACTION_RELEASE] && lv_btn_get_state(btn) != LV_BTN_STATE_INACTIVE) { - valid = ext->actions[LV_BTN_ACTION_RELEASE](btn); - } - } - } - } - - return valid; -} - /*===================== * Setter functions *====================*/ @@ -354,28 +243,118 @@ lv_style_t * lv_btn_get_style(lv_obj_t * btn, lv_btn_state_t state) * STATIC FUNCTIONS **********************/ -#if 0 /** - * Handle the drawing related tasks of the buttons + * Signal function of the button * @param btn pointer to a button object - * @param mask 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 true/false, depends on 'mode' + * @param sign a signal type from lv_signal_t enum + * @param param pointer to a signal specific variable + * @return LV_RES_OK: the object is not deleted in the function; LV_RES_INV: the object is deleted */ -static bool lv_btn_design(lv_obj_t * btn, const area_t * mask, lv_design_mode_t mode) +static lv_res_t lv_btn_signal(lv_obj_t * btn, lv_signal_t sign, void * param) { + lv_res_t res; - /* Because of the radius it is not sure the area is covered*/ - if(mode == LV_DESIGN_COVER_CHK) { - return false; + /* Include the ancient signal function */ + res = ancestor_signal(btn, sign, param); - } else if(mode == LV_DESIGN_DRAW_MAIN || mode == LV_DESIGN_DRAW_POST) { + /* The object can be deleted so check its validity and then + * make the object specific signal handling */ + if(res == LV_RES_OK) { + lv_btn_ext_t * ext = lv_obj_get_ext_attr(btn); + lv_btn_state_t state = lv_btn_get_state(btn); + bool tgl = lv_btn_get_toggle(btn); + if(sign == LV_SIGNAL_PRESSED) { + /*Refresh the state*/ + if(ext->state == LV_BTN_STATE_RELEASED) { + lv_btn_set_state(btn, LV_BTN_STATE_PRESSED); + } else if(ext->state == LV_BTN_STATE_TGL_RELEASED) { + lv_btn_set_state(btn, LV_BTN_STATE_TGL_PRESSED); + } + + ext->long_press_action_executed = 0; + /*Call the press action, 'param' is the caller indev_proc*/ + if(ext->actions[LV_BTN_ACTION_PRESS] && state != LV_BTN_STATE_INACTIVE) { + res = ext->actions[LV_BTN_ACTION_PRESS](btn); + } + } + else if(sign == LV_SIGNAL_PRESS_LOST) { + /*Refresh the state*/ + if(ext->state == LV_BTN_STATE_PRESSED) lv_btn_set_state(btn, LV_BTN_STATE_RELEASED); + else if(ext->state == LV_BTN_STATE_TGL_PRESSED) lv_btn_set_state(btn, LV_BTN_STATE_TGL_RELEASED); + } + 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_PRESSED) lv_btn_set_state(btn, LV_BTN_STATE_RELEASED); + else if(ext->state == LV_BTN_STATE_TGL_PRESSED) lv_btn_set_state(btn, LV_BTN_STATE_TGL_RELEASED); + } + } + else if(sign == LV_SIGNAL_RELEASED) { + /*If not dragged and it was not long press action then + *change state and run the action*/ + if(lv_indev_is_dragging(param) == false && ext->long_press_action_executed == 0) { + if(ext->state == LV_BTN_STATE_PRESSED && tgl == false) { + lv_btn_set_state(btn, LV_BTN_STATE_RELEASED); + } else if(ext->state == LV_BTN_STATE_TGL_PRESSED && tgl == false) { + lv_btn_set_state(btn, LV_BTN_STATE_TGL_RELEASED); + } else if(ext->state == LV_BTN_STATE_PRESSED && tgl == true) { + lv_btn_set_state(btn, LV_BTN_STATE_TGL_RELEASED); + } else if(ext->state == LV_BTN_STATE_TGL_PRESSED && tgl == true) { + lv_btn_set_state(btn, LV_BTN_STATE_RELEASED); + } + + if(ext->actions[LV_BTN_ACTION_RELEASE] && state != LV_BTN_STATE_INACTIVE) { + res = ext->actions[LV_BTN_ACTION_RELEASE](btn); + } + } else { /*If dragged change back the state*/ + if(ext->state == LV_BTN_STATE_PRESSED) { + lv_btn_set_state(btn, LV_BTN_STATE_RELEASED); + } else if(ext->state == LV_BTN_STATE_TGL_PRESSED) { + lv_btn_set_state(btn, LV_BTN_STATE_TGL_RELEASED); + } + } + } + else if(sign == LV_SIGNAL_LONG_PRESS) { + if(ext->actions[LV_BTN_ACTION_LONG_PRESS] && state != LV_BTN_STATE_INACTIVE) { + ext->long_press_action_executed = 1; + res = ext->actions[LV_BTN_ACTION_LONG_PRESS](btn); + } + } + else if(sign == LV_SIGNAL_LONG_PRESS_REP) { + if(ext->actions[LV_BTN_ACTION_LONG_PRESS_REPEATE] && state != LV_BTN_STATE_INACTIVE) { + res = ext->actions[LV_BTN_ACTION_LONG_PRESS_REPEATE](btn); + } + } + else if(sign == LV_SIGNAL_CONTROLL) { + char c = *((char*)param); + if(c == LV_GROUP_KEY_RIGHT || c == LV_GROUP_KEY_UP) { + if(lv_btn_get_toggle(btn) != false) lv_btn_set_state(btn, LV_BTN_STATE_TGL_RELEASED); + if(ext->actions[LV_BTN_ACTION_RELEASE] && lv_btn_get_state(btn) != LV_BTN_STATE_INACTIVE) { + res = ext->actions[LV_BTN_ACTION_RELEASE](btn); + } + } else if(c == LV_GROUP_KEY_LEFT || c == LV_GROUP_KEY_DOWN) { + if(lv_btn_get_toggle(btn) != false) lv_btn_set_state(btn, LV_BTN_STATE_RELEASED); + if(ext->actions[LV_BTN_ACTION_RELEASE] && lv_btn_get_state(btn) != LV_BTN_STATE_INACTIVE) { + res = ext->actions[LV_BTN_ACTION_RELEASE](btn); + } + } else if(c == LV_GROUP_KEY_ENTER) { + if(lv_btn_get_toggle(btn) != false) { + lv_btn_state_t state = lv_btn_get_state(btn); + if(state == LV_BTN_STATE_RELEASED) lv_btn_set_state(btn, LV_BTN_STATE_TGL_RELEASED); + else if(state == LV_BTN_STATE_PRESSED) lv_btn_set_state(btn, LV_BTN_STATE_TGL_PRESSED); + else if(state == LV_BTN_STATE_TGL_RELEASED) lv_btn_set_state(btn, LV_BTN_STATE_RELEASED); + else if(state == LV_BTN_STATE_TGL_PRESSED) lv_btn_set_state(btn, LV_BTN_STATE_PRESSED); + } + if(ext->actions[LV_BTN_ACTION_RELEASE] && lv_btn_get_state(btn) != LV_BTN_STATE_INACTIVE) { + res = ext->actions[LV_BTN_ACTION_RELEASE](btn); + } + } + } } - return true; + + return res; } -#endif + + #endif diff --git a/lv_objx/lv_btn.h b/lv_objx/lv_btn.h index f54d02dc6..c1cd254ae 100644 --- a/lv_objx/lv_btn.h +++ b/lv_objx/lv_btn.h @@ -78,14 +78,6 @@ typedef struct */ lv_obj_t * lv_btn_create(lv_obj_t * par, lv_obj_t * copy); -/** - * Signal function of the button - * @param btn pointer to a button object - * @param sign a signal type from lv_signal_t enum - * @param param pointer to a signal specific variable - */ -bool lv_btn_signal(lv_obj_t * btn, lv_signal_t sign, void * param); - /** * Enable the toggled states * @param btn pointer to a button object @@ -155,7 +147,6 @@ lv_action_t lv_btn_get_action(lv_obj_t * btn, lv_btn_action_t type); */ lv_style_t * lv_btn_get_style(lv_obj_t * btn, lv_btn_state_t state); - /**************************** * TRANSPARENT API FUNCTIONS ***************************/ @@ -199,7 +190,7 @@ static inline lv_cont_layout_t lv_btn_get_layout(lv_obj_t * btn) */ static inline bool lv_btn_get_hor_fit(lv_obj_t * btn) { - return lv_cont_get_fit_hor(btn); + return lv_cont_get_hor_fit(btn); } /** @@ -209,7 +200,7 @@ static inline bool lv_btn_get_hor_fit(lv_obj_t * btn) */ static inline bool lv_btn_get_ver_fit(lv_obj_t * btn) { - return lv_cont_get_fit_ver(btn); + return lv_cont_get_ver_fit(btn); } /********************** diff --git a/lv_objx/lv_btnm.c b/lv_objx/lv_btnm.c index 5285ca654..9f8142eb1 100644 --- a/lv_objx/lv_btnm.c +++ b/lv_objx/lv_btnm.c @@ -383,7 +383,7 @@ void lv_btnm_set_toggle(lv_obj_t * btnm, bool en, uint16_t id) * @param tgl_pr pointer to a style for toggled pressed state * @param ina pointer to a style for inactive state */ -void lv_btnm_set_style(lv_obj_t *btnm, lv_style_t *rel, lv_style_t *pr, +void lv_btnm_set_style_btn(lv_obj_t *btnm, lv_style_t *rel, lv_style_t *pr, lv_style_t *tgl_rel, lv_style_t *tgl_pr, lv_style_t *ina) @@ -431,7 +431,7 @@ lv_btnm_action_t lv_btnm_get_action(lv_obj_t * btnm) * @param state style in this state (LV_BTN_STATE_PR or LV_BTN_STATE_REL) * @return pointer the button style in the given state */ -lv_style_t * lv_btnm_get_button_style(lv_obj_t * btnm, lv_btn_state_t state) +lv_style_t * lv_btnm_get_style_btn(lv_obj_t * btnm, lv_btn_state_t state) { if(state >= LV_BTN_STATE_NUM) return lv_obj_get_style(btnm); @@ -497,18 +497,18 @@ static bool lv_btnm_design(lv_obj_t * btnm, const area_t * mask, lv_design_mode_ btn_h = area_get_height(&area_tmp); /*Load the style*/ - if(button_is_inactive(ext->map_p[txt_i])) btn_style = lv_btnm_get_button_style(btnm, LV_BTN_STATE_INACTIVE); - else if(btn_i != ext->button_id_pressed && btn_i != ext->button_id_toggled) btn_style = lv_btnm_get_button_style(btnm, LV_BTN_STATE_RELEASED); - else if(btn_i == ext->button_id_pressed && btn_i != ext->button_id_toggled) btn_style = lv_btnm_get_button_style(btnm, LV_BTN_STATE_PRESSED); - else if(btn_i != ext->button_id_pressed && btn_i == ext->button_id_toggled) btn_style = lv_btnm_get_button_style(btnm, LV_BTN_STATE_TGL_RELEASED); - else if(btn_i == ext->button_id_pressed && btn_i == ext->button_id_toggled) btn_style = lv_btnm_get_button_style(btnm, LV_BTN_STATE_TGL_PRESSED); + if(button_is_inactive(ext->map_p[txt_i])) btn_style = lv_btnm_get_style_btn(btnm, LV_BTN_STATE_INACTIVE); + else if(btn_i != ext->button_id_pressed && btn_i != ext->button_id_toggled) btn_style = lv_btnm_get_style_btn(btnm, LV_BTN_STATE_RELEASED); + else if(btn_i == ext->button_id_pressed && btn_i != ext->button_id_toggled) btn_style = lv_btnm_get_style_btn(btnm, LV_BTN_STATE_PRESSED); + else if(btn_i != ext->button_id_pressed && btn_i == ext->button_id_toggled) btn_style = lv_btnm_get_style_btn(btnm, LV_BTN_STATE_TGL_RELEASED); + else if(btn_i == ext->button_id_pressed && btn_i == ext->button_id_toggled) btn_style = lv_btnm_get_style_btn(btnm, LV_BTN_STATE_TGL_PRESSED); lv_draw_rect(&area_tmp, mask, btn_style); /*Calculate the size of the text*/ const font_t * font = btn_style->text.font; point_t txt_size; txt_get_size(&txt_size, ext->map_p[txt_i], font, - btn_style->text.space_letter, btn_style->text.space_line, + btn_style->text.letter_space, btn_style->text.line_space, area_get_width(&area_btnm), TXT_FLAG_NONE); area_tmp.x1 += (btn_w - txt_size.x) / 2; diff --git a/lv_objx/lv_btnm.h b/lv_objx/lv_btnm.h index d5e461413..94422a8e1 100644 --- a/lv_objx/lv_btnm.h +++ b/lv_objx/lv_btnm.h @@ -120,7 +120,7 @@ void lv_btnm_set_toggle(lv_obj_t * btnm, bool en, uint16_t id); * @param tgl_pr_style pointer to a style for toggled pressed state * @param inactive_style pointer to a style for inactive state */ -void lv_btnm_set_style(lv_obj_t *btnm, lv_style_t *rel, lv_style_t *pr, +void lv_btnm_set_style_btn(lv_obj_t *btnm, lv_style_t *rel, lv_style_t *pr, lv_style_t *tgl_rel, lv_style_t *tgl_pr, lv_style_t *ina); /** @@ -143,7 +143,32 @@ lv_btnm_action_t lv_btnm_get_action(lv_obj_t * btnm); * @param state style in this state (LV_BTN_STATE_PR or LV_BTN_STATE_REL) * @return pointer the button style in the given state */ -lv_style_t * lv_btnm_get_button_style(lv_obj_t * btnm, lv_btn_state_t state); +lv_style_t * lv_btnm_get_style_btn(lv_obj_t * btnm, lv_btn_state_t state); + + +/**************************** + * TRANSPARENT API FUNCTIONS + ***************************/ + +/** + * Set the style of a button matrix's background + * @param btnm pointer to a button matrix object + * @param bg pointer to the background style + */ +static inline void lv_btnm_set_style_bg(lv_obj_t *btnm, lv_style_t * bg) +{ + lv_obj_set_style(btnm, bg); +} + +/** + * Get the style of a button matrix + * @param btnm pointer to a button matrix object + * @return pointer to the backgrond style + */ +static inline lv_style_t * lv_btnm_get_style_bg(lv_obj_t *btnm) +{ + return lv_obj_get_style(btnm); +} /********************** * MACROS diff --git a/lv_objx/lv_cb.c b/lv_objx/lv_cb.c index 459744055..d980149e8 100644 --- a/lv_objx/lv_cb.c +++ b/lv_objx/lv_cb.c @@ -25,12 +25,14 @@ **********************/ static bool lv_cb_design(lv_obj_t * cb, const area_t * mask, lv_design_mode_t mode); static bool lv_bullet_design(lv_obj_t * bullet, const area_t * mask, lv_design_mode_t mode); +static lv_res_t lv_cb_signal(lv_obj_t * cb, lv_signal_t sign, void * param); /********************** * STATIC VARIABLES **********************/ -static lv_design_func_t ancestor_bg_design_f; -static lv_design_func_t ancestor_bullet_design_f; +static lv_design_func_t ancestor_bg_design; +static lv_design_func_t ancestor_bullet_design; +static lv_signal_func_t ancestor_signal; /********************** * MACROS @@ -55,30 +57,21 @@ lv_obj_t * lv_cb_create(lv_obj_t * par, lv_obj_t * copy) /*Create the ancestor basic object*/ lv_obj_t * new_cb = lv_btn_create(par, copy); dm_assert(new_cb); + if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_func(new_cb); + if(ancestor_bg_design == NULL) ancestor_bg_design = lv_obj_get_design_func(new_cb); lv_cb_ext_t * ext = lv_obj_allocate_ext_attr(new_cb, sizeof(lv_cb_ext_t)); dm_assert(ext); ext->bullet = NULL; ext->label = NULL; - if(ancestor_bg_design_f == NULL) ancestor_bg_design_f = lv_obj_get_design_func(new_cb); - lv_obj_set_signal_func(new_cb, lv_cb_signal); lv_obj_set_design_func(new_cb, lv_cb_design); /*Init the new checkbox object*/ if(copy == NULL) { ext->bullet = lv_btn_create(new_cb, NULL); - lv_btn_set_style(new_cb, &lv_style_transp, &lv_style_transp, - &lv_style_transp, &lv_style_transp, - &lv_style_transp); - - lv_cont_set_layout(new_cb, LV_CONT_LAYOUT_ROW_M); - lv_cont_set_fit(new_cb, true, true); - lv_btn_set_toggle(new_cb, true); - - if(ancestor_bullet_design_f == NULL) ancestor_bullet_design_f = 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); lv_btn_set_style(ext->bullet, &lv_style_pretty, &lv_style_pretty_color, &lv_style_btn_on_released, &lv_style_btn_on_pressed, @@ -86,7 +79,12 @@ lv_obj_t * lv_cb_create(lv_obj_t * par, lv_obj_t * copy) ext->label = lv_label_create(new_cb, NULL); lv_obj_set_style(ext->label, NULL); /*Inherit the style of the parent*/ - lv_label_set_text(ext->label, "Check box"); + + lv_cb_set_style_bg(new_cb, &lv_style_transp); + lv_cb_set_text(new_cb, "Check box"); + lv_cont_set_layout(new_cb, LV_CONT_LAYOUT_ROW_M); + lv_cont_set_fit(new_cb, true, true); + lv_btn_set_toggle(new_cb, true); lv_obj_refresh_style(new_cb); } else { @@ -103,47 +101,6 @@ lv_obj_t * lv_cb_create(lv_obj_t * par, lv_obj_t * copy) return new_cb; } - -/** - * Signal function of the check box - * @param cb pointer to a check box object - * @param sign a signal type from lv_signal_t enum - * @param param pointer to a signal specific variable - */ -bool lv_cb_signal(lv_obj_t * cb, lv_signal_t sign, void * param) -{ - bool valid; - - /* Include the ancient signal function */ - valid = lv_btn_signal(cb, sign, param); - - lv_cb_ext_t * ext = lv_obj_get_ext_attr(cb); - lv_style_t * style = lv_obj_get_style(cb); - - /* The object can be deleted so check its validity and then - * make the object specific signal handling */ - if(valid != false) { - if(sign == LV_SIGNAL_STYLE_CHG) { - lv_obj_set_size(ext->bullet, font_get_height(style->text.font), font_get_height(style->text.font)); - lv_btn_set_state(ext->bullet, lv_btn_get_state(cb)); - } 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_CONTROLL) { - 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 || - c == LV_GROUP_KEY_ENTER) { - lv_btn_set_state(ext->bullet, lv_btn_get_state(cb)); - } - } - } - - return valid; -} - - /*===================== * Setter functions *====================*/ @@ -210,7 +167,7 @@ static bool lv_cb_design(lv_obj_t * cb, const area_t * mask, lv_design_mode_t mo { if(mode == LV_DESIGN_COVER_CHK) { /*Return false if the object is not covers the mask_p area*/ - return ancestor_bg_design_f(cb, mask, mode); + return 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_btn_ext_t * bullet_ext = lv_obj_get_ext_attr(cb_ext->bullet); @@ -218,10 +175,10 @@ static bool lv_cb_design(lv_obj_t * cb, const area_t * mask, lv_design_mode_t mo /*Be sure the state of the bullet is the same as the parent button*/ bullet_ext->state = cb_ext->bg_btn.state; - return ancestor_bg_design_f(cb, mask, mode); + return ancestor_bg_design(cb, mask, mode); } else { - return ancestor_bg_design_f(cb, mask, mode); + return ancestor_bg_design(cb, mask, mode); } return true; @@ -240,7 +197,7 @@ static bool lv_cb_design(lv_obj_t * cb, const area_t * mask, lv_design_mode_t mo static bool lv_bullet_design(lv_obj_t * bullet, const area_t * mask, lv_design_mode_t mode) { if(mode == LV_DESIGN_COVER_CHK) { - return ancestor_bullet_design_f(bullet, mask, mode); + return ancestor_bullet_design(bullet, mask, mode); } else if(mode == LV_DESIGN_DRAW_MAIN) { #if LV_OBJ_GROUP != 0 /* If the check box is the active in a group and @@ -258,16 +215,57 @@ static bool lv_bullet_design(lv_obj_t * bullet, const area_t * mask, lv_design_m } } #endif - ancestor_bullet_design_f(bullet, mask, mode); + ancestor_bullet_design(bullet, mask, mode); #if LV_OBJ_GROUP != 0 bullet->style_p = style_ori; /*Revert the style*/ #endif } else if(mode == LV_DESIGN_DRAW_POST) { - ancestor_bullet_design_f(bullet, mask, mode); + ancestor_bullet_design(bullet, mask, mode); } return true; } + +/** + * Signal function of the check box + * @param cb pointer to a check box object + * @param sign a signal type from lv_signal_t enum + * @param param pointer to a signal specific variable + * @return LV_RES_OK: the object is not deleted in the function; LV_RES_INV: the object is deleted + */ +static lv_res_t lv_cb_signal(lv_obj_t * cb, lv_signal_t sign, void * param) +{ + lv_res_t res; + + /* Include the ancient signal function */ + res = ancestor_signal(cb, sign, param); + + lv_cb_ext_t * ext = lv_obj_get_ext_attr(cb); + lv_style_t * style = lv_obj_get_style(cb); + + /* The object can be deleted so check its validity and then + * make the object specific signal handling */ + if(res == LV_RES_OK) { + if(sign == LV_SIGNAL_STYLE_CHG) { + lv_obj_set_size(ext->bullet, font_get_height(style->text.font), font_get_height(style->text.font)); + lv_btn_set_state(ext->bullet, lv_btn_get_state(cb)); + } 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_CONTROLL) { + 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 || + c == LV_GROUP_KEY_ENTER) { + lv_btn_set_state(ext->bullet, lv_btn_get_state(cb)); + } + } + } + + return res; +} + #endif diff --git a/lv_objx/lv_cb.h b/lv_objx/lv_cb.h index c61b055dd..ce34f894a 100644 --- a/lv_objx/lv_cb.h +++ b/lv_objx/lv_cb.h @@ -58,14 +58,6 @@ typedef struct */ lv_obj_t * lv_cb_create(lv_obj_t * par, lv_obj_t * copy); -/** - * Signal function of the check box - * @param cb pointer to a check box object - * @param sign a signal type from lv_signal_t enum - * @param param pointer to a signal specific variable - */ -bool lv_cb_signal(lv_obj_t * cb, lv_signal_t sign, void * param); - /** * Set the text of a check box * @param cb pointer to a check box @@ -73,7 +65,6 @@ bool lv_cb_signal(lv_obj_t * cb, lv_signal_t sign, void * param); */ void lv_cb_set_text(lv_obj_t * cb, const char * txt); - /** * Set styles of a checkbox's bullet is each state. Use NULL for any style to leave it unchanged * @param cb pointer to checkbox object @@ -140,14 +131,12 @@ static inline void lv_cb_set_style_bg(lv_obj_t *cb, lv_style_t *bg) lv_btn_set_style(cb, bg, bg, bg, bg, bg); } - - /** * Get the current state of the check box * @param cb pointer to a check box object * @return true: checked; false: not checked */ -static inline bool lv_cb_is_checked(lv_obj_t * cb) +static inline bool lv_cb_get_checked(lv_obj_t * cb) { return lv_btn_get_state(cb) == LV_BTN_STATE_RELEASED ? true : false; } diff --git a/lv_objx/lv_cont.c b/lv_objx/lv_cont.c index 12c653ad0..3cdb99bf8 100644 --- a/lv_objx/lv_cont.c +++ b/lv_objx/lv_cont.c @@ -33,10 +33,7 @@ /********************** * STATIC PROTOTYPES **********************/ -#if 0 -static bool lv_cont_design(lv_obj_t * cont, const area_t * mask, lv_design_mode_t mode); -#endif - +static lv_res_t lv_cont_signal(lv_obj_t * cont, lv_signal_t sign, void * param); static void lv_cont_refr_layout(lv_obj_t * cont); static void lv_cont_layout_col(lv_obj_t * cont); static void lv_cont_layout_row(lv_obj_t * cont); @@ -48,6 +45,7 @@ static void lv_cont_refr_autofit(lv_obj_t * cont); /********************** * STATIC VARIABLES **********************/ +static lv_signal_func_t ancestor_signal; /********************** * MACROS @@ -70,20 +68,22 @@ static void lv_cont_refr_autofit(lv_obj_t * cont); lv_obj_t * lv_cont_create(lv_obj_t * par, lv_obj_t * copy) { /*Create a basic object*/ - lv_obj_t * new_rect = lv_obj_create(par, copy); - dm_assert(new_rect); - lv_obj_allocate_ext_attr(new_rect, sizeof(lv_cont_ext_t)); - lv_cont_ext_t * ext = lv_obj_get_ext_attr(new_rect); + lv_obj_t * new_cont = lv_obj_create(par, copy); + dm_assert(new_cont); + if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_func(new_cont); + + lv_obj_allocate_ext_attr(new_cont, sizeof(lv_cont_ext_t)); + lv_cont_ext_t * ext = lv_obj_get_ext_attr(new_cont); dm_assert(ext); ext->hor_fit = 0; ext->ver_fit = 0; ext->layout = LV_CONT_LAYOUT_OFF; - lv_obj_set_signal_func(new_rect, lv_cont_signal); + lv_obj_set_signal_func(new_cont, lv_cont_signal); /*Init the new container*/ if(copy == NULL) { - lv_obj_set_style(new_rect, &lv_style_plain); + lv_cont_set_style(new_cont, &lv_style_plain); } /*Copy an existing object*/ else { @@ -93,45 +93,10 @@ lv_obj_t * lv_cont_create(lv_obj_t * par, lv_obj_t * copy) ext->layout = copy_ext->layout; /*Refresh the style with new signal function*/ - lv_obj_refresh_style(new_rect); - + lv_obj_refresh_style(new_cont); } - return new_rect; -} - -/** - * Signal function of the container - * @param cont pointer to a container object - * @param sign a signal type from lv_signal_t enum - * @param param pointer to a signal specific variable - */ -bool lv_cont_signal(lv_obj_t * cont, lv_signal_t sign, void * param) -{ - bool valid; - - /* Include the ancient signal function */ - valid = lv_obj_signal(cont, sign, param); - - /* The object can be deleted so check its validity and then - * make the object specific signal handling */ - if(valid != false) { - if(sign == LV_SIGNAL_STYLE_CHG) { /*Recalculate the padding if the style changed*/ - lv_cont_refr_layout(cont); - lv_cont_refr_autofit(cont); - } else if(sign == LV_SIGNAL_CHILD_CHG) { - lv_cont_refr_layout(cont); - lv_cont_refr_autofit(cont); - } else if(sign == LV_SIGNAL_CORD_CHG) { - if(lv_obj_get_width(cont) != area_get_width(param) || - lv_obj_get_height(cont) != area_get_height(param)) { - lv_cont_refr_layout(cont); - lv_cont_refr_autofit(cont); - } - } - } - - return valid; + return new_cont; } /*===================== @@ -139,7 +104,7 @@ bool lv_cont_signal(lv_obj_t * cont, lv_signal_t sign, void * param) *====================*/ /** - * Set the layout on a container + * Set a layout on a container * @param cont pointer to a container object * @param layout a layout from 'lv_cont_layout_t' */ @@ -191,7 +156,7 @@ lv_cont_layout_t lv_cont_get_layout(lv_obj_t * cont) * @param cont pointer to a container object * @return true: horizontal fit is enabled; false: disabled */ -bool lv_cont_get_fit_hor(lv_obj_t * cont) +bool lv_cont_get_hor_fit(lv_obj_t * cont) { lv_cont_ext_t * ext = lv_obj_get_ext_attr(cont); return ext->hor_fit == 0 ? false : true; @@ -202,7 +167,7 @@ bool lv_cont_get_fit_hor(lv_obj_t * cont) * @param cont pointer to a container object * @return true: vertical fit is enabled; false: disabled */ -bool lv_cont_get_fit_ver(lv_obj_t * cont) +bool lv_cont_get_ver_fit(lv_obj_t * cont) { lv_cont_ext_t * ext = lv_obj_get_ext_attr(cont); return ext->ver_fit == 0 ? false : true; @@ -212,31 +177,41 @@ bool lv_cont_get_fit_ver(lv_obj_t * cont) /********************** * STATIC FUNCTIONS **********************/ -#if 0 + /** - * Handle the drawing related tasks of the containers - * @param cont pointer to an object - * @param mask 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 true/false, depends on 'mode' + * Signal function of the container + * @param cont pointer to a container object + * @param sign a signal type from lv_signal_t enum + * @param param pointer to a signal specific variable + * @return LV_RES_OK: the object is not deleted in the function; LV_RES_INV: the object is deleted */ -static bool lv_cont_design(lv_obj_t * cont, const area_t * mask, lv_design_mode_t mode) +static lv_res_t lv_cont_signal(lv_obj_t * cont, lv_signal_t sign, void * param) { - if(mode == LV_DESIGN_COVER_CHK) { + lv_res_t res; - return false; - } else if(mode == LV_DESIGN_DRAW_MAIN) { - - - } else if(mode == LV_DESIGN_DRAW_POST) { + /* Include the ancient signal function */ + res = ancestor_signal(cont, sign, param); + /* The object can be deleted so check its validity and then + * make the object specific signal handling */ + if(res == LV_RES_OK) { + if(sign == LV_SIGNAL_STYLE_CHG) { /*Recalculate the padding if the style changed*/ + lv_cont_refr_layout(cont); + lv_cont_refr_autofit(cont); + } else if(sign == LV_SIGNAL_CHILD_CHG) { + lv_cont_refr_layout(cont); + lv_cont_refr_autofit(cont); + } else if(sign == LV_SIGNAL_CORD_CHG) { + if(lv_obj_get_width(cont) != area_get_width(param) || + lv_obj_get_height(cont) != area_get_height(param)) { + lv_cont_refr_layout(cont); + lv_cont_refr_autofit(cont); + } + } } - return true; + + return res; } -#endif /** @@ -247,7 +222,7 @@ static void lv_cont_refr_layout(lv_obj_t * cont) { lv_cont_layout_t type = lv_cont_get_layout(cont); - /*'rect' has to be at least 1 child*/ + /*'cont' has to be at least 1 child*/ if(lv_obj_get_child(cont, NULL) == NULL) return; if(type == LV_CONT_LAYOUT_OFF) return; diff --git a/lv_objx/lv_cont.h b/lv_objx/lv_cont.h index 7e84fad59..a1bf3b225 100644 --- a/lv_objx/lv_cont.h +++ b/lv_objx/lv_cont.h @@ -54,7 +54,6 @@ typedef struct * GLOBAL PROTOTYPES **********************/ - /** * Create a container objects * @param par pointer to an object, it will be the parent of the new container @@ -63,14 +62,6 @@ typedef struct */ lv_obj_t * lv_cont_create(lv_obj_t * par, lv_obj_t * copy); -/** - * Signal function of the container - * @param cont pointer to a container object - * @param sign a signal type from lv_signal_t enum - * @param param pointer to a signal specific variable - */ -bool lv_cont_signal(lv_obj_t * cont, lv_signal_t sign, void * param); - /** * Set the layout on a container * @param cont pointer to a container object @@ -99,14 +90,38 @@ lv_cont_layout_t lv_cont_get_layout(lv_obj_t * cont); * @param cont pointer to a container object * @return true: horizontal fit is enabled; false: disabled */ -bool lv_cont_get_fit_hor(lv_obj_t * cont); +bool lv_cont_get_hor_fit(lv_obj_t * cont); /** * Get vertical fit enable attribute of a button * @param btn pointer to a button object * @return true: vertical padding is enabled; false: disabled */ -bool lv_cont_get_fit_ver(lv_obj_t * cont); +bool lv_cont_get_ver_fit(lv_obj_t * cont); + +/**************************** + * TRANSPARENT API FUNCTIONS + ***************************/ + +/** + * 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) +{ + lv_obj_set_style(cont, style); +} + +/** + * Get the style of a container + * @param cont pointer to a container object + * @return pointer to the container's style + */ +static inline void lv_cont_get_style(lv_obj_t *cont, lv_style_t * style) +{ + lv_obj_set_style(cont, style); +} /********************** * MACROS diff --git a/lv_objx/lv_ddlist.c b/lv_objx/lv_ddlist.c index de6be348a..dac5b8ee3 100644 --- a/lv_objx/lv_ddlist.c +++ b/lv_objx/lv_ddlist.c @@ -29,14 +29,17 @@ * STATIC PROTOTYPES **********************/ static bool lv_ddlist_design(lv_obj_t * ddlist, const area_t * mask, lv_design_mode_t mode); +static bool lv_ddlist_scrl_signal(lv_obj_t * scrl, lv_signal_t sign, void * param); static lv_res_t lv_ddlist_rel_action(lv_obj_t * ddlist); static void lv_ddlist_refr_size(lv_obj_t * ddlist, uint16_t anim_time); -static void lv_ddlist_pos_act_option(lv_obj_t * ddlist); +static void lv_ddlist_pos_current_option(lv_obj_t * ddlist); /********************** * STATIC VARIABLES **********************/ -static lv_design_func_t ancestor_design_f; +static lv_signal_func_t ancestor_signal; +static lv_signal_func_t ancestor_scrl_signal; +static lv_design_func_t ancestor_design; static const char * def_options[] = {"Option 1", "Option 2", "Option 3", ""}; /********************** * MACROS @@ -61,6 +64,9 @@ lv_obj_t * lv_ddlist_create(lv_obj_t * par, lv_obj_t * copy) /*Create the ancestor drop down list*/ lv_obj_t * new_ddlist = lv_page_create(par, copy); dm_assert(new_ddlist); + 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_design == NULL) ancestor_design = lv_obj_get_design_func(new_ddlist); /*Allocate the drop down list type specific extended data*/ lv_ddlist_ext_t * ext = lv_obj_allocate_ext_attr(new_ddlist, sizeof(lv_ddlist_ext_t)); @@ -77,23 +83,21 @@ lv_obj_t * lv_ddlist_create(lv_obj_t * par, lv_obj_t * copy) ext->selected_style = &lv_style_plain_color; /*The signal and design functions are not copied so set them here*/ - if(ancestor_design_f == NULL) ancestor_design_f = lv_obj_get_design_func(new_ddlist); - lv_obj_set_signal_func(new_ddlist, lv_ddlist_signal); + lv_obj_set_signal_func(lv_page_get_scrl(new_ddlist), lv_ddlist_scrl_signal); lv_obj_set_design_func(new_ddlist, lv_ddlist_design); /*Init the new drop down list drop down list*/ if(copy == NULL) { lv_obj_t * scrl = lv_page_get_scrl(new_ddlist); lv_obj_set_drag(scrl, false); - lv_obj_set_style(scrl, &lv_style_transp); - lv_cont_set_fit(scrl, true, true); + lv_page_set_scrl_fit(new_ddlist, true, true); ext->options_label = lv_label_create(new_ddlist, NULL); lv_cont_set_fit(new_ddlist, true, false); - lv_page_set_rel_action(new_ddlist, lv_ddlist_rel_action); + lv_page_set_release_action(new_ddlist, lv_ddlist_rel_action); lv_page_set_sb_mode(new_ddlist, LV_PAGE_SB_MODE_DRAG); - lv_obj_set_style(new_ddlist, &lv_style_pretty); + lv_ddlist_set_style(new_ddlist, &lv_style_pretty, NULL, &lv_style_plain_color); lv_ddlist_set_options(new_ddlist, def_options); } /*Copy an existing drop down list*/ @@ -127,20 +131,22 @@ bool lv_ddlist_signal(lv_obj_t * ddlist, lv_signal_t sign, void * param) bool valid; /* Include the ancient signal function */ - valid = lv_page_signal(ddlist, sign, param); + valid = ancestor_signal(ddlist, sign, param); /* The object can be deleted so check its validity and then * make the object specific signal handling */ if(valid != false) { - if(sign == LV_SIGNAL_STYLE_CHG) { + if(sign == LV_SIGNAL_STYLE_CHG) { lv_ddlist_refr_size(ddlist, 0); - } else if(sign == LV_SIGNAL_FOCUS) { + lv_obj_t *scrl = lv_page_get_scrl(ddlist); + lv_obj_refresh_ext_size(scrl); /*Because of the wider selected rectangle*/ + } else if(sign == LV_SIGNAL_FOCUS) { lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist); - if(ext->opened == false) { - ext->opened = true; - lv_ddlist_refr_size(ddlist, true); - } - } else if(sign == LV_SIGNAL_DEFOCUS) { + if(ext->opened == false) { + ext->opened = true; + lv_ddlist_refr_size(ddlist, true); + } + } else if(sign == LV_SIGNAL_DEFOCUS) { lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist); if(ext->opened != false) { ext->opened = false; @@ -173,7 +179,7 @@ bool lv_ddlist_signal(lv_obj_t * ddlist, lv_signal_t sign, void * param) } } } - + return valid; } @@ -239,7 +245,7 @@ void lv_ddlist_set_selected(lv_obj_t * ddlist, uint16_t sel_opt) /*Move the list to show the current option*/ if(ext->opened == 0) { - lv_ddlist_pos_act_option(ddlist); + lv_ddlist_pos_current_option(ddlist); } else { lv_obj_invalidate(ddlist); } @@ -250,10 +256,10 @@ void lv_ddlist_set_selected(lv_obj_t * ddlist, uint16_t sel_opt) * @param ddlist pointer to a drop down list * @param cb pointer to a call back function */ -void lv_ddlist_set_action(lv_obj_t * ddlist, lv_action_t cb) +void lv_ddlist_set_action(lv_obj_t * ddlist, lv_action_t action) { lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist); - ext->callback = cb; + ext->callback = action; } /** @@ -280,18 +286,6 @@ void lv_ddlist_set_anim_time(lv_obj_t * ddlist, uint16_t anim_time) ext->anim_time = anim_time; } -/** - * Set the style of the rectangle on the selected option - * @param ddlist pointer to a drop down list object - * @param style pointer the new style of the select rectangle - */ -void lv_ddlist_set_selected_style(lv_obj_t * ddlist, lv_style_t * style) -{ - lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist); - ext->selected_style = style; - -} - /** * Open the drop down list with or without animation * @param ddlist pointer to drop down list object @@ -301,6 +295,7 @@ void lv_ddlist_open(lv_obj_t * ddlist, bool anim) { lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist); ext->opened = 1; + lv_obj_set_drag(lv_page_get_scrl(ddlist), true); lv_ddlist_refr_size(ddlist, anim ? ext->anim_time : 0); } @@ -313,9 +308,27 @@ void lv_ddlist_close(lv_obj_t * ddlist, bool anim) { lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist); ext->opened = 0; + lv_obj_set_drag(lv_page_get_scrl(ddlist), false); lv_ddlist_refr_size(ddlist, anim ? ext->anim_time : 0); } +/** + * Set the style of a drop down list + * @param ddlist pointer to a drop down list object + * @param bg pointer to the new style of the background + * @param sb pointer to the new style of the scrollbars (only visible with fix height) + * @param sel pointer to the new style of the select rectangle + */ +void lv_ddlist_set_style(lv_obj_t * ddlist, lv_style_t *bg, lv_style_t *sb, lv_style_t *sel) +{ + lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist); + ext->selected_style = sel; + lv_obj_set_style(ext->options_label, bg); + + lv_page_set_style(ddlist, bg, &lv_style_transp_tight, sb); + +} + /*===================== * Getter functions *====================*/ @@ -420,38 +433,68 @@ static bool lv_ddlist_design(lv_obj_t * ddlist, const area_t * mask, lv_design_m { /*Return false if the object is not covers the mask_p area*/ if(mode == LV_DESIGN_COVER_CHK) { - return ancestor_design_f(ddlist, mask, mode); + return ancestor_design(ddlist, mask, mode); } /*Draw the object*/ else if(mode == LV_DESIGN_DRAW_MAIN) { - ancestor_design_f(ddlist, mask, mode); + ancestor_design(ddlist, mask, mode); - /*If the list is opened draw a rectangle below the selected item*/ + /*If the list is opened draw a rectangle under the selected item*/ lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist); if(ext->opened != 0) { - lv_style_t * style = lv_obj_get_style(ddlist); + lv_style_t *style = lv_ddlist_get_style_bg(ddlist); + lv_obj_t *scrl = lv_page_get_scrl(ddlist); const font_t * font = style->text.font; cord_t font_h = font_get_height(font) >> FONT_ANTIALIAS; area_t rect_area; rect_area.y1 = ext->options_label->coords.y1; - rect_area.y1 += ext->selected_option_id * (font_h + style->text.space_line); - rect_area.y1 -= style->text.space_line / 2; + rect_area.y1 += ext->selected_option_id * (font_h + style->text.line_space); + rect_area.y1 -= style->text.line_space / 2; - rect_area.y2 = rect_area.y1 + font_h + style->text.space_line; - rect_area.x1 = ext->options_label->coords.x1 - style->body.padding.hor; - rect_area.x2 = rect_area.x1 + lv_obj_get_width(lv_page_get_scrl(ddlist)); + rect_area.y2 = rect_area.y1 + font_h + style->text.line_space; + rect_area.x1 = scrl->coords.x1 - (style->body.padding.hor >> 1); /*Draw a littlebit wider rectangle then the text*/ + rect_area.x2 = scrl->coords.x2 + (style->body.padding.hor >> 1); lv_draw_rect(&rect_area, mask, ext->selected_style); } } /*Post draw when the children are drawn*/ else if(mode == LV_DESIGN_DRAW_POST) { - ancestor_design_f(ddlist, mask, mode); + ancestor_design(ddlist, mask, mode); } return true; } +/** + * Signal function of the drop down list's scrollable part + * @param scrl pointer to a drop down list's scrollable part + * @param sign a signal type from lv_signal_t enum + * @param param pointer to a signal specific variable + * @return true: the object is still valid (not deleted), false: the object become invalid + */ +static bool lv_ddlist_scrl_signal(lv_obj_t * scrl, lv_signal_t sign, void * param) +{ + bool valid; + + /* Include the ancient signal function */ + valid = ancestor_scrl_signal(scrl, sign, param); + + /* The object can be deleted so check its validity and then + * make the object specific signal handling */ + if(valid != false) { + if(sign == LV_SIGNAL_REFR_EXT_SIZE) { + /* Because of the wider selected rectangle ext. size + * In this way by dragging the scrollable part the wider rectangle area will be redrawn too*/ + lv_obj_t *ddlist = lv_obj_get_parent(scrl); + lv_style_t *style = lv_ddlist_get_style_bg(ddlist); + if(scrl->ext_size < (style->body.padding.hor >> 1)) scrl->ext_size = style->body.padding.hor >> 1; + } + } + + return valid; +} + /** * Called when a drop down list is released to open it or set new option * @param ddlist pointer to a drop down list object @@ -513,11 +556,11 @@ static void lv_ddlist_refr_size(lv_obj_t * ddlist, uint16_t anim_time) const font_t * font = style->text.font; lv_style_t * label_style = lv_obj_get_style(ext->options_label); cord_t font_h = font_get_height(font) >> FONT_ANTIALIAS; - new_height = font_h + 2 * label_style->text.space_line; + new_height = font_h + 2 * label_style->text.line_space; } if(anim_time == 0) { lv_obj_set_height(ddlist, new_height); - lv_ddlist_pos_act_option(ddlist); + lv_ddlist_pos_current_option(ddlist); } else { anim_t a; a.var = ddlist; @@ -525,7 +568,7 @@ static void lv_ddlist_refr_size(lv_obj_t * ddlist, uint16_t anim_time) a.end = new_height; a.fp = (anim_fp_t)lv_obj_set_height; a.path = anim_get_path(ANIM_PATH_LIN); - a.end_cb = (anim_cb_t)lv_ddlist_pos_act_option; + a.end_cb = (anim_cb_t)lv_ddlist_pos_current_option; a.act_time = 0; a.time = ext->anim_time; a.playback = 0; @@ -541,7 +584,7 @@ static void lv_ddlist_refr_size(lv_obj_t * ddlist, uint16_t anim_time) * Set the position of list when it is closed to show the selected item * @param ddlist pointer to a drop down list */ -static void lv_ddlist_pos_act_option(lv_obj_t * ddlist) +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); @@ -551,7 +594,7 @@ static void lv_ddlist_pos_act_option(lv_obj_t * ddlist) lv_obj_t * scrl = lv_page_get_scrl(ddlist); cord_t h = lv_obj_get_height(ddlist); - cord_t line_y1 = ext->selected_option_id * (font_h + label_style->text.space_line) + ext->options_label->coords.y1 - scrl->coords.y1; + cord_t line_y1 = ext->selected_option_id * (font_h + label_style->text.line_space) + ext->options_label->coords.y1 - scrl->coords.y1; lv_obj_set_y(scrl, - line_y1 + (h - font_h) / 2); diff --git a/lv_objx/lv_ddlist.h b/lv_objx/lv_ddlist.h index f09b4e555..8a8ae7f4e 100644 --- a/lv_objx/lv_ddlist.h +++ b/lv_objx/lv_ddlist.h @@ -99,9 +99,9 @@ void lv_ddlist_set_selected(lv_obj_t * ddlist, uint16_t sel_opt); /** * Set a function to call when a new option is chosen * @param ddlist pointer to a drop down list - * @param cb pointer to a call back function + * @param action pointer to a call back function */ -void lv_ddlist_set_action(lv_obj_t * ddlist, lv_action_t cb); +void lv_ddlist_set_action(lv_obj_t * ddlist, lv_action_t action); /** * Set the fix height value. @@ -118,13 +118,6 @@ void lv_ddlist_set_fix_height(lv_obj_t * ddlist, cord_t h); */ void lv_ddlist_set_anim_time(lv_obj_t * ddlist, uint16_t anim_time); -/** - * Set the style of the rectangle on the selected option - * @param ddlist pointer to a drop down list object - * @param style pointer the new style of the select rectangle - */ -void lv_ddlist_set_selected_style(lv_obj_t * ddlist, lv_style_t * style); - /** * Open the drop down list with or without animation * @param ddlist pointer to drop down list object @@ -139,6 +132,15 @@ void lv_ddlist_open(lv_obj_t * ddlist, bool anim); */ void lv_ddlist_close(lv_obj_t * ddlist, bool anim); +/** + * Set the style of a drop down list + * @param ddlist pointer to a drop down list object + * @param bg pointer to the new style of the background + * @param sb pointer to the new style of the scrollbars (only visible with fix height) + * @param sel pointer to the new style of the select rectangle + */ +void lv_ddlist_set_style(lv_obj_t * ddlist, lv_style_t * bg, lv_style_t * sb, lv_style_t * sel); + /** * Get the options of a drop down list * @param ddlist pointer to drop down list object @@ -181,6 +183,32 @@ lv_style_t * lv_ddlist_get_style_select(lv_obj_t * ddlist); */ uint16_t lv_ddlist_get_anim_time(lv_obj_t * ddlist); + +/**************************** + * TRANSPARENT API FUNCTIONS + ***************************/ + +/** +* Get the style of the drop down list background +* @param ddlist pointer to a text area object +* @return pointer to the style of the background +*/ +static inline lv_style_t * lv_ddlist_get_style_bg(lv_obj_t * ddlist) +{ + return lv_page_get_style_bg(ddlist); +} + +/** +* Get the style of the scrollbars of a drop down list +* @param ddlist pointer to a text area object +* @return pointer to the style of the scrollbars +*/ +static inline lv_style_t * lv_ddlist_get_style_scrollbar(lv_obj_t * ddlist) +{ + return lv_page_get_style_sb(ddlist); +} + + /********************** * MACROS **********************/ diff --git a/lv_objx/lv_gauge.c b/lv_objx/lv_gauge.c index c4c5db1e8..2077cb45f 100644 --- a/lv_objx/lv_gauge.c +++ b/lv_objx/lv_gauge.c @@ -27,7 +27,7 @@ #define LV_GAUGE_DEF_NEEDLE_COLOR COLOR_RED #define LV_GAUGE_DEF_LABEL_COUNT 6 -#define LV_GAUGE_DEF_SCALE_LINE_COUNT 21 /*Should be: ((label_cnt - 1) * internal_lines) + 1*/ +#define LV_GAUGE_DEF_LINE_COUNT 21 /*Should be: ((label_cnt - 1) * internal_lines) + 1*/ #define LV_GAUGE_DEF_ANGLE 220 @@ -88,15 +88,15 @@ lv_obj_t * lv_gauge_create(lv_obj_t * par, lv_obj_t * copy) /*Init the new gauge gauge*/ if(copy == NULL) { - lv_lmeter_set_scale(new_gauge, LV_GAUGE_DEF_ANGLE, LV_GAUGE_DEF_SCALE_LINE_COUNT); - lv_gauge_set_needle_num(new_gauge, 1, NULL); + 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_obj_set_size(new_gauge, 2 * LV_DPI, 2 * LV_DPI); lv_obj_set_style(new_gauge, &lv_style_pretty); } /*Copy an existing gauge*/ else { lv_gauge_ext_t * copy_ext = lv_obj_get_ext_attr(copy); - lv_gauge_set_needle_num(new_gauge, copy_ext->needle_count, copy_ext->needle_colors); + lv_gauge_set_needle_count(new_gauge, copy_ext->needle_count, copy_ext->needle_colors); uint8_t i; for(i = 0; i < ext->needle_count; i++) { @@ -147,7 +147,7 @@ bool lv_gauge_signal(lv_obj_t * gauge, lv_signal_t sign, void * param) * @param needle_cnt new count of needles * @param colors an array of colors for needles (with 'num' elements) */ -void lv_gauge_set_needle_num(lv_obj_t * gauge, uint8_t needle_cnt, color_t * colors) +void lv_gauge_set_needle_count(lv_obj_t * gauge, uint8_t needle_cnt, color_t * colors) { lv_gauge_ext_t * ext = lv_obj_get_ext_attr(gauge); if(ext->values != NULL) { @@ -157,7 +157,7 @@ void lv_gauge_set_needle_num(lv_obj_t * gauge, uint8_t needle_cnt, color_t * col ext->values = dm_realloc(ext->values, needle_cnt * sizeof(int16_t)); - int16_t min = lv_bar_get_min_value(gauge); + int16_t min = lv_gauge_get_min_value(gauge); uint8_t n; for(n = ext->needle_count; n < needle_cnt; n++) { ext->values[n] = min; @@ -168,17 +168,6 @@ void lv_gauge_set_needle_num(lv_obj_t * gauge, uint8_t needle_cnt, color_t * col lv_obj_invalidate(gauge); } -/** - * Set the number of labels (and the thicker lines too) - * @param gauge pointer to a gauge object - * @param label_cnt new count of labels - */ -void lv_gauge_set_label_count(lv_obj_t * gauge, uint8_t label_cnt) -{ - lv_gauge_ext_t * ext = lv_obj_get_ext_attr(gauge); - ext->label_count = label_cnt; -} - /** * Set the value of a needle * @param gauge pointer to a gauge @@ -191,24 +180,53 @@ void lv_gauge_set_value(lv_obj_t * gauge, uint8_t needle_id, int16_t value) if(needle_id >= ext->needle_count) return; - int16_t min = lv_bar_get_min_value(gauge); - int16_t max = lv_bar_get_max_value(gauge); + 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; ext->values[needle_id] = value; - /*To be consistent with bar set the first needle's value for the bar*/ - if(needle_id == 0) lv_bar_set_value(gauge, 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 + * @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) +{ + lv_lmeter_set_scale(gauge, angle, line_cnt); + + lv_gauge_ext_t * ext = lv_obj_get_ext_attr(gauge); + ext->label_count = label_cnt; +} + /*===================== * Getter functions *====================*/ +/** + * Get the value of a needle + * @param gauge pointer to gauge object + * @param needle the id of the needle + * @return the value of the needle [min,max] + */ +int16_t lv_gauge_get_value(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); + + if(needle >= ext->needle_count) return min; + + return ext->values[needle]; +} + /** * Get the count of needles on a gauge * @param gauge pointer to gauge @@ -231,23 +249,6 @@ uint8_t lv_gauge_get_label_count(lv_obj_t * gauge) return ext->label_count; } - -/** - * Get the value of a needle - * @param gauge pointer to gauge object - * @param needle the id of the needle - * @return the value of the needle [min,max] - */ -int16_t lv_gauge_get_value(lv_obj_t * gauge, uint8_t needle) -{ - lv_gauge_ext_t * ext = lv_obj_get_ext_attr(gauge); - int16_t min = lv_bar_get_min_value(gauge); - - if(needle >= ext->needle_count) return min; - - return ext->values[needle]; -} - /********************** * STATIC FUNCTIONS **********************/ @@ -278,23 +279,23 @@ static bool lv_gauge_design(lv_obj_t * gauge, const area_t * mask, lv_design_mod lv_gauge_draw_scale(gauge, mask); /*Draw the ancestor line meter with max value to show the rainbow like line colors*/ - uint16_t scale_num_tmp = ext->lmeter.scale_num; - int16_t value_tmp = ext->lmeter.bar.act_value; - ext->lmeter.bar.act_value = ext->lmeter.bar.max_value; + uint16_t line_cnt_tmp = ext->lmeter.line_cnt; + int16_t value_tmp = ext->lmeter.cur_value; + ext->lmeter.cur_value = ext->lmeter.max_value; ancestor_design_f(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.scale_num = ext->label_count; /*Only to labels*/ + 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.hor = style_tmp.body.padding.hor * 2; /*Longer lines*/ gauge->style_p = &style_tmp; ancestor_design_f(gauge, mask, mode); /*To draw lines*/ - ext->lmeter.scale_num = scale_num_tmp; /*Restore the parameters*/ - ext->lmeter.bar.act_value = value_tmp; + ext->lmeter.line_cnt = line_cnt_tmp; /*Restore the parameters*/ + ext->lmeter.cur_value = value_tmp; gauge->style_p = style; @@ -326,8 +327,8 @@ static void lv_gauge_draw_scale(lv_obj_t * gauge, const area_t * mask) 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_bar_get_min_value(gauge); - int16_t max = lv_bar_get_max_value(gauge); + 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++) { @@ -347,7 +348,7 @@ static void lv_gauge_draw_scale(lv_obj_t * gauge, const area_t * mask) area_t label_cord; point_t label_size; txt_get_size(&label_size, scale_txt, style->text.font, - style->text.space_letter, style->text.space_line, + style->text.letter_space, style->text.line_space, CORD_MAX, TXT_FLAG_NONE); /*Draw the label*/ @@ -370,18 +371,13 @@ static void lv_gauge_draw_needle(lv_obj_t * gauge, const area_t * mask) lv_gauge_ext_t * ext = lv_obj_get_ext_attr(gauge); lv_style_t * style = lv_obj_get_style(gauge); - /*To be consistent with bar use the bar value as the first needle*/ - if(ext->needle_count != 0) { - ext->values[0] = lv_bar_get_value(gauge); - } - cord_t r = lv_obj_get_width(gauge) / 2 - style->body.padding.hor; cord_t x_ofs = lv_obj_get_width(gauge) / 2 + gauge->coords.x1; cord_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_bar_get_min_value(gauge); - int16_t max = lv_bar_get_max_value(gauge); + int16_t min = lv_gauge_get_min_value(gauge); + int16_t max = lv_gauge_get_max_value(gauge); point_t p_mid; point_t p_end; uint8_t i; diff --git a/lv_objx/lv_gauge.h b/lv_objx/lv_gauge.h index b5d5b8d7d..e34849b52 100644 --- a/lv_objx/lv_gauge.h +++ b/lv_objx/lv_gauge.h @@ -75,41 +75,28 @@ bool lv_gauge_signal(lv_obj_t * gauge, lv_signal_t sign, void * param); /** * Set the number of needles * @param gauge pointer to gauge object - * @param num number of needles + * @param needle_cnt new count of needles * @param colors an array of colors for needles (with 'num' elements) */ -void lv_gauge_set_needle_num(lv_obj_t * gauge, uint8_t num, color_t * colors); +void lv_gauge_set_needle_count(lv_obj_t * gauge, uint8_t needle_cnt, color_t * colors); /** * Set the value of a needle - * @param gauge pointer to gauge - * @param needle the id of the needle + * @param gauge pointer to a gauge + * @param needle_id the id of the needle * @param value the new value */ -void lv_gauge_set_value(lv_obj_t * gauge, uint8_t needle, int16_t value); +void lv_gauge_set_value(lv_obj_t * gauge, uint8_t needle_id, int16_t value); /** - * Set which value is more critical (lower or higher) + * Set the scale settings of a gauge * @param gauge pointer to a gauge object - * @param low false: higher / true: lower value is more critical + * @param angle angle of the scale (0..360) + * @param line_cnt count of scale lines + * @param label_cnt count of scale labels */ -void lv_gauge_set_low_critical(lv_obj_t * gauge, bool low); +void lv_gauge_set_scale(lv_obj_t * gauge, uint16_t angle, uint8_t line_cnt, uint8_t label_cnt); -/** - * Set the critical style of the gauge - * @param gauge pointer to a gauge object - * @param style pointer to the new critical style - */ -void lv_gauge_set_style_critical(lv_obj_t * gauge, lv_style_t * style); - -/** - * Get the number of needles on a gauge - * @param gauge pointer to gauge - * @return number of needles - */ -uint8_t lv_gauge_get_needle_count(lv_obj_t * gauge); - -uint8_t lv_gauge_get_label_count(lv_obj_t * gauge); /** * Get the value of a needle * @param gauge pointer to gauge object @@ -119,18 +106,74 @@ uint8_t lv_gauge_get_label_count(lv_obj_t * gauge); int16_t lv_gauge_get_value(lv_obj_t * gauge, uint8_t needle); /** - * Get which value is more critical (lower or higher) - * @param gauge pointer to a gauge object - * @param low false: higher / true: lower value is more critical + * Get the count of needles on a gauge + * @param gauge pointer to gauge + * @return count of needles */ -bool lv_gauge_get_low_critical(lv_obj_t * gauge); +uint8_t lv_gauge_get_needle_count(lv_obj_t * gauge); /** - * Get the critical style of the gauge + * Set the number of labels (and the thicker lines too) * @param gauge pointer to a gauge object - * @return pointer to the critical style + * @return count of labels */ -lv_style_t * lv_gauge_get_style_critical(lv_obj_t * gauge); +uint8_t lv_gauge_get_label_count(lv_obj_t * gauge); + +/**************************** + * TRANSPARENT API FUNCTIONS + ***************************/ + +/** + * Set minimum and the maximum values of a gauge + * @param gauge pointer to he gauge object + * @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) +{ + lv_lmeter_set_range(gauge, min, max); +} + +/** + * Get the minimum value of a gauge + * @param gauge pointer to a gauge object + * @return the minimum value of the gauge + */ +static inline int16_t lv_gauge_get_min_value(lv_obj_t * lmeter) +{ + return lv_lmeter_get_min_value(lmeter); +} + +/** + * Get the maximum value of a gauge + * @param gauge pointer to a gauge object + * @return the maximum value of the gauge + */ +static inline int16_t lv_gauge_get_max_value(lv_obj_t * lmeter) +{ + return lv_lmeter_get_max_value(lmeter); +} + + +/** + * Get the scale number of a gauge + * @param gauge pointer to a gauge object + * @return number of the scale units + */ +static inline uint8_t lv_gauge_get_line_count(lv_obj_t * gauge) +{ + return lv_lmeter_get_line_count(gauge); +} + +/** + * Get the scale angle of a gauge + * @param gauge pointer to a gauge object + * @return angle of the scale + */ +static inline uint16_t lv_gauge_get_scale_angle(lv_obj_t * gauge) +{ + return lv_lmeter_get_scale_angle(gauge); +} /********************** * MACROS diff --git a/lv_objx/lv_img.c b/lv_objx/lv_img.c index e1f2f87ce..f6b923e17 100644 --- a/lv_objx/lv_img.c +++ b/lv_objx/lv_img.c @@ -190,7 +190,7 @@ void lv_img_set_file(lv_obj_t * img, const char * fn) else { lv_style_t * style = lv_obj_get_style(img); point_t size; - txt_get_size(&size, fn, style->text.font, style->text.space_letter, style->text.space_line, CORD_MAX, TXT_FLAG_NONE); + txt_get_size(&size, fn, style->text.font, style->text.letter_space, style->text.line_space, CORD_MAX, TXT_FLAG_NONE); ext->w = size.x; ext->h = size.y; ext->transp = 1; /*Symbols always have transparent parts*/ diff --git a/lv_objx/lv_kb.c b/lv_objx/lv_kb.c index c8abdc0c9..1e527ad89 100644 --- a/lv_objx/lv_kb.c +++ b/lv_objx/lv_kb.c @@ -16,6 +16,7 @@ /********************* * DEFINES *********************/ + /********************** * TYPEDEFS **********************/ @@ -183,7 +184,7 @@ void lv_kb_set_mode(lv_obj_t * kb, lv_kb_mode_t mode) * @param kb pointer to a Keyboard object * @param en true: show cursor on the current text area, false: hide cursor */ -void lv_kb_set_cur_mng(lv_obj_t * kb, bool en) +void lv_kb_set_cursor_manage(lv_obj_t * kb, bool en) { lv_kb_ext_t * ext = lv_obj_get_ext_attr(kb); ext->cur_mng = en == false? 0 : 1; @@ -246,7 +247,7 @@ lv_kb_mode_t lv_kb_get_mode(lv_obj_t * kb) * @param kb pointer to a Keyboard object * @return true: show cursor on the current text area, false: hide cursor */ -bool lv_kb_get_cur_mng(lv_obj_t * kb, bool en) +bool lv_kb_get_cursor_manage(lv_obj_t * kb, bool en) { lv_kb_ext_t * ext = lv_obj_get_ext_attr(kb); return ext->cur_mng == 0 ? false : true; @@ -337,7 +338,7 @@ static lv_res_t lv_app_kb_action(lv_obj_t * kb, const char * txt) lv_ta_del(ext->ta); } else if(strcmp(txt, "+/-") == 0) { uint16_t cur = lv_ta_get_cursor_pos(ext->ta); - const char * ta_txt = lv_ta_get_txt(ext->ta); + const char * ta_txt = lv_ta_get_text(ext->ta); if(ta_txt[0] == '-') { lv_ta_set_cursor_pos(ext->ta, 1); lv_ta_del(ext->ta); diff --git a/lv_objx/lv_kb.h b/lv_objx/lv_kb.h index a7e0848d5..ae0743012 100644 --- a/lv_objx/lv_kb.h +++ b/lv_objx/lv_kb.h @@ -37,11 +37,11 @@ typedef enum { typedef struct { lv_btnm_ext_t btnm; /*Ext. of ancestor*/ /*New data for this type */ - lv_obj_t * ta; - lv_kb_mode_t mode; - uint8_t cur_mng :1; - lv_action_t ok_action; - lv_action_t close_action; + lv_obj_t *ta; /*Pointer to the assigned text area*/ + lv_kb_mode_t mode; /*Key map type*/ + uint8_t cur_mng :1; /*1: automatically show/hide cursor when a text area is assigned or left*/ + lv_action_t ok_action; /*Called when the "Ok" button is clicked*/ + lv_action_t close_action; /*Called when the "Hide" button is clicked*/ }lv_kb_ext_t; /********************** @@ -84,7 +84,7 @@ void lv_kb_set_mode(lv_obj_t * kb, lv_kb_mode_t mode); * @param kb pointer to a Keyboard object * @param en true: show cursor on the current text area, false: hide cursor */ -void lv_kb_set_cur_mng(lv_obj_t * kb, bool en); +void lv_kb_set_cursor_manage(lv_obj_t * kb, bool en); /** * Set call back to call when the "Ok" button is pressed @@ -113,13 +113,12 @@ lv_obj_t * lv_kb_get_ta(lv_obj_t * kb); */ lv_kb_mode_t lv_kb_get_mode(lv_obj_t * kb); - /** * Get the current cursor manage mode. * @param kb pointer to a Keyboard object * @return true: show cursor on the current text area, false: hide cursor */ -bool lv_kb_get_cur_mng(lv_obj_t * kb, bool en); +bool lv_kb_get_cursor_manage(lv_obj_t * kb, bool en); /** * Get the callback to call when the "Ok" button is pressed @@ -135,6 +134,56 @@ lv_action_t lv_kb_get_ok_action(lv_obj_t * kb, lv_action_t action); */ lv_action_t lv_kb_get_close_action(lv_obj_t * kb, lv_action_t action); +/**************************** + * TRANSPARENT API FUNCTIONS + ***************************/ + +/** + * Set styles of the buttons is each state. Use NULL for any style to leave it unchanged. + * @param kb pointer to keyboard object + * @param rel pointer to a style for releases state + * @param pr pointer to a style for pressed state + * @param tgl_rel pointer to a style for toggled releases state + * @param tgl_pr pointer to a style for toggled pressed state + * @param ina pointer to a style for inactive state + */ +static inline void lv_kb_set_style_btn(lv_obj_t *kb, lv_style_t *rel, lv_style_t *pr, + lv_style_t *tgl_rel, lv_style_t *tgl_pr, + lv_style_t *ina) +{ + lv_btnm_set_style_btn(kb, rel, pr, tgl_rel, tgl_pr, ina); +} + +/** + * Set the style of a keyboards's background + * @param kb pointer to a keyboard object + * @param bg pointer to the background style + */ +static inline void lv_kb_set_style_bg(lv_obj_t *kb, lv_style_t * bg) +{ + lv_btnm_set_style_bg(kb, bg); +} + +/** + * Get the style of the buttons of keyboard + * @param kb pointer to a keyboard object + * @param state style in this state (LV_BTN_STATE_PR or LV_BTN_STATE_REL) + * @return pointer the button style in the given state + */ +static inline lv_style_t * lv_kb_kb_style_btn(lv_obj_t *kb, lv_btn_state_t state) +{ + return lv_btnm_get_style_btn(kb, state); +} + +/** + * Get the style of a keyboard + * @param kb pointer to a keyboard object + * @return pointer to the background style + */ +static inline lv_style_t * lv_kb_get_style_bg(lv_obj_t *kb) +{ + return lv_btnm_get_style_bg(kb); +} /********************** * MACROS **********************/ diff --git a/lv_objx/lv_label.c b/lv_objx/lv_label.c index 21ba325fe..8b24ac0b5 100644 --- a/lv_objx/lv_label.c +++ b/lv_objx/lv_label.c @@ -466,16 +466,16 @@ void lv_label_get_letter_pos(lv_obj_t * label, uint16_t index, point_t * pos) /*Search the line of the index letter */; while (txt[new_line_start] != '\0') { - new_line_start += txt_get_next_line(&txt[line_start], font, style->text.space_letter, max_w, flag); + new_line_start += 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.space_line; + y += letter_height + style->text.line_space; line_start = new_line_start; } /*If the last character is line break then go to the next line*/ if((txt[index - 1] == '\n' || txt[index - 1] == '\r') && txt[index] == '\0') { - y += letter_height + style->text.space_line; + y += letter_height + style->text.line_space; line_start = index; } @@ -494,13 +494,13 @@ void lv_label_get_letter_pos(lv_obj_t * label, uint16_t index, point_t * pos) continue; /*Skip the letter is it is part of a command*/ } } - x += (font_get_width(font, letter) >> FONT_ANTIALIAS) + style->text.space_letter; + x += (font_get_width(font, letter) >> FONT_ANTIALIAS) + style->text.letter_space; } if(ext->align == LV_LABEL_ALIGN_CENTER) { cord_t line_w; line_w = txt_get_width(&txt[line_start], new_line_start - line_start, - font, style->text.space_letter, flag); + font, style->text.letter_space, flag); x += lv_obj_get_width(label) / 2 - line_w / 2; } @@ -540,9 +540,9 @@ uint16_t lv_label_get_letter_on(lv_obj_t * label, point_t * pos) /*Search the line of the index letter */; while (txt[line_start] != '\0') { - new_line_start += txt_get_next_line(&txt[line_start], font, style->text.space_letter, max_w, flag); - if(pos->y <= y + letter_height + style->text.space_line) break; /*The line is found ('line_start')*/ - y += letter_height + style->text.space_line; + new_line_start += txt_get_next_line(&txt[line_start], font, style->text.letter_space, max_w, flag); + if(pos->y <= y + letter_height + style->text.line_space) break; /*The line is found ('line_start')*/ + y += letter_height + style->text.line_space; line_start = new_line_start; } @@ -551,7 +551,7 @@ uint16_t lv_label_get_letter_on(lv_obj_t * label, point_t * pos) if(ext->align == LV_LABEL_ALIGN_CENTER) { cord_t line_w; line_w = txt_get_width(&txt[line_start], new_line_start - line_start, - font, style->text.space_letter, flag); + font, style->text.letter_space, flag); x += lv_obj_get_width(label) / 2 - line_w / 2; } @@ -567,7 +567,7 @@ uint16_t lv_label_get_letter_on(lv_obj_t * label, point_t * pos) } } - x += (font_get_width(font, letter) >> FONT_ANTIALIAS) + style->text.space_letter; + x += (font_get_width(font, letter) >> FONT_ANTIALIAS) + style->text.letter_space; if(pos->x < x) break; /*Get the position*/ } @@ -651,7 +651,7 @@ static void lv_label_refr_text(lv_obj_t * label) if(ext->recolor != 0) flag |= TXT_FLAG_RECOLOR; if(ext->expand != 0) flag |= TXT_FLAG_EXPAND; if(ext->no_break != 0) flag |= TXT_FLAG_NO_BREAK; - txt_get_size(&size, ext->txt, font, style->text.space_letter, style->text.space_line, max_w, flag); + txt_get_size(&size, ext->txt, font, style->text.letter_space, style->text.line_space, max_w, flag); /*Refresh the full size in expand mode*/ if(ext->long_mode == LV_LABEL_LONG_EXPAND || ext->long_mode == LV_LABEL_LONG_SCROLL) { diff --git a/lv_objx/lv_list.c b/lv_objx/lv_list.c index f7a0c6a1d..e21f7c42e 100644 --- a/lv_objx/lv_list.c +++ b/lv_objx/lv_list.c @@ -11,7 +11,6 @@ #include "lv_list.h" #include "../lv_obj/lv_group.h" -#include "lv_cont.h" #include "misc/gfx/anim.h" #include "misc/math/math_base.h" @@ -39,6 +38,10 @@ static lv_obj_t * lv_list_get_next_btn(lv_obj_t * list, lv_obj_t * prev_btn); /********************** * STATIC VARIABLES **********************/ +static lv_signal_func_t btn_signal; +static lv_signal_func_t img_signal; +static lv_signal_func_t label_signal; +static lv_signal_func_t ancestor_signal; /********************** * MACROS @@ -63,10 +66,11 @@ lv_obj_t * lv_list_create(lv_obj_t * par, lv_obj_t * copy) /*Create the ancestor basic object*/ lv_obj_t * new_list = lv_page_create(par, copy); dm_assert(new_list); + if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_func(new_list); + lv_list_ext_t * ext = lv_obj_allocate_ext_attr(new_list, sizeof(lv_list_ext_t)); dm_assert(ext); - ext->sb_out = 0; ext->style_img = NULL; ext->styles_btn[LV_BTN_STATE_RELEASED] = &lv_style_btn_off_released; ext->styles_btn[LV_BTN_STATE_PRESSED] = &lv_style_btn_off_pressed; @@ -79,21 +83,17 @@ lv_obj_t * lv_list_create(lv_obj_t * par, lv_obj_t * copy) /*Init the new list object*/ if(copy == NULL) { lv_obj_set_size(new_list, 2 * LV_DPI, 3 * LV_DPI); - lv_cont_set_layout(ext->page.scrl, LV_LIST_LAYOUT_DEF); - lv_obj_set_style(new_list, &lv_style_transp_fit); - lv_obj_set_style(lv_page_get_scrl(new_list), &lv_style_pretty); - lv_page_set_sb_mode(new_list, LV_PAGE_SB_MODE_AUTO); + lv_page_set_scrl_layout(new_list, LV_LIST_LAYOUT_DEF); + lv_list_set_style_bg(new_list, &lv_style_transp_fit, &lv_style_pretty, NULL); + lv_page_set_sb_mode(new_list, LV_PAGE_SB_MODE_DRAG); } else { lv_list_ext_t * copy_ext = lv_obj_get_ext_attr(copy); - lv_list_set_btn_styles(new_list, copy_ext->styles_btn[LV_BTN_STATE_RELEASED], + lv_list_set_style_btn(new_list, copy_ext->styles_btn[LV_BTN_STATE_RELEASED], copy_ext->styles_btn[LV_BTN_STATE_PRESSED], copy_ext->styles_btn[LV_BTN_STATE_TGL_RELEASED], copy_ext->styles_btn[LV_BTN_STATE_TGL_PRESSED], copy_ext->styles_btn[LV_BTN_STATE_INACTIVE]); - lv_list_set_style_img(new_list, copy_ext->style_img); - - lv_list_set_sb_out(new_list, copy_ext->sb_out); /*Refresh the style with new signal function*/ lv_obj_refresh_style(new_list); @@ -113,7 +113,7 @@ bool lv_list_signal(lv_obj_t * list, lv_signal_t sign, void * param) bool valid; /* Include the ancient signal function */ - valid = lv_page_signal(list, sign, param); + valid = ancestor_signal(list, sign, param); /* The object can be deleted so check its validity and then * make the object specific signal handling */ @@ -219,8 +219,9 @@ lv_obj_t * lv_list_add(lv_obj_t * list, const char * img_fn, const char * txt, l lv_btn_set_action(liste, LV_BTN_ACTION_RELEASE, rel_action); lv_page_glue_obj(liste, true); - lv_cont_set_layout(liste, LV_CONT_LAYOUT_ROW_M); - lv_cont_set_fit(liste, false, true); + lv_btn_set_layout(liste, LV_CONT_LAYOUT_ROW_M); + lv_btn_set_fit(liste, false, true); + if(btn_signal == NULL) btn_signal = lv_obj_get_signal_func(liste); /*Make the size adjustment*/ cord_t w = lv_obj_get_width(list); @@ -228,10 +229,6 @@ lv_obj_t * lv_list_add(lv_obj_t * list, const char * img_fn, const char * txt, l cord_t pad_hor_tot = style->body.padding.hor + style_scrl->body.padding.hor; w -= pad_hor_tot * 2; - /*Make place for the scrollbar if pad_hor_tot is too small*/ - if(ext->sb_out != 0) { - if(pad_hor_tot < ext->page.sb_width) w -= ext->page.sb_width - pad_hor_tot; - } lv_obj_set_width(liste, w); #if USE_LV_IMG != 0 && USE_FSINT != 0 if(img_fn != NULL && img_fn[0] != '\0') { @@ -239,6 +236,7 @@ lv_obj_t * lv_list_add(lv_obj_t * list, const char * img_fn, const char * txt, l lv_img_set_file(img, img_fn); lv_obj_set_style(img, ext->style_img); lv_obj_set_click(img, false); + if(img_signal == NULL) img_signal = lv_obj_get_signal_func(img); } #endif if(txt != NULL) { @@ -247,8 +245,11 @@ lv_obj_t * lv_list_add(lv_obj_t * list, const char * img_fn, const char * txt, l lv_obj_set_click(label, false); lv_label_set_long_mode(label, LV_LABEL_LONG_ROLL); lv_obj_set_width(label, liste->coords.x2 - label->coords.x1); + if(label_signal == NULL) label_signal = lv_obj_get_signal_func(label); } + + return liste; } @@ -336,68 +337,32 @@ void lv_list_down(lv_obj_t * list) * Setter functions *====================*/ -/** - * Enable/Disable to scrollbar outside attribute - * @param list pointer to list object - * @param out true: reduce the buttons width therefore scroll bar will be out of the buttons, - * false: keep button size and place scroll bar on the buttons - */ -void lv_list_set_sb_out(lv_obj_t * list, bool out) -{ - lv_list_ext_t * ext = lv_obj_get_ext_attr(list); - - ext->sb_out = out == false ? 0 : 1; -} - - /** * Set styles of the list elements of a list in each state * @param list pointer to list object * @param rel pointer to a style for releases state * @param pr pointer to a style for pressed state - * @param trel pointer to a style for toggled releases state - * @param tpr pointer to a style for toggled pressed state + * @param tgl_rel pointer to a style for toggled releases state + * @param tgl_pr pointer to a style for toggled pressed state * @param ina pointer to a style for inactive state */ -void lv_list_set_btn_styles(lv_obj_t * list, lv_style_t * rel, lv_style_t * pr, - lv_style_t * trel, lv_style_t * tpr, +void lv_list_set_style_btn(lv_obj_t * list, lv_style_t * rel, lv_style_t * pr, + lv_style_t * tgl_rel, lv_style_t * tgl_pr, lv_style_t * ina) { lv_list_ext_t * ext = lv_obj_get_ext_attr(list); - ext->styles_btn[LV_BTN_STATE_RELEASED] = rel; - ext->styles_btn[LV_BTN_STATE_PRESSED] = pr; - ext->styles_btn[LV_BTN_STATE_TGL_RELEASED] = trel; - ext->styles_btn[LV_BTN_STATE_TGL_PRESSED] = tpr; - ext->styles_btn[LV_BTN_STATE_INACTIVE] = ina; + if(rel != NULL) ext->styles_btn[LV_BTN_STATE_RELEASED] = rel; + if(pr != NULL) ext->styles_btn[LV_BTN_STATE_PRESSED] = pr; + if(tgl_rel != NULL) ext->styles_btn[LV_BTN_STATE_TGL_RELEASED] = tgl_rel; + if(tgl_pr != NULL) ext->styles_btn[LV_BTN_STATE_TGL_PRESSED] = tgl_pr; + if(ina != NULL) ext->styles_btn[LV_BTN_STATE_INACTIVE] = ina; + /*Refresh all existing buttons*/ lv_obj_t * liste = lv_list_get_next_btn(list, NULL); while(liste != NULL) { - lv_btn_set_style(liste, rel, pr, trel, tpr, ina); - liste = lv_list_get_next_btn(list, liste); - } -} - - -/** - * Set the styles of the list element image (typically to set symbol font) - * @param list pointer to list object - * @param style pointer to the new style of the button images - */ -void lv_list_set_style_img(lv_obj_t * list, lv_style_t * style) -{ - lv_list_ext_t * ext = lv_obj_get_ext_attr(list); - - ext->style_img = style; - - lv_obj_t * liste = lv_list_get_next_btn(list, NULL); - lv_obj_t * img; - while(liste != NULL) - { - img = lv_list_get_element_img(liste); - if(img != NULL) lv_obj_set_style(img, style); - + lv_btn_set_style(liste, rel, pr, tgl_rel, tgl_pr, ina); liste = lv_list_get_next_btn(list, liste); } } @@ -411,9 +376,9 @@ void lv_list_set_style_img(lv_obj_t * list, lv_style_t * style) * @param liste pointer to list element * @return pointer to the text */ -const char * lv_list_get_element_text(lv_obj_t * liste) +const char * lv_list_get_btn_text(lv_obj_t * liste) { - lv_obj_t * label = lv_list_get_element_label(liste); + lv_obj_t * label = lv_list_get_btn_label(liste); if(label == NULL) return ""; return lv_label_get_text(label); } @@ -423,12 +388,12 @@ const char * lv_list_get_element_text(lv_obj_t * liste) * @param liste pointer to a list element (button) * @return pointer to the label from the list element or NULL if not found */ -lv_obj_t * lv_list_get_element_label(lv_obj_t * liste) +lv_obj_t * lv_list_get_btn_label(lv_obj_t * liste) { lv_obj_t * label = lv_obj_get_child(liste, NULL); if(label == NULL) return NULL; - while(label->signal_func != lv_label_signal) { + while(label->signal_func != label_signal) { label = lv_obj_get_child(liste, label); if(label == NULL) break; } @@ -441,13 +406,13 @@ lv_obj_t * lv_list_get_element_label(lv_obj_t * liste) * @param liste pointer to a list element (button) * @return pointer to the image from the list element or NULL if not found */ -lv_obj_t * lv_list_get_element_img(lv_obj_t * liste) +lv_obj_t * lv_list_get_btn_img(lv_obj_t * liste) { #if USE_LV_IMG != 0 && USE_FSINT != 0 lv_obj_t * img = lv_obj_get_child(liste, NULL); if(img == NULL) return NULL; - while(img->signal_func != lv_img_signal) { + while(img->signal_func != img_signal) { img = lv_obj_get_child(liste, img); if(img == NULL) break; } @@ -458,24 +423,13 @@ lv_obj_t * lv_list_get_element_img(lv_obj_t * liste) #endif } -/** - * Get the scroll bar outside attribute - * @param list pointer to list object - * @param en true: scroll bar outside the buttons, false: scroll bar inside - */ -bool lv_list_get_sb_out(lv_obj_t * list, bool en) -{ - lv_list_ext_t * ext = lv_obj_get_ext_attr(list); - return ext->sb_out == 0 ? false : true; -} - /** * Get the style of the list elements in a given state * @param list pointer to a list object * @param state a state from 'lv_btn_state_t' in which style should be get * @return pointer to the style in the given state */ -lv_style_t * lv_list_get_style_liste(lv_obj_t * list, lv_btn_state_t state) +lv_style_t * lv_list_get_style_btn(lv_obj_t * list, lv_btn_state_t state) { lv_list_ext_t * ext = lv_obj_get_ext_attr(list); @@ -484,49 +438,10 @@ lv_style_t * lv_list_get_style_liste(lv_obj_t * list, lv_btn_state_t state) return ext->styles_btn[state]; } - -/** - * Get the style of the list elements images - * @param list pointer to a list object - * @return pointer to the image style - */ -lv_style_t * lv_list_get_style_img(lv_obj_t * list, lv_btn_state_t state) -{ - lv_list_ext_t * ext = lv_obj_get_ext_attr(list); - - if(ext->style_img == NULL) return lv_list_get_style_liste(list, LV_BTN_STATE_RELEASED); - - return ext->style_img; -} - /********************** * STATIC FUNCTIONS **********************/ -#if 0 /*A new design function is not necessary*/ -/** - * Handle the drawing related tasks of the lists - * @param list pointer to an object - * @param mask 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 true/false, depends on 'mode' - */ -static bool lv_list_design(lv_obj_t * list, const area_t * mask, lv_design_mode_t mode) -{ - if(mode == LV_DESIGN_COVER_CHK) { - /*Return false if the object is not covers the mask_p area*/ - return false; - } - - /*Draw the object*/ - - return true; -} -#endif - /** * Get the next button from list * @param list pointer to a list object @@ -544,7 +459,7 @@ static lv_obj_t * lv_list_get_next_btn(lv_obj_t * list, lv_obj_t * prev_btn) btn = lv_obj_get_child(scrl, prev_btn); if(btn == NULL) return NULL; - while(btn->signal_func != lv_btn_signal) { + while(btn->signal_func != btn_signal) { btn = lv_obj_get_child(scrl, prev_btn); if(btn == NULL) break; } diff --git a/lv_objx/lv_list.h b/lv_objx/lv_list.h index d1ca4be16..f48b58ef7 100644 --- a/lv_objx/lv_list.h +++ b/lv_objx/lv_list.h @@ -50,7 +50,6 @@ typedef struct /*New data for this type */ 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*/ - uint8_t sb_out :1; /*1: Keep space for the scrollbar*/ }lv_list_ext_t; /********************** @@ -101,7 +100,7 @@ void lv_list_down(lv_obj_t * list); * @param out true: reduce the buttons width therefore scroll bar will be out of the buttons, * false: keep button size and place scroll bar on the buttons */ -void lv_list_set_sb_out(lv_obj_t * list, bool out); +void lv_list_set_sscrollbar_out(lv_obj_t * list, bool out); /** * Set styles of the list elements of a list in each state @@ -112,17 +111,10 @@ void lv_list_set_sb_out(lv_obj_t * list, bool out); * @param tpr pointer to a style for toggled pressed state * @param ina pointer to a style for inactive state */ -void lv_list_set_btn_styles(lv_obj_t * list, lv_style_t * rel, lv_style_t * pr, +void lv_list_set_style_btn(lv_obj_t * list, lv_style_t * rel, lv_style_t * pr, lv_style_t * trel, lv_style_t * tpr, lv_style_t * ina); -/** - * Set the styles of the list element image (typically to set symbol font) - * @param list pointer to list object - * @param style pointer to the new style of the button images - */ -void lv_list_set_style_img(lv_obj_t * list, lv_style_t * style); - /** * Get the text of a list element * @param liste pointer to list element @@ -135,14 +127,14 @@ const char * lv_list_get_element_text(lv_obj_t * liste); * @param liste pointer to a list element (button) * @return pointer to the label from the list element or NULL if not found */ -lv_obj_t * lv_list_get_element_label(lv_obj_t * liste); +lv_obj_t * lv_list_get_btn_label(lv_obj_t * liste); /** * Get the image object from a list element * @param liste pointer to a list element (button) * @return pointer to the image from the list element or NULL if not found */ -lv_obj_t * lv_list_get_element_img(lv_obj_t * liste); +lv_obj_t * lv_list_get_btn_img(lv_obj_t * liste); /** * Get the scroll bar outside attribute @@ -157,14 +149,23 @@ bool lv_list_get_sb_out(lv_obj_t * list, bool en); * @param state a state from 'lv_btn_state_t' in which style should be get * @return pointer to the style in the given state */ -lv_style_t * lv_list_get_style_liste(lv_obj_t * list, lv_btn_state_t state); +lv_style_t * lv_list_get_style_btne(lv_obj_t * list, lv_btn_state_t state); + +/**************************** + * TRANSPARENT API FUNCTIONS + ***************************/ /** - * Get the style of the list elements images + * Set a new styles for the list * @param list pointer to a list object - * @return pointer to the image style + * @param bg pointer to a style for the background (typically transparent) + * @param scrl pointer to a style for the scrollable area + * @param sb pointer to a style for the scroll bars */ -lv_style_t * lv_list_get_style_img(lv_obj_t * list, lv_btn_state_t state); +static inline void lv_list_set_style_bg(lv_obj_t *list, lv_style_t *bg, lv_style_t *scrl, lv_style_t *sb) +{ + lv_page_set_style(list, bg, scrl, sb); +} /********************** * MACROS diff --git a/lv_objx/lv_lmeter.c b/lv_objx/lv_lmeter.c index a608fcf7f..b60a91354 100644 --- a/lv_objx/lv_lmeter.c +++ b/lv_objx/lv_lmeter.c @@ -51,7 +51,7 @@ static bool lv_lmeter_design(lv_obj_t * lmeter, const area_t * mask, lv_design_m lv_obj_t * lv_lmeter_create(lv_obj_t * par, lv_obj_t * copy) { /*Create the ancestor of line meter*/ - lv_obj_t * new_lmeter = lv_bar_create(par, copy); + lv_obj_t * new_lmeter = lv_obj_create(par, copy); dm_assert(new_lmeter); /*Allocate the line meter type specific extended data*/ @@ -59,7 +59,10 @@ lv_obj_t * lv_lmeter_create(lv_obj_t * par, lv_obj_t * copy) dm_assert(ext); /*Initialize the allocated 'ext' */ - ext->scale_num = 31; /*Odd scale number looks better*/ + ext->min_value = 0; + ext->max_value = 100; + ext->cur_value = 0; + ext->line_cnt = 31; /*Odd scale number looks better*/ ext->scale_angle = 240; /*(scale_num - 1) * N looks better */ /*The signal and design functions are not copied so set them here*/ @@ -75,8 +78,10 @@ lv_obj_t * lv_lmeter_create(lv_obj_t * par, lv_obj_t * copy) else { lv_lmeter_ext_t * copy_ext = lv_obj_get_ext_attr(copy); ext->scale_angle = copy_ext->scale_angle; - ext->scale_num = copy_ext->scale_num; - + ext->line_cnt = copy_ext->line_cnt; + ext->min_value = copy_ext->min_value; + ext->max_value = copy_ext->max_value; + ext->cur_value = copy_ext->cur_value; /*Refresh the style with new signal function*/ lv_obj_refresh_style(new_lmeter); @@ -97,7 +102,7 @@ bool lv_lmeter_signal(lv_obj_t * lmeter, lv_signal_t sign, void * param) bool valid; /* Include the ancient signal function */ - valid = lv_bar_signal(lmeter, sign, param); + valid = lv_obj_signal(lmeter, sign, param); /* The object can be deleted so check its validity and then * make the object specific signal handling */ @@ -114,17 +119,52 @@ bool lv_lmeter_signal(lv_obj_t * lmeter, lv_signal_t sign, void * param) * Setter functions *====================*/ +/** + * Set a new value on the line meter + * @param lmeter pointer to a line meter object + * @param value new value + */ +void lv_lmeter_set_value(lv_obj_t *lmeter, int16_t value) +{ + lv_lmeter_ext_t * ext = lv_obj_get_ext_attr(lmeter); + ext->cur_value = value > ext->max_value ? ext->max_value : value; + ext->cur_value = ext->cur_value < ext->min_value ? ext->min_value : ext->cur_value; + lv_obj_invalidate(lmeter); +} + +/** + * Set minimum and the maximum values of a line meter + * @param lmeter pointer to he line meter object + * @param min minimum value + * @param max maximum value + */ +void lv_lmeter_set_range(lv_obj_t *lmeter, int16_t min, int16_t max) +{ + lv_lmeter_ext_t * ext = lv_obj_get_ext_attr(lmeter); + ext->max_value = max; + ext->min_value = min; + if(ext->cur_value > max) { + ext->cur_value = max; + lv_lmeter_set_value(lmeter, ext->cur_value); + } + if(ext->cur_value < min) { + ext->cur_value = min; + lv_lmeter_set_value(lmeter, ext->cur_value); + } + lv_obj_invalidate(lmeter); +} + /** * Set the scale settings of a line meter * @param lmeter pointer to a line meter object * @param angle angle of the scale (0..360) - * @param num number of scale units + * @param line_cnt number of lines */ -void lv_lmeter_set_scale(lv_obj_t * lmeter, uint16_t angle, uint8_t num) +void lv_lmeter_set_scale(lv_obj_t * lmeter, uint16_t angle, uint8_t line_cnt) { lv_lmeter_ext_t * ext = lv_obj_get_ext_attr(lmeter); ext->scale_angle = angle; - ext->scale_num = num; + ext->line_cnt = line_cnt; lv_obj_invalidate(lmeter); } @@ -134,15 +174,48 @@ void lv_lmeter_set_scale(lv_obj_t * lmeter, uint16_t angle, uint8_t num) * Getter functions *====================*/ +/** + * Get the value of a line meter + * @param lmeter pointer to a line meter object + * @return the value of the line meter + */ +int16_t lv_lmeter_get_value(lv_obj_t *lmeter) +{ + lv_lmeter_ext_t * ext = lv_obj_get_ext_attr(lmeter); + return ext->cur_value; +} + +/** + * Get the minimum value of a line meter + * @param lmeter pointer to a line meter object + * @return the minimum value of the line meter + */ +int16_t lv_lmeter_get_min_value(lv_obj_t * lmeter) +{ + lv_lmeter_ext_t * ext = lv_obj_get_ext_attr(lmeter); + return ext->min_value; +} + +/** + * Get the maximum value of a line meter + * @param lmeter pointer to a line meter object + * @return the maximum value of the line meter + */ +int16_t lv_lmeter_get_max_value(lv_obj_t * lmeter) +{ + lv_lmeter_ext_t * ext = lv_obj_get_ext_attr(lmeter); + return ext->max_value; +} + /** * Get the scale number of a line meter * @param lmeter pointer to a line meter object * @return number of the scale units */ -uint8_t lv_lmeter_get_scale_num(lv_obj_t * lmeter) +uint8_t lv_lmeter_get_line_count(lv_obj_t * lmeter) { lv_lmeter_ext_t * ext = lv_obj_get_ext_attr(lmeter); - return ext->scale_num ; + return ext->line_cnt ; } /** @@ -190,16 +263,14 @@ static bool lv_lmeter_design(lv_obj_t * lmeter, const area_t * mask, lv_design_m cord_t x_ofs = lv_obj_get_width(lmeter) / 2 + lmeter->coords.x1; cord_t y_ofs = lv_obj_get_height(lmeter) / 2 + lmeter->coords.y1; int16_t angle_ofs = 90 + (360 - ext->scale_angle) / 2; - int16_t min = lv_bar_get_min_value(lmeter); - int16_t max = lv_bar_get_max_value(lmeter); - int16_t level = (int32_t)((int32_t)(lv_bar_get_value(lmeter) - min) * ext->scale_num) / (max - min); + int16_t level = (int32_t)((int32_t)(ext->cur_value - ext->min_value) * ext->line_cnt) / (ext->max_value - ext->min_value); uint8_t i; style_tmp.line.color = style->body.color_main; - for(i = 0; i < ext->scale_num; i++) { + for(i = 0; i < ext->line_cnt; i++) { /*Calculate the position a scale label*/ - int16_t angle = (i * ext->scale_angle) / (ext->scale_num - 1) + angle_ofs; + int16_t angle = (i * ext->scale_angle) / (ext->line_cnt - 1) + angle_ofs; cord_t y_out = (int32_t)((int32_t)trigo_sin(angle) * r_out) / TRIGO_SIN_MAX; cord_t x_out = (int32_t)((int32_t)trigo_sin(angle + 90) * r_out) / TRIGO_SIN_MAX; @@ -217,7 +288,7 @@ static bool lv_lmeter_design(lv_obj_t * lmeter, const area_t * mask, lv_design_m if(i > level) style_tmp.line.color = style->line.color; else { - style_tmp.line.color = color_mix(style->body.color_gradient, style->body.color_main, (255 * i) / ext->scale_num); + style_tmp.line.color = color_mix(style->body.color_gradient, style->body.color_main, (255 * i) / ext->line_cnt); } lv_draw_line(&p1, &p2, mask, &style_tmp); diff --git a/lv_objx/lv_lmeter.h b/lv_objx/lv_lmeter.h index 12badccdf..cce2ca2a3 100644 --- a/lv_objx/lv_lmeter.h +++ b/lv_objx/lv_lmeter.h @@ -18,17 +18,12 @@ extern "C" { #if USE_LV_LMETER != 0 /*Testing of dependencies*/ -#if USE_LV_BAR == 0 -#error "lv_lmeter: lv_bar is required. Enable it in lv_conf.h (USE_LV_BAR 1) " -#endif - #if USE_TRIGO == 0 #error "lv_lmeter: trigo is required. Enable it in misc_conf.h (USE_TRIGO 1) " #endif #include "../lv_obj/lv_obj.h" -#include "lv_bar.h" /********************* * DEFINES @@ -40,10 +35,13 @@ extern "C" { /*Data of line meter*/ typedef struct { - lv_bar_ext_t bar; /*Ext. of ancestor*/ + /*No inherited ext.*/ /*Ext. of ancestor*/ /*New data for this type */ uint16_t scale_angle; /*Angle of the scale in deg. (0..360)*/ - uint8_t scale_num; /*Number of scale units */ + uint8_t line_cnt; /*Count of lines */ + int16_t cur_value; + int16_t min_value; + int16_t max_value; }lv_lmeter_ext_t; /********************** @@ -67,6 +65,21 @@ lv_obj_t * lv_lmeter_create(lv_obj_t * par, lv_obj_t * copy); */ bool lv_lmeter_signal(lv_obj_t * lmeter, lv_signal_t sign, void * param); +/** + * Set a new value on the line meter + * @param lmeter pointer to a line meter object + * @param value new value + */ +void lv_lmeter_set_value(lv_obj_t *lmeter, int16_t value); + +/** + * Set minimum and the maximum values of a line meter + * @param lmeter pointer to he line meter object + * @param min minimum value + * @param max maximum value + */ +void lv_lmeter_set_range(lv_obj_t *lmeter, int16_t min, int16_t max); + /** * Set the scale settings of a line meter * @param lmeter pointer to a line meter object @@ -75,12 +88,33 @@ bool lv_lmeter_signal(lv_obj_t * lmeter, lv_signal_t sign, void * param); */ void lv_lmeter_set_scale(lv_obj_t * lmeter, uint16_t angle, uint8_t num); +/** + * Get the value of a line meter + * @param lmeter pointer to a line meter object + * @return the value of the line meter + */ +int16_t lv_lmeter_get_value(lv_obj_t *lmeter); + +/** + * Get the minimum value of a line meter + * @param lmeter pointer to a line meter object + * @return the minimum value of the line meter + */ +int16_t lv_lmeter_get_min_value(lv_obj_t * lmeter); + +/** + * Get the maximum value of a line meter + * @param lmeter pointer to a line meter object + * @return the maximum value of the line meter + */ +int16_t lv_lmeter_get_max_value(lv_obj_t * lmeter); + /** * Get the scale number of a line meter * @param lmeter pointer to a line meter object * @return number of the scale units */ -uint8_t lv_lmeter_get_scale_num(lv_obj_t * lmeter); +uint8_t lv_lmeter_get_line_count(lv_obj_t * lmeter); /** * Get the scale angle of a line meter @@ -88,6 +122,32 @@ uint8_t lv_lmeter_get_scale_num(lv_obj_t * lmeter); * @return angle of the scale */ uint16_t lv_lmeter_get_scale_angle(lv_obj_t * lmeter); + +/**************************** + * TRANSPARENT API FUNCTIONS + ***************************/ +/** + * Set the styles of a line meter + * @param lmeter pointer to a line meter object + * @param style set the style of the line meter + * */ +static inline void lv_lmeter_set_style(lv_obj_t *lmeter, lv_style_t *style) +{ + lv_obj_set_style(lmeter, style); +} + + +/** + * Get the style of a line meter + * @param lmeter pointer to a line meter object + * @return pointer to the line meter's style + */ +static inline lv_style_t * lv_lmeter_get_style(lv_obj_t * lmeter) +{ + return lv_obj_get_style(lmeter); +} + + /********************** * MACROS **********************/ diff --git a/lv_objx/lv_mbox.c b/lv_objx/lv_mbox.c index 71e633726..cd8357baf 100644 --- a/lv_objx/lv_mbox.c +++ b/lv_objx/lv_mbox.c @@ -27,15 +27,15 @@ /********************** * STATIC PROTOTYPES **********************/ -#if 0 /*Unused*/ -static bool lv_mbox_design(lv_obj_t * mbox, const area_t * mask, lv_design_mode_t mode); -#endif +static lv_res_t lv_mbox_signal(lv_obj_t * mbox, lv_signal_t sign, void * param); static void lv_mbox_realign(lv_obj_t * mbox); static void lv_mbox_disable_fit(lv_obj_t * mbox); /********************** * STATIC VARIABLES **********************/ +static lv_signal_func_t ancestor_signal; + /********************** * MACROS **********************/ @@ -59,6 +59,7 @@ lv_obj_t * lv_mbox_create(lv_obj_t * par, lv_obj_t * copy) /*Create the ancestor message box*/ lv_obj_t * new_mbox = lv_cont_create(par, copy); dm_assert(new_mbox); + if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_func(new_mbox); /*Allocate the message box type specific extended data*/ lv_mbox_ext_t * ext = lv_obj_allocate_ext_attr(new_mbox, sizeof(lv_mbox_ext_t)); @@ -106,136 +107,6 @@ lv_obj_t * lv_mbox_create(lv_obj_t * par, lv_obj_t * copy) return new_mbox; } -/** - * Signal function of the message box - * @param mbox pointer to a message box object - * @param sign a signal type from lv_signal_t enum - * @param param pointer to a signal specific variable - * @return true: the object is still valid (not deleted), false: the object become invalid - */ -bool lv_mbox_signal(lv_obj_t * mbox, lv_signal_t sign, void * param) -{ - bool valid; - - /* Include the ancient signal function */ - valid = lv_cont_signal(mbox, sign, param); - - /* The object can be deleted so check its validity and then - * make the object specific signal handling */ - if(valid != false) { - lv_mbox_ext_t * ext = lv_obj_get_ext_attr(mbox); - - if(sign == LV_SIGNAL_CORD_CHG) { - /*If the size is changed refresh the message box*/ - if(area_get_width(param) != lv_obj_get_width(mbox) || - area_get_height(param) != lv_obj_get_height(mbox)) { - lv_mbox_realign(mbox); - } - } else if(sign == LV_SIGNAL_LONG_PRESS) { - lv_mbox_start_auto_close(mbox, 0); - lv_indev_wait_release(param); - valid = false; - } else if(sign == LV_SIGNAL_STYLE_CHG) { - /*Refresh all the buttons*/ - if(ext->btnh != NULL) { - lv_obj_t * btn; - btn = lv_obj_get_child(ext->btnh, NULL); - while(btn != NULL) { - /*Refresh the next button's style*/ - lv_btn_set_style(btn, ext->style_btn_rel, ext->style_btn_pr, NULL, NULL, NULL); - btn = lv_obj_get_child(ext->btnh, btn); - } - } - } else if(sign == LV_SIGNAL_FOCUS) { - /*Get the first button*/ - if(ext->btnh != NULL) { - lv_obj_t * btn = NULL; - lv_obj_t * btn_prev = NULL; - btn = lv_obj_get_child(ext->btnh, btn); - while(btn != NULL) { - btn_prev = btn; - btn = lv_obj_get_child(ext->btnh, btn); - } - if(btn_prev != NULL) { - lv_btn_set_state(btn_prev, LV_BTN_STATE_PRESSED); - } - } - } else if(sign == LV_SIGNAL_DEFOCUS) { - /*Get the 'pressed' button*/ - if(ext->btnh != NULL) { - lv_obj_t * btn = NULL; - btn = lv_obj_get_child(ext->btnh, btn); - while(btn != NULL) { - if(lv_btn_get_state(btn) == LV_BTN_STATE_PRESSED) break; - btn = lv_obj_get_child(ext->btnh, btn); - } - - if(btn != NULL) { - lv_btn_set_state(btn, LV_BTN_STATE_RELEASED); - } - } - } else if(sign == LV_SIGNAL_CONTROLL) { - lv_mbox_ext_t * ext = lv_obj_get_ext_attr(mbox); - char c = *((char*)param); - if(c == LV_GROUP_KEY_RIGHT || c == LV_GROUP_KEY_UP) { - /*Get the last pressed button*/ - if(ext->btnh != NULL) { - lv_obj_t * btn = NULL; - lv_obj_t * btn_prev = NULL; - btn = lv_obj_get_child(ext->btnh, btn); - while(btn != NULL) { - if(lv_btn_get_state(btn) == LV_BTN_STATE_PRESSED) break; - btn_prev = btn; - btn = lv_obj_get_child(ext->btnh, btn); - } - - if(btn_prev != NULL && btn != NULL) { - lv_btn_set_state(btn, LV_BTN_STATE_RELEASED); - lv_btn_set_state(btn_prev, LV_BTN_STATE_PRESSED); - } - } - } else if(c == LV_GROUP_KEY_LEFT || c == LV_GROUP_KEY_DOWN) { - /*Get the last pressed button*/ - if(ext->btnh != NULL) { - lv_obj_t * btn = NULL; - btn = lv_obj_get_child(ext->btnh, btn); - while(btn != NULL) { - if(lv_btn_get_state(btn) == LV_BTN_STATE_PRESSED) break; - btn = lv_obj_get_child(ext->btnh, btn); - } - - if(btn != NULL) { - lv_obj_t * btn_prev = lv_obj_get_child(ext->btnh, btn); - if(btn_prev != NULL) { - lv_btn_set_state(btn, LV_BTN_STATE_RELEASED); - lv_btn_set_state(btn_prev, LV_BTN_STATE_PRESSED); - } - } - - } - } else if(c == LV_GROUP_KEY_ENTER) { - /*Get the 'pressed' button*/ - if(ext->btnh != NULL) { - lv_obj_t * btn = NULL; - btn = lv_obj_get_child(ext->btnh, btn); - while(btn != NULL) { - if(lv_btn_get_state(btn) == LV_BTN_STATE_PRESSED) break; - btn = lv_obj_get_child(ext->btnh, btn); - } - - if(btn != NULL) { - lv_action_t rel_action; - rel_action = lv_btn_get_action(btn, LV_BTN_ACTION_RELEASE); - if(rel_action != NULL) rel_action(btn); - } - } - } - } - } - - return valid; -} - /** * A release action which can be assigned to a message box button to close it * @param btn pointer to the released button @@ -428,30 +299,136 @@ lv_style_t * lv_mbox_get_style_btn(lv_obj_t * mbox, lv_btn_state_t state) * STATIC FUNCTIONS **********************/ -#if 0 /*Not used*/ + /** - * Handle the drawing related tasks of the message boxs - * @param mbox pointer to an object - * @param mask 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 true/false, depends on 'mode' + * Signal function of the message box + * @param mbox pointer to a message box object + * @param sign a signal type from lv_signal_t enum + * @param param pointer to a signal specific variable + * @return LV_RES_OK: the object is not deleted in the function; LV_RES_INV: the object is deleted */ -static bool lv_mbox_design(lv_obj_t * mbox, const area_t * mask, lv_design_mode_t mode) +static lv_res_t lv_mbox_signal(lv_obj_t * mbox, lv_signal_t sign, void * param) { - if(mode == LV_DESIGN_COVER_CHK) { - /*Return false if the object is not covers the mask_p area*/ - return false; + lv_res_t res; + + /* Include the ancient signal function */ + res = ancestor_signal(mbox, sign, param); + + /* The object can be deleted so check its validity and then + * make the object specific signal handling */ + if(res == LV_RES_OK) { + lv_mbox_ext_t * ext = lv_obj_get_ext_attr(mbox); + + if(sign == LV_SIGNAL_CORD_CHG) { + /*If the size is changed refresh the message box*/ + if(area_get_width(param) != lv_obj_get_width(mbox) || + area_get_height(param) != lv_obj_get_height(mbox)) { + lv_mbox_realign(mbox); + } + } else if(sign == LV_SIGNAL_LONG_PRESS) { + lv_mbox_start_auto_close(mbox, 0); + lv_indev_wait_release(param); + res = LV_RES_INV; + } else if(sign == LV_SIGNAL_STYLE_CHG) { + /*Refresh all the buttons*/ + if(ext->btnh != NULL) { + lv_obj_t * btn; + btn = lv_obj_get_child(ext->btnh, NULL); + while(btn != NULL) { + /*Refresh the next button's style*/ + lv_btn_set_style(btn, ext->style_btn_rel, ext->style_btn_pr, NULL, NULL, NULL); + btn = lv_obj_get_child(ext->btnh, btn); + } + } + } else if(sign == LV_SIGNAL_FOCUS) { + /*Get the first button*/ + if(ext->btnh != NULL) { + lv_obj_t * btn = NULL; + lv_obj_t * btn_prev = NULL; + btn = lv_obj_get_child(ext->btnh, btn); + while(btn != NULL) { + btn_prev = btn; + btn = lv_obj_get_child(ext->btnh, btn); + } + if(btn_prev != NULL) { + lv_btn_set_state(btn_prev, LV_BTN_STATE_PRESSED); + } + } + } else if(sign == LV_SIGNAL_DEFOCUS) { + /*Get the 'pressed' button*/ + if(ext->btnh != NULL) { + lv_obj_t * btn = NULL; + btn = lv_obj_get_child(ext->btnh, btn); + while(btn != NULL) { + if(lv_btn_get_state(btn) == LV_BTN_STATE_PRESSED) break; + btn = lv_obj_get_child(ext->btnh, btn); + } + + if(btn != NULL) { + lv_btn_set_state(btn, LV_BTN_STATE_RELEASED); + } + } + } else if(sign == LV_SIGNAL_CONTROLL) { + lv_mbox_ext_t * ext = lv_obj_get_ext_attr(mbox); + char c = *((char*)param); + if(c == LV_GROUP_KEY_RIGHT || c == LV_GROUP_KEY_UP) { + /*Get the last pressed button*/ + if(ext->btnh != NULL) { + lv_obj_t * btn = NULL; + lv_obj_t * btn_prev = NULL; + btn = lv_obj_get_child(ext->btnh, btn); + while(btn != NULL) { + if(lv_btn_get_state(btn) == LV_BTN_STATE_PRESSED) break; + btn_prev = btn; + btn = lv_obj_get_child(ext->btnh, btn); + } + + if(btn_prev != NULL && btn != NULL) { + lv_btn_set_state(btn, LV_BTN_STATE_RELEASED); + lv_btn_set_state(btn_prev, LV_BTN_STATE_PRESSED); + } + } + } else if(c == LV_GROUP_KEY_LEFT || c == LV_GROUP_KEY_DOWN) { + /*Get the last pressed button*/ + if(ext->btnh != NULL) { + lv_obj_t * btn = NULL; + btn = lv_obj_get_child(ext->btnh, btn); + while(btn != NULL) { + if(lv_btn_get_state(btn) == LV_BTN_STATE_PRESSED) break; + btn = lv_obj_get_child(ext->btnh, btn); + } + + if(btn != NULL) { + lv_obj_t * btn_prev = lv_obj_get_child(ext->btnh, btn); + if(btn_prev != NULL) { + lv_btn_set_state(btn, LV_BTN_STATE_RELEASED); + lv_btn_set_state(btn_prev, LV_BTN_STATE_PRESSED); + } + } + + } + } else if(c == LV_GROUP_KEY_ENTER) { + /*Get the 'pressed' button*/ + if(ext->btnh != NULL) { + lv_obj_t * btn = NULL; + btn = lv_obj_get_child(ext->btnh, btn); + while(btn != NULL) { + if(lv_btn_get_state(btn) == LV_BTN_STATE_PRESSED) break; + btn = lv_obj_get_child(ext->btnh, btn); + } + + if(btn != NULL) { + lv_action_t rel_action; + rel_action = lv_btn_get_action(btn, LV_BTN_ACTION_RELEASE); + if(rel_action != NULL) rel_action(btn); + } + } + } + } } - - /*Draw the object*/ - - return true; + return res; } -#endif /** * Realign the elements of the message box diff --git a/lv_objx/lv_mbox.h b/lv_objx/lv_mbox.h index f9c2ac21e..c0694618b 100644 --- a/lv_objx/lv_mbox.h +++ b/lv_objx/lv_mbox.h @@ -67,15 +67,6 @@ typedef struct */ lv_obj_t * lv_mbox_create(lv_obj_t * par, lv_obj_t * copy); -/** - * Signal function of the message box - * @param mbox pointer to a message box object - * @param sign a signal type from lv_signal_t enum - * @param param pointer to a signal specific variable - * @return true: the object is still valid (not deleted), false: the object become invalid - */ -bool lv_mbox_signal(lv_obj_t * mbox, lv_signal_t sign, void * param); - /** * A release action which can be assigned to a message box button to close it * @param btn pointer to the released button diff --git a/lv_objx/lv_page.c b/lv_objx/lv_page.c index 7a0b319a9..6d5f18169 100644 --- a/lv_objx/lv_page.c +++ b/lv_objx/lv_page.c @@ -12,7 +12,6 @@ #include "misc/math/math_base.h" #include "../lv_obj/lv_group.h" #include "../lv_objx/lv_page.h" -#include "../lv_objx/lv_cont.h" #include "../lv_draw/lv_draw.h" #include "../lv_obj/lv_refr.h" #include "misc/gfx/anim.h" @@ -20,6 +19,7 @@ /********************* * DEFINES *********************/ +#define LV_PAGE_SB_MIN_SIZE (LV_DPI / 8) /********************** * TYPEDEFS @@ -31,12 +31,14 @@ static void lv_page_sb_refresh(lv_obj_t * main); static bool lv_page_design(lv_obj_t * scrl, const area_t * mask, lv_design_mode_t mode); static bool lv_scrl_design(lv_obj_t * scrl, const area_t * mask, lv_design_mode_t mode); +static lv_res_t lv_page_signal(lv_obj_t * page, lv_signal_t sign, void * param); +static lv_res_t lv_page_scrollable_signal(lv_obj_t * scrl, lv_signal_t sign, void * param); /********************** * STATIC VARIABLES **********************/ -static lv_design_func_t ancestor_page_design_f; -static lv_design_func_t ancestor_scrl_design_f; +static lv_signal_func_t ancestor_signal; +static lv_design_func_t ancestor_design; /********************** * MACROS @@ -61,6 +63,8 @@ lv_obj_t * lv_page_create(lv_obj_t * par, lv_obj_t * copy) /*Create the ancestor object*/ lv_obj_t * new_page = lv_cont_create(par, copy); dm_assert(new_page); + if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_func(new_page); + if(ancestor_design == NULL) ancestor_design = lv_obj_get_design_func(new_page); /*Allocate the object type specific extended data*/ lv_page_ext_t * ext = lv_obj_allocate_ext_attr(new_page, sizeof(lv_page_ext_t)); @@ -68,46 +72,36 @@ lv_obj_t * lv_page_create(lv_obj_t * par, lv_obj_t * copy) ext->scrl = NULL; ext->pr_action = NULL; ext->rel_action = NULL; - ext->sbh_draw = 0; - ext->sbv_draw = 0; - ext->style_sb = &lv_style_pretty; - ext->sb_width = LV_DPI / 8; /*Will be modified later*/ - ext->sb_mode = LV_PAGE_SB_MODE_ON; - - if(ancestor_page_design_f == NULL) ancestor_page_design_f = lv_obj_get_design_func(new_page); + ext->sb.hor_draw = 0; + ext->sb.ver_draw = 0; + ext->sb.style = &lv_style_pretty; + ext->sb.mode = LV_PAGE_SB_MODE_AUTO; /*Init the new page object*/ if(copy == NULL) { - lv_style_t * style = &lv_style_pretty_color; ext->scrl = lv_cont_create(new_page, NULL); - if(ancestor_scrl_design_f == NULL) ancestor_scrl_design_f = lv_obj_get_design_func(ext->scrl); - lv_obj_set_signal_func(ext->scrl, lv_page_scrl_signal); + lv_obj_set_signal_func(ext->scrl, lv_page_scrollable_signal); + lv_obj_set_design_func(ext->scrl, lv_scrl_design); lv_obj_set_drag(ext->scrl, true); lv_obj_set_drag_throw(ext->scrl, true); lv_obj_set_protect(ext->scrl, LV_PROTECT_PARENT); lv_cont_set_fit(ext->scrl, false, true); - lv_obj_set_style(ext->scrl, &lv_style_pretty); - lv_obj_set_design_func(ext->scrl, lv_scrl_design); - - lv_page_set_sb_width(new_page, style->body.padding.hor); - lv_page_set_sb_mode(new_page, ext->sb_mode); - lv_page_set_style_sb(new_page, ext->style_sb); /* Add the signal function only if 'scrolling' is created * because everything has to be ready before any signal is received*/ lv_obj_set_signal_func(new_page, lv_page_signal); lv_obj_set_design_func(new_page, lv_page_design); - lv_obj_set_style(new_page, style); + lv_page_set_style(new_page, &lv_style_pretty_color, &lv_style_pretty, &lv_style_pretty_color); + lv_page_set_sb_mode(new_page, ext->sb.mode); } else { lv_page_ext_t * copy_ext = lv_obj_get_ext_attr(copy); ext->scrl = lv_cont_create(new_page, copy_ext->scrl); - lv_obj_set_signal_func(ext->scrl, lv_page_scrl_signal); + lv_obj_set_signal_func(ext->scrl, lv_page_scrollable_signal); - lv_page_set_pr_action(new_page, copy_ext->pr_action); - lv_page_set_rel_action(new_page, copy_ext->rel_action); - lv_page_set_sb_mode(new_page, copy_ext->sb_mode); - lv_page_set_sb_width(new_page, copy_ext->sb_width); - lv_page_set_style_sb(new_page, copy_ext->style_sb); + lv_page_set_press_action(new_page, copy_ext->pr_action); + lv_page_set_release_action(new_page, copy_ext->rel_action); + lv_page_set_sb_mode(new_page, copy_ext->sb.mode); + lv_page_set_style(new_page, lv_obj_get_style(copy), lv_obj_get_style(copy_ext->scrl), copy_ext->sb.style); /* Add the signal function only if 'scrolling' is created * because everything has to be ready before any signal is received*/ @@ -123,26 +117,302 @@ lv_obj_t * lv_page_create(lv_obj_t * par, lv_obj_t * copy) return new_page; } +/*===================== + * Setter functions + *====================*/ + +/** + * Set a release action for the page + * @param page pointer to a page object + * @param rel_action a function to call when the page is released + */ +void lv_page_set_release_action(lv_obj_t * page, lv_action_t rel_action) +{ + lv_page_ext_t * ext = lv_obj_get_ext_attr(page); + ext->rel_action = rel_action; +} + +/** + * Set a press action for the page + * @param page pointer to a page object + * @param pr_action a function to call when the page is pressed + */ +void lv_page_set_press_action(lv_obj_t * page, lv_action_t pr_action) +{ + lv_page_ext_t * ext = lv_obj_get_ext_attr(page); + ext->pr_action = pr_action; +} + +/** + * Set the scroll bar mode on a page + * @param page pointer to a page object + * @param sb.mode the new mode from 'lv_page_sb.mode_t' enum + */ +void lv_page_set_sb_mode(lv_obj_t * page, lv_page_sb_mode_t sb_mode) +{ + lv_page_ext_t * ext = lv_obj_get_ext_attr(page); + ext->sb.mode = sb_mode; + ext->sb.hor_draw = 0; + ext->sb.ver_draw = 0; + lv_page_sb_refresh(page); + lv_obj_invalidate(page); +} + +/** + * Set a new styles for the page + * @param page pointer to a page object + * @param bg pointer to a style for the background + * @param scrl pointer to a style for the scrollable area + * @param sb pointer to a style for the scroll bars + */ +void lv_page_set_style(lv_obj_t *page, lv_style_t *bg, lv_style_t *scrl, lv_style_t *sb) +{ + lv_page_ext_t * ext = lv_obj_get_ext_attr(page); + if(sb != NULL) { + ext->sb.style = sb; + area_set_height(&ext->sb.hor_area, ext->sb.style->body.padding.inner); + area_set_width(&ext->sb.ver_area, ext->sb.style->body.padding.inner); + lv_page_sb_refresh(page); + lv_obj_invalidate(page); + } + if(scrl != NULL) lv_obj_set_style(ext->scrl, scrl); + if(bg != NULL) lv_obj_set_style(page, bg); + +} + +/** + * Glue the object to the page. After it the page can be moved (dragged) with this object too. + * @param obj pointer to an object on a page + * @param glue true: enable glue, false: disable glue + */ +void lv_page_glue_obj(lv_obj_t * obj, bool glue) +{ + lv_obj_set_drag_parent(obj, glue); + lv_obj_set_drag(obj, glue); +} + +/** + * Focus on an object. It ensures that the object will be visible on the page. + * @param page pointer to a page object + * @param obj pointer to an object to focus (must be on the page) + * @param anim_time scroll animation time in milliseconds (0: no animation) + */ +void lv_page_focus(lv_obj_t * page, lv_obj_t * obj, uint16_t anim_time) +{ + lv_page_ext_t * ext = lv_obj_get_ext_attr(page); + lv_style_t * style = lv_page_get_style_bg(page); + lv_style_t * style_scrl = lv_page_get_style_scrl(page); + + cord_t obj_y = obj->coords.y1 - ext->scrl->coords.y1; + cord_t obj_h = lv_obj_get_height(obj); + cord_t scrlable_y = lv_obj_get_y(ext->scrl); + cord_t page_h = lv_obj_get_height(page); + + cord_t top_err = -(scrlable_y + obj_y); + cord_t bot_err = scrlable_y + obj_y + obj_h - page_h; + + /*If obj is higher then the page focus where the "error" is smaller*/ + + /*Out of the page on the top*/ + if((obj_h <= page_h && top_err > 0) || + (obj_h > page_h && top_err < bot_err)) { + /*Calculate a new position and let some space above*/ + scrlable_y = -(obj_y - style_scrl->body.padding.ver - style->body.padding.ver); + scrlable_y += style_scrl->body.padding.ver; + } + /*Out of the page on the bottom*/ + else if((obj_h <= page_h && bot_err > 0) || + (obj_h > page_h && top_err >= bot_err)) { + /*Calculate a new position and let some space below*/ + scrlable_y = -obj_y; + scrlable_y += page_h - obj_h; + scrlable_y -= style_scrl->body.padding.ver; + } else { + /*Already in focus*/ + return; + } + + if(anim_time == 0) { + lv_obj_set_y(ext->scrl, scrlable_y); + } + else { + anim_t a; + a.act_time = 0; + a.start = lv_obj_get_y(ext->scrl); + a.end = scrlable_y; + a.time = anim_time; + a.end_cb = NULL; + a.playback = 0; + a.repeat = 0; + a.var = ext->scrl; + a.path = anim_get_path(ANIM_PATH_LIN); + a.fp = (anim_fp_t) lv_obj_set_y; + anim_create(&a); + } +} + +/*===================== + * Getter functions + *====================*/ + +/** + * Get the scrollable object of a page + * @param page pointer to a page object + * @return pointer to a container which is the scrollable part of the page + */ +lv_obj_t * lv_page_get_scrl(lv_obj_t * page) +{ + lv_page_ext_t * ext = lv_obj_get_ext_attr(page); + + return ext->scrl; +} + +/** + * Set the scroll bar mode on a page + * @param page pointer to a page object + * @return the mode from 'lv_page_sb.mode_t' enum + */ +lv_page_sb_mode_t lv_page_get_sb_mode(lv_obj_t * page) +{ + lv_page_ext_t * ext = lv_obj_get_ext_attr(page); + return ext->sb.mode; +} + +/** +* Get the style of the scrollable part of a page +* @param page pointer to a page object +* @return pointer to the style of the scrollale part +*/ +lv_style_t * lv_page_get_style_scrl(lv_obj_t * page) +{ + return lv_obj_get_style(lv_page_get_scrl(page)); +} + +/** +* Get the style of the scrolbars of a page +* @param page pointer to a page object +* @return pointer to the style of the scrollbars +*/ +lv_style_t * lv_page_get_style_sb(lv_obj_t * page) +{ + lv_page_ext_t * ext = lv_obj_get_ext_attr(page); + return ext->sb.style; +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +/** + * Handle the drawing related tasks of the pages + * @param page pointer to an object + * @param mask 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 true/false, depends on 'mode' + */ +static bool lv_page_design(lv_obj_t * scrl, const area_t * mask, lv_design_mode_t mode) +{ + if(mode == LV_DESIGN_COVER_CHK) { + return ancestor_design(scrl, mask, mode); + } else if(mode == LV_DESIGN_DRAW_MAIN) { + ancestor_design(scrl, mask, mode); + } else if(mode == LV_DESIGN_DRAW_POST) { /*Draw the scroll bars finally*/ + ancestor_design(scrl, mask, mode); + lv_page_ext_t * ext = lv_obj_get_ext_attr(scrl); + + /*Draw the scrollbars*/ + area_t sb_area; + if(ext->sb.hor_draw) { + /*Convert the relative coordinates to absolute*/ + area_cpy(&sb_area, &ext->sb.hor_area); + sb_area.x1 += scrl->coords.x1; + sb_area.y1 += scrl->coords.y1; + sb_area.x2 += scrl->coords.x1; + sb_area.y2 += scrl->coords.y1; + lv_draw_rect(&sb_area, mask, ext->sb.style); + } + + if(ext->sb.ver_draw) { + /*Convert the relative coordinates to absolute*/ + area_cpy(&sb_area, &ext->sb.ver_area); + sb_area.x1 += scrl->coords.x1; + sb_area.y1 += scrl->coords.y1; + sb_area.x2 += scrl->coords.x1; + sb_area.y2 += scrl->coords.y1; + lv_draw_rect(&sb_area, mask, ext->sb.style); + } + } + + return true; +} + +/** + * Handle the drawing related tasks of the scrollable object + * @param scrl pointer to an object + * @param mask 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 true/false, depends on 'mode' + */ +static bool lv_scrl_design(lv_obj_t * scrl, const area_t * mask, lv_design_mode_t mode) +{ + if(mode == LV_DESIGN_COVER_CHK) { + return ancestor_design(scrl, mask, mode); + } else if(mode == LV_DESIGN_DRAW_MAIN) { +#if LV_OBJ_GROUP != 0 + /* If the page is the active in a group and + * the background (page) is not visible (transparent or empty) + * then activate the style of the scrollable*/ + lv_style_t * style_ori = lv_obj_get_style(scrl); + lv_obj_t * page = lv_obj_get_parent(scrl); + lv_style_t * style_page = lv_obj_get_style(page); + lv_group_t * g = lv_obj_get_group(page); + if(style_page->body.empty != 0 || style_page->body.opa == OPA_TRANSP) { /*Background is visible?*/ + if(lv_group_get_focused(g) == page) { + lv_style_t * style_mod; + style_mod = lv_group_mod_style(g, style_ori); + scrl->style_p = style_mod; /*Temporally change the style to the activated */ + } + } +#endif + ancestor_design(scrl, mask, mode); + +#if LV_OBJ_GROUP != 0 + scrl->style_p = style_ori; /*Revert the style*/ +#endif + } else if(mode == LV_DESIGN_DRAW_POST) { + ancestor_design(scrl, mask, mode); + } + + return true; +} /** * Signal function of the page * @param page pointer to a page object * @param sign a signal type from lv_signal_t enum * @param param pointer to a signal specific variable + * @return LV_RES_OK: the object is not deleted in the function; LV_RES_INV: the object is deleted */ -bool lv_page_signal(lv_obj_t * page, lv_signal_t sign, void * param) +static lv_res_t lv_page_signal(lv_obj_t * page, lv_signal_t sign, void * param) { - bool obj_valid = true; + lv_res_t res; /* Include the ancient signal function */ - obj_valid = lv_cont_signal(page, sign, param); + res = ancestor_signal(page, sign, param); /* The object can be deleted so check its validity and then * make the object specific signal handling */ - if(obj_valid != false) { + if(res == LV_RES_OK) { lv_page_ext_t * ext = lv_obj_get_ext_attr(page); + lv_style_t * style = lv_obj_get_style(page); lv_obj_t * child; - if(sign == LV_SIGNAL_CHILD_CHG) { /*Move children to the scrollable object*/ + if(sign == LV_SIGNAL_CHILD_CHG) { /*Automatically move children to the scrollable object*/ child = lv_obj_get_child(page, NULL); while(child != NULL) { if(lv_obj_is_protected(child, LV_PROTECT_PARENT) == false) { @@ -153,46 +423,41 @@ bool lv_page_signal(lv_obj_t * page, lv_signal_t sign, void * param) child = lv_obj_get_child(page, child); } } - } else if(sign == LV_SIGNAL_STYLE_CHG) { - lv_style_t * style = lv_obj_get_style(page); - if(lv_cont_get_fit_hor(ext->scrl) == false) { + } + else if(sign == LV_SIGNAL_STYLE_CHG) { + /*If no hor_fit enabled set the scrollable's width to the page's width*/ + if(lv_cont_get_hor_fit(ext->scrl) == false) { lv_obj_set_width(ext->scrl, lv_obj_get_width(page) - 2 * style->body.padding.hor); } else { ext->scrl->signal_func(ext->scrl, LV_SIGNAL_CORD_CHG, &ext->scrl->coords); } - if(ext->sb_mode == LV_PAGE_SB_MODE_ON) { - ext->sbh_draw = 1; - ext->sbv_draw = 1; - } else { - ext->sbh_draw = 0; - ext->sbv_draw = 0; - } + /*The scrollbars are important only if they are visible now*/ + if(ext->sb.hor_draw || ext->sb.ver_draw) lv_page_sb_refresh(page); - lv_page_sb_refresh(page); - } else if(sign == LV_SIGNAL_CORD_CHG) { - lv_style_t * style = lv_obj_get_style(page); + } + else if(sign == LV_SIGNAL_CORD_CHG) { /*Refresh the scrollbar and notify the scrl if the size is changed*/ - if(ext->scrl != NULL && - (lv_obj_get_width(page) != area_get_width(param) || - lv_obj_get_height(page) != area_get_height(param))) { - - if(lv_cont_get_fit_hor(ext->scrl) == false) { + if(ext->scrl != NULL && (lv_obj_get_width(page) != area_get_width(param) || + lv_obj_get_height(page) != area_get_height(param))) + { + /*If no hor_fit enabled set the scrollable's width to the page's width*/ + if(lv_cont_get_hor_fit(ext->scrl) == false) { lv_obj_set_width(ext->scrl, lv_obj_get_width(page) - 2 * style->body.padding.hor); } ext->scrl->signal_func(ext->scrl, LV_SIGNAL_CORD_CHG, &ext->scrl->coords); /*The scrollbars are important only if they are visible now*/ - if(ext->sbh_draw != 0 || ext->sbv_draw != 0) - lv_page_sb_refresh(page); - + if(ext->sb.hor_draw || ext->sb.ver_draw) lv_page_sb_refresh(page); } - } else if(sign == LV_SIGNAL_PRESSED) { + } + else if(sign == LV_SIGNAL_PRESSED) { if(ext->pr_action != NULL) { ext->pr_action(page); } - } else if(sign == LV_SIGNAL_RELEASED) { + } + else if(sign == LV_SIGNAL_RELEASED) { if(lv_indev_is_dragging(lv_indev_get_act()) == false) { if(ext->rel_action != NULL) { ext->rel_action(page); @@ -200,8 +465,8 @@ bool lv_page_signal(lv_obj_t * page, lv_signal_t sign, void * param) } } } - - return obj_valid; + + return res; } /** @@ -209,29 +474,31 @@ bool lv_page_signal(lv_obj_t * page, lv_signal_t sign, void * param) * @param scrl pointer to the scrollable object * @param sign a signal type from lv_signal_t enum * @param param pointer to a signal specific variable + * @return LV_RES_OK: the object is not deleted in the function; LV_RES_INV: the object is deleted */ -bool lv_page_scrl_signal(lv_obj_t * scrl, lv_signal_t sign, void * param) +static lv_res_t lv_page_scrollable_signal(lv_obj_t * scrl, lv_signal_t sign, void * param) { - bool obj_valid = true; + lv_res_t res; /* Include the ancient signal function */ - obj_valid = lv_cont_signal(scrl, sign, param); + res = ancestor_signal(scrl, sign, param); /* The object can be deleted so check its validity and then * make the object specific signal handling */ - if(obj_valid != false) { + if(res != false) { lv_obj_t * page = lv_obj_get_parent(scrl); lv_style_t * page_style = lv_obj_get_style(page); lv_page_ext_t * page_ext = lv_obj_get_ext_attr(page); if(sign == LV_SIGNAL_CORD_CHG) { - /*Be sure the width of the scrollable is correct*/ - if(lv_cont_get_fit_hor(scrl) == false) { + if(lv_cont_get_hor_fit(scrl) == false) { lv_obj_set_width(scrl, lv_obj_get_width(page) - 2 * page_style->body.padding.hor); } + /*Limit the position of the scrollable object to be always visible + * (Do not let its edge inner then its parent respective edge)*/ cord_t new_x; cord_t new_y; bool refr_x = false; @@ -286,44 +553,37 @@ bool lv_page_scrl_signal(lv_obj_t * scrl, lv_signal_t sign, void * param) } lv_page_sb_refresh(page); - } else if(sign == LV_SIGNAL_DRAG_BEGIN) { - if(page_ext->sb_mode == LV_PAGE_SB_MODE_DRAG ) { - cord_t sbh_pad = MATH_MAX(page_ext->sb_width, page_style->body.padding.hor); - cord_t sbv_pad = MATH_MAX(page_ext->sb_width, page_style->body.padding.ver); - if(area_get_height(&page_ext->sbv) < lv_obj_get_height(scrl) - 2 * sbv_pad) { - page_ext->sbv_draw = 1; - } - if(area_get_width(&page_ext->sbh) < lv_obj_get_width(scrl) - 2 * sbh_pad) { - page_ext->sbh_draw = 1; - } - } - } else if(sign == LV_SIGNAL_DRAG_END) { - if(page_ext->sb_mode == LV_PAGE_SB_MODE_DRAG) { + } + else if(sign == LV_SIGNAL_DRAG_END) { + /*Hide scrollbars if required*/ + if(page_ext->sb.mode == LV_PAGE_SB_MODE_DRAG) { area_t sb_area_tmp; - if(page_ext->sbh_draw != 0) { - area_cpy(&sb_area_tmp, &page_ext->sbh); + if(page_ext->sb.hor_draw) { + area_cpy(&sb_area_tmp, &page_ext->sb.hor_area); sb_area_tmp.x1 += page->coords.x1; sb_area_tmp.y1 += page->coords.y1; sb_area_tmp.x2 += page->coords.x2; sb_area_tmp.y2 += page->coords.y2; lv_inv_area(&sb_area_tmp); - page_ext->sbh_draw = 0; + page_ext->sb.hor_draw = 0; } - if(page_ext->sbv_draw != 0) { - area_cpy(&sb_area_tmp, &page_ext->sbv); + if(page_ext->sb.ver_draw) { + area_cpy(&sb_area_tmp, &page_ext->sb.ver_area); sb_area_tmp.x1 += page->coords.x1; sb_area_tmp.y1 += page->coords.y1; sb_area_tmp.x2 += page->coords.x2; sb_area_tmp.y2 += page->coords.y2; lv_inv_area(&sb_area_tmp); - page_ext->sbv_draw = 0; + page_ext->sb.ver_draw = 0; } } - }else if(sign == LV_SIGNAL_PRESSED) { + } + else if(sign == LV_SIGNAL_PRESSED) { if(page_ext->pr_action != NULL) { page_ext->pr_action(page); } - } else if(sign == LV_SIGNAL_RELEASED) { + } + else if(sign == LV_SIGNAL_RELEASED) { if(lv_indev_is_dragging(lv_indev_get_act()) == false) { if(page_ext->rel_action != NULL) { page_ext->rel_action(page); @@ -332,289 +592,9 @@ bool lv_page_scrl_signal(lv_obj_t * scrl, lv_signal_t sign, void * param) } } - return obj_valid; + return res; } -/*===================== - * Setter functions - *====================*/ - -/** - * Set a release action for the page - * @param page pointer to a page object - * @param rel_action a function to call when the page is released - */ -void lv_page_set_rel_action(lv_obj_t * page, lv_action_t rel_action) -{ - lv_page_ext_t * ext = lv_obj_get_ext_attr(page); - ext->rel_action = rel_action; -} - -/** - * Set a press action for the page - * @param page pointer to a page object - * @param pr_action a function to call when the page is pressed - */ -void lv_page_set_pr_action(lv_obj_t * page, lv_action_t pr_action) -{ - lv_page_ext_t * ext = lv_obj_get_ext_attr(page); - ext->pr_action = pr_action; -} - -/** - * Set the scroll bar width on a page - * @param page pointer to a page object - * @param sb_width the new scroll bar width in pixels - */ -void lv_page_set_sb_width(lv_obj_t * page, cord_t sb_width) -{ - lv_page_ext_t * ext = lv_obj_get_ext_attr(page); - ext->sb_width = sb_width; - area_set_height(&ext->sbh, ext->sb_width); - area_set_width(&ext->sbv, ext->sb_width); - lv_page_sb_refresh(page); - lv_obj_invalidate(page); -} - -/** - * Set the scroll bar mode on a page - * @param page pointer to a page object - * @param sb_mode the new mode from 'lv_page_sb_mode_t' enum - */ -void lv_page_set_sb_mode(lv_obj_t * page, lv_page_sb_mode_t sb_mode) -{ - lv_page_ext_t * ext = lv_obj_get_ext_attr(page); - ext->sb_mode = sb_mode; - page->signal_func(page, LV_SIGNAL_STYLE_CHG, NULL); - lv_obj_invalidate(page); -} - -/** - * Set a new style for the scroll bars object on the page - * @param page pointer to a page object - * @param style pointer to a style for the scroll bars - */ -void lv_page_set_style_sb(lv_obj_t * page, lv_style_t * style) -{ - lv_page_ext_t * ext = lv_obj_get_ext_attr(page); - ext->style_sb = style; - lv_obj_invalidate(page); -} - -/** - * Glue the object to the page. After it the page can be moved (dragged) with this object too. - * @param obj pointer to an object on a page - * @param glue true: enable glue, false: disable glue - */ -void lv_page_glue_obj(lv_obj_t * obj, bool glue) -{ - lv_obj_set_drag_parent(obj, glue); - lv_obj_set_drag(obj, glue); -} - -/** - * Focus on an object. It ensures that the object will be visible on the page. - * @param page pointer to a page object - * @param obj pointer to an object to focus (must be on the page) - * @param anim_time scroll animation time in milliseconds (0: no animation) - */ -void lv_page_focus(lv_obj_t * page, lv_obj_t * obj, uint16_t anim_time) -{ - lv_page_ext_t * ext = lv_obj_get_ext_attr(page); - lv_style_t * style = lv_obj_get_style(page); - lv_obj_t * scrl = lv_page_get_scrl(page); - lv_style_t * style_scrl = lv_obj_get_style(scrl); - - cord_t obj_y = obj->coords.y1 - ext->scrl->coords.y1; - cord_t obj_h = lv_obj_get_height(obj); - cord_t scrlable_y = lv_obj_get_y(ext->scrl); - cord_t page_h = lv_obj_get_height(page); - - cord_t top_err = -(scrlable_y + obj_y); - cord_t bot_err = scrlable_y + obj_y + obj_h - page_h; - - /*If obj is higher then the page focus where the "error" is smaller*/ - /*Out of the page on the top*/ - if((obj_h <= page_h && top_err > 0) || - (obj_h > page_h && top_err < bot_err)) { - /*Calculate a new position and to let scrable_rects.vpad space above*/ - scrlable_y = -(obj_y - style_scrl->body.padding.ver - style->body.padding.ver); - scrlable_y += style_scrl->body.padding.ver; - } - /*Out of the page on the bottom*/ - else if((obj_h <= page_h && bot_err > 0) || - (obj_h > page_h && top_err >= bot_err)) { - /*Calculate a new position and to let scrable_rects.vpad space below*/ - scrlable_y = -obj_y; - scrlable_y += page_h - obj_h; - scrlable_y -= style_scrl->body.padding.ver; - } else { - /*Alraedy in focus*/ - return; - } - - if(anim_time == 0) { - lv_obj_set_y(ext->scrl, scrlable_y); - } - else { - anim_t a; - a.act_time = 0; - a.start = lv_obj_get_y(ext->scrl); - a.end = scrlable_y; - a.time = anim_time; - a.end_cb = NULL; - a.playback = 0; - a.repeat = 0; - a.var = ext->scrl; - a.path = anim_get_path(ANIM_PATH_LIN); - a.fp = (anim_fp_t) lv_obj_set_y; - anim_create(&a); - } -} - -/*===================== - * Getter functions - *====================*/ - -/** - * Get the scrollable object of a page- - * @param page pointer to page object - * @return pointer to a container which is the scrollable part of the page - */ -lv_obj_t * lv_page_get_scrl(lv_obj_t * page) -{ - lv_page_ext_t * ext = lv_obj_get_ext_attr(page); - - return ext->scrl; -} -/** - * Get the scroll bar width on a page - * @param page pointer to a page object - * @return the scroll bar width in pixels - */ -cord_t lv_page_get_sb_width(lv_obj_t * page) -{ - lv_page_ext_t * ext = lv_obj_get_ext_attr(page); - return ext->sb_width; -} - -/** - * Set the scroll bar mode on a page - * @param page pointer to a page object - * @return the mode from 'lv_page_sb_mode_t' enum - */ -lv_page_sb_mode_t lv_page_get_sb_mode(lv_obj_t * page) -{ - lv_page_ext_t * ext = lv_obj_get_ext_attr(page); - return ext->sb_mode; -} - -/** - * Set a new style for the scroll bars object on the page - * @param page pointer to a page object - * @return pointer to a style for the scroll bars - */ -lv_style_t * lv_page_get_style_sb(lv_obj_t * page) -{ - lv_page_ext_t * ext = lv_obj_get_ext_attr(page); - if(ext->style_sb == NULL) return lv_obj_get_style(page); - - else return ext->style_sb; -} - -/********************** - * STATIC FUNCTIONS - **********************/ - -/** - * Handle the drawing related tasks of the pages - * @param page pointer to an object - * @param mask 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 true/false, depends on 'mode' - */ -static bool lv_page_design(lv_obj_t * scrl, const area_t * mask, lv_design_mode_t mode) -{ - if(mode == LV_DESIGN_COVER_CHK) { - return ancestor_page_design_f(scrl, mask, mode); - } else if(mode == LV_DESIGN_DRAW_MAIN) { - ancestor_page_design_f(scrl, mask, mode); - } else if(mode == LV_DESIGN_DRAW_POST) { /*Draw the scroll bars finally*/ - ancestor_page_design_f(scrl, mask, mode); - lv_page_ext_t * ext = lv_obj_get_ext_attr(scrl); - - /*Draw the scrollbars*/ - area_t sb_area; - if(ext->sbh_draw != 0) { - /*Convert the relative coordinates to absolute*/ - area_cpy(&sb_area, &ext->sbh); - sb_area.x1 += scrl->coords.x1; - sb_area.y1 += scrl->coords.y1; - sb_area.x2 += scrl->coords.x1; - sb_area.y2 += scrl->coords.y1; - lv_draw_rect(&sb_area, mask, ext->style_sb); - } - - if(ext->sbv_draw != 0) { - /*Convert the relative coordinates to absolute*/ - area_cpy(&sb_area, &ext->sbv); - sb_area.x1 += scrl->coords.x1; - sb_area.y1 += scrl->coords.y1; - sb_area.x2 += scrl->coords.x1; - sb_area.y2 += scrl->coords.y1; - lv_draw_rect(&sb_area, mask, ext->style_sb); - } - } - - return true; -} -/** - * Handle the drawing related tasks of the scrollable object - * @param scrl pointer to an object - * @param mask 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 true/false, depends on 'mode' - */ -static bool lv_scrl_design(lv_obj_t * scrl, const area_t * mask, lv_design_mode_t mode) -{ - if(mode == LV_DESIGN_COVER_CHK) { - return ancestor_page_design_f(scrl, mask, mode); - } else if(mode == LV_DESIGN_DRAW_MAIN) { -#if LV_OBJ_GROUP != 0 - /* If the page is the active in a group and - * the background (page) is not visible (transparent or empty) - * then activate the style of the scrollable*/ - lv_style_t * style_ori = lv_obj_get_style(scrl); - lv_obj_t * page = lv_obj_get_parent(scrl); - lv_style_t * style_page = lv_obj_get_style(page); - lv_group_t * g = lv_obj_get_group(page); - if(style_page->body.empty != 0 || style_page->body.opa == OPA_TRANSP) { /*Background is visible?*/ - if(lv_group_get_focused(g) == page) { - lv_style_t * style_mod; - style_mod = lv_group_mod_style(g, style_ori); - scrl->style_p = style_mod; /*Temporally change the style to the activated */ - } - } -#endif - ancestor_page_design_f(scrl, mask, mode); - -#if LV_OBJ_GROUP != 0 - scrl->style_p = style_ori; /*Revert the style*/ -#endif - } else if(mode == LV_DESIGN_DRAW_POST) { - ancestor_page_design_f(scrl, mask, mode); - } - - return true; -} - - /** * Refresh the position and size of the scroll bars. @@ -622,10 +602,6 @@ static bool lv_scrl_design(lv_obj_t * scrl, const area_t * mask, lv_design_mode_ */ static void lv_page_sb_refresh(lv_obj_t * page) { - /*Always let sb_width padding above,under, left and right to the scrollbars - * else: - * - horizontal and vertical scrollbars can overlap on the corners - * - if the page has radius the scrollbar can be out of the radius */ lv_page_ext_t * ext = lv_obj_get_ext_attr(page); lv_style_t * style = lv_obj_get_style(page); @@ -637,28 +613,33 @@ static void lv_page_sb_refresh(lv_obj_t * page) cord_t vpad = style->body.padding.ver; cord_t obj_w = lv_obj_get_width(page); cord_t obj_h = lv_obj_get_height(page); - cord_t sbh_pad = MATH_MAX(ext->sb_width, style->body.padding.hor); - cord_t sbv_pad = MATH_MAX(ext->sb_width, style->body.padding.ver); - if(ext->sb_mode == LV_PAGE_SB_MODE_OFF) return; + /*Always let 'scrollbar width' padding above, under, left and right to the scrollbars + * else: + * - horizontal and vertical scrollbars can overlap on the corners + * - if the page has radius the scrollbar can be out of the radius */ + cord_t sb_hor_pad = MATH_MAX(ext->sb.style->body.padding.inner, style->body.padding.hor); + cord_t sb_ver_pad = MATH_MAX(ext->sb.style->body.padding.inner, style->body.padding.ver); - if(ext->sb_mode == LV_PAGE_SB_MODE_ON) { - ext->sbh_draw = 1; - ext->sbv_draw = 1; + if(ext->sb.mode == LV_PAGE_SB_MODE_OFF) return; + + if(ext->sb.mode == LV_PAGE_SB_MODE_ON) { + ext->sb.hor_draw = 1; + ext->sb.ver_draw = 1; } /*Invalidate the current (old) scrollbar areas*/ area_t sb_area_tmp; - if(ext->sbh_draw != 0) { - area_cpy(&sb_area_tmp, &ext->sbh); + if(ext->sb.hor_draw != 0) { + area_cpy(&sb_area_tmp, &ext->sb.hor_area); sb_area_tmp.x1 += page->coords.x1; sb_area_tmp.y1 += page->coords.y1; sb_area_tmp.x2 += page->coords.x2; sb_area_tmp.y2 += page->coords.y2; lv_inv_area(&sb_area_tmp); } - if(ext->sbv_draw != 0) { - area_cpy(&sb_area_tmp, &ext->sbv); + if(ext->sb.ver_draw != 0) { + area_cpy(&sb_area_tmp, &ext->sb.ver_area); sb_area_tmp.x1 += page->coords.x1; sb_area_tmp.y1 += page->coords.y1; sb_area_tmp.x2 += page->coords.x2; @@ -666,50 +647,61 @@ static void lv_page_sb_refresh(lv_obj_t * page) lv_inv_area(&sb_area_tmp); } + + if(ext->sb.mode == LV_PAGE_SB_MODE_DRAG && lv_indev_is_dragging(lv_indev_get_act()) == false) { + ext->sb.hor_draw = 0; + ext->sb.ver_draw = 0; + return; + + } + /*Horizontal scrollbar*/ if(scrl_w <= obj_w - 2 * hpad) { /*Full sized scroll bar*/ - area_set_width(&ext->sbh, obj_w - 2 * sbh_pad); - area_set_pos(&ext->sbh, sbh_pad, obj_h - ext->sb_width); - if(ext->sb_mode == LV_PAGE_SB_MODE_AUTO) ext->sbh_draw = 0; + area_set_width(&ext->sb.hor_area, obj_w - 2 * sb_hor_pad); + area_set_pos(&ext->sb.hor_area, sb_hor_pad, obj_h - ext->sb.style->body.padding.inner - ext->sb.style->body.padding.ver); + if(ext->sb.mode == LV_PAGE_SB_MODE_AUTO || ext->sb.mode == LV_PAGE_SB_MODE_DRAG) ext->sb.hor_draw = 0; } else { - size_tmp = (obj_w * (obj_w - (2 * sbh_pad))) / (scrl_w + 2 * hpad); - area_set_width(&ext->sbh, size_tmp); + size_tmp = (obj_w * (obj_w - (2 * sb_hor_pad))) / (scrl_w + 2 * hpad); + if(size_tmp < LV_PAGE_SB_MIN_SIZE) size_tmp = LV_PAGE_SB_MIN_SIZE; + area_set_width(&ext->sb.hor_area, size_tmp); - area_set_pos(&ext->sbh, sbh_pad + - (-(lv_obj_get_x(scrl) - hpad) * (obj_w - size_tmp - 2 * sbh_pad)) / - (scrl_w + 2 * hpad - obj_w ), obj_h - ext->sb_width); + area_set_pos(&ext->sb.hor_area, sb_hor_pad + + (-(lv_obj_get_x(scrl) - hpad) * (obj_w - size_tmp - 2 * sb_hor_pad)) / + (scrl_w + 2 * hpad - obj_w ), + obj_h - ext->sb.style->body.padding.inner - ext->sb.style->body.padding.ver); - if(ext->sb_mode == LV_PAGE_SB_MODE_AUTO) ext->sbh_draw = 1; + if(ext->sb.mode == LV_PAGE_SB_MODE_AUTO || ext->sb.mode == LV_PAGE_SB_MODE_DRAG) ext->sb.hor_draw = 1; } /*Vertical scrollbar*/ if(scrl_h <= obj_h - 2 * vpad) { /*Full sized scroll bar*/ - area_set_height(&ext->sbv, obj_h - 2 * sbv_pad); - area_set_pos(&ext->sbv, obj_w - ext->sb_width, sbv_pad); - if(ext->sb_mode == LV_PAGE_SB_MODE_AUTO) ext->sbv_draw = 0; + area_set_height(&ext->sb.ver_area, obj_h - 2 * sb_ver_pad); + area_set_pos(&ext->sb.ver_area, obj_w - ext->sb.style->body.padding.inner - ext->sb.style->body.padding.hor, sb_ver_pad); + if(ext->sb.mode == LV_PAGE_SB_MODE_AUTO || ext->sb.mode == LV_PAGE_SB_MODE_DRAG) ext->sb.ver_draw = 0; } else { - size_tmp = (obj_h * (obj_h - (2 * sbv_pad))) / (scrl_h + 2 * vpad); - area_set_height(&ext->sbv, size_tmp); + size_tmp = (obj_h * (obj_h - (2 * sb_ver_pad))) / (scrl_h + 2 * vpad); + if(size_tmp < LV_PAGE_SB_MIN_SIZE) size_tmp = LV_PAGE_SB_MIN_SIZE; + area_set_height(&ext->sb.ver_area, size_tmp); - area_set_pos(&ext->sbv, obj_w - ext->sb_width, - sbv_pad + - (-(lv_obj_get_y(scrl) - vpad) * (obj_h - size_tmp - 2 * sbv_pad)) / + area_set_pos(&ext->sb.ver_area, obj_w - ext->sb.style->body.padding.inner - ext->sb.style->body.padding.hor, + sb_ver_pad + + (-(lv_obj_get_y(scrl) - vpad) * (obj_h - size_tmp - 2 * sb_ver_pad)) / (scrl_h + 2 * vpad - obj_h )); - if(ext->sb_mode == LV_PAGE_SB_MODE_AUTO) ext->sbv_draw = 1; + if(ext->sb.mode == LV_PAGE_SB_MODE_AUTO || ext->sb.mode == LV_PAGE_SB_MODE_DRAG) ext->sb.ver_draw = 1; } /*Invalidate the new scrollbar areas*/ - if(ext->sbh_draw != 0) { - area_cpy(&sb_area_tmp, &ext->sbh); + if(ext->sb.hor_draw != 0) { + area_cpy(&sb_area_tmp, &ext->sb.hor_area); sb_area_tmp.x1 += page->coords.x1; sb_area_tmp.y1 += page->coords.y1; sb_area_tmp.x2 += page->coords.x2; sb_area_tmp.y2 += page->coords.y2; lv_inv_area(&sb_area_tmp); } - if(ext->sbv_draw != 0) { - area_cpy(&sb_area_tmp, &ext->sbv); + if(ext->sb.ver_draw != 0) { + area_cpy(&sb_area_tmp, &ext->sb.ver_area); sb_area_tmp.x1 += page->coords.x1; sb_area_tmp.y1 += page->coords.y1; sb_area_tmp.x2 += page->coords.x2; diff --git a/lv_objx/lv_page.h b/lv_objx/lv_page.h index eb39f570e..4cd68e72f 100644 --- a/lv_objx/lv_page.h +++ b/lv_objx/lv_page.h @@ -49,13 +49,14 @@ typedef struct lv_obj_t * scrl; /*The scrollable object on the background*/ lv_action_t rel_action; /*Function to call when the page is released*/ lv_action_t pr_action; /*Function to call when the page is pressed*/ - lv_style_t * style_sb; /*Style of scrollbars*/ - cord_t sb_width; /*Width of the scrollbars*/ - lv_page_sb_mode_t sb_mode; /*Scrollbar visibility from 'lv_page_sb_mode_t'*/ - area_t sbh; /*Horizontal scrollbar area relative to the page. (Handled by the library) */ - area_t sbv; /*Vertical scrollbar area relative to the page (Handled by the library)*/ - uint8_t sbh_draw :1; /*1: horizontal scrollbar is visible now (Handled by the library)*/ - uint8_t sbv_draw :1; /*1: vertical scrollbar is visible now (Handled by the library)*/ + struct { + lv_style_t *style; /*Style of scrollbars*/ + area_t hor_area; /*Horizontal scrollbar area relative to the page. (Handled by the library) */ + area_t ver_area; /*Vertical scrollbar area relative to the page (Handled by the library)*/ + uint8_t hor_draw :1; /*1: horizontal scrollbar is visible now (Handled by the library)*/ + uint8_t ver_draw :1; /*1: vertical scrollbar is visible now (Handled by the library)*/ + uint8_t mode :3; /*Scrollbar visibility from 'lv_page_sb_mode_t'*/ + }sb; }lv_page_ext_t; @@ -71,42 +72,19 @@ typedef struct */ lv_obj_t * lv_page_create(lv_obj_t * par, lv_obj_t * copy); -/** - * Signal function of the page - * @param page pointer to a page object - * @param sign a signal type from lv_signal_t enum - * @param param pointer to a signal specific variable - */ -bool lv_page_signal(lv_obj_t * page, lv_signal_t sign, void * param); - -/** - * Signal function of the scrollable part of a page - * @param scrl pointer to the scrollable object - * @param sign a signal type from lv_signal_t enum - * @param param pointer to a signal specific variable - */ -bool lv_page_scrl_signal(lv_obj_t * scrl, lv_signal_t sign, void * param); - /** * Set a release action for the page * @param page pointer to a page object * @param rel_action a function to call when the page is released */ -void lv_page_set_rel_action(lv_obj_t * page, lv_action_t rel_action); +void lv_page_set_release_action(lv_obj_t * page, lv_action_t rel_action); /** * Set a press action for the page * @param page pointer to a page object * @param pr_action a function to call when the page is pressed */ -void lv_page_set_pr_action(lv_obj_t * page, lv_action_t pr_action); - -/** - * Set the scroll bar width on a page - * @param page pointer to a page object - * @param sb_width the new scroll bar width in pixels - */ -void lv_page_set_sb_width(lv_obj_t * page, cord_t sb_width); +void lv_page_set_press_action(lv_obj_t * page, lv_action_t pr_action); /** * Set the scroll bar mode on a page @@ -116,12 +94,13 @@ void lv_page_set_sb_width(lv_obj_t * page, cord_t sb_width); void lv_page_set_sb_mode(lv_obj_t * page, lv_page_sb_mode_t sb_mode); /** - * Set a new style for the scroll bars object on the page + * Set a new styles for the page * @param page pointer to a page object - * @param style pointer to a style for the scroll bars + * @param bg pointer to a style for the background + * @param scrl pointer to a style for the scrollable area + * @param sb pointer to a style for the scroll bars */ -void lv_page_set_style_sb(lv_obj_t * page, lv_style_t * style); - +void lv_page_set_style(lv_obj_t *page, lv_style_t *bg, lv_style_t *scrl, lv_style_t *sb); /** * Glue the object to the page. After it the page can be moved (dragged) with this object too. * @param obj pointer to an object on a page @@ -144,13 +123,6 @@ void lv_page_focus(lv_obj_t * page, lv_obj_t * obj, uint16_t anim_time); */ lv_obj_t * lv_page_get_scrl(lv_obj_t * page); -/** - * Get the scroll bar width on a page - * @param page pointer to a page object - * @return the scroll bar width in pixels - */ -cord_t lv_page_get_sb_width(lv_obj_t * page); - /** * Set the scroll bar mode on a page * @param page pointer to a page object @@ -159,12 +131,128 @@ cord_t lv_page_get_sb_width(lv_obj_t * page); lv_page_sb_mode_t lv_page_get_sb_mode(lv_obj_t * page); /** - * Set a new style for the scroll bars object on the page - * @param page pointer to a page object - * @return pointer to a style for the scroll bars - */ +* Get the style of the scrollable part of a page +* @param page pointer to a page object +* @return pointer to the style of the scrollale part +*/ +lv_style_t * lv_page_get_style_scrl(lv_obj_t * page); + +/** +* Get the style of the scrolbars of a page +* @param page pointer to a page object +* @return pointer to the style of the scrollbars +*/ lv_style_t * lv_page_get_style_sb(lv_obj_t * page); +/****************************** + * TRANSPARENT API FUNCTIONS + ******************************/ + +/** + * Set the fit attribute of the scrollable part of a page. + * It means it can set its size automatically to involve all children. + * (Can be set separately horizontally and vertically) + * @param page pointer to a page object + * @param hor_en true: enable horizontal fit + * @param ver_en true: enable vertical fit + */ +static inline void lv_page_set_scrl_fit(lv_obj_t *page, bool hor_en, bool ver_en) +{ + lv_cont_set_fit(lv_page_get_scrl(page), hor_en, ver_en); +} + +/** + * Set width of the scrollable part of a page + * @param page pointer to a page object + * @param w the new width of the scrollable (it ha no effect is horizontal fit is enabled) + */ +static inline void lv_page_set_scrl_width(lv_obj_t *page, cord_t w) +{ + lv_obj_set_width(lv_page_get_scrl(page), w); +} + +/** + * Set height of the scrollable part of a page + * @param page pointer to a page object + * @param h the new height of the scrollable (it ha no effect is vertical fit is enabled) + */ +static inline void lv_page_set_scrl_height(lv_obj_t *page, cord_t h) +{ + lv_obj_set_height(lv_page_get_scrl(page), h); + +} + +/** +* Set the layout of the scrollable part of the page +* @param page pointer to a page object +* @param layout a layout from 'lv_cont_layout_t' +*/ +static inline void lv_page_set_scrl_layout(lv_obj_t * page, lv_cont_layout_t layout) +{ + lv_cont_set_layout(lv_page_get_scrl(page), layout); +} + +/** + * Get width of the scrollable part of a page + * @param page pointer to a page object + * @return the width of the scrollable + */ +static inline cord_t lv_page_get_scrl_width(lv_obj_t *page) +{ + return lv_obj_get_width(lv_page_get_scrl(page)); +} + +/** +* Get the style of page's background +* @param page pointer to a page object +* @return pointer to the style of background +*/ +static inline lv_style_t * lv_page_get_style_bg(lv_obj_t * page) +{ + return lv_obj_get_style(page); +} + + +/** + * Get height of the scrollable part of a page + * @param page pointer to a page object + * @return the height of the scrollable + */ +static inline cord_t lv_page_get_scrl_height(lv_obj_t *page) +{ + return lv_obj_get_height(lv_page_get_scrl(page)); +} + +/** +* Get the layout of the scrollable part of a page +* @param page pointer to page object +* @return the layout from 'lv_cont_layout_t' +*/ +static inline lv_cont_layout_t lv_page_get_scrl_layout(lv_obj_t * page) +{ + return lv_cont_get_layout(lv_page_get_scrl(page)); +} + +/** +* Get horizontal fit attribute of the scrollable part of a page +* @param page pointer to a page object +* @return true: horizontal fit is enabled; false: disabled +*/ +static inline bool lv_page_get_scrl_hor_fit(lv_obj_t * page) +{ + return lv_cont_get_hor_fit(lv_page_get_scrl(page)); +} + +/** +* Get vertical fit attribute of the scrollable part of a page +* @param page pointer to a page object +* @return true: vertical fit is enabled; false: disabled +*/ +static inline bool lv_page_get_scrl_fit_ver(lv_obj_t * page) +{ + return lv_cont_get_ver_fit(lv_page_get_scrl(page)); +} + /********************** * MACROS **********************/ diff --git a/lv_objx/lv_roller.c b/lv_objx/lv_roller.c index 737767d33..2c8776386 100644 --- a/lv_objx/lv_roller.c +++ b/lv_objx/lv_roller.c @@ -71,14 +71,14 @@ lv_obj_t * lv_roller_create(lv_obj_t * par, lv_obj_t * copy) if(copy == NULL) { lv_obj_t * scrl = lv_page_get_scrl(new_roller); lv_obj_set_drag(scrl, true); /*In ddlist is might be disabled*/ - lv_page_set_rel_action(new_roller, NULL); /*Handle roller specific actions*/ + lv_page_set_release_action(new_roller, NULL); /*Handle roller specific actions*/ lv_cont_set_fit(lv_page_get_scrl(new_roller), true, false); /*Height is specified directly*/ lv_obj_set_signal_func(scrl, roller_scrl_signal); lv_ddlist_open(new_roller, false); lv_style_t * style_label = lv_obj_get_style(ext->ddlist.options_label); lv_ddlist_set_fix_height(new_roller, (font_get_height(style_label->text.font) >> FONT_ANTIALIAS) * 3 - + style_label->text.space_line * 4); + + style_label->text.line_space * 4); lv_obj_refresh_style(new_roller); /*To set scrollable size automatically*/ } /*Copy an existing roller*/ @@ -191,8 +191,8 @@ static bool lv_roller_design(lv_obj_t * roller, const area_t * mask, lv_design_m lv_roller_ext_t * ext = lv_obj_get_ext_attr(roller); cord_t font_h = font_get_height(font) >> FONT_ANTIALIAS; area_t rect_area; - rect_area.y1 = roller->coords.y1 + lv_obj_get_height(roller) / 2 - font_h / 2 - style->text.space_line - 2; - rect_area.y2 = rect_area.y1 + font_h + style->text.space_line; + rect_area.y1 = roller->coords.y1 + lv_obj_get_height(roller) / 2 - font_h / 2 - style->text.line_space - 2; + rect_area.y2 = rect_area.y1 + font_h + style->text.line_space; rect_area.x1 = ext->ddlist.options_label->coords.x1 - style->body.padding.hor; rect_area.x2 = rect_area.x1 + lv_obj_get_width(lv_page_get_scrl(roller)); @@ -233,7 +233,7 @@ static bool roller_scrl_signal(lv_obj_t * roller_scrl, lv_signal_t sign, void * if(sign == LV_SIGNAL_DRAG_END) { /*If dragged then align the list to there be an element in the middle*/ cord_t label_y1 = ext->ddlist.options_label->coords.y1 - roller->coords.y1; - cord_t label_unit = (font_get_height(style_label->text.font) >> FONT_ANTIALIAS) + style_label->text.space_line / 2; + cord_t label_unit = (font_get_height(style_label->text.font) >> FONT_ANTIALIAS) + style_label->text.line_space / 2; cord_t mid = (roller->coords.y2 - roller->coords.y1) / 2; id = (mid - label_y1) / label_unit; if(id < 0) id = 0; @@ -246,7 +246,7 @@ static bool roller_scrl_signal(lv_obj_t * roller_scrl, lv_signal_t sign, void * point_t p; lv_indev_get_point(indev, &p); p.y = p.y - ext->ddlist.options_label->coords.y1; - id = p.y / (font_h + style_label->text.space_line); + id = p.y / (font_h + style_label->text.line_space); if(id < 0) id = 0; if(id >= ext->ddlist.option_cnt) id = ext->ddlist.option_cnt - 1; ext->ddlist.selected_option_id = id; @@ -256,7 +256,7 @@ static bool roller_scrl_signal(lv_obj_t * roller_scrl, lv_signal_t sign, void * /*Position the scrollable according to the new selected option*/ if(id != -1) { cord_t h = lv_obj_get_height(roller); - cord_t line_y1 = id * (font_h + style_label->text.space_line) + ext->ddlist.options_label->coords.y1 - roller_scrl->coords.y1; + cord_t line_y1 = id * (font_h + style_label->text.line_space) + ext->ddlist.options_label->coords.y1 - roller_scrl->coords.y1; cord_t new_y = - line_y1 + (h - font_h) / 2; if(ext->ddlist.anim_time == 0) { diff --git a/lv_objx/lv_slider.c b/lv_objx/lv_slider.c index 369967e28..33b3a4f1d 100644 --- a/lv_objx/lv_slider.c +++ b/lv_objx/lv_slider.c @@ -117,7 +117,7 @@ bool lv_slider_signal(lv_obj_t * slider, lv_signal_t sign, void * param) int16_t tmp; if(sign == LV_SIGNAL_PRESSED) { - ext->tmp_value = lv_bar_get_value(slider); + ext->tmp_value = lv_slider_get_value(slider); } else if(sign == LV_SIGNAL_PRESSING) { lv_indev_get_point(param, &p); @@ -132,14 +132,14 @@ bool lv_slider_signal(lv_obj_t * slider, lv_signal_t sign, void * param) tmp = ext->bar.max_value - tmp; /*Invert he value: small value means higher y*/ } - lv_bar_set_value(slider, tmp); + lv_slider_set_value(slider, tmp); } else if (sign == LV_SIGNAL_PRESS_LOST) { - lv_bar_set_value(slider, ext->tmp_value); + lv_slider_set_value(slider, ext->tmp_value); } else if (sign == LV_SIGNAL_RELEASED) { - ext->tmp_value = lv_bar_get_value(slider); - lv_bar_set_value(slider, ext->tmp_value); + ext->tmp_value = lv_slider_get_value(slider); + lv_slider_set_value(slider, ext->tmp_value); if(ext->action != NULL) ext->action(slider); } else if(sign == LV_SIGNAL_CORD_CHG) { @@ -166,10 +166,10 @@ bool lv_slider_signal(lv_obj_t * slider, lv_signal_t sign, void * param) lv_slider_ext_t * ext = lv_obj_get_ext_attr(slider); char c = *((char*)param); if(c == LV_GROUP_KEY_RIGHT || c == LV_GROUP_KEY_UP) { - lv_bar_set_value(slider, lv_bar_get_value(slider) + 1); + lv_slider_set_value(slider, lv_slider_get_value(slider) + 1); if(ext->action != NULL) ext->action(slider); } else if(c == LV_GROUP_KEY_LEFT || c == LV_GROUP_KEY_DOWN) { - lv_bar_set_value(slider, lv_bar_get_value(slider) - 1); + lv_slider_set_value(slider, lv_slider_get_value(slider) - 1); if(ext->action != NULL) ext->action(slider); } } @@ -196,7 +196,7 @@ void lv_slider_set_action(lv_obj_t * slider, lv_action_t action) /** * Set the styles of a slider - * @param bar pointer to a bar object + * @param slider pointer to a slider object * @param bg pointer to the background's style (NULL to leave unchanged) * @param indic pointer to the indicator's style (NULL to leave unchanged) * @param knob pointer to the knob's style (NULL to leave unchanged) @@ -210,7 +210,7 @@ void lv_slider_set_style(lv_obj_t * slider, lv_style_t *bg, lv_style_t *indic, l lv_obj_invalidate(slider); } - lv_bar_set_styles(slider, bg, indic); + lv_bar_set_style(slider, bg, indic); } /** @@ -242,7 +242,7 @@ lv_action_t lv_slider_get_action(lv_obj_t * slider) /** * Set the styles of a slider - * @param slider pointer to a bar object + * @param slider pointer to a slider object * @return pointer to the knob's style */ lv_style_t * lv_slider_get_style_knob(lv_obj_t * slider) @@ -334,9 +334,9 @@ static bool lv_slider_design(lv_obj_t * slider, const area_t * mask, lv_design_m cord_t slider_w = area_get_width(&slider->coords); cord_t slider_h = area_get_height(&slider->coords); - cord_t act_value = lv_bar_get_value(slider); - cord_t min_value = lv_bar_get_min_value(slider); - cord_t max_value = lv_bar_get_max_value(slider); + cord_t act_value = lv_slider_get_value(slider); + cord_t min_value = lv_slider_get_min_value(slider); + cord_t max_value = lv_slider_get_max_value(slider); if(slider_w >= slider_h) { area_indic.x2 = (int32_t) ((int32_t)area_get_width(&area_indic) * act_value) / (max_value - min_value); diff --git a/lv_objx/lv_slider.h b/lv_objx/lv_slider.h index c7d9d79c2..3295c5a4f 100644 --- a/lv_objx/lv_slider.h +++ b/lv_objx/lv_slider.h @@ -155,7 +155,7 @@ static inline void lv_slider_set_range(lv_obj_t *slider, int16_t min, int16_t ma */ static inline int16_t lv_slider_get_value(lv_obj_t * slider) { - return lv_slider_get_value(slider); + return lv_bar_get_value(slider); } /** @@ -163,7 +163,7 @@ static inline int16_t lv_slider_get_value(lv_obj_t * slider) * @param slider pointer to a slider object * @return the minimum value of the slider */ -static inline int16_t lv_slider_slider_min_value(lv_obj_t * slider) +static inline int16_t lv_slider_get_min_value(lv_obj_t * slider) { return lv_bar_get_min_value(slider); } diff --git a/lv_objx/lv_sw.c b/lv_objx/lv_sw.c index 908344fcd..c3c8b1323 100644 --- a/lv_objx/lv_sw.c +++ b/lv_objx/lv_sw.c @@ -65,7 +65,7 @@ lv_obj_t * lv_sw_create(lv_obj_t * par, lv_obj_t * copy) /*Init the new switch switch*/ if(copy == NULL) { - lv_bar_set_range(new_sw, 0, 1); + lv_slider_set_range(new_sw, 0, 1); lv_obj_set_size(new_sw, 2 * LV_DPI / 3, LV_DPI / 3); lv_slider_set_knob_in(new_sw, true); } @@ -92,7 +92,7 @@ bool lv_sw_signal(lv_obj_t * sw, lv_signal_t sign, void * param) bool valid; lv_sw_ext_t * ext = lv_obj_get_ext_attr(sw); - int16_t old_val = lv_bar_get_value(sw); + int16_t old_val = lv_slider_get_value(sw); lv_action_t slider_cb = ext->slider.action; ext->slider.action = NULL; /*Do not let the slider to call the callback. The Switch will do it*/ @@ -107,7 +107,7 @@ bool lv_sw_signal(lv_obj_t * sw, lv_signal_t sign, void * param) /*Nothing to cleanup. (No dynamically allocated memory in 'ext')*/ } else if(sign == LV_SIGNAL_PRESSING) { - int16_t act_val = lv_bar_get_value(sw); + int16_t act_val = lv_slider_get_value(sw); if(act_val != old_val) ext->changed = 1; } else if(sign == LV_SIGNAL_PRESS_LOST) { @@ -115,9 +115,9 @@ bool lv_sw_signal(lv_obj_t * sw, lv_signal_t sign, void * param) } else if(sign == LV_SIGNAL_RELEASED) { if(ext->changed == 0) { - int16_t v = lv_bar_get_value(sw); - if(v == 0) lv_bar_set_value(sw, 1); - else lv_bar_set_value(sw, 0); + int16_t v = lv_slider_get_value(sw); + if(v == 0) lv_slider_set_value(sw, 1); + else lv_slider_set_value(sw, 0); } if(slider_cb != NULL) slider_cb(sw); diff --git a/lv_objx/lv_ta.c b/lv_objx/lv_ta.c index 015e69778..93bb3847b 100644 --- a/lv_objx/lv_ta.c +++ b/lv_objx/lv_ta.c @@ -21,9 +21,6 @@ * DEFINES *********************/ /*Test configuration*/ -#ifndef LV_TA_MAX_LENGTH -#define LV_TA_MAX_LENGTH 256 -#endif #ifndef LV_TA_CUR_BLINK_TIME #define LV_TA_CUR_BLINK_TIME 400 /*ms*/ @@ -44,7 +41,7 @@ * STATIC PROTOTYPES **********************/ static bool lv_ta_design(lv_obj_t * ta, const area_t * mask, lv_design_mode_t mode); -static bool lv_ta_scrling_design(lv_obj_t * scrl, const area_t * mask, lv_design_mode_t mode); +static bool lv_ta_scrollable_design(lv_obj_t * scrl, const area_t * mask, lv_design_mode_t mode); static void cursor_blink_anim(lv_obj_t * ta, uint8_t show); static void pwd_char_hider_anim(lv_obj_t * ta, int32_t x); static void pwd_char_hider(lv_obj_t * ta); @@ -53,8 +50,10 @@ static void lv_ta_save_valid_cursor_x(lv_obj_t * ta); /********************** * STATIC VARIABLES **********************/ -lv_design_func_t ancestor_design_f; -lv_design_func_t scrl_design_f; +static lv_design_func_t ancestor_design; +static lv_design_func_t scrl_design; +static lv_signal_func_t ancestor_signal; +static lv_signal_func_t scrl_signal; /********************** * MACROS @@ -79,7 +78,10 @@ lv_obj_t * lv_ta_create(lv_obj_t * par, lv_obj_t * copy) /*Create the ancestor object*/ lv_obj_t * new_ta = lv_page_create(par, copy); dm_assert(new_ta); - + if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_func(new_ta); + if(ancestor_design == NULL) ancestor_design = lv_obj_get_design_func(new_ta); + if(scrl_signal == NULL) scrl_signal = lv_obj_get_signal_func(lv_page_get_scrl(new_ta)); + if(scrl_design == NULL) scrl_design = lv_obj_get_design_func(lv_page_get_scrl(new_ta)); /*Allocate the object type specific extended data*/ lv_ta_ext_t * ext = lv_obj_allocate_ext_attr(new_ta, sizeof(lv_ta_ext_t)); dm_assert(ext); @@ -93,30 +95,28 @@ lv_obj_t * lv_ta_create(lv_obj_t * par, lv_obj_t * copy) ext->cursor_valid_x = 0; ext->label = NULL; - if(ancestor_design_f == NULL) ancestor_design_f = lv_obj_get_design_func(new_ta); - if(scrl_design_f == NULL) scrl_design_f = lv_obj_get_design_func(ext->page.scrl); lv_obj_set_signal_func(new_ta, lv_ta_signal); - lv_obj_set_signal_func(lv_page_get_scrl(new_ta), lv_ta_scrl_signal); + lv_obj_set_signal_func(lv_page_get_scrl(new_ta), lv_ta_scrollable_signal); lv_obj_set_design_func(new_ta, lv_ta_design); /*Init the new text area object*/ if(copy == NULL) { ext->label = lv_label_create(new_ta, NULL); - lv_obj_set_design_func(ext->page.scrl, lv_ta_scrling_design); + lv_obj_set_design_func(ext->page.scrl, lv_ta_scrollable_design); lv_label_set_long_mode(ext->label, LV_LABEL_LONG_BREAK); lv_label_set_text(ext->label, "Text area"); lv_page_glue_obj(ext->label, true); lv_obj_set_click(ext->label, false); lv_obj_set_style(new_ta, &lv_style_pretty); - lv_page_set_sb_mode(new_ta, LV_PAGE_SB_MODE_AUTO); + lv_page_set_sb_mode(new_ta, LV_PAGE_SB_MODE_DRAG); lv_obj_set_style(lv_page_get_scrl(new_ta), &lv_style_transp_fit); lv_obj_set_size(new_ta, LV_TA_DEF_WIDTH, LV_TA_DEF_HEIGHT); } /*Copy an existing object*/ else { - lv_obj_set_design_func(ext->page.scrl, lv_ta_scrling_design); + lv_obj_set_design_func(ext->page.scrl, lv_ta_scrollable_design); lv_ta_ext_t * copy_ext = lv_obj_get_ext_attr(copy); ext->label = lv_label_create(new_ta, copy_ext->label); ext->cursor_show = copy_ext->cursor_show; @@ -159,7 +159,7 @@ bool lv_ta_signal(lv_obj_t * ta, lv_signal_t sign, void * param) bool valid; /* Include the ancient signal function */ - valid = lv_page_signal(ta, sign, param); + valid = ancestor_signal(ta, sign, param); /* The object can be deleted so check its validity and then * make the object specific signal handling */ @@ -222,12 +222,12 @@ bool lv_ta_signal(lv_obj_t * ta, lv_signal_t sign, void * param) * @param param pointer to a signal specific variable * @return true: the object is still valid (not deleted), false: the object become invalid */ -bool lv_ta_scrl_signal(lv_obj_t * scrl, lv_signal_t sign, void * param) +bool lv_ta_scrollable_signal(lv_obj_t * scrl, lv_signal_t sign, void * param) { bool valid; /* Include the ancient signal function */ - valid = lv_page_scrl_signal(scrl, sign, param); + valid = scrl_signal(scrl, sign, param); /* The object can be deleted so check its validity and then * make the object specific signal handling */ @@ -238,7 +238,7 @@ bool lv_ta_scrl_signal(lv_obj_t * scrl, lv_signal_t sign, void * param) lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta); lv_style_t * style_label = lv_obj_get_style(ext->label); - scrl->ext_size = MATH_MAX(scrl->ext_size, style_label->text.space_line + font_get_height(style_label->text.font)); + scrl->ext_size = MATH_MAX(scrl->ext_size, style_label->text.line_space + font_get_height(style_label->text.font)); } } return valid; @@ -316,7 +316,6 @@ void lv_ta_add_char(lv_obj_t * ta, uint32_t c) void lv_ta_add_text(lv_obj_t * ta, const char * txt) { lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta); - const char * label_txt = lv_label_get_text(ext->label); uint16_t txt_len = strlen(txt); if(ext->pwd_mode != 0) pwd_char_hider(ta); /*Make sure all the current text contains only '*'*/ @@ -559,7 +558,7 @@ void lv_ta_cursor_down(lv_obj_t * ta) lv_style_t * label_style = lv_obj_get_style(ext->label); const font_t * font_p = label_style->text.font; cord_t font_h = font_get_height(font_p) >> FONT_ANTIALIAS; - pos.y += font_h + label_style->text.space_line + 1; + pos.y += font_h + label_style->text.line_space + 1; pos.x = ext->cursor_valid_x; /*Do not go below he last line*/ @@ -586,7 +585,7 @@ void lv_ta_cursor_up(lv_obj_t * ta) lv_style_t * label_style = lv_obj_get_style(ext->label); const font_t * font = label_style->text.font; cord_t font_h = font_get_height(font) >> FONT_ANTIALIAS; - pos.y -= font_h + label_style->text.space_line - 1; + pos.y -= font_h + label_style->text.line_space - 1; pos.x = ext->cursor_valid_x; /*Get the letter index on the new cursor position and set it*/ @@ -620,29 +619,31 @@ void lv_ta_set_cursor_type(lv_obj_t * ta, lv_ta_cursor_type_t cur_type) } /** - * Set the style of the cursor (NULL to use label's style) + * Set the style of the text area * @param ta pointer to a text area object - * @param style pointer to the new cursor style + * @param bg pointer to the new background style (NULL to leave unchanged) + * @param sb pointer to the new scrollbar style (NULL to leave unchanged) + * @param cur pointer to the new cursor style (NULL to use the label's style) */ -void lv_ta_set_cursor_style(lv_obj_t * ta, lv_style_t * style) +void lv_ta_set_style(lv_obj_t * ta, lv_style_t *bg, lv_style_t *sb, lv_style_t *cur) { lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta); - ext->cursor_style = style; - lv_obj_invalidate(ta); + ext->cursor_style = cur; + lv_page_set_style(ta, bg, &lv_style_transp_tight, sb); } /** * Enable/Disable password mode - * @param ta ointer to a text area object - * @param en true: enable, false: disable + * @param ta pointer to a text area object + * @param pwd_en true: enable, false: disable */ -void lv_ta_set_pwd_mode(lv_obj_t * ta, bool en) +void lv_ta_set_pwd_mode(lv_obj_t * ta, bool pwd_en) { lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta); /*Pwd mode is now enabled*/ - if(ext->pwd_mode == 0 && en != false) { + if(ext->pwd_mode == 0 && pwd_en != false) { char * txt = lv_label_get_text(ext->label); uint16_t len = strlen(txt); ext->pwd_tmp = dm_alloc(len + 1); @@ -657,13 +658,13 @@ void lv_ta_set_pwd_mode(lv_obj_t * ta, bool en) lv_label_set_text(ext->label, NULL); } /*Pwd mode is now disabled*/ - else if(ext->pwd_mode == 1 && en == false) { + else if(ext->pwd_mode == 1 && pwd_en == false) { lv_label_set_text(ext->label, ext->pwd_tmp); dm_free(ext->pwd_tmp); ext->pwd_tmp = NULL; } - ext->pwd_mode = en == false ? 0 : 1; + ext->pwd_mode = pwd_en == false ? 0 : 1; } /** @@ -708,7 +709,7 @@ void lv_ta_set_one_line(lv_obj_t * ta, bool en) * @param ta pointer to a text area object * @return pointer to the text */ -const char * lv_ta_get_txt(lv_obj_t * ta) +const char * lv_ta_get_text(lv_obj_t * ta) { lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta); @@ -773,7 +774,7 @@ lv_ta_cursor_type_t lv_ta_get_cursor_type(lv_obj_t * ta) * @param ta pointer to a text area object * @return style pointer to the new cursor style */ -lv_style_t * lv_ta_get_cursor_style(lv_obj_t * ta) +lv_style_t * lv_ta_get_style_cursor(lv_obj_t * ta) { lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta); return ext->cursor_style; @@ -808,24 +809,20 @@ static bool lv_ta_design(lv_obj_t * ta, const area_t * masp, lv_design_mode_t mo { if(mode == LV_DESIGN_COVER_CHK) { /*Return false if the object is not covers the mask_p area*/ - return ancestor_design_f(ta, masp, mode); + return ancestor_design(ta, masp, mode); } else if(mode == LV_DESIGN_DRAW_MAIN) { /*Draw the object*/ - ancestor_design_f(ta, masp, mode); + ancestor_design(ta, masp, mode); } else if(mode == LV_DESIGN_DRAW_POST) { - ancestor_design_f(ta, masp, mode); + ancestor_design(ta, masp, mode); } return true; } /** * An extended scrollable design of the page. Calls the normal design function and draws a cursor. -<<<<<<< HEAD * @param scrl pointer to the scrollable part of the Text area -======= - * @param scrl pointer to the scrollabla part of the Text area ->>>>>>> fc3b967f33a3af469bd1edbfdfa42d516dc58d20 * @param mask 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) @@ -833,16 +830,16 @@ static bool lv_ta_design(lv_obj_t * ta, const area_t * masp, lv_design_mode_t mo * LV_DESIGN_DRAW_POST: drawing after every children are drawn * @return return true/false, depends on 'mode' */ -static bool lv_ta_scrling_design(lv_obj_t * scrl, const area_t * mask, lv_design_mode_t mode) +static bool lv_ta_scrollable_design(lv_obj_t * scrl, const area_t * mask, lv_design_mode_t mode) { if(mode == LV_DESIGN_COVER_CHK) { /*Return false if the object is not covers the mask_p area*/ - return scrl_design_f(scrl, mask, mode); + return scrl_design(scrl, mask, mode); } else if(mode == LV_DESIGN_DRAW_MAIN) { /*Draw the object*/ - scrl_design_f(scrl, mask, mode); + scrl_design(scrl, mask, mode); } else if(mode == LV_DESIGN_DRAW_POST) { - scrl_design_f(scrl, mask, mode); + scrl_design(scrl, mask, mode); /*Draw the cursor too*/ lv_obj_t * ta = lv_obj_get_parent(scrl); @@ -899,7 +896,7 @@ static bool lv_ta_scrling_design(lv_obj_t * scrl, const area_t * mask, lv_design /*If the cursor is out of the text (most right) draw it to the next line*/ if(letter_pos.x + ta_ext->label->coords.x1 + letter_w > ta_ext->label->coords.x2 && ta_ext->one_line == 0) { letter_pos.x = 0; - letter_pos.y += letter_h + label_style->text.space_line; + letter_pos.y += letter_h + label_style->text.line_space; if(letter != '\0'){ byte_pos += txt_utf8_size(txt[byte_pos]); diff --git a/lv_objx/lv_ta.h b/lv_objx/lv_ta.h index f7f74e3fe..adf341b7a 100644 --- a/lv_objx/lv_ta.h +++ b/lv_objx/lv_ta.h @@ -90,7 +90,7 @@ bool lv_ta_signal(lv_obj_t * ta, lv_signal_t sign, void * param); * @param param pointer to a signal specific variable * @return true: the object is still valid (not deleted), false: the object become invalid */ -bool lv_ta_scrl_signal(lv_obj_t * scrl, lv_signal_t sign, void * param); +bool lv_ta_scrollable_signal(lv_obj_t * scrl, lv_signal_t sign, void * param); /** * Insert a character to the current cursor position @@ -192,7 +192,7 @@ void lv_ta_set_one_line(lv_obj_t * ta, bool en); * @param ta obj pointer to a text area object * @return pointer to the text */ -const char * lv_ta_get_txt(lv_obj_t * ta); +const char * lv_ta_get_text(lv_obj_t * ta); /** * Get the label of a text area @@ -227,7 +227,7 @@ lv_ta_cursor_type_t lv_ta_get_cursor_type(lv_obj_t * ta); * @param ta pointer to a text area object * @return style pointer to the new cursor style */ -lv_style_t * lv_ta_get_cursor_style(lv_obj_t * ta); +lv_style_t * lv_ta_get_style_cursor(lv_obj_t * ta); /** * Get the password mode @@ -236,6 +236,30 @@ lv_style_t * lv_ta_get_cursor_style(lv_obj_t * ta); */ bool lv_ta_get_pwd_mode(lv_obj_t * ta); +/**************************** + * TRANSPARENT API FUNCTIONS + ***************************/ + +/** +* Get the style of the text area background +* @param ta pointer to a text area object +* @return pointer to the style of the background +*/ +static inline lv_style_t * lv_ta_get_style_bg(lv_obj_t * ta) +{ + return lv_page_get_style_bg(ta); +} + +/** +* Get the style of the scrollbars of a text area +* @param ta pointer to a text area object +* @return pointer to the style of the scrollbars +*/ +static inline lv_style_t * lv_ta_get_style_scrollbar(lv_obj_t * ta) +{ + return lv_page_get_style_sb(ta); +} + /********************** * MACROS **********************/ diff --git a/lv_objx/lv_tabview.c b/lv_objx/lv_tabview.c index 58edf2679..a59221d78 100644 --- a/lv_objx/lv_tabview.c +++ b/lv_objx/lv_tabview.c @@ -24,10 +24,6 @@ /********************** * STATIC PROTOTYPES **********************/ -#if 0 /*Unused*/ -static bool lv_tab_design(lv_obj_t * tab, const area_t * mask, lv_design_mode_t mode); -#endif - static bool tabpage_signal(lv_obj_t * tab_page, lv_signal_t sign, void * param); static bool tabscrl_signal(lv_obj_t * tab_scrl, lv_signal_t sign, void * param); @@ -39,6 +35,8 @@ static lv_res_t tab_btnm_action(lv_obj_t * tab_btnm, const char * tab_name); /********************** * STATIC VARIABLES **********************/ +static lv_signal_func_t ancestor_signal; +static lv_signal_func_t page_signal; static lv_signal_func_t page_scrl_signal; static const char * tab_def[] = {""}; /********************** @@ -64,6 +62,7 @@ lv_obj_t * lv_tabview_create(lv_obj_t * par, lv_obj_t * copy) /*Create the ancestor of tab*/ lv_obj_t * new_tabview = lv_obj_create(par, copy); dm_assert(new_tabview); + if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_func(new_tabview); /*Allocate the tab type specific extended data*/ lv_tabview_ext_t * ext = lv_obj_allocate_ext_attr(new_tabview, sizeof(lv_tabview_ext_t)); @@ -99,7 +98,6 @@ lv_obj_t * lv_tabview_create(lv_obj_t * par, lv_obj_t * copy) lv_btnm_set_toggle(ext->tabs, true, 0); ext->indic = lv_obj_create(ext->tabs, NULL); - lv_style_t * style_indic = lv_obj_get_style(ext->indic); lv_obj_set_size(ext->indic, LV_DPI, LV_DPI / 10); lv_obj_align(ext->indic, ext->tabs, LV_ALIGN_IN_BOTTOM_LEFT, 0, 0); lv_obj_set_click(ext->indic, false); @@ -151,7 +149,7 @@ bool lv_tabview_signal(lv_obj_t * tabview, lv_signal_t sign, void * param) bool valid; /* Include the ancient signal function */ - valid = lv_obj_signal(tabview, sign, param); + valid = ancestor_signal(tabview, sign, param); /* The object can be deleted so check its validity and then * make the object specific signal handling */ @@ -192,9 +190,11 @@ lv_obj_t * lv_tabview_add_tab(lv_obj_t * tabview, const char * name) lv_obj_set_size(h, lv_obj_get_width(tabview), lv_obj_get_height(tabview) - lv_obj_get_height(ext->tabs)); lv_obj_set_style(h, &lv_style_transp_fit); lv_obj_set_style(lv_page_get_scrl(h), &lv_style_transp_fit); - lv_obj_set_signal_func(h, tabpage_signal); lv_page_set_sb_mode(h, LV_PAGE_SB_MODE_AUTO); + + if(page_signal == NULL) page_signal = lv_obj_get_signal_func(h); if(page_scrl_signal == NULL) page_scrl_signal = lv_obj_get_signal_func(lv_page_get_scrl(h)); + lv_obj_set_signal_func(h, tabpage_signal); lv_obj_set_signal_func(lv_page_get_scrl(h), tabscrl_signal); /*Extend the button matrix map with the new name*/ @@ -483,7 +483,7 @@ static bool tabpage_signal(lv_obj_t * tab_page, lv_signal_t sign, void * param) bool valid; /* Include the ancient signal function */ - valid = lv_page_signal(tab_page, sign, param); + valid = page_signal(tab_page, sign, param); /* The object can be deleted so check its validity and then * make the object specific signal handling */