merge bidi
This commit is contained in:
@@ -196,6 +196,12 @@ typedef void * lv_img_decoder_user_data_t;
|
|||||||
* font's bitmaps */
|
* font's bitmaps */
|
||||||
#define LV_ATTRIBUTE_LARGE_CONST
|
#define LV_ATTRIBUTE_LARGE_CONST
|
||||||
|
|
||||||
|
/* Export integer constant to binding.
|
||||||
|
* This macro is used with constants in the form of LV_<CONST> that
|
||||||
|
* should also appear on lvgl binding API such as Micropython
|
||||||
|
*/
|
||||||
|
#define LV_EXPORT_CONST_INT(int_value)
|
||||||
|
|
||||||
/*===================
|
/*===================
|
||||||
* HAL settings
|
* HAL settings
|
||||||
*==================*/
|
*==================*/
|
||||||
@@ -336,14 +342,27 @@ typedef void * lv_font_user_data_t;
|
|||||||
/*Can break (wrap) texts on these chars*/
|
/*Can break (wrap) texts on these chars*/
|
||||||
#define LV_TXT_BREAK_CHARS " ,.;:-_"
|
#define LV_TXT_BREAK_CHARS " ,.;:-_"
|
||||||
|
|
||||||
/* If a character is at least this long, will break wherever "prettiest" */
|
/* If a character is at least this long, will break wherever "prettiest" */
|
||||||
#define LV_TXT_LINE_BREAK_LONG_LEN 12
|
#define LV_TXT_LINE_BREAK_LONG_LEN 12
|
||||||
|
|
||||||
/* Minimum number of characters of a word to put on a line before a break */
|
/* Minimum number of characters of a word to put on a line before a break */
|
||||||
#define LV_TXT_LINE_BREAK_LONG_PRE_MIN_LEN 3
|
#define LV_TXT_LINE_BREAK_LONG_PRE_MIN_LEN 3
|
||||||
|
|
||||||
/* Minimum number of characters of a word to put on a line after a break */
|
/* Minimum number of characters of a word to put on a line after a break */
|
||||||
#define LV_TXT_LINE_BREAK_LONG_POST_MIN_LEN 3
|
#define LV_TXT_LINE_BREAK_LONG_POST_MIN_LEN 3
|
||||||
|
|
||||||
|
/* Support bidirectional texts.
|
||||||
|
* Allows mixing Left-to-Right and Right-to-Left texts.
|
||||||
|
* The direction will be processed according to the Unicode Bidirectioanl Algorithm:
|
||||||
|
* https://www.w3.org/International/articles/inline-bidi-markup/uba-basics*/
|
||||||
|
#define LV_USE_BIDI 0
|
||||||
|
#if LV_USE_BIDI
|
||||||
|
/* Set the default direction. Supported values:
|
||||||
|
* `LV_BIDI_DIR_LTR` Left-to-Right
|
||||||
|
* `LV_BIDI_DIR_RTL` Right-to-Left
|
||||||
|
* `LV_BIDI_DIR_AUTO` detect texts base direction */
|
||||||
|
#define LV_BIDI_BASE_DIR_DEF LV_BIDI_DIR_AUTO
|
||||||
|
#endif
|
||||||
|
|
||||||
/*Change the built in (v)snprintf functions*/
|
/*Change the built in (v)snprintf functions*/
|
||||||
#define LV_SPRINTF_CUSTOM 0
|
#define LV_SPRINTF_CUSTOM 0
|
||||||
|
|||||||
1
lvgl.h
1
lvgl.h
@@ -34,6 +34,7 @@ extern "C" {
|
|||||||
|
|
||||||
#include "src/lv_font/lv_font.h"
|
#include "src/lv_font/lv_font.h"
|
||||||
#include "src/lv_font/lv_font_fmt_txt.h"
|
#include "src/lv_font/lv_font_fmt_txt.h"
|
||||||
|
#include "src/lv_misc/lv_bidi.h"
|
||||||
|
|
||||||
#include "src/lv_objx/lv_btn.h"
|
#include "src/lv_objx/lv_btn.h"
|
||||||
#include "src/lv_objx/lv_imgbtn.h"
|
#include "src/lv_objx/lv_imgbtn.h"
|
||||||
|
|||||||
@@ -266,6 +266,14 @@
|
|||||||
#define LV_ATTRIBUTE_LARGE_CONST
|
#define LV_ATTRIBUTE_LARGE_CONST
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Export integer constant to binding.
|
||||||
|
* This macro is used with constants in the form of LV_<CONST> that
|
||||||
|
* should also appear on lvgl binding API such as Micropython
|
||||||
|
*/
|
||||||
|
#ifndef LV_EXPORT_CONST_INT
|
||||||
|
#define LV_EXPORT_CONST_INT(int_value)
|
||||||
|
#endif
|
||||||
|
|
||||||
/*===================
|
/*===================
|
||||||
* HAL settings
|
* HAL settings
|
||||||
*==================*/
|
*==================*/
|
||||||
@@ -465,19 +473,36 @@
|
|||||||
#define LV_TXT_BREAK_CHARS " ,.;:-_"
|
#define LV_TXT_BREAK_CHARS " ,.;:-_"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* If a character is at least this long, will break wherever "prettiest" */
|
/* If a character is at least this long, will break wherever "prettiest" */
|
||||||
#ifndef LV_TXT_LINE_BREAK_LONG_LEN
|
#ifndef LV_TXT_LINE_BREAK_LONG_LEN
|
||||||
#define LV_TXT_LINE_BREAK_LONG_LEN 12
|
#define LV_TXT_LINE_BREAK_LONG_LEN 12
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Minimum number of characters of a word to put on a line before a break */
|
/* Minimum number of characters of a word to put on a line before a break */
|
||||||
#ifndef LV_TXT_LINE_BREAK_LONG_PRE_MIN_LEN
|
#ifndef LV_TXT_LINE_BREAK_LONG_PRE_MIN_LEN
|
||||||
#define LV_TXT_LINE_BREAK_LONG_PRE_MIN_LEN 3
|
#define LV_TXT_LINE_BREAK_LONG_PRE_MIN_LEN 3
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Minimum number of characters of a word to put on a line after a break */
|
/* Minimum number of characters of a word to put on a line after a break */
|
||||||
#ifndef LV_TXT_LINE_BREAK_LONG_POST_MIN_LEN
|
#ifndef LV_TXT_LINE_BREAK_LONG_POST_MIN_LEN
|
||||||
#define LV_TXT_LINE_BREAK_LONG_POST_MIN_LEN 3
|
#define LV_TXT_LINE_BREAK_LONG_POST_MIN_LEN 3
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Support bidirectional texts.
|
||||||
|
* Allows mixing Left-to-Right and Right-to-Left texts.
|
||||||
|
* The direction will be processed according to the Unicode Bidirectioanl Algorithm:
|
||||||
|
* https://www.w3.org/International/articles/inline-bidi-markup/uba-basics*/
|
||||||
|
#ifndef LV_USE_BIDI
|
||||||
|
#define LV_USE_BIDI 0
|
||||||
|
#endif
|
||||||
|
#if LV_USE_BIDI
|
||||||
|
/* Set the default direction. Supported values:
|
||||||
|
* `LV_BIDI_DIR_LTR` Left-to-Right
|
||||||
|
* `LV_BIDI_DIR_RTL` Right-to-Left
|
||||||
|
* `LV_BIDI_DIR_AUTO` detect texts base direction */
|
||||||
|
#ifndef LV_BIDI_BASE_DIR_DEF
|
||||||
|
#define LV_BIDI_BASE_DIR_DEF LV_BIDI_DIR_AUTO
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*Change the built in (v)snprintf functions*/
|
/*Change the built in (v)snprintf functions*/
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ static void refresh_children_position(lv_obj_t * obj, lv_coord_t x_diff, lv_coor
|
|||||||
static void report_style_mod_core(void * style_p, lv_obj_t * obj);
|
static void report_style_mod_core(void * style_p, lv_obj_t * obj);
|
||||||
static void refresh_children_style(lv_obj_t * obj);
|
static void refresh_children_style(lv_obj_t * obj);
|
||||||
static void delete_children(lv_obj_t * obj);
|
static void delete_children(lv_obj_t * obj);
|
||||||
|
static void base_dir_refr_children(lv_obj_t * obj);
|
||||||
static void lv_event_mark_deleted(lv_obj_t * obj);
|
static void lv_event_mark_deleted(lv_obj_t * obj);
|
||||||
static void lv_obj_del_async_cb(void * obj);
|
static void lv_obj_del_async_cb(void * obj);
|
||||||
static lv_design_res_t lv_obj_design(lv_obj_t * obj, const lv_area_t * clip_area, lv_design_mode_t mode);
|
static lv_design_res_t lv_obj_design(lv_obj_t * obj, const lv_area_t * clip_area, lv_design_mode_t mode);
|
||||||
@@ -207,6 +208,16 @@ lv_obj_t * lv_obj_create(lv_obj_t * parent, const lv_obj_t * copy)
|
|||||||
new_obj->opa_scale_en = 0;
|
new_obj->opa_scale_en = 0;
|
||||||
new_obj->opa_scale = LV_OPA_COVER;
|
new_obj->opa_scale = LV_OPA_COVER;
|
||||||
new_obj->parent_event = 0;
|
new_obj->parent_event = 0;
|
||||||
|
#if LV_USE_BIDI
|
||||||
|
#if LV_BIDI_BASE_DIR_DEF == LV_BIDI_DIR_LTR || LV_BIDI_BASE_DIR_DEF == LV_BIDI_DIR_RTL || LV_BIDI_BASE_DIR_DEF == LV_BIDI_DIR_AUTO
|
||||||
|
new_obj->base_dir = LV_BIDI_BASE_DIR_DEF;
|
||||||
|
#else
|
||||||
|
#error "`LV_BIDI_BASE_DIR_DEF` should be `LV_BASE_DIR_LTR` or `LV_BASE_DIR_RTL` (See lv_conf.h)"
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
new_obj->base_dir = LV_BIDI_DIR_LTR;
|
||||||
|
#endif
|
||||||
|
|
||||||
new_obj->reserved = 0;
|
new_obj->reserved = 0;
|
||||||
|
|
||||||
new_obj->ext_attr = NULL;
|
new_obj->ext_attr = NULL;
|
||||||
@@ -225,11 +236,22 @@ lv_obj_t * lv_obj_create(lv_obj_t * parent, const lv_obj_t * copy)
|
|||||||
new_obj->par = parent; /*Set the parent*/
|
new_obj->par = parent; /*Set the parent*/
|
||||||
lv_ll_init(&(new_obj->child_ll), sizeof(lv_obj_t));
|
lv_ll_init(&(new_obj->child_ll), sizeof(lv_obj_t));
|
||||||
|
|
||||||
|
#if LV_USE_BIDI
|
||||||
|
new_obj->base_dir = LV_BIDI_DIR_INHERIT;
|
||||||
|
#else
|
||||||
|
new_obj->base_dir = LV_BIDI_DIR_LTR;
|
||||||
|
#endif
|
||||||
|
|
||||||
/*Set coordinates left top corner of parent*/
|
/*Set coordinates left top corner of parent*/
|
||||||
new_obj->coords.x1 = parent->coords.x1;
|
|
||||||
new_obj->coords.y1 = parent->coords.y1;
|
new_obj->coords.y1 = parent->coords.y1;
|
||||||
new_obj->coords.x2 = parent->coords.x1 + LV_OBJ_DEF_WIDTH;
|
|
||||||
new_obj->coords.y2 = parent->coords.y1 + LV_OBJ_DEF_HEIGHT;
|
new_obj->coords.y2 = parent->coords.y1 + LV_OBJ_DEF_HEIGHT;
|
||||||
|
if(lv_obj_get_base_dir(new_obj) == LV_BIDI_DIR_RTL) {
|
||||||
|
new_obj->coords.x2 = parent->coords.x2;
|
||||||
|
new_obj->coords.x1 = parent->coords.x2 - LV_OBJ_DEF_WIDTH;
|
||||||
|
} else {
|
||||||
|
new_obj->coords.x1 = parent->coords.x1;
|
||||||
|
new_obj->coords.x2 = parent->coords.x1 + LV_OBJ_DEF_WIDTH;
|
||||||
|
}
|
||||||
new_obj->ext_draw_pad = 0;
|
new_obj->ext_draw_pad = 0;
|
||||||
|
|
||||||
#if LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_FULL
|
#if LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_FULL
|
||||||
@@ -292,6 +314,7 @@ lv_obj_t * lv_obj_create(lv_obj_t * parent, const lv_obj_t * copy)
|
|||||||
new_obj->opa_scale = LV_OPA_COVER;
|
new_obj->opa_scale = LV_OPA_COVER;
|
||||||
new_obj->opa_scale_en = 0;
|
new_obj->opa_scale_en = 0;
|
||||||
new_obj->parent_event = 0;
|
new_obj->parent_event = 0;
|
||||||
|
new_obj->reserved = 0;
|
||||||
|
|
||||||
new_obj->ext_attr = NULL;
|
new_obj->ext_attr = NULL;
|
||||||
}
|
}
|
||||||
@@ -725,8 +748,12 @@ void lv_obj_set_size(lv_obj_t * obj, lv_coord_t w, lv_coord_t h)
|
|||||||
lv_obj_get_coords(obj, &ori);
|
lv_obj_get_coords(obj, &ori);
|
||||||
|
|
||||||
/*Set the length and height*/
|
/*Set the length and height*/
|
||||||
obj->coords.x2 = obj->coords.x1 + w - 1;
|
|
||||||
obj->coords.y2 = obj->coords.y1 + h - 1;
|
obj->coords.y2 = obj->coords.y1 + h - 1;
|
||||||
|
if(lv_obj_get_base_dir(obj) == LV_BIDI_DIR_RTL) {
|
||||||
|
obj->coords.x1 = obj->coords.x2 - w + 1;
|
||||||
|
} else {
|
||||||
|
obj->coords.x2 = obj->coords.x1 + w - 1;
|
||||||
|
}
|
||||||
|
|
||||||
/*Send a signal to the object with its new coordinates*/
|
/*Send a signal to the object with its new coordinates*/
|
||||||
obj->signal_cb(obj, LV_SIGNAL_CORD_CHG, &ori);
|
obj->signal_cb(obj, LV_SIGNAL_CORD_CHG, &ori);
|
||||||
@@ -1336,6 +1363,23 @@ void lv_obj_set_parent_event(lv_obj_t * obj, bool en)
|
|||||||
obj->parent_event = (en == true ? 1 : 0);
|
obj->parent_event = (en == true ? 1 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void lv_obj_set_base_dir(lv_obj_t * obj, lv_bidi_dir_t dir)
|
||||||
|
{
|
||||||
|
if(dir != LV_BIDI_DIR_LTR && dir != LV_BIDI_DIR_RTL &&
|
||||||
|
dir != LV_BIDI_DIR_AUTO && dir != LV_BIDI_DIR_INHERIT) {
|
||||||
|
|
||||||
|
LV_LOG_WARN("lv_obj_set_base_dir: invalid base dir");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
obj->base_dir = dir;
|
||||||
|
lv_signal_send(obj, LV_SIGNAL_BASE_DIR_CHG, NULL);
|
||||||
|
|
||||||
|
/* Notify the children about the parent base dir has changed.
|
||||||
|
* (The children might have `LV_BIDI_DIR_INHERIT`)*/
|
||||||
|
base_dir_refr_children(obj);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the opa scale enable parameter (required to set opa_scale with `lv_obj_set_opa_scale()`)
|
* Set the opa scale enable parameter (required to set opa_scale with `lv_obj_set_opa_scale()`)
|
||||||
* @param obj pointer to an object
|
* @param obj pointer to an object
|
||||||
@@ -1757,8 +1801,11 @@ lv_coord_t lv_obj_get_x(const lv_obj_t * obj)
|
|||||||
|
|
||||||
lv_coord_t rel_x;
|
lv_coord_t rel_x;
|
||||||
lv_obj_t * parent = lv_obj_get_parent(obj);
|
lv_obj_t * parent = lv_obj_get_parent(obj);
|
||||||
|
if(parent) {
|
||||||
rel_x = obj->coords.x1 - parent->coords.x1;
|
rel_x = obj->coords.x1 - parent->coords.x1;
|
||||||
|
} else {
|
||||||
|
rel_x = obj->coords.x1;
|
||||||
|
}
|
||||||
return rel_x;
|
return rel_x;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1773,8 +1820,11 @@ lv_coord_t lv_obj_get_y(const lv_obj_t * obj)
|
|||||||
|
|
||||||
lv_coord_t rel_y;
|
lv_coord_t rel_y;
|
||||||
lv_obj_t * parent = lv_obj_get_parent(obj);
|
lv_obj_t * parent = lv_obj_get_parent(obj);
|
||||||
|
if(parent) {
|
||||||
rel_y = obj->coords.y1 - parent->coords.y1;
|
rel_y = obj->coords.y1 - parent->coords.y1;
|
||||||
|
} else {
|
||||||
|
rel_y = obj->coords.y1;
|
||||||
|
}
|
||||||
return rel_y;
|
return rel_y;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2083,6 +2133,25 @@ bool lv_obj_get_parent_event(const lv_obj_t * obj)
|
|||||||
return obj->parent_event == 0 ? false : true;
|
return obj->parent_event == 0 ? false : true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
lv_bidi_dir_t lv_obj_get_base_dir(const lv_obj_t * obj)
|
||||||
|
{
|
||||||
|
#if LV_USE_BIDI
|
||||||
|
const lv_obj_t * parent = obj;
|
||||||
|
|
||||||
|
while(parent) {
|
||||||
|
if(parent->base_dir != LV_BIDI_DIR_INHERIT) return parent->base_dir;
|
||||||
|
|
||||||
|
parent = lv_obj_get_parent(parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
return LV_BIDI_BASE_DIR_DEF;
|
||||||
|
#else
|
||||||
|
return LV_BIDI_DIR_LTR;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the opa scale enable parameter
|
* Get the opa scale enable parameter
|
||||||
* @param obj pointer to an object
|
* @param obj pointer to an object
|
||||||
@@ -2549,6 +2618,22 @@ static void delete_children(lv_obj_t * obj)
|
|||||||
lv_mem_free(obj); /*Free the object itself*/
|
lv_mem_free(obj); /*Free the object itself*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void base_dir_refr_children(lv_obj_t * obj)
|
||||||
|
{
|
||||||
|
lv_obj_t * child;
|
||||||
|
child = lv_obj_get_child(obj, NULL);
|
||||||
|
|
||||||
|
while(child) {
|
||||||
|
if(child->base_dir == LV_BIDI_DIR_INHERIT) {
|
||||||
|
lv_signal_send(child, LV_SIGNAL_BASE_DIR_CHG, NULL);
|
||||||
|
base_dir_refr_children(child);
|
||||||
|
}
|
||||||
|
|
||||||
|
child = lv_obj_get_child(obj, child);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void lv_event_mark_deleted(lv_obj_t * obj)
|
static void lv_event_mark_deleted(lv_obj_t * obj)
|
||||||
{
|
{
|
||||||
lv_event_temp_data_t * t = event_temp_data_head;
|
lv_event_temp_data_t * t = event_temp_data_head;
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ extern "C" {
|
|||||||
#include "../lv_misc/lv_ll.h"
|
#include "../lv_misc/lv_ll.h"
|
||||||
#include "../lv_misc/lv_color.h"
|
#include "../lv_misc/lv_color.h"
|
||||||
#include "../lv_misc/lv_log.h"
|
#include "../lv_misc/lv_log.h"
|
||||||
|
#include "../lv_misc/lv_bidi.h"
|
||||||
#include "../lv_hal/lv_hal.h"
|
#include "../lv_hal/lv_hal.h"
|
||||||
|
|
||||||
/*********************
|
/*********************
|
||||||
@@ -122,6 +123,7 @@ enum {
|
|||||||
LV_SIGNAL_CORD_CHG, /**< Object coordinates/size have changed */
|
LV_SIGNAL_CORD_CHG, /**< Object coordinates/size have changed */
|
||||||
LV_SIGNAL_PARENT_SIZE_CHG, /**< Parent's size has changed */
|
LV_SIGNAL_PARENT_SIZE_CHG, /**< Parent's size has changed */
|
||||||
LV_SIGNAL_STYLE_CHG, /**< Object's style has changed */
|
LV_SIGNAL_STYLE_CHG, /**< Object's style has changed */
|
||||||
|
LV_SIGNAL_BASE_DIR_CHG, /**<The base dir has changed*/
|
||||||
LV_SIGNAL_REFR_EXT_DRAW_PAD, /**< Object's extra padding has changed */
|
LV_SIGNAL_REFR_EXT_DRAW_PAD, /**< Object's extra padding has changed */
|
||||||
LV_SIGNAL_GET_TYPE, /**< LittlevGL needs to retrieve the object's type */
|
LV_SIGNAL_GET_TYPE, /**< LittlevGL needs to retrieve the object's type */
|
||||||
|
|
||||||
@@ -135,6 +137,7 @@ enum {
|
|||||||
LV_SIGNAL_DRAG_BEGIN,
|
LV_SIGNAL_DRAG_BEGIN,
|
||||||
LV_SIGNAL_DRAG_THROW_BEGIN,
|
LV_SIGNAL_DRAG_THROW_BEGIN,
|
||||||
LV_SIGNAL_DRAG_END,
|
LV_SIGNAL_DRAG_END,
|
||||||
|
|
||||||
/*Group related*/
|
/*Group related*/
|
||||||
LV_SIGNAL_FOCUS,
|
LV_SIGNAL_FOCUS,
|
||||||
LV_SIGNAL_DEFOCUS,
|
LV_SIGNAL_DEFOCUS,
|
||||||
@@ -220,10 +223,9 @@ typedef struct _lv_obj_t
|
|||||||
uint8_t top : 1; /**< 1: If the object or its children is clicked it goes to the foreground*/
|
uint8_t top : 1; /**< 1: If the object or its children is clicked it goes to the foreground*/
|
||||||
uint8_t opa_scale_en : 1; /**< 1: opa_scale is set*/
|
uint8_t opa_scale_en : 1; /**< 1: opa_scale is set*/
|
||||||
uint8_t parent_event : 1; /**< 1: Send the object's events to the parent too. */
|
uint8_t parent_event : 1; /**< 1: Send the object's events to the parent too. */
|
||||||
|
|
||||||
lv_drag_dir_t drag_dir : 3; /**< Which directions the object can be dragged in */
|
lv_drag_dir_t drag_dir : 3; /**< Which directions the object can be dragged in */
|
||||||
uint8_t reserved : 5; /**< Reserved for future use */
|
lv_bidi_dir_t base_dir : 2; /**< Base direction of texts related to this object */
|
||||||
|
uint8_t reserved : 3; /**< Reserved for future use*/
|
||||||
uint8_t protect; /**< Automatically happening actions can be prevented. 'OR'ed values from
|
uint8_t protect; /**< Automatically happening actions can be prevented. 'OR'ed values from
|
||||||
`lv_protect_t`*/
|
`lv_protect_t`*/
|
||||||
lv_opa_t opa_scale; /**< Scale down the opacity by this factor. Effects all children as well*/
|
lv_opa_t opa_scale; /**< Scale down the opacity by this factor. Effects all children as well*/
|
||||||
@@ -515,6 +517,7 @@ void lv_obj_set_drag_parent(lv_obj_t * obj, bool en);
|
|||||||
*/
|
*/
|
||||||
void lv_obj_set_parent_event(lv_obj_t * obj, bool en);
|
void lv_obj_set_parent_event(lv_obj_t * obj, bool en);
|
||||||
|
|
||||||
|
void lv_obj_set_base_dir(lv_obj_t * obj, lv_bidi_dir_t dir);
|
||||||
/**
|
/**
|
||||||
* Set the opa scale enable parameter (required to set opa_scale with `lv_obj_set_opa_scale()`)
|
* Set the opa scale enable parameter (required to set opa_scale with `lv_obj_set_opa_scale()`)
|
||||||
* @param obj pointer to an object
|
* @param obj pointer to an object
|
||||||
@@ -854,6 +857,9 @@ bool lv_obj_get_drag_parent(const lv_obj_t * obj);
|
|||||||
*/
|
*/
|
||||||
bool lv_obj_get_parent_event(const lv_obj_t * obj);
|
bool lv_obj_get_parent_event(const lv_obj_t * obj);
|
||||||
|
|
||||||
|
|
||||||
|
lv_bidi_dir_t lv_obj_get_base_dir(const lv_obj_t * obj);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the opa scale enable parameter
|
* Get the opa scale enable parameter
|
||||||
* @param obj pointer to an object
|
* @param obj pointer to an object
|
||||||
|
|||||||
@@ -26,6 +26,8 @@ extern "C" {
|
|||||||
#define LV_RADIUS_CIRCLE (LV_COORD_MAX) /**< A very big radius to always draw as circle*/
|
#define LV_RADIUS_CIRCLE (LV_COORD_MAX) /**< A very big radius to always draw as circle*/
|
||||||
#define LV_STYLE_DEGUG_SENTINEL_VALUE 0x12345678
|
#define LV_STYLE_DEGUG_SENTINEL_VALUE 0x12345678
|
||||||
|
|
||||||
|
LV_EXPORT_CONST_INT(LV_RADIUS_CIRCLE);
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
* TYPEDEFS
|
* TYPEDEFS
|
||||||
**********************/
|
**********************/
|
||||||
|
|||||||
@@ -29,6 +29,9 @@ extern "C" {
|
|||||||
#define LV_COORD_MAX ((lv_coord_t)((uint32_t)((uint32_t)1 << (8 * sizeof(lv_coord_t) - 1)) - 1000))
|
#define LV_COORD_MAX ((lv_coord_t)((uint32_t)((uint32_t)1 << (8 * sizeof(lv_coord_t) - 1)) - 1000))
|
||||||
#define LV_COORD_MIN (-LV_COORD_MAX)
|
#define LV_COORD_MIN (-LV_COORD_MAX)
|
||||||
|
|
||||||
|
LV_EXPORT_CONST_INT(LV_COORD_MAX);
|
||||||
|
LV_EXPORT_CONST_INT(LV_COORD_MIN);
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
* TYPEDEFS
|
* TYPEDEFS
|
||||||
**********************/
|
**********************/
|
||||||
|
|||||||
321
src/lv_misc/lv_bidi.c
Normal file
321
src/lv_misc/lv_bidi.c
Normal file
@@ -0,0 +1,321 @@
|
|||||||
|
/**
|
||||||
|
* @file lv_bidi.c
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*********************
|
||||||
|
* INCLUDES
|
||||||
|
*********************/
|
||||||
|
#include "lv_bidi.h"
|
||||||
|
#include <stddef.h>
|
||||||
|
#include "lv_txt.h"
|
||||||
|
|
||||||
|
#if LV_USE_BIDI
|
||||||
|
|
||||||
|
/*********************
|
||||||
|
* DEFINES
|
||||||
|
*********************/
|
||||||
|
|
||||||
|
/**********************
|
||||||
|
* TYPEDEFS
|
||||||
|
**********************/
|
||||||
|
|
||||||
|
/**********************
|
||||||
|
* STATIC PROTOTYPES
|
||||||
|
**********************/
|
||||||
|
static void process_paragraph(const char * str_in, char * str_out, uint32_t len, lv_bidi_dir_t base_dir);
|
||||||
|
static uint32_t get_next_paragraph(const char * txt);
|
||||||
|
static lv_bidi_dir_t get_next_run(const char * txt, lv_bidi_dir_t base_dir, uint32_t * len);
|
||||||
|
static void rtl_reverse(char * dest, const char * src, uint32_t len);
|
||||||
|
static uint32_t char_change_to_pair(uint32_t letter);
|
||||||
|
|
||||||
|
/**********************
|
||||||
|
* STATIC VARIABLES
|
||||||
|
**********************/
|
||||||
|
|
||||||
|
/**********************
|
||||||
|
* MACROS
|
||||||
|
**********************/
|
||||||
|
|
||||||
|
/**********************
|
||||||
|
* GLOBAL FUNCTIONS
|
||||||
|
**********************/
|
||||||
|
|
||||||
|
void lv_bidi_process(const char * str_in, char * str_out, lv_bidi_dir_t base_dir)
|
||||||
|
{
|
||||||
|
|
||||||
|
if(base_dir == LV_BIDI_DIR_AUTO) base_dir = lv_bidi_detect_base_dir(str_in);
|
||||||
|
|
||||||
|
uint32_t par_start = 0;
|
||||||
|
uint32_t par_len;
|
||||||
|
|
||||||
|
while(str_in[par_start] == '\n' || str_in[par_start] == '\r') {
|
||||||
|
str_out[par_start] = str_in[par_start];
|
||||||
|
par_start ++;
|
||||||
|
}
|
||||||
|
|
||||||
|
while(str_in[par_start] != '\0') {
|
||||||
|
par_len = get_next_paragraph(&str_in[par_start]);
|
||||||
|
process_paragraph(&str_in[par_start], &str_out[par_start], par_len, base_dir);
|
||||||
|
par_start += par_len;
|
||||||
|
|
||||||
|
while(str_in[par_start] == '\n' || str_in[par_start] == '\r') {
|
||||||
|
str_out[par_start] = str_in[par_start];
|
||||||
|
par_start ++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
str_out[par_start] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
lv_bidi_dir_t lv_bidi_detect_base_dir(const char * txt)
|
||||||
|
{
|
||||||
|
uint32_t i = 0;
|
||||||
|
uint32_t letter;
|
||||||
|
while(txt[i] != '\0') {
|
||||||
|
letter = lv_txt_encoded_next(txt, &i);
|
||||||
|
|
||||||
|
lv_bidi_dir_t dir;
|
||||||
|
dir = lv_bidi_get_letter_dir(letter);
|
||||||
|
if(dir == LV_BIDI_DIR_RTL || dir == LV_BIDI_DIR_LTR) return dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*If there were no strong char earlier return with the default base dir */
|
||||||
|
if(LV_BIDI_BASE_DIR_DEF == LV_BIDI_DIR_AUTO) return LV_BIDI_DIR_LTR;
|
||||||
|
else return LV_BIDI_BASE_DIR_DEF;
|
||||||
|
}
|
||||||
|
|
||||||
|
lv_bidi_dir_t lv_bidi_get_letter_dir(uint32_t letter)
|
||||||
|
{
|
||||||
|
if(lv_bidi_letter_is_rtl(letter)) return LV_BIDI_DIR_RTL;
|
||||||
|
if(lv_bidi_letter_is_neutral(letter)) return LV_BIDI_DIR_NEUTRAL;
|
||||||
|
if(lv_bidi_letter_is_weak(letter)) return LV_BIDI_DIR_WEAK;
|
||||||
|
|
||||||
|
return LV_BIDI_DIR_LTR;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool lv_bidi_letter_is_weak(uint32_t letter)
|
||||||
|
{
|
||||||
|
uint32_t i = 0;
|
||||||
|
static const char weaks[] = "0123456789";
|
||||||
|
|
||||||
|
do {
|
||||||
|
uint32_t x = lv_txt_encoded_next(weaks, &i);
|
||||||
|
if(letter == x) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} while(weaks[i] != '\0');
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool lv_bidi_letter_is_rtl(uint32_t letter)
|
||||||
|
{
|
||||||
|
if(letter >= 0x5d0 && letter <= 0x5ea) return true;
|
||||||
|
if(letter == 0x202E) return true; /*Unicode of LV_BIDI_RLO*/
|
||||||
|
// if(letter >= 'a' && letter <= 'z') return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool lv_bidi_letter_is_neutral(uint32_t letter)
|
||||||
|
{
|
||||||
|
uint16_t i;
|
||||||
|
static const char neutrals[] = " \t\n\r.,:;'\"`!?%/\\=()[]{}<>@#&$|";
|
||||||
|
for(i = 0; neutrals[i] != '\0'; i++) {
|
||||||
|
if(letter == (uint32_t)neutrals[i]) return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**********************
|
||||||
|
* STATIC FUNCTIONS
|
||||||
|
**********************/
|
||||||
|
|
||||||
|
static void process_paragraph(const char * str_in, char * str_out, uint32_t len, lv_bidi_dir_t base_dir)
|
||||||
|
{
|
||||||
|
uint32_t run_len = 0;
|
||||||
|
lv_bidi_dir_t run_dir;
|
||||||
|
uint32_t rd = 0;
|
||||||
|
uint32_t wr;
|
||||||
|
if(base_dir == LV_BIDI_DIR_RTL) wr = len;
|
||||||
|
else wr = 0;
|
||||||
|
|
||||||
|
str_out[len] = '\0';
|
||||||
|
|
||||||
|
lv_bidi_dir_t dir = base_dir;
|
||||||
|
|
||||||
|
/*Process neutral chars in the beginning*/
|
||||||
|
while(rd < len) {
|
||||||
|
uint32_t letter = lv_txt_encoded_next(str_in, &rd);
|
||||||
|
dir = lv_bidi_get_letter_dir(letter);
|
||||||
|
if(dir != LV_BIDI_DIR_NEUTRAL && dir != LV_BIDI_DIR_WEAK) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(rd && str_in[rd] != '\0') lv_txt_encoded_prev(str_in, &rd);
|
||||||
|
|
||||||
|
if(rd) {
|
||||||
|
if(base_dir == LV_BIDI_DIR_LTR) {
|
||||||
|
memcpy(&str_out[wr], str_in, rd);
|
||||||
|
wr += rd;
|
||||||
|
} else {
|
||||||
|
wr -= rd;
|
||||||
|
rtl_reverse(&str_out[wr], str_in, rd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*Get and process the runs*/
|
||||||
|
while(rd < len) {
|
||||||
|
run_dir = get_next_run(&str_in[rd], base_dir, &run_len);
|
||||||
|
|
||||||
|
if(base_dir == LV_BIDI_DIR_LTR) {
|
||||||
|
if(run_dir == LV_BIDI_DIR_LTR) memcpy(&str_out[wr], &str_in[rd], run_len);
|
||||||
|
else rtl_reverse(&str_out[wr], &str_in[rd], run_len);
|
||||||
|
wr += run_len;
|
||||||
|
} else {
|
||||||
|
wr -= run_len;
|
||||||
|
if(run_dir == LV_BIDI_DIR_LTR) memcpy(&str_out[wr], &str_in[rd], run_len);
|
||||||
|
else rtl_reverse(&str_out[wr], &str_in[rd], run_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
rd += run_len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t get_next_paragraph(const char * txt)
|
||||||
|
{
|
||||||
|
uint32_t i = 0;
|
||||||
|
|
||||||
|
lv_txt_encoded_next(txt, &i);
|
||||||
|
|
||||||
|
while(txt[i] != '\0' && txt[i] != '\n' && txt[i] != '\r') {
|
||||||
|
lv_txt_encoded_next(txt, &i);
|
||||||
|
}
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
static lv_bidi_dir_t get_next_run(const char * txt, lv_bidi_dir_t base_dir, uint32_t * len)
|
||||||
|
{
|
||||||
|
uint32_t i = 0;
|
||||||
|
uint32_t letter;
|
||||||
|
|
||||||
|
letter = lv_txt_encoded_next(txt, NULL);
|
||||||
|
lv_bidi_dir_t dir = lv_bidi_get_letter_dir(letter);
|
||||||
|
|
||||||
|
/*Find the first strong char. Skip the neutrals*/
|
||||||
|
while(dir == LV_BIDI_DIR_NEUTRAL || dir == LV_BIDI_DIR_WEAK) {
|
||||||
|
letter = lv_txt_encoded_next(txt, &i);
|
||||||
|
dir = lv_bidi_get_letter_dir(letter);
|
||||||
|
if(txt[i] == '\0' || txt[i] == '\n' || txt[i] == '\r') {
|
||||||
|
*len = i;
|
||||||
|
return base_dir;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lv_bidi_dir_t run_dir = dir;
|
||||||
|
|
||||||
|
uint32_t i_prev = i;
|
||||||
|
uint32_t i_last_strong = i;
|
||||||
|
|
||||||
|
/*Find the next char which has different direction*/
|
||||||
|
lv_bidi_dir_t next_dir = base_dir;
|
||||||
|
while(txt[i] != '\0'&& txt[i] != '\n' && txt[i] != '\r') {
|
||||||
|
letter = lv_txt_encoded_next(txt, &i);
|
||||||
|
next_dir = lv_bidi_get_letter_dir(letter);
|
||||||
|
|
||||||
|
/*New dir found?*/
|
||||||
|
if((next_dir == LV_BIDI_DIR_RTL || next_dir == LV_BIDI_DIR_LTR) && next_dir != run_dir) {
|
||||||
|
/*Include neutrals if `run_dir == base_dir` */
|
||||||
|
if(run_dir == base_dir) *len = i_prev;
|
||||||
|
/*Exclude neutrals if `run_dir != base_dir` */
|
||||||
|
else *len = i_last_strong;
|
||||||
|
|
||||||
|
return run_dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(next_dir != LV_BIDI_DIR_NEUTRAL) i_last_strong = i;
|
||||||
|
|
||||||
|
i_prev = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*Handle end of of string. Apply `base_dir` on trailing neutrals*/
|
||||||
|
|
||||||
|
/*Include neutrals if `run_dir == base_dir` */
|
||||||
|
if(run_dir == base_dir) *len = i_prev;
|
||||||
|
/*Exclude neutrals if `run_dir != base_dir` */
|
||||||
|
else *len = i_last_strong;
|
||||||
|
|
||||||
|
return run_dir;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rtl_reverse(char * dest, const char * src, uint32_t len)
|
||||||
|
{
|
||||||
|
uint32_t i = len;
|
||||||
|
uint32_t wr = 0;
|
||||||
|
|
||||||
|
while(i) {
|
||||||
|
uint32_t letter = lv_txt_encoded_prev(src, &i);
|
||||||
|
|
||||||
|
/*Keep weak letters (numbers) as LTR*/
|
||||||
|
if(lv_bidi_letter_is_weak(letter)) {
|
||||||
|
uint32_t last_weak = i;
|
||||||
|
uint32_t first_weak = i;
|
||||||
|
while(i) {
|
||||||
|
letter = lv_txt_encoded_prev(src, &i);
|
||||||
|
/*No need to call `char_change_to_pair` because there not such chars here*/
|
||||||
|
|
||||||
|
/*Finish on non-weak char */
|
||||||
|
/*but treat number and currency related chars as weak*/
|
||||||
|
if(lv_bidi_letter_is_weak(letter) == false && letter != '.' && letter != ',' && letter != '$') {
|
||||||
|
lv_txt_encoded_next(src, &i); /*Rewind one letter*/
|
||||||
|
first_weak = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(i == 0) first_weak = 0;
|
||||||
|
|
||||||
|
memcpy(&dest[wr], &src[first_weak], last_weak - first_weak + 1);
|
||||||
|
wr += last_weak - first_weak + 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
/*Simply store in reversed order*/
|
||||||
|
else {
|
||||||
|
uint32_t letter_size = lv_txt_encoded_size((const char *)&src[i]);
|
||||||
|
/*Swap arithmetical symbols*/
|
||||||
|
if(letter_size == 1) {
|
||||||
|
uint32_t new_letter = letter = char_change_to_pair(letter);
|
||||||
|
dest[wr] = (uint8_t)new_letter;
|
||||||
|
wr += 1;
|
||||||
|
}
|
||||||
|
/*Just store the letter*/
|
||||||
|
else {
|
||||||
|
memcpy(&dest[wr], &src[i], letter_size);
|
||||||
|
wr += letter_size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t char_change_to_pair(uint32_t letter)
|
||||||
|
{
|
||||||
|
static uint8_t left[] = {"<({["};
|
||||||
|
static uint8_t right[] = {">)}]"};
|
||||||
|
|
||||||
|
uint8_t i;
|
||||||
|
for(i = 0; left[i] != '\0'; i++) {
|
||||||
|
if(letter == left[i]) return right[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i = 0; right[i] != '\0'; i++) {
|
||||||
|
if(letter == right[i]) return left[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return letter;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /*LV_USE_BIDI*/
|
||||||
72
src/lv_misc/lv_bidi.h
Normal file
72
src/lv_misc/lv_bidi.h
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
/**
|
||||||
|
* @file lv_bifi.h
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LV_BIDI_H
|
||||||
|
#define LV_BIDI_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*********************
|
||||||
|
* INCLUDES
|
||||||
|
*********************/
|
||||||
|
#ifdef LV_CONF_INCLUDE_SIMPLE
|
||||||
|
#include "lv_conf.h"
|
||||||
|
#else
|
||||||
|
#include "../../../lv_conf.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
/*********************
|
||||||
|
* DEFINES
|
||||||
|
*********************/
|
||||||
|
/* Special non printable strong characters.
|
||||||
|
* They can be inserted to texts to affect the run's direction*/
|
||||||
|
#define LV_BIDI_LRO "\xE2\x80\xAD" /*U+202D*/
|
||||||
|
#define LV_BIDI_RLO "\xE2\x80\xAE" /*U+202E*/
|
||||||
|
|
||||||
|
/**********************
|
||||||
|
* TYPEDEFS
|
||||||
|
**********************/
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
/*The first 4 values are stored in `lv_obj_t` on 2 bits*/
|
||||||
|
LV_BIDI_DIR_LTR = 0x00,
|
||||||
|
LV_BIDI_DIR_RTL = 0x01,
|
||||||
|
LV_BIDI_DIR_AUTO = 0x02,
|
||||||
|
LV_BIDI_DIR_INHERIT = 0x03,
|
||||||
|
|
||||||
|
LV_BIDI_DIR_NEUTRAL = 0x20,
|
||||||
|
LV_BIDI_DIR_WEAK = 0x21,
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef uint8_t lv_bidi_dir_t;
|
||||||
|
|
||||||
|
/**********************
|
||||||
|
* GLOBAL PROTOTYPES
|
||||||
|
**********************/
|
||||||
|
#if LV_USE_BIDI
|
||||||
|
|
||||||
|
void lv_bidi_process(const char * str_in, char * str_out, lv_bidi_dir_t base_dir);
|
||||||
|
lv_bidi_dir_t lv_bidi_detect_base_dir(const char * txt);
|
||||||
|
lv_bidi_dir_t lv_bidi_get_letter_dir(uint32_t letter);
|
||||||
|
bool lv_bidi_letter_is_weak(uint32_t letter);
|
||||||
|
bool lv_bidi_letter_is_rtl(uint32_t letter);
|
||||||
|
bool lv_bidi_letter_is_neutral(uint32_t letter);
|
||||||
|
|
||||||
|
/**********************
|
||||||
|
* MACROS
|
||||||
|
**********************/
|
||||||
|
|
||||||
|
#endif /*LV_USE_BIDI*/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} /* extern "C" */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /*LV_BIDI_H*/
|
||||||
@@ -26,13 +26,14 @@ extern "C" {
|
|||||||
|
|
||||||
/*Possible log level. For compatibility declare it independently from `LV_USE_LOG`*/
|
/*Possible log level. For compatibility declare it independently from `LV_USE_LOG`*/
|
||||||
|
|
||||||
#define LV_LOG_LEVEL_TRACE 0 /**< A lot of logs to give detailed information*/
|
enum {
|
||||||
#define LV_LOG_LEVEL_INFO 1 /**< Log important events*/
|
LV_LOG_LEVEL_TRACE = 0, /**< A lot of logs to give detailed information*/
|
||||||
#define LV_LOG_LEVEL_WARN 2 /**< Log if something unwanted happened but didn't caused problem*/
|
LV_LOG_LEVEL_INFO = 1, /**< Log important events*/
|
||||||
#define LV_LOG_LEVEL_ERROR 3 /**< Only critical issue, when the system may fail*/
|
LV_LOG_LEVEL_WARN = 2, /**< Log if something unwanted happened but didn't caused problem*/
|
||||||
#define LV_LOG_LEVEL_NONE 4 /**< Do not log anything*/
|
LV_LOG_LEVEL_ERROR = 3, /**< Only critical issue, when the system may fail*/
|
||||||
#define _LV_LOG_LEVEL_NUM 5 /**< Number of log levels */
|
LV_LOG_LEVEL_NONE = 4, /**< Do not log anything*/
|
||||||
|
_LV_LOG_LEVEL_NUM = 5 /**< Number of log levels */
|
||||||
|
};
|
||||||
typedef int8_t lv_log_level_t;
|
typedef int8_t lv_log_level_t;
|
||||||
|
|
||||||
#if LV_USE_LOG
|
#if LV_USE_LOG
|
||||||
|
|||||||
@@ -467,7 +467,7 @@ static uint8_t lv_txt_utf8_size(const char * str)
|
|||||||
return 3;
|
return 3;
|
||||||
else if((str[0] & 0xF8) == 0xF0)
|
else if((str[0] & 0xF8) == 0xF0)
|
||||||
return 4;
|
return 4;
|
||||||
return 1; /*If the char was invalid step tell it's 1 byte long*/
|
return 0; /*If the char was invalid tell it's 1 byte long*/
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -644,7 +644,8 @@ static uint32_t lv_txt_utf8_get_byte_id(const char * txt, uint32_t utf8_id)
|
|||||||
uint32_t i;
|
uint32_t i;
|
||||||
uint32_t byte_cnt = 0;
|
uint32_t byte_cnt = 0;
|
||||||
for(i = 0; i < utf8_id; i++) {
|
for(i = 0; i < utf8_id; i++) {
|
||||||
byte_cnt += lv_txt_encoded_size(&txt[byte_cnt]);
|
uint8_t c_size = lv_txt_encoded_size(&txt[byte_cnt]);
|
||||||
|
byte_cnt += c_size > 0 ? c_size : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return byte_cnt;
|
return byte_cnt;
|
||||||
|
|||||||
@@ -43,6 +43,11 @@ extern "C" {
|
|||||||
/** log2(LV_BAR_ANIM_STATE_END) used to normalize data*/
|
/** log2(LV_BAR_ANIM_STATE_END) used to normalize data*/
|
||||||
#define LV_BAR_ANIM_STATE_NORM 8
|
#define LV_BAR_ANIM_STATE_NORM 8
|
||||||
|
|
||||||
|
LV_EXPORT_CONST_INT(LV_BAR_ANIM_STATE_START);
|
||||||
|
LV_EXPORT_CONST_INT(LV_BAR_ANIM_STATE_END);
|
||||||
|
LV_EXPORT_CONST_INT(LV_BAR_ANIM_STATE_INV);
|
||||||
|
LV_EXPORT_CONST_INT(LV_BAR_ANIM_STATE_NORM);
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
* TYPEDEFS
|
* TYPEDEFS
|
||||||
**********************/
|
**********************/
|
||||||
|
|||||||
@@ -207,6 +207,8 @@ void lv_btnm_set_map(const lv_obj_t * btnm, const char * map[])
|
|||||||
btn_h = lv_obj_get_height(btnm)- act_y - style_bg->body.padding.bottom - 1;
|
btn_h = lv_obj_get_height(btnm)- act_y - style_bg->body.padding.bottom - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lv_bidi_dir_t base_dir = lv_obj_get_base_dir(btnm);
|
||||||
|
|
||||||
/*Only deal with the non empty lines*/
|
/*Only deal with the non empty lines*/
|
||||||
if(btn_cnt != 0) {
|
if(btn_cnt != 0) {
|
||||||
/*Calculate the width of all units*/
|
/*Calculate the width of all units*/
|
||||||
@@ -214,7 +216,8 @@ void lv_btnm_set_map(const lv_obj_t * btnm, const char * map[])
|
|||||||
|
|
||||||
/*Set the button size and positions and set the texts*/
|
/*Set the button size and positions and set the texts*/
|
||||||
uint16_t i;
|
uint16_t i;
|
||||||
lv_coord_t act_x = style_bg->body.padding.left;
|
lv_coord_t act_x;
|
||||||
|
|
||||||
lv_coord_t act_unit_w;
|
lv_coord_t act_unit_w;
|
||||||
unit_act_cnt = 0;
|
unit_act_cnt = 0;
|
||||||
for(i = 0; i < btn_cnt; i++) {
|
for(i = 0; i < btn_cnt; i++) {
|
||||||
@@ -225,9 +228,13 @@ void lv_btnm_set_map(const lv_obj_t * btnm, const char * map[])
|
|||||||
act_unit_w--; /*-1 because e.g. width = 100 means 101 pixels (0..100)*/
|
act_unit_w--; /*-1 because e.g. width = 100 means 101 pixels (0..100)*/
|
||||||
|
|
||||||
/*Always recalculate act_x because of rounding errors */
|
/*Always recalculate act_x because of rounding errors */
|
||||||
|
if(base_dir == LV_BIDI_DIR_RTL) {
|
||||||
|
act_x = (unit_act_cnt * all_unit_w) / unit_cnt + i * style_bg->body.padding.inner;
|
||||||
|
act_x = lv_obj_get_width(btnm) - style_bg->body.padding.right - act_x - act_unit_w - 1;
|
||||||
|
} else {
|
||||||
act_x = (unit_act_cnt * all_unit_w) / unit_cnt + i * style_bg->body.padding.inner +
|
act_x = (unit_act_cnt * all_unit_w) / unit_cnt + i * style_bg->body.padding.inner +
|
||||||
style_bg->body.padding.left;
|
style_bg->body.padding.left;
|
||||||
|
}
|
||||||
/* Set the button's area.
|
/* Set the button's area.
|
||||||
* If inner padding is zero then use the prev. button x2 as x1 to avoid rounding
|
* If inner padding is zero then use the prev. button x2 as x1 to avoid rounding
|
||||||
* errors*/
|
* errors*/
|
||||||
@@ -643,7 +650,6 @@ static lv_design_res_t lv_btnm_design(lv_obj_t * btnm, const lv_area_t * clip_ar
|
|||||||
}
|
}
|
||||||
/*Draw the object*/
|
/*Draw the object*/
|
||||||
else if(mode == LV_DESIGN_DRAW_MAIN) {
|
else if(mode == LV_DESIGN_DRAW_MAIN) {
|
||||||
|
|
||||||
ancestor_design_f(btnm, clip_area, mode);
|
ancestor_design_f(btnm, clip_area, mode);
|
||||||
|
|
||||||
lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm);
|
lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm);
|
||||||
@@ -664,6 +670,10 @@ static lv_design_res_t lv_btnm_design(lv_obj_t * btnm, const lv_area_t * clip_ar
|
|||||||
lv_txt_flag_t txt_flag = LV_TXT_FLAG_NONE;
|
lv_txt_flag_t txt_flag = LV_TXT_FLAG_NONE;
|
||||||
|
|
||||||
if(ext->recolor) txt_flag = LV_TXT_FLAG_RECOLOR;
|
if(ext->recolor) txt_flag = LV_TXT_FLAG_RECOLOR;
|
||||||
|
#if LV_USE_BIDI
|
||||||
|
char * bidi_buf = lv_mem_alloc(64);
|
||||||
|
lv_bidi_dir_t base_dir = lv_obj_get_base_dir(btnm);
|
||||||
|
#endif
|
||||||
|
|
||||||
for(btn_i = 0; btn_i < ext->btn_cnt; btn_i++, txt_i++) {
|
for(btn_i = 0; btn_i < ext->btn_cnt; btn_i++, txt_i++) {
|
||||||
/*Search the next valid text in the map*/
|
/*Search the next valid text in the map*/
|
||||||
@@ -733,8 +743,22 @@ static lv_design_res_t lv_btnm_design(lv_obj_t * btnm, const lv_area_t * clip_ar
|
|||||||
area_tmp.x2 = area_tmp.x1 + txt_size.x;
|
area_tmp.x2 = area_tmp.x1 + txt_size.x;
|
||||||
area_tmp.y2 = area_tmp.y1 + txt_size.y;
|
area_tmp.y2 = area_tmp.y1 + txt_size.y;
|
||||||
|
|
||||||
|
#if LV_USE_BIDI == 0
|
||||||
lv_draw_label(&area_tmp, clip_area, btn_style, opa_scale, ext->map_p[txt_i], txt_flag, NULL, -1, -1, NULL);
|
lv_draw_label(&area_tmp, clip_area, btn_style, opa_scale, ext->map_p[txt_i], txt_flag, NULL, -1, -1, NULL);
|
||||||
|
#else
|
||||||
|
uint32_t txt_len = strlen(ext->map_p[txt_i]) + 1;
|
||||||
|
if(txt_len > lv_mem_get_size(bidi_buf)) {
|
||||||
|
bidi_buf = lv_mem_realloc(bidi_buf, txt_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lv_bidi_process(ext->map_p[txt_i], bidi_buf, base_dir);
|
||||||
|
lv_draw_label(&area_tmp, clip_area, btn_style, opa_scale, bidi_buf, txt_flag, NULL, -1, -1, NULL);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#if LV_USE_BIDI
|
||||||
|
lv_mem_free(bidi_buf);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
return LV_DESIGN_RES_OK;
|
return LV_DESIGN_RES_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,6 +31,8 @@ extern "C" {
|
|||||||
#define LV_BTNM_WIDTH_MASK 0x0007
|
#define LV_BTNM_WIDTH_MASK 0x0007
|
||||||
#define LV_BTNM_BTN_NONE 0xFFFF
|
#define LV_BTNM_BTN_NONE 0xFFFF
|
||||||
|
|
||||||
|
LV_EXPORT_CONST_INT(LV_BTNM_BTN_NONE);
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
* TYPEDEFS
|
* TYPEDEFS
|
||||||
**********************/
|
**********************/
|
||||||
|
|||||||
@@ -34,6 +34,9 @@ extern "C" {
|
|||||||
/**Automatically calculate the tick length*/
|
/**Automatically calculate the tick length*/
|
||||||
#define LV_CHART_TICK_LENGTH_AUTO 255
|
#define LV_CHART_TICK_LENGTH_AUTO 255
|
||||||
|
|
||||||
|
LV_EXPORT_CONST_INT(LV_CHART_POINT_DEF);
|
||||||
|
LV_EXPORT_CONST_INT(LV_CHART_TICK_LENGTH_AUTO);
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
* TYPEDEFS
|
* TYPEDEFS
|
||||||
**********************/
|
**********************/
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
#include "../lv_misc/lv_area.h"
|
#include "../lv_misc/lv_area.h"
|
||||||
#include "../lv_misc/lv_color.h"
|
#include "../lv_misc/lv_color.h"
|
||||||
#include "../lv_misc/lv_math.h"
|
#include "../lv_misc/lv_math.h"
|
||||||
|
#include "../lv_misc/lv_bidi.h"
|
||||||
|
|
||||||
/*********************
|
/*********************
|
||||||
* DEFINES
|
* DEFINES
|
||||||
@@ -366,23 +367,23 @@ static void lv_cont_layout_row(lv_obj_t * cont)
|
|||||||
lv_align_t align;
|
lv_align_t align;
|
||||||
const lv_style_t * style = lv_obj_get_style(cont);
|
const lv_style_t * style = lv_obj_get_style(cont);
|
||||||
lv_coord_t vpad_corr;
|
lv_coord_t vpad_corr;
|
||||||
|
lv_bidi_dir_t base_dir = lv_obj_get_base_dir(cont);
|
||||||
switch(type) {
|
switch(type) {
|
||||||
case LV_LAYOUT_ROW_T:
|
case LV_LAYOUT_ROW_T:
|
||||||
vpad_corr = style->body.padding.top;
|
vpad_corr = style->body.padding.top;
|
||||||
align = LV_ALIGN_IN_TOP_LEFT;
|
align = base_dir == LV_BIDI_DIR_RTL ? LV_ALIGN_IN_TOP_RIGHT : LV_ALIGN_IN_TOP_LEFT;
|
||||||
break;
|
break;
|
||||||
case LV_LAYOUT_ROW_M:
|
case LV_LAYOUT_ROW_M:
|
||||||
vpad_corr = 0;
|
vpad_corr = 0;
|
||||||
align = LV_ALIGN_IN_LEFT_MID;
|
align = base_dir == LV_BIDI_DIR_RTL ? LV_ALIGN_IN_RIGHT_MID: LV_ALIGN_IN_LEFT_MID;
|
||||||
break;
|
break;
|
||||||
case LV_LAYOUT_ROW_B:
|
case LV_LAYOUT_ROW_B:
|
||||||
vpad_corr = -style->body.padding.bottom;
|
vpad_corr = -style->body.padding.bottom;
|
||||||
align = LV_ALIGN_IN_BOTTOM_LEFT;
|
align = base_dir == LV_BIDI_DIR_RTL ? LV_ALIGN_IN_BOTTOM_RIGHT: LV_ALIGN_IN_BOTTOM_LEFT;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
vpad_corr = 0;
|
vpad_corr = 0;
|
||||||
align = LV_ALIGN_IN_TOP_LEFT;
|
align = base_dir == LV_BIDI_DIR_RTL ? LV_ALIGN_IN_TOP_RIGHT : LV_ALIGN_IN_TOP_LEFT;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -391,12 +392,19 @@ static void lv_cont_layout_row(lv_obj_t * cont)
|
|||||||
lv_obj_set_protect(cont, LV_PROTECT_CHILD_CHG);
|
lv_obj_set_protect(cont, LV_PROTECT_CHILD_CHG);
|
||||||
|
|
||||||
/* Align the children */
|
/* Align the children */
|
||||||
lv_coord_t last_cord = style->body.padding.left;
|
lv_coord_t last_cord;
|
||||||
|
if(base_dir == LV_BIDI_DIR_RTL) last_cord = style->body.padding.right;
|
||||||
|
else last_cord = style->body.padding.left;
|
||||||
|
|
||||||
LV_LL_READ_BACK(cont->child_ll, child)
|
LV_LL_READ_BACK(cont->child_ll, child)
|
||||||
{
|
{
|
||||||
if(lv_obj_get_hidden(child) != false || lv_obj_is_protected(child, LV_PROTECT_POS) != false) continue;
|
if(lv_obj_get_hidden(child) != false || lv_obj_is_protected(child, LV_PROTECT_POS) != false) continue;
|
||||||
|
|
||||||
lv_obj_align(child, cont, align, last_cord, vpad_corr);
|
// last_cord -= lv_obj_get_width(child);
|
||||||
|
|
||||||
|
if(base_dir == LV_BIDI_DIR_RTL) lv_obj_align(child, cont, align, -last_cord, vpad_corr);
|
||||||
|
else lv_obj_align(child, cont, align, last_cord, vpad_corr);
|
||||||
|
|
||||||
last_cord += lv_obj_get_width(child) + style->body.padding.inner;
|
last_cord += lv_obj_get_width(child) + style->body.padding.inner;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -113,6 +113,11 @@ lv_obj_t * lv_ddlist_create(lv_obj_t * par, const lv_obj_t * copy)
|
|||||||
lv_obj_set_drag(scrl, false);
|
lv_obj_set_drag(scrl, false);
|
||||||
lv_page_set_scrl_fit2(new_ddlist, LV_FIT_FILL, LV_FIT_TIGHT);
|
lv_page_set_scrl_fit2(new_ddlist, LV_FIT_FILL, LV_FIT_TIGHT);
|
||||||
|
|
||||||
|
/*Save (a later restore) the original X coordinate because it changes as the FITs applies*/
|
||||||
|
lv_coord_t x;
|
||||||
|
if(lv_obj_get_base_dir(new_ddlist) == LV_BIDI_DIR_RTL) x = lv_obj_get_x(new_ddlist) + lv_obj_get_width(new_ddlist);
|
||||||
|
else x = lv_obj_get_x(new_ddlist);
|
||||||
|
|
||||||
ext->label = lv_label_create(new_ddlist, NULL);
|
ext->label = lv_label_create(new_ddlist, NULL);
|
||||||
lv_cont_set_fit2(new_ddlist, LV_FIT_TIGHT, LV_FIT_NONE);
|
lv_cont_set_fit2(new_ddlist, LV_FIT_TIGHT, LV_FIT_NONE);
|
||||||
lv_page_set_sb_mode(new_ddlist, LV_SB_MODE_HIDE);
|
lv_page_set_sb_mode(new_ddlist, LV_SB_MODE_HIDE);
|
||||||
@@ -120,6 +125,10 @@ lv_obj_t * lv_ddlist_create(lv_obj_t * par, const lv_obj_t * copy)
|
|||||||
|
|
||||||
lv_ddlist_set_options(new_ddlist, "Option 1\nOption 2\nOption 3");
|
lv_ddlist_set_options(new_ddlist, "Option 1\nOption 2\nOption 3");
|
||||||
|
|
||||||
|
/*Restore the original X coordinate*/
|
||||||
|
if(lv_obj_get_base_dir(new_ddlist) == LV_BIDI_DIR_RTL) lv_obj_set_x(new_ddlist, x - lv_obj_get_width(new_ddlist));
|
||||||
|
else lv_obj_set_x(new_ddlist, x);
|
||||||
|
|
||||||
/*Set the default styles*/
|
/*Set the default styles*/
|
||||||
lv_theme_t * th = lv_theme_get_current();
|
lv_theme_t * th = lv_theme_get_current();
|
||||||
if(th) {
|
if(th) {
|
||||||
@@ -131,6 +140,8 @@ lv_obj_t * lv_ddlist_create(lv_obj_t * par, const lv_obj_t * copy)
|
|||||||
lv_ddlist_set_style(new_ddlist, LV_DDLIST_STYLE_SEL, &lv_style_plain_color);
|
lv_ddlist_set_style(new_ddlist, LV_DDLIST_STYLE_SEL, &lv_style_plain_color);
|
||||||
lv_ddlist_set_style(new_ddlist, LV_DDLIST_STYLE_SB, &lv_style_pretty_color);
|
lv_ddlist_set_style(new_ddlist, LV_DDLIST_STYLE_SB, &lv_style_pretty_color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
/*Copy an existing drop down list*/
|
/*Copy an existing drop down list*/
|
||||||
else {
|
else {
|
||||||
@@ -186,7 +197,8 @@ void lv_ddlist_set_options(lv_obj_t * ddlist, const char * options)
|
|||||||
|
|
||||||
lv_ddlist_refr_width(ddlist);
|
lv_ddlist_refr_width(ddlist);
|
||||||
|
|
||||||
switch(lv_label_get_align(ext->label)) {
|
lv_label_align_t align = lv_label_get_align(ext->label);
|
||||||
|
switch(align) {
|
||||||
case LV_LABEL_ALIGN_LEFT: lv_obj_align(ext->label, NULL, LV_ALIGN_IN_LEFT_MID, 0, 0); break;
|
case LV_LABEL_ALIGN_LEFT: lv_obj_align(ext->label, NULL, LV_ALIGN_IN_LEFT_MID, 0, 0); break;
|
||||||
case LV_LABEL_ALIGN_CENTER: lv_obj_align(ext->label, NULL, LV_ALIGN_CENTER, 0, 0); break;
|
case LV_LABEL_ALIGN_CENTER: lv_obj_align(ext->label, NULL, LV_ALIGN_CENTER, 0, 0); break;
|
||||||
case LV_LABEL_ALIGN_RIGHT: lv_obj_align(ext->label, NULL, LV_ALIGN_IN_RIGHT_MID, 0, 0); break;
|
case LV_LABEL_ALIGN_RIGHT: lv_obj_align(ext->label, NULL, LV_ALIGN_IN_RIGHT_MID, 0, 0); break;
|
||||||
@@ -661,6 +673,15 @@ static lv_res_t lv_ddlist_signal(lv_obj_t * ddlist, lv_signal_t sign, void * par
|
|||||||
lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist);
|
lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist);
|
||||||
|
|
||||||
if(sign == LV_SIGNAL_STYLE_CHG) {
|
if(sign == LV_SIGNAL_STYLE_CHG) {
|
||||||
|
lv_ddlist_refr_size(ddlist, 0);
|
||||||
|
} else if(sign == LV_SIGNAL_BASE_DIR_CHG) {
|
||||||
|
lv_label_align_t align = lv_label_get_align(ext->label);
|
||||||
|
switch(align) {
|
||||||
|
case LV_LABEL_ALIGN_LEFT: lv_obj_align(ext->label, NULL, LV_ALIGN_IN_LEFT_MID, 0, 0); break;
|
||||||
|
case LV_LABEL_ALIGN_CENTER: lv_obj_align(ext->label, NULL, LV_ALIGN_CENTER, 0, 0); break;
|
||||||
|
case LV_LABEL_ALIGN_RIGHT: lv_obj_align(ext->label, NULL, LV_ALIGN_IN_RIGHT_MID, 0, 0); break;
|
||||||
|
}
|
||||||
|
|
||||||
lv_ddlist_refr_size(ddlist, 0);
|
lv_ddlist_refr_size(ddlist, 0);
|
||||||
} else if(sign == LV_SIGNAL_CLEANUP) {
|
} else if(sign == LV_SIGNAL_CLEANUP) {
|
||||||
ext->label = NULL;
|
ext->label = NULL;
|
||||||
@@ -980,11 +1001,20 @@ static void lv_ddlist_pos_current_option(lv_obj_t * ddlist)
|
|||||||
*/
|
*/
|
||||||
static void lv_ddlist_refr_width(lv_obj_t * ddlist)
|
static void lv_ddlist_refr_width(lv_obj_t * ddlist)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/*Save the current x coordinate because it should be kept after the refrsh*/
|
||||||
|
lv_coord_t x;
|
||||||
|
if(lv_obj_get_base_dir(ddlist) == LV_BIDI_DIR_RTL) x = lv_obj_get_x(ddlist) + lv_obj_get_width(ddlist);
|
||||||
|
else x = lv_obj_get_x(ddlist);
|
||||||
|
|
||||||
/*Set the TIGHT fit horizontally the set the width to the content*/
|
/*Set the TIGHT fit horizontally the set the width to the content*/
|
||||||
lv_page_set_scrl_fit2(ddlist, LV_FIT_TIGHT, lv_page_get_scrl_fit_bottom(ddlist));
|
lv_page_set_scrl_fit2(ddlist, LV_FIT_TIGHT, lv_page_get_scrl_fit_bottom(ddlist));
|
||||||
|
|
||||||
/*Revert FILL fit to fill the parent with the options area. It allows to RIGHT/CENTER align the text*/
|
/*Revert FILL fit to fill the parent with the options area. It allows to RIGHT/CENTER align the text*/
|
||||||
lv_page_set_scrl_fit2(ddlist, LV_FIT_FILL, lv_page_get_scrl_fit_bottom(ddlist));
|
lv_page_set_scrl_fit2(ddlist, LV_FIT_FILL, lv_page_get_scrl_fit_bottom(ddlist));
|
||||||
|
|
||||||
|
if(lv_obj_get_base_dir(ddlist) == LV_BIDI_DIR_RTL) lv_obj_set_x(ddlist, x - lv_obj_get_width(ddlist));
|
||||||
|
else lv_obj_set_x(ddlist, x);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -131,6 +131,7 @@ lv_obj_t * lv_kb_create(lv_obj_t * par, const lv_obj_t * copy)
|
|||||||
lv_obj_set_event_cb(new_kb, lv_kb_def_event_cb);
|
lv_obj_set_event_cb(new_kb, lv_kb_def_event_cb);
|
||||||
lv_btnm_set_map(new_kb, kb_map_lc);
|
lv_btnm_set_map(new_kb, kb_map_lc);
|
||||||
lv_btnm_set_ctrl_map(new_kb, kb_ctrl_lc_map);
|
lv_btnm_set_ctrl_map(new_kb, kb_ctrl_lc_map);
|
||||||
|
lv_obj_set_base_dir(new_kb, LV_BIDI_DIR_LTR);
|
||||||
|
|
||||||
/*Set the default styles*/
|
/*Set the default styles*/
|
||||||
lv_theme_t * th = lv_theme_get_current();
|
lv_theme_t * th = lv_theme_get_current();
|
||||||
@@ -395,7 +396,7 @@ void lv_kb_def_event_cb(lv_obj_t * kb, lv_event_t event)
|
|||||||
/*Add the characters to the text area if set*/
|
/*Add the characters to the text area if set*/
|
||||||
if(ext->ta == NULL) return;
|
if(ext->ta == NULL) return;
|
||||||
|
|
||||||
if(strcmp(txt, "Enter") == 0)
|
if(strcmp(txt, LV_SYMBOL_NEW_LINE) == 0)
|
||||||
lv_ta_add_char(ext->ta, '\n');
|
lv_ta_add_char(ext->ta, '\n');
|
||||||
else if(strcmp(txt, LV_SYMBOL_LEFT) == 0)
|
else if(strcmp(txt, LV_SYMBOL_LEFT) == 0)
|
||||||
lv_ta_cursor_left(ext->ta);
|
lv_ta_cursor_left(ext->ta);
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
#include "../lv_core/lv_group.h"
|
#include "../lv_core/lv_group.h"
|
||||||
#include "../lv_misc/lv_color.h"
|
#include "../lv_misc/lv_color.h"
|
||||||
#include "../lv_misc/lv_math.h"
|
#include "../lv_misc/lv_math.h"
|
||||||
|
#include "../lv_misc/lv_bidi.h"
|
||||||
#include "../lv_misc/lv_printf.h"
|
#include "../lv_misc/lv_printf.h"
|
||||||
|
|
||||||
/*********************
|
/*********************
|
||||||
@@ -92,7 +93,7 @@ lv_obj_t * lv_label_create(lv_obj_t * par, const lv_obj_t * copy)
|
|||||||
ext->static_txt = 0;
|
ext->static_txt = 0;
|
||||||
ext->recolor = 0;
|
ext->recolor = 0;
|
||||||
ext->body_draw = 0;
|
ext->body_draw = 0;
|
||||||
ext->align = LV_LABEL_ALIGN_LEFT;
|
ext->align = LV_LABEL_ALIGN_AUTO;
|
||||||
ext->dot_end = LV_LABEL_DOT_END_INV;
|
ext->dot_end = LV_LABEL_DOT_END_INV;
|
||||||
ext->long_mode = LV_LABEL_LONG_EXPAND;
|
ext->long_mode = LV_LABEL_LONG_EXPAND;
|
||||||
#if LV_USE_ANIMATION
|
#if LV_USE_ANIMATION
|
||||||
@@ -204,8 +205,14 @@ void lv_label_set_text(lv_obj_t * label, const char * text)
|
|||||||
LV_ASSERT_MEM(ext->text);
|
LV_ASSERT_MEM(ext->text);
|
||||||
if(ext->text == NULL) return;
|
if(ext->text == NULL) return;
|
||||||
|
|
||||||
|
#if LV_USE_BIDI == 0
|
||||||
strcpy(ext->text, text);
|
strcpy(ext->text, text);
|
||||||
ext->static_txt = 0; /*Now the text is dynamically allocated*/
|
#else
|
||||||
|
lv_bidi_dir_t base_dir = lv_obj_get_base_dir(label);
|
||||||
|
lv_bidi_process(text, ext->text, base_dir);
|
||||||
|
#endif
|
||||||
|
/*Now the text is dynamically allocated*/
|
||||||
|
ext->static_txt = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
lv_label_refr_text(label);
|
lv_label_refr_text(label);
|
||||||
@@ -506,7 +513,22 @@ lv_label_align_t lv_label_get_align(const lv_obj_t * label)
|
|||||||
LV_ASSERT_OBJ(label, LV_OBJX_NAME);
|
LV_ASSERT_OBJ(label, LV_OBJX_NAME);
|
||||||
|
|
||||||
lv_label_ext_t * ext = lv_obj_get_ext_attr(label);
|
lv_label_ext_t * ext = lv_obj_get_ext_attr(label);
|
||||||
return ext->align;
|
|
||||||
|
lv_label_align_t align = ext->align;
|
||||||
|
|
||||||
|
if(align == LV_LABEL_ALIGN_AUTO) {
|
||||||
|
#if LV_USE_BIDI
|
||||||
|
lv_bidi_dir_t base_dir = lv_obj_get_base_dir(label);
|
||||||
|
if(base_dir == LV_BIDI_DIR_AUTO) base_dir = lv_bidi_detect_base_dir(ext->text);
|
||||||
|
|
||||||
|
if(base_dir == LV_BIDI_DIR_LTR) align = LV_LABEL_ALIGN_LEFT;
|
||||||
|
else if (base_dir == LV_BIDI_DIR_RTL) align = LV_LABEL_ALIGN_RIGHT;
|
||||||
|
#else
|
||||||
|
align = LV_LABEL_ALIGN_LEFT;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
return align;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -578,7 +600,10 @@ void lv_label_get_letter_pos(const lv_obj_t * label, uint16_t index, lv_point_t
|
|||||||
|
|
||||||
if(ext->recolor != 0) flag |= LV_TXT_FLAG_RECOLOR;
|
if(ext->recolor != 0) flag |= LV_TXT_FLAG_RECOLOR;
|
||||||
if(ext->expand != 0) flag |= LV_TXT_FLAG_EXPAND;
|
if(ext->expand != 0) flag |= LV_TXT_FLAG_EXPAND;
|
||||||
if(ext->align == LV_LABEL_ALIGN_CENTER) flag |= LV_TXT_FLAG_CENTER;
|
|
||||||
|
lv_label_align_t align = lv_label_get_align(label);
|
||||||
|
if(align == LV_LABEL_ALIGN_CENTER) flag |= LV_TXT_FLAG_CENTER;
|
||||||
|
if(align == LV_LABEL_ALIGN_RIGHT) flag |= LV_TXT_FLAG_RIGHT;
|
||||||
|
|
||||||
/*If the width will be expanded the set the max length to very big */
|
/*If the width will be expanded the set the max length to very big */
|
||||||
if(ext->long_mode == LV_LABEL_LONG_EXPAND) {
|
if(ext->long_mode == LV_LABEL_LONG_EXPAND) {
|
||||||
@@ -610,12 +635,12 @@ void lv_label_get_letter_pos(const lv_obj_t * label, uint16_t index, lv_point_t
|
|||||||
|
|
||||||
if(index != line_start) x += style->text.letter_space;
|
if(index != line_start) x += style->text.letter_space;
|
||||||
|
|
||||||
if(ext->align == LV_LABEL_ALIGN_CENTER) {
|
if(align == LV_LABEL_ALIGN_CENTER) {
|
||||||
lv_coord_t line_w;
|
lv_coord_t line_w;
|
||||||
line_w = lv_txt_get_width(&txt[line_start], new_line_start - line_start, font, style->text.letter_space, flag);
|
line_w = lv_txt_get_width(&txt[line_start], new_line_start - line_start, font, style->text.letter_space, flag);
|
||||||
x += lv_obj_get_width(label) / 2 - line_w / 2;
|
x += lv_obj_get_width(label) / 2 - line_w / 2;
|
||||||
|
|
||||||
} else if(ext->align == LV_LABEL_ALIGN_RIGHT) {
|
} else if(align == LV_LABEL_ALIGN_RIGHT) {
|
||||||
lv_coord_t line_w;
|
lv_coord_t line_w;
|
||||||
line_w = lv_txt_get_width(&txt[line_start], new_line_start - line_start, font, style->text.letter_space, flag);
|
line_w = lv_txt_get_width(&txt[line_start], new_line_start - line_start, font, style->text.letter_space, flag);
|
||||||
|
|
||||||
@@ -650,7 +675,10 @@ uint16_t lv_label_get_letter_on(const lv_obj_t * label, lv_point_t * pos)
|
|||||||
|
|
||||||
if(ext->recolor != 0) flag |= LV_TXT_FLAG_RECOLOR;
|
if(ext->recolor != 0) flag |= LV_TXT_FLAG_RECOLOR;
|
||||||
if(ext->expand != 0) flag |= LV_TXT_FLAG_EXPAND;
|
if(ext->expand != 0) flag |= LV_TXT_FLAG_EXPAND;
|
||||||
if(ext->align == LV_LABEL_ALIGN_CENTER) flag |= LV_TXT_FLAG_CENTER;
|
|
||||||
|
lv_label_align_t align = lv_label_get_align(label);
|
||||||
|
if(align == LV_LABEL_ALIGN_CENTER) flag |= LV_TXT_FLAG_CENTER;
|
||||||
|
if(align == LV_LABEL_ALIGN_RIGHT) flag |= LV_TXT_FLAG_RIGHT;
|
||||||
|
|
||||||
/*If the width will be expanded set the max length to very big */
|
/*If the width will be expanded set the max length to very big */
|
||||||
if(ext->long_mode == LV_LABEL_LONG_EXPAND) {
|
if(ext->long_mode == LV_LABEL_LONG_EXPAND) {
|
||||||
@@ -669,11 +697,16 @@ uint16_t lv_label_get_letter_on(const lv_obj_t * label, lv_point_t * pos)
|
|||||||
|
|
||||||
/*Calculate the x coordinate*/
|
/*Calculate the x coordinate*/
|
||||||
lv_coord_t x = 0;
|
lv_coord_t x = 0;
|
||||||
if(ext->align == LV_LABEL_ALIGN_CENTER) {
|
if(align == LV_LABEL_ALIGN_CENTER) {
|
||||||
lv_coord_t line_w;
|
lv_coord_t line_w;
|
||||||
line_w = lv_txt_get_width(&txt[line_start], new_line_start - line_start, font, style->text.letter_space, flag);
|
line_w = lv_txt_get_width(&txt[line_start], new_line_start - line_start, font, style->text.letter_space, flag);
|
||||||
x += lv_obj_get_width(label) / 2 - line_w / 2;
|
x += lv_obj_get_width(label) / 2 - line_w / 2;
|
||||||
}
|
}
|
||||||
|
else if(align == LV_LABEL_ALIGN_RIGHT) {
|
||||||
|
lv_coord_t line_w;
|
||||||
|
line_w = lv_txt_get_width(&txt[line_start], new_line_start - line_start, font, style->text.letter_space, flag);
|
||||||
|
x += lv_obj_get_width(label) - line_w;
|
||||||
|
}
|
||||||
|
|
||||||
lv_txt_cmd_state_t cmd_state = LV_TXT_CMD_STATE_WAIT;
|
lv_txt_cmd_state_t cmd_state = LV_TXT_CMD_STATE_WAIT;
|
||||||
|
|
||||||
@@ -871,7 +904,18 @@ void lv_label_ins_text(lv_obj_t * label, uint32_t pos, const char * txt)
|
|||||||
pos = lv_txt_get_encoded_length(ext->text);
|
pos = lv_txt_get_encoded_length(ext->text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if LV_USE_BIDI
|
||||||
|
char * bidi_buf = lv_mem_alloc(ins_len) + 1;
|
||||||
|
LV_ASSERT_MEM(bidi_buf);
|
||||||
|
if(bidi_buf == NULL) return;
|
||||||
|
|
||||||
|
lv_bidi_process(txt, bidi_buf, lv_obj_get_base_dir(label));
|
||||||
|
lv_txt_ins(ext->text, pos, bidi_buf);
|
||||||
|
|
||||||
|
lv_mem_free(bidi_buf);
|
||||||
|
#else
|
||||||
lv_txt_ins(ext->text, pos, txt);
|
lv_txt_ins(ext->text, pos, txt);
|
||||||
|
#endif
|
||||||
|
|
||||||
lv_label_refr_text(label);
|
lv_label_refr_text(label);
|
||||||
}
|
}
|
||||||
@@ -947,14 +991,13 @@ static lv_design_res_t lv_label_design(lv_obj_t * label, const lv_area_t * clip_
|
|||||||
lv_draw_rect(&bg, clip_area, style, lv_obj_get_opa_scale(label));
|
lv_draw_rect(&bg, clip_area, style, lv_obj_get_opa_scale(label));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*TEST: draw a background for the label*/
|
lv_label_align_t align = lv_label_get_align(label);
|
||||||
// lv_draw_rect(&label->coords, mask, &lv_style_plain_color, LV_OPA_COVER);
|
|
||||||
|
|
||||||
lv_txt_flag_t flag = LV_TXT_FLAG_NONE;
|
lv_txt_flag_t flag = LV_TXT_FLAG_NONE;
|
||||||
if(ext->recolor != 0) flag |= LV_TXT_FLAG_RECOLOR;
|
if(ext->recolor != 0) flag |= LV_TXT_FLAG_RECOLOR;
|
||||||
if(ext->expand != 0) flag |= LV_TXT_FLAG_EXPAND;
|
if(ext->expand != 0) flag |= LV_TXT_FLAG_EXPAND;
|
||||||
if(ext->align == LV_LABEL_ALIGN_CENTER) flag |= LV_TXT_FLAG_CENTER;
|
if(align == LV_LABEL_ALIGN_CENTER) flag |= LV_TXT_FLAG_CENTER;
|
||||||
if(ext->align == LV_LABEL_ALIGN_RIGHT) flag |= LV_TXT_FLAG_RIGHT;
|
if(align == LV_LABEL_ALIGN_RIGHT) flag |= LV_TXT_FLAG_RIGHT;
|
||||||
|
|
||||||
/* In ROLL mode the CENTER and RIGHT are pointless so remove them.
|
/* In ROLL mode the CENTER and RIGHT are pointless so remove them.
|
||||||
* (In addition they will result mis-alignment is this case)*/
|
* (In addition they will result mis-alignment is this case)*/
|
||||||
@@ -1054,6 +1097,18 @@ static lv_res_t lv_label_signal(lv_obj_t * label, lv_signal_t sign, void * param
|
|||||||
label->ext_draw_pad = LV_MATH_MAX(label->ext_draw_pad, style->body.padding.bottom);
|
label->ext_draw_pad = LV_MATH_MAX(label->ext_draw_pad, style->body.padding.bottom);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if(sign == LV_SIGNAL_BASE_DIR_CHG) {
|
||||||
|
#if LV_USE_BIDI
|
||||||
|
if(ext->static_txt == 0) lv_label_set_text(label, NULL);
|
||||||
|
#endif
|
||||||
|
} else if(sign == LV_SIGNAL_GET_TYPE) {
|
||||||
|
lv_obj_type_t * buf = param;
|
||||||
|
uint8_t i;
|
||||||
|
for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/
|
||||||
|
if(buf->type[i] == NULL) break;
|
||||||
|
}
|
||||||
|
buf->type[i] = "lv_label";
|
||||||
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@@ -1137,11 +1192,12 @@ static void lv_label_refr_text(lv_obj_t * label)
|
|||||||
/*In roll inf. mode keep the size but start offset animations*/
|
/*In roll inf. mode keep the size but start offset animations*/
|
||||||
else if(ext->long_mode == LV_LABEL_LONG_SROLL_CIRC) {
|
else if(ext->long_mode == LV_LABEL_LONG_SROLL_CIRC) {
|
||||||
#if LV_USE_ANIMATION
|
#if LV_USE_ANIMATION
|
||||||
|
lv_label_align_t align = lv_label_get_align(label);
|
||||||
|
|
||||||
lv_anim_t anim;
|
lv_anim_t anim;
|
||||||
anim.var = label;
|
anim.var = label;
|
||||||
anim.repeat = 1;
|
anim.repeat = 1;
|
||||||
anim.playback = 0;
|
anim.playback = 0;
|
||||||
anim.start = 0;
|
|
||||||
anim.act_time = -(((lv_font_get_glyph_width(style->text.font, ' ', ' ') + style->text.letter_space) * 1000) /
|
anim.act_time = -(((lv_font_get_glyph_width(style->text.font, ' ', ' ') + style->text.letter_space) * 1000) /
|
||||||
ext->anim_speed) *
|
ext->anim_speed) *
|
||||||
LV_LABEL_WAIT_CHAR_COUNT;
|
LV_LABEL_WAIT_CHAR_COUNT;
|
||||||
@@ -1152,7 +1208,14 @@ static void lv_label_refr_text(lv_obj_t * label)
|
|||||||
|
|
||||||
bool hor_anim = false;
|
bool hor_anim = false;
|
||||||
if(size.x > lv_obj_get_width(label)) {
|
if(size.x > lv_obj_get_width(label)) {
|
||||||
|
if(align == LV_LABEL_ALIGN_RIGHT) {
|
||||||
|
anim.end = 0;
|
||||||
|
anim.start = -size.x - lv_font_get_glyph_width(font, ' ', ' ') * LV_LABEL_WAIT_CHAR_COUNT;
|
||||||
|
} else {
|
||||||
|
anim.start = 0;
|
||||||
anim.end = -size.x - lv_font_get_glyph_width(font, ' ', ' ') * LV_LABEL_WAIT_CHAR_COUNT;
|
anim.end = -size.x - lv_font_get_glyph_width(font, ' ', ' ') * LV_LABEL_WAIT_CHAR_COUNT;
|
||||||
|
}
|
||||||
|
|
||||||
anim.exec_cb = (lv_anim_exec_xcb_t)lv_label_set_offset_x;
|
anim.exec_cb = (lv_anim_exec_xcb_t)lv_label_set_offset_x;
|
||||||
anim.time = lv_anim_speed_to_time(ext->anim_speed, anim.start, anim.end);
|
anim.time = lv_anim_speed_to_time(ext->anim_speed, anim.start, anim.end);
|
||||||
lv_anim_create(&anim);
|
lv_anim_create(&anim);
|
||||||
@@ -1164,7 +1227,14 @@ static void lv_label_refr_text(lv_obj_t * label)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(size.y > lv_obj_get_height(label) && hor_anim == false) {
|
if(size.y > lv_obj_get_height(label) && hor_anim == false) {
|
||||||
|
if(align == LV_LABEL_ALIGN_RIGHT) {
|
||||||
|
anim.end = 0;
|
||||||
|
anim.start = -size.y - (lv_font_get_line_height(font));
|
||||||
|
} else {
|
||||||
|
anim.start = 0;
|
||||||
anim.end = -size.y - (lv_font_get_line_height(font));
|
anim.end = -size.y - (lv_font_get_line_height(font));
|
||||||
|
}
|
||||||
|
|
||||||
anim.exec_cb = (lv_anim_exec_xcb_t)lv_label_set_offset_y;
|
anim.exec_cb = (lv_anim_exec_xcb_t)lv_label_set_offset_y;
|
||||||
anim.time = lv_anim_speed_to_time(ext->anim_speed, anim.start, anim.end);
|
anim.time = lv_anim_speed_to_time(ext->anim_speed, anim.start, anim.end);
|
||||||
lv_anim_create(&anim);
|
lv_anim_create(&anim);
|
||||||
|
|||||||
@@ -35,6 +35,10 @@ extern "C" {
|
|||||||
#define LV_LABEL_POS_LAST 0xFFFF
|
#define LV_LABEL_POS_LAST 0xFFFF
|
||||||
#define LV_LABEL_TEXT_SEL_OFF 0xFFFF
|
#define LV_LABEL_TEXT_SEL_OFF 0xFFFF
|
||||||
|
|
||||||
|
LV_EXPORT_CONST_INT(LV_LABEL_DOT_NUM);
|
||||||
|
LV_EXPORT_CONST_INT(LV_LABEL_POS_LAST);
|
||||||
|
LV_EXPORT_CONST_INT(LV_LABEL_TEXT_SEL_OFF);
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
* TYPEDEFS
|
* TYPEDEFS
|
||||||
**********************/
|
**********************/
|
||||||
@@ -56,6 +60,7 @@ enum {
|
|||||||
LV_LABEL_ALIGN_LEFT, /**< Align text to left */
|
LV_LABEL_ALIGN_LEFT, /**< Align text to left */
|
||||||
LV_LABEL_ALIGN_CENTER, /**< Align text to center */
|
LV_LABEL_ALIGN_CENTER, /**< Align text to center */
|
||||||
LV_LABEL_ALIGN_RIGHT, /**< Align text to right */
|
LV_LABEL_ALIGN_RIGHT, /**< Align text to right */
|
||||||
|
LV_LABEL_ALIGN_AUTO, /**< Use LEFT or RIGHT depending on the direction of the text (LTR/RTL)*/
|
||||||
};
|
};
|
||||||
typedef uint8_t lv_label_align_t;
|
typedef uint8_t lv_label_align_t;
|
||||||
|
|
||||||
@@ -65,11 +70,12 @@ typedef struct
|
|||||||
/*Inherited from 'base_obj' so no inherited ext.*/ /*Ext. of ancestor*/
|
/*Inherited from 'base_obj' so no inherited ext.*/ /*Ext. of ancestor*/
|
||||||
/*New data for this type */
|
/*New data for this type */
|
||||||
char * text; /*Text of the label*/
|
char * text; /*Text of the label*/
|
||||||
|
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
char * tmp_ptr; /* Pointer to the allocated memory containing the character which are replaced by dots (Handled
|
char * tmp_ptr; /* Pointer to the allocated memory containing the character which are replaced by dots (Handled
|
||||||
by the library)*/
|
by the library)*/
|
||||||
char tmp[sizeof(char *)]; /* Directly store the characters if <=4 characters */
|
char tmp[LV_LABEL_DOT_NUM + 1]; /* Directly store the characters if <=4 characters */
|
||||||
} dot;
|
} dot;
|
||||||
uint16_t dot_end; /*The text end position in dot mode (Handled by the library)*/
|
uint16_t dot_end; /*The text end position in dot mode (Handled by the library)*/
|
||||||
lv_point_t offset; /*Text draw position offset*/
|
lv_point_t offset; /*Text draw position offset*/
|
||||||
|
|||||||
@@ -218,7 +218,8 @@ lv_obj_t * lv_list_add_btn(lv_obj_t * list, const void * img_src, const char * t
|
|||||||
lv_label_set_text(label, txt);
|
lv_label_set_text(label, txt);
|
||||||
lv_obj_set_click(label, false);
|
lv_obj_set_click(label, false);
|
||||||
lv_label_set_long_mode(label, LV_LABEL_LONG_SROLL_CIRC);
|
lv_label_set_long_mode(label, LV_LABEL_LONG_SROLL_CIRC);
|
||||||
lv_obj_set_width(label, liste->coords.x2 - label->coords.x1 - btn_hor_pad);
|
if(lv_obj_get_base_dir(liste) == LV_BIDI_DIR_RTL) lv_obj_set_width(label, label->coords.x2 - liste->coords.x1 - btn_hor_pad);
|
||||||
|
else lv_obj_set_width(label, liste->coords.x2 - label->coords.x1 - btn_hor_pad);
|
||||||
if(label_signal == NULL) label_signal = lv_obj_get_signal_cb(label);
|
if(label_signal == NULL) label_signal = lv_obj_get_signal_cb(label);
|
||||||
}
|
}
|
||||||
#if LV_USE_GROUP
|
#if LV_USE_GROUP
|
||||||
|
|||||||
@@ -871,8 +871,10 @@ static lv_res_t lv_page_signal(lv_obj_t * page, lv_signal_t sign, void * param)
|
|||||||
/*Automatically move children to the scrollable object*/
|
/*Automatically move children to the scrollable object*/
|
||||||
else if(sign == LV_SIGNAL_CHILD_CHG) {
|
else if(sign == LV_SIGNAL_CHILD_CHG) {
|
||||||
lv_obj_t * child;
|
lv_obj_t * child;
|
||||||
const lv_style_t * style = lv_page_get_style(page, LV_PAGE_STYLE_SCRL);
|
const lv_style_t * style_bg = lv_page_get_style(page, LV_PAGE_STYLE_BG);
|
||||||
|
const lv_style_t * style_scrl = lv_page_get_style(page, LV_PAGE_STYLE_SCRL);
|
||||||
lv_fit_t fit_left = lv_page_get_scrl_fit_left(page);
|
lv_fit_t fit_left = lv_page_get_scrl_fit_left(page);
|
||||||
|
lv_fit_t fit_right = lv_page_get_scrl_fit_right(page);
|
||||||
lv_fit_t fit_top = lv_page_get_scrl_fit_top(page);
|
lv_fit_t fit_top = lv_page_get_scrl_fit_top(page);
|
||||||
child = lv_obj_get_child(page, NULL);
|
child = lv_obj_get_child(page, NULL);
|
||||||
while(child != NULL) {
|
while(child != NULL) {
|
||||||
@@ -880,15 +882,19 @@ static lv_res_t lv_page_signal(lv_obj_t * page, lv_signal_t sign, void * param)
|
|||||||
lv_obj_t * tmp = child;
|
lv_obj_t * tmp = child;
|
||||||
child = lv_obj_get_child(page, child); /*Get the next child before move this*/
|
child = lv_obj_get_child(page, child); /*Get the next child before move this*/
|
||||||
|
|
||||||
/* Reposition the child to take padding into account (Only if it's on (0;0) now)
|
/* Reposition the child to take padding into account (Only if it's on (0;0) or (widht;height) coordinates now)
|
||||||
* It's required to keep new the object on the same coordinate if FIT is enabled.*/
|
* It's required to keep new the object on the same coordinate if FIT is enabled.*/
|
||||||
if((tmp->coords.x1 == page->coords.x1) && (fit_left == LV_FIT_TIGHT || fit_left == LV_FIT_FILL)) {
|
if((tmp->coords.x1 == page->coords.x1) && (fit_left == LV_FIT_TIGHT || fit_left == LV_FIT_FILL)) {
|
||||||
tmp->coords.x1 += style->body.padding.left;
|
tmp->coords.x1 += style_scrl->body.padding.left;
|
||||||
tmp->coords.x2 += style->body.padding.left;
|
tmp->coords.x2 += style_scrl->body.padding.left;
|
||||||
|
}
|
||||||
|
else if((tmp->coords.x2 == page->coords.x2) && (fit_right == LV_FIT_TIGHT || fit_right == LV_FIT_FILL)) {
|
||||||
|
tmp->coords.x1 -= style_scrl->body.padding.right + style_bg->body.padding.right;
|
||||||
|
tmp->coords.x2 -= style_scrl->body.padding.right + style_bg->body.padding.right;
|
||||||
}
|
}
|
||||||
if((tmp->coords.y1 == page->coords.y1) && (fit_top == LV_FIT_TIGHT || fit_top == LV_FIT_FILL)) {
|
if((tmp->coords.y1 == page->coords.y1) && (fit_top == LV_FIT_TIGHT || fit_top == LV_FIT_FILL)) {
|
||||||
tmp->coords.y1 += style->body.padding.top;
|
tmp->coords.y1 += style_scrl->body.padding.top;
|
||||||
tmp->coords.y2 += style->body.padding.top;
|
tmp->coords.y2 += style_scrl->body.padding.top;
|
||||||
}
|
}
|
||||||
lv_obj_set_parent(tmp, ext->scrl);
|
lv_obj_set_parent(tmp, ext->scrl);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -1850,53 +1850,53 @@ static void update_cursor_position_on_click(lv_obj_t * ta, lv_signal_t sign, lv_
|
|||||||
lv_indev_get_vect(click_source, &vect_act);
|
lv_indev_get_vect(click_source, &vect_act);
|
||||||
|
|
||||||
if(point_act.x < 0 || point_act.y < 0) return; /*Ignore event from keypad*/
|
if(point_act.x < 0 || point_act.y < 0) return; /*Ignore event from keypad*/
|
||||||
lv_point_t relative_position;
|
lv_point_t rel_pos;
|
||||||
relative_position.x = point_act.x - label_coords.x1;
|
rel_pos.x = point_act.x - label_coords.x1;
|
||||||
relative_position.y = point_act.y - label_coords.y1;
|
rel_pos.y = point_act.y - label_coords.y1;
|
||||||
|
|
||||||
lv_coord_t label_width = lv_obj_get_width(ext->label);
|
lv_coord_t label_width = lv_obj_get_width(ext->label);
|
||||||
|
|
||||||
uint16_t index_of_char_at_position;
|
uint16_t char_id_at_click;
|
||||||
|
|
||||||
#if LV_LABEL_TEXT_SEL
|
#if LV_LABEL_TEXT_SEL
|
||||||
lv_label_ext_t * ext_label = lv_obj_get_ext_attr(ext->label);
|
lv_label_ext_t * ext_label = lv_obj_get_ext_attr(ext->label);
|
||||||
bool click_outside_label;
|
bool click_outside_label;
|
||||||
/*Check if the click happened on the left side of the area outside the label*/
|
/*Check if the click happened on the left side of the area outside the label*/
|
||||||
if(relative_position.x < 0) {
|
if(rel_pos.x < 0) {
|
||||||
index_of_char_at_position = 0;
|
char_id_at_click = 0;
|
||||||
click_outside_label = true;
|
click_outside_label = true;
|
||||||
}
|
}
|
||||||
/*Check if the click happened on the right side of the area outside the label*/
|
/*Check if the click happened on the right side of the area outside the label*/
|
||||||
else if(relative_position.x >= label_width) {
|
else if(rel_pos.x >= label_width) {
|
||||||
index_of_char_at_position = LV_TA_CURSOR_LAST;
|
char_id_at_click = LV_TA_CURSOR_LAST;
|
||||||
click_outside_label = true;
|
click_outside_label = true;
|
||||||
} else {
|
} else {
|
||||||
index_of_char_at_position = lv_label_get_letter_on(ext->label, &relative_position);
|
char_id_at_click = lv_label_get_letter_on(ext->label, &rel_pos);
|
||||||
click_outside_label = !lv_label_is_char_under_pos(ext->label, &relative_position);
|
click_outside_label = !lv_label_is_char_under_pos(ext->label, &rel_pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ext->text_sel_en) {
|
if(ext->text_sel_en) {
|
||||||
if(!ext->text_sel_in_prog && !click_outside_label && sign == LV_SIGNAL_PRESSED) {
|
if(!ext->text_sel_in_prog && !click_outside_label && sign == LV_SIGNAL_PRESSED) {
|
||||||
/*Input device just went down. Store the selection start position*/
|
/*Input device just went down. Store the selection start position*/
|
||||||
ext->tmp_sel_start = index_of_char_at_position;
|
ext->tmp_sel_start = char_id_at_click;
|
||||||
ext->tmp_sel_end = LV_LABEL_TEXT_SEL_OFF;
|
ext->tmp_sel_end = LV_LABEL_TEXT_SEL_OFF;
|
||||||
ext->text_sel_in_prog = 1;
|
ext->text_sel_in_prog = 1;
|
||||||
lv_obj_set_drag(lv_page_get_scrl(ta), false);
|
lv_obj_set_drag(lv_page_get_scrl(ta), false);
|
||||||
} else if(ext->text_sel_in_prog && sign == LV_SIGNAL_PRESSING) {
|
} else if(ext->text_sel_in_prog && sign == LV_SIGNAL_PRESSING) {
|
||||||
/*Input device may be moving. Store the end position */
|
/*Input device may be moving. Store the end position */
|
||||||
ext->tmp_sel_end = index_of_char_at_position;
|
ext->tmp_sel_end = char_id_at_click;
|
||||||
} else if(ext->text_sel_in_prog && (sign == LV_SIGNAL_PRESS_LOST || sign == LV_SIGNAL_RELEASED)) {
|
} 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.*/
|
/*Input device is released. Check if anything was selected.*/
|
||||||
lv_obj_set_drag(lv_page_get_scrl(ta), true);
|
lv_obj_set_drag(lv_page_get_scrl(ta), true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ext->text_sel_in_prog || sign == LV_SIGNAL_PRESSED) lv_ta_set_cursor_pos(ta, index_of_char_at_position);
|
if(ext->text_sel_in_prog || sign == LV_SIGNAL_PRESSED) lv_ta_set_cursor_pos(ta, char_id_at_click);
|
||||||
|
|
||||||
if(ext->text_sel_in_prog) {
|
if(ext->text_sel_in_prog) {
|
||||||
/*If the selected area has changed then update the real values and*/
|
/*If the selected area has changed then update the real values and*/
|
||||||
/*invalidate the text area.*/
|
|
||||||
|
|
||||||
|
/*Invalidate the text area.*/
|
||||||
if(ext->tmp_sel_start > ext->tmp_sel_end) {
|
if(ext->tmp_sel_start > ext->tmp_sel_end) {
|
||||||
if(ext_label->txt_sel_start != ext->tmp_sel_end || ext_label->txt_sel_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_start = ext->tmp_sel_end;
|
||||||
@@ -1923,17 +1923,17 @@ static void update_cursor_position_on_click(lv_obj_t * ta, lv_signal_t sign, lv_
|
|||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
/*Check if the click happened on the left side of the area outside the label*/
|
/*Check if the click happened on the left side of the area outside the label*/
|
||||||
if(relative_position.x < 0) {
|
if(rel_pos.x < 0) {
|
||||||
index_of_char_at_position = 0;
|
char_id_at_click = 0;
|
||||||
}
|
}
|
||||||
/*Check if the click happened on the right side of the area outside the label*/
|
/*Check if the click happened on the right side of the area outside the label*/
|
||||||
else if(relative_position.x >= label_width) {
|
else if(rel_pos.x >= label_width) {
|
||||||
index_of_char_at_position = LV_TA_CURSOR_LAST;
|
char_id_at_click = LV_TA_CURSOR_LAST;
|
||||||
} else {
|
} else {
|
||||||
index_of_char_at_position = lv_label_get_letter_on(ext->label, &relative_position);
|
char_id_at_click = lv_label_get_letter_on(ext->label, &rel_pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(sign == LV_SIGNAL_PRESSED) lv_ta_set_cursor_pos(ta, index_of_char_at_position);
|
if(sign == LV_SIGNAL_PRESSED) lv_ta_set_cursor_pos(ta, char_id_at_click);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -39,6 +39,8 @@ extern "C" {
|
|||||||
*********************/
|
*********************/
|
||||||
#define LV_TA_CURSOR_LAST (0x7FFF) /*Put the cursor after the last character*/
|
#define LV_TA_CURSOR_LAST (0x7FFF) /*Put the cursor after the last character*/
|
||||||
|
|
||||||
|
LV_EXPORT_CONST_INT(LV_TA_CURSOR_LAST);
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
* TYPEDEFS
|
* TYPEDEFS
|
||||||
**********************/
|
**********************/
|
||||||
|
|||||||
@@ -145,20 +145,31 @@ void lv_table_set_cell_value(lv_obj_t * table, uint16_t row, uint16_t col, const
|
|||||||
uint32_t cell = row * ext->col_cnt + col;
|
uint32_t cell = row * ext->col_cnt + col;
|
||||||
lv_table_cell_format_t format;
|
lv_table_cell_format_t format;
|
||||||
|
|
||||||
|
lv_bidi_dir_t base_dir = lv_obj_get_base_dir(table);
|
||||||
|
|
||||||
/*Save the format byte*/
|
/*Save the format byte*/
|
||||||
if(ext->cell_data[cell]) {
|
if(ext->cell_data[cell]) {
|
||||||
format.format_byte = ext->cell_data[cell][0];
|
format.format_byte = ext->cell_data[cell][0];
|
||||||
}
|
}
|
||||||
/*Initialize the format byte*/
|
/*Initialize the format byte*/
|
||||||
else {
|
else {
|
||||||
format.s.align = LV_LABEL_ALIGN_LEFT;
|
if(base_dir == LV_BIDI_DIR_LTR) format.s.align = LV_LABEL_ALIGN_LEFT;
|
||||||
|
else if(base_dir == LV_BIDI_DIR_RTL) format.s.align = LV_LABEL_ALIGN_RIGHT;
|
||||||
|
else if(base_dir == LV_BIDI_DIR_AUTO) format.s.align = lv_bidi_detect_base_dir(txt);
|
||||||
|
|
||||||
format.s.right_merge = 0;
|
format.s.right_merge = 0;
|
||||||
format.s.type = 0;
|
format.s.type = 0;
|
||||||
format.s.crop = 0;
|
format.s.crop = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ext->cell_data[cell] = lv_mem_realloc(ext->cell_data[cell], strlen(txt) + 2); /*+1: trailing '\0; +1: format byte*/
|
ext->cell_data[cell] = lv_mem_realloc(ext->cell_data[cell], strlen(txt) + 2); /*+1: trailing '\0; +1: format byte*/
|
||||||
strcpy(ext->cell_data[cell] + 1, txt); /*Leave the format byte*/
|
|
||||||
|
#if LV_USE_BIDI == 0
|
||||||
|
strcpy(ext->cell_data[cell] + 1, txt); /*+1 to skip the format byte*/
|
||||||
|
#else
|
||||||
|
lv_bidi_process(txt, ext->cell_data[cell] + 1, base_dir);
|
||||||
|
#endif
|
||||||
|
|
||||||
ext->cell_data[cell][0] = format.format_byte;
|
ext->cell_data[cell][0] = format.format_byte;
|
||||||
refr_size(table);
|
refr_size(table);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -143,7 +143,7 @@ lv_obj_t * lv_tabview_create(lv_obj_t * par, const lv_obj_t * copy)
|
|||||||
lv_tabview_set_style(new_tabview, LV_TABVIEW_STYLE_BTN_TGL_PR, th->style.tabview.btn.tgl_pr);
|
lv_tabview_set_style(new_tabview, LV_TABVIEW_STYLE_BTN_TGL_PR, th->style.tabview.btn.tgl_pr);
|
||||||
} else {
|
} else {
|
||||||
lv_tabview_set_style(new_tabview, LV_TABVIEW_STYLE_BG, &lv_style_plain);
|
lv_tabview_set_style(new_tabview, LV_TABVIEW_STYLE_BG, &lv_style_plain);
|
||||||
lv_tabview_set_style(new_tabview, LV_TABVIEW_STYLE_BTN_BG, &lv_style_transp);
|
lv_tabview_set_style(new_tabview, LV_TABVIEW_STYLE_BTN_BG, &lv_style_pretty);//transp);
|
||||||
lv_tabview_set_style(new_tabview, LV_TABVIEW_STYLE_INDIC, &lv_style_plain_color);
|
lv_tabview_set_style(new_tabview, LV_TABVIEW_STYLE_INDIC, &lv_style_plain_color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -319,6 +319,10 @@ void lv_tabview_set_tab_act(lv_obj_t * tabview, uint16_t id, lv_anim_enable_t an
|
|||||||
|
|
||||||
ext->tab_cur = id;
|
ext->tab_cur = id;
|
||||||
|
|
||||||
|
if(lv_obj_get_base_dir(tabview) == LV_BIDI_DIR_RTL) {
|
||||||
|
id = (ext->tab_cnt - (id + 1));
|
||||||
|
}
|
||||||
|
|
||||||
lv_coord_t cont_x;
|
lv_coord_t cont_x;
|
||||||
|
|
||||||
switch(ext->btns_pos) {
|
switch(ext->btns_pos) {
|
||||||
@@ -358,6 +362,11 @@ void lv_tabview_set_tab_act(lv_obj_t * tabview, uint16_t id, lv_anim_enable_t an
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
lv_bidi_dir_t base_dir = lv_obj_get_base_dir(tabview);
|
||||||
|
|
||||||
|
if(base_dir == LV_BIDI_DIR_RTL) id = ext->tab_cnt - id - 1;
|
||||||
|
|
||||||
|
|
||||||
/*Move the indicator*/
|
/*Move the indicator*/
|
||||||
const lv_style_t * tabs_style = lv_obj_get_style(ext->btns);
|
const lv_style_t * tabs_style = lv_obj_get_style(ext->btns);
|
||||||
lv_coord_t indic_size;
|
lv_coord_t indic_size;
|
||||||
@@ -741,7 +750,6 @@ static lv_res_t tabview_scrl_signal(lv_obj_t * tabview_scrl, lv_signal_t sign, v
|
|||||||
if(res != LV_RES_OK) return res;
|
if(res != LV_RES_OK) return res;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user