Find engine shared library file properly
[platform/core/appfw/ui-gadget-1.git] / ug-efl-engine / ug-efl-engine.c
1 /*
2  *  UI Gadget
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Jayoun Lee <airjany@samsung.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */
21
22 #include <glib.h>
23 #include <Elementary.h>
24 #include <ui-gadget-engine.h>
25
26 #include "ug.h"
27 #include "ug-efl-engine.h"
28 #include "ug-dbg.h"
29
30 #ifndef UG_ENGINE_API
31 #define UG_ENGINE_API __attribute__ ((visibility("default")))
32 #endif
33
34 static Evas_Object *navi = NULL;
35 static Evas_Object *conform = NULL;
36 static void on_show_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);
37 static void (*show_end_cb)(void* data) = NULL;
38 static void (*hide_end_cb)(void* data) = NULL;
39 static void __show_finished(void *data, Evas_Object *obj, void *event_info);
40
41 static Evas_Object *_get_win_conformant(Evas_Object *win)
42 {
43         Evas_Object *con = NULL;
44
45         if (!win) {
46                 _WRN("\t Invalid param error");
47                 return NULL;
48         }
49
50         con = evas_object_data_get(win, "\377 elm,conformant");
51         if (con)
52                 _DBG("\t success to get conformant");
53         else
54                 _WRN("\t fail to get conformant");
55
56         return con;
57 }
58
59 static void _layout_del_cb(void *data, Evas_Object *obj, void *event_info)
60 {
61         ui_gadget_h ug = (ui_gadget_h)data;
62         if (!ug)
63                 return;
64
65         _WRN("ug(%p) layout is deleted by abnormal path", ug);
66
67         evas_object_event_callback_del(ug->layout, EVAS_CALLBACK_DEL,
68                 (Evas_Object_Event_Cb)_layout_del_cb);
69
70         ug->layout_state = UG_LAYOUT_DESTROY;
71         ug->layout = NULL;
72 }
73
74 static void __del_effect_end(ui_gadget_h ug)
75 {
76         if (navi) {
77                 Elm_Object_Item *t = elm_naviframe_top_item_get(navi);
78                 Elm_Object_Item *b = elm_naviframe_bottom_item_get(navi);
79                 if (t == b) {
80                         _DBG("\t unset navi");
81                         elm_object_part_content_unset(conform, "elm.swallow.ug");
82                         evas_object_hide(navi);
83                 }
84         }
85         if (ug->layout) {
86                 evas_object_hide(ug->layout);
87                 evas_object_event_callback_del(ug->layout, EVAS_CALLBACK_DEL,
88                         (Evas_Object_Event_Cb)_layout_del_cb);
89         }
90
91         ug->layout_state = UG_LAYOUT_DESTROY;
92
93         hide_end_cb(ug);
94 }
95
96 static void __del_finished(void *data, Evas_Object *obj, void *event_info)
97 {
98         ui_gadget_h ug = (ui_gadget_h)data;
99         if (!ug)
100                 return;
101
102         _DBG("\t obj=%p ug=%p", obj, ug);
103
104         evas_object_smart_callback_del(obj, "transition,finished",
105                                         __del_finished);
106
107         if(ug->layout_state == UG_LAYOUT_HIDEEFFECT)
108                 __del_effect_end(ug);
109         else
110                 _ERR("wrong ug(%p) state(%d)", ug, ug->layout_state);
111 }
112
113 static void __del_effect_top_layout(ui_gadget_h ug)
114 {
115         _DBG("\t cb transition add ug=%p", ug);
116         evas_object_smart_callback_add(navi, "transition,finished",
117                                 __del_finished, ug);
118         elm_naviframe_item_pop(navi);
119         ug->effect_layout = NULL;
120         ug->layout_state = UG_LAYOUT_HIDEEFFECT;
121 }
122
123 static void __del_effect_layout(ui_gadget_h ug, ui_gadget_h t_ug)
124 {
125         if (!ug)
126                 return;
127
128         _DBG("\t ug=%p state=%d , t_ug=%p", ug, ug->layout_state, t_ug);
129
130         _DBG("\t remove navi item: ug=%p state=%d", ug, ug->layout_state);
131         elm_object_item_del(ug->effect_layout);
132         ug->effect_layout = NULL;
133
134         __del_effect_end(ug);
135 }
136
137 static void __hide_end(ui_gadget_h ug)
138 {
139         if (navi) {
140                 Elm_Object_Item *t = elm_naviframe_top_item_get(navi);
141                 Elm_Object_Item *b = elm_naviframe_bottom_item_get(navi);
142                 if (t == b) {
143                         _DBG("\t unset navi");
144                         elm_object_part_content_unset(conform, "elm.swallow.ug");
145                         evas_object_hide(navi);
146                 }
147         }
148
149         if (ug->layout) {
150                 evas_object_hide(ug->layout);
151         }
152 }
153
154 static void __hide_effect_end(ui_gadget_h ug)
155 {
156         __hide_end(ug);
157
158         ug->layout_state = UG_LAYOUT_HIDE;
159 }
160
161 static void __hide_finished(void *data, Evas_Object *obj, void *event_info)
162 {
163         ui_gadget_h ug = (ui_gadget_h)data;
164         if (!ug)
165                 return;
166
167         _DBG("\t obj=%p ug=%p", obj, ug);
168
169         evas_object_smart_callback_del(obj, "transition,finished",
170                                         __hide_finished);
171
172         if(ug->layout_state == UG_LAYOUT_HIDEEFFECT)
173                 __hide_effect_end(ug);
174         else
175                 _ERR("wrong ug(%p) state(%d)", ug, ug->layout_state);
176 }
177
178 static void __on_hideonly_cb(void *data, Evas_Object *obj)
179 {
180         ui_gadget_h ug = (ui_gadget_h)data;
181
182         if (!ug)
183                 return;
184
185         _DBG("\t obj=%p ug=%p layout_state=%d state=%d", obj, ug, ug->layout_state, ug->state);
186
187         evas_object_intercept_hide_callback_del(ug->layout, __on_hideonly_cb);
188         evas_object_event_callback_add(ug->layout, EVAS_CALLBACK_SHOW, on_show_cb, ug);
189
190         if (ug->layout_state == UG_LAYOUT_SHOW) {
191                 ug->layout_state = UG_LAYOUT_HIDE;
192         } else if (ug->layout_state == UG_LAYOUT_NOEFFECT) {
193                 ;
194         } else {
195                 _ERR("wrong ug(%p) state(%d)", ug, ug->layout_state);
196                 return;
197         }
198
199         if ((elm_naviframe_top_item_get(navi) == ug->effect_layout) 
200                 && (ug->layout_state != UG_LAYOUT_NOEFFECT)) {
201                 _DBG("\t cb transition add ug=%p", ug);
202                 evas_object_smart_callback_add(navi, "transition,finished",
203                                 __hide_finished, ug);
204                 elm_naviframe_item_pop(navi);
205                 ug->layout_state = UG_LAYOUT_HIDEEFFECT;
206         } else {
207                 elm_object_item_del(ug->effect_layout);
208                 __hide_end(ug);
209         }
210
211         ug->effect_layout = NULL;
212 }
213
214 static void on_destroy(ui_gadget_h ug, ui_gadget_h t_ug,
215                        void (*hide_cb)(void* data))
216 {
217         if (!ug)
218                 return;
219         _DBG("\t ug=%p tug=%p layout_state=%d", ug, t_ug, ug->layout_state);
220
221         evas_object_intercept_hide_callback_del(ug->layout,
222                                                 __on_hideonly_cb);
223
224         if(hide_cb == NULL) {
225                 /* ug_destroy_all case */
226                 evas_object_event_callback_del(ug->layout, EVAS_CALLBACK_DEL,
227                         (Evas_Object_Event_Cb)_layout_del_cb);
228                 return;
229         }
230
231         if(!hide_end_cb)
232                 hide_end_cb = hide_cb;
233
234         if (ug != t_ug) {
235                 _DBG("requested ug(%p) is not top ug(%p)", ug, t_ug);
236                 __del_effect_layout(ug, t_ug);
237                 return;
238         }
239
240         if(ug->layout_state == UG_LAYOUT_SHOW) {
241                 __del_effect_top_layout(ug);
242         } else if (ug->layout_state == UG_LAYOUT_SHOWEFFECT) {
243                 evas_object_smart_callback_del(navi, "transition,finished",
244                                         __show_finished);
245                 __del_effect_top_layout(ug);
246         } else if (ug->layout_state == UG_LAYOUT_HIDE
247                 || ug->layout_state == UG_LAYOUT_NOEFFECT) {
248                 __del_effect_layout(ug, t_ug);
249         } else if (ug->layout_state == UG_LAYOUT_HIDEEFFECT) {
250                 ;
251         } else {
252                 _WRN("[UG Effect Plug-in] : layout state(%p) error!!", ug->layout_state);
253                 __del_effect_end(ug);
254         }
255 }
256
257 static void __show_finished(void *data, Evas_Object *obj, void *event_info)
258 {
259         ui_gadget_h ug = (ui_gadget_h)data;
260         if (!ug)
261                 return;
262
263         _DBG("\tobj=%p ug=%p", obj, ug);
264
265         evas_object_smart_callback_del(obj, "transition,finished",
266                                         __show_finished);
267
268         if (ug->layout_state == UG_LAYOUT_DESTROY) {
269                 _DBG("ug(%p) already destroyed", ug);
270         } else if (ug->layout_state == UG_LAYOUT_SHOWEFFECT) {
271                 ug->layout_state = UG_LAYOUT_SHOW;
272                 if((show_end_cb)&&(ug->state == UG_STATE_CREATED))
273                         show_end_cb(ug);
274         } else {
275                 _ERR("wrong state(%d)", ug->layout_state);
276         }
277
278         return;
279 }
280
281 static void on_show_cb(void *data, Evas *e, Evas_Object *obj,
282                        void *event_info)
283 {
284         ui_gadget_h ug = (ui_gadget_h)data;
285         if (!ug)
286                 return;
287         _DBG("\tobj=%p ug=%p layout=%p state=%d", obj, ug, ug->layout, ug->layout_state);
288
289         evas_object_event_callback_del(ug->layout, EVAS_CALLBACK_SHOW, on_show_cb);
290
291         evas_object_intercept_hide_callback_add(ug->layout,
292                                                 __on_hideonly_cb, ug);
293
294         //if 'elm.swallow.ug' string is changed, msg team have to apply this changes.
295         elm_object_part_content_set(conform, "elm.swallow.ug", navi);
296
297         if (ug->layout_state == UG_LAYOUT_HIDEEFFECT
298                 || ug->layout_state == UG_LAYOUT_HIDE
299             || ug->layout_state == UG_LAYOUT_INIT) {
300                 _DBG("\t UG_LAYOUT_Init(%d) obj=%p", ug->layout_state, obj);
301                 ug->layout_state = UG_LAYOUT_SHOWEFFECT;
302
303                 evas_object_smart_callback_add(navi, "transition,finished",
304                                                 __show_finished, ug);
305                 ug->effect_layout = elm_naviframe_item_push(navi, NULL, NULL, NULL,
306                                                     ug->layout, NULL);
307         } else if (ug->layout_state == UG_LAYOUT_NOEFFECT) {
308                 _DBG("\t UG_LAYOUT_NOEFFECT obj=%p", obj);
309                 Elm_Object_Item *navi_top = elm_naviframe_top_item_get(navi);
310                 ug->effect_layout = elm_naviframe_item_insert_after(navi,
311                                 navi_top, NULL, NULL, NULL, ug->layout, NULL);
312                 //ug start cb
313                 if(show_end_cb)
314                         show_end_cb(ug);
315         } else {
316                 _ERR("\tlayout state error!! state=%d\n", ug->layout_state);
317         }
318
319         _DBG("\ton_show_cb end ug=%p", ug);
320 }
321
322 static void *on_create(void *win, ui_gadget_h ug,
323                                         void (*show_cb)(void* data))
324 {
325         Evas_Object *navi_bg;
326         Evas_Object *con = NULL;
327
328         if (!ug)
329                 return NULL;
330         _DBG("\t ug=%p state=%d", ug, ug->layout_state);
331
332         con = evas_object_data_get(win, "\377 elm,conformant");
333         if (con) {
334                 conform = con;
335                 _DBG("\t There is conformant");
336         } else {
337                 _ERR("\t There is no conformant");
338                 return NULL;
339         }
340
341         if (!navi) {
342                 navi = elm_naviframe_add(conform);
343                 elm_object_focus_allow_set(navi, EINA_FALSE);
344                 elm_object_style_set(navi, "uglib");
345                 elm_naviframe_content_preserve_on_pop_set(navi, EINA_TRUE);
346                 _DBG("\t new navi first navi=%p", navi);
347                 elm_naviframe_prev_btn_auto_pushed_set(navi, EINA_FALSE);
348
349                 navi_bg = evas_object_rectangle_add(evas_object_evas_get(navi));
350                 evas_object_size_hint_fill_set(navi_bg, EVAS_HINT_FILL,
351                                                 EVAS_HINT_FILL);
352                 evas_object_color_set(navi_bg, 0, 0, 0, 0);
353                 elm_naviframe_item_push(navi, NULL, NULL, NULL, navi_bg, NULL);
354         }
355
356         if(!show_end_cb)
357                 show_end_cb = show_cb;
358
359         evas_object_hide(ug->layout);
360         evas_object_event_callback_add(ug->layout, EVAS_CALLBACK_SHOW, on_show_cb, ug);
361         evas_object_event_callback_add(ug->layout, EVAS_CALLBACK_DEL,
362                 (Evas_Object_Event_Cb)_layout_del_cb, ug);
363
364         ug->layout_state = UG_LAYOUT_INIT;
365
366         return conform;
367 }
368
369 static void *on_request(void *data, ui_gadget_h ug, int req)
370 {
371         void *ret;
372
373         _DBG("on_request ug(%p) req(%d)", ug, req);
374
375         switch(req)
376         {
377                 case UG_UI_REQ_GET_CONFORMANT :
378                         ret = (void *)_get_win_conformant((Evas_Object *)data);
379                         break;
380                 default :
381                         _WRN("wrong req id(%d)", req);
382                         return NULL;
383         }
384
385         return ret;
386 }
387
388 UG_ENGINE_API int UG_ENGINE_INIT(struct ug_engine_ops *ops)
389 {
390         if (!ops)
391                 return -1;
392
393         ops->create = on_create;
394         ops->destroy = on_destroy;
395         ops->request = on_request;
396
397         return 0;
398 }
399
400 UG_ENGINE_API void UG_ENGINE_EXIT(struct ug_engine_ops *ops)
401 {
402 }