Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
CTCaer
GitHub Repository: CTCaer/hekate
Path: blob/master/bdk/libs/lvgl/lv_objx/lv_arc.c
1476 views
1
/**
2
* @file lv_arc.c
3
*
4
*/
5
6
7
/*********************
8
* INCLUDES
9
*********************/
10
#include "lv_arc.h"
11
#if USE_LV_ARC != 0
12
13
#include "../lv_misc/lv_math.h"
14
#include "../lv_draw/lv_draw_arc.h"
15
#include "../lv_themes/lv_theme.h"
16
17
18
/*********************
19
* DEFINES
20
*********************/
21
22
/**********************
23
* TYPEDEFS
24
**********************/
25
26
/**********************
27
* STATIC PROTOTYPES
28
**********************/
29
static bool lv_arc_design(lv_obj_t * arc, const lv_area_t * mask, lv_design_mode_t mode);
30
static lv_res_t lv_arc_signal(lv_obj_t * arc, lv_signal_t sign, void * param);
31
32
/**********************
33
* STATIC VARIABLES
34
**********************/
35
static lv_signal_func_t ancestor_signal;
36
static lv_design_func_t ancestor_design;
37
38
/**********************
39
* MACROS
40
**********************/
41
42
/**********************
43
* GLOBAL FUNCTIONS
44
**********************/
45
46
/**
47
* Create a arc object
48
* @param par pointer to an object, it will be the parent of the new arc
49
* @param copy pointer to a arc object, if not NULL then the new object will be copied from it
50
* @return pointer to the created arc
51
*/
52
lv_obj_t * lv_arc_create(lv_obj_t * par, const lv_obj_t * copy)
53
{
54
55
LV_LOG_TRACE("arc create started");
56
57
/*Create the ancestor of arc*/
58
lv_obj_t * new_arc = lv_obj_create(par, copy);
59
lv_mem_assert(new_arc);
60
if(new_arc == NULL) return NULL;
61
62
/*Allocate the arc type specific extended data*/
63
lv_arc_ext_t * ext = lv_obj_allocate_ext_attr(new_arc, sizeof(lv_arc_ext_t));
64
lv_mem_assert(ext);
65
if(ext == NULL) return NULL;
66
67
if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_func(new_arc);
68
if(ancestor_design == NULL) ancestor_design = lv_obj_get_design_func(new_arc);
69
70
/*Initialize the allocated 'ext' */
71
ext->angle_start = 45;
72
ext->angle_end = 315;
73
74
/*The signal and design functions are not copied so set them here*/
75
lv_obj_set_signal_func(new_arc, lv_arc_signal);
76
lv_obj_set_design_func(new_arc, lv_arc_design);
77
78
/*Init the new arc arc*/
79
if(copy == NULL) {
80
/*Set the default styles*/
81
lv_theme_t * th = lv_theme_get_current();
82
if(th) {
83
lv_arc_set_style(new_arc, LV_ARC_STYLE_MAIN, th->arc);
84
} else {
85
lv_arc_set_style(new_arc, LV_ARC_STYLE_MAIN, &lv_style_plain_color);
86
}
87
88
}
89
/*Copy an existing arc*/
90
else {
91
lv_arc_ext_t * copy_ext = lv_obj_get_ext_attr(copy);
92
ext->angle_start = copy_ext->angle_start;
93
ext->angle_end = copy_ext->angle_end;
94
95
/*Refresh the style with new signal function*/
96
lv_obj_refresh_style(new_arc);
97
}
98
99
LV_LOG_INFO("arc created");
100
101
return new_arc;
102
}
103
104
/*======================
105
* Add/remove functions
106
*=====================*/
107
108
/*
109
* New object specific "add" or "remove" functions come here
110
*/
111
112
113
/*=====================
114
* Setter functions
115
*====================*/
116
117
/**
118
* Set the start and end angles of an arc. 0 deg: bottom, 90 deg: right etc.
119
* @param arc pointer to an arc object
120
* @param start the start angle [0..360]
121
* @param end the end angle [0..360]
122
*/
123
void lv_arc_set_angles(lv_obj_t * arc, uint16_t start, uint16_t end)
124
{
125
lv_arc_ext_t * ext = lv_obj_get_ext_attr(arc);
126
127
if(start > 360) start = 360;
128
if(end > 360) end = 360;
129
130
ext->angle_start = start;
131
ext->angle_end = end;
132
133
lv_obj_invalidate(arc);
134
}
135
136
/**
137
* Set a style of a arc.
138
* @param arc pointer to arc object
139
* @param type which style should be set
140
* @param style pointer to a style
141
* */
142
void lv_arc_set_style(lv_obj_t * arc, lv_arc_style_t type, lv_style_t * style)
143
{
144
switch(type) {
145
case LV_ARC_STYLE_MAIN:
146
lv_obj_set_style(arc, style);
147
break;
148
}
149
}
150
151
/*=====================
152
* Getter functions
153
*====================*/
154
155
/**
156
* Get the start angle of an arc.
157
* @param arc pointer to an arc object
158
* @return the start angle [0..360]
159
*/
160
uint16_t lv_arc_get_angle_start(lv_obj_t * arc)
161
{
162
lv_arc_ext_t * ext = lv_obj_get_ext_attr(arc);
163
164
return ext->angle_start;
165
}
166
167
/**
168
* Get the end angle of an arc.
169
* @param arc pointer to an arc object
170
* @return the end angle [0..360]
171
*/
172
uint16_t lv_arc_get_angle_end(lv_obj_t * arc)
173
{
174
lv_arc_ext_t * ext = lv_obj_get_ext_attr(arc);
175
176
return ext->angle_end;
177
}
178
179
/**
180
* Get style of a arc.
181
* @param arc pointer to arc object
182
* @param type which style should be get
183
* @return style pointer to the style
184
* */
185
lv_style_t * lv_arc_get_style(const lv_obj_t * arc, lv_arc_style_t type)
186
{
187
lv_style_t * style = NULL;
188
189
switch(type) {
190
case LV_ARC_STYLE_MAIN:
191
style = lv_obj_get_style(arc);
192
break;
193
default:
194
style = NULL;
195
break;
196
}
197
198
return style;
199
}
200
201
/*=====================
202
* Other functions
203
*====================*/
204
205
/*
206
* New object specific "other" functions come here
207
*/
208
209
/**********************
210
* STATIC FUNCTIONS
211
**********************/
212
213
/**
214
* Handle the drawing related tasks of the arcs
215
* @param arc pointer to an object
216
* @param mask the object will be drawn only in this area
217
* @param mode LV_DESIGN_COVER_CHK: only check if the object fully covers the 'mask_p' area
218
* (return 'true' if yes)
219
* LV_DESIGN_DRAW: draw the object (always return 'true')
220
* LV_DESIGN_DRAW_POST: drawing after every children are drawn
221
* @param return true/false, depends on 'mode'
222
*/
223
static bool lv_arc_design(lv_obj_t * arc, const lv_area_t * mask, lv_design_mode_t mode)
224
{
225
/*Return false if the object is not covers the mask_p area*/
226
if(mode == LV_DESIGN_COVER_CHK) {
227
return false;
228
}
229
/*Draw the object*/
230
else if(mode == LV_DESIGN_DRAW_MAIN) {
231
lv_arc_ext_t * ext = lv_obj_get_ext_attr(arc);
232
lv_style_t * style = lv_arc_get_style(arc, LV_ARC_STYLE_MAIN);
233
234
lv_coord_t r = (LV_MATH_MIN(lv_obj_get_width(arc), lv_obj_get_height(arc))) / 2;
235
lv_coord_t x = arc->coords.x1 + lv_obj_get_width(arc) / 2;
236
lv_coord_t y = arc->coords.y1 + lv_obj_get_height(arc) / 2;
237
lv_opa_t opa_scale = lv_obj_get_opa_scale(arc);
238
lv_draw_arc(x, y, r, mask, ext->angle_start, ext->angle_end, style, opa_scale);
239
240
241
/*Draw circle on the ends if enabled */
242
if(style->line.rounded) {
243
lv_coord_t thick_half = style->line.width / 2;
244
lv_coord_t cir_x = ((r - thick_half) * lv_trigo_sin(ext->angle_start) >> LV_TRIGO_SHIFT);
245
lv_coord_t cir_y = ((r - thick_half) * lv_trigo_sin(ext->angle_start + 90) >> LV_TRIGO_SHIFT);
246
247
lv_style_t cir_style;
248
lv_style_copy(&cir_style, &lv_style_plain);
249
cir_style.body.grad_color = style->line.color;
250
cir_style.body.main_color = cir_style.body.grad_color;
251
cir_style.body.radius = LV_RADIUS_CIRCLE;
252
lv_area_t cir_area;
253
cir_area.x1 = cir_x + x - thick_half;
254
cir_area.y1 = cir_y + y - thick_half;
255
cir_area.x2 = cir_x + x + thick_half;
256
cir_area.y2 = cir_y + y + thick_half;
257
258
lv_draw_rect(&cir_area, mask, &cir_style, opa_scale);
259
260
cir_x = ((r - thick_half) * lv_trigo_sin(ext->angle_end) >> LV_TRIGO_SHIFT);
261
cir_y = ((r - thick_half) * lv_trigo_sin(ext->angle_end + 90) >> LV_TRIGO_SHIFT);
262
263
cir_area.x1 = cir_x + x - thick_half;
264
cir_area.y1 = cir_y + y - thick_half;
265
cir_area.x2 = cir_x + x + thick_half;
266
cir_area.y2 = cir_y + y + thick_half;
267
268
lv_draw_rect(&cir_area, mask, &cir_style, opa_scale);
269
}
270
271
}
272
/*Post draw when the children are drawn*/
273
else if(mode == LV_DESIGN_DRAW_POST) {
274
275
}
276
277
return true;
278
}
279
280
/**
281
* Signal function of the arc
282
* @param arc pointer to a arc object
283
* @param sign a signal type from lv_signal_t enum
284
* @param param pointer to a signal specific variable
285
* @return LV_RES_OK: the object is not deleted in the function; LV_RES_INV: the object is deleted
286
*/
287
static lv_res_t lv_arc_signal(lv_obj_t * arc, lv_signal_t sign, void * param)
288
{
289
lv_res_t res;
290
291
/* Include the ancient signal function */
292
res = ancestor_signal(arc, sign, param);
293
if(res != LV_RES_OK) return res;
294
295
296
if(sign == LV_SIGNAL_CLEANUP) {
297
/*Nothing to cleanup. (No dynamically allocated memory in 'ext')*/
298
} else if(sign == LV_SIGNAL_GET_TYPE) {
299
lv_obj_type_t * buf = param;
300
uint8_t i;
301
for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/
302
if(buf->type[i] == NULL) break;
303
}
304
buf->type[i] = "lv_arc";
305
}
306
307
return res;
308
}
309
310
#endif
311
312