/** * 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; }
/** * Signal function of the label * @param label pointer to a label 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_label_signal(lv_obj_t * label, lv_signal_t sign, void * param) { lv_res_t res; /* Include the ancient signal function */ res = ancestor_signal(label, sign, param); if(res != LV_RES_OK) return res; lv_label_ext_t * ext = lv_obj_get_ext_attr(label); if(sign == LV_SIGNAL_CLEANUP) { if(ext->static_txt == 0) { lv_mem_free(ext->text); ext->text = NULL; } } else if(sign == LV_SIGNAL_STYLE_CHG) { /*Revert dots for proper refresh*/ lv_label_revert_dots(label); lv_label_refr_text(label); } else if (sign == LV_SIGNAL_CORD_CHG) { if(lv_area_get_width(&label->coords) != lv_area_get_width(param) || lv_area_get_height(&label->coords) != lv_area_get_height(param)) { lv_label_revert_dots(label); lv_label_refr_text(label); } } else if(sign == LV_SIGNAL_REFR_EXT_SIZE) { if(ext->body_draw) { lv_style_t * style = lv_label_get_style(label); label->ext_size = LV_MATH_MAX(label->ext_size, style->body.padding.hor); label->ext_size = LV_MATH_MAX(label->ext_size, style->body.padding.ver); } } else if(sign == LV_SIGNAL_GET_TYPE) { lv_obj_type_t * buf = param; uint8_t i; for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/ if(buf->type[i] == NULL) break; } buf->type[i] = "lv_label"; } return res; }
/** * 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; }
/** * 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 * @return LV_RES_OK: the object is not deleted in the function; LV_RES_INV: the object is deleted */ static lv_res_t lv_page_scrollable_signal(lv_obj_t * scrl, lv_signal_t sign, void * param) { lv_res_t res; /* Include the ancient signal function */ res = ancestor_signal(scrl, sign, param); if(res != LV_RES_OK) return res; 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_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)*/ lv_coord_t new_x; lv_coord_t new_y; bool refr_x = false; bool refr_y = false; lv_area_t page_cords; lv_area_t scrl_cords; lv_coord_t hpad = page_style->body.padding.hor; lv_coord_t vpad = page_style->body.padding.ver; new_x = lv_obj_get_x(scrl); new_y = lv_obj_get_y(scrl); lv_obj_get_coords(scrl, &scrl_cords); lv_obj_get_coords(page, &page_cords); /*scrollable width smaller then page width? -> align to left*/ if(lv_area_get_width(&scrl_cords) + 2 * hpad < lv_area_get_width(&page_cords)) { if(scrl_cords.x1 != page_cords.x1 + hpad) { new_x = hpad; refr_x = true; } } else { /*The edges of the scrollable can not be in the page (minus hpad) */ if(scrl_cords.x2 < page_cords.x2 - hpad) { new_x = lv_area_get_width(&page_cords) - lv_area_get_width(&scrl_cords) - hpad; /* Right align */ refr_x = true; } if (scrl_cords.x1 > page_cords.x1 + hpad) { new_x = hpad; /*Left align*/ refr_x = true; } } /*scrollable height smaller then page height? -> align to left*/ if(lv_area_get_height(&scrl_cords) + 2 * vpad < lv_area_get_height(&page_cords)) { if(scrl_cords.y1 != page_cords.y1 + vpad) { new_y = vpad; refr_y = true; } } else { /*The edges of the scrollable can not be in the page (minus vpad) */ if(scrl_cords.y2 < page_cords.y2 - vpad) { new_y = lv_area_get_height(&page_cords) - lv_area_get_height(&scrl_cords) - vpad; /* Bottom align */ refr_y = true; } if (scrl_cords.y1 > page_cords.y1 + vpad) { new_y = vpad; /*Top align*/ refr_y = true; } } if(refr_x != false || refr_y != false) { lv_obj_set_pos(scrl, new_x, new_y); } lv_page_sb_refresh(page); } else if(sign == LV_SIGNAL_DRAG_END) { /*Hide scrollbars if required*/ if(page_ext->sb.mode == LV_SB_MODE_DRAG) { lv_area_t sb_area_tmp; if(page_ext->sb.hor_draw) { lv_area_copy(&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->sb.hor_draw = 0; } if(page_ext->sb.ver_draw) { lv_area_copy(&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->sb.ver_draw = 0; } } } else if(sign == LV_SIGNAL_PRESSED) { if(page_ext->pr_action != NULL) { page_ext->pr_action(page); } } 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); } } } return res; }
/** * 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 */ static lv_res_t lv_page_signal(lv_obj_t * page, lv_signal_t sign, void * param) { lv_res_t res; /* Include the ancient signal function */ res = ancestor_signal(page, sign, param); if(res != LV_RES_OK) return res; 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) { /*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) { lv_obj_t * tmp = child; child = lv_obj_get_child(page, child); /*Get the next child before move this*/ lv_obj_set_parent(tmp, ext->scrl); } else { child = lv_obj_get_child(page, child); } } } 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); } /*The scrollbars are important only if they are visible now*/ if(ext->sb.hor_draw || ext->sb.ver_draw) lv_page_sb_refresh(page); /*Refresh the ext. size because the scrollbars might be positioned out of the page*/ lv_obj_refresh_ext_size(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) != lv_area_get_width(param) || lv_obj_get_height(page) != lv_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->sb.hor_draw || ext->sb.ver_draw) lv_page_sb_refresh(page); } } else if(sign == LV_SIGNAL_PRESSED) { if(ext->pr_action != NULL) { ext->pr_action(page); } } 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); } } } else if(sign == LV_SIGNAL_REFR_EXT_SIZE) { /*Ensure ext. size for the scrollbars if they are out of the page*/ if(page->ext_size < (-ext->sb.style->body.padding.hor)) page->ext_size = -ext->sb.style->body.padding.hor; if(page->ext_size < (-ext->sb.style->body.padding.ver)) page->ext_size = -ext->sb.style->body.padding.ver; } else if(sign == LV_SIGNAL_GET_TYPE) { lv_obj_type_t * buf = param; uint8_t i; for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/ if(buf->type[i] == NULL) break; } buf->type[i] = "lv_page"; } return res; }