summaryrefslogtreecommitdiff
path: root/src/lib
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 /src/lib
parentbbbd05148ad6c67450c92e87741f097b49f77352 (diff)
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
Diffstat (limited to 'src/lib')
-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
20 files changed, 2011 insertions, 54 deletions
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;
92#include "interfaces/efl_ui_scrollbar.eo.h" 92#include "interfaces/efl_ui_scrollbar.eo.h"
93#include "interfaces/efl_ui_scrollable_interactive.eo.h" 93#include "interfaces/efl_ui_scrollable_interactive.eo.h"
94#include "interfaces/efl_ui_selectable.eo.h" 94#include "interfaces/efl_ui_selectable.eo.h"
95#include "interfaces/efl_ui_multi_selectable.eo.h"
95#include "interfaces/efl_ui_zoom.eo.h" 96#include "interfaces/efl_ui_zoom.eo.h"
96 97
97#include "interfaces/efl_screen.eo.h" 98#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 @@
74#include "interfaces/efl_ui_scrollable_interactive.eo.c" 74#include "interfaces/efl_ui_scrollable_interactive.eo.c"
75#include "interfaces/efl_ui_scrollbar.eo.c" 75#include "interfaces/efl_ui_scrollbar.eo.c"
76#include "interfaces/efl_ui_selectable.eo.c" 76#include "interfaces/efl_ui_selectable.eo.c"
77#include "interfaces/efl_ui_multi_selectable.eo.c"
77#include "interfaces/efl_ui_zoom.eo.c" 78#include "interfaces/efl_ui_zoom.eo.c"
78 79
79EAPI void 80EAPI 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 @@
1interface Efl.Ui.Item {
2 [[Efl UI item interface]]
3 legacy_prefix: null;
4 methods {
5 @property prev {
6 get {
7 [[Get the item before this one in the widget's list of items.
8
9 See also @.next.
10 ]]
11 }
12 values {
13 item: Efl.Ui.Item; [[The item before the object in its parent's
14 list. If there is no previous item or in case
15 of error, $null is returned.]]
16 }
17 }
18 @property next {
19 get {
20 [[Get the item after this one in the widget's list of items.
21
22 See also @.prev.
23 ]]
24 }
25 values {
26 item: Efl.Ui.Item; [[The item after the object in its parent's
27 list. If there is no next item or in case
28 of error, $null is returned.]]
29 }
30 }
31 @property selected {
32 [[Indicates whether this item is currently selected.]]
33 get {
34 [[Get the selected state of this item.]]
35 }
36 set {
37 [[Set the selected state of $item.
38
39 This sets the selected state of the given item $it.
40 $true for selected, $false for not selected.
41
42 If a new item is selected the previously selected will
43 be unselected. Previously selected item can be retrieved
44 with @Efl.Ui.Menu.selected_item.get.
45
46 Selected items will be highlighted.
47 ]]
48 }
49 values {
50 selected: bool; [[The selection state.]]
51 }
52 }
53 }
54}
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 @@
1enum Efl.Ui.Select_Mode {
2 [[Type of multi selectable object.]]
3 legacy: efl_ui_select;
4 single, [[Only single child is selected. if the child is selected,
5 previous selected child will be unselected.]]
6 single_always, [[Same as single select except, this will be selected
7 in every select calls though child is already been selected.]]
8 multi, [[allow multiple selection of children.]]
9 none [[Last value of select mode. child cannot be selected at all.]]
10}
11
12interface Efl.Ui.Multi_Selectable ()
13{
14 [[Efl UI Multi selectable interface.
15 The container have to control select property of multiple chidren.]]
16 eo_prefix: efl_ui;
17 methods
18 {
19 @property select_mode {
20 [[The mode type for children selection.]]
21 set {}
22 get {}
23 values {
24 mode: Efl.Ui.Select_Mode; [[Type of selection of children]]
25 }
26 }
27 }
28}
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;
324# include <efl_ui_image_factory.eo.h> 324# include <efl_ui_image_factory.eo.h>
325# include <efl_ui_slider_interval.eo.h> 325# include <efl_ui_slider_interval.eo.h>
326# include <efl_ui_layout_factory.eo.h> 326# include <efl_ui_layout_factory.eo.h>
327# include <efl_ui_item.eo.h>
328# include <efl_ui_list_item.eo.h>
329# include <efl_ui_list_default_item_part_icon.eo.h>
330# include <efl_ui_list_default_item_part_end.eo.h>
331# include <efl_ui_list_default_item.eo.h>
332# include <efl_ui_list_empty_item.eo.h>
333# include <efl_ui_list.eo.h>
327# include <efl_ui_view_list_types.eot.h> 334# include <efl_ui_view_list_types.eot.h>
328# include <efl_ui_view_list_segarray.h> 335# include <efl_ui_view_list_segarray.h>
329# include <efl_ui_view_list_segarray.eo.h> 336# 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 @@
1#ifdef HAVE_CONFIG_H
2# include "elementary_config.h"
3#endif
4
5#define EFL_ACCESS_PROTECTED
6#define EFL_UI_WIDGET_PART_BG_PROTECTED
7
8#include <Elementary.h>
9
10#include "elm_priv.h"
11#include "efl_ui_item_private.h"
12
13#define MY_CLASS EFL_UI_ITEM_CLASS
14#define MY_CLASS_PFX efl_ui_item
15
16#define MY_CLASS_NAME "Efl.Ui.Item"
17
18static void
19_item_select(Eo *obj, Efl_Ui_Item_Data *pd)
20{
21 if (pd->selected &&
22 (*(pd->select_mode) != EFL_UI_SELECT_SINGLE_ALWAYS))
23 return;
24 if (*(pd->select_mode) == EFL_UI_SELECT_NONE) return;
25
26 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
27
28 pd->selected = EINA_TRUE;
29 edje_object_signal_emit(wd->resize_obj, "efl,state,selected", "efl");
30 efl_event_callback_call(obj, EFL_UI_EVENT_SELECTED, NULL);
31}
32
33static void
34_item_unselect(Eo *obj, Efl_Ui_Item_Data *pd)
35{
36 if (!pd->selected) return;
37 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
38
39 pd->selected = EINA_FALSE;
40 edje_object_signal_emit(wd->resize_obj, "efl,state,unselected", "efl");
41 efl_event_callback_call(obj, EFL_UI_EVENT_UNSELECTED, NULL);
42}
43
44/* Mouse Controls */
45static Eina_Bool
46_item_longpressed(void *data)
47{
48 Efl_Ui_Item *item = data;
49 EFL_UI_ITEM_DATA_GET_OR_RETURN(item, pd, ECORE_CALLBACK_CANCEL);
50
51 pd->longpress_timer = NULL;
52
53 efl_event_callback_call(item, EFL_UI_EVENT_LONGPRESSED, NULL);
54 return ECORE_CALLBACK_CANCEL;
55}
56
57static void
58_item_mouse_down(void *data,
59 Evas *evas EINA_UNUSED,
60 Evas_Object *obj EINA_UNUSED,
61 void *event_info)
62{
63 Evas_Event_Mouse_Down *ev = event_info;
64 Eo *item = data;
65 EFL_UI_ITEM_DATA_GET_OR_RETURN(item, pd);
66 ELM_WIDGET_DATA_GET_OR_RETURN(item, wd);
67 if (wd->disabled) return;
68 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
69
70 edje_object_signal_emit(wd->resize_obj, "efl,state,pressed", "efl");
71
72 pd->longpress_timer = ecore_timer_add(_elm_config->longpress_timeout, _item_longpressed, item);
73 efl_event_callback_call(item, EFL_UI_EVENT_PRESSED, NULL);
74}
75
76static void
77_item_mouse_up(void *data,
78 Evas *evas EINA_UNUSED,
79 Evas_Object *obj EINA_UNUSED,
80 void *event_info)
81{
82 Evas_Event_Mouse_Up *ev = event_info;
83 Eo *item = data;
84 EFL_UI_ITEM_DATA_GET_OR_RETURN(item, pd);
85 ELM_WIDGET_DATA_GET_OR_RETURN(item, wd);
86 if (wd->disabled) return;
87 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
88 {
89 //FIXME: should we send this message to fallback?
90 edje_object_signal_emit(wd->resize_obj, "efl,state,unpressed", "efl");
91 //efl_event_callback_call(item, EFL_UI_EVENT_UNPRESSED, NULL);
92 return;
93 }
94
95 if (pd->longpress_timer)
96 {
97 ecore_timer_del(pd->longpress_timer);
98 pd->longpress_timer = NULL;
99 }
100
101 edje_object_signal_emit(wd->resize_obj, "efl,state,unpressed", "efl");
102 efl_event_callback_call(item, EFL_UI_EVENT_UNPRESSED, NULL);
103
104 if ((*(pd->select_mode) != EFL_UI_SELECT_SINGLE_ALWAYS) && (pd->selected))
105 _item_unselect(item, pd);
106 else if (*(pd->select_mode) != EFL_UI_SELECT_NONE)
107 _item_select(item, pd);
108}
109
110static void
111_item_mouse_move(void *data EINA_UNUSED,
112 Evas *evas EINA_UNUSED,
113 Evas_Object *obj EINA_UNUSED,
114 void *event_info)
115{
116 Evas_Event_Mouse_Move *ev = event_info;
117 Eo *item = data;
118 EFL_UI_ITEM_DATA_GET_OR_RETURN(item, pd);
119 ELM_WIDGET_DATA_GET_OR_RETURN(item, wd);
120 if (wd->disabled) return;
121 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
122 {
123 edje_object_signal_emit(wd->resize_obj, "efl,state,unpressed", "efl");
124 return;
125 }
126}
127
128static void
129_item_mouse_in(void *data EINA_UNUSED,
130 Evas *evas EINA_UNUSED,
131 Evas_Object *obj EINA_UNUSED,
132 void *event_info)
133{
134 Evas_Event_Mouse_In *ev = event_info;
135 Eo *item = data;
136 EFL_UI_ITEM_DATA_GET_OR_RETURN(item, pd);
137 ELM_WIDGET_DATA_GET_OR_RETURN(item, wd);
138 if (wd->disabled) return;
139
140 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
141}
142
143static void
144_item_mouse_callback_add(Eo *obj, void *data)
145{
146 evas_object_event_callback_add
147 (obj, EVAS_CALLBACK_MOUSE_DOWN, _item_mouse_down, data);
148 evas_object_event_callback_add
149 (obj, EVAS_CALLBACK_MOUSE_UP, _item_mouse_up, data);
150 evas_object_event_callback_add
151 (obj, EVAS_CALLBACK_MOUSE_MOVE, _item_mouse_move, data);
152 evas_object_event_callback_add
153 (obj, EVAS_CALLBACK_MOUSE_IN, _item_mouse_in, data);
154}
155
156static void
157_item_mouse_callback_del(Eo *obj, void *data)
158{
159 evas_object_event_callback_del_full
160 (obj, EVAS_CALLBACK_MOUSE_DOWN, _item_mouse_down, data);
161 evas_object_event_callback_del_full
162 (obj, EVAS_CALLBACK_MOUSE_UP, _item_mouse_up, data);
163 evas_object_event_callback_del_full
164 (obj, EVAS_CALLBACK_MOUSE_MOVE, _item_mouse_move, data);
165 evas_object_event_callback_del_full
166 (obj, EVAS_CALLBACK_MOUSE_IN, _item_mouse_in, data);
167}
168/* Mouse Controls ends */
169
170static void
171_sizing_eval(Evas_Object *obj, Efl_Ui_Item_Data *pd)
172{
173 Evas_Coord minh = -1, minw = -1;
174 Evas_Coord rest_w = 0, rest_h = 0;
175 ELM_WIDGET_DATA_GET_OR_RETURN(pd->obj, wd);
176
177 edje_object_size_min_restricted_calc(wd->resize_obj, &minw, &minh,
178 rest_w, rest_h);
179 evas_object_size_hint_min_set(obj, minw, minh);
180
181 pd->needs_size_calc = EINA_FALSE;
182}
183
184static void
185_efl_ui_item_elm_layout_sizing_eval(Eo *obj, Efl_Ui_Item_Data *pd)
186{
187 if (pd->needs_size_calc) return;
188 pd->needs_size_calc = EINA_TRUE;
189
190 efl_canvas_group_change(obj);
191}
192
193EOLIAN static void
194_efl_ui_item_efl_canvas_group_group_calculate(Eo *obj, Efl_Ui_Item_Data *pd)
195{
196 if (pd->needs_size_calc)
197 {
198 _sizing_eval(obj, pd);
199 pd->needs_size_calc = EINA_FALSE;
200 }
201}
202
203EOLIAN static Eo *
204_efl_ui_item_efl_object_constructor(Eo *obj, Efl_Ui_Item_Data *pd)
205{
206 pd->obj = obj;
207 obj = efl_constructor(efl_super(obj, MY_CLASS));
208
209 return obj;
210}
211
212EOLIAN static Efl_Object *
213_efl_ui_item_efl_object_finalize(Eo *obj, Efl_Ui_Item_Data *pd EINA_UNUSED)
214{
215 Eo *eo;
216 eo = efl_finalize(efl_super(obj, MY_CLASS));
217 ELM_WIDGET_DATA_GET_OR_RETURN(eo, wd, eo);
218
219 _item_mouse_callback_add(wd->resize_obj, eo);
220 return eo;
221}
222
223EOLIAN static void
224_efl_ui_item_efl_object_destructor(Eo *obj, Efl_Ui_Item_Data *pd EINA_UNUSED)
225{
226 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
227
228 _item_mouse_callback_del(wd->resize_obj, obj);
229 efl_destructor(efl_super(obj, MY_CLASS));
230}
231
232EOLIAN static int
233_efl_ui_item_index_get(const Eo *obj, Efl_Ui_Item_Data *pd)
234{
235 return efl_pack_index_get(pd->parent, obj);
236}
237
238EOLIAN static void
239_efl_ui_item_selected_set(Eo *obj, Efl_Ui_Item_Data *pd, Eina_Bool select)
240{
241 Eina_Bool selected = !!select;
242 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
243 if (wd->disabled) return;
244
245 if (selected) _item_select(obj, pd);
246 else _item_unselect(obj, pd);
247}
248
249EOLIAN static Eina_Bool
250_efl_ui_item_selected_get(const Eo *obj EINA_UNUSED, Efl_Ui_Item_Data *pd)
251{
252 return pd->selected;
253}
254
255/* Internal EO APIs and hidden overrides */
256
257#define EFL_UI_ITEM_EXTRA_OPS \
258 ELM_LAYOUT_SIZING_EVAL_OPS(efl_ui_item)
259
260#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 @@
1abstract Efl.Ui.Item (Efl.Ui.Layout.Object, Efl.Ui.Selectable, Efl.Ui.Clickable)
2{
3 [[Item abstract class for pack widget. All item have to be inherited from this class.]]
4 methods {
5 @property index {
6 [[index number of item from their parent object.]]
7 get {}
8 values {
9 index : int;
10 }
11 }
12 @property selected {
13 [[Select property for item object.
14 Item can be selected by user mouse/key input also]]
15 set {}
16 get {}
17 values {
18 select: bool;
19 }
20 }
21 }
22 implements {
23 //Efl.Object
24 Efl.Object.constructor;
25 Efl.Object.finalize;
26 Efl.Object.destructor;
27 //Efl.Canvas
28 Efl.Canvas.Group.group_calculate;
29 }
30}
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 @@
1#ifndef EFL_UI_ITEM_PRIVATE_H
2#define EFL_UI_ITEM_PRIVATE_H
3
4#include "Elementary.h"
5
6typedef struct _Efl_Ui_Item_Data
7{
8 // Eo Objects
9 Eo *obj; /* Self-Object */
10 Eo *parent; /* Parent Widget */
11
12 Efl_Ui_Select_Mode *select_mode; /* Select Mdoe of parent widget */
13 Ecore_Timer *longpress_timer; /* Timer for longpress handle */
14
15 // Boolean Data
16 Eina_Bool selected : 1; /* State for item selected */
17 Eina_Bool needs_size_calc : 1; /* Flag for Size calculation */
18} Efl_Ui_Item_Data;
19
20
21#define EFL_UI_ITEM_DATA_GET(o, pd) \
22 Efl_Ui_Item_Data * pd = efl_data_scope_safe_get(o, EFL_UI_ITEM_CLASS)
23
24#define EFL_UI_ITEM_DATA_GET_OR_RETURN(o, ptr, ...) \
25 EFL_UI_ITEM_DATA_GET(o, ptr); \
26 if (EINA_UNLIKELY(!ptr)) \
27 { \
28 ERR("No widget data for object %p (%s)", \
29 o, evas_object_type_get(o)); \
30 return __VA_ARGS__; \
31 }
32
33#define EFL_UI_ITEM_CHECK_OR_RETURN(obj, ...) \
34 if (EINA_UNLIKELY(!efl_isa((obj), EFL_UI_ITEM_CLASS))) \
35 return __VA_ARGS__;
36
37#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 @@
1#ifdef HAVE_CONFIG_H
2# include "elementary_config.h"
3#endif
4
5#define ELM_LAYOUT_PROTECTED
6#define EFL_UI_SCROLL_MANAGER_PROTECTED
7#define EFL_UI_SCROLLBAR_PROTECTED
8#define EFL_UI_SCROLLBAR_BETA
9
10#include <Elementary.h>
11#include "elm_priv.h"
12#include "efl_ui_list_item_private.h"
13#include "efl_ui_item_private.h"
14#include "efl_ui_list_private.h"
15
16#define MY_CLASS EFL_UI_LIST_CLASS
17#define MY_CLASS_PFX efl_ui_list
18
19#define MY_CLASS_NAME "Efl.Ui.List"
20
21static void
22_item_scroll_internal(Eo *obj,
23 Efl_Ui_List_Item *item,
24 double align,
25 Eina_Bool anim)
26{
27 EFL_UI_LIST_DATA_GET_OR_RETURN(obj, pd);
28 Eina_Rect ipos, view;
29 Eina_Position2D vpos;
30
31 if (!pd->smanager) return;
32
33 ipos = efl_gfx_entity_geometry_get(item);
34 view = efl_ui_scrollable_viewport_geometry_get(pd->smanager);
35 vpos = efl_ui_scrollable_content_pos_get(pd->smanager);
36
37 ipos.x = view.x;
38 ipos.w = ipos.w;
39
40 // FIXME: align case will not correctly show in the position because of
41 // bar size calculation. there are no certain way to know the scroll calcuation finished.
42 if (EINA_DBL_EQ(align, -1.0))
43 {
44 ipos.y = ipos.y + vpos.y - view.y;
45 ipos.h = ipos.h;
46 }
47 else if ((align > 0.0 || EINA_DBL_EQ(align, 0.0)) &&
48 (align < 1.0 || EINA_DBL_EQ(align, 1.0)))
49 {
50 ipos.y = ipos.y + vpos.y - view.y - (int)((view.h - ipos.h) * align);
51 ipos.h = view.h;
52 }
53 else ERR("align (%.2lf) is not proper value. it must be the value between [0.0 , 1.0]!", align);
54
55 efl_ui_scrollable_scroll(pd->smanager, ipos, anim);
56}
57
58static void
59_efl_ui_list_bar_read_and_update(Eo *obj)
60{
61 EFL_UI_LIST_DATA_GET_OR_RETURN(obj, pd);
62 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
63 double vx = 0.0, vy = 0.0;
64
65 edje_object_part_drag_value_get
66 (wd->resize_obj, "efl.dragable.vbar", NULL, &vy);
67
68 /* FIXME: Horizontal Scroll is not yet supported in the list.
69 edje_object_part_drag_value_get
70 (wd->resize_obj, "efl.dragable.hbar", &vx, NULL);
71 */
72
73 efl_ui_scrollbar_bar_position_set(pd->smanager, vx, vy);
74}
75
76static void
77_efl_ui_list_reload_cb(void *data,
78 Evas_Object *obj EINA_UNUSED,
79 const char *emission EINA_UNUSED,
80 const char *source EINA_UNUSED)
81{
82 Eo *list = data;
83 EFL_UI_LIST_DATA_GET_OR_RETURN(list, pd);
84
85 efl_ui_scrollbar_bar_visibility_update(pd->smanager);
86}
87
88static void
89_efl_ui_list_vbar_drag_cb(void *data,
90 Evas_Object *obj EINA_UNUSED,
91 const char *emission EINA_UNUSED,
92 const char *source EINA_UNUSED)
93{
94 _efl_ui_list_bar_read_and_update(data);
95
96 Efl_Ui_Scrollbar_Direction type = EFL_UI_SCROLLBAR_DIRECTION_VERTICAL;
97 efl_event_callback_call(data, EFL_UI_SCROLLBAR_EVENT_BAR_DRAG, &type);
98}
99
100static void
101_efl_ui_list_vbar_press_cb(void *data,
102 Evas_Object *obj EINA_UNUSED,
103 const char *emission EINA_UNUSED,
104 const char *source EINA_UNUSED)
105{
106 Efl_Ui_Scrollbar_Direction type = EFL_UI_SCROLLBAR_DIRECTION_VERTICAL;
107 efl_event_callback_call(data, EFL_UI_SCROLLBAR_EVENT_BAR_PRESS, &type);
108}
109
110static void
111_efl_ui_list_vbar_unpress_cb(void *data,
112 Evas_Object *obj EINA_UNUSED,
113 const char *emission EINA_UNUSED,
114 const char *source EINA_UNUSED)
115{
116 Efl_Ui_Scrollbar_Direction type = EFL_UI_SCROLLBAR_DIRECTION_VERTICAL;
117 efl_event_callback_call(data, EFL_UI_SCROLLBAR_EVENT_BAR_UNPRESS, &type);
118}
119
120static void
121_efl_ui_list_edje_drag_start_cb(void *data,
122 Evas_Object *obj EINA_UNUSED,
123 const char *emission EINA_UNUSED,
124 const char *source EINA_UNUSED)
125{
126 Eo *list = data;
127 EFL_UI_LIST_DATA_GET_OR_RETURN(list, pd);
128
129 _efl_ui_list_bar_read_and_update(list);
130
131 pd->freeze_want = efl_ui_scrollable_scroll_freeze_get(pd->smanager);
132 efl_ui_scrollable_scroll_freeze_set(pd->smanager, EINA_TRUE);
133 efl_event_callback_call(list, EFL_UI_EVENT_SCROLL_DRAG_START, NULL);
134}
135
136static void
137_efl_ui_list_edje_drag_stop_cb(void *data,
138 Evas_Object *obj EINA_UNUSED,
139 const char *emission EINA_UNUSED,
140 const char *source EINA_UNUSED)
141{
142 Eo *list = data;
143 EFL_UI_LIST_DATA_GET_OR_RETURN(list, pd);
144
145 _efl_ui_list_bar_read_and_update(list);
146
147 efl_ui_scrollable_scroll_freeze_set(pd->smanager, pd->freeze_want);
148 efl_event_callback_call(list, EFL_UI_EVENT_SCROLL_DRAG_STOP, NULL);
149}
150
151static void
152_efl_ui_list_edje_drag_cb(void *data,
153 Evas_Object *obj EINA_UNUSED,
154 const char *emission EINA_UNUSED,
155 const char *source EINA_UNUSED)
156{
157 _efl_ui_list_bar_read_and_update(data);
158}
159
160/* FIXME: Horizontal Scroll is not yet supported in the list.
161 static void
162 _efl_ui_list_hbar_drag_cb(void *data,
163 Evas_Object *obj EINA_UNUSED,
164 const char *emission EINA_UNUSED,
165 const char *source EINA_UNUSED)
166 {
167 _efl_ui_list_bar_read_and_update(data);
168
169 Efl_Ui_Scrollbar_Direction type = EFL_UI_SCROLLBAR_DIRECTION_HORIZONTAL;
170 efl_event_callback_call(data, EFL_UI_SCROLLBAR_EVENT_BAR_DRAG, &type);
171 }
172
173 static void
174 _efl_ui_list_hbar_press_cb(void *data,
175 Evas_Object *obj EINA_UNUSED,
176 const char *emission EINA_UNUSED,
177 const char *source EINA_UNUSED)
178 {
179 Efl_Ui_Scrollbar_Direction type = EFL_UI_SCROLLBAR_DIRECTION_HORIZONTAL;
180 efl_event_callback_call(data, EFL_UI_SCROLLBAR_EVENT_BAR_PRESS, &type);
181 }
182
183 static void
184 _efl_ui_list_hbar_unpress_cb(void *data,
185 Evas_Object *obj EINA_UNUSED,
186 const char *emission EINA_UNUSED,
187 const char *source EINA_UNUSED)
188 {
189 Efl_Ui_Scrollbar_Direction type = EFL_UI_SCROLLBAR_DIRECTION_HORIZONTAL;
190 efl_event_callback_call(data, EFL_UI_SCROLLBAR_EVENT_BAR_UNPRESS, &type);
191 }
192 */
193
194static void
195_efl_ui_list_bar_size_changed_cb(void *data, const Efl_Event *event EINA_UNUSED)
196{
197 Eo *obj = data;
198 EFL_UI_LIST_DATA_GET_OR_RETURN(obj, pd);
199 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
200
201 double width = 0.0, height = 0.0;
202
203 edje_object_calc_force(wd->resize_obj);
204 efl_ui_scrollbar_bar_size_get(pd->smanager, &width, &height);
205 edje_object_part_drag_size_set(wd->resize_obj, "efl.dragable.hbar", width, 1.0);
206 edje_object_part_drag_size_set(wd->resize_obj, "efl.dragable.vbar", 1.0, height);
207}
208
209static void
210_efl_ui_list_bar_pos_changed_cb(void *data, const Efl_Event *event EINA_UNUSED)
211{
212 Eo *obj = data;
213 EFL_UI_LIST_DATA_GET_OR_RETURN(obj, pd);
214 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
215
216 double posx = 0.0, posy = 0.0;
217
218 efl_ui_scrollbar_bar_position_get(pd->smanager, &posx, &posy);
219 edje_object_part_drag_value_set(wd->resize_obj, "efl.dragable.hbar", posx, 0.0);
220 edje_object_part_drag_value_set(wd->resize_obj, "efl.dragable.vbar", 0.0, posy);
221}
222
223static void
224_efl_ui_list_bar_show_cb(void *data, const Efl_Event *event)
225{
226 Eo *obj = data;
227 EFL_UI_LIST_DATA_GET_OR_RETURN(obj, pd);
228 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
229 Efl_Ui_Scrollbar_Direction type = *(Efl_Ui_Scrollbar_Direction *)(event->info);
230
231 if (type == EFL_UI_SCROLLBAR_DIRECTION_HORIZONTAL)
232 edje_object_signal_emit(wd->resize_obj, "efl,action,show,hbar", "efl");
233 else if (type == EFL_UI_SCROLLBAR_DIRECTION_VERTICAL)
234 edje_object_signal_emit(wd->resize_obj, "efl,action,show,vbar", "efl");
235}
236
237static void
238_efl_ui_list_bar_hide_cb(void *data, const Efl_Event *event)
239{
240 Eo *obj = data;
241 EFL_UI_LIST_DATA_GET_OR_RETURN(obj, pd);
242 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
243 Efl_Ui_Scrollbar_Direction type = *(Efl_Ui_Scrollbar_Direction *)(event->info);
244
245 if (type == EFL_UI_SCROLLBAR_DIRECTION_HORIZONTAL)
246 edje_object_signal_emit(wd->resize_obj, "efl,action,hide,hbar", "efl");
247 else if (type == EFL_UI_SCROLLBAR_DIRECTION_VERTICAL)
248 edje_object_signal_emit(wd->resize_obj, "efl,action,hide,vbar", "efl");
249}
250
251static void
252_scroll_edje_object_attach(Eo *obj)
253{
254 EFL_UI_LIST_DATA_GET_OR_RETURN(obj, pd);
255
256 efl_layout_signal_callback_add
257 (obj, "reload", "efl",
258 _efl_ui_list_reload_cb, obj);
259 efl_layout_signal_callback_add
260 (obj, "drag", "efl.dragable.vbar",
261 _efl_ui_list_vbar_drag_cb, obj);
262 efl_layout_signal_callback_add
263 (obj, "drag,set", "efl.dragable.vbar",
264 _efl_ui_list_edje_drag_cb, obj);
265 efl_layout_signal_callback_add
266 (obj, "drag,start", "efl.dragable.vbar",
267 _efl_ui_list_edje_drag_start_cb, obj);
268 efl_layout_signal_callback_add
269 (obj, "drag,stop", "efl.dragable.vbar",
270 _efl_ui_list_edje_drag_stop_cb, obj);
271 efl_layout_signal_callback_add
272 (obj, "drag,step", "efl.dragable.vbar",
273 _efl_ui_list_edje_drag_cb, obj);
274 efl_layout_signal_callback_add
275 (obj, "drag,page", "efl.dragable.vbar",
276 _efl_ui_list_edje_drag_cb, obj);
277 efl_layout_signal_callback_add
278 (obj, "efl,vbar,press", "efl",
279 _efl_ui_list_vbar_press_cb, obj);
280 efl_layout_signal_callback_add
281 (obj, "efl,vbar,unpress", "efl",
282 _efl_ui_list_vbar_unpress_cb, obj);
283
284 /* FIXME: Horizontal Scroll is not yet supported in the list.
285 efl_layout_signal_callback_add
286 (obj, "drag", "efl.dragable.hbar",
287 _efl_ui_list_hbar_drag_cb, obj);
288 efl_layout_signal_callback_add
289 (obj, "drag,set", "efl.dragable.hbar",
290 _efl_ui_list_edje_drag_cb, obj);
291 efl_layout_signal_callback_add
292 (obj, "drag,start", "efl.dragable.hbar",
293 _efl_ui_list_edje_drag_start_cb, obj);
294 efl_layout_signal_callback_add
295 (obj, "drag,stop", "efl.dragable.hbar",
296 _efl_ui_list_edje_drag_stop_cb, obj);
297 efl_layout_signal_callback_add
298 (obj, "drag,step", "efl.dragable.hbar",
299 _efl_ui_list_edje_drag_cb, obj);
300 efl_layout_signal_callback_add
301 (obj, "drag,page", "efl.dragable.hbar",
302 _efl_ui_list_edje_drag_cb, obj);
303 efl_layout_signal_callback_add
304 (obj, "efl,hbar,press", "efl",
305 _efl_ui_list_hbar_press_cb, obj);
306 efl_layout_signal_callback_add
307 (obj, "efl,hbar,unpress", "efl",
308 _efl_ui_list_hbar_unpress_cb, obj);
309 */
310}
311
312static void
313_scroll_edje_object_detach(Eo *obj)
314{
315 EFL_UI_LIST_DATA_GET_OR_RETURN(obj, pd);
316
317 efl_layout_signal_callback_del
318 (obj, "reload", "efl",
319 _efl_ui_list_reload_cb, obj);
320 efl_layout_signal_callback_del
321 (obj, "drag", "efl.dragable.vbar",
322 _efl_ui_list_vbar_drag_cb, obj);
323 efl_layout_signal_callback_del
324 (obj, "drag,set", "efl.dragable.vbar",
325 _efl_ui_list_edje_drag_cb, obj);
326 efl_layout_signal_callback_del
327 (obj, "drag,start", "efl.dragable.vbar",
328 _efl_ui_list_edje_drag_start_cb, obj);
329 efl_layout_signal_callback_del
330 (obj, "drag,stop", "efl.dragable.vbar",
331 _efl_ui_list_edje_drag_stop_cb, obj);
332 efl_layout_signal_callback_del
333 (obj, "drag,step", "efl.dragable.vbar",
334 _efl_ui_list_edje_drag_cb, obj);
335 efl_layout_signal_callback_del
336 (obj, "drag,page", "efl.dragable.vbar",
337 _efl_ui_list_edje_drag_cb, obj);
338 efl_layout_signal_callback_del
339 (obj, "efl,vbar,press", "efl",
340 _efl_ui_list_vbar_press_cb, obj);
341 efl_layout_signal_callback_del
342 (obj, "efl,vbar,unpress", "efl",
343 _efl_ui_list_vbar_unpress_cb, obj);
344
345 /* FIXME: Horizontal Scroll is not yet supported in the list.
346 efl_layout_signal_callback_del
347 (obj, "drag", "efl.dragable.hbar",
348 _efl_ui_list_hbar_drag_cb, obj);
349 efl_layout_signal_callback_del
350 (obj, "drag,set", "efl.dragable.hbar",
351 _efl_ui_list_edje_drag_cb, obj);
352 efl_layout_signal_callback_del
353 (obj, "drag,start", "efl.dragable.hbar",
354 _efl_ui_list_edje_drag_start_cb, obj);
355 efl_layout_signal_callback_del
356 (obj, "drag,stop", "efl.dragable.hbar",
357 _efl_ui_list_edje_drag_stop_cb, obj);
358 efl_layout_signal_callback_del
359 (obj, "drag,step", "efl.dragable.hbar",
360 _efl_ui_list_edje_drag_cb, obj);
361 efl_layout_signal_callback_del
362 (obj, "drag,page", "efl.dragable.hbar",
363 _efl_ui_list_edje_drag_cb, obj);
364 efl_layout_signal_callback_del
365 (obj, "efl,hbar,press", "efl",
366 _efl_ui_list_hbar_press_cb, obj);
367 efl_layout_signal_callback_del
368 (obj, "efl,hbar,unpress", "efl",
369 _efl_ui_list_hbar_unpress_cb, obj);
370 */
371}
372
373static void
374_efl_ui_list_pan_resized_cb(void *data, const Efl_Event *ev EINA_UNUSED)
375{
376 Eo *obj = data;
377 EFL_UI_LIST_DATA_GET_OR_RETURN(obj, pd);
378 if (!pd->smanager) return;
379
380 elm_layout_sizing_eval(obj);
381
382 if (!pd->pan_resized)
383 {
384 Eina_Rect view = efl_ui_scrollable_viewport_geometry_get(pd->smanager);
385 // FIXME: Below code is workaround size check
386 if (view.h > 1)
387 {
388 pd->pan_resized = EINA_TRUE;
389 if (pd->scroll.item)
390 {
391 _item_scroll_internal(obj, pd->scroll.item, pd->scroll.align, pd->scroll.anim);
392
393 pd->scroll.item = NULL;
394 pd->scroll.align = 0.0;
395 pd->scroll.anim = EINA_FALSE;
396 return;
397 }
398 }
399 }
400}
401
402static void
403_efl_ui_list_resized_cb(void *data, const Efl_Event *ev EINA_UNUSED)
404{
405 elm_layout_sizing_eval(data);
406}
407
408static void
409_efl_ui_list_size_hint_changed_cb(void *data, const Efl_Event *ev EINA_UNUSED)
410{
411 elm_layout_sizing_eval(data);
412}
413
414EOLIAN static Eo *
415_efl_ui_list_efl_object_constructor(Eo *obj, Efl_Ui_List_Data *pd EINA_UNUSED)
416{
417 obj = efl_constructor(efl_super(obj, MY_CLASS));
418
419 return obj;
420}
421
422EOLIAN static Eo *
423_efl_ui_list_efl_object_finalize(Eo *obj,
424 Efl_Ui_List_Data *pd)
425{
426 obj = efl_finalize(efl_super(obj, MY_CLASS));
427
428 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, NULL);
429
430 efl_ui_layout_object_theme_set(obj, "list", "base", efl_ui_widget_style_get(obj));
431
432 pd->smanager = efl_add(EFL_UI_SCROLL_MANAGER_CLASS, obj);
433 efl_ui_mirrored_set(pd->smanager, efl_ui_mirrored_get(obj));
434
435 pd->pan = efl_add(EFL_UI_PAN_CLASS, obj);
436
437 efl_ui_scroll_manager_pan_set(pd->smanager, pd->pan);
438 edje_object_part_swallow(wd->resize_obj, "efl.content", pd->pan);
439
440 pd->box = efl_add(EFL_UI_BOX_CLASS, obj,
441 efl_ui_direction_set(efl_added, EFL_UI_DIR_VERTICAL));
442 efl_ui_mirrored_set(pd->box, efl_ui_mirrored_get(obj));
443 efl_content_set(pd->pan, pd->box);
444
445 pd->select_mode = EFL_UI_SELECT_SINGLE;
446
447 _scroll_edje_object_attach(obj);
448
449 efl_event_callback_add(obj, EFL_UI_SCROLLBAR_EVENT_BAR_SIZE_CHANGED,
450 _efl_ui_list_bar_size_changed_cb, obj);
451 efl_event_callback_add(obj, EFL_UI_SCROLLBAR_EVENT_BAR_POS_CHANGED,
452 _efl_ui_list_bar_pos_changed_cb, obj);
453 efl_event_callback_add(obj, EFL_UI_SCROLLBAR_EVENT_BAR_SHOW,
454 _efl_ui_list_bar_show_cb, obj);
455 efl_event_callback_add(obj, EFL_UI_SCROLLBAR_EVENT_BAR_HIDE,
456 _efl_ui_list_bar_hide_cb, obj);
457 efl_event_callback_add(obj, EFL_GFX_ENTITY_EVENT_RESIZE,
458 _efl_ui_list_resized_cb, obj);
459 efl_event_callback_add(obj, EFL_GFX_ENTITY_EVENT_CHANGE_SIZE_HINTS,
460 _efl_ui_list_size_hint_changed_cb, obj);
461 efl_event_callback_add(pd->pan, EFL_GFX_ENTITY_EVENT_RESIZE,
462 _efl_ui_list_pan_resized_cb, obj);
463
464 elm_layout_sizing_eval(obj);
465
466 return obj;
467}
468
469EOLIAN static void
470_efl_ui_list_efl_object_destructor(Eo *obj, Efl_Ui_List_Data *pd)
471{
472 _scroll_edje_object_detach(obj);
473
474 efl_event_callback_del(obj, EFL_UI_SCROLLBAR_EVENT_BAR_SIZE_CHANGED,
475 _efl_ui_list_bar_size_changed_cb, obj);
476 efl_event_callback_del(obj, EFL_UI_SCROLLBAR_EVENT_BAR_POS_CHANGED,
477 _efl_ui_list_bar_pos_changed_cb, obj);
478 efl_event_callback_del(obj, EFL_UI_SCROLLBAR_EVENT_BAR_SHOW,
479 _efl_ui_list_bar_show_cb, obj);
480 efl_event_callback_del(obj, EFL_UI_SCROLLBAR_EVENT_BAR_HIDE,
481 _efl_ui_list_bar_hide_cb, obj);
482 efl_event_callback_del(obj, EFL_GFX_ENTITY_EVENT_RESIZE,
483 _efl_ui_list_resized_cb, obj);
484 efl_event_callback_del(obj, EFL_GFX_ENTITY_EVENT_CHANGE_SIZE_HINTS,
485 _efl_ui_list_size_hint_changed_cb, obj);
486 efl_event_callback_del(pd->pan, EFL_GFX_ENTITY_EVENT_RESIZE,
487 _efl_ui_list_pan_resized_cb, obj);
488
489 efl_del(pd->box);
490 pd->box = NULL;
491 efl_del(pd->pan);
492 pd->pan = NULL;
493 efl_del(pd->smanager);
494 pd->smanager = NULL;
495
496 efl_destructor(efl_super(obj, MY_CLASS));
497}
498
499EOLIAN static void
500_efl_ui_list_efl_canvas_group_group_calculate(Eo *obj EINA_UNUSED, Efl_Ui_List_Data *pd EINA_UNUSED)
501{
502 // Need to be implemented
503 efl_canvas_group_calculate(efl_super(obj, MY_CLASS));
504}
505
506EOLIAN static void
507_efl_ui_list_elm_layout_sizing_eval(Eo *obj, Efl_Ui_List_Data *pd)
508{
509 Eina_Size2D min = {0, 0}, max = {0, 0}, size = {-1, -1};
510 Eina_Rect view = {};
511 Evas_Coord vmw = 0, vmh = 0;
512 double xw = 0.0, yw = 0.0;
513
514 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
515
516 if (pd->box)
517 {
518 min = efl_gfx_size_hint_combined_min_get(pd->box);
519 max = efl_gfx_size_hint_max_get(pd->box);
520 efl_gfx_size_hint_weight_get(pd->box, &xw, &yw);
521 }
522
523 if (pd->smanager)
524 view = efl_ui_scrollable_viewport_geometry_get(pd->smanager);
525
526 if (xw > 0.0)
527 {
528 if ((min.w > 0) && (view.w < min.w))
529 view.w = min.w;
530 else if ((max.w > 0) && (view.w > max.w))
531 view.w = max.w;
532 }
533 else if (min.w > 0)
534 view.w = min.w;
535
536 if (yw > 0.0)
537 {
538 if ((min.h > 0) && (view.h < min.h))
539 view.h = min.h;
540 else if ((max.h > 0) && (view.h > max.h))
541 view.h = max.h;
542 }
543 else if (min.h > 0)
544 view.h = min.h;
545
546 if (pd->box) efl_gfx_entity_size_set(pd->box, EINA_SIZE2D(view.w, view.h));
547
548 edje_object_size_min_calc(wd->resize_obj, &vmw, &vmh);
549
550 if (pd->match_content_w) size.w = vmw + min.w;
551 if (pd->match_content_h) size.h = vmh + min.h;
552
553 max = efl_gfx_size_hint_max_get(obj);
554 if ((max.w > 0) && (size.w > max.w)) size.w = max.w;
555 if ((max.h > 0) && (size.h > max.h)) size.h = max.h;
556
557 efl_gfx_size_hint_min_set(obj, size);
558}
559
560//FIXME: is this box related API could be improved more?
561EOLIAN static int
562_efl_ui_list_efl_container_content_count(Eo *obj EINA_UNUSED, Efl_Ui_List_Data *pd)
563{
564 return pd->box ? efl_content_count(pd->box) : 0;
565}
566
567EOLIAN static Eina_Iterator *
568_efl_ui_list_efl_container_content_iterate(Eo *obj EINA_UNUSED, Efl_Ui_List_Data *pd)
569{
570 return pd->box ? efl_content_iterate(pd->box) : NULL;
571}
572
573/* FIXME: Direction is not supported yet in the list
574 EOLIAN static void
575 _efl_ui_list_efl_ui_direction_direction_set(Eo *obj, Efl_Ui_List_Data *pd, Efl_Ui_Dir dir)
576 {
577 switch (dir)
578 {
579 case EFL_UI_DIR_RTL:
580 // FIXME: Should be inverted!
581 case EFL_UI_DIR_HORIZONTAL:
582 case EFL_UI_DIR_LTR:
583 pd->dir = EFL_UI_DIR_HORIZONTAL;
584 break;
585
586 case EFL_UI_DIR_UP:
587 // FIXME: Should be inverted!
588 case EFL_UI_DIR_DOWN:
589 case EFL_UI_DIR_VERTICAL:
590 case EFL_UI_DIR_DEFAULT:
591 default:
592 pd->dir = EFL_UI_DIR_VERTICAL;
593 break;
594 }
595
596 efl_pack_layout_request(obj);
597 }
598 */
599
600EOLIAN static Efl_Ui_Theme_Apply
601_efl_ui_list_efl_ui_widget_theme_apply(Eo *obj, Efl_Ui_List_Data *pd)
602{
603 Efl_Ui_Theme_Apply int_ret = EFL_UI_THEME_APPLY_FAILED;
604 int_ret = efl_ui_widget_theme_apply(efl_super(obj, MY_CLASS));
605 if (!int_ret) return EFL_UI_THEME_APPLY_FAILED;
606
607 efl_ui_mirrored_set(pd->smanager, efl_ui_mirrored_get(obj));
608
609 elm_layout_sizing_eval(obj);
610
611 return int_ret;
612}
613
614static void
615_list_item_pressed(void *data, const Efl_Event *event)
616{
617 Eo *obj = data;
618 Efl_Ui_List_Item *item = event->object;
619 efl_event_callback_call(obj, EFL_UI_EVENT_PRESSED, item);
620}
621
622static void
623_list_item_unpressed(void *data, const Efl_Event *event)
624{
625 Eo *obj = data;
626 Efl_Ui_List_Item *item = event->object;
627 efl_event_callback_call(obj, EFL_UI_EVENT_UNPRESSED, item);
628}
629
630static void
631_list_item_longpressed(void *data, const Efl_Event *event)
632{
633 Eo *obj = data;
634 Efl_Ui_List_Item *item = event->object;
635 efl_event_callback_call(obj, EFL_UI_EVENT_LONGPRESSED, item);
636}
637
638static void
639_list_item_selected(void *data, const Efl_Event *event)
640{
641 Eo *obj = data;
642 Efl_Ui_List_Item *item = event->object;
643 Efl_Ui_List_Item *selected;
644 EFL_UI_LIST_DATA_GET_OR_RETURN(obj, pd);
645
646 /* Single Select */
647 if (pd->select_mode != EFL_UI_SELECT_MULTI)
648 {
649 EINA_LIST_FREE(pd->selected, selected)
650 {
651 if (selected != item)
652 efl_ui_item_selected_set(selected, EINA_FALSE);
653 }
654 }
655 pd->selected = eina_list_append(pd->selected, item);
656 pd->last_selected = item;
657
658 efl_event_callback_call(obj, EFL_UI_EVENT_SELECTED, item);
659}
660
661static void
662_list_item_unselected(void *data, const Efl_Event *event)
663{
664 Eo *obj = data;
665 Efl_Ui_List_Item *item = event->object;
666 EFL_UI_LIST_DATA_GET_OR_RETURN(obj, pd);
667
668 pd->selected = eina_list_remove(pd->selected, item);
669 if (pd->last_selected == item) pd->last_selected = NULL;
670
671 efl_event_callback_call(obj, EFL_UI_EVENT_UNSELECTED, item);
672}
673
674static Eina_Bool
675_list_item_process(Eo *obj, Efl_Ui_List_Data *pd, EINA_UNUSED Efl_Ui_List_Item *it)
676{
677 EFL_UI_LIST_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
678
679 //FIXME: This is tricky workaround for set select mode and parent value.
680 EFL_UI_LIST_ITEM_DATA_GET(it, ld);
681 EFL_UI_ITEM_DATA_GET(it, id);
682 id->select_mode = &(pd->select_mode);
683 id->parent = obj;
684 ld->parent = obj;
685 efl_ui_mirrored_set(it, efl_ui_mirrored_get(obj));
686
687 efl_event_callback_add(it, EFL_UI_EVENT_PRESSED, _list_item_pressed, obj);
688 efl_event_callback_add(it, EFL_UI_EVENT_UNPRESSED, _list_item_unpressed, obj);
689 efl_event_callback_add(it, EFL_UI_EVENT_LONGPRESSED, _list_item_longpressed, obj);
690 efl_event_callback_add(it, EFL_UI_EVENT_SELECTED, _list_item_selected, obj);
691 efl_event_callback_add(it, EFL_UI_EVENT_UNSELECTED, _list_item_unselected, obj);
692
693 return EINA_TRUE;
694}
695
696static void
697_list_item_clear(Eo *obj, Efl_Ui_List_Data *pd EINA_UNUSED, EINA_UNUSED Efl_Ui_List_Item *it)
698{
699 EFL_UI_LIST_ITEM_CHECK_OR_RETURN(it);
700 EFL_UI_LIST_ITEM_DATA_GET(it, ld);
701 EFL_UI_ITEM_DATA_GET(it, id);
702 id->select_mode = NULL;
703 id->parent = NULL;
704 ld->parent = NULL;
705
706 efl_event_callback_del(it, EFL_UI_EVENT_PRESSED, _list_item_pressed, obj);
707 efl_event_callback_del(it, EFL_UI_EVENT_UNPRESSED, _list_item_unpressed, obj);
708 efl_event_callback_del(it, EFL_UI_EVENT_LONGPRESSED, _list_item_longpressed, obj);
709 efl_event_callback_del(it, EFL_UI_EVENT_SELECTED, _list_item_selected, obj);
710 efl_event_callback_del(it, EFL_UI_EVENT_UNSELECTED, _list_item_unselected, obj);
711}
712
713/* Pack APIs */
714EOLIAN static Eina_Bool
715_efl_ui_list_efl_pack_pack_clear(Eo *obj, Efl_Ui_List_Data *pd)
716{
717 Eina_Bool ret = efl_pack_clear(pd->box);
718
719 if (ret)
720 {
721 eina_list_free(pd->items);
722 eina_list_free(pd->selected);
723 pd->items = NULL;
724 pd->selected = NULL;
725 }
726
727 elm_layout_sizing_eval(obj);
728 return ret;
729}
730
731EOLIAN static Eina_Bool
732_efl_ui_list_efl_pack_unpack_all(Eo *obj, Efl_Ui_List_Data *pd)
733{
734 Eina_Bool ret = efl_pack_unpack_all(pd->box);
735
736 if (ret)
737 {
738 Efl_Ui_List_Item *it = NULL;
739 EINA_LIST_FREE(pd->items, it)
740 {
741 _list_item_clear(obj, pd, it);
742 }
743 eina_list_free(pd->selected);
744 pd->items = NULL;
745 pd->selected = NULL;
746 }
747
748 elm_layout_sizing_eval(obj);
749 return ret;
750}
751
752EOLIAN static Eina_Bool
753_efl_ui_list_efl_pack_unpack(Eo *obj, Efl_Ui_List_Data *pd, Efl_Gfx_Entity *subobj)
754{
755 Eina_Bool ret = efl_pack_unpack(pd->box, subobj);
756 Efl_Ui_List_Item *item = (Efl_Ui_List_Item *)subobj;
757
758 if (ret)
759 {
760 pd->items = eina_list_remove(pd->items, item);
761 if (efl_ui_item_selected_get(item))
762 {
763 pd->selected = eina_list_remove(pd->selected, item);
764 }
765 _list_item_clear(obj, pd, item);
766 }
767
768 elm_layout_sizing_eval(obj);
769 return ret;
770}
771
772EOLIAN static Eina_Bool
773_efl_ui_list_efl_pack_pack(Eo *obj, Efl_Ui_List_Data *pd, Efl_Gfx_Entity *subobj)
774{
775 if (!_list_item_process(obj, pd, subobj)) return EINA_FALSE;
776
777 Eina_Bool ret = efl_pack_end(pd->box, subobj);
778 pd->items = eina_list_append(pd->items, subobj);
779 return ret;
780}
781
782EOLIAN static Eina_Bool
783_efl_ui_list_efl_pack_linear_pack_end(Eo *obj, Efl_Ui_List_Data *pd, Efl_Gfx_Entity *subobj)
784{
785 if (!_list_item_process(obj, pd, subobj)) return EINA_FALSE;
786
787 Eina_Bool ret = efl_pack_end(pd->box, subobj);
788 pd->items = eina_list_append(pd->items, subobj);
789 return ret;
790}
791
792EOLIAN static Eina_Bool
793_efl_ui_list_efl_pack_linear_pack_begin(Eo *obj, Efl_Ui_List_Data *pd, Efl_Gfx_Entity *subobj)
794{
795 if (!_list_item_process(obj, pd, subobj)) return EINA_FALSE;
796
797 Eina_Bool ret = efl_pack_begin(pd->box, subobj);
798 pd->items = eina_list_prepend(pd->items, subobj);
799 return ret;
800}
801
802EOLIAN static Eina_Bool
803_efl_ui_list_efl_pack_linear_pack_before(Eo *obj,
804 Efl_Ui_List_Data *pd,
805 Efl_Gfx_Entity *subobj,
806 const Efl_Gfx_Entity *existing)
807{
808 if (!_list_item_process(obj, pd, subobj)) return EINA_FALSE;
809 EFL_UI_LIST_ITEM_CHECK_OR_RETURN(existing, EINA_FALSE);
810
811 Eina_Bool ret = efl_pack_before(pd->box, subobj, existing);
812 pd->items = eina_list_prepend_relative(pd->items, subobj, existing);
813 return ret;
814}
815
816EOLIAN static Eina_Bool
817_efl_ui_list_efl_pack_linear_pack_after(Eo *obj,
818 Efl_Ui_List_Data *pd,
819 Efl_Gfx_Entity *subobj,
820 const Efl_Gfx_Entity *existing)
821{
822 if (!_list_item_process(obj, pd, subobj)) return EINA_FALSE;
823 EFL_UI_LIST_ITEM_CHECK_OR_RETURN(existing, EINA_FALSE);
824
825 Eina_Bool ret = efl_pack_after(pd->box, subobj, existing);
826 pd->items = eina_list_append_relative(pd->items, subobj, existing);
827 return ret;
828}
829
830EOLIAN static Eina_Bool
831_efl_ui_list_efl_pack_linear_pack_at(Eo *obj,
832 Efl_Ui_List_Data *pd,
833 Efl_Gfx_Entity *subobj,
834 int index)
835{
836 if (!_list_item_process(obj, pd, subobj)) return EINA_FALSE;
837 Efl_Ui_List_Item *existing = efl_pack_content_get(pd->box, index);
838
839 Eina_Bool ret = efl_pack_at(pd->box, subobj, index);
840 pd->items = eina_list_append_relative(pd->items, subobj, existing);
841 return ret;
842}
843
844EOLIAN static Efl_Gfx_Entity *
845_efl_ui_list_efl_pack_linear_pack_content_get(Eo *obj EINA_UNUSED, Efl_Ui_List_Data *pd, int index)
846{
847 return efl_pack_content_get(pd->box, index);
848}
849
850EOLIAN static Efl_Gfx_Entity *
851_efl_ui_list_efl_pack_linear_pack_unpack_at(Eo *obj EINA_UNUSED, Efl_Ui_List_Data *pd, int index)
852{
853 return efl_pack_unpack_at(pd->box, index);
854}
855
856EOLIAN static int
857_efl_ui_list_efl_pack_linear_pack_index_get(Eo *obj EINA_UNUSED,
858 Efl_Ui_List_Data *pd,
859 const Efl_Gfx_Entity *subobj)
860{
861 return efl_pack_index_get(pd->box, subobj);
862}
863
864EOLIAN static void
865_efl_ui_list_efl_pack_layout_layout_update(Eo *obj, Efl_Ui_List_Data *pd)
866{
867 efl_pack_layout_update(pd->box);
868 elm_layout_sizing_eval(obj);
869
870 efl_event_callback_legacy_call(obj, EFL_PACK_EVENT_LAYOUT_UPDATED, NULL);
871}
872
873EOLIAN static void
874_efl_ui_list_efl_pack_layout_layout_request(Eo *obj, Efl_Ui_List_Data *pd)
875{
876 efl_pack_layout_request(pd->box);
877 elm_layout_sizing_eval(obj);
878}
879
880EOLIAN static void
881_efl_ui_list_efl_pack_pack_padding_set(Eo *obj EINA_UNUSED,
882 Efl_Ui_List_Data *pd,
883 double h,
884 double v,
885 Eina_Bool scalable)
886{
887 efl_pack_padding_set(pd->box, h, v, scalable);
888}
889
890EOLIAN static void
891_efl_ui_list_efl_pack_pack_padding_get(const Eo *obj EINA_UNUSED,
892 Efl_Ui_List_Data *pd,
893 double *h,
894 double *v,
895 Eina_Bool *scalable)
896{
897 efl_pack_padding_get(pd->box, h, v, scalable);
898}
899
900/* FIXME: align could not work properly on the list
901 EOLIAN static void
902 _efl_ui_list_efl_pack_pack_align_set(Eo *obj, Efl_Ui_List_Data *pd, double h, double v)
903 {
904 efl_pack_align_set(pd->box, h, v);
905 }
906
907 EOLIAN static void
908 _efl_ui_list_efl_pack_pack_align_get(Eo *obj EINA_UNUSED, Efl_Ui_List_Data *pd, double *h, double *v)
909 {
910 efl_pack_align_get(pd->box, &h, &v);
911 }
912 */
913
914/* Scroll APIs */
915EOLIAN static Eina_Size2D
916_efl_ui_list_efl_ui_scrollable_interactive_content_size_get(const Eo *obj EINA_UNUSED,
917 Efl_Ui_List_Data *pd)
918{
919 return efl_ui_scrollable_content_size_get(pd->smanager);
920}
921
922EOLIAN static Eina_Rect
923_efl_ui_list_efl_ui_scrollable_interactive_viewport_geometry_get(const Eo *obj EINA_UNUSED,
924 Efl_Ui_List_Data *pd)
925{
926 return efl_ui_scrollable_viewport_geometry_get(pd->smanager);
927}
928
929EOLIAN static void
930_efl_ui_list_efl_ui_scrollable_interactive_bounce_enabled_set(Eo *obj EINA_UNUSED,
931 Efl_Ui_List_Data *pd,
932 Eina_Bool horiz,
933 Eina_Bool vert)
934{
935 efl_ui_scrollable_bounce_enabled_set(pd->smanager, horiz, vert);
936}
937
938EOLIAN static void
939_efl_ui_list_efl_ui_scrollable_interactive_bounce_enabled_get(const Eo *obj EINA_UNUSED,
940 Efl_Ui_List_Data *pd,
941 Eina_Bool *horiz,
942 Eina_Bool *vert)
943{
944 efl_ui_scrollable_bounce_enabled_get(pd->smanager, horiz, vert);
945}
946
947EOLIAN static Eina_Bool
948_efl_ui_list_efl_ui_scrollable_interactive_scroll_hold_get(const Eo *obj EINA_UNUSED,
949 Efl_Ui_List_Data *pd)
950{
951 return efl_ui_scrollable_scroll_hold_get(pd->smanager);
952}
953
954EOLIAN static void
955_efl_ui_list_efl_ui_scrollable_interactive_scroll_hold_set(Eo *obj EINA_UNUSED,
956 Efl_Ui_List_Data *pd,
957 Eina_Bool hold)
958{
959 efl_ui_scrollable_scroll_hold_set(pd->smanager, hold);
960}
961
962EOLIAN static Eina_Bool
963_efl_ui_list_efl_ui_scrollable_interactive_scroll_freeze_get(const Eo *obj EINA_UNUSED,
964 Efl_Ui_List_Data *pd)
965{
966 return efl_ui_scrollable_scroll_freeze_get(pd->smanager);
967}
968
969EOLIAN static void
970_efl_ui_list_efl_ui_scrollable_interactive_scroll_freeze_set(Eo *obj EINA_UNUSED,
971 Efl_Ui_List_Data *pd,
972 Eina_Bool freeze)
973{
974 efl_ui_scrollable_scroll_freeze_set(pd->smanager, freeze);
975}
976
977EOLIAN static void
978_efl_ui_list_efl_ui_scrollable_interactive_match_content_set(Eo *obj EINA_UNUSED,
979 Efl_Ui_List_Data *pd,
980 Eina_Bool match_content_w,
981 Eina_Bool match_content_h)
982{
983 pd->match_content_w = !!match_content_w;
984 pd->match_content_h = !!match_content_h;
985
986 efl_ui_scrollable_match_content_set(pd->smanager, match_content_w, match_content_h);
987
988 elm_layout_sizing_eval(obj);
989}
990
991EOLIAN static void
992_efl_ui_list_efl_ui_scrollbar_bar_mode_set(Eo *obj EINA_UNUSED,
993 Efl_Ui_List_Data *pd,
994 Efl_Ui_Scrollbar_Mode hmode,
995 Efl_Ui_Scrollbar_Mode vmode)
996{
997 efl_ui_scrollbar_bar_mode_set(pd->smanager, hmode, vmode);
998}
999
1000EOLIAN static void
1001_efl_ui_list_efl_ui_scrollbar_bar_mode_get(const Eo *obj EINA_UNUSED,
1002 Efl_Ui_List_Data *pd,
1003 Efl_Ui_Scrollbar_Mode *hmode,
1004 Efl_Ui_Scrollbar_Mode *vmode)
1005{
1006 efl_ui_scrollbar_bar_mode_get(pd->smanager, hmode, vmode);
1007}
1008
1009EOLIAN static void
1010_efl_ui_list_efl_ui_scrollable_interactive_scroll(Eo *obj EINA_UNUSED,
1011 Efl_Ui_List_Data *pd,
1012 Eina_Rect rc,
1013 Eina_Bool animation)
1014{
1015 efl_ui_scrollable_scroll(pd->smanager, rc, animation);
1016}
1017
1018EOLIAN static void
1019_efl_ui_list_efl_ui_multi_selectable_select_mode_set(Eo *obj EINA_UNUSED,
1020 Efl_Ui_List_Data *pd,
1021 Efl_Ui_Select_Mode mode)
1022{
1023 Efl_Ui_List_Item *selected;
1024
1025 if ((pd->select_mode == EFL_UI_SELECT_MULTI &&
1026 mode != EFL_UI_SELECT_MULTI) ||
1027 mode == EFL_UI_SELECT_NONE)
1028 {
1029 Eina_List *clone = eina_list_clone(pd->selected);
1030 EINA_LIST_FREE(clone, selected)
1031 efl_ui_item_selected_set(selected, EINA_FALSE);
1032 }
1033
1034 pd->select_mode = mode;
1035}
1036
1037EOLIAN static Efl_Ui_Select_Mode
1038_efl_ui_list_efl_ui_multi_selectable_select_mode_get(const Eo *obj EINA_UNUSED, Efl_Ui_List_Data *pd)
1039{
1040 return pd->select_mode;
1041}
1042
1043/* List APIs */
1044EOLIAN static void
1045_efl_ui_list_item_scroll(Eo *obj,
1046 Efl_Ui_List_Data *pd,
1047 Efl_Ui_List_Item *item,
1048 Eina_Bool animation)
1049{
1050 // Need to be implemented here.
1051 if (pd->pan_resized)
1052 {
1053 _item_scroll_internal(obj, item, -1.0, animation);
1054 }
1055 else
1056 {
1057 pd->scroll.item = item;
1058 pd->scroll.align = -1.0;
1059 pd->scroll.anim = animation;
1060 }
1061}
1062
1063EOLIAN static void
1064_efl_ui_list_item_scroll_align(Eo *obj,
1065 Efl_Ui_List_Data *pd,
1066 Efl_Ui_List_Item *item,
1067 double align,
1068 Eina_Bool animation)
1069{
1070 // Need to be implemented here.
1071 if (pd->pan_resized)
1072 {
1073 _item_scroll_internal(obj, item, align, animation);
1074 }
1075 else
1076 {
1077 pd->scroll.item = item;
1078 pd->scroll.align = align;
1079 pd->scroll.anim = animation;
1080 }
1081}
1082
1083EOLIAN static Efl_Ui_List_Item *
1084_efl_ui_list_last_selected_item_get(const Eo *obj EINA_UNUSED, Efl_Ui_List_Data *pd)
1085{
1086 return pd->last_selected;
1087}
1088
1089static Eina_Bool
1090_list_item_iterator_next(Item_Iterator *it, void **data)
1091{
1092 Efl_Ui_List_Item *item;
1093
1094 if (!eina_iterator_next(it->real_iterator, (void **)&item))
1095 return EINA_FALSE;
1096
1097 if (data) *data = item;
1098 return EINA_TRUE;
1099}
1100
1101static Eo *
1102_list_item_iterator_get_container(Item_Iterator *it)
1103{
1104 return it->object;
1105}
1106
1107static void
1108_list_item_iterator_free(Item_Iterator *it)
1109{
1110 eina_iterator_free(it->real_iterator);
1111 eina_list_free(it->list);
1112 free(it);
1113}
1114
1115EOLIAN static Eina_Iterator *
1116_efl_ui_list_selected_items_get(Eo *obj, Efl_Ui_List_Data *pd)
1117{
1118 Item_Iterator *item;
1119
1120 item = calloc(1, sizeof(*item));
1121 if (!item) return NULL;
1122
1123 EINA_MAGIC_SET(&item->iterator, EINA_MAGIC_ITERATOR);
1124
1125 item->list = eina_list_clone(pd->selected);
1126 item->real_iterator = eina_list_iterator_new(item->list);
1127 item->iterator.version = EINA_ITERATOR_VERSION;
1128 item->iterator.next = FUNC_ITERATOR_NEXT(_list_item_iterator_next);
1129 item->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(_list_item_iterator_get_container);
1130 item->iterator.free = FUNC_ITERATOR_FREE(_list_item_iterator_free);
1131 item->object = obj;
1132
1133 return &item->iterator;
1134}
1135
1136/* Internal EO APIs and hidden overrides */
1137#define EFL_UI_LIST_EXTRA_OPS \
1138 ELM_LAYOUT_SIZING_EVAL_OPS(efl_ui_list)
1139
1140#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 @@
1import efl_ui_list_item;
2
3class Efl.Ui.List (Efl.Ui.Layout.Object,
4 Efl.Ui.Scrollable_Interactive,
5 Efl.Ui.Scrollbar,
6 Efl.Pack_Linear, Efl.Pack_Layout,
7 Efl.Ui.Clickable,
8 Efl.Ui.Selectable,
9 Efl.Ui.Multi_Selectable)
10{
11 [[Simple list widget with Pack interface.]]
12 methods {
13 item_scroll {
14 [[scroll move the item to show in the viewport.]]
15 params {
16 @in item: Efl.Ui.List_Item; [[Target item.]]
17 @in animation: bool; [[Boolean value for animation of scroll move.]]
18 }
19 }
20 item_scroll_align {
21 [[scroll move the item to show at the align position of the viewport.]]
22 params {
23 @in item: Efl.Ui.List_Item; [[Target item.]]
24 @in align: double; [[align value in Viewport.]]
25 @in animation: bool; [[Boolean value for animation of scroll move.]]
26 }
27 }
28 @property last_selected_item {
29 [[Property data of last selected item.]]
30 get {}
31 values {
32 return: Efl.Ui.List_Item; [[last selected item of list.]]
33 }
34 }
35 selected_items_get {
36 [[Get the selected items iterator. The iterator sequence will be decided by selection.]]
37 return: iterator<Efl.Ui.List_Item> @owned @warn_unused; [[Iterator covered by selected items list.
38 user have to free the iterator after used.]]
39 }
40 }
41 implements {
42 //Efl.Object
43 Efl.Object.constructor;
44 Efl.Object.finalize;
45 Efl.Object.destructor;
46
47 //Efl.Canvas
48 Efl.Canvas.Group.group_calculate;
49
50 //Efl.Container
51 Efl.Container.content_iterate;
52 Efl.Container.content_count;
53
54 //Efl.Ui.Direction.direction { get; set; } //TODO
55
56 //Efl.Ui.Widget
57 Efl.Ui.Widget.theme_apply;
58
59 //Efl.Ui.Focus
60 //Efl.Ui.Focus.Object.on_focus_update;
61
62 //Efl.Pack
63 Efl.Pack.pack_clear;
64 Efl.Pack.unpack_all;
65 Efl.Pack.unpack;
66 Efl.Pack.pack;
67 Efl.Pack_Linear.pack_begin;
68 Efl.Pack_Linear.pack_end;
69 Efl.Pack_Linear.pack_before;
70 Efl.Pack_Linear.pack_after;
71 Efl.Pack_Linear.pack_at;
72 Efl.Pack_Linear.pack_content_get;
73 Efl.Pack_Linear.pack_unpack_at;
74 Efl.Pack_Linear.pack_index_get;
75 Efl.Pack_Layout.layout_update;
76 Efl.Pack_Layout.layout_request;
77 Efl.Pack.pack_padding { get; set; }
78 //Efl.Pack.pack_align { get; set; }
79
80 //Efl.Ui.Scrollable
81 Efl.Ui.Scrollable_Interactive.scroll;
82 Efl.Ui.Scrollable_Interactive.content_size{ get; }
83 Efl.Ui.Scrollable_Interactive.viewport_geometry{ get; }
84 Efl.Ui.Scrollable_Interactive.bounce_enabled { set; get; }
85 Efl.Ui.Scrollable_Interactive.scroll_freeze { get; set; }
86 Efl.Ui.Scrollable_Interactive.scroll_hold { get; set; }
87 Efl.Ui.Scrollable_Interactive.match_content { set; }
88 Efl.Ui.Scrollbar.bar_mode { get; set; }
89
90 //Efl.Ui.Multi_Selectable
91 Efl.Ui.Multi_Selectable.select_mode {get; set;}
92 }
93}
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 @@
1#ifdef HAVE_CONFIG_H
2# include "elementary_config.h"
3#endif
4
5#define EFL_UI_LIST_DEFAULT_ITEM_PROTECTED
6
7#include <Elementary.h>
8
9#include "elm_priv.h"
10#include "efl_ui_list_default_item_part_icon.eo.h"
11#include "efl_ui_list_default_item_part_end.eo.h"
12#include "elm_part_helper.h"
13
14#define MY_CLASS EFL_UI_LIST_DEFAULT_ITEM_CLASS
15#define MY_CLASS_PFX efl_ui_list_default_item
16
17#define MY_CLASS_NAME "Efl.Ui.List_Default_Item"
18
19EOLIAN static Efl_Object *
20_efl_ui_list_default_item_efl_object_finalize(Eo *obj, void *pd EINA_UNUSED)
21{
22 Eo *eo;
23 eo = efl_finalize(efl_super(obj, MY_CLASS));
24 ELM_WIDGET_DATA_GET_OR_RETURN(eo, wd, eo);
25 Efl_Ui_Theme_Apply theme_apply = efl_ui_layout_object_theme_set(obj, "list_item", NULL, NULL);
26
27 if (theme_apply == EFL_UI_THEME_APPLY_FAILED)
28 CRI("Default Item(%p) failed to set theme [efl/list_item]!", eo);
29 return eo;
30}
31
32EOLIAN static void
33_efl_ui_list_default_item_efl_object_destructor(Eo *obj, void *pd EINA_UNUSED)
34{
35 efl_destructor(efl_super(obj, MY_CLASS));
36}
37
38/* Efl.Part */
39
40ELM_PART_TEXT_DEFAULT_GET(efl_ui_list_default_item, "efl.text")
41ELM_PART_TEXT_DEFAULT_IMPLEMENT(efl_ui_list_default_item, void)
42ELM_PART_MARKUP_DEFAULT_IMPLEMENT(efl_ui_list_default_item, void)
43ELM_PART_CONTENT_DEFAULT_GET(efl_ui_list_default_item, "efl.icon")
44ELM_PART_CONTENT_DEFAULT_IMPLEMENT(efl_ui_list_default_item, void
45)
46
47Eina_Bool
48_efl_ui_list_default_item_part_icon_efl_content_content_set(Eo *obj, void *pd EINA_UNUSED, Efl_Gfx_Entity *content)
49{
50 Elm_Part_Data *wd = efl_data_scope_get(obj, EFL_UI_WIDGET_PART_CLASS);
51 return efl_content_set(efl_part(efl_super(wd->obj, MY_CLASS), wd->part), content);
52}
53
54Efl_Gfx_Entity *
55_efl_ui_list_default_item_part_icon_efl_content_content_get(const Eo *obj, void *pd EINA_UNUSED)
56{
57 Elm_Part_Data *wd = efl_data_scope_get(obj, EFL_UI_WIDGET_PART_CLASS);
58 return efl_content_get(efl_part(efl_super(wd->obj, MY_CLASS), wd->part));
59}
60
61Efl_Gfx_Entity *
62_efl_ui_list_default_item_part_icon_efl_content_content_unset(Eo *obj, void *pd EINA_UNUSED)
63{
64 Elm_Part_Data *wd = efl_data_scope_get(obj, EFL_UI_WIDGET_PART_CLASS);
65 return efl_content_unset(efl_part(efl_super(wd->obj, MY_CLASS), wd->part));
66}
67#include "efl_ui_list_default_item_part_icon.eo.c"
68
69Eina_Bool
70_efl_ui_list_default_item_part_end_efl_content_content_set(Eo *obj, void *pd EINA_UNUSED, Efl_Gfx_Entity *content)
71{
72 Elm_Part_Data *wd = efl_data_scope_get(obj, EFL_UI_WIDGET_PART_CLASS);
73 return efl_content_set(efl_part(efl_super(wd->obj, MY_CLASS), wd->part), content);
74}
75
76Efl_Gfx_Entity *
77_efl_ui_list_default_item_part_end_efl_content_content_get(const Eo *obj, void *pd EINA_UNUSED)
78{
79 Elm_Part_Data *wd = efl_data_scope_get(obj, EFL_UI_WIDGET_PART_CLASS);
80 return efl_content_get(efl_part(efl_super(wd->obj, MY_CLASS), wd->part));
81}
82
83Efl_Gfx_Entity *
84_efl_ui_list_default_item_part_end_efl_content_content_unset(Eo *obj, void *pd EINA_UNUSED)
85{
86 Elm_Part_Data *wd = efl_data_scope_get(obj, EFL_UI_WIDGET_PART_CLASS);
87 return efl_content_unset(efl_part(efl_super(wd->obj, MY_CLASS), wd->part));
88}
89#include "efl_ui_list_default_item_part_end.eo.c"
90
91EOLIAN static Efl_Object *
92_efl_ui_list_default_item_efl_part_part(const Eo *obj, void *wd EINA_UNUSED, const char *part)
93{
94 EINA_SAFETY_ON_NULL_RETURN_VAL(part, NULL);
95 if (eina_streq(part, "text"))
96 return ELM_PART_IMPLEMENT(EFL_UI_LAYOUT_PART_TEXT_CLASS, obj, "efl.text");
97 else if (eina_streq(part, "icon"))
98 return ELM_PART_IMPLEMENT(EFL_UI_LIST_DEFAULT_ITEM_PART_ICON_CLASS, obj, "efl.icon");
99 else if (eina_streq(part, "end"))
100 return ELM_PART_IMPLEMENT(EFL_UI_LIST_DEFAULT_ITEM_PART_END_CLASS, obj, "efl.end");
101
102 return efl_part(efl_super(obj, MY_CLASS), part);
103}
104/* Efl.Part end */
105
106/* Internal EO APIs and hidden overrides */
107#define EFL_UI_LIST_DEFAULT_ITEM_EXTRA_OPS \
108 ELM_PART_TEXT_DEFAULT_OPS(efl_ui_list_default_item), \
109 ELM_PART_CONTENT_DEFAULT_OPS(efl_ui_list_default_item)
110
111#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 @@
1
2class Efl.Ui.List_Default_Item (Efl.Ui.List_Item,
3 Efl.Text,
4 Efl.Text_Markup,
5 Efl.Ui.Translatable,
6 Efl.Content)
7{
8 [[List Default Item class.
9 This class need to be sub object of list widget.
10 text and contents can be appliable by efl_text,
11 efl_content or efl_part APIs.]]
12 data: null;
13 implements {
14 //Efl.Object
15 Efl.Object.finalize;
16 Efl.Object.destructor;
17 Efl.Text.text { get; set; }
18 Efl.Text_Markup.markup { get; set; }
19 Efl.Ui.Translatable.translatable_text { get; set; }
20 Efl.Content.content { get; set; }
21 Efl.Content.content_unset;
22 Efl.Part.part;
23 }
24}
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 @@
1class Efl.Ui.List_Default_Item_Part_End (Efl.Ui.Layout.Part, Efl.Content)
2{
3 [[List Default Item internal content of end part class]]
4 data: null;
5 implements {
6 Efl.Content.content { get; set; }
7 Efl.Content.content_unset;
8 }
9} \ 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 @@
1class Efl.Ui.List_Default_Item_Part_Icon (Efl.Ui.Layout.Part, Efl.Content)
2{
3 [[List Default Item internal content of icon part class]]
4 data: null;
5 implements {
6 Efl.Content.content { get; set; }
7 Efl.Content.content_unset;
8 }
9} \ 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 @@
1#ifdef HAVE_CONFIG_H
2# include "elementary_config.h"
3#endif
4
5#define EFL_UI_LIST_EMPTY_ITEM_PROTECTED
6
7#include <Elementary.h>
8
9#include "elm_priv.h"
10#include "elm_part_helper.h"
11
12#define MY_CLASS EFL_UI_LIST_EMPTY_ITEM_CLASS
13#define MY_CLASS_PFX efl_ui_list_empty_item
14
15#define MY_CLASS_NAME "Efl.Ui.List_Empty_Item"
16
17EOLIAN static Efl_Object *
18_efl_ui_list_empty_item_efl_object_finalize(Eo *obj, void *pd EINA_UNUSED)
19{
20 Eo *eo;
21 eo = efl_finalize(efl_super(obj, MY_CLASS));
22 ELM_WIDGET_DATA_GET_OR_RETURN(eo, wd, eo);
23 Efl_Ui_Theme_Apply theme_apply = efl_ui_layout_object_theme_set(obj, "list_item", NULL, "empty");
24
25 if (theme_apply == EFL_UI_THEME_APPLY_FAILED)
26 CRI("Empty Item(%p) failed to set theme [efl/list_item:empty]!", eo);
27 return eo;
28}
29
30EOLIAN static void
31_efl_ui_list_empty_item_efl_object_destructor(Eo *obj, void *pd EINA_UNUSED)
32{
33 efl_destructor(efl_super(obj, MY_CLASS));
34}
35
36/* Efl.Part */
37ELM_PART_CONTENT_DEFAULT_GET(efl_ui_list_empty_item, "efl.content")
38ELM_PART_CONTENT_DEFAULT_IMPLEMENT(efl_ui_list_empty_item, void)
39/* Efl.Part end */
40
41EOLIAN static Efl_Object *
42_efl_ui_list_empty_item_efl_part_part(const Eo *obj, void *wd EINA_UNUSED, const char *part)
43{
44 EINA_SAFETY_ON_NULL_RETURN_VAL(part, NULL);
45 if (eina_streq(part, "content"))
46 return ELM_PART_IMPLEMENT(EFL_UI_LAYOUT_PART_CONTENT_CLASS, obj, "efl.content");
47
48 return efl_part(efl_super(obj, MY_CLASS), part);
49}
50
51/* Internal EO APIs and hidden overrides */
52
53#define EFL_UI_LIST_EMPTY_ITEM_EXTRA_OPS \
54 ELM_PART_CONTENT_DEFAULT_OPS(efl_ui_list_empty_item)
55
56#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 @@
1
2class Efl.Ui.List_Empty_Item (Efl.Ui.List_Item, Efl.Content)
3{
4 [[List Empty Item class. This item have only one swallow space,
5 thus user can decorate item by filling the swallow with
6 any kind of container.]]
7 data: null;
8 implements {
9 //Efl.Object
10 Efl.Object.finalize;
11 Efl.Object.destructor;
12 Efl.Content.content { get; set; }
13 Efl.Content.content_unset;
14 Efl.Part.part;
15 }
16}
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 @@
1#ifdef HAVE_CONFIG_H
2# include "elementary_config.h"
3#endif
4
5#define EFL_ACCESS_PROTECTED
6#define EFL_UI_WIDGET_PART_BG_PROTECTED
7
8#include <Elementary.h>
9
10#include "elm_priv.h"
11#include "efl_ui_list_item_private.h"
12
13#define MY_CLASS EFL_UI_LIST_ITEM_CLASS
14#define MY_CLASS_PFX efl_ui_list_item
15
16#define MY_CLASS_NAME "Efl.Ui.List_Item"
17
18static void
19_sizing_eval(Evas_Object *obj, Efl_Ui_List_Item_Data *pd)
20{
21 Evas_Coord minh = -1, minw = -1;
22 Evas_Coord rest_w = 0, rest_h = 0;
23 ELM_WIDGET_DATA_GET_OR_RETURN(pd->obj, wd);
24
25 edje_object_size_min_restricted_calc(wd->resize_obj, &minw, &minh,
26 rest_w, rest_h);
27 evas_object_size_hint_min_set(obj, minw, minh);
28
29 pd->needs_size_calc = EINA_FALSE;
30}
31
32static void
33_efl_ui_list_item_elm_layout_sizing_eval(Eo *obj, Efl_Ui_List_Item_Data *pd)
34{
35 if (pd->needs_size_calc) return;
36 pd->needs_size_calc = EINA_TRUE;
37
38 efl_canvas_group_change(obj);
39}
40
41EOLIAN static void
42_efl_ui_list_item_efl_canvas_group_group_calculate(Eo *obj, Efl_Ui_List_Item_Data *pd)
43{
44 if (pd->needs_size_calc)
45 {
46 _sizing_eval(obj, pd);
47 pd->needs_size_calc = EINA_FALSE;
48 }
49}
50
51EOLIAN static Eo *
52_efl_ui_list_item_efl_object_constructor(Eo *obj, Efl_Ui_List_Item_Data *pd)
53{
54 pd->obj = obj;
55 obj = efl_constructor(efl_super(obj, MY_CLASS));
56
57 return obj;
58}
59
60EOLIAN static Efl_Object *
61_efl_ui_list_item_efl_object_finalize(Eo *obj, Efl_Ui_List_Item_Data *pd EINA_UNUSED)
62{
63 Eo *eo;
64 eo = efl_finalize(efl_super(obj, MY_CLASS));
65 ELM_WIDGET_DATA_GET_OR_RETURN(eo, wd, eo);
66
67 return eo;
68}
69
70EOLIAN static void
71_efl_ui_list_item_efl_object_destructor(Eo *obj, Efl_Ui_List_Item_Data *pd EINA_UNUSED)
72{
73 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
74
75 efl_destructor(efl_super(obj, MY_CLASS));
76}
77
78/* Internal EO APIs and hidden overrides */
79
80#define EFL_UI_LIST_ITEM_EXTRA_OPS \
81 ELM_LAYOUT_SIZING_EVAL_OPS(efl_ui_list_item)
82
83#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 @@
1
2abstract Efl.Ui.List_Item (Efl.Ui.Item)
3{
4 implements {
5 //Efl.Object
6 Efl.Object.constructor;
7 Efl.Object.finalize;
8 Efl.Object.destructor;
9 //Efl.Canvas
10 Efl.Canvas.Group.group_calculate;
11 }
12}
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 @@
1#ifndef EFL_UI_LIST_ITEM_PRIVATE_H
2#define EFL_UI_LIST_ITEM_PRIVATE_H
3
4#include "Elementary.h"
5
6typedef struct _Efl_Ui_List_Item_Data
7{
8 // Eo Objects
9 Eo *obj; /* Self-Object */
10 Eo *parent; /* Parent Widget */
11 Eina_Bool needs_size_calc : 1; /* Flag for Size calculation */
12} Efl_Ui_List_Item_Data;
13
14
15#define EFL_UI_LIST_ITEM_DATA_GET(o, pd) \
16 Efl_Ui_List_Item_Data * pd = efl_data_scope_safe_get(o, EFL_UI_LIST_ITEM_CLASS)
17
18#define EFL_UI_LIST_ITEM_DATA_GET_OR_RETURN(o, ptr, ...) \
19 EFL_UI_LIST_ITEM_DATA_GET(o, ptr); \
20 if (EINA_UNLIKELY(!ptr)) \
21 { \
22 ERR("No widget data for object %p (%s)", \
23 o, evas_object_type_get(o)); \
24 return __VA_ARGS__; \
25 }
26
27#define EFL_UI_LIST_ITEM_CHECK_OR_RETURN(obj, ...) \
28 if (EINA_UNLIKELY(!efl_isa((obj), EFL_UI_LIST_ITEM_CLASS))) \
29 return __VA_ARGS__;
30
31#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 @@
1#ifndef EFL_UI_LIST_PRIVATE_H
2#define EFL_UI_LIST_PRIVATE_H
3
4#include "Elementary.h"
5
6typedef struct _Efl_Ui_List_Data
7{
8 // Eo Objects
9 Eo *box; /* Internal box for Efl.Pack support */
10 Eo *pan; /* Internal pan for scroll */
11 Eo *smanager; /* Scroll Manager for support scroll with pan */
12
13 struct {
14 Efl_Ui_List_Item *item; /* Scroll target item */
15 double align; /* Item scroll aligned position.
16 -1 is for default case of scroll in */
17 Eina_Bool anim : 1; /* boolean data for animation on scroll */
18 } scroll; /* Item scroll values for deferred operation */
19
20 Eina_List *items; /* All item list for internal maintaining */
21 Eina_List *selected; /* Selected items list */
22 Efl_Ui_List_Item *last_selected; /* latest selected item */
23
24 Efl_Ui_Select_Mode select_mode; /* Select mode for items
25 with single or multiple seleciton */
26
27 // Boolean Data
28 Eina_Bool freeze_want : 1; /* Flag for Scroll freezing */
29 Eina_Bool match_content_w: 1; /* Flag for size matching on content width.
30 it will disable horizontal scroll */
31 Eina_Bool match_content_h: 1; /* Flag for size matching on content height.
32 it will disable vertical scroll */
33 Eina_Bool pan_resized : 1; /* Flag for pan resized.
34 This value is used for checking scroll is
35 calculated after initialized */
36} Efl_Ui_List_Data;
37
38typedef struct _Item_Iterator
39{
40 Eina_Iterator iterator;
41 Eina_List *list;
42 Eina_Iterator *real_iterator;
43 Eo *object;
44} Item_Iterator;
45
46
47#define EFL_UI_LIST_DATA_GET(o, pd) \
48 Efl_Ui_List_Data * pd = efl_data_scope_safe_get(o, EFL_UI_LIST_CLASS)
49
50#define EFL_UI_LIST_DATA_GET_OR_RETURN(o, ptr, ...) \
51 EFL_UI_LIST_DATA_GET(o, ptr); \
52 if (EINA_UNLIKELY(!ptr)) \
53 { \
54 ERR("No widget data for object %p (%s)", \
55 o, evas_object_type_get(o)); \
56 return __VA_ARGS__; \
57 }
58
59#define EFL_UI_LIST_CHECK(obj) \
60 if (EINA_UNLIKELY(!efl_isa((obj), EFL_UI_LIST_CLASS))) \
61 return
62
63#endif