summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/Makefile_Elementary.am13
-rw-r--r--src/examples/elementary/efl_ui_grid_example_1.c104
-rw-r--r--src/lib/elementary/Elementary.h5
-rw-r--r--src/lib/elementary/efl_ui_grid.c1315
-rw-r--r--src/lib/elementary/efl_ui_grid.eo96
-rw-r--r--src/lib/elementary/efl_ui_grid_default_item.c112
-rw-r--r--src/lib/elementary/efl_ui_grid_default_item.eo28
-rw-r--r--src/lib/elementary/efl_ui_grid_default_item_part_end.eo9
-rw-r--r--src/lib/elementary/efl_ui_grid_default_item_part_icon.eo9
-rw-r--r--src/lib/elementary/efl_ui_grid_item.c83
-rw-r--r--src/lib/elementary/efl_ui_grid_item.eo12
-rw-r--r--src/lib/elementary/efl_ui_grid_item_private.h41
-rw-r--r--src/lib/elementary/efl_ui_grid_private.h83
-rw-r--r--src/lib/elementary/efl_ui_list_default_item_part_icon.eo2
-rw-r--r--src/lib/elementary/meson.build10
-rw-r--r--src/tests/elementary/efl_ui_test_grid.c338
-rw-r--r--src/tests/elementary/elm_suite.c4
-rw-r--r--src/tests/elementary/elm_suite.h4
-rw-r--r--src/tests/elementary/meson.build3
19 files changed, 2268 insertions, 3 deletions
diff --git a/src/Makefile_Elementary.am b/src/Makefile_Elementary.am
index dd05b9d21f..f41adcaca6 100644
--- a/src/Makefile_Elementary.am
+++ b/src/Makefile_Elementary.am
@@ -89,6 +89,11 @@ elm_public_eolian_files = \
89 lib/elementary/efl_ui_list_default_item.eo \ 89 lib/elementary/efl_ui_list_default_item.eo \
90 lib/elementary/efl_ui_list_empty_item.eo \ 90 lib/elementary/efl_ui_list_empty_item.eo \
91 lib/elementary/efl_ui_list.eo \ 91 lib/elementary/efl_ui_list.eo \
92 lib/elementary/efl_ui_grid_item.eo \
93 lib/elementary/efl_ui_grid_default_item_part_icon.eo \
94 lib/elementary/efl_ui_grid_default_item_part_end.eo \
95 lib/elementary/efl_ui_grid_default_item.eo \
96 lib/elementary/efl_ui_grid.eo \
92 lib/elementary/efl_ui_panes_part.eo \ 97 lib/elementary/efl_ui_panes_part.eo \
93 lib/elementary/efl_ui_progressbar_part.eo \ 98 lib/elementary/efl_ui_progressbar_part.eo \
94 lib/elementary/elm_slider.eo \ 99 lib/elementary/elm_slider.eo \
@@ -415,6 +420,8 @@ includesunstable_HEADERS = \
415 lib/elementary/efl_ui_item_private.h \ 420 lib/elementary/efl_ui_item_private.h \
416 lib/elementary/efl_ui_list_item_private.h \ 421 lib/elementary/efl_ui_list_item_private.h \
417 lib/elementary/efl_ui_list_private.h \ 422 lib/elementary/efl_ui_list_private.h \
423 lib/elementary/efl_ui_grid_item_private.h \
424 lib/elementary/efl_ui_grid_private.h \
418 lib/elementary/efl_ui_list_view_private.h \ 425 lib/elementary/efl_ui_list_view_private.h \
419 lib/elementary/efl_ui_list_view_seg_array.h \ 426 lib/elementary/efl_ui_list_view_seg_array.h \
420 lib/elementary/elm_widget_web.h \ 427 lib/elementary/elm_widget_web.h \
@@ -844,6 +851,9 @@ lib_elementary_libelementary_la_SOURCES = \
844 lib/elementary/efl_ui_list_default_item.c \ 851 lib/elementary/efl_ui_list_default_item.c \
845 lib/elementary/efl_ui_list_empty_item.c \ 852 lib/elementary/efl_ui_list_empty_item.c \
846 lib/elementary/efl_ui_list.c \ 853 lib/elementary/efl_ui_list.c \
854 lib/elementary/efl_ui_grid_item.c \
855 lib/elementary/efl_ui_grid_default_item.c \
856 lib/elementary/efl_ui_grid.c \
847 lib/elementary/efl_ui_list_view.c \ 857 lib/elementary/efl_ui_list_view.c \
848 lib/elementary/efl_ui_list_view_precise_layouter.c \ 858 lib/elementary/efl_ui_list_view_precise_layouter.c \
849 lib/elementary/efl_ui_list_view_seg_array.c \ 859 lib/elementary/efl_ui_list_view_seg_array.c \
@@ -1566,7 +1576,8 @@ tests_elementary_elm_suite_SOURCES = \
1566 tests/elementary/elm_test_focus_common.c \ 1576 tests/elementary/elm_test_focus_common.c \
1567 tests/elementary/elm_test_focus_common.h \ 1577 tests/elementary/elm_test_focus_common.h \
1568 tests/elementary/elm_test_focus.c \ 1578 tests/elementary/elm_test_focus.c \
1569 tests/elementary/elm_test_focus_sub.c 1579 tests/elementary/elm_test_focus_sub.c \
1580 tests/elementary/efl_ui_test_grid.c
1570 1581
1571tests_elementary_elm_suite_CPPFLAGS = \ 1582tests_elementary_elm_suite_CPPFLAGS = \
1572-DELM_INTERNAL_API_ARGESFSDFEFC=1 \ 1583-DELM_INTERNAL_API_ARGESFSDFEFC=1 \
diff --git a/src/examples/elementary/efl_ui_grid_example_1.c b/src/examples/elementary/efl_ui_grid_example_1.c
new file mode 100644
index 0000000000..26bf850e68
--- /dev/null
+++ b/src/examples/elementary/efl_ui_grid_example_1.c
@@ -0,0 +1,104 @@
1// gcc -o efl_ui_grid_example_1 efl_ui_grid_example_1.c `pkg-config --cflags --libs elementary`
2
3#ifdef HAVE_CONFIG_H
4#include "elementary_config.h"
5#else
6#define EFL_BETA_API_SUPPORT 1
7#define EFL_EO_API_SUPPORT 1
8#endif
9
10#include <Elementary.h>
11#include <Efl.h>
12#include <stdio.h>
13
14#define IMAX 500;
15
16typedef struct _Grid_Event_Data {
17 Eo *grid;
18 Eo *item;
19} Grid_Event_Data;
20
21Eo *
22EoGenerate(const Efl_Class *klass, Eo *parent, Efl_Ui_Dir dir)
23{
24 Eo* obj = efl_add(klass, parent);
25 if (dir != EFL_UI_DIR_DEFAULT) efl_ui_direction_set(obj, dir);
26 efl_gfx_size_hint_weight_set(obj, EFL_GFX_SIZE_HINT_EXPAND, EFL_GFX_SIZE_HINT_EXPAND);
27 efl_gfx_size_hint_align_set(obj, EFL_GFX_SIZE_HINT_FILL, EFL_GFX_SIZE_HINT_FILL);
28 return obj;
29}
30
31EAPI_MAIN int
32elm_main(int argc, char **argv)
33{
34 int itemmax = IMAX;
35 int i = 0;
36 if (argv[1]) itemmax = atoi(argv[1]);
37 Eo *win, *box, *bbx, *upbtn, *allbtn, *clrbtn;
38 Eo *grid, *gitem;
39 Grid_Event_Data *gd = calloc(sizeof(Grid_Event_Data *), 1);
40
41 win = efl_add(EFL_UI_WIN_CLASS, efl_main_loop_get(),
42 efl_ui_win_type_set(efl_added, EFL_UI_WIN_BASIC),
43 efl_text_set(efl_added, "Efl.Ui.Grid"),
44 efl_ui_win_autodel_set(efl_added, EINA_TRUE));
45
46 box = EoGenerate(EFL_UI_BOX_CLASS, win, EFL_UI_DIR_VERTICAL);
47 elm_win_resize_object_add(win, box);
48
49 Eo *btn = efl_add(EFL_UI_BUTTON_CLASS, box);
50 efl_gfx_size_hint_weight_set(btn, 0.3, 0.3);
51 efl_gfx_size_hint_align_set(btn, EFL_GFX_SIZE_HINT_FILL, EFL_GFX_SIZE_HINT_FILL);
52 efl_text_set(btn, "BUTTON");
53 efl_pack_end(box, btn);
54
55 Eina_Bool horiz = 0;
56 // TEST#1 : Create Grid
57 gd->grid = grid = EoGenerate(EFL_UI_GRID_CLASS, box, (horiz ? EFL_UI_DIR_HORIZONTAL : EFL_UI_DIR_VERTICAL));
58 efl_ui_grid_item_size_set(grid, EINA_SIZE2D(100, 120)); // 4X4
59 efl_pack_padding_set(grid, 5.0, 5.0, EINA_TRUE);
60 efl_pack_align_set(grid, 0.5, 0.5);
61 efl_pack_end(box, grid);
62
63 // TEST#2 : Set Item Default Size
64
65 Efl_Ui_Grid_Item *target = NULL;
66
67 for (i = 0; i < itemmax; i++)
68 {
69 int r = 0, g = 0, b = 0;
70 // TEST#3 : Create Grid Item
71 gitem = efl_add(EFL_UI_GRID_DEFAULT_ITEM_CLASS, grid);
72 if (i == 300) target = gitem;
73 if (i == 0) gd->item = gitem;
74 Eo *rect = evas_object_rectangle_add(evas_object_evas_get(win));
75 switch (i % 5)
76 {
77 case 0:
78 r = 255;
79 break;
80 case 1:
81 g = 255;
82 break;
83 case 2:
84 b = 255;
85 break;
86 case 3:
87 r = g = b = 255;
88 break;
89 case 4:
90 r = g = b = 0;
91 break;
92 }
93 efl_gfx_color_set(rect, r, g, b, 255);
94 efl_content_set(gitem, rect);
95 // TEST#4 : Pack end
96 efl_pack_end(grid, gitem);
97 }
98
99 efl_gfx_entity_size_set(win, EINA_SIZE2D(417, 600));
100
101 elm_run();
102 return 0;
103}
104ELM_MAIN()
diff --git a/src/lib/elementary/Elementary.h b/src/lib/elementary/Elementary.h
index 1c220a11a2..9bd33c4feb 100644
--- a/src/lib/elementary/Elementary.h
+++ b/src/lib/elementary/Elementary.h
@@ -334,6 +334,11 @@ typedef Eo Efl_Ui_Focus_Manager;
334# include <efl_ui_list_default_item.eo.h> 334# include <efl_ui_list_default_item.eo.h>
335# include <efl_ui_list_empty_item.eo.h> 335# include <efl_ui_list_empty_item.eo.h>
336# include <efl_ui_list.eo.h> 336# include <efl_ui_list.eo.h>
337# include <efl_ui_grid_item.eo.h>
338# include <efl_ui_grid_default_item_part_icon.eo.h>
339# include <efl_ui_grid_default_item_part_end.eo.h>
340# include <efl_ui_grid_default_item.eo.h>
341# include <efl_ui_grid.eo.h>
337# include <efl_ui_list_view_types.eot.h> 342# include <efl_ui_list_view_types.eot.h>
338# include <efl_ui_list_view_seg_array.h> 343# include <efl_ui_list_view_seg_array.h>
339# include <efl_ui_list_view_seg_array.eo.h> 344# include <efl_ui_list_view_seg_array.eo.h>
diff --git a/src/lib/elementary/efl_ui_grid.c b/src/lib/elementary/efl_ui_grid.c
new file mode 100644
index 0000000000..e983708950
--- /dev/null
+++ b/src/lib/elementary/efl_ui_grid.c
@@ -0,0 +1,1315 @@
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_grid_private.h"
13#include "efl_ui_item_private.h"
14#include "efl_ui_grid_item_private.h"
15
16#define MY_CLASS EFL_UI_GRID_CLASS
17#define MY_CLASS_PFX efl_ui_grid
18
19#define MY_CLASS_NAME "Efl.Ui.Grid"
20
21static void _grid_clear_internal(Eo *obj, Efl_Ui_Grid_Data *pd);
22static void _grid_item_unpack_internal(Eo *obj, Efl_Ui_Grid_Data *pd, Efl_Ui_Grid_Item *item);
23
24static void
25_need_update(Efl_Ui_Grid_Data *pd)
26{
27 pd->need_update = EINA_TRUE;
28 //group_calculate call
29 efl_canvas_group_change(pd->obj);
30}
31
32static void
33_relayout(Eo *obj EINA_UNUSED, Efl_Ui_Grid_Data *pd, Eina_Position2D pan)
34{
35 Eina_List *l;
36 Efl_Ui_Grid_Item *item;
37 Efl_Ui_Grid_Item_Data *prev;
38 Eina_Position2D ipos;
39 Eina_Position2D cur = {0, 0};
40 int outer;
41 int count = 0;
42 Eina_Bool horiz = 0;
43 Eina_Size2D min, max;
44
45 if (pd->dir == EFL_UI_DIR_HORIZONTAL) horiz = 1;
46
47 if (!pd->linemax)
48 {
49 pd->linemax =(horiz ?
50 ((pd->geo.h + pd->item.pad.h) / (pd->item.size.h + pd->item.pad.h)) :
51 ((pd->geo.w + pd->item.pad.w) / (pd->item.size.w + pd->item.pad.w)));
52 if (!pd->linemax) pd->linemax = 1;
53 }
54
55
56 outer = (horiz ?
57 (pd->geo.h + pd->item.pad.h) - (pd->linemax * (pd->item.size.h + pd->item.pad.h)) :
58 (pd->geo.w + pd->item.pad.w) - (pd->linemax * (pd->item.size.w + pd->item.pad.w)));
59 // outer left top
60 outer = (horiz ? (outer * pd->item.align.h) : (outer * pd->item.align.w));
61 outer = (horiz ? (outer + pd->geo.y) : (outer + pd->geo.x));
62
63 // Block?
64 EINA_LIST_FOREACH(pd->items, l, item)
65 {
66 EFL_UI_GRID_ITEM_DATA_GET(item, id);
67
68 if (pd->need_update || id->update_me || id->update_begin)
69 {
70 // Index begin with zero value :
71 id->index = count;
72 if (id->update_me) id->update_me = EINA_FALSE;
73 if (id->update_begin)
74 {
75 id->update_begin = EINA_FALSE;
76 pd->need_update = EINA_TRUE;
77 }
78 if (horiz)
79 {
80 id->pos.row = (count % pd->linemax);
81 id->pos.col = (count / pd->linemax);
82 //Next Line
83 if (count == 0)
84 {
85 cur.x = pd->geo.x;
86 cur.y = outer;
87 }
88 else if (id->pos.row == 0)// ((cur.y + pd->item.pad.h + pd->item.size.h) > pd->geo.h)
89 {
90 cur.x = prev->geo.x + pd->item.size.w + pd->item.pad.w;
91 cur.y = outer;
92 }
93 else
94 {
95 //cur.x = cur.x;
96 cur.y = prev->geo.y + pd->item.size.h + pd->item.pad.h;
97 }
98 }
99 else
100 {
101 id->pos.row = (count / pd->linemax);
102 id->pos.col = (count % pd->linemax);
103 //Next Line
104 if (count == 0)
105 {
106 cur.x = outer;
107 cur.y = pd->geo.y;
108 }
109 else if (id->pos.col == 0)//((cur.x + pd->item.pad.w + pd->item.size.w) > pd->geo.w)
110 {
111 cur.x = outer;
112 cur.y = prev->geo.y + pd->item.size.h + pd->item.pad.h;
113 }
114 else
115 {
116 cur.x = prev->geo.x + pd->item.size.w + pd->item.pad.w;
117 //cur.y = cur.y;
118 }
119 }
120
121 min = efl_gfx_size_hint_min_get(item);
122 max = efl_gfx_size_hint_max_get(item);
123
124 if (pd->item.size.w < min.w) pd->item.size.w = min.w;
125 if (pd->item.size.h < min.h) pd->item.size.h = min.h;
126 if ((max.w > 0) && pd->item.size.w > max.w) pd->item.size.w = max.w;
127 if ((max.h > 0) && pd->item.size.h > max.h) pd->item.size.h = max.h;
128
129 id->geo.x = cur.x;
130 id->geo.y = cur.y;
131 id->geo.w = pd->item.size.w;
132 id->geo.h = pd->item.size.h;
133
134
135 }
136
137 ipos.x = id->geo.x - pan.x;
138 ipos.y = id->geo.y - pan.y;
139
140 //
141 efl_gfx_entity_position_set(item, ipos);
142 efl_gfx_entity_size_set(item, id->geo.size);
143 //efl_gfx_size_hint_restricted_min_set(item, id->geo.size);
144
145 prev = id;
146 count++;
147 }
148
149 if (horiz)
150 pd->geo.w = cur.x + pd->item.size.w + pd->item.pad.w - pd->geo.x;
151 else
152 pd->geo.h = cur.y + pd->item.size.h + pd->item.pad.h - pd->geo.y;
153
154 //efl_gfx_size_hint_restricted_min_set(pd->content, pd->geo.size);
155 efl_gfx_entity_size_set(pd->content, pd->geo.size);
156
157 pd->need_update = EINA_FALSE;
158}
159
160static void
161_reposition(Eo *obj EINA_UNUSED, Efl_Ui_Grid_Data *pd, Eina_Position2D pan)
162{
163 Efl_Ui_Grid_Item *item;
164 Eina_List *l;
165 Eina_Position2D ipos;
166
167 // Block?
168 EINA_LIST_FOREACH(pd->items, l, item)
169 {
170 EFL_UI_GRID_ITEM_DATA_GET(item, id);
171
172 ipos.x = id->geo.x - pan.x;
173 ipos.y = id->geo.y - pan.y;
174 efl_gfx_entity_position_set(item, ipos);
175 efl_gfx_entity_size_set(item, id->geo.size);
176 //efl_gfx_size_hint_min_set(item, id->geo.size);
177 }
178
179}
180
181//Need to reimplements for grid
182static void
183_item_scroll_internal(Eo *obj,
184 Efl_Ui_Grid_Item *item,
185 double align,
186 Eina_Bool anim)
187{
188 EFL_UI_GRID_DATA_GET_OR_RETURN(obj, pd);
189 Eina_Rect ipos, view;
190 Eina_Position2D vpos;
191
192 if (!pd->smanager) return;
193
194 ipos = efl_gfx_entity_geometry_get(item);
195 view = efl_ui_scrollable_viewport_geometry_get(pd->smanager);
196 vpos = efl_ui_scrollable_content_pos_get(pd->smanager);
197
198 if (pd->dir == EFL_UI_DIR_HORIZONTAL)
199 {
200 ipos.y = view.y;
201 ipos.h = ipos.h;
202
203 // FIXME: align case will not correctly show in the position because of
204 // bar size calculation. there are no certain way to know the scroll calcuation finished.
205 if (EINA_DBL_EQ(align, -1.0)) //Internal Prefix
206 {
207 ipos.x = ipos.x + vpos.x - view.x;
208 ipos.w = ipos.w;
209 }
210 else if ((align > 0.0 || EINA_DBL_EQ(align, 0.0)) &&
211 (align < 1.0 || EINA_DBL_EQ(align, 1.0)))
212 {
213 ipos.x = ipos.x + vpos.x - view.x - (int)((view.w - ipos.w) * align);
214 ipos.w = view.w;
215 }
216 else ERR("align (%.2lf) is not proper value. it must be the value between [0.0 , 1.0]!", align);
217
218 }
219 else //VERTICAL
220 {
221 ipos.x = view.x;
222 ipos.w = ipos.w;
223
224 // FIXME: align case will not correctly show in the position because of
225 // bar size calculation. there are no certain way to know the scroll calcuation finished.
226 if (EINA_DBL_EQ(align, -1.0)) //Internal Prefix
227 {
228 ipos.y = ipos.y + vpos.y - view.y;
229 ipos.h = ipos.h;
230 }
231 else if ((align > 0.0 || EINA_DBL_EQ(align, 0.0)) &&
232 (align < 1.0 || EINA_DBL_EQ(align, 1.0)))
233 {
234 ipos.y = ipos.y + vpos.y - view.y - (int)((view.h - ipos.h) * align);
235 ipos.h = view.h;
236 }
237 else ERR("align (%.2lf) is not proper value. it must be the value between [0.0 , 1.0]!", align);
238 }
239
240 efl_ui_scrollable_scroll(pd->smanager, ipos, anim);
241}
242
243static void
244_efl_ui_grid_bar_read_and_update(Eo *obj)
245{
246 EFL_UI_GRID_DATA_GET_OR_RETURN(obj, pd);
247 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
248 double vx = 0.0, vy = 0.0;
249
250 edje_object_part_drag_value_get
251 (wd->resize_obj, "efl.dragable.vbar", NULL, &vy);
252
253 edje_object_part_drag_value_get
254 (wd->resize_obj, "efl.dragable.hbar", &vx, NULL);
255
256 efl_ui_scrollbar_bar_position_set(pd->smanager, vx, vy);
257}
258
259static void
260_efl_ui_grid_reload_cb(void *data,
261 Evas_Object *obj EINA_UNUSED,
262 const char *emission EINA_UNUSED,
263 const char *source EINA_UNUSED)
264{
265 Eo *list = data;
266 EFL_UI_GRID_DATA_GET_OR_RETURN(list, pd);
267
268 efl_ui_scrollbar_bar_visibility_update(pd->smanager);
269}
270
271static void
272_efl_ui_grid_vbar_drag_cb(void *data,
273 Evas_Object *obj EINA_UNUSED,
274 const char *emission EINA_UNUSED,
275 const char *source EINA_UNUSED)
276{
277 _efl_ui_grid_bar_read_and_update(data);
278
279 Efl_Ui_Scrollbar_Direction type = EFL_UI_SCROLLBAR_DIRECTION_VERTICAL;
280 efl_event_callback_call(data, EFL_UI_SCROLLBAR_EVENT_BAR_DRAG, &type);
281}
282
283static void
284_efl_ui_grid_vbar_press_cb(void *data,
285 Evas_Object *obj EINA_UNUSED,
286 const char *emission EINA_UNUSED,
287 const char *source EINA_UNUSED)
288{
289 Efl_Ui_Scrollbar_Direction type = EFL_UI_SCROLLBAR_DIRECTION_VERTICAL;
290 efl_event_callback_call(data, EFL_UI_SCROLLBAR_EVENT_BAR_PRESS, &type);
291}
292
293static void
294_efl_ui_grid_vbar_unpress_cb(void *data,
295 Evas_Object *obj EINA_UNUSED,
296 const char *emission EINA_UNUSED,
297 const char *source EINA_UNUSED)
298{
299 Efl_Ui_Scrollbar_Direction type = EFL_UI_SCROLLBAR_DIRECTION_VERTICAL;
300 efl_event_callback_call(data, EFL_UI_SCROLLBAR_EVENT_BAR_UNPRESS, &type);
301}
302
303static void
304_efl_ui_grid_edje_drag_start_cb(void *data,
305 Evas_Object *obj EINA_UNUSED,
306 const char *emission EINA_UNUSED,
307 const char *source EINA_UNUSED)
308{
309 Eo *list = data;
310 EFL_UI_GRID_DATA_GET_OR_RETURN(list, pd);
311
312 _efl_ui_grid_bar_read_and_update(list);
313
314 pd->freeze_want = efl_ui_scrollable_scroll_freeze_get(pd->smanager);
315 efl_ui_scrollable_scroll_freeze_set(pd->smanager, EINA_TRUE);
316 efl_event_callback_call(list, EFL_UI_EVENT_SCROLL_DRAG_START, NULL);
317}
318
319static void
320_efl_ui_grid_edje_drag_stop_cb(void *data,
321 Evas_Object *obj EINA_UNUSED,
322 const char *emission EINA_UNUSED,
323 const char *source EINA_UNUSED)
324{
325 Eo *list = data;
326 EFL_UI_GRID_DATA_GET_OR_RETURN(list, pd);
327
328 _efl_ui_grid_bar_read_and_update(list);
329
330 efl_ui_scrollable_scroll_freeze_set(pd->smanager, pd->freeze_want);
331 efl_event_callback_call(list, EFL_UI_EVENT_SCROLL_DRAG_STOP, NULL);
332}
333
334static void
335_efl_ui_grid_edje_drag_cb(void *data,
336 Evas_Object *obj EINA_UNUSED,
337 const char *emission EINA_UNUSED,
338 const char *source EINA_UNUSED)
339{
340 _efl_ui_grid_bar_read_and_update(data);
341}
342
343static void
344_efl_ui_grid_hbar_drag_cb(void *data,
345 Evas_Object *obj EINA_UNUSED,
346 const char *emission EINA_UNUSED,
347 const char *source EINA_UNUSED)
348{
349 _efl_ui_grid_bar_read_and_update(data);
350
351 Efl_Ui_Scrollbar_Direction type = EFL_UI_SCROLLBAR_DIRECTION_HORIZONTAL;
352 efl_event_callback_call(data, EFL_UI_SCROLLBAR_EVENT_BAR_DRAG, &type);
353}
354
355static void
356_efl_ui_grid_hbar_press_cb(void *data,
357 Evas_Object *obj EINA_UNUSED,
358 const char *emission EINA_UNUSED,
359 const char *source EINA_UNUSED)
360{
361 Efl_Ui_Scrollbar_Direction type = EFL_UI_SCROLLBAR_DIRECTION_HORIZONTAL;
362 efl_event_callback_call(data, EFL_UI_SCROLLBAR_EVENT_BAR_PRESS, &type);
363}
364
365static void
366_efl_ui_grid_hbar_unpress_cb(void *data,
367 Evas_Object *obj EINA_UNUSED,
368 const char *emission EINA_UNUSED,
369 const char *source EINA_UNUSED)
370{
371 Efl_Ui_Scrollbar_Direction type = EFL_UI_SCROLLBAR_DIRECTION_HORIZONTAL;
372 efl_event_callback_call(data, EFL_UI_SCROLLBAR_EVENT_BAR_UNPRESS, &type);
373}
374
375static void
376_efl_ui_grid_bar_size_changed_cb(void *data, const Efl_Event *event EINA_UNUSED)
377{
378 Eo *obj = data;
379 EFL_UI_GRID_DATA_GET_OR_RETURN(obj, pd);
380 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
381
382 double width = 0.0, height = 0.0;
383
384 edje_object_calc_force(wd->resize_obj);
385 efl_ui_scrollbar_bar_size_get(pd->smanager, &width, &height);
386 edje_object_part_drag_size_set(wd->resize_obj, "efl.dragable.hbar", width, 1.0);
387 edje_object_part_drag_size_set(wd->resize_obj, "efl.dragable.vbar", 1.0, height);
388}
389
390static void
391_efl_ui_grid_bar_pos_changed_cb(void *data, const Efl_Event *event EINA_UNUSED)
392{
393 Eo *obj = data;
394 EFL_UI_GRID_DATA_GET_OR_RETURN(obj, pd);
395 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
396
397 double posx = 0.0, posy = 0.0;
398
399 efl_ui_scrollbar_bar_position_get(pd->smanager, &posx, &posy);
400 edje_object_part_drag_value_set(wd->resize_obj, "efl.dragable.hbar", posx, 0.0);
401 edje_object_part_drag_value_set(wd->resize_obj, "efl.dragable.vbar", 0.0, posy);
402}
403
404static void
405_efl_ui_grid_bar_show_cb(void *data, const Efl_Event *event)
406{
407 Eo *obj = data;
408 EFL_UI_GRID_DATA_GET_OR_RETURN(obj, pd);
409 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
410 Efl_Ui_Scrollbar_Direction type = *(Efl_Ui_Scrollbar_Direction *)(event->info);
411
412 if (type == EFL_UI_SCROLLBAR_DIRECTION_HORIZONTAL)
413 edje_object_signal_emit(wd->resize_obj, "efl,action,show,hbar", "efl");
414 else if (type == EFL_UI_SCROLLBAR_DIRECTION_VERTICAL)
415 edje_object_signal_emit(wd->resize_obj, "efl,action,show,vbar", "efl");
416}
417
418static void
419_efl_ui_grid_bar_hide_cb(void *data, const Efl_Event *event)
420{
421 Eo *obj = data;
422 EFL_UI_GRID_DATA_GET_OR_RETURN(obj, pd);
423 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
424 Efl_Ui_Scrollbar_Direction type = *(Efl_Ui_Scrollbar_Direction *)(event->info);
425
426 if (type == EFL_UI_SCROLLBAR_DIRECTION_HORIZONTAL)
427 edje_object_signal_emit(wd->resize_obj, "efl,action,hide,hbar", "efl");
428 else if (type == EFL_UI_SCROLLBAR_DIRECTION_VERTICAL)
429 edje_object_signal_emit(wd->resize_obj, "efl,action,hide,vbar", "efl");
430}
431
432static void
433_scroll_edje_object_attach(Eo *obj)
434{
435 EFL_UI_GRID_DATA_GET_OR_RETURN(obj, pd);
436
437 efl_layout_signal_callback_add(obj, "reload", "efl",
438 _efl_ui_grid_reload_cb, obj);
439 efl_layout_signal_callback_add(obj, "drag", "efl.dragable.vbar",
440 _efl_ui_grid_vbar_drag_cb, obj);
441 efl_layout_signal_callback_add(obj, "drag,set", "efl.dragable.vbar",
442 _efl_ui_grid_edje_drag_cb, obj);
443 efl_layout_signal_callback_add(obj, "drag,start", "efl.dragable.vbar",
444 _efl_ui_grid_edje_drag_start_cb, obj);
445 efl_layout_signal_callback_add(obj, "drag,stop", "efl.dragable.vbar",
446 _efl_ui_grid_edje_drag_stop_cb, obj);
447 efl_layout_signal_callback_add(obj, "drag,step", "efl.dragable.vbar",
448 _efl_ui_grid_edje_drag_cb, obj);
449 efl_layout_signal_callback_add(obj, "drag,page", "efl.dragable.vbar",
450 _efl_ui_grid_edje_drag_cb, obj);
451 efl_layout_signal_callback_add(obj, "efl,vbar,press", "efl",
452 _efl_ui_grid_vbar_press_cb, obj);
453 efl_layout_signal_callback_add(obj, "efl,vbar,unpress", "efl",
454 _efl_ui_grid_vbar_unpress_cb, obj);
455
456 efl_layout_signal_callback_add(obj, "drag", "efl.dragable.hbar",
457 _efl_ui_grid_hbar_drag_cb, obj);
458 efl_layout_signal_callback_add(obj, "drag,set", "efl.dragable.hbar",
459 _efl_ui_grid_edje_drag_cb, obj);
460 efl_layout_signal_callback_add(obj, "drag,start", "efl.dragable.hbar",
461 _efl_ui_grid_edje_drag_start_cb, obj);
462 efl_layout_signal_callback_add(obj, "drag,stop", "efl.dragable.hbar",
463 _efl_ui_grid_edje_drag_stop_cb, obj);
464 efl_layout_signal_callback_add(obj, "drag,step", "efl.dragable.hbar",
465 _efl_ui_grid_edje_drag_cb, obj);
466 efl_layout_signal_callback_add(obj, "drag,page", "efl.dragable.hbar",
467 _efl_ui_grid_edje_drag_cb, obj);
468 efl_layout_signal_callback_add(obj, "efl,hbar,press", "efl",
469 _efl_ui_grid_hbar_press_cb, obj);
470 efl_layout_signal_callback_add(obj, "efl,hbar,unpress", "efl",
471 _efl_ui_grid_hbar_unpress_cb, obj);
472}
473
474static void
475_scroll_edje_object_detach(Eo *obj)
476{
477 EFL_UI_GRID_DATA_GET_OR_RETURN(obj, pd);
478
479 efl_layout_signal_callback_del(obj, "reload", "efl",
480 _efl_ui_grid_reload_cb, obj);
481 efl_layout_signal_callback_del(obj, "drag", "efl.dragable.vbar",
482 _efl_ui_grid_vbar_drag_cb, obj);
483 efl_layout_signal_callback_del(obj, "drag,set", "efl.dragable.vbar",
484 _efl_ui_grid_edje_drag_cb, obj);
485 efl_layout_signal_callback_del(obj, "drag,start", "efl.dragable.vbar",
486 _efl_ui_grid_edje_drag_start_cb, obj);
487 efl_layout_signal_callback_del(obj, "drag,stop", "efl.dragable.vbar",
488 _efl_ui_grid_edje_drag_stop_cb, obj);
489 efl_layout_signal_callback_del(obj, "drag,step", "efl.dragable.vbar",
490 _efl_ui_grid_edje_drag_cb, obj);
491 efl_layout_signal_callback_del(obj, "drag,page", "efl.dragable.vbar",
492 _efl_ui_grid_edje_drag_cb, obj);
493 efl_layout_signal_callback_del(obj, "efl,vbar,press", "efl",
494 _efl_ui_grid_vbar_press_cb, obj);
495 efl_layout_signal_callback_del(obj, "efl,vbar,unpress", "efl",
496 _efl_ui_grid_vbar_unpress_cb, obj);
497
498 efl_layout_signal_callback_del(obj, "drag", "efl.dragable.hbar",
499 _efl_ui_grid_hbar_drag_cb, obj);
500 efl_layout_signal_callback_del(obj, "drag,set", "efl.dragable.hbar",
501 _efl_ui_grid_edje_drag_cb, obj);
502 efl_layout_signal_callback_del(obj, "drag,start", "efl.dragable.hbar",
503 _efl_ui_grid_edje_drag_start_cb, obj);
504 efl_layout_signal_callback_del(obj, "drag,stop", "efl.dragable.hbar",
505 _efl_ui_grid_edje_drag_stop_cb, obj);
506 efl_layout_signal_callback_del(obj, "drag,step", "efl.dragable.hbar",
507 _efl_ui_grid_edje_drag_cb, obj);
508 efl_layout_signal_callback_del(obj, "drag,page", "efl.dragable.hbar",
509 _efl_ui_grid_edje_drag_cb, obj);
510 efl_layout_signal_callback_del(obj, "efl,hbar,press", "efl",
511 _efl_ui_grid_hbar_press_cb, obj);
512 efl_layout_signal_callback_del(obj, "efl,hbar,unpress", "efl",
513 _efl_ui_grid_hbar_unpress_cb, obj);
514}
515
516static void
517_efl_ui_grid_content_moved_cb(void *data, const Efl_Event *ev EINA_UNUSED)
518{
519 Eo *obj = data;
520 EFL_UI_GRID_DATA_GET_OR_RETURN(obj, pd);
521 if (!pd->smanager) return;
522
523 efl_canvas_group_change(pd->obj);
524}
525
526static void
527_efl_ui_grid_pan_resized_cb(void *data, const Efl_Event *ev EINA_UNUSED)
528{
529 Eo *obj = data;
530 EFL_UI_GRID_DATA_GET_OR_RETURN(obj, pd);
531 if (!pd->smanager) return;
532
533 //reset linemax for recalculate layout.
534 pd->linemax = 0;
535
536 _need_update(pd);
537 elm_layout_sizing_eval(obj);
538
539 pd->pan_resized = EINA_TRUE;
540}
541
542static void
543_efl_ui_grid_resized_cb(void *data, const Efl_Event *ev EINA_UNUSED)
544{
545 elm_layout_sizing_eval(data);
546}
547
548static void
549_efl_ui_grid_size_hint_changed_cb(void *data, const Efl_Event *ev EINA_UNUSED)
550{
551 elm_layout_sizing_eval(data);
552}
553
554EOLIAN static Eo *
555_efl_ui_grid_efl_object_constructor(Eo *obj, Efl_Ui_Grid_Data *pd EINA_UNUSED)
556{
557 obj = efl_constructor(efl_super(obj, MY_CLASS));
558
559 return obj;
560}
561
562EOLIAN static Eo *
563_efl_ui_grid_efl_object_finalize(Eo *obj,
564 Efl_Ui_Grid_Data *pd)
565{
566 pd->obj = obj = efl_finalize(efl_super(obj, MY_CLASS));
567 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, NULL);
568
569 efl_ui_layout_theme_set(obj, "grid", "base", efl_ui_widget_style_get(obj));
570
571 pd->smanager = efl_add(EFL_UI_SCROLL_MANAGER_CLASS, obj);
572 efl_composite_attach(obj, pd->smanager);
573 efl_ui_mirrored_set(pd->smanager, efl_ui_mirrored_get(obj));
574
575 pd->pan = efl_add(EFL_UI_PAN_CLASS, obj);
576
577 efl_ui_scroll_manager_pan_set(pd->smanager, pd->pan);
578 edje_object_part_swallow(wd->resize_obj, "efl.content", pd->pan);
579
580 pd->select_mode = EFL_UI_SELECT_SINGLE;
581
582 if ((pd->item.size.w == 0) && (pd->item.size.h == 0))
583 {
584 pd->item.size.w = 1;
585 pd->item.size.h = 1;
586 }
587
588 _scroll_edje_object_attach(obj);
589
590 //FIXME: Workaround code! fake Content for pan resize.
591 // to remove this code, we need to customize pan class.
592 pd->content = efl_add(EFL_CANVAS_RECTANGLE_CLASS, evas_object_evas_get(obj));
593 efl_gfx_color_set(pd->content, 0, 0, 0, 0);
594 efl_content_set(pd->pan, pd->content);
595
596 efl_event_callback_add(obj, EFL_UI_SCROLLBAR_EVENT_BAR_SIZE_CHANGED,
597 _efl_ui_grid_bar_size_changed_cb, obj);
598 efl_event_callback_add(obj, EFL_UI_SCROLLBAR_EVENT_BAR_POS_CHANGED,
599 _efl_ui_grid_bar_pos_changed_cb, obj);
600 efl_event_callback_add(obj, EFL_UI_SCROLLBAR_EVENT_BAR_SHOW,
601 _efl_ui_grid_bar_show_cb, obj);
602 efl_event_callback_add(obj, EFL_UI_SCROLLBAR_EVENT_BAR_HIDE,
603 _efl_ui_grid_bar_hide_cb, obj);
604 efl_event_callback_add(obj, EFL_GFX_ENTITY_EVENT_RESIZE,
605 _efl_ui_grid_resized_cb, obj);
606 efl_event_callback_add(obj, EFL_GFX_ENTITY_EVENT_CHANGE_SIZE_HINTS,
607 _efl_ui_grid_size_hint_changed_cb, obj);
608 efl_event_callback_add(pd->pan, EFL_GFX_ENTITY_EVENT_RESIZE,
609 _efl_ui_grid_pan_resized_cb, obj);
610 efl_event_callback_add(pd->content, EFL_GFX_ENTITY_EVENT_MOVE,
611 _efl_ui_grid_content_moved_cb, obj);
612
613 elm_layout_sizing_eval(obj);
614
615 return obj;
616}
617
618
619EOLIAN static void
620_efl_ui_grid_efl_object_invalidate(Eo *obj, Efl_Ui_Grid_Data *pd)
621{
622 _scroll_edje_object_detach(obj);
623
624 efl_event_callback_del(obj, EFL_UI_SCROLLBAR_EVENT_BAR_SIZE_CHANGED,
625 _efl_ui_grid_bar_size_changed_cb, obj);
626 efl_event_callback_del(obj, EFL_UI_SCROLLBAR_EVENT_BAR_POS_CHANGED,
627 _efl_ui_grid_bar_pos_changed_cb, obj);
628 efl_event_callback_del(obj, EFL_UI_SCROLLBAR_EVENT_BAR_SHOW,
629 _efl_ui_grid_bar_show_cb, obj);
630 efl_event_callback_del(obj, EFL_UI_SCROLLBAR_EVENT_BAR_HIDE,
631 _efl_ui_grid_bar_hide_cb, obj);
632 efl_event_callback_del(obj, EFL_GFX_ENTITY_EVENT_RESIZE,
633 _efl_ui_grid_resized_cb, obj);
634 efl_event_callback_del(obj, EFL_GFX_ENTITY_EVENT_CHANGE_SIZE_HINTS,
635 _efl_ui_grid_size_hint_changed_cb, obj);
636 efl_event_callback_del(pd->pan, EFL_GFX_ENTITY_EVENT_RESIZE,
637 _efl_ui_grid_pan_resized_cb, obj);
638 efl_event_callback_del(pd->content, EFL_GFX_ENTITY_EVENT_MOVE,
639 _efl_ui_grid_content_moved_cb, obj);
640 _grid_clear_internal(obj, pd);
641
642 if (pd->smanager) efl_del(pd->smanager);
643 pd->smanager = NULL;
644 if (pd->content) efl_del(pd->content);
645 pd->content = NULL;
646 if (pd->pan) efl_del(pd->pan);
647 pd->pan = NULL;
648
649 efl_invalidate(efl_super(obj, MY_CLASS));
650}
651
652EOLIAN static void
653_efl_ui_grid_efl_object_destructor(Eo *obj, Efl_Ui_Grid_Data *pd EINA_UNUSED)
654{
655 efl_destructor(efl_super(obj, MY_CLASS));
656}
657
658EOLIAN static void
659_efl_ui_grid_efl_canvas_group_group_calculate(Eo *obj, Efl_Ui_Grid_Data *pd)
660{
661
662 Eina_Position2D pos = efl_ui_scrollable_content_pos_get(pd->smanager);
663 Eina_Rect geo = efl_ui_scrollable_viewport_geometry_get(pd->smanager);
664
665 //ERR("pos[%d,%d], geo[%d,%d,%d,%d]", pos.x, pos.y, geo.x, geo.y, geo.w, geo.h);
666
667 if (geo.w <= 1 || geo.h <= 1) return;
668 // Need to be implemented
669 if (pd->need_update)
670 {
671 _relayout(obj, pd, pos);
672 }
673 else
674 {
675 if (pd->pre_pos.x != pos.x || pd->pre_pos.y != pos.y)
676 {
677 _reposition(obj, pd, pos);
678 }
679 }
680
681 pd->pre_pos = pos;
682
683 if (pd->pan_resized)
684 {
685 pd->pan_resized = EINA_FALSE;
686 // FIXME: Below code is workaround size check
687 if ((geo.h > 1) && (pd->scroll.item))
688 {
689 _item_scroll_internal(obj, pd->scroll.item, pd->scroll.align, pd->scroll.anim);
690
691 pd->scroll.item = NULL;
692 pd->scroll.align = 0.0;
693 pd->scroll.anim = EINA_FALSE;
694 return;
695 }
696 }
697
698 efl_canvas_group_calculate(efl_super(obj, MY_CLASS));
699}
700
701EOLIAN static void
702_efl_ui_grid_elm_layout_sizing_eval(Eo *obj, Efl_Ui_Grid_Data *pd)
703{
704 Eina_Size2D min = {0, 0}, max = {0, 0}, size = {-1, -1};
705 Eina_Rect view = {};
706 Evas_Coord vmw = 0, vmh = 0;
707 double xw = 0.0, yw = 0.0;
708
709 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
710
711
712 min = efl_gfx_size_hint_combined_min_get(obj);
713 max = efl_gfx_size_hint_max_get(obj);
714
715 if (pd->smanager)
716 view = efl_ui_scrollable_viewport_geometry_get(pd->smanager);
717
718 if (xw > 0.0)
719 {
720 if ((min.w > 0) && (view.w < min.w))
721 view.w = min.w;
722 else if ((max.w > 0) && (view.w > max.w))
723 view.w = max.w;
724 }
725 else if (min.w > 0)
726 view.w = min.w;
727
728 if (yw > 0.0)
729 {
730 if ((min.h > 0) && (view.h < min.h))
731 view.h = min.h;
732 else if ((max.h > 0) && (view.h > max.h))
733 view.h = max.h;
734 }
735 else if (min.h > 0)
736 view.h = min.h;
737
738 edje_object_size_min_calc(wd->resize_obj, &vmw, &vmh);
739
740 if (pd->match_content_w) size.w = vmw + min.w;
741 if (pd->match_content_h) size.h = vmh + min.h;
742
743 max = efl_gfx_size_hint_max_get(obj);
744 if ((max.w > 0) && (size.w > max.w)) size.w = max.w;
745 if ((max.h > 0) && (size.h > max.h)) size.h = max.h;
746 pd->geo = view;
747 efl_gfx_size_hint_min_set(obj, size);
748
749 _need_update(pd);
750 return;
751}
752
753EOLIAN static int
754_efl_ui_grid_efl_container_content_count(Eo *obj EINA_UNUSED, Efl_Ui_Grid_Data *pd)
755{
756 return eina_list_count(pd->items);
757}
758
759static Eina_Bool
760_grid_item_iterator_next(Item_Iterator *it, void **data)
761{
762 Efl_Ui_Grid_Item *item;
763
764 if (!eina_iterator_next(it->real_iterator, (void **)&item))
765 return EINA_FALSE;
766
767 if (data) *data = item;
768 return EINA_TRUE;
769}
770
771static Eo *
772_grid_item_iterator_get_container(Item_Iterator *it)
773{
774 return it->object;
775}
776
777static void
778_grid_item_iterator_free(Item_Iterator *it)
779{
780 eina_iterator_free(it->real_iterator);
781 eina_list_free(it->list);
782 free(it);
783}
784
785static Eina_Iterator *
786_grid_item_iterator_new(Eo *obj, Eina_List *list)
787{
788 // NEED-TO-IMPLEMENTS
789 Item_Iterator *item;
790
791 item = calloc(1, sizeof(*item));
792 if (!item) return NULL;
793
794 EINA_MAGIC_SET(&item->iterator, EINA_MAGIC_ITERATOR);
795
796 item->list = eina_list_clone(list);
797 item->real_iterator = eina_list_iterator_new(item->list);
798 item->iterator.version = EINA_ITERATOR_VERSION;
799 item->iterator.next = FUNC_ITERATOR_NEXT(_grid_item_iterator_next);
800 item->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(_grid_item_iterator_get_container);
801 item->iterator.free = FUNC_ITERATOR_FREE(_grid_item_iterator_free);
802 item->object = obj;
803
804 return &item->iterator;
805}
806
807EOLIAN static Eina_Iterator *
808_efl_ui_grid_efl_container_content_iterate(Eo *obj, Efl_Ui_Grid_Data *pd)
809{
810 return _grid_item_iterator_new(obj, pd->items);
811}
812
813EOLIAN static void
814_efl_ui_grid_efl_ui_direction_direction_set(Eo *obj EINA_UNUSED, Efl_Ui_Grid_Data *pd, Efl_Ui_Dir dir)
815{
816 //FIXME: Currently only support horizontal and vertical mode.
817 switch (dir)
818 {
819 case EFL_UI_DIR_RTL:
820 // FIXME: Should be inverted!
821 case EFL_UI_DIR_HORIZONTAL:
822 case EFL_UI_DIR_LTR:
823 pd->dir = EFL_UI_DIR_HORIZONTAL;
824 break;
825
826 case EFL_UI_DIR_UP:
827 // FIXME: Should be inverted!
828 case EFL_UI_DIR_DOWN:
829 case EFL_UI_DIR_VERTICAL:
830 case EFL_UI_DIR_DEFAULT:
831 default:
832 pd->dir = EFL_UI_DIR_VERTICAL;
833 break;
834 }
835
836 pd->linemax = 0;
837 efl_pack_layout_request(obj);
838}
839
840EOLIAN static Efl_Ui_Dir
841_efl_ui_grid_efl_ui_direction_direction_get(const Eo *obj EINA_UNUSED, Efl_Ui_Grid_Data *pd)
842{
843 return pd->dir;
844}
845
846
847EOLIAN static Efl_Ui_Theme_Apply_Result
848_efl_ui_grid_efl_ui_widget_theme_apply(Eo *obj, Efl_Ui_Grid_Data *pd)
849{
850 Efl_Ui_Theme_Apply_Result int_ret = EFL_UI_THEME_APPLY_RESULT_FAIL;
851 int_ret = efl_ui_widget_theme_apply(efl_super(obj, MY_CLASS));
852 if (!int_ret) return EFL_UI_THEME_APPLY_RESULT_FAIL;
853
854 efl_ui_mirrored_set(pd->smanager, efl_ui_mirrored_get(obj));
855
856 elm_layout_sizing_eval(obj);
857
858 return int_ret;
859}
860
861static void
862_grid_item_pressed(void *data, const Efl_Event *event)
863{
864 Eo *obj = data;
865 Efl_Ui_Grid_Item *item = event->object;
866 efl_event_callback_call(obj, EFL_UI_EVENT_PRESSED, item);
867}
868
869static void
870_grid_item_unpressed(void *data, const Efl_Event *event)
871{
872 Eo *obj = data;
873 Efl_Ui_Grid_Item *item = event->object;
874 efl_event_callback_call(obj, EFL_UI_EVENT_UNPRESSED, item);
875}
876
877static void
878_grid_item_longpressed(void *data, const Efl_Event *event)
879{
880 Eo *obj = data;
881 Efl_Ui_Grid_Item *item = event->object;
882 efl_event_callback_call(obj, EFL_UI_EVENT_LONGPRESSED, item);
883}
884
885static void
886_grid_item_selected(void *data, const Efl_Event *event)
887{
888 Eo *obj = data;
889 Efl_Ui_Grid_Item *item = event->object;
890 Efl_Ui_Grid_Item *selected;
891 EFL_UI_GRID_DATA_GET_OR_RETURN(obj, pd);
892
893 /* Single Select */
894 if (pd->select_mode != EFL_UI_SELECT_MULTI)
895 {
896 EINA_LIST_FREE(pd->selected, selected)
897 {
898 if (selected != item)
899 efl_ui_item_selected_set(selected, EINA_FALSE);
900 }
901 }
902 pd->selected = eina_list_append(pd->selected, item);
903 pd->last_selected = item;
904
905 efl_event_callback_call(obj, EFL_UI_EVENT_SELECTED, item);
906}
907
908static void
909_grid_item_unselected(void *data, const Efl_Event *event)
910{
911 Eo *obj = data;
912 Efl_Ui_Grid_Item *item = event->object;
913 EFL_UI_GRID_DATA_GET_OR_RETURN(obj, pd);
914
915 pd->selected = eina_list_remove(pd->selected, item);
916 if (pd->last_selected == item) pd->last_selected = NULL;
917
918 efl_event_callback_call(obj, EFL_UI_EVENT_UNSELECTED, item);
919}
920
921static void
922_grid_item_deleted(void *data, const Efl_Event *event)
923{
924 Eo *obj = data;
925 Efl_Ui_Grid_Item *it = event->object;
926 EFL_UI_GRID_DATA_GET(obj, pd);
927 _grid_item_unpack_internal(obj, pd, it);
928}
929
930static Eina_Bool
931_grid_item_process(Eo *obj, Efl_Ui_Grid_Data *pd, EINA_UNUSED Efl_Ui_Grid_Item *it)
932{
933 EFL_UI_GRID_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
934
935 //FIXME: This is tricky workaround for set select mode and parent value.
936 EFL_UI_GRID_ITEM_DATA_GET(it, gd);
937 EFL_UI_ITEM_DATA_GET(it, id);
938 id->select_mode = &(pd->select_mode);
939 id->parent = obj;
940 gd->parent = obj;
941 efl_canvas_group_member_add(pd->pan, it);
942 efl_ui_mirrored_set(it, efl_ui_mirrored_get(obj));
943
944 efl_event_callback_add(it, EFL_UI_EVENT_PRESSED, _grid_item_pressed, obj);
945 efl_event_callback_add(it, EFL_UI_EVENT_UNPRESSED, _grid_item_unpressed, obj);
946 efl_event_callback_add(it, EFL_UI_EVENT_LONGPRESSED, _grid_item_longpressed, obj);
947 efl_event_callback_add(it, EFL_UI_EVENT_SELECTED, _grid_item_selected, obj);
948 efl_event_callback_add(it, EFL_UI_EVENT_UNSELECTED, _grid_item_unselected, obj);
949 efl_event_callback_add(it, EFL_EVENT_DEL, _grid_item_deleted, obj);
950
951 return EINA_TRUE;
952}
953
954static void
955_grid_item_unpack_internal(Eo *obj, Efl_Ui_Grid_Data *pd, Efl_Ui_Grid_Item *it)
956{
957 EFL_UI_GRID_ITEM_CHECK_OR_RETURN(it);
958 EFL_UI_GRID_ITEM_DATA_GET(it, ld);
959 EFL_UI_ITEM_DATA_GET(it, id);
960 id->select_mode = NULL;
961 id->parent = NULL;
962 ld->parent = NULL;
963
964 pd->items = eina_list_remove(pd->items, it);
965 if (efl_ui_item_selected_get(it))
966 {
967 pd->selected = eina_list_remove(pd->selected, it);
968 }
969
970 efl_event_callback_del(it, EFL_UI_EVENT_PRESSED, _grid_item_pressed, obj);
971 efl_event_callback_del(it, EFL_UI_EVENT_UNPRESSED, _grid_item_unpressed, obj);
972 efl_event_callback_del(it, EFL_UI_EVENT_LONGPRESSED, _grid_item_longpressed, obj);
973 efl_event_callback_del(it, EFL_UI_EVENT_SELECTED, _grid_item_selected, obj);
974 efl_event_callback_del(it, EFL_UI_EVENT_UNSELECTED, _grid_item_unselected, obj);
975 efl_event_callback_del(it, EFL_EVENT_DEL, _grid_item_deleted, obj);
976}
977
978
979static void
980_grid_clear_internal(Eo *obj EINA_UNUSED, Efl_Ui_Grid_Data *pd)
981{
982 Efl_Ui_Grid_Item *it = NULL;
983 Eina_List *l, *ll;
984 EINA_LIST_FOREACH_SAFE(pd->items, l, ll, it)
985 {
986 efl_del(it);
987 }
988 eina_list_free(pd->selected);
989 pd->items = NULL;
990 pd->selected = NULL;
991}
992
993/* Pack APIs */
994EOLIAN static Eina_Bool
995_efl_ui_grid_efl_pack_pack_clear(Eo *obj, Efl_Ui_Grid_Data *pd)
996{
997 _grid_clear_internal(obj, pd);
998
999 elm_layout_sizing_eval(obj);
1000 return EINA_TRUE;
1001}
1002
1003EOLIAN static Eina_Bool
1004_efl_ui_grid_efl_pack_unpack_all(Eo *obj, Efl_Ui_Grid_Data *pd)
1005{
1006
1007 Efl_Ui_Grid_Item *it = NULL;
1008 Eina_List *l, *ll;
1009 EINA_LIST_FOREACH_SAFE(pd->items, l, ll, it)
1010 {
1011 _grid_item_unpack_internal(obj, pd, it);
1012 }
1013 eina_list_free(pd->selected);
1014 pd->items = NULL;
1015 pd->selected = NULL;
1016
1017 elm_layout_sizing_eval(obj);
1018 return EINA_TRUE;
1019}
1020
1021EOLIAN static Eina_Bool
1022_efl_ui_grid_efl_pack_unpack(Eo *obj, Efl_Ui_Grid_Data *pd, Efl_Gfx_Entity *subobj)
1023{
1024 Efl_Ui_Grid_Item *item = (Efl_Ui_Grid_Item *)subobj;
1025
1026 _grid_item_unpack_internal(obj, pd, item);
1027
1028 elm_layout_sizing_eval(obj);
1029 return EINA_TRUE;
1030}
1031
1032EOLIAN static Eina_Bool
1033_efl_ui_grid_efl_pack_pack(Eo *obj, Efl_Ui_Grid_Data *pd EINA_UNUSED, Efl_Gfx_Entity *subobj)
1034{
1035 return efl_pack_end(obj, subobj);
1036}
1037
1038EOLIAN static Eina_Bool
1039_efl_ui_grid_efl_pack_linear_pack_end(Eo *obj, Efl_Ui_Grid_Data *pd, Efl_Gfx_Entity *subobj)
1040{
1041 if (!_grid_item_process(obj, pd, subobj)) return EINA_FALSE;
1042 EFL_UI_GRID_ITEM_DATA_GET(subobj, pid);
1043 pd->items = eina_list_append(pd->items, subobj);
1044
1045 pid->update_me = EINA_TRUE;
1046
1047 efl_canvas_group_change(obj);
1048 return EINA_TRUE;
1049}
1050
1051EOLIAN static Eina_Bool
1052_efl_ui_grid_efl_pack_linear_pack_begin(Eo *obj, Efl_Ui_Grid_Data *pd, Efl_Gfx_Entity *subobj)
1053{
1054 if (!_grid_item_process(obj, pd, subobj)) return EINA_FALSE;
1055 EFL_UI_GRID_ITEM_DATA_GET(subobj, pid);
1056 pd->items = eina_list_prepend(pd->items, subobj);
1057 // Defered item's placing in group calculation
1058 pid->update_me = EINA_TRUE;
1059 _need_update(pd);
1060 return EINA_TRUE;
1061}
1062
1063EOLIAN static Eina_Bool
1064_efl_ui_grid_efl_pack_linear_pack_before(Eo *obj,
1065 Efl_Ui_Grid_Data *pd,
1066 Efl_Gfx_Entity *subobj,
1067 const Efl_Gfx_Entity *existing)
1068{
1069 if (!_grid_item_process(obj, pd, subobj)) return EINA_FALSE;
1070 EFL_UI_GRID_ITEM_CHECK_OR_RETURN(existing, EINA_FALSE);
1071 EFL_UI_GRID_ITEM_DATA_GET(subobj, pid);
1072
1073 pd->items = eina_list_prepend_relative(pd->items, subobj, existing);
1074 // Defered item's placing in group calculation
1075 pid->update_begin = EINA_TRUE;
1076 _need_update(pd);
1077 return EINA_TRUE;
1078}
1079
1080EOLIAN static Eina_Bool
1081_efl_ui_grid_efl_pack_linear_pack_after(Eo *obj,
1082 Efl_Ui_Grid_Data *pd,
1083 Efl_Gfx_Entity *subobj,
1084 const Efl_Gfx_Entity *existing)
1085{
1086 if (!_grid_item_process(obj, pd, subobj)) return EINA_FALSE;
1087 EFL_UI_GRID_ITEM_CHECK_OR_RETURN(existing, EINA_FALSE);
1088 EFL_UI_GRID_ITEM_DATA_GET(subobj, pid);
1089
1090 pd->items = eina_list_append_relative(pd->items, subobj, existing);
1091 // Defered item's placing in group calculation
1092 pid->update_begin = EINA_TRUE;
1093 _need_update(pd);
1094 return EINA_TRUE;
1095}
1096
1097EOLIAN static Eina_Bool
1098_efl_ui_grid_efl_pack_linear_pack_at(Eo *obj,
1099 Efl_Ui_Grid_Data *pd,
1100 Efl_Gfx_Entity *subobj,
1101 int index)
1102{
1103 if (!_grid_item_process(obj, pd, subobj)) return EINA_FALSE;
1104 Efl_Ui_Grid_Item *existing = eina_list_nth(pd->items, index);
1105 EFL_UI_GRID_ITEM_DATA_GET(subobj, pid);
1106
1107 pd->items = eina_list_prepend_relative(pd->items, subobj, existing);
1108 // Defered item's placing in group calculation
1109 pid->update_begin = EINA_TRUE;
1110 _need_update(pd);
1111 return EINA_TRUE;
1112}
1113
1114EOLIAN static Efl_Gfx_Entity *
1115_efl_ui_grid_efl_pack_linear_pack_content_get(Eo *obj EINA_UNUSED, Efl_Ui_Grid_Data *pd, int index)
1116{
1117 return eina_list_nth(pd->items, index);
1118}
1119
1120EOLIAN static Efl_Gfx_Entity *
1121_efl_ui_grid_efl_pack_linear_pack_unpack_at(Eo *obj EINA_UNUSED, Efl_Ui_Grid_Data *pd, int index)
1122{
1123 Efl_Gfx_Entity *target = eina_list_nth(pd->items, index);
1124 pd->items = eina_list_remove(pd->items, target);
1125 /*
1126 if (after)
1127 {
1128 }
1129 else
1130 */
1131 _need_update(pd);
1132 return target;
1133}
1134
1135EOLIAN static int
1136_efl_ui_grid_efl_pack_linear_pack_index_get(Eo *obj EINA_UNUSED,
1137 Efl_Ui_Grid_Data *pd,
1138 const Efl_Gfx_Entity *subobj)
1139{
1140 return eina_list_data_idx(pd->items, (void *)subobj);
1141}
1142
1143EOLIAN static void
1144_efl_ui_grid_efl_pack_layout_layout_update(Eo *obj, Efl_Ui_Grid_Data *pd)
1145{
1146 _need_update(pd);
1147 elm_layout_sizing_eval(obj);
1148
1149 efl_event_callback_legacy_call(obj, EFL_PACK_EVENT_LAYOUT_UPDATED, NULL);
1150}
1151
1152EOLIAN static void
1153_efl_ui_grid_efl_pack_layout_layout_request(Eo *obj, Efl_Ui_Grid_Data *pd)
1154{
1155 _need_update(pd);
1156 elm_layout_sizing_eval(obj);
1157}
1158
1159EOLIAN static void
1160_efl_ui_grid_efl_pack_pack_padding_set(Eo *obj EINA_UNUSED,
1161 Efl_Ui_Grid_Data *pd,
1162 double h,
1163 double v,
1164 Eina_Bool scalable)
1165{
1166 pd->item.pad.w = (int )h;
1167 pd->item.pad.h = (int) v;
1168
1169 pd->pad_scalable = !!scalable;
1170
1171 //reset linemax for recalculate layout
1172 pd->linemax = 0;
1173 _need_update(pd);
1174}
1175
1176EOLIAN static void
1177_efl_ui_grid_efl_pack_pack_padding_get(const Eo *obj EINA_UNUSED,
1178 Efl_Ui_Grid_Data *pd,
1179 double *h,
1180 double *v,
1181 Eina_Bool *scalable)
1182{
1183 //??
1184 *h = (double) pd->item.pad.w;
1185 *v = (double) pd->item.pad.h;
1186 *scalable = !!pd->pad_scalable;
1187}
1188
1189EOLIAN static void
1190_efl_ui_grid_efl_pack_pack_align_set(Eo *obj EINA_UNUSED, Efl_Ui_Grid_Data *pd, double h, double v)
1191{
1192 pd->item.align.w = h;
1193 pd->item.align.h = v;
1194 _need_update(pd);
1195}
1196
1197EOLIAN static void
1198_efl_ui_grid_efl_pack_pack_align_get(const Eo *obj EINA_UNUSED, Efl_Ui_Grid_Data *pd, double *h, double *v)
1199{
1200 *h = pd->item.align.w;
1201 *v = pd->item.align.h;
1202}
1203
1204EOLIAN static void
1205_efl_ui_grid_efl_ui_scrollable_interactive_match_content_set(Eo *obj EINA_UNUSED,
1206 Efl_Ui_Grid_Data *pd,
1207 Eina_Bool match_content_w,
1208 Eina_Bool match_content_h)
1209{
1210 pd->match_content_w = !!match_content_w;
1211 pd->match_content_h = !!match_content_h;
1212
1213 efl_ui_scrollable_match_content_set(pd->smanager, match_content_w, match_content_h);
1214
1215 elm_layout_sizing_eval(obj);
1216}
1217
1218EOLIAN static void
1219_efl_ui_grid_efl_ui_multi_selectable_select_mode_set(Eo *obj EINA_UNUSED,
1220 Efl_Ui_Grid_Data *pd,
1221 Efl_Ui_Select_Mode mode)
1222{
1223 Efl_Ui_Grid_Item *selected;
1224
1225 if ((pd->select_mode == EFL_UI_SELECT_MULTI &&
1226 mode != EFL_UI_SELECT_MULTI) ||
1227 mode == EFL_UI_SELECT_NONE)
1228 {
1229 Eina_List *clone = eina_list_clone(pd->selected);
1230 EINA_LIST_FREE(clone, selected)
1231 efl_ui_item_selected_set(selected, EINA_FALSE);
1232 }
1233
1234 pd->select_mode = mode;
1235}
1236
1237EOLIAN static Efl_Ui_Select_Mode
1238_efl_ui_grid_efl_ui_multi_selectable_select_mode_get(const Eo *obj EINA_UNUSED, Efl_Ui_Grid_Data *pd)
1239{
1240 return pd->select_mode;
1241}
1242
1243/* List APIs */
1244EOLIAN static void
1245_efl_ui_grid_item_scroll(Eo *obj,
1246 Efl_Ui_Grid_Data *pd,
1247 Efl_Ui_Grid_Item *item,
1248 Eina_Bool animation)
1249{
1250 // Need to be implemented here.
1251 if (pd->pan_resized)
1252 {
1253 _item_scroll_internal(obj, item, -1.0, animation);
1254 }
1255 else
1256 {
1257 pd->scroll.item = item;
1258 pd->scroll.align = -1.0;
1259 pd->scroll.anim = animation;
1260 }
1261}
1262
1263EOLIAN static void
1264_efl_ui_grid_item_scroll_align(Eo *obj,
1265 Efl_Ui_Grid_Data *pd,
1266 Efl_Ui_Grid_Item *item,
1267 double align,
1268 Eina_Bool animation)
1269{
1270 // Need to be implemented here.
1271 if (pd->pan_resized)
1272 {
1273 _item_scroll_internal(obj, item, align, animation);
1274 }
1275 else
1276 {
1277 pd->scroll.item = item;
1278 pd->scroll.align = align;
1279 pd->scroll.anim = animation;
1280 }
1281}
1282
1283EOLIAN static Efl_Ui_Grid_Item *
1284_efl_ui_grid_last_selected_item_get(const Eo *obj EINA_UNUSED, Efl_Ui_Grid_Data *pd)
1285{
1286 return pd->last_selected;
1287}
1288
1289EOLIAN static Eina_Iterator *
1290_efl_ui_grid_selected_items_get(Eo *obj, Efl_Ui_Grid_Data *pd)
1291{
1292 return _grid_item_iterator_new(obj, pd->selected);
1293}
1294
1295EOLIAN static void
1296_efl_ui_grid_item_size_set(Eo *obj EINA_UNUSED, Efl_Ui_Grid_Data *pd, Eina_Size2D size)
1297{
1298 pd->item.size = size;
1299 //reset linemax for recalculate layout.
1300 pd->linemax = 0;
1301
1302 _need_update(pd);
1303}
1304
1305EOLIAN static Eina_Size2D
1306_efl_ui_grid_item_size_get(const Eo *obj EINA_UNUSED, Efl_Ui_Grid_Data *pd)
1307{
1308 return pd->item.size;
1309}
1310
1311/* Internal EO APIs and hidden overrides */
1312#define EFL_UI_GRID_EXTRA_OPS \
1313 ELM_LAYOUT_SIZING_EVAL_OPS(efl_ui_grid)
1314
1315#include "efl_ui_grid.eo.c"
diff --git a/src/lib/elementary/efl_ui_grid.eo b/src/lib/elementary/efl_ui_grid.eo
new file mode 100644
index 0000000000..7f92c0dc9f
--- /dev/null
+++ b/src/lib/elementary/efl_ui_grid.eo
@@ -0,0 +1,96 @@
1import efl_ui_grid_item;
2
3class Efl.Ui.Grid (Efl.Ui.Layout,
4 Efl.Ui.Scrollable_Interactive,
5 Efl.Ui.Scrollbar,
6 Efl.Pack_Linear, Efl.Pack_Layout,
7 Efl.Ui.Direction,
8 Efl.Ui.Clickable,
9 Efl.Ui.Selectable,
10 Efl.Ui.Multi_Selectable)
11{
12 [[Simple grid widget with Pack interface.]]
13 methods {
14 @property item_size {
15 [[Property data of item size.]]
16 set {}
17 get {}
18 values {
19 size: Eina.Size2D; [[last selected item of grid.]]
20 }
21 }
22 item_scroll {
23 [[scroll move the item to show in the viewport.]]
24 params {
25 @in item: Efl.Ui.Grid_Item; [[Target item.]]
26 @in animation: bool; [[Boolean value for animation of scroll move.]]
27 }
28 }
29 item_scroll_align {
30 [[scroll move the item to show at the align position of the viewport.]]
31 params {
32 @in item: Efl.Ui.Grid_Item; [[Target item.]]
33 @in align: double; [[align value in Viewport.]]
34 @in animation: bool; [[Boolean value for animation of scroll move.]]
35 }
36 }
37 @property last_selected_item {
38 [[Property data of last selected item.]]
39 get {}
40 values {
41 item: Efl.Ui.Grid_Item; [[last selected item of grid.]]
42 }
43 }
44 selected_items_get {
45 [[Get the selected items iterator. The iterator sequence will be decided by selection.]]
46 return: iterator<Efl.Ui.Grid_Item> @owned @warn_unused; [[Iterator covered by selected items list.
47 user have to free the iterator after used.]]
48 }
49 }
50 implements {
51 //Efl.Object
52 Efl.Object.constructor;
53 Efl.Object.finalize;
54 Efl.Object.destructor;
55 Efl.Object.invalidate;
56
57 //Efl.Canvas
58 Efl.Canvas.Group.group_calculate;
59 //Efl.Container
60 Efl.Container.content_iterate;
61 Efl.Container.content_count;
62
63 Efl.Ui.Direction.direction { get; set; }
64
65 //Efl.Ui.Widget
66 Efl.Ui.Widget.theme_apply;
67
68 //Efl.Ui.Focus
69 //Efl.Ui.Focus.Object.on_focus_update;
70
71 //Efl.Pack
72 Efl.Pack.pack_clear;
73 Efl.Pack.unpack_all;
74 Efl.Pack.unpack;
75 Efl.Pack.pack;
76 Efl.Pack_Linear.pack_end;
77
78 Efl.Pack_Linear.pack_begin;
79 Efl.Pack_Linear.pack_before;
80 Efl.Pack_Linear.pack_after;
81 Efl.Pack_Linear.pack_at;
82 Efl.Pack_Linear.pack_unpack_at;
83 Efl.Pack_Linear.pack_index_get;
84 Efl.Pack_Linear.pack_content_get;
85 Efl.Pack_Layout.layout_update;
86 Efl.Pack_Layout.layout_request;
87 Efl.Pack.pack_padding { get; set; }
88 Efl.Pack.pack_align { get; set; }
89
90 //Efl.Ui.Scrollable
91 Efl.Ui.Scrollable_Interactive.match_content { set; }
92
93 //Efl.Ui.Multi_Selectable
94 Efl.Ui.Multi_Selectable.select_mode {get; set;}
95 }
96}
diff --git a/src/lib/elementary/efl_ui_grid_default_item.c b/src/lib/elementary/efl_ui_grid_default_item.c
new file mode 100644
index 0000000000..ffc5e674a0
--- /dev/null
+++ b/src/lib/elementary/efl_ui_grid_default_item.c
@@ -0,0 +1,112 @@
1#ifdef HAVE_CONFIG_H
2# include "elementary_config.h"
3#endif
4
5#define EFL_UI_GRID_DEFAULT_ITEM_PROTECTED
6#define EFL_PART_PROTECTED
7
8#include <Elementary.h>
9
10#include "elm_priv.h"
11#include "efl_ui_grid_default_item_part_icon.eo.h"
12#include "efl_ui_grid_default_item_part_end.eo.h"
13#include "elm_part_helper.h"
14
15#define MY_CLASS EFL_UI_GRID_DEFAULT_ITEM_CLASS
16#define MY_CLASS_PFX efl_ui_grid_default_item
17
18#define MY_CLASS_NAME "Efl.Ui.Grid_Default_Item"
19
20EOLIAN static Efl_Object *
21_efl_ui_grid_default_item_efl_object_finalize(Eo *obj, void *pd EINA_UNUSED)
22{
23 Eo *eo;
24 eo = efl_finalize(efl_super(obj, MY_CLASS));
25 ELM_WIDGET_DATA_GET_OR_RETURN(eo, wd, eo);
26 Efl_Ui_Theme_Apply_Result theme_apply = efl_ui_layout_theme_set(obj, "grid_item", NULL, NULL);
27
28 if (theme_apply == EFL_UI_THEME_APPLY_RESULT_FAIL)
29 CRI("Default Item(%p) failed to set theme [efl/grid_item]!", eo);
30 return eo;
31}
32
33EOLIAN static void
34_efl_ui_grid_default_item_efl_object_destructor(Eo *obj, void *pd EINA_UNUSED)
35{
36 efl_destructor(efl_super(obj, MY_CLASS));
37}
38
39/* Efl.Part */
40
41ELM_PART_TEXT_DEFAULT_GET(efl_ui_grid_default_item, "efl.text")
42ELM_PART_TEXT_DEFAULT_IMPLEMENT(efl_ui_grid_default_item, void)
43ELM_PART_MARKUP_DEFAULT_IMPLEMENT(efl_ui_grid_default_item, void)
44ELM_PART_CONTENT_DEFAULT_GET(efl_ui_grid_default_item, "efl.icon")
45ELM_PART_CONTENT_DEFAULT_IMPLEMENT(efl_ui_grid_default_item, void
46)
47
48Eina_Bool
49_efl_ui_grid_default_item_part_icon_efl_content_content_set(Eo *obj, void *pd EINA_UNUSED, Efl_Gfx_Entity *content)
50{
51 Elm_Part_Data *wd = efl_data_scope_get(obj, EFL_UI_WIDGET_PART_CLASS);
52 return efl_content_set(efl_part(efl_super(wd->obj, MY_CLASS), wd->part), content);
53}
54
55Efl_Gfx_Entity *
56_efl_ui_grid_default_item_part_icon_efl_content_content_get(const Eo *obj, void *pd EINA_UNUSED)
57{
58 Elm_Part_Data *wd = efl_data_scope_get(obj, EFL_UI_WIDGET_PART_CLASS);
59 return efl_content_get(efl_part(efl_super(wd->obj, MY_CLASS), wd->part));
60}
61
62Efl_Gfx_Entity *
63_efl_ui_grid_default_item_part_icon_efl_content_content_unset(Eo *obj, void *pd EINA_UNUSED)
64{
65 Elm_Part_Data *wd = efl_data_scope_get(obj, EFL_UI_WIDGET_PART_CLASS);
66 return efl_content_unset(efl_part(efl_super(wd->obj, MY_CLASS), wd->part));
67}
68#include "efl_ui_grid_default_item_part_icon.eo.c"
69
70Eina_Bool
71_efl_ui_grid_default_item_part_end_efl_content_content_set(Eo *obj, void *pd EINA_UNUSED, Efl_Gfx_Entity *content)
72{
73 Elm_Part_Data *wd = efl_data_scope_get(obj, EFL_UI_WIDGET_PART_CLASS);
74 return efl_content_set(efl_part(efl_super(wd->obj, MY_CLASS), wd->part), content);
75}
76
77Efl_Gfx_Entity *
78_efl_ui_grid_default_item_part_end_efl_content_content_get(const Eo *obj, void *pd EINA_UNUSED)
79{
80 Elm_Part_Data *wd = efl_data_scope_get(obj, EFL_UI_WIDGET_PART_CLASS);
81 return efl_content_get(efl_part(efl_super(wd->obj, MY_CLASS), wd->part));
82}
83
84Efl_Gfx_Entity *
85_efl_ui_grid_default_item_part_end_efl_content_content_unset(Eo *obj, void *pd EINA_UNUSED)
86{
87 Elm_Part_Data *wd = efl_data_scope_get(obj, EFL_UI_WIDGET_PART_CLASS);
88 return efl_content_unset(efl_part(efl_super(wd->obj, MY_CLASS), wd->part));
89}
90#include "efl_ui_grid_default_item_part_end.eo.c"
91
92EOLIAN static Efl_Object *
93_efl_ui_grid_default_item_efl_part_part_get(const Eo *obj, void *wd EINA_UNUSED, const char *part)
94{
95 EINA_SAFETY_ON_NULL_RETURN_VAL(part, NULL);
96 if (eina_streq(part, "text"))
97 return ELM_PART_IMPLEMENT(EFL_UI_LAYOUT_PART_TEXT_CLASS, obj, "efl.text");
98 else if (eina_streq(part, "icon"))
99 return ELM_PART_IMPLEMENT(EFL_UI_GRID_DEFAULT_ITEM_PART_ICON_CLASS, obj, "efl.icon");
100 else if (eina_streq(part, "end"))
101 return ELM_PART_IMPLEMENT(EFL_UI_GRID_DEFAULT_ITEM_PART_END_CLASS, obj, "efl.end");
102
103 return efl_part_get(efl_super(obj, MY_CLASS), part);
104}
105/* Efl.Part end */
106
107/* Internal EO APIs and hidden overrides */
108#define EFL_UI_GRID_DEFAULT_ITEM_EXTRA_OPS \
109 ELM_PART_TEXT_DEFAULT_OPS(efl_ui_grid_default_item), \
110 ELM_PART_CONTENT_DEFAULT_OPS(efl_ui_grid_default_item)
111
112#include "efl_ui_grid_default_item.eo.c"
diff --git a/src/lib/elementary/efl_ui_grid_default_item.eo b/src/lib/elementary/efl_ui_grid_default_item.eo
new file mode 100644
index 0000000000..425ed14582
--- /dev/null
+++ b/src/lib/elementary/efl_ui_grid_default_item.eo
@@ -0,0 +1,28 @@
1
2class Efl.Ui.Grid_Default_Item (Efl.Ui.Grid_Item,
3 Efl.Text,
4 Efl.Text_Markup,
5 Efl.Ui.Translatable,
6 Efl.Content)
7{
8 [[Grid 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 parts {
14 icon: Efl.Ui.Grid_Default_Item_Part_Icon; [[]]
15 end: Efl.Ui.Grid_Default_Item_Part_End; [[]]
16 }
17 implements {
18 //Efl.Object
19 Efl.Object.finalize;
20 Efl.Object.destructor;
21 Efl.Text.text { get; set; }
22 Efl.Text_Markup.markup { get; set; }
23 Efl.Ui.Translatable.translatable_text { get; set; }
24 Efl.Content.content { get; set; }
25 Efl.Content.content_unset;
26 Efl.Part.part_get;
27 }
28}
diff --git a/src/lib/elementary/efl_ui_grid_default_item_part_end.eo b/src/lib/elementary/efl_ui_grid_default_item_part_end.eo
new file mode 100644
index 0000000000..486ccbd98f
--- /dev/null
+++ b/src/lib/elementary/efl_ui_grid_default_item_part_end.eo
@@ -0,0 +1,9 @@
1class Efl.Ui.Grid_Default_Item_Part_End (Efl.Ui.Layout_Part, Efl.Content)
2{
3 [[Grid 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}
diff --git a/src/lib/elementary/efl_ui_grid_default_item_part_icon.eo b/src/lib/elementary/efl_ui_grid_default_item_part_icon.eo
new file mode 100644
index 0000000000..75436f6f7c
--- /dev/null
+++ b/src/lib/elementary/efl_ui_grid_default_item_part_icon.eo
@@ -0,0 +1,9 @@
1class Efl.Ui.Grid_Default_Item_Part_Icon (Efl.Ui.Layout_Part, Efl.Content)
2{
3 [[Grid 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}
diff --git a/src/lib/elementary/efl_ui_grid_item.c b/src/lib/elementary/efl_ui_grid_item.c
new file mode 100644
index 0000000000..29daea7896
--- /dev/null
+++ b/src/lib/elementary/efl_ui_grid_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_grid_item_private.h"
12
13#define MY_CLASS EFL_UI_GRID_ITEM_CLASS
14#define MY_CLASS_PFX efl_ui_grid_item
15
16#define MY_CLASS_NAME "Efl.Ui.Grid_Item"
17
18static void
19_sizing_eval(Evas_Object *obj, Efl_Ui_Grid_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_grid_item_elm_layout_sizing_eval(Eo *obj, Efl_Ui_Grid_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_grid_item_efl_canvas_group_group_calculate(Eo *obj, Efl_Ui_Grid_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_grid_item_efl_object_constructor(Eo *obj, Efl_Ui_Grid_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_grid_item_efl_object_finalize(Eo *obj, Efl_Ui_Grid_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_grid_item_efl_object_destructor(Eo *obj, Efl_Ui_Grid_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_GRID_ITEM_EXTRA_OPS \
81 ELM_LAYOUT_SIZING_EVAL_OPS(efl_ui_grid_item)
82
83#include "efl_ui_grid_item.eo.c"
diff --git a/src/lib/elementary/efl_ui_grid_item.eo b/src/lib/elementary/efl_ui_grid_item.eo
new file mode 100644
index 0000000000..6c2eeeda01
--- /dev/null
+++ b/src/lib/elementary/efl_ui_grid_item.eo
@@ -0,0 +1,12 @@
1
2abstract Efl.Ui.Grid_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_grid_item_private.h b/src/lib/elementary/efl_ui_grid_item_private.h
new file mode 100644
index 0000000000..cec53f91ce
--- /dev/null
+++ b/src/lib/elementary/efl_ui_grid_item_private.h
@@ -0,0 +1,41 @@
1#ifndef EFL_UI_GRID_ITEM_PRIVATE_H
2#define EFL_UI_GRID_ITEM_PRIVATE_H
3
4#include "Elementary.h"
5
6typedef struct _Efl_Ui_Grid_Item_Data
7{
8 // Eo Objects
9 Eo *obj; /* Self-Object */
10 Eo *parent; /* Parent Widget */
11 Eina_Rect geo;
12 int index;
13 struct {
14 int row;
15 int col;
16 } pos;
17
18 /* Boolean Values */
19 Eina_Bool needs_size_calc : 1; /* Flag for Size calculation */
20 Eina_Bool update_me: 1;
21 Eina_Bool update_begin: 1;
22} Efl_Ui_Grid_Item_Data;
23
24
25#define EFL_UI_GRID_ITEM_DATA_GET(o, pd) \
26 Efl_Ui_Grid_Item_Data * pd = efl_data_scope_safe_get(o, EFL_UI_GRID_ITEM_CLASS)
27
28#define EFL_UI_GRID_ITEM_DATA_GET_OR_RETURN(o, ptr, ...) \
29 EFL_UI_GRID_ITEM_DATA_GET(o, ptr); \
30 if (EINA_UNLIKELY(!ptr)) \
31 { \
32 ERR("No widget data for object %p (%s)", \
33 o, evas_object_type_get(o)); \
34 return __VA_ARGS__; \
35 }
36
37#define EFL_UI_GRID_ITEM_CHECK_OR_RETURN(obj, ...) \
38 if (EINA_UNLIKELY(!efl_isa((obj), EFL_UI_GRID_ITEM_CLASS))) \
39 return __VA_ARGS__;
40
41#endif
diff --git a/src/lib/elementary/efl_ui_grid_private.h b/src/lib/elementary/efl_ui_grid_private.h
new file mode 100644
index 0000000000..a48d183639
--- /dev/null
+++ b/src/lib/elementary/efl_ui_grid_private.h
@@ -0,0 +1,83 @@
1#ifndef EFL_UI_GRID_PRIVATE_H
2#define EFL_UI_GRID_PRIVATE_H
3
4#include "Elementary.h"
5
6typedef struct _Efl_Ui_Grid_Data
7{
8 // Eo Objects
9 Eo *obj;
10 Eo *pan; /* Internal pan for scroll */
11 Eo *content;
12 Eo *smanager; /* Scroll Manager for support scroll with pan */
13 Eina_Rect geo;
14 Eina_Position2D pre_pos;
15 Efl_Ui_Dir dir;
16
17 struct {
18 Efl_Ui_Grid_Item *item; /* Scroll target item */
19 double align; /* Item scroll aligned position.
20 -1 is for default case of scroll in */
21 Eina_Bool anim : 1; /* boolean data for animation on scroll */
22 } scroll; /* Item scroll values for deferred operation */
23
24 struct {
25 Eina_Size2D size;
26 Eina_Size2D pad;
27 struct {
28 double w;
29 double h;
30 } align;
31 int count;
32 int row;
33 int col;
34 } item;
35
36 int linemax;
37
38 Eina_List *items; /* All item list for internal maintaining */
39 Eina_List *selected; /* Selected items list */
40 Efl_Ui_Grid_Item *last_selected; /* latest selected item */
41
42 Efl_Ui_Select_Mode select_mode; /* Select mode for items
43 with single or multiple seleciton */
44
45 // Boolean Data
46 Eina_Bool freeze_want : 1; /* Flag for Scroll freezing */
47 Eina_Bool match_content_w: 1; /* Flag for size matching on content width.
48 it will disable horizontal scroll */
49 Eina_Bool match_content_h: 1; /* Flag for size matching on content height.
50 it will disable vertical scroll */
51 Eina_Bool pan_resized : 1; /* Flag for pan resized.
52 This value is used for checking scroll is
53 calculated after initialized */
54 Eina_Bool need_update: 1;
55 Eina_Bool pad_scalable: 1;
56} Efl_Ui_Grid_Data;
57
58typedef struct _Item_Iterator
59{
60 Eina_Iterator iterator;
61 Eina_List *list;
62 Eina_Iterator *real_iterator;
63 Eo *object;
64} Item_Iterator;
65
66
67#define EFL_UI_GRID_DATA_GET(o, pd) \
68 Efl_Ui_Grid_Data * pd = efl_data_scope_safe_get(o, EFL_UI_GRID_CLASS)
69
70#define EFL_UI_GRID_DATA_GET_OR_RETURN(o, ptr, ...) \
71 EFL_UI_GRID_DATA_GET(o, ptr); \
72 if (EINA_UNLIKELY(!ptr)) \
73 { \
74 ERR("No widget data for object %p (%s)", \
75 o, evas_object_type_get(o)); \
76 return __VA_ARGS__; \
77 }
78
79#define EFL_UI_GRID_CHECK(obj) \
80 if (EINA_UNLIKELY(!efl_isa((obj), EFL_UI_GRID_CLASS))) \
81 return
82
83#endif
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
index b3359eb595..319be19fe3 100644
--- a/src/lib/elementary/efl_ui_list_default_item_part_icon.eo
+++ b/src/lib/elementary/efl_ui_list_default_item_part_icon.eo
@@ -6,4 +6,4 @@ class Efl.Ui.List_Default_Item_Part_Icon (Efl.Ui.Layout_Part, Efl.Content)
6 Efl.Content.content { get; set; } 6 Efl.Content.content { get; set; }
7 Efl.Content.content_unset; 7 Efl.Content.content_unset;
8 } 8 }
9} \ No newline at end of file 9}
diff --git a/src/lib/elementary/meson.build b/src/lib/elementary/meson.build
index 3420684b3f..daf89bb085 100644
--- a/src/lib/elementary/meson.build
+++ b/src/lib/elementary/meson.build
@@ -216,6 +216,11 @@ pub_eo_files = [
216 'efl_ui_list_default_item.eo', 216 'efl_ui_list_default_item.eo',
217 'efl_ui_list_empty_item.eo', 217 'efl_ui_list_empty_item.eo',
218 'efl_ui_list.eo', 218 'efl_ui_list.eo',
219 'efl_ui_grid_item.eo',
220 'efl_ui_grid_default_item_part_icon.eo',
221 'efl_ui_grid_default_item_part_end.eo',
222 'efl_ui_grid_default_item.eo',
223 'efl_ui_grid.eo',
219 'efl_ui_panes_part.eo', 224 'efl_ui_panes_part.eo',
220 'efl_ui_progressbar_part.eo', 225 'efl_ui_progressbar_part.eo',
221 'elm_slider.eo', 226 'elm_slider.eo',
@@ -441,6 +446,8 @@ elementary_headers_unstable = [
441 'efl_ui_item_private.h', 446 'efl_ui_item_private.h',
442 'efl_ui_list_item_private.h', 447 'efl_ui_list_item_private.h',
443 'efl_ui_list_private.h', 448 'efl_ui_list_private.h',
449 'efl_ui_grid_item_private.h',
450 'efl_ui_grid_private.h',
444 'efl_ui_list_view_private.h', 451 'efl_ui_list_view_private.h',
445 'efl_ui_list_view_seg_array.h', 452 'efl_ui_list_view_seg_array.h',
446 'elm_widget_web.h', 453 'elm_widget_web.h',
@@ -866,6 +873,9 @@ elementary_src = [
866 'efl_ui_list_default_item.c', 873 'efl_ui_list_default_item.c',
867 'efl_ui_list_empty_item.c', 874 'efl_ui_list_empty_item.c',
868 'efl_ui_list.c', 875 'efl_ui_list.c',
876 'efl_ui_grid_item.c',
877 'efl_ui_grid_default_item.c',
878 'efl_ui_grid.c',
869 'efl_ui_list_view.c', 879 'efl_ui_list_view.c',
870 'efl_ui_list_view_precise_layouter.c', 880 'efl_ui_list_view_precise_layouter.c',
871 'efl_ui_list_view_seg_array.c', 881 'efl_ui_list_view_seg_array.c',
diff --git a/src/tests/elementary/efl_ui_test_grid.c b/src/tests/elementary/efl_ui_test_grid.c
new file mode 100644
index 0000000000..a6975ab262
--- /dev/null
+++ b/src/tests/elementary/efl_ui_test_grid.c
@@ -0,0 +1,338 @@
1#ifdef HAVE_CONFIG_H
2# include "elementary_config.h"
3#endif
4
5#define EFL_ACCESS_OBJECT_BETA
6#include <Elementary.h>
7#include "elm_suite.h"
8
9static Eo *win, *box;
10static Efl_Ui_Grid *grid;
11
12static void
13grid_setup()
14{
15 //win = win_add();
16 win = efl_add(EFL_UI_WIN_CLASS, efl_main_loop_get(),
17 efl_ui_win_type_set(efl_added, EFL_UI_WIN_BASIC),
18 efl_text_set(efl_added, "Efl.Ui.Grid"),
19 efl_ui_win_autodel_set(efl_added, EINA_TRUE));
20 box = efl_add(EFL_UI_BOX_CLASS, win,
21 efl_ui_direction_set(efl_added, EFL_UI_DIR_VERTICAL));
22 efl_gfx_size_hint_weight_set(box, EFL_GFX_SIZE_HINT_EXPAND, EFL_GFX_SIZE_HINT_EXPAND);
23 efl_gfx_size_hint_align_set(box, EFL_GFX_SIZE_HINT_FILL, EFL_GFX_SIZE_HINT_FILL);
24 elm_win_resize_object_add(win, box);
25
26 grid = efl_add(EFL_UI_GRID_CLASS, box);
27
28 efl_ui_grid_item_size_set(grid, EINA_SIZE2D(100, 100));
29 efl_pack_padding_set(grid, 5.0, 5.0, EINA_TRUE);
30 efl_pack_align_set(grid, 0.5, 0.5);
31 efl_pack_end(box, grid);
32
33 efl_gfx_entity_size_set(win, EINA_SIZE2D(500, 500));
34}
35
36static void
37grid_teardown()
38{
39 if (grid)
40 {
41 efl_del(grid);
42 grid = NULL;
43 }
44 if (win)
45 {
46 efl_del(win);
47 win = NULL;
48 }
49}
50
51static Eina_Bool
52grid_item_pack(Eo *grid, int count, Eina_List **l)
53{
54 int i;
55 Efl_Ui_Grid_Item *item;
56 for (i = 0; i < count; i++)
57 {
58 item = efl_add(EFL_UI_GRID_DEFAULT_ITEM_CLASS, grid);
59 if (!item) return EINA_FALSE;
60 if (l) *l = eina_list_append(*l, item);
61 efl_pack(grid, item);
62 }
63 return EINA_TRUE;
64}
65
66EFL_START_TEST (efl_ui_grid_class_check)
67{
68 const char *class;
69
70 class = efl_class_name_get(grid);
71
72 ck_assert(class != NULL);
73 ck_assert(!strcmp(class, "Efl.Ui.Grid"));
74}
75EFL_END_TEST
76
77EFL_START_TEST (efl_ui_grid_pack)
78{
79 Efl_Ui_Grid_Item *item;
80 int count;
81
82 item = efl_add(EFL_UI_GRID_DEFAULT_ITEM_CLASS, grid);
83 efl_pack(grid, item);
84
85 count = efl_content_count(grid);
86
87 ck_assert(count == 1);
88}
89EFL_END_TEST
90
91EFL_START_TEST (efl_ui_grid_unpack)
92{
93 Efl_Ui_Grid_Item *item;
94 int count;
95
96 item = efl_add(EFL_UI_GRID_DEFAULT_ITEM_CLASS, grid);
97 efl_pack(grid, item);
98
99 efl_pack_unpack(grid, item);
100
101 count = efl_content_count(grid);
102 ck_assert(count == 0);
103
104 efl_del(item);
105}
106EFL_END_TEST
107
108EFL_START_TEST (efl_ui_grid_unpack_all)
109{
110 Efl_Ui_Grid_Item *item;
111 int count_before = 10;
112 int count;
113 Eina_Iterator *itor;
114
115 ck_assert(grid_item_pack(grid, count_before, NULL) != EINA_FALSE);
116
117 itor = efl_content_iterate(grid);
118 efl_pack_unpack_all(grid);
119
120 count = efl_content_count(grid);
121 ck_assert(count == 0);
122
123 EINA_ITERATOR_FOREACH(itor, item)
124 efl_del(item);
125
126 free(itor);
127}
128EFL_END_TEST
129
130EFL_START_TEST (efl_ui_grid_pack_clear)
131{
132 int count_before = 10;
133 int count;
134
135 ck_assert(grid_item_pack(grid, count_before, NULL) != EINA_FALSE);
136
137 efl_pack_clear(grid);
138
139 count = efl_content_count(grid);
140 ck_assert(count == 0);
141}
142EFL_END_TEST
143
144
145EFL_START_TEST (efl_ui_grid_pack_end)
146{
147 Efl_Ui_Grid_Item *item, *compare;
148 int count_before = 10;
149 int count;
150
151 ck_assert(grid_item_pack(grid, count_before, NULL) != EINA_FALSE);
152
153 item = efl_add(EFL_UI_GRID_DEFAULT_ITEM_CLASS, grid);
154 ck_assert(item != NULL);
155 efl_pack_end(grid, item);
156
157 count = efl_content_count(grid);
158 ck_assert(count == (count_before + 1));
159
160 compare = efl_pack_content_get(grid, (count - 1));
161 ck_assert(compare != NULL);
162 ck_assert(item == compare);
163}
164EFL_END_TEST
165
166EFL_START_TEST (efl_ui_grid_pack_begin)
167{
168 Efl_Ui_Grid_Item *item, *compare;
169 int count_before = 10;
170 int count;
171
172 ck_assert(grid_item_pack(grid, count_before, NULL) != EINA_FALSE);
173
174 item = efl_add(EFL_UI_GRID_DEFAULT_ITEM_CLASS, grid);
175 ck_assert(item != NULL);
176 efl_pack_begin(grid, item);
177
178 count = efl_content_count(grid);
179 ck_assert(count == (count_before + 1));
180
181 compare = efl_pack_content_get(grid, 0);
182 ck_assert(compare != NULL);
183 ck_assert(item == compare);
184}
185EFL_END_TEST
186
187EFL_START_TEST (efl_ui_grid_pack_after)
188{
189 Efl_Ui_Grid_Item *item, *after, *compare;
190 int count_before = 10;
191 int count;
192 int index = 5;
193
194 ck_assert(grid_item_pack(grid, count_before, NULL) != EINA_FALSE);
195
196 after = efl_pack_content_get(grid, index);
197 ck_assert(after != NULL);
198
199 item = efl_add(EFL_UI_GRID_DEFAULT_ITEM_CLASS, grid);
200 ck_assert(item != NULL);
201 efl_pack_after(grid, item, after);
202
203 count = efl_content_count(grid);
204 ck_assert(count == (count_before + 1));
205
206 compare = efl_pack_content_get(grid, index + 1);
207 ck_assert(compare != NULL);
208 ck_assert(item == compare);
209}
210EFL_END_TEST
211
212EFL_START_TEST (efl_ui_grid_pack_before)
213{
214 Efl_Ui_Grid_Item *item, *before, *compare;
215 int count_before = 10;
216 int count;
217 int index = 5;
218
219 ck_assert(grid_item_pack(grid, count_before, NULL) != EINA_FALSE);
220
221 before = efl_pack_content_get(grid, index);
222 ck_assert(before != NULL);
223
224 item = efl_add(EFL_UI_GRID_DEFAULT_ITEM_CLASS, grid);
225 ck_assert(item != NULL);
226 efl_pack_before(grid, item, before);
227
228 count = efl_content_count(grid);
229 ck_assert(count == (count_before + 1));
230
231 compare = efl_pack_content_get(grid, index);
232 ck_assert(compare != NULL);
233 ck_assert(item == compare);
234}
235EFL_END_TEST
236
237EFL_START_TEST (efl_ui_grid_content_count)
238{
239 int count = 10, compare;
240
241 ck_assert(grid_item_pack(grid, count, NULL) != EINA_FALSE);
242
243 compare = efl_content_count(grid);
244
245 ck_assert(count == compare);
246}
247EFL_END_TEST
248
249EFL_START_TEST (efl_ui_grid_content_iterate)
250{
251 int count = 10;
252 Efl_Ui_Grid_Item *item;
253 Eina_List *item_list = NULL;
254 Eina_Iterator *item_itr;
255
256 ck_assert(grid_item_pack(grid, count, &item_list) != EINA_FALSE);
257
258 /* Get Item Content Iterator */
259 item_itr = efl_content_iterate(grid);
260
261 EINA_ITERATOR_FOREACH(item_itr, item)
262 {
263 /* Compare the iterator data and list data */
264 ck_assert(item == eina_list_data_get(item_list));
265 item_list = eina_list_remove(item_list, item);
266 }
267 eina_iterator_free(item_itr);
268
269 ck_assert(item_list == NULL);
270}
271EFL_END_TEST
272
273
274int tcount = 0;
275
276static void
277grid_timer_cb(void *data EINA_UNUSED, const Efl_Event *event)
278{
279 ck_assert(0);
280 efl_del(event->object);
281 ecore_main_loop_quit();
282}
283
284static void
285grid_scroll_start_cb(void *data EINA_UNUSED, const Efl_Event *event EINA_UNUSED)
286{
287 //printf("LSH :: scroll start!!!\n");
288}
289
290static void
291grid_scroll_stop_cb(void *data, const Efl_Event *event EINA_UNUSED)
292{
293 Efl_Loop_Timer *timer = data;
294 efl_del(timer);
295 ecore_main_loop_quit();
296}
297
298EFL_CALLBACKS_ARRAY_DEFINE(grid_scroll_callbacks,
299 { EFL_UI_EVENT_SCROLL_START, grid_scroll_start_cb },
300 { EFL_UI_EVENT_SCROLL_STOP, grid_scroll_stop_cb });
301
302EFL_START_TEST (efl_ui_grid_scroll)
303{
304 Efl_Ui_Grid_Item *item;
305 Efl_Loop_Timer *timer;
306
307 ck_assert(grid_item_pack(grid, 100, NULL) != EINA_FALSE);
308 item = efl_pack_content_get(grid, 50);
309
310 timer = efl_add(EFL_LOOP_TIMER_CLASS, efl_main_loop_get(),
311 efl_event_callback_add(efl_added, EFL_LOOP_TIMER_EVENT_TICK, grid_timer_cb, NULL),
312 efl_loop_timer_loop_reset(efl_added),
313 efl_loop_timer_interval_set(efl_added, 3.0));
314
315 efl_event_callback_array_add(grid, grid_scroll_callbacks(), timer);
316 /*FIXME: efl_ui_scroll_interface only emit scroll event when animation exist */
317 efl_ui_grid_item_scroll(grid, item, EINA_TRUE);
318 ecore_main_loop_begin();
319}
320EFL_END_TEST
321
322
323void efl_ui_test_grid(TCase *tc)
324{
325 tcase_add_checked_fixture(tc, grid_setup, grid_teardown);
326 tcase_add_test(tc, efl_ui_grid_class_check);
327 tcase_add_test(tc, efl_ui_grid_pack);
328 tcase_add_test(tc, efl_ui_grid_unpack);
329 tcase_add_test(tc, efl_ui_grid_unpack_all);
330 tcase_add_test(tc, efl_ui_grid_pack_clear);
331 tcase_add_test(tc, efl_ui_grid_pack_end);
332 tcase_add_test(tc, efl_ui_grid_pack_begin);
333 tcase_add_test(tc, efl_ui_grid_pack_after);
334 tcase_add_test(tc, efl_ui_grid_pack_before);
335 tcase_add_test(tc, efl_ui_grid_content_count);
336 tcase_add_test(tc, efl_ui_grid_content_iterate);
337 tcase_add_test(tc, efl_ui_grid_scroll);
338}
diff --git a/src/tests/elementary/elm_suite.c b/src/tests/elementary/elm_suite.c
index 198179b880..a4914e0ae8 100644
--- a/src/tests/elementary/elm_suite.c
+++ b/src/tests/elementary/elm_suite.c
@@ -89,6 +89,10 @@ static const Efl_Test_Case etc[] = {
89 { "elm_code_widget_undo", elm_code_test_widget_undo }, 89 { "elm_code_widget_undo", elm_code_test_widget_undo },
90 { "elm_focus", elm_test_focus}, 90 { "elm_focus", elm_test_focus},
91 { "elm_focus_sub", elm_test_focus_sub}, 91 { "elm_focus_sub", elm_test_focus_sub},
92/* FIXME : This test must move efl_ui_suite when it ready *
93 * EFL_UI_TEST BEGIN */
94 { "efl_ui_grid", efl_ui_test_grid},
95/* EFL_UI_TEST END */
92 { NULL, NULL } 96 { NULL, NULL }
93}; 97};
94 98
diff --git a/src/tests/elementary/elm_suite.h b/src/tests/elementary/elm_suite.h
index ea291376f9..f5e699b9cb 100644
--- a/src/tests/elementary/elm_suite.h
+++ b/src/tests/elementary/elm_suite.h
@@ -83,6 +83,10 @@ void elm_test_spinner(TCase *tc);
83void elm_test_plug(TCase *tc); 83void elm_test_plug(TCase *tc);
84void elm_test_focus(TCase *tc); 84void elm_test_focus(TCase *tc);
85void elm_test_focus_sub(TCase *tc); 85void elm_test_focus_sub(TCase *tc);
86/* FIXME : This test must move efl_ui_suite when it ready *
87 * EFL_UI_TEST BEGIN */
88void efl_ui_test_grid(TCase *tc);
89/* EFL_UI_TEST END */
86 90
87void elm_code_file_test_load(TCase *tc); 91void elm_code_file_test_load(TCase *tc);
88void elm_code_file_test_memory(TCase *tc); 92void elm_code_file_test_memory(TCase *tc);
diff --git a/src/tests/elementary/meson.build b/src/tests/elementary/meson.build
index b6073af73d..f63b7ace06 100644
--- a/src/tests/elementary/meson.build
+++ b/src/tests/elementary/meson.build
@@ -99,7 +99,8 @@ elementary_suite_src = [
99 'elm_test_focus_common.c', 99 'elm_test_focus_common.c',
100 'elm_test_focus_common.h', 100 'elm_test_focus_common.h',
101 'elm_test_focus.c', 101 'elm_test_focus.c',
102 'elm_test_focus_sub.c' 102 'elm_test_focus_sub.c',
103 'efl_ui_test_grid.c'
103] 104]
104 105
105elementary_suite = executable('elementary_suite', 106elementary_suite = executable('elementary_suite',