Merge branch 'dev-6.0' of https://github.com/littlevgl/lvgl into dev-6.0
This commit is contained in:
@@ -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: -)*/
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
*====================*/
|
||||
|
||||
@@ -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*/
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user