/** * Refresh the position of the roller. It uses the id stored in: ext->ddlist.selected_option_id * @param roller pointer to a roller object * @param anim_en true: refresh with animation; false: without animation */ static void refr_position(lv_obj_t *roller, bool anim_en) { lv_obj_t *roller_scrl = lv_page_get_scrl(roller); lv_roller_ext_t * ext = lv_obj_get_ext_attr(roller); lv_style_t * style_label = lv_obj_get_style(ext->ddlist.label); const lv_font_t * font = style_label->text.font; lv_coord_t font_h = lv_font_get_height_scale(font); lv_coord_t h = lv_obj_get_height(roller); int32_t id = ext->ddlist.sel_opt_id; lv_coord_t line_y1 = id * (font_h + style_label->text.line_space) + ext->ddlist.label->coords.y1 - roller_scrl->coords.y1; lv_coord_t new_y = - line_y1 + (h - font_h) / 2; if(ext->ddlist.anim_time == 0 || anim_en == false) { lv_obj_set_y(roller_scrl, new_y); } else { #if USE_LV_ANIMATION lv_anim_t a; a.var = roller_scrl; a.start = lv_obj_get_y(roller_scrl); a.end = new_y; a.fp = (lv_anim_fp_t)lv_obj_set_y; a.path = lv_anim_path_linear; a.end_cb = NULL; a.act_time = 0; a.time = ext->ddlist.anim_time; a.playback = 0; a.playback_pause = 0; a.repeat = 0; a.repeat_pause = 0; lv_anim_create(&a); #endif } }
/** * 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(page, LV_PAGE_STYLE_BG); lv_style_t * style_scrl = lv_page_get_style(page, LV_PAGE_STYLE_SCRL); lv_coord_t obj_y = obj->coords.y1 - ext->scrl->coords.y1; lv_coord_t obj_h = lv_obj_get_height(obj); lv_coord_t scrlable_y = lv_obj_get_y(ext->scrl); lv_coord_t page_h = lv_obj_get_height(page); lv_coord_t top_err = -(scrlable_y + obj_y); lv_coord_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 { #if USE_LV_ANIMATION lv_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 = lv_anim_path_linear; a.fp = (lv_anim_fp_t) lv_obj_set_y; lv_anim_create(&a); #endif } }
static void lv_sw_anim_to_value(lv_obj_t * sw, int16_t value) { #if USE_LV_ANIMATION lv_anim_t a; lv_sw_ext_t * ext = lv_obj_get_ext_attr(sw); a.var = sw; a.start = ext->slider.bar.cur_value; a.end = value; a.fp = (lv_anim_fp_t)lv_slider_set_value; a.path = lv_anim_path_linear; a.end_cb = NULL; a.act_time = 0; a.time = lv_sw_get_anim_time(sw); a.playback = 0; a.playback_pause = 0; a.repeat = 0; a.repeat_pause = 0; lv_anim_create(&a); #endif }
/** * Refresh the size of drop down list according to its status (open or closed) * @param ddlist pointer to a drop down list object * @param anim_en Change the size (open/close) with or without animation (true/false) */ static void lv_ddlist_refr_size(lv_obj_t * ddlist, bool anim_en) { #if USE_LV_ANIMATION == 0 anim_en = false; #endif lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist); lv_style_t * style = lv_obj_get_style(ddlist); lv_coord_t new_height; if(ext->opened) { /*Open the list*/ if(ext->fix_height == 0) new_height = lv_obj_get_height(lv_page_get_scrl(ddlist)) + 2 * style->body.padding.ver; else new_height = ext->fix_height; } else { /*Close the list*/ const lv_font_t * font = style->text.font; lv_style_t * label_style = lv_obj_get_style(ext->label); lv_coord_t font_h = lv_font_get_height(font); new_height = font_h + 2 * label_style->text.line_space; } if(anim_en == 0) { lv_obj_set_height(ddlist, new_height); lv_ddlist_pos_current_option(ddlist); } else { #if USE_LV_ANIMATION lv_anim_t a; a.var = ddlist; a.start = lv_obj_get_height(ddlist); a.end = new_height; a.fp = (lv_anim_fp_t)lv_obj_set_height; a.path = lv_anim_path_linear; a.end_cb = (lv_anim_cb_t)lv_ddlist_pos_current_option; a.act_time = 0; a.time = ext->anim_time; a.playback = 0; a.playback_pause = 0; a.repeat = 0; a.repeat_pause = 0; lv_anim_create(&a); #endif } }
/** * Refresh the label with its text stored in its extended data * @param label pointer to a label object */ static void lv_label_refr_text(lv_obj_t * label) { lv_label_ext_t * ext = lv_obj_get_ext_attr(label); if(ext->text == NULL) return; lv_coord_t max_w = lv_obj_get_width(label); lv_style_t * style = lv_obj_get_style(label); const lv_font_t * font = style->text.font; /*If the width will be expanded set the max length to very big */ if(ext->long_mode == LV_LABEL_LONG_EXPAND || ext->long_mode == LV_LABEL_LONG_SCROLL) { max_w = LV_COORD_MAX; } /*Calc. the height and longest line*/ lv_point_t size; lv_txt_flag_t flag = LV_TXT_FLAG_NONE; if(ext->recolor != 0) flag |= LV_TXT_FLAG_RECOLOR; if(ext->expand != 0) flag |= LV_TXT_FLAG_EXPAND; if(ext->no_break != 0) flag |= LV_TXT_FLAG_NO_BREAK; lv_txt_get_size(&size, ext->text, font, style->text.letter_space, style->text.line_space, max_w, flag); /*Set the full size in expand mode*/ if(ext->long_mode == LV_LABEL_LONG_EXPAND || ext->long_mode == LV_LABEL_LONG_SCROLL) { lv_obj_set_size(label, size.x, size.y); /*Start scrolling if the label is greater then its parent*/ if(ext->long_mode == LV_LABEL_LONG_SCROLL) { #if USE_LV_ANIMATION lv_obj_t * parent = lv_obj_get_parent(label); /*Delete the potential previous scroller animations*/ lv_anim_del(label, (lv_anim_fp_t) lv_obj_set_x); lv_anim_del(label, (lv_anim_fp_t) lv_obj_set_y); lv_anim_t anim; anim.var = label; anim.repeat = 1; anim.playback = 1; anim.start = lv_font_get_width(font, ' '); anim.act_time = 0; anim.end_cb = NULL; anim.path = lv_anim_path_linear; anim.playback_pause = (((lv_font_get_width(style->text.font, ' ') + style->text.letter_space) * 1000) / ext->anim_speed) * ANIM_WAIT_CHAR_COUNT; anim.repeat_pause = anim.playback_pause; if(lv_obj_get_width(label) > lv_obj_get_width(parent)) { anim.end = lv_obj_get_width(parent) - lv_obj_get_width(label) - lv_font_get_width(font, ' '); anim.fp = (lv_anim_fp_t) lv_obj_set_x; anim.time = lv_anim_speed_to_time(ext->anim_speed, anim.start, anim.end); lv_anim_create(&anim); } else if(lv_obj_get_height(label) > lv_obj_get_height(parent)) { anim.end = lv_obj_get_height(parent) - lv_obj_get_height(label) - lv_font_get_height(font); anim.fp = (lv_anim_fp_t)lv_obj_set_y; anim.time = lv_anim_speed_to_time(ext->anim_speed, anim.start, anim.end); lv_anim_create(&anim); } #endif } } /*In roll mode keep the size but start offset animations*/ else if(ext->long_mode == LV_LABEL_LONG_ROLL) { #if USE_LV_ANIMATION lv_anim_t anim; anim.var = label; anim.repeat = 1; anim.playback = 1; anim.start = lv_font_get_width(font, ' '); anim.act_time = 0; anim.end_cb = NULL; anim.path = lv_anim_path_linear; anim.playback_pause = (((lv_font_get_width(style->text.font, ' ') + style->text.letter_space) * 1000) / ext->anim_speed) * ANIM_WAIT_CHAR_COUNT;; anim.repeat_pause = anim.playback_pause; bool hor_anim = false; if(size.x > lv_obj_get_width(label)) { anim.end = lv_obj_get_width(label) - size.x - lv_font_get_width(font, ' '); anim.fp = (lv_anim_fp_t) lv_label_set_offset_x; anim.time = lv_anim_speed_to_time(ext->anim_speed, anim.start, anim.end); lv_anim_create(&anim); hor_anim = true; } else { /*Delete the offset animation if not required*/ lv_anim_del(label, (lv_anim_fp_t) lv_label_set_offset_x); ext->offset.x = 0; } if(size.y > lv_obj_get_height(label) && hor_anim == false) { anim.end = lv_obj_get_height(label) - size.y - (lv_font_get_height(font)); anim.fp = (lv_anim_fp_t)lv_label_set_offset_y; anim.time = lv_anim_speed_to_time(ext->anim_speed, anim.start, anim.end); lv_anim_create(&anim); } else { /*Delete the offset animation if not required*/ lv_anim_del(label, (lv_anim_fp_t) lv_label_set_offset_y); ext->offset.y = 0; } #endif } else if(ext->long_mode == LV_LABEL_LONG_DOT) { if(size.y <= lv_obj_get_height(label)) { /*No dots are required, the text is short enough*/ ext->dot_end = LV_LABEL_DOT_END_INV; } else if(lv_txt_get_length(ext->text) <= LV_LABEL_DOT_NUM) { /*Don't turn to dots all the characters*/ ext->dot_end = LV_LABEL_DOT_END_INV; } else { lv_point_t p; p.x = lv_obj_get_width(label) - (lv_font_get_width(style->text.font, '.') + style->text.letter_space) * LV_LABEL_DOT_NUM; /*Shrink with dots*/ p.y = lv_obj_get_height(label); p.y -= p.y % (lv_font_get_height(style->text.font) + style->text.line_space); /*Round down to the last line*/ p.y -= style->text.line_space; /*Trim the last line space*/ uint32_t letter_id = lv_label_get_letter_on(label, &p); #if LV_TXT_UTF8 == 0 /*Save letters under the dots and replace them with dots*/ uint8_t i; for(i = 0; i < LV_LABEL_DOT_NUM; i++) { ext->dot_tmp[i] = ext->text[letter_id + i]; ext->text[letter_id + i] = '.'; } ext->dot_tmp[LV_LABEL_DOT_NUM] = ext->text[letter_id + LV_LABEL_DOT_NUM]; ext->text[letter_id + LV_LABEL_DOT_NUM] = '\0'; ext->dot_end = letter_id + LV_LABEL_DOT_NUM; #else /*Save letters under the dots and replace them with dots*/ uint32_t i; uint32_t byte_id = txt_utf8_get_byte_id(ext->text, letter_id); uint32_t byte_id_ori = byte_id; uint8_t len = 0; for(i = 0; i <= LV_LABEL_DOT_NUM; i++) { len += lv_txt_utf8_size(ext->text[byte_id]); lv_txt_utf8_next(ext->text, &byte_id); } memcpy(ext->dot_tmp, &ext->text[byte_id_ori], len); ext->dot_tmp[len] = '\0'; /*Close with a zero*/ for(i = 0; i < LV_LABEL_DOT_NUM; i++) { ext->text[byte_id_ori + i] = '.'; } ext->text[byte_id_ori + LV_LABEL_DOT_NUM] = '\0'; ext->dot_end = letter_id + LV_LABEL_DOT_NUM; #endif } } /*In break mode only the height can change*/ else if (ext->long_mode == LV_LABEL_LONG_BREAK) { lv_obj_set_height(label, size.y); } lv_obj_invalidate(label); }