On Mon, May 24, 2010 at 8:41 AM, Enlightenment SVN
<[email protected]> wrote:
> Log:
> Implement elm index sorted insert
> - Name index item as Elm_Index_Item
> - Add some other index functions:
> + Item find
> + Data get/set
> + Letter get
>
> I think this stuff will make easier to create index for
> dynamically created lists.
>
> Author: bdilly
> Date: 2010-05-23 16:41:32 -0700 (Sun, 23 May 2010)
> New Revision: 49171
>
> Modified:
> trunk/TMP/st/elementary/src/lib/Elementary.h.in
> trunk/TMP/st/elementary/src/lib/elm_index.c
>
> Modified: trunk/TMP/st/elementary/src/lib/Elementary.h.in
> ===================================================================
> --- trunk/TMP/st/elementary/src/lib/Elementary.h.in 2010-05-23 23:23:51
> UTC (rev 49170)
> +++ trunk/TMP/st/elementary/src/lib/Elementary.h.in 2010-05-23 23:41:32
> UTC (rev 49171)
> @@ -1266,6 +1266,7 @@
> * vertical (two up/down buttons at the right side and text left aligned)
> */
>
> + typedef struct _Elm_Index_Item Elm_Index_Item;
> EAPI Evas_Object *elm_index_add(Evas_Object *parent);
> EAPI void elm_index_active_set(Evas_Object *obj, Eina_Bool active);
> EAPI void elm_index_item_level_set(Evas_Object *obj, int level);
> @@ -1275,9 +1276,14 @@
> EAPI void elm_index_item_prepend(Evas_Object *obj, const char
> *letter, const void *item);
> EAPI void elm_index_item_append_relative(Evas_Object *obj, const
> char *letter, const void *item, const void *relative);
> EAPI void elm_index_item_prepend_relative(Evas_Object *obj, const
> char *letter, const void *item, const void *relative);
> + EAPI void elm_index_item_sorted_insert(Evas_Object *obj, const
> char *letter, const void *item, Eina_Compare_Cb cmp_func, Eina_Compare_Cb
> cmp_data_func);
> EAPI void elm_index_item_del(Evas_Object *obj, const void *item);
> + EAPI Elm_Index_Item *elm_index_item_find(Evas_Object *obj, const void
> *item);
> EAPI void elm_index_item_clear(Evas_Object *obj);
> EAPI void elm_index_item_go(Evas_Object *obj, int level);
> + EAPI void *elm_index_item_data_get(const Elm_Index_Item *item);
> + EAPI void elm_index_item_data_set(Elm_Index_Item *it, const void
> *data);
> + EAPI const char *elm_index_item_letter_get(const Elm_Index_Item *item);
> /* smart callbacks called:
> * "changed" - when the selected index item changes
> * "delay,changed" - when the selected index item changes, but after some
> small idle period
>
> Modified: trunk/TMP/st/elementary/src/lib/elm_index.c
> ===================================================================
> --- trunk/TMP/st/elementary/src/lib/elm_index.c 2010-05-23 23:23:51 UTC (rev
> 49170)
> +++ trunk/TMP/st/elementary/src/lib/elm_index.c 2010-05-23 23:41:32 UTC (rev
> 49171)
> @@ -9,7 +9,6 @@
> */
>
> typedef struct _Widget_Data Widget_Data;
> -typedef struct _Item Item;
>
> struct _Widget_Data
> {
> @@ -26,7 +25,7 @@
> Eina_Bool down : 1;
> };
>
> -struct _Item
> +struct _Elm_Index_Item
> {
> Evas_Object *obj;
> const char *letter;
> @@ -42,13 +41,13 @@
> static void _sizing_eval(Evas_Object *obj);
> static void _index_box_auto_fill(Evas_Object *obj, Evas_Object *box, int
> level);
> static void _index_box_clear(Evas_Object *obj, Evas_Object *box, int level);
> -static void _item_free(Item *it);
> +static void _item_free(Elm_Index_Item *it);
>
> static void
> _del_hook(Evas_Object *obj)
> {
> Widget_Data *wd = elm_widget_data_get(obj);
> - Item *it;
> + Elm_Index_Item *it;
> Eina_List *l, *clear = NULL;
> if (!wd) return;
> _index_box_clear(obj, wd->bx[wd->level], wd->level);
> @@ -138,13 +137,13 @@
> evas_object_size_hint_max_set(obj, maxw, maxh);
> }
>
> -static Item *
> +static Elm_Index_Item *
> _item_new(Evas_Object *obj, const char *letter, const void *item)
> {
> Widget_Data *wd = elm_widget_data_get(obj);
> - Item *it;
> + Elm_Index_Item *it;
> if (!wd) return NULL;
> - it = calloc(1, sizeof(Item));
> + it = calloc(1, sizeof(Elm_Index_Item));
> if (!it) return NULL;
> it->obj = obj;
> it->letter = eina_stringshare_add(letter);
> @@ -153,12 +152,12 @@
> return it;
> }
>
> -static Item *
> +static Elm_Index_Item *
> _item_find(Evas_Object *obj, const void *item)
> {
> Widget_Data *wd = elm_widget_data_get(obj);
> Eina_List *l;
> - Item *it;
> + Elm_Index_Item *it;
> if (!wd) return NULL;
> EINA_LIST_FOREACH(wd->items, l, it)
> if (it->data == item) return it;
> @@ -166,7 +165,7 @@
> }
>
> static void
> -_item_free(Item *it)
> +_item_free(Elm_Index_Item *it)
> {
> Widget_Data *wd = elm_widget_data_get(it->obj);
> if (!wd) return;
> @@ -182,7 +181,7 @@
> {
> Widget_Data *wd = elm_widget_data_get(obj);
> Eina_List *l;
> - Item *it;
> + Elm_Index_Item *it;
> Evas_Coord mw, mh, w, h;
> int i = 0;
> if (!wd) return;
> @@ -235,7 +234,7 @@
> {
> Widget_Data *wd = elm_widget_data_get(obj);
> Eina_List *l;
> - Item *it;
> + Elm_Index_Item *it;
> if (!wd) return;
> if (!wd->level_active[level]) return;
> EINA_LIST_FOREACH(wd->items, l, it)
> @@ -264,7 +263,7 @@
> _sel_eval(Evas_Object *obj, Evas_Coord evx, Evas_Coord evy)
> {
> Widget_Data *wd = elm_widget_data_get(obj);
> - Item *it, *it_closest, *it_last;
> + Elm_Index_Item *it, *it_closest, *it_last;
> Eina_List *l;
> Evas_Coord x, y, w, h, bx, by, bw, bh, xx, yy;
> double cdv = 0.5;
> @@ -614,7 +613,7 @@
> ELM_CHECK_WIDTYPE(obj, widtype) NULL;
> Widget_Data *wd = elm_widget_data_get(obj);
> Eina_List *l;
> - Item *it;
> + Elm_Index_Item *it;
> if (!wd) return NULL;
> EINA_LIST_FOREACH(wd->items, l, it)
> if ((it->selected) && (it->level == level)) return it->data;
> @@ -635,7 +634,7 @@
> {
> ELM_CHECK_WIDTYPE(obj, widtype);
> Widget_Data *wd = elm_widget_data_get(obj);
> - Item *it;
> + Elm_Index_Item *it;
> if (!wd) return;
> it = _item_new(obj, letter, item);
> if (!it) return;
> @@ -657,7 +656,7 @@
> {
> ELM_CHECK_WIDTYPE(obj, widtype);
> Widget_Data *wd = elm_widget_data_get(obj);
> - Item *it;
> + Elm_Index_Item *it;
>
> if (!wd) return;
> it = _item_new(obj, letter, item);
> @@ -681,7 +680,7 @@
> {
> ELM_CHECK_WIDTYPE(obj, widtype);
> Widget_Data *wd = elm_widget_data_get(obj);
> - Item *it, *it_rel;
> + Elm_Index_Item *it, *it_rel;
> if (!wd) return;
> if (!relative)
> {
> @@ -715,7 +714,7 @@
> {
> ELM_CHECK_WIDTYPE(obj, widtype);
> Widget_Data *wd = elm_widget_data_get(obj);
> - Item *it, *it_rel;
> + Elm_Index_Item *it, *it_rel;
> if (!wd) return;
> if (!relative)
> {
> @@ -735,6 +734,62 @@
> }
>
> /**
> + * Insert a new @p item into the sorted index @p obj in @p letter.
> + *
> + * @param obj The index object
> + * @param letter Letter under which the item should be indexed
> + * @param item The item to put in the index
> + * @param cmp_func The function called for the sort of index items.
> + * @param cmp_data_func The function called for the sort of the data. It will
> + * be used when cmp_func return 0. It means the index item already exists.
> + * So, to decide which data item should be pointed by the index item, a
> function
> + * to compare them is needed. If this function is not provided, index items
> + * will be duplicated.
> + *
> + * @ingroup Index
> + */
> +EAPI void
> +elm_index_item_sorted_insert(Evas_Object *obj, const char *letter, const
> void *item, Eina_Compare_Cb cmp_func, Eina_Compare_Cb cmp_data_func)
> +{
> + ELM_CHECK_WIDTYPE(obj, widtype);
> + Widget_Data *wd = elm_widget_data_get(obj);
> + Eina_List *lnear;
> + Elm_Index_Item *it;
> + int cmp;
> +
> + if (!wd) return;
> + if (!(wd->items))
> + {
> + elm_index_item_append(obj, letter, item);
> + return;
> + }
> +
> + it = _item_new(obj, letter, item);
> + if (!it) return;
> +
> + lnear = eina_list_search_sorted_near_list(wd->items, cmp_func, it, &cmp);
> + if (cmp < 0)
> + wd->items = eina_list_append_relative_list(wd->items, it, lnear);
> + else if (cmp > 0)
> + wd->items = eina_list_prepend_relative_list(wd->items, it, lnear);
> + else
> + {
> + /* If cmp_data_func is not provided, append a duplicated item */
> + if (!cmp_data_func)
> + wd->items = eina_list_append_relative_list(wd->items, it, lnear);
> + else
> + {
> + Elm_Index_Item *p_it = eina_list_data_get(lnear);
> + if (cmp_data_func(p_it->data, it->data) >= 0)
> + p_it->data = it->data;
> + _item_free(it);
What happens to the old data from p_it here?
Also, what about the case where the cmp_data_func is used to sort
two different items with the same label? Shouldn't a 0 return be used
for replace and the other two just for order of insertion?
> + }
> + }
> +
> + _index_box_clear(obj, wd->bx[wd->level], wd->level);
> +}
> +
> +/**
> * Remove an item from the index.
> *
> * @param obj The index object
> @@ -747,7 +802,7 @@
> {
> ELM_CHECK_WIDTYPE(obj, widtype);
> Widget_Data *wd = elm_widget_data_get(obj);
> - Item *it;
> + Elm_Index_Item *it;
> if (!wd) return;
> it = _item_find(obj, item);
> if (!it) return;
> @@ -756,6 +811,24 @@
> }
>
> /**
> + * Find an index item using item data.
> + *
> + * @param obj The index object
> + * @param item The item pointed by index item
> + * @return The index item pointing to @p item
> + *
> + * @ingroup Index
> + */
> +EAPI Elm_Index_Item *
> +elm_index_item_find(Evas_Object *obj, const void *item)
> +{
> + ELM_CHECK_WIDTYPE(obj, widtype);
> + Widget_Data *wd = elm_widget_data_get(obj);
> + if (!wd) return NULL;
> + return _item_find(obj, item);
> +}
> +
> +/**
> * Clears an index of its items.
> *
> * @param obj The index object.
> @@ -767,7 +840,7 @@
> {
> ELM_CHECK_WIDTYPE(obj, widtype);
> Widget_Data *wd = elm_widget_data_get(obj);
> - Item *it;
> + Elm_Index_Item *it;
> Eina_List *l, *clear = NULL;
> if (!wd) return;
> _index_box_clear(obj, wd->bx[wd->level], wd->level);
> @@ -796,3 +869,51 @@
> _index_box_auto_fill(obj, wd->bx[0], 0);
> if (wd->level == 1) _index_box_auto_fill(obj, wd->bx[1], 1);
> }
> +
> +/**
> + * Returns the data associated with the item.
> + *
> + * @param it The list item
> + * @return The data associated with @p it
> + *
> + * @ingroup Index
> + */
> +EAPI void *
> +elm_index_item_data_get(const Elm_Index_Item *it)
> +{
> + if (!it) return NULL;
> + return (void *)it->data;
> +}
> +
> +/**
> + * Set the data item from the index item
> + *
> + * This set a new data value.
> + *
> + * @param it The item
> + * @param data The new data pointer to set
> + *
> + * @ingroup Index
> + */
> +EAPI void
> +elm_index_item_data_set(Elm_Index_Item *it, const void *data)
> +{
> + if (!it) return;
> + it->data = data;
> +}
> +
> +/**
> + * Gets the letter of the item.
> + *
> + * @param it The list item
> + * @return The letter of @p it
> + *
> + * @ingroup Index
> + */
> +EAPI const char *
> +elm_index_item_letter_get(const Elm_Index_Item *it)
> +{
> + if (!it) return NULL;
> + return it->letter;
> +}
> +
>
>
> ------------------------------------------------------------------------------
>
> _______________________________________________
> enlightenment-svn mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/enlightenment-svn
>
------------------------------------------------------------------------------
_______________________________________________
enlightenment-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel