Hello,

I added group index feature.
This feature support to show item indicates group index.
I attached capture images showing group index.
As you can see attached png images, Group index item includes same group
items.

The group index is shown until every items that have same group index are
scrolled.
so group index realize/unrealize is not excuteded in _item_block_position
function.
instead of the function, group index is controlled in _pan_calculate
function.

"Genlist Group" and "Genlist Group Tree" menu is added in elementary_test.
you can test group index operations in elementary_test.

This patch is not support elm_genlist_item_insert_before/after operation of
group index.
We are now considering the operations in group index.,

This patch assumes that the previous 2 patches are already applied to
upstream.
'[E-devel] [Patch] Tree support for elm_genlist_item_prepend() API.'
'[E-devel] [Patch] Tree support for elm_genlist_item_insert_before/after()
APIs',
So this patch does not include the changes of the previous patch.

I separated this patch.

- 004.elm_genlist.c.patch.txt
    Patch for src/lib/elm_genlist.c
- 005.test_genlist.c.patch.txt
    Patch for src/bin/test_genlist.c 
- 006.genlist.patch.txt
    Patch for data/theme/default.edc

And you have to add attached group_index.png file into 'data/themes'
'group_index.png' file is group index background image. 


Daniel Juyung Seo help make test code and refactoring group index code.

Please review it and let me know if there is any problem in this patch.

Thanks.
Seunggyun Kim

--- src/lib/Elementary.h.in.ori 2010-12-30 16:41:18.000000000 +0900
+++ src/lib/Elementary.h.in     2010-12-30 14:39:34.000000000 +0900
@@ -1682,7 +1682,8 @@ extern "C" {
    typedef enum _Elm_Genlist_Item_Flags
      {
         ELM_GENLIST_ITEM_NONE = 0,
-        ELM_GENLIST_ITEM_SUBITEMS = (1 << 0)
+        ELM_GENLIST_ITEM_SUBITEMS = (1 << 0),
+        ELM_GENLIST_ITEM_GROUP = (1 << 1)
      } Elm_Genlist_Item_Flags;
    typedef struct _Elm_Genlist_Item_Class Elm_Genlist_Item_Class;
    typedef struct _Elm_Genlist_Item       Elm_Genlist_Item; /**< Item of 
Elm_Genlist. Sub-type of Elm_Widget_Item */
--- src/lib/elm_genlist.c.ori   2010-12-30 14:16:24.000000000 +0900
+++ src/lib/elm_genlist.c       2010-12-30 14:36:16.000000000 +0900
@@ -271,6 +271,7 @@ struct _Widget_Data
 {
    Evas_Object      *obj, *scr, *pan_smart;
    Eina_Inlist      *items, *blocks;
+   Eina_List        *group_items;
    Pan              *pan;
    Evas_Coord        pan_x, pan_y, w, h, minw, minh, realminw, prev_viewport_w;
    Ecore_Job        *calc_job, *update_job;
@@ -335,6 +336,7 @@ struct _Elm_Genlist_Item
    Evas_Coord                    x, y, w, h, minw, minh;
    const Elm_Genlist_Item_Class *itc;
    Elm_Genlist_Item             *parent;
+   Elm_Genlist_Item             *group_item;
    Elm_Genlist_Item_Flags        flags;
    struct
    {
@@ -347,6 +349,7 @@ struct _Elm_Genlist_Item
    Ecore_Timer      *long_timer;
    Ecore_Timer      *swipe_timer;
    Evas_Coord        dx, dy;
+   Evas_Coord        scrl_x, scrl_y;
 
    Elm_Genlist_Item *rel;
 
@@ -368,6 +371,7 @@ struct _Elm_Genlist_Item
    Eina_Bool   before : 1;
 
    Eina_Bool   want_unrealize : 1;
+   Eina_Bool   want_realize : 1;
    Eina_Bool   realized : 1;
    Eina_Bool   selected : 1;
    Eina_Bool   hilighted : 1;
@@ -791,7 +795,11 @@ _item_hilight(Elm_Genlist_Item *it)
    edje_object_signal_emit(it->base.view, "elm,state,selected", "elm");
    selectraise = edje_object_data_get(it->base.view, "selectraise");
    if ((selectraise) && (!strcmp(selectraise, "on")))
-     evas_object_raise(it->base.view);
+     {
+        evas_object_raise(it->base.view);
+        if ((it->group_item) && (it->group_item->realized))
+           evas_object_raise(it->group_item->base.view);
+     }
    it->hilighted = EINA_TRUE;
 }
 
@@ -1433,7 +1441,10 @@ _item_realize(Elm_Genlist_Item *it,
         evas_object_color_set(it->spacer, 0, 0, 0, 0);
         elm_widget_sub_object_add(it->base.widget, it->spacer);
      }
-   for (it2 = it, depth = 0; it2->parent; it2 = it2->parent) depth += 1;
+   for (it2 = it, depth = 0; it2->parent; it2 = it2->parent)
+     {
+        if (it2->parent->flags != ELM_GENLIST_ITEM_GROUP) depth += 1;
+     }
    it->expanded_depth = depth;
    treesize = edje_object_data_get(it->base.view, "treesize");
    if (treesize) tsize = atoi(treesize);
@@ -1729,13 +1742,16 @@ _item_block_unrealize(Item_Block *itb)
    if (!itb->realized) return;
    EINA_LIST_FOREACH(itb->items, l, it)
      {
-        if (it->dragging)
+        if (it->flags != ELM_GENLIST_ITEM_GROUP)
           {
-             dragging = EINA_TRUE;
-             it->want_unrealize = EINA_TRUE;
+             if (it->dragging)
+               {
+                  dragging = EINA_TRUE;
+                  it->want_unrealize = EINA_TRUE;
+               }
+             else
+                _item_unrealize(it);
           }
-        else
-          _item_unrealize(it);
      }
    if (!dragging)
      {
@@ -1752,6 +1768,7 @@ _item_block_position(Item_Block *itb,
 {
    const Eina_List *l;
    Elm_Genlist_Item *it;
+   Elm_Genlist_Item *git;
    Evas_Coord y = 0, ox, oy, ow, oh, cvx, cvy, cvw, cvh;
    int vis;
 
@@ -1764,31 +1781,69 @@ _item_block_position(Item_Block *itb,
         it->x = 0;
         it->y = y;
         it->w = itb->w;
-        vis = (ELM_RECTS_INTERSECT(itb->x + it->x - it->wd->pan_x + ox,
-                                   itb->y + it->y - it->wd->pan_y + oy,
-                                   it->w, it->h,
-                                   cvx, cvy, cvw, cvh));
-        if ((itb->realized) && (!it->realized))
-          {
-             if (vis) _item_realize(it, in, 0);
-          }
-        if (it->realized)
+        it->scrl_x = itb->x + it->x - it->wd->pan_x + ox;
+        it->scrl_y = itb->y + it->y - it->wd->pan_y + oy;
+
+        if (it->flags != ELM_GENLIST_ITEM_GROUP)
           {
-             if (vis)
+             vis = (ELM_RECTS_INTERSECT(it->scrl_x, it->scrl_y, it->w, it->h,
+                                        cvx, cvy, cvw, cvh));
+             if ((itb->realized) && (!it->realized))
                {
-                  evas_object_resize(it->base.view, it->w, it->h);
-                  evas_object_move(it->base.view,
-                                   ox + itb->x + it->x - itb->wd->pan_x,
-                                   oy + itb->y + it->y - itb->wd->pan_y);
-                  evas_object_show(it->base.view);
+                  if (vis) _item_realize(it, in, 0);
                }
-             else
+             if (it->realized)
                {
-                  if (!it->dragging) _item_unrealize(it);
+                  if (vis)
+                    {
+                       git = it->group_item;
+                       if (git)
+                         {
+                            if (git->scrl_y < oy)
+                               git->scrl_y = oy;
+                            if ((git->scrl_y + git->h) > (it->scrl_y + it->h))
+                               git->scrl_y = (it->scrl_y + it->h) - git->minh;
+                            git->want_realize = EINA_TRUE;
+                         }
+                       evas_object_resize(it->base.view, it->w, it->h);
+                       evas_object_move(it->base.view,
+                                        it->scrl_x, it->scrl_y);
+                       evas_object_show(it->base.view);
+                    }
+                  else
+                    {
+                       if (!it->dragging) _item_unrealize(it);
+                    }
                }
+             in++;
           }
         y += it->h;
-        in++;
+     }
+}
+
+static void
+_group_items_recalc(void *data)
+{
+   Widget_Data *wd = data;
+   Eina_List *l;
+   Elm_Genlist_Item *git;
+
+   EINA_LIST_FOREACH(wd->group_items, l, git)
+     {
+        if (git->want_realize) 
+          {
+             if (!git->realized)
+                _item_realize(git, 0, 0);
+             evas_object_resize(git->base.view, wd->minw, git->h);
+             evas_object_move(git->base.view, git->scrl_x, git->scrl_y);
+             evas_object_show(git->base.view);
+             evas_object_raise(git->base.view);
+          }
+        else if (!git->want_realize && git->realized)
+          {
+             if (!git->dragging) 
+                _item_unrealize(git);
+          }
      }
 }
 
@@ -2151,9 +2206,15 @@ _pan_calculate(Evas_Object *obj)
    Item_Block *itb;
    Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh;
    int in = 0;
+   Elm_Genlist_Item *git;
+   Eina_List *l;
 
    evas_object_geometry_get(obj, &ox, &oy, &ow, &oh);
    evas_output_viewport_get(evas_object_evas_get(obj), &cvx, &cvy, &cvw, &cvh);
+   EINA_LIST_FOREACH(sd->wd->group_items, l, git)
+     {
+        git->want_realize = EINA_FALSE;
+     }
    EINA_INLIST_FOREACH(sd->wd->blocks, itb)
    {
       itb->w = sd->wd->minw;
@@ -2172,6 +2233,7 @@ _pan_calculate(Evas_Object *obj)
         }
       in += itb->count;
    }
+   _group_items_recalc(sd->wd);
 }
 
 static void
@@ -2634,6 +2696,8 @@ elm_genlist_item_append(Evas_Object     
    if (!it) return NULL;
    if (!it->parent)
      {
+        if (flags & ELM_GENLIST_ITEM_GROUP)
+           wd->group_items = eina_list_append(wd->group_items, it);
         wd->items = eina_inlist_append(wd->items, EINA_INLIST_GET(it));
         it->rel = NULL;
      }
@@ -2649,6 +2713,11 @@ elm_genlist_item_append(Evas_Object     
                                       EINA_INLIST_GET(it2));
         it->rel = it2;
         it->rel->relcount++;
+
+        if (it->parent->flags & ELM_GENLIST_ITEM_GROUP) 
+           it->group_item = parent;
+        else if (it->parent->group_item)
+           it->group_item = it->parent->group_item;
      }
    it->before = EINA_FALSE;
    _item_queue(wd, it);
@@ -2689,6 +2758,8 @@ elm_genlist_item_prepend(Evas_Object    
    if (!it) return NULL;
    if (!it->parent)
      {
+        if (flags & ELM_GENLIST_ITEM_GROUP)
+           wd->group_items = eina_list_prepend(wd->group_items, it);
         wd->items = eina_inlist_prepend(wd->items, EINA_INLIST_GET(it));
         it->rel = NULL;
      }
@@ -3473,6 +3544,7 @@ EAPI void
 elm_genlist_item_show(Elm_Genlist_Item *it)
 {
    ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
+   Evas_Coord gith = 0;
    if (it->delete_me) return;
    if ((it->queued) || (!it->mincalcd))
      {
@@ -3486,6 +3558,8 @@ elm_genlist_item_show(Elm_Genlist_Item *
         it->wd->show_item->showme = EINA_FALSE;
         it->wd->show_item = NULL;
      }
+   if ((it->group_item) && (it->wd->pan_y > (it->y + it->block->y)))
+      gith = it->group_item->h;
    elm_smart_scroller_child_region_show(it->wd->scr,
                                         it->x + it->block->x,
                                         it->y + it->block->y,
@@ -3507,6 +3581,7 @@ EAPI void
 elm_genlist_item_bring_in(Elm_Genlist_Item *it)
 {
    ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
+   Evas_Coord gith = 0; 
    if (it->delete_me) return;
    if ((it->queued) || (!it->mincalcd))
      {
@@ -3520,9 +3595,11 @@ elm_genlist_item_bring_in(Elm_Genlist_It
         it->wd->show_item->showme = EINA_FALSE;
         it->wd->show_item = NULL;
      }
+   if ((it->group_item) && (it->wd->pan_y > (it->y + it->block->y)))
+      gith = it->group_item->h;
    elm_smart_scroller_region_bring_in(it->wd->scr,
                                       it->x + it->block->x,
-                                      it->y + it->block->y,
+                                      it->y + it->block->y - gith,
                                       it->block->w, it->h);
 }
 
@@ -3541,6 +3618,7 @@ elm_genlist_item_top_show(Elm_Genlist_It
 {
    ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
    Evas_Coord ow, oh;
+   Evas_Coord gith = 0;
 
    if (it->delete_me) return;
    if ((it->queued) || (!it->mincalcd))
@@ -3556,9 +3634,10 @@ elm_genlist_item_top_show(Elm_Genlist_It
         it->wd->show_item = NULL;
      }
    evas_object_geometry_get(it->wd->pan_smart, NULL, NULL, &ow, &oh);
+   if (it->group_item) gith = it->group_item->h;
    elm_smart_scroller_child_region_show(it->wd->scr,
                                         it->x + it->block->x,
-                                        it->y + it->block->y,
+                                        it->y + it->block->y - gith,
                                         it->block->w, oh);
 }
 
@@ -3578,6 +3657,7 @@ elm_genlist_item_top_bring_in(Elm_Genlis
 {
    ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
    Evas_Coord ow, oh;
+   Evas_Coord gith = 0;
 
    if (it->delete_me) return;
    if ((it->queued) || (!it->mincalcd))
@@ -3593,9 +3673,10 @@ elm_genlist_item_top_bring_in(Elm_Genlis
         it->wd->show_item = NULL;
      }
    evas_object_geometry_get(it->wd->pan_smart, NULL, NULL, &ow, &oh);
+   if (it->group_item) gith = it->group_item->h;
    elm_smart_scroller_region_bring_in(it->wd->scr,
                                       it->x + it->block->x,
-                                      it->y + it->block->y,
+                                      it->y + it->block->y - gith,
                                       it->block->w, oh);
 }
 

--- src/bin/test_genlist.c.ori  2010-12-30 14:37:30.000000000 +0900
+++ src/bin/test_genlist.c      2010-12-30 16:13:27.000000000 +0900
@@ -1313,4 +1313,318 @@ test_genlist7(void *data __UNUSED__, Eva
    evas_object_resize(win, 320, 320);
    evas_object_show(win);
 }
+
+/*************/
+
+static Elm_Genlist_Item_Class itc_group;
+char *gl8_label_get(void *data, Evas_Object *obj __UNUSED__, const char *part 
__UNUSED__)
+{
+   char buf[256];
+   snprintf(buf, sizeof(buf), "Group Index # %i (Item # %i)",  
(int)((long)data / 10), (int)(long)data);
+   return strdup(buf);
+}
+
+static void
+_bt_show_cb(void *data, Evas_Object *obj __UNUSED__, void *event_info 
__UNUSED__)
+{
+    elm_genlist_item_top_show(data);
+    //elm_genlist_item_show(data);
+    //elm_genlist_item_middle_show(data);
+}
+static void
+_bt_bring_cb(void *data, Evas_Object *obj __UNUSED__, void *event_info 
__UNUSED__)
+{
+    elm_genlist_item_top_bring_in(data);
+    //elm_genlist_item_bring_in(data);
+    //elm_genlist_item_middle_bring_in(data);
+}
+
+void
+test_genlist8(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void 
*event_info __UNUSED__)
+{
+   Evas_Object *win, *bg, *gl, *bt[8], *bx, *bx2, *bx3;
+   Evas_Object *over;
+   Elm_Genlist_Item *gli, *git;
+   int i, bt_count, bt_num;
+
+   win = elm_win_add(NULL, "genlist-group", ELM_WIN_BASIC);
+   elm_win_title_set(win, "Genlist Group");
+   elm_win_autodel_set(win, 1);
+
+   bg = elm_bg_add(win);
+   elm_win_resize_object_add(win, bg);
+   evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(bg);
+
+   bx = elm_box_add(win);
+   evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_win_resize_object_add(win, bx);
+   evas_object_show(bx);
+
+   gl = elm_genlist_add(win);
+   evas_object_smart_callback_add(gl, "selected", _gl_selected, NULL);
+   evas_object_smart_callback_add(gl, "clicked", _gl_clicked, NULL);
+   evas_object_smart_callback_add(gl, "longpressed", _gl_longpress, NULL);
+   evas_object_size_hint_weight_set(gl, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(gl, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   elm_box_pack_end(bx, gl);
+   evas_object_show(gl);
+
+   itc1.item_style     = "default";
+   itc1.func.label_get = gl_label_get;
+   itc1.func.icon_get  = gl_icon_get;
+   itc1.func.state_get = gl_state_get;
+   itc1.func.del       = gl_del;
+
+   itc_group.item_style     = "group_index";
+   itc_group.func.label_get = gl8_label_get;
+   itc_group.func.icon_get  = NULL;
+   itc_group.func.state_get = NULL;
+   itc_group.func.del       = gl_del;
+
+   bx2 = elm_box_add(win);
+   elm_box_horizontal_set(bx2, EINA_TRUE);
+   elm_box_homogenous_set(bx2, EINA_TRUE);
+   evas_object_size_hint_weight_set(bx2, EVAS_HINT_EXPAND, 0.0);
+   evas_object_size_hint_align_set(bx2, EVAS_HINT_FILL, EVAS_HINT_FILL);
+
+   bt_num = 0;
+   bt[bt_num] = elm_button_add(win);
+   elm_button_label_set(bt[bt_num], "Show 0");
+   evas_object_size_hint_align_set(bt[bt_num], EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt[bt_num], EVAS_HINT_EXPAND, 0.0);
+   evas_object_show(bt[bt_num]);
+   elm_box_pack_end(bx2, bt[bt_num]);
+
+   bt[++bt_num] = elm_button_add(win);
+   elm_button_label_set(bt[bt_num], "Show 26");
+   evas_object_size_hint_align_set(bt[bt_num], EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt[bt_num], EVAS_HINT_EXPAND, 0.0);
+   evas_object_show(bt[bt_num]);
+   elm_box_pack_end(bx2, bt[bt_num]);
+
+   bt[++bt_num] = elm_button_add(win);
+   elm_button_label_set(bt[bt_num], "Show 101");
+   evas_object_size_hint_align_set(bt[bt_num], EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt[bt_num], EVAS_HINT_EXPAND, 0.0);
+   evas_object_show(bt[bt_num]);
+   elm_box_pack_end(bx2, bt[bt_num]);
+
+   bt[++bt_num] = elm_button_add(win);
+   elm_button_label_set(bt[bt_num], "Show 480");
+   evas_object_size_hint_align_set(bt[bt_num], EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt[bt_num], EVAS_HINT_EXPAND, 0.0);
+   evas_object_show(bt[bt_num]);
+   elm_box_pack_end(bx2, bt[bt_num]);
+
+   elm_box_pack_end(bx, bx2);
+   evas_object_show(bx2);
+
+   bx3 = elm_box_add(win);
+   elm_box_horizontal_set(bx3, EINA_TRUE);
+   elm_box_homogenous_set(bx3, EINA_TRUE);
+   evas_object_size_hint_weight_set(bx3, EVAS_HINT_EXPAND, 0.0);
+   evas_object_size_hint_align_set(bx3, EVAS_HINT_FILL, EVAS_HINT_FILL);
+
+   bt[++bt_num] = elm_button_add(win);
+   elm_button_label_set(bt[bt_num], "Bring top 0");
+   evas_object_size_hint_align_set(bt[bt_num], EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt[bt_num], EVAS_HINT_EXPAND, 0.0);
+   evas_object_show(bt[bt_num]);
+   elm_box_pack_end(bx3, bt[bt_num]);
+
+   bt[++bt_num] = elm_button_add(win);
+   elm_button_label_set(bt[bt_num], "Bring top 31");
+   evas_object_size_hint_align_set(bt[bt_num], EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt[bt_num], EVAS_HINT_EXPAND, 0.0);
+   evas_object_show(bt[bt_num]);
+   elm_box_pack_end(bx3, bt[bt_num]);
+
+   bt[++bt_num] = elm_button_add(win);
+   elm_button_label_set(bt[bt_num], "Bring top 239");
+   evas_object_size_hint_align_set(bt[bt_num], EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt[bt_num], EVAS_HINT_EXPAND, 0.0);
+   evas_object_show(bt[bt_num]);
+   elm_box_pack_end(bx3, bt[bt_num]);
+
+   bt[++bt_num] = elm_button_add(win);
+   elm_button_label_set(bt[bt_num], "Bring top 477");
+   evas_object_size_hint_align_set(bt[bt_num], EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt[bt_num], EVAS_HINT_EXPAND, 0.0);
+   evas_object_show(bt[bt_num]);
+   elm_box_pack_end(bx3, bt[bt_num]);
+
+   elm_box_pack_end(bx, bx3);
+   evas_object_show(bx3);
+
+   bt_count = 0;
+   for (i = 0; i < 500; i++)
+     {
+        if (!(i % 10))
+          {
+             gli = git = elm_genlist_item_append(gl, &itc_group,
+                                           (void *)(long)i/* item data */,
+                                           NULL/* parent */,
+                                           ELM_GENLIST_ITEM_GROUP,
+                                           gl_sel/* func */,
+                                           (void *)(long)(i * 10)/* func data 
*/);
+          }
+        else if (git)
+          {
+             gli = elm_genlist_item_append(gl, &itc1,
+                                           (void *)(long)i/* item data */,
+                                           git/* parent */,
+                                           ELM_GENLIST_ITEM_NONE,
+                                           gl_sel/* func */,
+                                           (void *)(long)(i * 10)/* func data 
*/);
+          }
+        //elm_genlist_item_display_only_set(gli, EINA_TRUE);
+        switch (i)
+          {
+           case 0: 
+              evas_object_smart_callback_add(bt[0], "clicked", _bt_show_cb, 
gli);
+              evas_object_smart_callback_add(bt[4], "clicked", _bt_bring_cb, 
gli);
+              break;
+           case 26: 
+              evas_object_smart_callback_add(bt[1], "clicked", _bt_show_cb, 
gli);
+              break;
+           case 31: 
+              evas_object_smart_callback_add(bt[5], "clicked", _bt_bring_cb, 
gli);
+              break;
+           case 101: 
+              evas_object_smart_callback_add(bt[2], "clicked", _bt_show_cb, 
gli);
+              break;
+           case 239: 
+              evas_object_smart_callback_add(bt[6], "clicked", _bt_bring_cb, 
gli);
+              break;
+           case 477: 
+              evas_object_smart_callback_add(bt[7], "clicked", _bt_bring_cb, 
gli);
+              break;
+           case 480: 
+              evas_object_smart_callback_add(bt[3], "clicked", _bt_show_cb, 
gli);
+              break;
+          }
+     }
+
+   evas_object_resize(win, 480, 800);
+   evas_object_show(win);
+}
+
+/*************/
+
+static void
+gl9_exp(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
+{
+   Elm_Genlist_Item *it = event_info;
+   Evas_Object *gl = elm_genlist_item_genlist_get(it);
+   int val = (int)(long)elm_genlist_item_data_get(it);
+   val *= 10;
+   elm_genlist_item_append(gl, &itc1,
+                           (void *)(long)(val + 1)/* item data */, it/* parent 
*/,
+                           ELM_GENLIST_ITEM_NONE, gl4_sel/* func */,
+                           NULL/* func data */);
+   elm_genlist_item_append(gl, &itc1,
+                           (void *)(long)(val + 2)/* item data */, it/* parent 
*/,
+                           ELM_GENLIST_ITEM_NONE, gl4_sel/* func */,
+                           NULL/* func data */);
+   elm_genlist_item_append(gl, &itc1,
+                           (void *)(long)(val + 3)/* item data */, it/* parent 
*/,
+                           ELM_GENLIST_ITEM_SUBITEMS, gl4_sel/* func */,
+                           NULL/* func data */);
+}
+static void
+gl9_con(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
+{
+   Elm_Genlist_Item *it = event_info;
+   elm_genlist_item_subitems_clear(it);
+}
+
+static void
+gl9_exp_req(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void 
*event_info)
+{
+   Elm_Genlist_Item *it = event_info;
+   elm_genlist_item_expanded_set(it, EINA_TRUE);
+}
+static void
+gl9_con_req(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void 
*event_info)
+{
+   Elm_Genlist_Item *it = event_info;
+   elm_genlist_item_expanded_set(it, EINA_FALSE);
+}
+
+void
+test_genlist9(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void 
*event_info __UNUSED__)
+{
+   Evas_Object *win, *bg, *gl, *bt[8], *bx, *bx2, *bx3;
+   Evas_Object *over;
+   Elm_Genlist_Item *git;
+
+   win = elm_win_add(NULL, "genlist-group-tree", ELM_WIN_BASIC);
+   elm_win_title_set(win, "Genlist Group Tree");
+   elm_win_autodel_set(win, 1);
+
+   bg = elm_bg_add(win);
+   elm_win_resize_object_add(win, bg);
+   evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(bg);
+
+   bx = elm_box_add(win);
+   evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_win_resize_object_add(win, bx);
+   evas_object_show(bx);
+
+   gl = elm_genlist_add(win);
+   evas_object_smart_callback_add(gl, "selected", _gl_selected, NULL);
+   evas_object_smart_callback_add(gl, "clicked", _gl_clicked, NULL);
+   evas_object_smart_callback_add(gl, "longpressed", _gl_longpress, NULL);
+   evas_object_size_hint_weight_set(gl, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(gl, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   elm_box_pack_end(bx, gl);
+   evas_object_show(gl);
+
+   itc1.item_style     = "default";
+   itc1.func.label_get = gl_label_get;
+   itc1.func.icon_get  = gl_icon_get;
+   itc1.func.state_get = gl_state_get;
+   itc1.func.del       = gl_del;
+
+   itc_group.item_style     = "group_index";
+   itc_group.func.label_get = gl8_label_get;
+   itc_group.func.icon_get  = NULL;
+   itc_group.func.state_get = NULL;
+   itc_group.func.del       = gl_del;
+
+   git = elm_genlist_item_append(gl, &itc_group,
+                          (void *)0/* item data */, NULL/* parent */, 
ELM_GENLIST_ITEM_GROUP, gl4_sel/* func */,
+                          NULL/* func data */);
+   elm_genlist_item_append(gl, &itc1,
+                          (void *)1/* item data */, git/* parent */, 
ELM_GENLIST_ITEM_SUBITEMS, gl4_sel/* func */,
+                          NULL/* func data */);
+   elm_genlist_item_append(gl, &itc1,
+                          (void *)2/* item data */, git/* parent */, 
ELM_GENLIST_ITEM_NONE, gl4_sel/* func */,
+                          NULL/* func data */);
+   elm_genlist_item_append(gl, &itc1,
+                          (void *)3/* item data */, git/* parent */, 
ELM_GENLIST_ITEM_SUBITEMS, gl4_sel/* func */,
+                          NULL/* func data */);
+   git = elm_genlist_item_append(gl, &itc_group,
+                          (void *)4/* item data */, NULL/* parent */, 
ELM_GENLIST_ITEM_GROUP, gl4_sel/* func */,
+                          NULL/* func data */);
+   elm_genlist_item_append(gl, &itc1,
+                          (void *)5/* item data */, git/* parent */, 
ELM_GENLIST_ITEM_SUBITEMS, gl4_sel/* func */,
+                          NULL/* func data */);
+   elm_genlist_item_append(gl, &itc1,
+                          (void *)6/* item data */, git/* parent */, 
ELM_GENLIST_ITEM_NONE, gl4_sel/* func */,
+                          NULL/* func data */);
+   elm_genlist_item_append(gl, &itc1,
+                          (void *)7/* item data */, git/* parent */, 
ELM_GENLIST_ITEM_SUBITEMS, gl4_sel/* func */,
+                          NULL/* func data */);
+
+   evas_object_smart_callback_add(gl, "expand,request", gl9_exp_req, gl);
+   evas_object_smart_callback_add(gl, "contract,request", gl9_con_req, gl);
+   evas_object_smart_callback_add(gl, "expanded", gl9_exp, gl);
+   evas_object_smart_callback_add(gl, "contracted", gl9_con, gl);
+
+   evas_object_resize(win, 480, 800);
+   evas_object_show(win);
+}
 #endif

Index: src/bin/test.c
===================================================================
--- src/bin/test.c      (revision 55777)
+++ src/bin/test.c      (working copy)
@@ -65,6 +65,8 @@ void test_genlist4(void *data, Evas_Object *obj, v
 void test_genlist5(void *data, Evas_Object *obj, void *event_info);
 void test_genlist6(void *data, Evas_Object *obj, void *event_info);
 void test_genlist7(void *data, Evas_Object *obj, void *event_info);
+void test_genlist8(void *data, Evas_Object *obj, void *event_info);
+void test_genlist9(void *data, Evas_Object *obj, void *event_info);
 void test_table(void *data, Evas_Object *obj, void *event_info);
 void test_gengrid(void *data, Evas_Object *obj, void *event_info);
 void test_gengrid2(void *data, Evas_Object *obj, void *event_info);
@@ -299,6 +301,8 @@ my_win_main(char *autorun)
    ADD_TEST("Genlist 5", test_genlist5);
    ADD_TEST("Genlist 7", test_genlist7);
    ADD_TEST("Genlist Tree", test_genlist6);
+   ADD_TEST("Genlist Group", test_genlist8);
+   ADD_TEST("Genlist Group Tree", test_genlist9);
    ADD_TEST("GenGrid", test_gengrid);
    ADD_TEST("GenGrid 2", test_gengrid2);
    ADD_TEST("Checks", test_check);
Index: data/themes/default.edc
===================================================================
--- data/themes/default.edc     (revision 55777)
+++ data/themes/default.edc     (working copy)
@@ -16233,6 +16233,282 @@ collections {
          }
       }
    }
+   group { name: "elm/genlist/item/group_index/default";
+      alias: "elm/genlist/item_odd/group_index/default";
+      data.item: "stacking" "above";
+      data.item: "selectraise" "on";
+      data.item: "labels" "elm.text";
+      data.item: "icons" "elm.swallow.icon elm.swallow.end";
+      data.item: "treesize" "20";
+//      data.item: "states" "";
+      images {
+         image: "bt_sm_base1.png" COMP;
+         image: "bt_sm_shine.png" COMP;
+         image: "bt_sm_hilight.png" COMP;
+         image: "ilist_item_shadow.png" COMP;
+         image: "group_index.png" COMP;
+      }
+      parts {
+         part {
+            name: "event";
+            type: RECT;
+            repeat_events: 0;
+            description {
+               state: "default" 0.0;
+               color: 0 0 0 0;
+            }
+         }
+         part {
+            name: "base_sh";
+            mouse_events: 0;
+            description {
+               state: "default" 0.0;
+               align: 0.0 0.0;
+               min: 0 10;
+               fixed: 1 1;
+               rel1 {
+                  to: "base";
+                  relative: 0.0 1.0;
+                  offset: 0 0;
+               }
+               rel2 {
+                  to: "base";
+                  relative: 1.0 1.0;
+                  offset: -1 0;
+               }
+               image {
+                  normal: "ilist_item_shadow.png";
+               }
+               fill.smooth: 0;
+            }
+         }
+         part {
+            name: "base";
+            mouse_events: 0;
+            description {
+               state: "default" 0.0;
+               image {
+                  normal: "group_index.png";
+                  border: 2 2 2 2;
+               }
+               fill.smooth: 0;
+            }
+         }
+         part { name: "bg";
+            clip_to: "disclip";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               visible: 0;
+               color: 255 255 255 0;
+               rel1 {
+                  relative: 0.0 0.0;
+                  offset: -5 -5;
+               }
+               rel2 {
+                  relative: 1.0 1.0;
+                  offset: 4 4;
+               }
+               image {
+                  normal: "bt_sm_base1.png";
+                  border: 6 6 6 6;
+               }
+               image.middle: SOLID;
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               color: 255 255 255 255;
+               rel1 {
+                  relative: 0.0 0.0;
+                  offset: -2 -2;
+               }
+               rel2 {
+                  relative: 1.0 1.0;
+                  offset: 1 1;
+               }
+            }
+         }
+         part { name: "elm.swallow.pad";
+            type: SWALLOW;
+            description { state: "default" 0.0;
+               fixed: 1 0;
+               align: 0.0 0.5;
+               rel1 {
+                  relative: 0.0  0.0;
+                  offset: 4 4;
+               }
+               rel2 {
+                  relative: 0.0  1.0;
+                  offset: 4 -5;
+               }
+            }
+         }
+         part { name: "elm.swallow.icon";
+            clip_to: "disclip";
+            type: SWALLOW;
+            description { state: "default" 0.0;
+               fixed: 1 0;
+               align: 0.0 0.5;
+               rel1 {
+                  to_x: "elm.swallow.pad";
+                  relative: 1.0 0.0;
+                  offset: -1 4;
+               }
+               rel2 {
+                  to_x: "elm.swallow.pad";
+                  relative: 1.0 1.0;
+                  offset: -1 -5;
+               }
+            }
+         }
+         part { name: "elm.swallow.end";
+            clip_to: "disclip";
+            type: SWALLOW;
+            description { state: "default" 0.0;
+               fixed: 1 0;
+               align: 1.0 0.5;
+               aspect: 1.0 1.0;
+               aspect_preference: VERTICAL;
+               rel1 {
+                  relative: 1.0 0.0;
+                  offset: -5 4;
+               }
+               rel2 {
+                  relative: 1.0 1.0;
+                  offset: -5 -5;
+               }
+            }
+         }
+         part { name: "elm.text";
+            clip_to: "disclip";
+            type: TEXT;
+            effect: SOFT_SHADOW;
+            mouse_events: 0;
+            scale: 1;
+            description {
+               state: "default" 0.0;
+//               min: 16 16;
+               rel1 {
+                  to_x: "elm.swallow.icon";
+                  relative: 1.0  0.0;
+                  offset: 0 4;
+               }
+               rel2 {
+                  to_x: "elm.swallow.end";
+                  relative: 0.0  1.0;
+                  offset: -1 -5;
+               }
+               color: 0 0 0 255;
+               color3: 0 0 0 0;
+               text {
+                  font: "Sans";
+                  size: 10;
+                  min: 1 1;
+//                  min: 0 1;
+                  align: 0.0 0.5;
+                  text_class: "list_item";
+               }
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               color: 224 224 224 255;
+               color3: 0 0 0 64;
+            }
+         }
+         part { name: "fg1";
+            clip_to: "disclip";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               visible: 0;
+               color: 255 255 255 0;
+               rel1.to: "bg";
+               rel2.relative: 1.0 0.5;
+               rel2.to: "bg";
+               image {
+                  normal: "bt_sm_hilight.png";
+                  border: 6 6 6 0;
+               }
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               color: 255 255 255 255;
+            }
+         }
+         part { name: "fg2";
+            clip_to: "disclip";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               visible: 0;
+               color: 255 255 255 0;
+               rel1.to: "bg";
+               rel2.to: "bg";
+               image {
+                  normal: "bt_sm_shine.png";
+                  border: 6 6 6 0;
+               }
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               color: 255 255 255 255;
+            }
+         }
+         part { name: "disclip";
+            type: RECT;
+            description { state: "default" 0.0;
+               rel1.to: "bg";
+               rel2.to: "bg";
+            }
+            description { state: "disabled" 0.0;
+               inherit: "default" 0.0;
+               color: 255 255 255 64;
+            }
+         }
+      }
+      programs {
+         // signal: elm,state,%s,active
+         //   a "check" item named %s went active
+         // signal: elm,state,%s,passive
+         //   a "check" item named %s went passive
+         // default is passive
+         program {
+            name:    "go_active";
+            signal:  "elm,state,selected";
+            source:  "elm";
+            action:  STATE_SET "selected" 0.0;
+            target:  "bg";
+            target:  "fg1";
+            target:  "fg2";
+            target:  "elm.text";
+         }
+         program {
+            name:    "go_passive";
+            signal:  "elm,state,unselected";
+            source:  "elm";
+            action:  STATE_SET "default" 0.0;
+            target:  "bg";
+            target:  "fg1";
+            target:  "fg2";
+            target:  "elm.text";
+            transition: LINEAR 0.1;
+         }
+         program {
+            name:    "go_disabled";
+            signal:  "elm,state,disabled";
+            source:  "elm";
+            action:  STATE_SET "disabled" 0.0;
+            target:  "disclip";
+         }
+         program {
+            name:    "go_enabled";
+            signal:  "elm,state,enabled";
+            source:  "elm";
+            action:  STATE_SET "default" 0.0;
+            target:  "disclip";
+         }
+      }
+   }
    group { name: "elm/genlist/item_compress/message/default";
       data.item: "stacking" "above";
       data.item: "selectraise" "on";

------------------------------------------------------------------------------
Learn how Oracle Real Application Clusters (RAC) One Node allows customers
to consolidate database storage, standardize their database environment, and, 
should the need arise, upgrade to a full multi-node Oracle RAC database 
without downtime or disruption
http://p.sf.net/sfu/oracle-sfdevnl
_______________________________________________
enlightenment-devel mailing list
enlightenment-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel

Reply via email to