summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYeongjong Lee <cleanlyj@naver.com>2019-04-18 08:22:44 +0000
committerMarcel Hollerbach <mail@marcel-hollerbach.de>2019-04-21 12:13:13 +0200
commit3e495010431e75afa12452d27c649bbf8b2b9bf9 (patch)
treef021a488d881d14f63c9d73f28fa321618167c96
parentef3281c924533e083fab9f71e3d459e7087a7da1 (diff)
ui.table: remove leagcy evas_table from Efl.Ui.Table
Remove evas_table. This expect to improve performance by removing internal function call related evas_table. Reviewed-by: Marcel Hollerbach <mail@marcel-hollerbach.de> Differential Revision: https://phab.enlightenment.org/D8615
-rw-r--r--src/lib/elementary/efl_ui_table.c729
-rw-r--r--src/lib/elementary/efl_ui_table.eo3
-rw-r--r--src/lib/elementary/efl_ui_table_layout.c18
-rw-r--r--src/lib/elementary/efl_ui_table_private.h13
-rw-r--r--src/tests/elementary/efl_ui_test_table.c152
5 files changed, 545 insertions, 370 deletions
diff --git a/src/lib/elementary/efl_ui_table.c b/src/lib/elementary/efl_ui_table.c
index 7a11f2fb71..402b812bc8 100644
--- a/src/lib/elementary/efl_ui_table.c
+++ b/src/lib/elementary/efl_ui_table.c
@@ -1,136 +1,153 @@
1#include "efl_ui_table_private.h" 1#include "efl_ui_table_private.h"
2 2
3#include "../evas/canvas/evas_table_eo.h"
4
5#define MY_CLASS EFL_UI_TABLE_CLASS 3#define MY_CLASS EFL_UI_TABLE_CLASS
6#define MY_CLASS_NAME "Efl.Ui.Table" 4#define MY_CLASS_NAME "Efl.Ui.Table"
7#define MY_CLASS_NAME_LEGACY "elm_grid"
8
9typedef struct _Custom_Table_Data Custom_Table_Data;
10
11static void _subobj_del_cb(void *data, const Efl_Event *event);
12static void _item_remove(Efl_Ui_Table *obj, Efl_Ui_Table_Data *pd, Efl_Gfx_Entity *subobj);
13
14struct _Custom_Table_Data
15{
16 Efl_Ui_Table *parent;
17 Efl_Ui_Table_Data *gd;
18};
19 5
20EFL_CALLBACKS_ARRAY_DEFINE(subobj_callbacks, 6#define EFL_UI_TABLE_DATA_GET(o, pd) \
21 { EFL_EVENT_DEL, _subobj_del_cb }); 7 Efl_Ui_Table_Data *pd = efl_data_scope_get(o, EFL_UI_TABLE_CLASS)
22 8
23static void 9inline static Table_Item *
24_mirrored_set(Evas_Object *obj, Eina_Bool rtl) 10_efl_ui_table_item_date_get(Eo *obj, Efl_Ui_Table_Data *pd, Efl_Gfx_Entity *subobj)
25{ 11{
26 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd); 12 Table_Item *gi;
27 13 if (!efl_invalidated_get(subobj) &&
28 evas_object_table_mirrored_set(wd->resize_obj, rtl); 14 (obj != efl_canvas_object_render_parent_get(subobj)))
15 {
16 ERR("%p is not a child of %p", subobj, obj);
17 return NULL;
18 }
19 gi = efl_key_data_get(subobj, TABLE_ITEM_KEY);
20 if (!gi)
21 {
22 WRN("item %p has no table internal data", subobj);
23 EINA_INLIST_FOREACH(EINA_INLIST_GET(pd->items), gi)
24 {
25 if (gi->object == subobj)
26 break;
27 }
28 if (!gi)
29 {
30 ERR("item %p was not found in this table", subobj);
31 return NULL;
32 }
33 }
34 return gi;
29} 35}
30 36
31EOLIAN static Eina_Error 37static void
32_efl_ui_table_efl_ui_widget_theme_apply(Eo *obj, Efl_Ui_Table_Data *pd EINA_UNUSED) 38_on_child_size_changed(void *data, const Efl_Event *event EINA_UNUSED)
33{ 39{
34 Eina_Error int_ret = EFL_UI_THEME_APPLY_ERROR_GENERIC; 40 Eo *table = data;
35 int_ret = efl_ui_widget_theme_apply(efl_super(obj, MY_CLASS)); 41 efl_pack_layout_request(table);
36 if (int_ret == EFL_UI_THEME_APPLY_ERROR_GENERIC) return int_ret;
37
38 _mirrored_set(obj, efl_ui_mirrored_get(obj));
39
40 return int_ret;
41} 42}
42 43
43static void 44static void
44_layout_updated_emit(Efl_Ui_Table *obj) 45_on_child_hints_changed(void *data, const Efl_Event *event EINA_UNUSED)
45{ 46{
46 efl_event_callback_legacy_call(obj, EFL_PACK_EVENT_LAYOUT_UPDATED, NULL); 47 Eo *table = data;
48 efl_pack_layout_request(table);
47} 49}
48 50
49static void 51static void
50_sizing_eval(Evas_Object *obj, Efl_Ui_Table_Data *pd EINA_UNUSED) 52_on_child_del(void *data, const Efl_Event *event)
51{ 53{
52 Evas_Coord minw = 0, minh = 0, maxw = -1, maxh = -1; 54 Eo *table = data;
53 Evas_Coord w, h; 55 Table_Item *gi;
54 56 EFL_UI_TABLE_DATA_GET(table, pd);
55 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
56 if (!efl_alive_get(obj)) return;
57 57
58 evas_object_size_hint_combined_min_get(wd->resize_obj, &minw, &minh); 58 gi = _efl_ui_table_item_date_get(table, pd, event->object);
59 evas_object_size_hint_max_get(wd->resize_obj, &maxw, &maxh); 59 if (!gi) return;
60 evas_object_size_hint_min_set(obj, minw, minh);
61 evas_object_size_hint_max_set(obj, maxw, maxh);
62 evas_object_geometry_get(obj, NULL, NULL, &w, &h);
63 if (w < minw) w = minw;
64 if (h < minh) h = minh;
65 if ((maxw >= 0) && (w > maxw)) w = maxw;
66 if ((maxh >= 0) && (h > maxh)) h = maxh;
67 evas_object_resize(obj, w, h);
68}
69 60
70static void 61 pd->items = (Table_Item *)
71_table_size_hints_changed(void *data, Evas *e EINA_UNUSED, 62 eina_inlist_remove(EINA_INLIST_GET(pd->items), EINA_INLIST_GET(gi));
72 Evas_Object *table EINA_UNUSED, 63 free(gi);
73 void *event_info EINA_UNUSED)
74{
75 Efl_Ui_Table_Data *pd = efl_data_scope_get(data, MY_CLASS);
76 64
77 if (table == data) 65 pd->count--;
78 efl_pack_layout_request(data); 66 efl_key_data_set(event->object, TABLE_ITEM_KEY, NULL);
79 else
80 _sizing_eval(data, pd);
81}
82 67
83static void 68 efl_pack_layout_request(table);
84_efl_ui_table_size_hints_changed_cb(void *data EINA_UNUSED, const Efl_Event *ev)
85{
86 efl_pack_layout_request(ev->object);
87} 69}
88 70
89/* Custom table class: overrides smart_calculate. */ 71EFL_CALLBACKS_ARRAY_DEFINE(efl_ui_table_callbacks,
90static void _custom_table_calc(Eo *obj, Custom_Table_Data *pd); 72 { EFL_GFX_ENTITY_EVENT_SIZE_CHANGED, _on_child_size_changed },
73 { EFL_GFX_ENTITY_EVENT_HINTS_CHANGED, _on_child_hints_changed },
74 { EFL_EVENT_DEL, _on_child_del }
75);
91 76
92static Eina_Bool 77static void
93_custom_table_initializer(Efl_Class *klass) 78_efl_ui_table_last_position_get(Eo * obj, Efl_Ui_Table_Data *pd, int *last_col, int *last_row)
94{ 79{
95 EFL_OPS_DEFINE(ops, 80 Table_Item *gi;
96 EFL_OBJECT_OP_FUNC(efl_canvas_group_calculate, _custom_table_calc) 81 int col = -1, row = -1;
97 ); 82 int req_cols, req_rows;
98
99 return efl_class_functions_set(klass, &ops, NULL);
100};
101 83
102static const Efl_Class_Description custom_table_class_desc = { 84 if (!pd->linear_recalc)
103 EO_VERSION, "Efl.Ui.Table.Internal", EFL_CLASS_TYPE_REGULAR, 85 {
104 sizeof(Custom_Table_Data), _custom_table_initializer, NULL, NULL 86 *last_col = pd->last_col;
105}; 87 *last_row = pd->last_row;
88 return;
89 }
106 90
107EFL_DEFINE_CLASS(_efl_ui_table_custom_table_class_get, &custom_table_class_desc, 91 efl_pack_table_size_get(obj, &req_cols, &req_rows);
108 EVAS_TABLE_CLASS, NULL)
109 92
110#define CUSTOM_TABLE_CLASS _efl_ui_table_custom_table_class_get() 93 if (efl_ui_dir_is_horizontal(pd->dir1, EINA_TRUE))
94 {
95 EINA_INLIST_REVERSE_FOREACH(EINA_INLIST_GET(pd->items), gi)
96 {
97 if ((gi->row < row) || (req_cols < gi->col) || (req_rows < gi->row))
98 continue;
99
100 if (gi->row > row)
101 {
102 row = gi->row;
103 col = gi->col;
104 }
105 else if (gi->col > col)
106 {
107 col = gi->col;
108 }
109 }
110 }
111 else
112 {
113 EINA_INLIST_REVERSE_FOREACH(EINA_INLIST_GET(pd->items), gi)
114 {
115 if ((gi->col < col) || (req_cols < gi->col) || (req_rows < gi->row))
116 continue;
117
118 if (gi->col > col)
119 {
120 col = gi->col;
121 row = gi->row;
122 }
123 else if (gi->row > row)
124 {
125 row = gi->row;
126 }
127 }
128 }
129 *last_col = col;
130 *last_row = row;
131 pd->linear_recalc = EINA_FALSE;
132}
111 133
112static void 134static void
113_custom_table_calc(Eo *obj, Custom_Table_Data *pd) 135_efl_ui_table_size_hints_changed_cb(void *data EINA_UNUSED, const Efl_Event *ev)
114{ 136{
115 int cols, rows; 137 efl_pack_layout_request(ev->object);
116
117 evas_object_table_col_row_size_get(obj, &cols, &rows);
118 if ((cols < 1) || (rows < 1)) return;
119
120 efl_pack_layout_update(pd->parent);
121 _layout_updated_emit(pd->parent);
122} 138}
123/* End of custom table class */
124 139
125EOLIAN static void 140EOLIAN static void
126_efl_ui_table_homogeneous_set(Eo *obj, Efl_Ui_Table_Data *pd, Eina_Bool homogeneoush, Eina_Bool homogeneousv) 141_efl_ui_table_homogeneous_set(Eo *obj, Efl_Ui_Table_Data *pd, Eina_Bool homogeneoush, Eina_Bool homogeneousv)
127{ 142{
128 if ((pd->homogeneoush == !!homogeneoush) && 143 homogeneoush = !!homogeneoush;
129 (pd->homogeneousv == !!homogeneousv)) 144 homogeneousv = !!homogeneousv;
145
146 if ((pd->homogeneoush == homogeneoush) && (pd->homogeneousv == homogeneousv))
130 return; 147 return;
131 148
132 pd->homogeneoush = !!homogeneoush; 149 pd->homogeneoush = homogeneoush;
133 pd->homogeneousv = !!homogeneousv; 150 pd->homogeneousv = homogeneousv;
134 efl_pack_layout_request(obj); 151 efl_pack_layout_request(obj);
135} 152}
136 153
@@ -148,66 +165,50 @@ _efl_ui_table_efl_pack_layout_layout_update(Eo *obj, Efl_Ui_Table_Data *pd)
148} 165}
149 166
150EOLIAN void 167EOLIAN void
151_efl_ui_table_efl_canvas_group_group_calculate(Eo *obj, Efl_Ui_Table_Data *pd EINA_UNUSED) 168_efl_ui_table_efl_canvas_group_group_calculate(Eo *obj, Efl_Ui_Table_Data *_pd EINA_UNUSED)
152{ 169{
153 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
154
155 efl_pack_layout_update(obj); 170 efl_pack_layout_update(obj);
156} 171}
157 172
158EOLIAN static void 173EOLIAN static void
159_efl_ui_table_efl_canvas_group_group_add(Eo *obj, Efl_Ui_Table_Data *pd) 174_efl_ui_table_efl_gfx_entity_size_set(Eo *obj, Efl_Ui_Table_Data *_pd EINA_UNUSED, Eina_Size2D sz)
160{ 175{
161 Custom_Table_Data *custom; 176 efl_gfx_entity_size_set(efl_super(obj, MY_CLASS), sz);
162 Evas_Object *table; 177 efl_canvas_group_change(obj);
163 178}
164 table = efl_add(CUSTOM_TABLE_CLASS, obj);
165 custom = efl_data_scope_get(table, CUSTOM_TABLE_CLASS);
166 custom->gd = pd;
167 custom->parent = obj;
168 179
169 evas_object_table_homogeneous_set(table, EVAS_OBJECT_TABLE_HOMOGENEOUS_TABLE); 180EOLIAN static void
170 elm_widget_resize_object_set(obj, table); 181_efl_ui_table_efl_gfx_entity_position_set(Eo *obj, Efl_Ui_Table_Data *_pd EINA_UNUSED, Eina_Position2D pos)
182{
183 efl_gfx_entity_position_set(efl_super(obj, MY_CLASS), pos);
184 efl_canvas_group_change(obj);
185}
171 186
172 evas_object_event_callback_add 187EOLIAN static void
173 (table, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _table_size_hints_changed, obj); 188_efl_ui_table_efl_canvas_group_group_add(Eo *obj, Efl_Ui_Table_Data *pd)
174 efl_event_callback_add(obj, EFL_GFX_ENTITY_EVENT_HINTS_CHANGED, 189{
175 _efl_ui_table_size_hints_changed_cb, NULL); 190 pd->clipper = efl_add(EFL_CANVAS_RECTANGLE_CLASS, obj);
191 evas_object_static_clip_set(pd->clipper, EINA_TRUE);
192 efl_gfx_entity_geometry_set(pd->clipper, EINA_RECT(-49999, -49999, 99999, 99999));
193 efl_canvas_group_member_add(obj, pd->clipper);
194 efl_ui_widget_sub_object_add(obj, pd->clipper);
176 195
177 efl_canvas_group_add(efl_super(obj, MY_CLASS)); 196 efl_canvas_group_add(efl_super(obj, MY_CLASS));
197 elm_widget_sub_object_parent_add(obj);
178 198
179 elm_widget_can_focus_set(obj, EINA_FALSE); 199 efl_ui_widget_focus_allow_set(obj, EINA_FALSE);
180 elm_widget_highlight_ignore_set(obj, EINA_FALSE); 200 elm_widget_highlight_ignore_set(obj, EINA_FALSE);
181 201
182 efl_ui_widget_theme_apply(obj); 202 efl_event_callback_add(obj, EFL_GFX_ENTITY_EVENT_HINTS_CHANGED,
203 _efl_ui_table_size_hints_changed_cb, NULL);
183} 204}
184 205
185EOLIAN static void 206EOLIAN static void
186_efl_ui_table_efl_canvas_group_group_del(Eo *obj, Efl_Ui_Table_Data *pd EINA_UNUSED) 207_efl_ui_table_efl_canvas_group_group_del(Eo *obj, Efl_Ui_Table_Data *_pd EINA_UNUSED)
187{ 208{
188 Eina_List *l;
189 Evas_Object *child;
190
191 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
192
193 evas_object_event_callback_del_full
194 (wd->resize_obj, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
195 _table_size_hints_changed, obj);
196 efl_event_callback_del(obj, EFL_GFX_ENTITY_EVENT_HINTS_CHANGED, 209 efl_event_callback_del(obj, EFL_GFX_ENTITY_EVENT_HINTS_CHANGED,
197 _efl_ui_table_size_hints_changed_cb, NULL); 210 _efl_ui_table_size_hints_changed_cb, NULL);
198 211
199 /* let's make our table object the *last* to be processed, since it
200 * may (smart) parent other sub objects here */
201 EINA_LIST_FOREACH(wd->subobjs, l, child)
202 {
203 if (child == wd->resize_obj)
204 {
205 wd->subobjs =
206 eina_list_demote_list(wd->subobjs, l);
207 break;
208 }
209 }
210
211 efl_canvas_group_del(efl_super(obj, MY_CLASS)); 212 efl_canvas_group_del(efl_super(obj, MY_CLASS));
212} 213}
213 214
@@ -216,6 +217,7 @@ _efl_ui_table_efl_object_constructor(Eo *obj, Efl_Ui_Table_Data *pd)
216{ 217{
217 obj = efl_constructor(efl_super(obj, MY_CLASS)); 218 obj = efl_constructor(efl_super(obj, MY_CLASS));
218 efl_canvas_object_type_set(obj, MY_CLASS_NAME); 219 efl_canvas_object_type_set(obj, MY_CLASS_NAME);
220 efl_access_object_access_type_set(obj, EFL_ACCESS_TYPE_SKIPPED);
219 efl_access_object_role_set(obj, EFL_ACCESS_ROLE_FILLER); 221 efl_access_object_role_set(obj, EFL_ACCESS_ROLE_FILLER);
220 222
221 pd->dir1 = EFL_UI_DIR_RIGHT; 223 pd->dir1 = EFL_UI_DIR_RIGHT;
@@ -224,38 +226,35 @@ _efl_ui_table_efl_object_constructor(Eo *obj, Efl_Ui_Table_Data *pd)
224 pd->last_row = -1; 226 pd->last_row = -1;
225 pd->req_cols = 0; 227 pd->req_cols = 0;
226 pd->req_rows = 0; 228 pd->req_rows = 0;
229 pd->cols = 0;
230 pd->rows = 0;
227 pd->align.h = 0.5; 231 pd->align.h = 0.5;
228 pd->align.v = 0.5; 232 pd->align.v = 0.5;
229 233
230 return obj; 234 return obj;
231} 235}
232 236
233
234
235EOLIAN static void 237EOLIAN static void
236_efl_ui_table_efl_pack_pack_padding_set(Eo *obj, Efl_Ui_Table_Data *pd EINA_UNUSED, double h, double v, Eina_Bool scalable) 238_efl_ui_table_efl_pack_pack_padding_set(Eo *obj, Efl_Ui_Table_Data *pd, double h, double v, Eina_Bool scalable)
237{ 239{
238 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd); 240 scalable = !!scalable;
239
240 if (h < 0) h = 0; 241 if (h < 0) h = 0;
241 if (v < 0) v = 0; 242 if (v < 0) v = 0;
243
244 if (EINA_DBL_EQ(pd->pad.h, h) && EINA_DBL_EQ(pd->pad.v, v) &&
245 (pd->pad.scalable == scalable))
246 return;
247
242 pd->pad.h = h; 248 pd->pad.h = h;
243 pd->pad.v = v; 249 pd->pad.v = v;
244 pd->pad.scalable = !!scalable; 250 pd->pad.scalable = scalable;
245 if (pd->pad.scalable) 251
246 { 252 efl_pack_layout_request(obj);
247 double scale = elm_object_scale_get(obj);
248 evas_object_table_padding_set(wd->resize_obj, h * scale, v * scale);
249 }
250 else
251 evas_object_table_padding_set(wd->resize_obj, h, v);
252} 253}
253 254
254EOLIAN static void 255EOLIAN static void
255_efl_ui_table_efl_pack_pack_padding_get(const Eo *obj, Efl_Ui_Table_Data *pd EINA_UNUSED, double *h, double *v, Eina_Bool *scalable) 256_efl_ui_table_efl_pack_pack_padding_get(const Eo *obj EINA_UNUSED, Efl_Ui_Table_Data *pd, double *h, double *v, Eina_Bool *scalable)
256{ 257{
257 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
258
259 if (scalable) *scalable = pd->pad.scalable; 258 if (scalable) *scalable = pd->pad.scalable;
260 if (h) *h = pd->pad.h; 259 if (h) *h = pd->pad.h;
261 if (v) *v = pd->pad.v; 260 if (v) *v = pd->pad.v;
@@ -264,12 +263,14 @@ _efl_ui_table_efl_pack_pack_padding_get(const Eo *obj, Efl_Ui_Table_Data *pd EIN
264EOLIAN static void 263EOLIAN static void
265_efl_ui_table_efl_pack_pack_align_set(Eo *obj, Efl_Ui_Table_Data *pd, double h, double v) 264_efl_ui_table_efl_pack_pack_align_set(Eo *obj, Efl_Ui_Table_Data *pd, double h, double v)
266{ 265{
267 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
268
269 if (h < 0) h = -1; 266 if (h < 0) h = -1;
267 else if (h > 1) h = 1;
270 if (v < 0) v = -1; 268 if (v < 0) v = -1;
271 if (h > 1) h = 1; 269 else if (v > 1) v = 1;
272 if (v > 1) v = 1; 270
271 if (EINA_DBL_EQ(pd->align.h, h) && EINA_DBL_EQ(pd->align.v, v))
272 return;
273
273 pd->align.h = h; 274 pd->align.h = h;
274 pd->align.v = v; 275 pd->align.v = v;
275 276
@@ -283,38 +284,20 @@ _efl_ui_table_efl_pack_pack_align_get(const Eo *obj EINA_UNUSED, Efl_Ui_Table_Da
283 if (v) *v = pd->align.v; 284 if (v) *v = pd->align.v;
284} 285}
285 286
286static void
287_subobj_del_cb(void *data, const Efl_Event *event)
288{
289 Efl_Ui_Table *obj = data;
290 Efl_Ui_Table_Data *pd = efl_data_scope_get(obj, EFL_UI_TABLE_CLASS);
291
292 efl_event_callback_array_del(event->object, subobj_callbacks(), data);
293 _item_remove(obj, pd, event->object);
294
295 if (!elm_widget_sub_object_del(obj, event->object))
296 WRN("failed to remove child from its parent");
297}
298
299static Eina_Bool 287static Eina_Bool
300_pack_at(Eo *obj, Efl_Ui_Table_Data *pd, Efl_Gfx_Entity *subobj, 288_pack_at(Eo *obj, Efl_Ui_Table_Data *pd, Efl_Gfx_Entity *subobj, int col, int row, int colspan, int rowspan)
301 int col, int row, int colspan, int rowspan, Eina_Bool linear)
302{ 289{
303 Table_Item *gi = NULL; 290 Table_Item *gi;
304
305 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, EINA_FALSE);
306
307 gi = efl_key_data_get(subobj, TABLE_ITEM_KEY);
308 291
309 if (gi && efl_ui_widget_parent_get(subobj) == obj) 292 if (efl_key_data_get(subobj, TABLE_ITEM_KEY))
310 { 293 {
311 ERR("subobj %p %s is already added to this", subobj, efl_class_name_get(subobj) ); 294 if (efl_canvas_object_render_parent_get(subobj) == obj)
295 ERR("subobj %p %s is already added to this", subobj, efl_class_name_get(subobj));
296 else
297 ERR("subobj %p %s currently belongs to different table", subobj, efl_class_name_get(subobj));
298
312 return EINA_FALSE; 299 return EINA_FALSE;
313 } 300 }
314 else if (gi && efl_ui_widget_parent_get(subobj) != obj)
315 {
316 gi = NULL;
317 }
318 301
319 if (col < 0) col = 0; 302 if (col < 0) col = 0;
320 if (row < 0) row = 0; 303 if (row < 0) row = 0;
@@ -337,28 +320,39 @@ _pack_at(Eo *obj, Efl_Ui_Table_Data *pd, Efl_Gfx_Entity *subobj,
337 col, row, colspan, rowspan, pd->req_cols, pd->req_rows); 320 col, row, colspan, rowspan, pd->req_cols, pd->req_rows);
338 } 321 }
339 322
340 if (!gi) 323 if (!efl_ui_widget_sub_object_add(obj, subobj))
341 { 324 return EINA_FALSE;
342 if (!elm_widget_sub_object_add(obj, subobj))
343 return EINA_FALSE;
344 gi = calloc(1, sizeof(*gi));
345 if (!gi) return EINA_FALSE;
346 gi->col = col;
347 gi->row = row;
348 gi->col_span = colspan;
349 gi->row_span = rowspan;
350 gi->linear = !!linear;
351 gi->object = subobj; // xref(, obj);
352 pd->count++;
353 pd->items = (Table_Item *)
354 eina_inlist_append(EINA_INLIST_GET(pd->items), EINA_INLIST_GET(gi));
355 325
356 efl_key_data_set(subobj, TABLE_ITEM_KEY, gi); 326 gi = calloc(1, sizeof(*gi));
357 efl_event_callback_legacy_call(obj, EFL_CONTAINER_EVENT_CONTENT_ADDED, subobj); 327 if (!gi) return EINA_FALSE;
358 efl_event_callback_array_add(subobj, subobj_callbacks(), obj); 328 gi->col = col;
359 } 329 gi->row = row;
330 gi->col_span = colspan;
331 gi->row_span = rowspan;
332 gi->object = subobj;
333 pd->count++;
334 pd->items = (Table_Item *)
335 eina_inlist_append(EINA_INLIST_GET(pd->items), EINA_INLIST_GET(gi));
336
337 efl_key_data_set(subobj, TABLE_ITEM_KEY, gi);
338 efl_key_data_set(subobj, "_elm_leaveme", obj);
339 efl_canvas_object_clipper_set(subobj, pd->clipper);
340 efl_event_callback_array_add(subobj, efl_ui_table_callbacks(), obj);
360 341
361 return evas_object_table_pack(wd->resize_obj, subobj, col, row, colspan, rowspan); 342 efl_canvas_group_member_add(obj, subobj);
343 efl_event_callback_call(obj, EFL_CONTAINER_EVENT_CONTENT_ADDED, subobj);
344
345 if ((gi->col > pd->last_col) || (gi->row > pd->last_row))
346 pd->linear_recalc = EINA_TRUE;
347
348 if (pd->cols < gi->col + gi->col_span)
349 pd->cols = gi->col + gi->col_span;
350 if (pd->rows < gi->row + gi->row_span)
351 pd->rows = gi->row + gi->row_span;
352
353 efl_pack_layout_request(obj);
354
355 return EINA_TRUE;
362} 356}
363 357
364EOLIAN static Eina_Bool 358EOLIAN static Eina_Bool
@@ -368,35 +362,26 @@ _efl_ui_table_efl_pack_table_pack_table(Eo *obj, Efl_Ui_Table_Data *pd,
368{ 362{
369 EINA_SAFETY_ON_NULL_RETURN_VAL(subobj, EINA_FALSE); 363 EINA_SAFETY_ON_NULL_RETURN_VAL(subobj, EINA_FALSE);
370 364
371 return _pack_at(obj, pd, subobj, col, row, colspan, rowspan, EINA_FALSE); 365 return _pack_at(obj, pd, subobj, col, row, colspan, rowspan);
372} 366}
373 367
374EOLIAN static Eina_Bool 368EOLIAN static Eina_Bool
375_efl_ui_table_efl_pack_table_table_position_get(const Eo *obj, Efl_Ui_Table_Data *pd EINA_UNUSED, Evas_Object *subobj, int *col, int *row, int *colspan, int *rowspan) 369_efl_ui_table_efl_pack_table_table_position_get(const Eo *obj, Efl_Ui_Table_Data *pd, Evas_Object *subobj, int *col, int *row, int *colspan, int *rowspan)
376{ 370{
377 int c = -1, r = -1, cs = 0, rs = 0; 371 int c = -1, r = -1, cs = 0, rs = 0;
378 Table_Item *gi; 372 Table_Item *gi;
379 Eina_Bool ret = EINA_FALSE; 373 Eina_Bool ret = EINA_FALSE;
380 374
381 if (obj != elm_widget_parent_widget_get(subobj)) 375 gi = _efl_ui_table_item_date_get((Eo *)obj, pd, subobj);
382 {
383 if (efl_invalidated_get(subobj)) goto end;
384 ERR("%p is not a child of %p", subobj, obj);
385 goto end;
386 }
387
388 gi = efl_key_data_get(subobj, TABLE_ITEM_KEY);
389 if (gi) 376 if (gi)
390 { 377 {
391 c = gi->col; 378 c = gi->col;
392 r = gi->row; 379 r = gi->row;
393 cs = gi->col_span; 380 cs = gi->col_span;
394 rs = gi->row_span; 381 rs = gi->row_span;
382 ret = EINA_TRUE;
395 } 383 }
396 384
397 ret = EINA_TRUE;
398
399end:
400 if (col) *col = c; 385 if (col) *col = c;
401 if (row) *row = r; 386 if (row) *row = r;
402 if (colspan) *colspan = cs; 387 if (colspan) *colspan = cs;
@@ -405,96 +390,86 @@ end:
405} 390}
406 391
407EOLIAN static Efl_Gfx_Entity * 392EOLIAN static Efl_Gfx_Entity *
408_efl_ui_table_efl_pack_table_table_content_get(Eo *obj, Efl_Ui_Table_Data *pd EINA_UNUSED, int col, int row) 393_efl_ui_table_efl_pack_table_table_content_get(Eo *obj EINA_UNUSED, Efl_Ui_Table_Data *pd, int col, int row)
409{ 394{
410 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, NULL); 395 Table_Item *gi;
396 EINA_INLIST_FOREACH(EINA_INLIST_GET(pd->items), gi)
397 {
398 if (gi->col == col && gi->row == row)
399 return gi->object;
400 }
411 401
412 return evas_object_table_child_get(wd->resize_obj, col, row); 402 return NULL;
413} 403}
414 404
415static void 405static Eina_Bool
416_item_remove(Efl_Ui_Table *obj, Efl_Ui_Table_Data *pd, Efl_Gfx_Entity *subobj) 406_item_remove(Efl_Ui_Table *obj, Efl_Ui_Table_Data *pd, Table_Item *gi)
417{ 407{
418 Table_Item *gi = efl_key_data_get(subobj, TABLE_ITEM_KEY); 408 Efl_Gfx_Entity *subobj = gi->object;
419 Table_Item *gi2, *last = NULL;
420 409
421 if (!gi) 410 if (!subobj || !_elm_widget_sub_object_redirect_to_top(obj, subobj))
422 { 411 return EINA_FALSE;
423 WRN("item %p has no table internal data", subobj);
424 EINA_INLIST_FOREACH(EINA_INLIST_GET(pd->items), gi)
425 if (gi->object == subobj)
426 break;
427 if (!gi)
428 {
429 ERR("item %p was not found in this table", subobj);
430 return;
431 }
432 }
433 412
434 if (!gi->linear) 413 efl_canvas_object_clipper_set(subobj, NULL);
435 goto end; 414 efl_key_data_set(subobj, "_elm_leaveme", NULL);
415 efl_key_data_set(subobj, TABLE_ITEM_KEY, NULL);
416 efl_event_callback_array_del(subobj, efl_ui_table_callbacks(), obj);
436 417
437 EINA_INLIST_REVERSE_FOREACH(EINA_INLIST_GET(pd->items), gi2) 418 efl_canvas_group_member_remove(obj, subobj);
438 { 419 efl_event_callback_call(obj, EFL_CONTAINER_EVENT_CONTENT_REMOVED, subobj);
439 if (gi2 == gi) continue; 420
440 if (!gi2->linear) continue; 421 if ((gi->col == pd->last_col) && (gi->row == pd->last_row))
441 last = gi2; 422 pd->linear_recalc = EINA_TRUE;
442 break; 423
443 } 424 if (gi->col + gi->col_span >= pd->cols)
444 if (last) 425 pd->cols_recalc = EINA_TRUE;
445 { 426 if (gi->row + gi->row_span >= pd->rows)
446 if (efl_ui_dir_is_horizontal(pd->dir1, EINA_TRUE)) 427 pd->rows_recalc = EINA_TRUE;
447 {
448 pd->last_col = last->col + last->col_span - 1;
449 pd->last_row = last->row;
450 }
451 else
452 {
453 pd->last_row = last->row + last->row_span - 1;
454 pd->last_col = last->col;
455 }
456 }
457 else
458 {
459 pd->last_col = -1;
460 pd->last_row = -1;
461 }
462 428
463end:
464 efl_event_callback_legacy_call(obj, EFL_CONTAINER_EVENT_CONTENT_REMOVED, subobj);
465 pd->items = (Table_Item *) 429 pd->items = (Table_Item *)
466 eina_inlist_remove(EINA_INLIST_GET(pd->items), EINA_INLIST_GET(gi)); 430 eina_inlist_remove(EINA_INLIST_GET(pd->items), EINA_INLIST_GET(gi));
467 pd->count--;
468 efl_key_data_set(subobj, TABLE_ITEM_KEY, NULL);
469 efl_event_callback_array_del(subobj, subobj_callbacks(), obj);
470 free(gi); 431 free(gi);
432
433 pd->count--;
434 efl_pack_layout_request(obj);
435
436 return EINA_TRUE;
471} 437}
472 438
473EOLIAN static Eina_Bool 439EOLIAN static Eina_Bool
474_efl_ui_table_efl_pack_unpack(Eo *obj, Efl_Ui_Table_Data *pd, Efl_Gfx_Entity *subobj) 440_efl_ui_table_efl_pack_unpack(Eo *obj, Efl_Ui_Table_Data *pd, Efl_Gfx_Entity *subobj)
475{ 441{
476 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, EINA_FALSE); 442 Table_Item *gi = _efl_ui_table_item_date_get(obj, pd, subobj);
443 if (!gi) return EINA_FALSE;
477 444
478 _item_remove(obj, pd, subobj); 445 return _item_remove(obj, pd, gi);
479 if (evas_object_table_unpack(wd->resize_obj, subobj))
480 {
481 if (elm_widget_sub_object_del(obj, subobj))
482 return EINA_TRUE;
483 return EINA_FALSE; // oops - unlikely
484 }
485
486 return EINA_FALSE;
487} 446}
488 447
489EOLIAN static Eina_Bool 448EOLIAN static Eina_Bool
490_efl_ui_table_efl_pack_pack_clear(Eo *obj, Efl_Ui_Table_Data *pd) 449_efl_ui_table_efl_pack_pack_clear(Eo *obj, Efl_Ui_Table_Data *pd)
491{ 450{
492 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, EINA_FALSE); 451 Table_Item *gi;
493 452
494 while (pd->items) 453 EINA_INLIST_FREE(EINA_INLIST_GET(pd->items), gi)
495 _item_remove(obj, pd, pd->items->object); 454 {
455 efl_event_callback_array_del(gi->object, efl_ui_table_callbacks(), obj);
456 efl_del(gi->object);
496 457
497 evas_object_table_clear(wd->resize_obj, EINA_TRUE); 458 pd->items = (Table_Item *)
459 eina_inlist_remove(EINA_INLIST_GET(pd->items), EINA_INLIST_GET(gi));
460 free(gi);
461 }
462
463 pd->linear_recalc = EINA_TRUE;
464 pd->cols_recalc = EINA_TRUE;
465 pd->rows_recalc = EINA_TRUE;
466
467 pd->last_col = -1;
468 pd->last_row = -1;
469 pd->cols = 0;
470 pd->rows = 0;
471 pd->count = 0;
472 efl_pack_layout_request(obj);
498 473
499 return EINA_TRUE; 474 return EINA_TRUE;
500} 475}
@@ -502,79 +477,106 @@ _efl_ui_table_efl_pack_pack_clear(Eo *obj, Efl_Ui_Table_Data *pd)
502EOLIAN static Eina_Bool 477EOLIAN static Eina_Bool
503_efl_ui_table_efl_pack_unpack_all(Eo *obj, Efl_Ui_Table_Data *pd) 478_efl_ui_table_efl_pack_unpack_all(Eo *obj, Efl_Ui_Table_Data *pd)
504{ 479{
505 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, EINA_FALSE); 480 Table_Item *gi;
481 Eina_Bool ret = EINA_TRUE;
506 482
507 while (pd->items) 483 EINA_INLIST_FREE(EINA_INLIST_GET(pd->items), gi)
508 _item_remove(obj, pd, pd->items->object); 484 ret &= _item_remove(obj, pd, gi);
509 485
510 evas_object_table_clear(wd->resize_obj, EINA_FALSE); 486 pd->linear_recalc = EINA_TRUE;
487 pd->cols_recalc = EINA_TRUE;
488 pd->rows_recalc = EINA_TRUE;
511 489
512 return EINA_TRUE; 490 pd->last_col = -1;
491 pd->last_row = -1;
492 pd->cols = 0;
493 pd->rows = 0;
494
495 return ret;
513} 496}
514 497
515EOLIAN static void 498EOLIAN static void
516_efl_ui_table_efl_pack_layout_layout_request(Eo *obj, Efl_Ui_Table_Data *pd EINA_UNUSED) 499_efl_ui_table_efl_pack_layout_layout_request(Eo *obj, Efl_Ui_Table_Data *pd EINA_UNUSED)
517{ 500{
518 evas_object_smart_need_recalculate_set(obj, EINA_TRUE); 501 efl_canvas_group_need_recalculate_set(obj, EINA_TRUE);
519} 502}
520 503
521static Eina_Bool 504static Eina_Bool
522_table_item_iterator_next(Table_Item_Iterator *it, void **data) 505_efl_ui_table_item_iterator_next(Table_Item_Iterator *it, void **data)
523{ 506{
524 Efl_Gfx_Entity *sub; 507 Table_Item *gi;
525 508
526 if (!eina_iterator_next(it->real_iterator, (void **) &sub)) 509 if (!it->cur)
527 return EINA_FALSE; 510 return EINA_FALSE;
528 511
529 if (data) *data = sub; 512 if (data)
513 {
514 gi = EINA_INLIST_CONTAINER_GET(it->cur, Table_Item);
515 *data = gi->object;
516 }
517
518 it->cur = it->cur->next;
519
530 return EINA_TRUE; 520 return EINA_TRUE;
531} 521}
532 522
533static Eo * 523static Eo *
534_table_item_iterator_get_container(Table_Item_Iterator *it) 524_efl_ui_table_item_iterator_get_container(Table_Item_Iterator *it)
535{ 525{
536 return it->object; 526 return it->object;
537} 527}
538 528
539static void 529static void
540_table_item_iterator_free(Table_Item_Iterator *it) 530_efl_ui_table_item_iterator_free(Table_Item_Iterator *it)
541{ 531{
542 eina_iterator_free(it->real_iterator);
543 eina_list_free(it->list);
544 free(it); 532 free(it);
545} 533}
546 534
547static inline Eina_Iterator * 535static inline Eina_Iterator *
548_table_item_iterator_create(Eo *obj, Eina_List *list) 536_efl_ui_table_item_iterator_create(Eo *obj, Eina_Inlist *list)
549{ 537{
550 Table_Item_Iterator *it; 538 Table_Item_Iterator *it;
551 if (!list) return NULL;
552 539
553 it = calloc(1, sizeof(*it)); 540 it = calloc(1, sizeof(*it));
554 if (!it) return NULL; 541 if (!it) return NULL;
555 542
556 EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR); 543 EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR);
557 544
558 it->list = list;
559 it->real_iterator = eina_list_iterator_new(it->list);
560 it->iterator.version = EINA_ITERATOR_VERSION;
561 it->iterator.next = FUNC_ITERATOR_NEXT(_table_item_iterator_next);
562 it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(_table_item_iterator_get_container);
563 it->iterator.free = FUNC_ITERATOR_FREE(_table_item_iterator_free);
564 it->object = obj; 545 it->object = obj;
546 it->cur = list;
547
548 it->iterator.version = EINA_ITERATOR_VERSION;
549 it->iterator.next = FUNC_ITERATOR_NEXT(_efl_ui_table_item_iterator_next);
550 it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(
551 _efl_ui_table_item_iterator_get_container);
552 it->iterator.free = FUNC_ITERATOR_FREE(_efl_ui_table_item_iterator_free);
565 553
566 return &it->iterator; 554 return &it->iterator;
567} 555}
568 556
569EOLIAN static Eina_Iterator * 557EOLIAN static Eina_Iterator *
570_efl_ui_table_efl_container_content_iterate(Eo *obj, Efl_Ui_Table_Data *pd EINA_UNUSED) 558_efl_ui_table_efl_container_content_iterate(Eo *obj, Efl_Ui_Table_Data *pd)
571{ 559{
572 Eina_List *list; 560 Table_Item_Iterator *it;
561
562 if (!pd->count)
563 return NULL;
564
565 it = calloc(1, sizeof(*it));
566 if (!it) return NULL;
567
568 EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR);
569
570 it->object = obj;
571 it->cur = EINA_INLIST_GET(pd->items);
573 572
574 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, NULL); 573 it->iterator.version = EINA_ITERATOR_VERSION;
574 it->iterator.next = FUNC_ITERATOR_NEXT(_efl_ui_table_item_iterator_next);
575 it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(
576 _efl_ui_table_item_iterator_get_container);
577 it->iterator.free = FUNC_ITERATOR_FREE(_efl_ui_table_item_iterator_free);
575 578
576 list = evas_object_table_children_get(wd->resize_obj); 579 return &it->iterator;
577 return _table_item_iterator_create(obj, list);
578} 580}
579 581
580EOLIAN static int 582EOLIAN static int
@@ -584,36 +586,35 @@ _efl_ui_table_efl_container_content_count(Eo *obj EINA_UNUSED, Efl_Ui_Table_Data
584} 586}
585 587
586EOLIAN static Eina_Iterator * 588EOLIAN static Eina_Iterator *
587_efl_ui_table_efl_pack_table_table_contents_get(Eo *obj, Efl_Ui_Table_Data *pd EINA_UNUSED, 589_efl_ui_table_efl_pack_table_table_contents_get(Eo *obj EINA_UNUSED, Efl_Ui_Table_Data *pd, int col, int row, Eina_Bool below)
588 int col, int row, Eina_Bool below)
589{ 590{
590 Eina_List *list, *atlist = NULL; 591 Table_Item *gi;
591 Evas_Object *sobj; 592 Eina_List *atlist = NULL;
592
593 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, NULL);
594 593
595 list = evas_object_table_children_get(wd->resize_obj); 594 EINA_INLIST_FOREACH(EINA_INLIST_GET(pd->items), gi)
596 EINA_LIST_FREE(list, sobj)
597 { 595 {
598 Table_Item *gi = efl_key_data_get(sobj, TABLE_ITEM_KEY);
599 if (!gi) continue;
600
601 if ((gi->col == col) && (gi->row == row)) 596 if ((gi->col == col) && (gi->row == row))
602 atlist = eina_list_append(atlist, sobj); 597 atlist = eina_list_append(atlist, gi->object);
603 else if (below) 598 else if (below)
604 { 599 {
605 if ((gi->col <= col) && (gi->col + gi->col_span >= col) && 600 if ((gi->col <= col) && (gi->col + gi->col_span >= col) &&
606 (gi->row <= row) && (gi->row + gi->row_span >= row)) 601 (gi->row <= row) && (gi->row + gi->row_span >= row))
607 atlist = eina_list_append(atlist, sobj); 602 atlist = eina_list_append(atlist, gi->object);
608 } 603 }
609 } 604 }
610 605
611 return _table_item_iterator_create(obj, atlist); 606 return eina_list_iterator_new(atlist);
612} 607}
613 608
614EOLIAN static void 609EOLIAN static void
615_efl_ui_table_efl_ui_direction_direction_set(Eo *obj, Efl_Ui_Table_Data *pd, Efl_Ui_Dir dir) 610_efl_ui_table_efl_ui_direction_direction_set(Eo *obj, Efl_Ui_Table_Data *pd, Efl_Ui_Dir dir)
616{ 611{
612 if (pd->dir1 == dir)
613 return;
614
615 if (dir == EFL_UI_DIR_DEFAULT)
616 dir = EFL_UI_DIR_RIGHT;
617
617 pd->dir1 = dir; 618 pd->dir1 = dir;
618 619
619 /* if both directions are either horizontal or vertical, need to adjust 620 /* if both directions are either horizontal or vertical, need to adjust
@@ -621,10 +622,10 @@ _efl_ui_table_efl_ui_direction_direction_set(Eo *obj, Efl_Ui_Table_Data *pd, Efl
621 if (efl_ui_dir_is_horizontal(pd->dir1, EINA_TRUE) == 622 if (efl_ui_dir_is_horizontal(pd->dir1, EINA_TRUE) ==
622 efl_ui_dir_is_horizontal(pd->dir2, EINA_FALSE)) 623 efl_ui_dir_is_horizontal(pd->dir2, EINA_FALSE))
623 { 624 {
624 if (!efl_ui_dir_is_horizontal(pd->dir1, EINA_TRUE)) 625 if (efl_ui_dir_is_horizontal(pd->dir1, EINA_TRUE))
625 pd->dir2 = EFL_UI_DIR_RIGHT;
626 else
627 pd->dir2 = EFL_UI_DIR_DOWN; 626 pd->dir2 = EFL_UI_DIR_DOWN;
627 else
628 pd->dir2 = EFL_UI_DIR_RIGHT;
628 } 629 }
629 630
630 efl_pack_layout_request(obj); 631 efl_pack_layout_request(obj);
@@ -639,6 +640,9 @@ _efl_ui_table_efl_ui_direction_direction_get(const Eo *obj EINA_UNUSED, Efl_Ui_T
639EOLIAN static void 640EOLIAN static void
640_efl_ui_table_efl_pack_table_table_direction_set(Eo *obj, Efl_Ui_Table_Data *pd, Efl_Ui_Dir primary, Efl_Ui_Dir secondary) 641_efl_ui_table_efl_pack_table_table_direction_set(Eo *obj, Efl_Ui_Table_Data *pd, Efl_Ui_Dir primary, Efl_Ui_Dir secondary)
641{ 642{
643 if ((pd->dir1 == primary) && (pd->dir2 == secondary))
644 return;
645
642 pd->dir1 = primary; 646 pd->dir1 = primary;
643 pd->dir2 = secondary; 647 pd->dir2 = secondary;
644 648
@@ -664,19 +668,23 @@ _efl_ui_table_efl_pack_table_table_direction_get(const Eo *obj EINA_UNUSED, Efl_
664} 668}
665 669
666EOLIAN static void 670EOLIAN static void
667_efl_ui_table_efl_pack_table_table_size_set(Eo *obj, Efl_Ui_Table_Data *pd EINA_UNUSED, int cols, int rows) 671_efl_ui_table_efl_pack_table_table_size_set(Eo *obj, Efl_Ui_Table_Data *pd, int cols, int rows)
668{ 672{
669 if (cols < 0) cols = 0; 673 if (cols < 0) cols = 0;
670 if (rows < 0) rows = 0; 674 if (rows < 0) rows = 0;
671 675
676 if ((pd->req_cols == cols) && (pd->req_rows == rows))
677 return;
678
672 pd->req_cols = cols; 679 pd->req_cols = cols;
673 pd->req_rows = rows; 680 pd->req_rows = rows;
681 pd->linear_recalc = EINA_TRUE;
674 682
675 efl_pack_layout_request(obj); 683 efl_pack_layout_request(obj);
676} 684}
677 685
678EOLIAN static void 686EOLIAN static void
679_efl_ui_table_efl_pack_table_table_size_get(const Eo *obj EINA_UNUSED, Efl_Ui_Table_Data *pd EINA_UNUSED, int *cols, int *rows) 687_efl_ui_table_efl_pack_table_table_size_get(const Eo *obj, Efl_Ui_Table_Data *pd EINA_UNUSED, int *cols, int *rows)
680{ 688{
681 if (cols) *cols = efl_pack_table_columns_get(obj); 689 if (cols) *cols = efl_pack_table_columns_get(obj);
682 if (rows) *rows = efl_pack_table_rows_get(obj); 690 if (rows) *rows = efl_pack_table_rows_get(obj);
@@ -685,7 +693,11 @@ _efl_ui_table_efl_pack_table_table_size_get(const Eo *obj EINA_UNUSED, Efl_Ui_Ta
685EOLIAN static void 693EOLIAN static void
686_efl_ui_table_efl_pack_table_table_columns_set(Eo *obj, Efl_Ui_Table_Data *pd, int columns) 694_efl_ui_table_efl_pack_table_table_columns_set(Eo *obj, Efl_Ui_Table_Data *pd, int columns)
687{ 695{
696 if (pd->req_cols == columns)
697 return;
698
688 pd->req_cols = columns; 699 pd->req_cols = columns;
700 pd->linear_recalc = EINA_TRUE;
689 701
690 efl_pack_layout_request(obj); 702 efl_pack_layout_request(obj);
691} 703}
@@ -693,20 +705,28 @@ _efl_ui_table_efl_pack_table_table_columns_set(Eo *obj, Efl_Ui_Table_Data *pd, i
693EOLIAN static int 705EOLIAN static int
694_efl_ui_table_efl_pack_table_table_columns_get(const Eo *obj EINA_UNUSED, Efl_Ui_Table_Data *pd) 706_efl_ui_table_efl_pack_table_table_columns_get(const Eo *obj EINA_UNUSED, Efl_Ui_Table_Data *pd)
695{ 707{
696 if (!pd->req_cols) 708 Table_Item *gi;
709 if (pd->cols_recalc)
697 { 710 {
698 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, 0); 711 pd->cols = 0;
699 int cols; 712 EINA_INLIST_REVERSE_FOREACH(EINA_INLIST_GET(pd->items), gi)
700 evas_object_table_col_row_size_get(wd->resize_obj, &cols, NULL); 713 {
701 return cols; 714 if (pd->cols < gi->col + gi->col_span)
715 pd->cols = gi->col+ gi->col_span;
716 }
717 pd->cols_recalc = EINA_FALSE;
702 } 718 }
703 return pd->req_cols; 719 return pd->req_cols ? : pd->cols;
704} 720}
705 721
706EOLIAN static void 722EOLIAN static void
707_efl_ui_table_efl_pack_table_table_rows_set(Eo *obj, Efl_Ui_Table_Data *pd, int rows) 723_efl_ui_table_efl_pack_table_table_rows_set(Eo *obj, Efl_Ui_Table_Data *pd, int rows)
708{ 724{
725 if (pd->req_rows == rows)
726 return;
727
709 pd->req_rows = rows; 728 pd->req_rows = rows;
729 pd->linear_recalc = EINA_TRUE;
710 730
711 efl_pack_layout_request(obj); 731 efl_pack_layout_request(obj);
712} 732}
@@ -714,50 +734,55 @@ _efl_ui_table_efl_pack_table_table_rows_set(Eo *obj, Efl_Ui_Table_Data *pd, int
714EOLIAN static int 734EOLIAN static int
715_efl_ui_table_efl_pack_table_table_rows_get(const Eo *obj EINA_UNUSED, Efl_Ui_Table_Data *pd) 735_efl_ui_table_efl_pack_table_table_rows_get(const Eo *obj EINA_UNUSED, Efl_Ui_Table_Data *pd)
716{ 736{
717 if (!pd->req_rows) 737 Table_Item *gi;
738 if (pd->rows_recalc)
718 { 739 {
719 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, 0); 740 pd->rows = 0;
720 int rows; 741 EINA_INLIST_REVERSE_FOREACH(EINA_INLIST_GET(pd->items), gi)
721 evas_object_table_col_row_size_get(wd->resize_obj, NULL, &rows); 742 {
722 return rows; 743 if (pd->rows < gi->row + gi->row_span)
744 pd->rows = gi->row + gi->row_span;
745 }
746 pd->rows_recalc = EINA_FALSE;
723 } 747 }
724 return pd->req_rows; 748 return pd->req_rows ? : pd->rows;
725} 749}
726 750
727EOLIAN static Eina_Bool 751EOLIAN static Eina_Bool
728_efl_ui_table_efl_pack_pack(Eo *obj, Efl_Ui_Table_Data *pd, Efl_Gfx_Entity *subobj) 752_efl_ui_table_efl_pack_pack(Eo *obj, Efl_Ui_Table_Data *pd, Efl_Gfx_Entity *subobj)
729{ 753{
754 int last_col, last_row;
755
730 EINA_SAFETY_ON_NULL_RETURN_VAL(subobj, EINA_FALSE); 756 EINA_SAFETY_ON_NULL_RETURN_VAL(subobj, EINA_FALSE);
731 757
732 int col = pd->last_col; 758 _efl_ui_table_last_position_get(obj, pd, &last_col, &last_row);
733 int row = pd->last_row;
734 759
735 if (efl_ui_dir_is_horizontal(pd->dir1, EINA_TRUE)) 760 if (efl_ui_dir_is_horizontal(pd->dir1, EINA_TRUE))
736 { 761 {
737 col++; 762 last_col++;
738 if (pd->req_cols && (col >= pd->req_cols)) 763 if (pd->req_cols && (last_col >= pd->req_cols))
739 { 764 {
740 col = 0; 765 last_col = 0;
741 row++; 766 last_row++;
742 } 767 }
743 if (row < 0) row = 0; 768 if (last_row < 0) last_row = 0;
744 } 769 }
745 else 770 else
746 { 771 {
747 row++; 772 last_row++;
748 if (pd->req_rows && (row >= pd->req_rows)) 773 if (pd->req_rows && (last_row >= pd->req_rows))
749 { 774 {
750 row = 0; 775 last_row = 0;
751 col++; 776 last_col++;
752 } 777 }
753 if (col < 0) col = 0; 778 if (last_col < 0) last_col = 0;
754 } 779 }
755 780
756 pd->last_col = col; 781 pd->last_col = last_col;
757 pd->last_row = row; 782 pd->last_row = last_row;
758 783
759 DBG("packing new obj at %d,%d", col, row); 784 DBG("packing new obj at %d,%d", last_col, last_row);
760 return _pack_at(obj, pd, subobj, col, row, 1, 1, EINA_TRUE); 785 return _pack_at(obj, pd, subobj, last_col, last_row, 1, 1);
761} 786}
762 787
763/* Internal EO APIs and hidden overrides */ 788/* Internal EO APIs and hidden overrides */
diff --git a/src/lib/elementary/efl_ui_table.eo b/src/lib/elementary/efl_ui_table.eo
index 7bcf3195a1..dd4b0f7bc7 100644
--- a/src/lib/elementary/efl_ui_table.eo
+++ b/src/lib/elementary/efl_ui_table.eo
@@ -20,7 +20,8 @@ class @beta Efl.Ui.Table extends Efl.Ui.Widget implements Efl.Pack_Table, Efl.Pa
20 implements { 20 implements {
21 Efl.Object.constructor; 21 Efl.Object.constructor;
22 Efl.Canvas.Group.group_calculate; 22 Efl.Canvas.Group.group_calculate;
23 Efl.Ui.Widget.theme_apply; 23 Efl.Gfx.Entity.position { set; }
24 Efl.Gfx.Entity.size { set; }
24 Efl.Container.content_iterate; 25 Efl.Container.content_iterate;
25 Efl.Container.content_count; 26 Efl.Container.content_count;
26 Efl.Ui.Direction.direction { get; set; } 27 Efl.Ui.Direction.direction { get; set; }
diff --git a/src/lib/elementary/efl_ui_table_layout.c b/src/lib/elementary/efl_ui_table_layout.c
index 3d29551de5..ac90b63876 100644
--- a/src/lib/elementary/efl_ui_table_layout.c
+++ b/src/lib/elementary/efl_ui_table_layout.c
@@ -224,13 +224,14 @@ _efl_ui_table_custom_layout(Efl_Ui_Table *ui_table, Efl_Ui_Table_Data *pd)
224 Table_Item *ti; 224 Table_Item *ti;
225 Item_Calc *items, *item; 225 Item_Calc *items, *item;
226 Efl_Ui_Container_Item_Hints *hints; 226 Efl_Ui_Container_Item_Hints *hints;
227 int id = 0, i = 0, rows, cols; 227 int id = 0, i = 0, count, rows, cols;
228 int (*_efl_ui_table_item_pos_get[2])(Table_Calc *, Item_Calc *, Eina_Bool); 228 int (*_efl_ui_table_item_pos_get[2])(Table_Calc *, Item_Calc *, Eina_Bool);
229 int (*_efl_ui_table_item_size_get[2])(Table_Calc *, Item_Calc *, Eina_Bool); 229 int (*_efl_ui_table_item_size_get[2])(Table_Calc *, Item_Calc *, Eina_Bool);
230
231 Table_Calc table_calc; 230 Table_Calc table_calc;
232 231
233 if (!pd->count) 232 count = pd->count;
233
234 if (!count)
234 { 235 {
235 efl_gfx_hint_size_restricted_min_set(ui_table, EINA_SIZE2D(0, 0)); 236 efl_gfx_hint_size_restricted_min_set(ui_table, EINA_SIZE2D(0, 0));
236 return; 237 return;
@@ -249,20 +250,21 @@ _efl_ui_table_custom_layout(Efl_Ui_Table *ui_table, Efl_Ui_Table_Data *pd)
249 memset(table_calc.cell_calc[0], 0, cols * sizeof(Cell_Calc)); 250 memset(table_calc.cell_calc[0], 0, cols * sizeof(Cell_Calc));
250 memset(table_calc.cell_calc[1], 0, rows * sizeof(Cell_Calc)); 251 memset(table_calc.cell_calc[1], 0, rows * sizeof(Cell_Calc));
251 252
252 items = alloca(pd->count * sizeof(*items)); 253 items = alloca(count * sizeof(*items));
253#ifdef DEBUG 254#ifdef DEBUG
254 memset(items, 0, pd->count * sizeof(*items)); 255 memset(items, 0, count * sizeof(*items));
255#endif 256#endif
256 257
257 table_calc.cols = cols; 258 table_calc.cols = cols;
258 table_calc.rows = rows; 259 table_calc.rows = rows;
259 // scan all items, get their properties, calculate total weight & min size 260 // scan all items, get their properties, calculate total weight & min size
260 EINA_INLIST_FOREACH(pd->items, ti) 261 EINA_INLIST_FOREACH(EINA_INLIST_GET(pd->items), ti)
261 { 262 {
262 if (((ti->col + ti->col_span) > cols) || 263 if (((ti->col + ti->col_span) > cols) ||
263 ((ti->row + ti->row_span) > rows)) 264 ((ti->row + ti->row_span) > rows))
264 { 265 {
265 efl_gfx_entity_visible_set(ti->object, EINA_FALSE); 266 efl_gfx_entity_geometry_set(ti->object, EINA_RECT(9999, 9999, 0, 0));
267 count--;
266 continue; 268 continue;
267 } 269 }
268 270
@@ -343,7 +345,7 @@ _efl_ui_table_custom_layout(Efl_Ui_Table *ui_table, Efl_Ui_Table_Data *pd)
343 _efl_ui_table_item_size_get[1] = _efl_ui_table_regular_item_size_get; 345 _efl_ui_table_item_size_get[1] = _efl_ui_table_regular_item_size_get;
344 } 346 }
345 347
346 for (i = 0; i < pd->count; i++) 348 for (i = 0; i < count; i++)
347 { 349 {
348 Eina_Rect space, item_geom; 350 Eina_Rect space, item_geom;
349 item = &items[i]; 351 item = &items[i];
diff --git a/src/lib/elementary/efl_ui_table_private.h b/src/lib/elementary/efl_ui_table_private.h
index 4aea410376..5b1e193646 100644
--- a/src/lib/elementary/efl_ui_table_private.h
+++ b/src/lib/elementary/efl_ui_table_private.h
@@ -25,17 +25,17 @@ struct _Table_Item
25 Efl_Gfx_Entity *object; 25 Efl_Gfx_Entity *object;
26 int col_span, row_span; 26 int col_span, row_span;
27 int col, row; 27 int col, row;
28
29 Eina_Bool linear : 1;
30}; 28};
31 29
32struct _Efl_Ui_Table_Data 30struct _Efl_Ui_Table_Data
33{ 31{
34 Table_Item *items; 32 Table_Item *items;
33 Eo *clipper;
35 int count; 34 int count;
36 35
36 int cols, rows;
37 int req_cols, req_rows; // requested - 0 means infinite 37 int req_cols, req_rows; // requested - 0 means infinite
38 int last_col, last_row; // only used by linear apis 38 int last_col, last_row; // only used by pack api
39 Efl_Ui_Dir dir1, dir2; // must be orthogonal (H,V or V,H) 39 Efl_Ui_Dir dir1, dir2; // must be orthogonal (H,V or V,H)
40 struct { 40 struct {
41 double h, v; 41 double h, v;
@@ -44,6 +44,8 @@ struct _Efl_Ui_Table_Data
44 struct { 44 struct {
45 double h, v; 45 double h, v;
46 } align; 46 } align;
47 Eina_Bool cols_recalc : 1;
48 Eina_Bool rows_recalc : 1;
47 Eina_Bool linear_recalc : 1; 49 Eina_Bool linear_recalc : 1;
48 Eina_Bool homogeneoush : 1; 50 Eina_Bool homogeneoush : 1;
49 Eina_Bool homogeneousv : 1; 51 Eina_Bool homogeneousv : 1;
@@ -52,9 +54,8 @@ struct _Efl_Ui_Table_Data
52struct _Table_Item_Iterator 54struct _Table_Item_Iterator
53{ 55{
54 Eina_Iterator iterator; 56 Eina_Iterator iterator;
55 Eina_Iterator *real_iterator; 57 Efl_Ui_Table *object;
56 Eina_List *list; 58 Eina_Inlist *cur;
57 Efl_Ui_Table *object;
58}; 59};
59 60
60#endif 61#endif
diff --git a/src/tests/elementary/efl_ui_test_table.c b/src/tests/elementary/efl_ui_test_table.c
index f299fdd9bc..0762528641 100644
--- a/src/tests/elementary/efl_ui_test_table.c
+++ b/src/tests/elementary/efl_ui_test_table.c
@@ -251,9 +251,7 @@ layout_setup()
251{ 251{
252 win = win_add(); 252 win = win_add();
253 253
254 layout = efl_add(EFL_UI_TABLE_CLASS, win, 254 layout = efl_add(EFL_UI_TABLE_CLASS, win);
255 efl_pack_align_set(efl_added, 0.8, 0.2),
256 efl_ui_direction_set(efl_added, EFL_UI_DIR_VERTICAL));
257} 255}
258 256
259static void 257static void
@@ -281,6 +279,9 @@ EFL_START_TEST (efl_ui_table_layout_update)
281{ 279{
282 int i, max_index = (sizeof(hints) / sizeof(Hint)); 280 int i, max_index = (sizeof(hints) / sizeof(Hint));
283 281
282 efl_pack_align_set(layout, 0.8, 0.2);
283 efl_ui_direction_set(layout, EFL_UI_DIR_VERTICAL);
284
284 Eo *btn = efl_add(EFL_UI_BUTTON_CLASS, layout, 285 Eo *btn = efl_add(EFL_UI_BUTTON_CLASS, layout,
285 efl_pack_table(layout, efl_added, 0, 0, 1, 1)); 286 efl_pack_table(layout, efl_added, 0, 0, 1, 1));
286 287
@@ -297,6 +298,9 @@ EFL_START_TEST (efl_ui_table_layout_update_pack)
297 int i, max_index2, max_index3; 298 int i, max_index2, max_index3;
298 Eo *btn, *btn2, *btn3; 299 Eo *btn, *btn2, *btn3;
299 300
301 efl_pack_align_set(layout, 0.8, 0.2);
302 efl_ui_direction_set(layout, EFL_UI_DIR_VERTICAL);
303
300 max_index2 = ((sizeof(hints2) / sizeof(Hint)) / 2); 304 max_index2 = ((sizeof(hints2) / sizeof(Hint)) / 2);
301 max_index3 = ((sizeof(hints3) / sizeof(Hint)) / 3); 305 max_index3 = ((sizeof(hints3) / sizeof(Hint)) / 3);
302 306
@@ -333,6 +337,9 @@ EFL_START_TEST (efl_ui_table_layout_update_matrix)
333 int i, j, max_index = (sizeof(hints_matrix) / sizeof(Hint)); 337 int i, j, max_index = (sizeof(hints_matrix) / sizeof(Hint));
334 Eo *btn[9]; 338 Eo *btn[9];
335 339
340 efl_pack_align_set(layout, 0.8, 0.2);
341 efl_ui_direction_set(layout, EFL_UI_DIR_VERTICAL);
342
336 efl_gfx_hint_margin_set(layout, 10, 10, 20, 20); 343 efl_gfx_hint_margin_set(layout, 10, 10, 20, 20);
337 efl_ui_table_homogeneous_set(layout, 0, 1); 344 efl_ui_table_homogeneous_set(layout, 0, 1);
338 efl_pack_padding_set(layout, 10, 5, 0); 345 efl_pack_padding_set(layout, 10, 5, 0);
@@ -419,6 +426,143 @@ EFL_START_TEST (efl_ui_table_size)
419} 426}
420EFL_END_TEST 427EFL_END_TEST
421 428
429EFL_START_TEST (efl_ui_table_pack_table)
430{
431#define BTN_NUM 3
432 Eo *o, *btn[BTN_NUM];
433 Eina_Iterator *itr;
434 int i, cols, rows;
435
436 for (i = 0; i < BTN_NUM; i++)
437 btn[i] = efl_add(EFL_UI_BUTTON_CLASS, layout);
438
439 //pack test
440 ck_assert(efl_pack(layout, btn[0]));
441 ck_assert_ptr_eq(efl_pack_table_content_get(layout, 0, 0), btn[0]);
442 efl_pack_table_size_get(layout, &cols, &rows);
443 ck_assert_int_eq(cols, 1);
444 ck_assert_int_eq(rows, 1);
445
446 ck_assert(efl_pack_table(layout, btn[1], 6, 0, 1, 1));
447 ck_assert_ptr_eq(efl_pack_table_content_get(layout, 6, 0), btn[1]);
448 efl_pack_table_size_get(layout, &cols, &rows);
449 ck_assert_int_eq(cols, 7);
450 ck_assert_int_eq(rows, 1);
451
452 ck_assert(efl_pack(layout, btn[2]));
453 ck_assert_ptr_eq(efl_pack_table_content_get(layout, 7, 0), btn[2]);
454 efl_pack_table_size_get(layout, &cols, &rows);
455 ck_assert_int_eq(cols, 8);
456 ck_assert_int_eq(rows, 1);
457
458 ck_assert_int_eq(efl_content_count(layout), BTN_NUM);
459
460 i = 0;
461 itr = efl_content_iterate(layout);
462 EINA_ITERATOR_FOREACH(itr, o)
463 {
464 ck_assert_ptr_eq(o, btn[i++]);
465 }
466 eina_iterator_free(itr);
467
468 //unpack test
469 ck_assert(efl_pack_unpack(layout, btn[2]));
470 ck_assert(!efl_pack_unpack(layout, btn[2]));
471
472 efl_pack_unpack_all(layout);
473 ck_assert_int_eq(efl_content_count(layout), 0);
474 ck_assert(!efl_invalidated_get(btn[0]));
475
476 for (i = 0; i < BTN_NUM; i++)
477 efl_pack(layout, btn[i]);
478
479 efl_pack_clear(layout);
480 ck_assert_int_eq(efl_content_count(layout), 0);
481 ck_assert(efl_invalidated_get(btn[0]));
482#undef BTN_NUM
483}
484EFL_END_TEST
485
486EFL_START_TEST (efl_ui_table_properties)
487{
488 double h, v;
489 Eina_Bool b;
490 Eina_Bool homogeneoush, homogeneousv;
491 Efl_Ui_Dir dirh, dirv;
492
493 //align test
494 efl_pack_align_get(layout, &h, &v);
495 ck_assert(EINA_DBL_EQ(h, 0.5));
496 ck_assert(EINA_DBL_EQ(v, 0.5));
497
498 efl_pack_align_set(layout, 0.3, 0.8234);
499 efl_pack_align_get(layout, &h, &v);
500 ck_assert(EINA_DBL_EQ(h, 0.3));
501 ck_assert(EINA_DBL_EQ(v, 0.8234));
502
503 efl_pack_align_set(layout, -0.23, 123);
504 efl_pack_align_get(layout, &h, &v);
505 ck_assert(EINA_DBL_EQ(h, -1));
506 ck_assert(EINA_DBL_EQ(v, 1));
507
508 //padding test
509 efl_pack_padding_get(layout, &h, &v, &b);
510 ck_assert(EINA_DBL_EQ(h, 0.0));
511 ck_assert(EINA_DBL_EQ(v, 0.0));
512 ck_assert_int_eq(b, 0);
513
514 efl_pack_padding_set(layout, 0.3, 0.8234, 1);
515 efl_pack_padding_get(layout, &h, &v, &b);
516 ck_assert(EINA_DBL_EQ(h, 0.3));
517 ck_assert(EINA_DBL_EQ(v, 0.8234));
518 ck_assert_int_eq(b, 1);
519
520 efl_pack_padding_set(layout, -1.23, 123, 45);
521 efl_pack_padding_get(layout, &h, &v, &b);
522 ck_assert(EINA_DBL_EQ(h, 0));
523 ck_assert(EINA_DBL_EQ(v, 123));
524 ck_assert_int_eq(b, 1);
525
526 //direction test
527 efl_pack_table_direction_get(layout, &dirh, &dirv);
528 ck_assert_int_eq(dirh, EFL_UI_DIR_RIGHT);
529 ck_assert_int_eq(dirv, EFL_UI_DIR_DOWN);
530
531 efl_pack_table_direction_set(layout, EFL_UI_DIR_VERTICAL, EFL_UI_DIR_HORIZONTAL);
532 efl_pack_table_direction_get(layout, &dirh, &dirv);
533 ck_assert_int_eq(dirh, EFL_UI_DIR_VERTICAL);
534 ck_assert_int_eq(dirv, EFL_UI_DIR_HORIZONTAL);
535
536 efl_pack_table_direction_set(layout, EFL_UI_DIR_RIGHT, EFL_UI_DIR_RIGHT);
537 efl_pack_table_direction_get(layout, &dirh, &dirv);
538 ck_assert_int_eq(dirh, EFL_UI_DIR_RIGHT);
539 ck_assert_int_eq(dirv, EFL_UI_DIR_DOWN);
540
541 ck_assert_int_eq(efl_ui_direction_get(layout), EFL_UI_DIR_RIGHT);
542
543 efl_ui_direction_set(layout, EFL_UI_DIR_DEFAULT);
544 ck_assert_int_eq(efl_ui_direction_get(layout), EFL_UI_DIR_RIGHT);
545
546 efl_ui_direction_set(layout, EFL_UI_DIR_HORIZONTAL);
547 ck_assert_int_eq(efl_ui_direction_get(layout), EFL_UI_DIR_HORIZONTAL);
548
549 //homogeneous test
550 efl_ui_table_homogeneous_get(layout, &homogeneoush, &homogeneousv);
551 ck_assert_int_eq(homogeneoush, 0);
552 ck_assert_int_eq(homogeneousv, 0);
553
554 efl_ui_table_homogeneous_set(layout, 123, -123);
555 efl_ui_table_homogeneous_get(layout, &homogeneoush, &homogeneousv);
556 ck_assert_int_eq(homogeneoush, 1);
557 ck_assert_int_eq(homogeneousv, 1);
558
559 efl_ui_table_homogeneous_set(layout, 1, 0);
560 efl_ui_table_homogeneous_get(layout, &homogeneoush, &homogeneousv);
561 ck_assert_int_eq(homogeneoush, 1);
562 ck_assert_int_eq(homogeneousv, 0);
563}
564EFL_END_TEST
565
422void efl_ui_test_table(TCase *tc) 566void efl_ui_test_table(TCase *tc)
423{ 567{
424 tcase_add_checked_fixture(tc, layout_setup, layout_teardown); 568 tcase_add_checked_fixture(tc, layout_setup, layout_teardown);
@@ -427,4 +571,6 @@ void efl_ui_test_table(TCase *tc)
427 tcase_add_test(tc, efl_ui_table_layout_update); 571 tcase_add_test(tc, efl_ui_table_layout_update);
428 tcase_add_test(tc, efl_ui_table_layout_update_pack); 572 tcase_add_test(tc, efl_ui_table_layout_update_pack);
429 tcase_add_test(tc, efl_ui_table_layout_update_matrix); 573 tcase_add_test(tc, efl_ui_table_layout_update_matrix);
574 tcase_add_test(tc, efl_ui_table_pack_table);
575 tcase_add_test(tc, efl_ui_table_properties);
430} 576}