bidi: add LV_LABEL_ALIGN_AUTO, LV_BIDI_DIR_AOUT/INHERIT, LV_SIGNAL_BASE_DIR_CHG

This commit is contained in:
Gabor Kiss-Vamosi
2019-10-08 16:26:55 +02:00
parent c64dc1d645
commit 6190763382
11 changed files with 211 additions and 25 deletions

View File

@@ -297,6 +297,19 @@ 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 " ,.;:-_"
/* 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 1
#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
/*=================== /*===================
* LV_OBJ SETTINGS * LV_OBJ SETTINGS
*==================*/ *==================*/

1
lvgl.h
View File

@@ -33,6 +33,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"

View File

@@ -412,6 +412,23 @@
#define LV_TXT_BREAK_CHARS " ,.;:-_" #define LV_TXT_BREAK_CHARS " ,.;:-_"
#endif #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 1
#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
/*=================== /*===================
* LV_OBJ SETTINGS * LV_OBJ SETTINGS
*==================*/ *==================*/

View File

@@ -49,6 +49,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 bool lv_obj_design(lv_obj_t * obj, const lv_area_t * mask_p, lv_design_mode_t mode); static bool lv_obj_design(lv_obj_t * obj, const lv_area_t * mask_p, lv_design_mode_t mode);
@@ -204,6 +205,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;
@@ -288,6 +299,12 @@ 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;
#if LV_USE_BIDI
new_obj->base_dir = LV_BIDI_DIR_INHERIT;
#else
new_obj->base_dir = LV_BIDI_DIR_LTR;
#endif
new_obj->reserved = 0;
new_obj->ext_attr = NULL; new_obj->ext_attr = NULL;
} }
@@ -1266,6 +1283,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
@@ -1931,6 +1965,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
@@ -2326,6 +2379,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;

View File

@@ -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"
/********************* /*********************
@@ -111,7 +112,8 @@ enum {
LV_SIGNAL_CHILD_CHG, /**< Child was removed/added */ LV_SIGNAL_CHILD_CHG, /**< Child was removed/added */
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 */
@@ -123,7 +125,8 @@ enum {
LV_SIGNAL_LONG_PRESS, /**< Object has been pressed for at least `LV_INDEV_LONG_PRESS_TIME`. Not called if dragged.*/ LV_SIGNAL_LONG_PRESS, /**< Object has been pressed for at least `LV_INDEV_LONG_PRESS_TIME`. Not called if dragged.*/
LV_SIGNAL_LONG_PRESS_REP, /**< Called after `LV_INDEV_LONG_PRESS_TIME` in every `LV_INDEV_LONG_PRESS_REP_TIME` ms. Not called if dragged.*/ LV_SIGNAL_LONG_PRESS_REP, /**< Called after `LV_INDEV_LONG_PRESS_TIME` in every `LV_INDEV_LONG_PRESS_REP_TIME` ms. Not called if dragged.*/
LV_SIGNAL_DRAG_BEGIN, LV_SIGNAL_DRAG_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,
@@ -218,7 +221,8 @@ typedef struct _lv_obj_t
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 : 2; /**< Which directions the object can be dragged in */ lv_drag_dir_t drag_dir : 2; /**< Which directions the object can be dragged in */
uint8_t reserved : 6; /**< 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*/
@@ -510,6 +514,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
@@ -849,6 +854,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

View File

@@ -89,11 +89,11 @@ void lv_style_init(void)
lv_style_scr.body.shadow.color = LV_COLOR_GRAY; lv_style_scr.body.shadow.color = LV_COLOR_GRAY;
lv_style_scr.body.shadow.type = LV_SHADOW_FULL; lv_style_scr.body.shadow.type = LV_SHADOW_FULL;
lv_style_scr.body.shadow.width = 0; lv_style_scr.body.shadow.width = 0;
LV_FONT_DECLARE(lv_font_heb_16);
lv_style_scr.text.opa = LV_OPA_COVER; lv_style_scr.text.opa = LV_OPA_COVER;
lv_style_scr.text.color = lv_color_make(0x30, 0x30, 0x30); lv_style_scr.text.color = lv_color_make(0x30, 0x30, 0x30);
lv_style_scr.text.sel_color = lv_color_make(0x55, 0x96, 0xd8); lv_style_scr.text.sel_color = lv_color_make(0x55, 0x96, 0xd8);
lv_style_scr.text.font = LV_FONT_DEFAULT; lv_style_scr.text.font = &lv_font_heb_16;//LV_FONT_DEFAULT;
lv_style_scr.text.letter_space = 0; lv_style_scr.text.letter_space = 0;
lv_style_scr.text.line_space = 2; lv_style_scr.text.line_space = 2;

View File

@@ -10,6 +10,8 @@
#include <stddef.h> #include <stddef.h>
#include "lv_txt.h" #include "lv_txt.h"
#if LV_USE_BIDI
/********************* /*********************
* DEFINES * DEFINES
*********************/ *********************/
@@ -62,7 +64,6 @@ void lv_bidi_process(const char * str_in, char * str_out, lv_bidi_dir_t base_dir
if(dir != LV_BIDI_DIR_NEUTRAL) break; if(dir != LV_BIDI_DIR_NEUTRAL) break;
} }
/*if there were neutrals in the beginning apply `base_dir` on them */
if(rd && str_in[rd] != '\0') lv_txt_encoded_prev(str_in, &rd); if(rd && str_in[rd] != '\0') lv_txt_encoded_prev(str_in, &rd);
if(rd) { if(rd) {
@@ -110,6 +111,21 @@ 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)
{
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 */
return LV_BIDI_BASE_DIR_DEF;
}
lv_bidi_dir_t lv_bidi_get_letter_dir(uint32_t letter) lv_bidi_dir_t lv_bidi_get_letter_dir(uint32_t letter)
{ {
@@ -279,7 +295,6 @@ static uint32_t char_change_to_pair(uint32_t letter)
} }
return letter; return letter;
} }
#endif /*LV_USE_BIDI*/

View File

@@ -23,19 +23,27 @@ extern "C" {
/********************** /**********************
* TYPEDEFS * TYPEDEFS
**********************/ **********************/
typedef enum enum
{ {
LV_BIDI_DIR_LTR, /*The first 4 values are stored in `lv_obj_t` on 2 bits*/
LV_BIDI_DIR_RTL, LV_BIDI_DIR_LTR = 0x00,
LV_BIDI_DIR_NEUTRAL, LV_BIDI_DIR_RTL = 0x01,
LV_BIDI_DIR_WEAK, LV_BIDI_DIR_AUTO = 0x02,
}lv_bidi_dir_t; LV_BIDI_DIR_INHERIT = 0x03,
LV_BIDI_DIR_NEUTRAL = 0x20,
LV_BIDI_DIR_WEAK = 0x21,
};
typedef uint8_t lv_bidi_dir_t;
/********************** /**********************
* GLOBAL PROTOTYPES * GLOBAL PROTOTYPES
**********************/ **********************/
void lv_bidi_process(const char * str_in, char * str_out, lv_bidi_dir_t base_dir); #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); 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_weak(uint32_t letter);
bool lv_bidi_letter_is_rtl(uint32_t letter); bool lv_bidi_letter_is_rtl(uint32_t letter);
@@ -45,6 +53,8 @@ bool lv_bidi_letter_is_neutral(uint32_t letter);
* MACROS * MACROS
**********************/ **********************/
#endif /*LV_USE_BIDI*/
#ifdef __cplusplus #ifdef __cplusplus
} /* extern "C" */ } /* extern "C" */
#endif #endif

View File

@@ -180,7 +180,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;
@@ -621,6 +622,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;

View File

@@ -13,6 +13,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"
/********************* /*********************
* DEFINES * DEFINES
@@ -88,7 +89,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
@@ -190,14 +191,33 @@ void lv_label_set_text(lv_obj_t * label, const char * text)
if(ext->text != NULL && ext->static_txt == 0) { if(ext->text != NULL && ext->static_txt == 0) {
lv_mem_free(ext->text); lv_mem_free(ext->text);
ext->text = NULL; ext->text = NULL;
#if LV_USE_BIDI
lv_mem_free(ext->text_ori);
ext->text_ori = NULL;
#endif
} }
ext->text = lv_mem_alloc(len); ext->text = lv_mem_alloc(len);
lv_mem_assert(ext->text); lv_mem_assert(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
ext->text_ori = lv_mem_alloc(len);
lv_mem_assert(ext->text_ori);
if(ext->text_ori == NULL) return;
strcpy(ext->text_ori, text);
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(text);
lv_bidi_process(ext->text_ori, 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);
@@ -425,7 +445,22 @@ lv_label_long_mode_t lv_label_get_long_mode(const lv_obj_t * label)
lv_label_align_t lv_label_get_align(const lv_obj_t * label) lv_label_align_t lv_label_get_align(const lv_obj_t * label)
{ {
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;
} }
/** /**
@@ -842,14 +877,13 @@ static bool lv_label_design(lv_obj_t * label, const lv_area_t * mask, lv_design_
lv_draw_rect(&bg, mask, style, lv_obj_get_opa_scale(label)); lv_draw_rect(&bg, mask, 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)*/
@@ -947,6 +981,9 @@ 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.top); label->ext_draw_pad = LV_MATH_MAX(label->ext_draw_pad, style->body.padding.top);
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(ext->static_txt == 0) lv_label_set_text(label, NULL);
} else if(sign == LV_SIGNAL_GET_TYPE) { } else if(sign == LV_SIGNAL_GET_TYPE) {
lv_obj_type_t * buf = param; lv_obj_type_t * buf = param;
uint8_t i; uint8_t i;

View File

@@ -55,6 +55,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;
@@ -63,12 +64,17 @@ 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*/
#if LV_USE_BIDI
char * text_ori; /*The original text. With BiDi `text` stores the characters in "bidi" ordered text*/
#endif
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*/