3 typedef struct _E_Smart_Data E_Smart_Data;
4 typedef struct _E_Flowlayout_Item E_Flowlayout_Item;
12 unsigned char changed : 1;
13 unsigned char horizontal : 1;
14 unsigned char homogenous : 1;
15 unsigned char fill : 1;
16 unsigned char flowright : 1;
17 unsigned char flowbottom : 1;
29 struct _E_Flowlayout_Item
32 unsigned char fill_w : 1;
33 unsigned char fill_h : 1;
34 unsigned char expand_w : 1;
35 unsigned char expand_h : 1;
45 /* local subsystem functions */
46 static E_Flowlayout_Item *_e_flowlayout_smart_adopt(E_Smart_Data *sd, Evas_Object *obj);
47 static void _e_flowlayout_smart_disown(Evas_Object *obj);
48 static void _e_flowlayout_smart_item_del_hook(void *data, Evas *e, Evas_Object *obj, void *event_info);
49 static void _e_flowlayout_smart_reconfigure(E_Smart_Data *sd);
50 static void _e_flowlayout_smart_extents_calcuate(E_Smart_Data *sd);
52 static void _e_flowlayout_smart_init(void);
53 static void _e_flowlayout_smart_add(Evas_Object *obj);
54 static void _e_flowlayout_smart_del(Evas_Object *obj);
55 static void _e_flowlayout_smart_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y);
56 static void _e_flowlayout_smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h);
57 static void _e_flowlayout_smart_show(Evas_Object *obj);
58 static void _e_flowlayout_smart_hide(Evas_Object *obj);
59 static void _e_flowlayout_smart_color_set(Evas_Object *obj, int r, int g, int b, int a);
60 static void _e_flowlayout_smart_clip_set(Evas_Object *obj, Evas_Object *clip);
61 static void _e_flowlayout_smart_clip_unset(Evas_Object *obj);
63 /* local subsystem globals */
64 static Evas_Smart *_e_smart = NULL;
66 /* externally accessible functions */
68 e_flowlayout_add(Evas *evas)
70 _e_flowlayout_smart_init();
71 return evas_object_smart_add(evas, _e_smart);
75 e_flowlayout_freeze(Evas_Object *obj)
79 sd = evas_object_smart_data_get(obj);
86 e_flowlayout_thaw(Evas_Object *obj)
90 sd = evas_object_smart_data_get(obj);
93 if (sd->frozen <= 0) _e_flowlayout_smart_reconfigure(sd);
98 e_flowlayout_orientation_set(Evas_Object *obj, int horizontal)
102 sd = evas_object_smart_data_get(obj);
104 if (((sd->horizontal) && (horizontal)) ||
105 ((!sd->horizontal) && (!horizontal))) return;
106 sd->horizontal = horizontal;
108 if (sd->frozen <= 0) _e_flowlayout_smart_reconfigure(sd);
112 e_flowlayout_orientation_get(Evas_Object *obj)
116 sd = evas_object_smart_data_get(obj);
118 return sd->horizontal;
122 e_flowlayout_flowdirection_set(Evas_Object *obj, int right, int bottom)
126 sd = evas_object_smart_data_get(obj);
128 if ((((sd->flowbottom) && (bottom)) ||
129 ((!sd->flowbottom) && (!bottom))) &&
130 (((sd->flowright) && (right)) ||
131 ((!sd->flowright) && (!right)))) return;
132 sd->flowright = right;
133 sd->flowbottom = bottom;
135 if (sd->frozen <= 0) _e_flowlayout_smart_reconfigure(sd);
139 e_flowlayout_flowdirection_get(Evas_Object *obj, int *right, int *bottom)
143 sd = evas_object_smart_data_get(obj);
145 if (right) *right = sd->flowright;
146 if (bottom) *bottom = sd->flowright;
150 e_flowlayout_homogenous_set(Evas_Object *obj, int homogenous)
154 sd = evas_object_smart_data_get(obj);
156 if (sd->homogenous == homogenous) return;
157 sd->homogenous = homogenous;
159 if (sd->frozen <= 0) _e_flowlayout_smart_reconfigure(sd);
163 e_flowlayout_homogenous_get(Evas_Object *obj)
167 sd = evas_object_smart_data_get(obj);
169 return sd->homogenous;
173 e_flowlayout_fill_set(Evas_Object *obj, int fill)
177 sd = evas_object_smart_data_get(obj);
179 if (sd->fill == fill) return;
182 if (sd->frozen <= 0) _e_flowlayout_smart_reconfigure(sd);
186 e_flowlayout_fill_get(Evas_Object *obj)
190 sd = evas_object_smart_data_get(obj);
197 e_flowlayout_pack_start(Evas_Object *obj, Evas_Object *child)
201 sd = evas_object_smart_data_get(obj);
203 _e_flowlayout_smart_adopt(sd, child);
204 sd->items = eina_list_prepend(sd->items, child);
206 if (sd->frozen <= 0) _e_flowlayout_smart_reconfigure(sd);
211 e_flowlayout_pack_end(Evas_Object *obj, Evas_Object *child)
215 sd = evas_object_smart_data_get(obj);
217 _e_flowlayout_smart_adopt(sd, child);
218 sd->items = eina_list_append(sd->items, child);
220 if (sd->frozen <= 0) _e_flowlayout_smart_reconfigure(sd);
221 return eina_list_count(sd->items) - 1;
225 e_flowlayout_pack_before(Evas_Object *obj, Evas_Object *child, Evas_Object *before)
232 sd = evas_object_smart_data_get(obj);
234 _e_flowlayout_smart_adopt(sd, child);
235 sd->items = eina_list_prepend_relative(sd->items, child, before);
236 EINA_LIST_FOREACH(sd->items, l, item)
238 if (item == child) break;
242 if (sd->frozen <= 0) _e_flowlayout_smart_reconfigure(sd);
247 e_flowlayout_pack_after(Evas_Object *obj, Evas_Object *child, Evas_Object *after)
254 sd = evas_object_smart_data_get(obj);
256 _e_flowlayout_smart_adopt(sd, child);
257 sd->items = eina_list_append_relative(sd->items, child, after);
258 EINA_LIST_FOREACH(sd->items, l, item)
260 if (item == child) break;
264 if (sd->frozen <= 0) _e_flowlayout_smart_reconfigure(sd);
269 e_flowlayout_pack_count_get(Evas_Object *obj)
273 sd = evas_object_smart_data_get(obj);
275 return eina_list_count(sd->items);
279 e_flowlayout_pack_object_nth(Evas_Object *obj, int n)
283 sd = evas_object_smart_data_get(obj);
284 if (!sd) return NULL;
285 return eina_list_nth(sd->items, n);
289 e_flowlayout_pack_object_first(Evas_Object *obj)
293 sd = evas_object_smart_data_get(obj);
294 if (!sd) return NULL;
295 return eina_list_data_get(sd->items);
299 e_flowlayout_pack_object_last(Evas_Object *obj)
303 sd = evas_object_smart_data_get(obj);
304 if (!sd) return NULL;
305 return eina_list_data_get(eina_list_last(sd->items));
309 e_flowlayout_pack_options_set(Evas_Object *obj, int fill_w, int fill_h, int expand_w, int expand_h, double align_x, double align_y, Evas_Coord min_w, Evas_Coord min_h, Evas_Coord max_w, Evas_Coord max_h)
311 E_Flowlayout_Item *bi;
313 bi = evas_object_data_get(obj, "e_flowlayout_data");
317 bi->expand_w = expand_w;
318 bi->expand_h = expand_h;
319 bi->align.x = align_x;
320 bi->align.y = align_y;
326 if (bi->sd->frozen <= 0) _e_flowlayout_smart_reconfigure(bi->sd);
330 e_flowlayout_unpack(Evas_Object *obj)
332 E_Flowlayout_Item *bi;
335 bi = evas_object_data_get(obj, "e_flowlayout_data");
339 sd->items = eina_list_remove(sd->items, obj);
340 _e_flowlayout_smart_disown(obj);
342 if (sd->frozen <= 0) _e_flowlayout_smart_reconfigure(sd);
346 e_flowlayout_size_min_get(Evas_Object *obj, Evas_Coord *minw, Evas_Coord *minh)
350 sd = evas_object_smart_data_get(obj);
352 if (sd->changed) _e_flowlayout_smart_extents_calcuate(sd);
353 if (minw) *minw = sd->min.w;
354 if (minh) *minh = sd->min.h;
358 e_flowlayout_size_max_get(Evas_Object *obj, Evas_Coord *maxw, Evas_Coord *maxh)
362 sd = evas_object_smart_data_get(obj);
364 if (sd->changed) _e_flowlayout_smart_extents_calcuate(sd);
365 if (maxw) *maxw = sd->max.w;
366 if (maxh) *maxh = sd->max.h;
370 e_flowlayout_max_children(Evas_Object *obj)
374 sd = evas_object_smart_data_get(obj);
376 if (!sd->homogenous) return -1;
377 return (sd->rows * sd->cols);
380 e_flowlayout_align_get(Evas_Object *obj, double *ax, double *ay)
384 sd = evas_object_smart_data_get(obj);
386 if (ax) *ax = sd->align.x;
387 if (ay) *ay = sd->align.y;
391 e_flowlayout_align_set(Evas_Object *obj, double ax, double ay)
395 sd = evas_object_smart_data_get(obj);
397 if ((sd->align.x == ax) && (sd->align.y == ay)) return;
401 if (sd->frozen <= 0) _e_flowlayout_smart_reconfigure(sd);
404 /* local subsystem functions */
405 static E_Flowlayout_Item *
406 _e_flowlayout_smart_adopt(E_Smart_Data *sd, Evas_Object *obj)
408 E_Flowlayout_Item *bi;
410 bi = calloc(1, sizeof(E_Flowlayout_Item));
411 if (!bi) return NULL;
425 evas_object_clip_set(obj, sd->clip);
426 evas_object_smart_member_add(obj, bi->sd->obj);
427 evas_object_data_set(obj, "e_flowlayout_data", bi);
428 evas_object_event_callback_add(obj, EVAS_CALLBACK_FREE,
429 _e_flowlayout_smart_item_del_hook, NULL);
430 if ((!evas_object_visible_get(sd->clip)) &&
431 (evas_object_visible_get(sd->obj)))
432 evas_object_show(sd->clip);
437 _e_flowlayout_smart_disown(Evas_Object *obj)
439 E_Flowlayout_Item *bi;
441 bi = evas_object_data_get(obj, "e_flowlayout_data");
445 if (evas_object_visible_get(bi->sd->clip))
446 evas_object_hide(bi->sd->clip);
448 evas_object_event_callback_del(obj,
450 _e_flowlayout_smart_item_del_hook);
451 evas_object_smart_member_del(obj);
452 evas_object_clip_unset(obj);
453 evas_object_data_del(obj, "e_flowlayout_data");
458 _e_flowlayout_smart_item_del_hook(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
460 e_flowlayout_unpack(obj);
464 _e_flowlayout_smart_reconfigure(E_Smart_Data *sd)
466 Evas_Coord x, y, w, h, xx, yy, cr, cc;
473 if (!sd->changed) return;
475 /* local variables */
481 /* Calculate extents */
482 _e_flowlayout_smart_extents_calcuate(sd);
485 count = eina_list_count(sd->items);
488 /* Too small? move a little */
491 x = x + ((w - minw) * (1.0 - sd->align.x));
496 y = y + ((h - minh) * (1.0 - sd->align.y));
500 /* Some odd expanding counter */
501 EINA_LIST_FOREACH(sd->items, l, obj)
503 E_Flowlayout_Item *bi;
505 bi = evas_object_data_get(obj, "e_flowlayout_data");
510 if (bi->expand_w) expand++;
514 if (bi->expand_h) expand++;
519 /* If no expansion, w is minw, h is minh */
524 x += (double)(w - minw) * sd->align.x;
529 y += (double)(h - minh) * sd->align.y;
534 /* Some calculations */
546 /* Now for the real deal */
547 EINA_LIST_FOREACH(sd->items, l, obj)
549 E_Flowlayout_Item *bi;
551 bi = evas_object_data_get(obj, "e_flowlayout_data");
560 Evas_Coord ww, hh, ow, oh;
565 int num = count - (cr)*(sd->cols);
572 if (bi->fill_w) ow = ww;
573 if ((bi->max.w >= 0) && (bi->max.w < ow)) ow = bi->max.w;
575 if (bi->fill_h) oh = hh;
576 if ((bi->max.h >= 0) && (bi->max.h < oh)) oh = bi->max.h;
581 evas_object_move(obj,
582 xx + (Evas_Coord)(((double)(ww - ow)) * bi->align.x),
583 yy + (Evas_Coord)(((double)(hh - oh)) * bi->align.y));
587 evas_object_move(obj,
588 xx + (Evas_Coord)(((double)(ww - ow)) * bi->align.x),
589 yy - hh + (Evas_Coord)(((double)(hh - oh)) * bi->align.y));
591 evas_object_resize(obj, ow, oh);
598 evas_object_move(obj,
599 xx - ww + (Evas_Coord)(((double)(ww - ow)) * bi->align.x),
600 yy + (Evas_Coord)(((double)(hh - oh)) * bi->align.y));
604 evas_object_move(obj,
605 xx - ww + (Evas_Coord)(((double)(ww - ow)) * bi->align.x),
606 yy - hh + (Evas_Coord)(((double)(hh - oh)) * bi->align.y));
609 evas_object_resize(obj, ow, oh);
627 /* TODO Nonhomogenous Horizontal */
637 Evas_Coord ww, hh, ow, oh;
642 int num = count - (cc)*(sd->rows);
649 if (bi->fill_h) oh = hh;
650 if ((bi->max.h >= 0) && (bi->max.h < oh)) oh = bi->max.h;
652 if (bi->fill_w) ow = ww;
653 if ((bi->max.w >= 0) && (bi->max.w < ow)) ow = bi->max.w;
658 evas_object_move(obj,
659 xx + (Evas_Coord)(((double)(ww - ow)) * bi->align.x),
660 yy + (Evas_Coord)(((double)(hh - oh)) * bi->align.y));
664 evas_object_move(obj,
665 xx - ww + (Evas_Coord)(((double)(ww - ow)) * bi->align.x),
666 yy + (Evas_Coord)(((double)(hh - oh)) * bi->align.y));
668 evas_object_resize(obj, ow, oh);
675 evas_object_move(obj,
676 xx + (Evas_Coord)(((double)(ww - ow)) * bi->align.x),
677 yy - hh + (Evas_Coord)(((double)(hh - oh)) * bi->align.y));
681 evas_object_move(obj,
682 xx - ww + (Evas_Coord)(((double)(ww - ow)) * bi->align.x),
683 yy - hh + (Evas_Coord)(((double)(hh - oh)) * bi->align.y));
686 evas_object_resize(obj, ow, oh);
705 /* TODO Nonhomogeneous Vertical */
716 _e_flowlayout_smart_extents_calcuate(E_Smart_Data *sd)
720 int minw, minh, count;
722 /* FIXME: need to calc max */
723 sd->max.w = -1; /* max < 0 == unlimited */
730 EINA_LIST_FOREACH(sd->items, l, obj)
732 E_Flowlayout_Item *bi;
734 bi = evas_object_data_get(obj, "e_flowlayout_data");
739 if (minh < bi->min.h) minh = bi->min.h;
740 if (minw < bi->min.w) minw = bi->min.w;
744 if (minw < bi->min.w) minw = bi->min.w;
745 if (minh < bi->min.h) minh = bi->min.h;
751 sd->rows = sd->h/minh;
754 count = eina_list_count(sd->items);
755 sd->cols = sd->w/minw;
756 if (count < sd->cols) sd->cols = count;
769 sd->cols = sd->w/minw;
772 count = eina_list_count(sd->items);
773 sd->rows = sd->h/minh;
774 if (count < sd->cols) sd->rows = count;
789 /* TODO nonhomogenous */
792 EINA_LIST_FOREACH(sd->items, l, obj)
794 E_Flowlayout_Item *bi;
796 bi = evas_object_data_get(obj, "e_flowlayout_data");
801 if (minh < bi->min.h) minh = bi->min.h*sd->rows;
806 if (minw < bi->min.w) minw = bi->min.w*sd->cols;
813 sd->rows = sd->h/minh;
816 minw = minw/sd->cols + 0.2*minw;
820 sd->cols = sd->w/minw;
823 minh = minh/sd->cols + 0.2*minh;
835 _e_flowlayout_smart_init(void)
837 if (_e_smart) return;
839 static const Evas_Smart_Class sc =
842 EVAS_SMART_CLASS_VERSION,
843 _e_flowlayout_smart_add,
844 _e_flowlayout_smart_del,
845 _e_flowlayout_smart_move,
846 _e_flowlayout_smart_resize,
847 _e_flowlayout_smart_show,
848 _e_flowlayout_smart_hide,
849 _e_flowlayout_smart_color_set,
850 _e_flowlayout_smart_clip_set,
851 _e_flowlayout_smart_clip_unset,
860 _e_smart = evas_smart_class_new(&sc);
865 _e_flowlayout_smart_add(Evas_Object *obj)
869 sd = calloc(1, sizeof(E_Smart_Data));
878 sd->clip = evas_object_rectangle_add(evas_object_evas_get(obj));
879 evas_object_smart_member_add(sd->clip, obj);
880 evas_object_move(sd->clip, -100004, -100004);
881 evas_object_resize(sd->clip, 200008, 200008);
882 evas_object_color_set(sd->clip, 255, 255, 255, 255);
883 evas_object_smart_data_set(obj, sd);
887 _e_flowlayout_smart_del(Evas_Object *obj)
891 sd = evas_object_smart_data_get(obj);
893 /* FIXME: this gets into an infinite loop when changin basic->advanced on
900 child = eina_list_data_get(sd->items);
901 e_flowlayout_unpack(child);
903 evas_object_del(sd->clip);
908 _e_flowlayout_smart_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
912 sd = evas_object_smart_data_get(obj);
914 if ((x == sd->x) && (y == sd->y)) return;
922 EINA_LIST_FOREACH(sd->items, l, item)
926 evas_object_geometry_get(item, &ox, &oy, NULL, NULL);
927 evas_object_move(item, ox + dx, oy + dy);
935 _e_flowlayout_smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h)
939 sd = evas_object_smart_data_get(obj);
941 if ((w == sd->w) && (h == sd->h)) return;
945 _e_flowlayout_smart_reconfigure(sd);
949 _e_flowlayout_smart_show(Evas_Object *obj)
953 sd = evas_object_smart_data_get(obj);
955 if (sd->items) evas_object_show(sd->clip);
959 _e_flowlayout_smart_hide(Evas_Object *obj)
963 sd = evas_object_smart_data_get(obj);
965 evas_object_hide(sd->clip);
969 _e_flowlayout_smart_color_set(Evas_Object *obj, int r, int g, int b, int a)
973 sd = evas_object_smart_data_get(obj);
975 evas_object_color_set(sd->clip, r, g, b, a);
979 _e_flowlayout_smart_clip_set(Evas_Object *obj, Evas_Object *clip)
983 sd = evas_object_smart_data_get(obj);
985 evas_object_clip_set(sd->clip, clip);
989 _e_flowlayout_smart_clip_unset(Evas_Object *obj)
993 sd = evas_object_smart_data_get(obj);
995 evas_object_clip_unset(sd->clip);