1
0
mirror of https://github.com/lvgl/lvgl.git synced 2025-01-28 07:03:00 +08:00

Merge branch 'dev-5.2' into fix_attribute

This commit is contained in:
Zaltora 2018-08-10 13:13:54 +02:00
commit 1ece6c1612
20 changed files with 276 additions and 126 deletions

View File

@ -68,6 +68,7 @@
/*Color settings*/
#define LV_COLOR_DEPTH 16 /*Color depth: 1/8/16/24*/
#define LV_COLOR_16_SWAP 1 /*Swap the 2 bytes of RGB565 color. Useful if the display has a 8 bit interface (e.g. SPI)*/
#define LV_COLOR_TRANSP LV_COLOR_LIME /*Images pixels with this color will not be drawn (with chroma keying)*/
/*Text settings*/

View File

@ -181,6 +181,17 @@ void lv_indev_get_point(const lv_indev_t * indev, lv_point_t * point)
}
}
/**
* Get the last key of an input device (for LV_INDEV_TYPE_KEYPAD)
* @param indev pointer to an input device
* @return the last pressed key (0 on error)
*/
uint32_t lv_indev_get_key(const lv_indev_t * indev)
{
if(indev->driver.type != LV_INDEV_TYPE_KEYPAD) return 0;
else return indev->proc.last_key;
}
/**
* Check if there is dragging with an input device or not (for LV_INDEV_TYPE_POINTER and LV_INDEV_TYPE_BUTTON)
* @param indev pointer to an input device

View File

@ -98,6 +98,13 @@ void lv_indev_set_button_points(lv_indev_t *indev, lv_point_t *points);
*/
void lv_indev_get_point(const lv_indev_t * indev, lv_point_t * point);
/**
* Get the last key of an input device (for LV_INDEV_TYPE_KEYPAD)
* @param indev pointer to an input device
* @return the last pressed key (0 on error)
*/
uint32_t lv_indev_get_key(const lv_indev_t * indev);
/**
* Check if there is dragging with an input device or not (for LV_INDEV_TYPE_POINTER and LV_INDEV_TYPE_BUTTON)
* @param indev pointer to an input device

View File

@ -292,7 +292,6 @@ static void lv_refr_area_with_vdb(const lv_area_t * area_p)
/*Round down the lines of VDB if rounding is added*/
if(round_cb) {
/**/
lv_area_t tmp;
tmp.x1 = 0;
tmp.x2 = 0;
@ -303,14 +302,14 @@ static void lv_refr_area_with_vdb(const lv_area_t * area_p)
do {
tmp.y2 = y_tmp;
round_cb(&tmp);
y_tmp --; /*Decrement the number of line until it is rounded to a smaller value the original. */
} while(tmp.y2 > max_row && y_tmp != 0);
y_tmp --; /*Decrement the number of line until it is rounded to a smaller (or equal) value then the original. */
} while(lv_area_get_height(&tmp) > max_row && y_tmp != 0);
if(y_tmp == 0) {
LV_LOG_WARN("Can't set VDB height using the round function. (Wrong round_cb or to small VDB)");
return;
} else {
max_row = tmp.y2;
max_row = tmp.y2 + 1;
}
}

View File

@ -33,7 +33,6 @@
* GLOBAL FUNCTIONS
**********************/
#if USE_LV_IMG
/**
* Draw an image
* @param coords the coordinates of the image
@ -45,14 +44,12 @@
void lv_draw_img(const lv_area_t * coords, const lv_area_t * mask,
const void * src, const lv_style_t * style, lv_opa_t opa_scale)
{
if(src == NULL) {
lv_draw_rect(coords, mask, &lv_style_plain, LV_OPA_COVER);
lv_draw_label(coords, mask, &lv_style_plain, LV_OPA_COVER, "No\ndata", LV_TXT_FLAG_NONE, NULL);
return;
}
lv_opa_t opa = opa_scale == LV_OPA_COVER ? style->image.opa : (uint16_t)((uint16_t) style->image.opa * opa_scale) >> 8;
const uint8_t * u8_p = (uint8_t *) src;
@ -149,11 +146,8 @@ void lv_draw_img(const lv_area_t * coords, const lv_area_t * mask,
}
map_fp(coords, mask, img_var->pixel_map, opa, img_var->header.chroma_keyed, img_var->header.alpha_byte, style->image.color, style->image.intense);
}
}
#endif
/**********************
* STATIC FUNCTIONS

View File

@ -27,8 +27,6 @@ extern "C" {
* GLOBAL PROTOTYPES
**********************/
#if USE_LV_IMG
/**
* Draw an image
* @param coords the coordinates of the image
@ -40,8 +38,6 @@ extern "C" {
void lv_draw_img(const lv_area_t * coords, const lv_area_t * mask,
const void * src, const lv_style_t * style, lv_opa_t opa_scale);
#endif
/**********************
* MACROS
**********************/

View File

@ -471,7 +471,7 @@ static void lv_draw_rect_border_straight(const lv_area_t * coords, const lv_area
lv_coord_t width = lv_area_get_width(coords);
lv_coord_t height = lv_area_get_height(coords);
uint16_t bwidth = style->body.border.width;
lv_opa_t opa = (uint16_t)((uint16_t) style->body.border.opa * opa_scale) >> 8;
lv_opa_t opa = opa_scale == LV_OPA_COVER ? style->body.border.opa : (uint16_t)((uint16_t) style->body.border.opa * opa_scale) >> 8;
lv_border_part_t part = style->body.border.part;
lv_color_t color = style->body.border.color;
lv_area_t work_area;

View File

@ -62,6 +62,8 @@ static void sw_color_fill(lv_area_t * mem_area, lv_color_t * mem, const lv_area_
*/
void lv_vpx(lv_coord_t x, lv_coord_t y, const lv_area_t * mask_p, lv_color_t color, lv_opa_t opa)
{
if(opa == LV_OPA_TRANSP) return;
lv_vdb_t * vdb_p = lv_vdb_get();
/*Pixel out of the mask*/
@ -100,6 +102,8 @@ void lv_vpx(lv_coord_t x, lv_coord_t y, const lv_area_t * mask_p, lv_color_t col
void lv_vfill(const lv_area_t * cords_p, const lv_area_t * mask_p,
lv_color_t color, lv_opa_t opa)
{
if(opa == LV_OPA_TRANSP) return;
lv_area_t res_a;
bool union_ok;
lv_vdb_t * vdb_p = lv_vdb_get();
@ -220,6 +224,9 @@ void lv_vletter(const lv_point_t * pos_p, const lv_area_t * mask_p,
204, 221, 238, 255
};
if(opa == LV_OPA_TRANSP) return;
if(font_p == NULL) {
LV_LOG_WARN("Font: character's bitmap not found");
return;
@ -357,6 +364,8 @@ void lv_vmap(const lv_area_t * cords_p, const lv_area_t * mask_p,
lv_color_t recolor, lv_opa_t recolor_opa)
{
if(opa == LV_OPA_TRANSP) return;
lv_area_t masked_a;
bool union_ok;
lv_vdb_t * vdb_p = lv_vdb_get();

View File

@ -6835,8 +6835,13 @@ static const lv_font_glyph_dsc_t lv_font_symbol_30_glyph_dsc[] = {
#endif
};
lv_font_t lv_font_symbol_30 = {
#if LV_TXT_UTF8
.unicode_first = 61440, /*First Unicode letter in this font*/
.unicode_last = 62190, /*Last Unicode letter in this font*/
#else
.unicode_first = 192, /*First Unicode letter in this font*/
.unicode_last = 241, /*Last Unicode letter in this font*/
#endif
.h_px = 30, /*Font height in pixels*/
.glyph_bitmap = lv_font_symbol_30_glyph_bitmap, /*Bitmap of glyphs*/
.glyph_dsc = lv_font_symbol_30_glyph_dsc, /*Description of glyphs*/

View File

@ -96,9 +96,21 @@ typedef union
{
struct
{
#if LV_COLOR_16_SWAP == 0
uint16_t blue :5;
uint16_t green :6;
uint16_t red :5;
#else
// uint16_t blue :5;
// uint16_t green_h :3;
// uint16_t green_l :3;
// uint16_t red :5;
uint16_t green_h :3;
uint16_t red :5;
uint16_t blue :5;
uint16_t green_l :3;
#endif
};
uint16_t full;
} lv_color16_t;
@ -171,10 +183,17 @@ static inline uint8_t lv_color_to1(lv_color_t color)
return 0;
}
#elif LV_COLOR_DEPTH == 16
# if LV_COLOR_16_SWAP == 0
if((color.red & 0x10) ||
(color.green & 0x20) ||
(color.blue & 0x10)) {
return 1;
# else
if((color.red & 0x10) ||
(color.green_h & 0x20) ||
(color.blue & 0x10)) {
return 1;
# endif
} else {
return 0;
}
@ -197,11 +216,20 @@ static inline uint8_t lv_color_to8(lv_color_t color)
#elif LV_COLOR_DEPTH == 8
return color.full;
#elif LV_COLOR_DEPTH == 16
# if LV_COLOR_16_SWAP == 0
lv_color8_t ret;
ret.red = color.red >> 2; /* 5 - 3 = 2*/
ret.green = color.green >> 3; /* 6 - 3 = 3*/
ret.blue = color.blue >> 3; /* 5 - 2 = 3*/
return ret.full;
# else
lv_color8_t ret;
ret.red = color.red >> 2; /* 5 - 3 = 2*/
ret.green = color.green_h; /* 6 - 3 = 3*/
ret.blue = color.blue >> 3; /* 5 - 2 = 3*/
return ret.full;
# endif
#elif LV_COLOR_DEPTH == 24
lv_color8_t ret;
ret.red = color.red >> 5; /* 8 - 3 = 5*/
@ -246,12 +274,21 @@ static inline uint32_t lv_color_to24(lv_color_t color)
ret.alpha = 0xFF;
return ret.full;
#elif LV_COLOR_DEPTH == 16
# if LV_COLOR_16_SWAP == 0
lv_color24_t ret;
ret.red = color.red * 8; /*(2^8 - 1)/(2^5 - 1) = 255/31 = 8*/
ret.green = color.green * 4; /*(2^8 - 1)/(2^6 - 1) = 255/63 = 4*/
ret.blue = color.blue * 8; /*(2^8 - 1)/(2^5 - 1) = 255/31 = 8*/
ret.alpha = 0xFF;
return ret.full;
# else
lv_color24_t ret;
ret.red = color.red * 8; /*(2^8 - 1)/(2^5 - 1) = 255/31 = 8*/
ret.green = ((color.green_h << 3) + color.green_l) * 4; /*(2^8 - 1)/(2^6 - 1) = 255/63 = 4*/
ret.blue = color.blue * 8; /*(2^8 - 1)/(2^5 - 1) = 255/31 = 8*/
ret.alpha = 0xFF;
return ret.full;
# endif
#elif LV_COLOR_DEPTH == 24
return color.full;
#endif
@ -262,7 +299,15 @@ static inline lv_color_t lv_color_mix(lv_color_t c1, lv_color_t c2, uint8_t mix)
lv_color_t ret;
#if LV_COLOR_DEPTH != 1
ret.red = (uint16_t)((uint16_t) c1.red * mix + (c2.red * (255 - mix))) >> 8;
# if LV_COLOR_DEPTH == 16 && LV_COLOR_16_SWAP
uint16_t g_1 = (c1.green_h << 3) + c1.green_l;
uint16_t g_2 = (c2.green_h << 3) + c2.green_l;
uint16_t g_out = (uint16_t)((uint16_t) g_1 * mix + (g_2 * (255 - mix))) >> 8;
ret.green_h = g_out >> 3;
ret.green_l = g_out & 0x7;
# else
ret.green = (uint16_t)((uint16_t) c1.green * mix + (c2.green * (255 - mix))) >> 8;
# endif
ret.blue = (uint16_t)((uint16_t) c1.blue * mix + (c2.blue * (255 - mix))) >> 8;
# if LV_COLOR_DEPTH == 24
ret.alpha = 0xFF;
@ -295,7 +340,11 @@ static inline uint8_t lv_color_brightness(lv_color_t color)
#elif LV_COLOR_DEPTH == 8
#define LV_COLOR_MAKE(r8, g8, b8) ((lv_color_t){{b8 >> 6, g8 >> 5, r8 >> 5}})
#elif LV_COLOR_DEPTH == 16
#define LV_COLOR_MAKE(r8, g8, b8) ((lv_color_t){{b8 >> 3, g8 >> 2, r8 >> 3}})
# if LV_COLOR_16_SWAP == 0
# define LV_COLOR_MAKE(r8, g8, b8) ((lv_color_t){{b8 >> 3, g8 >> 2, r8 >> 3}})
# else
# define LV_COLOR_MAKE(r8, g8, b8) ((lv_color_t){{g8 >> 5, r8 >> 3, b8 >> 3, (g8 >> 2) & 0x7}})
# endif
#elif LV_COLOR_DEPTH == 24
#define LV_COLOR_MAKE(r8, g8, b8) ((lv_color_t){{b8, g8, r8, 0xff}}) /*Fix 0xff alpha*/
#endif

View File

@ -26,6 +26,7 @@ static bool is_break_char(uint32_t letter);
#if LV_TXT_UTF8
static uint8_t lv_txt_utf8_size(const char * str);
static uint32_t lv_txt_unicode_to_utf8(uint32_t letter_uni);
static uint32_t lv_txt_utf8_conv_wc(uint32_t c);
static uint32_t lv_txt_utf8_next(const char * txt, uint32_t * i);
static uint32_t lv_txt_utf8_prev(const char * txt, uint32_t * i_start);
static uint32_t lv_txt_utf8_get_byte_id(const char * txt, uint32_t utf8_id);
@ -34,6 +35,7 @@ static uint32_t lv_txt_utf8_get_length(const char * txt);
#else
static uint8_t lv_txt_ascii_size(const char * str);
static uint32_t lv_txt_unicode_to_ascii(uint32_t letter_uni);
static uint32_t lv_txt_ascii_conv_wc(uint32_t c);
static uint32_t lv_txt_ascii_next(const char * txt, uint32_t * i);
static uint32_t lv_txt_ascii_prev(const char * txt, uint32_t * i_start);
static uint32_t lv_txt_ascii_get_byte_id(const char * txt, uint32_t utf8_id);
@ -52,6 +54,7 @@ static uint32_t lv_txt_ascii_get_length(const char * txt);
#if LV_TXT_UTF8
uint8_t (*lv_txt_encoded_size)(const char *) = lv_txt_utf8_size;
uint32_t (*lv_txt_unicode_to_encoded)(uint32_t) = lv_txt_unicode_to_utf8;
uint32_t (*lv_txt_encoded_conv_wc)(uint32_t) = lv_txt_utf8_conv_wc;
uint32_t (*lv_txt_encoded_next)(const char * , uint32_t *) = lv_txt_utf8_next;
uint32_t (*lv_txt_encoded_prev)(const char * , uint32_t * ) = lv_txt_utf8_prev;
uint32_t (*txt_encoded_get_byte_id)(const char * , uint32_t) = lv_txt_utf8_get_byte_id;
@ -60,6 +63,7 @@ uint32_t (*lv_txt_get_encoded_length)(const char * ) = lv_txt_utf8_get_length
#else
uint8_t (*lv_txt_encoded_size)(const char *) = lv_txt_ascii_size;
uint32_t (*lv_txt_unicode_to_encoded)(uint32_t) = lv_txt_unicode_to_ascii;
uint32_t (*lv_txt_encoded_conv_wc)(uint32_t) = lv_txt_ascii_conv_wc;
uint32_t (*lv_txt_encoded_next)(const char * , uint32_t *) = lv_txt_ascii_next;
uint32_t (*lv_txt_encoded_prev)(const char * , uint32_t * ) = lv_txt_ascii_prev;
uint32_t (*txt_encoded_get_byte_id)(const char * , uint32_t) = lv_txt_ascii_get_byte_id;
@ -379,6 +383,29 @@ static uint32_t lv_txt_unicode_to_utf8(uint32_t letter_uni)
return *res_p;
}
/**
* Convert a wide character, e.g. 'Á' little endian to be UTF-8 compatible
* @param c a wide character or a Little endian number
* @return `c` in big endian
*/
static uint32_t lv_txt_utf8_conv_wc(uint32_t c)
{
/*Swap the bytes (UTF-8 is big endian, but the MCUs are little endian)*/
if((c & 0x80) != 0) {
uint32_t swapped;
uint8_t c8[4];
memcpy(c8, &c, 4);
swapped = (c8[0] << 24) + (c8[1] << 16) + (c8[2] << 8) + (c8[3]);
uint8_t i;
for(i = 0; i < 4; i++) {
if((swapped & 0xFF) == 0) swapped = (swapped >> 8); /*Ignore leading zeros (they were in the end originally)*/
}
c = swapped;
}
return c;
}
/**
* Decode an UTF-8 character from a string.
* @param txt pointer to '\0' terminated string
@ -570,6 +597,17 @@ static uint32_t lv_txt_unicode_to_ascii(uint32_t letter_uni)
else return ' ';
}
/**
* Convert wide characters to ASCII, however wide characters in ASCII range (e.g. 'A') are ASCII compatible by default.
* So this function does nothing just returns with `c`.
* @param c a character, e.g. 'A'
* @return same as `c`
*/
static uint32_t lv_txt_ascii_conv_wc(uint32_t c)
{
return c;
}
/**
* Decode an UTF-8 character from a string.
* @param txt pointer to '\0' terminated string

View File

@ -134,6 +134,13 @@ extern uint8_t (*lv_txt_encoded_size)(const char *);
*/
extern uint32_t (*lv_txt_unicode_to_encoded)(uint32_t );
/**
* Convert a wide character, e.g. 'Á' little endian to be compatible with the encoded format.
* @param c a wide character
* @return `c` in the encoded format
*/
extern uint32_t (*lv_txt_encoded_conv_wc) (uint32_t c);
/**
* Decode the next encoded character from a string.
* @param txt pointer to '\0' terminated string

View File

@ -389,14 +389,12 @@ static bool lv_btn_design(lv_obj_t * btn, const lv_area_t * mask, lv_design_mode
}
else if(mode == LV_DESIGN_DRAW_MAIN) {
ancestor_design(btn, mask, mode);
#if USE_LV_ANIMATION
if(btn != ink_obj) {
lv_style_t * style = lv_obj_get_style(btn);
lv_draw_rect(&btn->coords, mask, style, LV_OPA_COVER);
ancestor_design(btn, mask, mode);
} else {
lv_btn_ext_t * ext = lv_obj_get_ext_attr(btn);
lv_opa_t opa_scale = lv_obj_get_opa_scale(btn);
lv_btn_ext_t * ext = lv_obj_get_ext_attr(btn);
/*Draw the normal button*/
lv_draw_rect(&btn->coords, mask, ext->styles[ink_bg_state], opa_scale);
@ -436,6 +434,8 @@ static bool lv_btn_design(lv_obj_t * btn, const lv_area_t * mask, lv_design_mode
/*Draw the circle*/
lv_draw_rect(&cir_area, mask, &cir_style, opa_scale);
}
#else
ancestor_design(btn, mask, mode);
#endif
}
else if(mode == LV_DESIGN_DRAW_POST) {

View File

@ -108,6 +108,7 @@ lv_obj_t * lv_ddlist_create(lv_obj_t * par, const lv_obj_t * copy)
lv_cont_set_fit(new_ddlist, true, false);
lv_page_set_rel_action(new_ddlist, lv_ddlist_release_action);
lv_page_set_sb_mode(new_ddlist, LV_SB_MODE_DRAG);
lv_page_set_sb_mode(new_ddlist, LV_SB_MODE_HIDE);
lv_page_set_style(new_ddlist, LV_PAGE_STYLE_SCRL, &lv_style_transp_tight);
lv_ddlist_set_options(new_ddlist, "Option 1\nOption 2\nOption 3");
@ -465,39 +466,40 @@ static bool lv_ddlist_design(lv_obj_t * ddlist, const lv_area_t * mask, lv_desig
}
/*Post draw when the children are drawn*/
else if(mode == LV_DESIGN_DRAW_POST) {
ancestor_design(ddlist, mask, mode);
/*Redraw the text on the selected area with a different color*/
lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist);
lv_opa_t opa_scale = lv_obj_get_opa_scale(ddlist);
/*Redraw only in opened state*/
if(ext->opened == 0) return true;
if(ext->opened) {
lv_style_t * style = lv_ddlist_get_style(ddlist, LV_DDLIST_STYLE_BG);
const lv_font_t * font = style->text.font;
lv_coord_t font_h = lv_font_get_height(font);
lv_style_t * style = lv_ddlist_get_style(ddlist, LV_DDLIST_STYLE_BG);
const lv_font_t * font = style->text.font;
lv_coord_t font_h = lv_font_get_height(font);
lv_area_t area_sel;
area_sel.y1 = ext->label->coords.y1;
area_sel.y1 += ext->sel_opt_id * (font_h + style->text.line_space);
area_sel.y1 -= style->text.line_space / 2;
lv_area_t area_sel;
area_sel.y1 = ext->label->coords.y1;
area_sel.y1 += ext->sel_opt_id * (font_h + style->text.line_space);
area_sel.y1 -= style->text.line_space / 2;
area_sel.y2 = area_sel.y1 + font_h + style->text.line_space - 1;
area_sel.x1 = ddlist->coords.x1;
area_sel.x2 = ddlist->coords.x2;
lv_area_t mask_sel;
bool area_ok;
area_ok = lv_area_intersect(&mask_sel, mask, &area_sel);
if(area_ok) {
lv_style_t * sel_style = lv_ddlist_get_style(ddlist, LV_DDLIST_STYLE_SEL);
lv_style_t new_style;
lv_style_copy(&new_style, style);
new_style.text.color = sel_style->text.color;
new_style.text.opa = sel_style->text.opa;
lv_draw_label(&ext->label->coords, &mask_sel, &new_style, opa_scale,
lv_label_get_text(ext->label), LV_TXT_FLAG_NONE, NULL);
area_sel.y2 = area_sel.y1 + font_h + style->text.line_space - 1;
area_sel.x1 = ddlist->coords.x1;
area_sel.x2 = ddlist->coords.x2;
lv_area_t mask_sel;
bool area_ok;
area_ok = lv_area_intersect(&mask_sel, mask, &area_sel);
if(area_ok) {
lv_style_t * sel_style = lv_ddlist_get_style(ddlist, LV_DDLIST_STYLE_SEL);
lv_style_t new_style;
lv_style_copy(&new_style, style);
new_style.text.color = sel_style->text.color;
new_style.text.opa = sel_style->text.opa;
lv_draw_label(&ext->label->coords, &mask_sel, &new_style, opa_scale,
lv_label_get_text(ext->label), LV_TXT_FLAG_NONE, NULL);
}
}
/*Draw the scrollbar in the ancestor page design function*/
ancestor_design(ddlist, mask, mode);
}
return true;
@ -682,11 +684,15 @@ static void lv_ddlist_refr_size(lv_obj_t * ddlist, bool anim_en)
if(ext->opened) { /*Open the list*/
if(ext->fix_height == 0) new_height = lv_obj_get_height(lv_page_get_scrl(ddlist)) + 2 * style->body.padding.ver;
else new_height = ext->fix_height;
lv_page_set_sb_mode(ddlist, LV_SB_MODE_UNHIDE);
} else { /*Close the list*/
const lv_font_t * font = style->text.font;
lv_style_t * label_style = lv_obj_get_style(ext->label);
lv_coord_t font_h = lv_font_get_height(font);
new_height = font_h + 2 * label_style->text.line_space;
lv_page_set_sb_mode(ddlist, LV_SB_MODE_HIDE);
}
if(anim_en == 0) {

View File

@ -220,7 +220,7 @@ void lv_ddlist_open(lv_obj_t * ddlist, bool anim);
* @param ddlist pointer to drop down list object
* @param anim true: use animation; false: not use animations
*/
void lv_ddlist_close_en(lv_obj_t * ddlist, bool anim);
void lv_ddlist_close(lv_obj_t * ddlist, bool anim);
/**********************
* MACROS

View File

@ -20,7 +20,7 @@
* DEFINES
*********************/
#define LV_PAGE_SB_MIN_SIZE (LV_DPI / 8)
#define LV_PAGE_GROUP_SCROLL_ANIM_TIME 200
#define LV_PAGE_SCROLL_ANIM_TIME 200 /*[ms] Scroll anim time on `lv_page_scroll_up/down/left/rigth`*/
/**********************
* TYPEDEFS
@ -193,9 +193,16 @@ void lv_page_set_sb_mode(lv_obj_t * page, lv_sb_mode_t sb_mode)
lv_page_ext_t * ext = lv_obj_get_ext_attr(page);
if(ext->sb.mode == sb_mode) return;
ext->sb.mode = sb_mode;
if(sb_mode == LV_SB_MODE_HIDE) ext->sb.mode |= LV_SB_MODE_HIDE; /*Set the hidden flag*/
else if (sb_mode == LV_SB_MODE_UNHIDE) ext->sb.mode &= (~LV_SB_MODE_HIDE); /*Clear the hidden flag*/
else {
if(ext->sb.mode & LV_SB_MODE_HIDE) sb_mode |= LV_SB_MODE_HIDE;
ext->sb.mode = sb_mode;
}
ext->sb.hor_draw = 0;
ext->sb.ver_draw = 0;
lv_page_sb_refresh(page);
lv_obj_invalidate(page);
}
@ -389,58 +396,60 @@ void lv_page_focus(lv_obj_t * page, const lv_obj_t * obj, uint16_t anim_time)
}
/**
* Scroll down the page a little
* Scroll the page horizontally
* @param page pointer to a page object
* @param dist the distance to scroll (< 0: scroll right; > 0 scroll left)
*/
void lv_page_scroll_down(lv_obj_t * page)
void lv_page_scroll_hor(lv_obj_t * page, lv_coord_t dist)
{
lv_obj_t * scrl = lv_page_get_scrl(page);
#if USE_LV_ANIMATION
lv_anim_t a;
a.var = scrl;
a.start = lv_obj_get_y(scrl);
a.end = a.start - lv_obj_get_height(page) / 4;
a.fp = (lv_anim_fp_t)lv_obj_set_y;
a.start = lv_obj_get_x(scrl);
a.end = a.start + dist;
a.fp = (lv_anim_fp_t)lv_obj_set_x;
a.path = lv_anim_path_linear;
a.end_cb = NULL;
a.act_time = 0;
a.time = LV_PAGE_GROUP_SCROLL_ANIM_TIME;
a.time = LV_PAGE_SCROLL_ANIM_TIME;
a.playback = 0;
a.playback_pause = 0;
a.repeat = 0;
a.repeat_pause = 0;
lv_anim_create(&a);
#else
lv_obj_set_y(scrl, lv_obj_get_y(scrl) - lv_obj_get_height(page) / 4);
lv_obj_set_x(scrl, lv_obj_get_x(scrl) + dist);
#endif
}
/**
*Scroll up the page a little
* Scroll the page vertically
* @param page pointer to a page object
* @param dist the distance to scroll (< 0: scroll down; > 0 scroll up)
*/
void lv_page_scroll_up(lv_obj_t * page)
void lv_page_scroll_ver(lv_obj_t * page, lv_coord_t dist)
{
lv_obj_t * scrl = lv_page_get_scrl(page);
#if USE_LV_ANIMATION
lv_anim_t a;
a.var = scrl;
a.start = lv_obj_get_y(scrl);
a.end = a.start + lv_obj_get_height(page) / 4;
a.end = a.start + dist;
a.fp = (lv_anim_fp_t)lv_obj_set_y;
a.path = lv_anim_path_linear;
a.end_cb = NULL;
a.act_time = 0;
a.time = LV_PAGE_GROUP_SCROLL_ANIM_TIME;
a.time = LV_PAGE_SCROLL_ANIM_TIME;
a.playback = 0;
a.playback_pause = 0;
a.repeat = 0;
a.repeat_pause = 0;
lv_anim_create(&a);
#else
lv_obj_set_y(scrl, lv_obj_get_y(scrl) + lv_obj_get_height(page) / 4);
lv_obj_set_y(scrl, lv_obj_get_x(scrl) + dist);
#endif
}
@ -482,12 +491,11 @@ static bool lv_page_design(lv_obj_t * page, const lv_area_t * mask, lv_design_mo
style->body.shadow.width = shadow_width_tmp;
style->body.empty = empty_tmp;
lv_page_ext_t * ext = lv_obj_get_ext_attr(page);
/*Draw the scrollbars*/
lv_area_t sb_area;
if(ext->sb.hor_draw) {
if(ext->sb.hor_draw && (ext->sb.mode & LV_SB_MODE_HIDE) == 0) {
/*Convert the relative coordinates to absolute*/
lv_area_copy(&sb_area, &ext->sb.hor_area);
sb_area.x1 += page->coords.x1;
@ -497,7 +505,7 @@ static bool lv_page_design(lv_obj_t * page, const lv_area_t * mask, lv_design_mo
lv_draw_rect(&sb_area, mask, ext->sb.style, lv_obj_get_opa_scale(page));
}
if(ext->sb.ver_draw) {
if(ext->sb.ver_draw && (ext->sb.mode & LV_SB_MODE_HIDE) == 0) {
/*Convert the relative coordinates to absolute*/
lv_area_copy(&sb_area, &ext->sb.ver_area);
sb_area.x1 += page->coords.x1;
@ -627,11 +635,14 @@ static lv_res_t lv_page_signal(lv_obj_t * page, lv_signal_t sign, void * param)
} else if(sign == LV_SIGNAL_CONTROLL) {
uint32_t c = *((uint32_t *) param);
if((c == LV_GROUP_KEY_DOWN || c == LV_GROUP_KEY_RIGHT) && ext->arrow_scroll) {
lv_page_scroll_down(page);
} else if((c == LV_GROUP_KEY_UP || c == LV_GROUP_KEY_LEFT) && ext->arrow_scroll) {
lv_page_scroll_up(page);
if((c == LV_GROUP_KEY_DOWN) && ext->arrow_scroll) {
lv_page_scroll_ver(page, - lv_obj_get_height(page) / 4);
} else if((c == LV_GROUP_KEY_UP) && ext->arrow_scroll) {
lv_page_scroll_ver(page, lv_obj_get_height(page) / 4);
} else if((c == LV_GROUP_KEY_RIGHT) && ext->arrow_scroll) {
lv_page_scroll_hor(page, - lv_obj_get_width(page) / 4);
} else if((c == LV_GROUP_KEY_LEFT) && ext->arrow_scroll) {
lv_page_scroll_hor(page, lv_obj_get_width(page) / 4);
}
} else if(sign == LV_SIGNAL_GET_EDITABLE) {
bool * editable = (bool *)param;

View File

@ -40,10 +40,12 @@ extern "C" {
/*Scrollbar modes: shows when should the scrollbars be visible*/
typedef enum
{
LV_SB_MODE_OFF, /*Never show scrollbars*/
LV_SB_MODE_ON, /*Always show scrollbars*/
LV_SB_MODE_DRAG, /*Show scrollbars when page is being dragged*/
LV_SB_MODE_AUTO, /*Show scrollbars when the scrollable container is large enough to be scrolled*/
LV_SB_MODE_OFF = 0x0, /*Never show scrollbars*/
LV_SB_MODE_ON = 0x1, /*Always show scrollbars*/
LV_SB_MODE_DRAG = 0x2, /*Show scrollbars when page is being dragged*/
LV_SB_MODE_AUTO = 0x3, /*Show scrollbars when the scrollable container is large enough to be scrolled*/
LV_SB_MODE_HIDE = 0x4, /*Hide the scroll bar temporally*/
LV_SB_MODE_UNHIDE = 0x5, /*Unhide the previously hidden scrollbar. Recover it's type too*/
} lv_sb_mode_t;
/*Data of page*/
@ -279,16 +281,18 @@ void lv_page_glue_obj(lv_obj_t * obj, bool glue);
void lv_page_focus(lv_obj_t * page, const lv_obj_t * obj, uint16_t anim_time);
/**
* Scroll down the page a little
* Scroll the page horizontally
* @param page pointer to a page object
* @param dist the distance to scroll (< 0: scroll left; > 0 scroll right)
*/
void lv_page_scroll_down(lv_obj_t * page);
void lv_page_scroll_hor(lv_obj_t * page, lv_coord_t dist);
/**
* Scroll up the page a little
* Scroll the page vertically
* @param page pointer to a page object
* @param dist the distance to scroll (< 0: scroll down; > 0 scroll up)
*/
void lv_page_scroll_up(lv_obj_t * page);
void lv_page_scroll_ver(lv_obj_t * page, lv_coord_t dist);
/**********************
* MACROS

View File

@ -178,11 +178,12 @@ lv_obj_t * lv_ta_create(lv_obj_t * par, const lv_obj_t * copy)
*=====================*/
/**
* Insert a character to the current cursor position
* Insert a character to the current cursor position.
* To add a wide char, e.g. 'Á' use `lv_txt_encoded_conv_wc('Á')`
* @param ta pointer to a text area object
* @param c a character
* @param c a character (e.g. 'a')
*/
void lv_ta_add_char(lv_obj_t * ta, char c)
void lv_ta_add_char(lv_obj_t * ta, uint32_t c)
{
lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta);
@ -191,17 +192,19 @@ void lv_ta_add_char(lv_obj_t * ta, char c)
return;
}
if(char_is_accepted(ta, c) == false) {
uint32_t c_uni = lv_txt_encoded_next(&c, NULL);
if(char_is_accepted(ta, c_uni) == false) {
LV_LOG_INFO("Character is no accepted by the text area (too long text or not in the accepted list)");
return;
}
if(ext->pwd_mode != 0) pwd_char_hider(ta); /*Make sure all the current text contains only '*'*/
char letter_buf[2];
uint32_t letter_buf[2];
letter_buf[0] = c;
letter_buf[1] = '\0';
lv_label_ins_text(ext->label, ext->cursor.pos, letter_buf); /*Insert the character*/
lv_label_ins_text(ext->label, ext->cursor.pos, (const char *)letter_buf); /*Insert the character*/
if(ext->pwd_mode != 0) {
@ -209,7 +212,7 @@ void lv_ta_add_char(lv_obj_t * ta, char c)
lv_mem_assert(ext->pwd_tmp);
if(ext->pwd_tmp== NULL) return;
lv_txt_ins(ext->pwd_tmp, ext->cursor.pos, letter_buf);
lv_txt_ins(ext->pwd_tmp, ext->cursor.pos, (const char *)letter_buf);
#if USE_LV_ANIMATION
/*Auto hide characters*/
@ -247,13 +250,14 @@ void lv_ta_add_text(lv_obj_t * ta, const char * txt)
if(ext->pwd_mode != 0) pwd_char_hider(ta); /*Make sure all the current text contains only '*'*/
/*If only one character is added check if it is accepted*/
if(lv_txt_get_encoded_length(txt) == 1) {
uint32_t c = lv_txt_encoded_next(txt, NULL);
if(char_is_accepted(ta, c) == false) {
LV_LOG_INFO("Character is no accepted by the text area (too long text or not in the accepted list)");
return;
/*Add the character one-by-one if not all characters are accepted or there is character limit.*/
if(lv_ta_get_accepted_chars(ta) || lv_ta_get_max_length(ta)) {
uint32_t i = 0;
while(txt[i] != '\0') {
uint32_t c = lv_txt_encoded_next(txt, &i);
lv_ta_add_char(ta,lv_txt_unicode_to_encoded(c));
}
return;
}
/*Insert the text*/
@ -342,10 +346,23 @@ void lv_ta_del_char(lv_obj_t * ta)
void lv_ta_set_text(lv_obj_t * ta, const char * txt)
{
lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta);
lv_label_set_text(ext->label, txt);
lv_ta_set_cursor_pos(ta, LV_TA_CURSOR_LAST);
/*Don't let 'width == 0' because cursor will not be visible*/
/*Add the character one-by-one if not all characters are accepted or there is character limit.*/
if(lv_ta_get_accepted_chars(ta) || lv_ta_get_max_length(ta)) {
lv_label_set_text(ext->label, "");
lv_ta_set_cursor_pos(ta, LV_TA_CURSOR_LAST);
uint32_t i = 0;
while(txt[i] != '\0') {
uint32_t c = lv_txt_encoded_next(txt, &i);
lv_ta_add_char(ta,lv_txt_unicode_to_encoded(c));
}
} else {
lv_label_set_text(ext->label, txt);
lv_ta_set_cursor_pos(ta, LV_TA_CURSOR_LAST);
}
/*Don't let 'width == 0' because the cursor will not be visible*/
if(lv_obj_get_width(ext->label) == 0) {
lv_style_t * style = lv_obj_get_style(ext->label);
lv_obj_set_width(ext->label, lv_font_get_width(style->text.font, ' '));
@ -1029,32 +1046,13 @@ static lv_res_t lv_ta_signal(lv_obj_t * ta, lv_signal_t sign, void * param)
}
} else if(sign == LV_SIGNAL_CONTROLL) {
uint32_t c = *((uint32_t *)param); /*uint32_t because can be UTF-8*/
if(c == LV_GROUP_KEY_RIGHT) lv_ta_cursor_right(ta);
else if(c == LV_GROUP_KEY_LEFT) lv_ta_cursor_left(ta);
else if(c == LV_GROUP_KEY_UP) lv_ta_cursor_up(ta);
if(c == LV_GROUP_KEY_RIGHT) lv_ta_cursor_right(ta);
else if(c == LV_GROUP_KEY_LEFT) lv_ta_cursor_left(ta);
else if(c == LV_GROUP_KEY_UP) lv_ta_cursor_up(ta);
else if(c == LV_GROUP_KEY_DOWN) lv_ta_cursor_down(ta);
else if(c == LV_GROUP_KEY_DEL) lv_ta_del_char(ta);
else if(c == LV_GROUP_KEY_DEL) lv_ta_del_char(ta);
else {
#if LV_TXT_UTF8 != 0
/*Swap the bytes (UTF-8 is big endian, but the MCUs are little endian)*/
if((c & 0x80) == 0) { /*ASCII*/
lv_ta_add_char(ta, (char)c);
} else {
uint32_t swapped[2] = {0, 0}; /*the 2. element is the closing '\0'*/
uint8_t c8[4];
memcpy(c8, &c, 4);
swapped[0] = (c8[0] << 24) + (c8[1] << 16) + (c8[2] << 8) + (c8[3]);
char * p = (char *)swapped;
uint8_t i;
for(i = 0; i < 4; i++) {
if(p[0] == 0) p++; /*Ignore leading zeros (they were in the end originally)*/
}
lv_ta_add_text(ta, p);
}
#else
lv_ta_add_char(ta, (char)c);
#endif
lv_ta_add_char(ta, c);
}
} else if(sign == LV_SIGNAL_GET_EDITABLE) {
bool * editable = (bool *)param;
@ -1156,6 +1154,12 @@ static void pwd_char_hider(lv_obj_t * ta)
}
}
/**
* Test an unicode character if it is accepted or not. Checks max length and accepted char list.
* @param ta pointer to a test area object
* @param c an unicode character
* @return true: accapted; false: rejected
*/
static bool char_is_accepted(lv_obj_t * ta, uint32_t c)
{
lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta);

View File

@ -97,11 +97,12 @@ lv_obj_t * lv_ta_create(lv_obj_t * par, const lv_obj_t * copy);
*=====================*/
/**
* Insert a character to the current cursor position
* Insert a character to the current cursor position.
* To add a wide char, e.g. 'Á' use `lv_txt_encoded_conv_wc('Á')`
* @param ta pointer to a text area object
* @param c a character
* @param c a character (e.g. 'a')
*/
void lv_ta_add_char(lv_obj_t * ta, char c);
void lv_ta_add_char(lv_obj_t * ta, uint32_t c);
/**
* Insert a text to the current cursor position

View File

@ -223,17 +223,25 @@ lv_style_t * lv_win_get_style(const lv_obj_t *win, lv_win_style_t type);
*/
void lv_win_focus(lv_obj_t * win, lv_obj_t * obj, uint16_t anim_time);
static inline void lv_win_scroll_down(lv_obj_t * win)
/**
* Scroll the window horizontally
* @param win pointer to a window object
* @param dist the distance to scroll (< 0: scroll right; > 0 scroll left)
*/
static inline void lv_win_scroll_hor(lv_obj_t * win, lv_coord_t dist)
{
lv_win_ext_t * ext = lv_obj_get_ext_attr(win);
lv_page_scroll_down(ext->page);
lv_page_scroll_hor(ext->page, dist);
}
static inline void lv_win_scroll_up(lv_obj_t * win)
/**
* Scroll the window vertically
* @param win pointer to a window object
* @param dist the distance to scroll (< 0: scroll down; > 0 scroll up)
*/
static inline void lv_win_scroll_ver(lv_obj_t * win, lv_coord_t dist)
{
lv_win_ext_t * ext = lv_obj_get_ext_attr(win);
lv_page_scroll_up(ext->page);
lv_page_scroll_ver(ext->page, dist);
}
/**********************