diff --git a/lv_objx/lv_btn.c b/lv_objx/lv_btn.c index b454a7968..6560bc700 100644 --- a/lv_objx/lv_btn.c +++ b/lv_objx/lv_btn.c @@ -25,7 +25,7 @@ * STATIC PROTOTYPES **********************/ static bool lv_btn_design(lv_obj_t * btn, const area_t * mask, lv_design_mode_t mode); -static void lv_btn_style_load(lv_obj_t * btn, lv_rects_t * rects); +static void lv_btn_style_load(lv_obj_t * btn, lv_rects_t * new_rects); static void lv_btns_init(void); /********************** @@ -35,6 +35,8 @@ static lv_btns_t lv_btns_def; static lv_btns_t lv_btns_transp; static lv_btns_t lv_btns_border; +static lv_design_f_t ancestor_design_f; + /********************** * MACROS **********************/ @@ -56,12 +58,18 @@ lv_obj_t * lv_btn_create(lv_obj_t * par, lv_obj_t * copy) new_btn = lv_rect_create(par, copy); /*Allocate the extended data*/ lv_obj_alloc_ext(new_btn, sizeof(lv_btn_ext_t)); + + if(ancestor_design_f == NULL) { + ancestor_design_f = lv_obj_get_design_f(new_btn); + } + lv_obj_set_signal_f(new_btn, lv_btn_signal); lv_obj_set_design_f(new_btn, lv_btn_design); lv_btn_ext_t * ext = lv_obj_get_ext(new_btn); ext->lpr_exec = 0; + /*If no copy do the basic initialization*/ if(copy == NULL) { @@ -70,7 +78,6 @@ lv_obj_t * lv_btn_create(lv_obj_t * par, lv_obj_t * copy) ext->rel_action = NULL; ext->lpr_action = NULL; ext->tgl = 0; - lv_obj_set_style(new_btn, lv_btns_get(LV_BTNS_DEF, NULL)); lv_rect_set_layout(new_btn, LV_RECT_LAYOUT_CENTER); } /*Copy 'copy'*/ @@ -83,6 +90,8 @@ lv_obj_t * lv_btn_create(lv_obj_t * par, lv_obj_t * copy) ext->tgl = ori_btn_ext->tgl; } + lv_obj_set_style(new_btn, lv_btns_get(LV_BTNS_DEF, NULL)); + return new_btn; } @@ -330,51 +339,44 @@ static bool lv_btn_design(lv_obj_t * btn, const area_t * mask, lv_design_mode_t /* Because of the radius it is not sure the area is covered*/ if(mode == LV_DESIGN_COVER_CHK) { - uint16_t r = btns_p->rects.round; - area_t area_tmp; - - /*Check horizontally without radius*/ - lv_obj_get_cords(btn, &area_tmp); - area_tmp.x1 += r; - area_tmp.x2 -= r; - if(area_is_in(mask, &area_tmp) == true) return true; - - /*Check vertically without radius*/ - lv_obj_get_cords(btn, &area_tmp); - area_tmp.y1 += r; - area_tmp.y2 -= r; - if(area_is_in(mask, &area_tmp) == true) return true; - - return false; + return ancestor_design_f(btn, mask, mode); } else if(mode == LV_DESIGN_DRAW_MAIN) { opa_t opa = lv_obj_get_opa(btn); area_t area; lv_obj_get_cords(btn, &area); + /*Temporally set a rectangle style for the button to draw it as rectangle*/ lv_rects_t rects_tmp; - + lv_btns_t * btns_tmp = lv_obj_get_style(btn); lv_btn_style_load(btn, &rects_tmp); - - /*Draw the rectangle*/ - lv_draw_rect(&area, mask, &rects_tmp, opa); + btn->style_p = &rects_tmp; + ancestor_design_f(btn, mask, mode); /*Draw the rectangle*/ + btn->style_p = btns_tmp; /*Reload the origial butto style*/ } return true; } /** - * Load the corresponding style according to the state to 'rects' in 'lv_btns_t' - * @param obj pointer to a button object + * Crate a rectangle style according to the state of the button + * @param btn pointer to a button object + * @param new_rects load the style here (pointer to a rectangle style) */ -static void lv_btn_style_load(lv_obj_t * btn, lv_rects_t * rects) +static void lv_btn_style_load(lv_obj_t * btn, lv_rects_t * new_rects) { lv_btn_state_t state = lv_btn_get_state(btn); - lv_btns_t * ext = lv_obj_get_style(btn); + lv_btns_t * style = lv_obj_get_style(btn); /*Load the style*/ - memcpy(rects, &ext->rects, sizeof(lv_rects_t)); - rects->objs.color = ext->mcolor[state]; - rects->gcolor = ext->gcolor[state]; - rects->bcolor = ext->bcolor[state]; + memcpy(new_rects, &style->rects, sizeof(lv_rects_t)); + new_rects->objs.color = style->mcolor[state]; + new_rects->gcolor = style->gcolor[state]; + new_rects->bcolor = style->bcolor[state]; + new_rects->lcolor = style->lcolor[state]; + if(style->light_en[state] != 0) { + new_rects->light = style->rects.light; + } else { + new_rects->light = 0; + } } /** @@ -386,25 +388,36 @@ static void lv_btns_init(void) lv_btns_def.mcolor[LV_BTN_STATE_REL] = COLOR_MAKE(0x40, 0x60, 0x80); lv_btns_def.gcolor[LV_BTN_STATE_REL] = COLOR_BLACK; lv_btns_def.bcolor[LV_BTN_STATE_REL] = COLOR_WHITE; + lv_btns_def.lcolor[LV_BTN_STATE_REL] = COLOR_MAKE(0x30, 0x40, 0x50); + lv_btns_def.light_en[LV_BTN_STATE_REL] = 0; lv_btns_def.mcolor[LV_BTN_STATE_PR] = COLOR_MAKE(0x60, 0x80, 0xa0); lv_btns_def.gcolor[LV_BTN_STATE_PR] = COLOR_MAKE(0x20, 0x30, 0x40); lv_btns_def.bcolor[LV_BTN_STATE_PR] = COLOR_WHITE; + lv_btns_def.lcolor[LV_BTN_STATE_PR] = COLOR_MAKE(0x30, 0x40, 0x50); + lv_btns_def.light_en[LV_BTN_STATE_PR] = 1; lv_btns_def.mcolor[LV_BTN_STATE_TGL_REL] = COLOR_MAKE(0x80, 0x00, 0x00); lv_btns_def.gcolor[LV_BTN_STATE_TGL_REL] = COLOR_MAKE(0x20, 0x20, 0x20); lv_btns_def.bcolor[LV_BTN_STATE_TGL_REL] = COLOR_WHITE; + lv_btns_def.lcolor[LV_BTN_STATE_TGL_REL] = COLOR_MAKE(0x30, 0x40, 0x50); + lv_btns_def.light_en[LV_BTN_STATE_TGL_REL] = 0; lv_btns_def.mcolor[LV_BTN_STATE_TGL_PR] = COLOR_MAKE(0xf0, 0x26, 0x26); lv_btns_def.gcolor[LV_BTN_STATE_TGL_PR] = COLOR_MAKE(0x40, 0x40, 0x40); lv_btns_def.bcolor[LV_BTN_STATE_TGL_PR] = COLOR_WHITE; + lv_btns_def.lcolor[LV_BTN_STATE_TGL_PR] = COLOR_MAKE(0x30, 0x40, 0x50); + lv_btns_def.light_en[LV_BTN_STATE_TGL_PR] = 1; lv_btns_def.mcolor[LV_BTN_STATE_INA] = COLOR_SILVER; lv_btns_def.gcolor[LV_BTN_STATE_INA] = COLOR_GRAY; lv_btns_def.bcolor[LV_BTN_STATE_INA] = COLOR_WHITE; + lv_btns_def.lcolor[LV_BTN_STATE_INA] = COLOR_MAKE(0x30, 0x40, 0x50); + lv_btns_def.light_en[LV_BTN_STATE_INA] = 0; lv_btns_def.rects.bwidth = 2 * LV_STYLE_MULT; lv_btns_def.rects.bopa = 50; + lv_btns_def.rects.light = 8 * LV_STYLE_MULT; lv_btns_def.rects.empty = 0; lv_btns_def.rects.round = 4 * LV_STYLE_MULT; lv_btns_def.rects.hpad = 10 * LV_STYLE_MULT; diff --git a/lv_objx/lv_btn.h b/lv_objx/lv_btn.h index 7ebee8283..95ed0e971 100644 --- a/lv_objx/lv_btn.h +++ b/lv_objx/lv_btn.h @@ -41,6 +41,8 @@ typedef struct color_t mcolor[LV_BTN_STATE_NUM]; color_t gcolor[LV_BTN_STATE_NUM]; color_t bcolor[LV_BTN_STATE_NUM]; + color_t lcolor[LV_BTN_STATE_NUM]; + uint8_t light_en[LV_BTN_STATE_NUM]; }lv_btns_t; /*Built-in styles of button*/ diff --git a/lv_objx/lv_rect.c b/lv_objx/lv_rect.c index 326a86960..e7692572d 100644 --- a/lv_objx/lv_rect.c +++ b/lv_objx/lv_rect.c @@ -36,13 +36,14 @@ * STATIC PROTOTYPES **********************/ static bool lv_rect_design(lv_obj_t * rect, const area_t * mask, lv_design_mode_t mode); -static void lv_rects_init(void); +static void lv_rect_draw_light(lv_obj_t * rect, const area_t * mask); static void lv_rect_refr_layout(lv_obj_t * rect); static void lv_rect_layout_col(lv_obj_t * rect); static void lv_rect_layout_row(lv_obj_t * rect); static void lv_rect_layout_center(lv_obj_t * rect); static void lv_rect_layout_grid(lv_obj_t * rect); static void lv_rect_refr_autofit(lv_obj_t * rect); +static void lv_rects_init(void); /********************** * STATIC VARIABLES @@ -112,8 +113,15 @@ bool lv_rect_signal(lv_obj_t * rect, lv_signal_t sign, void * param) /* The object can be deleted so check its validity and then * make the object specific signal handling */ if(valid != false) { + + lv_rects_t * style = lv_obj_get_style(rect); + switch(sign) { case LV_SIGNAL_STYLE_CHG: /*Recalculate the padding if the style changed*/ + lv_rect_refr_layout(rect); + lv_rect_refr_autofit(rect); + lv_obj_ext_size_refr(rect); + break; case LV_SIGNAL_CHILD_CHG: lv_rect_refr_layout(rect); lv_rect_refr_autofit(rect); @@ -125,10 +133,9 @@ bool lv_rect_signal(lv_obj_t * rect, lv_signal_t sign, void * param) lv_rect_refr_autofit(rect); } break; - - - break; - + case LV_SIGNAL_REFR_EXT_SIZE: + if(style->light > rect->ext_size) rect->ext_size = style->light; + break; default: break; } @@ -291,15 +298,64 @@ static bool lv_rect_design(lv_obj_t * rect, const area_t * mask, lv_design_mode_ return false; } else if(mode == LV_DESIGN_DRAW_MAIN) { opa_t opa = lv_obj_get_opa(rect); + lv_rects_t * style = lv_obj_get_style(rect); area_t area; lv_obj_get_cords(rect, &area); /*Draw the rectangle*/ - lv_draw_rect(&area, mask, lv_obj_get_style(rect), opa); + lv_draw_rect(&area, mask, style, opa); + lv_rect_draw_light(rect, mask); + + } else if(mode == LV_DESIGN_DRAW_POST) { + } return true; } +/** + * Draw a light around the object + * @param rect pointer to rectangle object + * @param mask pointer to a mask area (from the design functions) + */ +static void lv_rect_draw_light(lv_obj_t * rect, const area_t * mask) +{ + lv_rects_t * style = lv_obj_get_style(rect); + cord_t light_size = style->light; + if(light_size == 0) return; + if(light_size < LV_DOWNSCALE) light_size = LV_DOWNSCALE; + + area_t light_area; + lv_rects_t light_style; + lv_obj_get_cords(rect, &light_area); + + memcpy(&light_style, style, sizeof(lv_rects_t)); + + light_style.empty = 1; + light_style.bwidth = light_size; + light_style.round = style->round + light_size; + light_style.bcolor = style->lcolor; + light_style.bopa = 100; + + light_area.x1 -= light_size; + light_area.y1 -= light_size; + light_area.x2 += light_size; + light_area.y2 += light_size; + + cord_t i; + uint8_t res = LV_DOWNSCALE ; + opa_t opa_sub = lv_obj_get_opa(rect) / (light_size / LV_DOWNSCALE); + + for(i = 1; i < light_size; i += res) { + lv_draw_rect(&light_area, mask, &light_style, (uint16_t) opa_sub); + light_style.round -= res; + light_style.bwidth -= res; + light_area.x1 += res; + light_area.y1 += res; + light_area.x2 -= res; + light_area.y2 -= res; + } +} + /** * Refresh the layout of a rectangle * @param rect pointer to an object which layout should be refreshed @@ -612,6 +668,8 @@ static void lv_rects_init(void) lv_rects_def.hpad = 10 * LV_STYLE_MULT; lv_rects_def.vpad = 10 * LV_STYLE_MULT; lv_rects_def.opad = 10 * LV_STYLE_MULT; + lv_rects_def.light = 0; + lv_rects_def.lcolor = COLOR_MAKE(0x60, 0x60, 0x60); /*Transparent style*/ memcpy(&lv_rects_transp, &lv_rects_def, sizeof(lv_rects_t)); diff --git a/lv_objx/lv_rect.h b/lv_objx/lv_rect.h index 585c39d9d..120bfb9fe 100644 --- a/lv_objx/lv_rect.h +++ b/lv_objx/lv_rect.h @@ -42,13 +42,15 @@ typedef struct { lv_objs_t objs; /*Style of ancestor*/ /*New style element for this type */ - color_t gcolor; - color_t bcolor; + color_t gcolor; /*Gradient color*/ + color_t bcolor; /*Border color*/ + color_t lcolor; /*Light color*/ uint16_t bwidth; uint16_t round; cord_t hpad; cord_t vpad; cord_t opad; + cord_t light; /*Light size*/ uint8_t bopa; uint8_t empty :1; }lv_rects_t; diff --git a/lv_objx/lv_win.c b/lv_objx/lv_win.c index 3b0d72c0b..ccf0167e8 100644 --- a/lv_objx/lv_win.c +++ b/lv_objx/lv_win.c @@ -352,7 +352,7 @@ static void lv_wins_init(void) /** * Realign the building elements of a window - * @param win pointer to window object + * @param win pointer to window objectker */ static void lv_win_realign(lv_obj_t * win) {