genlist: check item validation in GENLIST_ITEM_CHECK
[platform/upstream/elementary.git] / src / 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
7 /* DO NOT USE THIS HEADER UNLESS YOU ARE PREPARED FOR BREAKING OF YOUR
8  * CODE. THIS IS ELEMENTARY'S INTERNAL WIDGET API (for now) AND IS NOT
9  * FINAL. CALL elm_widget_api_check(ELM_INTERNAL_API_VERSION) TO CHECK
10  * IT AT RUNTIME.
11  */
12
13 /**
14  * @internal
15  * @addtogroup Widget
16  * @{
17  *
18  * @section elm-genlist-class The Elementary Genlist Class
19  *
20  * Elementary, besides having the @ref Elm_Genlist widget, exposes its
21  * foundation -- the Elementary Genlist Class -- in order to create
22  * other widgets which are a genlist with some more logic on top.
23  */
24
25 /**
26  * Base widget smart data extended with genlist instance data.
27  */
28 typedef struct _Elm_Genlist_Data Elm_Genlist_Data;
29
30 typedef enum
31 {
32    ELM_GENLIST_TREE_EFFECT_NONE = 0,
33    ELM_GENLIST_TREE_EFFECT_EXPAND = 1,
34    ELM_GENLIST_TREE_EFFECT_CONTRACT = 2
35 } Elm_Genlist_Item_Move_Effect_Mode;
36
37 struct _Elm_Genlist_Data
38 {
39    Eina_Inlist_Sorted_State             *state;
40    Evas_Object                          *hit_rect;
41    Evas_Object                          *pan_obj;
42    Evas_Object                          *stack[2]; // stacking markers in pan
43    Evas_Object                          *obj; // the object itself
44
45    Eina_List                            *selected; /* a list of
46                                                     * selected
47                                                     * items */
48    Eina_List                            *deselecting; /* a list of items currently being deselected */
49    Eina_List                            *group_items; /* a list of
50                                                        * groups index
51                                                        * items */
52    Eina_Inlist                          *items; /* an inlist of all items */
53    Elm_Gen_Item                         *reorder_it; /* item currently
54                                                      * being
55                                                      * repositioned */
56    Elm_Object_Item                      *last_selected_item;
57    Elm_Object_Item                      *focused_item; /**< a focused item by keypad arrow or mouse. This is set to NULL if widget looses focus. */
58    Elm_Object_Item                      *last_focused_item; /**< This records the last focused item when widget looses focus. This is required to set the focus on last focused item when widgets gets focus. */
59    Ecore_Job                            *calc_job;
60    int                                   walking;
61    int                                   minw, minh;
62    Eina_Bool                             scr_minw : 1; /* a flag for determining
63                                                         * minimum width to limit
64                                                         * as their content size */
65    Eina_Bool                             scr_minh : 1; /* a flag for determining
66                                                         * minimum height to limit
67                                                         * as their content size */
68    unsigned int                          item_count;
69    Evas_Coord                            pan_x, pan_y;
70    Elm_Object_Select_Mode                select_mode;
71    Elm_Object_Multi_Select_Mode          multi_select_mode; /**< select mode for multiple selection */
72
73    Eina_Inlist                          *blocks; /* an inlist of all
74                                                   * blocks. a block
75                                                   * consists of a
76                                                   * certain number of
77                                                   * items. maximum
78                                                   * number of items in
79                                                   * a block is
80                                                   * 'max_items_per_block'. */
81    Evas_Coord                            reorder_old_pan_y, w, h, realminw;
82    Evas_Coord                            prev_viewport_w; /* previous scrollable
83                                                            * interface's
84                                                            * viewport size.
85                                                            * This is used only
86                                                            * when genlist is in
87                                                            * a compress mode. */
88    Ecore_Job                            *update_job;
89    Ecore_Idle_Enterer                   *queue_idle_enterer;
90    Ecore_Idler                          *must_recalc_idler;
91    Eina_List                            *queue;
92    Elm_Gen_Item                         *show_item, *anchor_item, *mode_item,
93                                         *reorder_rel, *expanded_item;
94    Eina_Inlist                          *item_cache; /* an inlist of
95                                                       * edje object it
96                                                       * cache. */
97    Evas_Coord                            anchor_y;
98    Evas_Coord                            reorder_start_y; /* reorder
99                                                            * it's
100                                                            * initial y
101                                                            * coordinate
102                                                            * in the
103                                                            * pan. */
104    Elm_List_Mode                         mode;
105    Ecore_Timer                          *multi_timer, *scr_hold_timer;
106    Ecore_Animator                       *reorder_move_animator;
107    const char                           *decorate_it_type;
108    double                                start_time;
109    Evas_Coord                            prev_x, prev_y, prev_mx, prev_my;
110    Evas_Coord                            cur_x, cur_y, cur_mx, cur_my;
111
112    struct
113    {
114       Evas_Coord x, y;
115    } history[SWIPE_MOVES];
116
117    int                                   multi_device;
118    int                                   item_cache_count;
119
120    /* maximum number of cached items. (max_items_per_block * 2) */
121    int                                   item_cache_max;
122    int                                   movements;
123
124    /* maximum number of items per block */
125    int                                   max_items_per_block;
126
127    /* longpress timeout. this value comes from _elm_config by
128     * default. this can be changed by
129     * elm_genlist_longpress_timeout_set() */
130    double                                longpress_timeout;
131    Eina_Compare_Cb                       item_compare_cb;
132    Eina_Compare_Cb                       item_compare_data_cb;
133
134    /* a scrollto type which remembers where to scroll ex) in, top,
135     * middle */
136    Elm_Genlist_Item_Scrollto_Type        scroll_to_type;
137    Evas_Object                          *event_block_rect; /**< This object blocks the event in some cases. For example, when the tree effect is running and not finished, this object blocks events to the genlist. */
138    Eina_List                            *move_items; /* items move for
139                                                       * tree effect */
140    Elm_Gen_Item                         *expanded_next_item;
141    Ecore_Animator                       *tree_effect_animator;
142    Elm_Genlist_Item_Move_Effect_Mode     move_effect_mode;
143    int                                   reorder_fast;
144
145    Eina_List                            *filter_queue;
146    Eina_List                            *filtered_list;
147    void                                 *filter_data;
148    unsigned int                          processed_count;
149    unsigned int                          filtered_count;
150    Ecore_Idle_Enterer                   *queue_filter_enterer;
151    Eina_Hash                             *size_caches;
152
153    Eina_Bool                             filter;
154    //TIZEN_ONLY(20160329): genlist: enhance accessibility scroll & highlight (30d9a6012e629cd9ea60eae8d576f3ebb94ada86)
155    Elm_Gen_Item                         *atspi_item_to_highlight;
156    //
157
158    Eina_Bool                             focus_on_selection_enabled : 1;
159    Eina_Bool                             tree_effect_enabled : 1;
160    Eina_Bool                             auto_scroll_enabled : 1;
161    Eina_Bool                             decorate_all_mode : 1;
162    Eina_Bool                             height_for_width : 1;
163    Eina_Bool                             reorder_pan_move : 1;
164    Eina_Bool                             multi_timeout : 1;
165    Eina_Bool                             multi_touched : 1;
166    Eina_Bool                             reorder_mode : 1; /* a flag
167                                                             * for
168                                                             * reorder
169                                                             * mode
170                                                             * enable/disable */
171    /* this flag means genlist is supposed to be scrolled. if this flag
172     * is set to @c EINA_TRUE, genlist checks whether it's ok to scroll
173     * genlist now or not. */
174    Eina_Bool                             check_scroll : 1;
175    Eina_Bool                             pan_changed : 1;
176    Eina_Bool                             wasselected : 1;
177    Eina_Bool                             homogeneous : 1;
178    Eina_Bool                             longpressed : 1;
179    /* a flag for items can be highlighted or not. by default this flag
180     * is true. */
181    Eina_Bool                             mouse_down : 1;
182    Eina_Bool                             multi_down : 1;
183    Eina_Bool                             on_sub_del : 1;
184
185    Eina_Bool                             highlight : 1;
186    Eina_Bool                             h_bounce : 1;
187    Eina_Bool                             v_bounce : 1;
188    Eina_Bool                             bring_in : 1; /* a flag to
189                                                         * describe the
190                                                         * scroll
191                                                         * animation. (show,
192                                                         * bring in) */
193
194    /* this is set to @c EINA_TRUE when the item is re-queued. this
195     * happens when the item is un-queued but the rel item is still in
196     * the queue. this item will be processed later. */
197    Eina_Bool                             requeued : 1;
198    Eina_Bool                             on_hold : 1;
199    Eina_Bool                             multi : 1; /* a flag for item
200                                                      * multi
201                                                      * selection */
202
203    Eina_Bool                             swipe : 1;
204    /**< value whether item loop feature is enabled or not. */
205    Eina_Bool                             item_loop_enable : 1;
206    Eina_Bool                             item_looping_on : 1;
207    Eina_List                             *prepend_items;
208 };
209
210 typedef struct _Item_Block Item_Block;
211 typedef struct _Item_Cache Item_Cache;
212 typedef struct _Item_Size Item_Size;
213
214 struct Elm_Gen_Item_Type
215 {
216    Elm_Gen_Item           *it;
217
218    Elm_Genlist_Data       *wsd;
219
220    Item_Block             *block;
221    Eina_List              *items;
222    Evas_Coord              w, h, minw, minh;
223    Elm_Gen_Item           *group_item;
224    Elm_Genlist_Item_Type   type;
225    Eina_List              *deco_it_texts, *deco_it_contents;
226    Eina_List              *deco_all_texts, *deco_all_contents;
227    Eina_List              *flip_contents;
228    Ecore_Timer            *swipe_timer;
229    Evas_Coord              scrl_x, scrl_y, old_scrl_y;
230
231    Elm_Gen_Item           *rel;
232    Eina_List              *rel_revs; // FIXME: find better way not to use this
233    Evas_Object            *deco_it_view;
234    int                     expanded_depth;
235    int                     order_num_in;
236
237    Eina_Bool               decorate_all_item_realized : 1;
238    Eina_Bool               tree_effect_finished : 1; /* tree effect */
239    Eina_Bool               move_effect_enabled : 1;
240    Eina_Bool               tree_effect_hide_me : 1; /* item hide for
241                                                     * tree effect */
242
243    Eina_Bool               stacking_even : 1;
244    Eina_Bool               want_realize : 1;
245    Eina_Bool               nocache_once : 1; /* do not use cache for
246                                               * this item only once */
247    Eina_Bool               nostacking : 1;
248    Eina_Bool               expanded : 1;
249    Eina_Bool               mincalcd : 1;
250    Eina_Bool               updateme : 1;
251    Eina_Bool               nocache : 1; /* do not use cache for this item */
252    Eina_Bool               queued : 1;
253    Eina_Bool               before : 1;
254    Eina_Bool               show_me : 1;
255 };
256
257 struct _Item_Block
258 {
259    EINA_INLIST;
260
261    int                     count;
262    int                     num;
263    int                     reorder_offset;
264    Elm_Genlist_Data       *sd;
265    Eina_List              *items;
266    Evas_Coord              x, y, w, h, minw, minh;
267    int                     position;
268    int                     item_position_stamp;
269
270    Eina_Bool               position_update : 1;
271    Eina_Bool               want_unrealize : 1;
272    Eina_Bool               must_recalc : 1;
273    Eina_Bool               realized : 1;
274    Eina_Bool               updateme : 1;
275    Eina_Bool               changed : 1;
276    Eina_Bool               show_me : 1;
277 };
278
279 struct _Item_Cache
280 {
281    EINA_INLIST;
282
283    Evas_Object *base_view, *spacer;
284    const Elm_Genlist_Item_Class  *item_class; // it->itc
285    Eina_Bool    tree : 1; // it->group
286    Eina_List   *contents; // content objects for reusing
287 };
288
289 struct _Item_Size
290 {
291      const Elm_Genlist_Item_Class *itc;
292      Evas_Coord minw;
293      Evas_Coord minh;
294 };
295
296 typedef struct _Elm_Genlist_Pan_Data Elm_Genlist_Pan_Data;
297 struct _Elm_Genlist_Pan_Data
298 {
299    Evas_Object            *wobj;
300    Elm_Genlist_Data       *wsd;
301    Ecore_Job              *resize_job;
302 };
303
304 /**
305  * Structure added to genlist for internal filter iterator implementation
306  * Can be extended to genlist as a whole in future if needed.
307  */
308 typedef struct _Elm_Genlist_Filter Elm_Genlist_Filter;
309 struct _Elm_Genlist_Filter
310 {
311    Eina_Iterator iterator;
312    const Eina_Inlist *head;
313    const Eina_Inlist *current;
314 };
315
316 #define ELM_GENLIST_FILTER_ITERATOR_ITEM_GET(ptr,                 \
317                                   type) ((type *)((char *)ptr - \
318                                                   offsetof(type, __in_list)))
319
320
321 /**
322  * @}
323  */
324
325 #define GL_IT(_it) (_it->item)
326
327 #define ELM_GENLIST_DATA_GET(o, sd) \
328   Elm_Genlist_Data * sd = eo_data_scope_get(o, ELM_GENLIST_CLASS)
329
330 #define ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd) \
331   Elm_Genlist_Data * sd = GL_IT(it)->wsd
332
333 #define ELM_GENLIST_PAN_DATA_GET(o, sd) \
334   Elm_Genlist_Pan_Data * sd = eo_data_scope_get(o, ELM_GENLIST_PAN_CLASS)
335
336 #define ELM_GENLIST_DATA_GET_OR_RETURN(o, ptr)       \
337   ELM_GENLIST_DATA_GET(o, ptr);                      \
338   if (EINA_UNLIKELY(!ptr))                           \
339     {                                                \
340        CRI("No widget data for object %p (%s)",      \
341            o, evas_object_type_get(o));              \
342        return;                                       \
343     }
344
345 #define ELM_GENLIST_DATA_GET_OR_RETURN_VAL(o, ptr, val) \
346   ELM_GENLIST_DATA_GET(o, ptr);                         \
347   if (EINA_UNLIKELY(!ptr))                              \
348     {                                                   \
349        CRI("No widget data for object %p (%s)",         \
350            o, evas_object_type_get(o));                 \
351        return val;                                      \
352     }
353
354 #define ELM_GENLIST_CHECK(obj)                              \
355   if (EINA_UNLIKELY(!eo_isa((obj), ELM_GENLIST_CLASS))) \
356     return
357
358 #define ELM_GENLIST_ITEM_CHECK(it)                          \
359   if (!it) return; \
360   ELM_WIDGET_ITEM_CHECK_OR_RETURN(it->base, ); \
361   ELM_GENLIST_CHECK(it->base->widget);
362
363 #define ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, ...)                      \
364   if (!it) return __VA_ARGS__; \
365   ELM_WIDGET_ITEM_CHECK_OR_RETURN(it->base, __VA_ARGS__); \
366   ELM_GENLIST_CHECK(it->base->widget) __VA_ARGS__;
367
368 #define ELM_GENLIST_ITEM_CHECK_OR_GOTO(it, label)              \
369   if (!it) goto label; \
370   ELM_WIDGET_ITEM_CHECK_OR_GOTO(it->base, label); \
371   if (!it->base->widget || !eo_isa                              \
372         ((it->base->widget), ELM_GENLIST_CLASS)) goto label;
373
374 #define ELM_GENLIST_ITEM_DATA_GET(o, sd) \
375   Elm_Gen_Item* sd = eo_data_scope_get(o, ELM_GENLIST_ITEM_CLASS)
376
377 #endif