fix long standing layer set bug
[profile/ivi/evas.git] / src / lib / canvas / evas_layer.c
1 #include "evas_common.h"
2 #include "evas_private.h"
3
4 static void _evas_layer_free(Evas_Layer *lay);
5
6 void
7 evas_object_inject(Evas_Object *obj, Evas *e)
8 {
9    Evas_Layer *lay;
10
11    if (obj->in_layer) return;
12    lay = evas_layer_find(e, obj->cur.layer);
13    if (!lay)
14      {
15         lay = evas_layer_new(e);
16         lay->layer = obj->cur.layer;
17         evas_layer_add(lay);
18      }
19    lay->objects = (Evas_Object *)eina_inlist_append(EINA_INLIST_GET(lay->objects), EINA_INLIST_GET(obj));
20    lay->usage++;
21    obj->layer = lay;
22    obj->in_layer = 1;
23 }
24
25 void
26 evas_object_release(Evas_Object *obj, int clean_layer)
27 {
28    if (!obj->in_layer) return;
29    obj->layer->objects = (Evas_Object *)eina_inlist_remove(EINA_INLIST_GET(obj->layer->objects), EINA_INLIST_GET(obj));
30    obj->layer->usage--;
31    if (clean_layer)
32      {
33         if (obj->layer->usage <= 0)
34           {
35              evas_layer_del(obj->layer);
36              _evas_layer_free(obj->layer);
37           }
38      }
39    obj->layer = NULL;
40    obj->in_layer = 0;
41 }
42
43 Evas_Layer *
44 evas_layer_new(Evas *e)
45 {
46    Evas_Layer *lay;
47
48    lay = calloc(1, sizeof(Evas_Layer));
49    if (!lay) return NULL;
50    lay->evas = e;
51    return lay;
52 }
53
54 static void
55 _evas_layer_free(Evas_Layer *lay)
56 {
57    free(lay);
58 }
59
60 void
61 evas_layer_pre_free(Evas_Layer *lay)
62 {
63    Evas_Object *obj;
64
65    EINA_INLIST_FOREACH(lay->objects, obj)
66      {
67         if ((!obj->smart.parent) && (!obj->delete_me))
68           evas_object_del(obj);
69      }
70 }
71
72 void
73 evas_layer_free_objects(Evas_Layer *lay)
74 {
75    while (lay->objects)
76      {
77         Evas_Object *obj;
78
79         obj = (Evas_Object *)lay->objects;
80         evas_object_free(obj, 0);
81      }
82 }
83
84 void
85 evas_layer_clean(Evas *e)
86 {
87    Evas_Layer *tmp;
88
89    while (e->layers)
90      {
91         tmp = e->layers;
92         evas_layer_del(tmp);
93         _evas_layer_free(tmp);
94      }
95 }
96
97 Evas_Layer *
98 evas_layer_find(Evas *e, short layer_num)
99 {
100    Evas_Layer *layer;
101
102    EINA_INLIST_FOREACH(e->layers, layer)
103      {
104         if (layer->layer == layer_num) return layer;
105      }
106    return NULL;
107 }
108
109 void
110 evas_layer_add(Evas_Layer *lay)
111 {
112    Evas_Layer *layer;
113
114    EINA_INLIST_FOREACH(lay->evas->layers, layer)
115      {
116         if (layer->layer > lay->layer)
117           {
118              lay->evas->layers = (Evas_Layer *)eina_inlist_prepend_relative(EINA_INLIST_GET(lay->evas->layers),
119                                                                             EINA_INLIST_GET(lay),
120                                                                             EINA_INLIST_GET(layer));
121              return;
122           }
123      }
124    lay->evas->layers = (Evas_Layer *)eina_inlist_append(EINA_INLIST_GET(lay->evas->layers), EINA_INLIST_GET(lay));
125 }
126
127 void
128 evas_layer_del(Evas_Layer *lay)
129 {
130    Evas *e;
131
132    e = lay->evas;
133    e->layers = (Evas_Layer *)eina_inlist_remove(EINA_INLIST_GET(e->layers), EINA_INLIST_GET(lay));
134 }
135
136 static void
137 _evas_object_layer_set_child(Evas_Object *obj, Evas_Object *par, short l)
138 {
139    Evas *e;
140    
141    if (obj->delete_me) return;
142    if (obj->cur.layer == l) return;
143    e = obj->layer->evas;
144    evas_object_release(obj, 1);
145    obj->cur.layer = l;
146    obj->layer = par->layer;
147    obj->layer->usage++;
148    if (obj->smart.smart)
149      {
150         Eina_Inlist *contained;
151         Evas_Object *member;
152         
153         contained = (Eina_Inlist *)evas_object_smart_members_get_direct(obj);
154         EINA_INLIST_FOREACH(contained, member)
155           {
156              _evas_object_layer_set_child(member, obj, l);
157           }
158      }
159 }
160
161 /* public functions */
162
163 EAPI void
164 evas_object_layer_set(Evas_Object *obj, short l)
165 {
166    Evas *e;
167
168    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
169    return;
170    MAGIC_CHECK_END();
171    if (obj->delete_me) return;
172    if (evas_object_intercept_call_layer_set(obj, l)) return;
173    if (obj->smart.parent) return;
174    if (obj->cur.layer == l)
175      {
176         evas_object_raise(obj);
177         return;
178      }
179    e = obj->layer->evas;
180    evas_object_release(obj, 1);
181    obj->cur.layer = l;
182    evas_object_inject(obj, e);
183    obj->restack = 1;
184    evas_object_change(obj);
185    if (obj->clip.clipees)
186      {
187         evas_object_inform_call_restack(obj);
188         return;
189      }
190    evas_object_change(obj);
191    if (!obj->smart.smart)
192      {
193         if (evas_object_is_in_output_rect(obj,
194                                           obj->layer->evas->pointer.x,
195                                           obj->layer->evas->pointer.y, 1, 1) &&
196             obj->cur.visible)
197           if (eina_list_data_find(obj->layer->evas->pointer.object.in, obj))
198             evas_event_feed_mouse_move(obj->layer->evas,
199                                        obj->layer->evas->pointer.x,
200                                        obj->layer->evas->pointer.y,
201                                        obj->layer->evas->last_timestamp,
202                                        NULL);
203      }
204    else
205      {
206         Eina_Inlist *contained;
207         Evas_Object *member;
208         
209         contained = (Eina_Inlist *)evas_object_smart_members_get_direct(obj);
210         EINA_INLIST_FOREACH(contained, member)
211           {
212             _evas_object_layer_set_child(member, obj, l);
213           }
214      }
215    evas_object_inform_call_restack(obj);
216 }
217
218 EAPI short
219 evas_object_layer_get(const Evas_Object *obj)
220 {
221    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
222    return 0;
223    MAGIC_CHECK_END();
224    if (obj->smart.parent)
225      {
226         return obj->smart.parent->cur.layer;
227      }
228    return obj->cur.layer;
229 }