/** * Draw the scale on a gauge * @param gauge pointer to gauge object * @param mask mask of drawing */ static void lv_gauge_draw_scale(lv_obj_t * gauge, const lv_area_t * mask) { char scale_txt[16]; lv_gauge_ext_t * ext = lv_obj_get_ext_attr(gauge); lv_style_t * style = lv_obj_get_style(gauge); lv_coord_t r = lv_obj_get_width(gauge) / 2 - (3 * style->body.padding.hor) - style->body.padding.inner; lv_coord_t x_ofs = lv_obj_get_width(gauge) / 2 + gauge->coords.x1; lv_coord_t y_ofs = lv_obj_get_height(gauge) / 2 + gauge->coords.y1; int16_t scale_angle = lv_lmeter_get_scale_angle(gauge); uint16_t label_num = ext->label_count; int16_t angle_ofs = 90 + (360 - scale_angle) / 2; int16_t min = lv_gauge_get_min_value(gauge); int16_t max = lv_gauge_get_max_value(gauge); uint8_t i; for(i = 0; i < label_num; i++) { /*Calculate the position a scale label*/ int16_t angle = (i * scale_angle) / (label_num - 1) + angle_ofs; lv_coord_t y = (int32_t)((int32_t)lv_trigo_sin(angle) * r) / LV_TRIGO_SIN_MAX; y += y_ofs; lv_coord_t x = (int32_t)((int32_t)lv_trigo_sin(angle + 90) * r) / LV_TRIGO_SIN_MAX; x += x_ofs; int16_t scale_act = (int32_t)((int32_t)(max - min) * i) / (label_num - 1); scale_act += min; lv_math_num_to_str(scale_act, scale_txt); lv_area_t label_cord; lv_point_t label_size; lv_txt_get_size(&label_size, scale_txt, style->text.font, style->text.letter_space, style->text.line_space, LV_COORD_MAX, LV_TXT_FLAG_NONE); /*Draw the label*/ label_cord.x1 = x - label_size.x / 2; label_cord.y1 = y - label_size.y / 2; label_cord.x2 = label_cord.x1 + label_size.x; label_cord.y2 = label_cord.y1 + label_size.y; lv_draw_label(&label_cord, mask, style, scale_txt, LV_TXT_FLAG_NONE, NULL); } }
/** * 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); }