/** * Create a label objects * @param par pointer to an object, it will be the parent of the new label * @param copy pointer to a button object, if not NULL then the new object will be copied from it * @return pointer to the created button */ lv_obj_t * lv_label_create(lv_obj_t * par, lv_obj_t * copy) { /*Create a basic object*/ lv_obj_t * new_label = lv_obj_create(par, copy); lv_mem_assert(new_label); if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_func(new_label); /*Extend the basic object to a label object*/ lv_obj_allocate_ext_attr(new_label, sizeof(lv_label_ext_t)); lv_label_ext_t * ext = lv_obj_get_ext_attr(new_label); lv_mem_assert(ext); ext->text = NULL; ext->static_txt = 0; ext->recolor = 0; ext->no_break = 0; ext->body_draw = 0; ext->align = LV_LABEL_ALIGN_LEFT; ext->dot_end = LV_LABEL_DOT_END_INV; ext->long_mode = LV_LABEL_LONG_EXPAND; ext->anim_speed = LV_LABEL_SCROLL_SPEED; ext->offset.x = 0; ext->offset.y = 0; lv_obj_set_design_func(new_label, lv_label_design); lv_obj_set_signal_func(new_label, lv_label_signal); /*Init the new label*/ if(copy == NULL) { lv_obj_set_click(new_label, false); lv_label_set_long_mode(new_label, LV_LABEL_LONG_EXPAND); lv_label_set_text(new_label, "Text"); lv_label_set_style(new_label, NULL); /*Inherit parent's style*/ } /*Copy 'copy' if not NULL*/ else { lv_label_ext_t * copy_ext = lv_obj_get_ext_attr(copy); lv_label_set_long_mode(new_label, lv_label_get_long_mode(copy)); lv_label_set_recolor(new_label, lv_label_get_recolor(copy)); lv_label_set_body_draw(new_label, lv_label_get_body_draw(copy)); lv_label_set_align(new_label, lv_label_get_align(copy)); if(copy_ext->static_txt == 0) lv_label_set_text(new_label, lv_label_get_text(copy)); else lv_label_set_static_text(new_label, lv_label_get_text(copy)); /*In DOT mode save the text byte-to-byte because a '\0' can be in the middle*/ if(copy_ext->long_mode == LV_LABEL_LONG_DOT) { ext->text = lv_mem_realloc(ext->text, lv_mem_get_size(copy_ext->text)); memcpy(ext->text, copy_ext->text, lv_mem_get_size(copy_ext->text)); } memcpy(ext->dot_tmp, copy_ext->dot_tmp, sizeof(ext->dot_tmp)); ext->dot_end = copy_ext->dot_end; /*Refresh the style with new signal function*/ lv_obj_refresh_style(new_label); } return new_label; }
/** * Handle the drawing related tasks of the rollers * @param roller 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_roller_design(lv_obj_t * roller, const lv_area_t * mask, lv_design_mode_t mode) { /*Return false if the object is not covers the mask_p area*/ if(mode == LV_DESIGN_COVER_CHK) { return false; } /*Draw the object*/ else if(mode == LV_DESIGN_DRAW_MAIN) { draw_bg(roller, mask); lv_style_t *style = lv_roller_get_style(roller, LV_ROLLER_STYLE_BG); const lv_font_t * font = style->text.font; lv_roller_ext_t * ext = lv_obj_get_ext_attr(roller); lv_coord_t font_h = lv_font_get_height_scale(font); lv_area_t rect_area; 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 = roller->coords.x1; rect_area.x2 = roller->coords.x2; lv_draw_rect(&rect_area, mask, ext->ddlist.sel_style); } /*Post draw when the children are drawn*/ else if(mode == LV_DESIGN_DRAW_POST) { lv_style_t *style = lv_roller_get_style(roller, LV_ROLLER_STYLE_BG); lv_roller_ext_t * ext = lv_obj_get_ext_attr(roller); const lv_font_t * font = style->text.font; lv_coord_t font_h = lv_font_get_height_scale(font); /*Redraw the text on the selected area with a different color*/ lv_area_t rect_area; 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 = roller->coords.x1; rect_area.x2 = roller->coords.x2; lv_area_t mask_sel; bool area_ok; area_ok = lv_area_union(&mask_sel, mask, &rect_area); if(area_ok) { lv_style_t *sel_style = lv_roller_get_style(roller, LV_ROLLER_STYLE_SEL); lv_style_t new_style; lv_style_copy(&new_style, style); new_style.text.color = sel_style->text.color; new_style.text.opa = sel_style->text.opa; lv_draw_label(&ext->ddlist.label->coords, &mask_sel, &new_style, lv_label_get_text(ext->ddlist.label), LV_TXT_FLAG_CENTER, NULL); } } return true; }
/** * Set the behavior of the label with longer text then the object size * @param label pointer to a label object * @param long_mode the new mode from 'lv_label_long_mode' enum. */ void lv_label_set_long_mode(lv_obj_t * label, lv_label_long_mode_t long_mode) { lv_label_ext_t * ext = lv_obj_get_ext_attr(label); #if USE_LV_ANIMATION /*Delete the old animation (if exists)*/ 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_del(label, (lv_anim_fp_t) lv_label_set_offset_x); lv_anim_del(label, (lv_anim_fp_t) lv_label_set_offset_y); #endif ext->offset.x = 0; ext->offset.y = 0; if(long_mode == LV_LABEL_LONG_ROLL) ext->expand = 1; else ext->expand = 0; /*Restore the character under the dots*/ if(ext->long_mode == LV_LABEL_LONG_DOT && ext->dot_end != LV_LABEL_DOT_END_INV) { lv_label_revert_dots(label); } ext->long_mode = long_mode; lv_label_refr_text(label); }
/** * Set a new text for a label. Memory will be allocated to store the text by the label. * @param label pointer to a label object * @param text '\0' terminated character string. NULL to refresh with the current text. */ void lv_label_set_text(lv_obj_t * label, const char * text) { lv_obj_invalidate(label); lv_label_ext_t * ext = lv_obj_get_ext_attr(label); /*If text is NULL then refresh */ if(text == NULL) { lv_label_refr_text(label); return; } if(ext->text == text) { /*If set its own text then reallocate it (maybe its size changed)*/ ext->text = lv_mem_realloc(ext->text, strlen(ext->text) + 1); } else { /*Allocate space for the new text*/ uint32_t len = strlen(text) + 1; if(ext->text != NULL && ext->static_txt == 0) { lv_mem_free(ext->text); ext->text = NULL; } ext->text = lv_mem_alloc(len); strcpy(ext->text, text); ext->static_txt = 0; /*Now the text is dynamically allocated*/ } lv_label_refr_text(label); }
/** * Handle the drawing related tasks of the sliders * @param slider 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_slider_design(lv_obj_t * slider, const lv_area_t * mask, lv_design_mode_t mode) { /*Return false if the object is not covers the mask_p area*/ if(mode == LV_DESIGN_COVER_CHK) { return false; } /*Draw the object*/ else if(mode == LV_DESIGN_DRAW_MAIN) { lv_slider_ext_t * ext = lv_obj_get_ext_attr(slider); lv_style_t * style_bg = lv_slider_get_style(slider, LV_SLIDER_STYLE_BG); lv_style_t * style_knob = lv_slider_get_style(slider, LV_SLIDER_STYLE_KNOB); lv_style_t * style_indic = lv_slider_get_style(slider, LV_SLIDER_STYLE_INDIC); lv_coord_t slider_w = lv_area_get_width(&slider->coords); lv_coord_t slider_h = lv_area_get_height(&slider->coords); /*Draw the bar*/ lv_area_t area_bg; lv_area_copy(&area_bg, &slider->coords); /*Be sure at least LV_SLIDER_SIZE_MIN size will remain*/ lv_coord_t pad_ver_bg = style_bg->body.padding.ver; lv_coord_t pad_hor_bg = style_bg->body.padding.hor; if(pad_ver_bg * 2 + LV_SLIDER_SIZE_MIN > lv_area_get_height(&area_bg)) { pad_ver_bg = (lv_area_get_height(&area_bg) - LV_SLIDER_SIZE_MIN) >> 1; }
/** * Get the value of a slider * @param slider pointer to a slider object * @return the value of the slider */ int16_t lv_slider_get_value(lv_obj_t * slider) { lv_slider_ext_t * ext = lv_obj_get_ext_attr(slider); if(ext->drag_value != LV_SLIDER_NOT_PRESSED) return ext->drag_value; else return lv_bar_get_value(slider); }
/** * 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; }
/** * Turn ON the switch * @param sw pointer to a switch object */ void lv_sw_on(lv_obj_t * sw) { lv_sw_ext_t * ext = lv_obj_get_ext_attr(sw); lv_slider_set_value(sw, LV_SWITCH_SLIDER_ANIM_MAX); lv_slider_set_style(sw, LV_SLIDER_STYLE_KNOB, ext->style_knob_on); }
/** * 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 } }
void lv_sw_set_anim_time(lv_obj_t *sw, uint16_t anim_time) { #if USE_LV_ANIMATION lv_sw_ext_t * ext = lv_obj_get_ext_attr(sw); ext->anim_time = anim_time; #endif }
/** * Insert a text to the label. The label text can not be static. * @param label pointer to a label object * @param pos character index to insert. Expressed in character index and not byte index (Different in UTF-8) * 0: before first char. * LV_LABEL_POS_LAST: after last char. * @param txt pointer to the text to insert */ void lv_label_ins_text(lv_obj_t * label, uint32_t pos, const char * txt) { lv_label_ext_t * ext = lv_obj_get_ext_attr(label); /*Can not append to static text*/ if(ext->static_txt != 0) return; lv_obj_invalidate(label); /*Allocate space for the new text*/ uint32_t old_len = strlen(ext->text); uint32_t ins_len = strlen(txt); uint32_t new_len = ins_len + old_len; ext->text = lv_mem_realloc(ext->text, new_len + 1); if(pos == LV_LABEL_POS_LAST) { #if LV_TXT_UTF8 == 0 pos = old_len; #else pos = lv_txt_get_length(ext->text); #endif } lv_txt_ins(ext->text, pos, txt); lv_label_refr_text(label); }
/** * Set the label to ignore (or accept) line breaks on '\n' * @param label pointer to a label object * @param no_break_en true: ignore line breaks, false: make line breaks on '\n' */ void lv_label_set_no_break(lv_obj_t * label, bool no_break_en) { lv_label_ext_t * ext = lv_obj_get_ext_attr(label); ext->no_break = no_break_en == false ? 0 : 1; lv_label_refr_text(label); }
/** * Set the height to show the given number of rows (options) * @param roller pointer to a roller object * @param row_cnt number of desired visible rows */ void lv_roller_set_visible_row_count(lv_obj_t *roller, uint8_t row_cnt) { lv_roller_ext_t *ext = lv_obj_get_ext_attr(roller); lv_style_t * style_label = lv_obj_get_style(ext->ddlist.label); lv_ddlist_set_fix_height(roller, lv_font_get_height_scale(style_label->text.font) * row_cnt + style_label->text.line_space * (row_cnt)); }
/** * Turn OFF the switch * @param sw pointer to a switch object */ void lv_sw_off(lv_obj_t * sw) { lv_sw_ext_t * ext = lv_obj_get_ext_attr(sw); lv_slider_set_value(sw, 0); lv_slider_set_style(sw, LV_SLIDER_STYLE_KNOB, ext->style_knob_off); }
/** * Get a style of a switch * @param sw pointer to a switch object * @param type which style should be get * @return style pointer to a style */ lv_style_t * lv_sw_get_style(const lv_obj_t * sw, lv_sw_style_t type) { lv_style_t * style = NULL; lv_sw_ext_t * ext = lv_obj_get_ext_attr(sw); switch(type) { case LV_SW_STYLE_BG: style = lv_slider_get_style(sw, LV_SLIDER_STYLE_BG); break; case LV_SW_STYLE_INDIC: style = lv_slider_get_style(sw, LV_SLIDER_STYLE_INDIC); break; case LV_SW_STYLE_KNOB_OFF: style = ext->style_knob_off; break; case LV_SW_STYLE_KNOB_ON: style = ext->style_knob_on; break; default: style = NULL; break; } return style; }
/** * Enable the recoloring by in-line commands * @param label pointer to a label object * @param recolor_en true: enable recoloring, false: disable */ void lv_label_set_recolor(lv_obj_t * label, bool recolor_en) { lv_label_ext_t * ext = lv_obj_get_ext_attr(label); ext->recolor = recolor_en == false ? 0 : 1; lv_label_refr_text(label); /*Refresh the text because the potential colo codes in text needs to be hided or revealed*/ }
/** * Turn OFF the switch with an animation * @param sw pointer to a switch object */ void lv_sw_off_anim(lv_obj_t * sw) { lv_sw_ext_t * ext = lv_obj_get_ext_attr(sw); if(lv_sw_get_anim_time(sw) > 0) lv_sw_anim_to_value(sw, 0); else lv_slider_set_value(sw, 0); lv_slider_set_style(sw, LV_SLIDER_STYLE_KNOB, ext->style_knob_off); }
/** * 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_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 the brightness of a LED object * @param led pointer to a LED object * @param bright 0 (max. dark) ... 255 (max. light) */ void lv_led_set_bright(lv_obj_t * led, uint8_t bright) { /*Set the brightness*/ lv_led_ext_t * ext = lv_obj_get_ext_attr(led); ext->bright = bright; /*Invalidate the object there fore it will be redrawn*/ lv_obj_invalidate(led); }
/** * Set the label to draw (or not draw) background specified in its style's body * @param label pointer to a label object * @param body_en true: draw body; false: don't draw body */ void lv_label_set_body_draw(lv_obj_t *label, bool body_en) { lv_label_ext_t * ext = lv_obj_get_ext_attr(label); ext->body_draw = body_en == false ? 0 : 1; lv_obj_refresh_ext_size(label); lv_obj_invalidate(label); }
/** * Set the open/close animation time. * @param ddlist pointer to a drop down list * @param anim_time: open/close animation time [ms] */ void lv_ddlist_set_anim_time(lv_obj_t * ddlist, uint16_t anim_time) { lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist); #if USE_LV_ANIMATION == 0 anim_time = 0; #endif ext->anim_time = anim_time; }
/** * Set the fix height for the drop down list * If 0 then the opened ddlist will be auto. sized else the set height will be applied. * @param ddlist pointer to a drop down list * @param h the height when the list is opened (0: auto size) */ void lv_ddlist_set_fix_height(lv_obj_t * ddlist, lv_coord_t h) { lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist); if(ext->fix_height == h) return; ext->fix_height = h; lv_ddlist_refr_size(ddlist, false); }
/** * 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]; }
/** * Set the label's animation speed in LV_LABEL_LONG_ROLL and SCROLL modes * @param label pointer to a label object * @param anim_speed speed of animation in px/sec unit */ void lv_label_set_anim_speed(lv_obj_t *label, uint16_t anim_speed) { lv_label_ext_t *ext = lv_obj_get_ext_attr(label); ext->anim_speed = anim_speed; if(ext->long_mode == LV_LABEL_LONG_ROLL || ext->long_mode == LV_LABEL_LONG_SCROLL) { lv_label_refr_text(label); } }
/** * Set the align of the label (left or center) * @param label pointer to a label object * @param align 'LV_LABEL_ALIGN_LEFT' or 'LV_LABEL_ALIGN_LEFT' */ void lv_label_set_align(lv_obj_t *label, lv_label_align_t align) { lv_label_ext_t *ext = lv_obj_get_ext_attr(label); ext->align = align; lv_obj_invalidate(label); /*Enough to invalidate because alignment is only drawing related (lv_refr_label_text() not required)*/ }
/** * Close (Collapse) the drop down list * @param ddlist pointer to drop down list object * @param anim_en true: use animation; false: not use animations */ void lv_ddlist_close(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); ext->opened = 0; lv_obj_set_drag(lv_page_get_scrl(ddlist), false); lv_ddlist_refr_size(ddlist, anim_en); }
uint16_t lv_sw_get_anim_time(const lv_obj_t *sw) { #if USE_LV_ANIMATION lv_sw_ext_t * ext = lv_obj_get_ext_attr(sw); return ext->anim_time; #else return 0; #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 } }
/** * Signal function of the roller * @param roller pointer to a roller 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_roller_signal(lv_obj_t * roller, lv_signal_t sign, void * param) { lv_res_t res = LV_RES_OK; /*Don't let the drop down list to handle the control signals. It works differently*/ if(sign != LV_SIGNAL_CONTROLL && sign != LV_SIGNAL_FOCUS && sign != LV_SIGNAL_DEFOCUS) { /* Include the ancient signal function */ res = ancestor_signal(roller, sign, param); if(res != LV_RES_OK) return res; } lv_roller_ext_t * ext = lv_obj_get_ext_attr(roller); if(sign == LV_SIGNAL_STYLE_CHG) { lv_obj_set_height(lv_page_get_scrl(roller), lv_obj_get_height(ext->ddlist.label) + lv_obj_get_height(roller)); lv_obj_align(ext->ddlist.label, NULL, LV_ALIGN_CENTER, 0, 0); lv_ddlist_set_selected(roller, ext->ddlist.sel_opt_id); refr_position(roller, false); } else if(sign == LV_SIGNAL_CORD_CHG) { if(lv_obj_get_width(roller) != lv_area_get_width(param) || lv_obj_get_height(roller) != lv_area_get_height(param)) { lv_ddlist_set_fix_height(roller, lv_obj_get_height(roller)); lv_obj_set_height(lv_page_get_scrl(roller), lv_obj_get_height(ext->ddlist.label) + lv_obj_get_height(roller)); lv_obj_align(ext->ddlist.label, NULL, LV_ALIGN_CENTER, 0, 0); lv_ddlist_set_selected(roller, ext->ddlist.sel_opt_id); refr_position(roller, false); } } else if(sign == LV_SIGNAL_CONTROLL) { char c = *((char*)param); if(c == LV_GROUP_KEY_RIGHT || c == LV_GROUP_KEY_DOWN) { if(ext->ddlist.sel_opt_id +1 < ext->ddlist.option_cnt) { lv_roller_set_selected(roller, ext->ddlist.sel_opt_id + 1, true); if(ext->ddlist.action != NULL) { ext->ddlist.action(roller); } } } else if(c == LV_GROUP_KEY_LEFT || c == LV_GROUP_KEY_UP) { if(ext->ddlist.sel_opt_id > 0) { lv_roller_set_selected(roller, ext->ddlist.sel_opt_id - 1, true); if(ext->ddlist.action != NULL) { ext->ddlist.action(roller); } } } } return res; }
/** * Create a gauge objects * @param par pointer to an object, it will be the parent of the new gauge * @param copy pointer to a gauge object, if not NULL then the new object will be copied from it * @return pointer to the created gauge */ lv_obj_t * lv_gauge_create(lv_obj_t * par, lv_obj_t * copy) { /*Create the ancestor gauge*/ lv_obj_t * new_gauge = lv_lmeter_create(par, copy); lv_mem_assert(new_gauge); /*Allocate the gauge type specific extended data*/ lv_gauge_ext_t * ext = lv_obj_allocate_ext_attr(new_gauge, sizeof(lv_gauge_ext_t)); lv_mem_assert(ext); /*Initialize the allocated 'ext' */ ext->needle_count = 0; ext->values = NULL; ext->needle_colors = NULL; ext->label_count = LV_GAUGE_DEF_LABEL_COUNT; if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_func(new_gauge); if(ancestor_design == NULL) ancestor_design = lv_obj_get_design_func(new_gauge); /*The signal and design functions are not copied so set them here*/ lv_obj_set_signal_func(new_gauge, lv_gauge_signal); lv_obj_set_design_func(new_gauge, lv_gauge_design); /*Init the new gauge gauge*/ if(copy == 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_gauge_set_critical_value(new_gauge, 80); lv_obj_set_size(new_gauge, 2 * LV_DPI, 2 * LV_DPI); /*Set the default styles*/ lv_theme_t *th = lv_theme_get_current(); if(th) { lv_gauge_set_style(new_gauge, th->gauge); } else { lv_gauge_set_style(new_gauge, &lv_style_pretty_color); } } /*Copy an existing gauge*/ else { lv_gauge_ext_t * copy_ext = lv_obj_get_ext_attr(copy); 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++) { ext->values[i] = copy_ext->values[i]; } ext->label_count = copy_ext->label_count; /*Refresh the style with new signal function*/ lv_obj_refresh_style(new_gauge); } return new_gauge; }