LVGL 库提交
This commit is contained in:
@@ -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
|
||||
@@ -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*/
|
||||
Reference in New Issue
Block a user