aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/evas/src/lib/canvas/evas_object_box.c
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/evas/src/lib/canvas/evas_object_box.c')
-rw-r--r--libraries/evas/src/lib/canvas/evas_object_box.c2127
1 files changed, 0 insertions, 2127 deletions
diff --git a/libraries/evas/src/lib/canvas/evas_object_box.c b/libraries/evas/src/lib/canvas/evas_object_box.c
deleted file mode 100644
index 228d37c..0000000
--- a/libraries/evas/src/lib/canvas/evas_object_box.c
+++ /dev/null
@@ -1,2127 +0,0 @@
1#include "evas_common.h"
2
3#ifdef _WIN32_WCE
4# undef remove
5#endif
6
7typedef struct _Evas_Object_Box_Iterator Evas_Object_Box_Iterator;
8typedef struct _Evas_Object_Box_Accessor Evas_Object_Box_Accessor;
9
10struct _Evas_Object_Box_Iterator
11{
12 Eina_Iterator iterator;
13
14 Eina_Iterator *real_iterator;
15 const Evas_Object *box;
16};
17
18struct _Evas_Object_Box_Accessor
19{
20 Eina_Accessor accessor;
21
22 Eina_Accessor *real_accessor;
23 const Evas_Object *box;
24};
25
26#define _evas_object_box_type "Evas_Object_Box"
27#define SIG_CHILD_ADDED "child,added"
28#define SIG_CHILD_REMOVED "child,removed"
29
30static const Evas_Smart_Cb_Description _signals[] =
31{
32 {SIG_CHILD_ADDED, ""},
33 {SIG_CHILD_REMOVED, ""},
34 {NULL, NULL}
35};
36
37
38static void _sizing_eval(Evas_Object *obj);
39
40#define EVAS_OBJECT_BOX_DATA_GET(o, ptr) \
41 Evas_Object_Box_Data *ptr = evas_object_smart_data_get(o)
42
43#define EVAS_OBJECT_BOX_DATA_GET_OR_RETURN(o, ptr) \
44 EVAS_OBJECT_BOX_DATA_GET(o, ptr); \
45 if (!ptr) \
46 { \
47 CRIT("no widget data for object %p (%s)", \
48 o, evas_object_type_get(o)); \
49 fflush(stderr); \
50 abort(); \
51 return; \
52}
53
54#define EVAS_OBJECT_BOX_DATA_GET_OR_RETURN_VAL(o, ptr, val) \
55 EVAS_OBJECT_BOX_DATA_GET(o, ptr); \
56 if (!ptr) \
57 { \
58 CRIT("no widget data for object %p (%s)", \
59 o, evas_object_type_get(o)); \
60 fflush(stderr); \
61 abort(); \
62 return val; \
63 }
64
65EVAS_SMART_SUBCLASS_NEW(_evas_object_box_type, _evas_object_box,
66 Evas_Object_Box_Api, Evas_Smart_Class,
67 evas_object_smart_clipped_class_get, NULL)
68
69static Eina_Bool
70_evas_object_box_iterator_next(Evas_Object_Box_Iterator *it, void **data)
71{
72 Evas_Object_Box_Option *opt;
73
74 if (!eina_iterator_next(it->real_iterator, (void **)&opt))
75 return EINA_FALSE;
76 if (data) *data = opt->obj;
77 return EINA_TRUE;
78}
79
80static Evas_Object *
81_evas_object_box_iterator_get_container(Evas_Object_Box_Iterator *it)
82{
83 return (Evas_Object *)it->box;
84}
85
86static void
87_evas_object_box_iterator_free(Evas_Object_Box_Iterator *it)
88{
89 eina_iterator_free(it->real_iterator);
90 free(it);
91}
92
93static Eina_Bool
94_evas_object_box_accessor_get_at(Evas_Object_Box_Accessor *it, unsigned int idx, void **data)
95{
96 Evas_Object_Box_Option *opt = NULL;
97
98 if (!eina_accessor_data_get(it->real_accessor, idx, (void *)&opt))
99 return EINA_FALSE;
100 if (data) *data = opt->obj;
101 return EINA_TRUE;
102}
103
104static Evas_Object *
105_evas_object_box_accessor_get_container(Evas_Object_Box_Accessor *it)
106{
107 return (Evas_Object *)it->box;
108}
109
110static void
111_evas_object_box_accessor_free(Evas_Object_Box_Accessor *it)
112{
113 eina_accessor_free(it->real_accessor);
114 free(it);
115}
116
117static void
118_on_child_resize(void *data, Evas *evas __UNUSED__, Evas_Object *o __UNUSED__, void *einfo __UNUSED__)
119{
120 Evas_Object *box = data;
121 EVAS_OBJECT_BOX_DATA_GET_OR_RETURN(box, priv);
122 if (!priv->layouting) evas_object_smart_changed(box);
123}
124
125static void
126_on_child_del(void *data, Evas *evas __UNUSED__, Evas_Object *o, void *einfo __UNUSED__)
127{
128 const Evas_Object_Box_Api *api;
129 Evas_Object *box = data;
130
131 EVAS_OBJECT_BOX_DATA_GET(box, priv);
132 api = priv->api;
133
134 if ((!api) || (!api->remove))
135 {
136 ERR("no api->remove");
137 return;
138 }
139
140 if (!api->remove(box, priv, o))
141 ERR("child removal failed");
142 evas_object_smart_changed(box);
143}
144
145static void
146_on_child_hints_changed(void *data, Evas *evas __UNUSED__, Evas_Object *o __UNUSED__, void *einfo __UNUSED__)
147{
148 Evas_Object *box = data;
149 EVAS_OBJECT_BOX_DATA_GET_OR_RETURN(box, priv);
150 if (!priv->layouting) evas_object_smart_changed(box);
151}
152
153static void
154_on_hints_changed(void *data __UNUSED__, Evas *evas __UNUSED__, Evas_Object *o , void *einfo __UNUSED__)
155{
156 _sizing_eval(o);
157}
158
159static Evas_Object_Box_Option *
160_evas_object_box_option_new(Evas_Object *o, Evas_Object_Box_Data *priv, Evas_Object *child)
161{
162 Evas_Object_Box_Option *opt;
163 const Evas_Object_Box_Api *api;
164
165 api = priv->api;
166 if ((!api) || (!api->option_new))
167 {
168 ERR("no api->option_new");
169 return NULL;
170 }
171
172 opt = api->option_new(o, priv, child);
173 if (!opt)
174 {
175 ERR("option_new failed");
176 return NULL;
177 }
178
179 return opt;
180}
181
182static void
183_evas_object_box_child_callbacks_unregister(Evas_Object *obj)
184{
185 evas_object_event_callback_del
186 (obj, EVAS_CALLBACK_RESIZE, _on_child_resize);
187 evas_object_event_callback_del
188 (obj, EVAS_CALLBACK_FREE, _on_child_del);
189 evas_object_event_callback_del
190 (obj, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _on_child_hints_changed);
191}
192
193static Evas_Object_Box_Option *
194_evas_object_box_option_callbacks_register(Evas_Object *o, Evas_Object_Box_Data *priv, Evas_Object_Box_Option *opt)
195{
196 const Evas_Object_Box_Api *api;
197 Evas_Object *obj = opt->obj;
198
199 api = priv->api;
200
201 if ((!api) || (!api->option_free))
202 {
203 WRN("api->option_free not set (may cause memory leaks, segfaults)");
204 return NULL;
205 }
206
207 evas_object_event_callback_add
208 (obj, EVAS_CALLBACK_RESIZE, _on_child_resize, o);
209 evas_object_event_callback_add
210 (obj, EVAS_CALLBACK_FREE, _on_child_del, o);
211 evas_object_event_callback_add
212 (obj, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _on_child_hints_changed, o);
213
214 return opt;
215}
216
217static Evas_Object_Box_Option *
218_evas_object_box_option_new_default(Evas_Object *o __UNUSED__, Evas_Object_Box_Data *priv __UNUSED__, Evas_Object *child)
219{
220 Evas_Object_Box_Option *opt;
221
222 opt = (Evas_Object_Box_Option *)malloc(sizeof(*opt));
223 if (!opt)
224 return NULL;
225
226 opt->obj = child;
227
228 return opt;
229}
230
231static void
232_evas_object_box_option_free_default(Evas_Object *o __UNUSED__, Evas_Object_Box_Data *priv __UNUSED__, Evas_Object_Box_Option *opt)
233{
234 free(opt);
235}
236
237static Evas_Object_Box_Option *
238_evas_object_box_append_default(Evas_Object *o, Evas_Object_Box_Data *priv, Evas_Object *child)
239{
240 Evas_Object_Box_Option *opt;
241
242 opt = _evas_object_box_option_new(o, priv, child);
243 if (!opt)
244 return NULL;
245
246 priv->children = eina_list_append(priv->children, opt);
247 priv->children_changed = EINA_TRUE;
248 evas_object_smart_callback_call(o, SIG_CHILD_ADDED, opt);
249
250 return opt;
251}
252
253static Evas_Object_Box_Option *
254_evas_object_box_prepend_default(Evas_Object *o, Evas_Object_Box_Data *priv, Evas_Object *child)
255{
256 Evas_Object_Box_Option *opt;
257
258 opt = _evas_object_box_option_new(o, priv, child);
259 if (!opt)
260 return NULL;
261
262 priv->children = eina_list_prepend(priv->children, opt);
263 priv->children_changed = EINA_TRUE;
264 evas_object_smart_callback_call(o, SIG_CHILD_ADDED, opt);
265
266 return opt;
267}
268
269static Evas_Object_Box_Option *
270_evas_object_box_insert_before_default(Evas_Object *o, Evas_Object_Box_Data *priv, Evas_Object *child, const Evas_Object *reference)
271{
272 Eina_List *l;
273 Evas_Object_Box_Option *opt;
274
275 EINA_LIST_FOREACH(priv->children, l, opt)
276 {
277 if (opt->obj == reference)
278 {
279 Evas_Object_Box_Option *new_opt;
280
281 new_opt = _evas_object_box_option_new(o, priv, child);
282 if (!new_opt)
283 return NULL;
284
285 priv->children = eina_list_prepend_relative
286 (priv->children, new_opt, opt);
287 priv->children_changed = EINA_TRUE;
288 evas_object_smart_callback_call(o, SIG_CHILD_ADDED, new_opt);
289 return new_opt;
290 }
291 }
292
293 return NULL;
294}
295
296static Evas_Object_Box_Option *
297_evas_object_box_insert_after_default(Evas_Object *o, Evas_Object_Box_Data *priv, Evas_Object *child, const Evas_Object *reference)
298{
299 Eina_List *l;
300 Evas_Object_Box_Option *opt;
301
302 EINA_LIST_FOREACH(priv->children, l, opt)
303 {
304 if (opt->obj == reference)
305 {
306 Evas_Object_Box_Option *new_opt;
307
308 new_opt = _evas_object_box_option_new(o, priv, child);
309 if (!new_opt)
310 return NULL;
311
312 priv->children = eina_list_append_relative
313 (priv->children, new_opt, opt);
314 priv->children_changed = EINA_TRUE;
315 evas_object_smart_callback_call(o, SIG_CHILD_ADDED, new_opt);
316 return new_opt;
317 }
318 }
319
320 return NULL;
321}
322
323static Evas_Object_Box_Option *
324_evas_object_box_insert_at_default(Evas_Object *o, Evas_Object_Box_Data *priv, Evas_Object *child, unsigned int pos)
325{
326 Eina_List *l;
327 unsigned int i;
328
329 if ((pos == 0) && (eina_list_count(priv->children) == 0))
330 {
331 Evas_Object_Box_Option *new_opt;
332
333 new_opt = _evas_object_box_option_new(o, priv, child);
334 if (!new_opt)
335 return NULL;
336
337 priv->children = eina_list_prepend(priv->children, new_opt);
338 priv->children_changed = EINA_TRUE;
339 evas_object_smart_callback_call(o, SIG_CHILD_ADDED, new_opt);
340 return new_opt;
341 }
342
343 for (l = priv->children, i = 0; l; l = l->next, i++)
344 {
345 Evas_Object_Box_Option *opt = l->data;
346
347 if (i == pos)
348 {
349 Evas_Object_Box_Option *new_opt;
350
351 new_opt = _evas_object_box_option_new(o, priv, child);
352 if (!new_opt)
353 return NULL;
354
355 priv->children = eina_list_prepend_relative
356 (priv->children, new_opt, opt);
357 priv->children_changed = EINA_TRUE;
358 evas_object_smart_callback_call(o, SIG_CHILD_ADDED, new_opt);
359 return new_opt;
360 }
361 }
362
363 return NULL;
364}
365
366static Evas_Object *
367_evas_object_box_remove_default(Evas_Object *o, Evas_Object_Box_Data *priv, Evas_Object *child)
368{
369 const Evas_Object_Box_Api *api;
370 Evas_Object_Box_Option *opt;
371 Eina_List *l;
372
373 api = priv->api;
374
375 if ((!api) || (!api->option_free))
376 {
377 ERR("api->option_free not set (may cause memory leaks, segfaults)");
378 return NULL;
379 }
380
381 EINA_LIST_FOREACH(priv->children, l, opt)
382 {
383 Evas_Object *obj = opt->obj;
384
385 if (obj == child)
386 {
387 priv->children = eina_list_remove(priv->children, opt);
388 api->option_free(o, priv, opt);
389 priv->children_changed = EINA_TRUE;
390 evas_object_smart_callback_call(o, SIG_CHILD_REMOVED, obj);
391
392 return obj;
393 }
394 }
395
396 return NULL;
397}
398
399static Evas_Object *
400_evas_object_box_remove_at_default(Evas_Object *o, Evas_Object_Box_Data *priv, unsigned int pos)
401{
402 const Evas_Object_Box_Api *api;
403 Eina_List *node;
404 Evas_Object_Box_Option *opt;
405 Evas_Object *obj;
406
407 api = priv->api;
408
409 if ((!api) || (!api->option_free))
410 {
411 WRN("api->option_free not set (may cause memory leaks, segfaults)");
412 return NULL;
413 }
414
415 node = eina_list_nth_list(priv->children, pos);
416 if (!node)
417 {
418 ERR("No item to be removed at position %d", pos);
419 return NULL;
420 }
421
422 opt = node->data;
423 obj = opt->obj;
424
425 priv->children = eina_list_remove_list(priv->children, node);
426 api->option_free(o, priv, opt);
427 priv->children_changed = EINA_TRUE;
428 evas_object_smart_callback_call(o, SIG_CHILD_REMOVED, obj);
429 return obj;
430}
431
432static void
433_evas_object_box_smart_add(Evas_Object *o)
434{
435 Evas_Object_Box_Data *priv;
436
437 priv = evas_object_smart_data_get(o);
438 if (!priv)
439 {
440 const Evas_Smart *smart;
441 const Evas_Smart_Class *sc;
442
443 priv = (Evas_Object_Box_Data *)calloc(1, sizeof(*priv));
444 if (!priv)
445 {
446 ERR("Could not allocate object private data.");
447 return;
448 }
449
450 smart = evas_object_smart_smart_get(o);
451 sc = evas_smart_class_get(smart);
452 priv->api = (const Evas_Object_Box_Api *)sc;
453
454 evas_object_smart_data_set(o, priv);
455 }
456 _evas_object_box_parent_sc->add(o);
457
458
459 evas_object_event_callback_add
460 (o, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _on_hints_changed, o);
461 priv->children = NULL;
462 priv->align.h = 0.5;
463 priv->align.v = 0.5;
464 priv->pad.h = 0;
465 priv->pad.v = 0;
466 priv->layout.cb = evas_object_box_layout_horizontal;
467 priv->layout.data = NULL;
468 priv->layout.free_data = NULL;
469}
470
471static void
472_evas_object_box_smart_del(Evas_Object *o)
473{
474 const Evas_Object_Box_Api *api;
475 Eina_List *l;
476
477 EVAS_OBJECT_BOX_DATA_GET(o, priv);
478
479 api = priv->api;
480 if ((!api) || (!api->option_free))
481 {
482 WRN("api->option_free not set (may cause memory leaks, segfaults)");
483 return;
484 }
485
486 l = priv->children;
487 while (l)
488 {
489 Evas_Object_Box_Option *opt = l->data;
490
491 _evas_object_box_child_callbacks_unregister(opt->obj);
492 api->option_free(o, priv, opt);
493 l = eina_list_remove_list(l, l);
494 }
495
496 if (priv->layout.data && priv->layout.free_data)
497 priv->layout.free_data(priv->layout.data);
498
499 _evas_object_box_parent_sc->del(o);
500}
501
502static void
503_evas_object_box_smart_resize(Evas_Object *o, Evas_Coord w, Evas_Coord h)
504{
505 Evas_Coord ow, oh;
506 evas_object_geometry_get(o, NULL, NULL, &ow, &oh);
507 if ((ow == w) && (oh == h)) return;
508 evas_object_smart_changed(o);
509}
510
511static void
512_evas_object_box_smart_calculate(Evas_Object *o)
513{
514 EVAS_OBJECT_BOX_DATA_GET_OR_RETURN(o, priv);
515 if (priv->layout.cb)
516 {
517 priv->layouting = 1;
518 priv->layout.cb(o, priv, priv->layout.data);
519 priv->layouting = 0;
520 priv->children_changed = EINA_FALSE;
521 }
522 else
523 ERR("No layout function set for %p box.", o);
524}
525
526static void
527_evas_object_box_smart_set_user(Evas_Object_Box_Api *api)
528{
529 api->base.add = _evas_object_box_smart_add;
530 api->base.del = _evas_object_box_smart_del;
531 api->base.resize = _evas_object_box_smart_resize;
532 api->base.calculate = _evas_object_box_smart_calculate;
533 api->base.callbacks = _signals;
534
535 api->append = _evas_object_box_append_default;
536 api->prepend = _evas_object_box_prepend_default;
537 api->insert_before = _evas_object_box_insert_before_default;
538 api->insert_after = _evas_object_box_insert_after_default;
539 api->insert_at = _evas_object_box_insert_at_default;
540 api->remove = _evas_object_box_remove_default;
541 api->remove_at = _evas_object_box_remove_at_default;
542 api->option_new = _evas_object_box_option_new_default;
543 api->option_free = _evas_object_box_option_free_default;
544}
545
546EAPI Evas_Object *
547evas_object_box_add(Evas *evas)
548{
549 return evas_object_smart_add(evas, _evas_object_box_smart_class_new());
550}
551
552EAPI Evas_Object *
553evas_object_box_add_to(Evas_Object *parent)
554{
555 Evas *evas;
556 Evas_Object *o;
557
558 evas = evas_object_evas_get(parent);
559 o = evas_object_box_add(evas);
560 evas_object_smart_member_add(o, parent);
561 return o;
562}
563
564EAPI void
565evas_object_box_smart_set(Evas_Object_Box_Api *api)
566{
567 if (!api)
568 return;
569 _evas_object_box_smart_set(api);
570}
571
572EAPI const Evas_Object_Box_Api *
573evas_object_box_smart_class_get(void)
574{
575 static Evas_Object_Box_Api _sc =
576 EVAS_OBJECT_BOX_API_INIT_NAME_VERSION(_evas_object_box_type);
577 static const Evas_Object_Box_Api *class = NULL;
578
579 if (class)
580 return class;
581
582 evas_object_box_smart_set(&_sc);
583 class = &_sc;
584
585 return class;
586}
587
588EAPI void
589evas_object_box_layout_set(Evas_Object *o, Evas_Object_Box_Layout cb, const void *data, void (*free_data)(void *data))
590{
591 EVAS_OBJECT_BOX_DATA_GET_OR_RETURN(o, priv);
592
593 if ((priv->layout.cb == cb) && (priv->layout.data == data) &&
594 (priv->layout.free_data == free_data))
595 return;
596
597 if (priv->layout.data && priv->layout.free_data)
598 priv->layout.free_data(priv->layout.data);
599
600 priv->layout.cb = cb;
601 priv->layout.data = (void *)data;
602 priv->layout.free_data = free_data;
603 evas_object_smart_changed(o);
604}
605
606static void
607_fixed_point_divide_and_decompose_integer(int dividend, int divisor, int *int_part, int *frac_part)
608{
609 int quotient = (long long)(dividend << 16) / divisor;
610 *frac_part = quotient & 0xffff;
611 *int_part = quotient >> 16;
612}
613
614static void
615_layout_dimension_change_min_max_cell_bound(int dim, int *new_dim, int min_d, int max_d, int cell_sz)
616{
617 if (dim > cell_sz)
618 {
619 if ((min_d != 0) && (cell_sz < min_d))
620 *new_dim = min_d;
621 else
622 *new_dim = cell_sz;
623 }
624 else
625 {
626 if ((max_d != -1) && (cell_sz > max_d))
627 *new_dim = max_d;
628 else
629 *new_dim = cell_sz;
630 }
631}
632
633static void
634_layout_set_offset_and_expand_dimension_space_max_bounded(int dim, int *new_dim, int space_sz, int max_dim, int *offset, double align, int pad_before, int pad_after)
635{
636 if (align >= 0.0)
637 {
638 *new_dim = dim;
639 *offset = (space_sz - (dim + pad_before + pad_after)) * align
640 + pad_before;
641 }
642 else
643 {
644 if ((max_dim != -1) && (space_sz > max_dim))
645 {
646 *new_dim = max_dim;
647 *offset = (space_sz - (max_dim + pad_before + pad_after)) * 0.5
648 + pad_before;
649 }
650 else
651 {
652 *new_dim = space_sz;
653 *offset = 0;
654 }
655 }
656}
657
658static void
659_layout_set_offset_and_change_dimension_min_max_cell_bounded(int dim, int *new_dim, int min_dim, int max_dim, int cell_sz, int *offset, double align, int pad_before, int pad_after)
660{
661 if (align >= 0.0)
662 {
663 *new_dim = dim;
664 *offset =
665 (cell_sz - (dim + pad_before + pad_after)) * align + pad_before;
666 }
667 else
668 {
669 *offset = pad_before;
670 _layout_dimension_change_min_max_cell_bound
671 (dim, new_dim, min_dim, max_dim, cell_sz - pad_before - pad_after);
672 }
673}
674
675static void
676_sizing_eval(Evas_Object *obj)
677{
678 Evas_Coord minw, minh, maxw, maxh;
679 Evas_Coord w, h;
680
681 evas_object_size_hint_min_get(obj, &minw, &minh);
682 evas_object_size_hint_max_get(obj, &maxw, &maxh);
683 evas_object_geometry_get(obj, NULL, NULL, &w, &h);
684
685 if (w < minw) w = minw;
686 if (h < minh) h = minh;
687 if ((maxw >= 0) && (w > maxw)) w = maxw;
688 if ((maxh >= 0) && (h > maxh)) h = maxh;
689
690 evas_object_resize(obj, w, h);
691}
692
693static int
694_evas_object_box_layout_horizontal_weight_apply(Evas_Object_Box_Data *priv, Evas_Object_Box_Option **objects, int n_objects, int remaining, int weight_total)
695{
696 int rem_diff = 0;
697 int i;
698
699 for (i = 0; i < n_objects; i++)
700 {
701 Evas_Object_Box_Option *opt = objects[i];
702 Evas_Object *o = opt->obj;
703 int h;
704
705 evas_object_geometry_get(o, NULL, NULL, NULL, &h);
706
707 if (remaining <= 0)
708 {
709 int min_w;
710
711 evas_object_size_hint_min_get(o, &min_w, NULL);
712 evas_object_resize(o, min_w, h);
713 }
714 else
715 {
716 double normal_weight, weight_x;
717 int target_size;
718 int max_w;
719
720 evas_object_size_hint_weight_get(o, &weight_x, NULL);
721 normal_weight = weight_x / weight_total;
722 target_size = (int)((double)remaining * normal_weight);
723
724 evas_object_size_hint_max_get(o, &max_w, NULL);
725 if ((max_w != -1) && (target_size > max_w))
726 {
727 evas_object_resize(o, max_w, h);
728 rem_diff += max_w;
729 objects[i] = objects[n_objects - 1];
730 weight_total -= weight_x;
731 n_objects--;
732 return _evas_object_box_layout_horizontal_weight_apply
733 (priv, objects, n_objects, remaining - rem_diff,
734 weight_total);
735 }
736 else
737 {
738 evas_object_resize(o, target_size, h);
739 rem_diff += target_size;
740 }
741 }
742 }
743
744 return remaining - rem_diff;
745}
746
747EAPI void
748evas_object_box_layout_horizontal(Evas_Object *o, Evas_Object_Box_Data *priv, void *data __UNUSED__)
749{
750 int pad_inc = 0, sub_pixel = 0;
751 int req_w, global_pad, remaining, top_h = 0;
752 double weight_total = 0.0;
753 int weight_use = 0;
754 int x, y, w, h;
755 int n_children;
756 Evas_Object_Box_Option *opt;
757 Evas_Object_Box_Option **objects;
758 Eina_List *l;
759
760 n_children = eina_list_count(priv->children);
761 if (!n_children)
762 return;
763
764 objects = (Evas_Object_Box_Option **)alloca(sizeof(Evas_Object_Box_Option *) * n_children);
765 if (!objects)
766 return;
767
768 evas_object_geometry_get(o, &x, &y, &w, &h);
769 global_pad = priv->pad.h;
770 req_w = global_pad * (n_children - 1);
771
772 EINA_LIST_FOREACH(priv->children, l, opt)
773 {
774 int padding_l, padding_r;
775 double weight_x;
776
777 _sizing_eval(opt->obj);
778 evas_object_size_hint_weight_get(opt->obj, &weight_x, NULL);
779 evas_object_size_hint_padding_get
780 (opt->obj, &padding_l, &padding_r, NULL, NULL);
781 req_w += padding_l + padding_r;
782
783 if (!weight_x)
784 {
785 int child_w;
786
787 evas_object_geometry_get(opt->obj, NULL, NULL, &child_w, NULL);
788 req_w += child_w;
789 }
790 else
791 {
792 objects[weight_use] = opt;
793 weight_use++;
794 weight_total += weight_x;
795 }
796 }
797
798 remaining = w - req_w;
799
800 if (weight_use)
801 remaining = _evas_object_box_layout_horizontal_weight_apply
802 (priv, objects, weight_use, remaining, weight_total);
803
804 if (priv->align.h >= 0.0)
805 x += remaining * priv->align.h;
806 else if (n_children == 1)
807 x += remaining / 2;
808 else
809 { /* justified */
810 _fixed_point_divide_and_decompose_integer
811 (remaining, n_children - 1, &global_pad, &pad_inc);
812 global_pad += priv->pad.h;
813 }
814
815 EINA_LIST_FOREACH(priv->children, l, opt)
816 {
817 int child_w, child_h, max_h, new_h, off_x, off_y;
818 int padding_l, padding_r, padding_t, padding_b;
819 double align_y;
820
821 evas_object_size_hint_align_get(opt->obj, NULL, &align_y);
822 evas_object_size_hint_padding_get
823 (opt->obj, &padding_l, &padding_r, &padding_t, &padding_b);
824 evas_object_size_hint_max_get(opt->obj, NULL, &max_h);
825
826 evas_object_geometry_get(opt->obj, NULL, NULL, &child_w, &child_h);
827
828 off_x = padding_l;
829 new_h = child_h;
830 if (new_h > top_h) top_h = new_h;
831
832 _layout_set_offset_and_expand_dimension_space_max_bounded
833 (child_h, &new_h, h, max_h, &off_y, align_y, padding_t, padding_b);
834
835 if (new_h != child_h)
836 evas_object_resize(opt->obj, child_w, new_h);
837 evas_object_move(opt->obj, x + off_x, y + off_y);
838
839 x += child_w + padding_l + padding_r + global_pad;
840 sub_pixel += pad_inc;
841 if (sub_pixel >= 1 << 16)
842 {
843 x++;
844 sub_pixel -= 1 << 16;
845 }
846 }
847
848 evas_object_size_hint_min_set(o, req_w, top_h);
849}
850
851static int
852_evas_object_box_layout_vertical_weight_apply(Evas_Object_Box_Data *priv, Evas_Object_Box_Option **objects, int n_objects, int remaining, int weight_total)
853{
854 int rem_diff = 0;
855 int i;
856
857 for (i = 0; i < n_objects; i++)
858 {
859 Evas_Object_Box_Option *opt = objects[i];
860 Evas_Object *o = opt->obj;
861 int w;
862
863 evas_object_geometry_get(o, NULL, NULL, &w, NULL);
864
865 if (remaining <= 0)
866 {
867 int min_h;
868
869 evas_object_size_hint_min_get(o, NULL, &min_h);
870 evas_object_resize(o, w, min_h);
871 }
872 else
873 {
874 double normal_weight, weight_y;
875 int target_size;
876 int max_h;
877
878 evas_object_size_hint_weight_get(o, NULL, &weight_y);
879 normal_weight = weight_y / weight_total;
880 target_size = (int)((double)remaining * normal_weight);
881
882 evas_object_size_hint_max_get(o, NULL, &max_h);
883 if ((max_h != -1) && (target_size > max_h))
884 {
885 evas_object_resize(o, w, max_h);
886 rem_diff += max_h;
887 objects[i] = objects[n_objects - 1];
888 weight_total -= weight_y;
889 n_objects--;
890 return _evas_object_box_layout_vertical_weight_apply
891 (priv, objects, n_objects, remaining - rem_diff,
892 weight_total);
893 }
894 else
895 {
896 evas_object_resize(o, w, target_size);
897 rem_diff += target_size;
898 }
899 }
900 }
901
902 return remaining - rem_diff;
903}
904
905EAPI void
906evas_object_box_layout_vertical(Evas_Object *o, Evas_Object_Box_Data *priv, void *data __UNUSED__)
907{
908 int pad_inc = 0, sub_pixel = 0;
909 int req_h, global_pad, remaining, top_w = 0;
910 double weight_total = 0.0;
911 int weight_use = 0;
912 int x, y, w, h;
913 int n_children;
914 Evas_Object_Box_Option *opt;
915 Evas_Object_Box_Option **objects;
916 Eina_List *l;
917
918 n_children = eina_list_count(priv->children);
919 if (!n_children)
920 return;
921
922 objects = (Evas_Object_Box_Option **)alloca(sizeof(Evas_Object_Box_Option *) * n_children);
923 if (!objects)
924 return;
925
926 evas_object_geometry_get(o, &x, &y, &w, &h);
927 global_pad = priv->pad.v;
928 req_h = global_pad * (n_children - 1);
929
930 EINA_LIST_FOREACH(priv->children, l, opt)
931 {
932 int padding_t, padding_b;
933 double weight_y;
934
935 _sizing_eval(opt->obj);
936 evas_object_size_hint_weight_get(opt->obj, NULL, &weight_y);
937 evas_object_size_hint_padding_get
938 (opt->obj, NULL, NULL, &padding_t, &padding_b);
939 req_h += padding_t + padding_b;
940
941 if (!weight_y)
942 {
943 int child_h;
944
945 evas_object_geometry_get(opt->obj, NULL, NULL, NULL, &child_h);
946 req_h += child_h;
947 }
948 else
949 {
950 objects[weight_use] = opt;
951 weight_use++;
952 weight_total += weight_y;
953 }
954 }
955
956 remaining = h - req_h;
957
958 if (weight_use)
959 remaining = _evas_object_box_layout_vertical_weight_apply
960 (priv, objects, weight_use, remaining, weight_total);
961
962 if (priv->align.v >= 0.0)
963 y += remaining * priv->align.v;
964 else if (n_children == 1)
965 y += remaining / 2;
966 else
967 { /* justified */
968 _fixed_point_divide_and_decompose_integer
969 (remaining, n_children - 1, &global_pad, &pad_inc);
970 global_pad += priv->pad.v;
971 }
972
973 EINA_LIST_FOREACH(priv->children, l, opt)
974 {
975 int child_w, child_h, max_w, new_w, off_x, off_y;
976 int padding_l, padding_r, padding_t, padding_b;
977 double align_x;
978
979 evas_object_size_hint_align_get(opt->obj, &align_x, NULL);
980 evas_object_size_hint_padding_get
981 (opt->obj, &padding_l, &padding_r, &padding_t, &padding_b);
982 evas_object_size_hint_max_get(opt->obj, &max_w, NULL);
983
984 evas_object_geometry_get(opt->obj, NULL, NULL, &child_w, &child_h);
985
986 off_y = padding_t;
987 new_w = child_w;
988
989 _layout_set_offset_and_expand_dimension_space_max_bounded
990 (child_w, &new_w, w, max_w, &off_x, align_x, padding_l, padding_r);
991
992 if (new_w > top_w) top_w = new_w;
993
994 if (new_w != child_w)
995 evas_object_resize(opt->obj, new_w, child_h);
996 evas_object_move(opt->obj, x + off_x, y + off_y);
997
998 y += child_h + padding_t + padding_b + global_pad;
999 sub_pixel += pad_inc;
1000 if (sub_pixel >= 1 << 16)
1001 {
1002 y++;
1003 sub_pixel -= 1 << 16;
1004 }
1005 }
1006
1007 evas_object_size_hint_min_set(o, top_w, req_h);
1008}
1009
1010EAPI void
1011evas_object_box_layout_homogeneous_horizontal(Evas_Object *o, Evas_Object_Box_Data *priv, void *data __UNUSED__)
1012{
1013 int cell_sz, share, inc;
1014 int sub_pixel = 0;
1015 int x, y, w, h;
1016 int n_children;
1017 Evas_Object_Box_Option *opt;
1018 Eina_List *l;
1019
1020 n_children = eina_list_count(priv->children);
1021 if (!n_children)
1022 return;
1023
1024 evas_object_geometry_get(o, &x, &y, &w, &h);
1025
1026 share = w - priv->pad.h * (n_children - 1);
1027 _fixed_point_divide_and_decompose_integer
1028 (share, n_children, &cell_sz, &inc);
1029
1030 EINA_LIST_FOREACH(priv->children, l, opt)
1031 {
1032 int child_w, child_h, max_h, min_w, max_w, new_w, new_h, off_x, off_y;
1033 int padding_l, padding_r, padding_t, padding_b;
1034 double align_x, align_y;
1035
1036 evas_object_size_hint_align_get(opt->obj, &align_x, &align_y);
1037 evas_object_size_hint_padding_get
1038 (opt->obj, &padding_l, &padding_r, &padding_t, &padding_b);
1039 evas_object_size_hint_max_get(opt->obj, &max_w, &max_h);
1040 evas_object_size_hint_min_get(opt->obj, &min_w, NULL);
1041
1042 _sizing_eval(opt->obj);
1043 evas_object_geometry_get(opt->obj, NULL, NULL, &child_w, &child_h);
1044
1045 new_w = child_w;
1046 new_h = child_h;
1047
1048 _layout_set_offset_and_expand_dimension_space_max_bounded
1049 (child_h, &new_h, h, max_h, &off_y, align_y, padding_t, padding_b);
1050
1051 _layout_set_offset_and_change_dimension_min_max_cell_bounded
1052 (child_w, &new_w, min_w, max_w, cell_sz, &off_x, align_x,
1053 padding_l, padding_r);
1054
1055 if ((new_w != child_w) || (new_h != child_h))
1056 evas_object_resize(opt->obj, new_w, new_h);
1057 evas_object_move(opt->obj, x + off_x, y + off_y);
1058
1059 x += cell_sz + priv->pad.h;
1060 sub_pixel += inc;
1061 if (sub_pixel >= 1 << 16)
1062 {
1063 x++;
1064 sub_pixel -= 1 << 16;
1065 }
1066 }
1067
1068 evas_object_size_hint_min_set(o, w, h);
1069}
1070
1071EAPI void
1072evas_object_box_layout_homogeneous_vertical(Evas_Object *o, Evas_Object_Box_Data *priv, void *data __UNUSED__)
1073{
1074 int cell_sz, share, inc;
1075 int sub_pixel = 0;
1076 int x, y, w, h;
1077 int n_children;
1078 Evas_Object_Box_Option *opt;
1079 Eina_List *l;
1080
1081 n_children = eina_list_count(priv->children);
1082 if (!n_children)
1083 return;
1084
1085 evas_object_geometry_get(o, &x, &y, &w, &h);
1086
1087 share = h - priv->pad.v * (n_children - 1);
1088 _fixed_point_divide_and_decompose_integer
1089 (share, n_children, &cell_sz, &inc);
1090
1091 EINA_LIST_FOREACH(priv->children, l, opt)
1092 {
1093 int child_w, child_h, max_w, min_h, max_h, new_w, new_h, off_x, off_y;
1094 int padding_l, padding_r, padding_t, padding_b;
1095 double align_x, align_y;
1096
1097 evas_object_size_hint_align_get(opt->obj, &align_x, &align_y);
1098 evas_object_size_hint_padding_get
1099 (opt->obj, &padding_l, &padding_r, &padding_t, &padding_b);
1100 evas_object_size_hint_max_get(opt->obj, &max_w, &max_h);
1101 evas_object_size_hint_min_get(opt->obj, NULL, &min_h);
1102
1103 _sizing_eval(opt->obj);
1104 evas_object_geometry_get(opt->obj, NULL, NULL, &child_w, &child_h);
1105 new_w = child_w;
1106 new_h = child_h;
1107
1108 _layout_set_offset_and_expand_dimension_space_max_bounded
1109 (child_w, &new_w, w, max_w, &off_x, align_x, padding_l, padding_r);
1110
1111 _layout_set_offset_and_change_dimension_min_max_cell_bounded
1112 (child_h, &new_h, min_h, max_h, cell_sz, &off_y, align_y,
1113 padding_t, padding_b);
1114
1115 if ((new_w != child_w) || (new_h != child_h))
1116 evas_object_resize(opt->obj, new_w, new_h);
1117 evas_object_move(opt->obj, x + off_x, y + off_y);
1118
1119 y += cell_sz + priv->pad.v;
1120 sub_pixel += inc;
1121 if (sub_pixel >= 1 << 16)
1122 {
1123 y++;
1124 sub_pixel -= 1 << 16;
1125 }
1126 }
1127
1128 evas_object_size_hint_min_set(o, w, h);
1129}
1130
1131EAPI void
1132evas_object_box_layout_homogeneous_max_size_horizontal(Evas_Object *o, Evas_Object_Box_Data *priv, void *data __UNUSED__)
1133{
1134 int remaining, global_pad, pad_inc = 0, sub_pixel = 0;
1135 int cell_sz = 0;
1136 int x, y, w, h;
1137 int top_h = 0;
1138 int n_children;
1139 Evas_Object_Box_Option *opt;
1140 Eina_List *l;
1141
1142 n_children = eina_list_count(priv->children);
1143 if (!n_children)
1144 return;
1145
1146 evas_object_geometry_get(o, &x, &y, &w, &h);
1147
1148 EINA_LIST_FOREACH(priv->children, l, opt)
1149 {
1150 int child_w, padding_l, padding_r;
1151
1152 _sizing_eval(opt->obj);
1153 evas_object_size_hint_padding_get
1154 (opt->obj, &padding_l, &padding_r, NULL, NULL);
1155 evas_object_geometry_get(opt->obj, NULL, NULL, &child_w, NULL);
1156 if (child_w + padding_l + padding_r > cell_sz)
1157 cell_sz = child_w + padding_l + padding_r;
1158 }
1159
1160 global_pad = priv->pad.h;
1161 remaining = w - n_children * cell_sz - global_pad * (n_children - 1);
1162
1163 if (priv->align.h >= 0.0)
1164 x += remaining * priv->align.h;
1165 else if (n_children == 1)
1166 x += remaining / 2;
1167 else
1168 { /* justified */
1169 _fixed_point_divide_and_decompose_integer
1170 (remaining, n_children - 1, &global_pad, &pad_inc);
1171 global_pad += priv->pad.h;
1172 }
1173
1174 EINA_LIST_FOREACH(priv->children, l, opt)
1175 {
1176 int child_w, child_h, min_w, max_w, max_h, new_w, new_h, off_x, off_y;
1177 int padding_l, padding_r, padding_t, padding_b;
1178 double align_x, align_y;
1179
1180 evas_object_size_hint_align_get(opt->obj, &align_x, &align_y);
1181 evas_object_size_hint_padding_get
1182 (opt->obj, &padding_l, &padding_r, &padding_t, &padding_b);
1183 evas_object_size_hint_max_get(opt->obj, &max_w, &max_h);
1184 evas_object_size_hint_min_get(opt->obj, &min_w, NULL);
1185
1186 evas_object_geometry_get(opt->obj, NULL, NULL, &child_w, &child_h);
1187
1188 new_w = child_w;
1189 new_h = child_h;
1190 if (new_h > top_h) top_h = new_h;
1191
1192 _layout_set_offset_and_expand_dimension_space_max_bounded
1193 (child_h, &new_h, h, max_h, &off_y, align_y, padding_t, padding_b);
1194
1195 _layout_set_offset_and_change_dimension_min_max_cell_bounded
1196 (child_w, &new_w, min_w, max_w, cell_sz, &off_x, align_x,
1197 padding_l, padding_r);
1198
1199 if ((new_w != child_w) || (new_h != child_h))
1200 evas_object_resize(opt->obj, new_w, new_h);
1201 evas_object_move(opt->obj, x + off_x, y + off_y);
1202
1203 x += cell_sz + global_pad;
1204 sub_pixel += pad_inc;
1205 if (sub_pixel >= 1 << 16)
1206 {
1207 x++;
1208 sub_pixel -= 1 << 16;
1209 }
1210 }
1211
1212 evas_object_size_hint_min_set(o, x, top_h);
1213}
1214
1215EAPI void
1216evas_object_box_layout_homogeneous_max_size_vertical(Evas_Object *o, Evas_Object_Box_Data *priv, void *data __UNUSED__)
1217{
1218 int remaining, global_pad, pad_inc = 0, sub_pixel = 0;
1219 int cell_sz = 0;
1220 int x, y, w, h;
1221 int top_w = 0;
1222 int n_children;
1223 Evas_Object_Box_Option *opt;
1224 Eina_List *l;
1225
1226 n_children = eina_list_count(priv->children);
1227 if (!n_children)
1228 return;
1229
1230 evas_object_geometry_get(o, &x, &y, &w, &h);
1231
1232 EINA_LIST_FOREACH(priv->children, l, opt)
1233 {
1234 int child_h, padding_t, padding_b;
1235
1236 _sizing_eval(opt->obj);
1237 evas_object_size_hint_padding_get
1238 (opt->obj, NULL, NULL, &padding_t, &padding_b);
1239 evas_object_geometry_get(opt->obj, NULL, NULL, NULL, &child_h);
1240 if (child_h + padding_t + padding_b > cell_sz)
1241 cell_sz = child_h + padding_t + padding_b;
1242 }
1243
1244 global_pad = priv->pad.v;
1245 remaining = h - n_children * cell_sz - global_pad * (n_children - 1);
1246
1247 if (priv->align.v >= 0.0)
1248 y += remaining * priv->align.v;
1249 else if (n_children == 1)
1250 y += remaining / 2;
1251 else
1252 { /* justified */
1253 _fixed_point_divide_and_decompose_integer
1254 (remaining, n_children - 1, &global_pad, &pad_inc);
1255 global_pad += priv->pad.v;
1256 }
1257
1258 EINA_LIST_FOREACH(priv->children, l, opt)
1259 {
1260 int child_w, child_h, max_h, min_h, max_w, new_w, new_h, off_x, off_y;
1261 int padding_l, padding_r, padding_t, padding_b;
1262 double align_x, align_y;
1263
1264 evas_object_size_hint_align_get(opt->obj, &align_x, &align_y);
1265 evas_object_size_hint_padding_get
1266 (opt->obj, &padding_l, &padding_r, &padding_t, &padding_b);
1267 evas_object_size_hint_max_get(opt->obj, &max_w, &max_h);
1268 evas_object_size_hint_min_get(opt->obj, NULL, &min_h);
1269
1270 evas_object_geometry_get(opt->obj, NULL, NULL, &child_w, &child_h);
1271
1272 new_w = child_w;
1273 new_h = child_h;
1274 if (new_w > top_w) top_w = new_w;
1275
1276 _layout_set_offset_and_expand_dimension_space_max_bounded
1277 (child_w, &new_w, w, max_w, &off_x, align_x, padding_l, padding_r);
1278
1279 _layout_set_offset_and_change_dimension_min_max_cell_bounded
1280 (child_h, &new_h, min_h, max_h, cell_sz, &off_y, align_y,
1281 padding_t, padding_b);
1282
1283 if ((new_w != child_w) || (new_h != child_h))
1284 evas_object_resize(opt->obj, new_w, new_h);
1285 evas_object_move(opt->obj, x + off_x, y + off_y);
1286
1287 y += cell_sz + global_pad;
1288 sub_pixel += pad_inc;
1289 if (sub_pixel >= 1 << 16)
1290 {
1291 y++;
1292 sub_pixel -= 1 << 16;
1293 }
1294 }
1295
1296 evas_object_size_hint_min_set(o, top_w, y);
1297}
1298
1299static void
1300_evas_object_box_layout_flow_horizontal_row_info_collect(Evas_Object_Box_Data *priv, int box_w, int *row_count, int *row_max_h, int *row_break, int *row_width, int *off_y_ret, int *max_h_ret)
1301{
1302 int i, remain_w = box_w, start_i = 0;
1303 int off_y = 0, max_h = 0, n_rows = 0;
1304 Eina_List *l;
1305
1306 for (i = 0, l = priv->children; l; i++, l = l->next)
1307 {
1308 Evas_Object_Box_Option *opt = l->data;
1309 int padding_l, padding_r, padding_t, padding_b;
1310 int child_w, child_h, off_x = 0;
1311
1312 evas_object_size_hint_padding_get
1313 (opt->obj, &padding_l, &padding_r, &padding_t, &padding_b);
1314
1315 _sizing_eval(opt->obj);
1316 evas_object_geometry_get(opt->obj, NULL, NULL, &child_w, &child_h);
1317
1318 child_w += padding_l + padding_r + priv->pad.h;
1319 child_h += padding_t + padding_b;
1320
1321 remain_w -= child_w;
1322 if (remain_w + priv->pad.h >= 0)
1323 { /* continue "line" */
1324 if (child_h > max_h)
1325 max_h = child_h;
1326
1327 off_x += child_w;
1328 row_width[n_rows] += child_w;
1329 }
1330 else
1331 { /* break line */
1332 if (i == start_i)
1333 { /* obj goes to actual line */
1334 max_h = child_h;
1335 row_width[n_rows] = child_w;
1336 }
1337 else
1338 { /* obj goes to next line */
1339 row_max_h[n_rows] = max_h;
1340 row_break[n_rows] = i - 1;
1341 n_rows++;
1342
1343 off_x = child_w;
1344 off_y += max_h;
1345 max_h = child_h;
1346
1347 row_width[n_rows] = child_w;
1348 start_i = i;
1349
1350 remain_w = box_w - off_x;
1351 }
1352 }
1353 }
1354
1355 row_break[n_rows] = i - 1;
1356 row_max_h[n_rows] = max_h;
1357
1358 *row_count = n_rows;
1359 *off_y_ret = off_y;
1360 *max_h_ret = max_h;
1361}
1362
1363EAPI void
1364evas_object_box_layout_flow_horizontal(Evas_Object *o, Evas_Object_Box_Data *priv, void *data __UNUSED__)
1365{
1366 int n_children;
1367 int r, row_count = 0;
1368 int min_w = 0, min_h = 0;
1369 int max_h, inc_y;
1370 int remain_y, i;
1371 int x, y, w, h;
1372 Eina_List *l;
1373 int *row_max_h;
1374 int *row_break;
1375 int *row_width;
1376 int offset_y;
1377
1378 n_children = eina_list_count(priv->children);
1379 if (!n_children)
1380 return;
1381
1382 /* *per row* arrays */
1383 row_max_h = (int *)alloca(sizeof(int) * n_children);
1384 if (!row_max_h)
1385 return;
1386 row_break = (int *)alloca(sizeof(int) * n_children);
1387 if (!row_break)
1388 return;
1389 row_width = (int *)alloca(sizeof(int) * n_children);
1390 if (!row_width)
1391 return;
1392
1393 memset(row_width, 0, sizeof(row_width));
1394
1395 evas_object_geometry_get(o, &x, &y, &w, &h);
1396
1397 _evas_object_box_layout_flow_horizontal_row_info_collect
1398 (priv, w, &row_count, row_max_h, row_break, row_width, &offset_y, &max_h);
1399
1400 inc_y = 0;
1401 remain_y = h - (offset_y + max_h);
1402
1403 if (remain_y > 0)
1404 {
1405 if (priv->align.v >= 0.0)
1406 inc_y = priv->align.v * remain_y;
1407 else if (row_count == 0)
1408 y += remain_y / 2;
1409 else /* y-justified */
1410 inc_y = remain_y / row_count;
1411 }
1412
1413 inc_y += priv->pad.v;
1414
1415 for (i = 0, r = 0, l = priv->children; r <= row_count; r++)
1416 {
1417 int row_justify = 0, just_inc = 0, sub_pixel = 0;
1418 int row_size, remain_x;
1419
1420 row_size = row_break[r] - i;
1421 remain_x = (w - row_width[r]);
1422
1423 if (priv->align.h < 0.0)
1424 {
1425 if (row_size == 0)
1426 x += remain_x / 2;
1427 else
1428 _fixed_point_divide_and_decompose_integer
1429 (remain_x, row_size, &row_justify, &just_inc);
1430 }
1431
1432 row_justify += priv->pad.h;
1433
1434 for (; i <= row_break[r]; i++, l = l->next)
1435 {
1436 Evas_Object_Box_Option *opt = l->data;
1437 int off_x, off_y, y_remain;
1438 int padding_l, padding_r;
1439 int child_w, child_h;
1440 double align_y;
1441
1442 evas_object_size_hint_align_get(opt->obj, NULL, &align_y);
1443 evas_object_size_hint_padding_get
1444 (opt->obj, &padding_l, &padding_r, NULL, NULL);
1445
1446 evas_object_geometry_get
1447 (opt->obj, NULL, NULL, &child_w, &child_h);
1448
1449 y_remain = row_max_h[r] - child_h;
1450
1451 off_x = padding_l;
1452 if (priv->align.h >= 0.0)
1453 off_x += remain_x * priv->align.h;
1454 off_y = y_remain * align_y;
1455
1456 evas_object_move(opt->obj, x + off_x, y + off_y);
1457
1458 x += child_w + padding_l + padding_r + row_justify;
1459
1460 sub_pixel += just_inc;
1461 if (sub_pixel >= 1 << 16)
1462 {
1463 x++;
1464 sub_pixel -= 1 << 16;
1465 }
1466 }
1467
1468 evas_object_geometry_get(o, &x, NULL, NULL, NULL);
1469 if (min_w < row_width[r])
1470 min_w = row_width[r];
1471 min_h += row_max_h[r];
1472 y += row_max_h[r] + inc_y;
1473 }
1474
1475 evas_object_size_hint_min_set(o, min_w, min_h);
1476}
1477
1478static void
1479_evas_object_box_layout_flow_vertical_col_info_collect(Evas_Object_Box_Data *priv, int box_h, int *col_count, int *col_max_w, int *col_break, int *col_height, int *off_x_ret, int *max_w_ret)
1480{
1481 int i, remain_h = box_h, start_i = 0;
1482 int off_x = 0, max_w = 0, n_cols = 0;
1483 Eina_List *l;
1484
1485 for (i = 0, l = priv->children; l; i++, l = l->next)
1486 {
1487 Evas_Object_Box_Option *opt = l->data;
1488 int padding_l, padding_r, padding_t, padding_b;
1489 int child_w, child_h, off_y = 0;
1490
1491 evas_object_size_hint_padding_get
1492 (opt->obj, &padding_l, &padding_r, &padding_t, &padding_b);
1493
1494 _sizing_eval(opt->obj);
1495 evas_object_geometry_get(opt->obj, NULL, NULL, &child_w, &child_h);
1496
1497 child_w += padding_l + padding_r;
1498 child_h += padding_t + padding_b + priv->pad.v;
1499
1500 remain_h -= child_h;
1501 if (remain_h + priv->pad.v >= 0)
1502 { /* continue "col" */
1503 if (child_w > max_w)
1504 max_w = child_w;
1505
1506 off_y += child_h;
1507 col_height[n_cols] += child_h;
1508 }
1509 else
1510 {
1511 /* break col */
1512 if (i == start_i)
1513 { /* obj goes to actual col */
1514 max_w = child_w;
1515 col_height[n_cols] = child_h;
1516 }
1517 else
1518 { /* obj goes to next col */
1519 col_max_w[n_cols] = max_w;
1520 col_break[n_cols] = i - 1;
1521 n_cols++;
1522
1523 off_x += max_w;
1524 off_y = child_h;
1525 max_w = child_w;
1526
1527 col_height[n_cols] = child_h;
1528 start_i = i;
1529
1530 remain_h = box_h - off_y;
1531 }
1532 }
1533 }
1534
1535 col_break[n_cols] = i - 1;
1536 col_max_w[n_cols] = max_w;
1537
1538 *col_count = n_cols;
1539 *off_x_ret = off_x;
1540 *max_w_ret = max_w;
1541}
1542
1543EAPI void
1544evas_object_box_layout_flow_vertical(Evas_Object *o, Evas_Object_Box_Data *priv, void *data __UNUSED__)
1545{
1546 int n_children;
1547 int c, col_count;
1548 int min_w = 0, min_h = 0;
1549 int max_w, inc_x;
1550 int remain_x, i;
1551 int x, y, w, h;
1552 Eina_List *l;
1553 int *col_max_w;
1554 int *col_break;
1555 int *col_height;
1556 int offset_x;
1557
1558 n_children = eina_list_count(priv->children);
1559 if (!n_children)
1560 return;
1561
1562 /* *per col* arrays */
1563 col_max_w = (int *)alloca(sizeof(int) * n_children);
1564 if (!col_max_w)
1565 return;
1566 col_break = (int *)alloca(sizeof(int) * n_children);
1567 if (!col_break)
1568 return;
1569 col_height = (int *)alloca(sizeof(int) * n_children);
1570 if (!col_height)
1571 return;
1572
1573 memset(col_height, 0, sizeof(col_height));
1574
1575 evas_object_geometry_get(o, &x, &y, &w, &h);
1576
1577 _evas_object_box_layout_flow_vertical_col_info_collect
1578 (priv, h, &col_count, col_max_w, col_break, col_height, &offset_x, &max_w);
1579
1580 inc_x = 0;
1581 remain_x = w - (offset_x + max_w);
1582
1583 if (remain_x > 0)
1584 {
1585 if (priv->align.h >= 0)
1586 inc_x = priv->align.h * remain_x;
1587 else if (col_count == 0)
1588 x += remain_x / 2;
1589 else /* x-justified */
1590 inc_x = remain_x / col_count;
1591 }
1592
1593 inc_x += priv->pad.h;
1594
1595 for (i = 0, c = 0, l = priv->children; c <= col_count; c++)
1596 {
1597 int col_justify = 0, just_inc = 0, sub_pixel = 0;
1598 int col_size, remain_y;
1599
1600 col_size = col_break[c] - i;
1601 remain_y = (h - col_height[c]);
1602
1603 if (priv->align.v < 0.0)
1604 {
1605 if (col_size == 0)
1606 y += remain_y / 2;
1607 else
1608 _fixed_point_divide_and_decompose_integer
1609 (remain_y, col_size, &col_justify, &just_inc);
1610 }
1611
1612 col_justify += priv->pad.v;
1613
1614 for (; i <= col_break[c]; i++, l = l->next)
1615 {
1616 Evas_Object_Box_Option *opt = l->data;
1617 int off_x, off_y, x_remain;
1618 int padding_t, padding_b;
1619 int child_w, child_h;
1620 double align_x;
1621
1622 evas_object_size_hint_align_get(opt->obj, &align_x, NULL);
1623 evas_object_size_hint_padding_get
1624 (opt->obj, NULL, NULL, &padding_t, &padding_b);
1625
1626 evas_object_geometry_get
1627 (opt->obj, NULL, NULL, &child_w, &child_h);
1628
1629 x_remain = col_max_w[c] - child_w;
1630
1631 off_x = x_remain * align_x;
1632 off_y = padding_t;
1633 if (priv->align.v >= 0.0)
1634 off_y += remain_y * priv->align.v;
1635
1636 evas_object_move(opt->obj, x + off_x, y + off_y);
1637
1638 y += child_h + padding_t + padding_b + col_justify;
1639
1640 sub_pixel += just_inc;
1641 if (sub_pixel >= 1 << 16)
1642 {
1643 y++;
1644 sub_pixel -= 1 << 16;
1645 }
1646 }
1647
1648 evas_object_geometry_get(o, NULL, &y, NULL, NULL);
1649 min_w += col_max_w[c];
1650 if (min_h < col_height[c])
1651 min_h = col_height[c];
1652 x += col_max_w[c] + inc_x;
1653 }
1654
1655 evas_object_size_hint_min_set(o, min_w, min_h);
1656}
1657
1658EAPI void
1659evas_object_box_layout_stack(Evas_Object *o, Evas_Object_Box_Data *priv, void *data __UNUSED__)
1660{
1661 Eina_List *l;
1662 Evas_Coord ox, oy, ow, oh;
1663 Evas_Coord top_w = 0, top_h = 0;
1664 Evas_Object_Box_Option *opt;
1665 Evas_Object *old_child = NULL;
1666
1667 evas_object_geometry_get(o, &ox, &oy, &ow, &oh);
1668
1669 EINA_LIST_FOREACH(priv->children, l, opt)
1670 {
1671 Evas_Object *child = opt->obj;
1672 Evas_Coord max_w, max_h, min_w, min_h, pad_l, pad_r, pad_t, pad_b,
1673 child_w, child_h, new_w, new_h, off_x, off_y;
1674 double align_x, align_y;
1675
1676 evas_object_size_hint_align_get(child, &align_x, &align_y);
1677 evas_object_size_hint_padding_get
1678 (child, &pad_l, &pad_r, &pad_t, &pad_b);
1679 evas_object_size_hint_max_get(child, &max_w, &max_h);
1680 evas_object_size_hint_min_get(child, &min_w, &min_h);
1681
1682 _sizing_eval(opt->obj);
1683 evas_object_geometry_get(child, NULL, NULL, &child_w, &child_h);
1684 new_w = child_w;
1685 new_h = child_h;
1686 if (new_w > top_w) top_w = new_w;
1687 if (new_h > top_h) top_h = new_h;
1688
1689 _layout_set_offset_and_change_dimension_min_max_cell_bounded
1690 (child_w, &new_w, min_w, max_w, ow, &off_x, align_x, pad_l, pad_r);
1691 _layout_set_offset_and_change_dimension_min_max_cell_bounded
1692 (child_h, &new_h, min_h, max_h, oh, &off_y, align_y, pad_t, pad_b);
1693
1694 if ((new_w != child_w) || (new_h != child_h))
1695 evas_object_resize(child, new_w, new_h);
1696 evas_object_move(child, ox + off_x, oy + off_y);
1697
1698 if (old_child)
1699 evas_object_stack_above(child, old_child);
1700 old_child = child;
1701 }
1702
1703 evas_object_size_hint_min_set(o, top_w, top_h);
1704}
1705
1706EAPI void
1707evas_object_box_align_set(Evas_Object *o, double horizontal, double vertical)
1708{
1709 EVAS_OBJECT_BOX_DATA_GET_OR_RETURN(o, priv);
1710 if (priv->align.h == horizontal && priv->align.v == vertical)
1711 return;
1712 priv->align.h = horizontal;
1713 priv->align.v = vertical;
1714 evas_object_smart_changed(o);
1715}
1716
1717EAPI void
1718evas_object_box_align_get(const Evas_Object *o, double *horizontal, double *vertical)
1719{
1720 EVAS_OBJECT_BOX_DATA_GET(o, priv);
1721 if (priv)
1722 {
1723 if (horizontal) *horizontal = priv->align.h;
1724 if (vertical) *vertical = priv->align.v;
1725 }
1726 else
1727 {
1728 if (horizontal) *horizontal = 0.5;
1729 if (vertical) *vertical = 0.5;
1730 }
1731}
1732
1733EAPI void
1734evas_object_box_padding_set(Evas_Object *o, Evas_Coord horizontal, Evas_Coord vertical)
1735{
1736 EVAS_OBJECT_BOX_DATA_GET_OR_RETURN(o, priv);
1737 if (priv->pad.h == horizontal && priv->pad.v == vertical)
1738 return;
1739 priv->pad.h = horizontal;
1740 priv->pad.v = vertical;
1741 evas_object_smart_changed(o);
1742}
1743
1744EAPI void
1745evas_object_box_padding_get(const Evas_Object *o, Evas_Coord *horizontal, Evas_Coord *vertical)
1746{
1747 EVAS_OBJECT_BOX_DATA_GET(o, priv);
1748 if (priv)
1749 {
1750 if (horizontal) *horizontal = priv->pad.h;
1751 if (vertical) *vertical = priv->pad.v;
1752 }
1753 else
1754 {
1755 if (horizontal) *horizontal = 0;
1756 if (vertical) *vertical = 0;
1757 }
1758}
1759
1760EAPI Evas_Object_Box_Option *
1761evas_object_box_append(Evas_Object *o, Evas_Object *child)
1762{
1763 Evas_Object_Box_Option *opt;
1764 const Evas_Object_Box_Api *api;
1765
1766 EVAS_OBJECT_BOX_DATA_GET_OR_RETURN_VAL(o, priv, 0);
1767 if (!child)
1768 return NULL;
1769
1770 api = priv->api;
1771 if ((!api) || (!api->append))
1772 return NULL;
1773
1774 opt = api->append(o, priv, child);
1775
1776 if (opt)
1777 {
1778 evas_object_smart_member_add(child, o);
1779 evas_object_smart_changed(o);
1780 return _evas_object_box_option_callbacks_register(o, priv, opt);
1781 }
1782
1783 return NULL;
1784}
1785
1786EAPI Evas_Object_Box_Option *
1787evas_object_box_prepend(Evas_Object *o, Evas_Object *child)
1788{
1789 Evas_Object_Box_Option *opt;
1790 const Evas_Object_Box_Api *api;
1791
1792 EVAS_OBJECT_BOX_DATA_GET_OR_RETURN_VAL(o, priv, 0);
1793 if (!child)
1794 return NULL;
1795
1796 api = priv->api;
1797 if ((!api) || (!api->prepend))
1798 return NULL;
1799
1800 opt = api->prepend(o, priv, child);
1801
1802 if (opt)
1803 {
1804 evas_object_smart_member_add(child, o);
1805 evas_object_smart_changed(o);
1806 return _evas_object_box_option_callbacks_register(o, priv, opt);
1807 }
1808
1809 return NULL;
1810}
1811
1812EAPI Evas_Object_Box_Option *
1813evas_object_box_insert_before(Evas_Object *o, Evas_Object *child, const Evas_Object *reference)
1814{
1815 Evas_Object_Box_Option *opt;
1816 const Evas_Object_Box_Api *api;
1817
1818 EVAS_OBJECT_BOX_DATA_GET_OR_RETURN_VAL(o, priv, 0);
1819 if (!child)
1820 return NULL;
1821
1822 api = priv->api;
1823 if ((!api) || (!api->insert_before))
1824 return NULL;
1825
1826 opt = api->insert_before(o, priv, child, reference);
1827
1828 if (opt)
1829 {
1830 evas_object_smart_member_add(child, o);
1831 evas_object_smart_changed(o);
1832 return _evas_object_box_option_callbacks_register(o, priv, opt);
1833 }
1834
1835 return NULL;
1836}
1837
1838EAPI Evas_Object_Box_Option *
1839evas_object_box_insert_after(Evas_Object *o, Evas_Object *child, const Evas_Object *reference)
1840{
1841 Evas_Object_Box_Option *opt;
1842 const Evas_Object_Box_Api *api;
1843
1844 EVAS_OBJECT_BOX_DATA_GET_OR_RETURN_VAL(o, priv, NULL);
1845 if (!child)
1846 return NULL;
1847
1848 api = priv->api;
1849 if ((!api) || (!api->insert_after))
1850 return NULL;
1851
1852 opt = api->insert_after(o, priv, child, reference);
1853
1854 if (opt)
1855 {
1856 evas_object_smart_member_add(child, o);
1857 evas_object_smart_changed(o);
1858 return _evas_object_box_option_callbacks_register(o, priv, opt);
1859 }
1860
1861 return NULL;
1862}
1863
1864EAPI Evas_Object_Box_Option *
1865evas_object_box_insert_at(Evas_Object *o, Evas_Object *child, unsigned int pos)
1866{
1867 Evas_Object_Box_Option *opt;
1868 const Evas_Object_Box_Api *api;
1869
1870 EVAS_OBJECT_BOX_DATA_GET_OR_RETURN_VAL(o, priv, 0);
1871 if (!child)
1872 return NULL;
1873
1874 api = priv->api;
1875 if ((!api) || (!api->insert_at))
1876 return NULL;
1877
1878 opt = api->insert_at(o, priv, child, pos);
1879
1880 if (opt)
1881 {
1882 evas_object_smart_member_add(child, o);
1883 evas_object_smart_changed(o);
1884 return _evas_object_box_option_callbacks_register(o, priv, opt);
1885 }
1886
1887 return NULL;
1888}
1889
1890EAPI Eina_Bool
1891evas_object_box_remove(Evas_Object *o, Evas_Object *child)
1892{
1893 const Evas_Object_Box_Api *api;
1894 Evas_Object *obj;
1895
1896 EVAS_OBJECT_BOX_DATA_GET_OR_RETURN_VAL(o, priv, 0);
1897 if (!child) return EINA_FALSE;
1898
1899 api = priv->api;
1900 if ((!api) || (!api->remove))
1901 return 0;
1902
1903 obj = api->remove(o, priv, child);
1904
1905 if (obj)
1906 {
1907 _evas_object_box_child_callbacks_unregister(obj);
1908 evas_object_smart_member_del(obj);
1909 evas_object_smart_changed(o);
1910 return EINA_TRUE;
1911 }
1912
1913 return EINA_FALSE;
1914}
1915
1916EAPI Eina_Bool
1917evas_object_box_remove_at(Evas_Object *o, unsigned int pos)
1918{
1919 const Evas_Object_Box_Api *api;
1920 Evas_Object *obj;
1921
1922 EVAS_OBJECT_BOX_DATA_GET_OR_RETURN_VAL(o, priv, 0);
1923 api = priv->api;
1924 if ((!api) || (!api->remove_at)) return EINA_FALSE;
1925
1926 obj = api->remove_at(o, priv, pos);
1927
1928 if (obj)
1929 {
1930 _evas_object_box_child_callbacks_unregister(obj);
1931 evas_object_smart_member_del(obj);
1932 evas_object_smart_changed(o);
1933 return EINA_TRUE;
1934 }
1935
1936 return EINA_FALSE;
1937}
1938
1939EAPI Eina_Bool
1940evas_object_box_remove_all(Evas_Object *o, Eina_Bool clear)
1941{
1942 const Evas_Object_Box_Api *api;
1943
1944 EVAS_OBJECT_BOX_DATA_GET_OR_RETURN_VAL(o, priv, 0);
1945
1946 api = priv->api;
1947 if ((!api) || (!api->remove)) return EINA_FALSE;
1948
1949 evas_object_smart_changed(o);
1950
1951 while (priv->children)
1952 {
1953 Evas_Object_Box_Option *opt = priv->children->data;
1954 Evas_Object *obj;
1955
1956 obj = api->remove(o, priv, opt->obj);
1957 if (obj)
1958 {
1959 _evas_object_box_child_callbacks_unregister(obj);
1960 evas_object_smart_member_del(obj);
1961 if (clear)
1962 evas_object_del(obj);
1963 }
1964 else return EINA_FALSE;
1965 }
1966
1967 return EINA_TRUE;
1968}
1969
1970EAPI Eina_Iterator *
1971evas_object_box_iterator_new(const Evas_Object *o)
1972{
1973 Evas_Object_Box_Iterator *it;
1974
1975 EVAS_OBJECT_BOX_DATA_GET_OR_RETURN_VAL(o, priv, NULL);
1976
1977 if (!priv->children) return NULL;
1978
1979 it = calloc(1, sizeof(Evas_Object_Box_Iterator));
1980 if (!it) return NULL;
1981
1982 EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR);
1983
1984 it->real_iterator = eina_list_iterator_new(priv->children);
1985 it->box = o;
1986
1987 it->iterator.next = FUNC_ITERATOR_NEXT(_evas_object_box_iterator_next);
1988 it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(_evas_object_box_iterator_get_container);
1989 it->iterator.free = FUNC_ITERATOR_FREE(_evas_object_box_iterator_free);
1990
1991 return &it->iterator;
1992}
1993
1994EAPI Eina_Accessor *
1995evas_object_box_accessor_new(const Evas_Object *o)
1996{
1997 Evas_Object_Box_Accessor *it;
1998
1999 EVAS_OBJECT_BOX_DATA_GET_OR_RETURN_VAL(o, priv, NULL);
2000
2001 if (!priv->children) return NULL;
2002
2003 it = calloc(1, sizeof(Evas_Object_Box_Accessor));
2004 if (!it) return NULL;
2005
2006 EINA_MAGIC_SET(&it->accessor, EINA_MAGIC_ACCESSOR);
2007
2008 it->real_accessor = eina_list_accessor_new(priv->children);
2009 it->box = o;
2010
2011 it->accessor.get_at = FUNC_ACCESSOR_GET_AT(_evas_object_box_accessor_get_at);
2012 it->accessor.get_container = FUNC_ACCESSOR_GET_CONTAINER(_evas_object_box_accessor_get_container);
2013 it->accessor.free = FUNC_ACCESSOR_FREE(_evas_object_box_accessor_free);
2014
2015 return &it->accessor;
2016}
2017
2018EAPI Eina_List *
2019evas_object_box_children_get(const Evas_Object *o)
2020{
2021 Eina_List *new_list = NULL, *l;
2022 Evas_Object_Box_Option *opt;
2023
2024 EVAS_OBJECT_BOX_DATA_GET_OR_RETURN_VAL(o, priv, NULL);
2025
2026 EINA_LIST_FOREACH(priv->children, l, opt)
2027 new_list = eina_list_append(new_list, opt->obj);
2028
2029 return new_list;
2030}
2031
2032EAPI const char *
2033evas_object_box_option_property_name_get(Evas_Object *o, int property)
2034{
2035 const Evas_Object_Box_Api *api;
2036
2037 EVAS_OBJECT_BOX_DATA_GET_OR_RETURN_VAL(o, priv, NULL);
2038
2039 if (property < 0)
2040 return NULL;
2041
2042 api = priv->api;
2043 if ((!api) || (!api->property_name_get))
2044 return NULL;
2045
2046 return api->property_name_get(o, property);
2047}
2048
2049EAPI int
2050evas_object_box_option_property_id_get(Evas_Object *o, const char *name)
2051{
2052 const Evas_Object_Box_Api *api;
2053
2054 EVAS_OBJECT_BOX_DATA_GET_OR_RETURN_VAL(o, priv, -1);
2055
2056 if (!name)
2057 return -1;
2058
2059 api = priv->api;
2060 if ((!api) || (!api->property_id_get))
2061 return -1;
2062
2063 return api->property_id_get(o, name);
2064}
2065
2066EAPI Eina_Bool
2067evas_object_box_option_property_set(Evas_Object *o, Evas_Object_Box_Option *opt, int property, ...)
2068{
2069 Eina_Bool ret;
2070 va_list args;
2071
2072 va_start(args, property);
2073 ret = evas_object_box_option_property_vset(o, opt, property, args);
2074 va_end(args);
2075
2076 return ret;
2077}
2078
2079
2080EAPI Eina_Bool
2081evas_object_box_option_property_vset(Evas_Object *o, Evas_Object_Box_Option *opt, int property, va_list args)
2082{
2083 const Evas_Object_Box_Api *api;
2084
2085 EVAS_OBJECT_BOX_DATA_GET_OR_RETURN_VAL(o, priv, 0);
2086
2087 if (!opt) return EINA_FALSE;
2088
2089 api = priv->api;
2090 if ((!api) || (!api->property_set))
2091 return EINA_FALSE;
2092
2093 if (!api->property_set(o, opt, property, args))
2094 return EINA_FALSE;
2095
2096 evas_object_smart_changed(o);
2097 return EINA_TRUE;
2098}
2099
2100EAPI Eina_Bool
2101evas_object_box_option_property_get(Evas_Object *o, Evas_Object_Box_Option *opt, int property, ...)
2102{
2103 Eina_Bool ret;
2104 va_list args;
2105
2106 va_start(args, property);
2107 ret = evas_object_box_option_property_vget(o, opt, property, args);
2108 va_end(args);
2109
2110 return ret;
2111}
2112
2113EAPI Eina_Bool
2114evas_object_box_option_property_vget(Evas_Object *o, Evas_Object_Box_Option *opt, int property, va_list args)
2115{
2116 const Evas_Object_Box_Api *api;
2117
2118 EVAS_OBJECT_BOX_DATA_GET_OR_RETURN_VAL(o, priv, 0);
2119
2120 if (!opt) return EINA_FALSE;
2121
2122 api = priv->api;
2123 if ((!api) || (!api->property_get))
2124 return EINA_FALSE;
2125
2126 return api->property_get(o, opt, property, args);
2127}