1
0
mirror of https://github.com/lvgl/lvgl.git synced 2025-01-28 07:03:00 +08:00

merge master

This commit is contained in:
Gabor Kiss-Vamosi 2020-12-28 13:08:26 +01:00
commit f0999ccbd4
32 changed files with 3082 additions and 318 deletions

8
.github/pull_request_template.md vendored Normal file
View File

@ -0,0 +1,8 @@
### Description of the feature or fix
A clear and concise description of what the bug or new feature is.
### Checkpoints
- [ ] Follow the [styling guide](https://github.com/lvgl/lvgl/blob/master/docs/CODING_STYLE.md)
- [ ] Update CHANGELOG.md
- [ ] Update the documentation

View File

@ -1,6 +1,27 @@
# Changelog
## v7.8.0 (Planned to 01.12.2020)
## v7.9.0
### New features
- feat(chart) add lv_chart_remove_series and lv_chart_hide_series
- feat(img_cahce) allow disabling image cacheing
- calendar: make get_day_of_week() public
### Bugfixes
- fix(draw_rect) free buffer used for arabic processing
- fix(win) arabic process the title of the window
- fix(dropdown) arabic process the option in lv_dropdown_add_option
- fix(textarea) buffer overflow in password mode with UTF-8 characters
- fix(textarea) cursor position after hiding character in password mode
- fix(linemeter) draw critical lines with correct color
## v7.8.1 (Plannad at 15.12.2020)
### Bugfixes
- fix(lv_scr_load_anim) fix when multiple screen are loaded at tsame time with delay
- fix(page) fix LV_SCOLLBAR_MODE_DRAG
## v7.8.0 (01.12.2020)
### New features
- make DMA2D non blocking

View File

@ -3,10 +3,30 @@ if(ESP_PLATFORM)
file(GLOB_RECURSE SOURCES src/*.c)
idf_component_register(SRCS ${SOURCES}
INCLUDE_DIRS . src)
INCLUDE_DIRS . src
REQUIRES main)
target_compile_definitions(${COMPONENT_LIB} PUBLIC "-DLV_CONF_INCLUDE_SIMPLE")
target_compile_definitions(${COMPONENT_LIB} PUBLIC "-DLV_CONF_SKIP")
if (CONFIG_LV_MEM_CUSTOM)
if (CONFIG_LV_MEM_CUSTOM_ALLOC)
target_compile_definitions(${COMPONENT_LIB} PUBLIC "-DLV_MEM_CUSTOM_ALLOC=${CONFIG_LV_MEM_CUSTOM_ALLOC}")
endif()
if (CONFIG_LV_MEM_CUSTOM_FREE)
target_compile_definitions(${COMPONENT_LIB} PUBLIC "-DLV_MEM_CUSTOM_FREE=${CONFIG_LV_MEM_CUSTOM_FREE}")
endif()
endif()
if (CONFIG_LV_TICK_CUSTOM)
if (CONFIG_LV_TICK_CUSTOM_SYS_TIME_EXPR)
target_compile_definitions(${COMPONENT_LIB} PUBLIC "-DLV_TICK_CUSTOM_SYS_TIME_EXPR=${CONFIG_LV_TICK_CUSTOM_SYS_TIME_EXPR}")
endif()
endif()
if (CONFIG_LV_USER_DATA_FREE)
target_compile_definitions(${COMPONENT_LIB} PUBLIC "-DLV_USER_DATA_FREE=${CONFIG_LV_USER_DATA_FREE}")
endif()
if (CONFIG_LV_ATTRIBUTE_FAST_MEM_USE_IRAM)
target_compile_definitions(${COMPONENT_LIB} PUBLIC "-DLV_ATTRIBUTE_FAST_MEM=IRAM_ATTR")

62
Kconfig
View File

@ -1,4 +1,4 @@
# Kconfig file for LVGL v7.7.1
# Kconfig file for LVGL v7.8.1
menu "LVGL configuration"
@ -105,11 +105,38 @@ menu "LVGL configuration"
displays.
menu "Memory manager settings"
config LV_MEM_CUSTOM
bool
prompt "If true use custom malloc/free, otherwise use the built-in `lv_mem_alloc` and `lv_mem_free`"
config LV_MEM_CUSTOM_INCLUDE
string
prompt "Header to include for the custom memory function"
default stdlib.h
depends on LV_MEM_CUSTOM
config LV_MEM_CUSTOM_ALLOC
string
prompt "Wrapper to malloc"
default malloc
depends on LV_MEM_CUSTOM
config LV_MEM_CUSTOM_FREE
string
prompt "Wrapper to free"
default free
depends on LV_MEM_CUSTOM
config LV_MEM_SIZE_BYTES
int
prompt "Size of the memory used by `lv_mem_alloc` in kilobytes (>= 2kB)"
range 2 128
default 32
default 32
depends on !LV_MEM_CUSTOM
config LV_MEMCPY_MEMSET_STD
bool
prompt "Use the standard memcpy and memset instead of LVGL's own functions"
endmenu
menu "Indev device settings"
@ -204,6 +231,17 @@ menu "LVGL configuration"
default y if !LV_CONF_MINIMAL
config LV_USE_USER_DATA
bool "Add a 'user_data' to drivers and objects."
config LV_USE_USER_DATA_FREE
bool "Free the user data field upon object deletion"
depends on LV_USE_USER_DATA
config LV_USER_DATA_FREE_INCLUDE
string "Header for user data free function"
default "something.h"
depends on LV_USE_USER_DATA_FREE
config LV_USER_DATA_FREE
string "Invoking for user data free function. It has the lv_obj_t pointer as single parameter."
default "(user_data_free)"
depends on LV_USE_USER_DATA_FREE
config LV_USE_PERF_MONITOR
bool "Show CPU usage and FPS count in the right bottom corner."
config LV_USE_API_EXTENSION_V6
@ -235,11 +273,29 @@ menu "LVGL configuration"
LV_IMG_CACHE_DEF_SIZE must be >= 1
endmenu
menu "Compiler settings"
menu "Compiler Settings"
config LV_BIG_ENDIAN_SYSTEM
bool "For big endian systems set to 1"
endmenu
menu "HAL Settings"
config LV_TICK_CUSTOM
bool
prompt "Use a custom tick source"
config LV_TICK_CUSTOM_INCLUDE
string
prompt "Header for the system time function"
default Arduino.h
depends on LV_TICK_CUSTOM
config LV_TICK_CUSTOM_SYS_TIME_EXPR
string
prompt "Expression evaluating to current system time in ms"
default "(millis())"
depends on LV_TICK_CUSTOM
endmenu
menu "Log Settings"
config LV_USE_LOG
bool "Enable the log module"

View File

@ -244,7 +244,7 @@ typedef void * lv_fs_drv_user_data_t;
* (I.e. no new image decoder is added)
* With complex image decoders (e.g. PNG or JPG) caching can save the continuous open/decode of images.
* However the opened images might consume additional RAM.
* LV_IMG_CACHE_DEF_SIZE must be >= 1 */
* Set it to 0 to disable caching */
#define LV_IMG_CACHE_DEF_SIZE 1
/*Declare the type of the user data of image decoder (can be e.g. `void *`, `int`, `struct`)*/

View File

@ -85,10 +85,10 @@ def update_version(ver):
templ = fnmatch.filter(os.listdir('.'), '*_templ*.h')
if len(templ) > 0 and templ[0]:
if len(templ) > 0 and templ[0]:
print("Updating version in " + templ[0])
cmd("sed -i -r 's/v[0-9]+\.[0-9]+\.[0-9]+/"+ "v" + ver_num + "/' " + templ[0])
cmd("sed -i -r 's/v[0-9]+\.[0-9]+\.[0-9]+.*/"+ "v" + ver_num + "/' " + templ[0])
if os.path.exists("library.json"):
print("Updating version in library.json")
cmd("sed -i -r 's/[0-9]+\.[0-9]+\.[0-9]+/"+ ver_num +"/' library.json")
@ -100,6 +100,9 @@ def update_version(ver):
if path.exists("conf.py"):
cmd("sed -i -r \"s/'v[0-9]+\.[0-9]+\.[0-9]+.*'/\'" + ver_str + "'/\" conf.py")
if path.exists("Kconfig"):
cmd("sed -i -r \"s/'v[0-9]+\.[0-9]+\.[0-9]+.*'/\'" + ver_str + "'/\" Kconfig")
if path.exists("lvgl.h"):
define_set("./lvgl.h", "LVGL_VERSION_MAJOR", str(ver[0]))
define_set("./lvgl.h", "LVGL_VERSION_MINOR", str(ver[1]))

View File

@ -55,7 +55,7 @@ if __name__ == '__main__':
print("Invalid argument. Usage ./release.py bugfix | minor | major")
exit(1)
os.chdir(workdir)
#os.chdir(workdir)
clone_repos()
release.make()
for p in proj_list:

View File

@ -201,7 +201,7 @@
# endif
#endif
/* Complier prefix for a big array declaration */
/* Compiler prefix for a big array declaration */
#ifndef LV_MEM_ATTR
# ifdef CONFIG_LV_MEM_ATTR
# define LV_MEM_ATTR CONFIG_LV_MEM_ATTR
@ -330,7 +330,7 @@
#endif
/* Long press time in milliseconds.
* Time to send `LV_EVENT_LONG_PRESSSED`) */
* Time to send `LV_EVENT_LONG_PRESSED`) */
#ifndef LV_INDEV_DEF_LONG_PRESS_TIME
# ifdef CONFIG_LV_INDEV_DEF_LONG_PRESS_TIME
# define LV_INDEV_DEF_LONG_PRESS_TIME CONFIG_LV_INDEV_DEF_LONG_PRESS_TIME
@ -1312,7 +1312,7 @@ e.g. "stm32f769xx.h" or "stm32f429xx.h" */
/* Support bidirectional texts.
* Allows mixing Left-to-Right and Right-to-Left texts.
* The direction will be processed according to the Unicode Bidirectioanl Algorithm:
* The direction will be processed according to the Unicode Bidirectional Algorithm:
* https://www.w3.org/International/articles/inline-bidi-markup/uba-basics*/
#ifndef LV_USE_BIDI
# ifdef CONFIG_LV_USE_BIDI

View File

@ -195,6 +195,20 @@ void lv_disp_set_bg_opa(lv_disp_t * disp, lv_opa_t opa)
void lv_scr_load_anim(lv_obj_t * new_scr, lv_scr_load_anim_t anim_type, uint32_t time, uint32_t delay, bool auto_del)
{
lv_disp_t * d = lv_obj_get_disp(new_scr);
lv_obj_t * act_scr = lv_scr_act();
if(d->del_prev && act_scr != d->scr_to_load) {
lv_obj_del(act_scr);
lv_disp_load_scr(d->scr_to_load);
lv_anim_del(d->scr_to_load, NULL);
lv_obj_set_pos(d->scr_to_load, 0, 0);
lv_style_remove_prop(lv_obj_get_local_style(d->scr_to_load, LV_OBJ_PART_MAIN), LV_STYLE_OPA_SCALE);
act_scr = d->scr_to_load;
}
d->scr_to_load = new_scr;
if(d->prev_scr && d->del_prev) {
lv_obj_del(d->prev_scr);
@ -377,13 +391,13 @@ static void opa_scale_anim(lv_obj_t * obj, lv_anim_value_t v)
// lv_obj_set_style_bg_color(obj, LV_PART_MAIN, LV_STATE_DEFAULT, v);
}
static void scr_anim_ready(lv_anim_t * a)
{
lv_disp_t * d = lv_obj_get_disp(a->var);
if(d->prev_scr && d->del_prev) lv_obj_del(d->prev_scr);
d->prev_scr = NULL;
d->scr_to_load = NULL;
lv_style_remove_prop(lv_obj_get_local_style(a->var, LV_PART_MAIN, LV_STATE_DEFAULT), LV_STYLE_OPA);
}
#endif

View File

@ -165,8 +165,9 @@ void lv_init(void)
_lv_indev_init();
_lv_img_decoder_init();
#if LV_IMG_CACHE_DEF_SIZE
lv_img_cache_set_size(LV_IMG_CACHE_DEF_SIZE);
#endif
/*Test if the IDE has UTF-8 encoding*/
char * txt = "Á";

View File

@ -40,6 +40,7 @@ LV_ATTRIBUTE_FAST_MEM static void lv_draw_map(const lv_area_t * map_area, const
bool chroma_key, bool alpha_byte);
static void show_error(const lv_area_t * coords, const lv_area_t * clip_area, const char * msg);
static void draw_cleanup(lv_img_cache_entry_t * cache);
/**********************
* STATIC VARIABLES
@ -267,9 +268,10 @@ LV_ATTRIBUTE_FAST_MEM static lv_res_t lv_img_draw_core(const lv_area_t * coords,
lv_area_t mask_com; /*Common area of mask and coords*/
bool union_ok;
union_ok = _lv_area_intersect(&mask_com, clip_area, &map_area_rot);
/*Out of mask. There is nothing to draw so the image is drawn successfully.*/
if(union_ok == false) {
return LV_RES_OK; /*Out of mask. There is nothing to draw so the image is drawn
successfully.*/
draw_cleanup(cdsc);
return LV_RES_OK;
}
lv_draw_map(coords, &mask_com, cdsc->dec_dsc.img_data, draw_dsc, chroma_keyed, alpha_byte);
@ -279,9 +281,10 @@ LV_ATTRIBUTE_FAST_MEM static lv_res_t lv_img_draw_core(const lv_area_t * coords,
lv_area_t mask_com; /*Common area of mask and coords*/
bool union_ok;
union_ok = _lv_area_intersect(&mask_com, clip_area, coords);
/*Out of mask. There is nothing to draw so the image is drawn successfully.*/
if(union_ok == false) {
return LV_RES_OK; /*Out of mask. There is nothing to draw so the image is drawn
successfully.*/
draw_cleanup(cdsc);
return LV_RES_OK;
}
int32_t width = lv_area_get_width(&mask_com);
@ -306,6 +309,7 @@ LV_ATTRIBUTE_FAST_MEM static lv_res_t lv_img_draw_core(const lv_area_t * coords,
lv_img_decoder_close(&cdsc->dec_dsc);
LV_LOG_WARN("Image draw can't read the line");
_lv_mem_buf_release(buf);
draw_cleanup(cdsc);
return LV_RES_INV;
}
@ -318,6 +322,7 @@ LV_ATTRIBUTE_FAST_MEM static lv_res_t lv_img_draw_core(const lv_area_t * coords,
_lv_mem_buf_release(buf);
}
draw_cleanup(cdsc);
return LV_RES_OK;
}
@ -649,3 +654,13 @@ static void show_error(const lv_area_t * coords, const lv_area_t * clip_area, co
lv_draw_label(coords, clip_area, &label_dsc, msg, NULL);
}
static void draw_cleanup(lv_img_cache_entry_t * cache)
{
/*Automatically close images with no caching*/
#if LV_IMG_CACHE_DEF_SIZE == 0
lv_img_decoder_close(&cache->dec_dsc);
#else
LV_UNUSED(cache);
#endif
}

View File

@ -1241,6 +1241,10 @@ static void draw_content(const lv_area_t * coords, const lv_area_t * clip, const
if(src_type == LV_IMG_SRC_SYMBOL) lv_draw_label(&coords_tmp, clip, &label_dsc, dsc->content_src, NULL);
else lv_draw_img(&coords_tmp, clip, dsc->content_src, &img_dsc);
#if LV_USE_ARABIC_PERSIAN_CHARS
_lv_mem_buf_release(str);
#endif
}
#endif

View File

@ -19,7 +19,7 @@
/*********************
* DEFINES
*********************/
/*Decrement life with this value in every open*/
/*Decrement life with this value on every open*/
#define LV_IMG_CACHE_AGING 1
/*Boost life by this factor (multiply time_to_open with this value)*/
@ -29,10 +29,6 @@
* "die" from very high values */
#define LV_IMG_CACHE_LIFE_LIMIT 1000
#if LV_IMG_CACHE_DEF_SIZE < 1
#error "LV_IMG_CACHE_DEF_SIZE must be >= 1. See lv_conf.h"
#endif
/**********************
* TYPEDEFS
**********************/
@ -40,11 +36,16 @@
/**********************
* STATIC PROTOTYPES
**********************/
#if LV_IMG_CACHE_DEF_SIZE == 0
static lv_img_cache_entry_t cache_temp;
#endif
/**********************
* STATIC VARIABLES
**********************/
#if LV_IMG_CACHE_DEF_SIZE
static uint16_t entry_cnt;
#endif
/**********************
* MACROS
@ -64,6 +65,10 @@ static uint16_t entry_cnt;
*/
lv_img_cache_entry_t * _lv_img_cache_open(const void * src, lv_color_t color)
{
/*Is the image cached?*/
lv_img_cache_entry_t * cached_src = NULL;
#if LV_IMG_CACHE_DEF_SIZE
if(entry_cnt == 0) {
LV_LOG_WARN("lv_img_cache_open: the cache size is 0");
return NULL;
@ -79,8 +84,6 @@ lv_img_cache_entry_t * _lv_img_cache_open(const void * src, lv_color_t color)
}
}
/*Is the image cached?*/
lv_img_cache_entry_t * cached_src = NULL;
for(i = 0; i < entry_cnt; i++) {
bool match = false;
lv_img_src_t src_type = lv_img_src_get_type(cache[i].dec_dsc.src);
@ -104,48 +107,51 @@ lv_img_cache_entry_t * _lv_img_cache_open(const void * src, lv_color_t color)
}
/*The image is not cached then cache it now*/
if(cached_src == NULL) {
/*Find an entry to reuse. Select the entry with the least life*/
cached_src = &cache[0];
for(i = 1; i < entry_cnt; i++) {
if(cache[i].life < cached_src->life) {
cached_src = &cache[i];
}
}
if(cached_src) return cached_src;
/*Close the decoder to reuse if it was opened (has a valid source)*/
if(cached_src->dec_dsc.src) {
lv_img_decoder_close(&cached_src->dec_dsc);
LV_LOG_INFO("image draw: cache miss, close and reuse an entry");
/*Find an entry to reuse. Select the entry with the least life*/
cached_src = &cache[0];
for(i = 1; i < entry_cnt; i++) {
if(cache[i].life < cached_src->life) {
cached_src = &cache[i];
}
else {
LV_LOG_INFO("image draw: cache miss, cached to an empty entry");
}
/*Open the image and measure the time to open*/
uint32_t t_start;
t_start = lv_tick_get();
cached_src->dec_dsc.time_to_open = 0;
lv_res_t open_res = lv_img_decoder_open(&cached_src->dec_dsc, src, color);
if(open_res == LV_RES_INV) {
LV_LOG_WARN("Image draw cannot open the image resource");
lv_img_decoder_close(&cached_src->dec_dsc);
_lv_memset_00(&cached_src->dec_dsc, sizeof(lv_img_decoder_dsc_t));
_lv_memset_00(cached_src, sizeof(lv_img_cache_entry_t));
cached_src->life = INT32_MIN; /*Make the empty entry very "weak" to force its use */
return NULL;
}
cached_src->life = 0;
/*If `time_to_open` was not set in the open function set it here*/
if(cached_src->dec_dsc.time_to_open == 0) {
cached_src->dec_dsc.time_to_open = lv_tick_elaps(t_start);
}
if(cached_src->dec_dsc.time_to_open == 0) cached_src->dec_dsc.time_to_open = 1;
}
/*Close the decoder to reuse if it was opened (has a valid source)*/
if(cached_src->dec_dsc.src) {
lv_img_decoder_close(&cached_src->dec_dsc);
LV_LOG_INFO("image draw: cache miss, close and reuse an entry");
}
else {
LV_LOG_INFO("image draw: cache miss, cached to an empty entry");
}
#else
cached_src = &cache_temp;
#endif
/*Open the image and measure the time to open*/
uint32_t t_start;
t_start = lv_tick_get();
cached_src->dec_dsc.time_to_open = 0;
lv_res_t open_res = lv_img_decoder_open(&cached_src->dec_dsc, src, color);
if(open_res == LV_RES_INV) {
LV_LOG_WARN("Image draw cannot open the image resource");
lv_img_decoder_close(&cached_src->dec_dsc);
_lv_memset_00(&cached_src->dec_dsc, sizeof(lv_img_decoder_dsc_t));
_lv_memset_00(cached_src, sizeof(lv_img_cache_entry_t));
cached_src->life = INT32_MIN; /*Make the empty entry very "weak" to force its use */
return NULL;
}
cached_src->life = 0;
/*If `time_to_open` was not set in the open function set it here*/
if(cached_src->dec_dsc.time_to_open == 0) {
cached_src->dec_dsc.time_to_open = lv_tick_elaps(t_start);
}
if(cached_src->dec_dsc.time_to_open == 0) cached_src->dec_dsc.time_to_open = 1;
return cached_src;
}
@ -157,6 +163,10 @@ lv_img_cache_entry_t * _lv_img_cache_open(const void * src, lv_color_t color)
*/
void lv_img_cache_set_size(uint16_t new_entry_cnt)
{
#if LV_IMG_CACHE_DEF_SIZE == 0
LV_UNUSED(new_entry_cnt);
LV_LOG_WARN("Can't change cache size because it's disabled by LV_IMG_CACHE_DEF_SIZE = 0");
#else
if(LV_GC_ROOT(_lv_img_cache_array) != NULL) {
/*Clean the cache before free it*/
lv_img_cache_invalidate_src(NULL);
@ -178,6 +188,7 @@ void lv_img_cache_set_size(uint16_t new_entry_cnt)
_lv_memset_00(&LV_GC_ROOT(_lv_img_cache_array)[i].dec_dsc, sizeof(lv_img_decoder_dsc_t));
_lv_memset_00(&LV_GC_ROOT(_lv_img_cache_array)[i], sizeof(lv_img_cache_entry_t));
}
#endif
}
/**
@ -187,7 +198,7 @@ void lv_img_cache_set_size(uint16_t new_entry_cnt)
*/
void lv_img_cache_invalidate_src(const void * src)
{
#if LV_IMG_CACHE_DEF_SIZE
lv_img_cache_entry_t * cache = LV_GC_ROOT(_lv_img_cache_array);
uint16_t i;
@ -201,6 +212,7 @@ void lv_img_cache_invalidate_src(const void * src)
_lv_memset_00(&cache[i], sizeof(lv_img_cache_entry_t));
}
}
#endif
}
/**********************

View File

@ -56,7 +56,7 @@
#define PXP_OUT_PIXEL_FORMAT kPXP_OutputPixelFormatRGB565
#define PXP_AS_PIXEL_FORMAT kPXP_AsPixelFormatRGB565
#define PXP_PS_PIXEL_FORMAT kPXP_PsPixelFormatRGB565
#elif
#else
#error Only 16bit color depth is supported. Set LV_COLOR_DEPTH to 16.
#endif

View File

@ -155,6 +155,9 @@ typedef struct _disp_t {
struct _lv_obj_t ** screens; /**< Array of screen objects. `NULL` terminated*/
struct _lv_obj_t * act_scr; /**< Currently active screen on this display */
struct _lv_obj_t * prev_scr; /**< Previous screen. Used during screen animations */
#if LV_USE_ANIMATION
struct _lv_obj_t * scr_to_load; /**< The screen prepared to load in lv_scr_load_anim*/
#endif
struct _lv_obj_t * top_layer; /**< @see lv_disp_get_layer_top */
struct _lv_obj_t * sys_layer; /**< @see lv_disp_get_layer_sys */
uint32_t screen_cnt;

View File

@ -8,6 +8,7 @@
*********************/
#include <stdarg.h>
#include "lv_txt.h"
#include "lv_txt_ap.h"
#include "lv_math.h"
#include "lv_log.h"
#include "lv_debug.h"
@ -793,7 +794,7 @@ static uint8_t lv_txt_iso8859_1_size(const char * str)
*/
static uint32_t lv_txt_unicode_to_iso8859_1(uint32_t letter_uni)
{
if(letter_uni < 128)
if(letter_uni < 256)
return letter_uni;
else
return ' ';

View File

@ -16,6 +16,7 @@ extern "C" {
#include "../lv_conf_internal.h"
#include <stdbool.h>
#include <stdarg.h>
#include "lv_area.h"
#include "lv_area.h"
#include "../lv_font/lv_font.h"

View File

@ -69,7 +69,7 @@ const ap_chars_map_t ap_chars_map[] = {
{36, 0xFEE6, 1, 2, -1, {1, 1}}, // ن
{38, 0xFEEE, -1, 0, -1, {1, 0}}, // و
{37, 0xFEEA, 1, 2, -1, {1, 1}}, // ه
{39, 0xFBFD, 1, 2, -1, {1, 1}}, // ي
{39, 0xFEF0, 0, 0, -1, {1, 0}}, // ى
{40, 0xFEF2, 1, 2, -1, {1, 1}}, // ي
{170, 0xFBFD, 1, 2, -1, {1, 1}}, // ی
{7, 0xFE94, 1, 2, -1, {1, 0}}, // ة

File diff suppressed because it is too large Load Diff

1090
src/lv_widgets/lv_calendar.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,208 @@
/**
* @file lv_calendar.h
*
*/
#ifndef LV_CALENDAR_H
#define LV_CALENDAR_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
#include "../lv_conf_internal.h"
#if LV_USE_CALENDAR != 0
#include "../lv_core/lv_obj.h"
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**
* Represents a date on the calendar object (platform-agnostic).
*/
typedef struct {
uint16_t year;
int8_t month;
int8_t day;
} lv_calendar_date_t;
/*Data of calendar*/
typedef struct {
/*None*/ /*Ext. of ancestor*/
/*New data for this type */
lv_calendar_date_t today; /*Date of today*/
lv_calendar_date_t showed_date; /*Currently visible month (day is ignored)*/
lv_calendar_date_t * highlighted_dates; /*Apply different style on these days (pointer to an
array defined by the user)*/
int8_t btn_pressing; /*-1: prev month pressing, +1 next month pressing on the header*/
uint16_t highlighted_dates_num; /*Number of elements in `highlighted_days`*/
lv_calendar_date_t pressed_date;
const char ** day_names; /*Pointer to an array with the name of the days (NULL: use default names)*/
const char ** month_names; /*Pointer to an array with the name of the month (NULL. use default names)*/
/*Styles*/
lv_style_list_t style_header;
lv_style_list_t style_day_names;
lv_style_list_t style_date_nums;
} lv_calendar_ext_t;
/** Calendar parts*/
enum {
LV_CALENDAR_PART_BG, /**< Background and "normal" date numbers style */
LV_CALENDAR_PART_HEADER, /** Calendar header style */
LV_CALENDAR_PART_DAY_NAMES, /** Day name style */
LV_CALENDAR_PART_DATE, /** Day name style */
};
typedef uint8_t lv_calendar_part_t;
/**********************
* GLOBAL PROTOTYPES
**********************/
/**
* Create a calendar objects
* @param par pointer to an object, it will be the parent of the new calendar
* @param copy pointer to a calendar object, if not NULL then the new object will be copied from it
* @return pointer to the created calendar
*/
lv_obj_t * lv_calendar_create(lv_obj_t * par, const lv_obj_t * copy);
/*======================
* Add/remove functions
*=====================*/
/*=====================
* Setter functions
*====================*/
/**
* Set the today's date
* @param calendar pointer to a calendar object
* @param today pointer to an `lv_calendar_date_t` variable containing the date of today. The value
* will be saved it can be local variable too.
*/
void lv_calendar_set_today_date(lv_obj_t * calendar, lv_calendar_date_t * today);
/**
* Set the currently showed
* @param calendar pointer to a calendar object
* @param showed pointer to an `lv_calendar_date_t` variable containing the date to show. The value
* will be saved it can be local variable too.
*/
void lv_calendar_set_showed_date(lv_obj_t * calendar, lv_calendar_date_t * showed);
/**
* Set the the highlighted dates
* @param calendar pointer to a calendar object
* @param highlighted pointer to an `lv_calendar_date_t` array containing the dates. ONLY A POINTER
* WILL BE SAVED! CAN'T BE LOCAL ARRAY.
* @param date_num number of dates in the array
*/
void lv_calendar_set_highlighted_dates(lv_obj_t * calendar, lv_calendar_date_t highlighted[], uint16_t date_num);
/**
* Set the name of the days
* @param calendar pointer to a calendar object
* @param day_names pointer to an array with the names. E.g. `const char * days[7] = {"Sun", "Mon",
* ...}` Only the pointer will be saved so this variable can't be local which will be destroyed
* later.
*/
void lv_calendar_set_day_names(lv_obj_t * calendar, const char ** day_names);
/**
* Set the name of the month
* @param calendar pointer to a calendar object
* @param month_names pointer to an array with the names. E.g. `const char * days[12] = {"Jan", "Feb",
* ...}` Only the pointer will be saved so this variable can't be local which will be destroyed
* later.
*/
void lv_calendar_set_month_names(lv_obj_t * calendar, const char ** month_names);
/*=====================
* Getter functions
*====================*/
/**
* Get the today's date
* @param calendar pointer to a calendar object
* @return return pointer to an `lv_calendar_date_t` variable containing the date of today.
*/
lv_calendar_date_t * lv_calendar_get_today_date(const lv_obj_t * calendar);
/**
* Get the currently showed
* @param calendar pointer to a calendar object
* @return pointer to an `lv_calendar_date_t` variable containing the date is being shown.
*/
lv_calendar_date_t * lv_calendar_get_showed_date(const lv_obj_t * calendar);
/**
* Get the the pressed date.
* @param calendar pointer to a calendar object
* @return pointer to an `lv_calendar_date_t` variable containing the pressed date.
* `NULL` if not date pressed (e.g. the header)
*/
lv_calendar_date_t * lv_calendar_get_pressed_date(const lv_obj_t * calendar);
/**
* Get the the highlighted dates
* @param calendar pointer to a calendar object
* @return pointer to an `lv_calendar_date_t` array containing the dates.
*/
lv_calendar_date_t * lv_calendar_get_highlighted_dates(const lv_obj_t * calendar);
/**
* Get the number of the highlighted dates
* @param calendar pointer to a calendar object
* @return number of highlighted days
*/
uint16_t lv_calendar_get_highlighted_dates_num(const lv_obj_t * calendar);
/**
* Get the name of the days
* @param calendar pointer to a calendar object
* @return pointer to the array of day names
*/
const char ** lv_calendar_get_day_names(const lv_obj_t * calendar);
/**
* Get the name of the month
* @param calendar pointer to a calendar object
* @return pointer to the array of month names
*/
const char ** lv_calendar_get_month_names(const lv_obj_t * calendar);
/**
* Get the day of the week
* @param year a year
* @param month a month (1..12)
* @param day a day (1..31)
* @return [0..6] which means [Sun..Sat] or [Mon..Sun] depending on LV_CALENDAR_WEEK_STARTS_MONDAY
*/
uint8_t lv_calendar_get_day_of_week(uint32_t year, uint32_t month, uint32_t day);
/*=====================
* Other functions
*====================*/
/**********************
* MACROS
**********************/
#endif /*LV_USE_CALENDAR*/
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /*LV_CALENDAR_H*/

View File

@ -136,6 +136,7 @@ lv_chart_series_t * lv_chart_add_series(lv_obj_t * obj, lv_color_t color)
ser->start_point = 0;
ser->ext_buf_assigned = false;
ser->hidden = 0;
ser->y_axis = LV_CHART_AXIS_PRIMARY_Y;
uint16_t i;
@ -148,6 +149,32 @@ lv_chart_series_t * lv_chart_add_series(lv_obj_t * obj, lv_color_t color)
return ser;
}
/**
* Deallocate and remove a data series from a chart
* @param chart pointer to a chart object
* @param series pointer to a data series on 'chart'
*/
void lv_chart_remove_series(lv_obj_t * obj, lv_chart_series_t * series)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
LV_ASSERT_NULL(series);
lv_chart_t * chart = (lv_chart_t *)obj;
if(!series->ext_buf_assigned && series->points) lv_mem_free(series->points);
_lv_ll_remove(&chart->series_ll, series);
lv_mem_free(series);
return;
}
/**
* Add a cursor with a given color
* @param chart pointer to chart object
* @param color color of the cursor
* @param dir direction of the cursor. `LV_CHART_CURSOR_RIGHT/LEFT/TOP/DOWN`. OR-ed values are possible
* @return pointer to the created cursor
*/
lv_chart_cursor_t * lv_chart_add_cursor(lv_obj_t * obj, lv_color_t color, lv_cursor_direction_t axes)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
@ -185,6 +212,22 @@ void lv_chart_clear_series(lv_obj_t * obj, lv_chart_series_t * series)
series->start_point = 0;
}
/**
* Hide/Unhide a single series of a chart.
* @param chart pointer to a chart object.
* @param series pointer to a series object
* @param hide true: hide the series
*/
void lv_chart_hide_series(lv_obj_t * chart, lv_chart_series_t * series, bool hide)
{
LV_ASSERT_OBJ(chart, LV_OBJX_NAME);
LV_ASSERT_NULL(series);
series->hidden = hide ? 1 : 0;
lv_chart_refresh(chart);
}
/*=====================
* Setter functions
*====================*/
@ -228,7 +271,7 @@ void lv_chart_set_y_range(lv_obj_t * obj, lv_chart_axis_t axis, lv_coord_t ymin,
if(chart->ymin[axis] == ymin && chart->ymax[axis] == ymax) return;
chart->ymin[axis] = ymin;
chart->ymax[axis] = ymax;
chart->ymax[axis] = (ymax == ymin ? ymax + 1 : ymax);;
lv_chart_refresh(obj);
}
@ -600,6 +643,7 @@ void lv_chart_set_cursor_point(lv_obj_t * obj, lv_chart_cursor_t * cursor, lv_po
lv_chart_refresh(obj);
}
/*=====================
* Getter functions
*====================*/
@ -1074,6 +1118,7 @@ static void draw_series_line(lv_obj_t * obj, const lv_area_t * clip_area)
/*Go through all data lines*/
_LV_LL_READ_BACK(&chart->series_ll, ser) {
if (ser->hidden) continue;
line_dsc.color = ser->color;
point_dsc.bg_color = ser->color;
area_dsc.bg_color = ser->color;
@ -1213,6 +1258,7 @@ static void draw_series_column(lv_obj_t * obj, const lv_area_t * clip_area)
/*Draw the current point of all data line*/
_LV_LL_READ_BACK(&chart->series_ll, ser) {
if (ser->hidden) continue;
lv_coord_t start_point = chart->update_mode == LV_CHART_UPDATE_MODE_SHIFT ? ser->start_point : 0;
col_a.x1 = x_act;

View File

@ -71,6 +71,7 @@ typedef struct {
lv_color_t color;
uint16_t start_point;
uint8_t ext_buf_assigned : 1;
uint8_t hidden : 1;
lv_chart_axis_t y_axis : 1;
} lv_chart_series_t;
@ -152,6 +153,13 @@ lv_obj_t * lv_chart_create(lv_obj_t * par, const lv_obj_t * copy);
*/
lv_chart_series_t * lv_chart_add_series(lv_obj_t * chart, lv_color_t color);
/**
* Deallocate and remove a data series from a chart
* @param chart pointer to a chart object
* @param series pointer to a data series on 'chart'
*/
void lv_chart_remove_series(lv_obj_t * chart, lv_chart_series_t * series);
/**
* Add a cursor with a given color
* @param chart pointer to chart object
@ -168,6 +176,15 @@ lv_chart_cursor_t * lv_chart_add_cursor(lv_obj_t * chart, lv_color_t color, lv_c
*/
void lv_chart_clear_series(lv_obj_t * chart, lv_chart_series_t * series);
/**
* Hide/Unhide a single series of a chart.
* @param chart pointer to a chart object.
* @param series pointer to a series object
* @param hide true: hide the series
*/
void lv_chart_hide_series(lv_obj_t * chart, lv_chart_series_t * series, bool hide);
/*=====================
* Setter functions
*====================*/

View File

@ -1,223 +0,0 @@
/**
* @file lv_cont.h
*
*/
#ifndef LV_CONT_H
#define LV_CONT_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
#include "../lv_conf_internal.h"
#if LV_USE_CONT != 0
#include "../lv_core/lv_obj.h"
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/** Container layout options*/
enum {
LV_LAYOUT_OFF = 0, /**< No layout */
LV_LAYOUT_CENTER, /**< Center objects */
/**
* COLUMN:
* - Place the object below each other
* - Keep `pad_top` space on the top
* - Keep `pad_inner` space between the objects
*/
LV_LAYOUT_COLUMN_LEFT, /**< Column left align*/
LV_LAYOUT_COLUMN_MID, /**< Column middle align*/
LV_LAYOUT_COLUMN_RIGHT, /**< Column right align*/
/**
* ROW:
* - Place the object next to each other
* - Keep `pad_left` space on the left
* - Keep `pad_inner` space between the objects
* - If the object which applies the layout has `base_dir == LV_BIDI_DIR_RTL`
* the row will start from the right applying `pad.right` space
*/
LV_LAYOUT_ROW_TOP, /**< Row top align*/
LV_LAYOUT_ROW_MID, /**< Row middle align*/
LV_LAYOUT_ROW_BOTTOM, /**< Row bottom align*/
/**
* PRETTY:
* - Place the object next to each other
* - If there is no more space start a new row
* - Respect `pad_left` and `pad_right` when determining the available space in a row
* - Keep `pad_inner` space between the objects in the same row
* - Keep `pad_inner` space between the objects in rows
* - Divide the remaining horizontal space equally
*/
LV_LAYOUT_PRETTY_TOP, /**< Row top align*/
LV_LAYOUT_PRETTY_MID, /**< Row middle align*/
LV_LAYOUT_PRETTY_BOTTOM, /**< Row bottom align*/
/**
* GRID
* - Place the object next to each other
* - If there is no more space start a new row
* - Respect `pad_left` and `pad_right` when determining the available space in a row
* - Keep `pad_inner` space between the objects in the same row
* - Keep `pad_inner` space between the objects in rows
* - Unlike `PRETTY`, `GRID` always keep `pad_inner` space horizontally between objects
* so it doesn't divide the remaining horizontal space equally
*/
LV_LAYOUT_GRID, /**< Align same-sized object into a grid*/
_LV_LAYOUT_LAST
};
typedef uint8_t lv_layout_t;
/**
* How to resize the container around the children.
*/
enum {
LV_FIT_NONE, /**< Do not change the size automatically*/
LV_FIT_TIGHT, /**< Shrink wrap around the children */
LV_FIT_PARENT, /**< Align the size to the parent's edge*/
LV_FIT_MAX, /**< Align the size to the parent's edge first but if there is an object out of it
then get larger */
_LV_FIT_LAST
};
typedef uint8_t lv_fit_t;
typedef struct {
/*Inherited from 'base_obj' so no inherited ext. */ /*Ext. of ancestor*/
/*New data for this type */
lv_layout_t layout : 4; /*A layout from 'lv_layout_t' enum*/
lv_fit_t fit_left : 2; /*A fit type from `lv_fit_t` enum */
lv_fit_t fit_right : 2; /*A fit type from `lv_fit_t` enum */
lv_fit_t fit_top : 2; /*A fit type from `lv_fit_t` enum */
lv_fit_t fit_bottom : 2; /*A fit type from `lv_fit_t` enum */
} lv_cont_ext_t;
/*Part of the container*/
enum {
LV_CONT_PART_MAIN = LV_OBJ_PART_MAIN,
_LV_CONT_PART_VIRTUAL_LAST = _LV_OBJ_PART_VIRTUAL_LAST,
_LV_CONT_PART_REAL_LAST = _LV_OBJ_PART_REAL_LAST,
};
/**********************
* GLOBAL PROTOTYPES
**********************/
/**
* Create a container objects
* @param par pointer to an object, it will be the parent of the new container
* @param copy pointer to a container object, if not NULL then the new object will be copied from it
* @return pointer to the created container
*/
lv_obj_t * lv_cont_create(lv_obj_t * par, const lv_obj_t * copy);
/*=====================
* Setter functions
*====================*/
/**
* Set a layout on a container
* @param cont pointer to a container object
* @param layout a layout from 'lv_cont_layout_t'
*/
void lv_cont_set_layout(lv_obj_t * cont, lv_layout_t layout);
/**
* Set the fit policy in all 4 directions separately.
* It tell how to change the container's size automatically.
* @param cont pointer to a container object
* @param left left fit policy from `lv_fit_t`
* @param right right fit policy from `lv_fit_t`
* @param top top fit policy from `lv_fit_t`
* @param bottom bottom fit policy from `lv_fit_t`
*/
void lv_cont_set_fit4(lv_obj_t * cont, lv_fit_t left, lv_fit_t right, lv_fit_t top, lv_fit_t bottom);
/**
* Set the fit policy horizontally and vertically separately.
* It tells how to change the container's size automatically.
* @param cont pointer to a container object
* @param hor horizontal fit policy from `lv_fit_t`
* @param ver vertical fit policy from `lv_fit_t`
*/
static inline void lv_cont_set_fit2(lv_obj_t * cont, lv_fit_t hor, lv_fit_t ver)
{
lv_cont_set_fit4(cont, hor, hor, ver, ver);
}
/**
* Set the fit policy in all 4 direction at once.
* It tells how to change the container's size automatically.
* @param cont pointer to a container object
* @param fit fit policy from `lv_fit_t`
*/
static inline void lv_cont_set_fit(lv_obj_t * cont, lv_fit_t fit)
{
lv_cont_set_fit4(cont, fit, fit, fit, fit);
}
/*=====================
* Getter functions
*====================*/
/**
* Get the layout of a container
* @param cont pointer to container object
* @return the layout from 'lv_cont_layout_t'
*/
lv_layout_t lv_cont_get_layout(const lv_obj_t * cont);
/**
* Get left fit mode of a container
* @param cont pointer to a container object
* @return an element of `lv_fit_t`
*/
lv_fit_t lv_cont_get_fit_left(const lv_obj_t * cont);
/**
* Get right fit mode of a container
* @param cont pointer to a container object
* @return an element of `lv_fit_t`
*/
lv_fit_t lv_cont_get_fit_right(const lv_obj_t * cont);
/**
* Get top fit mode of a container
* @param cont pointer to a container object
* @return an element of `lv_fit_t`
*/
lv_fit_t lv_cont_get_fit_top(const lv_obj_t * cont);
/**
* Get bottom fit mode of a container
* @param cont pointer to a container object
* @return an element of `lv_fit_t`
*/
lv_fit_t lv_cont_get_fit_bottom(const lv_obj_t * cont);
/**********************
* MACROS
**********************/
#endif /*LV_USE_CONT*/
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /*LV_CONT_H*/

View File

@ -241,7 +241,12 @@ void lv_dropdown_add_option(lv_obj_t * obj, const char * option, uint32_t pos)
/*Allocate space for the new option*/
size_t old_len = (ext->options == NULL) ? 0 : strlen(ext->options);
size_t ins_len = strlen(option);
#if LV_USE_ARABIC_PERSIAN_CHARS == 0
size_t ins_len = strlen(option) + 1;
#else
size_t ins_len = _lv_txt_ap_calc_bytes_cnt(option) + 1;
#endif
size_t new_len = ins_len + old_len + 2; /* +2 for terminating NULL and possible \n */
ext->options = lv_mem_realloc(ext->options, new_len + 1);
LV_ASSERT_MEM(ext->options);
@ -269,9 +274,13 @@ void lv_dropdown_add_option(lv_obj_t * obj, const char * option, uint32_t pos)
char * ins_buf = _lv_mem_buf_get(ins_len + 2); /* + 2 for terminating NULL and possible \n */
LV_ASSERT_MEM(ins_buf);
if(ins_buf == NULL) return;
#if LV_USE_ARABIC_PERSIAN_CHARS == 0
strcpy(ins_buf, option);
if(pos < ext->option_cnt)
strcat(ins_buf, "\n");
#else
_lv_txt_ap_proc(option, ins_buf);
#endif
if(pos < ext->option_cnt) strcat(ins_buf, "\n");
_lv_txt_ins(ext->options, _lv_txt_encoded_get_char_id(ext->options, insert_pos), ins_buf);
_lv_mem_buf_release(ins_buf);
@ -294,10 +303,8 @@ void lv_dropdown_set_selected(lv_obj_t * obj, uint16_t sel_opt)
ext->sel_opt_id = sel_opt < ext->option_cnt ? sel_opt : ext->option_cnt - 1;
ext->sel_opt_id_orig = ext->sel_opt_id;
/*Move the list to show the current option*/
if(ext->list != NULL) {
lv_obj_invalidate(ddlist);
}
lv_obj_invalidate(ddlist);
}
/**

View File

@ -447,7 +447,7 @@ void lv_linemeter_draw_scale(lv_obj_t * lmeter, const lv_area_t * clip_area, uin
p1.y = y_out_extra;
/* Set the color of the lines */
if((!ext->mirrored && i > level) || (ext->mirrored && i < level)) {
if((!ext->mirrored && i >= level) || (ext->mirrored && i <= level)) {
line_dsc.color = end_color;
line_dsc.width = end_line_width;
}

View File

@ -9,13 +9,13 @@
#include "lv_table.h"
#if LV_USE_TABLE != 0
#include "../lv_misc/lv_debug.h"
#include "../lv_core/lv_indev.h"
#include "../lv_misc/lv_debug.h"
#include "../lv_misc/lv_txt.h"
#include "../lv_misc/lv_txt_ap.h"
#include "../lv_misc/lv_math.h"
#include "../lv_draw/lv_draw_label.h"
#include "../lv_misc/lv_printf.h"
#include "../lv_draw/lv_draw_label.h"
#include "../lv_themes/lv_theme.h"
/*********************

View File

@ -166,7 +166,7 @@ lv_obj_t * lv_tabview_create(lv_obj_t * par, const lv_obj_t * copy)
lv_btnmatrix_set_map(ext->btns, ext->tab_name_ptr);
lv_style_list_copy(lv_obj_get_style_list(tabview, LV_TABVIEW_PART_BG_SCROLLABLE), lv_obj_get_style_list(copy,
LV_TABVIEW_PART_BG_SCROLLABLE));
LV_TABVIEW_PART_BG_SCROLLABLE));
lv_style_list_copy(lv_obj_get_style_list(tabview, LV_TABVIEW_PART_TAB_BG), lv_obj_get_style_list(copy,
LV_TABVIEW_PART_TAB_BG));
lv_style_list_copy(lv_obj_get_style_list(tabview, LV_TABVIEW_PART_TAB_BTN), lv_obj_get_style_list(copy,
@ -616,7 +616,7 @@ static lv_res_t lv_tabview_signal(lv_obj_t * tabview, lv_signal_t sign, void * p
else if(info->part == LV_TABVIEW_PART_TAB_BTN) info->result = lv_obj_get_state(ext->btns, LV_BTNMATRIX_PART_BTN);
else if(info->part == LV_TABVIEW_PART_INDIC) info->result = lv_obj_get_state(ext->indic, LV_OBJ_PART_MAIN);
else if(info->part == LV_TABVIEW_PART_BG_SCROLLABLE) info->result = lv_obj_get_state(ext->content,
LV_PAGE_PART_SCROLLABLE);
LV_PAGE_PART_SCROLLABLE);
return LV_RES_OK;
}

View File

@ -257,8 +257,7 @@ void lv_textarea_add_char(lv_obj_t * ta, uint32_t c)
lv_textarea_clear_selection(ta); /*Clear selection*/
if(ext->pwd_mode != 0) {
ext->pwd_tmp = lv_mem_realloc(ext->pwd_tmp, strlen(ext->pwd_tmp) + 2); /*+2: the new char + \0 */
ext->pwd_tmp = lv_mem_realloc(ext->pwd_tmp, strlen(ext->pwd_tmp) + strlen(letter_buf) + 1); /*+2: the new char + \0 */
LV_ASSERT_MEM(ext->pwd_tmp);
if(ext->pwd_tmp == NULL) return;
@ -1458,6 +1457,7 @@ static void pwd_char_hider(lv_obj_t * ta)
lv_label_set_text(ext->label, txt_tmp);
_lv_mem_buf_release(txt_tmp);
refr_cursor_area(ta);
}
}

View File

@ -92,6 +92,7 @@ lv_obj_t * lv_win_create(lv_obj_t * par, const lv_obj_t * copy)
ext->page = NULL;
ext->header = NULL;
ext->title_txt = lv_mem_alloc(strlen(DEF_TITLE) + 1);
ext->title_txt_align = LV_TXT_FLAG_NONE;
strcpy(ext->title_txt, DEF_TITLE);
/*Init the new window object*/
@ -257,11 +258,20 @@ void lv_win_set_title(lv_obj_t * win, const char * title)
lv_win_ext_t * ext = lv_obj_get_ext_attr(win);
ext->title_txt = lv_mem_realloc(ext->title_txt, strlen(title) + 1);
#if LV_USE_ARABIC_PERSIAN_CHARS == 0
size_t len = strlen(title) + 1;
#else
size_t len = _lv_txt_ap_calc_bytes_cnt(title) + 1;
#endif
ext->title_txt = lv_mem_realloc(ext->title_txt, len + 1);
LV_ASSERT_MEM(ext->title_txt);
if(ext->title_txt == NULL) return;
#if LV_USE_ARABIC_PERSIAN_CHARS == 0
strcpy(ext->title_txt, title);
#else
_lv_txt_ap_proc(title, ext->title_txt);
#endif
lv_obj_invalidate(ext->header);
}
@ -363,6 +373,14 @@ void lv_win_set_drag(lv_obj_t * win, bool en)
lv_obj_set_drag(win, en);
}
void lv_win_title_set_alignment(lv_obj_t * win, uint8_t alignment)
{
lv_win_ext_t * ext = lv_obj_get_ext_attr(win);
ext->title_txt_align = alignment;
}
/*=====================
* Getter functions
*====================*/
@ -491,6 +509,14 @@ lv_coord_t lv_win_get_width(lv_obj_t * win)
return lv_obj_get_width_fit(scrl) - left - right;
}
uint8_t lv_win_title_get_alignment(lv_obj_t * win)
{
lv_win_ext_t * ext = lv_obj_get_ext_attr(win);
return ext->title_txt_align;
}
/*=====================
* Other functions
*====================*/
@ -538,11 +564,13 @@ static lv_design_res_t lv_win_header_design(lv_obj_t * header, const lv_area_t *
lv_win_ext_t * ext = lv_obj_get_ext_attr(win);
lv_style_int_t header_left = lv_obj_get_style_pad_left(win, LV_WIN_PART_HEADER);
lv_style_int_t header_right = lv_obj_get_style_pad_right(win, LV_WIN_PART_HEADER);
lv_style_int_t header_inner = lv_obj_get_style_pad_inner(win, LV_WIN_PART_HEADER);
lv_draw_label_dsc_t label_dsc;
lv_draw_label_dsc_init(&label_dsc);
lv_obj_init_draw_label_dsc(header, LV_OBJ_PART_MAIN, &label_dsc);
label_dsc.flag = ext->title_txt_align;
lv_area_t txt_area;
lv_point_t txt_size;
@ -557,21 +585,41 @@ static lv_design_res_t lv_win_header_design(lv_obj_t * header, const lv_area_t *
/*Get x position of the title (should be on the right of the buttons on the left)*/
lv_coord_t left_btn_offset = 0;
lv_coord_t btn_offset = 0;
btn = lv_obj_get_child_back(ext->header, NULL);
while(btn != NULL) {
if(LV_WIN_BTN_ALIGN_LEFT == lv_win_btn_get_alignment(btn)) {
left_btn_offset += btn_w + header_inner;
btn_offset += btn_w + header_inner;
}
btn = lv_obj_get_child_back(header, btn);
}
txt_area.x1 = header->coords.x1 + header_left + left_btn_offset;
txt_area.y1 = header->coords.y1 + (lv_obj_get_height(header) - txt_size.y) / 2;
txt_area.x2 = txt_area.x1 + txt_size.x + left_btn_offset;
txt_area.y2 = txt_area.y1 + txt_size.y;
switch(label_dsc.flag) {
case LV_TXT_FLAG_CENTER:
txt_area.x1 = header->coords.x1 + header_left + btn_offset;
txt_area.x2 = header->coords.x2 - header_right - btn_offset;
txt_area.y1 = header->coords.y1 + (lv_obj_get_height(header) - txt_size.y) / 2;
txt_area.y2 = txt_area.y1 + txt_size.y;
break;
case LV_TXT_FLAG_RIGHT:
txt_area.x1 = header->coords.x1;
txt_area.x2 = header->coords.x2 - header_right - btn_offset;
txt_area.y1 = header->coords.y1 + (lv_obj_get_height(header) - txt_size.y) / 2;
txt_area.y2 = txt_area.y1 + txt_size.y;
break;
case LV_TXT_FLAG_FIT || LV_TXT_FLAG_EXPAND:
txt_area.x1 = header->coords.x1;
txt_area.x2 = header->coords.x2;
txt_area.y1 = header->coords.y1 + (lv_obj_get_height(header) - txt_size.y) / 2;
txt_area.y2 = txt_area.y1 + txt_size.y;
break;
default:
txt_area.x1 = header->coords.x1 + header_left + btn_offset;
txt_area.x2 = txt_area.x1 + txt_size.x + btn_offset;
txt_area.y1 = header->coords.y1 + (lv_obj_get_height(header) - txt_size.y) / 2;
txt_area.y2 = txt_area.y1 + txt_size.y;
break;
}
lv_draw_label(&txt_area, clip_area, &label_dsc, ext->title_txt, NULL);
}
else if(mode == LV_DESIGN_DRAW_POST) {

View File

@ -57,6 +57,7 @@ typedef struct {
lv_obj_t * header; /*Pointer to the header container of the window*/
char * title_txt; /*Pointer to the title label of the window*/
lv_coord_t btn_w; /*Width of the control buttons*/
uint8_t title_txt_align; /*Control the alignment of the header text*/
} lv_win_ext_t;
/** Window parts. */
@ -175,6 +176,13 @@ void lv_win_set_anim_time(lv_obj_t * win, uint16_t anim_time);
*/
void lv_win_set_drag(lv_obj_t * win, bool en);
/**
* Set alignment of title text in window header.
* @param win pointer to a window object
* @param alignment set the type of alignment with LV_TXT_FLAGS
*/
void lv_win_title_set_alignment(lv_obj_t * win, uint8_t alignment);
/*=====================
* Getter functions
*====================*/
@ -254,6 +262,12 @@ static inline bool lv_win_get_drag(const lv_obj_t * win)
return lv_obj_get_drag(win);
}
/**
* Get the current alignment of title text in window header.
* @param win pointer to a window object
*/
uint8_t lv_win_title_get_alignment(lv_obj_t * win);
/*=====================
* Other functions
*====================*/

View File

@ -1,11 +1,11 @@
#include "../lvgl.h"
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include "lv_test_core/lv_test_core.h"
#include "lv_test_widgets/lv_test_label.h"
#if LV_BUILD_TEST
#include <sys/time.h>
static void hal_init(void);
static void dummy_flush_cb(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p);