diff --git a/lv_conf_templ.h b/lv_conf_templ.h index cce4c48b7..f43efeda6 100644 --- a/lv_conf_templ.h +++ b/lv_conf_templ.h @@ -46,7 +46,7 @@ * to store the graphical objects and other data */ #define LV_MEM_CUSTOM 0 /*1: use custom malloc/free, 0: use the built-in lv_mem_alloc/lv_mem_free*/ #if LV_MEM_CUSTOM == 0 -# define LV_MEM_SIZE (16U * 1024U) /*Size memory used by `lv_mem_alloc` in bytes (>= 2kB)*/ +# define LV_MEM_SIZE (32U * 1024U) /*Size memory used by `lv_mem_alloc` in bytes (>= 2kB)*/ # define LV_MEM_ATTR /*Complier prefix for big array declaration*/ # define LV_MEM_ADR 0 /*Set an address for memory pool instead of allocation it as an array. Can be in external SRAM too.*/ # define LV_MEM_AUTO_DEFRAG 1 /*Automatically defrag on free*/ diff --git a/lv_core/lv_group.c b/lv_core/lv_group.c index a2de32fd4..6a4550890 100644 --- a/lv_core/lv_group.c +++ b/lv_core/lv_group.c @@ -466,7 +466,7 @@ static void style_mod_def(lv_style_t * style) style->body.border.color = LV_COLOR_ORANGE; /*If not empty or has border then emphasis the border*/ - if(style->body.empty == 0 || style->body.border.width != 0) style->body.border.width = LV_DPI / 20; + if(style->body.opa != LV_OPA_TRANSP || style->body.border.width != 0) style->body.border.width = LV_DPI / 20; style->body.main_color = lv_color_mix(style->body.main_color, LV_COLOR_ORANGE, LV_OPA_70); style->body.grad_color = lv_color_mix(style->body.grad_color, LV_COLOR_ORANGE, LV_OPA_70); @@ -495,7 +495,7 @@ static void style_mod_edit_def(lv_style_t * style) style->body.border.color = LV_COLOR_GREEN; /*If not empty or has border then emphasis the border*/ - if(style->body.empty == 0 || style->body.border.width != 0) style->body.border.width = LV_DPI / 20; + if(style->body.opa != LV_OPA_TRANSP || style->body.border.width != 0) style->body.border.width = LV_DPI / 20; style->body.main_color = lv_color_mix(style->body.main_color, LV_COLOR_GREEN, LV_OPA_70); style->body.grad_color = lv_color_mix(style->body.grad_color, LV_COLOR_GREEN, LV_OPA_70); diff --git a/lv_core/lv_indev.c b/lv_core/lv_indev.c index c8011dde5..fa2bab6fd 100644 --- a/lv_core/lv_indev.c +++ b/lv_core/lv_indev.c @@ -43,7 +43,7 @@ static void indev_proc_release(lv_indev_proc_t * proc); static void indev_proc_reset_query_handler(lv_indev_t * indev); static lv_obj_t * indev_search_obj(const lv_indev_proc_t * proc, lv_obj_t * obj); static void indev_drag(lv_indev_proc_t * state); -static void indev_drag_throw(lv_indev_proc_t * state); +static void indev_drag_throw(lv_indev_proc_t * proc); #endif /********************** @@ -425,7 +425,6 @@ static void indev_keypad_proc(lv_indev_t * i, lv_indev_data_t * data) } else if(data->key == LV_GROUP_KEY_ENTER) { if(!i->proc.long_pr_sent) { focused->signal_cb(focused, LV_SIGNAL_RELEASED, indev_act); - lv_obj_send_event(focused, LV_EVENT_RELEASED); lv_obj_send_event(focused, LV_EVENT_CLICKED); } } else { @@ -618,7 +617,7 @@ static void indev_proc_press(lv_indev_proc_t * proc) * It is necessary to count the long press time.*/ proc->pr_timestamp = lv_tick_get(); proc->long_pr_sent = 0; - proc->drag_range_out = 0; + proc->drag_limit_out = 0; proc->drag_in_prog = 0; proc->drag_sum.x = 0; proc->drag_sum.y = 0; @@ -652,6 +651,21 @@ static void indev_proc_press(lv_indev_proc_t * proc) proc->vect.x = proc->act_point.x - proc->last_point.x; proc->vect.y = proc->act_point.y - proc->last_point.y; + proc->drawg_throw_vect.x = (proc->drawg_throw_vect.x * 5) >> 3; + proc->drawg_throw_vect.y = (proc->drawg_throw_vect.y * 5) >> 3; + + if(proc->drawg_throw_vect.x < 0) proc->drawg_throw_vect.x++; + else if(proc->drawg_throw_vect.x > 0) proc->drawg_throw_vect.x--; + + if(proc->drawg_throw_vect.y < 0) proc->drawg_throw_vect.y++; + else if(proc->drawg_throw_vect.y > 0) proc->drawg_throw_vect.y--; + + proc->drawg_throw_vect.x += (proc->vect.x * 4) >> 3; + proc->drawg_throw_vect.y += (proc->vect.y * 4) >> 3; + + printf("dtv:%d\n", proc->drawg_throw_vect.y); + + /*If there is active object and it can be dragged run the drag*/ if(proc->act_obj != NULL) { proc->act_obj->signal_cb(proc->act_obj, LV_SIGNAL_PRESSING, indev_act); @@ -715,9 +729,10 @@ static void indev_proc_release(lv_indev_proc_t * proc) lv_obj_t * obj_on = indev_search_obj(proc, proc->act_obj); if(obj_on == proc->act_obj) { proc->act_obj->signal_cb(proc->act_obj, LV_SIGNAL_RELEASED, indev_act); - lv_obj_send_event(proc->act_obj, LV_EVENT_RELEASED); if(proc->long_pr_sent == 0 && proc->drag_in_prog == 0) { lv_obj_send_event(proc->act_obj, LV_EVENT_CLICKED); + } else { + lv_obj_send_event(proc->act_obj, LV_EVENT_RELEASED); } } else { @@ -730,9 +745,11 @@ static void indev_proc_release(lv_indev_proc_t * proc) * If it is already not pressed then was handled in `indev_proc_press`*/ else { proc->act_obj->signal_cb(proc->act_obj, LV_SIGNAL_RELEASED, indev_act); - lv_obj_send_event(proc->act_obj, LV_SIGNAL_RELEASED); + if(proc->long_pr_sent == 0 && proc->drag_in_prog == 0) { lv_obj_send_event(proc->act_obj, LV_EVENT_CLICKED); + } else { + lv_obj_send_event(proc->act_obj, LV_SIGNAL_RELEASED); } } @@ -794,7 +811,7 @@ static void indev_proc_reset_query_handler(lv_indev_t * indev) if(indev->proc.reset_query) { indev->proc.act_obj = NULL; indev->proc.last_obj = NULL; - indev->proc.drag_range_out = 0; + indev->proc.drag_limit_out = 0; indev->proc.drag_in_prog = 0; indev->proc.long_pr_sent = 0; indev->proc.pr_timestamp = 0; @@ -868,19 +885,20 @@ static void indev_drag(lv_indev_proc_t * state) state->drag_sum.y += state->vect.y; /*Enough move?*/ - if(state->drag_range_out == 0) { + if(state->drag_limit_out == 0) { /*If a move is greater then LV_DRAG_LIMIT then begin the drag*/ if(LV_MATH_ABS(state->drag_sum.x) >= LV_INDEV_DRAG_LIMIT || LV_MATH_ABS(state->drag_sum.y) >= LV_INDEV_DRAG_LIMIT) { - state->drag_range_out = 1; + state->drag_limit_out = 1; } } - /*If the drag limit is stepped over then handle the dragging*/ - if(state->drag_range_out != 0) { + /*If the drag limit is exceeded handle the dragging*/ + if(state->drag_limit_out != 0) { /*Set new position if the vector is not zero*/ if(state->vect.x != 0 || - state->vect.y != 0) { + state->vect.y != 0) + { /*Get the coordinates of the object and modify them*/ lv_coord_t act_x = lv_obj_get_x(drag_obj); lv_coord_t act_y = lv_obj_get_y(drag_obj); @@ -894,9 +912,8 @@ static void indev_drag(lv_indev_proc_t * state) lv_obj_set_pos(drag_obj, act_x + state->vect.x, act_y + state->vect.y); /*Set the drag in progress flag if the object is really moved*/ - if(drag_obj->coords.x1 != prev_x || drag_obj->coords.y1 != prev_y) { - if(state->drag_range_out != 0) { /*Send the drag begin signal on first move*/ + if(state->drag_in_prog != 0) { /*Send the drag begin signal on first move*/ drag_obj->signal_cb(drag_obj, LV_SIGNAL_DRAG_BEGIN, indev_act); if(state->reset_query != 0) return; } @@ -922,12 +939,13 @@ static void indev_drag(lv_indev_proc_t * state) * Handle throwing by drag if the drag is ended * @param indev pointer to an input device state */ -static void indev_drag_throw(lv_indev_proc_t * state) +static void indev_drag_throw(lv_indev_proc_t * proc) { - if(state->drag_in_prog == 0) return; + if(proc->drag_in_prog == 0) return; /*Set new position if the vector is not zero*/ - lv_obj_t * drag_obj = state->last_obj; + lv_obj_t * drag_obj = proc->last_obj; + /*If drag parent is active check recursively the drag_parent attribute*/ while(lv_obj_get_drag_parent(drag_obj) != false && @@ -935,45 +953,50 @@ static void indev_drag_throw(lv_indev_proc_t * state) drag_obj = lv_obj_get_parent(drag_obj); } - if(drag_obj == NULL) return; + if(drag_obj == NULL) { + return; + } /*Return if the drag throw is not enabled*/ if(lv_obj_get_drag_throw(drag_obj) == false) { - state->drag_in_prog = 0; + proc->drag_in_prog = 0; drag_obj->signal_cb(drag_obj, LV_SIGNAL_DRAG_END, indev_act); return; } /*Reduce the vectors*/ - state->vect.x = state->vect.x * (100 - LV_INDEV_DRAG_THROW) / 100; - state->vect.y = state->vect.y * (100 - LV_INDEV_DRAG_THROW) / 100; + proc->drawg_throw_vect.x = proc->drawg_throw_vect.x * (100 - LV_INDEV_DRAG_THROW) / 100; + proc->drawg_throw_vect.y = proc->drawg_throw_vect.y * (100 - LV_INDEV_DRAG_THROW) / 100; - if(state->vect.x != 0 || - state->vect.y != 0) { + if(proc->drawg_throw_vect.x != 0 || + proc->drawg_throw_vect.y != 0) { /*Get the coordinates and modify them*/ lv_area_t coords_ori; lv_obj_get_coords(drag_obj, &coords_ori); - lv_coord_t act_x = lv_obj_get_x(drag_obj) + state->vect.x; - lv_coord_t act_y = lv_obj_get_y(drag_obj) + state->vect.y; + lv_coord_t act_x = lv_obj_get_x(drag_obj) + proc->drawg_throw_vect.x; + lv_coord_t act_y = lv_obj_get_y(drag_obj) + proc->drawg_throw_vect.y; lv_obj_set_pos(drag_obj, act_x, act_y); lv_area_t coord_new; lv_obj_get_coords(drag_obj, &coord_new); /*If non of the coordinates are changed then do not continue throwing*/ - if((coords_ori.x1 == coord_new.x1 || state->vect.x == 0) && - (coords_ori.y1 == coord_new.y1 || state->vect.y == 0)) { - state->drag_in_prog = 0; - state->vect.x = 0; - state->vect.y = 0; + if((coords_ori.x1 == coord_new.x1 || proc->drawg_throw_vect.x == 0) && + (coords_ori.y1 == coord_new.y1 || proc->drawg_throw_vect.y == 0)) { + proc->drag_in_prog = 0; + proc->vect.x = 0; + proc->vect.y = 0; + proc->drawg_throw_vect.x = 0; + proc->drawg_throw_vect.y = 0; drag_obj->signal_cb(drag_obj, LV_SIGNAL_DRAG_END, indev_act); } } /*If the vectors become 0 -> drag_in_prog = 0 and send a drag end signal*/ else { - state->drag_in_prog = 0; + proc->drag_in_prog = 0; drag_obj->signal_cb(drag_obj, LV_SIGNAL_DRAG_END, indev_act); } + } #endif diff --git a/lv_core/lv_obj.c b/lv_core/lv_obj.c index f94bfc4d7..c8eb0c9c9 100644 --- a/lv_core/lv_obj.c +++ b/lv_core/lv_obj.c @@ -232,7 +232,7 @@ lv_obj_t * lv_obj_create(lv_obj_t * parent, const lv_obj_t * copy) new_obj->style_p = &lv_style_plain_color; } - /*Set virtual functions*/ + /*Set callbacks*/ lv_obj_set_signal_cb(new_obj, lv_obj_signal); lv_obj_set_design_cb(new_obj, lv_obj_design); @@ -1813,11 +1813,15 @@ static bool lv_obj_design(lv_obj_t * obj, const lv_area_t * mask_p, lv_design_m { if(mode == LV_DESIGN_COVER_CHK) { + /*Most trivial test. The mask is fully IN the object? If no it surely not covers it*/ + if(lv_area_is_in(mask_p, &obj->coords) == false) return false; + + /*Can cover the area only if fully solid (no opacity)*/ + lv_style_t * style = lv_obj_get_style(obj); + if(style->body.opa != LV_OPA_COVER) return false; + /* Because of the radius it is not sure the area is covered * Check the areas where there is no radius*/ - lv_style_t * style = lv_obj_get_style(obj); - if(style->body.empty != 0) return false; - uint16_t r = style->body.radius; if(r == LV_RADIUS_CIRCLE) return false; diff --git a/lv_core/lv_style.c b/lv_core/lv_style.c index 02dc011ba..487d2e1f1 100644 --- a/lv_core/lv_style.c +++ b/lv_core/lv_style.c @@ -78,8 +78,8 @@ void lv_style_init(void) lv_style_scr.body.main_color = LV_COLOR_WHITE; lv_style_scr.body.grad_color = LV_COLOR_WHITE; lv_style_scr.body.radius = 0; - lv_style_scr.body.padding.ver = LV_DPI / 12; - lv_style_scr.body.padding.hor = LV_DPI / 12; + lv_style_scr.body.padding.ver = 0; + lv_style_scr.body.padding.hor = 0; lv_style_scr.body.padding.inner = LV_DPI / 12; lv_style_scr.body.border.color = LV_COLOR_BLACK; @@ -108,6 +108,8 @@ void lv_style_init(void) /*Plain style (by default near the same as the screen style)*/ memcpy(&lv_style_plain, &lv_style_scr, sizeof(lv_style_t)); + lv_style_plain.body.padding.hor = LV_DPI / 12; + lv_style_plain.body.padding.ver = LV_DPI / 12; /*Plain color style*/ memcpy(&lv_style_plain_color, &lv_style_plain, sizeof(lv_style_t)); @@ -140,9 +142,9 @@ void lv_style_init(void) /*Transparent style*/ memcpy(&lv_style_transp, &lv_style_plain, sizeof(lv_style_t)); - lv_style_transp.body.empty = 1; lv_style_transp.glass = 1; lv_style_transp.body.border.width = 0; + lv_style_transp.body.opa = LV_OPA_TRANSP; /*Transparent fitting size*/ memcpy(&lv_style_transp_fit, &lv_style_transp, sizeof(lv_style_t)); @@ -252,14 +254,12 @@ void lv_style_mix(const lv_style_t * start, const lv_style_t * end, lv_style_t * res->line.color = lv_color_mix(end->line.color, start->line.color, opa); if(ratio < (STYLE_MIX_MAX >> 1)) { - res->body.empty = start->body.empty; res->body.border.part = start->body.border.part; res->glass = start->glass; res->text.font = start->text.font; res->body.shadow.type = start->body.shadow.type; res->line.rounded = start->line.rounded; } else { - res->body.empty = end->body.empty; res->body.border.part = end->body.border.part; res->glass = end->glass; res->text.font = end->text.font; diff --git a/lv_draw/lv_draw_rect.c b/lv_draw/lv_draw_rect.c index b1d341ad8..7bde1d883 100644 --- a/lv_draw/lv_draw_rect.c +++ b/lv_draw/lv_draw_rect.c @@ -71,7 +71,7 @@ void lv_draw_rect(const lv_area_t * coords, const lv_area_t * mask, const lv_sty lv_draw_shadow(coords, mask, style, opa_scale); } #endif - if(style->body.empty == 0 && style->body.opa >= LV_OPA_MIN) { + if(style->body.opa > LV_OPA_MIN) { lv_draw_rect_main_mid(coords, mask, style, opa_scale); if(style->body.radius != 0) { diff --git a/lv_hal/lv_hal_indev.h b/lv_hal/lv_hal_indev.h index 42cadc6ea..0391fb528 100644 --- a/lv_hal/lv_hal_indev.h +++ b/lv_hal/lv_hal_indev.h @@ -93,11 +93,12 @@ typedef struct _lv_indev_proc_t { lv_point_t last_point; lv_point_t vect; lv_point_t drag_sum; /*Count the dragged pixels to check LV_INDEV_DRAG_LIMIT*/ + lv_point_t drawg_throw_vect; struct _lv_obj_t * act_obj; struct _lv_obj_t * last_obj; /*Flags*/ - uint8_t drag_range_out :1; + uint8_t drag_limit_out :1; uint8_t drag_in_prog :1; uint8_t wait_unil_release :1; }; diff --git a/lv_objx/lv_bar.c b/lv_objx/lv_bar.c index 3f546d795..1cad94963 100644 --- a/lv_objx/lv_bar.c +++ b/lv_objx/lv_bar.c @@ -385,7 +385,7 @@ static bool lv_bar_design(lv_obj_t * bar, const lv_area_t * mask, lv_design_mode lv_style_t * style_bg = lv_bar_get_style(bar, LV_BAR_STYLE_BG); lv_style_t style_tmp; lv_style_copy(&style_tmp, style_bg); - style_tmp.body.empty = 1; + style_tmp.body.opa = LV_OPA_TRANSP; style_tmp.body.shadow.width = 0; lv_draw_rect(&bar->coords, mask, &style_tmp, opa_scale); } diff --git a/lv_objx/lv_cb.c b/lv_objx/lv_cb.c index 248d5f86b..b7b613984 100644 --- a/lv_objx/lv_cb.c +++ b/lv_objx/lv_cb.c @@ -273,13 +273,13 @@ static bool lv_bullet_design(lv_obj_t * bullet, const lv_area_t * mask, lv_desig } else if(mode == LV_DESIGN_DRAW_MAIN) { #if USE_LV_GROUP /* If the check box is the active in a group and - * the background is not visible (transparent or empty) + * the background is not visible (transparent) * then activate the style of the bullet*/ lv_style_t * style_ori = lv_obj_get_style(bullet); lv_obj_t * bg = lv_obj_get_parent(bullet); lv_style_t * style_page = lv_obj_get_style(bg); lv_group_t * g = lv_obj_get_group(bg); - if(style_page->body.empty != 0 || style_page->body.opa == LV_OPA_TRANSP) { /*Background is visible?*/ + if(style_page->body.opa == LV_OPA_TRANSP) { /*Is the Background visible?*/ if(lv_group_get_focused(g) == bg) { lv_style_t * style_mod; style_mod = lv_group_mod_style(g, style_ori); diff --git a/lv_objx/lv_chart.c b/lv_objx/lv_chart.c index 14e21fff0..39e394ac2 100644 --- a/lv_objx/lv_chart.c +++ b/lv_objx/lv_chart.c @@ -674,7 +674,6 @@ static void lv_chart_draw_points(lv_obj_t * chart, const lv_area_t * mask) lv_style_copy(&style_point, &lv_style_plain); style_point.body.border.width = 0; - style_point.body.empty = 0; style_point.body.radius = LV_RADIUS_CIRCLE; style_point.body.opa = ext->series.opa; style_point.body.radius = ext->series.width; @@ -725,7 +724,6 @@ static void lv_chart_draw_cols(lv_obj_t * chart, const lv_area_t * mask) lv_style_copy(&rects, &lv_style_plain); rects.body.border.width = 0; - rects.body.empty = 0; rects.body.radius = 0; rects.body.opa = ext->series.opa; diff --git a/lv_objx/lv_ddlist.c b/lv_objx/lv_ddlist.c index d8e832761..62c95c1be 100644 --- a/lv_objx/lv_ddlist.c +++ b/lv_objx/lv_ddlist.c @@ -93,6 +93,7 @@ lv_obj_t * lv_ddlist_create(lv_obj_t * par, const lv_obj_t * copy) ext->anim_time = LV_DDLIST_ANIM_TIME; ext->sel_style = &lv_style_plain_color; ext->draw_arrow = 0; /*Do not draw arrow by default*/ + ext->stay_open = 1; /*The signal and design functions are not copied so set them here*/ lv_obj_set_signal_cb(new_ddlist, lv_ddlist_signal); @@ -103,7 +104,7 @@ lv_obj_t * lv_ddlist_create(lv_obj_t * par, const lv_obj_t * copy) if(copy == NULL) { lv_obj_t * scrl = lv_page_get_scrl(new_ddlist); lv_obj_set_drag(scrl, false); - lv_page_set_scrl_fit2(new_ddlist, LV_FIT_TIGHT, LV_FIT_TIGHT); + lv_page_set_scrl_fit2(new_ddlist, LV_FIT_FLOOD, LV_FIT_TIGHT); ext->label = lv_label_create(new_ddlist, NULL); lv_cont_set_fit2(new_ddlist, LV_FIT_TIGHT, LV_FIT_NONE); @@ -151,19 +152,6 @@ lv_obj_t * lv_ddlist_create(lv_obj_t * par, const lv_obj_t * copy) * Setter functions *====================*/ -/** - * Set arrow draw in a drop down list - * @param ddlist pointer to drop down list object - * @param en enable/disable a arrow draw. E.g. "true" for draw. - */ -void lv_ddlist_set_draw_arrow(lv_obj_t * ddlist, bool en) -{ - lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist); - - /*Set the flag*/ - ext->draw_arrow = en; -} - /** * Set the options in a drop down list from a string * @param ddlist pointer to drop down list object @@ -226,13 +214,40 @@ void lv_ddlist_set_fix_height(lv_obj_t * ddlist, lv_coord_t h) * @param ddlist pointer to a drop down list * @param fit fit mode fron `lv_fit_t` (Typically `LV_FIT_NONE` or `LV_FIT_TIGHT`) */ -void lv_ddlist_set_hor_fit(lv_obj_t * ddlist, lv_fit_t fit) +void lv_ddlist_set_fit(lv_obj_t * ddlist, lv_fit_t fit) { - lv_cont_set_fit2(ddlist, fit, lv_cont_get_fit_top(ddlist)); + lv_cont_set_fit2(ddlist, fit, LV_FIT_NONE); lv_ddlist_refr_size(ddlist, false); } +/** + * Set arrow draw in a drop down list + * @param ddlist pointer to drop down list object + * @param en enable/disable a arrow draw. E.g. "true" for draw. + */ +void lv_ddlist_set_draw_arrow(lv_obj_t * ddlist, bool en) +{ + lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist); + + /*Set the flag*/ + ext->draw_arrow = en ? 1 : 0; +} + +/** + * Leave the list opened when a new value is selected + * @param ddlist pointer to drop down list object + * @param en enable/disable "stay open" feature + */ +void lv_ddlist_set_stay_open(lv_obj_t * ddlist, bool en) +{ + lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist); + + /*Set the flag*/ + ext->stay_open = en ? 1 : 0; +} + + /** * Set the open/close animation time. * @param ddlist pointer to a drop down list @@ -283,16 +298,6 @@ void lv_ddlist_set_align(lv_obj_t *ddlist, lv_label_align_t align) * Getter functions *====================*/ -/** - * Get arrow draw in a drop down list - * @param ddlist pointer to drop down list object - */ -bool lv_ddlist_get_draw_arrow(lv_obj_t * ddlist) -{ - lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist); - - return ext->draw_arrow; -} /** * Get the options of a drop down list @@ -353,6 +358,28 @@ lv_coord_t lv_ddlist_get_fix_height(const lv_obj_t * ddlist) return ext->fix_height; } +/** + * Get arrow draw in a drop down list + * @param ddlist pointer to drop down list object + */ +bool lv_ddlist_get_draw_arrow(lv_obj_t * ddlist) +{ + lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist); + + return ext->draw_arrow ? true : false; +} + +/** + * Get whether the drop down list stay open after selecting a value or not + * @param ddlist pointer to drop down list object + */ +bool lv_ddlist_get_stay_open(lv_obj_t * ddlist) +{ + lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist); + + return ext->stay_open ? true : false; +} + /** * Get the open/close animation time. * @param ddlist pointer to a drop down list @@ -720,7 +747,9 @@ static lv_res_t lv_ddlist_scrl_signal(lv_obj_t * scrl, lv_signal_t sign, void * if(scrl->ext_size < style->body.padding.hor) scrl->ext_size = style->body.padding.hor; } else if(sign == LV_SIGNAL_RELEASED) { - release_handler(ddlist); + if(lv_indev_is_dragging(lv_indev_get_act()) == false) { + release_handler(ddlist); + } } else if(sign == LV_SIGNAL_CLEANUP) { lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist); @@ -742,9 +771,8 @@ static lv_res_t release_handler(lv_obj_t * ddlist) if(ext->opened == 0) { /*Open the list*/ ext->opened = 1; lv_obj_set_drag(lv_page_get_scrl(ddlist), true); + lv_ddlist_refr_size(ddlist, true); } else { - ext->opened = 0; - lv_obj_set_drag(lv_page_get_scrl(ddlist), false); /*Search the clicked option*/ lv_indev_t * indev = lv_indev_get_act(); @@ -768,8 +796,15 @@ static lv_res_t release_handler(lv_obj_t * ddlist) ext->sel_opt_id = new_opt; lv_obj_send_event(ddlist, LV_EVENT_VALUE_CHANGED); + + if(ext->stay_open == 0) { + ext->opened = 0; + lv_obj_set_drag(lv_page_get_scrl(ddlist), false); + lv_ddlist_refr_size(ddlist, true); + } else { + lv_obj_invalidate(ddlist); + } } - lv_ddlist_refr_size(ddlist, true); return LV_RES_OK; diff --git a/lv_objx/lv_ddlist.h b/lv_objx/lv_ddlist.h index 0f143ecce..5e5c6e60c 100644 --- a/lv_objx/lv_ddlist.h +++ b/lv_objx/lv_ddlist.h @@ -54,7 +54,7 @@ typedef struct uint16_t anim_time; /*Open/Close animation time [ms]*/ uint8_t opened :1; /*1: The list is opened (handled by the library)*/ uint8_t draw_arrow :1; /*1: Draw arrow*/ - + uint8_t stay_open :1; /*1: Don't close the list when a new item is selected*/ lv_coord_t fix_height; /*Height of the ddlist when opened. (0: auto-size)*/ } lv_ddlist_ext_t; @@ -80,13 +80,6 @@ lv_obj_t * lv_ddlist_create(lv_obj_t * par, const lv_obj_t * copy); * Setter functions *====================*/ -/** - * Set arrow draw in a drop down list - * @param ddlist pointer to drop down list object - * @param en enable/disable a arrow draw. E.g. "true" for draw. - */ -void lv_ddlist_set_draw_arrow(lv_obj_t * ddlist, bool en); - /** * Set the options in a drop down list from a string * @param ddlist pointer to drop down list object @@ -115,7 +108,21 @@ void lv_ddlist_set_fix_height(lv_obj_t * ddlist, lv_coord_t h); * @param ddlist pointer to a drop down list * @param fit fit mode fron `lv_fit_t` (Typically `LV_FIT_NONE` or `LV_FIT_TIGHT`) */ -void lv_ddlist_set_hor_fit(lv_obj_t * ddlist, lv_fit_t fit); +void lv_ddlist_set_fit(lv_obj_t * ddlist, lv_fit_t fit); + +/** + * Set arrow draw in a drop down list + * @param ddlist pointer to drop down list object + * @param en enable/disable a arrow draw. E.g. "true" for draw. + */ +void lv_ddlist_set_draw_arrow(lv_obj_t * ddlist, bool en); + +/** + * Leave the list opened when a new value is selected + * @param ddlist pointer to drop down list object + * @param en enable/disable "stay open" feature + */ +void lv_ddlist_set_stay_open(lv_obj_t * ddlist, bool en); /** * Set the scroll bar mode of a drop down list @@ -154,11 +161,6 @@ void lv_ddlist_set_align(lv_obj_t *ddlist, lv_label_align_t align); * Getter functions *====================*/ -/** - * Get arrow draw in a drop down list - * @param ddlist pointer to drop down list object - */ -bool lv_ddlist_get_draw_arrow(lv_obj_t * ddlist); /** * Get the options of a drop down list @@ -189,6 +191,18 @@ void lv_ddlist_get_selected_str(const lv_obj_t * ddlist, char * buf); */ lv_coord_t lv_ddlist_get_fix_height(const lv_obj_t * ddlist); +/** + * Get arrow draw in a drop down list + * @param ddlist pointer to drop down list object + */ +bool lv_ddlist_get_draw_arrow(lv_obj_t * ddlist); + +/** + * Get whether the drop down list stay open after selecting a value or not + * @param ddlist pointer to drop down list object + */ +bool lv_ddlist_get_stay_open(lv_obj_t * ddlist); + /** * Get the scroll bar mode of a drop down list * @param ddlist pointer to a drop down list object diff --git a/lv_objx/lv_page.c b/lv_objx/lv_page.c index c714c9873..147a9319e 100644 --- a/lv_objx/lv_page.c +++ b/lv_objx/lv_page.c @@ -585,12 +585,12 @@ static bool lv_page_design(lv_obj_t * page, const lv_area_t * mask, lv_design_mo /*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; + lv_opa_t opa_tmp = style->body.opa; style->body.shadow.width = 0; - style->body.empty = 1; + style->body.opa = LV_OPA_TRANSP; lv_draw_rect(&page->coords, mask, style, lv_obj_get_opa_scale(page)); style->body.shadow.width = shadow_width_tmp; - style->body.empty = empty_tmp; + style->body.opa = opa_tmp; lv_page_ext_t * ext = lv_obj_get_ext_attr(page); @@ -677,16 +677,24 @@ static bool lv_scrl_design(lv_obj_t * scrl, const lv_area_t * mask, lv_design_mo } else if(mode == LV_DESIGN_DRAW_MAIN) { #if USE_LV_GROUP /* If the page is focused in a group and - * the background object is not visible (transparent or empty) + * the background object is not visible (transparent) * then "activate" the style of the scrollable*/ lv_style_t * style_scrl_ori = lv_obj_get_style(scrl); lv_obj_t * page = lv_obj_get_parent(scrl); lv_style_t * style_page = lv_obj_get_style(page); lv_group_t * g = lv_obj_get_group(page); - if((style_page->body.empty || style_page->body.opa == LV_OPA_TRANSP) && style_page->body.border.width == 0) { /*Is the background visible?*/ + if((style_page->body.opa == LV_OPA_TRANSP) && style_page->body.border.width == 0) { /*Is the background visible?*/ if(lv_group_get_focused(g) == page) { lv_style_t * style_mod; style_mod = lv_group_mod_style(g, style_scrl_ori); + /*If still not visible modify the style a littel bit*/ + if((style_mod->body.opa == LV_OPA_TRANSP) && style_mod->body.border.width == 0) { + style_mod->body.opa = LV_OPA_50; + style_mod->body.border.width = 1; + style_mod = lv_group_mod_style(g, style_mod); + } + + scrl->style_p = style_mod; /*Temporally change the style to the activated */ } } @@ -729,10 +737,10 @@ static lv_res_t lv_page_signal(lv_obj_t * page, lv_signal_t sign, void * param) /*Reposition the child to take padding into account*/ lv_style_t * style = lv_page_get_style(page, LV_PAGE_STYLE_SCRL); - child->coords.x1 += style->body.padding.hor; - child->coords.x2 += style->body.padding.hor; - child->coords.y1 += style->body.padding.ver; - child->coords.y2 += style->body.padding.ver; + tmp->coords.x1 += style->body.padding.hor; + tmp->coords.x2 += style->body.padding.hor; + tmp->coords.y1 += style->body.padding.ver; + tmp->coords.y2 += style->body.padding.ver; lv_obj_set_parent(tmp, ext->scrl); } else { diff --git a/lv_objx/lv_roller.c b/lv_objx/lv_roller.c index 81d404432..4a6f41dd6 100644 --- a/lv_objx/lv_roller.c +++ b/lv_objx/lv_roller.c @@ -87,6 +87,7 @@ lv_obj_t * lv_roller_create(lv_obj_t * par, const lv_obj_t * copy) lv_page_set_scrl_fit2(new_roller, LV_FIT_TIGHT, LV_FIT_NONE); /*Height is specified directly*/ lv_ddlist_open(new_roller, false); lv_ddlist_set_anim_time(new_roller, LV_ROLLER_ANIM_TIME); + lv_ddlist_set_stay_open(new_roller, true); lv_roller_set_visible_row_count(new_roller, 3); lv_label_set_align(ext->ddlist.label, LV_LABEL_ALIGN_CENTER); diff --git a/lv_objx/lv_roller.h b/lv_objx/lv_roller.h index a4c268256..40fce4a62 100644 --- a/lv_objx/lv_roller.h +++ b/lv_objx/lv_roller.h @@ -104,7 +104,7 @@ void lv_roller_set_visible_row_count(lv_obj_t *roller, uint8_t row_cnt); */ static inline void lv_roller_set_hor_fit(lv_obj_t * roller, bool en) { - lv_ddlist_set_hor_fit(roller, en); + lv_ddlist_set_fit(roller, en); } /** diff --git a/lv_objx/lv_spinbox.c b/lv_objx/lv_spinbox.c index 27df3e7d5..7a237f533 100644 --- a/lv_objx/lv_spinbox.c +++ b/lv_objx/lv_spinbox.c @@ -63,8 +63,6 @@ lv_obj_t * lv_spinbox_create(lv_obj_t * par, const lv_obj_t * copy) if(ancestor_design == NULL) ancestor_design = lv_obj_get_design_func(new_spinbox); /*Initialize the allocated 'ext'*/ - ext->ta.one_line = 1; - ext->ta.pwd_mode = 0; ext->ta.accapted_chars = "1234567890+-. "; ext->value = 0; @@ -77,6 +75,7 @@ lv_obj_t * lv_spinbox_create(lv_obj_t * par, const lv_obj_t * copy) ext->value_changed_cb = NULL; lv_ta_set_cursor_type(new_spinbox, LV_CURSOR_BLOCK | LV_CURSOR_HIDDEN); /*hidden by default*/ + lv_ta_set_one_line(new_spinbox, true); /*The signal and design functions are not copied so set them here*/ lv_obj_set_signal_cb(new_spinbox, lv_spinbox_signal); diff --git a/lv_objx/lv_tabview.c b/lv_objx/lv_tabview.c index 51e9f0f6d..bf6fdae09 100644 --- a/lv_objx/lv_tabview.c +++ b/lv_objx/lv_tabview.c @@ -106,8 +106,7 @@ lv_obj_t * lv_tabview_create(lv_obj_t * par, const lv_obj_t * copy) ext->tab_name_ptr[0] = ""; ext->tab_cnt = 0; - lv_disp_t * disp = lv_obj_get_disp(new_tabview); - lv_obj_set_size(new_tabview, lv_disp_get_hor_res(disp), lv_disp_get_ver_res(disp)); + lv_obj_set_size(new_tabview, LV_DPI * 3, LV_DPI * 2); ext->btns = lv_btnm_create(new_tabview, NULL); lv_obj_set_height(ext->btns, 3 * LV_DPI / 4); diff --git a/lv_objx/lv_win.c b/lv_objx/lv_win.c index 29945619b..65272f09c 100644 --- a/lv_objx/lv_win.c +++ b/lv_objx/lv_win.c @@ -105,7 +105,7 @@ lv_obj_t * lv_win_create(lv_obj_t * par, const lv_obj_t * copy) lv_win_set_style(new_win, LV_WIN_STYLE_BTN_PR, th->style.win.btn.pr); } else { lv_win_set_style(new_win, LV_WIN_STYLE_BG, &lv_style_plain); - lv_win_set_style(new_win, LV_WIN_STYLE_CONTENT_BG, &lv_style_plain); + lv_win_set_style(new_win, LV_WIN_STYLE_CONTENT_BG, &lv_style_transp_fit); lv_win_set_style(new_win, LV_WIN_STYLE_CONTENT_SCRL, &lv_style_transp); lv_win_set_style(new_win, LV_WIN_STYLE_HEADER, &lv_style_plain_color); } @@ -133,11 +133,11 @@ lv_obj_t * lv_win_create(lv_obj_t * par, const lv_obj_t * copy) } lv_obj_set_signal_cb(new_win, lv_win_signal); - - /*Refresh the style with new signal function*/ - lv_obj_refresh_style(new_win); } + /*Refresh the style with new signal function*/ + lv_obj_refresh_style(new_win); + lv_win_realign(new_win); LV_LOG_INFO("window created");