1 /**
2 * @file lv_obj.h
3 *
4 */
5
6 #ifndef LV_OBJ_H
7 #define LV_OBJ_H
8
9 #ifdef __cplusplus
10 extern "C" {
11 #endif
12
13 /*********************
14 * INCLUDES
15 *********************/
16 #include "../lv_conf_internal.h"
17
18 #include <stddef.h>
19 #include <stdbool.h>
20 #include "../misc/lv_style.h"
21 #include "../misc/lv_types.h"
22 #include "../misc/lv_area.h"
23 #include "../misc/lv_color.h"
24 #include "../misc/lv_assert.h"
25 #include "../hal/lv_hal.h"
26
27 /*********************
28 * DEFINES
29 *********************/
30
31 /**********************
32 * TYPEDEFS
33 **********************/
34
35 struct _lv_obj_t;
36
37 /**
38 * Possible states of a widget.
39 * OR-ed values are possible
40 */
41 enum {
42 LV_STATE_DEFAULT = 0x0000,
43 LV_STATE_CHECKED = 0x0001,
44 LV_STATE_FOCUSED = 0x0002,
45 LV_STATE_FOCUS_KEY = 0x0004,
46 LV_STATE_EDITED = 0x0008,
47 LV_STATE_HOVERED = 0x0010,
48 LV_STATE_PRESSED = 0x0020,
49 LV_STATE_SCROLLED = 0x0040,
50 LV_STATE_DISABLED = 0x0080,
51
52 LV_STATE_USER_1 = 0x1000,
53 LV_STATE_USER_2 = 0x2000,
54 LV_STATE_USER_3 = 0x4000,
55 LV_STATE_USER_4 = 0x8000,
56
57 LV_STATE_ANY = 0xFFFF, /**< Special value can be used in some functions to target all states*/
58 };
59
60 typedef uint16_t lv_state_t;
61
62 /**
63 * The possible parts of widgets.
64 * The parts can be considered as the internal building block of the widgets.
65 * E.g. slider = background + indicator + knob
66 * Not all parts are used by every widget
67 */
68 enum {
69 LV_PART_MAIN = 0x000000, /**< A background like rectangle*/
70 LV_PART_SCROLLBAR = 0x010000, /**< The scrollbar(s)*/
71 LV_PART_INDICATOR = 0x020000, /**< Indicator, e.g. for slider, bar, switch, or the tick box of the checkbox*/
72 LV_PART_KNOB = 0x030000, /**< Like handle to grab to adjust the value*/
73 LV_PART_SELECTED = 0x040000, /**< Indicate the currently selected option or section*/
74 LV_PART_ITEMS = 0x050000, /**< Used if the widget has multiple similar elements (e.g. table cells)*/
75 LV_PART_TICKS = 0x060000, /**< Ticks on scale e.g. for a chart or meter*/
76 LV_PART_CURSOR = 0x070000, /**< Mark a specific place e.g. for text area's cursor or on a chart*/
77
78 LV_PART_CUSTOM_FIRST = 0x080000, /**< Extension point for custom widgets*/
79
80 LV_PART_ANY = 0x0F0000, /**< Special value can be used in some functions to target all parts*/
81 };
82
83 typedef uint32_t lv_part_t;
84
85 /**
86 * On/Off features controlling the object's behavior.
87 * OR-ed values are possible
88 */
89 enum {
90 LV_OBJ_FLAG_HIDDEN = (1L << 0), /**< Make the object hidden. (Like it wasn't there at all)*/
91 LV_OBJ_FLAG_CLICKABLE = (1L << 1), /**< Make the object clickable by the input devices*/
92 LV_OBJ_FLAG_CLICK_FOCUSABLE = (1L << 2), /**< Add focused state to the object when clicked*/
93 LV_OBJ_FLAG_CHECKABLE = (1L << 3), /**< Toggle checked state when the object is clicked*/
94 LV_OBJ_FLAG_SCROLLABLE = (1L << 4), /**< Make the object scrollable*/
95 LV_OBJ_FLAG_SCROLL_ELASTIC = (1L << 5), /**< Allow scrolling inside but with slower speed*/
96 LV_OBJ_FLAG_SCROLL_MOMENTUM = (1L << 6), /**< Make the object scroll further when "thrown"*/
97 LV_OBJ_FLAG_SCROLL_ONE = (1L << 7), /**< Allow scrolling only one snappable children*/
98 LV_OBJ_FLAG_SCROLL_CHAIN_HOR = (1L << 8), /**< Allow propagating the horizontal scroll to a parent*/
99 LV_OBJ_FLAG_SCROLL_CHAIN_VER = (1L << 9), /**< Allow propagating the vertical scroll to a parent*/
100 LV_OBJ_FLAG_SCROLL_CHAIN = (LV_OBJ_FLAG_SCROLL_CHAIN_HOR | LV_OBJ_FLAG_SCROLL_CHAIN_VER),
101 LV_OBJ_FLAG_SCROLL_ON_FOCUS = (1L << 10), /**< Automatically scroll object to make it visible when focused*/
102 LV_OBJ_FLAG_SCROLL_WITH_ARROW = (1L << 11), /**< Allow scrolling the focused object with arrow keys*/
103 LV_OBJ_FLAG_SNAPPABLE = (1L << 12), /**< If scroll snap is enabled on the parent it can snap to this object*/
104 LV_OBJ_FLAG_PRESS_LOCK = (1L << 13), /**< Keep the object pressed even if the press slid from the object*/
105 LV_OBJ_FLAG_EVENT_BUBBLE = (1L << 14), /**< Propagate the events to the parent too*/
106 LV_OBJ_FLAG_GESTURE_BUBBLE = (1L << 15), /**< Propagate the gestures to the parent*/
107 LV_OBJ_FLAG_ADV_HITTEST = (1L << 16), /**< Allow performing more accurate hit (click) test. E.g. consider rounded corners.*/
108 LV_OBJ_FLAG_IGNORE_LAYOUT = (1L << 17), /**< Make the object position-able by the layouts*/
109 LV_OBJ_FLAG_FLOATING = (1L << 18), /**< Do not scroll the object when the parent scrolls and ignore layout*/
110 LV_OBJ_FLAG_OVERFLOW_VISIBLE = (1L << 19), /**< Do not clip the children's content to the parent's boundary*/
111
112 LV_OBJ_FLAG_LAYOUT_1 = (1L << 23), /**< Custom flag, free to use by layouts*/
113 LV_OBJ_FLAG_LAYOUT_2 = (1L << 24), /**< Custom flag, free to use by layouts*/
114
115 LV_OBJ_FLAG_WIDGET_1 = (1L << 25), /**< Custom flag, free to use by widget*/
116 LV_OBJ_FLAG_WIDGET_2 = (1L << 26), /**< Custom flag, free to use by widget*/
117 LV_OBJ_FLAG_USER_1 = (1L << 27), /**< Custom flag, free to use by user*/
118 LV_OBJ_FLAG_USER_2 = (1L << 28), /**< Custom flag, free to use by user*/
119 LV_OBJ_FLAG_USER_3 = (1L << 29), /**< Custom flag, free to use by user*/
120 LV_OBJ_FLAG_USER_4 = (1L << 30), /**< Custom flag, free to use by user*/
121
122 };
123
124 typedef uint32_t lv_obj_flag_t;
125
126 /**
127 * `type` field in `lv_obj_draw_part_dsc_t` if `class_p = lv_obj_class`
128 * Used in `LV_EVENT_DRAW_PART_BEGIN` and `LV_EVENT_DRAW_PART_END`
129 */
130 typedef enum {
131 LV_OBJ_DRAW_PART_RECTANGLE, /**< The main rectangle*/
132 LV_OBJ_DRAW_PART_BORDER_POST,/**< The border if style_border_post = true*/
133 LV_OBJ_DRAW_PART_SCROLLBAR, /**< The scrollbar*/
134 } lv_obj_draw_part_type_t;
135
136 #include "lv_obj_tree.h"
137 #include "lv_obj_pos.h"
138 #include "lv_obj_scroll.h"
139 #include "lv_obj_style.h"
140 #include "lv_obj_draw.h"
141 #include "lv_obj_class.h"
142 #include "lv_event.h"
143 #include "lv_group.h"
144
145 /**
146 * Make the base object's class publicly available.
147 */
148 extern const lv_obj_class_t lv_obj_class;
149
150 /**
151 * Special, rarely used attributes.
152 * They are allocated automatically if any elements is set.
153 */
154 typedef struct {
155 struct _lv_obj_t ** children; /**< Store the pointer of the children in an array.*/
156 uint32_t child_cnt; /**< Number of children*/
157 lv_group_t * group_p;
158
159 struct _lv_event_dsc_t * event_dsc; /**< Dynamically allocated event callback and user data array*/
160 lv_point_t scroll; /**< The current X/Y scroll offset*/
161
162 lv_coord_t ext_click_pad; /**< Extra click padding in all direction*/
163 lv_coord_t ext_draw_size; /**< EXTend the size in every direction for drawing.*/
164
165 lv_scrollbar_mode_t scrollbar_mode : 2; /**< How to display scrollbars*/
166 lv_scroll_snap_t scroll_snap_x : 2; /**< Where to align the snappable children horizontally*/
167 lv_scroll_snap_t scroll_snap_y : 2; /**< Where to align the snappable children vertically*/
168 lv_dir_t scroll_dir : 4; /**< The allowed scroll direction(s)*/
169 uint8_t event_dsc_cnt : 6; /**< Number of event callbacks stored in `event_dsc` array*/
170 uint8_t layer_type : 2; /**< Cache the layer type here. Element of @lv_intermediate_layer_type_t */
171 } _lv_obj_spec_attr_t;
172
173 typedef struct _lv_obj_t {
174 const lv_obj_class_t * class_p;
175 struct _lv_obj_t * parent;
176 _lv_obj_spec_attr_t * spec_attr;
177 _lv_obj_style_t * styles;
178 #if LV_USE_USER_DATA
179 void * user_data;
180 #endif
181 lv_area_t coords;
182 lv_obj_flag_t flags;
183 lv_state_t state;
184 uint16_t layout_inv : 1;
185 uint16_t readjust_scroll_after_layout : 1;
186 uint16_t scr_layout_inv : 1;
187 uint16_t skip_trans : 1;
188 uint16_t style_cnt : 6;
189 uint16_t h_layout : 1;
190 uint16_t w_layout : 1;
191 uint16_t being_deleted : 1;
192 } lv_obj_t;
193
194 /**********************
195 * GLOBAL PROTOTYPES
196 **********************/
197
198 /**
199 * Initialize LVGL library.
200 * Should be called before any other LVGL related function.
201 */
202 void lv_init(void);
203
204 #if LV_ENABLE_GC || !LV_MEM_CUSTOM
205
206 /**
207 * Deinit the 'lv' library
208 * Currently only implemented when not using custom allocators, or GC is enabled.
209 */
210 void lv_deinit(void);
211
212 #endif
213
214 /**
215 * Returns whether the 'lv' library is currently initialized
216 */
217 bool lv_is_initialized(void);
218
219 /**
220 * Create a base object (a rectangle)
221 * @param parent pointer to a parent object. If NULL then a screen will be created.
222 * @return pointer to the new object
223 */
224 lv_obj_t * lv_obj_create(lv_obj_t * parent);
225
226 /*=====================
227 * Setter functions
228 *====================*/
229
230 /**
231 * Set one or more flags
232 * @param obj pointer to an object
233 * @param f R-ed values from `lv_obj_flag_t` to set.
234 */
235 void lv_obj_add_flag(lv_obj_t * obj, lv_obj_flag_t f);
236
237 /**
238 * Clear one or more flags
239 * @param obj pointer to an object
240 * @param f OR-ed values from `lv_obj_flag_t` to set.
241 */
242 void lv_obj_clear_flag(lv_obj_t * obj, lv_obj_flag_t f);
243
244 /**
245 * Add one or more states to the object. The other state bits will remain unchanged.
246 * If specified in the styles, transition animation will be started from the previous state to the current.
247 * @param obj pointer to an object
248 * @param state the states to add. E.g `LV_STATE_PRESSED | LV_STATE_FOCUSED`
249 */
250 void lv_obj_add_state(lv_obj_t * obj, lv_state_t state);
251
252 /**
253 * Remove one or more states to the object. The other state bits will remain unchanged.
254 * If specified in the styles, transition animation will be started from the previous state to the current.
255 * @param obj pointer to an object
256 * @param state the states to add. E.g `LV_STATE_PRESSED | LV_STATE_FOCUSED`
257 */
258 void lv_obj_clear_state(lv_obj_t * obj, lv_state_t state);
259
260 /**
261 * Set the user_data field of the object
262 * @param obj pointer to an object
263 * @param user_data pointer to the new user_data.
264 */
265 #if LV_USE_USER_DATA
lv_obj_set_user_data(lv_obj_t * obj,void * user_data)266 static inline void lv_obj_set_user_data(lv_obj_t * obj, void * user_data)
267 {
268 obj->user_data = user_data;
269 }
270 #endif
271
272 /*=======================
273 * Getter functions
274 *======================*/
275
276 /**
277 * Check if a given flag or all the given flags are set on an object.
278 * @param obj pointer to an object
279 * @param f the flag(s) to check (OR-ed values can be used)
280 * @return true: all flags are set; false: not all flags are set
281 */
282 bool lv_obj_has_flag(const lv_obj_t * obj, lv_obj_flag_t f);
283
284 /**
285 * Check if a given flag or any of the flags are set on an object.
286 * @param obj pointer to an object
287 * @param f the flag(s) to check (OR-ed values can be used)
288 * @return true: at lest one flag flag is set; false: none of the flags are set
289 */
290 bool lv_obj_has_flag_any(const lv_obj_t * obj, lv_obj_flag_t f);
291
292 /**
293 * Get the state of an object
294 * @param obj pointer to an object
295 * @return the state (OR-ed values from `lv_state_t`)
296 */
297 lv_state_t lv_obj_get_state(const lv_obj_t * obj);
298
299 /**
300 * Check if the object is in a given state or not.
301 * @param obj pointer to an object
302 * @param state a state or combination of states to check
303 * @return true: `obj` is in `state`; false: `obj` is not in `state`
304 */
305 bool lv_obj_has_state(const lv_obj_t * obj, lv_state_t state);
306
307 /**
308 * Get the group of the object
309 * @param obj pointer to an object
310 * @return the pointer to group of the object
311 */
312 void * lv_obj_get_group(const lv_obj_t * obj);
313
314 /**
315 * Get the user_data field of the object
316 * @param obj pointer to an object
317 * @return the pointer to the user_data of the object
318 */
319 #if LV_USE_USER_DATA
lv_obj_get_user_data(lv_obj_t * obj)320 static inline void * lv_obj_get_user_data(lv_obj_t * obj)
321 {
322 return obj->user_data;
323 }
324 #endif
325
326 /*=======================
327 * Other functions
328 *======================*/
329
330 /**
331 * Allocate special data for an object if not allocated yet.
332 * @param obj pointer to an object
333 */
334 void lv_obj_allocate_spec_attr(lv_obj_t * obj);
335
336 /**
337 * Check the type of obj.
338 * @param obj pointer to an object
339 * @param class_p a class to check (e.g. `lv_slider_class`)
340 * @return true: `class_p` is the `obj` class.
341 */
342 bool lv_obj_check_type(const lv_obj_t * obj, const lv_obj_class_t * class_p);
343
344 /**
345 * Check if any object has a given class (type).
346 * It checks the ancestor classes too.
347 * @param obj pointer to an object
348 * @param class_p a class to check (e.g. `lv_slider_class`)
349 * @return true: `obj` has the given class
350 */
351 bool lv_obj_has_class(const lv_obj_t * obj, const lv_obj_class_t * class_p);
352
353 /**
354 * Get the class (type) of the object
355 * @param obj pointer to an object
356 * @return the class (type) of the object
357 */
358 const lv_obj_class_t * lv_obj_get_class(const lv_obj_t * obj);
359
360 /**
361 * Check if any object is still "alive".
362 * @param obj pointer to an object
363 * @return true: valid
364 */
365 bool lv_obj_is_valid(const lv_obj_t * obj);
366
367 /**
368 * Scale the given number of pixels (a distance or size) relative to a 160 DPI display
369 * considering the DPI of the `obj`'s display.
370 * It ensures that e.g. `lv_dpx(100)` will have the same physical size regardless to the
371 * DPI of the display.
372 * @param obj an object whose display's dpi should be considered
373 * @param n the number of pixels to scale
374 * @return `n x current_dpi/160`
375 */
lv_obj_dpx(const lv_obj_t * obj,lv_coord_t n)376 static inline lv_coord_t lv_obj_dpx(const lv_obj_t * obj, lv_coord_t n)
377 {
378 return _LV_DPX_CALC(lv_disp_get_dpi(lv_obj_get_disp(obj)), n);
379 }
380
381 /**********************
382 * MACROS
383 **********************/
384
385 #if LV_USE_ASSERT_OBJ
386 # define LV_ASSERT_OBJ(obj_p, obj_class) \
387 do { \
388 LV_ASSERT_MSG(obj_p != NULL, "The object is NULL"); \
389 LV_ASSERT_MSG(lv_obj_has_class(obj_p, obj_class) == true, "Incompatible object type."); \
390 LV_ASSERT_MSG(lv_obj_is_valid(obj_p) == true, "The object is invalid, deleted or corrupted?"); \
391 } while(0)
392 # else
393 # define LV_ASSERT_OBJ(obj_p, obj_class) do{}while(0)
394 #endif
395
396 #if LV_USE_LOG && LV_LOG_TRACE_OBJ_CREATE
397 # define LV_TRACE_OBJ_CREATE(...) LV_LOG_TRACE(__VA_ARGS__)
398 #else
399 # define LV_TRACE_OBJ_CREATE(...)
400 #endif
401
402 #ifdef __cplusplus
403 } /*extern "C"*/
404 #endif
405
406 #endif /*LV_OBJ_H*/
407