genlist: check item validation in GENLIST_ITEM_CHECK
[platform/upstream/elementary.git] / src / mobile_lib / elm_widget_genlist.h
1 #ifndef ELM_WIDGET_GENLIST_H
2 #define ELM_WIDGET_GENLIST_H
3
4 #include "elm_gen_common.h"
5 #include "Elementary.h"
6 #define BANDED_MAX_ITEMS 20
7
8 /* DO NOT USE THIS HEADER UNLESS YOU ARE PREPARED FOR BREAKING OF YOUR
9  * CODE. THIS IS ELEMENTARY'S INTERNAL WIDGET API (for now) AND IS NOT
10  * FINAL. CALL elm_widget_api_check(ELM_INTERNAL_API_VERSION) TO CHECK
11  * IT AT RUNTIME.
12  */
13
14 /**
15  * @internal
16  * @addtogroup Widget
17  * @{
18  *
19  * @section elm-genlist-class The Elementary Genlist Class
20  *
21  * Elementary, besides having the @ref Elm_Genlist widget, exposes its
22  * foundation -- the Elementary Genlist Class -- in order to create
23  * other widgets which are a genlist with some more logic on top.
24  */
25
26 /**
27  * Base widget smart data extended with genlist instance data.
28  */
29 typedef struct _Elm_Genlist_Data Elm_Genlist_Data;
30
31 typedef enum
32 {
33    ELM_GENLIST_TREE_EFFECT_NONE = 0,
34    ELM_GENLIST_TREE_EFFECT_EXPAND = 1,
35    ELM_GENLIST_TREE_EFFECT_CONTRACT = 2
36 } Elm_Genlist_Item_Move_Effect_Mode;
37
38 struct _Elm_Genlist_Data
39 {
40    struct
41      {
42         Elm_Gen_Item *it;
43         int dir;
44         Eina_List *move_items;
45         Ecore_Animator *anim;
46      } reorder;
47    struct
48      {
49         Eina_List                        *items;
50         Eina_List                        *pending_items;
51         Ecore_Animator                   *anim;
52         int                              cnt;
53      } del_fx;
54    struct
55      {
56         Eina_List                        *items;
57         Ecore_Animator                   *anim;
58         int                              cnt;
59      } add_fx;
60
61    /* longpress timeout. this value comes from _elm_config by
62     * default. this can be changed by
63     * elm_genlist_longpress_timeout_set() */
64    double                                longpress_timeout;
65    double                                start_time;
66
67    Eina_Inlist_Sorted_State             *state;
68    Evas_Object                          *hit_rect;
69    Evas_Object                          *pan_obj;
70
71    Evas_Object                          *focused_content;
72    Elm_Gen_Item                         *focused_item;
73
74    //Evas_Object                          *stack[2]; // stacking markers in pan
75    Evas_Object                          *obj; // the object itself
76
77    Eina_List                            *selected; /* a list of
78                                                     * selected
79                                                     * items */
80    //Eina_List                            *deselecting; /* a list of items currently being deselected */
81    Eina_List                            *group_items; /* a list of
82                                                        * groups index
83                                                        * items */
84    Eina_Inlist                          *items; /* an inlist of all items */
85    //Elm_Gen_Item                         *reorder_it; /* item currently
86    //                                                  * being
87    //                                                  * repositioned */
88
89    Elm_Object_Item                      *last_selected_item;
90    int                                   minw, minh;
91
92    unsigned int                          item_count;
93    Evas_Coord                            pan_x, pan_y;
94    Elm_Object_Select_Mode                select_mode;
95
96    Evas_Coord                            comp_y;
97    int                                   dir;
98    Eina_List                            *blocks_realized;
99    Eina_Inlist                          *blocks; /* an inlist of all
100                                                   * blocks. a block
101                                                   * consists of a
102                                                   * certain number of
103                                                   * items. maximum
104                                                   * number of items in
105                                                   * a block is
106                                                   * 'max_items_per_block'. */
107    Evas_Coord                            prev_viewport_w;
108    Ecore_Idle_Enterer                   *queue_idle_enterer;
109    Eina_List                            *queue;
110    Elm_Gen_Item                         *show_item, *mode_item, *expanded_item;
111    Eina_Inlist                          *item_cache; /* an inlist of
112                                                       * edje object it
113                                                       * cache. */
114
115    Elm_List_Mode                         mode;
116    Ecore_Timer                          *scr_hold_timer;
117    const char                           *decorate_it_type;
118    Evas_Coord                            prev_x, prev_y, prev_mx, prev_my;
119    Evas_Coord                            cur_x, cur_y, cur_mx, cur_my;
120
121    int                                   item_cache_count;
122    int                                   item_cache_max; /* maximum
123                                                           * number of
124                                                           * cached
125                                                           * items */
126    /* maximum number of items per block */
127    int                                   max_items_per_block;
128
129    Eina_Compare_Cb                       item_compare_cb;
130    Eina_Compare_Cb                       item_compare_data_cb;
131
132    /* a scrollto type which remembers where to scroll ex) in, top,
133     * middle */
134    Elm_Genlist_Item_Scrollto_Type        scroll_to_type;
135
136    Evas_Object                          *g_layer;
137    Elm_Gen_Item                         *g_item;
138    const char                           *g_type;
139    Eina_Hash                             *size_caches;
140    Evas_Coord                            finger_minw, finger_minh;
141    int                                   processed_sizes;
142    Ecore_Job                             *dummy_job;
143    Ecore_Timer                           *scr_timer;
144    Elm_Gen_Item                          *key_down_item;
145 // TIZEN ONLY(20150701) : Banded Color UX Feature
146    /*for banded ux*/
147    Elm_Gen_Item                          *top_drawn_item;
148    Evas_Object                           *banded_bg_rect; /* banded color
149                                                              background feature.
150                                                              enabled only
151                                                              un-scrollable. */
152 // TIZEN_ONLY
153    Elm_Gen_Item                         *highlighted_item;
154    Evas_Coord                            viewport_w, viewport_h;
155    Elm_Gen_Item                         *atspi_item_to_highlight;
156    // TIZEN_ONLY(20180326) : Atspi: enhance finding next and prev item on screen's edge
157    int                                   scroll_delta_y_backup;
158    //
159    Elm_Gen_Item                         *aligned_item;
160
161    Eina_List                            *filter_queue;
162    Eina_List                            *filtered_list;
163    void                                 *filter_data;
164    unsigned int                          processed_count;
165    unsigned int                          filtered_count;
166    Ecore_Idle_Enterer                   *queue_filter_enterer;
167    Elm_Genlist_Item_Scrollto_Type        focus_scrollto_type;
168
169    Elm_Gen_Item                          *adjusted_item;
170    Evas_Object                           *focus_bg;
171
172    /* this is genlist item Fx effect on Add/Remove */
173    Eina_Bool                             fx_mode : 1;
174    Eina_Bool                             scr_minw : 1;
175    Eina_Bool                             scr_minh : 1;
176    Eina_Bool                             select_on_focus_enabled : 1;
177    Eina_Bool                             decorate_all_mode : 1;
178    Eina_Bool                             reorder_mode : 1; /* a flag
179                                                             * for
180                                                             * reorder
181                                                             * mode
182                                                             * enable/disable */
183    Eina_Bool                             reorder_force : 1; /* a flag
184                                                              * for
185                                                              * reorder
186                                                              * by force */
187    /* this flag means genlist is supposed to be scrolled. if this flag
188     * is set to EINA_TRUE, genlist checks whether it's ok to scroll
189     * genlist now or not. */
190
191    Eina_Bool                             homogeneous : 1;
192    Eina_Bool                             realization_mode : 1;
193
194    Eina_Bool                             on_sub_del : 1;
195
196    /* a flag for items can be highlighted or not. by default this flag
197        * is true. */
198    Eina_Bool                             highlight : 1;
199    Eina_Bool                             h_bounce : 1;
200    Eina_Bool                             v_bounce : 1;
201    Eina_Bool                             bring_in : 1; /* a flag to
202                                                         * describe the
203                                                         * scroll
204                                                         * animation. (show,
205                                                         * bring in) */
206
207    /* this is set to EINA_TRUE when the item is re-queued. this
208     * happens when the item is un-queued but the rel item is still in
209     * the queue. this item will be processed later. */
210    Eina_Bool                             requeued : 1;
211    Eina_Bool                             multi : 1; /* a flag for item
212                                                      * multi
213                                                      * selection */
214    Eina_Bool                             sorting : 1;
215    Eina_Bool                             calc_done : 1;
216    Eina_Bool                             was_selected : 1;
217    Eina_Bool                             no_cache : 1;
218    Eina_Bool                             on_hold : 1; /* a flag for check
219                                                        * item selected or
220                                                        * not */
221
222 // TIZEN ONLY(20150701) : Banded Color UX Feature
223    /*for banded ux*/
224    Eina_Bool                             banded_bg_on : 1;
225 // TIZEN_ONLY
226
227    Eina_Bool                             is_access : 1;
228    Eina_Bool                             filter : 1;
229    Eina_Bool                             unhighlight_skip: 1;
230    Eina_Bool                             bottom_margin_enabled : 1;
231    Eina_Bool                             unhighlighted : 1;
232    Eina_Bool                             focus_on_selection_enabled : 1;
233 };
234
235 typedef struct _Item_Block Item_Block;
236 typedef struct _Item_Cache Item_Cache;
237 typedef struct _Elm_Genlist_Filter Elm_Genlist_Filter;
238
239 struct Elm_Gen_Item_Type
240 {
241    Elm_Gen_Item           *it;
242
243    Elm_Genlist_Data       *wsd;
244
245    Item_Block             *block;
246    Eina_List              *items;
247    Evas_Coord              w, h, minw, minh;
248    Elm_Gen_Item           *group_item;
249    Elm_Genlist_Item_Type   type;
250    Eina_List              *deco_it_texts, *deco_it_contents;
251    Eina_List              *deco_all_texts, *deco_all_contents;
252    Eina_List              *flip_contents, *flip_content_objs;
253    Ecore_Timer            *swipe_timer;
254    Evas_Coord              scrl_x, scrl_y, old_scrl_y;
255
256    Elm_Gen_Item           *rel;
257    Eina_List              *rel_revs; // FIXME: find better way not to use this
258    Evas_Object            *deco_it_view;
259    int                     expanded_depth;
260    int                     order_num_in;
261
262 // TIZEN ONLY(20150701) : Banded Color UX Feature
263    int                     banded_color_index;
264    Evas_Object            *banded_bg;
265    Ecore_Animator         *banded_anim;
266 // TIZEN ONLY
267
268    Evas_Coord              reorder_offset;
269
270    Ecore_Timer             *highlight_timer;
271    Evas_Object             *proxy;
272
273    Eina_Bool               decorate_all_item_realized : 1;
274    Eina_Bool               tree_effect_finished : 1; /* tree effect */
275    Eina_Bool               move_effect_enabled : 1;
276    Eina_Bool               tree_effect_hide_me : 1; /* item hide for
277                                                     * tree effect */
278
279    Eina_Bool               stacking_even : 1;
280    Eina_Bool               want_realize : 1;
281    Eina_Bool               nocache_once : 1; /* do not use cache for
282                                               * this item only once */
283    Eina_Bool               nostacking : 1;
284    Eina_Bool               expanded : 1;
285    Eina_Bool               mincalcd : 1;
286    Eina_Bool               updateme : 1;
287    Eina_Bool               nocache : 1; /* do not use cache for this item */
288    Eina_Bool               queued : 1;
289    Eina_Bool               before : 1;
290    Eina_Bool               show_me : 1;
291
292    Eina_Bool               is_prepend : 1;
293    Eina_Bool               calc_done : 1;
294    Eina_Bool               multiline : 1;
295    Eina_Bool               resized : 1;
296 };
297
298
299 struct _Item_Block
300 {
301    EINA_INLIST;
302
303    int                     count;
304    int                     num;
305    int                     reorder_offset;
306    Elm_Genlist_Data       *sd;
307    Eina_List              *items;
308    Evas_Coord              x, y, w, h, minw, minh;
309    int                     position;
310    int                     item_position_stamp;
311
312    Eina_Bool               position_update : 1;
313    Eina_Bool               want_unrealize : 1;
314    Eina_Bool               must_recalc : 1;
315    Eina_Bool               realized : 1;
316    Eina_Bool               updateme : 1;
317    Eina_Bool               changed : 1;
318    Eina_Bool               show_me : 1;
319
320    Eina_Bool               calc_done : 1;
321 };
322
323 struct _Item_Cache
324 {
325    EINA_INLIST;
326
327    Evas_Object *base_view, *spacer;
328
329    const Elm_Genlist_Item_Class  *item_class; // it->itc
330    Eina_Bool    multiline;
331    Eina_List   *contents; // content objects for reusing
332    Eina_Bool    selected : 1; // it->selected
333    Eina_Bool    disabled : 1; // it->disabled
334    Eina_Bool    expanded : 1; // it->item->expanded
335    Eina_Bool    tree : 1; // it->group
336 };
337
338 typedef struct _Elm_Genlist_Pan_Data Elm_Genlist_Pan_Data;
339 struct _Elm_Genlist_Pan_Data
340 {
341    Evas_Object            *wobj;
342    Elm_Genlist_Data       *wsd;
343    Ecore_Job              *resize_job;
344 };
345
346 /**
347  * Structure added to genlist for internal filter iterator implementation
348  * Can be extended to genlist as a whole in future if needed.
349  */
350 struct _Elm_Genlist_Filter
351 {
352    Eina_Iterator iterator;
353    const Eina_Inlist *head;
354    const Eina_Inlist *current;
355 };
356
357
358 /**
359  * @}
360  */
361
362 #define GL_IT(_it) (_it->item)
363
364 #define ELM_GENLIST_DATA_GET(o, sd) \
365   Elm_Genlist_Data * sd = eo_data_scope_get(o, ELM_GENLIST_CLASS)
366
367 #define ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd) \
368   Elm_Genlist_Data * sd = GL_IT(it)->wsd
369
370 #define ELM_GENLIST_PAN_DATA_GET(o, sd) \
371   Elm_Genlist_Pan_Data * sd = eo_data_scope_get(o, ELM_GENLIST_PAN_CLASS)
372
373 #define ELM_GENLIST_DATA_GET_OR_RETURN(o, ptr)       \
374   ELM_GENLIST_DATA_GET(o, ptr);                      \
375   if (EINA_UNLIKELY(!ptr))                           \
376     {                                                \
377        CRI("No widget data for object %p (%s)",      \
378            o, evas_object_type_get(o));              \
379        return;                                       \
380     }
381
382 #define ELM_GENLIST_DATA_GET_OR_RETURN_VAL(o, ptr, val) \
383   ELM_GENLIST_DATA_GET(o, ptr);                         \
384   if (EINA_UNLIKELY(!ptr))                              \
385     {                                                   \
386        CRI("No widget data for object %p (%s)",         \
387            o, evas_object_type_get(o));                 \
388        return val;                                      \
389     }
390
391 #define ELM_GENLIST_CHECK(obj)                              \
392   if (EINA_UNLIKELY(!eo_isa((obj), ELM_GENLIST_CLASS))) \
393     return
394
395 #define ELM_GENLIST_ITEM_CHECK(it)                          \
396   if (!it) return; \
397   ELM_WIDGET_ITEM_CHECK_OR_RETURN(it->base, ); \
398   ELM_GENLIST_CHECK(it->base->widget);
399
400 #define ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, ...)                      \
401   if (!it) return __VA_ARGS__; \
402   ELM_WIDGET_ITEM_CHECK_OR_RETURN(it->base, __VA_ARGS__); \
403   ELM_GENLIST_CHECK(it->base->widget) __VA_ARGS__;
404
405 #define ELM_GENLIST_ITEM_CHECK_OR_GOTO(it, label)              \
406   if (!it) goto label; \
407   ELM_WIDGET_ITEM_CHECK_OR_GOTO(it->base, label); \
408   if (!it->base->widget || !eo_isa                              \
409         ((it->base->widget), ELM_GENLIST_CLASS)) goto label;
410
411 #define ELM_GENLIST_ITEM_DATA_GET(o, sd) \
412   Elm_Gen_Item* sd = eo_data_scope_get(o, ELM_GENLIST_ITEM_CLASS)
413
414 #define ELM_GENLIST_FILTER_ITERATOR_ITEM_GET(ptr,                 \
415                                   type) ((type *)((char *)ptr - \
416                                                   offsetof(type, __in_list)))
417
418 #endif