summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcel Hollerbach <mail@marcel-hollerbach.de>2019-07-24 14:43:45 +0200
committerCedric BAIL <cedric.bail@free.fr>2019-07-24 12:05:06 -0700
commita6543fb68f411f98eb841ed922124d411e7e2a48 (patch)
tree61a2e5ffb75c082c749a29d4a7090935f3192736
parent7525ab16f110c84c31950d9d9fbd0f705424c8db (diff)
efl_ui_grid: make it work with item_container
this also reformats the example, removes comments that are misleading, removes UI elements that have no purpose. Reviewed-by: Cedric BAIL <cedric.bail@free.fr> Differential Revision: https://phab.enlightenment.org/D9384
-rw-r--r--src/examples/elementary/efl_ui_grid_example_1.c122
-rw-r--r--src/examples/elementary/meson.build1
-rw-r--r--src/lib/elementary/efl_ui_grid.c1106
-rw-r--r--src/lib/elementary/efl_ui_grid.eo94
-rw-r--r--src/lib/elementary/efl_ui_grid_private.h83
-rw-r--r--src/lib/elementary/meson.build1
-rw-r--r--src/tests/elementary/efl_ui_test_grid.c6
7 files changed, 57 insertions, 1356 deletions
diff --git a/src/examples/elementary/efl_ui_grid_example_1.c b/src/examples/elementary/efl_ui_grid_example_1.c
index 47e668a9aa..fb854fc0e2 100644
--- a/src/examples/elementary/efl_ui_grid_example_1.c
+++ b/src/examples/elementary/efl_ui_grid_example_1.c
@@ -13,92 +13,66 @@
13 13
14#define IMAX 500; 14#define IMAX 500;
15 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_Layout_Orientation dir)
23{
24 Eo* obj = efl_add(klass, parent);
25 if (dir != EFL_UI_LAYOUT_ORIENTATION_DEFAULT) efl_ui_layout_orientation_set(obj, dir);
26 efl_gfx_hint_weight_set(obj, EFL_GFX_HINT_EXPAND, EFL_GFX_HINT_EXPAND);
27 efl_gfx_hint_fill_set(obj, EINA_TRUE, EINA_TRUE);
28 return obj;
29}
30
31EAPI_MAIN int 16EAPI_MAIN int
32elm_main(int argc, char **argv) 17elm_main(int argc EINA_UNUSED, char **argv EINA_UNUSED)
33{ 18{
34 int itemmax = IMAX; 19 int i = 0, itemmax = IMAX;
35 int i = 0; 20 Efl_Ui_Win *win;
36 if (argv[1]) itemmax = atoi(argv[1]); 21 Efl_Ui_Box *box;
37 Eo *win, *box, *bbx, *upbtn, *allbtn, *clrbtn; 22 Efl_Ui_Grid *grid;
38 Eo *grid, *gitem; 23 Efl_Ui_Item *gitem;
39 Grid_Event_Data *gd = calloc(sizeof(Grid_Event_Data *), 1); 24
40 25 win = efl_add(EFL_UI_WIN_CLASS, efl_main_loop_get(),
41 win = efl_add(EFL_UI_WIN_CLASS, efl_main_loop_get(), 26 efl_ui_win_type_set(efl_added, EFL_UI_WIN_TYPE_BASIC),
42 efl_ui_win_type_set(efl_added, EFL_UI_WIN_TYPE_BASIC), 27 efl_text_set(efl_added, "Efl.Ui.Grid"),
43 efl_text_set(efl_added, "Efl.Ui.Grid"), 28 efl_ui_win_autodel_set(efl_added, EINA_TRUE));
44 efl_ui_win_autodel_set(efl_added, EINA_TRUE)); 29
45 30 box = efl_add(EFL_UI_BOX_CLASS, win);
46 box = EoGenerate(EFL_UI_BOX_CLASS, win, EFL_UI_LAYOUT_ORIENTATION_VERTICAL); 31 efl_gfx_hint_weight_set(box, EFL_GFX_HINT_EXPAND, EFL_GFX_HINT_EXPAND);
47 elm_win_resize_object_add(win, box); 32 elm_win_resize_object_add(win, box);
48 33
49 Eo *btn = efl_add(EFL_UI_BUTTON_CLASS, box); 34 grid = efl_add(EFL_UI_GRID_CLASS, box);
50 efl_gfx_hint_weight_set(btn, 0.3, 0.3); 35 efl_gfx_hint_weight_set(grid, EFL_GFX_HINT_EXPAND, EFL_GFX_HINT_EXPAND);
51 efl_gfx_hint_fill_set(btn, EINA_TRUE, EINA_TRUE);
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_LAYOUT_ORIENTATION_HORIZONTAL : EFL_UI_LAYOUT_ORIENTATION_VERTICAL));
58 efl_ui_grid_item_size_set(grid, EINA_SIZE2D(100, 120)); // 4X4
59 efl_gfx_arrangement_content_padding_set(grid, 5.0, 5.0, EINA_TRUE);
60 efl_gfx_arrangement_content_align_set(grid, 0.5, 0.5);
61 efl_pack_end(box, grid); 36 efl_pack_end(box, grid);
62 37
63 // TEST#2 : Set Item Default Size 38 for (i = 0; i < itemmax; i++)
39 {
40 int r = 0, g = 0, b = 0;
41 gitem = efl_add(EFL_UI_GRID_DEFAULT_ITEM_CLASS, grid);
42 efl_gfx_hint_size_min_set(gitem, EINA_SIZE2D(100, 120));
64 43
65 Efl_Ui_Grid_Item *target = NULL; 44 Eo *rect = evas_object_rectangle_add(evas_object_evas_get(win));
45 switch (i % 5)
46 {
47 case 0:
48 r = 255;
49 break;
66 50
67 for (i = 0; i < itemmax; i++) 51 case 1:
68 { 52 g = 255;
69 int r = 0, g = 0, b = 0; 53 break;
70 // TEST#3 : Create Grid Item 54
71 gitem = efl_add(EFL_UI_GRID_DEFAULT_ITEM_CLASS, grid); 55 case 2:
72 if (i == 300) target = gitem; 56 b = 255;
73 if (i == 0) gd->item = gitem; 57 break;
74 Eo *rect = evas_object_rectangle_add(evas_object_evas_get(win)); 58
75 switch (i % 5) 59 case 3:
76 { 60 r = g = b = 255;
77 case 0: 61 break;
78 r = 255; 62
79 break; 63 case 4:
80 case 1: 64 r = g = b = 0;
81 g = 255; 65 break;
82 break; 66 }
83 case 2: 67 efl_gfx_color_set(rect, r, g, b, 255);
84 b = 255; 68 efl_content_set(gitem, rect);
85 break; 69 efl_pack_end(grid, gitem);
86 case 3: 70 }
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 71
99 efl_gfx_entity_size_set(win, EINA_SIZE2D(417, 600)); 72 efl_gfx_entity_size_set(win, EINA_SIZE2D(417, 600));
100 73
101 elm_run(); 74 elm_run();
102 return 0; 75 return 0;
103} 76}
77
104ELM_MAIN() 78ELM_MAIN()
diff --git a/src/examples/elementary/meson.build b/src/examples/elementary/meson.build
index f29a94f687..53d1213d4c 100644
--- a/src/examples/elementary/meson.build
+++ b/src/examples/elementary/meson.build
@@ -119,6 +119,7 @@ examples = [
119 'efl_ui_theme_example_02', 119 'efl_ui_theme_example_02',
120 'efl_ui_slideshow_example', 120 'efl_ui_slideshow_example',
121 'efl_ui_radio_example_01', 121 'efl_ui_radio_example_01',
122 'efl_ui_grid_example_1'
122] 123]
123 124
124foreach example : examples 125foreach example : examples
diff --git a/src/lib/elementary/efl_ui_grid.c b/src/lib/elementary/efl_ui_grid.c
index 20ef53d2f1..7322e5fdcf 100644
--- a/src/lib/elementary/efl_ui_grid.c
+++ b/src/lib/elementary/efl_ui_grid.c
@@ -8,7 +8,6 @@
8 8
9#include <Elementary.h> 9#include <Elementary.h>
10#include "elm_priv.h" 10#include "elm_priv.h"
11#include "efl_ui_grid_private.h"
12#include "efl_ui_item_private.h" 11#include "efl_ui_item_private.h"
13#include "efl_ui_grid_item_private.h" 12#include "efl_ui_grid_item_private.h"
14 13
@@ -17,1117 +16,18 @@
17 16
18#define MY_CLASS_NAME "Efl.Ui.Grid" 17#define MY_CLASS_NAME "Efl.Ui.Grid"
19 18
20static void _grid_clear_internal(Eo *obj, Efl_Ui_Grid_Data *pd); 19typedef struct {
21static void _grid_item_unpack_internal(Eo *obj, Efl_Ui_Grid_Data *pd, Efl_Ui_Grid_Item *item);
22 20
23static int 21} Efl_Ui_Grid_Data;
24clamp_index(Efl_Ui_Grid_Data *pd, int index)
25{
26 if (index < ((int)eina_list_count(pd->items)) * -1)
27 return -1;
28 else if (index > (int)eina_list_count(pd->items) - 1)
29 return 1;
30 return 0;
31}
32
33static int
34index_adjust(Efl_Ui_Grid_Data *pd, int index)
35{
36 int c = eina_list_count(pd->items);
37 if (index < c * -1)
38 return 0;
39 else if (index > c - 1)
40 return c - 1;
41 else if (index < 0)
42 return index + c;
43 return index;
44}
45
46static void
47_need_update(Efl_Ui_Grid_Data *pd)
48{
49 pd->need_update = EINA_TRUE;
50 //group_calculate call
51 efl_canvas_group_change(pd->obj);
52}
53
54static void
55_relayout(Eo *obj EINA_UNUSED, Efl_Ui_Grid_Data *pd, Eina_Position2D pan)
56{
57 Eina_List *l;
58 Efl_Ui_Grid_Item *item;
59 Efl_Ui_Grid_Item_Data *prev;
60 Eina_Position2D ipos;
61 Eina_Position2D cur = {0, 0};
62 int outer;
63 int count = 0;
64 Eina_Bool horiz = 0;
65 Eina_Size2D min, max;
66
67 if (pd->dir == EFL_UI_LAYOUT_ORIENTATION_HORIZONTAL) horiz = 1;
68
69 if (!pd->linemax)
70 {
71 pd->linemax =(horiz ?
72 ((pd->geo.h + pd->item.pad.h) / (pd->item.size.h + pd->item.pad.h)) :
73 ((pd->geo.w + pd->item.pad.w) / (pd->item.size.w + pd->item.pad.w)));
74 if (!pd->linemax) pd->linemax = 1;
75 }
76
77
78 outer = (horiz ?
79 (pd->geo.h + pd->item.pad.h) - (pd->linemax * (pd->item.size.h + pd->item.pad.h)) :
80 (pd->geo.w + pd->item.pad.w) - (pd->linemax * (pd->item.size.w + pd->item.pad.w)));
81 // outer left top
82 outer = (horiz ? (outer * pd->item.align.h) : (outer * pd->item.align.w));
83 outer = (horiz ? (outer + pd->geo.y) : (outer + pd->geo.x));
84
85 // Block?
86 EINA_LIST_FOREACH(pd->items, l, item)
87 {
88 EFL_UI_GRID_ITEM_DATA_GET(item, id);
89
90 if (pd->need_update || (id && (id->update_me || id->update_begin)))
91 {
92 // Index begin with zero value :
93 id->index = count;
94 if (id->update_me) id->update_me = EINA_FALSE;
95 if (id->update_begin)
96 {
97 id->update_begin = EINA_FALSE;
98 pd->need_update = EINA_TRUE;
99 }
100 if (horiz)
101 {
102 id->pos.row = (count % pd->linemax);
103 id->pos.col = (count / pd->linemax);
104 //Next Line
105 if (count == 0)
106 {
107 cur.x = pd->geo.x;
108 cur.y = outer;
109 }
110 else if (id->pos.row == 0)// ((cur.y + pd->item.pad.h + pd->item.size.h) > pd->geo.h)
111 {
112 cur.x = prev->geo.x + pd->item.size.w + pd->item.pad.w;
113 cur.y = outer;
114 }
115 else
116 {
117 //cur.x = cur.x;
118 cur.y = prev->geo.y + pd->item.size.h + pd->item.pad.h;
119 }
120 }
121 else
122 {
123 id->pos.row = (count / pd->linemax);
124 id->pos.col = (count % pd->linemax);
125 //Next Line
126 if (count == 0)
127 {
128 cur.x = outer;
129 cur.y = pd->geo.y;
130 }
131 else if (id->pos.col == 0)//((cur.x + pd->item.pad.w + pd->item.size.w) > pd->geo.w)
132 {
133 cur.x = outer;
134 cur.y = prev->geo.y + pd->item.size.h + pd->item.pad.h;
135 }
136 else
137 {
138 cur.x = prev->geo.x + pd->item.size.w + pd->item.pad.w;
139 //cur.y = cur.y;
140 }
141 }
142
143 min = efl_gfx_hint_size_min_get(item);
144 max = efl_gfx_hint_size_max_get(item);
145
146 if (pd->item.size.w < min.w) pd->item.size.w = min.w;
147 if (pd->item.size.h < min.h) pd->item.size.h = min.h;
148 if ((max.w > 0) && pd->item.size.w > max.w) pd->item.size.w = max.w;
149 if ((max.h > 0) && pd->item.size.h > max.h) pd->item.size.h = max.h;
150
151 id->geo.x = cur.x;
152 id->geo.y = cur.y;
153 id->geo.w = pd->item.size.w;
154 id->geo.h = pd->item.size.h;
155
156
157 }
158
159 ipos.x = id->geo.x - pan.x;
160 ipos.y = id->geo.y - pan.y;
161
162 //
163 efl_gfx_entity_position_set(item, ipos);
164 efl_gfx_entity_size_set(item, id->geo.size);
165 //efl_gfx_hint_size_restricted_min_set(item, id->geo.size);
166
167 prev = id;
168 count++;
169 }
170
171 if (horiz)
172 pd->geo.w = cur.x + pd->item.size.w + pd->item.pad.w - pd->geo.x;
173 else
174 pd->geo.h = cur.y + pd->item.size.h + pd->item.pad.h - pd->geo.y;
175
176 //efl_gfx_hint_size_restricted_min_set(pd->content, pd->geo.size);
177 efl_gfx_entity_size_set(pd->content, pd->geo.size);
178
179 pd->need_update = EINA_FALSE;
180}
181
182static void
183_reposition(Eo *obj EINA_UNUSED, Efl_Ui_Grid_Data *pd, Eina_Position2D pan)
184{
185 Efl_Ui_Grid_Item *item;
186 Eina_List *l;
187 Eina_Position2D ipos;
188
189 // Block?
190 EINA_LIST_FOREACH(pd->items, l, item)
191 {
192 EFL_UI_GRID_ITEM_DATA_GET(item, id);
193 if (!id) continue;
194
195 ipos.x = id->geo.x - pan.x;
196 ipos.y = id->geo.y - pan.y;
197 efl_gfx_entity_position_set(item, ipos);
198 efl_gfx_entity_size_set(item, id->geo.size);
199 //efl_gfx_hint_size_min_set(item, id->geo.size);
200 }
201
202}
203
204//Need to reimplements for grid
205static void
206_item_scroll_internal(Eo *obj,
207 Efl_Ui_Grid_Item *item,
208 double align,
209 Eina_Bool anim)
210{
211 EFL_UI_GRID_DATA_GET_OR_RETURN(obj, pd);
212 Eina_Rect ipos, view;
213 Eina_Position2D vpos;
214
215 if (!pd->smanager) return;
216
217 ipos = efl_gfx_entity_geometry_get(item);
218 view = efl_ui_scrollable_viewport_geometry_get(pd->smanager);
219 vpos = efl_ui_scrollable_content_pos_get(pd->smanager);
220
221 if (pd->dir == EFL_UI_LAYOUT_ORIENTATION_HORIZONTAL)
222 {
223 ipos.y = view.y;
224 //ipos.h = ipos.h;
225
226 // FIXME: align case will not correctly show in the position because of
227 // bar size calculation. there are no certain way to know the scroll calcuation finished.
228 if (EINA_DBL_EQ(align, -1.0)) //Internal Prefix
229 {
230 ipos.x = ipos.x + vpos.x - view.x;
231 //ipos.w = ipos.w;
232 }
233 else if ((align > 0.0 || EINA_DBL_EQ(align, 0.0)) &&
234 (align < 1.0 || EINA_DBL_EQ(align, 1.0)))
235 {
236 ipos.x = ipos.x + vpos.x - view.x - (int)((view.w - ipos.w) * align);
237 ipos.w = view.w;
238 }
239 else ERR("align (%.2lf) is not proper value. it must be the value between [0.0 , 1.0]!", align);
240
241 }
242 else //VERTICAL
243 {
244 ipos.x = view.x;
245 //ipos.w = ipos.w;
246
247 // FIXME: align case will not correctly show in the position because of
248 // bar size calculation. there are no certain way to know the scroll calcuation finished.
249 if (EINA_DBL_EQ(align, -1.0)) //Internal Prefix
250 {
251 ipos.y = ipos.y + vpos.y - view.y;
252 //ipos.h = ipos.h;
253 }
254 else if ((align > 0.0 || EINA_DBL_EQ(align, 0.0)) &&
255 (align < 1.0 || EINA_DBL_EQ(align, 1.0)))
256 {
257 ipos.y = ipos.y + vpos.y - view.y - (int)((view.h - ipos.h) * align);
258 ipos.h = view.h;
259 }
260 else ERR("align (%.2lf) is not proper value. it must be the value between [0.0 , 1.0]!", align);
261 }
262
263 efl_ui_scrollable_scroll(pd->smanager, ipos, anim);
264}
265
266static void
267_efl_ui_grid_bar_size_changed_cb(void *data, const Efl_Event *event EINA_UNUSED)
268{
269 Eo *obj = data;
270 EFL_UI_GRID_DATA_GET_OR_RETURN(obj, pd);
271 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
272
273 double width = 0.0, height = 0.0;
274
275 edje_object_calc_force(wd->resize_obj);
276 efl_ui_scrollbar_bar_size_get(pd->smanager, &width, &height);
277 edje_object_part_drag_size_set(wd->resize_obj, "efl.dragable.hbar", width, 1.0);
278 edje_object_part_drag_size_set(wd->resize_obj, "efl.dragable.vbar", 1.0, height);
279}
280
281static void
282_efl_ui_grid_bar_pos_changed_cb(void *data, const Efl_Event *event EINA_UNUSED)
283{
284 Eo *obj = data;
285 EFL_UI_GRID_DATA_GET_OR_RETURN(obj, pd);
286 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
287
288 double posx = 0.0, posy = 0.0;
289
290 efl_ui_scrollbar_bar_position_get(pd->smanager, &posx, &posy);
291 edje_object_part_drag_value_set(wd->resize_obj, "efl.dragable.hbar", posx, 0.0);
292 edje_object_part_drag_value_set(wd->resize_obj, "efl.dragable.vbar", 0.0, posy);
293}
294
295static void
296_efl_ui_grid_bar_show_cb(void *data, const Efl_Event *event)
297{
298 Eo *obj = data;
299 EFL_UI_GRID_DATA_GET_OR_RETURN(obj, pd);
300 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
301 Efl_Ui_Scrollbar_Direction type = *(Efl_Ui_Scrollbar_Direction *)(event->info);
302
303 if (type == EFL_UI_SCROLLBAR_DIRECTION_HORIZONTAL)
304 edje_object_signal_emit(wd->resize_obj, "efl,action,show,hbar", "efl");
305 else if (type == EFL_UI_SCROLLBAR_DIRECTION_VERTICAL)
306 edje_object_signal_emit(wd->resize_obj, "efl,action,show,vbar", "efl");
307}
308
309static void
310_efl_ui_grid_bar_hide_cb(void *data, const Efl_Event *event)
311{
312 Eo *obj = data;
313 EFL_UI_GRID_DATA_GET_OR_RETURN(obj, pd);
314 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
315 Efl_Ui_Scrollbar_Direction type = *(Efl_Ui_Scrollbar_Direction *)(event->info);
316
317 if (type == EFL_UI_SCROLLBAR_DIRECTION_HORIZONTAL)
318 edje_object_signal_emit(wd->resize_obj, "efl,action,hide,hbar", "efl");
319 else if (type == EFL_UI_SCROLLBAR_DIRECTION_VERTICAL)
320 edje_object_signal_emit(wd->resize_obj, "efl,action,hide,vbar", "efl");
321}
322
323static void
324_efl_ui_grid_content_moved_cb(void *data, const Efl_Event *ev EINA_UNUSED)
325{
326 Eo *obj = data;
327 EFL_UI_GRID_DATA_GET_OR_RETURN(obj, pd);
328 if (!pd->smanager) return;
329
330 efl_canvas_group_change(pd->obj);
331}
332
333static void
334_efl_ui_grid_pan_resized_cb(void *data, const Efl_Event *ev EINA_UNUSED)
335{
336 Eo *obj = data;
337 EFL_UI_GRID_DATA_GET_OR_RETURN(obj, pd);
338 if (!pd->smanager) return;
339
340 //reset linemax for recalculate layout.
341 pd->linemax = 0;
342
343 _need_update(pd);
344 elm_layout_sizing_eval(obj);
345
346 pd->pan_resized = EINA_TRUE;
347}
348
349static void
350_efl_ui_grid_resized_cb(void *data, const Efl_Event *ev EINA_UNUSED)
351{
352 elm_layout_sizing_eval(data);
353}
354
355static void
356_efl_ui_grid_size_hint_changed_cb(void *data, const Efl_Event *ev EINA_UNUSED)
357{
358 elm_layout_sizing_eval(data);
359}
360 22
361EOLIAN static Eo * 23EOLIAN static Eo *
362_efl_ui_grid_efl_object_constructor(Eo *obj, Efl_Ui_Grid_Data *pd EINA_UNUSED) 24_efl_ui_grid_efl_object_constructor(Eo *obj, Efl_Ui_Grid_Data *pd EINA_UNUSED)
363{ 25{
364 obj = efl_constructor(efl_super(obj, MY_CLASS)); 26 obj = efl_constructor(efl_super(obj, MY_CLASS));
365 27
366 return obj; 28 efl_ui_item_container_position_manager_set(obj, efl_new(EFL_UI_GRID_POSITION_MANAGER_CLASS));
367}
368
369EOLIAN static Eo *
370_efl_ui_grid_efl_object_finalize(Eo *obj,
371 Efl_Ui_Grid_Data *pd)
372{
373 pd->obj = obj = efl_finalize(efl_super(obj, MY_CLASS));
374 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, NULL);
375
376 efl_ui_layout_theme_set(obj, "grid", "base", efl_ui_widget_style_get(obj));
377
378 pd->smanager = efl_add(EFL_UI_SCROLL_MANAGER_CLASS, obj);
379 efl_composite_attach(obj, pd->smanager);
380 efl_ui_mirrored_set(pd->smanager, efl_ui_mirrored_get(obj));
381
382 pd->pan = efl_add(EFL_UI_PAN_CLASS, obj);
383
384 efl_ui_scroll_manager_pan_set(pd->smanager, pd->pan);
385 edje_object_part_swallow(wd->resize_obj, "efl.content", pd->pan);
386
387 pd->select_mode = EFL_UI_SELECT_MODE_SINGLE;
388
389 if ((pd->item.size.w == 0) && (pd->item.size.h == 0))
390 {
391 pd->item.size.w = 1;
392 pd->item.size.h = 1;
393 }
394
395 efl_ui_scroll_connector_bind(obj, pd->smanager);
396
397 //FIXME: Workaround code! fake Content for pan resize.
398 // to remove this code, we need to customize pan class.
399 pd->content = efl_add(EFL_CANVAS_RECTANGLE_CLASS, evas_object_evas_get(obj));
400 efl_gfx_color_set(pd->content, 0, 0, 0, 0);
401 efl_content_set(pd->pan, pd->content);
402
403 efl_event_callback_add(obj, EFL_UI_SCROLLBAR_EVENT_BAR_SIZE_CHANGED,
404 _efl_ui_grid_bar_size_changed_cb, obj);
405 efl_event_callback_add(obj, EFL_UI_SCROLLBAR_EVENT_BAR_POS_CHANGED,
406 _efl_ui_grid_bar_pos_changed_cb, obj);
407 efl_event_callback_add(obj, EFL_UI_SCROLLBAR_EVENT_BAR_SHOW,
408 _efl_ui_grid_bar_show_cb, obj);
409 efl_event_callback_add(obj, EFL_UI_SCROLLBAR_EVENT_BAR_HIDE,
410 _efl_ui_grid_bar_hide_cb, obj);
411 efl_event_callback_add(obj, EFL_GFX_ENTITY_EVENT_SIZE_CHANGED,
412 _efl_ui_grid_resized_cb, obj);
413 efl_event_callback_add(obj, EFL_GFX_ENTITY_EVENT_HINTS_CHANGED,
414 _efl_ui_grid_size_hint_changed_cb, obj);
415 efl_event_callback_add(pd->pan, EFL_GFX_ENTITY_EVENT_SIZE_CHANGED,
416 _efl_ui_grid_pan_resized_cb, obj);
417 efl_event_callback_add(pd->content, EFL_GFX_ENTITY_EVENT_POSITION_CHANGED,
418 _efl_ui_grid_content_moved_cb, obj);
419
420 elm_layout_sizing_eval(obj);
421 29
422 return obj; 30 return obj;
423} 31}
424 32
425
426EOLIAN static void
427_efl_ui_grid_efl_object_invalidate(Eo *obj, Efl_Ui_Grid_Data *pd)
428{
429 efl_ui_scroll_connector_unbind(obj);
430
431 efl_event_callback_del(obj, EFL_UI_SCROLLBAR_EVENT_BAR_SIZE_CHANGED,
432 _efl_ui_grid_bar_size_changed_cb, obj);
433 efl_event_callback_del(obj, EFL_UI_SCROLLBAR_EVENT_BAR_POS_CHANGED,
434 _efl_ui_grid_bar_pos_changed_cb, obj);
435 efl_event_callback_del(obj, EFL_UI_SCROLLBAR_EVENT_BAR_SHOW,
436 _efl_ui_grid_bar_show_cb, obj);
437 efl_event_callback_del(obj, EFL_UI_SCROLLBAR_EVENT_BAR_HIDE,
438 _efl_ui_grid_bar_hide_cb, obj);
439 efl_event_callback_del(obj, EFL_GFX_ENTITY_EVENT_SIZE_CHANGED,
440 _efl_ui_grid_resized_cb, obj);
441 efl_event_callback_del(obj, EFL_GFX_ENTITY_EVENT_HINTS_CHANGED,
442 _efl_ui_grid_size_hint_changed_cb, obj);
443 efl_event_callback_del(pd->pan, EFL_GFX_ENTITY_EVENT_SIZE_CHANGED,
444 _efl_ui_grid_pan_resized_cb, obj);
445 efl_event_callback_del(pd->content, EFL_GFX_ENTITY_EVENT_POSITION_CHANGED,
446 _efl_ui_grid_content_moved_cb, obj);
447 _grid_clear_internal(obj, pd);
448
449 if (pd->smanager) efl_del(pd->smanager);
450 pd->smanager = NULL;
451 if (pd->content) efl_del(pd->content);
452 pd->content = NULL;
453 if (pd->pan) efl_del(pd->pan);
454 pd->pan = NULL;
455
456 efl_invalidate(efl_super(obj, MY_CLASS));
457}
458
459EOLIAN static void
460_efl_ui_grid_efl_object_destructor(Eo *obj, Efl_Ui_Grid_Data *pd EINA_UNUSED)
461{
462 efl_destructor(efl_super(obj, MY_CLASS));
463}
464
465EOLIAN static void
466_efl_ui_grid_efl_canvas_group_group_calculate(Eo *obj, Efl_Ui_Grid_Data *pd)
467{
468
469 Eina_Position2D pos = efl_ui_scrollable_content_pos_get(pd->smanager);
470 Eina_Rect geo = efl_ui_scrollable_viewport_geometry_get(pd->smanager);
471
472 //ERR("pos[%d,%d], geo[%d,%d,%d,%d]", pos.x, pos.y, geo.x, geo.y, geo.w, geo.h);
473
474 if (geo.w <= 1 || geo.h <= 1) return;
475 // Need to be implemented
476 if (pd->need_update)
477 {
478 _relayout(obj, pd, pos);
479 }
480 else
481 {
482 if (pd->pre_pos.x != pos.x || pd->pre_pos.y != pos.y)
483 {
484 _reposition(obj, pd, pos);
485 }
486 }
487
488 pd->pre_pos = pos;
489
490 if (pd->pan_resized)
491 {
492 pd->pan_resized = EINA_FALSE;
493 // FIXME: Below code is workaround size check
494 if ((geo.h > 1) && (pd->scroll.item))
495 {
496 _item_scroll_internal(obj, pd->scroll.item, pd->scroll.align, pd->scroll.anim);
497
498 pd->scroll.item = NULL;
499 pd->scroll.align = 0.0;
500 pd->scroll.anim = EINA_FALSE;
501 return;
502 }
503 }
504
505 efl_canvas_group_calculate(efl_super(obj, MY_CLASS));
506}
507
508EOLIAN static void
509_efl_ui_grid_elm_layout_sizing_eval(Eo *obj, Efl_Ui_Grid_Data *pd)
510{
511 Eina_Size2D min = {0, 0}, max = {0, 0}, size = {-1, -1};
512 Eina_Rect view = {};
513 Evas_Coord vmw = 0, vmh = 0;
514 double xw = 0.0, yw = 0.0;
515
516 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
517
518
519 min = efl_gfx_hint_size_combined_min_get(obj);
520 max = efl_gfx_hint_size_max_get(obj);
521 efl_gfx_hint_weight_get(obj, &xw, &yw);
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 edje_object_size_min_calc(wd->resize_obj, &vmw, &vmh);
547
548 if (pd->match_content_w) size.w = vmw + min.w;
549 if (pd->match_content_h) size.h = vmh + min.h;
550
551 max = efl_gfx_hint_size_max_get(obj);
552 if ((max.w > 0) && (size.w > max.w)) size.w = max.w;
553 if ((max.h > 0) && (size.h > max.h)) size.h = max.h;
554 pd->geo = view;
555 efl_gfx_hint_size_min_set(obj, size);
556
557 _need_update(pd);
558 return;
559}
560
561EOLIAN static int
562_efl_ui_grid_efl_container_content_count(Eo *obj EINA_UNUSED, Efl_Ui_Grid_Data *pd)
563{
564 return eina_list_count(pd->items);
565}
566
567static Eina_Bool
568_grid_item_iterator_next(Item_Iterator *it, void **data)
569{
570 Efl_Ui_Grid_Item *item;
571
572 if (!eina_iterator_next(it->real_iterator, (void **)&item))
573 return EINA_FALSE;
574
575 if (data) *data = item;
576 return EINA_TRUE;
577}
578
579static Eo *
580_grid_item_iterator_get_container(Item_Iterator *it)
581{
582 return it->object;
583}
584
585static void
586_grid_item_iterator_free(Item_Iterator *it)
587{
588 eina_iterator_free(it->real_iterator);
589 eina_list_free(it->list);
590 free(it);
591}
592
593static Eina_Iterator *
594_grid_item_iterator_new(Eo *obj, Eina_List *list)
595{
596 // NEED-TO-IMPLEMENTS
597 Item_Iterator *item;
598
599 item = calloc(1, sizeof(*item));
600 if (!item) return NULL;
601
602 EINA_MAGIC_SET(&item->iterator, EINA_MAGIC_ITERATOR);
603
604 item->list = eina_list_clone(list);
605 item->real_iterator = eina_list_iterator_new(item->list);
606 item->iterator.version = EINA_ITERATOR_VERSION;
607 item->iterator.next = FUNC_ITERATOR_NEXT(_grid_item_iterator_next);
608 item->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(_grid_item_iterator_get_container);
609 item->iterator.free = FUNC_ITERATOR_FREE(_grid_item_iterator_free);
610 item->object = obj;
611
612 return &item->iterator;
613}
614
615EOLIAN static Eina_Iterator *
616_efl_ui_grid_efl_container_content_iterate(Eo *obj, Efl_Ui_Grid_Data *pd)
617{
618 return _grid_item_iterator_new(obj, pd->items);
619}
620
621EOLIAN static void
622_efl_ui_grid_efl_ui_layout_orientable_orientation_set(Eo *obj EINA_UNUSED, Efl_Ui_Grid_Data *pd, Efl_Ui_Layout_Orientation dir)
623{
624 //FIXME: Currently only support horizontal and vertical mode.
625 switch (dir)
626 {
627 case EFL_UI_LAYOUT_ORIENTATION_HORIZONTAL:
628 pd->dir = EFL_UI_LAYOUT_ORIENTATION_HORIZONTAL;
629 break;
630 case EFL_UI_LAYOUT_ORIENTATION_VERTICAL:
631 case EFL_UI_LAYOUT_ORIENTATION_DEFAULT:
632 default:
633 pd->dir = EFL_UI_LAYOUT_ORIENTATION_VERTICAL;
634 break;
635 }
636
637 pd->linemax = 0;
638 efl_pack_layout_request(obj);
639}
640
641EOLIAN static Efl_Ui_Layout_Orientation
642_efl_ui_grid_efl_ui_layout_orientable_orientation_get(const Eo *obj EINA_UNUSED, Efl_Ui_Grid_Data *pd)
643{
644 return pd->dir;
645}
646
647
648EOLIAN static Eina_Error
649_efl_ui_grid_efl_ui_widget_theme_apply(Eo *obj, Efl_Ui_Grid_Data *pd)
650{
651 Eina_Error int_ret = EFL_UI_THEME_APPLY_ERROR_GENERIC;
652 int_ret = efl_ui_widget_theme_apply(efl_super(obj, MY_CLASS));
653 if (int_ret == EFL_UI_THEME_APPLY_ERROR_GENERIC) return int_ret;
654
655 efl_ui_mirrored_set(pd->smanager, efl_ui_mirrored_get(obj));
656
657 elm_layout_sizing_eval(obj);
658
659 return int_ret;
660}
661
662static void
663_grid_item_pressed(void *data, const Efl_Event *event)
664{
665 Eo *obj = data;
666 Efl_Ui_Grid_Item *item = event->object;
667 efl_event_callback_call(obj, EFL_UI_EVENT_PRESSED, item);
668}
669
670static void
671_grid_item_unpressed(void *data, const Efl_Event *event)
672{
673 Eo *obj = data;
674 Efl_Ui_Grid_Item *item = event->object;
675 efl_event_callback_call(obj, EFL_UI_EVENT_UNPRESSED, item);
676}
677
678static void
679_grid_item_longpressed(void *data, const Efl_Event *event)
680{
681 Eo *obj = data;
682 Efl_Ui_Grid_Item *item = event->object;
683 efl_event_callback_call(obj, EFL_UI_EVENT_LONGPRESSED, item);
684}
685
686static void
687_grid_item_selected(void *data, const Efl_Event *event)
688{
689 Eo *obj = data;
690 Efl_Ui_Grid_Item *item = event->object;
691 Efl_Ui_Grid_Item *selected;
692 EFL_UI_GRID_DATA_GET_OR_RETURN(obj, pd);
693
694 /* Single Select */
695 if (pd->select_mode != EFL_UI_SELECT_MODE_MULTI)
696 {
697 EINA_LIST_FREE(pd->selected, selected)
698 {
699 if (selected != item)
700 efl_ui_item_selected_set(selected, EINA_FALSE);
701 }
702 }
703 pd->selected = eina_list_append(pd->selected, item);
704 pd->last_selected = item;
705
706 efl_event_callback_call(obj, EFL_UI_EVENT_ITEM_SELECTED, item);
707}
708
709static void
710_grid_item_unselected(void *data, const Efl_Event *event)
711{
712 Eo *obj = data;
713 Efl_Ui_Grid_Item *item = event->object;
714 EFL_UI_GRID_DATA_GET_OR_RETURN(obj, pd);
715
716 pd->selected = eina_list_remove(pd->selected, item);
717 if (pd->last_selected == item) pd->last_selected = NULL;
718
719 efl_event_callback_call(obj, EFL_UI_EVENT_ITEM_UNSELECTED, item);
720}
721
722static void
723_grid_item_deleted(void *data, const Efl_Event *event)
724{
725 Eo *obj = data;
726 Efl_Ui_Grid_Item *it = event->object;
727 EFL_UI_GRID_DATA_GET_OR_RETURN(obj, pd);
728 _grid_item_unpack_internal(obj, pd, it);
729}
730
731static Eina_Bool
732_grid_item_process(Eo *obj, Efl_Ui_Grid_Data *pd, EINA_UNUSED Efl_Ui_Grid_Item *it)
733{
734 if (!efl_isa(it, EFL_UI_GRID_ITEM_CLASS))
735 {
736 ERR("Item must be of type EFL_UI_GRID_ITEM_CLASS");
737 return EINA_FALSE;
738 }
739
740 if (eina_list_data_find(pd->items, it))
741 {
742 ERR("Item already added to this container!");
743 return EINA_FALSE;
744 }
745
746 if (!efl_ui_widget_sub_object_add(obj, it))
747 return EINA_FALSE;
748
749 efl_ui_item_container_set(it, obj);
750 efl_canvas_group_member_add(pd->pan, it);
751 efl_ui_mirrored_set(it, efl_ui_mirrored_get(obj));
752
753 efl_event_callback_add(it, EFL_UI_EVENT_PRESSED, _grid_item_pressed, obj);
754 efl_event_callback_add(it, EFL_UI_EVENT_UNPRESSED, _grid_item_unpressed, obj);
755 efl_event_callback_add(it, EFL_UI_EVENT_LONGPRESSED, _grid_item_longpressed, obj);
756 efl_event_callback_add(it, EFL_UI_EVENT_ITEM_SELECTED, _grid_item_selected, obj);
757 efl_event_callback_add(it, EFL_UI_EVENT_ITEM_UNSELECTED, _grid_item_unselected, obj);
758 efl_event_callback_add(it, EFL_EVENT_DEL, _grid_item_deleted, obj);
759
760 return EINA_TRUE;
761}
762
763static void
764_grid_item_unpack_internal(Eo *obj, Efl_Ui_Grid_Data *pd, Efl_Ui_Grid_Item *it)
765{
766 EFL_UI_GRID_ITEM_CHECK_OR_RETURN(it);
767 efl_ui_item_container_set(it, NULL);
768
769 pd->items = eina_list_remove(pd->items, it);
770 if (efl_ui_item_selected_get(it))
771 {
772 pd->selected = eina_list_remove(pd->selected, it);
773 }
774
775 efl_event_callback_del(it, EFL_UI_EVENT_PRESSED, _grid_item_pressed, obj);
776 efl_event_callback_del(it, EFL_UI_EVENT_UNPRESSED, _grid_item_unpressed, obj);
777 efl_event_callback_del(it, EFL_UI_EVENT_LONGPRESSED, _grid_item_longpressed, obj);
778 efl_event_callback_del(it, EFL_UI_EVENT_ITEM_SELECTED, _grid_item_selected, obj);
779 efl_event_callback_del(it, EFL_UI_EVENT_ITEM_UNSELECTED, _grid_item_unselected, obj);
780 efl_event_callback_del(it, EFL_EVENT_DEL, _grid_item_deleted, obj);
781
782 efl_canvas_group_member_remove(pd->pan, it);
783 _elm_widget_sub_object_redirect_to_top(obj, it);
784}
785
786
787static void
788_grid_clear_internal(Eo *obj EINA_UNUSED, Efl_Ui_Grid_Data *pd)
789{
790 Efl_Ui_Grid_Item *it = NULL;
791 Eina_List *l, *ll;
792 EINA_LIST_FOREACH_SAFE(pd->items, l, ll, it)
793 {
794 efl_del(it);
795 }
796 eina_list_free(pd->selected);
797 pd->items = NULL;
798 pd->selected = NULL;
799}
800
801/* Pack APIs */
802EOLIAN static Eina_Bool
803_efl_ui_grid_efl_pack_pack_clear(Eo *obj, Efl_Ui_Grid_Data *pd)
804{
805 _grid_clear_internal(obj, pd);
806
807 elm_layout_sizing_eval(obj);
808 return EINA_TRUE;
809}
810
811EOLIAN static Eina_Bool
812_efl_ui_grid_efl_pack_unpack_all(Eo *obj, Efl_Ui_Grid_Data *pd)
813{
814
815 Efl_Ui_Grid_Item *it = NULL;
816 Eina_List *l, *ll;
817 EINA_LIST_FOREACH_SAFE(pd->items, l, ll, it)
818 {
819 _grid_item_unpack_internal(obj, pd, it);
820 }
821 eina_list_free(pd->selected);
822 pd->items = NULL;
823 pd->selected = NULL;
824
825 elm_layout_sizing_eval(obj);
826 return EINA_TRUE;
827}
828
829EOLIAN static Eina_Bool
830_efl_ui_grid_efl_pack_unpack(Eo *obj, Efl_Ui_Grid_Data *pd, Efl_Gfx_Entity *subobj)
831{
832 Efl_Ui_Grid_Item *item = (Efl_Ui_Grid_Item *)subobj;
833
834 if (!eina_list_data_find(pd->items, item))
835 {
836 ERR("Element is not part of this container");
837 return EINA_FALSE;
838 }
839
840 _grid_item_unpack_internal(obj, pd, item);
841
842 elm_layout_sizing_eval(obj);
843 return EINA_TRUE;
844}
845
846EOLIAN static Eina_Bool
847_efl_ui_grid_efl_pack_pack(Eo *obj, Efl_Ui_Grid_Data *pd EINA_UNUSED, Efl_Gfx_Entity *subobj)
848{
849 return efl_pack_end(obj, subobj);
850}
851
852EOLIAN static Eina_Bool
853_efl_ui_grid_efl_pack_linear_pack_end(Eo *obj, Efl_Ui_Grid_Data *pd, Efl_Gfx_Entity *subobj)
854{
855 if (!_grid_item_process(obj, pd, subobj)) return EINA_FALSE;
856 EFL_UI_GRID_ITEM_DATA_GET_OR_RETURN(subobj, pid, EINA_FALSE);
857 pd->items = eina_list_append(pd->items, subobj);
858
859 pid->update_me = EINA_TRUE;
860
861 efl_canvas_group_change(obj);
862 return EINA_TRUE;
863}
864
865EOLIAN static Eina_Bool
866_efl_ui_grid_efl_pack_linear_pack_begin(Eo *obj, Efl_Ui_Grid_Data *pd, Efl_Gfx_Entity *subobj)
867{
868 if (!_grid_item_process(obj, pd, subobj)) return EINA_FALSE;
869 EFL_UI_GRID_ITEM_DATA_GET_OR_RETURN(subobj, pid, EINA_FALSE);
870 pd->items = eina_list_prepend(pd->items, subobj);
871 // Defered item's placing in group calculation
872 pid->update_me = EINA_TRUE;
873 _need_update(pd);
874 return EINA_TRUE;
875}
876
877EOLIAN static Eina_Bool
878_efl_ui_grid_efl_pack_linear_pack_before(Eo *obj,
879 Efl_Ui_Grid_Data *pd,
880 Efl_Gfx_Entity *subobj,
881 const Efl_Gfx_Entity *existing)
882{
883 if (!_grid_item_process(obj, pd, subobj)) return EINA_FALSE;
884 EFL_UI_GRID_ITEM_CHECK_OR_RETURN(existing, EINA_FALSE);
885 EFL_UI_GRID_ITEM_DATA_GET_OR_RETURN(subobj, pid, EINA_FALSE);
886
887 pd->items = eina_list_prepend_relative(pd->items, subobj, existing);
888 // Defered item's placing in group calculation
889 pid->update_begin = EINA_TRUE;
890 _need_update(pd);
891 return EINA_TRUE;
892}
893
894EOLIAN static Eina_Bool
895_efl_ui_grid_efl_pack_linear_pack_after(Eo *obj,
896 Efl_Ui_Grid_Data *pd,
897 Efl_Gfx_Entity *subobj,
898 const Efl_Gfx_Entity *existing)
899{
900 if (!_grid_item_process(obj, pd, subobj)) return EINA_FALSE;
901 EFL_UI_GRID_ITEM_CHECK_OR_RETURN(existing, EINA_FALSE);
902 EFL_UI_GRID_ITEM_DATA_GET_OR_RETURN(subobj, pid, EINA_FALSE);
903
904 pd->items = eina_list_append_relative(pd->items, subobj, existing);
905 // Defered item's placing in group calculation
906 pid->update_begin = EINA_TRUE;
907 _need_update(pd);
908 return EINA_TRUE;
909}
910
911EOLIAN static Eina_Bool
912_efl_ui_grid_efl_pack_linear_pack_at(Eo *obj,
913 Efl_Ui_Grid_Data *pd,
914 Efl_Gfx_Entity *subobj,
915 int index)
916{
917 int clamp = clamp_index(pd, index);
918 index = index_adjust(pd, index);
919 if (!_grid_item_process(obj, pd, subobj)) return EINA_FALSE;
920 Efl_Ui_Grid_Item *existing = eina_list_nth(pd->items, index);
921 EFL_UI_GRID_ITEM_DATA_GET_OR_RETURN(subobj, pid, EINA_FALSE);
922
923 if (clamp == 0)
924 pd->items = eina_list_prepend_relative(pd->items, subobj, existing);
925 else if (clamp == 1)
926 pd->items = eina_list_append(pd->items, subobj);
927 else
928 pd->items = eina_list_prepend(pd->items, subobj);
929
930 // Defered item's placing in group calculation
931 pid->update_begin = EINA_TRUE;
932 _need_update(pd);
933 return EINA_TRUE;
934}
935
936EOLIAN static Efl_Gfx_Entity *
937_efl_ui_grid_efl_pack_linear_pack_content_get(Eo *obj EINA_UNUSED, Efl_Ui_Grid_Data *pd, int index)
938{
939 index = index_adjust(pd, index);
940 return eina_list_nth(pd->items, index);
941}
942
943EOLIAN static Efl_Gfx_Entity *
944_efl_ui_grid_efl_pack_linear_pack_unpack_at(Eo *obj EINA_UNUSED, Efl_Ui_Grid_Data *pd, int index)
945{
946 index = index_adjust(pd, index);
947 Efl_Gfx_Entity *target = eina_list_nth(pd->items, index);
948 _grid_item_unpack_internal(obj, pd, target);
949 _need_update(pd);
950 return target;
951}
952
953EOLIAN static int
954_efl_ui_grid_efl_pack_linear_pack_index_get(Eo *obj EINA_UNUSED,
955 Efl_Ui_Grid_Data *pd,
956 const Efl_Gfx_Entity *subobj)
957{
958 return eina_list_data_idx(pd->items, (void *)subobj);
959}
960
961EOLIAN static void
962_efl_ui_grid_efl_pack_layout_layout_update(Eo *obj, Efl_Ui_Grid_Data *pd)
963{
964 _need_update(pd);
965 elm_layout_sizing_eval(obj);
966
967 efl_event_callback_legacy_call(obj, EFL_PACK_EVENT_LAYOUT_UPDATED, NULL);
968}
969
970EOLIAN static void
971_efl_ui_grid_efl_pack_layout_layout_request(Eo *obj, Efl_Ui_Grid_Data *pd)
972{
973 _need_update(pd);
974 elm_layout_sizing_eval(obj);
975}
976
977EOLIAN static void
978_efl_ui_grid_efl_gfx_arrangement_content_padding_set(Eo *obj EINA_UNUSED,
979 Efl_Ui_Grid_Data *pd,
980 double h,
981 double v,
982 Eina_Bool scalable)
983{
984 pd->item.pad.w = (int )h;
985 pd->item.pad.h = (int) v;
986
987 pd->pad_scalable = !!scalable;
988
989 //reset linemax for recalculate layout
990 pd->linemax = 0;
991 _need_update(pd);
992}
993
994EOLIAN static void
995_efl_ui_grid_efl_gfx_arrangement_content_padding_get(const Eo *obj EINA_UNUSED,
996 Efl_Ui_Grid_Data *pd,
997 double *h,
998 double *v,
999 Eina_Bool *scalable)
1000{
1001 //??
1002 *h = (double) pd->item.pad.w;
1003 *v = (double) pd->item.pad.h;
1004 *scalable = !!pd->pad_scalable;
1005}
1006
1007EOLIAN static void
1008_efl_ui_grid_efl_gfx_arrangement_content_align_set(Eo *obj EINA_UNUSED, Efl_Ui_Grid_Data *pd, double h, double v)
1009{
1010 pd->item.align.w = h;
1011 pd->item.align.h = v;
1012 _need_update(pd);
1013}
1014
1015EOLIAN static void
1016_efl_ui_grid_efl_gfx_arrangement_content_align_get(const Eo *obj EINA_UNUSED, Efl_Ui_Grid_Data *pd, double *h, double *v)
1017{
1018 *h = pd->item.align.w;
1019 *v = pd->item.align.h;
1020}
1021
1022EOLIAN static void
1023_efl_ui_grid_efl_ui_scrollable_interactive_match_content_set(Eo *obj EINA_UNUSED,
1024 Efl_Ui_Grid_Data *pd,
1025 Eina_Bool match_content_w,
1026 Eina_Bool match_content_h)
1027{
1028 pd->match_content_w = !!match_content_w;
1029 pd->match_content_h = !!match_content_h;
1030
1031 efl_ui_scrollable_match_content_set(pd->smanager, match_content_w, match_content_h);
1032
1033 elm_layout_sizing_eval(obj);
1034}
1035
1036EOLIAN static void
1037_efl_ui_grid_efl_ui_multi_selectable_select_mode_set(Eo *obj EINA_UNUSED,
1038 Efl_Ui_Grid_Data *pd,
1039 Efl_Ui_Select_Mode mode)
1040{
1041 Efl_Ui_Grid_Item *selected;
1042
1043 if ((pd->select_mode == EFL_UI_SELECT_MODE_MULTI &&
1044 mode != EFL_UI_SELECT_MODE_MULTI) ||
1045 mode == EFL_UI_SELECT_MODE_NONE)
1046 {
1047 Eina_List *clone = eina_list_clone(pd->selected);
1048 EINA_LIST_FREE(clone, selected)
1049 efl_ui_item_selected_set(selected, EINA_FALSE);
1050 }
1051
1052 pd->select_mode = mode;
1053}
1054
1055EOLIAN static Efl_Ui_Select_Mode
1056_efl_ui_grid_efl_ui_multi_selectable_select_mode_get(const Eo *obj EINA_UNUSED, Efl_Ui_Grid_Data *pd)
1057{
1058 return pd->select_mode;
1059}
1060
1061/* List APIs */
1062EOLIAN static void
1063_efl_ui_grid_item_scroll(Eo *obj,
1064 Efl_Ui_Grid_Data *pd,
1065 Efl_Ui_Grid_Item *item,
1066 Eina_Bool animation)
1067{
1068 // Need to be implemented here.
1069 if (pd->pan_resized)
1070 {
1071 _item_scroll_internal(obj, item, -1.0, animation);
1072 }
1073 else
1074 {
1075 pd->scroll.item = item;
1076 pd->scroll.align = -1.0;
1077 pd->scroll.anim = animation;
1078 }
1079}
1080
1081EOLIAN static void
1082_efl_ui_grid_item_scroll_align(Eo *obj,
1083 Efl_Ui_Grid_Data *pd,
1084 Efl_Ui_Grid_Item *item,
1085 double align,
1086 Eina_Bool animation)
1087{
1088 // Need to be implemented here.
1089 if (pd->pan_resized)
1090 {
1091 _item_scroll_internal(obj, item, align, animation);
1092 }
1093 else
1094 {
1095 pd->scroll.item = item;
1096 pd->scroll.align = align;
1097 pd->scroll.anim = animation;
1098 }
1099}
1100
1101EOLIAN static Efl_Ui_Grid_Item *
1102_efl_ui_grid_last_selected_item_get(const Eo *obj EINA_UNUSED, Efl_Ui_Grid_Data *pd)
1103{
1104 return pd->last_selected;
1105}
1106
1107EOLIAN static Eina_Iterator *
1108_efl_ui_grid_selected_items_get(Eo *obj, Efl_Ui_Grid_Data *pd)
1109{
1110 return _grid_item_iterator_new(obj, pd->selected);
1111}
1112
1113EOLIAN static void
1114_efl_ui_grid_item_size_set(Eo *obj EINA_UNUSED, Efl_Ui_Grid_Data *pd, Eina_Size2D size)
1115{
1116 pd->item.size = size;
1117 //reset linemax for recalculate layout.
1118 pd->linemax = 0;
1119
1120 _need_update(pd);
1121}
1122
1123EOLIAN static Eina_Size2D
1124_efl_ui_grid_item_size_get(const Eo *obj EINA_UNUSED, Efl_Ui_Grid_Data *pd)
1125{
1126 return pd->item.size;
1127}
1128
1129/* Internal EO APIs and hidden overrides */
1130#define EFL_UI_GRID_EXTRA_OPS \
1131 ELM_LAYOUT_SIZING_EVAL_OPS(efl_ui_grid)
1132
1133#include "efl_ui_grid.eo.c" 33#include "efl_ui_grid.eo.c"
diff --git a/src/lib/elementary/efl_ui_grid.eo b/src/lib/elementary/efl_ui_grid.eo
index c1a3e3ab0c..ce4fbd6a29 100644
--- a/src/lib/elementary/efl_ui_grid.eo
+++ b/src/lib/elementary/efl_ui_grid.eo
@@ -1,100 +1,10 @@
1import efl_ui_grid_item; 1import efl_ui_grid_item;
2 2
3class @beta Efl.Ui.Grid extends Efl.Ui.Layout_Base implements 3class @beta Efl.Ui.Grid extends Efl.Ui.Item_Container
4 Efl.Ui.Scrollable_Interactive,
5 Efl.Ui.Scrollbar,
6 Efl.Pack_Linear, Efl.Pack_Layout,
7 Efl.Ui.Layout_Orientable,
8 Efl.Ui.Selectable,
9 Efl.Ui.Multi_Selectable,
10 Efl.Gfx.Arrangement
11{ 4{
12 [[Simple grid widget with Pack interface.]] 5 [[Simple grid widget with Pack interface.]]
13 methods { 6
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 @no_unused; [[Iterator covered by selected items list.
47 user have to free the iterator after used.]]
48 }
49 }
50 implements { 7 implements {
51 //Efl.Object
52 Efl.Object.constructor; 8 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.Layout_Orientable.orientation { 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.Gfx.Arrangement.content_padding { get; set; }
88 Efl.Gfx.Arrangement.content_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 composite {
97 Efl.Ui.Scrollable_Interactive;
98 Efl.Ui.Scrollbar;
99 } 9 }
100} 10}
diff --git a/src/lib/elementary/efl_ui_grid_private.h b/src/lib/elementary/efl_ui_grid_private.h
deleted file mode 100644
index c9c8e0ef1b..0000000000
--- a/src/lib/elementary/efl_ui_grid_private.h
+++ /dev/null
@@ -1,83 +0,0 @@
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_Layout_Orientation 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/meson.build b/src/lib/elementary/meson.build
index 3aef4df9ce..0764f61ced 100644
--- a/src/lib/elementary/meson.build
+++ b/src/lib/elementary/meson.build
@@ -357,7 +357,6 @@ elementary_headers_unstable = [
357 'efl_ui_list_item_private.h', 357 'efl_ui_list_item_private.h',
358 'efl_ui_list_private.h', 358 'efl_ui_list_private.h',
359 'efl_ui_grid_item_private.h', 359 'efl_ui_grid_item_private.h',
360 'efl_ui_grid_private.h',
361 'efl_ui_list_view_private.h', 360 'efl_ui_list_view_private.h',
362 'efl_ui_list_view_seg_array.h', 361 'efl_ui_list_view_seg_array.h',
363 'elm_widget_web.h', 362 'elm_widget_web.h',
diff --git a/src/tests/elementary/efl_ui_test_grid.c b/src/tests/elementary/efl_ui_test_grid.c
index 50daae06bd..1ddf055399 100644
--- a/src/tests/elementary/efl_ui_test_grid.c
+++ b/src/tests/elementary/efl_ui_test_grid.c
@@ -17,7 +17,6 @@ grid_setup()
17 17
18 grid = efl_add(EFL_UI_GRID_CLASS, win); 18 grid = efl_add(EFL_UI_GRID_CLASS, win);
19 19
20 efl_ui_grid_item_size_set(grid, EINA_SIZE2D(100, 100));
21 efl_gfx_entity_size_set(grid, EINA_SIZE2D(500, 50)); 20 efl_gfx_entity_size_set(grid, EINA_SIZE2D(500, 50));
22 efl_gfx_entity_size_set(win, EINA_SIZE2D(500, 50)); 21 efl_gfx_entity_size_set(win, EINA_SIZE2D(500, 50));
23 efl_gfx_entity_visible_set(win, EINA_TRUE); 22 efl_gfx_entity_visible_set(win, EINA_TRUE);
@@ -31,6 +30,7 @@ grid_item_pack(Eo *grid, int count, Eina_List **l)
31 for (i = 0; i < count; i++) 30 for (i = 0; i < count; i++)
32 { 31 {
33 item = efl_add(EFL_UI_GRID_DEFAULT_ITEM_CLASS, grid); 32 item = efl_add(EFL_UI_GRID_DEFAULT_ITEM_CLASS, grid);
33 efl_gfx_hint_size_min_set(item, EINA_SIZE2D(100, 100));
34 if (!item) return EINA_FALSE; 34 if (!item) return EINA_FALSE;
35 if (l) *l = eina_list_append(*l, item); 35 if (l) *l = eina_list_append(*l, item);
36 efl_pack(grid, item); 36 efl_pack(grid, item);
@@ -282,14 +282,14 @@ EFL_START_TEST(efl_ui_grid_scroll)
282 ck_assert(grid_item_pack(grid, 100, NULL) != EINA_FALSE); 282 ck_assert(grid_item_pack(grid, 100, NULL) != EINA_FALSE);
283 item = efl_pack_content_get(grid, 50); 283 item = efl_pack_content_get(grid, 50);
284 284
285 timer = efl_add(EFL_LOOP_TIMER_CLASS, efl_main_loop_get(), 285 timer = efl_add(EFL_LOOP_TIMER_CLASS, efl_main_loop_get(),
286 efl_event_callback_add(efl_added, EFL_LOOP_TIMER_EVENT_TIMER_TICK, grid_timer_cb, NULL), 286 efl_event_callback_add(efl_added, EFL_LOOP_TIMER_EVENT_TIMER_TICK, grid_timer_cb, NULL),
287 efl_loop_timer_loop_reset(efl_added), 287 efl_loop_timer_loop_reset(efl_added),
288 efl_loop_timer_interval_set(efl_added, 3.0)); 288 efl_loop_timer_interval_set(efl_added, 3.0));
289 289
290 efl_event_callback_array_add(grid, grid_scroll_callbacks(), timer); 290 efl_event_callback_array_add(grid, grid_scroll_callbacks(), timer);
291 /*FIXME: efl_ui_scroll_interface only emit scroll event when animation exist */ 291 /*FIXME: efl_ui_scroll_interface only emit scroll event when animation exist */
292 efl_ui_grid_item_scroll(grid, item, EINA_TRUE); 292 efl_ui_item_container_item_scroll(grid, item, EINA_TRUE);
293 ecore_main_loop_begin(); 293 ecore_main_loop_begin();
294} 294}
295EFL_END_TEST 295EFL_END_TEST