Compare commits
42 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e66f19e5ce | ||
|
|
8ed224fd63 | ||
|
|
998ad66c84 | ||
|
|
83c55c2a64 | ||
|
|
6ed420e043 | ||
|
|
de44f74522 | ||
|
|
ed5f91ab72 | ||
|
|
e5f58151ac | ||
|
|
26ab373b43 | ||
|
|
3dbee9b584 | ||
|
|
56a48e0173 | ||
|
|
aba10b0170 | ||
|
|
f0c52b3511 | ||
|
|
6dd1884228 | ||
|
|
20d56ee6e9 | ||
|
|
196bcb9b0e | ||
|
|
cee779a56d | ||
|
|
07b6d93de4 | ||
|
|
091174069d | ||
|
|
43ed3eb1f4 | ||
|
|
c4d978fa6f | ||
|
|
0ca874bc49 | ||
|
|
3d22dc5722 | ||
|
|
62d21734d9 | ||
|
|
cd69be12d1 | ||
|
|
1b83855c72 | ||
|
|
243145d8c9 | ||
|
|
cb021a425a | ||
|
|
b0fecc6bb2 | ||
|
|
4e177e01ea | ||
|
|
2bf91dbbb5 | ||
|
|
aac672e88b | ||
|
|
93d7bd4cf5 | ||
|
|
57c2201386 | ||
|
|
0ea6bcd40c | ||
|
|
0a7f6a6331 | ||
|
|
b04dea5971 | ||
|
|
e90ce9d4b7 | ||
|
|
5fc66822b9 | ||
|
|
e2d7fa4477 | ||
|
|
861f07bb77 | ||
|
|
6d4de78756 |
8
.github/pull_request_template.md
vendored
Normal file
8
.github/pull_request_template.md
vendored
Normal 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
|
||||
22
CHANGELOG.md
22
CHANGELOG.md
@@ -1,6 +1,26 @@
|
||||
# Changelog
|
||||
|
||||
## v7.8.1 (Plannad at 15.12.2020)
|
||||
## v7.9.0 (Plann1d at 05.01.2020
|
||||
|
||||
### 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
|
||||
- Added support for Zephyr integration
|
||||
|
||||
### 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
|
||||
- fix(kconfig) handle disable sprintf float correctly.
|
||||
- fix(layout) stop layout after recursion threshold is reached
|
||||
- fix(gauge) fix redraw with image needle
|
||||
|
||||
|
||||
## v7.8.1
|
||||
|
||||
### Bugfixes
|
||||
- fix(lv_scr_load_anim) fix when multiple screen are loaded at tsame time with delay
|
||||
|
||||
@@ -3,15 +3,62 @@ 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")
|
||||
endif()
|
||||
|
||||
elseif(ZEPHYR_BASE)
|
||||
|
||||
if(CONFIG_LVGL)
|
||||
|
||||
zephyr_include_directories(${ZEPHYR_BASE}/lib/gui/lvgl)
|
||||
|
||||
target_include_directories(lvgl INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
zephyr_compile_definitions(LV_CONF_KCONFIG_EXTERNAL_INCLUDE=<autoconf.h>)
|
||||
|
||||
zephyr_compile_definitions_ifdef(CONFIG_LV_MEM_CUSTOM
|
||||
LV_MEM_CUSTOM_ALLOC=${CONFIG_LV_MEM_CUSTOM_ALLOC}
|
||||
)
|
||||
zephyr_compile_definitions_ifdef(CONFIG_LV_MEM_CUSTOM
|
||||
LV_MEM_CUSTOM_FREE=${CONFIG_LV_MEM_CUSTOM_FREE}
|
||||
)
|
||||
zephyr_compile_definitions_ifdef(CONFIG_LV_TICK_CUSTOM
|
||||
LV_TICK_CUSTOM_SYS_TIME_EXPR=${CONFIG_LV_TICK_CUSTOM_SYS_TIME_EXPR}
|
||||
)
|
||||
|
||||
zephyr_library()
|
||||
|
||||
file(GLOB_RECURSE SOURCES src/*.c)
|
||||
zephyr_library_sources(${SOURCES})
|
||||
|
||||
endif() # CONFIG_LVGL
|
||||
|
||||
else()
|
||||
message(FATAL_ERROR "Unknown platform.")
|
||||
endif()
|
||||
|
||||
62
Kconfig
62
Kconfig
@@ -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"
|
||||
|
||||
@@ -27,14 +27,12 @@ Planned to November/December 2020
|
||||
- Simplified File system interface ([feat/new_fs_api](https://github.com/lvgl/lvgl/tree/feat/new-fs-api) branch) to make porting easier
|
||||
- Work in progress
|
||||
- Remove the align parameter from `lv_canvas_draw_text`
|
||||
- Remove the copy paramter from create functions
|
||||
- Style selectors and style-based states See [#1832](https://github.com/lvgl/lvgl/issues/1832)
|
||||
- Add Object Orianted system [#1919](https://github.com/lvgl/lvgl/issues/1919)
|
||||
|
||||
## v8.1
|
||||
- Add radio button widget
|
||||
- Make the copy paramter obsolate in create functions
|
||||
- Optimize and simplifie styles [#1832](https://github.com/lvgl/lvgl/issues/1832)
|
||||
- Use a more generic inheritenace [#1919](https://github.com/lvgl/lvgl/issues/1919)
|
||||
|
||||
## v8.x
|
||||
- Add radio button widget
|
||||
- Unit testing (gtest?). See [#1658](https://github.com/lvgl/lvgl/issues/1658)
|
||||
- Benchmarking (gem5?). See [#1660](https://github.com/lvgl/lvgl/issues/1660)
|
||||
|
||||
@@ -47,10 +45,8 @@ Planned to November/December 2020
|
||||
- Handle stride. See [#1858](https://github.com/lvgl/lvgl/issues/1858)
|
||||
- Make gradients more versatile
|
||||
- Make image transformations more versatile
|
||||
- Allow snapshoting object to tranfrom them as images
|
||||
- Allow snapshoting object to tranfrom them to images
|
||||
|
||||
## v10
|
||||
- Remove property level states
|
||||
|
||||
|
||||
## Ideas
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "lvgl",
|
||||
"version": "7.8.1",
|
||||
"version": "7.9.0",
|
||||
"keywords": "graphics, gui, embedded, tft, lvgl",
|
||||
"description": "Graphics library to create embedded GUI with easy-to-use graphical elements, beautiful visual effects and low memory footprint. It offers anti-aliasing, opacity, and animations using only one frame buffer.",
|
||||
"repository": {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name=lvgl
|
||||
version=7.8.1
|
||||
version=7.9.0
|
||||
author=kisvegabor
|
||||
maintainer=kisvegabor,embeddedt,pete-pjb
|
||||
sentence=Full-featured Graphics Library for Embedded Systems
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* @file lv_conf.h
|
||||
* Configuration file for v7.8.1-dev
|
||||
* Configuration file for v7.9.0
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -240,7 +240,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`)*/
|
||||
|
||||
4
lvgl.h
4
lvgl.h
@@ -15,8 +15,8 @@ extern "C" {
|
||||
* CURRENT VERSION OF LVGL
|
||||
***************************/
|
||||
#define LVGL_VERSION_MAJOR 7
|
||||
#define LVGL_VERSION_MINOR 8
|
||||
#define LVGL_VERSION_PATCH 1
|
||||
#define LVGL_VERSION_MINOR 9
|
||||
#define LVGL_VERSION_PATCH 0
|
||||
#define LVGL_VERSION_INFO ""
|
||||
|
||||
/*********************
|
||||
|
||||
@@ -93,14 +93,13 @@ for i in fin.read().splitlines():
|
||||
|
||||
if r:
|
||||
line = re.sub('\(.*?\)', '', r[1], 1) #remove parentheses from macros
|
||||
|
||||
dr = re.sub('.*# *define', '', i, 1)
|
||||
d = "# define " + dr
|
||||
|
||||
|
||||
fout.write(
|
||||
f'#ifndef {line}\n'
|
||||
f'# ifdef CONFIG_{line}\n'
|
||||
f'# define {line} CONFIG_{line}\n'
|
||||
f'# ifdef CONFIG_{line.upper()}\n'
|
||||
f'# define {line} CONFIG_{line.upper()}\n'
|
||||
f'# else\n'
|
||||
f'{d}\n'
|
||||
f'# endif\n'
|
||||
|
||||
@@ -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]))
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -602,7 +602,7 @@ e.g. "stm32f769xx.h" or "stm32f429xx.h" */
|
||||
* (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 */
|
||||
#ifndef LV_IMG_CACHE_DEF_SIZE
|
||||
# ifdef CONFIG_LV_IMG_CACHE_DEF_SIZE
|
||||
# define LV_IMG_CACHE_DEF_SIZE CONFIG_LV_IMG_CACHE_DEF_SIZE
|
||||
@@ -1373,15 +1373,15 @@ e.g. "stm32f769xx.h" or "stm32f429xx.h" */
|
||||
# endif
|
||||
#endif
|
||||
#ifndef lv_snprintf
|
||||
# ifdef CONFIG_lv_snprintf
|
||||
# define lv_snprintf CONFIG_lv_snprintf
|
||||
# ifdef CONFIG_LV_SNPRINTF
|
||||
# define lv_snprintf CONFIG_LV_SNPRINTF
|
||||
# else
|
||||
# define lv_snprintf snprintf
|
||||
# endif
|
||||
#endif
|
||||
#ifndef lv_vsnprintf
|
||||
# ifdef CONFIG_lv_vsnprintf
|
||||
# define lv_vsnprintf CONFIG_lv_vsnprintf
|
||||
# ifdef CONFIG_LV_VSNPRINTF
|
||||
# define lv_vsnprintf CONFIG_LV_VSNPRINTF
|
||||
# else
|
||||
# define lv_vsnprintf vsnprintf
|
||||
# endif
|
||||
|
||||
@@ -400,6 +400,20 @@ extern "C" {
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*------------------
|
||||
* SPRINTF DISABLE FLOAT
|
||||
*-----------------*/
|
||||
|
||||
#if defined(CONFIG_LV_CONF_SKIP) || defined(LV_CONF_SKIP)
|
||||
# ifndef LV_SPRINTF_DISABLE_FLOAT
|
||||
# ifndef CONFIG_LV_SPRINTF_DISABLE_FLOAT
|
||||
# define LV_SPRINTF_DISABLE_FLOAT 0
|
||||
# else
|
||||
# define LV_SPRINTF_DISABLE_FLOAT 1
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2020 Jan Van Winkel <jan.van_winkel@dxplore.eu>
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifdef __ZEPHYR__
|
||||
|
||||
#include <autoconf.h>
|
||||
|
||||
#define LV_MEM_CUSTOM 1
|
||||
|
||||
#define LV_MEMCPY_MEMSET_STD 1
|
||||
|
||||
#ifdef CONFIG_LVGL_MEM_POOL_HEAP_KERNEL
|
||||
|
||||
#define LV_MEM_CUSTOM_INCLUDE "kernel.h"
|
||||
#define LV_MEM_CUSTOM_ALLOC k_malloc
|
||||
#define LV_MEM_CUTOM_FREE k_free
|
||||
|
||||
#elif defined(CONFIG_LVGL_MEM_POOL_HEAP_LIB_C)
|
||||
|
||||
#define LV_MEM_CUSTOM_INCLUDE "stdlib.h"
|
||||
#define LV_MEM_CUSTOM_ALLOC malloc
|
||||
#define LV_MEM_CUTOM_FREE free
|
||||
|
||||
#else
|
||||
|
||||
#define LV_MEM_CUSTOM_INCLUDE "lvgl_mem.h"
|
||||
#define LV_MEM_CUSTOM_ALLOC lvgl_malloc
|
||||
#define LV_MEM_CUTOM_FREE lvgl_free
|
||||
|
||||
#endif
|
||||
|
||||
#define LV_ENABLE_GC 0
|
||||
|
||||
#define LV_TICK_CUSTOM 1
|
||||
#define LV_TICK_CUSTOM_INCLUDE "kernel.h"
|
||||
#define LV_TICK_CUSTOM_SYS_TIME_EXPR (k_uptime_get_32())
|
||||
|
||||
#define LV_SPRINTF_CUSTOM 1
|
||||
|
||||
#if LV_SPRINTF_CUSTOM
|
||||
#define LV_SPRINTF_INCLUDE "stdio.h"
|
||||
#define lv_snprintf snprintf
|
||||
#define lv_vsnprintf vsnprintf
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -217,7 +217,7 @@ void lv_scr_load_anim(lv_obj_t * new_scr, lv_scr_load_anim_t anim_type, uint32_t
|
||||
lv_obj_t * act_scr = lv_scr_act();
|
||||
|
||||
|
||||
if(d->del_prev && act_scr != d->scr_to_load) {
|
||||
if(d->del_prev && act_scr != d->scr_to_load && 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);
|
||||
|
||||
@@ -221,8 +221,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 = "Á";
|
||||
|
||||
@@ -1656,7 +1657,8 @@ void lv_obj_set_parent_event(lv_obj_t * obj, bool en)
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the base direction of the object
|
||||
* Set the base direction of the object.
|
||||
* @note This only works if LV_USE_BIDI is enabled.
|
||||
* @param obj pointer to an object
|
||||
* @param dir the new base direction. `LV_BIDI_DIR_LTR/RTL/AUTO/INHERIT`
|
||||
*/
|
||||
|
||||
@@ -775,6 +775,7 @@ void lv_obj_set_parent_event(lv_obj_t * obj, bool en);
|
||||
|
||||
/**
|
||||
* Set the base direction of the object
|
||||
* @note This only works if LV_USE_BIDI is enabled.
|
||||
* @param obj pointer to an object
|
||||
* @param dir the new base direction. `LV_BIDI_DIR_LTR/RTL/AUTO/INHERIT`
|
||||
*/
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -1331,6 +1331,10 @@ static void draw_value_str(const lv_area_t * coords, const lv_area_t * clip, con
|
||||
label_dsc.opa = dsc->value_opa;
|
||||
|
||||
lv_draw_label(&value_area, clip, &label_dsc, str, NULL);
|
||||
|
||||
#if LV_USE_ARABIC_PERSIAN_CHARS
|
||||
_lv_mem_buf_release(str);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -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
|
||||
**********************/
|
||||
static uint16_t entry_cnt;
|
||||
#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
|
||||
}
|
||||
|
||||
/**********************
|
||||
|
||||
@@ -794,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 ' ';
|
||||
|
||||
@@ -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}}, // ة
|
||||
|
||||
@@ -44,7 +44,6 @@ 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_day_names(lv_obj_t * calendar, const lv_area_t * mask);
|
||||
static void draw_dates(lv_obj_t * calendar, const lv_area_t * clip_area);
|
||||
static uint8_t get_day_of_week(uint32_t year, uint32_t month, uint32_t day);
|
||||
static bool is_highlighted(lv_obj_t * calendar, day_draw_state_t draw_state, int32_t year, int32_t month, int32_t day);
|
||||
static bool is_pressed(lv_obj_t * calendar, day_draw_state_t draw_state, int32_t year, int32_t month, int32_t day);
|
||||
static const char * get_day_name(lv_obj_t * calendar, uint8_t day);
|
||||
@@ -365,6 +364,27 @@ const char ** lv_calendar_get_month_names(const lv_obj_t * calendar)
|
||||
return ext->month_names;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
uint32_t a = month < 3 ? 1 : 0;
|
||||
uint32_t b = year - a;
|
||||
|
||||
#if LV_CALENDAR_WEEK_STARTS_MONDAY
|
||||
uint32_t day_of_week = (day + (31 * (month - 2 + 12 * a) / 12) + b + (b / 4) - (b / 100) + (b / 400) - 1) % 7;
|
||||
#else
|
||||
uint32_t day_of_week = (day + (31 * (month - 2 + 12 * a) / 12) + b + (b / 4) - (b / 100) + (b / 400)) % 7;
|
||||
#endif
|
||||
|
||||
return day_of_week;
|
||||
}
|
||||
|
||||
/*=====================
|
||||
* Other functions
|
||||
*====================*/
|
||||
@@ -617,22 +637,22 @@ static bool calculate_touched_day(lv_obj_t * calendar, const lv_point_t * touche
|
||||
uint8_t i_pos = 0;
|
||||
i_pos = (y_pos * 7) + x_pos;
|
||||
lv_calendar_ext_t * ext = lv_obj_get_ext_attr(calendar);
|
||||
if(i_pos < get_day_of_week(ext->showed_date.year, ext->showed_date.month, 1)) {
|
||||
if(i_pos < lv_calendar_get_day_of_week(ext->showed_date.year, ext->showed_date.month, 1)) {
|
||||
ext->pressed_date.year = ext->showed_date.year - (ext->showed_date.month == 1 ? 1 : 0);
|
||||
ext->pressed_date.month = ext->showed_date.month == 1 ? 12 : (ext->showed_date.month - 1);
|
||||
ext->pressed_date.day = get_month_length(ext->pressed_date.year, ext->pressed_date.month) -
|
||||
get_day_of_week(ext->showed_date.year, ext->showed_date.month, 1) + 1 + i_pos;
|
||||
lv_calendar_get_day_of_week(ext->showed_date.year, ext->showed_date.month, 1) + 1 + i_pos;
|
||||
}
|
||||
else if(i_pos < (get_day_of_week(ext->showed_date.year, ext->showed_date.month, 1) +
|
||||
else if(i_pos < (lv_calendar_get_day_of_week(ext->showed_date.year, ext->showed_date.month, 1) +
|
||||
get_month_length(ext->showed_date.year, ext->showed_date.month))) {
|
||||
ext->pressed_date.year = ext->showed_date.year;
|
||||
ext->pressed_date.month = ext->showed_date.month;
|
||||
ext->pressed_date.day = i_pos + 1 - get_day_of_week(ext->showed_date.year, ext->showed_date.month, 1);
|
||||
ext->pressed_date.day = i_pos + 1 - lv_calendar_get_day_of_week(ext->showed_date.year, ext->showed_date.month, 1);
|
||||
}
|
||||
else if(i_pos < 42) {
|
||||
ext->pressed_date.year = ext->showed_date.year + (ext->showed_date.month == 12 ? 1 : 0);
|
||||
ext->pressed_date.month = ext->showed_date.month == 12 ? 1 : (ext->showed_date.month + 1);
|
||||
ext->pressed_date.day = i_pos + 1 - get_day_of_week(ext->showed_date.year, ext->showed_date.month, 1) -
|
||||
ext->pressed_date.day = i_pos + 1 - lv_calendar_get_day_of_week(ext->showed_date.year, ext->showed_date.month, 1) -
|
||||
get_month_length(ext->showed_date.year, ext->showed_date.month);
|
||||
}
|
||||
return true;
|
||||
@@ -826,7 +846,7 @@ static void draw_dates(lv_obj_t * calendar, const lv_area_t * clip_area)
|
||||
lv_coord_t box_h = (days_h - 5 * date_inner) / 6;
|
||||
lv_coord_t box_size = LV_MATH_MIN(box_w, box_h);
|
||||
|
||||
uint8_t month_start_day = get_day_of_week(ext->showed_date.year, ext->showed_date.month, 1);
|
||||
uint8_t month_start_day = lv_calendar_get_day_of_week(ext->showed_date.year, ext->showed_date.month, 1);
|
||||
|
||||
day_draw_state_t draw_state;
|
||||
|
||||
@@ -1067,25 +1087,4 @@ static uint8_t is_leap_year(uint32_t year)
|
||||
return (year % 4) || ((year % 100 == 0) && (year % 400)) ? 0 : 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the day of the week
|
||||
* @param year a year
|
||||
* @param month a month
|
||||
* @param day a day
|
||||
* @return [0..6] which means [Sun..Sat] or [Mon..Sun] depending on LV_CALENDAR_WEEK_STARTS_MONDAY
|
||||
*/
|
||||
static uint8_t get_day_of_week(uint32_t year, uint32_t month, uint32_t day)
|
||||
{
|
||||
uint32_t a = month < 3 ? 1 : 0;
|
||||
uint32_t b = year - a;
|
||||
|
||||
#if LV_CALENDAR_WEEK_STARTS_MONDAY
|
||||
uint32_t day_of_week = (day + (31 * (month - 2 + 12 * a) / 12) + b + (b / 4) - (b / 100) + (b / 400) - 1) % 7;
|
||||
#else
|
||||
uint32_t day_of_week = (day + (31 * (month - 2 + 12 * a) / 12) + b + (b / 4) - (b / 100) + (b / 400)) % 7;
|
||||
#endif
|
||||
|
||||
return day_of_week;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -182,6 +182,15 @@ const char ** lv_calendar_get_day_names(const lv_obj_t * calendar);
|
||||
*/
|
||||
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
|
||||
*====================*/
|
||||
|
||||
@@ -195,6 +195,7 @@ lv_chart_series_t * lv_chart_add_series(lv_obj_t * chart, 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;
|
||||
@@ -207,6 +208,33 @@ lv_chart_series_t * lv_chart_add_series(lv_obj_t * chart, 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 * chart, lv_chart_series_t * series)
|
||||
{
|
||||
LV_ASSERT_OBJ(chart, LV_OBJX_NAME);
|
||||
LV_ASSERT_NULL(series);
|
||||
|
||||
if(chart == NULL || series == NULL) return;
|
||||
lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart);
|
||||
if(!series->ext_buf_assigned && series->points) lv_mem_free(series->points);
|
||||
|
||||
_lv_ll_remove(&ext->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 * chart, lv_color_t color, lv_cursor_direction_t axes)
|
||||
{
|
||||
LV_ASSERT_OBJ(chart, LV_OBJX_NAME);
|
||||
@@ -246,6 +274,22 @@ void lv_chart_clear_series(lv_obj_t * chart, 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
|
||||
*====================*/
|
||||
@@ -289,7 +333,7 @@ void lv_chart_set_y_range(lv_obj_t * chart, lv_chart_axis_t axis, lv_coord_t ymi
|
||||
if(ext->ymin[axis] == ymin && ext->ymax[axis] == ymax) return;
|
||||
|
||||
ext->ymin[axis] = ymin;
|
||||
ext->ymax[axis] = ymax;
|
||||
ext->ymax[axis] = (ymax == ymin ? ymax + 1 : ymax);
|
||||
|
||||
lv_chart_refresh(chart);
|
||||
}
|
||||
@@ -666,6 +710,7 @@ void lv_chart_set_cursor_point(lv_obj_t * chart, lv_chart_cursor_t * cursor, lv_
|
||||
lv_chart_refresh(chart);
|
||||
}
|
||||
|
||||
|
||||
/*=====================
|
||||
* Getter functions
|
||||
*====================*/
|
||||
@@ -1135,6 +1180,7 @@ static void draw_series_line(lv_obj_t * chart, const lv_area_t * series_area, co
|
||||
|
||||
/*Go through all data lines*/
|
||||
_LV_LL_READ_BACK(ext->series_ll, ser) {
|
||||
if(ser->hidden) continue;
|
||||
line_dsc.color = ser->color;
|
||||
point_dsc.bg_color = ser->color;
|
||||
area_dsc.bg_color = ser->color;
|
||||
@@ -1148,7 +1194,7 @@ static void draw_series_line(lv_obj_t * chart, const lv_area_t * series_area, co
|
||||
lv_coord_t p_act = start_point;
|
||||
lv_coord_t p_prev = start_point;
|
||||
int32_t y_tmp = (int32_t)((int32_t)ser->points[p_prev] - ext->ymin[ser->y_axis]) * h;
|
||||
y_tmp = y_tmp / (ext->ymax[ser->y_axis] - ext->ymin[ser->y_axis]);
|
||||
y_tmp = y_tmp / (ext->ymax[ser->y_axis] - ext->ymin[ser->y_axis]);
|
||||
p2.y = h - y_tmp + y_ofs;
|
||||
|
||||
for(i = 0; i < ext->point_cnt; i++) {
|
||||
@@ -1271,6 +1317,7 @@ static void draw_series_column(lv_obj_t * chart, const lv_area_t * series_area,
|
||||
|
||||
/*Draw the current point of all data line*/
|
||||
_LV_LL_READ_BACK(ext->series_ll, ser) {
|
||||
if(ser->hidden) continue;
|
||||
lv_coord_t start_point = ext->update_mode == LV_CHART_UPDATE_MODE_SHIFT ? ser->start_point : 0;
|
||||
|
||||
col_a.x1 = x_act;
|
||||
|
||||
@@ -74,6 +74,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;
|
||||
|
||||
@@ -153,6 +154,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
|
||||
@@ -169,6 +177,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
|
||||
*====================*/
|
||||
|
||||
@@ -27,6 +27,10 @@
|
||||
*********************/
|
||||
#define LV_OBJX_NAME "lv_cont"
|
||||
|
||||
#ifndef LV_LAYOUT_MAX_RECURSION
|
||||
#define LV_LAYOUT_MAX_RECURSION 10
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
@@ -664,142 +668,152 @@ static void lv_cont_refr_autofit(lv_obj_t * cont)
|
||||
return;
|
||||
}
|
||||
|
||||
lv_area_t tight_area;
|
||||
lv_area_t ori;
|
||||
lv_obj_t * child_i;
|
||||
static int recursion_level = 0;
|
||||
recursion_level++;
|
||||
/*Ensure it won't keep recursing forever*/
|
||||
if(recursion_level <= LV_LAYOUT_MAX_RECURSION) {
|
||||
lv_area_t tight_area;
|
||||
lv_area_t ori;
|
||||
lv_obj_t * child_i;
|
||||
|
||||
lv_obj_t * par = lv_obj_get_parent(cont);
|
||||
lv_area_t parent_area;
|
||||
lv_area_copy(&parent_area, &par->coords);
|
||||
parent_area.x1 += lv_obj_get_style_pad_left(par, LV_OBJ_PART_MAIN);
|
||||
parent_area.x2 -= lv_obj_get_style_pad_right(par, LV_OBJ_PART_MAIN);
|
||||
parent_area.y1 += lv_obj_get_style_pad_top(par, LV_OBJ_PART_MAIN);
|
||||
parent_area.y2 -= lv_obj_get_style_pad_bottom(par, LV_OBJ_PART_MAIN);
|
||||
lv_obj_t * par = lv_obj_get_parent(cont);
|
||||
lv_area_t parent_area;
|
||||
lv_area_copy(&parent_area, &par->coords);
|
||||
parent_area.x1 += lv_obj_get_style_pad_left(par, LV_OBJ_PART_MAIN);
|
||||
parent_area.x2 -= lv_obj_get_style_pad_right(par, LV_OBJ_PART_MAIN);
|
||||
parent_area.y1 += lv_obj_get_style_pad_top(par, LV_OBJ_PART_MAIN);
|
||||
parent_area.y2 -= lv_obj_get_style_pad_bottom(par, LV_OBJ_PART_MAIN);
|
||||
|
||||
/*Search the side coordinates of the children*/
|
||||
lv_obj_get_coords(cont, &ori);
|
||||
lv_obj_get_coords(cont, &tight_area);
|
||||
/*Search the side coordinates of the children*/
|
||||
lv_obj_get_coords(cont, &ori);
|
||||
lv_obj_get_coords(cont, &tight_area);
|
||||
|
||||
bool has_children = _lv_ll_is_empty(&cont->child_ll) ? false : true;
|
||||
bool has_children = _lv_ll_is_empty(&cont->child_ll) ? false : true;
|
||||
|
||||
if(has_children) {
|
||||
tight_area.x1 = LV_COORD_MAX;
|
||||
tight_area.y1 = LV_COORD_MAX;
|
||||
tight_area.x2 = LV_COORD_MIN;
|
||||
tight_area.y2 = LV_COORD_MIN;
|
||||
if(has_children) {
|
||||
tight_area.x1 = LV_COORD_MAX;
|
||||
tight_area.y1 = LV_COORD_MAX;
|
||||
tight_area.x2 = LV_COORD_MIN;
|
||||
tight_area.y2 = LV_COORD_MIN;
|
||||
|
||||
_LV_LL_READ(cont->child_ll, child_i) {
|
||||
if(lv_obj_get_hidden(child_i) != false) continue;
|
||||
_LV_LL_READ(cont->child_ll, child_i) {
|
||||
if(lv_obj_get_hidden(child_i) != false) continue;
|
||||
|
||||
if(ext->fit_left != LV_FIT_PARENT) {
|
||||
lv_style_int_t mleft = lv_obj_get_style_margin_left(child_i, LV_OBJ_PART_MAIN);
|
||||
tight_area.x1 = LV_MATH_MIN(tight_area.x1, child_i->coords.x1 - mleft);
|
||||
if(ext->fit_left != LV_FIT_PARENT) {
|
||||
lv_style_int_t mleft = lv_obj_get_style_margin_left(child_i, LV_OBJ_PART_MAIN);
|
||||
tight_area.x1 = LV_MATH_MIN(tight_area.x1, child_i->coords.x1 - mleft);
|
||||
}
|
||||
|
||||
if(ext->fit_right != LV_FIT_PARENT) {
|
||||
lv_style_int_t mright = lv_obj_get_style_margin_right(child_i, LV_OBJ_PART_MAIN);
|
||||
tight_area.x2 = LV_MATH_MAX(tight_area.x2, child_i->coords.x2 + mright);
|
||||
}
|
||||
|
||||
if(ext->fit_top != LV_FIT_PARENT) {
|
||||
lv_style_int_t mtop = lv_obj_get_style_margin_top(child_i, LV_OBJ_PART_MAIN);
|
||||
tight_area.y1 = LV_MATH_MIN(tight_area.y1, child_i->coords.y1 - mtop);
|
||||
}
|
||||
|
||||
if(ext->fit_bottom != LV_FIT_PARENT) {
|
||||
lv_style_int_t mbottom = lv_obj_get_style_margin_bottom(child_i, LV_OBJ_PART_MAIN);
|
||||
tight_area.y2 = LV_MATH_MAX(tight_area.y2, child_i->coords.y2 + mbottom);
|
||||
}
|
||||
}
|
||||
|
||||
if(ext->fit_right != LV_FIT_PARENT) {
|
||||
lv_style_int_t mright = lv_obj_get_style_margin_right(child_i, LV_OBJ_PART_MAIN);
|
||||
tight_area.x2 = LV_MATH_MAX(tight_area.x2, child_i->coords.x2 + mright);
|
||||
}
|
||||
|
||||
if(ext->fit_top != LV_FIT_PARENT) {
|
||||
lv_style_int_t mtop = lv_obj_get_style_margin_top(child_i, LV_OBJ_PART_MAIN);
|
||||
tight_area.y1 = LV_MATH_MIN(tight_area.y1, child_i->coords.y1 - mtop);
|
||||
}
|
||||
|
||||
if(ext->fit_bottom != LV_FIT_PARENT) {
|
||||
lv_style_int_t mbottom = lv_obj_get_style_margin_bottom(child_i, LV_OBJ_PART_MAIN);
|
||||
tight_area.y2 = LV_MATH_MAX(tight_area.y2, child_i->coords.y2 + mbottom);
|
||||
}
|
||||
tight_area.x1 -= lv_obj_get_style_pad_left(cont, LV_CONT_PART_MAIN);
|
||||
tight_area.x2 += lv_obj_get_style_pad_right(cont, LV_CONT_PART_MAIN);
|
||||
tight_area.y1 -= lv_obj_get_style_pad_top(cont, LV_CONT_PART_MAIN);
|
||||
tight_area.y2 += lv_obj_get_style_pad_bottom(cont, LV_CONT_PART_MAIN);
|
||||
}
|
||||
|
||||
tight_area.x1 -= lv_obj_get_style_pad_left(cont, LV_CONT_PART_MAIN);
|
||||
tight_area.x2 += lv_obj_get_style_pad_right(cont, LV_CONT_PART_MAIN);
|
||||
tight_area.y1 -= lv_obj_get_style_pad_top(cont, LV_CONT_PART_MAIN);
|
||||
tight_area.y2 += lv_obj_get_style_pad_bottom(cont, LV_CONT_PART_MAIN);
|
||||
}
|
||||
lv_area_t new_area;
|
||||
lv_area_copy(&new_area, &ori);
|
||||
|
||||
lv_area_t new_area;
|
||||
lv_area_copy(&new_area, &ori);
|
||||
|
||||
switch(ext->fit_left) {
|
||||
case LV_FIT_TIGHT:
|
||||
new_area.x1 = tight_area.x1;
|
||||
break;
|
||||
case LV_FIT_PARENT:
|
||||
new_area.x1 = parent_area.x1;
|
||||
break;
|
||||
case LV_FIT_MAX:
|
||||
new_area.x1 = has_children ? LV_MATH_MIN(tight_area.x1, parent_area.x1) : parent_area.x1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch(ext->fit_right) {
|
||||
case LV_FIT_TIGHT:
|
||||
new_area.x2 = tight_area.x2;
|
||||
break;
|
||||
case LV_FIT_PARENT:
|
||||
new_area.x2 = parent_area.x2;
|
||||
break;
|
||||
case LV_FIT_MAX:
|
||||
new_area.x2 = has_children ? LV_MATH_MAX(tight_area.x2, parent_area.x2) : parent_area.x2;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch(ext->fit_top) {
|
||||
case LV_FIT_TIGHT:
|
||||
new_area.y1 = tight_area.y1;
|
||||
break;
|
||||
case LV_FIT_PARENT:
|
||||
new_area.y1 = parent_area.y1;
|
||||
break;
|
||||
case LV_FIT_MAX:
|
||||
new_area.y1 = has_children ? LV_MATH_MIN(tight_area.y1, parent_area.y1) : parent_area.y1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch(ext->fit_bottom) {
|
||||
case LV_FIT_TIGHT:
|
||||
new_area.y2 = tight_area.y2;
|
||||
break;
|
||||
case LV_FIT_PARENT:
|
||||
new_area.y2 = parent_area.y2;
|
||||
break;
|
||||
case LV_FIT_MAX:
|
||||
new_area.y2 = has_children ? LV_MATH_MAX(tight_area.y2, parent_area.y2) : parent_area.y2;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/*Do nothing if the coordinates are not changed*/
|
||||
if(cont->coords.x1 != new_area.x1 || cont->coords.y1 != new_area.y1 || cont->coords.x2 != new_area.x2 ||
|
||||
cont->coords.y2 != new_area.y2) {
|
||||
|
||||
lv_obj_invalidate(cont);
|
||||
lv_area_copy(&cont->coords, &new_area);
|
||||
lv_obj_invalidate(cont);
|
||||
|
||||
/*Notify the object about its new coordinates*/
|
||||
cont->signal_cb(cont, LV_SIGNAL_COORD_CHG, &ori);
|
||||
|
||||
/*Inform the parent about the new coordinates*/
|
||||
par->signal_cb(par, LV_SIGNAL_CHILD_CHG, cont);
|
||||
|
||||
if(lv_obj_get_auto_realign(cont)) {
|
||||
lv_obj_realign(cont);
|
||||
switch(ext->fit_left) {
|
||||
case LV_FIT_TIGHT:
|
||||
new_area.x1 = tight_area.x1;
|
||||
break;
|
||||
case LV_FIT_PARENT:
|
||||
new_area.x1 = parent_area.x1;
|
||||
break;
|
||||
case LV_FIT_MAX:
|
||||
new_area.x1 = has_children ? LV_MATH_MIN(tight_area.x1, parent_area.x1) : parent_area.x1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/*Tell the children the parent's size has changed*/
|
||||
_LV_LL_READ(cont->child_ll, child_i) {
|
||||
child_i->signal_cb(child_i, LV_SIGNAL_PARENT_SIZE_CHG, &ori);
|
||||
switch(ext->fit_right) {
|
||||
case LV_FIT_TIGHT:
|
||||
new_area.x2 = tight_area.x2;
|
||||
break;
|
||||
case LV_FIT_PARENT:
|
||||
new_area.x2 = parent_area.x2;
|
||||
break;
|
||||
case LV_FIT_MAX:
|
||||
new_area.x2 = has_children ? LV_MATH_MAX(tight_area.x2, parent_area.x2) : parent_area.x2;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch(ext->fit_top) {
|
||||
case LV_FIT_TIGHT:
|
||||
new_area.y1 = tight_area.y1;
|
||||
break;
|
||||
case LV_FIT_PARENT:
|
||||
new_area.y1 = parent_area.y1;
|
||||
break;
|
||||
case LV_FIT_MAX:
|
||||
new_area.y1 = has_children ? LV_MATH_MIN(tight_area.y1, parent_area.y1) : parent_area.y1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch(ext->fit_bottom) {
|
||||
case LV_FIT_TIGHT:
|
||||
new_area.y2 = tight_area.y2;
|
||||
break;
|
||||
case LV_FIT_PARENT:
|
||||
new_area.y2 = parent_area.y2;
|
||||
break;
|
||||
case LV_FIT_MAX:
|
||||
new_area.y2 = has_children ? LV_MATH_MAX(tight_area.y2, parent_area.y2) : parent_area.y2;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/*Do nothing if the coordinates are not changed*/
|
||||
if(cont->coords.x1 != new_area.x1 || cont->coords.y1 != new_area.y1 || cont->coords.x2 != new_area.x2 ||
|
||||
cont->coords.y2 != new_area.y2) {
|
||||
|
||||
lv_obj_invalidate(cont);
|
||||
lv_area_copy(&cont->coords, &new_area);
|
||||
lv_obj_invalidate(cont);
|
||||
|
||||
/*Notify the object about its new coordinates*/
|
||||
cont->signal_cb(cont, LV_SIGNAL_COORD_CHG, &ori);
|
||||
|
||||
/*Inform the parent about the new coordinates*/
|
||||
par->signal_cb(par, LV_SIGNAL_CHILD_CHG, cont);
|
||||
|
||||
if(lv_obj_get_auto_realign(cont)) {
|
||||
lv_obj_realign(cont);
|
||||
}
|
||||
|
||||
/*Tell the children the parent's size has changed*/
|
||||
_LV_LL_READ(cont->child_ll, child_i) {
|
||||
child_i->signal_cb(child_i, LV_SIGNAL_PARENT_SIZE_CHG, &ori);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
LV_LOG_ERROR("LV_LAYOUT_MAX_RECURSION reached! You may have encountered issue #1539.");
|
||||
}
|
||||
|
||||
recursion_level--;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -303,7 +303,12 @@ void lv_dropdown_add_option(lv_obj_t * ddlist, 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);
|
||||
@@ -331,9 +336,13 @@ void lv_dropdown_add_option(lv_obj_t * ddlist, 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);
|
||||
|
||||
|
||||
@@ -197,15 +197,9 @@ void lv_gauge_set_value(lv_obj_t * gauge, uint8_t needle_id, int32_t value)
|
||||
int32_t old_value = ext->values[needle_id];
|
||||
ext->values[needle_id] = value;
|
||||
|
||||
// lv_obj_invalidate(gauge);
|
||||
|
||||
lv_style_int_t pad = lv_obj_get_style_pad_inner(gauge, LV_GAUGE_PART_NEEDLE);
|
||||
lv_style_int_t left = lv_obj_get_style_pad_left(gauge, LV_GAUGE_PART_MAIN);
|
||||
lv_style_int_t right = lv_obj_get_style_pad_right(gauge, LV_GAUGE_PART_MAIN);
|
||||
lv_style_int_t top = lv_obj_get_style_pad_top(gauge, LV_GAUGE_PART_MAIN);
|
||||
lv_coord_t r = (lv_obj_get_width(gauge) - left - right) / 2 - pad;
|
||||
lv_coord_t x_ofs = gauge->coords.x1 + r + left + pad;
|
||||
lv_coord_t y_ofs = gauge->coords.y1 + r + top + pad;
|
||||
lv_coord_t r = lv_obj_get_width(gauge) / 2;
|
||||
lv_coord_t x_ofs = gauge->coords.x1 + r;
|
||||
lv_coord_t y_ofs = gauge->coords.y1 + r;
|
||||
uint16_t angle = lv_linemeter_get_scale_angle(gauge);
|
||||
int16_t angle_ofs = 90 + (360 - angle) / 2 + lv_gauge_get_angle_offset(gauge);
|
||||
lv_point_t p_mid;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -276,8 +276,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;
|
||||
|
||||
@@ -1671,6 +1670,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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
*====================*/
|
||||
|
||||
2
zephyr/module.yml
Normal file
2
zephyr/module.yml
Normal file
@@ -0,0 +1,2 @@
|
||||
build:
|
||||
cmake: .
|
||||
Reference in New Issue
Block a user