summaryrefslogtreecommitdiff
path: root/src/lib/evas/canvas/evas_object_table.c
diff options
context:
space:
mode:
authorVincent Torri <vincent.torri@gmail.com>2012-11-04 11:51:42 +0000
committerVincent Torri <vincent.torri@gmail.com>2012-11-04 11:51:42 +0000
commitc15e9c6575c3b5f39ded167dda5259de3de96151 (patch)
tree5115d7ae3620af24c2bc094cd062575af7adeda9 /src/lib/evas/canvas/evas_object_table.c
parenta5ac6a987caec5a7f7596a25d0a065b9cc94c50c (diff)
merge: and now Evas
I've tested make -j 3 install and it works nicely I've tested expedite with software and opengl xlib, and it works. Not tested other engines, so please report any problems (engines or other) on the ML. TODO: examples and tests, I'll add them later ISSUE: Eina_Unicode size check. It indirectly depends on eina_config.h, which is created at the end of the configure script. So its size is always 0. I don't know how that size is used, so I can't do a lot, for now. SVN revision: 78895
Diffstat (limited to 'src/lib/evas/canvas/evas_object_table.c')
-rw-r--r--src/lib/evas/canvas/evas_object_table.c1624
1 files changed, 1624 insertions, 0 deletions
diff --git a/src/lib/evas/canvas/evas_object_table.c b/src/lib/evas/canvas/evas_object_table.c
new file mode 100644
index 0000000..6bf5c47
--- /dev/null
+++ b/src/lib/evas/canvas/evas_object_table.c
@@ -0,0 +1,1624 @@
1#include "evas_common.h"
2#include "evas_private.h"
3#include <errno.h>
4
5#include <Eo.h>
6
7EAPI Eo_Op EVAS_OBJ_TABLE_BASE_ID = EO_NOOP;
8
9#define MY_CLASS EVAS_OBJ_TABLE_CLASS
10
11#define MY_CLASS_NAME "Evas_Object_Table"
12
13typedef struct _Evas_Object_Table_Data Evas_Object_Table_Data;
14typedef struct _Evas_Object_Table_Option Evas_Object_Table_Option;
15typedef struct _Evas_Object_Table_Cache Evas_Object_Table_Cache;
16typedef struct _Evas_Object_Table_Iterator Evas_Object_Table_Iterator;
17typedef struct _Evas_Object_Table_Accessor Evas_Object_Table_Accessor;
18
19struct _Evas_Object_Table_Option
20{
21 Evas_Object *obj;
22 unsigned short col, row, colspan, rowspan, end_col, end_row;
23 struct {
24 Evas_Coord w, h;
25 } min, max;
26 struct {
27 double h, v;
28 } align;
29 struct {
30 Evas_Coord l, r, t, b;
31 } pad;
32 Eina_Bool expand_h : 1; /* XXX required? */
33 Eina_Bool expand_v : 1; /* XXX required? */
34 Eina_Bool fill_h : 1;
35 Eina_Bool fill_v : 1;
36};
37
38struct _Evas_Object_Table_Cache
39{
40 struct {
41 struct {
42 double h, v;
43 } weights;
44 struct {
45 int h, v;
46 } expands;
47 struct {
48 Evas_Coord w, h;
49 } min;
50 } total;
51 struct {
52 double *h, *v;
53 } weights;
54 struct {
55 Evas_Coord *h, *v;
56 } sizes;
57 struct {
58 Eina_Bool *h, *v;
59 } expands;
60 double ___pad; // padding to make sure doubles at end can be aligned
61};
62
63struct _Evas_Object_Table_Data
64{
65 Eina_List *children;
66 struct {
67 Evas_Coord h, v;
68 } pad;
69 struct {
70 double h, v;
71 } align;
72 struct {
73 int cols, rows;
74 } size;
75 Evas_Object_Table_Cache *cache;
76 Evas_Object_Table_Homogeneous_Mode homogeneous;
77 Eina_Bool hints_changed : 1;
78 Eina_Bool expand_h : 1;
79 Eina_Bool expand_v : 1;
80 Eina_Bool is_mirrored : 1;
81};
82
83struct _Evas_Object_Table_Iterator
84{
85 Eina_Iterator iterator;
86
87 Eina_Iterator *real_iterator;
88 const Evas_Object *table;
89};
90
91struct _Evas_Object_Table_Accessor
92{
93 Eina_Accessor accessor;
94
95 Eina_Accessor *real_accessor;
96 const Evas_Object *table;
97};
98
99#define EVAS_OBJECT_TABLE_DATA_GET(o, ptr) \
100 Evas_Object_Table_Data *ptr = eo_data_get(o, MY_CLASS)
101
102#define EVAS_OBJECT_TABLE_DATA_GET_OR_RETURN(o, ptr) \
103 EVAS_OBJECT_TABLE_DATA_GET(o, ptr); \
104if (!ptr) \
105{ \
106 CRIT("no widget data for object %p (%s)", \
107 o, evas_object_type_get(o)); \
108 return; \
109}
110
111#define EVAS_OBJECT_TABLE_DATA_GET_OR_RETURN_VAL(o, ptr, val) \
112 EVAS_OBJECT_TABLE_DATA_GET(o, ptr); \
113if (!ptr) \
114{ \
115 CRIT("No widget data for object %p (%s)", \
116 o, evas_object_type_get(o)); \
117 return val; \
118}
119
120static const char EVAS_OBJECT_TABLE_OPTION_KEY[] = "|EvTb";
121
122static Eina_Bool
123_evas_object_table_iterator_next(Evas_Object_Table_Iterator *it, void **data)
124{
125 Evas_Object_Table_Option *opt;
126
127 if (!eina_iterator_next(it->real_iterator, (void **)&opt))
128 return EINA_FALSE;
129 if (data) *data = opt->obj;
130 return EINA_TRUE;
131}
132
133static Evas_Object *
134_evas_object_table_iterator_get_container(Evas_Object_Table_Iterator *it)
135{
136 return (Evas_Object *)it->table;
137}
138
139static void
140_evas_object_table_iterator_free(Evas_Object_Table_Iterator *it)
141{
142 eina_iterator_free(it->real_iterator);
143 free(it);
144}
145
146static Eina_Bool
147_evas_object_table_accessor_get_at(Evas_Object_Table_Accessor *it, unsigned int idx, void **data)
148{
149 Evas_Object_Table_Option *opt = NULL;
150
151 if (!eina_accessor_data_get(it->real_accessor, idx, (void **)&opt))
152 return EINA_FALSE;
153 if (data) *data = opt->obj;
154 return EINA_TRUE;
155}
156
157static Evas_Object *
158_evas_object_table_accessor_get_container(Evas_Object_Table_Accessor *it)
159{
160 return (Evas_Object *)it->table;
161}
162
163static void
164_evas_object_table_accessor_free(Evas_Object_Table_Accessor *it)
165{
166 eina_accessor_free(it->real_accessor);
167 free(it);
168}
169
170static Evas_Object_Table_Cache *
171_evas_object_table_cache_alloc(int cols, int rows)
172{
173 Evas_Object_Table_Cache *cache;
174 int size;
175
176 size = sizeof(Evas_Object_Table_Cache) +
177 ((cols + rows) *
178 (sizeof(double) + sizeof(Evas_Coord) + sizeof(Eina_Bool)));
179 cache = malloc(size);
180 if (!cache)
181 {
182 ERR("Could not allocate table cache %dx%d (%d bytes): %s",
183 cols, rows, size, strerror(errno));
184 return NULL;
185 }
186
187 cache->weights.h = (double *)(cache + 1);
188 cache->weights.v = (double *)(cache->weights.h + cols);
189 cache->sizes.h = (Evas_Coord *)(cache->weights.v + rows);
190 cache->sizes.v = (Evas_Coord *)(cache->sizes.h + cols);
191 cache->expands.h = (Eina_Bool *)(cache->sizes.v + rows);
192 cache->expands.v = (Eina_Bool *)(cache->expands.h + cols);
193
194 return cache;
195}
196
197static void
198_evas_object_table_cache_free(Evas_Object_Table_Cache *cache)
199{
200 free(cache);
201}
202
203static void
204_evas_object_table_cache_reset(Evas_Object_Table_Data *priv)
205{
206 Evas_Object_Table_Cache *c = priv->cache;
207 int size;
208
209 c->total.expands.v = 0;
210 c->total.expands.h = 0;
211 c->total.min.w = 0;
212 c->total.min.h = 0;
213
214 size = ((priv->size.rows + priv->size.cols) *
215 (sizeof(double) + sizeof(Evas_Coord) + sizeof(Eina_Bool)));
216 memset(c + 1, 0, size);
217}
218
219static void
220_evas_object_table_cache_invalidate(Evas_Object_Table_Data *priv)
221{
222 priv->hints_changed = 1;
223 if (priv->cache)
224 {
225 _evas_object_table_cache_free(priv->cache);
226 priv->cache = NULL;
227 }
228}
229
230static Evas_Object_Table_Option *
231_evas_object_table_option_get(Evas_Object *o)
232{
233 return evas_object_data_get(o, EVAS_OBJECT_TABLE_OPTION_KEY);
234}
235
236static void
237_evas_object_table_option_set(Evas_Object *o, const Evas_Object_Table_Option *opt)
238{
239 evas_object_data_set(o, EVAS_OBJECT_TABLE_OPTION_KEY, opt);
240}
241
242static Evas_Object_Table_Option *
243_evas_object_table_option_del(Evas_Object *o)
244{
245 return evas_object_data_del(o, EVAS_OBJECT_TABLE_OPTION_KEY);
246}
247
248static void
249_on_child_del(void *data, Evas *evas EINA_UNUSED, Evas_Object *child, void *einfo EINA_UNUSED)
250{
251 Evas_Object *table = data;
252 evas_object_table_unpack(table, child);
253}
254
255static void
256_on_child_hints_changed(void *data, Evas *evas EINA_UNUSED, Evas_Object *child EINA_UNUSED, void *einfo EINA_UNUSED)
257{
258 Evas_Object *table = data;
259 EVAS_OBJECT_TABLE_DATA_GET_OR_RETURN(table, priv);
260 _evas_object_table_cache_invalidate(priv);
261 evas_object_smart_changed(table);
262}
263
264static void
265_evas_object_table_child_connect(Evas_Object *o, Evas_Object *child)
266{
267 evas_object_event_callback_add
268 (child, EVAS_CALLBACK_DEL, _on_child_del, o);
269 evas_object_event_callback_add
270 (child, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _on_child_hints_changed, o);
271}
272
273static void
274_evas_object_table_child_disconnect(Evas_Object *o, Evas_Object *child)
275{
276 evas_object_event_callback_del_full
277 (child, EVAS_CALLBACK_DEL, _on_child_del, o);
278 evas_object_event_callback_del_full
279 (child, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _on_child_hints_changed, o);
280}
281
282static void
283_evas_object_table_calculate_cell(const Evas_Object_Table_Option *opt, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h)
284{
285 Evas_Coord cw, ch;
286
287 *w -= opt->pad.l + opt->pad.r;
288 if (*w < opt->min.w)
289 cw = opt->min.w;
290 else if ((opt->max.w > -1) && (*w > opt->max.w))
291 cw = opt->max.w;
292 else if (opt->fill_h)
293 cw = *w;
294 else
295 cw = opt->min.w;
296
297 *h -= opt->pad.t + opt->pad.b;
298 if (*h < opt->min.h)
299 ch = opt->min.h;
300 else if ((opt->max.h > -1) && (*h > opt->max.h))
301 ch = opt->max.h;
302 else if (opt->fill_v)
303 ch = *h;
304 else
305 ch = opt->min.h;
306
307 *x += opt->pad.l;
308 if (cw != *w)
309 {
310 *x += (*w - cw) * opt->align.h;
311 *w = cw;
312 }
313
314 *y += opt->pad.t;
315 if (ch != *h)
316 {
317 *y += (*h - ch) * opt->align.v;
318 *h = ch;
319 }
320}
321
322static void
323_evas_object_table_calculate_hints_homogeneous(Evas_Object *o, Evas_Object_Table_Data *priv)
324{
325 Eina_List *l;
326 Evas_Object_Table_Option *opt;
327 Evas_Coord minw, minh, o_minw, o_minh;
328 Eina_Bool expand_h, expand_v;
329
330 o_minw = 0;
331 o_minh = 0;
332 minw = 0;
333 minh = 0;
334 expand_h = 0;
335 expand_v = 0;
336
337 EINA_LIST_FOREACH(priv->children, l, opt)
338 {
339 Evas_Object *child = opt->obj;
340 Evas_Coord child_minw, child_minh, cell_minw, cell_minh;
341 double weightw, weighth;
342
343 evas_object_size_hint_min_get(child, &opt->min.w, &opt->min.h);
344 evas_object_size_hint_max_get(child, &opt->max.w, &opt->max.h);
345 evas_object_size_hint_padding_get
346 (child, &opt->pad.l, &opt->pad.r, &opt->pad.t, &opt->pad.b);
347 evas_object_size_hint_align_get(child, &opt->align.h, &opt->align.v);
348 evas_object_size_hint_weight_get(child, &weightw, &weighth);
349
350 child_minw = opt->min.w + opt->pad.l + opt->pad.r;
351 child_minh = opt->min.h + opt->pad.t + opt->pad.b;
352
353 cell_minw = (child_minw + opt->colspan - 1) / opt->colspan;
354 cell_minh = (child_minh + opt->rowspan - 1) / opt->rowspan;
355
356 opt->expand_h = 0;
357 if ((weightw > 0.0) &&
358 ((opt->max.w < 0) ||
359 ((opt->max.w > -1) && (opt->min.w < opt->max.w))))
360 {
361 opt->expand_h = 1;
362 expand_h = 1;
363 }
364
365 opt->expand_v = 0;
366 if ((weighth > 0.0) &&
367 ((opt->max.h < 0) ||
368 ((opt->max.h > -1) && (opt->min.h < opt->max.h))))
369 {
370 opt->expand_v = 1;
371 expand_v = 1;
372 }
373
374 opt->fill_h = 0;
375 if (opt->align.h < 0.0)
376 {
377 opt->align.h = 0.5;
378 opt->fill_h = 1;
379 }
380 opt->fill_v = 0;
381 if (opt->align.v < 0.0)
382 {
383 opt->align.v = 0.5;
384 opt->fill_v = 1;
385 }
386
387 /* greatest mininum values, with paddings */
388 if (minw < cell_minw)
389 minw = cell_minw;
390 if (minh < cell_minh)
391 minh = cell_minh;
392 /* greatest mininum values, without paddings */
393 if (o_minw < opt->min.w)
394 o_minw = opt->min.w;
395 if (o_minh < opt->min.h)
396 o_minh = opt->min.h;
397 }
398
399 if (priv->homogeneous == EVAS_OBJECT_TABLE_HOMOGENEOUS_ITEM)
400 {
401 if (o_minw < 1)
402 {
403 ERR("homogeneous table based on item size but no "
404 "horizontal mininum size specified! Using expand.");
405 expand_h = 1;
406 }
407 if (o_minh < 1)
408 {
409 ERR("homogeneous table based on item size but no "
410 "vertical mininum size specified! Using expand.");
411 expand_v = 1;
412 }
413 }
414
415 minw = priv->size.cols * (minw + priv->pad.h) - priv->pad.h;
416 minh = priv->size.rows * (minh + priv->pad.v) - priv->pad.v;
417
418 priv->hints_changed = 0;
419 priv->expand_h = expand_h;
420 priv->expand_v = expand_v;
421
422 if ((minw > 0 ) || (minh > 0))
423 evas_object_size_hint_min_set(o, minw, minh);
424
425 // XXX hint max?
426}
427
428static void
429_evas_object_table_calculate_layout_homogeneous_sizes_item(const Evas_Object *o, const Evas_Object_Table_Data *priv, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h)
430{
431 Evas_Coord minw, minh;
432 Eina_Bool expand_h, expand_v;
433
434 evas_object_size_hint_min_get(o, &minw, &minh);
435 expand_h = priv->expand_h;
436 expand_v = priv->expand_v;
437
438 if (*w < minw)
439 expand_h = 0;
440 if (!expand_h)
441 {
442 *x += (*w - minw) * priv->align.h;
443 *w = minw;
444 }
445
446 if (*h < minh)
447 expand_v = 0;
448 if (!expand_v)
449 {
450 *y += (*h - minh) * priv->align.v;
451 *h = minh;
452 }
453}
454
455static void
456_evas_object_table_calculate_layout_homogeneous_sizes(const Evas_Object *o, const Evas_Object_Table_Data *priv, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h, Evas_Coord *cellw, Evas_Coord *cellh)
457{
458 evas_object_geometry_get(o, x, y, w, h);
459 if (priv->homogeneous == EVAS_OBJECT_TABLE_HOMOGENEOUS_ITEM)
460 _evas_object_table_calculate_layout_homogeneous_sizes_item
461 (o, priv, x, y, w, h);
462
463 *cellw = (*w + priv->size.cols - 1) / priv->size.cols;
464 *cellh = (*h + priv->size.rows - 1) / priv->size.rows;
465}
466
467static void
468_evas_object_table_calculate_layout_homogeneous(Evas_Object *o, Evas_Object_Table_Data *priv)
469{
470 Evas_Coord x = 0, y = 0, w = 0, h = 0, ww, hh, cellw = 0, cellh = 0;
471 Eina_List *l;
472 Evas_Object_Table_Option *opt;
473
474 _evas_object_table_calculate_layout_homogeneous_sizes
475 (o, priv, &x, &y, &w, &h, &cellw, &cellh);
476
477 ww = w - ((priv->size.cols - 1) * priv->pad.h);
478 hh = h - ((priv->size.rows - 1) * priv->pad.v);
479
480 if (ww < 0) ww = 0;
481 if (ww < 0) ww = 0;
482
483 EINA_LIST_FOREACH(priv->children, l, opt)
484 {
485 Evas_Object *child = opt->obj;
486 Evas_Coord cx, cy, cw, ch, cox, coy, cow, coh;
487
488 cx = x + ((opt->col * ww) / priv->size.cols);
489 cw = x + (((opt->col + opt->colspan) * ww) / priv->size.cols) - cx;
490 cy = y + ((opt->row * hh) / priv->size.rows);
491 ch = y + (((opt->row + opt->rowspan) * hh) / priv->size.rows) - cy;
492
493 cx += (opt->col) * priv->pad.h;
494 cy += (opt->row) * priv->pad.v;
495
496 cox = cx;
497 coy = cy;
498 cow = cw;
499 coh = ch;
500
501 _evas_object_table_calculate_cell(opt, &cx, &cy, &cw, &ch);
502 if (cw > cow)
503 {
504 cx = cox;
505 cw = cow;
506 }
507 if (ch > coh)
508 {
509 cy = coy;
510 ch = coh;
511 }
512
513 if (priv->is_mirrored)
514 {
515 evas_object_move(opt->obj, x + w - (cx - x + cw), cy);
516 }
517 else
518 {
519 evas_object_move(child, cx, cy);
520 }
521 evas_object_resize(child, cw, ch);
522 }
523}
524
525static void
526_evas_object_table_smart_calculate_homogeneous(Evas_Object *o, Evas_Object_Table_Data *priv)
527{
528 if (priv->hints_changed)
529 _evas_object_table_calculate_hints_homogeneous(o, priv);
530 _evas_object_table_calculate_layout_homogeneous(o, priv);
531}
532
533static int
534_evas_object_table_count_expands(const Eina_Bool *expands, int start, int end)
535{
536 const Eina_Bool *itr = expands + start, *itr_end = expands + end;
537 int count = 0;
538
539 for (; itr < itr_end; itr++)
540 {
541 if (*itr)
542 count++;
543 }
544
545 return count;
546}
547
548static Evas_Coord
549_evas_object_table_sum_sizes(const Evas_Coord *sizes, int start, int end)
550{
551 const Evas_Coord *itr = sizes + start, *itr_end = sizes + end;
552 Evas_Coord sum = 0;
553
554 for (; itr < itr_end; itr++)
555 sum += *itr;
556
557 return sum;
558}
559
560static void
561_evas_object_table_sizes_calc_noexpand(Evas_Coord *sizes, int start, int end, Evas_Coord space)
562{
563 Evas_Coord *itr = sizes + start, *itr_end = sizes + end - 1;
564 Evas_Coord step;
565 int units;
566
567 /* XXX move to fixed point math and spread errors among cells */
568 units = end - start;
569 step = space / units;
570 for (; itr < itr_end; itr++)
571 *itr += step;
572
573 *itr += space - step * (units - 1);
574}
575
576static void
577_evas_object_table_sizes_calc_expand(Evas_Coord *sizes, int start, int end, Evas_Coord space, const Eina_Bool *expands, int expand_count, double *weights, double weighttot)
578{
579 Evas_Coord *itr = sizes + start, *itr_end = sizes + end;
580 const Eina_Bool *itr_expand = expands + start;
581 Evas_Coord step = 0, last_space = 0;
582 int total = 0, i = start;
583
584 /* XXX move to fixed point math and spread errors among cells */
585 if (weighttot > 0.0)
586 {
587 step = space / expand_count;
588 last_space = space - step * (expand_count - 1);
589 }
590
591 for (; itr < itr_end; itr++, itr_expand++, i++)
592 {
593 if (weighttot <= 0.0)
594 {
595 if (*itr_expand)
596 {
597 expand_count--;
598 if (expand_count > 0)
599 *itr += step;
600 else
601 {
602 *itr += last_space;
603 break;
604 }
605 }
606 }
607 else
608 {
609 if (*itr_expand)
610 {
611 expand_count--;
612 if (expand_count > 0)
613 {
614 step = (weights[i] / weighttot) * space;
615 *itr += step;
616 total += step;
617 }
618 else
619 {
620 *itr += space - total;
621 break;
622 }
623 }
624 }
625 }
626}
627
628static void
629_evas_object_table_calculate_hints_regular(Evas_Object *o, Evas_Object_Table_Data *priv)
630{
631 Evas_Object_Table_Option *opt;
632 Evas_Object_Table_Cache *c;
633 Eina_List *l;
634 double totweightw = 0.0, totweighth = 0.0;
635 int i;
636
637 if (!priv->cache)
638 {
639 priv->cache = _evas_object_table_cache_alloc
640 (priv->size.cols, priv->size.rows);
641 if (!priv->cache)
642 return;
643 }
644 c = priv->cache;
645 _evas_object_table_cache_reset(priv);
646
647 /* cache interesting data */
648 memset(c->expands.h, 1, priv->size.cols);
649 memset(c->expands.v, 1, priv->size.rows);
650 memset(c->weights.h, 0, priv->size.cols);
651 memset(c->weights.v, 0, priv->size.rows);
652 EINA_LIST_FOREACH(priv->children, l, opt)
653 {
654 Evas_Object *child = opt->obj;
655 double weightw, weighth;
656
657 evas_object_size_hint_min_get(child, &opt->min.w, &opt->min.h);
658 evas_object_size_hint_max_get(child, &opt->max.w, &opt->max.h);
659 evas_object_size_hint_padding_get
660 (child, &opt->pad.l, &opt->pad.r, &opt->pad.t, &opt->pad.b);
661 evas_object_size_hint_align_get(child, &opt->align.h, &opt->align.v);
662 evas_object_size_hint_weight_get(child, &weightw, &weighth);
663
664 opt->expand_h = 0;
665 if ((weightw > 0.0) &&
666 ((opt->max.w < 0) ||
667 ((opt->max.w > -1) && (opt->min.w < opt->max.w))))
668 opt->expand_h = 1;
669
670 opt->expand_v = 0;
671 if ((weighth > 0.0) &&
672 ((opt->max.h < 0) ||
673 ((opt->max.h > -1) && (opt->min.h < opt->max.h))))
674 opt->expand_v = 1;
675
676 opt->fill_h = 0;
677 if (opt->align.h < 0.0)
678 {
679 opt->align.h = 0.5;
680 opt->fill_h = 1;
681 }
682 opt->fill_v = 0;
683 if (opt->align.v < 0.0)
684 {
685 opt->align.v = 0.5;
686 opt->fill_v = 1;
687 }
688
689 if (!opt->expand_h)
690 memset(c->expands.h + opt->col, 0, opt->colspan);
691 else
692 {
693 for (i = opt->col; i < opt->col + opt->colspan; i++)
694 c->weights.h[i] += (weightw / (double)opt->colspan);
695 }
696 if (!opt->expand_v)
697 memset(c->expands.v + opt->row, 0, opt->rowspan);
698 else
699 {
700 for (i = opt->row; i < opt->row + opt->rowspan; i++)
701 c->weights.v[i] += (weighth / (double)opt->rowspan);
702 }
703 }
704 for (i = 0; i < priv->size.cols; i++) totweightw += c->weights.h[i];
705 for (i = 0; i < priv->size.rows; i++) totweighth += c->weights.v[i];
706
707 /* calculate sizes for each row and column */
708 EINA_LIST_FOREACH(priv->children, l, opt)
709 {
710 Evas_Coord tot, need;
711
712 /* handle horizontal */
713 tot = _evas_object_table_sum_sizes(c->sizes.h, opt->col, opt->end_col);
714 need = opt->min.w + opt->pad.l + opt->pad.r;
715 if (tot < need)
716 {
717 Evas_Coord space = need - tot;
718 int count;
719
720 count = _evas_object_table_count_expands
721 (c->expands.h, opt->col, opt->end_col);
722
723 if (count > 0)
724 _evas_object_table_sizes_calc_expand
725 (c->sizes.h, opt->col, opt->end_col, space,
726 c->expands.h, count, c->weights.h, totweightw);
727 else
728 _evas_object_table_sizes_calc_noexpand
729 (c->sizes.h, opt->col, opt->end_col, space);
730 }
731
732 /* handle vertical */
733 tot = _evas_object_table_sum_sizes(c->sizes.v, opt->row, opt->end_row);
734 need = opt->min.h + opt->pad.t + opt->pad.b;
735 if (tot < opt->min.h)
736 {
737 Evas_Coord space = need - tot;
738 int count;
739
740 count = _evas_object_table_count_expands
741 (c->expands.v, opt->row, opt->end_row);
742
743 if (count > 0)
744 _evas_object_table_sizes_calc_expand
745 (c->sizes.v, opt->row, opt->end_row, space,
746 c->expands.v, count, c->weights.v, totweighth);
747 else
748 _evas_object_table_sizes_calc_noexpand
749 (c->sizes.v, opt->row, opt->end_row, space);
750 }
751 }
752
753 c->total.weights.h = totweightw;
754 c->total.weights.v = totweighth;
755
756 c->total.expands.h = _evas_object_table_count_expands
757 (c->expands.h, 0, priv->size.cols);
758 c->total.expands.v = _evas_object_table_count_expands
759 (c->expands.v, 0, priv->size.rows);
760
761 c->total.min.w = _evas_object_table_sum_sizes
762 (c->sizes.h, 0, priv->size.cols);
763 c->total.min.h = _evas_object_table_sum_sizes
764 (c->sizes.v, 0, priv->size.rows);
765
766 c->total.min.w += priv->pad.h * (priv->size.cols - 1);
767 c->total.min.h += priv->pad.v * (priv->size.rows - 1);
768
769 if ((c->total.min.w > 0) || (c->total.min.h > 0))
770 evas_object_size_hint_min_set(o, c->total.min.w, c->total.min.h);
771
772 // XXX hint max?
773}
774
775static void
776_evas_object_table_calculate_layout_regular(Evas_Object *o, Evas_Object_Table_Data *priv)
777{
778 Evas_Object_Table_Option *opt;
779 Evas_Object_Table_Cache *c;
780 Eina_List *l;
781 Evas_Coord *cols = NULL, *rows = NULL;
782 Evas_Coord x, y, w, h;
783
784 evas_object_geometry_get(o, &x, &y, &w, &h);
785 c = priv->cache;
786
787 /* handle horizontal */
788 if ((c->total.expands.h <= 0) || (c->total.min.w >= w))
789 {
790 x += (w - c->total.min.w) * priv->align.h;
791 w = c->total.min.w;
792 cols = c->sizes.h;
793 }
794 else
795 {
796 int size = priv->size.cols * sizeof(Evas_Coord);
797 cols = malloc(size);
798 if (!cols)
799 {
800 ERR("Could not allocate temp columns (%d bytes): %s",
801 size, strerror(errno));
802 goto end;
803 }
804 memcpy(cols, c->sizes.h, size);
805 _evas_object_table_sizes_calc_expand
806 (cols, 0, priv->size.cols, w - c->total.min.w,
807 c->expands.h, c->total.expands.h, c->weights.h, c->total.weights.h);
808 }
809
810 /* handle vertical */
811 if ((c->total.expands.v <= 0) || (c->total.min.h >= h))
812 {
813 y += (h - c->total.min.h) * priv->align.v;
814 h = c->total.min.h;
815 rows = c->sizes.v;
816 }
817 else
818 {
819 int size = priv->size.rows * sizeof(Evas_Coord);
820 rows = malloc(size);
821 if (!rows)
822 {
823 ERR("could not allocate temp rows (%d bytes): %s",
824 size, strerror(errno));
825 goto end;
826 }
827 memcpy(rows, c->sizes.v, size);
828 _evas_object_table_sizes_calc_expand
829 (rows, 0, priv->size.rows, h - c->total.min.h,
830 c->expands.v, c->total.expands.v, c->weights.v, c->total.weights.v);
831 }
832
833 EINA_LIST_FOREACH(priv->children, l, opt)
834 {
835 Evas_Object *child = opt->obj;
836 Evas_Coord cx, cy, cw, ch;
837
838 cx = x + opt->col * (priv->pad.h);
839 cx += _evas_object_table_sum_sizes(cols, 0, opt->col);
840 cw = _evas_object_table_sum_sizes(cols, opt->col, opt->end_col);
841
842 cy = y + opt->row * (priv->pad.v);
843 cy += _evas_object_table_sum_sizes(rows, 0, opt->row);
844 ch = _evas_object_table_sum_sizes(rows, opt->row, opt->end_row);
845
846 _evas_object_table_calculate_cell(opt, &cx, &cy, &cw, &ch);
847
848 if (priv->is_mirrored)
849 {
850 evas_object_move(opt->obj, x + w - (cx - x + cw), cy);
851 }
852 else
853 {
854 evas_object_move(child, cx, cy);
855 }
856 evas_object_resize(child, cw, ch);
857 }
858
859 end:
860 if (cols != c->sizes.h)
861 {
862 if (cols) free(cols);
863 }
864 if (rows != c->sizes.v)
865 {
866 if (rows) free(rows);
867 }
868}
869
870static void
871_evas_object_table_smart_calculate_regular(Evas_Object *o, Evas_Object_Table_Data *priv)
872{
873 if (priv->hints_changed)
874 _evas_object_table_calculate_hints_regular(o, priv);
875 _evas_object_table_calculate_layout_regular(o, priv);
876}
877
878static void
879_smart_add(Eo *obj, void *_pd, va_list *list EINA_UNUSED)
880{
881 Evas_Object_Table_Data *priv = _pd;
882 priv->pad.h = 0;
883 priv->pad.v = 0;
884 priv->align.h = 0.5;
885 priv->align.v = 0.5;
886 priv->size.cols = 0;
887 priv->size.rows = 0;
888 priv->cache = NULL;
889 priv->homogeneous = EVAS_OBJECT_TABLE_HOMOGENEOUS_NONE;
890 priv->hints_changed = 1;
891 priv->expand_h = 0;
892 priv->expand_v = 0;
893
894 eo_do_super(obj, evas_obj_smart_add());
895}
896
897static void
898_smart_del(Eo *obj, void *_pd, va_list *list EINA_UNUSED)
899{
900 Evas_Object_Table_Data *priv = _pd;
901 Eina_List *l;
902
903 l = priv->children;
904 while (l)
905 {
906 Evas_Object_Table_Option *opt = l->data;
907 _evas_object_table_child_disconnect(obj, opt->obj);
908 _evas_object_table_option_del(opt->obj);
909 free(opt);
910 l = eina_list_remove_list(l, l);
911 }
912
913 if (priv->cache)
914 {
915 _evas_object_table_cache_free(priv->cache);
916 priv->cache = NULL;
917 }
918
919 eo_do_super(obj, evas_obj_smart_del());
920}
921
922static void
923_smart_resize(Eo *obj, void *_pd EINA_UNUSED, va_list *list)
924{
925 Evas_Coord w = va_arg(*list, Evas_Coord);
926 Evas_Coord h = va_arg(*list, Evas_Coord);
927 Evas_Coord ow, oh;
928 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
929 if ((ow == w) && (oh == h)) return;
930 evas_object_smart_changed(obj);
931}
932
933static void
934_smart_calculate(Eo *o, void *_pd, va_list *list EINA_UNUSED)
935{
936 Evas_Object_Table_Data *priv = _pd;
937
938 if ((priv->size.cols < 1) || (priv->size.rows < 1))
939 {
940 DBG("Nothing to do: cols=%d, rows=%d",
941 priv->size.cols, priv->size.rows);
942 return;
943 }
944
945 if (priv->homogeneous)
946 _evas_object_table_smart_calculate_homogeneous(o, priv);
947 else
948 _evas_object_table_smart_calculate_regular(o, priv);
949}
950
951EAPI Evas_Object *
952evas_object_table_add(Evas *evas)
953{
954 Evas_Object *obj = eo_add(MY_CLASS, evas);
955 eo_unref(obj);
956 return obj;
957}
958
959static void
960_constructor(Eo *obj, void *class_data EINA_UNUSED, va_list *list EINA_UNUSED)
961{
962 eo_do_super(obj, eo_constructor());
963 eo_do(obj, evas_obj_type_set(MY_CLASS_NAME));
964}
965
966EAPI Evas_Object *
967evas_object_table_add_to(Evas_Object *parent)
968{
969 Evas_Object *ret = NULL;
970 eo_do(parent, evas_obj_table_add_to(&ret));
971 return ret;
972}
973
974static void
975_add_to(Eo *parent, void *_pd EINA_UNUSED, va_list *list)
976{
977 Evas_Object **ret = va_arg(*list, Evas_Object **);
978 Evas *evas;
979
980 evas = evas_object_evas_get(parent);
981 *ret = evas_object_table_add(evas);
982 evas_object_smart_member_add(*ret, parent);
983}
984
985EAPI void
986evas_object_table_homogeneous_set(Evas_Object *o, Evas_Object_Table_Homogeneous_Mode homogeneous)
987{
988 eo_do(o, evas_obj_table_homogeneous_set(homogeneous));
989}
990
991static void
992_homogeneous_set(Eo *o, void *_pd, va_list *list)
993{
994 Evas_Object_Table_Homogeneous_Mode homogeneous = va_arg(*list, Evas_Object_Table_Homogeneous_Mode);
995
996 Evas_Object_Table_Data *priv = _pd;
997 if (priv->homogeneous == homogeneous)
998 return;
999 priv->homogeneous = homogeneous;
1000 _evas_object_table_cache_invalidate(priv);
1001 evas_object_smart_changed(o);
1002}
1003
1004EAPI Evas_Object_Table_Homogeneous_Mode
1005evas_object_table_homogeneous_get(const Evas_Object *o)
1006{
1007 Evas_Object_Table_Homogeneous_Mode ret = EVAS_OBJECT_TABLE_HOMOGENEOUS_NONE;
1008 eo_do((Eo *)o, evas_obj_table_homogeneous_get(&ret));
1009 return ret;
1010}
1011
1012static void
1013_homogeneous_get(Eo *o EINA_UNUSED, void *_pd, va_list *list)
1014{
1015 Evas_Object_Table_Homogeneous_Mode *ret = va_arg(*list, Evas_Object_Table_Homogeneous_Mode *);
1016 const Evas_Object_Table_Data *priv = _pd;
1017 *ret = priv->homogeneous;
1018}
1019
1020EAPI void
1021evas_object_table_align_set(Evas_Object *o, double horizontal, double vertical)
1022{
1023 eo_do(o, evas_obj_table_align_set(horizontal, vertical));
1024}
1025
1026static void
1027_align_set(Eo *o, void *_pd, va_list *list)
1028{
1029 double horizontal = va_arg(*list, double);
1030 double vertical = va_arg(*list, double);
1031
1032 Evas_Object_Table_Data *priv = _pd;
1033 if (priv->align.h == horizontal && priv->align.v == vertical)
1034 return;
1035 priv->align.h = horizontal;
1036 priv->align.v = vertical;
1037 evas_object_smart_changed(o);
1038}
1039
1040EAPI void
1041evas_object_table_align_get(const Evas_Object *o, double *horizontal, double *vertical)
1042{
1043 eo_do((Eo *)o, evas_obj_table_align_get(horizontal, vertical));
1044}
1045
1046static void
1047_align_get(Eo *o EINA_UNUSED, void *_pd, va_list *list)
1048{
1049 double *horizontal = va_arg(*list, double *);
1050 double *vertical = va_arg(*list, double *);
1051
1052 const Evas_Object_Table_Data *priv = _pd;
1053 if (priv)
1054 {
1055 if (horizontal) *horizontal = priv->align.h;
1056 if (vertical) *vertical = priv->align.v;
1057 }
1058 else
1059 {
1060 if (horizontal) *horizontal = 0.5;
1061 if (vertical) *vertical = 0.5;
1062 }
1063}
1064
1065EAPI void
1066evas_object_table_padding_set(Evas_Object *o, Evas_Coord horizontal, Evas_Coord vertical)
1067{
1068 eo_do(o, evas_obj_table_padding_set(horizontal, vertical));
1069}
1070
1071static void
1072_padding_set(Eo *o, void *_pd, va_list *list)
1073{
1074 Evas_Coord horizontal = va_arg(*list, Evas_Coord);
1075 Evas_Coord vertical = va_arg(*list, Evas_Coord);
1076
1077 Evas_Object_Table_Data *priv = _pd;
1078 if (priv->pad.h == horizontal && priv->pad.v == vertical)
1079 return;
1080 priv->pad.h = horizontal;
1081 priv->pad.v = vertical;
1082 _evas_object_table_cache_invalidate(priv);
1083 evas_object_smart_changed(o);
1084}
1085
1086EAPI void
1087evas_object_table_padding_get(const Evas_Object *o, Evas_Coord *horizontal, Evas_Coord *vertical)
1088{
1089 eo_do((Eo *)o, evas_obj_table_padding_get(horizontal, vertical));
1090}
1091
1092static void
1093_padding_get(Eo *o EINA_UNUSED, void *_pd, va_list *list)
1094{
1095 Evas_Coord *horizontal = va_arg(*list, Evas_Coord *);
1096 Evas_Coord *vertical = va_arg(*list, Evas_Coord *);
1097
1098 const Evas_Object_Table_Data *priv = _pd;
1099 if (priv)
1100 {
1101 if (horizontal) *horizontal = priv->pad.h;
1102 if (vertical) *vertical = priv->pad.v;
1103 }
1104 else
1105 {
1106 if (horizontal) *horizontal = 0;
1107 if (vertical) *vertical = 0;
1108 }
1109}
1110
1111EAPI Eina_Bool
1112evas_object_table_pack_get(const Evas_Object *o, Evas_Object *child, unsigned short *col, unsigned short *row, unsigned short *colspan, unsigned short *rowspan)
1113{
1114 Eina_Bool ret = EINA_FALSE;
1115 eo_do((Eo *)o, evas_obj_table_pack_get(child, col, row, colspan, rowspan, &ret));
1116 return ret;
1117}
1118
1119static void
1120_pack_get(Eo *o EINA_UNUSED, void *_pd EINA_UNUSED, va_list *list)
1121{
1122 Evas_Object *child = va_arg(*list, Evas_Object *);
1123 unsigned short *col = va_arg(*list, unsigned short *);
1124 unsigned short *row = va_arg(*list, unsigned short *);
1125 unsigned short *colspan = va_arg(*list, unsigned short *);
1126 unsigned short *rowspan = va_arg(*list, unsigned short *);
1127 Eina_Bool *ret = va_arg(*list, Eina_Bool *);
1128 if (ret) *ret = EINA_FALSE;
1129
1130 Evas_Object_Table_Option *opt;
1131
1132 opt = _evas_object_table_option_get(child);
1133 if (!opt)
1134 {
1135 if (col) *col = 0;
1136 if (row) *row = 0;
1137 if (colspan) *colspan = 0;
1138 if (rowspan) *rowspan = 0;
1139 return;
1140 }
1141 if (col) *col = opt->col;
1142 if (row) *row = opt->row;
1143 if (colspan) *colspan = opt->colspan;
1144 if (rowspan) *rowspan = opt->rowspan;
1145 if (ret) *ret = EINA_TRUE;
1146}
1147
1148EAPI Eina_Bool
1149evas_object_table_pack(Evas_Object *o, Evas_Object *child, unsigned short col, unsigned short row, unsigned short colspan, unsigned short rowspan)
1150{
1151 Eina_Bool ret = EINA_FALSE;
1152 eo_do(o, evas_obj_table_pack(child, col, row, colspan, rowspan, &ret));
1153 return ret;
1154}
1155
1156static void
1157_pack(Eo *o, void *_pd, va_list *list)
1158{
1159 Evas_Object *child = va_arg(*list, Evas_Object *);
1160 unsigned short col = va_arg(*list, int);
1161 unsigned short row = va_arg(*list, int);
1162 unsigned short colspan = va_arg(*list, int);
1163 unsigned short rowspan = va_arg(*list, int);
1164 Eina_Bool *ret = va_arg(*list, Eina_Bool *);
1165 if (ret) *ret = EINA_FALSE;
1166
1167 Evas_Object_Table_Option *opt;
1168
1169 Evas_Object_Table_Data *priv = _pd;
1170
1171 if (rowspan < 1)
1172 {
1173 ERR("rowspan < 1");
1174 return;
1175 }
1176 if (colspan < 1)
1177 {
1178 ERR("colspan < 1");
1179 return;
1180 }
1181
1182 opt = _evas_object_table_option_get(child);
1183 if (!opt)
1184 {
1185 opt = malloc(sizeof(*opt));
1186 if (!opt)
1187 {
1188 ERR("could not allocate table option data.");
1189 return;
1190 }
1191 }
1192
1193 opt->obj = child;
1194 opt->col = col;
1195 opt->row = row;
1196 opt->colspan = colspan;
1197 opt->rowspan = rowspan;
1198 opt->end_col = col + colspan;
1199 opt->end_row = row + rowspan;
1200
1201 if (evas_object_smart_parent_get(child) == o)
1202 {
1203 Eina_Bool need_shrink = EINA_FALSE;
1204
1205 if (priv->size.cols < opt->end_col)
1206 priv->size.cols = opt->end_col;
1207 else
1208 need_shrink = EINA_TRUE;
1209 if (priv->size.rows < opt->end_row)
1210 priv->size.rows = opt->end_row;
1211 else
1212 need_shrink = EINA_TRUE;
1213
1214 if (need_shrink)
1215 {
1216 Eina_List *l;
1217 Evas_Object_Table_Option *opt2;
1218 int max_row = 0, max_col = 0;
1219
1220 EINA_LIST_FOREACH(priv->children, l, opt2)
1221 {
1222 if (max_col < opt2->end_col) max_col = opt2->end_col;
1223 if (max_row < opt2->end_row) max_row = opt2->end_row;
1224 }
1225 priv->size.cols = max_col;
1226 priv->size.rows = max_row;
1227 }
1228 }
1229 else
1230 {
1231 opt->min.w = 0;
1232 opt->min.h = 0;
1233 opt->max.w = 0;
1234 opt->max.h = 0;
1235 opt->align.h = 0.5;
1236 opt->align.v = 0.5;
1237 opt->pad.l = 0;
1238 opt->pad.r = 0;
1239 opt->pad.t = 0;
1240 opt->pad.b = 0;
1241 opt->expand_h = 0;
1242 opt->expand_v = 0;
1243
1244 priv->children = eina_list_append(priv->children, opt);
1245
1246 if (priv->size.cols < opt->end_col)
1247 priv->size.cols = opt->end_col;
1248 if (priv->size.rows < opt->end_row)
1249 priv->size.rows = opt->end_row;
1250
1251 _evas_object_table_option_set(child, opt);
1252 evas_object_smart_member_add(child, o);
1253 _evas_object_table_child_connect(o, child);
1254 }
1255 _evas_object_table_cache_invalidate(priv);
1256 evas_object_smart_changed(o);
1257 if (ret) *ret = EINA_TRUE;
1258}
1259
1260static void
1261_evas_object_table_remove_opt(Evas_Object_Table_Data *priv, Evas_Object_Table_Option *opt)
1262{
1263 Eina_List *l;
1264 int max_row, max_col, was_greatest;
1265
1266 max_row = 0;
1267 max_col = 0;
1268 was_greatest = 0;
1269 l = priv->children;
1270 while (l)
1271 {
1272 Evas_Object_Table_Option *cur_opt = l->data;
1273
1274 if (cur_opt != opt)
1275 {
1276 if (max_col < cur_opt->end_col)
1277 max_col = cur_opt->end_col;
1278 if (max_row < cur_opt->end_row)
1279 max_row = cur_opt->end_row;
1280
1281 l = l->next;
1282 }
1283 else
1284 {
1285 Eina_List *tmp = l->next;
1286 priv->children = eina_list_remove_list(priv->children, l);
1287
1288 if ((priv->size.cols > opt->end_col) &&
1289 (priv->size.rows > opt->end_row))
1290 break;
1291 else
1292 {
1293 was_greatest = 1;
1294 l = tmp;
1295 }
1296 }
1297 }
1298
1299 if (was_greatest)
1300 {
1301 priv->size.cols = max_col;
1302 priv->size.rows = max_row;
1303 }
1304}
1305
1306EAPI Eina_Bool
1307evas_object_table_unpack(Evas_Object *o, Evas_Object *child)
1308{
1309 Eina_Bool ret = EINA_FALSE;
1310 eo_do(o, evas_obj_table_unpack(child, &ret));
1311 return ret;
1312}
1313
1314static void
1315_unpack(Eo *o, void *_pd, va_list *list)
1316{
1317 Evas_Object *child = va_arg(*list, Evas_Object *);
1318 Eina_Bool *ret = va_arg(*list, Eina_Bool *);
1319 if (ret) *ret = EINA_FALSE;
1320
1321 Evas_Object_Table_Option *opt;
1322
1323 Evas_Object_Table_Data *priv = _pd;
1324
1325 if (o != evas_object_smart_parent_get(child))
1326 {
1327 ERR("cannot unpack child from incorrect table!");
1328 return;
1329 }
1330
1331 opt = _evas_object_table_option_del(child);
1332 if (!opt)
1333 {
1334 ERR("cannot unpack child with no packing option!");
1335 return;
1336 }
1337
1338 _evas_object_table_child_disconnect(o, child);
1339 _evas_object_table_remove_opt(priv, opt);
1340 evas_object_smart_member_del(child);
1341 free(opt);
1342 _evas_object_table_cache_invalidate(priv);
1343 evas_object_smart_changed(o);
1344
1345 if (ret) *ret = EINA_TRUE;
1346}
1347
1348EAPI void
1349evas_object_table_clear(Evas_Object *o, Eina_Bool clear)
1350{
1351 eo_do(o, evas_obj_table_clear(clear));
1352}
1353
1354static void
1355_clear(Eo *o, void *_pd, va_list *list)
1356{
1357 Eina_Bool clear = va_arg(*list, int);
1358
1359 Evas_Object_Table_Option *opt;
1360
1361 Evas_Object_Table_Data *priv = _pd;
1362
1363 EINA_LIST_FREE(priv->children, opt)
1364 {
1365 _evas_object_table_child_disconnect(o, opt->obj);
1366 _evas_object_table_option_del(opt->obj);
1367 evas_object_smart_member_del(opt->obj);
1368 if (clear)
1369 evas_object_del(opt->obj);
1370 free(opt);
1371 }
1372 priv->size.cols = 0;
1373 priv->size.rows = 0;
1374 _evas_object_table_cache_invalidate(priv);
1375 evas_object_smart_changed(o);
1376}
1377
1378EAPI void
1379evas_object_table_col_row_size_get(const Evas_Object *o, int *cols, int *rows)
1380{
1381 eo_do((Eo *)o, evas_obj_table_col_row_size_get(cols, rows));
1382}
1383
1384static void
1385_col_row_size_get(Eo *o EINA_UNUSED, void *_pd, va_list *list)
1386{
1387 int *cols = va_arg(*list, int *);
1388 int *rows = va_arg(*list, int *);
1389
1390 const Evas_Object_Table_Data *priv = _pd;
1391 if (priv)
1392 {
1393 if (cols) *cols = priv->size.cols;
1394 if (rows) *rows = priv->size.rows;
1395 }
1396 else
1397 {
1398 if (cols) *cols = -1;
1399 if (rows) *rows = -1;
1400 }
1401}
1402
1403EAPI Eina_Iterator *
1404evas_object_table_iterator_new(const Evas_Object *o)
1405{
1406 Eina_Iterator *ret = NULL;
1407 eo_do((Eo *)o, evas_obj_table_iterator_new(&ret));
1408 return ret;
1409}
1410
1411static void
1412_iterator_new(Eo *o, void *_pd, va_list *list)
1413{
1414 Eina_Iterator **ret = va_arg(*list, Eina_Iterator **);
1415
1416 Evas_Object_Table_Iterator *it;
1417
1418 const Evas_Object_Table_Data *priv = _pd;
1419
1420 if (!priv->children)
1421 {
1422 *ret = NULL;
1423 return;
1424 }
1425
1426 it = calloc(1, sizeof(Evas_Object_Table_Iterator));
1427 if (!it)
1428 {
1429 *ret = NULL;
1430 return;
1431 }
1432
1433 EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR);
1434
1435 it->real_iterator = eina_list_iterator_new(priv->children);
1436 it->table = o;
1437
1438 it->iterator.next = FUNC_ITERATOR_NEXT(_evas_object_table_iterator_next);
1439 it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(_evas_object_table_iterator_get_container);
1440 it->iterator.free = FUNC_ITERATOR_FREE(_evas_object_table_iterator_free);
1441
1442 *ret = &it->iterator;
1443}
1444
1445EAPI Eina_Accessor *
1446evas_object_table_accessor_new(const Evas_Object *o)
1447{
1448 Eina_Accessor *ret = NULL;
1449 eo_do((Eo *)o, evas_obj_table_accessor_new(&ret));
1450 return ret;
1451}
1452
1453static void
1454_accessor_new(Eo *o, void *_pd, va_list *list)
1455{
1456 Eina_Accessor **ret = va_arg(*list, Eina_Accessor **);
1457
1458 Evas_Object_Table_Accessor *it;
1459
1460 const Evas_Object_Table_Data *priv = _pd;
1461
1462 if (!priv->children)
1463 {
1464 *ret = NULL;
1465 return;
1466 }
1467
1468 it = calloc(1, sizeof(Evas_Object_Table_Accessor));
1469 if (!it)
1470 {
1471 *ret = NULL;
1472 return;
1473 }
1474
1475 EINA_MAGIC_SET(&it->accessor, EINA_MAGIC_ACCESSOR);
1476
1477 it->real_accessor = eina_list_accessor_new(priv->children);
1478 it->table = o;
1479
1480 it->accessor.get_at = FUNC_ACCESSOR_GET_AT(_evas_object_table_accessor_get_at);
1481 it->accessor.get_container = FUNC_ACCESSOR_GET_CONTAINER(_evas_object_table_accessor_get_container);
1482 it->accessor.free = FUNC_ACCESSOR_FREE(_evas_object_table_accessor_free);
1483
1484 *ret = &it->accessor;
1485}
1486
1487EAPI Eina_List *
1488evas_object_table_children_get(const Evas_Object *o)
1489{
1490 Eina_List *ret = NULL;
1491 eo_do((Eo *)o, evas_obj_table_children_get(&ret));
1492 return ret;
1493}
1494
1495static void
1496_children_get(Eo *o EINA_UNUSED, void *_pd, va_list *list)
1497{
1498 Eina_List **ret = va_arg(*list, Eina_List **);
1499
1500 Eina_List *new_list = NULL, *l;
1501 Evas_Object_Table_Option *opt;
1502
1503 const Evas_Object_Table_Data *priv = _pd;
1504
1505 EINA_LIST_FOREACH(priv->children, l, opt)
1506 new_list = eina_list_append(new_list, opt->obj);
1507
1508 *ret = new_list;
1509}
1510
1511Evas_Object *
1512evas_object_table_child_get(const Evas_Object *o, unsigned short col, unsigned short row)
1513{
1514 Eina_List *l;
1515 Evas_Object_Table_Option *opt;
1516
1517 EVAS_OBJECT_TABLE_DATA_GET_OR_RETURN_VAL(o, priv, NULL);
1518
1519 EINA_LIST_FOREACH(priv->children, l, opt)
1520 if (opt->col == col && opt->row == row)
1521 return opt->obj;
1522 return NULL;
1523}
1524
1525EAPI Eina_Bool
1526evas_object_table_mirrored_get(const Evas_Object *obj)
1527{
1528 Eina_Bool ret = EINA_FALSE;
1529 eo_do((Eo *)obj, evas_obj_table_mirrored_get(&ret));
1530 return ret;
1531}
1532
1533static void
1534_mirrored_get(Eo *o EINA_UNUSED, void *_pd, va_list *list)
1535{
1536 Eina_Bool *ret = va_arg(*list, Eina_Bool *);
1537
1538 const Evas_Object_Table_Data *priv = _pd;
1539
1540 *ret = priv->is_mirrored;
1541}
1542
1543EAPI void
1544evas_object_table_mirrored_set(Evas_Object *obj, Eina_Bool mirrored)
1545{
1546 eo_do(obj, evas_obj_table_mirrored_set(mirrored));
1547}
1548
1549static void
1550_mirrored_set(Eo *o, void *_pd, va_list *list)
1551{
1552 Eina_Bool mirrored = va_arg(*list, int);
1553
1554 Evas_Object_Table_Data *priv = _pd;
1555 if (priv->is_mirrored != mirrored)
1556 {
1557 priv->is_mirrored = mirrored;
1558 eo_do(o, evas_obj_smart_calculate());
1559 }
1560}
1561
1562static void
1563_class_constructor(Eo_Class *klass)
1564{
1565 const Eo_Op_Func_Description func_desc[] = {
1566 EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_CONSTRUCTOR), _constructor),
1567 EO_OP_FUNC(EVAS_OBJ_TABLE_ID(EVAS_OBJ_TABLE_SUB_ID_ADD_TO), _add_to),
1568 EO_OP_FUNC(EVAS_OBJ_TABLE_ID(EVAS_OBJ_TABLE_SUB_ID_HOMOGENEOUS_SET), _homogeneous_set),
1569 EO_OP_FUNC(EVAS_OBJ_TABLE_ID(EVAS_OBJ_TABLE_SUB_ID_HOMOGENEOUS_GET), _homogeneous_get),
1570 EO_OP_FUNC(EVAS_OBJ_TABLE_ID(EVAS_OBJ_TABLE_SUB_ID_ALIGN_SET), _align_set),
1571 EO_OP_FUNC(EVAS_OBJ_TABLE_ID(EVAS_OBJ_TABLE_SUB_ID_ALIGN_GET), _align_get),
1572 EO_OP_FUNC(EVAS_OBJ_TABLE_ID(EVAS_OBJ_TABLE_SUB_ID_PADDING_SET), _padding_set),
1573 EO_OP_FUNC(EVAS_OBJ_TABLE_ID(EVAS_OBJ_TABLE_SUB_ID_PADDING_GET), _padding_get),
1574 EO_OP_FUNC(EVAS_OBJ_TABLE_ID(EVAS_OBJ_TABLE_SUB_ID_PACK_GET), _pack_get),
1575 EO_OP_FUNC(EVAS_OBJ_TABLE_ID(EVAS_OBJ_TABLE_SUB_ID_PACK), _pack),
1576 EO_OP_FUNC(EVAS_OBJ_TABLE_ID(EVAS_OBJ_TABLE_SUB_ID_UNPACK), _unpack),
1577 EO_OP_FUNC(EVAS_OBJ_TABLE_ID(EVAS_OBJ_TABLE_SUB_ID_CLEAR), _clear),
1578 EO_OP_FUNC(EVAS_OBJ_TABLE_ID(EVAS_OBJ_TABLE_SUB_ID_COL_ROW_SIZE_GET), _col_row_size_get),
1579 EO_OP_FUNC(EVAS_OBJ_TABLE_ID(EVAS_OBJ_TABLE_SUB_ID_ITERATOR_NEW), _iterator_new),
1580 EO_OP_FUNC(EVAS_OBJ_TABLE_ID(EVAS_OBJ_TABLE_SUB_ID_ACCESSOR_NEW), _accessor_new),
1581 EO_OP_FUNC(EVAS_OBJ_TABLE_ID(EVAS_OBJ_TABLE_SUB_ID_CHILDREN_GET), _children_get),
1582 EO_OP_FUNC(EVAS_OBJ_TABLE_ID(EVAS_OBJ_TABLE_SUB_ID_MIRRORED_GET), _mirrored_get),
1583 EO_OP_FUNC(EVAS_OBJ_TABLE_ID(EVAS_OBJ_TABLE_SUB_ID_MIRRORED_SET), _mirrored_set),
1584 EO_OP_FUNC(EVAS_OBJ_SMART_ID(EVAS_OBJ_SMART_SUB_ID_ADD), _smart_add),
1585 EO_OP_FUNC(EVAS_OBJ_SMART_ID(EVAS_OBJ_SMART_SUB_ID_DEL), _smart_del),
1586 EO_OP_FUNC(EVAS_OBJ_SMART_ID(EVAS_OBJ_SMART_SUB_ID_RESIZE), _smart_resize),
1587 EO_OP_FUNC(EVAS_OBJ_SMART_ID(EVAS_OBJ_SMART_SUB_ID_CALCULATE), _smart_calculate),
1588 EO_OP_FUNC_SENTINEL
1589 };
1590 eo_class_funcs_set(klass, func_desc);
1591}
1592static const Eo_Op_Description op_desc[] = {
1593 EO_OP_DESCRIPTION(EVAS_OBJ_TABLE_SUB_ID_ADD_TO, "Create a table that is child of a given element parent."),
1594 EO_OP_DESCRIPTION(EVAS_OBJ_TABLE_SUB_ID_HOMOGENEOUS_SET, "Set how this table should layout children."),
1595 EO_OP_DESCRIPTION(EVAS_OBJ_TABLE_SUB_ID_HOMOGENEOUS_GET, "Get the current layout homogeneous mode."),
1596 EO_OP_DESCRIPTION(EVAS_OBJ_TABLE_SUB_ID_ALIGN_SET, "Set the alignment of the whole bounding box of contents."),
1597 EO_OP_DESCRIPTION(EVAS_OBJ_TABLE_SUB_ID_ALIGN_GET, "Get alignment of the whole bounding box of contents."),
1598 EO_OP_DESCRIPTION(EVAS_OBJ_TABLE_SUB_ID_PADDING_SET, "Set padding between cells."),
1599 EO_OP_DESCRIPTION(EVAS_OBJ_TABLE_SUB_ID_PADDING_GET, "Get padding between cells."),
1600 EO_OP_DESCRIPTION(EVAS_OBJ_TABLE_SUB_ID_PACK_GET, "Get packing location of a child of table."),
1601 EO_OP_DESCRIPTION(EVAS_OBJ_TABLE_SUB_ID_PACK, "Add a new child to a table object or set its current packing."),
1602 EO_OP_DESCRIPTION(EVAS_OBJ_TABLE_SUB_ID_UNPACK, "Remove child from table."),
1603 EO_OP_DESCRIPTION(EVAS_OBJ_TABLE_SUB_ID_CLEAR, "Faster way to remove all child objects from a table object."),
1604 EO_OP_DESCRIPTION(EVAS_OBJ_TABLE_SUB_ID_COL_ROW_SIZE_GET, "Get the number of columns and rows this table takes."),
1605 EO_OP_DESCRIPTION(EVAS_OBJ_TABLE_SUB_ID_ITERATOR_NEW, "Get an iterator to walk the list of children for the table."),
1606 EO_OP_DESCRIPTION(EVAS_OBJ_TABLE_SUB_ID_ACCESSOR_NEW, "Get an accessor to get random access to the list of children for the table."),
1607 EO_OP_DESCRIPTION(EVAS_OBJ_TABLE_SUB_ID_CHILDREN_GET, "Get the list of children for the table."),
1608 EO_OP_DESCRIPTION(EVAS_OBJ_TABLE_SUB_ID_MIRRORED_GET, "Gets the mirrored mode of the table."),
1609 EO_OP_DESCRIPTION(EVAS_OBJ_TABLE_SUB_ID_MIRRORED_SET, "Sets the mirrored mode of the table."),
1610 EO_OP_DESCRIPTION_SENTINEL
1611};
1612static const Eo_Class_Description class_desc = {
1613 EO_VERSION,
1614 "Evas_Object_Table",
1615 EO_CLASS_TYPE_REGULAR,
1616 EO_CLASS_DESCRIPTION_OPS(&EVAS_OBJ_TABLE_BASE_ID, op_desc, EVAS_OBJ_TABLE_SUB_ID_LAST),
1617 NULL,
1618 sizeof(Evas_Object_Table_Data),
1619 _class_constructor,
1620 NULL
1621};
1622
1623EO_DEFINE_CLASS(evas_object_table_class_get, &class_desc, EVAS_OBJ_SMART_CLIPPED_CLASS, NULL);
1624