LVGL 库提交

This commit is contained in:
2026-08-30 08:57:07 +08:00
parent 26c9098630
commit e2f199c6bf
1056 changed files with 556743 additions and 45 deletions
+268
View File
@@ -0,0 +1,268 @@
/**
* @file lv_line.c
*
*/
/*********************
* INCLUDES
*********************/
#include "lv_line_private.h"
#include "../../core/lv_obj_class_private.h"
#if LV_USE_LINE != 0
#include "../../misc/lv_assert.h"
#include "../../misc/lv_math.h"
#include "../../misc/lv_types.h"
#include "../../draw/lv_draw.h"
/*********************
* DEFINES
*********************/
#define MY_CLASS (&lv_line_class)
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
static void lv_line_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj);
static void line_set_points(lv_obj_t * obj, const lv_point_precise_t points[], uint32_t point_num, bool mut);
static void lv_line_event(const lv_obj_class_t * class_p, lv_event_t * e);
/**********************
* STATIC VARIABLES
**********************/
const lv_obj_class_t lv_line_class = {
.constructor_cb = lv_line_constructor,
.event_cb = lv_line_event,
.width_def = LV_SIZE_CONTENT,
.height_def = LV_SIZE_CONTENT,
.instance_size = sizeof(lv_line_t),
.base_class = &lv_obj_class,
.name = "lv_line",
};
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
lv_obj_t * lv_line_create(lv_obj_t * parent)
{
LV_LOG_INFO("begin");
lv_obj_t * obj = lv_obj_class_create_obj(MY_CLASS, parent);
lv_obj_class_init_obj(obj);
return obj;
}
/*=====================
* Setter functions
*====================*/
void lv_line_set_points(lv_obj_t * obj, const lv_point_precise_t points[], uint32_t point_num)
{
line_set_points(obj, points, point_num, false);
}
void lv_line_set_points_mutable(lv_obj_t * obj, lv_point_precise_t points[], uint32_t point_num)
{
line_set_points(obj, points, point_num, true);
}
void lv_line_set_y_invert(lv_obj_t * obj, bool en)
{
LV_ASSERT_OBJ(obj, MY_CLASS);
lv_line_t * line = (lv_line_t *)obj;
if(line->y_inv == en) return;
line->y_inv = en ? 1U : 0U;
lv_obj_invalidate(obj);
}
/*=====================
* Getter functions
*====================*/
const lv_point_precise_t * lv_line_get_points(lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, MY_CLASS);
lv_line_t * line = (lv_line_t *)obj;
return line->point_array.constant;
}
uint32_t lv_line_get_point_count(lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, MY_CLASS);
lv_line_t * line = (lv_line_t *)obj;
return line->point_num;
}
bool lv_line_is_point_array_mutable(lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, MY_CLASS);
lv_line_t * line = (lv_line_t *)obj;
return line->point_array_is_mutable;
}
lv_point_precise_t * lv_line_get_points_mutable(lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, MY_CLASS);
lv_line_t * line = (lv_line_t *)obj;
if(!line->point_array_is_mutable) {
LV_LOG_WARN("the line point array is not mutable");
return NULL;
}
return line->point_array.mut;
}
bool lv_line_get_y_invert(const lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, MY_CLASS);
lv_line_t * line = (lv_line_t *)obj;
return line->y_inv == 1U;
}
/**********************
* STATIC FUNCTIONS
**********************/
static void lv_line_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj)
{
LV_UNUSED(class_p);
LV_TRACE_OBJ_CREATE("begin");
lv_line_t * line = (lv_line_t *)obj;
line->point_num = 0;
line->point_array.constant = NULL;
line->y_inv = 0;
line->point_array_is_mutable = 0;
lv_obj_remove_flag(obj, LV_OBJ_FLAG_CLICKABLE);
LV_TRACE_OBJ_CREATE("finished");
}
static void line_set_points(lv_obj_t * obj, const lv_point_precise_t points[], uint32_t point_num, bool mut)
{
LV_ASSERT_OBJ(obj, MY_CLASS);
lv_line_t * line = (lv_line_t *)obj;
line->point_array.constant = points;
line->point_num = point_num;
line->point_array_is_mutable = mut;
lv_obj_refresh_self_size(obj);
lv_obj_invalidate(obj);
}
static inline lv_value_precise_t resolve_point_coord(lv_value_precise_t coord, int32_t max)
{
if(LV_COORD_IS_PCT((int32_t)coord)) {
return LV_CLAMP(0, max * LV_COORD_GET_PCT((int32_t)coord) / 100, max);
}
else {
return coord;
}
}
static void lv_line_event(const lv_obj_class_t * class_p, lv_event_t * e)
{
LV_UNUSED(class_p);
lv_result_t res;
/*Call the ancestor's event handler*/
res = lv_obj_event_base(MY_CLASS, e);
if(res != LV_RESULT_OK) return;
lv_event_code_t code = lv_event_get_code(e);
lv_obj_t * obj = lv_event_get_current_target(e);
if(code == LV_EVENT_REFR_EXT_DRAW_SIZE) {
/*The corner of the skew lines is out of the intended area*/
int32_t line_width = lv_obj_get_style_line_width(obj, LV_PART_MAIN);
int32_t * s = lv_event_get_param(e);
if(*s < line_width) *s = line_width;
}
else if(code == LV_EVENT_GET_SELF_SIZE) {
lv_line_t * line = (lv_line_t *)obj;
if(line->point_num == 0 || line->point_array.constant == NULL) return;
lv_point_t * p = lv_event_get_param(e);
int32_t w = 0;
int32_t h = 0;
uint32_t i;
for(i = 0; i < line->point_num; i++) {
if(!LV_COORD_IS_PCT((int32_t)line->point_array.constant[i].x)) {
w = (int32_t)LV_MAX(line->point_array.constant[i].x, w);
}
if(!LV_COORD_IS_PCT((int32_t)line->point_array.constant[i].y)) {
h = (int32_t)LV_MAX(line->point_array.constant[i].y, h);
}
}
p->x = w;
p->y = h;
}
else if(code == LV_EVENT_DRAW_MAIN) {
lv_line_t * line = (lv_line_t *)obj;
lv_layer_t * layer = lv_event_get_layer(e);
if(line->point_num == 0 || line->point_array.constant == NULL) return;
lv_area_t area;
lv_obj_get_coords(obj, &area);
int32_t x_ofs = area.x1 - lv_obj_get_scroll_x(obj);
int32_t y_ofs = area.y1 - lv_obj_get_scroll_y(obj);
lv_draw_line_dsc_t line_dsc;
lv_draw_line_dsc_init(&line_dsc);
line_dsc.base.layer = layer;
lv_obj_init_draw_line_dsc(obj, LV_PART_MAIN, &line_dsc);
/*Read all points and draw the lines*/
uint32_t i;
for(i = 0; i < line->point_num - 1; i++) {
int32_t w = lv_obj_get_width(obj);
int32_t h = lv_obj_get_height(obj);
line_dsc.p1.x = resolve_point_coord(line->point_array.constant[i].x, w) + x_ofs;
line_dsc.p1.y = resolve_point_coord(line->point_array.constant[i].y, h);
line_dsc.p2.x = resolve_point_coord(line->point_array.constant[i + 1].x, w) + x_ofs;
line_dsc.p2.y = resolve_point_coord(line->point_array.constant[i + 1].y, h);
if(line->y_inv == 0) {
line_dsc.p1.y = line_dsc.p1.y + y_ofs;
line_dsc.p2.y = line_dsc.p2.y + y_ofs;
}
else {
line_dsc.p1.y = h - line_dsc.p1.y + y_ofs;
line_dsc.p2.y = h - line_dsc.p2.y + y_ofs;
}
lv_draw_line(layer, &line_dsc);
line_dsc.round_start = 0; /*Draw the rounding only on the end points after the first line*/
}
}
}
#endif
+118
View File
@@ -0,0 +1,118 @@
/**
* @file lv_line.h
*
*/
#ifndef LV_LINE_H
#define LV_LINE_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
#include "../../core/lv_obj.h"
#if LV_USE_LINE != 0
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_line_class;
/**********************
* GLOBAL PROTOTYPES
**********************/
/**
* Create a line object
* @param parent pointer to an object, it will be the parent of the new line
* @return pointer to the created line
*/
lv_obj_t * lv_line_create(lv_obj_t * parent);
/*=====================
* Setter functions
*====================*/
/**
* Set an array of points. The line object will connect these points.
* @param obj pointer to a line object
* @param points an array of points. Only the address is saved, so the array needs to be alive while the line exists
* @param point_num number of points in 'point_a'
*/
void lv_line_set_points(lv_obj_t * obj, const lv_point_precise_t points[], uint32_t point_num);
/**
* Set a non-const array of points. Identical to `lv_line_set_points` except the array may be retrieved by `lv_line_get_points_mutable`.
* @param obj pointer to a line object
* @param points a non-const array of points. Only the address is saved, so the array needs to be alive while the line exists.
* @param point_num number of points in 'point_a'
*/
void lv_line_set_points_mutable(lv_obj_t * obj, lv_point_precise_t points[], uint32_t point_num);
/**
* Enable (or disable) the y coordinate inversion.
* If enabled then y will be subtracted from the height of the object,
* therefore the y = 0 coordinate will be on the bottom.
* @param obj pointer to a line object
* @param en true: enable the y inversion, false:disable the y inversion
*/
void lv_line_set_y_invert(lv_obj_t * obj, bool en);
/*=====================
* Getter functions
*====================*/
/**
* Get the pointer to the array of points.
* @param obj pointer to a line object
* @return const pointer to the array of points
*/
const lv_point_precise_t * lv_line_get_points(lv_obj_t * obj);
/**
* Get the number of points in the array of points.
* @param obj pointer to a line object
* @return number of points in array of points
*/
uint32_t lv_line_get_point_count(lv_obj_t * obj);
/**
* Check the mutability of the stored point array pointer.
* @param obj pointer to a line object
* @return true: the point array pointer is mutable, false: constant
*/
bool lv_line_is_point_array_mutable(lv_obj_t * obj);
/**
* Get a pointer to the mutable array of points or NULL if it is not mutable
* @param obj pointer to a line object
* @return pointer to the array of points. NULL if not mutable.
*/
lv_point_precise_t * lv_line_get_points_mutable(lv_obj_t * obj);
/**
* Get the y inversion attribute
* @param obj pointer to a line object
* @return true: y inversion is enabled, false: disabled
*/
bool lv_line_get_y_invert(const lv_obj_t * obj);
/**********************
* MACROS
**********************/
#endif /*LV_USE_LINE*/
#ifdef __cplusplus
} /*extern "C"*/
#endif
#endif /*LV_LINE_H*/
@@ -0,0 +1,57 @@
/**
* @file lv_line_private.h
*
*/
#ifndef LV_LINE_PRIVATE_H
#define LV_LINE_PRIVATE_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
#include "../../core/lv_obj_private.h"
#include "lv_line.h"
#if LV_USE_LINE != 0
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/** Data of line */
struct _lv_line_t {
lv_obj_t obj;
union {
const lv_point_precise_t * constant;
lv_point_precise_t * mut;
} point_array; /**< Pointer to an array with the points of the line*/
uint32_t point_num; /**< Number of points in 'point_array'*/
uint32_t y_inv : 1; /**< 1: y == 0 will be on the bottom*/
uint32_t point_array_is_mutable : 1; /**< whether the point array is const or mutable*/
};
/**********************
* GLOBAL PROTOTYPES
**********************/
/**********************
* MACROS
**********************/
#endif /* LV_USE_LINE != 0 */
#ifdef __cplusplus
} /*extern "C"*/
#endif
#endif /*LV_LINE_PRIVATE_H*/