1 /**
2  * @file lv_group.h
3  *
4  */
5 
6 #ifndef LV_GROUP_H
7 #define LV_GROUP_H
8 
9 #ifdef __cplusplus
10 extern "C" {
11 #endif
12 
13 /*********************
14  *      INCLUDES
15  *********************/
16 
17 #include "../lv_conf_internal.h"
18 
19 #include <stdint.h>
20 #include <stdbool.h>
21 #include "../misc/lv_ll.h"
22 #include "../misc/lv_types.h"
23 
24 /*********************
25  *      DEFINES
26  *********************/
27 /*Predefined keys to control the focused object via lv_group_send(group, c)*/
28 
29 enum {
30     LV_KEY_UP        = 17,  /*0x11*/
31     LV_KEY_DOWN      = 18,  /*0x12*/
32     LV_KEY_RIGHT     = 19,  /*0x13*/
33     LV_KEY_LEFT      = 20,  /*0x14*/
34     LV_KEY_ESC       = 27,  /*0x1B*/
35     LV_KEY_DEL       = 127, /*0x7F*/
36     LV_KEY_BACKSPACE = 8,   /*0x08*/
37     LV_KEY_ENTER     = 10,  /*0x0A, '\n'*/
38     LV_KEY_NEXT      = 9,   /*0x09, '\t'*/
39     LV_KEY_PREV      = 11,  /*0x0B, '*/
40     LV_KEY_HOME      = 2,   /*0x02, STX*/
41     LV_KEY_END       = 3,   /*0x03, ETX*/
42 };
43 typedef uint8_t lv_key_t;
44 
45 /**********************
46  *      TYPEDEFS
47  **********************/
48 
49 struct _lv_obj_t;
50 struct _lv_group_t;
51 
52 typedef void (*lv_group_focus_cb_t)(struct _lv_group_t *);
53 typedef void (*lv_group_edge_cb_t)(struct _lv_group_t *, bool);
54 
55 /**
56  * Groups can be used to logically hold objects so that they can be individually focused.
57  * They are NOT for laying out objects on a screen (try layouts for that).
58  */
59 typedef struct _lv_group_t {
60     lv_ll_t obj_ll;        /**< Linked list to store the objects in the group*/
61     struct _lv_obj_t ** obj_focus; /**< The object in focus*/
62 
63     lv_group_focus_cb_t focus_cb;              /**< A function to call when a new object is focused (optional)*/
64     lv_group_edge_cb_t  edge_cb;               /**< A function to call when an edge is reached, no more focus
65                                                     targets are available in this direction (to allow edge feedback
66                                                     like a sound or a scroll bounce) */
67 
68 #if LV_USE_USER_DATA
69     void * user_data;
70 #endif
71 
72     uint8_t frozen : 1;         /**< 1: can't focus to new object*/
73     uint8_t editing : 1;        /**< 1: Edit mode, 0: Navigate mode*/
74     uint8_t refocus_policy : 1; /**< 1: Focus prev if focused on deletion. 0: Focus next if focused on
75                                    deletion.*/
76     uint8_t wrap : 1;           /**< 1: Focus next/prev can wrap at end of list. 0: Focus next/prev stops at end
77                                    of list.*/
78 } lv_group_t;
79 
80 typedef enum {
81     LV_GROUP_REFOCUS_POLICY_NEXT = 0,
82     LV_GROUP_REFOCUS_POLICY_PREV = 1
83 } lv_group_refocus_policy_t;
84 
85 /**********************
86  * GLOBAL PROTOTYPES
87  **********************/
88 
89 /**
90  * Init. the group module
91  * @remarks Internal function, do not call directly.
92  */
93 void _lv_group_init(void);
94 
95 /**
96  * Create a new object group
97  * @return          pointer to the new object group
98  */
99 lv_group_t * lv_group_create(void);
100 
101 /**
102  * Delete a group object
103  * @param group     pointer to a group
104  */
105 void lv_group_del(lv_group_t * group);
106 
107 /**
108  * Set a default group. New object are added to this group if it's enabled in their class with `add_to_def_group = true`
109  * @param group     pointer to a group (can be `NULL`)
110  */
111 void lv_group_set_default(lv_group_t * group);
112 
113 /**
114  * Get the default group
115  * @return          pointer to the default group
116  */
117 lv_group_t * lv_group_get_default(void);
118 
119 /**
120  * Add an object to a group
121  * @param group     pointer to a group
122  * @param obj       pointer to an object to add
123  */
124 void lv_group_add_obj(lv_group_t * group, struct _lv_obj_t * obj);
125 
126 /**
127  * Swap 2 object in a group. The object must be in the same group
128  * @param obj1  pointer to an object
129  * @param obj2  pointer to an other object
130  */
131 void lv_group_swap_obj(struct _lv_obj_t * obj1, struct _lv_obj_t * obj2);
132 
133 /**
134  * Remove an object from its group
135  * @param obj       pointer to an object to remove
136  */
137 void lv_group_remove_obj(struct _lv_obj_t * obj);
138 
139 /**
140  * Remove all objects from a group
141  * @param group     pointer to a group
142  */
143 void lv_group_remove_all_objs(lv_group_t * group);
144 
145 /**
146  * Focus on an object (defocus the current)
147  * @param obj       pointer to an object to focus on
148  */
149 void lv_group_focus_obj(struct _lv_obj_t * obj);
150 
151 /**
152  * Focus the next object in a group (defocus the current)
153  * @param group     pointer to a group
154  */
155 void lv_group_focus_next(lv_group_t * group);
156 
157 /**
158  * Focus the previous object in a group (defocus the current)
159  * @param group     pointer to a group
160  */
161 void lv_group_focus_prev(lv_group_t * group);
162 
163 /**
164  * Do not let to change the focus from the current object
165  * @param group     pointer to a group
166  * @param en        true: freeze, false: release freezing (normal mode)
167  */
168 void lv_group_focus_freeze(lv_group_t * group, bool en);
169 
170 /**
171  * Send a control character to the focuses object of a group
172  * @param group     pointer to a group
173  * @param c         a character (use LV_KEY_.. to navigate)
174  * @return          result of focused object in group.
175  */
176 lv_res_t lv_group_send_data(lv_group_t * group, uint32_t c);
177 
178 /**
179  * Set a function for a group which will be called when a new object is focused
180  * @param group         pointer to a group
181  * @param focus_cb      the call back function or NULL if unused
182  */
183 void lv_group_set_focus_cb(lv_group_t * group, lv_group_focus_cb_t focus_cb);
184 
185 /**
186  * Set a function for a group which will be called when a focus edge is reached
187  * @param group         pointer to a group
188  * @param edge_cb      the call back function or NULL if unused
189  */
190 void lv_group_set_edge_cb(lv_group_t * group, lv_group_edge_cb_t edge_cb);
191 
192 /**
193  * Set whether the next or previous item in a group is focused if the currently focused obj is
194  * deleted.
195  * @param group         pointer to a group
196  * @param policy        new refocus policy enum
197  */
198 void lv_group_set_refocus_policy(lv_group_t * group, lv_group_refocus_policy_t policy);
199 
200 /**
201  * Manually set the current mode (edit or navigate).
202  * @param group         pointer to group
203  * @param edit          true: edit mode; false: navigate mode
204  */
205 void lv_group_set_editing(lv_group_t * group, bool edit);
206 
207 /**
208  * Set whether focus next/prev will allow wrapping from first->last or last->first object.
209  * @param group         pointer to group
210  * @param               en true: wrapping enabled; false: wrapping disabled
211  */
212 void lv_group_set_wrap(lv_group_t * group, bool en);
213 
214 /**
215  * Get the focused object or NULL if there isn't one
216  * @param group         pointer to a group
217  * @return              pointer to the focused object
218  */
219 struct _lv_obj_t * lv_group_get_focused(const lv_group_t * group);
220 
221 /**
222  * Get the focus callback function of a group
223  * @param group pointer to a group
224  * @return the call back function or NULL if not set
225  */
226 lv_group_focus_cb_t lv_group_get_focus_cb(const lv_group_t * group);
227 
228 /**
229  * Get the edge callback function of a group
230  * @param group pointer to a group
231  * @return the call back function or NULL if not set
232  */
233 lv_group_edge_cb_t lv_group_get_edge_cb(const lv_group_t * group);
234 
235 /**
236  * Get the current mode (edit or navigate).
237  * @param group         pointer to group
238  * @return              true: edit mode; false: navigate mode
239  */
240 bool lv_group_get_editing(const lv_group_t * group);
241 
242 /**
243  * Get whether focus next/prev will allow wrapping from first->last or last->first object.
244  * @param group         pointer to group
245  * @param               en true: wrapping enabled; false: wrapping disabled
246  */
247 bool lv_group_get_wrap(lv_group_t * group);
248 
249 /**
250  * Get the number of object in the group
251  * @param group         pointer to a group
252  * @return              number of objects in the group
253  */
254 uint32_t lv_group_get_obj_count(lv_group_t * group);
255 
256 /**********************
257  *      MACROS
258  **********************/
259 
260 #ifdef __cplusplus
261 } /*extern "C"*/
262 #endif
263 
264 #endif /*LV_GROUP_H*/
265