From: chanwook jung <jchanwook@gmail.com>
authorchanwook jung <jchanwook@gmail.com>
Wed, 7 Mar 2012 12:15:36 +0000 (12:15 +0000)
committerCarsten Haitzler <raster@rasterman.com>
Wed, 7 Mar 2012 12:15:36 +0000 (12:15 +0000)
Subject: [E-devel] [Patch] elm_genlist : Add tree effect APIs

I made a patch for Tree Effect in elm_genlist.
This feature shows the flip effect when expand/contract the expandable
list.

External APIs :
+EAPI void               elm_genlist_tree_effect_enabled_set(Evas_Object
*obj, Eina_Bool enabled);
- Set Genlist tree effect

+EAPI Eina_Bool          elm_genlist_tree_effect_enabled_get(const
Evas_Object *obj);
- Get Genlist tree effect status

You can test it. "Genlist Tree Effect".

SVN revision: 68934

data/themes/widgets/genlist.edc
src/bin/test.c
src/bin/test_genlist.c
src/lib/elm_gen_common.h
src/lib/elm_genlist.c
src/lib/elm_genlist.h

index b2acb97..ac2ee06 100644 (file)
@@ -9561,3 +9561,632 @@ group { name: "elm/genlist/item/edit/default";
       }
    }
 }
+
+#define GENLIST_PART_MAP_START( param_x, param_y, param_z ) \
+description { state: "map_transition" 0.0; \
+   inherit: "default" 0.0; \
+   color: 50 50 50 100; \
+   map { \
+      perspective: "point"; \
+      on: 1; \
+      smooth: 1; \
+      perspective_on: 1; \
+      backface_cull: 1; \
+      rotation { \
+         center: "point"; \
+         x: param_x; \
+         y: param_y; \
+         z: param_z; \
+      } \
+   } \
+} \
+description { \
+   state: "hide" 0.0; \
+   inherit: "default" 0.0; \
+   visible: 0; \
+}
+
+#define GENLIST_PART_MAP_FINISH( param_x, param_y, param_z ) \
+description { \
+   state: "map_rotate" 0.0; \
+   inherit: "default" 0.0; \
+   map { \
+      perspective: "point"; \
+      on: 1; \
+      smooth: 1; \
+      perspective_on: 1; \
+      backface_cull: 1; \
+      rotation { \
+         center: "point"; \
+         x: param_x; \
+         y: param_y; \
+         z: param_z; \
+      } \
+   } \
+}
+
+group { name: "elm/genlist/tree/tree_effect/default";
+   data.item: "selectraise" "on";
+   data.item: "texts" "elm.text";
+   data.item: "contents" "elm.swallow.icon elm.swallow.end";
+   data.item: "treesize" "20";
+   images {
+      image: "bt_sm_base1.png" COMP;
+      image: "bt_sm_shine.png" COMP;
+      image: "bt_sm_hilight.png" COMP;
+      image: "ilist_1.png" COMP;
+      image: "ilist_2.png" COMP;
+      image: "ilist_item_shadow.png" COMP;
+      image: "icon_arrow_left.png" COMP;
+      image: "icon_arrow_right.png" COMP;
+      image: "icon_arrow_down.png" COMP;
+   }
+   parts {
+      part { name: "point";
+         type: RECT;
+         scale: 1;
+         description {
+            state: "default" 0.0;
+            color: 0 0 0 0;
+            rel1 { relative: 0.0 0.0; }
+            rel2 { relative: 1.0 0.0; }
+         }
+      }
+      part {
+         name:           "event";
+         type:           RECT;
+         repeat_events: 1;
+         description {
+            state: "default" 0.0;
+            color: 0 0 0 0;
+         }
+      }
+      part { name: "reorder_bg";
+         mouse_events: 0;
+         description { state: "default" 0.0;
+            visible: 0;
+            color: 255 255 255 0;
+            rel1 {
+               relative: 0.0 0.0;
+               offset: -7 -7;
+            }
+            rel2 {
+               relative: 1.0 1.0;
+               offset: 9 9;
+            }
+            image {
+               normal: "bt_bases.png";
+               border: 6 6 6 6;
+            }
+         }
+         description { state: "enabled" 0.0;
+            inherit: "default" 0.0;
+            visible: 1;
+            color: 255 255 255 255;
+         }
+      }
+      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;
+         }
+         description {
+            state: "default" 1.0;
+            inherit: "default" 0.0;
+            visible: 0;
+         }
+         GENLIST_PART_MAP_START(-90.0, 0.0, 0.0)
+         GENLIST_PART_MAP_FINISH(0.0, 0.0, 0.0)
+      }
+      part {
+         name: "base";
+         mouse_events: 0;
+         description {
+            state: "default" 0.0;
+            image {
+               normal: "ilist_1.png";
+               border: 2 2 2 2;
+            }
+            fill.smooth: 0;
+         }
+         description {
+            state: "default" 1.0;
+            inherit: "default" 0.0;
+            image.normal: "ilist_2.png";
+         }
+         GENLIST_PART_MAP_START(-90.0, 0.0, 0.0)
+         GENLIST_PART_MAP_FINISH(0.0, 0.0, 0.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;
+            }
+         }
+         GENLIST_PART_MAP_START(-90.0, 0.0, 0.0)
+         GENLIST_PART_MAP_FINISH(0.0, 0.0, 0.0)
+      }
+      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;
+            }
+         }
+         GENLIST_PART_MAP_START(-90.0, 0.0, 0.0)
+         GENLIST_PART_MAP_FINISH(0.0, 0.0, 0.0)
+      }
+      part { name: "arrow";
+         clip_to: "disclip";
+         ignore_flags: ON_HOLD;
+         description { state: "default" 0.0;
+            fixed: 1 0;
+            align: 0.0 0.5;
+            aspect: 1.0 1.0;
+            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;
+            }
+            image.normal: "icon_arrow_right.png";
+         }
+         description { state: "default" 0.1;
+            inherit: "default" 0.0;
+            image.normal: "icon_arrow_left.png";
+         }
+         description { state: "active" 0.0;
+            inherit: "default" 0.0;
+            image.normal: "icon_arrow_down.png";
+         }
+         description { state: "active" 0.1;
+            inherit: "default" 0.0;
+            image.normal: "icon_arrow_down.png";
+         }
+         GENLIST_PART_MAP_START(-90.0, 0.0, 0.0)
+         GENLIST_PART_MAP_FINISH(0.0, 0.0, 0.0)
+      }
+      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: "arrow";
+               relative: 1.0  0.0;
+               offset:   4    4;
+            }
+            rel2 {
+               to_x: "arrow";
+               relative: 1.0  1.0;
+               offset:   4   -5;
+            }
+         }
+         GENLIST_PART_MAP_START(-90.0, 0.0, 0.0)
+         GENLIST_PART_MAP_FINISH(0.0, 0.0, 0.0)
+      }
+      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;
+            }
+         }
+         GENLIST_PART_MAP_START(-90.0, 0.0, 0.0)
+         GENLIST_PART_MAP_FINISH(0.0, 0.0, 0.0)
+      }
+      part { name: "elm.text";
+         clip_to: "disclip";
+         type:           TEXT;
+         effect:         SOFT_SHADOW;
+         mouse_events:   0;
+         scale: 1;
+         description {
+            state: "default" 0.0;
+            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;
+               align: -1.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;
+         }
+         GENLIST_PART_MAP_START(-90.0, 0.0, 0.0)
+         GENLIST_PART_MAP_FINISH(0.0, 0.0, 0.0)
+      }
+      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;
+         }
+         GENLIST_PART_MAP_START(-90.0, 0.0, 0.0)
+         GENLIST_PART_MAP_FINISH(0.0, 0.0, 0.0)
+      }
+      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;
+         }
+         GENLIST_PART_MAP_START(-90.0, 0.0, 0.0)
+         GENLIST_PART_MAP_FINISH(0.0, 0.0, 0.0)
+      }
+      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:    "odd";
+         signal:  "elm,state,odd";
+         source:  "elm";
+         action:  STATE_SET "default" 1.0;
+         target:  "base_sh";
+         target:  "base";
+      }
+      program {
+         name:    "even";
+         signal:  "elm,state,even";
+         source:  "elm";
+         action:  STATE_SET "default" 0.0;
+         target:  "base_sh";
+         target:  "base";
+      }
+      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";
+      }
+      program {
+         name:    "go_reorder_disabled";
+         signal:  "elm,state,reorder,disabled";
+         source:  "elm";
+         action:  STATE_SET "default" 0.0;
+         target:  "reorder_bg";
+         transition: DECELERATE 0.5;
+      }
+      program {
+         name:    "go_reorder_enabled";
+         signal:  "elm,state,reorder,enabled";
+         source:  "elm";
+         action:  STATE_SET "enabled" 0.0;
+         target:  "reorder_bg";
+         transition: DECELERATE 0.5;
+      }
+      program {
+         name:    "expand";
+         signal:  "mouse,up,1";
+         source:  "arrow";
+         action:  SIGNAL_EMIT "elm,action,expand,toggle" "elm";
+      }
+      program {
+         name:    "go_expanded";
+         signal:  "elm,state,expanded";
+         source:  "elm";
+         script {
+            new st[31];
+            new Float:vl;
+            get_state(PART:"arrow", st, 30, vl);
+            set_state(PART:"arrow", "active", vl);
+         }
+      }
+      program {
+         name:    "go_contracted";
+         signal:  "elm,state,contracted";
+         source:  "elm";
+         script {
+            new st[31];
+            new Float:vl;
+            get_state(PART:"arrow", st, 30, vl);
+            set_state(PART:"arrow", "default", vl);
+         }
+      }
+      program { name: "to_rtl";
+         signal: "edje,state,rtl";
+         source: "edje";
+         script {
+            new st[31];
+            new Float:vl;
+            get_state(PART:"arrow", st, 30, vl);
+            if (vl == 0.0) {
+               set_state(PART:"arrow", st, 0.1);
+            }
+         }
+      }
+      program { name: "to_ltr";
+         signal: "edje,state,ltr";
+         source: "edje";
+         script {
+            new st[31];
+            new Float:vl;
+            get_state(PART:"arrow", st, 30, vl);
+            if (vl == 0.1) {
+               set_state(PART:"arrow", st, 0.0);
+            }
+         }
+      }
+      program {
+         name: "rotaion_transition";
+         signal: "flip_item";
+         action: STATE_SET "map_transition" 0.0;
+         after: "rotation";
+         target: "reorder_bg";
+         target: "base_sh";
+         target: "base";
+         target: "bg";
+         target: "arrow";
+         target: "elm.swallow.pad";
+         target: "elm.swallow.icon";
+         target: "elm.swallow.end";
+         target: "elm.text";
+         target: "fg1";
+         target: "fg2";
+      }
+      program {
+         name: "rotation";
+         action: STATE_SET "map_rotate" 0.0;
+         transition: LINEAR 0.2;
+         after: "rotation_end";
+         target: "reorder_bg";
+         target: "base_sh";
+         target: "base";
+         target: "bg";
+         target: "arrow";
+         target: "elm.swallow.pad";
+         target: "elm.swallow.icon";
+         target: "elm.swallow.end";
+         target: "elm.text";
+         target: "fg1";
+         target: "fg2";
+      }
+      program {
+         name: "rotation_end";
+         action: STATE_SET "default" 0.0;
+         target: "reorder_bg";
+         target: "base_sh";
+         target: "base";
+         target: "bg";
+         target: "arrow";
+         target: "elm.swallow.pad";
+         target: "elm.swallow.icon";
+         target: "elm.swallow.end";
+         target: "elm.text";
+         target: "fg1";
+         target: "fg2";
+      }
+      program {
+         name: "rotation_transition2";
+         signal: "elm,state,contract_flip";
+         action: STATE_SET "map_rotate" 0.0;
+         after: "rotation2";
+         target: "reorder_bg";
+         target: "base_sh";
+         target: "base";
+         target: "bg";
+         target: "arrow";
+         target: "elm.swallow.pad";
+         target: "elm.swallow.icon";
+         target: "elm.swallow.end";
+         target: "elm.text";
+         target: "fg1";
+         target: "fg2";
+      }
+      program {
+         name: "rotation2";
+         action: STATE_SET "map_transition" 0.0;
+         transition: LINEAR 0.5;
+         after: "rotation3";
+         target: "reorder_bg";
+         target: "base_sh";
+         target: "base";
+         target: "bg";
+         target: "arrow";
+         target: "elm.swallow.pad";
+         target: "elm.swallow.icon";
+         target: "elm.swallow.end";
+         target: "elm.text";
+         target: "fg1";
+         target: "fg2";
+      }
+      program {
+         name: "rotation3";
+         action: STATE_SET "hide" 0.0;
+         target: "reorder_bg";
+         target: "base_sh";
+         target: "base";
+         target: "bg";
+         target: "arrow";
+         target: "elm.swallow.pad";
+         target: "elm.swallow.icon";
+         target: "elm.swallow.end";
+         target: "elm.text";
+         target: "fg1";
+         target: "fg2";
+      }
+      program {
+         name: "show";
+         signal: "elm,state,show";
+         action: STATE_SET "default" 0.0;
+         target: "reorder_bg";
+         target: "base_sh";
+         target: "base";
+         target: "bg";
+         target: "arrow";
+         target: "elm.swallow.pad";
+         target: "elm.swallow.icon";
+         target: "elm.swallow.end";
+         target: "elm.text";
+         target: "fg1";
+         target: "fg2";
+      }
+      program {
+         name: "hide";
+         signal: "elm,state,hide";
+         action: STATE_SET "hide" 0.0;
+         target: "reorder_bg";
+         target: "base_sh";
+         target: "base";
+         target: "bg";
+         target: "arrow";
+         target: "elm.swallow.pad";
+         target: "elm.swallow.icon";
+         target: "elm.swallow.end";
+         target: "elm.text";
+         target: "fg1";
+         target: "fg2";
+      }
+   }
+}
index 24cb4c0..de0e075 100644 (file)
@@ -87,6 +87,7 @@ void test_genlist13(void *data, Evas_Object *obj, void *event_info);
 void test_genlist14(void *data, Evas_Object *obj, void *event_info);
 void test_genlist15(void *data, Evas_Object *obj, void *event_info);
 void test_genlist16(void *data, Evas_Object *obj, void *event_info);
+void test_genlist17(void *data, Evas_Object *obj, void *event_info);
 void test_gesture_layer(void *data, Evas_Object *obj, void *event_info);
 void test_gesture_layer2(void *data, Evas_Object *obj, void *event_info);
 void test_gesture_layer3(void *data, Evas_Object *obj, void *event_info);
@@ -437,6 +438,7 @@ add_tests:
    ADD_TEST(NULL, "Lists", "Genlist Tree, Insert Relative", test_genlist14);
    ADD_TEST(NULL, "Lists", "Genlist Edit Mode", test_genlist15);
    ADD_TEST(NULL, "Lists", "Genlist Flip Mode", test_genlist16);
+   ADD_TEST(NULL, "Lists", "Genlist Tree Effect", test_genlist17);
    ADD_TEST(NULL, "Lists", "GenGrid", test_gengrid);
    ADD_TEST(NULL, "Lists", "GenGrid 2", test_gengrid2);
    ADD_TEST(NULL, "Lists", "GenGrid Group", test_gengrid3);
index 5723e63..abe9e1f 100644 (file)
@@ -2591,4 +2591,199 @@ test_genlist16(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_i
    evas_object_resize(win, 520, 520);
    evas_object_show(win);
 }
+
+static Elm_Genlist_Item_Class itc17;
+
+static void
+gl17_sel(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
+{
+   Elm_Object_Item *glit = event_info;
+   int depth = elm_genlist_item_expanded_depth_get(glit);
+   printf("expanded depth for selected item is %d\n", depth);
+}
+
+static void
+gl17_exp(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
+{
+   Elm_Object_Item *glit = event_info;
+   Evas_Object *gl = elm_object_item_widget_get(glit);
+   int val = (int)(long) elm_object_item_data_get(glit);
+   val *= 10;
+   elm_genlist_item_append(gl, &itc17,
+                           (void *)(long) (val + 1)/* item data */,
+                           glit/* parent */,
+                           ELM_GENLIST_ITEM_SUBITEMS, gl17_sel/* func */,
+                           NULL/* func data */);
+   elm_genlist_item_append(gl, &itc17,
+                           (void *)(long) (val + 2)/* item data */,
+                           glit/* parent */,
+                           ELM_GENLIST_ITEM_SUBITEMS, gl17_sel/* func */,
+                           NULL/* func data */);
+   elm_genlist_item_append(gl, &itc17,
+                           (void *)(long) (val + 3)/* item data */,
+                           glit/* parent */,
+                           ELM_GENLIST_ITEM_SUBITEMS, gl17_sel/* func */,
+                           NULL/* func data */);
+   elm_genlist_item_append(gl, &itc17,
+                           (void *)(long) (val + 4)/* item data */,
+                           glit/* parent */,
+                           ELM_GENLIST_ITEM_SUBITEMS, gl17_sel/* func */,
+                           NULL/* func data */);
+   elm_genlist_item_append(gl, &itc17,
+                           (void *)(long) (val + 5)/* item data */,
+                           glit/* parent */,
+                           ELM_GENLIST_ITEM_SUBITEMS, gl17_sel/* func */,
+                           NULL/* func data */);
+   elm_genlist_item_append(gl, &itc17,
+                           (void *)(long) (val + 6)/* item data */,
+                           glit/* parent */,
+                           ELM_GENLIST_ITEM_SUBITEMS, gl17_sel/* func */,
+                           NULL/* func data */);
+}
+
+static void
+gl17_con(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
+{
+   Elm_Object_Item *glit = event_info;
+   elm_genlist_item_subitems_clear(glit);
+}
+
+static void
+gl17_exp_req(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
+{
+   Elm_Object_Item *glit = event_info;
+   elm_genlist_item_expanded_set(glit, EINA_TRUE);
+}
+
+static void
+gl17_con_req(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
+{
+   Elm_Object_Item *glit = event_info;
+   elm_genlist_item_expanded_set(glit, EINA_FALSE);
+}
+
+char *gl17_text_get(void *data, Evas_Object *obj __UNUSED__, const char *part __UNUSED__)
+{
+   char buf[256];
+   snprintf(buf, sizeof(buf), "Item mode %i", (int)(long)data);
+   return strdup(buf);
+}
+
+Evas_Object *gl17_content_get(void *data __UNUSED__, Evas_Object *obj, const char *part)
+{
+   char buf[PATH_MAX];
+   if (!strcmp(part, "elm.swallow.icon"))
+     {
+        Evas_Object *ic = elm_icon_add(obj);
+        snprintf(buf, sizeof(buf), "%s/images/logo_small.png", elm_app_data_dir_get());
+        elm_icon_file_set(ic, buf, NULL);
+        evas_object_size_hint_aspect_set(ic, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1);
+        evas_object_show(ic);
+        return ic;
+     }
+   else if (!strcmp(part, "elm.swallow.end"))
+     {
+        Evas_Object *ck;
+        ck = elm_check_add(obj);
+        evas_object_propagate_events_set(ck, EINA_FALSE);
+        evas_object_show(ck);
+        return ck;
+     }
+   return NULL;
+}
+
+Eina_Bool gl17_state_get(void *data __UNUSED__, Evas_Object *obj __UNUSED__, const char *part __UNUSED__)
+{
+   return EINA_FALSE;
+}
+
+void gl17_del(void *data __UNUSED__, Evas_Object *obj __UNUSED__)
+{
+   printf("item deleted.\n");
+}
+
+static void
+gl17_enabled_set(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   elm_genlist_tree_effect_enabled_set(data, EINA_TRUE);
+}
+
+static void
+gl17_disabled_set(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   elm_genlist_tree_effect_enabled_set(data, EINA_FALSE);
+}
+       
+void
+test_genlist17(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   Evas_Object *win, *gl, *bx, *bx2, *bt;
+
+   win = elm_win_util_standard_add("genlist17", "Genlist Tree Effect");
+   elm_win_autodel_set(win, EINA_TRUE);
+
+   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_size_hint_align_set(gl, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(gl, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(gl);
+
+   elm_genlist_tree_effect_enabled_set(gl,EINA_TRUE);
+
+   itc17.item_style     = "tree_effect";
+   itc17.func.text_get = gl17_text_get;
+   itc17.func.content_get  = gl17_content_get;
+   itc17.func.state_get = gl17_state_get;
+   itc17.func.del       = gl17_del;
+
+   elm_genlist_item_append(gl, &itc17,
+                           (void *)1/* item data */, NULL/* parent */, ELM_GENLIST_ITEM_SUBITEMS, gl17_sel/* func */,
+                           NULL/* func data */);
+   elm_genlist_item_append(gl, &itc17,
+                           (void *)2/* item data */, NULL/* parent */, ELM_GENLIST_ITEM_SUBITEMS, gl17_sel/* func */,
+                           NULL/* func data */);
+   elm_genlist_item_append(gl, &itc17,
+                           (void *)3/* item data */, NULL/* parent */, ELM_GENLIST_ITEM_SUBITEMS, gl17_sel/* func */,
+                           NULL/* func data */);
+
+   evas_object_smart_callback_add(gl, "expand,request", gl17_exp_req, gl);
+   evas_object_smart_callback_add(gl, "contract,request", gl17_con_req, gl);
+   evas_object_smart_callback_add(gl, "expanded", gl17_exp, gl);
+   evas_object_smart_callback_add(gl, "contracted", gl17_con, gl);
+
+   elm_box_pack_end(bx, gl);
+   evas_object_show(bx);
+
+   bx2 = elm_box_add(win);
+   elm_box_horizontal_set(bx2, EINA_TRUE);
+   elm_box_homogeneous_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 = elm_button_add(win);
+   elm_object_text_set(bt, "Enable");
+   evas_object_smart_callback_add(bt, "clicked", gl17_enabled_set, gl);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_object_text_set(bt, "Disable");
+   evas_object_smart_callback_add(bt, "clicked", gl17_disabled_set, gl);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_show(bt);
+
+   elm_box_pack_end(bx, bx2);
+   evas_object_show(bx2);
+
+   evas_object_resize(win, 320, 320);
+   evas_object_show(win);
+}
 #endif
index 4ba674b..507471c 100644 (file)
@@ -119,7 +119,7 @@ struct _Widget_Data
    Ecore_Timer                   *multi_timer, *scr_hold_timer;
    Ecore_Animator                *reorder_move_animator;
    const char                    *mode_type;
-   unsigned int                   start_time;
+   double                         start_time;
    Evas_Coord                     prev_x, prev_y, prev_mx, prev_my;
    Evas_Coord                     cur_x, cur_y, cur_mx, cur_my;
    Eina_Bool                      mouse_down : 1;
@@ -138,6 +138,7 @@ struct _Widget_Data
    Eina_Bool                      pan_changed : 1;
    Eina_Bool                      requeued : 1; /**< this is set to EINA_TRUE when the item is re-queued. this happens when the item is un-queued but the rel item is still in the queue. this item will be processed later. */
    Eina_Bool                      check_scroll : 1; /**< this flag means genlist is supposed to be scrolled. if this flag is set to EINA_TRUE, genlist checks whether it's ok to scroll genlist now or not. */
+   Eina_Bool                      tree_effect_enabled : 1; /**< tree effect */
    struct
      {
         Evas_Coord x, y;
@@ -152,6 +153,11 @@ struct _Widget_Data
    Eina_Compare_Cb                item_compare_cb;
    Eina_Compare_Cb                item_compare_data_cb;
    Elm_Genlist_Item_Scrollto_Type scrollto_type; /**< a scrollto type which remembers where to scroll ex) in, top, middle */
+   Evas_Object                   *alpha_bg; /**< not to receive event when tree effect is not finished */
+   Eina_List                     *move_items; /**< items move for tree effect */
+   Elm_Gen_Item                  *expanded_next_item;
+   Ecore_Animator                *item_moving_effect_timer; /**< tree effect */
+   Elm_Genlist_Item_Move_Effect_Mode move_effect_mode;
 
    /* The stuff below directly come from gengrid without any thinking */
    unsigned int                   nmax;
index 288d235..45daa7e 100644 (file)
@@ -76,6 +76,7 @@ struct Elm_Gen_Item_Type
    Eina_Bool                     nostacking : 1;
    Eina_Bool                     move_effect_enabled : 1;
    Eina_Bool                     edit_mode_item_realized : 1;
+   Eina_Bool                     tree_effect_finished : 1; /* tree effect */
 };
 
 struct _Item_Block
@@ -169,6 +170,12 @@ static void      _elm_genlist_clear(Evas_Object *obj,
 static void      _pan_child_size_get(Evas_Object *obj,
                                      Evas_Coord  *w,
                                      Evas_Coord  *h);
+static Evas_Object* _create_tray_alpha_bg(const Evas_Object *obj);
+static void         _item_contract_emit(Elm_Gen_Item *it);
+static int          _item_tree_effect_before(Elm_Gen_Item *it);
+static void         _item_tree_effect(Widget_Data *wd, int y);
+static void         _item_tree_effect_finish(Widget_Data *wd);
+static Eina_Bool    _item_moving_effect_timer_cb(void *data);
 
 static Evas_Smart_Class _pan_sc = EVAS_SMART_CLASS_INIT_VERSION;
 
@@ -206,6 +213,7 @@ static const char SIG_MULTI_PINCH_IN[] = "multi,pinch,in";
 static const char SIG_SWIPE[] = "swipe";
 static const char SIG_MOVED[] = "moved";
 static const char SIG_INDEX_UPDATE[] = "index,update";
+static const char SIG_TREE_EFFECT_FINISHED [] = "tree,effect,finished";
 
 static const Evas_Smart_Cb_Description _signals[] = {
    {SIG_CLICKED_DOUBLE, ""},
@@ -241,6 +249,7 @@ static const Evas_Smart_Cb_Description _signals[] = {
    {SIG_MULTI_PINCH_IN, ""},
    {SIG_SWIPE, ""},
    {SIG_MOVED, ""},
+   {SIG_TREE_EFFECT_FINISHED, ""},
    {NULL, NULL}
 };
 
@@ -816,6 +825,19 @@ _item_block_del(Elm_Gen_Item *it)
 }
 
 static void
+_item_subitems_clear(Elm_Gen_Item *it)
+{
+   ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
+   Eina_List *tl = NULL, *l;
+   Elm_Object_Item *it2;
+
+   EINA_LIST_FOREACH(it->item->items, l, it2)
+     tl = eina_list_append(tl, it2);
+   EINA_LIST_FREE(tl, it2)
+     elm_object_item_del(it2);
+}
+
+static void
 _item_del(Elm_Gen_Item *it)
 {
    Evas_Object *obj = WIDGET(it);
@@ -1962,7 +1984,7 @@ _item_realize(Elm_Gen_Item *it,
      it->item->nocache_once = EINA_FALSE;
    else if (!it->item->nocache)
      itc = _item_cache_find(it);
-   if (itc)
+   if (itc && (!it->wd->tree_effect_enabled))
      {
         VIEW(it) = itc->base_view;
         itc->base_view = NULL;
@@ -2437,7 +2459,8 @@ _item_block_position(Item_Block *itb,
                     }
                   else
                     {
-                       _elm_genlist_item_unrealize(it, EINA_FALSE);
+                       if (!it->wd->item_moving_effect_timer)
+                         _elm_genlist_item_unrealize(it, EINA_FALSE);
                     }
                }
              in++;
@@ -2967,7 +2990,21 @@ _pan_calculate(Evas_Object *obj)
         sd->wd->reorder_old_pan_y = sd->wd->pan_y;
         sd->wd->start_time = ecore_loop_time_get();
      }
-   _item_auto_scroll(sd->wd);
+
+   if (sd->wd->tree_effect_enabled && (sd->wd->move_effect_mode != ELM_GENLIST_ITEM_MOVE_EFFECT_NONE))
+     {
+        if (!sd->wd->item_moving_effect_timer)
+          {
+             _item_tree_effect_before(sd->wd->expanded_item);
+             evas_object_raise(sd->wd->alpha_bg);
+             evas_object_show(sd->wd->alpha_bg);
+             sd->wd->start_time = ecore_time_get();
+             sd->wd->item_moving_effect_timer = ecore_animator_add(_item_moving_effect_timer_cb, sd->wd);
+          }
+     }
+   else
+     _item_auto_scroll(sd->wd);
+
    evas_event_thaw(evas_object_evas_get(obj));
    evas_event_thaw_eval(evas_object_evas_get(obj));
 }
@@ -4402,6 +4439,10 @@ _elm_genlist_clear(Evas_Object *obj, Eina_Bool standby)
    wd->pan_y = 0;
    wd->minw = 0;
    wd->minh = 0;
+
+   if (wd->alpha_bg) evas_object_del(wd->alpha_bg);
+   wd->alpha_bg = NULL;
+
    if (wd->pan_smart)
      {
         evas_object_size_hint_min_set(wd->pan_smart, wd->minw, wd->minh);
@@ -4601,15 +4642,26 @@ EAPI void
 elm_genlist_item_subitems_clear(Elm_Object_Item *it)
 {
    ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
-   Eina_List *tl = NULL, *l;
-   Elm_Gen_Item *_it;
-   Elm_Object_Item *it2;
-   _it = (Elm_Gen_Item *)it;
+   Widget_Data *wd = elm_widget_data_get(WIDGET(it));
+   if (!wd) return;
+   Elm_Gen_Item *_it = (Elm_Gen_Item *) it;
 
-   EINA_LIST_FOREACH(_it->item->items, l, it2)
-     tl = eina_list_append(tl, it2);
-   EINA_LIST_FREE(tl, it2)
-     elm_object_item_del(it2);
+   if (!wd->tree_effect_enabled || !wd->move_effect_mode)
+     _item_subitems_clear(_it);
+   else
+     {
+        if (!wd->item_moving_effect_timer)
+          {
+             wd->expanded_item = _it;
+             _item_tree_effect_before(_it);
+             evas_object_raise(wd->alpha_bg);
+             evas_object_show(wd->alpha_bg);
+             wd->start_time = ecore_time_get();
+             wd->item_moving_effect_timer = ecore_animator_add(_item_moving_effect_timer_cb, wd);
+          }
+        else
+           _item_subitems_clear(_it);
+     }
 }
 
 EAPI void
@@ -4650,6 +4702,57 @@ elm_genlist_item_selected_get(const Elm_Object_Item *it)
    return ((Elm_Gen_Item *)it)->selected;
 }
 
+Elm_Gen_Item *
+_elm_genlist_expanded_next_item_get(Elm_Gen_Item *it)
+{
+   Elm_Gen_Item *it2;
+   if (it->item->expanded)
+     {
+        it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it);
+     }
+   else
+     {
+        it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it);
+        while (it2)
+          {
+             if (it->item->expanded_depth >= it2->item->expanded_depth) break;
+             it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it2);
+          }
+     }
+   return it2;
+}
+
+static void
+_elm_genlist_move_items_set(Elm_Gen_Item *it)
+{
+   Eina_List *l;
+   Elm_Gen_Item *it2 = NULL;
+   Evas_Coord ox, oy, ow, oh, dh = 0;
+
+   it->wd->expanded_next_item = _elm_genlist_expanded_next_item_get(it);
+
+   if (it->item->expanded)
+     {
+        it->wd->move_items = elm_genlist_realized_items_get(it->wd->obj);
+        EINA_LIST_FOREACH(it->wd->move_items, l, it2)
+          {
+             if (it2 == it->wd->expanded_next_item) break;
+             it->wd->move_items = eina_list_remove(it->wd->move_items, it2);
+          }
+     }
+   else
+     {
+        evas_object_geometry_get(it->wd->pan_smart, &ox, &oy, &ow, &oh);
+        it2 = it->wd->expanded_next_item;
+        while (it2 && (dh < oy + oh))
+          {
+             dh += it2->item->h;
+             it->wd->move_items = eina_list_append(it->wd->move_items, it2);
+             it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it2);
+          }
+     }
+}
+
 EAPI void
 elm_genlist_item_expanded_set(Elm_Object_Item  *it,
                               Eina_Bool         expanded)
@@ -4659,21 +4762,27 @@ elm_genlist_item_expanded_set(Elm_Object_Item  *it,
    expanded = !!expanded;
    if (_it->item->expanded == expanded) return;
    _it->item->expanded = expanded;
+   _it->wd->expanded_item = _it;
+   _elm_genlist_move_items_set(_it);
+
+   if (_it->wd->tree_effect_enabled && !_it->wd->alpha_bg)
+      _it->wd->alpha_bg = _create_tray_alpha_bg(WIDGET(_it));
+
    if (_it->item->expanded)
      {
+        _it->wd->move_effect_mode = ELM_GENLIST_ITEM_MOVE_EFFECT_EXPAND;
         if (_it->realized)
           edje_object_signal_emit(VIEW(_it), "elm,state,expanded", "elm");
         evas_object_smart_callback_call(WIDGET(_it), SIG_EXPANDED, _it);
         _it->wd->auto_scroll_enabled = EINA_TRUE;
-        _it->wd->expanded_item = _it;
      }
    else
      {
+        _it->wd->move_effect_mode = ELM_GENLIST_ITEM_MOVE_EFFECT_CONTRACT;
         if (_it->realized)
           edje_object_signal_emit(VIEW(_it), "elm,state,contracted", "elm");
         evas_object_smart_callback_call(WIDGET(_it), SIG_CONTRACTED, _it);
         _it->wd->auto_scroll_enabled = EINA_FALSE;
-        _it->wd->expanded_item = NULL;
      }
 }
 
@@ -5755,3 +5864,285 @@ _elm_genlist_item_del_serious(Elm_Gen_Item *it)
      it->wd->last_selected_item = NULL;
    it->wd->item_count--;
 }
+
+EAPI void
+elm_genlist_tree_effect_enabled_set(Evas_Object *obj, Eina_Bool enabled)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   wd->tree_effect_enabled = !!enabled;
+}
+
+EAPI Eina_Bool
+elm_genlist_tree_effect_enabled_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return EINA_FALSE;
+   return wd->tree_effect_enabled;
+}
+
+static Evas_Object*
+_create_tray_alpha_bg(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return NULL;
+
+   Evas_Object *bg = NULL;
+   Evas_Coord ox, oy, ow, oh;
+
+   evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh);
+   bg  =  evas_object_rectangle_add(evas_object_evas_get(wd->obj));
+   evas_object_color_set(bg,0,0,0,0);
+   evas_object_resize(bg , ow, oh);
+   evas_object_move(bg , ox, oy);
+   return bg ;
+}
+
+static void
+_item_contract_emit(Elm_Gen_Item *it)
+{
+   Elm_Gen_Item *it2;
+   Eina_List *l;
+
+   edje_object_signal_emit(VIEW(it), "elm,state,contract_flip", "");
+   it->item->tree_effect_finished = EINA_FALSE;
+
+   EINA_LIST_FOREACH(it->item->items, l, it2)
+     if (it2) _item_contract_emit(it2);
+}
+
+static int
+_item_tree_effect_before(Elm_Gen_Item *it)
+{
+   Elm_Gen_Item *it2;
+   Eina_List *l;
+
+   EINA_LIST_FOREACH(it->item->items, l, it2)
+     {
+        if (it2->parent && (it == it2->parent))
+          {
+             if (it->wd->move_effect_mode == ELM_GENLIST_ITEM_MOVE_EFFECT_EXPAND)
+               edje_object_signal_emit(VIEW(it2), "elm,state,hide", "");
+             else if (it->wd->move_effect_mode == ELM_GENLIST_ITEM_MOVE_EFFECT_CONTRACT)
+               _item_contract_emit(it2);
+          }
+     }
+   return ECORE_CALLBACK_CANCEL;
+}
+
+static void
+_item_tree_effect(Widget_Data *wd, int y)
+{
+   Elm_Gen_Item *it = NULL, *expanded_next_it;
+
+   expanded_next_it = wd->expanded_next_item;
+
+   if (wd->move_effect_mode == ELM_GENLIST_ITEM_MOVE_EFFECT_EXPAND)
+     {
+        it = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) expanded_next_it);
+        while (it)
+          {
+             if (it->item->expanded_depth <= expanded_next_it->item->expanded_depth) break;
+             if (it->item->scrl_y && (it->item->scrl_y < expanded_next_it->item->old_scrl_y + y) &&
+                 (it->item->expanded_depth > expanded_next_it->item->expanded_depth))
+               {
+                  if (!it->item->tree_effect_finished)
+                    {
+                       edje_object_signal_emit(VIEW(it), "flip_item", "");
+                       evas_object_show(VIEW(it));
+                       it->item->tree_effect_finished = EINA_TRUE;
+                    }
+               }
+             it = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) it);
+          }
+     }
+   else if (wd->move_effect_mode == ELM_GENLIST_ITEM_MOVE_EFFECT_CONTRACT)
+     {
+        it = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) expanded_next_it);
+        while (it)
+          {
+             if ((it->item->scrl_y > expanded_next_it->item->old_scrl_y + y) &&
+                 (it->item->expanded_depth > expanded_next_it->item->expanded_depth))
+               {
+                  if (!it->item->tree_effect_finished)
+                    {
+                       edje_object_signal_emit(VIEW(it), "elm,state,hide", "");
+                       it->item->tree_effect_finished = EINA_TRUE;
+                    }
+               }
+             else
+               break;
+             it = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) it);
+          }
+     }
+}
+
+static void
+_item_tree_effect_finish(Widget_Data *wd)
+{
+   Item_Block *itb;
+   Elm_Gen_Item *it = NULL;
+   const Eina_List *l;
+
+   if (wd->item_moving_effect_timer)
+     {
+        if (wd->move_effect_mode == ELM_GENLIST_ITEM_MOVE_EFFECT_CONTRACT)
+           _item_subitems_clear(wd->expanded_item);
+        EINA_INLIST_FOREACH(wd->blocks, itb)
+          {
+             EINA_LIST_FOREACH(itb->items, l, it)
+               {
+                  it->item->tree_effect_finished = EINA_TRUE;
+                  it->item->old_scrl_y = it->item->scrl_y;
+               }
+          }
+     }
+   _item_auto_scroll(wd);
+   evas_object_lower(wd->alpha_bg);
+   evas_object_hide(wd->alpha_bg);
+   wd->move_effect_mode = ELM_GENLIST_ITEM_MOVE_EFFECT_NONE;
+   if (wd->move_items) wd->move_items = eina_list_free(wd->move_items);
+
+   evas_object_smart_callback_call(wd->pan_smart, "changed", NULL);
+   evas_object_smart_callback_call(wd->obj, SIG_TREE_EFFECT_FINISHED, NULL);
+   evas_object_smart_changed(wd->pan_smart);
+
+   wd->item_moving_effect_timer = NULL;
+}
+
+static Eina_Bool
+_item_moving_effect_timer_cb(void *data)
+{
+   Widget_Data *wd = data;
+   if (!wd) return EINA_FALSE;
+   Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh;
+   Elm_Gen_Item *it = NULL, *it2, *expanded_next_it;
+   const Eina_List *l;
+   double effect_duration = 0.5, t;
+   int y = 0, dy = 0, dh = 0;
+   Eina_Bool end = EINA_FALSE, vis = EINA_TRUE;
+   int in = 0;
+
+   t = ((0.0 > (t = ecore_time_get() - wd->start_time)) ? 0.0 : t);
+   evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh);
+   evas_output_viewport_get(evas_object_evas_get(wd->pan_smart), &cvx, &cvy, &cvw, &cvh);
+   if (t > effect_duration) end = EINA_TRUE;
+
+   // Below while statement is needed, when the genlist is resized.
+   it2 = wd->expanded_item;
+   while (it2 && vis)
+     {
+        evas_object_move(VIEW(it2), it2->item->scrl_x, it2->item->scrl_y);
+        vis = (ELM_RECTS_INTERSECT(it2->item->scrl_x, it2->item->scrl_y, it2->item->w, it2->item->h,
+                                   cvx, cvy, cvw, cvh));
+        it2 = (Elm_Gen_Item *) elm_genlist_item_prev_get((Elm_Object_Item *) it2);
+     }
+
+   if (wd->expanded_next_item)
+     {
+        expanded_next_it = wd->expanded_next_item;
+
+        /* move items */
+        EINA_LIST_FOREACH(wd->move_items, l, it)
+          {
+             if (wd->move_effect_mode == ELM_GENLIST_ITEM_MOVE_EFFECT_EXPAND)
+               {
+                  expanded_next_it->item->old_scrl_y = wd->expanded_item->item->old_scrl_y + wd->expanded_item->item->h;
+                  if (expanded_next_it->item->scrl_y < expanded_next_it->item->old_scrl_y) //did not calculate next item position
+                    expanded_next_it->item->scrl_y = cvy + cvh;
+
+                  dy = ((expanded_next_it->item->scrl_y >= (cvy + cvh)) ?
+                         cvy + cvh : expanded_next_it->item->scrl_y) -
+                         expanded_next_it->item->old_scrl_y;
+               }
+             else if (wd->move_effect_mode == ELM_GENLIST_ITEM_MOVE_EFFECT_CONTRACT)
+               {
+                  if (expanded_next_it->item->scrl_y > expanded_next_it->item->old_scrl_y) //did not calculate next item position
+                     expanded_next_it->item->old_scrl_y = cvy + cvh;
+
+                  if (expanded_next_it->item->old_scrl_y > (cvy + cvh))
+                    {
+                       dy = (wd->expanded_item->item->scrl_y + wd->expanded_item->item->h) -
+                            cvy + cvh;
+                       expanded_next_it->item->old_scrl_y = cvy + cvh;
+                    }
+                  else
+                    {
+                       dy = (wd->expanded_item->item->scrl_y + wd->expanded_item->item->h) -
+                             expanded_next_it->item->old_scrl_y;
+                    }
+               }
+
+             if (t <= effect_duration)
+               {
+                  y = ((1 - (1 - (t / effect_duration)) * (1 - (t /effect_duration))) * dy);
+               }
+             else
+               {
+                  end = EINA_TRUE;
+                  y = dy;
+               }
+
+             if (!it->realized)
+               {
+                  _item_realize(it, in, 0);
+               }
+             in++;
+
+             if (it != expanded_next_it)
+               {
+                  it->item->old_scrl_y = expanded_next_it->item->old_scrl_y + expanded_next_it->item->h + dh;
+                  dh += it->item->h;
+               }
+
+             if ((it->item->old_scrl_y + y) < (cvy + cvh))
+               _item_position(it, VIEW(it),it->item->scrl_x, it->item->old_scrl_y + y);
+          }
+        /* tree effect */
+        _item_tree_effect(wd, y);
+     }
+   else
+     {
+        int expanded_item_num = 0;
+        int num = 0;
+
+        if (wd->expanded_item)
+          it = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) wd->expanded_item);
+
+        it2 = it;
+        while (it2)
+          {
+             expanded_item_num++;
+             it2 = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it2);
+          }
+
+        while (it)
+          {
+             num++;
+             if (wd->expanded_item->item->expanded_depth >= it->item->expanded_depth) break;
+             if (wd->move_effect_mode == ELM_GENLIST_ITEM_MOVE_EFFECT_EXPAND)
+               {
+                  if (!it->item->tree_effect_finished)
+                    {
+                       if (t >= (((num - 1) * effect_duration) / expanded_item_num))
+                         {
+                            edje_object_signal_emit(VIEW(it), "flip_item", "");
+                            evas_object_show(VIEW(it));
+                            it->item->tree_effect_finished = EINA_TRUE;
+                         }
+                    }
+               }
+             it = (Elm_Gen_Item *) elm_genlist_item_next_get((Elm_Object_Item *) it);
+          }
+     }
+
+   if (end)
+     {
+        _item_tree_effect_finish(wd);
+        return ECORE_CALLBACK_CANCEL;
+     }
+   return ECORE_CALLBACK_RENEW;
+}
index b20d4c5..547145b 100644 (file)
  * - @c "moved" - This is called when a genlist item is moved.
  * - @c "language,changed" - This is called when the program's language is
  *   changed.
+ * - @c "tree,effect,finished" - This is called when a genlist tree effect is finished.
  *
  * Supported elm_object common APIs
  * @li elm_object_signal_emit()
@@ -380,6 +381,13 @@ typedef enum
    ELM_GENLIST_ITEM_SCROLLTO_MIDDLE = (1 << 2)   /**< middle show, middle bring in */
 } Elm_Genlist_Item_Scrollto_Type;
 
+typedef enum
+{
+   ELM_GENLIST_ITEM_MOVE_EFFECT_NONE         = 0,
+   ELM_GENLIST_ITEM_MOVE_EFFECT_EXPAND       = 1,
+   ELM_GENLIST_ITEM_MOVE_EFFECT_CONTRACT     = 2
+} Elm_Genlist_Item_Move_Effect_Mode;
+
 /**
  * @see Elm_Gen_Item_Class
  */
@@ -1878,5 +1886,27 @@ EAPI void elm_genlist_item_flip_set(Elm_Object_Item *it, Eina_Bool flip);
 EAPI Eina_Bool elm_genlist_item_flip_get(const Elm_Object_Item *it);
 
 /**
+ * Set Genlist tree effect
+ *
+ * @param obj The genlist object
+ * @param The tree effect status
+ * (EINA_TRUE = enabled, EINA_FALSE = disabled
+ *
+ * @ingroup Genlist
+ */
+EAPI void               elm_genlist_tree_effect_enabled_set(Evas_Object *obj, Eina_Bool enabled);
+
+/**
+ * Get Genlist tree effect
+ *
+ * @param obj The genlist object
+ * @return The tree effect status
+ * (EINA_TRUE = enabled, EINA_FALSE = disabled
+ *
+ * @ingroup Genlist
+ */
+EAPI Eina_Bool          elm_genlist_tree_effect_enabled_get(const Evas_Object *obj);
+
+/**
  * @}
  */