aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSangHyeon Lee <sh10233.lee@samsung.com>2018-04-23 15:13:59 +0900
committerSangHyeon Lee <sh10233.lee@samsung.com>2018-04-28 13:41:41 +0900
commit75f21087f57ac836fa28556239fafe2669696289 (patch)
tree3590304e24214e7c16a27d62911c727b2301f0bb
parenttests: disable ecore system modules in elm_suite (diff)
downloadefl-75f21087f57ac836fa28556239fafe2669696289.tar.gz
efl_ui_list : introduce new list widget for simple usage
Summary: most usage of simple list, items are very limited and loading performance is not serious. to support those requirement, this efl.ui.list will create scrollable box with efl.pack. user can create list by packing an pre-loaded item object, Efl.Ui.List.Item class. Test Plan: tested in efl_ui_list_example_1.c in examples. Reviewers: cedric, felipealmeida Subscribers: woohyun, Jaehyun_Cho Differential Revision: https://phab.enlightenment.org/D5861
-rw-r--r--data/elementary/themes/edc/efl/list.edc473
-rw-r--r--src/Makefile_Efl.am1
-rw-r--r--src/Makefile_Elementary.am15
-rw-r--r--src/examples/elementary/.gitignore1
-rw-r--r--src/examples/elementary/Makefile.am2
-rw-r--r--src/examples/elementary/efl_ui_list_example_1.c327
-rw-r--r--src/examples/elementary/efl_ui_view_list_example_1.c2
-rw-r--r--src/examples/elementary/efl_ui_view_list_example_2.c2
-rw-r--r--src/examples/elementary/efl_ui_view_list_example_3.c4
-rw-r--r--src/lib/efl/Efl.h1
-rw-r--r--src/lib/efl/interfaces/efl_interfaces_main.c1
-rw-r--r--src/lib/efl/interfaces/efl_ui_item.eo54
-rw-r--r--src/lib/efl/interfaces/efl_ui_multi_selectable.eo28
-rw-r--r--src/lib/elementary/Elementary.h7
-rw-r--r--src/lib/elementary/efl_ui_item.c260
-rw-r--r--src/lib/elementary/efl_ui_item.eo30
-rw-r--r--src/lib/elementary/efl_ui_item_private.h37
-rw-r--r--src/lib/elementary/efl_ui_list.c1140
-rw-r--r--src/lib/elementary/efl_ui_list.eo93
-rw-r--r--src/lib/elementary/efl_ui_list_default_item.c111
-rw-r--r--src/lib/elementary/efl_ui_list_default_item.eo24
-rw-r--r--src/lib/elementary/efl_ui_list_default_item_part_end.eo9
-rw-r--r--src/lib/elementary/efl_ui_list_default_item_part_icon.eo9
-rw-r--r--src/lib/elementary/efl_ui_list_empty_item.c56
-rw-r--r--src/lib/elementary/efl_ui_list_empty_item.eo16
-rw-r--r--src/lib/elementary/efl_ui_list_item.c83
-rw-r--r--src/lib/elementary/efl_ui_list_item.eo12
-rw-r--r--src/lib/elementary/efl_ui_list_item_private.h31
-rw-r--r--src/lib/elementary/efl_ui_list_private.h63
29 files changed, 2687 insertions, 205 deletions
diff --git a/data/elementary/themes/edc/efl/list.edc b/data/elementary/themes/edc/efl/list.edc
index 4b309c8ce5..1bc55ec4d6 100644
--- a/data/elementary/themes/edc/efl/list.edc
+++ b/data/elementary/themes/edc/efl/list.edc
@@ -1,8 +1,12 @@
-group { "efl/view_list";
+group { "efl/list";
inherit: "efl/scroller";
}
-group { name: "efl/list/item";
+group { "efl/view_list";
+ inherit: "efl/list";
+}
+
+group { "efl/list_item";
data.item: "selectraise" "on";
data.item: "focusraise" "on";
images.image: "bevel_curved_horiz_out.png" COMP;
@@ -11,118 +15,91 @@ group { name: "efl/list/item";
images.image: "bevel_horiz_out.png" COMP;
images.image: "shine.png" COMP;
parts {
- part { name: "event"; type: RECT;
- description { state: "default" 0.0;
+ rect { "event";
+ desc { "default";
color: 0 0 0 0;
}
- description { state: "disabled" 0.0;
- inherit: "default" 0.0;
- visible: 0;
+ desc { "disabled";
+ inherit: "default";
+ hid;
}
}
- part { name: "base"; type: RECT; mouse_events: 0;
- description { state: "default" 0.0;
+ rect { "base"; nomouse;
+ desc { "default";
color: 64 64 64 255;
color_class: "list_item_base";
}
- description { state: "odd" 0.0;
+ desc { "odd";
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: "bevel"; mouse_events: 0;
- description { state: "default" 0.0;
+
+ image { "bevel"; nomouse;
+ desc { "default";
image.normal: "bevel_curved_horiz_out.png";
image.border: 0 0 2 2;
image.middle: 0;
fill.smooth: 0;
}
}
- part { name: "sel_shadow"; mouse_events: 0;
- description { state: "default" 0.0;
+ swallow { "efl.background";
+ desc { "default";
+ rel.to: "base";
+ vis;
+ }
+ }
+ image { "sel_shadow"; nomouse;
+ desc { "default";
image.normal: "shadow_rounded_horiz.png";
image.border: 0 0 9 9;
rel1.offset: 0 -4;
rel2.offset: -1 5;
fill.smooth: 0;
- visible: 0;
+ hid;
}
- description { state: "selected" 0.0;
- inherit: "default" 0.0;
- visible: 1;
+ desc { "selected";
+ inherit: "default";
+ vis;
}
}
- part { name: "sel_base"; mouse_events: 0;
- description { state: "default" 0.0;
+ image { "sel_base"; nomouse;
+ desc { "default";
image.normal: "vgrad_med_dark.png";
fill.smooth: 0;
- visible: 0;
+ hid;
TILED_HORIZ(120)
}
- description { state: "selected" 0.0;
- inherit: "default" 0.0;
- visible: 1;
+ desc { "selected";
+ inherit: "default";
+ vis;
}
}
- part { name: "sel_bevel"; mouse_events: 0;
- description { state: "default" 0.0;
+ image { "sel_bevel"; nomouse;
+ desc { "default";
image.normal: "bevel_horiz_out.png";
image.border: 0 0 2 2;
image.middle: 0;
fill.smooth: 0;
- visible: 0;
+ hid;
}
- description { state: "selected" 0.0;
- inherit: "default" 0.0;
- visible: 1;
+ desc { "selected";
+ inherit: "default";
+ vis;
}
}
- 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;
+ text { "efl.text"; nomouse;
effect: SHADOW BOTTOM;
scale: 1;
- description { state: "default" 0.0;
+ desc { "default";
rel1.offset: 2 3;
rel1.relative: 1.0 0.0;
- rel1.to_x: "elm.swallow.icon";
+ rel1.to_x: "efl.icon";
rel2.offset: -3 -3;
rel2.relative: 0.0 1.0;
- rel2.to_x: "elm.swallow.end";
+ rel2.to_x: "efl.end";
color: FN_COL_DEFAULT;
color_class: "list_item";
text { font: FN; size: 10;
@@ -132,160 +109,362 @@ group { name: "efl/list/item";
text_class: "list_item";
}
}
- description { state: "selected" 0.0;
- inherit: "default" 0.0;
- visible: 0;
+ desc { "selected";
+ inherit: "default";
+ hid;
}
- description { state: "disabled" 0.0;
- inherit: "default" 0.0;
- visible: 0;
+ desc { "disabled";
+ inherit: "default";
+ hid;
}
}
- part { name: "label2"; type: TEXT; mouse_events: 0;
+ text { "label2"; nomouse;
effect: SHADOW BOTTOM;
scale: 1;
- description { state: "default" 0.0;
- rel1.to: "elm.text";
- rel2.to: "elm.text";
+ desc { "default";
+ rel1.to: "efl.text";
+ rel2.to: "efl.text";
color: FN_COL_DISABLE;
color_class: "list_item_disabled";
text { font: FN; size: 10;
- text_source: "elm.text";
+ text_source: "efl.text";
align: 0.0 0.5;
text_class: "list_item";
}
- visible: 0;
+ hid;
}
- description { state: "selected" 0.0;
- inherit: "default" 0.0;
- visible: 0;
+ desc { "selected";
+ inherit: "default";
+ hid;
}
- description { state: "disabled" 0.0;
- inherit: "default" 0.0;
- visible: 1;
+ desc { "disabled";
+ inherit: "default";
+ vis;
}
}
- part { name: "label3"; type: TEXT; mouse_events: 0;
+ text { "label3"; nomouse;
effect: GLOW;
scale: 1;
- description { state: "default" 0.0;
+ desc { "default";
rel1.offset: -2 -3;
- rel1.to: "elm.text";
+ rel1.to: "efl.text";
rel2.offset: 1 1;
- rel2.to: "elm.text";
+ rel2.to: "efl.text";
color: FN_COL_HIGHLIGHT;
color_class: "list_item_selected";
text { font: FN; size: 10;
- text_source: "elm.text";
+ text_source: "efl.text";
align: 0.0 0.5;
text_class: "list_item";
}
- visible: 0;
+ hid;
+ }
+ desc { "selected";
+ inherit: "default";
+ vis;
+ }
+ desc { "disabled";
+ inherit: "default";
+ hid;
+ }
+ }
+ //##//
+ swallow { "efl.icon";
+ desc { "default";
+ 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;
+ }
+ }
+ swallow { "efl.end";
+ desc { "default";
+ 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;
+ }
+ }
+ //##//
+ image { "sel_shine"; nomouse;
+ desc { "default";
+ image.normal: "shine.png";
+ rel1.offset: 0 -2;
+ rel1.to: "sel_base";
+ rel2.relative: 1.0 0.0;
+ rel2.offset: -1 2;
+ rel2.to: "sel_base";
+ hid;
+ FIXED_SIZE(69, 5)
+ }
+ desc { "selected";
+ inherit: "default";
+ vis;
}
- description { state: "selected" 0.0;
- inherit: "default" 0.0;
- visible: 1;
+ }
+ rect { "event_block";
+ desc { "default";
+ color: 0 0 0 0;
+ hid;
}
- description { state: "disabled" 0.0;
- inherit: "default" 0.0;
- visible: 0;
+ desc { "disabled";
+ inherit: "default";
+ vis;
}
}
+ }
+ programs {
+ program {
+ signal: "efl,state,odd"; source: "efl";
+ action: STATE_SET "odd";
+ target: "base";
+ }
program {
- signal: "elm,state,selected"; source: "elm";
- action: STATE_SET "selected" 0.0;
- target: "elm.text";
+ signal: "efl,state,even"; source: "efl";
+ action: STATE_SET "default";
+ target: "base";
+ }
+ program {
+ signal: "efl,state,pressed"; source: "efl";
+ action: STATE_SET "selected";
+ target: "sel_shadow";
+ target: "sel_base";
+ target: "sel_bevel";
+ target: "efl.text";
target: "label2";
target: "label3";
+ target: "sel_shine";
}
program {
- signal: "elm,state,unselected"; source: "elm";
- action: STATE_SET "default" 0.0;
- target: "elm.text";
+ signal: "efl,state,unpressed"; source: "efl";
+ action: STATE_SET "default";
+ target: "sel_shadow";
+ target: "sel_base";
+ target: "sel_bevel";
+ target: "efl.text";
target: "label2";
target: "label3";
+ target: "sel_shine";
}
program {
- signal: "elm,state,disabled"; source: "elm";
- action: STATE_SET "disabled" 0.0;
- target: "elm.text";
+ signal: "efl,state,selected"; source: "efl";
+ action: STATE_SET "selected";
+ target: "sel_shadow";
+ target: "sel_base";
+ target: "sel_bevel";
+ target: "efl.text";
target: "label2";
target: "label3";
+ target: "sel_shine";
}
program {
- signal: "elm,state,enabled"; source: "elm";
- action: STATE_SET "default" 0.0;
- target: "elm.text";
+ signal: "efl,state,unselected"; source: "efl";
+ action: STATE_SET "default";
+ target: "sel_shadow";
+ target: "sel_base";
+ target: "sel_bevel";
+ target: "efl.text";
target: "label2";
target: "label3";
+ target: "sel_shine";
}
- //##//
- 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;
+ program {
+ signal: "efl,state,disabled"; source: "efl";
+ action: STATE_SET "disabled";
+ target: "event";
+ target: "efl.text";
+ target: "label2";
+ target: "label3";
+ target: "event_block";
+ }
+ program {
+ signal: "efl,state,enabled"; source: "efl";
+ action: STATE_SET "default";
+ target: "event";
+ target: "efl.text";
+ target: "label2";
+ target: "label3";
+ target: "event_block";
+ }
+ }
+}
+
+group { "efl/list_item:empty";
+ data.item: "selectraise" "on";
+ data.item: "focusraise" "on";
+ images.image: "bevel_curved_horiz_out.png" COMP;
+ images.image: "shadow_rounded_horiz.png" COMP;
+ images.image: "vgrad_med_dark.png" COMP;
+ images.image: "bevel_horiz_out.png" COMP;
+ images.image: "shine.png" COMP;
+ parts {
+ rect { "event";
+ desc { "default";
+ color: 0 0 0 0;
+ }
+ desc { "disabled";
+ inherit: "default";
+ hid;
}
}
- 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;
+ rect { "base"; nomouse;
+ desc { "default";
+ color: 64 64 64 255;
+ color_class: "list_item_base";
+ }
+ desc { "odd";
+ color: 56 56 56 255;
+ color_class: "list_item_base_odd";
+ }
+ }
+
+ image { "bevel"; nomouse;
+ desc { "default";
+ image.normal: "bevel_curved_horiz_out.png";
+ image.border: 0 0 2 2;
+ image.middle: 0;
+ fill.smooth: 0;
+ }
+ }
+ swallow { "efl.background";
+ desc { "default";
+ rel.to: "base";
+ vis;
+ }
+ }
+ image { "sel_shadow"; nomouse;
+ desc { "default";
+ image.normal: "shadow_rounded_horiz.png";
+ image.border: 0 0 9 9;
+ rel1.offset: 0 -4;
+ rel2.offset: -1 5;
+ fill.smooth: 0;
+ hid;
+ }
+ desc { "selected";
+ inherit: "default";
+ vis;
+ }
+ }
+ image { "sel_base"; nomouse;
+ desc { "default";
+ image.normal: "vgrad_med_dark.png";
+ fill.smooth: 0;
+ hid;
+ TILED_HORIZ(120)
+ }
+ desc { "selected";
+ inherit: "default";
+ vis;
+ }
+ }
+ image { "sel_bevel"; nomouse;
+ desc { "default";
+ image.normal: "bevel_horiz_out.png";
+ image.border: 0 0 2 2;
+ image.middle: 0;
+ fill.smooth: 0;
+ hid;
+ }
+ desc { "selected";
+ inherit: "default";
+ vis;
+ }
+ }
+ //##//
+ swallow { "efl.content"; mouse;
+ scale;
+ desc { "default";
+ min: 19 19;
+ rel1.offset: -1 2;
rel2.offset: -3 -3;
}
}
//##//
-
- part { name: "sel_shine"; mouse_events: 0;
- description { state: "default" 0.0;
+ image { "sel_shine";
+ desc { "default";
image.normal: "shine.png";
rel1.offset: 0 -2;
rel1.to: "sel_base";
rel2.relative: 1.0 0.0;
rel2.offset: -1 2;
rel2.to: "sel_base";
- visible: 0;
+ hid;
FIXED_SIZE(69, 5)
}
- description { state: "selected" 0.0;
- inherit: "default" 0.0;
- visible: 1;
+ desc { "selected";
+ inherit: "default";
+ vis;
}
}
- part { name: "event_block"; type: RECT;
- description { state: "default" 0.0;
+ rect { "event_block"; mouse;
+ desc { "default";
color: 0 0 0 0;
- visible: 0;
+ hid;
}
- description { state: "disabled" 0.0;
- inherit: "default" 0.0;
- visible: 1;
+ desc { "disabled";
+ inherit: "default";
+ vis;
}
}
+ }
+ programs {
+ program {
+ signal: "efl,state,odd"; source: "efl";
+ action: STATE_SET "odd";
+ target: "base";
+ }
program {
- signal: "elm,state,selected"; source: "elm";
- action: STATE_SET "selected" 0.0;
+ signal: "efl,state,even"; source: "efl";
+ action: STATE_SET "default";
+ target: "base";
+ }
+ program {
+ signal: "efl,state,pressed"; source: "efl";
+ action: STATE_SET "selected";
+ target: "sel_shadow";
+ target: "sel_base";
+ target: "sel_bevel";
target: "sel_shine";
}
program {
- signal: "elm,state,unselected"; source: "elm";
- action: STATE_SET "default" 0.0;
+ signal: "efl,state,unpressed"; source: "efl";
+ action: STATE_SET "default";
+ target: "sel_shadow";
+ target: "sel_base";
+ target: "sel_bevel";
target: "sel_shine";
}
program {
- signal: "elm,state,disabled"; source: "elm";
- action: STATE_SET "disabled" 0.0;
+ signal: "efl,state,selected"; source: "efl";
+ action: STATE_SET "selected";
+ target: "sel_shadow";
+ target: "sel_base";
+ target: "sel_bevel";
+ target: "sel_shine";
+ }
+ program {
+ signal: "efl,state,unselected"; source: "efl";
+ action: STATE_SET "default";
+ target: "sel_shadow";
+ target: "sel_base";
+ target: "sel_bevel";
+ target: "sel_shine";
+ }
+ program {
+ signal: "efl,state,disabled"; source: "efl";
+ action: STATE_SET "disabled";
+ target: "event";
target: "event_block";
}
program {
- signal: "elm,state,enabled"; source: "elm";
- action: STATE_SET "default" 0.0;
+ signal: "efl,state,enabled"; source: "efl";
+ action: STATE_SET "default";
+ target: "event";
target: "event_block";
}
}
diff --git a/src/Makefile_Efl.am b/src/Makefile_Efl.am
index 595b1e604f..972eda7e04 100644
--- a/src/Makefile_Efl.am
+++ b/src/Makefile_Efl.am
@@ -12,6 +12,7 @@ efl_eolian_legacy_files = \
lib/efl/interfaces/efl_ui_scrollable_interactive.eo \
lib/efl/interfaces/efl_ui_scrollbar.eo \
lib/efl/interfaces/efl_ui_selectable.eo \
+ lib/efl/interfaces/efl_ui_multi_selectable.eo \
lib/efl/interfaces/efl_ui_zoom.eo \
$(NULL)
diff --git a/src/Makefile_Elementary.am b/src/Makefile_Elementary.am
index d101d85bdb..ac528db73c 100644
--- a/src/Makefile_Elementary.am
+++ b/src/Makefile_Elementary.am
@@ -81,6 +81,13 @@ elm_public_eolian_files = \
lib/elementary/efl_ui_view_list_pan.eo \
lib/elementary/efl_ui_view_list_segarray.eo \
lib/elementary/efl_ui_view_list_relayout.eo \
+ lib/elementary/efl_ui_item.eo \
+ lib/elementary/efl_ui_list_item.eo \
+ lib/elementary/efl_ui_list_default_item_part_icon.eo \
+ lib/elementary/efl_ui_list_default_item_part_end.eo \
+ lib/elementary/efl_ui_list_default_item.eo \
+ lib/elementary/efl_ui_list_empty_item.eo \
+ lib/elementary/efl_ui_list.eo \
lib/elementary/efl_ui_panes_part.eo \
lib/elementary/efl_ui_progressbar_part.eo \
lib/elementary/efl_ui_slider_part_indicator.eo \
@@ -391,6 +398,9 @@ 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_item_private.h \
+ lib/elementary/efl_ui_list_item_private.h \
+ lib/elementary/efl_ui_list_private.h \
lib/elementary/efl_ui_view_list_private.h \
lib/elementary/efl_ui_view_list_segarray.h \
lib/elementary/elm_widget_web.h \
@@ -809,6 +819,11 @@ 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_item.c \
+ lib/elementary/efl_ui_list_item.c \
+ lib/elementary/efl_ui_list_default_item.c \
+ lib/elementary/efl_ui_list_empty_item.c \
+ lib/elementary/efl_ui_list.c \
lib/elementary/efl_ui_view_list.c \
lib/elementary/efl_ui_view_list_precise_layouter.c \
lib/elementary/efl_ui_view_list_segarray.c \
diff --git a/src/examples/elementary/.gitignore b/src/examples/elementary/.gitignore
index 896a69007f..f59adb353e 100644
--- a/src/examples/elementary/.gitignore
+++ b/src/examples/elementary/.gitignore
@@ -60,6 +60,7 @@
/list_example_01
/list_example_02
/list_example_03
+/efl_ui_list_example_1
/efl_ui_view_list_example_1
/efl_ui_view_list_example_2
/efl_ui_view_list_example_3
diff --git a/src/examples/elementary/Makefile.am b/src/examples/elementary/Makefile.am
index 488b48f28c..51dbd2051a 100644
--- a/src/examples/elementary/Makefile.am
+++ b/src/examples/elementary/Makefile.am
@@ -177,6 +177,7 @@ efl_thread_3.c \
efl_thread_4.c \
efl_thread_5.c \
efl_thread_6.c \
+efl_ui_list_example_1.c \
efl_ui_view_list_example_1.c \
efl_ui_view_list_example_2.c \
efl_ui_view_list_example_3.c
@@ -393,6 +394,7 @@ efl_thread_3 \
efl_thread_4 \
efl_thread_5 \
efl_thread_6 \
+efl_ui_list_example_1 \
efl_ui_view_list_example_1 \
efl_ui_view_list_example_2 \
efl_ui_view_list_example_3
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..432c58621c
--- /dev/null
+++ b/src/examples/elementary/efl_ui_list_example_1.c
@@ -0,0 +1,327 @@
+// gcc -o efl_ui_list_example_1 efl_ui_list_example_1.c `pkg-config --cflags --libs elementary`
+// ./efl_ui_list_example_1 item_style_name
+
+#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
+
+typedef struct _List_Scroll_Data {
+ Eo *list;
+ Eo *slider;
+ Eina_Bool anim;
+} List_Scroll_Data;
+List_Scroll_Data priv_d;
+
+
+static void
+_list_selected(void *data, const Efl_Event *ev)
+{
+ Eo *list = ev->object;
+ Eo *item = ev->info, *tmp;
+ printf("list item [%p:%d] is %s\n", item, efl_ui_item_index_get(item), (efl_ui_item_selected_get(item)? "selected" : "unselected"));
+
+ Eina_Iterator *selects = efl_ui_list_selected_items_get(list);
+
+ EINA_ITERATOR_FOREACH(selects, tmp)
+ printf("selected [%p:%d] ", tmp, efl_ui_item_index_get(tmp));
+ printf("\n");
+ eina_iterator_free(selects);
+}
+
+static void
+_list_unselected(void *data, const Efl_Event *ev)
+{
+ Eo *item = ev->info;
+ printf("list item [%p : %d] is %s\n", item, efl_ui_item_index_get(item), (efl_ui_item_selected_get(item)? "selected" : "unselected"));
+}
+
+static void
+_list_pressed(void *data, const Efl_Event *ev)
+{
+ Eo *item = ev->info;
+ printf("list item [%p : %d] is pressed\n", item, efl_ui_item_index_get(item));
+}
+
+static void
+_list_unpressed(void *data, const Efl_Event *ev)
+{
+ Eo *item = ev->info;
+ printf("list item [%p : %d] is unpressed\n", item, efl_ui_item_index_get(item));
+}
+
+static void
+_list_longpressed(void *data, const Efl_Event *ev)
+{
+ Eo *item = ev->info;
+ printf("list item [%p : %d] is longpressed\n", item, efl_ui_item_index_get(item));
+}
+
+static void
+_select_radio_changed(void *data, const Efl_Event *ev)
+{
+ Eo *list = data;
+ efl_ui_select_mode_set(list, efl_ui_radio_state_value_get(ev->object));
+}
+
+static void
+_anim_radio_changed(void *data, const Efl_Event *ev)
+{
+ priv_d.anim = efl_ui_radio_state_value_get(ev->object);
+}
+
+static void
+_scrl_btn_clicked(void *data, const Efl_Event *ev)
+{
+ Efl_Ui_List_Item *item = efl_ui_list_last_selected_item_get(priv_d.list);
+ printf("show [%d:%p] [%d]\n", efl_ui_item_index_get(item), item, priv_d.anim);
+ efl_ui_list_item_scroll(priv_d.list, item, priv_d.anim);
+}
+
+static void
+_scrl_align_btn_clicked(void *data, const Efl_Event *ev)
+{
+ Efl_Ui_List_Item *item = efl_ui_list_last_selected_item_get(priv_d.list);
+ double align = efl_ui_range_value_get(priv_d.slider);
+ printf("show [%d:%p] [%.2lf], [%d]\n", efl_ui_item_index_get(item), item, align, priv_d.anim);
+ efl_ui_list_item_scroll_align(priv_d.list, item, align, priv_d.anim);
+}
+
+EAPI_MAIN int
+elm_main(int argc, char **argv)
+{
+ Eo *win, *list;
+ Eo *wbox, *ibox, *bbox, *rbox;
+ Eo *item, *check, *txt;
+ Eo *radio, *select_radio, *anim_radio;
+ Eo *slider, *scrl_btn;
+ int i;
+ char buf[256];
+ Eina_Bool emptystyle = EINA_FALSE;
+
+ win = elm_win_util_standard_add("list", "list");
+ elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED);
+ elm_win_autodel_set(win, EINA_TRUE);
+ efl_gfx_entity_size_set(win, EINA_SIZE2D(400, 800));
+
+ wbox = efl_add(EFL_UI_BOX_CLASS, win);
+ efl_ui_direction_set(wbox, EFL_UI_DIR_VERTICAL);
+ efl_gfx_size_hint_weight_set(wbox, EFL_GFX_SIZE_HINT_EXPAND, EFL_GFX_SIZE_HINT_EXPAND);
+ efl_gfx_size_hint_align_set(wbox, EFL_GFX_SIZE_HINT_FILL, EFL_GFX_SIZE_HINT_FILL);
+
+ if ((argv[1] != NULL) &&
+ (!strcmp(argv[1], "empty")))
+ emptystyle = EINA_TRUE;
+
+ priv_d.list = list = efl_add(EFL_UI_LIST_CLASS, wbox);
+ efl_gfx_size_hint_weight_set(list, EFL_GFX_SIZE_HINT_EXPAND, 0.9);
+
+ efl_event_callback_add(list, EFL_UI_EVENT_SELECTED, _list_selected, NULL);
+ efl_event_callback_add(list, EFL_UI_EVENT_UNSELECTED, _list_unselected, NULL);
+ efl_event_callback_add(list, EFL_UI_EVENT_PRESSED, _list_pressed, NULL);
+ efl_event_callback_add(list, EFL_UI_EVENT_UNPRESSED, _list_unpressed, NULL);
+ efl_event_callback_add(list, EFL_UI_EVENT_LONGPRESSED, _list_longpressed, NULL);
+
+ for (i = 0; i < NUM_ITEMS; i++)
+ {
+ if (emptystyle) item = efl_add(EFL_UI_LIST_EMPTY_ITEM_CLASS, list);
+ else item = efl_add(EFL_UI_LIST_DEFAULT_ITEM_CLASS, list);
+
+ /* disable case test */
+ if (i == 1) efl_ui_widget_disabled_set(item, EINA_TRUE);
+
+ if (emptystyle)
+ {
+ ibox = efl_add(EFL_UI_BOX_CLASS, item);
+ efl_ui_direction_set(ibox, EFL_UI_DIR_HORIZONTAL);
+
+ txt = efl_add(EFL_UI_TEXT_CLASS, ibox);
+ efl_gfx_size_hint_weight_set(txt, 0.95, EFL_GFX_SIZE_HINT_EXPAND);
+ efl_text_halign_set(txt, 0.2);
+ efl_text_interactive_selection_allowed_set(txt, EINA_FALSE);
+ snprintf(buf, sizeof(buf), "empty style item [%d]", i);
+ efl_text_set(txt, buf);
+ efl_pack_end(ibox, txt);
+
+ check = efl_add(EFL_UI_CHECK_CLASS, ibox);
+ efl_gfx_size_hint_weight_set(check, 0.05, EFL_GFX_SIZE_HINT_EXPAND);
+ efl_pack_end(ibox, check);
+
+ if (i % 2)
+ efl_content_set(item, ibox);
+ else
+ efl_content_set(efl_part(item, "content"), ibox);
+ }
+ else
+ {
+ snprintf(buf, sizeof(buf), "default style item [%d]", i);
+ if (i % 2)
+ efl_text_set(efl_part(item, "text"), buf);
+ else
+ efl_text_set(item, buf);
+
+
+ check = efl_add(EFL_UI_CHECK_CLASS, item);
+ if ((i % 3) == 0)
+ efl_content_set(efl_part(item, "end"), check);
+ else if ((i % 3) == 1)
+ efl_content_set(efl_part(item, "icon"), check);
+ else
+ efl_content_set(item, check);
+ }
+ /* Pack APIs test */
+ switch (i)
+ {
+ case 10:
+ efl_gfx_color_set(efl_part(item, "background"), 255, 0, 0, 255);
+ efl_pack_begin(list, item);
+ break;
+
+ case 20:
+ efl_gfx_color_set(efl_part(item, "background"), 0, 255, 0, 255);
+ efl_pack_before(list, item, efl_pack_content_get(list, 19));
+ break;
+
+ case 30:
+ efl_gfx_color_set(efl_part(item, "background"), 0, 0, 255, 255);
+ efl_pack_after(list, item, efl_pack_content_get(list, 29));
+ break;
+
+ case 40:
+ efl_file_set(efl_part(item, "background"), "./sky_01.jpg", NULL);
+ efl_gfx_image_scale_type_set(efl_part(item, "background"), EFL_GFX_IMAGE_SCALE_TYPE_FIT_OUTSIDE);
+ efl_pack_at(list, item, 39);
+ break;
+
+ case 50:
+ efl_file_set(efl_part(item, "background"), "./sky_01.jpg", NULL);
+ efl_gfx_image_scale_type_set(efl_part(item, "background"), EFL_GFX_IMAGE_SCALE_TYPE_TILE);
+ efl_pack(list, item);
+ break;
+
+ case 60:
+ efl_pack(list, item);
+ efl_pack_unpack(list, item);
+ efl_del(item);
+ break;
+
+ default:
+ efl_pack_end(list, item);
+ }
+ }
+
+ efl_pack_end(wbox, list);
+
+ /*select mode */
+ txt = efl_add(EFL_UI_TEXT_CLASS, wbox);
+ efl_gfx_size_hint_weight_set(txt, EFL_GFX_SIZE_HINT_EXPAND, 0.01);
+ efl_text_halign_set(txt, 0.02);
+ efl_text_interactive_selection_allowed_set(txt, EINA_FALSE);
+ efl_text_set(txt, "Select Mode");
+ efl_pack_end(wbox, txt);
+
+ bbox = efl_add(EFL_UI_BOX_CLASS, wbox);
+ efl_ui_direction_set(bbox, EFL_UI_DIR_HORIZONTAL);
+ efl_gfx_size_hint_weight_set(bbox, EFL_GFX_SIZE_HINT_EXPAND, 0.05);
+
+ select_radio = radio = efl_add(EFL_UI_RADIO_CLASS, wbox);
+ efl_text_set(radio, "SINGLE");
+ efl_ui_radio_state_value_set(radio, EFL_UI_SELECT_SINGLE);
+ efl_event_callback_add(radio, EFL_UI_RADIO_EVENT_CHANGED, _select_radio_changed, list);
+ efl_pack_end(bbox, radio);
+ radio = efl_add(EFL_UI_RADIO_CLASS, wbox);
+ efl_text_set(radio, "SINGLE_ALWAYS");
+ efl_ui_radio_state_value_set(radio, EFL_UI_SELECT_SINGLE_ALWAYS);
+ efl_ui_radio_group_add(radio, select_radio);
+ efl_event_callback_add(radio, EFL_UI_RADIO_EVENT_CHANGED, _select_radio_changed, list);
+ efl_pack_end(bbox, radio);
+ radio = efl_add(EFL_UI_RADIO_CLASS, wbox);
+ efl_text_set(radio, "MULTI");
+ efl_ui_radio_state_value_set(radio, EFL_UI_SELECT_MULTI);
+ efl_ui_radio_group_add(radio, select_radio);
+ efl_event_callback_add(radio, EFL_UI_RADIO_EVENT_CHANGED, _select_radio_changed, list);
+ efl_pack_end(bbox, radio);
+ radio = efl_add(EFL_UI_RADIO_CLASS, wbox);
+ efl_text_set(radio, "NONE");
+ efl_ui_radio_state_value_set(radio, EFL_UI_SELECT_NONE);
+ efl_ui_radio_group_add(radio, select_radio);
+ efl_event_callback_add(radio, EFL_UI_RADIO_EVENT_CHANGED, _select_radio_changed, list);
+ efl_pack_end(bbox, radio);
+ efl_pack_end(wbox, bbox);
+
+ /* scroll mode */
+ txt = efl_add(EFL_UI_TEXT_CLASS, wbox);
+ efl_gfx_size_hint_weight_set(txt, EFL_GFX_SIZE_HINT_EXPAND, 0.01);
+ efl_text_interactive_selection_allowed_set(txt, EINA_FALSE);
+ efl_text_halign_set(txt, 0.02);
+ efl_text_set(txt, "Item Scroll");
+ efl_pack_end(wbox, txt);
+
+ priv_d.slider = slider = efl_add(EFL_UI_SLIDER_CLASS, wbox);
+ efl_ui_direction_set(slider, EFL_UI_DIR_HORIZONTAL);
+ efl_gfx_size_hint_weight_set(slider, 0.0, 0.05);
+ efl_gfx_size_hint_align_set(slider, 0.5, 0.5);
+ efl_gfx_size_hint_min_set(slider, EINA_SIZE2D(380, 20));
+ efl_ui_range_min_max_set(slider, 0.0, 1.0);
+ efl_pack_end(wbox, slider);
+
+ bbox = efl_add(EFL_UI_BOX_CLASS, wbox);
+ efl_ui_direction_set(bbox, EFL_UI_DIR_HORIZONTAL);
+ efl_gfx_size_hint_weight_set(bbox, EFL_GFX_SIZE_HINT_EXPAND, 0.05);
+
+ rbox = efl_add(EFL_UI_BOX_CLASS, bbox);
+ efl_ui_direction_set(rbox, EFL_UI_DIR_VERTICAL);
+
+ anim_radio = radio = efl_add(EFL_UI_RADIO_CLASS, rbox);
+ efl_gfx_size_hint_align_set(radio, 0.5, 0.5);
+ efl_text_set(radio, "ANIMATION OFF");
+ efl_ui_radio_state_value_set(radio, 0);
+ efl_event_callback_add(radio, EFL_UI_RADIO_EVENT_CHANGED, _anim_radio_changed, NULL);
+ efl_pack_end(rbox, radio);
+ radio = efl_add(EFL_UI_RADIO_CLASS, rbox);
+ efl_gfx_size_hint_align_set(radio, 0.5, 0.5);
+ efl_text_set(radio, "ANIMATION ON");
+ efl_ui_radio_state_value_set(radio, 1);
+ efl_ui_radio_group_add(radio, anim_radio);
+ efl_event_callback_add(radio, EFL_UI_RADIO_EVENT_CHANGED, _anim_radio_changed, NULL);
+ efl_pack_end(rbox, radio);
+ efl_pack_end(bbox, rbox);
+
+ rbox = efl_add(EFL_UI_BOX_CLASS, bbox);
+ efl_ui_direction_set(rbox, EFL_UI_DIR_VERTICAL);
+
+ scrl_btn = efl_add(EFL_UI_BUTTON_CLASS, rbox);
+ efl_text_set(scrl_btn, "Scroll Item");
+ efl_gfx_size_hint_align_set(scrl_btn, 0.5, 0.5);
+ efl_gfx_size_hint_min_set(scrl_btn, EINA_SIZE2D(200, 25));
+ efl_event_callback_add(scrl_btn, EFL_UI_EVENT_CLICKED, _scrl_btn_clicked, NULL);
+ efl_pack_end(rbox, scrl_btn);
+
+ scrl_btn = efl_add(EFL_UI_BUTTON_CLASS, rbox);
+ efl_text_set(scrl_btn, "Scroll Item Align");
+ efl_gfx_size_hint_align_set(scrl_btn, 0.5, 0.5);
+ efl_gfx_size_hint_min_set(scrl_btn, EINA_SIZE2D(200, 25));
+ efl_event_callback_add(scrl_btn, EFL_UI_EVENT_CLICKED, _scrl_align_btn_clicked, NULL);
+ efl_pack_end(rbox, scrl_btn);
+
+ efl_pack_end(bbox, rbox);
+ efl_pack_end(wbox, bbox);
+
+ elm_win_resize_object_add(win, wbox);
+ //window show
+ efl_gfx_entity_visible_set(win, EINA_TRUE);
+
+ elm_run();
+
+ return 0;
+}
+ELM_MAIN() \ No newline at end of file
diff --git a/src/examples/elementary/efl_ui_view_list_example_1.c b/src/examples/elementary/efl_ui_view_list_example_1.c
index 3994fa419f..621f81ee99 100644
--- a/src/examples/elementary/efl_ui_view_list_example_1.c
+++ b/src/examples/elementary/efl_ui_view_list_example_1.c
@@ -85,7 +85,7 @@ elm_main(int argc, char **argv)
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");
+ efl_ui_layout_factory_theme_config(factory, "list_item", NULL, "default");
li = efl_add(EFL_UI_VIEW_LIST_CLASS, win);
efl_ui_view_list_layout_factory_set(li, factory);
diff --git a/src/examples/elementary/efl_ui_view_list_example_2.c b/src/examples/elementary/efl_ui_view_list_example_2.c
index 6a7c0eed2f..fac0e5d8f4 100644
--- a/src/examples/elementary/efl_ui_view_list_example_2.c
+++ b/src/examples/elementary/efl_ui_view_list_example_2.c
@@ -46,7 +46,7 @@ elm_main(int argc, char **argv)
model = efl_add(EIO_MODEL_CLASS, efl_main_loop_get(), 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");
+ efl_ui_layout_factory_theme_config(factory, "list_item", NULL, "default");
li = efl_add(EFL_UI_VIEW_LIST_CLASS, win);
efl_ui_view_list_layout_factory_set(li, factory);
diff --git a/src/examples/elementary/efl_ui_view_list_example_3.c b/src/examples/elementary/efl_ui_view_list_example_3.c
index 53a816c661..c2e8281ed2 100644
--- a/src/examples/elementary/efl_ui_view_list_example_3.c
+++ b/src/examples/elementary/efl_ui_view_list_example_3.c
@@ -223,7 +223,7 @@ elm_main(int argc, char **argv)
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");
+ efl_ui_layout_factory_theme_config(factory, "list_item", NULL, "default");
priv->list1 = efl_add(EFL_UI_VIEW_LIST_CLASS, win, efl_ui_view_model_set(efl_added, priv->model));
efl_event_callback_add(priv->list1, EFL_UI_VIEW_LIST_EVENT_ITEM_REALIZED, _realized_1_cb, priv);
@@ -235,7 +235,7 @@ elm_main(int argc, char **argv)
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");
+ efl_ui_layout_factory_theme_config(factory, "list_item", NULL, "default");
priv->list2 = efl_add(EFL_UI_VIEW_LIST_CLASS, win, efl_ui_view_model_set(efl_added, priv->model));
efl_event_callback_add(priv->list2, EFL_UI_VIEW_LIST_EVENT_ITEM_REALIZED, _realized_2_cb, priv->list2);
evas_object_size_hint_weight_set(priv->list2, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
diff --git a/src/lib/efl/Efl.h b/src/lib/efl/Efl.h
index 22175bf086..e9b00b1d50 100644
--- a/src/lib/efl/Efl.h
+++ b/src/lib/efl/Efl.h
@@ -92,6 +92,7 @@ typedef Efl_Gfx_Path_Command_Type Efl_Gfx_Path_Command;
#include "interfaces/efl_ui_scrollbar.eo.h"
#include "interfaces/efl_ui_scrollable_interactive.eo.h"
#include "interfaces/efl_ui_selectable.eo.h"
+#include "interfaces/efl_ui_multi_selectable.eo.h"
#include "interfaces/efl_ui_zoom.eo.h"
#include "interfaces/efl_screen.eo.h"
diff --git a/src/lib/efl/interfaces/efl_interfaces_main.c b/src/lib/efl/interfaces/efl_interfaces_main.c
index d245e4afeb..4e02e1e5e1 100644
--- a/src/lib/efl/interfaces/efl_interfaces_main.c
+++ b/src/lib/efl/interfaces/efl_interfaces_main.c
@@ -74,6 +74,7 @@
#include "interfaces/efl_ui_scrollable_interactive.eo.c"
#include "interfaces/efl_ui_scrollbar.eo.c"
#include "interfaces/efl_ui_selectable.eo.c"
+#include "interfaces/efl_ui_multi_selectable.eo.c"
#include "interfaces/efl_ui_zoom.eo.c"
EAPI void
diff --git a/src/lib/efl/interfaces/efl_ui_item.eo b/src/lib/efl/interfaces/efl_ui_item.eo
deleted file mode 100644
index 49ef31b6d5..0000000000
--- a/src/lib/efl/interfaces/efl_ui_item.eo
+++ /dev/null
@@ -1,54 +0,0 @@
-interface Efl.Ui.Item {
- [[Efl UI item interface]]
- legacy_prefix: null;
- methods {
- @property prev {
- get {
- [[Get the item before this one in the widget's list of items.
-
- See also @.next.
- ]]
- }
- values {
- item: Efl.Ui.Item; [[The item before the object in its parent's
- list. If there is no previous item or in case
- of error, $null is returned.]]
- }
- }
- @property next {
- get {
- [[Get the item after this one in the widget's list of items.
-
- See also @.prev.
- ]]
- }
- values {
- item: Efl.Ui.Item; [[The item after the object in its parent's
- list. If there is no next item or in case
- of error, $null is returned.]]
- }
- }
- @property selected {
- [[Indicates whether this item is currently selected.]]
- get {
- [[Get the selected state of this item.]]
- }
- set {
- [[Set the selected state of $item.
-
- This sets the selected state of the given item $it.
- $true for selected, $false for not selected.
-
- If a new item is selected the previously selected will
- be unselected. Previously selected item can be retrieved
- with @Efl.Ui.Menu.selected_item.get.
-
- Selected items will be highlighted.
- ]]
- }
- values {
- selected: bool; [[The selection state.]]
- }
- }
- }
-}
diff --git a/src/lib/efl/interfaces/efl_ui_multi_selectable.eo b/src/lib/efl/interfaces/efl_ui_multi_selectable.eo
new file mode 100644
index 0000000000..8e82750441
--- /dev/null
+++ b/src/lib/efl/interfaces/efl_ui_multi_selectable.eo
@@ -0,0 +1,28 @@
+enum Efl.Ui.Select_Mode {
+ [[Type of multi selectable object.]]
+ legacy: efl_ui_select;
+ single, [[Only single child is selected. if the child is selected,
+ previous selected child will be unselected.]]
+ single_always, [[Same as single select except, this will be selected
+ in every select calls though child is already been selected.]]
+ multi, [[allow multiple selection of children.]]
+ none [[Last value of select mode. child cannot be selected at all.]]
+}
+
+interface Efl.Ui.Multi_Selectable ()
+{
+ [[Efl UI Multi selectable interface.
+ The container have to control select property of multiple chidren.]]
+ eo_prefix: efl_ui;
+ methods
+ {
+ @property select_mode {
+ [[The mode type for children selection.]]
+ set {}
+ get {}
+ values {
+ mode: Efl.Ui.Select_Mode; [[Type of selection of children]]
+ }
+ }
+ }
+}
diff --git a/src/lib/elementary/Elementary.h b/src/lib/elementary/Elementary.h
index 2853ba26e9..b59383a4d7 100644
--- a/src/lib/elementary/Elementary.h
+++ b/src/lib/elementary/Elementary.h
@@ -324,6 +324,13 @@ typedef Eo Efl_Ui_Focus_Manager;
# include <efl_ui_image_factory.eo.h>
# include <efl_ui_slider_interval.eo.h>
# include <efl_ui_layout_factory.eo.h>
+# include <efl_ui_item.eo.h>
+# include <efl_ui_list_item.eo.h>
+# include <efl_ui_list_default_item_part_icon.eo.h>
+# include <efl_ui_list_default_item_part_end.eo.h>
+# include <efl_ui_list_default_item.eo.h>
+# include <efl_ui_list_empty_item.eo.h>
+# include <efl_ui_list.eo.h>
# include <efl_ui_view_list_types.eot.h>
# include <efl_ui_view_list_segarray.h>
# include <efl_ui_view_list_segarray.eo.h>
diff --git a/src/lib/elementary/efl_ui_item.c b/src/lib/elementary/efl_ui_item.c
new file mode 100644
index 0000000000..5eed4b2c7b
--- /dev/null
+++ b/src/lib/elementary/efl_ui_item.c
@@ -0,0 +1,260 @@
+#ifdef HAVE_CONFIG_H
+# include "elementary_config.h"
+#endif
+
+#define EFL_ACCESS_PROTECTED
+#define EFL_UI_WIDGET_PART_BG_PROTECTED
+
+#include <Elementary.h>
+
+#include "elm_priv.h"
+#include "efl_ui_item_private.h"
+
+#define MY_CLASS EFL_UI_ITEM_CLASS
+#define MY_CLASS_PFX efl_ui_item
+
+#define MY_CLASS_NAME "Efl.Ui.Item"
+
+static void
+_item_select(Eo *obj, Efl_Ui_Item_Data *pd)
+{
+ if (pd->selected &&
+ (*(pd->select_mode) != EFL_UI_SELECT_SINGLE_ALWAYS))
+ return;
+ if (*(pd->select_mode) == EFL_UI_SELECT_NONE) return;
+
+ ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
+
+ pd->selected = EINA_TRUE;
+ edje_object_signal_emit(wd->resize_obj, "efl,state,selected", "efl");
+ efl_event_callback_call(obj, EFL_UI_EVENT_SELECTED, NULL);
+}
+
+static void
+_item_unselect(Eo *obj, Efl_Ui_Item_Data *pd)
+{
+ if (!pd->selected) return;
+ ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
+
+ pd->selected = EINA_FALSE;
+ edje_object_signal_emit(wd->resize_obj, "efl,state,unselected", "efl");
+ efl_event_callback_call(obj, EFL_UI_EVENT_UNSELECTED, NULL);
+}
+
+/* Mouse Controls */
+static Eina_Bool
+_item_longpressed(void *data)
+{
+ Efl_Ui_Item *item = data;
+ EFL_UI_ITEM_DATA_GET_OR_RETURN(item, pd, ECORE_CALLBACK_CANCEL);
+
+ pd->longpress_timer = NULL;
+
+ efl_event_callback_call(item, EFL_UI_EVENT_LONGPRESSED, NULL);
+ return ECORE_CALLBACK_CANCEL;
+}
+
+static void
+_item_mouse_down(void *data,
+ Evas *evas EINA_UNUSED,
+ Evas_Object *obj EINA_UNUSED,
+ void *event_info)
+{
+ Evas_Event_Mouse_Down *ev = event_info;
+ Eo *item = data;
+ EFL_UI_ITEM_DATA_GET_OR_RETURN(item, pd);
+ ELM_WIDGET_DATA_GET_OR_RETURN(item, wd);
+ if (wd->disabled) return;
+ if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
+
+ edje_object_signal_emit(wd->resize_obj, "efl,state,pressed", "efl");
+
+ pd->longpress_timer = ecore_timer_add(_elm_config->longpress_timeout, _item_longpressed, item);
+ efl_event_callback_call(item, EFL_UI_EVENT_PRESSED, NULL);
+}
+
+static void
+_item_mouse_up(void *data,
+ Evas *evas EINA_UNUSED,
+ Evas_Object *obj EINA_UNUSED,
+ void *event_info)
+{
+ Evas_Event_Mouse_Up *ev = event_info;
+ Eo *item = data;
+ EFL_UI_ITEM_DATA_GET_OR_RETURN(item, pd);
+ ELM_WIDGET_DATA_GET_OR_RETURN(item, wd);
+ if (wd->disabled) return;
+ if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
+ {
+ //FIXME: should we send this message to fallback?
+ edje_object_signal_emit(wd->resize_obj, "efl,state,unpressed", "efl");
+ //efl_event_callback_call(item, EFL_UI_EVENT_UNPRESSED, NULL);
+ return;
+ }
+
+ if (pd->longpress_timer)
+ {
+ ecore_timer_del(pd->longpress_timer);
+ pd->longpress_timer = NULL;
+ }
+
+ edje_object_signal_emit(wd->resize_obj, "efl,state,unpressed", "efl");
+ efl_event_callback_call(item, EFL_UI_EVENT_UNPRESSED, NULL);
+
+ if ((*(pd->select_mode) != EFL_UI_SELECT_SINGLE_ALWAYS) && (pd->selected))
+ _item_unselect(item, pd);
+ else if (*(pd->select_mode) != EFL_UI_SELECT_NONE)
+ _item_select(item, pd);
+}
+
+static void
+_item_mouse_move(void *data EINA_UNUSED,
+ Evas *evas EINA_UNUSED,
+ Evas_Object *obj EINA_UNUSED,
+ void *event_info)
+{
+ Evas_Event_Mouse_Move *ev = event_info;
+ Eo *item = data;
+ EFL_UI_ITEM_DATA_GET_OR_RETURN(item, pd);
+ ELM_WIDGET_DATA_GET_OR_RETURN(item, wd);
+ if (wd->disabled) return;
+ if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
+ {
+ edje_object_signal_emit(wd->resize_obj, "efl,state,unpressed", "efl");
+ return;
+ }
+}
+
+static void
+_item_mouse_in(void *data EINA_UNUSED,
+ Evas *evas EINA_UNUSED,
+ Evas_Object *obj EINA_UNUSED,
+ void *event_info)
+{
+ Evas_Event_Mouse_In *ev = event_info;
+ Eo *item = data;
+ EFL_UI_ITEM_DATA_GET_OR_RETURN(item, pd);
+ ELM_WIDGET_DATA_GET_OR_RETURN(item, wd);
+ if (wd->disabled) return;
+
+ if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
+}
+
+static void
+_item_mouse_callback_add(Eo *obj, void *data)
+{
+ evas_object_event_callback_add
+ (obj, EVAS_CALLBACK_MOUSE_DOWN, _item_mouse_down, data);
+ evas_object_event_callback_add
+ (obj, EVAS_CALLBACK_MOUSE_UP, _item_mouse_up, data);
+ evas_object_event_callback_add
+ (obj, EVAS_CALLBACK_MOUSE_MOVE, _item_mouse_move, data);
+ evas_object_event_callback_add
+ (obj, EVAS_CALLBACK_MOUSE_IN, _item_mouse_in, data);
+}
+
+static void
+_item_mouse_callback_del(Eo *obj, void *data)
+{
+ evas_object_event_callback_del_full
+ (obj, EVAS_CALLBACK_MOUSE_DOWN, _item_mouse_down, data);
+ evas_object_event_callback_del_full
+ (obj, EVAS_CALLBACK_MOUSE_UP, _item_mouse_up, data);
+ evas_object_event_callback_del_full
+ (obj, EVAS_CALLBACK_MOUSE_MOVE, _item_mouse_move, data);
+ evas_object_event_callback_del_full
+ (obj, EVAS_CALLBACK_MOUSE_IN, _item_mouse_in, data);
+}
+/* Mouse Controls ends */
+
+static void
+_sizing_eval(Evas_Object *obj, Efl_Ui_Item_Data *pd)
+{
+ Evas_Coord minh = -1, minw = -1;
+ Evas_Coord rest_w = 0, rest_h = 0;
+ ELM_WIDGET_DATA_GET_OR_RETURN(pd->obj, wd);
+
+ edje_object_size_min_restricted_calc(wd->resize_obj, &minw, &minh,
+ rest_w, rest_h);
+ evas_object_size_hint_min_set(obj, minw, minh);
+
+ pd->needs_size_calc = EINA_FALSE;
+}
+
+static void
+_efl_ui_item_elm_layout_sizing_eval(Eo *obj, Efl_Ui_Item_Data *pd)
+{
+ if (pd->needs_size_calc) return;
+ pd->needs_size_calc = EINA_TRUE;
+
+ efl_canvas_group_change(obj);
+}
+
+EOLIAN static void
+_efl_ui_item_efl_canvas_group_group_calculate(Eo *obj, Efl_Ui_Item_Data *pd)
+{
+ if (pd->needs_size_calc)
+ {
+ _sizing_eval(obj, pd);
+ pd->needs_size_calc = EINA_FALSE;
+ }
+}
+
+EOLIAN static Eo *
+_efl_ui_item_efl_object_constructor(Eo *obj, Efl_Ui_Item_Data *pd)
+{
+ pd->obj = obj;
+ obj = efl_constructor(efl_super(obj, MY_CLASS));
+
+ return obj;
+}
+
+EOLIAN static Efl_Object *
+_efl_ui_item_efl_object_finalize(Eo *obj, Efl_Ui_Item_Data *pd EINA_UNUSED)
+{
+ Eo *eo;
+ eo = efl_finalize(efl_super(obj, MY_CLASS));
+ ELM_WIDGET_DATA_GET_OR_RETURN(eo, wd, eo);
+
+ _item_mouse_callback_add(wd->resize_obj, eo);
+ return eo;
+}
+
+EOLIAN static void
+_efl_ui_item_efl_object_destructor(Eo *obj, Efl_Ui_Item_Data *pd EINA_UNUSED)
+{
+ ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
+
+ _item_mouse_callback_del(wd->resize_obj, obj);
+ efl_destructor(efl_super(obj, MY_CLASS));
+}
+
+EOLIAN static int
+_efl_ui_item_index_get(const Eo *obj, Efl_Ui_Item_Data *pd)
+{
+ return efl_pack_index_get(pd->parent, obj);
+}
+
+EOLIAN static void
+_efl_ui_item_selected_set(Eo *obj, Efl_Ui_Item_Data *pd, Eina_Bool select)
+{
+ Eina_Bool selected = !!select;
+ ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
+ if (wd->disabled) return;
+
+ if (selected) _item_select(obj, pd);
+ else _item_unselect(obj, pd);
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_item_selected_get(const Eo *obj EINA_UNUSED, Efl_Ui_Item_Data *pd)
+{
+ return pd->selected;
+}
+
+/* Internal EO APIs and hidden overrides */
+
+#define EFL_UI_ITEM_EXTRA_OPS \
+ ELM_LAYOUT_SIZING_EVAL_OPS(efl_ui_item)
+
+#include "efl_ui_item.eo.c"
diff --git a/src/lib/elementary/efl_ui_item.eo b/src/lib/elementary/efl_ui_item.eo
new file mode 100644
index 0000000000..6137dd9fb7
--- /dev/null
+++ b/src/lib/elementary/efl_ui_item.eo
@@ -0,0 +1,30 @@
+abstract Efl.Ui.Item (Efl.Ui.Layout.Object, Efl.Ui.Selectable, Efl.Ui.Clickable)
+{
+ [[Item abstract class for pack widget. All item have to be inherited from this class.]]
+ methods {
+ @property index {
+ [[index number of item from their parent object.]]
+ get {}
+ values {
+ index : int;
+ }
+ }
+ @property selected {
+ [[Select property for item object.
+ Item can be selected by user mouse/key input also]]
+ set {}
+ get {}
+ values {
+ select: bool;
+ }
+ }
+ }
+ implements {
+ //Efl.Object
+ Efl.Object.constructor;
+ Efl.Object.finalize;
+ Efl.Object.destructor;
+ //Efl.Canvas
+ Efl.Canvas.Group.group_calculate;
+ }
+}
diff --git a/src/lib/elementary/efl_ui_item_private.h b/src/lib/elementary/efl_ui_item_private.h
new file mode 100644
index 0000000000..b8849a2316
--- /dev/null
+++ b/src/lib/elementary/efl_ui_item_private.h
@@ -0,0 +1,37 @@
+#ifndef EFL_UI_ITEM_PRIVATE_H
+#define EFL_UI_ITEM_PRIVATE_H
+
+#include "Elementary.h"
+
+typedef struct _Efl_Ui_Item_Data
+{
+ // Eo Objects
+ Eo *obj; /* Self-Object */
+ Eo *parent; /* Parent Widget */
+
+ Efl_Ui_Select_Mode *select_mode; /* Select Mdoe of parent widget */
+ Ecore_Timer *longpress_timer; /* Timer for longpress handle */
+
+ // Boolean Data
+ Eina_Bool selected : 1; /* State for item selected */
+ Eina_Bool needs_size_calc : 1; /* Flag for Size calculation */
+} Efl_Ui_Item_Data;
+
+
+#define EFL_UI_ITEM_DATA_GET(o, pd) \
+ Efl_Ui_Item_Data * pd = efl_data_scope_safe_get(o, EFL_UI_ITEM_CLASS)
+
+#define EFL_UI_ITEM_DATA_GET_OR_RETURN(o, ptr, ...) \
+ EFL_UI_ITEM_DATA_GET(o, ptr); \
+ if (EINA_UNLIKELY(!ptr)) \
+ { \
+ ERR("No widget data for object %p (%s)", \
+ o, evas_object_type_get(o)); \
+ return __VA_ARGS__; \
+ }
+
+#define EFL_UI_ITEM_CHECK_OR_RETURN(obj, ...) \
+ if (EINA_UNLIKELY(!efl_isa((obj), EFL_UI_ITEM_CLASS))) \
+ return __VA_ARGS__;
+
+#endif
diff --git a/src/lib/elementary/efl_ui_list.c b/src/lib/elementary/efl_ui_list.c
new file mode 100644
index 0000000000..bb6abf3ef3
--- /dev/null
+++ b/src/lib/elementary/efl_ui_list.c
@@ -0,0 +1,1140 @@
+#ifdef HAVE_CONFIG_H
+# include "elementary_config.h"
+#endif
+
+#define ELM_LAYOUT_PROTECTED
+#define EFL_UI_SCROLL_MANAGER_PROTECTED
+#define EFL_UI_SCROLLBAR_PROTECTED
+#define EFL_UI_SCROLLBAR_BETA
+
+#include <Elementary.h>
+#include "elm_priv.h"
+#include "efl_ui_list_item_private.h"
+#include "efl_ui_item_private.h"
+#include "efl_ui_list_private.h"
+
+#define MY_CLASS EFL_UI_LIST_CLASS
+#define MY_CLASS_PFX efl_ui_list
+
+#define MY_CLASS_NAME "Efl.Ui.List"
+
+static void
+_item_scroll_internal(Eo *obj,
+ Efl_Ui_List_Item *item,
+ double align,
+ Eina_Bool anim)
+{
+ EFL_UI_LIST_DATA_GET_OR_RETURN(obj, pd);
+ Eina_Rect ipos, view;
+ Eina_Position2D vpos;
+
+ if (!pd->smanager) return;
+
+ ipos = efl_gfx_entity_geometry_get(item);
+ view = efl_ui_scrollable_viewport_geometry_get(pd->smanager);
+ vpos = efl_ui_scrollable_content_pos_get(pd->smanager);
+
+ ipos.x = view.x;
+ ipos.w = ipos.w;
+
+ // FIXME: align case will not correctly show in the position because of
+ // bar size calculation. there are no certain way to know the scroll calcuation finished.
+ if (EINA_DBL_EQ(align, -1.0))
+ {
+ ipos.y = ipos.y + vpos.y - view.y;
+ ipos.h = ipos.h;
+ }
+ else if ((align > 0.0 || EINA_DBL_EQ(align, 0.0)) &&
+ (align < 1.0 || EINA_DBL_EQ(align, 1.0)))
+ {
+ ipos.y = ipos.y + vpos.y - view.y - (int)((view.h - ipos.h) * align);
+ ipos.h = view.h;
+ }
+ else ERR("align (%.2lf) is not proper value. it must be the value between [0.0 , 1.0]!", align);
+
+ efl_ui_scrollable_scroll(pd->smanager, ipos, anim);
+}
+
+static void
+_efl_ui_list_bar_read_and_update(Eo *obj)
+{
+ EFL_UI_LIST_DATA_GET_OR_RETURN(obj, pd);
+ ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
+ double vx = 0.0, vy = 0.0;
+
+ edje_object_part_drag_value_get
+ (wd->resize_obj, "efl.dragable.vbar", NULL, &vy);
+
+ /* FIXME: Horizontal Scroll is not yet supported in the list.
+ edje_object_part_drag_value_get
+ (wd->resize_obj, "efl.dragable.hbar", &vx, NULL);
+ */
+
+ efl_ui_scrollbar_bar_position_set(pd->smanager, vx, vy);
+}
+
+static void
+_efl_ui_list_reload_cb(void *data,
+ Evas_Object *obj EINA_UNUSED,
+ const char *emission EINA_UNUSED,
+ const char *source EINA_UNUSED)
+{
+ Eo *list = data;
+ EFL_UI_LIST_DATA_GET_OR_RETURN(list, pd);
+
+ efl_ui_scrollbar_bar_visibility_update(pd->smanager);
+}
+
+static void
+_efl_ui_list_vbar_drag_cb(void *data,
+ Evas_Object *obj EINA_UNUSED,
+ const char *emission EINA_UNUSED,
+ const char *source EINA_UNUSED)
+{
+ _efl_ui_list_bar_read_and_update(data);
+
+ Efl_Ui_Scrollbar_Direction type = EFL_UI_SCROLLBAR_DIRECTION_VERTICAL;
+ efl_event_callback_call(data, EFL_UI_SCROLLBAR_EVENT_BAR_DRAG, &type);
+}
+
+static void
+_efl_ui_list_vbar_press_cb(void *data,
+ Evas_Object *obj EINA_UNUSED,
+ const char *emission EINA_UNUSED,
+ const char *source EINA_UNUSED)
+{
+ Efl_Ui_Scrollbar_Direction type = EFL_UI_SCROLLBAR_DIRECTION_VERTICAL;
+ efl_event_callback_call(data, EFL_UI_SCROLLBAR_EVENT_BAR_PRESS, &type);
+}
+
+static void
+_efl_ui_list_vbar_unpress_cb(void *data,
+ Evas_Object *obj EINA_UNUSED,
+ const char *emission EINA_UNUSED,
+ const char *source EINA_UNUSED)
+{
+ Efl_Ui_Scrollbar_Direction type = EFL_UI_SCROLLBAR_DIRECTION_VERTICAL;
+ efl_event_callback_call(data, EFL_UI_SCROLLBAR_EVENT_BAR_UNPRESS, &type);
+}
+
+static void
+_efl_ui_list_edje_drag_start_cb(void *data,
+ Evas_Object *obj EINA_UNUSED,
+ const char *emission EINA_UNUSED,
+ const char *source EINA_UNUSED)
+{
+ Eo *list = data;
+ EFL_UI_LIST_DATA_GET_OR_RETURN(list, pd);
+
+ _efl_ui_list_bar_read_and_update(list);
+
+ pd->freeze_want = efl_ui_scrollable_scroll_freeze_get(pd->smanager);
+ efl_ui_scrollable_scroll_freeze_set(pd->smanager, EINA_TRUE);
+ efl_event_callback_call(list, EFL_UI_EVENT_SCROLL_DRAG_START, NULL);
+}
+
+static void
+_efl_ui_list_edje_drag_stop_cb(void *data,
+ Evas_Object *obj EINA_UNUSED,
+ const char *emission EINA_UNUSED,
+ const char *source EINA_UNUSED)
+{
+ Eo *list = data;
+ EFL_UI_LIST_DATA_GET_OR_RETURN(list, pd);
+
+ _efl_ui_list_bar_read_and_update(list);
+
+ efl_ui_scrollable_scroll_freeze_set(pd->smanager, pd->freeze_want);
+ efl_event_callback_call(list, EFL_UI_EVENT_SCROLL_DRAG_STOP, NULL);
+}
+
+static void
+_efl_ui_list_edje_drag_cb(void *data,
+ Evas_Object *obj EINA_UNUSED,
+ const char *emission EINA_UNUSED,
+ const char *source EINA_UNUSED)
+{
+ _efl_ui_list_bar_read_and_update(data);
+}
+
+/* FIXME: Horizontal Scroll is not yet supported in the list.
+ static void
+ _efl_ui_list_hbar_drag_cb(void *data,
+ Evas_Object *obj EINA_UNUSED,
+ const char *emission EINA_UNUSED,
+ const char *source EINA_UNUSED)
+ {
+ _efl_ui_list_bar_read_and_update(data);
+
+ Efl_Ui_Scrollbar_Direction type = EFL_UI_SCROLLBAR_DIRECTION_HORIZONTAL;
+ efl_event_callback_call(data, EFL_UI_SCROLLBAR_EVENT_BAR_DRAG, &type);
+ }
+
+ static void
+ _efl_ui_list_hbar_press_cb(void *data,
+ Evas_Object *obj EINA_UNUSED,
+ const char *emission EINA_UNUSED,
+ const char *source EINA_UNUSED)
+ {
+ Efl_Ui_Scrollbar_Direction type = EFL_UI_SCROLLBAR_DIRECTION_HORIZONTAL;
+ efl_event_callback_call(data, EFL_UI_SCROLLBAR_EVENT_BAR_PRESS, &type);
+ }
+
+ static void
+ _efl_ui_list_hbar_unpress_cb(void *data,
+ Evas_Object *obj EINA_UNUSED,
+ const char *emission EINA_UNUSED,
+ const char *source EINA_UNUSED)
+ {
+ Efl_Ui_Scrollbar_Direction type = EFL_UI_SCROLLBAR_DIRECTION_HORIZONTAL;
+ efl_event_callback_call(data, EFL_UI_SCROLLBAR_EVENT_BAR_UNPRESS, &type);
+ }
+ */
+
+static void
+_efl_ui_list_bar_size_changed_cb(void *data, const Efl_Event *event EINA_UNUSED)
+{
+ Eo *obj = data;
+ EFL_UI_LIST_DATA_GET_OR_RETURN(obj, pd);
+ ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
+
+ double width = 0.0, height = 0.0;
+
+ edje_object_calc_force(wd->resize_obj);
+ efl_ui_scrollbar_bar_size_get(pd->smanager, &width, &height);
+ edje_object_part_drag_size_set(wd->resize_obj, "efl.dragable.hbar", width, 1.0);
+ edje_object_part_drag_size_set(wd->resize_obj, "efl.dragable.vbar", 1.0, height);
+}
+
+static void
+_efl_ui_list_bar_pos_changed_cb(void *data, const Efl_Event *event EINA_UNUSED)
+{
+ Eo *obj = data;
+ EFL_UI_LIST_DATA_GET_OR_RETURN(obj, pd);
+ ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
+
+ double posx = 0.0, posy = 0.0;
+
+ efl_ui_scrollbar_bar_position_get(pd->smanager, &posx, &posy);
+ edje_object_part_drag_value_set(wd->resize_obj, "efl.dragable.hbar", posx, 0.0);
+ edje_object_part_drag_value_set(wd->resize_obj, "efl.dragable.vbar", 0.0, posy);
+}
+
+static void
+_efl_ui_list_bar_show_cb(void *data, const Efl_Event *event)
+{
+ Eo *obj = data;
+ EFL_UI_LIST_DATA_GET_OR_RETURN(obj, pd);
+ ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
+ Efl_Ui_Scrollbar_Direction type = *(Efl_Ui_Scrollbar_Direction *)(event->info);
+
+ if (type == EFL_UI_SCROLLBAR_DIRECTION_HORIZONTAL)
+ edje_object_signal_emit(wd->resize_obj, "efl,action,show,hbar", "efl");
+ else if (type == EFL_UI_SCROLLBAR_DIRECTION_VERTICAL)
+ edje_object_signal_emit(wd->resize_obj, "efl,action,show,vbar", "efl");
+}
+
+static void
+_efl_ui_list_bar_hide_cb(void *data, const Efl_Event *event)
+{
+ Eo *obj = data;
+ EFL_UI_LIST_DATA_GET_OR_RETURN(obj, pd);
+ ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
+ Efl_Ui_Scrollbar_Direction type = *(Efl_Ui_Scrollbar_Direction *)(event->info);
+
+ if (type == EFL_UI_SCROLLBAR_DIRECTION_HORIZONTAL)
+ edje_object_signal_emit(wd->resize_obj, "efl,action,hide,hbar", "efl");
+ else if (type == EFL_UI_SCROLLBAR_DIRECTION_VERTICAL)
+ edje_object_signal_emit(wd->resize_obj, "efl,action,hide,vbar", "efl");
+}
+
+static void
+_scroll_edje_object_attach(Eo *obj)
+{
+ EFL_UI_LIST_DATA_GET_OR_RETURN(obj, pd);
+
+ efl_layout_signal_callback_add
+ (obj, "reload", "efl",
+ _efl_ui_list_reload_cb, obj);
+ efl_layout_signal_callback_add
+ (obj, "drag", "efl.dragable.vbar",
+ _efl_ui_list_vbar_drag_cb, obj);
+ efl_layout_signal_callback_add
+ (obj, "drag,set", "efl.dragable.vbar",
+ _efl_ui_list_edje_drag_cb, obj);
+ efl_layout_signal_callback_add
+ (obj, "drag,start", "efl.dragable.vbar",
+ _efl_ui_list_edje_drag_start_cb, obj);
+ efl_layout_signal_callback_add
+ (obj, "drag,stop", "efl.dragable.vbar",
+ _efl_ui_list_edje_drag_stop_cb, obj);
+ efl_layout_signal_callback_add
+ (obj, "drag,step", "efl.dragable.vbar",
+ _efl_ui_list_edje_drag_cb, obj);
+ efl_layout_signal_callback_add
+ (obj, "drag,page", "efl.dragable.vbar",
+ _efl_ui_list_edje_drag_cb, obj);
+ efl_layout_signal_callback_add
+ (obj, "efl,vbar,press", "efl",
+ _efl_ui_list_vbar_press_cb, obj);
+ efl_layout_signal_callback_add
+ (obj, "efl,vbar,unpress", "efl",
+ _efl_ui_list_vbar_unpress_cb, obj);
+
+ /* FIXME: Horizontal Scroll is not yet supported in the list.
+ efl_layout_signal_callback_add
+ (obj, "drag", "efl.dragable.hbar",
+ _efl_ui_list_hbar_drag_cb, obj);
+ efl_layout_signal_callback_add
+ (obj, "drag,set", "efl.dragable.hbar",
+ _efl_ui_list_edje_drag_cb, obj);
+ efl_layout_signal_callback_add
+ (obj, "drag,start", "efl.dragable.hbar",
+ _efl_ui_list_edje_drag_start_cb, obj);
+ efl_layout_signal_callback_add
+ (obj, "drag,stop", "efl.dragable.hbar",
+ _efl_ui_list_edje_drag_stop_cb, obj);
+ efl_layout_signal_callback_add
+ (obj, "drag,step", "efl.dragable.hbar",
+ _efl_ui_list_edje_drag_cb, obj);
+ efl_layout_signal_callback_add
+ (obj, "drag,page", "efl.dragable.hbar",
+ _efl_ui_list_edje_drag_cb, obj);
+ efl_layout_signal_callback_add
+ (obj, "efl,hbar,press", "efl",
+ _efl_ui_list_hbar_press_cb, obj);
+ efl_layout_signal_callback_add
+ (obj, "efl,hbar,unpress", "efl",
+ _efl_ui_list_hbar_unpress_cb, obj);
+ */
+}
+
+static void
+_scroll_edje_object_detach(Eo *obj)
+{
+ EFL_UI_LIST_DATA_GET_OR_RETURN(obj, pd);
+
+ efl_layout_signal_callback_del
+ (obj, "reload", "efl",
+ _efl_ui_list_reload_cb, obj);
+ efl_layout_signal_callback_del
+ (obj, "drag", "efl.dragable.vbar",
+ _efl_ui_list_vbar_drag_cb, obj);
+ efl_layout_signal_callback_del
+ (obj, "drag,set", "efl.dragable.vbar",
+ _efl_ui_list_edje_drag_cb, obj);
+ efl_layout_signal_callback_del
+ (obj, "drag,start", "efl.dragable.vbar",
+ _efl_ui_list_edje_drag_start_cb, obj);
+ efl_layout_signal_callback_del
+ (obj, "drag,stop", "efl.dragable.vbar",
+ _efl_ui_list_edje_drag_stop_cb, obj);
+ efl_layout_signal_callback_del
+ (obj, "drag,step", "efl.dragable.vbar",
+ _efl_ui_list_edje_drag_cb, obj);
+ efl_layout_signal_callback_del
+ (obj, "drag,page", "efl.dragable.vbar",
+ _efl_ui_list_edje_drag_cb, obj);
+ efl_layout_signal_callback_del
+ (obj, "efl,vbar,press", "efl",
+ _efl_ui_list_vbar_press_cb, obj);
+ efl_layout_signal_callback_del
+ (obj, "efl,vbar,unpress", "efl",
+ _efl_ui_list_vbar_unpress_cb, obj);
+
+ /* FIXME: Horizontal Scroll is not yet supported in the list.
+ efl_layout_signal_callback_del
+ (obj, "drag", "efl.dragable.hbar",
+ _efl_ui_list_hbar_drag_cb, obj);
+ efl_layout_signal_callback_del
+ (obj, "drag,set", "efl.dragable.hbar",
+ _efl_ui_list_edje_drag_cb, obj);
+ efl_layout_signal_callback_del
+ (obj, "drag,start", "efl.dragable.hbar",
+ _efl_ui_list_edje_drag_start_cb, obj);
+ efl_layout_signal_callback_del
+ (obj, "drag,stop", "efl.dragable.hbar",
+ _efl_ui_list_edje_drag_stop_cb, obj);
+ efl_layout_signal_callback_del
+ (obj, "drag,step", "efl.dragable.hbar",
+ _efl_ui_list_edje_drag_cb, obj);
+ efl_layout_signal_callback_del
+ (obj, "drag,page", "efl.dragable.hbar",
+ _efl_ui_list_edje_drag_cb, obj);
+ efl_layout_signal_callback_del
+ (obj, "efl,hbar,press", "efl",
+ _efl_ui_list_hbar_press_cb, obj);
+ efl_layout_signal_callback_del
+ (obj, "efl,hbar,unpress", "efl",
+ _efl_ui_list_hbar_unpress_cb, obj);
+ */
+}
+
+static void
+_efl_ui_list_pan_resized_cb(void *data, const Efl_Event *ev EINA_UNUSED)
+{
+ Eo *obj = data;
+ EFL_UI_LIST_DATA_GET_OR_RETURN(obj, pd);
+ if (!pd->smanager) return;
+
+ elm_layout_sizing_eval(obj);
+
+ if (!pd->pan_resized)
+ {
+ Eina_Rect view = efl_ui_scrollable_viewport_geometry_get(pd->smanager);
+ // FIXME: Below code is workaround size check
+ if (view.h > 1)
+ {
+ pd->pan_resized = EINA_TRUE;
+ if (pd->scroll.item)
+ {
+ _item_scroll_internal(obj, pd->scroll.item, pd->scroll.align, pd->scroll.anim);
+
+ pd->scroll.item = NULL;
+ pd->scroll.align = 0.0;
+ pd->scroll.anim = EINA_FALSE;
+ return;
+ }
+ }
+ }
+}
+
+static void
+_efl_ui_list_resized_cb(void *data, const Efl_Event *ev EINA_UNUSED)
+{
+ elm_layout_sizing_eval(data);
+}
+
+static void
+_efl_ui_list_size_hint_changed_cb(void *data, const Efl_Event *ev EINA_UNUSED)
+{
+ elm_layout_sizing_eval(data);
+}
+
+EOLIAN static Eo *
+_efl_ui_list_efl_object_constructor(Eo *obj, Efl_Ui_List_Data *pd EINA_UNUSED)
+{
+ obj = efl_constructor(efl_super(obj, MY_CLASS));
+
+ return obj;
+}
+
+EOLIAN static Eo *
+_efl_ui_list_efl_object_finalize(Eo *obj,
+ Efl_Ui_List_Data *pd)
+{
+ obj = efl_finalize(efl_super(obj, MY_CLASS));
+
+ ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, NULL);
+
+ efl_ui_layout_object_theme_set(obj, "list", "base", efl_ui_widget_style_get(obj));
+
+ pd->smanager = efl_add(EFL_UI_SCROLL_MANAGER_CLASS, obj);
+ efl_ui_mirrored_set(pd->smanager, efl_ui_mirrored_get(obj));
+
+ pd->pan = efl_add(EFL_UI_PAN_CLASS, obj);
+
+ efl_ui_scroll_manager_pan_set(pd->smanager, pd->pan);
+ edje_object_part_swallow(wd->resize_obj, "efl.content", pd->pan);
+
+ pd->box = efl_add(EFL_UI_BOX_CLASS, obj,
+ efl_ui_direction_set(efl_added, EFL_UI_DIR_VERTICAL));
+ efl_ui_mirrored_set(pd->box, efl_ui_mirrored_get(obj));
+ efl_content_set(pd->pan, pd->box);
+
+ pd->select_mode = EFL_UI_SELECT_SINGLE;
+
+ _scroll_edje_object_attach(obj);
+
+ efl_event_callback_add(obj, EFL_UI_SCROLLBAR_EVENT_BAR_SIZE_CHANGED,
+ _efl_ui_list_bar_size_changed_cb, obj);
+ efl_event_callback_add(obj, EFL_UI_SCROLLBAR_EVENT_BAR_POS_CHANGED,
+ _efl_ui_list_bar_pos_changed_cb, obj);
+ efl_event_callback_add(obj, EFL_UI_SCROLLBAR_EVENT_BAR_SHOW,
+ _efl_ui_list_bar_show_cb, obj);
+ efl_event_callback_add(obj, EFL_UI_SCROLLBAR_EVENT_BAR_HIDE,
+ _efl_ui_list_bar_hide_cb, obj);
+ efl_event_callback_add(obj, EFL_GFX_ENTITY_EVENT_RESIZE,
+ _efl_ui_list_resized_cb, obj);
+ efl_event_callback_add(obj, EFL_GFX_ENTITY_EVENT_CHANGE_SIZE_HINTS,
+ _efl_ui_list_size_hint_changed_cb, obj);
+ efl_event_callback_add(pd->pan, EFL_GFX_ENTITY_EVENT_RESIZE,
+ _efl_ui_list_pan_resized_cb, obj);
+
+ elm_layout_sizing_eval(obj);
+
+ return obj;
+}
+
+EOLIAN static void
+_efl_ui_list_efl_object_destructor(Eo *obj, Efl_Ui_List_Data *pd)
+{
+ _scroll_edje_object_detach(obj);
+
+ efl_event_callback_del(obj, EFL_UI_SCROLLBAR_EVENT_BAR_SIZE_CHANGED,
+ _efl_ui_list_bar_size_changed_cb, obj);
+ efl_event_callback_del(obj, EFL_UI_SCROLLBAR_EVENT_BAR_POS_CHANGED,
+ _efl_ui_list_bar_pos_changed_cb, obj);
+ efl_event_callback_del(obj, EFL_UI_SCROLLBAR_EVENT_BAR_SHOW,
+ _efl_ui_list_bar_show_cb, obj);
+ efl_event_callback_del(obj, EFL_UI_SCROLLBAR_EVENT_BAR_HIDE,
+ _efl_ui_list_bar_hide_cb, obj);
+ efl_event_callback_del(obj, EFL_GFX_ENTITY_EVENT_RESIZE,
+ _efl_ui_list_resized_cb, obj);
+ efl_event_callback_del(obj, EFL_GFX_ENTITY_EVENT_CHANGE_SIZE_HINTS,
+ _efl_ui_list_size_hint_changed_cb, obj);
+ efl_event_callback_del(pd->pan, EFL_GFX_ENTITY_EVENT_RESIZE,
+ _efl_ui_list_pan_resized_cb, obj);
+
+ efl_del(pd->box);
+ pd->box = NULL;
+ efl_del(pd->pan);
+ pd->pan = NULL;
+ efl_del(pd->smanager);
+ pd->smanager = NULL;
+
+ efl_destructor(efl_super(obj, MY_CLASS));
+}
+
+EOLIAN static void
+_efl_ui_list_efl_canvas_group_group_calculate(Eo *obj EINA_UNUSED, Efl_Ui_List_Data *pd EINA_UNUSED)
+{
+ // Need to be implemented
+ efl_canvas_group_calculate(efl_super(obj, MY_CLASS));
+}
+
+EOLIAN static void
+_efl_ui_list_elm_layout_sizing_eval(Eo *obj, Efl_Ui_List_Data *pd)
+{
+ Eina_Size2D min = {0, 0}, max = {0, 0}, size = {-1, -1};
+ Eina_Rect view = {};
+ Evas_Coord vmw = 0, vmh = 0;
+ double xw = 0.0, yw = 0.0;
+
+ ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
+
+ if (pd->box)
+ {
+ min = efl_gfx_size_hint_combined_min_get(pd->box);
+ max = efl_gfx_size_hint_max_get(pd->box);
+ efl_gfx_size_hint_weight_get(pd->box, &xw, &yw);
+ }
+
+ if (pd->smanager)
+ view = efl_ui_scrollable_viewport_geometry_get(pd->smanager);
+
+ if (xw > 0.0)
+ {
+ if ((min.w > 0) && (view.w < min.w))
+ view.w = min.w;
+ else if ((max.w > 0) && (view.w > max.w))
+ view.w = max.w;
+ }
+ else if (min.w > 0)
+ view.w = min.w;
+
+ if (yw > 0.0)
+ {
+ if ((min.h > 0) && (view.h < min.h))
+ view.h = min.h;
+ else if ((max.h > 0) && (view.h > max.h))
+ view.h = max.h;
+ }
+ else if (min.h > 0)
+ view.h = min.h;
+
+ if (pd->box) efl_gfx_entity_size_set(pd->box, EINA_SIZE2D(view.w, view.h));
+
+ edje_object_size_min_calc(wd->resize_obj, &vmw, &vmh);
+
+ if (pd->match_content_w) size.w = vmw + min.w;
+ if (pd->match_content_h) size.h = vmh + min.h;
+
+ max = efl_gfx_size_hint_max_get(obj);
+ if ((max.w > 0) && (size.w > max.w)) size.w = max.w;
+ if ((max.h > 0) && (size.h > max.h)) size.h = max.h;
+
+ efl_gfx_size_hint_min_set(obj, size);
+}
+
+//FIXME: is this box related API could be improved more?
+EOLIAN static int
+_efl_ui_list_efl_container_content_count(Eo *obj EINA_UNUSED, Efl_Ui_List_Data *pd)
+{
+ return pd->box ? efl_content_count(pd->box) : 0;
+}
+
+EOLIAN static Eina_Iterator *
+_efl_ui_list_efl_container_content_iterate(Eo *obj EINA_UNUSED, Efl_Ui_List_Data *pd)
+{
+ return pd->box ? efl_content_iterate(pd->box) : NULL;
+}
+
+/* FIXME: Direction is not supported yet in the list
+ EOLIAN static void
+ _efl_ui_list_efl_ui_direction_direction_set(Eo *obj, Efl_Ui_List_Data *pd, Efl_Ui_Dir dir)
+ {
+ switch (dir)
+ {
+ case EFL_UI_DIR_RTL:
+ // FIXME: Should be inverted!
+ case EFL_UI_DIR_HORIZONTAL:
+ case EFL_UI_DIR_LTR:
+ pd->dir = EFL_UI_DIR_HORIZONTAL;
+ break;
+
+ case EFL_UI_DIR_UP:
+ // FIXME: Should be inverted!
+ case EFL_UI_DIR_DOWN:
+ case EFL_UI_DIR_VERTICAL:
+ case EFL_UI_DIR_DEFAULT:
+ default:
+ pd->dir = EFL_UI_DIR_VERTICAL;
+ break;
+ }
+
+ efl_pack_layout_request(obj);
+ }
+ */
+
+EOLIAN static Efl_Ui_Theme_Apply
+_efl_ui_list_efl_ui_widget_theme_apply(Eo *obj, Efl_Ui_List_Data *pd)
+{
+ Efl_Ui_Theme_Apply int_ret = EFL_UI_THEME_APPLY_FAILED;
+ int_ret = efl_ui_widget_theme_apply(efl_super(obj, MY_CLASS));
+ if (!int_ret) return EFL_UI_THEME_APPLY_FAILED;
+
+ efl_ui_mirrored_set(pd->smanager, efl_ui_mirrored_get(obj));
+
+ elm_layout_sizing_eval(obj);
+
+ return int_ret;
+}
+
+static void
+_list_item_pressed(void *data, const Efl_Event *event)
+{
+ Eo *obj = data;
+ Efl_Ui_List_Item *item = event->object;
+ efl_event_callback_call(obj, EFL_UI_EVENT_PRESSED, item);
+}
+
+static void
+_list_item_unpressed(void *data, const Efl_Event *event)
+{
+ Eo *obj = data;
+ Efl_Ui_List_Item *item = event->object;
+ efl_event_callback_call(obj, EFL_UI_EVENT_UNPRESSED, item);
+}
+
+static void
+_list_item_longpressed(void *data, const Efl_Event *event)
+{
+ Eo *obj = data;
+ Efl_Ui_List_Item *item = event->object;
+ efl_event_callback_call(obj, EFL_UI_EVENT_LONGPRESSED, item);
+}
+
+static void
+_list_item_selected(void *data, const Efl_Event *event)
+{
+ Eo *obj = data;
+ Efl_Ui_List_Item *item = event->object;
+ Efl_Ui_List_Item *selected;
+ EFL_UI_LIST_DATA_GET_OR_RETURN(obj, pd);
+
+ /* Single Select */
+ if (pd->select_mode != EFL_UI_SELECT_MULTI)
+ {
+ EINA_LIST_FREE(pd->selected, selected)
+ {
+ if (selected != item)
+ efl_ui_item_selected_set(selected, EINA_FALSE);
+ }
+ }
+ pd->selected = eina_list_append(pd->selected, item);
+ pd->last_selected = item;
+
+ efl_event_callback_call(obj, EFL_UI_EVENT_SELECTED, item);
+}
+
+static void
+_list_item_unselected(void *data, const Efl_Event *event)
+{
+ Eo *obj = data;
+ Efl_Ui_List_Item *item = event->object;
+ EFL_UI_LIST_DATA_GET_OR_RETURN(obj, pd);
+
+ pd->selected = eina_list_remove(pd->selected, item);
+ if (pd->last_selected == item) pd->last_selected = NULL;
+
+ efl_event_callback_call(obj, EFL_UI_EVENT_UNSELECTED, item);
+}
+
+static Eina_Bool
+_list_item_process(Eo *obj, Efl_Ui_List_Data *pd, EINA_UNUSED Efl_Ui_List_Item *it)
+{
+ EFL_UI_LIST_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
+
+ //FIXME: This is tricky workaround for set select mode and parent value.
+ EFL_UI_LIST_ITEM_DATA_GET(it, ld);
+ EFL_UI_ITEM_DATA_GET(it, id);
+ id->select_mode = &(pd->select_mode);
+ id->parent = obj;
+ ld->parent = obj;
+ efl_ui_mirrored_set(it, efl_ui_mirrored_get(obj));
+
+ efl_event_callback_add(it, EFL_UI_EVENT_PRESSED, _list_item_pressed, obj);
+ efl_event_callback_add(it, EFL_UI_EVENT_UNPRESSED, _list_item_unpressed, obj);
+ efl_event_callback_add(it, EFL_UI_EVENT_LONGPRESSED, _list_item_longpressed, obj);
+ efl_event_callback_add(it, EFL_UI_EVENT_SELECTED, _list_item_selected, obj);
+ efl_event_callback_add(it, EFL_UI_EVENT_UNSELECTED, _list_item_unselected, obj);
+
+ return EINA_TRUE;
+}
+
+static void
+_list_item_clear(Eo *obj, Efl_Ui_List_Data *pd EINA_UNUSED, EINA_UNUSED Efl_Ui_List_Item *it)
+{
+ EFL_UI_LIST_ITEM_CHECK_OR_RETURN(it);
+ EFL_UI_LIST_ITEM_DATA_GET(it, ld);
+ EFL_UI_ITEM_DATA_GET(it, id);
+ id->select_mode = NULL;
+ id->parent = NULL;
+ ld->parent = NULL;
+
+ efl_event_callback_del(it, EFL_UI_EVENT_PRESSED, _list_item_pressed, obj);
+ efl_event_callback_del(it, EFL_UI_EVENT_UNPRESSED, _list_item_unpressed, obj);
+ efl_event_callback_del(it, EFL_UI_EVENT_LONGPRESSED, _list_item_longpressed, obj);
+ efl_event_callback_del(it, EFL_UI_EVENT_SELECTED, _list_item_selected, obj);
+ efl_event_callback_del(it, EFL_UI_EVENT_UNSELECTED, _list_item_unselected, obj);
+}
+
+/* Pack APIs */
+EOLIAN static Eina_Bool
+_efl_ui_list_efl_pack_pack_clear(Eo *obj, Efl_Ui_List_Data *pd)
+{
+ Eina_Bool ret = efl_pack_clear(pd->box);
+
+ if (ret)
+ {
+ eina_list_free(pd->items);
+ eina_list_free(pd->selected);
+ pd->items = NULL;
+ pd->selected = NULL;
+ }
+
+ elm_layout_sizing_eval(obj);
+ return ret;
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_list_efl_pack_unpack_all(Eo *obj, Efl_Ui_List_Data *pd)
+{
+ Eina_Bool ret = efl_pack_unpack_all(pd->box);
+
+ if (ret)
+ {
+ Efl_Ui_List_Item *it = NULL;
+ EINA_LIST_FREE(pd->items, it)
+ {
+ _list_item_clear(obj, pd, it);
+ }
+ eina_list_free(pd->selected);
+ pd->items = NULL;
+ pd->selected = NULL;
+ }
+
+ elm_layout_sizing_eval(obj);
+ return ret;
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_list_efl_pack_unpack(Eo *obj, Efl_Ui_List_Data *pd, Efl_Gfx_Entity *subobj)
+{
+ Eina_Bool ret = efl_pack_unpack(pd->box, subobj);
+ Efl_Ui_List_Item *item = (Efl_Ui_List_Item *)subobj;
+
+ if (ret)
+ {
+ pd->items = eina_list_remove(pd->items, item);
+ if (efl_ui_item_selected_get(item))
+ {
+ pd->selected = eina_list_remove(pd->selected, item);
+ }
+ _list_item_clear(obj, pd, item);
+ }
+
+ elm_layout_sizing_eval(obj);
+ return ret;
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_list_efl_pack_pack(Eo *obj, Efl_Ui_List_Data *pd, Efl_Gfx_Entity *subobj)
+{
+ if (!_list_item_process(obj, pd, subobj)) return EINA_FALSE;
+
+ Eina_Bool ret = efl_pack_end(pd->box, subobj);
+ pd->items = eina_list_append(pd->items, subobj);
+ return ret;
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_list_efl_pack_linear_pack_end(Eo *obj, Efl_Ui_List_Data *pd, Efl_Gfx_Entity *subobj)
+{
+ if (!_list_item_process(obj, pd, subobj)) return EINA_FALSE;
+
+ Eina_Bool ret = efl_pack_end(pd->box, subobj);
+ pd->items = eina_list_append(pd->items, subobj);
+ return ret;
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_list_efl_pack_linear_pack_begin(Eo *obj, Efl_Ui_List_Data *pd, Efl_Gfx_Entity *subobj)
+{
+ if (!_list_item_process(obj, pd, subobj)) return EINA_FALSE;
+
+ Eina_Bool ret = efl_pack_begin(pd->box, subobj);
+ pd->items = eina_list_prepend(pd->items, subobj);
+ return ret;
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_list_efl_pack_linear_pack_before(Eo *obj,
+ Efl_Ui_List_Data *pd,
+ Efl_Gfx_Entity *subobj,
+ const Efl_Gfx_Entity *existing)
+{
+ if (!_list_item_process(obj, pd, subobj)) return EINA_FALSE;
+ EFL_UI_LIST_ITEM_CHECK_OR_RETURN(existing, EINA_FALSE);
+
+ Eina_Bool ret = efl_pack_before(pd->box, subobj, existing);
+ pd->items = eina_list_prepend_relative(pd->items, subobj, existing);
+ return ret;
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_list_efl_pack_linear_pack_after(Eo *obj,
+ Efl_Ui_List_Data *pd,
+ Efl_Gfx_Entity *subobj,
+ const Efl_Gfx_Entity *existing)
+{
+ if (!_list_item_process(obj, pd, subobj)) return EINA_FALSE;
+ EFL_UI_LIST_ITEM_CHECK_OR_RETURN(existing, EINA_FALSE);
+
+ Eina_Bool ret = efl_pack_after(pd->box, subobj, existing);
+ pd->items = eina_list_append_relative(pd->items, subobj, existing);
+ return ret;
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_list_efl_pack_linear_pack_at(Eo *obj,
+ Efl_Ui_List_Data *pd,
+ Efl_Gfx_Entity *subobj,
+ int index)
+{
+ if (!_list_item_process(obj, pd, subobj)) return EINA_FALSE;
+ Efl_Ui_List_Item *existing = efl_pack_content_get(pd->box, index);
+
+ Eina_Bool ret = efl_pack_at(pd->box, subobj, index);
+ pd->items = eina_list_append_relative(pd->items, subobj, existing);
+ return ret;
+}
+
+EOLIAN static Efl_Gfx_Entity *
+_efl_ui_list_efl_pack_linear_pack_content_get(Eo *obj EINA_UNUSED, Efl_Ui_List_Data *pd, int index)
+{
+ return efl_pack_content_get(pd->box, index);
+}
+
+EOLIAN static Efl_Gfx_Entity *
+_efl_ui_list_efl_pack_linear_pack_unpack_at(Eo *obj EINA_UNUSED, Efl_Ui_List_Data *pd, int index)
+{
+ return efl_pack_unpack_at(pd->box, index);
+}
+
+EOLIAN static int
+_efl_ui_list_efl_pack_linear_pack_index_get(Eo *obj EINA_UNUSED,
+ Efl_Ui_List_Data *pd,
+ const Efl_Gfx_Entity *subobj)
+{
+ return efl_pack_index_get(pd->box, subobj);
+}
+
+EOLIAN static void
+_efl_ui_list_efl_pack_layout_layout_update(Eo *obj, Efl_Ui_List_Data *pd)
+{
+ efl_pack_layout_update(pd->box);
+ elm_layout_sizing_eval(obj);
+
+ efl_event_callback_legacy_call(obj, EFL_PACK_EVENT_LAYOUT_UPDATED, NULL);
+}
+
+EOLIAN static void
+_efl_ui_list_efl_pack_layout_layout_request(Eo *obj, Efl_Ui_List_Data *pd)
+{
+ efl_pack_layout_request(pd->box);
+ elm_layout_sizing_eval(obj);
+}
+
+EOLIAN static void
+_efl_ui_list_efl_pack_pack_padding_set(Eo *obj EINA_UNUSED,
+ Efl_Ui_List_Data *pd,
+ double h,
+ double v,
+ Eina_Bool scalable)
+{
+ efl_pack_padding_set(pd->box, h, v, scalable);
+}
+
+EOLIAN static void
+_efl_ui_list_efl_pack_pack_padding_get(const Eo *obj EINA_UNUSED,
+ Efl_Ui_List_Data *pd,
+ double *h,
+ double *v,
+ Eina_Bool *scalable)
+{
+ efl_pack_padding_get(pd->box, h, v, scalable);
+}
+
+/* FIXME: align could not work properly on the list
+ EOLIAN static void
+ _efl_ui_list_efl_pack_pack_align_set(Eo *obj, Efl_Ui_List_Data *pd, double h, double v)
+ {
+ efl_pack_align_set(pd->box, h, v);
+ }
+
+ EOLIAN static void
+ _efl_ui_list_efl_pack_pack_align_get(Eo *obj EINA_UNUSED, Efl_Ui_List_Data *pd, double *h, double *v)
+ {
+ efl_pack_align_get(pd->box, &h, &v);
+ }
+ */
+
+/* Scroll APIs */
+EOLIAN static Eina_Size2D
+_efl_ui_list_efl_ui_scrollable_interactive_content_size_get(const Eo *obj EINA_UNUSED,
+ Efl_Ui_List_Data *pd)
+{
+ return efl_ui_scrollable_content_size_get(pd->smanager);
+}
+
+EOLIAN static Eina_Rect
+_efl_ui_list_efl_ui_scrollable_interactive_viewport_geometry_get(const Eo *obj EINA_UNUSED,
+ Efl_Ui_List_Data *pd)
+{
+ return efl_ui_scrollable_viewport_geometry_get(pd->smanager);
+}
+
+EOLIAN static void
+_efl_ui_list_efl_ui_scrollable_interactive_bounce_enabled_set(Eo *obj EINA_UNUSED,
+ Efl_Ui_List_Data *pd,
+ Eina_Bool horiz,
+ Eina_Bool vert)
+{
+ efl_ui_scrollable_bounce_enabled_set(pd->smanager, horiz, vert);
+}
+
+EOLIAN static void
+_efl_ui_list_efl_ui_scrollable_interactive_bounce_enabled_get(const Eo *obj EINA_UNUSED,
+ Efl_Ui_List_Data *pd,
+ Eina_Bool *horiz,
+ Eina_Bool *vert)
+{
+ efl_ui_scrollable_bounce_enabled_get(pd->smanager, horiz, vert);
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_list_efl_ui_scrollable_interactive_scroll_hold_get(const Eo *obj EINA_UNUSED,
+ Efl_Ui_List_Data *pd)
+{
+ return efl_ui_scrollable_scroll_hold_get(pd->smanager);
+}
+
+EOLIAN static void
+_efl_ui_list_efl_ui_scrollable_interactive_scroll_hold_set(Eo *obj EINA_UNUSED,
+ Efl_Ui_List_Data *pd,
+ Eina_Bool hold)
+{
+ efl_ui_scrollable_scroll_hold_set(pd->smanager, hold);
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_list_efl_ui_scrollable_interactive_scroll_freeze_get(const Eo *obj EINA_UNUSED,
+ Efl_Ui_List_Data *pd)
+{
+ return efl_ui_scrollable_scroll_freeze_get(pd->smanager);
+}
+
+EOLIAN static void
+_efl_ui_list_efl_ui_scrollable_interactive_scroll_freeze_set(Eo *obj EINA_UNUSED,
+ Efl_Ui_List_Data *pd,
+ Eina_Bool freeze)
+{
+ efl_ui_scrollable_scroll_freeze_set(pd->smanager, freeze);
+}
+
+EOLIAN static void
+_efl_ui_list_efl_ui_scrollable_interactive_match_content_set(Eo *obj EINA_UNUSED,
+ Efl_Ui_List_Data *pd,
+ Eina_Bool match_content_w,
+ Eina_Bool match_content_h)
+{
+ pd->match_content_w = !!match_content_w;
+ pd->match_content_h = !!match_content_h;
+
+ efl_ui_scrollable_match_content_set(pd->smanager, match_content_w, match_content_h);
+
+ elm_layout_sizing_eval(obj);
+}
+
+EOLIAN static void
+_efl_ui_list_efl_ui_scrollbar_bar_mode_set(Eo *obj EINA_UNUSED,
+ Efl_Ui_List_Data *pd,
+ Efl_Ui_Scrollbar_Mode hmode,
+ Efl_Ui_Scrollbar_Mode vmode)
+{
+ efl_ui_scrollbar_bar_mode_set(pd->smanager, hmode, vmode);
+}
+
+EOLIAN static void
+_efl_ui_list_efl_ui_scrollbar_bar_mode_get(const Eo *obj EINA_UNUSED,
+ Efl_Ui_List_Data *pd,
+ Efl_Ui_Scrollbar_Mode *hmode,
+ Efl_Ui_Scrollbar_Mode *vmode)
+{
+ efl_ui_scrollbar_bar_mode_get(pd->smanager, hmode, vmode);
+}
+
+EOLIAN static void
+_efl_ui_list_efl_ui_scrollable_interactive_scroll(Eo *obj EINA_UNUSED,
+ Efl_Ui_List_Data *pd,
+ Eina_Rect rc,
+ Eina_Bool animation)
+{
+ efl_ui_scrollable_scroll(pd->smanager, rc, animation);
+}
+
+EOLIAN static void
+_efl_ui_list_efl_ui_multi_selectable_select_mode_set(Eo *obj EINA_UNUSED,
+ Efl_Ui_List_Data *pd,
+ Efl_Ui_Select_Mode mode)
+{
+ Efl_Ui_List_Item *selected;
+
+ if ((pd->select_mode == EFL_UI_SELECT_MULTI &&
+ mode != EFL_UI_SELECT_MULTI) ||
+ mode == EFL_UI_SELECT_NONE)
+ {
+ Eina_List *clone = eina_list_clone(pd->selected);
+ EINA_LIST_FREE(clone, selected)
+ efl_ui_item_selected_set(selected, EINA_FALSE);
+ }
+
+ pd->select_mode = mode;
+}
+
+EOLIAN static Efl_Ui_Select_Mode
+_efl_ui_list_efl_ui_multi_selectable_select_mode_get(const Eo *obj EINA_UNUSED, Efl_Ui_List_Data *pd)
+{
+ return pd->select_mode;
+}
+
+/* List APIs */
+EOLIAN static void
+_efl_ui_list_item_scroll(Eo *obj,
+ Efl_Ui_List_Data *pd,
+ Efl_Ui_List_Item *item,
+ Eina_Bool animation)
+{
+ // Need to be implemented here.
+ if (pd->pan_resized)
+ {
+ _item_scroll_internal(obj, item, -1.0, animation);
+ }
+ else
+ {
+ pd->scroll.item = item;
+ pd->scroll.align = -1.0;
+ pd->scroll.anim = animation;
+ }
+}
+
+EOLIAN static void
+_efl_ui_list_item_scroll_align(Eo *obj,
+ Efl_Ui_List_Data *pd,
+ Efl_Ui_List_Item *item,
+ double align,
+ Eina_Bool animation)
+{
+ // Need to be implemented here.
+ if (pd->pan_resized)
+ {
+ _item_scroll_internal(obj, item, align, animation);
+ }
+ else
+ {
+ pd->scroll.item = item;
+ pd->scroll.align = align;
+ pd->scroll.anim = animation;
+ }
+}
+
+EOLIAN static Efl_Ui_List_Item *
+_efl_ui_list_last_selected_item_get(const Eo *obj EINA_UNUSED, Efl_Ui_List_Data *pd)
+{
+ return pd->last_selected;
+}
+
+static Eina_Bool
+_list_item_iterator_next(Item_Iterator *it, void **data)
+{
+ Efl_Ui_List_Item *item;
+
+ if (!eina_iterator_next(it->real_iterator, (void **)&item))
+ return EINA_FALSE;
+
+ if (data) *data = item;
+ return EINA_TRUE;
+}
+
+static Eo *
+_list_item_iterator_get_container(Item_Iterator *it)
+{
+ return it->object;
+}
+
+static void
+_list_item_iterator_free(Item_Iterator *it)
+{
+ eina_iterator_free(it->real_iterator);
+ eina_list_free(it->list);
+ free(it);
+}
+
+EOLIAN static Eina_Iterator *
+_efl_ui_list_selected_items_get(Eo *obj, Efl_Ui_List_Data *pd)
+{
+ Item_Iterator *item;
+
+ item = calloc(1, sizeof(*item));
+ if (!item) return NULL;
+
+ EINA_MAGIC_SET(&item->iterator, EINA_MAGIC_ITERATOR);
+
+ item->list = eina_list_clone(pd->selected);
+ item->real_iterator = eina_list_iterator_new(item->list);
+ item->iterator.version = EINA_ITERATOR_VERSION;
+ item->iterator.next = FUNC_ITERATOR_NEXT(_list_item_iterator_next);
+ item->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(_list_item_iterator_get_container);
+ item->iterator.free = FUNC_ITERATOR_FREE(_list_item_iterator_free);
+ item->object = obj;
+
+ return &item->iterator;
+}
+
+/* Internal EO APIs and hidden overrides */
+#define EFL_UI_LIST_EXTRA_OPS \
+ ELM_LAYOUT_SIZING_EVAL_OPS(efl_ui_list)
+
+#include "efl_ui_list.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..b97e5b5b99
--- /dev/null
+++ b/src/lib/elementary/efl_ui_list.eo
@@ -0,0 +1,93 @@
+import efl_ui_list_item;
+
+class Efl.Ui.List (Efl.Ui.Layout.Object,
+ Efl.Ui.Scrollable_Interactive,
+ Efl.Ui.Scrollbar,
+ Efl.Pack_Linear, Efl.Pack_Layout,
+ Efl.Ui.Clickable,
+ Efl.Ui.Selectable,
+ Efl.Ui.Multi_Selectable)
+{
+ [[Simple list widget with Pack interface.]]
+ methods {
+ item_scroll {
+ [[scroll move the item to show in the viewport.]]
+ params {
+ @in item: Efl.Ui.List_Item; [[Target item.]]
+ @in animation: bool; [[Boolean value for animation of scroll move.]]
+ }
+ }
+ item_scroll_align {
+ [[scroll move the item to show at the align position of the viewport.]]
+ params {
+ @in item: Efl.Ui.List_Item; [[Target item.]]
+ @in align: double; [[align value in Viewport.]]
+ @in animation: bool; [[Boolean value for animation of scroll move.]]
+ }
+ }
+ @property last_selected_item {
+ [[Property data of last selected item.]]
+ get {}
+ values {
+ return: Efl.Ui.List_Item; [[last selected item of list.]]
+ }
+ }
+ selected_items_get {
+ [[Get the selected items iterator. The iterator sequence will be decided by selection.]]
+ return: iterator<Efl.Ui.List_Item> @owned @warn_unused; [[Iterator covered by selected items list.
+ user have to free the iterator after used.]]
+ }
+ }
+ implements {
+ //Efl.Object
+ Efl.Object.constructor;
+ Efl.Object.finalize;
+ Efl.Object.destructor;
+
+ //Efl.Canvas
+ Efl.Canvas.Group.group_calculate;
+
+ //Efl.Container
+ Efl.Container.content_iterate;
+ Efl.Container.content_count;
+
+ //Efl.Ui.Direction.direction { get; set; } //TODO
+
+ //Efl.Ui.Widget
+ Efl.Ui.Widget.theme_apply;
+
+ //Efl.Ui.Focus
+ //Efl.Ui.Focus.Object.on_focus_update;
+
+ //Efl.Pack
+ Efl.Pack.pack_clear;
+ Efl.Pack.unpack_all;
+ Efl.Pack.unpack;
+ Efl.Pack.pack;
+ Efl.Pack_Linear.pack_begin;
+ Efl.Pack_Linear.pack_end;
+ Efl.Pack_Linear.pack_before;
+ Efl.Pack_Linear.pack_after;
+ Efl.Pack_Linear.pack_at;
+ Efl.Pack_Linear.pack_content_get;
+ Efl.Pack_Linear.pack_unpack_at;
+ Efl.Pack_Linear.pack_index_get;
+ Efl.Pack_Layout.layout_update;
+ Efl.Pack_Layout.layout_request;
+ Efl.Pack.pack_padding { get; set; }
+ //Efl.Pack.pack_align { get; set; }
+
+ //Efl.Ui.Scrollable
+ Efl.Ui.Scrollable_Interactive.scroll;
+ Efl.Ui.Scrollable_Interactive.content_size{ get; }
+ Efl.Ui.Scrollable_Interactive.viewport_geometry{ get; }
+ Efl.Ui.Scrollable_Interactive.bounce_enabled { set; get; }
+ Efl.Ui.Scrollable_Interactive.scroll_freeze { get; set; }
+ Efl.Ui.Scrollable_Interactive.scroll_hold { get; set; }
+ Efl.Ui.Scrollable_Interactive.match_content { set; }
+ Efl.Ui.Scrollbar.bar_mode { get; set; }
+
+ //Efl.Ui.Multi_Selectable
+ Efl.Ui.Multi_Selectable.select_mode {get; set;}
+ }
+}
diff --git a/src/lib/elementary/efl_ui_list_default_item.c b/src/lib/elementary/efl_ui_list_default_item.c
new file mode 100644
index 0000000000..25e9fdabe7
--- /dev/null
+++ b/src/lib/elementary/efl_ui_list_default_item.c
@@ -0,0 +1,111 @@
+#ifdef HAVE_CONFIG_H
+# include "elementary_config.h"
+#endif
+
+#define EFL_UI_LIST_DEFAULT_ITEM_PROTECTED
+
+#include <Elementary.h>
+
+#include "elm_priv.h"
+#include "efl_ui_list_default_item_part_icon.eo.h"
+#include "efl_ui_list_default_item_part_end.eo.h"
+#include "elm_part_helper.h"
+
+#define MY_CLASS EFL_UI_LIST_DEFAULT_ITEM_CLASS
+#define MY_CLASS_PFX efl_ui_list_default_item
+
+#define MY_CLASS_NAME "Efl.Ui.List_Default_Item"
+
+EOLIAN static Efl_Object *
+_efl_ui_list_default_item_efl_object_finalize(Eo *obj, void *pd EINA_UNUSED)
+{
+ Eo *eo;
+ eo = efl_finalize(efl_super(obj, MY_CLASS));
+ ELM_WIDGET_DATA_GET_OR_RETURN(eo, wd, eo);
+ Efl_Ui_Theme_Apply theme_apply = efl_ui_layout_object_theme_set(obj, "list_item", NULL, NULL);
+
+ if (theme_apply == EFL_UI_THEME_APPLY_FAILED)
+ CRI("Default Item(%p) failed to set theme [efl/list_item]!", eo);
+ return eo;
+}
+
+EOLIAN static void
+_efl_ui_list_default_item_efl_object_destructor(Eo *obj, void *pd EINA_UNUSED)
+{
+ efl_destructor(efl_super(obj, MY_CLASS));
+}
+
+/* Efl.Part */
+
+ELM_PART_TEXT_DEFAULT_GET(efl_ui_list_default_item, "efl.text")
+ELM_PART_TEXT_DEFAULT_IMPLEMENT(efl_ui_list_default_item, void)
+ELM_PART_MARKUP_DEFAULT_IMPLEMENT(efl_ui_list_default_item, void)
+ELM_PART_CONTENT_DEFAULT_GET(efl_ui_list_default_item, "efl.icon")
+ELM_PART_CONTENT_DEFAULT_IMPLEMENT(efl_ui_list_default_item, void
+)
+
+Eina_Bool
+_efl_ui_list_default_item_part_icon_efl_content_content_set(Eo *obj, void *pd EINA_UNUSED, Efl_Gfx_Entity *content)
+{
+ Elm_Part_Data *wd = efl_data_scope_get(obj, EFL_UI_WIDGET_PART_CLASS);
+ return efl_content_set(efl_part(efl_super(wd->obj, MY_CLASS), wd->part), content);
+}
+
+Efl_Gfx_Entity *
+_efl_ui_list_default_item_part_icon_efl_content_content_get(const Eo *obj, void *pd EINA_UNUSED)
+{
+ Elm_Part_Data *wd = efl_data_scope_get(obj, EFL_UI_WIDGET_PART_CLASS);
+ return efl_content_get(efl_part(efl_super(wd->obj, MY_CLASS), wd->part));
+}
+
+Efl_Gfx_Entity *
+_efl_ui_list_default_item_part_icon_efl_content_content_unset(Eo *obj, void *pd EINA_UNUSED)
+{
+ Elm_Part_Data *wd = efl_data_scope_get(obj, EFL_UI_WIDGET_PART_CLASS);
+ return efl_content_unset(efl_part(efl_super(wd->obj, MY_CLASS), wd->part));
+}
+#include "efl_ui_list_default_item_part_icon.eo.c"
+
+Eina_Bool
+_efl_ui_list_default_item_part_end_efl_content_content_set(Eo *obj, void *pd EINA_UNUSED, Efl_Gfx_Entity *content)
+{
+ Elm_Part_Data *wd = efl_data_scope_get(obj, EFL_UI_WIDGET_PART_CLASS);
+ return efl_content_set(efl_part(efl_super(wd->obj, MY_CLASS), wd->part), content);
+}
+
+Efl_Gfx_Entity *
+_efl_ui_list_default_item_part_end_efl_content_content_get(const Eo *obj, void *pd EINA_UNUSED)
+{
+ Elm_Part_Data *wd = efl_data_scope_get(obj, EFL_UI_WIDGET_PART_CLASS);
+ return efl_content_get(efl_part(efl_super(wd->obj, MY_CLASS), wd->part));
+}
+
+Efl_Gfx_Entity *
+_efl_ui_list_default_item_part_end_efl_content_content_unset(Eo *obj, void *pd EINA_UNUSED)
+{
+ Elm_Part_Data *wd = efl_data_scope_get(obj, EFL_UI_WIDGET_PART_CLASS);
+ return efl_content_unset(efl_part(efl_super(wd->obj, MY_CLASS), wd->part));
+}
+#include "efl_ui_list_default_item_part_end.eo.c"
+
+EOLIAN static Efl_Object *
+_efl_ui_list_default_item_efl_part_part(const Eo *obj, void *wd EINA_UNUSED, const char *part)
+{
+ EINA_SAFETY_ON_NULL_RETURN_VAL(part, NULL);
+ if (eina_streq(part, "text"))
+ return ELM_PART_IMPLEMENT(EFL_UI_LAYOUT_PART_TEXT_CLASS, obj, "efl.text");
+ else if (eina_streq(part, "icon"))
+ return ELM_PART_IMPLEMENT(EFL_UI_LIST_DEFAULT_ITEM_PART_ICON_CLASS, obj, "efl.icon");
+ else if (eina_streq(part, "end"))
+ return ELM_PART_IMPLEMENT(EFL_UI_LIST_DEFAULT_ITEM_PART_END_CLASS, obj, "efl.end");
+
+ return efl_part(efl_super(obj, MY_CLASS), part);
+}
+/* Efl.Part end */
+
+/* Internal EO APIs and hidden overrides */
+#define EFL_UI_LIST_DEFAULT_ITEM_EXTRA_OPS \
+ ELM_PART_TEXT_DEFAULT_OPS(efl_ui_list_default_item), \
+ ELM_PART_CONTENT_DEFAULT_OPS(efl_ui_list_default_item)
+
+#include "efl_ui_list_default_item.eo.c"
diff --git a/src/lib/elementary/efl_ui_list_default_item.eo b/src/lib/elementary/efl_ui_list_default_item.eo
new file mode 100644
index 0000000000..0fcb0b6f0b
--- /dev/null
+++ b/src/lib/elementary/efl_ui_list_default_item.eo
@@ -0,0 +1,24 @@
+
+class Efl.Ui.List_Default_Item (Efl.Ui.List_Item,
+ Efl.Text,
+ Efl.Text_Markup,
+ Efl.Ui.Translatable,
+ Efl.Content)
+{
+ [[List Default Item class.
+ This class need to be sub object of list widget.
+ text and contents can be appliable by efl_text,
+ efl_content or efl_part APIs.]]
+ data: null;
+ implements {
+ //Efl.Object
+ Efl.Object.finalize;
+ Efl.Object.destructor;
+ Efl.Text.text { get; set; }
+ Efl.Text_Markup.markup { get; set; }
+ Efl.Ui.Translatable.translatable_text { get; set; }
+ Efl.Content.content { get; set; }
+ Efl.Content.content_unset;
+ Efl.Part.part;
+ }
+}
diff --git a/src/lib/elementary/efl_ui_list_default_item_part_end.eo b/src/lib/elementary/efl_ui_list_default_item_part_end.eo
new file mode 100644
index 0000000000..7388c9f49b
--- /dev/null
+++ b/src/lib/elementary/efl_ui_list_default_item_part_end.eo
@@ -0,0 +1,9 @@
+class Efl.Ui.List_Default_Item_Part_End (Efl.Ui.Layout.Part, Efl.Content)
+{
+ [[List Default Item internal content of end part class]]
+ data: null;
+ implements {
+ Efl.Content.content { get; set; }
+ Efl.Content.content_unset;
+ }
+} \ No newline at end of file
diff --git a/src/lib/elementary/efl_ui_list_default_item_part_icon.eo b/src/lib/elementary/efl_ui_list_default_item_part_icon.eo
new file mode 100644
index 0000000000..faed96db51
--- /dev/null
+++ b/src/lib/elementary/efl_ui_list_default_item_part_icon.eo
@@ -0,0 +1,9 @@
+class Efl.Ui.List_Default_Item_Part_Icon (Efl.Ui.Layout.Part, Efl.Content)
+{
+ [[List Default Item internal content of icon part class]]
+ data: null;
+ implements {
+ Efl.Content.content { get; set; }
+ Efl.Content.content_unset;
+ }
+} \ No newline at end of file
diff --git a/src/lib/elementary/efl_ui_list_empty_item.c b/src/lib/elementary/efl_ui_list_empty_item.c
new file mode 100644
index 0000000000..b78707ad57
--- /dev/null
+++ b/src/lib/elementary/efl_ui_list_empty_item.c
@@ -0,0 +1,56 @@
+#ifdef HAVE_CONFIG_H
+# include "elementary_config.h"
+#endif
+
+#define EFL_UI_LIST_EMPTY_ITEM_PROTECTED
+
+#include <Elementary.h>
+
+#include "elm_priv.h"
+#include "elm_part_helper.h"
+
+#define MY_CLASS EFL_UI_LIST_EMPTY_ITEM_CLASS
+#define MY_CLASS_PFX efl_ui_list_empty_item
+
+#define MY_CLASS_NAME "Efl.Ui.List_Empty_Item"
+
+EOLIAN static Efl_Object *
+_efl_ui_list_empty_item_efl_object_finalize(Eo *obj, void *pd EINA_UNUSED)
+{
+ Eo *eo;
+ eo = efl_finalize(efl_super(obj, MY_CLASS));
+ ELM_WIDGET_DATA_GET_OR_RETURN(eo, wd, eo);
+ Efl_Ui_Theme_Apply theme_apply = efl_ui_layout_object_theme_set(obj, "list_item", NULL, "empty");
+
+ if (theme_apply == EFL_UI_THEME_APPLY_FAILED)
+ CRI("Empty Item(%p) failed to set theme [efl/list_item:empty]!", eo);
+ return eo;
+}
+
+EOLIAN static void
+_efl_ui_list_empty_item_efl_object_destructor(Eo *obj, void *pd EINA_UNUSED)
+{
+ efl_destructor(efl_super(obj, MY_CLASS));
+}
+
+/* Efl.Part */
+ELM_PART_CONTENT_DEFAULT_GET(efl_ui_list_empty_item, "efl.content")
+ELM_PART_CONTENT_DEFAULT_IMPLEMENT(efl_ui_list_empty_item, void)
+/* Efl.Part end */
+
+EOLIAN static Efl_Object *
+_efl_ui_list_empty_item_efl_part_part(const Eo *obj, void *wd EINA_UNUSED, const char *part)
+{
+ EINA_SAFETY_ON_NULL_RETURN_VAL(part, NULL);
+ if (eina_streq(part, "content"))
+ return ELM_PART_IMPLEMENT(EFL_UI_LAYOUT_PART_CONTENT_CLASS, obj, "efl.content");
+
+ return efl_part(efl_super(obj, MY_CLASS), part);
+}
+
+/* Internal EO APIs and hidden overrides */
+
+#define EFL_UI_LIST_EMPTY_ITEM_EXTRA_OPS \
+ ELM_PART_CONTENT_DEFAULT_OPS(efl_ui_list_empty_item)
+
+#include "efl_ui_list_empty_item.eo.c"
diff --git a/src/lib/elementary/efl_ui_list_empty_item.eo b/src/lib/elementary/efl_ui_list_empty_item.eo
new file mode 100644
index 0000000000..a139ef3bf1
--- /dev/null
+++ b/src/lib/elementary/efl_ui_list_empty_item.eo
@@ -0,0 +1,16 @@
+
+class Efl.Ui.List_Empty_Item (Efl.Ui.List_Item, Efl.Content)
+{
+ [[List Empty Item class. This item have only one swallow space,
+ thus user can decorate item by filling the swallow with
+ any kind of container.]]
+ data: null;
+ implements {
+ //Efl.Object
+ Efl.Object.finalize;
+ Efl.Object.destructor;
+ Efl.Content.content { get; set; }
+ Efl.Content.content_unset;
+ Efl.Part.part;
+ }
+}
diff --git a/src/lib/elementary/efl_ui_list_item.c b/src/lib/elementary/efl_ui_list_item.c
new file mode 100644
index 0000000000..1fe67e9c0c
--- /dev/null
+++ b/src/lib/elementary/efl_ui_list_item.c
@@ -0,0 +1,83 @@
+#ifdef HAVE_CONFIG_H
+# include "elementary_config.h"
+#endif
+
+#define EFL_ACCESS_PROTECTED
+#define EFL_UI_WIDGET_PART_BG_PROTECTED
+
+#include <Elementary.h>
+
+#include "elm_priv.h"
+#include "efl_ui_list_item_private.h"
+
+#define MY_CLASS EFL_UI_LIST_ITEM_CLASS
+#define MY_CLASS_PFX efl_ui_list_item
+
+#define MY_CLASS_NAME "Efl.Ui.List_Item"
+
+static void
+_sizing_eval(Evas_Object *obj, Efl_Ui_List_Item_Data *pd)
+{
+ Evas_Coord minh = -1, minw = -1;
+ Evas_Coord rest_w = 0, rest_h = 0;
+ ELM_WIDGET_DATA_GET_OR_RETURN(pd->obj, wd);
+
+ edje_object_size_min_restricted_calc(wd->resize_obj, &minw, &minh,
+ rest_w, rest_h);
+ evas_object_size_hint_min_set(obj, minw, minh);
+
+ pd->needs_size_calc = EINA_FALSE;
+}
+
+static void
+_efl_ui_list_item_elm_layout_sizing_eval(Eo *obj, Efl_Ui_List_Item_Data *pd)
+{
+ if (pd->needs_size_calc) return;
+ pd->needs_size_calc = EINA_TRUE;
+
+ efl_canvas_group_change(obj);
+}
+
+EOLIAN static void
+_efl_ui_list_item_efl_canvas_group_group_calculate(Eo *obj, Efl_Ui_List_Item_Data *pd)
+{
+ if (pd->needs_size_calc)
+ {
+ _sizing_eval(obj, pd);
+ pd->needs_size_calc = EINA_FALSE;
+ }
+}
+
+EOLIAN static Eo *
+_efl_ui_list_item_efl_object_constructor(Eo *obj, Efl_Ui_List_Item_Data *pd)
+{
+ pd->obj = obj;
+ obj = efl_constructor(efl_super(obj, MY_CLASS));
+
+ return obj;
+}
+
+EOLIAN static Efl_Object *
+_efl_ui_list_item_efl_object_finalize(Eo *obj, Efl_Ui_List_Item_Data *pd EINA_UNUSED)
+{
+ Eo *eo;
+ eo = efl_finalize(efl_super(obj, MY_CLASS));
+ ELM_WIDGET_DATA_GET_OR_RETURN(eo, wd, eo);
+
+ return eo;
+}
+
+EOLIAN static void
+_efl_ui_list_item_efl_object_destructor(Eo *obj, Efl_Ui_List_Item_Data *pd EINA_UNUSED)
+{
+ ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
+
+ efl_destructor(efl_super(obj, MY_CLASS));
+}
+
+/* Internal EO APIs and hidden overrides */
+
+#define EFL_UI_LIST_ITEM_EXTRA_OPS \
+ ELM_LAYOUT_SIZING_EVAL_OPS(efl_ui_list_item)
+
+#include "efl_ui_list_item.eo.c"
diff --git a/src/lib/elementary/efl_ui_list_item.eo b/src/lib/elementary/efl_ui_list_item.eo
new file mode 100644
index 0000000000..82943ad3c6
--- /dev/null
+++ b/src/lib/elementary/efl_ui_list_item.eo
@@ -0,0 +1,12 @@
+
+abstract Efl.Ui.List_Item (Efl.Ui.Item)
+{
+ implements {
+ //Efl.Object
+ Efl.Object.constructor;
+ Efl.Object.finalize;
+ Efl.Object.destructor;
+ //Efl.Canvas
+ Efl.Canvas.Group.group_calculate;
+ }
+}
diff --git a/src/lib/elementary/efl_ui_list_item_private.h b/src/lib/elementary/efl_ui_list_item_private.h
new file mode 100644
index 0000000000..e68b3fa14a
--- /dev/null
+++ b/src/lib/elementary/efl_ui_list_item_private.h
@@ -0,0 +1,31 @@
+#ifndef EFL_UI_LIST_ITEM_PRIVATE_H
+#define EFL_UI_LIST_ITEM_PRIVATE_H
+
+#include "Elementary.h"
+
+typedef struct _Efl_Ui_List_Item_Data
+{
+ // Eo Objects
+ Eo *obj; /* Self-Object */
+ Eo *parent; /* Parent Widget */
+ Eina_Bool needs_size_calc : 1; /* Flag for Size calculation */
+} Efl_Ui_List_Item_Data;
+
+
+#define EFL_UI_LIST_ITEM_DATA_GET(o, pd) \
+ Efl_Ui_List_Item_Data * pd = efl_data_scope_safe_get(o, EFL_UI_LIST_ITEM_CLASS)
+
+#define EFL_UI_LIST_ITEM_DATA_GET_OR_RETURN(o, ptr, ...) \
+ EFL_UI_LIST_ITEM_DATA_GET(o, ptr); \
+ if (EINA_UNLIKELY(!ptr)) \
+ { \
+ ERR("No widget data for object %p (%s)", \
+ o, evas_object_type_get(o)); \
+ return __VA_ARGS__; \
+ }
+
+#define EFL_UI_LIST_ITEM_CHECK_OR_RETURN(obj, ...) \
+ if (EINA_UNLIKELY(!efl_isa((obj), EFL_UI_LIST_ITEM_CLASS))) \
+ return __VA_ARGS__;
+
+#endif
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..409956dce1
--- /dev/null
+++ b/src/lib/elementary/efl_ui_list_private.h
@@ -0,0 +1,63 @@
+#ifndef EFL_UI_LIST_PRIVATE_H
+#define EFL_UI_LIST_PRIVATE_H
+
+#include "Elementary.h"
+
+typedef struct _Efl_Ui_List_Data
+{
+ // Eo Objects
+ Eo *box; /* Internal box for Efl.Pack support */
+ Eo *pan; /* Internal pan for scroll */
+ Eo *smanager; /* Scroll Manager for support scroll with pan */
+
+ struct {
+ Efl_Ui_List_Item *item; /* Scroll target item */
+ double align; /* Item scroll aligned position.
+ -1 is for default case of scroll in */
+ Eina_Bool anim : 1; /* boolean data for animation on scroll */
+ } scroll; /* Item scroll values for deferred operation */
+
+ Eina_List *items; /* All item list for internal maintaining */
+ Eina_List *selected; /* Selected items list */
+ Efl_Ui_List_Item *last_selected; /* latest selected item */
+
+ Efl_Ui_Select_Mode select_mode; /* Select mode for items
+ with single or multiple seleciton */
+
+ // Boolean Data
+ Eina_Bool freeze_want : 1; /* Flag for Scroll freezing */
+ Eina_Bool match_content_w: 1; /* Flag for size matching on content width.
+ it will disable horizontal scroll */
+ Eina_Bool match_content_h: 1; /* Flag for size matching on content height.
+ it will disable vertical scroll */
+ Eina_Bool pan_resized : 1; /* Flag for pan resized.
+ This value is used for checking scroll is
+ calculated after initialized */
+} Efl_Ui_List_Data;
+
+typedef struct _Item_Iterator
+{
+ Eina_Iterator iterator;
+ Eina_List *list;
+ Eina_Iterator *real_iterator;
+ Eo *object;
+} Item_Iterator;
+
+
+#define EFL_UI_LIST_DATA_GET(o, pd) \
+ Efl_Ui_List_Data * pd = efl_data_scope_safe_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)) \
+ { \
+ ERR("No widget data for object %p (%s)", \
+ o, evas_object_type_get(o)); \
+ return __VA_ARGS__; \
+ }
+
+#define EFL_UI_LIST_CHECK(obj) \
+ if (EINA_UNLIKELY(!efl_isa((obj), EFL_UI_LIST_CLASS))) \
+ return
+
+#endif