diff --git a/lv_objx/lv_btnm.c b/lv_objx/lv_btnm.c index aa19d5097..4ec1ef5ee 100644 --- a/lv_objx/lv_btnm.c +++ b/lv_objx/lv_btnm.c @@ -353,14 +353,21 @@ void lv_btnm_set_tgl(lv_obj_t * btnm, bool en, uint16_t id) /** * Set the styles of the buttons of the button matrix * @param btnm pointer to a button matrix object - * @param state style in this state (LV_BTN_STATE_PR or LV_BTN_STATE_REL) - * @param style pointer to style + * @param rel pointer to a style for releases state + * @param pr pointer to a style for pressed state + * @param trel pointer to a style for toggled releases state + * @param tpr pointer to a style for toggled pressed state + * @param ina pointer to a style for inactive state */ -void lv_btnm_set_styles_btn(lv_obj_t * btnm, lv_style_t * rel, lv_style_t * pr) +void lv_btnm_set_styles_btn(lv_obj_t * btnm, lv_style_t * rel, lv_style_t * pr, + lv_style_t * trel, lv_style_t * tpr, lv_style_t * ina) { lv_btnm_ext_t * ext = lv_obj_get_ext(btnm); ext->style_btn_rel = rel; ext->style_btn_pr = pr; + ext->style_btn_trel = trel; + ext->style_btn_tpr = tpr; + ext->style_btn_ina = ina; lv_obj_inv(btnm); diff --git a/lv_objx/lv_btnm.h b/lv_objx/lv_btnm.h index d43a63d93..652a437c3 100644 --- a/lv_objx/lv_btnm.h +++ b/lv_objx/lv_btnm.h @@ -47,8 +47,9 @@ typedef struct lv_btnm_callback_t cb; /*A function to call when a button is releases*/ lv_style_t * style_btn_rel; /*Style of the released buttons*/ lv_style_t * style_btn_pr; /*Style of the pressed buttons*/ - lv_style_t * style_btn_trel; /*Style of the released buttons*/ - lv_style_t * style_btn_tpr; /*Style of the pressed buttons*/ + lv_style_t * style_btn_trel; /*Style of the toggled released buttons*/ + lv_style_t * style_btn_tpr; /*Style of the toggled pressed buttons*/ + lv_style_t * style_btn_ina; /*Style of the inactive buttons*/ uint8_t tgl :1; /*Enable toggling*/ }lv_btnm_ext_t; @@ -100,13 +101,18 @@ void lv_btnm_set_action(lv_obj_t * btnm, lv_btnm_callback_t cb); */ void lv_btnm_set_tgl(lv_obj_t * btnm, bool en, uint16_t id); + /** - * Set the styles of the buttons of the button matrox + * Set the styles of the buttons of the button matrix * @param btnm pointer to a button matrix object - * @param state style in this state (LV_BTN_STATE_PR or LV_BTN_STATE_REL) - * @param style pointer to style + * @param rel pointer to a style for releases state + * @param pr pointer to a style for pressed state + * @param trel pointer to a style for toggled releases state + * @param tpr pointer to a style for toggled pressed state + * @param ina pointer to a style for inactive state */ -void lv_btnm_set_styles_btn(lv_obj_t * btnm, lv_style_t * rel, lv_style_t * pr); +void lv_btnm_set_styles_btn(lv_obj_t * btnm, lv_style_t * rel, lv_style_t * pr, + lv_style_t * trel, lv_style_t * tpr, lv_style_t * ina); /** * Get the current map of a button matrix diff --git a/lv_objx/lv_ddlist.c b/lv_objx/lv_ddlist.c index 80d57d85b..ce50d4c1b 100644 --- a/lv_objx/lv_ddlist.c +++ b/lv_objx/lv_ddlist.c @@ -195,8 +195,8 @@ void lv_ddlist_set_options(lv_obj_t * ddlist, const char ** options) lv_label_set_text(ext->opt_label, ""); uint16_t i = 0; while(options[i][0] != '\0') { - lv_label_append_text(ext->opt_label, options[i]); - if(options[i + 1][0] != '\0') lv_label_append_text(ext->opt_label, "\n"); + lv_label_ins_text(ext->opt_label, LV_LABEL_POS_LAST, options[i]); + if(options[i + 1][0] != '\0') lv_label_ins_text(ext->opt_label, LV_LABEL_POS_LAST, "\n"); i++; } @@ -235,11 +235,13 @@ void lv_ddlist_set_selected(lv_obj_t * ddlist, uint16_t sel_opt) { lv_ddlist_ext_t * ext = lv_obj_get_ext(ddlist); - ext->sel_opt = sel_opt; + ext->sel_opt = sel_opt < ext->num_opt ? sel_opt : ext->num_opt - 1; /*Move the list to show the current option*/ if(ext->opened == 0) { lv_ddlist_pos_act_option(ddlist); + } else { + lv_obj_inv(ddlist); } } @@ -287,6 +289,20 @@ void lv_ddlist_set_style_select(lv_obj_t * ddlist, lv_style_t * style) lv_ddlist_ext_t * ext = lv_obj_get_ext(ddlist); ext->style_sel = style; +} + +/** + * Open or Collapse the drop down list + * @param ddlist pointer to drop down list object + * @param state true: open; false: collapse + * @param anim true: use animations; false: not use animations + */ +void lv_ddlist_open(lv_obj_t * ddlist, bool state, bool anim) +{ + lv_ddlist_ext_t * ext = lv_obj_get_ext(ddlist); + ext->opened = state ? 1 : 0; + lv_ddlist_refr_size(ddlist, anim ? ext->anim_time : 0); + } /*===================== * Getter functions @@ -525,9 +541,11 @@ static void lv_ddlist_pos_act_option(lv_obj_t * ddlist) cord_t font_h = font_get_height(font) >> FONT_ANTIALIAS; lv_style_t * label_style = lv_obj_get_style(ext->opt_label); lv_obj_t * scrl = lv_page_get_scrl(ddlist); - lv_style_t * style_scrl = lv_obj_get_style(scrl); - lv_obj_set_y(scrl, -(ext->sel_opt * (font_h + label_style->line_space) - label_style->line_space) - style_scrl->hpad); + cord_t h = lv_obj_get_height(ddlist); + cord_t line_y1 = ext->sel_opt * (font_h + label_style->line_space) + ext->opt_label->cords.y1 - scrl->cords.y1; + + lv_obj_set_y(scrl, - line_y1 + (h - font_h) / 2); } diff --git a/lv_objx/lv_ddlist.h b/lv_objx/lv_ddlist.h index 3c9db2923..18ec4930d 100644 --- a/lv_objx/lv_ddlist.h +++ b/lv_objx/lv_ddlist.h @@ -113,6 +113,14 @@ void lv_ddlist_set_auto_size(lv_obj_t * ddlist, bool auto_size); */ void lv_ddlist_set_style_select(lv_obj_t * ddlist, lv_style_t * style); +/** + * Open or Collapse the drop down list + * @param ddlist pointer to drop down list object + * @param state true: open; false: collapse + * @param anim true: use animations; false: not use animations + */ +void lv_ddlist_open(lv_obj_t * ddlist, bool state, bool anim); + /** * Get the options of a drop down list * @param ddlist pointer to drop down list object diff --git a/lv_objx/lv_kb.c b/lv_objx/lv_kb.c index 94ef44b0b..bfff724c4 100644 --- a/lv_objx/lv_kb.c +++ b/lv_objx/lv_kb.c @@ -1,3 +1,4 @@ + /** * @file lv_kb.c * @@ -15,7 +16,6 @@ /********************* * DEFINES *********************/ - /********************** * TYPEDEFS **********************/ @@ -80,7 +80,6 @@ static const char * kb_map_num[] = { lv_obj_t * lv_kb_create(lv_obj_t * par, lv_obj_t * copy) { /*Create the ancestor of keyboard*/ - /*TODO modify it to the ancestor create function */ lv_obj_t * new_kb = lv_btnm_create(par, copy); dm_assert(new_kb); @@ -214,6 +213,7 @@ void lv_kb_set_close_action(lv_obj_t * kb, lv_action_t action) ext->close_action = action; } + /*===================== * Getter functions *====================*/ @@ -362,10 +362,10 @@ static lv_action_res_t lv_app_kb_action(lv_obj_t * kb, uint16_t i) lv_ta_set_cursor_pos(ext->ta, cur + 1); } } else if(strcmp(txt, "Hide") == 0) { - //lv_app_kb_close(false); + if(ext->close_action) ext->close_action(kb, NULL); return LV_ACTION_RES_INV; } else if(strcmp(txt, "Ok") == 0) { - //lv_app_kb_close(true); + if(ext->ok_action) ext->ok_action(kb, NULL); return LV_ACTION_RES_INV; } else { lv_ta_add_text(ext->ta, txt); diff --git a/lv_objx/lv_label.c b/lv_objx/lv_label.c index c68c5eb73..961476bd4 100644 --- a/lv_objx/lv_label.c +++ b/lv_objx/lv_label.c @@ -238,11 +238,16 @@ void lv_label_set_text_static(lv_obj_t * label, const char * text) } /** - * Append a text to the label. The label current label text can not be static. + * Insert a text to the label. The label current label text can not be static. * @param label pointer to label object - * @param text pointe rto the new text + * @param pos character index to insert + * 0: before first char. + * LV_LABEL_POS_LAST: after last char. + * < 0: count from the end + * -1: before the last char. + * @param txt pointer to the text to insert */ -void lv_label_append_text(lv_obj_t * label, const char * text) +void lv_label_ins_text(lv_obj_t * label, int32_t pos, const char * txt) { lv_label_ext_t * ext = lv_obj_get_ext(label); @@ -253,11 +258,21 @@ void lv_label_append_text(lv_obj_t * label, const char * text) /*Allocate space for the new text*/ uint32_t old_len = strlen(ext->txt); - uint32_t app_len = strlen(text); - uint32_t new_len = app_len + old_len; + uint32_t ins_len = strlen(txt); + uint32_t new_len = ins_len + old_len; ext->txt = dm_realloc(ext->txt, new_len + 1); - memcpy(ext->txt + old_len, text, app_len); - ext->txt[new_len] = '\0'; + + if(pos == LV_LABEL_POS_LAST) pos = old_len; + else if(pos < 0) pos = old_len + pos; + + /*Copy the second part into the end to make place to text to insert*/ + int32_t i; + for(i = new_len; i >= pos + ins_len; i--){ + ext->txt[i] = ext->txt[i - ins_len]; + } + + /* Copy the text into the new space*/ + memcpy(ext->txt + pos, txt, ins_len); lv_label_refr_text(label); } diff --git a/lv_objx/lv_label.h b/lv_objx/lv_label.h index 516eb2687..5bccfd68f 100644 --- a/lv_objx/lv_label.h +++ b/lv_objx/lv_label.h @@ -19,12 +19,13 @@ extern "C" { #include "../lv_obj/lv_obj.h" #include "misc/gfx/font.h" #include "misc/gfx/text.h" +#include "misc/gfx/fonts/symbol_def.h" /********************* * DEFINES *********************/ #define LV_LABEL_DOT_NUM 3 - +#define LV_LABEL_POS_LAST 0xFFFF /********************** * TYPEDEFS **********************/ @@ -103,11 +104,16 @@ void lv_label_set_text_array(lv_obj_t * label, const char * array, uint16_t size void lv_label_set_text_static(lv_obj_t * label, const char * text); /** - * Append a text to the label. The label current label text can not be static. + * Insert a text to the label. The label current label text can not be static. * @param label pointer to label object - * @param text pointe rto the new text + * @param pos character index to insert + * 0: before first char. + * LV_LABEL_POS_LAST: after last char. + * < 0: count from the end + * -1: before the last char. + * @param txt pointer to the text to insert */ -void lv_label_append_text(lv_obj_t * label, const char * text); +void lv_label_ins_text(lv_obj_t * label, int32_t pos, const char * txt); /** * Set the behavior of the label with longer text then the object size diff --git a/lv_objx/lv_roller.c b/lv_objx/lv_roller.c new file mode 100644 index 000000000..e25a8c3ef --- /dev/null +++ b/lv_objx/lv_roller.c @@ -0,0 +1,237 @@ +/** + * @file lv_roller.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_conf.h" +#if USE_LV_ROLLER != 0 + +#include "lv_roller.h" +#include "../lv_draw/lv_draw.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ +static bool lv_roller_design(lv_obj_t * roller, const area_t * mask, lv_design_mode_t mode); +bool roller_scrl_signal(lv_obj_t * roller_scrl, lv_signal_t sign, void * param); + +/********************** + * STATIC VARIABLES + **********************/ +static lv_signal_f_t ancestor_scr_signal_f; + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +/*----------------- + * Create function + *-----------------*/ + +/** + * 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 + */ +lv_obj_t * lv_roller_create(lv_obj_t * par, lv_obj_t * copy) +{ + /*Create the ancestor of roller*/ + /*TODO modify it to the ancestor create function */ + lv_obj_t * new_roller = lv_ddlist_create(par, copy); + dm_assert(new_roller); + + /*Allocate the roller type specific extended data*/ + lv_roller_ext_t * ext = lv_obj_alloc_ext(new_roller, sizeof(lv_roller_ext_t)); + dm_assert(ext); + + /*Initialize the allocated 'ext' */ + + /*The signal and design functions are not copied so set them here*/ + lv_obj_set_signal_f(new_roller, lv_roller_signal); + lv_obj_set_design_f(new_roller, lv_roller_design); + + if(ancestor_scr_signal_f == NULL) ancestor_scr_signal_f = lv_obj_get_signal_f(lv_page_get_scrl(new_roller)); + + /*Init the new roller roller*/ + if(copy == NULL) { + lv_obj_t * scrl = lv_page_get_scrl(new_roller); + lv_obj_set_drag(scrl, true); + lv_page_set_rel_action(new_roller, NULL); + lv_obj_set_signal_f(scrl, roller_scrl_signal); + // lv_ddlist_open(new_roller, true, false); + lv_obj_set_style(new_roller, lv_style_get(LV_STYLE_PRETTY, NULL)); + lv_cont_set_fit(lv_page_get_scrl(new_roller), true, false); + lv_ddlist_set_options_str(new_roller, "alma\nkorte\ncitrom\nbanan\neper\ndinnye"); + + lv_style_t * style_label = lv_obj_get_style(ext->ddlist.opt_label); + lv_obj_set_height(new_roller, (font_get_height(style_label->font) >> FONT_ANTIALIAS) * 3 + style_label->line_space * 4); + + lv_obj_set_height(lv_page_get_scrl(new_roller), lv_obj_get_height(ext->ddlist.opt_label) + lv_obj_get_height(new_roller)); + lv_obj_align(ext->ddlist.opt_label, NULL, LV_ALIGN_CENTER, 0, 0); + + } + /*Copy an existing roller*/ + else { + lv_roller_ext_t * copy_ext = lv_obj_get_ext(copy); + + /*Refresh the style with new signal function*/ + lv_obj_refr_style(new_roller); + } + + return new_roller; +} + +/** + * Signal function of the roller + * @param roller pointer to a roller object + * @param sign a signal type from lv_signal_t enum + * @param param pointer to a signal specific variable + * @return true: the object is still valid (not deleted), false: the object become invalid + */ +bool lv_roller_signal(lv_obj_t * roller, lv_signal_t sign, void * param) +{ + bool valid; + + /* Include the ancient signal function */ + /* TODO update it to the ancestor's signal function*/ + valid = lv_ddlist_signal(roller, sign, param); + + /* The object can be deleted so check its validity and then + * make the object specific signal handling */ + if(valid != false) { + if(sign == LV_SIGNAL_CLEANUP) { + /*Nothing to cleanup. (No dynamically allocated memory in 'ext')*/ + } + } + + return valid; +} + +/*====================== + * Add/remove functions + *=====================*/ + +/* + * New object specific "add" or "remove" functions come here + */ + + +/*===================== + * Setter functions + *====================*/ + +/* + * New object specific "set" functions come here + */ + + +/*===================== + * Getter functions + *====================*/ + +/* + * New object specific "get" functions come here + */ + +/*===================== + * Other functions + *====================*/ + +/* + * New object specific "other" functions come here + */ + +/********************** + * STATIC FUNCTIONS + **********************/ + + +/** + * Handle the drawing related tasks of the rollers + * @param roller pointer to an object + * @param mask the object will be drawn only in this area + * @param mode LV_DESIGN_COVER_CHK: only check if the object fully covers the 'mask_p' area + * (return 'true' if yes) + * LV_DESIGN_DRAW: draw the object (always return 'true') + * LV_DESIGN_DRAW_POST: drawing after every children are drawn + * @param return true/false, depends on 'mode' + */ +static bool lv_roller_design(lv_obj_t * roller, const area_t * mask, lv_design_mode_t mode) +{ + /*Return false if the object is not covers the mask_p area*/ + if(mode == LV_DESIGN_COVER_CHK) { + return false; + } + /*Draw the object*/ + else if(mode == LV_DESIGN_DRAW_MAIN) { + lv_style_t * style = lv_obj_get_style(roller); + lv_draw_rect(&roller->cords, mask, style); + + const font_t * font = style->font; + lv_roller_ext_t * ext = lv_obj_get_ext(roller); + cord_t font_h = font_get_height(font) >> FONT_ANTIALIAS; + area_t rect_area; + rect_area.y1 = roller->cords.y1 + lv_obj_get_height(roller) / 2 - font_h / 2 - style->line_space - 2; + + rect_area.y2 = rect_area.y1 + font_h + style->line_space; + rect_area.x1 = ext->ddlist.opt_label->cords.x1 - style->hpad; + rect_area.x2 = rect_area.x1 + lv_obj_get_width(lv_page_get_scrl(roller)); + + lv_draw_rect(&rect_area, mask, ext->ddlist.style_sel); + } + /*Post draw when the children are drawn*/ + else if(mode == LV_DESIGN_DRAW_POST) { + + } + + return true; +} + + +bool roller_scrl_signal(lv_obj_t * roller_scrl, lv_signal_t sign, void * param) +{ + bool valid; + + /* Include the ancient signal function */ + valid = ancestor_scr_signal_f(roller_scrl, sign, param); + + /* The object can be deleted so check its validity and then + * make the object specific signal handling */ + if(valid != false) { + if(sign == LV_SIGNAL_RELEASED) { + lv_obj_t * roller = lv_obj_get_parent(roller_scrl); + lv_roller_ext_t * ext = lv_obj_get_ext(roller); + lv_style_t * style_label = lv_obj_get_style(ext->ddlist.opt_label); + + cord_t label_y1 = ext->ddlist.page.scrl->cords.y1 - roller->cords.y1; + cord_t label_unit = (font_get_height(style_label->font) >> FONT_ANTIALIAS) + style_label->line_space / 2; + cord_t mid = (roller->cords.y2 - roller->cords.y1) / 2; + + int32_t id = (mid - label_y1) / label_unit; + + printf("roller diff: %d , unit: %d, id: %d\n", mid-label_y1, label_unit, id); + } + } + + return valid; +} + + + +#endif diff --git a/lv_objx/lv_roller.h b/lv_objx/lv_roller.h new file mode 100644 index 000000000..873254763 --- /dev/null +++ b/lv_objx/lv_roller.h @@ -0,0 +1,67 @@ +/** + * @file lv_roller.h + * + */ + +#ifndef LV_ROLLER_H +#define LV_ROLLER_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "lv_conf.h" +#if USE_LV_ROLLER != 0 + +#include "../lv_obj/lv_obj.h" +#include "lv_ddlist.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ +/*Data of roller*/ +typedef struct { + lv_ddlist_ext_t ddlist; /*Ext. of ancestor*/ + /*New data for this type */ +}lv_roller_ext_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Create a roller objects + * @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 + */ +lv_obj_t * lv_roller_create(lv_obj_t * par, lv_obj_t * copy); + +/** + * Signal function of the roller + * @param roller pointer to a roller object + * @param sign a signal type from lv_signal_t enum + * @param param pointer to a signal specific variable + * @return true: the object is still valid (not deleted), false: the object become invalid + */ +bool lv_roller_signal(lv_obj_t * roller, lv_signal_t sign, void * param); + + +/********************** + * MACROS + **********************/ + +#endif /*USE_LV_ROLLER*/ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /*LV_ROLLER_H*/ diff --git a/lv_objx/lv_tabview.c b/lv_objx/lv_tabview.c index d66ef2d57..74ddc6924 100644 --- a/lv_objx/lv_tabview.c +++ b/lv_objx/lv_tabview.c @@ -151,10 +151,11 @@ bool lv_tabview_signal(lv_obj_t * tabview, lv_signal_t sign, void * param) /* The object can be deleted so check its validity and then * make the object specific signal handling */ if(valid != false) { + lv_tabview_ext_t * ext = lv_obj_get_ext(tabview); if(sign == LV_SIGNAL_CLEANUP) { - /*Nothing to cleanup. (No dynamically allocated memory in 'ext')*/ + dm_free(ext->tab_name_ptr); + ext->tab_name_ptr = NULL; } else if(sign == LV_SIGNAL_CORD_CHG) { - lv_tabview_ext_t * ext = lv_obj_get_ext(tabview); if(ext->content != NULL && (lv_obj_get_width(tabview) != area_get_width(param) || lv_obj_get_height(tabview) != area_get_height(param))) diff --git a/lvgl.h b/lvgl.h index 3cdee0c7e..ef7144498 100644 --- a/lvgl.h +++ b/lvgl.h @@ -33,6 +33,7 @@ extern "C" { #include "lv_objx/lv_btnm.h" #include "lv_objx/lv_kb.h" #include "lv_objx/lv_ddlist.h" +#include "lv_objx/lv_roller.h" #include "lv_objx/lv_ta.h" #include "lv_objx/lv_win.h" #include "lv_objx/lv_tabview.h"