X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Flib%2Felm_gengrid.c;h=8ee50c47ccd1c5a53134ea56bc78f26f71d12c7f;hb=97e14e146c9feaf6b212dacef22bd0907c267b8a;hp=af2f4bea529dd2d247706c2d66fc4c1c430e1c8a;hpb=1743e43773ac4f78db65e854858b68fab96aa594;p=framework%2Fuifw%2Felementary.git diff --git a/src/lib/elm_gengrid.c b/src/lib/elm_gengrid.c index af2f4be..8ee50c4 100644 --- a/src/lib/elm_gengrid.c +++ b/src/lib/elm_gengrid.c @@ -2,104 +2,44 @@ #include #include "elm_priv.h" #include "els_scroller.h" +#include "elm_gen_common.h" - typedef struct _Widget_Data Widget_Data; - typedef struct _Pan Pan; +// internally allocated +#define CLASS_ALLOCATED 0x3a70f00f + +/* -- + * TODO: + * Handle non-homogeneous objects too. + */ #define PRELOAD 1 #define REORDER_EFFECT_TIME 0.5 - struct _Elm_Gengrid_Item -{ - ELM_WIDGET_ITEM; - EINA_INLIST; - Evas_Object *spacer; - const Elm_Gengrid_Item_Class *gic; - Ecore_Timer *long_timer; - Ecore_Animator *item_moving_effect_timer; - Widget_Data *wd; - Eina_List *labels, *icons, *states, *icon_objs; - struct - { - Evas_Smart_Cb func; - const void *data; - } func; - - Evas_Coord x, y, dx, dy, ox, oy, tx, ty, rx, ry; - unsigned int moving_effect_start_time; - int relcount; - int walking; - - struct - { - const void *data; - Elm_Tooltip_Item_Content_Cb content_cb; - Evas_Smart_Cb del_cb; - const char *style; - } tooltip; - - const char *mouse_cursor; - - Eina_Bool want_unrealize : 1; - Eina_Bool realized : 1; - Eina_Bool dragging : 1; - Eina_Bool down : 1; - Eina_Bool delete_me : 1; - Eina_Bool display_only : 1; - Eina_Bool disabled : 1; - Eina_Bool selected : 1; - Eina_Bool hilighted : 1; - Eina_Bool moving : 1; -}; - -struct _Widget_Data -{ - Evas_Object *self, *scr; - Evas_Object *pan_smart; - Pan *pan; - Eina_Inlist *items; - Ecore_Job *calc_job; - Eina_List *selected; - Elm_Gengrid_Item *last_selected_item, *reorder_item; - double align_x, align_y; - - Evas_Coord pan_x, pan_y, old_pan_x, old_pan_y; - Evas_Coord item_width, item_height; /* Each item size */ - Evas_Coord minw, minh; /* Total obj size */ - Evas_Coord reorder_item_x, reorder_item_y; - unsigned int nmax; - long count; - int walking; - - Eina_Bool horizontal : 1; - Eina_Bool on_hold : 1; - Eina_Bool longpressed : 1; - Eina_Bool multi : 1; - Eina_Bool no_select : 1; - Eina_Bool wasselected : 1; - Eina_Bool always_select : 1; - Eina_Bool clear_me : 1; - Eina_Bool h_bounce : 1; - Eina_Bool v_bounce : 1; - Eina_Bool reorder_mode : 1; - Eina_Bool reorder_item_changed : 1; - Eina_Bool move_effect_enabled : 1; -}; +#define ELM_GEN_SETUP(wd) \ + (wd)->calc_cb = (Ecore_Cb)_calc_job -#define ELM_GENGRID_ITEM_FROM_INLIST(it) \ - ((it) ? EINA_INLIST_CONTAINER_GET(it, Elm_Gengrid_Item) : NULL) +#define ELM_GEN_ITEM_SETUP(it) \ + (it)->del_cb = (Ecore_Cb)_item_del; \ + (it)->highlight_cb = (Ecore_Cb)_item_highlight; \ + (it)->unsel_cb = (Ecore_Cb)_item_unselect; \ + (it)->unrealize_cb = (Ecore_Cb)_item_unrealize_cb -struct _Pan +struct Elm_Gen_Item_Type { - Evas_Object_Smart_Clipped_Data __clipped_data; - Widget_Data *wd; + Elm_Gen_Item *it; + Ecore_Animator *item_reorder_move_animator; + Evas_Coord gx, gy, ox, oy, tx, ty, rx, ry; + unsigned int moving_effect_start_time; + int prev_group; + + Eina_Bool group_realized : 1; + Eina_Bool moving : 1; }; static const char *widtype = NULL; -static void _item_hilight(Elm_Gengrid_Item *it); -static void _item_unrealize(Elm_Gengrid_Item *it); -static void _item_select(Elm_Gengrid_Item *it); -static void _item_unselect(Elm_Gengrid_Item *it); +static void _item_highlight(Elm_Gen_Item *it); +static void _item_unrealize_cb(Elm_Gen_Item *it); +static void _item_unselect(Elm_Gen_Item *it); static void _calc_job(void *data); static void _on_focus_hook(void *data, Evas_Object *obj); @@ -120,7 +60,9 @@ static Eina_Bool _deselect_all_items(Widget_Data *wd); static Evas_Smart_Class _pan_sc = EVAS_SMART_CLASS_INIT_VERSION; static void _mirrored_set(Evas_Object *obj, Eina_Bool rtl); +static const char SIG_ACTIVATED[] = "activated"; static const char SIG_CLICKED_DOUBLE[] = "clicked,double"; +static const char SIG_LONGPRESSED[] = "longpressed"; static const char SIG_SELECTED[] = "selected"; static const char SIG_UNSELECTED[] = "unselected"; static const char SIG_REALIZED[] = "realized"; @@ -142,41 +84,41 @@ static const char SIG_EDGE_BOTTOM[] = "edge,bottom"; static const char SIG_EDGE_LEFT[] = "edge,left"; static const char SIG_EDGE_RIGHT[] = "edge,right"; static const char SIG_MOVED[] = "moved"; +static const char SIG_INDEX_UPDATE[] = "index,update"; static const Evas_Smart_Cb_Description _signals[] = { - {SIG_CLICKED_DOUBLE, ""}, - {SIG_SELECTED, ""}, - {SIG_UNSELECTED, ""}, - {SIG_REALIZED, ""}, - {SIG_UNREALIZED, ""}, - {SIG_CHANGED, ""}, - {SIG_DRAG_START_UP, ""}, - {SIG_DRAG_START_DOWN, ""}, - {SIG_DRAG_START_LEFT, ""}, - {SIG_DRAG_START_RIGHT, ""}, - {SIG_DRAG_STOP, ""}, - {SIG_DRAG, ""}, - {SIG_SCROLL, ""}, - {SIG_SCROLL_ANIM_START, ""}, - {SIG_SCROLL_ANIM_STOP, ""}, - {SIG_SCROLL_DRAG_START, ""}, - {SIG_SCROLL_DRAG_STOP, ""}, - {SIG_EDGE_TOP, ""}, - {SIG_EDGE_BOTTOM, ""}, - {SIG_EDGE_LEFT, ""}, - {SIG_EDGE_RIGHT, ""}, - {SIG_MOVED, ""}, - {NULL, NULL} + {SIG_ACTIVATED, ""}, + {SIG_CLICKED_DOUBLE, ""}, + {SIG_LONGPRESSED, ""}, + {SIG_SELECTED, ""}, + {SIG_UNSELECTED, ""}, + {SIG_REALIZED, ""}, + {SIG_UNREALIZED, ""}, + {SIG_CHANGED, ""}, + {SIG_DRAG_START_UP, ""}, + {SIG_DRAG_START_DOWN, ""}, + {SIG_DRAG_START_LEFT, ""}, + {SIG_DRAG_START_RIGHT, ""}, + {SIG_DRAG_STOP, ""}, + {SIG_DRAG, ""}, + {SIG_SCROLL, ""}, + {SIG_SCROLL_ANIM_START, ""}, + {SIG_SCROLL_ANIM_STOP, ""}, + {SIG_SCROLL_DRAG_START, ""}, + {SIG_SCROLL_DRAG_STOP, ""}, + {SIG_EDGE_TOP, ""}, + {SIG_EDGE_BOTTOM, ""}, + {SIG_EDGE_LEFT, ""}, + {SIG_EDGE_RIGHT, ""}, + {SIG_MOVED, ""}, + {NULL, NULL} }; -static Eina_Compare_Cb _elm_gengrid_item_compare_cb; -static Eina_Compare_Cb _elm_gengrid_item_compare_data_cb; - static Eina_Bool -_event_hook(Evas_Object *obj, - Evas_Object *src __UNUSED__, - Evas_Callback_Type type, - void *event_info) +_event_hook(Evas_Object *obj, + Evas_Object *src __UNUSED__, + Evas_Callback_Type type, + void *event_info) { if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE; Evas_Event_Key_Down *ev = event_info; @@ -186,7 +128,7 @@ _event_hook(Evas_Object *obj, if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE; if (elm_widget_disabled_get(obj)) return EINA_FALSE; - Elm_Gengrid_Item *it = NULL; + Elm_Object_Item *it = NULL; Evas_Coord x = 0; Evas_Coord y = 0; Evas_Coord step_x = 0; @@ -201,7 +143,8 @@ _event_hook(Evas_Object *obj, elm_smart_scroller_page_size_get(wd->scr, &page_x, &page_y); elm_smart_scroller_child_viewport_size_get(wd->scr, &v_w, &v_h); - if ((!strcmp(ev->keyname, "Left")) || (!strcmp(ev->keyname, "KP_Left"))) + if ((!strcmp(ev->keyname, "Left")) || + ((!strcmp(ev->keyname, "KP_Left")) && (!ev->string))) { if ((wd->horizontal) && (((evas_key_modifier_is_set(ev->modifiers, "Shift")) && @@ -222,7 +165,8 @@ _event_hook(Evas_Object *obj, else x -= step_x; } - else if ((!strcmp(ev->keyname, "Right")) || (!strcmp(ev->keyname, "KP_Right"))) + else if ((!strcmp(ev->keyname, "Right")) || + ((!strcmp(ev->keyname, "KP_Right")) && (!ev->string))) { if ((wd->horizontal) && (((evas_key_modifier_is_set(ev->modifiers, "Shift")) && @@ -243,7 +187,8 @@ _event_hook(Evas_Object *obj, else x += step_x; } - else if ((!strcmp(ev->keyname, "Up")) || (!strcmp(ev->keyname, "KP_Up"))) + else if ((!strcmp(ev->keyname, "Up")) || + ((!strcmp(ev->keyname, "KP_Up")) && (!ev->string))) { if ((wd->horizontal) && (((evas_key_modifier_is_set(ev->modifiers, "Shift")) && @@ -264,7 +209,8 @@ _event_hook(Evas_Object *obj, else y -= step_y; } - else if ((!strcmp(ev->keyname, "Down")) || (!strcmp(ev->keyname, "KP_Down"))) + else if ((!strcmp(ev->keyname, "Down")) || + ((!strcmp(ev->keyname, "KP_Down")) && (!ev->string))) { if ((wd->horizontal) && (((evas_key_modifier_is_set(ev->modifiers, "Shift")) && @@ -285,22 +231,26 @@ _event_hook(Evas_Object *obj, else y += step_y; } - else if ((!strcmp(ev->keyname, "Home")) || (!strcmp(ev->keyname, "KP_Home"))) + else if ((!strcmp(ev->keyname, "Home")) || + ((!strcmp(ev->keyname, "KP_Home")) && (!ev->string))) { it = elm_gengrid_first_item_get(obj); - elm_gengrid_item_bring_in(it); + elm_gengrid_item_bring_in(it, ELM_GENGRID_ITEM_SCROLLTO_IN); + elm_gengrid_item_selected_set(it, EINA_TRUE); ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD; return EINA_TRUE; } - else if ((!strcmp(ev->keyname, "End")) || (!strcmp(ev->keyname, "KP_End"))) + else if ((!strcmp(ev->keyname, "End")) || + ((!strcmp(ev->keyname, "KP_End")) && (!ev->string))) { it = elm_gengrid_last_item_get(obj); - elm_gengrid_item_bring_in(it); + elm_gengrid_item_bring_in(it, ELM_GENGRID_ITEM_SCROLLTO_IN); + elm_gengrid_item_selected_set(it, EINA_TRUE); ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD; return EINA_TRUE; } else if ((!strcmp(ev->keyname, "Prior")) || - (!strcmp(ev->keyname, "KP_Prior"))) + ((!strcmp(ev->keyname, "KP_Prior")) && (!ev->string))) { if (wd->horizontal) { @@ -317,7 +267,8 @@ _event_hook(Evas_Object *obj, y -= page_y; } } - else if ((!strcmp(ev->keyname, "Next")) || (!strcmp(ev->keyname, "KP_Next"))) + else if ((!strcmp(ev->keyname, "Next")) || + ((!strcmp(ev->keyname, "KP_Next")) && (!ev->string))) { if (wd->horizontal) { @@ -340,12 +291,13 @@ _event_hook(Evas_Object *obj, ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD; return EINA_TRUE; } - else if ((!strcmp(ev->keyname, "Return")) || - (!strcmp(ev->keyname, "KP_Enter")) || - (!strcmp(ev->keyname, "space"))) + else if (((!strcmp(ev->keyname, "Return")) || + (!strcmp(ev->keyname, "KP_Enter")) || + (!strcmp(ev->keyname, "space"))) + && (!wd->multi) && (wd->selected)) { it = elm_gengrid_selected_item_get(obj); - evas_object_smart_callback_call(it->wd->self, SIG_CLICKED_DOUBLE, it); + evas_object_smart_callback_call(WIDGET(it), SIG_ACTIVATED, it); } else return EINA_FALSE; @@ -358,8 +310,9 @@ static Eina_Bool _deselect_all_items(Widget_Data *wd) { if (!wd->selected) return EINA_FALSE; - while(wd->selected) - elm_gengrid_item_selected_set(wd->selected->data, EINA_FALSE); + while (wd->selected) + elm_gengrid_item_selected_set((Elm_Object_Item *) wd->selected->data, + EINA_FALSE); return EINA_TRUE; } @@ -369,18 +322,19 @@ _item_multi_select_left(Widget_Data *wd) { if (!wd->selected) return EINA_FALSE; - Elm_Gengrid_Item *prev = elm_gengrid_item_prev_get(wd->last_selected_item); + Elm_Object_Item *prev = + elm_gengrid_item_prev_get(wd->last_selected_item); if (!prev) return EINA_TRUE; if (elm_gengrid_item_selected_get(prev)) { elm_gengrid_item_selected_set(wd->last_selected_item, EINA_FALSE); wd->last_selected_item = prev; - elm_gengrid_item_show(wd->last_selected_item); + elm_gengrid_item_show(wd->last_selected_item, ELM_GENGRID_ITEM_SCROLLTO_IN); } else { elm_gengrid_item_selected_set(prev, EINA_TRUE); - elm_gengrid_item_show(prev); + elm_gengrid_item_show(prev, ELM_GENGRID_ITEM_SCROLLTO_IN); } return EINA_TRUE; @@ -391,18 +345,19 @@ _item_multi_select_right(Widget_Data *wd) { if (!wd->selected) return EINA_FALSE; - Elm_Gengrid_Item *next = elm_gengrid_item_next_get(wd->last_selected_item); + Elm_Object_Item *next = + elm_gengrid_item_next_get(wd->last_selected_item); if (!next) return EINA_TRUE; if (elm_gengrid_item_selected_get(next)) { elm_gengrid_item_selected_set(wd->last_selected_item, EINA_FALSE); wd->last_selected_item = next; - elm_gengrid_item_show(wd->last_selected_item); + elm_gengrid_item_show(wd->last_selected_item, ELM_GENGRID_ITEM_SCROLLTO_IN); } else { elm_gengrid_item_selected_set(next, EINA_TRUE); - elm_gengrid_item_show(next); + elm_gengrid_item_show(next, ELM_GENGRID_ITEM_SCROLLTO_IN); } return EINA_TRUE; @@ -441,32 +396,34 @@ _item_single_select_up(Widget_Data *wd) { unsigned int i; - Elm_Gengrid_Item *prev; + Elm_Gen_Item *prev; if (!wd->selected) { - prev = ELM_GENGRID_ITEM_FROM_INLIST(wd->items->last); - while ((prev) && (prev->delete_me)) - prev = ELM_GENGRID_ITEM_FROM_INLIST(EINA_INLIST_GET(prev)->prev); - elm_gengrid_item_selected_set(prev, EINA_TRUE); - elm_gengrid_item_show(prev); + prev = ELM_GEN_ITEM_FROM_INLIST(wd->items->last); + while ((prev) && (prev->generation < wd->generation)) + prev = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(prev)->prev); + elm_gengrid_item_selected_set((Elm_Object_Item *) prev, EINA_TRUE); + elm_gengrid_item_show((Elm_Object_Item *) prev, ELM_GENGRID_ITEM_SCROLLTO_IN); return EINA_TRUE; } - else prev = elm_gengrid_item_prev_get(wd->last_selected_item); + else + prev = (Elm_Gen_Item *) elm_gengrid_item_prev_get(wd->last_selected_item); if (!prev) return EINA_FALSE; for (i = 1; i < wd->nmax; i++) { - Elm_Gengrid_Item *tmp = elm_gengrid_item_prev_get(prev); + Elm_Object_Item *tmp = + elm_gengrid_item_prev_get((Elm_Object_Item *) prev); if (!tmp) return EINA_FALSE; - prev = tmp; + prev = (Elm_Gen_Item *) tmp; } _deselect_all_items(wd); - elm_gengrid_item_selected_set(prev, EINA_TRUE); - elm_gengrid_item_show(prev); + elm_gengrid_item_selected_set((Elm_Object_Item *) prev, EINA_TRUE); + elm_gengrid_item_show((Elm_Object_Item *) prev, ELM_GENGRID_ITEM_SCROLLTO_IN); return EINA_TRUE; } @@ -475,74 +432,78 @@ _item_single_select_down(Widget_Data *wd) { unsigned int i; - Elm_Gengrid_Item *next; + Elm_Gen_Item *next; if (!wd->selected) { - next = ELM_GENGRID_ITEM_FROM_INLIST(wd->items); - while ((next) && (next->delete_me)) - next = ELM_GENGRID_ITEM_FROM_INLIST(EINA_INLIST_GET(next)->next); - elm_gengrid_item_selected_set(next, EINA_TRUE); - elm_gengrid_item_show(next); + next = ELM_GEN_ITEM_FROM_INLIST(wd->items); + while ((next) && (next->generation < wd->generation)) + next = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(next)->next); + elm_gengrid_item_selected_set((Elm_Object_Item *) next, EINA_TRUE); + elm_gengrid_item_show((Elm_Object_Item *) next, ELM_GENGRID_ITEM_SCROLLTO_IN); return EINA_TRUE; } - else next = elm_gengrid_item_next_get(wd->last_selected_item); + else + next = (Elm_Gen_Item *) elm_gengrid_item_next_get(wd->last_selected_item); if (!next) return EINA_FALSE; for (i = 1; i < wd->nmax; i++) { - Elm_Gengrid_Item *tmp = elm_gengrid_item_next_get(next); + Elm_Object_Item *tmp = + elm_gengrid_item_next_get((Elm_Object_Item *) next); if (!tmp) return EINA_FALSE; - next = tmp; + next = (Elm_Gen_Item *) tmp; } _deselect_all_items(wd); - elm_gengrid_item_selected_set(next, EINA_TRUE); - elm_gengrid_item_show(next); + elm_gengrid_item_selected_set((Elm_Object_Item *) next, EINA_TRUE); + elm_gengrid_item_show((Elm_Object_Item *) next, ELM_GENGRID_ITEM_SCROLLTO_IN); return EINA_TRUE; } static Eina_Bool _item_single_select_left(Widget_Data *wd) { - Elm_Gengrid_Item *prev; + Elm_Gen_Item *prev; if (!wd->selected) { - prev = ELM_GENGRID_ITEM_FROM_INLIST(wd->items->last); - while ((prev) && (prev->delete_me)) - prev = ELM_GENGRID_ITEM_FROM_INLIST(EINA_INLIST_GET(prev)->prev); + prev = ELM_GEN_ITEM_FROM_INLIST(wd->items->last); + while ((prev) && (prev->generation < wd->generation)) + prev = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(prev)->prev); } - else prev = elm_gengrid_item_prev_get(wd->last_selected_item); + else + prev = (Elm_Gen_Item *) elm_gengrid_item_prev_get(wd->last_selected_item); if (!prev) return EINA_FALSE; _deselect_all_items(wd); - elm_gengrid_item_selected_set(prev, EINA_TRUE); - elm_gengrid_item_show(prev); + elm_gengrid_item_selected_set((Elm_Object_Item *) prev, EINA_TRUE); + elm_gengrid_item_show((Elm_Object_Item *) prev, ELM_GENGRID_ITEM_SCROLLTO_IN); return EINA_TRUE; } static Eina_Bool _item_single_select_right(Widget_Data *wd) { - Elm_Gengrid_Item *next; + Elm_Gen_Item *next; if (!wd->selected) { - next = ELM_GENGRID_ITEM_FROM_INLIST(wd->items); - while ((next) && (next->delete_me)) - next = ELM_GENGRID_ITEM_FROM_INLIST(EINA_INLIST_GET(next)->next); + next = ELM_GEN_ITEM_FROM_INLIST(wd->items); + while ((next) && (next->generation < wd->generation)) + next = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(next)->next); } - else next = elm_gengrid_item_next_get(wd->last_selected_item); + else + next = (Elm_Gen_Item *) elm_gengrid_item_next_get(wd->last_selected_item); if (!next) return EINA_FALSE; _deselect_all_items(wd); - elm_gengrid_item_selected_set(next, EINA_TRUE); - elm_gengrid_item_show(next); + elm_gengrid_item_selected_set((Elm_Object_Item *) next, EINA_TRUE); + elm_gengrid_item_show((Elm_Object_Item *) next, ELM_GENGRID_ITEM_SCROLLTO_IN); return EINA_TRUE; } @@ -554,15 +515,15 @@ _on_focus_hook(void *data __UNUSED__, if (!wd) return; if (elm_widget_focus_get(obj)) { - edje_object_signal_emit(wd->self, "elm,action,focus", "elm"); - evas_object_focus_set(wd->self, EINA_TRUE); + edje_object_signal_emit(wd->obj, "elm,action,focus", "elm"); + evas_object_focus_set(wd->obj, EINA_TRUE); if ((wd->selected) && (!wd->last_selected_item)) wd->last_selected_item = eina_list_data_get(wd->selected); } else { - edje_object_signal_emit(wd->self, "elm,action,unfocus", "elm"); - evas_object_focus_set(wd->self, EINA_FALSE); + edje_object_signal_emit(wd->obj, "elm,action,unfocus", "elm"); + evas_object_focus_set(wd->obj, EINA_FALSE); } } @@ -570,17 +531,17 @@ static void _mirrored_set(Evas_Object *obj, Eina_Bool rtl) { Widget_Data *wd = elm_widget_data_get(obj); - Elm_Gengrid_Item *it; + Elm_Gen_Item *it; if (!wd) return; elm_smart_scroller_mirrored_set(wd->scr, rtl); if (!wd->items) return; - it = ELM_GENGRID_ITEM_FROM_INLIST(wd->items); + it = ELM_GEN_ITEM_FROM_INLIST(wd->items); while (it) { edje_object_mirrored_set(VIEW(it), rtl); - elm_gengrid_item_update(it); - it = ELM_GENGRID_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next); + elm_gengrid_item_update((Elm_Object_Item *)it); + it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next); } } @@ -609,6 +570,7 @@ static void _del_hook(Evas_Object *obj) { Widget_Data *wd = elm_widget_data_get(obj); + if (wd->calc_job) ecore_job_del(wd->calc_job); free(wd); } @@ -624,12 +586,38 @@ _signal_emit_hook(Evas_Object *obj, } static void +_signal_callback_add_hook(Evas_Object *obj, + const char *emission, + const char *source, + Edje_Signal_Cb func_cb, + void *data) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + edje_object_signal_callback_add(elm_smart_scroller_edje_object_get(wd->scr), + emission, source, func_cb, data); +} + +static void +_signal_callback_del_hook(Evas_Object *obj, + const char *emission, + const char *source, + Edje_Signal_Cb func_cb, + void *data) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + edje_object_signal_callback_del_full(elm_smart_scroller_edje_object_get(wd->scr), + emission, source, func_cb, data); +} + +static void _mouse_move(void *data, Evas *evas __UNUSED__, Evas_Object *obj, void *event_info) { - Elm_Gengrid_Item *it = data; + Elm_Gen_Item *it = data; Evas_Event_Mouse_Move *ev = event_info; Evas_Coord minw = 0, minh = 0, x, y, dx, dy, adx, ady; Evas_Coord ox, oy, ow, oh, it_scrl_x, it_scrl_y; @@ -650,7 +638,7 @@ _mouse_move(void *data, ecore_timer_del(it->long_timer); it->long_timer = NULL; } - evas_object_smart_callback_call(it->wd->self, SIG_DRAG, it); + evas_object_smart_callback_call(WIDGET(it), SIG_DRAG, it); return; } if ((!it->down) || (it->wd->longpressed)) @@ -660,12 +648,12 @@ _mouse_move(void *data, ecore_timer_del(it->long_timer); it->long_timer = NULL; } - if ((it->wd->reorder_mode) && (it->wd->reorder_item)) + if ((it->wd->reorder_mode) && (it->wd->reorder_it)) { evas_object_geometry_get(it->wd->pan_smart, &ox, &oy, &ow, &oh); - it_scrl_x = ev->cur.canvas.x - it->wd->reorder_item->dx; - it_scrl_y = ev->cur.canvas.y - it->wd->reorder_item->dy; + it_scrl_x = ev->cur.canvas.x - it->wd->reorder_it->dx; + it_scrl_y = ev->cur.canvas.y - it->wd->reorder_it->dy; if (it_scrl_x < ox) it->wd->reorder_item_x = ox; else if (it_scrl_x + it->wd->item_width > ox + ow) @@ -682,7 +670,7 @@ _mouse_move(void *data, } return; } - if (!it->display_only) + if (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY) elm_coords_finger_size_adjust(1, &minw, 1, &minh); evas_object_geometry_get(obj, &x, &y, NULL, NULL); x = ev->cur.canvas.x - x; @@ -698,7 +686,7 @@ _mouse_move(void *data, if ((adx > minw) || (ady > minh)) { const char *left_drag, *right_drag; - if (!elm_widget_mirrored_get(it->wd->self)) + if (!elm_widget_mirrored_get(WIDGET(it))) { left_drag = SIG_DRAG_START_LEFT; right_drag = SIG_DRAG_START_RIGHT; @@ -720,27 +708,27 @@ _mouse_move(void *data, if (dy < 0) { if (ady > adx) - evas_object_smart_callback_call(it->wd->self, SIG_DRAG_START_UP, + evas_object_smart_callback_call(WIDGET(it), SIG_DRAG_START_UP, it); else { if (dx < 0) - evas_object_smart_callback_call(it->wd->self, + evas_object_smart_callback_call(WIDGET(it), left_drag, it); } } else { if (ady > adx) - evas_object_smart_callback_call(it->wd->self, + evas_object_smart_callback_call(WIDGET(it), SIG_DRAG_START_DOWN, it); else { if (dx < 0) - evas_object_smart_callback_call(it->wd->self, + evas_object_smart_callback_call(WIDGET(it), left_drag, it); else - evas_object_smart_callback_call(it->wd->self, + evas_object_smart_callback_call(WIDGET(it), right_drag, it); } } @@ -750,15 +738,16 @@ _mouse_move(void *data, static Eina_Bool _long_press(void *data) { - Elm_Gengrid_Item *it = data; + Elm_Gen_Item *it = data; it->long_timer = NULL; - if ((it->disabled) || (it->dragging)) return ECORE_CALLBACK_CANCEL; + if (elm_widget_item_disabled_get(it)|| (it->dragging)) + return ECORE_CALLBACK_CANCEL; it->wd->longpressed = EINA_TRUE; - evas_object_smart_callback_call(it->wd->self, "longpressed", it); + evas_object_smart_callback_call(WIDGET(it), SIG_LONGPRESSED, it); if (it->wd->reorder_mode) { - it->wd->reorder_item = it; + it->wd->reorder_it = it; evas_object_raise(VIEW(it)); elm_smart_scroller_hold_set(it->wd->scr, EINA_TRUE); elm_smart_scroller_bounce_allow_set(it->wd->scr, EINA_FALSE, EINA_FALSE); @@ -773,7 +762,7 @@ _mouse_down(void *data, Evas_Object *obj, void *event_info) { - Elm_Gengrid_Item *it = data; + Elm_Gen_Item *it = data; Evas_Event_Mouse_Down *ev = event_info; Evas_Coord x, y; @@ -786,10 +775,14 @@ _mouse_down(void *data, it->wd->longpressed = EINA_FALSE; if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) it->wd->on_hold = EINA_TRUE; else it->wd->on_hold = EINA_FALSE; + if (it->wd->on_hold) return; it->wd->wasselected = it->selected; - _item_hilight(it); + _item_highlight(it); if (ev->flags & EVAS_BUTTON_DOUBLE_CLICK) - evas_object_smart_callback_call(it->wd->self, SIG_CLICKED_DOUBLE, it); + { + evas_object_smart_callback_call(WIDGET(it), SIG_CLICKED_DOUBLE, it); + evas_object_smart_callback_call(WIDGET(it), SIG_ACTIVATED, it); + } if (it->long_timer) ecore_timer_del(it->long_timer); if (it->realized) it->long_timer = ecore_timer_add(_elm_config->longpress_timeout, @@ -804,7 +797,7 @@ _mouse_up(void *data, Evas_Object *obj __UNUSED__, void *event_info) { - Elm_Gengrid_Item *it = data; + Elm_Gen_Item *it = data; Evas_Event_Mouse_Up *ev = event_info; Eina_Bool dragged = EINA_FALSE; @@ -820,7 +813,7 @@ _mouse_up(void *data, if (it->dragging) { it->dragging = EINA_FALSE; - evas_object_smart_callback_call(it->wd->self, SIG_DRAG_STOP, it); + evas_object_smart_callback_call(WIDGET(it), SIG_DRAG_STOP, it); dragged = EINA_TRUE; } if (it->wd->on_hold) @@ -829,10 +822,10 @@ _mouse_up(void *data, it->wd->on_hold = EINA_FALSE; return; } - if ((it->wd->reorder_mode) && (it->wd->reorder_item)) + if ((it->wd->reorder_mode) && (it->wd->reorder_it)) { - evas_object_smart_callback_call(it->wd->self, SIG_MOVED, it->wd->reorder_item); - it->wd->reorder_item = NULL; + evas_object_smart_callback_call(WIDGET(it), SIG_MOVED, it->wd->reorder_it); + it->wd->reorder_it = NULL; it->wd->move_effect_enabled = EINA_FALSE; if (it->wd->calc_job) ecore_job_del(it->wd->calc_job); it->wd->calc_job = ecore_job_add(_calc_job, it->wd); @@ -850,15 +843,16 @@ _mouse_up(void *data, } if (dragged) { - if (it->want_unrealize) _item_unrealize(it); + if (it->want_unrealize) + _elm_genlist_item_unrealize(it, EINA_FALSE); } - if ((it->disabled) || (dragged)) return; + if (elm_widget_item_disabled_get(it) || (dragged)) return; if (it->wd->multi) { if (!it->selected) { - _item_hilight(it); - _item_select(it); + _item_highlight(it); + it->sel_cb(it); } else _item_unselect(it); } @@ -872,91 +866,105 @@ _mouse_up(void *data, else { const Eina_List *l, *l_next; - Elm_Gengrid_Item *item2; + Elm_Gen_Item *item2; EINA_LIST_FOREACH_SAFE(it->wd->selected, l, l_next, item2) if (item2 != it) _item_unselect(item2); } - _item_hilight(it); - _item_select(it); + _item_highlight(it); + it->sel_cb(it); } } static void -_item_hilight(Elm_Gengrid_Item *it) +_item_highlight(Elm_Gen_Item *it) { - if ((it->wd->no_select) || (it->delete_me) || (it->hilighted)) return; + if ((it->wd->select_mode == ELM_OBJECT_SELECT_MODE_NONE) || + (!it->wd->highlight) || (it->highlighted) || + (it->generation < it->wd->generation)) return; edje_object_signal_emit(VIEW(it), "elm,state,selected", "elm"); - it->hilighted = EINA_TRUE; + it->highlighted = EINA_TRUE; +} + +static void +_elm_gengrid_item_index_update(Elm_Gen_Item *it) +{ + if (it->position_update) + { + evas_object_smart_callback_call(WIDGET(it), SIG_INDEX_UPDATE, it); + it->position_update = EINA_FALSE; + } } static void -_item_realize(Elm_Gengrid_Item *it) +_item_realize(Elm_Gen_Item *it) { char buf[1024]; char style[1024]; - if ((it->realized) || (it->delete_me)) return; - VIEW(it) = edje_object_add(evas_object_evas_get(it->wd->self)); - edje_object_scale_set(VIEW(it), elm_widget_scale_get(it->wd->self) * + if ((it->realized) || (it->generation < it->wd->generation)) return; + VIEW(it) = edje_object_add(evas_object_evas_get(WIDGET(it))); + edje_object_scale_set(VIEW(it), elm_widget_scale_get(WIDGET(it)) * _elm_config->scale); edje_object_mirrored_set(VIEW(it), elm_widget_mirrored_get(WIDGET(it))); evas_object_smart_member_add(VIEW(it), it->wd->pan_smart); - elm_widget_sub_object_add(it->wd->self, VIEW(it)); + elm_widget_sub_object_add(WIDGET(it), VIEW(it)); snprintf(style, sizeof(style), "item/%s", - it->gic->item_style ? it->gic->item_style : "default"); - _elm_theme_object_set(it->wd->self, VIEW(it), "gengrid", style, - elm_widget_style_get(it->wd->self)); + it->itc->item_style ? it->itc->item_style : "default"); + _elm_theme_object_set(WIDGET(it), VIEW(it), "gengrid", style, + elm_widget_style_get(WIDGET(it))); it->spacer = - evas_object_rectangle_add(evas_object_evas_get(it->wd->self)); + evas_object_rectangle_add(evas_object_evas_get(WIDGET(it))); evas_object_color_set(it->spacer, 0, 0, 0, 0); - elm_widget_sub_object_add(it->wd->self, it->spacer); + elm_widget_sub_object_add(WIDGET(it), it->spacer); evas_object_size_hint_min_set(it->spacer, 2 * _elm_config->scale, 1); edje_object_part_swallow(VIEW(it), "elm.swallow.pad", it->spacer); - if (it->gic->func.label_get) + if (it->itc->func.text_get) { const Eina_List *l; const char *key; - it->labels = + it->texts = elm_widget_stringlist_get(edje_object_data_get(VIEW(it), - "labels")); - EINA_LIST_FOREACH(it->labels, l, key) + "texts")); + EINA_LIST_FOREACH(it->texts, l, key) { - char *s = it->gic->func.label_get - ((void *)it->base.data, it->wd->self, l->data); + char *s = it->itc->func.text_get + ((void *)it->base.data, WIDGET(it), key); if (s) { - edje_object_part_text_set(VIEW(it), l->data, s); + edje_object_part_text_escaped_set(VIEW(it), key, s); free(s); } } } - if (it->gic->func.content_get) + if (it->itc->func.content_get) { const Eina_List *l; const char *key; + Evas_Object *ic = NULL; - it->icons = + it->contents = elm_widget_stringlist_get(edje_object_data_get(VIEW(it), - "icons")); - EINA_LIST_FOREACH(it->icons, l, key) + "contents")); + EINA_LIST_FOREACH(it->contents, l, key) { - Evas_Object *ic = it->gic->func.content_get - ((void *)it->base.data, it->wd->self, l->data); + if (it->itc->func.content_get) + ic = it->itc->func.content_get + ((void *)it->base.data, WIDGET(it), key); if (ic) { - it->icon_objs = eina_list_append(it->icon_objs, ic); + it->content_objs = eina_list_append(it->content_objs, ic); edje_object_part_swallow(VIEW(it), key, ic); evas_object_show(ic); - elm_widget_sub_object_add(it->wd->self, ic); + elm_widget_sub_object_add(WIDGET(it), ic); } } } - if (it->gic->func.state_get) + if (it->itc->func.state_get) { const Eina_List *l; const char *key; @@ -966,8 +974,8 @@ _item_realize(Elm_Gengrid_Item *it) "states")); EINA_LIST_FOREACH(it->states, l, key) { - Eina_Bool on = it->gic->func.state_get - ((void *)it->base.data, it->wd->self, l->data); + Eina_Bool on = it->itc->func.state_get + ((void *)it->base.data, WIDGET(it), l->data); if (on) { snprintf(buf, sizeof(buf), "elm,state,%s,active", key); @@ -976,29 +984,44 @@ _item_realize(Elm_Gengrid_Item *it) } } - if ((!it->wd->item_width) && (!it->wd->item_height)) + if (it->group) { - edje_object_size_min_restricted_calc(VIEW(it), - &it->wd->item_width, - &it->wd->item_height, - it->wd->item_width, - it->wd->item_height); - elm_coords_finger_size_adjust(1, &it->wd->item_width, - 1, &it->wd->item_height); + if ((!it->wd->group_item_width) && (!it->wd->group_item_height)) + { + edje_object_size_min_restricted_calc(VIEW(it), + &it->wd->group_item_width, + &it->wd->group_item_height, + it->wd->group_item_width, + it->wd->group_item_height); + } } + else + { + if ((!it->wd->item_width) && (!it->wd->item_height)) + { + edje_object_size_min_restricted_calc(VIEW(it), + &it->wd->item_width, + &it->wd->item_height, + it->wd->item_width, + it->wd->item_height); + elm_coords_finger_size_adjust(1, &it->wd->item_width, + 1, &it->wd->item_height); + } - evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_MOUSE_DOWN, - _mouse_down, it); - evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_MOUSE_UP, - _mouse_up, it); - evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_MOUSE_MOVE, - _mouse_move, it); + evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_MOUSE_DOWN, + _mouse_down, it); + evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_MOUSE_UP, + _mouse_up, it); + evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_MOUSE_MOVE, + _mouse_move, it); - if (it->selected) - edje_object_signal_emit(VIEW(it), "elm,state,selected", "elm"); - if (it->disabled) - edje_object_signal_emit(VIEW(it), "elm,state,disabled", "elm"); + _elm_gengrid_item_index_update(it); + if (it->selected) + edje_object_signal_emit(VIEW(it), "elm,state,selected", "elm"); + if (elm_widget_item_disabled_get(it)) + edje_object_signal_emit(VIEW(it), "elm,state,disabled", "elm"); + } evas_object_show(VIEW(it)); if (it->tooltip.content_cb) @@ -1007,6 +1030,7 @@ _item_realize(Elm_Gengrid_Item *it) it->tooltip.content_cb, it->tooltip.data, NULL); elm_widget_item_tooltip_style_set(it, it->tooltip.style); + elm_widget_item_tooltip_window_mode_set(it, it->tooltip.free_size); } if (it->mouse_cursor) @@ -1017,81 +1041,118 @@ _item_realize(Elm_Gengrid_Item *it) } static void -_item_unrealize(Elm_Gengrid_Item *it) +_item_unrealize_cb(Elm_Gen_Item *it) { - Evas_Object *icon; - - if (!it->realized) return; - if (it->long_timer) - { - ecore_timer_del(it->long_timer); - it->long_timer = NULL; - } evas_object_del(VIEW(it)); VIEW(it) = NULL; evas_object_del(it->spacer); it->spacer = NULL; - elm_widget_stringlist_free(it->labels); - it->labels = NULL; - elm_widget_stringlist_free(it->icons); - it->icons = NULL; - elm_widget_stringlist_free(it->states); - it->states = NULL; - - EINA_LIST_FREE(it->icon_objs, icon) - evas_object_del(icon); - - it->realized = EINA_FALSE; - it->want_unrealize = EINA_FALSE; } static Eina_Bool -_reorder_item_moving_effect_timer_cb(void *data) +_reorder_item_move_animator_cb(void *data) { - Elm_Gengrid_Item *it = data; - double time, t; + Elm_Gen_Item *it = data; + double tt, t; Evas_Coord dx, dy; - time = REORDER_EFFECT_TIME; - t = ((0.0 > (t = ecore_loop_time_get()-it->moving_effect_start_time)) ? 0.0 : t); - dx = ((it->tx - it->ox) / 10) * _elm_config->scale; - dy = ((it->ty - it->oy) / 10) * _elm_config->scale; + tt = REORDER_EFFECT_TIME; + t = ((0.0 > (t = ecore_loop_time_get()-it->item->moving_effect_start_time)) ? 0.0 : t); + dx = ((it->item->tx - it->item->ox) / 10) * _elm_config->scale; + dy = ((it->item->ty - it->item->oy) / 10) * _elm_config->scale; - if (t <= time) + if (t <= tt) { - it->rx += (1 * sin((t / time) * (M_PI / 2)) * dx); - it->ry += (1 * sin((t / time) * (M_PI / 2)) * dy); + it->item->rx += (1 * sin((t / tt) * (M_PI / 2)) * dx); + it->item->ry += (1 * sin((t / tt) * (M_PI / 2)) * dy); } else { - it->rx += dx; - it->ry += dy; + it->item->rx += dx; + it->item->ry += dy; } - if ((((dx > 0) && (it->rx >= it->tx)) || ((dx <= 0) && (it->rx <= it->tx))) && - (((dy > 0) && (it->ry >= it->ty)) || ((dy <= 0) && (it->ry <= it->ty)))) + if ((((dx > 0) && (it->item->rx >= it->item->tx)) || ((dx <= 0) && (it->item->rx <= it->item->tx))) && + (((dy > 0) && (it->item->ry >= it->item->ty)) || ((dy <= 0) && (it->item->ry <= it->item->ty)))) { - evas_object_move(VIEW(it), it->tx, it->ty); - evas_object_resize(VIEW(it), it->wd->item_width, it->wd->item_height); - it->moving = EINA_FALSE; - it->item_moving_effect_timer = NULL; + evas_object_move(VIEW(it), it->item->tx, it->item->ty); + if (it->group) + { + Evas_Coord vw, vh; + evas_object_geometry_get(it->wd->pan_smart, NULL, NULL, &vw, &vh); + if (it->wd->horizontal) + evas_object_resize(VIEW(it), it->wd->group_item_width, vh); + else + evas_object_resize(VIEW(it), vw, it->wd->group_item_height); + } + else + evas_object_resize(VIEW(it), it->wd->item_width, it->wd->item_height); + it->item->moving = EINA_FALSE; + it->item->item_reorder_move_animator = NULL; return ECORE_CALLBACK_CANCEL; } - evas_object_move(VIEW(it), it->rx, it->ry); - evas_object_resize(VIEW(it), it->wd->item_width, it->wd->item_height); + evas_object_move(VIEW(it), it->item->rx, it->item->ry); + if (it->group) + { + Evas_Coord vw, vh; + evas_object_geometry_get(it->wd->pan_smart, NULL, NULL, &vw, &vh); + if (it->wd->horizontal) + evas_object_resize(VIEW(it), it->wd->group_item_width, vh); + else + evas_object_resize(VIEW(it), vw, it->wd->group_item_height); + } + else + evas_object_resize(VIEW(it), it->wd->item_width, it->wd->item_height); return ECORE_CALLBACK_RENEW; } static void -_item_place(Elm_Gengrid_Item *it, - Evas_Coord cx, - Evas_Coord cy) +_group_item_place(Pan *sd) { - Evas_Coord x, y, ox, oy, cvx, cvy, cvw, cvh; + Evas_Coord iw, ih, vw, vh; + Eina_List *l; + Eina_Bool was_realized; + Elm_Gen_Item *it; + evas_object_geometry_get(sd->wd->pan_smart, NULL, NULL, &vw, &vh); + if (sd->wd->horizontal) + { + iw = sd->wd->group_item_width; + ih = vh; + } + else + { + iw = vw; + ih = sd->wd->group_item_height; + } + EINA_LIST_FOREACH(sd->wd->group_items, l, it) + { + was_realized = it->realized; + if (it->item->group_realized) + { + _item_realize(it); + if (!was_realized) + evas_object_smart_callback_call(WIDGET(it), SIG_REALIZED, it); + evas_object_move(VIEW(it), it->item->gx, it->item->gy); + evas_object_resize(VIEW(it), iw, ih); + evas_object_raise(VIEW(it)); + } + else + _elm_genlist_item_unrealize(it, EINA_FALSE); + } +} + + +static void +_item_place(Elm_Gen_Item *it, + Evas_Coord cx, + Evas_Coord cy) +{ + Evas_Coord x, y, ox, oy, cvx, cvy, cvw, cvh, iw, ih, ww; Evas_Coord tch, tcw, alignw = 0, alignh = 0, vw, vh; Eina_Bool reorder_item_move_forward = EINA_FALSE; + long items_count; it->x = cx; it->y = cy; evas_object_geometry_get(it->wd->pan_smart, &ox, &oy, &vw, &vh); @@ -1105,6 +1166,7 @@ _item_place(Elm_Gengrid_Item *it, alignh = 0; alignw = 0; + items_count = it->wd->item_count - eina_list_count(it->wd->group_items) + it->wd->items_lost; if (it->wd->horizontal) { int columns, items_visible = 0, items_row; @@ -1114,127 +1176,212 @@ _item_place(Elm_Gengrid_Item *it, if (items_visible < 1) items_visible = 1; - columns = it->wd->count / items_visible; - if (it->wd->count % items_visible) + columns = items_count / items_visible; + if (items_count % items_visible) columns++; - tcw = it->wd->item_width * columns; + tcw = (it->wd->item_width * columns) + (it->wd->group_item_width * eina_list_count(it->wd->group_items)); alignw = (vw - tcw) * it->wd->align_x; items_row = items_visible; - if (items_row > it->wd->count) - items_row = it->wd->count; - tch = items_row * it->wd->item_height; + if ((unsigned int)items_row > it->wd->item_count) + items_row = it->wd->item_count; + if (it->wd->filled + && (unsigned int)it->wd->nmax > (unsigned int)it->wd->item_count) + tch = it->wd->nmax * it->wd->item_height; + else + tch = items_row * it->wd->item_height; alignh = (vh - tch) * it->wd->align_y; } else { - int rows, items_visible = 0, items_col; + unsigned int rows, items_visible = 0, items_col; if (it->wd->item_width > 0) items_visible = vw / it->wd->item_width; if (items_visible < 1) items_visible = 1; - rows = it->wd->count / items_visible; - if (it->wd->count % items_visible) + rows = items_count / items_visible; + if (items_count % items_visible) rows++; - tch = it->wd->item_height * rows; + tch = (it->wd->item_height * rows) + (it->wd->group_item_height * eina_list_count(it->wd->group_items)); alignh = (vh - tch) * it->wd->align_y; items_col = items_visible; - if (items_col > it->wd->count) - items_col = it->wd->count; - tcw = items_col * it->wd->item_width; + if (items_col > it->wd->item_count) + items_col = it->wd->item_count; + if (it->wd->filled + && (unsigned int)it->wd->nmax > (unsigned int)it->wd->item_count) + tcw = it->wd->nmax * it->wd->item_width; + else + tcw = items_col * it->wd->item_width; alignw = (vw - tcw) * it->wd->align_x; } - x = cx * it->wd->item_width - it->wd->pan_x + ox + alignw; - if (elm_widget_mirrored_get(it->wd->self)) - { /* Switch items side and componsate for pan_x when in RTL mode */ - Evas_Coord ww; - evas_object_geometry_get(it->wd->self, NULL, NULL, &ww, NULL); - x = ww - x - it->wd->item_width - it->wd->pan_x - it->wd->pan_x; + if (it->group) + { + if (it->wd->horizontal) + { + x = (((cx - it->item->prev_group) * it->wd->item_width) + (it->item->prev_group * it->wd->group_item_width)) - it->wd->pan_x + ox + alignw; + y = oy; + iw = it->wd->group_item_width; + ih = vh; + } + else + { + x = ox; + y = (((cy - it->item->prev_group) * it->wd->item_height) + (it->item->prev_group * it->wd->group_item_height)) - it->wd->pan_y + oy + alignh; + iw = vw; + ih = it->wd->group_item_height; + } + it->item->gx = x; + it->item->gy = y; + } + else + { + if (it->wd->horizontal) + { + x = (((cx - it->item->prev_group) * it->wd->item_width) + (it->item->prev_group * it->wd->group_item_width)) - it->wd->pan_x + ox + alignw; + y = (cy * it->wd->item_height) - it->wd->pan_y + oy + alignh; + } + else + { + x = (cx * it->wd->item_width) - it->wd->pan_x + ox + alignw; + y = (((cy - it->item->prev_group) * it->wd->item_height) + (it->item->prev_group * it->wd->group_item_height)) - it->wd->pan_y + oy + alignh; + } + if (elm_widget_mirrored_get(WIDGET(it))) + { /* Switch items side and componsate for pan_x when in RTL mode */ + evas_object_geometry_get(WIDGET(it), NULL, NULL, &ww, NULL); + x = ww - x - it->wd->item_width - it->wd->pan_x - it->wd->pan_x; + } + iw = it->wd->item_width; + ih = it->wd->item_height; } - - y = cy * it->wd->item_height - it->wd->pan_y + oy + alignh; Eina_Bool was_realized = it->realized; - if (ELM_RECTS_INTERSECT(x, y, it->wd->item_width, it->wd->item_height, - cvx, cvy, cvw, cvh)) + if (ELM_RECTS_INTERSECT(x, y, iw, ih, cvx, cvy, cvw, cvh)) { _item_realize(it); if (!was_realized) - evas_object_smart_callback_call(it->wd->self, SIG_REALIZED, it); + evas_object_smart_callback_call(WIDGET(it), SIG_REALIZED, it); + if (it->parent) + { + if (it->wd->horizontal) + { + if (it->parent->item->gx < ox) + { + it->parent->item->gx = x + it->wd->item_width - it->wd->group_item_width; + if (it->parent->item->gx > ox) + it->parent->item->gx = ox; + } + it->parent->item->group_realized = EINA_TRUE; + } + else + { + if (it->parent->item->gy < oy) + { + it->parent->item->gy = y + it->wd->item_height - it->wd->group_item_height; + if (it->parent->item->gy > oy) + it->parent->item->gy = oy; + } + it->parent->item->group_realized = EINA_TRUE; + } + } if (it->wd->reorder_mode) { - if (it->wd->reorder_item) + if (it->wd->reorder_it) { - if (it->moving) return; + if (it->item->moving) return; if (!it->wd->move_effect_enabled) { - it->ox = x; - it->oy = y; + it->item->ox = x; + it->item->oy = y; } - if (it->wd->reorder_item == it) + if (it->wd->reorder_it == it) { evas_object_move(VIEW(it), it->wd->reorder_item_x, it->wd->reorder_item_y); - evas_object_resize(VIEW(it), - it->wd->item_width, it->wd->item_height); + evas_object_resize(VIEW(it), iw, ih); return; } else { if (it->wd->move_effect_enabled) { - if ((it->ox != x) || (it->oy != y)) + if ((it->item->ox != x) || (it->item->oy != y)) { if (((it->wd->old_pan_x == it->wd->pan_x) && (it->wd->old_pan_y == it->wd->pan_y)) || - ((it->wd->old_pan_x != it->wd->pan_x) && !(it->ox - it->wd->pan_x + it->wd->old_pan_x == x)) || - ((it->wd->old_pan_y != it->wd->pan_y) && !(it->oy - it->wd->pan_y + it->wd->old_pan_y == y))) + ((it->wd->old_pan_x != it->wd->pan_x) && !(it->item->ox - it->wd->pan_x + it->wd->old_pan_x == x)) || + ((it->wd->old_pan_y != it->wd->pan_y) && !(it->item->oy - it->wd->pan_y + it->wd->old_pan_y == y))) { - it->tx = x; - it->ty = y; - it->rx = it->ox; - it->ry = it->oy; - it->moving = EINA_TRUE; - it->moving_effect_start_time = ecore_loop_time_get(); - it->item_moving_effect_timer = ecore_animator_add(_reorder_item_moving_effect_timer_cb, it); + it->item->tx = x; + it->item->ty = y; + it->item->rx = it->item->ox; + it->item->ry = it->item->oy; + it->item->moving = EINA_TRUE; + it->item->moving_effect_start_time = ecore_loop_time_get(); + it->item->item_reorder_move_animator = ecore_animator_add(_reorder_item_move_animator_cb, it); return; } } } - if (ELM_RECTS_INTERSECT(it->wd->reorder_item_x, it->wd->reorder_item_y, - it->wd->item_width, it->wd->item_height, - x+(it->wd->item_width/2), y+(it->wd->item_height/2), - 1, 1)) + /* need fix here */ + Evas_Coord nx, ny, nw, nh; + if (it->group) { if (it->wd->horizontal) { - if ((it->wd->nmax * it->wd->reorder_item->x + it->wd->reorder_item->y) > + nx = x + (it->wd->group_item_width / 2); + ny = y; + nw = 1; + nh = vh; + } + else + { + nx = x; + ny = y + (it->wd->group_item_height / 2); + nw = vw; + nh = 1; + } + } + else + { + nx = x + (it->wd->item_width / 2); + ny = y + (it->wd->item_height / 2); + nw = 1; + nh = 1; + } + + if ( ELM_RECTS_INTERSECT(it->wd->reorder_item_x, it->wd->reorder_item_y, + it->wd->item_width, it->wd->item_height, + nx, ny, nw, nh)) + { + if (it->wd->horizontal) + { + if ((it->wd->nmax * it->wd->reorder_it->x + it->wd->reorder_it->y) > (it->wd->nmax * it->x + it->y)) reorder_item_move_forward = EINA_TRUE; } else { - if ((it->wd->nmax * it->wd->reorder_item->y + it->wd->reorder_item->x) > + if ((it->wd->nmax * it->wd->reorder_it->y + it->wd->reorder_it->x) > (it->wd->nmax * it->y + it->x)) reorder_item_move_forward = EINA_TRUE; } it->wd->items = eina_inlist_remove(it->wd->items, - EINA_INLIST_GET(it->wd->reorder_item)); + EINA_INLIST_GET(it->wd->reorder_it)); if (reorder_item_move_forward) it->wd->items = eina_inlist_prepend_relative(it->wd->items, - EINA_INLIST_GET(it->wd->reorder_item), + EINA_INLIST_GET(it->wd->reorder_it), EINA_INLIST_GET(it)); else it->wd->items = eina_inlist_append_relative(it->wd->items, - EINA_INLIST_GET(it->wd->reorder_item), + EINA_INLIST_GET(it->wd->reorder_it), EINA_INLIST_GET(it)); it->wd->reorder_item_changed = EINA_TRUE; @@ -1246,108 +1393,67 @@ _item_place(Elm_Gengrid_Item *it, } } } - else if (it->item_moving_effect_timer) + else if (it->item->item_reorder_move_animator) { - ecore_animator_del(it->item_moving_effect_timer); - it->item_moving_effect_timer = NULL; - it->moving = EINA_FALSE; + ecore_animator_del(it->item->item_reorder_move_animator); + it->item->item_reorder_move_animator = NULL; + it->item->moving = EINA_FALSE; } } - evas_object_move(VIEW(it), x, y); - evas_object_resize(VIEW(it), it->wd->item_width, - it->wd->item_height); + if (!it->group) + { + evas_object_move(VIEW(it), x, y); + evas_object_resize(VIEW(it), iw, ih); + } + else + it->item->group_realized = EINA_TRUE; } else { - _item_unrealize(it); - if (was_realized) - evas_object_smart_callback_call(it->wd->self, SIG_UNREALIZED, it); + if (!it->group) + _elm_genlist_item_unrealize(it, EINA_FALSE); + else + it->item->group_realized = EINA_FALSE; } } -static Elm_Gengrid_Item * -_item_create(Widget_Data *wd, - const Elm_Gengrid_Item_Class *gic, - const void *data, - Evas_Smart_Cb func, - const void *func_data) +static void +_item_position_update(Eina_Inlist *list, int idx) { - Elm_Gengrid_Item *it; + Elm_Gen_Item *it; - it = elm_widget_item_new(wd->self, Elm_Gengrid_Item); - if (!it) return NULL; - wd->count++; - it->wd = wd; - it->gic = gic; - it->base.data = data; - it->func.func = func; - it->func.data = func_data; - it->mouse_cursor = NULL; - return it; + EINA_INLIST_FOREACH(list, it) + { + it->position = idx++; + it->position_update = EINA_TRUE; + } } static void -_item_del(Elm_Gengrid_Item *it) +_item_del(Elm_Gen_Item *it) { - elm_widget_item_pre_notify_del(it); - if (it->selected) - it->wd->selected = eina_list_remove(it->wd->selected, it); - if (it->realized) _item_unrealize(it); - if ((!it->delete_me) && (it->gic->func.del)) - it->gic->func.del((void *)it->base.data, it->wd->self); - it->delete_me = EINA_TRUE; - it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it)); - if (it->long_timer) ecore_timer_del(it->long_timer); - if (it->tooltip.del_cb) - it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it); - it->wd->walking -= it->walking; - it->wd->count--; - if (it->wd->calc_job) ecore_job_del(it->wd->calc_job); - it->wd->calc_job = ecore_job_add(_calc_job, it->wd); - elm_widget_item_del(it); -} + Evas_Object *obj = WIDGET(it); -static void -_item_select(Elm_Gengrid_Item *it) -{ - if ((it->wd->no_select) || (it->delete_me)) return; - if (it->selected) - { - if (it->wd->always_select) goto call; - return; - } - it->selected = EINA_TRUE; - it->wd->selected = eina_list_append(it->wd->selected, it); -call: - it->walking++; - it->wd->walking++; - if (it->func.func) - it->func.func((void *)it->func.data, it->wd->self, it); - if (!it->delete_me) - evas_object_smart_callback_call(it->wd->self, SIG_SELECTED, it); - it->walking--; - it->wd->walking--; - it->wd->last_selected_item = it; - if ((it->wd->clear_me) && (!it->wd->walking)) - elm_gengrid_clear(WIDGET(it)); - else - { - if ((!it->walking) && (it->delete_me)) - if (!it->relcount) _item_del(it); - } + evas_event_freeze(evas_object_evas_get(obj)); + it->wd->selected = eina_list_remove(it->wd->selected, it); + if (it->realized) _elm_genlist_item_unrealize(it, EINA_FALSE); + _elm_genlist_item_del_serious(it); + elm_gengrid_item_class_unref((Elm_Gengrid_Item_Class *)it->itc); + evas_event_thaw(evas_object_evas_get(obj)); + evas_event_thaw_eval(evas_object_evas_get(obj)); } static void -_item_unselect(Elm_Gengrid_Item *it) +_item_unselect(Elm_Gen_Item *it) { - if ((it->delete_me) || (!it->hilighted)) return; + if ((it->generation < it->wd->generation) || (!it->highlighted)) return; edje_object_signal_emit(VIEW(it), "elm,state,unselected", "elm"); - it->hilighted = EINA_FALSE; + it->highlighted = EINA_FALSE; if (it->selected) { it->selected = EINA_FALSE; it->wd->selected = eina_list_remove(it->wd->selected, it); - evas_object_smart_callback_call(it->wd->self, SIG_UNSELECTED, it); + evas_object_smart_callback_call(WIDGET(it), SIG_UNSELECTED, it); } } @@ -1356,7 +1462,10 @@ _calc_job(void *data) { Widget_Data *wd = data; Evas_Coord minw = 0, minh = 0, nmax = 0, cvw, cvh; - int count; + Elm_Gen_Item *it, *group_item = NULL; + int count_group = 0; + long count = 0; + wd->items_lost = 0; evas_object_geometry_get(wd->pan_smart, NULL, NULL, &cvw, &cvh); if ((cvw != 0) || (cvh != 0)) @@ -1369,16 +1478,37 @@ _calc_job(void *data) if (nmax < 1) nmax = 1; - count = wd->count; + EINA_INLIST_FOREACH(wd->items, it) + { + if (it->item->prev_group != count_group) + it->item->prev_group = count_group; + if (it->group) + { + count = count % nmax; + if (count) + wd->items_lost += nmax - count; + //printf("%d items and I lost %d\n", count, wd->items_lost); + count_group++; + if (count) count = 0; + group_item = it; + } + else + { + if (it->parent != group_item) + it->parent = group_item; + count++; + } + } + count = wd->item_count + wd->items_lost - count_group; if (wd->horizontal) { - minw = ceil(count / (float)nmax) * wd->item_width; + minw = (ceil(count / (float)nmax) * wd->item_width) + (count_group * wd->group_item_width); minh = nmax * wd->item_height; } else { minw = nmax * wd->item_width; - minh = ceil(count / (float)nmax) * wd->item_height; + minh = (ceil(count / (float)nmax) * wd->item_height) + (count_group * wd->group_item_height); } if ((minw != wd->minw) || (minh != wd->minh)) @@ -1472,7 +1602,7 @@ _pan_min_get(Evas_Object *obj, Evas_Coord *y) { Pan *sd = evas_object_smart_data_get(obj); - Evas_Coord mx, my; + Evas_Coord mx = 0, my = 0; if (!sd) return; _pan_max_get(obj, &mx, &my); @@ -1501,7 +1631,7 @@ _pan_calculate(Evas_Object *obj) { Pan *sd = evas_object_smart_data_get(obj); Evas_Coord cx = 0, cy = 0; - Elm_Gengrid_Item *it; + Elm_Gen_Item *it; if (!sd) return; if (!sd->wd->nmax) return; @@ -1510,21 +1640,58 @@ _pan_calculate(Evas_Object *obj) EINA_INLIST_FOREACH(sd->wd->items, it) { + if (it->group) + { + if (sd->wd->horizontal) + { + if (cy) + { + cx++; + cy = 0; + } + } + else + { + if (cx) + { + cx = 0; + cy++; + } + } + } _item_place(it, cx, cy); if (sd->wd->reorder_item_changed) return; - if (sd->wd->horizontal) + if (it->group) { - cy = (cy + 1) % sd->wd->nmax; - if (!cy) cx++; + if (sd->wd->horizontal) + { + cx++; + cy = 0; + } + else + { + cx = 0; + cy++; + } } else { - cx = (cx + 1) % sd->wd->nmax; - if (!cx) cy++; + if (sd->wd->horizontal) + { + cy = (cy + 1) % sd->wd->nmax; + if (!cy) cx++; + } + else + { + cx = (cx + 1) % sd->wd->nmax; + if (!cx) cy++; + } } } + _group_item_place(sd); + - if ((sd->wd->reorder_mode) && (sd->wd->reorder_item)) + if ((sd->wd->reorder_mode) && (sd->wd->reorder_it)) { if (!sd->wd->reorder_item_changed) { @@ -1533,7 +1700,7 @@ _pan_calculate(Evas_Object *obj) } sd->wd->move_effect_enabled = EINA_FALSE; } - evas_object_smart_callback_call(sd->wd->self, SIG_CHANGED, NULL); + evas_object_smart_callback_call(sd->wd->obj, SIG_CHANGED, NULL); } static void @@ -1548,9 +1715,9 @@ _pan_move(Evas_Object *obj, } static void -_hold_on(void *data __UNUSED__, - Evas_Object *obj, - void *event_info __UNUSED__) +_hold_on(void *data __UNUSED__, + Evas_Object *obj, + void *event_info __UNUSED__) { Widget_Data *wd = elm_widget_data_get(obj); if (!wd) return; @@ -1558,9 +1725,9 @@ _hold_on(void *data __UNUSED__, } static void -_hold_off(void *data __UNUSED__, - Evas_Object *obj, - void *event_info __UNUSED__) +_hold_off(void *data __UNUSED__, + Evas_Object *obj, + void *event_info __UNUSED__) { Widget_Data *wd = elm_widget_data_get(obj); if (!wd) return; @@ -1568,9 +1735,9 @@ _hold_off(void *data __UNUSED__, } static void -_freeze_on(void *data __UNUSED__, - Evas_Object *obj, - void *event_info __UNUSED__) +_freeze_on(void *data __UNUSED__, + Evas_Object *obj, + void *event_info __UNUSED__) { Widget_Data *wd = elm_widget_data_get(obj); if (!wd) return; @@ -1597,8 +1764,8 @@ _scr_anim_start(void *data, static void _scr_anim_stop(void *data, - Evas_Object *obj __UNUSED__, - void *event_info __UNUSED__) + Evas_Object *obj __UNUSED__, + void *event_info __UNUSED__) { evas_object_smart_callback_call(data, SIG_SCROLL_ANIM_STOP, NULL); } @@ -1651,7 +1818,6 @@ _edge_bottom(void *data, evas_object_smart_callback_call(data, SIG_EDGE_BOTTOM, NULL); } - static void _scr_scroll(void *data, Evas_Object *obj __UNUSED__, @@ -1661,21 +1827,63 @@ _scr_scroll(void *data, } static int -_elm_gengrid_item_compare_data(const void *data, const void *data1) +_elm_gengrid_item_compare(const void *data, const void *data1) +{ + Elm_Gen_Item *it, *item1; + it = ELM_GEN_ITEM_FROM_INLIST(data); + item1 = ELM_GEN_ITEM_FROM_INLIST(data1); + return it->wd->item_compare_cb(it, item1); +} + +static void +_item_disable_hook(Elm_Object_Item *it) +{ + Elm_Gen_Item *_it = (Elm_Gen_Item *)it; + + if (_it->generation < _it->wd->generation) return; + + if (_it->realized) + { + if (elm_widget_item_disabled_get(_it)) + edje_object_signal_emit(VIEW(_it), "elm,state,disabled", "elm"); + else + edje_object_signal_emit(VIEW(_it), "elm,state,enabled", "elm"); + } +} + +static void +_item_del_pre_hook(Elm_Object_Item *it) { - const Elm_Gengrid_Item *it = data; - const Elm_Gengrid_Item *item1 = data1; + Elm_Gen_Item *_it = (Elm_Gen_Item *)it; + if ((_it->relcount > 0) || (_it->walking > 0)) + { + _elm_genlist_item_del_notserious(_it); + return; + } - return _elm_gengrid_item_compare_data_cb(it->base.data, item1->base.data); + _item_del(_it); } -static int -_elm_gengrid_item_compare(const void *data, const void *data1) +static Elm_Gen_Item * +_item_new(Widget_Data *wd, + const Elm_Gengrid_Item_Class *itc, + const void *data, + Evas_Smart_Cb func, + const void *func_data) { - Elm_Gengrid_Item *it, *item1; - it = ELM_GENGRID_ITEM_FROM_INLIST(data); - item1 = ELM_GENGRID_ITEM_FROM_INLIST(data1); - return _elm_gengrid_item_compare_cb(it, item1); + Elm_Gen_Item *it; + + it = _elm_genlist_item_new(wd, itc, data, NULL, func, func_data); + if (!it) return NULL; + elm_widget_item_disable_hook_set(it, _item_disable_hook); + elm_widget_item_del_pre_hook_set(it, _item_del_pre_hook); + elm_gengrid_item_class_ref((Elm_Gengrid_Item_Class *)itc); + it->item = ELM_NEW(Elm_Gen_Item_Type); + wd->item_count++; + it->group = it->itc->item_style && (!strcmp(it->itc->item_style, "group_index")); + ELM_GEN_ITEM_SETUP(it); + + return it; } EAPI Evas_Object * @@ -1687,9 +1895,26 @@ elm_gengrid_add(Evas_Object *parent) static Evas_Smart *smart = NULL; Eina_Bool bounce = _elm_config->thumbscroll_bounce_enable; + if (!smart) + { + static Evas_Smart_Class sc; + + evas_object_smart_clipped_smart_set(&_pan_sc); + sc = _pan_sc; + sc.name = "elm_gengrid_pan"; + sc.version = EVAS_SMART_CLASS_VERSION; + sc.add = _pan_add; + sc.del = _pan_del; + sc.resize = _pan_resize; + sc.move = _pan_move; + sc.calculate = _pan_calculate; + if (!(smart = evas_smart_class_new(&sc))) return NULL; + } + ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL); ELM_SET_WIDTYPE(widtype, "gengrid"); + ELM_GEN_SETUP(wd); elm_widget_type_set(obj, "gengrid"); elm_widget_sub_object_add(parent, obj); elm_widget_on_focus_hook_set(obj, _on_focus_hook, NULL); @@ -1699,12 +1924,17 @@ elm_gengrid_add(Evas_Object *parent) elm_widget_theme_hook_set(obj, _theme_hook); elm_widget_signal_emit_hook_set(obj, _signal_emit_hook); elm_widget_can_focus_set(obj, EINA_TRUE); + elm_widget_signal_callback_add_hook_set(obj, _signal_callback_add_hook); + elm_widget_signal_callback_del_hook_set(obj, _signal_callback_del_hook); elm_widget_event_hook_set(obj, _event_hook); + wd->generation = 1; wd->scr = elm_smart_scroller_add(e); elm_smart_scroller_widget_set(wd->scr, obj); elm_smart_scroller_object_theme_set(obj, wd->scr, "gengrid", "base", "default"); + elm_smart_scroller_bounce_allow_set(wd->scr, bounce, + _elm_config->thumbscroll_bounce_enable); elm_widget_resize_object_set(obj, wd->scr); evas_object_smart_callback_add(wd->scr, "animate,start", _scr_anim_start, obj); @@ -1714,51 +1944,32 @@ elm_gengrid_add(Evas_Object *parent) evas_object_smart_callback_add(wd->scr, "edge,left", _edge_left, obj); evas_object_smart_callback_add(wd->scr, "edge,right", _edge_right, obj); evas_object_smart_callback_add(wd->scr, "edge,top", _edge_top, obj); - evas_object_smart_callback_add(wd->scr, "edge,bottom", _edge_bottom, obj); + evas_object_smart_callback_add(wd->scr, "edge,bottom", _edge_bottom, + obj); evas_object_smart_callback_add(wd->scr, "scroll", _scr_scroll, obj); - elm_smart_scroller_bounce_allow_set(wd->scr, bounce, bounce); - - wd->self = obj; + wd->obj = obj; wd->align_x = 0.5; wd->align_y = 0.5; wd->h_bounce = bounce; wd->v_bounce = bounce; - wd->no_select = EINA_FALSE; + wd->highlight = EINA_TRUE; evas_object_smart_callback_add(obj, "scroll-hold-on", _hold_on, obj); evas_object_smart_callback_add(obj, "scroll-hold-off", _hold_off, obj); evas_object_smart_callback_add(obj, "scroll-freeze-on", _freeze_on, obj); evas_object_smart_callback_add(obj, "scroll-freeze-off", _freeze_off, obj); - evas_object_smart_callbacks_descriptions_set(obj, _signals); - - if (!smart) - { - static Evas_Smart_Class sc; - - evas_object_smart_clipped_smart_set(&_pan_sc); - sc = _pan_sc; - sc.name = "elm_gengrid_pan"; - sc.version = EVAS_SMART_CLASS_VERSION; - sc.add = _pan_add; - sc.del = _pan_del; - sc.resize = _pan_resize; - sc.move = _pan_move; - sc.calculate = _pan_calculate; - smart = evas_smart_class_new(&sc); - } - if (smart) - { - wd->pan_smart = evas_object_smart_add(e, smart); - wd->pan = evas_object_smart_data_get(wd->pan_smart); - wd->pan->wd = wd; - } + wd->pan_smart = evas_object_smart_add(e, smart); + wd->pan = evas_object_smart_data_get(wd->pan_smart); + wd->pan->wd = wd; elm_smart_scroller_extern_pan_set(wd->scr, wd->pan_smart, _pan_set, _pan_get, _pan_max_get, _pan_min_get, _pan_child_size_get); + evas_object_smart_callbacks_descriptions_set(obj, _signals); + _mirrored_set(obj, elm_widget_mirrored_get(obj)); return obj; } @@ -1791,12 +2002,41 @@ elm_gengrid_item_size_get(const Evas_Object *obj, } EAPI void +elm_gengrid_group_item_size_set(Evas_Object *obj, + Evas_Coord w, + Evas_Coord h) +{ + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + if ((wd->group_item_width == w) && (wd->group_item_height == h)) return; + wd->group_item_width = w; + wd->group_item_height = h; + if (wd->calc_job) ecore_job_del(wd->calc_job); + wd->calc_job = ecore_job_add(_calc_job, wd); +} + +EAPI void +elm_gengrid_group_item_size_get(const Evas_Object *obj, + Evas_Coord *w, + Evas_Coord *h) +{ + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + if (w) *w = wd->group_item_width; + if (h) *h = wd->group_item_height; +} + +EAPI void elm_gengrid_align_set(Evas_Object *obj, double align_x, double align_y) { ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + double old_h = wd->align_x, old_y = wd->align_y; if (align_x > 1.0) align_x = 1.0; @@ -1809,6 +2049,9 @@ elm_gengrid_align_set(Evas_Object *obj, else if (align_y < 0.0) align_y = 0.0; wd->align_y = align_y; + + if ((old_h != wd->align_x) || (old_y != wd->align_y)) + evas_object_smart_calculate(wd->pan_smart); } EAPI void @@ -1822,165 +2065,159 @@ elm_gengrid_align_get(const Evas_Object *obj, if (align_y) *align_y = wd->align_y; } -EAPI Elm_Gengrid_Item * +EAPI Elm_Object_Item * elm_gengrid_item_append(Evas_Object *obj, - const Elm_Gengrid_Item_Class *gic, + const Elm_Gengrid_Item_Class *itc, const void *data, Evas_Smart_Cb func, const void *func_data) { - Elm_Gengrid_Item *it; + Elm_Gen_Item *it; ELM_CHECK_WIDTYPE(obj, widtype) NULL; Widget_Data *wd = elm_widget_data_get(obj); if (!wd) return NULL; - it = _item_create(wd, gic, data, func, func_data); + it = _item_new(wd, itc, data, func, func_data); if (!it) return NULL; wd->items = eina_inlist_append(wd->items, EINA_INLIST_GET(it)); + it->position = eina_inlist_count(wd->items); + it->position_update = EINA_TRUE; + + if (it->group) + wd->group_items = eina_list_prepend(wd->group_items, it); if (wd->calc_job) ecore_job_del(wd->calc_job); wd->calc_job = ecore_job_add(_calc_job, wd); - return it; + return (Elm_Object_Item *)it; } -EAPI Elm_Gengrid_Item * +EAPI Elm_Object_Item * elm_gengrid_item_prepend(Evas_Object *obj, - const Elm_Gengrid_Item_Class *gic, + const Elm_Gengrid_Item_Class *itc, const void *data, Evas_Smart_Cb func, const void *func_data) { - Elm_Gengrid_Item *it; + Elm_Gen_Item *it; ELM_CHECK_WIDTYPE(obj, widtype) NULL; Widget_Data *wd = elm_widget_data_get(obj); if (!wd) return NULL; - it = _item_create(wd, gic, data, func, func_data); + it = _item_new(wd, itc, data, func, func_data); if (!it) return NULL; wd->items = eina_inlist_prepend(wd->items, EINA_INLIST_GET(it)); + _item_position_update(wd->items, 0); + + if (it->group) + wd->group_items = eina_list_append(wd->group_items, it); if (wd->calc_job) ecore_job_del(wd->calc_job); wd->calc_job = ecore_job_add(_calc_job, wd); - return it; + return (Elm_Object_Item *)it; } -EAPI Elm_Gengrid_Item * +EAPI Elm_Object_Item * elm_gengrid_item_insert_before(Evas_Object *obj, - const Elm_Gengrid_Item_Class *gic, + const Elm_Gengrid_Item_Class *itc, const void *data, - Elm_Gengrid_Item *relative, + Elm_Object_Item *relative, Evas_Smart_Cb func, const void *func_data) { - Elm_Gengrid_Item *it; + Elm_Gen_Item *it; ELM_CHECK_WIDTYPE(obj, widtype) NULL; - EINA_SAFETY_ON_NULL_RETURN_VAL(relative, NULL); + ELM_OBJ_ITEM_CHECK_OR_RETURN(relative, NULL); Widget_Data *wd = elm_widget_data_get(obj); if (!wd) return NULL; - it = _item_create(wd, gic, data, func, func_data); + it = _item_new(wd, itc, data, func, func_data); if (!it) return NULL; wd->items = eina_inlist_prepend_relative - (wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(relative)); + (wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET((Elm_Gen_Item *) relative)); + Eina_Inlist *tmp = eina_inlist_find(wd->items, EINA_INLIST_GET(it)); + _item_position_update(tmp, ((Elm_Gen_Item *)relative)->position); + + if (it->group) + wd->group_items = eina_list_append_relative(wd->group_items, it, ((Elm_Gen_Item *) relative)->parent); if (wd->calc_job) ecore_job_del(wd->calc_job); wd->calc_job = ecore_job_add(_calc_job, wd); - return it; + return (Elm_Object_Item *)it; } -EAPI Elm_Gengrid_Item * +EAPI Elm_Object_Item * elm_gengrid_item_insert_after(Evas_Object *obj, - const Elm_Gengrid_Item_Class *gic, + const Elm_Gengrid_Item_Class *itc, const void *data, - Elm_Gengrid_Item *relative, + Elm_Object_Item *relative, Evas_Smart_Cb func, const void *func_data) { - Elm_Gengrid_Item *it; + Elm_Gen_Item *it; ELM_CHECK_WIDTYPE(obj, widtype) NULL; - EINA_SAFETY_ON_NULL_RETURN_VAL(relative, NULL); + ELM_OBJ_ITEM_CHECK_OR_RETURN(relative, NULL); Widget_Data *wd = elm_widget_data_get(obj); if (!wd) return NULL; - it = _item_create(wd, gic, data, func, func_data); + it = _item_new(wd, itc, data, func, func_data); if (!it) return NULL; wd->items = eina_inlist_append_relative - (wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(relative)); + (wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET((Elm_Gen_Item *) relative)); + Eina_Inlist *tmp = eina_inlist_find(wd->items, EINA_INLIST_GET(it)); + _item_position_update(tmp, ((Elm_Gen_Item *)relative)->position+1); - if (wd->calc_job) ecore_job_del(wd->calc_job); - wd->calc_job = ecore_job_add(_calc_job, wd); + if (it->group) + wd->group_items = eina_list_prepend_relative(wd->group_items, it, ((Elm_Gen_Item *) relative)->parent); - return it; -} - -EAPI Elm_Gengrid_Item * -elm_gengrid_item_direct_sorted_insert(Evas_Object *obj, - const Elm_Gengrid_Item_Class *gic, - const void *data, - Eina_Compare_Cb comp, - Evas_Smart_Cb func, - const void *func_data) -{ - Elm_Gengrid_Item *it; - ELM_CHECK_WIDTYPE(obj, widtype) NULL; - Widget_Data *wd = elm_widget_data_get(obj); - if (!wd) return NULL; - - it = _item_create(wd, gic, data, func, func_data); - if (!it) return NULL; - - _elm_gengrid_item_compare_cb = comp; - wd->items = eina_inlist_sorted_insert(wd->items, EINA_INLIST_GET(it), - _elm_gengrid_item_compare); if (wd->calc_job) ecore_job_del(wd->calc_job); wd->calc_job = ecore_job_add(_calc_job, wd); - return it; + return (Elm_Object_Item *)it; } -EAPI Elm_Gengrid_Item * +EAPI Elm_Object_Item * elm_gengrid_item_sorted_insert(Evas_Object *obj, - const Elm_Gengrid_Item_Class *gic, + const Elm_Gengrid_Item_Class *itc, const void *data, Eina_Compare_Cb comp, Evas_Smart_Cb func, const void *func_data) { - _elm_gengrid_item_compare_data_cb = comp; + Elm_Gen_Item *it; + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return NULL; - return elm_gengrid_item_direct_sorted_insert(obj, gic, data, _elm_gengrid_item_compare_data, func, func_data); -} + it = _item_new(wd, itc, data, func, func_data); + if (!it) return NULL; -EAPI void -elm_gengrid_item_del(Elm_Gengrid_Item *it) -{ - ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it); - if ((it->relcount > 0) || (it->walking > 0)) - { - it->delete_me = EINA_TRUE; - elm_widget_item_pre_notify_del(it); - if (it->selected) - it->wd->selected = eina_list_remove(it->wd->selected, it); - if (it->gic->func.del) - it->gic->func.del((void *)it->base.data, it->wd->self); - return; - } + if (!wd->state) + wd->state = eina_inlist_sorted_state_new(); + + wd->item_compare_cb = comp; + wd->items = eina_inlist_sorted_state_insert(wd->items, EINA_INLIST_GET(it), + _elm_gengrid_item_compare, wd->state); + _item_position_update(wd->items, 0); + + if (wd->calc_job) ecore_job_del(wd->calc_job); + wd->calc_job = ecore_job_add(_calc_job, wd); - _item_del(it); + return (Elm_Object_Item *)it; } EAPI void elm_gengrid_horizontal_set(Evas_Object *obj, - Eina_Bool setting) + Eina_Bool horizontal) { ELM_CHECK_WIDTYPE(obj, widtype); Widget_Data *wd = elm_widget_data_get(obj); if (!wd) return; - if (setting == wd->horizontal) return; - wd->horizontal = setting; + horizontal = !!horizontal; + if (horizontal == wd->horizontal) return; + wd->horizontal = horizontal; /* Update the items to conform to the new layout */ if (wd->calc_job) ecore_job_del(wd->calc_job); @@ -1999,114 +2236,54 @@ elm_gengrid_horizontal_get(const Evas_Object *obj) EAPI void elm_gengrid_clear(Evas_Object *obj) { - ELM_CHECK_WIDTYPE(obj, widtype); - Widget_Data *wd = elm_widget_data_get(obj); - if (!wd) return; - - if (wd->calc_job) - { - ecore_job_del(wd->calc_job); - wd->calc_job = NULL; - } - - if (wd->walking > 0) - { - Elm_Gengrid_Item *it; - wd->clear_me = 1; - EINA_INLIST_FOREACH(wd->items, it) - it->delete_me = 1; - return; - } - wd->clear_me = 0; - while (wd->items) - { - Elm_Gengrid_Item *it = ELM_GENGRID_ITEM_FROM_INLIST(wd->items); - - wd->items = eina_inlist_remove(wd->items, wd->items); - elm_widget_item_pre_notify_del(it); - if (it->realized) _item_unrealize(it); - if (it->gic->func.del) - it->gic->func.del((void *)it->base.data, wd->self); - if (it->long_timer) ecore_timer_del(it->long_timer); - elm_widget_item_del(it); - } - - if (wd->selected) - { - eina_list_free(wd->selected); - wd->selected = NULL; - } - - wd->pan_x = 0; - wd->pan_y = 0; - wd->minw = 0; - wd->minh = 0; - wd->count = 0; - evas_object_size_hint_min_set(wd->pan_smart, wd->minw, wd->minh); - evas_object_smart_callback_call(wd->pan_smart, "changed", NULL); + elm_genlist_clear(obj); } -EAPI const Evas_Object * -elm_gengrid_item_object_get(const Elm_Gengrid_Item *it) +EINA_DEPRECATED EAPI const Evas_Object * +elm_gengrid_item_object_get(const Elm_Object_Item *it) { - ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL); + ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL); return VIEW(it); } EAPI void -elm_gengrid_item_update(Elm_Gengrid_Item *it) -{ - ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it); - if (!it->realized) return; - if (it->want_unrealize) return; - _item_unrealize(it); - _item_realize(it); - _item_place(it, it->x, it->y); -} - -EAPI void * -elm_gengrid_item_data_get(const Elm_Gengrid_Item *it) -{ - ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL); - return elm_widget_item_data_get(it); -} - -EAPI void -elm_gengrid_item_data_set(Elm_Gengrid_Item *it, - const void *data) +elm_gengrid_item_update(Elm_Object_Item *it) { - ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it); - elm_widget_item_data_set(it, data); - elm_gengrid_item_update(it); + ELM_OBJ_ITEM_CHECK_OR_RETURN(it); + Elm_Gen_Item *_it = (Elm_Gen_Item *)it; + if (!_it->realized) return; + if (_it->want_unrealize) return; + _elm_genlist_item_unrealize(_it, EINA_FALSE); + _item_realize(_it); + _item_place(_it, _it->x, _it->y); } EAPI const Elm_Gengrid_Item_Class * -elm_gengrid_item_item_class_get(const Elm_Gengrid_Item *it) +elm_gengrid_item_item_class_get(const Elm_Object_Item *it) { - ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL); - if (it->delete_me) return NULL; - return it->gic; + return (Elm_Gengrid_Item_Class *)elm_genlist_item_item_class_get(it); } EAPI void -elm_gengrid_item_item_class_set(Elm_Gengrid_Item *it, - const Elm_Gengrid_Item_Class *gic) -{ - ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it); - EINA_SAFETY_ON_NULL_RETURN(gic); - if (it->delete_me) return; - it->gic = gic; +elm_gengrid_item_item_class_update(Elm_Object_Item *it, + const Elm_Gengrid_Item_Class *itc) +{ + ELM_OBJ_ITEM_CHECK_OR_RETURN(it); + EINA_SAFETY_ON_NULL_RETURN(itc); + Elm_Gen_Item *_it = (Elm_Gen_Item *)it; + if (_it->generation < _it->wd->generation) return; + _it->itc = itc; elm_gengrid_item_update(it); } EAPI void -elm_gengrid_item_pos_get(const Elm_Gengrid_Item *it, +elm_gengrid_item_pos_get(const Elm_Object_Item *it, unsigned int *x, unsigned int *y) { - ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it); - if (x) *x = it->x; - if (y) *y = it->y; + ELM_OBJ_ITEM_CHECK_OR_RETURN(it); + if (x) *x = ((Elm_Gen_Item *)it)->x; + if (y) *y = ((Elm_Gen_Item *)it)->y; } EAPI void @@ -2116,7 +2293,7 @@ elm_gengrid_multi_select_set(Evas_Object *obj, ELM_CHECK_WIDTYPE(obj, widtype); Widget_Data *wd = elm_widget_data_get(obj); if (!wd) return; - wd->multi = multi; + wd->multi = !!multi; } EAPI Eina_Bool @@ -2128,7 +2305,7 @@ elm_gengrid_multi_select_get(const Evas_Object *obj) return wd->multi; } -EAPI Elm_Gengrid_Item * +EAPI Elm_Object_Item * elm_gengrid_selected_item_get(const Evas_Object *obj) { ELM_CHECK_WIDTYPE(obj, widtype) NULL; @@ -2141,74 +2318,55 @@ elm_gengrid_selected_item_get(const Evas_Object *obj) EAPI const Eina_List * elm_gengrid_selected_items_get(const Evas_Object *obj) { - ELM_CHECK_WIDTYPE(obj, widtype) NULL; - Widget_Data *wd = elm_widget_data_get(obj); - if (!wd) return NULL; - return wd->selected; + return elm_genlist_selected_items_get(obj); } EAPI void -elm_gengrid_item_selected_set(Elm_Gengrid_Item *it, +elm_gengrid_item_selected_set(Elm_Object_Item *it, Eina_Bool selected) { - ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it); - Widget_Data *wd = it->wd; - if (!wd) return; - if (it->delete_me) return; - selected = !!selected; - if (it->selected == selected) return; - - if (selected) - { - if (!wd->multi) - { - while (wd->selected) - _item_unselect(wd->selected->data); - } - _item_hilight(it); - _item_select(it); - } - else - _item_unselect(it); + elm_genlist_item_selected_set(it, selected); } EAPI Eina_Bool -elm_gengrid_item_selected_get(const Elm_Gengrid_Item *it) +elm_gengrid_item_selected_get(const Elm_Object_Item *it) { - ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, EINA_FALSE); - return it->selected; + return elm_genlist_item_selected_get(it); } -EAPI void -elm_gengrid_item_disabled_set(Elm_Gengrid_Item *it, - Eina_Bool disabled) +EAPI Eina_List * +elm_gengrid_realized_items_get(const Evas_Object *obj) { - ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it); - if (it->disabled == disabled) return; - if (it->delete_me) return; - it->disabled = !!disabled; - if (it->realized) + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd = elm_widget_data_get(obj); + Eina_List *list = NULL; + Elm_Gen_Item *it; + + EINA_INLIST_FOREACH(wd->items, it) { - if (it->disabled) - edje_object_signal_emit(VIEW(it), "elm,state,disabled", "elm"); - else - edje_object_signal_emit(VIEW(it), "elm,state,enabled", "elm"); + if (it->realized) list = eina_list_append(list, (Elm_Object_Item *)it); } + return list; } -EAPI Eina_Bool -elm_gengrid_item_disabled_get(const Elm_Gengrid_Item *it) +EAPI void +elm_gengrid_realized_items_update(Evas_Object *obj) { - ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, EINA_FALSE); - if (it->delete_me) return EINA_FALSE; - return it->disabled; + ELM_CHECK_WIDTYPE(obj, widtype); + + Eina_List *list, *l; + Elm_Object_Item *it; + + list = elm_gengrid_realized_items_get(obj); + EINA_LIST_FOREACH(list, l, it) + elm_gengrid_item_update(it); } static Evas_Object * _elm_gengrid_item_label_create(void *data, Evas_Object *obj __UNUSED__, Evas_Object *tooltip, - void *item __UNUSED__) + void *it __UNUSED__) { Evas_Object *label = elm_label_add(tooltip); if (!label) @@ -2227,10 +2385,10 @@ _elm_gengrid_item_label_del_cb(void *data, } EAPI void -elm_gengrid_item_tooltip_text_set(Elm_Gengrid_Item *it, +elm_gengrid_item_tooltip_text_set(Elm_Object_Item *it, const char *text) { - ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it); + ELM_OBJ_ITEM_CHECK_OR_RETURN(it); text = eina_stringshare_add(text); elm_gengrid_item_tooltip_content_cb_set(it, _elm_gengrid_item_label_create, text, @@ -2238,28 +2396,29 @@ elm_gengrid_item_tooltip_text_set(Elm_Gengrid_Item *it, } EAPI void -elm_gengrid_item_tooltip_content_cb_set(Elm_Gengrid_Item *it, +elm_gengrid_item_tooltip_content_cb_set(Elm_Object_Item *it, Elm_Tooltip_Item_Content_Cb func, const void *data, Evas_Smart_Cb del_cb) { - ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_GOTO(it, error); + ELM_OBJ_ITEM_CHECK_OR_GOTO(it, error); + Elm_Gen_Item *_it = (Elm_Gen_Item *)it; - if ((it->tooltip.content_cb == func) && (it->tooltip.data == data)) + if ((_it->tooltip.content_cb == func) && (_it->tooltip.data == data)) return; - if (it->tooltip.del_cb) - it->tooltip.del_cb((void *)it->tooltip.data, - WIDGET(it), it); - it->tooltip.content_cb = func; - it->tooltip.data = data; - it->tooltip.del_cb = del_cb; - if (VIEW(it)) + if (_it->tooltip.del_cb) + _it->tooltip.del_cb((void *)_it->tooltip.data, WIDGET(_it), _it); + _it->tooltip.content_cb = func; + _it->tooltip.data = data; + _it->tooltip.del_cb = del_cb; + if (VIEW(_it)) { - elm_widget_item_tooltip_content_cb_set(it, - it->tooltip.content_cb, - it->tooltip.data, NULL); - elm_widget_item_tooltip_style_set(it, it->tooltip.style); + elm_widget_item_tooltip_content_cb_set(_it, + _it->tooltip.content_cb, + _it->tooltip.data, NULL); + elm_widget_item_tooltip_style_set(_it, _it->tooltip.style); + elm_widget_item_tooltip_window_mode_set(_it, _it->tooltip.free_size); } return; @@ -2269,108 +2428,109 @@ error: } EAPI void -elm_gengrid_item_tooltip_unset(Elm_Gengrid_Item *it) -{ - ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it); - if ((VIEW(it)) && (it->tooltip.content_cb)) - elm_widget_item_tooltip_unset(it); - - if (it->tooltip.del_cb) - it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it); - it->tooltip.del_cb = NULL; - it->tooltip.content_cb = NULL; - it->tooltip.data = NULL; - if (it->tooltip.style) +elm_gengrid_item_tooltip_unset(Elm_Object_Item *it) +{ + ELM_OBJ_ITEM_CHECK_OR_RETURN(it); + Elm_Gen_Item *_it = (Elm_Gen_Item *)it; + + if ((VIEW(_it)) && (_it->tooltip.content_cb)) + elm_widget_item_tooltip_unset(_it); + + if (_it->tooltip.del_cb) + _it->tooltip.del_cb((void *) _it->tooltip.data, WIDGET(_it), _it); + _it->tooltip.del_cb = NULL; + _it->tooltip.content_cb = NULL; + _it->tooltip.data = NULL; + _it->tooltip.free_size = EINA_FALSE; + if (_it->tooltip.style) elm_gengrid_item_tooltip_style_set(it, NULL); } EAPI void -elm_gengrid_item_tooltip_style_set(Elm_Gengrid_Item *it, +elm_gengrid_item_tooltip_style_set(Elm_Object_Item *it, const char *style) { - ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it); - eina_stringshare_replace(&it->tooltip.style, style); + ELM_OBJ_ITEM_CHECK_OR_RETURN(it); + eina_stringshare_replace(&((Elm_Gen_Item *)it)->tooltip.style, style); if (VIEW(it)) elm_widget_item_tooltip_style_set(it, style); } EAPI const char * -elm_gengrid_item_tooltip_style_get(const Elm_Gengrid_Item *it) +elm_gengrid_item_tooltip_style_get(const Elm_Object_Item *it) { - ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL); - return it->tooltip.style; + ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL); + return ((Elm_Gen_Item *)it)->tooltip.style; } EAPI Eina_Bool -elm_gengrid_item_tooltip_size_restrict_disable(Elm_Gengrid_Item *item, Eina_Bool disable) +elm_gengrid_item_tooltip_window_mode_set(Elm_Object_Item *it, Eina_Bool disable) { - ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(item, EINA_FALSE); - return elm_widget_item_tooltip_size_restrict_disable(item, disable); + ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE); + ((Elm_Gen_Item *)it)->tooltip.free_size = disable; + if (VIEW(it)) return elm_widget_item_tooltip_window_mode_set(it, disable); + return EINA_TRUE; } EAPI Eina_Bool -elm_gengrid_item_tooltip_size_restrict_disabled_get(const Elm_Gengrid_Item *item) +elm_gengrid_item_tooltip_window_mode_get(const Elm_Object_Item *it) { - ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(item, EINA_FALSE); - return elm_widget_item_tooltip_size_restrict_disabled_get(item); + ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE); + return ((Elm_Gen_Item *)it)->tooltip.free_size; } EAPI void -elm_gengrid_item_cursor_set(Elm_Gengrid_Item *it, +elm_gengrid_item_cursor_set(Elm_Object_Item *it, const char *cursor) { - ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it); - eina_stringshare_replace(&it->mouse_cursor, cursor); + ELM_OBJ_ITEM_CHECK_OR_RETURN(it); + eina_stringshare_replace(&((Elm_Gen_Item *)it)->mouse_cursor, cursor); if (VIEW(it)) elm_widget_item_cursor_set(it, cursor); } EAPI const char * -elm_gengrid_item_cursor_get(const Elm_Gengrid_Item *it) +elm_gengrid_item_cursor_get(const Elm_Object_Item *it) { - ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL); return elm_widget_item_cursor_get(it); } EAPI void -elm_gengrid_item_cursor_unset(Elm_Gengrid_Item *it) +elm_gengrid_item_cursor_unset(Elm_Object_Item *it) { - ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it); - if (!it->mouse_cursor) + ELM_OBJ_ITEM_CHECK_OR_RETURN(it); + Elm_Gen_Item *_it = (Elm_Gen_Item *)it; + if (!_it->mouse_cursor) return; - if (VIEW(it)) - elm_widget_item_cursor_unset(it); + if (VIEW(_it)) + elm_widget_item_cursor_unset(_it); - eina_stringshare_del(it->mouse_cursor); - it->mouse_cursor = NULL; + eina_stringshare_del(_it->mouse_cursor); + _it->mouse_cursor = NULL; } EAPI void -elm_gengrid_item_cursor_style_set(Elm_Gengrid_Item *it, +elm_gengrid_item_cursor_style_set(Elm_Object_Item *it, const char *style) { - ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it); elm_widget_item_cursor_style_set(it, style); } EAPI const char * -elm_gengrid_item_cursor_style_get(const Elm_Gengrid_Item *it) +elm_gengrid_item_cursor_style_get(const Elm_Object_Item *it) { - ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL); return elm_widget_item_cursor_style_get(it); } EAPI void -elm_gengrid_item_cursor_engine_only_set(Elm_Gengrid_Item *it, +elm_gengrid_item_cursor_engine_only_set(Elm_Object_Item *it, Eina_Bool engine_only) { - ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it); elm_widget_item_cursor_engine_only_set(it, engine_only); } EAPI Eina_Bool -elm_gengrid_item_cursor_engine_only_get(const Elm_Gengrid_Item *it) +elm_gengrid_item_cursor_engine_only_get(const Elm_Object_Item *it) { - ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, EINA_FALSE); return elm_widget_item_cursor_engine_only_get(it); } @@ -2381,7 +2541,7 @@ elm_gengrid_reorder_mode_set(Evas_Object *obj, ELM_CHECK_WIDTYPE(obj, widtype); Widget_Data *wd = elm_widget_data_get(obj); if (!wd) return; - wd->reorder_mode = reorder_mode; + wd->reorder_mode = !!reorder_mode; } EAPI Eina_Bool @@ -2394,200 +2554,316 @@ elm_gengrid_reorder_mode_get(const Evas_Object *obj) } EAPI void -elm_gengrid_always_select_mode_set(Evas_Object *obj, - Eina_Bool always_select) +elm_gengrid_bounce_set(Evas_Object *obj, + Eina_Bool h_bounce, + Eina_Bool v_bounce) { - ELM_CHECK_WIDTYPE(obj, widtype); - Widget_Data *wd = elm_widget_data_get(obj); - if (!wd) return; - wd->always_select = always_select; + elm_genlist_bounce_set(obj, h_bounce, v_bounce); } -EAPI Eina_Bool -elm_gengrid_always_select_mode_get(const Evas_Object *obj) +EAPI void +elm_gengrid_bounce_get(const Evas_Object *obj, + Eina_Bool *h_bounce, + Eina_Bool *v_bounce) { - ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; - Widget_Data *wd = elm_widget_data_get(obj); - if (!wd) return EINA_FALSE; - return wd->always_select; + elm_genlist_bounce_get(obj, h_bounce, v_bounce); } EAPI void -elm_gengrid_no_select_mode_set(Evas_Object *obj, - Eina_Bool no_select) +elm_gengrid_page_relative_set(Evas_Object *obj, + double h_pagerel, + double v_pagerel) { - ELM_CHECK_WIDTYPE(obj, widtype); - Widget_Data *wd = elm_widget_data_get(obj); - if (!wd) return; - wd->no_select = no_select; + _elm_genlist_page_relative_set(obj, h_pagerel, v_pagerel); } -EAPI Eina_Bool -elm_gengrid_no_select_mode_get(const Evas_Object *obj) +EAPI void +elm_gengrid_page_relative_get(const Evas_Object *obj, double *h_pagerel, double *v_pagerel) { - ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; - Widget_Data *wd = elm_widget_data_get(obj); - if (!wd) return EINA_FALSE; - return wd->no_select; + _elm_genlist_page_relative_get(obj, h_pagerel, v_pagerel); } EAPI void -elm_gengrid_bounce_set(Evas_Object *obj, - Eina_Bool h_bounce, - Eina_Bool v_bounce) +elm_gengrid_page_size_set(Evas_Object *obj, + Evas_Coord h_pagesize, + Evas_Coord v_pagesize) { - ELM_CHECK_WIDTYPE(obj, widtype); - Widget_Data *wd = elm_widget_data_get(obj); - if (!wd) return; - elm_smart_scroller_bounce_allow_set(wd->scr, h_bounce, v_bounce); - wd->h_bounce = h_bounce; - wd->v_bounce = v_bounce; + _elm_genlist_page_size_set(obj, h_pagesize, v_pagesize); } EAPI void -elm_gengrid_bounce_get(const Evas_Object *obj, - Eina_Bool *h_bounce, - Eina_Bool *v_bounce) +elm_gengrid_current_page_get(const Evas_Object *obj, int *h_pagenumber, int *v_pagenumber) { - ELM_CHECK_WIDTYPE(obj, widtype); - Widget_Data *wd = elm_widget_data_get(obj); - if (!wd) return; - *h_bounce = wd->h_bounce; - *v_bounce = wd->v_bounce; + _elm_genlist_current_page_get(obj, h_pagenumber, v_pagenumber); } EAPI void -elm_gengrid_page_relative_set(Evas_Object *obj, - double h_pagerel, - double v_pagerel) +elm_gengrid_last_page_get(const Evas_Object *obj, int *h_pagenumber, int *v_pagenumber) +{ + _elm_genlist_last_page_get(obj, h_pagenumber, v_pagenumber); +} + +EAPI void +elm_gengrid_page_show(const Evas_Object *obj, int h_pagenumber, int v_pagenumber) { - Evas_Coord pagesize_h; - Evas_Coord pagesize_v; + _elm_genlist_page_show(obj, h_pagenumber, v_pagenumber); +} +EAPI void +elm_gengrid_page_bring_in(const Evas_Object *obj, int h_pagenumber, int v_pagenumber) +{ + _elm_genlist_page_bring_in(obj, h_pagenumber, v_pagenumber); +} + +EAPI void +elm_gengrid_scroller_policy_set(Evas_Object *obj, + Elm_Scroller_Policy policy_h, + Elm_Scroller_Policy policy_v) +{ ELM_CHECK_WIDTYPE(obj, widtype); Widget_Data *wd = elm_widget_data_get(obj); - if (!wd) return; - - elm_smart_scroller_paging_get(wd->scr, NULL, NULL, &pagesize_h, &pagesize_v); - elm_smart_scroller_paging_set(wd->scr, h_pagerel, v_pagerel, pagesize_h, - pagesize_v); + if ((!wd) || (!wd->scr)) return; + if ((policy_h >= ELM_SCROLLER_POLICY_LAST) || + (policy_v >= ELM_SCROLLER_POLICY_LAST)) + return; + elm_smart_scroller_policy_set(wd->scr, policy_h, policy_v); } EAPI void -elm_gengrid_page_relative_get(const Evas_Object *obj, double *h_pagerel, double *v_pagerel) +elm_gengrid_scroller_policy_get(const Evas_Object *obj, + Elm_Scroller_Policy *policy_h, + Elm_Scroller_Policy *policy_v) { ELM_CHECK_WIDTYPE(obj, widtype); Widget_Data *wd = elm_widget_data_get(obj); - if (!wd) return; + Elm_Smart_Scroller_Policy s_policy_h, s_policy_v; + if ((!wd) || (!wd->scr)) return; + elm_smart_scroller_policy_get(wd->scr, &s_policy_h, &s_policy_v); + if (policy_h) *policy_h = (Elm_Scroller_Policy)s_policy_h; + if (policy_v) *policy_v = (Elm_Scroller_Policy)s_policy_v; +} + +EAPI Elm_Object_Item * +elm_gengrid_first_item_get(const Evas_Object *obj) +{ + return elm_genlist_first_item_get(obj); +} + +EAPI Elm_Object_Item * +elm_gengrid_last_item_get(const Evas_Object *obj) +{ + return elm_genlist_last_item_get(obj); +} + +EAPI Elm_Object_Item * +elm_gengrid_item_next_get(const Elm_Object_Item *it) +{ + return elm_genlist_item_next_get(it); +} - elm_smart_scroller_paging_get(wd->scr, h_pagerel, v_pagerel, NULL, NULL); +EAPI Elm_Object_Item * +elm_gengrid_item_prev_get(const Elm_Object_Item *it) +{ + return elm_genlist_item_prev_get(it); } EAPI void -elm_gengrid_page_size_set(Evas_Object *obj, - Evas_Coord h_pagesize, - Evas_Coord v_pagesize) +elm_gengrid_item_show(Elm_Object_Item *it, Elm_Gengrid_Item_Scrollto_Type type) { - double pagerel_h; - double pagerel_v; + ELM_OBJ_ITEM_CHECK_OR_RETURN(it); + Elm_Gen_Item *_it = (Elm_Gen_Item *)it; + Widget_Data *wd = _it->wd; + Evas_Coord minx = 0, miny = 0; + + if ((_it->generation < _it->wd->generation)) return; + _pan_min_get(wd->pan_smart, &minx, &miny); + + if (type==ELM_GENGRID_ITEM_SCROLLTO_IN) + { + //TODO : type based handling like genlist + } + + if (wd->horizontal) + elm_smart_scroller_region_bring_in(_it->wd->scr, + ((_it->x - _it->item->prev_group) * wd->item_width) + (_it->item->prev_group * _it->wd->group_item_width) + minx, + _it->y * wd->item_height + miny, + _it->wd->item_width, + _it->wd->item_height); + else + elm_smart_scroller_region_bring_in(_it->wd->scr, + _it->x * wd->item_width + minx, + ((_it->y - _it->item->prev_group) * wd->item_height) + (_it->item->prev_group * _it->wd->group_item_height) + miny, + _it->wd->item_width, + _it->wd->item_height); +} + +EAPI void +elm_gengrid_item_bring_in(Elm_Object_Item *it, Elm_Gengrid_Item_Scrollto_Type type) +{ + ELM_OBJ_ITEM_CHECK_OR_RETURN(it); + Elm_Gen_Item *_it = (Elm_Gen_Item *)it; + + if (_it->generation < _it->wd->generation) return; + Evas_Coord minx = 0, miny = 0; + Widget_Data *wd = _it->wd; + _pan_min_get(wd->pan_smart, &minx, &miny); + + if (type==ELM_GENGRID_ITEM_SCROLLTO_IN) + { + //TODO : type based handling like genlist + } + + if (wd->horizontal) + elm_smart_scroller_region_bring_in(_it->wd->scr, + ((_it->x - _it->item->prev_group) * wd->item_width) + (_it->item->prev_group * _it->wd->group_item_width) + minx, + _it->y * wd->item_height + miny, + _it->wd->item_width, + _it->wd->item_height); + else + elm_smart_scroller_region_bring_in(_it->wd->scr, + _it->x * wd->item_width + minx, + ((_it->y - _it->item->prev_group)* wd->item_height) + (_it->item->prev_group * _it->wd->group_item_height) + miny, + _it->wd->item_width, + _it->wd->item_height); +} + +EAPI void +elm_gengrid_filled_set(Evas_Object *obj, Eina_Bool fill) +{ ELM_CHECK_WIDTYPE(obj, widtype); Widget_Data *wd = elm_widget_data_get(obj); if (!wd) return; - elm_smart_scroller_paging_get(wd->scr, &pagerel_h, &pagerel_v, NULL, NULL); - elm_smart_scroller_paging_set(wd->scr, pagerel_h, pagerel_v, h_pagesize, - v_pagesize); + fill = !!fill; + if (wd->filled != fill) + wd->filled = fill; } -EAPI Elm_Gengrid_Item * -elm_gengrid_first_item_get(const Evas_Object *obj) +EAPI Eina_Bool +elm_gengrid_filled_get(const Evas_Object *obj) { - ELM_CHECK_WIDTYPE(obj, widtype) NULL; + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; Widget_Data *wd = elm_widget_data_get(obj); - if (!wd) return NULL; - if (!wd->items) return NULL; - Elm_Gengrid_Item *it = ELM_GENGRID_ITEM_FROM_INLIST(wd->items); - while ((it) && (it->delete_me)) - it = ELM_GENGRID_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next); - return it; + if (!wd) return EINA_FALSE; + return wd->filled; } -EAPI Elm_Gengrid_Item * -elm_gengrid_last_item_get(const Evas_Object *obj) +EAPI unsigned int +elm_gengrid_items_count(const Evas_Object *obj) { - ELM_CHECK_WIDTYPE(obj, widtype) NULL; + ELM_CHECK_WIDTYPE(obj, widtype) 0; Widget_Data *wd = elm_widget_data_get(obj); - if (!wd) return NULL; - if (!wd->items) return NULL; - Elm_Gengrid_Item *it = ELM_GENGRID_ITEM_FROM_INLIST(wd->items->last); - while ((it) && (it->delete_me)) - it = ELM_GENGRID_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev); - return it; + if (!wd) return 0; + return wd->item_count; } -EAPI Elm_Gengrid_Item * -elm_gengrid_item_next_get(const Elm_Gengrid_Item *it) +EAPI Elm_Gengrid_Item_Class * +elm_gengrid_item_class_new(void) { - ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL); - while (it) + Elm_Gengrid_Item_Class *itc; + + itc = calloc(1, sizeof(Elm_Gengrid_Item_Class)); + if (!itc) + return NULL; + itc->version = CLASS_ALLOCATED; + itc->refcount = 1; + itc->delete_me = EINA_FALSE; + + return itc; +} + +EAPI void +elm_gengrid_item_class_free(Elm_Gengrid_Item_Class *itc) +{ + if (itc && (itc->version == CLASS_ALLOCATED)) + { + if (!itc->delete_me) itc->delete_me = EINA_TRUE; + if (itc->refcount > 0) elm_gengrid_item_class_unref(itc); + else + { + itc->version = 0; + free(itc); + } + } +} + +EAPI void +elm_gengrid_item_class_ref(Elm_Gengrid_Item_Class *itc) +{ + if (itc && (itc->version == CLASS_ALLOCATED)) { - it = ELM_GENGRID_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next); - if ((it) && (!it->delete_me)) break; + itc->refcount++; + if (itc->refcount == 0) itc->refcount--; } - return (Elm_Gengrid_Item *)it; } -EAPI Elm_Gengrid_Item * -elm_gengrid_item_prev_get(const Elm_Gengrid_Item *it) +EAPI void +elm_gengrid_item_class_unref(Elm_Gengrid_Item_Class *itc) { - ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL); - while (it) + if (itc && (itc->version == CLASS_ALLOCATED)) { - it = ELM_GENGRID_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev); - if ((it) && (!it->delete_me)) break; + if (itc->refcount > 0) itc->refcount--; + if (itc->delete_me && (!itc->refcount)) + elm_gengrid_item_class_free(itc); } - return (Elm_Gengrid_Item *)it; } -EAPI Evas_Object * -elm_gengrid_item_gengrid_get(const Elm_Gengrid_Item *it) +EAPI void +elm_gengrid_select_mode_set(Evas_Object *obj, Elm_Object_Select_Mode mode) { - ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL); - return WIDGET(it); + elm_genlist_select_mode_set(obj, mode); +} + +EAPI Elm_Object_Select_Mode +elm_gengrid_select_mode_get(const Evas_Object *obj) +{ + return elm_genlist_select_mode_get(obj); } EAPI void -elm_gengrid_item_show(Elm_Gengrid_Item *it) +elm_gengrid_highlight_mode_set(Evas_Object *obj, + Eina_Bool highlight) { - ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it); - Widget_Data *wd = elm_widget_data_get(it->wd->self); - Evas_Coord minx = 0, miny = 0; + elm_genlist_highlight_mode_set(obj, highlight); +} - if (!wd) return; - if ((!it) || (it->delete_me)) return; - _pan_min_get(wd->pan_smart, &minx, &miny); +EAPI Eina_Bool +elm_gengrid_highlight_mode_get(const Evas_Object *obj) +{ + return elm_genlist_highlight_mode_get(obj); +} + +EAPI int +elm_gengrid_item_index_get(const Elm_Object_Item *it) +{ + ELM_OBJ_ITEM_CHECK_OR_RETURN(it, -1); + Elm_Gen_Item *_it = (Elm_Gen_Item *)it; - elm_smart_scroller_child_region_show(it->wd->scr, - it->x * wd->item_width + minx, - it->y * wd->item_height + miny, - it->wd->item_width, - it->wd->item_height); + return _it->position; } EAPI void -elm_gengrid_item_bring_in(Elm_Gengrid_Item *it) -{ - ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it); - if (it->delete_me) return; +elm_gengrid_item_select_mode_set(Elm_Object_Item *it, + Elm_Object_Select_Mode mode) +{ + ELM_OBJ_ITEM_CHECK_OR_RETURN(it); + Elm_Gen_Item *_it = (Elm_Gen_Item *)it; + if (!_it) return; + if (_it->generation < _it->wd->generation) return; + if (mode >= ELM_OBJECT_SELECT_MODE_MAX) + return; + if (_it->select_mode != mode) + _it->select_mode = mode; - Evas_Coord minx = 0, miny = 0; - Widget_Data *wd = elm_widget_data_get(it->wd->self); - if (!wd) return; - _pan_min_get(wd->pan_smart, &minx, &miny); + if (_it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY) + elm_gengrid_item_update(it); +} - elm_smart_scroller_region_bring_in(it->wd->scr, - it->x * wd->item_width + minx, - it->y * wd->item_height + miny, - it->wd->item_width, - it->wd->item_height); +EAPI Elm_Object_Select_Mode +elm_gengrid_item_select_mode_get(const Elm_Object_Item *it) +{ + ELM_OBJ_ITEM_CHECK_OR_RETURN(it, ELM_OBJECT_SELECT_MODE_MAX); + Elm_Gen_Item *_it = (Elm_Gen_Item *)it; + if (!_it) return ELM_OBJECT_SELECT_MODE_MAX; + return _it->select_mode; }