Merge branch 'dev-6.1' into fix/txt_long_len
This commit is contained in:
@@ -236,7 +236,7 @@ typedef void * lv_indev_drv_user_data_t; /*Type of user data in the i
|
|||||||
# define LV_LOG_LEVEL LV_LOG_LEVEL_WARN
|
# define LV_LOG_LEVEL LV_LOG_LEVEL_WARN
|
||||||
|
|
||||||
/* 1: Print the log with 'printf';
|
/* 1: Print the log with 'printf';
|
||||||
* 0: user need to register a callback with `lv_log_register_print`*/
|
* 0: user need to register a callback with `lv_log_register_print_cb`*/
|
||||||
# define LV_LOG_PRINTF 0
|
# define LV_LOG_PRINTF 0
|
||||||
#endif /*LV_USE_LOG*/
|
#endif /*LV_USE_LOG*/
|
||||||
|
|
||||||
@@ -344,7 +344,8 @@ 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 word is at least this long, will break wherever "prettiest"
|
||||||
* To disable, set to a value <= 0 */
|
* To disable, set to a value <= 0 */
|
||||||
#define LV_TXT_LINE_BREAK_LONG_LEN 12
|
#define LV_TXT_LINE_BREAK_LONG_LEN 12
|
||||||
|
|
||||||
@@ -356,6 +357,19 @@ typedef void * lv_font_user_data_t;
|
|||||||
* Depends on LV_TXT_LINE_BREAK_LONG_LEN. */
|
* Depends on LV_TXT_LINE_BREAK_LONG_LEN. */
|
||||||
#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
|
||||||
#if LV_SPRINTF_CUSTOM
|
#if LV_SPRINTF_CUSTOM
|
||||||
|
|||||||
2
lvgl.h
2
lvgl.h
@@ -25,6 +25,7 @@ extern "C" {
|
|||||||
|
|
||||||
#include "src/lv_core/lv_obj.h"
|
#include "src/lv_core/lv_obj.h"
|
||||||
#include "src/lv_core/lv_group.h"
|
#include "src/lv_core/lv_group.h"
|
||||||
|
#include "src/lv_core/lv_indev.h"
|
||||||
|
|
||||||
#include "src/lv_core/lv_refr.h"
|
#include "src/lv_core/lv_refr.h"
|
||||||
#include "src/lv_core/lv_disp.h"
|
#include "src/lv_core/lv_disp.h"
|
||||||
@@ -34,6 +35,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"
|
||||||
|
|||||||
@@ -473,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 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);
|
||||||
@@ -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);
|
||||||
@@ -1321,6 +1348,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
|
||||||
@@ -1742,8 +1786,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);
|
||||||
rel_x = obj->coords.x1 - parent->coords.x1;
|
if(parent) {
|
||||||
|
rel_x = obj->coords.x1 - parent->coords.x1;
|
||||||
|
} else {
|
||||||
|
rel_x = obj->coords.x1;
|
||||||
|
}
|
||||||
return rel_x;
|
return rel_x;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1758,8 +1805,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);
|
||||||
rel_y = obj->coords.y1 - parent->coords.y1;
|
if(parent) {
|
||||||
|
rel_y = obj->coords.y1 - parent->coords.y1;
|
||||||
|
} else {
|
||||||
|
rel_y = obj->coords.y1;
|
||||||
|
}
|
||||||
return rel_y;
|
return rel_y;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2068,6 +2118,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
|
||||||
@@ -2512,6 +2581,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"
|
||||||
|
|
||||||
/*********************
|
/*********************
|
||||||
@@ -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 */
|
||||||
|
|
||||||
@@ -124,6 +126,7 @@ enum {
|
|||||||
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
|
||||||
|
|||||||
@@ -215,79 +215,6 @@ void lv_draw_arc(lv_coord_t center_x, lv_coord_t center_y, uint16_t radius, cons
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint16_t fast_atan2(int x, int y)
|
|
||||||
{
|
|
||||||
// Fast XY vector to integer degree algorithm - Jan 2011 www.RomanBlack.com
|
|
||||||
// Converts any XY values including 0 to a degree value that should be
|
|
||||||
// within +/- 1 degree of the accurate value without needing
|
|
||||||
// large slow trig functions like ArcTan() or ArcCos().
|
|
||||||
// NOTE! at least one of the X or Y values must be non-zero!
|
|
||||||
// This is the full version, for all 4 quadrants and will generate
|
|
||||||
// the angle in integer degrees from 0-360.
|
|
||||||
// Any values of X and Y are usable including negative values provided
|
|
||||||
// they are between -1456 and 1456 so the 16bit multiply does not overflow.
|
|
||||||
|
|
||||||
unsigned char negflag;
|
|
||||||
unsigned char tempdegree;
|
|
||||||
unsigned char comp;
|
|
||||||
unsigned int degree; /*this will hold the result*/
|
|
||||||
unsigned int ux;
|
|
||||||
unsigned int uy;
|
|
||||||
|
|
||||||
/*Save the sign flags then remove signs and get XY as unsigned ints*/
|
|
||||||
negflag = 0;
|
|
||||||
if(x < 0) {
|
|
||||||
negflag += 0x01; /*x flag bit*/
|
|
||||||
x = (0 - x); /*is now +*/
|
|
||||||
}
|
|
||||||
ux = x; /*copy to unsigned var before multiply*/
|
|
||||||
if(y < 0) {
|
|
||||||
negflag += 0x02; /*y flag bit*/
|
|
||||||
y = (0 - y); /*is now +*/
|
|
||||||
}
|
|
||||||
uy = y; /*copy to unsigned var before multiply*/
|
|
||||||
|
|
||||||
/*1. Calc the scaled "degrees"*/
|
|
||||||
if(ux > uy) {
|
|
||||||
degree = (uy * 45) / ux; /*degree result will be 0-45 range*/
|
|
||||||
negflag += 0x10; /*octant flag bit*/
|
|
||||||
} else {
|
|
||||||
degree = (ux * 45) / uy; /*degree result will be 0-45 range*/
|
|
||||||
}
|
|
||||||
|
|
||||||
/*2. Compensate for the 4 degree error curve*/
|
|
||||||
comp = 0;
|
|
||||||
tempdegree = degree; /*use an unsigned char for speed!*/
|
|
||||||
if(tempdegree > 22) { /*if top half of range*/
|
|
||||||
if(tempdegree <= 44) comp++;
|
|
||||||
if(tempdegree <= 41) comp++;
|
|
||||||
if(tempdegree <= 37) comp++;
|
|
||||||
if(tempdegree <= 32) comp++; /*max is 4 degrees compensated*/
|
|
||||||
} else { /*else is lower half of range*/
|
|
||||||
if(tempdegree >= 2) comp++;
|
|
||||||
if(tempdegree >= 6) comp++;
|
|
||||||
if(tempdegree >= 10) comp++;
|
|
||||||
if(tempdegree >= 15) comp++; /*max is 4 degrees compensated*/
|
|
||||||
}
|
|
||||||
degree += comp; /*degree is now accurate to +/- 1 degree!*/
|
|
||||||
|
|
||||||
/*Invert degree if it was X>Y octant, makes 0-45 into 90-45*/
|
|
||||||
if(negflag & 0x10) degree = (90 - degree);
|
|
||||||
|
|
||||||
/*3. Degree is now 0-90 range for this quadrant,*/
|
|
||||||
/*need to invert it for whichever quadrant it was in*/
|
|
||||||
if(negflag & 0x02) { /*if -Y*/
|
|
||||||
if(negflag & 0x01) /*if -Y -X*/
|
|
||||||
degree = (180 + degree);
|
|
||||||
else /*else is -Y +X*/
|
|
||||||
degree = (180 - degree);
|
|
||||||
} else { /*else is +Y*/
|
|
||||||
if(negflag & 0x01) /*if +Y -X*/
|
|
||||||
degree = (360 - degree);
|
|
||||||
}
|
|
||||||
return degree;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
* STATIC FUNCTIONS
|
* STATIC FUNCTIONS
|
||||||
**********************/
|
**********************/
|
||||||
|
|||||||
@@ -343,11 +343,7 @@ void lv_draw_letter(const lv_point_t * pos_p, const lv_area_t * mask_p, const lv
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
uint8_t font_rgb[3];
|
uint8_t font_rgb[3];
|
||||||
#if LV_COLOR_16_SWAP == 0
|
uint8_t txt_rgb[3] = {LV_COLOR_GET_R(color), LV_COLOR_GET_G(color), LV_COLOR_GET_B(color)};
|
||||||
uint8_t txt_rgb[3] = {color.ch.red, color.ch.green, color.ch.blue};
|
|
||||||
#else
|
|
||||||
uint8_t txt_rgb[3] = {color.ch.red, (color.ch.green_h << 3) + color.ch.green_l, color.ch.blue};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
for(row = row_start; row < row_end; row++) {
|
for(row = row_start; row < row_end; row++) {
|
||||||
bitmask = bitmask_init >> col_bit;
|
bitmask = bitmask_init >> col_bit;
|
||||||
@@ -407,30 +403,16 @@ void lv_draw_letter(const lv_point_t * pos_p, const lv_area_t * mask_p, const lv
|
|||||||
res_color = *vdb_buf_tmp;
|
res_color = *vdb_buf_tmp;
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
#if LV_COLOR_16_SWAP == 0
|
uint8_t bg_rgb[3] = {LV_COLOR_GET_R(*vdb_buf_tmp), LV_COLOR_GET_G(*vdb_buf_tmp), LV_COLOR_GET_B(*vdb_buf_tmp)};
|
||||||
uint8_t bg_rgb[3] = {vdb_buf_tmp->ch.red, vdb_buf_tmp->ch.green, vdb_buf_tmp->ch.blue};
|
|
||||||
#else
|
|
||||||
uint8_t bg_rgb[3] = {vdb_buf_tmp->ch.red,
|
|
||||||
(vdb_buf_tmp->ch.green_h << 3) + vdb_buf_tmp->ch.green_l,
|
|
||||||
vdb_buf_tmp->ch.blue};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if LV_SUBPX_BGR
|
#if LV_SUBPX_BGR
|
||||||
res_color.ch.blue = (uint16_t)((uint16_t)txt_rgb[0] * font_rgb[0] + (bg_rgb[2] * (255 - font_rgb[0]))) >> 8;
|
LV_COLOR_SET_B(res_color, (uint16_t)((uint16_t)txt_rgb[0] * font_rgb[0] + (bg_rgb[2] * (255 - font_rgb[0]))) >> 8);
|
||||||
res_color.ch.red = (uint16_t)((uint16_t)txt_rgb[2] * font_rgb[2] + (bg_rgb[0] * (255 - font_rgb[2]))) >> 8;
|
LV_COLOR_SET_R(res_color, (uint16_t)((uint16_t)txt_rgb[2] * font_rgb[2] + (bg_rgb[0] * (255 - font_rgb[2]))) >> 8);
|
||||||
#else
|
#else
|
||||||
res_color.ch.red = (uint16_t)((uint16_t)txt_rgb[0] * font_rgb[0] + (bg_rgb[0] * (255 - font_rgb[0]))) >> 8;
|
LV_COLOR_SET_R(res_color, (uint16_t)((uint16_t)txt_rgb[0] * font_rgb[0] + (bg_rgb[0] * (255 - font_rgb[0]))) >> 8);
|
||||||
res_color.ch.blue = (uint16_t)((uint16_t)txt_rgb[2] * font_rgb[2] + (bg_rgb[2] * (255 - font_rgb[2]))) >> 8;
|
LV_COLOR_SET_B(res_color, (uint16_t)((uint16_t)txt_rgb[2] * font_rgb[2] + (bg_rgb[2] * (255 - font_rgb[2]))) >> 8);
|
||||||
#endif
|
#endif
|
||||||
|
LV_COLOR_SET_G(res_color, (uint16_t)((uint16_t)txt_rgb[1] * font_rgb[1] + (bg_rgb[1] * (255 - font_rgb[1]))) >> 8);
|
||||||
#if LV_COLOR_16_SWAP == 0
|
|
||||||
res_color.ch.green = (uint16_t)((uint16_t)txt_rgb[1] * font_rgb[1] + (bg_rgb[1] * (255 - font_rgb[1]))) >> 8;
|
|
||||||
#else
|
|
||||||
uint8_t green = (uint16_t)((uint16_t)txt_rgb[1] * font_rgb[1] + (bg_rgb[1] * (255 - font_rgb[1]))) >> 8;
|
|
||||||
res_color.ch.green_h = green >> 3;
|
|
||||||
res_color.ch.green_l = green & 0x7;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
}
|
||||||
if(scr_transp == false) {
|
if(scr_transp == false) {
|
||||||
vdb_buf_tmp->full = res_color.full;
|
vdb_buf_tmp->full = res_color.full;
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ void lv_draw_img(const lv_area_t * coords, const lv_area_t * mask, const void *
|
|||||||
if(src == NULL) {
|
if(src == NULL) {
|
||||||
LV_LOG_WARN("Image draw: src is NULL");
|
LV_LOG_WARN("Image draw: src is NULL");
|
||||||
lv_draw_rect(coords, mask, &lv_style_plain, LV_OPA_COVER);
|
lv_draw_rect(coords, mask, &lv_style_plain, LV_OPA_COVER);
|
||||||
lv_draw_label(coords, mask, &lv_style_plain, LV_OPA_COVER, "No\ndata", LV_TXT_FLAG_NONE, NULL, NULL, NULL);
|
lv_draw_label(coords, mask, &lv_style_plain, LV_OPA_COVER, "No\ndata", LV_TXT_FLAG_NONE, NULL, NULL, NULL, LV_BIDI_DIR_LTR);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,7 +61,7 @@ void lv_draw_img(const lv_area_t * coords, const lv_area_t * mask, const void *
|
|||||||
if(res == LV_RES_INV) {
|
if(res == LV_RES_INV) {
|
||||||
LV_LOG_WARN("Image draw error");
|
LV_LOG_WARN("Image draw error");
|
||||||
lv_draw_rect(coords, mask, &lv_style_plain, LV_OPA_COVER);
|
lv_draw_rect(coords, mask, &lv_style_plain, LV_OPA_COVER);
|
||||||
lv_draw_label(coords, mask, &lv_style_plain, LV_OPA_COVER, "No\ndata", LV_TXT_FLAG_NONE, NULL, NULL, NULL);
|
lv_draw_label(coords, mask, &lv_style_plain, LV_OPA_COVER, "No\ndata", LV_TXT_FLAG_NONE, NULL, NULL, NULL, LV_BIDI_DIR_LTR);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -562,7 +562,7 @@ static lv_res_t lv_img_draw_core(const lv_area_t * coords, const lv_area_t * mas
|
|||||||
if(cdsc->dec_dsc.error_msg != NULL) {
|
if(cdsc->dec_dsc.error_msg != NULL) {
|
||||||
LV_LOG_WARN("Image draw error");
|
LV_LOG_WARN("Image draw error");
|
||||||
lv_draw_rect(coords, mask, &lv_style_plain, LV_OPA_COVER);
|
lv_draw_rect(coords, mask, &lv_style_plain, LV_OPA_COVER);
|
||||||
lv_draw_label(coords, mask, &lv_style_plain, LV_OPA_COVER, cdsc->dec_dsc.error_msg, LV_TXT_FLAG_NONE, NULL, NULL, NULL);
|
lv_draw_label(coords, mask, &lv_style_plain, LV_OPA_COVER, cdsc->dec_dsc.error_msg, LV_TXT_FLAG_NONE, NULL, NULL, NULL, LV_BIDI_DIR_LTR);
|
||||||
}
|
}
|
||||||
/* The decoder open could open the image and gave the entire uncompressed image.
|
/* The decoder open could open the image and gave the entire uncompressed image.
|
||||||
* Just draw it!*/
|
* Just draw it!*/
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
*********************/
|
*********************/
|
||||||
#include "lv_draw_label.h"
|
#include "lv_draw_label.h"
|
||||||
#include "../lv_misc/lv_math.h"
|
#include "../lv_misc/lv_math.h"
|
||||||
|
#include "../lv_misc/lv_bidi.h"
|
||||||
|
|
||||||
/*********************
|
/*********************
|
||||||
* DEFINES
|
* DEFINES
|
||||||
@@ -55,16 +56,13 @@ static uint8_t hex_char_to_num(char hex);
|
|||||||
*/
|
*/
|
||||||
void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_style_t * style, lv_opa_t opa_scale,
|
void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_style_t * style, lv_opa_t opa_scale,
|
||||||
const char * txt, lv_txt_flag_t flag, lv_point_t * offset, lv_draw_label_txt_sel_t * sel,
|
const char * txt, lv_txt_flag_t flag, lv_point_t * offset, lv_draw_label_txt_sel_t * sel,
|
||||||
lv_draw_label_hint_t * hint)
|
lv_draw_label_hint_t * hint, lv_bidi_dir_t bidi_dir)
|
||||||
{
|
{
|
||||||
const lv_font_t * font = style->text.font;
|
const lv_font_t * font = style->text.font;
|
||||||
lv_coord_t w;
|
lv_coord_t w;
|
||||||
|
|
||||||
/*No need to waste processor time if string is empty*/
|
/*No need to waste processor time if string is empty*/
|
||||||
if (txt[0] == '\0')
|
if (txt[0] == '\0') return;
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if((flag & LV_TXT_FLAG_EXPAND) == 0) {
|
if((flag & LV_TXT_FLAG_EXPAND) == 0) {
|
||||||
/*Normally use the label's width as width*/
|
/*Normally use the label's width as width*/
|
||||||
@@ -73,7 +71,7 @@ void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_st
|
|||||||
/*If EXAPND is enabled then not limit the text's width to the object's width*/
|
/*If EXAPND is enabled then not limit the text's width to the object's width*/
|
||||||
lv_point_t p;
|
lv_point_t p;
|
||||||
lv_txt_get_size(&p, txt, style->text.font, style->text.letter_space, style->text.line_space, LV_COORD_MAX,
|
lv_txt_get_size(&p, txt, style->text.font, style->text.letter_space, style->text.line_space, LV_COORD_MAX,
|
||||||
flag);
|
flag);
|
||||||
w = p.x;
|
w = p.x;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -111,6 +109,7 @@ void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_st
|
|||||||
pos.y += hint->y;
|
pos.y += hint->y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uint32_t line_end = line_start + lv_txt_get_next_line(&txt[line_start], font, style->text.letter_space, w, flag);
|
uint32_t line_end = line_start + lv_txt_get_next_line(&txt[line_start], font, style->text.letter_space, w, flag);
|
||||||
|
|
||||||
/*Go the first visible line*/
|
/*Go the first visible line*/
|
||||||
@@ -145,6 +144,18 @@ void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_st
|
|||||||
|
|
||||||
lv_opa_t opa = opa_scale == LV_OPA_COVER ? style->text.opa : (uint16_t)((uint16_t)style->text.opa * opa_scale) >> 8;
|
lv_opa_t opa = opa_scale == LV_OPA_COVER ? style->text.opa : (uint16_t)((uint16_t)style->text.opa * opa_scale) >> 8;
|
||||||
|
|
||||||
|
uint16_t sel_start = 0xFFFF;
|
||||||
|
uint16_t sel_end = 0xFFFF;
|
||||||
|
if(sel) {
|
||||||
|
sel_start = sel->start;
|
||||||
|
sel_end = sel->end;
|
||||||
|
if(sel_start > sel_end) {
|
||||||
|
uint16_t tmp = sel_start;
|
||||||
|
sel_start = sel_end;
|
||||||
|
sel_end = tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
cmd_state_t cmd_state = CMD_STATE_WAIT;
|
cmd_state_t cmd_state = CMD_STATE_WAIT;
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
uint16_t par_start = 0;
|
uint16_t par_start = 0;
|
||||||
@@ -161,12 +172,31 @@ void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_st
|
|||||||
}
|
}
|
||||||
/*Write all letter of a line*/
|
/*Write all letter of a line*/
|
||||||
cmd_state = CMD_STATE_WAIT;
|
cmd_state = CMD_STATE_WAIT;
|
||||||
i = line_start;
|
i = 0;
|
||||||
uint32_t letter;
|
uint32_t letter;
|
||||||
uint32_t letter_next;
|
uint32_t letter_next;
|
||||||
while(i < line_end) {
|
#if LV_USE_BIDI
|
||||||
letter = lv_txt_encoded_next(txt, &i);
|
char *bidi_txt = lv_draw_get_buf(line_end - line_start + 1);
|
||||||
letter_next = lv_txt_encoded_next(&txt[i], NULL);
|
lv_bidi_process_paragraph(txt + line_start, bidi_txt, line_end - line_start, bidi_dir, NULL, 0);
|
||||||
|
#else
|
||||||
|
const char *bidi_txt = txt + line_start;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
while(i < line_end - line_start) {
|
||||||
|
uint16_t logical_char_pos = 0;
|
||||||
|
if(sel_start != 0xFFFF && sel_end != 0xFFFF) {
|
||||||
|
#if LV_USE_BIDI
|
||||||
|
logical_char_pos = lv_txt_encoded_get_char_id(txt, line_start);
|
||||||
|
uint16_t t = lv_txt_encoded_get_char_id(bidi_txt, i);
|
||||||
|
logical_char_pos += lv_bidi_get_logical_pos(bidi_txt, NULL, line_end - line_start, bidi_dir, t, NULL);
|
||||||
|
#else
|
||||||
|
logical_char_pos = lv_txt_encoded_get_char_id(txt, line_start + i);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
letter = lv_txt_encoded_next(bidi_txt, &i);
|
||||||
|
letter_next = lv_txt_encoded_next(&bidi_txt[i], NULL);
|
||||||
|
|
||||||
|
|
||||||
/*Handle the re-color command*/
|
/*Handle the re-color command*/
|
||||||
if((flag & LV_TXT_FLAG_RECOLOR) != 0) {
|
if((flag & LV_TXT_FLAG_RECOLOR) != 0) {
|
||||||
@@ -189,7 +219,7 @@ void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_st
|
|||||||
/*Get the parameter*/
|
/*Get the parameter*/
|
||||||
if(i - par_start == LABEL_RECOLOR_PAR_LENGTH + 1) {
|
if(i - par_start == LABEL_RECOLOR_PAR_LENGTH + 1) {
|
||||||
char buf[LABEL_RECOLOR_PAR_LENGTH + 1];
|
char buf[LABEL_RECOLOR_PAR_LENGTH + 1];
|
||||||
memcpy(buf, &txt[par_start], LABEL_RECOLOR_PAR_LENGTH);
|
memcpy(buf, &bidi_txt[par_start], LABEL_RECOLOR_PAR_LENGTH);
|
||||||
buf[LABEL_RECOLOR_PAR_LENGTH] = '\0';
|
buf[LABEL_RECOLOR_PAR_LENGTH] = '\0';
|
||||||
int r, g, b;
|
int r, g, b;
|
||||||
r = (hex_char_to_num(buf[0]) << 4) + hex_char_to_num(buf[1]);
|
r = (hex_char_to_num(buf[0]) << 4) + hex_char_to_num(buf[1]);
|
||||||
@@ -211,18 +241,14 @@ void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_st
|
|||||||
|
|
||||||
letter_w = lv_font_get_glyph_width(font, letter, letter_next);
|
letter_w = lv_font_get_glyph_width(font, letter, letter_next);
|
||||||
|
|
||||||
if(sel) {
|
if(sel_start != 0xFFFF && sel_end != 0xFFFF) {
|
||||||
if(sel->start != 0xFFFF && sel->end != 0xFFFF) {
|
if(logical_char_pos >= sel_start && logical_char_pos < sel_end) {
|
||||||
int char_ind = lv_encoded_get_char_id(txt, i);
|
lv_area_t sel_coords;
|
||||||
/*Do not draw the rectangle on the character at `sel_start`.*/
|
sel_coords.x1 = pos.x;
|
||||||
if(char_ind > sel->start && char_ind <= sel->end) {
|
sel_coords.y1 = pos.y;
|
||||||
lv_area_t sel_coords;
|
sel_coords.x2 = pos.x + letter_w + style->text.letter_space - 1;
|
||||||
sel_coords.x1 = pos.x;
|
sel_coords.y2 = pos.y + line_height - 1;
|
||||||
sel_coords.y1 = pos.y;
|
lv_draw_rect(&sel_coords, mask, &sel_style, opa);
|
||||||
sel_coords.x2 = pos.x + letter_w + style->text.letter_space - 1;
|
|
||||||
sel_coords.y2 = pos.y + line_height - 1;
|
|
||||||
lv_draw_rect(&sel_coords, mask, &sel_style, opa);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -240,7 +266,7 @@ void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_st
|
|||||||
/*Align to middle*/
|
/*Align to middle*/
|
||||||
if(flag & LV_TXT_FLAG_CENTER) {
|
if(flag & LV_TXT_FLAG_CENTER) {
|
||||||
line_width =
|
line_width =
|
||||||
lv_txt_get_width(&txt[line_start], line_end - line_start, font, style->text.letter_space, flag);
|
lv_txt_get_width(&txt[line_start], line_end - line_start, font, style->text.letter_space, flag);
|
||||||
|
|
||||||
pos.x += (lv_area_get_width(coords) - line_width) / 2;
|
pos.x += (lv_area_get_width(coords) - line_width) / 2;
|
||||||
|
|
||||||
@@ -248,7 +274,7 @@ void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_st
|
|||||||
/*Align to the right*/
|
/*Align to the right*/
|
||||||
else if(flag & LV_TXT_FLAG_RIGHT) {
|
else if(flag & LV_TXT_FLAG_RIGHT) {
|
||||||
line_width =
|
line_width =
|
||||||
lv_txt_get_width(&txt[line_start], line_end - line_start, font, style->text.letter_space, flag);
|
lv_txt_get_width(&txt[line_start], line_end - line_start, font, style->text.letter_space, flag);
|
||||||
pos.x += lv_area_get_width(coords) - line_width;
|
pos.x += lv_area_get_width(coords) - line_width;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -278,13 +304,13 @@ static uint8_t hex_char_to_num(char hex)
|
|||||||
if(hex >= 'a') hex -= 'a' - 'A'; /*Convert to upper case*/
|
if(hex >= 'a') hex -= 'a' - 'A'; /*Convert to upper case*/
|
||||||
|
|
||||||
switch(hex) {
|
switch(hex) {
|
||||||
case 'A': result = 10; break;
|
case 'A': result = 10; break;
|
||||||
case 'B': result = 11; break;
|
case 'B': result = 11; break;
|
||||||
case 'C': result = 12; break;
|
case 'C': result = 12; break;
|
||||||
case 'D': result = 13; break;
|
case 'D': result = 13; break;
|
||||||
case 'E': result = 14; break;
|
case 'E': result = 14; break;
|
||||||
case 'F': result = 15; break;
|
case 'F': result = 15; break;
|
||||||
default: result = 0; break;
|
default: result = 0; break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ extern "C" {
|
|||||||
* INCLUDES
|
* INCLUDES
|
||||||
*********************/
|
*********************/
|
||||||
#include "lv_draw.h"
|
#include "lv_draw.h"
|
||||||
|
#include "../lv_misc/lv_bidi.h"
|
||||||
|
|
||||||
/*********************
|
/*********************
|
||||||
* DEFINES
|
* DEFINES
|
||||||
@@ -62,10 +63,11 @@ typedef struct {
|
|||||||
* @param flag settings for the text from 'txt_flag_t' enum
|
* @param flag settings for the text from 'txt_flag_t' enum
|
||||||
* @param offset text offset in x and y direction (NULL if unused)
|
* @param offset text offset in x and y direction (NULL if unused)
|
||||||
* @param sel_start start index of selected area (`LV_LABEL_TXT_SEL_OFF` if none)
|
* @param sel_start start index of selected area (`LV_LABEL_TXT_SEL_OFF` if none)
|
||||||
|
* @param bidi_dir base direction of the text
|
||||||
*/
|
*/
|
||||||
void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_style_t * style, lv_opa_t opa_scale,
|
void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_style_t * style, lv_opa_t opa_scale,
|
||||||
const char * txt, lv_txt_flag_t flag, lv_point_t * offset, lv_draw_label_txt_sel_t * sel,
|
const char * txt, lv_txt_flag_t flag, lv_point_t * offset, lv_draw_label_txt_sel_t * sel,
|
||||||
lv_draw_label_hint_t * hint);
|
lv_draw_label_hint_t * hint, lv_bidi_dir_t bidi_dir);
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
* MACROS
|
* MACROS
|
||||||
|
|||||||
1133
src/lv_font/lv_font_heb_16.c
Normal file
1133
src/lv_font/lv_font_heb_16.c
Normal file
File diff suppressed because it is too large
Load Diff
540
src/lv_misc/lv_bidi.c
Normal file
540
src/lv_misc/lv_bidi.c
Normal file
@@ -0,0 +1,540 @@
|
|||||||
|
/**
|
||||||
|
* @file lv_bidi.c
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*********************
|
||||||
|
* INCLUDES
|
||||||
|
*********************/
|
||||||
|
#include <stddef.h>
|
||||||
|
#include "lv_bidi.h"
|
||||||
|
#include "lv_txt.h"
|
||||||
|
#include "../lv_draw/lv_draw.h"
|
||||||
|
|
||||||
|
#if LV_USE_BIDI
|
||||||
|
|
||||||
|
/*********************
|
||||||
|
* DEFINES
|
||||||
|
*********************/
|
||||||
|
#define LV_BIDI_BRACKLET_DEPTH 4
|
||||||
|
|
||||||
|
// Highest bit of the 16-bit pos_conv value specifies whether this pos is RTL or not
|
||||||
|
#define GET_POS(x) ((x) & 0x7FFF)
|
||||||
|
#define IS_RTL_POS(x) (((x) & 0x8000) != 0)
|
||||||
|
#define SET_RTL_POS(x, is_rtl) (GET_POS(x) | ((is_rtl)? 0x8000: 0))
|
||||||
|
|
||||||
|
/**********************
|
||||||
|
* TYPEDEFS
|
||||||
|
**********************/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint32_t bracklet_pos;
|
||||||
|
lv_bidi_dir_t dir;
|
||||||
|
}bracket_stack_t;
|
||||||
|
|
||||||
|
/**********************
|
||||||
|
* STATIC PROTOTYPES
|
||||||
|
**********************/
|
||||||
|
static lv_bidi_dir_t get_next_run(const char * txt, lv_bidi_dir_t base_dir, uint32_t max_len, uint32_t * len, uint16_t * pos_conv_len);
|
||||||
|
static void rtl_reverse(char * dest, const char * src, uint32_t len, uint16_t *pos_conv_out, uint16_t pos_conv_rd_base, uint16_t pos_conv_len);
|
||||||
|
static uint32_t char_change_to_pair(uint32_t letter);
|
||||||
|
static lv_bidi_dir_t bracket_process(const char * txt, uint32_t next_pos, uint32_t len, uint32_t letter, lv_bidi_dir_t base_dir);
|
||||||
|
static void fill_pos_conv(uint16_t * out, uint16_t len, uint16_t index);
|
||||||
|
static uint32_t get_txt_len(const char * txt, uint32_t max_len);
|
||||||
|
|
||||||
|
/**********************
|
||||||
|
* STATIC VARIABLES
|
||||||
|
**********************/
|
||||||
|
static const uint8_t bracket_left[] = {"<({["};
|
||||||
|
static const uint8_t bracket_right[] = {">)}]"};
|
||||||
|
static bracket_stack_t br_stack[LV_BIDI_BRACKLET_DEPTH];
|
||||||
|
static uint8_t br_stack_p;
|
||||||
|
|
||||||
|
/**********************
|
||||||
|
* 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 = lv_bidi_get_next_paragraph(&str_in[par_start]);
|
||||||
|
lv_bidi_process_paragraph(&str_in[par_start], &str_out[par_start], par_len, base_dir, NULL, 0);
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t lv_bidi_get_logical_pos(const char * str_in, char **bidi_txt, uint32_t len, lv_bidi_dir_t base_dir, uint32_t visual_pos, bool *is_rtl)
|
||||||
|
{
|
||||||
|
uint32_t pos_conv_len = get_txt_len(str_in, len);
|
||||||
|
void *buf = lv_draw_get_buf(len + pos_conv_len * sizeof(uint16_t));
|
||||||
|
if (bidi_txt) *bidi_txt = buf;
|
||||||
|
uint16_t *pos_conv_buf = (uint16_t*) ((char*)buf + len);
|
||||||
|
lv_bidi_process_paragraph(str_in, bidi_txt? *bidi_txt: NULL, len, base_dir, pos_conv_buf, pos_conv_len);
|
||||||
|
if (is_rtl) *is_rtl = IS_RTL_POS(pos_conv_buf[visual_pos]);
|
||||||
|
return GET_POS(pos_conv_buf[visual_pos]);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t lv_bidi_get_visual_pos(const char * str_in, char **bidi_txt, uint16_t len, lv_bidi_dir_t base_dir, uint32_t logical_pos, bool *is_rtl)
|
||||||
|
{
|
||||||
|
uint32_t pos_conv_len = get_txt_len(str_in, len);
|
||||||
|
void *buf = lv_draw_get_buf(len + pos_conv_len * sizeof(uint16_t));
|
||||||
|
if (bidi_txt) *bidi_txt = buf;
|
||||||
|
uint16_t *pos_conv_buf = (uint16_t*) ((char*)buf + len);
|
||||||
|
lv_bidi_process_paragraph(str_in, bidi_txt? *bidi_txt: NULL, len, base_dir, pos_conv_buf, pos_conv_len);
|
||||||
|
for (uint16_t i = 0; i < pos_conv_len; i++){
|
||||||
|
if (GET_POS(pos_conv_buf[i]) == logical_pos){
|
||||||
|
if (is_rtl) *is_rtl = IS_RTL_POS(pos_conv_buf[i]);
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (uint16_t) -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void lv_bidi_process_paragraph(const char * str_in, char * str_out, uint32_t len, lv_bidi_dir_t base_dir, uint16_t *pos_conv_out, uint16_t pos_conv_len)
|
||||||
|
{
|
||||||
|
uint32_t run_len = 0;
|
||||||
|
lv_bidi_dir_t run_dir;
|
||||||
|
uint32_t rd = 0;
|
||||||
|
uint32_t wr;
|
||||||
|
uint16_t pos_conv_run_len = 0;
|
||||||
|
uint16_t pos_conv_rd = 0;
|
||||||
|
uint16_t pos_conv_wr;
|
||||||
|
|
||||||
|
if(base_dir == LV_BIDI_DIR_AUTO) base_dir = lv_bidi_detect_base_dir(str_in);
|
||||||
|
if(base_dir == LV_BIDI_DIR_RTL) {
|
||||||
|
wr = len;
|
||||||
|
pos_conv_wr = pos_conv_len;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
wr = 0;
|
||||||
|
pos_conv_wr = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (str_out) str_out[len] = '\0';
|
||||||
|
|
||||||
|
lv_bidi_dir_t dir = base_dir;
|
||||||
|
|
||||||
|
/*Empty the bracket stack*/
|
||||||
|
br_stack_p = 0;
|
||||||
|
|
||||||
|
/*Process neutral chars in the beginning*/
|
||||||
|
while(rd < len) {
|
||||||
|
uint32_t letter = lv_txt_encoded_next(str_in, &rd);
|
||||||
|
pos_conv_rd++;
|
||||||
|
dir = lv_bidi_get_letter_dir(letter);
|
||||||
|
if(dir == LV_BIDI_DIR_NEUTRAL) dir = bracket_process(str_in, rd, len, letter, base_dir);
|
||||||
|
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);
|
||||||
|
pos_conv_rd--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(rd) {
|
||||||
|
if(base_dir == LV_BIDI_DIR_LTR) {
|
||||||
|
if (str_out) {
|
||||||
|
memcpy(&str_out[wr], str_in, rd);
|
||||||
|
wr += rd;
|
||||||
|
}
|
||||||
|
if (pos_conv_out) {
|
||||||
|
fill_pos_conv(&pos_conv_out[pos_conv_wr], pos_conv_rd, 0);
|
||||||
|
pos_conv_wr += pos_conv_rd;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
wr -= rd;
|
||||||
|
pos_conv_wr -= pos_conv_rd;
|
||||||
|
rtl_reverse(str_out? &str_out[wr]: NULL, str_in, rd, pos_conv_out? &pos_conv_out[pos_conv_wr]: NULL, 0, pos_conv_rd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*Get and process the runs*/
|
||||||
|
|
||||||
|
while(rd < len && str_in[rd]) {
|
||||||
|
run_dir = get_next_run(&str_in[rd], base_dir, len - rd, &run_len, &pos_conv_run_len);
|
||||||
|
|
||||||
|
if(base_dir == LV_BIDI_DIR_LTR) {
|
||||||
|
if(run_dir == LV_BIDI_DIR_LTR) {
|
||||||
|
if (str_out) memcpy(&str_out[wr], &str_in[rd], run_len);
|
||||||
|
if (pos_conv_out) fill_pos_conv(&pos_conv_out[pos_conv_wr], pos_conv_run_len, pos_conv_rd);
|
||||||
|
}
|
||||||
|
else rtl_reverse(str_out? &str_out[wr]: NULL, &str_in[rd], run_len, pos_conv_out? &pos_conv_out[pos_conv_wr] : NULL, pos_conv_rd, pos_conv_run_len);
|
||||||
|
wr += run_len;
|
||||||
|
pos_conv_wr += pos_conv_run_len;
|
||||||
|
} else {
|
||||||
|
wr -= run_len;
|
||||||
|
pos_conv_wr -= pos_conv_run_len;
|
||||||
|
if(run_dir == LV_BIDI_DIR_LTR) {
|
||||||
|
if (str_out) memcpy(&str_out[wr], &str_in[rd], run_len);
|
||||||
|
if (pos_conv_out) fill_pos_conv(&pos_conv_out[pos_conv_wr], pos_conv_run_len, pos_conv_rd);
|
||||||
|
}
|
||||||
|
else rtl_reverse(str_out? &str_out[wr]: NULL, &str_in[rd], run_len, pos_conv_out? &pos_conv_out[pos_conv_wr] : NULL, pos_conv_rd, pos_conv_run_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
rd += run_len;
|
||||||
|
pos_conv_rd += pos_conv_run_len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t lv_bidi_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 FUNCTIONS
|
||||||
|
**********************/
|
||||||
|
|
||||||
|
static uint32_t get_txt_len(const char * txt, uint32_t max_len)
|
||||||
|
{
|
||||||
|
uint32_t len = 0;
|
||||||
|
uint32_t i = 0;
|
||||||
|
|
||||||
|
while(i < max_len && txt[i] != '\0') {
|
||||||
|
lv_txt_encoded_next(txt, &i);
|
||||||
|
len++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void fill_pos_conv(uint16_t * out, uint16_t len, uint16_t index)
|
||||||
|
{
|
||||||
|
for (uint16_t i = 0; i < len; i++)
|
||||||
|
{
|
||||||
|
out[i] = SET_RTL_POS(index, false);
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static lv_bidi_dir_t get_next_run(const char * txt, lv_bidi_dir_t base_dir, uint32_t max_len, uint32_t * len, uint16_t * pos_conv_len)
|
||||||
|
{
|
||||||
|
uint32_t i = 0;
|
||||||
|
uint32_t letter;
|
||||||
|
|
||||||
|
uint16_t pos_conv_i = 0;
|
||||||
|
|
||||||
|
letter = lv_txt_encoded_next(txt, NULL);
|
||||||
|
lv_bidi_dir_t dir = lv_bidi_get_letter_dir(letter);
|
||||||
|
if(dir == LV_BIDI_DIR_NEUTRAL) dir = bracket_process(txt, 0, max_len, letter, base_dir);
|
||||||
|
|
||||||
|
/*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);
|
||||||
|
pos_conv_i++;
|
||||||
|
dir = lv_bidi_get_letter_dir(letter);
|
||||||
|
if(dir == LV_BIDI_DIR_NEUTRAL) dir = bracket_process(txt, i, max_len, letter, base_dir);
|
||||||
|
|
||||||
|
if(i >= max_len || txt[i] == '\0' || txt[i] == '\n' || txt[i] == '\r') {
|
||||||
|
*len = i;
|
||||||
|
*pos_conv_len = pos_conv_i;
|
||||||
|
return base_dir;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lv_bidi_dir_t run_dir = dir;
|
||||||
|
|
||||||
|
uint32_t i_prev = i;
|
||||||
|
uint32_t i_last_strong = i;
|
||||||
|
uint16_t pos_conv_i_prev = pos_conv_i;
|
||||||
|
uint16_t pos_conv_i_last_strong = pos_conv_i;
|
||||||
|
|
||||||
|
/*Find the next char which has different direction*/
|
||||||
|
lv_bidi_dir_t next_dir = base_dir;
|
||||||
|
while(i_prev < max_len && txt[i] != '\0' && txt[i] != '\n' && txt[i] != '\r') {
|
||||||
|
letter = lv_txt_encoded_next(txt, &i);
|
||||||
|
pos_conv_i++;
|
||||||
|
next_dir = lv_bidi_get_letter_dir(letter);
|
||||||
|
if(next_dir == LV_BIDI_DIR_NEUTRAL) next_dir = bracket_process(txt, i, max_len, letter, base_dir);
|
||||||
|
|
||||||
|
/*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;
|
||||||
|
*pos_conv_len = pos_conv_i_prev;
|
||||||
|
}
|
||||||
|
/*Exclude neutrals if `run_dir != base_dir` */
|
||||||
|
else {
|
||||||
|
*len = i_last_strong;
|
||||||
|
*pos_conv_len = pos_conv_i_last_strong;
|
||||||
|
}
|
||||||
|
|
||||||
|
return run_dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(next_dir != LV_BIDI_DIR_NEUTRAL) {
|
||||||
|
i_last_strong = i;
|
||||||
|
pos_conv_i_last_strong = pos_conv_i;
|
||||||
|
}
|
||||||
|
|
||||||
|
i_prev = i;
|
||||||
|
pos_conv_i_prev = pos_conv_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;
|
||||||
|
*pos_conv_len = pos_conv_i_prev;
|
||||||
|
}
|
||||||
|
/*Exclude neutrals if `run_dir != base_dir` */
|
||||||
|
else {
|
||||||
|
*len = i_last_strong;
|
||||||
|
*pos_conv_len = pos_conv_i_last_strong;
|
||||||
|
}
|
||||||
|
|
||||||
|
return run_dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rtl_reverse(char * dest, const char * src, uint32_t len, uint16_t *pos_conv_out, uint16_t pos_conv_rd_base, uint16_t pos_conv_len)
|
||||||
|
{
|
||||||
|
uint32_t i = len;
|
||||||
|
uint32_t wr = 0;
|
||||||
|
uint16_t pos_conv_i = pos_conv_len;
|
||||||
|
uint16_t pos_conv_wr = 0;
|
||||||
|
|
||||||
|
while(i) {
|
||||||
|
uint32_t letter = lv_txt_encoded_prev(src, &i);
|
||||||
|
uint16_t pos_conv_letter = --pos_conv_i;
|
||||||
|
|
||||||
|
/*Keep weak letters (numbers) as LTR*/
|
||||||
|
if(lv_bidi_letter_is_weak(letter)) {
|
||||||
|
uint32_t last_weak = i;
|
||||||
|
uint32_t first_weak = i;
|
||||||
|
uint16_t pos_conv_last_weak = pos_conv_i;
|
||||||
|
uint16_t pos_conv_first_weak = pos_conv_i;
|
||||||
|
while(i) {
|
||||||
|
letter = lv_txt_encoded_prev(src, &i);
|
||||||
|
pos_conv_letter = --pos_conv_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 != '$' && letter != '%') {
|
||||||
|
lv_txt_encoded_next(src, &i); /*Rewind one letter*/
|
||||||
|
pos_conv_i++;
|
||||||
|
first_weak = i;
|
||||||
|
pos_conv_first_weak = pos_conv_i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(i == 0) {
|
||||||
|
first_weak = 0;
|
||||||
|
pos_conv_first_weak = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dest) memcpy(&dest[wr], &src[first_weak], last_weak - first_weak + 1);
|
||||||
|
if (pos_conv_out) fill_pos_conv(&pos_conv_out[pos_conv_wr], pos_conv_last_weak - pos_conv_first_weak + 1, pos_conv_rd_base + pos_conv_first_weak);
|
||||||
|
wr += last_weak - first_weak + 1;
|
||||||
|
pos_conv_wr += pos_conv_last_weak - pos_conv_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);
|
||||||
|
if (dest) dest[wr] = (uint8_t)new_letter;
|
||||||
|
if (pos_conv_out) pos_conv_out[pos_conv_wr] = SET_RTL_POS(pos_conv_rd_base + pos_conv_letter, true);
|
||||||
|
wr++;
|
||||||
|
pos_conv_wr++;
|
||||||
|
}
|
||||||
|
/*Just store the letter*/
|
||||||
|
else {
|
||||||
|
if (dest) memcpy(&dest[wr], &src[i], letter_size);
|
||||||
|
if (pos_conv_out) pos_conv_out[pos_conv_wr] = SET_RTL_POS(pos_conv_rd_base + pos_conv_i, true);
|
||||||
|
wr += letter_size;
|
||||||
|
pos_conv_wr++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t char_change_to_pair(uint32_t letter)
|
||||||
|
{
|
||||||
|
|
||||||
|
uint8_t i;
|
||||||
|
for(i = 0; bracket_left[i] != '\0'; i++) {
|
||||||
|
if(letter == bracket_left[i]) return bracket_right[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i = 0; bracket_right[i] != '\0'; i++) {
|
||||||
|
if(letter == bracket_right[i]) return bracket_left[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return letter;
|
||||||
|
}
|
||||||
|
|
||||||
|
static lv_bidi_dir_t bracket_process(const char * txt, uint32_t next_pos, uint32_t len, uint32_t letter, lv_bidi_dir_t base_dir)
|
||||||
|
{
|
||||||
|
lv_bidi_dir_t bracket_dir = LV_BIDI_DIR_NEUTRAL;
|
||||||
|
|
||||||
|
uint8_t i;
|
||||||
|
/*Is the letter an opening bracket?*/
|
||||||
|
for(i = 0; bracket_left[i] != '\0'; i++) {
|
||||||
|
if(bracket_left[i] == letter) {
|
||||||
|
/* If so find it's matching closing bracket.
|
||||||
|
* If a char with base dir. direction is found then the brackets will have `base_dir` direction*/
|
||||||
|
uint32_t txt_i = next_pos;
|
||||||
|
while(txt_i < len) {
|
||||||
|
uint32_t letter_next = lv_txt_encoded_next(txt, &txt_i);
|
||||||
|
if(letter_next == bracket_right[i]) {
|
||||||
|
/*Closing bracket found*/
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
/*Save the dir*/
|
||||||
|
lv_bidi_dir_t letter_dir = lv_bidi_get_letter_dir(letter_next);
|
||||||
|
if(letter_dir == base_dir) {
|
||||||
|
bracket_dir = base_dir;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*There were no matching closing bracket*/
|
||||||
|
if(txt_i > len) return LV_BIDI_DIR_NEUTRAL;
|
||||||
|
|
||||||
|
/*There where a strong char with base dir in the bracket so the dir is found.*/
|
||||||
|
if(bracket_dir != LV_BIDI_DIR_NEUTRAL && bracket_dir != LV_BIDI_DIR_WEAK) break;
|
||||||
|
|
||||||
|
/*If there were no matching strong chars in the brackets then check the previous chars*/
|
||||||
|
txt_i = next_pos;
|
||||||
|
if(txt_i) lv_txt_encoded_prev(txt, &txt_i);
|
||||||
|
while(txt_i > 0) {
|
||||||
|
uint32_t letter_next = lv_txt_encoded_prev(txt, &txt_i);
|
||||||
|
lv_bidi_dir_t letter_dir = lv_bidi_get_letter_dir(letter_next);
|
||||||
|
if(letter_dir == LV_BIDI_DIR_LTR || letter_dir == LV_BIDI_DIR_RTL) {
|
||||||
|
bracket_dir = letter_dir;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*There where a previous strong char which can be used*/
|
||||||
|
if(bracket_dir != LV_BIDI_DIR_NEUTRAL) break;
|
||||||
|
|
||||||
|
/*There were no strong chars before the bracket, so use the base dir.*/
|
||||||
|
if(txt_i == 0) bracket_dir = base_dir;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*The letter was an opening bracket*/
|
||||||
|
if(bracket_left[i] != '\0') {
|
||||||
|
|
||||||
|
if(bracket_dir == LV_BIDI_DIR_NEUTRAL || br_stack_p == LV_BIDI_BRACKLET_DEPTH) return LV_BIDI_DIR_NEUTRAL;
|
||||||
|
|
||||||
|
br_stack[br_stack_p].bracklet_pos = i;
|
||||||
|
br_stack[br_stack_p].dir = bracket_dir;
|
||||||
|
|
||||||
|
br_stack_p++;
|
||||||
|
return bracket_dir;
|
||||||
|
} else if(br_stack_p > 0) {
|
||||||
|
/*Is the letter a closing bracket of the last opening?*/
|
||||||
|
if(letter == bracket_right[br_stack[br_stack_p - 1].bracklet_pos]) {
|
||||||
|
bracket_dir = br_stack[br_stack_p - 1].dir;
|
||||||
|
br_stack_p--;
|
||||||
|
return bracket_dir;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return LV_BIDI_DIR_NEUTRAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif /*LV_USE_BIDI*/
|
||||||
76
src/lv_misc/lv_bidi.h
Normal file
76
src/lv_misc/lv_bidi.h
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
/**
|
||||||
|
* @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);
|
||||||
|
void lv_bidi_process_paragraph(const char * str_in, char * str_out, uint32_t len, lv_bidi_dir_t base_dir, uint16_t *pos_conv_out, uint16_t pos_conv_len);
|
||||||
|
uint32_t lv_bidi_get_next_paragraph(const char * txt);
|
||||||
|
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);
|
||||||
|
uint16_t lv_bidi_get_logical_pos(const char * str_in, char **bidi_txt, uint32_t len, lv_bidi_dir_t base_dir, uint32_t visual_pos, bool *is_rtl);
|
||||||
|
uint16_t lv_bidi_get_visual_pos(const char * str_in, char **bidi_txt, uint16_t len, lv_bidi_dir_t base_dir, uint32_t logical_pos, bool *is_rtl);
|
||||||
|
|
||||||
|
/**********************
|
||||||
|
* MACROS
|
||||||
|
**********************/
|
||||||
|
|
||||||
|
#endif /*LV_USE_BIDI*/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} /* extern "C" */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /*LV_BIDI_H*/
|
||||||
@@ -90,6 +90,110 @@ enum {
|
|||||||
#error "Invalid LV_COLOR_DEPTH in lv_conf.h! Set it to 1, 8, 16 or 32!"
|
#error "Invalid LV_COLOR_DEPTH in lv_conf.h! Set it to 1, 8, 16 or 32!"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*---------------------------------------
|
||||||
|
* Macros for all existing color depths
|
||||||
|
* to set/get values of the color channels
|
||||||
|
*------------------------------------------*/
|
||||||
|
# define LV_COLOR_SET_R1(c, v) (c).ch.red = (v) & 0x1;
|
||||||
|
# define LV_COLOR_SET_G1(c, v) (c).ch.green = (v) & 0x1;
|
||||||
|
# define LV_COLOR_SET_B1(c, v) (c).ch.blue = (v) & 0x1;
|
||||||
|
# define LV_COLOR_SET_A1(c, v)
|
||||||
|
|
||||||
|
# define LV_COLOR_GET_R1(c) (c).ch.red
|
||||||
|
# define LV_COLOR_GET_G1(c) (c).ch.green
|
||||||
|
# define LV_COLOR_GET_B1(c) (c).ch.blue
|
||||||
|
# define LV_COLOR_GET_A1(c) 1
|
||||||
|
|
||||||
|
# define LV_COLOR_SET_R8(c, v) (c).ch.red = (v) & 0x7;
|
||||||
|
# define LV_COLOR_SET_G8(c, v) (c).ch.green = (v) & 0x7;
|
||||||
|
# define LV_COLOR_SET_B8(c, v) (c).ch.blue = (v) & 0x3;
|
||||||
|
# define LV_COLOR_SET_A8(c, v)
|
||||||
|
|
||||||
|
# define LV_COLOR_GET_R8(c) (c).ch.red
|
||||||
|
# define LV_COLOR_GET_G8(c) (c).ch.green
|
||||||
|
# define LV_COLOR_GET_B8(c) (c).ch.blue
|
||||||
|
# define LV_COLOR_GET_A8(c) 0xFF
|
||||||
|
|
||||||
|
# define LV_COLOR_SET_R16(c, v) (c).ch.red = (v) & 0x1F;
|
||||||
|
# define LV_COLOR_SET_G16(c, v) (c).ch.green = (v) & 0x3F;
|
||||||
|
# define LV_COLOR_SET_G16_SWAP(c, v) {(c).ch.green_h = ((v) >> 3) & 0x7; (c).ch.green_l = (v) & 0x7;}
|
||||||
|
# define LV_COLOR_SET_B16(c, v) (c).ch.blue = (v) & 0x1F;
|
||||||
|
# define LV_COLOR_SET_A16(c, v)
|
||||||
|
|
||||||
|
# define LV_COLOR_GET_R16(c) (c).ch.red
|
||||||
|
# define LV_COLOR_GET_G16(c) (c).ch.green
|
||||||
|
# define LV_COLOR_GET_G16_SWAP(c) (((c).ch.green_h << 3) + (c).ch.green_l)
|
||||||
|
# define LV_COLOR_GET_B16(c) (c).ch.blue
|
||||||
|
# define LV_COLOR_GET_A16(c) 0xFF
|
||||||
|
|
||||||
|
# define LV_COLOR_SET_R32(c, v) (c).ch.red = (v) & 0xFF;
|
||||||
|
# define LV_COLOR_SET_G32(c, v) (c).ch.green = (v) & 0xFF;
|
||||||
|
# define LV_COLOR_SET_B32(c, v) (c).ch.blue = (v) & 0xFF;
|
||||||
|
# define LV_COLOR_SET_A32(c, v) (c).ch.alpha = (v) & 0xFF;
|
||||||
|
|
||||||
|
# define LV_COLOR_GET_R32(c) (c).ch.red
|
||||||
|
# define LV_COLOR_GET_G32(c) (c).ch.green
|
||||||
|
# define LV_COLOR_GET_B32(c) (c).ch.blue
|
||||||
|
# define LV_COLOR_GET_A32(c) (c).ch.alpha
|
||||||
|
|
||||||
|
|
||||||
|
/*---------------------------------------
|
||||||
|
* Macros for the current color depth
|
||||||
|
* to set/get values of the color channels
|
||||||
|
*------------------------------------------*/
|
||||||
|
#if LV_COLOR_DEPTH == 1
|
||||||
|
# define LV_COLOR_SET_R(c, v) LV_COLOR_SET_R1(c,v)
|
||||||
|
# define LV_COLOR_SET_G(c, v) LV_COLOR_SET_G1(c,v)
|
||||||
|
# define LV_COLOR_SET_B(c, v) LV_COLOR_SET_B1(c,v)
|
||||||
|
# define LV_COLOR_SET_A(c, v) LV_COLOR_SET_A1(c,v)
|
||||||
|
|
||||||
|
# define LV_COLOR_GET_R(c) LV_COLOR_GET_R1(c)
|
||||||
|
# define LV_COLOR_GET_G(c) LV_COLOR_GET_G1(c)
|
||||||
|
# define LV_COLOR_GET_B(c) LV_COLOR_GET_B1(c)
|
||||||
|
# define LV_COLOR_GET_A(c) LV_COLOR_GET_A1(c)
|
||||||
|
|
||||||
|
#elif LV_COLOR_DEPTH == 8
|
||||||
|
# define LV_COLOR_SET_R(c, v) LV_COLOR_SET_R8(c,v)
|
||||||
|
# define LV_COLOR_SET_G(c, v) LV_COLOR_SET_G8(c,v)
|
||||||
|
# define LV_COLOR_SET_B(c, v) LV_COLOR_SET_B8(c,v)
|
||||||
|
# define LV_COLOR_SET_A(c, v) LV_COLOR_SET_A8(c,v)
|
||||||
|
|
||||||
|
# define LV_COLOR_GET_R(c) LV_COLOR_GET_R8(c)
|
||||||
|
# define LV_COLOR_GET_G(c) LV_COLOR_GET_G8(c)
|
||||||
|
# define LV_COLOR_GET_B(c) LV_COLOR_GET_B8(c)
|
||||||
|
# define LV_COLOR_GET_A(c) LV_COLOR_GET_A8(c)
|
||||||
|
|
||||||
|
#elif LV_COLOR_DEPTH == 16
|
||||||
|
# define LV_COLOR_SET_R(c, v) LV_COLOR_SET_R16(c,v)
|
||||||
|
# if LV_COLOR_16_SWAP == 0
|
||||||
|
# define LV_COLOR_SET_G(c, v) LV_COLOR_SET_G16(c,v)
|
||||||
|
# else
|
||||||
|
# define LV_COLOR_SET_G(c, v) LV_COLOR_SET_G16_SWAP(c,v)
|
||||||
|
# endif
|
||||||
|
# define LV_COLOR_SET_B(c, v) LV_COLOR_SET_B16(c,v)
|
||||||
|
# define LV_COLOR_SET_A(c, v) LV_COLOR_SET_A16(c,v)
|
||||||
|
|
||||||
|
# define LV_COLOR_GET_R(c) LV_COLOR_GET_R16(c)
|
||||||
|
# if LV_COLOR_16_SWAP == 0
|
||||||
|
# define LV_COLOR_GET_G(c) LV_COLOR_GET_G16(c)
|
||||||
|
# else
|
||||||
|
# define LV_COLOR_GET_G(c) LV_COLOR_GET_G16_SWAP(c)
|
||||||
|
# endif
|
||||||
|
# define LV_COLOR_GET_B(c) LV_COLOR_GET_B16(c)
|
||||||
|
# define LV_COLOR_GET_A(c) LV_COLOR_GET_A16(c)
|
||||||
|
|
||||||
|
#elif LV_COLOR_DEPTH == 32
|
||||||
|
# define LV_COLOR_SET_R(c, v) LV_COLOR_SET_R32(c,v)
|
||||||
|
# define LV_COLOR_SET_G(c, v) LV_COLOR_SET_G32(c,v)
|
||||||
|
# define LV_COLOR_SET_B(c, v) LV_COLOR_SET_B32(c,v)
|
||||||
|
# define LV_COLOR_SET_A(c, v) LV_COLOR_SET_A32(c,v)
|
||||||
|
|
||||||
|
# define LV_COLOR_GET_R(c) LV_COLOR_GET_R32(c)
|
||||||
|
# define LV_COLOR_GET_G(c) LV_COLOR_GET_G32(c)
|
||||||
|
# define LV_COLOR_GET_B(c) LV_COLOR_GET_B32(c)
|
||||||
|
# define LV_COLOR_GET_A(c) LV_COLOR_GET_A32(c)
|
||||||
|
#endif
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
* TYPEDEFS
|
* TYPEDEFS
|
||||||
**********************/
|
**********************/
|
||||||
@@ -194,24 +298,19 @@ static inline uint8_t lv_color_to1(lv_color_t color)
|
|||||||
#if LV_COLOR_DEPTH == 1
|
#if LV_COLOR_DEPTH == 1
|
||||||
return color.full;
|
return color.full;
|
||||||
#elif LV_COLOR_DEPTH == 8
|
#elif LV_COLOR_DEPTH == 8
|
||||||
if((color.ch.red & 0x4) || (color.ch.green & 0x4) || (color.ch.blue & 0x2)) {
|
if((LV_COLOR_GET_R(color) & 0x4) || (LV_COLOR_GET_G(color) & 0x4) || (LV_COLOR_GET_B(color) & 0x2)) {
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#elif LV_COLOR_DEPTH == 16
|
#elif LV_COLOR_DEPTH == 16
|
||||||
#if LV_COLOR_16_SWAP == 0
|
if((LV_COLOR_GET_R(color) & 0x10) || (LV_COLOR_GET_G(color) & 0x20) || (LV_COLOR_GET_B(color) & 0x10)) {
|
||||||
if((color.ch.red & 0x10) || (color.ch.green & 0x20) || (color.ch.blue & 0x10)) {
|
|
||||||
return 1;
|
return 1;
|
||||||
#else
|
|
||||||
if((color.ch.red & 0x10) || (color.ch.green_h & 0x20) || (color.ch.blue & 0x10)) {
|
|
||||||
return 1;
|
|
||||||
#endif
|
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#elif LV_COLOR_DEPTH == 32
|
#elif LV_COLOR_DEPTH == 32
|
||||||
if((color.ch.red & 0x80) || (color.ch.green & 0x80) || (color.ch.blue & 0x80)) {
|
if((LV_COLOR_GET_R(color) & 0x80) || (LV_COLOR_GET_G(color) & 0x80) || (LV_COLOR_GET_B(color) & 0x80)) {
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
@@ -229,31 +328,23 @@ static inline uint8_t lv_color_to8(lv_color_t color)
|
|||||||
#elif LV_COLOR_DEPTH == 8
|
#elif LV_COLOR_DEPTH == 8
|
||||||
return color.full;
|
return color.full;
|
||||||
#elif LV_COLOR_DEPTH == 16
|
#elif LV_COLOR_DEPTH == 16
|
||||||
|
|
||||||
#if LV_COLOR_16_SWAP == 0
|
|
||||||
lv_color8_t ret;
|
lv_color8_t ret;
|
||||||
ret.ch.red = color.ch.red >> 2; /* 5 - 3 = 2*/
|
LV_COLOR_SET_R8(ret, LV_COLOR_GET_R(color) >> 2); /* 5 - 3 = 2*/
|
||||||
ret.ch.green = color.ch.green >> 3; /* 6 - 3 = 3*/
|
LV_COLOR_SET_G8(ret, LV_COLOR_GET_G(color) >> 3); /* 6 - 3 = 3*/
|
||||||
ret.ch.blue = color.ch.blue >> 3; /* 5 - 2 = 3*/
|
LV_COLOR_SET_B8(ret, LV_COLOR_GET_B(color) >> 3); /* 5 - 2 = 3*/
|
||||||
return ret.full;
|
return ret.full;
|
||||||
#else
|
|
||||||
lv_color8_t ret;
|
|
||||||
ret.ch.red = color.ch.red >> 2; /* 5 - 3 = 2*/
|
|
||||||
ret.ch.green = color.ch.green_h; /* 6 - 3 = 3*/
|
|
||||||
ret.ch.blue = color.ch.blue >> 3; /* 5 - 2 = 3*/
|
|
||||||
return ret.full;
|
|
||||||
#endif
|
|
||||||
#elif LV_COLOR_DEPTH == 32
|
#elif LV_COLOR_DEPTH == 32
|
||||||
lv_color8_t ret;
|
lv_color8_t ret;
|
||||||
ret.ch.red = color.ch.red >> 5; /* 8 - 3 = 5*/
|
LV_COLOR_SET_R8(ret, LV_COLOR_GET_R(color) >> 5); /* 8 - 3 = 5*/
|
||||||
ret.ch.green = color.ch.green >> 5; /* 8 - 3 = 5*/
|
LV_COLOR_SET_G8(ret, LV_COLOR_GET_G(color) >> 5); /* 8 - 3 = 5*/
|
||||||
ret.ch.blue = color.ch.blue >> 6; /* 8 - 2 = 6*/
|
LV_COLOR_SET_B8(ret, LV_COLOR_GET_B(color) >> 6); /* 8 - 2 = 6*/
|
||||||
return ret.full;
|
return ret.full;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint16_t lv_color_to16(lv_color_t color)
|
static inline uint16_t lv_color_to16(lv_color_t color)
|
||||||
{
|
{
|
||||||
|
|
||||||
#if LV_COLOR_DEPTH == 1
|
#if LV_COLOR_DEPTH == 1
|
||||||
if(color.full == 0)
|
if(color.full == 0)
|
||||||
return 0;
|
return 0;
|
||||||
@@ -261,34 +352,30 @@ static inline uint16_t lv_color_to16(lv_color_t color)
|
|||||||
return 0xFFFF;
|
return 0xFFFF;
|
||||||
#elif LV_COLOR_DEPTH == 8
|
#elif LV_COLOR_DEPTH == 8
|
||||||
lv_color16_t ret;
|
lv_color16_t ret;
|
||||||
|
LV_COLOR_SET_R16(ret, LV_COLOR_GET_R(color) * 4); /*(2^5 - 1)/(2^3 - 1) = 31/7 = 4*/
|
||||||
#if LV_COLOR_16_SWAP == 0
|
#if LV_COLOR_16_SWAP == 0
|
||||||
ret.ch.red = color.ch.red * 4; /*(2^5 - 1)/(2^3 - 1) = 31/7 = 4*/
|
LV_COLOR_SET_G16(ret, LV_COLOR_GET_G(color) * 9); /*(2^6 - 1)/(2^3 - 1) = 63/7 = 9*/
|
||||||
ret.ch.green = color.ch.green * 9; /*(2^6 - 1)/(2^3 - 1) = 63/7 = 9*/
|
|
||||||
ret.ch.blue = color.ch.blue * 10; /*(2^5 - 1)/(2^2 - 1) = 31/3 = 10*/
|
|
||||||
#else
|
#else
|
||||||
ret.red = color.ch.red * 4;
|
LV_COLOR_SET_G16_SWAP(ret, (LV_COLOR_GET_G(color) * 9)); /*(2^6 - 1)/(2^3 - 1) = 63/7 = 9*/
|
||||||
uint8_t g_tmp = color.ch.green * 9;
|
|
||||||
ret.ch.green_h = (g_tmp & 0x1F) >> 3;
|
|
||||||
ret.ch.green_l = g_tmp & 0x07;
|
|
||||||
ret.ch.blue = color.ch.blue * 10;
|
|
||||||
#endif
|
#endif
|
||||||
|
LV_COLOR_SET_B16(ret, LV_COLOR_GET_B(color) * 10); /*(2^5 - 1)/(2^2 - 1) = 31/3 = 10*/
|
||||||
return ret.full;
|
return ret.full;
|
||||||
#elif LV_COLOR_DEPTH == 16
|
#elif LV_COLOR_DEPTH == 16
|
||||||
return color.full;
|
return color.full;
|
||||||
#elif LV_COLOR_DEPTH == 32
|
#elif LV_COLOR_DEPTH == 32
|
||||||
lv_color16_t ret;
|
lv_color16_t ret;
|
||||||
|
LV_COLOR_SET_R16(ret, LV_COLOR_GET_R(color) >> 3); /* 8 - 5 = 3*/
|
||||||
|
|
||||||
#if LV_COLOR_16_SWAP == 0
|
#if LV_COLOR_16_SWAP == 0
|
||||||
ret.ch.red = color.ch.red >> 3; /* 8 - 5 = 3*/
|
LV_COLOR_SET_G16(ret, LV_COLOR_GET_G(color) >> 2); /* 8 - 6 = 2*/
|
||||||
ret.ch.green = color.ch.green >> 2; /* 8 - 6 = 2*/
|
|
||||||
ret.ch.blue = color.ch.blue >> 3; /* 8 - 5 = 3*/
|
|
||||||
#else
|
#else
|
||||||
ret.ch.red = color.ch.red >> 3;
|
LV_COLOR_SET_G16_SWAP(ret, ret.ch.green_h = (LV_COLOR_GET_G(color) >> 2); /*(2^6 - 1)/(2^3 - 1) = 63/7 = 9*/
|
||||||
ret.ch.green_h = (color.ch.green & 0xE0) >> 5;
|
|
||||||
ret.ch.green_l = (color.ch.green & 0x1C) >> 2;
|
|
||||||
ret.ch.blue = color.ch.blue >> 3;
|
|
||||||
#endif
|
#endif
|
||||||
|
LV_COLOR_SET_B16(ret, LV_COLOR_GET_B(color) >> 3); /* 8 - 5 = 3*/
|
||||||
return ret.full;
|
return ret.full;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32_t lv_color_to32(lv_color_t color)
|
static inline uint32_t lv_color_to32(lv_color_t color)
|
||||||
@@ -300,10 +387,10 @@ static inline uint32_t lv_color_to32(lv_color_t color)
|
|||||||
return 0xFFFFFFFF;
|
return 0xFFFFFFFF;
|
||||||
#elif LV_COLOR_DEPTH == 8
|
#elif LV_COLOR_DEPTH == 8
|
||||||
lv_color32_t ret;
|
lv_color32_t ret;
|
||||||
ret.ch.red = color.ch.red * 36; /*(2^8 - 1)/(2^3 - 1) = 255/7 = 36*/
|
LV_COLOR_SET_R32(ret, LV_COLOR_GET_R(color) * 36); /*(2^8 - 1)/(2^3 - 1) = 255/7 = 36*/
|
||||||
ret.ch.green = color.ch.green * 36; /*(2^8 - 1)/(2^3 - 1) = 255/7 = 36*/
|
LV_COLOR_SET_G32(ret, LV_COLOR_GET_G(color) * 36); /*(2^8 - 1)/(2^3 - 1) = 255/7 = 36*/
|
||||||
ret.ch.blue = color.ch.blue * 85; /*(2^8 - 1)/(2^2 - 1) = 255/3 = 85*/
|
LV_COLOR_SET_B32(ret, LV_COLOR_GET_B(color) * 85); /*(2^8 - 1)/(2^2 - 1) = 255/3 = 85*/
|
||||||
ret.ch.alpha = 0xFF;
|
LV_COLOR_SET_A32(color, 0xFF);
|
||||||
return ret.full;
|
return ret.full;
|
||||||
#elif LV_COLOR_DEPTH == 16
|
#elif LV_COLOR_DEPTH == 16
|
||||||
/**
|
/**
|
||||||
@@ -335,14 +422,10 @@ static inline uint32_t lv_color_to32(lv_color_t color)
|
|||||||
* 6 259 3 0 255
|
* 6 259 3 0 255
|
||||||
*/
|
*/
|
||||||
lv_color32_t ret;
|
lv_color32_t ret;
|
||||||
ret.ch.red = ( color.ch.red * 263 + 7 ) >> 5;
|
LV_COLOR_SET_R32(ret, (LV_COLOR_GET_R(color) * 263 + 7 ) >> 5);
|
||||||
#if LV_COLOR_16_SWAP == 0
|
LV_COLOR_SET_G32(ret, (LV_COLOR_GET_G(color) * 259 + 3 ) >> 6);
|
||||||
ret.ch.green = ( color.ch.green * 259 + 3 ) >> 6;
|
LV_COLOR_SET_B32(ret, (LV_COLOR_GET_B(color) * 263 + 7 ) >> 5);
|
||||||
#else
|
LV_COLOR_SET_A32(ret, 0xFF);
|
||||||
ret.ch.green = (((color.ch.green_h << 3) + color.ch.green_l) * 259 + 3 ) >> 6;
|
|
||||||
#endif
|
|
||||||
ret.ch.blue = ( color.ch.blue * 263 + 7 ) >> 5;
|
|
||||||
ret.ch.alpha = 0xFF;
|
|
||||||
return ret.full;
|
return ret.full;
|
||||||
#elif LV_COLOR_DEPTH == 32
|
#elif LV_COLOR_DEPTH == 32
|
||||||
return color.full;
|
return color.full;
|
||||||
@@ -354,21 +437,10 @@ static inline lv_color_t lv_color_mix(lv_color_t c1, lv_color_t c2, uint8_t mix)
|
|||||||
lv_color_t ret;
|
lv_color_t ret;
|
||||||
#if LV_COLOR_DEPTH != 1
|
#if LV_COLOR_DEPTH != 1
|
||||||
/*LV_COLOR_DEPTH == 8, 16 or 32*/
|
/*LV_COLOR_DEPTH == 8, 16 or 32*/
|
||||||
ret.ch.red = (uint16_t)((uint16_t)c1.ch.red * mix + (c2.ch.red * (255 - mix))) >> 8;
|
LV_COLOR_SET_R(ret, (uint16_t)((uint16_t) LV_COLOR_GET_R(c1) * mix + LV_COLOR_GET_R(c2) * (255 - mix)) >> 8);
|
||||||
#if LV_COLOR_DEPTH == 16 && LV_COLOR_16_SWAP
|
LV_COLOR_SET_G(ret, (uint16_t)((uint16_t) LV_COLOR_GET_G(c1) * mix + LV_COLOR_GET_G(c2) * (255 - mix)) >> 8);
|
||||||
/*If swapped Green is in 2 parts*/
|
LV_COLOR_SET_B(ret, (uint16_t)((uint16_t) LV_COLOR_GET_B(c1) * mix + LV_COLOR_GET_B(c2) * (255 - mix)) >> 8);
|
||||||
uint16_t g_1 = (c1.ch.green_h << 3) + c1.ch.green_l;
|
LV_COLOR_SET_A(ret, 0xFF);
|
||||||
uint16_t g_2 = (c2.ch.green_h << 3) + c2.ch.green_l;
|
|
||||||
uint16_t g_out = (uint16_t)((uint16_t)g_1 * mix + (g_2 * (255 - mix))) >> 8;
|
|
||||||
ret.ch.green_h = g_out >> 3;
|
|
||||||
ret.ch.green_l = g_out & 0x7;
|
|
||||||
#else
|
|
||||||
ret.ch.green = (uint16_t)((uint16_t)c1.ch.green * mix + (c2.ch.green * (255 - mix))) >> 8;
|
|
||||||
#endif
|
|
||||||
ret.ch.blue = (uint16_t)((uint16_t)c1.ch.blue * mix + (c2.ch.blue * (255 - mix))) >> 8;
|
|
||||||
#if LV_COLOR_DEPTH == 32
|
|
||||||
ret.ch.alpha = 0xFF;
|
|
||||||
#endif
|
|
||||||
#else
|
#else
|
||||||
/*LV_COLOR_DEPTH == 1*/
|
/*LV_COLOR_DEPTH == 1*/
|
||||||
ret.full = mix > LV_OPA_50 ? c1.full : c2.full;
|
ret.full = mix > LV_OPA_50 ? c1.full : c2.full;
|
||||||
@@ -386,7 +458,7 @@ static inline uint8_t lv_color_brightness(lv_color_t color)
|
|||||||
{
|
{
|
||||||
lv_color32_t c32;
|
lv_color32_t c32;
|
||||||
c32.full = lv_color_to32(color);
|
c32.full = lv_color_to32(color);
|
||||||
uint16_t bright = 3 * c32.ch.red + c32.ch.blue + 4 * c32.ch.green;
|
uint16_t bright = 3 * LV_COLOR_GET_R32(c32) + LV_COLOR_GET_B32(c32) + 4 * LV_COLOR_GET_G32(c32);
|
||||||
return (uint16_t)bright >> 3;
|
return (uint16_t)bright >> 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -404,43 +476,36 @@ static inline lv_color_t lv_color_make(int r8, int g8, int b8)
|
|||||||
static inline lv_color_t lv_color_make(uint8_t r8, int g8, int b8)
|
static inline lv_color_t lv_color_make(uint8_t r8, int g8, int b8)
|
||||||
{
|
{
|
||||||
lv_color_t color;
|
lv_color_t color;
|
||||||
color.ch.blue = b8 >> 6;
|
LV_COLOR_SET_B(color, b8 >> 6);
|
||||||
color.ch.green = g8 >> 5;
|
LV_COLOR_SET_G(color, g8 >> 5);
|
||||||
color.ch.red = r8 >> 5;
|
LV_COLOR_SET_R(color, r8 >> 5);
|
||||||
|
LV_COLOR_SET_A(color, 0xFF);
|
||||||
return color;
|
return color;
|
||||||
}
|
}
|
||||||
#elif LV_COLOR_DEPTH == 16
|
#elif LV_COLOR_DEPTH == 16
|
||||||
#if LV_COLOR_16_SWAP == 0
|
#if LV_COLOR_16_SWAP == 0
|
||||||
#define LV_COLOR_MAKE(r8, g8, b8) ((lv_color_t){{b8 >> 3, g8 >> 2, r8 >> 3}})
|
#define LV_COLOR_MAKE(r8, g8, b8) ((lv_color_t){{b8 >> 3, g8 >> 2, r8 >> 3}})
|
||||||
static inline lv_color_t lv_color_make(uint8_t r8, uint8_t g8, uint8_t b8)
|
|
||||||
{
|
|
||||||
lv_color_t color;
|
|
||||||
color.ch.blue = (uint16_t)(b8 >> 3);
|
|
||||||
color.ch.green = (uint16_t)(g8 >> 2);
|
|
||||||
color.ch.red = (uint16_t)(r8 >> 3);
|
|
||||||
return color;
|
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
#define LV_COLOR_MAKE(r8, g8, b8) ((lv_color_t){{g8 >> 5, r8 >> 3, b8 >> 3, (g8 >> 2) & 0x7}})
|
#define LV_COLOR_MAKE(r8, g8, b8) ((lv_color_t){{g8 >> 5, r8 >> 3, b8 >> 3, (g8 >> 2) & 0x7}})
|
||||||
|
#endif
|
||||||
static inline lv_color_t lv_color_make(uint8_t r8, uint8_t g8, uint8_t b8)
|
static inline lv_color_t lv_color_make(uint8_t r8, uint8_t g8, uint8_t b8)
|
||||||
{
|
{
|
||||||
lv_color_t color;
|
lv_color_t color;
|
||||||
color.ch.green_h = (uint16_t)(g8 >> 5);
|
LV_COLOR_SET_B(color, b8 >> 3);
|
||||||
color.ch.red = (uint16_t)(r8 >> 3);
|
LV_COLOR_SET_G(color, g8 >> 2);
|
||||||
color.ch.blue = (uint16_t)(b8 >> 3);
|
LV_COLOR_SET_R(color, r8 >> 3);
|
||||||
color.ch.green_l = (uint16_t)((g8 >> 2) & 0x7);
|
LV_COLOR_SET_A(color, 0xFF);
|
||||||
return color;
|
return color;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
#elif LV_COLOR_DEPTH == 32
|
#elif LV_COLOR_DEPTH == 32
|
||||||
#define LV_COLOR_MAKE(r8, g8, b8) ((lv_color_t){{b8, g8, r8, 0xff}}) /*Fix 0xff alpha*/
|
#define LV_COLOR_MAKE(r8, g8, b8) ((lv_color_t){{b8, g8, r8, 0xff}}) /*Fix 0xff alpha*/
|
||||||
static inline lv_color_t lv_color_make(uint8_t r8, uint8_t g8, uint8_t b8)
|
static inline lv_color_t lv_color_make(uint8_t r8, uint8_t g8, uint8_t b8)
|
||||||
{
|
{
|
||||||
lv_color_t color;
|
lv_color_t color;
|
||||||
color.ch.blue = b8;
|
LV_COLOR_SET_B(color, b8);
|
||||||
color.ch.green = g8;
|
LV_COLOR_SET_G(color, g8);
|
||||||
color.ch.red = r8;
|
LV_COLOR_SET_R(color, r8);
|
||||||
color.ch.alpha = 0xff;
|
LV_COLOR_SET_A(color, 0xFF);
|
||||||
return color;
|
return color;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ uint32_t (*lv_txt_encoded_conv_wc)(uint32_t) = lv_txt_utf8_con
|
|||||||
uint32_t (*lv_txt_encoded_next)(const char *, uint32_t *) = lv_txt_utf8_next;
|
uint32_t (*lv_txt_encoded_next)(const char *, uint32_t *) = lv_txt_utf8_next;
|
||||||
uint32_t (*lv_txt_encoded_prev)(const char *, uint32_t *) = lv_txt_utf8_prev;
|
uint32_t (*lv_txt_encoded_prev)(const char *, uint32_t *) = lv_txt_utf8_prev;
|
||||||
uint32_t (*lv_txt_encoded_get_byte_id)(const char *, uint32_t) = lv_txt_utf8_get_byte_id;
|
uint32_t (*lv_txt_encoded_get_byte_id)(const char *, uint32_t) = lv_txt_utf8_get_byte_id;
|
||||||
uint32_t (*lv_encoded_get_char_id)(const char *, uint32_t) = lv_txt_utf8_get_char_id;
|
uint32_t (*lv_txt_encoded_get_char_id)(const char *, uint32_t) = lv_txt_utf8_get_char_id;
|
||||||
uint32_t (*lv_txt_get_encoded_length)(const char *) = lv_txt_utf8_get_length;
|
uint32_t (*lv_txt_get_encoded_length)(const char *) = lv_txt_utf8_get_length;
|
||||||
#elif LV_TXT_ENC == LV_TXT_ENC_ASCII
|
#elif LV_TXT_ENC == LV_TXT_ENC_ASCII
|
||||||
uint8_t (*lv_txt_encoded_size)(const char *) = lv_txt_iso8859_1_size;
|
uint8_t (*lv_txt_encoded_size)(const char *) = lv_txt_iso8859_1_size;
|
||||||
@@ -65,7 +65,7 @@ uint32_t (*lv_txt_encoded_conv_wc)(uint32_t) = lv_txt_iso8859_
|
|||||||
uint32_t (*lv_txt_encoded_next)(const char *, uint32_t *) = lv_txt_iso8859_1_next;
|
uint32_t (*lv_txt_encoded_next)(const char *, uint32_t *) = lv_txt_iso8859_1_next;
|
||||||
uint32_t (*lv_txt_encoded_prev)(const char *, uint32_t *) = lv_txt_iso8859_1_prev;
|
uint32_t (*lv_txt_encoded_prev)(const char *, uint32_t *) = lv_txt_iso8859_1_prev;
|
||||||
uint32_t (*lv_txt_encoded_get_byte_id)(const char *, uint32_t) = lv_txt_iso8859_1_get_byte_id;
|
uint32_t (*lv_txt_encoded_get_byte_id)(const char *, uint32_t) = lv_txt_iso8859_1_get_byte_id;
|
||||||
uint32_t (*lv_encoded_get_char_id)(const char *, uint32_t) = lv_txt_iso8859_1_get_char_id;
|
uint32_t (*lv_txt_encoded_get_char_id)(const char *, uint32_t) = lv_txt_iso8859_1_get_char_id;
|
||||||
uint32_t (*lv_txt_get_encoded_length)(const char *) = lv_txt_iso8859_1_get_length;
|
uint32_t (*lv_txt_get_encoded_length)(const char *) = lv_txt_iso8859_1_get_length;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -474,7 +474,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*/
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -651,7 +651,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;
|
||||||
|
|||||||
@@ -188,7 +188,7 @@ extern uint32_t (*lv_txt_encoded_get_byte_id)(const char *, uint32_t);
|
|||||||
* @param byte_id byte index
|
* @param byte_id byte index
|
||||||
* @return character index of the letter at 'byte_id'th position
|
* @return character index of the letter at 'byte_id'th position
|
||||||
*/
|
*/
|
||||||
extern uint32_t (*lv_encoded_get_char_id)(const char *, uint32_t);
|
extern uint32_t (*lv_txt_encoded_get_char_id)(const char *, uint32_t);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the number of characters (and NOT bytes) in a string.
|
* Get the number of characters (and NOT bytes) in a string.
|
||||||
|
|||||||
@@ -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 */
|
||||||
act_x = (unit_act_cnt * all_unit_w) / unit_cnt + i * style_bg->body.padding.inner +
|
if(base_dir == LV_BIDI_DIR_RTL) {
|
||||||
style_bg->body.padding.left;
|
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 +
|
||||||
|
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*/
|
||||||
@@ -644,7 +651,6 @@ static bool lv_btnm_design(lv_obj_t * btnm, const lv_area_t * mask, lv_design_mo
|
|||||||
}
|
}
|
||||||
/*Draw the object*/
|
/*Draw the object*/
|
||||||
else if(mode == LV_DESIGN_DRAW_MAIN) {
|
else if(mode == LV_DESIGN_DRAW_MAIN) {
|
||||||
|
|
||||||
ancestor_design_f(btnm, mask, mode);
|
ancestor_design_f(btnm, mask, mode);
|
||||||
|
|
||||||
lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm);
|
lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm);
|
||||||
@@ -665,7 +671,6 @@ static bool lv_btnm_design(lv_obj_t * btnm, const lv_area_t * mask, lv_design_mo
|
|||||||
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;
|
||||||
|
|
||||||
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*/
|
||||||
while(strcmp(ext->map_p[txt_i], "\n") == 0) {
|
while(strcmp(ext->map_p[txt_i], "\n") == 0) {
|
||||||
@@ -734,9 +739,10 @@ static bool lv_btnm_design(lv_obj_t * btnm, const lv_area_t * mask, lv_design_mo
|
|||||||
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;
|
||||||
|
|
||||||
lv_draw_label(&area_tmp, mask, btn_style, opa_scale, ext->map_p[txt_i], txt_flag, NULL, NULL, NULL);
|
lv_draw_label(&area_tmp, mask, btn_style, opa_scale, ext->map_p[txt_i], txt_flag, NULL, NULL, NULL, lv_obj_get_base_dir(btnm));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -670,6 +670,9 @@ static lv_coord_t get_day_names_height(lv_obj_t * calendar)
|
|||||||
static void draw_header(lv_obj_t * calendar, const lv_area_t * mask)
|
static void draw_header(lv_obj_t * calendar, const lv_area_t * mask)
|
||||||
{
|
{
|
||||||
lv_calendar_ext_t * ext = lv_obj_get_ext_attr(calendar);
|
lv_calendar_ext_t * ext = lv_obj_get_ext_attr(calendar);
|
||||||
|
|
||||||
|
lv_bidi_dir_t bidi_dir = lv_obj_get_base_dir(calendar);
|
||||||
|
|
||||||
lv_opa_t opa_scale = lv_obj_get_opa_scale(calendar);
|
lv_opa_t opa_scale = lv_obj_get_opa_scale(calendar);
|
||||||
|
|
||||||
lv_area_t header_area;
|
lv_area_t header_area;
|
||||||
@@ -687,19 +690,19 @@ static void draw_header(lv_obj_t * calendar, const lv_area_t * mask)
|
|||||||
txt_buf[5] = '\0';
|
txt_buf[5] = '\0';
|
||||||
strcpy(&txt_buf[5], get_month_name(calendar, ext->showed_date.month));
|
strcpy(&txt_buf[5], get_month_name(calendar, ext->showed_date.month));
|
||||||
header_area.y1 += ext->style_header->body.padding.top;
|
header_area.y1 += ext->style_header->body.padding.top;
|
||||||
lv_draw_label(&header_area, mask, ext->style_header, opa_scale, txt_buf, LV_TXT_FLAG_CENTER, NULL, NULL, NULL);
|
lv_draw_label(&header_area, mask, ext->style_header, opa_scale, txt_buf, LV_TXT_FLAG_CENTER, NULL, NULL, NULL, bidi_dir);
|
||||||
|
|
||||||
/*Add the left arrow*/
|
/*Add the left arrow*/
|
||||||
const lv_style_t * arrow_style = ext->btn_pressing < 0 ? ext->style_header_pr : ext->style_header;
|
const lv_style_t * arrow_style = ext->btn_pressing < 0 ? ext->style_header_pr : ext->style_header;
|
||||||
header_area.x1 += ext->style_header->body.padding.left;
|
header_area.x1 += ext->style_header->body.padding.left;
|
||||||
lv_draw_label(&header_area, mask, arrow_style, opa_scale, LV_SYMBOL_LEFT, LV_TXT_FLAG_NONE, NULL, NULL, NULL);
|
lv_draw_label(&header_area, mask, arrow_style, opa_scale, LV_SYMBOL_LEFT, LV_TXT_FLAG_NONE, NULL, NULL, NULL, bidi_dir);
|
||||||
|
|
||||||
/*Add the right arrow*/
|
/*Add the right arrow*/
|
||||||
arrow_style = ext->btn_pressing > 0 ? ext->style_header_pr : ext->style_header;
|
arrow_style = ext->btn_pressing > 0 ? ext->style_header_pr : ext->style_header;
|
||||||
header_area.x1 = header_area.x2 - ext->style_header->body.padding.right -
|
header_area.x1 = header_area.x2 - ext->style_header->body.padding.right -
|
||||||
lv_txt_get_width(LV_SYMBOL_RIGHT, strlen(LV_SYMBOL_RIGHT), arrow_style->text.font,
|
lv_txt_get_width(LV_SYMBOL_RIGHT, strlen(LV_SYMBOL_RIGHT), arrow_style->text.font,
|
||||||
arrow_style->text.line_space, LV_TXT_FLAG_NONE);
|
arrow_style->text.line_space, LV_TXT_FLAG_NONE);
|
||||||
lv_draw_label(&header_area, mask, arrow_style, opa_scale, LV_SYMBOL_RIGHT, LV_TXT_FLAG_NONE, NULL, NULL, NULL);
|
lv_draw_label(&header_area, mask, arrow_style, opa_scale, LV_SYMBOL_RIGHT, LV_TXT_FLAG_NONE, NULL, NULL, NULL, bidi_dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -710,6 +713,7 @@ static void draw_header(lv_obj_t * calendar, const lv_area_t * mask)
|
|||||||
static void draw_day_names(lv_obj_t * calendar, const lv_area_t * mask)
|
static void draw_day_names(lv_obj_t * calendar, const lv_area_t * mask)
|
||||||
{
|
{
|
||||||
lv_calendar_ext_t * ext = lv_obj_get_ext_attr(calendar);
|
lv_calendar_ext_t * ext = lv_obj_get_ext_attr(calendar);
|
||||||
|
lv_bidi_dir_t bidi_dir = lv_obj_get_base_dir(calendar);
|
||||||
lv_opa_t opa_scale = lv_obj_get_opa_scale(calendar);
|
lv_opa_t opa_scale = lv_obj_get_opa_scale(calendar);
|
||||||
|
|
||||||
lv_coord_t l_pad = ext->style_day_names->body.padding.left;
|
lv_coord_t l_pad = ext->style_day_names->body.padding.left;
|
||||||
@@ -724,7 +728,7 @@ static void draw_day_names(lv_obj_t * calendar, const lv_area_t * mask)
|
|||||||
label_area.x1 = calendar->coords.x1 + (w * i) / 7 + l_pad;
|
label_area.x1 = calendar->coords.x1 + (w * i) / 7 + l_pad;
|
||||||
label_area.x2 = label_area.x1 + box_w - 1;
|
label_area.x2 = label_area.x1 + box_w - 1;
|
||||||
lv_draw_label(&label_area, mask, ext->style_day_names, opa_scale, get_day_name(calendar, i), LV_TXT_FLAG_CENTER,
|
lv_draw_label(&label_area, mask, ext->style_day_names, opa_scale, get_day_name(calendar, i), LV_TXT_FLAG_CENTER,
|
||||||
NULL, NULL, NULL);
|
NULL, NULL, NULL, bidi_dir);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -736,6 +740,7 @@ static void draw_day_names(lv_obj_t * calendar, const lv_area_t * mask)
|
|||||||
static void draw_days(lv_obj_t * calendar, const lv_area_t * mask)
|
static void draw_days(lv_obj_t * calendar, const lv_area_t * mask)
|
||||||
{
|
{
|
||||||
lv_calendar_ext_t * ext = lv_obj_get_ext_attr(calendar);
|
lv_calendar_ext_t * ext = lv_obj_get_ext_attr(calendar);
|
||||||
|
lv_bidi_dir_t bidi_dir = lv_obj_get_base_dir(calendar);
|
||||||
const lv_style_t * style_bg = lv_calendar_get_style(calendar, LV_CALENDAR_STYLE_BG);
|
const lv_style_t * style_bg = lv_calendar_get_style(calendar, LV_CALENDAR_STYLE_BG);
|
||||||
lv_area_t label_area;
|
lv_area_t label_area;
|
||||||
lv_opa_t opa_scale = lv_obj_get_opa_scale(calendar);
|
lv_opa_t opa_scale = lv_obj_get_opa_scale(calendar);
|
||||||
@@ -853,7 +858,7 @@ static void draw_days(lv_obj_t * calendar, const lv_area_t * mask)
|
|||||||
|
|
||||||
/*Write the day's number*/
|
/*Write the day's number*/
|
||||||
lv_utils_num_to_str(day_cnt, buf);
|
lv_utils_num_to_str(day_cnt, buf);
|
||||||
lv_draw_label(&label_area, mask, final_style, opa_scale, buf, LV_TXT_FLAG_CENTER, NULL, NULL, NULL);
|
lv_draw_label(&label_area, mask, final_style, opa_scale, buf, LV_TXT_FLAG_CENTER, NULL, NULL, NULL, bidi_dir);
|
||||||
|
|
||||||
/*Go to the next day*/
|
/*Go to the next day*/
|
||||||
day_cnt++;
|
day_cnt++;
|
||||||
|
|||||||
@@ -585,7 +585,7 @@ void lv_canvas_draw_text(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y, lv_coord
|
|||||||
default: flag = LV_TXT_FLAG_NONE; break;
|
default: flag = LV_TXT_FLAG_NONE; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
lv_draw_label(&coords, &mask, style, LV_OPA_COVER, txt, flag, NULL, NULL, NULL);
|
lv_draw_label(&coords, &mask, style, LV_OPA_COVER, txt, flag, NULL, NULL, NULL, lv_obj_get_base_dir(canvas));
|
||||||
|
|
||||||
lv_refr_set_disp_refreshing(refr_ori);
|
lv_refr_set_disp_refreshing(refr_ori);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1379,7 +1379,7 @@ static void lv_chart_draw_y_ticks(lv_obj_t * chart, const lv_area_t * mask, uint
|
|||||||
a.x2 = p2.x + size.x + LV_CHART_AXIS_TO_LABEL_DISTANCE;
|
a.x2 = p2.x + size.x + LV_CHART_AXIS_TO_LABEL_DISTANCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
lv_draw_label(&a, mask, style, opa_scale, buf, LV_TXT_FLAG_CENTER, NULL, NULL, NULL);
|
lv_draw_label(&a, mask, style, opa_scale, buf, LV_TXT_FLAG_CENTER, NULL, NULL, NULL, lv_obj_get_base_dir(chart));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1465,7 +1465,7 @@ static void lv_chart_draw_x_ticks(lv_obj_t * chart, const lv_area_t * mask)
|
|||||||
/* set the area at some distance of the major tick len under of the tick */
|
/* set the area at some distance of the major tick len under of the tick */
|
||||||
lv_area_t a = {(p2.x - size.x / 2), (p2.y + LV_CHART_AXIS_TO_LABEL_DISTANCE), (p2.x + size.x / 2),
|
lv_area_t a = {(p2.x - size.x / 2), (p2.y + LV_CHART_AXIS_TO_LABEL_DISTANCE), (p2.x + size.x / 2),
|
||||||
(p2.y + size.y + LV_CHART_AXIS_TO_LABEL_DISTANCE)};
|
(p2.y + size.y + LV_CHART_AXIS_TO_LABEL_DISTANCE)};
|
||||||
lv_draw_label(&a, mask, style, opa_scale, buf, LV_TXT_FLAG_CENTER, NULL, NULL, NULL);
|
lv_draw_label(&a, mask, style, opa_scale, buf, LV_TXT_FLAG_CENTER, NULL, NULL, NULL, lv_obj_get_base_dir(chart));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -364,23 +365,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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -389,12 +390,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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -275,12 +275,8 @@ bool lv_cpicker_set_hsv(lv_obj_t * cpicker, lv_color_hsv_t hsv)
|
|||||||
*/
|
*/
|
||||||
bool lv_cpicker_set_color(lv_obj_t * cpicker, lv_color_t color)
|
bool lv_cpicker_set_color(lv_obj_t * cpicker, lv_color_t color)
|
||||||
{
|
{
|
||||||
#if LV_COLOR_DEPTH == 16 && LV_COLOR_16_SWAP != 0
|
return lv_cpicker_set_hsv(cpicker,
|
||||||
uint8_t green = (color.ch.green_h << 3) + color.ch.green_l;
|
lv_color_rgb_to_hsv(LV_COLOR_GET_R(color), LV_COLOR_GET_G(color), LV_COLOR_GET_B(color)));
|
||||||
return lv_cpicker_set_hsv(cpicker, lv_color_rgb_to_hsv(color.ch.red, green, color.ch.blue));
|
|
||||||
#else
|
|
||||||
return lv_cpicker_set_hsv(cpicker, lv_color_rgb_to_hsv(color.ch.red, color.ch.green, color.ch.blue));
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -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;
|
||||||
@@ -597,7 +609,7 @@ static bool lv_ddlist_design(lv_obj_t * ddlist, const lv_area_t * mask, lv_desig
|
|||||||
new_style.text.opa = sel_style->text.opa;
|
new_style.text.opa = sel_style->text.opa;
|
||||||
lv_txt_flag_t flag = lv_ddlist_get_txt_flag(ddlist);
|
lv_txt_flag_t flag = lv_ddlist_get_txt_flag(ddlist);
|
||||||
lv_draw_label(&ext->label->coords, &mask_sel, &new_style, opa_scale, lv_label_get_text(ext->label),
|
lv_draw_label(&ext->label->coords, &mask_sel, &new_style, opa_scale, lv_label_get_text(ext->label),
|
||||||
flag, NULL, NULL, NULL);
|
flag, NULL, NULL, NULL, lv_obj_get_base_dir(ddlist));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -630,9 +642,9 @@ static bool lv_ddlist_design(lv_obj_t * ddlist, const lv_area_t * mask, lv_desig
|
|||||||
bool area_ok;
|
bool area_ok;
|
||||||
area_ok = lv_area_intersect(&mask_arrow, mask, &area_arrow);
|
area_ok = lv_area_intersect(&mask_arrow, mask, &area_arrow);
|
||||||
if(area_ok) {
|
if(area_ok) {
|
||||||
|
/*Use a down arrow in ddlist, you can replace it with yourcustom symbol*/
|
||||||
lv_draw_label(&area_arrow, &mask_arrow, &new_style, opa_scale, LV_SYMBOL_DOWN, LV_TXT_FLAG_NONE,
|
lv_draw_label(&area_arrow, &mask_arrow, &new_style, opa_scale, LV_SYMBOL_DOWN, LV_TXT_FLAG_NONE,
|
||||||
NULL, NULL, NULL); /*Use a down arrow in ddlist, you can replace it with your
|
NULL, NULL, NULL, lv_obj_get_base_dir(ddlist));
|
||||||
custom symbol*/
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -662,7 +674,15 @@ static lv_res_t lv_ddlist_signal(lv_obj_t * ddlist, lv_signal_t sign, void * par
|
|||||||
|
|
||||||
if(sign == LV_SIGNAL_STYLE_CHG) {
|
if(sign == LV_SIGNAL_STYLE_CHG) {
|
||||||
lv_ddlist_refr_size(ddlist, 0);
|
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);
|
||||||
} else if(sign == LV_SIGNAL_CLEANUP) {
|
} else if(sign == LV_SIGNAL_CLEANUP) {
|
||||||
ext->label = NULL;
|
ext->label = NULL;
|
||||||
} else if(sign == LV_SIGNAL_FOCUS) {
|
} else if(sign == LV_SIGNAL_FOCUS) {
|
||||||
@@ -981,7 +1001,12 @@ 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)
|
||||||
{
|
{
|
||||||
lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist);
|
lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(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));
|
||||||
@@ -989,6 +1014,9 @@ static void lv_ddlist_refr_width(lv_obj_t * 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);
|
||||||
|
|
||||||
switch(lv_label_get_align(ext->label)) {
|
switch(lv_label_get_align(ext->label)) {
|
||||||
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;
|
||||||
|
|||||||
@@ -389,7 +389,7 @@ static void lv_gauge_draw_scale(lv_obj_t * gauge, const lv_area_t * mask)
|
|||||||
label_cord.x2 = label_cord.x1 + label_size.x;
|
label_cord.x2 = label_cord.x1 + label_size.x;
|
||||||
label_cord.y2 = label_cord.y1 + label_size.y;
|
label_cord.y2 = label_cord.y1 + label_size.y;
|
||||||
|
|
||||||
lv_draw_label(&label_cord, mask, style, opa_scale, scale_txt, LV_TXT_FLAG_NONE, NULL, NULL, NULL);
|
lv_draw_label(&label_cord, mask, style, opa_scale, scale_txt, LV_TXT_FLAG_NONE, NULL, NULL, NULL, lv_obj_get_base_dir(gauge));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -384,7 +384,7 @@ static bool lv_img_design(lv_obj_t * img, const lv_area_t * mask, lv_design_mode
|
|||||||
lv_style_t style_mod;
|
lv_style_t style_mod;
|
||||||
lv_style_copy(&style_mod, style);
|
lv_style_copy(&style_mod, style);
|
||||||
style_mod.text.color = style->image.color;
|
style_mod.text.color = style->image.color;
|
||||||
lv_draw_label(&coords, mask, &style_mod, opa_scale, ext->src, LV_TXT_FLAG_NONE, NULL, NULL, NULL);
|
lv_draw_label(&coords, mask, &style_mod, opa_scale, ext->src, LV_TXT_FLAG_NONE, NULL, NULL, NULL, lv_obj_get_base_dir(img));
|
||||||
} else {
|
} else {
|
||||||
/*Trigger the error handler of image drawer*/
|
/*Trigger the error handler of image drawer*/
|
||||||
LV_LOG_WARN("lv_img_design: image source type is unknown");
|
LV_LOG_WARN("lv_img_design: image source type is unknown");
|
||||||
|
|||||||
@@ -304,7 +304,7 @@ static bool lv_imgbtn_design(lv_obj_t * imgbtn, const lv_area_t * mask, lv_desig
|
|||||||
#if LV_IMGBTN_TILED == 0
|
#if LV_IMGBTN_TILED == 0
|
||||||
const void * src = ext->img_src[state];
|
const void * src = ext->img_src[state];
|
||||||
if(lv_img_src_get_type(src) == LV_IMG_SRC_SYMBOL) {
|
if(lv_img_src_get_type(src) == LV_IMG_SRC_SYMBOL) {
|
||||||
lv_draw_label(&imgbtn->coords, mask, style, opa_scale, src, LV_TXT_FLAG_NONE, NULL, NULL, NULL);
|
lv_draw_label(&imgbtn->coords, mask, style, opa_scale, src, LV_TXT_FLAG_NONE, NULL, NULL, NULL, lv_obj_get_base_dir(imgbtn));
|
||||||
} else {
|
} else {
|
||||||
lv_draw_img(&imgbtn->coords, mask, src, style, opa_scale);
|
lv_draw_img(&imgbtn->coords, mask, src, style, opa_scale);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -205,7 +206,9 @@ void lv_label_set_text(lv_obj_t * label, const char * text)
|
|||||||
if(ext->text == NULL) return;
|
if(ext->text == NULL) return;
|
||||||
|
|
||||||
strcpy(ext->text, text);
|
strcpy(ext->text, text);
|
||||||
ext->static_txt = 0; /*Now the text is dynamically allocated*/
|
|
||||||
|
/*Now the text is dynamically allocated*/
|
||||||
|
ext->static_txt = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
lv_label_refr_text(label);
|
lv_label_refr_text(label);
|
||||||
@@ -506,7 +509,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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -560,7 +578,7 @@ uint16_t lv_label_get_anim_speed(const lv_obj_t * label)
|
|||||||
* index (different in UTF-8)
|
* index (different in UTF-8)
|
||||||
* @param pos store the result here (E.g. index = 0 gives 0;0 coordinates)
|
* @param pos store the result here (E.g. index = 0 gives 0;0 coordinates)
|
||||||
*/
|
*/
|
||||||
void lv_label_get_letter_pos(const lv_obj_t * label, uint16_t index, lv_point_t * pos)
|
void lv_label_get_letter_pos(const lv_obj_t * label, uint16_t char_id, lv_point_t * pos)
|
||||||
{
|
{
|
||||||
LV_ASSERT_OBJ(label, LV_OBJX_NAME);
|
LV_ASSERT_OBJ(label, LV_OBJX_NAME);
|
||||||
LV_ASSERT_NULL(pos);
|
LV_ASSERT_NULL(pos);
|
||||||
@@ -578,19 +596,22 @@ 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) {
|
||||||
max_w = LV_COORD_MAX;
|
max_w = LV_COORD_MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
index = lv_txt_encoded_get_byte_id(txt, index);
|
uint16_t byte_id = lv_txt_encoded_get_byte_id(txt, char_id);
|
||||||
|
|
||||||
/*Search the line of the index letter */;
|
/*Search the line of the index letter */;
|
||||||
while(txt[new_line_start] != '\0') {
|
while(txt[new_line_start] != '\0') {
|
||||||
new_line_start += lv_txt_get_next_line(&txt[line_start], font, style->text.letter_space, max_w, flag);
|
new_line_start += lv_txt_get_next_line(&txt[line_start], font, style->text.letter_space, max_w, flag);
|
||||||
if(index < new_line_start || txt[new_line_start] == '\0')
|
if(byte_id < new_line_start || txt[new_line_start] == '\0')
|
||||||
break; /*The line of 'index' letter begins at 'line_start'*/
|
break; /*The line of 'index' letter begins at 'line_start'*/
|
||||||
|
|
||||||
y += letter_height + style->text.line_space;
|
y += letter_height + style->text.line_space;
|
||||||
@@ -598,26 +619,50 @@ void lv_label_get_letter_pos(const lv_obj_t * label, uint16_t index, lv_point_t
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*If the last character is line break then go to the next line*/
|
/*If the last character is line break then go to the next line*/
|
||||||
if(index > 0) {
|
if(byte_id > 0) {
|
||||||
if((txt[index - 1] == '\n' || txt[index - 1] == '\r') && txt[index] == '\0') {
|
if((txt[byte_id - 1] == '\n' || txt[byte_id - 1] == '\r') && txt[byte_id] == '\0') {
|
||||||
y += letter_height + style->text.line_space;
|
y += letter_height + style->text.line_space;
|
||||||
line_start = index;
|
line_start = byte_id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char *bidi_txt;
|
||||||
|
uint16_t visual_byte_pos;
|
||||||
|
#if LV_USE_BIDI
|
||||||
|
/*Handle Bidi*/
|
||||||
|
if(new_line_start == byte_id) {
|
||||||
|
visual_byte_pos = byte_id - line_start;
|
||||||
|
bidi_txt = &txt[line_start];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
uint16_t line_char_id = lv_txt_encoded_get_char_id(&txt[line_start], byte_id - line_start);
|
||||||
|
|
||||||
|
bool is_rtl;
|
||||||
|
char *mutable_bidi_txt;
|
||||||
|
uint16_t visual_char_pos = lv_bidi_get_visual_pos(&txt[line_start], &mutable_bidi_txt, new_line_start - line_start, lv_obj_get_base_dir(label), line_char_id, &is_rtl);
|
||||||
|
bidi_txt = mutable_bidi_txt;
|
||||||
|
if (is_rtl) visual_char_pos++;
|
||||||
|
visual_byte_pos = lv_txt_encoded_get_byte_id(bidi_txt, visual_char_pos);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
bidi_txt = &txt[line_start];
|
||||||
|
visual_byte_pos = byte_id - line_start;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*Calculate the x coordinate*/
|
/*Calculate the x coordinate*/
|
||||||
lv_coord_t x = lv_txt_get_width(&txt[line_start], index - line_start, font, style->text.letter_space, flag);
|
lv_coord_t x = lv_txt_get_width(bidi_txt, visual_byte_pos, font, style->text.letter_space, flag);
|
||||||
|
|
||||||
if(index != line_start) x += style->text.letter_space;
|
if(char_id != 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(bidi_txt, 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(bidi_txt, new_line_start - line_start, font, style->text.letter_space, flag);
|
||||||
|
|
||||||
x += lv_obj_get_width(label) - line_w;
|
x += lv_obj_get_width(label) - line_w;
|
||||||
}
|
}
|
||||||
@@ -647,10 +692,15 @@ uint16_t lv_label_get_letter_on(const lv_obj_t * label, lv_point_t * pos)
|
|||||||
uint8_t letter_height = lv_font_get_line_height(font);
|
uint8_t letter_height = lv_font_get_line_height(font);
|
||||||
lv_coord_t y = 0;
|
lv_coord_t y = 0;
|
||||||
lv_txt_flag_t flag = LV_TXT_FLAG_NONE;
|
lv_txt_flag_t flag = LV_TXT_FLAG_NONE;
|
||||||
|
uint16_t logical_pos;
|
||||||
|
char *bidi_txt;
|
||||||
|
|
||||||
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) {
|
||||||
@@ -675,47 +725,72 @@ uint16_t lv_label_get_letter_on(const lv_obj_t * label, lv_point_t * pos)
|
|||||||
line_start = new_line_start;
|
line_start = new_line_start;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if LV_USE_BIDI
|
||||||
|
bidi_txt = lv_draw_get_buf(new_line_start - line_start + 1);
|
||||||
|
uint16_t txt_len = new_line_start - line_start;
|
||||||
|
if(bidi_txt[new_line_start] == '\0') txt_len--;
|
||||||
|
lv_bidi_process_paragraph(txt + line_start, bidi_txt, txt_len, lv_obj_get_base_dir(label), NULL, 0);
|
||||||
|
#else
|
||||||
|
bidi_txt = (char*)txt + line_start;
|
||||||
|
#endif
|
||||||
|
|
||||||
/*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(bidi_txt, 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(bidi_txt, 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;
|
||||||
|
|
||||||
uint32_t i = line_start;
|
uint32_t i = 0;
|
||||||
uint32_t i_act = i;
|
uint32_t i_act = i;
|
||||||
uint32_t letter;
|
uint32_t letter;
|
||||||
uint32_t letter_next;
|
uint32_t letter_next;
|
||||||
|
|
||||||
while(i < new_line_start) {
|
if(new_line_start > 0) {
|
||||||
/* Get the current letter.*/
|
while(i + line_start < new_line_start) {
|
||||||
letter = lv_txt_encoded_next(txt, &i);
|
/* Get the current letter.*/
|
||||||
|
letter = lv_txt_encoded_next(bidi_txt, &i);
|
||||||
|
|
||||||
/*Get the next letter too for kerning*/
|
/*Get the next letter too for kerning*/
|
||||||
letter_next = lv_txt_encoded_next(&txt[i], NULL);
|
letter_next = lv_txt_encoded_next(&bidi_txt[i], NULL);
|
||||||
|
|
||||||
/*Handle the recolor command*/
|
/*Handle the recolor command*/
|
||||||
if((flag & LV_TXT_FLAG_RECOLOR) != 0) {
|
if((flag & LV_TXT_FLAG_RECOLOR) != 0) {
|
||||||
if(lv_txt_is_cmd(&cmd_state, txt[i]) != false) {
|
if(lv_txt_is_cmd(&cmd_state, bidi_txt[i]) != false) {
|
||||||
continue; /*Skip the letter is it is part of a command*/
|
continue; /*Skip the letter is it is part of a command*/
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
x += lv_font_get_glyph_width(font, letter, letter_next);
|
x += lv_font_get_glyph_width(font, letter, letter_next);
|
||||||
|
|
||||||
/*Finish if the x position or the last char of the line is reached*/
|
/*Finish if the x position or the last char of the line is reached*/
|
||||||
if(pos->x < x || i == new_line_start) {
|
if(pos->x < x || i + line_start == new_line_start) {
|
||||||
i = i_act;
|
i = i_act;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
x += style->text.letter_space;
|
||||||
|
i_act = i;
|
||||||
}
|
}
|
||||||
x += style->text.letter_space;
|
|
||||||
i_act = i;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return lv_encoded_get_char_id(txt, i);
|
#if LV_USE_BIDI
|
||||||
|
/*Handle Bidi*/
|
||||||
|
bool is_rtl;
|
||||||
|
logical_pos = lv_bidi_get_logical_pos(&txt[line_start], NULL, txt_len, lv_obj_get_base_dir(label), lv_txt_encoded_get_char_id(bidi_txt, i), &is_rtl);
|
||||||
|
if (is_rtl) logical_pos++;
|
||||||
|
#else
|
||||||
|
logical_pos = lv_txt_encoded_get_char_id(bidi_txt, i);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return logical_pos + lv_txt_encoded_get_char_id(txt, line_start);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -776,10 +851,11 @@ bool lv_label_is_char_under_pos(const lv_obj_t * label, lv_point_t * pos)
|
|||||||
uint8_t letter_height = lv_font_get_line_height(font);
|
uint8_t letter_height = lv_font_get_line_height(font);
|
||||||
lv_coord_t y = 0;
|
lv_coord_t y = 0;
|
||||||
lv_txt_flag_t flag = LV_TXT_FLAG_NONE;
|
lv_txt_flag_t flag = LV_TXT_FLAG_NONE;
|
||||||
|
lv_label_align_t align = lv_label_get_align(label);
|
||||||
|
|
||||||
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 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) {
|
||||||
@@ -799,11 +875,16 @@ bool lv_label_is_char_under_pos(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;
|
||||||
lv_coord_t last_x = 0;
|
lv_coord_t last_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;
|
||||||
|
|
||||||
@@ -878,7 +959,6 @@ void lv_label_ins_text(lv_obj_t * label, uint32_t pos, const char * txt)
|
|||||||
}
|
}
|
||||||
|
|
||||||
lv_txt_ins(ext->text, pos, txt);
|
lv_txt_ins(ext->text, pos, txt);
|
||||||
|
|
||||||
lv_label_refr_text(label);
|
lv_label_refr_text(label);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -953,14 +1033,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)*/
|
||||||
@@ -987,7 +1066,7 @@ static bool lv_label_design(lv_obj_t * label, const lv_area_t * mask, lv_design_
|
|||||||
|
|
||||||
sel.start = lv_label_get_text_sel_start(label);
|
sel.start = lv_label_get_text_sel_start(label);
|
||||||
sel.end = lv_label_get_text_sel_end(label);
|
sel.end = lv_label_get_text_sel_end(label);
|
||||||
lv_draw_label(&coords, mask, style, opa_scale, ext->text, flag, &ext->offset, &sel, hint);
|
lv_draw_label(&coords, mask, style, opa_scale, ext->text, flag, &ext->offset, &sel, hint, lv_obj_get_base_dir(label));
|
||||||
|
|
||||||
|
|
||||||
if(ext->long_mode == LV_LABEL_LONG_SROLL_CIRC) {
|
if(ext->long_mode == LV_LABEL_LONG_SROLL_CIRC) {
|
||||||
@@ -1003,14 +1082,14 @@ static bool lv_label_design(lv_obj_t * label, const lv_area_t * mask, lv_design_
|
|||||||
lv_font_get_glyph_width(style->text.font, ' ', ' ') * LV_LABEL_WAIT_CHAR_COUNT;
|
lv_font_get_glyph_width(style->text.font, ' ', ' ') * LV_LABEL_WAIT_CHAR_COUNT;
|
||||||
ofs.y = ext->offset.y;
|
ofs.y = ext->offset.y;
|
||||||
|
|
||||||
lv_draw_label(&coords, mask, style, opa_scale, ext->text, flag, &ofs, &sel, NULL);
|
lv_draw_label(&coords, mask, style, opa_scale, ext->text, flag, &ofs, &sel, NULL, lv_obj_get_base_dir(label));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*Draw the text again below the original to make an circular effect */
|
/*Draw the text again below the original to make an circular effect */
|
||||||
if(size.y > lv_obj_get_height(label)) {
|
if(size.y > lv_obj_get_height(label)) {
|
||||||
ofs.x = ext->offset.x;
|
ofs.x = ext->offset.x;
|
||||||
ofs.y = ext->offset.y + size.y + lv_font_get_line_height(style->text.font);
|
ofs.y = ext->offset.y + size.y + lv_font_get_line_height(style->text.font);
|
||||||
lv_draw_label(&coords, mask, style, opa_scale, ext->text, flag, &ofs, &sel, NULL);
|
lv_draw_label(&coords, mask, style, opa_scale, ext->text, flag, &ofs, &sel, NULL, lv_obj_get_base_dir(label));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1061,6 +1140,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;
|
||||||
}
|
}
|
||||||
@@ -1144,11 +1235,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;
|
||||||
@@ -1159,7 +1251,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)) {
|
||||||
anim.end = -size.x - lv_font_get_glyph_width(font, ' ', ' ') * LV_LABEL_WAIT_CHAR_COUNT;
|
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.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);
|
||||||
@@ -1171,7 +1270,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) {
|
||||||
anim.end = -size.y - (lv_font_get_line_height(font));
|
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.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);
|
||||||
|
|||||||
@@ -60,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;
|
||||||
|
|
||||||
@@ -68,12 +69,13 @@ 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
|
||||||
|
|||||||
@@ -177,6 +177,21 @@ void lv_lmeter_set_scale(lv_obj_t * lmeter, uint16_t angle, uint8_t line_cnt)
|
|||||||
lv_obj_invalidate(lmeter);
|
lv_obj_invalidate(lmeter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the angle settings of a line meter
|
||||||
|
* @param lmeter pointer to a line meter object
|
||||||
|
* @param angle angle where the meter will be facing (with its center)
|
||||||
|
*/
|
||||||
|
void lv_lmeter_set_angle(lv_obj_t * lmeter, uint16_t angle)
|
||||||
|
{
|
||||||
|
lv_lmeter_ext_t * ext = lv_obj_get_ext_attr(lmeter);
|
||||||
|
if(ext->angle == angle) return;
|
||||||
|
|
||||||
|
ext->angle = angle;
|
||||||
|
|
||||||
|
lv_obj_invalidate(lmeter);
|
||||||
|
}
|
||||||
|
|
||||||
/*=====================
|
/*=====================
|
||||||
* Getter functions
|
* Getter functions
|
||||||
*====================*/
|
*====================*/
|
||||||
@@ -287,7 +302,7 @@ static bool lv_lmeter_design(lv_obj_t * lmeter, const lv_area_t * mask, lv_desig
|
|||||||
|
|
||||||
lv_coord_t x_ofs = lv_obj_get_width(lmeter) / 2 + lmeter->coords.x1;
|
lv_coord_t x_ofs = lv_obj_get_width(lmeter) / 2 + lmeter->coords.x1;
|
||||||
lv_coord_t y_ofs = lv_obj_get_height(lmeter) / 2 + lmeter->coords.y1;
|
lv_coord_t y_ofs = lv_obj_get_height(lmeter) / 2 + lmeter->coords.y1;
|
||||||
int16_t angle_ofs = 90 + (360 - ext->scale_angle) / 2;
|
int16_t angle_ofs = ext->angle + 90 + (360 - ext->scale_angle) / 2;
|
||||||
int16_t level =
|
int16_t level =
|
||||||
(int32_t)((int32_t)(ext->cur_value - ext->min_value) * ext->line_cnt) / (ext->max_value - ext->min_value);
|
(int32_t)((int32_t)(ext->cur_value - ext->min_value) * ext->line_cnt) / (ext->max_value - ext->min_value);
|
||||||
uint8_t i;
|
uint8_t i;
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ typedef struct
|
|||||||
/*No inherited ext.*/ /*Ext. of ancestor*/
|
/*No inherited ext.*/ /*Ext. of ancestor*/
|
||||||
/*New data for this type */
|
/*New data for this type */
|
||||||
uint16_t scale_angle; /*Angle of the scale in deg. (0..360)*/
|
uint16_t scale_angle; /*Angle of the scale in deg. (0..360)*/
|
||||||
|
uint16_t angle;
|
||||||
uint8_t line_cnt; /*Count of lines */
|
uint8_t line_cnt; /*Count of lines */
|
||||||
int16_t cur_value;
|
int16_t cur_value;
|
||||||
int16_t min_value;
|
int16_t min_value;
|
||||||
@@ -88,6 +89,13 @@ void lv_lmeter_set_range(lv_obj_t * lmeter, int16_t min, int16_t max);
|
|||||||
*/
|
*/
|
||||||
void lv_lmeter_set_scale(lv_obj_t * lmeter, uint16_t angle, uint8_t line_cnt);
|
void lv_lmeter_set_scale(lv_obj_t * lmeter, uint16_t angle, uint8_t line_cnt);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the rotation settings of a line meter
|
||||||
|
* @param lmeter pointer to a line meter object
|
||||||
|
* @param angle angle of rotation (relative to the northen axis)
|
||||||
|
*/
|
||||||
|
void lv_lmeter_set_angle(lv_obj_t * lmeter, uint16_t angle);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the styles of a line meter
|
* Set the styles of a line meter
|
||||||
* @param lmeter pointer to a line meter object
|
* @param lmeter pointer to a line meter object
|
||||||
|
|||||||
@@ -828,8 +828,10 @@ static lv_res_t lv_page_signal(lv_obj_t * page, lv_signal_t sign, void * param)
|
|||||||
lv_page_ext_t * ext = lv_obj_get_ext_attr(page);
|
lv_page_ext_t * ext = lv_obj_get_ext_attr(page);
|
||||||
lv_obj_t * child;
|
lv_obj_t * child;
|
||||||
if(sign == LV_SIGNAL_CHILD_CHG) { /*Automatically move children to the scrollable object*/
|
if(sign == LV_SIGNAL_CHILD_CHG) { /*Automatically move children to the scrollable object*/
|
||||||
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) {
|
||||||
@@ -837,15 +839,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 {
|
||||||
|
|||||||
@@ -397,7 +397,7 @@ static bool lv_roller_design(lv_obj_t * roller, const lv_area_t * mask, lv_desig
|
|||||||
new_style.text.color = sel_style->text.color;
|
new_style.text.color = sel_style->text.color;
|
||||||
new_style.text.opa = sel_style->text.opa;
|
new_style.text.opa = sel_style->text.opa;
|
||||||
lv_draw_label(&ext->ddlist.label->coords, &mask_sel, &new_style, opa_scale,
|
lv_draw_label(&ext->ddlist.label->coords, &mask_sel, &new_style, opa_scale,
|
||||||
lv_label_get_text(ext->ddlist.label), txt_align, NULL, NULL, NULL);
|
lv_label_get_text(ext->ddlist.label), txt_align, NULL, NULL, NULL, lv_obj_get_base_dir(ext->ddlist.label));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
#include "../lv_core/lv_debug.h"
|
#include "../lv_core/lv_debug.h"
|
||||||
#include "../lv_core/lv_group.h"
|
#include "../lv_core/lv_group.h"
|
||||||
|
#include "../lv_core/lv_indev.h"
|
||||||
#include "../lv_draw/lv_draw.h"
|
#include "../lv_draw/lv_draw.h"
|
||||||
#include "../lv_themes/lv_theme.h"
|
#include "../lv_themes/lv_theme.h"
|
||||||
#include "../lv_misc/lv_math.h"
|
#include "../lv_misc/lv_math.h"
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
#include "../lv_core/lv_debug.h"
|
#include "../lv_core/lv_debug.h"
|
||||||
#include "../lv_themes/lv_theme.h"
|
#include "../lv_themes/lv_theme.h"
|
||||||
#include "../lv_misc/lv_math.h"
|
#include "../lv_misc/lv_math.h"
|
||||||
|
#include "../lv_core/lv_indev.h"
|
||||||
|
|
||||||
/*********************
|
/*********************
|
||||||
* DEFINES
|
* DEFINES
|
||||||
|
|||||||
@@ -1391,7 +1391,7 @@ static bool lv_ta_scrollable_design(lv_obj_t * scrl, const lv_area_t * mask, lv_
|
|||||||
|
|
||||||
cur_area.x1 += cur_style.body.padding.left;
|
cur_area.x1 += cur_style.body.padding.left;
|
||||||
cur_area.y1 += cur_style.body.padding.top;
|
cur_area.y1 += cur_style.body.padding.top;
|
||||||
lv_draw_label(&cur_area, mask, &cur_style, opa_scale, letter_buf, LV_TXT_FLAG_NONE, NULL, NULL, NULL);
|
lv_draw_label(&cur_area, mask, &cur_style, opa_scale, letter_buf, LV_TXT_FLAG_NONE, NULL, NULL, NULL, lv_obj_get_base_dir(ta));
|
||||||
|
|
||||||
} else if(ext->cursor.type == LV_CURSOR_OUTLINE) {
|
} else if(ext->cursor.type == LV_CURSOR_OUTLINE) {
|
||||||
cur_style.body.opa = LV_OPA_TRANSP;
|
cur_style.body.opa = LV_OPA_TRANSP;
|
||||||
@@ -1855,53 +1855,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->sel.start = index_of_char_at_position;
|
ext->sel.start = char_id_at_click;
|
||||||
ext->sel.end = LV_DRAW_LABEL_NO_TXT_SEL;
|
ext->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->sel.end = index_of_char_at_position;
|
ext->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->sel.start > ext->sel.end) {
|
if(ext->sel.start > ext->sel.end) {
|
||||||
if(ext_label->txt_sel_start != ext->sel.end || ext_label->txt_sel_end != ext->sel.start) {
|
if(ext_label->txt_sel_start != ext->sel.end || ext_label->txt_sel_end != ext->sel.start) {
|
||||||
ext_label->txt_sel_start = ext->sel.end;
|
ext_label->txt_sel_start = ext->sel.end;
|
||||||
@@ -1928,17 +1928,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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -151,14 +151,23 @@ void lv_table_set_cell_value(lv_obj_t * table, uint16_t row, uint16_t col, const
|
|||||||
}
|
}
|
||||||
/*Initialize the format byte*/
|
/*Initialize the format byte*/
|
||||||
else {
|
else {
|
||||||
format.s.align = LV_LABEL_ALIGN_LEFT;
|
#if LV_USE_BIDI
|
||||||
|
lv_bidi_dir_t base_dir = lv_obj_get_base_dir(table);
|
||||||
|
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);
|
||||||
|
#else
|
||||||
|
format.s.align = LV_LABEL_ALIGN_LEFT;
|
||||||
|
#endif
|
||||||
|
|
||||||
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*/
|
strcpy(ext->cell_data[cell] + 1, txt); /*+1 to skip the format byte*/
|
||||||
|
|
||||||
ext->cell_data[cell][0] = format.format_byte;
|
ext->cell_data[cell][0] = format.format_byte;
|
||||||
refr_size(table);
|
refr_size(table);
|
||||||
}
|
}
|
||||||
@@ -729,7 +738,7 @@ static bool lv_table_design(lv_obj_t * table, const lv_area_t * mask, lv_design_
|
|||||||
label_mask_ok = lv_area_intersect(&label_mask, mask, &cell_area);
|
label_mask_ok = lv_area_intersect(&label_mask, mask, &cell_area);
|
||||||
if(label_mask_ok) {
|
if(label_mask_ok) {
|
||||||
lv_draw_label(&txt_area, &label_mask, cell_style, opa_scale, ext->cell_data[cell] + 1,
|
lv_draw_label(&txt_area, &label_mask, cell_style, opa_scale, ext->cell_data[cell] + 1,
|
||||||
txt_flags, NULL, NULL, NULL);
|
txt_flags, NULL, NULL, NULL, lv_obj_get_base_dir(table));
|
||||||
}
|
}
|
||||||
/*Draw lines after '\n's*/
|
/*Draw lines after '\n's*/
|
||||||
lv_point_t p1;
|
lv_point_t p1;
|
||||||
|
|||||||
@@ -147,7 +147,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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -222,8 +222,8 @@ lv_obj_t * lv_tabview_add_tab(lv_obj_t * tabview, const char * name)
|
|||||||
lv_obj_t * h = lv_page_create(ext->content, NULL);
|
lv_obj_t * h = lv_page_create(ext->content, NULL);
|
||||||
lv_obj_set_size(h, lv_obj_get_width(tabview), lv_obj_get_height(ext->content));
|
lv_obj_set_size(h, lv_obj_get_width(tabview), lv_obj_get_height(ext->content));
|
||||||
lv_page_set_sb_mode(h, LV_SB_MODE_AUTO);
|
lv_page_set_sb_mode(h, LV_SB_MODE_AUTO);
|
||||||
lv_page_set_style(h, LV_PAGE_STYLE_BG, &lv_style_transp);
|
lv_page_set_style(h, LV_PAGE_STYLE_BG, &lv_style_transp_tight);
|
||||||
lv_page_set_style(h, LV_PAGE_STYLE_SCRL, &lv_style_transp);
|
lv_page_set_style(h, LV_PAGE_STYLE_SCRL, &lv_style_transp);//plain_color);
|
||||||
|
|
||||||
if(page_signal == NULL) page_signal = lv_obj_get_signal_cb(h);
|
if(page_signal == NULL) page_signal = lv_obj_get_signal_cb(h);
|
||||||
if(page_scrl_signal == NULL) page_scrl_signal = lv_obj_get_signal_cb(lv_page_get_scrl(h));
|
if(page_scrl_signal == NULL) page_scrl_signal = lv_obj_get_signal_cb(lv_page_get_scrl(h));
|
||||||
@@ -351,6 +351,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) {
|
||||||
@@ -910,7 +914,11 @@ static void tabpage_pressing_handler(lv_obj_t * tabview, lv_obj_t * tabpage)
|
|||||||
p = ((tabpage->coords.x1 - tabview->coords.x1) * (indic_size + tabs_style->body.padding.inner)) /
|
p = ((tabpage->coords.x1 - tabview->coords.x1) * (indic_size + tabs_style->body.padding.inner)) /
|
||||||
lv_obj_get_width(tabview);
|
lv_obj_get_width(tabview);
|
||||||
|
|
||||||
lv_obj_set_x(ext->indic, indic_size * ext->tab_cur + tabs_style->body.padding.inner * ext->tab_cur +
|
uint16_t id = ext->tab_cur;
|
||||||
|
if(lv_obj_get_base_dir(tabview) == LV_BIDI_DIR_RTL) {
|
||||||
|
id = (ext->tab_cnt - (id + 1));
|
||||||
|
}
|
||||||
|
lv_obj_set_x(ext->indic, indic_size * id + tabs_style->body.padding.inner * id +
|
||||||
indic_style->body.padding.left - p);
|
indic_style->body.padding.left - p);
|
||||||
break;
|
break;
|
||||||
case LV_TABVIEW_BTNS_POS_LEFT:
|
case LV_TABVIEW_BTNS_POS_LEFT:
|
||||||
@@ -953,13 +961,18 @@ static void tabpage_press_lost_handler(lv_obj_t * tabview, lv_obj_t * tabpage)
|
|||||||
lv_coord_t page_x2 = page_x1 + lv_obj_get_width(tabpage);
|
lv_coord_t page_x2 = page_x1 + lv_obj_get_width(tabpage);
|
||||||
lv_coord_t treshold = lv_obj_get_width(tabview) / 2;
|
lv_coord_t treshold = lv_obj_get_width(tabview) / 2;
|
||||||
|
|
||||||
uint16_t tab_cur = ext->tab_cur;
|
int16_t tab_cur = ext->tab_cur;
|
||||||
if(page_x1 > treshold) {
|
if(page_x1 > treshold) {
|
||||||
if(tab_cur != 0) tab_cur--;
|
if(lv_obj_get_base_dir(tabview) == LV_BIDI_DIR_RTL) tab_cur++;
|
||||||
|
else tab_cur--;
|
||||||
} else if(page_x2 < treshold) {
|
} else if(page_x2 < treshold) {
|
||||||
if(tab_cur < ext->tab_cnt - 1) tab_cur++;
|
if(lv_obj_get_base_dir(tabview) == LV_BIDI_DIR_RTL) tab_cur--;
|
||||||
|
else tab_cur++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(tab_cur > ext->tab_cnt - 1) tab_cur = ext->tab_cnt - 1;
|
||||||
|
else if(tab_cur < 0) tab_cur = 0;
|
||||||
|
|
||||||
uint32_t id_prev = lv_tabview_get_tab_act(tabview);
|
uint32_t id_prev = lv_tabview_get_tab_act(tabview);
|
||||||
lv_tabview_set_tab_act(tabview, tab_cur, LV_ANIM_ON);
|
lv_tabview_set_tab_act(tabview, tab_cur, LV_ANIM_ON);
|
||||||
uint32_t id_new = lv_tabview_get_tab_act(tabview);
|
uint32_t id_new = lv_tabview_get_tab_act(tabview);
|
||||||
|
|||||||
Reference in New Issue
Block a user