1 #include <Elementary.h>
2 #include <Elementary_Cursor.h>
4 #include "elm_widget_gengrid.h"
6 // internally allocated
7 #define CLASS_ALLOCATED 0x3a70f00f
11 * Handle non-homogeneous objects too.
15 #define REORDER_EFFECT_TIME 0.5
16 #define FX_MOVE_TIME 0.5
17 #define ITEM_HIGHLIGHT_TIMER 0.1
18 #define ITEM_SELECT_TIMER 0.01 // This is needed for highlight effect when item is unhighlighted right after item is highlighted and selected
28 EAPI const char ELM_GENGRID_SMART_NAME[] = "elm_gengrid";
29 EAPI const char ELM_GENGRID_PAN_SMART_NAME[] = "elm_gengrid_pan";
31 #define GG_IT(_it) (_it->item)
33 static const Evas_Smart_Interface *_smart_interfaces[] =
35 (Evas_Smart_Interface *)&ELM_SCROLLABLE_IFACE, NULL
38 static const char SIG_ACTIVATED[] = "activated";
39 static const char SIG_CLICKED_DOUBLE[] = "clicked,double";
40 static const char SIG_LONGPRESSED[] = "longpressed";
41 static const char SIG_SELECTED[] = "selected";
42 static const char SIG_UNSELECTED[] = "unselected";
43 static const char SIG_REALIZED[] = "realized";
44 static const char SIG_UNREALIZED[] = "unrealized";
45 static const char SIG_CHANGED[] = "changed";
46 static const char SIG_DRAG_START_UP[] = "drag,start,up";
47 static const char SIG_DRAG_START_DOWN[] = "drag,start,down";
48 static const char SIG_DRAG_START_LEFT[] = "drag,start,left";
49 static const char SIG_DRAG_START_RIGHT[] = "drag,start,right";
50 static const char SIG_DRAG_STOP[] = "drag,stop";
51 static const char SIG_DRAG[] = "drag";
52 static const char SIG_SCROLL[] = "scroll";
53 static const char SIG_SCROLL_ANIM_START[] = "scroll,anim,start";
54 static const char SIG_SCROLL_ANIM_STOP[] = "scroll,anim,stop";
55 static const char SIG_SCROLL_DRAG_START[] = "scroll,drag,start";
56 static const char SIG_SCROLL_DRAG_STOP[] = "scroll,drag,stop";
57 static const char SIG_EDGE_TOP[] = "edge,top";
58 static const char SIG_EDGE_BOTTOM[] = "edge,bottom";
59 static const char SIG_EDGE_LEFT[] = "edge,left";
60 static const char SIG_EDGE_RIGHT[] = "edge,right";
61 static const char SIG_MOVED[] = "moved";
62 static const char SIG_INDEX_UPDATE[] = "index,update";
63 static const char SIG_HIGHLIGHTED[] = "highlighted";
64 static const char SIG_UNHIGHLIGHTED[] = "unhighlighted";
65 static const char SIG_LANG_CHANGED[] = "language,changed";
66 static const char SIG_PRESSED[] = "pressed";
67 static const char SIG_RELEASED[] = "released";
68 static const char SIG_ITEM_FOCUSED[] = "item,focused";
69 static const char SIG_ITEM_UNFOCUSED[] = "item,unfocused";
71 static const Evas_Smart_Cb_Description _smart_callbacks[] = {
73 {SIG_CLICKED_DOUBLE, ""},
74 {SIG_LONGPRESSED, ""},
80 {SIG_DRAG_START_UP, ""},
81 {SIG_DRAG_START_DOWN, ""},
82 {SIG_DRAG_START_LEFT, ""},
83 {SIG_DRAG_START_RIGHT, ""},
87 {SIG_SCROLL_ANIM_START, ""},
88 {SIG_SCROLL_ANIM_STOP, ""},
89 {SIG_SCROLL_DRAG_START, ""},
90 {SIG_SCROLL_DRAG_STOP, ""},
92 {SIG_EDGE_BOTTOM, ""},
96 {SIG_HIGHLIGHTED, ""},
97 {SIG_UNHIGHLIGHTED, ""},
98 {SIG_LANG_CHANGED, ""},
101 {SIG_ITEM_FOCUSED, ""},
102 {SIG_ITEM_UNFOCUSED, ""},
106 EVAS_SMART_SUBCLASS_IFACE_NEW
107 (ELM_GENGRID_SMART_NAME, _elm_gengrid, Elm_Gengrid_Smart_Class,
108 Elm_Layout_Smart_Class, elm_layout_smart_class_get, _smart_callbacks,
111 ELM_INTERNAL_SMART_SUBCLASS_NEW
112 (ELM_GENGRID_PAN_SMART_NAME, _elm_gengrid_pan, Elm_Gengrid_Pan_Smart_Class,
113 Elm_Pan_Smart_Class, elm_pan_smart_class_get, NULL);
115 #if GENGRID_FX_SUPPORT
116 static Eina_Bool _elm_gengrid_fx_capture(Evas_Object *obj, int level);
117 static void _elm_gengrid_fx_play(Evas_Object *obj);
120 static void _gengrid_item_unfocused(Elm_Gen_Item *it);
122 _elm_gengrid_pan_smart_pos_max_get(const Evas_Object *obj,
126 _elm_gengrid_pan_smart_pos_min_get(const Evas_Object *obj,
130 _view_theme_update(Elm_Gen_Item *it);
133 _item_mouse_down_cb(void *data,
138 _item_mouse_up_cb(void *data,
140 Evas_Object *obj __UNUSED__,
144 _item_mouse_move_cb(void *data,
145 Evas *evas __UNUSED__,
150 _item_select(Elm_Gen_Item *it);
153 _item_unselect(Elm_Gen_Item *it);
156 _elm_gengrid_smart_translate(Evas_Object *obj)
158 evas_object_smart_callback_call(obj, SIG_LANG_CHANGED, NULL);
164 _item_show_region(void *data)
166 Elm_Gengrid_Smart_Data *sd = data;
167 Evas_Coord cvw, cvh, it_xpos = 0, it_ypos = 0, col = 0, row = 0, minx = 0, miny = 0;
168 Evas_Coord vw = 0, vh = 0;
169 Elm_Gen_Item *it = NULL;
171 #if GENGRID_FX_SUPPORT
172 if (sd->fx_first_captured) return;
174 evas_object_geometry_get(sd->pan_obj, NULL, NULL, &cvw, &cvh);
176 if ((cvw != 0) && (cvh != 0))
181 else if (sd->bring_in)
182 it = sd->bring_in_it;
184 _elm_gengrid_pan_smart_pos_min_get(sd->pan_obj, &minx, &miny);
186 if (sd->horizontal && (sd->item_height > 0))
188 row = cvh / sd->item_height;
189 if (row <= 0) row = 1;
190 x = it->position / row;
191 if (x == 0) y = it->position;
192 else if (x > 0) y = it->position % x;
194 it_xpos = ((x - GG_IT(it)->prev_group) * sd->item_width)
195 + (GG_IT(it)->prev_group * sd->group_item_width)
198 miny = miny + ((cvh - (sd->item_height * row))
199 * GG_IT(it)->wsd->align_y);
200 it_ypos = y * sd->item_height + miny;
205 else if (sd->item_width > 0)
207 col = cvw / sd->item_width;
208 if (col <= 0) col = 1;
209 y = it->position / col;
210 minx = minx + ((cvw - (sd->item_width * col))
211 * GG_IT(it)->wsd->align_x);
212 if (y == 0) x = it->position;
213 else if (y > 0) x = it->position % y;
214 it_xpos = x * sd->item_width + minx;
216 it_ypos = ((y - GG_IT(it)->prev_group) * sd->item_height)
217 + (GG_IT(it)->prev_group * sd->group_item_height)
225 switch (sd->scroll_to_type)
227 case ELM_GENGRID_ITEM_SCROLLTO_TOP:
228 sd->s_iface->content_viewport_size_get(WIDGET(it), &vw, &vh);
230 case ELM_GENGRID_ITEM_SCROLLTO_MIDDLE:
231 sd->s_iface->content_viewport_size_get(WIDGET(it), &vw, &vh);
232 it_xpos = it_xpos - ((vw - sd->item_width) / 2);
233 it_ypos = it_ypos - ((vh - sd->item_height) / 2);
237 vh = sd->item_height;
243 sd->s_iface->content_region_show(WIDGET(it),
244 it_xpos, it_ypos, vw, vh);
245 sd->show_region = EINA_FALSE;
249 sd->s_iface->region_bring_in(WIDGET(it),
250 it_xpos, it_ypos, vw, vh);
251 sd->bring_in = EINA_FALSE;
257 _calc_job(void *data)
259 Elm_Gengrid_Smart_Data *sd = data;
260 Evas_Coord minw = 0, minh = 0, nmax = 0, cvw, cvh;
261 Elm_Gen_Item *it, *group_item = NULL;
268 evas_object_geometry_get(sd->pan_obj, NULL, NULL, &cvw, &cvh);
270 if ((cvw != 0) || (cvh != 0))
272 if ((sd->horizontal) && (sd->item_height > 0))
273 nmax = cvh / sd->item_height;
274 else if (sd->item_width > 0)
275 nmax = cvw / sd->item_width;
280 EINA_INLIST_FOREACH(sd->items, it)
282 if (GG_IT(it)->prev_group != count_group)
283 GG_IT(it)->prev_group = count_group;
286 count = count % nmax;
288 sd->items_lost += nmax - count;
290 if (count) count = 0;
295 if (it->parent != group_item)
296 it->parent = group_item;
300 count = sd->item_count + sd->items_lost - count_group;
303 minw = (ceil(count / (float)nmax) * sd->item_width) +
304 (count_group * sd->group_item_width);
305 minh = nmax * sd->item_height;
309 minw = nmax * sd->item_width;
310 minh = (ceil(count / (float)nmax) * sd->item_height) +
311 (count_group * sd->group_item_height);
314 if ((minw != sd->minw) || (minh != sd->minh))
318 evas_object_smart_callback_call(sd->pan_obj, "changed", NULL);
322 evas_object_smart_changed(sd->pan_obj);
327 _elm_gengrid_pan_smart_add(Evas_Object *obj)
329 /* here just to allocate our extended data */
330 EVAS_SMART_DATA_ALLOC(obj, Elm_Gengrid_Pan_Smart_Data);
332 ELM_PAN_CLASS(_elm_gengrid_pan_parent_sc)->base.add(obj);
336 _elm_gengrid_pan_smart_move(Evas_Object *obj,
337 Evas_Coord x __UNUSED__,
338 Evas_Coord y __UNUSED__)
340 ELM_GENGRID_PAN_DATA_GET(obj, psd);
342 if (psd->wsd->calc_job) ecore_job_del(psd->wsd->calc_job);
347 _elm_gengrid_pan_smart_resize(Evas_Object *obj,
353 ELM_GENGRID_PAN_DATA_GET(obj, psd);
355 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
356 if ((ow == w) && (oh == h)) return;
357 if (psd->wsd->calc_job) ecore_job_del(psd->wsd->calc_job);
358 psd->wsd->calc_job = ecore_job_add(_calc_job, psd->wsd);
362 _item_unhighlight(Elm_Gen_Item *it)
364 if (!it->highlighted) return;
366 it->highlighted = EINA_FALSE;
368 edje_object_signal_emit(VIEW(it), "elm,state,unselected", "elm");
369 //******************** TIZEN Only
370 // If check is used on gengrid item, unhighlight it also.
372 Evas_Object *content;
373 EINA_LIST_FOREACH(it->content_objs, l, content)
375 const char *type = elm_widget_type_get(content);
376 if (type && !strcmp(type, "elm_check"))
377 elm_object_signal_emit(content, "elm,state,mouse,up", "elm");
379 //*******************************
380 evas_object_smart_callback_call(WIDGET(it), SIG_UNHIGHLIGHTED, it);
384 _item_unselect(Elm_Gen_Item *it)
386 Elm_Gengrid_Smart_Data *sd = GG_IT(it)->wsd;
388 if (!it->selected) return;
389 if (it->generation < sd->generation) return;
391 it->selected = EINA_FALSE;
392 sd->selected = eina_list_remove(sd->selected, it);
393 _item_unhighlight(it);
394 evas_object_smart_callback_call(WIDGET(it), SIG_UNSELECTED, it);
398 _item_highlight(Elm_Gen_Item *it)
400 Elm_Gengrid_Smart_Data *sd = GG_IT(it)->wsd;
402 if (!sd->highlight) return;
403 if (elm_widget_item_disabled_get(it)) return;
404 if (it->generation < GG_IT(it)->wsd->generation) return;
405 if ((sd->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
406 (it->select_mode == ELM_OBJECT_SELECT_MODE_NONE))
408 if (it->highlighted) return;
410 it->highlighted = EINA_TRUE;
411 edje_object_signal_emit(VIEW(it), "elm,state,selected", "elm");
412 edje_object_message_signal_process(VIEW(it));
414 //***************** TIZEN Only
415 // If check is used on gengrid item, highlight it also.
417 Evas_Object *content;
418 EINA_LIST_FOREACH(it->content_objs, l, content)
420 const char *type = elm_widget_type_get(content);
421 if (elm_widget_can_focus_get(content)) sd->focused_content = content;
422 if (type && !strcmp(type, "elm_check"))
423 elm_object_signal_emit(content, "elm,state,mouse,down", "elm");
425 //****************************
426 evas_object_smart_callback_call(WIDGET(it), SIG_HIGHLIGHTED, it);
430 _highlight_timer(void *data)
432 Elm_Gen_Item *it = data;
433 it->item->highlight_timer = NULL;
439 _select_timer(void *data)
441 Elm_Gen_Item *it = data;
442 it->item->highlight_timer = NULL;
444 if ((GG_IT(it)->wsd->select_mode == ELM_OBJECT_SELECT_MODE_ALWAYS) ||
445 (it->select_mode == ELM_OBJECT_SELECT_MODE_ALWAYS))
449 if (!it->selected)_item_select(it);
450 else _item_unselect(it);
457 _highlight_timer_disable(Elm_Gen_Item *it)
459 if (it->item->highlight_timer)
461 ecore_timer_del(it->item->highlight_timer);
462 it->item->highlight_timer = NULL;
467 _item_text_realize(Elm_Gen_Item *it,
471 if (it->itc->func.text_get)
477 elm_widget_stringlist_get(edje_object_data_get(target, "texts"));
478 EINA_LIST_FREE(source, key)
480 if (parts && fnmatch(parts, key, FNM_PERIOD))
483 char *s = it->itc->func.text_get
484 ((void *)it->base.data, WIDGET(it), key);
488 edje_object_part_text_escaped_set(target, key, s);
493 edje_object_part_text_set(target, key, "");
500 _item_content_realize(Elm_Gen_Item *it,
509 EINA_LIST_FREE(it->content_objs, c)
512 if (it->itc->func.content_get)
515 Evas_Object *ic = NULL;
518 source = elm_widget_stringlist_get
519 (edje_object_data_get(target, src));
521 EINA_LIST_FREE(source, key)
523 if (parts && fnmatch(parts, key, FNM_PERIOD))
526 Evas_Object *old = edje_object_part_swallow_get(target, key);
529 contents = eina_list_remove(contents, old);
530 evas_object_del(old);
533 if (it->itc->func.content_get)
534 ic = it->itc->func.content_get
535 ((void *)it->base.data, WIDGET(it), key);
538 if (!edje_object_part_swallow(target, key, ic))
540 WRN("%s (%p) can not be swallowed into %s",
541 evas_object_type_get(ic), ic, key);
545 evas_object_show(ic);
546 elm_widget_sub_object_add(WIDGET(it), ic);
547 contents = eina_list_append(contents, ic);
555 _item_state_realize(Elm_Gen_Item *it,
559 if (it->itc->func.state_get)
566 elm_widget_stringlist_get(edje_object_data_get(target, "states"));
567 EINA_LIST_FREE(source, key)
569 if (parts && fnmatch(parts, key, FNM_PERIOD))
572 Eina_Bool on = it->itc->func.state_get
573 ((void *)it->base.data, WIDGET(it), key);
577 snprintf(buf, sizeof(buf), "elm,state,%s,active", key);
578 edje_object_signal_emit(target, buf, "elm");
582 snprintf(buf, sizeof(buf), "elm,state,%s,passive", key);
583 edje_object_signal_emit(target, buf, "elm");
590 _item_mouse_move_cb(void *data,
591 Evas *evas __UNUSED__,
595 Elm_Gen_Item *it = data;
596 Evas_Event_Mouse_Move *ev = event_info;
597 Elm_Gengrid_Smart_Data *sd = GG_IT(it)->wsd;
598 Evas_Coord ox, oy, ow, oh, it_scrl_x, it_scrl_y;
599 Evas_Coord minw = 0, minh = 0, x, y, dx, dy, adx, ady;
600 if ((sd->reorder_mode) && (sd->reorder_it == it))
602 evas_object_geometry_get
603 (sd->pan_obj, &ox, &oy, &ow, &oh);
604 it_scrl_x = ev->cur.canvas.x - sd->reorder_it->dx;
605 it_scrl_y = ev->cur.canvas.y - sd->reorder_it->dy;
607 if (it_scrl_x < ox) sd->reorder_item_x = ox;
608 else if (it_scrl_x + sd->item_width > ox + ow)
609 sd->reorder_item_x = ox + ow - sd->item_width;
610 else sd->reorder_item_x = it_scrl_x;
612 if (it_scrl_y < oy) sd->reorder_item_y = oy;
613 else if (it_scrl_y + sd->item_height > oy + oh)
614 sd->reorder_item_y = oy + oh - sd->item_height;
615 else sd->reorder_item_y = it_scrl_y;
618 ecore_job_del(sd->calc_job);
619 sd->calc_job = ecore_job_add(_calc_job, sd);
622 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
624 if (it->item->highlight_timer)
626 ecore_timer_del(it->item->highlight_timer);
627 it->item->highlight_timer = NULL;
629 else if (!it->selected) _item_unhighlight(it);
633 ecore_timer_del(it->long_timer);
634 it->long_timer = NULL;
639 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
641 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
642 dx = ev->cur.canvas.x - x;
643 dy = ev->cur.canvas.y - y;
648 if (adx < 0) adx = -dx;
649 if (ady < 0) ady = -dy;
650 if ((adx > minw) || (ady > minh))
652 it->dragging = EINA_TRUE;
656 evas_object_smart_callback_call
657 (WIDGET(it), SIG_DRAG_START_LEFT, it);
659 evas_object_smart_callback_call
660 (WIDGET(it), SIG_DRAG_START_RIGHT, it);
665 evas_object_smart_callback_call
666 (WIDGET(it), SIG_DRAG_START_UP, it);
668 evas_object_smart_callback_call
669 (WIDGET(it), SIG_DRAG_START_DOWN, it);
674 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG, it);
679 _long_press_cb(void *data)
681 Elm_Gen_Item *it = data,*it2;
682 Elm_Gengrid_Smart_Data *sd = GG_IT(it)->wsd;
685 it->long_timer = NULL;
687 if (elm_widget_item_disabled_get(it) ||
688 (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY) ||
689 (sd->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
690 return ECORE_CALLBACK_CANCEL;
692 if ((sd->reorder_mode) && (!sd->key_down))
695 EINA_LIST_FOREACH_SAFE(sd->selected, l, ll, it2)
697 if (it != it2) _item_unselect(it2);
699 evas_object_raise(VIEW(it));
700 sd->s_iface->hold_set(WIDGET(it), EINA_TRUE);
701 sd->s_iface->bounce_allow_get
702 (WIDGET(it), &(GG_IT(it)->wsd->old_h_bounce),
703 &(GG_IT(it)->wsd->old_v_bounce));
705 sd->s_iface->bounce_allow_set(WIDGET(it), EINA_FALSE, EINA_FALSE);
706 edje_object_signal_emit(VIEW(it), "elm,state,reorder,enabled", "elm");
709 evas_object_smart_callback_call(WIDGET(it), SIG_LONGPRESSED, it);
711 return ECORE_CALLBACK_CANCEL;
715 _item_mouse_down_cb(void *data,
720 Evas_Event_Mouse_Down *ev = event_info;
721 Elm_Gen_Item *it = data;
722 Elm_Gengrid_Smart_Data *sd = GG_IT(it)->wsd;
725 // FIXME: To prevent duplicated callback call
726 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
728 if (ev->button != 1) return;
729 // mouse down activate only one finger touched
730 if (evas_event_down_count_get(evas) != 1) return;
732 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
733 it->dx = ev->canvas.x - x;
734 it->dy = ev->canvas.y - y;
736 sd->was_selected = it->selected;
737 if (it->item->highlight_timer) ecore_timer_del(it->item->highlight_timer);
738 it->item->highlight_timer = ecore_timer_add(ITEM_HIGHLIGHT_TIMER,
739 _highlight_timer, it);
740 if (it->long_timer) ecore_timer_del(it->long_timer);
741 it->long_timer = ecore_timer_add(sd->longpress_timeout, _long_press_cb, it);
743 if (ev->flags & EVAS_BUTTON_DOUBLE_CLICK)
745 evas_object_smart_callback_call(WIDGET(it), SIG_CLICKED_DOUBLE, it);
746 evas_object_smart_callback_call(WIDGET(it), SIG_ACTIVATED, it);
748 evas_object_smart_callback_call(WIDGET(it), SIG_PRESSED, it);
752 _elm_gengrid_item_unrealize(Elm_Gen_Item *it,
755 Evas_Object *content;
757 if (!it->realized) return;
758 if (GG_IT(it)->wsd->reorder_it == it) return;
759 #if GENGRID_FX_SUPPORT
760 if ((GG_IT(it)->has_proxy_it) && (!GG_IT(it)->wsd->gengrid_clearing))
762 if (!eina_list_data_find(GG_IT(it)->wsd->pending_unrealized_items, it))
763 GG_IT(it)->wsd->pending_unrealized_items =
764 eina_list_append(GG_IT(it)->wsd->pending_unrealized_items, it);
768 evas_event_freeze(evas_object_evas_get(WIDGET(it)));
770 evas_object_smart_callback_call(WIDGET(it), SIG_UNREALIZED, it);
773 ecore_timer_del(it->long_timer);
774 it->long_timer = NULL;
777 elm_widget_stringlist_free(it->texts);
779 elm_widget_stringlist_free(it->contents);
781 elm_widget_stringlist_free(it->states);
783 EINA_LIST_FREE (it->content_objs, content)
784 evas_object_del(content);
786 elm_widget_item_track_cancel(it);
788 evas_object_event_callback_del_full
789 (VIEW(it), EVAS_CALLBACK_MOUSE_DOWN, _item_mouse_down_cb, it);
790 evas_object_event_callback_del_full
791 (VIEW(it), EVAS_CALLBACK_MOUSE_UP, _item_mouse_up_cb, it);
792 evas_object_event_callback_del_full
793 (VIEW(it), EVAS_CALLBACK_MOUSE_MOVE, _item_mouse_move_cb, it);
795 it->unrealize_cb(it);
797 it->realized = EINA_FALSE;
798 it->want_unrealize = EINA_FALSE;
799 evas_event_thaw(evas_object_evas_get(WIDGET(it)));
800 evas_event_thaw_eval(evas_object_evas_get(WIDGET(it)));
804 _item_mouse_up_cb(void *data,
806 Evas_Object *obj __UNUSED__,
809 Evas_Event_Mouse_Up *ev = event_info;
810 Elm_Gen_Item *it = data;
811 Elm_Gengrid_Smart_Data *sd = GG_IT(it)->wsd;
813 if (ev->button != 1) return;
815 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
819 it ->dragging = EINA_FALSE;
820 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG_STOP, it);
823 if (evas_event_down_count_get(evas) != 0)
825 if (!it->item->highlight_timer) _item_unhighlight(it);
830 ecore_timer_del(it->long_timer);
831 it->long_timer = NULL;
833 if (it->item->highlight_timer)
835 ecore_timer_del(it->item->highlight_timer);
836 it->item->highlight_timer = NULL;
837 // Because naviframe can drop the all evevents.
838 // highlight it before select timer is called.
839 if (evas_event_down_count_get(evas) == 0) _item_highlight(it);
841 if ((sd->reorder_mode) &&
842 (sd->reorder_it == it))
844 if (!it->selected) _item_unhighlight(it);
845 evas_object_smart_callback_call
846 (WIDGET(it), SIG_MOVED, sd->reorder_it);
847 sd->reorder_it = NULL;
848 sd->move_effect_enabled = EINA_FALSE;
850 ecore_job_del(sd->calc_job);
852 ecore_job_add(_calc_job, sd);
854 sd->s_iface->hold_set(WIDGET(it), EINA_FALSE);
855 sd->s_iface->bounce_allow_set
856 (WIDGET(it), GG_IT(it)->wsd->old_h_bounce,
857 GG_IT(it)->wsd->old_v_bounce);
859 edje_object_signal_emit(VIEW(it), "elm,state,reorder,disabled", "elm");
861 else if ((evas_event_down_count_get(evas) == 0) &&
862 !(ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD))
864 // FIXME: if highlight mode is not used, mouse move cannot disable
866 if ((sd->highlight && it->highlighted) || !sd->highlight)
868 if (sd->was_selected == it->selected)
869 it->item->highlight_timer =
870 ecore_timer_add(ITEM_SELECT_TIMER, _select_timer, it);
873 evas_object_smart_callback_call(WIDGET(it), SIG_RELEASED, it);
877 _elm_gengrid_item_index_update(Elm_Gen_Item *it)
879 if (it->position_update)
881 evas_object_smart_callback_call(WIDGET(it), SIG_INDEX_UPDATE, it);
882 it->position_update = EINA_FALSE;
887 _item_unrealize_cb(Elm_Gen_Item *it)
889 evas_object_del(VIEW(it));
891 evas_object_del(it->spacer);
896 _access_info_cb(void *data, Evas_Object *obj __UNUSED__)
898 Elm_Gen_Item *it = (Elm_Gen_Item *)data;
899 ELM_GENGRID_ITEM_CHECK_OR_RETURN(it, NULL);
901 if (it->itc->func.text_get)
906 if (!(it->texts)) it->texts =
907 elm_widget_stringlist_get(edje_object_data_get(VIEW(it), "texts"));
909 EINA_LIST_FOREACH(it->texts, l, key)
911 char *s = it->itc->func.text_get
912 ((void *)it->base.data, WIDGET(it), key);
921 _access_state_cb(void *data, Evas_Object *obj __UNUSED__)
923 Elm_Gen_Item *it = (Elm_Gen_Item *)data;
924 ELM_GENGRID_ITEM_CHECK_OR_RETURN(it, NULL);
926 if (it->base.disabled)
927 return strdup(E_("State: Disabled"));
933 _access_on_highlight_cb(void *data)
935 Evas_Coord x, y, w, h;
936 Evas_Coord sx, sy, sw, sh;
937 Elm_Gen_Item *it = (Elm_Gen_Item *)data;
938 ELM_GENGRID_ITEM_CHECK_OR_RETURN(it);
940 ELM_GENGRID_DATA_GET(it->base.widget, sd);
942 evas_object_geometry_get(it->base.view, &x, &y, &w, &h);
944 evas_object_geometry_get(ELM_WIDGET_DATA(sd)->obj, &sx, &sy, &sw, &sh);
945 if ((x < sx) || (y < sy) || ((x + w) > (sx + sw)) || ((y + h) > (sy + sh)))
946 elm_gengrid_item_bring_in((Elm_Object_Item *)it,
947 ELM_GENGRID_ITEM_SCROLLTO_IN);
951 _access_activate_cb(void *data __UNUSED__,
952 Evas_Object *part_obj __UNUSED__,
953 Elm_Object_Item *item)
955 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
956 ELM_GENGRID_ITEM_CHECK_OR_RETURN(it);
958 if (!_elm_util_freeze_events_get(WIDGET(item)))
959 _item_select((Elm_Gen_Item *)item);
963 _access_widget_item_register(Elm_Gen_Item *it)
967 _elm_access_widget_item_register((Elm_Widget_Item *)it);
969 ai = _elm_access_object_get(it->base.access_obj);
971 //Tinzen only: comment out type information & state information
972 //_elm_access_text_set(ai, ELM_ACCESS_TYPE, E_("Gengrid Item"));
973 _elm_access_callback_set(ai, ELM_ACCESS_INFO, _access_info_cb, it);
974 //_elm_access_callback_set(ai, ELM_ACCESS_STATE, _access_state_cb, it);
975 _elm_access_on_highlight_hook_set(ai, _access_on_highlight_cb, it);
976 _elm_access_activate_callback_set(ai, _access_activate_cb, it);
979 // FIXME: There are applications which do not use elm_win as top widget.
980 // This is workaround! Those could not use focus!
981 static Eina_Bool _focus_enabled(Evas_Object *obj)
983 if (!elm_widget_focus_get(obj)) return EINA_FALSE;
985 const Evas_Object *win = elm_widget_top_get(obj);
986 const char *type = evas_object_type_get(win);
988 if (type && !strcmp(type, "elm_win"))
990 return elm_win_focus_highlight_enabled_get(win);
996 _view_theme_update(Elm_Gen_Item *it)
1000 snprintf(style, sizeof(style), "item/%s",
1001 it->itc->item_style ? it->itc->item_style : "default");
1002 elm_widget_theme_object_set(WIDGET(it), VIEW(it), "gengrid", style,
1003 elm_widget_style_get(WIDGET(it)));
1004 edje_object_mirrored_set(VIEW(it), elm_widget_mirrored_get(WIDGET(it)));
1005 edje_object_scale_set
1006 (VIEW(it), elm_widget_scale_get(WIDGET(it)) * elm_config_scale_get());
1010 _item_realize(Elm_Gen_Item *it)
1014 if ((it->realized) ||
1015 (it->generation < GG_IT(it)->wsd->generation))
1018 VIEW(it) = edje_object_add(evas_object_evas_get(WIDGET(it)));
1019 evas_object_smart_member_add(VIEW(it), GG_IT(it)->wsd->pan_obj);
1020 elm_widget_sub_object_add(WIDGET(it), VIEW(it));
1022 _view_theme_update(it);
1024 evas_object_rectangle_add(evas_object_evas_get(WIDGET(it)));
1025 evas_object_color_set(it->spacer, 0, 0, 0, 0);
1026 elm_widget_sub_object_add(WIDGET(it), it->spacer);
1027 evas_object_size_hint_min_set(it->spacer, 2 * elm_config_scale_get(), 1);
1028 edje_object_part_swallow(VIEW(it), "elm.swallow.pad", it->spacer);
1031 if (_elm_config->access_mode) _access_widget_item_register(it);
1033 if (it->itc->func.text_get)
1039 elm_widget_stringlist_get(edje_object_data_get(VIEW(it), "texts"));
1040 EINA_LIST_FOREACH(it->texts, l, key)
1042 char *s = it->itc->func.text_get
1043 ((void *)it->base.data, WIDGET(it), key);
1046 edje_object_part_text_escaped_set(VIEW(it), key, s);
1052 if (it->itc->func.content_get)
1056 Evas_Object *ic = NULL;
1058 it->contents = elm_widget_stringlist_get
1059 (edje_object_data_get(VIEW(it), "contents"));
1060 EINA_LIST_FOREACH(it->contents, l, key)
1062 if (it->itc->func.content_get)
1063 ic = it->itc->func.content_get
1064 ((void *)it->base.data, WIDGET(it), key);
1067 it->content_objs = eina_list_append(it->content_objs, ic);
1068 edje_object_part_swallow(VIEW(it), key, ic);
1069 evas_object_show(ic);
1070 elm_widget_sub_object_add(WIDGET(it), ic);
1075 if (it->itc->func.state_get)
1081 elm_widget_stringlist_get(edje_object_data_get(VIEW(it), "states"));
1082 EINA_LIST_FOREACH(it->states, l, key)
1084 Eina_Bool on = it->itc->func.state_get
1085 ((void *)it->base.data, WIDGET(it), l->data);
1088 snprintf(buf, sizeof(buf), "elm,state,%s,active", key);
1089 edje_object_signal_emit(VIEW(it), buf, "elm");
1096 if ((!GG_IT(it)->wsd->group_item_width)
1097 && (!GG_IT(it)->wsd->group_item_height))
1099 edje_object_size_min_restricted_calc
1100 (VIEW(it), &GG_IT(it)->wsd->group_item_width,
1101 &GG_IT(it)->wsd->group_item_height,
1102 GG_IT(it)->wsd->group_item_width,
1103 GG_IT(it)->wsd->group_item_height);
1108 if ((!GG_IT(it)->wsd->item_width)
1109 && (!GG_IT(it)->wsd->item_height))
1111 edje_object_size_min_restricted_calc
1112 (VIEW(it), &GG_IT(it)->wsd->item_width,
1113 &GG_IT(it)->wsd->item_height,
1114 GG_IT(it)->wsd->item_width,
1115 GG_IT(it)->wsd->item_height);
1116 elm_coords_finger_size_adjust
1117 (1, &GG_IT(it)->wsd->item_width, 1,
1118 &GG_IT(it)->wsd->item_height);
1121 evas_object_event_callback_add
1122 (VIEW(it), EVAS_CALLBACK_MOUSE_DOWN, _item_mouse_down_cb, it);
1123 evas_object_event_callback_add
1124 (VIEW(it), EVAS_CALLBACK_MOUSE_UP, _item_mouse_up_cb, it);
1126 evas_object_event_callback_add
1127 (VIEW(it), EVAS_CALLBACK_MOUSE_MOVE, _item_mouse_move_cb, it);
1129 _elm_gengrid_item_index_update(it);
1132 edje_object_signal_emit(VIEW(it), "elm,state,selected", "elm");
1134 if (_focus_enabled(ELM_WIDGET_DATA(GG_IT(it)->wsd)->obj))
1136 if (GG_IT(it)->wsd->focused)
1137 edje_object_signal_emit (VIEW(GG_IT(it)->wsd->focused), "elm,action,focus_highlight,show", "elm");
1139 if (elm_widget_item_disabled_get(it))
1140 edje_object_signal_emit(VIEW(it), "elm,state,disabled", "elm");
1142 evas_object_show(VIEW(it));
1144 if (it->tooltip.content_cb)
1146 elm_widget_item_tooltip_content_cb_set
1147 (it, it->tooltip.content_cb, it->tooltip.data, NULL);
1148 elm_widget_item_tooltip_style_set(it, it->tooltip.style);
1149 elm_widget_item_tooltip_window_mode_set(it, it->tooltip.free_size);
1152 if (it->mouse_cursor)
1153 elm_widget_item_cursor_set(it, it->mouse_cursor);
1155 it->realized = EINA_TRUE;
1156 it->want_unrealize = EINA_FALSE;
1160 _reorder_item_move_animator_cb(void *data)
1162 Elm_Gen_Item *it = data;
1166 tt = REORDER_EFFECT_TIME;
1167 t = ((0.0 > (t = ecore_loop_time_get() -
1168 GG_IT(it)->moving_effect_start_time)) ? 0.0 : t);
1169 dx = ((GG_IT(it)->tx - GG_IT(it)->ox) / 10)
1170 * elm_config_scale_get();
1171 dy = ((GG_IT(it)->ty - GG_IT(it)->oy) / 10)
1172 * elm_config_scale_get();
1176 GG_IT(it)->rx += (1 * sin((t / tt) * (M_PI / 2)) * dx);
1177 GG_IT(it)->ry += (1 * sin((t / tt) * (M_PI / 2)) * dy);
1181 GG_IT(it)->rx += dx;
1182 GG_IT(it)->ry += dy;
1185 if (((dx > 0) && (GG_IT(it)->rx >= GG_IT(it)->tx)) ||
1186 ((dx <= 0) && (GG_IT(it)->rx <= GG_IT(it)->tx))
1187 || ((dy > 0) && (GG_IT(it)->ry >= GG_IT(it)->ty)) ||
1188 ((dy <= 0) && (GG_IT(it)->ry <= GG_IT(it)->ty)))
1190 evas_object_move(VIEW(it), GG_IT(it)->tx, GG_IT(it)->ty);
1195 evas_object_geometry_get
1196 (GG_IT(it)->wsd->pan_obj, NULL, NULL, &vw, &vh);
1197 if (GG_IT(it)->wsd->horizontal)
1199 (VIEW(it), GG_IT(it)->wsd->group_item_width, vh);
1202 (VIEW(it), vw, GG_IT(it)->wsd->group_item_height);
1205 evas_object_resize(VIEW(it), GG_IT(it)->wsd->item_width,
1206 GG_IT(it)->wsd->item_height);
1207 GG_IT(it)->moving = EINA_FALSE;
1208 GG_IT(it)->item_reorder_move_animator = NULL;
1210 return ECORE_CALLBACK_CANCEL;
1213 evas_object_move(VIEW(it), GG_IT(it)->rx, GG_IT(it)->ry);
1218 evas_object_geometry_get
1219 (GG_IT(it)->wsd->pan_obj, NULL, NULL, &vw, &vh);
1220 if (GG_IT(it)->wsd->horizontal)
1222 (VIEW(it), GG_IT(it)->wsd->group_item_width, vh);
1225 (VIEW(it), vw, GG_IT(it)->wsd->group_item_height);
1229 (VIEW(it), GG_IT(it)->wsd->item_width,
1230 GG_IT(it)->wsd->item_height);
1232 return ECORE_CALLBACK_RENEW;
1236 _item_place(Elm_Gen_Item *it,
1240 Evas_Coord x, y, ox, oy, cvx, cvy, cvw, cvh, iw, ih, ww;
1241 Evas_Coord tch, tcw, alignw = 0, alignh = 0, vw, vh;
1242 Eina_Bool reorder_item_move_forward = EINA_FALSE;
1243 Elm_Gengrid_Smart_Data *wsd;
1244 Eina_Bool was_realized;
1245 Elm_Gen_Item_Type *item;
1249 wsd = GG_IT(it)->wsd;
1254 evas_object_geometry_get(wsd->pan_obj, &ox, &oy, &vw, &vh);
1256 /* Preload rows/columns at each side of the Gengrid */
1257 cvx = ox - PRELOAD * wsd->item_width;
1258 cvy = oy - PRELOAD * wsd->item_height;
1259 cvw = vw + 2 * PRELOAD * wsd->item_width;
1260 cvh = vh + 2 * PRELOAD * wsd->item_height;
1265 items_count = wsd->item_count -
1266 eina_list_count(wsd->group_items) + wsd->items_lost;
1267 if (wsd->horizontal)
1269 int columns, items_visible = 0, items_row;
1271 if (wsd->item_height > 0)
1272 items_visible = vh / wsd->item_height;
1273 if (items_visible < 1)
1276 columns = items_count / items_visible;
1277 if (items_count % items_visible)
1280 tcw = (wsd->item_width * columns) + (wsd->group_item_width *
1281 eina_list_count(wsd->group_items));
1282 alignw = (vw - tcw) * wsd->align_x;
1284 items_row = items_visible;
1285 if ((unsigned int)items_row > wsd->item_count)
1286 items_row = wsd->item_count;
1287 if (wsd->filled && (unsigned int)wsd->nmax
1288 > (unsigned int)wsd->item_count)
1289 tch = wsd->nmax * wsd->item_height;
1291 tch = items_row * wsd->item_height;
1292 alignh = (vh - tch) * wsd->align_y;
1293 it->position = items_row * cx + cy;
1297 unsigned int rows, items_visible = 0, items_col;
1299 if (wsd->item_width > 0)
1300 items_visible = vw / wsd->item_width;
1301 if (items_visible < 1)
1304 rows = items_count / items_visible;
1305 if (items_count % items_visible)
1308 tch = (wsd->item_height * rows) + (wsd->group_item_height *
1309 eina_list_count(wsd->group_items));
1310 alignh = (vh - tch) * wsd->align_y;
1312 items_col = items_visible;
1313 if (items_col > wsd->item_count)
1314 items_col = wsd->item_count;
1315 if (wsd->filled && (unsigned int)wsd->nmax
1316 > (unsigned int)wsd->item_count)
1317 tcw = wsd->nmax * wsd->item_width;
1319 tcw = items_col * wsd->item_width;
1320 alignw = (vw - tcw) * wsd->align_x;
1321 it->position = cx + items_col * cy;
1326 if (wsd->horizontal)
1328 x = (((cx - item->prev_group) * wsd->item_width)
1329 + (item->prev_group * wsd->group_item_width)) -
1330 wsd->pan_x + ox + alignw;
1332 iw = wsd->group_item_width;
1338 y = (((cy - item->prev_group) * wsd->item_height)
1339 + (item->prev_group * wsd->group_item_height))
1340 - wsd->pan_y + oy + alignh;
1342 ih = wsd->group_item_height;
1349 if (wsd->horizontal)
1351 x = (((cx - item->prev_group) * wsd->item_width)
1352 + (item->prev_group * wsd->group_item_width)) -
1353 wsd->pan_x + ox + alignw;
1354 y = (cy * wsd->item_height) - wsd->pan_y + oy + alignh;
1358 x = (cx * wsd->item_width) - wsd->pan_x + ox + alignw;
1359 y = (((cy - item->prev_group)
1360 * wsd->item_height) + (item->prev_group *
1361 wsd->group_item_height)) -
1362 wsd->pan_y + oy + alignh;
1364 if (elm_widget_mirrored_get(WIDGET(it))) /* Switch items side
1365 * and componsate for
1369 evas_object_geometry_get(WIDGET(it), NULL, NULL, &ww, NULL);
1370 x = ww - x - wsd->item_width - wsd->pan_x - wsd->pan_x;
1372 iw = wsd->item_width;
1373 ih = wsd->item_height;
1376 was_realized = it->realized;
1377 if (ELM_RECTS_INTERSECT(x, y, iw, ih, cvx, cvy, cvw, cvh))
1381 evas_object_smart_callback_call(WIDGET(it), SIG_REALIZED, it);
1384 if (wsd->horizontal)
1386 if (it->parent->item->gx < ox)
1388 it->parent->item->gx = x + wsd->item_width -
1389 wsd->group_item_width;
1390 if (it->parent->item->gx > ox)
1391 it->parent->item->gx = ox;
1393 it->parent->item->group_realized = EINA_TRUE;
1397 if (it->parent->item->gy < oy)
1399 it->parent->item->gy = y + wsd->item_height -
1400 wsd->group_item_height;
1401 if (it->parent->item->gy > oy)
1402 it->parent->item->gy = oy;
1404 it->parent->item->group_realized = EINA_TRUE;
1407 if (wsd->reorder_mode)
1409 if (wsd->reorder_it)
1411 if (item->moving) return;
1413 if (!wsd->move_effect_enabled)
1418 if (wsd->reorder_it == it)
1420 evas_object_move(VIEW(it), wsd->reorder_item_x,
1421 wsd->reorder_item_y);
1422 evas_object_resize(VIEW(it), iw, ih);
1427 Evas_Coord nx, ny, nw, nh;
1429 if (wsd->move_effect_enabled)
1431 if ((item->ox != x) || (item->oy != y))
1432 if (((wsd->old_pan_x == wsd->pan_x)
1433 && (wsd->old_pan_y == wsd->pan_y))
1434 || ((wsd->old_pan_x != wsd->pan_x) &&
1435 !(item->ox - wsd->pan_x
1436 + wsd->old_pan_x == x)) ||
1437 ((wsd->old_pan_y != wsd->pan_y) &&
1438 !(item->oy - wsd->pan_y +
1439 wsd->old_pan_y == y)))
1443 item->rx = item->ox;
1444 item->ry = item->oy;
1445 item->moving = EINA_TRUE;
1446 item->moving_effect_start_time =
1447 ecore_loop_time_get();
1448 if (item->item_reorder_move_animator)
1450 (item->item_reorder_move_animator);
1451 item->item_reorder_move_animator =
1453 (_reorder_item_move_animator_cb, it);
1461 if (wsd->horizontal)
1463 nx = x + (wsd->group_item_width / 2);
1471 ny = y + (wsd->group_item_height / 2);
1478 nx = x + (wsd->item_width / 2);
1479 ny = y + (wsd->item_height / 2);
1484 if (ELM_RECTS_INTERSECT
1485 (wsd->reorder_item_x, wsd->reorder_item_y,
1486 wsd->item_width, wsd->item_height,
1489 if (wsd->horizontal)
1491 if ((wsd->nmax * wsd->reorder_it->x +
1492 wsd->reorder_it->y) >
1493 (wsd->nmax * it->x + it->y))
1494 reorder_item_move_forward = EINA_TRUE;
1498 if ((wsd->nmax * wsd->reorder_it->y +
1499 wsd->reorder_it->x) >
1500 (wsd->nmax * it->y + it->x))
1501 reorder_item_move_forward = EINA_TRUE;
1504 wsd->items = eina_inlist_remove
1506 EINA_INLIST_GET(wsd->reorder_it));
1507 if (reorder_item_move_forward)
1508 wsd->items = eina_inlist_prepend_relative
1510 EINA_INLIST_GET(wsd->reorder_it),
1511 EINA_INLIST_GET(it));
1513 wsd->items = eina_inlist_append_relative
1515 EINA_INLIST_GET(wsd->reorder_it),
1516 EINA_INLIST_GET(it));
1518 wsd->reorder_item_changed = EINA_TRUE;
1519 wsd->move_effect_enabled = EINA_TRUE;
1521 ecore_job_del(wsd->calc_job);
1523 ecore_job_add(_calc_job, wsd);
1529 else if (item->item_reorder_move_animator)
1532 (item->item_reorder_move_animator);
1533 item->item_reorder_move_animator = NULL;
1534 item->moving = EINA_FALSE;
1537 #if GENGRID_FX_SUPPORT
1538 GG_IT(it)->scrl_x = x;
1539 GG_IT(it)->scrl_y = y;
1543 if (it->group) item->group_realized = EINA_TRUE;
1544 evas_object_move(VIEW(it), x, y);
1545 evas_object_resize(VIEW(it), iw, ih);
1550 _elm_gengrid_item_unrealize(it, EINA_FALSE);
1552 item->group_realized = EINA_FALSE;
1557 _group_item_place(Elm_Gengrid_Pan_Smart_Data *psd)
1559 Evas_Coord iw, ih, vw, vh;
1560 Eina_Bool was_realized;
1564 evas_object_geometry_get(psd->wsd->pan_obj, NULL, NULL, &vw, &vh);
1565 if (psd->wsd->horizontal)
1567 iw = psd->wsd->group_item_width;
1573 ih = psd->wsd->group_item_height;
1575 EINA_LIST_FOREACH(psd->wsd->group_items, l, it)
1577 was_realized = it->realized;
1578 if (GG_IT(it)->group_realized)
1582 evas_object_smart_callback_call(WIDGET(it), SIG_REALIZED, it);
1583 //Need to update the correct coordenates for group index fo fx use.
1584 GG_IT(it)->scrl_x = GG_IT(it)->gx;
1585 GG_IT(it)->scrl_y = GG_IT(it)->gy;
1587 (VIEW(it), GG_IT(it)->gx,
1589 evas_object_resize(VIEW(it), iw, ih);
1590 evas_object_raise(VIEW(it));
1593 _elm_gengrid_item_unrealize(it, EINA_FALSE);
1598 _elm_gengrid_pan_smart_calculate(Evas_Object *obj)
1600 Evas_Coord cx = 0, cy = 0;
1603 ELM_GENGRID_PAN_DATA_GET(obj, psd);
1605 #if GENGRID_FX_SUPPORT
1606 if (psd->wsd->fx_playing) return;
1609 if (!psd->wsd->nmax) return;
1611 psd->wsd->reorder_item_changed = EINA_FALSE;
1613 EINA_INLIST_FOREACH(psd->wsd->items, it)
1617 if (psd->wsd->horizontal)
1634 _item_place(it, cx, cy);
1635 if (psd->wsd->reorder_item_changed) return;
1638 if (psd->wsd->horizontal)
1651 if (psd->wsd->horizontal)
1653 cy = (cy + 1) % psd->wsd->nmax;
1658 cx = (cx + 1) % psd->wsd->nmax;
1663 _group_item_place(psd);
1665 if ((psd->wsd->reorder_mode) && (psd->wsd->reorder_it))
1667 if (!psd->wsd->reorder_item_changed)
1669 psd->wsd->old_pan_x = psd->wsd->pan_x;
1670 psd->wsd->old_pan_y = psd->wsd->pan_y;
1672 psd->wsd->move_effect_enabled = EINA_FALSE;
1674 evas_object_smart_callback_call
1675 (ELM_WIDGET_DATA(psd->wsd)->obj, SIG_CHANGED, NULL);
1676 if ((psd->wsd->show_region || psd->wsd->bring_in))
1677 _item_show_region(psd->wsd);
1679 #if GENGRID_FX_SUPPORT
1680 psd->wsd->rendered = EINA_TRUE;
1681 if (psd->wsd->fx_mode)
1683 if (_elm_gengrid_fx_capture(ELM_WIDGET_DATA(psd->wsd)->obj, 1))
1684 _elm_gengrid_fx_play(ELM_WIDGET_DATA(psd->wsd)->obj);
1690 _elm_gengrid_pan_smart_pos_set(Evas_Object *obj,
1694 ELM_GENGRID_PAN_DATA_GET(obj, psd);
1696 if ((x == psd->wsd->pan_x) && (y == psd->wsd->pan_y)) return;
1697 psd->wsd->pan_x = x;
1698 psd->wsd->pan_y = y;
1699 evas_object_smart_changed(obj);
1703 _elm_gengrid_pan_smart_pos_get(const Evas_Object *obj,
1707 ELM_GENGRID_PAN_DATA_GET(obj, psd);
1709 if (x) *x = psd->wsd->pan_x;
1710 if (y) *y = psd->wsd->pan_y;
1714 _elm_gengrid_pan_smart_content_size_get(const Evas_Object *obj,
1718 ELM_GENGRID_PAN_DATA_GET(obj, psd);
1720 if (w) *w = psd->wsd->minw;
1721 if (h) *h = psd->wsd->minh;
1725 _elm_gengrid_pan_smart_pos_max_get(const Evas_Object *obj,
1731 ELM_GENGRID_PAN_DATA_GET(obj, psd);
1733 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
1735 *x = (ow < psd->wsd->minw) ? psd->wsd->minw - ow : 0;
1737 *y = (oh < psd->wsd->minh) ? psd->wsd->minh - oh : 0;
1741 _elm_gengrid_pan_smart_pos_min_get(const Evas_Object *obj,
1745 Evas_Coord mx = 0, my = 0;
1747 ELM_GENGRID_PAN_DATA_GET(obj, psd);
1749 _elm_gengrid_pan_smart_pos_max_get(obj, &mx, &my);
1751 *x = -mx * psd->wsd->align_x;
1753 *y = -my * psd->wsd->align_y;
1757 _elm_gengrid_pan_smart_set_user(Elm_Gengrid_Pan_Smart_Class *sc)
1759 ELM_PAN_CLASS(sc)->base.add = _elm_gengrid_pan_smart_add;
1760 ELM_PAN_CLASS(sc)->base.move = _elm_gengrid_pan_smart_move;
1761 ELM_PAN_CLASS(sc)->base.resize = _elm_gengrid_pan_smart_resize;
1762 ELM_PAN_CLASS(sc)->base.calculate = _elm_gengrid_pan_smart_calculate;
1764 ELM_PAN_CLASS(sc)->pos_set = _elm_gengrid_pan_smart_pos_set;
1765 ELM_PAN_CLASS(sc)->pos_get = _elm_gengrid_pan_smart_pos_get;
1766 ELM_PAN_CLASS(sc)->pos_max_get = _elm_gengrid_pan_smart_pos_max_get;
1767 ELM_PAN_CLASS(sc)->pos_min_get = _elm_gengrid_pan_smart_pos_min_get;
1768 ELM_PAN_CLASS(sc)->content_size_get =
1769 _elm_gengrid_pan_smart_content_size_get;
1774 _item_multi_select_left(Elm_Gengrid_Smart_Data *sd)
1776 Elm_Object_Item *prev;
1778 if (!sd->selected) return EINA_FALSE;
1780 prev = elm_gengrid_item_prev_get(sd->last_selected_item);
1781 if (!prev) return EINA_TRUE;
1783 if (elm_gengrid_item_selected_get(prev))
1785 elm_gengrid_item_selected_set(sd->last_selected_item, EINA_FALSE);
1786 sd->last_selected_item = prev;
1787 elm_gengrid_item_show
1788 (sd->last_selected_item, ELM_GENGRID_ITEM_SCROLLTO_IN);
1792 elm_gengrid_item_selected_set(prev, EINA_TRUE);
1793 elm_gengrid_item_show(prev, ELM_GENGRID_ITEM_SCROLLTO_IN);
1800 _item_multi_select_right(Elm_Gengrid_Smart_Data *sd)
1802 Elm_Object_Item *next;
1804 if (!sd->selected) return EINA_FALSE;
1806 next = elm_gengrid_item_next_get(sd->last_selected_item);
1807 if (!next) return EINA_TRUE;
1809 if (elm_gengrid_item_selected_get(next))
1811 elm_gengrid_item_selected_set(sd->last_selected_item, EINA_FALSE);
1812 sd->last_selected_item = next;
1813 elm_gengrid_item_show
1814 (sd->last_selected_item, ELM_GENGRID_ITEM_SCROLLTO_IN);
1818 elm_gengrid_item_selected_set(next, EINA_TRUE);
1819 elm_gengrid_item_show(next, ELM_GENGRID_ITEM_SCROLLTO_IN);
1826 _item_multi_select_up(Elm_Gengrid_Smart_Data *sd)
1829 Eina_Bool r = EINA_TRUE;
1831 if (!sd->selected) return EINA_FALSE;
1833 for (i = 0; (r) && (i < sd->nmax); i++)
1834 r &= _item_multi_select_left(sd);
1840 _item_multi_select_down(Elm_Gengrid_Smart_Data *sd)
1843 Eina_Bool r = EINA_TRUE;
1845 if (!sd->selected) return EINA_FALSE;
1847 for (i = 0; (r) && (i < sd->nmax); i++)
1848 r &= _item_multi_select_right(sd);
1854 _all_items_deselect(Elm_Gengrid_Smart_Data *sd)
1856 if (!sd->selected) return EINA_FALSE;
1858 while (sd->selected)
1859 elm_gengrid_item_selected_set
1860 ((Elm_Object_Item *)sd->selected->data, EINA_FALSE);
1866 _item_single_select_up(Elm_Gengrid_Smart_Data *sd)
1873 prev = ELM_GEN_ITEM_FROM_INLIST(sd->items->last);
1874 while ((prev) && (prev->generation < sd->generation))
1875 prev = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(prev)->prev);
1876 elm_gengrid_item_selected_set((Elm_Object_Item *)prev, EINA_TRUE);
1877 elm_gengrid_item_show
1878 ((Elm_Object_Item *)prev, ELM_GENGRID_ITEM_SCROLLTO_IN);
1882 prev = (Elm_Gen_Item *)elm_gengrid_item_prev_get(sd->last_selected_item);
1884 if (!prev) return EINA_FALSE;
1886 for (i = 1; i < sd->nmax; i++)
1888 Elm_Object_Item *tmp =
1889 elm_gengrid_item_prev_get((Elm_Object_Item *)prev);
1890 if (!tmp) return EINA_FALSE;
1891 prev = (Elm_Gen_Item *)tmp;
1894 _all_items_deselect(sd);
1896 elm_gengrid_item_selected_set((Elm_Object_Item *)prev, EINA_TRUE);
1897 elm_gengrid_item_show
1898 ((Elm_Object_Item *)prev, ELM_GENGRID_ITEM_SCROLLTO_IN);
1903 _item_single_select_down(Elm_Gengrid_Smart_Data *sd)
1910 next = ELM_GEN_ITEM_FROM_INLIST(sd->items);
1911 while ((next) && (next->generation < sd->generation))
1912 next = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(next)->next);
1913 elm_gengrid_item_selected_set((Elm_Object_Item *)next, EINA_TRUE);
1914 elm_gengrid_item_show
1915 ((Elm_Object_Item *)next, ELM_GENGRID_ITEM_SCROLLTO_IN);
1919 next = (Elm_Gen_Item *)elm_gengrid_item_next_get(sd->last_selected_item);
1921 if (!next) return EINA_FALSE;
1923 for (i = 1; i < sd->nmax; i++)
1925 Elm_Object_Item *tmp =
1926 elm_gengrid_item_next_get((Elm_Object_Item *)next);
1927 if (!tmp) return EINA_FALSE;
1928 next = (Elm_Gen_Item *)tmp;
1931 _all_items_deselect(sd);
1933 elm_gengrid_item_selected_set((Elm_Object_Item *)next, EINA_TRUE);
1934 elm_gengrid_item_show
1935 ((Elm_Object_Item *)next, ELM_GENGRID_ITEM_SCROLLTO_IN);
1941 _item_single_select_left(Elm_Gengrid_Smart_Data *sd)
1947 prev = ELM_GEN_ITEM_FROM_INLIST(sd->items->last);
1948 while ((prev) && (prev->generation < sd->generation))
1949 prev = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(prev)->prev);
1952 prev = (Elm_Gen_Item *)elm_gengrid_item_prev_get(sd->last_selected_item);
1954 if (!prev) return EINA_FALSE;
1956 _all_items_deselect(sd);
1958 elm_gengrid_item_selected_set((Elm_Object_Item *)prev, EINA_TRUE);
1959 elm_gengrid_item_show
1960 ((Elm_Object_Item *)prev, ELM_GENGRID_ITEM_SCROLLTO_IN);
1966 _item_single_select_right(Elm_Gengrid_Smart_Data *sd)
1972 next = ELM_GEN_ITEM_FROM_INLIST(sd->items);
1973 while ((next) && (next->generation < sd->generation))
1974 next = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(next)->next);
1977 next = (Elm_Gen_Item *)elm_gengrid_item_next_get(sd->last_selected_item);
1979 if (!next) return EINA_FALSE;
1981 _all_items_deselect(sd);
1983 elm_gengrid_item_selected_set((Elm_Object_Item *)next, EINA_TRUE);
1984 elm_gengrid_item_show
1985 ((Elm_Object_Item *)next, ELM_GENGRID_ITEM_SCROLLTO_IN);
1990 static void _gengrid_item_unfocused(Elm_Gen_Item *it)
1993 Elm_Gengrid_Smart_Data *sd = GG_IT(it)->wsd;
1994 if (!sd->focused) return;
1996 if (sd->focused_content)
1998 elm_object_focus_set(ELM_WIDGET_DATA(sd)->obj, EINA_FALSE);
1999 elm_object_focus_set(ELM_WIDGET_DATA(sd)->obj, EINA_TRUE);
2000 sd->focused_content = NULL;
2002 edje_object_signal_emit
2003 (VIEW(sd->focused), "elm,action,focus_highlight,hide", "elm");
2005 if (it == sd->focused) sd->focused = NULL;
2006 evas_object_smart_callback_call(WIDGET(it), SIG_ITEM_UNFOCUSED, it);
2009 static void _gengrid_item_focused(Elm_Gen_Item *it, Elm_Gengrid_Item_Scrollto_Type type)
2012 Elm_Gengrid_Smart_Data *sd = GG_IT(it)->wsd;
2013 Evas_Coord x, y, w, h, sx, sy, sw, sh;
2015 if (sd->focused && (it != sd->focused)) _gengrid_item_unfocused(sd->focused);
2016 evas_object_geometry_get(VIEW(it), &x, &y, &w, &h);
2017 evas_object_geometry_get(ELM_WIDGET_DATA(sd)->obj, &sx, &sy, &sw, &sh);
2018 if ((x < sx) || (y < sy) || ((x + w) > (sx + sw)) || ((y + h) > (sy + sh)))
2020 elm_gengrid_item_bring_in((Elm_Object_Item *)it, type);
2023 if (_focus_enabled(ELM_WIDGET_DATA(sd)->obj))
2024 edje_object_signal_emit
2025 (VIEW(it), "elm,action,focus_highlight,show", "elm");
2028 evas_object_smart_callback_call(WIDGET(it), SIG_ITEM_FOCUSED, it);
2031 static Elm_Gen_Item *_gengrid_item_focusable_search(Elm_Gen_Item *it, int dir)
2033 if (!it) return NULL;
2034 Elm_Gen_Item *tmp = it;
2035 Elm_Gengrid_Smart_Data *sd;
2036 sd = GG_IT(it)->wsd;
2039 while (tmp && (tmp->generation <= sd->generation))
2041 if (!elm_object_item_disabled_get((Elm_Object_Item *)tmp) &&
2042 ((tmp->select_mode == ELM_OBJECT_SELECT_MODE_DEFAULT) ||
2043 (tmp->select_mode == ELM_OBJECT_SELECT_MODE_ALWAYS)))
2045 tmp = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(tmp)->next);
2048 while (tmp && (tmp->generation <= sd->generation))
2050 if (!elm_object_item_disabled_get((Elm_Object_Item *)tmp) &&
2051 ((tmp->select_mode == ELM_OBJECT_SELECT_MODE_DEFAULT) ||
2052 (tmp->select_mode == ELM_OBJECT_SELECT_MODE_ALWAYS)))
2054 tmp = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(tmp)->prev);
2060 static Eina_Bool _gengrid_item_focused_next(Elm_Gengrid_Smart_Data *sd, Focus_Dir dir)
2062 Elm_Gen_Item *it = NULL;
2063 Evas_Coord cvw, cvh, dist = 0;
2064 Elm_Gen_Item *old_focused = sd->focused;
2067 evas_object_geometry_get(sd->pan_obj, NULL, NULL, &cvw, &cvh);
2069 if (dir == FOCUS_DIR_DOWN || dir == FOCUS_DIR_UP)
2071 if ((!sd->horizontal) && (sd->item_width > 0))
2072 dist = cvw / sd->item_width;
2074 if (dist <= 0) dist = 1;
2076 if (dir == FOCUS_DIR_DOWN)
2081 if (it->group) dist = 1;
2082 for (i = 0; i < dist; i++)
2084 it = ELM_GEN_ITEM_FROM_INLIST
2085 (EINA_INLIST_GET(it)->next);
2087 else if (it->group) break;
2089 _gengrid_item_unfocused(sd->focused);
2091 else it = ELM_GEN_ITEM_FROM_INLIST(sd->items);
2092 it = _gengrid_item_focusable_search(it, 1);
2094 else if (dir == FOCUS_DIR_UP)
2099 if (it->group) dist = 1;
2100 for (i = 0; i < dist; i++)
2102 it = ELM_GEN_ITEM_FROM_INLIST
2103 (EINA_INLIST_GET(it)->prev);
2105 else if (it->group) break;
2107 _gengrid_item_unfocused(sd->focused);
2109 else it = ELM_GEN_ITEM_FROM_INLIST(sd->items->last);
2110 it = _gengrid_item_focusable_search(it, -1);
2114 if (old_focused) _gengrid_item_focused(old_focused, ELM_GENGRID_ITEM_SCROLLTO_IN);
2117 _gengrid_item_focused(it, ELM_GENGRID_ITEM_SCROLLTO_IN);
2119 else if (dir == FOCUS_DIR_LEFT || dir == FOCUS_DIR_RIGHT)
2121 if (sd->horizontal && (sd->item_height > 0))
2122 dist = cvh / sd->item_height;
2124 if (dist <= 0) dist = 1;
2126 if (dir == FOCUS_DIR_LEFT)
2131 for (i = 0; i < dist; i++)
2133 it = ELM_GEN_ITEM_FROM_INLIST
2134 (EINA_INLIST_GET(it)->prev);
2136 else if (it->group) break;
2138 _gengrid_item_unfocused(sd->focused);
2140 else it = ELM_GEN_ITEM_FROM_INLIST(sd->items->last);
2141 it = _gengrid_item_focusable_search(it, -1);
2143 else if (dir == FOCUS_DIR_RIGHT)
2148 for (i = 0; i < dist; i++)
2150 it = ELM_GEN_ITEM_FROM_INLIST
2151 (EINA_INLIST_GET(it)->next);
2153 else if (it->group) break;
2155 _gengrid_item_unfocused(sd->focused);
2157 else it = ELM_GEN_ITEM_FROM_INLIST(sd->items);
2158 it = _gengrid_item_focusable_search(it, 1);
2162 if (old_focused) _gengrid_item_focused(old_focused, ELM_GENGRID_ITEM_SCROLLTO_IN);
2165 _gengrid_item_focused(it, ELM_GENGRID_ITEM_SCROLLTO_IN);
2167 else return EINA_FALSE;
2173 _elm_gengrid_smart_event(Evas_Object *obj,
2174 Evas_Object *src __UNUSED__,
2175 Evas_Callback_Type type,
2182 Evas_Coord step_x = 0;
2183 Evas_Coord step_y = 0;
2184 Evas_Coord page_x = 0;
2185 Evas_Coord page_y = 0;
2186 Evas_Event_Key_Down *ev = event_info;
2188 ELM_GENGRID_DATA_GET(obj, sd);
2190 if (type != EVAS_CALLBACK_KEY_DOWN && type != EVAS_CALLBACK_KEY_UP)
2192 if (!sd->items) return EINA_FALSE;
2193 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
2194 if (elm_widget_disabled_get(obj)) return EINA_FALSE;
2195 if (!_focus_enabled(obj)) return EINA_FALSE;
2197 sd->s_iface->content_pos_get(obj, &x, &y);
2198 sd->s_iface->step_size_get(obj, &step_x, &step_y);
2199 sd->s_iface->page_size_get(obj, &page_x, &page_y);
2200 sd->s_iface->content_viewport_size_get(obj, &v_w, &v_h);
2202 #ifdef ELM_FOCUSED_UI
2203 if ((!strcmp(ev->keyname, "Left")) ||
2204 ((!strcmp(ev->keyname, "KP_Left")) && (!ev->string)))
2206 if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
2207 if (sd->select_on_focus_enabled)
2209 if ((sd->horizontal) &&
2210 (((evas_key_modifier_is_set(ev->modifiers, "Shift"))
2211 && (_item_multi_select_up(sd)))
2212 || (_item_single_select_up(sd))))
2214 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2217 else if ((!sd->horizontal) &&
2218 (((evas_key_modifier_is_set(ev->modifiers, "Shift"))
2219 && (_item_multi_select_left(sd)))
2220 || (_item_single_select_left(sd))))
2222 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2232 if (_gengrid_item_focused_next(sd, FOCUS_DIR_LEFT))
2234 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2243 else if ((!strcmp(ev->keyname, "Right")) ||
2244 ((!strcmp(ev->keyname, "KP_Right")) && (!ev->string)))
2246 if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
2247 if (sd->select_on_focus_enabled)
2249 if ((sd->horizontal) &&
2250 (((evas_key_modifier_is_set(ev->modifiers, "Shift"))
2251 && (_item_multi_select_down(sd)))
2252 || (_item_single_select_down(sd))))
2254 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2257 else if ((!sd->horizontal) &&
2258 (((evas_key_modifier_is_set(ev->modifiers, "Shift"))
2259 && (_item_multi_select_right(sd)))
2260 || (_item_single_select_right(sd))))
2262 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2272 if (_gengrid_item_focused_next(sd, FOCUS_DIR_RIGHT))
2274 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2283 else if ((!strcmp(ev->keyname, "Up")) ||
2284 ((!strcmp(ev->keyname, "KP_Up")) && (!ev->string)))
2286 if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
2287 if (sd->select_on_focus_enabled)
2289 if ((sd->horizontal) &&
2290 (((evas_key_modifier_is_set(ev->modifiers, "Shift"))
2291 && (_item_multi_select_left(sd)))
2292 || (_item_single_select_left(sd))))
2294 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2297 else if ((!sd->horizontal) &&
2298 (((evas_key_modifier_is_set(ev->modifiers, "Shift"))
2299 && (_item_multi_select_up(sd)))
2300 || (_item_single_select_up(sd))))
2302 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2312 if (_gengrid_item_focused_next(sd, FOCUS_DIR_UP))
2314 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2323 else if ((!strcmp(ev->keyname, "Down")) ||
2324 ((!strcmp(ev->keyname, "KP_Down")) && (!ev->string)))
2326 if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
2327 if (sd->select_on_focus_enabled)
2329 if ((sd->horizontal) &&
2330 (((evas_key_modifier_is_set(ev->modifiers, "Shift"))
2331 && (_item_multi_select_right(sd)))
2332 || (_item_single_select_right(sd))))
2334 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2337 else if ((!sd->horizontal) &&
2338 (((evas_key_modifier_is_set(ev->modifiers, "Shift"))
2339 && (_item_multi_select_down(sd)))
2340 || (_item_single_select_down(sd))))
2342 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2352 if (_gengrid_item_focused_next(sd, FOCUS_DIR_DOWN))
2354 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2363 else if ((!strcmp(ev->keyname, "Home")) ||
2364 ((!strcmp(ev->keyname, "KP_Home")) && (!ev->string)))
2366 if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
2367 Elm_Object_Item *it = NULL;
2368 if (sd->select_on_focus_enabled)
2370 it = elm_gengrid_first_item_get(obj);
2371 elm_gengrid_item_bring_in(it, ELM_GENGRID_ITEM_SCROLLTO_IN);
2372 elm_gengrid_item_selected_set(it, EINA_TRUE);
2373 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2377 _gengrid_item_unfocused(sd->focused);
2378 _gengrid_item_focused_next(sd, FOCUS_DIR_DOWN);
2379 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2383 else if ((!strcmp(ev->keyname, "End")) ||
2384 ((!strcmp(ev->keyname, "KP_End")) && (!ev->string)))
2386 if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
2387 Elm_Object_Item *it = NULL;
2388 if (sd->select_on_focus_enabled)
2390 it = elm_gengrid_last_item_get(obj);
2391 elm_gengrid_item_bring_in(it, ELM_GENGRID_ITEM_SCROLLTO_IN);
2392 elm_gengrid_item_selected_set(it, EINA_TRUE);
2393 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2397 _gengrid_item_unfocused(sd->focused);
2398 sd->focused = ELM_GEN_ITEM_FROM_INLIST(sd->items->last);
2399 _gengrid_item_focused_next(sd, FOCUS_DIR_UP);
2400 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2404 else if ((!strcmp(ev->keyname, "Prior")) ||
2405 ((!strcmp(ev->keyname, "KP_Prior")) && (!ev->string)))
2407 if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
2408 Elm_Gen_Item *it = sd->focused;
2409 int before_pos = it->position;
2410 int after_pos = it->position;
2412 if (sd->item_height > 0) page_y = v_h / sd->item_height;
2413 if (sd->item_width > 0) page_x = v_w / sd->item_width;
2415 while ((before_pos - after_pos) < (page_x * page_y))
2417 if (elm_gengrid_item_prev_get((Elm_Object_Item *) it))
2418 it = (Elm_Gen_Item *)
2419 elm_gengrid_item_prev_get((Elm_Object_Item *) it);
2421 after_pos = it->position;
2423 if (_gengrid_item_focusable_search(it, 1))
2424 it = _gengrid_item_focusable_search(it, 1);
2425 else if (_gengrid_item_focusable_search(it, -1))
2426 it = _gengrid_item_focusable_search(it, -1);
2428 _gengrid_item_focused(it, ELM_GENGRID_ITEM_SCROLLTO_TOP);
2430 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2433 else if ((!strcmp(ev->keyname, "Next")) ||
2434 ((!strcmp(ev->keyname, "KP_Next")) && (!ev->string)))
2436 if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
2437 Elm_Gen_Item *it = sd->focused;
2438 int before_pos = it->position;
2439 int after_pos = it->position;
2441 _gengrid_item_unfocused(sd->focused);
2442 if (sd->item_height > 0) page_y = v_h / sd->item_height;
2443 if (sd->item_width > 0) page_x = v_w / sd->item_width;
2445 while ((after_pos - before_pos) < (page_x * page_y))
2447 if (elm_gengrid_item_next_get((Elm_Object_Item *) it))
2448 it = (Elm_Gen_Item *)
2449 elm_gengrid_item_next_get((Elm_Object_Item *) it);
2451 after_pos = it->position;
2453 if (_gengrid_item_focusable_search(it, -1))
2454 it = _gengrid_item_focusable_search(it, -1);
2455 else if (_gengrid_item_focusable_search(it, 1))
2456 it = _gengrid_item_focusable_search(it, 1);
2458 _gengrid_item_focused(it, ELM_GENGRID_ITEM_SCROLLTO_TOP);
2460 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2463 else if (!strcmp(ev->keyname, "Escape"))
2465 if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
2466 if (!_all_items_deselect(sd)) return EINA_FALSE;
2467 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2470 else if (((!strcmp(ev->keyname, "Return")) ||
2471 (!strcmp(ev->keyname, "KP_Enter"))) &&
2474 if (type == EVAS_CALLBACK_KEY_DOWN && !sd->key_down)
2476 sd->key_down = sd->focused;
2478 edje_object_signal_emit
2479 (VIEW(sd->key_down), "elm,action,focus_highlight,hide", "elm");
2481 _item_highlight(sd->key_down);
2482 if (sd->key_down->long_timer)
2483 ecore_timer_del(sd->key_down->long_timer);
2484 sd->key_down->long_timer = ecore_timer_add(sd->longpress_timeout,
2485 _long_press_cb, sd->key_down);
2486 evas_object_smart_callback_call(obj, SIG_ACTIVATED, sd->key_down);
2487 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2490 else if (type == EVAS_CALLBACK_KEY_UP && sd->key_down)
2492 edje_object_signal_emit
2493 (VIEW(sd->key_down), "elm,action,focus_highlight,show", "elm");
2495 if (sd->key_down->long_timer)
2496 ecore_timer_del(sd->key_down->long_timer);
2497 sd->key_down->long_timer = NULL;
2498 if (GG_IT(sd->key_down)->highlight_timer)
2499 ecore_timer_del(GG_IT(sd->key_down)->highlight_timer);
2500 GG_IT(sd->key_down)->highlight_timer = ecore_timer_add
2501 (ITEM_SELECT_TIMER, _select_timer, sd->key_down);
2502 sd->key_down = NULL;
2503 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2506 else return EINA_FALSE;
2509 else return EINA_FALSE;
2511 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2512 sd->s_iface->content_pos_set(obj, x, y, EINA_TRUE);
2520 _elm_gengrid_focus_highlight_show(void *data __UNUSED__,
2522 const char *emission __UNUSED__,
2523 const char *src __UNUSED__)
2525 ELM_GENGRID_DATA_GET(obj, sd);
2526 if (sd->focused) _gengrid_item_focused(sd->focused, ELM_GENGRID_ITEM_SCROLLTO_IN);
2530 _elm_gengrid_focus_highlight_hide(void *data __UNUSED__,
2532 const char *emission __UNUSED__,
2533 const char *src __UNUSED__)
2535 ELM_GENGRID_DATA_GET(obj, sd);
2538 // Do not use _gengrid_item_unfocused because focus should be remained
2539 edje_object_signal_emit
2540 (VIEW(sd->focused), "elm,action,focus_highlight,hide", "elm");
2545 _elm_gengrid_smart_on_focus(Evas_Object *obj)
2547 ELM_GENGRID_DATA_GET(obj, sd);
2549 if (!ELM_WIDGET_CLASS(_elm_gengrid_parent_sc)->on_focus(obj))
2552 if (elm_widget_focus_get(obj) && (sd->selected) &&
2553 (!sd->last_selected_item))
2554 sd->last_selected_item = eina_list_data_get(sd->selected);
2556 if (sd->select_on_focus_enabled) return EINA_TRUE;
2558 if (elm_widget_focus_get(obj))
2560 if (_focus_enabled(obj))
2563 _gengrid_item_focused(sd->focused, ELM_GENGRID_ITEM_SCROLLTO_IN);
2565 _gengrid_item_focused_next(sd, FOCUS_DIR_DOWN);
2570 // when key down and not called key up
2571 // and focus is not on genlist, call select_timer forcely
2574 _select_timer(sd->key_down);
2575 sd->key_down = NULL;
2580 edje_object_signal_emit
2581 (VIEW(sd->focused), "elm,action,focus_highlight,hide", "elm");
2588 _elm_gengrid_smart_on_focus_region(const Evas_Object *obj __UNUSED__,
2594 //FIXME: Gengrid should not move region when first focus in,
2595 //But when focus by Keyboard or enforced focus set by
2596 //applications, region move should be possible.
2606 _elm_gengrid_smart_focus_next(const Evas_Object *obj,
2607 Elm_Focus_Direction dir,
2610 Eina_List *items = NULL;
2613 ELM_GENGRID_CHECK(obj) EINA_FALSE;
2614 ELM_GENGRID_DATA_GET(obj, sd);
2616 EINA_INLIST_FOREACH(sd->items, it)
2619 items = eina_list_append(items, it->base.access_obj);
2622 return elm_widget_focus_list_next_get
2623 (obj, items, eina_list_data_get, dir, next);
2627 _mirrored_set(Evas_Object *obj,
2632 ELM_GENGRID_DATA_GET(obj, sd);
2634 sd->s_iface->mirrored_set(obj, rtl);
2636 if (!sd->items) return;
2637 it = ELM_GEN_ITEM_FROM_INLIST(sd->items);
2641 edje_object_mirrored_set(VIEW(it), rtl);
2642 elm_gengrid_item_update((Elm_Object_Item *)it);
2643 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
2648 _elm_gengrid_smart_theme(Evas_Object *obj)
2650 if (!ELM_WIDGET_CLASS(_elm_gengrid_parent_sc)->theme(obj))
2653 _mirrored_set(obj, elm_widget_mirrored_get(obj));
2659 _item_position_update(Eina_Inlist *list,
2664 EINA_INLIST_FOREACH(list, it)
2666 it->position = idx++;
2667 it->position_update = EINA_TRUE;
2672 _elm_gengrid_item_del_not_serious(Elm_Gen_Item *it)
2674 elm_widget_item_pre_notify_del(it);
2675 it->generation = GG_IT(it)->wsd->generation - 1; /* This means that the
2676 * item is deleted */
2678 if (it->walking > 0) return;
2681 GG_IT(it)->wsd->selected =
2682 eina_list_remove(GG_IT(it)->wsd->selected, it);
2684 if (it->itc->func.del)
2685 it->itc->func.del((void *)it->base.data, WIDGET(it));
2689 _elm_gengrid_item_del_common(Elm_Gen_Item *it)
2691 #if GENGRID_FX_SUPPORT
2692 if (!eina_list_data_find(GG_IT(it)->wsd->pending_del_items, it))
2694 GG_IT(it)->wsd->items = eina_inlist_remove
2695 (GG_IT(it)->wsd->items, EINA_INLIST_GET(it));
2697 if (it->tooltip.del_cb)
2698 it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
2699 GG_IT(it)->wsd->walking -= it->walking;
2701 if (GG_IT(it)->wsd->focused == it) _gengrid_item_unfocused(it); //GG_IT(it)->wsd->focused = NULL;
2702 if (GG_IT(it)->wsd->key_down == it) GG_IT(it)->wsd->key_down = NULL;
2704 if (it->item->highlight_timer)
2706 ecore_timer_del(it->item->highlight_timer);
2707 it->item->highlight_timer = NULL;
2711 ecore_timer_del(it->long_timer);
2712 it->long_timer = NULL;
2715 GG_IT(it)->wsd->group_items =
2716 eina_list_remove(GG_IT(it)->wsd->group_items, it);
2718 if (GG_IT(it)->wsd->state)
2720 eina_inlist_sorted_state_free(GG_IT(it)->wsd->state);
2721 GG_IT(it)->wsd->state = NULL;
2723 if (GG_IT(it)->wsd->calc_job) ecore_job_del(GG_IT(it)->wsd->calc_job);
2724 GG_IT(it)->wsd->calc_job =
2725 ecore_job_add(GG_IT(it)->wsd->calc_cb, GG_IT(it)->wsd);
2727 if (GG_IT(it)->wsd->last_selected_item == (Elm_Object_Item *)it)
2728 GG_IT(it)->wsd->last_selected_item = NULL;
2730 GG_IT(it)->wsd->item_count--;
2734 _elm_gengrid_item_del_serious(Elm_Gen_Item *it)
2736 _elm_gengrid_item_del_not_serious(it);
2737 _elm_gengrid_item_del_common(it);
2739 if ((it == GG_IT(it)->wsd->bring_in_it) && (GG_IT(it)->wsd->bring_in == EINA_TRUE))
2741 GG_IT(it)->wsd->bring_in_it = NULL;
2742 GG_IT(it)->wsd->bring_in = EINA_FALSE;
2745 if ((it == GG_IT(it)->wsd->show_it) && (GG_IT(it)->wsd->show_region == EINA_TRUE))
2747 GG_IT(it)->wsd->show_it = NULL;
2748 GG_IT(it)->wsd->show_region = EINA_FALSE;
2756 _item_del(Elm_Gen_Item *it)
2758 Evas_Object *obj = WIDGET(it);
2760 evas_event_freeze(evas_object_evas_get(obj));
2761 #if GENGRID_FX_SUPPORT
2762 GG_IT(it)->has_proxy_it = EINA_FALSE;
2764 GG_IT(it)->wsd->selected = eina_list_remove(GG_IT(it)->wsd->selected, it);
2765 if (it->realized) _elm_gengrid_item_unrealize(it, EINA_FALSE);
2766 _elm_gengrid_item_del_serious(it);
2767 elm_gengrid_item_class_unref((Elm_Gengrid_Item_Class *)it->itc);
2768 evas_event_thaw(evas_object_evas_get(obj));
2769 evas_event_thaw_eval(evas_object_evas_get(obj));
2773 _scroll_animate_start_cb(Evas_Object *obj,
2774 void *data __UNUSED__)
2776 evas_object_smart_callback_call(obj, SIG_SCROLL_ANIM_START, NULL);
2780 _scroll_animate_stop_cb(Evas_Object *obj,
2781 void *data __UNUSED__)
2783 evas_object_smart_callback_call(obj, SIG_SCROLL_ANIM_STOP, NULL);
2787 _scroll_drag_start_cb(Evas_Object *obj,
2788 void *data __UNUSED__)
2790 evas_object_smart_callback_call(obj, SIG_SCROLL_DRAG_START, NULL);
2794 _scroll_drag_stop_cb(Evas_Object *obj,
2795 void *data __UNUSED__)
2797 evas_object_smart_callback_call(obj, SIG_SCROLL_DRAG_STOP, NULL);
2801 _edge_left_cb(Evas_Object *obj,
2802 void *data __UNUSED__)
2804 evas_object_smart_callback_call(obj, SIG_EDGE_LEFT, NULL);
2808 _edge_right_cb(Evas_Object *obj,
2809 void *data __UNUSED__)
2811 evas_object_smart_callback_call(obj, SIG_EDGE_RIGHT, NULL);
2815 _edge_top_cb(Evas_Object *obj,
2816 void *data __UNUSED__)
2818 evas_object_smart_callback_call(obj, SIG_EDGE_TOP, NULL);
2822 _edge_bottom_cb(Evas_Object *obj,
2823 void *data __UNUSED__)
2825 evas_object_smart_callback_call(obj, SIG_EDGE_BOTTOM, NULL);
2829 _scroll_cb(Evas_Object *obj,
2830 void *data __UNUSED__)
2832 evas_object_smart_callback_call(obj, SIG_SCROLL, NULL);
2836 _elm_gengrid_item_compare(const void *data,
2839 Elm_Gen_Item *it, *item1;
2840 Eina_Compare_Cb cb = NULL;
2843 it = ELM_GEN_ITEM_FROM_INLIST(data);
2844 item1 = ELM_GEN_ITEM_FROM_INLIST(data1);
2845 if (it && GG_IT(it)->wsd->item_compare_cb)
2846 cb = GG_IT(it)->wsd->item_compare_cb;
2847 else if (item1 && GG_IT(item1)->wsd->item_compare_cb)
2848 cb = GG_IT(item1)->wsd->item_compare_cb;
2849 if (cb && it && item1) return cb(it, item1);
2850 d = (char *)data - (char *)data1;
2851 if (d < 0) return -1;
2857 _item_disable_hook(Elm_Object_Item *item)
2859 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
2861 if (it->generation < GG_IT(it)->wsd->generation) return;
2863 _highlight_timer_disable(it);
2864 if (it == GG_IT(it)->wsd->focused) _gengrid_item_unfocused(it);
2868 if (elm_widget_item_disabled_get(it))
2869 edje_object_signal_emit(VIEW(it), "elm,state,disabled", "elm");
2871 edje_object_signal_emit(VIEW(it), "elm,state,enabled", "elm");
2875 #if GENGRID_FX_SUPPORT
2877 _item_del_post_fx_process(Elm_Gen_Item *it)
2879 Evas_Object *obj = WIDGET(it);
2881 evas_event_freeze(evas_object_evas_get(obj));
2883 GG_IT(it)->has_proxy_it = EINA_FALSE;
2885 if (it->itc->func.del)
2886 it->itc->func.del((void *)it->base.data, WIDGET(it));
2888 if (GG_IT(it)->wsd->calc_job) ecore_job_del(GG_IT(it)->wsd->calc_job);
2889 GG_IT(it)->wsd->calc_job =
2890 ecore_job_add(GG_IT(it)->wsd->calc_cb, GG_IT(it)->wsd);
2892 if ((it == GG_IT(it)->wsd->bring_in_it) && (GG_IT(it)->wsd->bring_in == EINA_TRUE))
2894 GG_IT(it)->wsd->bring_in_it = NULL;
2895 GG_IT(it)->wsd->bring_in = EINA_FALSE;
2898 if ((it == GG_IT(it)->wsd->show_it) && (GG_IT(it)->wsd->show_region == EINA_TRUE))
2900 GG_IT(it)->wsd->show_it = NULL;
2901 GG_IT(it)->wsd->show_region = EINA_FALSE;
2906 elm_gengrid_item_class_unref((Elm_Gengrid_Item_Class *)it->itc);
2907 evas_event_thaw(evas_object_evas_get(obj));
2908 evas_event_thaw_eval(evas_object_evas_get(obj));
2912 _item_del_pre_fx_process(Elm_Gen_Item *it)
2914 _elm_gengrid_fx_capture(ELM_WIDGET_DATA(GG_IT(it)->wsd)->obj, 0);
2915 if (!eina_list_data_find(GG_IT(it)->wsd->pending_del_items, it))
2917 GG_IT(it)->wsd->pending_del_items = eina_list_append(GG_IT(it)->wsd->pending_del_items, it);
2920 evas_object_event_callback_del_full
2921 (VIEW(it), EVAS_CALLBACK_MOUSE_DOWN, _item_mouse_down_cb, it);
2922 evas_object_event_callback_del_full
2923 (VIEW(it), EVAS_CALLBACK_MOUSE_UP, _item_mouse_up_cb, it);
2925 evas_object_event_callback_del_full
2926 (VIEW(it), EVAS_CALLBACK_MOUSE_MOVE, _item_mouse_move_cb, it);
2928 _highlight_timer_disable(it);
2930 GG_IT(it)->wsd->items = eina_inlist_remove
2931 (GG_IT(it)->wsd->items, EINA_INLIST_GET(it));
2933 if (it->realized) _elm_gengrid_item_unrealize(it, EINA_FALSE);
2935 elm_widget_item_pre_notify_del(it);
2936 it->generation = GG_IT(it)->wsd->generation - 1; /* This means that the
2937 * item is deleted */
2938 if (it->walking > 0) return;
2941 GG_IT(it)->wsd->selected =
2942 eina_list_remove(GG_IT(it)->wsd->selected, it);
2944 _elm_gengrid_item_del_common(it);
2950 _item_del_pre_hook(Elm_Object_Item *item)
2952 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
2954 #if GENGRID_FX_SUPPORT
2955 if ((GG_IT(it)->wsd->fx_mode) && (!GG_IT(it)->wsd->gengrid_clearing))
2957 _item_del_pre_fx_process(it);
2961 if (it->walking > 0)
2963 _elm_gengrid_item_del_not_serious(it);
2971 static Evas_Object *
2972 _item_content_get_hook(Elm_Gen_Item *it,
2975 return edje_object_part_swallow_get(VIEW(it), part);
2979 _item_text_get_hook(Elm_Gen_Item *it,
2982 if (!it->itc->func.text_get) return NULL;
2983 return edje_object_part_text_get(VIEW(it), part);
2987 _item_signal_emit_hook(Elm_Object_Item *it,
2988 const char *emission,
2991 edje_object_signal_emit(VIEW(it), emission, source);
2995 _elm_gengrid_clear(Evas_Object *obj,
2998 Eina_Inlist *next, *l;
3001 ELM_GENGRID_DATA_GET(obj, sd);
3003 if (!standby) sd->generation++;
3007 eina_inlist_sorted_state_free(sd->state);
3011 if (sd->walking > 0)
3013 sd->clear_me = EINA_TRUE;
3016 evas_event_freeze(evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
3018 #if GENGRID_FX_SUPPORT
3019 Elm_Gen_FX_Item *fi;
3022 EINA_LIST_FREE(sd->capture_before_items, pi)
3024 if (pi->proxy) evas_object_smart_member_del(pi->proxy);
3025 if (pi->proxy) evas_object_del(pi->proxy);
3028 EINA_LIST_FREE(sd->capture_after_items, pi)
3030 if (pi->proxy) evas_object_smart_member_del(pi->proxy);
3031 if (pi->proxy) evas_object_del(pi->proxy);
3034 EINA_LIST_FREE(sd->fx_items, fi)
3036 if (fi->trans) elm_transit_del(fi->trans);
3039 EINA_LIST_FREE (sd->pending_unrealized_items, it)
3041 if ((it) && (GG_IT(it))) GG_IT(it)->has_proxy_it = EINA_FALSE;
3042 _elm_gengrid_item_unrealize(it, EINA_FALSE);
3044 EINA_LIST_FREE (sd->pending_del_items, it)
3046 _item_del_post_fx_process(it);
3047 elm_widget_item_free(it);
3049 sd->gengrid_clearing = EINA_TRUE;
3050 sd->fx_playing = EINA_FALSE;
3051 sd->fx_first_captured = EINA_FALSE;
3052 sd->rendered = EINA_FALSE;
3055 for (l = sd->items, next = l ? l->next : NULL;
3057 l = next, next = next ? next->next : NULL)
3059 it = ELM_GEN_ITEM_FROM_INLIST(l);
3061 if (it->generation < sd->generation)
3063 Elm_Gen_Item *itn = NULL;
3065 if (next) itn = ELM_GEN_ITEM_FROM_INLIST(next);
3066 if (itn) itn->walking++; /* prevent early death of subitem */
3068 elm_widget_item_free(it);
3069 if (itn) itn->walking--;
3072 sd->clear_me = EINA_FALSE;
3073 sd->pan_changed = EINA_TRUE;
3076 ecore_job_del(sd->calc_job);
3077 sd->calc_job = NULL;
3080 if (sd->focused) sd->focused = NULL;
3081 if (sd->key_down) sd->key_down = NULL;
3082 if (sd->selected) sd->selected = eina_list_free(sd->selected);
3083 if (sd->clear_cb) sd->clear_cb(sd);
3091 evas_object_size_hint_min_set(sd->pan_obj, sd->minw, sd->minh);
3092 evas_object_smart_callback_call(sd->pan_obj, "changed", NULL);
3094 sd->s_iface->content_region_show(obj, 0, 0, 0, 0);
3096 #if GENGRID_FX_SUPPORT
3097 sd->gengrid_clearing = EINA_FALSE;
3099 evas_event_thaw(evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
3100 evas_event_thaw_eval(evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
3104 _item_select(Elm_Gen_Item *it)
3106 Evas_Object *obj = WIDGET(it);
3107 Elm_Gengrid_Smart_Data *sd = GG_IT(it)->wsd;
3108 if (elm_widget_item_disabled_get(it)) return;
3109 if ((sd->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
3110 (it->select_mode == ELM_OBJECT_SELECT_MODE_NONE))
3112 if (sd->select_mode != ELM_OBJECT_SELECT_MODE_ALWAYS &&
3113 it->select_mode != ELM_OBJECT_SELECT_MODE_ALWAYS &&
3118 const Eina_List *l, *ll;
3120 EINA_LIST_FOREACH_SAFE(sd->selected, l, ll, it2)
3121 if (it2 != it) _item_unselect(it2);
3126 sd->selected = eina_list_append(sd->selected, it);
3127 it->selected = EINA_TRUE;
3129 sd->last_selected_item = (Elm_Object_Item *)it;
3130 _item_highlight(it);
3131 _gengrid_item_focused(it, ELM_GENGRID_ITEM_SCROLLTO_IN);
3133 // FIXME: after evas_object_raise, mouse event callbacks(ex, UP, DOWN)
3134 // can be called again eventhough already received it.
3135 const char *selectraise = edje_object_data_get(VIEW(it), "selectraise");
3136 if ((selectraise) && (!strcmp(selectraise, "on")))
3138 evas_object_raise(VIEW(it));
3141 evas_object_ref(obj);
3142 if (it->func.func) it->func.func((void *)it->func.data, WIDGET(it), it);
3143 if (EINA_MAGIC_CHECK((Elm_Widget_Item *)it, ELM_WIDGET_ITEM_MAGIC))
3145 if (it->generation == sd->generation)
3146 evas_object_smart_callback_call(WIDGET(it), SIG_SELECTED, it);
3148 evas_object_unref(obj);
3151 static Elm_Gen_Item *
3152 _elm_gengrid_item_new(Elm_Gengrid_Smart_Data *sd,
3153 const Elm_Gen_Item_Class *itc,
3156 const void *func_data)
3160 if (!itc) return NULL;
3162 it = elm_widget_item_new(ELM_WIDGET_DATA(sd)->obj, Elm_Gen_Item);
3163 if (!it) return NULL;
3165 it->generation = sd->generation;
3167 elm_gengrid_item_class_ref((Elm_Gengrid_Item_Class *)itc);
3169 it->base.data = data;
3171 it->func.func = func;
3172 it->func.data = func_data;
3174 elm_widget_item_content_get_hook_set(it, _item_content_get_hook);
3175 elm_widget_item_text_get_hook_set(it, _item_text_get_hook);
3176 elm_widget_item_disable_hook_set(it, _item_disable_hook);
3177 elm_widget_item_del_pre_hook_set(it, _item_del_pre_hook);
3178 elm_widget_item_signal_emit_hook_set(it, _item_signal_emit_hook);
3181 it->sel_cb = (Ecore_Cb)_item_select;
3183 it->item = ELM_NEW(Elm_Gen_Item_Type);
3185 GG_IT(it)->wsd = sd;
3188 it->group = it->itc->item_style &&
3189 (!strncmp(it->itc->item_style, "group_index", 11));
3191 it->del_cb = (Ecore_Cb)_item_del;
3192 it->highlight_cb = (Ecore_Cb)_item_highlight;
3193 it->unsel_cb = (Ecore_Cb)_item_unselect;
3194 it->unrealize_cb = (Ecore_Cb)_item_unrealize_cb;
3196 #if GENGRID_FX_SUPPORT
3197 it->item->num = sd->item_count;
3199 _elm_gengrid_fx_capture(ELM_WIDGET_DATA(sd)->obj, 0);
3205 /* common layout sizing won't apply here */
3207 _elm_gengrid_smart_sizing_eval(Evas_Object *obj __UNUSED__)
3213 _elm_gengrid_smart_add(Evas_Object *obj)
3215 EVAS_SMART_DATA_ALLOC(obj, Elm_Gengrid_Smart_Data);
3217 ELM_WIDGET_CLASS(_elm_gengrid_parent_sc)->base.add(obj);
3221 _elm_gengrid_smart_del(Evas_Object *obj)
3223 ELM_GENGRID_DATA_GET(obj, sd);
3225 elm_gengrid_clear(obj);
3226 evas_object_del(sd->pan_obj);
3229 if (sd->calc_job) ecore_job_del(sd->calc_job);
3231 ELM_WIDGET_CLASS(_elm_gengrid_parent_sc)->base.del(obj);
3235 _elm_gengrid_smart_move(Evas_Object *obj,
3239 ELM_GENGRID_DATA_GET(obj, sd);
3241 ELM_WIDGET_CLASS(_elm_gengrid_parent_sc)->base.move(obj, x, y);
3243 evas_object_move(sd->hit_rect, x, y);
3247 _elm_gengrid_smart_resize(Evas_Object *obj,
3251 ELM_GENGRID_DATA_GET(obj, sd);
3253 ELM_WIDGET_CLASS(_elm_gengrid_parent_sc)->base.resize(obj, w, h);
3255 evas_object_resize(sd->hit_rect, w, h);
3259 _elm_gengrid_smart_hide(Evas_Object *obj)
3261 ELM_GENGRID_DATA_GET(obj, sd);
3264 ELM_WIDGET_CLASS(_elm_gengrid_parent_sc)->base.hide(obj);
3266 evas_object_hide(sd->hit_rect);
3268 EINA_INLIST_FOREACH(sd->items, it)
3270 if (it->long_timer) ecore_timer_del(it->long_timer);
3271 it->long_timer = NULL;
3276 _elm_gengrid_smart_member_add(Evas_Object *obj,
3277 Evas_Object *member)
3279 ELM_GENGRID_DATA_GET(obj, sd);
3281 ELM_WIDGET_CLASS(_elm_gengrid_parent_sc)->base.member_add(obj, member);
3284 evas_object_raise(sd->hit_rect);
3288 _access_obj_process(Elm_Gengrid_Smart_Data * sd, Eina_Bool is_access)
3292 EINA_INLIST_FOREACH(sd->items, it)
3294 if (!it->realized) continue;
3295 if (is_access) _access_widget_item_register(it);
3297 _elm_access_widget_item_unregister((Elm_Widget_Item *)it);
3303 _access_hook(Evas_Object *obj, Eina_Bool is_access)
3305 ELM_GENGRID_CHECK(obj);
3306 ELM_GENGRID_DATA_GET(obj, sd);
3309 ELM_WIDGET_CLASS(ELM_WIDGET_DATA(sd)->api)->focus_next =
3310 _elm_gengrid_smart_focus_next;
3312 ELM_WIDGET_CLASS(ELM_WIDGET_DATA(sd)->api)->focus_next = NULL;
3314 _access_obj_process(sd, is_access);
3318 _elm_gengrid_smart_set_user(Elm_Gengrid_Smart_Class *sc)
3320 ELM_WIDGET_CLASS(sc)->base.add = _elm_gengrid_smart_add;
3321 ELM_WIDGET_CLASS(sc)->base.del = _elm_gengrid_smart_del;
3322 ELM_WIDGET_CLASS(sc)->base.move = _elm_gengrid_smart_move;
3323 ELM_WIDGET_CLASS(sc)->base.resize = _elm_gengrid_smart_resize;
3324 ELM_WIDGET_CLASS(sc)->base.hide = _elm_gengrid_smart_hide;
3325 ELM_WIDGET_CLASS(sc)->base.member_add = _elm_gengrid_smart_member_add;
3327 ELM_WIDGET_CLASS(sc)->on_focus = _elm_gengrid_smart_on_focus;
3328 ELM_WIDGET_CLASS(sc)->on_focus_region = _elm_gengrid_smart_on_focus_region;
3329 ELM_WIDGET_CLASS(sc)->theme = _elm_gengrid_smart_theme;
3330 ELM_WIDGET_CLASS(sc)->event = _elm_gengrid_smart_event;
3332 /* not a 'focus chain manager' */
3333 ELM_WIDGET_CLASS(sc)->focus_next = NULL;
3334 ELM_WIDGET_CLASS(sc)->focus_direction_manager_is = NULL;
3335 ELM_WIDGET_CLASS(sc)->focus_direction = NULL;
3336 ELM_WIDGET_CLASS(sc)->translate = _elm_gengrid_smart_translate;
3338 ELM_LAYOUT_CLASS(sc)->sizing_eval = _elm_gengrid_smart_sizing_eval;
3341 if (_elm_config->access_mode == ELM_ACCESS_MODE_ON)
3342 ELM_WIDGET_CLASS(sc)->focus_next = _elm_gengrid_smart_focus_next;
3344 ELM_WIDGET_CLASS(sc)->focus_next = NULL;
3346 ELM_WIDGET_CLASS(sc)->access = _access_hook;
3349 EAPI const Elm_Gengrid_Smart_Class *
3350 elm_gengrid_smart_class_get(void)
3352 static Elm_Gengrid_Smart_Class _sc =
3353 ELM_GENGRID_SMART_CLASS_INIT_NAME_VERSION(ELM_GENGRID_SMART_NAME);
3354 static const Elm_Gengrid_Smart_Class *class = NULL;
3355 Evas_Smart_Class *esc = (Evas_Smart_Class *)&_sc;
3360 _elm_gengrid_smart_set(&_sc);
3361 esc->callbacks = _smart_callbacks;
3368 elm_gengrid_add(Evas_Object *parent)
3371 Eina_Bool bounce = _elm_config->thumbscroll_bounce_enable;
3372 Elm_Gengrid_Pan_Smart_Data *pan_data;
3374 EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
3376 obj = elm_widget_add(_elm_gengrid_smart_class_new(), parent);
3377 if (!obj) return NULL;
3379 if (!elm_widget_sub_object_add(parent, obj))
3380 ERR("could not add %p as sub object of %p", obj, parent);
3382 ELM_GENGRID_DATA_GET(obj, sd);
3384 sd->hit_rect = evas_object_rectangle_add(evas_object_evas_get(obj));
3385 evas_object_smart_member_add(sd->hit_rect, obj);
3386 elm_widget_sub_object_add(obj, sd->hit_rect);
3388 /* common scroller hit rectangle setup */
3389 evas_object_color_set(sd->hit_rect, 0, 0, 0, 0);
3390 evas_object_show(sd->hit_rect);
3391 evas_object_repeat_events_set(sd->hit_rect, EINA_TRUE);
3393 elm_widget_can_focus_set(obj, EINA_TRUE);
3395 sd->calc_cb = (Ecore_Cb)_calc_job;
3399 elm_layout_theme_set(obj, "gengrid", "base", elm_widget_style_get(obj));
3401 /* interface's add() routine issued AFTER the object's smart_add() */
3402 sd->s_iface = evas_object_smart_interface_get
3403 (obj, ELM_SCROLLABLE_IFACE_NAME);
3405 sd->s_iface->objects_set
3406 (obj, ELM_WIDGET_DATA(sd)->resize_obj, sd->hit_rect);
3408 sd->old_h_bounce = bounce;
3409 sd->old_v_bounce = bounce;
3410 sd->s_iface->bounce_allow_set(obj, bounce, bounce);
3412 sd->s_iface->animate_start_cb_set(obj, _scroll_animate_start_cb);
3413 sd->s_iface->animate_stop_cb_set(obj, _scroll_animate_stop_cb);
3414 sd->s_iface->drag_start_cb_set(obj, _scroll_drag_start_cb);
3415 sd->s_iface->drag_stop_cb_set(obj, _scroll_drag_stop_cb);
3416 sd->s_iface->edge_left_cb_set(obj, _edge_left_cb);
3417 sd->s_iface->edge_right_cb_set(obj, _edge_right_cb);
3418 sd->s_iface->edge_top_cb_set(obj, _edge_top_cb);
3419 sd->s_iface->edge_bottom_cb_set(obj, _edge_bottom_cb);
3420 sd->s_iface->scroll_cb_set(obj, _scroll_cb);
3424 sd->highlight = EINA_TRUE;
3425 sd->longpress_timeout = _elm_config->longpress_timeout;
3427 #if GENGRID_FX_SUPPORT
3428 sd->fx_mode = EINA_TRUE;
3429 sd->rendered = EINA_FALSE;
3430 sd->fx_first_captured = EINA_FALSE;
3431 sd->fx_playing = EINA_FALSE;
3432 sd->gengrid_clearing = EINA_FALSE;
3435 sd->pan_obj = evas_object_smart_add
3436 (evas_object_evas_get(obj), _elm_gengrid_pan_smart_class_new());
3437 pan_data = evas_object_smart_data_get(sd->pan_obj);
3440 sd->s_iface->extern_pan_set(obj, sd->pan_obj);
3442 const char *str = edje_object_data_get(ELM_WIDGET_DATA(sd)->resize_obj,
3444 if ((str) && (!strcmp(str, "on")))
3445 elm_widget_highlight_in_theme_set(obj, EINA_TRUE);
3447 elm_widget_highlight_in_theme_set(obj, EINA_FALSE);
3448 sd->select_on_focus_enabled = EINA_FALSE;
3449 elm_widget_signal_callback_add(obj, "elm,action,focus_highlight,hide", "elm", _elm_gengrid_focus_highlight_hide, obj);
3450 elm_widget_signal_callback_add(obj, "elm,action,focus_highlight,show", "elm", _elm_gengrid_focus_highlight_show, obj);
3452 //Tizen Only: This should be removed when eo is applied.
3453 ELM_WIDGET_DATA_GET(obj, wsd);
3454 wsd->on_create = EINA_FALSE;
3460 elm_gengrid_item_size_set(Evas_Object *obj,
3464 ELM_GENGRID_CHECK(obj);
3465 ELM_GENGRID_DATA_GET(obj, sd);
3467 if ((sd->item_width == w) && (sd->item_height == h)) return;
3469 sd->item_height = h;
3470 if (sd->calc_job) ecore_job_del(sd->calc_job);
3471 sd->calc_job = ecore_job_add(_calc_job, sd);
3475 elm_gengrid_item_size_get(const Evas_Object *obj,
3479 ELM_GENGRID_CHECK(obj);
3480 ELM_GENGRID_DATA_GET(obj, sd);
3482 if (w) *w = sd->item_width;
3483 if (h) *h = sd->item_height;
3487 elm_gengrid_group_item_size_set(Evas_Object *obj,
3491 ELM_GENGRID_CHECK(obj);
3492 ELM_GENGRID_DATA_GET(obj, sd);
3494 if ((sd->group_item_width == w) && (sd->group_item_height == h)) return;
3495 sd->group_item_width = w;
3496 sd->group_item_height = h;
3497 if (sd->calc_job) ecore_job_del(sd->calc_job);
3498 sd->calc_job = ecore_job_add(_calc_job, sd);
3502 elm_gengrid_group_item_size_get(const Evas_Object *obj,
3506 ELM_GENGRID_CHECK(obj);
3507 ELM_GENGRID_DATA_GET(obj, sd);
3509 if (w) *w = sd->group_item_width;
3510 if (h) *h = sd->group_item_height;
3514 elm_gengrid_align_set(Evas_Object *obj,
3518 double old_h, old_y;
3520 ELM_GENGRID_CHECK(obj);
3521 ELM_GENGRID_DATA_GET(obj, sd);
3523 old_h = sd->align_x;
3524 old_y = sd->align_y;
3528 else if (align_x < 0.0)
3530 sd->align_x = align_x;
3534 else if (align_y < 0.0)
3536 sd->align_y = align_y;
3538 if ((old_h != sd->align_x) || (old_y != sd->align_y))
3539 evas_object_smart_calculate(sd->pan_obj);
3543 elm_gengrid_align_get(const Evas_Object *obj,
3547 ELM_GENGRID_CHECK(obj);
3548 ELM_GENGRID_DATA_GET(obj, sd);
3550 if (align_x) *align_x = sd->align_x;
3551 if (align_y) *align_y = sd->align_y;
3554 EAPI Elm_Object_Item *
3555 elm_gengrid_item_append(Evas_Object *obj,
3556 const Elm_Gengrid_Item_Class *itc,
3559 const void *func_data)
3563 ELM_GENGRID_CHECK(obj) NULL;
3564 ELM_GENGRID_DATA_GET(obj, sd);
3566 it = _elm_gengrid_item_new(sd, itc, data, func, func_data);
3567 if (!it) return NULL;
3569 sd->items = eina_inlist_append(sd->items, EINA_INLIST_GET(it));
3570 it->position = eina_inlist_count(sd->items);
3571 it->position_update = EINA_TRUE;
3574 sd->group_items = eina_list_prepend(sd->group_items, it);
3576 if (sd->calc_job) ecore_job_del(sd->calc_job);
3577 sd->calc_job = ecore_job_add(_calc_job, sd);
3579 return (Elm_Object_Item *)it;
3582 EAPI Elm_Object_Item *
3583 elm_gengrid_item_prepend(Evas_Object *obj,
3584 const Elm_Gengrid_Item_Class *itc,
3587 const void *func_data)
3591 ELM_GENGRID_CHECK(obj) NULL;
3592 ELM_GENGRID_DATA_GET(obj, sd);
3594 it = _elm_gengrid_item_new(sd, itc, data, func, func_data);
3595 if (!it) return NULL;
3597 sd->items = eina_inlist_prepend(sd->items, EINA_INLIST_GET(it));
3598 _item_position_update(sd->items, 0);
3601 sd->group_items = eina_list_append(sd->group_items, it);
3603 if (sd->calc_job) ecore_job_del(sd->calc_job);
3604 sd->calc_job = ecore_job_add(_calc_job, sd);
3606 return (Elm_Object_Item *)it;
3609 EAPI Elm_Object_Item *
3610 elm_gengrid_item_insert_before(Evas_Object *obj,
3611 const Elm_Gengrid_Item_Class *itc,
3613 Elm_Object_Item *relative,
3615 const void *func_data)
3620 ELM_GENGRID_CHECK(obj) NULL;
3621 ELM_GENGRID_ITEM_CHECK_OR_RETURN(relative, NULL);
3622 ELM_GENGRID_DATA_GET(obj, sd);
3624 it = _elm_gengrid_item_new(sd, itc, data, func, func_data);
3625 if (!it) return NULL;
3626 sd->items = eina_inlist_prepend_relative
3627 (sd->items, EINA_INLIST_GET(it),
3628 EINA_INLIST_GET((Elm_Gen_Item *)relative));
3629 tmp = eina_inlist_find(sd->items, EINA_INLIST_GET(it));
3630 _item_position_update(tmp, ((Elm_Gen_Item *)relative)->position);
3633 sd->group_items = eina_list_append_relative
3634 (sd->group_items, it, ((Elm_Gen_Item *)relative)->parent);
3636 if (sd->calc_job) ecore_job_del(sd->calc_job);
3637 sd->calc_job = ecore_job_add(_calc_job, sd);
3639 return (Elm_Object_Item *)it;
3642 EAPI Elm_Object_Item *
3643 elm_gengrid_item_insert_after(Evas_Object *obj,
3644 const Elm_Gengrid_Item_Class *itc,
3646 Elm_Object_Item *relative,
3648 const void *func_data)
3653 ELM_GENGRID_CHECK(obj) NULL;
3654 ELM_GENGRID_ITEM_CHECK_OR_RETURN(relative, NULL);
3655 ELM_GENGRID_DATA_GET(obj, sd);
3657 it = _elm_gengrid_item_new(sd, itc, data, func, func_data);
3658 if (!it) return NULL;
3659 sd->items = eina_inlist_append_relative
3660 (sd->items, EINA_INLIST_GET(it),
3661 EINA_INLIST_GET((Elm_Gen_Item *)relative));
3662 tmp = eina_inlist_find(sd->items, EINA_INLIST_GET(it));
3663 _item_position_update(tmp, ((Elm_Gen_Item *)relative)->position + 1);
3666 sd->group_items = eina_list_prepend_relative
3667 (sd->group_items, it, ((Elm_Gen_Item *)relative)->parent);
3669 if (sd->calc_job) ecore_job_del(sd->calc_job);
3670 sd->calc_job = ecore_job_add(_calc_job, sd);
3672 return (Elm_Object_Item *)it;
3675 EAPI Elm_Object_Item *
3676 elm_gengrid_item_sorted_insert(Evas_Object *obj,
3677 const Elm_Gengrid_Item_Class *itc,
3679 Eina_Compare_Cb comp,
3681 const void *func_data)
3685 ELM_GENGRID_CHECK(obj) NULL;
3686 ELM_GENGRID_DATA_GET(obj, sd);
3688 it = _elm_gengrid_item_new(sd, itc, data, func, func_data);
3689 if (!it) return NULL;
3693 sd->state = eina_inlist_sorted_state_new();
3694 eina_inlist_sorted_state_init(sd->state, sd->items);
3697 sd->item_compare_cb = comp;
3698 sd->items = eina_inlist_sorted_state_insert
3699 (sd->items, EINA_INLIST_GET(it), _elm_gengrid_item_compare, sd->state);
3700 _item_position_update(sd->items, 0);
3702 if (sd->calc_job) ecore_job_del(sd->calc_job);
3703 sd->calc_job = ecore_job_add(_calc_job, sd);
3705 return (Elm_Object_Item *)it;
3709 elm_gengrid_horizontal_set(Evas_Object *obj,
3710 Eina_Bool horizontal)
3712 ELM_GENGRID_CHECK(obj);
3713 ELM_GENGRID_DATA_GET(obj, sd);
3715 horizontal = !!horizontal;
3716 if (horizontal == sd->horizontal) return;
3717 sd->horizontal = horizontal;
3719 /* Update the items to conform to the new layout */
3720 if (sd->calc_job) ecore_job_del(sd->calc_job);
3721 sd->calc_job = ecore_job_add(_calc_job, sd);
3725 elm_gengrid_horizontal_get(const Evas_Object *obj)
3727 ELM_GENGRID_CHECK(obj) EINA_FALSE;
3728 ELM_GENGRID_DATA_GET(obj, sd);
3730 return sd->horizontal;
3734 elm_gengrid_clear(Evas_Object *obj)
3736 ELM_GENGRID_CHECK(obj);
3738 _elm_gengrid_clear(obj, EINA_FALSE);
3741 EINA_DEPRECATED EAPI const Evas_Object *
3742 elm_gengrid_item_object_get(const Elm_Object_Item *it)
3744 ELM_GENGRID_ITEM_CHECK_OR_RETURN(it, NULL);
3750 elm_gengrid_item_update(Elm_Object_Item *item)
3752 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
3754 ELM_GENGRID_ITEM_CHECK_OR_RETURN(it);
3756 if (!it->realized) return;
3757 if (it->want_unrealize) return;
3758 if (!VIEW(it)) return;
3762 Eina_List *texts = elm_widget_stringlist_get
3763 (edje_object_data_get(VIEW(it), "texts"));
3764 EINA_LIST_FREE(texts, part)
3765 edje_object_part_text_set(VIEW(it), part, NULL);
3766 EINA_LIST_FREE(it->content_objs, c)
3768 // FIXME: For animation, befor del, processing edc.
3769 if (evas_object_smart_type_check(c, "elm_layout"))
3770 edje_object_message_signal_process(elm_layout_edje_get(c));
3771 // FIXME: If parent-child relationship was broken before 'ic'
3772 // is deleted, freeze_pop will not be called. ex) elm_slider
3773 // If layout is used instead of edje, this problme can be
3775 if (0 != elm_widget_scroll_freeze_get(c))
3776 elm_widget_scroll_freeze_pop(c);
3780 _item_text_realize(it, VIEW(it), NULL);
3781 _item_state_realize(it, VIEW(it), NULL);
3782 it->content_objs = _item_content_realize(it, VIEW(it), it->content_objs, "contents", NULL);
3783 _item_state_realize(it, VIEW(it), NULL);
3786 edje_object_signal_emit(VIEW(it), "elm,state,selected", "elm");
3788 if (_focus_enabled(ELM_WIDGET_DATA(GG_IT(it)->wsd)->obj))
3790 if (GG_IT(it)->wsd->focused)
3791 edje_object_signal_emit (VIEW(GG_IT(it)->wsd->focused), "elm,action,focus_highlight,show", "elm");
3793 if (elm_widget_item_disabled_get(it))
3794 edje_object_signal_emit(VIEW(it), "elm,state,disabled", "elm");
3797 EAPI const Elm_Gengrid_Item_Class *
3798 elm_gengrid_item_item_class_get(const Elm_Object_Item *it)
3800 Elm_Gen_Item *item = (Elm_Gen_Item *)it;
3802 ELM_GENGRID_ITEM_CHECK_OR_RETURN(it, NULL);
3804 if (item->generation < GG_IT(item)->wsd->generation) return NULL;
3809 elm_gengrid_item_fields_update(Elm_Object_Item *item,
3811 Elm_Gengrid_Item_Field_Type itf)
3813 ELM_GENGRID_ITEM_CHECK_OR_RETURN(item);
3814 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
3816 if ((!itf) || (itf & ELM_GENGRID_ITEM_FIELD_TEXT))
3818 _item_text_realize(it, VIEW(it), parts);
3820 if ((!itf) || (itf & ELM_GENGRID_ITEM_FIELD_CONTENT))
3822 it->content_objs = _item_content_realize
3823 (it, VIEW(it), it->content_objs, "contents", parts);
3825 if ((!itf) || (itf & ELM_GENGRID_ITEM_FIELD_STATE))
3827 _item_state_realize(it, VIEW(it), parts);
3832 elm_gengrid_item_item_class_update(Elm_Object_Item *item,
3833 const Elm_Gengrid_Item_Class *itc)
3835 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
3837 ELM_GENGRID_ITEM_CHECK_OR_RETURN(it);
3838 EINA_SAFETY_ON_NULL_RETURN(itc);
3840 if (it->generation < GG_IT(it)->wsd->generation) return;
3842 _view_theme_update(it);
3843 elm_gengrid_item_update(item);
3847 elm_gengrid_item_pos_get(const Elm_Object_Item *it,
3851 ELM_GENGRID_ITEM_CHECK_OR_RETURN(it);
3853 if (x) *x = ((Elm_Gen_Item *)it)->x;
3854 if (y) *y = ((Elm_Gen_Item *)it)->y;
3858 elm_gengrid_multi_select_set(Evas_Object *obj,
3861 ELM_GENGRID_CHECK(obj);
3862 ELM_GENGRID_DATA_GET(obj, sd);
3864 sd->multi = !!multi;
3865 if (!sd->multi && sd->selected)
3869 Elm_Gen_Item *last = sd->selected->data;
3870 EINA_LIST_FOREACH_SAFE(sd->selected, l, ll, it)
3871 if (last != it) _item_unselect(it);
3876 elm_gengrid_multi_select_get(const Evas_Object *obj)
3878 ELM_GENGRID_CHECK(obj) EINA_FALSE;
3879 ELM_GENGRID_DATA_GET(obj, sd);
3884 EAPI Elm_Object_Item *
3885 elm_gengrid_selected_item_get(const Evas_Object *obj)
3887 ELM_GENGRID_CHECK(obj) NULL;
3888 ELM_GENGRID_DATA_GET(obj, sd);
3890 if (sd->selected) return sd->selected->data;
3894 EAPI const Eina_List *
3895 elm_gengrid_selected_items_get(const Evas_Object *obj)
3897 ELM_GENGRID_CHECK(obj) NULL;
3898 ELM_GENGRID_DATA_GET(obj, sd);
3900 return sd->selected;
3904 elm_gengrid_item_selected_set(Elm_Object_Item *item,
3907 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
3908 ELM_GENGRID_ITEM_CHECK_OR_RETURN(it);
3910 if ((it->generation < GG_IT(it)->wsd->generation) ||
3911 elm_widget_item_disabled_get(it))
3913 if (selected) _item_highlight(it);
3914 else _item_unhighlight(it);
3916 if (it->selected == selected) return;
3918 if (selected) _item_select(it);
3919 else _item_unselect(it);
3923 elm_gengrid_item_selected_get(const Elm_Object_Item *it)
3925 ELM_GENGRID_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
3927 return ((Elm_Gen_Item *)it)->selected;
3931 elm_gengrid_realized_items_get(const Evas_Object *obj)
3933 Eina_List *list = NULL;
3936 ELM_GENGRID_CHECK(obj) NULL;
3937 ELM_GENGRID_DATA_GET(obj, sd);
3939 EINA_INLIST_FOREACH(sd->items, it)
3941 if (it->realized) list = eina_list_append(list, (Elm_Object_Item *)it);
3947 elm_gengrid_realized_items_update(Evas_Object *obj)
3949 Eina_List *list, *l;
3950 Elm_Object_Item *it;
3952 ELM_GENGRID_CHECK(obj);
3954 list = elm_gengrid_realized_items_get(obj);
3955 EINA_LIST_FOREACH(list, l, it)
3956 elm_gengrid_item_update(it);
3959 static Evas_Object *
3960 _elm_gengrid_item_label_create(void *data,
3961 Evas_Object *obj __UNUSED__,
3962 Evas_Object *tooltip,
3963 void *it __UNUSED__)
3965 Evas_Object *label = elm_label_add(tooltip);
3968 elm_object_style_set(label, "tooltip");
3969 elm_object_text_set(label, data);
3974 _elm_gengrid_item_label_del_cb(void *data,
3975 Evas_Object *obj __UNUSED__,
3976 void *event_info __UNUSED__)
3978 eina_stringshare_del(data);
3982 elm_gengrid_item_tooltip_text_set(Elm_Object_Item *it,
3985 ELM_GENGRID_ITEM_CHECK_OR_RETURN(it);
3987 text = eina_stringshare_add(text);
3988 elm_gengrid_item_tooltip_content_cb_set
3989 (it, _elm_gengrid_item_label_create, text,
3990 _elm_gengrid_item_label_del_cb);
3994 elm_gengrid_item_tooltip_content_cb_set(Elm_Object_Item *item,
3995 Elm_Tooltip_Item_Content_Cb func,
3997 Evas_Smart_Cb del_cb)
3999 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
4001 ELM_GENGRID_ITEM_CHECK_OR_GOTO(it, error);
4003 if ((it->tooltip.content_cb == func) && (it->tooltip.data == data))
4006 if (it->tooltip.del_cb)
4007 it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
4008 it->tooltip.content_cb = func;
4009 it->tooltip.data = data;
4010 it->tooltip.del_cb = del_cb;
4013 elm_widget_item_tooltip_content_cb_set
4014 (it, it->tooltip.content_cb, it->tooltip.data, NULL);
4015 elm_widget_item_tooltip_style_set(it, it->tooltip.style);
4016 elm_widget_item_tooltip_window_mode_set(it, it->tooltip.free_size);
4022 if (del_cb) del_cb((void *)data, NULL, NULL);
4026 elm_gengrid_item_tooltip_unset(Elm_Object_Item *item)
4028 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
4030 ELM_GENGRID_ITEM_CHECK_OR_RETURN(it);
4032 if ((VIEW(it)) && (it->tooltip.content_cb))
4033 elm_widget_item_tooltip_unset(it);
4035 if (it->tooltip.del_cb)
4036 it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
4037 it->tooltip.del_cb = NULL;
4038 it->tooltip.content_cb = NULL;
4039 it->tooltip.data = NULL;
4040 it->tooltip.free_size = EINA_FALSE;
4041 if (it->tooltip.style)
4042 elm_gengrid_item_tooltip_style_set(item, NULL);
4046 elm_gengrid_item_tooltip_style_set(Elm_Object_Item *it,
4049 ELM_GENGRID_ITEM_CHECK_OR_RETURN(it);
4051 eina_stringshare_replace(&((Elm_Gen_Item *)it)->tooltip.style, style);
4052 if (VIEW(it)) elm_widget_item_tooltip_style_set(it, style);
4056 elm_gengrid_item_tooltip_style_get(const Elm_Object_Item *it)
4058 ELM_GENGRID_ITEM_CHECK_OR_RETURN(it, NULL);
4060 return ((Elm_Gen_Item *)it)->tooltip.style;
4064 elm_gengrid_item_tooltip_window_mode_set(Elm_Object_Item *it,
4067 ELM_GENGRID_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
4069 ((Elm_Gen_Item *)it)->tooltip.free_size = disable;
4070 if (VIEW(it)) return elm_widget_item_tooltip_window_mode_set(it, disable);
4076 elm_gengrid_item_tooltip_window_mode_get(const Elm_Object_Item *it)
4078 ELM_GENGRID_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
4080 return ((Elm_Gen_Item *)it)->tooltip.free_size;
4084 elm_gengrid_item_cursor_set(Elm_Object_Item *it,
4087 ELM_GENGRID_ITEM_CHECK_OR_RETURN(it);
4089 eina_stringshare_replace(&((Elm_Gen_Item *)it)->mouse_cursor, cursor);
4090 if (VIEW(it)) elm_widget_item_cursor_set(it, cursor);
4094 elm_gengrid_item_cursor_get(const Elm_Object_Item *it)
4096 return elm_widget_item_cursor_get(it);
4100 elm_gengrid_item_cursor_unset(Elm_Object_Item *item)
4102 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
4104 ELM_GENGRID_ITEM_CHECK_OR_RETURN(it);
4105 if (!it->mouse_cursor)
4109 elm_widget_item_cursor_unset(it);
4111 eina_stringshare_del(it->mouse_cursor);
4112 it->mouse_cursor = NULL;
4116 elm_gengrid_item_cursor_style_set(Elm_Object_Item *it,
4119 elm_widget_item_cursor_style_set(it, style);
4123 elm_gengrid_item_cursor_style_get(const Elm_Object_Item *it)
4125 return elm_widget_item_cursor_style_get(it);
4129 elm_gengrid_item_cursor_engine_only_set(Elm_Object_Item *it,
4130 Eina_Bool engine_only)
4132 elm_widget_item_cursor_engine_only_set(it, engine_only);
4136 elm_gengrid_item_cursor_engine_only_get(const Elm_Object_Item *it)
4138 return elm_widget_item_cursor_engine_only_get(it);
4142 elm_gengrid_reorder_mode_set(Evas_Object *obj,
4143 Eina_Bool reorder_mode)
4145 ELM_GENGRID_CHECK(obj);
4146 ELM_GENGRID_DATA_GET(obj, sd);
4148 sd->reorder_mode = !!reorder_mode;
4152 elm_gengrid_reorder_mode_get(const Evas_Object *obj)
4154 ELM_GENGRID_CHECK(obj) EINA_FALSE;
4155 ELM_GENGRID_DATA_GET(obj, sd);
4157 return sd->reorder_mode;
4161 elm_gengrid_bounce_set(Evas_Object *obj,
4165 ELM_GENGRID_CHECK(obj);
4166 ELM_GENGRID_DATA_GET(obj, sd);
4168 sd->s_iface->bounce_allow_set(obj, !!h_bounce, !!v_bounce);
4172 elm_gengrid_bounce_get(const Evas_Object *obj,
4173 Eina_Bool *h_bounce,
4174 Eina_Bool *v_bounce)
4176 ELM_GENGRID_CHECK(obj);
4177 ELM_GENGRID_DATA_GET(obj, sd);
4179 sd->s_iface->bounce_allow_get(obj, h_bounce, v_bounce);
4183 elm_gengrid_page_relative_set(Evas_Object *obj,
4187 Evas_Coord pagesize_h;
4188 Evas_Coord pagesize_v;
4190 ELM_GENGRID_CHECK(obj);
4191 ELM_GENGRID_DATA_GET(obj, sd);
4193 sd->s_iface->paging_get(obj, NULL, NULL, &pagesize_h, &pagesize_v);
4194 sd->s_iface->paging_set
4195 (obj, h_pagerel, v_pagerel, pagesize_h, pagesize_v);
4199 elm_gengrid_page_relative_get(const Evas_Object *obj,
4203 ELM_GENGRID_CHECK(obj);
4204 ELM_GENGRID_DATA_GET(obj, sd);
4206 sd->s_iface->paging_get(obj, h_pagerel, v_pagerel, NULL, NULL);
4210 elm_gengrid_page_size_set(Evas_Object *obj,
4211 Evas_Coord h_pagesize,
4212 Evas_Coord v_pagesize)
4217 ELM_GENGRID_CHECK(obj);
4218 ELM_GENGRID_DATA_GET(obj, sd);
4220 sd->s_iface->paging_get(obj, &pagerel_h, &pagerel_v, NULL, NULL);
4221 sd->s_iface->paging_set
4222 (obj, pagerel_h, pagerel_v, h_pagesize, v_pagesize);
4226 elm_gengrid_current_page_get(const Evas_Object *obj,
4230 ELM_GENGRID_CHECK(obj);
4231 ELM_GENGRID_DATA_GET(obj, sd);
4233 sd->s_iface->current_page_get(obj, h_pagenumber, v_pagenumber);
4237 elm_gengrid_last_page_get(const Evas_Object *obj,
4241 ELM_GENGRID_CHECK(obj);
4242 ELM_GENGRID_DATA_GET(obj, sd);
4244 sd->s_iface->last_page_get(obj, h_pagenumber, v_pagenumber);
4248 elm_gengrid_page_show(const Evas_Object *obj,
4252 ELM_GENGRID_CHECK(obj);
4253 ELM_GENGRID_DATA_GET(obj, sd);
4255 sd->s_iface->page_show((Evas_Object *)obj, h_pagenumber, v_pagenumber);
4259 elm_gengrid_page_bring_in(const Evas_Object *obj,
4263 ELM_GENGRID_CHECK(obj);
4264 ELM_GENGRID_DATA_GET(obj, sd);
4266 sd->s_iface->page_bring_in((Evas_Object *)obj, h_pagenumber, v_pagenumber);
4270 elm_gengrid_longpress_timeout_set(Evas_Object *obj,
4273 ELM_GENGRID_CHECK(obj);
4274 ELM_GENGRID_DATA_GET(obj, sd);
4276 sd->longpress_timeout = timeout;
4280 elm_gengrid_longpress_timeout_get(const Evas_Object *obj)
4282 ELM_GENGRID_CHECK(obj);
4283 ELM_GENGRID_DATA_GET(obj, sd);
4285 return sd->longpress_timeout;
4289 elm_gengrid_scroller_policy_set(Evas_Object *obj,
4290 Elm_Scroller_Policy policy_h,
4291 Elm_Scroller_Policy policy_v)
4293 ELM_GENGRID_CHECK(obj);
4294 ELM_GENGRID_DATA_GET(obj, sd);
4296 if ((policy_h >= ELM_SCROLLER_POLICY_LAST) ||
4297 (policy_v >= ELM_SCROLLER_POLICY_LAST))
4300 sd->s_iface->policy_set(obj, policy_h, policy_v);
4304 elm_gengrid_scroller_policy_get(const Evas_Object *obj,
4305 Elm_Scroller_Policy *policy_h,
4306 Elm_Scroller_Policy *policy_v)
4308 Elm_Scroller_Policy s_policy_h, s_policy_v;
4310 ELM_GENGRID_CHECK(obj);
4311 ELM_GENGRID_DATA_GET(obj, sd);
4313 sd->s_iface->policy_get(obj, &s_policy_h, &s_policy_v);
4314 if (policy_h) *policy_h = (Elm_Scroller_Policy)s_policy_h;
4315 if (policy_v) *policy_v = (Elm_Scroller_Policy)s_policy_v;
4318 EAPI Elm_Object_Item *
4319 elm_gengrid_first_item_get(const Evas_Object *obj)
4321 ELM_GENGRID_CHECK(obj) NULL;
4322 ELM_GENGRID_DATA_GET_OR_RETURN_VAL(obj, sd, NULL);
4324 if (!sd->items) return NULL;
4326 Elm_Gen_Item *it = ELM_GEN_ITEM_FROM_INLIST(sd->items);
4328 while ((it) && (it->generation < sd->generation))
4329 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
4331 return (Elm_Object_Item *)it;
4334 EAPI Elm_Object_Item *
4335 elm_gengrid_at_xy_item_get(const Evas_Object *obj,
4341 ELM_GENGRID_CHECK(obj) NULL;
4342 ELM_GENGRID_DATA_GET_OR_RETURN_VAL(obj, sd, NULL);
4344 Elm_Gen_Item *it = ELM_GEN_ITEM_FROM_INLIST(sd->items);
4346 Evas_Coord l = 0, r = 0, t = 0, b = 0; /* left, right, top, bottom */
4347 Eina_Bool init = EINA_TRUE;
4349 while ((it) && (it->generation < sd->generation))
4350 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
4355 Evas_Coord itx, ity;
4356 Evas_Coord itw, ith;
4357 evas_object_geometry_get(VIEW(it), &itx, &ity, &itw, &ith);
4359 /* Record leftmost, rightmost, top, bottom cords to set posret */
4360 if ((itw > 0) && (ith > 0) && (itx >= 0) && (ity >= 0))
4361 { /* A scroller, ignore items in negative cords,or not rendered */
4374 if ((itx + itw) > r)
4378 if ((ity + ith) > b)
4383 if (ELM_RECTS_INTERSECT
4384 (itx, ity, itw, ith, x, y, 1, 1))
4388 if (y <= (ity + (ith / 4))) *yposret = -1;
4389 else if (y >= (ity + ith - (ith / 4)))
4396 if (x <= (itx + (itw / 4))) *xposret = -1;
4397 else if (x >= (itx + itw - (itw / 4)))
4402 return (Elm_Object_Item *) it;
4405 } while ((it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next)));
4407 /* No item found, tell the user if hit left/right/top/bottom of items */
4429 EAPI Elm_Object_Item *
4430 elm_gengrid_last_item_get(const Evas_Object *obj)
4432 ELM_GENGRID_CHECK(obj) NULL;
4433 ELM_GENGRID_DATA_GET_OR_RETURN_VAL(obj, sd, NULL);
4435 if (!sd->items) return NULL;
4437 Elm_Gen_Item *it = ELM_GEN_ITEM_FROM_INLIST(sd->items->last);
4438 while ((it) && (it->generation < sd->generation))
4439 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
4441 return (Elm_Object_Item *)it;
4444 EAPI Elm_Object_Item *
4445 elm_gengrid_item_next_get(const Elm_Object_Item *item)
4447 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
4449 ELM_GENGRID_ITEM_CHECK_OR_RETURN(it, NULL);
4453 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
4454 if ((it) && (it->generation == GG_IT(it)->wsd->generation)) break;
4457 return (Elm_Object_Item *)it;
4460 EAPI Elm_Object_Item *
4461 elm_gengrid_item_prev_get(const Elm_Object_Item *item)
4463 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
4465 ELM_GENGRID_ITEM_CHECK_OR_RETURN(it, NULL);
4469 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
4470 if ((it) && (it->generation == GG_IT(it)->wsd->generation)) break;
4473 return (Elm_Object_Item *)it;
4477 elm_gengrid_item_show(Elm_Object_Item *item,
4478 Elm_Gengrid_Item_Scrollto_Type type)
4480 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
4481 Elm_Gengrid_Smart_Data *sd;
4483 ELM_GENGRID_ITEM_CHECK_OR_RETURN(it);
4484 sd = GG_IT(it)->wsd;
4486 if ((it->generation < sd->generation)) return;
4488 sd->show_region = EINA_TRUE;
4490 sd->scroll_to_type = type;
4492 if (sd->calc_job) ecore_job_del(sd->calc_job);
4493 sd->calc_job = ecore_job_add(_calc_job, sd);
4497 elm_gengrid_item_bring_in(Elm_Object_Item *item,
4498 Elm_Gengrid_Item_Scrollto_Type type)
4500 Elm_Gengrid_Smart_Data *sd;
4501 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
4503 ELM_GENGRID_ITEM_CHECK_OR_RETURN(it);
4504 sd = GG_IT(it)->wsd;
4506 if (it->generation < sd->generation) return;
4508 sd->bring_in = EINA_TRUE;
4509 sd->bring_in_it = it;
4510 sd->scroll_to_type = type;
4512 if (sd->calc_job) ecore_job_del(sd->calc_job);
4513 sd->calc_job = ecore_job_add(_calc_job, sd);
4517 elm_gengrid_filled_set(Evas_Object *obj,
4520 ELM_GENGRID_CHECK(obj);
4521 ELM_GENGRID_DATA_GET(obj, sd);
4524 if (sd->filled != fill)
4529 elm_gengrid_filled_get(const Evas_Object *obj)
4531 ELM_GENGRID_CHECK(obj) EINA_FALSE;
4532 ELM_GENGRID_DATA_GET(obj, sd);
4538 elm_gengrid_items_count(const Evas_Object *obj)
4540 ELM_GENGRID_CHECK(obj) 0;
4541 ELM_GENGRID_DATA_GET(obj, sd);
4543 return sd->item_count;
4546 EAPI Elm_Gengrid_Item_Class *
4547 elm_gengrid_item_class_new(void)
4549 Elm_Gengrid_Item_Class *itc;
4551 itc = calloc(1, sizeof(Elm_Gengrid_Item_Class));
4554 itc->version = CLASS_ALLOCATED;
4556 itc->delete_me = EINA_FALSE;
4562 elm_gengrid_item_class_free(Elm_Gengrid_Item_Class *itc)
4564 if (!itc || (itc->version != CLASS_ALLOCATED)) return;
4566 if (!itc->delete_me) itc->delete_me = EINA_TRUE;
4567 if (itc->refcount > 0) elm_gengrid_item_class_unref(itc);
4576 elm_gengrid_item_class_ref(Elm_Gengrid_Item_Class *itc)
4578 if (itc && (itc->version == CLASS_ALLOCATED))
4581 if (itc->refcount == 0) itc->refcount--;
4586 elm_gengrid_item_class_unref(Elm_Gengrid_Item_Class *itc)
4588 if (itc && (itc->version == CLASS_ALLOCATED))
4590 if (itc->refcount > 0) itc->refcount--;
4591 if (itc->delete_me && (!itc->refcount))
4592 elm_gengrid_item_class_free(itc);
4597 elm_gengrid_select_mode_set(Evas_Object *obj,
4598 Elm_Object_Select_Mode mode)
4600 ELM_GENGRID_CHECK(obj);
4601 ELM_GENGRID_DATA_GET(obj, sd);
4603 if (mode >= ELM_OBJECT_SELECT_MODE_MAX)
4606 if (sd->select_mode != mode)
4607 sd->select_mode = mode;
4610 EAPI Elm_Object_Select_Mode
4611 elm_gengrid_select_mode_get(const Evas_Object *obj)
4613 ELM_GENGRID_CHECK(obj) ELM_OBJECT_SELECT_MODE_MAX;
4614 ELM_GENGRID_DATA_GET(obj, sd);
4616 return sd->select_mode;
4620 elm_gengrid_highlight_mode_set(Evas_Object *obj,
4621 Eina_Bool highlight)
4623 ELM_GENGRID_CHECK(obj);
4624 ELM_GENGRID_DATA_GET(obj, sd);
4626 sd->highlight = !!highlight;
4630 elm_gengrid_highlight_mode_get(const Evas_Object *obj)
4632 ELM_GENGRID_CHECK(obj) EINA_FALSE;
4633 ELM_GENGRID_DATA_GET(obj, sd);
4635 return sd->highlight;
4639 elm_gengrid_item_index_get(const Elm_Object_Item *item)
4641 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
4643 ELM_GENGRID_ITEM_CHECK_OR_RETURN(it, -1);
4645 return it->position;
4649 elm_gengrid_item_select_mode_set(Elm_Object_Item *item,
4650 Elm_Object_Select_Mode mode)
4652 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
4654 ELM_GENGRID_ITEM_CHECK_OR_RETURN(it);
4656 if (it->generation < GG_IT(it)->wsd->generation) return;
4657 if (mode >= ELM_OBJECT_SELECT_MODE_MAX)
4660 if (it->select_mode != mode)
4661 it->select_mode = mode;
4663 if (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
4664 elm_gengrid_item_update(item);
4667 EAPI Elm_Object_Select_Mode
4668 elm_gengrid_item_select_mode_get(const Elm_Object_Item *item)
4670 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
4672 ELM_GENGRID_ITEM_CHECK_OR_RETURN(it, ELM_OBJECT_SELECT_MODE_MAX);
4674 return it->select_mode;
4677 #if GENGRID_FX_SUPPORT
4679 elm_gengrid_fx_mode_set(Evas_Object *obj, Eina_Bool mode)
4681 ELM_GENGRID_CHECK(obj);
4682 ELM_GENGRID_DATA_GET(obj, sd);
4688 elm_gengrid_fx_mode_get(const Evas_Object *obj)
4690 ELM_GENGRID_CHECK(obj) EINA_FALSE;
4691 ELM_GENGRID_DATA_GET(obj, sd);
4697 _elm_gengrid_proxy_item_new(const Elm_Object_Item *item)
4699 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
4700 if ((!it) || (!it->item)) return EINA_FALSE;
4703 Proxy_Item *pi = NULL;
4704 pi = calloc(1, sizeof(Proxy_Item));
4705 if (!pi) return NULL;
4707 pi->proxy = evas_object_image_filled_add
4708 (evas_object_evas_get(ELM_WIDGET_DATA(GG_IT(it)->wsd)->obj));
4714 evas_object_clip_set(pi->proxy, evas_object_clip_get(GG_IT(it)->wsd->pan_obj));
4715 evas_object_smart_member_add(pi->proxy, GG_IT(it)->wsd->pan_obj);
4716 evas_object_hide(pi->proxy);
4717 evas_object_image_source_set(pi->proxy, VIEW(it));
4719 GG_IT(it)->has_proxy_it = EINA_TRUE;
4721 pi->num = it->item->num;
4722 pi->x = it->item->scrl_x;
4723 pi->y = it->item->scrl_y;
4724 pi->w = it->item->w;
4725 pi->h = it->item->h;
4727 evas_object_geometry_get(VIEW(it), NULL, NULL, &w, &h);
4729 if (w <= 0 || h <= 0)
4731 evas_object_size_hint_min_get(VIEW(it), &w, &h);
4732 evas_object_size_hint_min_set(pi->proxy, w, h);
4734 else evas_object_resize(pi->proxy, w, h);
4740 _elm_gengrid_fx_capture(Evas_Object *obj, int level)
4742 ELM_GENGRID_DATA_GET(obj, sd);
4746 Evas_Coord ox, oy, ow, oh;
4748 if ((!sd->rendered) || (sd->fx_playing)) return EINA_FALSE;
4749 if ((!level) && (sd->fx_first_captured)) return EINA_FALSE;
4750 if ((level) && (!sd->fx_first_captured)) return EINA_FALSE;
4752 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
4756 sd->fx_first_captured = EINA_TRUE;
4757 EINA_LIST_FREE(sd->capture_before_items, pi)
4759 if (pi->proxy) evas_object_smart_member_del(pi->proxy);
4760 if (pi->proxy) evas_object_del(pi->proxy);
4766 EINA_LIST_FREE(sd->capture_after_items, pi)
4768 if (pi->proxy) evas_object_smart_member_del(pi->proxy);
4769 if (pi->proxy) evas_object_del(pi->proxy);
4773 EINA_INLIST_FOREACH(sd->items, it)
4777 pi = _elm_gengrid_proxy_item_new((Elm_Object_Item *)it);
4780 sd->capture_before_items = eina_list_append(sd->capture_before_items, pi);
4782 sd->capture_after_items = eina_list_append(sd->capture_after_items, pi);
4788 static Elm_Gen_FX_Item *
4789 _elm_gengrid_fx_item_find(const Elm_Object_Item *item)
4791 Elm_Gen_Item *it = (Elm_Gen_Item *)item;
4792 if (!it) return EINA_FALSE;
4794 Elm_Gengrid_Smart_Data *sd = GG_IT(it)->wsd;
4795 if (!sd) return NULL;
4797 Elm_Gen_FX_Item *fi = NULL;
4800 EINA_LIST_FOREACH(sd->fx_items, l, fi)
4802 if (fi->it == it) return fi;
4807 static Elm_Gen_FX_Item *
4808 _elm_gengrid_fx_item_new(const Proxy_Item *pi)
4810 if ((!pi) || (!pi->it)) return NULL;
4812 Elm_Gen_FX_Item *fi = NULL;
4813 fi = calloc(1, sizeof(Elm_Gen_FX_Item));
4814 if (!fi) return NULL;
4817 GG_IT(fi->it)->fi = fi;
4818 fi->proxy = pi->proxy;
4820 fi->from.x = fi->to.x = pi->x;
4821 fi->from.y = fi->to.y = pi->y;
4822 fi->from.w = fi->to.w = pi->w;
4823 fi->from.h = fi->to.h = pi->h;
4824 fi->update = EINA_FALSE;
4830 _elm_gengrid_fx_items_make(Evas_Object *obj)
4832 ELM_GENGRID_CHECK(obj);
4833 ELM_GENGRID_DATA_GET(obj, sd);
4835 Elm_Gen_FX_Item *fi;
4838 Evas_Coord ox, oy, ow, oh;
4840 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
4842 EINA_LIST_FOREACH(sd->capture_before_items, l, pi)
4844 fi = _elm_gengrid_fx_item_new(pi);
4845 if (fi) sd->fx_items = eina_list_append(sd->fx_items, fi);
4848 EINA_LIST_FOREACH(sd->capture_after_items, l, pi)
4850 fi = _elm_gengrid_fx_item_find((Elm_Object_Item *)pi->it);
4854 fi->type = ELM_GEN_ITEM_FX_TYPE_SAME;
4855 fi->update = EINA_TRUE;
4863 fi = _elm_gengrid_fx_item_new(pi);
4866 fi->type = ELM_GEN_ITEM_FX_TYPE_ADD;
4867 fi->update = EINA_TRUE;
4868 sd->fx_items = eina_list_append(sd->fx_items, fi);
4873 EINA_LIST_FOREACH(sd->fx_items, l, fi)
4877 fi->type = ELM_GEN_ITEM_FX_TYPE_DEL;
4878 fi->update = EINA_TRUE;
4884 _item_fx_op(Elm_Transit_Effect *data, Elm_Transit *transit __UNUSED__, double progress __UNUSED__)
4886 Elm_Gen_FX_Item *fi = data;
4887 evas_object_lower(fi->proxy);
4892 _item_fx_done(Elm_Transit_Effect *data, Elm_Transit *transit __UNUSED__)
4894 Elm_Gen_FX_Item *fx_done_it = data;
4895 Elm_Gengrid_Smart_Data *sd;
4897 if ((!fx_done_it) || (!fx_done_it->it)) return;
4899 sd = GG_IT(fx_done_it->it)->wsd;
4902 evas_object_image_source_visible_set(fx_done_it->proxy, EINA_TRUE);
4903 evas_object_lower(fx_done_it->proxy);
4905 evas_object_move(VIEW(fx_done_it->it), fx_done_it->to.x, fx_done_it->to.y);
4906 GG_IT(fx_done_it->it)->has_proxy_it = EINA_FALSE;
4908 evas_object_clip_unset(fx_done_it->proxy);
4912 _item_fx_del_cb(void *data, Elm_Transit *transit __UNUSED__)
4914 Elm_Gen_FX_Item *fx_done_it = data;
4915 Elm_Gen_Item *it = NULL;
4916 Proxy_Item *pi = NULL;
4918 Elm_Gengrid_Smart_Data *sd;
4919 Eina_Bool has_del_it = EINA_FALSE;
4921 if ((!fx_done_it) || (!fx_done_it->it)) return;
4923 sd = GG_IT(fx_done_it->it)->wsd;
4926 sd->fx_items = eina_list_remove(sd->fx_items, fx_done_it);
4929 if (!eina_list_count(sd->fx_items))
4931 EINA_LIST_FREE (sd->pending_unrealized_items, it)
4933 GG_IT(it)->has_proxy_it = EINA_FALSE;
4934 _elm_gengrid_item_unrealize(it, EINA_FALSE);
4937 EINA_LIST_FREE (sd->pending_del_items, it)
4939 _item_del_post_fx_process(it);
4940 elm_widget_item_free(it);
4941 has_del_it = EINA_TRUE;
4943 EINA_LIST_FOREACH(sd->capture_before_items, l, pi)
4944 evas_object_hide(pi->proxy);
4945 EINA_LIST_FOREACH(sd->capture_after_items, l, pi)
4946 evas_object_hide(pi->proxy);
4948 sd->fx_playing = EINA_FALSE;
4949 sd->fx_first_captured = EINA_FALSE;
4951 sd->pan_changed = EINA_TRUE;
4952 if (!has_del_it) evas_object_smart_changed(sd->pan_obj);
4957 _elm_gengrid_fx_play(Evas_Object *obj)
4959 ELM_GENGRID_CHECK(obj);
4960 ELM_GENGRID_DATA_GET(obj, sd);
4962 Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh;
4963 Elm_Gen_FX_Item *fi;
4966 if (!sd->fx_mode) return;
4968 EINA_LIST_FREE(sd->fx_items, fi)
4970 if (fi->trans) elm_transit_del(fi->trans);
4974 _elm_gengrid_fx_items_make(obj);
4975 if (!eina_list_count(sd->fx_items)) return;
4976 sd->fx_playing = EINA_TRUE;
4978 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
4979 evas_output_viewport_get(evas_object_evas_get(obj), &cvx, &cvy, &cvw, &cvh);
4981 EINA_LIST_FOREACH(sd->fx_items, l, fi)
4983 if (!fi->proxy) continue;
4985 if ((fi->from.y <= oy) || (fi->from.y + fi->from.h >= oy + oh))
4987 evas_object_move(VIEW(fi->it), fi->to.x, fi->to.y);
4989 else if ((fi->to.y <= oy) || (fi->to.y + fi->to.h >= oy + oh))
4991 evas_object_move(VIEW(fi->it), fi->from.x, fi->from.y);
4994 evas_object_resize(fi->proxy, fi->to.w, fi->to.h);
4995 evas_object_show(fi->proxy);
4997 fi->trans = elm_transit_add();
4998 elm_transit_object_add(fi->trans, fi->proxy);
4999 elm_transit_event_enabled_set(fi->trans, EINA_FALSE);
5001 evas_object_image_source_visible_set(fi->proxy, EINA_FALSE);
5002 elm_transit_tween_mode_set(fi->trans, ELM_TRANSIT_TWEEN_MODE_DECELERATE);
5004 if (fi->type == ELM_GEN_ITEM_FX_TYPE_SAME)
5006 evas_object_raise(fi->proxy);
5007 elm_transit_effect_translation_add(fi->trans, fi->from.x, fi->from.y, fi->to.x, fi->to.y);
5010 else if (fi->type == ELM_GEN_ITEM_FX_TYPE_ADD)
5012 elm_transit_effect_translation_add(fi->trans, fi->from.x, fi->from.y, fi->to.x, fi->to.y);
5013 elm_transit_effect_color_add(fi->trans, 0, 0, 0, 0, 255, 255, 255, 255);
5014 elm_transit_effect_zoom_add(fi->trans, 0.5, 1.0);
5016 else if (fi->type == ELM_GEN_ITEM_FX_TYPE_DEL)
5018 elm_transit_effect_translation_add(fi->trans, fi->from.x, fi->from.y, fi->to.x, fi->to.y);
5019 elm_transit_effect_color_add(fi->trans, 255, 255, 255, 255, 0, 0, 0, 0);
5020 elm_transit_effect_zoom_add(fi->trans, 1.0, 0.5);
5022 elm_transit_effect_add(fi->trans, _item_fx_op, fi, _item_fx_done);
5023 elm_transit_del_cb_set(fi->trans, _item_fx_del_cb, fi);
5025 elm_transit_duration_set(fi->trans, FX_MOVE_TIME);
5026 elm_transit_objects_final_state_keep_set(fi->trans, EINA_FALSE);
5027 elm_transit_go(fi->trans);