move around - flatter.
[profile/ivi/evas.git] / src / lib / canvas / evas_stack.c
1 #include "evas_common.h"
2 #include "evas_private.h"
3
4 static Evas_Object *
5 evas_object_above_get_internal(const Evas_Object *obj)
6 {
7    if (((Evas_Object_List *)obj)->next)
8      return (Evas_Object *)(((Evas_Object_List *)obj)->next);
9    else
10      {
11         if (((Evas_Object_List *)(((Evas_Object *)obj)->layer))->next)
12           {
13              Evas_Layer *l;
14
15              l = (Evas_Layer *)(((Evas_Object_List *)(((Evas_Object *)obj)->layer))->next);
16              return l->objects;
17           }
18      }
19    return NULL;
20 }
21
22 static Evas_Object *
23 evas_object_below_get_internal(const Evas_Object *obj)
24 {
25    if (((Evas_Object_List *)obj)->prev)
26      return (Evas_Object *)(((Evas_Object_List *)obj)->prev);
27    else
28      {
29         if (((Evas_Object_List *)(((Evas_Object *)obj)->layer))->prev)
30           {
31              Evas_Layer *l;
32
33              l = (Evas_Layer *)(((Evas_Object_List *)(((Evas_Object *)obj)->layer))->prev);
34              return (Evas_Object *)(((Evas_Object_List *)(l->objects))->last);
35           }
36      }
37    return NULL;
38 }
39
40 /**
41  * Raise @p obj to the top of its layer.
42  *
43  * @param obj the object to raise
44  *
45  */
46 EAPI void
47 evas_object_raise(Evas_Object *obj)
48 {
49    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
50    return;
51    MAGIC_CHECK_END();
52    if (evas_object_intercept_call_raise(obj)) return;
53    if (!(((Evas_Object_List *)obj)->next))
54      {
55         evas_object_inform_call_restack(obj);
56         return;
57      }
58    if (obj->smart.parent)
59      evas_object_smart_member_raise(obj);
60    else
61      {
62         if (obj->in_layer)
63           {
64              obj->layer->objects = evas_object_list_remove(obj->layer->objects, obj);
65              obj->layer->objects = evas_object_list_append(obj->layer->objects, obj);
66           }
67      }
68    if (obj->clip.clipees)
69      {
70         evas_object_inform_call_restack(obj);
71         return;
72      }
73    if (obj->layer) evas_render_invalidate(obj->layer->evas);
74    obj->restack = 1;
75    evas_object_change(obj);
76    evas_object_inform_call_restack(obj);
77    if (obj->layer->evas->events_frozen <= 0)
78      {
79         if (!evas_event_passes_through(obj))
80           {
81              if (!obj->smart.smart)
82                {
83                   if (evas_object_is_in_output_rect(obj,
84                                                     obj->layer->evas->pointer.x,
85                                                     obj->layer->evas->pointer.y, 1, 1) &&
86                       obj->cur.visible)
87                     evas_event_feed_mouse_move(obj->layer->evas,
88                                                obj->layer->evas->pointer.x,
89                                                obj->layer->evas->pointer.y,
90                                                obj->layer->evas->last_timestamp,
91                                                NULL);
92                }
93           }
94      }
95 }
96
97 /**
98  * Lower @p obj to the bottom of its layer.
99  *
100  * @param obj the object to lower
101  *
102  */
103 EAPI void
104 evas_object_lower(Evas_Object *obj)
105 {
106    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
107    return;
108    MAGIC_CHECK_END();
109    if (evas_object_intercept_call_lower(obj)) return;
110    if (!(((Evas_Object_List *)obj)->prev))
111      {
112         evas_object_inform_call_restack(obj);
113         return;
114      }
115    if (obj->smart.parent)
116      evas_object_smart_member_lower(obj);
117    else
118      {
119         if (obj->in_layer)
120           {
121              obj->layer->objects = evas_object_list_remove(obj->layer->objects, obj);
122              obj->layer->objects = evas_object_list_prepend(obj->layer->objects, obj);
123           }
124      }
125    if (obj->clip.clipees)
126      {
127         evas_object_inform_call_restack(obj);
128         return;
129      }
130    if (obj->layer) evas_render_invalidate(obj->layer->evas);
131    obj->restack = 1;
132    evas_object_change(obj);
133    evas_object_inform_call_restack(obj);
134    if (obj->layer->evas->events_frozen <= 0)
135      {
136         if (!evas_event_passes_through(obj))
137           {
138              if (!obj->smart.smart)
139                {
140                   if (evas_object_is_in_output_rect(obj,
141                                                     obj->layer->evas->pointer.x,
142                                                     obj->layer->evas->pointer.y, 1, 1) &&
143                       obj->cur.visible)
144                     evas_event_feed_mouse_move(obj->layer->evas,
145                                                obj->layer->evas->pointer.x,
146                                                obj->layer->evas->pointer.y,
147                                                obj->layer->evas->last_timestamp,
148                                                NULL);
149                }
150           }
151      }
152 }
153
154 /**
155  * Stack @p obj immediately above @p above 
156  *
157  * If @p obj is a member of a smart object, then @p above must also be
158  * a member of the same smart object.
159  *
160  * Similarly, if @p obj is not a member of smart object, @p above may 
161  * not either. 
162  *
163  * @param obj the object to stack
164  * @param above the object above which to stack
165  *
166  */
167 EAPI void
168 evas_object_stack_above(Evas_Object *obj, Evas_Object *above)
169 {
170    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
171    return;
172    MAGIC_CHECK_END();
173    MAGIC_CHECK(above, Evas_Object, MAGIC_OBJ);
174    return;
175    MAGIC_CHECK_END();
176    if (evas_object_intercept_call_stack_above(obj, above)) return;
177    if (!above)
178      {
179         evas_object_raise(obj);
180         return;
181      }
182    if (((Evas_Object_List *)obj)->prev == (Evas_Object_List *)above)
183      {
184         evas_object_inform_call_restack(obj);
185         return;
186      }
187    if (obj->smart.parent)
188      {
189         if (obj->smart.parent != above->smart.parent)
190           {
191 //           printf("BITCH! evas_object_stack_above(), %p not inside same smart as %p!\n", obj, above);
192              return;
193           }
194         evas_object_smart_member_stack_above(obj, above);
195      }
196    else
197      {
198         if (above->smart.parent) return;
199         if (obj->layer != above->layer)
200           {
201              return;
202           }
203         if (obj->in_layer)
204           {
205              obj->layer->objects = evas_object_list_remove(obj->layer->objects, obj);
206              obj->layer->objects = evas_object_list_append_relative(obj->layer->objects, obj, above);
207           }
208      }
209    if (obj->clip.clipees)
210      {
211         evas_object_inform_call_restack(obj);
212         return;
213      }
214    if (obj->layer) evas_render_invalidate(obj->layer->evas);
215    obj->restack = 1;
216    evas_object_change(obj);
217    evas_object_inform_call_restack(obj);
218    if (obj->layer->evas->events_frozen <= 0)
219      {
220         if (!evas_event_passes_through(obj))
221           {
222              if (!obj->smart.smart)
223                {
224                   if (evas_object_is_in_output_rect(obj,
225                                                     obj->layer->evas->pointer.x,
226                                                     obj->layer->evas->pointer.y, 1, 1) &&
227                       obj->cur.visible)
228                     evas_event_feed_mouse_move(obj->layer->evas,
229                                                obj->layer->evas->pointer.x,
230                                                obj->layer->evas->pointer.y,
231                                                obj->layer->evas->last_timestamp,
232                                                NULL);
233                }
234           }
235      }
236 }
237
238 /**
239  * Stack @p obj immediately below @p below 
240  *
241  * If @p obj is a member of a smart object, then @p below must also be
242  * a member of the same smart object.
243  *
244  * Similarly, if @p obj is not a member of smart object, @p below may 
245  * not either. 
246  *
247  * @param obj the object to stack
248  * @param below the object below which to stack
249  *
250  */
251 EAPI void
252 evas_object_stack_below(Evas_Object *obj, Evas_Object *below)
253 {
254    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
255    return;
256    MAGIC_CHECK_END();
257    MAGIC_CHECK(below, Evas_Object, MAGIC_OBJ);
258    return;
259    MAGIC_CHECK_END();
260    if (evas_object_intercept_call_stack_below(obj, below)) return;
261    if (!below)
262      {
263         evas_object_lower(obj);
264         return;
265      }
266    if (((Evas_Object_List *)obj)->next == (Evas_Object_List *)below)
267      {
268         evas_object_inform_call_restack(obj);
269         return;
270      }
271    if (obj->smart.parent)
272      {
273         if (obj->smart.parent != below->smart.parent)
274           {
275 //           printf("BITCH! evas_object_stack_below(), %p not inside same smart as %p!\n", obj, below);
276              return;
277           }
278         evas_object_smart_member_stack_below(obj, below);
279      }
280    else
281      {
282         if (below->smart.parent) return;
283         if (obj->layer != below->layer)
284           {
285              return;
286           }
287         if (obj->in_layer)
288           {
289              obj->layer->objects = evas_object_list_remove(obj->layer->objects, obj);
290              obj->layer->objects = evas_object_list_prepend_relative(obj->layer->objects, obj, below);
291           }
292      }
293    if (obj->clip.clipees)
294      {
295         evas_object_inform_call_restack(obj);
296         return;
297      }
298    if (obj->layer) evas_render_invalidate(obj->layer->evas);
299    obj->restack = 1;
300    evas_object_change(obj);
301    evas_object_inform_call_restack(obj);
302    if (obj->layer->evas->events_frozen <= 0)
303      {
304         if (!evas_event_passes_through(obj))
305           {
306              if (!obj->smart.smart)
307                {
308                   if (evas_object_is_in_output_rect(obj,
309                                                     obj->layer->evas->pointer.x,
310                                                     obj->layer->evas->pointer.y, 1, 1) &&
311                       obj->cur.visible)
312                     evas_event_feed_mouse_move(obj->layer->evas,
313                                                obj->layer->evas->pointer.x,
314                                                obj->layer->evas->pointer.y,
315                                                obj->layer->evas->last_timestamp,
316                                                NULL);
317                }
318           }
319      }
320 }
321
322 /**
323  * Get the evas object above @p obj
324  *
325  * @param obj an Evas_Object
326  * @return the Evas_Object directly above
327  *
328  */
329 EAPI Evas_Object *
330 evas_object_above_get(const Evas_Object *obj)
331 {
332    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
333    return NULL;
334    MAGIC_CHECK_END();
335    if (obj->smart.parent)
336      {
337         do
338           {
339              obj = (Evas_Object *)(((Evas_Object_List *)(obj))->next);
340              if ((obj) && (!obj->delete_me)) return (Evas_Object *)obj;
341           }
342         while (obj);
343         return NULL;
344      }
345    obj = evas_object_above_get_internal(obj);
346    while (obj)
347      {
348         if (!obj->delete_me) return (Evas_Object *)obj;
349         obj = evas_object_above_get_internal(obj);
350      }
351    return NULL;
352 }
353
354 /**
355  * Get the evas object below @p obj
356  *
357  * @param obj an Evas_Object
358  * @return the Evas_Object directly below
359  *
360  */
361 EAPI Evas_Object *
362 evas_object_below_get(const Evas_Object *obj)
363 {
364    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
365    return NULL;
366    MAGIC_CHECK_END();
367    if (obj->smart.parent)
368      {
369         do
370           {
371              obj = (Evas_Object *)(((Evas_Object_List *)(obj))->prev);
372              if ((obj) && (!obj->delete_me)) return (Evas_Object *)obj;
373           }
374         while (obj);
375         return NULL;
376      }
377    obj = evas_object_below_get_internal(obj);
378    while (obj)
379      {
380         if (!obj->delete_me) return (Evas_Object *)obj;
381         obj = evas_object_below_get_internal(obj);
382      }
383    return NULL;
384 }
385
386 /**
387  * Get the lowest evas object on the Evas @p e
388  *
389  * @param e an Evas
390  * @return the lowest object
391  *
392  */
393 EAPI Evas_Object *
394 evas_object_bottom_get(const Evas *e)
395 {
396    MAGIC_CHECK(e, Evas, MAGIC_EVAS);
397    return NULL;
398    MAGIC_CHECK_END();
399    if (e->layers)
400      {
401         Evas_Object *obj;
402         
403         obj = e->layers->objects;
404         while (obj)
405           {
406              if (!obj->delete_me) return obj;
407              obj = evas_object_above_get_internal(obj);
408           }
409      }
410    return NULL;
411 }
412
413 /**
414  * Get the highest evas object on the Evas @p e
415  *
416  * @param e an Evas
417  * @return the highest object
418  *
419  */
420 EAPI Evas_Object *
421 evas_object_top_get(const Evas *e)
422 {
423    Evas_Object *obj = NULL;
424    Evas_Object_List *list;
425    Evas_Layer *layer;
426
427    MAGIC_CHECK(e, Evas, MAGIC_EVAS);
428    return NULL;
429    MAGIC_CHECK_END();
430
431    list = (Evas_Object_List *) e->layers;
432    if (!list) return NULL;
433
434    layer = (Evas_Layer *) list->last;
435    if (!layer) return NULL;
436
437    list = (Evas_Object_List *) layer->objects;
438    if (!list) return NULL;
439
440    obj = (Evas_Object *) list->last;
441    if (!obj) return NULL;
442
443    while (obj)
444      {
445         if (!obj->delete_me) return obj;
446         obj = evas_object_below_get_internal(obj);
447      }
448
449    return obj;
450 }