+
+EAPI Elm_Genlist_Item_Type
+elm_genlist_item_type_get(const Elm_Object_Item *it)
+{
+ ELM_OBJ_ITEM_CHECK_OR_RETURN(it, ELM_GENLIST_ITEM_MAX);
+ Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
+ return _it->item->type;
+}
+
+EINA_DEPRECATED EAPI Elm_Genlist_Item_Type
+elm_genlist_item_flags_get(const Elm_Object_Item *it)
+{
+ return elm_genlist_item_type_get(it);
+}
+
+EAPI Elm_Genlist_Item_Class *
+elm_genlist_item_class_new(void)
+{
+ Elm_Genlist_Item_Class *itc;
+
+ itc = calloc(1, sizeof(Elm_Genlist_Item_Class));
+ if (!itc)
+ return NULL;
+ itc->version = CLASS_ALLOCATED;
+ itc->refcount = 1;
+ itc->delete_me = EINA_FALSE;
+
+ return itc;
+}
+
+EAPI void
+elm_genlist_item_class_free(Elm_Genlist_Item_Class *itc)
+{
+ if (itc && (itc->version == CLASS_ALLOCATED))
+ {
+ if (!itc->delete_me) itc->delete_me = EINA_TRUE;
+ if (itc->refcount > 0) elm_genlist_item_class_unref(itc);
+ else
+ {
+ itc->version = 0;
+ free(itc);
+ }
+ }
+}
+
+EAPI void
+elm_genlist_item_class_ref(Elm_Genlist_Item_Class *itc)
+{
+ if (itc && (itc->version == CLASS_ALLOCATED))
+ {
+ itc->refcount++;
+ if (itc->refcount == 0) itc->refcount--;
+ }
+}
+
+EAPI void
+elm_genlist_item_class_unref(Elm_Genlist_Item_Class *itc)
+{
+ if (itc && (itc->version == CLASS_ALLOCATED))
+ {
+ if (itc->refcount > 0) itc->refcount--;
+ if (itc->delete_me && (!itc->refcount))
+ elm_genlist_item_class_free(itc);
+ }
+}
+
+void _flip_job(void *data)
+{
+ Elm_Gen_Item *it = (Elm_Gen_Item *) data;
+ _elm_genlist_item_unrealize(it, EINA_FALSE);
+ if (it->selected) _item_unselect(it);
+ it->flipped = EINA_TRUE;
+ it->item->nocache = EINA_TRUE;
+}
+
+EAPI void
+elm_genlist_item_flip_set(Elm_Object_Item *it,
+ Eina_Bool flip)
+{
+ ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
+ Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
+
+ flip = !!flip;
+ if (_it->flipped == flip) return;
+
+ if (flip)
+ {
+ ecore_job_add(_flip_job, _it);
+ if (_it->wd->calc_job) ecore_job_del(_it->wd->calc_job);
+ _it->wd->calc_job = ecore_job_add(_calc_job, _it->wd);
+ }
+ else
+ {
+ _it->flipped = flip;
+ _item_cache_zero(_it->wd);
+ elm_genlist_item_update(it);
+ _it->item->nocache = EINA_FALSE;
+ }
+}
+
+EAPI Eina_Bool
+elm_genlist_item_flip_get(const Elm_Object_Item *it)
+{
+ ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
+ Elm_Gen_Item *_it = (Elm_Gen_Item *)it;
+ return _it->flipped;
+}
+
+EAPI void
+elm_genlist_select_mode_set(Evas_Object *obj, Elm_Object_Select_Mode_Type mode)
+{
+ ELM_CHECK_WIDTYPE(obj, widtype);
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return;
+ if (mode >= ELM_OBJECT_SELECT_MODE_MAX)
+ return;
+ if (wd->select_mode != mode)
+ wd->select_mode = mode;
+}
+
+EAPI Elm_Object_Select_Mode_Type
+elm_genlist_select_mode_get(const Evas_Object *obj)
+{
+ ELM_CHECK_WIDTYPE(obj, widtype) ELM_OBJECT_SELECT_MODE_MAX;
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return ELM_OBJECT_SELECT_MODE_MAX;
+ return wd->select_mode;
+}
+
+EAPI void
+elm_genlist_hilight_mode_set(Evas_Object *obj,
+ Eina_Bool hilight)
+{
+ ELM_CHECK_WIDTYPE(obj, widtype);
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return;
+ hilight = !!hilight;
+ wd->no_highlight = !hilight;
+}
+
+EAPI Eina_Bool
+elm_genlist_hilight_mode_get(const Evas_Object *obj)
+{
+ ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return EINA_FALSE;
+ return !wd->no_highlight;
+}
+
+/* for gengrid as of now */
+void
+_elm_genlist_page_relative_set(Evas_Object *obj,
+ double h_pagerel,
+ double v_pagerel)
+{
+ Evas_Coord pagesize_h;
+ Evas_Coord pagesize_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);
+}
+
+/* for gengrid as of now */
+void
+_elm_genlist_page_relative_get(const 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;
+
+ elm_smart_scroller_paging_get(wd->scr, h_pagerel, v_pagerel, NULL, NULL);
+}
+
+/* for gengrid as of now */
+void
+_elm_genlist_page_size_set(Evas_Object *obj,
+ Evas_Coord h_pagesize,
+ Evas_Coord v_pagesize)
+{
+ double pagerel_h;
+ double pagerel_v;
+
+ 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);
+}
+
+/* for gengrid as of now */
+void
+_elm_genlist_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;
+ elm_smart_scroller_current_page_get(wd->scr, h_pagenumber, v_pagenumber);
+}
+
+/* for gengrid as of now */
+void
+_elm_genlist_last_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;
+ elm_smart_scroller_last_page_get(wd->scr, h_pagenumber, v_pagenumber);
+}
+
+/* for gengrid as of now */
+void
+_elm_genlist_page_show(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;
+ elm_smart_scroller_page_show(wd->scr, h_pagenumber, v_pagenumber);
+}
+
+/* for gengrid as of now */
+void
+_elm_genlist_page_bring_in(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;
+ elm_smart_scroller_page_bring_in(wd->scr, h_pagenumber, v_pagenumber);
+}
+
+void
+_elm_genlist_item_unrealize(Elm_Gen_Item *it,
+ Eina_Bool calc)
+{
+ Evas_Object *content;
+
+ if (!it->realized) return;
+ if (it->wd->reorder_it == it) return;
+
+ evas_event_freeze(evas_object_evas_get(WIDGET(it)));
+ if (!calc)
+ evas_object_smart_callback_call(WIDGET(it), SIG_UNREALIZED, it);
+ if (it->long_timer)
+ {
+ ecore_timer_del(it->long_timer);
+ it->long_timer = NULL;
+ }
+
+ elm_widget_stringlist_free(it->texts);
+ it->texts = NULL;
+ elm_widget_stringlist_free(it->contents);
+ it->contents = NULL;
+ elm_widget_stringlist_free(it->states);
+ it->states = NULL;
+
+ EINA_LIST_FREE(it->content_objs, content)
+ evas_object_del(content);
+
+ it->unrealize_cb(it);
+
+ it->realized = EINA_FALSE;
+ it->want_unrealize = EINA_FALSE;
+ evas_event_thaw(evas_object_evas_get(WIDGET(it)));
+ evas_event_thaw_eval(evas_object_evas_get(WIDGET(it)));
+}
+
+void
+_elm_genlist_item_del_notserious(Elm_Gen_Item *it)
+{
+ elm_widget_item_pre_notify_del(it);
+ it->generation = it->wd->generation - 1; /* This means that the item is deleted */
+ if (it->selected) it->wd->selected = eina_list_remove(it->wd->selected, it);
+
+ if (it->itc->func.del)
+ it->itc->func.del((void *)it->base.data, WIDGET(it));
+}
+
+void
+_elm_genlist_item_del_serious(Elm_Gen_Item *it)
+{
+ _elm_genlist_item_del_notserious(it);
+ it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it));
+ if (it->tooltip.del_cb)
+ it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
+ it->wd->walking -= it->walking;
+ if (it->long_timer) ecore_timer_del(it->long_timer);
+ if (it->group)
+ it->wd->group_items = eina_list_remove(it->wd->group_items, it);
+
+ if (it->wd->state)
+ {
+ eina_inlist_sorted_state_free(it->wd->state);
+ it->wd->state = NULL;
+ }
+ if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
+ it->wd->calc_job = ecore_job_add(it->wd->calc_cb, it->wd);
+ free(it->item);
+
+ it->item = NULL;
+ if (it->wd->last_selected_item == (Elm_Object_Item *)it)
+ it->wd->last_selected_item = NULL;
+ it->wd->item_count--;
+}
+
+EAPI void
+elm_genlist_tree_effect_enabled_set(Evas_Object *obj, Eina_Bool enabled)
+{
+ ELM_CHECK_WIDTYPE(obj, widtype);
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return;
+ wd->tree_effect_enabled = !!enabled;
+}
+
+EAPI Eina_Bool
+elm_genlist_tree_effect_enabled_get(const Evas_Object *obj)
+{
+ ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return EINA_FALSE;
+ return wd->tree_effect_enabled;
+}
+
+static Evas_Object*
+_create_tray_alpha_bg(const Evas_Object *obj)
+{
+ ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return NULL;
+
+ Evas_Object *bg = NULL;
+ Evas_Coord ox, oy, ow, oh;
+
+ evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh);
+ bg = evas_object_rectangle_add(evas_object_evas_get(wd->obj));
+ evas_object_color_set(bg,0,0,0,0);
+ evas_object_resize(bg , ow, oh);
+ evas_object_move(bg , ox, oy);
+ return bg ;
+}
+
+static void
+_item_contract_emit(Elm_Gen_Item *it)
+{
+ Elm_Gen_Item *it2;
+ Eina_List *l;
+
+ edje_object_signal_emit(VIEW(it), "elm,state,contract_flip", "");
+ it->item->tree_effect_finished = EINA_FALSE;
+
+ EINA_LIST_FOREACH(it->item->items, l, it2)
+ if (it2) _item_contract_emit(it2);
+}
+
+static int
+_item_tree_effect_before(Elm_Gen_Item *it)
+{
+ Elm_Gen_Item *it2;
+ Eina_List *l;
+
+ EINA_LIST_FOREACH(it->item->items, l, it2)
+ {
+ if (it2->parent && (it == it2->parent))
+ {
+ if (it->wd->move_effect_mode == ELM_GENLIST_ITEM_MOVE_EFFECT_EXPAND)
+ edje_object_signal_emit(VIEW(it2), "elm,state,hide", "");
+ else if (it->wd->move_effect_mode == ELM_GENLIST_ITEM_MOVE_EFFECT_CONTRACT)
+ _item_contract_emit(it2);
+ }
+ }
+ return ECORE_CALLBACK_CANCEL;
+}
+
+static void
+_item_tree_effect(Widget_Data *wd, int y)
+{
+ Elm_Gen_Item *it = NULL, *expanded_next_it;
+
+ expanded_next_it = wd->expanded_next_item;
+
+ if (wd->move_effect_mode == ELM_GENLIST_ITEM_MOVE_EFFECT_EXPAND)
+ {
+ it = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) expanded_next_it);
+ while (it)
+ {
+ if (it->item->expanded_depth <= expanded_next_it->item->expanded_depth) break;
+ if (it->item->scrl_y && (it->item->scrl_y < expanded_next_it->item->old_scrl_y + y) &&
+ (it->item->expanded_depth > expanded_next_it->item->expanded_depth))
+ {
+ if (!it->item->tree_effect_finished)
+ {
+ edje_object_signal_emit(VIEW(it), "flip_item", "");
+ evas_object_show(VIEW(it));
+ it->item->tree_effect_finished = EINA_TRUE;
+ }
+ }
+ it = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) it);
+ }
+ }
+ else if (wd->move_effect_mode == ELM_GENLIST_ITEM_MOVE_EFFECT_CONTRACT)
+ {
+ it = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) expanded_next_it);
+ while (it)
+ {
+ if ((it->item->scrl_y > expanded_next_it->item->old_scrl_y + y) &&
+ (it->item->expanded_depth > expanded_next_it->item->expanded_depth))
+ {
+ if (!it->item->tree_effect_finished)
+ {
+ edje_object_signal_emit(VIEW(it), "elm,state,hide", "");
+ it->item->tree_effect_finished = EINA_TRUE;
+ }
+ }
+ else
+ break;
+ it = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) it);
+ }
+ }
+}
+
+static void
+_item_tree_effect_finish(Widget_Data *wd)
+{
+ Item_Block *itb;
+ Elm_Gen_Item *it = NULL;
+ const Eina_List *l;
+
+ if (wd->item_moving_effect_timer)
+ {
+ if (wd->move_effect_mode == ELM_GENLIST_ITEM_MOVE_EFFECT_CONTRACT)
+ _item_subitems_clear(wd->expanded_item);
+ EINA_INLIST_FOREACH(wd->blocks, itb)
+ {
+ EINA_LIST_FOREACH(itb->items, l, it)
+ {
+ it->item->tree_effect_finished = EINA_TRUE;
+ it->item->old_scrl_y = it->item->scrl_y;
+ }
+ }
+ }
+ _item_auto_scroll(wd);
+ evas_object_lower(wd->alpha_bg);
+ evas_object_hide(wd->alpha_bg);
+ wd->move_effect_mode = ELM_GENLIST_ITEM_MOVE_EFFECT_NONE;
+ if (wd->move_items) wd->move_items = eina_list_free(wd->move_items);
+
+ evas_object_smart_callback_call(wd->pan_smart, "changed", NULL);
+ evas_object_smart_callback_call(wd->obj, SIG_TREE_EFFECT_FINISHED, NULL);
+ evas_object_smart_changed(wd->pan_smart);
+
+ wd->item_moving_effect_timer = NULL;
+}
+
+static Eina_Bool
+_item_moving_effect_timer_cb(void *data)
+{
+ Widget_Data *wd = data;
+ if (!wd) return EINA_FALSE;
+ Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh;
+ Elm_Gen_Item *it = NULL, *it2, *expanded_next_it;
+ const Eina_List *l;
+ double effect_duration = 0.5, t;
+ int y = 0, dy = 0, dh = 0;
+ Eina_Bool end = EINA_FALSE, vis = EINA_TRUE;
+ int in = 0;
+
+ t = ((0.0 > (t = ecore_time_get() - wd->start_time)) ? 0.0 : t);
+ evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh);
+ evas_output_viewport_get(evas_object_evas_get(wd->pan_smart), &cvx, &cvy, &cvw, &cvh);
+ if (t > effect_duration) end = EINA_TRUE;
+
+ // Below while statement is needed, when the genlist is resized.
+ it2 = wd->expanded_item;
+ while (it2 && vis)
+ {
+ evas_object_move(VIEW(it2), it2->item->scrl_x, it2->item->scrl_y);
+ vis = (ELM_RECTS_INTERSECT(it2->item->scrl_x, it2->item->scrl_y, it2->item->w, it2->item->h,
+ cvx, cvy, cvw, cvh));
+ it2 = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) it2);
+ }
+
+ if (wd->expanded_next_item)
+ {
+ expanded_next_it = wd->expanded_next_item;
+
+ /* move items */
+ EINA_LIST_FOREACH(wd->move_items, l, it)
+ {
+ if (wd->move_effect_mode == ELM_GENLIST_ITEM_MOVE_EFFECT_EXPAND)
+ {
+ expanded_next_it->item->old_scrl_y = wd->expanded_item->item->old_scrl_y + wd->expanded_item->item->h;
+ if (expanded_next_it->item->scrl_y < expanded_next_it->item->old_scrl_y) //did not calculate next item position
+ expanded_next_it->item->scrl_y = cvy + cvh;
+
+ dy = ((expanded_next_it->item->scrl_y >= (cvy + cvh)) ?
+ cvy + cvh : expanded_next_it->item->scrl_y) -
+ expanded_next_it->item->old_scrl_y;
+ }
+ else if (wd->move_effect_mode == ELM_GENLIST_ITEM_MOVE_EFFECT_CONTRACT)
+ {
+ if (expanded_next_it->item->scrl_y > expanded_next_it->item->old_scrl_y) //did not calculate next item position
+ expanded_next_it->item->old_scrl_y = cvy + cvh;
+
+ if (expanded_next_it->item->old_scrl_y > (cvy + cvh))
+ {
+ dy = (wd->expanded_item->item->scrl_y + wd->expanded_item->item->h) -
+ cvy + cvh;
+ expanded_next_it->item->old_scrl_y = cvy + cvh;
+ }
+ else
+ {
+ dy = (wd->expanded_item->item->scrl_y + wd->expanded_item->item->h) -
+ expanded_next_it->item->old_scrl_y;
+ }
+ }
+
+ if (t <= effect_duration)
+ {
+ y = ((1 - (1 - (t / effect_duration)) * (1 - (t /effect_duration))) * dy);
+ }
+ else
+ {
+ end = EINA_TRUE;
+ y = dy;
+ }
+
+ if (!it->realized)
+ {
+ _item_realize(it, in, 0);
+ }
+ in++;
+
+ if (it != expanded_next_it)
+ {
+ it->item->old_scrl_y = expanded_next_it->item->old_scrl_y + expanded_next_it->item->h + dh;
+ dh += it->item->h;
+ }
+
+ if ((it->item->old_scrl_y + y) < (cvy + cvh))
+ _item_position(it, VIEW(it),it->item->scrl_x, it->item->old_scrl_y + y);
+ }
+ /* tree effect */
+ _item_tree_effect(wd, y);
+ }
+ else
+ {
+ int expanded_item_num = 0;
+ int num = 0;
+
+ if (wd->expanded_item)
+ it = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) wd->expanded_item);
+
+ it2 = it;
+ while (it2)
+ {
+ expanded_item_num++;
+ it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it2);
+ }
+
+ while (it)
+ {
+ num++;
+ if (wd->expanded_item->item->expanded_depth >= it->item->expanded_depth) break;
+ if (wd->move_effect_mode == ELM_GENLIST_ITEM_MOVE_EFFECT_EXPAND)
+ {
+ if (!it->item->tree_effect_finished)
+ {
+ if (t >= (((num - 1) * effect_duration) / expanded_item_num))
+ {
+ edje_object_signal_emit(VIEW(it), "flip_item", "");
+ evas_object_show(VIEW(it));
+ it->item->tree_effect_finished = EINA_TRUE;
+ }
+ }
+ }
+ it = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it);
+ }
+ }
+
+ if (end)
+ {
+ _item_tree_effect_finish(wd);
+ return ECORE_CALLBACK_CANCEL;
+ }
+ return ECORE_CALLBACK_RENEW;
+}