diff --git a/lvgl.h b/lvgl.h index 0747c4ff0..a4caf7309 100644 --- a/lvgl.h +++ b/lvgl.h @@ -32,6 +32,8 @@ extern "C" { #include "src/lv_core/lv_obj.h" #include "src/lv_core/lv_group.h" #include "src/lv_core/lv_indev.h" +#include "src/lv_core/lv_flex.h" +#include "src/lv_core/lv_grid.h" #include "src/lv_core/lv_refr.h" #include "src/lv_core/lv_disp.h" @@ -43,6 +45,7 @@ extern "C" { #include "src/lv_font/lv_font_fmt_txt.h" #include "src/lv_misc/lv_printf.h" +#include "src/lv_widgets/lv_arc.h" #include "src/lv_widgets/lv_btn.h" #include "src/lv_widgets/lv_imgbtn.h" #include "src/lv_widgets/lv_img.h" @@ -60,7 +63,6 @@ extern "C" { #include "src/lv_widgets/lv_canvas.h" #include "src/lv_widgets/lv_meter.h" #include "src/lv_widgets/lv_switch.h" -#include "src/lv_widgets/lv_arc.h" #include "src/lv_draw/lv_img_cache.h" diff --git a/scripts/style_api_gen.py b/scripts/style_api_gen.py index 04501be9f..aef41446f 100755 --- a/scripts/style_api_gen.py +++ b/scripts/style_api_gen.py @@ -9,7 +9,7 @@ props = [ {'name': 'COLOR_FILTER_CB', 'style_type': 'func', 'var_type': 'lv_color_filter_cb_t' }, {'name': 'COLOR_FILTER_OPA', 'style_type': 'num', 'var_type': 'lv_opa_t' }, {'name': 'ANIM_TIME', 'style_type': 'num', 'var_type': 'uint32_t' }, -{'name': 'TRANSITION', 'style_type': 'ptr', 'var_type': 'const lv_style_transition_t *' }, +{'name': 'TRANSITION', 'style_type': 'ptr', 'var_type': 'const lv_style_transition_dsc_t *' }, {'name': 'SIZE', 'style_type': 'num', 'var_type': 'lv_coord_t' }, {'name': 'BLEND_MODE', 'style_type': 'num', 'var_type': 'lv_blend_mode_t' }, {'name': 'PAD_TOP', 'style_type': 'num', 'var_type': 'lv_coord_t' }, @@ -90,13 +90,17 @@ def obj_style_get(i): def style_set(i): print("static inline void lv_style_set_" + props[i]['name'].lower() +"(lv_style_t * style, "+ props[i]['var_type'] +" value) {") - print(" lv_style_value_t v = {." + props[i][ 'style_type'] +" = value}; lv_style_set_prop(style, LV_STYLE_" + props[i]['name'] +", v); }") + print(" lv_style_value_t v = {." + props[i]['style_type'] +" = value}; lv_style_set_prop(style, LV_STYLE_" + props[i]['name'] +", v); }") print("") +def local_style_set(i): + print("static inline void lv_obj_set_style_" + props[i]['name'].lower() + "(struct _lv_obj_t * obj, uint32_t part, uint32_t state, " + props[i]['var_type'] +" value) {") + print(" lv_style_value_t v = {." + props[i]['style_type'] +" = value}; lv_obj_set_local_style_prop(obj, part, state, LV_STYLE_" + props[i]['name'] +", v); }") + print("") for i in range(len(props)): - style_set(i) + local_style_set(i) diff --git a/src/lv_core/lv_flex.c b/src/lv_core/lv_flex.c index 650e9ad26..1bc061b23 100644 --- a/src/lv_core/lv_flex.c +++ b/src/lv_core/lv_flex.c @@ -41,20 +41,29 @@ static lv_obj_t * get_next_item(lv_obj_t * cont, bool rev, int32_t * item_id); /********************** * GLOBAL VARIABLES **********************/ -const lv_flex_t lv_flex_center = { +const lv_flex_t lv_flex_center_row = { .base.update_cb = flex_update, .item_main_place = LV_FLEX_PLACE_CENTER, .item_cross_place = LV_FLEX_PLACE_CENTER, - .track_place = LV_FLEX_PLACE_CENTER, + .track_cross_place = LV_FLEX_PLACE_CENTER, .dir = LV_FLEX_FLOW_ROW, .wrap = 1 }; +const lv_flex_t lv_flex_center_column = { + .base.update_cb = flex_update, + .item_main_place = LV_FLEX_PLACE_CENTER, + .item_cross_place = LV_FLEX_PLACE_CENTER, + .track_cross_place = LV_FLEX_PLACE_CENTER, + .dir = LV_FLEX_FLOW_COLUMN, + .wrap = 1 +}; + const lv_flex_t lv_flex_stacked = { .base.update_cb = flex_update, .item_main_place = LV_FLEX_PLACE_START, .item_cross_place = LV_FLEX_PLACE_START, - .track_place = LV_FLEX_PLACE_START, + .track_cross_place = LV_FLEX_PLACE_START, .dir = LV_FLEX_FLOW_COLUMN }; @@ -62,7 +71,7 @@ const lv_flex_t lv_flex_even = { .base.update_cb = flex_update, .item_main_place = LV_FLEX_PLACE_SPACE_EVENLY, .item_cross_place = LV_FLEX_PLACE_CENTER, - .track_place = LV_FLEX_PLACE_CENTER, + .track_cross_place = LV_FLEX_PLACE_CENTER, .dir = LV_FLEX_FLOW_ROW, .wrap = 1 }; @@ -89,7 +98,7 @@ void lv_flex_init(lv_flex_t * flex) flex->base.update_cb = flex_update; flex->dir = LV_FLEX_FLOW_ROW; flex->item_main_place = LV_FLEX_PLACE_START; - flex->track_place = LV_FLEX_PLACE_START; + flex->track_cross_place = LV_FLEX_PLACE_START; flex->item_cross_place = LV_FLEX_PLACE_START; } @@ -100,10 +109,10 @@ void lv_flex_set_flow(lv_flex_t * flex, lv_flex_flow_t flow) flex->rev = flow & _LV_FLEX_REVERSE ? 1 : 0; } -void lv_flex_set_place(lv_flex_t * flex, lv_flex_place_t item_main_place, lv_flex_place_t item_cross_place, lv_flex_place_t track_place) +void lv_flex_set_place(lv_flex_t * flex, lv_flex_place_t item_main_place, lv_flex_place_t item_cross_place, lv_flex_place_t track_cross_place) { flex->item_main_place = item_main_place; - flex->track_place = track_place; + flex->track_cross_place = track_cross_place; flex->item_cross_place = item_cross_place; } @@ -136,7 +145,7 @@ static void flex_update(lv_obj_t * cont, lv_obj_t * item) lv_coord_t abs_y = cont->coords.y1 + lv_obj_get_style_pad_top(cont, LV_PART_MAIN) - lv_obj_get_scroll_y(cont); lv_coord_t abs_x = cont->coords.x1 + lv_obj_get_style_pad_left(cont, LV_PART_MAIN) - lv_obj_get_scroll_x(cont); - lv_flex_place_t cross_place = f->track_place; + lv_flex_place_t cross_place = f->track_cross_place; lv_coord_t * cross_pos = (row ? &abs_y : &abs_x); if((row && cont->h_set == LV_SIZE_AUTO) || diff --git a/src/lv_core/lv_flex.h b/src/lv_core/lv_flex.h index 66b02de0d..ce3e1005a 100644 --- a/src/lv_core/lv_flex.h +++ b/src/lv_core/lv_flex.h @@ -57,7 +57,7 @@ typedef struct { uint32_t wrap :1; uint32_t rev :1; uint32_t item_main_place :3; - uint32_t track_place :3; + uint32_t track_cross_place :3; uint32_t item_cross_place :3; }lv_flex_t; @@ -85,7 +85,7 @@ void lv_flex_set_flow(lv_flex_t * flex, lv_flex_flow_t flow); * @param item_cross_place: where to place the item in their track on the cross axis. `LV_FLEX_PLACE_START/END/CENTER` * @param track_place: how to place the tracks in the cross direction. Any value of `lv_flex_place_t`. */ -void lv_flex_set_place(lv_flex_t * flex, lv_flex_place_t item_main_place, lv_flex_place_t item_cross_place, lv_flex_place_t track_place); +void lv_flex_set_place(lv_flex_t * flex, lv_flex_place_t item_main_place, lv_flex_place_t item_cross_place, lv_flex_place_t track_cross_place); /** * Sets the width or height (on main axis) to grow the object in order fill the free space @@ -101,7 +101,8 @@ void lv_obj_set_flex_grow(struct _lv_obj_t * obj, uint8_t grow); /** * Predefines flex layouts */ -extern const lv_flex_t lv_flex_center; /**< Center in a row with wrap*/ +extern const lv_flex_t lv_flex_center_row; /**< Center in a row with wrap*/ +extern const lv_flex_t lv_flex_center_column; /**< Center in a column with wrap*/ extern const lv_flex_t lv_flex_stacked; /**< Stack the items vertically*/ extern const lv_flex_t lv_flex_even; /**< Place the items evenly in row with wrapping and vertical centering*/ diff --git a/src/lv_core/lv_obj.c b/src/lv_core/lv_obj.c index faf331387..913d280f3 100644 --- a/src/lv_core/lv_obj.c +++ b/src/lv_core/lv_obj.c @@ -348,7 +348,7 @@ void lv_obj_set_state(lv_obj_t * obj, lv_state_t new_state) for(j = 0; tr->props[j] != 0 && tsi < STYLE_TRANSITION_MAX; j++) { uint32_t t; for(t = 0; t < tsi; t++) { - if(ts[t].prop == tr->props[j] && ts[t].state > obj_style->state) break; + if(ts[t].prop == tr->props[j] && ts[t].state >= obj_style->state) break; } /*If not found add it*/ @@ -395,7 +395,7 @@ void lv_obj_clear_state(lv_obj_t * obj, lv_state_t state) } } -void lv_obj_set_event_cb(lv_obj_t * obj, lv_event_cb_t event_cb) +void lv_obj_add_event_cb(lv_obj_t * obj, lv_event_cb_t event_cb) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); lv_obj_allocate_spec_attr(obj); @@ -466,7 +466,15 @@ lv_state_t lv_obj_get_state(const lv_obj_t * obj) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); - return ((lv_obj_t *)obj)->state; + return obj->state; +} + + +bool lv_obj_has_state(const lv_obj_t * obj, lv_state_t state) +{ + LV_ASSERT_OBJ(obj, LV_OBJX_NAME); + + return obj->state & state ? true : false; } lv_event_cb_t lv_obj_get_event_cb(const lv_obj_t * obj, uint32_t id) diff --git a/src/lv_core/lv_obj.h b/src/lv_core/lv_obj.h index 861c6846c..2aac5319a 100644 --- a/src/lv_core/lv_obj.h +++ b/src/lv_core/lv_obj.h @@ -82,10 +82,10 @@ typedef enum { LV_EVENT_DELETE, /**< Object is being deleted */ LV_EVENT_COVER_CHECK, /**< Check if the object fully covers the 'mask_p' area */ - LV_EVENT_REFR_EXT_SIZE, /**< Draw extras on the object */ + LV_EVENT_REFR_EXT_DRAW_SIZE, /**< Draw extras on the object */ LV_EVENT_DRAW_MAIN_BEGIN, - LV_EVENT_DRAW_MAIN_FINISH, + LV_EVENT_DRAW_MAIN_END, LV_EVENT_DRAW_POST_BEGIN, LV_EVENT_DRAW_POST_END, LV_EVENT_DRAW_PART_BEGIN, @@ -162,6 +162,7 @@ enum { LV_STATE_PRESSED = 0x20, LV_STATE_SCROLLED = 0x40, LV_STATE_DISABLED = 0x80, + _LV_STATE_RESERVED = 0x80, LV_STATE_ANY = 0x1FF, /**< Special value can be used in some functions to target all states */ }; @@ -329,9 +330,9 @@ void lv_deinit(void); /** * Create a base object (a rectangle) - * @param parent: pointer to a parent object. If NULL then a screen will be created. - * @param copy: DEPRECATED, will be removed in v9. - * Pointer to an other base object to copy. + * @param parent pointer to a parent object. If NULL then a screen will be created. + * @param copy DEPRECATED, will be removed in v9. + * Pointer to an other base object to copy. * @return pointer to the new object */ lv_obj_t * lv_obj_create(lv_obj_t * parent, const lv_obj_t * copy); @@ -352,14 +353,14 @@ lv_res_t lv_event_send(lv_obj_t * obj, lv_event_t event, void * data); /** * Get the `data` parameter of the current event - * @return the `data` parameter + * @return the `data` parameter */ void * lv_event_get_data(void); /** * Register a new, custom event ID. * It can be used the same way as e.g. `LV_EVENT_CLICKED` to send custom events - * @return the new event id + * @return the new event id * @example * uint32_t LV_EVENT_MINE = 0; * ... @@ -371,8 +372,8 @@ uint32_t lv_event_register_id(void); /** * Send an event to the object - * @param obj pointer to an object - * @param event the type of the event from `lv_event_t`. + * @param obj pointer to an object + * @param event the type of the event from `lv_event_t`. * @return LV_RES_OK or LV_RES_INV */ lv_res_t lv_signal_send(lv_obj_t * obj, lv_signal_t signal, void * param); @@ -381,26 +382,25 @@ lv_res_t lv_signal_send(lv_obj_t * obj, lv_signal_t signal, void * param); * Setter functions *====================*/ - /** * Set one or more flags - * @param obj: pointer to an object - * @param f: OR-ed values from `lv_obj_flag_t` to set. + * @param obj pointer to an object + * @param f R-ed values from `lv_obj_flag_t` to set. */ void lv_obj_add_flag(lv_obj_t * obj, lv_obj_flag_t f); /** * Clear one or more flags - * @param obj: pointer to an object - * @param f: OR-ed values from `lv_obj_flag_t` to set. + * @param obj pointer to an object + * @param f OR-ed values from `lv_obj_flag_t` to set. */ void lv_obj_clear_flag(lv_obj_t * obj, lv_obj_flag_t f); /** * Set the state (fully overwrite) of an object. * If specified in the styles, transition animations will be started from the previous state to the current. - * @param obj: pointer to an object - * @param state: the new state + * @param obj pointer to an object + * @param state the new state */ void lv_obj_set_state(lv_obj_t * obj, lv_state_t new_state); @@ -408,31 +408,32 @@ void lv_obj_set_state(lv_obj_t * obj, lv_state_t new_state); /** * Add one or more states to the object. The other state bits will remain unchanged. * If specified in the styles, transition animation will be started from the previous state to the current. - * @param obj: pointer to an object - * @param state: the states to add. E.g `LV_STATE_PRESSED | LV_STATE_FOCUSED` + * @param obj pointer to an object + * @param state the states to add. E.g `LV_STATE_PRESSED | LV_STATE_FOCUSED` */ void lv_obj_add_state(lv_obj_t * obj, lv_state_t state); /** * Remove one or more states to the object. The other state bits will remain unchanged. * If specified in the styles, transition animation will be started from the previous state to the current. - * @param obj: pointer to an object - * @param state: the states to add. E.g `LV_STATE_PRESSED | LV_STATE_FOCUSED` + * @param obj pointer to an object + * @param state the states to add. E.g `LV_STATE_PRESSED | LV_STATE_FOCUSED` */ void lv_obj_clear_state(lv_obj_t * obj, lv_state_t state); /** - * Set a an event handler function for an object. + * Add a an event handler function for an object. * Used by the user to react on event which happens with the object. - * @param obj pointer to an object - * @param event_cb the new event function + * An object can have multiple event handler. They will be called in the same the order as they were added. + * @param obj pointer to an object + * @param event_cb the new event function */ -void lv_obj_set_event_cb(lv_obj_t * obj, lv_event_cb_t event_cb); +void lv_obj_add_event_cb(lv_obj_t * obj, lv_event_cb_t event_cb); /** * Set the base direction of the object - * @param obj pointer to an object - * @param dir the new base direction. `LV_BIDI_DIR_LTR/RTL/AUTO/INHERIT` + * @param obj pointer to an object + * @param dir the new base direction. `LV_BIDI_DIR_LTR/RTL/AUTO/INHERIT` */ void lv_obj_set_base_dir(lv_obj_t * obj, lv_bidi_dir_t dir); @@ -443,38 +444,46 @@ void lv_obj_set_base_dir(lv_obj_t * obj, lv_bidi_dir_t dir); /** * Check if a given flag or flags are set on an object. - * @param obj pointer to an object - * @param f the flag(s) to check (OR-ed values can be used) - * @return true: all flags are set; false: not all flags are set + * @param obj pointer to an object + * @param f the flag(s) to check (OR-ed values can be used) + * @return true: all flags are set; false: not all flags are set */ bool lv_obj_has_flag(const lv_obj_t * obj, lv_obj_flag_t f); /** * Get the base direction of the object - * @param obj pointer to an object - * @return the base direction. `LV_BIDI_DIR_LTR/RTL/AUTO/INHERIT` + * @param obj pointer to an object + * @return the base direction. `LV_BIDI_DIR_LTR/RTL/AUTO/INHERIT` */ lv_bidi_dir_t lv_obj_get_base_dir(const lv_obj_t * obj); /** * Get the state of an object - * @param obj pointer to an object - * @return the state (OR-ed values from `lv_state_t`) + * @param obj pointer to an object + * @return the state (OR-ed values from `lv_state_t`) */ lv_state_t lv_obj_get_state(const lv_obj_t * obj); +/** + * Check if the object is in a given state or not. + * @param obj pointer to an object + * @param state a state or combination of states to check + * @return true: `obj` is in `state`; false: `obj` is not in `state` + */ +bool lv_obj_has_state(const lv_obj_t * obj, lv_state_t state); + /** * Get the event function of an object - * @param obj: pointer to an object - * @param id: the index of the event callback. 0: the firstly added - * @return the event function + * @param obj pointer to an object + * @param id the index of the event callback. 0: the firstly added + * @return the event function */ lv_event_cb_t lv_obj_get_event_cb(const lv_obj_t * obj, uint32_t id); /** * Get the group of the object - * @param obj pointer to an object - * @return the pointer to group of the object + * @param obj pointer to an object + * @return the pointer to group of the object */ void * lv_obj_get_group(const lv_obj_t * obj); @@ -484,38 +493,38 @@ void * lv_obj_get_group(const lv_obj_t * obj); /** * Allocate special data for an object if not allocated yet. - * @param obj pointer to an object + * @param obj pointer to an object */ void lv_obj_allocate_spec_attr(lv_obj_t * obj); /** * Get the focused object by taking `LV_OBJ_FLAG_FOCUS_BUBBLE` into account. - * @param obj the start object - * @return the object to to really focus + * @param obj the start object + * @return the object to to really focus */ lv_obj_t * lv_obj_get_focused_obj(const lv_obj_t * obj); /** * Get object's and its ancestors type. Put their name in `type_buf` starting with the current type. * E.g. buf.type[0]="lv_btn", buf.type[1]="lv_cont", buf.type[2]="lv_obj" - * @param obj pointer to an object which type should be get - * @param buf pointer to an `lv_obj_type_t` buffer to store the types + * @param obj pointer to an object which type should be get + * @param buf pointer to an `lv_obj_type_t` buffer to store the types */ bool lv_obj_check_type(const lv_obj_t * obj, const void * class_p); /** * Check if any object has a given type - * @param obj pointer to an object - * @param obj_type type of the object. (e.g. "lv_btn") - * @return true: valid + * @param obj pointer to an object + * @param obj_type type of the object. (e.g. "lv_btn") + * @return true: valid */ bool _lv_debug_check_obj_type(const lv_obj_t * obj, const char * obj_type); /** * Check if any object is still "alive", and part of the hierarchy - * @param obj pointer to an object - * @param obj_type type of the object. (e.g. "lv_btn") - * @return true: valid + * @param obj pointer to an object + * @param obj_type type of the object. (e.g. "lv_btn") + * @return true: valid */ bool _lv_debug_check_obj_valid(const lv_obj_t * obj); diff --git a/src/lv_core/lv_obj_draw.c b/src/lv_core/lv_obj_draw.c index 44262187a..95eb121a3 100644 --- a/src/lv_core/lv_obj_draw.c +++ b/src/lv_core/lv_obj_draw.c @@ -223,17 +223,10 @@ void lv_obj_init_draw_label_dsc(lv_obj_t * obj, uint8_t part, lv_draw_label_dsc_ draw_dsc->bidi_dir = lv_obj_get_base_dir(obj); #endif - lv_text_align_t align = lv_obj_get_style_text_align(obj, part); - switch (align) { - case LV_TEXT_ALIGN_CENTER: - draw_dsc->flag |= LV_TEXT_FLAG_CENTER; - break; - case LV_TEXT_ALIGN_RIGHT: - draw_dsc->flag |= LV_TEXT_FLAG_RIGHT; - break; - case LV_TEXT_ALIGN_AUTO: - draw_dsc->flag |= draw_dsc->bidi_dir == LV_BIDI_DIR_RTL ? LV_TEXT_FLAG_RIGHT : LV_TEXT_FLAG_CENTER; - break; + draw_dsc->align = lv_obj_get_style_text_align(obj, part); + if(draw_dsc->align == LV_TEXT_ALIGN_AUTO) { + if(draw_dsc->bidi_dir == LV_BIDI_DIR_RTL) draw_dsc->align = LV_TEXT_ALIGN_RIGHT; + draw_dsc->align = LV_TEXT_ALIGN_LEFT; } } @@ -356,7 +349,7 @@ lv_coord_t lv_obj_calculate_ext_draw_size(lv_obj_t * obj, uint8_t part) lv_coord_t letter_space = lv_obj_get_style_text_letter_space(obj, part); lv_coord_t line_space = lv_obj_get_style_text_letter_space(obj, part); const lv_font_t * font = lv_obj_get_style_text_font(obj, part); - _lv_txt_get_size(&content_size, content_text, font, letter_space, line_space, LV_COORD_MAX, LV_TEXT_FLAG_NONE); + lv_txt_get_size(&content_size, content_text, font, letter_space, line_space, LV_COORD_MAX, LV_TEXT_FLAG_NONE); lv_area_t content_area; content_area.x1 = 0; @@ -403,6 +396,7 @@ void lv_obj_refresh_ext_draw_size(lv_obj_t * obj) lv_coord_t s_old = _lv_obj_get_ext_draw_size(obj); lv_coord_t s_new = 0; lv_signal_send(obj, LV_SIGNAL_REFR_EXT_DRAW_SIZE, &s_new); + lv_event_send(obj, LV_EVENT_REFR_EXT_DRAW_SIZE, &s_new); if(s_new != s_old) lv_obj_invalidate(obj); diff --git a/src/lv_core/lv_obj_draw.h b/src/lv_core/lv_obj_draw.h index dd7a579f7..b8cab00a3 100644 --- a/src/lv_core/lv_obj_draw.h +++ b/src/lv_core/lv_obj_draw.h @@ -36,19 +36,22 @@ typedef enum { typedef struct { + const lv_area_t * draw_area; + const lv_area_t * clip_area; lv_draw_rect_dsc_t * rect_dsc; lv_draw_label_dsc_t * label_dsc; lv_draw_line_dsc_t * line_dsc; lv_draw_img_dsc_t * img_dsc; lv_draw_arc_dsc_t * arc_dsc; - char text[16]; - const lv_area_t * draw_area; const lv_point_t * p1; const lv_point_t * p2; const lv_coord_t * radius; - const lv_area_t * clip_area; + char text[16]; uint32_t id; - uint8_t part; + uint32_t part :8; + uint32_t sub_part_id :12; + uint32_t size :12; + const void * sub_part_ptr; }lv_obj_draw_hook_dsc_t; /** Design modes */ diff --git a/src/lv_core/lv_obj_scroll.c b/src/lv_core/lv_obj_scroll.c index 68fdf3842..50620274f 100644 --- a/src/lv_core/lv_obj_scroll.c +++ b/src/lv_core/lv_obj_scroll.c @@ -297,13 +297,31 @@ void lv_obj_scroll_to(lv_obj_t * obj, lv_coord_t x, lv_coord_t y, lv_anim_enable void lv_obj_scroll_to_x(lv_obj_t * obj, lv_coord_t x, lv_anim_enable_t anim_en) { lv_anim_del(obj, (lv_anim_exec_xcb_t) scroll_anim_x_cb); - lv_obj_scroll_by(obj, -x + lv_obj_get_scroll_x(obj), 0, anim_en); + + /*Don't let scroll more then naturally possible by the size of the content*/ + if(x < 0) x = 0; + lv_coord_t scroll_max = lv_obj_get_scroll_left(obj) + lv_obj_get_scroll_right(obj); + if(x > scroll_max) x = scroll_max; + + lv_coord_t scroll_x = lv_obj_get_scroll_x(obj); + lv_coord_t diff = -x + scroll_x; + + lv_obj_scroll_by(obj, diff, 0, anim_en); } void lv_obj_scroll_to_y(lv_obj_t * obj, lv_coord_t y, lv_anim_enable_t anim_en) { lv_anim_del(obj, (lv_anim_exec_xcb_t) scroll_anim_y_cb); - lv_obj_scroll_by(obj, 0, -y + lv_obj_get_scroll_y(obj), anim_en); + + /*Don't let scroll more then naturally possible by the size of the content*/ + if(y < 0) y = 0; + lv_coord_t scroll_max = lv_obj_get_scroll_top(obj) + lv_obj_get_scroll_bottom(obj); + if(y > scroll_max) y = scroll_max; + + lv_coord_t scroll_y = lv_obj_get_scroll_y(obj); + lv_coord_t diff = -y + scroll_y; + + lv_obj_scroll_by(obj, 0, diff, anim_en); } void lv_obj_scroll_to_view(lv_obj_t * obj, lv_anim_enable_t anim_en) diff --git a/src/lv_core/lv_obj_scroll.h b/src/lv_core/lv_obj_scroll.h index f574cae25..6349c2605 100644 --- a/src/lv_core/lv_obj_scroll.h +++ b/src/lv_core/lv_obj_scroll.h @@ -203,7 +203,8 @@ void _lv_obj_scroll_by_raw(struct _lv_obj_t * obj, lv_coord_t x, lv_coord_t y); void lv_obj_scroll_by(struct _lv_obj_t * obj, lv_coord_t x, lv_coord_t y, lv_anim_enable_t anim_en); /** - * Scroll to a given coordinate on an object + * Scroll to a given coordinate on an object. + * `x` and `y` will be limited internally to allow scrolling only on the content area. * @param obj pointer to an object to scroll * @param x pixels to scroll horizontally * @param y pixels to scroll vertically @@ -212,7 +213,8 @@ void lv_obj_scroll_by(struct _lv_obj_t * obj, lv_coord_t x, lv_coord_t y, lv_ani void lv_obj_scroll_to(struct _lv_obj_t * obj, lv_coord_t x, lv_coord_t y, lv_anim_enable_t anim_en); /** - * Scroll to a given X coordinate on an object + * Scroll to a given X coordinate on an object. + * `x` will be limited internally to allow scrolling only on the content area. * @param obj pointer to an object to scroll * @param x pixels to scroll horizontally * @param anim_en LV_ANIM_ON: scroll with animation; LV_ANIM_OFF: scroll immediately @@ -220,7 +222,8 @@ void lv_obj_scroll_to(struct _lv_obj_t * obj, lv_coord_t x, lv_coord_t y, lv_ani void lv_obj_scroll_to_x(struct _lv_obj_t * obj, lv_coord_t x, lv_anim_enable_t anim_en); /** - * Scroll to a given X coordinate on an object + * Scroll to a given Y coordinate on an object + * `y` will be limited internally to allow scrolling only on the content area. * @param obj pointer to an object to scroll * @param y pixels to scroll vertically * @param anim_en LV_ANIM_ON: scroll with animation; LV_ANIM_OFF: scroll immediately diff --git a/src/lv_core/lv_obj_style.c b/src/lv_core/lv_obj_style.c index 7c10b13e4..37c8906f0 100644 --- a/src/lv_core/lv_obj_style.c +++ b/src/lv_core/lv_obj_style.c @@ -61,6 +61,7 @@ static void fade_in_anim_ready(lv_anim_t * a); /********************** * STATIC VARIABLES **********************/ +static style_refr = true; /********************** * MACROS @@ -70,23 +71,11 @@ static void fade_in_anim_ready(lv_anim_t * a); * GLOBAL FUNCTIONS **********************/ -/** - * Initialize the object related style manager module. - * Called by LVGL in `lv_init()` - */ void _lv_obj_style_init(void) { _lv_ll_init(&LV_GC_ROOT(_lv_obj_style_trans_ll), sizeof(trans_t)); } -/** - * Add a style to an object. - * @param obj: pointer to an object - * @param part: a part of the object to which the style should be added E.g. `LV_PART_MAIN` or `LV_PART_KNOB` - * @param state: a state or combination of states to which the style should be assigned - * @param style: pointer to a style to add - * @example lv_obj_add_style_no_refresh(slider, LV_PART_KNOB, LV_STATE_PRESSED, &style1); - */ void lv_obj_add_style(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_style_t * style) { trans_del(obj, part, 0xFF, NULL); @@ -118,13 +107,6 @@ void lv_obj_add_style(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_ lv_obj_refresh_style(obj, LV_STYLE_PROP_ALL); } -/** - * Add a style to an object. - * @param obj: pointer to an object - * @param part: a part of the object from which the style should be removed E.g. `LV_PART_MAIN` or `LV_PART_KNOB` - * @param state: a state or combination of states from which the style should be removed - * @param style: pointer to a style to remove - */ void lv_obj_remove_style(lv_obj_t * obj, uint32_t part, uint32_t state, lv_style_t * style) { uint32_t i = 0; @@ -163,13 +145,9 @@ void lv_obj_remove_style(lv_obj_t * obj, uint32_t part, uint32_t state, lv_style } } -/** - * Notify all object if a style is modified - * @param style: pointer to a style. Only the objects with this style will be notified - * (NULL to notify all objects) - */ void lv_obj_report_style_change(lv_style_t * style) { + if(!style_refr) return; lv_disp_t * d = lv_disp_get_next(NULL); while(d) { @@ -181,16 +159,12 @@ void lv_obj_report_style_change(lv_style_t * style) } } -/** - * Notify an object and its children about its style is modified. - * @param obj: pointer to an object - * @param prop: `LV_STYLE_PROP_ALL` or an `LV_STYLE_...` property. - * It is used to optimize what needs to be refreshed. - */ void lv_obj_refresh_style(lv_obj_t * obj,lv_style_prop_t prop) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); + if(!style_refr) return; + update_cache(obj, LV_PART_MAIN, prop); lv_obj_invalidate(obj); @@ -209,16 +183,11 @@ void lv_obj_refresh_style(lv_obj_t * obj,lv_style_prop_t prop) } } -/** - * Get the value of a style property. The current state of the object will be considered. - * Inherited properties will be inherited. - * If a property is not set a default value will be returned. - * @param obj: pointer to an object - * @param part: a part from which the property should be get - * @param prop: the property to get - * @return the value of the property. - * Should be read from the correct field of the `lv_style_value_t` according to the type of the property. - */ +void lv_obj_enable_style_refresh(bool en) +{ + style_refr = en; +} + lv_style_value_t lv_obj_get_style_prop(const lv_obj_t * obj, uint8_t part, lv_style_prop_t prop) { lv_style_value_t value_act; @@ -248,31 +217,13 @@ lv_style_value_t lv_obj_get_style_prop(const lv_obj_t * obj, uint8_t part, lv_st return value_act; } - -/** - * Set local style property on an object's part and state. - * @param obj: pointer to an object - * @param part: a part to which the property should be added - * @param state: a state to which the property should be added - * @param prop: the property - * @param value: value of the property. The correct element should be set according to the type of the property - */ void lv_obj_set_local_style_prop(lv_obj_t * obj, uint32_t part, uint32_t state, lv_style_prop_t prop, lv_style_value_t value) { lv_style_t * style = get_local_style(obj, part, state); lv_style_set_prop(style, prop, value); lv_obj_refresh_style(obj, prop); - } -/** - * Remove a local style property from a part of an object with a given state. - * @param obj: pointer to an object - * @param part: the part of the object which style property should be removed. - * @param state: the state from which the property should be removed. - * @param prop: a style property to remove. - * @return true: the property was found and removed; false: the property was not found - */ bool lv_obj_remove_local_style_prop(lv_obj_t * obj, uint32_t part, uint32_t state, lv_style_prop_t prop) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); @@ -293,19 +244,6 @@ bool lv_obj_remove_local_style_prop(lv_obj_t * obj, uint32_t part, uint32_t stat return lv_style_remove_prop(obj->style_list.styles[i].style, prop); } -/** - * Allocate and initialize a transition for a property of an object if the properties value is different in the new state. - * It allocates `lv_style_trans_t` in `_lv_obj_style_trans_ll` and set only `start/end_values`. No animation will be created here. - * @param obj and object to add the transition - * @param prop the property to apply the transaction - * @param part the part of the object to apply the transaction - * @param prev_state the previous state of the objects - * @param new_state the new state of the object - * @param time duration of transition in [ms] - * @param delay delay before starting the transition in [ms] - * @param path the path of the transition - * @return pointer to the allocated `the transaction` variable or `NULL` if no transition created - */ void lv_obj_style_create_transition(lv_obj_t * obj, lv_style_prop_t prop, uint8_t part, lv_state_t prev_state, lv_state_t new_state, uint32_t time, uint32_t delay, const lv_anim_path_t * path) { @@ -362,13 +300,6 @@ void lv_obj_style_create_transition(lv_obj_t * obj, lv_style_prop_t prop, uint8_ } } -/** - * Compare the style properties of an object in 2 different states - * @param obj pointer to an object - * @param state1 a state - * @param state2 an other state - * @return an element of `_lv_style_state_cmp_t` - */ _lv_style_state_cmp_t lv_obj_style_state_compare(lv_obj_t * obj, lv_state_t state1, lv_state_t state2) { lv_obj_style_list_t * list = &obj->style_list; @@ -432,13 +363,6 @@ _lv_style_state_cmp_t lv_obj_style_state_compare(lv_obj_t * obj, lv_state_t stat return res; } - -/** - * Fade in (from transparent to fully cover) an object and all its children using an `opa_scale` animation. - * @param obj the object to fade in - * @param time duration of the animation [ms] - * @param delay wait before the animation starts [ms] - */ void lv_obj_fade_in(lv_obj_t * obj, uint32_t time, uint32_t delay) { lv_anim_t a; @@ -452,12 +376,6 @@ void lv_obj_fade_in(lv_obj_t * obj, uint32_t time, uint32_t delay) lv_anim_start(&a); } -/** - * Fade out (from fully cover to transparent) an object and all its children using an `opa_scale` animation. - * @param obj the object to fade in - * @param time duration of the animation [ms] - * @param delay wait before the animation starts [ms] - */ void lv_obj_fade_out(lv_obj_t * obj, uint32_t time, uint32_t delay) { lv_anim_t a; @@ -552,7 +470,8 @@ static bool get_prop_core(const lv_obj_t * obj, uint8_t part, lv_style_prop_t pr cache_t cache_res = read_cache(obj, part, prop); switch(cache_res) { case CACHE_ZERO: - v->ptr = 0; + if(prop == LV_STYLE_TRANSFORM_ZOOM) v->num = LV_IMG_ZOOM_NONE; + else v->ptr = 0; return true; case CACHE_TRUE: v->num = 1; @@ -703,7 +622,7 @@ static void update_cache(lv_obj_t * obj, lv_part_t part, lv_style_prop_t prop) else list->cache_outline_width_zero = 0; } if(prop == LV_STYLE_PROP_ALL || prop == LV_STYLE_SHADOW_WIDTH) { - if(get_prop_core(obj, part, LV_STYLE_OUTLINE_WIDTH, &v) == false) v.num = 0; + if(get_prop_core(obj, part, LV_STYLE_SHADOW_WIDTH, &v) == false) v.num = 0; if(v.num == 0) list->cache_shadow_width_zero = 1; else list->cache_shadow_width_zero = 0; } @@ -805,10 +724,6 @@ static cache_t read_cache(const lv_obj_t * obj, lv_part_t part, lv_style_prop_t if(list->cache_shadow_width_zero ) return CACHE_ZERO; else return CACHE_NEED_CHECK; break; - case LV_STYLE_IMG_RECOLOR_OPA: - if(list->cache_shadow_width_zero ) return CACHE_ZERO; - else return CACHE_NEED_CHECK; - break; case LV_STYLE_CONTENT_TEXT: if(list->cache_content_text_zero ) return CACHE_ZERO; else return CACHE_NEED_CHECK; @@ -832,7 +747,7 @@ static cache_t read_cache(const lv_obj_t * obj, lv_part_t part, lv_style_prop_t /*255 or Needs check*/ case LV_STYLE_BG_OPA: if(list->cache_bg_opa_cover) return CACHE_255; - else return CACHE_ZERO; + else return CACHE_NEED_CHECK; break; case LV_STYLE_IMG_OPA: if(list->cache_img_opa_cover) return CACHE_255; diff --git a/src/lv_core/lv_obj_style.h b/src/lv_core/lv_obj_style.h index cd9be00d7..522804aaa 100644 --- a/src/lv_core/lv_obj_style.h +++ b/src/lv_core/lv_obj_style.h @@ -82,67 +82,77 @@ void _lv_obj_style_init(void); /** * Add a style to an object. - * @param obj: pointer to an object - * @param part: a part of the object to which the style should be added E.g. `LV_PART_MAIN` or `LV_PART_KNOB` - * @param state: a state or combination of states to which the style should be assigned - * @param style: pointer to a style to add - * @example lv_obj_add_style_no_refresh(slider, LV_PART_KNOB, LV_STATE_PRESSED, &style1); + * @param obj pointer to an object + * @param part a part of the object to which the style should be added E.g. `LV_PART_MAIN` or `LV_PART_KNOB` + * @param state a state or combination of states to which the style should be assigned + * @param style pointer to a style to add + * @example lv_obj_add_style_no_refresh(slider, LV_PART_KNOB, LV_STATE_PRESSED, &style1); */ void lv_obj_add_style(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_style_t * style); /** * Add a style to an object. - * @param obj: pointer to an object - * @param part: a part of the object from which the style should be removed E.g. `LV_PART_MAIN` or `LV_PART_KNOB` - * @param state: a state or combination of states from which the style should be removed - * @param style: pointer to a style to remove + * @param obj pointer to an object + * @param part a part of the object from which the style should be removed E.g. `LV_PART_MAIN` or `LV_PART_KNOB` + * @param state a state or combination of states from which the style should be removed + * @param style pointer to a style to remove + * @example lv_obj_remove_style(obj, LV_PART_ANY, LV_STATE_ANY, &style); //Remove a specific style + * @example lv_obj_remove_style(obj, LV_PART_MAIN, LV_STATE_ANY, &style); //Remove all styles from the main part + * @example lv_obj_remove_style(obj, LV_PART_ANY, LV_STATE_ANY, NULL); //Remove all styles */ void lv_obj_remove_style(struct _lv_obj_t * objj, uint32_t part, uint32_t state, lv_style_t * style); /** * Notify all object if a style is modified - * @param style: pointer to a style. Only the objects with this style will be notified - * (NULL to notify all objects) + * @param style pointer to a style. Only the objects with this style will be notified + * (NULL to notify all objects) */ void lv_obj_report_style_change(lv_style_t * style); /** * Notify an object and its children about its style is modified. - * @param obj: pointer to an object - * @param prop: `LV_STYLE_PROP_ALL` or an `LV_STYLE_...` property. - * It is used to optimize what needs to be refreshed. + * @param obj pointer to an object + * @param prop `LV_STYLE_PROP_ALL` or an `LV_STYLE_...` property. + * It is used to optimize what needs to be refreshed. */ void lv_obj_refresh_style(struct _lv_obj_t * obj,lv_style_prop_t prop); +/** + * Enable or disable automatic style refreshing when a new style is added/removed to/from an object + * or any other style change happens. + * @param en true: enable refreshing; false: disable refreshing + */ +void lv_obj_enable_style_refresh(bool en); + /** * Get the value of a style property. The current state of the object will be considered. * Inherited properties will be inherited. * If a property is not set a default value will be returned. - * @param obj: pointer to an object - * @param part: a part from which the property should be get - * @param prop: the property to get - * @return the value of the property. - * Should be read from the correct field of the `lv_style_value_t` according to the type of the property. + * @param obj pointer to an object + * @param part a part from which the property should be get + * @param prop the property to get + * @return the value of the property. + * Should be read from the correct field of the `lv_style_value_t` according to the type of the property. */ lv_style_value_t lv_obj_get_style_prop(const struct _lv_obj_t * obj, uint8_t part, lv_style_prop_t prop); /** * Set local style property on an object's part and state. - * @param obj: pointer to an object - * @param part: a part to which the property should be added - * @param state: a state to which the property should be added - * @param prop: the property - * @param value: value of the property. The correct element should be set according to the type of the property + * @param obj pointer to an object + * @param part a part to which the property should be added + * @param state a state to which the property should be added + * @param prop the property + * @param value value of the property. The correct element should be set according to the type of the property */ void lv_obj_set_local_style_prop(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_style_prop_t prop, lv_style_value_t value); /** * Remove a local style property from a part of an object with a given state. - * @param obj: pointer to an object - * @param part: the part of the object which style property should be removed. - * @param state: the state from which the property should be removed. - * @param prop: a style property to remove. - * @return true: the property was found and removed; false: the property was not found + * @param obj pointer to an object + * @param part the part of the object which style property should be removed. + * @param state the state from which the property should be removed. + * @param prop a style property to remove. + * @return true the property was found and removed; false: the property was not found */ bool lv_obj_remove_local_style_prop(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_style_prop_t prop); @@ -392,6 +402,254 @@ static inline lv_coord_t lv_obj_get_style_content_line_space(const struct _lv_ob static inline lv_text_decor_t lv_obj_get_style_content_decor(const struct _lv_obj_t * obj, uint32_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_CONTENT_DECOR); return (lv_text_decor_t) v.num; } + +/*===================== + * Local style set + *====================*/ +static inline void lv_obj_set_style_radius(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_coord_t value) { + lv_style_value_t v = {.num = value}; lv_obj_set_local_style_prop(obj, part, state, LV_STYLE_RADIUS, v); } + +static inline void lv_obj_set_style_clip_corner(struct _lv_obj_t * obj, uint32_t part, uint32_t state, bool value) { + lv_style_value_t v = {.num = value}; lv_obj_set_local_style_prop(obj, part, state, LV_STYLE_CLIP_CORNER, v); } + +static inline void lv_obj_set_style_transform_width(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_coord_t value) { + lv_style_value_t v = {.num = value}; lv_obj_set_local_style_prop(obj, part, state, LV_STYLE_TRANSFORM_WIDTH, v); } + +static inline void lv_obj_set_style_transform_height(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_coord_t value) { + lv_style_value_t v = {.num = value}; lv_obj_set_local_style_prop(obj, part, state, LV_STYLE_TRANSFORM_HEIGHT, v); } + +static inline void lv_obj_set_style_transform_zoom(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_coord_t value) { + lv_style_value_t v = {.num = value}; lv_obj_set_local_style_prop(obj, part, state, LV_STYLE_TRANSFORM_ZOOM, v); } + +static inline void lv_obj_set_style_transform_angle(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_coord_t value) { + lv_style_value_t v = {.num = value}; lv_obj_set_local_style_prop(obj, part, state, LV_STYLE_TRANSFORM_ANGLE, v); } + +static inline void lv_obj_set_style_opa(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_opa_t value) { + lv_style_value_t v = {.num = value}; lv_obj_set_local_style_prop(obj, part, state, LV_STYLE_OPA, v); } + +static inline void lv_obj_set_style_color_filter_cb(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_color_filter_cb_t value) { + lv_style_value_t v = {.func = (void(*)(void))value}; lv_obj_set_local_style_prop(obj, part, state, LV_STYLE_COLOR_FILTER_CB, v); } + +static inline void lv_obj_set_style_color_filter_opa(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_opa_t value) { + lv_style_value_t v = {.num = value}; lv_obj_set_local_style_prop(obj, part, state, LV_STYLE_COLOR_FILTER_OPA, v); } + +static inline void lv_obj_set_style_anim_time(struct _lv_obj_t * obj, uint32_t part, uint32_t state, uint32_t value) { + lv_style_value_t v = {.num = value}; lv_obj_set_local_style_prop(obj, part, state, LV_STYLE_ANIM_TIME, v); } + +static inline void lv_obj_set_style_transition(struct _lv_obj_t * obj, uint32_t part, uint32_t state, const lv_style_transition_dsc_t * value) { + lv_style_value_t v = {.ptr = value}; lv_obj_set_local_style_prop(obj, part, state, LV_STYLE_TRANSITION, v); } + +static inline void lv_obj_set_style_size(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_coord_t value) { + lv_style_value_t v = {.num = value}; lv_obj_set_local_style_prop(obj, part, state, LV_STYLE_SIZE, v); } + +static inline void lv_obj_set_style_blend_mode(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_blend_mode_t value) { + lv_style_value_t v = {.num = value}; lv_obj_set_local_style_prop(obj, part, state, LV_STYLE_BLEND_MODE, v); } + +static inline void lv_obj_set_style_pad_top(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_coord_t value) { + lv_style_value_t v = {.num = value}; lv_obj_set_local_style_prop(obj, part, state, LV_STYLE_PAD_TOP, v); } + +static inline void lv_obj_set_style_pad_bottom(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_coord_t value) { + lv_style_value_t v = {.num = value}; lv_obj_set_local_style_prop(obj, part, state, LV_STYLE_PAD_BOTTOM, v); } + +static inline void lv_obj_set_style_pad_left(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_coord_t value) { + lv_style_value_t v = {.num = value}; lv_obj_set_local_style_prop(obj, part, state, LV_STYLE_PAD_LEFT, v); } + +static inline void lv_obj_set_style_pad_right(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_coord_t value) { + lv_style_value_t v = {.num = value}; lv_obj_set_local_style_prop(obj, part, state, LV_STYLE_PAD_RIGHT, v); } + +static inline void lv_obj_set_style_pad_row(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_coord_t value) { + lv_style_value_t v = {.num = value}; lv_obj_set_local_style_prop(obj, part, state, LV_STYLE_PAD_ROW, v); } + +static inline void lv_obj_set_style_pad_column(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_coord_t value) { + lv_style_value_t v = {.num = value}; lv_obj_set_local_style_prop(obj, part, state, LV_STYLE_PAD_COLUMN, v); } + +static inline void lv_obj_set_style_bg_color(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_color_t value) { + lv_style_value_t v = {.color = value}; lv_obj_set_local_style_prop(obj, part, state, LV_STYLE_BG_COLOR, v); } + +static inline void lv_obj_set_style_bg_color_filtered(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_color_t value) { + lv_style_value_t v = {.color = value}; lv_obj_set_local_style_prop(obj, part, state, LV_STYLE_BG_COLOR_FILTERED, v); } + +static inline void lv_obj_set_style_bg_opa(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_opa_t value) { + lv_style_value_t v = {.num = value}; lv_obj_set_local_style_prop(obj, part, state, LV_STYLE_BG_OPA, v); } + +static inline void lv_obj_set_style_bg_grad_color(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_color_t value) { + lv_style_value_t v = {.color = value}; lv_obj_set_local_style_prop(obj, part, state, LV_STYLE_BG_GRAD_COLOR, v); } + +static inline void lv_obj_set_style_bg_grad_color_filtered(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_color_t value) { + lv_style_value_t v = {.color = value}; lv_obj_set_local_style_prop(obj, part, state, LV_STYLE_BG_GRAD_COLOR_FILTERED, v); } + +static inline void lv_obj_set_style_bg_grad_dir(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_grad_dir_t value) { + lv_style_value_t v = {.num = value}; lv_obj_set_local_style_prop(obj, part, state, LV_STYLE_BG_GRAD_DIR, v); } + +static inline void lv_obj_set_style_bg_main_stop(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_coord_t value) { + lv_style_value_t v = {.num = value}; lv_obj_set_local_style_prop(obj, part, state, LV_STYLE_BG_MAIN_STOP, v); } + +static inline void lv_obj_set_style_bg_grad_stop(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_coord_t value) { + lv_style_value_t v = {.num = value}; lv_obj_set_local_style_prop(obj, part, state, LV_STYLE_BG_GRAD_STOP, v); } + +static inline void lv_obj_set_style_bg_img_src(struct _lv_obj_t * obj, uint32_t part, uint32_t state, const void * value) { + lv_style_value_t v = {.ptr = value}; lv_obj_set_local_style_prop(obj, part, state, LV_STYLE_BG_IMG_SRC, v); } + +static inline void lv_obj_set_style_bg_img_opa(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_opa_t value) { + lv_style_value_t v = {.num = value}; lv_obj_set_local_style_prop(obj, part, state, LV_STYLE_BG_IMG_OPA, v); } + +static inline void lv_obj_set_style_bg_img_recolor(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_color_t value) { + lv_style_value_t v = {.color = value}; lv_obj_set_local_style_prop(obj, part, state, LV_STYLE_BG_IMG_RECOLOR, v); } + +static inline void lv_obj_set_style_bg_img_recolor_filtered(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_color_t value) { + lv_style_value_t v = {.color = value}; lv_obj_set_local_style_prop(obj, part, state, LV_STYLE_BG_IMG_RECOLOR_FILTERED, v); } + +static inline void lv_obj_set_style_bg_img_recolor_opa(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_opa_t value) { + lv_style_value_t v = {.num = value}; lv_obj_set_local_style_prop(obj, part, state, LV_STYLE_BG_IMG_RECOLOR_OPA, v); } + +static inline void lv_obj_set_style_bg_img_tiled(struct _lv_obj_t * obj, uint32_t part, uint32_t state, bool value) { + lv_style_value_t v = {.num = value}; lv_obj_set_local_style_prop(obj, part, state, LV_STYLE_BG_IMG_TILED, v); } + +static inline void lv_obj_set_style_border_color(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_color_t value) { + lv_style_value_t v = {.color = value}; lv_obj_set_local_style_prop(obj, part, state, LV_STYLE_BORDER_COLOR, v); } + +static inline void lv_obj_set_style_border_color_filtered(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_color_t value) { + lv_style_value_t v = {.color = value}; lv_obj_set_local_style_prop(obj, part, state, LV_STYLE_BORDER_COLOR_FILTERED, v); } + +static inline void lv_obj_set_style_border_opa(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_opa_t value) { + lv_style_value_t v = {.num = value}; lv_obj_set_local_style_prop(obj, part, state, LV_STYLE_BORDER_OPA, v); } + +static inline void lv_obj_set_style_border_width(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_coord_t value) { + lv_style_value_t v = {.num = value}; lv_obj_set_local_style_prop(obj, part, state, LV_STYLE_BORDER_WIDTH, v); } + +static inline void lv_obj_set_style_border_side(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_border_side_t value) { + lv_style_value_t v = {.num = value}; lv_obj_set_local_style_prop(obj, part, state, LV_STYLE_BORDER_SIDE, v); } + +static inline void lv_obj_set_style_border_post(struct _lv_obj_t * obj, uint32_t part, uint32_t state, bool value) { + lv_style_value_t v = {.num = value}; lv_obj_set_local_style_prop(obj, part, state, LV_STYLE_BORDER_POST, v); } + +static inline void lv_obj_set_style_text_color(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_color_t value) { + lv_style_value_t v = {.color = value}; lv_obj_set_local_style_prop(obj, part, state, LV_STYLE_TEXT_COLOR, v); } + +static inline void lv_obj_set_style_text_color_filtered(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_color_t value) { + lv_style_value_t v = {.color = value}; lv_obj_set_local_style_prop(obj, part, state, LV_STYLE_TEXT_COLOR_FILTERED, v); } + +static inline void lv_obj_set_style_text_opa(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_opa_t value) { + lv_style_value_t v = {.num = value}; lv_obj_set_local_style_prop(obj, part, state, LV_STYLE_TEXT_OPA, v); } + +static inline void lv_obj_set_style_text_font(struct _lv_obj_t * obj, uint32_t part, uint32_t state, const lv_font_t * value) { + lv_style_value_t v = {.ptr = value}; lv_obj_set_local_style_prop(obj, part, state, LV_STYLE_TEXT_FONT, v); } + +static inline void lv_obj_set_style_text_letter_space(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_coord_t value) { + lv_style_value_t v = {.num = value}; lv_obj_set_local_style_prop(obj, part, state, LV_STYLE_TEXT_LETTER_SPACE, v); } + +static inline void lv_obj_set_style_text_line_space(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_coord_t value) { + lv_style_value_t v = {.num = value}; lv_obj_set_local_style_prop(obj, part, state, LV_STYLE_TEXT_LINE_SPACE, v); } + +static inline void lv_obj_set_style_text_decor(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_text_decor_t value) { + lv_style_value_t v = {.num = value}; lv_obj_set_local_style_prop(obj, part, state, LV_STYLE_TEXT_DECOR, v); } + +static inline void lv_obj_set_style_text_align(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_text_align_t value) { + lv_style_value_t v = {.num = value}; lv_obj_set_local_style_prop(obj, part, state, LV_STYLE_TEXT_ALIGN, v); } + +static inline void lv_obj_set_style_img_opa(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_opa_t value) { + lv_style_value_t v = {.num = value}; lv_obj_set_local_style_prop(obj, part, state, LV_STYLE_IMG_OPA, v); } + +static inline void lv_obj_set_style_img_recolor(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_color_t value) { + lv_style_value_t v = {.color = value}; lv_obj_set_local_style_prop(obj, part, state, LV_STYLE_IMG_RECOLOR, v); } + +static inline void lv_obj_set_style_img_recolor_filtered(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_color_t value) { + lv_style_value_t v = {.color = value}; lv_obj_set_local_style_prop(obj, part, state, LV_STYLE_IMG_RECOLOR_FILTERED, v); } + +static inline void lv_obj_set_style_img_recolor_opa(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_opa_t value) { + lv_style_value_t v = {.num = value}; lv_obj_set_local_style_prop(obj, part, state, LV_STYLE_IMG_RECOLOR_OPA, v); } + +static inline void lv_obj_set_style_outline_width(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_coord_t value) { + lv_style_value_t v = {.num = value}; lv_obj_set_local_style_prop(obj, part, state, LV_STYLE_OUTLINE_WIDTH, v); } + +static inline void lv_obj_set_style_outline_color(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_color_t value) { + lv_style_value_t v = {.color = value}; lv_obj_set_local_style_prop(obj, part, state, LV_STYLE_OUTLINE_COLOR, v); } + +static inline void lv_obj_set_style_outline_color_filtered(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_color_t value) { + lv_style_value_t v = {.color = value}; lv_obj_set_local_style_prop(obj, part, state, LV_STYLE_OUTLINE_COLOR_FILTERED, v); } + +static inline void lv_obj_set_style_outline_opa(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_opa_t value) { + lv_style_value_t v = {.num = value}; lv_obj_set_local_style_prop(obj, part, state, LV_STYLE_OUTLINE_OPA, v); } + +static inline void lv_obj_set_style_outline_pad(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_coord_t value) { + lv_style_value_t v = {.num = value}; lv_obj_set_local_style_prop(obj, part, state, LV_STYLE_OUTLINE_PAD, v); } + +static inline void lv_obj_set_style_shadow_width(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_coord_t value) { + lv_style_value_t v = {.num = value}; lv_obj_set_local_style_prop(obj, part, state, LV_STYLE_SHADOW_WIDTH, v); } + +static inline void lv_obj_set_style_shadow_ofs_x(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_coord_t value) { + lv_style_value_t v = {.num = value}; lv_obj_set_local_style_prop(obj, part, state, LV_STYLE_SHADOW_OFS_X, v); } + +static inline void lv_obj_set_style_shadow_ofs_y(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_coord_t value) { + lv_style_value_t v = {.num = value}; lv_obj_set_local_style_prop(obj, part, state, LV_STYLE_SHADOW_OFS_Y, v); } + +static inline void lv_obj_set_style_shadow_spread(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_coord_t value) { + lv_style_value_t v = {.num = value}; lv_obj_set_local_style_prop(obj, part, state, LV_STYLE_SHADOW_SPREAD, v); } + +static inline void lv_obj_set_style_shadow_color(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_color_t value) { + lv_style_value_t v = {.color = value}; lv_obj_set_local_style_prop(obj, part, state, LV_STYLE_SHADOW_COLOR, v); } + +static inline void lv_obj_set_style_shadow_color_filtered(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_color_t value) { + lv_style_value_t v = {.color = value}; lv_obj_set_local_style_prop(obj, part, state, LV_STYLE_SHADOW_COLOR_FILTERED, v); } + +static inline void lv_obj_set_style_shadow_opa(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_opa_t value) { + lv_style_value_t v = {.num = value}; lv_obj_set_local_style_prop(obj, part, state, LV_STYLE_SHADOW_OPA, v); } + +static inline void lv_obj_set_style_line_width(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_coord_t value) { + lv_style_value_t v = {.num = value}; lv_obj_set_local_style_prop(obj, part, state, LV_STYLE_LINE_WIDTH, v); } + +static inline void lv_obj_set_style_line_dash_width(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_coord_t value) { + lv_style_value_t v = {.num = value}; lv_obj_set_local_style_prop(obj, part, state, LV_STYLE_LINE_DASH_WIDTH, v); } + +static inline void lv_obj_set_style_line_dash_gap(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_coord_t value) { + lv_style_value_t v = {.num = value}; lv_obj_set_local_style_prop(obj, part, state, LV_STYLE_LINE_DASH_GAP, v); } + +static inline void lv_obj_set_style_line_rounded(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_coord_t value) { + lv_style_value_t v = {.num = value}; lv_obj_set_local_style_prop(obj, part, state, LV_STYLE_LINE_ROUNDED, v); } + +static inline void lv_obj_set_style_line_color(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_color_t value) { + lv_style_value_t v = {.color = value}; lv_obj_set_local_style_prop(obj, part, state, LV_STYLE_LINE_COLOR, v); } + +static inline void lv_obj_set_style_line_color_filtered(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_color_t value) { + lv_style_value_t v = {.color = value}; lv_obj_set_local_style_prop(obj, part, state, LV_STYLE_LINE_COLOR_FILTERED, v); } + +static inline void lv_obj_set_style_line_opa(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_opa_t value) { + lv_style_value_t v = {.num = value}; lv_obj_set_local_style_prop(obj, part, state, LV_STYLE_LINE_OPA, v); } + +static inline void lv_obj_set_style_content_text(struct _lv_obj_t * obj, uint32_t part, uint32_t state, const char * value) { + lv_style_value_t v = {.ptr = value}; lv_obj_set_local_style_prop(obj, part, state, LV_STYLE_CONTENT_TEXT, v); } + +static inline void lv_obj_set_style_content_align(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_align_t value) { + lv_style_value_t v = {.num = value}; lv_obj_set_local_style_prop(obj, part, state, LV_STYLE_CONTENT_ALIGN, v); } + +static inline void lv_obj_set_style_content_ofs_x(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_coord_t value) { + lv_style_value_t v = {.num = value}; lv_obj_set_local_style_prop(obj, part, state, LV_STYLE_CONTENT_OFS_X, v); } + +static inline void lv_obj_set_style_content_ofs_y(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_coord_t value) { + lv_style_value_t v = {.num = value}; lv_obj_set_local_style_prop(obj, part, state, LV_STYLE_CONTENT_OFS_Y, v); } + +static inline void lv_obj_set_style_content_opa(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_opa_t value) { + lv_style_value_t v = {.num = value}; lv_obj_set_local_style_prop(obj, part, state, LV_STYLE_CONTENT_OPA, v); } + +static inline void lv_obj_set_style_content_font(struct _lv_obj_t * obj, uint32_t part, uint32_t state, const lv_font_t * value) { + lv_style_value_t v = {.ptr = value}; lv_obj_set_local_style_prop(obj, part, state, LV_STYLE_CONTENT_FONT, v); } + +static inline void lv_obj_set_style_content_color(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_color_t value) { + lv_style_value_t v = {.color = value}; lv_obj_set_local_style_prop(obj, part, state, LV_STYLE_CONTENT_COLOR, v); } + +static inline void lv_obj_set_style_content_color_filtered(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_color_t value) { + lv_style_value_t v = {.color = value}; lv_obj_set_local_style_prop(obj, part, state, LV_STYLE_CONTENT_COLOR_FILTERED, v); } + +static inline void lv_obj_set_style_content_letter_space(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_coord_t value) { + lv_style_value_t v = {.num = value}; lv_obj_set_local_style_prop(obj, part, state, LV_STYLE_CONTENT_LETTER_SPACE, v); } + +static inline void lv_obj_set_style_content_line_space(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_coord_t value) { + lv_style_value_t v = {.num = value}; lv_obj_set_local_style_prop(obj, part, state, LV_STYLE_CONTENT_LINE_SPACE, v); } + +static inline void lv_obj_set_style_content_decor(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_text_decor_t value) { + lv_style_value_t v = {.num = value}; lv_obj_set_local_style_prop(obj, part, state, LV_STYLE_CONTENT_DECOR, v); } + + /********************** * MACROS **********************/ diff --git a/src/lv_core/lv_refr.c b/src/lv_core/lv_refr.c index 04354ef2e..3f9729f9c 100644 --- a/src/lv_core/lv_refr.c +++ b/src/lv_core/lv_refr.c @@ -655,9 +655,9 @@ static void lv_refr_obj_and_children(lv_obj_t * top_p, const lv_area_t * mask_p) } /*Call the post draw draw function of the parents of the to object*/ - lv_event_send(par, LV_EVENT_DRAW_POST_BEGIN, NULL); + lv_event_send(par, LV_EVENT_DRAW_POST_BEGIN, mask_p); par->class_p->draw_cb(par, mask_p, LV_DRAW_MODE_POST_DRAW); - lv_event_send(par, LV_EVENT_DRAW_POST_END, NULL); + lv_event_send(par, LV_EVENT_DRAW_POST_END, mask_p); /*The new border will be the last parents, *so the 'younger' brothers of parent will be refreshed*/ @@ -694,9 +694,9 @@ static void lv_refr_obj(lv_obj_t * obj, const lv_area_t * mask_ori_p) /*Draw the parent and its children only if they ore on 'mask_parent'*/ if(union_ok != false) { /* Redraw the object */ - lv_event_send(obj, LV_EVENT_DRAW_MAIN_BEGIN, NULL); + lv_event_send(obj, LV_EVENT_DRAW_MAIN_BEGIN, &obj_ext_mask); obj->class_p->draw_cb(obj, &obj_ext_mask, LV_DRAW_MODE_MAIN_DRAW); - lv_event_send(obj, LV_EVENT_DRAW_MAIN_BEGIN, NULL); + lv_event_send(obj, LV_EVENT_DRAW_MAIN_END, &obj_ext_mask); #if MASK_AREA_DEBUG static lv_color_t debug_color = LV_COLOR_RED; @@ -743,9 +743,9 @@ static void lv_refr_obj(lv_obj_t * obj, const lv_area_t * mask_ori_p) } /* If all the children are redrawn make 'post draw' draw */ - lv_event_send(obj, LV_EVENT_DRAW_POST_BEGIN, NULL); + lv_event_send(obj, LV_EVENT_DRAW_POST_BEGIN, &obj_ext_mask); obj->class_p->draw_cb(obj, &obj_ext_mask, LV_DRAW_MODE_POST_DRAW); - lv_event_send(obj, LV_EVENT_DRAW_POST_END, NULL); + lv_event_send(obj, LV_EVENT_DRAW_POST_END, &obj_ext_mask); } } diff --git a/src/lv_draw/lv_draw_label.c b/src/lv_draw/lv_draw_label.c index 70d1f77da..e2d14c072 100644 --- a/src/lv_draw/lv_draw_label.c +++ b/src/lv_draw/lv_draw_label.c @@ -137,7 +137,7 @@ LV_ATTRIBUTE_FAST_MEM void lv_draw_label(const lv_area_t * coords, const lv_area else { /*If EXAPND is enabled then not limit the text's width to the object's width*/ lv_point_t p; - _lv_txt_get_size(&p, txt, dsc->font, dsc->letter_space, dsc->line_space, LV_COORD_MAX, + lv_txt_get_size(&p, txt, dsc->font, dsc->letter_space, dsc->line_space, LV_COORD_MAX, dsc->flag); w = p.x; } @@ -195,14 +195,14 @@ LV_ATTRIBUTE_FAST_MEM void lv_draw_label(const lv_area_t * coords, const lv_area } /*Align to middle*/ - if(dsc->flag & LV_TEXT_FLAG_CENTER) { + if(dsc->align == LV_TEXT_ALIGN_CENTER) { line_width = _lv_txt_get_width(&txt[line_start], line_end - line_start, font, dsc->letter_space, dsc->flag); pos.x += (lv_area_get_width(coords) - line_width) / 2; } /*Align to the right*/ - else if(dsc->flag & LV_TEXT_FLAG_RIGHT) { + else if(dsc->align == LV_TEXT_ALIGN_RIGHT) { line_width = _lv_txt_get_width(&txt[line_start], line_end - line_start, font, dsc->letter_space, dsc->flag); pos.x += lv_area_get_width(coords) - line_width; } @@ -361,7 +361,7 @@ LV_ATTRIBUTE_FAST_MEM void lv_draw_label(const lv_area_t * coords, const lv_area pos.x = coords->x1; /*Align to middle*/ - if(dsc->flag & LV_TEXT_FLAG_CENTER) { + if(dsc->align == LV_TEXT_ALIGN_CENTER) { line_width = _lv_txt_get_width(&txt[line_start], line_end - line_start, font, dsc->letter_space, dsc->flag); @@ -369,7 +369,7 @@ LV_ATTRIBUTE_FAST_MEM void lv_draw_label(const lv_area_t * coords, const lv_area } /*Align to the right*/ - else if(dsc->flag & LV_TEXT_FLAG_RIGHT) { + else if(dsc->align == LV_TEXT_ALIGN_RIGHT) { line_width = _lv_txt_get_width(&txt[line_start], line_end - line_start, font, dsc->letter_space, dsc->flag); pos.x += lv_area_get_width(coords) - line_width; diff --git a/src/lv_draw/lv_draw_label.h b/src/lv_draw/lv_draw_label.h index d76a5b1db..69d6f0973 100644 --- a/src/lv_draw/lv_draw_label.h +++ b/src/lv_draw/lv_draw_label.h @@ -28,21 +28,22 @@ extern "C" { **********************/ typedef struct { + const lv_font_t * font; + uint32_t sel_start; + uint32_t sel_end; lv_color_t color; lv_color_t sel_color; lv_color_t sel_bg_color; - const lv_font_t * font; - lv_opa_t opa; lv_coord_t line_space; lv_coord_t letter_space; - uint32_t sel_start; - uint32_t sel_end; lv_coord_t ofs_x; lv_coord_t ofs_y; + lv_opa_t opa; lv_bidi_dir_t bidi_dir; lv_text_flag_t flag; - lv_text_decor_t decor; - lv_blend_mode_t blend_mode; + lv_text_align_t align :2; + lv_text_decor_t decor : 3; + lv_blend_mode_t blend_mode: 3; } lv_draw_label_dsc_t; /** Store some info to speed up drawing of very large texts diff --git a/src/lv_draw/lv_draw_line.c b/src/lv_draw/lv_draw_line.c index 86c41e583..d191842f3 100644 --- a/src/lv_draw/lv_draw_line.c +++ b/src/lv_draw/lv_draw_line.c @@ -177,7 +177,7 @@ LV_ATTRIBUTE_FAST_MEM static void draw_line_hor(const lv_point_t * point1, const lv_coord_t dash_start = 0; if(dashed) { - dash_start = (vdb->area.x1 + draw_area.x1) % (dsc->dash_gap + dsc->dash_width); + dash_start = (point1->x) % (dsc->dash_gap + dsc->dash_width); } lv_opa_t * mask_buf = lv_mem_buf_get(draw_area_w); diff --git a/src/lv_draw/lv_draw_mask.c b/src/lv_draw/lv_draw_mask.c index 7c9e8d896..bdf2bc99f 100644 --- a/src/lv_draw/lv_draw_mask.c +++ b/src/lv_draw/lv_draw_mask.c @@ -7,9 +7,9 @@ * INCLUDES *********************/ -#if LV_DRAW_COMPLEX #include "lv_draw_mask.h" +#if LV_DRAW_COMPLEX #include "../lv_misc/lv_math.h" #include "../lv_misc/lv_log.h" #include "../lv_misc/lv_debug.h" diff --git a/src/lv_draw/lv_draw_rect.c b/src/lv_draw/lv_draw_rect.c index 3a5eea477..874137548 100644 --- a/src/lv_draw/lv_draw_rect.c +++ b/src/lv_draw/lv_draw_rect.c @@ -37,7 +37,7 @@ LV_ATTRIBUTE_FAST_MEM static void draw_border(const lv_area_t * coords, const lv static void draw_outline(const lv_area_t * coords, const lv_area_t * clip, const lv_draw_rect_dsc_t * dsc); -#if LV_USE_COMPLEX +#if LV_DRAW_COMPLEX LV_ATTRIBUTE_FAST_MEM static void draw_shadow(const lv_area_t * coords, const lv_area_t * clip, const lv_draw_rect_dsc_t * dsc); LV_ATTRIBUTE_FAST_MEM static void shadow_draw_corner_buf(const lv_area_t * coords, uint16_t * sh_buf, lv_coord_t s, @@ -49,7 +49,7 @@ static void draw_content(const lv_area_t * coords, const lv_area_t * clip, const static void draw_full_border(const lv_area_t * area_inner, const lv_area_t * area_outer, const lv_area_t * clip, lv_coord_t radius, bool radius_is_in, lv_color_t color, lv_opa_t opa, lv_blend_mode_t blend_mode); -#if LV_USE_COMPLEX +#if LV_DRAW_COMPLEX LV_ATTRIBUTE_FAST_MEM static inline lv_color_t grad_get(const lv_draw_rect_dsc_t * dsc, lv_coord_t s, lv_coord_t i); #endif @@ -192,10 +192,9 @@ LV_ATTRIBUTE_FAST_MEM static void draw_bg(const lv_area_t * coords, const lv_are else { int32_t draw_area_w = lv_area_get_width(&draw_area); int16_t mask_rout_id = LV_MASK_ID_INV; - lv_opa_t * mask_buf = NULL; + lv_opa_t * mask_buf = lv_mem_buf_get(draw_area_w); lv_draw_mask_radius_param_t mask_rout_param; if(rout > 0) { - mask_buf = lv_mem_buf_get(draw_area_w); lv_draw_mask_radius_init(&mask_rout_param, &coords_bg, rout, false); mask_rout_id = lv_draw_mask_add(&mask_rout_param, NULL); } @@ -1201,8 +1200,10 @@ static void draw_content(const lv_area_t * coords, const lv_area_t * clip, const label_dsc.color = dsc->content_color; label_dsc.font = dsc->content_font; label_dsc.opa = dsc->content_opa; + label_dsc.letter_space = dsc->content_letter_space; + label_dsc.line_space = dsc->content_line_space; lv_point_t s; - _lv_txt_get_size(&s, dsc->content_text, label_dsc.font, label_dsc.letter_space, label_dsc.line_space, LV_COORD_MAX, + lv_txt_get_size(&s, dsc->content_text, label_dsc.font, label_dsc.letter_space, label_dsc.line_space, LV_COORD_MAX, LV_TEXT_FLAG_NONE); diff --git a/src/lv_draw/lv_img_decoder.c b/src/lv_draw/lv_img_decoder.c index 2fe37420e..eb5ce3d6b 100644 --- a/src/lv_draw/lv_img_decoder.c +++ b/src/lv_draw/lv_img_decoder.c @@ -80,7 +80,7 @@ void _lv_img_decoder_init(void) * @param header the image info will be stored here * @return LV_RES_OK: success; LV_RES_INV: wasn't able to get info about the image */ -lv_res_t lv_img_decoder_get_info(const char * src, lv_img_header_t * header) +lv_res_t lv_img_decoder_get_info(const void * src, lv_img_header_t * header) { header->always_zero = 0; header->h = 0; diff --git a/src/lv_draw/lv_img_decoder.h b/src/lv_draw/lv_img_decoder.h index 34b370acc..a8e15ee95 100644 --- a/src/lv_draw/lv_img_decoder.h +++ b/src/lv_draw/lv_img_decoder.h @@ -146,7 +146,7 @@ void _lv_img_decoder_init(void); * @param header the image info will be stored here * @return LV_RES_OK: success; LV_RES_INV: wasn't able to get info about the image */ -lv_res_t lv_img_decoder_get_info(const char * src, lv_img_header_t * header); +lv_res_t lv_img_decoder_get_info(const void * src, lv_img_header_t * header); /** * Open an image. diff --git a/src/lv_misc/lv_anim.c b/src/lv_misc/lv_anim.c index c6d1f3dcc..c3243600b 100644 --- a/src/lv_misc/lv_anim.c +++ b/src/lv_misc/lv_anim.c @@ -356,7 +356,7 @@ lv_anim_value_t lv_anim_path_overshoot(const lv_anim_path_t * path, const lv_ani else t = (uint32_t)((uint32_t)a->act_time * 1024) / a->time; - int32_t step = lv_bezier3(t, 0, 1000, 1300, 1024); + int32_t step = lv_bezier3(t, 0, 1000, 1500, 1024); int32_t new_value; new_value = (int32_t)step * (a->end - a->start); diff --git a/src/lv_misc/lv_math.c b/src/lv_misc/lv_math.c index a82a17c7e..252f2840d 100644 --- a/src/lv_misc/lv_math.c +++ b/src/lv_misc/lv_math.c @@ -253,6 +253,20 @@ int32_t lv_map(int32_t x, int32_t min_in, int32_t max_in, int32_t min_out, int32 return ((x - min_in) * delta_out) / delta_in + min_out; } +uint32_t lv_rand(uint32_t min, uint32_t max) +{ + static uint32_t a = 0x1234ABCD; /*Seed*/ + + /* Algorithm "xor" from p. 4 of Marsaglia, "Xorshift RNGs" */ + uint32_t x = a; + x ^= x << 13; + x ^= x >> 17; + x ^= x << 5; + a = x; + + return (a % (max - min + 1)) + min; +} + /********************** * STATIC FUNCTIONS **********************/ diff --git a/src/lv_misc/lv_math.h b/src/lv_misc/lv_math.h index a9872aaf0..526399db2 100644 --- a/src/lv_misc/lv_math.h +++ b/src/lv_misc/lv_math.h @@ -108,6 +108,13 @@ int64_t lv_pow(int64_t base, int8_t exp); */ int32_t lv_map(int32_t x, int32_t min_in, int32_t max_in, int32_t min, int32_t max); +/** + * Get a pseudo random number in the given range + * @param min the minimum value + * @param max the maximum value + * @return return the random number. min <= return_value <= max + */ +uint32_t lv_rand(uint32_t min, uint32_t max); /********************** * MACROS **********************/ diff --git a/src/lv_misc/lv_style.c b/src/lv_misc/lv_style.c index a20630e9e..b31752c56 100644 --- a/src/lv_misc/lv_style.c +++ b/src/lv_misc/lv_style.c @@ -214,9 +214,11 @@ lv_style_value_t lv_style_prop_get_default(lv_style_prop_t prop) case LV_STYLE_BORDER_OPA: case LV_STYLE_TEXT_OPA: case LV_STYLE_IMG_OPA: + case LV_STYLE_BG_IMG_OPA: case LV_STYLE_LINE_OPA: case LV_STYLE_OUTLINE_OPA: case LV_STYLE_SHADOW_OPA: + case LV_STYLE_CONTENT_OPA: value.num = LV_OPA_COVER; break; case LV_STYLE_BG_GRAD_STOP: @@ -226,6 +228,7 @@ lv_style_value_t lv_style_prop_get_default(lv_style_prop_t prop) value.num = LV_BORDER_SIDE_FULL; break; case LV_STYLE_TEXT_FONT: + case LV_STYLE_CONTENT_FONT: value.ptr = LV_THEME_DEFAULT_FONT_NORMAL; break; case LV_STYLE_SIZE: diff --git a/src/lv_misc/lv_style.h b/src/lv_misc/lv_style.h index 3be3c6d9c..42ab532f0 100644 --- a/src/lv_misc/lv_style.h +++ b/src/lv_misc/lv_style.h @@ -436,6 +436,9 @@ static inline void lv_style_set_bg_grad_stop(lv_style_t * style, lv_coord_t valu static inline void lv_style_set_bg_img_src(lv_style_t * style, const void * value) { lv_style_value_t v = {.ptr = value}; lv_style_set_prop(style, LV_STYLE_BG_IMG_SRC, v); } +static inline void lv_style_set_bg_img_opa(lv_style_t * style, lv_opa_t value) { + lv_style_value_t v = {.num = value}; lv_style_set_prop(style, LV_STYLE_BG_IMG_OPA, v); } + static inline void lv_style_set_bg_img_recolor(lv_style_t * style, lv_color_t value) { lv_style_value_t v = {.color = value}; lv_style_set_prop(style, LV_STYLE_BG_IMG_RECOLOR, v); } diff --git a/src/lv_misc/lv_txt.c b/src/lv_misc/lv_txt.c index b9e24144a..44a8bd70c 100644 --- a/src/lv_misc/lv_txt.c +++ b/src/lv_misc/lv_txt.c @@ -90,11 +90,11 @@ static inline bool is_break_char(uint32_t letter); * @param font pointer to font of the text * @param letter_space letter space of the text * @param txt.line_space line space of the text - * @param flags settings for the text from 'txt_flag_t' enum + * @param flags settings for the text from ::lv_text_flag_t * @param max_width max with of the text (break the lines to fit this size) Set CORD_MAX to avoid * line breaks */ -void _lv_txt_get_size(lv_point_t * size_res, const char * text, const lv_font_t * font, lv_coord_t letter_space, +void lv_txt_get_size(lv_point_t * size_res, const char * text, const lv_font_t * font, lv_coord_t letter_space, lv_coord_t line_space, lv_coord_t max_width, lv_text_flag_t flag) { size_res->x = 0; diff --git a/src/lv_misc/lv_txt.h b/src/lv_misc/lv_txt.h index 43be8d90a..f8acda1ff 100644 --- a/src/lv_misc/lv_txt.h +++ b/src/lv_misc/lv_txt.h @@ -42,9 +42,7 @@ enum { LV_TEXT_FLAG_NONE = 0x00, LV_TEXT_FLAG_RECOLOR = 0x01, /**< Enable parsing of recolor command*/ LV_TEXT_FLAG_EXPAND = 0x02, /**< Ignore max-width to avoid automatic word wrapping*/ - LV_TEXT_FLAG_CENTER = 0x04, /**< Align the text to the middle*/ - LV_TEXT_FLAG_RIGHT = 0x08, /**< Align the text to the right*/ - LV_TEXT_FLAG_FIT = 0x10, /**< Max-width is already equal to the longest line. (Used to skip some calculation)*/ + LV_TEXT_FLAG_FIT = 0x04, /**< Max-width is already equal to the longest line. (Used to skip some calculation)*/ }; typedef uint8_t lv_text_flag_t; @@ -77,11 +75,11 @@ typedef uint8_t lv_text_align_t; * @param font pointer to font of the text * @param letter_space letter space of the text * @param line_space line space of the text - * @param flags settings for the text from 'txt_flag_t' enum + * @param flags settings for the text from ::lv_text_flag_t * @param max_width max with of the text (break the lines to fit this size) Set CORD_MAX to avoid * line breaks */ -void _lv_txt_get_size(lv_point_t * size_res, const char * text, const lv_font_t * font, lv_coord_t letter_space, +void lv_txt_get_size(lv_point_t * size_res, const char * text, const lv_font_t * font, lv_coord_t letter_space, lv_coord_t line_space, lv_coord_t max_width, lv_text_flag_t flag); /** diff --git a/src/lv_themes/lv_theme_default.c b/src/lv_themes/lv_theme_default.c index de637b088..c075f2824 100644 --- a/src/lv_themes/lv_theme_default.c +++ b/src/lv_themes/lv_theme_default.c @@ -23,7 +23,7 @@ #define RADIUS_DEFAULT LV_DPX(8) /*SCREEN*/ -#define COLOR_SCR (IS_LIGHT ? lv_color_hex(0xeaeff3) : lv_color_hex(0x444b5a)) +#define COLOR_SCR (IS_LIGHT ? lv_color_hex(0xf5f8fa) : lv_color_hex(0x444b5a)) #define COLOR_SCR_TEXT (IS_LIGHT ? lv_color_hex(0x3b3e42) : lv_color_hex(0xe7e9ec)) /*BUTTON*/ @@ -61,7 +61,7 @@ #define COLOR_BG_TEXT_DIS (IS_LIGHT ? lv_color_hex3(0xaaa) : lv_color_hex3(0x999)) /*SECONDARY BACKGROUND*/ -#define COLOR_GRAY (IS_LIGHT ? lv_color_hex(0xd4d7d9) : lv_color_hex(0x45494d)) +#define COLOR_GRAY (IS_LIGHT ? lv_color_hex(0xcfd2d4) : lv_color_hex(0x45494d)) #define COLOR_BG_SEC_BORDER (IS_LIGHT ? lv_color_hex(0xdfe7ed) : lv_color_hex(0x404040)) #define COLOR_BG_SEC_TEXT (IS_LIGHT ? lv_color_hex(0x31404f) : lv_color_hex(0xa5a8ad)) #define COLOR_BG_SEC_TEXT_DIS (IS_LIGHT ? lv_color_hex(0xaaaaaa) : lv_color_hex(0xa5a8ad)) @@ -92,8 +92,11 @@ typedef struct { lv_style_t disabled; lv_style_t pad_zero; lv_style_t pad_small; + lv_style_t pad_normal; lv_style_t pad_gap; lv_style_t pad_small_negative; + lv_style_t line_space_large; + lv_style_t text_align_center; lv_style_t focus_border; lv_style_t focus_outline; lv_style_t edit_outline; @@ -151,6 +154,7 @@ typedef struct { * STATIC PROTOTYPES **********************/ static void theme_apply(lv_theme_t * th, lv_obj_t * obj); +static lv_color_t gray_filter(lv_color_t color, lv_opa_t opa); static void style_init_reset(lv_style_t * style); /********************** @@ -172,11 +176,10 @@ static bool inited; static void basic_init(void) { const static lv_style_prop_t trans_props[] = { - LV_STYLE_BG_OPA, LV_STYLE_BG_COLOR, - LV_STYLE_TRANSFORM_WIDTH, - LV_STYLE_TRANSFORM_HEIGHT, - LV_STYLE_TRANSFORM_ZOOM, - LV_STYLE_TRANSFORM_ANGLE, + LV_STYLE_BG_OPA, LV_STYLE_BG_COLOR, LV_STYLE_CONTENT_OPA, + LV_STYLE_TRANSFORM_WIDTH, LV_STYLE_TRANSFORM_HEIGHT, + LV_STYLE_TRANSFORM_ZOOM, LV_STYLE_TRANSFORM_ANGLE, + LV_STYLE_CONTENT_OFS_X, LV_STYLE_CONTENT_OFS_Y, LV_STYLE_COLOR_FILTER_OPA, LV_STYLE_COLOR_FILTER_CB, 0 }; @@ -198,9 +201,9 @@ static void basic_init(void) lv_style_set_bg_opa(&styles->scrollbar, LV_OPA_COVER); lv_style_set_bg_color(&styles->scrollbar, (IS_LIGHT ? lv_color_hex(0xcccfd1) : lv_color_hex(0x777f85))); lv_style_set_radius(&styles->scrollbar, LV_RADIUS_CIRCLE); - lv_style_set_pad_left(&styles->scrollbar, LV_DPX(7)); - lv_style_set_pad_right(&styles->scrollbar, LV_DPX(7)); + lv_style_set_pad_right(&styles->scrollbar, LV_DPX(7)); lv_style_set_pad_top(&styles->scrollbar, LV_DPX(7)); + lv_style_set_size(&styles->scrollbar, LV_DPX(5)); lv_style_set_bg_opa(&styles->scrollbar, LV_OPA_40); lv_style_set_transition(&styles->scrollbar, &trans_normal); @@ -257,14 +260,21 @@ static void basic_init(void) lv_style_set_color_filter_opa(&styles->pressed, LV_OPA_20); style_init_reset(&styles->disabled); - lv_style_set_color_filter_cb(&styles->disabled, lv_color_lighten); - lv_style_set_color_filter_opa(&styles->disabled, LV_OPA_40); + lv_style_set_color_filter_cb(&styles->disabled, gray_filter); + lv_style_set_color_filter_opa(&styles->disabled, LV_OPA_50); style_init_reset(&styles->clip_corner); lv_style_set_clip_corner(&styles->clip_corner, true); + style_init_reset(&styles->pad_normal); + lv_style_set_pad_all(&styles->pad_normal, PAD_DEF); + lv_style_set_pad_row(&styles->pad_normal, PAD_DEF); + lv_style_set_pad_column(&styles->pad_normal, PAD_DEF); + style_init_reset(&styles->pad_small); lv_style_set_pad_all(&styles->pad_small, LV_DPX(10)); + lv_style_set_pad_row(&styles->pad_small, LV_DPX(5)); + lv_style_set_pad_column(&styles->pad_small, LV_DPX(5)); style_init_reset(&styles->pad_gap); lv_style_set_pad_row(&styles->pad_gap, LV_DPX(10)); @@ -273,8 +283,16 @@ static void basic_init(void) style_init_reset(&styles->pad_small_negative); lv_style_set_pad_all(&styles->pad_small_negative, - LV_DPX(4)); + style_init_reset(&styles->line_space_large); + lv_style_set_text_line_space(&styles->line_space_large, LV_DPX(20)); + + style_init_reset(&styles->text_align_center); + lv_style_set_text_align(&styles->text_align_center, LV_TEXT_ALIGN_CENTER); + style_init_reset(&styles->pad_zero); lv_style_set_pad_all(&styles->pad_zero, 0); + lv_style_set_pad_row(&styles->pad_zero, 0); + lv_style_set_pad_column(&styles->pad_zero, 0); style_init_reset(&styles->bg_color_primary); lv_style_set_bg_color(&styles->bg_color_primary, theme.color_primary); @@ -298,6 +316,9 @@ static void basic_init(void) style_init_reset(&styles->circle); lv_style_set_radius(&styles->circle, LV_RADIUS_CIRCLE); + style_init_reset(&styles->no_radius); + lv_style_set_radius(&styles->no_radius, 0); + style_init_reset(&styles->grow); lv_style_set_transform_width(&styles->grow, LV_DPX(3)); lv_style_set_transform_height(&styles->grow, LV_DPX(3)); @@ -343,8 +364,8 @@ static void basic_init(void) style_init_reset(&styles->cb_marker_checked); lv_style_set_content_text(&styles->cb_marker_checked, LV_SYMBOL_OK); - lv_style_set_text_color(&styles->cb_marker_checked, LV_COLOR_WHITE); - lv_style_set_text_font(&styles->cb_marker_checked, theme.font_small); + lv_style_set_content_color(&styles->cb_marker_checked, LV_COLOR_WHITE); + lv_style_set_content_font(&styles->cb_marker_checked, theme.font_small); #endif #if LV_USE_CHART @@ -352,10 +373,12 @@ static void basic_init(void) lv_style_set_line_width(&styles->chart_series, LV_DPX(3)); lv_style_set_radius(&styles->chart_series, LV_DPX(1)); lv_style_set_size(&styles->chart_series, LV_DPX(5)); + lv_style_set_pad_column(&styles->chart_series, LV_DPX(2)); style_init_reset(&styles->chart_ticks); lv_style_set_line_width(&styles->chart_ticks, LV_DPX(1)); - lv_style_set_line_color(&styles->chart_ticks, COLOR_GRAY); + lv_style_set_line_color(&styles->chart_ticks, COLOR_SCR_TEXT); + lv_style_set_pad_all(&styles->chart_ticks, LV_DPX(2)); #endif @@ -378,6 +401,7 @@ static void basic_init(void) style_init_reset(&styles->table_cell); lv_style_set_border_width(&styles->table_cell, LV_DPX(1)); lv_style_set_border_color(&styles->table_cell, CARD_BORDER_COLOR); + lv_style_set_border_side(&styles->table_cell, LV_BORDER_SIDE_TOP | LV_BORDER_SIDE_BOTTOM ); #endif #if LV_USE_TEXTAREA @@ -393,38 +417,6 @@ static void basic_init(void) #endif } -// -//static void ddlist_init(void) -//{ -//#if LV_USE_DROPDOWN != 0 -// -// style_init_reset(&styles->ddlist_page); -// lv_style_set_text_line_space(&styles->ddlist_page, LV_STATE_DEFAULT, LV_DPX(20)); -// lv_style_set_clip_corner(&styles->ddlist_page, LV_STATE_DEFAULT, true); -// -// style_init_reset(&styles->ddlist_sel); -// lv_style_set_bg_opa(&styles->ddlist_sel, LV_STATE_DEFAULT, LV_OPA_COVER); -// lv_style_set_bg_color(&styles->ddlist_sel, LV_STATE_DEFAULT, theme.color_primary); -// lv_style_set_text_color(&styles->ddlist_sel, LV_STATE_DEFAULT, IS_LIGHT ? lv_color_hex3(0xfff) : lv_color_hex3(0xfff)); -// lv_style_set_bg_color(&styles->ddlist_sel, LV_STATE_PRESSED, CARD_PR_COLOR); -// lv_style_set_text_color(&styles->ddlist_sel, LV_STATE_PRESSED, CARD_TEXT_PR_COLOR); -//#endif -//} - -//static void roller_init(void) -//{ -//#if LV_USE_ROLLER != 0 -// style_init_reset(&styles->roller_bg); -// lv_style_set_text_line_space(&styles->roller_bg, LV_STATE_DEFAULT, LV_DPX(25)); -// -// style_init_reset(&styles->roller_sel); -// lv_style_set_bg_opa(&styles->roller_sel, LV_STATE_DEFAULT, LV_OPA_COVER); -// lv_style_set_bg_color(&styles->roller_sel, LV_STATE_DEFAULT, theme.color_primary); -// lv_style_set_text_color(&styles->roller_sel, LV_STATE_DEFAULT, LV_COLOR_WHITE); -//#endif -//} - - /********************** * GLOBAL FUNCTIONS @@ -505,14 +497,12 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj) #if LV_USE_BTNMATRIX else if(lv_obj_check_type(obj, &lv_btnmatrix)) { lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->card); - lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->pad_gap); lv_obj_add_style(obj, LV_PART_ITEMS, LV_STATE_DEFAULT, &styles->btn); lv_obj_add_style(obj, LV_PART_ITEMS, LV_STATE_PRESSED, &styles->pressed); - lv_obj_add_style(obj, LV_PART_ITEMS, LV_STATE_PRESSED, &styles->grow); - lv_obj_add_style(obj, LV_PART_ITEMS, LV_STATE_DEFAULT, &styles->transition_delayed); - lv_obj_add_style(obj, LV_PART_ITEMS, LV_STATE_PRESSED, &styles->transition_normal); + lv_obj_add_style(obj, LV_PART_ITEMS, LV_STATE_CHECKED, &styles->bg_color_primary); } #endif + #if LV_USE_BAR else if(lv_obj_check_type(obj, &lv_bar)) { lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->bg_color_gray); @@ -540,18 +530,20 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj) #if LV_USE_TABLE else if(lv_obj_check_type(obj, &lv_table)) { lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->card); + lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->pad_zero); + lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->no_radius); lv_obj_add_style(obj, LV_PART_SCROLLBAR, LV_STATE_DEFAULT, &styles->scrollbar); lv_obj_add_style(obj, LV_PART_SCROLLBAR, LV_STATE_SCROLLED, &styles->scrollbar_scrolled); - lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_SCROLLED, &styles->transition_normal); lv_obj_add_style(obj, LV_PART_ITEMS, LV_STATE_DEFAULT, &styles->bg_color_white); lv_obj_add_style(obj, LV_PART_ITEMS, LV_STATE_DEFAULT, &styles->table_cell); - lv_obj_add_style(obj, LV_PART_ITEMS, LV_STATE_DEFAULT, &styles->pad_small); + lv_obj_add_style(obj, LV_PART_ITEMS, LV_STATE_DEFAULT, &styles->pad_normal); } #endif #if LV_USE_CHECKBOX else if(lv_obj_check_type(obj, &lv_checkbox)) { lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->pad_gap); + lv_obj_add_style(obj, LV_PART_MARKER, LV_STATE_DISABLED, &styles->disabled); lv_obj_add_style(obj, LV_PART_MARKER, LV_STATE_DEFAULT, &styles->cb_marker); lv_obj_add_style(obj, LV_PART_MARKER, LV_STATE_CHECKED, &styles->bg_color_primary); lv_obj_add_style(obj, LV_PART_MARKER, LV_STATE_CHECKED, &styles->cb_marker_checked); @@ -566,11 +558,14 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj) else if(lv_obj_check_type(obj, &lv_switch)) { lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->bg_color_gray); lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->circle); + lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DISABLED, &styles->disabled); lv_obj_add_style(obj, LV_PART_INDICATOR, LV_STATE_DEFAULT, &styles->bg_color_primary); lv_obj_add_style(obj, LV_PART_INDICATOR, LV_STATE_DEFAULT, &styles->circle); + lv_obj_add_style(obj, LV_PART_INDICATOR, LV_STATE_DISABLED, &styles->disabled); lv_obj_add_style(obj, LV_PART_KNOB, LV_STATE_DEFAULT, &styles->knob); lv_obj_add_style(obj, LV_PART_KNOB, LV_STATE_DEFAULT, &styles->bg_color_white); lv_obj_add_style(obj, LV_PART_KNOB, LV_STATE_DEFAULT, &styles->pad_small_negative); + lv_obj_add_style(obj, LV_PART_KNOB, LV_STATE_DISABLED, &styles->disabled); } #endif @@ -578,11 +573,11 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj) else if(lv_obj_check_type(obj, &lv_chart)) { lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->card); lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->line_dashed); - lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->pad_zero); + lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->pad_small); lv_obj_add_style(obj, LV_PART_SCROLLBAR, LV_STATE_DEFAULT, &styles->scrollbar); lv_obj_add_style(obj, LV_PART_SCROLLBAR, LV_STATE_SCROLLED, &styles->scrollbar_scrolled); lv_obj_add_style(obj, LV_PART_ITEMS, LV_STATE_DEFAULT, &styles->chart_series); - lv_obj_add_style(obj, LV_PART_MARKER, LV_STATE_DEFAULT, &styles->pad_small); + lv_obj_add_style(obj, LV_PART_ITEMS, LV_STATE_PRESSED, &styles->bg_color_primary); lv_obj_add_style(obj, LV_PART_MARKER, LV_STATE_DEFAULT, &styles->chart_ticks); } #endif @@ -591,18 +586,28 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj) else if(lv_obj_check_type(obj, &lv_roller)) { lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->card); lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->anim); + lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->line_space_large); + lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->text_align_center); lv_obj_add_style(obj, LV_PART_SELECTED, LV_STATE_DEFAULT, &styles->bg_color_primary); } #endif #if LV_USE_DROPDOWN else if(lv_obj_check_type(obj, &lv_dropdown)) { - lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->card); + lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->btn); + lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->pad_normal); + lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->transition_delayed); + lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_PRESSED, &styles->pressed); + lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_PRESSED, &styles->transition_normal); + lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_PRESSED, &styles->grow); lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_CHECKED, &styles->ddlist_flip); lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->transition_normal); } else if(lv_obj_check_type(obj, &lv_dropdown_list)) { lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->card); + lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->line_space_large); + lv_obj_add_style(obj, LV_PART_SCROLLBAR, LV_STATE_DEFAULT, &styles->scrollbar); + lv_obj_add_style(obj, LV_PART_SCROLLBAR, LV_STATE_SCROLLED, &styles->scrollbar_scrolled); lv_obj_add_style(obj, LV_PART_SELECTED, LV_STATE_DEFAULT, &styles->bg_color_primary); lv_obj_add_style(obj, LV_PART_SELECTED, LV_STATE_PRESSED, &styles->bg_color_gray); } @@ -661,6 +666,10 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj) * STATIC FUNCTIONS **********************/ +static lv_color_t gray_filter(lv_color_t color, lv_opa_t opa) +{ + return lv_color_mix(LV_COLOR_SILVER, color, opa); +} static void style_init_reset(lv_style_t * style) { if(inited) lv_style_reset(style); diff --git a/src/lv_widgets/lv_bar.c b/src/lv_widgets/lv_bar.c index 84519753f..ad71f1de3 100644 --- a/src/lv_widgets/lv_bar.c +++ b/src/lv_widgets/lv_bar.c @@ -11,7 +11,6 @@ #include "../lv_misc/lv_debug.h" #include "../lv_draw/lv_draw.h" -#include "../lv_themes/lv_theme.h" #include "../lv_misc/lv_anim.h" #include "../lv_misc/lv_math.h" #include @@ -21,11 +20,24 @@ *********************/ #define LV_OBJX_NAME "lv_bar" -#define LV_BAR_SIZE_MIN 4 /*hor. pad and ver. pad cannot make the indicator smaller then this [px]*/ +/** hor. pad and ver. pad cannot make the indicator smaller then this [px]*/ +#define LV_BAR_SIZE_MIN 4 #define LV_BAR_IS_ANIMATING(anim_struct) (((anim_struct).anim_state) != LV_BAR_ANIM_STATE_INV) #define LV_BAR_GET_ANIM_VALUE(orig_value, anim_struct) (LV_BAR_IS_ANIMATING(anim_struct) ? ((anim_struct).anim_end) : (orig_value)) +/** Bar animation start value. (Not the real value of the Bar just indicates process animation)*/ +#define LV_BAR_ANIM_STATE_START 0 + +/** Bar animation end value. (Not the real value of the Bar just indicates process animation)*/ +#define LV_BAR_ANIM_STATE_END 256 + +/** Mark no animation is in progress */ +#define LV_BAR_ANIM_STATE_INV -1 + +/** log2(LV_BAR_ANIM_STATE_END) used to normalize data*/ +#define LV_BAR_ANIM_STATE_NORM 8 + /********************** * TYPEDEFS **********************/ @@ -38,7 +50,6 @@ static void lv_bar_destructor(lv_obj_t * obj); static lv_draw_res_t lv_bar_draw(lv_obj_t * bar, const lv_area_t * clip_area, lv_draw_mode_t mode); static lv_res_t lv_bar_signal(lv_obj_t * bar, lv_signal_t sign, void * param); static void draw_indic(lv_obj_t * bar, const lv_area_t * clip_area); - static void lv_bar_set_value_with_anim(lv_obj_t * obj, int16_t new_value, int16_t * value_ptr, lv_bar_anim_t * anim_info, lv_anim_enable_t en); static void lv_bar_init_anim(lv_obj_t * bar, lv_bar_anim_t * bar_anim); @@ -64,13 +75,7 @@ const lv_obj_class_t lv_bar = { /********************** * GLOBAL FUNCTIONS **********************/ -/** - * Create a bar objects - * @param par pointer to an object, it will be the parent of the new bar - * @param copy DEPRECATED, will be removed in v9. - * Pointer to an other bar to copy. - * @return pointer to the created bar - */ + lv_obj_t * lv_bar_create(lv_obj_t * parent, const lv_obj_t * copy) { return lv_obj_create_from_class(&lv_bar, parent, copy); @@ -80,12 +85,6 @@ lv_obj_t * lv_bar_create(lv_obj_t * parent, const lv_obj_t * copy) * Setter functions *====================*/ -/** - * Set a new value on the bar - * @param bar pointer to a bar object - * @param value new value - * @param anim LV_ANIM_ON: set the value with an animation; LV_ANIM_OFF: change the value immediately - */ void lv_bar_set_value(lv_obj_t * obj, int16_t value, lv_anim_enable_t anim) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); @@ -94,39 +93,25 @@ void lv_bar_set_value(lv_obj_t * obj, int16_t value, lv_anim_enable_t anim) if(bar->cur_value == value) return; value = LV_CLAMP(bar->min_value, value, bar->max_value); - value = value < bar->start_value ? bar->start_value : value; /*Can be smaller then the left value*/ + value = value < bar->start_value ? bar->start_value : value; /*Can't be smaller then the left value*/ if(bar->cur_value == value) return; lv_bar_set_value_with_anim(obj, value, &bar->cur_value, &bar->cur_value_anim, anim); } -/** - * Set a new start value on the bar - * @param bar pointer to a bar object - * @param value new start value - * @param anim LV_ANIM_ON: set the value with an animation; LV_ANIM_OFF: change the value immediately - */ -void lv_bar_set_start_value(lv_obj_t * obj, int16_t start_value, lv_anim_enable_t anim) +void lv_bar_set_start_value(lv_obj_t * obj, int16_t value, lv_anim_enable_t anim) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); lv_bar_t * bar = (lv_bar_t *)obj; - int16_t new_value = start_value; - new_value = new_value > bar->max_value ? bar->max_value : new_value; - new_value = new_value < bar->min_value ? bar->min_value : new_value; - new_value = new_value > bar->cur_value ? bar->cur_value : new_value; + value = LV_CLAMP(bar->min_value, value, bar->max_value); + value = value > bar->cur_value ? bar->cur_value : value; /*Can't be greater then the right value*/ - if(bar->start_value == new_value) return; - lv_bar_set_value_with_anim(obj, new_value, &bar->start_value, &bar->start_value_anim, anim); + if(bar->start_value == value) return; + lv_bar_set_value_with_anim(obj, value, &bar->start_value, &bar->start_value_anim, anim); } -/** - * Set minimum and the maximum values of a bar - * @param bar pointer to the bar object - * @param min minimum value - * @param max maximum value - */ void lv_bar_set_range(lv_obj_t * obj, int16_t min, int16_t max) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); @@ -138,7 +123,7 @@ void lv_bar_set_range(lv_obj_t * obj, int16_t min, int16_t max) bar->max_value = max; bar->min_value = min; - if(lv_bar_get_type(obj) != LV_BAR_TYPE_CUSTOM) + if(lv_bar_get_type(obj) != LV_BAR_TYPE_RANGE) bar->start_value = min; if(bar->cur_value > max) { @@ -152,19 +137,15 @@ void lv_bar_set_range(lv_obj_t * obj, int16_t min, int16_t max) lv_obj_invalidate(obj); } -/** - * Set the type of bar. - * @param bar pointer to bar object - * @param type bar type - */ void lv_bar_set_type(lv_obj_t * obj, lv_bar_type_t type) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); lv_bar_t * bar = (lv_bar_t *)obj; bar->type = type; - if(bar->type != LV_BAR_TYPE_CUSTOM) + if(bar->type != LV_BAR_TYPE_RANGE) { bar->start_value = bar->min_value; + } lv_obj_invalidate(obj); } @@ -173,11 +154,6 @@ void lv_bar_set_type(lv_obj_t * obj, lv_bar_type_t type) * Getter functions *====================*/ -/** - * Get the value of a bar - * @param bar pointer to a bar object - * @return the value of the bar - */ int16_t lv_bar_get_value(const lv_obj_t * obj) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); @@ -186,26 +162,16 @@ int16_t lv_bar_get_value(const lv_obj_t * obj) return LV_BAR_GET_ANIM_VALUE(bar->cur_value, bar->cur_value_anim); } -/** - * Get the start value of a bar - * @param bar pointer to a bar object - * @return the start value of the bar - */ int16_t lv_bar_get_start_value(const lv_obj_t * obj) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); lv_bar_t * bar = (lv_bar_t *)obj; - if(bar->type != LV_BAR_TYPE_CUSTOM) return bar->min_value; + if(bar->type != LV_BAR_TYPE_RANGE) return bar->min_value; return LV_BAR_GET_ANIM_VALUE(bar->start_value, bar->start_value_anim); } -/** - * Get the minimum value of a bar - * @param bar pointer to a bar object - * @return the minimum value of the bar - */ int16_t lv_bar_get_min_value(const lv_obj_t * obj) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); @@ -213,11 +179,6 @@ int16_t lv_bar_get_min_value(const lv_obj_t * obj) return bar->min_value; } -/** - * Get the maximum value of a bar - * @param bar pointer to a bar object - * @return the maximum value of the bar - */ int16_t lv_bar_get_max_value(const lv_obj_t * obj) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); @@ -226,11 +187,6 @@ int16_t lv_bar_get_max_value(const lv_obj_t * obj) return bar->max_value; } -/** - * Get the type of bar. - * @param bar pointer to bar object - * @return bar type - */ lv_bar_type_t lv_bar_get_type(lv_obj_t * obj) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); @@ -279,27 +235,12 @@ static void lv_bar_constructor(lv_obj_t * obj, lv_obj_t * parent, const lv_obj_t static void lv_bar_destructor(lv_obj_t * obj) { -// lv_bar_t * bar = obj; -// -// _lv_obj_reset_style_list_no_refr(obj, LV_PART_INDICATOR); -//#if LV_USE_ANIMATION -// lv_anim_del(&bar->cur_value_anim, NULL); -// lv_anim_del(&bar->start_value_anim, NULL); -//#endif + lv_bar_t * bar = (lv_bar_t *)obj; -// bar->class_p->base_p->destructor(obj); + lv_anim_del(&bar->cur_value_anim, NULL); + lv_anim_del(&bar->start_value_anim, NULL); } -/** - * Handle the drawing related tasks of the bars - * @param bar pointer to an object - * @param clip_area the object will be drawn only in this area - * @param mode LV_DRAW_COVER_CHK: only check if the object fully covers the 'mask_p' area - * (return 'true' if yes) - * LV_DRAW_DRAW: draw the object (always return 'true') - * LV_DRAW_DRAW_POST: drawing after every children are drawn - * @param return an element of `lv_draw_res_t` - */ static lv_draw_res_t lv_bar_draw(lv_obj_t * obj, const lv_area_t * clip_area, lv_draw_mode_t mode) { if(mode == LV_DRAW_MODE_COVER_CHECK) { @@ -321,8 +262,6 @@ static void draw_indic(lv_obj_t * obj, const lv_area_t * clip_area) { lv_bar_t * bar = (lv_bar_t *)obj; - lv_bidi_dir_t base_dir = lv_obj_get_base_dir(obj); - lv_area_t bar_coords; lv_obj_get_coords(obj, &bar_coords); @@ -414,6 +353,7 @@ static void draw_indic(lv_obj_t * obj, const lv_area_t * clip_area) anim_cur_value_x = (int32_t)((int32_t)anim_length * (bar->cur_value - bar->min_value)) / range; } + lv_bidi_dir_t base_dir = lv_obj_get_base_dir(obj); if(hor && base_dir == LV_BIDI_DIR_RTL) { /* Swap axes */ lv_coord_t * tmp; @@ -444,8 +384,6 @@ static void draw_indic(lv_obj_t * obj, const lv_area_t * clip_area) } } - /*Draw the indicator*/ - /*Do not draw a zero length indicator*/ if(!sym && indic_length_calc(&bar->indic_area) <= 1) return; @@ -466,13 +404,16 @@ static void draw_indic(lv_obj_t * obj, const lv_area_t * clip_area) if((hor && lv_area_get_width(&bar->indic_area) > bg_radius * 2) || (!hor && lv_area_get_height(&bar->indic_area) > bg_radius * 2)) { lv_opa_t bg_opa = draw_indic_dsc.bg_opa; + lv_opa_t bg_img_opa = draw_indic_dsc.bg_img_opa; lv_opa_t border_opa = draw_indic_dsc.border_opa; lv_opa_t content_opa = draw_indic_dsc.content_opa; draw_indic_dsc.bg_opa = LV_OPA_TRANSP; + draw_indic_dsc.bg_img_opa = LV_OPA_TRANSP; draw_indic_dsc.border_opa = LV_OPA_TRANSP; draw_indic_dsc.content_opa = LV_OPA_TRANSP; lv_draw_rect(&bar->indic_area, clip_area, &draw_indic_dsc); draw_indic_dsc.bg_opa = bg_opa; + draw_indic_dsc.bg_img_opa = bg_img_opa; draw_indic_dsc.border_opa = border_opa; draw_indic_dsc.content_opa = content_opa; } @@ -483,7 +424,7 @@ static void draw_indic(lv_obj_t * obj, const lv_area_t * clip_area) int16_t mask_bg_id = lv_draw_mask_add(&mask_bg_param, NULL); #endif - /*Draw_only the background and the pattern*/ + /*Draw_only the background and background image*/ lv_opa_t shadow_opa = draw_indic_dsc.shadow_opa; lv_opa_t border_opa = draw_indic_dsc.border_opa; lv_opa_t content_opa = draw_indic_dsc.content_opa; @@ -513,6 +454,7 @@ static void draw_indic(lv_obj_t * obj, const lv_area_t * clip_area) lv_draw_mask_radius_init(&mask_indic_param, &bar->indic_area, draw_indic_dsc.radius, false); int16_t mask_indic_id = lv_draw_mask_add(&mask_indic_param, NULL); #endif + lv_draw_rect(&mask_indic_max_area, clip_area, &draw_indic_dsc); draw_indic_dsc.border_opa = border_opa; draw_indic_dsc.shadow_opa = shadow_opa; @@ -520,6 +462,7 @@ static void draw_indic(lv_obj_t * obj, const lv_area_t * clip_area) /*Draw the border*/ draw_indic_dsc.bg_opa = LV_OPA_TRANSP; + draw_indic_dsc.bg_img_opa = LV_OPA_TRANSP; draw_indic_dsc.shadow_opa = LV_OPA_TRANSP; draw_indic_dsc.content_opa = LV_OPA_TRANSP; lv_draw_rect(&bar->indic_area, clip_area, &draw_indic_dsc); @@ -529,19 +472,12 @@ static void draw_indic(lv_obj_t * obj, const lv_area_t * clip_area) lv_draw_mask_remove_id(mask_bg_id); #endif - /*When not masks draw the value*/ + /*When not masks draw the content*/ draw_indic_dsc.content_opa = content_opa; draw_indic_dsc.border_opa = LV_OPA_TRANSP; lv_draw_rect(&bar->indic_area, clip_area, &draw_indic_dsc); } -/** - * Signal function of the bar - * @param bar pointer to a bar 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_bar_signal(lv_obj_t * obj, lv_signal_t sign, void * param) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); diff --git a/src/lv_widgets/lv_bar.h b/src/lv_widgets/lv_bar.h index f1153b06c..7b1e30469 100644 --- a/src/lv_widgets/lv_bar.h +++ b/src/lv_widgets/lv_bar.h @@ -26,18 +26,6 @@ extern "C" { * DEFINES *********************/ -/** Bar animation start value. (Not the real value of the Bar just indicates process animation)*/ -#define LV_BAR_ANIM_STATE_START 0 - -/** Bar animation end value. (Not the real value of the Bar just indicates process animation)*/ -#define LV_BAR_ANIM_STATE_END 256 - -/** Mark no animation is in progress */ -#define LV_BAR_ANIM_STATE_INV -1 - -/** log2(LV_BAR_ANIM_STATE_END) used to normalize data*/ -#define LV_BAR_ANIM_STATE_NORM 8 - /********************** * TYPEDEFS **********************/ @@ -45,7 +33,7 @@ extern "C" { enum { LV_BAR_TYPE_NORMAL, LV_BAR_TYPE_SYMMETRICAL, - LV_BAR_TYPE_CUSTOM + LV_BAR_TYPE_RANGE }; typedef uint8_t lv_bar_type_t; @@ -76,7 +64,7 @@ extern const lv_obj_class_t lv_bar; /** * Create a bar objects - * @param par pointer to an object, it will be the parent of the new bar + * @param parent pointer to an object, it will be the parent of the new bar * @param copy DEPRECATED, will be removed in v9. * Pointer to an other bar to copy. * @return pointer to the created bar @@ -89,34 +77,34 @@ lv_obj_t * lv_bar_create(lv_obj_t * parent, const lv_obj_t * copy); /** * Set a new value on the bar - * @param bar pointer to a bar object - * @param value new value - * @param anim LV_ANIM_ON: set the value with an animation; LV_ANIM_OFF: change the value immediately + * @param bar: pointer to a bar object + * @param value: new value + * @param anim: LV_ANIM_ON: set the value with an animation; LV_ANIM_OFF: change the value immediately */ -void lv_bar_set_value(lv_obj_t * bar, int16_t value, lv_anim_enable_t anim); +void lv_bar_set_value(lv_obj_t * obj, int16_t value, lv_anim_enable_t anim); /** * Set a new start value on the bar - * @param bar pointer to a bar object - * @param value new start value - * @param anim LV_ANIM_ON: set the value with an animation; LV_ANIM_OFF: change the value immediately + * @param obj: pointer to a bar object + * @param value: new start value + * @param anim: LV_ANIM_ON: set the value with an animation; LV_ANIM_OFF: change the value immediately */ -void lv_bar_set_start_value(lv_obj_t * bar, int16_t start_value, lv_anim_enable_t anim); +void lv_bar_set_start_value(lv_obj_t * obj, int16_t start_value, lv_anim_enable_t anim); /** * Set minimum and the maximum values of a bar - * @param bar pointer to the bar object - * @param min minimum value - * @param max maximum value + * @param obj: pointer to the bar object + * @param min: minimum value + * @param max: maximum value */ -void lv_bar_set_range(lv_obj_t * bar, int16_t min, int16_t max); +void lv_bar_set_range(lv_obj_t * obj, int16_t min, int16_t max); /** * Set the type of bar. - * @param bar pointer to bar object - * @param type bar type + * @param obj: pointer to bar object + * @param type: bar type */ -void lv_bar_set_type(lv_obj_t * bar, lv_bar_type_t type); +void lv_bar_set_type(lv_obj_t * obj, lv_bar_type_t type); /*===================== * Getter functions @@ -124,38 +112,38 @@ void lv_bar_set_type(lv_obj_t * bar, lv_bar_type_t type); /** * Get the value of a bar - * @param bar pointer to a bar object + * @param obj: pointer to a bar object * @return the value of the bar */ -int16_t lv_bar_get_value(const lv_obj_t * bar); +int16_t lv_bar_get_value(const lv_obj_t * obj); /** * Get the start value of a bar - * @param bar pointer to a bar object + * @param obj: pointer to a bar object * @return the start value of the bar */ -int16_t lv_bar_get_start_value(const lv_obj_t * bar); +int16_t lv_bar_get_start_value(const lv_obj_t * obj); /** * Get the minimum value of a bar - * @param bar pointer to a bar object + * @param obj: pointer to a bar object * @return the minimum value of the bar */ -int16_t lv_bar_get_min_value(const lv_obj_t * bar); +int16_t lv_bar_get_min_value(const lv_obj_t * obj); /** * Get the maximum value of a bar - * @param bar pointer to a bar object + * @param obj: pointer to a bar object * @return the maximum value of the bar */ -int16_t lv_bar_get_max_value(const lv_obj_t * bar); +int16_t lv_bar_get_max_value(const lv_obj_t * obj); /** * Get the type of bar. - * @param bar pointer to bar object + * @param obj: pointer to bar object * @return bar type */ -lv_bar_type_t lv_bar_get_type(lv_obj_t * bar); +lv_bar_type_t lv_bar_get_type(lv_obj_t * obj); /********************** * MACROS diff --git a/src/lv_widgets/lv_btn.c b/src/lv_widgets/lv_btn.c index 32e96728b..3a367a648 100644 --- a/src/lv_widgets/lv_btn.c +++ b/src/lv_widgets/lv_btn.c @@ -39,7 +39,6 @@ const lv_obj_class_t lv_btn = { .base_class = &lv_obj }; - /********************** * MACROS **********************/ @@ -48,27 +47,12 @@ const lv_obj_class_t lv_btn = { * GLOBAL FUNCTIONS **********************/ -/** - * Create a button object - * @param parent pointer to an object, it will be the parent of the new button - * @param copy DEPRECATED, will be removed in v9. - * Pointer to an other button to copy. - * @return pointer to the created button - */ lv_obj_t * lv_btn_create(lv_obj_t * parent, const lv_obj_t * copy) { LV_LOG_TRACE("button create started"); return lv_obj_create_from_class(&lv_btn, parent, copy); } -/*===================== - * Setter functions - *====================*/ - -/*===================== - * Getter functions - *====================*/ - /********************** * STATIC FUNCTIONS **********************/ @@ -87,16 +71,9 @@ static void lv_btn_constructor(lv_obj_t * obj, lv_obj_t * parent, const lv_obj_t static void lv_btn_destructor(lv_obj_t * obj) { -// lv_bar_t * bar = obj; -// -// _lv_obj_reset_style_list_no_refr(obj, LV_BAR_PART_INDIC); -//#if LV_USE_ANIMATION -// lv_anim_del(&bar->cur_value_anim, NULL); -// lv_anim_del(&bar->start_value_anim, NULL); -//#endif -// lv_btn.base_p->destructor(obj); } + static lv_draw_res_t lv_btn_draw(lv_obj_t * obj, const lv_area_t * clip_area, lv_draw_mode_t mode) { return lv_obj.draw_cb(obj, clip_area, mode); diff --git a/src/lv_widgets/lv_btn.h b/src/lv_widgets/lv_btn.h index abd618cb6..0c27573e7 100644 --- a/src/lv_widgets/lv_btn.h +++ b/src/lv_widgets/lv_btn.h @@ -32,33 +32,24 @@ typedef struct { extern const lv_obj_class_t lv_btn; - /********************** * GLOBAL PROTOTYPES **********************/ /** * Create a button object - * @param parent pointer to an object, it will be the parent of the new button - * @param copy DEPRECATED, will be removed in v9. - * Pointer to an other button to copy. - * @return pointer to the created button + * @param parent pointer to an object, it will be the parent of the new button + * @param copy DEPRECATED, will be removed in v9. + * Pointer to an other button to copy. + * @return pointer to the created button */ lv_obj_t * lv_btn_create(lv_obj_t * parent, const lv_obj_t * copy); -/*===================== - * Setter functions - *====================*/ - -/*===================== - * Getter functions - *====================*/ - /********************** * MACROS **********************/ -#endif /*LV_USE_BUTTON*/ +#endif /*LV_USE_BTN*/ #ifdef __cplusplus } /* extern "C" */ diff --git a/src/lv_widgets/lv_btnmatrix.c b/src/lv_widgets/lv_btnmatrix.c index e1a649078..e43f7e6b4 100644 --- a/src/lv_widgets/lv_btnmatrix.c +++ b/src/lv_widgets/lv_btnmatrix.c @@ -1,5 +1,5 @@ /** - * @file lv_obj.c + * @file lv_btnmatrix.c * */ @@ -22,6 +22,7 @@ *********************/ #define LV_OBJX_NAME "lv_btnmatrix" #define BTN_EXTRA_CLICK_AREA_MAX (LV_DPI / 4) +#define LV_BTNMATRIX_WIDTH_MASK 0x0007 /********************** * TYPEDEFS @@ -71,29 +72,15 @@ const lv_obj_class_t lv_btnmatrix = { * GLOBAL FUNCTIONS **********************/ -/** - * Create a button matrix objects - * @param par pointer to an object, it will be the parent of the new button matrix - * @param copy pointer to a button matrix object, if not NULL then the new object will be copied - * from it - * @return pointer to the created button matrix - */ lv_obj_t * lv_btnmatrix_create(lv_obj_t * parent, const lv_obj_t * copy) { - return lv_obj_create_from_class(&lv_btnmatrix, parent, copy); + return lv_obj_create_from_class(&lv_btnmatrix, parent, copy); } /*===================== * Setter functions *====================*/ -/** - * Set a new map. Buttons will be created/deleted according to the map. The - * button matrix keeps a reference to the map and so the string array must not - * be deallocated during the life of the matrix. - * @param obj pointer to a button matrix object - * @param map pointer a string array. The last string has to be: "". Use "\n" to make a line break. - */ void lv_btnmatrix_set_map(lv_obj_t * obj, const char * map[]) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); @@ -184,18 +171,6 @@ void lv_btnmatrix_set_map(lv_obj_t * obj, const char * map[]) lv_obj_invalidate(obj); } -/** - * Set the button control map (hidden, disabled etc.) for a button matrix. The - * control map array will be copied and so may be deallocated after this - * function returns. - * @param obj pointer to a button matrix object - * @param ctrl_map pointer to an array of `lv_btn_ctrl_t` control bytes. The - * length of the array and position of the elements must match - * the number and order of the individual buttons (i.e. excludes - * newline entries). - * An element of the map should look like e.g.: - * `ctrl_map[0] = width | LV_BTNMATRIX_CTRL_NO_REPEAT | LV_BTNMATRIX_CTRL_TGL_ENABLE` - */ void lv_btnmatrix_set_ctrl_map(lv_obj_t * obj, const lv_btnmatrix_ctrl_t ctrl_map[]) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); @@ -206,11 +181,6 @@ void lv_btnmatrix_set_ctrl_map(lv_obj_t * obj, const lv_btnmatrix_ctrl_t ctrl_ma lv_btnmatrix_set_map(obj, btnm->map_p); } -/** - * Set the focused button i.e. visually highlight it. - * @param obj pointer to button matrix object - * @param id index of the button to focus(`LV_BTNMATRIX_BTN_NONE` to remove focus) - */ void lv_btnmatrix_set_focused_btn(lv_obj_t * obj, uint16_t id) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); @@ -225,11 +195,6 @@ void lv_btnmatrix_set_focused_btn(lv_obj_t * obj, uint16_t id) lv_obj_invalidate(obj); } -/** - * Enable recoloring of button's texts - * @param obj pointer to button matrix object - * @param en true: enable recoloring; false: disable - */ void lv_btnmatrix_set_recolor(const lv_obj_t * obj, bool en) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); @@ -240,11 +205,6 @@ void lv_btnmatrix_set_recolor(const lv_obj_t * obj, bool en) lv_obj_invalidate(obj); } -/** - * Set the attributes of a button of the button matrix - * @param obj pointer to button matrix object - * @param btn_id 0 based index of the button to modify. (Not counting new lines) - */ void lv_btnmatrix_set_btn_ctrl(lv_obj_t * obj, uint16_t btn_id, lv_btnmatrix_ctrl_t ctrl) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); @@ -261,11 +221,6 @@ void lv_btnmatrix_set_btn_ctrl(lv_obj_t * obj, uint16_t btn_id, lv_btnmatrix_ctr invalidate_button_area(obj, btn_id); } -/** - * Clear the attributes of a button of the button matrix - * @param obj pointer to button matrix object - * @param btn_id 0 based index of the button to modify. (Not counting new lines) - */ void lv_btnmatrix_clear_btn_ctrl(const lv_obj_t * obj, uint16_t btn_id, lv_btnmatrix_ctrl_t ctrl) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); @@ -278,11 +233,6 @@ void lv_btnmatrix_clear_btn_ctrl(const lv_obj_t * obj, uint16_t btn_id, lv_btnma invalidate_button_area(obj, btn_id); } -/** - * Set the attributes of all buttons of a button matrix - * @param obj pointer to a button matrix object - * @param ctrl attribute(s) to set from `lv_btnmatrix_ctrl_t`. Values can be ORed. - */ void lv_btnmatrix_set_btn_ctrl_all(lv_obj_t * obj, lv_btnmatrix_ctrl_t ctrl) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); @@ -294,12 +244,6 @@ void lv_btnmatrix_set_btn_ctrl_all(lv_obj_t * obj, lv_btnmatrix_ctrl_t ctrl) } } -/** - * Clear the attributes of all buttons of a button matrix - * @param obj pointer to a button matrix object - * @param ctrl attribute(s) to set from `lv_btnmatrix_ctrl_t`. Values can be ORed. - * @param en true: set the attributes; false: clear the attributes - */ void lv_btnmatrix_clear_btn_ctrl_all(lv_obj_t * obj, lv_btnmatrix_ctrl_t ctrl) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); @@ -311,15 +255,6 @@ void lv_btnmatrix_clear_btn_ctrl_all(lv_obj_t * obj, lv_btnmatrix_ctrl_t ctrl) } } -/** - * Set a single buttons relative width. - * This method will cause the matrix be regenerated and is a relatively - * expensive operation. It is recommended that initial width be specified using - * `lv_btnmatrix_set_ctrl_map` and this method only be used for dynamic changes. - * @param obj pointer to button matrix object - * @param btn_id 0 based index of the button to modify. - * @param width Relative width compared to the buttons in the same row. [1..7] - */ void lv_btnmatrix_set_btn_width(lv_obj_t * obj, uint16_t btn_id, uint8_t width) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); @@ -332,19 +267,12 @@ void lv_btnmatrix_set_btn_width(lv_obj_t * obj, uint16_t btn_id, uint8_t width) lv_btnmatrix_set_map(obj, btnm->map_p); } -/** - * Make the button matrix like a selector widget (only one button may be checked at a time). - * `Checkable` must be enabled on the buttons you want to be selected with `lv_btnmatrix_set_ctrl` or - * `lv_btnmatrix_set_btn_ctrl_all`. - * @param obj pointer to a button matrix object - * @param one_chk whether "one check" mode is enabled - */ -void lv_btnmatrix_set_one_checked(lv_obj_t * obj, bool one_chk) +void lv_btnmatrix_set_one_checked(lv_obj_t * obj, bool en) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); lv_btnmatrix_t * btnm = (lv_btnmatrix_t *)obj;; - btnm->one_check = one_chk; + btnm->one_check = en; /*If more than one button is toggled only the first one should be*/ make_one_button_checked(obj, 0); @@ -354,12 +282,7 @@ void lv_btnmatrix_set_one_checked(lv_obj_t * obj, bool one_chk) * Getter functions *====================*/ -/** - * Get the current map of a button matrix - * @param obj pointer to a button matrix object - * @return the current map - */ -const char ** lv_btnmatrix_get_map_array(const lv_obj_t * obj) +const char ** lv_btnmatrix_get_map(const lv_obj_t * obj) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); @@ -367,11 +290,6 @@ const char ** lv_btnmatrix_get_map_array(const lv_obj_t * obj) return btnm->map_p; } -/** - * Check whether the button's text can use recolor or not - * @param obj pointer to button matrix object - * @return true: text recolor enable; false: disabled - */ bool lv_btnmatrix_get_recolor(const lv_obj_t * obj) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); @@ -381,17 +299,6 @@ bool lv_btnmatrix_get_recolor(const lv_obj_t * obj) return btnm->recolor; } -/** - * Get the index of the lastly "activated" button by the user (pressed, released etc) -<<<<<<< HEAD - * Useful in the the `event_cb` to get the text of the button, check if hidden etc. - * @param obj pointer to button matrix object -======= - * Useful in the `event_cb` to get the text of the button, check if hidden etc. - * @param btnm pointer to button matrix object ->>>>>>> master - * @return index of the last released button (LV_BTNMATRIX_BTN_NONE: if unset) - */ uint16_t lv_btnmatrix_get_active_btn(const lv_obj_t * obj) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); @@ -400,36 +307,15 @@ uint16_t lv_btnmatrix_get_active_btn(const lv_obj_t * obj) return btnm->btn_id_act; } -/** - * Get the text of the lastly "activated" button by the user (pressed, released etc) -<<<<<<< HEAD - * Useful in the the `event_cb` - * @param obj pointer to button matrix object -======= - * Useful in the `event_cb` - * @param btnm pointer to button matrix object ->>>>>>> master - * @return text of the last released button (NULL: if unset) - */ -const char * lv_btnmatrix_get_active_btn_text(const lv_obj_t * obj) +uint16_t lv_btnmatrix_get_pressed_btn(const lv_obj_t * obj) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); lv_btnmatrix_t * btnm = (lv_btnmatrix_t *)obj;; - if(btnm->btn_id_act != LV_BTNMATRIX_BTN_NONE) { - return lv_btnmatrix_get_btn_text(obj, btnm->btn_id_act); - } - else { - return NULL; - } + return btnm->btn_id_pr; } -/** - * Get the pressed button's index. - * The button be really pressed by the user or manually set to pressed with `lv_btnmatrix_set_pressed` - * @param obj pointer to button matrix object - * @return index of the pressed button (LV_BTNMATRIX_BTN_NONE: if unset) - */ + uint16_t lv_btnmatrix_get_focused_btn(const lv_obj_t * obj) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); @@ -438,18 +324,13 @@ uint16_t lv_btnmatrix_get_focused_btn(const lv_obj_t * obj) return btnm->btn_id_focused; } -/** - * Get the button's text - * @param obj pointer to button matrix object - * @param btn_id the index a button not counting new line characters. (The return value of - * lv_btnmatrix_get_pressed/released) - * @return text of btn_index` button - */ const char * lv_btnmatrix_get_btn_text(const lv_obj_t * obj, uint16_t btn_id) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); - lv_btnmatrix_t * btnm = (lv_btnmatrix_t *)obj;; + if(btn_id == LV_BTNMATRIX_BTN_NONE) return NULL; + + lv_btnmatrix_t * btnm = (lv_btnmatrix_t *)obj; if(btn_id > btnm->btn_cnt) return NULL; uint16_t txt_i = 0; @@ -468,15 +349,7 @@ const char * lv_btnmatrix_get_btn_text(const lv_obj_t * obj, uint16_t btn_id) return btnm->map_p[txt_i]; } -/** - * Get the whether a control value is enabled or disabled for button of a button matrix - * @param obj pointer to a button matrix object - * @param btn_id the index a button not counting new line characters. (E.g. the return value of - * lv_btnmatrix_get_pressed/released) - * @param ctrl control values to check (ORed value can be used) - * @return true: long press repeat is disabled; false: long press repeat enabled - */ -bool lv_btnmatrix_get_btn_ctrl(lv_obj_t * obj, uint16_t btn_id, lv_btnmatrix_ctrl_t ctrl) +bool lv_btnmatrix_has_btn_ctrl(lv_obj_t * obj, uint16_t btn_id, lv_btnmatrix_ctrl_t ctrl) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); @@ -486,11 +359,6 @@ bool lv_btnmatrix_get_btn_ctrl(lv_obj_t * obj, uint16_t btn_id, lv_btnmatrix_ctr return (btnm->ctrl_bits[btn_id] & ctrl) ? true : false; } -/** - * Find whether "one check" mode is enabled. - * @param obj Button matrix object - * @return whether "one check" mode is enabled - */ bool lv_btnmatrix_get_one_checked(const lv_obj_t * obj) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); @@ -537,10 +405,13 @@ static void lv_btnmatrix_constructor(lv_obj_t * obj, lv_obj_t * parent, const lv static void lv_btnmatrix_destructor(lv_obj_t * obj) { - -// lv_mem_free(btnm->button_areas); -// lv_mem_free(btnm->ctrl_bits); + lv_btnmatrix_t * btnm = (lv_btnmatrix_t *)obj; + lv_mem_free(btnm->button_areas); + lv_mem_free(btnm->ctrl_bits); + btnm->button_areas = NULL; + btnm->ctrl_bits = NULL; } + /** * Handle the drawing related tasks of the button matrix * @param obj pointer to a button matrix object @@ -584,10 +455,10 @@ static lv_draw_res_t lv_btnmatrix_draw(lv_obj_t * obj, const lv_area_t * clip_ar lv_state_t state_ori = obj->state; obj->state = LV_STATE_DEFAULT; obj->style_list.skip_trans = 1; - lv_draw_rect_dsc_init(&draw_rect_dsc_act); - lv_draw_label_dsc_init(&draw_label_dsc_act); - lv_obj_init_draw_rect_dsc(obj, LV_PART_ITEMS, &draw_rect_dsc_act); - lv_obj_init_draw_label_dsc(obj, LV_PART_ITEMS, &draw_label_dsc_act); + lv_draw_rect_dsc_init(&draw_rect_def_default); + lv_draw_label_dsc_init(&draw_label_def_default); + lv_obj_init_draw_rect_dsc(obj, LV_PART_ITEMS, &draw_rect_def_default); + lv_obj_init_draw_label_dsc(obj, LV_PART_ITEMS, &draw_label_def_default); draw_label_dsc_act.flag |= recolor_flag; obj->style_list.skip_trans = 0; obj->state = state_ori; @@ -634,14 +505,6 @@ static lv_draw_res_t lv_btnmatrix_draw(lv_obj_t * obj, const lv_area_t * clip_ar btn_area.x2 += area_obj.x1; btn_area.y2 += area_obj.y1; - /*Use the custom draw if any*/ - if(btnm->custom_draw_cb) { - obj->state = btn_state; - bool drawn = btnm->custom_draw_cb(obj, btn_i, &btn_area, clip_area); - obj->state = state_ori; - if(drawn) continue; - } - /*Set up the draw descriptors*/ if(btn_state == LV_STATE_DEFAULT) { lv_memcpy(&draw_rect_dsc_act, &draw_rect_def_default, sizeof(lv_draw_rect_dsc_t)); @@ -650,12 +513,14 @@ static lv_draw_res_t lv_btnmatrix_draw(lv_obj_t * obj, const lv_area_t * clip_ar /*In other cases get the styles directly without caching them*/ else { obj->state = btn_state; + obj->style_list.skip_trans = 1; lv_draw_rect_dsc_init(&draw_rect_dsc_act); lv_draw_label_dsc_init(&draw_label_dsc_act); lv_obj_init_draw_rect_dsc(obj, LV_PART_ITEMS, &draw_rect_dsc_act); lv_obj_init_draw_label_dsc(obj, LV_PART_ITEMS, &draw_label_dsc_act); draw_label_dsc_act.flag = recolor_flag; obj->state = state_ori; + obj->style_list.skip_trans = 0; } hook_dsc.draw_area = &btn_area; @@ -689,7 +554,7 @@ static lv_draw_res_t lv_btnmatrix_draw(lv_obj_t * obj, const lv_area_t * clip_ar #endif lv_point_t txt_size; - _lv_txt_get_size(&txt_size, txt, font, letter_space, + lv_txt_get_size(&txt_size, txt, font, letter_space, line_space, lv_area_get_width(&area_obj), recolor_flag); btn_area.x1 += (lv_area_get_width(&btn_area) - txt_size.x) / 2; @@ -1148,7 +1013,7 @@ static void invalidate_button_area(const lv_obj_t * obj, uint16_t btn_idx) static void make_one_button_checked(lv_obj_t * obj, uint16_t btn_idx) { /*Save whether the button was toggled*/ - bool was_toggled = lv_btnmatrix_get_btn_ctrl(obj, btn_idx, LV_BTNMATRIX_CTRL_CHECKED); + bool was_toggled = lv_btnmatrix_has_btn_ctrl(obj, btn_idx, LV_BTNMATRIX_CTRL_CHECKED); lv_btnmatrix_clear_btn_ctrl_all(obj, LV_BTNMATRIX_CTRL_CHECKED); diff --git a/src/lv_widgets/lv_btnmatrix.h b/src/lv_widgets/lv_btnmatrix.h index 5952b7c77..ae10e81d8 100644 --- a/src/lv_widgets/lv_btnmatrix.h +++ b/src/lv_widgets/lv_btnmatrix.h @@ -24,9 +24,7 @@ extern "C" { /********************* * DEFINES *********************/ -#define LV_BTNMATRIX_WIDTH_MASK 0x0007 #define LV_BTNMATRIX_BTN_NONE 0xFFFF - LV_EXPORT_CONST_INT(LV_BTNMATRIX_BTN_NONE); /********************** @@ -53,7 +51,6 @@ typedef struct { const char ** map_p; /*Pointer to the current map*/ lv_area_t * button_areas; /*Array of areas of buttons*/ lv_btnmatrix_ctrl_t * ctrl_bits; /*Array of control bytes*/ - lv_btnmatrix_btn_draw_cb_t custom_draw_cb; uint16_t btn_cnt; /*Number of button in 'map_p'(Handled by the library)*/ uint16_t btn_id_pr; /*Index of the currently pressed button or LV_BTNMATRIX_BTN_NONE*/ uint16_t btn_id_focused; /*Index of the currently focused button or LV_BTNMATRIX_BTN_NONE*/ @@ -71,12 +68,12 @@ extern const lv_obj_class_t lv_btnmatrix; /** * Create a button matrix objects - * @param par pointer to an object, it will be the parent of the new button matrix - * @param copy pointer to a button matrix object, if not NULL then the new object will be copied - * from it - * @return pointer to the created button matrix + * @param parent pointer to an object, it will be the parent of the new button matrix + * @param copy DEPRECATED, will be removed in v9. + * Pointer to an other button matrix to copy. + * @return pointer to the created button matrix */ -lv_obj_t * lv_btnmatrix_create(lv_obj_t * par, const lv_obj_t * copy); +lv_obj_t * lv_btnmatrix_create(lv_obj_t * parent, const lv_obj_t * copy); /*===================== * Setter functions @@ -86,87 +83,88 @@ lv_obj_t * lv_btnmatrix_create(lv_obj_t * par, const lv_obj_t * copy); * Set a new map. Buttons will be created/deleted according to the map. The * button matrix keeps a reference to the map and so the string array must not * be deallocated during the life of the matrix. - * @param btnm pointer to a button matrix object - * @param map pointer a string array. The last string has to be: "". Use "\n" to make a line break. + * @param obj pointer to a button matrix object + * @param map pointer a string array. The last string has to be: "". Use "\n" to make a line break. */ -void lv_btnmatrix_set_map(lv_obj_t * btnm, const char * map[]); +void lv_btnmatrix_set_map(lv_obj_t * obj, const char * map[]); /** - * Set the button control map (hidden, disabled etc.) for a button matrix. The - * control map array will be copied and so may be deallocated after this + * Set the button control map (hidden, disabled etc.) for a button matrix. + * The control map array will be copied and so may be deallocated after this * function returns. - * @param btnm pointer to a button matrix object - * @param ctrl_map pointer to an array of `lv_btn_ctrl_t` control bytes. The - * length of the array and position of the elements must match - * the number and order of the individual buttons (i.e. excludes - * newline entries). - * An element of the map should look like e.g.: + * @param obj pointer to a button matrix object + * @param ctrl_map pointer to an array of `lv_btn_ctrl_t` control bytes. The + * length of the array and position of the elements must match + * the number and order of the individual buttons (i.e. excludes + * newline entries). + * An element of the map should look like e.g.: * `ctrl_map[0] = width | LV_BTNMATRIX_CTRL_NO_REPEAT | LV_BTNMATRIX_CTRL_TGL_ENABLE` */ -void lv_btnmatrix_set_ctrl_map(lv_obj_t * btnm, const lv_btnmatrix_ctrl_t ctrl_map[]); +void lv_btnmatrix_set_ctrl_map(lv_obj_t * obj, const lv_btnmatrix_ctrl_t ctrl_map[]); /** * Set the focused button i.e. visually highlight it. - * @param btnm pointer to button matrix object - * @param id index of the button to focus(`LV_BTNMATRIX_BTN_NONE` to remove focus) + * @param obj pointer to button matrix object + * @param id index of the button to focus(`LV_BTNMATRIX_BTN_NONE` to remove focus) */ -void lv_btnmatrix_set_focused_btn(lv_obj_t * btnm, uint16_t id); +void lv_btnmatrix_set_focused_btn(lv_obj_t * obj, uint16_t id); /** - * Enable recoloring of button's texts - * @param btnm pointer to button matrix object - * @param en true: enable recoloring; false: disable + * Enable recoloring of button's texts. E.g. "a #ff0000 red# word" + * @param obj pointer to button matrix object + * @param en true: enable recoloring; false: disable */ -void lv_btnmatrix_set_recolor(const lv_obj_t * btnm, bool en); - +void lv_btnmatrix_set_recolor(const lv_obj_t * obj, bool en); /** * Set the attributes of a button of the button matrix - * @param btnm pointer to button matrix object - * @param btn_id 0 based index of the button to modify. (Not counting new lines) + * @param obj pointer to button matrix object + * @param btn_id 0 based index of the button to modify. (Not counting new lines) + * @param ctrl OR-ed attributs. E.g. `LV_BTNMATRIX_CTRL_NO_REPEAT | LV_BTNMATRIX_CTRL_CHECKABLE` */ -void lv_btnmatrix_set_btn_ctrl(lv_obj_t * btnm, uint16_t btn_id, lv_btnmatrix_ctrl_t ctrl); +void lv_btnmatrix_set_btn_ctrl(lv_obj_t * obj, uint16_t btn_id, lv_btnmatrix_ctrl_t ctrl); /** * Clear the attributes of a button of the button matrix - * @param btnm pointer to button matrix object - * @param btn_id 0 based index of the button to modify. (Not counting new lines) + * @param obj pointer to button matrix object + * @param btn_id 0 based index of the button to modify. (Not counting new lines) + * @param ctrl OR-ed attributs. E.g. `LV_BTNMATRIX_CTRL_NO_REPEAT | LV_BTNMATRIX_CTRL_CHECKABLE` */ -void lv_btnmatrix_clear_btn_ctrl(const lv_obj_t * btnm, uint16_t btn_id, lv_btnmatrix_ctrl_t ctrl); +void lv_btnmatrix_clear_btn_ctrl(const lv_obj_t * obj, uint16_t btn_id, lv_btnmatrix_ctrl_t ctrl); /** - * Set the attributes of all buttons of a button matrix - * @param btnm pointer to a button matrix object - * @param ctrl attribute(s) to set from `lv_btnmatrix_ctrl_t`. Values can be ORed. + * Set attributes of all buttons of a button matrix + * @param obj pointer to a button matrix object + * @param ctrl attribute(s) to set from `lv_btnmatrix_ctrl_t`. Values can be ORed. */ -void lv_btnmatrix_set_btn_ctrl_all(lv_obj_t * btnm, lv_btnmatrix_ctrl_t ctrl); +void lv_btnmatrix_set_btn_ctrl_all(lv_obj_t * obj, lv_btnmatrix_ctrl_t ctrl); /** * Clear the attributes of all buttons of a button matrix - * @param btnm pointer to a button matrix object - * @param ctrl attribute(s) to set from `lv_btnmatrix_ctrl_t`. Values can be ORed. - * @param en true: set the attributes; false: clear the attributes + * @param obj pointer to a button matrix object + * @param ctrl attribute(s) to set from `lv_btnmatrix_ctrl_t`. Values can be ORed. + * @param en true: set the attributes; false: clear the attributes */ -void lv_btnmatrix_clear_btn_ctrl_all(lv_obj_t * btnm, lv_btnmatrix_ctrl_t ctrl); +void lv_btnmatrix_clear_btn_ctrl_all(lv_obj_t * obj, lv_btnmatrix_ctrl_t ctrl); /** - * Set a single buttons relative width. + * Set a single button's relative width. * This method will cause the matrix be regenerated and is a relatively * expensive operation. It is recommended that initial width be specified using * `lv_btnmatrix_set_ctrl_map` and this method only be used for dynamic changes. - * @param btnm pointer to button matrix object - * @param btn_id 0 based index of the button to modify. - * @param width Relative width compared to the buttons in the same row. [1..7] + * @param obj pointer to button matrix object + * @param btn_id 0 based index of the button to modify. + * @param width relative width compared to the buttons in the same row. [1..7] */ -void lv_btnmatrix_set_btn_width(lv_obj_t * btnm, uint16_t btn_id, uint8_t width); +void lv_btnmatrix_set_btn_width(lv_obj_t * obj, uint16_t btn_id, uint8_t width); /** * Make the button matrix like a selector widget (only one button may be checked at a time). - * `Checkable` must be enabled on the buttons you want to be selected with `lv_btnmatrix_set_ctrl` or - * `lv_btnmatrix_set_btn_ctrl_all`. - * @param btnm pointer to a button matrix object - * @param one_chk whether "one check" mode is enabled + * `LV_BTNMATRIX_CTRL_CHECKABLE` must be enabled on the buttons to be selected useing + * `lv_btnmatrix_set_ctrl()` or `lv_btnmatrix_set_btn_ctrl_all()`. + * @param obj pointer to a button matrix object + * @param en: whether "one check" mode is enabled */ -void lv_btnmatrix_set_one_checked(lv_obj_t * btnm, bool one_chk); +void lv_btnmatrix_set_one_checked(lv_obj_t * obj, bool en); /*===================== * Getter functions @@ -174,66 +172,65 @@ void lv_btnmatrix_set_one_checked(lv_obj_t * btnm, bool one_chk); /** * Get the current map of a button matrix - * @param btnm pointer to a button matrix object - * @return the current map + * @param obj pointer to a button matrix object + * @return the current map */ -const char ** lv_btnmatrix_get_map_array(const lv_obj_t * btnm); +const char ** lv_btnmatrix_get_map(const lv_obj_t * obj); /** * Check whether the button's text can use recolor or not - * @param btnm pointer to button matrix object - * @return true: text recolor enable; false: disabled + * @param obj pointer to button matrix object + * @return true: text recolor enable; false: disabled */ -bool lv_btnmatrix_get_recolor(const lv_obj_t * btnm); +bool lv_btnmatrix_get_recolor(const lv_obj_t * obj); /** * Get the index of the lastly "activated" button by the user (pressed, released etc) - * Useful in the `event_cb` to get the text of the button, check if hidden etc. - * @param btnm pointer to button matrix object - * @return index of the last released button (LV_BTNMATRIX_BTN_NONE: if unset) + * Useful in the the `event_cb` to get the text of the button, check if hidden etc. + * @param obj pointer to button matrix object + * @return index of the last released button (LV_BTNMATRIX_BTN_NONE: if unset) */ -uint16_t lv_btnmatrix_get_active_btn(const lv_obj_t * btnm); +uint16_t lv_btnmatrix_get_active_btn(const lv_obj_t * obj); /** - * Get the text of the lastly "activated" button by the user (pressed, released etc) - * Useful in the `event_cb` - * @param btnm pointer to button matrix object - * @return text of the last released button (NULL: if unset) + * Get the index of the button being pressed button. + * Useful in the the `event_cb` to get the text of the button, check if hidden etc. + * @param obj pointer to button matrix object + * @return index of the last released button (LV_BTNMATRIX_BTN_NONE: if unset) */ -const char * lv_btnmatrix_get_active_btn_text(const lv_obj_t * btnm); +uint16_t lv_btnmatrix_get_pressed_btn(const lv_obj_t * obj); /** * Get the focused button's index. - * @param btnm pointer to button matrix object - * @return index of the focused button (LV_BTNMATRIX_BTN_NONE: if unset) + * @param obj pointer to button matrix object + * @return index of the focused button (LV_BTNMATRIX_BTN_NONE: if unset) */ -uint16_t lv_btnmatrix_get_focused_btn(const lv_obj_t * btnm); +uint16_t lv_btnmatrix_get_focused_btn(const lv_obj_t * obj); /** * Get the button's text - * @param btnm pointer to button matrix object - * @param btn_id the index a button not counting new line characters. (The return value of - * lv_btnmatrix_get_pressed/released) - * @return text of btn_index` button + * @param obj pointer to button matrix object + * @param btn_id the index a button not counting new line characters. + * (The return value of lv_btnmatrix_get_active/pressed/released) + * @return text of btn_index` button */ -const char * lv_btnmatrix_get_btn_text(const lv_obj_t * btnm, uint16_t btn_id); +const char * lv_btnmatrix_get_btn_text(const lv_obj_t * obj, uint16_t btn_id); /** * Get the whether a control value is enabled or disabled for button of a button matrix - * @param btnm pointer to a button matrix object - * @param btn_id the index a button not counting new line characters. (E.g. the return value of - * lv_btnmatrix_get_active) - * @param ctrl control values to check (ORed value can be used) - * @return true: long press repeat is disabled; false: long press repeat enabled + * @param obj pointer to a button matrix object + * @param btn_id the index of a button not counting new line characters. + * @param ctrl control values to check (ORed value can be used) + * @return true: the control attribute is enabled false: disabled */ -bool lv_btnmatrix_get_btn_ctrl(lv_obj_t * btnm, uint16_t btn_id, lv_btnmatrix_ctrl_t ctrl); +bool lv_btnmatrix_has_btn_ctrl(lv_obj_t * obj, uint16_t btn_id, lv_btnmatrix_ctrl_t ctrl); /** - * Find whether "one checked" mode is enabled. - * @param btnm Button matrix object - * @return whether "one checked" mode is enabled + * Tell whether "one check" mode is enabled or not. + * @param obj Button matrix object + * @return true: "one check" mode is enabled; false: disabled */ -bool lv_btnmatrix_get_one_checked(const lv_obj_t * btnm); +bool lv_btnmatrix_get_one_checked(const lv_obj_t * obj); /********************** diff --git a/src/lv_widgets/lv_canvas.c b/src/lv_widgets/lv_canvas.c index 1d4f7bd46..82ec35c50 100644 --- a/src/lv_widgets/lv_canvas.c +++ b/src/lv_widgets/lv_canvas.c @@ -12,7 +12,6 @@ #include "../lv_misc/lv_math.h" #include "../lv_draw/lv_draw.h" #include "../lv_core/lv_refr.h" -#include "../lv_themes/lv_theme.h" #if LV_USE_CANVAS != 0 @@ -72,12 +71,6 @@ const lv_obj_class_t lv_canvas = { * GLOBAL FUNCTIONS **********************/ -/** - * Create a canvas object - * @param par pointer to an object, it will be the parent of the new canvas - * @param copy pointer to a canvas object, if not NULL then the new object will be copied from it - * @return pointer to the created canvas - */ lv_obj_t * lv_canvas_create(lv_obj_t * parent, const lv_obj_t * copy) { return lv_obj_create_from_class(&lv_canvas, parent, copy); @@ -87,20 +80,6 @@ lv_obj_t * lv_canvas_create(lv_obj_t * parent, const lv_obj_t * copy) * Setter functions *====================*/ -/** - * Set a buffer for the canvas. - * @param buf a buffer where the content of the canvas will be. - * The required size is (lv_img_color_format_get_px_size(cf) * w * h) / 8) - * It can be allocated with `lv_mem_alloc()` or - * it can be statically allocated array (e.g. static lv_color_t buf[100*50]) or - * it can be an address in RAM or external SRAM - * @param canvas pointer to a canvas object - * @param w width of the canvas - * @param h height of the canvas - * @param cf color format. The following formats are supported: - * LV_IMG_CF_TRUE_COLOR, LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED, LV_IMG_CF_INDEXES_1/2/4/8BIT - * - */ void lv_canvas_set_buffer(lv_obj_t * obj, void * buf, lv_coord_t w, lv_coord_t h, lv_img_cf_t cf) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); @@ -116,13 +95,6 @@ void lv_canvas_set_buffer(lv_obj_t * obj, void * buf, lv_coord_t w, lv_coord_t h lv_img_set_src(obj, &canvas->dsc); } -/** - * Set the color of a pixel on the canvas - * @param canvas pointer to canvas object - * @param x x coordinate of the point to set - * @param y x coordinate of the point to set - * @param c color of the point - */ void lv_canvas_set_px(lv_obj_t * obj, lv_coord_t x, lv_coord_t y, lv_color_t c) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); @@ -133,16 +105,6 @@ void lv_canvas_set_px(lv_obj_t * obj, lv_coord_t x, lv_coord_t y, lv_color_t c) lv_obj_invalidate(obj); } -/** - * Set the palette color of a canvas with index format. Valid only for `LV_IMG_CF_INDEXED1/2/4/8` - * @param canvas pointer to canvas object - * @param id the palette color to set: - * - for `LV_IMG_CF_INDEXED1`: 0..1 - * - for `LV_IMG_CF_INDEXED2`: 0..3 - * - for `LV_IMG_CF_INDEXED4`: 0..15 - * - for `LV_IMG_CF_INDEXED8`: 0..255 - * @param c the color to set - */ void lv_canvas_set_palette(lv_obj_t * obj, uint8_t id, lv_color_t c) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); @@ -157,13 +119,6 @@ void lv_canvas_set_palette(lv_obj_t * obj, uint8_t id, lv_color_t c) * Getter functions *====================*/ -/** - * Get the color of a pixel on the canvas - * @param canvas - * @param x x coordinate of the point to set - * @param y x coordinate of the point to set - * @return color of the point - */ lv_color_t lv_canvas_get_px(lv_obj_t * obj, lv_coord_t x, lv_coord_t y) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); @@ -174,11 +129,6 @@ lv_color_t lv_canvas_get_px(lv_obj_t * obj, lv_coord_t x, lv_coord_t y) return lv_img_buf_get_px_color(&canvas->dsc, x, y, color); } -/** - * Get the image of the canvas as a pointer to an `lv_img_dsc_t` variable. - * @param canvas pointer to a canvas object - * @return pointer to the image descriptor. - */ lv_img_dsc_t * lv_canvas_get_img(lv_obj_t * obj) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); @@ -191,16 +141,6 @@ lv_img_dsc_t * lv_canvas_get_img(lv_obj_t * obj) * Other functions *====================*/ -/** - * Copy a buffer to the canvas - * @param canvas pointer to a canvas object - * @param to_copy buffer to copy. The color format has to match with the canvas's buffer color - * format - * @param w width of the buffer to copy - * @param h height of the buffer to copy - * @param x left side of the destination position - * @param y top side of the destination position - */ void lv_canvas_copy_buf(lv_obj_t * obj, const void * to_copy, lv_coord_t x, lv_coord_t y, lv_coord_t w, lv_coord_t h) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); @@ -224,21 +164,6 @@ void lv_canvas_copy_buf(lv_obj_t * obj, const void * to_copy, lv_coord_t x, lv_c } } -/** - * Transform and image and store the result on a canvas. - * @param canvas pointer to a canvas object to store the result of the transformation. - * @param img pointer to an image descriptor to transform. - * Can be the image descriptor of an other canvas too (`lv_canvas_get_img()`). - * @param angle the angle of rotation (0..3600), 0.1 deg resolution - * @param zoom zoom factor (256 no zoom); - * @param offset_x offset X to tell where to put the result data on destination canvas - * @param offset_y offset X to tell where to put the result data on destination canvas - * @param pivot_x pivot X of rotation. Relative to the source canvas - * Set to `source width / 2` to rotate around the center - * @param pivot_y pivot Y of rotation. Relative to the source canvas - * Set to `source height / 2` to rotate around the center - * @param antialias apply anti-aliasing during the transformation. Looks better but slower. - */ void lv_canvas_transform(lv_obj_t * obj, lv_img_dsc_t * img, int16_t angle, uint16_t zoom, lv_coord_t offset_x, lv_coord_t offset_y, int32_t pivot_x, int32_t pivot_y, bool antialias) @@ -342,12 +267,6 @@ void lv_canvas_transform(lv_obj_t * obj, lv_img_dsc_t * img, int16_t angle, uint #endif } -/** - * Apply horizontal blur on the canvas - * @param canvas pointer to a canvas object - * @param area the area to blur. If `NULL` the whole canvas will be blurred. - * @param r radius of the blur - */ void lv_canvas_blur_hor(lv_obj_t * obj, const lv_area_t * area, uint16_t r) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); @@ -476,12 +395,6 @@ void lv_canvas_blur_hor(lv_obj_t * obj, const lv_area_t * area, uint16_t r) lv_mem_buf_release(line_buf); } -/** - * Apply vertical blur on the canvas - * @param canvas pointer to a canvas object - * @param area the area to blur. If `NULL` the whole canvas will be blurred. - * @param r radius of the blur - */ void lv_canvas_blur_ver(lv_obj_t * obj, const lv_area_t * area, uint16_t r) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); @@ -615,12 +528,6 @@ void lv_canvas_blur_ver(lv_obj_t * obj, const lv_area_t * area, uint16_t r) lv_mem_buf_release(col_buf); } -/** - * Fill the canvas with color - * @param canvas pointer to a canvas - * @param color the background color - * @param opa the desired opacity - */ void lv_canvas_fill_bg(lv_obj_t * canvas, lv_color_t color, lv_opa_t opa) { LV_ASSERT_OBJ(canvas, LV_OBJX_NAME); @@ -650,17 +557,8 @@ void lv_canvas_fill_bg(lv_obj_t * canvas, lv_color_t color, lv_opa_t opa) lv_obj_invalidate(canvas); } -/** - * Draw a rectangle on the canvas - * @param canvas pointer to a canvas object - * @param x left coordinate of the rectangle - * @param y top coordinate of the rectangle - * @param w width of the rectangle - * @param h height of the rectangle - * @param rect_dsc descriptor of the rectangle - */ void lv_canvas_draw_rect(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y, lv_coord_t w, lv_coord_t h, - const lv_draw_rect_dsc_t * rect_dsc) + const lv_draw_rect_dsc_t * draw_dsc) { LV_ASSERT_OBJ(canvas, LV_OBJX_NAME); @@ -705,7 +603,7 @@ void lv_canvas_draw_rect(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y, lv_coord /*Disable anti-aliasing if drawing with transparent color to chroma keyed canvas*/ lv_color_t ctransp = LV_COLOR_TRANSP; if(dsc->header.cf == LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED && - rect_dsc->bg_color.full == ctransp.full) { + draw_dsc->bg_color.full == ctransp.full) { disp.driver.antialiasing = 0; } #endif @@ -713,24 +611,15 @@ void lv_canvas_draw_rect(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y, lv_coord lv_disp_t * refr_ori = _lv_refr_get_disp_refreshing(); _lv_refr_set_disp_refreshing(&disp); - lv_draw_rect(&coords, &mask, rect_dsc); + lv_draw_rect(&coords, &mask, draw_dsc); _lv_refr_set_disp_refreshing(refr_ori); lv_obj_invalidate(canvas); } -/** - * Draw a text on the canvas. - * @param canvas pointer to a canvas object - * @param x left coordinate of the text - * @param y top coordinate of the text - * @param max_w max width of the text. The text will be wrapped to fit into this size - * @param label_draw_dsc pointer to a valid label descriptor `lv_draw_label_dsc_t` - * @param txt text to display - */ void lv_canvas_draw_text(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y, lv_coord_t max_w, - lv_draw_label_dsc_t * label_draw_dsc, const char * txt) + lv_draw_label_dsc_t * draw_dsc, const char * txt) { LV_ASSERT_OBJ(canvas, LV_OBJX_NAME); @@ -773,21 +662,15 @@ void lv_canvas_draw_text(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y, lv_coord lv_disp_t * refr_ori = _lv_refr_get_disp_refreshing(); _lv_refr_set_disp_refreshing(&disp); - lv_draw_label(&coords, &mask, label_draw_dsc, txt, NULL); + lv_draw_label(&coords, &mask, draw_dsc, txt, NULL); _lv_refr_set_disp_refreshing(refr_ori); lv_obj_invalidate(canvas); } -/** - * Draw an image on the canvas - * @param canvas pointer to a canvas object - * @param src image source. Can be a pointer an `lv_img_dsc_t` variable or a path an image. - * @param img_draw_dsc pointer to a valid label descriptor `lv_draw_img_dsc_t` - */ void lv_canvas_draw_img(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y, const void * src, - const lv_draw_img_dsc_t * img_draw_dsc) + const lv_draw_img_dsc_t * draw_dsc) { LV_ASSERT_OBJ(canvas, LV_OBJX_NAME); @@ -837,22 +720,15 @@ void lv_canvas_draw_img(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y, const voi lv_disp_t * refr_ori = _lv_refr_get_disp_refreshing(); _lv_refr_set_disp_refreshing(&disp); - lv_draw_img(&coords, &mask, src, img_draw_dsc); + lv_draw_img(&coords, &mask, src, draw_dsc); _lv_refr_set_disp_refreshing(refr_ori); lv_obj_invalidate(canvas); } -/** - * Draw a line on the canvas - * @param canvas pointer to a canvas object - * @param points point of the line - * @param point_cnt number of points - * @param line_draw_dsc pointer to an initialized `lv_draw_line_dsc_t` variable - */ void lv_canvas_draw_line(lv_obj_t * canvas, const lv_point_t points[], uint32_t point_cnt, - const lv_draw_line_dsc_t * line_draw_dsc) + const lv_draw_line_dsc_t * draw_dsc) { LV_ASSERT_OBJ(canvas, LV_OBJX_NAME); @@ -889,7 +765,7 @@ void lv_canvas_draw_line(lv_obj_t * canvas, const lv_point_t points[], uint32_t /*Disable anti-aliasing if drawing with transparent color to chroma keyed canvas*/ lv_color_t ctransp = LV_COLOR_TRANSP; if(dsc->header.cf == LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED && - line_draw_dsc->color.full == ctransp.full) { + draw_dsc->color.full == ctransp.full) { disp.driver.antialiasing = 0; } #endif @@ -899,7 +775,7 @@ void lv_canvas_draw_line(lv_obj_t * canvas, const lv_point_t points[], uint32_t uint32_t i; for(i = 0; i < point_cnt - 1; i++) { - lv_draw_line(&points[i], &points[i + 1], &mask, line_draw_dsc); + lv_draw_line(&points[i], &points[i + 1], &mask, draw_dsc); } _lv_refr_set_disp_refreshing(refr_ori); @@ -907,15 +783,8 @@ void lv_canvas_draw_line(lv_obj_t * canvas, const lv_point_t points[], uint32_t lv_obj_invalidate(canvas); } -/** - * Draw a polygon on the canvas - * @param canvas pointer to a canvas object - * @param points point of the polygon - * @param point_cnt number of points - * @param poly_draw_dsc pointer to an initialized `lv_draw_rect_dsc_t` variable - */ void lv_canvas_draw_polygon(lv_obj_t * canvas, const lv_point_t points[], uint32_t point_cnt, - const lv_draw_rect_dsc_t * poly_draw_dsc) + const lv_draw_rect_dsc_t * draw_dsc) { LV_ASSERT_OBJ(canvas, LV_OBJX_NAME); @@ -953,7 +822,7 @@ void lv_canvas_draw_polygon(lv_obj_t * canvas, const lv_point_t points[], uint32 /*Disable anti-aliasing if drawing with transparent color to chroma keyed canvas*/ lv_color_t ctransp = LV_COLOR_TRANSP; if(dsc->header.cf == LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED && - poly_draw_dsc->bg_color.full == ctransp.full) { + draw_dsc->bg_color.full == ctransp.full) { disp.driver.antialiasing = 0; } #endif @@ -961,25 +830,15 @@ void lv_canvas_draw_polygon(lv_obj_t * canvas, const lv_point_t points[], uint32 lv_disp_t * refr_ori = _lv_refr_get_disp_refreshing(); _lv_refr_set_disp_refreshing(&disp); - lv_draw_polygon(points, point_cnt, &mask, poly_draw_dsc); + lv_draw_polygon(points, point_cnt, &mask, draw_dsc); _lv_refr_set_disp_refreshing(refr_ori); lv_obj_invalidate(canvas); } -/** - * Draw an arc on the canvas - * @param canvas pointer to a canvas object - * @param x origo x of the arc - * @param y origo y of the arc - * @param r radius of the arc - * @param start_angle start angle in degrees - * @param end_angle end angle in degrees - * @param arc_draw_dsc pointer to an initialized `lv_draw_line_dsc_t` variable - */ void lv_canvas_draw_arc(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y, lv_coord_t r, int32_t start_angle, - int32_t end_angle, const lv_draw_line_dsc_t * arc_draw_dsc) + int32_t end_angle, const lv_draw_arc_dsc_t * draw_dsc) { #if LV_DRAW_COMPLEX LV_ASSERT_OBJ(canvas, LV_OBJX_NAME); @@ -1018,7 +877,7 @@ void lv_canvas_draw_arc(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y, lv_coord_ /*Disable anti-aliasing if drawing with transparent color to chroma keyed canvas*/ lv_color_t ctransp = LV_COLOR_TRANSP; if(dsc->header.cf == LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED && - arc_draw_dsc->color.full == ctransp.full) { + draw_dsc->color.full == ctransp.full) { disp.driver.antialiasing = 0; } #endif @@ -1026,7 +885,7 @@ void lv_canvas_draw_arc(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y, lv_coord_ lv_disp_t * refr_ori = _lv_refr_get_disp_refreshing(); _lv_refr_set_disp_refreshing(&disp); - lv_draw_arc(x, y, r, start_angle, end_angle, &mask, arc_draw_dsc); + lv_draw_arc(x, y, r, start_angle, end_angle, &mask, draw_dsc); _lv_refr_set_disp_refreshing(refr_ori); diff --git a/src/lv_widgets/lv_canvas.h b/src/lv_widgets/lv_canvas.h index 1068f103d..e4ec8a86b 100644 --- a/src/lv_widgets/lv_canvas.h +++ b/src/lv_widgets/lv_canvas.h @@ -167,72 +167,71 @@ void lv_canvas_fill_bg(lv_obj_t * canvas, lv_color_t color, lv_opa_t opa); /** * Draw a rectangle on the canvas - * @param canvas pointer to a canvas object - * @param x left coordinate of the rectangle - * @param y top coordinate of the rectangle - * @param w width of the rectangle - * @param h height of the rectangle - * @param rect_dsc descriptor of the rectangle + * @param canvas: pointer to a canvas object + * @param x: left coordinate of the rectangle + * @param y: top coordinate of the rectangle + * @param w: width of the rectangle + * @param h: height of the rectangle + * @param draw_dsc: descriptor of the rectangle */ void lv_canvas_draw_rect(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y, lv_coord_t w, lv_coord_t h, - const lv_draw_rect_dsc_t * rect_dsc); + const lv_draw_rect_dsc_t * draw_dsc); /** * Draw a text on the canvas. - * @param canvas pointer to a canvas object - * @param x left coordinate of the text - * @param y top coordinate of the text - * @param max_w max width of the text. The text will be wrapped to fit into this size - * @param label_draw_dsc pointer to a valid label descriptor `lv_draw_label_dsc_t` - * @param txt text to display - * @param align align of the text (`LV_TEXT_ALIGN_LEFT/RIGHT/CENTER`) + * @param canvas: pointer to a canvas object + * @param x: left coordinate of the text + * @param y: top coordinate of the text + * @param max_w: max width of the text. The text will be wrapped to fit into this size + * @param draw_dsc: pointer to a valid label descriptor `lv_draw_label_dsc_t` + * @param txt: text to display */ void lv_canvas_draw_text(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y, lv_coord_t max_w, - lv_draw_label_dsc_t * label_draw_dsc, const char * txt); + lv_draw_label_dsc_t * draw_dsc, const char * txt); /** * Draw an image on the canvas - * @param canvas pointer to a canvas object - * @param x left coordinate of the image - * @param y top coordinate of the image - * @param src image source. Can be a pointer an `lv_img_dsc_t` variable or a path an image. - * @param img_draw_dsc pointer to a valid label descriptor `lv_draw_img_dsc_t` + * @param canvas: pointer to a canvas object + * @param x: left coordinate of the image + * @param y: top coordinate of the image + * @param src: image source. Can be a pointer an `lv_img_dsc_t` variable or a path an image. + * @param draw_dsc: pointer to a valid label descriptor `lv_draw_img_dsc_t` */ void lv_canvas_draw_img(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y, const void * src, - const lv_draw_img_dsc_t * img_draw_dsc); + const lv_draw_img_dsc_t * draw_dsc); /** * Draw a line on the canvas - * @param canvas pointer to a canvas object - * @param points point of the line - * @param point_cnt number of points - * @param line_draw_dsc pointer to an initialized `lv_draw_line_dsc_t` variable + * @param canvas: pointer to a canvas object + * @param points: point of the line + * @param point_cnt: number of points + * @param draw_dsc: pointer to an initialized `lv_draw_line_dsc_t` variable */ void lv_canvas_draw_line(lv_obj_t * canvas, const lv_point_t points[], uint32_t point_cnt, - const lv_draw_line_dsc_t * line_draw_dsc); + const lv_draw_line_dsc_t * draw_dsc); /** * Draw a polygon on the canvas - * @param canvas pointer to a canvas object - * @param points point of the polygon - * @param point_cnt number of points - * @param poly_draw_dsc pointer to an initialized `lv_draw_rect_dsc_t` variable + * @param canvas: pointer to a canvas object + * @param points: point of the polygon + * @param point_cnt: number of points + * @param draw_dsc: pointer to an initialized `lv_draw_rect_dsc_t` variable */ void lv_canvas_draw_polygon(lv_obj_t * canvas, const lv_point_t points[], uint32_t point_cnt, - const lv_draw_rect_dsc_t * poly_draw_dsc); + const lv_draw_rect_dsc_t * draw_dsc); /** * Draw an arc on the canvas - * @param canvas pointer to a canvas object - * @param x origo x of the arc - * @param y origo y of the arc - * @param r radius of the arc - * @param start_angle start angle in degrees - * @param end_angle end angle in degrees - * @param arc_draw_dsc pointer to an initialized `lv_draw_line_dsc_t` variable + * @param canvas: pointer to a canvas object + * @param x: origo x of the arc + * @param y: origo y of the arc + * @param r: radius of the arc + * @param start_angle: start angle in degrees + * @param end_angle: end angle in degrees + * @param draw_dsc: pointer to an initialized `lv_draw_line_dsc_t` variable */ void lv_canvas_draw_arc(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y, lv_coord_t r, int32_t start_angle, - int32_t end_angle, const lv_draw_line_dsc_t * arc_draw_dsc); + int32_t end_angle, const lv_draw_arc_dsc_t * draw_dsc); /********************** * MACROS diff --git a/src/lv_widgets/lv_chart.c b/src/lv_widgets/lv_chart.c index ecc3c0ba0..eb52487c2 100644 --- a/src/lv_widgets/lv_chart.c +++ b/src/lv_widgets/lv_chart.c @@ -26,10 +26,9 @@ #define LV_CHART_YMAX_DEF 100 #define LV_CHART_HDIV_DEF 3 #define LV_CHART_VDIV_DEF 5 -#define LV_CHART_PNUM_DEF 10 +#define LV_CHART_POINT_CNT_DEF 10 #define LV_CHART_LABEL_ITERATOR_FORWARD 1 #define LV_CHART_LABEL_ITERATOR_REVERSE 0 -#define TICK_LABEL_GAP LV_DPX(2) /********************** * TYPEDEFS @@ -45,8 +44,7 @@ static lv_res_t lv_chart_signal(lv_obj_t * obj, lv_signal_t sign, void * param); static void draw_div_lines(lv_obj_t * obj , const lv_area_t * mask); static void draw_series_line(lv_obj_t * obj, const lv_area_t * clip_area); -static void draw_series_column(lv_obj_t * obj, const lv_area_t * clip_area); -static void draw_cursors(lv_obj_t * obj, const lv_area_t * clip_area); +static void draw_series_bar(lv_obj_t * obj, const lv_area_t * clip_area); static void draw_axes(lv_obj_t * obj, const lv_area_t * mask); static uint32_t get_index_from_x(lv_obj_t * obj, lv_coord_t x); static void invalidate_point(lv_obj_t * obj, uint16_t i); @@ -71,32 +69,269 @@ const lv_obj_class_t lv_chart = { * GLOBAL FUNCTIONS **********************/ -/** - * Create a chart background objects - * @param par pointer to an object, it will be the parent of the new chart background - * @param copy pointer to a chart background object, if not NULL then the new object will be copied - * from it - * @return pointer to the created chart background - */ lv_obj_t * lv_chart_create(lv_obj_t * parent, const lv_obj_t * copy) { return lv_obj_create_from_class(&lv_chart, parent, copy); } -/*====================== - * Add/remove functions - *=====================*/ - -/** - * Allocate and add a data series to the chart - * @param chart pointer to a chart object - * @param color color of the data series - * @return pointer to the allocated data series - */ -lv_chart_series_t * lv_chart_add_series(lv_obj_t * obj, lv_color_t color) +void lv_chart_set_type(lv_obj_t * obj, lv_chart_type_t type) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); + lv_chart_t * chart = (lv_chart_t *)obj; + if(chart->type == type) return; + + chart->type = type; + + lv_chart_refresh(obj); +} + +void lv_chart_set_point_count(lv_obj_t * obj, uint16_t cnt) +{ + LV_ASSERT_OBJ(obj, LV_OBJX_NAME); + + lv_chart_t * chart = (lv_chart_t *)obj; + if(chart->point_cnt == cnt) return; + + lv_chart_series_t * ser; + uint16_t point_cnt_old = chart->point_cnt; + uint16_t i; + lv_coord_t def = LV_CHART_POINT_DEF; + + if(cnt < 1) cnt = 1; + + _LV_LL_READ_BACK(&chart->series_ll, ser) { + if(!ser->ext_buf_assigned) { + if(ser->last_point != 0) { + lv_coord_t * new_points = lv_mem_alloc(sizeof(lv_coord_t) * cnt); + LV_ASSERT_MEM(new_points); + if(new_points == NULL) return; + + if(cnt >= point_cnt_old) { + for(i = 0; i < point_cnt_old; i++) { + new_points[i] = + ser->points[(i + ser->last_point) % point_cnt_old]; /*Copy old contents to new array*/ + } + for(i = point_cnt_old; i < cnt; i++) { + new_points[i] = def; /*Fill up the rest with default value*/ + } + } + else { + for(i = 0; i < cnt; i++) { + new_points[i] = + ser->points[(i + ser->last_point) % point_cnt_old]; /*Copy old contents to new array*/ + } + } + + /*Switch over pointer from old to new*/ + lv_mem_free(ser->points); + ser->points = new_points; + } + else { + ser->points = lv_mem_realloc(ser->points, sizeof(lv_coord_t) * cnt); + LV_ASSERT_MEM(ser->points); + if(ser->points == NULL) return; + /*Initialize the new points*/ + if(cnt > point_cnt_old) { + for(i = point_cnt_old - 1; i < cnt; i++) { + ser->points[i] = def; + } + } + } + } + ser->last_point = 0; + } + + chart->point_cnt = cnt; + + lv_chart_refresh(obj); +} + +void lv_chart_set_range(lv_obj_t * obj, lv_chart_axis_t axis, lv_coord_t min, lv_coord_t max) +{ + LV_ASSERT_OBJ(obj, LV_OBJX_NAME); + + if(axis != LV_CHART_AXIS_PRIMARY_Y && axis != LV_CHART_AXIS_SECONDARY_Y) { + LV_LOG_WARN("Invalid axis: %d", axis); + return; + } + + lv_chart_t * chart = (lv_chart_t *)obj; + chart->ymin[axis] = min; + chart->ymax[axis] = (max == min ? max + 1 : max); + lv_chart_refresh(obj); +} + +void lv_chart_set_update_mode(lv_obj_t * obj, lv_chart_update_mode_t update_mode) +{ + LV_ASSERT_OBJ(obj, LV_OBJX_NAME); + + lv_chart_t * chart = (lv_chart_t *)obj; + if(chart->update_mode == update_mode) return; + + chart->update_mode = update_mode; + lv_obj_invalidate(obj); +} + +void lv_chart_set_div_line_count(lv_obj_t * obj, uint8_t hdiv, uint8_t vdiv) +{ + LV_ASSERT_OBJ(obj, LV_OBJX_NAME); + + lv_chart_t * chart = (lv_chart_t *)obj; + if(chart->hdiv_cnt == hdiv && chart->vdiv_cnt == vdiv) return; + + chart->hdiv_cnt = hdiv; + chart->vdiv_cnt = vdiv; + + lv_obj_invalidate(obj); +} + + +void lv_chart_set_zoom_x(lv_obj_t * obj, uint16_t zoom_x) +{ + LV_ASSERT_OBJ(obj, LV_OBJX_NAME); + + lv_chart_t * chart = (lv_chart_t *)obj; + if(chart->zoom_x == zoom_x) return; + + chart->zoom_x = zoom_x; + lv_obj_invalidate(obj); +} + +void lv_chart_set_zoom_y(lv_obj_t * obj, uint16_t zoom_y) +{ + LV_ASSERT_OBJ(obj, LV_OBJX_NAME); + + lv_chart_t * chart = (lv_chart_t *)obj; + if(chart->zoom_y == zoom_y) return; + + chart->zoom_y = zoom_y; + lv_obj_invalidate(obj); +} + +uint16_t lv_chart_get_zoom_x(const lv_obj_t * obj) +{ + LV_ASSERT_OBJ(obj, LV_OBJX_NAME); + + lv_chart_t * chart = (lv_chart_t *)obj; + return chart->zoom_x; +} + +uint16_t lv_chart_get_zoom_y(const lv_obj_t * obj) +{ + LV_ASSERT_OBJ(obj, LV_OBJX_NAME); + + lv_chart_t * chart = (lv_chart_t *)obj; + return chart->zoom_y; +} + +void lv_chart_set_axis_tick(lv_obj_t * obj, lv_chart_axis_t axis, lv_coord_t major_len, lv_coord_t minor_len, lv_coord_t major_cnt, lv_coord_t minor_cnt, bool label_en, lv_coord_t draw_size) +{ + LV_ASSERT_OBJ(obj, LV_OBJX_NAME); + + lv_chart_t * chart = (lv_chart_t *)obj; + chart->tick[axis].major_len = major_len; + chart->tick[axis].minor_len = minor_len; + chart->tick[axis].minor_cnt = minor_cnt; + chart->tick[axis].major_cnt = major_cnt; + chart->tick[axis].label_en = label_en; + chart->tick[axis].draw_size = draw_size; + + lv_obj_refresh_ext_draw_size(obj); + lv_obj_invalidate(obj); +} + +lv_chart_type_t lv_chart_get_type(const lv_obj_t * obj) +{ + LV_ASSERT_OBJ(obj, LV_OBJX_NAME); + + lv_chart_t * chart = (lv_chart_t *)obj; + return chart->type; +} + +uint16_t lv_chart_get_point_count(const lv_obj_t * obj) +{ + LV_ASSERT_OBJ(obj, LV_OBJX_NAME); + + lv_chart_t * chart = (lv_chart_t *)obj; + return chart->point_cnt; +} + +uint16_t lv_chart_get_x_start_point(const lv_obj_t * obj, lv_chart_series_t * ser) +{ + LV_ASSERT_NULL(ser); + + return(ser->last_point); +} + +void lv_chart_get_point_pos_by_id(lv_obj_t * obj, lv_chart_series_t * ser, uint16_t id, lv_point_t * p_out) +{ + LV_ASSERT_NULL(obj); + LV_ASSERT_NULL(ser); + + lv_chart_t * chart = (lv_chart_t *)obj; + if(id >= chart->point_cnt) { + LV_LOG_WARN("Invalid index: %d", id); + p_out->x = 0; + p_out->y = 0; + return; + } + + lv_coord_t w = (lv_obj_get_width_fit(obj) * chart->zoom_x) >> 8; + + if(chart->type & LV_CHART_TYPE_LINE) { + p_out->x = (w * id) / (chart->point_cnt - 1); + } + else if(chart->type & LV_CHART_TYPE_BAR) { + uint32_t ser_cnt = _lv_ll_get_len(&chart->series_ll); + uint32_t ser_gap = lv_obj_get_style_pad_column(obj, LV_PART_ITEMS); /*Gap between the column on the ~same X */ + uint32_t block_gap = lv_obj_get_style_pad_column(obj, LV_PART_MAIN); /*Gap between the column on ~adjacent X*/ + lv_coord_t block_w = (w) / chart->point_cnt - block_gap; + lv_coord_t col_w = block_w / ser_cnt; + + p_out->x = (int32_t)((int32_t)w * id) / chart->point_cnt; + + lv_chart_series_t * ser_i = NULL; + _LV_LL_READ_BACK(&chart->series_ll, ser_i) { + if(ser_i == ser) break; + p_out->x += col_w; + } + + p_out->x += (col_w - ser_gap) / 2; + } + + p_out->x += lv_obj_get_style_pad_left(obj, LV_PART_MAIN); + p_out->x -= lv_obj_get_scroll_left(obj); + + lv_coord_t h = (lv_obj_get_height_fit(obj) * chart->zoom_y) >> 8; + + p_out->y = (int32_t)((int32_t)ser->points[id] - chart->ymin[ser->y_axis]) * h; + p_out->y = p_out->y / (chart->ymax[ser->y_axis] - chart->ymin[ser->y_axis]); + p_out->y = h - p_out->y; + p_out->y += lv_obj_get_style_pad_top(obj, LV_PART_MAIN); + +} + +void lv_chart_refresh(lv_obj_t * obj) +{ + LV_ASSERT_OBJ(obj, LV_OBJX_NAME); + + lv_obj_invalidate(obj); +} + +/*====================== + * Series + *=====================*/ + +lv_chart_series_t * lv_chart_add_series(lv_obj_t * obj, lv_color_t color, lv_chart_axis_t axis) +{ + LV_ASSERT_OBJ(obj, LV_OBJX_NAME); + + if(axis != LV_CHART_AXIS_PRIMARY_Y && axis != LV_CHART_AXIS_SECONDARY_Y) { + LV_LOG_WARN("Invalid y axis"); + return NULL; + } + lv_chart_t * chart = (lv_chart_t *)obj; lv_chart_series_t * ser = _lv_ll_ins_head(&chart->series_ll); LV_ASSERT_MEM(ser); @@ -113,10 +348,10 @@ lv_chart_series_t * lv_chart_add_series(lv_obj_t * obj, lv_color_t color) return NULL; } - ser->start_point = 0; + ser->last_point = 0; ser->ext_buf_assigned = false; ser->hidden = 0; - ser->y_axis = LV_CHART_AXIS_PRIMARY_Y; + ser->y_axis = axis; uint16_t i; lv_coord_t * p_tmp = ser->points; @@ -128,11 +363,6 @@ lv_chart_series_t * lv_chart_add_series(lv_obj_t * obj, lv_color_t color) return ser; } -/** - * Deallocate and remove a data series from a chart - * @param chart pointer to a chart object - * @param series pointer to a data series on 'chart' - */ void lv_chart_remove_series(lv_obj_t * obj, lv_chart_series_t * series) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); @@ -147,56 +377,6 @@ void lv_chart_remove_series(lv_obj_t * obj, lv_chart_series_t * series) return; } -/** - * Add a cursor with a given color - * @param chart pointer to chart object - * @param color color of the cursor - * @param dir direction of the cursor. `LV_DIR_RIGHT/LEFT/TOP/DOWN`. OR-ed values are possible - * @return pointer to the created cursor - */ -lv_chart_cursor_t * lv_chart_add_cursor(lv_obj_t * obj, lv_color_t color, lv_dir_t axes) -{ - LV_ASSERT_OBJ(obj, LV_OBJX_NAME); - - lv_chart_t * chart = (lv_chart_t *)obj; - lv_chart_cursor_t * cursor = _lv_ll_ins_head(&chart->cursors_ll); - LV_ASSERT_MEM(cursor); - if(cursor == NULL) return NULL; - - cursor->point.x = 0U; - cursor->point.y = LV_CHART_POINT_DEF; - cursor->color = color; - cursor->axes = axes; - - return cursor; -} - -/** - * Clear the point of a series - * @param chart pointer to a chart object - * @param series pointer to the chart's series to clear - */ -void lv_chart_clear_series(lv_obj_t * obj, lv_chart_series_t * series) -{ - LV_ASSERT_OBJ(obj, LV_OBJX_NAME); - LV_ASSERT_NULL(series); - - lv_chart_t * chart = (lv_chart_t *)obj; - - uint32_t i; - for(i = 0; i < chart->point_cnt; i++) { - series->points[i] = LV_CHART_POINT_DEF; - } - - series->start_point = 0; -} - -/** - * Hide/Unhide a single series of a chart. - * @param chart pointer to a chart object. - * @param series pointer to a series object - * @param hide true: hide the series - */ void lv_chart_hide_series(lv_obj_t * chart, lv_chart_series_t * series, bool hide) { LV_ASSERT_OBJ(chart, LV_OBJX_NAME); @@ -206,248 +386,6 @@ void lv_chart_hide_series(lv_obj_t * chart, lv_chart_series_t * series, bool hid lv_chart_refresh(chart); } -/*===================== - * Setter functions - *====================*/ - -/** - * Set the number of horizontal and vertical division lines - * @param chart pointer to a graph background object - * @param hdiv number of horizontal division lines - * @param vdiv number of vertical division lines - */ -void lv_chart_set_div_line_count(lv_obj_t * obj, uint8_t hdiv, uint8_t vdiv) -{ - LV_ASSERT_OBJ(obj, LV_OBJX_NAME); - - lv_chart_t * chart = (lv_chart_t *)obj; - if(chart->hdiv_cnt == hdiv && chart->vdiv_cnt == vdiv) return; - - chart->hdiv_cnt = hdiv; - chart->vdiv_cnt = vdiv; - - lv_obj_invalidate(obj); -} - -/** - * Set the minimal and maximal y values on an axis - * @param chart pointer to a graph background object - * @param axis `LV_CHART_AXIS_PRIMARY_Y` or `LV_CHART_AXIS_SECONDARY_Y` - * @param ymin y minimum value - * @param ymax y maximum value - */ -void lv_chart_set_y_range(lv_obj_t * obj, lv_chart_axis_t axis, lv_coord_t ymin, lv_coord_t ymax) -{ - LV_ASSERT_OBJ(obj, LV_OBJX_NAME); - - if(axis != LV_CHART_AXIS_PRIMARY_Y && axis != LV_CHART_AXIS_SECONDARY_Y) { - LV_LOG_WARN("Invalid axis: %d", axis); - return; - } - - lv_chart_t * chart = (lv_chart_t *)obj; - chart->ymin[axis] = ymin; - chart->ymax[axis] = (ymax == ymin ? ymax + 1 : ymax); - lv_chart_refresh(obj); -} - -/** - * Set a new type for a chart - * @param chart pointer to a chart object - * @param type new type of the chart (from 'lv_chart_type_t' enum) - */ -void lv_chart_set_type(lv_obj_t * obj, lv_chart_type_t type) -{ - LV_ASSERT_OBJ(obj, LV_OBJX_NAME); - - lv_chart_t * chart = (lv_chart_t *)obj; - if(chart->type == type) return; - - chart->type = type; - - lv_chart_refresh(obj); -} - -/** - * Set the number of points on a data line on a chart - * @param chart pointer r to chart object - * @param point_cnt new number of points on the data lines - */ -void lv_chart_set_point_count(lv_obj_t * obj, uint16_t point_cnt) -{ - LV_ASSERT_OBJ(obj, LV_OBJX_NAME); - - lv_chart_t * chart = (lv_chart_t *)obj; - if(chart->point_cnt == point_cnt) return; - - lv_chart_series_t * ser; - uint16_t point_cnt_old = chart->point_cnt; - uint16_t i; - lv_coord_t def = LV_CHART_POINT_DEF; - - if(point_cnt < 1) point_cnt = 1; - - _LV_LL_READ_BACK(&chart->series_ll, ser) { - if(!ser->ext_buf_assigned) { - if(ser->start_point != 0) { - lv_coord_t * new_points = lv_mem_alloc(sizeof(lv_coord_t) * point_cnt); - LV_ASSERT_MEM(new_points); - if(new_points == NULL) return; - - if(point_cnt >= point_cnt_old) { - for(i = 0; i < point_cnt_old; i++) { - new_points[i] = - ser->points[(i + ser->start_point) % point_cnt_old]; /*Copy old contents to new array*/ - } - for(i = point_cnt_old; i < point_cnt; i++) { - new_points[i] = def; /*Fill up the rest with default value*/ - } - } - else { - for(i = 0; i < point_cnt; i++) { - new_points[i] = - ser->points[(i + ser->start_point) % point_cnt_old]; /*Copy old contents to new array*/ - } - } - - /*Switch over pointer from old to new*/ - lv_mem_free(ser->points); - ser->points = new_points; - } - else { - ser->points = lv_mem_realloc(ser->points, sizeof(lv_coord_t) * point_cnt); - LV_ASSERT_MEM(ser->points); - if(ser->points == NULL) return; - /*Initialize the new points*/ - if(point_cnt > point_cnt_old) { - for(i = point_cnt_old - 1; i < point_cnt; i++) { - ser->points[i] = def; - } - } - } - } - ser->start_point = 0; - } - - chart->point_cnt = point_cnt; - - lv_chart_refresh(obj); -} - -/** - * Initialize all data points with a value - * @param chart pointer to chart object - * @param ser pointer to a data series on 'chart' - * @param y the new value for all points - */ -void lv_chart_init_points(lv_obj_t * obj, lv_chart_series_t * ser, lv_coord_t y) -{ - LV_ASSERT_OBJ(obj, LV_OBJX_NAME); - LV_ASSERT_NULL(ser); - - lv_chart_t * chart = (lv_chart_t *)obj; - uint16_t i; - for(i = 0; i < chart->point_cnt; i++) { - ser->points[i] = y; - } - ser->start_point = 0; - lv_chart_refresh(obj); -} - -/** - * Set the value of points from an array - * @param chart pointer to chart object - * @param ser pointer to a data series on 'chart' - * @param y_array array of 'lv_coord_t' points (with 'points count' elements ) - */ -void lv_chart_set_points(lv_obj_t * obj, lv_chart_series_t * ser, lv_coord_t y_array[]) -{ - LV_ASSERT_OBJ(obj, LV_OBJX_NAME); - LV_ASSERT_NULL(ser); - - lv_chart_t * chart = (lv_chart_t *)obj; - memcpy(ser->points, y_array, chart->point_cnt * (sizeof(lv_coord_t))); - ser->start_point = 0; - lv_chart_refresh(obj); -} - -/** - * Shift all data left and set the rightmost data on a data line - * @param chart pointer to chart object - * @param ser pointer to a data series on 'chart' - * @param y the new value of the rightmost data - */ -void lv_chart_set_next(lv_obj_t * obj, lv_chart_series_t * ser, lv_coord_t y) -{ - LV_ASSERT_OBJ(obj, LV_OBJX_NAME); - LV_ASSERT_NULL(ser); - - lv_chart_t * chart = (lv_chart_t *)obj; - if(chart->update_mode == LV_CHART_UPDATE_MODE_SHIFT) { - ser->points[ser->start_point] = - y; /*This was the place of the former left most value, after shifting it is the rightmost*/ - ser->start_point = (ser->start_point + 1) % chart->point_cnt; - lv_chart_refresh(obj); - } - else if(chart->update_mode == LV_CHART_UPDATE_MODE_CIRCULAR) { - ser->points[ser->start_point] = y; - - invalidate_point(obj, ser->start_point); - - ser->start_point = (ser->start_point + 1) % chart->point_cnt; /*update the x for next incoming y*/ - } -} - -/** - * Set update mode of the chart object. - * @param chart pointer to a chart object - * @param update mode - */ -void lv_chart_set_update_mode(lv_obj_t * obj, lv_chart_update_mode_t update_mode) -{ - LV_ASSERT_OBJ(obj, LV_OBJX_NAME); - - lv_chart_t * chart = (lv_chart_t *)obj; - if(chart->update_mode == update_mode) return; - - chart->update_mode = update_mode; - lv_obj_invalidate(obj); -} - -/** - * Set the secondary y-axis tick count and labels of a chart - * @param chart pointer to a chart object - * @param list_of_values list of string values, terminated with \n, except the last - * @param num_tick_marks if list_of_values is NULL: total number of ticks per axis - * else number of ticks between two value labels - * @param options extra options - */ -void lv_chart_set_tick_label_cb(lv_obj_t * obj, lv_chart_tick_label_cb_t tick_label_cb, lv_coord_t ext_size) -{ - LV_ASSERT_OBJ(obj, LV_OBJX_NAME); - - lv_chart_t * chart = (lv_chart_t *)obj; - chart->tick_label_cb = tick_label_cb; - chart->ext_size = ext_size; - lv_obj_refresh_ext_draw_size(obj); - lv_obj_invalidate(obj); -} - -void lv_chart_set_sub_tick_conut(lv_obj_t * obj, lv_chart_axis_t axis, uint32_t cnt) -{ - LV_ASSERT_OBJ(obj, LV_OBJX_NAME); - - lv_chart_t * chart = (lv_chart_t *)obj; - chart->sub_tick_cnt[axis] = cnt; - lv_obj_invalidate(obj); -} - -/** - * Set the index of the x-axis start point in the data array - * @param chart pointer to a chart object - * @param ser pointer to a data series on 'chart' - * @param id the index of the x point in the data array - */ void lv_chart_set_x_start_point(lv_obj_t * obj, lv_chart_series_t * ser, uint16_t id) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); @@ -455,37 +393,66 @@ void lv_chart_set_x_start_point(lv_obj_t * obj, lv_chart_series_t * ser, uint16_ lv_chart_t * chart = (lv_chart_t *)obj; if(id >= chart->point_cnt) return; - ser->start_point = id; + ser->last_point = id; } -/** - * Set an external array of data points to use for the chart - * NOTE: It is the users responsibility to make sure the point_cnt matches the external array size. - * @param chart pointer to a chart object - * @param ser pointer to a data series on 'chart' - * @param array external array of points for chart - * @param point_cnt number of external points in the array - */ -void lv_chart_set_ext_array(lv_obj_t * obj, lv_chart_series_t * ser, lv_coord_t array[], uint16_t point_cnt) +lv_chart_series_t * lv_chart_get_series_next(const lv_obj_t * obj, const lv_chart_series_t * ser) +{ + LV_ASSERT_OBJ(obj, LV_OBJX_NAME); + + lv_chart_t * chart = (lv_chart_t *)obj; + if(ser == NULL) return _lv_ll_get_head(&chart->series_ll); + else return _lv_ll_get_next(&chart->series_ll, ser); +} + +/*===================== + * Set/Get value(s) + *====================*/ + + +void lv_chart_set_all_value(lv_obj_t * obj, lv_chart_series_t * ser, lv_coord_t value) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); LV_ASSERT_NULL(ser); - lv_chart_t * chart = (lv_chart_t *)obj; - if(!ser->ext_buf_assigned && ser->points) lv_mem_free(ser->points); - ser->ext_buf_assigned = true; - ser->points = array; - chart->point_cnt = point_cnt; + lv_chart_t * chart = (lv_chart_t *)obj; + uint16_t i; + for(i = 0; i < chart->point_cnt; i++) { + ser->points[i] = value; + } + ser->last_point = 0; + lv_chart_refresh(obj); } -/** - * Set an individual point y value in the chart series directly based on index - * @param chart pointer to a chart object - * @param ser pointer to a data series on 'chart' - * @param value value to assign to array point - * @param id the index of the x point in the array - */ -void lv_chart_set_point_id(lv_obj_t * obj, lv_chart_series_t * ser, lv_coord_t value, uint16_t id) +void lv_chart_set_next_value(lv_obj_t * obj, lv_chart_series_t * ser, lv_coord_t value) +{ + LV_ASSERT_OBJ(obj, LV_OBJX_NAME); + LV_ASSERT_NULL(ser); + + lv_chart_t * chart = (lv_chart_t *)obj; + if(chart->update_mode == LV_CHART_UPDATE_MODE_SHIFT) { + ser->points[ser->last_point] = + value; /*This was the place of the former left most value, after shifting it is the rightmost*/ + ser->last_point = (ser->last_point + 1) % chart->point_cnt; + lv_chart_refresh(obj); + } + else if(chart->update_mode == LV_CHART_UPDATE_MODE_CIRCULAR) { + ser->points[ser->last_point] = value; + + invalidate_point(obj, ser->last_point); + + uint32_t next_point = (ser->last_point + 1) % chart->point_cnt; /*update the x for next incoming y*/ + ser->last_point = next_point; + + ser->points[ser->last_point] = LV_CHART_POINT_DEF; + invalidate_point(obj, next_point); + + lv_obj_invalidate(obj); + + } +} + +void lv_chart_set_value_by_id(lv_obj_t * obj, lv_chart_series_t * ser, lv_coord_t value, uint16_t id) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); LV_ASSERT_NULL(ser); @@ -495,228 +462,34 @@ void lv_chart_set_point_id(lv_obj_t * obj, lv_chart_series_t * ser, lv_coord_t v ser->points[id] = value; } -/** - * Set the Y axis of a series - * @param chart pointer to a chart object - * @param ser pointer to series - * @param axis `LV_CHART_AXIS_PRIMARY_Y` or `LV_CHART_AXIS_SECONDARY_Y` - */ -void lv_chart_set_series_axis(lv_obj_t * obj, lv_chart_series_t * ser, lv_chart_axis_t axis) +void lv_chart_set_ext_array(lv_obj_t * obj, lv_chart_series_t * ser, lv_coord_t array[]) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); LV_ASSERT_NULL(ser); - if(axis >= _LV_CHART_AXIS_LAST) { - LV_LOG_WARN("Invalid axis: %d", axis); - return; - } - - if(ser->y_axis == axis) return; - - ser->y_axis = axis; - lv_chart_refresh(obj); -} - -/** - * Set the coordinate of the cursor with respect - * to the origin of series area of the chart. - * @param chart pointer to a chart object. - * @param cursor pointer to the cursor. - * @param point the new coordinate of cursor relative to the series area - */ -void lv_chart_set_cursor_point(lv_obj_t * obj, lv_chart_cursor_t * cursor, lv_point_t * point) -{ - LV_ASSERT_NULL(cursor); - LV_UNUSED(obj); - - cursor->point.x = point->x; - cursor->point.y = point->y; - lv_chart_refresh(obj); -} - -/*===================== - * Getter functions - *====================*/ - -/** - * Get the type of a chart - * @param chart pointer to chart object - * @return type of the chart (from 'lv_chart_t' enum) - */ -lv_chart_type_t lv_chart_get_type(const lv_obj_t * obj) -{ - LV_ASSERT_OBJ(obj, LV_OBJX_NAME); - - lv_chart_t * chart = (lv_chart_t *)obj; - return chart->type; -} - -/** - * Get the data point number per data line on chart - * @param chart pointer to chart object - * @return point number on each data line - */ -uint16_t lv_chart_get_point_count(const lv_obj_t * obj) -{ - LV_ASSERT_OBJ(obj, LV_OBJX_NAME); - - lv_chart_t * chart = (lv_chart_t *)obj; - return chart->point_cnt; -} - -/** - * Get the current index of the x-axis start point in the data array - * @param ser pointer to a data series on 'chart' - * @return the index of the current x start point in the data array - */ -uint16_t lv_chart_get_x_start_point(lv_chart_series_t * ser) -{ - LV_ASSERT_NULL(ser); - - return(ser->start_point); -} - -/** - * Get an individual point y value in the chart series directly based on index - * @param chart pointer to a chart object - * @param ser pointer to a data series on 'chart' - * @param id the index of the x point in the array - * @return value of array point at index id - */ -lv_coord_t lv_chart_get_point_id(lv_obj_t * obj, lv_chart_series_t * ser, uint16_t id) -{ - LV_ASSERT_OBJ(obj, LV_OBJX_NAME); - LV_ASSERT_NULL(ser); - - lv_chart_t * chart = (lv_chart_t *)obj; - if(id >= chart->point_cnt) id = 0; - return(ser->points[id]); - -} - -/** - * Get the Y axis of a series - * @param chart pointer to a chart object - * @param ser pointer to series - * @return `LV_CHART_AXIS_PRIMARY_Y` or `LV_CHART_AXIS_SECONDARY_Y` - */ -lv_chart_axis_t lv_chart_get_series_axis(lv_obj_t * obj, lv_chart_series_t * ser) -{ - LV_ASSERT_NULL(ser); - LV_UNUSED(obj); - - return ser->y_axis; -} - -/** - * Get the coordinate of the cursor with respect - * to the origin of series area of the chart. - * @param chart pointer to a chart object - * @param cursor pointer to cursor - * @return coordinate of the cursor as lv_point_t - */ -lv_point_t lv_chart_get_cursor_point(lv_obj_t * obj, lv_chart_cursor_t * cursor) -{ - LV_ASSERT_NULL(cursor); - LV_UNUSED(obj); - - return cursor->point; -} - -/** - * Get the x coordinate of the an index with respect - * to the origin of series area of the chart. - * @param chart pointer to a chart object - * @param ser pointer to series - * @param id the index. - * @return x coordinate of index - */ -lv_coord_t lv_chart_get_x_from_index(lv_obj_t * obj, lv_chart_series_t * ser, uint16_t id) -{ - LV_ASSERT_NULL(obj); - LV_ASSERT_NULL(ser); - - lv_chart_t * chart = (lv_chart_t *)obj; - if(id >= chart->point_cnt) { - LV_LOG_WARN("Invalid index: %d", id); - return 0; - } - - lv_coord_t w = lv_obj_get_width(obj); - - lv_coord_t x = 0; - - if(chart->type & LV_CHART_TYPE_LINE) { - x = (w * id) / (chart->point_cnt - 1); - } - else if(chart->type & LV_CHART_TYPE_COLUMN) { - lv_coord_t col_w = w / ((_lv_ll_get_len(&chart->series_ll) + 1) * chart->point_cnt); /* Suppose + 1 series as separator*/ - lv_chart_series_t * itr_ser = NULL; - lv_coord_t col_space = lv_obj_get_style_pad_left(obj, LV_PART_ITEMS); - - x = (int32_t)((int32_t)w * id) / chart->point_cnt; - x += col_w / 2; /*Start offset*/ - - _LV_LL_READ_BACK(&chart->series_ll, itr_ser) { - if(itr_ser == ser) break; - x += col_w; - } - - x += (col_w - col_space) / 2; - } - - return x; -} - -/** - * Get the y coordinate of the an index with respect - * to the origin of series area of the chart. - * @param chart pointer to a chart object - * @param ser pointer to series - * @param id the index. - * @return y coordinate of index - */ -lv_coord_t lv_chart_get_y_from_index(lv_obj_t * obj, lv_chart_series_t * ser, uint16_t id) -{ - LV_ASSERT_NULL(obj); - LV_ASSERT_NULL(ser); - - lv_chart_t * chart = (lv_chart_t *)obj; - if(id >= chart->point_cnt) { - LV_LOG_WARN("Invalid index: %d", id); - return 0; - } - - lv_coord_t h = lv_obj_get_height(obj); - - int32_t y = (int32_t)((int32_t)ser->points[id] - chart->ymin[ser->y_axis]) * h; - y = y / (chart->ymax[ser->y_axis] - chart->ymin[ser->y_axis]); - y = h - y; - - return (lv_coord_t)y; -} - -/*===================== - * Other functions - *====================*/ - -/** - * Refresh a chart if its data line has changed - * @param chart pointer to chart object - */ -void lv_chart_refresh(lv_obj_t * obj) -{ - LV_ASSERT_OBJ(obj, LV_OBJX_NAME); - + if(!ser->ext_buf_assigned && ser->points) lv_mem_free(ser->points); + ser->ext_buf_assigned = true; + ser->points = array; lv_obj_invalidate(obj); } +lv_coord_t * lv_chart_get_array(const lv_obj_t * obj, lv_chart_series_t * ser) +{ + LV_ASSERT_OBJ(obj, LV_OBJX_NAME); + LV_ASSERT_NULL(ser); + return ser->points; +} + +int32_t lv_chart_get_pressed_point(const lv_obj_t * obj) +{ + lv_chart_t * chart = (lv_chart_t *) obj; + return chart->pressed_point_id; +} + /********************** * STATIC FUNCTIONS **********************/ - - static void lv_chart_constructor(lv_obj_t * obj, lv_obj_t * parent, const lv_obj_t * copy) { LV_LOG_TRACE("chart create started"); @@ -726,7 +499,6 @@ static void lv_chart_constructor(lv_obj_t * obj, lv_obj_t * parent, const lv_obj lv_chart_t * chart = (lv_chart_t *) obj; _lv_ll_init(&chart->series_ll, sizeof(lv_chart_series_t)); - _lv_ll_init(&chart->cursors_ll, sizeof(lv_chart_cursor_t)); chart->ymin[LV_CHART_AXIS_PRIMARY_Y] = LV_CHART_YMIN_DEF; chart->ymax[LV_CHART_AXIS_PRIMARY_Y] = LV_CHART_YMAX_DEF; @@ -735,14 +507,12 @@ static void lv_chart_constructor(lv_obj_t * obj, lv_obj_t * parent, const lv_obj chart->hdiv_cnt = LV_CHART_HDIV_DEF; chart->vdiv_cnt = LV_CHART_VDIV_DEF; - chart->point_cnt = LV_CHART_PNUM_DEF; - chart->sub_tick_cnt[0] = 5; - chart->sub_tick_cnt[1] = 5; - chart->sub_tick_cnt[2] = 5; + chart->point_cnt = LV_CHART_POINT_CNT_DEF; + chart->pressed_point_id = -1; chart->type = LV_CHART_TYPE_LINE; chart->update_mode = LV_CHART_UPDATE_MODE_SHIFT; - chart->x_zoom = 512; - chart->y_zoom = 256; + chart->zoom_x = LV_IMG_ZOOM_NONE; + chart->zoom_y = LV_IMG_ZOOM_NONE; /*Init the new chart background object*/ if(copy == NULL) { @@ -763,40 +533,19 @@ static void lv_chart_constructor(lv_obj_t * obj, lv_obj_t * parent, const lv_obj static void lv_chart_destructor(lv_obj_t * obj) { + lv_chart_t * chart = (lv_chart_t *) obj; + lv_chart_series_t * ser; + while(chart->series_ll.head) { + ser = _lv_ll_get_head(&chart->series_ll); -// lv_chart_series_t * ser; -// while(chart->series_ll.head != NULL) { -// ser = _lv_ll_get_head(&chart->series_ll); -// -// if(!ser->ext_buf_assigned) lv_mem_free(ser->points); -// -// _lv_ll_remove(&chart->series_ll, ser); -// lv_mem_free(ser); -// } -// _lv_ll_clear(&chart->series_ll); -// -// _lv_obj_reset_style_list_no_refr(chart, LV_PART_ITEMS); -// _lv_obj_reset_style_list_no_refr(chart, LV_PART_CURSOR); -// _lv_obj_reset_style_list_no_refr(chart, LV_PART_MAIN); -//} + if(!ser->ext_buf_assigned) lv_mem_free(ser->points); - // lv_bar_t * bar = obj; - // - // _lv_obj_reset_style_list_no_refr(obj, LV_BAR_PART_INDIC); - // _lv_obj_reset_style_list_no_refr(sw, LV_PART_KNOB); - // - // bar->class_p->base_p->destructor(obj); + _lv_ll_remove(&chart->series_ll, ser); + lv_mem_free(ser); + } + _lv_ll_clear(&chart->series_ll); } -/** - * Handle the drawing related tasks of the chart backgrounds - * @param chart pointer to an object - * @param clip_area the object will be drawn only in this area - * @param mode LV_DRAW_COVER_CHK: only check if the object fully covers the 'mask_p' area - * (return 'true' if yes) - * LV_DRAW_DRAW: draw the object (always return 'true') - * LV_DRAW_DRAW_POST: drawing after every children are drawn - * @param return an element of `lv_draw_res_t` - */ + static lv_draw_res_t lv_chart_draw(lv_obj_t * obj, const lv_area_t * clip_area, lv_draw_mode_t mode) { if(mode == LV_DRAW_MODE_COVER_CHECK) { @@ -810,9 +559,7 @@ static lv_draw_res_t lv_chart_draw(lv_obj_t * obj, const lv_area_t * clip_area, lv_chart_t * chart = (lv_chart_t *)obj; if(chart->type & LV_CHART_TYPE_LINE) draw_series_line(obj, clip_area); - else if(chart->type & LV_CHART_TYPE_COLUMN) draw_series_column(obj, clip_area); - - draw_cursors(obj, clip_area); + else if(chart->type & LV_CHART_TYPE_BAR) draw_series_bar(obj, clip_area); } else if(mode == LV_DRAW_MODE_POST_DRAW) { lv_obj.draw_cb(obj, clip_area, mode); @@ -820,12 +567,6 @@ static lv_draw_res_t lv_chart_draw(lv_obj_t * obj, const lv_area_t * clip_area, return LV_DRAW_RES_OK; } -/** - * Signal function of the chart background - * @param chart pointer to a chart background object - * @param sign a signal type from lv_signal_t enum - * @param param pointer to a signal specific variable - */ static lv_res_t lv_chart_signal(lv_obj_t * obj, lv_signal_t sign, void * param) { /* Include the ancient signal function */ @@ -836,36 +577,33 @@ static lv_res_t lv_chart_signal(lv_obj_t * obj, lv_signal_t sign, void * param) lv_chart_t * chart = (lv_chart_t *)obj; if(sign == LV_SIGNAL_GET_SELF_SIZE) { lv_point_t * p = param; - p->x = (lv_obj_get_width(obj) * chart->x_zoom) >> 8; - p->y = (lv_obj_get_height(obj) * chart->y_zoom) >> 8; - } else if(sign == LV_SIGNAL_REFR_EXT_DRAW_SIZE) { - lv_coord_t * s = param; - *s = LV_MAX(*s, chart->ext_size); - } else if(sign == LV_SIGNAL_PRESSING) { + p->x = (lv_obj_get_width_fit(obj) * chart->zoom_x) >> 8; + p->y = (lv_obj_get_height_fit(obj) * chart->zoom_y) >> 8; + } else if(sign == LV_SIGNAL_PRESSED) { lv_indev_t * indev = lv_indev_get_act(); lv_point_t p; lv_indev_get_point(indev, &p); p.x -= obj->coords.x1; - uint32_t id = get_index_from_x(obj, p.x); + uint32_t id = get_index_from_x(obj, p.x + lv_obj_get_scroll_left(obj)); if(id != chart->pressed_point_id) { invalidate_point(obj, id); invalidate_point(obj, chart->pressed_point_id); chart->pressed_point_id = id; + lv_event_send(obj, LV_EVENT_VALUE_CHANGED, NULL); } - } else if(sign == LV_SIGNAL_PRESSING) { - invalidate_point(obj, chart->pressed_point_id); + } else if(sign == LV_SIGNAL_RELEASED) { +// invalidate_point(obj, chart->pressed_point_id); chart->pressed_point_id = -1; + } else if(sign == LV_SIGNAL_REFR_EXT_DRAW_SIZE) { + lv_coord_t * s = param; + *s = LV_MAX4(*s, chart->tick[LV_CHART_AXIS_X].draw_size, + chart->tick[LV_CHART_AXIS_PRIMARY_Y].draw_size, chart->tick[LV_CHART_AXIS_SECONDARY_Y].draw_size); } return res; } -/** - * Draw the division lines on chart background - * @param chart pointer to chart object - * @param clip_area mask, inherited from the draw function - */ static void draw_div_lines(lv_obj_t * obj, const lv_area_t * clip_area) { lv_chart_t * chart = (lv_chart_t *)obj; @@ -877,17 +615,20 @@ static void draw_div_lines(lv_obj_t * obj, const lv_area_t * clip_area) uint32_t i; lv_point_t p1; lv_point_t p2; - lv_coord_t h = (lv_obj_get_height(obj) * chart->y_zoom) >> 8; - lv_coord_t w = (lv_obj_get_width(obj) * chart->x_zoom) >> 8; - lv_coord_t x_ofs = obj->coords.x1 - lv_obj_get_scroll_left(obj); - lv_coord_t y_ofs = obj->coords.y1 - lv_obj_get_scroll_top(obj); + lv_coord_t pad_left = lv_obj_get_style_pad_left(obj, LV_PART_MAIN); + lv_coord_t pad_top = lv_obj_get_style_pad_top(obj, LV_PART_MAIN); + lv_coord_t w = (lv_obj_get_width_fit(obj) * chart->zoom_x) >> 8; + lv_coord_t h = (lv_obj_get_height_fit(obj) * chart->zoom_y) >> 8; lv_draw_line_dsc_t line_dsc; lv_draw_line_dsc_init(&line_dsc); lv_obj_init_draw_line_dsc(obj, LV_PART_MAIN, &line_dsc); + lv_coord_t scroll_left = lv_obj_get_scroll_left(obj); + lv_coord_t scroll_top = lv_obj_get_scroll_top(obj); if(chart->hdiv_cnt != 0) { - p1.x = obj->coords.x1; + lv_coord_t y_ofs = obj->coords.y1 + pad_top - scroll_top; + p1.x = obj->coords.x1 + scroll_left; p2.x = obj->coords.x2; for(i = 0; i <= chart->hdiv_cnt + 1; i++) { p1.y = (int32_t)((int32_t)(h - line_dsc.width) * i) / (chart->hdiv_cnt + 1); @@ -898,7 +639,8 @@ static void draw_div_lines(lv_obj_t * obj, const lv_area_t * clip_area) } if(chart->vdiv_cnt != 0) { - p1.y = obj->coords.y1; + lv_coord_t x_ofs = obj->coords.x1 + pad_left - scroll_left; + p1.y = obj->coords.y1 + scroll_top; p2.y = obj->coords.y2; for(i = 0; i <= chart->vdiv_cnt + 1; i++) { p1.x = (int32_t)((int32_t)(w - line_dsc.width) * i) / (chart->vdiv_cnt + 1); @@ -909,10 +651,6 @@ static void draw_div_lines(lv_obj_t * obj, const lv_area_t * clip_area) } } -/** - * Draw the data lines as lines on a chart - * @param obj pointer to chart object - */ static void draw_series_line(lv_obj_t * obj, const lv_area_t * clip_area) { lv_area_t com_area; @@ -923,10 +661,12 @@ static void draw_series_line(lv_obj_t * obj, const lv_area_t * clip_area) uint16_t i; lv_point_t p1; lv_point_t p2; - lv_coord_t w = (lv_obj_get_width(obj) * chart->x_zoom) >> 8; - lv_coord_t h = lv_obj_get_height(obj); - lv_coord_t x_ofs = obj->coords.x1 - lv_obj_get_scroll_left(obj); - lv_coord_t y_ofs = obj->coords.y1 - lv_obj_get_scroll_top(obj); + lv_coord_t pad_left = lv_obj_get_style_pad_left(obj, LV_PART_MAIN); + lv_coord_t pad_top = lv_obj_get_style_pad_top(obj, LV_PART_MAIN); + lv_coord_t w = (lv_obj_get_width_fit(obj) * chart->zoom_x) >> 8; + lv_coord_t h = (lv_obj_get_height_fit(obj) * chart->zoom_y) >> 8; + lv_coord_t x_ofs = obj->coords.x1 + pad_left - lv_obj_get_scroll_left(obj); + lv_coord_t y_ofs = obj->coords.y1 + pad_top - lv_obj_get_scroll_top(obj); lv_chart_series_t * ser; lv_area_t series_mask; @@ -961,7 +701,7 @@ static void draw_series_line(lv_obj_t * obj, const lv_area_t * clip_area) line_dsc_default.color = ser->color; point_dsc_default.bg_color = ser->color; - lv_coord_t start_point = chart->update_mode == LV_CHART_UPDATE_MODE_SHIFT ? ser->start_point : 0; + lv_coord_t start_point = chart->update_mode == LV_CHART_UPDATE_MODE_SHIFT ? ser->last_point : 0; p1.x = x_ofs; p2.x = x_ofs; @@ -996,17 +736,17 @@ static void draw_series_line(lv_obj_t * obj, const lv_area_t * clip_area) if(p2.x < clip_area->x1 - point_size_act) continue; hook_dsc.id = p_act; - hook_dsc.p1 = &p1; - hook_dsc.p2 = &p2; + hook_dsc.p1 = ser->points[p_prev] != LV_CHART_POINT_DEF ? &p1 : NULL; + hook_dsc.p2 = ser->points[p_act] != LV_CHART_POINT_DEF ? &p2 : NULL; lv_event_send(obj, LV_EVENT_DRAW_PART_BEGIN, &hook_dsc); /*Don't draw the first point. A second point is also required to draw the line*/ if(i != 0 && ser->points[p_prev] != LV_CHART_POINT_DEF && ser->points[p_act] != LV_CHART_POINT_DEF) { - lv_draw_line(&p1, &p2, &series_mask, &line_dsc_default); + lv_draw_line(&p1, &p2, &series_mask, &line_dsc_default); } - if(point_size_act) { + if(point_size_act && ser->points[p_prev] != LV_CHART_POINT_DEF) { lv_area_t point_area; point_area.x1 = p1.x; @@ -1017,9 +757,7 @@ static void draw_series_line(lv_obj_t * obj, const lv_area_t * clip_area) point_area.y2 = point_area.y1 + point_size_act; point_area.y1 -= point_size_act; - if(ser->points[p_act] != LV_CHART_POINT_DEF) { - lv_draw_rect(&point_area, &series_mask, &point_dsc_default); - } + lv_draw_rect(&point_area, &series_mask, &point_dsc_default); } lv_event_send(obj, LV_EVENT_DRAW_PART_END, &hook_dsc); @@ -1028,15 +766,16 @@ static void draw_series_line(lv_obj_t * obj, const lv_area_t * clip_area) /*Draw the last point*/ if(point_size) { - lv_area_t point_area; + point_size_act = p_act == chart->pressed_point_id ? point_size_pr : point_size; + lv_area_t point_area; point_area.x1 = p2.x; - point_area.x2 = point_area.x1 + point_size; - point_area.x1 -= point_size; + point_area.x2 = point_area.x1 + point_size_act; + point_area.x1 -= point_size_act; point_area.y1 = p2.y; - point_area.y2 = point_area.y1 + point_size; - point_area.y1 -= point_size; + point_area.y2 = point_area.y1 + point_size_act; + point_area.y1 -= point_size_act; if(ser->points[p_act] != LV_CHART_POINT_DEF) { lv_draw_rect(&point_area, &series_mask, &point_dsc_default); @@ -1045,12 +784,7 @@ static void draw_series_line(lv_obj_t * obj, const lv_area_t * clip_area) } } -/** - * Draw the data lines as columns on a chart - * @param chart pointer to chart object - * @param mask mask, inherited from the draw function - */ -static void draw_series_column(lv_obj_t * obj, const lv_area_t * clip_area) +static void draw_series_bar(lv_obj_t * obj, const lv_area_t * clip_area) { lv_area_t com_area; if(_lv_area_intersect(&com_area, &obj->coords, clip_area) == false) return; @@ -1059,15 +793,19 @@ static void draw_series_column(lv_obj_t * obj, const lv_area_t * clip_area) uint16_t i; lv_area_t col_a; - lv_coord_t w = lv_obj_get_width(obj); - lv_coord_t h = lv_obj_get_height(obj); + lv_coord_t pad_left = lv_obj_get_style_pad_left(obj, LV_PART_MAIN); + lv_coord_t pad_top = lv_obj_get_style_pad_top(obj, LV_PART_MAIN); + lv_coord_t w = (lv_obj_get_width_fit(obj) * chart->zoom_x) >> 8; + lv_coord_t h = (lv_obj_get_height_fit(obj) * chart->zoom_y) >> 8; int32_t y_tmp; lv_chart_series_t * ser; - lv_coord_t col_w = w / ((_lv_ll_get_len(&chart->series_ll) + 1) * chart->point_cnt); /* Suppose + 1 series as separator*/ - lv_coord_t x_ofs = col_w / 2 - lv_obj_get_scroll_left(obj);; /*Shift with a half col.*/ - lv_coord_t col_space = lv_obj_get_style_pad_left(obj, LV_PART_ITEMS); - - lv_coord_t y_ofs = -lv_obj_get_scroll_top(obj); + uint32_t ser_cnt = _lv_ll_get_len(&chart->series_ll); + uint32_t ser_gap = lv_obj_get_style_pad_column(obj, LV_PART_ITEMS); /*Gap between the column on the ~same X */ + uint32_t block_gap = lv_obj_get_style_pad_column(obj, LV_PART_MAIN); /*Gap between the column on ~adjacent X*/ + lv_coord_t block_w = (w) / chart->point_cnt - block_gap; + lv_coord_t col_w = block_w / ser_cnt; + lv_coord_t x_ofs = pad_left - lv_obj_get_scroll_left(obj); + lv_coord_t y_ofs = pad_top - lv_obj_get_scroll_top(obj); lv_draw_rect_dsc_t col_dsc; lv_draw_rect_dsc_init(&col_dsc); @@ -1076,7 +814,7 @@ static void draw_series_column(lv_obj_t * obj, const lv_area_t * clip_area) col_dsc.bg_opa = LV_OPA_COVER; /*Make the cols longer with `radius` to clip the rounding from the bottom*/ - col_a.y2 = obj->coords.y2 + col_dsc.radius + y_ofs; + col_a.y2 = obj->coords.y2 + col_dsc.radius; lv_area_t series_mask; bool mask_ret = _lv_area_intersect(&series_mask, &obj->coords, clip_area); @@ -1084,16 +822,15 @@ static void draw_series_column(lv_obj_t * obj, const lv_area_t * clip_area) /*Go through all points*/ for(i = 0; i < chart->point_cnt; i++) { - lv_coord_t x_act = (int32_t)((int32_t)w * i) / chart->point_cnt; - x_act += obj->coords.x1 + x_ofs; + lv_coord_t x_act = (int32_t)((int32_t)(w + block_gap) * i) / (chart->point_cnt) + obj->coords.x1 + x_ofs; /*Draw the current point of all data line*/ _LV_LL_READ_BACK(&chart->series_ll, ser) { if (ser->hidden) continue; - lv_coord_t start_point = chart->update_mode == LV_CHART_UPDATE_MODE_SHIFT ? ser->start_point : 0; + lv_coord_t start_point = chart->update_mode == LV_CHART_UPDATE_MODE_SHIFT ? ser->last_point : 0; col_a.x1 = x_act; - col_a.x2 = col_a.x1 + col_w - col_space; + col_a.x2 = col_a.x1 + col_w - ser_gap - 1; x_act += col_w; if(col_a.x2 < series_mask.x1) continue; @@ -1113,150 +850,59 @@ static void draw_series_column(lv_obj_t * obj, const lv_area_t * clip_area) } } -/** - * Draw the cursors as lines on a chart - * @param chart pointer to chart object - * @param clip_area the object will be drawn only in this area - */ -static void draw_cursors(lv_obj_t * obj, const lv_area_t * clip_area) -{ - lv_area_t series_mask; - bool mask_ret = _lv_area_intersect(&series_mask, &obj->coords, clip_area); - if(mask_ret == false) return; - - lv_chart_t * chart = (lv_chart_t *)obj; - if(_lv_ll_is_empty(&chart->cursors_ll)) return; - - lv_point_t p1; - lv_point_t p2; - lv_chart_cursor_t * cursor; - - lv_draw_line_dsc_t line_dsc; - lv_draw_line_dsc_init(&line_dsc); - lv_obj_init_draw_line_dsc(obj, LV_PART_MARKER, &line_dsc); - - lv_draw_rect_dsc_t point_dsc; - lv_draw_rect_dsc_init(&point_dsc); - point_dsc.bg_opa = line_dsc.opa; - point_dsc.radius = LV_RADIUS_CIRCLE; - - lv_coord_t point_radius = lv_obj_get_style_size(chart, LV_PART_MARKER); - - /*Do not bother with line ending is the point will over it*/ - if(point_radius > line_dsc.width / 2) line_dsc.raw_end = 1; - - /*Go through all cursor lines*/ - _LV_LL_READ_BACK(&chart->cursors_ll, cursor) { - line_dsc.color = cursor->color; - point_dsc.bg_color = cursor->color; - - if(cursor->axes & LV_DIR_RIGHT) { - p1.x = obj->coords.x1 + cursor->point.x; - p1.y = obj->coords.y1 + cursor->point.y; - p2.x = obj->coords.x2; - p2.y = p1.y; - lv_draw_line(&p1, &p2, &series_mask, &line_dsc); - } - - if(cursor->axes & LV_DIR_TOP) { - - p1.x = obj->coords.x1 + cursor->point.x; - p1.y = obj->coords.y1; - p2.x = p1.x; - p2.y = obj->coords.y1 + cursor->point.y; - lv_draw_line(&p1, &p2, &series_mask, &line_dsc); - } - - if(cursor->axes & LV_DIR_LEFT) { - p1.x = obj->coords.x1; - p1.y = obj->coords.y1 + cursor->point.y; - p2.x = p1.x + cursor->point.x; - p2.y = p1.y; - lv_draw_line(&p1, &p2, &series_mask, &line_dsc); - } - - if(cursor->axes & LV_DIR_BOTTOM) { - - p1.x = obj->coords.x1 + cursor->point.x; - p1.y = obj->coords.y1 + cursor->point.y; - p2.x = p1.x; - p2.y = obj->coords.y2; - lv_draw_line(&p1, &p2, &series_mask, &line_dsc); - } - - if(point_radius) { - lv_area_t point_area; - - point_area.x1 = obj->coords.x1 + cursor->point.x - point_radius; - point_area.x2 = obj->coords.x1 + cursor->point.x + point_radius; - - point_area.y1 = obj->coords.y1 + cursor->point.y - point_radius; - point_area.y2 = obj->coords.y1 + cursor->point.y + point_radius; - - /*Don't limit to `series_mask` to get full circles on the ends*/ - lv_draw_rect(&point_area, clip_area, &point_dsc); - } - - } - -} - static void draw_y_ticks(lv_obj_t * obj, const lv_area_t * clip_area, lv_chart_axis_t axis) { lv_chart_t * chart = (lv_chart_t *)obj; + lv_chart_tick_dsc_t * t = &chart->tick[axis]; + if(t->major_cnt <= 1) return; + if(!t->label_en && !t->major_len && !t->minor_len) return; + uint32_t i; - uint32_t major_tick_cnt = chart->hdiv_cnt + 1; - uint32_t sub_tick_cnt = chart->sub_tick_cnt[LV_CHART_AXIS_X] + 1; lv_point_t p1; lv_point_t p2; - lv_coord_t x_ofs; - lv_coord_t y_ofs = obj->coords.y1; - lv_coord_t h = (lv_obj_get_height(obj) * chart->y_zoom) >> 8; - /* chose correct side of the chart */ - lv_coord_t major_tick_len; + lv_coord_t pad_top = lv_obj_get_style_pad_top(obj, LV_PART_MAIN); + lv_coord_t h = (lv_obj_get_height_fit(obj) * chart->zoom_y) >> 8; + lv_coord_t y_ofs = obj->coords.y1 + pad_top - lv_obj_get_scroll_top(obj); + + lv_coord_t label_gap; + lv_coord_t x_ofs; if(axis == LV_CHART_AXIS_PRIMARY_Y) { + label_gap = lv_obj_get_style_pad_left(obj, LV_PART_MARKER); x_ofs = obj->coords.x1; - major_tick_len = lv_obj_get_style_pad_left(obj, LV_PART_MARKER); } else { + label_gap = lv_obj_get_style_pad_right(obj, LV_PART_MARKER); x_ofs = obj->coords.x2; - major_tick_len = lv_obj_get_style_pad_right(obj, LV_PART_MARKER); } - lv_coord_t minor_tick_len = major_tick_len / 2; - lv_coord_t label_gap = TICK_LABEL_GAP; - + lv_coord_t major_len = t->major_len; + lv_coord_t minor_len = t->minor_len; /* tick lines on secondary y axis are drawn in other direction*/ if(axis == LV_CHART_AXIS_SECONDARY_Y) { - major_tick_len *= -1; - minor_tick_len *= -1; + major_len *= -1; + minor_len *= -1; } lv_obj_draw_hook_dsc_t hook_dsc; lv_obj_draw_hook_dsc_init(&hook_dsc, clip_area); - hook_dsc.id = axis; + hook_dsc.sub_part_id = axis; hook_dsc.part = LV_PART_MARKER; lv_draw_line_dsc_t line_dsc; lv_draw_line_dsc_init(&line_dsc); lv_obj_init_draw_line_dsc(obj, LV_PART_MARKER, &line_dsc); - line_dsc.dash_gap = 0; - line_dsc.dash_width = 0; lv_draw_label_dsc_t label_dsc; lv_draw_label_dsc_init(&label_dsc); lv_obj_init_draw_label_dsc(obj, LV_PART_MARKER, &label_dsc); - uint32_t total_tick_num = major_tick_cnt * sub_tick_cnt; + uint32_t total_tick_num = (t->major_cnt - 1) * (t->minor_cnt); for(i = 0; i <= total_tick_num; i++) { /* draw a line at moving y position */ p2.y = p1.y = y_ofs + (int32_t)((int32_t)(h - line_dsc.width) * i) / total_tick_num; - if(p2.y - label_dsc.font->line_height > clip_area->y2) return; - if(p2.y + label_dsc.font->line_height < clip_area->y1) continue; - /* first point of the tick */ p1.x = x_ofs; @@ -1266,40 +912,48 @@ static void draw_y_ticks(lv_obj_t * obj, const lv_area_t * clip_area, lv_chart_a /* second point of the tick */ bool major = false; - if(i % sub_tick_cnt == 0) major = true; + if(i % t->minor_cnt == 0) major = true; - if(major) p2.x = p1.x - major_tick_len; /* major tick */ - else p2.x = p1.x - minor_tick_len; /* minor tick */ + if(major) p2.x = p1.x - major_len; /* major tick */ + else p2.x = p1.x - minor_len; /* minor tick */ - lv_draw_line(&p1, &p2, clip_area, &line_dsc); + if(p1.y + line_dsc.width / 2 >= obj->coords.y1 && + p2.y - line_dsc.width / 2 <= obj->coords.y2) + { + lv_draw_line(&p1, &p2, clip_area, &line_dsc); + } /* add text only to major tick */ - if(!major) continue; + if(major && t->label_en) { + int32_t tick_value = chart->ymax[axis] - lv_map(i, 0, total_tick_num, chart->ymin[axis], chart->ymax[axis]); + lv_snprintf(hook_dsc.text, sizeof(hook_dsc.text), "%d", tick_value); + hook_dsc.id = tick_value; + lv_event_send(obj, LV_EVENT_DRAW_PART_BEGIN, &hook_dsc); - int32_t tick_value = chart->ymax[axis] - lv_map(i, 0, total_tick_num, chart->ymin[axis], chart->ymax[axis]); - lv_snprintf(hook_dsc.text, sizeof(hook_dsc.text), "%d", tick_value); - lv_event_send(obj, LV_EVENT_DRAW_PART_BEGIN, &hook_dsc); + /* reserve appropriate area */ + lv_point_t size; + lv_txt_get_size(&size, hook_dsc.text, label_dsc.font, label_dsc.letter_space, label_dsc.line_space, LV_COORD_MAX, LV_TEXT_FLAG_NONE); - /* reserve appropriate area */ - lv_point_t size; - _lv_txt_get_size(&size, hook_dsc.text, label_dsc.font, label_dsc.letter_space, label_dsc.line_space, - LV_COORD_MAX, LV_TEXT_FLAG_CENTER); + /* set the area at some distance of the major tick len left of the tick */ + lv_area_t a; + a.y1 = p2.y - size.y / 2; + a.y2 = p2.y + size.y / 2; - /* set the area at some distance of the major tick len left of the tick */ - lv_area_t a; - a.y1 = p2.y - size.y / 2; - a.y2 = p2.y + size.y / 2; + if(axis == LV_CHART_AXIS_PRIMARY_Y) { + a.x1 = p2.x - size.x - label_gap; + a.x2 = p2.x - label_gap; + } + else { + a.x1 = p2.x + label_gap; + a.x2 = p2.x + size.x + label_gap; + } - if(axis == LV_CHART_AXIS_PRIMARY_Y) { - a.x1 = p2.x - size.x - label_gap; - a.x2 = p2.x - label_gap; + if(a.y2 >= obj->coords.y1 && + a.y1 <= obj->coords.y2) + { + lv_draw_label(&a, clip_area, &label_dsc, hook_dsc.text, NULL); + } } - else { - a.x1 = p2.x + label_gap; - a.x2 = p2.x + size.x + label_gap; - } - - lv_draw_label(&a, clip_area, &label_dsc, hook_dsc.text, NULL); } } @@ -1307,30 +961,31 @@ static void draw_x_ticks(lv_obj_t * obj, const lv_area_t * clip_area) { lv_chart_t * chart = (lv_chart_t *)obj; - lv_area_t series_mask; - bool mask_ret = _lv_area_intersect(&series_mask, &obj->coords, clip_area); - if(mask_ret == false) return; + + lv_chart_tick_dsc_t * t = &chart->tick[LV_CHART_AXIS_X]; + if(t->major_cnt <= 1) return; + if(!t->label_en && !t->major_len && !t->minor_len) return; uint32_t i; - uint32_t major_tick_cnt = chart->vdiv_cnt + 1; - uint32_t sub_tick_cnt = chart->sub_tick_cnt[LV_CHART_AXIS_X] + 1; lv_point_t p1; lv_point_t p2; - lv_coord_t x_ofs = obj->coords.x1 - lv_obj_get_scroll_left(obj); - lv_coord_t y_ofs = obj->coords.y1; - lv_coord_t h = lv_obj_get_height(obj); - lv_coord_t w = (lv_obj_get_width(obj) * chart->x_zoom) >> 8; + + lv_coord_t pad_left = lv_obj_get_style_pad_left(obj, LV_PART_MAIN); + lv_coord_t pad_top = lv_obj_get_style_pad_top(obj, LV_PART_MAIN); + lv_coord_t w = (lv_obj_get_width_fit(obj) * chart->zoom_x) >> 8; + lv_coord_t h = (lv_obj_get_height_fit(obj) * chart->zoom_y) >> 8; + + lv_coord_t x_ofs = obj->coords.x1 + pad_left - lv_obj_get_scroll_left(obj); + lv_coord_t y_ofs = obj->coords.y1 + pad_top; lv_draw_label_dsc_t label_dsc; lv_draw_label_dsc_init(&label_dsc); lv_obj_init_draw_label_dsc(obj, LV_PART_MARKER, &label_dsc); - lv_coord_t major_tick_len = lv_obj_get_style_pad_bottom(obj, LV_PART_MARKER); - lv_coord_t minor_tick_len = major_tick_len / 2; - lv_coord_t label_gap = TICK_LABEL_GAP; + lv_coord_t label_gap = t->label_en ? lv_obj_get_style_pad_bottom(obj, LV_PART_MARKER) : 0; if(h + y_ofs > clip_area->y2) return; - if(h + y_ofs + label_gap + label_dsc.font->line_height + major_tick_len < clip_area->y1) return; + if(h + y_ofs + label_gap + label_dsc.font->line_height + t->major_len < clip_area->y1) return; lv_draw_line_dsc_t line_dsc; lv_draw_line_dsc_init(&line_dsc); @@ -1340,42 +995,45 @@ static void draw_x_ticks(lv_obj_t * obj, const lv_area_t * clip_area) lv_obj_draw_hook_dsc_t hook_dsc; lv_obj_draw_hook_dsc_init(&hook_dsc, clip_area); - hook_dsc.id = LV_CHART_AXIS_X; + hook_dsc.sub_part_id = LV_CHART_AXIS_X; hook_dsc.part = LV_PART_MARKER; - - /* The columns don't start at the most right position - * so change the width and offset accordingly. */ - if(chart->type == LV_CHART_TYPE_COLUMN) { - uint32_t ser_num = _lv_ll_get_len(&chart->series_ll); - lv_coord_t col_w = w / ((ser_num + 1) * chart->point_cnt); /* Suppose + 1 series as separator*/ - x_ofs += col_w / 2 + (col_w * (ser_num) / 2); - w -= col_w * ser_num + col_w; + /* The columns ticks should be aligned to the center of blocks */ + if(chart->type == LV_CHART_TYPE_BAR) { + uint32_t block_gap = lv_obj_get_style_pad_column(obj, LV_PART_MAIN); /*Gap between the columns on ~adjacent X*/ + lv_coord_t block_w = (w + block_gap) / (chart->point_cnt); + x_ofs += block_w / 2; + w -= block_w; } p1.y = h + y_ofs; - uint32_t total_tick_num = major_tick_cnt * sub_tick_cnt; + uint32_t total_tick_num = (t->major_cnt - 1) * t->minor_cnt; for(i = 0; i <= total_tick_num; i++) { /* one extra loop - it may not exist in the list, empty label */ bool major = false; - if(i % sub_tick_cnt == 0) major = true; + if(i % t->minor_cnt == 0) major = true; /* draw a line at moving x position */ p2.x = p1.x = x_ofs + (int32_t)((int32_t)(w - line_dsc.width) * i) / total_tick_num; - if(p1.x > series_mask.x2) return; - p2.y = p1.y + (major ? major_tick_len : minor_tick_len); - lv_draw_line(&p1, &p2, clip_area, &line_dsc); + p2.y = p1.y + (major ? t->major_len : t->minor_len); - /* add text only to major tick */ - if(!major) continue; + if(p1.x + line_dsc.width / 2 >= obj->coords.x1 && + p2.x - line_dsc.width / 2 <= obj->coords.x2) + { + lv_draw_line(&p1, &p2, clip_area, &line_dsc); + } - lv_snprintf(hook_dsc.text, sizeof(hook_dsc.text), "%d", i / sub_tick_cnt); - lv_event_send(obj, LV_EVENT_DRAW_PART_BEGIN, &hook_dsc.text); + /* add text only to major tick */ + if(!major || !t->label_en) continue; + + int32_t tick_value = i / t->minor_cnt; + lv_snprintf(hook_dsc.text, sizeof(hook_dsc.text), "%d", i / t->minor_cnt); + hook_dsc.id = tick_value; + lv_event_send(obj, LV_EVENT_DRAW_PART_BEGIN, &hook_dsc); /* reserve appropriate area */ lv_point_t size; - _lv_txt_get_size(&size, hook_dsc.text, label_dsc.font, label_dsc.letter_space, label_dsc.line_space, - LV_COORD_MAX, LV_TEXT_FLAG_CENTER); + lv_txt_get_size(&size, hook_dsc.text, label_dsc.font, label_dsc.letter_space, label_dsc.line_space, LV_COORD_MAX, LV_TEXT_FLAG_NONE); /* set the area at some distance of the major tick len under of the tick */ lv_area_t a; @@ -1383,7 +1041,12 @@ static void draw_x_ticks(lv_obj_t * obj, const lv_area_t * clip_area) a.x2 = (p2.x + size.x / 2), a.y1 = p2.y + label_gap; a.y2 = (a.y1 + size.y); - lv_draw_label(&a, clip_area, &label_dsc, hook_dsc.text, NULL); + + if(a.x2 >= obj->coords.x1 && + a.x1 <= obj->coords.x2) + { + lv_draw_label(&a, clip_area, &label_dsc, hook_dsc.text, NULL); + } } } @@ -1401,31 +1064,28 @@ static void draw_axes(lv_obj_t * obj, const lv_area_t * mask) */ static uint32_t get_index_from_x(lv_obj_t * obj, lv_coord_t x) { - lv_coord_t w = lv_obj_get_width(obj); lv_chart_t * chart = (lv_chart_t *)obj; + lv_coord_t w = (lv_obj_get_width_fit(obj) * chart->zoom_x) >> 8; + lv_coord_t pad_left = lv_obj_get_style_pad_left(obj, LV_PART_MAIN); + x-= pad_left; if(x < 0) return 0; if(x > w) return chart->point_cnt - 1; if(chart->type == LV_CHART_TYPE_LINE) return (x * (chart->point_cnt - 1) + w / 2) / w; - if(chart->type == LV_CHART_TYPE_COLUMN) return (x * chart->point_cnt) / w; + if(chart->type == LV_CHART_TYPE_BAR) return (x * chart->point_cnt) / w; return 0; } -/** - * invalid area of the new line data lines on a chart - * @param obj pointer to chart object - */ static void invalidate_point(lv_obj_t * obj, uint16_t i) { + /*FIXME*/ lv_chart_t * chart = (lv_chart_t *)obj; if(i >= chart->point_cnt) return; - - lv_coord_t w = lv_obj_get_width(obj); + lv_coord_t w = lv_obj_get_width(obj); if(chart->type == LV_CHART_TYPE_LINE) { lv_coord_t x_ofs = obj->coords.x1; - lv_coord_t line_width = lv_obj_get_style_line_width(obj, LV_PART_ITEMS); lv_coord_t point_radius = lv_obj_get_style_size(obj, LV_PART_ITEMS); @@ -1446,7 +1106,7 @@ static void invalidate_point(lv_obj_t * obj, uint16_t i) lv_obj_invalidate_area(obj, &coords); } } - else if(chart->type == LV_CHART_TYPE_COLUMN) { + else if(chart->type == LV_CHART_TYPE_BAR) { lv_area_t col_a; lv_coord_t col_w = w / ((_lv_ll_get_len(&chart->series_ll) + 1) * chart->point_cnt); /* Suppose + 1 series as separator*/ lv_coord_t x_ofs = col_w / 2; /*Shift with a half col.*/ diff --git a/src/lv_widgets/lv_chart.h b/src/lv_widgets/lv_chart.h index acf7cfc5b..5299e661b 100644 --- a/src/lv_widgets/lv_chart.h +++ b/src/lv_widgets/lv_chart.h @@ -26,71 +26,78 @@ extern "C" { /**Default value of points. Can be used to not draw a point*/ #define LV_CHART_POINT_DEF (LV_COORD_MIN) - LV_EXPORT_CONST_INT(LV_CHART_POINT_DEF); -LV_EXPORT_CONST_INT(LV_CHART_TICK_LENGTH_AUTO); /********************** * TYPEDEFS **********************/ -/** Chart types*/ +/** + * Chart types + */ enum { LV_CHART_TYPE_NONE = 0x00, /**< Don't draw the series*/ LV_CHART_TYPE_LINE = 0x01, /**< Connect the points with lines*/ - LV_CHART_TYPE_COLUMN = 0x02, /**< Draw columns*/ + LV_CHART_TYPE_BAR = 0x02, /**< Draw columns*/ }; typedef uint8_t lv_chart_type_t; -/** Chart update mode for `lv_chart_set_next`*/ +/** + * Chart update mode for `lv_chart_set_next` + */ enum { - LV_CHART_UPDATE_MODE_SHIFT, /**< Shift old data to the left and add the new one o the right*/ + LV_CHART_UPDATE_MODE_SHIFT, /**< Shift old data to the left and add the new one the right*/ LV_CHART_UPDATE_MODE_CIRCULAR, /**< Add the new data in a circular way*/ }; typedef uint8_t lv_chart_update_mode_t; +/** + * Enumeration of the axis' + */ enum { LV_CHART_AXIS_PRIMARY_Y, /*Y axis should be the first to allow indexing arrays with the values*/ LV_CHART_AXIS_SECONDARY_Y, LV_CHART_AXIS_X, - _LV_CHART_AXIS_LAST, + _LV_CHART_AXIS_LAST }; typedef uint8_t lv_chart_axis_t; +/** + * Descriptor a chart series + */ typedef struct { lv_coord_t * points; lv_color_t color; - uint16_t start_point; - uint8_t ext_buf_assigned : 1; + uint16_t last_point; uint8_t hidden : 1; - lv_chart_axis_t y_axis : 1; + uint8_t ext_buf_assigned : 1; + lv_chart_axis_t y_axis : 2; } lv_chart_series_t; typedef struct { - lv_point_t point; - lv_color_t color; - lv_dir_t axes : 4; -} lv_chart_cursor_t; - -typedef void (*lv_chart_tick_label_cb_t)(const lv_obj_t * obj, lv_chart_axis_t axis, uint32_t tick_id, char buf[], size_t buf_len); + lv_coord_t major_len; + lv_coord_t minor_len; + lv_coord_t draw_size; + uint32_t minor_cnt :15; + uint32_t major_cnt :15; + uint32_t label_en :1; +}lv_chart_tick_dsc_t; typedef struct { lv_obj_t obj; - lv_ll_t series_ll; /*Linked list for the data line pointers (stores lv_chart_series_t)*/ - lv_ll_t cursors_ll; /*Linked list for the cursor pointers (stores lv_chart_cursor_t)*/ - lv_chart_tick_label_cb_t tick_label_cb; + lv_ll_t series_ll; /**< Linked list for the data line pointers (stores lv_chart_series_t)*/ + + lv_chart_tick_dsc_t tick[_LV_CHART_AXIS_LAST]; + int32_t pressed_point_id; + uint8_t hdiv_cnt; /**< Number of horizontal division lines*/ + uint8_t vdiv_cnt; /**< Number of vertical division lines*/ + uint16_t point_cnt; /**< Point number in a data line*/ lv_coord_t ymin[2]; lv_coord_t ymax[2]; - lv_coord_t ext_size; - int32_t pressed_point_id; - uint8_t hdiv_cnt; /*Number of horizontal division lines*/ - uint8_t vdiv_cnt; /*Number of vertical division lines*/ - uint8_t sub_tick_cnt[_LV_CHART_AXIS_LAST]; - uint16_t point_cnt; /*Point number in a data line*/ - lv_chart_type_t type; /*Line, column or point chart (from 'lv_chart_type_t')*/ - uint16_t x_zoom; - uint16_t y_zoom; - uint8_t update_mode : 1; + uint16_t zoom_x; + uint16_t zoom_y; + lv_chart_type_t type :2; /**< Line or column chart */ + lv_chart_update_mode_t update_mode : 1; }lv_chart_t; extern const lv_obj_class_t lv_chart; @@ -100,294 +107,227 @@ extern const lv_obj_class_t lv_chart; **********************/ /** - * Create a chart background objects - * @param par pointer to an object, it will be the parent of the new chart background - * @param copy pointer to a chart background object, if not NULL then the new object will be copied - * from it - * @return pointer to the created chart background + * Create a chart objects + * @param parent pointer to an object, it will be the parent of the new button + * @param copy DEPRECATED, will be removed in v9. + * Pointer to an other chart to copy. + * @return pointer to the created chart */ -lv_obj_t * lv_chart_create(lv_obj_t * par, const lv_obj_t * copy); +lv_obj_t * lv_chart_create(lv_obj_t * parent, const lv_obj_t * copy); + +/** + * Set a new type for a chart + * @param obj pointer to a chart object + * @param type new type of the chart (from 'lv_chart_type_t' enum) + */ +void lv_chart_set_type(lv_obj_t * obj, lv_chart_type_t type); +/** + * Set the number of points on a data line on a chart + * @param obj pointer r to chart object + * @param cnt new number of points on the data lines + */ +void lv_chart_set_point_count(lv_obj_t * obj, uint16_t cnt); + +/** + * Set the minimal and maximal y values on an axis + * @param obj pointer to a chart object + * @param axis `LV_CHART_AXIS_PRIMARY_Y` or `LV_CHART_AXIS_SECONDARY_Y` + * @param min minimum value of the y axis + * @param max maximum value of the y axis + */ +void lv_chart_set_range(lv_obj_t * obj, lv_chart_axis_t axis, lv_coord_t min, lv_coord_t max); + +/** + * Set update mode of the chart object. Affects + * @param obj pointer to a chart object + * @param mode the update mode + */ +void lv_chart_set_update_mode(lv_obj_t * obj, lv_chart_update_mode_t update_mode); + +/** + * Set the number of horizontal and vertical division lines + * @param obj pointer to a chart object + * @param hdiv number of horizontal division lines + * @param vdiv number of vertical division lines + */ +void lv_chart_set_div_line_count(lv_obj_t * obj, uint8_t hdiv, uint8_t vdiv); + +/** + * Zoom into the chart in X direction + * @param obj pointer to a chart object + * @param zoom_x zoom in x direction. LV_ZOOM_NONE or 256 for no zoom, 512 double zoom + */ +void lv_chart_set_zoom_x(lv_obj_t * obj, uint16_t zoom_x); + +/** + * Zoom into the chart in Y direction + * @param obj pointer to a chart object + * @param zoom_y zoom in y direction. LV_ZOOM_NONE or 256 for no zoom, 512 double zoom + */ +void lv_chart_set_zoom_y(lv_obj_t * obj, uint16_t zoom_y); + +/** + * Get X zoom of a chart + * @param obj pointer to a chart object + * @return the X zoom value + */ +uint16_t lv_chart_get_zoom_x(const lv_obj_t * obj); + +/** + * Get Y zoom of a chart + * @param obj pointer to a chart object + * @return the Y zoom value + */ +uint16_t lv_chart_get_zoom_y(const lv_obj_t * obj); + +/** + * Set the number of tick lines between two division lines + * @param obj pointer to a chart object + * @param axis an axis which sub tick count should be set + * @param major_len length of major ticks + * @param minor_len length of minor ticks + * @param major_cnt number of major ticks on the axis + * @param minor_cnt number of minor ticks between two major ticks + * @param label_en true: enable label drawing on major ticks + * @param draw_size extra size required to draw the tick and labels + * (start with 20 px and increase if the ticks/labels are clipped) + */ +void lv_chart_set_axis_tick(lv_obj_t * obj, lv_chart_axis_t axis, lv_coord_t major_len, lv_coord_t minor_len, lv_coord_t major_cnt, lv_coord_t minor_cnt, bool label_en, lv_coord_t draw_size); + +/** + * Get the type of a chart + * @param obj pointer to chart object + * @return type of the chart (from 'lv_chart_t' enum) + */ +lv_chart_type_t lv_chart_get_type(const lv_obj_t * obj); + +/** + * Get the data point number per data line on chart + * @param chart pointer to chart object + * @return point number on each data line + */ +uint16_t lv_chart_get_point_count(const lv_obj_t * obj); + +/** + * Get the current index of the x-axis start point in the data array + * @param chart pointer to a chart object + * @param ser pointer to a data series on 'chart' + * @return the index of the current x start point in the data array + */ +uint16_t lv_chart_get_x_start_point(const lv_obj_t * obj, lv_chart_series_t * ser); + +/** + * Get the position of point of the an index relative to the chart. + * @param chart pointer to a chart object + * @param ser pointer to series + * @param id the index. + * @param p_out store the result position here + */ +void lv_chart_get_point_pos_by_id(lv_obj_t * obj, lv_chart_series_t * ser, uint16_t id, lv_point_t * p_out); + +/** + * Refresh a chart if its data line has changed + * @param chart pointer to chart object + */ +void lv_chart_refresh(lv_obj_t * obj); /*====================== - * Add/remove functions + * Series *=====================*/ /** * Allocate and add a data series to the chart - * @param chart pointer to a chart object - * @param color color of the data series - * @return pointer to the allocated data series + * @param obj pointer to a chart object + * @param color color of the data series + * @param axis the y axis to which the series should be attached (::LV_CHART_AXIS_PRIMARY_Y or ::LV_CHART_AXIS_SECONDARY_Y) + * @return pointer to the allocated data series */ -lv_chart_series_t * lv_chart_add_series(lv_obj_t * chart, lv_color_t color); +lv_chart_series_t * lv_chart_add_series(lv_obj_t * obj, lv_color_t color, lv_chart_axis_t axis); /** * Deallocate and remove a data series from a chart - * @param chart pointer to a chart object - * @param series pointer to a data series on 'chart' + * @param chart pointer to a chart object + * @param series pointer to a data series on 'chart' */ -void lv_chart_remove_series(lv_obj_t * chart, lv_chart_series_t * series); - -/** - * Add a cursor with a given color - * @param chart pointer to chart object - * @param color color of the cursor - * @param dir direction of the cursor. `LV_DIR_RIGHT/LEFT/TOP/BOTTOM/HOR/VER/ALL` - * @return pointer to the created cursor - */ -lv_chart_cursor_t * lv_chart_add_cursor(lv_obj_t * chart, lv_color_t color, lv_dir_t dir); - -/** - * Clear the point of a series - * @param chart pointer to a chart object - * @param series pointer to the chart's series to clear - */ -void lv_chart_clear_series(lv_obj_t * chart, lv_chart_series_t * series); +void lv_chart_remove_series(lv_obj_t * obj, lv_chart_series_t * series); /** * Hide/Unhide a single series of a chart. - * @param chart pointer to a chart object. - * @param series pointer to a series object - * @param hide true: hide the series + * @param obj pointer to a chart object. + * @param series pointer to a series object + * @param hide true: hide the series */ void lv_chart_hide_series(lv_obj_t * chart, lv_chart_series_t * series, bool hide); +/** + * Set the index of the x-axis start point in the data array. + * This point will be considers the first (left) point and the other points will be drawn after it. + * @param obj pointer to a chart object + * @param ser pointer to a data series on 'chart' + * @param id the index of the x point in the data array + */ +void lv_chart_set_x_start_point(lv_obj_t * obj, lv_chart_series_t * ser, uint16_t id); + +/** + * Get the next series. + * @param chart pointer to a chart + * @param ser the previous series or NULL to get the first + * @return the next series or NULL if thre is no more. + */ +lv_chart_series_t * lv_chart_get_series_next(const lv_obj_t * chart, const lv_chart_series_t * ser); + /*===================== - * Setter functions + * Set/Get value(s) *====================*/ /** - * Set the number of horizontal and vertical division lines - * @param chart pointer to a graph background object - * @param hdiv number of horizontal division lines - * @param vdiv number of vertical division lines + * Initialize all data points of a series with a value + * @param obj pointer to chart object + * @param ser pointer to a data series on 'chart' + * @param value the new value for all points. `LV_CHART_POINT_DEF` can be used to hide the points. */ -void lv_chart_set_div_line_count(lv_obj_t * chart, uint8_t hdiv, uint8_t vdiv); +void lv_chart_set_all_value(lv_obj_t * obj, lv_chart_series_t * ser, lv_coord_t value); /** - * Set the minimal and maximal y values on an axis - * @param chart pointer to a graph background object - * @param axis `LV_CHART_AXIS_PRIMARY_Y` or `LV_CHART_AXIS_SECONDARY_Y` - * @param ymin y minimum value - * @param ymax y maximum value + * Set the next point according to the update mode policy. + * @param obj pointer to chart object + * @param ser pointer to a data series on 'chart' + * @param value the new value of the next data */ -void lv_chart_set_y_range(lv_obj_t * chart, lv_chart_axis_t axis, lv_coord_t ymin, lv_coord_t ymax); +void lv_chart_set_next_value(lv_obj_t * obj, lv_chart_series_t * ser, lv_coord_t value); /** - * Set a new type for a chart - * @param chart pointer to a chart object - * @param type new type of the chart (from 'lv_chart_type_t' enum) + * Set an individual point's y value of a chart's series directly based on its index + * @param obj pointer to a chart object + * @param ser pointer to a data series on 'chart' + * @param value value to assign to array point + * @param id the index of the x point in the array */ -void lv_chart_set_type(lv_obj_t * chart, lv_chart_type_t type); - -/** - * Set the number of points on a data line on a chart - * @param chart pointer r to chart object - * @param point_cnt new number of points on the data lines - */ -void lv_chart_set_point_count(lv_obj_t * chart, uint16_t point_cnt); - -/** - * Initialize all data points with a value - * @param chart pointer to chart object - * @param ser pointer to a data series on 'chart' - * @param y the new value for all points - */ -void lv_chart_init_points(lv_obj_t * chart, lv_chart_series_t * ser, lv_coord_t y); - -/** - * Set the value of points from an array - * @param chart pointer to chart object - * @param ser pointer to a data series on 'chart' - * @param y_array array of 'lv_coord_t' points (with 'points count' elements ) - */ -void lv_chart_set_points(lv_obj_t * chart, lv_chart_series_t * ser, lv_coord_t y_array[]); - -/** - * Shift all data right and set the most right data on a data line - * @param chart pointer to chart object - * @param ser pointer to a data series on 'chart' - * @param y the new value of the most right data - */ -void lv_chart_set_next(lv_obj_t * chart, lv_chart_series_t * ser, lv_coord_t y); - -/** - * Set update mode of the chart object. - * @param chart pointer to a chart object - * @param update mode - */ -void lv_chart_set_update_mode(lv_obj_t * chart, lv_chart_update_mode_t update_mode); - -/** - * Set the length of the tick marks on the x axis - * @param chart pointer to the chart - * @param major_tick_len the length of the major tick or `LV_CHART_TICK_LENGTH_AUTO` to set automatically - * (where labels are added) - * @param minor_tick_len the length of the minor tick, `LV_CHART_TICK_LENGTH_AUTO` to set automatically - * (where no labels are added) - */ -void lv_chart_set_x_tick_length(lv_obj_t * chart, uint8_t major_tick_len, uint8_t minor_tick_len); - -/** - * Set the length of the tick marks on the y axis - * @param chart pointer to the chart - * @param major_tick_len the length of the major tick or `LV_CHART_TICK_LENGTH_AUTO` to set automatically - * (where labels are added) - * @param minor_tick_len the length of the minor tick, `LV_CHART_TICK_LENGTH_AUTO` to set automatically - * (where no labels are added) - */ -void lv_chart_set_y_tick_length(lv_obj_t * chart, uint8_t major_tick_len, uint8_t minor_tick_len); - -/** - * Set the length of the tick marks on the secondary y axis - * @param chart pointer to the chart - * @param major_tick_len the length of the major tick or `LV_CHART_TICK_LENGTH_AUTO` to set automatically - * (where labels are added) - * @param minor_tick_len the length of the minor tick, `LV_CHART_TICK_LENGTH_AUTO` to set automatically - * (where no labels are added) - */ -void lv_chart_set_secondary_y_tick_length(lv_obj_t * chart, uint8_t major_tick_len, uint8_t minor_tick_len); - -/** - * Set the x-axis tick count and labels of a chart - * @param chart pointer to a chart object - * @param list_of_values list of string values, terminated with \n, except the last - * @param num_tick_marks if list_of_values is NULL: total number of ticks per axis - * else number of ticks between two value labels - * @param options extra options - */ -void lv_chart_set_tick_label_cb(lv_obj_t * chart, lv_chart_tick_label_cb_t tick_label_cb, lv_coord_t ext_size); - -/** - * Set the index of the x-axis start point in the data array - * @param chart pointer to a chart object - * @param ser pointer to a data series on 'chart' - * @param id the index of the x point in the data array - */ -void lv_chart_set_x_start_point(lv_obj_t * chart, lv_chart_series_t * ser, uint16_t id); +void lv_chart_set_value_by_id(lv_obj_t * obj, lv_chart_series_t * ser, lv_coord_t value, uint16_t id); /** * Set an external array of data points to use for the chart - * NOTE: It is the users responsibility to make sure the point_cnt matches the external array size. - * @param chart pointer to a chart object - * @param ser pointer to a data series on 'chart' - * @param array external array of points for chart + * NOTE: It is the users responsibility to make sure the `point_cnt` matches the external array size. + * @param obj pointer to a chart object + * @param ser pointer to a data series on 'chart' + * @param array external array of points for chart */ -void lv_chart_set_ext_array(lv_obj_t * chart, lv_chart_series_t * ser, lv_coord_t array[], uint16_t point_cnt); +void lv_chart_set_ext_array(lv_obj_t * obj, lv_chart_series_t * ser, lv_coord_t array[]); /** - * Set an individual point value in the chart series directly based on index - * @param chart pointer to a chart object - * @param ser pointer to a data series on 'chart' - * @param value value to assign to array point - * @param id the index of the x point in the array + * Get the array of values of a series + * @param obj pointer to a chart object + * @param ser pointer to a data series on 'chart' + * @return the array of values with 'point_count' elements */ -void lv_chart_set_point_id(lv_obj_t * chart, lv_chart_series_t * ser, lv_coord_t value, uint16_t id); +lv_coord_t * lv_chart_get_array(const lv_obj_t * obj, lv_chart_series_t * ser); /** - * Set the Y axis of a series - * @param chart pointer to a chart object - * @param ser pointer to series - * @param axis `LV_CHART_AXIS_PRIMARY_Y` or `LV_CHART_AXIS_SECONDARY_Y` + * Get the index of the currently pressed point. It's the same for every series. + * @param obj pointer to a chart object + * @return -1: if no pointid being pressed or the index of the point [0 .. point count] */ -void lv_chart_set_series_axis(lv_obj_t * chart, lv_chart_series_t * ser, lv_chart_axis_t axis); - -/** - * Set the coordinate of the cursor with respect - * to the origin of series area of the chart. - * @param chart pointer to a chart object. - * @param cursor pointer to the cursor. - * @param point the new coordinate of cursor relative to the series area - */ -void lv_chart_set_cursor_point(lv_obj_t * chart, lv_chart_cursor_t * cursor, lv_point_t * point); - -/*===================== - * Getter functions - *====================*/ - -/** - * Get the type of a chart - * @param chart pointer to chart object - * @return type of the chart (from 'lv_chart_t' enum) - */ -lv_chart_type_t lv_chart_get_type(const lv_obj_t * chart); - -/** - * Get the data point number per data line on chart - * @param chart pointer to chart object - * @return point number on each data line - */ -uint16_t lv_chart_get_point_count(const lv_obj_t * chart); - -/** - * get the current index of the x-axis start point in the data array - * @param ser pointer to a data series on 'chart' - * @return the index of the current x start point in the data array - */ -uint16_t lv_chart_get_x_start_point(lv_chart_series_t * ser); - -/** - * Get an individual point value in the chart series directly based on index - * @param chart pointer to a chart object - * @param ser pointer to a data series on 'chart' - * @param id the index of the x point in the array - * @return value of array point at index id - */ -lv_coord_t lv_chart_get_point_id(lv_obj_t * chart, lv_chart_series_t * ser, uint16_t id); - -/** - * Get the Y axis of a series - * @param chart pointer to a chart object - * @param ser pointer to series - * @return `LV_CHART_AXIS_PRIMARY_Y` or `LV_CHART_AXIS_SECONDARY_Y` - */ -lv_chart_axis_t lv_chart_get_series_axis(lv_obj_t * chart, lv_chart_series_t * ser); - -/** - * Get the coordinate of the cursor with respect - * to the origin of series area of the chart. - * @param chart pointer to a chart object - * @param cursor pointer to cursor - * @return coordinate of the cursor as lv_point_t - */ -lv_point_t lv_chart_get_cursor_point(lv_obj_t * chart, lv_chart_cursor_t * cursor); - -/** - * Get the nearest index to an X coordinate - * @param chart pointer to a chart object - * @param coord the coordination of the point relative to the series area. - * @return the found index - */ -uint16_t lv_chart_get_nearest_index_from_coord(lv_obj_t * chart, lv_coord_t x); - -/** - * Get the x coordinate of the an index with respect - * to the origin of series area of the chart. - * @param chart pointer to a chart object - * @param ser pointer to series - * @param id the index. - * @return x coordinate of index - */ -lv_coord_t lv_chart_get_x_from_index(lv_obj_t * chart, lv_chart_series_t * ser, uint16_t id); - -/** - * Get the y coordinate of the an index with respect - * to the origin of series area of the chart. - * @param chart pointer to a chart object - * @param ser pointer to series - * @param id the index. - * @return y coordinate of index - */ -lv_coord_t lv_chart_get_y_from_index(lv_obj_t * chart, lv_chart_series_t * ser, uint16_t id); - -/*===================== - * Other functions - *====================*/ - -/** - * Refresh a chart if its data line has changed - * @param chart pointer to chart object - */ -void lv_chart_refresh(lv_obj_t * chart); +int32_t lv_chart_get_pressed_point(const lv_obj_t * obj); /********************** * MACROS diff --git a/src/lv_widgets/lv_checkbox.c b/src/lv_widgets/lv_checkbox.c index 103cfdd00..ee0044e6c 100644 --- a/src/lv_widgets/lv_checkbox.c +++ b/src/lv_widgets/lv_checkbox.c @@ -11,8 +11,7 @@ #include "../lv_misc/lv_debug.h" #include "../lv_core/lv_group.h" -#include "../lv_themes/lv_theme.h" -#include "lv_label.h" +#include "../lv_draw/lv_draw.h" /********************* * DEFINES @@ -51,12 +50,6 @@ const lv_obj_class_t lv_checkbox = { * GLOBAL FUNCTIONS **********************/ -/** - * Create a check box objects - * @param par pointer to an object, it will be the parent of the new check box - * @param copy pointer to a check box object, if not NULL then the new object will be copied from it - * @return pointer to the created check box - */ lv_obj_t * lv_checkbox_create(lv_obj_t * parent, const lv_obj_t * copy) { return lv_obj_create_from_class(&lv_checkbox, parent, copy); @@ -66,12 +59,6 @@ lv_obj_t * lv_checkbox_create(lv_obj_t * parent, const lv_obj_t * copy) * Setter functions *====================*/ -/** - * Set the text of a check box. `txt` will be copied and may be deallocated - * after this function returns. - * @param cb pointer to a check box - * @param txt the text of the check box. NULL to refresh with the current text. - */ void lv_checkbox_set_text(lv_obj_t * obj, const char * txt) { lv_checkbox_t * cb = (lv_checkbox_t *) obj; @@ -94,12 +81,6 @@ void lv_checkbox_set_text(lv_obj_t * obj, const char * txt) lv_obj_handle_self_size_chg(obj); } -/** - * Set the text of a check box. `txt` must not be deallocated during the life - * of this checkbox. - * @param cb pointer to a check box - * @param txt the text of the check box. NULL to refresh with the current text. - */ void lv_checkbox_set_text_static(lv_obj_t * obj, const char * txt) { lv_checkbox_t * cb = (lv_checkbox_t *) obj; @@ -116,11 +97,6 @@ void lv_checkbox_set_text_static(lv_obj_t * obj, const char * txt) * Getter functions *====================*/ -/** - * Get the text of a check box - * @param cb pointer to check box object - * @return pointer to the text of the check box - */ const char * lv_checkbox_get_text(const lv_obj_t * obj) { lv_checkbox_t * cb = (lv_checkbox_t *) obj; @@ -226,7 +202,7 @@ static lv_draw_res_t lv_checkbox_draw(lv_obj_t * obj, const lv_area_t * clip_are lv_coord_t letter_space = lv_obj_get_style_text_letter_space(obj, LV_PART_MAIN); lv_point_t txt_size; - _lv_txt_get_size(&txt_size, cb->txt, font, letter_space, line_space, LV_COORD_MAX, LV_TEXT_FLAG_NONE); + lv_txt_get_size(&txt_size, cb->txt, font, letter_space, line_space, LV_COORD_MAX, LV_TEXT_FLAG_NONE); lv_draw_label_dsc_t txt_dsc; lv_draw_label_dsc_init(&txt_dsc); @@ -270,7 +246,7 @@ static lv_res_t lv_checkbox_signal(lv_obj_t * obj, lv_signal_t sign, void * para lv_coord_t letter_space = lv_obj_get_style_text_letter_space(obj, LV_PART_MAIN); lv_point_t txt_size; - _lv_txt_get_size(&txt_size, cb->txt, font, letter_space, line_space, LV_COORD_MAX, LV_TEXT_FLAG_NONE); + lv_txt_get_size(&txt_size, cb->txt, font, letter_space, line_space, LV_COORD_MAX, LV_TEXT_FLAG_NONE); lv_coord_t bg_colp = lv_obj_get_style_pad_column(obj, LV_PART_MAIN); diff --git a/src/lv_widgets/lv_checkbox.h b/src/lv_widgets/lv_checkbox.h index 717e994c1..ab1dd4745 100644 --- a/src/lv_widgets/lv_checkbox.h +++ b/src/lv_widgets/lv_checkbox.h @@ -39,12 +39,13 @@ extern const lv_obj_class_t lv_checkbox; **********************/ /** - * Create a check box objects - * @param par pointer to an object, it will be the parent of the new check box - * @param copy pointer to a check box object, if not NULL then the new object will be copied from it - * @return pointer to the created check box + * Create a check box object + * @param parent pointer to an object, it will be the parent of the new button + * @param copy DEPRECATED, will be removed in v9. + * Pointer to an other check box to copy. + * @return pointer to the created check box */ -lv_obj_t * lv_checkbox_create(lv_obj_t * par, const lv_obj_t * copy); +lv_obj_t * lv_checkbox_create(lv_obj_t * parent, const lv_obj_t * copy); /*===================== * Setter functions @@ -53,18 +54,18 @@ lv_obj_t * lv_checkbox_create(lv_obj_t * par, const lv_obj_t * copy); /** * Set the text of a check box. `txt` will be copied and may be deallocated * after this function returns. - * @param cb pointer to a check box - * @param txt the text of the check box. NULL to refresh with the current text. + * @param cb pointer to a check box + * @param txt the text of the check box. NULL to refresh with the current text. */ -void lv_checkbox_set_text(lv_obj_t * cb, const char * txt); +void lv_checkbox_set_text(lv_obj_t * obj, const char * txt); /** * Set the text of a check box. `txt` must not be deallocated during the life * of this checkbox. - * @param cb pointer to a check box - * @param txt the text of the check box. NULL to refresh with the current text. + * @param cb pointer to a check box + * @param txt the text of the check box. NULL to refresh with the current text. */ -void lv_checkbox_set_text_static(lv_obj_t * cb, const char * txt); +void lv_checkbox_set_text_static(lv_obj_t * obj, const char * txt); /*===================== * Getter functions @@ -72,10 +73,10 @@ void lv_checkbox_set_text_static(lv_obj_t * cb, const char * txt); /** * Get the text of a check box - * @param cb pointer to check box object - * @return pointer to the text of the check box + * @param cb pointer to check box object + * @return pointer to the text of the check box */ -const char * lv_checkbox_get_text(const lv_obj_t * cb); +const char * lv_checkbox_get_text(const lv_obj_t * obj); /********************** * MACROS diff --git a/src/lv_widgets/lv_dropdown.c b/src/lv_widgets/lv_dropdown.c index 631292def..ef5f83428 100644 --- a/src/lv_widgets/lv_dropdown.c +++ b/src/lv_widgets/lv_dropdown.c @@ -44,6 +44,7 @@ static void lv_dropdown_list_constructor(lv_obj_t * obj, lv_obj_t * parent, cons static void lv_dropdown_list_destructor(lv_obj_t * obj); static lv_draw_res_t lv_dropdown_list_draw(lv_obj_t * obj, const lv_area_t * clip_area, lv_draw_mode_t mode); static lv_res_t lv_dropdown_list_signal(lv_obj_t * list, lv_signal_t sign, void * param); + static void draw_box(lv_obj_t * dropdown_obj, const lv_area_t * clip_area, uint16_t id, lv_state_t state); static void draw_box_label(lv_obj_t * dropdown_obj, const lv_area_t * clip_area, uint16_t id, lv_state_t state); static lv_res_t list_release_handler(lv_obj_t * list_obj); @@ -83,13 +84,6 @@ const lv_obj_class_t lv_dropdown_list = { * GLOBAL FUNCTIONS **********************/ -/** - * Create a drop down list objects - * @param par pointer to an object, it will be the parent of the new drop down list - * @param copy pointer to a drop down list object, if not NULL then the new object will be copied - * from it - * @return pointer to the created drop down list - */ lv_obj_t * lv_dropdown_create(lv_obj_t * parent, const lv_obj_t * copy) { return lv_obj_create_from_class(&lv_dropdown, parent, copy); @@ -99,11 +93,6 @@ lv_obj_t * lv_dropdown_create(lv_obj_t * parent, const lv_obj_t * copy) * Setter functions *====================*/ -/** - * Set text of the ddlist (Displayed on the button if `show_selected = false`) - * @param ddlist pointer to a drop down list object - * @param txt the text as a string (Only it's pointer is saved) - */ void lv_dropdown_set_text(lv_obj_t * obj, const char * txt) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); @@ -115,32 +104,6 @@ void lv_dropdown_set_text(lv_obj_t * obj, const char * txt) lv_obj_invalidate(obj); } -/** - * Clear all options in a drop down list. Static or dynamic. - * @param ddlist pointer to drop down list object - */ -void lv_dropdown_clear_options(lv_obj_t * obj) -{ - LV_ASSERT_OBJ(obj, LV_OBJX_NAME); - lv_dropdown_t * dropdown = (lv_dropdown_t *) obj; - if(dropdown->options == NULL) return; - - if(dropdown->static_txt == 0) - lv_mem_free(dropdown->options); - - dropdown->options = NULL; - dropdown->static_txt = 0; - dropdown->option_cnt = 0; - - lv_obj_invalidate(obj); -} - -/** - * Set the options in a drop down list from a string - * @param ddlist pointer to drop down list object - * @param options a string with '\n' separated options. E.g. "One\nTwo\nThree" - * The options string can be destroyed after calling this function - */ void lv_dropdown_set_options(lv_obj_t * obj, const char * options) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); @@ -185,11 +148,6 @@ void lv_dropdown_set_options(lv_obj_t * obj, const char * options) dropdown->static_txt = 0; } -/** - * Set the options in a drop down list from a string - * @param ddlist pointer to drop down list object - * @param options a static string with '\n' separated options. E.g. "One\nTwo\nThree" - */ void lv_dropdown_set_options_static(lv_obj_t * obj, const char * options) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); @@ -216,12 +174,6 @@ void lv_dropdown_set_options_static(lv_obj_t * obj, const char * options) dropdown->options = (char *)options; } -/** - * Add an options to a drop down list from a string. Only works for dynamic options. - * @param ddlist pointer to drop down list object - * @param option a string without '\n'. E.g. "Four" - * @param pos the insert position, indexed from 0, LV_DROPDOWN_POS_LAST = end of string - */ void lv_dropdown_add_option(lv_obj_t * obj, const char * option, uint32_t pos) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); @@ -292,11 +244,22 @@ void lv_dropdown_add_option(lv_obj_t * obj, const char * option, uint32_t pos) lv_obj_invalidate(obj); } -/** - * Set the selected option - * @param ddlist pointer to drop down list object - * @param sel_opt id of the selected option (0 ... number of option - 1); - */ +void lv_dropdown_clear_options(lv_obj_t * obj) +{ + LV_ASSERT_OBJ(obj, LV_OBJX_NAME); + lv_dropdown_t * dropdown = (lv_dropdown_t *) obj; + if(dropdown->options == NULL) return; + + if(dropdown->static_txt == 0) + lv_mem_free(dropdown->options); + + dropdown->options = NULL; + dropdown->static_txt = 0; + dropdown->option_cnt = 0; + + lv_obj_invalidate(obj); +} + void lv_dropdown_set_selected(lv_obj_t * obj, uint16_t sel_opt) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); @@ -310,11 +273,6 @@ void lv_dropdown_set_selected(lv_obj_t * obj, uint16_t sel_opt) lv_obj_invalidate(obj); } -/** - * Set the direction of the a drop down list - * @param ddlist pointer to a drop down list object - * @param dir LV_DIR_LEFT/RIGHT/TOP/BOTTOM - */ void lv_dropdown_set_dir(lv_obj_t * obj, lv_dir_t dir) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); @@ -327,11 +285,6 @@ void lv_dropdown_set_dir(lv_obj_t * obj, lv_dir_t dir) lv_obj_invalidate(obj); } -/** - * Set the maximal height for the drop down list - * @param ddlist pointer to a drop down list - * @param h the maximal height - */ void lv_dropdown_set_max_height(lv_obj_t * obj, lv_coord_t h) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); @@ -342,11 +295,6 @@ void lv_dropdown_set_max_height(lv_obj_t * obj, lv_coord_t h) dropdown->max_height = h; } -/** - * Set an arrow or other symbol to display when the drop-down list is closed. - * @param ddlist pointer to drop down list object - * @param symbol a text like `LV_SYMBOL_DOWN` or NULL to not draw icon - */ void lv_dropdown_set_symbol(lv_obj_t * obj, const void * symbol) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); @@ -360,11 +308,15 @@ void lv_dropdown_set_symbol(lv_obj_t * obj, const void * symbol) * Getter functions *====================*/ -/** - * Get text of the ddlist (Displayed on the button if `show_selected = false`) - * @param ddlist pointer to a drop down list object - * @return the text string - */ +lv_obj_t * lv_dropdown_get_list(lv_obj_t * obj) +{ + LV_ASSERT_OBJ(obj, LV_OBJX_NAME); + lv_dropdown_t * dropdown = (lv_dropdown_t *) obj; + + return dropdown->list; + +} + const char * lv_dropdown_get_text(lv_obj_t * obj) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); @@ -373,11 +325,6 @@ const char * lv_dropdown_get_text(lv_obj_t * obj) return dropdown->text; } -/** - * Get the options of a drop down list - * @param ddlist pointer to drop down list object - * @return the options separated by '\n'-s (E.g. "Option1\nOption2\nOption3") - */ const char * lv_dropdown_get_options(const lv_obj_t * obj) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); @@ -386,11 +333,6 @@ const char * lv_dropdown_get_options(const lv_obj_t * obj) return dropdown->options; } -/** - * Get the selected option - * @param ddlist pointer to drop down list object - * @return id of the selected option (0 ... number of option - 1); - */ uint16_t lv_dropdown_get_selected(const lv_obj_t * obj) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); @@ -400,11 +342,6 @@ uint16_t lv_dropdown_get_selected(const lv_obj_t * obj) return dropdown->sel_opt_id; } -/** - * Get the total number of options - * @param ddlist pointer to drop down list object - * @return the total number of options in the list - */ uint16_t lv_dropdown_get_option_cnt(const lv_obj_t * obj) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); @@ -414,12 +351,6 @@ uint16_t lv_dropdown_get_option_cnt(const lv_obj_t * obj) return dropdown->option_cnt; } -/** - * Get the current selected option as a string - * @param ddlist pointer to ddlist object - * @param buf pointer to an array to store the string - * @param buf_size size of `buf` in bytes. 0: to ignore it. - */ void lv_dropdown_get_selected_str(const lv_obj_t * obj, char * buf, uint32_t buf_size) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); @@ -446,11 +377,6 @@ void lv_dropdown_get_selected_str(const lv_obj_t * obj, char * buf, uint32_t buf buf[c] = '\0'; } -/** - * Get the fix height value. - * @param ddlist pointer to a drop down list object - * @return the height if the ddlist is opened (0: auto size) - */ lv_coord_t lv_dropdown_get_max_height(const lv_obj_t * obj) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); @@ -459,11 +385,6 @@ lv_coord_t lv_dropdown_get_max_height(const lv_obj_t * obj) return dropdown->max_height; } -/** - * Get the symbol to draw when the drop-down list is closed - * @param ddlist pointer to drop down list object - * @return the symbol or NULL if not enabled - */ const char * lv_dropdown_get_symbol(lv_obj_t * obj) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); @@ -473,11 +394,6 @@ const char * lv_dropdown_get_symbol(lv_obj_t * obj) return dropdown->symbol; } -/** - * Get the direction of the drop down list - * @param ddlist pointer to a drop down list object - * @return LV_DIR_LEF/RIGHT/TOP/BOTTOM - */ lv_dir_t lv_dropdown_get_dir(const lv_obj_t * obj) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); @@ -491,10 +407,6 @@ lv_dir_t lv_dropdown_get_dir(const lv_obj_t * obj) * Other functions *====================*/ -/** - * Open the drop down list with or without animation - * @param ddlist pointer to drop down list object - */ void lv_dropdown_open(lv_obj_t * dropdown_obj) { lv_dropdown_t * dropdown = (lv_dropdown_t *) dropdown_obj; @@ -530,10 +442,10 @@ void lv_dropdown_open(lv_obj_t * dropdown_obj) if(dropdown_obj->coords.y1 > LV_VER_RES - dropdown_obj->coords.y2) { /*There is more space on the top, so make it drop up*/ dir = LV_DIR_TOP; - list_h = dropdown_obj->coords.y1; + list_h = dropdown_obj->coords.y1 - 1; } else { - list_h = LV_VER_RES - dropdown_obj->coords.y2; + list_h = LV_VER_RES - dropdown_obj->coords.y2 - 1; } } } @@ -564,8 +476,8 @@ void lv_dropdown_open(lv_obj_t * dropdown_obj) else if(dir == LV_DIR_RIGHT)lv_obj_align(dropdown->list, dropdown_obj, LV_ALIGN_OUT_RIGHT_TOP, 0, 0); if(dropdown->dir == LV_DIR_LEFT || dropdown->dir == LV_DIR_RIGHT) { - if(dropdown->list->coords.y2 > LV_VER_RES) { - lv_obj_set_y(dropdown->list, lv_obj_get_y(dropdown->list) - (dropdown->list->coords.y2 - LV_VER_RES)); + if(dropdown->list->coords.y2 >= LV_VER_RES) { + lv_obj_set_y(dropdown->list, lv_obj_get_y(dropdown->list) - (dropdown->list->coords.y2 - LV_VER_RES) - 1); } } @@ -585,10 +497,6 @@ void lv_dropdown_open(lv_obj_t * dropdown_obj) } } -/** - * Close (Collapse) the drop down list - * @param ddlist pointer to drop down list object - */ void lv_dropdown_close(lv_obj_t * obj) { lv_obj_clear_state(obj, LV_STATE_CHECKED); @@ -722,8 +630,7 @@ static lv_draw_res_t lv_dropdown_draw(lv_obj_t * obj, const lv_area_t * clip_are lv_coord_t symbol_h; if(symbol_type == LV_IMG_SRC_SYMBOL) { lv_point_t size; - _lv_txt_get_size(&size, dropdown->symbol, label_dsc.font, label_dsc.letter_space, label_dsc.line_space, LV_COORD_MAX, - label_dsc.flag); + lv_txt_get_size(&size, dropdown->symbol, label_dsc.font, label_dsc.letter_space, label_dsc.line_space, LV_COORD_MAX, label_dsc.flag); symbol_w = size.x; symbol_h = size.y; } else { @@ -739,8 +646,6 @@ static lv_draw_res_t lv_dropdown_draw(lv_obj_t * obj, const lv_area_t * clip_are } lv_area_t symbol_area; - symbol_area.y1 = obj->coords.y1 + top; - symbol_area.y2 = symbol_area.y1 + symbol_h - 1; if(symbol_to_left) { symbol_area.x1 = obj->coords.x1 + left; symbol_area.x2 = symbol_area.x1 + symbol_w - 1; @@ -750,8 +655,12 @@ static lv_draw_res_t lv_dropdown_draw(lv_obj_t * obj, const lv_area_t * clip_are } if(symbol_type == LV_IMG_SRC_SYMBOL) { + symbol_area.y1 = obj->coords.y1 + top; + symbol_area.y2 = symbol_area.y1 + symbol_h - 1; lv_draw_label(&symbol_area, clip_area, &label_dsc, dropdown->symbol, NULL); } else { + symbol_area.y1 = obj->coords.y1 + (lv_obj_get_height(obj) - symbol_h) / 2; + symbol_area.y2 = symbol_area.y1 + symbol_h - 1; lv_draw_img_dsc_t img_dsc; lv_draw_img_dsc_init(&img_dsc); lv_obj_init_draw_img_dsc(obj, LV_PART_MAIN, &img_dsc); @@ -762,8 +671,7 @@ static lv_draw_res_t lv_dropdown_draw(lv_obj_t * obj, const lv_area_t * clip_are } lv_point_t size; - _lv_txt_get_size(&size, opt_txt, label_dsc.font, label_dsc.letter_space, label_dsc.line_space, LV_COORD_MAX, - label_dsc.flag); + lv_txt_get_size(&size, opt_txt, label_dsc.font, label_dsc.letter_space, label_dsc.line_space, LV_COORD_MAX, label_dsc.flag); lv_area_t txt_area; txt_area.y1 = obj->coords.y1 + top; @@ -1174,12 +1082,8 @@ static void position_to_selected(lv_obj_t * dropdown_obj) const lv_font_t * font = lv_obj_get_style_text_font(label, LV_PART_MAIN); lv_coord_t font_h = lv_font_get_line_height(font); lv_coord_t line_space = lv_obj_get_style_text_line_space(label, LV_PART_MAIN); - - lv_coord_t line_y1 = dropdown->sel_opt_id * (font_h + line_space); - - /*Do not allow scrolling in*/ - lv_coord_t bottom_diff = dropdown->list->coords.y2 - lv_obj_get_style_pad_bottom(dropdown->list, LV_PART_MAIN) - (label->coords.y2 - line_y1); - if(bottom_diff > 0) line_y1 -= bottom_diff; + lv_coord_t unit_h = font_h + line_space; + lv_coord_t line_y1 = dropdown->sel_opt_id * unit_h; /*Scroll to the selected option*/ lv_obj_scroll_to_y(dropdown->list, line_y1, LV_ANIM_OFF); diff --git a/src/lv_widgets/lv_dropdown.h b/src/lv_widgets/lv_dropdown.h index 5b1b22892..d7bd05f6f 100644 --- a/src/lv_widgets/lv_dropdown.h +++ b/src/lv_widgets/lv_dropdown.h @@ -29,6 +29,7 @@ extern "C" { * DEFINES *********************/ #define LV_DROPDOWN_POS_LAST 0xFFFF +LV_EXPORT_CONST_INT(LV_DROPDOWN_POS_LAST); /********************** * TYPEDEFS @@ -60,160 +61,173 @@ extern const lv_obj_class_t lv_dropdown_list; /********************** * GLOBAL PROTOTYPES **********************/ + /** - * Create a drop down list objects - * @param par pointer to an object, it will be the parent of the new drop down list - * @param copy pointer to a drop down list object, if not NULL then the new object will be copied - * from it - * @return pointer to the created drop down list + * Create a drop-down list objects + * @param parent pointer to an object, it will be the parent of the new drop-down list + * @param copy DEPRECATED, will be removed in v9. + * Pointer to an other drop-down list to copy. + * @return pointer to the created drop-down list */ -lv_obj_t * lv_dropdown_create(lv_obj_t * par, const lv_obj_t * copy); +lv_obj_t * lv_dropdown_create(lv_obj_t * parent, const lv_obj_t * copy); /*===================== * Setter functions *====================*/ /** - * Set text of the ddlist (Displayed on the button if `show_selected = false`) - * @param ddlist pointer to a drop down list object - * @param txt the text as a string (Only it's pointer is saved) + * Set text of the drop-down list's button. + * If set to `NULL` the selected option's text will be displayed on the button. + * If set to a specific text then that text will be shown regardless the selected option. + * @param obj pointer to a drop-down list object + * @param txt the text as a string (Only it's pointer is saved) */ -void lv_dropdown_set_text(lv_obj_t * ddlist, const char * txt); +void lv_dropdown_set_text(lv_obj_t * obj, const char * txt); /** - * Clear all options in a drop down list. Static or dynamic. - * @param ddlist pointer to drop down list object + * Set the options in a drop-down list from a string. + * The options will be copied and saved in the object so the `options` can be destroyed after calling this function + * @param obj pointer to drop-down list object + * @param options a string with '\n' separated options. E.g. "One\nTwo\nThree" */ -void lv_dropdown_clear_options(lv_obj_t * ddlist); +void lv_dropdown_set_options(lv_obj_t * obj, const char * options); /** - * Set the options in a drop down list from a string - * @param ddlist pointer to drop down list object - * @param options a string with '\n' separated options. E.g. "One\nTwo\nThree" - * The options string can be destroyed after calling this function + * Set the options in a drop-down list from a static string (global, static or dynamically allocated). + * Only the pointer of the option string will be saved. + * @param obj pointer to drop-down list object + * @param options a static string with '\n' separated options. E.g. "One\nTwo\nThree" */ -void lv_dropdown_set_options(lv_obj_t * ddlist, const char * options); +void lv_dropdown_set_options_static(lv_obj_t * obj, const char * options); /** - * Set the options in a drop down list from a string - * @param ddlist pointer to drop down list object - * @param options a static string with '\n' separated options. E.g. "One\nTwo\nThree" + * Add an options to a drop-down list from a string. Only works for non-static options. + * @param obj pointer to drop-down list object + * @param option a string without '\n'. E.g. "Four" + * @param pos the insert position, indexed from 0, LV_DROPDOWN_POS_LAST = end of string */ -void lv_dropdown_set_options_static(lv_obj_t * ddlist, const char * options); +void lv_dropdown_add_option(lv_obj_t * obj, const char * option, uint32_t pos); /** - * Add an options to a drop down list from a string. Only works for dynamic options. - * @param ddlist pointer to drop down list object - * @param option a string without '\n'. E.g. "Four" - * @param pos the insert position, indexed from 0, LV_DROPDOWN_POS_LAST = end of string + * Clear all options in a drop-down list. Works with both static and dynamic optins. + * @param obj pointer to drop-down list object */ -void lv_dropdown_add_option(lv_obj_t * ddlist, const char * option, uint32_t pos); +void lv_dropdown_clear_options(lv_obj_t * obj); /** * Set the selected option - * @param ddlist pointer to drop down list object - * @param sel_opt id of the selected option (0 ... number of option - 1); + * @param obj pointer to drop-down list object + * @param sel_opt id of the selected option (0 ... number of option - 1); */ -void lv_dropdown_set_selected(lv_obj_t * ddlist, uint16_t sel_opt); +void lv_dropdown_set_selected(lv_obj_t * obj, uint16_t sel_opt); /** - * Set the direction of the a drop down list - * @param ddlist pointer to a drop down list object - * @param dir LV_DIR_LEFT/RIGHT/TOP/BOTTOM + * Set the direction of the a drop-down list + * @param obj pointer to a drop-down list object + * @param dir LV_DIR_LEFT/RIGHT/TOP/BOTTOM */ -void lv_dropdown_set_dir(lv_obj_t * ddlist, lv_dir_t dir); +void lv_dropdown_set_dir(lv_obj_t * obj, lv_dir_t dir); /** - * Set the maximal height for the drop down list - * @param ddlist pointer to a drop down list - * @param h the maximal height + * Set the maximal height for the drop-down list + * @param obj pointer to a drop-down list + * @param h the maximal height */ -void lv_dropdown_set_max_height(lv_obj_t * ddlist, lv_coord_t h); +void lv_dropdown_set_max_height(lv_obj_t * obj, lv_coord_t h); /** - * Set an arrow or other symbol to display when the drop-down list is closed. - * @param ddlist pointer to drop down list object - * @param symbol a text like `LV_SYMBOL_DOWN` or NULL to not draw icon + * Set an arrow or other symbol to display when on drop-down list's button. Typically a down caret or arrow. + * @param obj pointer to drop-down list object + * @param symbol a text like `LV_SYMBOL_DOWN`, an image (pointer or path) or NULL to not draw symbol icon + * @note angle and zoom transformation can be applied if the symbol is an image. + * E.g. when drop down is checked (opened) rotate the symbol by 180 */ -void lv_dropdown_set_symbol(lv_obj_t * ddlist, const void * symbol); +void lv_dropdown_set_symbol(lv_obj_t * obj, const void * symbol); /*===================== * Getter functions *====================*/ /** - * Get text of the ddlist (Displayed on the button if `show_selected = false`) - * @param ddlist pointer to a drop down list object - * @return the text string + * Get the list of a drop-down to allow styling or other modifications + * @param obj pointer to a drop-down list object + * @return pointer to the list of the drop-down */ -const char * lv_dropdown_get_text(lv_obj_t * ddlist); +lv_obj_t * lv_dropdown_get_list(lv_obj_t * obj); /** - * Get the options of a drop down list - * @param ddlist pointer to drop down list object - * @return the options separated by '\n'-s (E.g. "Option1\nOption2\nOption3") + * Get text of the drop-down list's button. + * @param obj pointer to a drop-down list object + * @return the text as string, `NULL` if no text */ -const char * lv_dropdown_get_options(const lv_obj_t * ddlist); +const char * lv_dropdown_get_text(lv_obj_t * obj); /** - * Get the selected option - * @param ddlist pointer to drop down list object - * @return id of the selected option (0 ... number of option - 1); + * Get the options of a drop-down list + * @param obj pointer to drop-down list object + * @return the options separated by '\n'-s (E.g. "Option1\nOption2\nOption3") */ -uint16_t lv_dropdown_get_selected(const lv_obj_t * ddlist); +const char * lv_dropdown_get_options(const lv_obj_t * obj); + +/** + * Get the index of the selected option + * @param obj pointer to drop-down list object + * @return index of the selected option (0 ... number of option - 1); + */ +uint16_t lv_dropdown_get_selected(const lv_obj_t * obj); /** * Get the total number of options - * @param ddlist pointer to drop down list object - * @return the total number of options in the list + * @param obj pointer to drop-down list object + * @return the total number of options in the list */ -uint16_t lv_dropdown_get_option_cnt(const lv_obj_t * ddlist); +uint16_t lv_dropdown_get_option_cnt(const lv_obj_t * obj); /** * Get the current selected option as a string - * @param ddlist pointer to ddlist object - * @param buf pointer to an array to store the string - * @param buf_size size of `buf` in bytes. 0: to ignore it. + * @param obj pointer to drop-down object + * @param buf pointer to an array to store the string + * @param buf_size size of `buf` in bytes. 0: to ignore it. */ -void lv_dropdown_get_selected_str(const lv_obj_t * ddlist, char * buf, uint32_t buf_size); +void lv_dropdown_get_selected_str(const lv_obj_t * obj, char * buf, uint32_t buf_size); /** - * Get the fix height value. - * @param ddlist pointer to a drop down list object - * @return the height if the ddlist is opened (0: auto size) + * Get the maximal height of the list. + * @param obj pointer to a drop-down list object + * @return the maximal height of the list */ -lv_coord_t lv_dropdown_get_max_height(const lv_obj_t * ddlist); +lv_coord_t lv_dropdown_get_max_height(const lv_obj_t * obj); /** - * Get the symbol to draw when the drop-down list is closed - * @param ddlist pointer to drop down list object - * @return the symbol or NULL if not enabled + * Get the symbol on the drop-down list. Typically a down caret or arrow. + * @param obj pointer to drop-down list object + * @return the symbol or NULL if not enabled */ -const char * lv_dropdown_get_symbol(lv_obj_t * ddlist); +const char * lv_dropdown_get_symbol(lv_obj_t * obj); /** - * Get the symbol to draw when the drop-down list is closed - * @param ddlist pointer to drop down list object - * @return the symbol or NULL if not enabled + * Get the direction of the drop-down list + * @param obj pointer to a drop-down list object + * @return LV_DIR_LEF/RIGHT/TOP/BOTTOM */ -lv_dir_t lv_dropdown_get_dir(const lv_obj_t * ddlist); +lv_dir_t lv_dropdown_get_dir(const lv_obj_t * obj); /*===================== * Other functions *====================*/ /** - * Open the drop down list with or without animation - * @param ddlist pointer to drop down list object + * Open the drop.down list + * @param obj pointer to drop-down list object */ -void lv_dropdown_open(lv_obj_t * ddlist); +void lv_dropdown_open(lv_obj_t * dropdown_obj); /** - * Close (Collapse) the drop down list - * @param ddlist pointer to drop down list object - * @param anim_en LV_ANIM_ON: use animation; LV_ANOM_OFF: not use animations + * Close (Collapse) the drop-down list + * @param obj pointer to drop-down list object */ -void lv_dropdown_close(lv_obj_t * ddlist); +void lv_dropdown_close(lv_obj_t * obj); + /********************** * MACROS diff --git a/src/lv_widgets/lv_img.c b/src/lv_widgets/lv_img.c index bfb1a0505..d9b99fced 100644 --- a/src/lv_widgets/lv_img.c +++ b/src/lv_widgets/lv_img.c @@ -54,12 +54,6 @@ const lv_obj_class_t lv_img = { * GLOBAL FUNCTIONS **********************/ -/** - * Create an image objects - * @param par pointer to an object, it will be the parent of the new button - * @param copy pointer to a image object, if not NULL then the new object will be copied from it - * @return pointer to the created image - */ lv_obj_t * lv_img_create(lv_obj_t * parent, const lv_obj_t * copy) { return lv_obj_create_from_class(&lv_img, parent, copy); @@ -69,18 +63,13 @@ lv_obj_t * lv_img_create(lv_obj_t * parent, const lv_obj_t * copy) * Setter functions *====================*/ -/** - * Set the pixel map to display by the image - * @param img pointer to an image object - * @param data the image data - */ -void lv_img_set_src(lv_obj_t * obj, const void * src_img) +void lv_img_set_src(lv_obj_t * obj, const void * src) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); lv_obj_invalidate(obj); - lv_img_src_t src_type = lv_img_src_get_type(src_img); + lv_img_src_t src_type = lv_img_src_get_type(src); lv_img_t * img = (lv_img_t *)obj; #if LV_USE_LOG && LV_LOG_LEVEL >= LV_LOG_LEVEL_INFO @@ -111,7 +100,7 @@ void lv_img_set_src(lv_obj_t * obj, const void * src_img) } lv_img_header_t header; - lv_img_decoder_get_info(src_img, &header); + lv_img_decoder_get_info(src, &header); /*Save the source*/ if(src_type == LV_IMG_SRC_VARIABLE) { @@ -121,11 +110,11 @@ void lv_img_set_src(lv_obj_t * obj, const void * src_img) if(img->src_type == LV_IMG_SRC_FILE || img->src_type == LV_IMG_SRC_SYMBOL) { lv_mem_free(img->src); } - img->src = src_img; + img->src = src; } else if(src_type == LV_IMG_SRC_FILE || src_type == LV_IMG_SRC_SYMBOL) { /* If the new and the old src are the same then it was only a refresh.*/ - if(img->src != src_img) { + if(img->src != src) { const void * old_src = NULL; /* If memory was allocated because of the previous `src_type` then save its pointer and free after allocation. * It's important to allocate first to be sure the new data will be on a new address. @@ -133,10 +122,10 @@ void lv_img_set_src(lv_obj_t * obj, const void * src_img) if(img->src_type == LV_IMG_SRC_FILE || img->src_type == LV_IMG_SRC_SYMBOL) { old_src = img->src; } - char * new_str = lv_mem_alloc(strlen(src_img) + 1); + char * new_str = lv_mem_alloc(strlen(src) + 1); LV_ASSERT_MEM(new_str); if(new_str == NULL) return; - strcpy(new_str, src_img); + strcpy(new_str, src); img->src = new_str; if(old_src) lv_mem_free(old_src); @@ -149,8 +138,7 @@ void lv_img_set_src(lv_obj_t * obj, const void * src_img) lv_coord_t letter_space = lv_obj_get_style_text_letter_space(obj, LV_PART_MAIN); lv_coord_t line_space = lv_obj_get_style_text_line_space(obj, LV_PART_MAIN); lv_point_t size; - _lv_txt_get_size(&size, src_img, font, letter_space, line_space, - LV_COORD_MAX, LV_TEXT_FLAG_NONE); + lv_txt_get_size(&size, src, font, letter_space, line_space, LV_COORD_MAX, LV_TEXT_FLAG_NONE); header.w = size.x; header.h = size.y; } @@ -170,12 +158,6 @@ void lv_img_set_src(lv_obj_t * obj, const void * src_img) lv_obj_invalidate(obj); } -/** - * Set an offset for the source of an image. - * so the image will be displayed from the new origin. - * @param img pointer to an image - * @param x: the new offset along x axis. - */ void lv_img_set_offset_x(lv_obj_t * obj, lv_coord_t x) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); @@ -188,12 +170,6 @@ void lv_img_set_offset_x(lv_obj_t * obj, lv_coord_t x) lv_obj_invalidate(obj); } -/** - * Set an offset for the source of an image. - * so the image will be displayed from the new origin. - * @param img pointer to an image - * @param y: the new offset along y axis. - */ void lv_img_set_offset_y(lv_obj_t * obj, lv_coord_t y) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); @@ -206,52 +182,6 @@ void lv_img_set_offset_y(lv_obj_t * obj, lv_coord_t y) lv_obj_invalidate(obj); } -/** - * Set the rotation center of the image. - * The image will be rotated around this point - * @param img pointer to an image object - * @param x rotation center x of the image - * @param y rotation center y of the image - */ -void lv_img_set_pivot(lv_obj_t * obj, lv_coord_t x, lv_coord_t y) -{ - lv_img_t * img = (lv_img_t *)obj; - if(img->pivot.x == x && img->pivot.y == y) return; - - lv_coord_t transf_zoom = lv_obj_get_style_transform_zoom(obj, LV_PART_MAIN); - transf_zoom = (transf_zoom * img->zoom) >> 8; - - lv_coord_t transf_angle = lv_obj_get_style_transform_angle(obj, LV_PART_MAIN); - transf_angle += img->angle; - - lv_coord_t w = lv_obj_get_width(obj); - lv_coord_t h = lv_obj_get_height(obj); - lv_area_t a; - _lv_img_buf_get_transformed_area(&a, w, h, transf_angle, transf_zoom, &img->pivot); - a.x1 += obj->coords.x1; - a.y1 += obj->coords.y1; - a.x2 += obj->coords.x1; - a.y2 += obj->coords.y1; - lv_obj_invalidate_area(obj, &a); - - img->pivot.x = x; - img->pivot.y = y; - lv_obj_refresh_ext_draw_size(obj); - - _lv_img_buf_get_transformed_area(&a, w, h, transf_angle, transf_zoom, &img->pivot); - a.x1 += obj->coords.x1; - a.y1 += obj->coords.y1; - a.x2 += obj->coords.x1; - a.y2 += obj->coords.y1; - lv_obj_invalidate_area(obj, &a); -} - -/** - * Set the rotation angle of the image. - * The image will be rotated around the set pivot set by `lv_img_set_pivot()` - * @param img pointer to an image object - * @param angle rotation angle in degree with 0.1 degree resolution (0..3600: clock wise) - */ void lv_img_set_angle(lv_obj_t * obj, int16_t angle) { if(angle < 0 || angle >= 3600) angle = angle % 3600; @@ -285,16 +215,39 @@ void lv_img_set_angle(lv_obj_t * obj, int16_t angle) lv_obj_invalidate_area(obj, &a); } -/** - * Set the zoom factor of the image. - * @param img pointer to an image object - * @param zoom the zoom factor. - * - 256 or LV_ZOOM_IMG_NONE for no zoom - * - <256: scale down - * - >256 scale up - * - 128 half size - * - 512 double size - */ +void lv_img_set_pivot(lv_obj_t * obj, lv_coord_t x, lv_coord_t y) +{ + lv_img_t * img = (lv_img_t *)obj; + if(img->pivot.x == x && img->pivot.y == y) return; + + lv_coord_t transf_zoom = lv_obj_get_style_transform_zoom(obj, LV_PART_MAIN); + transf_zoom = (transf_zoom * img->zoom) >> 8; + + lv_coord_t transf_angle = lv_obj_get_style_transform_angle(obj, LV_PART_MAIN); + transf_angle += img->angle; + + lv_coord_t w = lv_obj_get_width(obj); + lv_coord_t h = lv_obj_get_height(obj); + lv_area_t a; + _lv_img_buf_get_transformed_area(&a, w, h, transf_angle, transf_zoom, &img->pivot); + a.x1 += obj->coords.x1; + a.y1 += obj->coords.y1; + a.x2 += obj->coords.x1; + a.y2 += obj->coords.y1; + lv_obj_invalidate_area(obj, &a); + + img->pivot.x = x; + img->pivot.y = y; + lv_obj_refresh_ext_draw_size(obj); + + _lv_img_buf_get_transformed_area(&a, w, h, transf_angle, transf_zoom, &img->pivot); + a.x1 += obj->coords.x1; + a.y1 += obj->coords.y1; + a.x2 += obj->coords.x1; + a.y2 += obj->coords.y1; + lv_obj_invalidate_area(obj, &a); +} + void lv_img_set_zoom(lv_obj_t * obj, uint16_t zoom) { lv_img_t * img = (lv_img_t *)obj; @@ -328,11 +281,6 @@ void lv_img_set_zoom(lv_obj_t * obj, uint16_t zoom) lv_obj_invalidate_area(obj, &a); } -/** - * Enable/disable anti-aliasing for the transformations (rotate, zoom) or not - * @param img pointer to an image object - * @param antialias true: anti-aliased; false: not anti-aliased - */ void lv_img_set_antialias(lv_obj_t * obj, bool antialias) { lv_img_t * img = (lv_img_t *)obj; @@ -346,11 +294,6 @@ void lv_img_set_antialias(lv_obj_t * obj, bool antialias) * Getter functions *====================*/ -/** - * Get the source of the image - * @param img pointer to an image object - * @return the image source (symbol, file name or C array) - */ const void * lv_img_get_src(lv_obj_t * obj) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); @@ -360,11 +303,6 @@ const void * lv_img_get_src(lv_obj_t * obj) return img->src; } -/** - * Get the offset.x attribute of the img object. - * @param img pointer to an image - * @return offset.x value. - */ lv_coord_t lv_img_get_offset_x(lv_obj_t * obj) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); @@ -374,11 +312,6 @@ lv_coord_t lv_img_get_offset_x(lv_obj_t * obj) return img->offset.x; } -/** - * Get the offset.y attribute of the img object. - * @param img pointer to an image - * @return offset.y value. - */ lv_coord_t lv_img_get_offset_y(lv_obj_t * obj) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); @@ -388,25 +321,6 @@ lv_coord_t lv_img_get_offset_y(lv_obj_t * obj) return img->offset.y; } -/** - * Get the rotation center of the image. - * @param img pointer to an image object - * @param center rotation center of the image - */ -void lv_img_get_pivot(lv_obj_t * obj, lv_point_t * pivot) -{ - LV_ASSERT_OBJ(obj, LV_OBJX_NAME); - - lv_img_t * img = (lv_img_t *)obj; - - *pivot = img->pivot; -} - -/** - * Get the rotation angle of the image. - * @param img pointer to an image object - * @return rotation angle in degree (0..359) - */ uint16_t lv_img_get_angle(lv_obj_t * obj) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); @@ -416,11 +330,15 @@ uint16_t lv_img_get_angle(lv_obj_t * obj) return img->angle; } -/** - * Get the zoom factor of the image. - * @param img pointer to an image object - * @return zoom factor (256: no zoom) - */ +void lv_img_get_pivot(lv_obj_t * obj, lv_point_t * pivot) +{ + LV_ASSERT_OBJ(obj, LV_OBJX_NAME); + + lv_img_t * img = (lv_img_t *)obj; + + *pivot = img->pivot; +} + uint16_t lv_img_get_zoom(lv_obj_t * obj) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); @@ -430,11 +348,6 @@ uint16_t lv_img_get_zoom(lv_obj_t * obj) return img->zoom; } -/** - * Get whether the transformations (rotate, zoom) are anti-aliased or not - * @param img pointer to an image object - * @return true: anti-aliased; false: not anti-aliased - */ bool lv_img_get_antialias(lv_obj_t * obj) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); @@ -450,43 +363,43 @@ bool lv_img_get_antialias(lv_obj_t * obj) static void lv_img_constructor(lv_obj_t * obj, lv_obj_t * parent, const lv_obj_t * copy) { - LV_LOG_TRACE("lv_bar create started"); + LV_LOG_TRACE("lv_bar create started"); - lv_obj_construct_base(obj, parent, copy); + lv_obj_construct_base(obj, parent, copy); - lv_img_t * img = (lv_img_t *)obj; + lv_img_t * img = (lv_img_t *)obj; - img->src = NULL; - img->src_type = LV_IMG_SRC_UNKNOWN; - img->cf = LV_IMG_CF_UNKNOWN; - img->w = lv_obj_get_width(obj); - img->h = lv_obj_get_height(obj); - img->angle = 0; - img->zoom = LV_IMG_ZOOM_NONE; - img->antialias = LV_ANTIALIAS ? 1 : 0; - img->offset.x = 0; - img->offset.y = 0; - img->pivot.x = 0; - img->pivot.y = 0; + img->src = NULL; + img->src_type = LV_IMG_SRC_UNKNOWN; + img->cf = LV_IMG_CF_UNKNOWN; + img->w = lv_obj_get_width(obj); + img->h = lv_obj_get_height(obj); + img->angle = 0; + img->zoom = LV_IMG_ZOOM_NONE; + img->antialias = LV_ANTIALIAS ? 1 : 0; + img->offset.x = 0; + img->offset.y = 0; + img->pivot.x = 0; + img->pivot.y = 0; - if(copy == NULL) { - lv_obj_clear_flag(obj, LV_OBJ_FLAG_CLICKABLE); - lv_obj_add_flag(obj, LV_OBJ_FLAG_ADV_HITTEST); + if(copy == NULL) { + lv_obj_clear_flag(obj, LV_OBJ_FLAG_CLICKABLE); + lv_obj_add_flag(obj, LV_OBJ_FLAG_ADV_HITTEST); - /* Enable auto size for non screens - * because image screens are wallpapers - * and must be screen sized*/ - if(parent) lv_obj_set_size(obj, LV_SIZE_AUTO, LV_SIZE_AUTO); - } - else { - lv_img_t * copy_img = (lv_img_t *) copy; - img->zoom = copy_img->zoom; - img->angle = copy_img->angle; - img->antialias = copy_img->antialias; - img->offset = copy_img->offset; - img->pivot = copy_img->pivot; - lv_img_set_src(obj, copy_img->src); - } + /* Enable auto size for non screens + * because image screens are wallpapers + * and must be screen sized*/ + if(parent) lv_obj_set_size(obj, LV_SIZE_AUTO, LV_SIZE_AUTO); + } + else { + lv_img_t * copy_img = (lv_img_t *) copy; + img->zoom = copy_img->zoom; + img->angle = copy_img->angle; + img->antialias = copy_img->antialias; + img->offset = copy_img->offset; + img->pivot = copy_img->pivot; + lv_img_set_src(obj, copy_img->src); + } } static void lv_img_destructor(lv_obj_t * obj) @@ -497,16 +410,7 @@ static void lv_img_destructor(lv_obj_t * obj) // img->src_type = LV_IMG_SRC_UNKNOWN; // } } -/** - * Handle the drawing related tasks of the images - * @param img pointer to an object - * @param clip_area the object will be drawn only in this area - * @param mode LV_DRAW_COVER_CHK: only check if the object fully covers the 'mask_p' area - * (return 'true' if yes) - * LV_DRAW_DRAW: draw the object (always return 'true') - * LV_DRAW_DRAW_POST: drawing after every children are drawn - * @param return an element of `lv_draw_res_t` - */ + static lv_draw_res_t lv_img_draw(lv_obj_t * obj, const lv_area_t * clip_area, lv_draw_mode_t mode) { lv_img_t * img = (lv_img_t *)obj; @@ -576,10 +480,9 @@ static lv_draw_res_t lv_img_draw(lv_obj_t * obj, const lv_area_t * clip_area, lv lv_obj.draw_cb(obj, clip_area, mode); lv_area_copy(&obj->coords, &ori_coords); - if(mode == LV_DRAW_MODE_MAIN_DRAW) { + if(mode == LV_DRAW_MODE_MAIN_DRAW) { if(img->h == 0 || img->w == 0) return true; - if(zoom_final == 0) return LV_DRAW_RES_OK; lv_area_t img_coords; @@ -602,42 +505,19 @@ static lv_draw_res_t lv_img_draw(lv_obj_t * obj, const lv_area_t * clip_area, lv img_dsc.pivot.y = img->pivot.y; img_dsc.antialias = img->antialias; - lv_coord_t zoomed_src_w = (int32_t)((int32_t)img->w * zoom_final) >> 8; - if(zoomed_src_w <= 0) return LV_DRAW_RES_OK; - lv_coord_t zoomed_src_h = (int32_t)((int32_t)img->h * zoom_final) >> 8; - if(zoomed_src_h <= 0) return LV_DRAW_RES_OK; - lv_area_t zoomed_coords; - lv_area_copy(&zoomed_coords, &img_coords); - lv_coord_t img_w = lv_area_get_width(&img_coords); - lv_coord_t img_h = lv_area_get_height(&img_coords); - - zoomed_coords.x1 += (int32_t)((int32_t)img->offset.x * zoom_final) >> 8; - zoomed_coords.y1 += (int32_t)((int32_t)img->offset.y * zoom_final) >> 8; - zoomed_coords.x2 = zoomed_coords.x1 + ((int32_t)((int32_t)(img_w - 1) * zoom_final) >> 8); - zoomed_coords.y2 = zoomed_coords.y1 + ((int32_t)((int32_t)(img_h - 1) * zoom_final) >> 8); - - if(zoomed_coords.x1 > obj->coords.x1) zoomed_coords.x1 -= img->w; - if(zoomed_coords.y1 > obj->coords.y1) zoomed_coords.y1 -= img->h; - - lv_area_t clip_real; - _lv_img_buf_get_transformed_area(&clip_real, img_w, img_h, angle_final, zoom_final, - &img->pivot); - clip_real.x1 += img_coords.x1; - clip_real.x2 += img_coords.x1; - clip_real.y1 += img_coords.y1; - clip_real.y2 += img_coords.y1; - - if(_lv_area_intersect(&clip_real, &clip_real, clip_area) == false) return LV_DRAW_RES_OK; - lv_area_t coords_tmp; - coords_tmp.y1 = zoomed_coords.y1; - coords_tmp.y2 = zoomed_coords.y1 + img->h - 1; - for(; coords_tmp.y1 < zoomed_coords.y2; coords_tmp.y1 += zoomed_src_h, coords_tmp.y2 += zoomed_src_h) { - coords_tmp.x1 = zoomed_coords.x1; - coords_tmp.x2 = zoomed_coords.x1 + img->w - 1; - for(; coords_tmp.x1 < zoomed_coords.x2; coords_tmp.x1 += zoomed_src_w, coords_tmp.x2 += zoomed_src_w) { - lv_draw_img(&coords_tmp, &clip_real, img->src, &img_dsc); + coords_tmp.y1 = obj->coords.y1 + img->offset.y; + if(coords_tmp.y1 > obj->coords.y1) coords_tmp.y1 -= img->h; + coords_tmp.y2 = coords_tmp.y1 + img->h - 1; + + for(; coords_tmp.y1 < obj->coords.y2; coords_tmp.y1 += img->h, coords_tmp.y2 += img->h) { + coords_tmp.x1 = obj->coords.x1 + img->offset.x; + if(coords_tmp.x1 > obj->coords.x1) coords_tmp.x1 -= img->w; + coords_tmp.x2 = coords_tmp.x1 + img->w - 1; + + for(; coords_tmp.x1 < obj->coords.x2; coords_tmp.x1 += img->w, coords_tmp.x2 += img->w) { + lv_draw_img(&coords_tmp, clip_area, img->src, &img_dsc); } } } @@ -660,13 +540,6 @@ static lv_draw_res_t lv_img_draw(lv_obj_t * obj, const lv_area_t * clip_area, lv return LV_DRAW_RES_OK; } -/** - * Signal function of the image - * @param img pointer to an image 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_img_signal(lv_obj_t * obj, lv_signal_t sign, void * param) { lv_res_t res; diff --git a/src/lv_widgets/lv_img.h b/src/lv_widgets/lv_img.h index 7fac50b28..b44b5081e 100644 --- a/src/lv_widgets/lv_img.h +++ b/src/lv_widgets/lv_img.h @@ -50,75 +50,80 @@ extern const lv_obj_class_t lv_img; **********************/ /** - * Create an image objects - * @param par pointer to an object, it will be the parent of the new button - * @param copy pointer to a image object, if not NULL then the new object will be copied from it + * Create a image objects + * @param parent pointer to an object, it will be the parent of the new image + * @param copy DEPRECATED, will be removed in v9. + * Pointer to an other bar to copy. * @return pointer to the created image */ -lv_obj_t * lv_img_create(lv_obj_t * par, const lv_obj_t * copy); +lv_obj_t * lv_img_create(lv_obj_t * parent, const lv_obj_t * copy); /*===================== * Setter functions *====================*/ /** - * Set the pixel map to display by the image - * @param img pointer to an image object - * @param data the image data + * Set the image data to display on the the object + * @param obj pointer to an image object + * @param src_img 1) pointer to an ::lv_img_dsc_t descriptor (converted by LVGL's image converter) (e.g. &my_img) or + * 2) path to an image file (e.g. "S:/dir/img.bin")or + * 3) a SYMBOL (e.g. LV_SYMBOL_OK) */ -void lv_img_set_src(lv_obj_t * img, const void * src_img); +void lv_img_set_src(lv_obj_t * obj, const void * src); + +/** + * Set an offset for the source of an image so the image will be displayed from the new origin. + * @param obj pointer to an image + * @param x the new offset along x axis. + */ +void lv_img_set_offset_x(lv_obj_t * obj, lv_coord_t x); /** * Set an offset for the source of an image. * so the image will be displayed from the new origin. - * @param img pointer to an image - * @param x: the new offset along x axis. + * @param obj pointer to an image + * @param y the new offset along y axis. */ -void lv_img_set_offset_x(lv_obj_t * img, lv_coord_t x); +void lv_img_set_offset_y(lv_obj_t * obj, lv_coord_t y); -/** - * Set an offset for the source of an image. - * so the image will be displayed from the new origin. - * @param img pointer to an image - * @param y: the new offset along y axis. - */ -void lv_img_set_offset_y(lv_obj_t * img, lv_coord_t y); - -/** - * Set the rotation center of the image. - * The image will be rotated around this point - * @param img pointer to an image object - * @param x rotation center x of the image - * @param y rotation center y of the image - */ -void lv_img_set_pivot(lv_obj_t * img, lv_coord_t x, lv_coord_t y); /** * Set the rotation angle of the image. * The image will be rotated around the set pivot set by `lv_img_set_pivot()` - * @param img pointer to an image object - * @param angle rotation angle in degree with 0.1 degree resolution (0..3600: clock wise) + * @param obj pointer to an image object + * @param angle rotation angle in degree with 0.1 degree resolution (0..3600: clock wise) */ -void lv_img_set_angle(lv_obj_t * img, int16_t angle); +void lv_img_set_angle(lv_obj_t * obj, int16_t angle); + +/** + * Set the rotation center of the image. + * The image will be rotated around this point + * @param obj pointer to an image object + * @param x rotation center x of the image + * @param y rotation center y of the image + */ +void lv_img_set_pivot(lv_obj_t * obj, lv_coord_t x, lv_coord_t y); + /** * Set the zoom factor of the image. - * @param img pointer to an image object - * @param zoom the zoom factor. - * - 256 or LV_ZOOM_IMG_NONE for no zoom - * - <256: scale down - * - >256 scale up - * - 128 half size - * - 512 double size + * @param img pointer to an image object + * @param zoom the zoom factor. + * @example 256 or LV_ZOOM_IMG_NONE for no zoom + * @example <256: scale down + * @example >256 scale up + * @example 128 half size + * @example 512 double size */ -void lv_img_set_zoom(lv_obj_t * img, uint16_t zoom); +void lv_img_set_zoom(lv_obj_t * obj, uint16_t zoom); /** - * Enable/disable anti-aliasing for the transformations (rotate, zoom) or not - * @param img pointer to an image object + * Enable/disable anti-aliasing for the transformations (rotate, zoom) or not. + * The qualitiy is better with anti-aliasing looks better but slower. + * @param obj pointer to an image object * @param antialias true: anti-aliased; false: not anti-aliased */ -void lv_img_set_antialias(lv_obj_t * img, bool antialias); +void lv_img_set_antialias(lv_obj_t * obj, bool antialias); /*===================== * Getter functions @@ -126,58 +131,58 @@ void lv_img_set_antialias(lv_obj_t * img, bool antialias); /** * Get the source of the image - * @param img pointer to an image object - * @return the image source (symbol, file name or C array) + * @param obj pointer to an image object + * @return the image source (symbol, file name or ::lv-img_dsc_t for C arrays) */ -const void * lv_img_get_src(lv_obj_t * img); +const void * lv_img_get_src(lv_obj_t * obj); /** - * Get the offset.x attribute of the img object. - * @param img pointer to an image - * @return offset.x value. + * Get the offset's x attribute of the image object. + * @param img pointer to an image + * @return offset X value. */ -lv_coord_t lv_img_get_offset_x(lv_obj_t * img); +lv_coord_t lv_img_get_offset_x(lv_obj_t * obj); /** - * Get the offset.y attribute of the img object. - * @param img pointer to an image - * @return offset.y value. + * Get the offset's y attribute of the image object. + * @param obj pointer to an image + * @return offset Y value. */ -lv_coord_t lv_img_get_offset_y(lv_obj_t * img); +lv_coord_t lv_img_get_offset_y(lv_obj_t * obj); /** * Get the rotation angle of the image. - * @param img pointer to an image object - * @return rotation angle in degree (0..359) + * @param obj pointer to an image object + * @return rotation angle in 0.1 degrees (0..3600) */ -uint16_t lv_img_get_angle(lv_obj_t * img); +uint16_t lv_img_get_angle(lv_obj_t * obj); /** - * Get the rotation center of the image. - * @param img pointer to an image object - * @param center rotation center of the image + * Get the pivot (rotation center) of the image. + * @param img pointer to an image object + * @param pivot store the rotation center here */ -void lv_img_get_pivot(lv_obj_t * img, lv_point_t * center); +void lv_img_get_pivot(lv_obj_t * obj, lv_point_t * pivot);; /** * Get the zoom factor of the image. - * @param img pointer to an image object - * @return zoom factor (256: no zoom) + * @param obj pointer to an image object + * @return zoom factor (256: no zoom) */ -uint16_t lv_img_get_zoom(lv_obj_t * img); +uint16_t lv_img_get_zoom(lv_obj_t * obj); /** * Get whether the transformations (rotate, zoom) are anti-aliased or not - * @param img pointer to an image object - * @return true: anti-aliased; false: not anti-aliased + * @param obj pointer to an image object + * @return true: anti-aliased; false: not anti-aliased */ -bool lv_img_get_antialias(lv_obj_t * img); +bool lv_img_get_antialias(lv_obj_t * obj); /********************** * MACROS **********************/ -/*Use this macro to declare an image in a c file*/ +/** Use this macro to declare an image in a C file*/ #define LV_IMG_DECLARE(var_name) extern const lv_img_dsc_t var_name; #endif /*LV_USE_IMG*/ diff --git a/src/lv_widgets/lv_label.c b/src/lv_widgets/lv_label.c index 3d7c840cf..35af7a4ab 100644 --- a/src/lv_widgets/lv_label.c +++ b/src/lv_widgets/lv_label.c @@ -38,6 +38,8 @@ static void lv_label_constructor(lv_obj_t * obj, lv_obj_t * parent, const lv_obj static void lv_label_destructor(lv_obj_t * obj); static lv_res_t lv_label_signal(lv_obj_t * label, lv_signal_t sign, void * param); static lv_draw_res_t lv_label_draw(lv_obj_t * label, const lv_area_t * clip_area, lv_draw_mode_t mode); + +static void lv_label_refr_text(lv_obj_t * obj); static void lv_label_revert_dots(lv_obj_t * label); static void lv_label_set_offset_x(lv_obj_t * label, lv_coord_t x); @@ -68,13 +70,6 @@ const lv_obj_class_t lv_label = { * GLOBAL FUNCTIONS **********************/ -/** - * Create a label objects - * @param parent pointer to an object, it will be the parent of the new label - * @param copy DEPRECATED, will be removed in v9. - * Pointer to an other label to copy. - * @return pointer to the created button - */ lv_obj_t * lv_label_create(lv_obj_t * parent, const lv_obj_t * copy) { return lv_obj_create_from_class(&lv_label, parent, copy); @@ -84,11 +79,6 @@ lv_obj_t * lv_label_create(lv_obj_t * parent, const lv_obj_t * copy) * Setter functions *====================*/ -/** - * 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 * obj, const char * text) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); @@ -153,11 +143,6 @@ void lv_label_set_text(lv_obj_t * obj, const char * text) lv_label_refr_text(obj); } -/** - * Set a new formatted text for a label. Memory will be allocated to store the text by the label. - * @param label pointer to a label object - * @param fmt `printf`-like format - */ void lv_label_set_text_fmt(lv_obj_t * obj, const char * fmt, ...) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); @@ -186,12 +171,6 @@ void lv_label_set_text_fmt(lv_obj_t * obj, const char * fmt, ...) lv_label_refr_text(obj); } -/** - * Set a static text. It will not be saved by the label so the 'text' variable - * has to be 'alive' while the label exist. - * @param label pointer to a label object - * @param text pointer to a text. NULL to refresh with the current text. - */ void lv_label_set_text_static(lv_obj_t * obj, const char * text) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); @@ -210,13 +189,6 @@ void lv_label_set_text_static(lv_obj_t * obj, const char * text) lv_label_refr_text(obj); } -/** - * 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. - * In LV_LONG_BREAK/LONG/ROLL the size of the label should be set AFTER this - * function - */ void lv_label_set_long_mode(lv_obj_t * obj, lv_label_long_mode_t long_mode) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); @@ -245,11 +217,6 @@ void lv_label_set_long_mode(lv_obj_t * obj, lv_label_long_mode_t long_mode) lv_label_refr_text(obj); } -/** - * Enable the recoloring by in-line commands - * @param label pointer to a label object - * @param en true: enable recoloring, false: disable - */ void lv_label_set_recolor(lv_obj_t * obj, bool en) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); @@ -295,11 +262,6 @@ void lv_label_set_text_sel_end(lv_obj_t * obj, uint32_t index) * Getter functions *====================*/ -/** - * Get the text of a label - * @param label pointer to a label object - * @return the text of the label - */ char * lv_label_get_text(const lv_obj_t * obj) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); @@ -307,11 +269,6 @@ char * lv_label_get_text(const lv_obj_t * obj) return label->text; } -/** - * Get the long mode of a label - * @param label pointer to a label object - * @return the long mode - */ lv_label_long_mode_t lv_label_get_long_mode(const lv_obj_t * obj) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); @@ -319,11 +276,6 @@ lv_label_long_mode_t lv_label_get_long_mode(const lv_obj_t * obj) return label->long_mode; } -/** - * Get the recoloring attribute - * @param label pointer to a label object - * @return true: recoloring is enabled, false: disable - */ bool lv_label_get_recolor(const lv_obj_t * obj) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); @@ -332,13 +284,6 @@ bool lv_label_get_recolor(const lv_obj_t * obj) return label->recolor == 0 ? false : true; } -/** - * Get the relative x and y coordinates of a letter - * @param label pointer to a label object - * @param index index of the letter [0 ... text length]. Expressed in character index, not byte - * index (different in UTF-8) - * @param pos store the result here (E.g. index = 0 gives 0;0 coordinates) - */ void lv_label_get_letter_pos(const lv_obj_t * obj, uint32_t char_id, lv_point_t * pos) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); @@ -381,9 +326,6 @@ void lv_label_get_letter_pos(const lv_obj_t * obj, uint32_t char_id, lv_point_t if(label->expand != 0) flag |= LV_TEXT_FLAG_EXPAND; if(label->long_mode == LV_LABEL_LONG_EXPAND) flag |= LV_TEXT_FLAG_FIT; - if(align == LV_TEXT_ALIGN_CENTER) flag |= LV_TEXT_FLAG_CENTER; - if(align == LV_TEXT_ALIGN_RIGHT) flag |= LV_TEXT_FLAG_RIGHT; - uint32_t byte_id = _lv_txt_encoded_get_byte_id(txt, char_id); /*Search the line of the index letter */; @@ -453,13 +395,6 @@ void lv_label_get_letter_pos(const lv_obj_t * obj, uint32_t char_id, lv_point_t #endif } -/** - * Get the index of letter on a relative point of a label - * @param label pointer to label object - * @param pos pointer to point with coordinates on a the label - * @return the index of the letter on the 'pos_p' point (E.g. on 0;0 is the 0. letter) - * Expressed in character index and not byte index (different in UTF-8) - */ uint32_t lv_label_get_letter_on(const lv_obj_t * obj, lv_point_t * pos_in) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); @@ -490,8 +425,6 @@ uint32_t lv_label_get_letter_on(const lv_obj_t * obj, lv_point_t * pos_in) if(label->long_mode == LV_LABEL_LONG_EXPAND) flag |= LV_TEXT_FLAG_FIT; lv_text_align_t align = lv_obj_get_style_text_align(obj, LV_PART_MAIN); - if(align == LV_TEXT_ALIGN_CENTER) flag |= LV_TEXT_FLAG_CENTER; - if(align == LV_TEXT_ALIGN_RIGHT) flag |= LV_TEXT_FLAG_RIGHT; /*Search the line of the index letter */; while(txt[line_start] != '\0') { @@ -586,49 +519,6 @@ uint32_t lv_label_get_letter_on(const lv_obj_t * obj, lv_point_t * pos_in) return logical_pos + _lv_txt_encoded_get_char_id(txt, line_start); } -/** - * @brief Get the selection start index. - * @param label pointer to a label object. - * @return selection start index. `LV_LABEL_TXT_SEL_OFF` if nothing is selected. - */ -uint32_t lv_label_get_text_sel_start(const lv_obj_t * obj) -{ - LV_ASSERT_OBJ(obj, LV_OBJX_NAME); - -#if LV_LABEL_TEXT_SEL - lv_label_t * label = (lv_label_t *)obj; - return label->sel_start; - -#else - (void)obj; /*Unused*/ - return LV_LABEL_TEXT_SEL_OFF; -#endif -} - -/** - * @brief Get the selection end index. - * @param label pointer to a label object. - * @return selection end index. `LV_LABEL_TXT_SEL_OFF` if nothing is selected. - */ -uint32_t lv_label_get_text_sel_end(const lv_obj_t * obj) -{ - LV_ASSERT_OBJ(obj, LV_OBJX_NAME); - -#if LV_LABEL_TEXT_SEL - lv_label_t * label = (lv_label_t *)obj; - return label->sel_end; -#else - (void)obj; /*Unused*/ - return LV_LABEL_TEXT_SEL_OFF; -#endif -} - -/** - * Check if a character is drawn under a point. - * @param label Label object - * @param pos Point to check for character under - * @return whether a character is drawn under the point - */ bool lv_label_is_char_under_pos(const lv_obj_t * obj, lv_point_t * pos) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); @@ -652,7 +542,6 @@ bool lv_label_is_char_under_pos(const lv_obj_t * obj, lv_point_t * pos) if(label->recolor != 0) flag |= LV_TEXT_FLAG_RECOLOR; if(label->expand != 0) flag |= LV_TEXT_FLAG_EXPAND; if(label->long_mode == LV_LABEL_LONG_EXPAND) flag |= LV_TEXT_FLAG_FIT; - if(align == LV_TEXT_ALIGN_CENTER) flag |= LV_TEXT_FLAG_CENTER; /*Search the line of the index letter */; while(txt[line_start] != '\0') { @@ -715,17 +604,37 @@ bool lv_label_is_char_under_pos(const lv_obj_t * obj, lv_point_t * pos) return (pos->x >= (last_x - letter_space) && pos->x <= (last_x + max_diff)); } +uint32_t lv_label_get_text_sel_start(const lv_obj_t * obj) +{ + LV_ASSERT_OBJ(obj, LV_OBJX_NAME); + +#if LV_LABEL_TEXT_SEL + lv_label_t * label = (lv_label_t *)obj; + return label->sel_start; + +#else + (void)obj; /*Unused*/ + return LV_LABEL_TEXT_SEL_OFF; +#endif +} + +uint32_t lv_label_get_text_sel_end(const lv_obj_t * obj) +{ + LV_ASSERT_OBJ(obj, LV_OBJX_NAME); + +#if LV_LABEL_TEXT_SEL + lv_label_t * label = (lv_label_t *)obj; + return label->sel_end; +#else + (void)obj; /*Unused*/ + return LV_LABEL_TEXT_SEL_OFF; +#endif +} + /*===================== * Other functions *====================*/ -/** - * 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 * obj, uint32_t pos, const char * txt) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); @@ -765,13 +674,6 @@ void lv_label_ins_text(lv_obj_t * obj, uint32_t pos, const char * txt) lv_label_set_text(obj, NULL); } -/** - * Delete characters from a 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. - * @param cnt number of characters to cut - */ void lv_label_cut_text(lv_obj_t * obj, uint32_t pos, uint32_t cnt) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); @@ -790,11 +692,206 @@ void lv_label_cut_text(lv_obj_t * obj, uint32_t pos, uint32_t cnt) lv_label_refr_text(obj); } + +/********************** + * STATIC FUNCTIONS + **********************/ + +static void lv_label_constructor(lv_obj_t * obj, lv_obj_t * parent, const lv_obj_t * copy) +{ + LV_LOG_TRACE("label create started"); + + lv_obj_construct_base(obj, parent, copy); + + lv_label_t * label = (lv_label_t *)obj; + + label->text = NULL; + label->static_txt = 0; + label->recolor = 0; + label->dot_end = LV_LABEL_DOT_END_INV; + label->long_mode = LV_LABEL_LONG_EXPAND; + label->offset.x = 0; + label->offset.y = 0; + +#if LV_LABEL_LONG_TXT_HINT + label->hint.line_start = -1; + label->hint.coord_y = 0; + label->hint.y = 0; +#endif + +#if LV_LABEL_TEXT_SEL + label->sel_start = LV_DRAW_LABEL_NO_TXT_SEL; + label->sel_end = LV_DRAW_LABEL_NO_TXT_SEL; +#endif + label->dot.tmp_ptr = NULL; + label->dot_tmp_alloc = 0; + + lv_obj_clear_flag(obj, LV_OBJ_FLAG_CLICKABLE); + lv_label_set_long_mode(obj, LV_LABEL_LONG_EXPAND); + lv_label_set_text(obj, "Text"); + + LV_LOG_INFO("label created"); +} + +static void lv_label_destructor(lv_obj_t * obj) +{ +// lv_label_dot_tmp_free(label->dot_...); +// lv_label_dot_tmp_free(label->text); + +// lv_bar_t * bar = obj; +// +// _lv_obj_reset_style_list_no_refr(obj, LV_PART_INDICATOR); +//#if LV_USE_ANIMATION +// lv_anim_del(&bar->cur_value_anim, NULL); +// lv_anim_del(&bar->start_value_anim, NULL); +//#endif + +// bar->class_p->base_p->destructor(obj); +} + +/** + * Handle the drawing related tasks of the labels + * @param label pointer to a label object + * @param clip_area the object will be drawn only in this area + * @param mode LV_DRAW_COVER_CHK: only check if the object fully covers the 'mask_p' area + * (return 'true' if yes) + * LV_DRAW_DRAW: draw the object (always return 'true') + * LV_DRAW_DRAW_POST: drawing after every children are drawn + * @param return an element of `lv_draw_res_t` + */ +static lv_draw_res_t lv_label_draw(lv_obj_t * obj, const lv_area_t * clip_area, lv_draw_mode_t mode) +{ + /* A label never covers an area */ + if(mode == LV_DRAW_MODE_COVER_CHECK) + return LV_DRAW_RES_NOT_COVER; + else if(mode == LV_DRAW_MODE_MAIN_DRAW) { + + lv_obj.draw_cb(obj, clip_area, mode); + + lv_label_t * label = (lv_label_t *)obj; + lv_area_t txt_coords; + get_txt_coords(obj, &txt_coords); + + lv_area_t txt_clip; + bool is_common = _lv_area_intersect(&txt_clip, clip_area, &txt_coords); + if(!is_common) return LV_DRAW_RES_OK; + + lv_text_align_t align = lv_obj_get_style_text_align(obj, LV_PART_MAIN); + lv_text_flag_t flag = LV_TEXT_FLAG_NONE; + if(label->recolor != 0) flag |= LV_TEXT_FLAG_RECOLOR; + if(label->expand != 0) flag |= LV_TEXT_FLAG_EXPAND; + if(label->long_mode == LV_LABEL_LONG_EXPAND) flag |= LV_TEXT_FLAG_FIT; + + lv_draw_label_dsc_t label_draw_dsc; + lv_draw_label_dsc_init(&label_draw_dsc); + + label_draw_dsc.ofs_x = label->offset.x; + label_draw_dsc.ofs_y = label->offset.y; + label_draw_dsc.flag = flag; + lv_obj_init_draw_label_dsc(obj, LV_PART_MAIN, &label_draw_dsc); + + label_draw_dsc.sel_start = lv_label_get_text_sel_start(obj); + label_draw_dsc.sel_end = lv_label_get_text_sel_end(obj); + if(label_draw_dsc.sel_start != LV_DRAW_LABEL_NO_TXT_SEL && label_draw_dsc.sel_end != LV_DRAW_LABEL_NO_TXT_SEL) { + label_draw_dsc.sel_color = lv_obj_get_style_text_color_filtered(obj, LV_PART_SELECTED); + label_draw_dsc.sel_bg_color = lv_obj_get_style_bg_color(obj, LV_PART_SELECTED); + } + + /* In SROLL and SROLL_CIRC mode the CENTER and RIGHT are pointless so remove them. + * (In addition they will result misalignment is this case)*/ + if((label->long_mode == LV_LABEL_LONG_SROLL || label->long_mode == LV_LABEL_LONG_SROLL_CIRC) && + (align == LV_TEXT_ALIGN_CENTER || align == LV_TEXT_ALIGN_RIGHT)) { + lv_point_t size; + lv_txt_get_size(&size, label->text, label_draw_dsc.font, label_draw_dsc.letter_space, label_draw_dsc.line_space, + LV_COORD_MAX, flag); + if(size.x > lv_area_get_width(&txt_coords)) { + label_draw_dsc.align = LV_TEXT_ALIGN_LEFT; + } + } +#if LV_LABEL_LONG_TXT_HINT + lv_draw_label_hint_t * hint = &label->hint; + if(label->long_mode == LV_LABEL_LONG_SROLL_CIRC || lv_area_get_height(&txt_coords) < LV_LABEL_HINT_HEIGHT_LIMIT) + hint = NULL; + +#else + /*Just for compatibility*/ + lv_draw_label_hint_t * hint = NULL; +#endif + + lv_draw_label(&txt_coords, &txt_clip, &label_draw_dsc, label->text, hint); + + if(label->long_mode == LV_LABEL_LONG_SROLL_CIRC) { + lv_point_t size; + lv_txt_get_size(&size, label->text, label_draw_dsc.font, label_draw_dsc.letter_space, label_draw_dsc.line_space, + LV_COORD_MAX, flag); + + /*Draw the text again on label to the original to make an circular effect */ + if(size.x > lv_area_get_width(&txt_coords)) { + label_draw_dsc.ofs_x = label->offset.x + size.x + + lv_font_get_glyph_width(label_draw_dsc.font, ' ', ' ') * LV_LABEL_WAIT_CHAR_COUNT; + label_draw_dsc.ofs_y = label->offset.y; + + lv_draw_label(&txt_coords, &txt_clip, &label_draw_dsc, label->text, hint); + } + + /*Draw the text again below the original to make an circular effect */ + if(size.y > lv_area_get_height(&txt_coords)) { + label_draw_dsc.ofs_x = label->offset.x; + label_draw_dsc.ofs_y = label->offset.y + size.y + lv_font_get_line_height(label_draw_dsc.font); + + lv_draw_label(&txt_coords, &txt_clip, &label_draw_dsc, label->text, hint); + } + } + } else if(mode == LV_DRAW_MODE_POST_DRAW) { + lv_obj.draw_cb(obj, clip_area, mode); + } + + return LV_DRAW_RES_OK; +} + +/** + * 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 * obj, lv_signal_t sign, void * param) +{ + lv_res_t res; + + /* Include the ancient signal function */ + res = lv_obj.signal_cb(obj, sign, param); + if(res != LV_RES_OK) return res; + + if(sign == LV_SIGNAL_STYLE_CHG) { + /*Revert dots for proper refresh*/ + lv_label_revert_dots(obj); + lv_label_refr_text(obj); + } + else if(sign == LV_SIGNAL_COORD_CHG) { + if(lv_area_get_width(&obj->coords) != lv_area_get_width(param) || + lv_area_get_height(&obj->coords) != lv_area_get_height(param)) { + lv_label_revert_dots(obj); + lv_label_refr_text(obj); + } + } + else if(sign == LV_SIGNAL_BASE_DIR_CHG) { +#if LV_USE_BIDI + lv_label_t * label = (lv_label_t *)obj; + if(label->static_txt == 0) lv_label_set_text(obj, NULL); +#endif + } + + return res; +} + + /** * Refresh the label with its text stored in its labelended data * @param label pointer to a label object */ -void lv_label_refr_text(lv_obj_t * obj) +static void lv_label_refr_text(lv_obj_t * obj) { lv_label_t * label = (lv_label_t *)obj; if(label->text == NULL) return; @@ -815,7 +912,7 @@ void lv_label_refr_text(lv_obj_t * obj) if(label->recolor != 0) flag |= LV_TEXT_FLAG_RECOLOR; if(label->expand != 0) flag |= LV_TEXT_FLAG_EXPAND; if(label->long_mode == LV_LABEL_LONG_EXPAND) flag |= LV_TEXT_FLAG_FIT; - _lv_txt_get_size(&size, label->text, font, letter_space, line_space, max_w, flag); + lv_txt_get_size(&size, label->text, font, letter_space, line_space, max_w, flag); /*Set the full size in expand mode*/ if(label->long_mode == LV_LABEL_LONG_EXPAND) { @@ -826,6 +923,7 @@ void lv_label_refr_text(lv_obj_t * obj) /*In roll mode keep the size but start offset animations*/ else if(label->long_mode == LV_LABEL_LONG_SROLL) { uint16_t anim_speed = lv_obj_get_style_anim_time(obj, LV_PART_MAIN); + if(anim_speed == 0) anim_speed = LV_LABEL_DEF_SCROLL_SPEED; lv_anim_t a; lv_anim_init(&a); lv_anim_set_var(&a, obj); @@ -908,6 +1006,7 @@ void lv_label_refr_text(lv_obj_t * obj) /*In roll inf. mode keep the size but start offset animations*/ else if(label->long_mode == LV_LABEL_LONG_SROLL_CIRC) { uint16_t anim_speed = lv_obj_get_style_anim_time(obj, LV_PART_MAIN); + if(anim_speed == 0) anim_speed = LV_LABEL_DEF_SCROLL_SPEED; lv_anim_t a; lv_anim_init(&a); lv_anim_set_var(&a, obj); @@ -1021,201 +1120,6 @@ void lv_label_refr_text(lv_obj_t * obj) lv_obj_invalidate(obj); } -/********************** - * STATIC FUNCTIONS - **********************/ - - -static void lv_label_constructor(lv_obj_t * obj, lv_obj_t * parent, const lv_obj_t * copy) -{ - LV_LOG_TRACE("label create started"); - - lv_obj_construct_base(obj, parent, copy); - - lv_label_t * label = (lv_label_t *)obj; - - label->text = NULL; - label->static_txt = 0; - label->recolor = 0; - label->dot_end = LV_LABEL_DOT_END_INV; - label->long_mode = LV_LABEL_LONG_EXPAND; - label->offset.x = 0; - label->offset.y = 0; - -#if LV_LABEL_LONG_TXT_HINT - label->hint.line_start = -1; - label->hint.coord_y = 0; - label->hint.y = 0; -#endif - -#if LV_LABEL_TEXT_SEL - label->sel_start = LV_DRAW_LABEL_NO_TXT_SEL; - label->sel_end = LV_DRAW_LABEL_NO_TXT_SEL; -#endif - label->dot.tmp_ptr = NULL; - label->dot_tmp_alloc = 0; - - lv_obj_clear_flag(obj, LV_OBJ_FLAG_CLICKABLE); - lv_label_set_long_mode(obj, LV_LABEL_LONG_EXPAND); - lv_label_set_text(obj, "Text"); - - LV_LOG_INFO("label created"); -} - -static void lv_label_destructor(lv_obj_t * obj) -{ -// lv_label_dot_tmp_free(label->dot_...); -// lv_label_dot_tmp_free(label->text); - -// lv_bar_t * bar = obj; -// -// _lv_obj_reset_style_list_no_refr(obj, LV_PART_INDICATOR); -//#if LV_USE_ANIMATION -// lv_anim_del(&bar->cur_value_anim, NULL); -// lv_anim_del(&bar->start_value_anim, NULL); -//#endif - -// bar->class_p->base_p->destructor(obj); -} - -/** - * Handle the drawing related tasks of the labels - * @param label pointer to a label object - * @param clip_area the object will be drawn only in this area - * @param mode LV_DRAW_COVER_CHK: only check if the object fully covers the 'mask_p' area - * (return 'true' if yes) - * LV_DRAW_DRAW: draw the object (always return 'true') - * LV_DRAW_DRAW_POST: drawing after every children are drawn - * @param return an element of `lv_draw_res_t` - */ -static lv_draw_res_t lv_label_draw(lv_obj_t * obj, const lv_area_t * clip_area, lv_draw_mode_t mode) -{ - /* A label never covers an area */ - if(mode == LV_DRAW_MODE_COVER_CHECK) - return LV_DRAW_RES_NOT_COVER; - else if(mode == LV_DRAW_MODE_MAIN_DRAW) { - - lv_obj.draw_cb(obj, clip_area, mode); - - lv_label_t * label = (lv_label_t *)obj; - lv_area_t txt_coords; - get_txt_coords(obj, &txt_coords); - - lv_area_t txt_clip; - bool is_common = _lv_area_intersect(&txt_clip, clip_area, &txt_coords); - if(!is_common) return LV_DRAW_RES_OK; - - lv_text_align_t align = lv_obj_get_style_text_align(obj, LV_PART_MAIN); - lv_text_flag_t flag = LV_TEXT_FLAG_NONE; - if(label->recolor != 0) flag |= LV_TEXT_FLAG_RECOLOR; - if(label->expand != 0) flag |= LV_TEXT_FLAG_EXPAND; - if(label->long_mode == LV_LABEL_LONG_EXPAND) flag |= LV_TEXT_FLAG_FIT; - if(align == LV_TEXT_ALIGN_CENTER) flag |= LV_TEXT_FLAG_CENTER; - if(align == LV_TEXT_ALIGN_RIGHT) flag |= LV_TEXT_FLAG_RIGHT; - - lv_draw_label_dsc_t label_draw_dsc; - lv_draw_label_dsc_init(&label_draw_dsc); - - label_draw_dsc.ofs_x = label->offset.x; - label_draw_dsc.ofs_y = label->offset.y; - label_draw_dsc.flag = flag; - lv_obj_init_draw_label_dsc(obj, LV_PART_MAIN, &label_draw_dsc); - - label_draw_dsc.sel_start = lv_label_get_text_sel_start(obj); - label_draw_dsc.sel_end = lv_label_get_text_sel_end(obj); - if(label_draw_dsc.sel_start != LV_DRAW_LABEL_NO_TXT_SEL && label_draw_dsc.sel_end != LV_DRAW_LABEL_NO_TXT_SEL) { - label_draw_dsc.sel_color = lv_obj_get_style_text_color_filtered(obj, LV_PART_SELECTED); - label_draw_dsc.sel_bg_color = lv_obj_get_style_bg_color(obj, LV_PART_SELECTED); - } - - /* In SROLL and SROLL_CIRC mode the CENTER and RIGHT are pointless so remove them. - * (In addition they will result misalignment is this case)*/ - if((label->long_mode == LV_LABEL_LONG_SROLL || label->long_mode == LV_LABEL_LONG_SROLL_CIRC) && - (align == LV_TEXT_ALIGN_CENTER || align == LV_TEXT_ALIGN_RIGHT)) { - lv_point_t size; - _lv_txt_get_size(&size, label->text, label_draw_dsc.font, label_draw_dsc.letter_space, label_draw_dsc.line_space, - LV_COORD_MAX, flag); - if(size.x > lv_area_get_width(&txt_coords)) { - label_draw_dsc.flag &= ~LV_TEXT_FLAG_RIGHT; - label_draw_dsc.flag &= ~LV_TEXT_FLAG_CENTER; - } - } -#if LV_LABEL_LONG_TXT_HINT - lv_draw_label_hint_t * hint = &label->hint; - if(label->long_mode == LV_LABEL_LONG_SROLL_CIRC || lv_area_get_height(&txt_coords) < LV_LABEL_HINT_HEIGHT_LIMIT) - hint = NULL; - -#else - /*Just for compatibility*/ - lv_draw_label_hint_t * hint = NULL; -#endif - - lv_draw_label(&txt_coords, &txt_clip, &label_draw_dsc, label->text, hint); - - if(label->long_mode == LV_LABEL_LONG_SROLL_CIRC) { - lv_point_t size; - _lv_txt_get_size(&size, label->text, label_draw_dsc.font, label_draw_dsc.letter_space, label_draw_dsc.line_space, - LV_COORD_MAX, flag); - - /*Draw the text again on label to the original to make an circular effect */ - if(size.x > lv_area_get_width(&txt_coords)) { - label_draw_dsc.ofs_x = label->offset.x + size.x + - lv_font_get_glyph_width(label_draw_dsc.font, ' ', ' ') * LV_LABEL_WAIT_CHAR_COUNT; - label_draw_dsc.ofs_y = label->offset.y; - - lv_draw_label(&txt_coords, &txt_clip, &label_draw_dsc, label->text, hint); - } - - /*Draw the text again below the original to make an circular effect */ - if(size.y > lv_area_get_height(&txt_coords)) { - label_draw_dsc.ofs_x = label->offset.x; - label_draw_dsc.ofs_y = label->offset.y + size.y + lv_font_get_line_height(label_draw_dsc.font); - - lv_draw_label(&txt_coords, &txt_clip, &label_draw_dsc, label->text, hint); - } - } - } else if(mode == LV_DRAW_MODE_POST_DRAW) { - lv_obj.draw_cb(obj, clip_area, mode); - } - - return LV_DRAW_RES_OK; -} - -/** - * 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 * obj, lv_signal_t sign, void * param) -{ - lv_res_t res; - - /* Include the ancient signal function */ - res = lv_obj.signal_cb(obj, sign, param); - if(res != LV_RES_OK) return res; - - if(sign == LV_SIGNAL_STYLE_CHG) { - /*Revert dots for proper refresh*/ - lv_label_revert_dots(obj); - lv_label_refr_text(obj); - } - else if(sign == LV_SIGNAL_COORD_CHG) { - if(lv_area_get_width(&obj->coords) != lv_area_get_width(param) || - lv_area_get_height(&obj->coords) != lv_area_get_height(param)) { - lv_label_revert_dots(obj); - lv_label_refr_text(obj); - } - } - else if(sign == LV_SIGNAL_BASE_DIR_CHG) { -#if LV_USE_BIDI - if(label->static_txt == 0) lv_label_set_text(label, NULL); -#endif - } - - return res; -} static void lv_label_revert_dots(lv_obj_t * obj) { diff --git a/src/lv_widgets/lv_label.h b/src/lv_widgets/lv_label.h index acb82e0eb..907d179bc 100644 --- a/src/lv_widgets/lv_label.h +++ b/src/lv_widgets/lv_label.h @@ -83,10 +83,10 @@ extern const lv_obj_class_t lv_label; /** * Create a label objects - * @param parent pointer to an object, it will be the parent of the new label - * @param copy DEPRECATED, will be removed in v9. - * Pointer to an other label to copy. - * @return pointer to the created button + * @param parent pointer to an object, it will be the parent of the new label + * @param copy DEPRECATED, will be removed in v9. + * Pointer to an other label to copy. + * @return pointer to the created button */ lv_obj_t * lv_label_create(lv_obj_t * parent, const lv_obj_t * copy); @@ -96,55 +96,56 @@ lv_obj_t * lv_label_create(lv_obj_t * parent, const lv_obj_t * copy); /** * 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. + * @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); +void lv_label_set_text(lv_obj_t * obj, const char * text); /** * Set a new formatted text for a label. Memory will be allocated to store the text by the label. - * @param label pointer to a label object - * @param fmt `printf`-like format + * @param label pointer to a label object + * @param fmt `printf`-like format + * @example lv_label_set_text_fmt(label1, "%d user", user_num); */ -void lv_label_set_text_fmt(lv_obj_t * label, const char * fmt, ...); +void lv_label_set_text_fmt(lv_obj_t * obj, const char * fmt, ...); /** * Set a static text. It will not be saved by the label so the 'text' variable * has to be 'alive' while the label exist. - * @param label pointer to a label object - * @param text pointer to a text. NULL to refresh with the current text. + * @param label pointer to a label object + * @param text pointer to a text. NULL to refresh with the current text. */ -void lv_label_set_text_static(lv_obj_t * label, const char * text); +void lv_label_set_text_static(lv_obj_t * obj, const char * text); /** * 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. - * In LV_LONG_BREAK/LONG/ROLL the size of the label should be set AFTER this - * function + * @param label pointer to a label object + * @param long_mode the new mode from 'lv_label_long_mode' enum. + * In LV_LONG_WRAP/DOT/SCROLL/SCROLL_CIRC the size of the label should be set AFTER this function */ -void lv_label_set_long_mode(lv_obj_t * label, lv_label_long_mode_t long_mode); +void lv_label_set_long_mode(lv_obj_t * obj, lv_label_long_mode_t long_mode); /** * Enable the recoloring by in-line commands - * @param label pointer to a label object - * @param en true: enable recoloring, false: disable + * @param label pointer to a label object + * @param en true: enable recoloring, false: disable + * @example "This is a #ff0000 red# word" */ -void lv_label_set_recolor(lv_obj_t * label, bool en); +void lv_label_set_recolor(lv_obj_t * obj, bool en); /** - * @brief Set the selection start index. - * @param label pointer to a label object. - * @param index index to set. `LV_LABEL_TXT_SEL_OFF` to select nothing. + * Set where text selection should start + * @param obj pointer to a label object + * @param index character index from where selection should start. `LV_LABEL_TEXT_SEL_OFF` for no selection */ -void lv_label_set_text_sel_start(lv_obj_t * label, uint32_t index); +void lv_label_set_text_sel_start(lv_obj_t * obj, uint32_t index); /** - * @brief Set the selection end index. - * @param label pointer to a label object. - * @param index index to set. `LV_LABEL_TXT_SEL_OFF` to select nothing. + * Set where text selection should end + * @param obj pointer to a label object + * @param index character index where selection should end. `LV_LABEL_TEXT_SEL_OFF` for no selection */ -void lv_label_set_text_sel_end(lv_obj_t * label, uint32_t index); +void lv_label_set_text_sel_end(lv_obj_t * obj, uint32_t index); /*===================== * Getter functions @@ -152,49 +153,42 @@ void lv_label_set_text_sel_end(lv_obj_t * label, uint32_t index); /** * Get the text of a label - * @param label pointer to a label object - * @return the text of the label + * @param obj pointer to a label object + * @return the text of the label */ -char * lv_label_get_text(const lv_obj_t * label); +char * lv_label_get_text(const lv_obj_t * obj); /** * Get the long mode of a label - * @param label pointer to a label object - * @return the long mode + * @param obj pointer to a label object + * @return the current long mode */ -lv_label_long_mode_t lv_label_get_long_mode(const lv_obj_t * label); +lv_label_long_mode_t lv_label_get_long_mode(const lv_obj_t * obj); /** * Get the recoloring attribute - * @param label pointer to a label object - * @return true: recoloring is enabled, false: disable + * @param obj pointer to a label object + * @return true: recoloring is enabled, false: disable */ -bool lv_label_get_recolor(const lv_obj_t * label); - -/** - * Get the label's animation speed in LV_LABEL_LONG_ROLL and SCROLL modes - * @param label pointer to a label object - * @return speed of animation in px/sec unit - */ -uint16_t lv_label_get_anim_speed(const lv_obj_t * label); +bool lv_label_get_recolor(const lv_obj_t * obj); /** * Get the relative x and y coordinates of a letter - * @param label pointer to a label object - * @param index index of the letter [0 ... text length]. Expressed in character index, not byte - * index (different in UTF-8) - * @param pos store the result here (E.g. index = 0 gives 0;0 coordinates) + * @param obj pointer to a label object + * @param index index of the character [0 ... text length - 1]. + * Expressed in character index, not byte index (different in UTF-8) + * @param pos store the result here (E.g. index = 0 gives 0;0 coordinates if the text if aligned to the left) */ -void lv_label_get_letter_pos(const lv_obj_t * label, uint32_t index, lv_point_t * pos); +void lv_label_get_letter_pos(const lv_obj_t * obj, uint32_t char_id, lv_point_t * pos); /** - * Get the index of letter on a relative point of a label - * @param label pointer to label object - * @param pos pointer to point with coordinates on a the label - * @return the index of the letter on the 'pos_p' point (E.g. on 0;0 is the 0. letter) - * Expressed in character index and not byte index (different in UTF-8) + * Get the index of letter on a relative point of a label. + * @param obj pointer to label object + * @param pos pointer to point with coordinates on a the label + * @return The index of the letter on the 'pos_p' point (E.g. on 0;0 is the 0. letter if aligned to the left) + * Expressed in character index and not byte index (different in UTF-8) */ -uint32_t lv_label_get_letter_on(const lv_obj_t * label, lv_point_t * pos); +uint32_t lv_label_get_letter_on(const lv_obj_t * obj, lv_point_t * pos_in); /** * Check if a character is drawn under a point. @@ -202,49 +196,43 @@ uint32_t lv_label_get_letter_on(const lv_obj_t * label, lv_point_t * pos); * @param pos Point to check for character under * @return whether a character is drawn under the point */ -bool lv_label_is_char_under_pos(const lv_obj_t * label, lv_point_t * pos); +bool lv_label_is_char_under_pos(const lv_obj_t * obj, lv_point_t * pos); /** * @brief Get the selection start index. - * @param label pointer to a label object. - * @return selection start index. `LV_LABEL_TXT_SEL_OFF` if nothing is selected. + * @param obj pointer to a label object. + * @return selection start index. `LV_LABEL_TEXT_SEL_OFF` if nothing is selected. */ -uint32_t lv_label_get_text_sel_start(const lv_obj_t * label); +uint32_t lv_label_get_text_sel_start(const lv_obj_t * obj); /** * @brief Get the selection end index. - * @param label pointer to a label object. - * @return selection end index. `LV_LABEL_TXT_SEL_OFF` if nothing is selected. + * @param obj pointer to a label object. + * @return selection end index. `LV_LABEL_TXT_SEL_OFF` if nothing is selected. */ -uint32_t lv_label_get_text_sel_end(const lv_obj_t * label); +uint32_t lv_label_get_text_sel_end(const lv_obj_t * obj); /*===================== * Other functions *====================*/ /** - * 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 + * Insert a text to a label. The label text can not be static. + * @param obj pointer to a label object + * @param pos character index to insert. Expressed in character index and not byte index. + * 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); +void lv_label_ins_text(lv_obj_t * obj, uint32_t pos, const char * txt); /** * Delete characters from a 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. - * @param cnt number of characters to cut + * @param label pointer to a label object + * @param pos character index from where to cut. Expressed in character index and not byte index. + * 0: start in from of the first character + * @param cnt number of characters to cut */ -void lv_label_cut_text(lv_obj_t * label, uint32_t pos, uint32_t cnt); - -/** - * Refresh the label with its text stored in its extended data - * @param label pointer to a label object - */ -void lv_label_refr_text(lv_obj_t * label); +void lv_label_cut_text(lv_obj_t * obj, uint32_t pos, uint32_t cnt); /********************** * MACROS diff --git a/src/lv_widgets/lv_line.c b/src/lv_widgets/lv_line.c index 65d38c70e..1df55e45c 100644 --- a/src/lv_widgets/lv_line.c +++ b/src/lv_widgets/lv_line.c @@ -54,11 +54,6 @@ const lv_obj_class_t lv_line = { * GLOBAL FUNCTIONS **********************/ -/** - * Create a line objects - * @param par pointer to an object, it will be the parent of the new line - * @return pointer to the created line - */ lv_obj_t * lv_line_create(lv_obj_t * parent, const lv_obj_t * copy) { return lv_obj_create_from_class(&lv_line, parent, copy); @@ -68,19 +63,12 @@ lv_obj_t * lv_line_create(lv_obj_t * parent, const lv_obj_t * copy) * Setter functions *====================*/ -/** - * Set an array of points. The line object will connect these points. - * @param line pointer to a line object - * @param point_a an array of points. Only the address is saved, - * so the array can NOT be a local variable which will be destroyed - * @param point_num number of points in 'point_a' - */ -void lv_line_set_points(lv_obj_t * obj, const lv_point_t point_a[], uint16_t point_num) +void lv_line_set_points(lv_obj_t * obj, const lv_point_t points[], uint16_t point_num) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); lv_line_t * line = (lv_line_t *) obj; - line->point_array = point_a; + line->point_array = points; line->point_num = point_num; lv_obj_handle_self_size_chg(obj); @@ -88,13 +76,6 @@ void lv_line_set_points(lv_obj_t * obj, const lv_point_t point_a[], uint16_t poi lv_obj_invalidate(obj); } -/** - * Enable (or disable) the y coordinate inversion. - * If enabled then y will be subtracted from the height of the object, - * therefore the y=0 coordinate will be on the bottom. - * @param line pointer to a line object - * @param en true: enable the y inversion, false:disable the y inversion - */ void lv_line_set_y_invert(lv_obj_t * obj, bool en) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); @@ -111,11 +92,6 @@ void lv_line_set_y_invert(lv_obj_t * obj, bool en) * Getter functions *====================*/ -/** - * Get the y inversion attribute - * @param line pointer to a line object - * @return true: y inversion is enabled, false: disabled - */ bool lv_line_get_y_invert(const lv_obj_t * obj) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); @@ -162,16 +138,7 @@ static void lv_line_destructor(lv_obj_t * obj) { } -/** - * Handle the drawing related tasks of the lines - * @param line pointer to an object - * @param clip_area the object will be drawn only in this area - * @param mode LV_DRAW_COVER_CHK: only check if the object fully covers the 'mask_p' area - * (return 'true' if yes) - * LV_DRAW_DRAW: draw the object (always return 'true') - * LV_DRAW_DRAW_POST: drawing after every children are drawn - * @param return an element of `lv_draw_res_t` - */ + static lv_draw_res_t lv_line_draw(lv_obj_t * obj, const lv_area_t * clip_area, lv_draw_mode_t mode) { /*A line never covers an area*/ @@ -219,12 +186,6 @@ static lv_draw_res_t lv_line_draw(lv_obj_t * obj, const lv_area_t * clip_area, l return LV_DRAW_RES_OK; } -/** - * Signal function of the line - * @param line pointer to a line object - * @param sign a signal type from lv_signal_t enum - * @return LV_RES_OK: the object is not deleted in the function; LV_RES_INV: the object is deleted - */ static lv_res_t lv_line_signal(lv_obj_t * obj, lv_signal_t sign, void * param) { lv_res_t res; diff --git a/src/lv_widgets/lv_line.h b/src/lv_widgets/lv_line.h index 3acd7f561..a99ce68ca 100644 --- a/src/lv_widgets/lv_line.h +++ b/src/lv_widgets/lv_line.h @@ -30,9 +30,9 @@ extern "C" { /*Data of line*/ typedef struct { lv_obj_t obj; - const lv_point_t * point_array; /*Pointer to an array with the points of the line*/ - uint16_t point_num; /*Number of points in 'point_array' */ - uint8_t y_inv : 1; /*1: y == 0 will be on the bottom*/ + const lv_point_t * point_array; /**< Pointer to an array with the points of the line*/ + uint16_t point_num; /**< Number of points in 'point_array' */ + uint8_t y_inv : 1; /**< 1: y == 0 will be on the bottom*/ } lv_line_t; extern const lv_obj_class_t lv_line; @@ -46,7 +46,7 @@ extern const lv_obj_class_t lv_line; * @param par pointer to an object, it will be the parent of the new line * @return pointer to the created line */ -lv_obj_t * lv_line_create(lv_obj_t * par, const lv_obj_t * copy); +lv_obj_t * lv_line_create(lv_obj_t * parent, const lv_obj_t * copy); /*===================== * Setter functions @@ -54,25 +54,20 @@ lv_obj_t * lv_line_create(lv_obj_t * par, const lv_obj_t * copy); /** * Set an array of points. The line object will connect these points. - * @param line pointer to a line object - * @param point_a an array of points. Only the address is saved, - * so the array can NOT be a local variable which will be destroyed - * @param point_num number of points in 'point_a' + * @param obj pointer to a line object + * @param points an array of points. Only the address is saved, so the array needs to be alive while the line exists + * @param point_num number of points in 'point_a' */ -void lv_line_set_points(lv_obj_t * line, const lv_point_t point_a[], uint16_t point_num); +void lv_line_set_points(lv_obj_t * obj, const lv_point_t points[], uint16_t point_num); /** * Enable (or disable) the y coordinate inversion. * If enabled then y will be subtracted from the height of the object, - * therefore the y=0 coordinate will be on the bottom. - * @param line pointer to a line object - * @param en true: enable the y inversion, false:disable the y inversion + * therefore the y = 0 coordinate will be on the bottom. + * @param obj pointer to a line object + * @param en true: enable the y inversion, false:disable the y inversion */ -void lv_line_set_y_invert(lv_obj_t * line, bool en); - -#define lv_line_set_y_inv \ - lv_line_set_y_invert /*The name was inconsistent. In v.6.0 only `lv_line_set_y_invert`will \ -work */ +void lv_line_set_y_invert(lv_obj_t * obj, bool en); /*===================== * Getter functions @@ -80,10 +75,10 @@ work */ /** * Get the y inversion attribute - * @param line pointer to a line object - * @return true: y inversion is enabled, false: disabled + * @param obj pointer to a line object + * @return true: y inversion is enabled, false: disabled */ -bool lv_line_get_y_invert(const lv_obj_t * line); +bool lv_line_get_y_invert(const lv_obj_t * obj); /********************** * MACROS diff --git a/src/lv_widgets/lv_meter.c b/src/lv_widgets/lv_meter.c index 30502c6b8..d51e16417 100644 --- a/src/lv_widgets/lv_meter.c +++ b/src/lv_widgets/lv_meter.c @@ -572,7 +572,7 @@ static void draw_lines_and_labels(lv_obj_t * obj, const lv_area_t * clip_area, c lv_event_send(obj, LV_EVENT_DRAW_PART_BEGIN, &hook_dsc); lv_point_t label_size; - _lv_txt_get_size(&label_size, hook_dsc.text, label_dsc.font, label_dsc.letter_space, label_dsc.line_space, + lv_txt_get_size(&label_size, hook_dsc.text, label_dsc.font, label_dsc.letter_space, label_dsc.line_space, LV_COORD_MAX, LV_TEXT_FLAG_NONE); lv_area_t label_cord; diff --git a/src/lv_widgets/lv_roller.c b/src/lv_widgets/lv_roller.c index 5b9845209..c85eece9c 100644 --- a/src/lv_widgets/lv_roller.c +++ b/src/lv_widgets/lv_roller.c @@ -332,9 +332,6 @@ static void lv_roller_destructor(lv_obj_t * obj) // bar->class_p->base_p->destructor(obj); } -/********************** - * STATIC FUNCTIONS - **********************/ static void lv_roller_label_constructor(lv_obj_t * obj, lv_obj_t * parent, const lv_obj_t * copy) { lv_label.constructor(obj, parent, copy); @@ -400,18 +397,10 @@ static lv_draw_res_t lv_roller_draw(lv_obj_t * obj, const lv_area_t * clip_area, area_ok = _lv_area_intersect(&mask_sel, clip_area, &rect_area); if(area_ok) { lv_obj_t * label = get_label(obj); - lv_text_align_t label_align = lv_obj_get_style_text_align(label, LV_PART_MAIN); - - if(LV_TEXT_ALIGN_CENTER == label_align) { - label_dsc.flag |= LV_TEXT_FLAG_CENTER; - } - else if(LV_TEXT_ALIGN_RIGHT == label_align) { - label_dsc.flag |= LV_TEXT_FLAG_RIGHT; - } /*Get the size of the "selected text"*/ lv_point_t res_p; - _lv_txt_get_size(&res_p, lv_label_get_text(label), label_dsc.font, label_dsc.letter_space, label_dsc.line_space, + lv_txt_get_size(&res_p, lv_label_get_text(label), label_dsc.font, label_dsc.letter_space, label_dsc.line_space, lv_obj_get_width(obj), LV_TEXT_FLAG_EXPAND); /*Move the selected label proportionally with the background label*/ @@ -819,7 +808,7 @@ static lv_coord_t get_selected_label_width(const lv_obj_t * obj) lv_coord_t letter_space = lv_obj_get_style_text_letter_space(obj, LV_PART_SELECTED); const char * txt = lv_label_get_text(label); lv_point_t size; - _lv_txt_get_size(&size, txt, font, letter_space, 0, LV_COORD_MAX, LV_TEXT_FLAG_NONE); + lv_txt_get_size(&size, txt, font, letter_space, 0, LV_COORD_MAX, LV_TEXT_FLAG_NONE); return size.x; } diff --git a/src/lv_widgets/lv_roller.h b/src/lv_widgets/lv_roller.h index 01bddf72d..f7130202c 100644 --- a/src/lv_widgets/lv_roller.h +++ b/src/lv_widgets/lv_roller.h @@ -38,9 +38,9 @@ typedef uint8_t lv_roller_mode_t; typedef struct { lv_obj_t obj; - uint16_t option_cnt; /*Number of options*/ - uint16_t sel_opt_id; /*Index of the current option*/ - uint16_t sel_opt_id_ori; /*Store the original index on focus*/ + uint16_t option_cnt; /**< Number of options*/ + uint16_t sel_opt_id; /**< Index of the current option*/ + uint16_t sel_opt_id_ori; /**< Store the original index on focus*/ lv_roller_mode_t mode : 1; uint32_t moved : 1; }lv_roller_t; @@ -53,12 +53,13 @@ extern const lv_obj_class_t lv_roller; **********************/ /** - * Create a roller object - * @param par pointer to an object, it will be the parent of the new roller - * @param copy pointer to a roller object, if not NULL then the new object will be copied from it - * @return pointer to the created roller + * Create a roller objects + * @param parent pointer to an object, it will be the parent of the new roller + * @param copy DEPRECATED, will be removed in v9. + * Pointer to an other roller to copy. + * @return pointer to the created roller */ -lv_obj_t * lv_roller_create(lv_obj_t * par, const lv_obj_t * copy); +lv_obj_t * lv_roller_create(lv_obj_t * parent, const lv_obj_t * copy); /*===================== * Setter functions @@ -66,58 +67,60 @@ lv_obj_t * lv_roller_create(lv_obj_t * par, const lv_obj_t * copy); /** * Set the options on a roller - * @param roller pointer to roller object - * @param options a string with '\n' separated options. E.g. "One\nTwo\nThree" - * @param mode `LV_ROLLER_MODE_NORMAL` or `LV_ROLLER_MODE_INFINITE` + * @param obj pointer to roller object + * @param options a string with '\n' separated options. E.g. "One\nTwo\nThree" + * @param mode `LV_ROLLER_MODE_NORMAL` or `LV_ROLLER_MODE_INFINITE` */ -void lv_roller_set_options(lv_obj_t * roller, const char * options, lv_roller_mode_t mode); +void lv_roller_set_options(lv_obj_t * obj, const char * options, lv_roller_mode_t mode); /** * Set the selected option - * @param roller pointer to a roller object - * @param sel_opt id of the selected option (0 ... number of option - 1); - * @param anim LV_ANIM_ON: set with animation; LV_ANIM_OFF set immediately + * @param obj pointer to a roller object + * @param sel_opt index of the selected option (0 ... number of option - 1); + * @param anim_en LV_ANIM_ON: set with animation; LV_ANOM_OFF set immediately */ -void lv_roller_set_selected(lv_obj_t * roller, uint16_t sel_opt, lv_anim_enable_t anim); +void lv_roller_set_selected(lv_obj_t * obj, uint16_t sel_opt, lv_anim_enable_t anim); /** * 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 + * @param obj 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); +void lv_roller_set_visible_row_count(lv_obj_t * obj, uint8_t row_cnt); /*===================== * Getter functions *====================*/ -/** - * Get the id of the selected option - * @param roller pointer to a roller object - * @return id of the selected option (0 ... number of option - 1); - */ -uint16_t lv_roller_get_selected(const lv_obj_t * roller); /** - * Get the total number of options - * @param roller pointer to a roller object - * @return the total number of options in the list + * Get the index of the selected option + * @param obj pointer to a roller object + * @return index of the selected option (0 ... number of option - 1); */ -uint16_t lv_roller_get_option_cnt(const lv_obj_t * roller); +uint16_t lv_roller_get_selected(const lv_obj_t * obj); /** - * Get the current selected option as a string - * @param roller pointer to roller object - * @param buf pointer to an array to store the string - * @param buf_size size of `buf` in bytes. 0: to ignore it. + * Get the current selected option as a string. + * @param obj pointer to ddlist object + * @param buf pointer to an array to store the string + * @param buf_size size of `buf` in bytes. 0: to ignore it. */ -void lv_roller_get_selected_str(const lv_obj_t * roller, char * buf, uint32_t buf_size); +void lv_roller_get_selected_str(const lv_obj_t * obj, char * buf, uint32_t buf_size); + /** * Get the options of a roller - * @param roller pointer to roller object - * @return the options separated by '\n'-s (E.g. "Option1\nOption2\nOption3") + * @param obj pointer to roller object + * @return the options separated by '\n'-s (E.g. "Option1\nOption2\nOption3") */ -const char * lv_roller_get_options(const lv_obj_t * roller); +const char * lv_roller_get_options(const lv_obj_t * obj); + +/** + * Get the total number of options + * @param obj pointer to a roller object + * @return the total number of options + */ +uint16_t lv_roller_get_option_cnt(const lv_obj_t * obj); /********************** * MACROS diff --git a/src/lv_widgets/lv_slider.c b/src/lv_widgets/lv_slider.c index ae56decb5..a9188a295 100644 --- a/src/lv_widgets/lv_slider.c +++ b/src/lv_widgets/lv_slider.c @@ -61,32 +61,12 @@ const lv_obj_class_t lv_slider = { * GLOBAL FUNCTIONS **********************/ -/** - * Create a slider objects - * @param parent pointer to an object, it will be the parent of the new slider - * @param copy DEPRECATED, will be removed in v9. - * Pointer to an other slider to copy. - * @return pointer to the created slider - */ lv_obj_t * lv_slider_create(lv_obj_t * parent, const lv_obj_t * copy) { return lv_obj_create_from_class(&lv_slider, parent, copy); } -/*===================== - * Setter functions - *====================*/ - -/*===================== - * Getter functions - *====================*/ - -/** - * Give the slider is being dragged or not - * @param slider pointer to a slider object - * @return true: drag in progress false: not dragged - */ bool lv_slider_is_dragged(const lv_obj_t * obj) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); @@ -132,16 +112,6 @@ static void lv_slider_destructor(lv_obj_t * obj) // slider->class_p->base_p->destructor(obj); } -/** - * Handle the drawing related tasks of the sliders - * @param slider pointer to an object - * @param clip_area the object will be drawn only in this area - * @param mode LV_DRAW_COVER_CHK: only check if the object fully covers the 'mask_p' area - * (return 'true' if yes) - * LV_DRAW_DRAW: draw the object (always return 'true') - * LV_DRAW_DRAW_POST: drawing after every children are drawn - * @param return an element of `lv_draw_res_t` - */ static lv_draw_res_t lv_slider_draw(lv_obj_t * obj, const lv_area_t * clip_area, lv_draw_mode_t mode) { /*Return false if the object is not covers the mask_p area*/ @@ -165,13 +135,6 @@ static lv_draw_res_t lv_slider_draw(lv_obj_t * obj, const lv_area_t * clip_area, return LV_DRAW_RES_OK; } -/** - * Signal function of the slider - * @param slider pointer to a slider 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_slider_signal(lv_obj_t * obj, lv_signal_t sign, void * param) { lv_res_t res; @@ -195,10 +158,8 @@ static lv_res_t lv_slider_signal(lv_obj_t * obj, lv_signal_t sign, void * param) info->result = _lv_area_is_point_on(&slider->left_knob_area, info->point, 0); } } - - lv_point_t p; - - if(sign == LV_SIGNAL_PRESSED) { + else if(sign == LV_SIGNAL_PRESSED) { + lv_point_t p; slider->dragging = true; if(type == LV_SLIDER_TYPE_NORMAL || type == LV_SLIDER_TYPE_SYMMETRICAL) { slider->value_to_set = &slider->bar.cur_value; @@ -250,6 +211,7 @@ static lv_res_t lv_slider_signal(lv_obj_t * obj, lv_signal_t sign, void * param) else if(sign == LV_SIGNAL_PRESSING && slider->value_to_set != NULL) { if(lv_indev_get_type(param) != LV_INDEV_TYPE_POINTER) return res; + lv_point_t p; lv_indev_get_point(param, &p); lv_bidi_dir_t base_dir = lv_obj_get_base_dir(obj); @@ -380,7 +342,7 @@ static lv_res_t lv_slider_signal(lv_obj_t * obj, lv_signal_t sign, void * param) return res; } -void draw_knob(lv_obj_t * obj, const lv_area_t * clip_area) +static void draw_knob(lv_obj_t * obj, const lv_area_t * clip_area) { lv_slider_t * slider = (lv_slider_t *)obj; lv_bidi_dir_t base_dir = lv_obj_get_base_dir(obj); diff --git a/src/lv_widgets/lv_slider.h b/src/lv_widgets/lv_slider.h index 9481479d8..e7faeb85b 100644 --- a/src/lv_widgets/lv_slider.h +++ b/src/lv_widgets/lv_slider.h @@ -34,9 +34,9 @@ extern "C" { **********************/ enum { - LV_SLIDER_TYPE_NORMAL, - LV_SLIDER_TYPE_SYMMETRICAL, - LV_SLIDER_TYPE_RANGE + LV_SLIDER_TYPE_NORMAL = LV_BAR_TYPE_NORMAL, + LV_SLIDER_TYPE_SYMMETRICAL = LV_BAR_TYPE_SYMMETRICAL, + LV_SLIDER_TYPE_RANGE = LV_BAR_TYPE_RANGE }; typedef uint8_t lv_slider_type_t; @@ -57,10 +57,10 @@ extern const lv_obj_class_t lv_slider; /** * Create a slider objects - * @param parent pointer to an object, it will be the parent of the new slider - * @param copy DEPRECATED, will be removed in v9. - * Pointer to an other slider to copy. - * @return pointer to the created slider + * @param parent pointer to an object, it will be the parent of the new slider + * @param copy DEPRECATED, will be removed in v9. + * Pointer to an other slider to copy. + * @return pointer to the created slider */ lv_obj_t * lv_slider_create(lv_obj_t * parent, const lv_obj_t * copy); @@ -70,51 +70,45 @@ lv_obj_t * lv_slider_create(lv_obj_t * parent, const lv_obj_t * copy); /** * Set a new value on the slider - * @param slider pointer to a slider object - * @param value new value - * @param anim LV_ANIM_ON: set the value with an animation; LV_ANIM_OFF: change the value immediately + * @param obj pointer to a slider object + * @param value the new value + * @param anim LV_ANIM_ON: set the value with an animation; LV_ANIM_OFF: change the value immediately */ -static inline void lv_slider_set_value(lv_obj_t * slider, int16_t value, lv_anim_enable_t anim) +static inline void lv_slider_set_value(lv_obj_t * obj, int16_t value, lv_anim_enable_t anim) { - lv_bar_set_value(slider, value, anim); + lv_bar_set_value(obj, value, anim); } /** * Set a new value for the left knob of a slider - * @param slider pointer to a slider object - * @param left_value new value - * @param anim LV_ANIM_ON: set the value with an animation; LV_ANIM_OFF: change the value immediately + * @param obj pointer to a slider object + * @param value new value + * @param anim LV_ANIM_ON: set the value with an animation; LV_ANIM_OFF: change the value immediately */ -static inline void lv_slider_set_left_value(lv_obj_t * slider, int16_t left_value, lv_anim_enable_t anim) +static inline void lv_slider_set_left_value(lv_obj_t * obj, int16_t value, lv_anim_enable_t anim) { - lv_bar_set_start_value(slider, left_value, anim); + lv_bar_set_start_value(obj, value, anim); } /** * Set minimum and the maximum values of a bar - * @param slider pointer to the slider object - * @param min minimum value - * @param max maximum value + * @param obj pointer to the slider object + * @param min minimum value + * @param max maximum value */ -static inline void lv_slider_set_range(lv_obj_t * slider, int16_t min, int16_t max) +static inline void lv_slider_set_range(lv_obj_t * obj, int16_t min, int16_t max) { - lv_bar_set_range(slider, min, max); + lv_bar_set_range(obj, min, max); } /** - * Make the slider symmetric to zero. The indicator will grow from zero instead of the minimum - * position. - * @param slider pointer to a slider object - * @param en true: enable disable symmetric behavior; false: disable + * Set the type of slider. + * @param obj pointer to a slider object + * @param en the type of the slider. See ::lv_slider_type_t */ -static inline void lv_slider_set_type(lv_obj_t * slider, lv_slider_type_t type) +static inline void lv_slider_set_type(lv_obj_t * obj, lv_slider_type_t type) { - if(type == LV_SLIDER_TYPE_NORMAL) - lv_bar_set_type(slider, LV_BAR_TYPE_NORMAL); - else if(type == LV_SLIDER_TYPE_SYMMETRICAL) - lv_bar_set_type(slider, LV_BAR_TYPE_SYMMETRICAL); - else if(type == LV_SLIDER_TYPE_RANGE) - lv_bar_set_type(slider, LV_BAR_TYPE_CUSTOM); + lv_bar_set_type(obj, (lv_bar_type_t)type); } /*===================== @@ -123,62 +117,61 @@ static inline void lv_slider_set_type(lv_obj_t * slider, lv_slider_type_t type) /** * Get the value of the main knob of a slider - * @param slider pointer to a slider object - * @return the value of the main knob of the slider + * @param obj pointer to a slider object + * @return the value of the main knob of the slider */ -static inline int16_t lv_slider_get_value(const lv_obj_t * slider) +static inline int16_t lv_slider_get_value(const lv_obj_t * obj) { - return lv_bar_get_value(slider); + return lv_bar_get_value(obj); } /** * Get the value of the left knob of a slider - * @param slider pointer to a slider object - * @return the value of the left knob of the slider + * @param obj pointer to a slider object + * @return the value of the left knob of the slider */ -static inline int16_t lv_slider_get_left_value(const lv_obj_t * slider) +static inline int16_t lv_slider_get_left_value(const lv_obj_t * obj) { - return lv_bar_get_start_value(slider); + return lv_bar_get_start_value(obj); } /** * Get the minimum value of a slider - * @param slider pointer to a slider object - * @return the minimum value of the slider + * @param obj pointer to a slider object + * @return the minimum value of the slider */ -static inline int16_t lv_slider_get_min_value(const lv_obj_t * slider) +static inline int16_t lv_slider_get_min_value(const lv_obj_t * obj) { - return lv_bar_get_min_value(slider); + return lv_bar_get_min_value(obj); } /** * Get the maximum value of a slider - * @param slider pointer to a slider object - * @return the maximum value of the slider + * @param obj pointer to a slider object + * @return the maximum value of the slider */ -static inline int16_t lv_slider_get_max_value(const lv_obj_t * slider) +static inline int16_t lv_slider_get_max_value(const lv_obj_t * obj) { - return lv_bar_get_max_value(slider); + return lv_bar_get_max_value(obj); } /** * Give the slider is being dragged or not - * @param slider pointer to a slider object - * @return true: drag in progress false: not dragged + * @param obj pointer to a slider object + * @return true: drag in progress false: not dragged */ -bool lv_slider_is_dragged(const lv_obj_t * slider); - +bool lv_slider_is_dragged(const lv_obj_t * obj); /** - * Get whether the slider is symmetric or not. - * @param slider pointer to a bar object - * @return true: symmetric is enabled; false: disable + * Get the type of the slider. + * @param obj pointer to a bar object + * @return see ::lv_slider_type_t */ static inline lv_slider_type_t lv_slider_get_type(lv_obj_t * slider) { lv_bar_type_t type = lv_bar_get_type(slider); if(type == LV_BAR_TYPE_SYMMETRICAL) return LV_SLIDER_TYPE_SYMMETRICAL; - else if(type == LV_BAR_TYPE_CUSTOM)return LV_SLIDER_TYPE_RANGE; + else if(type == LV_BAR_TYPE_RANGE) return LV_SLIDER_TYPE_RANGE; else return LV_SLIDER_TYPE_NORMAL; } diff --git a/src/lv_widgets/lv_table.c b/src/lv_widgets/lv_table.c index f6e404335..4250b1942 100644 --- a/src/lv_widgets/lv_table.c +++ b/src/lv_widgets/lv_table.c @@ -105,7 +105,7 @@ void lv_table_set_cell_value(lv_obj_t * obj, uint16_t row, uint16_t col, const c format.s.crop = 0; } -#if LV_USE_ARABIC_PERSIAN_CHARS + #if LV_USE_ARABIC_PERSIAN_CHARS /*Get the size of the Arabic text and process it*/ size_t len_ap = _lv_txt_ap_calc_bytes_cnt(txt); table->cell_data[cell] = lv_mem_realloc(table->cell_data[cell], len_ap + 1); @@ -116,7 +116,6 @@ void lv_table_set_cell_value(lv_obj_t * obj, uint16_t row, uint16_t col, const c #else table->cell_data[cell] = lv_mem_realloc(table->cell_data[cell], strlen(txt) + 2); /*+1: trailing '\0; +1: format byte*/ LV_ASSERT_MEM(table->cell_data[cell]); - if(table->cell_data[cell] == NULL) return; strcpy(table->cell_data[cell] + 1, txt); /*+1 to skip the format byte*/ #endif @@ -257,22 +256,36 @@ void lv_table_set_col_cnt(lv_obj_t * obj, uint16_t col_cnt) LV_ASSERT_MEM(table->col_w); if(table->col_w == NULL) return; - table->cell_data = lv_mem_realloc(table->cell_data, table->row_cnt * table->col_cnt * sizeof(char *)); - LV_ASSERT_MEM(table->cell_data); - if(table->cell_data == NULL) return; + char ** new_cell_data = lv_mem_alloc(table->row_cnt * table->col_cnt * sizeof(char *)); + LV_ASSERT_MEM(new_cell_data); + if(new_cell_data == NULL) return; + uint32_t new_cell_cnt = table->col_cnt * table->row_cnt; + lv_memset_00(new_cell_data, new_cell_cnt * sizeof(table->cell_data[0])); /*Initialize the new fields*/ if(old_col_cnt < col_cnt) { - uint32_t old_cell_cnt = old_col_cnt * table->row_cnt; - uint32_t new_cell_cnt = table->col_cnt * table->row_cnt; - lv_memset_00(&table->cell_data[old_cell_cnt], (new_cell_cnt - old_cell_cnt) * sizeof(table->cell_data[0])); - uint32_t col; - for(col = old_cell_cnt; col < new_cell_cnt; col++) { + for(col = old_col_cnt; col < col_cnt; col++) { table->col_w[col] = LV_DPI; } } + /*The new column(s) messes up the mapping of `cell_data`*/ + uint32_t old_col_start; + uint32_t new_col_start; + uint32_t min_col_cnt = LV_MIN(old_col_cnt, col_cnt); + uint32_t row; + for(row = 0; row < table->row_cnt; row++) { + old_col_start = row * old_col_cnt; + new_col_start = row * col_cnt; + + lv_memcpy_small(&new_cell_data[new_col_start], &table->cell_data[old_col_start], sizeof(new_cell_data[0]) * min_col_cnt); + } + + lv_mem_free(table->cell_data); + table->cell_data = new_cell_data; + + refr_size(obj) ; } @@ -571,7 +584,7 @@ static void lv_table_constructor(lv_obj_t * obj, lv_obj_t * parent, const lv_obj table->col_w = lv_mem_alloc(table->col_cnt * sizeof(table->col_w[0])); table->row_h = lv_mem_alloc(table->row_cnt * sizeof(table->row_h[0])); table->col_w[0] = LV_DPI; - table->row_h[0] = LV_DPI; /*It will be overwritten when the theme is applied*/ + table->row_h[0] = LV_DPI; table->cell_data = lv_mem_realloc(table->cell_data, table->row_cnt * table->col_cnt * sizeof(char *)); table->cell_data[0] = NULL; @@ -754,11 +767,10 @@ static lv_draw_res_t lv_table_draw(lv_obj_t * obj, const lv_area_t * clip_area, if(format.s.crop == 0) txt_flags = LV_TEXT_FLAG_NONE; else txt_flags = LV_TEXT_FLAG_EXPAND; - _lv_txt_get_size(&txt_size, table->cell_data[cell] + 1, label_dsc_base.font, - label_dsc_base.letter_space, label_dsc_base.line_space, + lv_txt_get_size(&txt_size, table->cell_data[cell] + 1, label_dsc_base.font, + label_dsc_act.letter_space, label_dsc_act.line_space, lv_area_get_width(&txt_area), txt_flags); - label_dsc_base.flag = 0; /*Align the content to the middle if not cropped*/ if(format.s.crop == 0) { txt_area.y1 = cell_area.y1 + h_row / 2 - txt_size.y / 2; @@ -892,7 +904,7 @@ static lv_coord_t get_row_height(lv_obj_t * obj, uint16_t row_id, const lv_font_ else { txt_w -= cell_left + cell_right; - _lv_txt_get_size(&txt_size, table->cell_data[cell] + 1, font, + lv_txt_get_size(&txt_size, table->cell_data[cell] + 1, font, letter_space, line_space, txt_w, LV_TEXT_FLAG_NONE); h_max = LV_MAX(txt_size.y + cell_top + cell_bottom, h_max); diff --git a/src/lv_widgets/lv_table.h b/src/lv_widgets/lv_table.h index ab80469a1..cf707d3fb 100644 --- a/src/lv_widgets/lv_table.h +++ b/src/lv_widgets/lv_table.h @@ -65,12 +65,13 @@ extern const lv_obj_class_t lv_table; **********************/ /** - * Create a table object - * @param par pointer to an object, it will be the parent of the new table - * @param copy pointer to a table object, if not NULL then the new object will be copied from it + * Create a table objects + * @param parent pointer to an object, it will be the parent of the new table + * @param copy DEPRECATED, will be removed in v9. + * Pointer to an other table to copy. * @return pointer to the created table */ -lv_obj_t * lv_table_create(lv_obj_t * par, const lv_obj_t * copy); +lv_obj_t * lv_table_create(lv_obj_t * parent, const lv_obj_t * copy); /*===================== * Setter functions @@ -78,62 +79,62 @@ lv_obj_t * lv_table_create(lv_obj_t * par, const lv_obj_t * copy); /** * Set the value of a cell. - * @param table pointer to a Table object - * @param row id of the row [0 .. row_cnt -1] - * @param col id of the column [0 .. col_cnt -1] - * @param txt text to display in the cell. It will be copied and saved so this variable is not - * required after this function call. + * @param obj pointer to a table object + * @param row id of the row [0 .. row_cnt -1] + * @param col id of the column [0 .. col_cnt -1] + * @param txt text to display in the cell. + * It will be copied and saved so this variable is not required after this function call. */ -void lv_table_set_cell_value(lv_obj_t * table, uint16_t row, uint16_t col, const char * txt); +void lv_table_set_cell_value(lv_obj_t * obj, uint16_t row, uint16_t col, const char * txt); /** * Set the value of a cell. Memory will be allocated to store the text by the table. - * @param table pointer to a Table object - * @param row id of the row [0 .. row_cnt -1] - * @param col id of the column [0 .. col_cnt -1] - * @param fmt `printf`-like format + * @param obj pointer to a table object + * @param row index of the row [0 .. row_cnt -1] + * @param col index of the column [0 .. col_cnt -1] + * @param fmt ` printf`-like format */ -void lv_table_set_cell_value_fmt(lv_obj_t * table, uint16_t row, uint16_t col, const char * fmt, ...); +void lv_table_set_cell_value_fmt(lv_obj_t * obj, uint16_t row, uint16_t col, const char * fmt, ...); /** * Set the number of rows - * @param table table pointer to a Table object - * @param row_cnt number of rows + * @param obj table pointer to a table object + * @param row_cnt number of rows */ -void lv_table_set_row_cnt(lv_obj_t * table, uint16_t row_cnt); +void lv_table_set_row_cnt(lv_obj_t * obj, uint16_t row_cnt); /** * Set the number of columns - * @param table table pointer to a Table object - * @param col_cnt number of columns. Must be < LV_TABLE_COL_MAX + * @param obj table pointer to a table object + * @param col_cnt number of columns. */ -void lv_table_set_col_cnt(lv_obj_t * table, uint16_t col_cnt); +void lv_table_set_col_cnt(lv_obj_t * obj, uint16_t col_cnt); /** * Set the width of a column - * @param table table pointer to a Table object - * @param col_id id of the column [0 .. LV_TABLE_COL_MAX -1] - * @param w width of the column + * @param obj table pointer to a table object + * @param col_id id of the column [0 .. LV_TABLE_COL_MAX -1] + * @param w width of the column */ -void lv_table_set_col_width(lv_obj_t * table, uint16_t col_id, lv_coord_t w); +void lv_table_set_col_width(lv_obj_t * obj, uint16_t col_id, lv_coord_t w); /** - * Set the cell crop. (Don't adjust the height of the cell according to its content) - * @param table pointer to a Table object - * @param row id of the row [0 .. row_cnt -1] - * @param col id of the column [0 .. col_cnt -1] - * @param crop true: crop the cell content; false: set the cell height to the content. + * Set the cell crop. (Don't adjust the height of the cell according to this cell's content) + * @param obj pointer to a table object + * @param row id of the row [0 .. row_cnt -1] + * @param col id of the column [0 .. col_cnt -1] + * @param crop true: crop the cell content; false: set the cell height to the content. */ -void lv_table_set_cell_crop(lv_obj_t * table, uint16_t row, uint16_t col, bool crop); +void lv_table_set_cell_crop(lv_obj_t * obj, uint16_t row, uint16_t col, bool crop); /** * Merge a cell with the right neighbor. The value of the cell to the right won't be displayed. - * @param table table pointer to a Table object - * @param row id of the row [0 .. row_cnt -1] - * @param col id of the column [0 .. col_cnt -1] - * @param en true: merge right; false: don't merge right + * @param obj table pointer to a table object + * @param row index of the row [0 .. row_cnt -1] + * @param col index of the column [0 .. col_cnt -1] + * @param en true: merge right; false: don't merge right */ -void lv_table_set_cell_merge_right(lv_obj_t * table, uint16_t row, uint16_t col, bool en); +void lv_table_set_cell_merge_right(lv_obj_t * obj, uint16_t row, uint16_t col, bool en); /*===================== * Getter functions @@ -141,65 +142,62 @@ void lv_table_set_cell_merge_right(lv_obj_t * table, uint16_t row, uint16_t col, /** * Get the value of a cell. - * @param table pointer to a Table object - * @param row id of the row [0 .. row_cnt -1] - * @param col id of the column [0 .. col_cnt -1] - * @return text in the cell + * @param obj pointer to a table object + * @param row index of the row [0 .. row_cnt -1] + * @param col index of the column [0 .. col_cnt -1] + * @return text of the cell */ -const char * lv_table_get_cell_value(lv_obj_t * table, uint16_t row, uint16_t col); +const char * lv_table_get_cell_value(lv_obj_t * obj, uint16_t row, uint16_t col); /** * Get the number of rows. - * @param table table pointer to a Table object - * @return number of rows. + * @param obj table pointer to a table object + * @return number of rows. */ -uint16_t lv_table_get_row_cnt(lv_obj_t * table); +uint16_t lv_table_get_row_cnt(lv_obj_t * obj); /** * Get the number of columns. - * @param table table pointer to a Table object - * @return number of columns. + * @param obj table pointer to a table object + * @return number of columns. */ -uint16_t lv_table_get_col_cnt(lv_obj_t * table); +uint16_t lv_table_get_col_cnt(lv_obj_t * obj); /** * Get the width of a column - * @param table table pointer to a Table object - * @param col_id id of the column [0 .. LV_TABLE_COL_MAX -1] - * @return width of the column + * @param obj table pointer to a table object + * @param col_id id of the column [0 .. LV_TABLE_COL_MAX -1] + * @return width of the column */ -lv_coord_t lv_table_get_col_width(lv_obj_t * table, uint16_t col_id); +lv_coord_t lv_table_get_col_width(lv_obj_t * obj, uint16_t col_id); /** * Get the crop property of a cell - * @param table pointer to a Table object - * @param row id of the row [0 .. row_cnt -1] - * @param col id of the column [0 .. col_cnt -1] - * @return true: text crop enabled; false: disabled + * @param obj pointer to a table object + * @param row index of the row [0 .. row_cnt -1] + * @param col index of the column [0 .. col_cnt -1] + * @return true: text crop enabled; false: disabled */ -bool lv_table_get_cell_crop(lv_obj_t * table, uint16_t row, uint16_t col); +bool lv_table_get_cell_crop(lv_obj_t * obj, uint16_t row, uint16_t col); /** * Get the cell merge attribute. - * @param table table pointer to a Table object - * @param row id of the row [0 .. row_cnt -1] - * @param col id of the column [0 .. col_cnt -1] - * @return true: merge right; false: don't merge right + * @param obj pointer to a table object + * @param row index of the row [0 .. row_cnt -1] + * @param col index of the column [0 .. col_cnt -1] + * @return true: merge right; false: don't merge right */ -bool lv_table_get_cell_merge_right(lv_obj_t * table, uint16_t row, uint16_t col); +bool lv_table_get_cell_merge_right(lv_obj_t * obj, uint16_t row, uint16_t col); /** * Get the last pressed or being pressed cell - * @param table pointer to a table object - * @param row pointer to variable to store the pressed row - * @param col pointer to variable to store the pressed column - * @return LV_RES_OK: a valid pressed cell was found, LV_RES_INV: no valid cell is pressed + * @param obj pointer to a table object + * @param row pointer to variable to store the pressed row + * @param col pointer to variable to store the pressed column + * @return LV_RES_OK: a valid pressed cell was found, LV_RES_INV: no valid cell is pressed */ -lv_res_t lv_table_get_pressed_cell(lv_obj_t * table, uint16_t * row, uint16_t * col); +lv_res_t lv_table_get_pressed_cell(lv_obj_t * obj, uint16_t * row, uint16_t * col); -/*===================== - * Other functions - *====================*/ /********************** * MACROS