2 # include "elementary_config.h"
7 #define ELM_INTERFACE_ATSPI_ACCESSIBLE_PROTECTED
8 #define ELM_INTERFACE_ATSPI_WIDGET_ACTION_PROTECTED
9 #define ELM_WIDGET_ITEM_PROTECTED
11 #include <Elementary.h>
12 #include <Elementary_Cursor.h>
15 #include "elm_widget_genlist.h"
16 #include "elm_interface_scrollable.h"
18 #define MY_PAN_CLASS ELM_GENLIST_PAN_CLASS
20 #define MY_PAN_CLASS_NAME "Elm_Genlist_Pan"
21 #define MY_PAN_CLASS_NAME_LEGACY "elm_genlist_pan"
23 #define MY_CLASS ELM_GENLIST_CLASS
25 #define MY_CLASS_NAME "Elm_Genlist"
26 #define MY_CLASS_NAME_LEGACY "elm_genlist"
28 // internally allocated
29 #define CLASS_ALLOCATED 0x3a70f11f
31 #define MAX_ITEMS_PER_BLOCK 32
32 #define REORDER_EFFECT_TIME 0.5
33 #define MULTI_DOWN_TIME 1.0
34 #define SWIPE_TIME 0.4
35 #define SCR_HOLD_TIME 0.1
37 #define ERR_ABORT(_msg) \
40 if (getenv("ELM_ERROR_ABORT")) abort(); \
43 #define ELM_PRIV_GENLIST_SIGNALS(cmd) \
44 cmd(SIG_ACTIVATED, "activated", "") \
45 cmd(SIG_CLICKED_DOUBLE, "clicked,double", "") \
46 cmd(SIG_CLICKED_RIGHT, "clicked,right", "") \
47 cmd(SIG_SELECTED, "selected", "") \
48 cmd(SIG_UNSELECTED, "unselected", "") \
49 cmd(SIG_EXPANDED, "expanded", "") \
50 cmd(SIG_CONTRACTED, "contracted", "") \
51 cmd(SIG_EXPAND_REQUEST, "expand,request", "") \
52 cmd(SIG_CONTRACT_REQUEST, "contract,request", "") \
53 cmd(SIG_REALIZED, "realized", "") \
54 cmd(SIG_UNREALIZED, "unrealized", "") \
55 cmd(SIG_DRAG_START_UP, "drag,start,up", "") \
56 cmd(SIG_DRAG_START_DOWN, "drag,start,down", "") \
57 cmd(SIG_DRAG_START_LEFT, "drag,start,left", "") \
58 cmd(SIG_DRAG_START_RIGHT, "drag,start,right", "") \
59 cmd(SIG_DRAG_STOP, "drag,stop", "") \
60 cmd(SIG_DRAG, "drag", "") \
61 cmd(SIG_LONGPRESSED, "longpressed", "") \
62 cmd(SIG_SCROLL, "scroll", "") \
63 cmd(SIG_SCROLL_ANIM_START, "scroll,anim,start", "") \
64 cmd(SIG_SCROLL_ANIM_STOP, "scroll,anim,stop", "") \
65 cmd(SIG_SCROLL_DRAG_START, "scroll,drag,start", "") \
66 cmd(SIG_SCROLL_DRAG_STOP, "scroll,drag,stop", "") \
67 cmd(SIG_EDGE_TOP, "edge,top", "") \
68 cmd(SIG_EDGE_BOTTOM, "edge,bottom", "") \
69 cmd(SIG_EDGE_LEFT, "edge,left", "") \
70 cmd(SIG_EDGE_RIGHT, "edge,right", "") \
71 cmd(SIG_VBAR_DRAG, "vbar,drag", "") \
72 cmd(SIG_VBAR_PRESS, "vbar,press", "") \
73 cmd(SIG_VBAR_UNPRESS, "vbar,unpress", "") \
74 cmd(SIG_HBAR_DRAG, "hbar,drag", "") \
75 cmd(SIG_HBAR_PRESS, "hbar,press", "") \
76 cmd(SIG_HBAR_UNPRESS, "hbar,unpress", "") \
77 cmd(SIG_MULTI_SWIPE_LEFT, "multi,swipe,left", "") \
78 cmd(SIG_MULTI_SWIPE_RIGHT, "multi,swipe,right", "") \
79 cmd(SIG_MULTI_SWIPE_UP, "multi,swipe,up", "") \
80 cmd(SIG_MULTI_SWIPE_DOWN, "multi,swipe,down", "") \
81 cmd(SIG_MULTI_PINCH_OUT, "multi,pinch,out", "") \
82 cmd(SIG_MULTI_PINCH_IN, "multi,pinch,in", "") \
83 cmd(SIG_SWIPE, "swipe", "") \
84 cmd(SIG_MOVED, "moved", "") \
85 cmd(SIG_MOVED_AFTER, "moved,after", "") \
86 cmd(SIG_MOVED_BEFORE, "moved,before", "") \
87 cmd(SIG_INDEX_UPDATE, "index,update", "") \
88 cmd(SIG_TREE_EFFECT_FINISHED , "tree,effect,finished", "") \
89 cmd(SIG_HIGHLIGHTED, "highlighted", "") \
90 cmd(SIG_UNHIGHLIGHTED, "unhighlighted", "") \
91 cmd(SIG_ITEM_FOCUSED, "item,focused", "") \
92 cmd(SIG_ITEM_UNFOCUSED, "item,unfocused", "") \
93 cmd(SIG_PRESSED, "pressed", "") \
94 cmd(SIG_RELEASED, "released", "")
96 ELM_PRIV_GENLIST_SIGNALS(ELM_PRIV_STATIC_VARIABLE_DECLARE);
98 static const Evas_Smart_Cb_Description _smart_callbacks[] = {
99 ELM_PRIV_GENLIST_SIGNALS(ELM_PRIV_SMART_CALLBACKS_DESC)
100 {SIG_WIDGET_LANG_CHANGED, ""}, /**< handled by elm_widget */
101 {SIG_WIDGET_ACCESS_CHANGED, ""}, /**< handled by elm_widget */
102 {SIG_LAYOUT_FOCUSED, ""}, /**< handled by elm_layout */
103 {SIG_LAYOUT_UNFOCUSED, ""}, /**< handled by elm_layout */
107 #undef ELM_PRIV_GENLIST_SIGNALS
109 /* edje signals internally used */
110 static const char SIGNAL_ENABLED[] = "elm,state,enabled";
111 static const char SIGNAL_DISABLED[] = "elm,state,disabled";
112 static const char SIGNAL_SELECTED[] = "elm,state,selected";
113 static const char SIGNAL_UNSELECTED[] = "elm,state,unselected";
114 static const char SIGNAL_EXPANDED[] = "elm,state,expanded";
115 static const char SIGNAL_CONTRACTED[] = "elm,state,contracted";
116 static const char SIGNAL_FLIP_ENABLED[] = "elm,state,flip,enabled";
117 static const char SIGNAL_FLIP_DISABLED[] = "elm,state,flip,disabled";
118 static const char SIGNAL_DECORATE_ENABLED[] = "elm,state,decorate,enabled";
119 static const char SIGNAL_DECORATE_DISABLED[] = "elm,state,decorate,disabled";
120 static const char SIGNAL_DECORATE_ENABLED_EFFECT[] = "elm,state,decorate,enabled,effect";
121 static const char SIGNAL_REORDER_ENABLED[] = "elm,state,reorder,enabled";
122 static const char SIGNAL_REORDER_DISABLED[] = "elm,state,reorder,disabled";
123 static const char SIGNAL_REORDER_MODE_SET[] = "elm,state,reorder,mode_set";
124 static const char SIGNAL_REORDER_MODE_UNSET[] = "elm,state,reorder,mode_unset";
125 static const char SIGNAL_CONTRACT_FLIP[] = "elm,state,contract_flip";
126 static const char SIGNAL_SHOW[] = "elm,state,show";
127 static const char SIGNAL_HIDE[] = "elm,state,hide";
128 static const char SIGNAL_FLIP_ITEM[] = "elm,action,flip_item";
129 static const char SIGNAL_ODD[] = "elm,state,odd";
130 static const char SIGNAL_EVEN[] = "elm,state,even";
131 static const char SIGNAL_FOCUSED[] = "elm,state,focused";
132 static const char SIGNAL_UNFOCUSED[] = "elm,state,unfocused";
133 static const char SIGNAL_LIST_SINGLE[] = "elm,state,list,single";
134 static const char SIGNAL_LIST_FIRST[] = "elm,state,list,first";
135 static const char SIGNAL_LIST_LAST[] = "elm,state,list,last";
136 static const char SIGNAL_LIST_MIDDLE[] = "elm,state,list,middle";
137 static const char SIGNAL_GROUP_SINGLE[] = "elm,state,group,single";
138 static const char SIGNAL_GROUP_FIRST[] = "elm,state,group,first";
139 static const char SIGNAL_GROUP_LAST[] = "elm,state,group,last";
140 static const char SIGNAL_GROUP_MIDDLE[] = "elm,state,group,middle";
142 static void _item_unrealize(Elm_Gen_Item *it);
143 static Eina_Bool _item_select(Elm_Gen_Item *it);
144 static void _item_unselect(Elm_Gen_Item *it);
145 static void _item_highlight(Elm_Gen_Item *it);
146 static Eina_Bool _key_action_move(Evas_Object *obj, const char *params);
147 static Eina_Bool _key_action_select(Evas_Object *obj, const char *params);
148 static Eina_Bool _key_action_escape(Evas_Object *obj, const char *params);
149 static void _calc_job(void *data);
150 static Eina_Bool _item_block_recalc(Item_Block *itb, int in, Eina_Bool qadd);
151 static void _item_mouse_callbacks_add(Elm_Gen_Item *it, Evas_Object *view);
152 static void _item_mouse_callbacks_del(Elm_Gen_Item *it, Evas_Object *view);
153 static void _access_activate_cb(void *data EINA_UNUSED,
154 Evas_Object *part_obj EINA_UNUSED,
155 Elm_Object_Item *item);
156 static void _decorate_item_set(Elm_Gen_Item *);
157 static void _internal_elm_genlist_clear(Evas_Object *obj);
159 static const Elm_Action key_actions[] = {
160 {"move", _key_action_move},
161 {"select", _key_action_select},
162 {"escape", _key_action_escape},
168 _is_no_select(Elm_Gen_Item *it)
170 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
172 if ((sd->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
173 (sd->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY) ||
174 (it->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
175 (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
181 _elm_genlist_pan_elm_pan_pos_set(Eo *obj, Elm_Genlist_Pan_Data *psd, Evas_Coord x, Evas_Coord y)
185 Elm_Genlist_Data *sd = psd->wsd;
187 if ((x == sd->pan_x) && (y == sd->pan_y)) return;
191 EINA_INLIST_FOREACH(sd->blocks, itb)
193 if ((itb->y + itb->h) > y)
198 EINA_LIST_FOREACH(itb->items, l2, it)
200 if ((itb->y + it->y) >= y)
202 sd->anchor_item = it;
203 sd->anchor_y = -(itb->y + it->y - y);
210 if (!sd->reorder_move_animator) evas_object_smart_changed(obj);
214 _elm_genlist_pan_elm_pan_pos_get(Eo *obj EINA_UNUSED, Elm_Genlist_Pan_Data *psd, Evas_Coord *x, Evas_Coord *y)
216 if (x) *x = psd->wsd->pan_x;
217 if (y) *y = psd->wsd->pan_y;
221 _elm_genlist_pan_elm_pan_pos_max_get(Eo *obj, Elm_Genlist_Pan_Data *psd, Evas_Coord *x, Evas_Coord *y)
225 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
226 ow = psd->wsd->minw - ow;
228 oh = psd->wsd->minh - oh;
235 _elm_genlist_pan_elm_pan_pos_min_get(Eo *obj EINA_UNUSED, Elm_Genlist_Pan_Data *_pd EINA_UNUSED, Evas_Coord *x, Evas_Coord *y)
242 _elm_genlist_pan_elm_pan_content_size_get(Eo *obj EINA_UNUSED, Elm_Genlist_Pan_Data *psd, Evas_Coord *w, Evas_Coord *h)
244 if (w) *w = psd->wsd->minw;
245 if (h) *h = psd->wsd->minh;
249 _elm_genlist_pan_evas_object_smart_del(Eo *obj, Elm_Genlist_Pan_Data *psd)
251 ecore_job_del(psd->resize_job);
253 eo_do_super(obj, MY_PAN_CLASS, evas_obj_smart_del());
257 _elm_genlist_pan_evas_object_smart_move(Eo *obj, Elm_Genlist_Pan_Data *psd, Evas_Coord _gen_param2 EINA_UNUSED, Evas_Coord _gen_param3 EINA_UNUSED)
259 psd->wsd->pan_changed = EINA_TRUE;
260 evas_object_smart_changed(obj);
261 ELM_SAFE_FREE(psd->wsd->calc_job, ecore_job_del);
265 _elm_genlist_pan_smart_resize_job(void *data)
267 ELM_GENLIST_PAN_DATA_GET(data, psd);
269 elm_layout_sizing_eval(psd->wobj);
270 psd->resize_job = NULL;
274 _elm_genlist_pan_evas_object_smart_resize(Eo *obj, Elm_Genlist_Pan_Data *psd, Evas_Coord w, Evas_Coord h)
278 Elm_Genlist_Data *sd = psd->wsd;
280 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
281 if ((ow == w) && (oh == h)) return;
282 if ((sd->mode == ELM_LIST_COMPRESS) && (ow != w))
285 ecore_job_del(psd->resize_job);
287 ecore_job_add(_elm_genlist_pan_smart_resize_job, obj);
289 sd->pan_changed = EINA_TRUE;
290 evas_object_smart_changed(obj);
291 ecore_job_del(sd->calc_job);
292 // if the width changed we may have to resize content if scrollbar went
293 // away or appeared to queue a job to deal with it. it should settle in
294 // the end to a steady-state
296 sd->calc_job = ecore_job_add(_calc_job, psd->wobj);
302 _item_text_realize(Elm_Gen_Item *it,
311 if (!it->itc->func.text_get) return;
314 *source = elm_widget_stringlist_get
315 (edje_object_data_get(target, "texts"));
316 EINA_LIST_FOREACH(*source, l, key)
318 if (parts && fnmatch(parts, key, FNM_PERIOD)) continue;
320 s = it->itc->func.text_get
321 ((void *)WIDGET_ITEM_DATA_GET(EO_OBJ(it)), WIDGET(it), key);
324 edje_object_part_text_escaped_set(target, key, s);
329 edje_object_part_text_set(target, key, "");
335 _item_content_realize(Elm_Gen_Item *it,
337 Eina_List **contents,
341 Evas_Object *content;
345 EINA_LIST_FREE(*contents, content)
346 evas_object_del(content);
348 if (it->itc->func.content_get)
353 source = elm_widget_stringlist_get(edje_object_data_get(target, src));
355 EINA_LIST_FREE(source, key)
357 if (parts && fnmatch(parts, key, FNM_PERIOD))
360 Evas_Object *old = edje_object_part_swallow_get(target, key);
363 *contents = eina_list_remove(*contents, old);
364 evas_object_del(old);
367 if (it->itc->func.content_get)
368 content = it->itc->func.content_get
369 ((void *)WIDGET_ITEM_DATA_GET(EO_OBJ(it)), WIDGET(it), key);
370 if (!content) continue;
371 *contents = eina_list_append(*contents, content);
372 if (!edje_object_part_swallow(target, key, content))
374 ERR("%s (%p) can not be swallowed into %s",
375 evas_object_type_get(content), content, key);
376 evas_object_hide(content);
379 elm_widget_sub_object_add(WIDGET(it), content);
380 if (eo_do(EO_OBJ(it), elm_wdg_item_disabled_get()))
381 elm_widget_disabled_set(content, EINA_TRUE);
387 _item_state_realize(Elm_Gen_Item *it, Evas_Object *target, const char *parts)
393 if (!it->itc->func.state_get) return;
395 src = elm_widget_stringlist_get(edje_object_data_get(target, "states"));
396 EINA_LIST_FREE(src, key)
398 if (parts && fnmatch(parts, key, FNM_PERIOD)) continue;
400 Eina_Bool on = it->itc->func.state_get
401 ((void *)WIDGET_ITEM_DATA_GET(EO_OBJ(it)), WIDGET(it), key);
405 snprintf(buf, sizeof(buf), "elm,state,%s,active", key);
406 edje_object_signal_emit(target, buf, "elm");
410 snprintf(buf, sizeof(buf), "elm,state,%s,passive", key);
411 edje_object_signal_emit(target, buf, "elm");
414 edje_object_message_signal_process(target);
418 * Apply the right style for the created item view.
421 _view_style_update(Elm_Gen_Item *it, Evas_Object *view, const char *style)
424 const char *stacking_even;
425 const char *stacking;
426 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
428 // FIXME: There exists
429 // item, item_compress, item_odd, item_compress_odd,
430 // tree, tree_compress, tree_odd, tree_odd_compress
431 // But those used case by case. :-(
432 // Anyway, belows codes are for backward..
433 if (it->decorate_it_set)
435 // item, item_compress, item_odd, item_compress_odd
436 strncpy(buf, "item", sizeof(buf));
437 if (sd->mode == ELM_LIST_COMPRESS)
438 strncat(buf, "_compress", sizeof(buf) - strlen(buf) - 1);
440 if (it->item->order_num_in & 0x1)
441 strncat(buf, "_odd", sizeof(buf) - strlen(buf) - 1);
442 strncat(buf, "/", sizeof(buf) - strlen(buf) - 1);
443 strncat(buf, style, sizeof(buf) - strlen(buf) - 1);
447 // item, item_compress, tree, tree_compress
448 if (it->item->type & ELM_GENLIST_ITEM_TREE)
449 snprintf(buf, sizeof(buf), "tree%s/%s",
450 sd->mode == ELM_LIST_COMPRESS ? "_compress" :
451 "", style ? : "default");
453 snprintf(buf, sizeof(buf), "item%s/%s",
454 sd->mode == ELM_LIST_COMPRESS ? "_compress" :
455 "",style ? : "default");
458 if (!elm_widget_theme_object_set(WIDGET(it), view,
460 elm_widget_style_get(WIDGET(it))))
462 ERR("%s is not a valid genlist item style. "
463 "Automatically falls back into default style.",
465 elm_widget_theme_object_set
466 (WIDGET(it), VIEW(it), "genlist", "item/default", "default");
469 edje_object_mirrored_set(view, elm_widget_mirrored_get(WIDGET(it)));
470 edje_object_scale_set(view, elm_widget_scale_get(WIDGET(it))
471 * elm_config_scale_get());
473 stacking_even = edje_object_data_get(VIEW(it), "stacking_even");
474 if (!stacking_even) stacking_even = "above";
475 it->item->stacking_even = !!strcmp("above", stacking_even);
477 stacking = edje_object_data_get(VIEW(it), "stacking");
478 if (!stacking) stacking = "yes";
479 it->item->nostacking = !!strcmp("yes", stacking);
483 * Create a VIEW(it) during _item_realize()
486 _view_create(Elm_Gen_Item *it, const char *style)
488 Evas_Object *view = edje_object_add(evas_object_evas_get(WIDGET(it)));
489 evas_object_smart_member_add(view, GL_IT(it)->wsd->pan_obj);
490 elm_widget_sub_object_add(WIDGET(it), view);
491 edje_object_scale_set(view, elm_widget_scale_get(WIDGET(it)) *
492 elm_config_scale_get());
494 _view_style_update(it, view, style);
499 _view_clear(Evas_Object *view, Eina_List **texts, Eina_List **contents)
505 EINA_LIST_FOREACH(*texts, l, part)
506 edje_object_part_text_set(view, part, NULL);
507 ELM_SAFE_FREE(*texts, elm_widget_stringlist_free);
509 EINA_LIST_FREE(*contents, c)
514 _item_scroll(Elm_Genlist_Data *sd)
517 Elm_Gen_Item *it = NULL;
518 Evas_Coord ow, oh, dx = 0, dy = 0, dw = 0, dh = 0;
520 if (!sd->show_item) return;
522 evas_object_geometry_get(sd->pan_obj, NULL, NULL, &ow, &oh);
524 dx = it->x + it->item->block->x;
525 dy = it->y + it->item->block->y;
526 dw = it->item->block->w;
529 switch (sd->scroll_to_type)
531 case ELM_GENLIST_ITEM_SCROLLTO_TOP:
532 if (it->item->group_item) gith = it->item->group_item->item->h;
536 case ELM_GENLIST_ITEM_SCROLLTO_MIDDLE:
537 dy += ((it->item->h / 2) - (oh / 2));
540 case ELM_GENLIST_ITEM_SCROLLTO_IN:
542 if ((sd->expanded_item) &&
543 ((sd->show_item->y + sd->show_item->item->block->y
544 + sd->show_item->item->h) -
545 (sd->expanded_item->y + sd->expanded_item->item->block->y) > oh))
547 it = sd->expanded_item;
548 if (it->item->group_item) gith = it->item->group_item->item->h;
549 dx = it->x + it->item->block->x;
550 dy = it->y + it->item->block->y - gith;
551 dw = it->item->block->w;
555 if ((it->item->group_item) &&
556 (sd->pan_y > (it->y + it->item->block->y)))
557 gith = it->item->group_item->item->h;
564 eo_do(sd->obj, elm_interface_scrollable_region_bring_in(dx, dy, dw, dh));
566 eo_do(sd->obj, elm_interface_scrollable_content_region_show
569 it->item->show_me = EINA_FALSE;
570 sd->show_item = NULL;
571 sd->auto_scroll_enabled = EINA_FALSE;
572 sd->check_scroll = EINA_FALSE;
576 _elm_genlist_item_unrealize(Elm_Gen_Item *it,
579 if (!it->realized) return;
580 if (GL_IT(it)->wsd->reorder_it == it)
582 WRN("reordering item should not be unrealized");
586 evas_event_freeze(evas_object_evas_get(WIDGET(it)));
588 evas_object_smart_callback_call(WIDGET(it), SIG_UNREALIZED, EO_OBJ(it));
589 ELM_SAFE_FREE(it->long_timer, ecore_timer_del);
591 _view_clear(VIEW(it), &(it->texts), &(it->contents));
592 ELM_SAFE_FREE(it->item_focus_chain, eina_list_free);
594 eo_do(EO_OBJ(it), elm_wdg_item_track_cancel());
598 it->realized = EINA_FALSE;
599 it->want_unrealize = EINA_FALSE;
601 evas_event_thaw(evas_object_evas_get(WIDGET(it)));
602 evas_event_thaw_eval(evas_object_evas_get(WIDGET(it)));
606 _item_block_unrealize(Item_Block *itb)
610 Eina_Bool dragging = EINA_FALSE;
612 if (!itb->realized) return;
613 evas_event_freeze(evas_object_evas_get((itb->sd)->obj));
615 EINA_LIST_FOREACH(itb->items, l, it)
617 if (itb->must_recalc || !(GL_IT(it)->type & ELM_GENLIST_ITEM_GROUP))
621 dragging = EINA_TRUE;
622 it->want_unrealize = EINA_TRUE;
625 _elm_genlist_item_unrealize(it, EINA_FALSE);
630 itb->realized = EINA_FALSE;
631 itb->want_unrealize = EINA_TRUE;
634 itb->want_unrealize = EINA_FALSE;
635 evas_event_thaw(evas_object_evas_get((itb->sd)->obj));
636 evas_event_thaw_eval(evas_object_evas_get((itb->sd)->obj));
640 _must_recalc_idler(void *data)
642 ELM_GENLIST_DATA_GET(data, sd);
644 ecore_job_del(sd->calc_job);
645 sd->calc_job = ecore_job_add(_calc_job, data);
646 sd->must_recalc_idler = NULL;
647 return ECORE_CALLBACK_CANCEL;
651 _calc_job(void *data)
654 Item_Block *itb, *chb = NULL;
655 Evas_Coord pan_w = 0, pan_h = 0;
656 ELM_GENLIST_DATA_GET(data, sd);
657 Eina_Bool minw_change = EINA_FALSE;
658 Eina_Bool did_must_recalc = EINA_FALSE;
659 Evas_Coord minw = -1, minh = 0, y = 0, ow, dy = 0, vw = 0;
661 evas_object_geometry_get(sd->pan_obj, NULL, NULL, &ow, &sd->h);
662 if (sd->mode == ELM_LIST_COMPRESS)
663 eo_do(sd->obj, elm_interface_scrollable_content_viewport_geometry_get
664 (NULL, NULL, &vw, NULL));
666 if (sd->w != ow) sd->w = ow;
668 evas_event_freeze(evas_object_evas_get(sd->obj));
669 EINA_INLIST_FOREACH(sd->blocks, itb)
671 Eina_Bool show_me = EINA_FALSE;
674 show_me = itb->show_me;
675 itb->show_me = EINA_FALSE;
678 if (itb->realized) _item_block_unrealize(itb);
680 if ((itb->changed) || ((itb->must_recalc) && (!did_must_recalc)))
682 if (itb->must_recalc)
687 EINA_LIST_FOREACH(itb->items, l, it)
688 it->item->mincalcd = EINA_FALSE;
689 itb->changed = EINA_TRUE;
690 did_must_recalc = EINA_TRUE;
691 if (itb->realized) _item_block_unrealize(itb);
692 itb->must_recalc = EINA_FALSE;
694 show_me = _item_block_recalc(itb, in, EINA_FALSE);
700 if (minw < itb->minw)
704 minw_change = EINA_TRUE;
706 if ((sd->mode == ELM_LIST_COMPRESS) && (minw > vw))
709 minw_change = EINA_TRUE;
715 if ((show_me) && (sd->show_item) && (!sd->show_item->item->queued))
716 sd->check_scroll = EINA_TRUE;
720 EINA_INLIST_FOREACH(sd->blocks, itb)
726 if ((chb) && (EINA_INLIST_GET(chb)->next))
728 EINA_INLIST_FOREACH(EINA_INLIST_GET(chb)->next, itb)
730 if (itb->realized) _item_block_unrealize(itb);
734 if (minw < sd->w) minw = sd->w;
735 if ((minw != sd->minw) || (minh != sd->minh))
739 evas_object_smart_callback_call(sd->pan_obj, "changed", NULL);
740 elm_layout_sizing_eval(sd->obj);
747 if ((sd->anchor_item) && (sd->anchor_item->item->block)
748 && (!sd->auto_scroll_enabled))
753 it = sd->anchor_item;
755 eo_do(sd->obj, elm_interface_scrollable_content_pos_set
756 (sd->pan_x, it->item->block->y
757 + it->y + it_y, EINA_TRUE));
758 sd->anchor_item = it;
764 if (!sd->must_recalc_idler)
765 sd->must_recalc_idler = ecore_idler_add(_must_recalc_idler, data);
767 if (sd->check_scroll)
769 eo_do(sd->pan_obj, elm_obj_pan_content_size_get(&pan_w, &pan_h));
770 if (EINA_INLIST_GET(sd->show_item) == sd->items->last)
771 sd->scroll_to_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
773 switch (sd->scroll_to_type)
775 case ELM_GENLIST_ITEM_SCROLLTO_TOP:
779 case ELM_GENLIST_ITEM_SCROLLTO_MIDDLE:
783 case ELM_GENLIST_ITEM_SCROLLTO_IN:
788 if ((sd->show_item) && (sd->show_item->item->block))
790 if ((pan_w > (sd->show_item->x + sd->show_item->item->block->x))
791 && (pan_h > (sd->show_item->y + sd->show_item->item->block->y
800 evas_object_smart_changed(sd->pan_obj);
801 evas_event_thaw(evas_object_evas_get(sd->obj));
802 evas_event_thaw_eval(evas_object_evas_get(sd->obj));
806 _elm_genlist_elm_layout_sizing_eval(Eo *obj, Elm_Genlist_Data *sd)
808 Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;
809 Evas_Coord vmw = 0, vmh = 0;
811 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
813 if (sd->on_sub_del) return;;
815 evas_object_size_hint_min_get(obj, &minw, NULL);
816 evas_object_size_hint_max_get(obj, &maxw, &maxh);
818 edje_object_size_min_calc(wd->resize_obj, &vmw, &vmh);
820 if (sd->mode == ELM_LIST_COMPRESS)
822 Evas_Coord vw = 0, vh = 0;
824 eo_do(obj, elm_interface_scrollable_content_viewport_geometry_get
825 (NULL, NULL, &vw, &vh));
826 if ((vw != 0) && (vw != sd->prev_viewport_w))
830 sd->prev_viewport_w = vw;
832 EINA_INLIST_FOREACH(sd->blocks, itb)
834 itb->must_recalc = EINA_TRUE;
836 ecore_job_del(sd->calc_job);
837 sd->calc_job = ecore_job_add(_calc_job, obj);
842 else if (sd->mode == ELM_LIST_LIMIT)
845 minw = vmw + sd->realminw;
853 evas_object_size_hint_min_set(obj, minw, minh);
854 evas_object_size_hint_max_set(obj, maxw, maxh);
858 _item_contract_emit(Elm_Object_Item *eo_it)
860 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
861 Elm_Object_Item *eo_it2;
865 edje_object_signal_emit(VIEW(it), SIGNAL_CONTRACT_FLIP, "");
866 edje_object_signal_emit(VIEW(it), SIGNAL_CONTRACT_FLIP, "elm");
867 it->item->tree_effect_finished = EINA_FALSE;
869 EINA_LIST_FOREACH(it->item->items, l, eo_it2)
870 if (eo_it2) _item_contract_emit(eo_it2);
874 _item_tree_effect_before(Elm_Gen_Item *it)
876 Elm_Object_Item *eo_it2;
878 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
880 EINA_LIST_FOREACH(it->item->items, l, eo_it2)
882 ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
883 if (it2->parent && (it == it2->parent))
886 it2->item->tree_effect_hide_me = EINA_TRUE;
887 if (sd->move_effect_mode ==
888 ELM_GENLIST_TREE_EFFECT_EXPAND)
891 edje_object_signal_emit(VIEW(it2), SIGNAL_HIDE, "");
892 edje_object_signal_emit(VIEW(it2), SIGNAL_HIDE, "elm");
894 else if (sd->move_effect_mode ==
895 ELM_GENLIST_TREE_EFFECT_CONTRACT)
896 _item_contract_emit(eo_it2);
899 return ECORE_CALLBACK_CANCEL;
903 _item_position(Elm_Gen_Item *it,
910 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
913 (evas_object_evas_get(sd->obj));
914 evas_object_resize(view, it->item->w, it->item->h);
915 evas_object_move(view, it_x, it_y);
916 evas_object_show(view);
917 evas_event_thaw(evas_object_evas_get(sd->obj));
919 (evas_object_evas_get(sd->obj));
923 _item_tree_effect(Elm_Genlist_Data *sd,
926 Elm_Gen_Item *expanded_next_it;
927 Elm_Object_Item *eo_it;
929 expanded_next_it = sd->expanded_next_item;
931 if (sd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
933 eo_it = elm_genlist_item_prev_get(EO_OBJ(expanded_next_it));
936 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
937 if (it->item->expanded_depth <=
938 expanded_next_it->item->expanded_depth) break;
939 if (it->item->scrl_y &&
940 (it->item->scrl_y <= expanded_next_it->item->old_scrl_y + y)
941 && (it->item->expanded_depth >
942 expanded_next_it->item->expanded_depth))
944 if (!it->item->tree_effect_finished)
947 edje_object_signal_emit(VIEW(it), "flip_item", "");
948 edje_object_signal_emit(VIEW(it), SIGNAL_FLIP_ITEM,
951 (it, VIEW(it), it->item->scrl_x, it->item->scrl_y);
952 it->item->tree_effect_finished = EINA_TRUE;
955 eo_it = elm_genlist_item_prev_get(eo_it);
958 else if (sd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_CONTRACT)
960 eo_it = elm_genlist_item_prev_get(EO_OBJ(expanded_next_it));
963 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
964 if ((it->item->scrl_y > expanded_next_it->item->old_scrl_y + y) &&
965 (it->item->expanded_depth >
966 expanded_next_it->item->expanded_depth))
968 if (!it->item->tree_effect_finished)
971 edje_object_signal_emit(VIEW(it), SIGNAL_HIDE, "");
972 edje_object_signal_emit(VIEW(it), SIGNAL_HIDE, "elm");
973 it->item->tree_effect_finished = EINA_TRUE;
978 eo_it = elm_genlist_item_prev_get(eo_it);
984 _item_sub_items_clear(Elm_Gen_Item *it)
986 Eina_List *tl = NULL, *l;
987 Elm_Object_Item *eo_it2;
989 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
991 EINA_LIST_FOREACH(it->item->items, l, eo_it2)
992 tl = eina_list_append(tl, eo_it2);
993 EINA_LIST_FREE(tl, eo_it2)
994 eo_do(eo_it2, elm_wdg_item_del());
998 _item_auto_scroll(Elm_Genlist_Data *sd)
1000 Elm_Object_Item *eo_tmp_item = NULL;
1002 if ((sd->expanded_item) && (sd->auto_scroll_enabled))
1004 eo_tmp_item = eina_list_data_get
1005 (eina_list_last(sd->expanded_item->item->items));
1006 if (!eo_tmp_item) return;
1007 ELM_GENLIST_ITEM_DATA_GET(eo_tmp_item, tmp_item);
1008 sd->show_item = tmp_item;
1009 sd->bring_in = EINA_TRUE;
1010 sd->scroll_to_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
1011 if ((sd->show_item->item->queued) || (!sd->show_item->item->mincalcd))
1013 sd->show_item->item->show_me = EINA_TRUE;
1014 sd->auto_scroll_enabled = EINA_FALSE;
1022 _item_tree_effect_finish(Elm_Genlist_Data *sd)
1024 Elm_Object_Item *eo_it = NULL;
1027 if (sd->tree_effect_animator)
1029 if (sd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_CONTRACT)
1030 _item_sub_items_clear(sd->expanded_item);
1032 EINA_LIST_FOREACH(sd->expanded_item->item->items, l, eo_it)
1034 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
1035 it->item->tree_effect_finished = EINA_TRUE;
1036 it->item->old_scrl_y = it->item->scrl_y;
1037 if (GL_IT(it)->wsd->move_effect_mode ==
1038 ELM_GENLIST_TREE_EFFECT_EXPAND)
1041 edje_object_signal_emit(VIEW(it), SIGNAL_SHOW, "");
1042 edje_object_signal_emit(VIEW(it), SIGNAL_SHOW, "elm");
1047 _item_auto_scroll(sd);
1048 evas_object_lower(sd->event_block_rect);
1049 evas_object_hide(sd->event_block_rect);
1050 sd->move_effect_mode = ELM_GENLIST_TREE_EFFECT_NONE;
1051 sd->move_items = eina_list_free(sd->move_items);
1053 evas_object_smart_callback_call(sd->pan_obj, "changed", NULL);
1054 evas_object_smart_callback_call
1055 (sd->obj, SIG_TREE_EFFECT_FINISHED, NULL);
1056 evas_object_smart_changed(sd->pan_obj);
1058 sd->tree_effect_animator = NULL;
1062 _elm_genlist_item_position_state_update(Elm_Gen_Item *it)
1064 unsigned idx = it->item->order_num_in;
1066 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
1068 if (!it->item->nostacking)
1070 if ((idx & 0x1) ^ it->item->stacking_even)
1072 if (it->deco_all_view) evas_object_stack_below(it->deco_all_view, sd->stack[0]);
1073 else evas_object_stack_below(VIEW(it), sd->stack[0]);
1077 if (it->deco_all_view) evas_object_stack_above(it->deco_all_view, sd->stack[0]);
1078 else evas_object_stack_above(VIEW(it), sd->stack[0]);
1084 edje_object_signal_emit(VIEW(it), SIGNAL_ODD, "elm");
1085 if (it->deco_all_view)
1086 edje_object_signal_emit(it->deco_all_view, SIGNAL_ODD, "elm");
1090 edje_object_signal_emit(VIEW(it), SIGNAL_EVEN, "elm");
1091 if (it->deco_all_view)
1092 edje_object_signal_emit(it->deco_all_view, SIGNAL_EVEN, "elm");
1095 if (sd->item_count == 1)
1097 edje_object_signal_emit(VIEW(it), SIGNAL_LIST_SINGLE, "elm");
1098 if (it->deco_all_view)
1099 edje_object_signal_emit(it->deco_all_view, SIGNAL_LIST_SINGLE, "elm");
1103 edje_object_signal_emit(VIEW(it), SIGNAL_LIST_FIRST, "elm");
1104 if (it->deco_all_view)
1105 edje_object_signal_emit(it->deco_all_view, SIGNAL_LIST_FIRST, "elm");
1107 else if (idx == sd->item_count - 1)
1109 edje_object_signal_emit(VIEW(it), SIGNAL_LIST_LAST, "elm");
1110 if (it->deco_all_view)
1111 edje_object_signal_emit(it->deco_all_view, SIGNAL_LIST_LAST, "elm");
1115 edje_object_signal_emit(VIEW(it), SIGNAL_LIST_MIDDLE, "elm");
1116 if (it->deco_all_view)
1117 edje_object_signal_emit(it->deco_all_view, SIGNAL_LIST_MIDDLE, "elm");
1122 unsigned first_idx = it->parent->item->order_num_in + 1;
1123 unsigned count = eina_list_count(it->parent->item->items);
1127 edje_object_signal_emit(VIEW(it), SIGNAL_GROUP_SINGLE, "elm");
1128 if (it->deco_all_view)
1129 edje_object_signal_emit(it->deco_all_view, SIGNAL_GROUP_SINGLE,
1132 else if (idx == first_idx)
1134 edje_object_signal_emit(VIEW(it), SIGNAL_GROUP_FIRST, "elm");
1135 if (it->deco_all_view)
1136 edje_object_signal_emit(it->deco_all_view, SIGNAL_GROUP_FIRST,
1139 else if (EO_OBJ(it) == eina_list_data_get(eina_list_last(it->parent->item->items)))
1141 edje_object_signal_emit(VIEW(it), SIGNAL_GROUP_LAST, "elm");
1142 if (it->deco_all_view)
1143 edje_object_signal_emit(it->deco_all_view, SIGNAL_GROUP_LAST,
1146 else if (idx > first_idx)
1148 edje_object_signal_emit(VIEW(it), SIGNAL_GROUP_MIDDLE, "elm");
1149 if (it->deco_all_view)
1150 edje_object_signal_emit(it->deco_all_view, SIGNAL_GROUP_MIDDLE,
1157 _item_order_update(const Eina_Inlist *l,
1160 Elm_Gen_Item *it, *it2;
1163 * always update position state of previous item, it may have been
1164 * marked as "single" if it was the only element at the time, or
1165 * "middle", "first" or "last" in the case of insert into different
1168 if ((l->prev) && (start > 0))
1170 it = ELM_GEN_ITEM_FROM_INLIST(l->prev);
1171 it->item->order_num_in = start - 1;
1172 _elm_genlist_item_position_state_update(it);
1175 for (it = ELM_GEN_ITEM_FROM_INLIST(l); l; l = l->next,
1176 it = ELM_GEN_ITEM_FROM_INLIST(l))
1178 it->item->order_num_in = start++;
1179 _elm_genlist_item_position_state_update(it);
1180 it2 = ELM_GEN_ITEM_FROM_INLIST(l->next);
1181 if (it2 && (it->item->order_num_in != it2->item->order_num_in))
1187 _elm_genlist_item_state_update(Elm_Gen_Item *it,
1192 if (it->selected != itc->selected)
1196 edje_object_signal_emit(VIEW(it), SIGNAL_SELECTED, "elm");
1197 if (it->deco_all_view)
1198 edje_object_signal_emit
1199 (it->deco_all_view, SIGNAL_SELECTED, "elm");
1202 if (eo_do(EO_OBJ(it), elm_wdg_item_disabled_get()) != itc->disabled)
1204 if (eo_do(EO_OBJ(it), elm_wdg_item_disabled_get()))
1205 edje_object_signal_emit(VIEW(it), SIGNAL_DISABLED,"elm");
1206 if (it->deco_all_view)
1207 edje_object_signal_emit
1208 (it->deco_all_view, SIGNAL_DISABLED, "elm");
1210 if (it->item->expanded != itc->expanded)
1212 if (it->item->expanded)
1213 edje_object_signal_emit(VIEW(it), SIGNAL_EXPANDED, "elm");
1214 if (it->deco_all_view)
1215 edje_object_signal_emit
1216 (it->deco_all_view, SIGNAL_EXPANDED, "elm");
1223 edje_object_signal_emit(VIEW(it), SIGNAL_SELECTED, "elm");
1224 if (it->deco_all_view)
1225 edje_object_signal_emit
1226 (it->deco_all_view, SIGNAL_SELECTED, "elm");
1228 if (eo_do(EO_OBJ(it), elm_wdg_item_disabled_get()))
1230 edje_object_signal_emit(VIEW(it), SIGNAL_DISABLED, "elm");
1231 if (it->deco_all_view)
1232 edje_object_signal_emit
1233 (it->deco_all_view, SIGNAL_DISABLED, "elm");
1235 if (it->item->expanded)
1237 edje_object_signal_emit(VIEW(it), SIGNAL_EXPANDED, "elm");
1238 if (it->deco_all_view)
1239 edje_object_signal_emit
1240 (it->deco_all_view, SIGNAL_EXPANDED, "elm");
1243 if (it == (Elm_Gen_Item *)GL_IT(it)->wsd->focused_item &&
1244 elm_widget_focus_highlight_enabled_get(WIDGET(it)))
1245 edje_object_signal_emit(VIEW(it), SIGNAL_FOCUSED, "elm");
1249 _view_inflate(Evas_Object *view, Elm_Gen_Item *it, Eina_List **sources,
1250 Eina_List **contents)
1253 if (sources) _item_text_realize(it, view, sources, NULL);
1254 if (contents) _item_content_realize(it, view, contents, "contents", NULL);
1255 _item_state_realize(it, view, NULL);
1259 _elm_genlist_item_index_update(Elm_Gen_Item *it)
1261 if (it->position_update || GL_IT(it)->block->position_update)
1263 evas_object_smart_callback_call(WIDGET(it), SIG_INDEX_UPDATE,
1265 it->position_update = EINA_FALSE;
1270 _decorate_all_item_position(Elm_Gen_Item *it,
1274 if ((!it) || (!GL_IT(it)->wsd->decorate_all_mode)) return;
1275 evas_object_resize(it->deco_all_view, it->item->w, it->item->h);
1276 evas_object_move(it->deco_all_view, itx, ity);
1280 _decorate_all_item_realize(Elm_Gen_Item *it,
1281 Eina_Bool effect_on)
1284 const char *stacking;
1285 const char *stacking_even;
1288 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
1290 if (it->item->decorate_all_item_realized) return;
1292 it->deco_all_view = edje_object_add(evas_object_evas_get(WIDGET(it)));
1293 edje_object_scale_set(it->deco_all_view, elm_widget_scale_get(WIDGET(it)) *
1294 elm_config_scale_get());
1295 evas_object_smart_member_add(it->deco_all_view, sd->pan_obj);
1296 elm_widget_sub_object_add(WIDGET(it), it->deco_all_view);
1298 if (it->item->type & ELM_GENLIST_ITEM_TREE)
1299 strncpy(buf, "tree", sizeof(buf));
1300 else strncpy(buf, "item", sizeof(buf));
1301 if (sd->mode == ELM_LIST_COMPRESS)
1302 strncat(buf, "_compress", sizeof(buf) - strlen(buf) - 1);
1304 strncat(buf, "/", sizeof(buf) - strlen(buf) - 1);
1305 strncat(buf, it->itc->decorate_all_item_style, sizeof(buf) - strlen(buf) - 1);
1307 elm_widget_theme_object_set(WIDGET(it), it->deco_all_view, "genlist", buf,
1308 elm_widget_style_get(WIDGET(it)));
1310 stacking_even = edje_object_data_get(VIEW(it), "stacking_even");
1311 if (!stacking_even) stacking_even = "above";
1312 it->item->stacking_even = !!strcmp("above", stacking_even);
1314 stacking = edje_object_data_get(VIEW(it), "stacking");
1315 if (!stacking) stacking = "yes";
1316 it->item->nostacking = !!strcmp("yes", stacking);
1318 edje_object_mirrored_set
1319 (it->deco_all_view, elm_widget_mirrored_get(WIDGET(it)));
1321 _elm_genlist_item_position_state_update(it);
1322 _elm_genlist_item_state_update(it, NULL);
1324 if (GL_IT(it)->wsd->reorder_mode)
1326 edje_object_signal_emit(it->deco_all_view, SIGNAL_REORDER_MODE_UNSET,
1331 edje_object_signal_emit
1332 (it->deco_all_view, SIGNAL_DECORATE_ENABLED_EFFECT, "elm");
1334 edje_object_signal_emit
1335 (it->deco_all_view, SIGNAL_DECORATE_ENABLED, "elm");
1337 _item_mouse_callbacks_del(it, VIEW(it));
1338 _item_mouse_callbacks_add(it, it->deco_all_view);
1341 edje_object_signal_emit
1342 (it->deco_all_view, SIGNAL_FLIP_ENABLED, "elm");
1343 _view_inflate(it->deco_all_view, it, NULL, &(GL_IT(it)->deco_all_contents));
1344 edje_object_part_swallow
1345 (it->deco_all_view, "elm.swallow.decorate.content", VIEW(it));
1347 _decorate_all_item_position(it, it->item->scrl_x, it->item->scrl_y);
1348 evas_object_show(it->deco_all_view);
1351 edje_object_signal_emit(it->deco_all_view, SIGNAL_SELECTED, "elm");
1353 it->item->decorate_all_item_realized = EINA_TRUE;
1354 it->want_unrealize = EINA_FALSE;
1357 //-- tree expand/contract signal handle routine --//
1359 _expand_toggle_signal_cb(void *data,
1360 Evas_Object *obj EINA_UNUSED,
1361 const char *emission EINA_UNUSED,
1362 const char *source EINA_UNUSED)
1364 Elm_Gen_Item *it = data;
1366 if (it->item->expanded)
1367 evas_object_smart_callback_call(WIDGET(it), SIG_CONTRACT_REQUEST, EO_OBJ(it));
1369 evas_object_smart_callback_call(WIDGET(it), SIG_EXPAND_REQUEST, EO_OBJ(it));
1373 _expand_signal_cb(void *data,
1374 Evas_Object *obj EINA_UNUSED,
1375 const char *emission EINA_UNUSED,
1376 const char *source EINA_UNUSED)
1378 Elm_Gen_Item *it = data;
1380 if (!it->item->expanded)
1381 evas_object_smart_callback_call(WIDGET(it), SIG_EXPAND_REQUEST, EO_OBJ(it));
1385 _contract_signal_cb(void *data,
1386 Evas_Object *obj EINA_UNUSED,
1387 const char *emission EINA_UNUSED,
1388 const char *source EINA_UNUSED)
1390 Elm_Gen_Item *it = data;
1392 if (it->item->expanded)
1393 evas_object_smart_callback_call(WIDGET(it), SIG_CONTRACT_REQUEST, EO_OBJ(it));
1396 //-- item cache handle routine --//
1397 // clean up item cache by removing overflowed caches
1399 _item_cache_clean(Elm_Genlist_Data *sd)
1401 evas_event_freeze(evas_object_evas_get(sd->obj));
1403 while ((sd->item_cache) && (sd->item_cache_count > sd->item_cache_max))
1407 itc = EINA_INLIST_CONTAINER_GET(sd->item_cache->last, Item_Cache);
1408 sd->item_cache = eina_inlist_remove
1409 (sd->item_cache, sd->item_cache->last);
1410 sd->item_cache_count--;
1411 evas_object_del(itc->spacer);
1412 evas_object_del(itc->base_view);
1413 eina_stringshare_del(itc->item_style);
1416 evas_event_thaw(evas_object_evas_get(sd->obj));
1417 evas_event_thaw_eval(evas_object_evas_get(sd->obj));
1420 // free one item cache
1422 _item_cache_free(Item_Cache *itc)
1424 evas_object_del(itc->spacer);
1425 evas_object_del(itc->base_view);
1426 eina_stringshare_del(itc->item_style);
1430 // empty all item caches
1432 _item_cache_zero(Elm_Genlist_Data *sd)
1434 int pmax = sd->item_cache_max;
1436 sd->item_cache_max = 0;
1437 _item_cache_clean(sd);
1438 sd->item_cache_max = pmax;
1441 // add an item to item cache
1443 _item_cache_add(Elm_Gen_Item *it)
1446 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
1447 Evas_Object *obj = sd->obj;
1449 evas_event_freeze(evas_object_evas_get(obj));
1450 if (sd->item_cache_max <= 0)
1452 ELM_SAFE_FREE(VIEW(it), evas_object_del);
1453 ELM_SAFE_FREE(it->spacer, evas_object_del);
1455 evas_event_thaw(evas_object_evas_get(obj));
1456 evas_event_thaw_eval(evas_object_evas_get(obj));
1461 sd->item_cache_count++;
1462 itc = calloc(1, sizeof(Item_Cache));
1465 evas_event_thaw(evas_object_evas_get(obj));
1466 evas_event_thaw_eval(evas_object_evas_get(obj));
1470 eina_inlist_prepend(sd->item_cache, EINA_INLIST_GET(itc));
1471 itc->spacer = it->spacer;
1473 itc->base_view = VIEW(it);
1476 edje_object_signal_emit(itc->base_view, SIGNAL_UNSELECTED, "elm");
1477 evas_object_hide(itc->base_view);
1478 evas_object_move(itc->base_view, -9999, -9999);
1479 itc->item_style = eina_stringshare_add(it->itc->item_style);
1480 if (it->item->type & ELM_GENLIST_ITEM_TREE) itc->tree = 1;
1481 itc->selected = it->selected;
1482 itc->disabled = eo_do(EO_OBJ(it), elm_wdg_item_disabled_get());
1483 itc->expanded = it->item->expanded;
1484 ELM_SAFE_FREE(it->long_timer, ecore_timer_del);
1485 ELM_SAFE_FREE(it->item->swipe_timer, ecore_timer_del);
1487 // FIXME: other callbacks?
1488 edje_object_signal_callback_del_full
1489 (itc->base_view, "elm,action,expand,toggle", "elm",
1490 _expand_toggle_signal_cb, it);
1491 edje_object_signal_callback_del_full
1492 (itc->base_view, "elm,action,expand", "elm", _expand_signal_cb, it);
1493 edje_object_signal_callback_del_full
1494 (itc->base_view, "elm,action,contract", "elm", _contract_signal_cb, it);
1495 _item_mouse_callbacks_del(it, itc->base_view);
1496 _item_cache_clean(sd);
1498 evas_event_thaw(evas_object_evas_get(obj));
1499 evas_event_thaw_eval(evas_object_evas_get(obj));
1502 // find an item from item cache and remove it from the cache
1504 _item_cache_find(Elm_Gen_Item *it)
1506 Item_Cache *itc = NULL;
1509 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
1511 if (it->item->type & ELM_GENLIST_ITEM_TREE) tree = 1;
1512 EINA_INLIST_FOREACH_SAFE(sd->item_cache, l, itc)
1514 if ((itc->selected) || (itc->disabled) || (itc->expanded))
1517 if ((itc->tree == tree) &&
1518 (((!it->itc->item_style) && (!itc->item_style)) ||
1519 (it->itc->item_style && itc->item_style &&
1520 (!strcmp(it->itc->item_style, itc->item_style)))))
1523 eina_inlist_remove (sd->item_cache, EINA_INLIST_GET(itc));
1524 sd->item_cache_count--;
1533 _access_info_cb(void *data, Evas_Object *obj EINA_UNUSED)
1538 Elm_Gen_Item *it = (Elm_Gen_Item *)data;
1539 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, NULL);
1541 buf = eina_strbuf_new();
1543 if (it->itc->func.text_get)
1548 if (!(it->texts)) it->texts =
1549 elm_widget_stringlist_get(edje_object_data_get(VIEW(it), "texts"));
1551 EINA_LIST_FOREACH(it->texts, l, key)
1553 char *s = it->itc->func.text_get
1554 ((void *)WIDGET_ITEM_DATA_GET(EO_OBJ(it)), WIDGET(it), key);
1558 if (eina_strbuf_length_get(buf) > 0) eina_strbuf_append(buf, ", ");
1559 eina_strbuf_append(buf, s);
1565 ret = eina_strbuf_string_steal(buf);
1566 eina_strbuf_free(buf);
1571 _access_state_cb(void *data, Evas_Object *obj EINA_UNUSED)
1573 Elm_Gen_Item *it = (Elm_Gen_Item *)data;
1574 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, NULL);
1576 if (it->base->disabled)
1577 return strdup(E_("State: Disabled"));
1583 _access_on_highlight_cb(void *data)
1585 Evas_Coord x, y, w, h;
1586 Evas_Coord sx, sy, sw, sh;
1587 Elm_Gen_Item *it = (Elm_Gen_Item *)data;
1588 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
1590 evas_object_geometry_get(it->base->view, &x, &y, &w, &h);
1591 // XXX There would be a reason.
1592 if ((w == 0) && (h == 0)) return;
1594 evas_object_geometry_get(it->base->widget, &sx, &sy, &sw, &sh);
1595 if ((x < sx) || (y < sy) || ((x + w) > (sx + sw)) || ((y + h) > (sy + sh)))
1596 elm_genlist_item_bring_in(EO_OBJ(it),
1597 ELM_GENLIST_ITEM_SCROLLTO_IN);
1601 _access_widget_item_register(Elm_Gen_Item *it)
1603 Elm_Access_Info *ai;
1605 _elm_access_widget_item_register(it->base);
1607 ai = _elm_access_info_get(it->base->access_obj);
1609 _elm_access_callback_set(ai, ELM_ACCESS_INFO, _access_info_cb, it);
1610 _elm_access_callback_set(ai, ELM_ACCESS_STATE, _access_state_cb, it);
1611 _elm_access_on_highlight_hook_set(ai, _access_on_highlight_cb, it);
1612 _elm_access_activate_callback_set(ai, _access_activate_cb, EO_OBJ(it));
1616 _item_realize(Elm_Gen_Item *it,
1620 Item_Cache *itc = NULL;
1621 const char *treesize;
1623 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
1627 if (it->item->order_num_in != in)
1629 _item_order_update(EINA_INLIST_GET(it), in);
1630 _elm_genlist_item_state_update(it, NULL);
1631 _elm_genlist_item_index_update(it);
1635 it->item->order_num_in = in;
1637 if (it->item->nocache_once)
1638 it->item->nocache_once = EINA_FALSE;
1639 else if (!it->item->nocache)
1640 itc = _item_cache_find(it);
1641 if (itc && (!sd->tree_effect_enabled))
1643 VIEW(it) = itc->base_view;
1644 itc->base_view = NULL;
1645 it->spacer = itc->spacer;
1649 VIEW(it) = _view_create(it, it->itc->item_style);
1652 if (_elm_config->access_mode) _access_widget_item_register(it);
1654 _item_order_update(EINA_INLIST_GET(it), in);
1656 if (sd->reorder_mode)
1657 edje_object_signal_emit(VIEW(it), SIGNAL_REORDER_MODE_SET, "elm");
1659 edje_object_signal_emit(VIEW(it), SIGNAL_REORDER_MODE_UNSET, "elm");
1661 treesize = edje_object_data_get(VIEW(it), "treesize");
1662 if (treesize) tsize = atoi(treesize);
1664 if (edje_object_part_exists(VIEW(it), "elm.swallow.pad"))
1666 if (!it->spacer && treesize)
1669 evas_object_rectangle_add(evas_object_evas_get(WIDGET(it)));
1670 evas_object_color_set(it->spacer, 0, 0, 0, 0);
1671 elm_widget_sub_object_add(WIDGET(it), it->spacer);
1674 evas_object_size_hint_min_set
1675 (it->spacer, (it->item->expanded_depth * tsize) *
1676 elm_config_scale_get(), 1);
1677 edje_object_part_swallow(VIEW(it), "elm.swallow.pad", it->spacer);
1681 ELM_SAFE_FREE(it->spacer, evas_object_del);
1686 edje_object_signal_callback_add
1687 (VIEW(it), "elm,action,expand,toggle", "elm",
1688 _expand_toggle_signal_cb, it);
1689 edje_object_signal_callback_add
1690 (VIEW(it), "elm,action,expand", "elm", _expand_signal_cb, it);
1691 edje_object_signal_callback_add
1692 (VIEW(it), "elm,action,contract", "elm", _contract_signal_cb, it);
1693 _item_mouse_callbacks_add(it, VIEW(it));
1695 if ((sd->decorate_all_mode) && (!it->deco_all_view) &&
1696 (it->item->type != ELM_GENLIST_ITEM_GROUP) &&
1697 (it->itc->decorate_all_item_style))
1698 _decorate_all_item_realize(it, EINA_FALSE);
1700 _elm_genlist_item_state_update(it, itc);
1701 _elm_genlist_item_index_update(it);
1704 /* homogeneous genlist shortcut */
1705 if ((calc) && (sd->homogeneous) && (!it->item->mincalcd) &&
1706 (((GL_IT(it)->type & ELM_GENLIST_ITEM_GROUP) && sd->group_item_width) ||
1707 (!(GL_IT(it)->type & ELM_GENLIST_ITEM_GROUP) && sd->item_width)))
1709 if (GL_IT(it)->type & ELM_GENLIST_ITEM_GROUP)
1711 it->item->w = it->item->minw = sd->group_item_width;
1712 it->item->h = it->item->minh = sd->group_item_height;
1716 it->item->w = it->item->minw = sd->item_width;
1717 it->item->h = it->item->minh = sd->item_height;
1719 it->item->mincalcd = EINA_TRUE;
1723 if (eina_list_count(it->contents) != 0)
1724 ERR_ABORT("If you see this error, please notify us and we"
1727 _view_inflate(VIEW(it), it, &it->texts, &it->contents);
1728 if (it->has_contents != (!!it->contents))
1729 it->item->mincalcd = EINA_FALSE;
1730 it->has_contents = !!it->contents;
1733 edje_object_signal_emit(VIEW(it), SIGNAL_FLIP_ENABLED, "elm");
1734 _item_content_realize(it, VIEW(it), &GL_IT(it)->flip_contents,
1738 /* access: unregister item which have no text and content */
1739 if (_elm_config->access_mode && !it->texts && !it->contents)
1740 _elm_access_widget_item_unregister(it->base);
1742 if (!it->item->mincalcd)
1744 Evas_Coord mw = -1, mh = -1;
1746 if (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
1747 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
1748 if (sd->mode == ELM_LIST_COMPRESS)
1749 mw = sd->prev_viewport_w;
1750 edje_object_size_min_restricted_calc(VIEW(it), &mw, &mh, mw, mh);
1751 if (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
1752 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
1753 it->item->w = it->item->minw = mw;
1754 it->item->h = it->item->minh = mh;
1755 it->item->mincalcd = EINA_TRUE;
1757 if ((!sd->group_item_width) &&
1758 (GL_IT(it)->type & ELM_GENLIST_ITEM_GROUP))
1760 sd->group_item_width = mw;
1761 sd->group_item_height = mh;
1763 else if ((!sd->item_width) &&
1764 (it->item->type == ELM_GENLIST_ITEM_NONE))
1766 sd->item_width = mw;
1767 sd->item_height = mh;
1770 if (!calc) evas_object_show(VIEW(it));
1773 if (it->tooltip.content_cb)
1776 elm_wdg_item_tooltip_content_cb_set(
1777 it->tooltip.content_cb, it->tooltip.data, NULL),
1778 elm_wdg_item_tooltip_style_set(it->tooltip.style),
1779 elm_wdg_item_tooltip_window_mode_set(it->tooltip.free_size));
1782 if (it->mouse_cursor)
1784 elm_wdg_item_cursor_set(it->mouse_cursor));
1786 it->realized = EINA_TRUE;
1787 it->want_unrealize = EINA_FALSE;
1789 if (itc) _item_cache_free(itc);
1792 if (it->item->tree_effect_hide_me)
1794 if (sd->move_effect_mode
1795 != ELM_GENLIST_TREE_EFFECT_NONE)
1798 edje_object_signal_emit(VIEW(it), SIGNAL_HIDE, "");
1799 edje_object_signal_emit(VIEW(it), SIGNAL_HIDE, "elm");
1801 it->item->tree_effect_hide_me = EINA_FALSE;
1804 if (it->item->type == ELM_GENLIST_ITEM_NONE)
1808 EINA_LIST_FOREACH(it->contents, l, eobj)
1809 if (elm_widget_is(eobj) && elm_object_focus_allow_get(eobj))
1810 it->item_focus_chain = eina_list_append
1811 (it->item_focus_chain, eobj);
1815 if (it->item->type == ELM_GENLIST_ITEM_TREE)
1817 Evas_Object* t_eobj;
1819 EINA_LIST_FOREACH(it->contents, tl, t_eobj)
1820 if (elm_widget_is(t_eobj) && elm_object_focus_allow_get(t_eobj))
1821 it->item_focus_chain = eina_list_append
1822 (it->item_focus_chain, t_eobj);
1826 evas_object_smart_callback_call(WIDGET(it), SIG_REALIZED, EO_OBJ(it));
1829 //Send a signal so that an item changes its style according to its expand depth
1830 if (GL_IT(it)->expanded_depth > 0)
1833 snprintf(buf, sizeof(buf), "elm,state,expanded_depth,%d",
1834 GL_IT(it)->expanded_depth);
1835 edje_object_signal_emit(VIEW(it), buf, "elm");
1838 if ((!calc) && (sd->decorate_all_mode) &&
1839 (it->item->type != ELM_GENLIST_ITEM_GROUP))
1841 if (it->itc->decorate_all_item_style)
1843 if (!it->deco_all_view)
1844 _decorate_all_item_realize(it, EINA_FALSE);
1845 edje_object_message_signal_process(it->deco_all_view);
1849 if (it->decorate_it_set) _decorate_item_set(it);
1851 edje_object_message_signal_process(VIEW(it));
1855 _tree_effect_animator_cb(void *data)
1859 int y = 0, dy = 0, dh = 0;
1860 double effect_duration = 0.3, t;
1861 ELM_GENLIST_DATA_GET(data, sd);
1862 Eina_Bool end = EINA_FALSE, vis = EINA_TRUE;
1863 Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh;
1864 Elm_Gen_Item *it = NULL, *it2, *expanded_next_it;
1865 Elm_Object_Item *eo_it = NULL, *eo_it2;
1867 t = ((0.0 > (t = ecore_time_get() - sd->start_time)) ? 0.0 : t);
1868 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
1869 evas_output_viewport_get
1870 (evas_object_evas_get(sd->pan_obj), &cvx, &cvy, &cvw, &cvh);
1871 if (t > effect_duration) end = EINA_TRUE;
1873 // Below while statement is needed, when the genlist is resized.
1874 it2 = sd->expanded_item;
1875 eo_it2 = EO_OBJ(it2);
1876 while (eo_it2 && vis)
1878 it2 = eo_data_scope_get(eo_it2, ELM_GENLIST_ITEM_CLASS);
1879 evas_object_move(VIEW(it2), it2->item->scrl_x, it2->item->scrl_y);
1880 vis = (ELM_RECTS_INTERSECT(it2->item->scrl_x, it2->item->scrl_y,
1881 it2->item->w, it2->item->h, cvx, cvy, cvw,
1883 eo_it2 = elm_genlist_item_prev_get(eo_it2);
1886 if (sd->expanded_next_item)
1888 expanded_next_it = sd->expanded_next_item;
1891 EINA_LIST_FOREACH(sd->move_items, l, it)
1893 if (sd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
1895 expanded_next_it->item->old_scrl_y =
1896 sd->expanded_item->item->old_scrl_y
1897 + sd->expanded_item->item->h;
1898 if (expanded_next_it->item->scrl_y <=
1899 expanded_next_it->item->old_scrl_y) /* did not
1903 expanded_next_it->item->scrl_y = cvy + cvh;
1905 dy = ((expanded_next_it->item->scrl_y >= (cvy + cvh)) ?
1906 cvy + cvh : expanded_next_it->item->scrl_y) -
1907 expanded_next_it->item->old_scrl_y;
1909 else if (sd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_CONTRACT)
1911 if (expanded_next_it->item->scrl_y >
1912 expanded_next_it->item->old_scrl_y) /* did not
1916 expanded_next_it->item->old_scrl_y = cvy + cvh;
1918 if (expanded_next_it->item->old_scrl_y > (cvy + cvh))
1920 dy = (sd->expanded_item->item->scrl_y +
1921 sd->expanded_item->item->h) - cvy + cvh;
1922 expanded_next_it->item->old_scrl_y = cvy + cvh;
1926 dy = (sd->expanded_item->item->scrl_y +
1927 sd->expanded_item->item->h) -
1928 expanded_next_it->item->old_scrl_y;
1932 if (t <= effect_duration)
1934 y = ((1 - (1 - (t / effect_duration)) *
1935 (1 - (t / effect_duration))) * dy);
1943 if (!it->realized && !it->item->queued)
1944 _item_realize(it, in, 0);
1947 if (it != expanded_next_it)
1949 it->item->old_scrl_y =
1950 expanded_next_it->item->old_scrl_y +
1951 expanded_next_it->item->h + dh;
1956 if ((it->item->old_scrl_y + y) < (cvy + cvh))
1957 _item_position(it, VIEW(it), it->item->scrl_x,
1958 it->item->old_scrl_y + y);
1961 _item_tree_effect(sd, y);
1965 int expanded_item_num = 0;
1968 if (sd->expanded_item)
1969 eo_it = elm_genlist_item_next_get(EO_OBJ(sd->expanded_item));
1974 expanded_item_num++;
1975 eo_it2 = elm_genlist_item_next_get(eo_it2);
1980 it = eo_data_scope_get(eo_it, ELM_GENLIST_ITEM_CLASS);
1982 if (sd->expanded_item->item->expanded_depth >=
1983 it->item->expanded_depth) break;
1984 if (sd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
1986 if (!it->item->tree_effect_finished)
1988 if (t >= (((num - 1) * effect_duration) /
1992 edje_object_signal_emit(VIEW(it), "flip_item", "");
1993 edje_object_signal_emit(VIEW(it), SIGNAL_FLIP_ITEM,
1995 _item_position(it, VIEW(it), it->item->scrl_x,
1997 it->item->tree_effect_finished = EINA_TRUE;
2001 eo_it = elm_genlist_item_next_get(eo_it);
2007 _item_tree_effect_finish(sd);
2008 return ECORE_CALLBACK_CANCEL;
2011 return ECORE_CALLBACK_RENEW;
2015 _group_items_recalc(void *data)
2019 Elm_Genlist_Data *sd = data;
2021 evas_event_freeze(evas_object_evas_get(sd->obj));
2022 EINA_LIST_FOREACH(sd->group_items, l, git)
2024 if (git->item->want_realize)
2026 if (!git->realized) _item_realize(git, 0, EINA_FALSE);
2027 evas_object_resize(VIEW(git), sd->minw, git->item->h);
2028 evas_object_move(VIEW(git), git->item->scrl_x, git->item->scrl_y);
2029 evas_object_stack_above(VIEW(git), sd->stack[1]);
2030 evas_object_show(VIEW(git));
2032 else if (!git->item->want_realize && git->realized)
2035 _elm_genlist_item_unrealize(git, EINA_FALSE);
2038 evas_event_thaw(evas_object_evas_get(sd->obj));
2039 evas_event_thaw_eval(evas_object_evas_get(sd->obj));
2043 _reorder_move_animator_cb(void *data)
2046 Elm_Gen_Item *it = data;
2047 Eina_Bool down = EINA_FALSE;
2048 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
2049 int y, dy = it->item->h / 10 * elm_config_scale_get(), diff;
2051 t = ((0.0 > (t = ecore_loop_time_get()
2052 - sd->start_time)) ? 0.0 : t);
2054 if (t <= REORDER_EFFECT_TIME)
2055 y = (1 * sin((t / REORDER_EFFECT_TIME) * (M_PI / 2)) * dy);
2058 diff = abs(it->item->old_scrl_y - it->item->scrl_y);
2059 if (diff < dy) y = diff;
2060 else if (diff > it->item->h) y = diff / 2;
2062 if (it->item->old_scrl_y < it->item->scrl_y)
2064 it->item->old_scrl_y += y;
2067 else if (it->item->old_scrl_y > it->item->scrl_y)
2069 it->item->old_scrl_y -= y;
2073 if (it->deco_all_view)
2075 (it, it->deco_all_view, it->item->scrl_x, it->item->old_scrl_y);
2077 _item_position(it, VIEW(it), it->item->scrl_x, it->item->old_scrl_y);
2078 _group_items_recalc(sd);
2080 if ((sd->reorder_pan_move) ||
2081 (down && it->item->old_scrl_y >= it->item->scrl_y) ||
2082 (!down && it->item->old_scrl_y <= it->item->scrl_y))
2084 it->item->old_scrl_y = it->item->scrl_y;
2085 it->item->move_effect_enabled = EINA_FALSE;
2086 sd->reorder_move_animator = NULL;
2087 return ECORE_CALLBACK_CANCEL;
2090 return ECORE_CALLBACK_RENEW;
2094 _reorder_item_space_get(Elm_Gen_Item *it)
2096 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
2097 Elm_Gen_Item *reorder_it = sd->reorder_it;
2098 Evas_Coord rox, roy, row, roh, oy, oh;
2099 Eina_Bool top = EINA_FALSE;
2101 if (!reorder_it) return 0;
2103 evas_object_geometry_get(sd->pan_obj, NULL, &oy, NULL, &oh);
2104 evas_object_geometry_get
2105 (sd->VIEW(reorder_it), &rox, &roy, &row, &roh);
2107 if ((sd->reorder_start_y < it->item->block->y) &&
2108 (roy - oy + (roh / 2) >= it->item->block->y - sd->pan_y))
2110 it->item->block->reorder_offset =
2111 sd->reorder_it->item->h * -1;
2112 if (it->item->block->count == 1)
2113 sd->reorder_rel = it;
2115 else if ((sd->reorder_start_y >= it->item->block->y) &&
2116 (roy - oy + (roh / 2) <= it->item->block->y - sd->pan_y))
2118 it->item->block->reorder_offset = sd->reorder_it->item->h;
2121 it->item->block->reorder_offset = 0;
2123 it->item->scrl_y += it->item->block->reorder_offset;
2125 top = (ELM_RECTS_INTERSECT
2126 (it->item->scrl_x, it->item->scrl_y, it->item->w, it->item->h,
2127 rox, roy + (roh / 2), row, 1));
2130 sd->reorder_rel = it;
2131 it->item->scrl_y += sd->reorder_it->item->h;
2132 return sd->reorder_it->item->h;
2139 _item_block_position(Item_Block *itb,
2145 Eina_Bool vis = EINA_FALSE;
2146 Evas_Coord y = 0, ox, oy, ow, oh, cvx, cvy, cvw, cvh;
2147 Elm_Genlist_Data *sd = NULL;
2149 evas_event_freeze(evas_object_evas_get((itb->sd)->obj));
2150 evas_object_geometry_get(itb->sd->pan_obj, &ox, &oy, &ow, &oh);
2151 evas_output_viewport_get
2152 (evas_object_evas_get((itb->sd)->obj),
2153 &cvx, &cvy, &cvw, &cvh);
2155 EINA_LIST_FOREACH(itb->items, l, it)
2157 sd = GL_IT(it)->wsd;
2158 if (sd->reorder_it == it) continue;
2162 it->item->w = itb->w;
2163 it->item->scrl_x = itb->x + it->x - sd->pan_x + ox;
2164 it->item->scrl_y = itb->y + it->y - sd->pan_y + oy;
2166 vis = (ELM_RECTS_INTERSECT
2167 (it->item->scrl_x, it->item->scrl_y, it->item->w, it->item->h,
2168 cvx, cvy, cvw, cvh));
2169 if (!(GL_IT(it)->type & ELM_GENLIST_ITEM_GROUP))
2171 if ((itb->realized) && (!it->realized))
2173 if (vis) _item_realize(it, in, EINA_FALSE);
2177 if (vis || it->dragging)
2179 if (sd->reorder_mode)
2180 y += _reorder_item_space_get(it);
2181 git = it->item->group_item;
2184 if (git->item->scrl_y < oy)
2185 git->item->scrl_y = oy;
2186 if ((git->item->scrl_y + git->item->h) >
2187 (it->item->scrl_y + it->item->h))
2188 git->item->scrl_y = (it->item->scrl_y +
2189 it->item->h) - git->item->h;
2190 git->item->scrl_x = it->item->scrl_x;
2191 git->item->want_realize = EINA_TRUE;
2193 if ((sd->reorder_it) &&
2194 (it->item->old_scrl_y != it->item->scrl_y))
2196 if (!it->item->move_effect_enabled)
2198 it->item->move_effect_enabled = EINA_TRUE;
2199 sd->reorder_move_animator =
2201 _reorder_move_animator_cb, it);
2204 if (!it->item->move_effect_enabled)
2206 if ((sd->decorate_all_mode) &&
2207 (it->itc->decorate_all_item_style))
2208 _decorate_all_item_position
2209 (it, it->item->scrl_x, it->item->scrl_y);
2212 if (!sd->tree_effect_enabled ||
2213 (sd->move_effect_mode ==
2214 ELM_GENLIST_TREE_EFFECT_NONE) ||
2215 ((sd->move_effect_mode !=
2216 ELM_GENLIST_TREE_EFFECT_NONE) &&
2217 (it->item->old_scrl_y ==
2220 if (it->item->deco_it_view)
2222 (it, it->item->deco_it_view,
2227 (it, VIEW(it), it->item->scrl_x,
2231 it->item->old_scrl_y = it->item->scrl_y;
2236 if (!sd->tree_effect_animator)
2237 _elm_genlist_item_unrealize(it, EINA_FALSE);
2244 if (vis) it->item->want_realize = EINA_TRUE;
2248 evas_event_thaw(evas_object_evas_get((itb->sd)->obj));
2249 evas_event_thaw_eval(evas_object_evas_get((itb->sd)->obj));
2253 _item_block_realize(Item_Block *itb)
2255 if (itb->realized) return;
2257 itb->realized = EINA_TRUE;
2258 itb->want_unrealize = EINA_FALSE;
2262 _elm_genlist_pan_evas_object_smart_calculate(Eo *obj, Elm_Genlist_Pan_Data *psd)
2264 Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh;
2265 Evas_Coord vx = 0, vy = 0, vw = 0, vh = 0;
2271 Elm_Genlist_Data *sd = psd->wsd;
2273 evas_event_freeze(evas_object_evas_get(obj));
2275 if (sd->pan_changed)
2277 ecore_job_del(sd->calc_job);
2278 sd->calc_job = NULL;
2280 sd->pan_changed = EINA_FALSE;
2283 evas_object_geometry_get(obj, &ox, &oy, &ow, &oh);
2284 evas_output_viewport_get(evas_object_evas_get(obj), &cvx, &cvy, &cvw, &cvh);
2285 EINA_LIST_FOREACH(sd->group_items, l, git)
2287 git->item->want_realize = EINA_FALSE;
2290 if (sd->tree_effect_enabled &&
2291 (sd->move_effect_mode != ELM_GENLIST_TREE_EFFECT_NONE))
2293 if (!sd->tree_effect_animator)
2295 _item_tree_effect_before(sd->expanded_item);
2296 evas_object_raise(sd->event_block_rect);
2297 evas_object_stack_below(sd->event_block_rect, sd->stack[1]);
2298 evas_object_show(sd->event_block_rect);
2299 sd->start_time = ecore_time_get();
2300 sd->tree_effect_animator =
2301 ecore_animator_add(_tree_effect_animator_cb, sd->obj);
2305 EINA_INLIST_FOREACH(sd->blocks, itb)
2308 if (ELM_RECTS_INTERSECT(itb->x - sd->pan_x + ox,
2309 itb->y - sd->pan_y + oy,
2311 cvx, cvy, cvw, cvh))
2313 if ((!itb->realized) || (itb->changed))
2314 _item_block_realize(itb);
2315 _item_block_position(itb, in);
2319 if (itb->realized) _item_block_unrealize(itb);
2323 if ((!sd->reorder_it) || (sd->reorder_pan_move))
2324 _group_items_recalc(sd);
2325 if ((sd->reorder_mode) && (sd->reorder_it))
2327 if (sd->pan_y != sd->reorder_old_pan_y)
2328 sd->reorder_pan_move = EINA_TRUE;
2329 else sd->reorder_pan_move = EINA_FALSE;
2331 evas_object_raise(sd->VIEW(reorder_it));
2332 evas_object_stack_below(sd->VIEW(reorder_it), sd->stack[1]);
2333 sd->reorder_old_pan_y = sd->pan_y;
2334 sd->start_time = ecore_loop_time_get();
2337 if (!sd->tree_effect_enabled ||
2338 (sd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_NONE))
2339 _item_auto_scroll(sd);
2342 elm_interface_scrollable_content_pos_get(&vx, &vy),
2343 elm_interface_scrollable_content_viewport_geometry_get
2344 (NULL, NULL, &vw, &vh));
2346 if (sd->reorder_fast == 1)
2347 eo_do((sd)->obj, elm_interface_scrollable_content_region_show(vx, vy - 10, vw, vh));
2348 else if (sd->reorder_fast == -1)
2349 eo_do((sd)->obj, elm_interface_scrollable_content_region_show(vx, vy + 10, vw, vh));
2351 if (sd->focused_item && !sd->item_loop_enable)
2352 _elm_widget_focus_highlight_start(psd->wobj);
2354 evas_event_thaw(evas_object_evas_get(obj));
2355 evas_event_thaw_eval(evas_object_evas_get(obj));
2359 _elm_genlist_pan_eo_base_destructor(Eo *obj, Elm_Genlist_Pan_Data *psd)
2361 eo_data_unref(psd->wobj, psd->wsd);
2362 eo_do_super(obj, MY_PAN_CLASS, eo_destructor());
2366 _elm_genlist_pan_class_constructor(Eo_Class *klass)
2368 evas_smart_legacy_type_register(MY_PAN_CLASS_NAME_LEGACY, klass);
2371 #include "elm_genlist_pan.eo.c"
2374 _item_multi_select_up(Elm_Genlist_Data *sd)
2376 Elm_Object_Item *eo_prev;
2378 if (!sd->selected) return EINA_FALSE;
2379 if (!sd->multi) return EINA_FALSE;
2381 eo_prev = elm_genlist_item_prev_get(sd->last_selected_item);
2384 ELM_GENLIST_ITEM_DATA_GET(eo_prev, prev);
2385 if ((!_is_no_select(prev)) && (!elm_object_item_disabled_get(eo_prev)))
2387 eo_prev = EO_OBJ(ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(prev)->prev));
2389 if (!eo_prev) return EINA_TRUE;
2391 if (elm_genlist_item_selected_get(eo_prev))
2393 elm_genlist_item_selected_set(sd->last_selected_item, EINA_FALSE);
2394 sd->last_selected_item = eo_prev;
2398 elm_genlist_item_selected_set(eo_prev, EINA_TRUE);
2404 _item_multi_select_down(Elm_Genlist_Data *sd)
2406 Elm_Object_Item *eo_next;
2408 if (!sd->selected) return EINA_FALSE;
2409 if (!sd->multi) return EINA_FALSE;
2411 eo_next = elm_genlist_item_next_get(sd->last_selected_item);
2414 ELM_GENLIST_ITEM_DATA_GET(eo_next, next);
2415 if ((_is_no_select(next)) && (!elm_object_item_disabled_get(eo_next)))
2417 eo_next = EO_OBJ(ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(next)->next));
2419 if (!eo_next) return EINA_TRUE;
2421 if (elm_genlist_item_selected_get(eo_next))
2423 elm_genlist_item_selected_set(sd->last_selected_item, EINA_FALSE);
2424 sd->last_selected_item = eo_next;
2428 elm_genlist_item_selected_set(eo_next, EINA_TRUE);
2435 _all_items_deselect(Elm_Genlist_Data *sd)
2437 if (!sd->selected) return EINA_FALSE;
2439 sd->deselecting = eina_list_clone(sd->selected);
2440 while (sd->deselecting)
2442 Elm_Object_Item *it = eina_list_data_get(sd->deselecting);
2444 sd->deselecting = eina_list_remove_list(sd->deselecting, sd->deselecting);
2445 elm_genlist_item_selected_set(it, EINA_FALSE);
2452 _item_single_select_up(Elm_Genlist_Data *sd)
2454 Elm_Gen_Item *prev = NULL;
2457 prev = ELM_GEN_ITEM_FROM_INLIST(sd->items->last);
2460 Elm_Object_Item *eo_prev = elm_genlist_item_prev_get
2461 (sd->last_selected_item);
2462 prev = eo_data_scope_get(eo_prev, ELM_GENLIST_ITEM_CLASS);
2467 if ((!_is_no_select(prev)) &&
2468 (!elm_object_item_disabled_get(EO_OBJ(prev))))
2470 prev = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(prev)->prev);
2473 if (!prev) return EINA_FALSE;
2475 _all_items_deselect(sd);
2477 elm_genlist_item_selected_set(EO_OBJ(prev), EINA_TRUE);
2482 _item_single_select_down(Elm_Genlist_Data *sd)
2484 Elm_Gen_Item *next = NULL;
2485 Elm_Object_Item *eo_next = NULL;
2488 next = ELM_GEN_ITEM_FROM_INLIST(sd->items);
2491 eo_next = elm_genlist_item_next_get(sd->last_selected_item);
2492 next = eo_data_scope_get(eo_next, ELM_GENLIST_ITEM_CLASS);
2497 if ((!_is_no_select(next)) &&
2498 (!elm_object_item_disabled_get(EO_OBJ(next))))
2500 next = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(next)->next);
2503 if (!next) return EINA_FALSE;
2505 _all_items_deselect(sd);
2507 elm_genlist_item_selected_set(EO_OBJ(next), EINA_TRUE);
2513 _elm_genlist_item_focused(Elm_Object_Item *eo_it)
2515 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
2516 Evas_Object *obj = WIDGET(it);
2517 ELM_GENLIST_DATA_GET(obj, sd);
2518 const char *focus_raise;
2520 if (_is_no_select(it) ||
2521 (eo_it == sd->focused_item) ||
2522 (eo_do(eo_it, elm_wdg_item_disabled_get())))
2525 switch (_elm_config->focus_autoscroll_mode)
2527 case ELM_FOCUS_AUTOSCROLL_MODE_SHOW:
2528 elm_genlist_item_show(eo_it,
2529 ELM_GENLIST_ITEM_SCROLLTO_IN);
2531 case ELM_FOCUS_AUTOSCROLL_MODE_BRING_IN:
2532 elm_genlist_item_bring_in(eo_it,
2533 ELM_GENLIST_ITEM_SCROLLTO_IN);
2539 sd->focused_item = eo_it;
2541 if (elm_widget_focus_highlight_enabled_get(obj))
2542 edje_object_signal_emit(VIEW(it), SIGNAL_FOCUSED, "elm");
2544 focus_raise = edje_object_data_get(VIEW(it), "focusraise");
2545 if ((focus_raise) && (!strcmp(focus_raise, "on")))
2546 evas_object_raise(VIEW(it));
2547 evas_object_smart_callback_call(obj, SIG_ITEM_FOCUSED, eo_it);
2551 _elm_genlist_item_unfocused(Elm_Object_Item *eo_it)
2555 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
2556 Evas_Object *obj = WIDGET(it);
2557 ELM_GENLIST_DATA_GET(obj, sd);
2559 if (_is_no_select(it))
2562 if ((!sd->focused_item) ||
2563 (eo_it != sd->focused_item))
2566 if (elm_widget_focus_highlight_enabled_get(obj))
2568 ELM_GENLIST_ITEM_DATA_GET(sd->focused_item, focus_it);
2569 edje_object_signal_emit(VIEW(focus_it), SIGNAL_UNFOCUSED, "elm");
2572 sd->focused_item = NULL;
2573 evas_object_smart_callback_call(obj, SIG_ITEM_UNFOCUSED, eo_it);
2577 _item_focused_next(Evas_Object *obj, Elm_Focus_Direction dir)
2579 ELM_GENLIST_DATA_GET(obj, sd);
2581 Elm_Object_Item *eo_next;
2582 Elm_Object_Item *eo_first_item;
2583 Elm_Object_Item *eo_last_item;
2585 if (!sd->focused_item)
2587 if (dir == ELM_FOCUS_UP)
2588 next = ELM_GEN_ITEM_FROM_INLIST(sd->items->last);
2589 else if (dir == ELM_FOCUS_DOWN)
2590 next = ELM_GEN_ITEM_FROM_INLIST(sd->items);
2595 (!eo_do(EO_OBJ(next), elm_wdg_item_disabled_get())))
2596 next = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(next)->next);
2600 ELM_GENLIST_ITEM_DATA_GET(sd->focused_item, focus_it);
2601 if (dir == ELM_FOCUS_UP)
2603 eo_first_item = elm_genlist_first_item_get(WIDGET(focus_it));
2604 if (eo_first_item == sd->focused_item) return EINA_FALSE;
2605 eo_next = elm_genlist_item_prev_get(sd->focused_item);
2606 next = eo_data_scope_get(eo_next, ELM_GENLIST_ITEM_CLASS);
2608 while (eo_do(eo_next, elm_wdg_item_disabled_get()))
2610 eo_next = elm_genlist_item_prev_get(eo_next);
2611 next = eo_data_scope_get(eo_next, ELM_GENLIST_ITEM_CLASS);
2614 else if (dir == ELM_FOCUS_DOWN)
2616 eo_last_item = elm_genlist_last_item_get(WIDGET(focus_it));
2617 if (eo_last_item == sd->focused_item) return EINA_FALSE;
2618 eo_next = elm_genlist_item_next_get(sd->focused_item);
2619 next = eo_data_scope_get(eo_next, ELM_GENLIST_ITEM_CLASS);
2621 while (eo_do(eo_next, elm_wdg_item_disabled_get()))
2623 eo_next = elm_genlist_item_next_get(eo_next);
2624 next = eo_data_scope_get(eo_next, ELM_GENLIST_ITEM_CLASS);
2630 if (!next) return EINA_FALSE;
2633 elm_object_item_focus_set(EO_OBJ(next), EINA_TRUE);
2639 _elm_genlist_item_content_focus_set(Elm_Gen_Item *it, Elm_Focus_Direction dir)
2641 Evas_Object *focused_obj = NULL;
2645 if (!GL_IT(it)->wsd->focus_on_selection_enabled) return;
2647 if (!it->item_focus_chain)
2649 elm_object_focus_set(VIEW(it), EINA_TRUE);
2653 EINA_LIST_FOREACH(it->item_focus_chain, l, focused_obj)
2654 if (elm_object_focus_get(focused_obj)) break;
2656 if (focused_obj && (dir != ELM_FOCUS_PREVIOUS))
2658 Evas_Object *nextfocus;
2659 if (elm_widget_focus_next_get(focused_obj, dir, &nextfocus))
2661 elm_object_focus_set(nextfocus, EINA_TRUE);
2666 if (!l) l = it->item_focus_chain;
2668 if (dir == ELM_FOCUS_RIGHT)
2670 l = eina_list_next(l);
2671 if (!l) l = it->item_focus_chain;
2673 else if (dir == ELM_FOCUS_LEFT)
2675 l = eina_list_prev(l);
2676 if (!l) l = eina_list_last(it->item_focus_chain);
2679 elm_object_focus_set(eina_list_data_get(l), EINA_TRUE);
2683 _key_action_move_dir(Evas_Object *obj, Elm_Focus_Direction dir, Eina_Bool multi)
2685 ELM_GENLIST_DATA_GET(obj, sd);
2686 Elm_Object_Item *it = NULL;
2687 Eina_Bool ret = EINA_FALSE;
2690 Eina_Bool focus_only = EINA_FALSE;
2692 // get content size and viewport size
2694 elm_interface_scrollable_content_viewport_geometry_get
2695 (NULL, NULL, NULL, &v),
2696 elm_interface_scrollable_content_size_get(NULL, &min));
2698 if (_elm_config->item_select_on_focus_disable)
2700 ret = _item_focused_next(obj, dir);
2706 if (dir == ELM_FOCUS_UP)
2707 ret = _item_multi_select_up(sd);
2708 else if (dir == ELM_FOCUS_DOWN)
2709 ret = _item_multi_select_down(sd);
2713 if (dir == ELM_FOCUS_UP)
2714 ret = _item_single_select_up(sd);
2715 else if (dir == ELM_FOCUS_DOWN)
2716 ret = _item_single_select_down(sd);
2722 focus_only = _elm_config->item_select_on_focus_disable && elm_widget_focus_highlight_enabled_get(obj);
2723 // handle item loop feature
2724 if (sd->item_loop_enable && !sd->item_looping_on)
2728 if (dir == ELM_FOCUS_UP)
2730 elm_layout_signal_emit(obj, "elm,action,looping,up", "elm");
2731 sd->item_looping_on = EINA_TRUE;
2733 else if (dir == ELM_FOCUS_DOWN)
2735 elm_layout_signal_emit(obj, "elm,action,looping,down", "elm");
2736 sd->item_looping_on = EINA_TRUE;
2741 if (dir == ELM_FOCUS_UP)
2742 it = elm_genlist_last_item_get(obj);
2743 else if (dir == ELM_FOCUS_DOWN)
2744 it = elm_genlist_first_item_get(obj);
2746 if (it && focus_only)
2747 elm_object_item_focus_set(it, EINA_TRUE);
2749 elm_genlist_item_selected_set(it, EINA_TRUE);
2753 else if (sd->item_looping_on)
2760 _key_action_move(Evas_Object *obj, const char *params)
2762 ELM_GENLIST_DATA_GET(obj, sd);
2763 const char *dir = params;
2769 Evas_Coord step_x = 0;
2770 Evas_Coord step_y = 0;
2771 Evas_Coord page_x = 0;
2772 Evas_Coord page_y = 0;
2773 Elm_Object_Item *it = NULL;
2774 Evas_Coord pan_max_x = 0, pan_max_y = 0;
2777 elm_interface_scrollable_content_pos_get(&x, &y),
2778 elm_interface_scrollable_step_size_get(&step_x, &step_y),
2779 elm_interface_scrollable_page_size_get(&page_x, &page_y),
2780 elm_interface_scrollable_content_viewport_geometry_get
2781 (NULL, NULL, &v_w, &v_h));
2783 if (!strcmp(dir, "left"))
2787 Elm_Object_Item *eo_gt = elm_genlist_selected_item_get(obj);
2788 ELM_GENLIST_ITEM_DATA_GET(eo_gt, gt);
2789 _elm_genlist_item_content_focus_set(gt, ELM_FOCUS_LEFT);
2793 else if (!strcmp(dir, "right"))
2797 Elm_Object_Item *eo_gt = elm_genlist_selected_item_get(obj);
2798 ELM_GENLIST_ITEM_DATA_GET(eo_gt, gt);
2799 _elm_genlist_item_content_focus_set(gt, ELM_FOCUS_RIGHT);
2803 else if (!strcmp(dir, "up"))
2805 if (_key_action_move_dir(obj, ELM_FOCUS_UP, EINA_FALSE)) return EINA_TRUE;
2806 else return EINA_FALSE;
2808 else if (!strcmp(dir, "up_multi"))
2810 if (_key_action_move_dir(obj, ELM_FOCUS_UP, EINA_TRUE)) return EINA_TRUE;
2811 else if (_key_action_move_dir(obj, ELM_FOCUS_UP, EINA_FALSE)) return EINA_TRUE;
2812 else return EINA_FALSE;
2814 else if (!strcmp(dir, "down"))
2816 if (_key_action_move_dir(obj, ELM_FOCUS_DOWN, EINA_FALSE)) return EINA_TRUE;
2817 else return EINA_FALSE;
2819 else if (!strcmp(dir, "down_multi"))
2821 if (_key_action_move_dir(obj, ELM_FOCUS_DOWN, EINA_TRUE)) return EINA_TRUE;
2822 else if (_key_action_move_dir(obj, ELM_FOCUS_DOWN, EINA_FALSE)) return EINA_TRUE;
2823 else return EINA_FALSE;
2825 else if (!strcmp(dir, "first"))
2827 it = elm_genlist_first_item_get(obj);
2830 elm_genlist_item_selected_set(it, EINA_TRUE);
2834 else if (!strcmp(dir, "last"))
2836 it = elm_genlist_last_item_get(obj);
2839 elm_genlist_item_selected_set(it, EINA_TRUE);
2843 else if (!strcmp(dir, "prior"))
2846 y -= -(page_y * v_h) / 100;
2850 else if (!strcmp(dir, "next"))
2853 y += -(page_y * v_h) / 100;
2857 else return EINA_FALSE;
2859 eo_do(sd->pan_obj, elm_obj_pan_pos_max_get(&pan_max_x, &pan_max_y));
2861 if (x > pan_max_x) x = pan_max_x;
2863 if (y > pan_max_y) y = pan_max_y;
2865 eo_do(obj, elm_interface_scrollable_content_pos_set(x, y, EINA_TRUE));
2871 _key_action_select(Evas_Object *obj, const char *params)
2873 Elm_Object_Item *eo_it = NULL;
2875 eo_it = elm_object_focused_item_get(obj);
2876 if (!eo_it) return EINA_TRUE;
2877 elm_genlist_item_expanded_set(eo_it, !elm_genlist_item_expanded_get(eo_it));
2878 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
2879 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
2882 ((sd->multi_select_mode != ELM_OBJECT_MULTI_SELECT_MODE_WITH_CONTROL) ||
2883 (!strcmp(params, "multi"))))
2887 _item_highlight(it);
2888 if (_item_select(it)) goto deleted;
2897 while (sd->selected)
2899 Elm_Object_Item *eo_sel = sd->selected->data;
2900 Elm_Gen_Item *sel = eo_data_scope_get(eo_sel, ELM_GENLIST_ITEM_CLASS);
2901 _item_unselect(sel);
2906 const Eina_List *l, *l_next;
2907 Elm_Object_Item *eo_it2;
2909 EINA_LIST_FOREACH_SAFE(sd->selected, l, l_next, eo_it2)
2911 ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
2913 _item_unselect(it2);
2916 _item_highlight(it);
2917 if (_item_select(it)) goto deleted;
2920 evas_object_smart_callback_call(WIDGET(it), SIG_ACTIVATED, EO_OBJ(it));
2929 _key_action_escape(Evas_Object *obj, const char *params EINA_UNUSED)
2931 ELM_GENLIST_DATA_GET(obj, sd);
2933 if (!_all_items_deselect(sd)) return EINA_FALSE;
2937 EOLIAN static Eina_Bool
2938 _elm_genlist_elm_widget_event(Eo *obj, Elm_Genlist_Data *sd, Evas_Object *src, Evas_Callback_Type type, void *event_info)
2941 Evas_Event_Key_Down *ev = event_info;
2943 if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
2944 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
2945 if (!sd->items) return EINA_FALSE;
2947 if (!_elm_config_key_binding_call(obj, ev, key_actions))
2950 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2954 /* This function disables the specific code of the layout sub object add.
2955 * Only the widget sub_object_add is called.
2957 EOLIAN static Eina_Bool
2958 _elm_genlist_elm_layout_sub_object_add_enable(Eo *obj EINA_UNUSED, Elm_Genlist_Data *_pd EINA_UNUSED)
2963 EOLIAN static Eina_Bool
2964 _elm_genlist_elm_widget_sub_object_add(Eo *obj, Elm_Genlist_Data *_pd EINA_UNUSED, Evas_Object *sobj)
2966 Eina_Bool int_ret = EINA_FALSE;
2968 /* skipping layout's code, which registers size hint changing
2969 * callback on sub objects. this is here because items'
2970 * content_get() routines may change hints on the objects after
2971 * creation, thus issuing TOO MANY sizing_eval()'s here. they are
2972 * not needed at here anyway, so let's skip listening to those
2974 eo_do_super(obj, MY_CLASS, int_ret = elm_obj_widget_sub_object_add(sobj));
2975 if (!int_ret) return EINA_FALSE;
2980 EOLIAN static Eina_Bool
2981 _elm_genlist_elm_widget_sub_object_del(Eo *obj, Elm_Genlist_Data *sd, Evas_Object *sobj)
2983 Eina_Bool int_ret = EINA_FALSE;
2986 /* XXX: hack -- also skipping sizing recalculation on
2987 * sub-object-del. genlist's crazy code paths (like groups and
2988 * such) seem to issue a whole lot of deletions and Evas bitches
2989 * about too many recalculations */
2990 sd->on_sub_del = EINA_TRUE;
2992 eo_do_super(obj, MY_CLASS, int_ret = elm_obj_widget_sub_object_del(sobj));
2993 if (!int_ret) return EINA_FALSE;
2995 sd->on_sub_del = EINA_FALSE;
3001 * This function searches the nearest visible item based on the given item.
3002 * If the given item is in the genlist viewport, this returns the given item.
3003 * Or this searches the realized items and checks the nearest fully visible item
3004 * according to the given item's position.
3006 static Elm_Object_Item *
3007 _elm_genlist_nearest_visible_item_get(Evas_Object *obj, Elm_Object_Item *eo_it)
3009 Evas_Coord vx = 0, vy = 0, vw = 0, vh = 0; // genlist viewport geometry
3010 Evas_Coord ix = 0, iy = 0, iw = 0, ih = 0; // given item geometry
3011 Evas_Coord cx = 0, cy = 0, cw = 0, ch = 0; // candidate item geometry
3012 Eina_List *item_list = NULL, *l = NULL;
3013 Elm_Object_Item *eo_item = NULL;
3014 ELM_GENLIST_DATA_GET(obj, sd);
3015 Eina_Bool search_next = EINA_FALSE;
3017 if (!eo_it) return NULL;
3018 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
3020 evas_object_geometry_get(sd->pan_obj, &vx, &vy, &vw, &vh);
3021 evas_object_geometry_get(VIEW(it), &ix, &iy, &iw, &ih); // FIXME: check if the item is realized or not
3023 if (ELM_RECTS_INCLUDE(vx, vy, vw, vh, ix, iy, iw, ih))
3025 if (!elm_object_item_disabled_get(eo_it))
3028 search_next = EINA_TRUE;
3031 item_list = elm_genlist_realized_items_get(obj);
3033 if ((iy < vy) || search_next)
3035 EINA_LIST_FOREACH(item_list, l, eo_item)
3037 ELM_GENLIST_ITEM_DATA_GET(eo_item, item);
3038 evas_object_geometry_get(VIEW(item), &cx, &cy, &cw, &ch);
3039 if (ELM_RECTS_INCLUDE(vx, vy, vw, vh, cx, cy, cw, ch) &&
3040 !elm_object_item_disabled_get(eo_item))
3042 eina_list_free(item_list);
3049 EINA_LIST_REVERSE_FOREACH(item_list, l, eo_item)
3051 ELM_GENLIST_ITEM_DATA_GET(eo_item, item);
3052 evas_object_geometry_get(VIEW(item), &cx, &cy, &cw, &ch);
3053 if (ELM_RECTS_INCLUDE(vx, vy, vw, vh, cx, cy, cw, ch) &&
3054 !elm_object_item_disabled_get(eo_item))
3056 eina_list_free(item_list);
3061 eina_list_free(item_list);
3066 EOLIAN static Eina_Bool
3067 _elm_genlist_elm_widget_on_focus(Eo *obj, Elm_Genlist_Data *sd)
3069 Eina_Bool int_ret = EINA_FALSE;
3070 Elm_Object_Item *eo_it = NULL;
3071 Eina_Bool is_sel = EINA_FALSE;
3073 eo_do_super(obj, MY_CLASS, int_ret = elm_obj_widget_on_focus());
3074 if (!int_ret) return EINA_FALSE;
3076 if (elm_widget_focus_get(obj) && (sd->items) && (sd->selected) &&
3077 (!sd->last_selected_item))
3079 sd->last_selected_item = eina_list_data_get(sd->selected);
3082 if (elm_widget_focus_get(obj) && !sd->mouse_down)
3084 if (sd->last_focused_item)
3085 eo_it = sd->last_focused_item;
3086 else if (sd->last_selected_item)
3087 eo_it = sd->last_selected_item;
3088 else if (_elm_config->first_item_focus_on_first_focus_in &&
3089 elm_widget_focus_highlight_enabled_get(obj))
3091 eo_it = elm_genlist_first_item_get(obj);
3097 eo_it = _elm_genlist_nearest_visible_item_get(obj, eo_it);
3100 if (!_elm_config->item_select_on_focus_disable && is_sel)
3101 elm_genlist_item_selected_set(eo_it, EINA_TRUE);
3103 elm_object_item_focus_set(eo_it, EINA_TRUE);
3104 _elm_widget_focus_highlight_start(obj);
3110 if (sd->focused_item)
3112 sd->last_focused_item = sd->focused_item;
3113 _elm_genlist_item_unfocused(sd->focused_item);
3120 static Eina_Bool _elm_genlist_smart_focus_next_enable = EINA_FALSE;
3122 EOLIAN static Eina_Bool
3123 _elm_genlist_elm_widget_focus_next_manager_is(Eo *obj EINA_UNUSED, Elm_Genlist_Data *_pd EINA_UNUSED)
3125 return _elm_genlist_smart_focus_next_enable;
3128 EOLIAN static Eina_Bool
3129 _elm_genlist_elm_widget_focus_direction_manager_is(Eo *obj EINA_UNUSED, Elm_Genlist_Data *_pd EINA_UNUSED)
3134 EOLIAN static Eina_Bool
3135 _elm_genlist_elm_widget_focus_next(Eo *obj, Elm_Genlist_Data *sd, Elm_Focus_Direction dir, Evas_Object **next)
3137 Evas_Coord x, y, w, h;
3138 Evas_Coord sx, sy, sw, sh;
3140 Eina_List *items = NULL;
3141 Eina_Bool done = EINA_FALSE;
3143 evas_object_geometry_get(sd->obj, &sx, &sy, &sw, &sh);
3145 EINA_INLIST_FOREACH(sd->blocks, itb)
3153 EINA_LIST_FOREACH(itb->items, l, it)
3157 evas_object_geometry_get(it->base->view, &x, &y, &w, &h);
3159 /* check item which displays more than half of its size */
3160 if (it->base->access_obj &&
3162 (x + (w / 2), y + (h / 2), 0, 0, sx, sy, sw, sh))
3163 items = eina_list_append(items, it->base->access_obj);
3165 if (!it->base->access_order) continue;
3169 EINA_LIST_FOREACH(it->base->access_order, subl, subo)
3170 items = eina_list_append(items, subo);
3174 else if (done) break;
3177 return elm_widget_focus_list_next_get
3178 (obj, items, eina_list_data_get, dir, next);
3182 _mirrored_set(Evas_Object *obj,
3185 ELM_GENLIST_DATA_GET(obj, sd);
3187 _item_cache_zero(sd);
3188 eo_do(obj, elm_interface_scrollable_mirrored_set(rtl));
3191 EOLIAN static Eina_Bool
3192 _elm_genlist_elm_widget_theme_apply(Eo *obj, Elm_Genlist_Data *sd)
3195 Eina_Bool int_ret = EINA_FALSE;
3199 eo_do_super(obj, MY_CLASS, int_ret = elm_obj_widget_theme_apply());
3200 if (!int_ret) return EINA_FALSE;
3202 evas_event_freeze(evas_object_evas_get(obj));
3203 _item_cache_zero(sd);
3204 _mirrored_set(obj, elm_widget_mirrored_get(obj));
3206 sd->item_width = sd->item_height = 0;
3207 sd->group_item_width = sd->group_item_height = 0;
3208 sd->minw = sd->minh = sd->realminw = 0;
3210 EINA_INLIST_FOREACH(sd->blocks, itb)
3212 if (itb->realized) _item_block_unrealize(itb);
3213 EINA_LIST_FOREACH(itb->items, l, it)
3214 it->item->mincalcd = EINA_FALSE;
3216 itb->changed = EINA_TRUE;
3218 ecore_job_del(sd->calc_job);
3219 sd->calc_job = ecore_job_add(_calc_job, obj);
3220 elm_layout_sizing_eval(obj);
3221 evas_event_thaw(evas_object_evas_get(obj));
3222 evas_event_thaw_eval(evas_object_evas_get(obj));
3227 /* FIXME: take off later. maybe this show region coords belong in the
3228 * interface (new api functions, set/get)? */
3230 _show_region_hook(void *data EINA_UNUSED,
3233 Evas_Coord x, y, w, h;
3235 ELM_GENLIST_DATA_GET_OR_RETURN(obj, sd);
3237 elm_widget_show_region_get(obj, &x, &y, &w, &h);
3238 //x & y are screen coordinates, Add with pan coordinates
3241 eo_do(obj, elm_interface_scrollable_content_region_show(x, y, w, h));
3245 _item_highlight(Elm_Gen_Item *it)
3247 const char *selectraise;
3248 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
3250 if (_is_no_select(it) ||
3252 (it->highlighted) || eo_do(EO_OBJ(it), elm_wdg_item_disabled_get()) ||
3253 (it->item->deco_it_view))
3256 edje_object_signal_emit(VIEW(it), SIGNAL_SELECTED, "elm");
3257 if (it->deco_all_view)
3258 edje_object_signal_emit(it->deco_all_view, SIGNAL_SELECTED, "elm");
3259 evas_object_smart_callback_call(WIDGET(it), SIG_HIGHLIGHTED, EO_OBJ(it));
3261 selectraise = edje_object_data_get(VIEW(it), "selectraise");
3262 if ((selectraise) && (!strcmp(selectraise, "on")))
3264 if (it->deco_all_view) evas_object_stack_below(it->deco_all_view, sd->stack[1]);
3265 else evas_object_stack_below(VIEW(it), sd->stack[1]);
3266 if ((it->item->group_item) && (it->item->group_item->realized))
3267 evas_object_stack_above(it->item->VIEW(group_item), sd->stack[1]);
3269 it->highlighted = EINA_TRUE;
3273 _item_unhighlight(Elm_Gen_Item *it)
3275 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
3277 if (!it->highlighted) return;
3279 edje_object_signal_emit(VIEW(it), SIGNAL_UNSELECTED, "elm");
3280 evas_object_smart_callback_call(WIDGET(it), SIG_UNHIGHLIGHTED, EO_OBJ(it));
3281 if (it->deco_all_view)
3282 edje_object_signal_emit
3283 (it->deco_all_view, SIGNAL_UNSELECTED, "elm");
3285 if (!it->item->nostacking)
3287 if ((it->item->order_num_in & 0x1) ^ it->item->stacking_even)
3289 if (it->deco_all_view) evas_object_stack_below(it->deco_all_view, sd->stack[0]);
3290 else evas_object_stack_below(VIEW(it), sd->stack[0]);
3294 if (it->deco_all_view) evas_object_stack_above(it->deco_all_view, sd->stack[0]);
3295 else evas_object_stack_above(VIEW(it), sd->stack[0]);
3298 it->highlighted = EINA_FALSE;
3302 _item_block_position_update(Eina_Inlist *list,
3307 EINA_INLIST_FOREACH(list, tmp)
3309 tmp->position = idx++;
3310 tmp->position_update = EINA_TRUE;
3315 _item_position_update(Eina_List *list,
3321 EINA_LIST_FOREACH(list, l, it)
3323 it->position = idx++;
3324 it->position_update = EINA_TRUE;
3329 _item_block_merge(Item_Block *left,
3335 EINA_LIST_FOREACH(right->items, l, it2)
3337 it2->item->block = left;
3339 left->changed = EINA_TRUE;
3341 left->items = eina_list_merge(left->items, right->items);
3345 _item_block_del(Elm_Gen_Item *it)
3348 Item_Block *itb = it->item->block;
3349 Eina_Bool block_changed = EINA_FALSE;
3350 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
3352 itb->items = eina_list_remove(itb->items, it);
3354 itb->changed = EINA_TRUE;
3355 ecore_job_del(sd->calc_job);
3356 sd->calc_job = ecore_job_add(_calc_job, sd->obj);
3361 il = EINA_INLIST_GET(itb);
3362 itbn = (Item_Block *)(il->next);
3364 it->parent->item->items =
3365 eina_list_remove(it->parent->item->items, EO_OBJ(it));
3368 _item_block_position_update(il->next, itb->position);
3369 sd->blocks = eina_inlist_remove(sd->blocks, il);
3372 if (itbn) itbn->changed = EINA_TRUE;
3376 if (itb->count < (sd->max_items_per_block / 2))
3381 il = EINA_INLIST_GET(itb);
3382 itbp = (Item_Block *)(il->prev);
3383 itbn = (Item_Block *)(il->next);
3385 /* merge block with previous */
3387 ((itbp->count + itb->count) <
3388 (sd->max_items_per_block +
3389 (sd->max_items_per_block / 2))))
3391 _item_block_merge(itbp, itb);
3392 _item_block_position_update
3393 (EINA_INLIST_GET(itb)->next, itb->position);
3394 sd->blocks = eina_inlist_remove
3395 (sd->blocks, EINA_INLIST_GET(itb));
3397 block_changed = EINA_TRUE;
3399 /* merge block with next */
3401 ((itbn->count + itb->count) <
3402 (sd->max_items_per_block +
3403 (sd->max_items_per_block / 2))))
3405 _item_block_merge(itb, itbn);
3406 _item_block_position_update
3407 (EINA_INLIST_GET(itbn)->next, itbn->position);
3409 eina_inlist_remove(sd->blocks, EINA_INLIST_GET(itbn));
3411 block_changed = EINA_TRUE;
3418 sd->pan_changed = EINA_TRUE;
3419 evas_object_smart_changed(sd->pan_obj);
3420 ecore_job_del(sd->calc_job);
3421 sd->calc_job = NULL;
3426 _decorate_all_item_unrealize(Elm_Gen_Item *it)
3428 if ((!it) || (!it->item->decorate_all_item_realized)) return;
3430 edje_object_part_unswallow(it->deco_all_view, VIEW(it));
3431 evas_object_smart_member_add(VIEW(it), GL_IT(it)->wsd->pan_obj);
3432 elm_widget_sub_object_add(WIDGET(it), VIEW(it));
3433 _elm_genlist_item_position_state_update(it);
3434 _elm_genlist_item_state_update(it, NULL);
3436 if (it->item->wsd->reorder_mode)
3438 edje_object_signal_emit(VIEW(it), SIGNAL_REORDER_MODE_SET, "elm");
3439 edje_object_signal_emit(it->deco_all_view, SIGNAL_REORDER_MODE_UNSET,
3443 _view_clear(it->deco_all_view, &(GL_IT(it)->deco_all_texts),
3444 &(GL_IT(it)->deco_all_contents));
3446 edje_object_signal_emit(VIEW(it), SIGNAL_DECORATE_DISABLED, "elm");
3448 edje_object_message_signal_process(it->deco_all_view);
3449 _item_mouse_callbacks_del(it, it->deco_all_view);
3450 _item_mouse_callbacks_add(it, VIEW(it));
3452 ELM_SAFE_FREE(it->deco_all_view, evas_object_del);
3454 it->item->decorate_all_item_realized = EINA_FALSE;
3458 _elm_genlist_item_del_not_serious(Elm_Gen_Item *it)
3460 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
3461 Elm_Object_Item *eo_it = EO_OBJ(it);
3463 eo_do(eo_it, elm_wdg_item_pre_notify_del());
3467 sd->selected = eina_list_remove(sd->selected, EO_OBJ(it));
3468 if (sd->deselecting)
3469 sd->deselecting = eina_list_remove(sd->deselecting, it);
3471 if (sd->last_focused_item == eo_it)
3472 sd->last_focused_item = NULL;
3473 if (sd->focused_item == eo_it)
3474 sd->focused_item = NULL;
3475 if (sd->last_selected_item == eo_it)
3476 sd->last_selected_item = NULL;
3478 if (it->itc->func.del)
3479 it->itc->func.del((void *)WIDGET_ITEM_DATA_GET(EO_OBJ(it)), WIDGET(it));
3483 _elm_genlist_item_del_serious(Elm_Gen_Item *it)
3485 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
3487 _elm_genlist_item_del_not_serious(it);
3489 //(it->walking == -1) means it's already removed from the list.
3490 if (it->walking != -1)
3491 sd->items = eina_inlist_remove(sd->items, EINA_INLIST_GET(it));
3492 if (it->tooltip.del_cb)
3493 it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
3494 ELM_SAFE_FREE(it->long_timer, ecore_timer_del);
3495 if (GL_IT(it)->type & ELM_GENLIST_ITEM_GROUP)
3496 sd->group_items = eina_list_remove(sd->group_items, it);
3498 ELM_SAFE_FREE(sd->state, eina_inlist_sorted_state_free);
3499 ecore_job_del(sd->calc_job);
3500 sd->calc_job = ecore_job_add(_calc_job, sd->obj);
3504 ELM_SAFE_FREE(it->item, free);
3508 _item_del(Elm_Gen_Item *it)
3510 Evas_Object *obj = WIDGET(it);
3511 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
3513 evas_event_freeze(evas_object_evas_get(obj));
3517 it->item->rel->item->rel_revs =
3518 eina_list_remove(it->item->rel->item->rel_revs, it);
3520 if (it->item->rel_revs)
3523 EINA_LIST_FREE(it->item->rel_revs, tmp) tmp->item->rel = NULL;
3525 elm_genlist_item_subitems_clear(EO_OBJ(it));
3526 if (sd->show_item == it) sd->show_item = NULL;
3527 if (it->realized) _elm_genlist_item_unrealize(it, EINA_FALSE);
3528 if (it->item->decorate_all_item_realized) _decorate_all_item_unrealize(it);
3529 if (it->item->block) _item_block_del(it);
3530 if (it->item->queued)
3531 sd->queue = eina_list_remove(sd->queue, it);
3532 if (sd->anchor_item == it)
3534 sd->anchor_item = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
3535 if (!sd->anchor_item)
3537 ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
3539 if (sd->expanded_item == it)
3541 if (sd->tree_effect_animator)
3543 _item_tree_effect_finish(sd);
3544 ELM_SAFE_FREE(sd->tree_effect_animator, ecore_animator_del);
3546 sd->expanded_item = NULL;
3547 sd->move_effect_mode = ELM_GENLIST_TREE_EFFECT_NONE;
3549 if (sd->expanded_next_item == it) sd->expanded_next_item = NULL;
3550 if (sd->move_items) sd->move_items = eina_list_remove(sd->move_items, it);
3552 it->parent->item->items = eina_list_remove(it->parent->item->items, EO_OBJ(it));
3553 ELM_SAFE_FREE(it->item->swipe_timer, ecore_timer_del);
3554 _elm_genlist_item_del_serious(it);
3555 elm_genlist_item_class_unref((Elm_Genlist_Item_Class *)it->itc);
3556 evas_event_thaw(evas_object_evas_get(obj));
3557 evas_event_thaw_eval(evas_object_evas_get(obj));
3558 if (!sd->queue) _item_scroll(sd);
3562 _item_unselect(Elm_Gen_Item *it)
3564 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
3566 _item_unhighlight(it); /* unhighlight the item first */
3567 if (!it->selected) return; /* then check whether the item is selected */
3569 if (GL_IT(it)->wsd->focus_on_selection_enabled)
3573 EINA_LIST_FOREACH(it->item_focus_chain, l, eobj)
3574 elm_object_focus_set(eobj, EINA_FALSE);
3577 it->selected = EINA_FALSE;
3578 sd->selected = eina_list_remove(sd->selected, EO_OBJ(it));
3579 evas_object_smart_callback_call(WIDGET(it), SIG_UNSELECTED, EO_OBJ(it));
3583 _item_mouse_in_cb(void *data,
3584 Evas *evas EINA_UNUSED,
3585 Evas_Object *obj EINA_UNUSED,
3586 void *event_info EINA_UNUSED)
3588 Elm_Gen_Item *it = data;
3589 if (!elm_object_item_disabled_get(EO_OBJ(it)) &&
3590 (_elm_config->focus_move_policy == ELM_FOCUS_MOVE_POLICY_IN))
3591 elm_object_item_focus_set(EO_OBJ(it), EINA_TRUE);
3595 _item_mouse_move_cb(void *data,
3596 Evas *evas EINA_UNUSED,
3600 Elm_Gen_Item *it = data;
3601 Evas_Event_Mouse_Move *ev = event_info;
3602 Evas_Coord ox, oy, ow, oh, it_scrl_y, y_pos;
3603 Evas_Coord minw = 0, minh = 0, x, y, w, h, dx, dy, adx, ady;
3604 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
3605 Elm_Object_Item *eo_it = EO_OBJ(it);
3607 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
3611 sd->on_hold = EINA_TRUE;
3612 if ((!sd->wasselected) && (!it->flipped))
3616 if (sd->multi_touched)
3618 sd->cur_x = ev->cur.canvas.x;
3619 sd->cur_y = ev->cur.canvas.y;
3622 if ((it->dragging) && (it->down))
3624 if (sd->movements == SWIPE_MOVES)
3625 sd->swipe = EINA_TRUE;
3628 sd->history[sd->movements].x = ev->cur.canvas.x;
3629 sd->history[sd->movements].y = ev->cur.canvas.y;
3630 if (abs((sd->history[sd->movements].x -
3631 sd->history[0].x)) > 40)
3632 sd->swipe = EINA_TRUE;
3636 ELM_SAFE_FREE(it->long_timer, ecore_timer_del);
3637 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG, eo_it);
3640 if ((!it->down) || (sd->longpressed))
3642 ELM_SAFE_FREE(it->long_timer, ecore_timer_del);
3643 if ((sd->reorder_mode) && (sd->reorder_it))
3645 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
3647 if (ev->cur.canvas.y < (oy + (sd->reorder_it->item->h / 2)))
3648 sd->reorder_fast = 1;
3649 else if (ev->cur.canvas.y > (oy + oh - (sd->reorder_it->item->h / 2)))
3650 sd->reorder_fast = -1;
3651 else sd->reorder_fast = 0;
3653 it_scrl_y = ev->cur.canvas.y - sd->reorder_it->dy;
3655 if (!sd->reorder_start_y)
3656 sd->reorder_start_y = it->item->block->y + it->y;
3660 else if (it_scrl_y + sd->reorder_it->item->h > oy + oh)
3661 y_pos = oy + oh - sd->reorder_it->item->h;
3665 if (it->deco_all_view)
3666 _item_position(it, it->deco_all_view, it->item->scrl_x, y_pos);
3668 _item_position(it, VIEW(it), it->item->scrl_x, y_pos);
3670 ecore_job_del(sd->calc_job);
3671 sd->calc_job = ecore_job_add(_calc_job, sd->obj);
3675 if (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
3676 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
3678 evas_object_geometry_get(obj, &x, &y, &w, &h);
3679 x = ev->cur.canvas.x - x;
3680 y = ev->cur.canvas.y - y;
3683 if (adx < 0) adx = -dx;
3687 if (ady < 0) ady = -dy;
3692 // gah! annoying drag detection - leave this alone
3695 if (minw < h) minw = h;
3696 if (minh < h) minh = h;
3700 if (minw < w) minw = w;
3701 if (minh < w) minh = w;
3703 if (minw < 5) minw = 5;
3704 if (minh < 5) minh = 5;
3706 if ((adx > minw) || (ady > minh))
3708 it->dragging = EINA_TRUE;
3709 ELM_SAFE_FREE(it->long_timer, ecore_timer_del);
3710 if (!sd->wasselected)
3715 evas_object_smart_callback_call
3716 (WIDGET(it), SIG_DRAG_START_UP, eo_it);
3720 evas_object_smart_callback_call
3721 (WIDGET(it), SIG_DRAG_START_LEFT, eo_it);
3723 evas_object_smart_callback_call
3724 (WIDGET(it), SIG_DRAG_START_RIGHT, eo_it);
3730 evas_object_smart_callback_call
3731 (WIDGET(it), SIG_DRAG_START_DOWN, eo_it);
3735 evas_object_smart_callback_call
3736 (WIDGET(it), SIG_DRAG_START_LEFT, eo_it);
3738 evas_object_smart_callback_call
3739 (WIDGET(it), SIG_DRAG_START_RIGHT, eo_it);
3746 _long_press_cb(void *data)
3748 Elm_Gen_Item *it = data;
3749 Elm_Object_Item *eo_it_tmp;
3751 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
3753 it->long_timer = NULL;
3754 if (_is_no_select(it) ||
3755 eo_do(EO_OBJ(it), elm_wdg_item_disabled_get()) || (it->dragging))
3756 return ECORE_CALLBACK_CANCEL;
3758 sd->longpressed = EINA_TRUE;
3759 evas_object_smart_callback_call(WIDGET(it), SIG_LONGPRESSED, EO_OBJ(it));
3760 if ((sd->reorder_mode) && !(GL_IT(it)->type & ELM_GENLIST_ITEM_GROUP))
3762 sd->reorder_it = it;
3763 sd->reorder_start_y = 0;
3764 if (it->deco_all_view)
3765 evas_object_stack_below(it->deco_all_view, sd->stack[1]);
3767 evas_object_stack_below(VIEW(it), sd->stack[1]);
3769 eo_do(sd->obj, elm_interface_scrollable_hold_set(EINA_TRUE));
3770 eo_do(sd->obj, elm_interface_scrollable_bounce_allow_set
3771 (EINA_FALSE, EINA_FALSE));
3773 list = elm_genlist_realized_items_get
3775 EINA_LIST_FREE(list, eo_it_tmp)
3777 ELM_GENLIST_ITEM_DATA_GET(eo_it_tmp, it_tmp);
3778 if (it != it_tmp) _item_unselect(it_tmp);
3781 if (elm_genlist_item_expanded_get(EO_OBJ(it)))
3783 elm_genlist_item_expanded_set(EO_OBJ(it), EINA_FALSE);
3784 return ECORE_CALLBACK_RENEW;
3787 if (!sd->decorate_all_mode)
3788 edje_object_signal_emit(VIEW(it), SIGNAL_REORDER_ENABLED, "elm");
3791 return ECORE_CALLBACK_CANCEL;
3795 _swipe_do(Elm_Gen_Item *it)
3798 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
3800 if (_is_no_select(it) ||
3801 eo_do(EO_OBJ(it), elm_wdg_item_disabled_get())) return;
3803 sd->swipe = EINA_FALSE;
3804 for (i = 0; i < sd->movements; i++)
3806 sum += sd->history[i].x;
3807 if (abs(sd->history[0].y - sd->history[i].y) > 10)
3811 sum /= sd->movements;
3812 if (abs(sum - sd->history[0].x) <= 10) return;
3813 evas_object_smart_callback_call(WIDGET(it), SIG_SWIPE, EO_OBJ(it));
3817 _swipe_cancel(void *data)
3819 Elm_Gen_Item *it = data;
3820 if (!it) return ECORE_CALLBACK_CANCEL;
3821 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
3823 sd->swipe = EINA_FALSE;
3826 return ECORE_CALLBACK_RENEW;
3830 _multi_cancel(void *data)
3832 ELM_GENLIST_DATA_GET(data, sd);
3834 if (!sd) return ECORE_CALLBACK_CANCEL;
3835 sd->multi_timeout = EINA_TRUE;
3837 return ECORE_CALLBACK_RENEW;
3841 _multi_touch_gesture_eval(Elm_Gen_Item *it)
3843 Evas_Coord minw = 0, minh = 0;
3844 Evas_Coord off_x, off_y, off_mx, off_my;
3845 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
3846 Elm_Object_Item *eo_it = EO_OBJ(it);
3848 sd->multi_touched = EINA_FALSE;
3849 ELM_SAFE_FREE(sd->multi_timer, ecore_timer_del);
3850 if (sd->multi_timeout)
3852 sd->multi_timeout = EINA_FALSE;
3856 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
3857 off_x = abs(sd->cur_x - sd->prev_x);
3858 off_y = abs(sd->cur_y - sd->prev_y);
3859 off_mx = abs(sd->cur_mx - sd->prev_mx);
3860 off_my = abs(sd->cur_my - sd->prev_my);
3862 if (((off_x > minw) || (off_y > minh)) && ((off_mx > minw)
3863 || (off_my > minh)))
3865 if ((off_x + off_mx) > (off_y + off_my))
3867 if ((sd->cur_x > sd->prev_x) && (sd->cur_mx > sd->prev_mx))
3868 evas_object_smart_callback_call
3869 (WIDGET(it), SIG_MULTI_SWIPE_RIGHT, eo_it);
3870 else if ((sd->cur_x < sd->prev_x) && (sd->cur_mx < sd->prev_mx))
3871 evas_object_smart_callback_call
3872 (WIDGET(it), SIG_MULTI_SWIPE_LEFT, eo_it);
3873 else if (abs(sd->cur_x - sd->cur_mx) >
3874 abs(sd->prev_x - sd->prev_mx))
3875 evas_object_smart_callback_call
3876 (WIDGET(it), SIG_MULTI_PINCH_OUT, eo_it);
3878 evas_object_smart_callback_call
3879 (WIDGET(it), SIG_MULTI_PINCH_IN, eo_it);
3883 if ((sd->cur_y > sd->prev_y) && (sd->cur_my > sd->prev_my))
3884 evas_object_smart_callback_call
3885 (WIDGET(it), SIG_MULTI_SWIPE_DOWN, eo_it);
3886 else if ((sd->cur_y < sd->prev_y) && (sd->cur_my < sd->prev_my))
3887 evas_object_smart_callback_call
3888 (WIDGET(it), SIG_MULTI_SWIPE_UP, eo_it);
3889 else if (abs(sd->cur_y - sd->cur_my) >
3890 abs(sd->prev_y - sd->prev_my))
3891 evas_object_smart_callback_call
3892 (WIDGET(it), SIG_MULTI_PINCH_OUT, eo_it);
3894 evas_object_smart_callback_call
3895 (WIDGET(it), SIG_MULTI_PINCH_IN, eo_it);
3899 sd->multi_timeout = EINA_FALSE;
3903 _item_multi_down_cb(void *data,
3904 Evas *evas EINA_UNUSED,
3905 Evas_Object *obj EINA_UNUSED,
3908 Elm_Gen_Item *it = data;
3909 Evas_Event_Multi_Down *ev = event_info;
3910 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
3912 if ((sd->multi_device != 0) || (sd->multi_touched)
3913 || (sd->multi_timeout))
3916 sd->multi_device = ev->device;
3917 sd->multi_down = EINA_TRUE;
3918 sd->multi_touched = EINA_TRUE;
3919 sd->prev_mx = ev->canvas.x;
3920 sd->prev_my = ev->canvas.y;
3921 if (!sd->wasselected) _item_unselect(it);
3922 sd->wasselected = EINA_FALSE;
3923 sd->longpressed = EINA_FALSE;
3924 ELM_SAFE_FREE(it->long_timer, ecore_timer_del);
3927 it->dragging = EINA_FALSE;
3928 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG_STOP, EO_OBJ(it));
3930 ELM_SAFE_FREE(it->item->swipe_timer, ecore_timer_del);
3933 sd->swipe = EINA_FALSE;
3935 sd->on_hold = EINA_FALSE;
3940 _item_multi_up_cb(void *data,
3941 Evas *evas EINA_UNUSED,
3942 Evas_Object *obj EINA_UNUSED,
3945 Elm_Gen_Item *it = data;
3946 Evas_Event_Multi_Up *ev = event_info;
3947 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
3949 if (sd->multi_device != ev->device) return;
3950 sd->multi_device = 0;
3951 sd->multi_down = EINA_FALSE;
3952 if (sd->mouse_down) return;
3953 _multi_touch_gesture_eval(data);
3957 _item_multi_move_cb(void *data,
3958 Evas *evas EINA_UNUSED,
3959 Evas_Object *obj EINA_UNUSED,
3962 Elm_Gen_Item *it = data;
3963 Evas_Event_Multi_Move *ev = event_info;
3964 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
3966 if (sd->multi_device != ev->device) return;
3967 sd->cur_mx = ev->cur.canvas.x;
3968 sd->cur_my = ev->cur.canvas.y;
3972 _item_mouse_down_cb(void *data,
3973 Evas *evas EINA_UNUSED,
3977 Evas_Event_Mouse_Down *ev = event_info;
3978 Elm_Gen_Item *it = data;
3980 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
3981 Elm_Object_Item *eo_it = EO_OBJ(it);
3983 if (ev->button == 3)
3985 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
3986 it->dx = ev->canvas.x - x;
3987 it->dy = ev->canvas.y - y;
3990 if (ev->button != 1) return;
3991 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
3993 sd->on_hold = EINA_TRUE;
3996 it->down = EINA_TRUE;
3997 it->dragging = EINA_FALSE;
3998 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
3999 it->dx = ev->canvas.x - x;
4000 it->dy = ev->canvas.y - y;
4001 sd->mouse_down = EINA_TRUE;
4002 if (!sd->multi_touched)
4004 sd->prev_x = ev->canvas.x;
4005 sd->prev_y = ev->canvas.y;
4006 sd->multi_timeout = EINA_FALSE;
4007 ecore_timer_del(sd->multi_timer);
4008 sd->multi_timer = ecore_timer_add(MULTI_DOWN_TIME, _multi_cancel, sd->obj);
4010 sd->longpressed = EINA_FALSE;
4011 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) sd->on_hold = EINA_TRUE;
4012 else sd->on_hold = EINA_FALSE;
4013 if (sd->on_hold) return;
4014 sd->wasselected = it->selected;
4016 ecore_timer_del(it->item->swipe_timer);
4017 it->item->swipe_timer = ecore_timer_add(SWIPE_TIME, _swipe_cancel, it);
4018 ELM_SAFE_FREE(it->long_timer, ecore_timer_del);
4020 it->long_timer = ecore_timer_add
4021 (sd->longpress_timeout, _long_press_cb, it);
4023 it->long_timer = NULL;
4024 sd->swipe = EINA_FALSE;
4027 if (_is_no_select(it) ||
4028 eo_do((Eo *)eo_it, elm_wdg_item_disabled_get()))
4031 // and finally call the user callbacks.
4032 // NOTE: keep this code at the bottom, as the user can change the
4033 // list at this point (clear, delete, etc...)
4034 _item_highlight(it);
4035 if (ev->flags & EVAS_BUTTON_DOUBLE_CLICK)
4037 evas_object_smart_callback_call(WIDGET(it), SIG_CLICKED_DOUBLE, eo_it);
4038 evas_object_smart_callback_call(WIDGET(it), SIG_ACTIVATED, eo_it);
4040 evas_object_smart_callback_call(WIDGET(it), SIG_PRESSED, eo_it);
4044 _item_block_new(Elm_Genlist_Data *sd,
4049 itb = calloc(1, sizeof(Item_Block));
4050 if (!itb) return NULL;
4054 sd->blocks = eina_inlist_prepend(sd->blocks, EINA_INLIST_GET(itb));
4055 _item_block_position_update(sd->blocks, 0);
4059 sd->blocks = eina_inlist_append(sd->blocks, EINA_INLIST_GET(itb));
4060 itb->position_update = EINA_TRUE;
4061 if (sd->blocks != EINA_INLIST_GET(itb))
4064 ((Item_Block *)(EINA_INLIST_GET(itb)->prev))->position + 1;
4078 * This function adds an item to a block's item list. This may or may not
4079 * rearrange existing blocks and create a new block.
4083 _item_block_add(Elm_Genlist_Data *sd,
4086 Item_Block *itb = NULL;
4088 // when a new item does not depend on another item
4094 itb = calloc(1, sizeof(Item_Block));
4095 if (!itb) return EINA_FALSE;
4097 if (!it->item->rel->item->block)
4100 eina_inlist_append(sd->blocks, EINA_INLIST_GET(itb));
4101 itb->items = eina_list_append(itb->items, it);
4102 itb->position_update = EINA_TRUE;
4103 it->position = eina_list_count(itb->items);
4104 it->position_update = EINA_TRUE;
4106 if (sd->blocks != EINA_INLIST_GET(itb))
4110 (EINA_INLIST_GET(itb)->prev))->position + 1;
4121 tmp = eina_list_data_find_list(itb->items, it->item->rel);
4122 if (it->item->before)
4124 sd->blocks = eina_inlist_prepend_relative
4125 (sd->blocks, EINA_INLIST_GET(itb),
4126 EINA_INLIST_GET(it->item->rel->item->block));
4128 eina_list_prepend_relative_list(itb->items, it, tmp);
4130 /* Update index from where we prepended */
4131 _item_position_update
4132 (eina_list_prev(tmp), it->item->rel->position);
4133 _item_block_position_update
4134 (EINA_INLIST_GET(itb),
4135 it->item->rel->item->block->position);
4139 sd->blocks = eina_inlist_append_relative
4140 (sd->blocks, EINA_INLIST_GET(itb),
4141 EINA_INLIST_GET(it->item->rel->item->block));
4143 eina_list_append_relative_list(itb->items, it, tmp);
4145 /* Update block index from where we appended */
4146 _item_position_update
4147 (eina_list_next(tmp), it->item->rel->position + 1);
4148 _item_block_position_update
4149 (EINA_INLIST_GET(itb),
4150 it->item->rel->item->block->position + 1);
4156 // item move_before, prepend, insert_before, sorted_insert with before
4157 if (it->item->before)
4161 itb = (Item_Block *)(sd->blocks);
4162 if (itb->count >= sd->max_items_per_block)
4164 itb = _item_block_new(sd, EINA_TRUE);
4165 if (!itb) return EINA_FALSE;
4170 itb = _item_block_new(sd, EINA_TRUE);
4171 if (!itb) return EINA_FALSE;
4173 itb->items = eina_list_prepend(itb->items, it);
4175 _item_position_update(itb->items, 0);
4177 // item move_after, append, insert_after, sorted_insert without before
4182 itb = (Item_Block *)(sd->blocks->last);
4183 if (itb->count >= sd->max_items_per_block)
4185 itb = _item_block_new(sd, EINA_FALSE);
4186 if (!itb) return EINA_FALSE;
4191 itb = _item_block_new(sd, EINA_FALSE);
4192 if (!itb) return EINA_FALSE;
4194 itb->items = eina_list_append(itb->items, it);
4195 it->position = eina_list_count(itb->items);
4199 // when a new item depends on another item
4204 if (it->item->rel->item->queued)
4206 /* NOTE: for a strange reason eina_list and eina_inlist
4207 don't have the same property on sorted insertion
4208 order, so the queue is not always ordered like the
4209 item list. This lead to issue where we depend on an
4210 item that is not yet created. As a quick work around,
4211 we reschedule the calc of the item and stop reordering
4212 the list to prevent any nasty issue to show up here.
4214 sd->queue = eina_list_append(sd->queue, it);
4215 sd->requeued = EINA_TRUE;
4216 it->item->queued = EINA_TRUE;
4220 itb = it->item->rel->item->block;
4221 if (!itb) goto newblock;
4222 tmp = eina_list_data_find_list(itb->items, it->item->rel);
4223 if (it->item->before)
4225 itb->items = eina_list_prepend_relative_list(itb->items, it, tmp);
4226 _item_position_update
4227 (eina_list_prev(tmp), it->item->rel->position);
4231 itb->items = eina_list_append_relative_list(itb->items, it, tmp);
4232 _item_position_update
4233 (eina_list_next(tmp), it->item->rel->position + 1);
4238 itb->changed = EINA_TRUE;
4239 it->item->block = itb;
4240 ecore_job_del(itb->sd->calc_job);
4241 itb->sd->calc_job = ecore_job_add(_calc_job, itb->sd->obj);
4243 if (itb->count > itb->sd->max_items_per_block)
4248 Eina_Bool done = EINA_FALSE;
4250 newc = itb->count / 2;
4252 if (EINA_INLIST_GET(itb)->prev)
4254 Item_Block *itbp = (Item_Block *)(EINA_INLIST_GET(itb)->prev);
4256 if (itbp->count + newc < sd->max_items_per_block / 2)
4258 /* moving items to previous block */
4259 while ((itb->count > newc) && (itb->items))
4261 it2 = eina_list_data_get(itb->items);
4262 itb->items = eina_list_remove_list
4263 (itb->items, itb->items);
4266 itbp->items = eina_list_append(itbp->items, it2);
4267 it2->item->block = itbp;
4275 if (!done && EINA_INLIST_GET(itb)->next)
4277 Item_Block *itbn = (Item_Block *)(EINA_INLIST_GET(itb)->next);
4279 if (itbn->count + newc < sd->max_items_per_block / 2)
4281 /* moving items to next block */
4282 while ((itb->count > newc) && (itb->items))
4286 l = eina_list_last(itb->items);
4287 it2 = eina_list_data_get(l);
4288 itb->items = eina_list_remove_list(itb->items, l);
4291 itbn->items = eina_list_prepend(itbn->items, it2);
4292 it2->item->block = itbn;
4302 /* moving items to new block */
4303 itb2 = calloc(1, sizeof(Item_Block));
4304 if (!itb2) return EINA_FALSE;
4307 eina_inlist_append_relative(sd->blocks, EINA_INLIST_GET(itb2),
4308 EINA_INLIST_GET(itb));
4309 itb2->changed = EINA_TRUE;
4310 while ((itb->count > newc) && (itb->items))
4314 l = eina_list_last(itb->items);
4316 itb->items = eina_list_remove_list(itb->items, l);
4319 itb2->items = eina_list_prepend(itb2->items, it2);
4320 it2->item->block = itb2;
4330 _item_process(Elm_Genlist_Data *sd,
4333 if (!_item_block_add(sd, it)) return EINA_TRUE;
4335 _item_block_realize(it->item->block);
4341 _item_process_post(Elm_Genlist_Data *sd,
4345 Eina_Bool show_me = EINA_FALSE;
4347 if (it->item->block->changed)
4349 show_me = _item_block_recalc
4350 (it->item->block, it->item->block->num, qadd);
4351 it->item->block->changed = 0;
4352 if (sd->pan_changed)
4354 ELM_SAFE_FREE(sd->calc_job, ecore_job_del);
4356 sd->pan_changed = EINA_FALSE;
4359 if (show_me) it->item->block->show_me = EINA_TRUE;
4361 /* when prepending, move the scroller along with the first selected
4362 * item to create the illusion that we're watching the selected
4363 * item this prevents the selected item being scrolled off the
4366 if (sd->selected && it->item->before)
4369 Elm_Object_Item *eo_it2;
4371 eo_it2 = sd->selected->data;
4372 ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
4373 if (!it2->item->block) return;
4374 eo_do(sd->obj, elm_interface_scrollable_content_pos_get(NULL, &y));
4375 evas_object_geometry_get(sd->pan_obj, NULL, NULL, NULL, &h);
4376 if ((it->y + it->item->block->y > y + h) ||
4377 (it->y + it->item->block->y + it->item->h < y))
4378 /* offscreen, just update */
4379 eo_do(sd->obj, elm_interface_scrollable_content_region_show
4380 (it2->x + it2->item->block->x, y,
4381 it2->item->block->w, h));
4383 eo_do(sd->obj, elm_interface_scrollable_content_region_show
4384 (it->x + it->item->block->x,
4385 y + it->item->h, it->item->block->w, h));
4390 _queue_process(Elm_Genlist_Data *sd)
4395 t0 = ecore_time_get();
4396 for (n = 0; (sd->queue) && (n < 128); n++)
4400 it = eina_list_data_get(sd->queue);
4401 sd->queue = eina_list_remove_list(sd->queue, sd->queue);
4402 it->item->queued = EINA_FALSE;
4403 if (_item_process(sd, it)) continue;
4404 t = ecore_time_get();
4405 _item_process_post(sd, it, EINA_TRUE);
4406 /* same as eina_inlist_count > 1 */
4407 if (sd->blocks && sd->blocks->next)
4409 if ((t - t0) > (ecore_animator_frametime_get())) break;
4412 if (!sd->queue) _item_scroll(sd);
4417 _idle_process(void *data,
4420 Elm_Genlist_Data *sd = data;
4422 if (_queue_process(sd) > 0) *wakeup = EINA_TRUE;
4425 return ECORE_CALLBACK_CANCEL;
4427 return ECORE_CALLBACK_RENEW;
4431 _item_idle_enterer(void *data)
4433 Eina_Bool wakeup = EINA_FALSE;
4434 ELM_GENLIST_DATA_GET(data, sd);
4435 Eina_Bool ok = _idle_process(sd, &wakeup);
4440 ecore_job_del(sd->calc_job);
4441 sd->calc_job = ecore_job_add(_calc_job, data);
4443 if (ok == ECORE_CALLBACK_CANCEL) sd->queue_idle_enterer = NULL;
4449 _requeue_idle_enterer(Elm_Genlist_Data *sd)
4451 ecore_idle_enterer_del(sd->queue_idle_enterer);
4452 sd->queue_idle_enterer = ecore_idle_enterer_add(_item_idle_enterer, sd->obj);
4456 _item_queue(Elm_Genlist_Data *sd,
4462 if (it->item->queued) return;
4463 it->item->queued = EINA_TRUE;
4464 if (cb && !sd->requeued)
4465 sd->queue = eina_list_sorted_insert(sd->queue, cb, it);
4467 sd->queue = eina_list_append(sd->queue, it);
4468 // FIXME: why does a freeze then thaw here cause some genlist
4469 // elm_genlist_item_append() to be much much slower?
4470 // evas_event_freeze(evas_object_evas_get(sd->obj));
4471 while ((sd->queue) && ((!sd->blocks) || (!sd->blocks->next)))
4473 ELM_SAFE_FREE(sd->queue_idle_enterer, ecore_idle_enterer_del);
4476 while ((sd->queue) && (sd->blocks) &&
4477 (sd->homogeneous) && (sd->mode == ELM_LIST_COMPRESS))
4479 ELM_SAFE_FREE(sd->queue_idle_enterer, ecore_idle_enterer_del);
4483 // evas_event_thaw(evas_object_evas_get(sd->obj));
4484 // evas_event_thaw_eval(evas_object_evas_get(sd->obj));
4485 evas_object_geometry_get(sd->obj, NULL, NULL, &w, NULL);
4486 if (w > 0) _requeue_idle_enterer(sd);
4489 /* If the application wants to know the relative item, use
4490 * elm_genlist_item_prev_get(it)*/
4492 _item_move_after(Elm_Gen_Item *it,
4493 Elm_Gen_Item *after)
4497 if (it == after) return;
4498 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
4501 eina_inlist_remove(sd->items, EINA_INLIST_GET(it));
4502 if (it->item->block) _item_block_del(it);
4504 sd->items = eina_inlist_append_relative
4505 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(after));
4507 it->item->rel->item->rel_revs =
4508 eina_list_remove(it->item->rel->item->rel_revs, it);
4509 it->item->rel = after;
4510 after->item->rel_revs = eina_list_append(after->item->rel_revs, it);
4511 it->item->before = EINA_FALSE;
4512 if (after->item->group_item) it->item->group_item = after->item->group_item;
4513 _item_queue(sd, it, NULL);
4515 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED_AFTER, EO_OBJ(it));
4519 _access_activate_cb(void *data EINA_UNUSED,
4520 Evas_Object *part_obj EINA_UNUSED,
4521 Elm_Object_Item *eo_it)
4523 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
4526 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
4533 _item_highlight(it);
4543 while (sd->selected)
4545 Elm_Object_Item *eo_sel = sd->selected->data;
4546 Elm_Gen_Item *sel = eo_data_scope_get(eo_sel, ELM_GENLIST_ITEM_CLASS);
4547 _item_unselect(sel);
4552 const Eina_List *l, *l_next;
4553 Elm_Object_Item *eo_it2;
4555 EINA_LIST_FOREACH_SAFE(sd->selected, l, l_next, eo_it2)
4557 ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
4559 _item_unselect(it2);
4562 _item_highlight(it);
4567 /* If the application wants to know the relative item, use
4568 * elm_genlist_item_next_get(it)*/
4570 _item_move_before(Elm_Gen_Item *it,
4571 Elm_Gen_Item *before)
4574 if (!before) return;
4575 if (it == before) return;
4576 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
4579 eina_inlist_remove(sd->items, EINA_INLIST_GET(it));
4580 if (it->item->block) _item_block_del(it);
4581 sd->items = eina_inlist_prepend_relative
4582 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(before));
4584 it->item->rel->item->rel_revs =
4585 eina_list_remove(it->item->rel->item->rel_revs, it);
4586 it->item->rel = before;
4587 before->item->rel_revs = eina_list_append(before->item->rel_revs, it);
4588 it->item->before = EINA_TRUE;
4589 if (before->item->group_item)
4590 it->item->group_item = before->item->group_item;
4591 _item_queue(sd, it, NULL);
4593 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED_BEFORE, EO_OBJ(it));
4597 _item_mouse_up_cb(void *data,
4598 Evas *evas EINA_UNUSED,
4599 Evas_Object *obj EINA_UNUSED,
4602 Evas_Event_Mouse_Up *ev = event_info;
4603 Eina_Bool dragged = EINA_FALSE;
4604 Elm_Gen_Item *it = data;
4605 Evas_Coord x, y, dx, dy;
4607 if ((ev->button == 3) && (!it->dragging))
4609 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
4610 dx = it->dx - (ev->canvas.x - x);
4611 dy = it->dy - (ev->canvas.y - y);
4612 if (dx < 0) dx = -dx;
4613 if (dy < 0) dy = -dy;
4614 if ((dx < 5) && (dy < 5))
4615 evas_object_smart_callback_call(WIDGET(it), SIG_CLICKED_RIGHT, EO_OBJ(it));
4619 if (ev->button != 1) return;
4620 it->down = EINA_FALSE;
4621 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
4623 sd->mouse_down = EINA_FALSE;
4624 evas_object_smart_callback_call(WIDGET(it), SIG_RELEASED, EO_OBJ(it));
4625 if (sd->multi_touched)
4627 if ((!sd->multi) && (!it->selected) && (it->highlighted))
4628 _item_unhighlight(it);
4629 if (sd->multi_down) return;
4630 _multi_touch_gesture_eval(it);
4633 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
4634 sd->on_hold = EINA_TRUE;
4635 else sd->on_hold = EINA_FALSE;
4636 ELM_SAFE_FREE(it->long_timer, ecore_timer_del);
4639 it->dragging = EINA_FALSE;
4640 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG_STOP, EO_OBJ(it));
4643 ELM_SAFE_FREE(it->item->swipe_timer, ecore_timer_del);
4644 if (sd->multi_timer)
4646 ELM_SAFE_FREE(sd->multi_timer, ecore_timer_del);
4647 sd->multi_timeout = EINA_FALSE;
4651 if (sd->swipe) _swipe_do(it);
4652 sd->longpressed = EINA_FALSE;
4653 sd->on_hold = EINA_FALSE;
4656 if ((sd->reorder_mode) && (sd->reorder_it))
4658 Evas_Coord it_scrl_y = ev->canvas.y - sd->reorder_it->dy;
4659 sd->reorder_fast = 0;
4661 if (sd->reorder_rel &&
4662 (sd->reorder_it->parent == sd->reorder_rel->parent))
4664 if (it_scrl_y <= sd->reorder_rel->item->scrl_y)
4665 _item_move_before(sd->reorder_it, sd->reorder_rel);
4667 _item_move_after(sd->reorder_it, sd->reorder_rel);
4668 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED, EO_OBJ(it));
4672 ecore_job_del(sd->calc_job);
4673 sd->calc_job = ecore_job_add(_calc_job, sd->obj);
4675 edje_object_signal_emit(VIEW(it), SIGNAL_REORDER_DISABLED, "elm");
4676 sd->reorder_it = sd->reorder_rel = NULL;
4677 eo_do(sd->obj, elm_interface_scrollable_hold_set(EINA_FALSE));
4678 eo_do(sd->obj, elm_interface_scrollable_bounce_allow_set
4679 (sd->h_bounce, sd->v_bounce));
4681 if (sd->longpressed)
4683 sd->longpressed = EINA_FALSE;
4684 if ((!sd->wasselected) && (!it->flipped))
4686 sd->wasselected = EINA_FALSE;
4691 if (it->want_unrealize)
4693 _elm_genlist_item_unrealize(it, EINA_FALSE);
4694 if (it->item->block->want_unrealize)
4695 _item_block_unrealize(it->item->block);
4699 if (_is_no_select(it) ||
4700 (eo_do(EO_OBJ(it), elm_wdg_item_disabled_get()) || (dragged)))
4703 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
4705 evas_object_ref(sd->obj);
4708 ((sd->multi_select_mode != ELM_OBJECT_MULTI_SELECT_MODE_WITH_CONTROL) ||
4709 (evas_key_modifier_is_set(ev->modifiers, "Control"))))
4713 _item_highlight(it);
4714 if (_item_select(it)) goto deleted;
4723 while (sd->selected)
4725 Elm_Object_Item *eo_sel = sd->selected->data;
4726 Elm_Gen_Item *sel = eo_data_scope_get(eo_sel, ELM_GENLIST_ITEM_CLASS);
4727 _item_unselect(sel);
4732 const Eina_List *l, *l_next;
4733 Elm_Object_Item *eo_it2;
4735 EINA_LIST_FOREACH_SAFE(sd->selected, l, l_next, eo_it2)
4737 ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
4739 _item_unselect(it2);
4742 _item_highlight(it);
4743 if (_item_select(it)) goto deleted;
4746 if (sd->focused_item != EO_OBJ(it))
4747 elm_object_item_focus_set(EO_OBJ(it), EINA_TRUE);
4750 evas_object_unref(sd->obj);
4754 _item_mouse_callbacks_add(Elm_Gen_Item *it,
4757 evas_object_event_callback_add
4758 (view, EVAS_CALLBACK_MOUSE_DOWN, _item_mouse_down_cb, it);
4759 evas_object_event_callback_add
4760 (view, EVAS_CALLBACK_MOUSE_UP, _item_mouse_up_cb, it);
4761 evas_object_event_callback_add
4762 (view, EVAS_CALLBACK_MOUSE_MOVE, _item_mouse_move_cb, it);
4763 evas_object_event_callback_add
4764 (view, EVAS_CALLBACK_MULTI_DOWN, _item_multi_down_cb, it);
4765 evas_object_event_callback_add
4766 (view, EVAS_CALLBACK_MULTI_UP, _item_multi_up_cb, it);
4767 evas_object_event_callback_add
4768 (view, EVAS_CALLBACK_MULTI_MOVE, _item_multi_move_cb, it);
4769 evas_object_event_callback_add
4770 (view, EVAS_CALLBACK_MOUSE_IN, _item_mouse_in_cb, it);
4774 _item_mouse_callbacks_del(Elm_Gen_Item *it,
4777 evas_object_event_callback_del_full
4778 (view, EVAS_CALLBACK_MOUSE_DOWN, _item_mouse_down_cb, it);
4779 evas_object_event_callback_del_full
4780 (view, EVAS_CALLBACK_MOUSE_UP, _item_mouse_up_cb, it);
4781 evas_object_event_callback_del_full
4782 (view, EVAS_CALLBACK_MOUSE_MOVE, _item_mouse_move_cb, it);
4783 evas_object_event_callback_del_full
4784 (view, EVAS_CALLBACK_MULTI_DOWN, _item_multi_down_cb, it);
4785 evas_object_event_callback_del_full
4786 (view, EVAS_CALLBACK_MULTI_UP, _item_multi_up_cb, it);
4787 evas_object_event_callback_del_full
4788 (view, EVAS_CALLBACK_MULTI_MOVE, _item_multi_move_cb, it);
4789 evas_object_event_callback_del_full
4790 (view, EVAS_CALLBACK_MOUSE_IN, _item_mouse_in_cb, it);
4794 _scroll_hold_timer_cb(void *data)
4796 ELM_GENLIST_DATA_GET(data, sd);
4798 if (!data) return ECORE_CALLBACK_CANCEL;
4800 eo_do(sd->obj, elm_interface_scrollable_hold_set(EINA_FALSE));
4801 sd->scr_hold_timer = NULL;
4803 return ECORE_CALLBACK_CANCEL;
4807 _decorate_item_unrealize(Elm_Gen_Item *it)
4809 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
4810 Evas_Object *obj = sd->obj;
4812 if (!it->item->deco_it_view) return;
4814 evas_event_freeze(evas_object_evas_get(obj));
4816 _view_clear(GL_IT(it)->deco_it_view, &(GL_IT(it)->deco_it_texts),
4817 &(GL_IT(it)->deco_it_contents));
4819 edje_object_part_unswallow(it->item->deco_it_view, VIEW(it));
4820 evas_object_smart_member_add(VIEW(it), sd->pan_obj);
4821 ELM_SAFE_FREE(it->item->deco_it_view, evas_object_del);
4823 if (sd->mode_item == it)
4824 sd->mode_item = NULL;
4825 evas_event_thaw(evas_object_evas_get(obj));
4826 evas_event_thaw_eval(evas_object_evas_get(obj));
4830 _decorate_item_finished_signal_cb(void *data,
4832 const char *emission EINA_UNUSED,
4833 const char *source EINA_UNUSED)
4835 Elm_Gen_Item *it = data;
4839 if (!it || !obj) return;
4840 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
4842 te = evas_object_evas_get(obj);
4844 if ((!it->realized) || (!it->item->deco_it_view)) return;
4846 evas_event_freeze(te);
4847 it->item->nocache_once = EINA_FALSE;
4848 _decorate_item_unrealize(it);
4849 if (it->item->group_item)
4850 evas_object_stack_above(it->item->VIEW(group_item), sd->stack[1]);
4852 snprintf(buf, sizeof(buf), "elm,state,%s,passive,finished",
4853 sd->decorate_it_type);
4854 edje_object_signal_callback_del_full
4855 (obj, buf, "elm", _decorate_item_finished_signal_cb, it);
4856 evas_event_thaw(te);
4857 evas_event_thaw_eval(te);
4861 _item_unrealize(Elm_Gen_Item *it)
4863 Evas_Object *content;
4864 EINA_LIST_FREE(it->item->flip_contents, content)
4865 evas_object_del(content);
4868 if (_elm_config->access_mode == ELM_ACCESS_MODE_ON)
4869 _elm_access_widget_item_unregister(it->base);
4871 // unswallow VIEW(it) first then manipulate VIEW(it)
4872 _decorate_item_unrealize(it);
4873 if (GL_IT(it)->wsd->decorate_all_mode) _decorate_all_item_unrealize(it);
4875 if (it->item->nocache_once || it->item->nocache)
4877 ELM_SAFE_FREE(VIEW(it), evas_object_del);
4878 ELM_SAFE_FREE(it->spacer, evas_object_del);
4882 edje_object_mirrored_set(VIEW(it),
4883 elm_widget_mirrored_get(WIDGET(it)));
4884 edje_object_scale_set(VIEW(it),
4885 elm_widget_scale_get(WIDGET(it))
4886 * elm_config_scale_get());
4887 _item_cache_add(it);
4891 it->realized = EINA_FALSE;
4892 it->want_unrealize = EINA_FALSE;
4896 _item_block_recalc(Item_Block *itb,
4902 Evas_Coord minw = 0, minh = 0;
4903 Eina_Bool show_me = EINA_FALSE, changed = EINA_FALSE;
4905 Elm_Genlist_Data *sd = NULL;
4908 EINA_LIST_FOREACH(itb->items, l, it)
4910 sd = GL_IT(it)->wsd;
4911 show_me |= it->item->show_me;
4914 if (qadd || (itb->sd->homogeneous &&
4915 (((GL_IT(it)->type & ELM_GENLIST_ITEM_GROUP) &&
4916 (!itb->sd->group_item_height)) ||
4917 (!(GL_IT(it)->type & ELM_GENLIST_ITEM_GROUP) &&
4918 (!itb->sd->item_height)))))
4920 if (!it->item->mincalcd) changed = EINA_TRUE;
4923 Eina_Bool doit = EINA_TRUE;
4925 if (itb->sd->homogeneous)
4927 if ((GL_IT(it)->type & ELM_GENLIST_ITEM_GROUP) &&
4928 (itb->sd->group_item_height == 0))
4930 else if (itb->sd->item_height == 0)
4937 _item_realize(it, in, EINA_TRUE);
4938 _elm_genlist_item_unrealize(it, EINA_TRUE);
4942 if (GL_IT(it)->type & ELM_GENLIST_ITEM_GROUP)
4944 it->item->w = it->item->minw =
4945 sd->group_item_width;
4946 it->item->h = it->item->minh =
4947 sd->group_item_height;
4951 it->item->w = it->item->minw =
4953 it->item->h = it->item->minh =
4956 it->item->mincalcd = EINA_TRUE;
4962 if ((itb->sd->homogeneous) &&
4963 (itb->sd->mode == ELM_LIST_COMPRESS))
4965 if (GL_IT(it)->type & ELM_GENLIST_ITEM_GROUP)
4967 it->item->w = it->item->minw =
4968 sd->group_item_width;
4969 it->item->h = it->item->minh =
4970 sd->group_item_height;
4974 it->item->w = it->item->minw =
4976 it->item->h = it->item->minh =
4979 it->item->mincalcd = EINA_TRUE;
4983 _item_realize(it, in, EINA_TRUE);
4984 _elm_genlist_item_unrealize(it, EINA_TRUE);
4990 if (!it->item->mincalcd) changed = EINA_TRUE;
4991 _item_realize(it, in, EINA_FALSE);
4993 minh += it->item->minh;
4994 if (minw < it->item->minw) minw = it->item->minw;
5000 if (changed) itb->sd->pan_changed = changed;
5003 itb->changed = EINA_FALSE;
5004 itb->position_update = EINA_FALSE;
5010 _update_job(void *data)
5012 Eina_Bool position = EINA_FALSE, recalc = EINA_FALSE;
5013 ELM_GENLIST_DATA_GET(data, sd);
5018 sd->update_job = NULL;
5021 evas_event_freeze(evas_object_evas_get(sd->obj));
5022 EINA_INLIST_FOREACH(sd->blocks, itb)
5024 Evas_Coord itminw, itminh;
5031 _item_block_position(itb, num);
5035 recalc = EINA_FALSE;
5036 EINA_LIST_FOREACH(itb->items, l2, it)
5038 if (it->item->updateme)
5040 itminw = it->item->minw;
5041 itminh = it->item->minh;
5043 it->item->updateme = EINA_FALSE;
5046 _elm_genlist_item_unrealize(it, EINA_FALSE);
5047 _item_realize(it, num, EINA_FALSE);
5048 position = EINA_TRUE;
5052 _item_realize(it, num, EINA_TRUE);
5053 _elm_genlist_item_unrealize(it, EINA_TRUE);
5055 if ((it->item->minw != itminw) || (it->item->minh != itminh))
5060 itb->updateme = EINA_FALSE;
5063 position = EINA_TRUE;
5064 itb->changed = EINA_TRUE;
5065 _item_block_recalc(itb, num0, EINA_FALSE);
5066 _item_block_position(itb, num0);
5071 ecore_job_del(sd->calc_job);
5072 sd->calc_job = ecore_job_add(_calc_job, sd->obj);
5074 evas_event_thaw(evas_object_evas_get(sd->obj));
5075 evas_event_thaw_eval(evas_object_evas_get(sd->obj));
5079 _scroll_animate_start_cb(Evas_Object *obj,
5080 void *data EINA_UNUSED)
5082 evas_object_smart_callback_call(obj, SIG_SCROLL_ANIM_START, NULL);
5086 _scroll_animate_stop_cb(Evas_Object *obj,
5087 void *data EINA_UNUSED)
5089 evas_object_smart_callback_call(obj, SIG_SCROLL_ANIM_STOP, NULL);
5093 _scroll_drag_start_cb(Evas_Object *obj,
5094 void *data EINA_UNUSED)
5096 evas_object_smart_callback_call(obj, SIG_SCROLL_DRAG_START, NULL);
5100 _scroll_cb(Evas_Object *obj,
5101 void *data EINA_UNUSED)
5103 evas_object_smart_callback_call(obj, SIG_SCROLL, NULL);
5107 _scroll_drag_stop_cb(Evas_Object *obj,
5108 void *data EINA_UNUSED)
5110 evas_object_smart_callback_call(obj, SIG_SCROLL_DRAG_STOP, NULL);
5114 _edge_left_cb(Evas_Object *obj,
5115 void *data EINA_UNUSED)
5117 evas_object_smart_callback_call(obj, SIG_EDGE_LEFT, NULL);
5121 _edge_right_cb(Evas_Object *obj,
5122 void *data EINA_UNUSED)
5124 evas_object_smart_callback_call(obj, SIG_EDGE_RIGHT, NULL);
5128 _edge_top_cb(Evas_Object *obj,
5129 void *data EINA_UNUSED)
5131 evas_object_smart_callback_call(obj, SIG_EDGE_TOP, NULL);
5135 _edge_bottom_cb(Evas_Object *obj,
5136 void *data EINA_UNUSED)
5138 evas_object_smart_callback_call(obj, SIG_EDGE_BOTTOM, NULL);
5142 _vbar_drag_cb(Evas_Object *obj,
5143 void *data EINA_UNUSED)
5145 evas_object_smart_callback_call(obj, SIG_VBAR_DRAG, NULL);
5149 _vbar_press_cb(Evas_Object *obj,
5150 void *data EINA_UNUSED)
5152 evas_object_smart_callback_call(obj, SIG_VBAR_PRESS, NULL);
5156 _vbar_unpress_cb(Evas_Object *obj,
5157 void *data EINA_UNUSED)
5159 evas_object_smart_callback_call(obj, SIG_VBAR_UNPRESS, NULL);
5163 _hbar_drag_cb(Evas_Object *obj,
5164 void *data EINA_UNUSED)
5166 evas_object_smart_callback_call(obj, SIG_HBAR_DRAG, NULL);
5170 _hbar_press_cb(Evas_Object *obj,
5171 void *data EINA_UNUSED)
5173 evas_object_smart_callback_call(obj, SIG_HBAR_PRESS, NULL);
5177 _hbar_unpress_cb(Evas_Object *obj,
5178 void *data EINA_UNUSED)
5180 evas_object_smart_callback_call(obj, SIG_HBAR_UNPRESS, NULL);
5184 _decorate_item_realize(Elm_Gen_Item *it)
5186 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
5187 Evas_Object *obj = sd->obj;
5190 if (GL_IT(it)->deco_it_view) return;
5192 evas_event_freeze(evas_object_evas_get(obj));
5193 it->item->deco_it_view = _view_create(it, it->itc->decorate_item_style);
5195 /* signal callback add */
5196 evas_object_event_callback_add
5197 (GL_IT(it)->deco_it_view, EVAS_CALLBACK_MOUSE_DOWN, _item_mouse_down_cb,
5199 evas_object_event_callback_add
5200 (GL_IT(it)->deco_it_view, EVAS_CALLBACK_MOUSE_UP, _item_mouse_up_cb, it);
5201 evas_object_event_callback_add
5202 (GL_IT(it)->deco_it_view, EVAS_CALLBACK_MOUSE_MOVE, _item_mouse_move_cb,
5205 _view_inflate(it->item->deco_it_view, it, &GL_IT(it)->deco_it_texts,
5206 &GL_IT(it)->deco_it_contents);
5207 edje_object_part_swallow
5208 (it->item->deco_it_view,
5209 edje_object_data_get(it->item->deco_it_view, "mode_part"), VIEW(it));
5211 snprintf(buf, sizeof(buf), "elm,state,%s,active", sd->decorate_it_type);
5212 edje_object_signal_emit(GL_IT(it)->deco_it_view, buf, "elm");
5213 edje_object_signal_emit(VIEW(it), buf, "elm");
5215 it->want_unrealize = EINA_FALSE;
5216 evas_event_thaw(evas_object_evas_get(obj));
5217 evas_event_thaw_eval(evas_object_evas_get(obj));
5221 _decorate_item_set(Elm_Gen_Item *it)
5225 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
5228 it->item->nocache_once = EINA_TRUE;
5230 ELM_SAFE_FREE(sd->scr_hold_timer, ecore_timer_del);
5231 eo_do(sd->obj, elm_interface_scrollable_hold_set(EINA_TRUE));
5232 sd->scr_hold_timer = ecore_timer_add(SCR_HOLD_TIME, _scroll_hold_timer_cb, sd->obj);
5234 evas_event_freeze(evas_object_evas_get(sd->obj));
5235 _decorate_item_realize(it);
5236 if (it->item->group_item)
5237 evas_object_stack_above(it->item->VIEW(group_item), sd->stack[1]);
5239 (it, it->item->deco_it_view, it->item->scrl_x, it->item->scrl_y);
5240 evas_event_thaw(evas_object_evas_get(sd->obj));
5241 evas_event_thaw_eval(evas_object_evas_get(sd->obj));
5246 _decorate_item_unset(Elm_Genlist_Data *sd)
5248 char buf[1024], buf2[1024];
5251 if (!sd->mode_item) return;
5254 it->item->nocache_once = EINA_TRUE;
5256 snprintf(buf, sizeof(buf), "elm,state,%s,passive", sd->decorate_it_type);
5257 snprintf(buf2, sizeof(buf2), "elm,state,%s,passive,finished",
5258 sd->decorate_it_type);
5259 edje_object_signal_emit(it->item->deco_it_view, buf, "elm");
5260 edje_object_signal_callback_add
5261 (it->item->deco_it_view, buf2, "elm", _decorate_item_finished_signal_cb,
5263 sd->mode_item = NULL;
5267 _elm_genlist_looping_up_cb(void *data,
5268 Evas_Object *obj EINA_UNUSED,
5269 const char *emission EINA_UNUSED,
5270 const char *source EINA_UNUSED)
5272 Evas_Object *genlist = data;
5274 ELM_GENLIST_DATA_GET(genlist, sd);
5276 Elm_Object_Item *eo_it = elm_genlist_last_item_get(genlist);
5278 elm_genlist_item_show(eo_it, ELM_GENLIST_ITEM_SCROLLTO_IN);
5279 _elm_widget_focus_highlight_signal_emit(genlist, "elm,action,focus,move,up", "elm");
5280 elm_layout_signal_emit(genlist, "elm,action,looping,up,end", "elm");
5281 sd->item_looping_on = EINA_FALSE;
5285 _elm_genlist_looping_down_cb(void *data,
5286 Evas_Object *obj EINA_UNUSED,
5287 const char *emission EINA_UNUSED,
5288 const char *source EINA_UNUSED)
5290 Evas_Object *genlist = data;
5292 ELM_GENLIST_DATA_GET(genlist, sd);
5294 Elm_Object_Item *eo_it = elm_genlist_first_item_get(genlist);
5296 elm_genlist_item_show(eo_it, ELM_GENLIST_ITEM_SCROLLTO_IN);
5297 _elm_widget_focus_highlight_signal_emit(genlist, "elm,action,focus,move,down", "elm");
5298 elm_layout_signal_emit(genlist, "elm,action,looping,down,end", "elm");
5299 sd->item_looping_on = EINA_FALSE;
5303 _elm_genlist_focus_highlight_move_down_end_cb(void *data,
5304 Evas_Object *obj EINA_UNUSED,
5305 const char *emission EINA_UNUSED,
5306 const char *source EINA_UNUSED)
5308 Evas_Object *gl = data;
5309 Elm_Object_Item *eo_it = elm_genlist_first_item_get(gl);
5311 if (!_elm_config->item_select_on_focus_disable)
5312 elm_genlist_item_selected_set(eo_it, EINA_TRUE);
5314 elm_object_item_focus_set(eo_it, EINA_TRUE);
5316 _elm_widget_focus_highlight_signal_emit(gl, "elm,action,focus,move,home,up", "elm");
5320 _elm_genlist_focus_highlight_move_up_end_cb(void *data,
5321 Evas_Object *obj EINA_UNUSED,
5322 const char *emission EINA_UNUSED,
5323 const char *source EINA_UNUSED)
5325 Evas_Object *gl = data;
5326 Elm_Object_Item *eo_it = elm_genlist_last_item_get(gl);
5328 if (!_elm_config->item_select_on_focus_disable)
5329 elm_genlist_item_selected_set(eo_it, EINA_TRUE);
5331 elm_object_item_focus_set(eo_it, EINA_TRUE);
5333 _elm_widget_focus_highlight_signal_emit(gl, "elm,action,focus,move,home,down", "elm");
5337 _elm_genlist_evas_object_smart_add(Eo *obj, Elm_Genlist_Data *priv)
5339 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
5340 Elm_Genlist_Pan_Data *pan_data;
5341 Evas_Coord minw, minh;
5344 eo_do_super(obj, MY_CLASS, evas_obj_smart_add());
5345 elm_widget_sub_object_parent_add(obj);
5347 priv->hit_rect = evas_object_rectangle_add(evas_object_evas_get(obj));
5348 evas_object_smart_member_add(priv->hit_rect, obj);
5349 elm_widget_sub_object_add(obj, priv->hit_rect);
5351 /* common scroller hit rectangle setup */
5352 evas_object_color_set(priv->hit_rect, 0, 0, 0, 0);
5353 evas_object_show(priv->hit_rect);
5354 evas_object_repeat_events_set(priv->hit_rect, EINA_TRUE);
5356 elm_widget_can_focus_set(obj, EINA_TRUE);
5357 elm_widget_on_show_region_hook_set(obj, _show_region_hook, NULL);
5359 if (!elm_layout_theme_set
5360 (obj, "genlist", "base", elm_widget_style_get(obj)))
5361 CRI("Failed to set layout!");
5363 eo_do(obj, elm_interface_scrollable_objects_set(wd->resize_obj, priv->hit_rect));
5365 eo_do(obj, elm_interface_scrollable_bounce_allow_set
5366 (EINA_FALSE, _elm_config->thumbscroll_bounce_enable));
5367 priv->v_bounce = _elm_config->thumbscroll_bounce_enable;
5370 elm_interface_scrollable_animate_start_cb_set(_scroll_animate_start_cb),
5371 elm_interface_scrollable_animate_stop_cb_set(_scroll_animate_stop_cb),
5372 elm_interface_scrollable_scroll_cb_set(_scroll_cb),
5373 elm_interface_scrollable_drag_start_cb_set(_scroll_drag_start_cb),
5374 elm_interface_scrollable_drag_stop_cb_set(_scroll_drag_stop_cb),
5375 elm_interface_scrollable_edge_left_cb_set(_edge_left_cb),
5376 elm_interface_scrollable_edge_right_cb_set(_edge_right_cb),
5377 elm_interface_scrollable_edge_top_cb_set(_edge_top_cb),
5378 elm_interface_scrollable_edge_bottom_cb_set(_edge_bottom_cb),
5379 elm_interface_scrollable_vbar_drag_cb_set(_vbar_drag_cb),
5380 elm_interface_scrollable_vbar_press_cb_set(_vbar_press_cb),
5381 elm_interface_scrollable_vbar_unpress_cb_set(_vbar_unpress_cb),
5382 elm_interface_scrollable_hbar_drag_cb_set(_hbar_drag_cb),
5383 elm_interface_scrollable_hbar_press_cb_set(_hbar_press_cb),
5384 elm_interface_scrollable_hbar_unpress_cb_set(_hbar_unpress_cb));
5386 priv->mode = ELM_LIST_SCROLL;
5387 priv->max_items_per_block = MAX_ITEMS_PER_BLOCK;
5388 priv->item_cache_max = priv->max_items_per_block * 2;
5389 priv->longpress_timeout = _elm_config->longpress_timeout;
5390 priv->highlight = EINA_TRUE;
5392 priv->pan_obj = eo_add(MY_PAN_CLASS, evas_object_evas_get(obj));
5393 pan_data = eo_data_scope_get(priv->pan_obj, MY_PAN_CLASS);
5394 eo_data_ref(obj, NULL);
5395 pan_data->wobj = obj;
5396 pan_data->wsd = priv;
5398 for (i = 0; i < 2; i++)
5400 priv->stack[i] = evas_object_rectangle_add(evas_object_evas_get(obj));
5401 evas_object_smart_member_add(priv->stack[i], priv->pan_obj);
5404 eo_do(obj, elm_interface_scrollable_extern_pan_set(priv->pan_obj));
5406 edje_object_size_min_calc(wd->resize_obj, &minw, &minh);
5407 evas_object_size_hint_min_set(obj, minw, minh);
5409 _mirrored_set(obj, elm_widget_mirrored_get(obj));
5411 elm_layout_sizing_eval(obj);
5413 edje_object_signal_callback_add(wd->resize_obj, "elm,looping,up,done", "elm", _elm_genlist_looping_up_cb, obj);
5414 edje_object_signal_callback_add(wd->resize_obj, "elm,looping,down,done", "elm", _elm_genlist_looping_down_cb, obj);
5418 _elm_genlist_evas_object_smart_del(Eo *obj, Elm_Genlist_Data *sd)
5422 elm_genlist_clear(obj);
5423 for (i = 0; i < 2; i++)
5424 ELM_SAFE_FREE(sd->stack[i], evas_object_del);
5425 ELM_SAFE_FREE(sd->pan_obj, evas_object_del);
5427 _item_cache_zero(sd);
5428 ecore_job_del(sd->calc_job);
5429 ecore_job_del(sd->update_job);
5430 ecore_idle_enterer_del(sd->queue_idle_enterer);
5431 ecore_idler_del(sd->must_recalc_idler);
5432 ecore_timer_del(sd->multi_timer);
5433 eina_stringshare_del(sd->decorate_it_type);
5434 ecore_animator_del(sd->tree_effect_animator);
5436 eo_do_super(obj, MY_CLASS, evas_obj_smart_del());
5440 _elm_genlist_evas_object_smart_move(Eo *obj, Elm_Genlist_Data *sd, Evas_Coord x, Evas_Coord y)
5442 eo_do_super(obj, MY_CLASS, evas_obj_smart_move(x, y));
5444 evas_object_move(sd->hit_rect, x, y);
5448 _elm_genlist_evas_object_smart_resize(Eo *obj, Elm_Genlist_Data *sd, Evas_Coord w, Evas_Coord h)
5450 eo_do_super(obj, MY_CLASS, evas_obj_smart_resize(w, h));
5452 evas_object_resize(sd->hit_rect, w, h);
5453 if ((sd->queue) && (!sd->queue_idle_enterer) && (w > 0))
5454 _requeue_idle_enterer(sd);
5458 _elm_genlist_evas_object_smart_member_add(Eo *obj, Elm_Genlist_Data *sd, Evas_Object *member)
5460 eo_do_super(obj, MY_CLASS, evas_obj_smart_member_add(member));
5463 evas_object_raise(sd->hit_rect);
5467 _access_obj_process(Elm_Genlist_Data *sd, Eina_Bool is_access)
5470 Eina_Bool done = EINA_FALSE;
5472 EINA_INLIST_FOREACH(sd->blocks, itb)
5480 EINA_LIST_FOREACH(itb->items, l, it)
5482 if (!it->realized) continue;
5483 if (is_access) _access_widget_item_register(it);
5485 _elm_access_widget_item_unregister(it->base);
5488 else if (done) break;
5493 _elm_genlist_elm_widget_access(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool acs)
5495 _elm_genlist_smart_focus_next_enable = acs;
5496 _access_obj_process(sd, _elm_genlist_smart_focus_next_enable);
5500 elm_genlist_add(Evas_Object *parent)
5502 EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
5503 Evas_Object *obj = eo_add(MY_CLASS, parent);
5508 _elm_genlist_eo_base_constructor(Eo *obj, Elm_Genlist_Data *sd)
5512 eo_do_super(obj, MY_CLASS, eo_constructor());
5514 evas_obj_type_set(MY_CLASS_NAME_LEGACY),
5515 evas_obj_smart_callbacks_descriptions_set(_smart_callbacks),
5516 elm_interface_atspi_accessible_role_set(ELM_ATSPI_ROLE_LIST));
5520 _internal_elm_genlist_clear(Evas_Object *obj)
5522 ELM_GENLIST_DATA_GET(obj, sd);
5525 _elm_genlist_item_unfocused(sd->focused_item);
5526 if (sd->mode_item) sd->mode_item = NULL;
5528 ELM_SAFE_FREE(sd->state, eina_inlist_sorted_state_free);
5530 evas_event_freeze(evas_object_evas_get(sd->obj));
5532 // Do not use EINA_INLIST_FOREACH or EINA_INLIST_FOREACH_SAFE
5533 // because sd->items can be modified inside elm_widget_item_del()
5536 it = EINA_INLIST_CONTAINER_GET(sd->items->last, Elm_Gen_Item);
5537 eo_do(EO_OBJ(it), elm_wdg_item_del());
5540 sd->pan_changed = EINA_TRUE;
5543 ELM_SAFE_FREE(sd->calc_job, ecore_job_del);
5544 sd->anchor_item = NULL;
5545 ELM_SAFE_FREE(sd->queue_idle_enterer, ecore_idle_enterer_del);
5546 ELM_SAFE_FREE(sd->must_recalc_idler, ecore_idler_del);
5547 ELM_SAFE_FREE(sd->reorder_move_animator, ecore_animator_del);
5548 sd->reorder_old_pan_y = 0;
5551 if (sd->selected) ELM_SAFE_FREE(sd->selected, eina_list_free);
5553 sd->show_item = NULL;
5562 evas_object_size_hint_min_set(sd->pan_obj, sd->minw, sd->minh);
5563 evas_object_smart_callback_call(sd->pan_obj, "changed", NULL);
5565 elm_layout_sizing_eval(sd->obj);
5566 eo_do(obj, elm_interface_scrollable_content_region_show(0, 0, 0, 0));
5568 ELM_SAFE_FREE(sd->event_block_rect, evas_object_del);
5569 ELM_SAFE_FREE(sd->scr_hold_timer, ecore_timer_del);
5570 ELM_SAFE_FREE(sd->queue, eina_list_free);
5572 evas_event_thaw(evas_object_evas_get(sd->obj));
5573 evas_event_thaw_eval(evas_object_evas_get(sd->obj));
5576 /* Return EINA_TRUE if the item is deleted in this function */
5578 _item_select(Elm_Gen_Item *it)
5580 Evas_Object *obj = WIDGET(it);
5581 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
5582 Elm_Object_Item *eo_it = EO_OBJ(it);
5584 if (eo_do(eo_it, elm_wdg_item_disabled_get())) return EINA_FALSE;
5585 if (_is_no_select(it) || (it->decorate_it_set)) return EINA_FALSE;
5586 if ((sd->select_mode != ELM_OBJECT_SELECT_MODE_ALWAYS) &&
5587 (it->select_mode != ELM_OBJECT_SELECT_MODE_ALWAYS) && it->selected)
5592 const Eina_List *l, *ll;
5593 Elm_Object_Item *eo_it2;
5594 EINA_LIST_FOREACH_SAFE(sd->selected, l, ll, eo_it2)
5596 ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
5597 if (it2 != it) _item_unselect(it2);
5603 it->selected = EINA_TRUE;
5605 eina_list_append(sd->selected, eo_it);
5608 evas_object_ref(obj);
5610 elm_object_item_focus_set(eo_it, EINA_TRUE);
5611 _elm_genlist_item_content_focus_set(it, ELM_FOCUS_PREVIOUS);
5612 sd->last_selected_item = eo_it;
5613 _item_highlight(it);
5616 if (it->func.func) it->func.func((void *)it->func.data, WIDGET(it), eo_it);
5617 // delete item if it's requested deletion in the above callbacks.
5618 if ((it->base)->on_deletion) goto item_deleted;
5619 evas_object_smart_callback_call(WIDGET(it), SIG_SELECTED, eo_it);
5620 // delete item if it's requested deletion in the above callbacks.
5621 if ((it->base)->on_deletion) goto item_deleted;
5624 if (!(sd->focus_on_selection_enabled || _elm_config->item_select_on_focus_disable))
5626 Evas_Object *swallow_obj;
5628 EINA_LIST_FOREACH(it->contents, l, swallow_obj)
5630 if (elm_widget_is(swallow_obj) && elm_object_focus_get(swallow_obj))
5632 elm_object_focus_set(obj, EINA_FALSE);
5633 elm_object_focus_set(obj, EINA_TRUE);
5639 evas_object_unref(obj);
5643 it->walking = -1; //This item was removed from it's item list.
5646 evas_object_unref(obj);
5650 EOLIAN static Evas_Object *
5651 _elm_genlist_item_elm_widget_item_part_content_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it, const char * part)
5653 Evas_Object *ret = NULL;
5654 if (it->deco_all_view)
5655 ret = edje_object_part_swallow_get(it->deco_all_view, part);
5656 else if (it->decorate_it_set)
5657 ret = edje_object_part_swallow_get(it->item->deco_it_view, part);
5661 ret = edje_object_part_swallow_get(VIEW(it), part);
5663 ret = edje_object_part_swallow_get(VIEW(it), "elm.swallow.icon");
5668 EOLIAN static const char *
5669 _elm_genlist_item_elm_widget_item_part_text_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it, const char * part)
5671 if (!it->itc->func.text_get) return NULL;
5672 const char *ret = NULL;
5673 if (it->deco_all_view)
5674 ret = edje_object_part_text_get(it->deco_all_view, part);
5675 else if (it->decorate_it_set)
5676 ret = edje_object_part_text_get(it->item->deco_it_view, part);
5680 ret = edje_object_part_text_get(VIEW(it), part);
5682 ret = edje_object_part_text_get(VIEW(it), "elm.text");
5688 _elm_genlist_item_elm_widget_item_disable(Eo *eo_it, Elm_Gen_Item *it)
5694 if (eo_it == GL_IT(it)->wsd->focused_item)
5695 _elm_genlist_item_unfocused(eo_it);
5696 ELM_SAFE_FREE(it->long_timer, ecore_timer_del);
5700 if (eo_do(EO_OBJ(it), elm_wdg_item_disabled_get()))
5702 edje_object_signal_emit(VIEW(it), SIGNAL_DISABLED, "elm");
5703 if (it->deco_all_view)
5704 edje_object_signal_emit
5705 (it->deco_all_view, SIGNAL_DISABLED, "elm");
5709 edje_object_signal_emit(VIEW(it), SIGNAL_ENABLED, "elm");
5710 if (it->deco_all_view)
5711 edje_object_signal_emit
5712 (it->deco_all_view, SIGNAL_ENABLED, "elm");
5714 EINA_LIST_FOREACH(it->contents, l, obj)
5715 elm_widget_disabled_set(obj, eo_do(EO_OBJ(it), elm_wdg_item_disabled_get()));
5719 EOLIAN static Eina_Bool
5720 _elm_genlist_item_elm_widget_item_del_pre(Eo *eo_it EINA_UNUSED,
5723 /* This item is getting removed from a callback that triggered in the
5724 _item_select(). Just pend removing. Because this will be removed right
5725 after in the _item_select(). So pratically, this item won't be
5727 if (it->walking > 0)
5729 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
5730 sd->items = eina_inlist_remove(sd->items, EINA_INLIST_GET(it));
5739 _elm_genlist_item_elm_widget_item_signal_emit(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it, const char *emission, const char *source)
5743 WRN("Item is not realized yet");
5746 edje_object_signal_emit(VIEW(it), emission, source);
5747 if (it->deco_all_view)
5748 edje_object_signal_emit(it->deco_all_view, emission, source);
5752 _elm_genlist_item_elm_widget_item_focus_set(Eo *eo_it, Elm_Gen_Item *it, Eina_Bool focused)
5754 Evas_Object *obj = WIDGET(it);
5755 ELM_GENLIST_DATA_GET(obj, sd);
5759 sd->last_focused_item = eo_it;
5760 if (!elm_object_focus_get(obj))
5761 elm_object_focus_set(obj, EINA_TRUE);
5763 if (!elm_widget_focus_get(obj))
5766 if (eo_it != sd->focused_item)
5768 if (sd->focused_item)
5769 _elm_genlist_item_unfocused(sd->focused_item);
5770 _elm_genlist_item_focused(eo_it);
5772 _elm_widget_item_highlight_in_theme(obj, EO_OBJ(it));
5773 _elm_widget_highlight_in_theme_update(obj);
5774 _elm_widget_focus_highlight_start(obj);
5779 if (!elm_widget_focus_get(obj))
5781 _elm_genlist_item_unfocused(eo_it);
5785 EOLIAN static Eina_Bool
5786 _elm_genlist_item_elm_widget_item_focus_get(Eo *eo_it, Elm_Gen_Item *it)
5788 Evas_Object *obj = WIDGET(it);
5789 ELM_GENLIST_DATA_GET(obj, sd);
5791 if (eo_it == sd->focused_item)
5798 _elm_genlist_item_eo_base_constructor(Eo *eo_it, Elm_Gen_Item *it)
5800 eo_do_super(eo_it, ELM_GENLIST_ITEM_CLASS, eo_constructor());
5801 it->base = eo_data_scope_get(eo_it, ELM_WIDGET_ITEM_CLASS);
5804 static Elm_Gen_Item *
5805 _elm_genlist_item_new(Elm_Genlist_Data *sd,
5806 const Elm_Genlist_Item_Class *itc,
5808 Elm_Object_Item *eo_parent,
5809 Elm_Genlist_Item_Type type,
5811 const void *func_data)
5816 if (!itc) return NULL;
5818 Eo *eo_it = eo_add(ELM_GENLIST_ITEM_CLASS, sd->obj);
5819 if (!eo_it) return NULL;
5820 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
5823 elm_genlist_item_class_ref((Elm_Genlist_Item_Class *)itc);
5825 ELM_GENLIST_ITEM_DATA_GET(eo_parent, parent);
5826 WIDGET_ITEM_DATA_SET(EO_OBJ(it), data);
5827 it->parent = parent;
5828 it->func.func = func;
5829 it->func.data = func_data;
5831 GL_IT(it) = ELM_NEW(Elm_Gen_Item_Type);
5832 GL_IT(it)->wsd = sd;
5833 GL_IT(it)->type = type;
5837 if (GL_IT(it->parent)->type & ELM_GENLIST_ITEM_GROUP)
5838 GL_IT(it)->group_item = parent;
5839 else if (GL_IT(it->parent)->group_item)
5840 GL_IT(it)->group_item = GL_IT(it->parent)->group_item;
5842 for (it2 = it, depth = 0; it2->parent; it2 = it2->parent)
5844 if (!(GL_IT(it2->parent)->type & ELM_GENLIST_ITEM_GROUP)) depth += 1;
5846 GL_IT(it)->expanded_depth = depth;
5853 _elm_genlist_item_compare(const void *data,
5856 const Elm_Gen_Item *it, *item1;
5858 it = ELM_GEN_ITEM_FROM_INLIST(data);
5859 item1 = ELM_GEN_ITEM_FROM_INLIST(data1);
5860 return GL_IT(it)->wsd->item_compare_cb(EO_OBJ(it), EO_OBJ(item1));
5864 _elm_genlist_item_list_compare(const void *data,
5867 const Elm_Gen_Item *it = data;
5868 const Elm_Gen_Item *item1 = data1;
5870 return GL_IT(it)->wsd->item_compare_cb(EO_OBJ(it), EO_OBJ(item1));
5874 _elm_genlist_eo_item_list_compare(const void *data,
5877 const Elm_Object_Item *eo_it = data;
5878 const Elm_Object_Item *eo_item1 = data1;
5879 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
5881 return GL_IT(it)->wsd->item_compare_cb(eo_it, eo_item1);
5884 EOLIAN static unsigned int
5885 _elm_genlist_items_count(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
5887 return sd->item_count;
5891 _list_last_recursive(Eina_List *list)
5893 Eina_List *ll, *ll2;
5894 Elm_Object_Item *eo_it2;
5896 ll = eina_list_last(list);
5897 if (!ll) return NULL;
5900 ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
5902 if (it2->item->items)
5904 ll2 = _list_last_recursive(it2->item->items);
5914 EOLIAN static Elm_Object_Item*
5915 _elm_genlist_item_append(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, const Elm_Genlist_Item_Class *itc, const void *data, Elm_Object_Item *eo_parent, Elm_Genlist_Item_Type type, Evas_Smart_Cb func, const void *func_data)
5921 ELM_GENLIST_ITEM_DATA_GET(eo_parent, parent);
5922 ELM_GENLIST_ITEM_CHECK_OR_RETURN(parent, NULL);
5923 EINA_SAFETY_ON_FALSE_RETURN_VAL((obj == WIDGET(parent)), NULL);
5926 it = _elm_genlist_item_new
5927 (sd, itc, data, eo_parent, type, func, func_data);
5928 if (!it) return NULL;
5932 if (GL_IT(it)->type & ELM_GENLIST_ITEM_GROUP)
5933 sd->group_items = eina_list_append(sd->group_items, it);
5934 sd->items = eina_inlist_append(sd->items, EINA_INLIST_GET(it));
5935 it->item->rel = NULL;
5939 Elm_Object_Item *eo_it2 = NULL;
5940 Eina_List *ll = _list_last_recursive(it->parent->item->items);
5942 if (ll) eo_it2 = ll->data;
5943 it->parent->item->items =
5944 eina_list_append(it->parent->item->items, EO_OBJ(it));
5945 if (!eo_it2) eo_it2 = EO_OBJ(it->parent);
5946 ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
5947 sd->items = eina_inlist_append_relative
5948 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(it2));
5949 it->item->rel = it2;
5950 it2->item->rel_revs = eina_list_append(it2->item->rel_revs, it);
5952 it->item->before = EINA_FALSE;
5953 _item_queue(sd, it, NULL);
5958 EOLIAN static Elm_Object_Item*
5959 _elm_genlist_item_prepend(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, const Elm_Genlist_Item_Class *itc, const void *data, Elm_Object_Item *eo_parent, Elm_Genlist_Item_Type type, Evas_Smart_Cb func, const void *func_data)
5965 ELM_GENLIST_ITEM_DATA_GET(eo_parent, parent);
5966 ELM_GENLIST_ITEM_CHECK_OR_RETURN(parent, NULL);
5967 EINA_SAFETY_ON_FALSE_RETURN_VAL((obj == WIDGET(parent)), NULL);
5970 it = _elm_genlist_item_new
5971 (sd, itc, data, eo_parent, type, func, func_data);
5972 if (!it) return NULL;
5976 if (GL_IT(it)->type & ELM_GENLIST_ITEM_GROUP)
5977 sd->group_items = eina_list_prepend(sd->group_items, it);
5978 sd->items = eina_inlist_prepend(sd->items, EINA_INLIST_GET(it));
5979 it->item->rel = NULL;
5983 Elm_Object_Item *eo_it2 = NULL;
5984 Eina_List *ll = it->parent->item->items;
5986 if (ll) eo_it2 = ll->data;
5987 it->parent->item->items =
5988 eina_list_prepend(it->parent->item->items, EO_OBJ(it));
5989 if (!eo_it2) eo_it2 = EO_OBJ(it->parent);
5990 ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
5991 sd->items = eina_inlist_prepend_relative
5992 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(it2));
5993 it->item->rel = it2;
5994 it2->item->rel_revs = eina_list_append(it2->item->rel_revs, it);
5996 it->item->before = EINA_TRUE;
5997 _item_queue(sd, it, NULL);
6002 EOLIAN static Elm_Object_Item*
6003 _elm_genlist_item_insert_after(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, const Elm_Genlist_Item_Class *itc, const void *data, Elm_Object_Item *eo_parent, Elm_Object_Item *eo_after, Elm_Genlist_Item_Type type, Evas_Smart_Cb func, const void *func_data)
6005 ELM_GENLIST_ITEM_DATA_GET(eo_after, after);
6008 ELM_GENLIST_ITEM_CHECK_OR_RETURN(after, NULL);
6009 EINA_SAFETY_ON_FALSE_RETURN_VAL((obj == WIDGET(after)), NULL);
6012 ELM_GENLIST_ITEM_DATA_GET(eo_parent, parent);
6013 ELM_GENLIST_ITEM_CHECK_OR_RETURN(parent, NULL);
6014 EINA_SAFETY_ON_FALSE_RETURN_VAL((obj == WIDGET(parent)), NULL);
6017 /* It makes no sense to insert after in an empty list with after !=
6018 * NULL, something really bad is happening in your app. */
6019 EINA_SAFETY_ON_NULL_RETURN_VAL(sd->items, NULL);
6021 it = _elm_genlist_item_new
6022 (sd, itc, data, eo_parent, type, func, func_data);
6023 if (!it) return NULL;
6027 if ((GL_IT(it)->type & ELM_GENLIST_ITEM_GROUP) &&
6028 (GL_IT(after)->type & ELM_GENLIST_ITEM_GROUP))
6029 sd->group_items = eina_list_append_relative
6030 (sd->group_items, it, after);
6034 it->parent->item->items =
6035 eina_list_append_relative(it->parent->item->items, EO_OBJ(it), eo_after);
6037 sd->items = eina_inlist_append_relative
6038 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(after));
6040 it->item->rel = after;
6041 after->item->rel_revs = eina_list_append(after->item->rel_revs, it);
6042 it->item->before = EINA_FALSE;
6043 _item_queue(sd, it, NULL);
6048 EOLIAN static Elm_Object_Item*
6049 _elm_genlist_item_insert_before(Eo *obj, Elm_Genlist_Data *sd, const Elm_Genlist_Item_Class *itc, const void *data, Elm_Object_Item *eo_parent, Elm_Object_Item *eo_before, Elm_Genlist_Item_Type type, Evas_Smart_Cb func, const void *func_data)
6051 ELM_GENLIST_ITEM_DATA_GET(eo_before, before);
6054 ELM_GENLIST_ITEM_CHECK_OR_RETURN(before, NULL);
6055 EINA_SAFETY_ON_FALSE_RETURN_VAL((obj == WIDGET(before)), NULL);
6058 ELM_GENLIST_ITEM_DATA_GET(eo_parent, parent);
6059 ELM_GENLIST_ITEM_CHECK_OR_RETURN(parent, NULL);
6060 EINA_SAFETY_ON_FALSE_RETURN_VAL((obj == WIDGET(parent)), NULL);
6063 /* It makes no sense to insert before in an empty list with before
6064 * != NULL, something really bad is happening in your app. */
6065 EINA_SAFETY_ON_NULL_RETURN_VAL(sd->items, NULL);
6067 it = _elm_genlist_item_new
6068 (sd, itc, data, eo_parent, type, func, func_data);
6069 if (!it) return NULL;
6073 if ((GL_IT(it)->type & ELM_GENLIST_ITEM_GROUP) &&
6074 (GL_IT(before)->type & ELM_GENLIST_ITEM_GROUP))
6076 eina_list_prepend_relative(sd->group_items, it, before);
6080 it->parent->item->items =
6081 eina_list_prepend_relative(it->parent->item->items, EO_OBJ(it), eo_before);
6083 sd->items = eina_inlist_prepend_relative
6084 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(before));
6086 it->item->rel = before;
6087 GL_IT(before)->rel_revs = eina_list_append(GL_IT(before)->rel_revs, it);
6088 it->item->before = EINA_TRUE;
6089 _item_queue(sd, it, NULL);
6094 EOLIAN static Elm_Object_Item*
6095 _elm_genlist_item_sorted_insert(Eo *obj, Elm_Genlist_Data *sd, const Elm_Genlist_Item_Class *itc, const void *data, Elm_Object_Item *eo_parent, Elm_Genlist_Item_Type type, Eina_Compare_Cb comp, Evas_Smart_Cb func, const void *func_data)
6097 Elm_Gen_Item *rel = NULL;
6102 ELM_GENLIST_ITEM_DATA_GET(eo_parent, parent);
6103 ELM_GENLIST_ITEM_CHECK_OR_RETURN(parent, NULL);
6104 EINA_SAFETY_ON_FALSE_RETURN_VAL((obj == WIDGET(parent)), NULL);
6107 it = _elm_genlist_item_new
6108 (sd, itc, data, eo_parent, type, func, func_data);
6109 if (!it) return NULL;
6110 Elm_Object_Item *eo_it = EO_OBJ(it);
6112 sd->item_compare_cb = comp;
6116 Elm_Object_Item *eo_rel = NULL;
6120 l = eina_list_search_sorted_near_list
6121 (it->parent->item->items, _elm_genlist_eo_item_list_compare, eo_it,
6126 eo_rel = eina_list_data_get(l);
6127 rel = eo_data_scope_get(eo_rel, ELM_GENLIST_ITEM_CLASS);
6129 if (cmp_result >= 0)
6131 it->parent->item->items = eina_list_prepend_relative_list
6132 (it->parent->item->items, eo_it, l);
6133 sd->items = eina_inlist_prepend_relative
6134 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
6135 it->item->before = EINA_TRUE;
6137 else if (cmp_result < 0)
6139 it->parent->item->items = eina_list_append_relative_list
6140 (it->parent->item->items, eo_it, l);
6141 sd->items = eina_inlist_append_relative
6142 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
6143 it->item->before = EINA_FALSE;
6150 // ignoring the comparison
6151 it->parent->item->items = eina_list_prepend_relative_list
6152 (it->parent->item->items, eo_it, l);
6153 sd->items = eina_inlist_prepend_relative
6154 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
6155 it->item->before = EINA_FALSE;
6162 sd->state = eina_inlist_sorted_state_new();
6163 eina_inlist_sorted_state_init(sd->state, sd->items);
6164 sd->requeued = EINA_FALSE;
6167 if (GL_IT(it)->type == ELM_GENLIST_ITEM_GROUP)
6168 sd->group_items = eina_list_append(sd->group_items, it);
6170 sd->items = eina_inlist_sorted_state_insert
6171 (sd->items, EINA_INLIST_GET(it), _elm_genlist_item_compare,
6174 if (EINA_INLIST_GET(it)->next)
6176 rel = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
6177 it->item->before = EINA_TRUE;
6179 else if (EINA_INLIST_GET(it)->prev)
6181 rel = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
6182 it->item->before = EINA_FALSE;
6188 GL_IT(it)->rel = rel;
6189 rel->item->rel_revs = eina_list_append(rel->item->rel_revs, it);
6192 _item_queue(sd, it, _elm_genlist_item_list_compare);
6198 _elm_genlist_clear(Eo *obj, Elm_Genlist_Data *sd EINA_UNUSED)
6200 _internal_elm_genlist_clear(obj);
6204 _elm_genlist_multi_select_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool multi)
6206 sd->multi = !!multi;
6208 if (!sd->multi && sd->selected)
6211 Elm_Object_Item *eo_it;
6212 Elm_Object_Item *last = sd->selected->data;
6213 EINA_LIST_FOREACH_SAFE(sd->selected, l, ll, eo_it)
6217 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
6224 EOLIAN static Eina_Bool
6225 _elm_genlist_multi_select_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
6231 _elm_genlist_multi_select_mode_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Elm_Object_Multi_Select_Mode mode)
6233 if (mode >= ELM_OBJECT_MULTI_SELECT_MODE_MAX)
6236 if (sd->multi_select_mode != mode)
6237 sd->multi_select_mode = mode;
6240 EOLIAN static Elm_Object_Multi_Select_Mode
6241 _elm_genlist_multi_select_mode_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
6243 return sd->multi_select_mode;
6246 EOLIAN static Elm_Object_Item*
6247 _elm_genlist_selected_item_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
6250 return sd->selected->data;
6255 EOLIAN static const Eina_List*
6256 _elm_genlist_selected_items_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
6258 return sd->selected;
6261 EOLIAN static Eina_List*
6262 _elm_genlist_realized_items_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
6265 Eina_Bool done = EINA_FALSE;
6267 Eina_List *ret = NULL;
6269 EINA_INLIST_FOREACH(sd->blocks, itb)
6277 EINA_LIST_FOREACH(itb->items, l, it)
6279 if (it->realized) ret = eina_list_append(ret, EO_OBJ(it));
6291 EOLIAN static Elm_Object_Item*
6292 _elm_genlist_at_xy_item_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Evas_Coord x, Evas_Coord y, int *posret)
6294 Evas_Coord ox, oy, ow, oh;
6298 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
6300 EINA_INLIST_FOREACH(sd->blocks, itb)
6305 if (!ELM_RECTS_INTERSECT(ox + itb->x - itb->sd->pan_x,
6306 oy + itb->y - itb->sd->pan_y,
6307 itb->w, itb->h, x, y, 1, 1))
6309 EINA_LIST_FOREACH(itb->items, l, it)
6311 Evas_Coord itx, ity;
6313 itx = ox + itb->x + it->x - itb->sd->pan_x;
6314 ity = oy + itb->y + it->y - itb->sd->pan_y;
6315 if (ELM_RECTS_INTERSECT
6316 (itx, ity, it->item->w, it->item->h, x, y, 1, 1))
6320 if (y <= (ity + (it->item->h / 4))) *posret = -1;
6321 else if (y >= (ity + it->item->h - (it->item->h / 4)))
6328 lasty = ity + it->item->h;
6333 if (y > lasty) *posret = 1;
6340 EOLIAN static Elm_Object_Item*
6341 _elm_genlist_first_item_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
6343 return EO_OBJ(ELM_GEN_ITEM_FROM_INLIST(sd->items));
6346 EOLIAN static Elm_Object_Item*
6347 _elm_genlist_last_item_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
6351 if (!sd->items) return NULL;
6353 it = ELM_GEN_ITEM_FROM_INLIST(sd->items->last);
6358 EOLIAN static Elm_Object_Item *
6359 _elm_genlist_item_next_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
6363 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
6367 if (it) return EO_OBJ(it);
6371 EOLIAN static Elm_Object_Item *
6372 _elm_genlist_item_prev_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
6376 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
6380 if (it) return EO_OBJ(it);
6384 EOLIAN static Elm_Object_Item *
6385 _elm_genlist_item_parent_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
6387 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, NULL);
6389 return EO_OBJ(it->parent);
6392 EOLIAN static unsigned int
6393 _elm_genlist_item_subitems_count(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *item)
6395 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item, 0);
6397 return eina_list_count(item->item->items);
6400 EOLIAN static const Eina_List *
6401 _elm_genlist_item_subitems_get(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *item)
6403 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item, NULL);
6405 return item->item->items;
6409 _elm_genlist_item_subitems_clear(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it)
6411 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
6412 ELM_GENLIST_DATA_GET(WIDGET(it), sd);
6414 if (!sd->tree_effect_enabled || !sd->move_effect_mode)
6415 _item_sub_items_clear(it);
6418 if (!sd->tree_effect_animator)
6420 sd->expanded_item = it;
6421 _item_tree_effect_before(it);
6422 evas_object_stack_below(sd->event_block_rect, sd->stack[1]);
6423 evas_object_show(sd->event_block_rect);
6424 sd->start_time = ecore_time_get();
6425 sd->tree_effect_animator =
6426 ecore_animator_add(_tree_effect_animator_cb, sd->obj);
6429 _item_sub_items_clear(it);
6434 _elm_genlist_item_selected_set(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it,
6437 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
6439 if (eo_do(EO_OBJ(it), elm_wdg_item_disabled_get())) return;
6441 selected = !!selected;
6442 if (it->selected == selected) return;
6444 if (selected) _item_select(it);
6445 else _item_unselect(it);
6448 EOLIAN static Eina_Bool
6449 _elm_genlist_item_selected_get(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it)
6451 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
6453 return it->selected;
6456 static Elm_Gen_Item *
6457 _elm_genlist_expanded_next_item_get(Elm_Gen_Item *it)
6459 Elm_Object_Item *eo_it = EO_OBJ(it);
6460 Elm_Object_Item *eo_it2;
6462 if (it->item->expanded)
6464 eo_it2 = elm_genlist_item_next_get(eo_it);
6465 ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
6470 eo_it2 = elm_genlist_item_next_get(eo_it);
6473 ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
6474 if (it->item->expanded_depth >= it2->item->expanded_depth) return it2;
6475 eo_it2 = elm_genlist_item_next_get(eo_it2);
6478 return eo_data_scope_get(eo_it2, ELM_GENLIST_ITEM_CLASS);
6482 _elm_genlist_move_items_set(Elm_Gen_Item *it)
6485 Elm_Gen_Item *it2 = NULL;
6486 Evas_Coord ox, oy, ow, oh, dh = 0;
6487 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
6489 sd->expanded_next_item =
6490 _elm_genlist_expanded_next_item_get(it);
6492 if (it->item->expanded)
6494 Elm_Object_Item *eo_item;
6495 l = elm_genlist_realized_items_get((sd)->obj);
6496 EINA_LIST_FREE(l, eo_item)
6498 ELM_GENLIST_ITEM_DATA_GET(eo_item, item);
6499 sd->move_items = eina_list_append(sd->move_items, item);
6502 EINA_LIST_FOREACH_SAFE(sd->move_items, l, ll, it2)
6504 if (it2 == sd->expanded_next_item) break;
6505 sd->move_items = eina_list_remove(sd->move_items, it2);
6510 Elm_Object_Item *eo_it2 = NULL;
6511 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
6512 if (sd->expanded_next_item) eo_it2 = EO_OBJ(sd->expanded_next_item);
6514 while (eo_it2 && (dh < oy + oh))
6516 it2 = eo_data_scope_get(eo_it2, ELM_GENLIST_ITEM_CLASS);
6518 sd->move_items = eina_list_append(sd->move_items, it2);
6519 eo_it2 = elm_genlist_item_next_get(eo_it2);
6525 _event_block_rect_update(const Evas_Object *obj)
6527 Evas_Coord ox, oy, ow, oh;
6529 ELM_GENLIST_CHECK(obj);
6530 ELM_GENLIST_DATA_GET(obj, sd);
6532 if (!sd->event_block_rect)
6534 sd->event_block_rect = evas_object_rectangle_add(
6535 evas_object_evas_get(sd->obj));
6536 evas_object_smart_member_add(sd->event_block_rect, sd->pan_obj);
6539 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
6540 evas_object_color_set(sd->event_block_rect, 0, 0, 0, 0);
6541 evas_object_resize(sd->event_block_rect, ow, oh);
6542 evas_object_move(sd->event_block_rect, ox, oy);
6546 _elm_genlist_item_expanded_set(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it, Eina_Bool expanded)
6548 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
6549 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
6551 expanded = !!expanded;
6552 if (it->item->expanded == expanded) return;
6553 if (it->item->type != ELM_GENLIST_ITEM_TREE) return;
6554 it->item->expanded = expanded;
6555 sd->expanded_item = it;
6556 _elm_genlist_move_items_set(it);
6558 if (sd->tree_effect_enabled)
6559 _event_block_rect_update(WIDGET(it));
6561 if (it->item->expanded)
6563 sd->move_effect_mode = ELM_GENLIST_TREE_EFFECT_EXPAND;
6565 edje_object_signal_emit(VIEW(it), SIGNAL_EXPANDED, "elm");
6566 evas_object_smart_callback_call(WIDGET(it), SIG_EXPANDED, EO_OBJ(it));
6567 sd->auto_scroll_enabled = EINA_TRUE;
6571 sd->move_effect_mode = ELM_GENLIST_TREE_EFFECT_CONTRACT;
6573 edje_object_signal_emit(VIEW(it), SIGNAL_CONTRACTED, "elm");
6574 evas_object_smart_callback_call(WIDGET(it), SIG_CONTRACTED, EO_OBJ(it));
6575 sd->auto_scroll_enabled = EINA_FALSE;
6579 EOLIAN static Eina_Bool
6580 _elm_genlist_item_expanded_get(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it)
6582 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
6584 return GL_IT(it)->expanded;
6588 _elm_genlist_item_expanded_depth_get(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it)
6590 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, 0);
6592 return GL_IT(it)->expanded_depth;
6596 _elm_genlist_item_coordinates_calc(Elm_Gen_Item *it,
6597 Elm_Genlist_Item_Scrollto_Type type,
6604 Evas_Coord gith = 0;
6605 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
6608 (!((sd->homogeneous) &&
6609 (sd->mode == ELM_LIST_COMPRESS))))
6611 if ((it->item->queued) || (!it->item->mincalcd) || (sd->queue))
6614 sd->bring_in = bring_in;
6615 sd->scroll_to_type = type;
6616 it->item->show_me = EINA_TRUE;
6622 sd->show_item->item->show_me = EINA_FALSE;
6623 sd->show_item = NULL;
6626 evas_object_geometry_get(sd->pan_obj, NULL, NULL, w, h);
6629 case ELM_GENLIST_ITEM_SCROLLTO_IN:
6630 if ((it->item->group_item) &&
6631 (sd->pan_y > (it->y + it->item->block->y)))
6632 gith = it->item->group_item->item->h;
6634 *y = it->y + it->item->block->y - gith;
6637 case ELM_GENLIST_ITEM_SCROLLTO_TOP:
6638 if (it->item->group_item) gith = it->item->group_item->item->h;
6639 *y = it->y + it->item->block->y - gith;
6642 case ELM_GENLIST_ITEM_SCROLLTO_MIDDLE:
6643 *y = it->y + it->item->block->y - (*h / 2) + (it->item->h / 2);
6650 *x = it->x + it->item->block->x;
6651 *w = it->item->block->w;
6657 _elm_genlist_item_promote(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
6659 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
6661 Elm_Object_Item *eo_first_item = elm_genlist_first_item_get(WIDGET(it));
6662 ELM_GENLIST_ITEM_DATA_GET(eo_first_item, first_item);
6663 _item_move_before(it, first_item);
6667 _elm_genlist_item_demote(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
6669 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
6670 Elm_Object_Item *eo_last_item = elm_genlist_last_item_get(WIDGET(it));
6671 ELM_GENLIST_ITEM_DATA_GET(eo_last_item, last_item);
6672 _item_move_after(it, last_item);
6676 _elm_genlist_item_show(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *item, Elm_Genlist_Item_Scrollto_Type type)
6678 Evas_Coord x, y, w, h;
6680 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
6682 if (_elm_genlist_item_coordinates_calc
6683 (item, type, EINA_FALSE, &x, &y, &w, &h))
6684 eo_do(WIDGET(item), elm_interface_scrollable_content_region_show
6689 _elm_genlist_item_bring_in(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *item, Elm_Genlist_Item_Scrollto_Type type)
6691 Evas_Coord x, y, w, h;
6693 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
6695 if (_elm_genlist_item_coordinates_calc
6696 (item, type, EINA_TRUE, &x, &y, &w, &h))
6697 eo_do(WIDGET(item), elm_interface_scrollable_region_bring_in(x, y, w, h));
6701 _elm_genlist_item_all_contents_unset(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it, Eina_List **l)
6703 Evas_Object *content;
6705 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
6707 EINA_LIST_FREE(it->contents, content)
6709 elm_widget_sub_object_del(WIDGET(it), content);
6710 edje_object_part_unswallow(VIEW(it), content);
6711 evas_object_hide(content);
6712 if (l) *l = eina_list_append(*l, content);
6717 _elm_genlist_item_update(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it)
6719 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
6720 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
6722 if (!it->item->block) return;
6723 it->item->mincalcd = EINA_FALSE;
6724 it->item->updateme = EINA_TRUE;
6725 it->item->block->updateme = EINA_TRUE;
6726 ecore_job_del(sd->update_job);
6727 sd->update_job = ecore_job_add(_update_job, sd->obj);
6731 _elm_genlist_item_fields_update(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it,
6733 Elm_Genlist_Item_Field_Type itf)
6735 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
6737 if (!it->item->block) return;
6739 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_TEXT))
6741 _item_text_realize(it, VIEW(it), &it->texts, parts);
6743 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_CONTENT))
6745 _item_content_realize(it, VIEW(it), &it->contents, "contents", parts);
6748 _item_content_realize(it, VIEW(it), &GL_IT(it)->flip_contents,
6751 if (GL_IT(it)->deco_it_view)
6753 _item_content_realize(it, GL_IT(it)->deco_it_view,
6754 &GL_IT(it)->deco_it_contents,
6757 if (GL_IT(it)->wsd->decorate_all_mode)
6759 _item_content_realize(it, it->deco_all_view,
6760 &GL_IT(it)->deco_all_contents,
6763 if (it->has_contents != (!!it->contents))
6764 it->item->mincalcd = EINA_FALSE;
6765 it->has_contents = !!it->contents;
6766 if (it->item->type == ELM_GENLIST_ITEM_NONE)
6770 it->item_focus_chain = eina_list_free(it->item_focus_chain);
6771 EINA_LIST_FOREACH(it->contents, l, eobj)
6772 if (elm_widget_is(eobj) && elm_object_focus_allow_get(eobj))
6773 it->item_focus_chain = eina_list_append(it->item_focus_chain, eobj);
6777 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_STATE))
6778 _item_state_realize(it, VIEW(it), parts);
6780 if (!it->item->mincalcd)
6781 elm_genlist_item_update(eo_item);
6785 _elm_genlist_item_item_class_update(Eo *eo_it, Elm_Gen_Item *it,
6786 const Elm_Genlist_Item_Class *itc)
6788 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
6789 EINA_SAFETY_ON_NULL_RETURN(itc);
6791 if (!it->item->block) return;
6792 it->item->nocache_once = EINA_TRUE;
6794 ELM_SAFE_FREE(it->texts, elm_widget_stringlist_free);
6795 ELM_SAFE_FREE(GL_IT(it)->deco_it_texts, elm_widget_stringlist_free);
6796 ELM_SAFE_FREE(GL_IT(it)->deco_all_texts, elm_widget_stringlist_free);
6798 elm_genlist_item_update(eo_it);
6801 EOLIAN static const Elm_Genlist_Item_Class *
6802 _elm_genlist_item_item_class_get(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it)
6804 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, NULL);
6809 static Evas_Object *
6810 _elm_genlist_item_label_create(void *data,
6811 Evas_Object *obj EINA_UNUSED,
6812 Evas_Object *tooltip,
6813 void *it EINA_UNUSED)
6815 Evas_Object *label = elm_label_add(tooltip);
6820 elm_object_style_set(label, "tooltip");
6821 elm_object_text_set(label, data);
6827 _elm_genlist_item_label_del_cb(void *data,
6828 Evas_Object *obj EINA_UNUSED,
6829 void *event_info EINA_UNUSED)
6831 eina_stringshare_del(data);
6835 elm_genlist_item_tooltip_text_set(Elm_Object_Item *it,
6838 eo_do(it, elm_wdg_item_tooltip_text_set(text));
6842 _elm_genlist_item_elm_widget_item_tooltip_text_set(Eo *eo_it, Elm_Gen_Item *it, const char *text)
6844 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
6846 text = eina_stringshare_add(text);
6847 elm_genlist_item_tooltip_content_cb_set
6848 (eo_it, _elm_genlist_item_label_create, text,
6849 _elm_genlist_item_label_del_cb);
6853 elm_genlist_item_tooltip_content_cb_set(Elm_Object_Item *item,
6854 Elm_Tooltip_Item_Content_Cb func,
6856 Evas_Smart_Cb del_cb)
6858 eo_do(item, elm_wdg_item_tooltip_content_cb_set(func, data, del_cb));
6862 _elm_genlist_item_elm_widget_item_tooltip_content_cb_set(Eo *eo_it, Elm_Gen_Item *it,
6863 Elm_Tooltip_Item_Content_Cb func,
6865 Evas_Smart_Cb del_cb)
6867 ELM_GENLIST_ITEM_CHECK_OR_GOTO(it, error);
6869 if ((it->tooltip.content_cb != func) || (it->tooltip.data != data))
6871 if (it->tooltip.del_cb)
6872 it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
6874 it->tooltip.content_cb = func;
6875 it->tooltip.data = data;
6876 it->tooltip.del_cb = del_cb;
6881 eo_do_super(eo_it, ELM_GENLIST_ITEM_CLASS,
6882 elm_wdg_item_tooltip_content_cb_set
6883 (it->tooltip.content_cb, it->tooltip.data, NULL));
6885 elm_wdg_item_tooltip_style_set(it->tooltip.style),
6886 elm_wdg_item_tooltip_window_mode_set(it->tooltip.free_size));
6892 if (del_cb) del_cb((void *)data, NULL, NULL);
6896 elm_genlist_item_tooltip_unset(Elm_Object_Item *item)
6898 eo_do(item, elm_wdg_item_tooltip_unset());
6902 _elm_genlist_item_elm_widget_item_tooltip_unset(Eo *eo_it, Elm_Gen_Item *it)
6904 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
6906 if ((VIEW(it)) && (it->tooltip.content_cb))
6907 eo_do_super(eo_it, ELM_GENLIST_ITEM_CLASS,
6908 elm_wdg_item_tooltip_unset());
6910 if (it->tooltip.del_cb)
6911 it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
6912 it->tooltip.del_cb = NULL;
6913 it->tooltip.content_cb = NULL;
6914 it->tooltip.data = NULL;
6915 it->tooltip.free_size = EINA_FALSE;
6916 if (it->tooltip.style)
6917 eo_do(eo_it, elm_wdg_item_tooltip_style_set(NULL));
6921 elm_genlist_item_tooltip_style_set(Elm_Object_Item *item,
6924 eo_do(item, elm_wdg_item_tooltip_style_set(style));
6928 _elm_genlist_item_elm_widget_item_tooltip_style_set(Eo *eo_it, Elm_Gen_Item *it,
6931 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
6933 eina_stringshare_replace(&it->tooltip.style, style);
6934 if (VIEW(it)) eo_do_super(eo_it, ELM_GENLIST_ITEM_CLASS,
6935 elm_wdg_item_tooltip_style_set(style));
6939 elm_genlist_item_tooltip_style_get(const Elm_Object_Item *it)
6941 return eo_do(it, elm_wdg_item_tooltip_style_get());
6945 elm_genlist_item_tooltip_window_mode_set(Elm_Object_Item *item,
6948 return eo_do(item, elm_wdg_item_tooltip_window_mode_set(disable));
6951 EOLIAN static Eina_Bool
6952 _elm_genlist_item_elm_widget_item_tooltip_window_mode_set(Eo *eo_it, Elm_Gen_Item *it,
6955 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
6957 it->tooltip.free_size = disable;
6959 return eo_do_super(eo_it, ELM_GENLIST_ITEM_CLASS,
6960 elm_wdg_item_tooltip_window_mode_set(disable));
6966 elm_genlist_item_tooltip_window_mode_get(const Elm_Object_Item *eo_it)
6968 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
6969 return eo_do(VIEW(it), elm_wdg_item_tooltip_window_mode_get());
6973 elm_genlist_item_cursor_set(Elm_Object_Item *item,
6976 eo_do(item, elm_wdg_item_cursor_set(cursor));
6980 _elm_genlist_item_elm_widget_item_cursor_set(Eo *eo_it, Elm_Gen_Item *it,
6983 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
6984 eina_stringshare_replace(&it->mouse_cursor, cursor);
6985 if (VIEW(it)) eo_do_super(eo_it, ELM_GENLIST_ITEM_CLASS,
6986 elm_wdg_item_cursor_set(cursor));
6990 elm_genlist_item_cursor_get(const Elm_Object_Item *eo_it)
6992 return eo_do(eo_it, elm_wdg_item_cursor_get());
6996 elm_genlist_item_cursor_unset(Elm_Object_Item *item)
6998 eo_do(item, elm_wdg_item_cursor_unset());
7002 _elm_genlist_item_elm_widget_item_cursor_unset(Eo *eo_it, Elm_Gen_Item *it)
7004 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7006 if (!it->mouse_cursor) return;
7008 if (VIEW(it)) eo_do_super(eo_it, ELM_GENLIST_ITEM_CLASS,
7009 elm_wdg_item_cursor_unset());
7011 ELM_SAFE_FREE(it->mouse_cursor, eina_stringshare_del);
7015 elm_genlist_item_cursor_style_set(Elm_Object_Item *eo_it,
7018 eo_do(eo_it, elm_wdg_item_cursor_style_set(style));
7022 elm_genlist_item_cursor_style_get(const Elm_Object_Item *eo_it)
7024 return eo_do( eo_it, elm_wdg_item_cursor_style_get());
7028 elm_genlist_item_cursor_engine_only_set(Elm_Object_Item *eo_it,
7029 Eina_Bool engine_only)
7031 eo_do(eo_it, elm_wdg_item_cursor_engine_only_set(engine_only));
7035 elm_genlist_item_cursor_engine_only_get(const Elm_Object_Item *eo_it)
7037 return eo_do( eo_it, elm_wdg_item_cursor_engine_only_get());
7041 _elm_genlist_item_index_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
7045 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, -1);
7047 EINA_INLIST_FOREACH(GL_IT(it)->wsd->items, tmp)
7049 if (tmp == it) break;
7056 _elm_genlist_mode_set(Eo *obj, Elm_Genlist_Data *sd, Elm_List_Mode mode)
7058 if (sd->mode == mode) return;
7060 elm_layout_sizing_eval(obj);
7063 EOLIAN static Elm_List_Mode
7064 _elm_genlist_mode_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
7070 elm_genlist_bounce_set(Evas_Object *obj,
7074 ELM_GENLIST_CHECK(obj);
7075 eo_do(obj, elm_interface_scrollable_bounce_allow_set(h_bounce, v_bounce));
7079 _elm_genlist_elm_interface_scrollable_bounce_allow_set(Eo *obj, Elm_Genlist_Data *sd, Eina_Bool h_bounce, Eina_Bool v_bounce)
7081 sd->h_bounce = !!h_bounce;
7082 sd->v_bounce = !!v_bounce;
7083 eo_do_super(obj, MY_CLASS, elm_interface_scrollable_bounce_allow_set
7084 (sd->h_bounce, sd->v_bounce));
7088 elm_genlist_bounce_get(const Evas_Object *obj,
7089 Eina_Bool *h_bounce,
7090 Eina_Bool *v_bounce)
7092 ELM_GENLIST_CHECK(obj);
7093 eo_do( obj, elm_interface_scrollable_bounce_allow_get
7094 (h_bounce, v_bounce));
7098 _elm_genlist_elm_interface_scrollable_bounce_allow_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool *h_bounce, Eina_Bool *v_bounce)
7100 if (h_bounce) *h_bounce = sd->h_bounce;
7101 if (v_bounce) *v_bounce = sd->v_bounce;
7105 _elm_genlist_homogeneous_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool homogeneous)
7107 sd->homogeneous = !!homogeneous;
7110 EOLIAN static Eina_Bool
7111 _elm_genlist_homogeneous_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
7113 return sd->homogeneous;
7117 _elm_genlist_block_count_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, int count)
7119 EINA_SAFETY_ON_TRUE_RETURN(count < 1);
7121 sd->max_items_per_block = count;
7122 sd->item_cache_max = sd->max_items_per_block * 2;
7123 _item_cache_clean(sd);
7127 _elm_genlist_block_count_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
7129 return sd->max_items_per_block;
7133 _elm_genlist_longpress_timeout_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, double timeout)
7135 sd->longpress_timeout = timeout;
7138 EOLIAN static double
7139 _elm_genlist_longpress_timeout_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
7141 return sd->longpress_timeout;
7145 elm_genlist_scroller_policy_set(Evas_Object *obj,
7146 Elm_Scroller_Policy policy_h,
7147 Elm_Scroller_Policy policy_v)
7149 ELM_GENLIST_CHECK(obj);
7150 eo_do(obj, elm_interface_scrollable_policy_set(policy_h, policy_v));
7154 _elm_genlist_elm_interface_scrollable_policy_set(Eo *obj, Elm_Genlist_Data *sd EINA_UNUSED, Elm_Scroller_Policy policy_h, Elm_Scroller_Policy policy_v)
7156 if ((policy_h >= ELM_SCROLLER_POLICY_LAST) ||
7157 (policy_v >= ELM_SCROLLER_POLICY_LAST))
7160 eo_do_super(obj, MY_CLASS, elm_interface_scrollable_policy_set(policy_h, policy_v));
7164 elm_genlist_scroller_policy_get(const Evas_Object *obj,
7165 Elm_Scroller_Policy *policy_h,
7166 Elm_Scroller_Policy *policy_v)
7168 ELM_GENLIST_CHECK(obj);
7169 eo_do( obj, elm_interface_scrollable_policy_get(policy_h, policy_v));
7173 _elm_genlist_elm_interface_scrollable_policy_get(Eo *obj, Elm_Genlist_Data *sd EINA_UNUSED, Elm_Scroller_Policy *policy_h, Elm_Scroller_Policy *policy_v)
7175 Elm_Scroller_Policy s_policy_h, s_policy_v;
7177 eo_do_super(obj, MY_CLASS, elm_interface_scrollable_policy_get
7178 (&s_policy_h, &s_policy_v));
7179 if (policy_h) *policy_h = (Elm_Scroller_Policy)s_policy_h;
7180 if (policy_v) *policy_v = (Elm_Scroller_Policy)s_policy_v;
7184 _elm_genlist_realized_items_update(Eo *obj, Elm_Genlist_Data *_pd EINA_UNUSED)
7187 Elm_Object_Item *it;
7189 list = elm_genlist_realized_items_get(obj);
7190 EINA_LIST_FREE(list, it)
7191 elm_genlist_item_update(it);
7195 _elm_genlist_item_decorate_mode_set(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it,
7196 const char *decorate_it_type,
7197 Eina_Bool decorate_it_set)
7199 Elm_Genlist_Data *sd;
7201 Elm_Object_Item *eo_it2 = NULL;
7203 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7204 sd = GL_IT(it)->wsd;
7206 if (!decorate_it_type) return;
7207 if (eo_do(eo_it, elm_wdg_item_disabled_get())) return;
7208 if (sd->decorate_all_mode) return;
7210 if ((sd->mode_item == it) &&
7211 (!strcmp(decorate_it_type, sd->decorate_it_type)) &&
7214 if (!it->itc->decorate_item_style) return;
7215 it->decorate_it_set = decorate_it_set;
7219 EINA_LIST_FOREACH(sd->selected, l, eo_it2)
7221 ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
7223 elm_genlist_item_selected_set(eo_it2, EINA_FALSE);
7228 Elm_Gen_Item *it2 = NULL;
7229 eo_it2 = elm_genlist_selected_item_get(sd->obj);
7230 if (eo_it2) it2 = eo_data_scope_get(eo_it2, ELM_GENLIST_ITEM_CLASS);
7231 if (it2 && it2->realized)
7232 elm_genlist_item_selected_set(eo_it2, EINA_FALSE);
7235 if (((sd->decorate_it_type)
7236 && (strcmp(decorate_it_type, sd->decorate_it_type))) ||
7237 (decorate_it_set) || ((it == sd->mode_item) && (!decorate_it_set)))
7238 _decorate_item_unset(sd);
7240 eina_stringshare_replace(&sd->decorate_it_type, decorate_it_type);
7241 if (decorate_it_set) _decorate_item_set(it);
7244 EOLIAN static const char *
7245 _elm_genlist_item_decorate_mode_get(Eo *eo_i EINA_UNUSED, Elm_Gen_Item *i)
7247 ELM_GENLIST_ITEM_CHECK_OR_RETURN(i, NULL);
7248 return GL_IT(i)->wsd->decorate_it_type;
7251 EOLIAN static Elm_Object_Item *
7252 _elm_genlist_decorated_item_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
7254 return EO_OBJ(sd->mode_item);
7257 EOLIAN static Eina_Bool
7258 _elm_genlist_decorate_mode_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
7260 return sd->decorate_all_mode;
7264 _elm_genlist_decorate_mode_set(Eo *obj, Elm_Genlist_Data *sd, Eina_Bool decorated)
7266 Elm_Object_Item *eo_it;
7268 Elm_Object_Item *deco_it;
7270 decorated = !!decorated;
7271 if (sd->decorate_all_mode == decorated) return;
7272 // decorate_all_mode should be set first
7273 // because content_get func. will be called after this
7274 // and user can check whether decorate_all_mode_ is enabled.
7275 sd->decorate_all_mode = decorated;
7277 ELM_SAFE_FREE(sd->tree_effect_animator, ecore_animator_del);
7278 sd->move_effect_mode = ELM_GENLIST_TREE_EFFECT_NONE;
7280 list = elm_genlist_realized_items_get(obj);
7281 if (!sd->decorate_all_mode)
7283 EINA_LIST_FREE(list, eo_it)
7285 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
7286 if (it->item->type != ELM_GENLIST_ITEM_GROUP)
7287 _decorate_all_item_unrealize(it);
7289 _item_cache_zero(sd);
7293 // unset decorated item
7294 deco_it = elm_genlist_decorated_item_get(obj);
7297 elm_genlist_item_decorate_mode_set
7298 (deco_it, elm_genlist_item_decorate_mode_get
7299 (deco_it), EINA_FALSE);
7300 _decorate_item_finished_signal_cb(deco_it, obj, NULL, NULL);
7303 EINA_LIST_FREE(list, eo_it)
7305 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
7306 if (it->item->type != ELM_GENLIST_ITEM_GROUP)
7308 if (it->itc->decorate_all_item_style)
7309 _decorate_all_item_realize(it, EINA_TRUE);
7314 ecore_job_del(sd->calc_job);
7315 sd->calc_job = ecore_job_add(_calc_job, sd->obj);
7319 _elm_genlist_reorder_mode_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool reorder_mode)
7321 Eina_List *realized;
7322 Elm_Object_Item *eo_it;
7324 if (sd->reorder_mode == !!reorder_mode) return;
7325 sd->reorder_mode = !!reorder_mode;
7326 realized = elm_genlist_realized_items_get(obj);
7327 EINA_LIST_FREE(realized, eo_it)
7329 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
7330 if (sd->reorder_mode)
7332 edje_object_signal_emit(VIEW(it), SIGNAL_REORDER_MODE_SET, "elm");
7333 if (it->deco_all_view)
7335 edje_object_signal_emit(it->deco_all_view,
7336 SIGNAL_REORDER_MODE_SET, "elm");
7341 edje_object_signal_emit(VIEW(it), SIGNAL_REORDER_MODE_UNSET, "elm");
7342 if (it->deco_all_view)
7344 edje_object_signal_emit(it->deco_all_view,
7345 SIGNAL_REORDER_MODE_UNSET, "elm");
7351 EOLIAN static Eina_Bool
7352 _elm_genlist_reorder_mode_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
7354 return sd->reorder_mode;
7357 EOLIAN static Elm_Genlist_Item_Type
7358 _elm_genlist_item_type_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
7360 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, ELM_GENLIST_ITEM_MAX);
7362 return GL_IT(it)->type;
7365 EAPI Elm_Genlist_Item_Class *
7366 elm_genlist_item_class_new(void)
7368 Elm_Genlist_Item_Class *itc = ELM_NEW(Elm_Genlist_Item_Class);
7369 EINA_SAFETY_ON_NULL_RETURN_VAL(itc, NULL);
7371 itc->version = CLASS_ALLOCATED;
7373 itc->delete_me = EINA_FALSE;
7379 elm_genlist_item_class_free(Elm_Genlist_Item_Class *itc)
7381 if (itc && (itc->version == CLASS_ALLOCATED))
7383 if (!itc->delete_me) itc->delete_me = EINA_TRUE;
7384 if (itc->refcount > 0) elm_genlist_item_class_unref(itc);
7394 elm_genlist_item_class_ref(Elm_Genlist_Item_Class *itc)
7396 if (itc && (itc->version == CLASS_ALLOCATED))
7399 if (itc->refcount == 0) itc->refcount--;
7404 elm_genlist_item_class_unref(Elm_Genlist_Item_Class *itc)
7406 if (itc && (itc->version == CLASS_ALLOCATED))
7408 if (itc->refcount > 0) itc->refcount--;
7409 if (itc->delete_me && (!itc->refcount))
7410 elm_genlist_item_class_free(itc);
7415 _flip_job(void *data)
7417 Elm_Gen_Item *it = (Elm_Gen_Item *)data;
7418 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
7421 _elm_genlist_item_unrealize(it, EINA_FALSE);
7423 it->flipped = EINA_TRUE;
7424 it->item->nocache = EINA_TRUE;
7425 ecore_job_del(sd->calc_job);
7426 sd->calc_job = ecore_job_add(_calc_job, sd->obj);
7430 _elm_genlist_item_flip_set(Eo *eo_it, Elm_Gen_Item *it, Eina_Bool flip)
7432 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7435 if (it->flipped == flip) return;
7439 ecore_job_add(_flip_job, it);
7443 edje_object_signal_emit(VIEW(it), SIGNAL_FLIP_DISABLED, "elm");
7444 if (GL_IT(it)->wsd->decorate_all_mode)
7445 edje_object_signal_emit(it->deco_all_view, SIGNAL_FLIP_DISABLED,
7449 _item_cache_zero(GL_IT(it)->wsd);
7450 elm_genlist_item_update(eo_it);
7451 it->item->nocache = EINA_FALSE;
7455 EOLIAN static Eina_Bool
7456 _elm_genlist_item_flip_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
7458 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
7464 _elm_genlist_select_mode_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Elm_Object_Select_Mode mode)
7466 if ((mode >= ELM_OBJECT_SELECT_MODE_MAX) || (sd->select_mode == mode))
7469 sd->select_mode = mode;
7471 if ((sd->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
7472 (sd->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
7476 EINA_LIST_FOREACH_SAFE(sd->selected, l, ll, it)
7481 EOLIAN static Elm_Object_Select_Mode
7482 _elm_genlist_select_mode_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
7484 return sd->select_mode;
7488 _elm_genlist_highlight_mode_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool highlight)
7490 sd->highlight = !!highlight;
7493 EOLIAN static Eina_Bool
7494 _elm_genlist_highlight_mode_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
7496 return sd->highlight;
7500 _elm_genlist_item_select_mode_set(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it,
7501 Elm_Object_Select_Mode mode)
7503 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7504 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
7506 if ((mode >= ELM_OBJECT_SELECT_MODE_MAX) || (it->select_mode == mode))
7509 it->select_mode = mode;
7511 if ((it->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
7512 (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
7515 if (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
7517 it->item->mincalcd = EINA_FALSE;
7518 it->item->updateme = EINA_TRUE;
7519 if (it->item->block) it->item->block->updateme = EINA_TRUE;
7520 ecore_job_del(sd->update_job);
7521 sd->update_job = ecore_job_add(_update_job, sd->obj);
7523 // reset homogeneous item size
7524 if (sd->homogeneous)
7526 if (GL_IT(it)->type & ELM_GENLIST_ITEM_GROUP)
7527 sd->group_item_width = sd->group_item_height = 0;
7529 sd->item_width = sd->item_height = 0;
7534 EOLIAN static Elm_Object_Select_Mode
7535 _elm_genlist_item_select_mode_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
7537 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, ELM_OBJECT_SELECT_MODE_MAX);
7539 return it->select_mode;
7543 _elm_genlist_tree_effect_enabled_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool enabled)
7545 sd->tree_effect_enabled = !!enabled;
7548 EOLIAN static Eina_Bool
7549 _elm_genlist_tree_effect_enabled_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
7551 return sd->tree_effect_enabled;
7555 _elm_genlist_focus_on_selection_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool enabled)
7557 sd->focus_on_selection_enabled = !!enabled;
7560 EOLIAN static Eina_Bool
7561 _elm_genlist_focus_on_selection_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
7563 return sd->focus_on_selection_enabled;
7566 EAPI Elm_Object_Item *
7567 elm_genlist_nth_item_get(const Evas_Object *obj, unsigned int nth)
7569 Elm_Gen_Item *it = NULL;
7573 ELM_GENLIST_CHECK(obj) NULL;
7574 ELM_GENLIST_DATA_GET(obj, sd);
7576 if (!sd->items) return NULL;
7578 a = eina_inlist_accessor_new(sd->items);
7579 if (!a) return NULL;
7580 if (eina_accessor_data_get(a, nth, &data))
7581 it = ELM_GEN_ITEM_FROM_INLIST(data);
7582 eina_accessor_free(a);
7587 _elm_genlist_elm_widget_focus_highlight_geometry_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h)
7589 Evas_Coord ox, oy, oh, ow, item_x = 0, item_y = 0, item_w = 0, item_h = 0;
7591 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
7593 if (sd->focused_item)
7595 ELM_GENLIST_ITEM_DATA_GET(sd->focused_item, focus_it);
7596 evas_object_geometry_get(VIEW(focus_it), &item_x, &item_y, &item_w, &item_h);
7597 elm_widget_focus_highlight_focus_part_geometry_get(VIEW(focus_it), &item_x, &item_y, &item_w, &item_h);
7609 if (item_y > (oy + oh - item_h))
7611 *y = oy + oh - item_h;
7614 if ((item_x + item_w) > (ox + ow))
7624 EOLIAN static Elm_Object_Item *
7625 _elm_genlist_search_by_text_item_get(Eo *obj EINA_UNUSED,
7626 Elm_Genlist_Data *sd,
7627 Elm_Object_Item *item_to_search_from,
7628 const char *part_name,
7629 const char *pattern,
7630 Elm_Glob_Match_Flags flags)
7632 Elm_Gen_Item *it = NULL;
7634 Eina_Inlist *start = NULL;
7637 if (!pattern) return NULL;
7638 if (!sd->items) return NULL;
7640 if (flags & ELM_GLOB_MATCH_NO_ESCAPE) fnflags |= FNM_NOESCAPE;
7641 if (flags & ELM_GLOB_MATCH_PATH) fnflags |= FNM_PATHNAME;
7642 if (flags & ELM_GLOB_MATCH_PERIOD) fnflags |= FNM_PERIOD;
7644 if (flags & ELM_GLOB_MATCH_NOCASE) fnflags |= FNM_CASEFOLD;
7647 start = (item_to_search_from) ?
7648 EINA_INLIST_GET((Elm_Gen_Item *)eo_data_scope_get(item_to_search_from, ELM_GENLIST_ITEM_CLASS)) :
7650 EINA_INLIST_FOREACH(start, it)
7652 if (!it->itc->func.text_get) continue;
7653 str = it->itc->func.text_get((void *)WIDGET_ITEM_DATA_GET(EO_OBJ(it)), WIDGET(it), part_name);
7655 if (!fnmatch(pattern, str, fnflags))
7665 EOLIAN static Elm_Object_Item*
7666 _elm_genlist_elm_widget_focused_item_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
7668 return sd->focused_item;
7672 _elm_genlist_elm_widget_item_loop_enabled_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool enable)
7674 if (enable == EINA_TRUE)
7676 _elm_widget_focus_highlight_signal_callback_add(obj, "elm,focus,move,down,end",
7677 "elm", _elm_genlist_focus_highlight_move_down_end_cb, obj);
7678 _elm_widget_focus_highlight_signal_callback_add(obj, "elm,focus,move,up,end",
7679 "elm", _elm_genlist_focus_highlight_move_up_end_cb, obj);
7683 _elm_widget_focus_highlight_signal_callback_del(obj, "elm,focus,move,down,end",
7684 "elm", _elm_genlist_focus_highlight_move_down_end_cb);
7685 _elm_widget_focus_highlight_signal_callback_del(obj, "elm,focus,move,up,end",
7686 "elm", _elm_genlist_focus_highlight_move_up_end_cb);
7689 sd->item_loop_enable = !!enable;
7692 EOLIAN static Eina_Bool
7693 _elm_genlist_elm_widget_item_loop_enabled_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
7695 return sd->item_loop_enable;
7699 _elm_genlist_class_constructor(Eo_Class *klass)
7701 if (_elm_config->access_mode)
7702 _elm_genlist_smart_focus_next_enable = EINA_TRUE;
7704 evas_smart_legacy_type_register(MY_CLASS_NAME_LEGACY, klass);
7707 EOLIAN const Elm_Atspi_Action *
7708 _elm_genlist_elm_interface_atspi_widget_action_elm_actions_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *pd EINA_UNUSED)
7710 static Elm_Atspi_Action atspi_actions[] = {
7711 { "move,prior", "move", "prior", _key_action_move},
7712 { "move,next", "move", "next", _key_action_move},
7713 { "move,left", "move", "left", _key_action_move},
7714 { "move,right", "move", "right", _key_action_move},
7715 { "move,up", "move", "up", _key_action_move},
7716 { "move,up,multi", "move", "up_multi", _key_action_move},
7717 { "move,down", "move", "down", _key_action_move},
7718 { "move,down,multi", "move", "down_multi", _key_action_move},
7719 { "move,first", "move", "first", _key_action_move},
7720 { "move,last", "move", "last", _key_action_move},
7721 { "select", "select", NULL, _key_action_select},
7722 { "select,multi", "select", "multi", _key_action_select},
7723 { "escape", "escape", NULL, _key_action_escape},
7724 { NULL, NULL, NULL, NULL }
7726 return &atspi_actions[0];
7729 #include "elm_genlist.eo.c"
7730 #include "elm_genlist_item.eo.c"