summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
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