Imported Upstream version 1.7.1
[platform/upstream/edje.git] / src / lib / edje_smart.c
1 #include "edje_private.h"
2
3 static void _edje_smart_add(Evas_Object * obj);
4 static void _edje_smart_del(Evas_Object * obj);
5 static void _edje_smart_move(Evas_Object * obj, Evas_Coord x, Evas_Coord y);
6 static void _edje_smart_resize(Evas_Object * obj, Evas_Coord w, Evas_Coord h);
7 static void _edje_smart_show(Evas_Object * obj);
8 static void _edje_smart_hide(Evas_Object * obj);
9 static void _edje_smart_calculate(Evas_Object * obj);
10
11 static Eina_Bool _edje_smart_file_set(Evas_Object *obj, const char *file, const char *group);
12
13 static Edje_Smart_Api _edje_smart_class = EDJE_SMART_API_INIT_NAME_VERSION("edje");
14 static Evas_Smart_Class _edje_smart_parent;
15 static Evas_Smart *_edje_smart = NULL;
16
17 Eina_List *_edje_edjes = NULL;
18
19 /************************** API Routines **************************/
20
21 EAPI Evas_Object *
22 edje_object_add(Evas *evas)
23 {
24    Evas_Object *e;
25
26    _edje_lib_ref();
27    
28    if (!_edje_smart)
29      {
30         memset(&_edje_smart_parent, 0, sizeof(_edje_smart_parent));
31         _edje_object_smart_set(&_edje_smart_class);
32         _edje_smart =
33            evas_smart_class_new((Evas_Smart_Class *)&_edje_smart_class);
34      }
35
36    e = evas_object_smart_add(evas, _edje_smart);
37
38    return e;
39 }
40
41 void
42 _edje_object_smart_set(Edje_Smart_Api *sc)
43 {
44    if (!sc)
45      return;
46
47    evas_object_smart_clipped_smart_set(&sc->base);
48
49    _edje_smart_parent.add = sc->base.add; /* Save parent class */
50    sc->base.add = _edje_smart_add;
51    _edje_smart_parent.del = sc->base.del; /* Save parent class */
52    sc->base.del = _edje_smart_del;
53    /* we'll handle move thank you */
54    sc->base.move = _edje_smart_move;
55    sc->base.resize = _edje_smart_resize;
56    _edje_smart_parent.show = sc->base.show; /* Save parent class */
57    sc->base.show = _edje_smart_show;
58    _edje_smart_parent.hide = sc->base.hide; /* Save parent class */
59    sc->base.hide = _edje_smart_hide;
60    sc->base.calculate = _edje_smart_calculate;
61    //sc->base.member_add = NULL;
62    //sc->base.member_del = NULL;
63    sc->file_set = _edje_smart_file_set;
64 }
65
66 const Edje_Smart_Api *
67 _edje_object_smart_class_get(void)
68 {
69    static const Edje_Smart_Api *class = NULL;
70
71    if (class)
72      return class;
73
74    _edje_object_smart_set(&_edje_smart_class);
75    class = &_edje_smart_class;
76
77    return class;
78 }
79
80 static void
81 _edje_color_class_free(void *data)
82 {
83    Edje_Color_Class *cc = data;
84
85    if (cc->name) eina_stringshare_del(cc->name);
86    free(cc);
87 }
88
89
90 /* Private Routines */
91 static void
92 _edje_smart_add(Evas_Object *obj)
93 {
94    Edje *ed;
95    Evas *tev = evas_object_evas_get(obj);
96
97    evas_event_freeze(tev);
98    ed = evas_object_smart_data_get(obj);
99    if (!ed)
100      {
101         const Evas_Smart *smart;
102         const Evas_Smart_Class *sc;
103
104         ed = calloc(1, sizeof(Edje));
105         if (!ed) goto end_smart_add;
106
107         smart = evas_object_smart_smart_get(obj);
108         sc = evas_smart_class_get(smart);
109         ed->api = (const Edje_Smart_Api *)sc;
110
111         evas_object_smart_data_set(obj, ed);
112      }
113
114    ed->base.evas = evas_object_evas_get(obj);
115    ed->base.clipper = evas_object_rectangle_add(ed->base.evas);
116    evas_object_static_clip_set(ed->base.clipper, 1);
117    evas_object_smart_member_add(ed->base.clipper, obj);
118    evas_object_color_set(ed->base.clipper, 255, 255, 255, 255);
119    evas_object_move(ed->base.clipper, -10000, -10000);
120    evas_object_resize(ed->base.clipper, 20000, 20000);
121    evas_object_pass_events_set(ed->base.clipper, 1);
122    ed->is_rtl = EINA_FALSE;
123    ed->have_objects = 1;
124    ed->references = 1;
125    ed->user_defined = NULL;
126    ed->color_classes = eina_hash_string_small_new(_edje_color_class_free);
127
128    evas_object_geometry_get(obj, &(ed->x), &(ed->y), &(ed->w), &(ed->h));
129    ed->obj = obj;
130    _edje_edjes = eina_list_append(_edje_edjes, obj);
131    /*
132      {
133         Eina_List *l;
134         const void *data;
135
136         printf("--- EDJE DUMP [%i]\n", eina_list_count(_edje_edjes));
137         EINA_LIST_FOREACH(_edge_edges, l, data)
138           {
139              ed = _edje_fetch(data);
140              printf("EDJE: %80s | %80s\n", ed->path, ed->part);
141           }
142         printf("--- EDJE DUMP [%i]\n", eina_list_count(_edje_edjes));
143      }
144    */
145 end_smart_add:
146    evas_event_thaw(tev);
147    evas_event_thaw_eval(tev);
148 }
149
150 static void
151 _edje_smart_del(Evas_Object * obj)
152 {
153    Edje *ed;
154
155    ed = evas_object_smart_data_get(obj);
156    if (!ed) return;
157    _edje_block_violate(ed);
158    ed->delete_me = 1;
159    _edje_edjes = eina_list_remove(_edje_edjes, obj);
160    evas_object_smart_data_set(obj, NULL);
161    if (_edje_script_only(ed)) _edje_script_only_shutdown(ed);
162    if (_edje_lua_script_only(ed)) _edje_lua_script_only_shutdown(ed);
163    if (ed->persp) edje_object_perspective_set(obj, NULL);
164    _edje_file_del(ed);
165    _edje_clean_objects(ed);
166    _edje_unref(ed);
167    _edje_lib_unref();
168 }
169
170 static void
171 _edje_smart_move(Evas_Object * obj, Evas_Coord x, Evas_Coord y)
172 {
173    Edje *ed;
174
175    ed = evas_object_smart_data_get(obj);
176    if (!ed) return;
177    if ((ed->x == x) && (ed->y == y)) return;
178    ed->x = x;
179    ed->y = y;
180 //   evas_object_move(ed->clipper, ed->x, ed->y);
181
182    if (_edje_script_only(ed))
183      {
184         _edje_script_only_move(ed);
185         return;
186      }
187    if (_edje_lua_script_only(ed))
188      {
189         _edje_lua_script_only_move(ed);
190         return;
191      }
192
193    if (ed->have_mapped_part)
194      {
195         ed->dirty = 1;
196         _edje_recalc_do(ed);
197      }
198    else
199      {
200         unsigned int i;
201
202         for (i = 0; i < ed->table_parts_size; i++)
203           {
204              Edje_Real_Part *ep;
205              Evas_Coord ox, oy;
206
207              ep = ed->table_parts[i];
208              evas_object_geometry_get(ep->object, &ox, &oy, NULL, NULL);
209              evas_object_move(ep->object, ed->x + ep->x + ep->text.offset.x, ed->y + ep->y + ep->text.offset.y);
210              if (ep->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
211                _edje_entry_real_part_configure(ep);
212              if (ep->swallowed_object)
213                {
214                   evas_object_geometry_get(ep->swallowed_object, &ox, &oy, NULL, NULL);
215                   evas_object_move(ep->swallowed_object, ed->x + ep->x + ep->text.offset.x, ed->y + ep->y + ep->text.offset.y);
216                }
217           }
218      }
219 //   _edje_emit(ed, "move", NULL);
220 }
221
222 static void
223 _edje_limit_emit(Edje *ed, const char *limit_name, Eina_Bool over)
224 {
225    char *buffer;
226    unsigned int length;
227
228    if (!limit_name) return ;
229
230    length = strlen(limit_name) + 13;
231    buffer = alloca(length);
232    snprintf(buffer, length, "limit,%s,%s", limit_name, over ? "over" : "below");
233    _edje_emit(ed, buffer, NULL);
234 }
235
236 static void
237 _edje_limit_get(Edje *ed, Edje_Limit **limits, unsigned int length, Evas_Coord size_current, Evas_Coord size_next)
238 {
239    unsigned int i;
240
241    if (size_next == size_current) return ;
242
243    for (i = 0; i < length; ++i)
244      {
245         if ((size_current <= limits[i]->value) && (limits[i]->value < size_next))
246           {
247              _edje_limit_emit(ed, limits[i]->name, EINA_TRUE);
248           }
249         else if ((size_next <= limits[i]->value) && (limits[i]->value < size_current))
250           {
251              _edje_limit_emit(ed, limits[i]->name, EINA_FALSE);
252           }
253      }
254 }
255
256 static void
257 _edje_smart_resize(Evas_Object * obj, Evas_Coord w, Evas_Coord h)
258 {
259    Edje *ed;
260
261    ed = evas_object_smart_data_get(obj);
262    if (!ed) return;
263    if ((w == ed->w) && (h == ed->h)) return;
264    if (ed->collection)
265      {
266         _edje_limit_get(ed, ed->collection->limits.horizontal, ed->collection->limits.horizontal_count, ed->w, w);
267         _edje_limit_get(ed, ed->collection->limits.vertical, ed->collection->limits.vertical_count, ed->h, h);
268      }
269    ed->w = w;
270    ed->h = h;
271 #ifdef EDJE_CALC_CACHE
272    ed->all_part_change = 1;
273 #endif
274    if (_edje_script_only(ed))
275      {
276         _edje_script_only_resize(ed);
277         return;
278      }
279    if (_edje_lua_script_only(ed))
280      {
281         _edje_lua_script_only_resize(ed);
282         return;
283      }
284 //   evas_object_resize(ed->clipper, ed->w, ed->h);
285    ed->dirty = 1;
286    _edje_recalc_do(ed);
287    _edje_emit(ed, "resize", NULL);
288 }
289
290 static void
291 _edje_smart_show(Evas_Object * obj)
292 {
293    Edje *ed;
294
295    _edje_smart_parent.show(obj);
296    ed = evas_object_smart_data_get(obj);
297    if (!ed) return;
298    if (evas_object_visible_get(obj)) return;
299    if (_edje_script_only(ed))
300      {
301         _edje_script_only_show(ed);
302         return;
303      }
304    if (_edje_lua_script_only(ed))
305      {
306         _edje_lua_script_only_show(ed);
307         return;
308      }
309    _edje_emit(ed, "show", NULL);
310 }
311
312 static void
313 _edje_smart_hide(Evas_Object * obj)
314 {
315    Edje *ed;
316
317    _edje_smart_parent.hide(obj);
318    ed = evas_object_smart_data_get(obj);
319    if (!ed) return;
320    if (!evas_object_visible_get(obj)) return;
321    if (_edje_script_only(ed))
322      {
323         _edje_script_only_hide(ed);
324         return;
325      }
326    if (_edje_lua_script_only(ed))
327      {
328         _edje_lua_script_only_hide(ed);
329         return;
330      }
331    _edje_emit(ed, "hide", NULL);
332 }
333
334 static void
335 _edje_smart_calculate(Evas_Object *obj)
336 {
337    Edje *ed;
338
339    ed = evas_object_smart_data_get(obj);
340    if (!ed) return;
341    _edje_recalc_do(ed);
342 }
343
344 static Eina_Bool
345 _edje_smart_file_set(Evas_Object *obj, const char *file, const char *group)
346 {
347    return _edje_object_file_set_internal(obj, file, group, NULL, NULL);
348 }