Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
CTCaer
GitHub Repository: CTCaer/hekate
Path: blob/master/bdk/libs/lvgl/lv_objx/lv_imgbtn.c
1476 views
1
/**
2
* @file lv_imgbtn.c
3
*
4
*/
5
6
/*********************
7
* INCLUDES
8
*********************/
9
#include "lv_imgbtn.h"
10
#if USE_LV_IMGBTN != 0
11
12
/*********************
13
* DEFINES
14
*********************/
15
16
/**********************
17
* TYPEDEFS
18
**********************/
19
20
/**********************
21
* STATIC PROTOTYPES
22
**********************/
23
static bool lv_imgbtn_design(lv_obj_t * imgbtn, const lv_area_t * mask, lv_design_mode_t mode);
24
static lv_res_t lv_imgbtn_signal(lv_obj_t * imgbtn, lv_signal_t sign, void * param);
25
static void refr_img(lv_obj_t * imgbtn);
26
27
/**********************
28
* STATIC VARIABLES
29
**********************/
30
static lv_signal_func_t ancestor_signal;
31
static lv_design_func_t ancestor_design;
32
33
/**********************
34
* MACROS
35
**********************/
36
37
/**********************
38
* GLOBAL FUNCTIONS
39
**********************/
40
41
/**
42
* Create a image button object
43
* @param par pointer to an object, it will be the parent of the new image button
44
* @param copy pointer to a image button object, if not NULL then the new object will be copied from it
45
* @return pointer to the created image button
46
*/
47
lv_obj_t * lv_imgbtn_create(lv_obj_t * par, const lv_obj_t * copy)
48
{
49
LV_LOG_TRACE("image button create started");
50
51
/*Create the ancestor of image button*/
52
lv_obj_t * new_imgbtn = lv_btn_create(par, copy);
53
lv_mem_assert(new_imgbtn);
54
if(new_imgbtn == NULL) return NULL;
55
56
/*Allocate the image button type specific extended data*/
57
lv_imgbtn_ext_t * ext = lv_obj_allocate_ext_attr(new_imgbtn, sizeof(lv_imgbtn_ext_t));
58
lv_mem_assert(ext);
59
if(ext == NULL) return NULL;
60
if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_func(new_imgbtn);
61
if(ancestor_design == NULL) ancestor_design = lv_obj_get_design_func(new_imgbtn);
62
63
/*Initialize the allocated 'ext' */
64
#if LV_IMGBTN_TILED == 0
65
memset(ext->img_src, 0, sizeof(ext->img_src));
66
#else
67
memset(ext->img_src_left, 0, sizeof(ext->img_src_left));
68
memset(ext->img_src_mid, 0, sizeof(ext->img_src_mid));
69
memset(ext->img_src_right, 0, sizeof(ext->img_src_right));
70
#endif
71
72
ext->act_cf = LV_IMG_CF_UNKOWN;
73
74
/*The signal and design functions are not copied so set them here*/
75
lv_obj_set_signal_func(new_imgbtn, lv_imgbtn_signal);
76
lv_obj_set_design_func(new_imgbtn, lv_imgbtn_design);
77
78
/*Init the new image button image button*/
79
if(copy == NULL) {
80
81
}
82
/*Copy an existing image button*/
83
else {
84
lv_imgbtn_ext_t * copy_ext = lv_obj_get_ext_attr(copy);
85
#if LV_IMGBTN_TILED == 0
86
memcpy(ext->img_src, copy_ext->img_src, sizeof(ext->img_src));
87
#else
88
memcpy(ext->img_src_left, copy_ext->img_src_left, sizeof(ext->img_src_left));
89
memcpy(ext->img_src_mid, copy_ext->img_src_mid, sizeof(ext->img_src_mid));
90
memcpy(ext->img_src_right, copy_ext->img_src_right, sizeof(ext->img_src_right));
91
#endif
92
/*Refresh the style with new signal function*/
93
lv_obj_refresh_style(new_imgbtn);
94
}
95
96
LV_LOG_INFO("image button created");
97
98
return new_imgbtn;
99
}
100
101
/*=====================
102
* Setter functions
103
*====================*/
104
105
#if LV_IMGBTN_TILED == 0
106
/**
107
* Set images for a state of the image button
108
* @param imgbtn pointer to an image button object
109
* @param state for which state set the new image (from `lv_btn_state_t`) `
110
* @param src pointer to an image source (a C array or path to a file)
111
*/
112
void lv_imgbtn_set_src(lv_obj_t * imgbtn, lv_btn_state_t state, const void * src)
113
{
114
lv_imgbtn_ext_t * ext = lv_obj_get_ext_attr(imgbtn);
115
116
ext->img_src[state] = src;
117
118
refr_img(imgbtn);
119
}
120
121
#else
122
/**
123
* Set images for a state of the image button
124
* @param imgbtn pointer to an image button object
125
* @param state for which state set the new image (from `lv_btn_state_t`) `
126
* @param src_left pointer to an image source for the left side of the button (a C array or path to a file)
127
* @param src_mid pointer to an image source for the middle of the button (ideally 1px wide) (a C array or path to a file)
128
* @param src_right pointer to an image source for the right side of the button (a C array or path to a file)
129
*/
130
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)
131
{
132
lv_imgbtn_ext_t * ext = lv_obj_get_ext_attr(imgbtn);
133
134
ext->img_src_left[state] = src_left;
135
ext->img_src_mid[state] = src_mid;
136
ext->img_src_right[state] = src_right;
137
138
refr_img(imgbtn);
139
}
140
141
#endif
142
143
/**
144
* Set a style of a image button.
145
* @param imgbtn pointer to image button object
146
* @param type which style should be set
147
* @param style pointer to a style
148
*/
149
void lv_imgbtn_set_style(lv_obj_t * imgbtn, lv_imgbtn_style_t type, lv_style_t * style)
150
{
151
lv_btn_set_style(imgbtn, type, style);
152
}
153
154
/*=====================
155
* Getter functions
156
*====================*/
157
158
#if LV_IMGBTN_TILED == 0
159
/**
160
* Get the images in a given state
161
* @param imgbtn pointer to an image button object
162
* @param state the state where to get the image (from `lv_btn_state_t`) `
163
* @return pointer to an image source (a C array or path to a file)
164
*/
165
const void * lv_imgbtn_get_src(lv_obj_t * imgbtn, lv_btn_state_t state)
166
{
167
lv_imgbtn_ext_t * ext = lv_obj_get_ext_attr(imgbtn);
168
169
return ext->img_src[state];
170
}
171
#else
172
173
/**
174
* Get the left image in a given state
175
* @param imgbtn pointer to an image button object
176
* @param state the state where to get the image (from `lv_btn_state_t`) `
177
* @return pointer to the left image source (a C array or path to a file)
178
*/
179
const void * lv_imgbtn_get_src_left(lv_obj_t * imgbtn, lv_btn_state_t state)
180
{
181
lv_imgbtn_ext_t * ext = lv_obj_get_ext_attr(imgbtn);
182
183
return ext->img_src_left[state];
184
}
185
186
/**
187
* Get the middle image in a given state
188
* @param imgbtn pointer to an image button object
189
* @param state the state where to get the image (from `lv_btn_state_t`) `
190
* @return pointer to the middle image source (a C array or path to a file)
191
*/
192
const void * lv_imgbtn_get_src_middle(lv_obj_t * imgbtn, lv_btn_state_t state)
193
{
194
lv_imgbtn_ext_t * ext = lv_obj_get_ext_attr(imgbtn);
195
196
return ext->img_src_mid[state];
197
}
198
199
/**
200
* Get the right image in a given state
201
* @param imgbtn pointer to an image button object
202
* @param state the state where to get the image (from `lv_btn_state_t`) `
203
* @return pointer to the left image source (a C array or path to a file)
204
*/
205
const void * lv_imgbtn_get_src_right(lv_obj_t * imgbtn, lv_btn_state_t state)
206
{
207
lv_imgbtn_ext_t * ext = lv_obj_get_ext_attr(imgbtn);
208
209
return ext->img_src_right[state];
210
}
211
212
#endif
213
214
/**
215
* Get style of a image button.
216
* @param imgbtn pointer to image button object
217
* @param type which style should be get
218
* @return style pointer to the style
219
*/
220
lv_style_t * lv_imgbtn_get_style(const lv_obj_t * imgbtn, lv_imgbtn_style_t type)
221
{
222
return lv_btn_get_style(imgbtn, type);
223
}
224
225
/*=====================
226
* Other functions
227
*====================*/
228
229
/*
230
* New object specific "other" functions come here
231
*/
232
233
/**********************
234
* STATIC FUNCTIONS
235
**********************/
236
237
/**
238
* Handle the drawing related tasks of the image buttons
239
* @param imgbtn pointer to an object
240
* @param mask the object will be drawn only in this area
241
* @param mode LV_DESIGN_COVER_CHK: only check if the object fully covers the 'mask_p' area
242
* (return 'true' if yes)
243
* LV_DESIGN_DRAW: draw the object (always return 'true')
244
* LV_DESIGN_DRAW_POST: drawing after every children are drawn
245
* @param return true/false, depends on 'mode'
246
*/
247
static bool lv_imgbtn_design(lv_obj_t * imgbtn, const lv_area_t * mask, lv_design_mode_t mode)
248
{
249
/*Return false if the object is not covers the mask_p area*/
250
if(mode == LV_DESIGN_COVER_CHK) {
251
lv_imgbtn_ext_t * ext = lv_obj_get_ext_attr(imgbtn);
252
bool cover = false;
253
if(ext->act_cf == LV_IMG_CF_TRUE_COLOR || ext->act_cf == LV_IMG_CF_RAW) {
254
cover = lv_area_is_in(mask, &imgbtn->coords);
255
}
256
257
return cover;
258
}
259
/*Draw the object*/
260
else if(mode == LV_DESIGN_DRAW_MAIN) {
261
/*Just draw an image*/
262
lv_imgbtn_ext_t * ext = lv_obj_get_ext_attr(imgbtn);
263
lv_btn_state_t state = lv_imgbtn_get_state(imgbtn);
264
lv_style_t * style = lv_imgbtn_get_style(imgbtn, state);
265
lv_opa_t opa_scale = lv_obj_get_opa_scale(imgbtn);
266
267
#if LV_IMGBTN_TILED == 0
268
const void * src = ext->img_src[state];
269
lv_draw_img(&imgbtn->coords, mask, src, style, opa_scale);
270
#else
271
const void * src;
272
lv_img_header_t header;
273
lv_area_t coords;
274
lv_coord_t left_w = 0;
275
lv_coord_t right_w = 0;
276
277
src = ext->img_src_left[state];
278
if(src) {
279
lv_img_dsc_get_info(src, &header);
280
left_w = header.w;
281
coords.x1 = imgbtn->coords.x1;
282
coords.y1 = imgbtn->coords.y1;
283
coords.x2 = coords.x1 + header.w - 1;
284
coords.y2 = coords.y1 + header.h - 1;
285
lv_draw_img(&coords, mask, src, style, opa_scale);
286
}
287
288
src = ext->img_src_right[state];
289
if(src) {
290
lv_img_dsc_get_info(src, &header);
291
right_w = header.w;
292
coords.x1 = imgbtn->coords.x2 - header.w + 1;
293
coords.y1 = imgbtn->coords.y1;
294
coords.x2 = imgbtn->coords.x2;
295
coords.y2 = imgbtn->coords.y1 + header.h - 1;
296
lv_draw_img(&coords, mask, src, style, opa_scale);
297
}
298
299
src = ext->img_src_mid[state];
300
if(src) {
301
lv_coord_t obj_w = lv_obj_get_width(imgbtn);
302
lv_coord_t i;
303
lv_img_dsc_get_info(src, &header);
304
305
coords.x1 = imgbtn->coords.x1 + left_w ;
306
coords.y1 = imgbtn->coords.y1;
307
coords.x2 = coords.x1 + header.w - 1;
308
coords.y2 = imgbtn->coords.y1 + header.h - 1;
309
310
for(i = 0; i < obj_w - right_w - left_w; i += header.w) {
311
lv_draw_img(&coords, mask, src, style, opa_scale);
312
coords.x1 = coords.x2 + 1;
313
coords.x2 += header.w;
314
}
315
}
316
317
318
#endif
319
320
}
321
/*Post draw when the children are drawn*/
322
else if(mode == LV_DESIGN_DRAW_POST) {
323
324
}
325
326
return true;
327
}
328
329
/**
330
* Signal function of the image button
331
* @param imgbtn pointer to a image button object
332
* @param sign a signal type from lv_signal_t enum
333
* @param param pointer to a signal specific variable
334
* @return LV_RES_OK: the object is not deleted in the function; LV_RES_INV: the object is deleted
335
*/
336
static lv_res_t lv_imgbtn_signal(lv_obj_t * imgbtn, lv_signal_t sign, void * param)
337
{
338
lv_res_t res;
339
340
/* Include the ancient signal function */
341
res = ancestor_signal(imgbtn, sign, param);
342
if(res != LV_RES_OK) return res;
343
344
if(sign == LV_SIGNAL_STYLE_CHG) {
345
/* If the style changed then the button was clicked, released etc. so probably the state was changed as well
346
* Set the new image for the new state.*/
347
refr_img(imgbtn);
348
} else if(sign == LV_SIGNAL_CLEANUP) {
349
/*Nothing to cleanup. (No dynamically allocated memory in 'ext')*/
350
} else if(sign == LV_SIGNAL_GET_TYPE) {
351
lv_obj_type_t * buf = param;
352
uint8_t i;
353
for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/
354
if(buf->type[i] == NULL) break;
355
}
356
buf->type[i] = "lv_imgbtn";
357
}
358
359
return res;
360
}
361
362
363
static void refr_img(lv_obj_t * imgbtn)
364
{
365
lv_imgbtn_ext_t * ext = lv_obj_get_ext_attr(imgbtn);
366
lv_btn_state_t state = lv_imgbtn_get_state(imgbtn);
367
lv_img_header_t header;
368
369
#if LV_IMGBTN_TILED == 0
370
const void * src = ext->img_src[state];
371
#else
372
const void * src = ext->img_src_mid[state];
373
#endif
374
375
lv_res_t info_res;
376
info_res = lv_img_dsc_get_info(src, &header);
377
if(info_res == LV_RES_OK) {
378
ext->act_cf = header.cf;
379
#if LV_IMGBTN_TILED == 0
380
lv_obj_set_size(imgbtn, header.w, header.h);
381
#else
382
lv_obj_set_height(imgbtn, header.h);
383
#endif
384
} else {
385
ext->act_cf = LV_IMG_CF_UNKOWN;
386
}
387
388
lv_obj_invalidate(imgbtn);
389
}
390
391
#endif
392
393