2016-09-30 15:29:00 +02:00
/**
* @ file lv_ta . c
*
*/
/*********************
* INCLUDES
* * * * * * * * * * * * * * * * * * * * */
# include "lv_conf.h"
# if USE_LV_TA != 0
# include "lv_ta.h"
2017-08-23 14:39:09 +02:00
# include "../lv_obj/lv_group.h"
2016-10-04 09:45:39 +02:00
# include "../lv_draw/lv_draw.h"
2017-08-23 14:39:09 +02:00
# include "misc/gfx/anim.h"
2017-09-22 09:52:53 +02:00
# include "misc/gfx/text.h"
2016-09-30 15:29:00 +02:00
/*********************
* DEFINES
* * * * * * * * * * * * * * * * * * * * */
2017-01-12 09:49:13 +01:00
/*Test configuration*/
# ifndef LV_TA_MAX_LENGTH
# define LV_TA_MAX_LENGTH 256
# endif
# ifndef LV_TA_CUR_BLINK_TIME
# define LV_TA_CUR_BLINK_TIME 400 /*ms*/
# endif
2017-07-07 16:22:24 +02:00
# ifndef LV_TA_PWD_SHOW_TIME
# define LV_TA_PWD_SHOW_TIME 1500 /*ms*/
# endif
2017-06-26 14:08:29 +02:00
# define LV_TA_DEF_WIDTH (2 * LV_DPI)
# define LV_TA_DEF_HEIGHT (1 * LV_DPI)
2016-09-30 15:29:00 +02:00
/**********************
* TYPEDEFS
* * * * * * * * * * * * * * * * * * * * * */
/**********************
* STATIC PROTOTYPES
* * * * * * * * * * * * * * * * * * * * * */
2016-10-07 11:15:46 +02:00
static bool lv_ta_design ( lv_obj_t * ta , const area_t * mask , lv_design_mode_t mode ) ;
2016-10-07 17:33:35 +02:00
static bool lv_ta_scrling_design ( lv_obj_t * scrling , const area_t * mask , lv_design_mode_t mode ) ;
2017-09-15 10:22:12 +02:00
static void cursor_blink_anim ( lv_obj_t * ta , uint8_t show ) ;
static void pwd_char_hider_anim ( lv_obj_t * ta , int32_t x ) ;
2017-07-07 16:22:24 +02:00
static void pwd_char_hider ( lv_obj_t * ta ) ;
2016-10-07 11:15:46 +02:00
static void lv_ta_save_valid_cursor_x ( lv_obj_t * ta ) ;
2016-09-30 15:29:00 +02:00
/**********************
* STATIC VARIABLES
* * * * * * * * * * * * * * * * * * * * * */
lv_design_f_t ancestor_design_f ;
2017-01-01 22:56:09 +01:00
lv_design_f_t scrl_design_f ;
2016-09-30 15:29:00 +02:00
/**********************
* MACROS
* * * * * * * * * * * * * * * * * * * * * */
/**********************
* GLOBAL FUNCTIONS
* * * * * * * * * * * * * * * * * * * * * */
/*-----------------
* Create function
* - - - - - - - - - - - - - - - - - */
/**
* Create a text area objects
2016-10-07 11:15:46 +02:00
* @ param par pointer to an object , it will be the parent of the new text area
* @ param copy pointer to a text area object , if not NULL then the new object will be copied from it
2016-09-30 15:29:00 +02:00
* @ return pointer to the created text area
*/
2016-10-07 11:15:46 +02:00
lv_obj_t * lv_ta_create ( lv_obj_t * par , lv_obj_t * copy )
2016-09-30 15:29:00 +02:00
{
/*Create the ancestor object*/
2016-10-07 11:15:46 +02:00
lv_obj_t * new_ta = lv_page_create ( par , copy ) ;
dm_assert ( new_ta ) ;
2016-09-30 15:29:00 +02:00
/*Allocate the object type specific extended data*/
2016-10-07 11:15:46 +02:00
lv_ta_ext_t * ext = lv_obj_alloc_ext ( new_ta , sizeof ( lv_ta_ext_t ) ) ;
dm_assert ( ext ) ;
2017-04-21 09:15:39 +02:00
ext - > cursor_show = 1 ;
ext - > cursor_state = 0 ;
2017-07-07 16:22:24 +02:00
ext - > pwd_mode = 0 ;
ext - > pwd_tmp = NULL ;
2017-09-15 10:22:12 +02:00
ext - > cursor_style = NULL ;
2017-01-02 14:10:32 +01:00
ext - > cursor_pos = 0 ;
2017-09-15 10:22:12 +02:00
ext - > cursor_type = LV_TA_CURSOR_LINE ;
2017-01-02 14:10:32 +01:00
ext - > cursor_valid_x = 0 ;
ext - > label = NULL ;
2016-09-30 15:29:00 +02:00
2017-01-02 14:10:32 +01:00
if ( ancestor_design_f = = NULL ) ancestor_design_f = lv_obj_get_design_f ( new_ta ) ;
if ( scrl_design_f = = NULL ) scrl_design_f = lv_obj_get_design_f ( ext - > page . scrl ) ;
2016-09-30 15:29:00 +02:00
2016-10-07 11:15:46 +02:00
lv_obj_set_signal_f ( new_ta , lv_ta_signal ) ;
lv_obj_set_design_f ( new_ta , lv_ta_design ) ;
2016-09-30 15:29:00 +02:00
/*Init the new text area object*/
2016-10-07 11:15:46 +02:00
if ( copy = = NULL ) {
ext - > label = lv_label_create ( new_ta , NULL ) ;
2016-12-15 10:31:30 +01:00
2017-01-01 22:56:09 +01:00
lv_obj_set_design_f ( ext - > page . scrl , lv_ta_scrling_design ) ;
2016-10-20 16:35:03 +02:00
lv_label_set_long_mode ( ext - > label , LV_LABEL_LONG_BREAK ) ;
2017-09-22 09:52:53 +02:00
lv_label_set_text ( ext - > label , " Text.area " ) ;
2016-10-07 11:15:46 +02:00
lv_page_glue_obj ( ext - > label , true ) ;
2016-12-18 22:07:03 +01:00
lv_obj_set_click ( ext - > label , false ) ;
2017-04-13 13:34:57 +02:00
lv_obj_set_style ( new_ta , lv_style_get ( LV_STYLE_PRETTY , NULL ) ) ;
lv_page_set_sb_mode ( new_ta , LV_PAGE_SB_MODE_AUTO ) ;
lv_obj_set_style ( lv_page_get_scrl ( new_ta ) , lv_style_get ( LV_STYLE_TRANSP_TIGHT , NULL ) ) ;
2017-01-02 15:00:21 +01:00
lv_obj_set_size ( new_ta , LV_TA_DEF_WIDTH , LV_TA_DEF_HEIGHT ) ;
2016-09-30 15:29:00 +02:00
}
/*Copy an existing object*/
else {
2017-01-01 22:56:09 +01:00
lv_obj_set_design_f ( ext - > page . scrl , lv_ta_scrling_design ) ;
2016-10-07 11:15:46 +02:00
lv_ta_ext_t * copy_ext = lv_obj_get_ext ( copy ) ;
ext - > label = lv_label_create ( new_ta , copy_ext - > label ) ;
2017-06-07 12:38:43 +02:00
ext - > cursor_show = copy_ext - > cursor_show ;
2017-07-28 14:26:51 +02:00
ext - > pwd_mode = copy_ext - > pwd_mode ;
2016-10-07 11:15:46 +02:00
lv_page_glue_obj ( ext - > label , true ) ;
2016-09-30 15:29:00 +02:00
2017-01-08 13:06:41 +01:00
/*Refresh the style with new signal function*/
lv_obj_refr_style ( new_ta ) ;
2016-09-30 15:29:00 +02:00
}
2016-12-15 10:31:30 +01:00
/*Create a cursor blinker animation*/
anim_t a ;
a . var = new_ta ;
2017-07-07 16:22:24 +02:00
a . fp = ( anim_fp_t ) cursor_blink_anim ;
2016-12-15 10:31:30 +01:00
a . time = LV_TA_CUR_BLINK_TIME ;
a . act_time = 0 ;
a . end_cb = NULL ;
2017-09-15 10:22:12 +02:00
a . start = 1 ;
a . end = 0 ;
2016-12-15 10:31:30 +01:00
a . repeat = 1 ;
a . repeat_pause = 0 ;
a . playback = 1 ;
a . playback_pause = 0 ;
a . path = anim_get_path ( ANIM_PATH_STEP ) ;
anim_create ( & a ) ;
2016-10-07 11:15:46 +02:00
return new_ta ;
2016-09-30 15:29:00 +02:00
}
/**
* Signal function of the text area
2016-10-07 11:15:46 +02:00
* @ param ta pointer to a text area object
2016-09-30 15:29:00 +02:00
* @ 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
*/
2016-10-07 11:15:46 +02:00
bool lv_ta_signal ( lv_obj_t * ta , lv_signal_t sign , void * param )
2016-09-30 15:29:00 +02:00
{
bool valid ;
/* Include the ancient signal function */
2016-10-07 11:15:46 +02:00
valid = lv_page_signal ( ta , sign , param ) ;
2016-09-30 15:29:00 +02:00
/* The object can be deleted so check its validity and then
* make the object specific signal handling */
if ( valid ! = false ) {
2016-10-07 11:15:46 +02:00
lv_ta_ext_t * ext = lv_obj_get_ext ( ta ) ;
2017-07-20 12:26:34 +02:00
if ( sign = = LV_SIGNAL_CLEANUP ) {
2017-08-16 11:38:26 +02:00
if ( ext - > pwd_tmp ! = NULL ) dm_free ( ext - > pwd_tmp ) ;
/* (The created label will be deleted automatically) */
2017-07-20 12:26:34 +02:00
} else if ( sign = = LV_SIGNAL_STYLE_CHG ) {
if ( ext - > label ) {
2017-09-15 10:22:12 +02:00
lv_obj_t * scrl = lv_page_get_scrl ( ta ) ;
lv_style_t * style_scrl = lv_obj_get_style ( scrl ) ;
lv_obj_set_width ( ext - > label , lv_obj_get_width ( scrl ) - 2 * style_scrl - > hpad ) ;
lv_obj_set_pos ( ext - > label , style_scrl - > hpad , style_scrl - > vpad ) ;
2017-07-20 12:26:34 +02:00
lv_label_set_text ( ext - > label , NULL ) ;
}
} else if ( sign = = LV_SIGNAL_CORD_CHG ) {
2016-10-04 09:45:39 +02:00
/*Set the label width according to the text area width*/
2017-09-15 10:22:12 +02:00
if ( ext - > label ) {
2017-08-16 11:28:04 +02:00
if ( lv_obj_get_width ( ta ) ! = area_get_width ( param ) | |
lv_obj_get_height ( ta ) ! = area_get_height ( param ) ) {
2017-09-15 10:22:12 +02:00
lv_obj_t * scrl = lv_page_get_scrl ( ta ) ;
lv_style_t * style_scrl = lv_obj_get_style ( scrl ) ;
lv_obj_set_width ( ext - > label , lv_obj_get_width ( scrl ) - 2 * style_scrl - > hpad ) ;
lv_obj_set_pos ( ext - > label , style_scrl - > hpad , style_scrl - > vpad ) ;
2017-09-11 10:28:14 +02:00
lv_label_set_text ( ext - > label , NULL ) ; /*Refresh the label*/
2017-08-16 11:28:04 +02:00
}
2017-07-20 12:26:34 +02:00
}
2017-07-25 09:02:21 +02:00
} else if ( sign = = LV_SIGNAL_CONTROLL ) {
char c = * ( ( char * ) param ) ;
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 ) ;
}
2017-07-20 12:26:34 +02:00
}
2016-09-30 15:29:00 +02:00
}
2017-07-25 09:02:21 +02:00
return valid ;
2016-09-30 15:29:00 +02:00
}
/*=====================
* Setter functions
* = = = = = = = = = = = = = = = = = = = = */
2016-10-04 09:45:39 +02:00
/**
* Insert a character to the current cursor position
2016-10-07 11:15:46 +02:00
* @ param ta pointer to a text area object
2016-10-04 09:45:39 +02:00
* @ param c a character
*/
2016-10-07 11:15:46 +02:00
void lv_ta_add_char ( lv_obj_t * ta , char c )
2016-09-30 15:29:00 +02:00
{
2016-10-07 11:15:46 +02:00
lv_ta_ext_t * ext = lv_obj_get_ext ( ta ) ;
2016-10-01 00:25:10 +02:00
2016-10-07 11:15:46 +02:00
const char * label_txt = lv_label_get_text ( ext - > label ) ;
2016-10-01 00:25:10 +02:00
2017-01-02 15:00:21 +01:00
/*Test the new length: txt length + 1 (closing'\0') + 1 (c character)*/
if ( ( strlen ( label_txt ) + 2 ) > LV_TA_MAX_LENGTH ) return ;
2017-07-07 16:22:24 +02:00
if ( ext - > pwd_mode ! = 0 ) pwd_char_hider ( ta ) ; /*Make sure all the current text contains only '*'*/
2017-01-02 15:00:21 +01:00
2017-09-22 09:52:53 +02:00
uint32_t cur_pos ;
# if TXT_UTF8 == 0
cur_pos = ext - > cursor_pos ;
# else
cur_pos = txt_utf8_get_id ( label_txt , ext - > cursor_pos ) ;
# endif
char buf [ LV_TA_MAX_LENGTH ] ;
2017-01-02 15:00:21 +01:00
/*Insert the character*/
2017-09-22 09:52:53 +02:00
memcpy ( buf , label_txt , cur_pos ) ;
buf [ cur_pos ] = c ;
memcpy ( buf + cur_pos + 1 , label_txt + cur_pos , strlen ( label_txt ) - cur_pos + 1 ) ;
2016-10-01 00:25:10 +02:00
2016-10-04 09:45:39 +02:00
/*Refresh the label*/
2016-10-07 11:15:46 +02:00
lv_label_set_text ( ext - > label , buf ) ;
2016-09-30 15:29:00 +02:00
2017-07-07 16:22:24 +02:00
if ( ext - > pwd_mode ! = 0 ) {
2017-09-22 09:52:53 +02:00
# if TXT_UTF8 != 0
cur_pos = txt_utf8_get_id ( ext - > pwd_tmp , ext - > cursor_pos ) ; /*Noral text contains '*', pwd_tmp normal UTF-8 letter, so the cursor points to a different byte*/
# endif
2017-08-29 15:08:18 +02:00
ext - > pwd_tmp = dm_realloc ( ext - > pwd_tmp , strlen ( ext - > pwd_tmp ) + 2 ) ; /*+2: the new char + \0 */
dm_assert ( ext - > pwd_tmp ) ;
2017-09-22 09:52:53 +02:00
memcpy ( buf , ext - > pwd_tmp , cur_pos ) ;
buf [ cur_pos ] = c ;
memcpy ( buf + cur_pos + 1 , ext - > pwd_tmp + cur_pos , strlen ( ext - > pwd_tmp ) - cur_pos + 1 ) ;
2017-08-29 15:08:18 +02:00
strcpy ( ext - > pwd_tmp , buf ) ;
2017-07-07 16:22:24 +02:00
anim_t a ;
a . var = ta ;
a . fp = ( anim_fp_t ) pwd_char_hider_anim ;
a . time = LV_TA_PWD_SHOW_TIME ;
a . act_time = 0 ;
a . end_cb = ( anim_cb_t ) pwd_char_hider ;
a . start = 0 ;
a . end = 1 ;
a . repeat = 0 ;
a . repeat_pause = 0 ;
a . playback = 0 ;
a . playback_pause = 0 ;
a . path = anim_get_path ( ANIM_PATH_STEP ) ;
anim_create ( & a ) ;
}
2017-08-29 15:08:18 +02:00
/*Move the cursor after the new character*/
lv_ta_set_cursor_pos ( ta , lv_ta_get_cursor_pos ( ta ) + 1 ) ;
/*It is a valid x step so save it*/
lv_ta_save_valid_cursor_x ( ta ) ;
2016-10-01 00:25:10 +02:00
}
2016-10-04 09:45:39 +02:00
/**
* Insert a text to the current cursor position
2016-10-07 11:15:46 +02:00
* @ param ta pointer to a text area object
2016-10-04 09:45:39 +02:00
* @ param txt a ' \0 ' terminated string to insert
*/
2016-10-07 11:15:46 +02:00
void lv_ta_add_text ( lv_obj_t * ta , const char * txt )
2016-10-01 00:25:10 +02:00
{
2016-10-07 11:15:46 +02:00
lv_ta_ext_t * ext = lv_obj_get_ext ( ta ) ;
2016-10-01 00:25:10 +02:00
2016-10-07 11:15:46 +02:00
const char * label_txt = lv_label_get_text ( ext - > label ) ;
2017-01-02 15:00:21 +01:00
uint16_t label_len = strlen ( label_txt ) ;
uint16_t txt_len = strlen ( txt ) ;
/*Test the new length (+ 1 for the closing '\0')*/
if ( ( label_len + txt_len + 1 ) > LV_TA_MAX_LENGTH ) return ;
2017-07-07 16:22:24 +02:00
if ( ext - > pwd_mode ! = 0 ) pwd_char_hider ( ta ) ; /*Make sure all the current text contains only '*'*/
2017-01-02 15:00:21 +01:00
/*Insert the text*/
char buf [ LV_TA_MAX_LENGTH ] ;
2016-10-01 00:25:10 +02:00
2017-09-22 09:52:53 +02:00
uint32_t cur_pos ;
# if TXT_UTF8 == 0
cur_pos = ext - > cursor_pos ;
# else
cur_pos = txt_utf8_get_id ( label_txt , ext - > cursor_pos ) ;
# endif
memcpy ( buf , label_txt , cur_pos ) ;
memcpy ( buf + cur_pos , txt , txt_len ) ;
memcpy ( buf + cur_pos + txt_len , label_txt + cur_pos , label_len - cur_pos + 1 ) ;
2016-10-01 00:25:10 +02:00
2016-10-04 09:45:39 +02:00
/*Refresh the label*/
2016-10-07 11:15:46 +02:00
lv_label_set_text ( ext - > label , buf ) ;
2016-10-01 00:25:10 +02:00
2017-07-07 16:22:24 +02:00
if ( ext - > pwd_mode ! = 0 ) {
2017-08-29 15:08:18 +02:00
ext - > pwd_tmp = dm_realloc ( ext - > pwd_tmp , strlen ( ext - > pwd_tmp ) + txt_len + 1 ) ;
dm_assert ( ext - > pwd_tmp ) ;
memcpy ( buf , ext - > pwd_tmp , ext - > cursor_pos ) ;
2017-09-22 09:52:53 +02:00
memcpy ( buf + cur_pos , txt , txt_len ) ;
memcpy ( buf + cur_pos + txt_len , ext - > pwd_tmp + ext - > cursor_pos , label_len - ext - > cursor_pos + 1 ) ;
2017-08-29 15:08:18 +02:00
strcpy ( ext - > pwd_tmp , buf ) ;
2017-07-07 16:22:24 +02:00
anim_t a ;
a . var = ta ;
a . fp = ( anim_fp_t ) pwd_char_hider_anim ;
a . time = LV_TA_PWD_SHOW_TIME ;
a . act_time = 0 ;
a . end_cb = ( anim_cb_t ) pwd_char_hider ;
a . start = 0 ;
a . end = 1 ;
a . repeat = 0 ;
a . repeat_pause = 0 ;
a . playback = 0 ;
a . playback_pause = 0 ;
a . path = anim_get_path ( ANIM_PATH_STEP ) ;
anim_create ( & a ) ;
}
2017-08-29 15:08:18 +02:00
/*Move the cursor after the new text*/
lv_ta_set_cursor_pos ( ta , lv_ta_get_cursor_pos ( ta ) + txt_len ) ;
/*It is a valid x step so save it*/
lv_ta_save_valid_cursor_x ( ta ) ;
2016-10-01 00:25:10 +02:00
}
2016-12-15 10:31:30 +01:00
/**
2016-12-18 22:07:03 +01:00
* Set the text of a text area
2016-12-15 10:31:30 +01:00
* @ param ta pointer to a text area
* @ param txt pointer to the text
*/
void lv_ta_set_text ( lv_obj_t * ta , const char * txt )
{
lv_ta_ext_t * ext = lv_obj_get_ext ( ta ) ;
lv_label_set_text ( ext - > label , txt ) ;
lv_ta_set_cursor_pos ( ta , LV_TA_CUR_LAST ) ;
2017-08-16 11:28:04 +02:00
/*Don't let 'width == 0' because cursor will not be visible*/
if ( lv_obj_get_width ( ext - > label ) = = 0 ) {
lv_style_t * style = lv_obj_get_style ( ext - > label ) ;
2017-09-15 10:22:12 +02:00
lv_obj_set_width ( ext - > label , font_get_width ( style - > font , ' ' ) ) ;
2017-08-16 11:28:04 +02:00
}
2016-12-15 10:31:30 +01:00
/*It is a valid x step so save it*/
lv_ta_save_valid_cursor_x ( ta ) ;
2017-07-07 16:22:24 +02:00
if ( ext - > pwd_mode ! = 0 ) {
2017-08-29 15:08:18 +02:00
ext - > pwd_tmp = dm_realloc ( ext - > pwd_tmp , strlen ( txt ) + 1 ) ;
strcpy ( ext - > pwd_tmp , txt ) ;
2017-07-07 16:22:24 +02:00
anim_t a ;
a . var = ta ;
a . fp = ( anim_fp_t ) pwd_char_hider_anim ;
a . time = LV_TA_PWD_SHOW_TIME ;
a . act_time = 0 ;
a . end_cb = ( anim_cb_t ) pwd_char_hider ;
a . start = 0 ;
a . end = 1 ;
a . repeat = 0 ;
a . repeat_pause = 0 ;
a . playback = 0 ;
a . playback_pause = 0 ;
a . path = anim_get_path ( ANIM_PATH_STEP ) ;
anim_create ( & a ) ;
}
2016-12-15 10:31:30 +01:00
}
2016-10-04 09:45:39 +02:00
/**
* Delete a the left character from the current cursor position
2016-10-07 11:15:46 +02:00
* @ param ta pointer to a text area object
2016-10-04 09:45:39 +02:00
*/
2016-10-07 11:15:46 +02:00
void lv_ta_del ( lv_obj_t * ta )
2016-10-01 00:25:10 +02:00
{
2016-10-07 11:15:46 +02:00
lv_ta_ext_t * ext = lv_obj_get_ext ( ta ) ;
uint16_t cur_pos = ext - > cursor_pos ;
2016-10-01 00:25:10 +02:00
if ( cur_pos = = 0 ) return ;
2016-10-04 09:45:39 +02:00
/*Delete a character*/
2016-10-01 00:25:10 +02:00
char buf [ LV_TA_MAX_LENGTH ] ;
2016-10-07 11:15:46 +02:00
const char * label_txt = lv_label_get_text ( ext - > label ) ;
2016-10-01 00:25:10 +02:00
uint16_t label_len = strlen ( label_txt ) ;
memcpy ( buf , label_txt , cur_pos - 1 ) ;
memcpy ( buf + cur_pos - 1 , label_txt + cur_pos , label_len - cur_pos + 1 ) ;
2016-10-04 09:45:39 +02:00
/*Refresh the label*/
2016-10-07 11:15:46 +02:00
lv_label_set_text ( ext - > label , buf ) ;
2017-08-16 11:28:04 +02:00
/*Don't let 'width == 0' because 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 , style - > line_width ) ;
}
2016-10-01 00:25:10 +02:00
2017-09-03 16:09:03 +02:00
if ( ext - > pwd_mode ! = 0 ) {
ext - > pwd_tmp = dm_realloc ( ext - > pwd_tmp , strlen ( buf ) ) ;
dm_assert ( ext - > pwd_tmp ) ;
strcpy ( ext - > pwd_tmp , buf ) ;
}
2016-10-04 09:45:39 +02:00
/*Move the cursor to the place of the deleted character*/
2016-10-07 11:15:46 +02:00
lv_ta_set_cursor_pos ( ta , lv_ta_get_cursor_pos ( ta ) - 1 ) ;
2016-10-04 09:45:39 +02:00
/*It is a valid x step so save it*/
2016-10-07 11:15:46 +02:00
lv_ta_save_valid_cursor_x ( ta ) ;
2016-10-01 00:25:10 +02:00
}
2016-12-15 10:31:30 +01:00
2016-10-04 09:45:39 +02:00
/**
* Set the cursor position
2016-10-07 11:15:46 +02:00
* @ param obj pointer to a text area object
2016-10-04 09:45:39 +02:00
* @ param pos the new cursor position in character index
2016-12-15 10:31:30 +01:00
* < 0 : index from the end of the text
* LV_TA_CUR_LAST : go after the last character
2016-10-04 09:45:39 +02:00
*/
2016-12-15 10:31:30 +01:00
void lv_ta_set_cursor_pos ( lv_obj_t * ta , int16_t pos )
2016-10-01 00:25:10 +02:00
{
2016-10-07 11:15:46 +02:00
lv_ta_ext_t * ext = lv_obj_get_ext ( ta ) ;
2017-04-13 10:20:35 +02:00
lv_obj_t * scrl = lv_page_get_scrl ( ta ) ;
lv_style_t * style_scrl = lv_obj_get_style ( scrl ) ;
2017-09-22 09:52:53 +02:00
uint16_t len = txt_len ( lv_label_get_text ( ext - > label ) ) ;
2016-10-04 09:45:39 +02:00
2017-09-22 09:52:53 +02:00
if ( pos < 0 ) pos = len + pos ;
2016-12-15 10:31:30 +01:00
2017-09-22 09:52:53 +02:00
if ( pos > len | | pos = = LV_TA_CUR_LAST ) pos = len ;
2016-10-04 09:45:39 +02:00
2016-10-07 11:15:46 +02:00
ext - > cursor_pos = pos ;
2016-10-04 09:45:39 +02:00
/*Position the label to make the cursor visible*/
2016-10-07 11:15:46 +02:00
lv_obj_t * label_par = lv_obj_get_parent ( ext - > label ) ;
2016-10-04 09:45:39 +02:00
point_t cur_pos ;
2017-04-13 10:20:35 +02:00
lv_style_t * style = lv_obj_get_style ( ta ) ;
const font_t * font_p = style - > font ;
2016-12-30 21:44:41 +01:00
area_t label_cords ;
area_t ta_cords ;
2016-10-07 11:15:46 +02:00
lv_label_get_letter_pos ( ext - > label , pos , & cur_pos ) ;
2016-12-30 21:44:41 +01:00
lv_obj_get_cords ( ta , & ta_cords ) ;
lv_obj_get_cords ( ext - > label , & label_cords ) ;
2016-10-04 09:45:39 +02:00
/*Check the top*/
2016-10-07 11:15:46 +02:00
if ( lv_obj_get_y ( label_par ) + cur_pos . y < 0 ) {
lv_obj_set_y ( label_par , - cur_pos . y ) ;
2016-10-04 09:45:39 +02:00
}
/*Check the bottom*/
2017-04-21 09:15:39 +02:00
cord_t font_h = font_get_height ( font_p ) > > FONT_ANTIALIAS ;
2017-04-13 10:20:35 +02:00
if ( label_cords . y1 + cur_pos . y + font_h + style_scrl - > vpad > ta_cords . y2 ) {
2016-10-07 11:15:46 +02:00
lv_obj_set_y ( label_par , - ( cur_pos . y - lv_obj_get_height ( ta ) +
2017-04-13 10:20:35 +02:00
font_h + 2 * style_scrl - > vpad ) ) ;
2016-10-04 09:45:39 +02:00
}
2017-08-16 11:28:04 +02:00
/*Check the left (use the font_h as general unit)*/
if ( lv_obj_get_x ( label_par ) + cur_pos . x < font_h ) {
lv_obj_set_x ( label_par , - cur_pos . x + font_h ) ;
}
/*Check the right (use the font_h as general unit)*/
if ( label_cords . x1 + cur_pos . x + font_h + style_scrl - > hpad > ta_cords . x2 ) {
lv_obj_set_x ( label_par , - ( cur_pos . x - lv_obj_get_width ( ta ) +
font_h + 2 * style_scrl - > hpad ) ) ;
}
2016-09-30 15:29:00 +02:00
2017-09-22 09:52:53 +02:00
/*Reset cursor blink animation*/
2017-09-15 10:22:12 +02:00
anim_t a ;
a . var = ta ;
a . fp = ( anim_fp_t ) cursor_blink_anim ;
a . time = LV_TA_CUR_BLINK_TIME ;
a . act_time = 0 ;
a . end_cb = NULL ;
a . start = 1 ;
a . end = 0 ;
a . repeat = 1 ;
a . repeat_pause = 0 ;
a . playback = 1 ;
a . playback_pause = 0 ;
a . path = anim_get_path ( ANIM_PATH_STEP ) ;
anim_create ( & a ) ;
2016-10-07 11:15:46 +02:00
lv_obj_inv ( ta ) ;
2016-09-30 15:29:00 +02:00
}
2016-10-04 09:45:39 +02:00
/**
* Move the cursor one character right
2016-10-07 11:15:46 +02:00
* @ param ta pointer to a text area object
2016-10-04 09:45:39 +02:00
*/
2016-10-07 11:15:46 +02:00
void lv_ta_cursor_right ( lv_obj_t * ta )
2016-10-04 09:45:39 +02:00
{
2016-10-07 11:15:46 +02:00
uint16_t cp = lv_ta_get_cursor_pos ( ta ) ;
2016-10-04 09:45:39 +02:00
cp + + ;
2016-10-07 11:15:46 +02:00
lv_ta_set_cursor_pos ( ta , cp ) ;
2016-10-04 09:45:39 +02:00
/*It is a valid x step so save it*/
2016-10-07 11:15:46 +02:00
lv_ta_save_valid_cursor_x ( ta ) ;
2016-10-04 09:45:39 +02:00
}
/**
* Move the cursor one character left
2016-10-07 11:15:46 +02:00
* @ param ta pointer to a text area object
2016-10-04 09:45:39 +02:00
*/
2016-10-07 11:15:46 +02:00
void lv_ta_cursor_left ( lv_obj_t * ta )
2016-10-04 09:45:39 +02:00
{
2016-10-07 11:15:46 +02:00
uint16_t cp = lv_ta_get_cursor_pos ( ta ) ;
2016-10-04 09:45:39 +02:00
if ( cp > 0 ) {
cp - - ;
2016-10-07 11:15:46 +02:00
lv_ta_set_cursor_pos ( ta , cp ) ;
2016-10-04 09:45:39 +02:00
/*It is a valid x step so save it*/
2016-10-07 11:15:46 +02:00
lv_ta_save_valid_cursor_x ( ta ) ;
2016-10-04 09:45:39 +02:00
}
}
/**
* Move the cursor one line down
2016-10-07 11:15:46 +02:00
* @ param ta pointer to a text area object
2016-10-04 09:45:39 +02:00
*/
2016-10-07 11:15:46 +02:00
void lv_ta_cursor_down ( lv_obj_t * ta )
2016-10-01 00:25:10 +02:00
{
2016-10-07 11:15:46 +02:00
lv_ta_ext_t * ext = lv_obj_get_ext ( ta ) ;
2016-10-01 00:25:10 +02:00
point_t pos ;
2016-10-04 09:45:39 +02:00
/*Get the position of the current letter*/
2016-10-07 11:15:46 +02:00
lv_label_get_letter_pos ( ext - > label , lv_ta_get_cursor_pos ( ta ) , & pos ) ;
2016-10-01 00:25:10 +02:00
2016-10-04 09:45:39 +02:00
/*Increment the y with one line and keep the valid x*/
2017-04-13 10:20:35 +02:00
lv_style_t * label_style = lv_obj_get_style ( ext - > label ) ;
2017-04-10 11:33:38 +02:00
const font_t * font_p = label_style - > font ;
2017-04-21 09:15:39 +02:00
cord_t font_h = font_get_height ( font_p ) > > FONT_ANTIALIAS ;
2017-03-20 07:07:05 +01:00
pos . y + = font_h + label_style - > line_space + 1 ;
2016-10-07 11:15:46 +02:00
pos . x = ext - > cursor_valid_x ;
2016-10-01 00:25:10 +02:00
2016-10-04 09:45:39 +02:00
/*Do not go below he last line*/
2016-10-07 11:15:46 +02:00
if ( pos . y < lv_obj_get_height ( ext - > label ) ) {
2016-10-04 09:45:39 +02:00
/*Get the letter index on the new cursor position and set it*/
2016-10-07 11:15:46 +02:00
uint16_t new_cur_pos = lv_label_get_letter_on ( ext - > label , & pos ) ;
lv_ta_set_cursor_pos ( ta , new_cur_pos ) ;
2016-10-04 09:45:39 +02:00
}
2016-10-01 00:25:10 +02:00
}
2016-10-04 09:45:39 +02:00
/**
* Move the cursor one line up
2016-10-07 11:15:46 +02:00
* @ param ta pointer to a text area object
2016-10-04 09:45:39 +02:00
*/
2016-10-07 11:15:46 +02:00
void lv_ta_cursor_up ( lv_obj_t * ta )
2016-10-01 00:25:10 +02:00
{
2016-10-07 11:15:46 +02:00
lv_ta_ext_t * ext = lv_obj_get_ext ( ta ) ;
2016-10-01 00:25:10 +02:00
point_t pos ;
2016-10-04 09:45:39 +02:00
/*Get the position of the current letter*/
2016-10-07 11:15:46 +02:00
lv_label_get_letter_pos ( ext - > label , lv_ta_get_cursor_pos ( ta ) , & pos ) ;
2016-10-01 00:25:10 +02:00
2016-10-04 09:45:39 +02:00
/*Decrement the y with one line and keep the valid x*/
2017-04-13 10:20:35 +02:00
lv_style_t * label_style = lv_obj_get_style ( ext - > label ) ;
2017-04-10 11:33:38 +02:00
const font_t * font = label_style - > font ;
2017-04-21 09:15:39 +02:00
cord_t font_h = font_get_height ( font ) > > FONT_ANTIALIAS ;
2017-03-20 07:07:05 +01:00
pos . y - = font_h + label_style - > line_space - 1 ;
2016-10-07 11:15:46 +02:00
pos . x = ext - > cursor_valid_x ;
2016-10-01 00:25:10 +02:00
2016-10-04 09:45:39 +02:00
/*Get the letter index on the new cursor position and set it*/
2016-10-07 11:15:46 +02:00
uint16_t new_cur_pos = lv_label_get_letter_on ( ext - > label , & pos ) ;
lv_ta_set_cursor_pos ( ta , new_cur_pos ) ;
2016-10-01 00:25:10 +02:00
}
2017-04-13 10:20:35 +02:00
2017-04-21 09:15:39 +02:00
/**
2017-07-07 16:22:24 +02:00
* Set the cursor visibility .
2017-04-21 09:15:39 +02:00
* @ param ta pointer to a text area object
* @ return show true : show the cursor and blink it , false : hide cursor
*/
void lv_ta_set_cursor_show ( lv_obj_t * ta , bool show )
{
lv_ta_ext_t * ext = lv_obj_get_ext ( ta ) ;
ext - > cursor_show = show = = false ? 0 : 1 ;
2017-08-23 14:19:42 +02:00
ext - > cursor_state = 0 ;
lv_obj_inv ( ta ) ;
2017-04-21 09:15:39 +02:00
}
2017-09-15 10:22:12 +02:00
/**
* Set the cursor type .
* @ param ta pointer to a text area object
* @ param cur_type : element of ' lv_ta_cursor_type_t '
*/
void lv_ta_set_cursor_type ( lv_obj_t * ta , lv_ta_cursor_type_t cur_type )
{
lv_ta_ext_t * ext = lv_obj_get_ext ( ta ) ;
ext - > cursor_type = cur_type ;
lv_obj_inv ( ta ) ;
}
/**
* Set the style of the cursor ( NULL to use label ' s style )
* @ param ta pointer to a text area object
* @ param style pointer to the new cursor style
*/
void lv_ta_set_cursor_style ( lv_obj_t * ta , lv_style_t * style )
{
lv_ta_ext_t * ext = lv_obj_get_ext ( ta ) ;
ext - > cursor_style = style ;
lv_obj_inv ( ta ) ;
}
2017-07-07 16:22:24 +02:00
/**
* Enable / Disable password mode
* @ param ta ointer to a text area object
* @ param en true : enable , false : disable
*/
void lv_ta_set_pwd_mode ( lv_obj_t * ta , bool en )
{
lv_ta_ext_t * ext = lv_obj_get_ext ( ta ) ;
/*Pwd mode is now enabled*/
if ( ext - > pwd_mode = = 0 & & en ! = false ) {
char * txt = lv_label_get_text ( ext - > label ) ;
2017-09-22 09:52:53 +02:00
uint16_t len = strlen ( txt ) ;
ext - > pwd_tmp = dm_alloc ( len + 1 ) ;
2017-07-07 16:22:24 +02:00
strcpy ( ext - > pwd_tmp , txt ) ;
uint16_t i ;
2017-09-22 09:52:53 +02:00
for ( i = 0 ; i < len ; i + + ) {
2017-07-07 16:22:24 +02:00
txt [ i ] = ' * ' ; /*All char to '*'*/
}
2017-09-22 09:52:53 +02:00
txt [ i ] = ' \0 ' ;
2017-07-07 16:22:24 +02:00
lv_label_set_text ( ext - > label , NULL ) ;
}
/*Pwd mode is now disabled*/
else if ( ext - > pwd_mode = = 1 & & en = = false ) {
lv_label_set_text ( ext - > label , ext - > pwd_tmp ) ;
dm_free ( ext - > pwd_tmp ) ;
ext - > pwd_tmp = NULL ;
}
ext - > pwd_mode = en = = false ? 0 : 1 ;
}
2017-08-16 11:28:04 +02:00
/**
* Configure the text area to one line or back to normal
* @ param ta pointer to a Text area object
* @ param en true : one line , false : normal
*/
void lv_ta_set_one_line ( lv_obj_t * ta , bool en )
{
if ( en ! = false ) {
lv_ta_ext_t * ext = lv_obj_get_ext ( ta ) ;
lv_style_t * style_ta = lv_obj_get_style ( ta ) ;
lv_style_t * style_label = lv_obj_get_style ( ext - > label ) ;
2017-09-12 10:55:36 +02:00
cord_t font_h = font_get_height ( style_label - > font ) > > FONT_ANTIALIAS ;
2017-08-16 11:28:04 +02:00
lv_cont_set_fit ( lv_page_get_scrl ( ta ) , true , true ) ;
2017-09-12 10:55:36 +02:00
lv_obj_set_height ( ta , font_h + style_ta - > vpad * 2 ) ;
2017-08-16 11:28:04 +02:00
lv_label_set_long_mode ( ext - > label , LV_LABEL_LONG_EXPAND ) ;
lv_label_set_no_break ( ext - > label , true ) ;
lv_obj_set_pos ( lv_page_get_scrl ( ta ) , style_ta - > hpad , style_ta - > vpad ) ;
} else {
lv_ta_ext_t * ext = lv_obj_get_ext ( ta ) ;
lv_style_t * style_ta = lv_obj_get_style ( ta ) ;
lv_cont_set_fit ( lv_page_get_scrl ( ta ) , false , true ) ;
lv_label_set_long_mode ( ext - > label , LV_LABEL_LONG_BREAK ) ;
lv_label_set_no_break ( ext - > label , false ) ;
lv_obj_set_height ( ta , LV_TA_DEF_HEIGHT ) ;
lv_obj_set_pos ( lv_page_get_scrl ( ta ) , style_ta - > hpad , style_ta - > vpad ) ;
}
}
2016-09-30 15:29:00 +02:00
/*=====================
* Getter functions
* = = = = = = = = = = = = = = = = = = = = */
2016-10-04 09:45:39 +02:00
/**
2017-06-13 14:49:41 +02:00
* Get the text of a text area
* @ param ta pointer to a text area object
2016-10-04 09:45:39 +02:00
* @ return pointer to the text
*/
2016-10-07 11:15:46 +02:00
const char * lv_ta_get_txt ( lv_obj_t * ta )
2016-10-04 09:45:39 +02:00
{
2016-10-07 11:15:46 +02:00
lv_ta_ext_t * ext = lv_obj_get_ext ( ta ) ;
2017-07-07 16:22:24 +02:00
const char * txt ;
if ( ext - > pwd_mode = = 0 ) {
txt = lv_label_get_text ( ext - > label ) ;
} else {
txt = ext - > pwd_tmp ;
}
return txt ;
2016-10-04 09:45:39 +02:00
}
2017-06-13 14:49:41 +02:00
/**
* Get the label of a text area
* @ param ta pointer to a text area object
* @ return pointer to the label object
*/
lv_obj_t * lv_ta_get_label ( lv_obj_t * ta )
{
lv_ta_ext_t * ext = lv_obj_get_ext ( ta ) ;
return ext - > label ;
}
2016-10-04 09:45:39 +02:00
/**
* Get the current cursor position in character index
2016-10-07 11:15:46 +02:00
* @ param ta pointer to a text area object
2016-10-04 09:45:39 +02:00
* @ return the cursor position
*/
2016-10-07 11:15:46 +02:00
uint16_t lv_ta_get_cursor_pos ( lv_obj_t * ta )
2016-10-04 09:45:39 +02:00
{
2016-10-07 11:15:46 +02:00
lv_ta_ext_t * ext = lv_obj_get_ext ( ta ) ;
return ext - > cursor_pos ;
2016-10-04 09:45:39 +02:00
}
2017-04-21 09:15:39 +02:00
/**
* Get the current cursor visibility .
* @ param ta pointer to a text area object
* @ return true : the cursor is drawn , false : the cursor is hidden
*/
bool lv_ta_get_cursor_show ( lv_obj_t * ta )
{
lv_ta_ext_t * ext = lv_obj_get_ext ( ta ) ;
return ext - > cursor_show ;
}
2017-09-15 10:22:12 +02:00
/**
* Get the current cursor type .
* @ param ta pointer to a text area object
* @ return element of ' lv_ta_cursor_type_t '
*/
lv_ta_cursor_type_t lv_ta_get_cursor_type ( lv_obj_t * ta )
{
lv_ta_ext_t * ext = lv_obj_get_ext ( ta ) ;
return ext - > cursor_type ;
}
/**
* Get the style of the cursor
* @ param ta pointer to a text area object
* @ return style pointer to the new cursor style
*/
lv_style_t * lv_ta_get_cursor_style ( lv_obj_t * ta )
{
lv_ta_ext_t * ext = lv_obj_get_ext ( ta ) ;
return ext - > cursor_style ;
}
2017-07-07 16:22:24 +02:00
/**
* Get the password mode
* @ param ta pointer to a text area object
* @ return true : password mode is enabled , false : disabled
*/
bool lv_ta_get_pwd_mode ( lv_obj_t * ta )
{
lv_ta_ext_t * ext = lv_obj_get_ext ( ta ) ;
return ext - > pwd_mode ;
}
2016-09-30 15:29:00 +02:00
/**********************
* STATIC FUNCTIONS
* * * * * * * * * * * * * * * * * * * * * */
/**
* Handle the drawing related tasks of the text areas
2016-10-07 11:15:46 +02:00
* @ param ta pointer to an object
2016-09-30 15:29:00 +02:00
* @ 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 )
2016-10-04 09:45:39 +02:00
* LV_DESIGN_DRAW_MAIN : draw the object ( always return ' true ' )
* LV_DESIGN_DRAW_POST : drawing after every children are drawn
2016-09-30 15:29:00 +02:00
* @ param return true / false , depends on ' mode '
*/
2016-10-07 11:15:46 +02:00
static bool lv_ta_design ( lv_obj_t * ta , const area_t * masp , lv_design_mode_t mode )
2016-09-30 15:29:00 +02:00
{
if ( mode = = LV_DESIGN_COVER_CHK ) {
/*Return false if the object is not covers the mask_p area*/
2016-10-07 11:15:46 +02:00
return ancestor_design_f ( ta , masp , mode ) ;
2016-10-04 09:45:39 +02:00
} else if ( mode = = LV_DESIGN_DRAW_MAIN ) {
/*Draw the object*/
2016-10-07 11:15:46 +02:00
ancestor_design_f ( ta , masp , mode ) ;
2016-10-04 09:45:39 +02:00
} else if ( mode = = LV_DESIGN_DRAW_POST ) {
2016-10-07 11:15:46 +02:00
ancestor_design_f ( ta , masp , mode ) ;
2016-09-30 15:29:00 +02:00
}
2016-10-04 09:45:39 +02:00
return true ;
}
2016-09-30 15:29:00 +02:00
2016-10-04 15:29:52 +02:00
/**
2016-10-07 17:33:35 +02:00
* An extended scrolling design of the page . Calls the normal design function and it draws a cursor .
2016-10-07 11:15:46 +02:00
* @ param label pointer to a text area object
* @ param mask the object will be drawn only in this area
2016-10-04 15:29:52 +02:00
* @ param mode LV_DESIGN_COVER_CHK : only check if the object fully covers the ' mask_p ' area
* ( return ' true ' if yes )
* LV_DESIGN_DRAW_MAIN : draw the object ( always return ' true ' )
* LV_DESIGN_DRAW_POST : drawing after every children are drawn
* @ return return true / false , depends on ' mode '
*/
2016-10-07 17:33:35 +02:00
static bool lv_ta_scrling_design ( lv_obj_t * scrling , const area_t * mask , lv_design_mode_t mode )
2016-10-04 09:45:39 +02:00
{
if ( mode = = LV_DESIGN_COVER_CHK ) {
/*Return false if the object is not covers the mask_p area*/
2017-01-01 22:56:09 +01:00
return scrl_design_f ( scrling , mask , mode ) ;
2016-10-04 09:45:39 +02:00
} else if ( mode = = LV_DESIGN_DRAW_MAIN ) {
/*Draw the object*/
2017-01-01 22:56:09 +01:00
scrl_design_f ( scrling , mask , mode ) ;
2016-10-04 09:45:39 +02:00
} else if ( mode = = LV_DESIGN_DRAW_POST ) {
2017-01-01 22:56:09 +01:00
scrl_design_f ( scrling , mask , mode ) ;
2016-10-04 09:45:39 +02:00
/*Draw the cursor too*/
2016-10-07 17:33:35 +02:00
lv_obj_t * ta = lv_obj_get_parent ( scrling ) ;
2016-10-07 11:15:46 +02:00
lv_ta_ext_t * ta_ext = lv_obj_get_ext ( ta ) ;
2017-09-15 10:22:12 +02:00
if ( ta_ext - > cursor_show = = 0 | | ta_ext - > cursor_state = = 0 ) return true ; /*The cursor is not visible now*/
lv_style_t * label_style = lv_obj_get_style ( ta_ext - > label ) ;
lv_style_t cur_style ;
if ( ta_ext - > cursor_style ! = NULL ) {
lv_style_cpy ( & cur_style , ta_ext - > cursor_style ) ;
}
else {
lv_style_cpy ( & cur_style , label_style ) ; /*Use the label style is no better option and modify it */
color_t ccolor_tmp = cur_style . ccolor ; /*Make letter color to cursor color*/
cur_style . ccolor = cur_style . mcolor ; /*In block mode the letter color will be current background color*/
cur_style . mcolor = ccolor_tmp ;
cur_style . gcolor = ccolor_tmp ;
cur_style . bcolor = ccolor_tmp ;
cur_style . bopa = OPA_COVER ;
cur_style . bwidth = 1 * LV_DOWNSCALE ;
cur_style . line_width = 1 * LV_DOWNSCALE ;
cur_style . swidth = 0 ;
cur_style . radius = 0 ;
cur_style . empty = 0 ;
cur_style . opa = OPA_COVER ;
}
2016-10-07 11:15:46 +02:00
2017-09-15 10:22:12 +02:00
uint16_t cur_pos = lv_ta_get_cursor_pos ( ta ) ;
const char * txt = lv_label_get_text ( ta_ext - > label ) ;
2017-09-22 09:52:53 +02:00
uint32_t byte_pos ;
# if TXT_UTF8 != 0
byte_pos = txt_utf8_get_id ( txt , cur_pos ) ;
# else
byte_pos = cur_pos ;
# endif
uint32_t letter = txt_utf8_next ( & txt [ byte_pos ] , NULL ) ;
printf ( " letter %d \n " , letter ) ;
cord_t letter_w = font_get_width ( label_style - > font , letter ! = ' \0 ' ? letter : ' ' ) ;
2017-09-15 10:22:12 +02:00
cord_t letter_h = font_get_height ( label_style - > font ) > > FONT_ANTIALIAS ;
point_t letter_pos ;
lv_label_get_letter_pos ( ta_ext - > label , cur_pos , & letter_pos ) ;
2016-10-07 11:15:46 +02:00
2017-09-15 10:22:12 +02:00
area_t cur_area ;
if ( ta_ext - > cursor_type = = LV_TA_CURSOR_LINE ) {
cur_area . x1 = letter_pos . x + ta_ext - > label - > cords . x1 ;
cur_area . y1 = letter_pos . y + ta_ext - > label - > cords . y1 ;
cur_area . x2 = letter_pos . x + ta_ext - > label - > cords . x1 + cur_style . line_width ;
cur_area . y2 = letter_pos . y + ta_ext - > label - > cords . y1 + letter_h ;
lv_draw_rect ( & cur_area , mask , & cur_style ) ;
} else if ( ta_ext - > cursor_type = = LV_TA_CURSOR_BLOCK ) {
cur_area . x1 = letter_pos . x + ta_ext - > label - > cords . x1 ;
2016-10-07 17:33:35 +02:00
cur_area . y1 = letter_pos . y + ta_ext - > label - > cords . y1 ;
2017-09-15 10:22:12 +02:00
cur_area . x2 = letter_pos . x + ta_ext - > label - > cords . x1 + letter_w ;
cur_area . y2 = letter_pos . y + ta_ext - > label - > cords . y1 + letter_h ;
lv_draw_rect ( & cur_area , mask , & cur_style ) ;
2017-09-22 09:52:53 +02:00
/*Get the current letter*/
# if TXT_UTF8 == 0
2017-09-15 10:22:12 +02:00
char letter_buf [ 2 ] ;
2017-09-22 09:52:53 +02:00
letter_buf [ 0 ] = txt [ byte_pos ] ;
letter_buf [ 1 ] = ' \0 ' ;
# else
char letter_buf [ 8 ] = { 0 } ;
memcpy ( letter_buf , & txt [ byte_pos ] , txt_utf8_size ( txt [ byte_pos ] ) ) ;
# endif
2017-09-15 10:22:12 +02:00
lv_draw_label ( & cur_area , mask , & cur_style , letter_buf , TXT_FLAG_NONE , 0 ) ;
} else if ( ta_ext - > cursor_type = = LV_TA_CURSOR_OUTLINE ) {
cur_area . x1 = letter_pos . x + ta_ext - > label - > cords . x1 ;
cur_area . y1 = letter_pos . y + ta_ext - > label - > cords . y1 ;
cur_area . x2 = letter_pos . x + ta_ext - > label - > cords . x1 + letter_w ;
cur_area . y2 = letter_pos . y + ta_ext - > label - > cords . y1 + letter_h ;
cur_style . empty = 1 ;
if ( cur_style . bwidth = = 0 ) cur_style . bwidth = 1 * LV_DOWNSCALE ; /*Be sure the border will be drawn*/
lv_draw_rect ( & cur_area , mask , & cur_style ) ;
} else if ( ta_ext - > cursor_type = = LV_TA_CURSOR_UNDERLINE ) {
cur_area . x1 = letter_pos . x + ta_ext - > label - > cords . x1 ;
cur_area . y1 = letter_pos . y + ta_ext - > label - > cords . y1 + letter_h - cur_style . line_width ;
cur_area . x2 = letter_pos . x + ta_ext - > label - > cords . x1 + letter_w ;
cur_area . y2 = letter_pos . y + ta_ext - > label - > cords . y1 + letter_h ;
lv_draw_rect ( & cur_area , mask , & cur_style ) ;
2016-10-07 11:15:46 +02:00
}
2017-09-15 10:22:12 +02:00
2016-10-04 09:45:39 +02:00
}
return true ;
}
2016-12-15 10:31:30 +01:00
/**
2017-04-21 09:15:39 +02:00
* Called to blink the cursor
2016-12-15 10:31:30 +01:00
* @ param ta pointer to a text area
2017-04-21 09:15:39 +02:00
* @ param hide 1 : hide the cursor , 0 : show it
2016-12-15 10:31:30 +01:00
*/
2017-09-15 10:22:12 +02:00
static void cursor_blink_anim ( lv_obj_t * ta , uint8_t show )
2016-12-15 10:31:30 +01:00
{
2017-07-07 16:22:24 +02:00
lv_ta_ext_t * ext = lv_obj_get_ext ( ta ) ;
2017-09-15 10:22:12 +02:00
if ( show ! = ext - > cursor_state ) {
ext - > cursor_state = show = = 0 ? 0 : 1 ;
2017-07-07 16:22:24 +02:00
if ( ext - > cursor_show ! = 0 ) lv_obj_inv ( ta ) ;
2016-12-18 22:07:03 +01:00
}
2016-12-15 10:31:30 +01:00
}
2017-07-07 16:22:24 +02:00
/**
* Dummy function to animate char hiding in pwd mode .
2017-09-15 10:22:12 +02:00
* Does nothing , but a function is required in car hiding anim .
2017-07-07 16:22:24 +02:00
* ( pwd_char_hider callback do the real job )
* @ param ta unused
* @ param x unused
*/
2017-09-15 10:22:12 +02:00
static void pwd_char_hider_anim ( lv_obj_t * ta , int32_t x )
2017-07-07 16:22:24 +02:00
{
}
/**
* Hide all characters ( convert them to ' * ' )
* @ param ta : pointer to text area object
*/
static void pwd_char_hider ( lv_obj_t * ta )
{
lv_ta_ext_t * ext = lv_obj_get_ext ( ta ) ;
if ( ext - > pwd_mode ! = 0 ) {
char * txt = lv_label_get_text ( ext - > label ) ;
2017-09-22 09:52:53 +02:00
int16_t len = txt_len ( txt ) ;
2017-07-07 16:22:24 +02:00
bool refr = false ;
uint16_t i ;
2017-09-22 09:52:53 +02:00
for ( i = 0 ; i < len ; i + + ) {
2017-07-07 16:22:24 +02:00
if ( txt [ i ] ! = ' * ' ) {
txt [ i ] = ' * ' ;
refr = true ;
}
}
if ( refr ! = false ) lv_label_set_text ( ext - > label , NULL ) ;
}
}
2016-10-04 09:45:39 +02:00
/**
* Save the cursor x position as valid . It is important when jumping up / down to a shorter line
2016-10-07 11:15:46 +02:00
* @ param ta pointer to a text area object
2016-10-04 09:45:39 +02:00
*/
2016-10-07 11:15:46 +02:00
static void lv_ta_save_valid_cursor_x ( lv_obj_t * ta )
2016-10-04 09:45:39 +02:00
{
2016-10-07 11:15:46 +02:00
lv_ta_ext_t * ext = lv_obj_get_ext ( ta ) ;
2016-10-04 09:45:39 +02:00
point_t cur_pos ;
2016-10-07 11:15:46 +02:00
lv_label_get_letter_pos ( ext - > label , ext - > cursor_pos , & cur_pos ) ;
ext - > cursor_valid_x = cur_pos . x ;
2016-09-30 15:29:00 +02:00
}
# endif