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  =)

> 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.

>
>> +         }
>> +     }
>> +
>> +   _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