Merge branch 'master' into svn_merge
[framework/uifw/elementary.git] / src / lib / elm_stackedicon.c
1 #include <Elementary.h>\r
2 #include "elm_priv.h"\r
3 \r
4 \r
5 /**\r
6  * @defgroup Stackedicon Stackedicon\r
7  * @ingroup Elementary\r
8  *\r
9  * This is a Stackedicon.\r
10  */\r
11 \r
12 \r
13 #define MAX_ITEM_NUM      (9)\r
14 #define MAX_MOVE_INTERVAL   (0.2)\r
15 #define ELM_MAX(v1, v2)       (((v1) > (v2)) ? (v1) : (v2))\r
16 #define ROT_RIGHT         (5)\r
17 #define ROT_LEFT         (-5)\r
18 #define MAX_SHOWN_ITEM      (3)         \r
19 \r
20 struct _Stackedicon_Item \r
21 {\r
22    Evas_Object *parent;\r
23    Evas_Object *ly;\r
24    Evas_Object *ic;   \r
25    Evas_Object *pad;   \r
26    const char *path;\r
27    int index;\r
28    Evas_Coord x, y, w, h;\r
29    Evas_Coord mw, mh;   \r
30    Eina_Bool exist : 1;   \r
31 };\r
32 \r
33 typedef struct _Widget_Data Widget_Data;\r
34 struct _Widget_Data \r
35 {   \r
36    Evas_Object *base;\r
37    int interval_x, interval_y;   \r
38    unsigned int time; \r
39    Ecore_Animator *animator;      \r
40    Eina_List *list;\r
41    Evas_Coord x, y, w, h;\r
42    Eina_Bool visible: 1;\r
43 \r
44    /*  fake img */\r
45    Evas_Object *fake_img;\r
46    int r, g, b, a;\r
47    int mdx, mdy, mmx, mmy;\r
48    Eina_Bool move_start: 1;\r
49    Eina_Bool on_update;\r
50 };\r
51 \r
52 static const char *widtype = NULL;\r
53 static void _del_hook(Evas_Object *obj);\r
54 static void _theme_hook(Evas_Object *obj);\r
55 static void _sizing_eval(Evas_Object *obj);\r
56 static void _del_image(void *data);\r
57 static void _del_all_image(void *data);\r
58 static unsigned int _current_time_get(void);\r
59 static void _icon_move_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);\r
60 static void _icon_move_to_zero(Evas_Object *obj);\r
61 static Eina_Bool _icon_move_to_zero_cb(void *data);\r
62 static void _icon_move_map(void *data, int interval_x, int interval_y);\r
63 static void _icon_map_pos(Evas_Object *obj, int index, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h);\r
64 static void _calc_item_size(int w, int h, int iw, int ih, int *res_w, int *res_h);\r
65 static void _add_image(Evas_Object *obj, void *data);\r
66 static void _fake_img_mouse_down_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);\r
67 static void _fake_img_mouse_move_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);\r
68 static void _fake_img_mouse_up_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);\r
69 static void _add_image_to_buffer(Evas_Object *obj, Evas* e, void *data);\r
70 static Evas_Object * _create_fake_image(Evas_Object *obj);\r
71 static void _show_all_image(Evas_Object *obj);\r
72 static void _hide_all_image(Evas_Object *obj);\r
73 static void _hide_hidden_image(Evas_Object *obj);\r
74 static void _update_stackedicon(Evas_Object *obj);\r
75 static void _resize_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);\r
76 static void _move_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);\r
77 static void _show_cb(void *data, Evas * e, Evas_Object * obj, void *event_info);\r
78 static void _hide_cb(void *data, Evas * e, Evas_Object * obj, void *event_info);\r
79 static void _event_init(Evas_Object *obj);\r
80 \r
81 static void\r
82 _del_hook(Evas_Object *obj)\r
83 {\r
84    Widget_Data *wd = elm_widget_data_get(obj);\r
85    Eina_List *l;\r
86    Elm_Stackedicon_Item *it;\r
87    if (!wd) return;\r
88    \r
89    if (wd->animator) \r
90      {\r
91         ecore_animator_del(wd->animator);\r
92         wd->animator = NULL;\r
93      }\r
94 \r
95    _del_all_image(wd);\r
96    \r
97    if (wd->list)\r
98      {\r
99         EINA_LIST_FOREACH(wd->list, l, it)\r
100            if (it) free(it);            \r
101         eina_list_free(wd->list);\r
102         wd->list = NULL;\r
103      }\r
104 }\r
105 \r
106 static void\r
107 _theme_hook(Evas_Object *obj)\r
108 {\r
109    Widget_Data *wd = elm_widget_data_get(obj);\r
110    Eina_List *l;\r
111    Elm_Stackedicon_Item *it;\r
112    if (!wd) return;\r
113 \r
114    _elm_theme_object_set(obj, wd->base, "stackedicon", "base", elm_widget_style_get(obj));\r
115    if (wd->fake_img) edje_object_part_swallow(wd->base, "elm.bg.swallow", wd->fake_img);\r
116    edje_object_scale_set(wd->base, elm_widget_scale_get(obj) * _elm_config->scale);\r
117    \r
118    EINA_LIST_FOREACH(wd->list, l, it) \r
119      {\r
120         if (it->ly)   _elm_theme_object_set(obj, it->ly, "stackedicon", "icon", elm_widget_style_get(obj));\r
121         if (it->ic)   edje_object_part_swallow(it->ly, "contents", it->ic);\r
122         if (it->pad)   edje_object_part_swallow(it->ly, "shadow", it->pad);\r
123         edje_object_scale_set(it->ly, elm_widget_scale_get(obj) * _elm_config->scale);\r
124      }\r
125    _update_stackedicon(obj);\r
126    _sizing_eval(obj);\r
127 }\r
128 \r
129 static void\r
130 _sizing_eval(Evas_Object *obj)\r
131 {\r
132    Widget_Data *wd = elm_widget_data_get(obj);\r
133    Evas_Coord minw = -1, minh = -1;\r
134    Evas_Coord w, h;\r
135    if (!wd) return;\r
136 \r
137    edje_object_size_min_restricted_calc(wd->base, &minw, &minh, minw, minh);\r
138    evas_object_size_hint_min_get(obj, &w, &h);\r
139    if (w > minw) minw = w;\r
140    if (h > minh) minh = h;\r
141    evas_object_size_hint_min_set(obj, minw, minh);\r
142 }\r
143 \r
144 static void \r
145 _del_image(void *data)\r
146 {\r
147    Elm_Stackedicon_Item *it = (Elm_Stackedicon_Item *)data;\r
148       \r
149    if (it->ly) \r
150      {\r
151         evas_object_del(it->ly);\r
152         evas_object_del(it->ic);            \r
153         evas_object_del(it->pad);      \r
154         it->ly = NULL;\r
155         it->ic = NULL;   \r
156         it->pad = NULL;         \r
157         it->exist = EINA_FALSE;\r
158      }\r
159 }\r
160 \r
161 static void \r
162 _del_all_image(void *data)\r
163 {\r
164    Widget_Data *wd = (Widget_Data *)data;   \r
165    Eina_List *l;\r
166    Elm_Stackedicon_Item *it = NULL;\r
167    if (!wd) return;\r
168    \r
169    EINA_LIST_FOREACH(wd->list, l, it)\r
170       if (it && it->exist) _del_image(it);\r
171 }\r
172 \r
173 static void \r
174 _icon_move_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)\r
175 {\r
176    Elm_Stackedicon_Item *it = data;\r
177    if (!it)   return;\r
178    Widget_Data *wd = elm_widget_data_get(it->parent);\r
179    if (!wd) return;\r
180    \r
181    Evas_Coord x, y;\r
182    \r
183    if (it->exist && it->ly)\r
184      {\r
185         evas_object_geometry_get(obj, &x, &y, NULL, NULL);\r
186         _icon_map_pos(it->ly, it->index, x, y, it->w, it->h);   \r
187      }   \r
188 }\r
189 \r
190 static void \r
191 _fake_img_mouse_down_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)\r
192 {\r
193    Widget_Data *wd = elm_widget_data_get(data);\r
194    Evas_Event_Mouse_Down *ev = event_info;\r
195    Eina_List *l;\r
196    Elm_Stackedicon_Item *it = NULL;\r
197    if (!wd) return;\r
198 \r
199    wd->mdx = ev->output.x;\r
200    wd->mdy = ev->output.y;\r
201 \r
202    it = NULL;\r
203    EINA_LIST_REVERSE_FOREACH(wd->list, l, it) \r
204      {\r
205         if (it)\r
206           {\r
207              if (!it->exist) _add_image(data, it);\r
208              evas_object_move(it->ly, wd->x + wd->w/2 - it->mw/2, wd->y + wd->h/2 - it->mh/2);   \r
209              if (wd->visible) evas_object_show(it->ly);\r
210           }\r
211      }\r
212 \r
213    EINA_LIST_REVERSE_FOREACH(wd->list, l, it)\r
214       if (it && it->exist) evas_object_raise(it->ly);\r
215 \r
216    evas_object_color_set(wd->fake_img, 0, 0, 0, 0);   \r
217    wd->move_start = TRUE;\r
218 }\r
219 \r
220 static void \r
221 _fake_img_mouse_move_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)\r
222 {\r
223    Widget_Data *wd = elm_widget_data_get(data);\r
224    Evas_Event_Mouse_Move *ev = event_info;\r
225    if (!wd || !ev->buttons) return;\r
226    \r
227    if (wd->move_start == TRUE)\r
228      {\r
229         evas_object_smart_callback_call(data, "drag,start", NULL);\r
230         _show_all_image(data);\r
231         wd->move_start = FALSE;\r
232      }\r
233 \r
234    wd->mmx = ev->cur.output.x;\r
235    wd->mmy = ev->cur.output.y;\r
236 \r
237    wd->interval_x = wd->mmx - wd->mdx;\r
238    wd->interval_y = wd->mmy - wd->mdy;    \r
239 \r
240    _icon_move_map(wd, wd->x + wd->interval_x, wd->y +  wd->interval_y);\r
241 }\r
242 \r
243 static void \r
244 _fake_img_mouse_up_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)\r
245 {\r
246    Widget_Data *wd = elm_widget_data_get(data);\r
247    double interval = 0.0;\r
248    if (!wd) return;\r
249 \r
250    interval = sqrt(wd->interval_x*wd->interval_x + wd->interval_y*wd->interval_y);\r
251    \r
252    if (((double)(interval/wd->h) > MAX_MOVE_INTERVAL))\r
253      {\r
254         wd->interval_x = 0;\r
255         wd->interval_y = 0;\r
256         \r
257         _icon_move_map(wd, wd->x, wd->y);      \r
258         _hide_hidden_image(data);\r
259         evas_object_smart_callback_call(data, "expanded", NULL);   \r
260         evas_object_smart_callback_call(data, "drag,stop", NULL);\r
261      }\r
262    else\r
263      {         \r
264         wd->mdx = 0;\r
265         wd->mdy = 0;\r
266         wd->mmx = 0;\r
267         wd->mmx = 0;   \r
268         \r
269         if (wd->animator) \r
270           {\r
271              ecore_animator_del(wd->animator);\r
272              wd->animator = NULL;\r
273           }\r
274         wd->time = _current_time_get();\r
275         wd->animator= ecore_animator_add(_icon_move_to_zero_cb, data);   \r
276      }   \r
277 }\r
278 \r
279 static unsigned int \r
280 _current_time_get(void)\r
281 {\r
282    struct timeval timev;\r
283    gettimeofday(&timev, NULL);\r
284    return ((timev.tv_sec * 1000) + ((timev.tv_usec) / 1000));\r
285 }\r
286 \r
287 static void \r
288 _icon_move_to_zero(Evas_Object *obj)\r
289 {\r
290    Widget_Data *wd = elm_widget_data_get(obj);\r
291    double t;\r
292    int x, y;\r
293    if (!wd) return;\r
294    \r
295    t = ELM_MAX(0.0, _current_time_get() - wd->time) / 100;\r
296 \r
297    if (t <= 1.0)\r
298      {\r
299         x = (1 * sin((t / 2.0) * (M_PI / 2)) * wd->interval_x);\r
300         y = (1 * sin((t / 2.0) * (M_PI / 2)) * wd->interval_y);            \r
301      } \r
302    else\r
303      {\r
304         x = wd->interval_x;\r
305         y = wd->interval_y;\r
306      }\r
307    \r
308    if ( y == wd->interval_y)\r
309      {\r
310         ecore_animator_del(wd->animator);\r
311         wd->animator = NULL;\r
312         wd->interval_x = 0;\r
313         wd->interval_y = 0;      \r
314         _icon_move_map(wd, wd->x, wd->y);\r
315         _hide_hidden_image(obj);\r
316         evas_object_smart_callback_call(obj, "clicked", NULL);\r
317         evas_object_smart_callback_call(obj, "drag,stop", NULL);\r
318      }\r
319    else\r
320      {   \r
321         _icon_move_map(wd, wd->x + wd->interval_x - x, wd->y + wd->interval_y - y);\r
322      }\r
323 }\r
324 \r
325 static Eina_Bool \r
326 _icon_move_to_zero_cb(void *data)\r
327 {\r
328     Evas_Object *obj = (Evas_Object *)data;\r
329    _icon_move_to_zero(obj);\r
330    \r
331    return EXIT_FAILURE;\r
332 }\r
333 \r
334 static void \r
335 _icon_move_map(void *data, int interval_x, int interval_y)\r
336 {\r
337    Widget_Data *wd = (Widget_Data *)data;\r
338    int i = 0;\r
339    int num = eina_list_count(wd->list);\r
340    int x = 0, y = 0;\r
341    if (!wd) return;\r
342    \r
343    for (i =0; i  < num; i++)\r
344      {\r
345         Elm_Stackedicon_Item *it = NULL;\r
346         it = (Elm_Stackedicon_Item *)eina_list_nth(wd->list, i);\r
347 \r
348         if (it != NULL)\r
349           {\r
350              x = wd->x  + wd->w/2 - it->mw/2 + ((interval_x - wd->x)/num)*(num -i);\r
351              y = wd->y + wd->h/2 - it->mh/2 + ((interval_y - wd->y)/num)*(num -i);\r
352              evas_object_move(it->ly, x, y);\r
353           }\r
354      }\r
355 }\r
356 \r
357 static void \r
358 _icon_map_pos(Evas_Object *obj, int index, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h)\r
359 {\r
360    Evas_Map *m;\r
361    int degree = 0;\r
362 \r
363    if ((index % 3) == 1)\r
364       degree = ROT_RIGHT;\r
365    else if ((index % 3) == 2)\r
366       degree = ROT_LEFT;\r
367 \r
368    m = evas_map_new(4);\r
369    evas_map_util_points_populate_from_geometry(m, x, y, w, h, 0);\r
370    evas_map_util_3d_rotate(m, 0, 0, degree, x + w/2, y + h/2, 0);\r
371    evas_map_util_3d_perspective(m, x + w/2, y + h/2, 0, 10000);\r
372    evas_map_smooth_set(m, 1);\r
373    evas_map_alpha_set(m, 1);\r
374    evas_object_map_set(obj, m);\r
375    evas_object_map_enable_set(obj, 1);\r
376    evas_map_free(m);   \r
377 }\r
378 \r
379 static void \r
380 _calc_item_size(int w, int h, int iw, int ih, int *res_w, int *res_h)\r
381 {\r
382    if (iw>ih)\r
383      {\r
384         if (w*ih/iw > h)\r
385           {\r
386              *res_w = h*iw/ih;\r
387              *res_h = h;                  \r
388           }\r
389         else\r
390           {\r
391              *res_w = w;\r
392              *res_h = w*ih/iw;                  \r
393           }      \r
394      }\r
395    else\r
396      {\r
397         if (h*iw/ih > w)\r
398           {\r
399              *res_w = w;\r
400              *res_h = w*h/(h*iw/ih);      \r
401           }\r
402         else\r
403           {\r
404              *res_w = h*iw/ih;\r
405              *res_h = h;            \r
406           }\r
407      }\r
408 }\r
409 \r
410 static void \r
411 _add_image(Evas_Object *obj, void *data)\r
412 {\r
413    Widget_Data *wd = elm_widget_data_get(obj);\r
414    Elm_Stackedicon_Item *it = (Elm_Stackedicon_Item *)data;\r
415    Evas_Object *ly = NULL;\r
416    Evas_Object *ic = NULL;\r
417    Evas_Object *pad = NULL;   \r
418    int iw, ih;\r
419    if (!wd || !it) return;\r
420 \r
421    ly = edje_object_add(evas_object_evas_get(obj));\r
422    if (!ly) return;\r
423    _elm_theme_object_set(obj, ly, "stackedicon", "icon", elm_widget_style_get(obj));\r
424    evas_object_size_hint_weight_set(ly, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);\r
425    elm_widget_sub_object_add(obj, ly); \r
426    \r
427    ic = evas_object_image_add(evas_object_evas_get(obj));\r
428    if (!ic) return;\r
429    evas_object_image_load_size_set(ic, wd->w/2, wd->h/2);\r
430    evas_object_image_file_set(ic, it->path, NULL);\r
431    evas_object_image_size_get(ic, &iw, &ih);\r
432    if (!iw || !ih) return;\r
433 \r
434    _calc_item_size(wd->w - 2, wd->h - 2, iw, ih, &it->w, &it->h);\r
435 \r
436    evas_object_image_fill_set(ic, 0, 0, it->w, it->h);\r
437    evas_object_size_hint_min_set(ly, it->w, it->h);\r
438    evas_object_resize(ly, it->w, it->h);\r
439 \r
440    evas_object_image_filled_set(ic, 1);\r
441    edje_object_part_swallow(ly, "contents", ic);\r
442    \r
443    pad = evas_object_rectangle_add(evas_object_evas_get(obj));\r
444    if (!pad) return;\r
445    evas_object_size_hint_align_set(pad, EVAS_HINT_FILL, EVAS_HINT_FILL);\r
446    evas_object_color_set(pad, 0, 0, 0, it->index*25);\r
447    edje_object_part_swallow(ly, "shadow", pad);\r
448    \r
449    evas_object_event_callback_add(ly, EVAS_CALLBACK_MOVE, _icon_move_cb, it);   \r
450 \r
451    it->mw = it->w;\r
452    it->mh = it->h;\r
453    it->ly = ly;\r
454    it->ic = ic;      \r
455    it->pad = pad;\r
456    it->exist = EINA_TRUE;\r
457 }\r
458 \r
459 static void \r
460 _add_image_to_buffer(Evas_Object *obj, Evas* e, void *data)\r
461 {\r
462    Widget_Data *wd = elm_widget_data_get(obj);\r
463    Elm_Stackedicon_Item *it = (Elm_Stackedicon_Item *)data;\r
464    Evas_Object *ly = NULL;\r
465    Evas_Object *ic = NULL;\r
466    int iw, ih, res_w, res_h;\r
467    if (!wd || !it) return;\r
468 \r
469    // FIXME: add an opaque rectangle because of alpha bug of evas_map.\r
470    Evas_Object* rect = evas_object_rectangle_add( e );\r
471    if (!rect) return;\r
472    evas_object_resize( rect, 1, 1);\r
473    evas_object_move(rect, wd->w/2, wd->h/2);\r
474    evas_object_color_set( rect, 0, 0, 0, 255 );\r
475    evas_object_show( rect );   \r
476 \r
477    ly = edje_object_add(e);\r
478    if (!ly) return;\r
479    _elm_theme_object_set(obj, ly, "stackedicon", "icon", elm_widget_style_get(obj));\r
480    evas_object_size_hint_weight_set(ly, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);\r
481 \r
482    ic = evas_object_image_add(e);\r
483    if (!ic) return;\r
484    evas_object_image_alpha_set(ic, EINA_TRUE);\r
485    evas_object_image_load_size_set(ic, wd->w/2, wd->h/2);\r
486    evas_object_image_file_set(ic, it->path, NULL);\r
487    evas_object_image_size_get(ic, &iw, &ih);\r
488    if (!iw || !ih) return;\r
489 \r
490    _calc_item_size(wd->w - 2, wd->h - 2, iw, ih, &res_w, &res_h);\r
491 \r
492    evas_object_image_fill_set(ic, 0, 0, res_w, res_h);      \r
493    evas_object_image_filled_set(ic, 1);\r
494    edje_object_part_swallow(ly, "contents", ic);\r
495 \r
496    evas_object_resize(ly, res_w, res_h);\r
497    evas_object_move(ly, (wd->w - res_w)/2, (wd->h - res_h)/2);      \r
498    evas_object_show(ly);   \r
499 \r
500    _icon_map_pos(ly, it->index, (wd->w - res_w)/2, (wd->h - res_h)/2, res_w, res_h);   \r
501 }\r
502 \r
503 static Evas_Object * \r
504 _create_fake_image(Evas_Object *obj)\r
505 {\r
506    Widget_Data *wd = elm_widget_data_get(obj);\r
507    Evas_Object *eo = NULL;\r
508    Eina_List *l = NULL;\r
509    Elm_Stackedicon_Item *it = NULL;\r
510    if (!wd) return NULL;\r
511 \r
512    // create fake_img\r
513    eo = evas_object_image_add(evas_object_evas_get(obj));\r
514    if (!eo) return NULL;\r
515    elm_widget_sub_object_add(obj, eo);\r
516    evas_object_image_alpha_set(eo,EINA_TRUE);\r
517    evas_object_image_data_set(eo, NULL);\r
518    evas_object_image_size_set(eo, wd->w, wd->h);\r
519    evas_object_image_fill_set(eo, 0, 0, wd->w, wd->h);   \r
520    edje_object_part_swallow(wd->base, "elm.bg.swallow", eo);\r
521 \r
522    // create ecore_evas (buffer)\r
523    Ecore_Evas* ee = ecore_evas_buffer_new( wd->w, wd->h );\r
524    Evas* e = ecore_evas_get( ee );\r
525 \r
526    // add shown icons\r
527    EINA_LIST_REVERSE_FOREACH(wd->list, l, it) \r
528      {\r
529         if (it->index >= MAX_SHOWN_ITEM) continue;\r
530         if (it) _add_image_to_buffer(obj, e, it);\r
531      }\r
532    ecore_evas_show( ee );\r
533 \r
534 \r
535    // copy buffer to data(mem)\r
536    unsigned char* data = (unsigned char*) calloc( 1, sizeof( unsigned char ) * 4 * wd->w * wd->h );\r
537    memcpy( data, (unsigned char*) ecore_evas_buffer_pixels_get( ee ), sizeof( unsigned char ) * 4 * wd->w * wd->h );\r
538    ecore_evas_free( ee );\r
539    \r
540    // copy data to fake_img \r
541    evas_object_image_data_copy_set(eo, data);\r
542    evas_object_image_data_update_add(eo, 0, 0, wd->w, wd->h);\r
543    evas_object_resize(eo, wd->w, wd->h);\r
544 \r
545    evas_object_color_get(eo, &wd->r, &wd->g, &wd->b, &wd->a);\r
546 \r
547    // add mouse events callback\r
548    evas_object_event_callback_add(eo, EVAS_CALLBACK_MOUSE_DOWN, _fake_img_mouse_down_cb, obj);\r
549    evas_object_event_callback_add(eo, EVAS_CALLBACK_MOUSE_MOVE, _fake_img_mouse_move_cb, obj);\r
550    evas_object_event_callback_add(eo, EVAS_CALLBACK_MOUSE_UP, _fake_img_mouse_up_cb, obj);\r
551 \r
552    return eo;\r
553 }   \r
554 \r
555 static void \r
556 _update_stackedicon(Evas_Object *obj)\r
557 {\r
558    Widget_Data *wd = elm_widget_data_get(obj);\r
559    if (!wd || ((wd->w == 1) && (wd->h == 1))) return;\r
560 \r
561    if (!wd->fake_img)\r
562      {\r
563         wd->fake_img = _create_fake_image(obj);\r
564      }\r
565    else if (wd->on_update)\r
566      {\r
567         wd->on_update = FALSE;\r
568         elm_widget_sub_object_del(obj, wd->fake_img);\r
569         edje_object_part_unswallow(wd->base, wd->fake_img);\r
570         evas_object_del(wd->fake_img);\r
571         wd->fake_img = NULL;\r
572         wd->fake_img = _create_fake_image(obj);\r
573      }\r
574 }\r
575 \r
576 static void _show_all_image(Evas_Object *obj)\r
577 {\r
578    Widget_Data *wd = elm_widget_data_get(obj);\r
579    if (!wd) return;\r
580    int i = 0;\r
581          \r
582    for (i =0; i < eina_list_count (wd->list); i++)\r
583      {\r
584         Elm_Stackedicon_Item *it = NULL;\r
585         it = (Elm_Stackedicon_Item *)eina_list_nth(wd->list, i);\r
586 \r
587         if (it != NULL)\r
588           {\r
589              if (it->exist == EINA_TRUE)\r
590                {   \r
591                   evas_object_show(it->ly);         \r
592                }\r
593           }\r
594      }\r
595 }\r
596 \r
597 static void _hide_all_image(Evas_Object *obj)\r
598 {\r
599    Widget_Data *wd = elm_widget_data_get(obj);\r
600    if (!wd) return;\r
601    int i = 0;\r
602          \r
603    for (i =0; i < eina_list_count (wd->list); i++)\r
604      {\r
605         Elm_Stackedicon_Item *it = NULL;\r
606         it = (Elm_Stackedicon_Item *)eina_list_nth(wd->list, i);\r
607 \r
608         if (it != NULL)\r
609           {\r
610              if (it->exist == EINA_TRUE)\r
611                {   \r
612                   evas_object_hide(it->ly);         \r
613                }\r
614           }\r
615      }\r
616 }\r
617 \r
618 static void _hide_hidden_image(Evas_Object *obj)\r
619 {\r
620    Widget_Data *wd = elm_widget_data_get(obj);\r
621    Eina_List *l;\r
622    Elm_Stackedicon_Item *it = NULL;\r
623    if (!wd) return;\r
624          \r
625    EINA_LIST_REVERSE_FOREACH(wd->list, l, it) \r
626      {\r
627         if (it->ly) evas_object_hide(it->ly);\r
628      }\r
629    evas_object_color_set(wd->fake_img, wd->r, wd->g, wd->b, wd->a);\r
630 }\r
631 \r
632 static void\r
633 _resize_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)\r
634 {\r
635    Widget_Data *wd = elm_widget_data_get(data);\r
636    Evas_Coord w, h;   \r
637    if (!wd) return;\r
638 \r
639    evas_object_geometry_get(obj, NULL, NULL, &w, &h);   \r
640    wd->w = w;\r
641    wd->h = h;\r
642    \r
643    _update_stackedicon(data);\r
644 }\r
645 \r
646 static void\r
647 _move_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)\r
648 {\r
649    Widget_Data *wd = elm_widget_data_get(data);\r
650    Evas_Coord x, y;   \r
651    if (!wd) return;\r
652 \r
653    evas_object_geometry_get(obj, &x, &y, NULL, NULL);   \r
654    wd->x = x;\r
655    wd->y = y;\r
656    \r
657    _update_stackedicon(data);   \r
658 }\r
659 \r
660 static void\r
661 _show_cb(void *data, Evas * e, Evas_Object * obj, void *event_info)\r
662 {\r
663    Widget_Data *wd = elm_widget_data_get(data);\r
664    if (!wd) return;\r
665 \r
666    wd->visible = EINA_TRUE;\r
667    _update_stackedicon(data);   \r
668 }\r
669 \r
670 static void\r
671 _hide_cb(void *data, Evas * e, Evas_Object * obj, void *event_info)\r
672 {\r
673    Widget_Data *wd = elm_widget_data_get(data);\r
674    if (!wd) return;\r
675 \r
676    wd->visible = EINA_FALSE;\r
677    _hide_all_image(data);\r
678 }\r
679 \r
680 static void\r
681 _event_init(Evas_Object *obj)\r
682 {      \r
683    Widget_Data *wd = elm_widget_data_get(obj);\r
684    if (!wd) return;\r
685    \r
686    evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, _resize_cb, obj);\r
687    evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE, _move_cb, obj);   \r
688    evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _show_cb, obj);\r
689    evas_object_event_callback_add(obj, EVAS_CALLBACK_HIDE, _hide_cb, obj);\r
690 }\r
691 \r
692 /**\r
693  * Add a new stackedicon to the parent\r
694  *\r
695  * @param parent The parent object\r
696  * @return The new object or NULL if it cannot be created\r
697  *\r
698  * @ingroup Stackedicon\r
699  */\r
700 EAPI Evas_Object *\r
701 elm_stackedicon_add(Evas_Object *parent)\r
702 {\r
703    Evas_Object *obj;\r
704    Evas *e;\r
705    Widget_Data *wd;\r
706 \r
707    wd = ELM_NEW(Widget_Data);\r
708    e = evas_object_evas_get(parent);\r
709    obj = elm_widget_add(e);\r
710    ELM_SET_WIDTYPE(widtype, "stackedicon");\r
711    elm_widget_type_set(obj, "stackedicon");\r
712    elm_widget_sub_object_add(parent, obj);\r
713    elm_widget_data_set(obj, wd);\r
714 \r
715    elm_widget_del_hook_set(obj, _del_hook);\r
716    elm_widget_theme_hook_set(obj, _theme_hook);\r
717    \r
718    wd->base = edje_object_add(e);\r
719    _elm_theme_object_set(obj, wd->base, "stackedicon", "base", "default");\r
720    elm_widget_resize_object_set(obj, wd->base);\r
721    \r
722    wd->w = 1;\r
723    wd->h = 1;\r
724    \r
725    _event_init(obj);\r
726    _sizing_eval(obj);\r
727 \r
728    return obj;\r
729 }\r
730 \r
731 /**\r
732  * This appends a path to the stackedicon\r
733  *\r
734  * @param    obj   The stackedicon object\r
735  * @param    path   The image full path\r
736  * @return   The new item or NULL if it cannot be created\r
737  *\r
738  * @ingroup Stackedicon\r
739  */\r
740 EAPI Elm_Stackedicon_Item *elm_stackedicon_item_append(Evas_Object *obj, const char *path)\r
741 {\r
742    ELM_CHECK_WIDTYPE(obj, widtype) NULL;\r
743    Widget_Data *wd = elm_widget_data_get(obj);\r
744    Elm_Stackedicon_Item *it;\r
745    if (!wd) return NULL;\r
746    if (eina_list_count(wd->list) >= MAX_ITEM_NUM) return NULL;\r
747    \r
748    it = (Elm_Stackedicon_Item *)calloc(1, sizeof(Elm_Stackedicon_Item));\r
749    it->path = eina_stringshare_add(path);\r
750    it->parent = obj;\r
751    it->ly = NULL;\r
752    it->ic = NULL;\r
753    it->pad = NULL;\r
754    it->index = eina_list_count(wd->list);\r
755    it->exist = EINA_FALSE;   \r
756    wd->list = eina_list_append(wd->list, it);\r
757 \r
758    if (it->index < MAX_SHOWN_ITEM)\r
759      {\r
760         wd->on_update = TRUE;\r
761         _update_stackedicon(obj);\r
762      }\r
763 \r
764    return it;\r
765 }\r
766 \r
767 /**\r
768  * This prepends a path to the stackedicon\r
769  *\r
770  * @param    obj   The stackedicon object\r
771  * @param    path   The image full path\r
772  * @return   The new item or NULL if it cannot be created\r
773  *\r
774  * @ingroup Stackedicon\r
775  */\r
776 EAPI Elm_Stackedicon_Item *elm_stackedicon_item_prepend(Evas_Object *obj, const char *path)\r
777 {   \r
778    ELM_CHECK_WIDTYPE(obj, widtype) NULL;\r
779    Widget_Data *wd = elm_widget_data_get(obj);\r
780    Elm_Stackedicon_Item *it;\r
781    if (!wd) return NULL;\r
782    if (eina_list_count(wd->list) >= MAX_ITEM_NUM) return NULL;\r
783    \r
784    it = (Elm_Stackedicon_Item *)calloc(1, sizeof(Elm_Stackedicon_Item));\r
785    it->path = eina_stringshare_add(path);\r
786    it->parent = obj;\r
787    it->ly = NULL;\r
788    it->ic = NULL;\r
789    it->pad = NULL;\r
790    it->index = eina_list_count(wd->list);\r
791    it->exist = EINA_FALSE;   \r
792    wd->list = eina_list_prepend(wd->list, it);\r
793 \r
794    if (it->index < MAX_SHOWN_ITEM)\r
795      {\r
796         wd->on_update = TRUE;\r
797         _update_stackedicon(obj);\r
798      }\r
799 \r
800    return it;\r
801 }\r
802 \r
803 /**\r
804  * This delete a path at the stackedicon\r
805  *\r
806  * @param    Elm_Stackedicon_Item   The delete item\r
807  *\r
808  * @ingroup Stackedicon\r
809  */\r
810 EAPI void elm_stackedicon_item_del(Elm_Stackedicon_Item *it)\r
811 {\r
812    if (!it)return;\r
813    ELM_CHECK_WIDTYPE(it->parent, widtype);\r
814    Evas_Object *obj = it->parent;\r
815    Widget_Data *wd = elm_widget_data_get(obj);\r
816    Eina_List *l;\r
817    Elm_Stackedicon_Item *_it = NULL;\r
818    int i = 0;\r
819    if (!wd) return;\r
820 \r
821    if (it->index < MAX_SHOWN_ITEM) wd->on_update = TRUE;\r
822 \r
823    if (it->exist == EINA_TRUE) _del_image(it);\r
824    wd->list = eina_list_remove(wd->list, it);\r
825    free(it);\r
826 \r
827    EINA_LIST_FOREACH(wd->list, l, _it)\r
828       if (_it->ly) _it->index = i++;\r
829 \r
830    _update_stackedicon(obj);\r
831 }\r
832 \r
833 /**\r
834  * Get item list from the stackedicon\r
835  *\r
836  * @param    obj   The stackedicon object\r
837  * @return   The item list or NULL if it cannot be created \r
838  *\r
839  * @ingroup Stackedicon\r
840  */\r
841 EAPI Eina_List *elm_stackedicon_item_list_get(Evas_Object *obj)\r
842 {\r
843    ELM_CHECK_WIDTYPE(obj, widtype) NULL;\r
844    Widget_Data *wd = elm_widget_data_get(obj);\r
845    if (!wd) return NULL;\r
846    return wd->list;\r
847 }\r
848 \r