1 #include "evas_common.h"
4 typedef struct _Evas_Object_Grid_Data Evas_Object_Grid_Data;
5 typedef struct _Evas_Object_Grid_Option Evas_Object_Grid_Option;
6 typedef struct _Evas_Object_Grid_Iterator Evas_Object_Grid_Iterator;
7 typedef struct _Evas_Object_Grid_Accessor Evas_Object_Grid_Accessor;
9 struct _Evas_Object_Grid_Option
16 struct _Evas_Object_Grid_Data
18 Evas_Object_Smart_Clipped_Data base;
23 Eina_Bool is_mirrored : 1;
26 struct _Evas_Object_Grid_Iterator
28 Eina_Iterator iterator;
30 Eina_Iterator *real_iterator;
31 const Evas_Object *grid;
34 struct _Evas_Object_Grid_Accessor
36 Eina_Accessor accessor;
38 Eina_Accessor *real_accessor;
39 const Evas_Object *grid;
42 #define EVAS_OBJECT_GRID_DATA_GET(o, ptr) \
43 Evas_Object_Grid_Data *ptr = evas_object_smart_data_get(o)
45 #define EVAS_OBJECT_GRID_DATA_GET_OR_RETURN(o, ptr) \
46 EVAS_OBJECT_GRID_DATA_GET(o, ptr); \
49 CRIT("no widget data for object %p (%s)", \
50 o, evas_object_type_get(o)); \
55 #define EVAS_OBJECT_GRID_DATA_GET_OR_RETURN_VAL(o, ptr, val) \
56 EVAS_OBJECT_GRID_DATA_GET(o, ptr); \
59 CRIT("No widget data for object %p (%s)", \
60 o, evas_object_type_get(o)); \
65 static const char EVAS_OBJECT_GRID_OPTION_KEY[] = "|EvGd";
68 _evas_object_grid_iterator_next(Evas_Object_Grid_Iterator *it, void **data)
70 Evas_Object_Grid_Option *opt;
72 if (!eina_iterator_next(it->real_iterator, (void **)&opt))
74 if (data) *data = opt->obj;
79 _evas_object_grid_iterator_get_container(Evas_Object_Grid_Iterator *it)
81 return (Evas_Object *)it->grid;
85 _evas_object_grid_iterator_free(Evas_Object_Grid_Iterator *it)
87 eina_iterator_free(it->real_iterator);
92 _evas_object_grid_accessor_get_at(Evas_Object_Grid_Accessor *it, unsigned int idx, void **data)
94 Evas_Object_Grid_Option *opt = NULL;
96 if (!eina_accessor_data_get(it->real_accessor, idx, (void **)&opt))
98 if (data) *data = opt->obj;
103 _evas_object_grid_accessor_get_container(Evas_Object_Grid_Accessor *it)
105 return (Evas_Object *)it->grid;
109 _evas_object_grid_accessor_free(Evas_Object_Grid_Accessor *it)
111 eina_accessor_free(it->real_accessor);
115 static Evas_Object_Grid_Option *
116 _evas_object_grid_option_get(Evas_Object *o)
118 return evas_object_data_get(o, EVAS_OBJECT_GRID_OPTION_KEY);
122 _evas_object_grid_option_set(Evas_Object *o, const Evas_Object_Grid_Option *opt)
124 evas_object_data_set(o, EVAS_OBJECT_GRID_OPTION_KEY, opt);
127 static Evas_Object_Grid_Option *
128 _evas_object_grid_option_del(Evas_Object *o)
130 return evas_object_data_del(o, EVAS_OBJECT_GRID_OPTION_KEY);
134 _on_child_del(void *data, Evas *evas __UNUSED__, Evas_Object *child, void *einfo __UNUSED__)
136 Evas_Object *grid = data;
137 evas_object_grid_unpack(grid, child);
141 _evas_object_grid_child_connect(Evas_Object *o, Evas_Object *child)
143 evas_object_event_callback_add
144 (child, EVAS_CALLBACK_DEL, _on_child_del, o);
148 _evas_object_grid_child_disconnect(Evas_Object *o, Evas_Object *child)
150 evas_object_event_callback_del_full
151 (child, EVAS_CALLBACK_DEL, _on_child_del, o);
154 EVAS_SMART_SUBCLASS_NEW("Evas_Object_Grid", _evas_object_grid,
155 Evas_Smart_Class, Evas_Smart_Class,
156 evas_object_smart_clipped_class_get, NULL)
159 _evas_object_grid_smart_add(Evas_Object *o)
161 EVAS_SMART_DATA_ALLOC(o, Evas_Object_Grid_Data)
166 _evas_object_grid_parent_sc->add(o);
170 _evas_object_grid_smart_del(Evas_Object *o)
172 EVAS_OBJECT_GRID_DATA_GET(o, priv);
178 Evas_Object_Grid_Option *opt = l->data;
179 _evas_object_grid_child_disconnect(o, opt->obj);
180 _evas_object_grid_option_del(opt->obj);
182 l = eina_list_remove_list(l, l);
184 _evas_object_grid_parent_sc->del(o);
188 _evas_object_grid_smart_resize(Evas_Object *o, Evas_Coord w, Evas_Coord h)
191 evas_object_geometry_get(o, NULL, NULL, &ow, &oh);
192 if ((ow == w) && (oh == h)) return;
193 evas_object_smart_changed(o);
197 _evas_object_grid_smart_calculate(Evas_Object *o)
200 Evas_Object_Grid_Option *opt;
201 Evas_Coord x, y, w, h, vw, vh, t;
204 EVAS_OBJECT_GRID_DATA_GET_OR_RETURN(o, priv);
206 if (!priv->children) return;
207 evas_object_geometry_get(o, &x, &y, &w, &h);
208 mirror = priv->is_mirrored;
211 EINA_LIST_FOREACH(priv->children, l, opt)
213 Evas_Coord x1, y1, x2, y2;
215 x1 = x + ((w * opt->x) / vw);
216 y1 = y + ((h * opt->y) / vh);
217 x2 = x + ((w * (opt->x + opt->w)) / vw);
218 y2 = y + ((h * (opt->y + opt->h)) / vh);
221 t = x1; x1 = x2; x2 = t;
222 t = y1; y1 = y2; y2 = t;
224 evas_object_move(opt->obj, x1, y1);
225 evas_object_resize(opt->obj, x2 - x1, y2 - y1);
230 _evas_object_grid_smart_set_user(Evas_Smart_Class *sc)
232 sc->add = _evas_object_grid_smart_add;
233 sc->del = _evas_object_grid_smart_del;
234 sc->resize = _evas_object_grid_smart_resize;
235 sc->calculate = _evas_object_grid_smart_calculate;
239 evas_object_grid_add(Evas *evas)
241 return evas_object_smart_add(evas, _evas_object_grid_smart_class_new());
245 evas_object_grid_add_to(Evas_Object *parent)
250 evas = evas_object_evas_get(parent);
251 o = evas_object_grid_add(evas);
252 evas_object_smart_member_add(o, parent);
257 evas_object_grid_size_set(Evas_Object *o, int w, int h)
259 EVAS_OBJECT_GRID_DATA_GET_OR_RETURN(o, priv);
260 if ((priv->size.w == w) && (priv->size.h == h)) return;
263 evas_object_smart_changed(o);
267 evas_object_grid_size_get(const Evas_Object *o, int *w, int *h)
271 EVAS_OBJECT_GRID_DATA_GET_OR_RETURN(o, priv);
272 if (w) *w = priv->size.w;
273 if (h) *h = priv->size.h;
277 evas_object_grid_pack(Evas_Object *o, Evas_Object *child, int x, int y, int w, int h)
279 Evas_Object_Grid_Option *opt;
280 Eina_Bool newobj = EINA_FALSE;
282 EVAS_OBJECT_GRID_DATA_GET_OR_RETURN_VAL(o, priv, 0);
284 opt = _evas_object_grid_option_get(child);
287 opt = malloc(sizeof(*opt));
290 ERR("could not allocate grid option data.");
304 priv->children = eina_list_append(priv->children, opt);
305 opt->l = eina_list_last(priv->children);
306 _evas_object_grid_option_set(child, opt);
307 evas_object_smart_member_add(child, o);
308 _evas_object_grid_child_connect(o, child);
310 // FIXME: we could keep a changed list
311 evas_object_smart_changed(o);
316 _evas_object_grid_remove_opt(Evas_Object_Grid_Data *priv, Evas_Object_Grid_Option *opt)
318 priv->children = eina_list_remove_list(priv->children, opt->l);
323 evas_object_grid_unpack(Evas_Object *o, Evas_Object *child)
325 Evas_Object_Grid_Option *opt;
327 EVAS_OBJECT_GRID_DATA_GET_OR_RETURN_VAL(o, priv, 0);
329 if (o != evas_object_smart_parent_get(child))
331 ERR("cannot unpack child from incorrect grid!");
335 opt = _evas_object_grid_option_del(child);
338 ERR("cannot unpack child with no packing option!");
342 _evas_object_grid_child_disconnect(o, child);
343 _evas_object_grid_remove_opt(priv, opt);
344 evas_object_smart_member_del(child);
350 evas_object_grid_clear(Evas_Object *o, Eina_Bool clear)
352 Evas_Object_Grid_Option *opt;
354 EVAS_OBJECT_GRID_DATA_GET_OR_RETURN(o, priv);
356 EINA_LIST_FREE(priv->children, opt)
358 _evas_object_grid_child_disconnect(o, opt->obj);
359 _evas_object_grid_option_del(opt->obj);
360 evas_object_smart_member_del(opt->obj);
362 evas_object_del(opt->obj);
368 evas_object_grid_pack_get(Evas_Object *o, Evas_Object *child, int *x, int *y, int *w, int *h)
370 Evas_Object_Grid_Option *opt;
376 EVAS_OBJECT_GRID_DATA_GET_OR_RETURN_VAL(o, priv, 0);
377 opt = _evas_object_grid_option_get(child);
387 evas_object_grid_iterator_new(const Evas_Object *o)
389 Evas_Object_Grid_Iterator *it;
391 EVAS_OBJECT_GRID_DATA_GET_OR_RETURN_VAL(o, priv, NULL);
393 if (!priv->children) return NULL;
395 it = calloc(1, sizeof(Evas_Object_Grid_Iterator));
396 if (!it) return NULL;
398 EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR);
400 it->real_iterator = eina_list_iterator_new(priv->children);
403 it->iterator.next = FUNC_ITERATOR_NEXT(_evas_object_grid_iterator_next);
404 it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(_evas_object_grid_iterator_get_container);
405 it->iterator.free = FUNC_ITERATOR_FREE(_evas_object_grid_iterator_free);
407 return &it->iterator;
411 evas_object_grid_accessor_new(const Evas_Object *o)
413 Evas_Object_Grid_Accessor *it;
415 EVAS_OBJECT_GRID_DATA_GET_OR_RETURN_VAL(o, priv, NULL);
417 if (!priv->children) return NULL;
419 it = calloc(1, sizeof(Evas_Object_Grid_Accessor));
420 if (!it) return NULL;
422 EINA_MAGIC_SET(&it->accessor, EINA_MAGIC_ACCESSOR);
424 it->real_accessor = eina_list_accessor_new(priv->children);
427 it->accessor.get_at = FUNC_ACCESSOR_GET_AT(_evas_object_grid_accessor_get_at);
428 it->accessor.get_container = FUNC_ACCESSOR_GET_CONTAINER(_evas_object_grid_accessor_get_container);
429 it->accessor.free = FUNC_ACCESSOR_FREE(_evas_object_grid_accessor_free);
431 return &it->accessor;
435 evas_object_grid_children_get(const Evas_Object *o)
437 Eina_List *new_list = NULL, *l;
438 Evas_Object_Grid_Option *opt;
440 EVAS_OBJECT_GRID_DATA_GET_OR_RETURN_VAL(o, priv, NULL);
442 EINA_LIST_FOREACH(priv->children, l, opt)
443 new_list = eina_list_append(new_list, opt->obj);
449 evas_object_grid_mirrored_get(const Evas_Object *obj)
451 EVAS_OBJECT_GRID_DATA_GET_OR_RETURN_VAL(obj, priv, EINA_FALSE);
452 return priv->is_mirrored;
456 evas_object_grid_mirrored_set(Evas_Object *obj, Eina_Bool mirrored)
458 EVAS_OBJECT_GRID_DATA_GET_OR_RETURN(obj, priv);
459 mirrored = !!mirrored;
460 if (priv->is_mirrored != mirrored)
462 priv->is_mirrored = mirrored;
463 _evas_object_grid_smart_calculate(obj);