Merge branch 'dev-6.0' of https://github.com/littlevgl/lvgl into dev-6.0

This commit is contained in:
Gabor Kiss-Vamosi
2019-04-19 05:46:13 +02:00
10 changed files with 319 additions and 139 deletions

View File

@@ -354,6 +354,7 @@ typedef void * lv_obj_user_data_t;
/*Hor, or ver. scroll speed [px/sec] in 'LV_LABEL_LONG_ROLL/ROLL_CIRC' mode*/
# define LV_LABEL_DEF_SCROLL_SPEED 25
# define LV_LABEL_WAIT_CHAR_COUNT 3 /* Waiting period at beginning/end of animation cycle */
# define LV_LABEL_TEXT_SEL 1 /*Enable selecting text of the label */
#endif
/*LED (dependencies: -)*/

View File

@@ -224,6 +224,7 @@ typedef struct _lv_obj_t
lv_opa_t opa_scale; /*Scale down the opacity by this factor. Effects all children as well*/
lv_coord_t ext_draw_pad; /*EXTtend the size in every direction for drawing. */
#if LV_USE_OBJ_REALIGN
lv_reailgn_t realign;
#endif

View File

@@ -50,12 +50,12 @@ static uint8_t hex_char_to_num(char hex);
* @param txt 0 terminated text to write
* @param flag settings for the text from 'txt_flag_t' enum
* @param offset text offset in x and y direction (NULL if unused)
* @param sel_start start index of selected area (-1 if none)
* @param sel_end end index of selected area (-1 if none)
* @param sel_start start index of selected area (`LV_LABEL_TXT_SEL_OFF` if none)
* @param sel_end end index of selected area (`LV_LABEL_TXT_SEL_OFF` if none)
*/
void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_style_t * style,
lv_opa_t opa_scale, const char * txt, lv_txt_flag_t flag, lv_point_t * offset,
int sel_start, int sel_end)
uint16_t sel_start, uint16_t sel_end)
{
const lv_font_t * font = style->text.font;
lv_coord_t w;
@@ -183,7 +183,7 @@ void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_st
letter_w = lv_font_get_width(font, letter);
if(sel_start != -1 && sel_end != -1) {
if(sel_start != 0xFFFF && sel_end != 0xFFFF) {
int char_ind = lv_encoded_get_char_id(txt, i);
/*Do not draw the rectangle on the character at `sel_start`.*/
if(char_ind > sel_start && char_ind <= sel_end) {

View File

@@ -36,12 +36,12 @@ extern "C" {
* @param txt 0 terminated text to write
* @param flag settings for the text from 'txt_flag_t' enum
* @param offset text offset in x and y direction (NULL if unused)
* @param sel_start start index of selected area (-1 if none)
* @param sel_end end index of selected area (-1 if none)
* @param sel_start start index of selected area (`LV_LABEL_TXT_SEL_OFF` if none)
* @param sel_end end index of selected area (`LV_LABEL_TXT_SEL_OFF` if none)
*/
void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_style_t * style,
lv_opa_t opa_scale, const char * txt, lv_txt_flag_t flag, lv_point_t * offset,
int sel_start, int sel_end);
uint16_t sel_start, uint16_t sel_end);
/**********************
* MACROS

View File

@@ -55,12 +55,12 @@ typedef struct
lv_cont_ext_t cont; /*Ext. of ancestor*/
/*New data for this type */
const lv_style_t * styles[LV_BTN_STATE_NUM]; /*Styles in each state*/
lv_btn_state_t state; /*Current state of the button from 'lv_btn_state_t' enum*/
#if LV_BTN_INK_EFFECT
uint16_t ink_in_time; /*[ms] Time of ink fill effect (0: disable ink effect)*/
uint16_t ink_wait_time; /*[ms] Wait before the ink disappears */
uint16_t ink_out_time; /*[ms] Time of ink disappearing*/
#endif
lv_btn_state_t state : 3; /*Current state of the button from 'lv_btn_state_t' enum*/
uint8_t toggle : 1; /*1: Toggle enabled*/
} lv_btn_ext_t;

View File

@@ -41,6 +41,11 @@ 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);
static void lv_label_set_offset_y(lv_obj_t * label, lv_coord_t y);
#endif
static bool lv_label_set_dot_tmp(lv_obj_t *label, char *data, uint16_t len);
static char * lv_label_get_dot_tmp(lv_obj_t *label);
static void lv_label_dot_tmp_free(lv_obj_t *label);
/**********************
* STATIC VARIABLES
**********************/
@@ -88,8 +93,12 @@ lv_obj_t * lv_label_create(lv_obj_t * par, const lv_obj_t * copy)
ext->anim_speed = LV_LABEL_DEF_SCROLL_SPEED;
ext->offset.x = 0;
ext->offset.y = 0;
ext->selection_start = -1;
ext->selection_end = -1;
#if LV_LABEL_TEXT_SEL
ext->txt_sel_start = LV_LABEL_TEXT_SEL_OFF;
ext->txt_sel_end = LV_LABEL_TEXT_SEL_OFF;
#endif
ext->dot_tmp_ptr = NULL;
ext->dot_tmp_alloc = 0;
lv_obj_set_design_cb(new_label, lv_label_design);
lv_obj_set_signal_cb(new_label, lv_label_signal);
@@ -121,7 +130,14 @@ lv_obj_t * lv_label_create(lv_obj_t * par, const lv_obj_t * copy)
memcpy(ext->text, copy_ext->text, lv_mem_get_size(copy_ext->text));
}
memcpy(ext->dot_tmp, copy_ext->dot_tmp, sizeof(ext->dot_tmp));
if(copy_ext->dot_tmp_alloc && copy_ext->dot_tmp_ptr ){
int len = strlen(copy_ext->dot_tmp_ptr);
lv_label_set_dot_tmp(new_label, ext->dot_tmp_ptr, len);
}
else{
memcpy(ext->dot_tmp, copy_ext->dot_tmp, sizeof(ext->dot_tmp));
}
ext->dot_tmp_alloc = copy_ext->dot_tmp_alloc;
ext->dot_end = copy_ext->dot_end;
/*Refresh the style with new signal function*/
@@ -337,6 +353,23 @@ void lv_label_set_anim_speed(lv_obj_t * label, uint16_t anim_speed)
}
}
void lv_label_set_text_sel_start( lv_obj_t * label, uint16_t index ) {
#if LV_LABEL_TEXT_SEL
lv_label_ext_t * ext = lv_obj_get_ext_attr(label);
ext->txt_sel_start = index;
lv_obj_invalidate(label);
#endif
}
void lv_label_set_text_sel_end( lv_obj_t * label, uint16_t index )
{
#if LV_LABEL_TEXT_SEL
lv_label_ext_t * ext = lv_obj_get_ext_attr(label);
ext->txt_sel_end = index;
lv_obj_invalidate(label);
#endif
}
/*=====================
* Getter functions
*====================*/
@@ -556,6 +589,37 @@ uint16_t lv_label_get_letter_on(const lv_obj_t * label, lv_point_t * pos)
return lv_encoded_get_char_id(txt, i);
}
/**
* @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.
*/
uint16_t lv_label_get_text_sel_start( const lv_obj_t * label ) {
#if LV_LABEL_TEXT_SEL
lv_label_ext_t * ext = lv_obj_get_ext_attr(label);
return ext->txt_sel_start;
#else
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.
*/
uint16_t lv_label_get_text_sel_end( const lv_obj_t * label ) {
#if LV_LABEL_TEXT_SEL
lv_label_ext_t * ext = lv_obj_get_ext_attr(label);
return ext->txt_sel_end;
#else
(void) label; /*Unused*/
return LV_LABEL_TEXT_SEL_OFF;
#endif
}
/**
* Check if a character is drawn under a point.
* @param label Label object
@@ -761,7 +825,7 @@ static bool lv_label_design(lv_obj_t * label, const lv_area_t * mask, lv_design_
}
lv_draw_label(&coords, mask, style, opa_scale, ext->text, flag, &ext->offset,
ext->selection_start, ext->selection_end);
lv_label_get_text_sel_start(label), lv_label_get_text_sel_end(label));
if(ext->long_mode == LV_LABEL_LONG_ROLL_CIRC) {
lv_point_t size;
@@ -774,8 +838,9 @@ static bool lv_label_design(lv_obj_t * label, const lv_area_t * mask, lv_design_
ofs.x = ext->offset.x + size.x +
lv_font_get_width(style->text.font, ' ') * LV_LABEL_WAIT_CHAR_COUNT;
ofs.y = ext->offset.y;
lv_draw_label(&coords, mask, style, opa_scale, ext->text, flag, &ofs,
ext->selection_start, ext->selection_end);
lv_label_get_text_sel_start(label), lv_label_get_text_sel_end(label));
}
/*Draw the text again below the original to make an circular effect */
@@ -783,7 +848,7 @@ static bool lv_label_design(lv_obj_t * label, const lv_area_t * mask, lv_design_
ofs.x = ext->offset.x;
ofs.y = ext->offset.y + size.y + lv_font_get_height(style->text.font);
lv_draw_label(&coords, mask, style, opa_scale, ext->text, flag, &ofs,
ext->selection_start, ext->selection_end);
lv_label_get_text_sel_start(label), lv_label_get_text_sel_end(label));
}
}
}
@@ -811,6 +876,7 @@ static lv_res_t lv_label_signal(lv_obj_t * label, lv_signal_t sign, void * param
lv_mem_free(ext->text);
ext->text = NULL;
}
lv_label_dot_tmp_free(label);
} else if(sign == LV_SIGNAL_STYLE_CHG) {
/*Revert dots for proper refresh*/
lv_label_revert_dots(label);
@@ -982,15 +1048,13 @@ static void lv_label_refr_text(lv_obj_t * label)
lv_txt_encoded_next(ext->text, &byte_id);
}
memcpy(ext->dot_tmp, &ext->text[byte_id_ori], len);
ext->dot_tmp[len] = '\0'; /*Close with a zero*/
for(i = 0; i < LV_LABEL_DOT_NUM; i++) {
ext->text[byte_id_ori + i] = '.';
if( lv_label_set_dot_tmp(label, &ext->text[byte_id_ori], len ) ){
for(i = 0; i < LV_LABEL_DOT_NUM; i++) {
ext->text[byte_id_ori + i] = '.';
}
ext->text[byte_id_ori + LV_LABEL_DOT_NUM] = '\0';
ext->dot_end = letter_id + LV_LABEL_DOT_NUM;
}
ext->text[byte_id_ori + LV_LABEL_DOT_NUM] = '\0';
ext->dot_end = letter_id + LV_LABEL_DOT_NUM;
}
}
/*In break mode only the height can change*/
@@ -1015,10 +1079,13 @@ static void lv_label_revert_dots(lv_obj_t * label)
/*Restore the characters*/
uint8_t i = 0;
while(ext->dot_tmp[i] != '\0') {
ext->text[byte_i + i] = ext->dot_tmp[i];
char* dot_tmp = lv_label_get_dot_tmp(label);
while(ext->text[byte_i + i] != '\0') {
ext->text[byte_i + i] = dot_tmp[i];
i++;
}
ext->text[byte_i + i] = dot_tmp[i];
lv_label_dot_tmp_free(label);
ext->dot_end = LV_LABEL_DOT_END_INV;
}
@@ -1038,4 +1105,64 @@ static void lv_label_set_offset_y(lv_obj_t * label, lv_coord_t y)
lv_obj_invalidate(label);
}
#endif
/**
* Store `len` characters from `data`. Allocates space if necessary.
*
* @param label pointer to label object
* @param len Number of characters to store.
* @return true on success.
*/
static bool lv_label_set_dot_tmp(lv_obj_t *label, char *data, uint16_t len){
lv_label_ext_t * ext = lv_obj_get_ext_attr(label);
lv_label_dot_tmp_free( label ); /* Deallocate any existing space */
if( len > sizeof(char *) ){
/* Memory needs to be allocated. Allocates an additional byte
* for a NULL-terminator so it can be copied. */
ext->dot_tmp_ptr = lv_mem_alloc(len + 1);
if( ext->dot_tmp_ptr == NULL ){
LV_LOG_ERROR("Failed to allocate memory for dot_tmp_ptr");
return false;
}
memcpy(ext->dot_tmp_ptr, data, len);
ext->dot_tmp_ptr[len]='\0';
ext->dot_tmp_alloc = true;
}
else {
/* Characters can be directly stored in object */
ext->dot_tmp_alloc = false;
memcpy(ext->dot_tmp, data, len);
}
return true;
}
/**
* Get the stored dot_tmp characters
* @param label pointer to label object
* @return char pointer to a stored characters. Is *not* necessarily NULL-terminated.
*/
static char * lv_label_get_dot_tmp(lv_obj_t *label){
lv_label_ext_t * ext = lv_obj_get_ext_attr(label);
if( ext->dot_tmp_alloc ){
return ext->dot_tmp_ptr;
}
else{
return ext->dot_tmp;
}
}
/**
* Free the dot_tmp_ptr field if it was previously allocated.
* Always clears the field
* @param label pointer to label object.
*/
static void lv_label_dot_tmp_free(lv_obj_t *label){
lv_label_ext_t * ext = lv_obj_get_ext_attr(label);
if( ext->dot_tmp_alloc && ext->dot_tmp_ptr ){
lv_mem_free(ext->dot_tmp_ptr);
}
ext->dot_tmp_alloc = false;
ext->dot_tmp_ptr = NULL;
}
#endif

View File

@@ -29,8 +29,9 @@ extern "C" {
/*********************
* DEFINES
*********************/
#define LV_LABEL_DOT_NUM 3
#define LV_LABEL_POS_LAST 0xFFFF
#define LV_LABEL_DOT_NUM 3
#define LV_LABEL_POS_LAST 0xFFFF
#define LV_LABEL_TEXT_SEL_OFF 0xFFFF
/**********************
* TYPEDEFS
@@ -62,20 +63,26 @@ typedef struct
/*Inherited from 'base_obj' so no inherited ext.*/ /*Ext. of ancestor*/
/*New data for this type */
char * text; /*Text of the label*/
lv_label_long_mode_t long_mode; /*Determinate what to do with the long texts*/
char dot_tmp[LV_LABEL_DOT_NUM * 4 +
1]; /*Store the character which are replaced by dots (Handled by the library)*/
union{
char * dot_tmp_ptr; /* Pointer to the allocated memory containing the character which are replaced by dots (Handled by the library)*/
char dot_tmp[ sizeof(char *) ]; /* Directly store the characters if <=4 characters */
};
uint16_t dot_end; /*The text end position in dot mode (Handled by the library)*/
uint16_t anim_speed; /*Speed of scroll and roll animation in px/sec unit*/
lv_point_t offset; /*Text draw position offset*/
#if LV_LABEL_TEXT_SEL
uint16_t txt_sel_start; /*Left-most selection character*/
uint16_t txt_sel_end; /*Right-most selection character*/
#endif
lv_label_long_mode_t long_mode : 3; /*Determinate what to do with the long texts*/
uint8_t static_txt : 1; /*Flag to indicate the text is static*/
uint8_t align : 2; /*Align type from 'lv_label_align_t'*/
uint8_t recolor : 1; /*Enable in-line letter re-coloring*/
uint8_t expand : 1; /*Ignore real width (used by the library with LV_LABEL_LONG_ROLL)*/
uint8_t body_draw : 1; /*Draw background body*/
int selection_start; /*Left-most selection character*/
int selection_end; /*Right-most selection character*/
uint8_t dot_tmp_alloc : 1; /*True if dot_tmp has been allocated. False if dot_tmp directly holds up to 4 bytes of characters */
} lv_label_ext_t;
/**********************
@@ -164,6 +171,21 @@ static inline void lv_label_set_style(lv_obj_t * label, const lv_style_t * style
{
lv_obj_set_style(label, style);
}
/**
* @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.
*/
void lv_label_set_text_sel_start( lv_obj_t * label, uint16_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.
*/
void lv_label_set_text_sel_end( lv_obj_t * label, uint16_t index );
/*=====================
* Getter functions
*====================*/
@@ -246,6 +268,21 @@ static inline const lv_style_t * lv_label_get_style(const lv_obj_t * label)
return lv_obj_get_style(label);
}
/**
* @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.
*/
uint16_t lv_label_get_text_sel_start( const lv_obj_t * label );
/**
* @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.
*/
uint16_t lv_label_get_text_sel_end( const lv_obj_t * label );
/*=====================
* Other functions
*====================*/

View File

@@ -1044,13 +1044,23 @@ static void scrl_def_event_cb(lv_obj_t * scrl, lv_event_t event)
{
lv_obj_t * page = lv_obj_get_parent(scrl);
if(event == LV_EVENT_PRESSED || event == LV_EVENT_PRESSING || event == LV_EVENT_PRESS_LOST ||
event == LV_EVENT_RELEASED || event == LV_EVENT_SHORT_CLICKED ||
event == LV_EVENT_LONG_PRESSED || event == LV_EVENT_LONG_PRESSED_REPEAT ||
event == LV_EVENT_LONG_HOVER_IN || event == LV_EVENT_LONG_HOVER_OUT ||
event == LV_EVENT_FOCUSED || event == LV_EVENT_DEFOCUSED) {
/*clang-format off*/
if(event == LV_EVENT_PRESSED ||
event == LV_EVENT_PRESSING ||
event == LV_EVENT_PRESS_LOST ||
event == LV_EVENT_RELEASED ||
event == LV_EVENT_SHORT_CLICKED ||
event == LV_EVENT_CLICKED ||
event == LV_EVENT_LONG_PRESSED ||
event == LV_EVENT_LONG_PRESSED_REPEAT ||
event == LV_EVENT_LONG_HOVER_IN ||
event == LV_EVENT_LONG_HOVER_OUT ||
event == LV_EVENT_FOCUSED ||
event == LV_EVENT_DEFOCUSED)
{
lv_event_send(page, event, lv_event_get_data());
}
/*clang-format on*/
}
/**

View File

@@ -793,11 +793,18 @@ void lv_ta_set_style(lv_obj_t * ta, lv_ta_style_t type, const lv_style_t * style
* @param ta pointer to a text area object
* @param en true or false to enable/disable selection mode
*/
void lv_ta_set_sel_mode(lv_obj_t * ta, bool en)
void lv_ta_set_text_sel(lv_obj_t * ta, bool en)
{
#if LV_LABEL_TEXT_SEL
lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta);
ext->sel_mode = en;
ext->text_sel_en = en;
if(!en) lv_ta_clear_selection(ta);
#else
(void) ta; /*Unused*/
(void) en; /*Unused*/
#endif
}
/*=====================
@@ -942,32 +949,6 @@ const lv_style_t * lv_ta_get_style(const lv_obj_t * ta, lv_ta_style_t type)
return style;
}
/**
* Get the selection index of the text area.
*
* The last character is exclusive (i.e. if the API says that the selection
* ranges from 6 to 7, only character 6 is selected).
* @param ta Text area object
* @param sel_start pointer to int used to hold first selected character
* @param sel_end pointer to int used to hold last selected character
*/
void lv_ta_get_selection(lv_obj_t * ta, int * sel_start, int * sel_end)
{
lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta);
lv_label_ext_t * ext_label = lv_obj_get_ext_attr(ext->label);
/*Force both values to -1 if there is no selection*/
if(ext_label->selection_start == -1 || ext_label->selection_end == -1) {
*sel_start = -1;
*sel_end = -1;
return;
}
*sel_start = ext_label->selection_start;
*sel_end = ext_label->selection_end;
}
/**
* Find whether text is selected or not.
* @param ta Text area object
@@ -975,10 +956,19 @@ void lv_ta_get_selection(lv_obj_t * ta, int * sel_start, int * sel_end)
*/
bool lv_ta_text_is_selected(const lv_obj_t * ta)
{
lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta);
lv_label_ext_t * ext_label = lv_obj_get_ext_attr(ext->label);
#if LV_LABEL_TEXT_SEL
lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta);
return (ext_label->selection_start == -1 || ext_label->selection_end == -1);
if((lv_label_get_text_sel_start(ext->label) == LV_LABEL_TEXT_SEL_OFF ||
lv_label_get_text_sel_end(ext->label) == LV_LABEL_TEXT_SEL_OFF)){
return true;
} else {
return false;
}
#else
(void) ta; /*Unused*/
return false;
#endif
}
/**
@@ -986,11 +976,15 @@ bool lv_ta_text_is_selected(const lv_obj_t * ta)
* @param ta pointer to a text area object
* @return true: selection mode is enabled, false: disabled
*/
bool lv_ta_get_sel_mode(lv_obj_t * ta)
bool lv_ta_get_text_sel_en(lv_obj_t * ta)
{
#if LV_LABEL_TEXT_SEL
lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta);
return ext->sel_mode;
return ext->text_sel_en;
#else
(void) ta; /*Unused*/
return false;
#endif
}
/*=====================
@@ -1003,14 +997,17 @@ bool lv_ta_get_sel_mode(lv_obj_t * ta)
*/
void lv_ta_clear_selection(lv_obj_t * ta)
{
#if LV_LABEL_TEXT_SEL
lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta);
lv_label_ext_t * ext_label = lv_obj_get_ext_attr(ext->label);
if(ext_label->selection_start != -1 || ext_label->selection_end != -1) {
ext_label->selection_start = -1;
ext_label->selection_end = -1;
lv_obj_invalidate(ta);
if(lv_label_get_text_sel_start(ext->label) != LV_LABEL_TEXT_SEL_OFF ||
lv_label_get_text_sel_end(ext->label) != LV_LABEL_TEXT_SEL_OFF){
lv_label_set_text_sel_start(ext->label, LV_LABEL_TEXT_SEL_OFF);
lv_label_set_text_sel_end(ext->label, LV_LABEL_TEXT_SEL_OFF);
}
#else
(void) ta; /*Unused*/
#endif
}
/**
@@ -1182,7 +1179,7 @@ static bool lv_ta_scrollable_design(lv_obj_t * scrl, const lv_area_t * mask, lv_
cur_area.x1 += cur_style.body.padding.left;
cur_area.y1 += cur_style.body.padding.top;
lv_draw_label(&cur_area, mask, &cur_style, opa_scale, letter_buf, LV_TXT_FLAG_NONE, 0,
-1, -1);
LV_LABEL_TEXT_SEL_OFF, LV_LABEL_TEXT_SEL_OFF);
} else if(ext->cursor.type == LV_CURSOR_OUTLINE) {
cur_style.body.opa = LV_OPA_TRANSP;
@@ -1640,18 +1637,12 @@ static void update_cursor_position_on_click(lv_obj_t * ta, lv_signal_t sign,
}
lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta);
lv_label_ext_t * ext_label = lv_obj_get_ext_attr(ext->label);
lv_area_t label_coords;
bool click_outside_label;
uint16_t index_of_char_at_position;
lv_obj_get_coords(ext->label, &label_coords);
lv_point_t point_act, vect_act;
lv_indev_get_point(click_source, &point_act);
lv_indev_get_vect(click_source, &vect_act);
if(point_act.x < 0 || point_act.y < 0) return; /*Ignore event from keypad*/
@@ -1661,6 +1652,12 @@ static void update_cursor_position_on_click(lv_obj_t * ta, lv_signal_t sign,
lv_coord_t label_width = lv_obj_get_width(ext->label);
uint16_t index_of_char_at_position;
#if LV_LABEL_TEXT_SEL
lv_label_ext_t * ext_label = lv_obj_get_ext_attr(ext->label);
bool click_outside_label;
/*Check if the click happened on the left side of the area outside the label*/
if(relative_position.x < 0) {
index_of_char_at_position = 0;
@@ -1675,52 +1672,71 @@ static void update_cursor_position_on_click(lv_obj_t * ta, lv_signal_t sign,
click_outside_label = !lv_label_is_char_under_pos(ext->label, &relative_position);
}
if(ext->sel_mode && !ext->selecting && !click_outside_label && sign == LV_SIGNAL_PRESSED) {
/*Input device just went down. Store the selection start position*/
ext->tmp_sel_start = index_of_char_at_position;
ext->tmp_sel_end = -1;
ext->selecting = 1;
lv_obj_set_drag(lv_page_get_scrl(ta), false);
} else if(ext->selecting && sign == LV_SIGNAL_PRESSING) {
/*Input device may be moving. Store the end position */
ext->tmp_sel_end = index_of_char_at_position;
} else if(ext->selecting && (sign == LV_SIGNAL_PRESS_LOST || sign == LV_SIGNAL_RELEASED)) {
/*Input device is released. Check if anything was selected.*/
lv_obj_set_drag(lv_page_get_scrl(ta), true);
if(ext->text_sel_en) {
if(!ext->text_sel_in_prog && !click_outside_label && sign == LV_SIGNAL_PRESSED) {
/*Input device just went down. Store the selection start position*/
ext->tmp_sel_start = index_of_char_at_position;
ext->tmp_sel_end = LV_LABEL_TEXT_SEL_OFF;
ext->text_sel_in_prog = 1;
lv_obj_set_drag(lv_page_get_scrl(ta), false);
} else if(ext->text_sel_in_prog && sign == LV_SIGNAL_PRESSING) {
/*Input device may be moving. Store the end position */
ext->tmp_sel_end = index_of_char_at_position;
} else if(ext->text_sel_in_prog && (sign == LV_SIGNAL_PRESS_LOST || sign == LV_SIGNAL_RELEASED)) {
/*Input device is released. Check if anything was selected.*/
lv_obj_set_drag(lv_page_get_scrl(ta), true);
}
}
if(ext->selecting || sign == LV_SIGNAL_PRESSED)
if(ext->text_sel_in_prog || sign == LV_SIGNAL_PRESSED)
lv_ta_set_cursor_pos(ta, index_of_char_at_position);
if(ext->selecting) {
if(ext->text_sel_in_prog) {
/*If the selected area has changed then update the real values and*/
/*invalidate the text area.*/
if(ext->tmp_sel_start > ext->tmp_sel_end) {
if(ext_label->selection_start != ext->tmp_sel_end ||
ext_label->selection_end != ext->tmp_sel_start) {
ext_label->selection_start = ext->tmp_sel_end;
ext_label->selection_end = ext->tmp_sel_start;
if(ext_label->txt_sel_start != ext->tmp_sel_end ||
ext_label->txt_sel_end != ext->tmp_sel_start) {
ext_label->txt_sel_start = ext->tmp_sel_end;
ext_label->txt_sel_end = ext->tmp_sel_start;
lv_obj_invalidate(ta);
}
} else if(ext->tmp_sel_start < ext->tmp_sel_end) {
if(ext_label->selection_start != ext->tmp_sel_start ||
ext_label->selection_end != ext->tmp_sel_end) {
ext_label->selection_start = ext->tmp_sel_start;
ext_label->selection_end = ext->tmp_sel_end;
if(ext_label->txt_sel_start != ext->tmp_sel_start ||
ext_label->txt_sel_end != ext->tmp_sel_end) {
ext_label->txt_sel_start = ext->tmp_sel_start;
ext_label->txt_sel_end = ext->tmp_sel_end;
lv_obj_invalidate(ta);
}
} else {
if(ext_label->selection_start != -1 || ext_label->selection_end != -1) {
ext_label->selection_start = -1;
ext_label->selection_end = -1;
if(ext_label->txt_sel_start != LV_LABEL_TEXT_SEL_OFF ||
ext_label->txt_sel_end != LV_LABEL_TEXT_SEL_OFF) {
ext_label->txt_sel_start = LV_LABEL_TEXT_SEL_OFF;
ext_label->txt_sel_end = LV_LABEL_TEXT_SEL_OFF;
lv_obj_invalidate(ta);
}
}
/*Finish selection if necessary */
if(sign == LV_SIGNAL_PRESS_LOST || sign == LV_SIGNAL_RELEASED) {
ext->selecting = 0;
ext->text_sel_in_prog = 0;
}
}
#else
/*Check if the click happened on the left side of the area outside the label*/
if(relative_position.x < 0) {
index_of_char_at_position = 0;
}
/*Check if the click happened on the right side of the area outside the label*/
else if(relative_position.x >= label_width) {
index_of_char_at_position = LV_TA_CURSOR_LAST;
} else {
index_of_char_at_position = lv_label_get_letter_on(ext->label, &relative_position);
}
if(sign == LV_SIGNAL_PRESSED)
lv_ta_set_cursor_pos(ta, index_of_char_at_position);
#endif
}
#endif

View File

@@ -59,8 +59,7 @@ typedef struct
lv_page_ext_t page; /*Ext. of ancestor*/
/*New data for this type */
lv_obj_t * label; /*Label of the text area*/
lv_obj_t * placeholder; /*Place holder label of the text area, only visible if text is an empty
string*/
lv_obj_t * placeholder; /*Place holder label. only visible if text is an empty string*/
char * pwd_tmp; /*Used to store the original text in password mode*/
const char * accapted_chars; /*Only these characters will be accepted. NULL: accept all*/
uint16_t max_length; /*The max. number of characters. 0: no limit*/
@@ -68,21 +67,22 @@ typedef struct
uint8_t one_line : 1; /*One line mode (ignore line breaks)*/
struct
{
const lv_style_t * style; /*Style of the cursor (NULL to use label's style)*/
lv_coord_t valid_x; /*Used when stepping up/down in text area when stepping to a shorter
line. (Handled by the library)*/
uint16_t
pos; /*The current cursor position (0: before 1. letter; 1: before 2. letter etc.)*/
lv_area_t area; /*Cursor area relative to the Text Area*/
uint16_t txt_byte_pos; /*Byte index of the letter after (on) the cursor*/
lv_cursor_type_t type : 4; /*Shape of the cursor*/
uint8_t
state : 1; /*Indicates that the cursor is visible now or not (Handled by the library)*/
const lv_style_t * style; /* Style of the cursor (NULL to use label's style)*/
lv_coord_t valid_x; /* Used when stepping up/down to a shorter line.
* (Used by the library)*/
uint16_t pos; /* The current cursor position
* (0: before 1st letter; 1: before 2nd letter ...)*/
lv_area_t area; /* Cursor area relative to the Text Area*/
uint16_t txt_byte_pos; /* Byte index of the letter after (on) the cursor*/
lv_cursor_type_t type : 4; /* Shape of the cursor*/
uint8_t state : 1; /*Cursor is visible now or not (Handled by the library)*/
} cursor;
int tmp_sel_start; /*Temporary value*/
int tmp_sel_end; /*Temporary value*/
uint8_t selecting : 1; /*User is in process of selecting */
uint8_t sel_mode : 1; /*Text can be selected on this text area*/
#if LV_LABEL_TEXT_SEL
uint16_t tmp_sel_start; /*Temporary value*/
uint16_t tmp_sel_end; /*Temporary value*/
uint8_t text_sel_in_prog : 1; /*User is in process of selecting */
uint8_t text_sel_en : 1; /*Text can be selected on this text area*/
#endif
} lv_ta_ext_t;
enum {
@@ -262,7 +262,7 @@ void lv_ta_set_style(lv_obj_t * ta, lv_ta_style_t type, const lv_style_t * style
* @param ta pointer to a text area object
* @param en true or false to enable/disable selection mode
*/
void lv_ta_set_sel_mode(lv_obj_t * ta, bool en);
void lv_ta_set_text_sel(lv_obj_t * ta, bool en);
/*=====================
* Getter functions
@@ -376,18 +376,6 @@ static inline bool lv_ta_get_edge_flash(lv_obj_t * ta)
*/
const lv_style_t * lv_ta_get_style(const lv_obj_t * ta, lv_ta_style_t type);
/**
* Get the selection index of the text area.
*
* The last character is exclusive (i.e. if the API says that the selection
* ranges from 6 to 7, only character 6 is selected).
* @param ta Text area object
* @param sel_start pointer to int used to hold first selected character
* @param sel_end pointer to int used to hold last selected character
*/
void lv_ta_get_selection(lv_obj_t * ta, int * sel_start, int * sel_end);
/**
* Find whether text is selected or not.
* @param ta Text area object
@@ -400,7 +388,7 @@ bool lv_ta_text_is_selected(const lv_obj_t * ta);
* @param ta pointer to a text area object
* @return true: selection mode is enabled, false: disabled
*/
bool lv_ta_get_sel_mode(lv_obj_t * ta);
bool lv_ta_get_text_sel_en(lv_obj_t * ta);
/*=====================
* Other functions