On Mon, May 24, 2010 at 10:48 PM, Bruno Dilly <[email protected]> wrote:
> On Mon, May 24, 2010 at 12:06 AM, Iván Briano (Sachiel)
> <[email protected]> wrote:
>> 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?
>
> Leaving this responsibility to cmp_data_func is a bad approach?
> In this function you know that if you return >= 0 this data will be
> replaced in index item, and
> if it need to be free or whatever you want, it's the time to do that.
> It won't happen in the cases I was working with (that is the index
> pointing to list items), but it surely can be a problem.
>
> I don't know, if you have a better solution in mind, I'm listening =)
>
Two options, document that cmp_data_func should take care of freeing
the old stuff if needed, or pass a free_func as yet another parameter.
>> 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
>
> This case should be solved by cmp_func. You can have a cmp_func like this:
>
> cmp_func (it1, it2)
> {
> label1 = elm_index_item_letter_get(it1);
> label2 = elm_index_item_letter_get(it2);
> ret = strcasecmp(label1, label2);
> if (!ret) {
> data1 = elm_index_item_data_get(it1);
> data2 = elm_index_item_data_get(it2);
> ret = function_to_sort_different_items_with_the_same_label(data1, data2);
> }
> return ret;
> }
>
>> for replace and the other two just for order of insertion?
>
> For sort, you should use cmp_func. The idea is to use cmp_data_func to decide
> which data should be pointed by an item index already there. Sometimes
> we will want that things just stay the way it already is, sometimes you will
> want a replacement.
>
Fine then.
>>
>>> + }
>>> + }
>>> +
>>> + _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
>>
>
------------------------------------------------------------------------------
_______________________________________________
enlightenment-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel