felipealmeida pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=fd92dec358bf6d98b4b334e938140049b6f5f12e

commit fd92dec358bf6d98b4b334e938140049b6f5f12e
Author: Felipe Magno de Almeida <[email protected]>
Date:   Tue Dec 12 22:59:48 2017 -0200

    elementary: Add efl_ui_list widget
---
 config/default/base.src.in                         | 269 +++++++++
 config/mobile/base.src.in                          | 269 +++++++++
 config/standard/base.src.in                        | 269 +++++++++
 data/elementary/themes/Makefile.am                 |   1 +
 data/elementary/themes/default.edc                 |   1 +
 data/elementary/themes/edc/efl/list.edc            |   8 +
 src/Makefile_Elementary.am                         |  15 +-
 src/examples/elementary/Makefile.am                |  25 +-
 src/examples/elementary/efl_ui_list_example.edc    | 280 +++++++++
 src/examples/elementary/efl_ui_list_example_1.c    | 111 ++++
 src/examples/elementary/efl_ui_list_example_2.c    |  74 +++
 src/examples/elementary/efl_ui_list_example_3.c    | 329 ++++++++++
 src/examples/elementary/layout_model_connect.c     |   1 -
 src/lib/elementary/Elementary.h                    |   8 +
 src/lib/elementary/efl_ui_layout.c                 |  32 +-
 src/lib/elementary/efl_ui_layout_factory.c         | 127 ++++
 src/lib/elementary/efl_ui_layout_factory.eo        |  22 +
 src/lib/elementary/efl_ui_list.c                   | 668 +++++++++++++++++++++
 src/lib/elementary/efl_ui_list.eo                  | 108 ++++
 src/lib/elementary/efl_ui_list_model.eo            |  48 ++
 src/lib/elementary/efl_ui_list_pan.eo              |  16 +
 src/lib/elementary/efl_ui_list_precise_layouter.c  | 659 ++++++++++++++++++++
 src/lib/elementary/efl_ui_list_precise_layouter.eo |   8 +
 src/lib/elementary/efl_ui_list_private.h           | 132 ++++
 src/lib/elementary/efl_ui_list_relayout.eo         |  23 +
 src/lib/elementary/efl_ui_list_segarray.c          | 427 +++++++++++++
 src/lib/elementary/efl_ui_list_segarray.h          |  42 ++
 src/lib/elementary/efl_ui_list_types.eot           |   9 +
 src/lib/elementary/elm_widget_layout.h             |   2 +-
 29 files changed, 3973 insertions(+), 10 deletions(-)

diff --git a/config/default/base.src.in b/config/default/base.src.in
index 10d7d0e6a5..7e9444c10c 100644
--- a/config/default/base.src.in
+++ b/config/default/base.src.in
@@ -2796,5 +2796,274 @@ group "Elm_Config" struct {
            }
         }
      }
+     group "Elm_Config_Bindings_Widget" struct {
+        value "name" string: "Efl.Ui.List";
+        group "key_bindings" list {
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "Left";
+              value "action" string: "move";
+              value "params" string: "left";
+              group "modifiers" list {
+                 group "Elm_Config_Binding_Modifier" struct {
+                    value "mod" string: "Shift";
+                    value "flag" uchar: 0;
+                 }
+              }
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "Left";
+              value "action" string: "move";
+              value "params" string: "left_multi";
+              group "modifiers" list {
+                 group "Elm_Config_Binding_Modifier" struct {
+                    value "mod" string: "Shift";
+                    value "flag" uchar: 1;
+                 }
+              }
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "KP_Left";
+              value "action" string: "move";
+              value "params" string: "left";
+              group "modifiers" list {
+                 group "Elm_Config_Binding_Modifier" struct {
+                    value "mod" string: "Shift";
+                    value "flag" uchar: 0;
+                 }
+              }
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "KP_Left";
+              value "action" string: "move";
+              value "params" string: "left_multi";
+              group "modifiers" list {
+                 group "Elm_Config_Binding_Modifier" struct {
+                    value "mod" string: "Shift";
+                    value "flag" uchar: 1;
+                 }
+              }
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "Right";
+              value "action" string: "move";
+              value "params" string: "right";
+              group "modifiers" list {
+                 group "Elm_Config_Binding_Modifier" struct {
+                    value "mod" string: "Shift";
+                    value "flag" uchar: 0;
+                 }
+              }
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "Right";
+              value "action" string: "move";
+              value "params" string: "right_multi";
+              group "modifiers" list {
+                 group "Elm_Config_Binding_Modifier" struct {
+                    value "mod" string: "Shift";
+                    value "flag" uchar: 1;
+                 }
+              }
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "KP_Right";
+              value "action" string: "move";
+              value "params" string: "right";
+              group "modifiers" list {
+                 group "Elm_Config_Binding_Modifier" struct {
+                    value "mod" string: "Shift";
+                    value "flag" uchar: 0;
+                 }
+              }
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "KP_Right";
+              value "action" string: "move";
+              value "params" string: "right_multi";
+              group "modifiers" list {
+                 group "Elm_Config_Binding_Modifier" struct {
+                    value "mod" string: "Shift";
+                    value "flag" uchar: 1;
+                 }
+              }
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "Up";
+              value "action" string: "move";
+              value "params" string: "up";
+              group "modifiers" list {
+                 group "Elm_Config_Binding_Modifier" struct {
+                    value "mod" string: "Shift";
+                    value "flag" uchar: 0;
+                 }
+              }
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "Up";
+              value "action" string: "move";
+              value "params" string: "up_multi";
+              group "modifiers" list {
+                 group "Elm_Config_Binding_Modifier" struct {
+                    value "mod" string: "Shift";
+                    value "flag" uchar: 1;
+                 }
+              }
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "KP_Up";
+              value "action" string: "move";
+              value "params" string: "up";
+              group "modifiers" list {
+                 group "Elm_Config_Binding_Modifier" struct {
+                    value "mod" string: "Shift";
+                    value "flag" uchar: 0;
+                 }
+              }
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "KP_Up";
+              value "action" string: "move";
+              value "params" string: "up_multi";
+              group "modifiers" list {
+                 group "Elm_Config_Binding_Modifier" struct {
+                    value "mod" string: "Shift";
+                    value "flag" uchar: 1;
+                 }
+              }
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "Down";
+              value "action" string: "move";
+              value "params" string: "down";
+              group "modifiers" list {
+                 group "Elm_Config_Binding_Modifier" struct {
+                    value "mod" string: "Shift";
+                    value "flag" uchar: 0;
+                 }
+              }
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "Down";
+              value "action" string: "move";
+              value "params" string: "down_multi";
+              group "modifiers" list {
+                 group "Elm_Config_Binding_Modifier" struct {
+                    value "mod" string: "Shift";
+                    value "flag" uchar: 1;
+                 }
+              }
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "KP_Down";
+              value "action" string: "move";
+              value "params" string: "down";
+              group "modifiers" list {
+                 group "Elm_Config_Binding_Modifier" struct {
+                    value "mod" string: "Shift";
+                    value "flag" uchar: 0;
+                 }
+              }
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "KP_Down";
+              value "action" string: "move";
+              value "params" string: "down_multi";
+              group "modifiers" list {
+                 group "Elm_Config_Binding_Modifier" struct {
+                    value "mod" string: "Shift";
+                    value "flag" uchar: 1;
+                 }
+              }
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "Prior";
+              value "action" string: "move";
+              value "params" string: "prior";
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "KP_Prior";
+              value "action" string: "move";
+              value "params" string: "prior";
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "Next";
+              value "action" string: "move";
+              value "params" string: "next";
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "KP_Next";
+              value "action" string: "move";
+              value "params" string: "next";
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "Home";
+              value "action" string: "move";
+              value "params" string: "first";
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "KP_Home";
+              value "action" string: "move";
+              value "params" string: "first";
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "End";
+              value "action" string: "move";
+              value "params" string: "last";
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "KP_End";
+              value "action" string: "move";
+              value "params" string: "last";
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "Return";
+              value "action" string: "select";
+              value "params" string: "";
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "KP_Enter";
+              value "action" string: "select";
+              value "params" string: "";
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "space";
+              value "action" string: "select";
+              value "params" string: "";
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "Escape";
+              value "action" string: "escape";
+              value "params" string: "";
+           }
+        }
+     }
   }
 }
diff --git a/config/mobile/base.src.in b/config/mobile/base.src.in
index 5f5b5dd63b..18d3612548 100644
--- a/config/mobile/base.src.in
+++ b/config/mobile/base.src.in
@@ -2789,5 +2789,274 @@ group "Elm_Config" struct {
            }
         }
      }
+     group "Elm_Config_Bindings_Widget" struct {
+        value "name" string: "Efl.Ui.List";
+        group "key_bindings" list {
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "Left";
+              value "action" string: "move";
+              value "params" string: "left";
+              group "modifiers" list {
+                 group "Elm_Config_Binding_Modifier" struct {
+                    value "mod" string: "Shift";
+                    value "flag" uchar: 0;
+                 }
+              }
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "Left";
+              value "action" string: "move";
+              value "params" string: "left_multi";
+              group "modifiers" list {
+                 group "Elm_Config_Binding_Modifier" struct {
+                    value "mod" string: "Shift";
+                    value "flag" uchar: 1;
+                 }
+              }
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "KP_Left";
+              value "action" string: "move";
+              value "params" string: "left";
+              group "modifiers" list {
+                 group "Elm_Config_Binding_Modifier" struct {
+                    value "mod" string: "Shift";
+                    value "flag" uchar: 0;
+                 }
+              }
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "KP_Left";
+              value "action" string: "move";
+              value "params" string: "left_multi";
+              group "modifiers" list {
+                 group "Elm_Config_Binding_Modifier" struct {
+                    value "mod" string: "Shift";
+                    value "flag" uchar: 1;
+                 }
+              }
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "Right";
+              value "action" string: "move";
+              value "params" string: "right";
+              group "modifiers" list {
+                 group "Elm_Config_Binding_Modifier" struct {
+                    value "mod" string: "Shift";
+                    value "flag" uchar: 0;
+                 }
+              }
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "Right";
+              value "action" string: "move";
+              value "params" string: "right_multi";
+              group "modifiers" list {
+                 group "Elm_Config_Binding_Modifier" struct {
+                    value "mod" string: "Shift";
+                    value "flag" uchar: 1;
+                 }
+              }
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "KP_Right";
+              value "action" string: "move";
+              value "params" string: "right";
+              group "modifiers" list {
+                 group "Elm_Config_Binding_Modifier" struct {
+                    value "mod" string: "Shift";
+                    value "flag" uchar: 0;
+                 }
+              }
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "KP_Right";
+              value "action" string: "move";
+              value "params" string: "right_multi";
+              group "modifiers" list {
+                 group "Elm_Config_Binding_Modifier" struct {
+                    value "mod" string: "Shift";
+                    value "flag" uchar: 1;
+                 }
+              }
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "Up";
+              value "action" string: "move";
+              value "params" string: "up";
+              group "modifiers" list {
+                 group "Elm_Config_Binding_Modifier" struct {
+                    value "mod" string: "Shift";
+                    value "flag" uchar: 0;
+                 }
+              }
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "Up";
+              value "action" string: "move";
+              value "params" string: "up_multi";
+              group "modifiers" list {
+                 group "Elm_Config_Binding_Modifier" struct {
+                    value "mod" string: "Shift";
+                    value "flag" uchar: 1;
+                 }
+              }
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "KP_Up";
+              value "action" string: "move";
+              value "params" string: "up";
+              group "modifiers" list {
+                 group "Elm_Config_Binding_Modifier" struct {
+                    value "mod" string: "Shift";
+                    value "flag" uchar: 0;
+                 }
+              }
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "KP_Up";
+              value "action" string: "move";
+              value "params" string: "up_multi";
+              group "modifiers" list {
+                 group "Elm_Config_Binding_Modifier" struct {
+                    value "mod" string: "Shift";
+                    value "flag" uchar: 1;
+                 }
+              }
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "Down";
+              value "action" string: "move";
+              value "params" string: "down";
+              group "modifiers" list {
+                 group "Elm_Config_Binding_Modifier" struct {
+                    value "mod" string: "Shift";
+                    value "flag" uchar: 0;
+                 }
+              }
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "Down";
+              value "action" string: "move";
+              value "params" string: "down_multi";
+              group "modifiers" list {
+                 group "Elm_Config_Binding_Modifier" struct {
+                    value "mod" string: "Shift";
+                    value "flag" uchar: 1;
+                 }
+              }
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "KP_Down";
+              value "action" string: "move";
+              value "params" string: "down";
+              group "modifiers" list {
+                 group "Elm_Config_Binding_Modifier" struct {
+                    value "mod" string: "Shift";
+                    value "flag" uchar: 0;
+                 }
+              }
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "KP_Down";
+              value "action" string: "move";
+              value "params" string: "down_multi";
+              group "modifiers" list {
+                 group "Elm_Config_Binding_Modifier" struct {
+                    value "mod" string: "Shift";
+                    value "flag" uchar: 1;
+                 }
+              }
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "Prior";
+              value "action" string: "move";
+              value "params" string: "prior";
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "KP_Prior";
+              value "action" string: "move";
+              value "params" string: "prior";
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "Next";
+              value "action" string: "move";
+              value "params" string: "next";
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "KP_Next";
+              value "action" string: "move";
+              value "params" string: "next";
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "Home";
+              value "action" string: "move";
+              value "params" string: "first";
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "KP_Home";
+              value "action" string: "move";
+              value "params" string: "first";
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "End";
+              value "action" string: "move";
+              value "params" string: "last";
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "KP_End";
+              value "action" string: "move";
+              value "params" string: "last";
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "Return";
+              value "action" string: "select";
+              value "params" string: "";
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "KP_Enter";
+              value "action" string: "select";
+              value "params" string: "";
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "space";
+              value "action" string: "select";
+              value "params" string: "";
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "Escape";
+              value "action" string: "escape";
+              value "params" string: "";
+           }
+        }
+     }
   }
 }
diff --git a/config/standard/base.src.in b/config/standard/base.src.in
index 13497910ae..9781512539 100644
--- a/config/standard/base.src.in
+++ b/config/standard/base.src.in
@@ -2786,5 +2786,274 @@ group "Elm_Config" struct {
            }
         }
      }
+     group "Elm_Config_Bindings_Widget" struct {
+        value "name" string: "Efl.Ui.List";
+        group "key_bindings" list {
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "Left";
+              value "action" string: "move";
+              value "params" string: "left";
+              group "modifiers" list {
+                 group "Elm_Config_Binding_Modifier" struct {
+                    value "mod" string: "Shift";
+                    value "flag" uchar: 0;
+                 }
+              }
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "Left";
+              value "action" string: "move";
+              value "params" string: "left_multi";
+              group "modifiers" list {
+                 group "Elm_Config_Binding_Modifier" struct {
+                    value "mod" string: "Shift";
+                    value "flag" uchar: 1;
+                 }
+              }
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "KP_Left";
+              value "action" string: "move";
+              value "params" string: "left";
+              group "modifiers" list {
+                 group "Elm_Config_Binding_Modifier" struct {
+                    value "mod" string: "Shift";
+                    value "flag" uchar: 0;
+                 }
+              }
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "KP_Left";
+              value "action" string: "move";
+              value "params" string: "left_multi";
+              group "modifiers" list {
+                 group "Elm_Config_Binding_Modifier" struct {
+                    value "mod" string: "Shift";
+                    value "flag" uchar: 1;
+                 }
+              }
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "Right";
+              value "action" string: "move";
+              value "params" string: "right";
+              group "modifiers" list {
+                 group "Elm_Config_Binding_Modifier" struct {
+                    value "mod" string: "Shift";
+                    value "flag" uchar: 0;
+                 }
+              }
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "Right";
+              value "action" string: "move";
+              value "params" string: "right_multi";
+              group "modifiers" list {
+                 group "Elm_Config_Binding_Modifier" struct {
+                    value "mod" string: "Shift";
+                    value "flag" uchar: 1;
+                 }
+              }
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "KP_Right";
+              value "action" string: "move";
+              value "params" string: "right";
+              group "modifiers" list {
+                 group "Elm_Config_Binding_Modifier" struct {
+                    value "mod" string: "Shift";
+                    value "flag" uchar: 0;
+                 }
+              }
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "KP_Right";
+              value "action" string: "move";
+              value "params" string: "right_multi";
+              group "modifiers" list {
+                 group "Elm_Config_Binding_Modifier" struct {
+                    value "mod" string: "Shift";
+                    value "flag" uchar: 1;
+                 }
+              }
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "Up";
+              value "action" string: "move";
+              value "params" string: "up";
+              group "modifiers" list {
+                 group "Elm_Config_Binding_Modifier" struct {
+                    value "mod" string: "Shift";
+                    value "flag" uchar: 0;
+                 }
+              }
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "Up";
+              value "action" string: "move";
+              value "params" string: "up_multi";
+              group "modifiers" list {
+                 group "Elm_Config_Binding_Modifier" struct {
+                    value "mod" string: "Shift";
+                    value "flag" uchar: 1;
+                 }
+              }
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "KP_Up";
+              value "action" string: "move";
+              value "params" string: "up";
+              group "modifiers" list {
+                 group "Elm_Config_Binding_Modifier" struct {
+                    value "mod" string: "Shift";
+                    value "flag" uchar: 0;
+                 }
+              }
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "KP_Up";
+              value "action" string: "move";
+              value "params" string: "up_multi";
+              group "modifiers" list {
+                 group "Elm_Config_Binding_Modifier" struct {
+                    value "mod" string: "Shift";
+                    value "flag" uchar: 1;
+                 }
+              }
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "Down";
+              value "action" string: "move";
+              value "params" string: "down";
+              group "modifiers" list {
+                 group "Elm_Config_Binding_Modifier" struct {
+                    value "mod" string: "Shift";
+                    value "flag" uchar: 0;
+                 }
+              }
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "Down";
+              value "action" string: "move";
+              value "params" string: "down_multi";
+              group "modifiers" list {
+                 group "Elm_Config_Binding_Modifier" struct {
+                    value "mod" string: "Shift";
+                    value "flag" uchar: 1;
+                 }
+              }
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "KP_Down";
+              value "action" string: "move";
+              value "params" string: "down";
+              group "modifiers" list {
+                 group "Elm_Config_Binding_Modifier" struct {
+                    value "mod" string: "Shift";
+                    value "flag" uchar: 0;
+                 }
+              }
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "KP_Down";
+              value "action" string: "move";
+              value "params" string: "down_multi";
+              group "modifiers" list {
+                 group "Elm_Config_Binding_Modifier" struct {
+                    value "mod" string: "Shift";
+                    value "flag" uchar: 1;
+                 }
+              }
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "Prior";
+              value "action" string: "move";
+              value "params" string: "prior";
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "KP_Prior";
+              value "action" string: "move";
+              value "params" string: "prior";
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "Next";
+              value "action" string: "move";
+              value "params" string: "next";
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "KP_Next";
+              value "action" string: "move";
+              value "params" string: "next";
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "Home";
+              value "action" string: "move";
+              value "params" string: "first";
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "KP_Home";
+              value "action" string: "move";
+              value "params" string: "first";
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "End";
+              value "action" string: "move";
+              value "params" string: "last";
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "KP_End";
+              value "action" string: "move";
+              value "params" string: "last";
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "Return";
+              value "action" string: "select";
+              value "params" string: "";
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "KP_Enter";
+              value "action" string: "select";
+              value "params" string: "";
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "space";
+              value "action" string: "select";
+              value "params" string: "";
+           }
+           group "Elm_Config_Binding_Key" struct {
+              value "context" int: 0;
+              value "key" string: "Escape";
+              value "action" string: "escape";
+              value "params" string: "";
+           }
+        }
+     }
   }
 }
diff --git a/data/elementary/themes/Makefile.am 
b/data/elementary/themes/Makefile.am
index 40ff6973c8..74ba32fa63 100644
--- a/data/elementary/themes/Makefile.am
+++ b/data/elementary/themes/Makefile.am
@@ -1037,6 +1037,7 @@ elementary/themes/edc/efl/text.edc \
 elementary/themes/edc/efl/textpath.edc \
 elementary/themes/edc/efl/tooltip.edc \
 elementary/themes/edc/efl/video.edc \
+elementary/themes/edc/efl/list.edc \
 elementary/themes/edc/efl/win.edc
 
 elementary_fdo_actions_128_files = \
diff --git a/data/elementary/themes/default.edc 
b/data/elementary/themes/default.edc
index 119f42eeba..0b43454863 100644
--- a/data/elementary/themes/default.edc
+++ b/data/elementary/themes/default.edc
@@ -168,6 +168,7 @@ collections {
 #include "edc/efl/button.edc"
 #include "edc/efl/calendar.edc"
 #include "edc/efl/nstate.edc"
+#include "edc/efl/list.edc"
 // XXX: mobile mode needs invisible scrollers... make signals that do this
 #include "edc/efl/scroller.edc"
 // XXX: mobile mode needs different entry setup
diff --git a/data/elementary/themes/edc/efl/list.edc 
b/data/elementary/themes/edc/efl/list.edc
new file mode 100644
index 0000000000..2707924020
--- /dev/null
+++ b/data/elementary/themes/edc/efl/list.edc
@@ -0,0 +1,8 @@
+group { "efl/list";
+   inherit: "elm/list/base/default";
+}
+
+group { "efl/list/item";
+   inherit: "elm/list/item/default";
+}
+
diff --git a/src/Makefile_Elementary.am b/src/Makefile_Elementary.am
index 4c78215646..17b689f07c 100644
--- a/src/Makefile_Elementary.am
+++ b/src/Makefile_Elementary.am
@@ -210,11 +210,18 @@ elm_legacy_eolian_files = \
        lib/elementary/elm_slideshow_item.eo \
        lib/elementary/elm_table.eo \
        lib/elementary/elm_thumb.eo \
+       lib/elementary/efl_ui_list.eo \
+       lib/elementary/efl_ui_list_pan.eo \
+       lib/elementary/efl_ui_list_model.eo \
+       lib/elementary/efl_ui_list_relayout.eo \
+       lib/elementary/efl_ui_list_precise_layouter.eo \
+       lib/elementary/efl_ui_layout_factory.eo \
        $(NULL)
 
 elm_eolian_type_files = \
        lib/elementary/elm_general.eot \
-       lib/elementary/efl_ui.eot
+       lib/elementary/efl_ui.eot \
+       lib/elementary/efl_ui_list_types.eot
 
 elm_public_eolian_c = $(elm_public_eolian_files:%.eo=%.eo.c)
 elm_public_eolian_h = $(elm_public_eolian_files:%.eo=%.eo.h) \
@@ -333,6 +340,8 @@ includesunstable_HEADERS = \
        lib/elementary/elm_widget_thumb.h \
        lib/elementary/elm_widget_toolbar.h \
        lib/elementary/efl_ui_video_private.h \
+       lib/elementary/efl_ui_list_private.h \
+       lib/elementary/efl_ui_list_segarray.h \
        lib/elementary/elm_widget_web.h \
        lib/elementary/efl_ui_clock.h \
        lib/elementary/elm_code.h \
@@ -733,6 +742,10 @@ lib_elementary_libelementary_la_SOURCES = \
        lib/elementary/efl_ui_focus_parent_provider_gen.c \
        lib/elementary/efl_ui_focus_util.c \
        lib/elementary/elm_widget_item_static_focus.c \
+       lib/elementary/efl_ui_list.c \
+       lib/elementary/efl_ui_list_precise_layouter.c \
+       lib/elementary/efl_ui_list_segarray.c \
+       lib/elementary/efl_ui_layout_factory.c \
        $(NULL)
 
 
diff --git a/src/examples/elementary/Makefile.am 
b/src/examples/elementary/Makefile.am
index d1a3767d85..879a38f824 100644
--- a/src/examples/elementary/Makefile.am
+++ b/src/examples/elementary/Makefile.am
@@ -176,7 +176,14 @@ efl_thread_2.c \
 efl_thread_3.c \
 efl_thread_4.c \
 efl_thread_5.c \
-efl_thread_6.c
+efl_thread_6.c \
+efl_thread_win32_1.c \
+efl_thread_win32_2.c \
+efl_thread_win32_3.c \
+efl_thread_win32_4.c \
+efl_ui_list_example_1.c \
+efl_ui_list_example_2.c \
+efl_ui_list_example_3.c
 
 if HAVE_CXX11
 SRCS += \
@@ -208,7 +215,8 @@ twitter_example_01.edc \
 evas3d_map_example.edc \
 theme_example.edc \
 layout_example.edc \
-codegen_example.edc
+codegen_example.edc \
+efl_ui_list_example.edc
 
 EDJS = $(EDCS:%.edc=%.edj)
 
@@ -230,13 +238,15 @@ files_DATA += \
        layout_example.edj\
        codegen_example.edj \
        evas3d_map_example.edj \
-       twitter_example_01.edj
+       twitter_example_01.edj \
+       efl_ui_list_example.edj
 
 CLEANFILES = \
        theme_example.edj \
        layout_example.edj\
        evas3d_map_example.edj \
-       twitter_example_01.edj
+       twitter_example_01.edj \
+       efl_ui_list_example.edj
 
 clean-local:
        rm -f *.epb *.cfg *.cfg.bkp
@@ -382,7 +392,10 @@ efl_thread_2 \
 efl_thread_3 \
 efl_thread_4 \
 efl_thread_5 \
-efl_thread_6
+efl_thread_6 \
+efl_ui_list_example_1 \
+efl_ui_list_example_2 \
+efl_ui_list_example_3
 #benchmark3d
 #sphere-hunter
 
@@ -594,7 +607,7 @@ screenshots: examples
                convert $(HTML_SS_DIR)/$${SS_FILE} 
$(LATEX_SS_DIR)/$${SS_FILE/.png/.eps} ; \
        done
 
-EXTRA_DIST = dict.txt layout_example.edc theme_example.edc codegen_example.edc 
evas3d_map_example.edc twitter_example_01.edc performance/layout.edc 
performance/background.png performance/target_texture.png 
sphere_hunter/sphere_hunter.edc sphere_hunter/score.jpg 
sphere_hunter/EFL_victory.png sphere_hunter/EFL_defeat.png 
codegen_example_generated.c codegen_example_generated.h codegen_example.edj 
prefs_example_01.epc prefs_example_02.epc prefs_example_03.epc 
prefs_example_03.edc
+EXTRA_DIST = dict.txt layout_example.edc theme_example.edc codegen_example.edc 
evas3d_map_example.edc twitter_example_01.edc efl_ui_list_example.edc 
performance/layout.edc performance/background.png 
performance/target_texture.png sphere_hunter/sphere_hunter.edc 
sphere_hunter/score.jpg sphere_hunter/EFL_victory.png 
sphere_hunter/EFL_defeat.png codegen_example_generated.c 
codegen_example_generated.h codegen_example.edj prefs_example_01.epc 
prefs_example_02.epc prefs_example_03.epc prefs_ex [...]
 
 
 examples: $(examples_PROGRAMS) $(EDJS)
diff --git a/src/examples/elementary/efl_ui_list_example.edc 
b/src/examples/elementary/efl_ui_list_example.edc
new file mode 100644
index 0000000000..3b46863b71
--- /dev/null
+++ b/src/examples/elementary/efl_ui_list_example.edc
@@ -0,0 +1,280 @@
+
+#define FN_COL_DEFAULT 255 255 255 255; color3: 0 0 0 128
+#define FN_COL_DISABLE 21 21 21 255; color3: 255 255 255 25;
+#define FN_COL_HIGHLIGHT 51 153 255 255; color2: 51 153 255 24; color3: 51 153 
255 18
+#define FIXED_SIZE(_WIDTH, _HEIGHT) \
+   min: _WIDTH _HEIGHT; max: _WIDTH _HEIGHT; fixed: 1 1;
+
+
+collections {
+
+group {
+   name: "elm/list/item/custom";
+   alias: "elm/list/item/default";
+   data.item: "selectraise" "on";
+   data.item: "focusraise" "on";
+   parts {
+      part { name: "event"; type: RECT;
+         description { state: "default" 0.0;
+            color: 0 0 0 0;
+         }
+         description { state: "disabled" 0.0;
+            inherit: "default" 0.0;
+            visible: 0;
+         }
+      }
+      part { name: "base"; type: RECT; mouse_events: 0;
+         description { state: "default" 0.0;
+            color: 46 46 56 255;
+            color_class: "list_item_base_odd";
+         }
+         description { state: "odd" 0.0;
+            color: 56 56 56 255;
+            color_class: "list_item_base_odd";
+         }
+      }
+      program {
+         signal: "elm,state,odd"; source: "elm";
+         action: STATE_SET "odd" 1.0;
+         target: "base";
+      }
+      program {
+         signal: "elm,state,even"; source: "elm";
+         action: STATE_SET "default" 0.0;
+         target: "base";
+      }
+      part { name: "sel_shadow"; mouse_events: 0;
+         description { state: "default" 0.0;
+            visible: 0;
+         }
+         description { state: "selected" 0.0;
+            inherit: "default" 0.0;
+            visible: 1;
+         }
+      }
+      part { name: "sel_base"; mouse_events: 0;
+         description { state: "default" 0.0;
+            fill.smooth: 0;
+            visible: 0;
+            fill { size { relative: 0.0 1.0; offset: 120 0; } }
+         }
+         description { state: "selected" 0.0;
+            inherit: "default" 0.0;
+            visible: 1;
+         }
+      }
+      part { name: "sel_bevel"; mouse_events: 0;
+         description { state: "default" 0.0;
+            fill.smooth: 0;
+            visible: 0;
+         }
+         description { state: "selected" 0.0;
+            inherit: "default" 0.0;
+            visible: 1;
+         }
+      }
+      program {
+         signal: "elm,state,selected"; source: "elm";
+         action: STATE_SET "selected" 0.0;
+         target: "sel_shadow";
+         target: "sel_base";
+         target: "sel_bevel";
+      }
+      program {
+         signal: "elm,state,unselected"; source: "elm";
+         action: STATE_SET "default" 0.0;
+         target: "sel_shadow";
+         target: "sel_base";
+         target: "sel_bevel";
+      }
+      program {
+         signal: "elm,state,disabled"; source: "elm";
+         action: STATE_SET "disabled" 0.0;
+         target: "event";
+      }
+      program {
+         signal: "elm,state,enabled"; source: "elm";
+         action: STATE_SET "default" 0.0;
+         target: "event";
+      }
+
+      //##//
+      part { name: "elm.text"; type: TEXT; mouse_events: 0;
+         effect: SHADOW BOTTOM;
+         scale: 1;
+         description { state: "default" 0.0;
+            rel1.offset: 2 3;
+            rel1.relative: 1.0 0.0;
+            rel1.to_x: "elm.swallow.icon";
+            rel2.offset: -3 -3;
+            rel2.relative: 0.0 1.0;
+            rel2.to_x: "elm.swallow.end";
+            color: FN_COL_DEFAULT;
+            color_class: "list_item";
+            text { font: FN; size: 10;
+               min: 1 1;
+               ellipsis: -1;
+               align: 0.0 0.5;
+               text_class: "list_item";
+            }
+         }
+         description { state: "selected" 0.0;
+            inherit: "default" 0.0;
+            visible: 0;
+         }
+         description { state: "disabled" 0.0;
+            inherit: "default" 0.0;
+            visible: 0;
+         }
+      }
+      part { name: "label2"; type: TEXT; mouse_events: 0;
+         effect: SHADOW BOTTOM;
+         scale: 1;
+         description { state: "default" 0.0;
+            rel1.to: "elm.text";
+            rel2.to: "elm.text";
+            color: FN_COL_DISABLE;
+            color_class: "list_item_disabled";
+            text { font: FN; size: 10;
+               text_source: "elm.text";
+               align: 0.0 0.5;
+               text_class: "list_item";
+            }
+            visible: 0;
+         }
+         description { state: "selected" 0.0;
+            inherit: "default" 0.0;
+            visible: 0;
+         }
+         description { state: "disabled" 0.0;
+            inherit: "default" 0.0;
+            visible: 1;
+         }
+      }
+      part { name: "label3"; type: TEXT; mouse_events: 0;
+         effect: GLOW;
+         scale: 1;
+         description { state: "default" 0.0;
+            rel1.offset: -2 -3;
+            rel1.to: "elm.text";
+            rel2.offset: 1 1;
+            rel2.to: "elm.text";
+            color: FN_COL_HIGHLIGHT;
+            color_class: "list_item_selected";
+            text { font: FN; size: 10;
+               text_source: "elm.text";
+               align: 0.0 0.5;
+               text_class: "list_item";
+            }
+            visible: 0;
+         }
+         description { state: "selected" 0.0;
+            inherit: "default" 0.0;
+            visible: 1;
+         }
+         description { state: "disabled" 0.0;
+            inherit: "default" 0.0;
+            visible: 0;
+         }
+      }
+      program {
+         signal: "elm,state,selected"; source: "elm";
+         action: STATE_SET "selected" 0.0;
+         target: "elm.text";
+         target: "label2";
+         target: "label3";
+      }
+      program {
+         signal: "elm,state,unselected"; source: "elm";
+         action: STATE_SET "default" 0.0;
+         target: "elm.text";
+         target: "label2";
+         target: "label3";
+      }
+      program {
+         signal: "elm,state,disabled"; source: "elm";
+         action: STATE_SET "disabled" 0.0;
+         target: "elm.text";
+         target: "label2";
+         target: "label3";
+      }
+      program {
+         signal: "elm,state,enabled"; source: "elm";
+         action: STATE_SET "default" 0.0;
+         target: "elm.text";
+         target: "label2";
+         target: "label3";
+      }
+      //##//
+      part { name: "elm.swallow.icon"; type: SWALLOW;
+         description { state: "default" 0.0;
+            fixed: 1 0;
+            align: 0.0 0.5;
+            aspect: 1.0 1.0;
+            rel1.offset: 2 2;
+            rel2.relative: 0.0 1.0;
+            rel2.offset: 2 -3;
+         }
+      }
+      part { name: "elm.swallow.end"; type: SWALLOW;
+         description { state: "default" 0.0;
+            fixed: 1 0;
+            align: 1.0 0.5;
+            aspect: 1.0 1.0;
+            rel1.offset: -3 2;
+            rel1.relative: 1.0 0.0;
+            rel2.offset: -3 -3;
+         }
+      }
+      //##//
+
+      part { name: "sel_shine"; mouse_events: 0;
+         description { state: "default" 0.0;
+            rel1.offset: 0 -2;
+            rel1.to: "sel_base";
+            rel2.relative: 1.0 0.0;
+            rel2.offset: -1 2;
+            rel2.to: "sel_base";
+            visible: 0;
+            FIXED_SIZE(69, 5)
+         }
+         description { state: "selected" 0.0;
+            inherit: "default" 0.0;
+            visible: 1;
+         }
+      }
+      part { name: "event_block"; type: RECT;
+         description { state: "default" 0.0;
+            color: 0 0 0 0;
+            visible: 0;
+         }
+         description { state: "disabled" 0.0;
+            inherit: "default" 0.0;
+            visible: 1;
+         }
+      }
+      program {
+         signal: "elm,state,selected"; source: "elm";
+         action: STATE_SET "selected" 0.0;
+         target: "sel_shine";
+      }
+      program {
+         signal: "elm,state,unselected"; source: "elm";
+         action: STATE_SET "default" 0.0;
+         target: "sel_shine";
+      }
+      program {
+         signal: "elm,state,disabled"; source: "elm";
+         action: STATE_SET "disabled" 0.0;
+         target: "event_block";
+      }
+      program {
+         signal: "elm,state,enabled"; source: "elm";
+         action: STATE_SET "default" 0.0;
+         target: "event_block";
+      }
+   }
+}
+
+}
+
diff --git a/src/examples/elementary/efl_ui_list_example_1.c 
b/src/examples/elementary/efl_ui_list_example_1.c
new file mode 100644
index 0000000000..488dca0dfb
--- /dev/null
+++ b/src/examples/elementary/efl_ui_list_example_1.c
@@ -0,0 +1,111 @@
+// gcc -o efl_ui_list_example_1 efl_ui_list_example_1.c `pkg-config --cflags 
--libs elementary`
+
+#ifdef HAVE_CONFIG_H
+# include "elementary_config.h"
+#else
+# define EFL_BETA_API_SUPPORT 1
+# define EFL_EO_API_SUPPORT 1
+#endif
+
+#include <Elementary.h>
+#include <Efl.h>
+#include <Eio.h>
+#include <stdio.h>
+
+#define NUM_ITEMS 400
+
+const char *styles[] = {
+        "odd",
+        "even"
+   };
+
+char edj_path[PATH_MAX];
+
+static void
+_realized_cb(void *data, const Efl_Event *event)
+{
+   Efl_Ui_List_Item_Event *ie = event->info;
+   if (!ie->layout) return;
+
+   Efl_Ui_Layout *layout = ie->layout;
+   elm_object_focus_allow_set(layout, EINA_TRUE);
+}
+
+/*
+static void
+_unrealized_cb(void *data EINA_UNUSED, const Efl_Event *event)
+{
+   Efl_Ui_List_Item_Event *ie = event->info;
+
+   efl_ui_view_model_set(ie->layout, NULL);
+   efl_del(ie->layout);
+}
+*/
+static Efl_Model*
+_make_model()
+{
+   Eina_Value vtext, vstyle;
+   Efl_Model_Item *model, *child;
+   unsigned int i, s;
+   char buf[256];
+
+   model = efl_add(EFL_MODEL_ITEM_CLASS, NULL);
+   eina_value_setup(&vtext, EINA_VALUE_TYPE_STRING);
+
+   for (i = 0; i < (NUM_ITEMS); i++)
+     {
+        s = i%2;
+        child = efl_model_child_add(model);
+        eina_value_set(&vtext, styles[s]);
+        efl_model_property_set(child, "odd_style", &vtext);
+
+        snprintf(buf, sizeof(buf), "Item # %i", i);
+        eina_value_set(&vtext, buf);
+        efl_model_property_set(child, "name", &vtext);
+     }
+
+   eina_value_flush(&vtext);
+   return model;
+}
+
+EAPI_MAIN int
+elm_main(int argc, char **argv)
+{
+   Efl_Ui_Layout_Factory *factory;
+   Evas_Object *win, *li, *bx, *vbx;
+   Eo *model;
+
+   win = elm_win_util_standard_add("viewlist", "Viewlist");
+   elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED);
+
+   elm_win_autodel_set(win, EINA_TRUE);
+
+   model = _make_model();
+
+   factory = efl_add(EFL_UI_LAYOUT_FACTORY_CLASS, win);
+   efl_ui_model_connect(factory, "signal/elm,state,%v", "odd_style");
+   efl_ui_model_connect(factory, "elm.text", "name");
+   efl_ui_layout_factory_theme_config(factory, "list", "item", "default");
+
+   li = efl_add(EFL_UI_LIST_CLASS, win);
+   efl_ui_list_layout_factory_set(li, factory);
+   efl_ui_view_model_set(li, model);
+   elm_box_pack_end(bx, li);
+
+   efl_event_callback_add(li, EFL_UI_LIST_EVENT_ITEM_REALIZED, _realized_cb, 
NULL);
+//   efl_event_callback_add(li, EFL_UI_LIST_EVENT_ITEM_UNREALIZED, 
_unrealized_cb, NULL);
+
+   elm_win_resize_object_add(win, li);
+   evas_object_size_hint_weight_set(li, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(li, EVAS_HINT_FILL, EVAS_HINT_FILL);
+
+   //showall
+   evas_object_show(li);
+   evas_object_resize(win, 320, 320);
+   evas_object_show(win);
+
+   elm_run();
+
+   return 0;
+}
+ELM_MAIN()
diff --git a/src/examples/elementary/efl_ui_list_example_2.c 
b/src/examples/elementary/efl_ui_list_example_2.c
new file mode 100644
index 0000000000..9f37e322e5
--- /dev/null
+++ b/src/examples/elementary/efl_ui_list_example_2.c
@@ -0,0 +1,74 @@
+// gcc -o efl_ui_list_example_2 efl_ui_list_example_2.c `pkg-config --cflags 
--libs elementary`
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#else
+# define EFL_BETA_API_SUPPORT 1
+# define EFL_EO_API_SUPPORT 1
+#endif
+
+#include <Elementary.h>
+#include <Efl.h>
+#include <Eio.h>
+#include <stdio.h>
+
+#define EFL_MODEL_TEST_FILENAME_PATH "/tmp"
+
+static void
+_realized_cb(void *data, const Efl_Event *event)
+{
+   Efl_Ui_List_Item_Event *ie = event->info;
+   Eo *imf = data;
+   printf("realize %d\n", ie->index);
+
+   evas_object_size_hint_weight_set(ie->layout, EVAS_HINT_EXPAND, 0);
+   evas_object_size_hint_align_set(ie->layout, EVAS_HINT_FILL, EVAS_HINT_FILL);
+
+   efl_ui_model_factory_connect(ie->layout, "elm.swallow.icon", imf);
+}
+
+EAPI_MAIN int
+elm_main(int argc, char **argv)
+{
+   Efl_Ui_Layout_Factory *factory;
+   Evas_Object *win;
+   Eo *imf, *model, *li;
+   char *dirname;
+
+   win = elm_win_util_standard_add("viewlist", "Viewlist");
+   elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED);
+
+   elm_win_autodel_set(win, EINA_TRUE);
+
+   if (argv[1] != NULL) dirname = argv[1];
+   else dirname = EFL_MODEL_TEST_FILENAME_PATH;
+
+   model = efl_add(EIO_MODEL_CLASS, NULL, eio_model_path_set(efl_added, 
dirname));
+   factory = efl_add(EFL_UI_LAYOUT_FACTORY_CLASS, win);
+   efl_ui_model_connect(factory, "elm.text", "filename");
+   efl_ui_layout_factory_theme_config(factory, "list", "item", "default");
+
+   li = efl_add(EFL_UI_LIST_CLASS, win);
+   efl_ui_list_layout_factory_set(li, factory);
+   efl_ui_view_model_set(li, model);
+
+   evas_object_size_hint_weight_set(li, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(li, EVAS_HINT_FILL, EVAS_HINT_FILL);
+
+
+   imf = efl_add(EFL_UI_IMAGE_FACTORY_CLASS, win);
+   efl_ui_model_connect(imf, "", "path"); //connect to "path" property
+   efl_event_callback_add(li, EFL_UI_LIST_EVENT_ITEM_REALIZED, _realized_cb, 
imf);
+
+   elm_win_resize_object_add(win, li);
+
+   //showall
+   evas_object_show(li);
+   evas_object_resize(win, 320, 320);
+   evas_object_show(win);
+
+   elm_run();
+
+   return 0;
+}
+ELM_MAIN()
diff --git a/src/examples/elementary/efl_ui_list_example_3.c 
b/src/examples/elementary/efl_ui_list_example_3.c
new file mode 100644
index 0000000000..3b35ec3528
--- /dev/null
+++ b/src/examples/elementary/efl_ui_list_example_3.c
@@ -0,0 +1,329 @@
+// gcc -o efl_ui_list_example_3 efl_ui_list_example_3.c `pkg-config --cflags 
--libs elementary`
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#else
+# define EFL_BETA_API_SUPPORT 1
+# define EFL_EO_API_SUPPORT 1
+#endif
+
+#define ELM_INTERFACE_ATSPI_SELECTION_PROTECTED
+
+#include <Eo.h>
+#include <Elementary.h>
+#include <Efl.h>
+#include <Eio.h>
+#include <stdio.h>
+
+const char *subtexts[] = {
+        "Captain",
+        "Princess ",
+        "Actor",
+        "Translator",
+        "Jedi",
+        "Singer",
+        "Fighter"
+   };
+
+const char *texts[] = {
+        "Morpheus",
+        "Leia",
+        "Chuck Norris",
+        "Nyota Uhura",
+        "Darth Vader",
+        "Elvis Presley",
+        "Chun-Li"
+   };
+
+char edj_path[PATH_MAX];
+
+struct _Priv_Data
+{
+   Eo *model;
+   Evas_Object *list1;
+   Evas_Object *list2;
+   Evas_Object *e_name;
+   Evas_Object *e_occ;
+   Evas_Object *selected;
+};
+typedef struct _Priv_Data Priv_Data;
+
+static void
+_cleanup_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, 
void *event_info EINA_UNUSED)
+{
+   Priv_Data *priv = (Priv_Data*)data;
+   efl_unref(priv->model);
+}
+
+static void
+_focused(void *data, const Efl_Event *event)
+{
+   Priv_Data *priv = (Priv_Data*)data;
+   priv->selected = efl_ui_focus_manager_focus_get(event->object);
+}
+
+static void
+_bt_add_clicked(void *data, Evas_Object *obj, void *event_info)
+{
+   Priv_Data *priv = (Priv_Data*)data;
+   Eina_Value vtext, value;
+   Efl_Model_Item *child;
+
+   eina_value_setup(&vtext, EINA_VALUE_TYPE_STRING);
+   eina_value_setup(&value, EINA_VALUE_TYPE_UCHAR);
+   child = efl_model_child_add(priv->model);
+
+   eina_value_set(&vtext, elm_object_text_get(priv->e_name));
+   efl_model_property_set(child, "name", &vtext);
+
+   eina_value_set(&vtext, elm_object_text_get(priv->e_occ));
+   efl_model_property_set(child, "occupation", &vtext);
+
+   eina_value_set(&value, EINA_FALSE);
+   efl_model_property_set(child, "selected", &vtext);
+
+   eina_value_flush(&vtext);
+   eina_value_flush(&value);
+}
+
+static void
+_bt_del_clicked(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
+{
+   Priv_Data *priv = (Priv_Data*)data;
+   Eo *child = NULL;
+
+   //l = efl_ui_focus_manager_focus_get(priv->list1);
+   if(priv->selected)
+     {
+        printf("focused %p\n", priv->selected);
+        child = efl_ui_view_model_get(priv->selected);
+        efl_model_child_del(priv->model, child);
+        priv->selected = NULL;
+     }
+   else
+     {
+        printf("no focused\n");
+     }
+}
+
+static void
+_bt_none_clicked(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
+{
+   Evas_Object *li = data;
+   efl_ui_list_select_mode_set(li, ELM_OBJECT_SELECT_MODE_NONE);
+}
+
+static void
+_bt_donly_clicked(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
+{
+   Evas_Object *li = data;
+   efl_ui_list_select_mode_set(li, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
+}
+
+static void
+_bt_default_clicked(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
+{
+   Evas_Object *li = data;
+   efl_ui_list_select_mode_set(li, ELM_OBJECT_SELECT_MODE_DEFAULT);
+}
+
+static void
+_bt_set_clicked(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
+{
+   Priv_Data *priv = data;
+   efl_ui_view_model_set(priv->list2, priv->model);
+}
+
+static void
+_bt_unset_clicked(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
+{
+   Evas_Object *li = data;
+   efl_ui_view_model_set(li, NULL);
+}
+static void
+_realized_1_cb(void *data EINA_UNUSED, const Efl_Event *event)
+{
+   Efl_Ui_List_Item_Event *ie = event->info;
+
+   evas_object_size_hint_weight_set(ie->layout, EVAS_HINT_EXPAND, 0);
+   evas_object_size_hint_align_set(ie->layout, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   efl_ui_model_connect(ie->layout, "elm.text", "name");
+   efl_ui_model_connect(ie->layout, "signal/elm,state,%v", "odd_style");
+}
+
+static void
+_realized_2_cb(void *data EINA_UNUSED, const Efl_Event *event)
+{
+   Efl_Ui_List_Item_Event *ie = event->info;
+   printf("relized 2\n");
+
+   elm_object_focus_allow_set(ie->layout, EINA_TRUE);
+   evas_object_size_hint_weight_set(ie->layout, EVAS_HINT_EXPAND, 0);
+   evas_object_size_hint_align_set(ie->layout, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   efl_ui_model_connect(ie->layout, "elm.text", "occupation");
+}
+
+static Efl_Model*
+_make_model()
+{
+   Eina_Value vtext, value;
+   Efl_Model_Item *model, *child;
+   unsigned int i, len;
+
+   model = efl_add(EFL_MODEL_ITEM_CLASS, NULL);
+   eina_value_setup(&vtext, EINA_VALUE_TYPE_STRING);
+   eina_value_setup(&value, EINA_VALUE_TYPE_UCHAR);
+
+   len = sizeof(texts)/sizeof(const char*);
+   for (i = 0; i < (len); i++)
+     {
+        child = efl_model_child_add(model);
+
+        i%2 ? eina_value_set(&vtext, "even") : eina_value_set(&vtext, "odd");
+        efl_model_property_set(child, "odd_style", &vtext);
+
+        eina_value_set(&vtext, texts[(i % len)]);
+        efl_model_property_set(child, "name", &vtext);
+
+        eina_value_set(&vtext, subtexts[(i % len)]);
+        efl_model_property_set(child, "occupation", &vtext);
+
+        eina_value_set(&value, EINA_FALSE);
+        efl_model_property_set(child, "selected", &value);
+     }
+
+   eina_value_flush(&vtext);
+   eina_value_flush(&value);
+   return model;
+}
+
+EAPI_MAIN int
+elm_main(int argc, char **argv)
+{
+   Priv_Data *priv;
+   Evas_Object *win, *bx, *vbx, *bt;
+   Efl_Ui_Layout_Factory *factory;
+
+   priv = alloca(sizeof(Priv_Data));
+   memset(priv, 0, sizeof(Priv_Data));
+
+   win = elm_win_util_standard_add("viewlist", "Viewlist");
+   elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED);
+   elm_win_autodel_set(win, EINA_TRUE);
+
+   bx = elm_box_add(win);
+   elm_box_horizontal_set(bx, EINA_TRUE);
+   evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_win_resize_object_add(win, bx);
+   evas_object_show(bx);
+
+   priv->model = _make_model();
+   factory = efl_add(EFL_UI_LAYOUT_FACTORY_CLASS, win);
+   efl_ui_model_connect(factory, "elm.text", "filename");
+   efl_ui_layout_factory_theme_config(factory, "list", "item", "default");
+
+   priv->list1 = efl_add(EFL_UI_LIST_CLASS, win, 
efl_ui_view_model_set(efl_added, priv->model));
+   efl_event_callback_add(priv->list1, EFL_UI_LIST_EVENT_ITEM_REALIZED, 
_realized_1_cb, priv);
+   evas_object_size_hint_weight_set(priv->list1, EVAS_HINT_EXPAND, 
EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(priv->list1, EVAS_HINT_FILL, 
EVAS_HINT_FILL);
+   elm_box_pack_end(bx, priv->list1);
+   efl_ui_list_layout_factory_set(priv->list1, factory);
+
+   factory = efl_add(EFL_UI_LAYOUT_FACTORY_CLASS, win);
+   efl_ui_model_connect(factory, "elm.text", "filename");
+   efl_ui_model_connect(factory, "signal/elm,state,%v", "selected");
+   efl_ui_layout_factory_theme_config(factory, "list", "item", "default");
+   priv->list2 = efl_add(EFL_UI_LIST_CLASS, win, 
efl_ui_view_model_set(efl_added, priv->model));
+   efl_event_callback_add(priv->list2, EFL_UI_LIST_EVENT_ITEM_REALIZED, 
_realized_2_cb, priv->list2);
+   evas_object_size_hint_weight_set(priv->list2, EVAS_HINT_EXPAND, 
EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(priv->list2, EVAS_HINT_FILL, 
EVAS_HINT_FILL);
+   efl_ui_list_layout_factory_set(priv->list2, factory);
+
+   vbx = elm_box_add(win);
+   elm_box_pack_end(bx, vbx);
+
+   bt = elm_label_add(win);
+   elm_object_text_set(bt, "Name:");
+   elm_box_pack_end(vbx, bt);
+   evas_object_show(bt);
+
+   priv->e_name = elm_entry_add(win);
+   elm_box_pack_end(vbx, priv->e_name);
+   elm_object_text_set(priv->e_name, "Neo");
+   evas_object_size_hint_weight_set(priv->e_name, EVAS_HINT_EXPAND, 
EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(priv->e_name, EVAS_HINT_FILL, 
EVAS_HINT_FILL);
+   evas_object_show(priv->e_name);
+
+   bt = elm_label_add(win);
+   elm_object_text_set(bt, "Occupation:");
+   elm_box_pack_end(vbx, bt);
+   evas_object_show(bt);
+
+   priv->e_occ = elm_entry_add(win);
+   elm_box_pack_end(vbx, priv->e_occ);
+   elm_object_text_set(priv->e_occ, "Chosen");
+   evas_object_size_hint_weight_set(priv->e_occ, EVAS_HINT_EXPAND, 
EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(priv->e_occ, EVAS_HINT_FILL, 
EVAS_HINT_FILL);
+   evas_object_show(priv->e_occ);
+
+   bt = elm_button_add(win);
+   elm_object_text_set(bt, "Add Item");
+   evas_object_smart_callback_add(bt, "clicked", _bt_add_clicked, priv);
+   evas_object_show(bt);
+   elm_box_pack_end(vbx, bt);
+
+   bt = elm_button_add(win);
+   elm_object_text_set(bt, "Delete Item");
+   evas_object_smart_callback_add(bt, "clicked", _bt_del_clicked, priv);
+   evas_object_show(bt);
+   elm_box_pack_end(vbx, bt);
+
+   bt = elm_button_add(win);
+   elm_object_text_set(bt, "Select None");
+   evas_object_smart_callback_add(bt, "clicked", _bt_none_clicked, 
priv->list2);
+   evas_object_show(bt);
+   elm_box_pack_end(vbx, bt);
+
+   bt = elm_button_add(win);
+   elm_object_text_set(bt, "Select DisplayOnly");
+   evas_object_smart_callback_add(bt, "clicked", _bt_donly_clicked, 
priv->list2);
+   evas_object_show(bt);
+   elm_box_pack_end(vbx, bt);
+
+   bt = elm_button_add(win);
+   elm_object_text_set(bt, "Select Default");
+   evas_object_smart_callback_add(bt, "clicked", _bt_default_clicked, 
priv->list2);
+   evas_object_show(bt);
+   elm_box_pack_end(vbx, bt);
+
+   bt = elm_button_add(win);
+   elm_object_text_set(bt, "Model Set");
+   evas_object_smart_callback_add(bt, "clicked", _bt_set_clicked, priv);
+   evas_object_show(bt);
+   elm_box_pack_end(vbx, bt);
+
+
+   bt = elm_button_add(win);
+   elm_object_text_set(bt, "Model Unset");
+   evas_object_smart_callback_add(bt, "clicked", _bt_unset_clicked, 
priv->list2);
+   evas_object_show(bt);
+   elm_box_pack_end(vbx, bt);
+
+   elm_box_pack_end(bx, priv->list2);
+   efl_event_callback_add(priv->list2, EFL_UI_FOCUS_MANAGER_EVENT_FOCUSED, 
_focused ,priv);
+
+   evas_object_event_callback_add(win, EVAS_CALLBACK_DEL, _cleanup_cb, priv);
+
+   //showall
+   evas_object_show(priv->list1);
+   evas_object_show(priv->list2);
+   evas_object_show(bx);
+   evas_object_show(vbx);
+   evas_object_resize(win, 400, 320);
+   evas_object_show(win);
+
+   elm_run();
+
+   return 0;
+}
+ELM_MAIN()
diff --git a/src/examples/elementary/layout_model_connect.c 
b/src/examples/elementary/layout_model_connect.c
index b856692246..aa34478f08 100644
--- a/src/examples/elementary/layout_model_connect.c
+++ b/src/examples/elementary/layout_model_connect.c
@@ -127,7 +127,6 @@ elm_main(int argc EINA_UNUSED, char **argv EINA_UNUSED)
    elm_object_part_content_set(panes, "right", bxr);
 
    /*Label widget */
-
     _label_init(win, bxr, "FILENAME:");
    priv->label = _label_init(win, bxr, "");
    efl_ui_model_connect(priv->label, "default", "path"); //connect "default" 
to "filename" property
diff --git a/src/lib/elementary/Elementary.h b/src/lib/elementary/Elementary.h
index 66b3c8fd14..c1422ae838 100644
--- a/src/lib/elementary/Elementary.h
+++ b/src/lib/elementary/Elementary.h
@@ -280,6 +280,7 @@ EAPI extern Elm_Version *elm_version;
 #include <elm_win.h>
 
 #ifdef EFL_EO_API_SUPPORT
+#include "efl_ui_list_segarray.h"
 # include <efl_config_global.eo.h>
 # include <efl_ui_widget_part.eo.h>
 # include <efl_ui_widget_part_bg.eo.h>
@@ -312,6 +313,13 @@ EAPI extern Elm_Version *elm_version;
 # include <efl_ui_spin.eo.h>
 # include <efl_ui_spin_button.eo.h>
 # include <efl_ui_image_factory.eo.h>
+# include <efl_ui_slider_interval.eo.h>
+# include <efl_ui_layout_factory.eo.h>
+# include <efl_ui_list_types.eot.h>
+# include <efl_ui_list_model.eo.h>
+# include <efl_ui_list_relayout.eo.h>
+# include <efl_ui_list.eo.h>
+# include <efl_ui_list_pan.eo.h>
 #endif
 
 /* include deprecated calls last of all */
diff --git a/src/lib/elementary/efl_ui_layout.c 
b/src/lib/elementary/efl_ui_layout.c
index 24fb83fd6c..5981fc1a54 100644
--- a/src/lib/elementary/efl_ui_layout.c
+++ b/src/lib/elementary/efl_ui_layout.c
@@ -1849,6 +1849,7 @@ _prop_future_then_cb(void* data, Efl_Event const*event)
    Efl_Ui_Layout_Sub_Connect *sc = data;
    const Eina_Value_Type *vtype;
    Eina_Value *value = (Eina_Value 
*)((Efl_Future_Event_Success*)event->info)->value;
+   Eina_Stringshare *selected;
    char *text;
 
    sc->future = NULL;
@@ -1858,6 +1859,18 @@ _prop_future_then_cb(void* data, Efl_Event const*event)
      {
          eina_value_get(value, &text);
          _view_update(sc, text);
+         return;
+     }
+
+   selected = eina_stringshare_add("selected");
+   if (vtype == EINA_VALUE_TYPE_UCHAR && sc->property == selected)
+     {
+         Eina_Bool sb = EINA_FALSE;
+         eina_value_get(value, &sb);
+         if (sb)
+           _view_update(sc, "selected");
+         else
+           _view_update(sc, "unselected");
      }
    else
      {
@@ -1865,6 +1878,8 @@ _prop_future_then_cb(void* data, Efl_Event const*event)
          _view_update(sc, text);
          free(text);
      }
+
+     eina_stringshare_del(selected);
 }
 
 static void
@@ -1904,6 +1919,7 @@ _efl_model_properties_changed_cb(void *data, const 
Efl_Event *event)
            {
               if (sc->property == ss_prop)
                 {
+                    if (sc->future) efl_future_cancel(sc->future);
                     sc->future = efl_model_property_get(pd->model, 
sc->property);
                     efl_future_then(sc->future, &_prop_future_then_cb, 
&_prop_future_error_cb, NULL, sc);
                 }
@@ -1915,9 +1931,15 @@ _efl_model_properties_changed_cb(void *data, const 
Efl_Event *event)
 EOLIAN static void
 _efl_ui_layout_efl_ui_view_model_set(Eo *obj EINA_UNUSED, Efl_Ui_Layout_Data 
*pd, Efl_Model *model)
 {
+   Efl_Ui_Layout_Sub_Connect *sc;
+   Eina_List *l;
+
    if (pd->model)
      {
          efl_event_callback_del(pd->model, EFL_MODEL_EVENT_PROPERTIES_CHANGED, 
_efl_model_properties_changed_cb, pd);
+         EINA_LIST_FOREACH(pd->prop_connect, l, sc)
+           if (sc->future) efl_future_cancel(sc->future);
+
          efl_unref(pd->model);
          pd->model = NULL;
      }
@@ -1929,7 +1951,15 @@ _efl_ui_layout_efl_ui_view_model_set(Eo *obj 
EINA_UNUSED, Efl_Ui_Layout_Data *pd
          efl_event_callback_add(pd->model, EFL_MODEL_EVENT_PROPERTIES_CHANGED, 
_efl_model_properties_changed_cb, pd);
      }
    else
-     return;
+     {
+        EINA_LIST_FOREACH(pd->prop_connect, l, sc)
+          {
+             if (!sc->is_signal)
+               elm_layout_text_set(obj, sc->name, NULL);
+          }
+
+        return;
+     }
 
    if (pd->prop_connect)
      _efl_ui_layout_view_model_update(pd);
diff --git a/src/lib/elementary/efl_ui_layout_factory.c 
b/src/lib/elementary/efl_ui_layout_factory.c
new file mode 100644
index 0000000000..6fe150dc3d
--- /dev/null
+++ b/src/lib/elementary/efl_ui_layout_factory.c
@@ -0,0 +1,127 @@
+#ifdef HAVE_CONFIG_H
+# include "elementary_config.h"
+#endif
+
+#include <Elementary.h>
+#include "elm_priv.h"
+
+#define MY_CLASS EFL_UI_LAYOUT_FACTORY_CLASS
+#define MY_CLASS_NAME "Efl.Ui.Layout_Factory"
+
+typedef struct _Efl_Ui_Layout_Factory_Data
+{
+    Eina_Array *layouts;
+    Eina_Hash *connects;
+    Eina_Stringshare *klass;
+    Eina_Stringshare *group;
+    Eina_Stringshare *style;
+} Efl_Ui_Layout_Factory_Data;
+
+Eina_Bool
+_model_connect(const Eina_Hash *hash EINA_UNUSED, const void *key, void *data, 
void *fdata)
+{
+   Eo *layout = fdata;
+   Eina_Stringshare *name = key;
+   Eina_Stringshare *property = data;
+
+   efl_ui_model_connect(layout, name, property);
+
+   return EINA_TRUE;
+}
+
+EOLIAN static Eo *
+_efl_ui_layout_factory_efl_object_constructor(Eo *obj, 
Efl_Ui_Layout_Factory_Data *pd)
+{
+   obj = efl_constructor(efl_super(obj, MY_CLASS));
+
+   pd->klass = NULL;
+   pd->group = NULL;
+   pd->style = NULL;
+   pd->layouts = eina_array_new(8);
+   pd->connects = 
eina_hash_stringshared_new(EINA_FREE_CB(eina_stringshare_del));
+
+   return obj;
+}
+
+EOLIAN static void
+_efl_ui_layout_factory_efl_object_destructor(Eo *obj, 
Efl_Ui_Layout_Factory_Data *pd)
+{
+   Eina_Array_Iterator iterator;
+   Eo *layout;
+   unsigned int i;
+
+   eina_stringshare_del(pd->klass);
+   eina_stringshare_del(pd->group);
+   eina_stringshare_del(pd->style);
+
+   EINA_ARRAY_ITER_NEXT(pd->layouts, i, layout, iterator)
+     efl_parent_set(layout, NULL);
+
+   eina_array_free(pd->layouts);
+   eina_hash_free(pd->connects);
+
+   efl_destructor(efl_super(obj, MY_CLASS));
+}
+
+EOLIAN static Efl_Gfx *
+_efl_ui_layout_factory_efl_ui_factory_create(Eo *obj EINA_UNUSED, 
Efl_Ui_Layout_Factory_Data *pd
+                                                        , Efl_Model *model, 
Efl_Gfx *parent)
+{
+   Efl_Gfx *layout;
+   EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
+/*
+   if (eina_array_count(pd->layouts))
+     {
+        layout = eina_array_pop(pd->layouts);
+        efl_parent_set(layout, parent);
+        efl_ui_view_model_set(layout, model);
+     }
+   else */
+     {
+        layout = efl_add(EFL_UI_LAYOUT_CLASS, parent,
+                         efl_ui_view_model_set(efl_added, model),
+                         elm_layout_theme_set(efl_added, pd->klass, pd->group, 
pd->style));
+
+        eina_hash_foreach(pd->connects, _model_connect, layout);
+
+        evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, 0);
+        evas_object_size_hint_align_set(layout, EVAS_HINT_FILL, 
EVAS_HINT_FILL);
+     }
+
+   return layout;
+}
+
+EOLIAN static void
+_efl_ui_layout_factory_efl_ui_factory_release(Eo *obj EINA_UNUSED, 
Efl_Ui_Layout_Factory_Data *pd EINA_UNUSED, Efl_Gfx *layout)
+{
+   efl_ui_view_model_set(layout, NULL);
+   efl_del(layout);
+}
+
+EOLIAN static void
+_efl_ui_layout_factory_efl_ui_model_connect_connect(Eo *obj EINA_UNUSED, 
Efl_Ui_Layout_Factory_Data *pd
+                                                                        , 
const char *name, const char *property)
+{
+   Eina_Stringshare *ss_name, *ss_prop;
+   ss_name = eina_stringshare_add(name);
+
+   if (property == NULL)
+     {
+        eina_hash_del(pd->connects, ss_name, NULL);
+        return;
+     }
+
+   ss_prop = eina_stringshare_add(property);
+   eina_stringshare_del(eina_hash_set(pd->connects, ss_name, ss_prop));
+}
+
+EOLIAN static void
+_efl_ui_layout_factory_theme_config(Eo *obj EINA_UNUSED, 
Efl_Ui_Layout_Factory_Data *pd
+                                        , const char *klass, const char 
*group, const char *style)
+{
+   eina_stringshare_replace(&pd->klass, klass);
+   eina_stringshare_replace(&pd->group, group);
+   eina_stringshare_replace(&pd->style, style);
+}
+
+#include "efl_ui_layout_factory.eo.c"
diff --git a/src/lib/elementary/efl_ui_layout_factory.eo 
b/src/lib/elementary/efl_ui_layout_factory.eo
new file mode 100644
index 0000000000..e712900d1c
--- /dev/null
+++ b/src/lib/elementary/efl_ui_layout_factory.eo
@@ -0,0 +1,22 @@
+class Efl.Ui.Layout_Factory (Efl.Object, Efl.Ui.Factory)
+{
+   [[Efl Ui Layout Factory class]]
+   methods {
+      theme_config {
+         [[]]
+         params {
+            klass: string; [[The class of the group.]]
+            group: string; [[The group.]]
+            style: string; [[The style to used.]]
+         }
+      }
+   }
+
+   implements {
+      Efl.Object.constructor;
+      Efl.Object.destructor;
+      Efl.Ui.Factory.create;
+      Efl.Ui.Factory.release;
+      Efl.Ui.Model.Connect.connect;
+   }
+}
diff --git a/src/lib/elementary/efl_ui_list.c b/src/lib/elementary/efl_ui_list.c
new file mode 100644
index 0000000000..4a70ab5bf4
--- /dev/null
+++ b/src/lib/elementary/efl_ui_list.c
@@ -0,0 +1,668 @@
+#ifdef HAVE_CONFIG_H
+# include "elementary_config.h"
+#endif
+#define ELM_ACCESS_PROTECTED
+#define ELM_ACCESS_WIDGET_ACTION_PROTECTED
+#define EFL_ACCESS_SELECTION_PROTECTED
+
+#include <Elementary.h>
+#include "efl_ui_list_private.h"
+#include "efl_ui_list_precise_layouter.eo.h"
+
+#include <assert.h>
+
+#define MY_CLASS EFL_UI_LIST_CLASS
+#define MY_CLASS_NAME "Efl.Ui.List"
+
+#define MY_PAN_CLASS EFL_UI_LIST_PAN_CLASS
+
+#define SIG_CHILD_ADDED "child,added"
+#define SIG_CHILD_REMOVED "child,removed"
+#define SELECTED_PROP "selected"
+
+static const Evas_Smart_Cb_Description _smart_callbacks[] = {
+   {SIG_CHILD_ADDED, ""},
+   {SIG_CHILD_REMOVED, ""},
+   {NULL, NULL}
+};
+
+void _efl_ui_list_custom_layout(Efl_Ui_List *);
+void _efl_ui_list_item_select_set(Efl_Ui_List_LayoutItem*, Eina_Bool);
+static void _layout(Efl_Ui_List_Data* pd);
+
+static Eina_Bool _key_action_move(Evas_Object *obj, const char *params);
+static Eina_Bool _key_action_select(Evas_Object *obj, const char *params);
+static Eina_Bool _key_action_escape(Evas_Object *obj, const char *params);
+
+static const Elm_Action key_actions[] = {
+   {"move", _key_action_move},
+   {"select", _key_action_select},
+   {"escape", _key_action_escape},
+   {NULL, NULL}
+};
+
+EOLIAN static void
+_efl_ui_list_pan_efl_canvas_group_group_calculate(Eo *obj EINA_UNUSED, 
Efl_Ui_List_Pan_Data *psd)
+{
+   evas_object_smart_changed(psd->wobj);
+}
+
+
+EOLIAN static void
+_efl_ui_list_pan_elm_pan_pos_set(Eo *obj EINA_UNUSED, Efl_Ui_List_Pan_Data 
*psd, Evas_Coord x, Evas_Coord y)
+{
+   if ((x == psd->x) && (y == psd->y)) return;
+
+   psd->x = x;
+   psd->y = y;
+
+   evas_object_smart_changed(psd->wobj);
+}
+
+EOLIAN static void
+_efl_ui_list_pan_elm_pan_pos_get(Eo *obj EINA_UNUSED, Efl_Ui_List_Pan_Data 
*psd, Evas_Coord *x, Evas_Coord *y)
+{
+   if (x) *x = psd->x;
+   if (y) *y = psd->y;
+}
+
+EOLIAN static void
+_efl_ui_list_pan_elm_pan_pos_max_get(Eo *obj EINA_UNUSED, Efl_Ui_List_Pan_Data 
*psd, Evas_Coord *x, Evas_Coord *y)
+{
+   Evas_Coord ow, oh;
+   Eina_Size2D min;
+
+   elm_interface_scrollable_content_viewport_geometry_get
+              (psd->wobj, NULL, NULL, &ow, &oh);
+
+   min = efl_ui_list_model_min_size_get(psd->wobj);
+   ow = min.w - ow;
+   if (ow < 0) ow = 0;
+   oh = min.h - oh;
+   if (oh < 0) oh = 0;
+
+   if (x) *x = ow;
+   if (y) *y = oh;
+}
+
+EOLIAN static void
+_efl_ui_list_pan_elm_pan_pos_min_get(Eo *obj EINA_UNUSED, Efl_Ui_List_Pan_Data 
*psd EINA_UNUSED, Evas_Coord *x, Evas_Coord *y)
+{
+   if (x) *x = 0;
+   if (y) *y = 0;
+}
+
+EOLIAN static void
+_efl_ui_list_pan_elm_pan_content_size_get(Eo *obj EINA_UNUSED, 
Efl_Ui_List_Pan_Data *psd, Evas_Coord *w, Evas_Coord *h)
+{
+   Eina_Size2D min;
+   min = efl_ui_list_model_min_size_get(psd->wobj);
+
+   if (w) *w = min.w;
+   if (h) *h = min.h;
+}
+
+EOLIAN static void
+_efl_ui_list_pan_efl_object_destructor(Eo *obj, Efl_Ui_List_Pan_Data *psd 
EINA_UNUSED)
+{
+   efl_destructor(efl_super(obj, MY_PAN_CLASS));
+}
+
+#include "efl_ui_list_pan.eo.c"
+
+static Eina_Bool
+_efl_model_properties_has(Efl_Model *model, Eina_Stringshare *propfind)
+{
+   const Eina_Array *properties;
+   Eina_Array_Iterator iter_prop;
+   Eina_Stringshare *property;
+   Eina_Bool ret = EINA_FALSE;
+   unsigned i = 0;
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(model, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(propfind, EINA_FALSE);
+
+   properties = efl_model_properties_get(model);
+
+   EINA_ARRAY_ITER_NEXT(properties, i, property, iter_prop)
+     {
+        if (property == propfind)
+          {
+             ret = EINA_TRUE;
+             break;
+          }
+     }
+   return ret;
+}
+
+static void
+_on_item_mouse_up(void *data, Evas *evas EINA_UNUSED, Evas_Object *o 
EINA_UNUSED, void *event_info)
+{
+   Evas_Event_Mouse_Down *ev = event_info;
+   Efl_Ui_List_LayoutItem *item = data;
+
+   if (ev->button != 1) return;
+   if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
+
+   _efl_ui_list_item_select_set(item, EINA_TRUE);
+}
+
+static void
+_count_then(void * data, Efl_Event const* event EINA_UNUSED)
+{
+   Efl_Ui_List_Data *pd = data;
+   EINA_SAFETY_ON_NULL_RETURN(pd);
+
+   pd->count_future = NULL;
+   _layout(pd);
+}
+
+static void
+_count_error(void * data, Efl_Event const* event EINA_UNUSED)
+{
+   Efl_Ui_List_Data *pd = data;
+   EINA_SAFETY_ON_NULL_RETURN(pd);
+   pd->count_future = NULL;
+}
+
+static void
+_children_slice_error(void * data EINA_UNUSED, Efl_Event const* event 
EINA_UNUSED)
+{
+   Efl_Ui_List_Data *pd = data;
+   EINA_SAFETY_ON_NULL_RETURN(pd);
+   pd->slice_future = NULL;
+}
+
+static void
+_show_region_hook(void *data EINA_UNUSED, Evas_Object *obj, Eina_Rect r)
+{
+   elm_interface_scrollable_content_region_show(obj, r.x, r.y, r.w, r.h);
+}
+
+EOLIAN static void
+_efl_ui_list_select_mode_set(Eo *obj EINA_UNUSED, Efl_Ui_List_Data *pd, 
Elm_Object_Select_Mode mode)
+{
+   if (pd->select_mode == mode)
+     return;
+
+   pd->select_mode = mode;
+}
+
+EOLIAN static Elm_Object_Select_Mode
+_efl_ui_list_select_mode_get(Eo *obj EINA_UNUSED, Efl_Ui_List_Data *pd)
+{
+   return pd->select_mode;
+}
+
+EOLIAN static void
+_efl_ui_list_default_style_set(Eo *obj EINA_UNUSED, Efl_Ui_List_Data *pd, 
Eina_Stringshare *style)
+{
+   eina_stringshare_replace(&pd->style, style);
+}
+
+EOLIAN static Eina_Stringshare *
+_efl_ui_list_default_style_get(Eo *obj EINA_UNUSED, Efl_Ui_List_Data *pd)
+{
+   return pd->style;
+}
+
+EOLIAN static void
+_efl_ui_list_homogeneous_set(Eo *obj EINA_UNUSED, Efl_Ui_List_Data *pd, 
Eina_Bool homogeneous)
+{
+   pd->homogeneous = homogeneous;
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_list_homogeneous_get(Eo *obj EINA_UNUSED, Efl_Ui_List_Data *pd)
+{
+   return pd->homogeneous;
+}
+
+EOLIAN static void
+_efl_ui_list_efl_gfx_position_set(Eo *obj, Efl_Ui_List_Data *pd, 
Eina_Position2D p)
+{
+   int pan_x, pan_y;
+   if (_evas_object_intercept_call(obj, EVAS_OBJECT_INTERCEPT_CB_MOVE, 0, p.x, 
p.y))
+     return;
+
+   efl_gfx_position_set(efl_super(obj, MY_CLASS), p);
+
+   elm_pan_pos_get(pd->pan_obj, &pan_x, &pan_y);
+   evas_object_move(pd->hit_rect, p.x, p.y);
+   evas_object_move(pd->pan_obj, p.x - pan_x, p.y - pan_y);
+   evas_object_smart_changed(pd->obj);
+}
+
+EOLIAN static void
+_efl_ui_list_elm_interface_scrollable_region_bring_in(Eo *obj, 
Efl_Ui_List_Data *pd, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h)
+{
+   int pan_x, pan_y;
+   elm_pan_pos_get(pd->pan_obj, &pan_x, &pan_y);
+   elm_interface_scrollable_region_bring_in(efl_super(obj, MY_CLASS), x + 
pan_x, y + pan_y, w, h);
+}
+
+EOLIAN static void
+_efl_ui_list_efl_gfx_size_set(Eo *obj, Efl_Ui_List_Data *pd, Eina_Size2D size)
+{
+   if (_evas_object_intercept_call(obj, EVAS_OBJECT_INTERCEPT_CB_RESIZE, 0, 
size.w, size.h))
+     return;
+
+   evas_object_resize(pd->hit_rect, size.w, size.h);
+   efl_gfx_size_set(efl_super(obj, MY_CLASS), size);
+
+   evas_object_smart_changed(pd->obj);
+}
+
+EOLIAN static void
+_efl_ui_list_efl_canvas_group_group_calculate(Eo *obj EINA_UNUSED, 
Efl_Ui_List_Data *pd)
+{
+   _layout(pd);
+}
+
+EOLIAN static void
+_efl_ui_list_efl_canvas_group_group_member_add(Eo *obj, Efl_Ui_List_Data *pd, 
Evas_Object *member)
+{
+   efl_canvas_group_member_add(efl_super(obj, MY_CLASS), member);
+
+   if (pd->hit_rect)
+     evas_object_raise(pd->hit_rect);
+}
+
+EOLIAN static void
+_efl_ui_list_efl_canvas_group_group_add(Eo *obj, Efl_Ui_List_Data *pd)
+{
+   Efl_Ui_List_Pan_Data *pan_data;
+   Evas_Coord minw, minh;
+
+   ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
+
+   efl_canvas_group_add(efl_super(obj, MY_CLASS));
+   elm_widget_sub_object_parent_add(obj);
+
+   elm_widget_can_focus_set(obj, EINA_TRUE);
+
+   if (!elm_layout_theme_set(obj, "list", "base", elm_widget_style_get(obj)))
+     CRI("Failed to set layout!");
+
+   pd->hit_rect = evas_object_rectangle_add(evas_object_evas_get(obj));
+   evas_object_data_set(pd->hit_rect, "_elm_leaveme", obj);
+   evas_object_smart_member_add(pd->hit_rect, obj);
+   elm_widget_sub_object_add(obj, pd->hit_rect);
+
+   /* common scroller hit rectangle setup */
+   evas_object_color_set(pd->hit_rect, 0, 0, 0, 0);
+   evas_object_show(pd->hit_rect);
+   evas_object_repeat_events_set(pd->hit_rect, EINA_TRUE);
+
+   elm_widget_on_show_region_hook_set(obj, NULL, _show_region_hook, NULL);
+
+   elm_interface_scrollable_objects_set(obj, wd->resize_obj, pd->hit_rect);
+   elm_interface_scrollable_bounce_allow_set
+           (obj, EINA_FALSE, _elm_config->thumbscroll_bounce_enable);
+
+   pd->mode = ELM_LIST_COMPRESS;
+
+   efl_access_type_set(obj, EFL_ACCESS_TYPE_DISABLED);
+   pd->pan_obj = efl_add(MY_PAN_CLASS, evas_object_evas_get(obj));
+   pan_data = efl_data_scope_get(pd->pan_obj, MY_PAN_CLASS);
+   pan_data->wobj = obj;
+
+   elm_interface_scrollable_extern_pan_set(obj, pd->pan_obj);
+   evas_object_show(pd->pan_obj);
+
+   edje_object_size_min_calc(wd->resize_obj, &minw, &minh);
+   evas_object_size_hint_min_set(obj, minw, minh);
+
+   elm_layout_sizing_eval(obj);
+}
+
+EOLIAN static void
+_efl_ui_list_efl_canvas_group_group_del(Eo *obj, Efl_Ui_List_Data *pd)
+{
+   ELM_SAFE_FREE(pd->pan_obj, evas_object_del);
+   efl_canvas_group_del(efl_super(obj, MY_CLASS));
+}
+
+EOLIAN static void
+_efl_ui_list_efl_ui_focus_manager_focus_set(Eo *obj EINA_UNUSED, 
Efl_Ui_List_Data *pd, Efl_Ui_Focus_Object *focus)
+{
+    efl_ui_focus_manager_focus_set(pd->manager, focus);
+}
+
+EOLIAN static Efl_Ui_Focus_Manager*
+_efl_ui_list_elm_widget_focus_manager_create(Eo *obj EINA_UNUSED, 
Efl_Ui_List_Data *pd EINA_UNUSED, Efl_Ui_Focus_Object *root)
+{
+   if (!pd->manager)
+     pd->manager = efl_add(EFL_UI_FOCUS_MANAGER_CALC_CLASS, obj,
+                          efl_ui_focus_manager_root_set(efl_added, root));
+
+   return pd->manager;
+}
+
+EOLIAN static Eo *
+_efl_ui_list_efl_object_finalize(Eo *obj, Efl_Ui_List_Data *pd)
+{
+
+   if (!pd->factory)
+     pd->factory = efl_add(EFL_UI_LAYOUT_FACTORY_CLASS, NULL);
+
+   if(!pd->relayout)
+     {
+        pd->relayout = efl_add(EFL_UI_LIST_PRECISE_LAYOUTER_CLASS, obj);
+        if (pd->model)
+          efl_ui_list_relayout_model_set(pd->relayout, pd->model);
+     }
+   return obj;
+}
+
+EOLIAN static Eo *
+_efl_ui_list_efl_object_constructor(Eo *obj, Efl_Ui_List_Data *pd)
+{
+   Efl_Ui_Focus_Manager *manager;
+
+   obj = efl_constructor(efl_super(obj, MY_CLASS));
+   pd->obj = obj;
+   efl_canvas_object_type_set(obj, MY_CLASS_NAME);
+   evas_object_smart_callbacks_descriptions_set(obj, _smart_callbacks);
+   efl_access_role_set(obj, EFL_ACCESS_ROLE_LIST);
+
+   efl_ui_list_segarray_setup(&pd->segarray, 32);
+
+   manager = efl_ui_widget_focus_manager_create(obj, obj);
+   efl_composite_attach(obj, manager);
+   _efl_ui_focus_manager_redirect_events_add(manager, obj);
+
+   pd->style = eina_stringshare_add(elm_widget_style_get(obj));
+
+   pd->factory = NULL;
+   pd->orient = EFL_ORIENT_DOWN;
+   pd->align.h = 0;
+   pd->align.v = 0;
+   pd->min.w = 0;
+   pd->min.h = 0;
+
+   return obj;
+}
+
+EOLIAN static void
+_efl_ui_list_efl_object_destructor(Eo *obj, Efl_Ui_List_Data *pd)
+{
+   efl_ui_list_relayout_model_set(pd->relayout, NULL);
+
+   efl_unref(pd->model);
+   eina_stringshare_del(pd->style);
+
+   efl_ui_list_segarray_flush(&pd->segarray);
+
+   efl_destructor(efl_super(obj, MY_CLASS));
+}
+
+EOLIAN static void
+_efl_ui_list_layout_factory_set(Eo *obj EINA_UNUSED, Efl_Ui_List_Data *pd, 
Efl_Ui_Factory *factory)
+{
+   if (pd->factory)
+     efl_unref(pd->factory);
+
+   pd->factory = factory;
+   efl_ref(pd->factory);
+}
+
+EOLIAN static void
+_efl_ui_list_efl_ui_view_model_set(Eo *obj, Efl_Ui_List_Data *pd, Efl_Model 
*model)
+{
+   if (pd->model == model)
+     return;
+
+   if (pd->count_future)
+     {
+        efl_future_cancel(pd->count_future);
+        pd->count_future = NULL;
+     }
+
+   if (pd->model)
+     {
+        if (pd->relayout)
+          efl_ui_list_relayout_model_set(pd->relayout, NULL);
+        efl_ui_list_segarray_flush(&pd->segarray);
+        efl_unref(pd->model);
+        pd->model = NULL;
+     }
+
+   if (model)
+     {
+        pd->model = model;
+        efl_ref(pd->model);
+        if (pd->relayout)
+          efl_ui_list_relayout_model_set(pd->relayout, model);
+        pd->count_future = efl_model_children_count_get(pd->model);
+        efl_future_then(pd->count_future, &_count_then, &_count_error, NULL, 
pd);
+     }
+
+   evas_object_smart_changed(pd->obj);
+}
+
+EOLIAN static Efl_Model *
+_efl_ui_list_efl_ui_view_model_get(Eo *obj EINA_UNUSED, Efl_Ui_List_Data *pd)
+{
+   return pd->model;
+}
+
+EOLIAN int
+_efl_ui_list_efl_access_selection_selected_children_count_get(Eo *obj 
EINA_UNUSED, Efl_Ui_List_Data *pd)
+{
+   return eina_list_count(pd->selected_items);
+}
+
+EOLIAN Eo*
+_efl_ui_list_efl_access_selection_selected_child_get(Eo *obj EINA_UNUSED, 
Efl_Ui_List_Data *pd, int child_index)
+{
+   if(child_index <  (int) eina_list_count(pd->selected_items))
+     {
+        Efl_Ui_List_Item* items = eina_list_nth(pd->selected_items, 
child_index);
+        return items[child_index].item.layout;
+     }
+   else
+     return NULL;
+}
+
+EOLIAN Eina_Bool
+_efl_ui_list_efl_access_selection_child_select(Eo *obj EINA_UNUSED, 
Efl_Ui_List_Data *pd EINA_UNUSED, int child_index EINA_UNUSED)
+{
+   return EINA_FALSE;
+}
+
+EOLIAN Eina_Bool
+_efl_ui_list_efl_access_selection_selected_child_deselect(Eo *obj EINA_UNUSED, 
Efl_Ui_List_Data *pd EINA_UNUSED, int child_index EINA_UNUSED)
+{
+   return EINA_FALSE;
+}
+
+EOLIAN Eina_Bool
+_efl_ui_list_efl_access_selection_is_child_selected(Eo *obj EINA_UNUSED, 
Efl_Ui_List_Data *pd, int child_index)
+{
+   return EINA_FALSE;
+}
+
+EOLIAN Eina_Bool
+_efl_ui_list_efl_access_selection_all_children_select(Eo *obj EINA_UNUSED, 
Efl_Ui_List_Data *pd)
+{
+   return EINA_TRUE;
+}
+
+EOLIAN Eina_Bool
+_efl_ui_list_efl_access_selection_clear(Eo *obj EINA_UNUSED, Efl_Ui_List_Data 
*pd)
+{
+   return EINA_TRUE;
+}
+
+EOLIAN Eina_Bool
+_efl_ui_list_efl_access_selection_child_deselect(Eo *obj EINA_UNUSED, 
Efl_Ui_List_Data *pd EINA_UNUSED, int child_index EINA_UNUSED)
+{
+   return EINA_FALSE;
+}
+
+static Eina_Bool
+_key_action_move(Evas_Object *obj, const char *params)
+{
+     return EINA_FALSE;
+}
+
+static Eina_Bool
+_key_action_select(Evas_Object *obj, const char *params EINA_UNUSED)
+{
+   return EINA_FALSE;
+}
+
+static Eina_Bool
+_key_action_escape(Evas_Object *obj, const char *params EINA_UNUSED)
+{
+   efl_ui_focus_manager_reset_history(obj);
+   return EINA_TRUE;
+}
+
+ELM_WIDGET_KEY_DOWN_DEFAULT_IMPLEMENT(efl_ui_list, Efl_Ui_List_Data)
+
+void
+_efl_ui_list_item_select_set(Efl_Ui_List_LayoutItem *item, Eina_Bool selected)
+{
+   Eina_Stringshare *sprop;
+   assert(item != NULL);
+   assert(item->children != NULL);
+
+   selected = !!selected;
+
+   sprop = eina_stringshare_add(SELECTED_PROP);
+
+   if (_efl_model_properties_has(item->children, sprop))
+     {
+        Eina_Value v;
+        eina_value_setup(&v, EINA_VALUE_TYPE_UCHAR);
+        eina_value_set(&v, selected);
+        efl_model_property_set(item->children, sprop, &v);
+        eina_value_flush(&v);
+     }
+   eina_stringshare_del(sprop);
+}
+
+static void
+_efl_ui_list_relayout_set(Eo *obj EINA_UNUSED, Efl_Ui_List_Data *pd 
EINA_UNUSED, Efl_Ui_List_Relayout *object)
+{
+   if(pd->relayout)
+     efl_unref(pd->relayout);
+
+   pd->relayout = object;
+   efl_ref(pd->relayout);
+}
+
+static Efl_Ui_List_Relayout *
+_efl_ui_list_relayout_get(Eo *obj EINA_UNUSED, Efl_Ui_List_Data *pd 
EINA_UNUSED)
+{
+   return pd->relayout;
+}
+
+static void
+_layout(Efl_Ui_List_Data *pd)
+{
+   if (!pd->model)
+     return;
+
+   efl_ui_list_relayout_layout_do(pd->relayout, pd->obj, pd->segarray_first, 
&pd->segarray);
+}
+
+static void
+_children_slice_then(void * data, Efl_Event const* event)
+{
+   Efl_Ui_List_Data *pd = data;
+   Eina_Accessor *acc = 
(Eina_Accessor*)((Efl_Future_Event_Success*)event->info)->value;
+
+   efl_ui_list_segarray_insert_accessor(&pd->segarray, 
pd->outstanding_slice.slice_start, acc);
+
+   pd->segarray_first = pd->outstanding_slice.slice_start;
+   pd->outstanding_slice.slice_start = pd->outstanding_slice.slice_count = 0;
+   pd->slice_future = NULL;
+}
+
+/* EFL UI LIST MODEL INTERFACE */
+EOLIAN static Eina_Size2D
+_efl_ui_list_efl_ui_list_model_min_size_get(Eo *obj EINA_UNUSED, 
Efl_Ui_List_Data *pd)
+{
+   return pd->min;
+}
+
+EOLIAN static void
+_efl_ui_list_efl_ui_list_model_min_size_set(Eo *obj, Efl_Ui_List_Data *pd, 
Eina_Size2D min)
+{
+   ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
+
+   pd->min.w = min.w;
+   pd->min.h = min.h;
+
+   evas_object_size_hint_min_set(wd->resize_obj, pd->min.w, pd->min.h);
+   efl_event_callback_legacy_call(pd->pan_obj, ELM_PAN_EVENT_CHANGED, NULL);
+}
+
+EOLIAN static Efl_Ui_List_LayoutItem *
+_efl_ui_list_efl_ui_list_model_realize(Eo *obj, Efl_Ui_List_Data *pd, 
Efl_Ui_List_LayoutItem *item)
+{
+   Efl_Ui_List_Item_Event evt;
+   EINA_SAFETY_ON_NULL_RETURN_VAL(item->children, item);
+
+   item->layout = efl_ui_factory_create(pd->factory, item->children, obj);
+   evas_object_smart_member_add(item->layout, pd->pan_obj);
+   evas_object_event_callback_add(item->layout, EVAS_CALLBACK_MOUSE_UP, 
_on_item_mouse_up, item);
+
+   evt.child = item->children;
+   evt.layout = item->layout;
+   evt.index = efl_ui_list_item_index_get((Efl_Ui_List_Item *)item);
+   efl_event_callback_call(obj, EFL_UI_LIST_EVENT_ITEM_REALIZED, &evt);
+
+   evas_object_show(item->layout);
+   return item;
+}
+
+EOLIAN static void
+_efl_ui_list_efl_ui_list_model_unrealize(Eo *obj, Efl_Ui_List_Data *pd, 
Efl_Ui_List_LayoutItem *item)
+{
+   Efl_Ui_List_Item_Event evt;
+   EINA_SAFETY_ON_NULL_RETURN(item->layout);
+
+   evas_object_event_callback_del_full(item->layout, EVAS_CALLBACK_MOUSE_UP, 
_on_item_mouse_up, item);
+   evas_object_hide(item->layout);
+   evas_object_move(item->layout, -9999, -9999);
+
+   evt.child = item->children;
+   evt.layout = item->layout;
+   evt.index = efl_ui_list_item_index_get((Efl_Ui_List_Item *)item);
+   efl_event_callback_call(obj, EFL_UI_LIST_EVENT_ITEM_UNREALIZED, &evt);
+
+   evas_object_smart_member_del(item->layout);
+   efl_ui_factory_release(pd->factory, item->layout);
+   item->layout = NULL;
+}
+
+EOLIAN static void
+_efl_ui_list_efl_ui_list_model_load_range_set(Eo* obj EINA_UNUSED, 
Efl_Ui_List_Data* pd, int first, int count)
+{
+   if(!pd->slice_future)
+     {
+        pd->slice_future = efl_model_children_slice_get(pd->model, first, 
count);
+        pd->outstanding_slice.slice_start = first;
+        pd->outstanding_slice.slice_count = count;
+        efl_future_then(pd->slice_future, &_children_slice_then, 
&_children_slice_error, NULL, pd);
+     }
+}
+
+EOLIAN static int
+_efl_ui_list_efl_ui_list_model_size_get(Eo *obj EINA_UNUSED, Efl_Ui_List_Data 
*pd)
+{
+    return pd->item_count;
+}
+
+/* Internal EO APIs and hidden overrides */
+
+#define EFL_UI_LIST_EXTRA_OPS \
+   EFL_CANVAS_GROUP_ADD_DEL_OPS(efl_ui_list)
+
+#include "efl_ui_list.eo.c"
+#include "efl_ui_list_relayout.eo.c"
+#include "efl_ui_list_model.eo.c"
diff --git a/src/lib/elementary/efl_ui_list.eo 
b/src/lib/elementary/efl_ui_list.eo
new file mode 100644
index 0000000000..e484b38504
--- /dev/null
+++ b/src/lib/elementary/efl_ui_list.eo
@@ -0,0 +1,108 @@
+import elm_general;
+
+struct Efl.Ui.List.Item_Event
+{
+   layout: Efl.Ui.Layout;
+   child: Efl.Model;
+   index: int;
+}
+class Efl.Ui.List (Efl.Ui.Layout, Efl.Ui.View, Elm.Interface_Scrollable,
+                Efl.Access.Widget.Action, Efl.Access.Selection,
+                Efl.Ui.Clickable, Efl.Ui.Selectable, Efl.Ui.List.Model)
+{
+   methods {
+      @property relayout {
+         values {
+            object: Efl.Ui.List.Relayout;
+         }
+      }
+      @property homogeneous {
+         get {
+           [[Get whether the homogeneous mode is enabled.]]
+         }
+         set {
+           [[Enable/disable homogeneous mode.]]
+         }
+         values {
+            homogeneous: bool; [[Assume the items within the genlist are of
+                                 the same height and width. Default is 
$false.]]
+         }
+      }
+      @property select_mode {
+         [[Listview select mode.]]
+         get {}
+         set {}
+         values {
+            mode: Elm.Object.Select_Mode(Elm.Object.Select_Mode.max); [[The 
select mode.]]
+         }
+      }
+      @property default_style {
+         values {
+            style: stringshare;
+         }
+      }
+      @property layout_factory {
+         [[Listview layout factory set.]]
+         set {}
+         values {
+            factory: Efl.Ui.Factory; [[The factory.]]
+         }
+      }
+   }
+   events {
+      item,realized : Efl.Ui.List.Item_Event;
+      item,unrealized : Efl.Ui.List.Item_Event;
+      item,focused : Efl.Ui.List.Item_Event;
+      item,unfocused : Efl.Ui.List.Item_Event;
+      item,highlighted : Efl.Ui.List.Item_Event;
+      item,unhighlighted : Efl.Ui.List.Item_Event;
+      item,selected : Efl.Ui.List.Item_Event;
+      item,unselected : Efl.Ui.List.Item_Event;
+   }
+
+   implements {
+      Efl.Object.constructor;
+      Efl.Object.finalize;
+      Efl.Object.destructor;
+      Efl.Gfx.position { set; }
+      Efl.Gfx.size { set; }
+      // Smart obj
+      Efl.Canvas.Group.group_member_add;
+      Efl.Canvas.Group.group_calculate;
+
+      Efl.Ui.List.Model.load_range { set;}
+      Efl.Ui.List.Model.realize;
+      Efl.Ui.List.Model.unrealize;
+      Efl.Ui.List.Model.size { get; }
+      Efl.Ui.List.Model.min_size { get; set; }
+
+      // Widget
+//      Elm.Widget.focus_next_manager_is;
+//      Elm.Widget.focus_direction_manager_is;
+//      Elm.Widget.focus_register;
+//      Elm.Widget.focus_next;
+//      Elm.Widget.on_focus_update;
+//      Elm.Widget.activate;
+//      Elm.Widget.focused_item { get; }
+//      Elm.Widget.focused_object { get; }
+      Elm.Widget.focus_manager_create;
+      Elm.Widget.widget_event;
+
+//      Efl.Ui.Focus.Manager.focus {set; }
+      //Efl.Ui.Layout.sizing_eval;
+      Efl.Ui.View.model { get; set; }
+
+      Elm.Interface_Scrollable.region_bring_in;
+//      Elm.Interface.Atspi_Accessible.children { get; }
+//      Elm.Interface.Atspi_Widget_Action.elm_actions { get; }
+//      Efl.Access.Widget.Action.elm_actions { get; }
+      Efl.Access.Selection.selected_children_count { get; }
+      Efl.Access.Selection.selected_child { get; }
+      Efl.Access.Selection.selected_child_deselect;
+      Efl.Access.Selection.child_select;
+      Efl.Access.Selection.child_deselect;
+      Efl.Access.Selection.is_child_selected;
+      Efl.Access.Selection.all_children_select;
+      Efl.Access.Selection.clear;
+   }
+}
diff --git a/src/lib/elementary/efl_ui_list_model.eo 
b/src/lib/elementary/efl_ui_list_model.eo
new file mode 100644
index 0000000000..ba2b2dc107
--- /dev/null
+++ b/src/lib/elementary/efl_ui_list_model.eo
@@ -0,0 +1,48 @@
+import efl_ui_list_types;
+
+interface Efl.Ui.List.Model (Efl.Interface)
+{
+   methods {
+      @property load_range {
+         set {}
+         values {
+            first: int;
+            count: int;
+         }
+      }
+      realize {
+         params {
+            item: ptr(Efl.Ui.List.LayoutItem);
+         }
+         return: ptr(Efl.Ui.List.LayoutItem);
+      }
+      unrealize {
+         params {
+            item: ptr(Efl.Ui.List.LayoutItem);
+         }
+      }
+      // @property visible_range {
+      //    set {}
+      //    values {
+      //       first: int;
+      //       count: int;
+      //    }
+      // }
+      @property size {
+         get {}
+         values {
+            s: int;
+         }
+      }
+      @property min_size {
+         [[Minimal content size.]]
+         set {}
+         get {}
+         values {
+            min: Eina.Size2D;
+         }
+      }
+
+
+   }
+}
diff --git a/src/lib/elementary/efl_ui_list_pan.eo 
b/src/lib/elementary/efl_ui_list_pan.eo
new file mode 100644
index 0000000000..7bbb176666
--- /dev/null
+++ b/src/lib/elementary/efl_ui_list_pan.eo
@@ -0,0 +1,16 @@
+class Efl.Ui.List.Pan (Elm.Pan)
+{
+   [[Elementary Efl_Ui_List pan class]]
+   implements {
+      Efl.Object.destructor;
+      Elm.Pan.content_size { get; }
+      Elm.Pan.pos { get; set; }
+      Elm.Pan.pos_min { get; }
+      Elm.Pan.pos_max { get; }
+      Efl.Canvas.Group.group_calculate;
+   }
+   events {
+      item,focused; [[Called when item got focus]]
+      item,unfocused; [[Called when item lost focus]]
+   }
+}
diff --git a/src/lib/elementary/efl_ui_list_precise_layouter.c 
b/src/lib/elementary/efl_ui_list_precise_layouter.c
new file mode 100644
index 0000000000..7f37b7f4b6
--- /dev/null
+++ b/src/lib/elementary/efl_ui_list_precise_layouter.c
@@ -0,0 +1,659 @@
+#ifdef HAVE_CONFIG_H
+# include "elementary_config.h"
+#endif
+
+#include <Elementary.h>
+
+#include <assert.h>
+
+#include "elm_priv.h"
+#include "efl_ui_list_segarray.h"
+
+#define MY_CLASS EFL_UI_LIST_PRECISE_LAYOUTER_CLASS
+
+typedef struct _Efl_Ui_List_Precise_Layouter_Data
+{
+   Eina_Bool initialized;
+   Eina_Bool recalc;
+   Eina_Bool resize;
+   Eina_Size2D min;
+   Efl_Model* model;
+   Efl_Ui_List_Model *modeler;
+   Efl_Future *count_future;
+   Ecore_Job *calc_job;
+   Efl_Ui_List_SegArray *segarray;
+   int first;
+   int count_total;
+   unsigned int calc_progress;
+} Efl_Ui_List_Precise_Layouter_Data;
+
+typedef struct _Efl_Ui_List_Precise_Layouter_Node_Data
+{
+  Eina_Size2D min;
+  Eina_Size2D size;
+  Eina_Bool realized;
+} Efl_Ui_List_Precise_Layouter_Node_Data;
+
+typedef struct _Efl_Ui_List_Precise_Layouter_Callback_Data
+{
+  Efl_Ui_List_Precise_Layouter_Data* pd;
+  Efl_Ui_List_LayoutItem* item;
+} Efl_Ui_List_Precise_Layouter_Callback_Data;
+
+
+#include "efl_ui_list_precise_layouter.eo.h"
+
+
+static void _efl_ui_list_relayout_layout_do(Efl_Ui_List_Precise_Layouter_Data 
*);
+static void _initilize(Eo *, Efl_Ui_List_Precise_Layouter_Data*, 
Efl_Ui_List_Model*, Efl_Ui_List_SegArray*);
+static void _finalize(Eo *, Efl_Ui_List_Precise_Layouter_Data*);
+static void _node_realize(Efl_Ui_List_Precise_Layouter_Data*, 
Efl_Ui_List_SegArray_Node*);
+static void _node_unrealize(Efl_Ui_List_Precise_Layouter_Data*, 
Efl_Ui_List_SegArray_Node*);
+
+static void
+_item_size_calc(Efl_Ui_List_Precise_Layouter_Data *pd, Efl_Ui_List_LayoutItem* 
item)
+{
+   int boxx, boxy, boxw, boxh, boxl, boxr, boxt, boxb, pad[4];
+   double align[2];
+   Eina_Size2D max;
+
+   efl_gfx_size_hint_margin_get(item->layout, &pad[0], &pad[1], &pad[2], 
&pad[3]);
+   evas_object_geometry_get(pd->modeler, &boxx, &boxy, &boxw, &boxh);
+   efl_gfx_size_hint_margin_get(pd->modeler, &boxl, &boxr, &boxt, &boxb);
+   efl_gfx_size_hint_align_get(item->layout, &align[0], &align[1]);
+   max = efl_gfx_size_hint_max_get(item->layout);
+
+   // box outer margin
+   boxw -= boxl + boxr;
+   boxh -= boxt + boxb;
+   boxx += boxl;
+   boxy += boxt;
+
+   if (align[0] < 0) align[0] = -1;
+   if (align[1] < 0) align[1] = -1;
+   if (align[0] > 1) align[0] = 1;
+   if (align[1] > 1) align[1] = 1;
+
+   if (max.w <= 0) max.w = INT_MAX;
+   if (max.h <= 0) max.h = INT_MAX;
+   if (max.w < item->min.w) max.w = item->min.w;
+   if (max.h < item->min.h) max.h = item->min.h;
+
+   // horizontally
+   if (max.w < INT_MAX)
+     {
+        item->size.w = MIN(MAX(item->min.w - pad[0] - pad[1], max.w), boxw);
+        item->pos.x = boxx + pad[0];
+     }
+   else if (align[0] < 0)
+     {
+        // fill x
+       item->size.w = boxw - pad[0] - pad[1];
+       item->pos.x = boxx + pad[0];
+     }
+   else
+     {
+        item->size.w = item->min.w - pad[0] - pad[1];
+        item->pos.x = boxx + ((boxw - item->size.w) * align[0]) + pad[0];
+     }
+
+   // vertically
+   if (max.h < INT_MAX)
+     {
+        item->size.h = MIN(MAX(item->min.h - pad[2] - pad[3], max.h), boxh);
+        item->pos.y = boxy + pad[2];
+     }
+   else if (align[1] < 0)
+     {
+        // fill y
+       item->size.h = item->min.h - pad[2] - pad[3];
+       item->pos.y = boxy + pad[2];
+     }
+   else
+     {
+        item->size.h = item->min.h - pad[2] - pad[3];
+        item->pos.y = boxy + ((item->min.h - item->size.h) * align[1]) + 
pad[2];
+     }
+}
+
+static void
+_item_min_calc(Efl_Ui_List_Precise_Layouter_Data *pd, Efl_Ui_List_LayoutItem* 
item
+                , Eina_Size2D min, Efl_Ui_List_SegArray_Node *itemnode)
+{
+   Efl_Ui_List_Precise_Layouter_Node_Data *nodedata = itemnode->layout_data;
+   Efl_Ui_List_LayoutItem *layout_item;
+   int i, pad[4];
+
+   efl_gfx_size_hint_margin_get(item->layout, &pad[0], &pad[1], &pad[2], 
&pad[3]);
+
+   min.w += pad[0] + pad[1];
+   min.h += pad[2] + pad[3];
+
+   if (item->min.h == min.h && item->min.w == min.h)
+     return;
+
+   pd->min.h += min.h - item->min.h;
+   nodedata->min.h += min.h - item->min.h;
+
+   if (nodedata->min.w <= min.w)
+     nodedata->min.w = min.w;
+   else if (nodedata->min.w == item->min.w)
+     {
+       nodedata->min.w = 0;
+       for (i = 0; i != itemnode->length; ++i)
+         {
+            layout_item = (Efl_Ui_List_LayoutItem *)itemnode->pointers[i];
+            if (nodedata->min.w < layout_item->min.w)
+              nodedata->min.w = layout_item->min.w;
+
+            if (item->min.w == layout_item->min.w)
+              break;
+         }
+     }
+
+   if (pd->min.w <= min.w)
+     pd->min.w = min.w;
+   else if (pd->min.w == item->min.w)
+     {
+        Efl_Ui_List_SegArray_Node *node;
+        Eina_Accessor *nodes = 
efl_ui_list_segarray_node_accessor_get(pd->segarray);
+        pd->min.w = min.w;
+
+        EINA_ACCESSOR_FOREACH(nodes, i, node)
+          {
+             Efl_Ui_List_Precise_Layouter_Node_Data *nodedata = 
node->layout_data;
+             if (pd->min.w < nodedata->min.w)
+               pd->min.w = nodedata->min.w;
+
+             if (item->min.w == nodedata->min.w)
+               break;
+          }
+       eina_accessor_free(nodes);
+     }
+
+   item->min.w = min.w;
+   item->min.h = min.h;
+
+   _item_size_calc(pd, item);
+}
+
+static void
+_count_then(void * data, Efl_Event const* event)
+{
+   Efl_Ui_List_Precise_Layouter_Data *pd = data;
+   EINA_SAFETY_ON_NULL_RETURN(pd);
+   pd->count_future = NULL;
+
+   pd->count_total = *(int*)((Efl_Future_Event_Success*)event->info)->value;
+
+   if (pd->modeler && (pd->count_total != 
efl_ui_list_segarray_count(pd->segarray)))
+     {
+        pd->recalc = EINA_TRUE;
+        efl_ui_list_model_load_range_set(pd->modeler, 0, 0); // load all
+     }
+}
+
+static void
+_count_error(void * data, Efl_Event const* event EINA_UNUSED)
+{
+   Efl_Ui_List_Precise_Layouter_Data *pd = data;
+   EINA_SAFETY_ON_NULL_RETURN(pd);
+   pd->count_future = NULL;
+}
+
+static void
+_on_item_size_hint_change(void *data, Evas *e EINA_UNUSED,
+                    Evas_Object *obj, void *event_info EINA_UNUSED)
+{
+   Efl_Ui_List_Precise_Layouter_Callback_Data *cb_data = data;
+   Efl_Ui_List_Precise_Layouter_Data *pd = cb_data->pd;
+   Efl_Ui_List_LayoutItem *item = cb_data->item;;
+   Efl_Ui_List_SegArray_Node *node = item->tree_node;
+   Efl_Ui_List_Precise_Layouter_Node_Data *nodedata = node->layout_data;
+
+   Eina_Size2D min = efl_gfx_size_hint_combined_min_get(obj);
+   _item_min_calc(pd, item, min, node);
+   if (!nodedata->realized)
+     {
+        free(evas_object_event_callback_del(item->layout, 
EVAS_CALLBACK_CHANGED_SIZE_HINTS, _on_item_size_hint_change));
+        efl_ui_list_model_unrealize(pd->modeler, item);
+     }
+}
+
+static void
+_on_modeler_resize(void *data, Evas *e EINA_UNUSED,
+                    Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
+{
+   Efl_Ui_List_Precise_Layouter_Data *pd = data;
+   pd->resize = EINA_TRUE;
+}
+
+static void
+_child_added_cb(void *data, const Efl_Event *event)
+{
+   Efl_Model_Children_Event* evt = event->info;
+   Efl_Ui_List_Precise_Layouter_Data *pd = data;
+
+   efl_ui_list_segarray_insert(pd->segarray, evt->index, evt->child);
+   pd->recalc = EINA_TRUE;
+   evas_object_smart_changed(pd->modeler);
+}
+
+static void
+_child_removed_cb(void *data, const Efl_Event *event)
+{
+   Efl_Model_Children_Event* evt = event->info;
+   Efl_Ui_List_Precise_Layouter_Data *pd = data;
+   Efl_Ui_List_LayoutItem *layout_item, *litem;
+   Efl_Ui_List_Precise_Layouter_Node_Data *nodedata;
+   Efl_Ui_List_SegArray_Node *itemnode;
+   Efl_Ui_List_Item* item;
+   int i;
+
+   item = efl_ui_list_segarray_remove(pd->segarray, evt->index);
+   if (!item) return;
+
+   litem = (Efl_Ui_List_LayoutItem *)item;
+   itemnode = litem->tree_node;
+   nodedata = itemnode->layout_data;
+
+   free(evas_object_event_callback_del(litem->layout, 
EVAS_CALLBACK_CHANGED_SIZE_HINTS, _on_item_size_hint_change));
+
+   pd->min.h -= litem->min.h;
+   nodedata->min.h -= litem->min.h;
+
+   if (nodedata->min.w == litem->min.w)
+     nodedata->min.w = 0;
+     for (i = 0; i != itemnode->length; ++i)
+       {
+          layout_item = (Efl_Ui_List_LayoutItem *)itemnode->pointers[i];
+          if (nodedata->min.w < layout_item->min.w)
+            nodedata->min.w = layout_item->min.w;
+
+          if (litem->min.w == layout_item->min.w)
+            {
+               nodedata->min.w = layout_item->min.w;
+               break;
+            }
+       }
+
+   if (pd->min.w == litem->min.w)
+     {
+        Efl_Ui_List_SegArray_Node *node;
+        Eina_Accessor *nodes = 
efl_ui_list_segarray_node_accessor_get(pd->segarray);
+        pd->min.w = 0;
+
+        EINA_ACCESSOR_FOREACH(nodes, i, node)
+          {
+             Efl_Ui_List_Precise_Layouter_Node_Data *nodedata = 
node->layout_data;
+             if (pd->min.w < nodedata->min.w)
+               pd->min.w = nodedata->min.w;
+
+             if (litem->min.w == nodedata->min.w)
+               break;
+          }
+       eina_accessor_free(nodes);
+     }
+
+   efl_ui_list_model_unrealize(pd->modeler, litem);
+
+   free(item);
+   pd->recalc = EINA_TRUE;
+   evas_object_smart_changed(pd->modeler);
+}
+
+static void
+_initilize(Eo *obj EINA_UNUSED, Efl_Ui_List_Precise_Layouter_Data *pd, 
Efl_Ui_List_Model *modeler, Efl_Ui_List_SegArray *segarray)
+{
+   if(pd->initialized)
+     return;
+
+   pd->recalc = EINA_TRUE;
+   pd->initialized = EINA_TRUE;
+
+   pd->modeler = modeler;
+   pd->segarray = segarray;
+
+   evas_object_event_callback_add(modeler, EVAS_CALLBACK_RESIZE, 
_on_modeler_resize, pd);
+//   efl_event_callback_add(pd->model, EFL_MODEL_EVENT_CHILDREN_COUNT_CHANGED, 
_count_changed, pd);
+   efl_event_callback_add(pd->model, EFL_MODEL_EVENT_CHILD_ADDED, 
_child_added_cb, pd);
+   efl_event_callback_add(pd->model, EFL_MODEL_EVENT_CHILD_REMOVED, 
_child_removed_cb, pd);
+   efl_ui_list_model_load_range_set(modeler, 0, 0); // load all
+
+   pd->min.w = 0;
+   pd->min.h = 0;
+}
+
+static void
+_finalize(Eo *obj EINA_UNUSED, Efl_Ui_List_Precise_Layouter_Data *pd)
+{
+   Efl_Ui_List_SegArray_Node* node;
+   int i = 0;
+
+   evas_object_event_callback_del_full(pd->modeler, EVAS_CALLBACK_RESIZE, 
_on_modeler_resize, pd);
+   efl_event_callback_del(pd->model, EFL_MODEL_EVENT_CHILD_ADDED, 
_child_added_cb, pd);
+   efl_event_callback_del(pd->model, EFL_MODEL_EVENT_CHILD_REMOVED, 
_child_removed_cb, pd);
+//   efl_event_callback_del(pd->model, EFL_MODEL_EVENT_CHILDREN_COUNT_CHANGED, 
_count_changed, pd);
+
+   Eina_Accessor *nodes = efl_ui_list_segarray_node_accessor_get(pd->segarray);
+   EINA_ACCESSOR_FOREACH(nodes, i, node)
+     {
+        _node_unrealize(pd, node);
+        free(node->layout_data);
+     }
+
+   eina_accessor_free(nodes);
+
+   pd->min.w = 0;
+   pd->min.h = 0;
+
+   efl_ui_list_model_min_size_set(pd->modeler, pd->min);
+
+   pd->segarray = NULL;
+   pd->modeler = NULL;
+
+   pd->initialized = EINA_FALSE;
+}
+
+static void
+_node_realize(Efl_Ui_List_Precise_Layouter_Data *pd, Efl_Ui_List_SegArray_Node 
*node)
+{
+   Efl_Ui_List_LayoutItem* layout_item;
+   Efl_Ui_List_Precise_Layouter_Callback_Data *cb_data;
+   Efl_Ui_List_Precise_Layouter_Node_Data *nodedata = node->layout_data;
+   int i;
+
+   if (nodedata->realized)
+     return;
+
+   nodedata->realized = EINA_TRUE;
+
+   for (i = 0; i != node->length; ++i)
+     {
+       layout_item = (Efl_Ui_List_LayoutItem *)node->pointers[i];
+       efl_ui_list_model_realize(pd->modeler, layout_item);
+
+       if (layout_item->layout)
+         {
+            cb_data = calloc(1, 
sizeof(Efl_Ui_List_Precise_Layouter_Callback_Data));
+            cb_data->pd = pd;
+            cb_data->item = layout_item;
+            evas_object_event_callback_add(layout_item->layout, 
EVAS_CALLBACK_CHANGED_SIZE_HINTS, _on_item_size_hint_change, cb_data);
+            _item_size_calc(pd, layout_item);
+         }
+     }
+}
+
+static void
+_node_unrealize(Efl_Ui_List_Precise_Layouter_Data *pd, 
Efl_Ui_List_SegArray_Node *node)
+{
+   Efl_Ui_List_LayoutItem* layout_item;
+   Efl_Ui_List_Precise_Layouter_Callback_Data *cb_data;
+   Efl_Ui_List_Precise_Layouter_Node_Data *nodedata = node->layout_data;
+   int i;
+
+   if (!nodedata->realized)
+     return;
+
+   nodedata->realized = EINA_FALSE;
+
+   for (i = 0; i != node->length; ++i)
+     {
+       layout_item = (Efl_Ui_List_LayoutItem *)node->pointers[i];
+       if (layout_item->layout)
+         {
+            cb_data = evas_object_event_callback_del(layout_item->layout, 
EVAS_CALLBACK_CHANGED_SIZE_HINTS, _on_item_size_hint_change);
+            free(cb_data);
+         }
+       efl_ui_list_model_unrealize(pd->modeler, layout_item);
+     }
+}
+
+static void
+_calc_range(Efl_Ui_List_Precise_Layouter_Data *pd)
+{
+   Efl_Ui_List_SegArray_Node *node;
+   Evas_Coord ow, oh, scr_x, scr_y, ch;
+   Efl_Ui_List_Precise_Layouter_Node_Data *nodedata;
+   int i;
+
+   elm_interface_scrollable_content_viewport_geometry_get
+              (pd->modeler, NULL, NULL, &ow, &oh);
+   elm_interface_scrollable_content_pos_get(pd->modeler, &scr_x, &scr_y);
+
+   ch = 0;
+   Eina_Accessor *nodes = efl_ui_list_segarray_node_accessor_get(pd->segarray);
+   EINA_ACCESSOR_FOREACH(nodes, i, node)
+     {
+        nodedata = node->layout_data;
+        if (!nodedata || !nodedata->min.h)
+          continue;
+
+        if ((scr_y < ch || scr_y < nodedata->min.h + ch) &&
+                        (scr_y + oh > ch || scr_y + oh > nodedata->min.h + ch))
+          _node_realize(pd, node);
+        else
+          _node_unrealize(pd, node);
+
+        ch += nodedata->min.h;
+     }
+   eina_accessor_free(nodes);
+}
+
+static void
+_calc_size_job(void *data)
+{
+   Efl_Ui_List_Precise_Layouter_Data *pd;
+   Efl_Ui_List_SegArray_Node *node;
+   Efl_Ui_List_LayoutItem *layout_item;
+   Eo *obj = data;
+   Eina_Size2D min;
+   int i;
+   double start_time = ecore_time_get();
+
+   EINA_SAFETY_ON_NULL_RETURN(data);
+   pd = efl_data_scope_get(obj, MY_CLASS);
+   if (EINA_UNLIKELY(!pd)) return;
+
+   pd->recalc = EINA_FALSE;
+
+   Eina_Accessor *nodes = efl_ui_list_segarray_node_accessor_get(pd->segarray);
+   while (eina_accessor_data_get(nodes, pd->calc_progress, (void **)&node))
+     {
+        pd->calc_progress++;
+        if (!node->layout_data)
+          node->layout_data = calloc(1, 
sizeof(Efl_Ui_List_Precise_Layouter_Node_Data));
+
+        for (i = 0; i != node->length; ++i)
+          {
+            layout_item = (Efl_Ui_List_LayoutItem *)node->pointers[i];
+            EINA_SAFETY_ON_NULL_RETURN(layout_item);
+
+            // cache size of new items
+            if ((layout_item->min.w == 0) && (layout_item->min.h == 0))
+              {
+                if (!layout_item->layout)
+                  {
+                    efl_ui_list_model_realize(pd->modeler, layout_item);
+                  }
+
+                min = efl_gfx_size_hint_combined_min_get(layout_item->layout);
+                if (min.w && min.h)
+                  {
+                    _item_min_calc(pd, layout_item, min, node);
+                    efl_ui_list_model_unrealize(pd->modeler, layout_item);
+                  }
+                else
+                  {
+                     Efl_Ui_List_Precise_Layouter_Callback_Data *cb_data = 
calloc(1, sizeof(Efl_Ui_List_Precise_Layouter_Callback_Data));
+                     cb_data->pd = pd;
+                     cb_data->item = layout_item;
+                     evas_object_event_callback_add(layout_item->layout, 
EVAS_CALLBACK_CHANGED_SIZE_HINTS, _on_item_size_hint_change, cb_data);
+                  }
+              }
+          }
+        if ( (ecore_time_get() - start_time ) > 0.01 )
+          {
+            ecore_job_del(pd->calc_job);
+            pd->calc_job = ecore_job_add(_calc_size_job, obj);
+            eina_accessor_free(nodes);
+            return;
+         }
+     }
+   eina_accessor_free(nodes);
+   pd->calc_progress = 0;
+   pd->calc_job = NULL;
+
+   evas_object_smart_changed(pd->modeler);
+}
+
+EOLIAN static Efl_Object *
+_efl_ui_list_precise_layouter_efl_object_constructor(Eo *obj EINA_UNUSED, 
Efl_Ui_List_Precise_Layouter_Data *pd)
+{
+   obj = efl_constructor(efl_super(obj, MY_CLASS));
+   pd->initialized = EINA_FALSE;
+   pd->count_future = NULL;
+
+   return obj;
+}
+
+EOLIAN static void
+_efl_ui_list_precise_layouter_efl_ui_list_relayout_model_set(Eo *obj 
EINA_UNUSED, Efl_Ui_List_Precise_Layouter_Data *pd, Efl_Model *model)
+{
+   if (pd->model == model)
+     return;
+
+   pd->count_total = 0;
+   if (pd->count_future)
+     {
+        efl_future_cancel(pd->count_future);
+        pd->count_future = NULL;
+     }
+
+   if (pd->model)
+     {
+        _finalize(obj, pd);
+        efl_unref(pd->model);
+        pd->model = NULL;
+     }
+
+   if (model)
+     {
+        pd->model = model;
+        efl_ref(pd->model);
+        pd->count_future = efl_model_children_count_get(pd->model);
+        efl_future_then(pd->count_future, &_count_then, &_count_error, NULL, 
pd);
+     }
+}
+
+static void
+_efl_ui_list_relayout_layout_do(Efl_Ui_List_Precise_Layouter_Data *pd)
+{
+   Evas_Coord ow, oh, scr_x, scr_y;
+   double cur_pos = 0;
+   Efl_Ui_List_LayoutItem* layout_item;
+   Efl_Ui_List_SegArray_Node *items_node;
+   int i, j = 0;
+
+   _calc_range(pd);
+
+   int boxx, boxy, boxw, boxh, extra = 0, rounding = 0;
+   int boxl = 0, boxr = 0, boxt = 0, boxb = 0;
+   evas_object_geometry_get(pd->modeler, &boxx, &boxy, &boxw, &boxh);
+   efl_gfx_size_hint_margin_get(pd->modeler, &boxl, &boxr, &boxt, &boxb);
+
+   // box outer margin
+   boxw -= boxl + boxr;
+   boxh -= boxt + boxb;
+   boxx += boxl;
+   boxy += boxt;
+
+    //padding can not be squeezed (note: could make it an option)
+//   int pad;
+//   double scale;
+//   scale = evas_object_scale_get(pd->modeler);
+//   pad = 0;//pd->pad.scalable ? (pd->pad.v * scale) : pd->pad.v;
+//   length -= pad * (pd->count_total - 1);
+
+   // available space. if <0 we overflow
+   extra = boxh - pd->min.h;
+   if (extra < 0) extra = 0;
+
+   efl_ui_list_model_min_size_set(pd->modeler, pd->min);
+
+   elm_interface_scrollable_content_viewport_geometry_get(pd->modeler, NULL, 
NULL, &ow, &oh);
+   elm_interface_scrollable_content_pos_get(pd->modeler, &scr_x, &scr_y);
+
+   Eina_Accessor *nodes = efl_ui_list_segarray_node_accessor_get(pd->segarray);
+   EINA_ACCESSOR_FOREACH(nodes, i, items_node)
+     {
+        Efl_Ui_List_Precise_Layouter_Node_Data *nodedata = 
items_node->layout_data;
+        if (!nodedata)
+          {
+            continue;
+          }
+
+        if (nodedata->realized)
+          {
+             for(j = 0; j != items_node->length;++j)
+               {
+                  layout_item = (Efl_Ui_List_LayoutItem 
*)items_node->pointers[j];
+                  double x, y, w, h;
+                  double weight_x, weight_y;
+
+                  if (layout_item->min.w && layout_item->min.h)
+                    {
+                       assert(layout_item->layout != NULL);
+                       if (pd->resize)
+                         _item_size_calc(pd, layout_item);
+
+                       efl_gfx_size_hint_weight_get(layout_item->layout, 
&weight_x, &weight_y);
+                       // extra rounding up (compensate cumulative error)
+                       if ((i == (pd->count_total - 1)) && (cur_pos - 
floor(cur_pos) >= 0.5))
+                         rounding = 1;
+
+                       x = layout_item->pos.x;
+                       y = layout_item->pos.y + cur_pos;
+                       w = layout_item->size.w;
+                       h = layout_item->size.h + rounding + weight_y * extra;
+                       cur_pos += h;
+
+                       if (w < pd->min.w) w = pd->min.w;
+                       if (w > ow) w = ow;
+
+                       evas_object_geometry_set(layout_item->layout, (x + 0 - 
scr_x), (y + 0 - scr_y), w, h);
+                    }
+               }
+          }
+        else
+          {
+             cur_pos += nodedata->min.h;
+          }
+     }
+   eina_accessor_free(nodes);
+
+   pd->resize = EINA_FALSE;
+}
+
+EOLIAN static void
+_efl_ui_list_precise_layouter_efl_ui_list_relayout_layout_do
+  (Eo *obj EINA_UNUSED, Efl_Ui_List_Precise_Layouter_Data *pd
+   , Efl_Ui_List_Model *modeler, int first, Efl_Ui_List_SegArray *segarray)
+{
+   _initilize(obj, pd, modeler, segarray);
+
+   pd->first = first;
+
+   if (pd->recalc)
+     {
+        // cache size of new items
+        pd->calc_progress = 0;
+        ecore_job_del(pd->calc_job);
+        pd->calc_job = ecore_job_add(_calc_size_job, obj);
+        return;
+     }
+
+   _efl_ui_list_relayout_layout_do(pd);
+}
+
+#include "efl_ui_list_precise_layouter.eo.c"
diff --git a/src/lib/elementary/efl_ui_list_precise_layouter.eo 
b/src/lib/elementary/efl_ui_list_precise_layouter.eo
new file mode 100644
index 0000000000..d6d276e4a4
--- /dev/null
+++ b/src/lib/elementary/efl_ui_list_precise_layouter.eo
@@ -0,0 +1,8 @@
+class Efl.Ui.List.Precise_Layouter (Efl.Object, Efl.Ui.List.Relayout)
+{
+   implements {
+      Efl.Object.constructor;
+      Efl.Ui.List.Relayout.layout_do;
+      Efl.Ui.List.Relayout.model { set; }
+   }
+}
diff --git a/src/lib/elementary/efl_ui_list_private.h 
b/src/lib/elementary/efl_ui_list_private.h
new file mode 100644
index 0000000000..607d1fe2b2
--- /dev/null
+++ b/src/lib/elementary/efl_ui_list_private.h
@@ -0,0 +1,132 @@
+#ifndef EFL_UI_LIST_PRIVATE_H
+#define EFL_UI_LIST_PRIVATE_H
+
+#ifdef HAVE_CONFIG_H
+# include "elementary_config.h"
+#endif
+
+#define ELM_INTERFACE_ATSPI_ACCESSIBLE_PROTECTED
+#define ELM_INTERFACE_ATSPI_SELECTION_PROTECTED
+#define ELM_INTERFACE_ATSPI_WIDGET_ACTION_PROTECTED
+
+#include <Elementary.h>
+#include "elm_priv.h"
+
+typedef struct _Efl_Ui_List_Item Efl_Ui_List_Item;
+typedef struct _Efl_Ui_List_Data Efl_Ui_List_Data;
+
+struct _Efl_Ui_List_Item
+{
+   Efl_Ui_List_LayoutItem item;
+   Efl_Future           *future;
+   Efl_Ui_List          *list;
+   // Evas_Coord           x, y, minw, minh, w, h;
+   // // double               h, v, wx, wy;
+   // double               wx, wy;
+};
+
+int efl_ui_list_item_index_get(Efl_Ui_List_Item const* item);
+
+typedef struct _Efl_Ui_List_Data Efl_Ui_List_Data;
+
+#include "efl_ui_list_segarray.h"
+
+struct _Efl_Ui_List_Data
+{
+   Eo                           *obj;
+   Evas_Object                  *hit_rect;
+   Efl_Model                    *model;
+
+   Efl_Orient                   orient;
+
+   struct {
+      double                    h, v;
+      Eina_Bool                 scalable: 1;
+   } pad;
+
+   struct {
+      double                    h, v;
+   } align;
+
+   struct {
+      double                    x, y;
+   } weight;
+
+   // struct {
+   //    Evas_Coord                w, h;
+   //    int                       start;
+   //    int                       slice;
+   // } realized;
+
+   int segarray_first;
+   Efl_Ui_List_SegArray segarray;
+
+   Evas_Object               *pan_obj;
+
+   Efl_Ui_Layout_Factory        *factory;
+   Eina_List                    *selected_items;
+   // struct {
+   //   Eina_Inarray               array;
+   // } items;
+   Eina_Stringshare             *style;
+   Elm_Object_Select_Mode       select_mode;
+   Elm_List_Mode                mode;
+
+   Efl_Ui_Focus_Manager         *manager;
+   Eina_Size2D                  min;
+   int                          /*average_item_size, avsom, */item_count;
+   Efl_Future                   *slice_future;
+   Efl_Future                   *count_future;
+   Efl_Ui_List_Relayout         *relayout;
+   struct {
+     int slice_start;
+     int slice_count;
+   } outstanding_slice;
+
+   Eina_Bool                    homogeneous : 1;
+   Eina_Bool                    recalc : 1;
+   Eina_Bool                    on_hold : 1;
+};
+
+typedef struct _Efl_Ui_List_Pan_Data Efl_Ui_List_Pan_Data;
+
+struct _Efl_Ui_List_Pan_Data
+{
+   Eo                     *wobj;
+   Evas_Coord             x, y, move_diff;
+
+   Ecore_Job              *resize_job;
+};
+
+typedef struct _Efl_Ui_List_Slice Efl_Ui_List_Slice;
+
+struct _Efl_Ui_List_Slice
+{
+   Efl_Ui_List_Data       *pd;
+   int                    newstart, slicestart, newslice;
+};
+
+
+
+#define EFL_UI_LIST_DATA_GET(o, ptr) \
+  Efl_Ui_List_Data * ptr = efl_data_scope_get(o, EFL_UI_LIST_CLASS)
+
+#define EFL_UI_LIST_DATA_GET_OR_RETURN(o, ptr)       \
+  EFL_UI_LIST_DATA_GET(o, ptr);                      \
+  if (EINA_UNLIKELY(!ptr))                           \
+    {                                                \
+       CRI("No widget data for object %p (%s)",      \
+           o, evas_object_type_get(o));              \
+       return;                                       \
+    }
+
+#define EFL_UI_LIST_DATA_GET_OR_RETURN_VAL(o, ptr, val) \
+  EFL_UI_LIST_DATA_GET(o, ptr);                         \
+  if (EINA_UNLIKELY(!ptr))                              \
+    {                                                   \
+       CRI("No widget data for object %p (%s)",         \
+           o, evas_object_type_get(o));                 \
+       return val;                                      \
+    }
+
+#endif
diff --git a/src/lib/elementary/efl_ui_list_relayout.eo 
b/src/lib/elementary/efl_ui_list_relayout.eo
new file mode 100644
index 0000000000..94daa479d5
--- /dev/null
+++ b/src/lib/elementary/efl_ui_list_relayout.eo
@@ -0,0 +1,23 @@
+import efl_ui_list_types;
+
+struct @extern Efl_Ui_List_SegArray;
+
+interface Efl.Ui.List.Relayout (Efl.Interface)
+{
+   methods {
+      layout_do {
+         params {
+            modeler: Efl.Ui.List.Model;
+            first: int;
+            children: ptr(Efl_Ui_List_SegArray);
+         }
+      }
+      @property model {
+         [[Model that is/will be ]]
+         set {}
+         values {
+            model: Efl.Model; [[Efl model]]
+         }
+      }
+   }
+}
diff --git a/src/lib/elementary/efl_ui_list_segarray.c 
b/src/lib/elementary/efl_ui_list_segarray.c
new file mode 100644
index 0000000000..79c55fbbe4
--- /dev/null
+++ b/src/lib/elementary/efl_ui_list_segarray.c
@@ -0,0 +1,427 @@
+#ifdef HAVE_CONFIG_H
+# include "elementary_config.h"
+#endif
+
+#include "efl_ui_list_private.h"
+#include "efl_ui_list_segarray.h"
+
+#include <Efl.h>
+
+#include <assert.h>
+
+static int _search_lookup_cb(Eina_Rbtree const* rbtree, const void* key, int 
length EINA_UNUSED, void* data EINA_UNUSED)
+{
+  Efl_Ui_List_SegArray_Node const* node = (void const*)rbtree;
+  int index = *(int*)key;
+  if(index < node->first)
+    {
+      return 1;
+    }
+  else if(index < node->first + node->length)
+    {
+      return 0;
+    }
+  else
+    {
+      return -1;
+    }
+}
+
+static int _insert_lookup_cb(Eina_Rbtree const* rbtree, const void* key, int 
length EINA_UNUSED, void* data EINA_UNUSED)
+{
+  Efl_Ui_List_SegArray_Node const* node = (void const*)rbtree;
+  int index = *(int*)key;
+  if(index < node->first)
+    {
+      return 1;
+    }
+  else if(index < node->first + node->max)
+    {
+      return 0;
+    }
+  else
+    {
+       return -1;
+    }
+}
+
+static Eina_Rbtree_Direction _rbtree_compare(Efl_Ui_List_SegArray_Node const* 
left,
+                                             Efl_Ui_List_SegArray_Node const* 
right, void* data EINA_UNUSED)
+{
+  if(left->first < right->first)
+    return EINA_RBTREE_LEFT;
+  else
+    return EINA_RBTREE_RIGHT;
+}
+
+
+static void
+_free_node(Efl_Ui_List_SegArray_Node* node, void* data EINA_UNUSED)
+{
+   int i = 0;
+
+   while (i < node->length)
+     {
+       free(node->pointers[i]);
+       ++i;
+     }
+
+   free(node);
+}
+
+static Efl_Ui_List_SegArray_Node*
+_alloc_node(Efl_Ui_List_SegArray* segarray, int first, int max)
+{
+   Efl_Ui_List_SegArray_Node* node;
+   node = calloc(1, sizeof(Efl_Ui_List_SegArray_Node) + 
max*sizeof(Efl_Ui_List_Item*));
+   node->first = first;
+   node->max = max;
+   void* tmp = segarray->root;
+   segarray->root = 
(void*)eina_rbtree_inline_insert(EINA_RBTREE_GET(segarray->root), 
EINA_RBTREE_GET(node),
+                                                     
EINA_RBTREE_CMP_NODE_CB(&_rbtree_compare), NULL);
+   segarray->node_count++;
+   return node;
+}
+
+void efl_ui_list_segarray_setup(Efl_Ui_List_SegArray* segarray, //int 
member_size,
+                                int initial_step_size)
+{
+   segarray->root = NULL;
+   segarray->array_initial_size = initial_step_size;
+}
+
+void efl_ui_list_segarray_flush(Efl_Ui_List_SegArray* segarray)
+{
+   eina_rbtree_delete(EINA_RBTREE_GET(segarray->root), 
EINA_RBTREE_FREE_CB(_free_node), NULL);
+   segarray->root = NULL;
+}
+
+static Efl_Ui_List_Item* _create_item_partial(Efl_Model* model)
+{
+   Efl_Ui_List_Item* item = calloc(1, sizeof(Efl_Ui_List_Item));
+   item->item.children = model;
+   return item;
+}
+
+static Efl_Ui_List_Item* _create_item(Efl_Model* model, 
Efl_Ui_List_SegArray_Node* node, unsigned int index)
+{
+   Efl_Ui_List_Item* item =  _create_item_partial(model);
+   item->item.index_offset = index - node->first;
+   item->item.tree_node = node;
+   return item;
+}
+
+Efl_Ui_List_Item*
+efl_ui_list_segarray_remove(Efl_Ui_List_SegArray* segarray, int index)
+{
+   Efl_Ui_List_SegArray_Node *node;
+   Efl_Ui_List_Item *item, *rt;
+   Eina_Iterator* iterator;
+   int offset;
+
+   node = (void*)eina_rbtree_inline_lookup(EINA_RBTREE_GET(segarray->root),
+                                        &index, sizeof(index), 
&_insert_lookup_cb, NULL);
+   if (!node) return NULL;
+
+   offset = index - node->first;
+   if (offset >= node->length) return NULL;
+
+   rt = node->pointers[offset];
+   segarray->count--;
+   node->length--;
+
+   if (offset >= node->length) return NULL;
+
+   while (offset < node->length)
+     {
+       node->pointers[offset] = node->pointers[offset+1];
+       item = node->pointers[offset];
+       --item->item.index_offset;
+       ++offset;
+     }
+
+   node = (void*)EINA_RBTREE_GET(node)->son[EINA_RBTREE_LEFT];
+   iterator = eina_rbtree_iterator_infix((void*)node);
+   while(eina_iterator_next(iterator, (void**)&node))
+     node->first--;
+
+   return rt;
+}
+
+static void
+_efl_ui_list_segarray_insert_at_node(Efl_Ui_List_SegArray* segarray, int 
index, Efl_Ui_List_Item* item, Efl_Ui_List_SegArray_Node* node)
+{
+   Eina_Iterator* iterator;
+   int pos;
+
+   if(node && node->length != node->max && (index - node->first) <= 
node->length)
+    {
+       pos = index - node->first;
+       item->item.tree_node = node;
+       item->item.index_offset = pos;
+       if(pos < node->length)
+         {
+            assert(node->length != node->max);
+
+            memmove(&node->pointers[pos], &node->pointers[pos+1], 
sizeof(node->pointers[pos])*(node->length - pos));
+            node->pointers[pos] = item;
+            node->length++;
+         }
+       else 
+         {
+            assert(pos == node->length);
+      
+            assert(node->length != node->max);
+            node->pointers[pos] = item;
+            node->length++;
+         }
+    }
+  else
+    {
+       node = _alloc_node(segarray, index, segarray->array_initial_size);
+       node->pointers[0] = item;
+       node->length++;
+       item->item.index_offset = 0;
+       item->item.tree_node = node;
+    }
+
+   node = (void*)EINA_RBTREE_GET(node)->son[EINA_RBTREE_LEFT];
+   iterator = eina_rbtree_iterator_infix((void*)node);
+   while(eina_iterator_next(iterator, (void**)&node))
+     {
+       node->first++;
+     }
+
+   eina_iterator_free(iterator);
+}
+
+
+void efl_ui_list_segarray_insert(Efl_Ui_List_SegArray* segarray, int index, 
Efl_Model* model)
+{
+  Efl_Ui_List_SegArray_Node* node, *next;
+  Efl_Ui_List_Item* item;
+
+  item = _create_item_partial(model);
+  
+  node = (void*)eina_rbtree_inline_lookup(EINA_RBTREE_GET(segarray->root),
+                                          &index, sizeof(index), 
&_insert_lookup_cb, NULL);
+  if(node)
+    {
+      next = (void*)EINA_RBTREE_GET(node)->son[EINA_RBTREE_LEFT];
+      if(next && next->first <= index)
+        _efl_ui_list_segarray_insert_at_node(segarray, index, item, next);
+      else
+        _efl_ui_list_segarray_insert_at_node(segarray, index, item, node);
+    }
+  else
+    _efl_ui_list_segarray_insert_at_node(segarray, index, item, NULL);
+}
+
+void efl_ui_list_segarray_insert_accessor(Efl_Ui_List_SegArray* segarray, int 
first, Eina_Accessor* accessor)
+{
+   int i;
+   Efl_Model* children;
+
+   EINA_ACCESSOR_FOREACH(accessor, i, children)
+     {
+        Efl_Ui_List_SegArray_Node *node;
+        int idx = first + i;
+
+        node = 
(void*)eina_rbtree_inline_lookup(EINA_RBTREE_GET(segarray->root),
+                                                &idx, sizeof(idx), 
&_insert_lookup_cb, NULL);
+        if (!node)
+          {
+             node = _alloc_node(segarray, idx, segarray->array_initial_size);
+          }
+
+        assert(node->length < node->max);
+        node->pointers[node->length] = _create_item(children, node, idx);
+        node->length++;
+        segarray->count++;
+     }
+}
+
+int efl_ui_list_segarray_count(Efl_Ui_List_SegArray const* segarray)
+{
+   return segarray->count;
+}
+
+typedef struct _Efl_Ui_List_Segarray_Eina_Accessor
+{
+   Eina_Accessor vtable;
+   Efl_Ui_List_SegArray* segarray;
+} Efl_Ui_List_Segarray_Eina_Accessor;
+
+static Eina_Bool
+_efl_ui_list_segarray_accessor_get_at(Efl_Ui_List_Segarray_Eina_Accessor* acc,
+                                      int idx, void** data)
+{
+   Efl_Ui_List_SegArray_Node* node;
+   node = 
(void*)eina_rbtree_inline_lookup(EINA_RBTREE_GET(acc->segarray->root),
+                                           &idx, sizeof(idx), 
&_search_lookup_cb, NULL);
+   if(node)
+     {
+        if(node->first <= idx && node->first + node->length > idx)
+          {
+             int i = idx - node->first;
+             Efl_Ui_List_Item* item = node->pointers[i];
+             *data = item;
+             return EINA_TRUE;
+          }
+     }
+   return EINA_FALSE;
+}
+
+static void*
+_efl_ui_list_segarray_accessor_get_container(Efl_Ui_List_Segarray_Eina_Accessor*
 acc EINA_UNUSED)
+{
+  return NULL;
+}
+
+static void
+_efl_ui_list_segarray_accessor_free(Efl_Ui_List_Segarray_Eina_Accessor* acc 
EINA_UNUSED)
+{
+   free(acc);
+}
+
+static void
+_efl_ui_list_segarray_accessor_lock(Efl_Ui_List_Segarray_Eina_Accessor* acc 
EINA_UNUSED)
+{
+}
+
+static void
+_efl_ui_list_segarray_accessor_unlock(Efl_Ui_List_Segarray_Eina_Accessor* acc 
EINA_UNUSED)
+{
+}
+
+static Eina_Accessor*
+_efl_ui_list_segarray_accessor_clone(Efl_Ui_List_Segarray_Eina_Accessor* acc 
EINA_UNUSED)
+{
+   return &acc->vtable;
+}
+
+static void
+_efl_ui_list_segarray_accessor_setup(Efl_Ui_List_Segarray_Eina_Accessor* acc, 
Efl_Ui_List_SegArray* segarray)
+{
+   EINA_MAGIC_SET(&acc->vtable, EINA_MAGIC_ACCESSOR);
+   acc->vtable.version = EINA_ACCESSOR_VERSION;
+   acc->vtable.get_at = 
FUNC_ACCESSOR_GET_AT(_efl_ui_list_segarray_accessor_get_at);
+   acc->vtable.get_container = 
FUNC_ACCESSOR_GET_CONTAINER(_efl_ui_list_segarray_accessor_get_container);
+   acc->vtable.free = FUNC_ACCESSOR_FREE(_efl_ui_list_segarray_accessor_free);
+   acc->vtable.lock = FUNC_ACCESSOR_LOCK(_efl_ui_list_segarray_accessor_lock);
+   acc->vtable.unlock = 
FUNC_ACCESSOR_LOCK(_efl_ui_list_segarray_accessor_unlock);
+   acc->vtable.clone = 
FUNC_ACCESSOR_CLONE(_efl_ui_list_segarray_accessor_clone);
+   acc->segarray = segarray;
+}
+
+Eina_Accessor* efl_ui_list_segarray_accessor_get(Efl_Ui_List_SegArray* 
segarray)
+{
+   Efl_Ui_List_Segarray_Eina_Accessor* acc = calloc(1, 
sizeof(Efl_Ui_List_Segarray_Eina_Accessor));
+   _efl_ui_list_segarray_accessor_setup(acc, segarray);
+   return &acc->vtable;
+}
+
+typedef struct _Efl_Ui_List_Segarray_Node_Accessor
+{
+   Eina_Accessor vtable;
+   Efl_Ui_List_SegArray* segarray;
+   Eina_Iterator* pre_iterator;
+   Efl_Ui_List_SegArray_Node* current_node;
+   int current_index;
+} Efl_Ui_List_Segarray_Node_Accessor;
+
+static Eina_Bool
+_efl_ui_list_segarray_node_accessor_get_at(Efl_Ui_List_Segarray_Node_Accessor* 
acc,
+                                      int idx, void** data)
+{
+   if(idx == acc->current_index && acc->current_node)
+     {
+        (*data) = acc->current_node;
+     }
+   else
+     {
+       if(acc->current_index >= idx || !acc->current_node)
+         {
+            eina_iterator_free(acc->pre_iterator);
+            acc->pre_iterator = NULL;
+            acc->current_node = NULL;
+            acc->current_index = -1;
+         }
+
+       if(!acc->pre_iterator)
+         acc->pre_iterator = 
eina_rbtree_iterator_infix((void*)acc->segarray->root);
+
+       for(;acc->current_index != idx;++acc->current_index)
+         {
+         if(!eina_iterator_next(acc->pre_iterator, (void**)&acc->current_node))
+           {
+             --acc->current_index;
+             return EINA_FALSE;
+           }
+         }
+       (*data) = acc->current_node;
+       return EINA_TRUE;
+     }
+   return EINA_FALSE;
+}
+
+static void*
+_efl_ui_list_segarray_node_accessor_get_container(Efl_Ui_List_Segarray_Node_Accessor*
 acc EINA_UNUSED)
+{
+  return NULL;
+}
+
+static void
+_efl_ui_list_segarray_node_accessor_free(Efl_Ui_List_Segarray_Node_Accessor* 
acc EINA_UNUSED)
+{
+   if (acc->pre_iterator)
+     eina_iterator_free(acc->pre_iterator);
+   free(acc);
+}
+
+static void
+_efl_ui_list_segarray_node_accessor_lock(Efl_Ui_List_Segarray_Node_Accessor* 
acc EINA_UNUSED)
+{
+}
+
+static void
+_efl_ui_list_segarray_node_accessor_unlock(Efl_Ui_List_Segarray_Node_Accessor* 
acc EINA_UNUSED)
+{
+}
+
+static Eina_Accessor*
+_efl_ui_list_segarray_node_accessor_clone(Efl_Ui_List_Segarray_Node_Accessor* 
acc EINA_UNUSED)
+{
+   return &acc->vtable;
+}
+
+static void
+_efl_ui_list_segarray_node_accessor_setup(Efl_Ui_List_Segarray_Node_Accessor* 
acc, Efl_Ui_List_SegArray* segarray)
+{
+   EINA_MAGIC_SET(&acc->vtable, EINA_MAGIC_ACCESSOR);
+   acc->vtable.version = EINA_ACCESSOR_VERSION;
+   acc->vtable.get_at = 
FUNC_ACCESSOR_GET_AT(_efl_ui_list_segarray_node_accessor_get_at);
+   acc->vtable.get_container = 
FUNC_ACCESSOR_GET_CONTAINER(_efl_ui_list_segarray_node_accessor_get_container);
+   acc->vtable.free = 
FUNC_ACCESSOR_FREE(_efl_ui_list_segarray_node_accessor_free);
+   acc->vtable.lock = 
FUNC_ACCESSOR_LOCK(_efl_ui_list_segarray_node_accessor_lock);
+   acc->vtable.unlock = 
FUNC_ACCESSOR_LOCK(_efl_ui_list_segarray_node_accessor_unlock);
+   acc->vtable.clone = 
FUNC_ACCESSOR_CLONE(_efl_ui_list_segarray_node_accessor_clone);
+   acc->segarray = segarray;
+   acc->pre_iterator = NULL;
+   acc->current_index = -1;
+   acc->current_node = NULL;
+}
+
+Eina_Accessor* efl_ui_list_segarray_node_accessor_get(Efl_Ui_List_SegArray* 
segarray)
+{
+   Efl_Ui_List_Segarray_Node_Accessor* acc = calloc(1, 
sizeof(Efl_Ui_List_Segarray_Node_Accessor));
+   _efl_ui_list_segarray_node_accessor_setup(acc, segarray);
+   return &acc->vtable;
+}
+
+int efl_ui_list_item_index_get(Efl_Ui_List_Item const* item)
+{
+  Efl_Ui_List_SegArray_Node* node = item->item.tree_node;
+  return item->item.index_offset + node->first;
+}
+
diff --git a/src/lib/elementary/efl_ui_list_segarray.h 
b/src/lib/elementary/efl_ui_list_segarray.h
new file mode 100644
index 0000000000..eb8529a0c2
--- /dev/null
+++ b/src/lib/elementary/efl_ui_list_segarray.h
@@ -0,0 +1,42 @@
+#ifndef EFL_UI_LIST_SEGARRAY_H
+#define EFL_UI_LIST_SEGARRAY_H
+
+#include "efl_ui_list_segarray.h"
+
+typedef struct _Efl_Ui_List_Item Efl_Ui_List_Item;
+
+typedef struct _Efl_Ui_List_SegArray_Node
+{
+   EINA_RBTREE;
+
+   int length;
+   int max;
+   int first;
+
+   void* layout_data;
+
+   Efl_Ui_List_Item* pointers[0];
+} Efl_Ui_List_SegArray_Node;
+
+typedef struct _Efl_Ui_List_SegArray
+{
+   Efl_Ui_List_SegArray_Node *root; // of Efl_Ui_List_SegArray_Nodea
+
+   int array_initial_size;
+   int node_count;
+   int count;
+} Efl_Ui_List_SegArray;
+
+Eina_Accessor* efl_ui_list_segarray_accessor_get(Efl_Ui_List_SegArray* 
segarray);
+Eina_Accessor* efl_ui_list_segarray_node_accessor_get(Efl_Ui_List_SegArray* 
segarray);
+Efl_Ui_List_SegArray_Node* 
efl_ui_list_segarray_item_node_get(Efl_Ui_List_SegArray* segarray,
+                                                              
Efl_Ui_List_Item* item);
+void efl_ui_list_segarray_insert_accessor(Efl_Ui_List_SegArray* segarray, int 
first, Eina_Accessor* accessor);
+int efl_ui_list_segarray_count(Efl_Ui_List_SegArray const* segarray);
+void efl_ui_list_segarray_setup(Efl_Ui_List_SegArray* segarray, int 
initial_step_size);
+void efl_ui_list_segarray_flush(Efl_Ui_List_SegArray* segarray);
+
+void efl_ui_list_segarray_insert(Efl_Ui_List_SegArray* segarray, int index, 
Efl_Model* model);
+Efl_Ui_List_Item *efl_ui_list_segarray_remove(Efl_Ui_List_SegArray* segarray, 
int index);
+
+#endif
diff --git a/src/lib/elementary/efl_ui_list_types.eot 
b/src/lib/elementary/efl_ui_list_types.eot
new file mode 100644
index 0000000000..a0997c8db4
--- /dev/null
+++ b/src/lib/elementary/efl_ui_list_types.eot
@@ -0,0 +1,9 @@
+struct Efl.Ui.List.LayoutItem {
+   layout: Efl.Ui.Layout;
+   children: Efl.Model;
+   index_offset: int;
+   tree_node: void_ptr;
+   min: Eina.Size2D;
+   size: Eina.Size2D;
+   pos: Eina.Position2D;
+}
diff --git a/src/lib/elementary/elm_widget_layout.h 
b/src/lib/elementary/elm_widget_layout.h
index 1a3cf2a394..0e0c088b73 100644
--- a/src/lib/elementary/elm_widget_layout.h
+++ b/src/lib/elementary/elm_widget_layout.h
@@ -53,7 +53,7 @@ typedef struct _Elm_Layout_Smart_Data
    Eina_List            *subs; /**< List of Elm_Layout_Sub_Object_Data 
structs, to hold the actual sub objects such as text, content and the children 
of box and table. */
    Eina_List            *edje_signals; /**< The list of edje signal callbacks. 
*/
    Eina_List            *parts_cursors; /**< The list of cursor names of 
layout parts. This is a list of Elm_Layout_Sub_Object_Cursor struct. */
-   Eina_List            *prop_connect; /**< The hash of properties connected 
to layout parts. */
+   Eina_List            *prop_connect; /**< The list of properties connected 
to layout parts. */
    Eina_Hash            *factories; /**< The hash with parts connected to 
factories. */
    Efl_Model            *model; /**< The model */
    int                   frozen; /**< Layout freeze counter */

-- 


Reply via email to