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;
31 struct _E_Flowlayout_Item
34 unsigned char fill_w : 1;
35 unsigned char fill_h : 1;
36 unsigned char expand_w : 1;
37 unsigned char expand_h : 1;
49 /* local subsystem functions */
50 static E_Flowlayout_Item *_e_flowlayout_smart_adopt(E_Smart_Data *sd, Evas_Object *obj);
51 static void _e_flowlayout_smart_disown(Evas_Object *obj);
52 static void _e_flowlayout_smart_item_del_hook(void *data, Evas *e, Evas_Object *obj, void *event_info);
53 static void _e_flowlayout_smart_reconfigure(E_Smart_Data *sd);
54 static void _e_flowlayout_smart_extents_calcuate(E_Smart_Data *sd);
56 static void _e_flowlayout_smart_init(void);
57 static void _e_flowlayout_smart_add(Evas_Object *obj);
58 static void _e_flowlayout_smart_del(Evas_Object *obj);
59 static void _e_flowlayout_smart_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y);
60 static void _e_flowlayout_smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h);
61 static void _e_flowlayout_smart_show(Evas_Object *obj);
62 static void _e_flowlayout_smart_hide(Evas_Object *obj);
63 static void _e_flowlayout_smart_color_set(Evas_Object *obj, int r, int g, int b, int a);
64 static void _e_flowlayout_smart_clip_set(Evas_Object *obj, Evas_Object *clip);
65 static void _e_flowlayout_smart_clip_unset(Evas_Object *obj);
67 /* local subsystem globals */
68 static Evas_Smart *_e_smart = NULL;
70 /* externally accessible functions */
72 e_flowlayout_add(Evas *evas)
74 _e_flowlayout_smart_init();
75 return evas_object_smart_add(evas, _e_smart);
79 e_flowlayout_freeze(Evas_Object *obj)
83 if (evas_object_smart_smart_get(obj) != _e_smart) SMARTERR(0);
84 sd = evas_object_smart_data_get(obj);
91 e_flowlayout_thaw(Evas_Object *obj)
95 if (evas_object_smart_smart_get(obj) != _e_smart) SMARTERR(0);
96 sd = evas_object_smart_data_get(obj);
99 if (sd->frozen <= 0) _e_flowlayout_smart_reconfigure(sd);
104 e_flowlayout_orientation_set(Evas_Object *obj, int horizontal)
108 if (evas_object_smart_smart_get(obj) != _e_smart) SMARTERRNR();
109 sd = evas_object_smart_data_get(obj);
111 if (((sd->horizontal) && (horizontal)) ||
112 ((!sd->horizontal) && (!horizontal))) return;
113 sd->horizontal = horizontal;
115 if (sd->frozen <= 0) _e_flowlayout_smart_reconfigure(sd);
119 e_flowlayout_orientation_get(Evas_Object *obj)
123 if (evas_object_smart_smart_get(obj) != _e_smart) SMARTERR(0);
124 sd = evas_object_smart_data_get(obj);
126 return sd->horizontal;
130 e_flowlayout_flowdirection_set(Evas_Object *obj, int right, int bottom)
134 if (evas_object_smart_smart_get(obj) != _e_smart) SMARTERRNR();
135 sd = evas_object_smart_data_get(obj);
137 if ((((sd->flowbottom) && (bottom)) ||
138 ((!sd->flowbottom) && (!bottom))) &&
139 (((sd->flowright) && (right)) ||
140 ((!sd->flowright) && (!right)))) return;
141 sd->flowright = right;
142 sd->flowbottom = bottom;
144 if (sd->frozen <= 0) _e_flowlayout_smart_reconfigure(sd);
148 e_flowlayout_flowdirection_get(Evas_Object *obj, int *right, int *bottom)
152 if (evas_object_smart_smart_get(obj) != _e_smart) SMARTERRNR();
153 sd = evas_object_smart_data_get(obj);
155 if (right) *right = sd->flowright;
156 if (bottom) *bottom = sd->flowright;
160 e_flowlayout_homogenous_set(Evas_Object *obj, int homogenous)
164 if (evas_object_smart_smart_get(obj) != _e_smart) SMARTERRNR();
165 sd = evas_object_smart_data_get(obj);
167 if (sd->homogenous == homogenous) return;
168 sd->homogenous = homogenous;
170 if (sd->frozen <= 0) _e_flowlayout_smart_reconfigure(sd);
174 e_flowlayout_homogenous_get(Evas_Object *obj)
178 if (evas_object_smart_smart_get(obj) != _e_smart) SMARTERR(0);
179 sd = evas_object_smart_data_get(obj);
181 return sd->homogenous;
185 e_flowlayout_fill_set(Evas_Object *obj, int fill)
189 if (evas_object_smart_smart_get(obj) != _e_smart) SMARTERRNR();
190 sd = evas_object_smart_data_get(obj);
192 if (sd->fill == fill) return;
195 if (sd->frozen <= 0) _e_flowlayout_smart_reconfigure(sd);
199 e_flowlayout_fill_get(Evas_Object *obj)
203 if (evas_object_smart_smart_get(obj) != _e_smart) SMARTERR(0);
204 sd = evas_object_smart_data_get(obj);
210 e_flowlayout_pack_start(Evas_Object *obj, Evas_Object *child)
214 if (evas_object_smart_smart_get(obj) != _e_smart) SMARTERR(0);
215 sd = evas_object_smart_data_get(obj);
217 _e_flowlayout_smart_adopt(sd, child);
218 sd->items = eina_list_prepend(sd->items, child);
220 if (sd->frozen <= 0) _e_flowlayout_smart_reconfigure(sd);
225 e_flowlayout_pack_end(Evas_Object *obj, Evas_Object *child)
229 if (evas_object_smart_smart_get(obj) != _e_smart) SMARTERR(0);
230 sd = evas_object_smart_data_get(obj);
232 _e_flowlayout_smart_adopt(sd, child);
233 sd->items = eina_list_append(sd->items, child);
235 if (sd->frozen <= 0) _e_flowlayout_smart_reconfigure(sd);
236 return eina_list_count(sd->items) - 1;
240 e_flowlayout_pack_before(Evas_Object *obj, Evas_Object *child, Evas_Object *before)
247 if (evas_object_smart_smart_get(obj) != _e_smart) SMARTERR(0);
248 sd = evas_object_smart_data_get(obj);
250 _e_flowlayout_smart_adopt(sd, child);
251 sd->items = eina_list_prepend_relative(sd->items, child, before);
252 EINA_LIST_FOREACH(sd->items, l, item)
254 if (item == child) break;
258 if (sd->frozen <= 0) _e_flowlayout_smart_reconfigure(sd);
263 e_flowlayout_pack_after(Evas_Object *obj, Evas_Object *child, Evas_Object *after)
270 if (evas_object_smart_smart_get(obj) != _e_smart) SMARTERR(0);
271 sd = evas_object_smart_data_get(obj);
273 _e_flowlayout_smart_adopt(sd, child);
274 sd->items = eina_list_append_relative(sd->items, child, after);
275 EINA_LIST_FOREACH(sd->items, l, item)
277 if (item == child) break;
281 if (sd->frozen <= 0) _e_flowlayout_smart_reconfigure(sd);
286 e_flowlayout_pack_count_get(Evas_Object *obj)
290 if (evas_object_smart_smart_get(obj) != _e_smart) SMARTERR(0);
291 sd = evas_object_smart_data_get(obj);
293 return eina_list_count(sd->items);
297 e_flowlayout_pack_object_nth(Evas_Object *obj, int n)
301 if (evas_object_smart_smart_get(obj) != _e_smart) SMARTERR(NULL);
302 sd = evas_object_smart_data_get(obj);
303 if (!sd) return NULL;
304 return eina_list_nth(sd->items, n);
308 e_flowlayout_pack_object_first(Evas_Object *obj)
312 if (evas_object_smart_smart_get(obj) != _e_smart) SMARTERR(NULL);
313 sd = evas_object_smart_data_get(obj);
314 if (!sd) return NULL;
315 return eina_list_data_get(sd->items);
319 e_flowlayout_pack_object_last(Evas_Object *obj)
323 if (evas_object_smart_smart_get(obj) != _e_smart) SMARTERR(NULL);
324 sd = evas_object_smart_data_get(obj);
325 if (!sd) return NULL;
326 return eina_list_data_get(eina_list_last(sd->items));
330 e_flowlayout_pack_object_prev(Evas_Object *obj, Evas_Object *child)
336 if (evas_object_smart_smart_get(obj) != _e_smart) SMARTERR(NULL);
337 sd = evas_object_smart_data_get(obj);
338 if (!sd) return NULL;
339 EINA_LIST_FOREACH(sd->items, l, o)
340 if (o == child) return eina_list_data_get(l->prev);
345 e_flowlayout_pack_object_next(Evas_Object *obj, Evas_Object *child)
351 if (evas_object_smart_smart_get(obj) != _e_smart) SMARTERR(NULL);
352 sd = evas_object_smart_data_get(obj);
353 if (!sd) return NULL;
354 EINA_LIST_FOREACH(sd->items, l, o)
355 if (o == child) return eina_list_data_get(l->next);
360 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)
362 E_Flowlayout_Item *bi;
364 bi = evas_object_data_get(obj, "e_flowlayout_data");
368 bi->expand_w = expand_w;
369 bi->expand_h = expand_h;
370 bi->align.x = align_x;
371 bi->align.y = align_y;
377 if (bi->sd->frozen <= 0) _e_flowlayout_smart_reconfigure(bi->sd);
381 e_flowlayout_unpack(Evas_Object *obj)
383 E_Flowlayout_Item *bi;
386 bi = evas_object_data_get(obj, "e_flowlayout_data");
390 sd->items = eina_list_remove(sd->items, obj);
391 _e_flowlayout_smart_disown(obj);
393 if (sd->frozen <= 0) _e_flowlayout_smart_reconfigure(sd);
397 e_flowlayout_size_min_get(Evas_Object *obj, Evas_Coord *minw, Evas_Coord *minh)
401 if (evas_object_smart_smart_get(obj) != _e_smart) SMARTERRNR();
402 sd = evas_object_smart_data_get(obj);
404 if (sd->changed) _e_flowlayout_smart_extents_calcuate(sd);
405 if (minw) *minw = sd->min.w;
406 if (minh) *minh = sd->min.h;
410 e_flowlayout_size_max_get(Evas_Object *obj, Evas_Coord *maxw, Evas_Coord *maxh)
414 if (evas_object_smart_smart_get(obj) != _e_smart) SMARTERRNR();
415 sd = evas_object_smart_data_get(obj);
417 if (sd->changed) _e_flowlayout_smart_extents_calcuate(sd);
418 if (maxw) *maxw = sd->max.w;
419 if (maxh) *maxh = sd->max.h;
423 e_flowlayout_max_children(Evas_Object *obj)
427 if (evas_object_smart_smart_get(obj) != _e_smart) SMARTERR(0);
428 sd = evas_object_smart_data_get(obj);
430 if (!sd->homogenous) return -1;
431 return sd->rows * sd->cols;
435 e_flowlayout_align_get(Evas_Object *obj, double *ax, double *ay)
439 if (evas_object_smart_smart_get(obj) != _e_smart) SMARTERRNR();
440 sd = evas_object_smart_data_get(obj);
442 if (ax) *ax = sd->align.x;
443 if (ay) *ay = sd->align.y;
447 e_flowlayout_align_set(Evas_Object *obj, double ax, double ay)
451 if (evas_object_smart_smart_get(obj) != _e_smart) SMARTERRNR();
452 sd = evas_object_smart_data_get(obj);
454 if ((sd->align.x == ax) && (sd->align.y == ay)) return;
458 if (sd->frozen <= 0) _e_flowlayout_smart_reconfigure(sd);
461 /* local subsystem functions */
462 static E_Flowlayout_Item *
463 _e_flowlayout_smart_adopt(E_Smart_Data *sd, Evas_Object *obj)
465 E_Flowlayout_Item *bi;
467 bi = calloc(1, sizeof(E_Flowlayout_Item));
468 if (!bi) return NULL;
482 evas_object_clip_set(obj, sd->clip);
483 evas_object_smart_member_add(obj, bi->sd->obj);
484 evas_object_data_set(obj, "e_flowlayout_data", bi);
485 evas_object_event_callback_add(obj, EVAS_CALLBACK_FREE,
486 _e_flowlayout_smart_item_del_hook, NULL);
487 if ((!evas_object_visible_get(sd->clip)) &&
488 (evas_object_visible_get(sd->obj)))
489 evas_object_show(sd->clip);
494 _e_flowlayout_smart_disown(Evas_Object *obj)
496 E_Flowlayout_Item *bi;
498 bi = evas_object_data_get(obj, "e_flowlayout_data");
502 if (evas_object_visible_get(bi->sd->clip))
503 evas_object_hide(bi->sd->clip);
505 evas_object_event_callback_del(obj,
507 _e_flowlayout_smart_item_del_hook);
508 evas_object_smart_member_del(obj);
509 evas_object_clip_unset(obj);
510 evas_object_data_del(obj, "e_flowlayout_data");
515 _e_flowlayout_smart_item_del_hook(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
517 e_flowlayout_unpack(obj);
521 _e_flowlayout_smart_reconfigure(E_Smart_Data *sd)
523 Evas_Coord x, y, w, h, xx, yy, cr, cc;
529 if (!sd->changed) return;
531 /* local variables */
537 /* Calculate extents */
538 _e_flowlayout_smart_extents_calcuate(sd);
541 count = eina_list_count(sd->items);
544 /* Too small? move a little */
547 x = x + ((w - minw) * (1.0 - sd->align.x));
552 y = y + ((h - minh) * (1.0 - sd->align.y));
556 /* Some odd expanding counter */
557 EINA_LIST_FOREACH(sd->items, l, obj)
559 E_Flowlayout_Item *bi;
561 bi = evas_object_data_get(obj, "e_flowlayout_data");
566 if (bi->expand_w) expand++;
570 if (bi->expand_h) expand++;
575 /* If no expansion, w is minw, h is minh */
580 x += (double)(w - minw) * sd->align.x;
585 y += (double)(h - minh) * sd->align.y;
590 /* Some calculations */
602 /* Now for the real deal */
603 EINA_LIST_FOREACH(sd->items, l, obj)
605 E_Flowlayout_Item *bi;
607 bi = evas_object_data_get(obj, "e_flowlayout_data");
616 Evas_Coord ww, hh, ow, oh;
621 int num = count - (cr) * (sd->cols);
628 if (bi->fill_w) ow = ww;
629 if ((bi->max.w >= 0) && (bi->max.w < ow)) ow = bi->max.w;
631 if (bi->fill_h) oh = hh;
632 if ((bi->max.h >= 0) && (bi->max.h < oh)) oh = bi->max.h;
637 evas_object_move(obj,
638 xx + (Evas_Coord)(((double)(ww - ow)) * bi->align.x),
639 yy + (Evas_Coord)(((double)(hh - oh)) * bi->align.y));
643 evas_object_move(obj,
644 xx + (Evas_Coord)(((double)(ww - ow)) * bi->align.x),
645 yy - hh + (Evas_Coord)(((double)(hh - oh)) * bi->align.y));
647 evas_object_resize(obj, ow, oh);
654 evas_object_move(obj,
655 xx - ww + (Evas_Coord)(((double)(ww - ow)) * bi->align.x),
656 yy + (Evas_Coord)(((double)(hh - oh)) * bi->align.y));
660 evas_object_move(obj,
661 xx - ww + (Evas_Coord)(((double)(ww - ow)) * bi->align.x),
662 yy - hh + (Evas_Coord)(((double)(hh - oh)) * bi->align.y));
664 evas_object_resize(obj, ow, oh);
682 /* TODO Nonhomogenous Horizontal */
692 Evas_Coord ww, hh, ow, oh;
697 int num = count - (cc) * (sd->rows);
704 if (bi->fill_h) oh = hh;
705 if ((bi->max.h >= 0) && (bi->max.h < oh)) oh = bi->max.h;
707 if (bi->fill_w) ow = ww;
708 if ((bi->max.w >= 0) && (bi->max.w < ow)) ow = bi->max.w;
713 evas_object_move(obj,
714 xx + (Evas_Coord)(((double)(ww - ow)) * bi->align.x),
715 yy + (Evas_Coord)(((double)(hh - oh)) * bi->align.y));
719 evas_object_move(obj,
720 xx - ww + (Evas_Coord)(((double)(ww - ow)) * bi->align.x),
721 yy + (Evas_Coord)(((double)(hh - oh)) * bi->align.y));
723 evas_object_resize(obj, ow, oh);
730 evas_object_move(obj,
731 xx + (Evas_Coord)(((double)(ww - ow)) * bi->align.x),
732 yy - hh + (Evas_Coord)(((double)(hh - oh)) * bi->align.y));
736 evas_object_move(obj,
737 xx - ww + (Evas_Coord)(((double)(ww - ow)) * bi->align.x),
738 yy - hh + (Evas_Coord)(((double)(hh - oh)) * bi->align.y));
740 evas_object_resize(obj, ow, oh);
758 /* TODO Nonhomogeneous Vertical */
769 _e_flowlayout_smart_extents_calcuate(E_Smart_Data *sd)
773 int minw, minh, count;
775 /* FIXME: need to calc max */
776 sd->max.w = -1; /* max < 0 == unlimited */
783 EINA_LIST_FOREACH(sd->items, l, obj)
785 E_Flowlayout_Item *bi;
787 bi = evas_object_data_get(obj, "e_flowlayout_data");
792 if (minh < bi->min.h) minh = bi->min.h;
793 if (minw < bi->min.w) minw = bi->min.w;
797 if (minw < bi->min.w) minw = bi->min.w;
798 if (minh < bi->min.h) minh = bi->min.h;
804 sd->rows = sd->h / minh;
807 count = eina_list_count(sd->items);
808 sd->cols = sd->w / minw;
809 if (count < sd->cols) sd->cols = count;
822 sd->cols = sd->w / minw;
825 count = eina_list_count(sd->items);
826 sd->rows = sd->h / minh;
827 if (count < sd->cols) sd->rows = count;
842 /* TODO nonhomogenous */
845 EINA_LIST_FOREACH(sd->items, l, obj)
847 E_Flowlayout_Item *bi;
849 bi = evas_object_data_get(obj, "e_flowlayout_data");
854 if (minh < bi->min.h) minh = bi->min.h * sd->rows;
859 if (minw < bi->min.w) minw = bi->min.w * sd->cols;
866 sd->rows = sd->h / minh;
869 minw = minw / sd->cols + 0.2 * minw;
873 sd->cols = sd->w / minw;
876 minh = minh / sd->cols + 0.2 * minh;
888 _e_flowlayout_smart_init(void)
890 if (_e_smart) return;
892 static const Evas_Smart_Class sc =
895 EVAS_SMART_CLASS_VERSION,
896 _e_flowlayout_smart_add,
897 _e_flowlayout_smart_del,
898 _e_flowlayout_smart_move,
899 _e_flowlayout_smart_resize,
900 _e_flowlayout_smart_show,
901 _e_flowlayout_smart_hide,
902 _e_flowlayout_smart_color_set,
903 _e_flowlayout_smart_clip_set,
904 _e_flowlayout_smart_clip_unset,
913 _e_smart = evas_smart_class_new(&sc);
918 _e_flowlayout_smart_add(Evas_Object *obj)
922 sd = calloc(1, sizeof(E_Smart_Data));
931 sd->clip = evas_object_rectangle_add(evas_object_evas_get(obj));
932 evas_object_smart_member_add(sd->clip, obj);
933 evas_object_move(sd->clip, -100004, -100004);
934 evas_object_resize(sd->clip, 200008, 200008);
935 evas_object_color_set(sd->clip, 255, 255, 255, 255);
936 evas_object_smart_data_set(obj, sd);
940 _e_flowlayout_smart_del(Evas_Object *obj)
944 sd = evas_object_smart_data_get(obj);
946 /* FIXME: this gets into an infinite loop when changin basic->advanced on
953 child = eina_list_data_get(sd->items);
954 e_flowlayout_unpack(child);
956 evas_object_del(sd->clip);
961 _e_flowlayout_smart_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
965 sd = evas_object_smart_data_get(obj);
967 if ((x == sd->x) && (y == sd->y)) return;
975 EINA_LIST_FOREACH(sd->items, l, item)
979 evas_object_geometry_get(item, &ox, &oy, NULL, NULL);
980 evas_object_move(item, ox + dx, oy + dy);
988 _e_flowlayout_smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h)
992 sd = evas_object_smart_data_get(obj);
994 if ((w == sd->w) && (h == sd->h)) return;
998 _e_flowlayout_smart_reconfigure(sd);
1002 _e_flowlayout_smart_show(Evas_Object *obj)
1006 sd = evas_object_smart_data_get(obj);
1008 if (sd->items) evas_object_show(sd->clip);
1012 _e_flowlayout_smart_hide(Evas_Object *obj)
1016 sd = evas_object_smart_data_get(obj);
1018 evas_object_hide(sd->clip);
1022 _e_flowlayout_smart_color_set(Evas_Object *obj, int r, int g, int b, int a)
1026 sd = evas_object_smart_data_get(obj);
1028 evas_object_color_set(sd->clip, r, g, b, a);
1032 _e_flowlayout_smart_clip_set(Evas_Object *obj, Evas_Object *clip)
1036 sd = evas_object_smart_data_get(obj);
1038 evas_object_clip_set(sd->clip, clip);
1042 _e_flowlayout_smart_clip_unset(Evas_Object *obj)
1046 sd = evas_object_smart_data_get(obj);
1048 evas_object_clip_unset(sd->clip);