3 /* FIXME: something is weird here - i had to reverse all stacking logic to make
6 typedef struct _E_Smart_Data E_Smart_Data;
7 typedef struct _E_Layout_Item E_Layout_Item;
11 Evas_Coord x, y, w, h;
16 unsigned char changed : 1;
23 Evas_Coord x, y, w, h;
27 /* local subsystem functions */
28 static E_Layout_Item *_e_layout_smart_adopt(E_Smart_Data *sd, Evas_Object *obj);
29 static void _e_layout_smart_disown(Evas_Object *obj);
30 static void _e_layout_smart_item_del_hook(void *data, Evas *e, Evas_Object *obj, void *event_info);
31 static void _e_layout_smart_reconfigure(E_Smart_Data *sd);
32 static void _e_layout_smart_move_resize_item(E_Layout_Item *li);
34 static void _e_layout_smart_init(void);
35 static void _e_layout_smart_add(Evas_Object *obj);
36 static void _e_layout_smart_del(Evas_Object *obj);
37 static void _e_layout_smart_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y);
38 static void _e_layout_smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h);
39 static void _e_layout_smart_show(Evas_Object *obj);
40 static void _e_layout_smart_hide(Evas_Object *obj);
41 static void _e_layout_smart_color_set(Evas_Object *obj, int r, int g, int b, int a);
42 static void _e_layout_smart_clip_set(Evas_Object *obj, Evas_Object *clip);
43 static void _e_layout_smart_clip_unset(Evas_Object *obj);
45 /* local subsystem globals */
46 static Evas_Smart *_e_smart = NULL;
48 /* externally accessible functions */
50 e_layout_add(Evas *evas)
52 _e_layout_smart_init();
53 return evas_object_smart_add(evas, _e_smart);
57 e_layout_freeze(Evas_Object *obj)
61 if (evas_object_smart_smart_get(obj) != _e_smart) SMARTERR(0);
62 sd = evas_object_smart_data_get(obj);
68 e_layout_thaw(Evas_Object *obj)
72 if (evas_object_smart_smart_get(obj) != _e_smart) SMARTERR(0);
73 sd = evas_object_smart_data_get(obj);
75 if (sd->frozen <= 0) _e_layout_smart_reconfigure(sd);
80 e_layout_virtual_size_set(Evas_Object *obj, Evas_Coord w, Evas_Coord h)
84 if (evas_object_smart_smart_get(obj) != _e_smart) SMARTERRNR();
85 sd = evas_object_smart_data_get(obj);
88 if ((sd->vw == w) && (sd->vh == h)) return;
92 if (sd->frozen <= 0) _e_layout_smart_reconfigure(sd);
96 e_layout_virtual_size_get(Evas_Object *obj, Evas_Coord *w, Evas_Coord *h)
100 if (evas_object_smart_smart_get(obj) != _e_smart) SMARTERRNR();
101 sd = evas_object_smart_data_get(obj);
107 e_layout_coord_canvas_to_virtual(Evas_Object *obj, Evas_Coord cx, Evas_Coord cy, Evas_Coord *vx, Evas_Coord *vy)
111 if (evas_object_smart_smart_get(obj) != _e_smart) SMARTERRNR();
112 sd = evas_object_smart_data_get(obj);
114 if (vx) *vx = (cx - sd->x) * ((double)(sd->vw) / sd->w);
115 if (vy) *vy = (cy - sd->y) * ((double)(sd->vh) / sd->h);
119 e_layout_coord_virtual_to_canvas(Evas_Object *obj, Evas_Coord vx, Evas_Coord vy, Evas_Coord *cx, Evas_Coord *cy)
123 if (evas_object_smart_smart_get(obj) != _e_smart) SMARTERRNR();
124 sd = evas_object_smart_data_get(obj);
126 if (cx) *cx = vx * ((double)(sd->w) / sd->vw) + sd->x;
127 if (cy) *cy = vy * ((double)(sd->h) / sd->vh) + sd->y;
131 e_layout_pack(Evas_Object *obj, Evas_Object *child)
136 if (evas_object_smart_smart_get(obj) != _e_smart) SMARTERRNR();
137 sd = evas_object_smart_data_get(obj);
138 _e_layout_smart_adopt(sd, child);
139 sd->items = eina_list_append(sd->items, child);
140 li = evas_object_data_get(child, "e_layout_data");
141 _e_layout_smart_move_resize_item(li);
145 e_layout_child_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
149 li = evas_object_data_get(obj, "e_layout_data");
151 if ((li->x == x) && (li->y == y)) return;
154 _e_layout_smart_move_resize_item(li);
158 e_layout_child_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h)
162 li = evas_object_data_get(obj, "e_layout_data");
166 if ((li->w == w) && (li->h == h)) return;
169 _e_layout_smart_move_resize_item(li);
173 e_layout_child_lower(Evas_Object *obj)
177 li = evas_object_data_get(obj, "e_layout_data");
179 if (!eina_list_data_find(li->sd->items, obj)) return;
180 if ((li->sd->items) && eina_list_next(li->sd->items))
182 li->sd->items = eina_list_remove(li->sd->items, obj);
183 evas_object_lower(obj);
184 li->sd->items = eina_list_prepend(li->sd->items, obj);
189 e_layout_child_raise(Evas_Object *obj)
193 li = evas_object_data_get(obj, "e_layout_data");
195 if (!eina_list_data_find(li->sd->items, obj)) return;
196 if ((li->sd->items) && eina_list_next(li->sd->items))
198 li->sd->items = eina_list_remove(li->sd->items, obj);
199 evas_object_raise(obj);
200 li->sd->items = eina_list_append(li->sd->items, obj);
205 e_layout_child_lower_below(Evas_Object *obj, Evas_Object *below)
209 li = evas_object_data_get(obj, "e_layout_data");
211 if (!eina_list_data_find(li->sd->items, below)) return;
212 if (!eina_list_data_find(li->sd->items, obj)) return;
213 if ((li->sd->items) && eina_list_next(li->sd->items))
215 li->sd->items = eina_list_remove(li->sd->items, obj);
216 evas_object_stack_below(obj, below);
217 li->sd->items = eina_list_prepend_relative(li->sd->items, obj, below);
222 e_layout_child_raise_above(Evas_Object *obj, Evas_Object *above)
226 li = evas_object_data_get(obj, "e_layout_data");
228 if (!eina_list_data_find(li->sd->items, above)) return;
229 if (!eina_list_data_find(li->sd->items, obj)) return;
230 if ((li->sd->items) && eina_list_next(li->sd->items))
232 li->sd->items = eina_list_remove(li->sd->items, obj);
233 evas_object_stack_above(obj, above);
234 li->sd->items = eina_list_append_relative(li->sd->items, obj, above);
239 e_layout_child_geometry_get(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h)
243 li = evas_object_data_get(obj, "e_layout_data");
253 e_layout_unpack(Evas_Object *obj)
258 li = evas_object_data_get(obj, "e_layout_data");
261 sd->items = eina_list_remove(sd->items, obj);
262 _e_layout_smart_disown(obj);
265 /* local subsystem functions */
266 static E_Layout_Item *
267 _e_layout_smart_adopt(E_Smart_Data *sd, Evas_Object *obj)
271 li = evas_object_data_get(obj, "e_layout_data");
272 if (li) e_layout_unpack(obj);
273 li = calloc(1, sizeof(E_Layout_Item));
274 if (!li) return NULL;
282 evas_object_clip_set(obj, sd->clip);
283 evas_object_smart_member_add(obj, li->sd->obj);
284 evas_object_data_set(obj, "e_layout_data", li);
285 evas_object_event_callback_add(obj, EVAS_CALLBACK_FREE,
286 _e_layout_smart_item_del_hook, NULL);
287 if ((!evas_object_visible_get(sd->clip)) &&
288 (evas_object_visible_get(sd->obj)))
289 evas_object_show(sd->clip);
294 _e_layout_smart_disown(Evas_Object *obj)
298 li = evas_object_data_get(obj, "e_layout_data");
302 if (evas_object_visible_get(li->sd->clip))
303 evas_object_hide(li->sd->clip);
305 evas_object_event_callback_del(obj,
307 _e_layout_smart_item_del_hook);
308 evas_object_smart_member_del(obj);
309 evas_object_data_del(obj, "e_layout_data");
314 _e_layout_smart_item_del_hook(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
316 e_layout_unpack(obj);
320 _e_layout_smart_reconfigure(E_Smart_Data *sd)
325 if (!sd->changed) return;
327 EINA_LIST_FOREACH(sd->items, l, obj)
330 li = evas_object_data_get(obj, "e_layout_data");
331 _e_layout_smart_move_resize_item(li);
337 _e_layout_smart_move_resize_item(E_Layout_Item *li)
339 evas_object_move(li->obj,
340 li->sd->x + ((li->x * li->sd->w) / li->sd->vw),
341 li->sd->y + ((li->y * li->sd->h) / li->sd->vh));
342 evas_object_resize(li->obj,
343 (li->w * li->sd->w) / li->sd->vw,
344 (li->h * li->sd->h) / li->sd->vh);
348 _e_layout_smart_init(void)
350 if (_e_smart) return;
352 static const Evas_Smart_Class sc =
355 EVAS_SMART_CLASS_VERSION,
358 _e_layout_smart_move,
359 _e_layout_smart_resize,
360 _e_layout_smart_show,
361 _e_layout_smart_hide,
362 _e_layout_smart_color_set,
363 _e_layout_smart_clip_set,
364 _e_layout_smart_clip_unset,
373 _e_smart = evas_smart_class_new(&sc);
378 _e_layout_smart_add(Evas_Object *obj)
382 sd = calloc(1, sizeof(E_Smart_Data));
391 sd->clip = evas_object_rectangle_add(evas_object_evas_get(obj));
392 evas_object_smart_member_add(sd->clip, obj);
393 evas_object_move(sd->clip, -100001, -100001);
394 evas_object_resize(sd->clip, 200002, 200002);
395 evas_object_color_set(sd->clip, 255, 255, 255, 255);
396 evas_object_smart_data_set(obj, sd);
400 _e_layout_smart_del(Evas_Object *obj)
404 sd = evas_object_smart_data_get(obj);
410 child = eina_list_data_get(sd->items);
411 e_layout_unpack(child);
413 evas_object_del(sd->clip);
418 _e_layout_smart_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
423 sd = evas_object_smart_data_get(obj);
425 if ((x == sd->x) && (y == sd->y)) return;
432 EINA_LIST_FOREACH(sd->items, l, item)
436 evas_object_geometry_get(item, &ox, &oy, NULL, NULL);
437 evas_object_move(item, ox + dx, oy + dy);
445 _e_layout_smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h)
449 sd = evas_object_smart_data_get(obj);
451 if ((w == sd->w) && (h == sd->h)) return;
455 _e_layout_smart_reconfigure(sd);
459 _e_layout_smart_show(Evas_Object *obj)
463 sd = evas_object_smart_data_get(obj);
465 if (sd->items) evas_object_show(sd->clip);
469 _e_layout_smart_hide(Evas_Object *obj)
473 sd = evas_object_smart_data_get(obj);
475 evas_object_hide(sd->clip);
479 _e_layout_smart_color_set(Evas_Object *obj, int r, int g, int b, int a)
483 sd = evas_object_smart_data_get(obj);
485 evas_object_color_set(sd->clip, r, g, b, a);
489 _e_layout_smart_clip_set(Evas_Object *obj, Evas_Object *clip)
493 sd = evas_object_smart_data_get(obj);
495 evas_object_clip_set(sd->clip, clip);
499 _e_layout_smart_clip_unset(Evas_Object *obj)
503 sd = evas_object_smart_data_get(obj);
505 evas_object_clip_unset(sd->clip);