On Mon, May 24, 2010 at 10:48 PM, Bruno Dilly <bdi...@profusion.mobi> wrote:
> On Mon, May 24, 2010 at 12:06 AM, Iván Briano (Sachiel)
> <sachi...@gmail.com> wrote:
>> On Mon, May 24, 2010 at 8:41 AM, Enlightenment SVN
>> <no-re...@enlightenment.org> 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
>>> enlightenment-...@lists.sourceforge.net
>>> https://lists.sourceforge.net/lists/listinfo/enlightenment-svn
>>>
>>
>> ------------------------------------------------------------------------------
>>
>> _______________________________________________
>> enlightenment-devel mailing list
>> enlightenment-devel@lists.sourceforge.net
>> https://lists.sourceforge.net/lists/listinfo/enlightenment-devel
>>
>

------------------------------------------------------------------------------

_______________________________________________
enlightenment-devel mailing list
enlightenment-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel

Reply via email to