merge dev-6.1

This commit is contained in:
Gabor Kiss-Vamosi 2019-10-08 16:29:40 +02:00
commit b06ef2620a
87 changed files with 13709 additions and 9385 deletions

View File

@ -93,7 +93,7 @@ You can use the [Simulators](https://docs.littlevgl.com/en/html/get-started/pc-s
1. [Download](https://littlevgl.com/download) or [Clone](https://github.com/littlevgl/lvgl) the library
2. Copy the `lvgl` folder into your project
3. Copy `lvgl/lv_conf_templ.h` as `lv_conf.h` next to the `lvgl` folder and set at least `LV_HOR_RES_MAX`, `LV_VER_RES_MAX` and `LV_COLOR_DEPTH`.
3. Copy `lvgl/lv_conf_template.h` as `lv_conf.h` next to the `lvgl` folder and set at least `LV_HOR_RES_MAX`, `LV_VER_RES_MAX` and `LV_COLOR_DEPTH`.
4. Include `lvgl/lvgl.h` where you need to use LittlevGL related functions.
5. Call `lv_tick_inc(x)` every `x` milliseconds **in a Timer or Task** (`x` should be between 1 and 10). It is required for the internal timing of LittlevGL.
6. Call `lv_init()`

View File

@ -43,6 +43,9 @@
/*Images pixels with this color will not be drawn (with chroma keying)*/
#define LV_COLOR_TRANSP LV_COLOR_LIME /*LV_COLOR_LIME: pure green*/
/* Enable chroma keying for indexed images. */
#define LV_INDEXED_CHROMA 1
/* Enable anti-aliasing (lines, and radiuses will be smoothed) */
#define LV_ANTIALIAS 1
@ -193,6 +196,12 @@ typedef void * lv_img_decoder_user_data_t;
* font's bitmaps */
#define LV_ATTRIBUTE_LARGE_CONST
/* Export integer constant to binding.
* This macro is used with constants in the form of LV_<CONST> that
* should also appear on lvgl binding API such as Micropython
*/
#define LV_EXPORT_CONST_INT(int_value)
/*===================
* HAL settings
*==================*/
@ -229,6 +238,42 @@ typedef void * lv_indev_drv_user_data_t; /*Type of user data in the i
# define LV_LOG_PRINTF 0
#endif /*LV_USE_LOG*/
/*=================
* Debug settings
*================*/
/* If Debug is enabled LittelvGL validates the parameters of the functions.
* If an invalid parameter is found an error log message is printed and
* the MCU halts at the error. (`LV_USE_LOG` should be enabled)
* If you are debugging the MCU you can pause
* the debugger to see exactly where the issue is.
*
* The behavior of asserts can be overwritten by redefining them here.
* E.g. #define LV_ASSERT_MEM(p) <my_assert_code>
*/
#define LV_USE_DEBUG 1
#if LV_USE_DEBUG
/*Check if the parameter is NULL. (Quite fast) */
#define LV_USE_ASSERT_NULL 1
/*Checks is the memory is successfully allocated or no. (Quite fast)*/
#define LV_USE_ASSERT_MEM 1
/* Check the strings.
* Search for NULL, very long strings, invalid characters, and unnatural repetitions. (Slow)
* If disabled `LV_USE_ASSERT_NULL` will be performed instead (if it's enabled) */
#define LV_USE_ASSERT_STR 0
/* Check NULL, the object's type and existence (e.g. not deleted). (Quite slow)
* If disabled `LV_USE_ASSERT_NULL` will be performed instead (if it's enabled) */
#define LV_USE_ASSERT_OBJ 0
/*Check if the styles are properly initialized. (Fast)*/
#define LV_USE_ASSERT_STYLE 1
#endif /*LV_USE_DEBUG*/
/*================
* THEME USAGE
*================*/
@ -297,6 +342,15 @@ typedef void * lv_font_user_data_t;
/*Can break (wrap) texts on these chars*/
#define LV_TXT_BREAK_CHARS " ,.;:-_"
/* If a character is at least this long, will break wherever "prettiest" */
#define LV_TXT_LINE_BREAK_LONG_LEN 12
/* Minimum number of characters of a word to put on a line before a break */
#define LV_TXT_LINE_BREAK_LONG_PRE_MIN_LEN 3
/* Minimum number of characters of a word to put on a line after a break */
#define LV_TXT_LINE_BREAK_LONG_POST_MIN_LEN 3
/* Support bidirectional texts.
* Allows mixing Left-to-Right and Right-to-Left texts.
* The direction will be processed according to the Unicode Bidirectioanl Algorithm:
@ -310,6 +364,14 @@ typedef void * lv_font_user_data_t;
#define LV_BIDI_BASE_DIR_DEF LV_BIDI_DIR_AUTO
#endif
/*Change the built in (v)snprintf functions*/
#define LV_SPRINTF_CUSTOM 0
#if LV_SPRINTF_CUSTOM
# define LV_SPRINTF_INCLUDE <stdio.h>
# define lv_snprintf snprintf
# define lv_vsnprintf vsnprintf
#endif /*LV_SPRINTF_CUSTOM*/
/*===================
* LV_OBJ SETTINGS
*==================*/

1
lvgl.h
View File

@ -28,6 +28,7 @@ extern "C" {
#include "src/lv_core/lv_refr.h"
#include "src/lv_core/lv_disp.h"
#include "src/lv_core/lv_debug.h"
#include "src/lv_themes/lv_theme.h"

View File

@ -50,6 +50,11 @@
#define LV_COLOR_TRANSP LV_COLOR_LIME /*LV_COLOR_LIME: pure green*/
#endif
/* Enable chroma keying for indexed images. */
#ifndef LV_INDEXED_CHROMA
#define LV_INDEXED_CHROMA 1
#endif
/* Enable anti-aliasing (lines, and radiuses will be smoothed) */
#ifndef LV_ANTIALIAS
#define LV_ANTIALIAS 1
@ -261,6 +266,14 @@
#define LV_ATTRIBUTE_LARGE_CONST
#endif
/* Export integer constant to binding.
* This macro is used with constants in the form of LV_<CONST> that
* should also appear on lvgl binding API such as Micropython
*/
#ifndef LV_EXPORT_CONST_INT(int_value)
#define LV_EXPORT_CONST_INT(int_value)
#endif
/*===================
* HAL settings
*==================*/
@ -307,6 +320,54 @@
#endif
#endif /*LV_USE_LOG*/
/*=================
* Debug settings
*================*/
/* If Debug is enabled LittelvGL validates the parameters of the functions.
* If an invalid parameter is found an error log message is printed and
* the MCU halts at the error. (`LV_USE_LOG` should be enabled)
* If you are debugging the MCU you can pause
* the debugger to see exactly where the issue is.
*
* The behavior of asserts can be overwritten by redefining them here.
* E.g. #define LV_ASSERT_MEM(p) <my_assert_code>
*/
#ifndef LV_USE_DEBUG
#define LV_USE_DEBUG 1
#endif
#if LV_USE_DEBUG
/*Check if the parameter is NULL. (Quite fast) */
#ifndef LV_USE_ASSERT_NULL
#define LV_USE_ASSERT_NULL 1
#endif
/*Checks is the memory is successfully allocated or no. (Quite fast)*/
#ifndef LV_USE_ASSERT_MEM
#define LV_USE_ASSERT_MEM 1
#endif
/* Check the strings.
* Search for NULL, very long strings, invalid characters, and unnatural repetitions. (Slow)
* If disabled `LV_USE_ASSERT_NULL` will be performed instead (if it's enabled) */
#ifndef LV_USE_ASSERT_STR
#define LV_USE_ASSERT_STR 0
#endif
/* Check NULL, the object's type and existence (e.g. not deleted). (Quite slow)
* If disabled `LV_USE_ASSERT_NULL` will be performed instead (if it's enabled) */
#ifndef LV_USE_ASSERT_OBJ
#define LV_USE_ASSERT_OBJ 0
#endif
/*Check if the styles are properly initialized. (Fast)*/
#ifndef LV_USE_ASSERT_STYLE
#define LV_USE_ASSERT_STYLE 1
#endif
#endif /*LV_USE_DEBUG*/
/*================
* THEME USAGE
*================*/
@ -412,6 +473,21 @@
#define LV_TXT_BREAK_CHARS " ,.;:-_"
#endif
/* If a character is at least this long, will break wherever "prettiest" */
#ifndef LV_TXT_LINE_BREAK_LONG_LEN
#define LV_TXT_LINE_BREAK_LONG_LEN 12
#endif
/* Minimum number of characters of a word to put on a line before a break */
#ifndef LV_TXT_LINE_BREAK_LONG_PRE_MIN_LEN
#define LV_TXT_LINE_BREAK_LONG_PRE_MIN_LEN 3
#endif
/* Minimum number of characters of a word to put on a line after a break */
#ifndef LV_TXT_LINE_BREAK_LONG_POST_MIN_LEN
#define LV_TXT_LINE_BREAK_LONG_POST_MIN_LEN 3
#endif
/* Support bidirectional texts.
* Allows mixing Left-to-Right and Right-to-Left texts.
* The direction will be processed according to the Unicode Bidirectioanl Algorithm:
@ -429,6 +505,22 @@
#endif
#endif
/*Change the built in (v)snprintf functions*/
#ifndef LV_SPRINTF_CUSTOM
#define LV_SPRINTF_CUSTOM 0
#endif
#if LV_SPRINTF_CUSTOM
#ifndef LV_SPRINTF_INCLUDE
# define LV_SPRINTF_INCLUDE <stdio.h>
#endif
#ifndef lv_snprintf
# define lv_snprintf snprintf
#endif
#ifndef lv_vsnprintf
# define lv_vsnprintf vsnprintf
#endif
#endif /*LV_SPRINTF_CUSTOM*/
/*===================
* LV_OBJ SETTINGS
*==================*/

View File

@ -4,6 +4,7 @@ CSRCS += lv_disp.c
CSRCS += lv_obj.c
CSRCS += lv_refr.c
CSRCS += lv_style.c
CSRCS += lv_debug.c
DEPPATH += --dep-path $(LVGL_DIR)/lvgl/src/lv_core
VPATH += :$(LVGL_DIR)/lvgl/src/lv_core

192
src/lv_core/lv_debug.c Normal file
View File

@ -0,0 +1,192 @@
/**
* @file lv_debug.c
*
*/
/*********************
* INCLUDES
*********************/
#include "lv_obj.h"
#if LV_USE_DEBUG
/*********************
* DEFINES
*********************/
#ifndef LV_DEBUG_STR_MAX_LENGTH
#define LV_DEBUG_STR_MAX_LENGTH (1024 * 8)
#endif
#ifndef LV_DEBUG_STR_MAX_REPEAT
#define LV_DEBUG_STR_MAX_REPEAT 8
#endif
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
static bool obj_valid_child(const lv_obj_t * parent, const lv_obj_t * obj_to_find);
/**********************
* STATIC VARIABLES
**********************/
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
bool lv_debug_check_null(const void * p)
{
if(p) return true;
return false;
}
bool lv_debug_check_obj_type(const lv_obj_t * obj, const char * obj_type)
{
if(obj_type[0] == '\0') return true;
lv_obj_type_t types;
lv_obj_get_type((lv_obj_t *)obj, &types);
uint8_t i;
for(i = 0; i < LV_MAX_ANCESTOR_NUM; i++) {
if(strcmp(types.type[i], obj_type) == 0) return true;
}
return false;
}
bool lv_debug_check_obj_valid(const lv_obj_t * obj)
{
lv_disp_t * disp = lv_disp_get_next(NULL);
while(disp) {
lv_obj_t * scr;
LV_LL_READ(disp->scr_ll, scr) {
if(scr == obj) return true;
bool found = obj_valid_child(scr, obj);
if(found) return true;
}
disp = lv_disp_get_next(disp);
}
return false;
}
bool lv_debug_check_style(const lv_style_t * style)
{
if(style == NULL) return true; /*NULL style is still valid*/
#if LV_USE_ASSERT_STYLE
if(style->debug_sentinel != LV_STYLE_DEGUG_SENTINEL_VALUE) {
LV_LOG_WARN("Invalid style (local variable or not initialized?)");
return false;
}
#endif
return true;
}
bool lv_debug_check_str(const void * str)
{
const uint8_t * s = (const uint8_t *)str;
uint8_t last_byte = 0;
uint32_t rep = 0;
uint32_t i;
for(i = 0; s[i] != '\0' && i < LV_DEBUG_STR_MAX_LENGTH; i++) {
if(s[i] != last_byte) {
last_byte = s[i];
rep = 1;
} else if(s[i] > 0x7F){
rep++;
if(rep > LV_DEBUG_STR_MAX_REPEAT) {
LV_LOG_WARN("lv_debug_check_str: a non-ASCII char has repeated more than LV_DEBUG_STR_MAX_REPEAT times)");
return false;
}
}
if(s[i] < 10) {
LV_LOG_WARN("lv_debug_check_str: invalid char in the string (< 10 value)");
return false; /*Shouldn't occur in strings*/
}
}
if(s[i] == '\0') return true;
LV_LOG_WARN("lv_debug_check_str: string is longer than LV_DEBUG_STR_MAX_LENGTH");
return false;
}
void lv_debug_log_error(const char * msg, unsigned long int value)
{
static const char hex[] = "0123456789ABCDEF";
uint32_t msg_len = strlen(msg);
uint32_t value_len = sizeof(unsigned long int);
if(msg_len < 230) {
char buf[255];
char * bufp = buf;
/*Add the function name*/
memcpy(bufp, msg, msg_len);
bufp += msg_len;
/*Add value in hey*/
*bufp = ' ';
bufp ++;
*bufp = '(';
bufp ++;
*bufp = '0';
bufp ++;
*bufp = 'x';
bufp ++;
int8_t i;
for(i = value_len * 2 - 1; i >= 0; i--) {
uint8_t x = (unsigned long int)((unsigned long int)value >> (i * 4)) & 0xF;
*bufp = hex[x];
bufp++;
}
*bufp = ')';
bufp ++;
*bufp = '\0';
LV_LOG_ERROR(buf);
} else {
LV_LOG_ERROR(msg);
}
}
/**********************
* STATIC FUNCTIONS
**********************/
static bool obj_valid_child(const lv_obj_t * parent, const lv_obj_t * obj_to_find)
{
/*Check all children of `parent`*/
lv_obj_t * child;
LV_LL_READ(parent->child_ll, child) {
if(child == obj_to_find) return true;
/*Check the children*/
bool found = obj_valid_child(child, obj_to_find);
if(found) return true;
}
return false;
}
#endif /*LV_USE_DEBUG*/

152
src/lv_core/lv_debug.h Normal file
View File

@ -0,0 +1,152 @@
/**
* @file lv_debug.h
*
*/
#ifndef LV_DEBUG_H
#define LV_DEBUG_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
#include "lv_obj.h"
#if LV_USE_DEBUG
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* GLOBAL PROTOTYPES
**********************/
bool lv_debug_check_null(const void * p);
bool lv_debug_check_obj_type(const lv_obj_t * obj, const char * obj_type);
bool lv_debug_check_obj_valid(const lv_obj_t * obj);
bool lv_debug_check_style(const void * str);
bool lv_debug_check_str(const void * str);
void lv_debug_log_error(const char * msg, uint64_t value);
/**********************
* MACROS
**********************/
#ifndef LV_DEBUG_ASSERT
#define LV_DEBUG_ASSERT(expr, msg, value) \
{ \
if(!(expr)) { \
LV_LOG_ERROR(__func__); \
lv_debug_log_error(msg, (unsigned long int)value); \
while(1); \
} \
}
#endif
/*----------------
* CHECKS
*----------------*/
#ifndef LV_DEBUG_IS_NULL
#define LV_DEBUG_IS_NULL(p) (lv_debug_check_null(p))
#endif
#ifndef LV_DEBUG_IS_STR
#define LV_DEBUG_IS_STR(str) (lv_debug_check_null(str) && \
lv_debug_check_str(str))
#endif
#ifndef LV_DEBUG_IS_OBJ
#define LV_DEBUG_IS_OBJ(obj_p, obj_type) (lv_debug_check_null(obj_p) && \
lv_debug_check_obj_valid(obj_p) && \
lv_debug_check_obj_type(obj_p, obj_type))
#endif
#ifndef LV_DEBUG_IS_STYLE
#define LV_DEBUG_IS_STYLE(style_p) (lv_debug_check_style(style_p))
#endif
/*-----------------
* ASSERTS
*-----------------*/
/*clang-format off*/
#if LV_USE_ASSERT_NULL
# ifndef LV_ASSERT_NULL
# define LV_ASSERT_NULL(p) LV_DEBUG_ASSERT(LV_DEBUG_IS_NULL(p), "NULL pointer", p);
# endif
#else
# define LV_ASSERT_NULL(p) true
#endif
#if LV_USE_ASSERT_MEM
# ifndef LV_ASSERT_MEM
# define LV_ASSERT_MEM(p) LV_DEBUG_ASSERT(LV_DEBUG_IS_NULL(p), "Out of memory", p);
# endif
#else
# define LV_ASSERT_MEM(p) true
#endif
#if LV_USE_ASSERT_STR
# ifndef LV_ASSERT_STR
# define LV_ASSERT_STR(str) LV_DEBUG_ASSERT(LV_DEBUG_IS_STR(str), "Strange or invalid string", str);
# endif
#else /* LV_USE_ASSERT_OBJ == 0 */
# if LV_USE_ASSERT_NULL /*Use at least LV_ASSERT_NULL if enabled*/
# define LV_ASSERT_STR(str) LV_ASSERT_NULL(str)
# else
# define LV_ASSERT_STR(str) true
# endif
#endif
#if LV_USE_ASSERT_OBJ
# ifndef LV_ASSERT_OBJ
# define LV_ASSERT_OBJ(obj_p, obj_type) LV_DEBUG_ASSERT(LV_DEBUG_IS_OBJ(obj_p, obj_type), "Invalid object", obj_p);
# endif
#else /* LV_USE_ASSERT_OBJ == 0 */
# if LV_USE_ASSERT_NULL /*Use at least LV_ASSERT_NULL if enabled*/
# define LV_ASSERT_OBJ(obj_p, obj_type) LV_ASSERT_NULL(obj_p)
# else
# define LV_ASSERT_OBJ(obj_p, obj_type) true
# endif
#endif
#if LV_USE_ASSERT_STYLE
# ifndef LV_ASSERT_STYLE
# define LV_ASSERT_STYLE(style_p) LV_DEBUG_ASSERT(LV_DEBUG_IS_STYLE(style_p), "Invalid style", style_p);
# endif
#else
# define LV_ASSERT_STYLE(style) true
#endif
#else /* LV_USE_DEBUG == 0 */
#define LV_ASSERT_NULL(p) true
#define LV_ASSERT_MEM(p) true
#define LV_ASSERT_STR(p) true
#define LV_ASSERT_OBJ(obj, obj_type) true
#define LV_ASSERT_STYLE(p) true
#endif /* LV_USE_DEBUG */
/*clang-format on*/
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /*LV_DEBUG_H*/

View File

@ -8,8 +8,9 @@
*********************/
#include "lv_group.h"
#if LV_USE_GROUP != 0
#include "../lv_themes/lv_theme.h"
#include <stddef.h>
#include "../lv_core/lv_debug.h"
#include "../lv_themes/lv_theme.h"
#include "../lv_misc/lv_gc.h"
#if defined(LV_GC_INCLUDE)
@ -62,7 +63,7 @@ void lv_group_init(void)
lv_group_t * lv_group_create(void)
{
lv_group_t * group = lv_ll_ins_head(&LV_GC_ROOT(_lv_group_ll));
lv_mem_assert(group);
LV_ASSERT_MEM(group);
if(group == NULL) return NULL;
lv_ll_init(&group->obj_ll, sizeof(lv_obj_t *));
@ -138,7 +139,7 @@ void lv_group_add_obj(lv_group_t * group, lv_obj_t * obj)
obj->group_p = group;
lv_obj_t ** next = lv_ll_ins_tail(&group->obj_ll);
lv_mem_assert(next);
LV_ASSERT_MEM(next);
if(next == NULL) return;
*next = obj;

View File

@ -11,6 +11,7 @@
#include "lv_refr.h"
#include "lv_group.h"
#include "lv_disp.h"
#include "../lv_core/lv_debug.h"
#include "../lv_themes/lv_theme.h"
#include "../lv_draw/lv_draw.h"
#include "../lv_misc/lv_anim.h"
@ -29,6 +30,7 @@
/*********************
* DEFINES
*********************/
#define LV_OBJX_NAME "lv_obj"
#define LV_OBJ_DEF_WIDTH (LV_DPI)
#define LV_OBJ_DEF_HEIGHT (2 * LV_DPI / 3)
@ -143,7 +145,7 @@ lv_obj_t * lv_obj_create(lv_obj_t * parent, const lv_obj_t * copy)
}
new_obj = lv_ll_ins_head(&disp->scr_ll);
lv_mem_assert(new_obj);
LV_ASSERT_MEM(new_obj);
if(new_obj == NULL) return NULL;
new_obj->par = NULL; /*Screens has no a parent*/
@ -182,8 +184,8 @@ lv_obj_t * lv_obj_create(lv_obj_t * parent, const lv_obj_t * copy)
new_obj->style_p = &lv_style_scr;
}
/*Set the callbacks*/
lv_obj_set_signal_cb(new_obj, lv_obj_signal);
lv_obj_set_design_cb(new_obj, lv_obj_design);
new_obj->signal_cb = lv_obj_signal;
new_obj->design_cb = lv_obj_design;
new_obj->event_cb = NULL;
/*Init. user date*/
@ -224,9 +226,10 @@ lv_obj_t * lv_obj_create(lv_obj_t * parent, const lv_obj_t * copy)
/*parent != NULL create normal obj. on a parent*/
else {
LV_LOG_TRACE("Object create started");
LV_ASSERT_OBJ(parent, LV_OBJX_NAME);
new_obj = lv_ll_ins_head(&parent->child_ll);
lv_mem_assert(new_obj);
LV_ASSERT_MEM(new_obj);
if(new_obj == NULL) return NULL;
new_obj->par = parent; /*Set the parent*/
@ -265,8 +268,8 @@ lv_obj_t * lv_obj_create(lv_obj_t * parent, const lv_obj_t * copy)
}
/*Set the callbacks*/
lv_obj_set_signal_cb(new_obj, lv_obj_signal);
lv_obj_set_design_cb(new_obj, lv_obj_design);
new_obj->signal_cb = lv_obj_signal;
new_obj->design_cb = lv_obj_design;
new_obj->event_cb = NULL;
#if LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_FULL
@ -311,6 +314,7 @@ lv_obj_t * lv_obj_create(lv_obj_t * parent, const lv_obj_t * copy)
/*Copy the attributes if required*/
if(copy != NULL) {
LV_ASSERT_OBJ(copy, LV_OBJX_NAME);
lv_area_copy(&new_obj->coords, &copy->coords);
new_obj->ext_draw_pad = copy->ext_draw_pad;
@ -336,7 +340,7 @@ lv_obj_t * lv_obj_create(lv_obj_t * parent, const lv_obj_t * copy)
new_obj->realign.auto_realign = copy->realign.auto_realign;
#endif
/*Only copy the `event_cb`. `signal_cb` and `design_cb` will be copied the the derived
/*Only copy the `event_cb`. `signal_cb` and `design_cb` will be copied in the derived
* object type (e.g. `lv_btn`)*/
new_obj->event_cb = copy->event_cb;
@ -391,6 +395,7 @@ lv_obj_t * lv_obj_create(lv_obj_t * parent, const lv_obj_t * copy)
*/
lv_res_t lv_obj_del(lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
lv_obj_invalidate(obj);
/*Delete from the group*/
@ -424,15 +429,6 @@ lv_res_t lv_obj_del(lv_obj_t * obj)
lv_event_mark_deleted(obj);
/*Remove the object from parent's children list*/
lv_obj_t * par = lv_obj_get_parent(obj);
if(par == NULL) { /*It is a screen*/
lv_disp_t * d = lv_obj_get_disp(obj);
lv_ll_rem(&d->scr_ll, obj);
} else {
lv_ll_rem(&(par->child_ll), obj);
}
/* Reset all input devices if the object to delete is used*/
lv_indev_t * indev = lv_indev_get_next(NULL);
while(indev) {
@ -455,6 +451,15 @@ lv_res_t lv_obj_del(lv_obj_t * obj)
* Now clean up the object specific data*/
obj->signal_cb(obj, LV_SIGNAL_CLEANUP, NULL);
/*Remove the object from parent's children list*/
lv_obj_t * par = lv_obj_get_parent(obj);
if(par == NULL) { /*It is a screen*/
lv_disp_t * d = lv_obj_get_disp(obj);
lv_ll_rem(&d->scr_ll, obj);
} else {
lv_ll_rem(&(par->child_ll), obj);
}
/*Delete the base objects*/
if(obj->ext_attr != NULL) lv_mem_free(obj->ext_attr);
lv_mem_free(obj); /*Free the object itself*/
@ -475,6 +480,7 @@ lv_res_t lv_obj_del(lv_obj_t * obj)
*/
void lv_obj_del_async(lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
lv_async_call(lv_obj_del_async_cb, obj);
}
@ -484,6 +490,7 @@ void lv_obj_del_async(lv_obj_t * obj)
*/
void lv_obj_clean(lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
lv_obj_t * child = lv_obj_get_child(obj, NULL);
lv_obj_t * child_next;
while(child) {
@ -501,6 +508,8 @@ void lv_obj_clean(lv_obj_t * obj)
*/
void lv_obj_invalidate(const lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
if(lv_obj_get_hidden(obj)) return;
/*Invalidate the object only if it belongs to the 'LV_GC_ROOT(_lv_act_scr)'*/
@ -548,6 +557,9 @@ void lv_obj_invalidate(const lv_obj_t * obj)
*/
void lv_obj_set_parent(lv_obj_t * obj, lv_obj_t * parent)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
LV_ASSERT_OBJ(parent, LV_OBJX_NAME);
if(obj->par == NULL) {
LV_LOG_WARN("Can't set the parent of a screen");
return;
@ -585,6 +597,8 @@ void lv_obj_set_parent(lv_obj_t * obj, lv_obj_t * parent)
*/
void lv_obj_move_foreground(lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
lv_obj_t * parent = lv_obj_get_parent(obj);
/*Do nothing of already in the foreground*/
@ -606,6 +620,8 @@ void lv_obj_move_foreground(lv_obj_t * obj)
*/
void lv_obj_move_background(lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
lv_obj_t * parent = lv_obj_get_parent(obj);
/*Do nothing of already in the background*/
@ -633,6 +649,8 @@ void lv_obj_move_background(lv_obj_t * obj)
*/
void lv_obj_set_pos(lv_obj_t * obj, lv_coord_t x, lv_coord_t y)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
/*Convert x and y to absolute coordinates*/
lv_obj_t * par = obj->par;
@ -680,6 +698,8 @@ void lv_obj_set_pos(lv_obj_t * obj, lv_coord_t x, lv_coord_t y)
*/
void lv_obj_set_x(lv_obj_t * obj, lv_coord_t x)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
lv_obj_set_pos(obj, x, lv_obj_get_y(obj));
}
@ -690,6 +710,8 @@ void lv_obj_set_x(lv_obj_t * obj, lv_coord_t x)
*/
void lv_obj_set_y(lv_obj_t * obj, lv_coord_t y)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
lv_obj_set_pos(obj, lv_obj_get_x(obj), y);
}
@ -701,6 +723,8 @@ void lv_obj_set_y(lv_obj_t * obj, lv_coord_t y)
*/
void lv_obj_set_size(lv_obj_t * obj, lv_coord_t w, lv_coord_t h)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
/* Do nothing if the size is not changed */
/* It is very important else recursive resizing can
@ -750,6 +774,8 @@ void lv_obj_set_size(lv_obj_t * obj, lv_coord_t w, lv_coord_t h)
*/
void lv_obj_set_width(lv_obj_t * obj, lv_coord_t w)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
lv_obj_set_size(obj, w, lv_obj_get_height(obj));
}
@ -760,6 +786,8 @@ void lv_obj_set_width(lv_obj_t * obj, lv_coord_t w)
*/
void lv_obj_set_height(lv_obj_t * obj, lv_coord_t h)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
lv_obj_set_size(obj, lv_obj_get_width(obj), h);
}
@ -773,6 +801,8 @@ void lv_obj_set_height(lv_obj_t * obj, lv_coord_t h)
*/
void lv_obj_align(lv_obj_t * obj, const lv_obj_t * base, lv_align_t align, lv_coord_t x_mod, lv_coord_t y_mod)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
lv_coord_t new_x = lv_obj_get_x(obj);
lv_coord_t new_y = lv_obj_get_y(obj);
@ -780,6 +810,9 @@ void lv_obj_align(lv_obj_t * obj, const lv_obj_t * base, lv_align_t align, lv_co
base = lv_obj_get_parent(obj);
}
LV_ASSERT_OBJ(base, LV_OBJX_NAME);
switch(align) {
case LV_ALIGN_CENTER:
new_x = lv_obj_get_width(base) / 2 - lv_obj_get_width(obj) / 2;
@ -918,6 +951,8 @@ void lv_obj_align(lv_obj_t * obj, const lv_obj_t * base, lv_align_t align, lv_co
*/
void lv_obj_align_origo(lv_obj_t * obj, const lv_obj_t * base, lv_align_t align, lv_coord_t x_mod, lv_coord_t y_mod)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
lv_coord_t new_x = lv_obj_get_x(obj);
lv_coord_t new_y = lv_obj_get_y(obj);
@ -928,6 +963,9 @@ void lv_obj_align_origo(lv_obj_t * obj, const lv_obj_t * base, lv_align_t align,
base = lv_obj_get_parent(obj);
}
LV_ASSERT_OBJ(base, LV_OBJX_NAME);
switch(align) {
case LV_ALIGN_CENTER:
new_x = lv_obj_get_width(base) / 2 - obj_w_half;
@ -1062,6 +1100,8 @@ void lv_obj_align_origo(lv_obj_t * obj, const lv_obj_t * base, lv_align_t align,
*/
void lv_obj_realign(lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
#if LV_USE_OBJ_REALIGN
if(obj->realign.origo_align)
lv_obj_align_origo(obj, obj->realign.base, obj->realign.align, obj->realign.xofs, obj->realign.yofs);
@ -1081,6 +1121,8 @@ void lv_obj_realign(lv_obj_t * obj)
*/
void lv_obj_set_auto_realign(lv_obj_t * obj, bool en)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
#if LV_USE_OBJ_REALIGN
obj->realign.auto_realign = en ? 1 : 0;
#else
@ -1099,6 +1141,8 @@ void lv_obj_set_auto_realign(lv_obj_t * obj, bool en)
*/
void lv_obj_set_ext_click_area(lv_obj_t * obj, uint8_t w, uint8_t h)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
obj->ext_click_pad_hor = w;
obj->ext_click_pad_ver = h;
}
@ -1116,6 +1160,8 @@ void lv_obj_set_ext_click_area(lv_obj_t * obj, uint8_t w, uint8_t h)
*/
void lv_obj_set_ext_click_area(lv_obj_t * obj, lv_coord_t left, lv_coord_t right, lv_coord_t top, lv_coord_t bottom)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
#if LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_FULL
obj->ext_click_pad.x1 = left;
obj->ext_click_pad.x2 = right;
@ -1144,6 +1190,9 @@ void lv_obj_set_ext_click_area(lv_obj_t * obj, lv_coord_t left, lv_coord_t right
*/
void lv_obj_set_style(lv_obj_t * obj, const lv_style_t * style)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
LV_ASSERT_STYLE(style);
obj->style_p = style;
/*Send a signal about style change to every children with NULL style*/
@ -1159,6 +1208,8 @@ void lv_obj_set_style(lv_obj_t * obj, const lv_style_t * style)
*/
void lv_obj_refresh_style(lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
lv_obj_invalidate(obj);
obj->signal_cb(obj, LV_SIGNAL_STYLE_CHG, NULL);
lv_obj_invalidate(obj);
@ -1171,6 +1222,8 @@ void lv_obj_refresh_style(lv_obj_t * obj)
*/
void lv_obj_report_style_mod(lv_style_t * style)
{
LV_ASSERT_STYLE(style);
lv_disp_t * d = lv_disp_get_next(NULL);
while(d) {
@ -1198,6 +1251,8 @@ void lv_obj_report_style_mod(lv_style_t * style)
*/
void lv_obj_set_hidden(lv_obj_t * obj, bool en)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
if(!obj->hidden) lv_obj_invalidate(obj); /*Invalidate when not hidden (hidden objects are ignored) */
obj->hidden = en == false ? 0 : 1;
@ -1215,6 +1270,8 @@ void lv_obj_set_hidden(lv_obj_t * obj, bool en)
*/
void lv_obj_set_click(lv_obj_t * obj, bool en)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
obj->click = (en == true ? 1 : 0);
}
@ -1226,6 +1283,8 @@ void lv_obj_set_click(lv_obj_t * obj, bool en)
*/
void lv_obj_set_top(lv_obj_t * obj, bool en)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
obj->top = (en == true ? 1 : 0);
}
@ -1236,6 +1295,8 @@ void lv_obj_set_top(lv_obj_t * obj, bool en)
*/
void lv_obj_set_drag(lv_obj_t * obj, bool en)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
if(en == true) lv_obj_set_click(obj, true); /*Drag is useless without enabled clicking*/
obj->drag = (en == true ? 1 : 0);
}
@ -1247,6 +1308,8 @@ void lv_obj_set_drag(lv_obj_t * obj, bool en)
*/
void lv_obj_set_drag_dir(lv_obj_t * obj, lv_drag_dir_t drag_dir)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
obj->drag_dir = drag_dir;
if(obj->drag_dir != 0) lv_obj_set_drag(obj, true); /*Drag direction requires drag*/
@ -1259,6 +1322,8 @@ void lv_obj_set_drag_dir(lv_obj_t * obj, lv_drag_dir_t drag_dir)
*/
void lv_obj_set_drag_throw(lv_obj_t * obj, bool en)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
obj->drag_throw = (en == true ? 1 : 0);
}
@ -1270,6 +1335,8 @@ void lv_obj_set_drag_throw(lv_obj_t * obj, bool en)
*/
void lv_obj_set_drag_parent(lv_obj_t * obj, bool en)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
obj->drag_parent = (en == true ? 1 : 0);
}
@ -1280,6 +1347,8 @@ void lv_obj_set_drag_parent(lv_obj_t * obj, bool en)
*/
void lv_obj_set_parent_event(lv_obj_t * obj, bool en)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
obj->parent_event = (en == true ? 1 : 0);
}
@ -1307,6 +1376,8 @@ void lv_obj_set_base_dir(lv_obj_t * obj, lv_bidi_dir_t dir)
*/
void lv_obj_set_opa_scale_enable(lv_obj_t * obj, bool en)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
obj->opa_scale_en = en ? 1 : 0;
}
@ -1320,6 +1391,8 @@ void lv_obj_set_opa_scale_enable(lv_obj_t * obj, bool en)
*/
void lv_obj_set_opa_scale(lv_obj_t * obj, lv_opa_t opa_scale)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
obj->opa_scale = opa_scale;
lv_obj_invalidate(obj);
}
@ -1331,6 +1404,8 @@ void lv_obj_set_opa_scale(lv_obj_t * obj, lv_opa_t opa_scale)
*/
void lv_obj_set_protect(lv_obj_t * obj, uint8_t prot)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
obj->protect |= prot;
}
@ -1341,6 +1416,8 @@ void lv_obj_set_protect(lv_obj_t * obj, uint8_t prot)
*/
void lv_obj_clear_protect(lv_obj_t * obj, uint8_t prot)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
prot = (~prot) & 0xFF;
obj->protect &= prot;
}
@ -1353,6 +1430,8 @@ void lv_obj_clear_protect(lv_obj_t * obj, uint8_t prot)
*/
void lv_obj_set_event_cb(lv_obj_t * obj, lv_event_cb_t event_cb)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
obj->event_cb = event_cb;
}
@ -1367,6 +1446,8 @@ lv_res_t lv_event_send(lv_obj_t * obj, lv_event_t event, const void * data)
{
if(obj == NULL) return LV_RES_OK;
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
lv_res_t res;
res = lv_event_send_func(obj->event_cb, obj, event, data);
return res;
@ -1384,6 +1465,8 @@ lv_res_t lv_event_send(lv_obj_t * obj, lv_event_t event, const void * data)
*/
lv_res_t lv_event_send_func(lv_event_cb_t event_xcb, lv_obj_t * obj, lv_event_t event, const void * data)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
/* Build a simple linked list from the objects used in the events
* It's important to know if an this object was deleted by a nested event
* called from this `even_cb`. */
@ -1448,6 +1531,8 @@ const void * lv_event_get_data(void)
*/
void lv_obj_set_signal_cb(lv_obj_t * obj, lv_signal_cb_t signal_cb)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
obj->signal_cb = signal_cb;
}
@ -1458,6 +1543,8 @@ void lv_obj_set_signal_cb(lv_obj_t * obj, lv_signal_cb_t signal_cb)
*/
void lv_signal_send(lv_obj_t * obj, lv_signal_t signal, void * param)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
if(obj->signal_cb) obj->signal_cb(obj, signal, param);
}
@ -1468,6 +1555,8 @@ void lv_signal_send(lv_obj_t * obj, lv_signal_t signal, void * param)
*/
void lv_obj_set_design_cb(lv_obj_t * obj, lv_design_cb_t design_cb)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
obj->design_cb = design_cb;
}
@ -1483,6 +1572,8 @@ void lv_obj_set_design_cb(lv_obj_t * obj, lv_design_cb_t design_cb)
*/
void * lv_obj_allocate_ext_attr(lv_obj_t * obj, uint16_t ext_size)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
obj->ext_attr = lv_mem_realloc(obj->ext_attr, ext_size);
return (void *)obj->ext_attr;
@ -1494,6 +1585,8 @@ void * lv_obj_allocate_ext_attr(lv_obj_t * obj, uint16_t ext_size)
*/
void lv_obj_refresh_ext_draw_pad(lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
obj->ext_draw_pad = 0;
obj->signal_cb(obj, LV_SIGNAL_REFR_EXT_DRAW_PAD, NULL);
@ -1511,6 +1604,8 @@ void lv_obj_refresh_ext_draw_pad(lv_obj_t * obj)
*/
lv_obj_t * lv_obj_get_screen(const lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
const lv_obj_t * par = obj;
const lv_obj_t * act_p;
@ -1529,6 +1624,8 @@ lv_obj_t * lv_obj_get_screen(const lv_obj_t * obj)
*/
lv_disp_t * lv_obj_get_disp(const lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
const lv_obj_t * scr;
if(obj->par == NULL)
@ -1561,6 +1658,8 @@ lv_disp_t * lv_obj_get_disp(const lv_obj_t * obj)
*/
lv_obj_t * lv_obj_get_parent(const lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
return obj->par;
}
@ -1573,6 +1672,8 @@ lv_obj_t * lv_obj_get_parent(const lv_obj_t * obj)
*/
lv_obj_t * lv_obj_get_child(const lv_obj_t * obj, const lv_obj_t * child)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
lv_obj_t * result = NULL;
if(child == NULL) {
@ -1593,6 +1694,8 @@ lv_obj_t * lv_obj_get_child(const lv_obj_t * obj, const lv_obj_t * child)
*/
lv_obj_t * lv_obj_get_child_back(const lv_obj_t * obj, const lv_obj_t * child)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
lv_obj_t * result = NULL;
if(child == NULL) {
@ -1611,6 +1714,8 @@ lv_obj_t * lv_obj_get_child_back(const lv_obj_t * obj, const lv_obj_t * child)
*/
uint16_t lv_obj_count_children(const lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
lv_obj_t * i;
uint16_t cnt = 0;
@ -1625,6 +1730,8 @@ uint16_t lv_obj_count_children(const lv_obj_t * obj)
*/
uint16_t lv_obj_count_children_recursive(const lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
lv_obj_t * i;
uint16_t cnt = 0;
@ -1648,6 +1755,8 @@ uint16_t lv_obj_count_children_recursive(const lv_obj_t * obj)
*/
void lv_obj_get_coords(const lv_obj_t * obj, lv_area_t * cords_p)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
lv_area_copy(cords_p, &obj->coords);
}
@ -1658,6 +1767,8 @@ void lv_obj_get_coords(const lv_obj_t * obj, lv_area_t * cords_p)
*/
void lv_obj_get_inner_coords(const lv_obj_t * obj, lv_area_t * coords_p)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
const lv_style_t * style = lv_obj_get_style(obj);
if(style->body.border.part & LV_BORDER_LEFT) coords_p->x1 += style->body.border.width;
@ -1675,6 +1786,8 @@ void lv_obj_get_inner_coords(const lv_obj_t * obj, lv_area_t * coords_p)
*/
lv_coord_t lv_obj_get_x(const lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
lv_coord_t rel_x;
lv_obj_t * parent = lv_obj_get_parent(obj);
rel_x = obj->coords.x1 - parent->coords.x1;
@ -1689,6 +1802,8 @@ lv_coord_t lv_obj_get_x(const lv_obj_t * obj)
*/
lv_coord_t lv_obj_get_y(const lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
lv_coord_t rel_y;
lv_obj_t * parent = lv_obj_get_parent(obj);
rel_y = obj->coords.y1 - parent->coords.y1;
@ -1703,6 +1818,8 @@ lv_coord_t lv_obj_get_y(const lv_obj_t * obj)
*/
lv_coord_t lv_obj_get_width(const lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
return lv_area_get_width(&obj->coords);
}
@ -1713,6 +1830,8 @@ lv_coord_t lv_obj_get_width(const lv_obj_t * obj)
*/
lv_coord_t lv_obj_get_height(const lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
return lv_area_get_height(&obj->coords);
}
@ -1723,6 +1842,8 @@ lv_coord_t lv_obj_get_height(const lv_obj_t * obj)
*/
lv_coord_t lv_obj_get_width_fit(lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
const lv_style_t * style = lv_obj_get_style(obj);
return lv_obj_get_width(obj) - style->body.padding.left - style->body.padding.right;
@ -1735,6 +1856,8 @@ lv_coord_t lv_obj_get_width_fit(lv_obj_t * obj)
*/
lv_coord_t lv_obj_get_height_fit(lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
const lv_style_t * style = lv_obj_get_style(obj);
return lv_obj_get_height(obj) - style->body.padding.top - style->body.padding.bottom;
@ -1747,6 +1870,8 @@ lv_coord_t lv_obj_get_height_fit(lv_obj_t * obj)
*/
bool lv_obj_get_auto_realign(lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
#if LV_USE_OBJ_REALIGN
return obj->realign.auto_realign ? true : false;
#else
@ -1762,6 +1887,8 @@ bool lv_obj_get_auto_realign(lv_obj_t * obj)
*/
lv_coord_t lv_obj_get_ext_click_pad_left(const lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
#if LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_TINY
return obj->ext_click_pad_hor;
#elif LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_FULL
@ -1779,6 +1906,8 @@ lv_coord_t lv_obj_get_ext_click_pad_left(const lv_obj_t * obj)
*/
lv_coord_t lv_obj_get_ext_click_pad_right(const lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
#if LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_TINY
return obj->ext_click_pad_hor;
#elif LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_FULL
@ -1796,6 +1925,8 @@ lv_coord_t lv_obj_get_ext_click_pad_right(const lv_obj_t * obj)
*/
lv_coord_t lv_obj_get_ext_click_pad_top(const lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
#if LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_TINY
return obj->ext_click_pad_ver;
#elif LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_FULL
@ -1813,6 +1944,8 @@ lv_coord_t lv_obj_get_ext_click_pad_top(const lv_obj_t * obj)
*/
lv_coord_t lv_obj_get_ext_click_pad_bottom(const lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
#if LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_TINY
return obj->ext_click_pad_ver
#elif LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_FULL
@ -1830,6 +1963,8 @@ lv_coord_t lv_obj_get_ext_click_pad_bottom(const lv_obj_t * obj)
*/
lv_coord_t lv_obj_get_ext_draw_pad(const lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
return obj->ext_draw_pad;
}
@ -1844,6 +1979,8 @@ lv_coord_t lv_obj_get_ext_draw_pad(const lv_obj_t * obj)
*/
const lv_style_t * lv_obj_get_style(const lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
const lv_style_t * style_act = obj->style_p;
if(style_act == NULL) {
lv_obj_t * par = obj->par;
@ -1892,6 +2029,8 @@ const lv_style_t * lv_obj_get_style(const lv_obj_t * obj)
*/
bool lv_obj_get_hidden(const lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
return obj->hidden == 0 ? false : true;
}
@ -1902,6 +2041,8 @@ bool lv_obj_get_hidden(const lv_obj_t * obj)
*/
bool lv_obj_get_click(const lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
return obj->click == 0 ? false : true;
}
@ -1912,6 +2053,8 @@ bool lv_obj_get_click(const lv_obj_t * obj)
*/
bool lv_obj_get_top(const lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
return obj->top == 0 ? false : true;
}
@ -1922,6 +2065,8 @@ bool lv_obj_get_top(const lv_obj_t * obj)
*/
bool lv_obj_get_drag(const lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
return obj->drag == 0 ? false : true;
}
@ -1932,6 +2077,8 @@ bool lv_obj_get_drag(const lv_obj_t * obj)
*/
lv_drag_dir_t lv_obj_get_drag_dir(const lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
return obj->drag_dir;
}
@ -1942,6 +2089,8 @@ lv_drag_dir_t lv_obj_get_drag_dir(const lv_obj_t * obj)
*/
bool lv_obj_get_drag_throw(const lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
return obj->drag_throw == 0 ? false : true;
}
@ -1962,6 +2111,8 @@ bool lv_obj_get_drag_parent(const lv_obj_t * obj)
*/
bool lv_obj_get_parent_event(const lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
return obj->parent_event == 0 ? false : true;
}
@ -1991,6 +2142,8 @@ lv_bidi_dir_t lv_obj_get_base_dir(const lv_obj_t * obj)
*/
lv_opa_t lv_obj_get_opa_scale_enable(const lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
return obj->opa_scale_en == 0 ? false : true;
}
@ -2001,6 +2154,8 @@ lv_opa_t lv_obj_get_opa_scale_enable(const lv_obj_t * obj)
*/
lv_opa_t lv_obj_get_opa_scale(const lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
const lv_obj_t * parent = obj;
while(parent) {
@ -2018,6 +2173,8 @@ lv_opa_t lv_obj_get_opa_scale(const lv_obj_t * obj)
*/
uint8_t lv_obj_get_protect(const lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
return obj->protect;
}
@ -2029,6 +2186,8 @@ uint8_t lv_obj_get_protect(const lv_obj_t * obj)
*/
bool lv_obj_is_protected(const lv_obj_t * obj, uint8_t prot)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
return (obj->protect & prot) == 0 ? false : true;
}
@ -2039,6 +2198,8 @@ bool lv_obj_is_protected(const lv_obj_t * obj, uint8_t prot)
*/
lv_signal_cb_t lv_obj_get_signal_cb(const lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
return obj->signal_cb;
}
@ -2049,6 +2210,8 @@ lv_signal_cb_t lv_obj_get_signal_cb(const lv_obj_t * obj)
*/
lv_design_cb_t lv_obj_get_design_cb(const lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
return obj->design_cb;
}
@ -2059,6 +2222,8 @@ lv_design_cb_t lv_obj_get_design_cb(const lv_obj_t * obj)
*/
lv_event_cb_t lv_obj_get_event_cb(const lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
return obj->event_cb;
}
@ -2074,6 +2239,8 @@ lv_event_cb_t lv_obj_get_event_cb(const lv_obj_t * obj)
*/
void * lv_obj_get_ext_attr(const lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
return obj->ext_attr;
}
@ -2085,6 +2252,9 @@ void * lv_obj_get_ext_attr(const lv_obj_t * obj)
*/
void lv_obj_get_type(lv_obj_t * obj, lv_obj_type_t * buf)
{
LV_ASSERT_NULL(buf);
LV_ASSERT_NULL(obj);
lv_obj_type_t tmp;
memset(buf, 0, sizeof(lv_obj_type_t));
@ -2113,6 +2283,8 @@ void lv_obj_get_type(lv_obj_t * obj, lv_obj_type_t * buf)
*/
lv_obj_user_data_t lv_obj_get_user_data(lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
return obj->user_data;
}
@ -2123,6 +2295,8 @@ lv_obj_user_data_t lv_obj_get_user_data(lv_obj_t * obj)
*/
lv_obj_user_data_t * lv_obj_get_user_data_ptr(lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
return &obj->user_data;
}
@ -2133,6 +2307,8 @@ lv_obj_user_data_t * lv_obj_get_user_data_ptr(lv_obj_t * obj)
*/
void lv_obj_set_user_data(lv_obj_t * obj, lv_obj_user_data_t data)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
memcpy(&obj->user_data, &data, sizeof(lv_obj_user_data_t));
}
#endif
@ -2145,6 +2321,8 @@ void lv_obj_set_user_data(lv_obj_t * obj, lv_obj_user_data_t data)
*/
void * lv_obj_get_group(const lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
return obj->group_p;
}
@ -2155,6 +2333,8 @@ void * lv_obj_get_group(const lv_obj_t * obj)
*/
bool lv_obj_is_focused(const lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
if(obj->group_p) {
if(lv_group_get_focused(obj->group_p) == obj) return true;
}
@ -2163,12 +2343,37 @@ bool lv_obj_is_focused(const lv_obj_t * obj)
}
#endif
/*-------------------
* OTHER FUNCTIONS
*------------------*/
/**
* Used in the signal callback to handle `LV_SIGNAL_GET_TYPE` signal
* @param obj pointer to an object
* @param buf pointer to `lv_obj_type_t`. (`param` i nteh signal callback)
* @param name name of the object. E.g. "lv_btn". (Only teh pointer is saved)
* @return LV_RES_OK
*/
lv_res_t lv_obj_handle_get_type_signal(lv_obj_type_t * buf, const char * name)
{
uint8_t i;
for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/
if(buf->type[i] == NULL) break;
}
buf->type[i] = name;
return LV_RES_OK;
}
/**********************
* STATIC FUNCTIONS
**********************/
static void lv_obj_del_async_cb(void * obj)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
lv_obj_del(obj);
}
@ -2229,24 +2434,19 @@ static bool lv_obj_design(lv_obj_t * obj, const lv_area_t * mask_p, lv_design_mo
*/
static lv_res_t lv_obj_signal(lv_obj_t * obj, lv_signal_t sign, void * param)
{
(void)param;
if(sign == LV_SIGNAL_GET_TYPE) return lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
lv_res_t res = LV_RES_OK;
const lv_style_t * style = lv_obj_get_style(obj);
if(sign == LV_SIGNAL_CHILD_CHG) {
/*Return 'invalid' if the child change signal is not enabled*/
if(lv_obj_is_protected(obj, LV_PROTECT_CHILD_CHG) != false) res = LV_RES_INV;
} else if(sign == LV_SIGNAL_REFR_EXT_DRAW_PAD) {
const lv_style_t * style = lv_obj_get_style(obj);
if(style->body.shadow.width > obj->ext_draw_pad) obj->ext_draw_pad = style->body.shadow.width;
} else if(sign == LV_SIGNAL_STYLE_CHG) {
lv_obj_refresh_ext_draw_pad(obj);
} else if(sign == LV_SIGNAL_GET_TYPE) {
lv_obj_type_t * buf = param;
buf->type[0] = "lv_obj";
}
return res;
}
@ -2367,13 +2567,13 @@ static void delete_children(lv_obj_t * obj)
indev = lv_indev_get_next(indev);
}
/* Clean up the object specific data*/
obj->signal_cb(obj, LV_SIGNAL_CLEANUP, NULL);
/*Remove the object from parent's children list*/
lv_obj_t * par = lv_obj_get_parent(obj);
lv_ll_rem(&(par->child_ll), obj);
/* Clean up the object specific data*/
obj->signal_cb(obj, LV_SIGNAL_CLEANUP, NULL);
/*Delete the base objects*/
if(obj->ext_attr != NULL) lv_mem_free(obj->ext_attr);
lv_mem_free(obj); /*Free the object itself*/

View File

@ -968,6 +968,18 @@ bool lv_obj_is_focused(const lv_obj_t * obj);
#endif
/*-------------------
* OTHER FUNCTIONS
*------------------*/
/**
* Used in the signal callback to handle `LV_SIGNAL_GET_TYPE` signal
* @param buf pointer to `lv_obj_type_t`. (`param` i nteh signal callback)
* @param name name of the object. E.g. "lv_btn". (Only teh pointer is saved)
* @return LV_RES_OK
*/
lv_res_t lv_obj_handle_get_type_signal(lv_obj_type_t * buf, const char * name);
/**********************
* MACROS
**********************/

View File

@ -7,6 +7,7 @@
* INCLUDES
*********************/
#include "lv_obj.h"
#include "../lv_core/lv_debug.h"
#include "../lv_misc/lv_mem.h"
#include "../lv_misc/lv_anim.h"
@ -106,6 +107,12 @@ void lv_style_init(void)
lv_style_scr.line.width = 2;
lv_style_scr.line.rounded = 0;
#if LV_USE_DEBUG
#if LV_USE_ASSERT_STYLE
lv_style_scr.debug_sentinel = LV_STYLE_DEGUG_SENTINEL_VALUE;
#endif
#endif
/*Plain style (by default near the same as the screen style)*/
lv_style_copy(&lv_style_plain, &lv_style_scr);
lv_style_plain.body.padding.left = LV_DPI / 20;
@ -287,7 +294,7 @@ void lv_style_anim_init(lv_anim_t * a)
lv_style_anim_dsc_t * dsc;
dsc = lv_mem_alloc(sizeof(lv_style_anim_dsc_t));
lv_mem_assert(dsc);
LV_ASSERT_MEM(dsc);
if(dsc == NULL) return;
dsc->ready_cb = NULL;
dsc->style_anim = NULL;

View File

@ -23,6 +23,9 @@ extern "C" {
* DEFINES
*********************/
#define LV_RADIUS_CIRCLE (LV_COORD_MAX) /**< A very big radius to always draw as circle*/
#define LV_STYLE_DEGUG_SENTINEL_VALUE 0x12345678
LV_EXPORT_CONST_INT(LV_RADIUS_CIRCLE);
/**********************
* TYPEDEFS
@ -119,6 +122,13 @@ typedef struct
lv_opa_t opa;
uint8_t rounded : 1; /**< 1: rounded line endings*/
} line;
#if LV_USE_DEBUG
#if LV_USE_ASSERT_STYLE
uint32_t debug_sentinel; /**<Should `LV_STYLE_DEGUG_SENTINEL_VALUE` to indicate that the style is valid*/
#endif
#endif
} lv_style_t;
#if LV_USE_ANIMATION
@ -272,6 +282,18 @@ extern lv_style_t lv_style_btn_ina;
* MACROS
**********************/
/**
* Create and initialize a `static` style
* Example:
* LV_STYLE_CREATE(my_style, &lv_style_plain);
* is equivalent to
* static lv_style_t my_style;
* lv_style_copy(my_style, &lv_style_plain);
*
* If the style to copy is `NULL` `lv_style_plain` will be used.
*/
#define LV_STYLE_CREATE(name, copy_p) static lv_style_t name; lv_style_copy(&name, copy_p == NULL ? &lv_style_plain : copy_p);
#ifdef __cplusplus
} /* extern "C" */
#endif

View File

@ -10,6 +10,7 @@
#include <stdio.h>
#include <stdbool.h>
#include "lv_draw.h"
#include "../lv_core/lv_debug.h"
#include "../lv_misc/lv_math.h"
#include "../lv_misc/lv_log.h"
#include "../lv_misc/lv_math.h"
@ -60,12 +61,12 @@ void * lv_draw_get_buf(uint32_t size)
if(LV_GC_ROOT(_lv_draw_buf) == NULL) {
LV_GC_ROOT(_lv_draw_buf) = lv_mem_alloc(size);
lv_mem_assert(LV_GC_ROOT(_lv_draw_buf));
LV_ASSERT_MEM(LV_GC_ROOT(_lv_draw_buf));
return LV_GC_ROOT(_lv_draw_buf);
}
LV_GC_ROOT(_lv_draw_buf) = lv_mem_realloc(LV_GC_ROOT(_lv_draw_buf), size);
lv_mem_assert(LV_GC_ROOT(_lv_draw_buf));
LV_ASSERT_MEM(LV_GC_ROOT(_lv_draw_buf));
return LV_GC_ROOT(_lv_draw_buf);
}

View File

@ -259,6 +259,9 @@ void lv_draw_letter(const lv_point_t * pos_p, const lv_area_t * mask_p, const lv
uint8_t bitmask_init;
uint8_t bitmask;
/*bpp = 3 should be converted to bpp = 4 in lv_font_get_glyph_bitmap */
if(g.bpp == 3) g.bpp = 4;
switch(g.bpp) {
case 1:
bpp_opa_table = bpp1_opa_table;

View File

@ -9,6 +9,7 @@
#include "lv_draw_img.h"
#include "lv_img_cache.h"
#include "../lv_misc/lv_log.h"
#include "../lv_misc/lv_mem.h"
/*********************
* DEFINES
@ -401,10 +402,14 @@ bool lv_img_color_format_is_chroma_keyed(lv_img_cf_t cf)
switch(cf) {
case LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED:
case LV_IMG_CF_RAW_CHROMA_KEYED:
#if LV_INDEXED_CHROMA
case LV_IMG_CF_INDEXED_1BIT:
case LV_IMG_CF_INDEXED_2BIT:
case LV_IMG_CF_INDEXED_4BIT:
case LV_IMG_CF_INDEXED_8BIT: is_chroma_keyed = true; break;
case LV_IMG_CF_INDEXED_8BIT:
#endif
is_chroma_keyed = true; break;
default: is_chroma_keyed = false; break;
}
@ -423,6 +428,10 @@ bool lv_img_color_format_has_alpha(lv_img_cf_t cf)
switch(cf) {
case LV_IMG_CF_TRUE_COLOR_ALPHA:
case LV_IMG_CF_RAW_ALPHA:
case LV_IMG_CF_INDEXED_1BIT:
case LV_IMG_CF_INDEXED_2BIT:
case LV_IMG_CF_INDEXED_4BIT:
case LV_IMG_CF_INDEXED_8BIT:
case LV_IMG_CF_ALPHA_1BIT:
case LV_IMG_CF_ALPHA_2BIT:
case LV_IMG_CF_ALPHA_4BIT:
@ -464,6 +473,66 @@ lv_img_src_t lv_img_src_get_type(const void * src)
return img_src_type;
}
lv_img_dsc_t *lv_img_buf_alloc(lv_coord_t w, lv_coord_t h, lv_img_cf_t cf)
{
/* Allocate image descriptor */
lv_img_dsc_t *dsc = lv_mem_alloc(sizeof(lv_img_dsc_t));
if(dsc == NULL)
return NULL;
memset(dsc, 0, sizeof(lv_img_dsc_t));
/* Get image data size */
dsc->data_size = lv_img_buf_get_img_size(w, h, cf);
if(dsc->data_size == 0) {
lv_mem_free(dsc);
return NULL;
}
/* Allocate raw buffer */
dsc->data = lv_mem_alloc(dsc->data_size);
if(dsc->data == NULL) {
lv_mem_free(dsc);
return NULL;
}
memset((uint8_t *)dsc->data, 0, dsc->data_size);
/* Fill in header */
dsc->header.always_zero = 0;
dsc->header.w = w;
dsc->header.h = h;
dsc->header.cf = cf;
return dsc;
}
void lv_img_buf_free(lv_img_dsc_t *dsc)
{
if(dsc != NULL) {
if(dsc->data != NULL)
lv_mem_free(dsc->data);
lv_mem_free(dsc);
}
}
uint32_t lv_img_buf_get_img_size(lv_coord_t w, lv_coord_t h, lv_img_cf_t cf)
{
switch(cf) {
case LV_IMG_CF_TRUE_COLOR: return LV_IMG_BUF_SIZE_TRUE_COLOR(w, h);
case LV_IMG_CF_TRUE_COLOR_ALPHA: return LV_IMG_BUF_SIZE_TRUE_COLOR_ALPHA(w, h);
case LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED: return LV_IMG_BUF_SIZE_TRUE_COLOR_CHROMA_KEYED(w, h);
case LV_IMG_CF_ALPHA_1BIT: return LV_IMG_BUF_SIZE_ALPHA_1BIT(w, h);
case LV_IMG_CF_ALPHA_2BIT: return LV_IMG_BUF_SIZE_ALPHA_2BIT(w, h);
case LV_IMG_CF_ALPHA_4BIT: return LV_IMG_BUF_SIZE_ALPHA_4BIT(w, h);
case LV_IMG_CF_ALPHA_8BIT: return LV_IMG_BUF_SIZE_ALPHA_8BIT(w, h);
case LV_IMG_CF_INDEXED_1BIT: return LV_IMG_BUF_SIZE_INDEXED_1BIT(w, h);
case LV_IMG_CF_INDEXED_2BIT: return LV_IMG_BUF_SIZE_INDEXED_2BIT(w, h);
case LV_IMG_CF_INDEXED_4BIT: return LV_IMG_BUF_SIZE_INDEXED_4BIT(w, h);
case LV_IMG_CF_INDEXED_8BIT: return LV_IMG_BUF_SIZE_INDEXED_8BIT(w, h);
default: return 0;
}
}
/**********************
* STATIC FUNCTIONS
**********************/
@ -506,7 +575,7 @@ static lv_res_t lv_img_draw_core(const lv_area_t * coords, const lv_area_t * mas
else {
lv_coord_t width = lv_area_get_width(&mask_com);
uint8_t * buf = lv_draw_get_buf(lv_area_get_width(&mask_com) * ((LV_COLOR_DEPTH >> 3) + 1)); /*+1 because of the possible alpha byte*/
uint8_t * buf = lv_draw_get_buf(lv_area_get_width(&mask_com) * LV_IMG_PX_SIZE_ALPHA_BYTE); /*space for the possible alpha byte*/
lv_area_t line;
lv_area_copy(&line, &mask_com);

View File

@ -20,6 +20,26 @@ extern "C" {
* DEFINES
*********************/
/**********************
* MACROS
**********************/
#define LV_IMG_BUF_SIZE_TRUE_COLOR(w, h) ((LV_COLOR_SIZE / 8) * w * h)
#define LV_IMG_BUF_SIZE_TRUE_COLOR_CHROMA_KEYED(w, h) ((LV_COLOR_SIZE / 8) * w * h)
#define LV_IMG_BUF_SIZE_TRUE_COLOR_ALPHA(w, h) (LV_IMG_PX_SIZE_ALPHA_BYTE * w * h)
/*+ 1: to be sure no fractional row*/
#define LV_IMG_BUF_SIZE_ALPHA_1BIT(w, h) ((((w / 8) + 1) * h))
#define LV_IMG_BUF_SIZE_ALPHA_2BIT(w, h) ((((w / 4) + 1) * h))
#define LV_IMG_BUF_SIZE_ALPHA_4BIT(w, h) ((((w / 2) + 1) * h))
#define LV_IMG_BUF_SIZE_ALPHA_8BIT(w, h) ((w * h))
/*4 * X: for palette*/
#define LV_IMG_BUF_SIZE_INDEXED_1BIT(w, h) (LV_IMG_BUF_SIZE_ALPHA_1BIT(w, h) + 4 * 2)
#define LV_IMG_BUF_SIZE_INDEXED_2BIT(w, h) (LV_IMG_BUF_SIZE_ALPHA_2BIT(w, h) + 4 * 4)
#define LV_IMG_BUF_SIZE_INDEXED_4BIT(w, h) (LV_IMG_BUF_SIZE_ALPHA_4BIT(w, h) + 4 * 16)
#define LV_IMG_BUF_SIZE_INDEXED_8BIT(w, h) (LV_IMG_BUF_SIZE_ALPHA_8BIT(w, h) + 4 * 256)
/**********************
* TYPEDEFS
**********************/
@ -120,9 +140,30 @@ bool lv_img_color_format_is_chroma_keyed(lv_img_cf_t cf);
*/
bool lv_img_color_format_has_alpha(lv_img_cf_t cf);
/**********************
* MACROS
**********************/
/**
* Allocate an image buffer in RAM
* @param w width of image
* @param h height of image
* @param cf a color format (`LV_IMG_CF_...`)
* @return an allocated image, or NULL on failure
*/
lv_img_dsc_t *lv_img_buf_alloc(lv_coord_t w, lv_coord_t h, lv_img_cf_t cf);
/**
* Free an allocated image buffer
* @param dsc image buffer to free
*/
void lv_img_buf_free(lv_img_dsc_t *dsc);
/**
* Get the memory consumption of a raw bitmap, given color format and dimensions.
* @param w width
* @param h height
* @param cf color format
* @return size in bytes
*/
uint32_t lv_img_buf_get_img_size(lv_coord_t w, lv_coord_t h, lv_img_cf_t cf);
#ifdef __cplusplus
} /* extern "C" */

View File

@ -60,6 +60,13 @@ void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_st
{
const lv_font_t * font = style->text.font;
lv_coord_t w;
/*No need to waste processor time if string is empty*/
if (txt[0] == '\0')
{
return;
}
if((flag & LV_TXT_FLAG_EXPAND) == 0) {
/*Normally use the label's width as width*/
w = lv_area_get_width(coords);

View File

@ -6,7 +6,10 @@
/*********************
* INCLUDES
*********************/
#include "../lv_core/lv_debug.h"
#include "lv_img_cache.h"
#include "lv_img_decoder.h"
#include "lv_draw_img.h"
#include "../lv_hal/lv_hal_tick.h"
#include "../lv_misc/lv_gc.h"
@ -79,7 +82,15 @@ lv_img_cache_entry_t * lv_img_cache_open(const void * src, const lv_style_t * st
/*Is the image cached?*/
lv_img_cache_entry_t * cached_src = NULL;
for(i = 0; i < entry_cnt; i++) {
if(cache[i].dec_dsc.src == src) {
bool match = false;
lv_img_src_t src_type = lv_img_src_get_type(cache[i].dec_dsc.src);
if(src_type == LV_IMG_SRC_VARIABLE) {
if(cache[i].dec_dsc.src == src) match = true;
} else if(src_type == LV_IMG_SRC_FILE) {
if(strcmp(cache[i].dec_dsc.src, src) == 0) match = true;
}
if(match) {
/* If opened increment its life.
* Image difficult to open should live longer to keep avoid frequent their recaching.
* Therefore increase `life` with `time_to_open`*/
@ -152,7 +163,7 @@ void lv_img_cache_set_size(uint16_t new_entry_cnt)
/*Reallocate the cache*/
LV_GC_ROOT(_lv_img_cache_array) = lv_mem_alloc(sizeof(lv_img_cache_entry_t) * new_entry_cnt);
lv_mem_assert(LV_GC_ROOT(_lv_img_cache_array));
LV_ASSERT_MEM(LV_GC_ROOT(_lv_img_cache_array));
if(LV_GC_ROOT(_lv_img_cache_array) == NULL) {
entry_cnt = 0;
return;

View File

@ -7,6 +7,7 @@
* INCLUDES
*********************/
#include "lv_img_decoder.h"
#include "../lv_core/lv_debug.h"
#include "../lv_draw/lv_draw_img.h"
#include "../lv_misc/lv_ll.h"
#include "../lv_misc/lv_color.h"
@ -31,6 +32,7 @@ typedef struct
lv_fs_file_t * f;
#endif
lv_color_t * palette;
lv_opa_t * opa;
} lv_img_decoder_built_in_data_t;
/**********************
@ -68,7 +70,7 @@ void lv_img_decoder_init(void)
decoder = lv_img_decoder_create();
if(decoder == NULL) {
LV_LOG_WARN("lv_img_decoder_init: out of memory");
lv_mem_assert(decoder);
LV_ASSERT_MEM(decoder);
return;
}
@ -118,10 +120,17 @@ lv_res_t lv_img_decoder_get_info(const char * src, lv_img_header_t * header)
lv_res_t lv_img_decoder_open(lv_img_decoder_dsc_t * dsc, const void * src, const lv_style_t * style)
{
dsc->style = style;
dsc->src = src;
dsc->src_type = lv_img_src_get_type(src);
dsc->user_data = NULL;
if(dsc->src_type == LV_IMG_SRC_FILE) {
uint16_t fnlen = strlen(src);
dsc->src = lv_mem_alloc(fnlen + 1);
strcpy((char *)dsc->src, src);
} else {
dsc->src = src;
}
lv_res_t res = LV_RES_INV;
lv_img_decoder_t * d;
@ -175,6 +184,11 @@ void lv_img_decoder_close(lv_img_decoder_dsc_t * dsc)
{
if(dsc->decoder) {
if(dsc->decoder->close_cb) dsc->decoder->close_cb(dsc->decoder, dsc);
if(dsc->src_type == LV_IMG_SRC_FILE) {
lv_mem_free(dsc->src);
dsc->src = NULL;
}
}
}
@ -186,7 +200,7 @@ lv_img_decoder_t * lv_img_decoder_create(void)
{
lv_img_decoder_t * decoder;
decoder = lv_ll_ins_head(&LV_GC_ROOT(_lv_img_defoder_ll));
lv_mem_assert(decoder);
LV_ASSERT_MEM(decoder);
if(decoder == NULL) return NULL;
memset(decoder, 0, sizeof(lv_img_decoder_t));
@ -321,7 +335,7 @@ lv_res_t lv_img_decoder_built_in_open(lv_img_decoder_t * decoder, lv_img_decoder
dsc->user_data = lv_mem_alloc(sizeof(lv_img_decoder_built_in_data_t));
if(dsc->user_data == NULL) {
LV_LOG_ERROR("img_decoder_built_in_open: out of memory");
lv_mem_assert(dsc->user_data);
LV_ASSERT_MEM(dsc->user_data);
}
memset(dsc->user_data, 0, sizeof(lv_img_decoder_built_in_data_t));
}
@ -330,7 +344,7 @@ lv_res_t lv_img_decoder_built_in_open(lv_img_decoder_t * decoder, lv_img_decoder
user_data->f = lv_mem_alloc(sizeof(f));
if(user_data->f == NULL) {
LV_LOG_ERROR("img_decoder_built_in_open: out of memory");
lv_mem_assert(user_data->f);
LV_ASSERT_MEM(user_data->f);
}
memcpy(user_data->f, &f, sizeof(f));
@ -368,17 +382,18 @@ lv_res_t lv_img_decoder_built_in_open(lv_img_decoder_t * decoder, lv_img_decoder
dsc->user_data = lv_mem_alloc(sizeof(lv_img_decoder_built_in_data_t));
if(dsc->user_data == NULL) {
LV_LOG_ERROR("img_decoder_built_in_open: out of memory");
lv_mem_assert(dsc->user_data);
LV_ASSERT_MEM(dsc->user_data);
}
memset(dsc->user_data, 0, sizeof(lv_img_decoder_built_in_data_t));
}
lv_img_decoder_built_in_data_t * user_data = dsc->user_data;
user_data->palette = lv_mem_alloc(palette_size * sizeof(lv_color_t));
if(user_data->palette == NULL) {
user_data->opa = lv_mem_alloc(palette_size * sizeof(lv_opa_t));
if(user_data->palette == NULL || user_data->opa == NULL) {
LV_LOG_ERROR("img_decoder_built_in_open: out of memory");
#if LV_USE_FILESYSTEM
lv_mem_assert(user_data->f);
LV_ASSERT_MEM(user_data->f);
#endif
}
@ -386,7 +401,13 @@ lv_res_t lv_img_decoder_built_in_open(lv_img_decoder_t * decoder, lv_img_decoder
/*Read the palette from file*/
#if LV_USE_FILESYSTEM
lv_fs_seek(user_data->f, 4); /*Skip the header*/
lv_fs_read(user_data->f, user_data->palette, palette_size * sizeof(lv_color_t), NULL);
lv_color32_t cur_color;
uint32_t i;
for(i = 0; i < palette_size; i++) {
lv_fs_read(user_data->f, &cur_color, sizeof(lv_color32_t), NULL);
user_data->palette[i] = lv_color_make(cur_color.ch.red, cur_color.ch.green, cur_color.ch.blue);
user_data->opa[i] = cur_color.ch.alpha;
}
#else
LV_LOG_WARN("Image built-in decoder can read the palette because LV_USE_FILESYSTEM = 0");
return LV_RES_INV;
@ -398,6 +419,7 @@ lv_res_t lv_img_decoder_built_in_open(lv_img_decoder_t * decoder, lv_img_decoder
uint32_t i;
for(i = 0; i < palette_size; i++) {
user_data->palette[i] = lv_color_make(palette_p[i].ch.red, palette_p[i].ch.green, palette_p[i].ch.blue);
user_data->opa[i] = palette_p[i].ch.alpha;
}
}
@ -699,13 +721,24 @@ static lv_res_t lv_img_decoder_built_in_line_indexed(lv_img_decoder_dsc_t * dsc,
#endif
}
uint8_t byte_act = 0;
uint8_t val_act;
lv_coord_t i;
lv_color_t * cbuf = (lv_color_t *)buf;
for(i = 0; i < len; i++) {
val_act = (data_tmp[byte_act] & (mask << pos)) >> pos;
cbuf[i] = user_data->palette[val_act];
val_act = (*data_tmp & (mask << pos)) >> pos;
lv_color_t color = user_data->palette[val_act];
#if LV_COLOR_DEPTH == 8 || LV_COLOR_DEPTH == 1
buf[i * LV_IMG_PX_SIZE_ALPHA_BYTE] = color.full;
#elif LV_COLOR_DEPTH == 16
/*Because of Alpha byte 16 bit color can start on odd address which can cause crash*/
buf[i * LV_IMG_PX_SIZE_ALPHA_BYTE] = color.full & 0xFF;
buf[i * LV_IMG_PX_SIZE_ALPHA_BYTE + 1] = (color.full >> 8) & 0xFF;
#elif LV_COLOR_DEPTH == 32
*((uint32_t *)&buf[i * LV_IMG_PX_SIZE_ALPHA_BYTE]) = color.full;
#else
#error "Invalid LV_COLOR_DEPTH. Check it in lv_conf.h"
#endif
buf[i * LV_IMG_PX_SIZE_ALPHA_BYTE + LV_IMG_PX_SIZE_ALPHA_BYTE - 1] = user_data->opa[val_act];
pos -= px_size;
if(pos < 0) {

View File

@ -8,9 +8,12 @@
*********************/
#include "lv_font.h"
#include "lv_font_fmt_txt.h"
#include "../lv_core/lv_debug.h"
#include "../lv_draw/lv_draw.h"
#include "../lv_misc/lv_types.h"
#include "../lv_misc/lv_log.h"
#include "../lv_misc/lv_utils.h"
#include "../lv_misc/lv_mem.h"
/*********************
* DEFINES
@ -19,6 +22,11 @@
/**********************
* TYPEDEFS
**********************/
typedef enum {
RLE_STATE_SINGLE = 0,
RLE_STATE_REPEATE,
RLE_STATE_COUNTER,
}rle_state_t;
/**********************
* STATIC PROTOTYPES
@ -29,10 +37,25 @@ static int32_t unicode_list_compare(const void * ref, const void * element);
static int32_t kern_pair_8_compare(const void * ref, const void * element);
static int32_t kern_pair_16_compare(const void * ref, const void * element);
static void decompress(const uint8_t * in, uint8_t * out, lv_coord_t w, lv_coord_t h, uint8_t bpp);
static void decompress_line(uint8_t * out, lv_coord_t w);
static uint8_t get_bits(const uint8_t * in, uint32_t bit_pos, uint8_t len);
static void bits_write(uint8_t * out, uint32_t bit_pos, uint8_t val, uint8_t len);
static void rle_init(const uint8_t * in, uint8_t bpp);
static uint8_t rle_next(void);
/**********************
* STATIC VARIABLES
**********************/
static uint32_t rle_rdp;
static const uint8_t * rle_in;
static uint8_t rle_bpp;
static uint8_t rle_prev_v;
static uint8_t rle_cnt;
static rle_state_t rle_state;
/**********************
* GLOBAL PROTOTYPES
**********************/
@ -59,7 +82,32 @@ const uint8_t * lv_font_get_bitmap_fmt_txt(const lv_font_t * font, uint32_t unic
const lv_font_fmt_txt_glyph_dsc_t * gdsc = &fdsc->glyph_dsc[gid];
if(gdsc) return &fdsc->glyph_bitmap[gdsc->bitmap_index];
if(fdsc->bitmap_format == LV_FONT_FMT_TXT_PLAIN) {
if(gdsc) return &fdsc->glyph_bitmap[gdsc->bitmap_index];
}
/*Handle compressed bitmap*/
else
{
static uint8_t * buf = NULL;
uint32_t gsize = gdsc->box_w * gdsc->box_h;
uint32_t buf_size = gsize;
switch(fdsc->bpp) {
case 1: buf_size = gsize >> 3; break;
case 2: buf_size = gsize >> 2; break;
case 3: buf_size = gsize >> 1; break;
case 4: buf_size = gsize >> 1; break;
}
if(lv_mem_get_size(buf) < buf_size) {
buf = lv_mem_realloc(buf, buf_size);
LV_ASSERT_MEM(buf);
if(buf == NULL) return NULL;
}
decompress(&fdsc->glyph_bitmap[gdsc->bitmap_index], buf, gdsc->box_w , gdsc->box_h, fdsc->bpp);
return buf;
}
/*If not returned earlier then the letter is not found in this font*/
return NULL;
@ -238,6 +286,176 @@ static int32_t kern_pair_16_compare(const void * ref, const void * element)
else return (int32_t) ref16_p[1] - element16_p[1];
}
/**
* The compress a glyph's bitmap
* @param in the compressed bitmap
* @param out buffer to store the result
* @param px_num number of pixels in the glyph (width * height)
* @param bpp bit per pixel (bpp = 3 will be converted to bpp = 4)
*/
static void decompress(const uint8_t * in, uint8_t * out, lv_coord_t w, lv_coord_t h, uint8_t bpp)
{
uint32_t wrp = 0;
uint8_t wr_size = bpp;
if(bpp == 3) wr_size = 4;
rle_init(in, bpp);
uint8_t * line_buf = lv_draw_get_buf(w * 2);
uint8_t * line_buf1 = line_buf;
uint8_t * line_buf2 = line_buf + w;
decompress_line(line_buf1, w);
lv_coord_t y;
lv_coord_t x;
for(x = 0; x < w; x++) {
bits_write(out,wrp, line_buf1[x], bpp);
wrp += wr_size;
}
for(y = 1; y < h; y++) {
decompress_line(line_buf2, w);
for(x = 0; x < w; x++) {
line_buf1[x] = line_buf2[x] ^ line_buf1[x];
bits_write(out,wrp, line_buf1[x], bpp);
wrp += wr_size;
}
}
}
/**
* Decompress one line. Store one pixel per byte
* @param out output buffer
* @param w width of the line in pixel count
*/
static void decompress_line(uint8_t * out, lv_coord_t w)
{
lv_coord_t i;
for(i = 0; i < w; i++) {
out[i] = rle_next();
}
}
/**
* Read bits from an input buffer. The read can cross byte boundary.
* @param in the input buffer to read from.
* @param bit_pos index of teh first bit to read.
* @param len number of bits to read (must be <= 8).
* @return the read bits
*/
static uint8_t get_bits(const uint8_t * in, uint32_t bit_pos, uint8_t len)
{
uint8_t res = 0;
uint32_t byte_pos = bit_pos >> 3;
bit_pos = bit_pos & 0x7;
uint8_t bit_mask = (uint16_t)((uint16_t) 1 << len) - 1;
uint16_t in16 = (in[byte_pos] << 8) + in[byte_pos + 1];
res = (in16 >> (16 - bit_pos - len)) & bit_mask;
return res;
}
/**
* Write `val` data to `bit_pos` position of `out`. The write can NOT cross byte boundary.
* @param out buffer where to write
* @param bit_pos bit index to write
* @param val value to write
* @param len length of bits to write from `val`. (Counted from the LSB).
* @note `len == 3` will be converted to `len = 4` and `val` will be upscaled too
*/
static void bits_write(uint8_t * out, uint32_t bit_pos, uint8_t val, uint8_t len)
{
if(len == 3) {
len = 4;
switch(val) {
case 0: val = 0; break;
case 1: val = 2; break;
case 2: val = 4; break;
case 3: val = 6; break;
case 4: val = 9; break;
case 5: val = 11; break;
case 6: val = 13; break;
case 7: val = 15; break;
}
}
uint16_t byte_pos = bit_pos >> 3;
bit_pos = bit_pos & 0x7;
bit_pos = 8 - bit_pos - len;
uint8_t bit_mask = (uint16_t)((uint16_t) 1 << len) - 1;
out[byte_pos] &= ((~bit_mask) << bit_pos);
out[byte_pos] |= (val << bit_pos);
}
static void rle_init(const uint8_t * in, uint8_t bpp)
{
rle_in = in;
rle_bpp = bpp;
rle_state = RLE_STATE_SINGLE;
rle_rdp = 0;
rle_prev_v = 0;
rle_cnt = 0;
}
static uint8_t rle_next(void)
{
uint8_t v = 0;
uint8_t ret = 0;
if(rle_state == RLE_STATE_SINGLE) {
ret = get_bits(rle_in, rle_rdp, rle_bpp);
if(rle_rdp != 0 && rle_prev_v == ret) {
rle_cnt = 0;
rle_state = RLE_STATE_REPEATE;
}
rle_prev_v = ret;
rle_rdp += rle_bpp;
}
else if(rle_state == RLE_STATE_REPEATE) {
v = get_bits(rle_in, rle_rdp, 1);
rle_cnt++;
rle_rdp += 1;
if(v == 1) {
ret = rle_prev_v;
if(rle_cnt == 11) {
rle_cnt = get_bits(rle_in, rle_rdp, 6);
rle_rdp += 6;
if(rle_cnt != 0) {
rle_state = RLE_STATE_COUNTER;
} else {
ret = get_bits(rle_in, rle_rdp, rle_bpp);
rle_prev_v = ret;
rle_rdp += rle_bpp;
rle_state = RLE_STATE_SINGLE;
}
}
} else {
ret = get_bits(rle_in, rle_rdp, rle_bpp);
rle_prev_v = ret;
rle_rdp += rle_bpp;
rle_state = RLE_STATE_SINGLE;
}
}
else if(rle_state == RLE_STATE_COUNTER) {
ret = rle_prev_v;
rle_cnt--;
if(rle_cnt == 0) {
ret = get_bits(rle_in, rle_rdp, rle_bpp);
rle_prev_v = ret;
rle_rdp += rle_bpp;
rle_state = RLE_STATE_SINGLE;
}
}
return ret;
}
/** Code Comparator.
*
* Compares the value of both input arguments.

View File

@ -45,7 +45,7 @@ typedef struct
uint8_t box_w; /**< Width of the glyph's bounding box*/
uint8_t box_h; /**< Height of the glyph's bounding box*/
int8_t ofs_x; /**< x offset of the bounding box*/
uint8_t ofs_y; /**< y offset of the bounding box. Measured from the top of the line*/
int8_t ofs_y; /**< y offset of the bounding box. Measured from the top of the line*/
}lv_font_fmt_txt_glyph_dsc_t;
@ -141,7 +141,7 @@ typedef struct {
3. value = class_pair_values[(left_class-1)*right_class_cnt + (righ_class-1)]
*/
const uint8_t * class_pair_values; /*left_class_num * right_class_num value*/
const int8_t * class_pair_values; /*left_class_num * right_class_num value*/
const uint8_t * left_class_mapping; /*Map the glyph_ids to classes: index -> glyph_id -> class_id*/
const uint8_t * right_class_mapping; /*Map the glyph_ids to classes: index -> glyph_id -> class_id*/
uint8_t left_class_cnt;
@ -180,7 +180,7 @@ typedef struct {
/*Number of cmap tables*/
uint16_t cmap_num :10;
/*Bit per pixel: 1, 2, 4 or 8*/
/*Bit per pixel: 1, 2, 3, 4*/
uint16_t bpp :3;
/*Type of `kern_dsc`*/

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -311,7 +311,7 @@ static LV_ATTRIBUTE_LARGE_CONST const uint8_t gylph_bitmap[] = {
* GLYPH DESCRIPTION
*--------------------*/
static lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = {
static const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = {
{.bitmap_index = 0, .adv_w = 0, .box_h = 0, .box_w = 0, .ofs_x = 0, .ofs_y = 0} /* id = 0 reserved */,
{.bitmap_index = 0, .adv_w = 128, .box_h = 0, .box_w = 0, .ofs_x = 0, .ofs_y = 0},
{.bitmap_index = 0, .adv_w = 128, .box_h = 7, .box_w = 1, .ofs_x = 3, .ofs_y = -1},
@ -460,4 +460,3 @@ lv_font_t lv_font_unscii_8 = {
};
#endif /*#if LV_FONT_UNSCII_8*/

View File

@ -11,57 +11,72 @@ extern "C" {
#include "../../../lv_conf.h"
#endif
/* In the font converter use this list as range:
61441, 61448, 61451, 61452, 61452, 61453, 61457, 61459, 61461, 61465,
61468, 61473, 61478, 61479, 61480, 61502, 61512, 61515, 61516, 61517,
61521, 61522, 61523, 61524, 61543, 61544, 61550, 61552, 61553, 61556,
61559, 61560, 61561, 61563, 61587, 61589, 61636, 61637, 61639, 61671,
61674, 61683, 61724, 61732, 61787, 61931, 62016, 62017, 62018, 62019,
62020, 62087, 62099, 62212, 62189, 62810, 63426, 63650
*/
#define LV_SYMBOL_AUDIO "\xef\x80\x81"
#define LV_SYMBOL_VIDEO "\xef\x80\x88"
#define LV_SYMBOL_LIST "\xef\x80\x8b"
#define LV_SYMBOL_OK "\xef\x80\x8c"
#define LV_SYMBOL_CLOSE "\xef\x80\x8d"
#define LV_SYMBOL_POWER "\xef\x80\x91"
#define LV_SYMBOL_SETTINGS "\xef\x80\x93"
#define LV_SYMBOL_TRASH "\xef\x80\x94"
#define LV_SYMBOL_HOME "\xef\x80\x95"
#define LV_SYMBOL_DOWNLOAD "\xef\x80\x99"
#define LV_SYMBOL_DRIVE "\xef\x80\x9c"
#define LV_SYMBOL_REFRESH "\xef\x80\xa1"
#define LV_SYMBOL_MUTE "\xef\x80\xa6"
#define LV_SYMBOL_VOLUME_MID "\xef\x80\xa7"
#define LV_SYMBOL_VOLUME_MAX "\xef\x80\xa8"
#define LV_SYMBOL_IMAGE "\xef\x80\xbe"
#define LV_SYMBOL_EDIT "\xef\x81\x80"
#define LV_SYMBOL_PREV "\xef\x81\x88"
#define LV_SYMBOL_PLAY "\xef\x81\x8b"
#define LV_SYMBOL_PAUSE "\xef\x81\x8c"
#define LV_SYMBOL_STOP "\xef\x81\x8d"
#define LV_SYMBOL_NEXT "\xef\x81\x91"
#define LV_SYMBOL_EJECT "\xef\x81\x92"
#define LV_SYMBOL_LEFT "\xef\x81\x93"
#define LV_SYMBOL_RIGHT "\xef\x81\x94"
#define LV_SYMBOL_PLUS "\xef\x81\xa7"
#define LV_SYMBOL_MINUS "\xef\x81\xa8"
#define LV_SYMBOL_WARNING "\xef\x81\xb1"
#define LV_SYMBOL_SHUFFLE "\xef\x81\xb4"
#define LV_SYMBOL_UP "\xef\x81\xb7"
#define LV_SYMBOL_DOWN "\xef\x81\xb8"
#define LV_SYMBOL_LOOP "\xef\x81\xb9"
#define LV_SYMBOL_DIRECTORY "\xef\x81\xbb"
#define LV_SYMBOL_UPLOAD "\xef\x82\x93"
#define LV_SYMBOL_CALL "\xef\x82\x95"
#define LV_SYMBOL_CUT "\xef\x83\x84"
#define LV_SYMBOL_COPY "\xef\x83\x85"
#define LV_SYMBOL_SAVE "\xef\x83\x87"
#define LV_SYMBOL_CHARGE "\xef\x83\xa7"
#define LV_SYMBOL_BELL "\xef\x83\xb3"
#define LV_SYMBOL_KEYBOARD "\xef\x84\x9c"
#define LV_SYMBOL_GPS "\xef\x84\xa4"
#define LV_SYMBOL_FILE "\xef\x85\x9b"
#define LV_SYMBOL_WIFI "\xef\x87\xab"
#define LV_SYMBOL_BATTERY_FULL "\xef\x89\x80"
#define LV_SYMBOL_BATTERY_3 "\xef\x89\x81"
#define LV_SYMBOL_BATTERY_2 "\xef\x89\x82"
#define LV_SYMBOL_BATTERY_1 "\xef\x89\x83"
#define LV_SYMBOL_BATTERY_EMPTY "\xef\x89\x84"
#define LV_SYMBOL_BLUETOOTH "\xef\x8a\x93"
#define LV_SYMBOL_AUDIO "\xef\x80\x81" /*61441, 0xF001*/
#define LV_SYMBOL_VIDEO "\xef\x80\x88" /*61448, 0xF008*/
#define LV_SYMBOL_LIST "\xef\x80\x8b" /*61451, 0xF00B*/
#define LV_SYMBOL_OK "\xef\x80\x8c" /*61452, 0xF00C*/
#define LV_SYMBOL_CLOSE "\xef\x80\x8d" /*61453, 0xF00D*/
#define LV_SYMBOL_POWER "\xef\x80\x91" /*61457, 0xF011*/
#define LV_SYMBOL_SETTINGS "\xef\x80\x93" /*61459, 0xF013*/
#define LV_SYMBOL_HOME "\xef\x80\x95" /*61461, 0xF015*/
#define LV_SYMBOL_DOWNLOAD "\xef\x80\x99" /*61465, 0xF019*/
#define LV_SYMBOL_DRIVE "\xef\x80\x9c" /*61468, 0xF01C*/
#define LV_SYMBOL_REFRESH "\xef\x80\xa1" /*61473, 0xF021*/
#define LV_SYMBOL_MUTE "\xef\x80\xa6" /*61478, 0xF026*/
#define LV_SYMBOL_VOLUME_MID "\xef\x80\xa7" /*61479, 0xF027*/
#define LV_SYMBOL_VOLUME_MAX "\xef\x80\xa8" /*61480, 0xF028*/
#define LV_SYMBOL_IMAGE "\xef\x80\xbe" /*61502, 0xF03E*/
#define LV_SYMBOL_EDIT "\xef\x8C\x84" /*62212, 0xF304*/
#define LV_SYMBOL_PREV "\xef\x81\x88" /*61512, 0xF048*/
#define LV_SYMBOL_PLAY "\xef\x81\x8b" /*61515, 0xF04B*/
#define LV_SYMBOL_PAUSE "\xef\x81\x8c" /*61516, 0xF04C*/
#define LV_SYMBOL_STOP "\xef\x81\x8d" /*61517, 0xF04D*/
#define LV_SYMBOL_NEXT "\xef\x81\x91" /*61521, 0xF051*/
#define LV_SYMBOL_EJECT "\xef\x81\x92" /*61522, 0xF052*/
#define LV_SYMBOL_LEFT "\xef\x81\x93" /*61523, 0xF053*/
#define LV_SYMBOL_RIGHT "\xef\x81\x94" /*61524, 0xF054*/
#define LV_SYMBOL_PLUS "\xef\x81\xa7" /*61543, 0xF067*/
#define LV_SYMBOL_MINUS "\xef\x81\xa8" /*61544, 0xF068*/
#define LV_SYMBOL_EYE_OPEN "\xef\x81\xae" /*61550, 0xF06E*/
#define LV_SYMBOL_EYE_CLOSE "\xef\x81\xb0" /*61552, 0xF070*/
#define LV_SYMBOL_WARNING "\xef\x81\xb1" /*61553, 0xF071*/
#define LV_SYMBOL_SHUFFLE "\xef\x81\xb4" /*61556, 0xF074*/
#define LV_SYMBOL_UP "\xef\x81\xb7" /*61559, 0xF077*/
#define LV_SYMBOL_DOWN "\xef\x81\xb8" /*61560, 0xF078*/
#define LV_SYMBOL_LOOP "\xef\x81\xb9" /*61561, 0xF079*/
#define LV_SYMBOL_DIRECTORY "\xef\x81\xbb" /*61563, 0xF07B*/
#define LV_SYMBOL_UPLOAD "\xef\x82\x93" /*61587, 0xF093*/
#define LV_SYMBOL_CALL "\xef\x82\x95" /*61589, 0xF095*/
#define LV_SYMBOL_CUT "\xef\x83\x84" /*61636, 0xF0C4*/
#define LV_SYMBOL_COPY "\xef\x83\x85" /*61637, 0xF0C5*/
#define LV_SYMBOL_SAVE "\xef\x83\x87" /*61639, 0xF0C7*/
#define LV_SYMBOL_CHARGE "\xef\x83\xa7" /*61671, 0xF0E7*/
#define LV_SYMBOL_PASTE "\xef\x83\xAA" /*61674, 0xF0EA*/
#define LV_SYMBOL_BELL "\xef\x83\xb3" /*61683, 0xF0F3*/
#define LV_SYMBOL_KEYBOARD "\xef\x84\x9c" /*61724, 0xF11C*/
#define LV_SYMBOL_GPS "\xef\x84\xa4" /*61732, 0xF124*/
#define LV_SYMBOL_FILE "\xef\x85\x9b" /*61787, 0xF158*/
#define LV_SYMBOL_WIFI "\xef\x87\xab" /*61931, 0xF1EB*/
#define LV_SYMBOL_BATTERY_FULL "\xef\x89\x80" /*62016, 0xF240*/
#define LV_SYMBOL_BATTERY_3 "\xef\x89\x81" /*62017, 0xF241*/
#define LV_SYMBOL_BATTERY_2 "\xef\x89\x82" /*62018, 0xF242*/
#define LV_SYMBOL_BATTERY_1 "\xef\x89\x83" /*62019, 0xF243*/
#define LV_SYMBOL_BATTERY_EMPTY "\xef\x89\x84" /*62020, 0xF244*/
#define LV_SYMBOL_USB "\xef\x8a\x87" /*62087, 0xF287*/
#define LV_SYMBOL_BLUETOOTH "\xef\x8a\x93" /*62099, 0xF293*/
#define LV_SYMBOL_TRASH "\xef\x8B\xAD" /*62189, 0xF2ED*/
#define LV_SYMBOL_BACKSPACE "\xef\x95\x9A" /*62810, 0xF55A*/
#define LV_SYMBOL_SD_CARD "\xef\x9F\x82" /*63426, 0xF7C2*/
#define LV_SYMBOL_NEW_LINE "\xef\xA2\xA2" /*63650, 0xF8A2*/
/** Invalid symbol at (U+F8FF). If written before a string then `lv_img` will show it as a label*/
#define LV_SYMBOL_DUMMY "\xEF\xA3\xBF"

View File

@ -12,6 +12,7 @@
#include <stdint.h>
#include <stddef.h>
#include "lv_hal.h"
#include "../lv_core/lv_debug.h"
#include "../lv_misc/lv_mem.h"
#include "../lv_core/lv_obj.h"
#include "../lv_core/lv_refr.h"
@ -118,7 +119,7 @@ lv_disp_t * lv_disp_drv_register(lv_disp_drv_t * driver)
{
lv_disp_t * disp = lv_ll_ins_head(&LV_GC_ROOT(_lv_disp_ll));
if(!disp) {
lv_mem_assert(disp);
LV_ASSERT_MEM(disp);
return NULL;
}
@ -137,7 +138,7 @@ lv_disp_t * lv_disp_drv_register(lv_disp_drv_t * driver)
disp->act_scr = lv_obj_create(NULL, NULL); /*Create a default screen on the display*/
disp->top_layer = lv_obj_create(NULL, NULL); /*Create top layer on the display*/
disp->sys_layer = lv_obj_create(NULL, NULL); /*Create top layer on the display*/
disp->sys_layer = lv_obj_create(NULL, NULL); /*Create sys layer on the display*/
lv_obj_set_style(disp->top_layer, &lv_style_transp);
lv_obj_set_style(disp->sys_layer, &lv_style_transp);
@ -147,7 +148,7 @@ lv_disp_t * lv_disp_drv_register(lv_disp_drv_t * driver)
/*Create a refresh task*/
disp->refr_task = lv_task_create(lv_disp_refr_task, LV_DISP_DEF_REFR_PERIOD, LV_TASK_PRIO_MID, disp);
lv_mem_assert(disp->refr_task);
LV_ASSERT_MEM(disp->refr_task);
if(disp->refr_task == NULL) return NULL;
lv_task_ready(disp->refr_task); /*Be sure the screen will be refreshed immediately on start up*/

View File

@ -8,6 +8,7 @@
/*********************
* INCLUDES
*********************/
#include "../lv_core/lv_debug.h"
#include "../lv_hal/lv_hal_indev.h"
#include "../lv_core/lv_indev.h"
#include "../lv_misc/lv_mem.h"
@ -77,7 +78,7 @@ lv_indev_t * lv_indev_drv_register(lv_indev_drv_t * driver)
lv_indev_t * indev = lv_ll_ins_head(&LV_GC_ROOT(_lv_indev_ll));
if(!indev) {
lv_mem_assert(indev);
LV_ASSERT_MEM(indev);
return NULL;
}

View File

@ -11,6 +11,7 @@
#if LV_USE_ANIMATION
#include <stddef.h>
#include <string.h>
#include "../lv_core/lv_debug.h"
#include "../lv_hal/lv_hal_tick.h"
#include "lv_task.h"
#include "lv_math.h"
@ -89,7 +90,7 @@ void lv_anim_create(lv_anim_t * a)
/*Add the new animation to the animation linked list*/
lv_anim_t * new_anim = lv_ll_ins_head(&LV_GC_ROOT(_lv_anim_ll));
lv_mem_assert(new_anim);
LV_ASSERT_MEM(new_anim);
if(new_anim == NULL) return;
/*Initialize the animation descriptor*/

View File

@ -29,6 +29,9 @@ extern "C" {
#define LV_COORD_MAX ((lv_coord_t)((uint32_t)((uint32_t)1 << (8 * sizeof(lv_coord_t) - 1)) - 1000))
#define LV_COORD_MIN (-LV_COORD_MAX)
LV_EXPORT_CONST_INT(LV_COORD_MAX);
LV_EXPORT_CONST_INT(LV_COORD_MIN);
/**********************
* TYPEDEFS
**********************/

View File

@ -9,6 +9,7 @@
#include "lv_fs.h"
#if LV_USE_FILESYSTEM
#include "../lv_core/lv_debug.h"
#include "lv_ll.h"
#include <string.h>
#include "lv_gc.h"
@ -107,7 +108,7 @@ lv_fs_res_t lv_fs_open(lv_fs_file_t * file_p, const char * path, lv_fs_mode_t mo
}
file_p->file_d = lv_mem_alloc(file_p->drv->file_size);
lv_mem_assert(file_p->file_d);
LV_ASSERT_MEM(file_p->file_d);
if(file_p->file_d == NULL) {
file_p->drv = NULL;
return LV_FS_RES_OUT_OF_MEM; /* Out of memory */
@ -367,7 +368,7 @@ lv_fs_res_t lv_fs_dir_open(lv_fs_dir_t * rddir_p, const char * path)
}
rddir_p->dir_d = lv_mem_alloc(rddir_p->drv->rddir_size);
lv_mem_assert(rddir_p->dir_d);
LV_ASSERT_MEM(rddir_p->dir_d);
if(rddir_p->dir_d == NULL) {
rddir_p->dir_d = NULL;
return LV_FS_RES_OUT_OF_MEM; /* Out of memory */
@ -486,7 +487,7 @@ void lv_fs_drv_register(lv_fs_drv_t * drv_p)
/*Save the new driver*/
lv_fs_drv_t * new_drv;
new_drv = lv_ll_ins_head(&LV_GC_ROOT(_lv_drv_ll));
lv_mem_assert(new_drv);
LV_ASSERT_MEM(new_drv);
if(new_drv == NULL) return;
memcpy(new_drv, drv_p, sizeof(lv_fs_drv_t));

View File

@ -29,6 +29,7 @@ extern "C" {
* DEFINES
*********************/
#define LV_FS_MAX_FN_LENGTH 64
#define LV_FS_MAX_PATH_LENGTH 256
/**********************
* TYPEDEFS

View File

@ -26,13 +26,14 @@ extern "C" {
/*Possible log level. For compatibility declare it independently from `LV_USE_LOG`*/
#define LV_LOG_LEVEL_TRACE 0 /**< A lot of logs to give detailed information*/
#define LV_LOG_LEVEL_INFO 1 /**< Log important events*/
#define LV_LOG_LEVEL_WARN 2 /**< Log if something unwanted happened but didn't caused problem*/
#define LV_LOG_LEVEL_ERROR 3 /**< Only critical issue, when the system may fail*/
#define LV_LOG_LEVEL_NONE 4 /**< Do not log anything*/
#define _LV_LOG_LEVEL_NUM 5 /**< Number of log levels */
enum {
LV_LOG_LEVEL_TRACE = 0, /**< A lot of logs to give detailed information*/
LV_LOG_LEVEL_INFO = 1, /**< Log important events*/
LV_LOG_LEVEL_WARN = 2, /**< Log if something unwanted happened but didn't caused problem*/
LV_LOG_LEVEL_ERROR = 3, /**< Only critical issue, when the system may fail*/
LV_LOG_LEVEL_NONE = 4, /**< Do not log anything*/
_LV_LOG_LEVEL_NUM = 5 /**< Number of log levels */
};
typedef int8_t lv_log_level_t;
#if LV_USE_LOG

View File

@ -110,27 +110,6 @@ uint32_t lv_mem_get_size(const void * data);
* MACROS
**********************/
/**
* Halt on NULL pointer
* p pointer to a memory
*/
#if LV_USE_LOG == 0
#define lv_mem_assert(p) \
{ \
if(p == NULL) \
while(1) \
; \
}
#else
#define lv_mem_assert(p) \
{ \
if(p == NULL) { \
LV_LOG_ERROR("Out of memory!"); \
while(1) \
; \
} \
}
#endif
#ifdef __cplusplus
} /* extern "C" */
#endif

View File

@ -12,6 +12,7 @@ CSRCS += lv_log.c
CSRCS += lv_gc.c
CSRCS += lv_utils.c
CSRCS += lv_async.c
CSRCS += lv_printf.c
DEPPATH += --dep-path $(LVGL_DIR)/lvgl/src/lv_misc
VPATH += :$(LVGL_DIR)/lvgl/src/lv_misc

861
src/lv_misc/lv_printf.c Normal file
View File

@ -0,0 +1,861 @@
///////////////////////////////////////////////////////////////////////////////
// \author (c) Marco Paland (info@paland.com)
// 2014-2019, PALANDesign Hannover, Germany
//
// \license The MIT License (MIT)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
// \brief Tiny printf, sprintf and (v)snprintf implementation, optimized for speed on
// embedded systems with a very limited resources. These routines are thread
// safe and reentrant!
// Use this instead of the bloated standard/newlib printf cause these use
// malloc for printf (and may not be thread safe).
//
///////////////////////////////////////////////////////////////////////////////
#include "lv_printf.h"
#if LV_SPRINTF_CUSTOM == 0
#include <stdbool.h>
#include <stdint.h>
// 'ntoa' conversion buffer size, this must be big enough to hold one converted
// numeric number including padded zeros (dynamically created on stack)
// default: 32 byte
#ifndef PRINTF_NTOA_BUFFER_SIZE
#define PRINTF_NTOA_BUFFER_SIZE 32U
#endif
// 'ftoa' conversion buffer size, this must be big enough to hold one converted
// float number including padded zeros (dynamically created on stack)
// default: 32 byte
#ifndef PRINTF_FTOA_BUFFER_SIZE
#define PRINTF_FTOA_BUFFER_SIZE 32U
#endif
// support for the floating point type (%f)
// default: activated
#ifndef PRINTF_DISABLE_SUPPORT_FLOAT
#define PRINTF_SUPPORT_FLOAT
#endif
// support for exponential floating point notation (%e/%g)
// default: activated
#ifndef PRINTF_DISABLE_SUPPORT_EXPONENTIAL
#define PRINTF_SUPPORT_EXPONENTIAL
#endif
// define the default floating point precision
// default: 6 digits
#ifndef PRINTF_DEFAULT_FLOAT_PRECISION
#define PRINTF_DEFAULT_FLOAT_PRECISION 6U
#endif
// define the largest float suitable to print with %f
// default: 1e9
#ifndef PRINTF_MAX_FLOAT
#define PRINTF_MAX_FLOAT 1e9
#endif
// support for the long long types (%llu or %p)
// default: activated
#ifndef PRINTF_DISABLE_SUPPORT_LONG_LONG
#define PRINTF_SUPPORT_LONG_LONG
#endif
// support for the ptrdiff_t type (%t)
// ptrdiff_t is normally defined in <stddef.h> as long or long long type
// default: activated
#ifndef PRINTF_DISABLE_SUPPORT_PTRDIFF_T
#define PRINTF_SUPPORT_PTRDIFF_T
#endif
///////////////////////////////////////////////////////////////////////////////
// internal flag definitions
#define FLAGS_ZEROPAD (1U << 0U)
#define FLAGS_LEFT (1U << 1U)
#define FLAGS_PLUS (1U << 2U)
#define FLAGS_SPACE (1U << 3U)
#define FLAGS_HASH (1U << 4U)
#define FLAGS_UPPERCASE (1U << 5U)
#define FLAGS_CHAR (1U << 6U)
#define FLAGS_SHORT (1U << 7U)
#define FLAGS_LONG (1U << 8U)
#define FLAGS_LONG_LONG (1U << 9U)
#define FLAGS_PRECISION (1U << 10U)
#define FLAGS_ADAPT_EXP (1U << 11U)
// import float.h for DBL_MAX
#if defined(PRINTF_SUPPORT_FLOAT)
#include <float.h>
#endif
// output function type
typedef void (*out_fct_type)(char character, void* buffer, size_t idx, size_t maxlen);
// wrapper (used as buffer) for output function type
typedef struct {
void (*fct)(char character, void* arg);
void* arg;
} out_fct_wrap_type;
// internal buffer output
static inline void _out_buffer(char character, void* buffer, size_t idx, size_t maxlen)
{
if (idx < maxlen) {
((char*)buffer)[idx] = character;
}
}
// internal null output
static inline void _out_null(char character, void* buffer, size_t idx, size_t maxlen)
{
(void)character; (void)buffer; (void)idx; (void)maxlen;
}
// internal output function wrapper
static inline void _out_fct(char character, void* buffer, size_t idx, size_t maxlen)
{
(void)idx; (void)maxlen;
if (character) {
// buffer is the output fct pointer
((out_fct_wrap_type*)buffer)->fct(character, ((out_fct_wrap_type*)buffer)->arg);
}
}
// internal secure strlen
// \return The length of the string (excluding the terminating 0) limited by 'maxsize'
static inline unsigned int _strnlen_s(const char* str, size_t maxsize)
{
const char* s;
for (s = str; *s && maxsize--; ++s);
return (unsigned int)(s - str);
}
// internal test if char is a digit (0-9)
// \return true if char is a digit
static inline bool _is_digit(char ch)
{
return (ch >= '0') && (ch <= '9');
}
// internal ASCII string to unsigned int conversion
static unsigned int _atoi(const char** str)
{
unsigned int i = 0U;
while (_is_digit(**str)) {
i = i * 10U + (unsigned int)(*((*str)++) - '0');
}
return i;
}
// output the specified string in reverse, taking care of any zero-padding
static size_t _out_rev(out_fct_type out, char* buffer, size_t idx, size_t maxlen, const char* buf, size_t len, unsigned int width, unsigned int flags)
{
const size_t start_idx = idx;
// pad spaces up to given width
if (!(flags & FLAGS_LEFT) && !(flags & FLAGS_ZEROPAD)) {
for (size_t i = len; i < width; i++) {
out(' ', buffer, idx++, maxlen);
}
}
// reverse string
while (len) {
out(buf[--len], buffer, idx++, maxlen);
}
// append pad spaces up to given width
if (flags & FLAGS_LEFT) {
while (idx - start_idx < width) {
out(' ', buffer, idx++, maxlen);
}
}
return idx;
}
// internal itoa format
static size_t _ntoa_format(out_fct_type out, char* buffer, size_t idx, size_t maxlen, char* buf, size_t len, bool negative, unsigned int base, unsigned int prec, unsigned int width, unsigned int flags)
{
// pad leading zeros
if (!(flags & FLAGS_LEFT)) {
if (width && (flags & FLAGS_ZEROPAD) && (negative || (flags & (FLAGS_PLUS | FLAGS_SPACE)))) {
width--;
}
while ((len < prec) && (len < PRINTF_NTOA_BUFFER_SIZE)) {
buf[len++] = '0';
}
while ((flags & FLAGS_ZEROPAD) && (len < width) && (len < PRINTF_NTOA_BUFFER_SIZE)) {
buf[len++] = '0';
}
}
// handle hash
if (flags & FLAGS_HASH) {
if (!(flags & FLAGS_PRECISION) && len && ((len == prec) || (len == width))) {
len--;
if (len && (base == 16U)) {
len--;
}
}
if ((base == 16U) && !(flags & FLAGS_UPPERCASE) && (len < PRINTF_NTOA_BUFFER_SIZE)) {
buf[len++] = 'x';
}
else if ((base == 16U) && (flags & FLAGS_UPPERCASE) && (len < PRINTF_NTOA_BUFFER_SIZE)) {
buf[len++] = 'X';
}
else if ((base == 2U) && (len < PRINTF_NTOA_BUFFER_SIZE)) {
buf[len++] = 'b';
}
if (len < PRINTF_NTOA_BUFFER_SIZE) {
buf[len++] = '0';
}
}
if (len < PRINTF_NTOA_BUFFER_SIZE) {
if (negative) {
buf[len++] = '-';
}
else if (flags & FLAGS_PLUS) {
buf[len++] = '+'; // ignore the space if the '+' exists
}
else if (flags & FLAGS_SPACE) {
buf[len++] = ' ';
}
}
return _out_rev(out, buffer, idx, maxlen, buf, len, width, flags);
}
// internal itoa for 'long' type
static size_t _ntoa_long(out_fct_type out, char* buffer, size_t idx, size_t maxlen, unsigned long value, bool negative, unsigned long base, unsigned int prec, unsigned int width, unsigned int flags)
{
char buf[PRINTF_NTOA_BUFFER_SIZE];
size_t len = 0U;
// no hash for 0 values
if (!value) {
flags &= ~FLAGS_HASH;
}
// write if precision != 0 and value is != 0
if (!(flags & FLAGS_PRECISION) || value) {
do {
const char digit = (char)(value % base);
buf[len++] = digit < 10 ? '0' + digit : (flags & FLAGS_UPPERCASE ? 'A' : 'a') + digit - 10;
value /= base;
} while (value && (len < PRINTF_NTOA_BUFFER_SIZE));
}
return _ntoa_format(out, buffer, idx, maxlen, buf, len, negative, (unsigned int)base, prec, width, flags);
}
// internal itoa for 'long long' type
#if defined(PRINTF_SUPPORT_LONG_LONG)
static size_t _ntoa_long_long(out_fct_type out, char* buffer, size_t idx, size_t maxlen, unsigned long long value, bool negative, unsigned long long base, unsigned int prec, unsigned int width, unsigned int flags)
{
char buf[PRINTF_NTOA_BUFFER_SIZE];
size_t len = 0U;
// no hash for 0 values
if (!value) {
flags &= ~FLAGS_HASH;
}
// write if precision != 0 and value is != 0
if (!(flags & FLAGS_PRECISION) || value) {
do {
const char digit = (char)(value % base);
buf[len++] = digit < 10 ? '0' + digit : (flags & FLAGS_UPPERCASE ? 'A' : 'a') + digit - 10;
value /= base;
} while (value && (len < PRINTF_NTOA_BUFFER_SIZE));
}
return _ntoa_format(out, buffer, idx, maxlen, buf, len, negative, (unsigned int)base, prec, width, flags);
}
#endif // PRINTF_SUPPORT_LONG_LONG
#if defined(PRINTF_SUPPORT_FLOAT)
#if defined(PRINTF_SUPPORT_EXPONENTIAL)
// forward declaration so that _ftoa can switch to exp notation for values > PRINTF_MAX_FLOAT
static size_t _etoa(out_fct_type out, char* buffer, size_t idx, size_t maxlen, double value, unsigned int prec, unsigned int width, unsigned int flags);
#endif
// internal ftoa for fixed decimal floating point
static size_t _ftoa(out_fct_type out, char* buffer, size_t idx, size_t maxlen, double value, unsigned int prec, unsigned int width, unsigned int flags)
{
char buf[PRINTF_FTOA_BUFFER_SIZE];
size_t len = 0U;
double diff = 0.0;
// powers of 10
static const double pow10[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 };
// test for special values
if (value != value)
return _out_rev(out, buffer, idx, maxlen, "nan", 3, width, flags);
if (value < -DBL_MAX)
return _out_rev(out, buffer, idx, maxlen, "fni-", 4, width, flags);
if (value > DBL_MAX)
return _out_rev(out, buffer, idx, maxlen, (flags & FLAGS_PLUS) ? "fni+" : "fni", (flags & FLAGS_PLUS) ? 4U : 3U, width, flags);
// test for very large values
// standard printf behavior is to print EVERY whole number digit -- which could be 100s of characters overflowing your buffers == bad
if ((value > PRINTF_MAX_FLOAT) || (value < -PRINTF_MAX_FLOAT)) {
#if defined(PRINTF_SUPPORT_EXPONENTIAL)
return _etoa(out, buffer, idx, maxlen, value, prec, width, flags);
#else
return 0U;
#endif
}
// test for negative
bool negative = false;
if (value < 0) {
negative = true;
value = 0 - value;
}
// set default precision, if not set explicitly
if (!(flags & FLAGS_PRECISION)) {
prec = PRINTF_DEFAULT_FLOAT_PRECISION;
}
// limit precision to 9, cause a prec >= 10 can lead to overflow errors
while ((len < PRINTF_FTOA_BUFFER_SIZE) && (prec > 9U)) {
buf[len++] = '0';
prec--;
}
int whole = (int)value;
double tmp = (value - whole) * pow10[prec];
unsigned long frac = (unsigned long)tmp;
diff = tmp - frac;
if (diff > 0.5) {
++frac;
// handle rollover, e.g. case 0.99 with prec 1 is 1.0
if (frac >= pow10[prec]) {
frac = 0;
++whole;
}
}
else if (diff < 0.5) {
}
else if ((frac == 0U) || (frac & 1U)) {
// if halfway, round up if odd OR if last digit is 0
++frac;
}
if (prec == 0U) {
diff = value - (double)whole;
if ((!(diff < 0.5) || (diff > 0.5)) && (whole & 1)) {
// exactly 0.5 and ODD, then round up
// 1.5 -> 2, but 2.5 -> 2
++whole;
}
}
else {
unsigned int count = prec;
// now do fractional part, as an unsigned number
while (len < PRINTF_FTOA_BUFFER_SIZE) {
--count;
buf[len++] = (char)(48U + (frac % 10U));
if (!(frac /= 10U)) {
break;
}
}
// add extra 0s
while ((len < PRINTF_FTOA_BUFFER_SIZE) && (count-- > 0U)) {
buf[len++] = '0';
}
if (len < PRINTF_FTOA_BUFFER_SIZE) {
// add decimal
buf[len++] = '.';
}
}
// do whole part, number is reversed
while (len < PRINTF_FTOA_BUFFER_SIZE) {
buf[len++] = (char)(48 + (whole % 10));
if (!(whole /= 10)) {
break;
}
}
// pad leading zeros
if (!(flags & FLAGS_LEFT) && (flags & FLAGS_ZEROPAD)) {
if (width && (negative || (flags & (FLAGS_PLUS | FLAGS_SPACE)))) {
width--;
}
while ((len < width) && (len < PRINTF_FTOA_BUFFER_SIZE)) {
buf[len++] = '0';
}
}
if (len < PRINTF_FTOA_BUFFER_SIZE) {
if (negative) {
buf[len++] = '-';
}
else if (flags & FLAGS_PLUS) {
buf[len++] = '+'; // ignore the space if the '+' exists
}
else if (flags & FLAGS_SPACE) {
buf[len++] = ' ';
}
}
return _out_rev(out, buffer, idx, maxlen, buf, len, width, flags);
}
#if defined(PRINTF_SUPPORT_EXPONENTIAL)
// internal ftoa variant for exponential floating-point type, contributed by Martijn Jasperse <m.jasperse@gmail.com>
static size_t _etoa(out_fct_type out, char* buffer, size_t idx, size_t maxlen, double value, unsigned int prec, unsigned int width, unsigned int flags)
{
// check for NaN and special values
if ((value != value) || (value > DBL_MAX) || (value < -DBL_MAX)) {
return _ftoa(out, buffer, idx, maxlen, value, prec, width, flags);
}
// determine the sign
const bool negative = value < 0;
if (negative) {
value = -value;
}
// default precision
if (!(flags & FLAGS_PRECISION)) {
prec = PRINTF_DEFAULT_FLOAT_PRECISION;
}
// determine the decimal exponent
// based on the algorithm by David Gay (https://www.ampl.com/netlib/fp/dtoa.c)
union {
uint64_t U;
double F;
} conv;
conv.F = value;
int exp2 = (int)((conv.U >> 52U) & 0x07FFU) - 1023; // effectively log2
conv.U = (conv.U & ((1ULL << 52U) - 1U)) | (1023ULL << 52U); // drop the exponent so conv.F is now in [1,2)
// now approximate log10 from the log2 integer part and an expansion of ln around 1.5
int expval = (int)(0.1760912590558 + exp2 * 0.301029995663981 + (conv.F - 1.5) * 0.289529654602168);
// now we want to compute 10^expval but we want to be sure it won't overflow
exp2 = (int)(expval * 3.321928094887362 + 0.5);
const double z = expval * 2.302585092994046 - exp2 * 0.6931471805599453;
const double z2 = z * z;
conv.U = (uint64_t)(exp2 + 1023) << 52U;
// compute exp(z) using continued fractions, see https://en.wikipedia.org/wiki/Exponential_function#Continued_fractions_for_ex
conv.F *= 1 + 2 * z / (2 - z + (z2 / (6 + (z2 / (10 + z2 / 14)))));
// correct for rounding errors
if (value < conv.F) {
expval--;
conv.F /= 10;
}
// the exponent format is "%+03d" and largest value is "307", so set aside 4-5 characters
unsigned int minwidth = ((expval < 100) && (expval > -100)) ? 4U : 5U;
// in "%g" mode, "prec" is the number of *significant figures* not decimals
if (flags & FLAGS_ADAPT_EXP) {
// do we want to fall-back to "%f" mode?
if ((value >= 1e-4) && (value < 1e6)) {
if ((int)prec > expval) {
prec = (unsigned)((int)prec - expval - 1);
}
else {
prec = 0;
}
flags |= FLAGS_PRECISION; // make sure _ftoa respects precision
// no characters in exponent
minwidth = 0U;
expval = 0;
}
else {
// we use one sigfig for the whole part
if ((prec > 0) && (flags & FLAGS_PRECISION)) {
--prec;
}
}
}
// will everything fit?
unsigned int fwidth = width;
if (width > minwidth) {
// we didn't fall-back so subtract the characters required for the exponent
fwidth -= minwidth;
} else {
// not enough characters, so go back to default sizing
fwidth = 0U;
}
if ((flags & FLAGS_LEFT) && minwidth) {
// if we're padding on the right, DON'T pad the floating part
fwidth = 0U;
}
// rescale the float value
if (expval) {
value /= conv.F;
}
// output the floating part
const size_t start_idx = idx;
idx = _ftoa(out, buffer, idx, maxlen, negative ? -value : value, prec, fwidth, flags & ~FLAGS_ADAPT_EXP);
// output the exponent part
if (minwidth) {
// output the exponential symbol
out((flags & FLAGS_UPPERCASE) ? 'E' : 'e', buffer, idx++, maxlen);
// output the exponent value
idx = _ntoa_long(out, buffer, idx, maxlen, (expval < 0) ? -expval : expval, expval < 0, 10, 0, minwidth-1, FLAGS_ZEROPAD | FLAGS_PLUS);
// might need to right-pad spaces
if (flags & FLAGS_LEFT) {
while (idx - start_idx < width) out(' ', buffer, idx++, maxlen);
}
}
return idx;
}
#endif // PRINTF_SUPPORT_EXPONENTIAL
#endif // PRINTF_SUPPORT_FLOAT
// internal vsnprintf
static int _vsnprintf(out_fct_type out, char* buffer, const size_t maxlen, const char* format, va_list va)
{
unsigned int flags, width, precision, n;
size_t idx = 0U;
if (!buffer) {
// use null output function
out = _out_null;
}
while (*format)
{
// format specifier? %[flags][width][.precision][length]
if (*format != '%') {
// no
out(*format, buffer, idx++, maxlen);
format++;
continue;
}
else {
// yes, evaluate it
format++;
}
// evaluate flags
flags = 0U;
do {
switch (*format) {
case '0': flags |= FLAGS_ZEROPAD; format++; n = 1U; break;
case '-': flags |= FLAGS_LEFT; format++; n = 1U; break;
case '+': flags |= FLAGS_PLUS; format++; n = 1U; break;
case ' ': flags |= FLAGS_SPACE; format++; n = 1U; break;
case '#': flags |= FLAGS_HASH; format++; n = 1U; break;
default : n = 0U; break;
}
} while (n);
// evaluate width field
width = 0U;
if (_is_digit(*format)) {
width = _atoi(&format);
}
else if (*format == '*') {
const int w = va_arg(va, int);
if (w < 0) {
flags |= FLAGS_LEFT; // reverse padding
width = (unsigned int)-w;
}
else {
width = (unsigned int)w;
}
format++;
}
// evaluate precision field
precision = 0U;
if (*format == '.') {
flags |= FLAGS_PRECISION;
format++;
if (_is_digit(*format)) {
precision = _atoi(&format);
}
else if (*format == '*') {
const int prec = (int)va_arg(va, int);
precision = prec > 0 ? (unsigned int)prec : 0U;
format++;
}
}
// evaluate length field
switch (*format) {
case 'l' :
flags |= FLAGS_LONG;
format++;
if (*format == 'l') {
flags |= FLAGS_LONG_LONG;
format++;
}
break;
case 'h' :
flags |= FLAGS_SHORT;
format++;
if (*format == 'h') {
flags |= FLAGS_CHAR;
format++;
}
break;
#if defined(PRINTF_SUPPORT_PTRDIFF_T)
case 't' :
flags |= (sizeof(ptrdiff_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG);
format++;
break;
#endif
case 'j' :
flags |= (sizeof(intmax_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG);
format++;
break;
case 'z' :
flags |= (sizeof(size_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG);
format++;
break;
default :
break;
}
// evaluate specifier
switch (*format) {
case 'd' :
case 'i' :
case 'u' :
case 'x' :
case 'X' :
case 'o' :
case 'b' : {
// set the base
unsigned int base;
if (*format == 'x' || *format == 'X') {
base = 16U;
}
else if (*format == 'o') {
base = 8U;
}
else if (*format == 'b') {
base = 2U;
}
else {
base = 10U;
flags &= ~FLAGS_HASH; // no hash for dec format
}
// uppercase
if (*format == 'X') {
flags |= FLAGS_UPPERCASE;
}
// no plus or space flag for u, x, X, o, b
if ((*format != 'i') && (*format != 'd')) {
flags &= ~(FLAGS_PLUS | FLAGS_SPACE);
}
// ignore '0' flag when precision is given
if (flags & FLAGS_PRECISION) {
flags &= ~FLAGS_ZEROPAD;
}
// convert the integer
if ((*format == 'i') || (*format == 'd')) {
// signed
if (flags & FLAGS_LONG_LONG) {
#if defined(PRINTF_SUPPORT_LONG_LONG)
const long long value = va_arg(va, long long);
idx = _ntoa_long_long(out, buffer, idx, maxlen, (unsigned long long)(value > 0 ? value : 0 - value), value < 0, base, precision, width, flags);
#endif
}
else if (flags & FLAGS_LONG) {
const long value = va_arg(va, long);
idx = _ntoa_long(out, buffer, idx, maxlen, (unsigned long)(value > 0 ? value : 0 - value), value < 0, base, precision, width, flags);
}
else {
const int value = (flags & FLAGS_CHAR) ? (char)va_arg(va, int) : (flags & FLAGS_SHORT) ? (short int)va_arg(va, int) : va_arg(va, int);
idx = _ntoa_long(out, buffer, idx, maxlen, (unsigned int)(value > 0 ? value : 0 - value), value < 0, base, precision, width, flags);
}
}
else {
// unsigned
if (flags & FLAGS_LONG_LONG) {
#if defined(PRINTF_SUPPORT_LONG_LONG)
idx = _ntoa_long_long(out, buffer, idx, maxlen, va_arg(va, unsigned long long), false, base, precision, width, flags);
#endif
}
else if (flags & FLAGS_LONG) {
idx = _ntoa_long(out, buffer, idx, maxlen, va_arg(va, unsigned long), false, base, precision, width, flags);
}
else {
const unsigned int value = (flags & FLAGS_CHAR) ? (unsigned char)va_arg(va, unsigned int) : (flags & FLAGS_SHORT) ? (unsigned short int)va_arg(va, unsigned int) : va_arg(va, unsigned int);
idx = _ntoa_long(out, buffer, idx, maxlen, value, false, base, precision, width, flags);
}
}
format++;
break;
}
#if defined(PRINTF_SUPPORT_FLOAT)
case 'f' :
case 'F' :
if (*format == 'F') flags |= FLAGS_UPPERCASE;
idx = _ftoa(out, buffer, idx, maxlen, va_arg(va, double), precision, width, flags);
format++;
break;
#if defined(PRINTF_SUPPORT_EXPONENTIAL)
case 'e':
case 'E':
case 'g':
case 'G':
if ((*format == 'g')||(*format == 'G')) flags |= FLAGS_ADAPT_EXP;
if ((*format == 'E')||(*format == 'G')) flags |= FLAGS_UPPERCASE;
idx = _etoa(out, buffer, idx, maxlen, va_arg(va, double), precision, width, flags);
format++;
break;
#endif // PRINTF_SUPPORT_EXPONENTIAL
#endif // PRINTF_SUPPORT_FLOAT
case 'c' : {
unsigned int l = 1U;
// pre padding
if (!(flags & FLAGS_LEFT)) {
while (l++ < width) {
out(' ', buffer, idx++, maxlen);
}
}
// char output
out((char)va_arg(va, int), buffer, idx++, maxlen);
// post padding
if (flags & FLAGS_LEFT) {
while (l++ < width) {
out(' ', buffer, idx++, maxlen);
}
}
format++;
break;
}
case 's' : {
const char* p = va_arg(va, char*);
unsigned int l = _strnlen_s(p, precision ? precision : (size_t)-1);
// pre padding
if (flags & FLAGS_PRECISION) {
l = (l < precision ? l : precision);
}
if (!(flags & FLAGS_LEFT)) {
while (l++ < width) {
out(' ', buffer, idx++, maxlen);
}
}
// string output
while ((*p != 0) && (!(flags & FLAGS_PRECISION) || precision--)) {
out(*(p++), buffer, idx++, maxlen);
}
// post padding
if (flags & FLAGS_LEFT) {
while (l++ < width) {
out(' ', buffer, idx++, maxlen);
}
}
format++;
break;
}
case 'p' : {
width = sizeof(void*) * 2U;
flags |= FLAGS_ZEROPAD | FLAGS_UPPERCASE;
#if defined(PRINTF_SUPPORT_LONG_LONG)
const bool is_ll = sizeof(uintptr_t) == sizeof(long long);
if (is_ll) {
idx = _ntoa_long_long(out, buffer, idx, maxlen, (uintptr_t)va_arg(va, void*), false, 16U, precision, width, flags);
}
else {
#endif
idx = _ntoa_long(out, buffer, idx, maxlen, (unsigned long)((uintptr_t)va_arg(va, void*)), false, 16U, precision, width, flags);
#if defined(PRINTF_SUPPORT_LONG_LONG)
}
#endif
format++;
break;
}
case '%' :
out('%', buffer, idx++, maxlen);
format++;
break;
default :
out(*format, buffer, idx++, maxlen);
format++;
break;
}
}
// termination
out((char)0, buffer, idx < maxlen ? idx : maxlen - 1U, maxlen);
// return written chars without terminating \0
return (int)idx;
}
///////////////////////////////////////////////////////////////////////////////
int lv_snprintf(char* buffer, size_t count, const char* format, ...)
{
va_list va;
va_start(va, format);
const int ret = _vsnprintf(_out_buffer, buffer, count, format, va);
va_end(va);
return ret;
}
int lv_vsnprintf(char* buffer, size_t count, const char* format, va_list va)
{
return _vsnprintf(_out_buffer, buffer, count, format, va);
}
#endif /*LV_SPRINTF_CUSTOM*/

75
src/lv_misc/lv_printf.h Normal file
View File

@ -0,0 +1,75 @@
///////////////////////////////////////////////////////////////////////////////
// \author (c) Marco Paland (info@paland.com)
// 2014-2019, PALANDesign Hannover, Germany
//
// \license The MIT License (MIT)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
// \brief Tiny printf, sprintf and snprintf implementation, optimized for speed on
// embedded systems with a very limited resources.
// Use this instead of bloated standard/newlib printf.
// These routines are thread safe and reentrant.
//
///////////////////////////////////////////////////////////////////////////////
#ifndef _LV_PRINTF_H_
#define _LV_PRINTF_H_
#ifdef __cplusplus
extern "C" {
#endif
#ifdef LV_CONF_INCLUDE_SIMPLE
#include "lv_conf.h"
#else
#include "../../../lv_conf.h"
#endif
#if LV_SPRINTF_CUSTOM == 0
#include <stdarg.h>
#include <stddef.h>
/**
* Tiny snprintf/vsnprintf implementation
* \param buffer A pointer to the buffer where to store the formatted string
* \param count The maximum number of characters to store in the buffer, including a terminating null character
* \param format A string that specifies the format of the output
* \param va A value identifying a variable arguments list
* \return The number of characters that COULD have been written into the buffer, not counting the terminating
* null character. A value equal or larger than count indicates truncation. Only when the returned value
* is non-negative and less than count, the string has been completely written.
*/
int lv_snprintf(char* buffer, size_t count, const char* format, ...);
int lv_vsnprintf(char* buffer, size_t count, const char* format, va_list va);
#else
#include LV_SPRINTF_INCLUDE
#endif
#ifdef __cplusplus
}
#endif
#endif // _PRINTF_H_

View File

@ -9,6 +9,7 @@
*********************/
#include <stddef.h>
#include "lv_task.h"
#include "../lv_core/lv_debug.h"
#include "../lv_hal/lv_hal_tick.h"
#include "lv_gc.h"
@ -173,7 +174,7 @@ lv_task_t * lv_task_create_basic(void)
/*It's the first task*/
if(NULL == tmp) {
new_task = lv_ll_ins_head(&LV_GC_ROOT(_lv_task_ll));
lv_mem_assert(new_task);
LV_ASSERT_MEM(new_task);
if(new_task == NULL) return NULL;
}
/*Insert the new task to proper place according to its priority*/
@ -181,7 +182,7 @@ lv_task_t * lv_task_create_basic(void)
do {
if(tmp->prio <= DEF_PRIO) {
new_task = lv_ll_ins_prev(&LV_GC_ROOT(_lv_task_ll), tmp);
lv_mem_assert(new_task);
LV_ASSERT_MEM(new_task);
if(new_task == NULL) return NULL;
break;
}
@ -191,7 +192,7 @@ lv_task_t * lv_task_create_basic(void)
/*Only too high priority tasks were found. Add the task to the end*/
if(tmp == NULL) {
new_task = lv_ll_ins_tail(&LV_GC_ROOT(_lv_task_ll));
lv_mem_assert(new_task);
LV_ASSERT_MEM(new_task);
if(new_task == NULL) return NULL;
}
}
@ -223,7 +224,7 @@ lv_task_t * lv_task_create_basic(void)
lv_task_t * lv_task_create(lv_task_cb_t task_cb, uint32_t period, lv_task_prio_t prio, void * user_data)
{
lv_task_t * new_task = lv_task_create_basic();
lv_mem_assert(new_task);
LV_ASSERT_MEM(new_task);
if(new_task == NULL) return NULL;
lv_task_set_cb(new_task, task_cb);

View File

@ -130,6 +130,137 @@ void lv_txt_get_size(lv_point_t * size_res, const char * text, const lv_font_t *
size_res->y -= line_space;
}
/**
* Get the next word of text. A word is delimited by break characters.
*
* If the word cannot fit in the max_width space, obey LV_TXT_LINE_BREAK_LONG_* rules.
*
* If the next word cannot fit anything, return 0.
*
* If the first character is a break character, returns the next index.
*
* Example calls from lv_txt_get_next_line() assuming sufficent max_width and
* txt = "Test text\n"
* 0123456789
*
* Calls would be as follows:
* 1. Return i=4, pointing at breakchar ' ', for the string "Test"
* 2. Return i=5, since i=4 was a breakchar.
* 3. Return i=9, pointing at breakchar '\n'
* 4. Parenting lv_txt_get_next_line() would detect subsequent '\0'
*
* @param txt a '\0' terminated string
* @param font pointer to a font
* @param letter_space letter space
* @param max_width max with of the text (break the lines to fit this size) Set CORD_MAX to avoid line breaks
* @param flags settings for the text from 'txt_flag_type' enum
* @param[out] word_w_ptr width (in pixels) of the parsed word. May be NULL.
* @return the index of the first char of the next word (in byte index not letter index. With UTF-8 they are different)
*/
static uint16_t lv_txt_get_next_word(const char * txt, const lv_font_t * font,
lv_coord_t letter_space, lv_coord_t max_width,
lv_txt_flag_t flag, uint32_t *word_w_ptr)
{
if(txt == NULL || txt[0] == '\0') return 0;
if(font == NULL) return 0;
if(flag & LV_TXT_FLAG_EXPAND) max_width = LV_COORD_MAX;
uint32_t i = 0, i_next = 0, i_next_next = 0; /* Iterating index into txt */
lv_txt_cmd_state_t cmd_state = LV_TXT_CMD_STATE_WAIT;
uint32_t letter = 0; /* Letter at i */
uint32_t letter_next = 0; /* Letter at i_next */
lv_coord_t letter_w;
lv_coord_t cur_w = 0; /* Pixel Width of transversed string */
uint32_t word_len = 0; /* Number of characters in the transversed word */
uint32_t break_index = NO_BREAK_FOUND; /* only used for "long" words */
uint32_t break_letter_count = 0; /* Number of characters up to the long word break point */
letter = lv_txt_encoded_next(txt, &i_next);
i_next_next = i_next;
while(txt[i] != '\0') {
letter_next = lv_txt_encoded_next(txt, &i_next_next);
word_len++;
/*Handle the recolor command*/
if((flag & LV_TXT_FLAG_RECOLOR) != 0) {
if(lv_txt_is_cmd(&cmd_state, letter) != false) {
continue; /*Skip the letter is it is part of a command*/
}
}
letter_w = lv_font_get_glyph_width(font, letter, letter_next);
cur_w += letter_w;
/* Test if this character fits within max_width */
if( break_index == NO_BREAK_FOUND && cur_w > max_width) {
break_index = i;
if(break_index > 0) { /* zero is possible if first character doesn't fit in width */
lv_txt_encoded_prev(txt, &break_index);
break_letter_count = word_len - 2;
}
else{
break_letter_count = word_len - 1;
}
/* break_index is now pointing at the character that doesn't fit */
}
/*Check for new line chars and breakchars*/
if(letter == '\n' || letter == '\r' || is_break_char(letter)) {
/* Update the output width on the first character if it fits.
* Must do this here incase first letter is a break character. */
if(i == 0 && break_index == NO_BREAK_FOUND && word_w_ptr != NULL) *word_w_ptr = cur_w;
word_len--;
break;
}
/* Update the output width */
if( word_w_ptr != NULL && break_index == NO_BREAK_FOUND ) *word_w_ptr = cur_w;
if(letter_w > 0) {
cur_w += letter_space;
}
i = i_next;
i_next = i_next_next;
letter = letter_next;
}
/* Entire Word fits in the provided space */
if( break_index == NO_BREAK_FOUND ) {
if( word_len == 0 || (letter == '\r' && letter_next == '\n') ) i = i_next;
return i;
}
/* Word doesn't fit in provided space, but isn't "long" */
if(word_len < LV_TXT_LINE_BREAK_LONG_LEN) {
if(word_w_ptr != NULL) *word_w_ptr = 0;
return 0;
}
/* Word is "long," but insufficient amounts can fit in provided space */
if(break_letter_count < LV_TXT_LINE_BREAK_LONG_PRE_MIN_LEN) {
if(word_w_ptr != NULL) *word_w_ptr = 0;
return 0;
}
/* Word is a "long", but letters may need to be better distributed */
{
i = break_index;
int32_t n_move = LV_TXT_LINE_BREAK_LONG_POST_MIN_LEN - (word_len - break_letter_count);
/* Move pointer "i" backwards */
for(;n_move>0; n_move--){
lv_txt_encoded_prev(txt, &i);
// todo: it would be appropriate to update the returned word width here
// However, in current usage, this doesn't impact anything.
}
}
return i;
}
/**
* Get the next line of text. Check line length and break chars too.
* @param txt a '\0' terminated string
@ -139,75 +270,45 @@ void lv_txt_get_size(lv_point_t * size_res, const char * text, const lv_font_t *
* @param flags settings for the text from 'txt_flag_type' enum
* @return the index of the first char of the new line (in byte index not letter index. With UTF-8 they are different)
*/
uint16_t lv_txt_get_next_line(const char * txt, const lv_font_t * font, lv_coord_t letter_space, lv_coord_t max_width,
lv_txt_flag_t flag)
uint16_t lv_txt_get_next_line(const char * txt, const lv_font_t * font,
lv_coord_t letter_space, lv_coord_t max_width, lv_txt_flag_t flag)
{
if(txt == NULL) return 0;
if(font == NULL) return 0;
if(flag & LV_TXT_FLAG_EXPAND) max_width = LV_COORD_MAX;
uint32_t i = 0;
uint32_t i_next = 0;
lv_coord_t cur_w = 0;
uint32_t last_break = NO_BREAK_FOUND;
lv_txt_cmd_state_t cmd_state = LV_TXT_CMD_STATE_WAIT;
uint32_t letter_w;
uint32_t letter = 0;
uint32_t letter_next = 0;
uint32_t i = 0; /* Iterating index into txt */
letter_next = lv_txt_encoded_next(txt, &i_next);
while(txt[i] != '\0' && max_width > 0) {
uint32_t word_w = 0;
uint32_t advance = lv_txt_get_next_word(&txt[i], font, letter_space, max_width, flag, &word_w);
max_width -= word_w;
while(txt[i] != '\0') {
letter = letter_next;
i = i_next;
letter_next = lv_txt_encoded_next(txt, &i_next);
/*Handle the recolor command*/
if((flag & LV_TXT_FLAG_RECOLOR) != 0) {
if(lv_txt_is_cmd(&cmd_state, letter) != false) {
continue; /*Skip the letter is it is part of a command*/
}
if( advance == 0 ){
if(i == 0) lv_txt_encoded_next(txt, &i); // prevent inf loops
break;
}
/*Check for new line chars*/
if(letter == '\n' || letter == '\r') {
/*Return with the first letter of the next line*/
if(letter == '\r' && letter_next == '\n')
return i_next;
else
return i;
} else { /*Check the actual length*/
letter_w = lv_font_get_glyph_width(font, letter, letter_next);
cur_w += letter_w;
i += advance;
/*If the txt is too long then finish, this is the line end*/
if(cur_w > max_width) {
/*If a break character was already found break there*/
if(last_break != NO_BREAK_FOUND) {
i = last_break;
} else {
/* Now this character is out of the area so it will be first character of the next line*/
/* But 'i' already points to the next character (because of lv_txt_utf8_next) step beck one*/
lv_txt_encoded_prev(txt, &i);
}
if(txt[i] == '\n') break;
}
/* Do not let to return without doing nothing.
* Find at least one character (Avoid infinite loop )*/
if(i == 0) lv_txt_encoded_next(txt, &i);
/* If this is the last of the string, make sure pointer is at NULL-terminator.
* This catches the case, for example of a string ending in "\n" */
if(txt[i] != '\0'){
uint32_t i_next = i;
int tmp;
uint32_t letter_next = lv_txt_encoded_next(txt, &i_next); /*Gets current character*/
tmp = i_next;
letter_next = lv_txt_encoded_next(txt, &i_next); /*Gets subsequent character*/
if(letter_next == '\0') i = tmp;
}
return i;
}
/*If this char still can fit to this line then check if
* txt can be broken here later */
else if(is_break_char(letter)) {
last_break = i; /*Save the first char index after break*/
}
}
if(letter_w > 0) {
cur_w += letter_space;
}
/*Always step at least one to avoid infinite loops*/
if(i == 0) {
lv_txt_encoded_next(txt, &i);
}
return i;

View File

@ -9,6 +9,7 @@
#include "lv_arc.h"
#if LV_USE_ARC != 0
#include "../lv_core/lv_debug.h"
#include "../lv_misc/lv_math.h"
#include "../lv_draw/lv_draw_arc.h"
#include "../lv_themes/lv_theme.h"
@ -16,6 +17,7 @@
/*********************
* DEFINES
*********************/
#define LV_OBJX_NAME "lv_arc"
/**********************
* TYPEDEFS
@ -54,12 +56,12 @@ lv_obj_t * lv_arc_create(lv_obj_t * par, const lv_obj_t * copy)
/*Create the ancestor of arc*/
lv_obj_t * new_arc = lv_obj_create(par, copy);
lv_mem_assert(new_arc);
LV_ASSERT_MEM(new_arc);
if(new_arc == NULL) return NULL;
/*Allocate the arc type specific extended data*/
lv_arc_ext_t * ext = lv_obj_allocate_ext_attr(new_arc, sizeof(lv_arc_ext_t));
lv_mem_assert(ext);
LV_ASSERT_MEM(ext);
if(ext == NULL) return NULL;
if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(new_arc);
@ -119,6 +121,8 @@ lv_obj_t * lv_arc_create(lv_obj_t * par, const lv_obj_t * copy)
*/
void lv_arc_set_angles(lv_obj_t * arc, uint16_t start, uint16_t end)
{
LV_ASSERT_OBJ(arc, LV_OBJX_NAME);
lv_arc_ext_t * ext = lv_obj_get_ext_attr(arc);
if(start > 360) start = 360;
@ -138,6 +142,8 @@ void lv_arc_set_angles(lv_obj_t * arc, uint16_t start, uint16_t end)
* */
void lv_arc_set_style(lv_obj_t * arc, lv_arc_style_t type, const lv_style_t * style)
{
LV_ASSERT_OBJ(arc, LV_OBJX_NAME);
switch(type) {
case LV_ARC_STYLE_MAIN: lv_obj_set_style(arc, style); break;
}
@ -154,6 +160,8 @@ void lv_arc_set_style(lv_obj_t * arc, lv_arc_style_t type, const lv_style_t * st
*/
uint16_t lv_arc_get_angle_start(lv_obj_t * arc)
{
LV_ASSERT_OBJ(arc, LV_OBJX_NAME);
lv_arc_ext_t * ext = lv_obj_get_ext_attr(arc);
return ext->angle_start;
@ -166,6 +174,8 @@ uint16_t lv_arc_get_angle_start(lv_obj_t * arc)
*/
uint16_t lv_arc_get_angle_end(lv_obj_t * arc)
{
LV_ASSERT_OBJ(arc, LV_OBJX_NAME);
lv_arc_ext_t * ext = lv_obj_get_ext_attr(arc);
return ext->angle_end;
@ -179,6 +189,8 @@ uint16_t lv_arc_get_angle_end(lv_obj_t * arc)
* */
const lv_style_t * lv_arc_get_style(const lv_obj_t * arc, lv_arc_style_t type)
{
LV_ASSERT_OBJ(arc, LV_OBJX_NAME);
const lv_style_t * style = NULL;
switch(type) {
@ -281,15 +293,10 @@ static lv_res_t lv_arc_signal(lv_obj_t * arc, lv_signal_t sign, void * param)
res = ancestor_signal(arc, sign, param);
if(res != LV_RES_OK) return res;
if(sign == LV_SIGNAL_GET_TYPE) return lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
if(sign == LV_SIGNAL_CLEANUP) {
/*Nothing to cleanup. (No dynamically allocated memory in 'ext')*/
} else if(sign == LV_SIGNAL_GET_TYPE) {
lv_obj_type_t * buf = param;
uint8_t i;
for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/
if(buf->type[i] == NULL) break;
}
buf->type[i] = "lv_arc";
}
return res;

View File

@ -11,6 +11,7 @@
#include "lv_bar.h"
#if LV_USE_BAR != 0
#include "../lv_core/lv_debug.h"
#include "../lv_draw/lv_draw.h"
#include "../lv_themes/lv_theme.h"
#include "../lv_misc/lv_anim.h"
@ -19,6 +20,7 @@
/*********************
* DEFINES
*********************/
#define LV_OBJX_NAME "lv_bar"
/**********************
* TYPEDEFS
@ -61,7 +63,7 @@ lv_obj_t * lv_bar_create(lv_obj_t * par, const lv_obj_t * copy)
/*Create the ancestor basic object*/
lv_obj_t * new_bar = lv_obj_create(par, copy);
lv_mem_assert(new_bar);
LV_ASSERT_MEM(new_bar);
if(new_bar == NULL) return NULL;
if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(new_bar);
@ -69,7 +71,7 @@ lv_obj_t * lv_bar_create(lv_obj_t * par, const lv_obj_t * copy)
/*Allocate the object type specific extended data*/
lv_bar_ext_t * ext = lv_obj_allocate_ext_attr(new_bar, sizeof(lv_bar_ext_t));
lv_mem_assert(ext);
LV_ASSERT_MEM(ext);
if(ext == NULL) return NULL;
ext->min_value = 0;
@ -130,6 +132,8 @@ lv_obj_t * lv_bar_create(lv_obj_t * par, const lv_obj_t * copy)
*/
void lv_bar_set_value(lv_obj_t * bar, int16_t value, lv_anim_enable_t anim)
{
LV_ASSERT_OBJ(bar, LV_OBJX_NAME);
#if LV_USE_ANIMATION == 0
anim = false;
#endif
@ -185,6 +189,8 @@ void lv_bar_set_value(lv_obj_t * bar, int16_t value, lv_anim_enable_t anim)
*/
void lv_bar_set_range(lv_obj_t * bar, int16_t min, int16_t max)
{
LV_ASSERT_OBJ(bar, LV_OBJX_NAME);
lv_bar_ext_t * ext = lv_obj_get_ext_attr(bar);
if(ext->min_value == min && ext->max_value == max) return;
@ -209,6 +215,8 @@ void lv_bar_set_range(lv_obj_t * bar, int16_t min, int16_t max)
*/
void lv_bar_set_sym(lv_obj_t * bar, bool en)
{
LV_ASSERT_OBJ(bar, LV_OBJX_NAME);
lv_bar_ext_t * ext = lv_obj_get_ext_attr(bar);
ext->sym = en ? 1 : 0;
}
@ -220,6 +228,8 @@ void lv_bar_set_sym(lv_obj_t * bar, bool en)
*/
void lv_bar_set_anim_time(lv_obj_t * bar, uint16_t anim_time)
{
LV_ASSERT_OBJ(bar, LV_OBJX_NAME);
#if LV_USE_ANIMATION
lv_bar_ext_t * ext = lv_obj_get_ext_attr(bar);
ext->anim_time = anim_time;
@ -237,6 +247,8 @@ void lv_bar_set_anim_time(lv_obj_t * bar, uint16_t anim_time)
*/
void lv_bar_set_style(lv_obj_t * bar, lv_bar_style_t type, const lv_style_t * style)
{
LV_ASSERT_OBJ(bar, LV_OBJX_NAME);
lv_bar_ext_t * ext = lv_obj_get_ext_attr(bar);
switch(type) {
@ -259,6 +271,8 @@ void lv_bar_set_style(lv_obj_t * bar, lv_bar_style_t type, const lv_style_t * st
*/
int16_t lv_bar_get_value(const lv_obj_t * bar)
{
LV_ASSERT_OBJ(bar, LV_OBJX_NAME);
lv_bar_ext_t * ext = lv_obj_get_ext_attr(bar);
/*If animated tell that it's already at the end value*/
#if LV_USE_ANIMATION
@ -275,6 +289,8 @@ int16_t lv_bar_get_value(const lv_obj_t * bar)
*/
int16_t lv_bar_get_min_value(const lv_obj_t * bar)
{
LV_ASSERT_OBJ(bar, LV_OBJX_NAME);
lv_bar_ext_t * ext = lv_obj_get_ext_attr(bar);
return ext->min_value;
}
@ -286,6 +302,8 @@ int16_t lv_bar_get_min_value(const lv_obj_t * bar)
*/
int16_t lv_bar_get_max_value(const lv_obj_t * bar)
{
LV_ASSERT_OBJ(bar, LV_OBJX_NAME);
lv_bar_ext_t * ext = lv_obj_get_ext_attr(bar);
return ext->max_value;
}
@ -297,6 +315,8 @@ int16_t lv_bar_get_max_value(const lv_obj_t * bar)
*/
bool lv_bar_get_sym(lv_obj_t * bar)
{
LV_ASSERT_OBJ(bar, LV_OBJX_NAME);
lv_bar_ext_t * ext = lv_obj_get_ext_attr(bar);
return ext->sym ? true : false;
}
@ -308,6 +328,8 @@ bool lv_bar_get_sym(lv_obj_t * bar)
*/
uint16_t lv_bar_get_anim_time(lv_obj_t * bar)
{
LV_ASSERT_OBJ(bar, LV_OBJX_NAME);
#if LV_USE_ANIMATION
lv_bar_ext_t * ext = lv_obj_get_ext_attr(bar);
return ext->anim_time;
@ -325,6 +347,8 @@ uint16_t lv_bar_get_anim_time(lv_obj_t * bar)
*/
const lv_style_t * lv_bar_get_style(const lv_obj_t * bar, lv_bar_style_t type)
{
LV_ASSERT_OBJ(bar, LV_OBJX_NAME);
const lv_style_t * style = NULL;
lv_bar_ext_t * ext = lv_obj_get_ext_attr(bar);
@ -495,17 +519,11 @@ static lv_res_t lv_bar_signal(lv_obj_t * bar, lv_signal_t sign, void * param)
/* Include the ancient signal function */
res = ancestor_signal(bar, sign, param);
if(res != LV_RES_OK) return res;
if(sign == LV_SIGNAL_GET_TYPE) return lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
if(sign == LV_SIGNAL_REFR_EXT_DRAW_PAD) {
const lv_style_t * style_indic = lv_bar_get_style(bar, LV_BAR_STYLE_INDIC);
if(style_indic->body.shadow.width > bar->ext_draw_pad) bar->ext_draw_pad = style_indic->body.shadow.width;
} else if(sign == LV_SIGNAL_GET_TYPE) {
lv_obj_type_t * buf = param;
uint8_t i;
for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/
if(buf->type[i] == NULL) break;
}
buf->type[i] = "lv_bar";
}
return res;

View File

@ -43,6 +43,11 @@ extern "C" {
/** log2(LV_BAR_ANIM_STATE_END) used to normalize data*/
#define LV_BAR_ANIM_STATE_NORM 8
LV_EXPORT_CONST_INT(LV_BAR_ANIM_STATE_START);
LV_EXPORT_CONST_INT(LV_BAR_ANIM_STATE_END);
LV_EXPORT_CONST_INT(LV_BAR_ANIM_STATE_INV);
LV_EXPORT_CONST_INT(LV_BAR_ANIM_STATE_NORM);
/**********************
* TYPEDEFS
**********************/

View File

@ -12,6 +12,7 @@
#include <string.h>
#include "../lv_core/lv_group.h"
#include "../lv_core/lv_debug.h"
#include "../lv_draw/lv_draw.h"
#include "../lv_themes/lv_theme.h"
#include "../lv_misc/lv_area.h"
@ -21,6 +22,7 @@
/*********************
* DEFINES
*********************/
#define LV_OBJX_NAME "lv_btn"
#define LV_BTN_INK_VALUE_MAX 256
#define LV_BTN_INK_VALUE_MAX_SHIFT 8
@ -76,7 +78,7 @@ lv_obj_t * lv_btn_create(lv_obj_t * par, const lv_obj_t * copy)
lv_obj_t * new_btn;
new_btn = lv_cont_create(par, copy);
lv_mem_assert(new_btn);
LV_ASSERT_MEM(new_btn);
if(new_btn == NULL) return NULL;
if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(new_btn);
@ -84,7 +86,7 @@ lv_obj_t * lv_btn_create(lv_obj_t * par, const lv_obj_t * copy)
/*Allocate the extended data*/
lv_btn_ext_t * ext = lv_obj_allocate_ext_attr(new_btn, sizeof(lv_btn_ext_t));
lv_mem_assert(ext);
LV_ASSERT_MEM(ext);
if(ext == NULL) return NULL;
ext->state = LV_BTN_STATE_REL;
@ -158,6 +160,8 @@ lv_obj_t * lv_btn_create(lv_obj_t * par, const lv_obj_t * copy)
*/
void lv_btn_set_toggle(lv_obj_t * btn, bool tgl)
{
LV_ASSERT_OBJ(btn, LV_OBJX_NAME);
lv_btn_ext_t * ext = lv_obj_get_ext_attr(btn);
ext->toggle = tgl != false ? 1 : 0;
@ -170,6 +174,8 @@ void lv_btn_set_toggle(lv_obj_t * btn, bool tgl)
*/
void lv_btn_set_state(lv_obj_t * btn, lv_btn_state_t state)
{
LV_ASSERT_OBJ(btn, LV_OBJX_NAME);
lv_btn_ext_t * ext = lv_obj_get_ext_attr(btn);
if(ext->state != state) {
ext->state = state;
@ -183,6 +189,8 @@ void lv_btn_set_state(lv_obj_t * btn, lv_btn_state_t state)
*/
void lv_btn_toggle(lv_obj_t * btn)
{
LV_ASSERT_OBJ(btn, LV_OBJX_NAME);
lv_btn_ext_t * ext = lv_obj_get_ext_attr(btn);
switch(ext->state) {
case LV_BTN_STATE_REL: lv_btn_set_state(btn, LV_BTN_STATE_TGL_REL); break;
@ -200,6 +208,8 @@ void lv_btn_toggle(lv_obj_t * btn)
*/
void lv_btn_set_ink_in_time(lv_obj_t * btn, uint16_t time)
{
LV_ASSERT_OBJ(btn, LV_OBJX_NAME);
#if LV_USE_ANIMATION && LV_BTN_INK_EFFECT
lv_btn_ext_t * ext = lv_obj_get_ext_attr(btn);
ext->ink_in_time = time;
@ -218,6 +228,8 @@ void lv_btn_set_ink_in_time(lv_obj_t * btn, uint16_t time)
*/
void lv_btn_set_ink_wait_time(lv_obj_t * btn, uint16_t time)
{
LV_ASSERT_OBJ(btn, LV_OBJX_NAME);
#if LV_USE_ANIMATION && LV_BTN_INK_EFFECT
lv_btn_ext_t * ext = lv_obj_get_ext_attr(btn);
@ -237,6 +249,8 @@ void lv_btn_set_ink_wait_time(lv_obj_t * btn, uint16_t time)
*/
void lv_btn_set_ink_out_time(lv_obj_t * btn, uint16_t time)
{
LV_ASSERT_OBJ(btn, LV_OBJX_NAME);
#if LV_USE_ANIMATION && LV_BTN_INK_EFFECT
lv_btn_ext_t * ext = lv_obj_get_ext_attr(btn);
ext->ink_out_time = time;
@ -256,6 +270,8 @@ void lv_btn_set_ink_out_time(lv_obj_t * btn, uint16_t time)
*/
void lv_btn_set_style(lv_obj_t * btn, lv_btn_style_t type, const lv_style_t * style)
{
LV_ASSERT_OBJ(btn, LV_OBJX_NAME);
lv_btn_ext_t * ext = lv_obj_get_ext_attr(btn);
switch(type) {
@ -281,6 +297,8 @@ void lv_btn_set_style(lv_obj_t * btn, lv_btn_style_t type, const lv_style_t * st
*/
lv_btn_state_t lv_btn_get_state(const lv_obj_t * btn)
{
LV_ASSERT_OBJ(btn, LV_OBJX_NAME);
lv_btn_ext_t * ext = lv_obj_get_ext_attr(btn);
return ext->state;
}
@ -292,6 +310,8 @@ lv_btn_state_t lv_btn_get_state(const lv_obj_t * btn)
*/
bool lv_btn_get_toggle(const lv_obj_t * btn)
{
LV_ASSERT_OBJ(btn, LV_OBJX_NAME);
lv_btn_ext_t * ext = lv_obj_get_ext_attr(btn);
return ext->toggle != 0 ? true : false;
@ -304,6 +324,8 @@ bool lv_btn_get_toggle(const lv_obj_t * btn)
*/
uint16_t lv_btn_get_ink_in_time(const lv_obj_t * btn)
{
LV_ASSERT_OBJ(btn, LV_OBJX_NAME);
#if LV_USE_ANIMATION && LV_BTN_INK_EFFECT
lv_btn_ext_t * ext = lv_obj_get_ext_attr(btn);
return ext->ink_in_time;
@ -320,6 +342,8 @@ uint16_t lv_btn_get_ink_in_time(const lv_obj_t * btn)
*/
uint16_t lv_btn_get_ink_wait_time(const lv_obj_t * btn)
{
LV_ASSERT_OBJ(btn, LV_OBJX_NAME);
#if LV_USE_ANIMATION && LV_BTN_INK_EFFECT
lv_btn_ext_t * ext = lv_obj_get_ext_attr(btn);
return ext->ink_wait_time;
@ -335,6 +359,8 @@ uint16_t lv_btn_get_ink_wait_time(const lv_obj_t * btn)
*/
uint16_t lv_btn_get_ink_out_time(const lv_obj_t * btn)
{
LV_ASSERT_OBJ(btn, LV_OBJX_NAME);
#if LV_USE_ANIMATION && LV_BTN_INK_EFFECT
lv_btn_ext_t * ext = lv_obj_get_ext_attr(btn);
return ext->ink_in_time;
@ -352,6 +378,8 @@ uint16_t lv_btn_get_ink_out_time(const lv_obj_t * btn)
*/
const lv_style_t * lv_btn_get_style(const lv_obj_t * btn, lv_btn_style_t type)
{
LV_ASSERT_OBJ(btn, LV_OBJX_NAME);
const lv_style_t * style = NULL;
lv_btn_ext_t * ext = lv_obj_get_ext_attr(btn);
lv_btn_state_t state = lv_btn_get_state(btn);
@ -483,6 +511,7 @@ static lv_res_t lv_btn_signal(lv_obj_t * btn, lv_signal_t sign, void * param)
/* Include the ancient signal function */
res = ancestor_signal(btn, sign, param);
if(res != LV_RES_OK) return res;
if(sign == LV_SIGNAL_GET_TYPE) return lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
lv_btn_ext_t * ext = lv_obj_get_ext_attr(btn);
bool tgl = lv_btn_get_toggle(btn);
@ -634,13 +663,6 @@ static lv_res_t lv_btn_signal(lv_obj_t * btn, lv_signal_t sign, void * param)
ink_obj = NULL;
}
#endif
} else if(sign == LV_SIGNAL_GET_TYPE) {
lv_obj_type_t * buf = param;
uint8_t i;
for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/
if(buf->type[i] == NULL) break;
}
buf->type[i] = "lv_btn";
}
return res;

View File

@ -9,6 +9,7 @@
#include "lv_btnm.h"
#if LV_USE_BTNM != 0
#include "../lv_core/lv_debug.h"
#include "../lv_core/lv_group.h"
#include "../lv_draw/lv_draw.h"
#include "../lv_core/lv_refr.h"
@ -18,6 +19,7 @@
/*********************
* DEFINES
*********************/
#define LV_OBJX_NAME "lv_btnm"
/**********************
* TYPEDEFS
@ -70,14 +72,14 @@ lv_obj_t * lv_btnm_create(lv_obj_t * par, const lv_obj_t * copy)
/*Create the ancestor object*/
lv_obj_t * new_btnm = lv_obj_create(par, copy);
lv_mem_assert(new_btnm);
LV_ASSERT_MEM(new_btnm);
if(new_btnm == NULL) return NULL;
if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(new_btnm);
/*Allocate the object type specific extended data*/
lv_btnm_ext_t * ext = lv_obj_allocate_ext_attr(new_btnm, sizeof(lv_btnm_ext_t));
lv_mem_assert(ext);
LV_ASSERT_MEM(ext);
if(ext == NULL) return NULL;
ext->btn_cnt = 0;
@ -101,8 +103,8 @@ lv_obj_t * lv_btnm_create(lv_obj_t * par, const lv_obj_t * copy)
/*Init the new button matrix object*/
if(copy == NULL) {
lv_obj_set_size(new_btnm, LV_DPI * 3, LV_DPI * 2);
lv_btnm_set_map(new_btnm, lv_btnm_def_map);
lv_obj_set_size(new_btnm, LV_DPI * 3, LV_DPI * 2);
/*Set the default styles*/
lv_theme_t * th = lv_theme_get_current();
@ -142,7 +144,8 @@ lv_obj_t * lv_btnm_create(lv_obj_t * par, const lv_obj_t * copy)
*/
void lv_btnm_set_map(const lv_obj_t * btnm, const char * map[])
{
if(map == NULL) return;
LV_ASSERT_OBJ(btnm, LV_OBJX_NAME);
LV_ASSERT_NULL(map);
/*
* lv_btnm_set_map is called on receipt of signals such as
@ -241,7 +244,7 @@ void lv_btnm_set_map(const lv_obj_t * btnm, const char * map[])
btn_i++;
}
}
act_y += btn_h + style_bg->body.padding.inner;
act_y += btn_h + style_bg->body.padding.inner + 1;
if(strlen(map_p_tmp[btn_cnt]) == 0) break; /*Break on end of map*/
map_p_tmp = &map_p_tmp[btn_cnt + 1]; /*Set the map to the next line*/
@ -265,6 +268,8 @@ void lv_btnm_set_map(const lv_obj_t * btnm, const char * map[])
*/
void lv_btnm_set_ctrl_map(const lv_obj_t * btnm, const lv_btnm_ctrl_t ctrl_map[])
{
LV_ASSERT_OBJ(btnm, LV_OBJX_NAME);
lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm);
memcpy(ext->ctrl_bits, ctrl_map, sizeof(lv_btnm_ctrl_t) * ext->btn_cnt);
@ -279,6 +284,8 @@ void lv_btnm_set_ctrl_map(const lv_obj_t * btnm, const lv_btnm_ctrl_t ctrl_map[]
*/
void lv_btnm_set_pressed(const lv_obj_t * btnm, uint16_t id)
{
LV_ASSERT_OBJ(btnm, LV_OBJX_NAME);
lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm);
if(id >= ext->btn_cnt && id != LV_BTNM_BTN_NONE) return;
@ -297,6 +304,8 @@ void lv_btnm_set_pressed(const lv_obj_t * btnm, uint16_t id)
*/
void lv_btnm_set_style(lv_obj_t * btnm, lv_btnm_style_t type, const lv_style_t * style)
{
LV_ASSERT_OBJ(btnm, LV_OBJX_NAME);
lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm);
switch(type) {
@ -331,6 +340,8 @@ void lv_btnm_set_style(lv_obj_t * btnm, lv_btnm_style_t type, const lv_style_t *
*/
void lv_btnm_set_recolor(const lv_obj_t * btnm, bool en)
{
LV_ASSERT_OBJ(btnm, LV_OBJX_NAME);
lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm);
ext->recolor = en;
@ -344,6 +355,8 @@ void lv_btnm_set_recolor(const lv_obj_t * btnm, bool en)
*/
void lv_btnm_set_btn_ctrl(const lv_obj_t * btnm, uint16_t btn_id, lv_btnm_ctrl_t ctrl)
{
LV_ASSERT_OBJ(btnm, LV_OBJX_NAME);
lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm);
if(btn_id >= ext->btn_cnt) return;
@ -359,6 +372,8 @@ void lv_btnm_set_btn_ctrl(const lv_obj_t * btnm, uint16_t btn_id, lv_btnm_ctrl_t
*/
void lv_btnm_clear_btn_ctrl(const lv_obj_t * btnm, uint16_t btn_id, lv_btnm_ctrl_t ctrl)
{
LV_ASSERT_OBJ(btnm, LV_OBJX_NAME);
lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm);
if(btn_id >= ext->btn_cnt) return;
@ -374,6 +389,8 @@ void lv_btnm_clear_btn_ctrl(const lv_obj_t * btnm, uint16_t btn_id, lv_btnm_ctrl
*/
void lv_btnm_set_btn_ctrl_all(lv_obj_t * btnm, lv_btnm_ctrl_t ctrl)
{
LV_ASSERT_OBJ(btnm, LV_OBJX_NAME);
lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm);
uint16_t i;
for(i = 0; i < ext->btn_cnt; i++) {
@ -389,6 +406,8 @@ void lv_btnm_set_btn_ctrl_all(lv_obj_t * btnm, lv_btnm_ctrl_t ctrl)
*/
void lv_btnm_clear_btn_ctrl_all(lv_obj_t * btnm, lv_btnm_ctrl_t ctrl)
{
LV_ASSERT_OBJ(btnm, LV_OBJX_NAME);
lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm);
uint16_t i;
for(i = 0; i < ext->btn_cnt; i++) {
@ -407,6 +426,8 @@ void lv_btnm_clear_btn_ctrl_all(lv_obj_t * btnm, lv_btnm_ctrl_t ctrl)
*/
void lv_btnm_set_btn_width(const lv_obj_t * btnm, uint16_t btn_id, uint8_t width)
{
LV_ASSERT_OBJ(btnm, LV_OBJX_NAME);
lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm);
if(btn_id >= ext->btn_cnt) return;
@ -427,6 +448,8 @@ void lv_btnm_set_btn_width(const lv_obj_t * btnm, uint16_t btn_id, uint8_t width
*/
void lv_btnm_set_one_toggle(lv_obj_t * btnm, bool one_toggle)
{
LV_ASSERT_OBJ(btnm, LV_OBJX_NAME);
lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm);
ext->one_toggle = one_toggle;
@ -445,6 +468,8 @@ void lv_btnm_set_one_toggle(lv_obj_t * btnm, bool one_toggle)
*/
const char ** lv_btnm_get_map_array(const lv_obj_t * btnm)
{
LV_ASSERT_OBJ(btnm, LV_OBJX_NAME);
lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm);
return ext->map_p;
}
@ -456,6 +481,8 @@ const char ** lv_btnm_get_map_array(const lv_obj_t * btnm)
*/
bool lv_btnm_get_recolor(const lv_obj_t * btnm)
{
LV_ASSERT_OBJ(btnm, LV_OBJX_NAME);
lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm);
return ext->recolor;
@ -469,6 +496,8 @@ bool lv_btnm_get_recolor(const lv_obj_t * btnm)
*/
uint16_t lv_btnm_get_active_btn(const lv_obj_t * btnm)
{
LV_ASSERT_OBJ(btnm, LV_OBJX_NAME);
lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm);
return ext->btn_id_act;
}
@ -481,6 +510,8 @@ uint16_t lv_btnm_get_active_btn(const lv_obj_t * btnm)
*/
const char * lv_btnm_get_active_btn_text(const lv_obj_t * btnm)
{
LV_ASSERT_OBJ(btnm, LV_OBJX_NAME);
lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm);
if(ext->btn_id_act != LV_BTNM_BTN_NONE) {
return lv_btnm_get_btn_text(btnm, ext->btn_id_act);
@ -497,6 +528,8 @@ const char * lv_btnm_get_active_btn_text(const lv_obj_t * btnm)
*/
uint16_t lv_btnm_get_pressed_btn(const lv_obj_t * btnm)
{
LV_ASSERT_OBJ(btnm, LV_OBJX_NAME);
lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm);
return ext->btn_id_pr;
}
@ -510,6 +543,8 @@ uint16_t lv_btnm_get_pressed_btn(const lv_obj_t * btnm)
*/
const char * lv_btnm_get_btn_text(const lv_obj_t * btnm, uint16_t btn_id)
{
LV_ASSERT_OBJ(btnm, LV_OBJX_NAME);
lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm);
if(btn_id > ext->btn_cnt) return NULL;
@ -539,6 +574,8 @@ const char * lv_btnm_get_btn_text(const lv_obj_t * btnm, uint16_t btn_id)
*/
bool lv_btnm_get_btn_ctrl(lv_obj_t * btnm, uint16_t btn_id, lv_btnm_ctrl_t ctrl)
{
LV_ASSERT_OBJ(btnm, LV_OBJX_NAME);
lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm);
if(btn_id >= ext->btn_cnt) return false;
@ -553,6 +590,8 @@ bool lv_btnm_get_btn_ctrl(lv_obj_t * btnm, uint16_t btn_id, lv_btnm_ctrl_t ctrl)
*/
const lv_style_t * lv_btnm_get_style(const lv_obj_t * btnm, lv_btnm_style_t type)
{
LV_ASSERT_OBJ(btnm, LV_OBJX_NAME);
const lv_style_t * style = NULL;
lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm);
@ -576,6 +615,8 @@ const lv_style_t * lv_btnm_get_style(const lv_obj_t * btnm, lv_btnm_style_t type
*/
bool lv_btnm_get_one_toggle(const lv_obj_t * btnm)
{
LV_ASSERT_OBJ(btnm, LV_OBJX_NAME);
lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm);
return ext->one_toggle;
@ -713,6 +754,7 @@ static lv_res_t lv_btnm_signal(lv_obj_t * btnm, lv_signal_t sign, void * param)
/* Include the ancient signal function */
res = ancestor_signal(btnm, sign, param);
if(res != LV_RES_OK) return res;
if(sign == LV_SIGNAL_GET_TYPE) return lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm);
lv_point_t p;
@ -897,15 +939,7 @@ static lv_res_t lv_btnm_signal(lv_obj_t * btnm, lv_signal_t sign, void * param)
} else if(sign == LV_SIGNAL_GET_EDITABLE) {
bool * editable = (bool *)param;
*editable = true;
} else if(sign == LV_SIGNAL_GET_TYPE) {
lv_obj_type_t * buf = param;
uint8_t i;
for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/
if(buf->type[i] == NULL) break;
}
buf->type[i] = "lv_btnm";
}
return res;
}
@ -938,9 +972,9 @@ static void allocate_btn_areas_and_controls(const lv_obj_t * btnm, const char **
}
ext->button_areas = lv_mem_alloc(sizeof(lv_area_t) * btn_cnt);
lv_mem_assert(ext->button_areas);
LV_ASSERT_MEM(ext->button_areas);
ext->ctrl_bits = lv_mem_alloc(sizeof(lv_btnm_ctrl_t) * btn_cnt);
lv_mem_assert(ext->ctrl_bits);
LV_ASSERT_MEM(ext->ctrl_bits);
if(ext->button_areas == NULL || ext->ctrl_bits == NULL) btn_cnt = 0;
memset(ext->ctrl_bits, 0, sizeof(lv_btnm_ctrl_t) * btn_cnt);

View File

@ -31,6 +31,8 @@ extern "C" {
#define LV_BTNM_WIDTH_MASK 0x0007
#define LV_BTNM_BTN_NONE 0xFFFF
LV_EXPORT_CONST_INT(LV_BTNM_BTN_NONE);
/**********************
* TYPEDEFS
**********************/

View File

@ -9,6 +9,7 @@
#include "lv_calendar.h"
#if LV_USE_CALENDAR != 0
#include "../lv_core/lv_debug.h"
#include "../lv_draw/lv_draw.h"
#include "../lv_hal/lv_hal_indev.h"
#include "../lv_misc/lv_utils.h"
@ -19,6 +20,7 @@
/*********************
* DEFINES
*********************/
#define LV_OBJX_NAME "lv_calendar"
/**********************
* TYPEDEFS
@ -77,12 +79,12 @@ lv_obj_t * lv_calendar_create(lv_obj_t * par, const lv_obj_t * copy)
/*Create the ancestor of calendar*/
lv_obj_t * new_calendar = lv_obj_create(par, copy);
lv_mem_assert(new_calendar);
LV_ASSERT_MEM(new_calendar);
if(new_calendar == NULL) return NULL;
/*Allocate the calendar type specific extended data*/
lv_calendar_ext_t * ext = lv_obj_allocate_ext_attr(new_calendar, sizeof(lv_calendar_ext_t));
lv_mem_assert(ext);
LV_ASSERT_MEM(ext);
if(ext == NULL) return NULL;
if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(new_calendar);
if(ancestor_design == NULL) ancestor_design = lv_obj_get_design_cb(new_calendar);
@ -195,6 +197,9 @@ lv_obj_t * lv_calendar_create(lv_obj_t * par, const lv_obj_t * copy)
*/
void lv_calendar_set_today_date(lv_obj_t * calendar, lv_calendar_date_t * today)
{
LV_ASSERT_OBJ(calendar, LV_OBJX_NAME);
LV_ASSERT_NULL(today);
lv_calendar_ext_t * ext = lv_obj_get_ext_attr(calendar);
ext->today.year = today->year;
ext->today.month = today->month;
@ -211,6 +216,9 @@ void lv_calendar_set_today_date(lv_obj_t * calendar, lv_calendar_date_t * today)
*/
void lv_calendar_set_showed_date(lv_obj_t * calendar, lv_calendar_date_t * showed)
{
LV_ASSERT_OBJ(calendar, LV_OBJX_NAME);
LV_ASSERT_NULL(showed);
lv_calendar_ext_t * ext = lv_obj_get_ext_attr(calendar);
ext->showed_date.year = showed->year;
ext->showed_date.month = showed->month;
@ -228,6 +236,9 @@ void lv_calendar_set_showed_date(lv_obj_t * calendar, lv_calendar_date_t * showe
*/
void lv_calendar_set_highlighted_dates(lv_obj_t * calendar, lv_calendar_date_t * highlighted, uint16_t date_num)
{
LV_ASSERT_OBJ(calendar, LV_OBJX_NAME);
LV_ASSERT_NULL(highlighted);
lv_calendar_ext_t * ext = lv_obj_get_ext_attr(calendar);
ext->highlighted_dates = highlighted;
ext->highlighted_dates_num = date_num;
@ -244,6 +255,9 @@ void lv_calendar_set_highlighted_dates(lv_obj_t * calendar, lv_calendar_date_t *
*/
void lv_calendar_set_day_names(lv_obj_t * calendar, const char ** day_names)
{
LV_ASSERT_OBJ(calendar, LV_OBJX_NAME);
LV_ASSERT_NULL(day_names);
lv_calendar_ext_t * ext = lv_obj_get_ext_attr(calendar);
ext->day_names = day_names;
lv_obj_invalidate(calendar);
@ -252,14 +266,17 @@ 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 day_names pointer to an array with the names. E.g. `const char * days[12] = {"Jan", "Feb",
* @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 ** day_names)
void lv_calendar_set_month_names(lv_obj_t * calendar, const char ** month_names)
{
LV_ASSERT_OBJ(calendar, LV_OBJX_NAME);
LV_ASSERT_NULL(month_names);
lv_calendar_ext_t * ext = lv_obj_get_ext_attr(calendar);
ext->month_names = day_names;
ext->month_names = month_names;
lv_obj_invalidate(calendar);
}
@ -271,6 +288,8 @@ void lv_calendar_set_month_names(lv_obj_t * calendar, const char ** day_names)
* */
void lv_calendar_set_style(lv_obj_t * calendar, lv_calendar_style_t type, const lv_style_t * style)
{
LV_ASSERT_OBJ(calendar, LV_OBJX_NAME);
lv_calendar_ext_t * ext = lv_obj_get_ext_attr(calendar);
switch(type) {
@ -298,6 +317,8 @@ void lv_calendar_set_style(lv_obj_t * calendar, lv_calendar_style_t type, const
*/
lv_calendar_date_t * lv_calendar_get_today_date(const lv_obj_t * calendar)
{
LV_ASSERT_OBJ(calendar, LV_OBJX_NAME);
lv_calendar_ext_t * ext = lv_obj_get_ext_attr(calendar);
return &ext->today;
}
@ -309,6 +330,8 @@ lv_calendar_date_t * lv_calendar_get_today_date(const lv_obj_t * calendar)
*/
lv_calendar_date_t * lv_calendar_get_showed_date(const lv_obj_t * calendar)
{
LV_ASSERT_OBJ(calendar, LV_OBJX_NAME);
lv_calendar_ext_t * ext = lv_obj_get_ext_attr(calendar);
return &ext->showed_date;
}
@ -321,6 +344,8 @@ lv_calendar_date_t * lv_calendar_get_showed_date(const lv_obj_t * calendar)
*/
lv_calendar_date_t * lv_calendar_get_pressed_date(const lv_obj_t * calendar)
{
LV_ASSERT_OBJ(calendar, LV_OBJX_NAME);
lv_calendar_ext_t * ext = lv_obj_get_ext_attr(calendar);
return ext->pressed_date.year != 0 ? &ext->pressed_date : NULL;
}
@ -332,6 +357,8 @@ lv_calendar_date_t * lv_calendar_get_pressed_date(const lv_obj_t * calendar)
*/
lv_calendar_date_t * lv_calendar_get_highlighted_dates(const lv_obj_t * calendar)
{
LV_ASSERT_OBJ(calendar, LV_OBJX_NAME);
lv_calendar_ext_t * ext = lv_obj_get_ext_attr(calendar);
return ext->highlighted_dates;
}
@ -343,6 +370,8 @@ lv_calendar_date_t * lv_calendar_get_highlighted_dates(const lv_obj_t * calendar
*/
uint16_t lv_calendar_get_highlighted_dates_num(const lv_obj_t * calendar)
{
LV_ASSERT_OBJ(calendar, LV_OBJX_NAME);
lv_calendar_ext_t * ext = lv_obj_get_ext_attr(calendar);
return ext->highlighted_dates_num;
}
@ -354,6 +383,8 @@ uint16_t lv_calendar_get_highlighted_dates_num(const lv_obj_t * calendar)
*/
const char ** lv_calendar_get_day_names(const lv_obj_t * calendar)
{
LV_ASSERT_OBJ(calendar, LV_OBJX_NAME);
lv_calendar_ext_t * ext = lv_obj_get_ext_attr(calendar);
return ext->day_names;
}
@ -365,6 +396,8 @@ const char ** lv_calendar_get_day_names(const lv_obj_t * calendar)
*/
const char ** lv_calendar_get_month_names(const lv_obj_t * calendar)
{
LV_ASSERT_OBJ(calendar, LV_OBJX_NAME);
lv_calendar_ext_t * ext = lv_obj_get_ext_attr(calendar);
return ext->month_names;
}
@ -377,6 +410,8 @@ const char ** lv_calendar_get_month_names(const lv_obj_t * calendar)
* */
const lv_style_t * lv_calendar_get_style(const lv_obj_t * calendar, lv_calendar_style_t type)
{
LV_ASSERT_OBJ(calendar, LV_OBJX_NAME);
const lv_style_t * style = NULL;
lv_calendar_ext_t * ext = lv_obj_get_ext_attr(calendar);
@ -454,6 +489,7 @@ static lv_res_t lv_calendar_signal(lv_obj_t * calendar, lv_signal_t sign, void *
/* Include the ancient signal function */
res = ancestor_signal(calendar, sign, param);
if(res != LV_RES_OK) return res;
if(sign == LV_SIGNAL_GET_TYPE) return lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
if(sign == LV_SIGNAL_CLEANUP) {
/*Nothing to cleanup. (No dynamically allocated memory in 'ext')*/
@ -542,13 +578,6 @@ static lv_res_t lv_calendar_signal(lv_obj_t * calendar, lv_signal_t sign, void *
}
lv_obj_invalidate(calendar);
}
} else if(sign == LV_SIGNAL_GET_TYPE) {
lv_obj_type_t * buf = param;
uint8_t i;
for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set date*/
if(buf->type[i] == NULL) break;
}
buf->type[i] = "lv_calendar";
}
return res;

View File

@ -136,11 +136,11 @@ 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 day_names pointer to an array with the names. E.g. `const char * days[12] = {"Jan", "Feb",
* @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 ** day_names);
void lv_calendar_set_month_names(lv_obj_t * calendar, const char ** month_names);
/**
* Set a style of a calendar.

View File

@ -8,6 +8,7 @@
*********************/
#include <stdlib.h>
#include "lv_canvas.h"
#include "../lv_core/lv_debug.h"
#include "../lv_misc/lv_math.h"
#include "../lv_draw/lv_draw.h"
#include "../lv_core/lv_refr.h"
@ -17,6 +18,7 @@
/*********************
* DEFINES
*********************/
#define LV_OBJX_NAME "lv_canvas"
/**********************
* TYPEDEFS
@ -53,12 +55,12 @@ lv_obj_t * lv_canvas_create(lv_obj_t * par, const lv_obj_t * copy)
/*Create the ancestor of canvas*/
lv_obj_t * new_canvas = lv_img_create(par, copy);
lv_mem_assert(new_canvas);
LV_ASSERT_MEM(new_canvas);
if(new_canvas == NULL) return NULL;
/*Allocate the canvas type specific extended data*/
lv_canvas_ext_t * ext = lv_obj_allocate_ext_attr(new_canvas, sizeof(lv_canvas_ext_t));
lv_mem_assert(ext);
LV_ASSERT_MEM(ext);
if(ext == NULL) return NULL;
if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(new_canvas);
if(ancestor_design == NULL) ancestor_design = lv_obj_get_design_cb(new_canvas);
@ -111,6 +113,9 @@ lv_obj_t * lv_canvas_create(lv_obj_t * par, const lv_obj_t * copy)
*/
void lv_canvas_set_buffer(lv_obj_t * canvas, void * buf, lv_coord_t w, lv_coord_t h, lv_img_cf_t cf)
{
LV_ASSERT_OBJ(canvas, LV_OBJX_NAME);
LV_ASSERT_NULL(buf);
lv_canvas_ext_t * ext = lv_obj_get_ext_attr(canvas);
ext->dsc.header.cf = cf;
@ -131,6 +136,8 @@ void lv_canvas_set_buffer(lv_obj_t * canvas, void * buf, lv_coord_t w, lv_coord_
*/
void lv_canvas_set_px(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y, lv_color_t c)
{
LV_ASSERT_OBJ(canvas, LV_OBJX_NAME);
lv_canvas_ext_t * ext = lv_obj_get_ext_attr(canvas);
lv_img_buf_set_px_color(&ext->dsc, x, y, c);
@ -149,6 +156,8 @@ void lv_canvas_set_px(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y, lv_color_t
*/
void lv_canvas_set_palette(lv_obj_t * canvas, uint8_t id, lv_color_t c)
{
LV_ASSERT_OBJ(canvas, LV_OBJX_NAME);
lv_canvas_ext_t * ext = lv_obj_get_ext_attr(canvas);
lv_img_buf_set_palette(&ext->dsc, id, c);
@ -163,6 +172,8 @@ void lv_canvas_set_palette(lv_obj_t * canvas, uint8_t id, lv_color_t c)
*/
void lv_canvas_set_style(lv_obj_t * canvas, lv_canvas_style_t type, const lv_style_t * style)
{
LV_ASSERT_OBJ(canvas, LV_OBJX_NAME);
switch(type) {
case LV_CANVAS_STYLE_MAIN: lv_img_set_style(canvas, LV_IMG_STYLE_MAIN, style); break;
}
@ -181,6 +192,8 @@ void lv_canvas_set_style(lv_obj_t * canvas, lv_canvas_style_t type, const lv_sty
*/
lv_color_t lv_canvas_get_px(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y)
{
LV_ASSERT_OBJ(canvas, LV_OBJX_NAME);
lv_canvas_ext_t * ext = lv_obj_get_ext_attr(canvas);
const lv_style_t * style = lv_canvas_get_style(canvas, LV_CANVAS_STYLE_MAIN);
@ -194,6 +207,8 @@ lv_color_t lv_canvas_get_px(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y)
*/
lv_img_dsc_t * lv_canvas_get_img(lv_obj_t * canvas)
{
LV_ASSERT_OBJ(canvas, LV_OBJX_NAME);
lv_canvas_ext_t * ext = lv_obj_get_ext_attr(canvas);
return &ext->dsc;
@ -207,6 +222,8 @@ lv_img_dsc_t * lv_canvas_get_img(lv_obj_t * canvas)
*/
const lv_style_t * lv_canvas_get_style(const lv_obj_t * canvas, lv_canvas_style_t type)
{
LV_ASSERT_OBJ(canvas, LV_OBJX_NAME);
const lv_style_t * style = NULL;
switch(type) {
@ -233,6 +250,9 @@ const lv_style_t * lv_canvas_get_style(const lv_obj_t * canvas, lv_canvas_style_
*/
void lv_canvas_copy_buf(lv_obj_t * canvas, const void * to_copy, lv_coord_t x, lv_coord_t y, lv_coord_t w, lv_coord_t h)
{
LV_ASSERT_OBJ(canvas, LV_OBJX_NAME);
LV_ASSERT_NULL(to_copy);
lv_canvas_ext_t * ext = lv_obj_get_ext_attr(canvas);
if(x + w >= ext->dsc.header.w || y + h >= ext->dsc.header.h) {
LV_LOG_WARN("lv_canvas_copy_buf: x or y out of the canvas");
@ -266,6 +286,9 @@ void lv_canvas_copy_buf(lv_obj_t * canvas, const void * to_copy, lv_coord_t x, l
void lv_canvas_rotate(lv_obj_t * canvas, lv_img_dsc_t * img, int16_t angle, lv_coord_t offset_x, lv_coord_t offset_y,
int32_t pivot_x, int32_t pivot_y)
{
LV_ASSERT_OBJ(canvas, LV_OBJX_NAME);
LV_ASSERT_NULL(img);
lv_canvas_ext_t * ext_dst = lv_obj_get_ext_attr(canvas);
const lv_style_t * style = lv_canvas_get_style(canvas, LV_CANVAS_STYLE_MAIN);
int32_t sinma = lv_trigo_sin(-angle);
@ -430,6 +453,8 @@ void lv_canvas_rotate(lv_obj_t * canvas, lv_img_dsc_t * img, int16_t angle, lv_c
*/
void lv_canvas_fill_bg(lv_obj_t * canvas, lv_color_t color)
{
LV_ASSERT_OBJ(canvas, LV_OBJX_NAME);
lv_img_dsc_t * dsc = lv_canvas_get_img(canvas);
uint32_t x = dsc->header.w * dsc->header.h;
@ -453,6 +478,9 @@ void lv_canvas_fill_bg(lv_obj_t * canvas, lv_color_t color)
void lv_canvas_draw_rect(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y, lv_coord_t w, lv_coord_t h,
const lv_style_t * style)
{
LV_ASSERT_OBJ(canvas, LV_OBJX_NAME);
LV_ASSERT_NULL(style);
lv_img_dsc_t * dsc = lv_canvas_get_img(canvas);
/* Create a dummy display to fool the lv_draw function.
@ -514,6 +542,9 @@ void lv_canvas_draw_rect(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y, lv_coord
void lv_canvas_draw_text(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y, lv_coord_t max_w, const lv_style_t * style,
const char * txt, lv_label_align_t align)
{
LV_ASSERT_OBJ(canvas, LV_OBJX_NAME);
LV_ASSERT_NULL(style);
lv_img_dsc_t * dsc = lv_canvas_get_img(canvas);
/* Create a dummy display to fool the lv_draw function.
@ -568,6 +599,9 @@ void lv_canvas_draw_text(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y, lv_coord
*/
void lv_canvas_draw_img(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y, const void * src, const lv_style_t * style)
{
LV_ASSERT_OBJ(canvas, LV_OBJX_NAME);
LV_ASSERT_NULL(style);
lv_img_dsc_t * dsc = lv_canvas_get_img(canvas);
/* Create a dummy display to fool the lv_draw function.
@ -621,6 +655,9 @@ void lv_canvas_draw_img(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y, const voi
*/
void lv_canvas_draw_line(lv_obj_t * canvas, const lv_point_t * points, uint32_t point_cnt, const lv_style_t * style)
{
LV_ASSERT_OBJ(canvas, LV_OBJX_NAME);
LV_ASSERT_NULL(style);
lv_img_dsc_t * dsc = lv_canvas_get_img(canvas);
/* Create a dummy display to fool the lv_draw function.
@ -675,6 +712,9 @@ void lv_canvas_draw_line(lv_obj_t * canvas, const lv_point_t * points, uint32_t
*/
void lv_canvas_draw_polygon(lv_obj_t * canvas, const lv_point_t * points, uint32_t point_cnt, const lv_style_t * style)
{
LV_ASSERT_OBJ(canvas, LV_OBJX_NAME);
LV_ASSERT_NULL(style);
lv_img_dsc_t * dsc = lv_canvas_get_img(canvas);
/* Create a dummy display to fool the lv_draw function.
@ -730,6 +770,9 @@ void lv_canvas_draw_polygon(lv_obj_t * canvas, const lv_point_t * points, uint32
void lv_canvas_draw_arc(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y, lv_coord_t r, int32_t start_angle,
int32_t end_angle, const lv_style_t * style)
{
LV_ASSERT_OBJ(canvas, LV_OBJX_NAME);
LV_ASSERT_NULL(style);
lv_img_dsc_t * dsc = lv_canvas_get_img(canvas);
/* Create a dummy display to fool the lv_draw function.
@ -790,16 +833,10 @@ static lv_res_t lv_canvas_signal(lv_obj_t * canvas, lv_signal_t sign, void * par
/* Include the ancient signal function */
res = ancestor_signal(canvas, sign, param);
if(res != LV_RES_OK) return res;
if(sign == LV_SIGNAL_GET_TYPE) return lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
if(sign == LV_SIGNAL_CLEANUP) {
/*Nothing to cleanup. (No dynamically allocated memory in 'ext')*/
} else if(sign == LV_SIGNAL_GET_TYPE) {
lv_obj_type_t * buf = param;
uint8_t i;
for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/
if(buf->type[i] == NULL) break;
}
buf->type[i] = "lv_canvas";
}
return res;

View File

@ -23,6 +23,7 @@ extern "C" {
#include "../lv_core/lv_obj.h"
#include "../lv_objx/lv_img.h"
#include "../lv_draw/lv_draw_img.h"
/*********************
* DEFINES
@ -239,21 +240,21 @@ void lv_canvas_draw_arc(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y, lv_coord_
/**********************
* MACROS
**********************/
#define LV_CANVAS_BUF_SIZE_TRUE_COLOR(w, h) ((LV_COLOR_SIZE / 8) * w * h)
#define LV_CANVAS_BUF_SIZE_TRUE_COLOR_CHROMA_KEYED(w, h) ((LV_COLOR_SIZE / 8) * w * h)
#define LV_CANVAS_BUF_SIZE_TRUE_COLOR_ALPHA(w, h) (LV_IMG_PX_SIZE_ALPHA_BYTE * w * h)
#define LV_CANVAS_BUF_SIZE_TRUE_COLOR(w, h) LV_IMG_BUF_SIZE_TRUE_COLOR(w, h)
#define LV_CANVAS_BUF_SIZE_TRUE_COLOR_CHROMA_KEYED(w, h) LV_IMG_BUF_SIZE_TRUE_COLOR_CHROMA_KEYED(w, h)
#define LV_CANVAS_BUF_SIZE_TRUE_COLOR_ALPHA(w, h) LV_IMG_BUF_SIZE_TRUE_COLOR_ALPHA(w, h)
/*+ 1: to be sure no fractional row*/
#define LV_CANVAS_BUF_SIZE_ALPHA_1BIT(w, h) ((((w / 8) + 1) * h))
#define LV_CANVAS_BUF_SIZE_ALPHA_2BIT(w, h) ((((w / 4) + 1) * h))
#define LV_CANVAS_BUF_SIZE_ALPHA_4BIT(w, h) ((((w / 2) + 1) * h))
#define LV_CANVAS_BUF_SIZE_ALPHA_8BIT(w, h) ((w * h))
#define LV_CANVAS_BUF_SIZE_ALPHA_1BIT(w, h) LV_IMG_BUF_SIZE_ALPHA_1BIT(w, h)
#define LV_CANVAS_BUF_SIZE_ALPHA_2BIT(w, h) LV_IMG_BUF_SIZE_ALPHA_2BIT(w, h)
#define LV_CANVAS_BUF_SIZE_ALPHA_4BIT(w, h) LV_IMG_BUF_SIZE_ALPHA_4BIT(w, h)
#define LV_CANVAS_BUF_SIZE_ALPHA_8BIT(w, h) LV_IMG_BUF_SIZE_ALPHA_8BIT(w, h)
/*4 * X: for palette*/
#define LV_CANVAS_BUF_SIZE_INDEXED_1BIT(w, h) (LV_CANVAS_BUF_SIZE_ALPHA_1BIT(w, h) + 4 * 2)
#define LV_CANVAS_BUF_SIZE_INDEXED_2BIT(w, h) (LV_CANVAS_BUF_SIZE_ALPHA_2BIT(w, h) + 4 * 4)
#define LV_CANVAS_BUF_SIZE_INDEXED_4BIT(w, h) (LV_CANVAS_BUF_SIZE_ALPHA_4BIT(w, h) + 4 * 16)
#define LV_CANVAS_BUF_SIZE_INDEXED_8BIT(w, h) (LV_CANVAS_BUF_SIZE_ALPHA_8BIT(w, h) + 4 * 256)
#define LV_CANVAS_BUF_SIZE_INDEXED_1BIT(w, h) LV_IMG_BUF_SIZE_INDEXED_1BIT(w, h)
#define LV_CANVAS_BUF_SIZE_INDEXED_2BIT(w, h) LV_IMG_BUF_SIZE_INDEXED_2BIT(w, h)
#define LV_CANVAS_BUF_SIZE_INDEXED_4BIT(w, h) LV_IMG_BUF_SIZE_INDEXED_4BIT(w, h)
#define LV_CANVAS_BUF_SIZE_INDEXED_8BIT(w, h) LV_IMG_BUF_SIZE_INDEXED_8BIT(w, h)
#endif /*LV_USE_CANVAS*/

View File

@ -9,12 +9,14 @@
#include "lv_cb.h"
#if LV_USE_CB != 0
#include "../lv_core/lv_debug.h"
#include "../lv_core/lv_group.h"
#include "../lv_themes/lv_theme.h"
/*********************
* DEFINES
*********************/
#define LV_OBJX_NAME "lv_cb"
/**********************
* TYPEDEFS
@ -55,14 +57,14 @@ lv_obj_t * lv_cb_create(lv_obj_t * par, const lv_obj_t * copy)
/*Create the ancestor basic object*/
lv_obj_t * new_cb = lv_btn_create(par, copy);
lv_mem_assert(new_cb);
LV_ASSERT_MEM(new_cb);
if(new_cb == NULL) return NULL;
if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(new_cb);
if(ancestor_bg_design == NULL) ancestor_bg_design = lv_obj_get_design_cb(new_cb);
lv_cb_ext_t * ext = lv_obj_allocate_ext_attr(new_cb, sizeof(lv_cb_ext_t));
lv_mem_assert(ext);
LV_ASSERT_MEM(ext);
if(ext == NULL) return NULL;
ext->bullet = NULL;
@ -126,6 +128,8 @@ lv_obj_t * lv_cb_create(lv_obj_t * par, const lv_obj_t * copy)
*/
void lv_cb_set_text(lv_obj_t * cb, const char * txt)
{
LV_ASSERT_OBJ(cb, LV_OBJX_NAME);
lv_cb_ext_t * ext = lv_obj_get_ext_attr(cb);
lv_label_set_text(ext->label, txt);
}
@ -138,6 +142,8 @@ void lv_cb_set_text(lv_obj_t * cb, const char * txt)
*/
void lv_cb_set_static_text(lv_obj_t * cb, const char * txt)
{
LV_ASSERT_OBJ(cb, LV_OBJX_NAME);
lv_cb_ext_t * ext = lv_obj_get_ext_attr(cb);
lv_label_set_static_text(ext->label, txt);
}
@ -150,6 +156,8 @@ void lv_cb_set_static_text(lv_obj_t * cb, const char * txt)
* */
void lv_cb_set_style(lv_obj_t * cb, lv_cb_style_t type, const lv_style_t * style)
{
LV_ASSERT_OBJ(cb, LV_OBJX_NAME);
lv_cb_ext_t * ext = lv_obj_get_ext_attr(cb);
switch(type) {
@ -179,6 +187,8 @@ void lv_cb_set_style(lv_obj_t * cb, lv_cb_style_t type, const lv_style_t * style
*/
const char * lv_cb_get_text(const lv_obj_t * cb)
{
LV_ASSERT_OBJ(cb, LV_OBJX_NAME);
lv_cb_ext_t * ext = lv_obj_get_ext_attr(cb);
return lv_label_get_text(ext->label);
}
@ -191,6 +201,8 @@ const char * lv_cb_get_text(const lv_obj_t * cb)
* */
const lv_style_t * lv_cb_get_style(const lv_obj_t * cb, lv_cb_style_t type)
{
LV_ASSERT_OBJ(cb, LV_OBJX_NAME);
const lv_style_t * style = NULL;
lv_cb_ext_t * ext = lv_obj_get_ext_attr(cb);
@ -300,6 +312,7 @@ static lv_res_t lv_cb_signal(lv_obj_t * cb, lv_signal_t sign, void * param)
/* Include the ancient signal function */
res = ancestor_signal(cb, sign, param);
if(res != LV_RES_OK) return res;
if(sign == LV_SIGNAL_GET_TYPE) return lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
lv_cb_ext_t * ext = lv_obj_get_ext_attr(cb);
@ -316,13 +329,6 @@ static lv_res_t lv_cb_signal(lv_obj_t * cb, lv_signal_t sign, void * param)
/*Follow the backgrounds state with the bullet*/
lv_btn_set_state(ext->bullet, lv_btn_get_state(cb));
}
} else if(sign == LV_SIGNAL_GET_TYPE) {
lv_obj_type_t * buf = param;
uint8_t i;
for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/
if(buf->type[i] == NULL) break;
}
buf->type[i] = "lv_cb";
}
return res;

View File

@ -9,6 +9,7 @@
#include "lv_chart.h"
#if LV_USE_CHART != 0
#include "../lv_core/lv_debug.h"
#include "../lv_core/lv_refr.h"
#include "../lv_draw/lv_draw.h"
#include "../lv_themes/lv_theme.h"
@ -16,6 +17,8 @@
/*********************
* DEFINES
*********************/
#define LV_OBJX_NAME "lv_chart"
#define LV_CHART_YMIN_DEF 0
#define LV_CHART_YMAX_DEF 100
#define LV_CHART_HDIV_DEF 3
@ -24,11 +27,22 @@
#define LV_CHART_AXIS_TO_LABEL_DISTANCE 4
#define LV_CHART_AXIS_MAJOR_TICK_LEN_COE 1 / 15
#define LV_CHART_AXIS_MINOR_TICK_LEN_COE 2 / 3
#define LV_CHART_AXIS_PRIMARY_Y 1
#define LV_CHART_AXIS_SECONDARY_Y 0
#define LV_CHART_LABEL_ITERATOR_FORWARD 1
#define LV_CHART_LABEL_ITERATOR_REVERSE 0
/**********************
* TYPEDEFS
**********************/
typedef struct {
const char * list_start;
const char * current_pos;
uint8_t items_left;
uint8_t is_reverse_iter;
} lv_chart_label_iterator_t;
/**********************
* STATIC PROTOTYPES
**********************/
@ -44,6 +58,9 @@ static void lv_chart_draw_axes(lv_obj_t * chart, const lv_area_t * mask);
static void lv_chart_inv_lines(lv_obj_t * chart, uint16_t i);
static void lv_chart_inv_points(lv_obj_t * chart, uint16_t i);
static void lv_chart_inv_cols(lv_obj_t * chart, uint16_t i);
static void lv_chart_get_next_label(lv_chart_label_iterator_t * iterator, char * buf);
static inline bool lv_chart_is_tick_with_label(uint8_t tick_num, lv_chart_axis_cfg_t * axis);
static lv_chart_label_iterator_t lv_chart_create_label_iter(const char * list, uint8_t iterator_dir);
/**********************
* STATIC VARIABLES
@ -72,12 +89,12 @@ lv_obj_t * lv_chart_create(lv_obj_t * par, const lv_obj_t * copy)
/*Create the ancestor basic object*/
lv_obj_t * new_chart = lv_obj_create(par, copy);
lv_mem_assert(new_chart);
LV_ASSERT_MEM(new_chart);
if(new_chart == NULL) return NULL;
/*Allocate the object type specific extended data*/
lv_chart_ext_t * ext = lv_obj_allocate_ext_attr(new_chart, sizeof(lv_chart_ext_t));
lv_mem_assert(ext);
LV_ASSERT_MEM(ext);
if(ext == NULL) return NULL;
lv_ll_init(&ext->series_ll, sizeof(lv_chart_series_t));
@ -96,10 +113,13 @@ lv_obj_t * lv_chart_create(lv_obj_t * par, const lv_obj_t * copy)
ext->margin = 0;
memset(&ext->x_axis, 0, sizeof(ext->x_axis));
memset(&ext->y_axis, 0, sizeof(ext->y_axis));
memset(&ext->secondary_y_axis, 0, sizeof(ext->secondary_y_axis));
ext->x_axis.major_tick_len = LV_CHART_TICK_LENGTH_AUTO;
ext->x_axis.minor_tick_len = LV_CHART_TICK_LENGTH_AUTO;
ext->y_axis.major_tick_len = LV_CHART_TICK_LENGTH_AUTO;
ext->y_axis.minor_tick_len = LV_CHART_TICK_LENGTH_AUTO;
ext->secondary_y_axis.major_tick_len = LV_CHART_TICK_LENGTH_AUTO;
ext->secondary_y_axis.minor_tick_len = LV_CHART_TICK_LENGTH_AUTO;
if(ancestor_design_f == NULL) ancestor_design_f = lv_obj_get_design_cb(new_chart);
if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(new_chart);
@ -132,6 +152,7 @@ lv_obj_t * lv_chart_create(lv_obj_t * par, const lv_obj_t * copy)
ext->margin = ext_copy->margin;
memcpy(&ext->x_axis, &ext_copy->x_axis, sizeof(lv_chart_axis_cfg_t));
memcpy(&ext->y_axis, &ext_copy->y_axis, sizeof(lv_chart_axis_cfg_t));
memcpy(&ext->secondary_y_axis, &ext_copy->secondary_y_axis, sizeof(lv_chart_axis_cfg_t));
/*Refresh the style with new signal function*/
lv_obj_refresh_style(new_chart);
@ -154,9 +175,11 @@ 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)
{
LV_ASSERT_OBJ(chart, LV_OBJX_NAME);
lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart);
lv_chart_series_t * ser = lv_ll_ins_head(&ext->series_ll);
lv_mem_assert(ser);
LV_ASSERT_MEM(ser);
if(ser == NULL) return NULL;
lv_coord_t def = LV_CHART_POINT_DEF;
@ -165,7 +188,7 @@ lv_chart_series_t * lv_chart_add_series(lv_obj_t * chart, lv_color_t color)
ser->color = color;
ser->points = lv_mem_alloc(sizeof(lv_coord_t) * ext->point_cnt);
lv_mem_assert(ser->points);
LV_ASSERT_MEM(ser->points);
if(ser->points == NULL) {
lv_ll_rem(&ext->series_ll, ser);
lv_mem_free(ser);
@ -193,6 +216,9 @@ lv_chart_series_t * lv_chart_add_series(lv_obj_t * chart, lv_color_t color)
*/
void lv_chart_clear_serie(lv_obj_t * chart, lv_chart_series_t * serie)
{
LV_ASSERT_OBJ(chart, LV_OBJX_NAME);
LV_ASSERT_NULL(serie);
if(chart == NULL || serie == NULL) return;
lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart);
if(ext == NULL) return;
@ -217,6 +243,8 @@ void lv_chart_clear_serie(lv_obj_t * chart, lv_chart_series_t * serie)
*/
void lv_chart_set_div_line_count(lv_obj_t * chart, uint8_t hdiv, uint8_t vdiv)
{
LV_ASSERT_OBJ(chart, LV_OBJX_NAME);
lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart);
if(ext->hdiv_cnt == hdiv && ext->vdiv_cnt == vdiv) return;
@ -234,6 +262,8 @@ void lv_chart_set_div_line_count(lv_obj_t * chart, uint8_t hdiv, uint8_t vdiv)
*/
void lv_chart_set_range(lv_obj_t * chart, lv_coord_t ymin, lv_coord_t ymax)
{
LV_ASSERT_OBJ(chart, LV_OBJX_NAME);
lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart);
if(ext->ymin == ymin && ext->ymax == ymax) return;
@ -250,6 +280,8 @@ void lv_chart_set_range(lv_obj_t * chart, lv_coord_t ymin, lv_coord_t ymax)
*/
void lv_chart_set_type(lv_obj_t * chart, lv_chart_type_t type)
{
LV_ASSERT_OBJ(chart, LV_OBJX_NAME);
lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart);
if(ext->type == type) return;
@ -265,6 +297,8 @@ void lv_chart_set_type(lv_obj_t * chart, lv_chart_type_t type)
*/
void lv_chart_set_point_count(lv_obj_t * chart, uint16_t point_cnt)
{
LV_ASSERT_OBJ(chart, LV_OBJX_NAME);
lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart);
if(ext->point_cnt == point_cnt) return;
@ -279,7 +313,7 @@ void lv_chart_set_point_count(lv_obj_t * chart, uint16_t point_cnt)
{
if(ser->start_point != 0) {
lv_coord_t * new_points = lv_mem_alloc(sizeof(lv_coord_t) * point_cnt);
lv_mem_assert(new_points);
LV_ASSERT_MEM(new_points);
if(new_points == NULL) return;
if(point_cnt >= point_cnt_old) {
@ -302,7 +336,7 @@ void lv_chart_set_point_count(lv_obj_t * chart, uint16_t point_cnt)
ser->points = new_points;
} else {
ser->points = lv_mem_realloc(ser->points, sizeof(lv_coord_t) * point_cnt);
lv_mem_assert(ser->points);
LV_ASSERT_MEM(ser->points);
if(ser->points == NULL) return;
/*Initialize the new points*/
if(point_cnt > point_cnt_old) {
@ -327,6 +361,8 @@ void lv_chart_set_point_count(lv_obj_t * chart, uint16_t point_cnt)
*/
void lv_chart_set_series_opa(lv_obj_t * chart, lv_opa_t opa)
{
LV_ASSERT_OBJ(chart, LV_OBJX_NAME);
lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart);
if(ext->series.opa == opa) return;
@ -341,6 +377,8 @@ void lv_chart_set_series_opa(lv_obj_t * chart, lv_opa_t opa)
*/
void lv_chart_set_series_width(lv_obj_t * chart, lv_coord_t width)
{
LV_ASSERT_OBJ(chart, LV_OBJX_NAME);
lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart);
if(ext->series.width == width) return;
@ -354,6 +392,8 @@ void lv_chart_set_series_width(lv_obj_t * chart, lv_coord_t width)
*/
void lv_chart_set_series_darking(lv_obj_t * chart, lv_opa_t dark_eff)
{
LV_ASSERT_OBJ(chart, LV_OBJX_NAME);
lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart);
if(ext->series.dark == dark_eff) return;
@ -369,6 +409,9 @@ void lv_chart_set_series_darking(lv_obj_t * chart, lv_opa_t dark_eff)
*/
void lv_chart_init_points(lv_obj_t * chart, lv_chart_series_t * ser, lv_coord_t y)
{
LV_ASSERT_OBJ(chart, LV_OBJX_NAME);
LV_ASSERT_NULL(ser);
lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart);
uint16_t i;
for(i = 0; i < ext->point_cnt; i++) {
@ -386,6 +429,9 @@ void lv_chart_init_points(lv_obj_t * chart, lv_chart_series_t * ser, lv_coord_t
*/
void lv_chart_set_points(lv_obj_t * chart, lv_chart_series_t * ser, lv_coord_t y_array[])
{
LV_ASSERT_OBJ(chart, LV_OBJX_NAME);
LV_ASSERT_NULL(ser);
lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart);
memcpy(ser->points, y_array, ext->point_cnt * (sizeof(lv_coord_t)));
ser->start_point = 0;
@ -400,6 +446,9 @@ void lv_chart_set_points(lv_obj_t * chart, lv_chart_series_t * ser, lv_coord_t y
*/
void lv_chart_set_next(lv_obj_t * chart, lv_chart_series_t * ser, lv_coord_t y)
{
LV_ASSERT_OBJ(chart, LV_OBJX_NAME);
LV_ASSERT_NULL(ser);
lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart);
if(ext->update_mode == LV_CHART_UPDATE_MODE_SHIFT) {
ser->points[ser->start_point] =
@ -426,6 +475,8 @@ void lv_chart_set_next(lv_obj_t * chart, lv_chart_series_t * ser, lv_coord_t y)
*/
void lv_chart_set_update_mode(lv_obj_t * chart, lv_chart_update_mode_t update_mode)
{
LV_ASSERT_OBJ(chart, LV_OBJX_NAME);
lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart);
if(ext->update_mode == update_mode) return;
@ -443,6 +494,8 @@ void lv_chart_set_update_mode(lv_obj_t * chart, lv_chart_update_mode_t update_mo
*/
void lv_chart_set_x_tick_length(lv_obj_t * chart, uint8_t major_tick_len, uint8_t minor_tick_len)
{
LV_ASSERT_OBJ(chart, LV_OBJX_NAME);
lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart);
ext->x_axis.major_tick_len = major_tick_len;
ext->x_axis.minor_tick_len = minor_tick_len;
@ -458,11 +511,30 @@ void lv_chart_set_x_tick_length(lv_obj_t * chart, uint8_t major_tick_len, uint8_
*/
void lv_chart_set_y_tick_length(lv_obj_t * chart, uint8_t major_tick_len, uint8_t minor_tick_len)
{
LV_ASSERT_OBJ(chart, LV_OBJX_NAME);
lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart);
ext->y_axis.major_tick_len = major_tick_len;
ext->y_axis.minor_tick_len = minor_tick_len;
}
/**
* Set the length of the tick marks on the secondary y axis
* @param chart pointer to the chart
* @param major_tick_len the length of the major tick or `LV_CHART_TICK_LENGTH_AUTO` to set automatically
* (where labels are added)
* @param minor_tick_len the length of the minor tick, `LV_CHART_TICK_LENGTH_AUTO` to set automatically
* (where no labels are added)
*/
void lv_chart_set_secondary_y_tick_length(lv_obj_t * chart, uint8_t major_tick_len, uint8_t minor_tick_len)
{
LV_ASSERT_OBJ(chart, LV_OBJX_NAME);
lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart);
ext->secondary_y_axis.major_tick_len = major_tick_len;
ext->secondary_y_axis.minor_tick_len = minor_tick_len;
}
/**
* Set the x-axis tick count and labels of a chart
* @param chart pointer to a chart object
@ -474,6 +546,9 @@ void lv_chart_set_y_tick_length(lv_obj_t * chart, uint8_t major_tick_len, uint8_
void lv_chart_set_x_tick_texts(lv_obj_t * chart, const char * list_of_values, uint8_t num_tick_marks,
lv_chart_axis_options_t options)
{
LV_ASSERT_OBJ(chart, LV_OBJX_NAME);
LV_ASSERT_NULL(list_of_values);
lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart);
ext->x_axis.num_tick_marks = num_tick_marks;
ext->x_axis.list_of_values = list_of_values;
@ -491,12 +566,35 @@ void lv_chart_set_x_tick_texts(lv_obj_t * chart, const char * list_of_values, ui
void lv_chart_set_y_tick_texts(lv_obj_t * chart, const char * list_of_values, uint8_t num_tick_marks,
lv_chart_axis_options_t options)
{
LV_ASSERT_OBJ(chart, LV_OBJX_NAME);
LV_ASSERT_NULL(list_of_values);
lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart);
ext->y_axis.num_tick_marks = num_tick_marks;
ext->y_axis.list_of_values = list_of_values;
ext->y_axis.options = options;
}
/**
* Set the secondary y-axis tick count and labels of a chart
* @param chart pointer to a chart object
* @param list_of_values list of string values, terminated with \n, except the last
* @param num_tick_marks if list_of_values is NULL: total number of ticks per axis
* else number of ticks between two value labels
* @param options extra options
*/
void lv_chart_set_secondary_y_tick_texts(lv_obj_t * chart, const char * list_of_values, uint8_t num_tick_marks,
lv_chart_axis_options_t options)
{
LV_ASSERT_OBJ(chart, LV_OBJX_NAME);
LV_ASSERT_NULL(list_of_values);
lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart);
ext->secondary_y_axis.num_tick_marks = num_tick_marks;
ext->secondary_y_axis.list_of_values = list_of_values;
ext->secondary_y_axis.options = options;
}
/**
* Set the margin around the chart, used for axes value and ticks
* @param chart pointer to an chart object
@ -504,6 +602,8 @@ void lv_chart_set_y_tick_texts(lv_obj_t * chart, const char * list_of_values, ui
*/
void lv_chart_set_margin(lv_obj_t * chart, uint16_t margin)
{
LV_ASSERT_OBJ(chart, LV_OBJX_NAME);
lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart);
ext->margin = margin;
lv_obj_refresh_ext_draw_pad(chart);
@ -520,6 +620,8 @@ void lv_chart_set_margin(lv_obj_t * chart, uint16_t margin)
*/
lv_chart_type_t lv_chart_get_type(const lv_obj_t * chart)
{
LV_ASSERT_OBJ(chart, LV_OBJX_NAME);
lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart);
return ext->type;
}
@ -531,6 +633,8 @@ lv_chart_type_t lv_chart_get_type(const lv_obj_t * chart)
*/
uint16_t lv_chart_get_point_cnt(const lv_obj_t * chart)
{
LV_ASSERT_OBJ(chart, LV_OBJX_NAME);
lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart);
return ext->point_cnt;
}
@ -542,6 +646,8 @@ uint16_t lv_chart_get_point_cnt(const lv_obj_t * chart)
*/
lv_opa_t lv_chart_get_series_opa(const lv_obj_t * chart)
{
LV_ASSERT_OBJ(chart, LV_OBJX_NAME);
lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart);
return ext->series.opa;
}
@ -553,6 +659,8 @@ lv_opa_t lv_chart_get_series_opa(const lv_obj_t * chart)
*/
lv_coord_t lv_chart_get_series_width(const lv_obj_t * chart)
{
LV_ASSERT_OBJ(chart, LV_OBJX_NAME);
lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart);
return ext->series.width;
}
@ -564,6 +672,8 @@ lv_coord_t lv_chart_get_series_width(const lv_obj_t * chart)
*/
lv_opa_t lv_chart_get_series_darking(const lv_obj_t * chart)
{
LV_ASSERT_OBJ(chart, LV_OBJX_NAME);
lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart);
return ext->series.dark;
}
@ -578,6 +688,8 @@ lv_opa_t lv_chart_get_series_darking(const lv_obj_t * chart)
*/
void lv_chart_refresh(lv_obj_t * chart)
{
LV_ASSERT_OBJ(chart, LV_OBJX_NAME);
lv_obj_invalidate(chart);
}
@ -588,6 +700,8 @@ void lv_chart_refresh(lv_obj_t * chart)
*/
uint16_t lv_chart_get_margin(lv_obj_t * chart)
{
LV_ASSERT_OBJ(chart, LV_OBJX_NAME);
lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart);
return ext->margin;
}
@ -647,12 +761,13 @@ static bool lv_chart_design(lv_obj_t * chart, const lv_area_t * mask, lv_design_
*/
static lv_res_t lv_chart_signal(lv_obj_t * chart, lv_signal_t sign, void * param)
{
lv_res_t res;
lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart);
/* Include the ancient signal function */
lv_res_t res;
res = ancestor_signal(chart, sign, param);
if(res != LV_RES_OK) return res;
if(sign == LV_SIGNAL_GET_TYPE) return lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart);
if(sign == LV_SIGNAL_CLEANUP) {
lv_coord_t ** datal;
@ -661,13 +776,6 @@ static lv_res_t lv_chart_signal(lv_obj_t * chart, lv_signal_t sign, void * param
lv_mem_free(*datal);
}
lv_ll_clear(&ext->series_ll);
} else if(sign == LV_SIGNAL_GET_TYPE) {
lv_obj_type_t * buf = param;
uint8_t i;
for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/
if(buf->type[i] == NULL) break;
}
buf->type[i] = "lv_chart";
} else if(sign == LV_SIGNAL_REFR_EXT_DRAW_PAD) {
/*Provide extra px draw area around the chart*/
chart->ext_draw_pad = ext->margin;
@ -1046,65 +1154,187 @@ static void lv_chart_draw_areas(lv_obj_t * chart, const lv_area_t * mask)
}
}
static void lv_chart_draw_y_ticks(lv_obj_t * chart, const lv_area_t * mask)
/**
* Create iterator for newline-separated list
* @param list pointer to newline-separated labels list
* @param iterator_dir LV_CHART_ITERATOR_FORWARD or LV_CHART_LABEL_ITERATOR_REVERSE
* @return lv_chart_label_iterator_t
*/
static lv_chart_label_iterator_t lv_chart_create_label_iter(const char * list, uint8_t iterator_dir)
{
lv_chart_label_iterator_t iterator = {0};
uint8_t j;
iterator.list_start = list;
/* count number of list items */
for(j = 0; list[j] != '\0'; j++) {
if(list[j] == '\n')
iterator.items_left++;
}
if(iterator_dir == LV_CHART_LABEL_ITERATOR_FORWARD) {
iterator.is_reverse_iter = 0;
iterator.current_pos = list;
} else {
iterator.is_reverse_iter = 1;
// -1 to skip '\0' at the end of the string
iterator.current_pos = list + j - 1;
}
iterator.items_left++;
return iterator;
}
/**
* Get next label from iterator created by lv_chart_create_label_iter()
* @param iterator iterator to get label from
* @param[out] buf buffer to point next label to
*/
static void lv_chart_get_next_label(lv_chart_label_iterator_t * iterator, char * buf)
{
uint8_t label_len = 0;
if (iterator->is_reverse_iter) {
const char * label_start;
/* count the length of the current label*/
while ((*iterator->current_pos != '\n') &&
(iterator->current_pos != iterator->list_start)) {
iterator->current_pos--;
label_len++;
}
label_start = iterator->current_pos;
if (*iterator->current_pos == '\n') {
/* do not copy \n symbol, +1 to skip it*/
label_start++;
/* skip newline*/
iterator->current_pos--;
} else {
/* it is last label in list (first one from the beginning )*/
label_len++;
}
/* do not allow output buffer overflow */
if (label_len > LV_CHART_AXIS_TICK_LABEL_MAX_LEN) {
label_len = LV_CHART_AXIS_TICK_LABEL_MAX_LEN;
}
strncpy(buf, label_start, label_len);
} else {
/* search for tick string */
while(iterator->current_pos[label_len] != '\n' &&
iterator->current_pos[label_len] != '\0') {
/* do not overflow the buffer, but move to the end of the current label */
if(label_len < LV_CHART_AXIS_TICK_LABEL_MAX_LEN) {
buf[label_len] = iterator->current_pos[label_len];
label_len++;
} else {
label_len++;
}
}
iterator->current_pos += label_len;
/* do not allow output buffer overflow */
if (label_len > LV_CHART_AXIS_TICK_LABEL_MAX_LEN) {
label_len = LV_CHART_AXIS_TICK_LABEL_MAX_LEN;
}
if(*iterator->current_pos == '\n') iterator->current_pos++;
}
/* terminate the string */
buf[label_len] = '\0';
}
/**
* Check whether there should be a label next to tick with given
* number
* @param tick_num number of the tick to check
* @param axis pointer to struct containing info on the axis
* @return true if label should be located next to current tick
*/
static inline bool lv_chart_is_tick_with_label(uint8_t tick_num, lv_chart_axis_cfg_t * axis)
{
return ((tick_num == 0) || ((tick_num % axis->num_tick_marks) == 0));
}
static void lv_chart_draw_y_ticks(lv_obj_t * chart, const lv_area_t * mask, uint8_t which_axis)
{
lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart);
lv_chart_axis_cfg_t * y_axis = (which_axis == LV_CHART_AXIS_PRIMARY_Y) ?
&ext->y_axis : &ext->secondary_y_axis;
if(ext->y_axis.list_of_values != NULL || ext->y_axis.num_tick_marks != 0) {
if(y_axis->list_of_values != NULL || y_axis->num_tick_marks != 0) {
const lv_style_t * style = lv_obj_get_style(chart);
lv_opa_t opa_scale = lv_obj_get_opa_scale(chart);
uint8_t i, j;
uint8_t list_index;
uint8_t i;
uint8_t num_of_labels;
uint8_t num_scale_ticks;
uint8_t major_tick_len, minor_tick_len;
int8_t major_tick_len, minor_tick_len;
uint8_t iter_dir;
lv_point_t p1;
lv_point_t p2;
lv_coord_t x_ofs = chart->coords.x1;
lv_coord_t x_ofs;
lv_chart_label_iterator_t iter;
lv_coord_t y_ofs = chart->coords.y1;
lv_coord_t h = lv_obj_get_height(chart);
lv_coord_t w = lv_obj_get_width(chart);
char buf[LV_CHART_AXIS_TICK_LABEL_MAX_LEN + 1]; /* up to N symbols per label + null terminator */
/* chose correct side of the chart */
if(which_axis == LV_CHART_AXIS_PRIMARY_Y)
x_ofs = chart->coords.x1;
else
x_ofs = chart->coords.x2;
/* calculate the size of tick marks */
if(ext->y_axis.major_tick_len == LV_CHART_TICK_LENGTH_AUTO)
if(y_axis->major_tick_len == LV_CHART_TICK_LENGTH_AUTO)
major_tick_len = (int32_t)w * LV_CHART_AXIS_MAJOR_TICK_LEN_COE;
else
major_tick_len = ext->y_axis.major_tick_len;
major_tick_len = y_axis->major_tick_len;
if(ext->y_axis.minor_tick_len == LV_CHART_TICK_LENGTH_AUTO)
if(y_axis->minor_tick_len == LV_CHART_TICK_LENGTH_AUTO)
minor_tick_len = major_tick_len * LV_CHART_AXIS_MINOR_TICK_LEN_COE;
else
minor_tick_len = ext->y_axis.minor_tick_len;
minor_tick_len = y_axis->minor_tick_len;
/* count the '\n'-s to determine the number of options */
list_index = 0;
num_of_labels = 0;
if(ext->y_axis.list_of_values != NULL) {
for(j = 0; ext->y_axis.list_of_values[j] != '\0'; j++) {
if(ext->y_axis.list_of_values[j] == '\n') num_of_labels++;
}
num_of_labels++; /* last option in the at row*/
/* tick lines on secondary y axis are drawn in other direction*/
if(which_axis == LV_CHART_AXIS_SECONDARY_Y) {
major_tick_len *= -1;
minor_tick_len *= -1;
}
iter_dir = (y_axis->options & LV_CHART_AXIS_INVERSE_LABELS_ORDER) ? LV_CHART_LABEL_ITERATOR_REVERSE : LV_CHART_LABEL_ITERATOR_FORWARD;
iter = lv_chart_create_label_iter(y_axis->list_of_values, iter_dir);
/*determine the number of options */
num_of_labels = iter.items_left;
/* we can't have string labels without ticks step, set to 1 if not specified */
if(ext->y_axis.num_tick_marks == 0) ext->y_axis.num_tick_marks = 1;
if(y_axis->num_tick_marks == 0) y_axis->num_tick_marks = 1;
/* calculate total number of ticks */
if(num_of_labels < 2)
num_scale_ticks = ext->y_axis.num_tick_marks;
num_scale_ticks = y_axis->num_tick_marks;
else
num_scale_ticks = (ext->y_axis.num_tick_marks * (num_of_labels - 1));
num_scale_ticks = (y_axis->num_tick_marks * (num_of_labels - 1));
for(i = 0; i < (num_scale_ticks + 1); i++) { /* one extra loop - it may not exist in the list, empty label */
/* first point of the tick */
p1.x = x_ofs - 1;
p1.x = x_ofs;
/* move extra pixel out of chart boundary */
if (which_axis == LV_CHART_AXIS_PRIMARY_Y)
p1.x--;
else
p1.x++;
/* second point of the tick */
if((num_of_labels != 0) && (i == 0 || i % ext->y_axis.num_tick_marks == 0))
if((num_of_labels != 0) && (i == 0 || i % y_axis->num_tick_marks == 0))
p2.x = p1.x - major_tick_len; /* major tick */
else
p2.x = p1.x - minor_tick_len; /* minor tick */
@ -1113,31 +1343,25 @@ static void lv_chart_draw_y_ticks(lv_obj_t * chart, const lv_area_t * mask)
p2.y = p1.y =
y_ofs + (int32_t)((int32_t)(h - style->line.width) * i) / num_scale_ticks;
if(i != num_scale_ticks)
lv_draw_line(&p1, &p2, mask, style, opa_scale);
else if((ext->y_axis.options & LV_CHART_AXIS_DRAW_LAST_TICK) != 0)
lv_draw_line(&p1, &p2, mask, style, opa_scale);
if(y_axis->options & LV_CHART_AXIS_INVERSE_LABELS_ORDER) {
/*if label order is inversed last tick have number 0*/
if(i != 0)
lv_draw_line(&p1, &p2, mask, style, opa_scale);
else if((y_axis->options & LV_CHART_AXIS_DRAW_LAST_TICK) != 0)
lv_draw_line(&p1, &p2, mask, style, opa_scale);
} else {
if(i != num_scale_ticks)
lv_draw_line(&p1, &p2, mask, style, opa_scale);
else if((y_axis->options & LV_CHART_AXIS_DRAW_LAST_TICK) != 0)
lv_draw_line(&p1, &p2, mask, style, opa_scale);
}
/* draw values if available */
if(num_of_labels != 0) {
/* add text only to major tick */
if(i == 0 || i % ext->y_axis.num_tick_marks == 0) {
/* search for tick string */
j = 0;
while(ext->y_axis.list_of_values[list_index] != '\n' &&
ext->y_axis.list_of_values[list_index] != '\0') {
/* do not overflow the buffer, but move to the end of the current label */
if(j < LV_CHART_AXIS_TICK_LABEL_MAX_LEN)
buf[j++] = ext->y_axis.list_of_values[list_index++];
else
list_index++;
}
if(lv_chart_is_tick_with_label(i, y_axis)) {
/* this was a string, but not end of the list, so jump to the next string */
if(ext->y_axis.list_of_values[list_index] == '\n') list_index++;
/* terminate the string */
buf[j] = '\0';
lv_chart_get_next_label(&iter, buf);
/* reserve appropriate area */
lv_point_t size;
@ -1145,8 +1369,16 @@ static void lv_chart_draw_y_ticks(lv_obj_t * chart, const lv_area_t * mask)
LV_COORD_MAX, LV_TXT_FLAG_CENTER);
/* set the area at some distance of the major tick len left of the tick */
lv_area_t a = {(p2.x - size.x - LV_CHART_AXIS_TO_LABEL_DISTANCE), (p2.y - size.y / 2),
(p2.x - LV_CHART_AXIS_TO_LABEL_DISTANCE), (p2.y + size.y / 2)};
lv_area_t a = {.y1 = p2.y - size.y / 2, .y2 = p2.y + size.y / 2};
if(which_axis == LV_CHART_AXIS_PRIMARY_Y) {
a.x1 = p2.x - size.x - LV_CHART_AXIS_TO_LABEL_DISTANCE;
a.x2 = p2.x - LV_CHART_AXIS_TO_LABEL_DISTANCE;
} else {
a.x1 = p2.x + LV_CHART_AXIS_TO_LABEL_DISTANCE;
a.x2 = p2.x + size.x + LV_CHART_AXIS_TO_LABEL_DISTANCE;
}
lv_draw_label(&a, mask, style, opa_scale, buf, LV_TXT_FLAG_CENTER, NULL, -1, -1, NULL);
}
}
@ -1164,11 +1396,11 @@ static void lv_chart_draw_x_ticks(lv_obj_t * chart, const lv_area_t * mask)
const lv_style_t * style = lv_obj_get_style(chart);
lv_opa_t opa_scale = lv_obj_get_opa_scale(chart);
uint8_t i, j;
uint8_t list_index;
uint8_t i;
uint8_t num_of_labels;
uint8_t num_scale_ticks;
uint8_t major_tick_len, minor_tick_len;
lv_chart_label_iterator_t iter;
lv_point_t p1;
lv_point_t p2;
lv_coord_t x_ofs = chart->coords.x1;
@ -1188,16 +1420,9 @@ static void lv_chart_draw_x_ticks(lv_obj_t * chart, const lv_area_t * mask)
else
minor_tick_len = ext->x_axis.minor_tick_len;
/* count the '\n'-s to determine the number of options */
list_index = 0;
num_of_labels = 0;
if(ext->x_axis.list_of_values != NULL) {
for(j = 0; ext->x_axis.list_of_values[j] != '\0'; j++) {
if(ext->x_axis.list_of_values[j] == '\n') num_of_labels++;
}
num_of_labels++; /* last option in the at row*/
}
/*determine the number of options */
iter = lv_chart_create_label_iter(ext->x_axis.list_of_values, LV_CHART_LABEL_ITERATOR_FORWARD);
num_of_labels = iter.items_left;
/* we can't have string labels without ticks step, set to 1 if not specified */
if(ext->x_axis.num_tick_marks == 0) ext->x_axis.num_tick_marks = 1;
@ -1229,23 +1454,8 @@ static void lv_chart_draw_x_ticks(lv_obj_t * chart, const lv_area_t * mask)
/* draw values if available */
if(num_of_labels != 0) {
/* add text only to major tick */
if(i == 0 || i % ext->x_axis.num_tick_marks == 0) {
/* search for tick string */
j = 0;
while(ext->x_axis.list_of_values[list_index] != '\n' &&
ext->x_axis.list_of_values[list_index] != '\0') {
/* do not overflow the buffer, but move to the end of the current label */
if(j < LV_CHART_AXIS_TICK_LABEL_MAX_LEN)
buf[j++] = ext->x_axis.list_of_values[list_index++];
else
list_index++;
}
/* this was a string, but not end of the list, so jump to the next string */
if(ext->x_axis.list_of_values[list_index] == '\n') list_index++;
/* terminate the string */
buf[j] = '\0';
if(lv_chart_is_tick_with_label(i, &(ext->x_axis))) {
lv_chart_get_next_label(&iter, buf);
/* reserve appropriate area */
lv_point_t size;
@ -1264,7 +1474,8 @@ static void lv_chart_draw_x_ticks(lv_obj_t * chart, const lv_area_t * mask)
static void lv_chart_draw_axes(lv_obj_t * chart, const lv_area_t * mask)
{
lv_chart_draw_y_ticks(chart, mask);
lv_chart_draw_y_ticks(chart, mask, LV_CHART_AXIS_PRIMARY_Y);
lv_chart_draw_y_ticks(chart, mask, LV_CHART_AXIS_SECONDARY_Y);
lv_chart_draw_x_ticks(chart, mask);
}

View File

@ -34,6 +34,9 @@ extern "C" {
/**Automatically calculate the tick length*/
#define LV_CHART_TICK_LENGTH_AUTO 255
LV_EXPORT_CONST_INT(LV_CHART_POINT_DEF);
LV_EXPORT_CONST_INT(LV_CHART_TICK_LENGTH_AUTO);
/**********************
* TYPEDEFS
**********************/
@ -65,8 +68,9 @@ typedef struct
/** Data of axis */
enum {
LV_CHART_AXIS_SKIP_LAST_TICK = 0x00, /**< don't draw the last tick */
LV_CHART_AXIS_DRAW_LAST_TICK = 0x01 /**< draw the last tick */
LV_CHART_AXIS_SKIP_LAST_TICK = 0x00, /**< don't draw the last tick */
LV_CHART_AXIS_DRAW_LAST_TICK = 0x01, /**< draw the last tick */
LV_CHART_AXIS_INVERSE_LABELS_ORDER = 0x02 /**< draw tick labels in an inversed order*/
};
typedef uint8_t lv_chart_axis_options_t;
@ -93,6 +97,7 @@ typedef struct
lv_chart_type_t type; /*Line, column or point chart (from 'lv_chart_type_t')*/
lv_chart_axis_cfg_t y_axis;
lv_chart_axis_cfg_t x_axis;
lv_chart_axis_cfg_t secondary_y_axis;
uint16_t margin;
uint8_t update_mode : 1;
struct
@ -259,6 +264,16 @@ void lv_chart_set_x_tick_length(lv_obj_t * chart, uint8_t major_tick_len, uint8_
*/
void lv_chart_set_y_tick_length(lv_obj_t * chart, uint8_t major_tick_len, uint8_t minor_tick_len);
/**
* Set the length of the tick marks on the secondary y axis
* @param chart pointer to the chart
* @param major_tick_len the length of the major tick or `LV_CHART_TICK_LENGTH_AUTO` to set automatically
* (where labels are added)
* @param minor_tick_len the length of the minor tick, `LV_CHART_TICK_LENGTH_AUTO` to set automatically
* (where no labels are added)
*/
void lv_chart_set_secondary_y_tick_length(lv_obj_t * chart, uint8_t major_tick_len, uint8_t minor_tick_len);
/**
* Set the x-axis tick count and labels of a chart
* @param chart pointer to a chart object
@ -270,6 +285,17 @@ void lv_chart_set_y_tick_length(lv_obj_t * chart, uint8_t major_tick_len, uint8_
void lv_chart_set_x_tick_texts(lv_obj_t * chart, const char * list_of_values, uint8_t num_tick_marks,
lv_chart_axis_options_t options);
/**
* Set the secondary y-axis tick count and labels of a chart
* @param chart pointer to a chart object
* @param list_of_values list of string values, terminated with \n, except the last
* @param num_tick_marks if list_of_values is NULL: total number of ticks per axis
* else number of ticks between two value labels
* @param options extra options
*/
void lv_chart_set_secondary_y_tick_texts(lv_obj_t * chart, const char * list_of_values, uint8_t num_tick_marks,
lv_chart_axis_options_t options);
/**
* Set the y-axis tick count and labels of a chart
* @param chart pointer to a chart object

View File

@ -14,6 +14,7 @@
#include <stdint.h>
#include <string.h>
#include "../lv_core/lv_debug.h"
#include "../lv_draw/lv_draw.h"
#include "../lv_draw/lv_draw_basic.h"
#include "../lv_themes/lv_theme.h"
@ -24,6 +25,7 @@
/*********************
* DEFINES
*********************/
#define LV_OBJX_NAME "lv_cont"
/**********************
* TYPEDEFS
@ -67,7 +69,7 @@ lv_obj_t * lv_cont_create(lv_obj_t * par, const lv_obj_t * copy)
/*Create a basic object*/
lv_obj_t * new_cont = lv_obj_create(par, copy);
lv_mem_assert(new_cont);
LV_ASSERT_MEM(new_cont);
if(new_cont == NULL) return NULL;
if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(new_cont);
@ -76,7 +78,7 @@ lv_obj_t * lv_cont_create(lv_obj_t * par, const lv_obj_t * copy)
lv_cont_ext_t * ext = lv_obj_get_ext_attr(new_cont);
if(ext == NULL) return NULL;
lv_mem_assert(ext);
LV_ASSERT_MEM(ext);
ext->fit_left = LV_FIT_NONE;
ext->fit_right = LV_FIT_NONE;
ext->fit_top = LV_FIT_NONE;
@ -126,6 +128,8 @@ lv_obj_t * lv_cont_create(lv_obj_t * par, const lv_obj_t * copy)
*/
void lv_cont_set_layout(lv_obj_t * cont, lv_layout_t layout)
{
LV_ASSERT_OBJ(cont, LV_OBJX_NAME);
lv_cont_ext_t * ext = lv_obj_get_ext_attr(cont);
if(ext->layout == layout) return;
@ -146,6 +150,8 @@ void lv_cont_set_layout(lv_obj_t * cont, lv_layout_t layout)
*/
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)
{
LV_ASSERT_OBJ(cont, LV_OBJX_NAME);
lv_obj_invalidate(cont);
lv_cont_ext_t * ext = lv_obj_get_ext_attr(cont);
if(ext->fit_left == left && ext->fit_right == right && ext->fit_top == top && ext->fit_bottom == bottom) {
@ -172,6 +178,8 @@ void lv_cont_set_fit4(lv_obj_t * cont, lv_fit_t left, lv_fit_t right, lv_fit_t t
*/
lv_layout_t lv_cont_get_layout(const lv_obj_t * cont)
{
LV_ASSERT_OBJ(cont, LV_OBJX_NAME);
lv_cont_ext_t * ext = lv_obj_get_ext_attr(cont);
return ext->layout;
}
@ -183,6 +191,8 @@ lv_layout_t lv_cont_get_layout(const lv_obj_t * cont)
*/
lv_fit_t lv_cont_get_fit_left(const lv_obj_t * cont)
{
LV_ASSERT_OBJ(cont, LV_OBJX_NAME);
lv_cont_ext_t * ext = lv_obj_get_ext_attr(cont);
return ext->fit_left;
}
@ -194,6 +204,8 @@ lv_fit_t lv_cont_get_fit_left(const lv_obj_t * cont)
*/
lv_fit_t lv_cont_get_fit_right(const lv_obj_t * cont)
{
LV_ASSERT_OBJ(cont, LV_OBJX_NAME);
lv_cont_ext_t * ext = lv_obj_get_ext_attr(cont);
return ext->fit_right;
}
@ -205,6 +217,8 @@ lv_fit_t lv_cont_get_fit_right(const lv_obj_t * cont)
*/
lv_fit_t lv_cont_get_fit_top(const lv_obj_t * cont)
{
LV_ASSERT_OBJ(cont, LV_OBJX_NAME);
lv_cont_ext_t * ext = lv_obj_get_ext_attr(cont);
return ext->fit_top;
}
@ -216,6 +230,8 @@ lv_fit_t lv_cont_get_fit_top(const lv_obj_t * cont)
*/
lv_fit_t lv_cont_get_fit_bottom(const lv_obj_t * cont)
{
LV_ASSERT_OBJ(cont, LV_OBJX_NAME);
lv_cont_ext_t * ext = lv_obj_get_ext_attr(cont);
return ext->fit_bottom;
}
@ -238,6 +254,7 @@ static lv_res_t lv_cont_signal(lv_obj_t * cont, lv_signal_t sign, void * param)
/* Include the ancient signal function */
res = ancestor_signal(cont, sign, param);
if(res != LV_RES_OK) return res;
if(sign == LV_SIGNAL_GET_TYPE) return lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
if(sign == LV_SIGNAL_STYLE_CHG) { /*Recalculate the padding if the style changed*/
lv_cont_refr_layout(cont);
@ -254,13 +271,6 @@ static lv_res_t lv_cont_signal(lv_obj_t * cont, lv_signal_t sign, void * param)
/*FLOOD and FILL fit needs to be refreshed if the parent size has changed*/
lv_cont_refr_autofit(cont);
} else if(sign == LV_SIGNAL_GET_TYPE) {
lv_obj_type_t * buf = param;
uint8_t i;
for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/
if(buf->type[i] == NULL) break;
}
buf->type[i] = "lv_cont";
}
return res;

View File

@ -9,6 +9,7 @@
#include "lv_ddlist.h"
#if LV_USE_DDLIST != 0
#include "../lv_core/lv_debug.h"
#include "../lv_draw/lv_draw.h"
#include "../lv_core/lv_group.h"
#include "../lv_core/lv_indev.h"
@ -21,6 +22,8 @@
/*********************
* DEFINES
*********************/
#define LV_OBJX_NAME "lv_ddlist"
#if LV_USE_ANIMATION == 0
#undef LV_DDLIST_DEF_ANIM_TIME
#define LV_DDLIST_DEF_ANIM_TIME 0 /*No animation*/
@ -74,7 +77,7 @@ lv_obj_t * lv_ddlist_create(lv_obj_t * par, const lv_obj_t * copy)
/*Create the ancestor drop down list*/
lv_obj_t * new_ddlist = lv_page_create(par, copy);
lv_mem_assert(new_ddlist);
LV_ASSERT_MEM(new_ddlist);
if(new_ddlist == NULL) return NULL;
if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(new_ddlist);
@ -83,7 +86,7 @@ lv_obj_t * lv_ddlist_create(lv_obj_t * par, const lv_obj_t * copy)
/*Allocate the drop down list type specific extended data*/
lv_ddlist_ext_t * ext = lv_obj_allocate_ext_attr(new_ddlist, sizeof(lv_ddlist_ext_t));
lv_mem_assert(ext);
LV_ASSERT_MEM(ext);
if(ext == NULL) return NULL;
/*Initialize the allocated 'ext' */
@ -164,6 +167,9 @@ lv_obj_t * lv_ddlist_create(lv_obj_t * par, const lv_obj_t * copy)
*/
void lv_ddlist_set_options(lv_obj_t * ddlist, const char * options)
{
LV_ASSERT_OBJ(ddlist, LV_OBJX_NAME);
LV_ASSERT_STR(options);
lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist);
/*Count the '\n'-s to determine the number of options*/
@ -197,6 +203,8 @@ void lv_ddlist_set_options(lv_obj_t * ddlist, const char * options)
*/
void lv_ddlist_set_selected(lv_obj_t * ddlist, uint16_t sel_opt)
{
LV_ASSERT_OBJ(ddlist, LV_OBJX_NAME);
lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist);
if(ext->sel_opt_id == sel_opt) return;
@ -218,6 +226,8 @@ void lv_ddlist_set_selected(lv_obj_t * ddlist, uint16_t sel_opt)
*/
void lv_ddlist_set_fix_height(lv_obj_t * ddlist, lv_coord_t h)
{
LV_ASSERT_OBJ(ddlist, LV_OBJX_NAME);
lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist);
if(ext->fix_height == h) return;
@ -233,6 +243,8 @@ void lv_ddlist_set_fix_height(lv_obj_t * ddlist, lv_coord_t h)
*/
void lv_ddlist_set_fix_width(lv_obj_t * ddlist, lv_coord_t w)
{
LV_ASSERT_OBJ(ddlist, LV_OBJX_NAME);
lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist);
if(w == 0) {
lv_cont_set_fit2(ddlist, LV_FIT_TIGHT, lv_cont_get_fit_bottom(ddlist));
@ -257,6 +269,8 @@ void lv_ddlist_set_fix_width(lv_obj_t * ddlist, lv_coord_t w)
*/
void lv_ddlist_set_draw_arrow(lv_obj_t * ddlist, bool en)
{
LV_ASSERT_OBJ(ddlist, LV_OBJX_NAME);
lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist);
/*Set the flag*/
@ -270,6 +284,8 @@ void lv_ddlist_set_draw_arrow(lv_obj_t * ddlist, bool en)
*/
void lv_ddlist_set_stay_open(lv_obj_t * ddlist, bool en)
{
LV_ASSERT_OBJ(ddlist, LV_OBJX_NAME);
lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist);
/*Set the flag*/
@ -284,6 +300,8 @@ void lv_ddlist_set_stay_open(lv_obj_t * ddlist, bool en)
*/
void lv_ddlist_set_style(lv_obj_t * ddlist, lv_ddlist_style_t type, const lv_style_t * style)
{
LV_ASSERT_OBJ(ddlist, LV_OBJX_NAME);
lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist);
switch(type) {
@ -302,6 +320,8 @@ void lv_ddlist_set_style(lv_obj_t * ddlist, lv_ddlist_style_t type, const lv_sty
void lv_ddlist_set_align(lv_obj_t * ddlist, lv_label_align_t align)
{
LV_ASSERT_OBJ(ddlist, LV_OBJX_NAME);
lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist);
lv_label_set_align(ext->label, align);
@ -322,6 +342,8 @@ void lv_ddlist_set_align(lv_obj_t * ddlist, lv_label_align_t align)
*/
const char * lv_ddlist_get_options(const lv_obj_t * ddlist)
{
LV_ASSERT_OBJ(ddlist, LV_OBJX_NAME);
lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist);
return lv_label_get_text(ext->label);
}
@ -333,6 +355,8 @@ const char * lv_ddlist_get_options(const lv_obj_t * ddlist)
*/
uint16_t lv_ddlist_get_selected(const lv_obj_t * ddlist)
{
LV_ASSERT_OBJ(ddlist, LV_OBJX_NAME);
lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist);
return ext->sel_opt_id;
@ -346,6 +370,8 @@ uint16_t lv_ddlist_get_selected(const lv_obj_t * ddlist)
*/
void lv_ddlist_get_selected_str(const lv_obj_t * ddlist, char * buf, uint16_t buf_size)
{
LV_ASSERT_OBJ(ddlist, LV_OBJX_NAME);
lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist);
uint16_t i;
@ -376,6 +402,8 @@ void lv_ddlist_get_selected_str(const lv_obj_t * ddlist, char * buf, uint16_t bu
*/
lv_coord_t lv_ddlist_get_fix_height(const lv_obj_t * ddlist)
{
LV_ASSERT_OBJ(ddlist, LV_OBJX_NAME);
lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist);
return ext->fix_height;
}
@ -386,6 +414,8 @@ lv_coord_t lv_ddlist_get_fix_height(const lv_obj_t * ddlist)
*/
bool lv_ddlist_get_draw_arrow(lv_obj_t * ddlist)
{
LV_ASSERT_OBJ(ddlist, LV_OBJX_NAME);
lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist);
return ext->draw_arrow ? true : false;
@ -397,6 +427,8 @@ bool lv_ddlist_get_draw_arrow(lv_obj_t * ddlist)
*/
bool lv_ddlist_get_stay_open(lv_obj_t * ddlist)
{
LV_ASSERT_OBJ(ddlist, LV_OBJX_NAME);
lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist);
return ext->stay_open ? true : false;
@ -410,6 +442,8 @@ bool lv_ddlist_get_stay_open(lv_obj_t * ddlist)
*/
const lv_style_t * lv_ddlist_get_style(const lv_obj_t * ddlist, lv_ddlist_style_t type)
{
LV_ASSERT_OBJ(ddlist, LV_OBJX_NAME);
lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist);
switch(type) {
@ -581,9 +615,14 @@ static bool lv_ddlist_design(lv_obj_t * ddlist, const lv_area_t * mask, lv_desig
new_style.text.color = sel_style->text.color;
new_style.text.opa = sel_style->text.opa;
lv_area_t area_arrow;
area_arrow.x2 = ddlist->coords.x2 - style->body.padding.right;
area_arrow.x1 = area_arrow.x2 -
lv_txt_get_width(LV_SYMBOL_DOWN, strlen(LV_SYMBOL_DOWN), sel_style->text.font, 0, 0);
lv_coord_t arrow_width = lv_txt_get_width(LV_SYMBOL_DOWN, strlen(LV_SYMBOL_DOWN), sel_style->text.font, 0, 0);
if(lv_label_get_align(ext->label) != LV_LABEL_ALIGN_RIGHT) {
area_arrow.x2 = ddlist->coords.x2 - style->body.padding.right;
area_arrow.x1 = area_arrow.x2 - arrow_width;
} else {
area_arrow.x1 = ddlist->coords.x1 + style->body.padding.left;
area_arrow.x2 = area_arrow.x1 + arrow_width;
}
area_arrow.y1 = ddlist->coords.y1 + style->text.line_space;
area_arrow.y2 = area_arrow.y1 + font_h;
@ -618,6 +657,7 @@ static lv_res_t lv_ddlist_signal(lv_obj_t * ddlist, lv_signal_t sign, void * par
/* Include the ancient signal function */
res = ancestor_signal(ddlist, sign, param);
if(res != LV_RES_OK) return res;
if(sign == LV_SIGNAL_GET_TYPE) return lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist);
@ -705,13 +745,6 @@ static lv_res_t lv_ddlist_signal(lv_obj_t * ddlist, lv_signal_t sign, void * par
} else if(sign == LV_SIGNAL_GET_EDITABLE) {
bool * editable = (bool *)param;
*editable = true;
} else if(sign == LV_SIGNAL_GET_TYPE) {
lv_obj_type_t * buf = param;
uint8_t i;
for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/
if(buf->type[i] == NULL) break;
}
buf->type[i] = "lv_ddlist";
}
return res;

View File

@ -9,6 +9,7 @@
#include "lv_gauge.h"
#if LV_USE_GAUGE != 0
#include "../lv_core/lv_debug.h"
#include "../lv_draw/lv_draw.h"
#include "../lv_themes/lv_theme.h"
#include "../lv_misc/lv_txt.h"
@ -20,6 +21,8 @@
/*********************
* DEFINES
*********************/
#define LV_OBJX_NAME "lv_gauge"
#define LV_GAUGE_DEF_NEEDLE_COLOR LV_COLOR_RED
#define LV_GAUGE_DEF_LABEL_COUNT 6
#define LV_GAUGE_DEF_LINE_COUNT 21 /*Should be: ((label_cnt - 1) * internal_lines) + 1*/
@ -65,12 +68,12 @@ lv_obj_t * lv_gauge_create(lv_obj_t * par, const lv_obj_t * copy)
/*Create the ancestor gauge*/
lv_obj_t * new_gauge = lv_lmeter_create(par, copy);
lv_mem_assert(new_gauge);
LV_ASSERT_MEM(new_gauge);
if(new_gauge == NULL) return NULL;
/*Allocate the gauge type specific extended data*/
lv_gauge_ext_t * ext = lv_obj_allocate_ext_attr(new_gauge, sizeof(lv_gauge_ext_t));
lv_mem_assert(ext);
LV_ASSERT_MEM(ext);
if(ext == NULL) return NULL;
/*Initialize the allocated 'ext' */
@ -131,6 +134,9 @@ lv_obj_t * lv_gauge_create(lv_obj_t * par, const lv_obj_t * copy)
*/
void lv_gauge_set_needle_count(lv_obj_t * gauge, uint8_t needle_cnt, const lv_color_t colors[])
{
LV_ASSERT_OBJ(gauge, LV_OBJX_NAME);
LV_ASSERT_NULL(colors);
lv_gauge_ext_t * ext = lv_obj_get_ext_attr(gauge);
if(ext->needle_count != needle_cnt) {
@ -140,7 +146,7 @@ void lv_gauge_set_needle_count(lv_obj_t * gauge, uint8_t needle_cnt, const lv_co
}
ext->values = lv_mem_realloc(ext->values, needle_cnt * sizeof(int16_t));
lv_mem_assert(ext->values);
LV_ASSERT_MEM(ext->values);
if(ext->values == NULL) return;
int16_t min = lv_gauge_get_min_value(gauge);
@ -164,6 +170,8 @@ void lv_gauge_set_needle_count(lv_obj_t * gauge, uint8_t needle_cnt, const lv_co
*/
void lv_gauge_set_value(lv_obj_t * gauge, uint8_t needle_id, int16_t value)
{
LV_ASSERT_OBJ(gauge, LV_OBJX_NAME);
lv_gauge_ext_t * ext = lv_obj_get_ext_attr(gauge);
if(needle_id >= ext->needle_count) return;
@ -193,6 +201,8 @@ void lv_gauge_set_value(lv_obj_t * gauge, uint8_t needle_id, int16_t value)
*/
void lv_gauge_set_scale(lv_obj_t * gauge, uint16_t angle, uint8_t line_cnt, uint8_t label_cnt)
{
LV_ASSERT_OBJ(gauge, LV_OBJX_NAME);
lv_lmeter_set_scale(gauge, angle, line_cnt);
lv_gauge_ext_t * ext = lv_obj_get_ext_attr(gauge);
@ -212,6 +222,8 @@ void lv_gauge_set_scale(lv_obj_t * gauge, uint16_t angle, uint8_t line_cnt, uint
*/
int16_t lv_gauge_get_value(const lv_obj_t * gauge, uint8_t needle)
{
LV_ASSERT_OBJ(gauge, LV_OBJX_NAME);
lv_gauge_ext_t * ext = lv_obj_get_ext_attr(gauge);
int16_t min = lv_gauge_get_min_value(gauge);
@ -227,6 +239,8 @@ int16_t lv_gauge_get_value(const lv_obj_t * gauge, uint8_t needle)
*/
uint8_t lv_gauge_get_needle_count(const lv_obj_t * gauge)
{
LV_ASSERT_OBJ(gauge, LV_OBJX_NAME);
lv_gauge_ext_t * ext = lv_obj_get_ext_attr(gauge);
return ext->needle_count;
}
@ -238,6 +252,8 @@ uint8_t lv_gauge_get_needle_count(const lv_obj_t * gauge)
*/
uint8_t lv_gauge_get_label_count(const lv_obj_t * gauge)
{
LV_ASSERT_OBJ(gauge, LV_OBJX_NAME);
lv_gauge_ext_t * ext = lv_obj_get_ext_attr(gauge);
return ext->label_count;
}
@ -258,7 +274,6 @@ uint8_t lv_gauge_get_label_count(const lv_obj_t * gauge)
*/
static bool lv_gauge_design(lv_obj_t * gauge, const lv_area_t * mask, lv_design_mode_t mode)
{
/*Return false if the object is not covers the mask_p area*/
if(mode == LV_DESIGN_COVER_CHK) {
return false;
@ -317,18 +332,12 @@ static lv_res_t lv_gauge_signal(lv_obj_t * gauge, lv_signal_t sign, void * param
/* Include the ancient signal function */
res = ancestor_signal(gauge, sign, param);
if(res != LV_RES_OK) return res;
if(sign == LV_SIGNAL_GET_TYPE) return lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
lv_gauge_ext_t * ext = lv_obj_get_ext_attr(gauge);
if(sign == LV_SIGNAL_CLEANUP) {
lv_mem_free(ext->values);
ext->values = NULL;
} else if(sign == LV_SIGNAL_GET_TYPE) {
lv_obj_type_t * buf = param;
uint8_t i;
for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/
if(buf->type[i] == NULL) break;
}
buf->type[i] = "lv_gauge";
}
return res;

View File

@ -14,6 +14,7 @@
#error "lv_img: lv_label is required. Enable it in lv_conf.h (LV_USE_LABEL 1) "
#endif
#include "../lv_core/lv_debug.h"
#include "../lv_themes/lv_theme.h"
#include "../lv_draw/lv_img_decoder.h"
#include "../lv_misc/lv_fs.h"
@ -23,6 +24,7 @@
/*********************
* DEFINES
*********************/
#define LV_OBJX_NAME "lv_img"
/**********************
* TYPEDEFS
@ -61,14 +63,14 @@ lv_obj_t * lv_img_create(lv_obj_t * par, const lv_obj_t * copy)
/*Create a basic object*/
new_img = lv_obj_create(par, copy);
lv_mem_assert(new_img);
LV_ASSERT_MEM(new_img);
if(new_img == NULL) return NULL;
if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(new_img);
/*Extend the basic object to image object*/
lv_img_ext_t * ext = lv_obj_allocate_ext_attr(new_img, sizeof(lv_img_ext_t));
lv_mem_assert(ext);
LV_ASSERT_MEM(ext);
if(ext == NULL) return NULL;
ext->src = NULL;
@ -121,6 +123,8 @@ lv_obj_t * lv_img_create(lv_obj_t * par, const lv_obj_t * copy)
*/
void lv_img_set_src(lv_obj_t * img, const void * src_img)
{
LV_ASSERT_OBJ(img, LV_OBJX_NAME);
lv_img_src_t src_type = lv_img_src_get_type(src_img);
lv_img_ext_t * ext = lv_obj_get_ext_attr(img);
@ -159,15 +163,20 @@ void lv_img_set_src(lv_obj_t * img, const void * src_img)
} else if(src_type == LV_IMG_SRC_FILE || src_type == LV_IMG_SRC_SYMBOL) {
/* If the new and the old src are the same then it was only a refresh.*/
if(ext->src != src_img) {
/*If memory was allocated because of the previous `src_type` then free it*/
const void * old_src = NULL;
/* If memory was allocated because of the previous `src_type` then save its pointer and free after allocation.
* It's important to allocate first to be sure the new data will be on a new address.
* Else `img_cache` wouldn't see the change in source.*/
if(ext->src_type == LV_IMG_SRC_FILE || ext->src_type == LV_IMG_SRC_SYMBOL) {
lv_mem_free(ext->src);
old_src = ext->src;
}
char * new_str = lv_mem_alloc(strlen(src_img) + 1);
lv_mem_assert(new_str);
LV_ASSERT_MEM(new_str);
if(new_str == NULL) return;
strcpy(new_str, src_img);
ext->src = new_str;
if(old_src) lv_mem_free(old_src);
}
}
@ -201,6 +210,8 @@ void lv_img_set_src(lv_obj_t * img, const void * src_img)
*/
void lv_img_set_auto_size(lv_obj_t * img, bool en)
{
LV_ASSERT_OBJ(img, LV_OBJX_NAME);
lv_img_ext_t * ext = lv_obj_get_ext_attr(img);
ext->auto_size = (en == false ? 0 : 1);
@ -214,6 +225,8 @@ void lv_img_set_auto_size(lv_obj_t * img, bool en)
*/
void lv_img_set_offset_x(lv_obj_t * img, lv_coord_t x)
{
LV_ASSERT_OBJ(img, LV_OBJX_NAME);
lv_img_ext_t * ext = lv_obj_get_ext_attr(img);
if(x < ext->w - 1) {
@ -230,6 +243,8 @@ void lv_img_set_offset_x(lv_obj_t * img, lv_coord_t x)
*/
void lv_img_set_offset_y(lv_obj_t * img, lv_coord_t y)
{
LV_ASSERT_OBJ(img, LV_OBJX_NAME);
lv_img_ext_t * ext = lv_obj_get_ext_attr(img);
if(y < ext->h - 1) {
@ -249,6 +264,8 @@ void lv_img_set_offset_y(lv_obj_t * img, lv_coord_t y)
*/
const void * lv_img_get_src(lv_obj_t * img)
{
LV_ASSERT_OBJ(img, LV_OBJX_NAME);
lv_img_ext_t * ext = lv_obj_get_ext_attr(img);
return ext->src;
@ -261,6 +278,8 @@ const void * lv_img_get_src(lv_obj_t * img)
*/
const char * lv_img_get_file_name(const lv_obj_t * img)
{
LV_ASSERT_OBJ(img, LV_OBJX_NAME);
lv_img_ext_t * ext = lv_obj_get_ext_attr(img);
if(ext->src_type == LV_IMG_SRC_FILE)
@ -276,6 +295,8 @@ const char * lv_img_get_file_name(const lv_obj_t * img)
*/
bool lv_img_get_auto_size(const lv_obj_t * img)
{
LV_ASSERT_OBJ(img, LV_OBJX_NAME);
lv_img_ext_t * ext = lv_obj_get_ext_attr(img);
return ext->auto_size == 0 ? false : true;
@ -288,6 +309,8 @@ bool lv_img_get_auto_size(const lv_obj_t * img)
*/
lv_coord_t lv_img_get_offset_x(lv_obj_t * img)
{
LV_ASSERT_OBJ(img, LV_OBJX_NAME);
lv_img_ext_t * ext = lv_obj_get_ext_attr(img);
return ext->offset.x;
@ -300,6 +323,8 @@ lv_coord_t lv_img_get_offset_x(lv_obj_t * img)
*/
lv_coord_t lv_img_get_offset_y(lv_obj_t * img)
{
LV_ASSERT_OBJ(img, LV_OBJX_NAME);
lv_img_ext_t * ext = lv_obj_get_ext_attr(img);
return ext->offset.y;
@ -385,6 +410,8 @@ static lv_res_t lv_img_signal(lv_obj_t * img, lv_signal_t sign, void * param)
res = ancestor_signal(img, sign, param);
if(res != LV_RES_OK) return res;
if(sign == LV_SIGNAL_GET_TYPE) return lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
lv_img_ext_t * ext = lv_obj_get_ext_attr(img);
if(sign == LV_SIGNAL_CLEANUP) {
if(ext->src_type == LV_IMG_SRC_FILE || ext->src_type == LV_IMG_SRC_SYMBOL) {
@ -397,13 +424,6 @@ static lv_res_t lv_img_signal(lv_obj_t * img, lv_signal_t sign, void * param)
if(ext->src_type == LV_IMG_SRC_SYMBOL) {
lv_img_set_src(img, ext->src);
}
} else if(sign == LV_SIGNAL_GET_TYPE) {
lv_obj_type_t * buf = param;
uint8_t i;
for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/
if(buf->type[i] == NULL) break;
}
buf->type[i] = "lv_img";
}
return res;

View File

@ -6,12 +6,17 @@
/*********************
* INCLUDES
*********************/
#include "../lv_core/lv_debug.h"
#include "lv_imgbtn.h"
#include "lv_label.h"
#if LV_USE_IMGBTN != 0
/*********************
* DEFINES
*********************/
#define LV_OBJX_NAME "lv_imgbtn"
/**********************
* TYPEDEFS
@ -51,12 +56,12 @@ lv_obj_t * lv_imgbtn_create(lv_obj_t * par, const lv_obj_t * copy)
/*Create the ancestor of image button*/
lv_obj_t * new_imgbtn = lv_btn_create(par, copy);
lv_mem_assert(new_imgbtn);
LV_ASSERT_MEM(new_imgbtn);
if(new_imgbtn == NULL) return NULL;
/*Allocate the image button type specific extended data*/
lv_imgbtn_ext_t * ext = lv_obj_allocate_ext_attr(new_imgbtn, sizeof(lv_imgbtn_ext_t));
lv_mem_assert(ext);
LV_ASSERT_MEM(ext);
if(ext == NULL) return NULL;
if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(new_imgbtn);
if(ancestor_design == NULL) ancestor_design = lv_obj_get_design_cb(new_imgbtn);
@ -112,6 +117,8 @@ lv_obj_t * lv_imgbtn_create(lv_obj_t * par, const lv_obj_t * copy)
*/
void lv_imgbtn_set_src(lv_obj_t * imgbtn, lv_btn_state_t state, const void * src)
{
LV_ASSERT_OBJ(imgbtn, LV_OBJX_NAME);
lv_imgbtn_ext_t * ext = lv_obj_get_ext_attr(imgbtn);
ext->img_src[state] = src;
@ -134,6 +141,17 @@ void lv_imgbtn_set_src(lv_obj_t * imgbtn, lv_btn_state_t state, const void * src
void lv_imgbtn_set_src(lv_obj_t * imgbtn, lv_btn_state_t state, const void * src_left, const void * src_mid,
const void * src_right)
{
LV_ASSERT_OBJ(imgbtn, LV_OBJX_NAME);
if(lv_img_src_get_type(src_left) == LV_IMG_SRC_SYMBOL ||
lv_img_src_get_type(src_mid) == LV_IMG_SRC_SYMBOL ||
lv_img_src_get_type(src_right) == LV_IMG_SRC_SYMBOL )
{
LV_LOG_WARN("lv_imgbtn_set_src: symbols are not supported in tiled mode");
return;
}
lv_imgbtn_ext_t * ext = lv_obj_get_ext_attr(imgbtn);
ext->img_src_left[state] = src_left;
@ -153,6 +171,8 @@ void lv_imgbtn_set_src(lv_obj_t * imgbtn, lv_btn_state_t state, const void * src
*/
void lv_imgbtn_set_style(lv_obj_t * imgbtn, lv_imgbtn_style_t type, const lv_style_t * style)
{
LV_ASSERT_OBJ(imgbtn, LV_OBJX_NAME);
lv_btn_set_style(imgbtn, type, style);
}
@ -169,6 +189,8 @@ void lv_imgbtn_set_style(lv_obj_t * imgbtn, lv_imgbtn_style_t type, const lv_sty
*/
const void * lv_imgbtn_get_src(lv_obj_t * imgbtn, lv_btn_state_t state)
{
LV_ASSERT_OBJ(imgbtn, LV_OBJX_NAME);
lv_imgbtn_ext_t * ext = lv_obj_get_ext_attr(imgbtn);
return ext->img_src[state];
@ -183,6 +205,8 @@ const void * lv_imgbtn_get_src(lv_obj_t * imgbtn, lv_btn_state_t state)
*/
const void * lv_imgbtn_get_src_left(lv_obj_t * imgbtn, lv_btn_state_t state)
{
LV_ASSERT_OBJ(imgbtn, LV_OBJX_NAME);
lv_imgbtn_ext_t * ext = lv_obj_get_ext_attr(imgbtn);
return ext->img_src_left[state];
@ -196,6 +220,8 @@ const void * lv_imgbtn_get_src_left(lv_obj_t * imgbtn, lv_btn_state_t state)
*/
const void * lv_imgbtn_get_src_middle(lv_obj_t * imgbtn, lv_btn_state_t state)
{
LV_ASSERT_OBJ(imgbtn, LV_OBJX_NAME);
lv_imgbtn_ext_t * ext = lv_obj_get_ext_attr(imgbtn);
return ext->img_src_mid[state];
@ -209,6 +235,8 @@ const void * lv_imgbtn_get_src_middle(lv_obj_t * imgbtn, lv_btn_state_t state)
*/
const void * lv_imgbtn_get_src_right(lv_obj_t * imgbtn, lv_btn_state_t state)
{
LV_ASSERT_OBJ(imgbtn, LV_OBJX_NAME);
lv_imgbtn_ext_t * ext = lv_obj_get_ext_attr(imgbtn);
return ext->img_src_right[state];
@ -224,6 +252,8 @@ const void * lv_imgbtn_get_src_right(lv_obj_t * imgbtn, lv_btn_state_t state)
*/
const lv_style_t * lv_imgbtn_get_style(const lv_obj_t * imgbtn, lv_imgbtn_style_t type)
{
LV_ASSERT_OBJ(imgbtn, LV_OBJX_NAME);
return lv_btn_get_style(imgbtn, type);
}
@ -269,10 +299,21 @@ static bool lv_imgbtn_design(lv_obj_t * imgbtn, const lv_area_t * mask, lv_desig
const lv_style_t * style = lv_imgbtn_get_style(imgbtn, state);
lv_opa_t opa_scale = lv_obj_get_opa_scale(imgbtn);
#if LV_IMGBTN_TILED == 0
const void * src = ext->img_src[state];
lv_draw_img(&imgbtn->coords, mask, src, style, opa_scale);
if(lv_img_src_get_type(src) == LV_IMG_SRC_SYMBOL) {
lv_draw_label(&imgbtn->coords, mask, style, opa_scale, src, LV_TXT_FLAG_NONE, NULL, LV_LABEL_TEXT_SEL_OFF, LV_LABEL_TEXT_SEL_OFF, NULL);
} else {
lv_draw_img(&imgbtn->coords, mask, src, style, opa_scale);
}
#else
if(lv_img_src_get_type(src) == LV_IMG_SRC_SYMBOL) {
LV_LOG_WARN("lv_imgbtn_design: SYMBOLS are not supported in tiled mode")
return;
}
const void * src;
lv_img_header_t header;
lv_area_t coords;
@ -343,6 +384,7 @@ static lv_res_t lv_imgbtn_signal(lv_obj_t * imgbtn, lv_signal_t sign, void * par
/* Include the ancient signal function */
res = ancestor_signal(imgbtn, sign, param);
if(res != LV_RES_OK) return res;
if(sign == LV_SIGNAL_GET_TYPE) return lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
if(sign == LV_SIGNAL_STYLE_CHG) {
/* If the style changed then the button was clicked, released etc. so probably the state was
@ -350,13 +392,6 @@ static lv_res_t lv_imgbtn_signal(lv_obj_t * imgbtn, lv_signal_t sign, void * par
refr_img(imgbtn);
} else if(sign == LV_SIGNAL_CLEANUP) {
/*Nothing to cleanup. (No dynamically allocated memory in 'ext')*/
} else if(sign == LV_SIGNAL_GET_TYPE) {
lv_obj_type_t * buf = param;
uint8_t i;
for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/
if(buf->type[i] == NULL) break;
}
buf->type[i] = "lv_imgbtn";
}
return res;
@ -374,8 +409,17 @@ static void refr_img(lv_obj_t * imgbtn)
const void * src = ext->img_src_mid[state];
#endif
lv_res_t info_res;
info_res = lv_img_decoder_get_info(src, &header);
lv_res_t info_res = LV_RES_OK;
if(lv_img_src_get_type(src) == LV_IMG_SRC_SYMBOL) {
const lv_style_t * style = ext->btn.styles[state];
header.h = lv_font_get_line_height(style->text.font);
header.w = lv_txt_get_width(src, strlen(src), style->text.font, style->text.letter_space, LV_TXT_FLAG_NONE);
header.always_zero = 0;
header.cf = LV_IMG_CF_ALPHA_1BIT;
} else {
info_res = lv_img_decoder_get_info(src, &header);
}
if(info_res == LV_RES_OK) {
ext->act_cf = header.cf;
#if LV_IMGBTN_TILED == 0

View File

@ -10,12 +10,15 @@
#include "lv_kb.h"
#if LV_USE_KB != 0
#include "lv_ta.h"
#include "../lv_core/lv_debug.h"
#include "../lv_themes/lv_theme.h"
#include "lv_ta.h"
/*********************
* DEFINES
*********************/
#define LV_OBJX_NAME "lv_kb"
#define LV_KB_CTRL_BTN_FLAGS (LV_BTNM_CTRL_NO_REPEAT | LV_BTNM_CTRL_CLICK_TRIG)
/**********************
@ -32,8 +35,8 @@ static lv_res_t lv_kb_signal(lv_obj_t * kb, lv_signal_t sign, void * param);
**********************/
static lv_signal_cb_t ancestor_signal;
/* clang-format off */
static const char * kb_map_lc[] = {"1#", "q", "w", "e", "r", "t", "y", "u", "i", "o", "p", "Bksp", "\n",
"ABC", "a", "s", "d", "f", "g", "h", "j", "k", "l", "Enter", "\n",
static const char * kb_map_lc[] = {"1#", "q", "w", "e", "r", "t", "y", "u", "i", "o", "p", LV_SYMBOL_BACKSPACE, "\n",
"ABC", "a", "s", "d", "f", "g", "h", "j", "k", "l", LV_SYMBOL_NEW_LINE, "\n",
"_", "-", "z", "x", "c", "v", "b", "n", "m", ".", ",", ":", "\n",
LV_SYMBOL_CLOSE, LV_SYMBOL_LEFT, " ", LV_SYMBOL_RIGHT, LV_SYMBOL_OK, ""};
@ -43,8 +46,8 @@ static const lv_btnm_ctrl_t kb_ctrl_lc_map[] = {
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
LV_KB_CTRL_BTN_FLAGS | 2, 2, 6, 2, LV_KB_CTRL_BTN_FLAGS | 2};
static const char * kb_map_uc[] = {"1#", "Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P", "Bksp", "\n",
"abc", "A", "S", "D", "F", "G", "H", "J", "K", "L", "Enter", "\n",
static const char * kb_map_uc[] = {"1#", "Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P", LV_SYMBOL_BACKSPACE, "\n",
"abc", "A", "S", "D", "F", "G", "H", "J", "K", "L", LV_SYMBOL_NEW_LINE, "\n",
"_", "-", "Z", "X", "C", "V", "B", "N", "M", ".", ",", ":", "\n",
LV_SYMBOL_CLOSE, LV_SYMBOL_LEFT, " ", LV_SYMBOL_RIGHT, LV_SYMBOL_OK, ""};
@ -54,7 +57,7 @@ static const lv_btnm_ctrl_t kb_ctrl_uc_map[] = {
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
LV_KB_CTRL_BTN_FLAGS | 2, 2, 6, 2, LV_KB_CTRL_BTN_FLAGS | 2};
static const char * kb_map_spec[] = {"0", "1", "2", "3", "4" ,"5", "6", "7", "8", "9", "Bksp", "\n",
static const char * kb_map_spec[] = {"0", "1", "2", "3", "4" ,"5", "6", "7", "8", "9", LV_SYMBOL_BACKSPACE, "\n",
"abc", "+", "-", "/", "*", "=", "%", "!", "?", "#", "<", ">", "\n",
"\\", "@", "$", "(", ")", "{", "}", "[", "]", ";", "\"", "'", "\n",
LV_SYMBOL_CLOSE, LV_SYMBOL_LEFT, " ", LV_SYMBOL_RIGHT, LV_SYMBOL_OK, ""};
@ -67,7 +70,7 @@ static const lv_btnm_ctrl_t kb_ctrl_spec_map[] = {
static const char * kb_map_num[] = {"1", "2", "3", LV_SYMBOL_CLOSE, "\n",
"4", "5", "6", LV_SYMBOL_OK, "\n",
"7", "8", "9", "Bksp", "\n",
"7", "8", "9", LV_SYMBOL_BACKSPACE, "\n",
"+/-", "0", ".", LV_SYMBOL_LEFT, LV_SYMBOL_RIGHT, ""};
static const lv_btnm_ctrl_t kb_ctrl_num_map[] = {
@ -97,14 +100,14 @@ lv_obj_t * lv_kb_create(lv_obj_t * par, const lv_obj_t * copy)
/*Create the ancestor of keyboard*/
lv_obj_t * new_kb = lv_btnm_create(par, copy);
lv_mem_assert(new_kb);
LV_ASSERT_MEM(new_kb);
if(new_kb == NULL) return NULL;
if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(new_kb);
/*Allocate the keyboard type specific extended data*/
lv_kb_ext_t * ext = lv_obj_allocate_ext_attr(new_kb, sizeof(lv_kb_ext_t));
lv_mem_assert(ext);
LV_ASSERT_MEM(ext);
if(ext == NULL) return NULL;
/*Initialize the allocated 'ext' */
@ -170,6 +173,9 @@ lv_obj_t * lv_kb_create(lv_obj_t * par, const lv_obj_t * copy)
*/
void lv_kb_set_ta(lv_obj_t * kb, lv_obj_t * ta)
{
LV_ASSERT_OBJ(kb, LV_OBJX_NAME);
if(ta) LV_ASSERT_OBJ(ta, "lv_ta");
lv_kb_ext_t * ext = lv_obj_get_ext_attr(kb);
lv_cursor_type_t cur_type;
@ -195,6 +201,8 @@ void lv_kb_set_ta(lv_obj_t * kb, lv_obj_t * ta)
*/
void lv_kb_set_mode(lv_obj_t * kb, lv_kb_mode_t mode)
{
LV_ASSERT_OBJ(kb, LV_OBJX_NAME);
lv_kb_ext_t * ext = lv_obj_get_ext_attr(kb);
if(ext->mode == mode) return;
@ -205,6 +213,9 @@ void lv_kb_set_mode(lv_obj_t * kb, lv_kb_mode_t mode)
} else if(mode == LV_KB_MODE_NUM) {
lv_btnm_set_map(kb, kb_map_num);
lv_btnm_set_ctrl_map(kb, kb_ctrl_num_map);
} else if(mode == LV_KB_MODE_TEXT_UPPER) {
lv_btnm_set_map(kb, kb_map_uc);
lv_btnm_set_ctrl_map(kb, kb_ctrl_uc_map);
}
}
@ -215,6 +226,8 @@ void lv_kb_set_mode(lv_obj_t * kb, lv_kb_mode_t mode)
*/
void lv_kb_set_cursor_manage(lv_obj_t * kb, bool en)
{
LV_ASSERT_OBJ(kb, LV_OBJX_NAME);
lv_kb_ext_t * ext = lv_obj_get_ext_attr(kb);
if(ext->cursor_mng == en) return;
@ -240,6 +253,8 @@ void lv_kb_set_cursor_manage(lv_obj_t * kb, bool en)
*/
void lv_kb_set_style(lv_obj_t * kb, lv_kb_style_t type, const lv_style_t * style)
{
LV_ASSERT_OBJ(kb, LV_OBJX_NAME);
switch(type) {
case LV_KB_STYLE_BG: lv_btnm_set_style(kb, LV_BTNM_STYLE_BG, style); break;
case LV_KB_STYLE_BTN_REL: lv_btnm_set_style(kb, LV_BTNM_STYLE_BTN_REL, style); break;
@ -261,6 +276,8 @@ void lv_kb_set_style(lv_obj_t * kb, lv_kb_style_t type, const lv_style_t * style
*/
lv_obj_t * lv_kb_get_ta(const lv_obj_t * kb)
{
LV_ASSERT_OBJ(kb, LV_OBJX_NAME);
lv_kb_ext_t * ext = lv_obj_get_ext_attr(kb);
return ext->ta;
}
@ -272,6 +289,8 @@ lv_obj_t * lv_kb_get_ta(const lv_obj_t * kb)
*/
lv_kb_mode_t lv_kb_get_mode(const lv_obj_t * kb)
{
LV_ASSERT_OBJ(kb, LV_OBJX_NAME);
lv_kb_ext_t * ext = lv_obj_get_ext_attr(kb);
return ext->mode;
}
@ -283,6 +302,8 @@ lv_kb_mode_t lv_kb_get_mode(const lv_obj_t * kb)
*/
bool lv_kb_get_cursor_manage(const lv_obj_t * kb)
{
LV_ASSERT_OBJ(kb, LV_OBJX_NAME);
lv_kb_ext_t * ext = lv_obj_get_ext_attr(kb);
return ext->cursor_mng == 0 ? false : true;
}
@ -295,6 +316,8 @@ bool lv_kb_get_cursor_manage(const lv_obj_t * kb)
*/
const lv_style_t * lv_kb_get_style(const lv_obj_t * kb, lv_kb_style_t type)
{
LV_ASSERT_OBJ(kb, LV_OBJX_NAME);
const lv_style_t * style = NULL;
switch(type) {
@ -323,6 +346,8 @@ const lv_style_t * lv_kb_get_style(const lv_obj_t * kb, lv_kb_style_t type)
*/
void lv_kb_def_event_cb(lv_obj_t * kb, lv_event_t event)
{
LV_ASSERT_OBJ(kb, LV_OBJX_NAME);
if(event != LV_EVENT_VALUE_CHANGED) return;
lv_kb_ext_t * ext = lv_obj_get_ext_attr(kb);
@ -376,7 +401,7 @@ void lv_kb_def_event_cb(lv_obj_t * kb, lv_event_t event)
lv_ta_cursor_left(ext->ta);
else if(strcmp(txt, LV_SYMBOL_RIGHT) == 0)
lv_ta_cursor_right(ext->ta);
else if(strcmp(txt, "Bksp") == 0)
else if(strcmp(txt, LV_SYMBOL_BACKSPACE) == 0)
lv_ta_del_char(ext->ta);
else if(strcmp(txt, "+/-") == 0) {
uint16_t cur = lv_ta_get_cursor_pos(ext->ta);
@ -419,6 +444,7 @@ static lv_res_t lv_kb_signal(lv_obj_t * kb, lv_signal_t sign, void * param)
/* Include the ancient signal function */
res = ancestor_signal(kb, sign, param);
if(res != LV_RES_OK) return res;
if(sign == LV_SIGNAL_GET_TYPE) return lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
if(sign == LV_SIGNAL_CLEANUP) {
/*Nothing to cleanup. (No dynamically allocated memory in 'ext')*/
@ -436,13 +462,6 @@ static lv_res_t lv_kb_signal(lv_obj_t * kb, lv_signal_t sign, void * param)
lv_cursor_type_t cur_type = lv_ta_get_cursor_type(ext->ta);
lv_ta_set_cursor_type(ext->ta, cur_type | LV_CURSOR_HIDDEN);
}
} else if(sign == LV_SIGNAL_GET_TYPE) {
lv_obj_type_t * buf = param;
uint8_t i;
for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/
if(buf->type[i] == NULL) break;
}
buf->type[i] = "lv_kb";
}
return res;

View File

@ -45,6 +45,7 @@ extern "C" {
enum {
LV_KB_MODE_TEXT,
LV_KB_MODE_NUM,
LV_KB_MODE_TEXT_UPPER,
};
typedef uint8_t lv_kb_mode_t;

View File

@ -10,14 +10,18 @@
#if LV_USE_LABEL != 0
#include "../lv_core/lv_obj.h"
#include "../lv_core/lv_debug.h"
#include "../lv_core/lv_group.h"
#include "../lv_misc/lv_color.h"
#include "../lv_misc/lv_math.h"
#include "../lv_misc/lv_bidi.h"
#include "../lv_misc/lv_printf.h"
/*********************
* DEFINES
*********************/
#define LV_OBJX_NAME "lv_label"
/*Test configurations*/
#ifndef LV_LABEL_DEF_SCROLL_SPEED
#define LV_LABEL_DEF_SCROLL_SPEED (25)
@ -73,7 +77,7 @@ lv_obj_t * lv_label_create(lv_obj_t * par, const lv_obj_t * copy)
/*Create a basic object*/
lv_obj_t * new_label = lv_obj_create(par, copy);
lv_mem_assert(new_label);
LV_ASSERT_MEM(new_label);
if(new_label == NULL) return NULL;
if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(new_label);
@ -82,7 +86,7 @@ lv_obj_t * lv_label_create(lv_obj_t * par, const lv_obj_t * copy)
lv_obj_allocate_ext_attr(new_label, sizeof(lv_label_ext_t));
lv_label_ext_t * ext = lv_obj_get_ext_attr(new_label);
lv_mem_assert(ext);
LV_ASSERT_MEM(ext);
if(ext == NULL) return NULL;
ext->text = NULL;
@ -136,7 +140,7 @@ lv_obj_t * lv_label_create(lv_obj_t * par, const lv_obj_t * copy)
/*In DOT mode save the text byte-to-byte because a '\0' can be in the middle*/
if(copy_ext->long_mode == LV_LABEL_LONG_DOT) {
ext->text = lv_mem_realloc(ext->text, lv_mem_get_size(copy_ext->text));
lv_mem_assert(ext->text);
LV_ASSERT_MEM(ext->text);
if(ext->text == NULL) return NULL;
memcpy(ext->text, copy_ext->text, lv_mem_get_size(copy_ext->text));
}
@ -170,6 +174,8 @@ lv_obj_t * lv_label_create(lv_obj_t * par, const lv_obj_t * copy)
*/
void lv_label_set_text(lv_obj_t * label, const char * text)
{
LV_ASSERT_OBJ(label, LV_OBJX_NAME);
lv_obj_invalidate(label);
lv_label_ext_t * ext = lv_obj_get_ext_attr(label);
@ -180,10 +186,12 @@ void lv_label_set_text(lv_obj_t * label, const char * text)
return;
}
LV_ASSERT_STR(text);
if(ext->text == text) {
/*If set its own text then reallocate it (maybe its size changed)*/
ext->text = lv_mem_realloc(ext->text, strlen(ext->text) + 1);
lv_mem_assert(ext->text);
LV_ASSERT_MEM(ext->text);
if(ext->text == NULL) return;
} else {
/*Allocate space for the new text*/
@ -199,7 +207,7 @@ void lv_label_set_text(lv_obj_t * label, const char * text)
}
ext->text = lv_mem_alloc(len);
lv_mem_assert(ext->text);
LV_ASSERT_MEM(ext->text);
if(ext->text == NULL) return;
#if LV_USE_BIDI == 0
@ -223,6 +231,54 @@ void lv_label_set_text(lv_obj_t * label, const char * text)
lv_label_refr_text(label);
}
/**
* Set a new formatted text for a label. Memory will be allocated to store the text by the label.
* @param label pointer to a label object
* @param fmt `printf`-like format
*/
void lv_label_set_text_fmt(lv_obj_t * label, const char * fmt, ...)
{
LV_ASSERT_OBJ(label, LV_OBJX_NAME);
LV_ASSERT_STR(fmt);
lv_obj_invalidate(label);
lv_label_ext_t * ext = lv_obj_get_ext_attr(label);
/*If text is NULL then refresh */
if(fmt == NULL) {
lv_label_refr_text(label);
return;
}
if(ext->text != NULL && ext->static_txt == 0) {
lv_mem_free(ext->text);
ext->text = NULL;
}
va_list ap, ap2;
va_start(ap, fmt);
va_copy(ap2, ap);
/*Allocate space for the new text by using trick from C99 standard section 7.19.6.12 */
uint32_t len = lv_vsnprintf(NULL, 0, fmt, ap);
va_end(ap);
ext->text = lv_mem_alloc(len+1);
LV_ASSERT_MEM(ext->text);
if(ext->text == NULL) return;
ext->text[len-1] = 0; /* Ensure NULL termination */
lv_vsnprintf(ext->text, len+1, fmt, ap2);
va_end(ap2);
ext->static_txt = 0; /*Now the text is dynamically allocated*/
lv_label_refr_text(label);
}
/**
* Set a new text for a label from a character array. The array don't has to be '\0' terminated.
* Memory will be allocated to store the array by the label.
@ -232,6 +288,8 @@ void lv_label_set_text(lv_obj_t * label, const char * text)
*/
void lv_label_set_array_text(lv_obj_t * label, const char * array, uint16_t size)
{
LV_ASSERT_OBJ(label, LV_OBJX_NAME);
lv_obj_invalidate(label);
lv_label_ext_t * ext = lv_obj_get_ext_attr(label);
@ -248,7 +306,7 @@ void lv_label_set_array_text(lv_obj_t * label, const char * array, uint16_t size
ext->text = NULL;
}
ext->text = lv_mem_alloc(size + 1);
lv_mem_assert(ext->text);
LV_ASSERT_MEM(ext->text);
if(ext->text == NULL) return;
memcpy(ext->text, array, size);
@ -266,6 +324,9 @@ void lv_label_set_array_text(lv_obj_t * label, const char * array, uint16_t size
*/
void lv_label_set_static_text(lv_obj_t * label, const char * text)
{
LV_ASSERT_OBJ(label, LV_OBJX_NAME);
LV_ASSERT_STR(text);
lv_label_ext_t * ext = lv_obj_get_ext_attr(label);
if(ext->static_txt == 0 && ext->text != NULL) {
lv_mem_free(ext->text);
@ -289,6 +350,8 @@ void lv_label_set_static_text(lv_obj_t * label, const char * text)
*/
void lv_label_set_long_mode(lv_obj_t * label, lv_label_long_mode_t long_mode)
{
LV_ASSERT_OBJ(label, LV_OBJX_NAME);
lv_label_ext_t * ext = lv_obj_get_ext_attr(label);
#if LV_USE_ANIMATION
@ -322,6 +385,8 @@ void lv_label_set_long_mode(lv_obj_t * label, lv_label_long_mode_t long_mode)
*/
void lv_label_set_align(lv_obj_t * label, lv_label_align_t align)
{
LV_ASSERT_OBJ(label, LV_OBJX_NAME);
lv_label_ext_t * ext = lv_obj_get_ext_attr(label);
if(ext->align == align) return;
@ -338,6 +403,8 @@ void lv_label_set_align(lv_obj_t * label, lv_label_align_t align)
*/
void lv_label_set_recolor(lv_obj_t * label, bool en)
{
LV_ASSERT_OBJ(label, LV_OBJX_NAME);
lv_label_ext_t * ext = lv_obj_get_ext_attr(label);
if(ext->recolor == en) return;
@ -354,6 +421,8 @@ void lv_label_set_recolor(lv_obj_t * label, bool en)
*/
void lv_label_set_body_draw(lv_obj_t * label, bool en)
{
LV_ASSERT_OBJ(label, LV_OBJX_NAME);
lv_label_ext_t * ext = lv_obj_get_ext_attr(label);
if(ext->body_draw == en) return;
@ -371,6 +440,8 @@ void lv_label_set_body_draw(lv_obj_t * label, bool en)
*/
void lv_label_set_anim_speed(lv_obj_t * label, uint16_t anim_speed)
{
LV_ASSERT_OBJ(label, LV_OBJX_NAME);
#if LV_USE_ANIMATION
lv_label_ext_t * ext = lv_obj_get_ext_attr(label);
if(ext->anim_speed == anim_speed) return;
@ -388,6 +459,8 @@ void lv_label_set_anim_speed(lv_obj_t * label, uint16_t anim_speed)
void lv_label_set_text_sel_start(lv_obj_t * label, uint16_t index)
{
LV_ASSERT_OBJ(label, LV_OBJX_NAME);
#if LV_LABEL_TEXT_SEL
lv_label_ext_t * ext = lv_obj_get_ext_attr(label);
ext->txt_sel_start = index;
@ -400,6 +473,8 @@ void lv_label_set_text_sel_start(lv_obj_t * label, uint16_t index)
void lv_label_set_text_sel_end(lv_obj_t * label, uint16_t index)
{
LV_ASSERT_OBJ(label, LV_OBJX_NAME);
#if LV_LABEL_TEXT_SEL
lv_label_ext_t * ext = lv_obj_get_ext_attr(label);
ext->txt_sel_end = index;
@ -421,6 +496,8 @@ void lv_label_set_text_sel_end(lv_obj_t * label, uint16_t index)
*/
char * lv_label_get_text(const lv_obj_t * label)
{
LV_ASSERT_OBJ(label, LV_OBJX_NAME);
lv_label_ext_t * ext = lv_obj_get_ext_attr(label);
return ext->text;
@ -433,6 +510,8 @@ char * lv_label_get_text(const lv_obj_t * label)
*/
lv_label_long_mode_t lv_label_get_long_mode(const lv_obj_t * label)
{
LV_ASSERT_OBJ(label, LV_OBJX_NAME);
lv_label_ext_t * ext = lv_obj_get_ext_attr(label);
return ext->long_mode;
}
@ -444,6 +523,8 @@ lv_label_long_mode_t lv_label_get_long_mode(const lv_obj_t * label)
*/
lv_label_align_t lv_label_get_align(const lv_obj_t * label)
{
LV_ASSERT_OBJ(label, LV_OBJX_NAME);
lv_label_ext_t * ext = lv_obj_get_ext_attr(label);
lv_label_align_t align = ext->align;
@ -470,6 +551,8 @@ lv_label_align_t lv_label_get_align(const lv_obj_t * label)
*/
bool lv_label_get_recolor(const lv_obj_t * label)
{
LV_ASSERT_OBJ(label, LV_OBJX_NAME);
lv_label_ext_t * ext = lv_obj_get_ext_attr(label);
return ext->recolor == 0 ? false : true;
}
@ -481,6 +564,8 @@ bool lv_label_get_recolor(const lv_obj_t * label)
*/
bool lv_label_get_body_draw(const lv_obj_t * label)
{
LV_ASSERT_OBJ(label, LV_OBJX_NAME);
lv_label_ext_t * ext = lv_obj_get_ext_attr(label);
return ext->body_draw == 0 ? false : true;
}
@ -492,6 +577,8 @@ bool lv_label_get_body_draw(const lv_obj_t * label)
*/
uint16_t lv_label_get_anim_speed(const lv_obj_t * label)
{
LV_ASSERT_OBJ(label, LV_OBJX_NAME);
#if LV_USE_ANIMATION
lv_label_ext_t * ext = lv_obj_get_ext_attr(label);
return ext->anim_speed;
@ -510,6 +597,9 @@ uint16_t lv_label_get_anim_speed(const lv_obj_t * label)
*/
void lv_label_get_letter_pos(const lv_obj_t * label, uint16_t index, lv_point_t * pos)
{
LV_ASSERT_OBJ(label, LV_OBJX_NAME);
LV_ASSERT_NULL(pos);
const char * txt = lv_label_get_text(label);
lv_label_ext_t * ext = lv_obj_get_ext_attr(label);
uint32_t line_start = 0;
@ -579,6 +669,9 @@ void lv_label_get_letter_pos(const lv_obj_t * label, uint16_t index, lv_point_t
*/
uint16_t lv_label_get_letter_on(const lv_obj_t * label, lv_point_t * pos)
{
LV_ASSERT_OBJ(label, LV_OBJX_NAME);
LV_ASSERT_NULL(pos);
const char * txt = lv_label_get_text(label);
lv_label_ext_t * ext = lv_obj_get_ext_attr(label);
uint32_t line_start = 0;
@ -661,6 +754,8 @@ uint16_t lv_label_get_letter_on(const lv_obj_t * label, lv_point_t * pos)
*/
uint16_t lv_label_get_text_sel_start(const lv_obj_t * label)
{
LV_ASSERT_OBJ(label, LV_OBJX_NAME);
#if LV_LABEL_TEXT_SEL
lv_label_ext_t * ext = lv_obj_get_ext_attr(label);
return ext->txt_sel_start;
@ -678,6 +773,8 @@ uint16_t lv_label_get_text_sel_start(const lv_obj_t * label)
*/
uint16_t lv_label_get_text_sel_end(const lv_obj_t * label)
{
LV_ASSERT_OBJ(label, LV_OBJX_NAME);
#if LV_LABEL_TEXT_SEL
lv_label_ext_t * ext = lv_obj_get_ext_attr(label);
return ext->txt_sel_end;
@ -695,6 +792,9 @@ uint16_t lv_label_get_text_sel_end(const lv_obj_t * label)
*/
bool lv_label_is_char_under_pos(const lv_obj_t * label, lv_point_t * pos)
{
LV_ASSERT_OBJ(label, LV_OBJX_NAME);
LV_ASSERT_NULL(pos);
const char * txt = lv_label_get_text(label);
lv_label_ext_t * ext = lv_obj_get_ext_attr(label);
uint32_t line_start = 0;
@ -784,6 +884,9 @@ bool lv_label_is_char_under_pos(const lv_obj_t * label, lv_point_t * pos)
*/
void lv_label_ins_text(lv_obj_t * label, uint32_t pos, const char * txt)
{
LV_ASSERT_OBJ(label, LV_OBJX_NAME);
LV_ASSERT_STR(txt);
lv_label_ext_t * ext = lv_obj_get_ext_attr(label);
/*Can not append to static text*/
@ -796,7 +899,7 @@ void lv_label_ins_text(lv_obj_t * label, uint32_t pos, const char * txt)
uint32_t ins_len = strlen(txt);
uint32_t new_len = ins_len + old_len;
ext->text = lv_mem_realloc(ext->text, new_len + 1);
lv_mem_assert(ext->text);
LV_ASSERT_MEM(ext->text);
if(ext->text == NULL) return;
if(pos == LV_LABEL_POS_LAST) {
@ -817,6 +920,8 @@ void lv_label_ins_text(lv_obj_t * label, uint32_t pos, const char * txt)
*/
void lv_label_cut_text(lv_obj_t * label, uint32_t pos, uint32_t cnt)
{
LV_ASSERT_OBJ(label, LV_OBJX_NAME);
lv_label_ext_t * ext = lv_obj_get_ext_attr(label);
/*Can not append to static text*/
@ -953,6 +1058,7 @@ static lv_res_t lv_label_signal(lv_obj_t * label, lv_signal_t sign, void * param
/* Include the ancient signal function */
res = ancestor_signal(label, sign, param);
if(res != LV_RES_OK) return res;
if(sign == LV_SIGNAL_GET_TYPE) return lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
lv_label_ext_t * ext = lv_obj_get_ext_attr(label);
if(sign == LV_SIGNAL_CLEANUP) {

View File

@ -21,6 +21,7 @@ extern "C" {
#if LV_USE_LABEL != 0
#include <stdarg.h>
#include "../lv_core/lv_obj.h"
#include "../lv_font/lv_font.h"
#include "../lv_font/lv_symbol_def.h"
@ -34,6 +35,10 @@ extern "C" {
#define LV_LABEL_POS_LAST 0xFFFF
#define LV_LABEL_TEXT_SEL_OFF 0xFFFF
LV_EXPORT_CONST_INT(LV_LABEL_DOT_NUM);
LV_EXPORT_CONST_INT(LV_LABEL_POS_LAST);
LV_EXPORT_CONST_INT(LV_LABEL_TEXT_SEL_OFF);
/**********************
* TYPEDEFS
**********************/
@ -130,6 +135,13 @@ lv_obj_t * lv_label_create(lv_obj_t * par, const lv_obj_t * copy);
*/
void lv_label_set_text(lv_obj_t * label, const char * text);
/**
* Set a new formatted text for a label. Memory will be allocated to store the text by the label.
* @param label pointer to a label object
* @param fmt `printf`-like format
*/
void lv_label_set_text_fmt(lv_obj_t * label, const char * fmt, ...);
/**
* Set a new text for a label from a character array. The array don't has to be '\0' terminated.
* Memory will be allocated to store the array by the label.

View File

@ -9,12 +9,15 @@
#include "lv_led.h"
#if LV_USE_LED != 0
#include "../lv_core/lv_debug.h"
#include "../lv_themes/lv_theme.h"
#include "../lv_draw/lv_draw.h"
/*********************
* DEFINES
*********************/
#define LV_OBJX_NAME "lv_led"
#define LV_LED_WIDTH_DEF (LV_DPI / 3)
#define LV_LED_HEIGHT_DEF (LV_DPI / 3)
#define LV_LED_BRIGHT_OFF 100
@ -56,7 +59,7 @@ lv_obj_t * lv_led_create(lv_obj_t * par, const lv_obj_t * copy)
/*Create the ancestor basic object*/
lv_obj_t * new_led = lv_obj_create(par, copy);
lv_mem_assert(new_led);
LV_ASSERT_MEM(new_led);
if(new_led == NULL) return NULL;
if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(new_led);
@ -64,7 +67,7 @@ lv_obj_t * lv_led_create(lv_obj_t * par, const lv_obj_t * copy)
/*Allocate the object type specific extended data*/
lv_led_ext_t * ext = lv_obj_allocate_ext_attr(new_led, sizeof(lv_led_ext_t));
lv_mem_assert(ext);
LV_ASSERT_MEM(ext);
if(ext == NULL) return NULL;
ext->bright = LV_LED_BRIGHT_ON;
@ -109,6 +112,8 @@ lv_obj_t * lv_led_create(lv_obj_t * par, const lv_obj_t * copy)
*/
void lv_led_set_bright(lv_obj_t * led, uint8_t bright)
{
LV_ASSERT_OBJ(led, LV_OBJX_NAME);
/*Set the brightness*/
lv_led_ext_t * ext = lv_obj_get_ext_attr(led);
if(ext->bright == bright) return;
@ -125,6 +130,8 @@ void lv_led_set_bright(lv_obj_t * led, uint8_t bright)
*/
void lv_led_on(lv_obj_t * led)
{
LV_ASSERT_OBJ(led, LV_OBJX_NAME);
lv_led_set_bright(led, LV_LED_BRIGHT_ON);
}
@ -134,6 +141,8 @@ void lv_led_on(lv_obj_t * led)
*/
void lv_led_off(lv_obj_t * led)
{
LV_ASSERT_OBJ(led, LV_OBJX_NAME);
lv_led_set_bright(led, LV_LED_BRIGHT_OFF);
}
@ -143,6 +152,8 @@ void lv_led_off(lv_obj_t * led)
*/
void lv_led_toggle(lv_obj_t * led)
{
LV_ASSERT_OBJ(led, LV_OBJX_NAME);
uint8_t bright = lv_led_get_bright(led);
if(bright > (LV_LED_BRIGHT_OFF + LV_LED_BRIGHT_ON) >> 1)
lv_led_off(led);
@ -161,6 +172,8 @@ void lv_led_toggle(lv_obj_t * led)
*/
uint8_t lv_led_get_bright(const lv_obj_t * led)
{
LV_ASSERT_OBJ(led, LV_OBJX_NAME);
lv_led_ext_t * ext = lv_obj_get_ext_attr(led);
return ext->bright;
}

View File

@ -9,6 +9,7 @@
#include "lv_line.h"
#if LV_USE_LINE != 0
#include "../lv_core/lv_debug.h"
#include "../lv_draw/lv_draw.h"
#include "../lv_misc/lv_math.h"
#include <stdbool.h>
@ -18,6 +19,7 @@
/*********************
* DEFINES
*********************/
#define LV_OBJX_NAME "lv_line"
/**********************
* TYPEDEFS
@ -53,14 +55,14 @@ lv_obj_t * lv_line_create(lv_obj_t * par, const lv_obj_t * copy)
/*Create a basic object*/
lv_obj_t * new_line = lv_obj_create(par, copy);
lv_mem_assert(new_line);
LV_ASSERT_MEM(new_line);
if(new_line == NULL) return NULL;
if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(new_line);
/*Extend the basic object to line object*/
lv_line_ext_t * ext = lv_obj_allocate_ext_attr(new_line, sizeof(lv_line_ext_t));
lv_mem_assert(ext);
LV_ASSERT_MEM(ext);
if(ext == NULL) return NULL;
ext->point_num = 0;
@ -107,6 +109,8 @@ lv_obj_t * lv_line_create(lv_obj_t * par, const lv_obj_t * copy)
*/
void lv_line_set_points(lv_obj_t * line, const lv_point_t point_a[], uint16_t point_num)
{
LV_ASSERT_OBJ(line, LV_OBJX_NAME);
lv_line_ext_t * ext = lv_obj_get_ext_attr(line);
ext->point_array = point_a;
ext->point_num = point_num;
@ -135,6 +139,8 @@ void lv_line_set_points(lv_obj_t * line, const lv_point_t point_a[], uint16_t po
*/
void lv_line_set_auto_size(lv_obj_t * line, bool en)
{
LV_ASSERT_OBJ(line, LV_OBJX_NAME);
lv_line_ext_t * ext = lv_obj_get_ext_attr(line);
if(ext->auto_size == en) return;
@ -153,6 +159,8 @@ void lv_line_set_auto_size(lv_obj_t * line, bool en)
*/
void lv_line_set_y_invert(lv_obj_t * line, bool en)
{
LV_ASSERT_OBJ(line, LV_OBJX_NAME);
lv_line_ext_t * ext = lv_obj_get_ext_attr(line);
if(ext->y_inv == en) return;
@ -172,6 +180,8 @@ void lv_line_set_y_invert(lv_obj_t * line, bool en)
*/
bool lv_line_get_auto_size(const lv_obj_t * line)
{
LV_ASSERT_OBJ(line, LV_OBJX_NAME);
lv_line_ext_t * ext = lv_obj_get_ext_attr(line);
return ext->auto_size == 0 ? false : true;
@ -184,6 +194,8 @@ bool lv_line_get_auto_size(const lv_obj_t * line)
*/
bool lv_line_get_y_invert(const lv_obj_t * line)
{
LV_ASSERT_OBJ(line, LV_OBJX_NAME);
lv_line_ext_t * ext = lv_obj_get_ext_attr(line);
return ext->y_inv == 0 ? false : true;
@ -282,15 +294,9 @@ static lv_res_t lv_line_signal(lv_obj_t * line, lv_signal_t sign, void * param)
/* Include the ancient signal function */
res = ancestor_signal(line, sign, param);
if(res != LV_RES_OK) return res;
if(sign == LV_SIGNAL_GET_TYPE) return lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
if(sign == LV_SIGNAL_GET_TYPE) {
lv_obj_type_t * buf = param;
uint8_t i;
for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/
if(buf->type[i] == NULL) break;
}
buf->type[i] = "lv_line";
} else if(sign == LV_SIGNAL_REFR_EXT_DRAW_PAD) {
if(sign == LV_SIGNAL_REFR_EXT_DRAW_PAD) {
const lv_style_t * style = lv_line_get_style(line, LV_LINE_STYLE_MAIN);
if(line->ext_draw_pad < style->line.width) line->ext_draw_pad = style->line.width;
}

View File

@ -9,6 +9,7 @@
#include "lv_list.h"
#if LV_USE_LIST != 0
#include "../lv_core/lv_debug.h"
#include "../lv_core/lv_group.h"
#include "../lv_themes/lv_theme.h"
#include "../lv_misc/lv_anim.h"
@ -17,6 +18,8 @@
/*********************
* DEFINES
*********************/
#define LV_OBJX_NAME "lv_list"
#define LV_LIST_LAYOUT_DEF LV_LAYOUT_COL_M
#if LV_USE_ANIMATION == 0
@ -69,13 +72,13 @@ lv_obj_t * lv_list_create(lv_obj_t * par, const lv_obj_t * copy)
/*Create the ancestor basic object*/
lv_obj_t * new_list = lv_page_create(par, copy);
lv_mem_assert(new_list);
LV_ASSERT_MEM(new_list);
if(new_list == NULL) return NULL;
if(ancestor_page_signal == NULL) ancestor_page_signal = lv_obj_get_signal_cb(new_list);
lv_list_ext_t * ext = lv_obj_allocate_ext_attr(new_list, sizeof(lv_list_ext_t));
lv_mem_assert(ext);
LV_ASSERT_MEM(ext);
if(ext == NULL) return NULL;
ext->style_img = NULL;
@ -149,13 +152,15 @@ lv_obj_t * lv_list_create(lv_obj_t * par, const lv_obj_t * copy)
/**
* Delete all children of the scrl object, without deleting scrl child.
* @param obj pointer to an object
* @param list pointer to an object
*/
void lv_list_clean(lv_obj_t * obj)
void lv_list_clean(lv_obj_t * list)
{
lv_obj_t * scrl = lv_page_get_scrl(obj);
LV_ASSERT_OBJ(list, LV_OBJX_NAME);
lv_obj_t * scrl = lv_page_get_scrl(list);
lv_obj_clean(scrl);
lv_list_ext_t * ext = lv_obj_get_ext_attr(obj);
lv_list_ext_t * ext = lv_obj_get_ext_attr(list);
ext->size = 0;
}
@ -172,6 +177,8 @@ void lv_list_clean(lv_obj_t * obj)
*/
lv_obj_t * lv_list_add_btn(lv_obj_t * list, const void * img_src, const char * txt)
{
LV_ASSERT_OBJ(list, LV_OBJX_NAME);
lv_list_ext_t * ext = lv_obj_get_ext_attr(list);
ext->size++;
/*Create a list element with the image an the text*/
@ -237,6 +244,8 @@ lv_obj_t * lv_list_add_btn(lv_obj_t * list, const void * img_src, const char * t
*/
bool lv_list_remove(const lv_obj_t * list, uint16_t index)
{
LV_ASSERT_OBJ(list, LV_OBJX_NAME);
lv_list_ext_t * ext = lv_obj_get_ext_attr(list);
if(index >= ext->size) return false;
uint16_t count = 0;
@ -264,6 +273,8 @@ bool lv_list_remove(const lv_obj_t * list, uint16_t index)
*/
void lv_list_set_single_mode(lv_obj_t * list, bool mode)
{
LV_ASSERT_OBJ(list, LV_OBJX_NAME);
lv_list_ext_t * ext = lv_obj_get_ext_attr(list);
ext->single_mode = mode;
@ -279,6 +290,9 @@ void lv_list_set_single_mode(lv_obj_t * list, bool mode)
*/
void lv_list_set_btn_selected(lv_obj_t * list, lv_obj_t * btn)
{
LV_ASSERT_OBJ(list, LV_OBJX_NAME);
if(btn) LV_ASSERT_OBJ(list, "lv_btn");
lv_list_ext_t * ext = lv_obj_get_ext_attr(list);
if(ext->selected_btn) {
@ -318,6 +332,8 @@ void lv_list_set_btn_selected(lv_obj_t * list, lv_obj_t * btn)
*/
void lv_list_set_style(lv_obj_t * list, lv_list_style_t type, const lv_style_t * style)
{
LV_ASSERT_OBJ(list, LV_OBJX_NAME);
lv_list_ext_t * ext = lv_obj_get_ext_attr(list);
lv_btn_style_t btn_style_refr = LV_BTN_STYLE_REL;
lv_obj_t * btn;
@ -363,6 +379,38 @@ void lv_list_set_style(lv_obj_t * list, lv_list_style_t type, const lv_style_t *
}
}
/**
* Set layout of a list
* @param list pointer to a list object
* @param layout which layout should be used
*/
void lv_list_set_layout(lv_obj_t * list, lv_layout_t layout)
{
LV_ASSERT_OBJ(list, LV_OBJX_NAME);
/* Update list layout if necessary */
if (layout == lv_list_get_layout(list)) return;
/* Get the first button on the list */
lv_obj_t * btn = lv_list_get_prev_btn(list, NULL);
/* Visit all buttons on the list and update their layout */
while(btn != NULL) {
/*If a column layout set the buttons' width to list width*/
if(layout == LV_LAYOUT_COL_M || layout == LV_LAYOUT_COL_L || layout == LV_LAYOUT_COL_R) {
lv_btn_set_fit2(list, LV_FIT_FLOOD, LV_FIT_TIGHT);
}
/*If a row layout set the buttons' width according to the content*/
else if (layout == LV_LAYOUT_ROW_M || layout == LV_LAYOUT_ROW_T || layout == LV_LAYOUT_ROW_B) {
lv_btn_set_fit(list, LV_FIT_TIGHT);
}
btn = lv_list_get_prev_btn(list, btn);
}
lv_page_set_scrl_layout(list, layout);
}
/*=====================
* Getter functions
*====================*/
@ -373,6 +421,8 @@ void lv_list_set_style(lv_obj_t * list, lv_list_style_t type, const lv_style_t *
*/
bool lv_list_get_single_mode(lv_obj_t * list)
{
LV_ASSERT_OBJ(list, LV_OBJX_NAME);
lv_list_ext_t * ext = lv_obj_get_ext_attr(list);
return (ext->single_mode);
@ -385,6 +435,8 @@ bool lv_list_get_single_mode(lv_obj_t * list)
*/
const char * lv_list_get_btn_text(const lv_obj_t * btn)
{
LV_ASSERT_OBJ(btn, "lv_btn");
lv_obj_t * label = lv_list_get_btn_label(btn);
if(label == NULL) return "";
return lv_label_get_text(label);
@ -397,6 +449,8 @@ const char * lv_list_get_btn_text(const lv_obj_t * btn)
*/
lv_obj_t * lv_list_get_btn_label(const lv_obj_t * btn)
{
LV_ASSERT_OBJ(btn, "lv_btn");
lv_obj_t * label = lv_obj_get_child(btn, NULL);
if(label == NULL) return NULL;
@ -415,6 +469,8 @@ lv_obj_t * lv_list_get_btn_label(const lv_obj_t * btn)
*/
lv_obj_t * lv_list_get_btn_img(const lv_obj_t * btn)
{
LV_ASSERT_OBJ(btn, "lv_btn");
#if LV_USE_IMG != 0
lv_obj_t * img = lv_obj_get_child(btn, NULL);
if(img == NULL) return NULL;
@ -438,6 +494,8 @@ lv_obj_t * lv_list_get_btn_img(const lv_obj_t * btn)
*/
lv_obj_t * lv_list_get_prev_btn(const lv_obj_t * list, lv_obj_t * prev_btn)
{
LV_ASSERT_OBJ(list, LV_OBJX_NAME);
/* Not a good practice but user can add/create objects to the lists manually.
* When getting the next button try to be sure that it is at least a button */
@ -463,6 +521,8 @@ lv_obj_t * lv_list_get_prev_btn(const lv_obj_t * list, lv_obj_t * prev_btn)
*/
lv_obj_t * lv_list_get_next_btn(const lv_obj_t * list, lv_obj_t * prev_btn)
{
LV_ASSERT_OBJ(list, LV_OBJX_NAME);
/* Not a good practice but user can add/create objects to the lists manually.
* When getting the next button try to be sure that it is at least a button */
@ -488,6 +548,9 @@ lv_obj_t * lv_list_get_next_btn(const lv_obj_t * list, lv_obj_t * prev_btn)
*/
int32_t lv_list_get_btn_index(const lv_obj_t * list, const lv_obj_t * btn)
{
LV_ASSERT_OBJ(list, LV_OBJX_NAME);
LV_ASSERT_OBJ(btn, "lv_btn");
int index = 0;
if(list == NULL) {
/* no list provided, assuming btn is part of a list */
@ -511,6 +574,8 @@ int32_t lv_list_get_btn_index(const lv_obj_t * list, const lv_obj_t * btn)
*/
uint16_t lv_list_get_size(const lv_obj_t * list)
{
LV_ASSERT_OBJ(list, LV_OBJX_NAME);
lv_list_ext_t * ext = lv_obj_get_ext_attr(list);
return ext->size;
}
@ -523,20 +588,35 @@ uint16_t lv_list_get_size(const lv_obj_t * list)
*/
lv_obj_t * lv_list_get_btn_selected(const lv_obj_t * list)
{
LV_ASSERT_OBJ(list, LV_OBJX_NAME);
lv_list_ext_t * ext = lv_obj_get_ext_attr(list);
return ext->selected_btn;
}
#endif
/**
* Get layout of a list
* @param list pointer to a list object
* @return layout of the list object
*/
lv_layout_t lv_list_get_layout(lv_obj_t * list)
{
LV_ASSERT_OBJ(list, LV_OBJX_NAME);
return lv_page_get_scrl_layout(list);
}
/**
* Get a style of a list
* @param list pointer to a list object
* @param type which style should be get
* @return style pointer to a style
* */
*/
const lv_style_t * lv_list_get_style(const lv_obj_t * list, lv_list_style_t type)
{
LV_ASSERT_OBJ(list, LV_OBJX_NAME);
const lv_style_t * style = NULL;
lv_list_ext_t * ext = lv_obj_get_ext_attr(list);
@ -555,6 +635,7 @@ const lv_style_t * lv_list_get_style(const lv_obj_t * list, lv_list_style_t type
return style;
}
/*=====================
* Other functions
*====================*/
@ -565,6 +646,8 @@ const lv_style_t * lv_list_get_style(const lv_obj_t * list, lv_list_style_t type
*/
void lv_list_up(const lv_obj_t * list)
{
LV_ASSERT_OBJ(list, LV_OBJX_NAME);
/*Search the first list element which 'y' coordinate is below the parent
* and position the list to show this element on the bottom*/
lv_obj_t * scrl = lv_page_get_scrl(list);
@ -610,6 +693,8 @@ void lv_list_up(const lv_obj_t * list)
*/
void lv_list_down(const lv_obj_t * list)
{
LV_ASSERT_OBJ(list, LV_OBJX_NAME);
/*Search the first list element which 'y' coordinate is above the parent
* and position the list to show this element on the top*/
lv_obj_t * scrl = lv_page_get_scrl(list);
@ -651,6 +736,7 @@ void lv_list_down(const lv_obj_t * list)
*/
void lv_list_focus(const lv_obj_t * btn, lv_anim_enable_t anim)
{
LV_ASSERT_OBJ(btn, "");
#if LV_USE_ANIMATION == 0
anim = false;
@ -679,6 +765,7 @@ static lv_res_t lv_list_signal(lv_obj_t * list, lv_signal_t sign, void * param)
/* Include the ancient signal function */
res = ancestor_page_signal(list, sign, param);
if(res != LV_RES_OK) return res;
if(sign == LV_SIGNAL_GET_TYPE) return lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
if(sign == LV_SIGNAL_RELEASED || sign == LV_SIGNAL_PRESSED || sign == LV_SIGNAL_PRESSING ||
sign == LV_SIGNAL_LONG_PRESS || sign == LV_SIGNAL_LONG_PRESS_REP) {
@ -808,13 +895,6 @@ static lv_res_t lv_list_signal(lv_obj_t * list, lv_signal_t sign, void * param)
}
}
#endif
} else if(sign == LV_SIGNAL_GET_TYPE) {
lv_obj_type_t * buf = param;
uint8_t i;
for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/
if(buf->type[i] == NULL) break;
}
buf->type[i] = "lv_list";
}
return res;
}
@ -833,6 +913,7 @@ static lv_res_t lv_list_btn_signal(lv_obj_t * btn, lv_signal_t sign, void * para
/* Include the ancient signal function */
res = ancestor_btn_signal(btn, sign, param);
if(res != LV_RES_OK) return res;
if(sign == LV_SIGNAL_GET_TYPE) return lv_obj_handle_get_type_signal(param, "");
if(sign == LV_SIGNAL_RELEASED) {
lv_obj_t * list = lv_obj_get_parent(lv_obj_get_parent(btn));

View File

@ -95,9 +95,9 @@ lv_obj_t * lv_list_create(lv_obj_t * par, const lv_obj_t * copy);
/**
* Delete all children of the scrl object, without deleting scrl child.
* @param obj pointer to an object
* @param list pointer to an object
*/
void lv_list_clean(lv_obj_t * obj);
void lv_list_clean(lv_obj_t * list);
/*======================
* Add/remove functions
@ -192,6 +192,13 @@ static inline void lv_list_set_anim_time(lv_obj_t * list, uint16_t anim_time)
*/
void lv_list_set_style(lv_obj_t * list, lv_list_style_t type, const lv_style_t * style);
/**
* Set layout of a list
* @param list pointer to a list object
* @param layout which layout should be used
*/
void lv_list_set_layout(lv_obj_t * list, lv_layout_t layout);
/*=====================
* Getter functions
*====================*/
@ -262,6 +269,13 @@ uint16_t lv_list_get_size(const lv_obj_t * list);
lv_obj_t * lv_list_get_btn_selected(const lv_obj_t * list);
#endif
/**
* Get layout of a list
* @param list pointer to a list object
* @return layout of the list object
*/
lv_layout_t lv_list_get_layout(lv_obj_t * list);
/**
* Get the scroll bar mode of a list
* @param list pointer to a list object

View File

@ -9,6 +9,7 @@
#include "lv_lmeter.h"
#if LV_USE_LMETER != 0
#include "../lv_core/lv_debug.h"
#include "../lv_draw/lv_draw.h"
#include "../lv_themes/lv_theme.h"
#include "../lv_core/lv_group.h"
@ -17,6 +18,8 @@
/*********************
* DEFINES
*********************/
#define LV_OBJX_NAME "lv_lmeter"
#define LV_LMETER_LINE_UPSCALE 5 /*2^x upscale of line to make rounding*/
#define LV_LMETER_LINE_UPSCALE_MASK ((1 << LV_LMETER_LINE_UPSCALE) - 1)
@ -57,14 +60,14 @@ lv_obj_t * lv_lmeter_create(lv_obj_t * par, const lv_obj_t * copy)
/*Create the ancestor of line meter*/
lv_obj_t * new_lmeter = lv_obj_create(par, copy);
lv_mem_assert(new_lmeter);
LV_ASSERT_MEM(new_lmeter);
if(new_lmeter == NULL) return NULL;
if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(new_lmeter);
/*Allocate the line meter type specific extended data*/
lv_lmeter_ext_t * ext = lv_obj_allocate_ext_attr(new_lmeter, sizeof(lv_lmeter_ext_t));
lv_mem_assert(ext);
LV_ASSERT_MEM(ext);
if(ext == NULL) return NULL;
/*Initialize the allocated 'ext' */
@ -119,6 +122,8 @@ lv_obj_t * lv_lmeter_create(lv_obj_t * par, const lv_obj_t * copy)
*/
void lv_lmeter_set_value(lv_obj_t * lmeter, int16_t value)
{
LV_ASSERT_OBJ(lmeter, LV_OBJX_NAME);
lv_lmeter_ext_t * ext = lv_obj_get_ext_attr(lmeter);
if(ext->cur_value == value) return;
@ -135,6 +140,8 @@ void lv_lmeter_set_value(lv_obj_t * lmeter, int16_t value)
*/
void lv_lmeter_set_range(lv_obj_t * lmeter, int16_t min, int16_t max)
{
LV_ASSERT_OBJ(lmeter, LV_OBJX_NAME);
lv_lmeter_ext_t * ext = lv_obj_get_ext_attr(lmeter);
if(ext->min_value == min && ext->max_value == max) return;
@ -159,6 +166,8 @@ void lv_lmeter_set_range(lv_obj_t * lmeter, int16_t min, int16_t max)
*/
void lv_lmeter_set_scale(lv_obj_t * lmeter, uint16_t angle, uint8_t line_cnt)
{
LV_ASSERT_OBJ(lmeter, LV_OBJX_NAME);
lv_lmeter_ext_t * ext = lv_obj_get_ext_attr(lmeter);
if(ext->scale_angle == angle && ext->line_cnt == line_cnt) return;
@ -179,6 +188,8 @@ void lv_lmeter_set_scale(lv_obj_t * lmeter, uint16_t angle, uint8_t line_cnt)
*/
int16_t lv_lmeter_get_value(const lv_obj_t * lmeter)
{
LV_ASSERT_OBJ(lmeter, LV_OBJX_NAME);
lv_lmeter_ext_t * ext = lv_obj_get_ext_attr(lmeter);
return ext->cur_value;
}
@ -190,6 +201,8 @@ int16_t lv_lmeter_get_value(const lv_obj_t * lmeter)
*/
int16_t lv_lmeter_get_min_value(const lv_obj_t * lmeter)
{
LV_ASSERT_OBJ(lmeter, LV_OBJX_NAME);
lv_lmeter_ext_t * ext = lv_obj_get_ext_attr(lmeter);
return ext->min_value;
}
@ -201,6 +214,8 @@ int16_t lv_lmeter_get_min_value(const lv_obj_t * lmeter)
*/
int16_t lv_lmeter_get_max_value(const lv_obj_t * lmeter)
{
LV_ASSERT_OBJ(lmeter, LV_OBJX_NAME);
lv_lmeter_ext_t * ext = lv_obj_get_ext_attr(lmeter);
return ext->max_value;
}
@ -212,6 +227,8 @@ int16_t lv_lmeter_get_max_value(const lv_obj_t * lmeter)
*/
uint8_t lv_lmeter_get_line_count(const lv_obj_t * lmeter)
{
LV_ASSERT_OBJ(lmeter, LV_OBJX_NAME);
lv_lmeter_ext_t * ext = lv_obj_get_ext_attr(lmeter);
return ext->line_cnt;
}
@ -223,6 +240,8 @@ uint8_t lv_lmeter_get_line_count(const lv_obj_t * lmeter)
*/
uint16_t lv_lmeter_get_scale_angle(const lv_obj_t * lmeter)
{
LV_ASSERT_OBJ(lmeter, LV_OBJX_NAME);
lv_lmeter_ext_t * ext = lv_obj_get_ext_attr(lmeter);
return ext->scale_angle;
}
@ -335,6 +354,7 @@ static lv_res_t lv_lmeter_signal(lv_obj_t * lmeter, lv_signal_t sign, void * par
/* Include the ancient signal function */
res = ancestor_signal(lmeter, sign, param);
if(res != LV_RES_OK) return res;
if(sign == LV_SIGNAL_GET_TYPE) return lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
if(sign == LV_SIGNAL_CLEANUP) {
/*Nothing to cleanup. (No dynamically allocated memory in 'ext')*/
@ -343,13 +363,6 @@ static lv_res_t lv_lmeter_signal(lv_obj_t * lmeter, lv_signal_t sign, void * par
} else if(sign == LV_SIGNAL_REFR_EXT_DRAW_PAD) {
const lv_style_t * style = lv_lmeter_get_style(lmeter, LV_LMETER_STYLE_MAIN);
lmeter->ext_draw_pad = LV_MATH_MAX(lmeter->ext_draw_pad, style->line.width);
} else if(sign == LV_SIGNAL_GET_TYPE) {
lv_obj_type_t * buf = param;
uint8_t i;
for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/
if(buf->type[i] == NULL) break;
}
buf->type[i] = "lv_lmeter";
}
return res;

View File

@ -9,6 +9,7 @@
#include "lv_mbox.h"
#if LV_USE_MBOX != 0
#include "../lv_core/lv_debug.h"
#include "../lv_core/lv_group.h"
#include "../lv_themes/lv_theme.h"
#include "../lv_misc/lv_anim.h"
@ -17,6 +18,7 @@
/*********************
* DEFINES
*********************/
#define LV_OBJX_NAME "lv_mbos"
#if LV_USE_ANIMATION
#ifndef LV_MBOX_CLOSE_ANIM_TIME
@ -68,14 +70,14 @@ lv_obj_t * lv_mbox_create(lv_obj_t * par, const lv_obj_t * copy)
/*Create the ancestor message box*/
lv_obj_t * new_mbox = lv_cont_create(par, copy);
lv_mem_assert(new_mbox);
LV_ASSERT_MEM(new_mbox);
if(new_mbox == NULL) return NULL;
if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(new_mbox);
/*Allocate the message box type specific extended data*/
lv_mbox_ext_t * ext = lv_obj_allocate_ext_attr(new_mbox, sizeof(lv_mbox_ext_t));
lv_mem_assert(ext);
LV_ASSERT_MEM(ext);
if(ext == NULL) return NULL;
ext->text = NULL;
@ -139,6 +141,9 @@ lv_obj_t * lv_mbox_create(lv_obj_t * par, const lv_obj_t * copy)
*/
void lv_mbox_add_btns(lv_obj_t * mbox, const char ** btn_map)
{
LV_ASSERT_OBJ(mbox, LV_OBJX_NAME);
LV_ASSERT_NULL(btn_map);
lv_mbox_ext_t * ext = lv_obj_get_ext_attr(mbox);
/*Create a button matrix if not exists yet*/
@ -174,6 +179,9 @@ void lv_mbox_add_btns(lv_obj_t * mbox, const char ** btn_map)
*/
void lv_mbox_set_text(lv_obj_t * mbox, const char * txt)
{
LV_ASSERT_OBJ(mbox, LV_OBJX_NAME);
LV_ASSERT_STR(txt);
lv_mbox_ext_t * ext = lv_obj_get_ext_attr(mbox);
lv_label_set_text(ext->text, txt);
@ -187,6 +195,8 @@ void lv_mbox_set_text(lv_obj_t * mbox, const char * txt)
*/
void lv_mbox_set_anim_time(lv_obj_t * mbox, uint16_t anim_time)
{
LV_ASSERT_OBJ(mbox, LV_OBJX_NAME);
#if LV_USE_ANIMATION
lv_mbox_ext_t * ext = lv_obj_get_ext_attr(mbox);
anim_time = 0;
@ -204,6 +214,8 @@ void lv_mbox_set_anim_time(lv_obj_t * mbox, uint16_t anim_time)
*/
void lv_mbox_start_auto_close(lv_obj_t * mbox, uint16_t delay)
{
LV_ASSERT_OBJ(mbox, LV_OBJX_NAME);
#if LV_USE_ANIMATION
if(lv_mbox_get_anim_time(mbox) != 0) {
/*Add shrinking animations*/
@ -258,6 +270,8 @@ void lv_mbox_start_auto_close(lv_obj_t * mbox, uint16_t delay)
*/
void lv_mbox_stop_auto_close(lv_obj_t * mbox)
{
LV_ASSERT_OBJ(mbox, LV_OBJX_NAME);
#if LV_USE_ANIMATION
lv_anim_del(mbox, NULL);
#else
@ -273,6 +287,8 @@ void lv_mbox_stop_auto_close(lv_obj_t * mbox)
*/
void lv_mbox_set_style(lv_obj_t * mbox, lv_mbox_style_t type, const lv_style_t * style)
{
LV_ASSERT_OBJ(mbox, LV_OBJX_NAME);
lv_mbox_ext_t * ext = lv_obj_get_ext_attr(mbox);
switch(type) {
@ -295,6 +311,8 @@ void lv_mbox_set_style(lv_obj_t * mbox, lv_mbox_style_t type, const lv_style_t *
*/
void lv_mbox_set_recolor(lv_obj_t * mbox, bool en)
{
LV_ASSERT_OBJ(mbox, LV_OBJX_NAME);
lv_mbox_ext_t * ext = lv_obj_get_ext_attr(mbox);
if(ext->btnm) lv_btnm_set_recolor(ext->btnm, en);
@ -311,6 +329,8 @@ void lv_mbox_set_recolor(lv_obj_t * mbox, bool en)
*/
const char * lv_mbox_get_text(const lv_obj_t * mbox)
{
LV_ASSERT_OBJ(mbox, LV_OBJX_NAME);
lv_mbox_ext_t * ext = lv_obj_get_ext_attr(mbox);
return lv_label_get_text(ext->text);
@ -324,6 +344,8 @@ const char * lv_mbox_get_text(const lv_obj_t * mbox)
*/
uint16_t lv_mbox_get_active_btn(lv_obj_t * mbox)
{
LV_ASSERT_OBJ(mbox, LV_OBJX_NAME);
lv_mbox_ext_t * ext = lv_obj_get_ext_attr(mbox);
if(ext->btnm)
return lv_btnm_get_active_btn(ext->btnm);
@ -339,6 +361,8 @@ uint16_t lv_mbox_get_active_btn(lv_obj_t * mbox)
*/
const char * lv_mbox_get_active_btn_text(lv_obj_t * mbox)
{
LV_ASSERT_OBJ(mbox, LV_OBJX_NAME);
lv_mbox_ext_t * ext = lv_obj_get_ext_attr(mbox);
if(ext->btnm)
return lv_btnm_get_active_btn_text(ext->btnm);
@ -353,6 +377,8 @@ const char * lv_mbox_get_active_btn_text(lv_obj_t * mbox)
*/
uint16_t lv_mbox_get_anim_time(const lv_obj_t * mbox)
{
LV_ASSERT_OBJ(mbox, LV_OBJX_NAME);
#if LV_USE_ANIMATION
lv_mbox_ext_t * ext = lv_obj_get_ext_attr(mbox);
return ext->anim_time;
@ -370,6 +396,8 @@ uint16_t lv_mbox_get_anim_time(const lv_obj_t * mbox)
*/
const lv_style_t * lv_mbox_get_style(const lv_obj_t * mbox, lv_mbox_style_t type)
{
LV_ASSERT_OBJ(mbox, LV_OBJX_NAME);
const lv_style_t * style = NULL;
lv_mbox_ext_t * ext = lv_obj_get_ext_attr(mbox);
@ -394,6 +422,8 @@ const lv_style_t * lv_mbox_get_style(const lv_obj_t * mbox, lv_mbox_style_t type
*/
bool lv_mbox_get_recolor(const lv_obj_t * mbox)
{
LV_ASSERT_OBJ(mbox, LV_OBJX_NAME);
lv_mbox_ext_t * ext = lv_obj_get_ext_attr(mbox);
if(!ext->btnm) return false;
@ -409,6 +439,8 @@ bool lv_mbox_get_recolor(const lv_obj_t * mbox)
*/
lv_obj_t * lv_mbox_get_btnm(lv_obj_t * mbox)
{
LV_ASSERT_OBJ(mbox, LV_OBJX_NAME);
lv_mbox_ext_t * ext = lv_obj_get_ext_attr(mbox);
return ext->btnm;
}
@ -441,6 +473,7 @@ static lv_res_t lv_mbox_signal(lv_obj_t * mbox, lv_signal_t sign, void * param)
/* Include the ancient signal function */
res = ancestor_signal(mbox, sign, param);
if(res != LV_RES_OK) return res;
if(sign == LV_SIGNAL_GET_TYPE) return lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
lv_mbox_ext_t * ext = lv_obj_get_ext_attr(mbox);
if(sign == LV_SIGNAL_CORD_CHG) {
@ -476,13 +509,6 @@ static lv_res_t lv_mbox_signal(lv_obj_t * mbox, lv_signal_t sign, void * param)
}
#endif
}
} else if(sign == LV_SIGNAL_GET_TYPE) {
lv_obj_type_t * buf = param;
uint8_t i;
for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/
if(buf->type[i] == NULL) break;
}
buf->type[i] = "lv_mbox";
}
return res;

View File

@ -15,6 +15,7 @@
/*********************
* INCLUDES
*********************/
#include "../lv_core/lv_debug.h"
//#include "lv_templ.h" /*TODO uncomment this*/
#if defined(LV_USE_TEMPL) && LV_USE_TEMPL != 0
@ -22,6 +23,7 @@
/*********************
* DEFINES
*********************/
#define LV_OBJ_X_NAME "lv_templ"
/**********************
* TYPEDEFS
@ -118,6 +120,8 @@ lv_obj_t * lv_templ_create(lv_obj_t * par, const lv_obj_t * copy)
*/
void lv_templ_set_style(lv_obj_t * templ, lv_templ_style_t type, const lv_style_t * style)
{
LV_ASSERT_OBJ(templ, LV_OBJX_NAME);
lv_templ_ext_t * ext = lv_obj_get_ext_attr(templ);
switch(type) {
@ -142,6 +146,8 @@ void lv_templ_set_style(lv_obj_t * templ, lv_templ_style_t type, const lv_style_
*/
lv_style_t * lv_templ_get_style(const lv_obj_t * templ, lv_templ_style_t type)
{
LV_ASSERT_OBJ(templ, LV_OBJX_NAME);
lv_templ_ext_t * ext = lv_obj_get_ext_attr(templ);
lv_style_t * style = NULL;
@ -207,16 +213,10 @@ static lv_res_t lv_templ_signal(lv_obj_t * templ, lv_signal_t sign, void * param
/* Include the ancient signal function */
res = ancestor_signal(templ, sign, param);
if(res != LV_RES_OK) return res;
if(sign == LV_SIGNAL_GET_TYPE) return lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
if(sign == LV_SIGNAL_CLEANUP) {
/*Nothing to cleanup. (No dynamically allocated memory in 'ext')*/
} else if(sign == LV_SIGNAL_GET_TYPE) {
lv_obj_type_t * buf = param;
uint8_t i;
for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/
if(buf->type[i] == NULL) break;
}
buf->type[i] = "lv_templ";
}
return res;

View File

@ -9,6 +9,7 @@
#include "../lv_objx/lv_page.h"
#if LV_USE_PAGE != 0
#include "../lv_core/lv_debug.h"
#include "../lv_core/lv_group.h"
#include "../lv_draw/lv_draw.h"
#include "../lv_themes/lv_theme.h"
@ -19,6 +20,8 @@
/*********************
* DEFINES
*********************/
#define LV_OBJX_NAME "lv_page"
#define LV_PAGE_SB_MIN_SIZE (LV_DPI / 8)
/*[ms] Scroll anim time on `lv_page_scroll_up/down/left/rigth`*/
@ -77,7 +80,7 @@ lv_obj_t * lv_page_create(lv_obj_t * par, const lv_obj_t * copy)
/*Create the ancestor object*/
lv_obj_t * new_page = lv_cont_create(par, copy);
lv_mem_assert(new_page);
LV_ASSERT_MEM(new_page);
if(new_page == NULL) return NULL;
if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(new_page);
@ -85,7 +88,7 @@ lv_obj_t * lv_page_create(lv_obj_t * par, const lv_obj_t * copy)
/*Allocate the object type specific extended data*/
lv_page_ext_t * ext = lv_obj_allocate_ext_attr(new_page, sizeof(lv_page_ext_t));
lv_mem_assert(ext);
LV_ASSERT_MEM(ext);
if(ext == NULL) return NULL;
ext->scrl = NULL;
@ -171,11 +174,13 @@ lv_obj_t * lv_page_create(lv_obj_t * par, const lv_obj_t * copy)
/**
* Delete all children of the scrl object, without deleting scrl child.
* @param obj pointer to an object
* @param page pointer to an object
*/
void lv_page_clean(lv_obj_t * obj)
void lv_page_clean(lv_obj_t * page)
{
lv_obj_t * scrl = lv_page_get_scrl(obj);
LV_ASSERT_OBJ(page, LV_OBJX_NAME);
lv_obj_t * scrl = lv_page_get_scrl(page);
lv_obj_clean(scrl);
}
@ -190,6 +195,8 @@ void lv_page_clean(lv_obj_t * obj)
*/
void lv_page_set_sb_mode(lv_obj_t * page, lv_sb_mode_t sb_mode)
{
LV_ASSERT_OBJ(page, LV_OBJX_NAME);
lv_page_ext_t * ext = lv_obj_get_ext_attr(page);
if(ext->sb.mode == sb_mode) return;
@ -216,6 +223,8 @@ void lv_page_set_sb_mode(lv_obj_t * page, lv_sb_mode_t sb_mode)
*/
void lv_page_set_anim_time(lv_obj_t * page, uint16_t anim_time)
{
LV_ASSERT_OBJ(page, LV_OBJX_NAME);
#if LV_USE_ANIMATION
lv_page_ext_t * ext = lv_obj_get_ext_attr(page);
ext->anim_time = anim_time;
@ -233,6 +242,8 @@ void lv_page_set_anim_time(lv_obj_t * page, uint16_t anim_time)
*/
void lv_page_set_scroll_propagation(lv_obj_t * page, bool en)
{
LV_ASSERT_OBJ(page, LV_OBJX_NAME);
lv_page_ext_t * ext = lv_obj_get_ext_attr(page);
ext->scroll_prop = en ? 1 : 0;
}
@ -244,6 +255,8 @@ void lv_page_set_scroll_propagation(lv_obj_t * page, bool en)
*/
void lv_page_set_edge_flash(lv_obj_t * page, bool en)
{
LV_ASSERT_OBJ(page, LV_OBJX_NAME);
#if LV_USE_ANIMATION
lv_page_ext_t * ext = lv_obj_get_ext_attr(page);
ext->edge_flash.enabled = en ? 1 : 0;
@ -261,6 +274,8 @@ void lv_page_set_edge_flash(lv_obj_t * page, bool en)
* */
void lv_page_set_style(lv_obj_t * page, lv_page_style_t type, const lv_style_t * style)
{
LV_ASSERT_OBJ(page, LV_OBJX_NAME);
lv_page_ext_t * ext = lv_obj_get_ext_attr(page);
switch(type) {
@ -291,6 +306,8 @@ void lv_page_set_style(lv_obj_t * page, lv_page_style_t type, const lv_style_t *
*/
lv_obj_t * lv_page_get_scrl(const lv_obj_t * page)
{
LV_ASSERT_OBJ(page, LV_OBJX_NAME);
lv_page_ext_t * ext = lv_obj_get_ext_attr(page);
return ext->scrl;
@ -303,6 +320,8 @@ lv_obj_t * lv_page_get_scrl(const lv_obj_t * page)
*/
uint16_t lv_page_get_anim_time(const lv_obj_t * page)
{
LV_ASSERT_OBJ(page, LV_OBJX_NAME);
#if LV_USE_ANIMATION
lv_page_ext_t * ext = lv_obj_get_ext_attr(page);
return ext->anim_time;
@ -319,6 +338,8 @@ uint16_t lv_page_get_anim_time(const lv_obj_t * page)
*/
lv_sb_mode_t lv_page_get_sb_mode(const lv_obj_t * page)
{
LV_ASSERT_OBJ(page, LV_OBJX_NAME);
lv_page_ext_t * ext = lv_obj_get_ext_attr(page);
return ext->sb.mode;
}
@ -330,6 +351,8 @@ lv_sb_mode_t lv_page_get_sb_mode(const lv_obj_t * page)
*/
bool lv_page_get_scroll_propagation(lv_obj_t * page)
{
LV_ASSERT_OBJ(page, LV_OBJX_NAME);
lv_page_ext_t * ext = lv_obj_get_ext_attr(page);
return ext->scroll_prop == 0 ? false : true;
}
@ -341,6 +364,8 @@ bool lv_page_get_scroll_propagation(lv_obj_t * page)
*/
bool lv_page_get_edge_flash(lv_obj_t * page)
{
LV_ASSERT_OBJ(page, LV_OBJX_NAME);
#if LV_USE_ANIMATION
lv_page_ext_t * ext = lv_obj_get_ext_attr(page);
return ext->edge_flash.enabled == 0 ? false : true;
@ -357,6 +382,8 @@ bool lv_page_get_edge_flash(lv_obj_t * page)
*/
lv_coord_t lv_page_get_fit_width(lv_obj_t * page)
{
LV_ASSERT_OBJ(page, LV_OBJX_NAME);
const lv_style_t * bg_style = lv_page_get_style(page, LV_PAGE_STYLE_BG);
const lv_style_t * scrl_style = lv_page_get_style(page, LV_PAGE_STYLE_SCRL);
@ -371,6 +398,8 @@ lv_coord_t lv_page_get_fit_width(lv_obj_t * page)
*/
lv_coord_t lv_page_get_fit_height(lv_obj_t * page)
{
LV_ASSERT_OBJ(page, LV_OBJX_NAME);
const lv_style_t * bg_style = lv_page_get_style(page, LV_PAGE_STYLE_BG);
const lv_style_t * scrl_style = lv_page_get_style(page, LV_PAGE_STYLE_SCRL);
@ -386,6 +415,8 @@ lv_coord_t lv_page_get_fit_height(lv_obj_t * page)
* */
const lv_style_t * lv_page_get_style(const lv_obj_t * page, lv_page_style_t type)
{
LV_ASSERT_OBJ(page, LV_OBJX_NAME);
const lv_style_t * style = NULL;
lv_page_ext_t * ext = lv_obj_get_ext_attr(page);
@ -792,6 +823,7 @@ static lv_res_t lv_page_signal(lv_obj_t * page, lv_signal_t sign, void * param)
/* Include the ancient signal function */
res = ancestor_signal(page, sign, param);
if(res != LV_RES_OK) return res;
if(sign == LV_SIGNAL_GET_TYPE) return lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
lv_page_ext_t * ext = lv_obj_get_ext_attr(page);
lv_obj_t * child;
@ -869,13 +901,6 @@ static lv_res_t lv_page_signal(lv_obj_t * page, lv_signal_t sign, void * param)
} else if(sign == LV_SIGNAL_GET_EDITABLE) {
bool * editable = (bool *)param;
*editable = true;
} else if(sign == LV_SIGNAL_GET_TYPE) {
lv_obj_type_t * buf = param;
uint8_t i;
for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/
if(buf->type[i] == NULL) break;
}
buf->type[i] = "lv_page";
}
return res;
@ -895,6 +920,7 @@ static lv_res_t lv_page_scrollable_signal(lv_obj_t * scrl, lv_signal_t sign, voi
/* Include the ancient signal function */
res = ancestor_signal(scrl, sign, param);
if(res != LV_RES_OK) return res;
if(sign == LV_SIGNAL_GET_TYPE) return lv_obj_handle_get_type_signal(param, "");
lv_obj_t * page = lv_obj_get_parent(scrl);
const lv_style_t * page_style = lv_obj_get_style(page);

View File

@ -113,9 +113,9 @@ lv_obj_t * lv_page_create(lv_obj_t * par, const lv_obj_t * copy);
/**
* Delete all children of the scrl object, without deleting scrl child.
* @param obj pointer to an object
* @param page pointer to an object
*/
void lv_page_clean(lv_obj_t * obj);
void lv_page_clean(lv_obj_t * page);
/**
* Get the scrollable object of a page

View File

@ -9,6 +9,7 @@
#include "lv_preload.h"
#if LV_USE_PRELOAD != 0
#include "../lv_core/lv_debug.h"
#include "../lv_misc/lv_math.h"
#include "../lv_draw/lv_draw_rect.h"
#include "../lv_draw/lv_draw_arc.h"
@ -17,6 +18,8 @@
/*********************
* DEFINES
*********************/
#define LV_OBJX_NAME "lv_preloader"
#ifndef LV_PRELOAD_DEF_ARC_LENGTH
#define LV_PRELOAD_DEF_ARC_LENGTH 60 /*[deg]*/
#endif
@ -66,12 +69,12 @@ lv_obj_t * lv_preload_create(lv_obj_t * par, const lv_obj_t * copy)
/*Create the ancestor of pre loader*/
lv_obj_t * new_preload = lv_arc_create(par, copy);
lv_mem_assert(new_preload);
LV_ASSERT_MEM(new_preload);
if(new_preload == NULL) return NULL;
/*Allocate the pre loader type specific extended data*/
lv_preload_ext_t * ext = lv_obj_allocate_ext_attr(new_preload, sizeof(lv_preload_ext_t));
lv_mem_assert(ext);
LV_ASSERT_MEM(ext);
if(ext == NULL) return NULL;
if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(new_preload);
@ -129,6 +132,8 @@ lv_obj_t * lv_preload_create(lv_obj_t * par, const lv_obj_t * copy)
*/
void lv_preload_set_arc_length(lv_obj_t * preload, lv_anim_value_t deg)
{
LV_ASSERT_OBJ(preload, LV_OBJX_NAME);
lv_preload_ext_t * ext = lv_obj_get_ext_attr(preload);
ext->arc_length = deg;
@ -141,6 +146,8 @@ void lv_preload_set_arc_length(lv_obj_t * preload, lv_anim_value_t deg)
*/
void lv_preload_set_spin_time(lv_obj_t * preload, uint16_t time)
{
LV_ASSERT_OBJ(preload, LV_OBJX_NAME);
lv_preload_ext_t * ext = lv_obj_get_ext_attr(preload);
ext->time = time;
@ -158,6 +165,8 @@ void lv_preload_set_spin_time(lv_obj_t * preload, uint16_t time)
* */
void lv_preload_set_style(lv_obj_t * preload, lv_preload_style_t type, const lv_style_t * style)
{
LV_ASSERT_OBJ(preload, LV_OBJX_NAME);
switch(type) {
case LV_PRELOAD_STYLE_MAIN: lv_arc_set_style(preload, LV_ARC_STYLE_MAIN, style); break;
}
@ -170,6 +179,8 @@ void lv_preload_set_style(lv_obj_t * preload, lv_preload_style_t type, const lv_
* */
void lv_preload_set_type(lv_obj_t * preload, lv_preload_type_t type)
{
LV_ASSERT_OBJ(preload, LV_OBJX_NAME);
lv_preload_ext_t * ext = lv_obj_get_ext_attr(preload);
/*delete previous animation*/
@ -220,9 +231,10 @@ void lv_preload_set_type(lv_obj_t * preload, lv_preload_type_t type)
lv_anim_create(&b);
break;
}
case LV_PRELOAD_TYPE_CONSTANT_ARC:
case LV_PRELOAD_TYPE_SPINNING_ARC:
default: {
ext->anim_type = LV_PRELOAD_TYPE_SPINNING_ARC;
ext->anim_type = type;
lv_anim_t a;
a.var = preload;
if(ext->anim_dir == LV_PRELOAD_DIR_FORWARD) {
@ -234,7 +246,8 @@ void lv_preload_set_type(lv_obj_t * preload, lv_preload_type_t type)
a.end = 360;
}
a.exec_cb = (lv_anim_exec_xcb_t)lv_preload_spinner_anim;
a.path_cb = lv_anim_path_ease_in_out;
a.path_cb = (LV_PRELOAD_TYPE_CONSTANT_ARC == type ?
lv_anim_path_linear : lv_anim_path_ease_in_out);
a.ready_cb = NULL;
a.act_time = 0;
a.time = ext->time;
@ -250,6 +263,8 @@ void lv_preload_set_type(lv_obj_t * preload, lv_preload_type_t type)
void lv_preload_set_dir(lv_obj_t * preload, lv_preload_dir_t dir)
{
LV_ASSERT_OBJ(preload, LV_OBJX_NAME);
lv_preload_ext_t * ext = lv_obj_get_ext_attr(preload);
ext->anim_dir = dir;
@ -266,6 +281,8 @@ void lv_preload_set_dir(lv_obj_t * preload, lv_preload_dir_t dir)
*/
lv_anim_value_t lv_preload_get_arc_length(const lv_obj_t * preload)
{
LV_ASSERT_OBJ(preload, LV_OBJX_NAME);
lv_preload_ext_t * ext = lv_obj_get_ext_attr(preload);
return ext->arc_length;
}
@ -276,6 +293,8 @@ lv_anim_value_t lv_preload_get_arc_length(const lv_obj_t * preload)
*/
uint16_t lv_preload_get_spin_time(const lv_obj_t * preload)
{
LV_ASSERT_OBJ(preload, LV_OBJX_NAME);
lv_preload_ext_t * ext = lv_obj_get_ext_attr(preload);
return ext->time;
}
@ -288,6 +307,8 @@ uint16_t lv_preload_get_spin_time(const lv_obj_t * preload)
* */
const lv_style_t * lv_preload_get_style(const lv_obj_t * preload, lv_preload_style_t type)
{
LV_ASSERT_OBJ(preload, LV_OBJX_NAME);
const lv_style_t * style = NULL;
switch(type) {
@ -305,6 +326,8 @@ const lv_style_t * lv_preload_get_style(const lv_obj_t * preload, lv_preload_sty
* */
lv_preload_type_t lv_preload_get_type(lv_obj_t * preload)
{
LV_ASSERT_OBJ(preload, LV_OBJX_NAME);
lv_preload_ext_t * ext = lv_obj_get_ext_attr(preload);
return ext->anim_type;
}
@ -409,16 +432,10 @@ static lv_res_t lv_preload_signal(lv_obj_t * preload, lv_signal_t sign, void * p
/* Include the ancient signal function */
res = ancestor_signal(preload, sign, param);
if(res != LV_RES_OK) return res;
if(sign == LV_SIGNAL_GET_TYPE) return lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
if(sign == LV_SIGNAL_CLEANUP) {
/*Nothing to cleanup. (No dynamically allocated memory in 'ext')*/
} else if(sign == LV_SIGNAL_GET_TYPE) {
lv_obj_type_t * buf = param;
uint8_t i;
for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/
if(buf->type[i] == NULL) break;
}
buf->type[i] = "lv_preload";
}
return res;

View File

@ -48,6 +48,7 @@ extern "C" {
enum {
LV_PRELOAD_TYPE_SPINNING_ARC,
LV_PRELOAD_TYPE_FILLSPIN_ARC,
LV_PRELOAD_TYPE_CONSTANT_ARC,
};
typedef uint8_t lv_preload_type_t;
@ -67,7 +68,7 @@ typedef struct
/*New data for this type */
lv_anim_value_t arc_length; /*Length of the spinning indicator in degree*/
uint16_t time; /*Time of one round*/
lv_preload_type_t anim_type : 1; /*Type of the arc animation*/
lv_preload_type_t anim_type : 2; /*Type of the arc animation*/
lv_preload_dir_t anim_dir : 1; /*Animation Direction*/
} lv_preload_ext_t;

View File

@ -9,6 +9,7 @@
#include "lv_roller.h"
#if LV_USE_ROLLER != 0
#include "../lv_core/lv_debug.h"
#include "../lv_draw/lv_draw.h"
#include "../lv_core/lv_group.h"
#include "../lv_themes/lv_theme.h"
@ -16,6 +17,8 @@
/*********************
* DEFINES
*********************/
#define LV_OBJX_NAME "lv_roller"
#if LV_USE_ANIMATION == 0
#undef LV_ROLLER_DEF_ANIM_TIME
#define LV_ROLLER_DEF_ANIM_TIME 0 /*No animation*/
@ -65,7 +68,7 @@ lv_obj_t * lv_roller_create(lv_obj_t * par, const lv_obj_t * copy)
/*Create the ancestor of roller*/
lv_obj_t * new_roller = lv_ddlist_create(par, copy);
lv_mem_assert(new_roller);
LV_ASSERT_MEM(new_roller);
if(new_roller == NULL) return NULL;
if(ancestor_scrl_signal == NULL) ancestor_scrl_signal = lv_obj_get_signal_cb(lv_page_get_scrl(new_roller));
@ -73,7 +76,7 @@ lv_obj_t * lv_roller_create(lv_obj_t * par, const lv_obj_t * copy)
/*Allocate the roller type specific extended data*/
lv_roller_ext_t * ext = lv_obj_allocate_ext_attr(new_roller, sizeof(lv_roller_ext_t));
lv_mem_assert(ext);
LV_ASSERT_MEM(ext);
if(ext == NULL) return NULL;
ext->ddlist.draw_arrow = 0; /*Do not draw arrow by default*/
@ -134,6 +137,9 @@ lv_obj_t * lv_roller_create(lv_obj_t * par, const lv_obj_t * copy)
*/
void lv_roller_set_options(lv_obj_t * roller, const char * options, lv_roller_mode_t mode)
{
LV_ASSERT_OBJ(roller, LV_OBJX_NAME);
LV_ASSERT_STR(options);
lv_roller_ext_t * ext = lv_obj_get_ext_attr(roller);
if(mode == LV_ROLLER_MODE_NORMAL) {
@ -175,6 +181,8 @@ void lv_roller_set_options(lv_obj_t * roller, const char * options, lv_roller_mo
*/
void lv_roller_set_align(lv_obj_t * roller, lv_label_align_t align)
{
LV_ASSERT_OBJ(roller, LV_OBJX_NAME);
lv_roller_ext_t * ext = lv_obj_get_ext_attr(roller);
lv_obj_t * label = ext->ddlist.label;
@ -197,6 +205,8 @@ void lv_roller_set_align(lv_obj_t * roller, lv_label_align_t align)
*/
void lv_roller_set_selected(lv_obj_t * roller, uint16_t sel_opt, lv_anim_enable_t anim)
{
LV_ASSERT_OBJ(roller, LV_OBJX_NAME);
#if LV_USE_ANIMATION == 0
anim = LV_ANIM_OFF;
#endif
@ -214,6 +224,8 @@ void lv_roller_set_selected(lv_obj_t * roller, uint16_t sel_opt, lv_anim_enable_
*/
void lv_roller_set_visible_row_count(lv_obj_t * roller, uint8_t row_cnt)
{
LV_ASSERT_OBJ(roller, LV_OBJX_NAME);
lv_roller_ext_t * ext = lv_obj_get_ext_attr(roller);
const lv_style_t * style_label = lv_obj_get_style(ext->ddlist.label);
uint8_t n_line_space = (row_cnt > 1) ? row_cnt - 1 : 1;
@ -229,6 +241,8 @@ void lv_roller_set_visible_row_count(lv_obj_t * roller, uint8_t row_cnt)
*/
void lv_roller_set_style(lv_obj_t * roller, lv_roller_style_t type, const lv_style_t * style)
{
LV_ASSERT_OBJ(roller, LV_OBJX_NAME);
switch(type) {
case LV_ROLLER_STYLE_BG: lv_obj_set_style(roller, style); break;
case LV_ROLLER_STYLE_SEL: lv_ddlist_set_style(roller, LV_DDLIST_STYLE_SEL, style); break;
@ -246,6 +260,8 @@ void lv_roller_set_style(lv_obj_t * roller, lv_roller_style_t type, const lv_sty
*/
uint16_t lv_roller_get_selected(const lv_obj_t * roller)
{
LV_ASSERT_OBJ(roller, LV_OBJX_NAME);
lv_roller_ext_t * ext = lv_obj_get_ext_attr(roller);
if(ext->mode == LV_ROLLER_MODE_INIFINITE) {
uint16_t real_id_cnt = ext->ddlist.option_cnt / LV_ROLLER_INF_PAGES;
@ -262,9 +278,11 @@ uint16_t lv_roller_get_selected(const lv_obj_t * roller)
*/
lv_label_align_t lv_roller_get_align(const lv_obj_t * roller)
{
LV_ASSERT_OBJ(roller, LV_OBJX_NAME);
lv_roller_ext_t * ext = lv_obj_get_ext_attr(roller);
lv_mem_assert(ext);
lv_mem_assert(ext->ddlist.label);
LV_ASSERT_MEM(ext);
LV_ASSERT_MEM(ext->ddlist.label);
return lv_label_get_align(ext->ddlist.label);
}
@ -275,6 +293,8 @@ lv_label_align_t lv_roller_get_align(const lv_obj_t * roller)
*/
bool lv_roller_get_hor_fit(const lv_obj_t * roller)
{
LV_ASSERT_OBJ(roller, LV_OBJX_NAME);
return lv_page_get_scrl_fit_left(roller);
}
@ -286,6 +306,8 @@ bool lv_roller_get_hor_fit(const lv_obj_t * roller)
* */
const lv_style_t * lv_roller_get_style(const lv_obj_t * roller, lv_roller_style_t type)
{
LV_ASSERT_OBJ(roller, LV_OBJX_NAME);
switch(type) {
case LV_ROLLER_STYLE_BG: return lv_obj_get_style(roller);
case LV_ROLLER_STYLE_SEL: return lv_ddlist_get_style(roller, LV_DDLIST_STYLE_SEL);
@ -399,6 +421,7 @@ static lv_res_t lv_roller_signal(lv_obj_t * roller, lv_signal_t sign, void * par
res = ancestor_signal(roller, sign, param);
if(res != LV_RES_OK) return res;
}
if(sign == LV_SIGNAL_GET_TYPE) return lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
lv_roller_ext_t * ext = lv_obj_get_ext_attr(roller);
@ -465,13 +488,6 @@ static lv_res_t lv_roller_signal(lv_obj_t * roller, lv_signal_t sign, void * par
ext->ddlist.sel_opt_id_ori = ori_id;
}
}
} else if(sign == LV_SIGNAL_GET_TYPE) {
lv_obj_type_t * buf = param;
uint8_t i;
for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/
if(buf->type[i] == NULL) break;
}
buf->type[i] = "lv_roller";
}
return res;

View File

@ -10,6 +10,7 @@
#include "lv_slider.h"
#if LV_USE_SLIDER != 0
#include "../lv_core/lv_debug.h"
#include "../lv_core/lv_group.h"
#include "../lv_draw/lv_draw.h"
#include "../lv_themes/lv_theme.h"
@ -18,6 +19,8 @@
/*********************
* DEFINES
*********************/
#define LV_OBJX_NAME "lv_slider"
#define LV_SLIDER_SIZE_MIN 4 /*hor. pad and ver. pad cannot make the bar or indicator smaller then this [px]*/
#define LV_SLIDER_NOT_PRESSED INT16_MIN
@ -57,7 +60,7 @@ lv_obj_t * lv_slider_create(lv_obj_t * par, const lv_obj_t * copy)
/*Create the ancestor slider*/
lv_obj_t * new_slider = lv_bar_create(par, copy);
lv_mem_assert(new_slider);
LV_ASSERT_MEM(new_slider);
if(new_slider == NULL) return NULL;
if(ancestor_design_f == NULL) ancestor_design_f = lv_obj_get_design_cb(new_slider);
@ -65,7 +68,7 @@ lv_obj_t * lv_slider_create(lv_obj_t * par, const lv_obj_t * copy)
/*Allocate the slider type specific extended data*/
lv_slider_ext_t * ext = lv_obj_allocate_ext_attr(new_slider, sizeof(lv_slider_ext_t));
lv_mem_assert(ext);
LV_ASSERT_MEM(ext);
if(ext == NULL) return NULL;
/*Initialize the allocated 'ext' */
@ -118,6 +121,8 @@ lv_obj_t * lv_slider_create(lv_obj_t * par, const lv_obj_t * copy)
*/
void lv_slider_set_knob_in(lv_obj_t * slider, bool in)
{
LV_ASSERT_OBJ(slider, LV_OBJX_NAME);
lv_slider_ext_t * ext = lv_obj_get_ext_attr(slider);
if(ext->knob_in == in) return;
@ -133,6 +138,8 @@ void lv_slider_set_knob_in(lv_obj_t * slider, bool in)
*/
void lv_slider_set_style(lv_obj_t * slider, lv_slider_style_t type, const lv_style_t * style)
{
LV_ASSERT_OBJ(slider, LV_OBJX_NAME);
lv_slider_ext_t * ext = lv_obj_get_ext_attr(slider);
switch(type) {
@ -156,6 +163,8 @@ void lv_slider_set_style(lv_obj_t * slider, lv_slider_style_t type, const lv_sty
*/
int16_t lv_slider_get_value(const lv_obj_t * slider)
{
LV_ASSERT_OBJ(slider, LV_OBJX_NAME);
lv_slider_ext_t * ext = lv_obj_get_ext_attr(slider);
if(ext->drag_value != LV_SLIDER_NOT_PRESSED)
@ -171,6 +180,8 @@ int16_t lv_slider_get_value(const lv_obj_t * slider)
*/
bool lv_slider_is_dragged(const lv_obj_t * slider)
{
LV_ASSERT_OBJ(slider, LV_OBJX_NAME);
lv_slider_ext_t * ext = lv_obj_get_ext_attr(slider);
return ext->drag_value == LV_SLIDER_NOT_PRESSED ? false : true;
}
@ -183,6 +194,8 @@ bool lv_slider_is_dragged(const lv_obj_t * slider)
*/
bool lv_slider_get_knob_in(const lv_obj_t * slider)
{
LV_ASSERT_OBJ(slider, LV_OBJX_NAME);
lv_slider_ext_t * ext = lv_obj_get_ext_attr(slider);
return ext->knob_in == 0 ? false : true;
}
@ -195,6 +208,8 @@ bool lv_slider_get_knob_in(const lv_obj_t * slider)
*/
const lv_style_t * lv_slider_get_style(const lv_obj_t * slider, lv_slider_style_t type)
{
LV_ASSERT_OBJ(slider, LV_OBJX_NAME);
const lv_style_t * style = NULL;
lv_slider_ext_t * ext = lv_obj_get_ext_attr(slider);
@ -316,6 +331,8 @@ static bool lv_slider_design(lv_obj_t * slider, const lv_area_t * mask, lv_desig
/*If dragged draw to the drag position*/
if(ext->drag_value != LV_SLIDER_NOT_PRESSED) cur_value = ext->drag_value;
bool sym = false;
if(ext->bar.sym && ext->bar.min_value < 0 && ext->bar.max_value > 0) sym = true;
if(slider_w >= slider_h) {
lv_coord_t indic_w = lv_area_get_width(&area_indic);
@ -335,7 +352,19 @@ static bool lv_slider_design(lv_obj_t * slider, const lv_area_t * mask, lv_desig
{
area_indic.x2 = (int32_t)((int32_t)indic_w * (cur_value - min_value)) / (max_value - min_value);
}
area_indic.x2 = area_indic.x1 + area_indic.x2 - 1;
if(sym) {
/*Calculate the coordinate of the zero point*/
lv_coord_t zero;
zero = area_indic.x1 + (-ext->bar.min_value * slider_w) / (ext->bar.max_value - ext->bar.min_value);
if(area_indic.x2 > zero)
area_indic.x1 = zero;
else {
area_indic.x1 = area_indic.x2;
area_indic.x2 = zero;
}
}
/*Draw the indicator but don't draw an ugly 1px wide rectangle on the left on min.
* value*/
@ -359,8 +388,21 @@ static bool lv_slider_design(lv_obj_t * slider, const lv_area_t * mask, lv_desig
{
area_indic.y1 = (int32_t)((int32_t)indic_h * (cur_value - min_value)) / (max_value - min_value);
}
area_indic.y1 = area_indic.y2 - area_indic.y1 + 1;
if(sym) {
/*Calculate the coordinate of the zero point*/
lv_coord_t zero;
zero = area_indic.y2 - (-ext->bar.min_value * slider_h) / (ext->bar.max_value - ext->bar.min_value);
if(area_indic.y1 < zero)
area_indic.y2 = zero;
else {
area_indic.y2 = area_indic.y1;
area_indic.y1 = zero;
}
}
/*Draw the indicator but don't draw an ugly 1px height rectangle on the bottom on min.
* value*/
if(area_indic.x1 != area_indic.x2) lv_draw_rect(&area_indic, mask, style_indic, opa_scale);
@ -386,7 +428,12 @@ static bool lv_slider_design(lv_obj_t * slider, const lv_area_t * mask, lv_desig
if(slider_w >= slider_h) {
if(ext->knob_in == 0) {
knob_area.x1 = area_indic.x2 - slider_h / 2;
if(sym == false) {
knob_area.x1 = area_indic.x2 - slider_h / 2;
} else {
if(cur_value > 0) knob_area.x1 = area_indic.x2 - slider_h / 2;
else knob_area.x1 = area_indic.x1 - slider_h / 2;
}
knob_area.x2 = knob_area.x1 + slider_h - 1;
} else {
#if LV_USE_ANIMATION
@ -415,7 +462,12 @@ static bool lv_slider_design(lv_obj_t * slider, const lv_area_t * mask, lv_desig
knob_area.y2 = slider->coords.y2;
} else {
if(ext->knob_in == 0) {
knob_area.y1 = area_indic.y1 - slider_w / 2;
if(sym == false) {
knob_area.y1 = area_indic.y1 - slider_w / 2;
} else {
if(cur_value > 0) knob_area.y1 = area_indic.y1 - slider_w / 2;
else knob_area.y1 = area_indic.y2 - slider_w / 2;
}
knob_area.y2 = knob_area.y1 + slider_w - 1;
} else {
#if LV_USE_ANIMATION
@ -465,6 +517,7 @@ static lv_res_t lv_slider_signal(lv_obj_t * slider, lv_signal_t sign, void * par
/* Include the ancient signal function */
res = ancestor_signal(slider, sign, param);
if(res != LV_RES_OK) return res;
if(sign == LV_SIGNAL_GET_TYPE) return lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
lv_slider_ext_t * ext = lv_obj_get_ext_attr(slider);
lv_point_t p;
@ -559,13 +612,6 @@ static lv_res_t lv_slider_signal(lv_obj_t * slider, lv_signal_t sign, void * par
} else if(sign == LV_SIGNAL_GET_EDITABLE) {
bool * editable = (bool *)param;
*editable = true;
} else if(sign == LV_SIGNAL_GET_TYPE) {
lv_obj_type_t * buf = param;
uint8_t i;
for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/
if(buf->type[i] == NULL) break;
}
buf->type[i] = "lv_slider";
}
return res;

View File

@ -93,15 +93,26 @@ static inline void lv_slider_set_range(lv_obj_t * slider, int16_t min, int16_t m
}
/**
* Set the animation time of the slider
* @param slider pointer to a bar object
* @param anim_time the animation time in milliseconds.
* Make the slider symmetric to zero. The indicator will grow from zero instead of the minimum
* position.
* @param slider pointer to a slider object
* @param en true: enable disable symmetric behavior; false: disable
*/
static inline void lv_slider_set_anim_time(lv_obj_t * slider, uint16_t anim_time)
{
lv_bar_set_anim_time(slider, anim_time);
}
/**
* Set the animation time of the slider
* @param slider pointer to a bar object
* @param anim_time the animation time in milliseconds.
*/
static inline void lv_slider_set_sym(lv_obj_t * slider, bool en)
{
lv_bar_set_sym(slider, en);
}
/**
* Set the 'knob in' attribute of a slider
* @param slider pointer to slider object
@ -156,6 +167,26 @@ static inline int16_t lv_slider_get_max_value(const lv_obj_t * slider)
*/
bool lv_slider_is_dragged(const lv_obj_t * slider);
/**
* Get the animation time of the slider
* @param slider pointer to a slider object
* @return the animation time in milliseconds.
*/
static inline uint16_t lv_slider_get_anim_time(lv_obj_t * slider)
{
return lv_bar_get_anim_time(slider);
}
/**
* Get whether the slider is symmetric or not.
* @param slider pointer to a bar object
* @return true: symmetric is enabled; false: disable
*/
static inline bool lv_slider_get_sym(lv_obj_t * slider)
{
return lv_bar_get_sym(slider);
}
/**
* Get the 'knob in' attribute of a slider
* @param slider pointer to slider object

View File

@ -9,6 +9,7 @@
#include "lv_spinbox.h"
#if LV_USE_SPINBOX != 0
#include "../lv_core/lv_debug.h"
#include "../lv_themes/lv_theme.h"
#include "../lv_misc/lv_math.h"
#include "../lv_misc/lv_utils.h"
@ -16,6 +17,7 @@
/*********************
* DEFINES
*********************/
#define LV_OBJX_NAME "lv_spinbox"
/**********************
* TYPEDEFS
@ -53,12 +55,12 @@ lv_obj_t * lv_spinbox_create(lv_obj_t * par, const lv_obj_t * copy)
/*Create the ancestor of spinbox*/
lv_obj_t * new_spinbox = lv_ta_create(par, copy);
lv_mem_assert(new_spinbox);
LV_ASSERT_MEM(new_spinbox);
if(new_spinbox == NULL) return NULL;
/*Allocate the spinbox type specific extended data*/
lv_spinbox_ext_t * ext = lv_obj_allocate_ext_attr(new_spinbox, sizeof(lv_spinbox_ext_t));
lv_mem_assert(ext);
LV_ASSERT_MEM(ext);
if(ext == NULL) return NULL;
if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(new_spinbox);
if(ancestor_design == NULL) ancestor_design = lv_obj_get_design_cb(new_spinbox);
@ -121,6 +123,8 @@ lv_obj_t * lv_spinbox_create(lv_obj_t * par, const lv_obj_t * copy)
*/
void lv_spinbox_set_value(lv_obj_t * spinbox, int32_t i)
{
LV_ASSERT_OBJ(spinbox, LV_OBJX_NAME);
lv_spinbox_ext_t * ext = lv_obj_get_ext_attr(spinbox);
if(ext == NULL) return;
@ -141,6 +145,8 @@ void lv_spinbox_set_value(lv_obj_t * spinbox, int32_t i)
*/
void lv_spinbox_set_digit_format(lv_obj_t * spinbox, uint8_t digit_count, uint8_t separator_position)
{
LV_ASSERT_OBJ(spinbox, LV_OBJX_NAME);
lv_spinbox_ext_t * ext = lv_obj_get_ext_attr(spinbox);
if(ext == NULL) return;
@ -161,6 +167,8 @@ void lv_spinbox_set_digit_format(lv_obj_t * spinbox, uint8_t digit_count, uint8_
*/
void lv_spinbox_set_step(lv_obj_t * spinbox, uint32_t step)
{
LV_ASSERT_OBJ(spinbox, LV_OBJX_NAME);
lv_spinbox_ext_t * ext = lv_obj_get_ext_attr(spinbox);
if(ext == NULL) return;
@ -175,6 +183,8 @@ void lv_spinbox_set_step(lv_obj_t * spinbox, uint32_t step)
*/
void lv_spinbox_set_range(lv_obj_t * spinbox, int32_t range_min, int32_t range_max)
{
LV_ASSERT_OBJ(spinbox, LV_OBJX_NAME);
lv_spinbox_ext_t * ext = lv_obj_get_ext_attr(spinbox);
if(ext == NULL) return;
@ -198,6 +208,8 @@ void lv_spinbox_set_range(lv_obj_t * spinbox, int32_t range_min, int32_t range_m
*/
void lv_spinbox_set_padding_left(lv_obj_t * spinbox, uint8_t padding)
{
LV_ASSERT_OBJ(spinbox, LV_OBJX_NAME);
lv_spinbox_ext_t * ext = lv_obj_get_ext_attr(spinbox);
ext->digit_padding_left = padding;
lv_spinbox_updatevalue(spinbox);
@ -214,6 +226,8 @@ void lv_spinbox_set_padding_left(lv_obj_t * spinbox, uint8_t padding)
*/
int32_t lv_spinbox_get_value(lv_obj_t * spinbox)
{
LV_ASSERT_OBJ(spinbox, LV_OBJX_NAME);
lv_spinbox_ext_t * ext = lv_obj_get_ext_attr(spinbox);
return ext->value;
@ -229,6 +243,8 @@ int32_t lv_spinbox_get_value(lv_obj_t * spinbox)
*/
void lv_spinbox_step_next(lv_obj_t * spinbox)
{
LV_ASSERT_OBJ(spinbox, LV_OBJX_NAME);
lv_spinbox_ext_t * ext = lv_obj_get_ext_attr(spinbox);
int32_t new_step = ext->step / 10;
@ -246,6 +262,8 @@ void lv_spinbox_step_next(lv_obj_t * spinbox)
*/
void lv_spinbox_step_prev(lv_obj_t * spinbox)
{
LV_ASSERT_OBJ(spinbox, LV_OBJX_NAME);
lv_spinbox_ext_t * ext = lv_obj_get_ext_attr(spinbox);
int32_t step_limit;
step_limit = LV_MATH_MAX(ext->range_max, (ext->range_min < 0 ? (-ext->range_min) : ext->range_min));
@ -261,6 +279,8 @@ void lv_spinbox_step_prev(lv_obj_t * spinbox)
*/
void lv_spinbox_increment(lv_obj_t * spinbox)
{
LV_ASSERT_OBJ(spinbox, LV_OBJX_NAME);
lv_spinbox_ext_t * ext = lv_obj_get_ext_attr(spinbox);
if(ext->value + ext->step <= ext->range_max) {
@ -281,6 +301,8 @@ void lv_spinbox_increment(lv_obj_t * spinbox)
*/
void lv_spinbox_decrement(lv_obj_t * spinbox)
{
LV_ASSERT_OBJ(spinbox, LV_OBJX_NAME);
lv_spinbox_ext_t * ext = lv_obj_get_ext_attr(spinbox);
if(ext->value - ext->step >= ext->range_min) {
@ -317,6 +339,7 @@ static lv_res_t lv_spinbox_signal(lv_obj_t * spinbox, lv_signal_t sign, void * p
res = ancestor_signal(spinbox, sign, param);
if(res != LV_RES_OK) return res;
}
if(sign == LV_SIGNAL_GET_TYPE) return lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
if(sign == LV_SIGNAL_CLEANUP) {
/*Nothing to cleanup. (No dynamically allocated memory in 'ext')*/

View File

@ -15,12 +15,14 @@
#error "lv_sw: lv_slider is required. Enable it in lv_conf.h (LV_USE_SLIDER 1) "
#endif
#include "../lv_core/lv_debug.h"
#include "../lv_themes/lv_theme.h"
#include "../lv_misc/lv_math.h"
/*********************
* DEFINES
*********************/
#define LV_OBJX_NAME "lv_sw"
/**********************
* TYPEDEFS
@ -56,14 +58,14 @@ lv_obj_t * lv_sw_create(lv_obj_t * par, const lv_obj_t * copy)
/*Create the ancestor of switch*/
lv_obj_t * new_sw = lv_slider_create(par, copy);
lv_mem_assert(new_sw);
LV_ASSERT_MEM(new_sw);
if(new_sw == NULL) return NULL;
if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(new_sw);
/*Allocate the switch type specific extended data*/
lv_sw_ext_t * ext = lv_obj_allocate_ext_attr(new_sw, sizeof(lv_sw_ext_t));
lv_mem_assert(ext);
LV_ASSERT_MEM(ext);
if(ext == NULL) return NULL;
/*Initialize the allocated 'ext' */
@ -129,6 +131,8 @@ lv_obj_t * lv_sw_create(lv_obj_t * par, const lv_obj_t * copy)
*/
void lv_sw_on(lv_obj_t * sw, lv_anim_enable_t anim)
{
LV_ASSERT_OBJ(sw, LV_OBJX_NAME);
#if LV_USE_ANIMATION == 0
anim = LV_ANIM_OFF;
#endif
@ -144,6 +148,8 @@ void lv_sw_on(lv_obj_t * sw, lv_anim_enable_t anim)
*/
void lv_sw_off(lv_obj_t * sw, lv_anim_enable_t anim)
{
LV_ASSERT_OBJ(sw, LV_OBJX_NAME);
#if LV_USE_ANIMATION == 0
anim = LV_ANIM_OFF;
#endif
@ -160,6 +166,8 @@ void lv_sw_off(lv_obj_t * sw, lv_anim_enable_t anim)
*/
bool lv_sw_toggle(lv_obj_t * sw, lv_anim_enable_t anim)
{
LV_ASSERT_OBJ(sw, LV_OBJX_NAME);
#if LV_USE_ANIMATION == 0
anim = LV_ANIM_OFF;
#endif
@ -181,6 +189,8 @@ bool lv_sw_toggle(lv_obj_t * sw, lv_anim_enable_t anim)
*/
void lv_sw_set_style(lv_obj_t * sw, lv_sw_style_t type, const lv_style_t * style)
{
LV_ASSERT_OBJ(sw, LV_OBJX_NAME);
lv_sw_ext_t * ext = lv_obj_get_ext_attr(sw);
switch(type) {
@ -199,6 +209,8 @@ void lv_sw_set_style(lv_obj_t * sw, lv_sw_style_t type, const lv_style_t * style
void lv_sw_set_anim_time(lv_obj_t * sw, uint16_t anim_time)
{
LV_ASSERT_OBJ(sw, LV_OBJX_NAME);
#if LV_USE_ANIMATION
lv_sw_ext_t * ext = lv_obj_get_ext_attr(sw);
ext->anim_time = anim_time;
@ -220,6 +232,8 @@ void lv_sw_set_anim_time(lv_obj_t * sw, uint16_t anim_time)
*/
const lv_style_t * lv_sw_get_style(const lv_obj_t * sw, lv_sw_style_t type)
{
LV_ASSERT_OBJ(sw, LV_OBJX_NAME);
const lv_style_t * style = NULL;
lv_sw_ext_t * ext = lv_obj_get_ext_attr(sw);
@ -236,6 +250,7 @@ const lv_style_t * lv_sw_get_style(const lv_obj_t * sw, lv_sw_style_t type)
uint16_t lv_sw_get_anim_time(const lv_obj_t * sw)
{
LV_ASSERT_OBJ(sw, LV_OBJX_NAME);
#if LV_USE_ANIMATION
lv_sw_ext_t * ext = lv_obj_get_ext_attr(sw);
@ -278,6 +293,7 @@ static lv_res_t lv_sw_signal(lv_obj_t * sw, lv_signal_t sign, void * param)
res = ancestor_signal(sw, sign, param);
if(res != LV_RES_OK) return res;
if(sign == LV_SIGNAL_GET_TYPE) return lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
sw->event_cb = event_cb;
@ -374,13 +390,6 @@ static lv_res_t lv_sw_signal(lv_obj_t * sw, lv_signal_t sign, void * param)
} else if(sign == LV_SIGNAL_GET_EDITABLE) {
bool * editable = (bool *)param;
*editable = false; /*The ancestor slider is editable the switch is not*/
} else if(sign == LV_SIGNAL_GET_TYPE) {
lv_obj_type_t * buf = param;
uint8_t i;
for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/
if(buf->type[i] == NULL) break;
}
buf->type[i] = "lv_sw";
}
return res;

View File

@ -9,6 +9,7 @@
#include "lv_ta.h"
#if LV_USE_TA != 0
#include <string.h>
#include "../lv_core/lv_debug.h"
#include "../lv_core/lv_group.h"
#include "../lv_core/lv_refr.h"
#include "../lv_draw/lv_draw.h"
@ -20,8 +21,9 @@
/*********************
* DEFINES
*********************/
/*Test configuration*/
#define LV_OBJX_NAME "lv_ta"
/*Test configuration*/
#ifndef LV_TA_DEF_CURSOR_BLINK_TIME
#define LV_TA_DEF_CURSOR_BLINK_TIME 400 /*ms*/
#endif
@ -85,7 +87,7 @@ lv_obj_t * lv_ta_create(lv_obj_t * par, const lv_obj_t * copy)
/*Create the ancestor object*/
lv_obj_t * new_ta = lv_page_create(par, copy);
lv_mem_assert(new_ta);
LV_ASSERT_MEM(new_ta);
if(new_ta == NULL) return NULL;
if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(new_ta);
@ -95,7 +97,7 @@ lv_obj_t * lv_ta_create(lv_obj_t * par, const lv_obj_t * copy)
/*Allocate the object type specific extended data*/
lv_ta_ext_t * ext = lv_obj_allocate_ext_attr(new_ta, sizeof(lv_ta_ext_t));
lv_mem_assert(ext);
LV_ASSERT_MEM(ext);
if(ext == NULL) return NULL;
ext->cursor.state = 1;
@ -173,7 +175,7 @@ lv_obj_t * lv_ta_create(lv_obj_t * par, const lv_obj_t * copy)
if(copy_ext->pwd_tmp) {
uint16_t len = lv_mem_get_size(copy_ext->pwd_tmp);
ext->pwd_tmp = lv_mem_alloc(len);
lv_mem_assert(ext->pwd_tmp);
LV_ASSERT_MEM(ext->pwd_tmp);
if(ext->pwd_tmp == NULL) return NULL;
memcpy(ext->pwd_tmp, copy_ext->pwd_tmp, len);
@ -224,6 +226,8 @@ lv_obj_t * lv_ta_create(lv_obj_t * par, const lv_obj_t * copy)
*/
void lv_ta_add_char(lv_obj_t * ta, uint32_t c)
{
LV_ASSERT_OBJ(ta, LV_OBJX_NAME);
lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta);
uint32_t letter_buf[2];
@ -267,7 +271,7 @@ void lv_ta_add_char(lv_obj_t * ta, uint32_t c)
if(ext->pwd_mode != 0) {
ext->pwd_tmp = lv_mem_realloc(ext->pwd_tmp, strlen(ext->pwd_tmp) + 2); /*+2: the new char + \0 */
lv_mem_assert(ext->pwd_tmp);
LV_ASSERT_MEM(ext->pwd_tmp);
if(ext->pwd_tmp == NULL) return;
lv_txt_ins(ext->pwd_tmp, ext->cursor.pos, (const char *)letter_buf);
@ -312,6 +316,9 @@ void lv_ta_add_char(lv_obj_t * ta, uint32_t c)
*/
void lv_ta_add_text(lv_obj_t * ta, const char * txt)
{
LV_ASSERT_OBJ(ta, LV_OBJX_NAME);
LV_ASSERT_NULL(txt);
lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta);
ta_insert_replace = NULL;
@ -348,7 +355,7 @@ void lv_ta_add_text(lv_obj_t * ta, const char * txt)
if(ext->pwd_mode != 0) {
ext->pwd_tmp = lv_mem_realloc(ext->pwd_tmp, strlen(ext->pwd_tmp) + strlen(txt) + 1);
lv_mem_assert(ext->pwd_tmp);
LV_ASSERT_MEM(ext->pwd_tmp);
if(ext->pwd_tmp == NULL) return;
lv_txt_ins(ext->pwd_tmp, ext->cursor.pos, txt);
@ -391,6 +398,8 @@ void lv_ta_add_text(lv_obj_t * ta, const char * txt)
*/
void lv_ta_del_char(lv_obj_t * ta)
{
LV_ASSERT_OBJ(ta, LV_OBJX_NAME);
lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta);
uint16_t cur_pos = ext->cursor.pos;
@ -427,7 +436,7 @@ void lv_ta_del_char(lv_obj_t * ta)
lv_txt_cut(ext->pwd_tmp, ext->cursor.pos - 1, lv_txt_encoded_size(&label_txt[byte_pos]));
ext->pwd_tmp = lv_mem_realloc(ext->pwd_tmp, strlen(ext->pwd_tmp) + 1);
lv_mem_assert(ext->pwd_tmp);
LV_ASSERT_MEM(ext->pwd_tmp);
if(ext->pwd_tmp == NULL) return;
}
@ -445,6 +454,8 @@ void lv_ta_del_char(lv_obj_t * ta)
*/
void lv_ta_del_char_forward(lv_obj_t * ta)
{
LV_ASSERT_OBJ(ta, LV_OBJX_NAME);
uint16_t cp = lv_ta_get_cursor_pos(ta);
lv_ta_set_cursor_pos(ta, cp + 1);
if(cp != lv_ta_get_cursor_pos(ta)) lv_ta_del_char(ta);
@ -461,6 +472,9 @@ void lv_ta_del_char_forward(lv_obj_t * ta)
*/
void lv_ta_set_text(lv_obj_t * ta, const char * txt)
{
LV_ASSERT_OBJ(ta, LV_OBJX_NAME);
LV_ASSERT_NULL(txt);
lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta);
/*Clear the existing selection*/
@ -489,7 +503,7 @@ void lv_ta_set_text(lv_obj_t * ta, const char * txt)
if(ext->pwd_mode != 0) {
ext->pwd_tmp = lv_mem_realloc(ext->pwd_tmp, strlen(txt) + 1);
lv_mem_assert(ext->pwd_tmp);
LV_ASSERT_MEM(ext->pwd_tmp);
if(ext->pwd_tmp == NULL) return;
strcpy(ext->pwd_tmp, txt);
@ -526,6 +540,9 @@ void lv_ta_set_text(lv_obj_t * ta, const char * txt)
*/
void lv_ta_set_placeholder_text(lv_obj_t * ta, const char * txt)
{
LV_ASSERT_OBJ(ta, LV_OBJX_NAME);
LV_ASSERT_NULL(txt);
lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta);
/*Create the placeholder label only when it is needed*/
@ -553,6 +570,8 @@ void lv_ta_set_placeholder_text(lv_obj_t * ta, const char * txt)
*/
void lv_ta_set_cursor_pos(lv_obj_t * ta, int16_t pos)
{
LV_ASSERT_OBJ(ta, LV_OBJX_NAME);
lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta);
if(ext->cursor.pos == pos) return;
@ -629,6 +648,8 @@ void lv_ta_set_cursor_pos(lv_obj_t * ta, int16_t pos)
*/
void lv_ta_set_cursor_type(lv_obj_t * ta, lv_cursor_type_t cur_type)
{
LV_ASSERT_OBJ(ta, LV_OBJX_NAME);
lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta);
if(ext->cursor.type == cur_type) return;
@ -644,6 +665,8 @@ void lv_ta_set_cursor_type(lv_obj_t * ta, lv_cursor_type_t cur_type)
*/
void lv_ta_set_cursor_click_pos(lv_obj_t * ta, bool en)
{
LV_ASSERT_OBJ(ta, LV_OBJX_NAME);
lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta);
ext->cursor.click_pos = en ? 1 : 0;
}
@ -655,6 +678,8 @@ void lv_ta_set_cursor_click_pos(lv_obj_t * ta, bool en)
*/
void lv_ta_set_pwd_mode(lv_obj_t * ta, bool en)
{
LV_ASSERT_OBJ(ta, LV_OBJX_NAME);
lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta);
if(ext->pwd_mode == en) return;
@ -663,7 +688,7 @@ void lv_ta_set_pwd_mode(lv_obj_t * ta, bool en)
char * txt = lv_label_get_text(ext->label);
uint16_t len = strlen(txt);
ext->pwd_tmp = lv_mem_alloc(len + 1);
lv_mem_assert(ext->pwd_tmp);
LV_ASSERT_MEM(ext->pwd_tmp);
if(ext->pwd_tmp == NULL) return;
strcpy(ext->pwd_tmp, txt);
@ -699,6 +724,8 @@ void lv_ta_set_pwd_mode(lv_obj_t * ta, bool en)
*/
void lv_ta_set_one_line(lv_obj_t * ta, bool en)
{
LV_ASSERT_OBJ(ta, LV_OBJX_NAME);
lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta);
if(ext->one_line == en) return;
@ -740,6 +767,8 @@ void lv_ta_set_one_line(lv_obj_t * ta, bool en)
*/
void lv_ta_set_text_align(lv_obj_t * ta, lv_label_align_t align)
{
LV_ASSERT_OBJ(ta, LV_OBJX_NAME);
lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta);
lv_obj_t * label = lv_ta_get_label(ta);
if(!ext->one_line) {
@ -772,6 +801,8 @@ void lv_ta_set_text_align(lv_obj_t * ta, lv_label_align_t align)
*/
void lv_ta_set_accepted_chars(lv_obj_t * ta, const char * list)
{
LV_ASSERT_OBJ(ta, LV_OBJX_NAME);
lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta);
ext->accapted_chars = list;
@ -784,6 +815,8 @@ void lv_ta_set_accepted_chars(lv_obj_t * ta, const char * list)
*/
void lv_ta_set_max_length(lv_obj_t * ta, uint16_t num)
{
LV_ASSERT_OBJ(ta, LV_OBJX_NAME);
lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta);
ext->max_length = num;
@ -799,6 +832,8 @@ void lv_ta_set_max_length(lv_obj_t * ta, uint16_t num)
*/
void lv_ta_set_insert_replace(lv_obj_t * ta, const char * txt)
{
LV_ASSERT_OBJ(ta, LV_OBJX_NAME);
(void)ta; /*Unused*/
ta_insert_replace = txt;
}
@ -811,6 +846,8 @@ void lv_ta_set_insert_replace(lv_obj_t * ta, const char * txt)
*/
void lv_ta_set_style(lv_obj_t * ta, lv_ta_style_t type, const lv_style_t * style)
{
LV_ASSERT_OBJ(ta, LV_OBJX_NAME);
lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta);
switch(type) {
@ -835,6 +872,8 @@ void lv_ta_set_style(lv_obj_t * ta, lv_ta_style_t type, const lv_style_t * style
*/
void lv_ta_set_text_sel(lv_obj_t * ta, bool en)
{
LV_ASSERT_OBJ(ta, LV_OBJX_NAME);
#if LV_LABEL_TEXT_SEL
lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta);
@ -854,6 +893,8 @@ void lv_ta_set_text_sel(lv_obj_t * ta, bool en)
*/
void lv_ta_set_pwd_show_time(lv_obj_t * ta, uint16_t time)
{
LV_ASSERT_OBJ(ta, LV_OBJX_NAME);
#if LV_USE_ANIMATION == 0
time = 0;
#endif
@ -869,6 +910,8 @@ void lv_ta_set_pwd_show_time(lv_obj_t * ta, uint16_t time)
*/
void lv_ta_set_cursor_blink_time(lv_obj_t * ta, uint16_t time)
{
LV_ASSERT_OBJ(ta, LV_OBJX_NAME);
#if LV_USE_ANIMATION == 0
time = 0;
#endif
@ -912,6 +955,8 @@ void lv_ta_set_cursor_blink_time(lv_obj_t * ta, uint16_t time)
*/
const char * lv_ta_get_text(const lv_obj_t * ta)
{
LV_ASSERT_OBJ(ta, LV_OBJX_NAME);
lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta);
const char * txt;
@ -931,6 +976,8 @@ const char * lv_ta_get_text(const lv_obj_t * ta)
*/
const char * lv_ta_get_placeholder_text(lv_obj_t * ta)
{
LV_ASSERT_OBJ(ta, LV_OBJX_NAME);
lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta);
const char * txt = NULL;
@ -947,6 +994,8 @@ const char * lv_ta_get_placeholder_text(lv_obj_t * ta)
*/
lv_obj_t * lv_ta_get_label(const lv_obj_t * ta)
{
LV_ASSERT_OBJ(ta, LV_OBJX_NAME);
lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta);
return ext->label;
}
@ -958,6 +1007,8 @@ lv_obj_t * lv_ta_get_label(const lv_obj_t * ta)
*/
uint16_t lv_ta_get_cursor_pos(const lv_obj_t * ta)
{
LV_ASSERT_OBJ(ta, LV_OBJX_NAME);
lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta);
return ext->cursor.pos;
}
@ -969,6 +1020,8 @@ uint16_t lv_ta_get_cursor_pos(const lv_obj_t * ta)
*/
lv_cursor_type_t lv_ta_get_cursor_type(const lv_obj_t * ta)
{
LV_ASSERT_OBJ(ta, LV_OBJX_NAME);
lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta);
return ext->cursor.type;
}
@ -980,6 +1033,8 @@ lv_cursor_type_t lv_ta_get_cursor_type(const lv_obj_t * ta)
*/
bool lv_ta_get_cursor_click_pos(lv_obj_t * ta)
{
LV_ASSERT_OBJ(ta, LV_OBJX_NAME);
lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta);
return ext->cursor.click_pos ? true : false;
}
@ -991,6 +1046,8 @@ bool lv_ta_get_cursor_click_pos(lv_obj_t * ta)
*/
bool lv_ta_get_pwd_mode(const lv_obj_t * ta)
{
LV_ASSERT_OBJ(ta, LV_OBJX_NAME);
lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta);
return ext->pwd_mode == 0 ? false : true;
}
@ -1002,6 +1059,8 @@ bool lv_ta_get_pwd_mode(const lv_obj_t * ta)
*/
bool lv_ta_get_one_line(const lv_obj_t * ta)
{
LV_ASSERT_OBJ(ta, LV_OBJX_NAME);
lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta);
return ext->one_line == 0 ? false : true;
}
@ -1013,6 +1072,8 @@ bool lv_ta_get_one_line(const lv_obj_t * ta)
*/
const char * lv_ta_get_accepted_chars(lv_obj_t * ta)
{
LV_ASSERT_OBJ(ta, LV_OBJX_NAME);
lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta);
return ext->accapted_chars;
@ -1025,6 +1086,8 @@ const char * lv_ta_get_accepted_chars(lv_obj_t * ta)
*/
uint16_t lv_ta_get_max_length(lv_obj_t * ta)
{
LV_ASSERT_OBJ(ta, LV_OBJX_NAME);
lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta);
return ext->max_length;
}
@ -1037,6 +1100,8 @@ uint16_t lv_ta_get_max_length(lv_obj_t * ta)
*/
const lv_style_t * lv_ta_get_style(const lv_obj_t * ta, lv_ta_style_t type)
{
LV_ASSERT_OBJ(ta, LV_OBJX_NAME);
const lv_style_t * style = NULL;
lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta);
@ -1061,6 +1126,8 @@ const lv_style_t * lv_ta_get_style(const lv_obj_t * ta, lv_ta_style_t type)
*/
bool lv_ta_text_is_selected(const lv_obj_t * ta)
{
LV_ASSERT_OBJ(ta, LV_OBJX_NAME);
#if LV_LABEL_TEXT_SEL
lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta);
@ -1083,6 +1150,8 @@ bool lv_ta_text_is_selected(const lv_obj_t * ta)
*/
bool lv_ta_get_text_sel_en(lv_obj_t * ta)
{
LV_ASSERT_OBJ(ta, LV_OBJX_NAME);
#if LV_LABEL_TEXT_SEL
lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta);
return ext->text_sel_en;
@ -1099,6 +1168,8 @@ bool lv_ta_get_text_sel_en(lv_obj_t * ta)
*/
uint16_t lv_ta_get_pwd_show_time(lv_obj_t * ta)
{
LV_ASSERT_OBJ(ta, LV_OBJX_NAME);
lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta);
return ext->pwd_show_time;
@ -1111,6 +1182,8 @@ uint16_t lv_ta_get_pwd_show_time(lv_obj_t * ta)
*/
uint16_t lv_ta_get_cursor_blink_time(lv_obj_t * ta)
{
LV_ASSERT_OBJ(ta, LV_OBJX_NAME);
lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta);
return ext->cursor.blink_time;
}
@ -1125,6 +1198,8 @@ uint16_t lv_ta_get_cursor_blink_time(lv_obj_t * ta)
*/
void lv_ta_clear_selection(lv_obj_t * ta)
{
LV_ASSERT_OBJ(ta, LV_OBJX_NAME);
#if LV_LABEL_TEXT_SEL
lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta);
@ -1144,6 +1219,8 @@ void lv_ta_clear_selection(lv_obj_t * ta)
*/
void lv_ta_cursor_right(lv_obj_t * ta)
{
LV_ASSERT_OBJ(ta, LV_OBJX_NAME);
uint16_t cp = lv_ta_get_cursor_pos(ta);
cp++;
lv_ta_set_cursor_pos(ta, cp);
@ -1155,6 +1232,8 @@ void lv_ta_cursor_right(lv_obj_t * ta)
*/
void lv_ta_cursor_left(lv_obj_t * ta)
{
LV_ASSERT_OBJ(ta, LV_OBJX_NAME);
uint16_t cp = lv_ta_get_cursor_pos(ta);
if(cp > 0) {
cp--;
@ -1168,6 +1247,8 @@ void lv_ta_cursor_left(lv_obj_t * ta)
*/
void lv_ta_cursor_down(lv_obj_t * ta)
{
LV_ASSERT_OBJ(ta, LV_OBJX_NAME);
lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta);
lv_point_t pos;
@ -1198,6 +1279,8 @@ void lv_ta_cursor_down(lv_obj_t * ta)
*/
void lv_ta_cursor_up(lv_obj_t * ta)
{
LV_ASSERT_OBJ(ta, LV_OBJX_NAME);
lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta);
lv_point_t pos;
@ -1331,6 +1414,7 @@ static lv_res_t lv_ta_signal(lv_obj_t * ta, lv_signal_t sign, void * param)
/* Include the ancient signal function */
res = ancestor_signal(ta, sign, param);
if(res != LV_RES_OK) return res;
if(sign == LV_SIGNAL_GET_TYPE) return lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta);
if(sign == LV_SIGNAL_CLEANUP) {
@ -1411,13 +1495,6 @@ static lv_res_t lv_ta_signal(lv_obj_t * ta, lv_signal_t sign, void * param)
} else if(sign == LV_SIGNAL_GET_EDITABLE) {
bool * editable = (bool *)param;
*editable = true;
} else if(sign == LV_SIGNAL_GET_TYPE) {
lv_obj_type_t * buf = param;
uint8_t i;
for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/
if(buf->type[i] == NULL) break;
}
buf->type[i] = "lv_ta";
} else if(sign == LV_SIGNAL_DEFOCUS) {
lv_cursor_type_t cur_type;
cur_type = lv_ta_get_cursor_type(ta);
@ -1461,6 +1538,7 @@ static lv_res_t lv_ta_scrollable_signal(lv_obj_t * scrl, lv_signal_t sign, void
/* Include the ancient signal function */
res = scrl_signal(scrl, sign, param);
if(res != LV_RES_OK) return res;
if(sign == LV_SIGNAL_GET_TYPE) return lv_obj_handle_get_type_signal(param, "");
lv_obj_t * ta = lv_obj_get_parent(scrl);
lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta);

View File

@ -39,6 +39,8 @@ extern "C" {
*********************/
#define LV_TA_CURSOR_LAST (0x7FFF) /*Put the cursor after the last character*/
LV_EXPORT_CONST_INT(LV_TA_CURSOR_LAST);
/**********************
* TYPEDEFS
**********************/

View File

@ -9,6 +9,7 @@
#include "lv_table.h"
#if LV_USE_TABLE != 0
#include "../lv_core/lv_debug.h"
#include "../lv_misc/lv_txt.h"
#include "../lv_misc/lv_math.h"
#include "../lv_draw/lv_draw_label.h"
@ -17,6 +18,7 @@
/*********************
* DEFINES
*********************/
#define LV_OBJX_NAME "lv_table"
/**********************
* TYPEDEFS
@ -56,12 +58,12 @@ lv_obj_t * lv_table_create(lv_obj_t * par, const lv_obj_t * copy)
/*Create the ancestor of table*/
lv_obj_t * new_table = lv_obj_create(par, copy);
lv_mem_assert(new_table);
LV_ASSERT_MEM(new_table);
if(new_table == NULL) return NULL;
/*Allocate the table type specific extended data*/
lv_table_ext_t * ext = lv_obj_allocate_ext_attr(new_table, sizeof(lv_table_ext_t));
lv_mem_assert(ext);
LV_ASSERT_MEM(ext);
if(ext == NULL) return NULL;
if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(new_table);
if(ancestor_scrl_design == NULL) ancestor_scrl_design = lv_obj_get_design_cb(new_table);
@ -132,6 +134,9 @@ lv_obj_t * lv_table_create(lv_obj_t * par, const lv_obj_t * copy)
*/
void lv_table_set_cell_value(lv_obj_t * table, uint16_t row, uint16_t col, const char * txt)
{
LV_ASSERT_OBJ(table, LV_OBJX_NAME);
LV_ASSERT_NULL(txt);
lv_table_ext_t * ext = lv_obj_get_ext_attr(table);
if(row >= ext->row_cnt || col >= ext->col_cnt) {
LV_LOG_WARN("lv_table_set_cell_value: invalid row or column");
@ -165,6 +170,8 @@ void lv_table_set_cell_value(lv_obj_t * table, uint16_t row, uint16_t col, const
*/
void lv_table_set_row_cnt(lv_obj_t * table, uint16_t row_cnt)
{
LV_ASSERT_OBJ(table, LV_OBJX_NAME);
lv_table_ext_t * ext = lv_obj_get_ext_attr(table);
uint16_t old_row_cnt = ext->row_cnt;
ext->row_cnt = row_cnt;
@ -193,6 +200,7 @@ void lv_table_set_row_cnt(lv_obj_t * table, uint16_t row_cnt)
*/
void lv_table_set_col_cnt(lv_obj_t * table, uint16_t col_cnt)
{
LV_ASSERT_OBJ(table, LV_OBJX_NAME);
if(col_cnt >= LV_TABLE_COL_MAX) {
LV_LOG_WARN("lv_table_set_col_cnt: too many columns. Must be < LV_TABLE_COL_MAX.");
@ -227,6 +235,8 @@ void lv_table_set_col_cnt(lv_obj_t * table, uint16_t col_cnt)
*/
void lv_table_set_col_width(lv_obj_t * table, uint16_t col_id, lv_coord_t w)
{
LV_ASSERT_OBJ(table, LV_OBJX_NAME);
if(col_id >= LV_TABLE_COL_MAX) {
LV_LOG_WARN("lv_table_set_col_width: too big 'col_id'. Must be < LV_TABLE_COL_MAX.");
return;
@ -246,6 +256,8 @@ void lv_table_set_col_width(lv_obj_t * table, uint16_t col_id, lv_coord_t w)
*/
void lv_table_set_cell_align(lv_obj_t * table, uint16_t row, uint16_t col, lv_label_align_t align)
{
LV_ASSERT_OBJ(table, LV_OBJX_NAME);
lv_table_ext_t * ext = lv_obj_get_ext_attr(table);
if(row >= ext->row_cnt || col >= ext->col_cnt) {
LV_LOG_WARN("lv_table_set_cell_align: invalid row or column");
@ -274,6 +286,8 @@ void lv_table_set_cell_align(lv_obj_t * table, uint16_t row, uint16_t col, lv_la
*/
void lv_table_set_cell_type(lv_obj_t * table, uint16_t row, uint16_t col, uint8_t type)
{
LV_ASSERT_OBJ(table, LV_OBJX_NAME);
lv_table_ext_t * ext = lv_obj_get_ext_attr(table);
if(row >= ext->row_cnt || col >= ext->col_cnt) {
LV_LOG_WARN("lv_table_set_cell_type: invalid row or column");
@ -305,6 +319,8 @@ void lv_table_set_cell_type(lv_obj_t * table, uint16_t row, uint16_t col, uint8_
*/
void lv_table_set_cell_crop(lv_obj_t * table, uint16_t row, uint16_t col, bool crop)
{
LV_ASSERT_OBJ(table, LV_OBJX_NAME);
lv_table_ext_t * ext = lv_obj_get_ext_attr(table);
if(row >= ext->row_cnt || col >= ext->col_cnt) {
LV_LOG_WARN("lv_table_set_cell_crop: invalid row or column");
@ -333,6 +349,8 @@ void lv_table_set_cell_crop(lv_obj_t * table, uint16_t row, uint16_t col, bool c
*/
void lv_table_set_cell_merge_right(lv_obj_t * table, uint16_t row, uint16_t col, bool en)
{
LV_ASSERT_OBJ(table, LV_OBJX_NAME);
lv_table_ext_t * ext = lv_obj_get_ext_attr(table);
if(row >= ext->row_cnt || col >= ext->col_cnt) {
LV_LOG_WARN("lv_table_set_cell_merge_right: invalid row or column");
@ -362,6 +380,8 @@ void lv_table_set_cell_merge_right(lv_obj_t * table, uint16_t row, uint16_t col,
*/
void lv_table_set_style(lv_obj_t * table, lv_table_style_t type, const lv_style_t * style)
{
LV_ASSERT_OBJ(table, LV_OBJX_NAME);
lv_table_ext_t * ext = lv_obj_get_ext_attr(table);
switch(type) {
@ -401,6 +421,8 @@ void lv_table_set_style(lv_obj_t * table, lv_table_style_t type, const lv_style_
*/
const char * lv_table_get_cell_value(lv_obj_t * table, uint16_t row, uint16_t col)
{
LV_ASSERT_OBJ(table, LV_OBJX_NAME);
lv_table_ext_t * ext = lv_obj_get_ext_attr(table);
if(row >= ext->row_cnt || col >= ext->col_cnt) {
LV_LOG_WARN("lv_table_set_cell_value: invalid row or column");
@ -420,6 +442,8 @@ const char * lv_table_get_cell_value(lv_obj_t * table, uint16_t row, uint16_t co
*/
uint16_t lv_table_get_row_cnt(lv_obj_t * table)
{
LV_ASSERT_OBJ(table, LV_OBJX_NAME);
lv_table_ext_t * ext = lv_obj_get_ext_attr(table);
return ext->row_cnt;
}
@ -431,6 +455,8 @@ uint16_t lv_table_get_row_cnt(lv_obj_t * table)
*/
uint16_t lv_table_get_col_cnt(lv_obj_t * table)
{
LV_ASSERT_OBJ(table, LV_OBJX_NAME);
lv_table_ext_t * ext = lv_obj_get_ext_attr(table);
return ext->col_cnt;
}
@ -443,6 +469,8 @@ uint16_t lv_table_get_col_cnt(lv_obj_t * table)
*/
lv_coord_t lv_table_get_col_width(lv_obj_t * table, uint16_t col_id)
{
LV_ASSERT_OBJ(table, LV_OBJX_NAME);
if(col_id >= LV_TABLE_COL_MAX) {
LV_LOG_WARN("lv_table_set_col_width: too big 'col_id'. Must be < LV_TABLE_COL_MAX.");
return 0;
@ -462,6 +490,8 @@ lv_coord_t lv_table_get_col_width(lv_obj_t * table, uint16_t col_id)
*/
lv_label_align_t lv_table_get_cell_align(lv_obj_t * table, uint16_t row, uint16_t col)
{
LV_ASSERT_OBJ(table, LV_OBJX_NAME);
lv_table_ext_t * ext = lv_obj_get_ext_attr(table);
if(row >= ext->row_cnt || col >= ext->col_cnt) {
LV_LOG_WARN("lv_table_set_cell_align: invalid row or column");
@ -487,6 +517,8 @@ lv_label_align_t lv_table_get_cell_align(lv_obj_t * table, uint16_t row, uint16_
*/
lv_label_align_t lv_table_get_cell_type(lv_obj_t * table, uint16_t row, uint16_t col)
{
LV_ASSERT_OBJ(table, LV_OBJX_NAME);
lv_table_ext_t * ext = lv_obj_get_ext_attr(table);
if(row >= ext->row_cnt || col >= ext->col_cnt) {
LV_LOG_WARN("lv_table_get_cell_type: invalid row or column");
@ -512,6 +544,8 @@ lv_label_align_t lv_table_get_cell_type(lv_obj_t * table, uint16_t row, uint16_t
*/
lv_label_align_t lv_table_get_cell_crop(lv_obj_t * table, uint16_t row, uint16_t col)
{
LV_ASSERT_OBJ(table, LV_OBJX_NAME);
lv_table_ext_t * ext = lv_obj_get_ext_attr(table);
if(row >= ext->row_cnt || col >= ext->col_cnt) {
LV_LOG_WARN("lv_table_get_cell_crop: invalid row or column");
@ -537,6 +571,8 @@ lv_label_align_t lv_table_get_cell_crop(lv_obj_t * table, uint16_t row, uint16_t
*/
bool lv_table_get_cell_merge_right(lv_obj_t * table, uint16_t row, uint16_t col)
{
LV_ASSERT_OBJ(table, LV_OBJX_NAME);
lv_table_ext_t * ext = lv_obj_get_ext_attr(table);
if(row >= ext->row_cnt || col >= ext->col_cnt) {
LV_LOG_WARN("lv_table_get_cell_merge_right: invalid row or column");
@ -562,6 +598,8 @@ bool lv_table_get_cell_merge_right(lv_obj_t * table, uint16_t row, uint16_t col)
*/
const lv_style_t * lv_table_get_style(const lv_obj_t * table, lv_table_style_t type)
{
LV_ASSERT_OBJ(table, LV_OBJX_NAME);
lv_table_ext_t * ext = lv_obj_get_ext_attr(table);
const lv_style_t * style = NULL;
@ -741,6 +779,7 @@ static lv_res_t lv_table_signal(lv_obj_t * table, lv_signal_t sign, void * param
/* Include the ancient signal function */
res = ancestor_signal(table, sign, param);
if(res != LV_RES_OK) return res;
if(sign == LV_SIGNAL_GET_TYPE) return lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
if(sign == LV_SIGNAL_CLEANUP) {
/*Free the cell texts*/
@ -754,13 +793,6 @@ static lv_res_t lv_table_signal(lv_obj_t * table, lv_signal_t sign, void * param
}
if(ext->cell_data != NULL)
lv_mem_free(ext->cell_data);
} else if(sign == LV_SIGNAL_GET_TYPE) {
lv_obj_type_t * buf = param;
uint8_t i;
for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/
if(buf->type[i] == NULL) break;
}
buf->type[i] = "lv_table";
}
return res;

View File

@ -10,6 +10,7 @@
#if LV_USE_TABVIEW != 0
#include "lv_btnm.h"
#include "../lv_core/lv_debug.h"
#include "../lv_themes/lv_theme.h"
#include "../lv_misc/lv_anim.h"
#include "../lv_core/lv_disp.h"
@ -17,6 +18,8 @@
/*********************
* DEFINES
*********************/
#define LV_OBJX_NAME "lv_tabview"
#if LV_USE_ANIMATION
#ifndef LV_TABVIEW_DEF_ANIM_TIME
#define LV_TABVIEW_DEF_ANIM_TIME 300 /*Animation time of focusing to the a list element [ms] (0: no animation) */
@ -71,13 +74,13 @@ lv_obj_t * lv_tabview_create(lv_obj_t * par, const lv_obj_t * copy)
/*Create the ancestor of tab*/
lv_obj_t * new_tabview = lv_obj_create(par, copy);
lv_mem_assert(new_tabview);
LV_ASSERT_MEM(new_tabview);
if(new_tabview == NULL) return NULL;
if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(new_tabview);
/*Allocate the tab type specific extended data*/
lv_tabview_ext_t * ext = lv_obj_allocate_ext_attr(new_tabview, sizeof(lv_tabview_ext_t));
lv_mem_assert(ext);
LV_ASSERT_MEM(ext);
if(ext == NULL) return NULL;
/*Initialize the allocated 'ext' */
@ -103,7 +106,7 @@ lv_obj_t * lv_tabview_create(lv_obj_t * par, const lv_obj_t * copy)
/*Init the new tab tab*/
if(copy == NULL) {
ext->tab_name_ptr = lv_mem_alloc(sizeof(char *));
lv_mem_assert(ext->tab_name_ptr);
LV_ASSERT_MEM(ext->tab_name_ptr);
if(ext->tab_name_ptr == NULL) return NULL;
ext->tab_name_ptr[0] = "";
ext->tab_cnt = 0;
@ -161,7 +164,7 @@ lv_obj_t * lv_tabview_create(lv_obj_t * par, const lv_obj_t * copy)
#endif
ext->tab_name_ptr = lv_mem_alloc(sizeof(char *));
lv_mem_assert(ext->tab_name_ptr);
LV_ASSERT_MEM(ext->tab_name_ptr);
if(ext->tab_name_ptr == NULL) return NULL;
ext->tab_name_ptr[0] = "";
lv_btnm_set_map(ext->btns, ext->tab_name_ptr);
@ -188,11 +191,13 @@ lv_obj_t * lv_tabview_create(lv_obj_t * par, const lv_obj_t * copy)
/**
* Delete all children of the scrl object, without deleting scrl child.
* @param obj pointer to an object
* @param tabview pointer to an object
*/
void lv_tabview_clean(lv_obj_t * obj)
void lv_tabview_clean(lv_obj_t * tabview)
{
lv_obj_t * scrl = lv_page_get_scrl(obj);
LV_ASSERT_OBJ(tabview, LV_OBJX_NAME);
lv_obj_t * scrl = lv_page_get_scrl(tabview);
lv_obj_clean(scrl);
}
@ -208,6 +213,9 @@ void lv_tabview_clean(lv_obj_t * obj)
*/
lv_obj_t * lv_tabview_add_tab(lv_obj_t * tabview, const char * name)
{
LV_ASSERT_OBJ(tabview, LV_OBJX_NAME);
LV_ASSERT_STR(name);
lv_tabview_ext_t * ext = lv_obj_get_ext_attr(tabview);
/*Create the container page*/
@ -225,7 +233,7 @@ lv_obj_t * lv_tabview_add_tab(lv_obj_t * tabview, const char * name)
/*Extend the button matrix map with the new name*/
char * name_dm;
name_dm = lv_mem_alloc(strlen(name) + 1); /*+1 for the the closing '\0' */
lv_mem_assert(name_dm);
LV_ASSERT_MEM(name_dm);
if(name_dm == NULL) return NULL;
strcpy(name_dm, name);
@ -242,7 +250,7 @@ lv_obj_t * lv_tabview_add_tab(lv_obj_t * tabview, const char * name)
break;
}
lv_mem_assert(ext->tab_name_ptr);
LV_ASSERT_MEM(ext->tab_name_ptr);
if(ext->tab_name_ptr == NULL) return NULL;
/* FIXME: It is not possible yet to switch tab button position from/to top/bottom from/to left/right at runtime.
@ -328,6 +336,8 @@ lv_obj_t * lv_tabview_add_tab(lv_obj_t * tabview, const char * name)
*/
void lv_tabview_set_tab_act(lv_obj_t * tabview, uint16_t id, lv_anim_enable_t anim)
{
LV_ASSERT_OBJ(tabview, LV_OBJX_NAME);
#if LV_USE_ANIMATION == 0
anim = LV_ANIM_OFF;
#endif
@ -452,6 +462,8 @@ void lv_tabview_set_tab_act(lv_obj_t * tabview, uint16_t id, lv_anim_enable_t an
*/
void lv_tabview_set_sliding(lv_obj_t * tabview, bool en)
{
LV_ASSERT_OBJ(tabview, LV_OBJX_NAME);
lv_tabview_ext_t * ext = lv_obj_get_ext_attr(tabview);
ext->slide_enable = en == false ? 0 : 1;
}
@ -463,6 +475,8 @@ void lv_tabview_set_sliding(lv_obj_t * tabview, bool en)
*/
void lv_tabview_set_anim_time(lv_obj_t * tabview, uint16_t anim_time)
{
LV_ASSERT_OBJ(tabview, LV_OBJX_NAME);
#if LV_USE_ANIMATION
lv_tabview_ext_t * ext = lv_obj_get_ext_attr(tabview);
ext->anim_time = anim_time;
@ -480,6 +494,8 @@ void lv_tabview_set_anim_time(lv_obj_t * tabview, uint16_t anim_time)
*/
void lv_tabview_set_style(lv_obj_t * tabview, lv_tabview_style_t type, const lv_style_t * style)
{
LV_ASSERT_OBJ(tabview, LV_OBJX_NAME);
lv_tabview_ext_t * ext = lv_obj_get_ext_attr(tabview);
switch(type) {
@ -517,6 +533,8 @@ void lv_tabview_set_style(lv_obj_t * tabview, lv_tabview_style_t type, const lv_
*/
void lv_tabview_set_btns_pos(lv_obj_t * tabview, lv_tabview_btns_pos_t btns_pos)
{
LV_ASSERT_OBJ(tabview, LV_OBJX_NAME);
lv_tabview_ext_t * ext = lv_obj_get_ext_attr(tabview);
ext->btns_pos = btns_pos;
@ -530,6 +548,8 @@ void lv_tabview_set_btns_pos(lv_obj_t * tabview, lv_tabview_btns_pos_t btns_pos)
*/
void lv_tabview_set_btns_hidden(lv_obj_t * tabview, bool en)
{
LV_ASSERT_OBJ(tabview, LV_OBJX_NAME);
lv_tabview_ext_t * ext = lv_obj_get_ext_attr(tabview);
ext->btns_hide = en;
@ -547,6 +567,8 @@ void lv_tabview_set_btns_hidden(lv_obj_t * tabview, bool en)
*/
uint16_t lv_tabview_get_tab_act(const lv_obj_t * tabview)
{
LV_ASSERT_OBJ(tabview, LV_OBJX_NAME);
lv_tabview_ext_t * ext = lv_obj_get_ext_attr(tabview);
return ext->tab_cur;
}
@ -558,6 +580,8 @@ uint16_t lv_tabview_get_tab_act(const lv_obj_t * tabview)
*/
uint16_t lv_tabview_get_tab_count(const lv_obj_t * tabview)
{
LV_ASSERT_OBJ(tabview, LV_OBJX_NAME);
lv_tabview_ext_t * ext = lv_obj_get_ext_attr(tabview);
return ext->tab_cnt;
}
@ -570,6 +594,8 @@ uint16_t lv_tabview_get_tab_count(const lv_obj_t * tabview)
*/
lv_obj_t * lv_tabview_get_tab(const lv_obj_t * tabview, uint16_t id)
{
LV_ASSERT_OBJ(tabview, LV_OBJX_NAME);
lv_tabview_ext_t * ext = lv_obj_get_ext_attr(tabview);
uint16_t i = 0;
lv_obj_t * page = lv_obj_get_child_back(ext->content, NULL);
@ -591,6 +617,8 @@ lv_obj_t * lv_tabview_get_tab(const lv_obj_t * tabview, uint16_t id)
*/
bool lv_tabview_get_sliding(const lv_obj_t * tabview)
{
LV_ASSERT_OBJ(tabview, LV_OBJX_NAME);
lv_tabview_ext_t * ext = lv_obj_get_ext_attr(tabview);
return ext->slide_enable ? true : false;
}
@ -602,6 +630,8 @@ bool lv_tabview_get_sliding(const lv_obj_t * tabview)
*/
uint16_t lv_tabview_get_anim_time(const lv_obj_t * tabview)
{
LV_ASSERT_OBJ(tabview, LV_OBJX_NAME);
#if LV_USE_ANIMATION
lv_tabview_ext_t * ext = lv_obj_get_ext_attr(tabview);
return ext->anim_time;
@ -619,6 +649,8 @@ uint16_t lv_tabview_get_anim_time(const lv_obj_t * tabview)
*/
const lv_style_t * lv_tabview_get_style(const lv_obj_t * tabview, lv_tabview_style_t type)
{
LV_ASSERT_OBJ(tabview, LV_OBJX_NAME);
const lv_style_t * style = NULL;
lv_tabview_ext_t * ext = lv_obj_get_ext_attr(tabview);
@ -641,6 +673,8 @@ const lv_style_t * lv_tabview_get_style(const lv_obj_t * tabview, lv_tabview_sty
*/
lv_tabview_btns_pos_t lv_tabview_get_btns_pos(const lv_obj_t * tabview)
{
LV_ASSERT_OBJ(tabview, LV_OBJX_NAME);
lv_tabview_ext_t * ext = lv_obj_get_ext_attr(tabview);
return ext->btns_pos;
}
@ -652,6 +686,8 @@ lv_tabview_btns_pos_t lv_tabview_get_btns_pos(const lv_obj_t * tabview)
*/
bool lv_tabview_get_btns_hidden(const lv_obj_t * tabview)
{
LV_ASSERT_OBJ(tabview, LV_OBJX_NAME);
lv_tabview_ext_t * ext = lv_obj_get_ext_attr(tabview);
return ext->btns_hide;
@ -675,6 +711,7 @@ static lv_res_t lv_tabview_signal(lv_obj_t * tabview, lv_signal_t sign, void * p
/* Include the ancient signal function */
res = ancestor_signal(tabview, sign, param);
if(res != LV_RES_OK) return res;
if(sign == LV_SIGNAL_GET_TYPE) return lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
lv_tabview_ext_t * ext = lv_obj_get_ext_attr(tabview);
if(sign == LV_SIGNAL_CLEANUP) {
@ -729,13 +766,6 @@ static lv_res_t lv_tabview_signal(lv_obj_t * tabview, lv_signal_t sign, void * p
} else if(sign == LV_SIGNAL_GET_EDITABLE) {
bool * editable = (bool *)param;
*editable = true;
} else if(sign == LV_SIGNAL_GET_TYPE) {
lv_obj_type_t * buf = param;
uint8_t i;
for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/
if(buf->type[i] == NULL) break;
}
buf->type[i] = "lv_tabview";
}
return res;
@ -755,6 +785,7 @@ static lv_res_t tabpage_signal(lv_obj_t * tab_page, lv_signal_t sign, void * par
/* Include the ancient signal function */
res = page_signal(tab_page, sign, param);
if(res != LV_RES_OK) return res;
if(sign == LV_SIGNAL_GET_TYPE) return lv_obj_handle_get_type_signal(param, "");
lv_obj_t * cont = lv_obj_get_parent(tab_page);
lv_obj_t * tabview = lv_obj_get_parent(cont);
@ -785,6 +816,7 @@ static lv_res_t tabpage_scrl_signal(lv_obj_t * tab_scrl, lv_signal_t sign, void
/* Include the ancient signal function */
res = page_scrl_signal(tab_scrl, sign, param);
if(res != LV_RES_OK) return res;
if(sign == LV_SIGNAL_GET_TYPE) return lv_obj_handle_get_type_signal(param, "");
lv_obj_t * tab_page = lv_obj_get_parent(tab_scrl);
lv_obj_t * cont = lv_obj_get_parent(tab_page);

View File

@ -94,9 +94,9 @@ lv_obj_t * lv_tabview_create(lv_obj_t * par, const lv_obj_t * copy);
/**
* Delete all children of the scrl object, without deleting scrl child.
* @param obj pointer to an object
* @param tabview pointer to an object
*/
void lv_tabview_clean(lv_obj_t * obj);
void lv_tabview_clean(lv_obj_t * tabview);
/*======================
* Add/remove functions

View File

@ -11,11 +11,14 @@
#include <stdbool.h>
#include "lv_cont.h"
#include "../lv_core/lv_debug.h"
#include "../lv_themes/lv_theme.h"
/*********************
* DEFINES
*********************/
#define LV_OBJX_NAME "lv_tileview"
#if LV_USE_ANIMATION
#ifndef LV_TILEVIEW_DEF_ANIM_TIME
#define LV_TILEVIEW_DEF_ANIM_TIME 300 /*Animation time loading a tile [ms] (0: no animation) */
@ -65,12 +68,12 @@ lv_obj_t * lv_tileview_create(lv_obj_t * par, const lv_obj_t * copy)
/*Create the ancestor of tileview*/
lv_obj_t * new_tileview = lv_page_create(par, copy);
lv_mem_assert(new_tileview);
LV_ASSERT_MEM(new_tileview);
if(new_tileview == NULL) return NULL;
/*Allocate the tileview type specific extended data*/
lv_tileview_ext_t * ext = lv_obj_allocate_ext_attr(new_tileview, sizeof(lv_tileview_ext_t));
lv_mem_assert(ext);
LV_ASSERT_MEM(ext);
if(ext == NULL) return NULL;
if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(new_tileview);
if(ancestor_scrl_signal == NULL) ancestor_scrl_signal = lv_obj_get_signal_cb(lv_page_get_scrl(new_tileview));
@ -142,6 +145,9 @@ lv_obj_t * lv_tileview_create(lv_obj_t * par, const lv_obj_t * copy)
*/
void lv_tileview_add_element(lv_obj_t * tileview, lv_obj_t * element)
{
LV_ASSERT_OBJ(tileview, LV_OBJX_NAME);
LV_ASSERT_NULL(tileview);
/* Let the objects event to propagate to the scrollable part of the tileview.
* It is required the handle dargging of the tileview with the element.*/
element->parent_event = 1;
@ -167,6 +173,9 @@ void lv_tileview_add_element(lv_obj_t * tileview, lv_obj_t * element)
*/
void lv_tileview_set_valid_positions(lv_obj_t * tileview, const lv_point_t * valid_pos, uint16_t valid_pos_cnt)
{
LV_ASSERT_OBJ(tileview, LV_OBJX_NAME);
LV_ASSERT_NULL(valid_pos);
lv_tileview_ext_t * ext = lv_obj_get_ext_attr(tileview);
ext->valid_pos = valid_pos;
ext->valid_pos_cnt = valid_pos_cnt;
@ -194,6 +203,8 @@ void lv_tileview_set_valid_positions(lv_obj_t * tileview, const lv_point_t * val
*/
void lv_tileview_set_tile_act(lv_obj_t * tileview, lv_coord_t x, lv_coord_t y, lv_anim_enable_t anim)
{
LV_ASSERT_OBJ(tileview, LV_OBJX_NAME);
#if LV_USE_ANIMATION == 0
anim = LV_ANIM_OFF;
#endif
@ -263,6 +274,7 @@ void lv_tileview_set_tile_act(lv_obj_t * tileview, lv_coord_t x, lv_coord_t y, l
*/
void lv_tileview_set_style(lv_obj_t * tileview, lv_tileview_style_t type, const lv_style_t * style)
{
LV_ASSERT_OBJ(tileview, LV_OBJX_NAME);
switch(type) {
case LV_TILEVIEW_STYLE_MAIN: lv_obj_set_style(tileview, style); break;
@ -285,6 +297,8 @@ void lv_tileview_set_style(lv_obj_t * tileview, lv_tileview_style_t type, const
*/
const lv_style_t * lv_tileview_get_style(const lv_obj_t * tileview, lv_tileview_style_t type)
{
LV_ASSERT_OBJ(tileview, LV_OBJX_NAME);
const lv_style_t * style = NULL;
switch(type) {
case LV_TILEVIEW_STYLE_MAIN: style = lv_obj_get_style(tileview); break;
@ -320,16 +334,10 @@ static lv_res_t lv_tileview_signal(lv_obj_t * tileview, lv_signal_t sign, void *
/* Include the ancient signal function */
res = ancestor_signal(tileview, sign, param);
if(res != LV_RES_OK) return res;
if(sign == LV_SIGNAL_GET_TYPE) return lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
if(sign == LV_SIGNAL_CLEANUP) {
/*Nothing to cleanup. (No dynamically allocated memory in 'ext')*/
} else if(sign == LV_SIGNAL_GET_TYPE) {
lv_obj_type_t * buf = param;
uint8_t i;
for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/
if(buf->type[i] == NULL) break;
}
buf->type[i] = "lv_tileview";
}
return res;

View File

@ -9,12 +9,14 @@
#include "lv_win.h"
#if LV_USE_WIN != 0
#include "../lv_core/lv_debug.h"
#include "../lv_themes/lv_theme.h"
#include "../lv_core/lv_disp.h"
/*********************
* DEFINES
*********************/
#define LV_OBJX_NAME "lv_win"
/**********************
* TYPEDEFS
@ -51,14 +53,14 @@ lv_obj_t * lv_win_create(lv_obj_t * par, const lv_obj_t * copy)
/*Create the ancestor object*/
lv_obj_t * new_win = lv_obj_create(par, copy);
lv_mem_assert(new_win);
LV_ASSERT_MEM(new_win);
if(new_win == NULL) return NULL;
if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(new_win);
/*Allocate the object type specific extended data*/
lv_win_ext_t * ext = lv_obj_allocate_ext_attr(new_win, sizeof(lv_win_ext_t));
lv_mem_assert(ext);
LV_ASSERT_MEM(ext);
if(ext == NULL) return NULL;
ext->page = NULL;
@ -94,6 +96,8 @@ lv_obj_t * lv_win_create(lv_obj_t * par, const lv_obj_t * copy)
ext->title = lv_label_create(ext->header, NULL);
lv_label_set_text(ext->title, "My title");
lv_obj_set_signal_cb(new_win, lv_win_signal);
/*Set the default styles*/
lv_theme_t * th = lv_theme_get_current();
if(th) {
@ -108,8 +112,6 @@ lv_obj_t * lv_win_create(lv_obj_t * par, const lv_obj_t * copy)
lv_win_set_style(new_win, LV_WIN_STYLE_CONTENT, &lv_style_transp);
lv_win_set_style(new_win, LV_WIN_STYLE_HEADER, &lv_style_plain_color);
}
lv_obj_set_signal_cb(new_win, lv_win_signal);
}
/*Copy an existing object*/
else {
@ -146,11 +148,13 @@ lv_obj_t * lv_win_create(lv_obj_t * par, const lv_obj_t * copy)
/**
* Delete all children of the scrl object, without deleting scrl child.
* @param obj pointer to an object
* @param win pointer to an object
*/
void lv_win_clean(lv_obj_t * obj)
void lv_win_clean(lv_obj_t * win)
{
lv_obj_t * scrl = lv_page_get_scrl(obj);
LV_ASSERT_OBJ(win, LV_OBJX_NAME);
lv_obj_t * scrl = lv_page_get_scrl(win);
lv_obj_clean(scrl);
}
@ -166,6 +170,9 @@ void lv_win_clean(lv_obj_t * obj)
*/
lv_obj_t * lv_win_add_btn(lv_obj_t * win, const void * img_src)
{
LV_ASSERT_OBJ(win, LV_OBJX_NAME);
LV_ASSERT_NULL(img_src);
lv_win_ext_t * ext = lv_obj_get_ext_attr(win);
lv_obj_t * btn = lv_btn_create(ext->header, NULL);
@ -193,6 +200,8 @@ lv_obj_t * lv_win_add_btn(lv_obj_t * win, const void * img_src)
*/
void lv_win_close_event_cb(lv_obj_t * btn, lv_event_t event)
{
LV_ASSERT_OBJ(btn, "lv_btn");
if(event == LV_EVENT_RELEASED) {
lv_obj_t * win = lv_win_get_from_btn(btn);
@ -207,6 +216,9 @@ void lv_win_close_event_cb(lv_obj_t * btn, lv_event_t event)
*/
void lv_win_set_title(lv_obj_t * win, const char * title)
{
LV_ASSERT_OBJ(win, LV_OBJX_NAME);
LV_ASSERT_STR(title);
lv_win_ext_t * ext = lv_obj_get_ext_attr(win);
lv_label_set_text(ext->title, title);
@ -220,6 +232,8 @@ void lv_win_set_title(lv_obj_t * win, const char * title)
*/
void lv_win_set_btn_size(lv_obj_t * win, lv_coord_t size)
{
LV_ASSERT_OBJ(win, LV_OBJX_NAME);
lv_win_ext_t * ext = lv_obj_get_ext_attr(win);
if(ext->btn_size == size) return;
@ -228,6 +242,22 @@ void lv_win_set_btn_size(lv_obj_t * win, lv_coord_t size)
lv_win_realign(win);
}
/**
* Set the size of the content area.
* @param win pointer to a window object
* @param w width
* @param h height (the window will be higher with the height of the header)
*/
void lv_win_set_content_size(lv_obj_t * win, lv_coord_t w, lv_coord_t h)
{
LV_ASSERT_OBJ(win, LV_OBJX_NAME);
lv_win_ext_t * ext = lv_obj_get_ext_attr(win);
h += lv_obj_get_height(ext->header);
lv_obj_set_size(win, w, h);
}
/**
* Set the layout of the window
* @param win pointer to a window object
@ -235,6 +265,8 @@ void lv_win_set_btn_size(lv_obj_t * win, lv_coord_t size)
*/
void lv_win_set_layout(lv_obj_t * win, lv_layout_t layout)
{
LV_ASSERT_OBJ(win, LV_OBJX_NAME);
lv_win_ext_t * ext = lv_obj_get_ext_attr(win);
lv_page_set_scrl_layout(ext->page, layout);
}
@ -246,6 +278,8 @@ void lv_win_set_layout(lv_obj_t * win, lv_layout_t layout)
*/
void lv_win_set_sb_mode(lv_obj_t * win, lv_sb_mode_t sb_mode)
{
LV_ASSERT_OBJ(win, LV_OBJX_NAME);
lv_win_ext_t * ext = lv_obj_get_ext_attr(win);
lv_page_set_sb_mode(ext->page, sb_mode);
}
@ -256,6 +290,8 @@ void lv_win_set_sb_mode(lv_obj_t * win, lv_sb_mode_t sb_mode)
*/
void lv_win_set_anim_time(lv_obj_t * win, uint16_t anim_time)
{
LV_ASSERT_OBJ(win, LV_OBJX_NAME);
lv_page_set_anim_time(lv_win_get_content(win), anim_time);
}
@ -267,6 +303,8 @@ void lv_win_set_anim_time(lv_obj_t * win, uint16_t anim_time)
*/
void lv_win_set_style(lv_obj_t * win, lv_win_style_t type, const lv_style_t * style)
{
LV_ASSERT_OBJ(win, LV_OBJX_NAME);
lv_win_ext_t * ext = lv_obj_get_ext_attr(win);
switch(type) {
@ -306,6 +344,8 @@ void lv_win_set_style(lv_obj_t * win, lv_win_style_t type, const lv_style_t * st
*/
void lv_win_set_drag(lv_obj_t * win, bool en)
{
LV_ASSERT_OBJ(win, LV_OBJX_NAME);
lv_win_ext_t * ext = lv_obj_get_ext_attr(win);
lv_obj_t * win_header = ext->header;
lv_obj_set_drag_parent(win_header, en);
@ -323,6 +363,8 @@ void lv_win_set_drag(lv_obj_t * win, bool en)
*/
const char * lv_win_get_title(const lv_obj_t * win)
{
LV_ASSERT_OBJ(win, LV_OBJX_NAME);
lv_win_ext_t * ext = lv_obj_get_ext_attr(win);
return lv_label_get_text(ext->title);
}
@ -334,6 +376,8 @@ const char * lv_win_get_title(const lv_obj_t * win)
*/
lv_obj_t * lv_win_get_content(const lv_obj_t * win)
{
LV_ASSERT_OBJ(win, LV_OBJX_NAME);
lv_win_ext_t * ext = lv_obj_get_ext_attr(win);
return ext->page;
}
@ -345,6 +389,8 @@ lv_obj_t * lv_win_get_content(const lv_obj_t * win)
*/
lv_coord_t lv_win_get_btn_size(const lv_obj_t * win)
{
LV_ASSERT_OBJ(win, LV_OBJX_NAME);
lv_win_ext_t * ext = lv_obj_get_ext_attr(win);
return ext->btn_size;
}
@ -357,6 +403,8 @@ lv_coord_t lv_win_get_btn_size(const lv_obj_t * win)
*/
lv_obj_t * lv_win_get_from_btn(const lv_obj_t * ctrl_btn)
{
LV_ASSERT_OBJ(ctrl_btn, "lv_btn");
lv_obj_t * header = lv_obj_get_parent(ctrl_btn);
lv_obj_t * win = lv_obj_get_parent(header);
@ -370,6 +418,8 @@ lv_obj_t * lv_win_get_from_btn(const lv_obj_t * ctrl_btn)
*/
lv_layout_t lv_win_get_layout(lv_obj_t * win)
{
LV_ASSERT_OBJ(win, LV_OBJX_NAME);
lv_win_ext_t * ext = lv_obj_get_ext_attr(win);
return lv_page_get_scrl_layout(ext->page);
}
@ -381,6 +431,8 @@ lv_layout_t lv_win_get_layout(lv_obj_t * win)
*/
lv_sb_mode_t lv_win_get_sb_mode(lv_obj_t * win)
{
LV_ASSERT_OBJ(win, LV_OBJX_NAME);
lv_win_ext_t * ext = lv_obj_get_ext_attr(win);
return lv_page_get_sb_mode(ext->page);
}
@ -392,6 +444,8 @@ lv_sb_mode_t lv_win_get_sb_mode(lv_obj_t * win)
*/
uint16_t lv_win_get_anim_time(const lv_obj_t * win)
{
LV_ASSERT_OBJ(win, LV_OBJX_NAME);
return lv_page_get_anim_time(lv_win_get_content(win));
}
@ -402,6 +456,8 @@ uint16_t lv_win_get_anim_time(const lv_obj_t * win)
*/
lv_coord_t lv_win_get_width(lv_obj_t * win)
{
LV_ASSERT_OBJ(win, LV_OBJX_NAME);
lv_win_ext_t * ext = lv_obj_get_ext_attr(win);
lv_obj_t * scrl = lv_page_get_scrl(ext->page);
const lv_style_t * style_scrl = lv_obj_get_style(scrl);
@ -417,6 +473,8 @@ lv_coord_t lv_win_get_width(lv_obj_t * win)
*/
const lv_style_t * lv_win_get_style(const lv_obj_t * win, lv_win_style_t type)
{
LV_ASSERT_OBJ(win, LV_OBJX_NAME);
const lv_style_t * style = NULL;
lv_win_ext_t * ext = lv_obj_get_ext_attr(win);
@ -445,6 +503,10 @@ const lv_style_t * lv_win_get_style(const lv_obj_t * win, lv_win_style_t type)
*/
void lv_win_focus(lv_obj_t * win, lv_obj_t * obj, lv_anim_enable_t anim_en)
{
LV_ASSERT_OBJ(win, LV_OBJX_NAME);
LV_ASSERT_OBJ(obj, "");
lv_win_ext_t * ext = lv_obj_get_ext_attr(win);
lv_page_focus(ext->page, obj, anim_en);
}
@ -467,6 +529,7 @@ static lv_res_t lv_win_signal(lv_obj_t * win, lv_signal_t sign, void * param)
/* Include the ancient signal function */
res = ancestor_signal(win, sign, param);
if(res != LV_RES_OK) return res;
if(sign == LV_SIGNAL_GET_TYPE) return lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
lv_win_ext_t * ext = lv_obj_get_ext_attr(win);
if(sign == LV_SIGNAL_CHILD_CHG) { /*Move children to the page*/
@ -498,13 +561,6 @@ static lv_res_t lv_win_signal(lv_obj_t * win, lv_signal_t sign, void * param)
} else if(sign == LV_SIGNAL_CONTROL) {
/*Forward all the control signals to the page*/
ext->page->signal_cb(ext->page, sign, param);
} else if(sign == LV_SIGNAL_GET_TYPE) {
lv_obj_type_t * buf = param;
uint8_t i;
for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/
if(buf->type[i] == NULL) break;
}
buf->type[i] = "lv_win";
}
return res;

View File

@ -91,9 +91,9 @@ lv_obj_t * lv_win_create(lv_obj_t * par, const lv_obj_t * copy);
/**
* Delete all children of the scrl object, without deleting scrl child.
* @param obj pointer to an object
* @param win pointer to an object
*/
void lv_win_clean(lv_obj_t * obj);
void lv_win_clean(lv_obj_t * win);
/*======================
* Add/remove functions
@ -132,6 +132,15 @@ void lv_win_set_title(lv_obj_t * win, const char * title);
*/
void lv_win_set_btn_size(lv_obj_t * win, lv_coord_t size);
/**
* Set the size of the content area.
* @param win pointer to a window object
* @param w width
* @param h height (the window will be higher with the height of the header)
*/
void lv_win_set_content_size(lv_obj_t * win, lv_coord_t w, lv_coord_t h);
/**
* Set the layout of the window
* @param win pointer to a window object

View File

@ -15,9 +15,9 @@ extern "C" {
*********************/
/*Current version of LittlevGL*/
#define LVGL_VERSION_MAJOR 6
#define LVGL_VERSION_MINOR 0
#define LVGL_VERSION_PATCH 2
#define LVGL_VERSION_INFO ""
#define LVGL_VERSION_MINOR 1
#define LVGL_VERSION_PATCH 0
#define LVGL_VERSION_INFO "dev"
/*********************