コード例 #1
0
ファイル: lv_page.c プロジェクト: databuser/lvgl
/**
 * 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 * page, const lv_area_t * mask, lv_design_mode_t mode)
{
    if(mode == LV_DESIGN_COVER_CHK) {
    	return ancestor_design(page, mask, mode);
    } else if(mode == LV_DESIGN_DRAW_MAIN) {
        /*Draw without border*/
        lv_style_t *style = lv_page_get_style(page, LV_PAGE_STYLE_BG);
        lv_coord_t border_width_tmp =  style->body.border.width;
        style->body.border.width = 0;
        lv_draw_rect(&page->coords, mask, style);
        style->body.border.width = border_width_tmp;

	} else if(mode == LV_DESIGN_DRAW_POST) { /*Draw the scroll bars finally*/

        /*Draw only a border*/
        lv_style_t *style = lv_page_get_style(page, LV_PAGE_STYLE_BG);
        lv_coord_t shadow_width_tmp =  style->body.shadow.width;
        uint8_t empty_tmp =  style->body.empty;
        style->body.shadow.width = 0;
        style->body.empty = 1;
        lv_draw_rect(&page->coords, mask, style);
        style->body.shadow.width = shadow_width_tmp;
        style->body.empty = empty_tmp;


		lv_page_ext_t * ext = lv_obj_get_ext_attr(page);

		/*Draw the scrollbars*/
		lv_area_t sb_area;
		if(ext->sb.hor_draw) {
		    /*Convert the relative coordinates to absolute*/
            lv_area_copy(&sb_area, &ext->sb.hor_area);
		    sb_area.x1 += page->coords.x1;
            sb_area.y1 += page->coords.y1;
            sb_area.x2 += page->coords.x1;
            sb_area.y2 += page->coords.y1;
			lv_draw_rect(&sb_area, mask, ext->sb.style);
		}

		if(ext->sb.ver_draw) {
            /*Convert the relative coordinates to absolute*/
            lv_area_copy(&sb_area, &ext->sb.ver_area);
            sb_area.x1 += page->coords.x1;
            sb_area.y1 += page->coords.y1;
            sb_area.x2 += page->coords.x1;
            sb_area.y2 += page->coords.y1;
			lv_draw_rect(&sb_area, mask, ext->sb.style);
		}
	}

	return true;
}
コード例 #2
0
/**
 * Draw a rectangle which has gradient on its top and bottom
 * @param roller pointer to a roller object
 * @param mask pointer to the current mask (from the design function)
 */
static void draw_bg(lv_obj_t *roller, const lv_area_t *mask)
{
    lv_style_t *style = lv_roller_get_style(roller, LV_ROLLER_STYLE_BG);
    lv_area_t half_mask;
    lv_area_t half_roller;
    lv_coord_t h = lv_obj_get_height(roller);
    bool union_ok;
    lv_area_copy(&half_roller, &roller->coords);

    half_roller.x1 -= roller->ext_size; /*Add ext size too (e.g. because of shadow draw) */
    half_roller.x2 += roller->ext_size;
    half_roller.y1 -= roller->ext_size;
    half_roller.y2 = roller->coords.y1 + h / 2;

    union_ok = lv_area_union(&half_mask, &half_roller, mask);

    half_roller.x1 += roller->ext_size; /*Revert ext. size adding*/
    half_roller.x2 -= roller->ext_size;
    half_roller.y1 += roller->ext_size;
    half_roller.y2 += style->body.radius;

    if(union_ok) {
        lv_draw_rect(&half_roller, &half_mask, style);
    }

    half_roller.x1 -= roller->ext_size; /*Add ext size too (e.g. because of shadow draw) */
    half_roller.x2 += roller->ext_size;
    half_roller.y2 = roller->coords.y2 + roller->ext_size;
    half_roller.y1 = roller->coords.y1 + h / 2;
    if((h & 0x1) == 0) half_roller.y1++;    /*With even height the pixels in the middle would be drawn twice*/

    union_ok = lv_area_union(&half_mask, &half_roller, mask);

    half_roller.x1 += roller->ext_size; /*Revert ext. size adding*/
    half_roller.x2 -= roller->ext_size;
    half_roller.y2 -= roller->ext_size;
    half_roller.y1 -= style->body.radius;

    if(union_ok){
        lv_color_t main_tmp = style->body.main_color;
        lv_color_t grad_tmp = style->body.grad_color;

        style->body.main_color = grad_tmp;
        style->body.grad_color = main_tmp;
        lv_draw_rect(&half_roller, &half_mask, style);
        style->body.main_color = main_tmp;
        style->body.grad_color = grad_tmp;
    }

}
コード例 #3
0
ファイル: lv_label.c プロジェクト: databuser/lvgl
/**
 * Handle the drawing related tasks of the labels
 * @param label pointer to a label 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_label_design(lv_obj_t * label, const lv_area_t * mask, lv_design_mode_t mode)
{
    /* A label never covers an area */
    if(mode == LV_DESIGN_COVER_CHK) return false;
    else if(mode == LV_DESIGN_DRAW_MAIN) {
        lv_area_t coords;
        lv_style_t * style = lv_obj_get_style(label);
        lv_obj_get_coords(label, &coords);

#if USE_LV_GROUP
        lv_group_t * g = lv_obj_get_group(label);
        if(lv_group_get_focused(g) == label) {
            lv_draw_rect(&coords, mask, style);
        }
#endif

        lv_label_ext_t * ext = lv_obj_get_ext_attr(label);

        if(ext->body_draw) {
            lv_area_t bg;
            lv_obj_get_coords(label, &bg);
            bg.x1 -= style->body.padding.hor;
            bg.x2 += style->body.padding.hor;
            bg.y1 -= style->body.padding.ver;
            bg.y2 += style->body.padding.ver;

            lv_draw_rect(&bg, mask, style);
        }

        /*TEST: draw a background for the label*/
//		lv_draw_rect(&label->coords, mask, &lv_style_plain_color);

		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;
        if(ext->align == LV_LABEL_ALIGN_CENTER) flag |= LV_TXT_FLAG_CENTER;

		lv_draw_label(&coords, mask, style, ext->text, flag, &ext->offset);
    }
    return true;
}
コード例 #4
0
/**
 * 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;
}
コード例 #5
0
ファイル: lv_gauge.c プロジェクト: Solitarily/Xmotion
/**
 * Draw the needles of a gauge
 * @param gauge pointer to gauge object
 * @param mask mask of drawing
 */
static void lv_gauge_draw_needle(lv_obj_t * gauge, const lv_area_t * mask)
{
    lv_style_t style_needle;
    lv_gauge_ext_t * ext = lv_obj_get_ext_attr(gauge);
    lv_style_t * style = lv_gauge_get_style(gauge);

    lv_coord_t r = lv_obj_get_width(gauge) / 2 - style->body.padding.hor;
    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;
    uint16_t angle = lv_lmeter_get_scale_angle(gauge);
    int16_t angle_ofs = 90 + (360 - angle) / 2;
    int16_t min = lv_gauge_get_min_value(gauge);
    int16_t max = lv_gauge_get_max_value(gauge);
    lv_point_t p_mid;
    lv_point_t p_end;
    uint8_t i;

    lv_style_copy(&style_needle, style);

    p_mid.x = x_ofs;
    p_mid.y = y_ofs;
    for(i = 0; i < ext->needle_count; i++) {
        /*Calculate the end point of a needle*/
        int16_t needle_angle = (ext->values[i] - min) * angle / (max - min) + angle_ofs;
        p_end.y = (lv_trigo_sin(needle_angle) * r) / LV_TRIGO_SIN_MAX + y_ofs;
        p_end.x = (lv_trigo_sin(needle_angle + 90) * r) / LV_TRIGO_SIN_MAX + x_ofs;

        /*Draw the needle with the corresponding color*/
        if(ext->needle_colors == NULL) style_needle.line.color = LV_GAUGE_DEF_NEEDLE_COLOR;
        else style_needle.line.color = ext->needle_colors[i];

        lv_draw_line(&p_mid, &p_end, mask, &style_needle);
    }

    /*Draw the needle middle area*/
    lv_style_t style_neddle_mid;
    lv_style_copy(&style_neddle_mid, &lv_style_plain);
    style_neddle_mid.body.main_color = style->body.border.color;
    style_neddle_mid.body.grad_color = style->body.border.color;
    style_neddle_mid.body.radius = LV_RADIUS_CIRCLE;

    lv_area_t nm_cord;
    nm_cord.x1 = x_ofs - style->body.padding.ver;
    nm_cord.y1 = y_ofs - style->body.padding.ver;
    nm_cord.x2 = x_ofs + style->body.padding.ver;
    nm_cord.y2 = y_ofs + style->body.padding.ver;

    lv_draw_rect(&nm_cord, mask, &style_neddle_mid);
}
コード例 #6
0
ファイル: lv_ddlist.c プロジェクト: Solitarily/Xmotion
/**
 * Handle the drawing related tasks of the drop down lists
 * @param ddlist 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_ddlist_design(lv_obj_t * ddlist, 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 ancestor_design(ddlist, mask, mode);
    }
    /*Draw the object*/
    else if(mode == LV_DESIGN_DRAW_MAIN) {
        ancestor_design(ddlist, mask, mode);

        lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist);

        /*If the list is opened draw a rectangle under the selected item*/
        if(ext->opened != 0) {
            lv_style_t *style = lv_ddlist_get_style(ddlist, LV_DDLIST_STYLE_BG);
            const lv_font_t * font = style->text.font;
            lv_coord_t font_h = lv_font_get_height(font);

            /*Draw the selected*/
            lv_area_t rect_area;
            rect_area.y1 = ext->label->coords.y1;
            rect_area.y1 += ext->sel_opt_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.line_space;
            rect_area.x1 = ddlist->coords.x1;
            rect_area.x2 = ddlist->coords.x2;

            lv_draw_rect(&rect_area, mask, ext->sel_style);
        }
    }
    /*Post draw when the children are drawn*/
    else if(mode == LV_DESIGN_DRAW_POST) {
        ancestor_design(ddlist, mask, mode);

        /*Redraw the text on the selected area with a different color*/
        lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist);

        /*Redraw only in opened state*/
        if(ext->opened == 0) return true;

        lv_style_t *style = lv_ddlist_get_style(ddlist, LV_DDLIST_STYLE_BG);
        const lv_font_t * font = style->text.font;
        lv_coord_t font_h = lv_font_get_height(font);

        lv_area_t area_sel;
        area_sel.y1 = ext->label->coords.y1;
        area_sel.y1 += ext->sel_opt_id * (font_h + style->text.line_space);
        area_sel.y1 -= style->text.line_space / 2;

        area_sel.y2 = area_sel.y1 + font_h + style->text.line_space;
        area_sel.x1 = ddlist->coords.x1;
        area_sel.x2 = ddlist->coords.x2;
        lv_area_t mask_sel;
        bool area_ok;
        area_ok = lv_area_union(&mask_sel, mask, &area_sel);
        if(area_ok) {
            lv_style_t *sel_style = lv_ddlist_get_style(ddlist, LV_DDLIST_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->label->coords, &mask_sel, &new_style,
                          lv_label_get_text(ext->label), LV_TXT_FLAG_NONE, NULL);
        }
    }

    return true;
}